From 15d04037fa0682838a0d03e51c25834d53c9c61c Mon Sep 17 00:00:00 2001 From: Spencer Bryngelson Date: Thu, 26 Mar 2026 18:51:15 -0400 Subject: [PATCH 01/14] Solid particle implementation for E-L solver --- docs/documentation/case.md | 52 +- docs/documentation/equations.md | 40 + docs/module_categories.json | 2 + src/common/m_boundary_common.fpp | 503 +++- src/common/m_derived_types.fpp | 37 +- src/common/m_helper.fpp | 9 +- src/common/m_helper_basic.fpp | 14 +- src/common/m_mpi_common.fpp | 333 ++- src/post_process/m_global_parameters.fpp | 112 +- src/post_process/m_mpi_proxy.fpp | 25 +- src/post_process/m_start_up.fpp | 9 +- src/pre_process/m_global_parameters.fpp | 185 +- src/pre_process/m_mpi_proxy.fpp | 28 +- src/pre_process/m_start_up.fpp | 6 +- src/simulation/m_bubbles.fpp | 103 +- src/simulation/m_bubbles_EE.fpp | 25 +- src/simulation/m_bubbles_EL.fpp | 1240 +++++++--- src/simulation/m_bubbles_EL_kernels.fpp | 572 +++-- src/simulation/m_compute_levelset.fpp | 49 +- src/simulation/m_data_output.fpp | 240 +- src/simulation/m_global_parameters.fpp | 211 +- src/simulation/m_ib_patches.fpp | 190 +- src/simulation/m_ibm.fpp | 69 +- src/simulation/m_mpi_proxy.fpp | 1182 ++++++++- src/simulation/m_particles_EL.fpp | 2645 +++++++++++++++++++++ src/simulation/m_particles_EL_kernels.fpp | 904 +++++++ src/simulation/m_rhs.fpp | 40 +- src/simulation/m_sim_helpers.fpp | 65 +- src/simulation/m_start_up.fpp | 43 +- src/simulation/m_time_steppers.fpp | 42 +- toolchain/mfc/params/definitions.py | 35 +- toolchain/mfc/params/descriptions.py | 8 + 32 files changed, 7916 insertions(+), 1102 deletions(-) create mode 100644 src/simulation/m_particles_EL.fpp create mode 100644 src/simulation/m_particles_EL_kernels.fpp diff --git a/docs/documentation/case.md b/docs/documentation/case.md index ecdeb786d4..1ae3851b33 100644 --- a/docs/documentation/case.md +++ b/docs/documentation/case.md @@ -266,6 +266,16 @@ Setup: Only requires specifying `init_dir` and filename pattern via `zeros_defau Implementation: All variables and file handling are managed in `src/common/include/ExtrusionHardcodedIC.fpp` with no manual grid configuration needed. Usage: Ideal for initializing simulations from lower-dimensional solutions, enabling users to add perturbations or modifications to the base extruded fields for flow instability studies. +The following parameters support hardcoded initial conditions that read interface data from files: + +| Parameter | Type | Description | +| ---: | :---: | :--- | +| `interface_file` | String | Path to interface geometry data file | +| `normFac` | Real | Interface normalization factor | +| `normMag` | Real | Interface normal magnitude | +| `g0_ic` | Real | Initial gas volume fraction for interfacial IC | +| `p0_ic` | Real | Initial pressure for interfacial IC | + #### Parameter Descriptions - `num_patches` defines the total number of patches defined in the domain. @@ -788,7 +798,7 @@ Details of the transducer acoustic source model can be found in \cite Maeda17. | ---: | :----: | :--- | | `bubbles_euler` | Logical | Ensemble-averaged bubble modeling | | `bubbles_lagrange` | Logical | Volume-averaged bubble modeling | -| `bubble_model` | Integer | [1] Gilmore; [2] Keller--Miksis; [3] Rayleigh-Plesset | +| `bubble_model` | Integer | [0] Particle; [1] Gilmore; [2] Keller--Miksis; [3] Rayleigh-Plesset | | `Ca` | Real | Cavitation number | | `Web` | Real | Weber number | | `Re_inv` | Real | Inverse Reynolds number | @@ -892,6 +902,13 @@ When ``polytropic = 'F'``, the gas compression is modeled as non-polytropic due | `epsilonb` | Real | Standard deviation scaling for the gaussian function | | `charwidth` | Real | Domain virtual depth (z direction, for 2D simulations) | | `valmaxvoid` | Real | Maximum void fraction permitted | +| `drag_model` | Integer | Drag model for bubble dynamics | +| `vel_model` | Integer | Velocity model for bubble interface | +| `charNz` | Integer | Characteristic size parameter | +| `input_path` | String | Path to bubble input file (default: `./input`) | +| `pressure_force` | Logical | Enable pressure gradient force | +| `gravity_force` | Logical | Enable gravitational force | +| `write_void_evol` | Logical | Write void fraction evolution data | - `nBubs_glb` Total number of bubbles. Their initial conditions need to be specified in the ./input/lag_bubbles.dat file. See the example cases for additional information. @@ -905,6 +922,39 @@ When ``polytropic = 'F'``, the gas compression is modeled as non-polytropic due - `massTransfer_model` Activates the mass transfer model at the bubble's interface based on (\cite Preston07). +#### 9.3 Lagrangian Solid Particle Model + +| Parameter | Type | Description | +| ---: | :---: | :--- | +| `particles_lagrange` | Logical | Lagrangian solid particle model switch | +| `nParticles_glb` | Integer | Global number of particles | +| `solver_approach` | Integer | 1: One-way coupling, 2: Two-way coupling | +| `smooth_type` | Integer | Smoothing function. 1: Gaussian, 2: Delta 3x3 | +| `stokes_drag` | Integer | Stokes drag model flag | +| `qs_drag_model` | Integer | Quasi-steady drag model (0: off, 1: Parmar, 2: Modified Parmar, 3: Osnes, 4: Gidaspow) | +| `added_mass_model` | Integer | Added mass model (0: off, >0: active) | +| `interpolation_order` | Integer | Polynomial order for barycentric field interpolation | +| `collision_force` | Logical | Enable soft-sphere DEM particle-particle collisions | +| `pressure_force` | Logical | Enable pressure gradient force on particles | +| `gravity_force` | Logical | Enable gravitational force on particles | +| `write_void_evol` | Logical | Write void fraction evolution data | +| `epsilonb` | Real | Standard deviation scaling for the Gaussian kernel | +| `valmaxvoid` | Real | Maximum void fraction permitted | +| `particle_pp%%rho0ref_particle` | Real | Reference particle material density | +| `particle_pp%%cp_particle` | Real | Particle specific heat capacity | + +- `particles_lagrange` activates the Euler-Lagrange solid particle solver. Particle initial conditions are read from `./input/lag_particles.dat`. The solver tracks non-deformable spherical particles in a compressible carrier flow using volume-averaged source terms (\cite Maeda18). + +- `nParticles_glb` specifies the total number of particles across all MPI ranks. Their initial positions, velocities, and radii must be specified in the input file. + +- `solver_approach` specifies the coupling method: [1] one-way coupling where particles are advected by the flow but do not influence it, [2] two-way coupling where particle forces are projected back onto the Eulerian grid as source terms. + +- `qs_drag_model` selects the quasi-steady drag correlation: [1] Parmar et al. (2010) with Sangani volume fraction correction, [2] Modified Parmar with Osnes et al. (2023) volume fraction correction, [3] Osnes et al. (2023) full correlation with Loth et al. (2021) rarefied regime, [4] Gidaspow (1994) correlation for dense particle suspensions. + +- `collision_force` activates soft-sphere DEM collisions using a spring-dashpot contact model with Hertzian stiffness. Collision forces between particles on different MPI ranks are communicated via non-blocking point-to-point messaging. + +- `interpolation_order` sets the order of the barycentric Lagrange polynomial used to interpolate Eulerian field quantities (pressure, velocity, density) to particle positions. Must be even; the interpolation stencil uses `N/2` points in each direction. + ### 10. Velocity Field Setup {#sec-velocity-field-setup} | Parameter | Type | Description | diff --git a/docs/documentation/equations.md b/docs/documentation/equations.md index 6bb17aa9de..b69a29adf2 100644 --- a/docs/documentation/equations.md +++ b/docs/documentation/equations.md @@ -514,6 +514,46 @@ with \f$\sigma = \varepsilon_b \max(\Delta x^{1/3}_\text{cell},\;R_\text{bubble} Each bubble is tracked individually with Keller-Miksis dynamics and 4th-order adaptive Runge-Kutta time integration. +### 6.3 Euler-Lagrange Solid Particles (`particles_lagrange = .true.`) + +**Source:** `src/simulation/m_particles_EL.fpp`, `src/simulation/m_particles_EL_kernels.fpp` + +The Euler-Lagrange particle solver tracks non-deformable solid particles in a compressible carrier flow. +The volume-averaged carrier flow equations use the same source term framework as the bubble model (Section 6.2), +with the particle volume fraction \f$\alpha_p\f$ replacing the bubble void fraction \f$\alpha\f$. + +**Particle volume fraction via Gaussian kernel:** + +\f[\alpha_p(\mathbf{x}) = \sum_n V_{p,n}\,\delta_\sigma(\mathbf{x} - \mathbf{x}_n)\f] + +where \f$V_{p,n} = \frac{4}{3}\pi R_n^3\f$ is the volume of particle \f$n\f$ and \f$\delta_\sigma\f$ is the Gaussian regularization kernel from Section 6.2. + +**Particle equation of motion:** + +\f[m_p \frac{d\mathbf{u}_p}{dt} = \mathbf{F}_\text{drag} + \mathbf{F}_\text{pressure} + \mathbf{F}_\text{AM} + \mathbf{F}_\text{gravity} + \mathbf{F}_\text{collision}\f] + +**Quasi-steady drag force:** + +\f[\mathbf{F}_\text{drag} = \beta\,(\mathbf{u}_f - \mathbf{u}_p)\f] + +where \f$\beta\f$ is a drag coefficient computed from one of several correlations selected via `qs_drag_model`: +- Parmar et al. (2010): Re and Ma corrections with Sangani et al. (1991) volume fraction correction +- Modified Parmar: Re and Ma corrections with Osnes et al. (2023) volume fraction correction +- Osnes et al. (2023): comprehensive correlation for compressible flow through random particle suspensions +- Gidaspow (1994): Ergun/Wen-Yu correlation for dense suspensions + +**Pressure gradient force** (`pressure_force = .true.`): + +\f[\mathbf{F}_\text{pressure} = -V_p\,\nabla p\f] + +**Added mass force** (`added_mass_model > 0`): + +\f[\mathbf{F}_\text{AM} = C_\text{AM}\,\rho_f\,V_p\left(\frac{D\mathbf{u}_f}{Dt} - \frac{d\mathbf{u}_p}{dt}\right)\f] + +**Collision force** (`collision_force = .true.`): + +Soft-sphere DEM model with Hertzian contact stiffness and viscous damping. + --- ## 7. Fluid-Structure Interaction diff --git a/docs/module_categories.json b/docs/module_categories.json index d1da0ed5ed..6d64a0e42f 100644 --- a/docs/module_categories.json +++ b/docs/module_categories.json @@ -19,6 +19,8 @@ "m_bubbles_EE", "m_bubbles_EL", "m_bubbles_EL_kernels", + "m_particles_EL", + "m_particles_EL_kernels", "m_qbmm", "m_hyperelastic", "m_hypoelastic", diff --git a/src/common/m_boundary_common.fpp b/src/common/m_boundary_common.fpp index 918b0daea5..b041bbc74d 100644 --- a/src/common/m_boundary_common.fpp +++ b/src/common/m_boundary_common.fpp @@ -20,13 +20,16 @@ module m_boundary_common type(scalar_field), dimension(:,:), allocatable :: bc_buffers $:GPU_DECLARE(create='[bc_buffers]') + type(int_bounds_info), dimension(3) :: beta_bc_bounds + $:GPU_DECLARE(create='[beta_bc_bounds]') + #ifdef MFC_MPI integer, dimension(1:3,1:2) :: MPI_BC_TYPE_TYPE integer, dimension(1:3,1:2) :: MPI_BC_BUFFER_TYPE #endif - private; public :: s_initialize_boundary_common_module, s_populate_variables_buffers, s_create_mpi_types, & - & s_populate_capillary_buffers, s_populate_F_igr_buffers, s_write_serial_boundary_condition_files, & + private; public :: s_initialize_boundary_common_module, s_populate_variables_buffers, s_populate_beta_buffers, & + & s_create_mpi_types, s_populate_capillary_buffers, s_populate_F_igr_buffers, s_write_serial_boundary_condition_files, & & s_write_parallel_boundary_condition_files, s_read_serial_boundary_condition_files, & & s_read_parallel_boundary_condition_files, s_assign_default_bc_type, s_populate_grid_variables_buffers, & & s_finalize_boundary_common_module @@ -39,7 +42,7 @@ module m_boundary_common contains - !> Allocate and set up boundary condition buffer arrays for all coordinate directions. + !> @brief Allocates and sets up boundary condition buffer arrays for all coordinate directions. impure subroutine s_initialize_boundary_common_module() integer :: i, j @@ -68,9 +71,26 @@ contains end do end if + if (bubbles_lagrange .or. particles_lagrange) then + beta_bc_bounds(1)%beg = -mapcells - 1 + beta_bc_bounds(1)%end = m + mapcells + 1 + ! n > 0 always for bubbles_lagrange + beta_bc_bounds(2)%beg = -mapcells - 1 + beta_bc_bounds(2)%end = n + mapcells + 1 + if (p == 0) then + beta_bc_bounds(3)%beg = 0 + beta_bc_bounds(3)%end = 0 + else + beta_bc_bounds(3)%beg = -mapcells - 1 + beta_bc_bounds(3)%end = p + mapcells + 1 + end if + end if + $:GPU_UPDATE(device='[beta_bc_bounds]') + end subroutine s_initialize_boundary_common_module - !> Populate the buffers of the primitive variables based on the selected boundary conditions. + !> The purpose of this procedure is to populate the buffers of the primitive variables, depending on the selected boundary + !! conditions. impure subroutine s_populate_variables_buffers(bc_type, q_prim_vf, pb_in, mv_in) type(scalar_field), dimension(sys_size), intent(inout) :: q_prim_vf @@ -78,7 +98,7 @@ contains type(integer_field), dimension(1:num_dims,1:2), intent(in) :: bc_type integer :: k, l - ! BC type codes defined in m_constants.fpp; non-negative values are MPI boundaries + ! Population of Buffers in x-direction if (bc_x%beg >= 0) then call s_mpi_sendrecv_variables_buffers(q_prim_vf, 1, -1, sys_size, pb_in, mv_in) @@ -241,7 +261,7 @@ contains if (bc_z%end >= 0) then call s_mpi_sendrecv_variables_buffers(q_prim_vf, 3, 1, sys_size, pb_in, mv_in) - else + else !< bc_x%end $:GPU_PARALLEL_LOOP(private='[l, k]', collapse=2) do l = -buff_size, n + buff_size do k = -buff_size, m + buff_size @@ -268,10 +288,11 @@ contains $:END_GPU_PARALLEL_LOOP() end if #:endif + ! END: Population of Buffers in z-direction end subroutine s_populate_variables_buffers - !> Fill ghost cells by copying the nearest boundary cell value along the specified direction. + !> @brief Fills ghost cells by copying the nearest boundary cell value along the specified direction. subroutine s_ghost_cell_extrapolation(q_prim_vf, bc_dir, bc_loc, k, l) $:GPU_ROUTINE(function_name='s_ghost_cell_extrapolation', parallelism='[seq]', cray_inline=True) @@ -287,7 +308,7 @@ contains q_prim_vf(i)%sf(-j, k, l) = q_prim_vf(i)%sf(0, k, l) end do end do - else !< bc_x%end + else !< bc_y%end do i = 1, sys_size do j = 1, buff_size q_prim_vf(i)%sf(m + j, k, l) = q_prim_vf(i)%sf(m, k, l) @@ -301,7 +322,7 @@ contains q_prim_vf(i)%sf(k, -j, l) = q_prim_vf(i)%sf(k, 0, l) end do end do - else !< bc_y%end + else !< bc_z%end do i = 1, sys_size do j = 1, buff_size q_prim_vf(i)%sf(k, n + j, l) = q_prim_vf(i)%sf(k, n, l) @@ -315,7 +336,7 @@ contains q_prim_vf(i)%sf(k, l, -j) = q_prim_vf(i)%sf(k, l, 0) end do end do - else !< bc_z%end + else !< bc_x%end do i = 1, sys_size do j = 1, buff_size q_prim_vf(i)%sf(k, l, p + j) = q_prim_vf(i)%sf(k, l, p) @@ -326,7 +347,8 @@ contains end subroutine s_ghost_cell_extrapolation - !> Apply reflective (symmetry) boundary conditions by mirroring primitive variables and flipping the normal velocity component. + !> @brief Applies reflective (symmetry) boundary conditions by mirroring primitive variables and flipping the normal velocity + !! component. subroutine s_symmetry(q_prim_vf, bc_dir, bc_loc, k, l, pb_in, mv_in) $:GPU_ROUTINE(parallelism='[seq]') @@ -371,7 +393,7 @@ contains end do end do end if - else !< bc_x%end + else !< bc_y%end do j = 1, buff_size do i = 1, contxe q_prim_vf(i)%sf(m + j, k, l) = q_prim_vf(i)%sf(m - (j - 1), k, l) @@ -440,7 +462,7 @@ contains end do end do end if - else !< bc_y%end + else !< bc_z%end do j = 1, buff_size do i = 1, momxb q_prim_vf(i)%sf(k, n + j, l) = q_prim_vf(i)%sf(k, n - (j - 1), l) @@ -510,7 +532,7 @@ contains end do end do end if - else !< bc_z%end + else !< bc_x%end do j = 1, buff_size do i = 1, momxb + 1 q_prim_vf(i)%sf(k, l, p + j) = q_prim_vf(i)%sf(k, l, p - (j - 1)) @@ -549,7 +571,7 @@ contains end subroutine s_symmetry - !> Apply periodic boundary conditions by copying values from the opposite domain boundary. + !> @brief Applies periodic boundary conditions by copying values from the opposite domain boundary. subroutine s_periodic(q_prim_vf, bc_dir, bc_loc, k, l, pb_in, mv_in) $:GPU_ROUTINE(parallelism='[seq]') @@ -577,7 +599,7 @@ contains end do end do end if - else !< bc_x%end + else !< bc_y%end do i = 1, sys_size do j = 1, buff_size q_prim_vf(i)%sf(m + j, k, l) = q_prim_vf(i)%sf(j - 1, k, l) @@ -613,7 +635,7 @@ contains end do end do end if - else !< bc_y%end + else !< bc_z%end do i = 1, sys_size do j = 1, buff_size q_prim_vf(i)%sf(k, n + j, l) = q_prim_vf(i)%sf(k, j - 1, l) @@ -649,7 +671,7 @@ contains end do end do end if - else !< bc_z%end + else do i = 1, sys_size do j = 1, buff_size q_prim_vf(i)%sf(k, l, p + j) = q_prim_vf(i)%sf(k, l, j - 1) @@ -671,7 +693,8 @@ contains end subroutine s_periodic - !> Apply axis boundary conditions for cylindrical coordinates by reflecting values across the axis with azimuthal phase shift. + !> @brief Applies axis boundary conditions for cylindrical coordinates by reflecting values across the axis with azimuthal phase + !! shift. subroutine s_axis(q_prim_vf, pb_in, mv_in, k, l) $:GPU_ROUTINE(parallelism='[seq]') @@ -721,7 +744,7 @@ contains end subroutine s_axis - !> Apply slip wall boundary conditions by extrapolating scalars and reflecting the wall-normal velocity component. + !> @brief Applies slip wall boundary conditions by extrapolating scalars and reflecting the wall-normal velocity component. subroutine s_slip_wall(q_prim_vf, bc_dir, bc_loc, k, l) $:GPU_ROUTINE(function_name='s_slip_wall',parallelism='[seq]', cray_inline=True) @@ -736,12 +759,12 @@ contains do j = 1, buff_size if (i == momxb) then q_prim_vf(i)%sf(-j, k, l) = -q_prim_vf(i)%sf(j - 1, k, l) + 2._wp*bc_x%vb1 - else + else !< bc_x%end q_prim_vf(i)%sf(-j, k, l) = q_prim_vf(i)%sf(0, k, l) end if end do end do - else !< bc_x%end + else do i = 1, sys_size do j = 1, buff_size if (i == momxb) then @@ -758,12 +781,12 @@ contains do j = 1, buff_size if (i == momxb + 1) then q_prim_vf(i)%sf(k, -j, l) = -q_prim_vf(i)%sf(k, j - 1, l) + 2._wp*bc_y%vb2 - else + else !< bc_y%end q_prim_vf(i)%sf(k, -j, l) = q_prim_vf(i)%sf(k, 0, l) end if end do end do - else !< bc_y%end + else do i = 1, sys_size do j = 1, buff_size if (i == momxb + 1) then @@ -780,12 +803,12 @@ contains do j = 1, buff_size if (i == momxe) then q_prim_vf(i)%sf(k, l, -j) = -q_prim_vf(i)%sf(k, l, j - 1) + 2._wp*bc_z%vb3 - else + else !< bc_z%end q_prim_vf(i)%sf(k, l, -j) = q_prim_vf(i)%sf(k, l, 0) end if end do end do - else !< bc_z%end + else do i = 1, sys_size do j = 1, buff_size if (i == momxe) then @@ -800,7 +823,7 @@ contains end subroutine s_slip_wall - !> Apply no-slip wall boundary conditions by reflecting and negating all velocity components at the wall. + !> @brief Applies no-slip wall boundary conditions by reflecting and negating all velocity components at the wall. subroutine s_no_slip_wall(q_prim_vf, bc_dir, bc_loc, k, l) $:GPU_ROUTINE(function_name='s_no_slip_wall',parallelism='[seq]', cray_inline=True) @@ -820,12 +843,12 @@ contains q_prim_vf(i)%sf(-j, k, l) = -q_prim_vf(i)%sf(j - 1, k, l) + 2._wp*bc_x%vb2 else if (i == momxb + 2 .and. num_dims > 2) then q_prim_vf(i)%sf(-j, k, l) = -q_prim_vf(i)%sf(j - 1, k, l) + 2._wp*bc_x%vb3 - else + else !< bc_x%end q_prim_vf(i)%sf(-j, k, l) = q_prim_vf(i)%sf(0, k, l) end if end do end do - else !< bc_x%end + else do i = 1, sys_size do j = 1, buff_size if (i == momxb) then @@ -850,12 +873,12 @@ contains q_prim_vf(i)%sf(k, -j, l) = -q_prim_vf(i)%sf(k, j - 1, l) + 2._wp*bc_y%vb2 else if (i == momxb + 2 .and. num_dims > 2) then q_prim_vf(i)%sf(k, -j, l) = -q_prim_vf(i)%sf(k, j - 1, l) + 2._wp*bc_y%vb3 - else + else !< bc_y%end q_prim_vf(i)%sf(k, -j, l) = q_prim_vf(i)%sf(k, 0, l) end if end do end do - else !< bc_y%end + else do i = 1, sys_size do j = 1, buff_size if (i == momxb) then @@ -880,12 +903,12 @@ contains q_prim_vf(i)%sf(k, l, -j) = -q_prim_vf(i)%sf(k, l, j - 1) + 2._wp*bc_z%vb2 else if (i == momxb + 2 .and. num_dims > 2) then q_prim_vf(i)%sf(k, l, -j) = -q_prim_vf(i)%sf(k, l, j - 1) + 2._wp*bc_z%vb3 - else + else !< bc_z%end q_prim_vf(i)%sf(k, l, -j) = q_prim_vf(i)%sf(k, l, 0) end if end do end do - else !< bc_z%end + else do i = 1, sys_size do j = 1, buff_size if (i == momxb) then @@ -894,7 +917,7 @@ contains q_prim_vf(i)%sf(k, l, p + j) = -q_prim_vf(i)%sf(k, l, p - (j - 1)) + 2._wp*bc_z%ve2 else if (i == momxb + 2 .and. num_dims > 2) then q_prim_vf(i)%sf(k, l, p + j) = -q_prim_vf(i)%sf(k, l, p - (j - 1)) + 2._wp*bc_z%ve3 - else + else !< bc_x%end q_prim_vf(i)%sf(k, l, p + j) = q_prim_vf(i)%sf(k, l, p) end if end do @@ -904,7 +927,7 @@ contains end subroutine s_no_slip_wall - !> Apply Dirichlet boundary conditions by prescribing ghost cell values from stored boundary buffers. + !> @brief Applies Dirichlet boundary conditions by prescribing ghost cell values from stored boundary buffers. subroutine s_dirichlet(q_prim_vf, bc_dir, bc_loc, k, l) $:GPU_ROUTINE(function_name='s_dirichlet',parallelism='[seq]', cray_inline=True) @@ -921,7 +944,7 @@ contains q_prim_vf(i)%sf(-j, k, l) = bc_buffers(1, 1)%sf(i, k, l) end do end do - else !< bc_x%end + else !< bc_y%end do i = 1, sys_size do j = 1, buff_size q_prim_vf(i)%sf(m + j, k, l) = bc_buffers(1, 2)%sf(i, k, l) @@ -936,7 +959,7 @@ contains q_prim_vf(i)%sf(k, -j, l) = bc_buffers(2, 1)%sf(k, i, l) end do end do - else !< bc_y%end + else !< bc_z%end do i = 1, sys_size do j = 1, buff_size q_prim_vf(i)%sf(k, n + j, l) = bc_buffers(2, 2)%sf(k, i, l) @@ -952,7 +975,7 @@ contains q_prim_vf(i)%sf(k, l, -j) = bc_buffers(3, 1)%sf(k, l, i) end do end do - else !< bc_z%end + else !< bc_x%end do i = 1, sys_size do j = 1, buff_size q_prim_vf(i)%sf(k, l, p + j) = bc_buffers(3, 2)%sf(k, l, i) @@ -967,7 +990,7 @@ contains end subroutine s_dirichlet - !> Extrapolate QBMM bubble pressure and mass-vapor variables into ghost cells by copying boundary values. + !> @brief Extrapolates QBMM bubble pressure and mass-vapor variables into ghost cells by copying boundary values. subroutine s_qbmm_extrapolation(bc_dir, bc_loc, k, l, pb_in, mv_in) $:GPU_ROUTINE(parallelism='[seq]') @@ -986,7 +1009,7 @@ contains end do end do end do - else !< bc_x%end + else !< bc_y%end do i = 1, nb do q = 1, nnode do j = 1, buff_size @@ -1006,7 +1029,7 @@ contains end do end do end do - else !< bc_y%end + else !< bc_z%end do i = 1, nb do q = 1, nnode do j = 1, buff_size @@ -1026,7 +1049,7 @@ contains end do end do end do - else !< bc_z%end + else do i = 1, nb do q = 1, nnode do j = 1, buff_size @@ -1040,7 +1063,329 @@ contains end subroutine s_qbmm_extrapolation - !> Populate ghost cell buffers for the color function and its divergence used in capillary surface tension. + impure subroutine s_populate_beta_buffers(q_beta, bc_type, nvar) + + type(scalar_field), dimension(:), intent(inout) :: q_beta + type(integer_field), dimension(1:num_dims,1:2), intent(in) :: bc_type + integer, intent(in) :: nvar + integer :: k, l + + !> x-direction + + if (bc_x%beg >= 0) then + call s_mpi_reduce_beta_variables_buffers(q_beta, 1, -1, nvar) + else + $:GPU_PARALLEL_LOOP(private='[l, k]', collapse=2) + do l = beta_bc_bounds(3)%beg, beta_bc_bounds(3)%end + do k = beta_bc_bounds(2)%beg, beta_bc_bounds(2)%end + select case (bc_x%beg) + case (BC_PERIODIC) + call s_beta_periodic(q_beta, 1, -1, k, l, nvar) + case (BC_REFLECTIVE) + call s_beta_reflective(q_beta, 1, -1, k, l, nvar) + case default + end select + end do + end do + $:END_GPU_PARALLEL_LOOP() + end if + + if (bc_x%end >= 0) then + call s_mpi_reduce_beta_variables_buffers(q_beta, 1, 1, nvar) + else + $:GPU_PARALLEL_LOOP(private='[l, k]', collapse=2) + do l = beta_bc_bounds(3)%beg, beta_bc_bounds(3)%end + do k = beta_bc_bounds(2)%beg, beta_bc_bounds(2)%end + select case (bc_x%end) + case (BC_PERIODIC) + call s_beta_periodic(q_beta, 1, 1, k, l, nvar) + case (BC_REFLECTIVE) + call s_beta_reflective(q_beta, 1, 1, k, l, nvar) + case default + end select + end do + end do + $:END_GPU_PARALLEL_LOOP() + end if + + !> y-direction + if (bc_y%beg >= 0) then + call s_mpi_reduce_beta_variables_buffers(q_beta, 2, -1, nvar) + else + $:GPU_PARALLEL_LOOP(private='[l, k]', collapse=2) + do l = beta_bc_bounds(3)%beg, beta_bc_bounds(3)%end + do k = beta_bc_bounds(1)%beg, beta_bc_bounds(1)%end + select case (bc_y%beg) + case (BC_PERIODIC) + call s_beta_periodic(q_beta, 2, -1, k, l, nvar) + case (BC_REFLECTIVE) + call s_beta_reflective(q_beta, 2, -1, k, l, nvar) + case default + end select + end do + end do + $:END_GPU_PARALLEL_LOOP() + end if + + if (bc_y%end >= 0) then + call s_mpi_reduce_beta_variables_buffers(q_beta, 2, 1, nvar) + else + $:GPU_PARALLEL_LOOP(private='[l, k]', collapse=2) + do l = beta_bc_bounds(3)%beg, beta_bc_bounds(3)%end + do k = beta_bc_bounds(1)%beg, beta_bc_bounds(1)%end + select case (bc_y%end) + case (BC_PERIODIC) + call s_beta_periodic(q_beta, 2, 1, k, l, nvar) + case (BC_REFLECTIVE) + call s_beta_reflective(q_beta, 2, 1, k, l, nvar) + case default + end select + end do + end do + $:END_GPU_PARALLEL_LOOP() + end if + + if (num_dims == 2) return + + #:if not MFC_CASE_OPTIMIZATION or num_dims > 2 + !> z-direction + if (bc_z%beg >= 0) then + call s_mpi_reduce_beta_variables_buffers(q_beta, 3, -1, nvar) + else + $:GPU_PARALLEL_LOOP(private='[l, k]', collapse=2) + do l = beta_bc_bounds(2)%beg, beta_bc_bounds(2)%end + do k = beta_bc_bounds(1)%beg, beta_bc_bounds(1)%end + select case (bc_type(3, 1)%sf(k, l, 0)) + case (BC_PERIODIC) + call s_beta_periodic(q_beta, 3, -1, k, l, nvar) + case (BC_REFLECTIVE) + call s_beta_reflective(q_beta, 3, -1, k, l, nvar) + case default + end select + end do + end do + $:END_GPU_PARALLEL_LOOP() + end if + + if (bc_z%end >= 0) then + call s_mpi_reduce_beta_variables_buffers(q_beta, 3, 1, nvar) + else !< bc_x%end + $:GPU_PARALLEL_LOOP(private='[l, k]', collapse=2) + do l = beta_bc_bounds(2)%beg, beta_bc_bounds(2)%end + do k = beta_bc_bounds(1)%beg, beta_bc_bounds(1)%end + select case (bc_type(3, 2)%sf(k, l, 0)) + case (BC_PERIODIC) + call s_beta_periodic(q_beta, 3, 1, k, l, nvar) + case (BC_REFLECTIVE) + call s_beta_reflective(q_beta, 3, 1, k, l, nvar) + case default + end select + end do + end do + $:END_GPU_PARALLEL_LOOP() + end if + #:endif + + end subroutine s_populate_beta_buffers + + subroutine s_beta_periodic(q_beta, bc_dir, bc_loc, k, l, nvar) + + $:GPU_ROUTINE(function_name='s_beta_periodic', parallelism='[seq]', cray_inline=True) + type(scalar_field), dimension(num_dims + 1), intent(inout) :: q_beta + integer, intent(in) :: bc_dir, bc_loc + integer, intent(in) :: k, l + integer, intent(in) :: nvar + integer :: j, i + + if (bc_dir == 1) then !< x-direction + if (bc_loc == -1) then ! bc_x%beg + do i = 1, nvar + do j = -mapCells - 1, mapCells + q_beta(beta_vars(i))%sf(j, k, l) = q_beta(beta_vars(i))%sf(j, k, l) + q_beta(beta_vars(i))%sf(m + j + 1, & + & k, l) + end do + end do + else !< bc_y%end + do i = 1, nvar + do j = -mapcells, mapcells + 1 + q_beta(beta_vars(i))%sf(m + j, k, l) = q_beta(beta_vars(i))%sf(j - 1, k, l) + end do + end do + end if + else if (bc_dir == 2) then !< y-direction + if (bc_loc == -1) then !< bc_y%beg + do i = 1, nvar + do j = -mapcells - 1, mapcells + q_beta(beta_vars(i))%sf(k, j, l) = q_beta(beta_vars(i))%sf(k, j, l) + q_beta(beta_vars(i))%sf(k, & + & n + j + 1, l) + end do + end do + else !< bc_z%end + do i = 1, nvar + do j = -mapcells, mapcells + 1 + q_beta(beta_vars(i))%sf(k, n + j, l) = q_beta(beta_vars(i))%sf(k, j - 1, l) + end do + end do + end if + else if (bc_dir == 3) then !< z-direction + if (bc_loc == -1) then !< bc_z%beg + do i = 1, nvar + do j = -mapcells - 1, mapcells + q_beta(beta_vars(i))%sf(k, l, j) = q_beta(beta_vars(i))%sf(k, l, j) + q_beta(beta_vars(i))%sf(k, l, & + & p + j + 1) + end do + end do + else + do i = 1, nvar + do j = -mapcells, mapcells + 1 + q_beta(beta_vars(i))%sf(k, l, p + j) = q_beta(beta_vars(i))%sf(k, l, j - 1) + end do + end do + end if + end if + + end subroutine s_beta_periodic + + subroutine s_beta_extrapolation(q_beta, bc_dir, bc_loc, k, l, nvar) + + $:GPU_ROUTINE(function_name='s_beta_extrapolation', parallelism='[seq]', cray_inline=True) + type(scalar_field), dimension(num_dims + 1), intent(inout) :: q_beta + integer, intent(in) :: bc_dir, bc_loc + integer, intent(in) :: k, l + integer, intent(in) :: nvar + integer :: j, i + + ! Set beta in buffer regions equal to zero + + if (bc_dir == 1) then !< x-direction + if (bc_loc == -1) then ! bc_x%beg + do i = 1, nvar + do j = 1, buff_size + q_beta(beta_vars(i))%sf(-j, k, l) = 0._wp + end do + end do + else !< bc_x%end + do i = 1, nvar + do j = 1, buff_size + q_beta(beta_vars(i))%sf(m + j, k, l) = 0._wp + end do + end do + end if + else if (bc_dir == 2) then !< y-direction + if (bc_loc == -1) then !< bc_y%beg + do i = 1, nvar + do j = 1, buff_size + q_beta(beta_vars(i))%sf(k, -j, l) = 0._wp + end do + end do + else + do i = 1, nvar + do j = 1, buff_size + q_beta(beta_vars(i))%sf(k, n + j, l) = 0._wp + end do + end do + end if + else if (bc_dir == 3) then !< z-direction + if (bc_loc == -1) then !< bc_z%beg + do i = 1, nvar + do j = 1, buff_size + q_beta(beta_vars(i))%sf(k, l, -j) = 0._wp + end do + end do + else + do i = 1, nvar + do j = 1, buff_size + q_beta(beta_vars(i))%sf(k, l, p + j) = 0._wp + end do + end do + end if + end if + + end subroutine s_beta_extrapolation + + subroutine s_beta_reflective(q_beta, bc_dir, bc_loc, k, l, nvar) + + $:GPU_ROUTINE(function_name='s_beta_reflective', parallelism='[seq]', cray_inline=True) + type(scalar_field), dimension(num_dims + 1), intent(inout) :: q_beta + integer, intent(in) :: bc_dir, bc_loc + integer, intent(in) :: k, l + integer, intent(in) :: nvar + integer :: j, i + + ! Reflective BC for void fraction: 1) Fold ghost-cell contributions back onto their mirror interior cells 2) Set ghost cells + ! = mirror of (now-folded) interior values + + if (bc_dir == 1) then !< x-direction + if (bc_loc == -1) then ! bc_x%beg + do i = 1, nvar + do j = 1, mapCells + 1 + q_beta(beta_vars(i))%sf(j - 1, k, l) = q_beta(beta_vars(i))%sf(j - 1, k, l) + q_beta(beta_vars(i))%sf(-j, & + & k, l) + end do + do j = 1, mapCells + 1 + q_beta(beta_vars(i))%sf(-j, k, l) = q_beta(beta_vars(i))%sf(j - 1, k, l) + end do + end do + else !< bc_y%end + do i = 1, nvar + do j = 1, mapCells + 1 + q_beta(beta_vars(i))%sf(m - (j - 1), k, l) = q_beta(beta_vars(i))%sf(m - (j - 1), k, & + & l) + q_beta(beta_vars(i))%sf(m + j, k, l) + end do + do j = 1, mapCells + 1 + q_beta(beta_vars(i))%sf(m + j, k, l) = q_beta(beta_vars(i))%sf(m - (j - 1), k, l) + end do + end do + end if + else if (bc_dir == 2) then !< y-direction + if (bc_loc == -1) then !< bc_y%beg + do i = 1, nvar + do j = 1, mapCells + 1 + q_beta(beta_vars(i))%sf(k, j - 1, l) = q_beta(beta_vars(i))%sf(k, j - 1, l) + q_beta(beta_vars(i))%sf(k, & + & -j, l) + end do + do j = 1, mapCells + 1 + q_beta(beta_vars(i))%sf(k, -j, l) = q_beta(beta_vars(i))%sf(k, j - 1, l) + end do + end do + else + do i = 1, nvar + do j = 1, mapCells + 1 + q_beta(beta_vars(i))%sf(k, n - (j - 1), l) = q_beta(beta_vars(i))%sf(k, n - (j - 1), & + & l) + q_beta(beta_vars(i))%sf(k, n + j, l) + end do + do j = 1, mapCells + 1 + q_beta(beta_vars(i))%sf(k, n + j, l) = q_beta(beta_vars(i))%sf(k, n - (j - 1), l) + end do + end do + end if + else if (bc_dir == 3) then !< z-direction + if (bc_loc == -1) then !< bc_z%beg + do i = 1, nvar + do j = 1, mapCells + 1 + q_beta(beta_vars(i))%sf(k, l, j - 1) = q_beta(beta_vars(i))%sf(k, l, j - 1) + q_beta(beta_vars(i))%sf(k, & + & l, -j) + end do + do j = 1, mapCells + 1 + q_beta(beta_vars(i))%sf(k, l, -j) = q_beta(beta_vars(i))%sf(k, l, j - 1) + end do + end do + else + do i = 1, nvar + do j = 1, mapCells + 1 + q_beta(beta_vars(i))%sf(k, l, p - (j - 1)) = q_beta(beta_vars(i))%sf(k, l, & + & p - (j - 1)) + q_beta(beta_vars(i))%sf(k, l, p + j) + end do + do j = 1, mapCells + 1 + q_beta(beta_vars(i))%sf(k, l, p + j) = q_beta(beta_vars(i))%sf(k, l, p - (j - 1)) + end do + end do + end if + end if + + end subroutine s_beta_reflective + + !> @brief Populates ghost cell buffers for the color function and its divergence used in capillary surface tension. impure subroutine s_populate_capillary_buffers(c_divs, bc_type) type(scalar_field), dimension(num_dims + 1), intent(inout) :: c_divs @@ -1051,7 +1396,7 @@ contains if (bc_x%beg >= 0) then call s_mpi_sendrecv_variables_buffers(c_divs, 1, -1, num_dims + 1) - else + else !< bc_z%end $:GPU_PARALLEL_LOOP(private='[l, k]', collapse=2) do l = 0, p do k = 0, n @@ -1093,7 +1438,7 @@ contains !> y-direction if (bc_y%beg >= 0) then call s_mpi_sendrecv_variables_buffers(c_divs, 2, -1, num_dims + 1) - else + else !< bc_x%end $:GPU_PARALLEL_LOOP(private='[l, k]', collapse=2) do l = 0, p do k = -buff_size, m + buff_size @@ -1112,7 +1457,7 @@ contains if (bc_y%end >= 0) then call s_mpi_sendrecv_variables_buffers(c_divs, 2, 1, num_dims + 1) - else + else !< bc_y%end $:GPU_PARALLEL_LOOP(private='[l, k]', collapse=2) do l = 0, p do k = -buff_size, m + buff_size @@ -1136,7 +1481,7 @@ contains !> z-direction if (bc_z%beg >= 0) then call s_mpi_sendrecv_variables_buffers(c_divs, 3, -1, num_dims + 1) - else + else !< bc_z%end $:GPU_PARALLEL_LOOP(private='[l, k]', collapse=2) do l = -buff_size, n + buff_size do k = -buff_size, m + buff_size @@ -1175,7 +1520,7 @@ contains end subroutine s_populate_capillary_buffers - !> Apply periodic boundary conditions to the color function and its divergence fields. + !> @brief Applies periodic boundary conditions to the color function and its divergence fields. subroutine s_color_function_periodic(c_divs, bc_dir, bc_loc, k, l) $:GPU_ROUTINE(function_name='s_color_function_periodic', parallelism='[seq]', cray_inline=True) @@ -1191,7 +1536,7 @@ contains c_divs(i)%sf(-j, k, l) = c_divs(i)%sf(m - (j - 1), k, l) end do end do - else !< bc_x%end + else do i = 1, num_dims + 1 do j = 1, buff_size c_divs(i)%sf(m + j, k, l) = c_divs(i)%sf(j - 1, k, l) @@ -1205,7 +1550,7 @@ contains c_divs(i)%sf(k, -j, l) = c_divs(i)%sf(k, n - (j - 1), l) end do end do - else !< bc_y%end + else do i = 1, num_dims + 1 do j = 1, buff_size c_divs(i)%sf(k, n + j, l) = c_divs(i)%sf(k, j - 1, l) @@ -1219,7 +1564,7 @@ contains c_divs(i)%sf(k, l, -j) = c_divs(i)%sf(k, l, p - (j - 1)) end do end do - else !< bc_z%end + else do i = 1, num_dims + 1 do j = 1, buff_size c_divs(i)%sf(k, l, p + j) = c_divs(i)%sf(k, l, j - 1) @@ -1230,7 +1575,7 @@ contains end subroutine s_color_function_periodic - !> Apply reflective boundary conditions to the color function and its divergence fields. + !> @brief Applies reflective boundary conditions to the color function and its divergence fields. subroutine s_color_function_reflective(c_divs, bc_dir, bc_loc, k, l) $:GPU_ROUTINE(function_name='s_color_function_reflective', parallelism='[seq]', cray_inline=True) @@ -1250,7 +1595,7 @@ contains end if end do end do - else !< bc_x%end + else do i = 1, num_dims + 1 do j = 1, buff_size if (i == bc_dir) then @@ -1309,7 +1654,7 @@ contains end subroutine s_color_function_reflective - !> Extrapolate the color function and its divergence into ghost cells by copying boundary values. + !> @brief Extrapolates the color function and its divergence into ghost cells by copying boundary values. subroutine s_color_function_ghost_cell_extrapolation(c_divs, bc_dir, bc_loc, k, l) $:GPU_ROUTINE(function_name='s_color_function_ghost_cell_extrapolation', parallelism='[seq]', cray_inline=True) @@ -1364,7 +1709,7 @@ contains end subroutine s_color_function_ghost_cell_extrapolation - !> Populate ghost cell buffers for the Jacobian scalar field used in the IGR elliptic solver. + !> @brief Populates ghost cell buffers for the Jacobian scalar field used in the IGR elliptic solver. impure subroutine s_populate_F_igr_buffers(bc_type, jac_sf) type(integer_field), dimension(1:num_dims,1:2), intent(in) :: bc_type @@ -1531,7 +1876,7 @@ contains end subroutine s_populate_F_igr_buffers - !> Create MPI derived datatypes for boundary condition type arrays and buffer arrays used in parallel I/O. + !> @brief Creates MPI derived datatypes for boundary condition type arrays and buffer arrays used in parallel I/O. impure subroutine s_create_mpi_types(bc_type) type(integer_field), dimension(1:num_dims,1:2), intent(in) :: bc_type @@ -1566,7 +1911,7 @@ contains end subroutine s_create_mpi_types - !> Write boundary condition type and buffer data to serial (unformatted) restart files. + !> @brief Writes boundary condition type and buffer data to serial (unformatted) restart files. subroutine s_write_serial_boundary_condition_files(q_prim_vf, bc_type, step_dirpath, old_grid_in) type(scalar_field), dimension(sys_size), intent(in) :: q_prim_vf @@ -1605,7 +1950,7 @@ contains end subroutine s_write_serial_boundary_condition_files - !> Write boundary condition type and buffer data to per-rank parallel files using MPI I/O. + !> @brief Writes boundary condition type and buffer data to per-rank parallel files using MPI I/O. subroutine s_write_parallel_boundary_condition_files(q_prim_vf, bc_type) type(scalar_field), dimension(sys_size), intent(in) :: q_prim_vf @@ -1670,7 +2015,7 @@ contains end subroutine s_write_parallel_boundary_condition_files - !> Read boundary condition type and buffer data from serial (unformatted) restart files. + !> @brief Reads boundary condition type and buffer data from serial (unformatted) restart files. subroutine s_read_serial_boundary_condition_files(step_dirpath, bc_type) character(LEN=*), intent(in) :: step_dirpath @@ -1715,7 +2060,7 @@ contains end subroutine s_read_serial_boundary_condition_files - !> Read boundary condition type and buffer data from per-rank parallel files using MPI I/O. + !> @brief Reads boundary condition type and buffer data from per-rank parallel files using MPI I/O. subroutine s_read_parallel_boundary_condition_files(bc_type) type(integer_field), dimension(1:num_dims,1:2), intent(inout) :: bc_type @@ -1780,7 +2125,7 @@ contains end subroutine s_read_parallel_boundary_condition_files - !> Pack primitive variable boundary slices into bc_buffers arrays for serialization. + !> @brief Packs primitive variable boundary slices into bc_buffers arrays for serialization. subroutine s_pack_boundary_condition_buffers(q_prim_vf) type(scalar_field), dimension(sys_size), intent(in) :: q_prim_vf @@ -1823,7 +2168,7 @@ contains end subroutine s_pack_boundary_condition_buffers - !> Initialize the per-cell boundary condition type arrays with the global default BC values. + !> @brief Initializes the per-cell boundary condition type arrays with the global default BC values. subroutine s_assign_default_bc_type(bc_type) type(integer_field), dimension(1:num_dims,1:2), intent(in) :: bc_type @@ -1849,8 +2194,8 @@ contains end subroutine s_assign_default_bc_type - !> Populate the buffers of the grid variables, which are constituted of the cell-boundary locations and cell-width - !! distributions, based on the boundary conditions. + !> The purpose of this subroutine is to populate the buffers of the grid variables, which are constituted of the cell- boundary + !! locations and cell-width distributions, based on the boundary conditions. subroutine s_populate_grid_variables_buffers integer :: i @@ -1858,10 +2203,33 @@ contains #ifdef MFC_SIMULATION ! Required for compatibility between codes type(int_bounds_info) :: offset_x, offset_y, offset_z - offset_x%beg = buff_size; offset_x%end = buff_size offset_y%beg = buff_size; offset_y%end = buff_size offset_z%beg = buff_size; offset_z%end = buff_size + +#ifdef MFC_MPI + ! Populate global domain boundaries with stretched grids + call s_mpi_allreduce_min(x_cb(-1), glb_bounds(1)%beg) + call s_mpi_allreduce_max(x_cb(m), glb_bounds(1)%end) + + if (n > 0) then + call s_mpi_allreduce_min(y_cb(-1), glb_bounds(2)%beg) + call s_mpi_allreduce_max(y_cb(n), glb_bounds(2)%end) + if (p > 0) then + call s_mpi_allreduce_min(z_cb(-1), glb_bounds(3)%beg) + call s_mpi_allreduce_max(z_cb(p), glb_bounds(3)%end) + end if + end if +#else + glb_bounds(1)%beg = x_cb(-1); glb_bounds(1)%end = x_cb(m) + if (n > 0) then + glb_bounds(2)%beg = y_cb(-1); glb_bounds(2)%end = y_cb(n) + if (p > 0) then + glb_bounds(3)%beg = z_cb(-1); glb_bounds(3)%end = z_cb(p) + end if + end if +#endif + $:GPU_UPDATE(device='[glb_bounds]') #endif #ifndef MFC_PRE_PROCESS @@ -1918,6 +2286,7 @@ contains do i = 1, buff_size x_cc(m + i) = x_cc(m + (i - 1)) + (dx(m + (i - 1)) + dx(m + i))/2._wp end do + ! END: Population of Buffers in x-direction ! Population of Buffers in y-direction @@ -1974,6 +2343,7 @@ contains do i = 1, buff_size y_cc(n + i) = y_cc(n + (i - 1)) + (dy(n + (i - 1)) + dy(n + i))/2._wp end do + ! END: Population of Buffers in y-direction ! Population of Buffers in z-direction @@ -2030,11 +2400,12 @@ contains do i = 1, buff_size z_cc(p + i) = z_cc(p + (i - 1)) + (dz(p + (i - 1)) + dz(p + i))/2._wp end do + ! END: Population of Buffers in z-direction #endif end subroutine s_populate_grid_variables_buffers - !> Deallocate boundary condition buffer arrays allocated during module initialization. + !> @brief Deallocates boundary condition buffer arrays allocated during module initialization. subroutine s_finalize_boundary_common_module() if (bc_io) then diff --git a/src/common/m_derived_types.fpp b/src/common/m_derived_types.fpp index 0c00de90d7..b7e78c8f06 100644 --- a/src/common/m_derived_types.fpp +++ b/src/common/m_derived_types.fpp @@ -396,18 +396,31 @@ module m_derived_types !> Lagrangian bubble parameters type bubbles_lagrange_parameters - integer :: solver_approach !< 1: One-way coupling, 2: two-way coupling - integer :: cluster_type !< Cluster model to find p_inf - logical :: pressure_corrector !< Cell pressure correction term - integer :: smooth_type !< Smoothing function. 1: Gaussian, 2:Delta 3x3 - logical :: heatTransfer_model !< Activate HEAT transfer model at the bubble-liquid interface - logical :: massTransfer_model !< Activate MASS transfer model at the bubble-liquid interface - logical :: write_bubbles !< Write files to track the bubble evolution each time step - logical :: write_bubbles_stats !< Write the maximum and minimum radius of each bubble - integer :: nBubs_glb !< Global number of bubbles - real(wp) :: epsilonb !< Standard deviation scaling for the gaussian function - real(wp) :: charwidth !< Domain virtual depth (z direction, for 2D simulations) - real(wp) :: valmaxvoid !< Maximum void fraction permitted + integer :: solver_approach !< 1: One-way coupling, 2: two-way coupling + integer :: cluster_type !< Cluster model to find p_inf + logical :: pressure_corrector !< Cell pressure correction term + integer :: smooth_type !< Smoothing function. 1: Gaussian, 2:Delta 3x3 + logical :: heatTransfer_model !< Activate HEAT transfer model at the bubble-liquid interface + logical :: massTransfer_model !< Activate MASS transfer model at the bubble-liquid interface + logical :: write_bubbles !< Write files to track the bubble evolution each time step + logical :: write_bubbles_stats !< Write the maximum and minimum radius of each bubble + integer :: nBubs_glb !< Global number of bubbles + real(wp) :: epsilonb !< Standard deviation scaling for the gaussian function + real(wp) :: charwidth !< Domain virtual depth (z direction, for 2D simulations) + real(wp) :: valmaxvoid !< Maximum void fraction permitted + logical :: write_void_evol !< Write files to track evolution of void fraction at each time step + integer :: nParticles_glb !< Global number of particles + integer :: vel_model !< Particle velocity model + integer :: drag_model !< Particle drag model + logical :: pressure_force !< Include pressure force translational motion + logical :: gravity_force !< Include gravity force in translational motion + integer :: qs_drag_model !< Particle QS drag model + integer :: stokes_drag !< Particle stokes drag + integer :: added_mass_model !< Particle added mass model + integer :: interpolation_order !< Fluid-to-Particle barycentric interpolation order + logical :: collision_force !< Include collision forces + character(LEN=pathlen_max) :: input_path !< Path to lag_bubbles.dat + integer :: charNz !< Number of grid cells in characteristic depth end type bubbles_lagrange_parameters !> Max and min number of cells in a direction of each combination of x-,y-, and z- diff --git a/src/common/m_helper.fpp b/src/common/m_helper.fpp index 4074530a8f..af79f2c730 100644 --- a/src/common/m_helper.fpp +++ b/src/common/m_helper.fpp @@ -18,7 +18,7 @@ module m_helper public :: s_comp_n_from_prim, s_comp_n_from_cons, s_initialize_bubbles_model, s_initialize_nonpoly, s_simpson, s_transcoeff, & & s_int_to_str, s_transform_vec, s_transform_triangle, s_transform_model, s_swap, f_cross, f_create_transform_matrix, & & f_create_bbox, s_print_2D_array, f_xor, f_logical_to_int, associated_legendre, real_ylm, double_factorial, factorial, & - & f_cut_on, f_cut_off, s_downsample_data, s_upsample_data + & f_cut_on, f_cut_off, s_downsample_data, s_upsample_data, s_initialize_particles_model contains @@ -83,6 +83,13 @@ contains end subroutine s_print_2D_array !> Initialize bubble model arrays for Euler or Lagrangian bubbles with polytropic or non-polytropic gas. + impure subroutine s_initialize_particles_model() + + rho0ref_particle = particle_pp%rho0ref_particle + cp_particle = particle_pp%cp_particle + + end subroutine s_initialize_particles_model + impure subroutine s_initialize_bubbles_model() ! Allocate memory diff --git a/src/common/m_helper_basic.fpp b/src/common/m_helper_basic.fpp index 7208a451da..5f3eaca98b 100644 --- a/src/common/m_helper_basic.fpp +++ b/src/common/m_helper_basic.fpp @@ -101,14 +101,13 @@ contains !> Compute ghost-cell buffer size and set interior/buffered coordinate index bounds. subroutine s_configure_coordinate_bounds(recon_type, weno_polyn, muscl_polyn, igr_order, buff_size, idwint, idwbuff, viscous, & - - & bubbles_lagrange, m, n, p, num_dims, igr, ib) + & bubbles_lagrange, particles_lagrange, m, n, p, num_dims, igr, ib, fd_number) integer, intent(in) :: recon_type, weno_polyn, muscl_polyn - integer, intent(in) :: m, n, p, num_dims, igr_order + integer, intent(in) :: m, n, p, num_dims, igr_order, fd_number integer, intent(inout) :: buff_size type(int_bounds_info), dimension(3), intent(inout) :: idwint, idwbuff - logical, intent(in) :: viscous, bubbles_lagrange + logical, intent(in) :: viscous, bubbles_lagrange, particles_lagrange logical, intent(in) :: igr logical, intent(in) :: ib @@ -128,7 +127,12 @@ contains ! Correction for smearing function in the lagrangian subgrid bubble model if (bubbles_lagrange) then - buff_size = max(buff_size, 6) + buff_size = max(buff_size + fd_number, mapCells + 1 + fd_number) + end if + + ! Correction for smearing function in the lagrangian subgrid particle model + if (particles_lagrange) then + buff_size = max(buff_size + fd_number, mapCells + 1 + fd_number) end if if (ib) then diff --git a/src/common/m_mpi_common.fpp b/src/common/m_mpi_common.fpp index 8a719f5758..fd18eaad4b 100644 --- a/src/common/m_mpi_common.fpp +++ b/src/common/m_mpi_common.fpp @@ -25,6 +25,11 @@ module m_mpi_common real(wp), private, allocatable, dimension(:) :: buff_send !< Primitive variable send buffer for halo exchange real(wp), private, allocatable, dimension(:) :: buff_recv !< Primitive variable receive buffer for halo exchange + type(int_bounds_info) :: comm_coords(3) + integer :: comm_size(3) + $:GPU_DECLARE(create='[comm_coords, comm_size]') + !! Variables for EL bubbles communication + #ifndef __NVCOMPILER_GPU_UNIFIED_MEM $:GPU_DECLARE(create='[buff_send, buff_recv]') #endif @@ -37,6 +42,8 @@ contains !> Initialize the module. impure subroutine s_initialize_mpi_common_module + integer :: beta_v_size, beta_comm_size_1, beta_comm_size_2, beta_comm_size_3, beta_halo_size + #ifdef MFC_MPI ! Allocating buff_send/recv and. Please note that for the sake of simplicity, both variables are provided sufficient storage ! to hold the largest buffer in the computational domain. @@ -58,6 +65,24 @@ contains halo_size = -1 + buff_size*(v_size) end if + if (bubbles_lagrange .or. particles_lagrange) then + beta_v_size = size(beta_vars) + beta_comm_size_1 = m + 2*mapCells + 3 + beta_comm_size_2 = merge(n + 2*mapCells + 3, 1, n > 0) + beta_comm_size_3 = merge(p + 2*mapCells + 3, 1, p > 0) + if (n > 0) then + if (p > 0) then + beta_halo_size = 2*(mapCells + 1)*beta_v_size*max(beta_comm_size_2*beta_comm_size_3, & + & beta_comm_size_1*beta_comm_size_3, beta_comm_size_1*beta_comm_size_2) - 1 + else + beta_halo_size = 2*(mapCells + 1)*beta_v_size*max(beta_comm_size_2, beta_comm_size_1) - 1 + end if + else + beta_halo_size = 2*(mapCells + 1)*beta_v_size - 1 + end if + halo_size = max(halo_size, beta_halo_size) + end if + $:GPU_UPDATE(device='[halo_size, v_size]') #ifndef __NVCOMPILER_GPU_UNIFIED_MEM @@ -286,40 +311,65 @@ contains !! performed by sifting through the local extrema of each stability criterion. Note that each of the local extrema is from a !! single process, within its assigned section of the computational domain. Finally, note that the global extrema values are !! only bookkeept on the rank 0 processor. - impure subroutine s_mpi_reduce_stability_criteria_extrema(icfl_max_loc, vcfl_max_loc, Rc_min_loc, icfl_max_glb, vcfl_max_glb, & - - & Rc_min_glb) + impure subroutine s_mpi_reduce_stability_criteria_extrema(icfl_max_loc, vcfl_max_loc, Rc_min_loc, bubs_loc, icfl_max_glb, & + & vcfl_max_glb, Rc_min_glb, bubs_glb) real(wp), intent(in) :: icfl_max_loc real(wp), intent(in) :: vcfl_max_loc real(wp), intent(in) :: Rc_min_loc + integer, intent(in) :: bubs_loc real(wp), intent(out) :: icfl_max_glb real(wp), intent(out) :: vcfl_max_glb real(wp), intent(out) :: Rc_min_glb + integer, intent(out) :: bubs_glb #ifdef MFC_SIMULATION #ifdef MFC_MPI integer :: ierr !< Generic flag used to identify and report MPI errors + bubs_glb = 0 + call MPI_REDUCE(icfl_max_loc, icfl_max_glb, 1, mpi_p, MPI_MAX, 0, MPI_COMM_WORLD, ierr) if (viscous) then call MPI_REDUCE(vcfl_max_loc, vcfl_max_glb, 1, mpi_p, MPI_MAX, 0, MPI_COMM_WORLD, ierr) call MPI_REDUCE(Rc_min_loc, Rc_min_glb, 1, mpi_p, MPI_MIN, 0, MPI_COMM_WORLD, ierr) end if + + if (bubbles_lagrange) then + call MPI_REDUCE(bubs_loc, bubs_glb, 1, MPI_INTEGER, MPI_SUM, 0, MPI_COMM_WORLD, ierr) + end if #else icfl_max_glb = icfl_max_loc + bubs_glb = 0 if (viscous) then vcfl_max_glb = vcfl_max_loc Rc_min_glb = Rc_min_loc end if + + if (bubbles_lagrange) bubs_glb = bubs_loc #endif #endif end subroutine s_mpi_reduce_stability_criteria_extrema !> Reduce a local real value to its global sum across all MPI ranks. + subroutine s_mpi_reduce_int_sum(var_loc, sum) + + integer, intent(in) :: var_loc + integer, intent(out) :: sum + +#ifdef MFC_MPI + integer :: ierr !< Generic flag used to identify and report MPI errors + + call MPI_REDUCE(var_loc, sum, 1, MPI_INTEGER, MPI_SUM, 0, MPI_COMM_WORLD, ierr) +#else + sum = var_loc +#endif + + end subroutine s_mpi_reduce_int_sum + impure subroutine s_mpi_allreduce_sum(var_loc, var_glb) real(wp), intent(in) :: var_loc @@ -425,6 +475,7 @@ contains #ifdef MFC_MPI integer :: ierr !< Generic flag used to identify and report MPI errors real(wp), dimension(2) :: var_glb !< Reduced (max value, rank) pair + call MPI_REDUCE(var_loc, var_glb, 1, mpi_2p, MPI_MAXLOC, 0, MPI_COMM_WORLD, ierr) call MPI_BCAST(var_glb, 1, mpi_2p, 0, MPI_COMM_WORLD, ierr) @@ -904,6 +955,224 @@ contains end subroutine s_mpi_sendrecv_variables_buffers !> Decompose the computational domain among processors by balancing cells per rank in each coordinate direction. + !! @param q_cons_vf Cell-average conservative variables + subroutine s_mpi_reduce_beta_variables_buffers(q_comm, mpi_dir, pbc_loc, nVar) + + type(scalar_field), dimension(1:), intent(inout) :: q_comm + integer, intent(in) :: mpi_dir, pbc_loc, nVar + integer :: i, j, k, l, r, q !< Generic loop iterators + integer :: lb_size + integer :: buffer_counts(1:3), buffer_count + type(int_bounds_info) :: boundary_conditions(1:3) + integer :: beg_end(1:2), grid_dims(1:3) + integer :: dst_proc, src_proc, recv_tag, send_tag + logical :: beg_end_geq_0, qbmm_comm, replace_buff + integer :: pack_offset, unpack_offset + +#ifdef MFC_MPI + integer :: ierr !< Generic flag used to identify and report MPI errors + + call nvtxStartRange("BETA-COMM-PACKBUF") + + comm_coords(1)%beg = -mapcells - 1 + comm_coords(1)%end = m + mapcells + 1 + comm_coords(2)%beg = merge(-mapcells - 1, 0, n > 0) + comm_coords(2)%end = merge(n + mapcells + 1, n, n > 0) + comm_coords(3)%beg = merge(-mapcells - 1, 0, p > 0) + comm_coords(3)%end = merge(p + mapcells + 1, p, p > 0) + + ! Compute sizes + comm_size(1) = comm_coords(1)%end - comm_coords(1)%beg + 1 + comm_size(2) = comm_coords(2)%end - comm_coords(2)%beg + 1 + comm_size(3) = comm_coords(3)%end - comm_coords(3)%beg + 1 + + ! Buffer counts using the conditional sizes + v_size = nVar + lb_size = 2*(mapcells + 1) ! Size of the buffer region for beta variables (-mapcells - 1, mapcells) + buffer_counts = (/lb_size*v_size*comm_size(2)*comm_size(3), lb_size*v_size*comm_size(1)*comm_size(3), & + & lb_size*v_size*comm_size(1)*comm_size(2)/) + + $:GPU_UPDATE(device='[v_size, comm_coords, comm_size]') + + buffer_count = buffer_counts(mpi_dir) + boundary_conditions = (/bc_x, bc_y, bc_z/) + beg_end = (/boundary_conditions(mpi_dir)%beg, boundary_conditions(mpi_dir)%end/) + beg_end_geq_0 = beg_end(max(pbc_loc, 0) - pbc_loc + 1) >= 0 + + send_tag = f_logical_to_int(.not. f_xor(beg_end_geq_0, pbc_loc == 1)) + recv_tag = f_logical_to_int(pbc_loc == 1) + + dst_proc = beg_end(1 + f_logical_to_int(f_xor(pbc_loc == 1, beg_end_geq_0))) + src_proc = beg_end(1 + f_logical_to_int(pbc_loc == 1)) + + grid_dims = (/m, n, p/) + + pack_offset = 0 + if (f_xor(pbc_loc == 1, beg_end_geq_0)) then + pack_offset = grid_dims(mpi_dir) + 1 + end if + + unpack_offset = 0 + if (pbc_loc == 1) then + unpack_offset = grid_dims(mpi_dir) + 1 + end if + + replace_buff = .false. + if (pbc_loc == 1 .and. beg_end_geq_0) replace_buff = .true. + + #:for mpi_dir in [1, 2, 3] + if (mpi_dir == ${mpi_dir}$) then + #:if mpi_dir == 1 + $:GPU_PARALLEL_LOOP(collapse=4,private='[r]') + do l = comm_coords(3)%beg, comm_coords(3)%end + do k = comm_coords(2)%beg, comm_coords(2)%end + do j = -mapcells - 1, mapcells + do i = 1, v_size + r = (i - 1) + v_size*((j + mapcells + 1) + lb_size*((k - comm_coords(2)%beg) + comm_size(2) & + & *(l - comm_coords(3)%beg))) + buff_send(r) = real(q_comm(beta_vars(i))%sf(j + pack_offset, k, l), kind=wp) + end do + end do + end do + end do + $:END_GPU_PARALLEL_LOOP() + #:elif mpi_dir == 2 + $:GPU_PARALLEL_LOOP(collapse=4,private='[r]') + do i = 1, v_size + do l = comm_coords(3)%beg, comm_coords(3)%end + do k = -mapcells - 1, mapcells + do j = comm_coords(1)%beg, comm_coords(1)%end + r = (i - 1) + v_size*((j - comm_coords(1)%beg) + comm_size(1)*((k + mapcells + 1) & + & + lb_size*(l - comm_coords(3)%beg))) + buff_send(r) = real(q_comm(beta_vars(i))%sf(j, k + pack_offset, l), kind=wp) + end do + end do + end do + end do + $:END_GPU_PARALLEL_LOOP() + #:else + $:GPU_PARALLEL_LOOP(collapse=4,private='[r]') + do i = 1, v_size + do l = -mapcells - 1, mapcells + do k = comm_coords(2)%beg, comm_coords(2)%end + do j = comm_coords(1)%beg, comm_coords(1)%end + r = (i - 1) + v_size*((j - comm_coords(1)%beg) + comm_size(1)*((k - comm_coords(2)%beg) & + & + comm_size(2)*(l + mapcells + 1))) + buff_send(r) = real(q_comm(beta_vars(i))%sf(j, k, l + pack_offset), kind=wp) + end do + end do + end do + end do + $:END_GPU_PARALLEL_LOOP() + #:endif + end if + #:endfor + call nvtxEndRange ! Packbuf + +#ifdef MFC_SIMULATION + #:for rdma_mpi in [False, True] + if (rdma_mpi .eqv. ${'.true.' if rdma_mpi else '.false.'}$) then + #:if rdma_mpi + #:call GPU_HOST_DATA(use_device_addr='[buff_send, buff_recv]') + call nvtxStartRange("BETA-COMM-SENDRECV-RDMA") + + call MPI_SENDRECV(buff_send, buffer_count, mpi_p, dst_proc, send_tag, buff_recv, buffer_count, mpi_p, & + & src_proc, recv_tag, MPI_COMM_WORLD, MPI_STATUS_IGNORE, ierr) + + call nvtxEndRange ! Packbuf + #:endcall GPU_HOST_DATA + $:GPU_WAIT() + #:else + call nvtxStartRange("BETA-COMM-DEV2HOST") + $:GPU_UPDATE(host='[buff_send]') + call nvtxEndRange ! Packbuf + call nvtxStartRange("BETA-COMM-SENDRECV-NO-RDMA") + + call MPI_SENDRECV(buff_send, buffer_count, mpi_p, dst_proc, send_tag, buff_recv, buffer_count, mpi_p, & + & src_proc, recv_tag, MPI_COMM_WORLD, MPI_STATUS_IGNORE, ierr) + + call nvtxEndRange ! Packbuf + + call nvtxStartRange("BETA-COMM-HOST2DEV") + $:GPU_UPDATE(device='[buff_recv]') + call nvtxEndRange ! Packbuf + #:endif + end if + #:endfor +#else + call MPI_SENDRECV(buff_send, buffer_count, mpi_p, dst_proc, send_tag, buff_recv, buffer_count, mpi_p, src_proc, recv_tag, & + & MPI_COMM_WORLD, MPI_STATUS_IGNORE, ierr) +#endif + + call nvtxStartRange("BETA-COMM-UNPACKBUF") + #:for mpi_dir in [1, 2, 3] + if (mpi_dir == ${mpi_dir}$) then + #:if mpi_dir == 1 + $:GPU_PARALLEL_LOOP(collapse=4,private='[r]',copyin='[replace_buff]') + do l = comm_coords(3)%beg, comm_coords(3)%end + do k = comm_coords(2)%beg, comm_coords(2)%end + do j = -mapcells - 1, mapcells + do i = 1, v_size + r = (i - 1) + v_size*((j + mapcells + 1) + lb_size*((k - comm_coords(2)%beg) + comm_size(2) & + & *(l - comm_coords(3)%beg))) + if (replace_buff) then + q_comm(beta_vars(i))%sf(j + unpack_offset, k, l) = real(buff_recv(r), kind=stp) + else + q_comm(beta_vars(i))%sf(j + unpack_offset, k, & + & l) = q_comm(beta_vars(i))%sf(j + unpack_offset, k, l) + real(buff_recv(r), & + & kind=stp) + end if + end do + end do + end do + end do + $:END_GPU_PARALLEL_LOOP() + #:elif mpi_dir == 2 + $:GPU_PARALLEL_LOOP(collapse=4,private='[r]',copyin='[replace_buff]') + do i = 1, v_size + do l = comm_coords(3)%beg, comm_coords(3)%end + do k = -mapcells - 1, mapcells + do j = comm_coords(1)%beg, comm_coords(1)%end + r = (i - 1) + v_size*((j - comm_coords(1)%beg) + comm_size(1)*((k + mapcells + 1) & + & + lb_size*(l - comm_coords(3)%beg))) + if (replace_buff) then + q_comm(beta_vars(i))%sf(j, k + unpack_offset, l) = real(buff_recv(r), kind=stp) + else + q_comm(beta_vars(i))%sf(j, k + unpack_offset, l) = q_comm(beta_vars(i))%sf(j, & + & k + unpack_offset, l) + real(buff_recv(r), kind=stp) + end if + end do + end do + end do + end do + $:END_GPU_PARALLEL_LOOP() + #:else + $:GPU_PARALLEL_LOOP(collapse=4,private='[r]',copyin='[replace_buff]') + do i = 1, v_size + do l = -mapcells - 1, mapcells + do k = comm_coords(2)%beg, comm_coords(2)%end + do j = comm_coords(1)%beg, comm_coords(1)%end + r = (i - 1) + v_size*((j - comm_coords(1)%beg) + comm_size(1)*((k - comm_coords(2)%beg) & + & + comm_size(2)*(l + mapcells + 1))) + if (replace_buff) then + q_comm(beta_vars(i))%sf(j, k, l + unpack_offset) = real(buff_recv(r), kind=stp) + else + q_comm(beta_vars(i))%sf(j, k, l + unpack_offset) = q_comm(beta_vars(i))%sf(j, k, & + & l + unpack_offset) + real(buff_recv(r), kind=stp) + end if + end do + end do + end do + end do + $:END_GPU_PARALLEL_LOOP() + #:endif + end if + #:endfor + call nvtxEndRange ! Packbuf +#endif + + end subroutine s_mpi_reduce_beta_variables_buffers + subroutine s_mpi_decompose_computational_domain #ifdef MFC_MPI @@ -914,9 +1183,17 @@ contains integer :: MPI_COMM_CART !< Cartesian processor topology communicator integer :: rem_cells !< Remaining cells after distribution among processors integer :: recon_order !< WENO or MUSCL reconstruction order - integer :: i, j !< Generic loop iterators + integer :: i, j, k !< Generic loop iterators integer :: ierr !< Generic flag used to identify and report MPI errors + ! temp array to store neighbor rank coordinates + integer, dimension(1:num_dims) :: neighbor_coords + + ! Zeroing out communication needs for moving EL bubbles/particles + nidx(1)%beg = 0; nidx(1)%end = 0 + nidx(2)%beg = 0; nidx(2)%end = 0 + nidx(3)%beg = 0; nidx(3)%end = 0 + if (recon_type == WENO_TYPE) then recon_order = weno_order else @@ -1069,6 +1346,7 @@ contains proc_coords(3) = proc_coords(3) - 1 call MPI_CART_RANK(MPI_COMM_CART, proc_coords, bc_z%beg, ierr) proc_coords(3) = proc_coords(3) + 1 + nidx(3)%beg = -1 end if ! Boundary condition at the end @@ -1076,6 +1354,7 @@ contains proc_coords(3) = proc_coords(3) + 1 call MPI_CART_RANK(MPI_COMM_CART, proc_coords, bc_z%end, ierr) proc_coords(3) = proc_coords(3) - 1 + nidx(3)%end = 1 end if #ifdef MFC_POST_PROCESS @@ -1181,6 +1460,7 @@ contains proc_coords(2) = proc_coords(2) - 1 call MPI_CART_RANK(MPI_COMM_CART, proc_coords, bc_y%beg, ierr) proc_coords(2) = proc_coords(2) + 1 + nidx(2)%beg = -1 end if ! Boundary condition at the end @@ -1188,6 +1468,7 @@ contains proc_coords(2) = proc_coords(2) + 1 call MPI_CART_RANK(MPI_COMM_CART, proc_coords, bc_y%end, ierr) proc_coords(2) = proc_coords(2) - 1 + nidx(2)%end = 1 end if #ifdef MFC_POST_PROCESS @@ -1264,6 +1545,7 @@ contains proc_coords(1) = proc_coords(1) - 1 call MPI_CART_RANK(MPI_COMM_CART, proc_coords, bc_x%beg, ierr) proc_coords(1) = proc_coords(1) + 1 + nidx(1)%beg = -1 end if ! Boundary condition at the end @@ -1271,20 +1553,21 @@ contains proc_coords(1) = proc_coords(1) + 1 call MPI_CART_RANK(MPI_COMM_CART, proc_coords, bc_x%end, ierr) proc_coords(1) = proc_coords(1) - 1 + nidx(1)%end = 1 end if #ifdef MFC_POST_PROCESS ! Ghost zone at the beginning if (proc_coords(1) > 0 .and. format == 1) then offset_x%beg = 2 - else + else ! PBC at the beginning only offset_x%beg = 0 end if ! Ghost zone at the end if (proc_coords(1) < num_procs_x - 1 .and. format == 1) then offset_x%end = 2 - else + else ! PBC at the end offset_x%end = 0 end if #endif @@ -1293,10 +1576,10 @@ contains if (parallel_io) then if (proc_coords(1) < rem_cells) then start_idx(1) = (m + 1)*proc_coords(1) - else + else ! PBC at the end only start_idx(1) = (m + 1)*proc_coords(1) + rem_cells end if - else + else ! PBC at the beginning only #ifdef MFC_PRE_PROCESS if (old_grid .neqv. .true.) then dx = (x_domain%end - x_domain%beg)/real(m_glb + 1, wp) @@ -1304,13 +1587,27 @@ contains if (proc_coords(1) < rem_cells) then x_domain%beg = x_domain%beg + dx*real((m + 1)*proc_coords(1)) x_domain%end = x_domain%end - dx*real((m + 1)*(num_procs_x - proc_coords(1) - 1) - (num_procs_x - rem_cells)) - else + else ! PBC at the end x_domain%beg = x_domain%beg + dx*real((m + 1)*proc_coords(1) + rem_cells) x_domain%end = x_domain%end - dx*real((m + 1)*(num_procs_x - proc_coords(1) - 1)) end if end if #endif end if + + @:ALLOCATE(neighbor_ranks(nidx(1)%beg:nidx(1)%end, nidx(2)%beg:nidx(2)%end, nidx(3)%beg:nidx(3)%end)) + do k = nidx(3)%beg, nidx(3)%end + do j = nidx(2)%beg, nidx(2)%end + do i = nidx(1)%beg, nidx(1)%end + if (abs(i) + abs(j) + abs(k) > 0) then + neighbor_coords(1) = proc_coords(1) + i + if (num_dims > 1) neighbor_coords(2) = proc_coords(2) + j + if (num_dims > 2) neighbor_coords(3) = proc_coords(3) + k + call MPI_CART_RANK(MPI_COMM_CART, neighbor_coords, neighbor_ranks(i, j, k), ierr) + end if + end do + end do + end do #endif end subroutine s_mpi_decompose_computational_domain @@ -1333,15 +1630,15 @@ contains if (bc_x%end >= 0) then ! PBC at the beginning and end call MPI_SENDRECV(dx(m - buff_size + 1), buff_size, mpi_p, bc_x%end, 0, dx(-buff_size), buff_size, mpi_p, & & bc_x%beg, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE, ierr) - else ! PBC at the beginning only + else ! PBC at the end only call MPI_SENDRECV(dx(0), buff_size, mpi_p, bc_x%beg, 1, dx(-buff_size), buff_size, mpi_p, bc_x%beg, 0, & & MPI_COMM_WORLD, MPI_STATUS_IGNORE, ierr) end if - else ! PBC at the end + else if (bc_x%beg >= 0) then ! PBC at the end and beginning call MPI_SENDRECV(dx(0), buff_size, mpi_p, bc_x%beg, 1, dx(m + 1), buff_size, mpi_p, bc_x%end, 1, & & MPI_COMM_WORLD, MPI_STATUS_IGNORE, ierr) - else ! PBC at the end only + else ! PBC at the beginning only call MPI_SENDRECV(dx(m - buff_size + 1), buff_size, mpi_p, bc_x%end, 0, dx(m + 1), buff_size, mpi_p, & & bc_x%end, 1, MPI_COMM_WORLD, MPI_STATUS_IGNORE, ierr) end if @@ -1352,15 +1649,15 @@ contains if (bc_y%end >= 0) then ! PBC at the beginning and end call MPI_SENDRECV(dy(n - buff_size + 1), buff_size, mpi_p, bc_y%end, 0, dy(-buff_size), buff_size, mpi_p, & & bc_y%beg, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE, ierr) - else ! PBC at the beginning only + else ! PBC at the end call MPI_SENDRECV(dy(0), buff_size, mpi_p, bc_y%beg, 1, dy(-buff_size), buff_size, mpi_p, bc_y%beg, 0, & & MPI_COMM_WORLD, MPI_STATUS_IGNORE, ierr) end if - else ! PBC at the end + else ! PBC at the end only if (bc_y%beg >= 0) then ! PBC at the end and beginning call MPI_SENDRECV(dy(0), buff_size, mpi_p, bc_y%beg, 1, dy(n + 1), buff_size, mpi_p, bc_y%end, 1, & & MPI_COMM_WORLD, MPI_STATUS_IGNORE, ierr) - else ! PBC at the end only + else call MPI_SENDRECV(dy(n - buff_size + 1), buff_size, mpi_p, bc_y%end, 0, dy(n + 1), buff_size, mpi_p, & & bc_y%end, 1, MPI_COMM_WORLD, MPI_STATUS_IGNORE, ierr) end if @@ -1371,15 +1668,15 @@ contains if (bc_z%end >= 0) then ! PBC at the beginning and end call MPI_SENDRECV(dz(p - buff_size + 1), buff_size, mpi_p, bc_z%end, 0, dz(-buff_size), buff_size, mpi_p, & & bc_z%beg, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE, ierr) - else ! PBC at the beginning only + else call MPI_SENDRECV(dz(0), buff_size, mpi_p, bc_z%beg, 1, dz(-buff_size), buff_size, mpi_p, bc_z%beg, 0, & & MPI_COMM_WORLD, MPI_STATUS_IGNORE, ierr) end if - else ! PBC at the end + else if (bc_z%beg >= 0) then ! PBC at the end and beginning call MPI_SENDRECV(dz(0), buff_size, mpi_p, bc_z%beg, 1, dz(p + 1), buff_size, mpi_p, bc_z%end, 1, & & MPI_COMM_WORLD, MPI_STATUS_IGNORE, ierr) - else ! PBC at the end only + else call MPI_SENDRECV(dz(p - buff_size + 1), buff_size, mpi_p, bc_z%end, 0, dz(p + 1), buff_size, mpi_p, & & bc_z%end, 1, MPI_COMM_WORLD, MPI_STATUS_IGNORE, ierr) end if diff --git a/src/post_process/m_global_parameters.fpp b/src/post_process/m_global_parameters.fpp index 0530c31081..212449b90f 100644 --- a/src/post_process/m_global_parameters.fpp +++ b/src/post_process/m_global_parameters.fpp @@ -26,6 +26,7 @@ module m_global_parameters ! Computational Domain Parameters integer :: proc_rank !< Rank of the local processor + !> @name Number of cells in the x-, y- and z-coordinate directions !> @{ integer :: m, m_root @@ -50,6 +51,7 @@ module m_global_parameters integer :: num_dims !< Number of spatial dimensions integer :: num_vels !< Number of velocity components (different from num_dims for mhd) + !> @name Cell-boundary locations in the x-, y- and z-coordinate directions !> @{ real(wp), allocatable, dimension(:) :: x_cb, x_root_cb, y_cb, z_cb @@ -66,10 +68,14 @@ module m_global_parameters real(wp), allocatable, dimension(:) :: dx, dy, dz !> @} - integer :: buff_size !< Number of ghost cells for boundary condition storage - integer :: t_step_start !< First time-step directory - integer :: t_step_stop !< Last time-step directory - integer :: t_step_save !< Interval between consecutive time-step directory + !> Number of cells in buffer region. For the variables which feature a buffer region, this region is used to store information + !! outside the computational domain based on the boundary conditions. + integer :: buff_size !< Number of ghost cells for boundary condition storage + integer, allocatable :: beta_vars(:) !< Indices of variables to communicate for bubble/particle coupling + integer :: t_step_start !< First time-step directory + integer :: t_step_stop !< Last time-step directory + integer :: t_step_save !< Interval between consecutive time-step directory + !> @name IO options for adaptive time-stepping !> @{ logical :: cfl_adap_dt, cfl_const_dt, cfl_dt @@ -80,7 +86,8 @@ module m_global_parameters integer :: n_start !> @} - ! NOTE: m_root, x_root_cb, x_root_cc = defragmented grid (1D only; equals m, x_cb, x_cc in serial) + ! NOTE: The variables m_root, x_root_cb and x_root_cc contain the grid data of the defragmented computational domain. They are + ! only used in 1D. For serial simulations, they are equal to m, x_cb and x_cc, respectively. !> @name Simulation Algorithm Parameters !> @{ @@ -110,6 +117,7 @@ module m_global_parameters !> @} integer :: avg_state !< Average state evaluation method + !> @name Annotations of the structure, i.e. the organization, of the state vectors !> @{ type(int_bounds_info) :: cont_idx !< Indexes of first & last continuity eqns. @@ -135,7 +143,8 @@ module m_global_parameters ! Cell Indices for the (local) interior points (O-m, O-n, 0-p). Stands for "InDices With BUFFer". type(int_bounds_info) :: idwint(1:3) - ! Cell indices (InDices With BUFFer): includes buffer in simulation only + ! Cell Indices for the entire (local) domain. In simulation, this includes the buffer region. idwbuff and idwint are the same + ! otherwise. Stands for "InDices With BUFFer". type(int_bounds_info) :: idwbuff(1:3) integer :: num_bc_patches logical :: bc_io @@ -144,16 +153,23 @@ module m_global_parameters type(int_bounds_info) :: bc_x, bc_y, bc_z !> @} - integer :: shear_num !< Number of shear stress components - integer, dimension(3) :: shear_indices !< Indices of the stress components that represent shear stress - integer :: shear_BC_flip_num !< Number of shear stress components to reflect for boundary conditions - integer, dimension(3, 2) :: shear_BC_flip_indices !< Shear stress BC reflection indices (1:3, 1:shear_BC_flip_num) - logical :: parallel_io !< Format of the data files - logical :: sim_data - logical :: file_per_process !< output format - integer, allocatable, dimension(:) :: proc_coords !< Processor coordinates in MPI_CART_COMM + integer :: shear_num !< Number of shear stress components + integer, dimension(3) :: shear_indices !< Indices of the stress components that represent shear stress + integer :: shear_BC_flip_num !< Number of shear stress components to reflect for boundary conditions + !> Indices of shear stress components to reflect for boundary conditions. Size: (1:3, 1:shear_BC_flip_num) for (x/y/z, + !! [indices]) + integer, dimension(3, 2) :: shear_BC_flip_indices !< Shear stress BC reflection indices (1:3, 1:shear_BC_flip_num) + logical :: parallel_io !< Format of the data files + logical :: sim_data + logical :: file_per_process !< output format + integer, allocatable, dimension(:) :: proc_coords !< Processor coordinates in MPI_CART_COMM + type(int_bounds_info), dimension(3) :: nidx + integer, allocatable, dimension(:,:,:) :: neighbor_ranks + !! Neighbor processor ranks + integer, allocatable, dimension(:) :: start_idx !< Starting cell-center index of local processor in global grid - integer :: num_ibs !< Number of immersed boundaries + integer :: num_ibs !< Number of immersed boundaries + #ifdef MFC_MPI type(mpi_io_var), public :: MPI_IO_DATA type(mpi_io_ib_var), public :: MPI_IO_IB_DATA @@ -168,10 +184,17 @@ module m_global_parameters integer :: mpi_info_int !> @} + !> Database of the physical parameters of each of the fluids that is present in the flow. These include the stiffened gas + !! equation of state parameters, and the Reynolds numbers. type(physical_parameters), dimension(num_fluids_max) :: fluid_pp !< Stiffened gas EOS parameters and Reynolds numbers per fluid + ! Subgrid Bubble Parameters type(subgrid_bubble_physical_parameters) :: bub_pp - real(wp), allocatable, dimension(:) :: adv !< Advection variables + + ! Subgrid Particle Parameters + type(subgrid_particle_physical_parameters) :: particle_pp + real(wp), allocatable, dimension(:) :: adv !< Advection variables + ! Formatted Database File(s) Structure Parameters integer :: format !< Format of the database file(s) @@ -180,6 +203,7 @@ module m_global_parameters logical :: output_partial_domain !< Specify portion of domain to output for post-processing type(bounds_info) :: x_output, y_output, z_output !< Portion of domain to output for post-processing type(int_bounds_info) :: x_output_idx, y_output_idx, z_output_idx !< Indices of domain to output for post-processing + !> @name Size of the ghost zone layer in the x-, y- and z-coordinate directions. The definition of the ghost zone layers is only !! necessary when using the Silo database file format in multidimensions. These zones provide VisIt with the subdomain !! connectivity information that it requires in order to produce smooth plots. @@ -201,6 +225,8 @@ module m_global_parameters logical :: E_wrt logical, dimension(num_fluids_max) :: alpha_rho_e_wrt logical :: fft_wrt + !> AMDFlang workaround: keep a dummy logical to avoid a compiler case-optimization bug when a parameter+GPU-kernel conditional + !! is false logical :: dummy !< AMDFlang workaround for case-optimization + GPU-kernel bug logical :: pres_wrt logical, dimension(num_fluids_max) :: alpha_wrt @@ -240,9 +266,19 @@ module m_global_parameters logical :: lag_betaC_wrt !> @} + !> Amplitude coefficients of the numerical Schlieren function that are used to adjust the intensity of numerical Schlieren + !! renderings for individual fluids. This enables waves and interfaces of varying strengths and in all of the fluids to be made + !! simultaneously visible on a single plot. real(wp), dimension(num_fluids_max) :: schlieren_alpha !< Per-fluid Schlieren intensity amplitude coefficients - integer :: fd_order !< Finite-difference order for vorticity and Schlieren derivatives - integer :: fd_number !< Finite-difference half-stencil size: MAX(1, fd_order/2) + + !> The order of the finite-difference (fd) approximations of the first-order derivatives that need to be evaluated when + !! vorticity and/or the numerical Schlieren function are to be outputted to the formatted database file(s). + integer :: fd_order !< Finite-difference order for vorticity and Schlieren derivatives + + !> The finite-difference number is given by MAX(1, fd_order/2). Essentially, it is a measure of the half-size of the + !! finite-difference stencil for the selected order of accuracy. + integer :: fd_number !< Finite-difference half-stencil size: MAX(1, fd_order/2) + !> @name Reference parameters for Tait EOS !> @{ real(wp) :: rhoref, pref @@ -271,6 +307,11 @@ module m_global_parameters integer :: nmom !> @} + !> @name Particle modeling variables and parameters + !> @{ + real(wp) :: cp_particle, rho0ref_particle + !> @} + !> @name surface tension coefficient !> @{ real(wp) :: sigma @@ -292,6 +333,7 @@ module m_global_parameters !> @name Lagrangian bubbles !> @{ logical :: bubbles_lagrange + logical :: particles_lagrange !> @} real(wp) :: Bx0 !< Constant magnetic field in the x-direction (1D) @@ -304,6 +346,7 @@ contains impure subroutine s_assign_default_values_to_user_inputs integer :: i !< Generic loop iterator + ! Logistics case_dir = '.' @@ -398,6 +441,10 @@ contains bub_pp%R_v = dflt_real; R_v = dflt_real bub_pp%R_g = dflt_real; R_g = dflt_real + ! Subgrid particle parameters + particle_pp%rho0ref_particle = dflt_real + particle_pp%cp_particle = dflt_real + ! Formatted database file(s) structure parameters format = dflt_int @@ -477,6 +524,7 @@ contains ! Lagrangian bubbles modeling bubbles_lagrange = .false. + particles_lagrange = .false. ! IBM num_ibs = dflt_int @@ -606,10 +654,9 @@ contains end if end if - if (bubbles_lagrange) then - beta_idx = sys_size + 1 - sys_size = beta_idx - end if + ! if (bubbles_lagrange) then beta_idx = sys_size + 1 sys_size = beta_idx end if + + ! if (particles_lagrange) then beta_idx = sys_size + 1 sys_size = beta_idx end if if (mhd) then B_idx%beg = sys_size + 1 @@ -733,6 +780,16 @@ contains sys_size = c_idx end if + if (bubbles_lagrange) then + beta_idx = sys_size + 1 + sys_size = beta_idx + end if + + if (particles_lagrange) then + beta_idx = sys_size + 1 + sys_size = beta_idx + end if + if (cont_damage) then damage_idx = sys_size + 1 sys_size = damage_idx @@ -748,6 +805,14 @@ contains end if end if + if (bubbles_lagrange) then + allocate (beta_vars(1:3)) + beta_vars(1:3) = [1, 2, 5] + else if (particles_lagrange) then + allocate (beta_vars(1:8)) + beta_vars(1:8) = [1, 2, 3, 4, 5, 6, 7, 8] + end if + if (chemistry) then species_idx%beg = sys_size + 1 species_idx%end = sys_size + num_species @@ -968,6 +1033,9 @@ contains if (ib) MPI_IO_IB_DATA%var%sf => null() #endif + if (allocated(neighbor_ranks)) deallocate (neighbor_ranks) + if (allocated(beta_vars)) deallocate (beta_vars) + end subroutine s_finalize_global_parameters_module end module m_global_parameters diff --git a/src/post_process/m_mpi_proxy.fpp b/src/post_process/m_mpi_proxy.fpp index c91f140d39..873aa683ba 100644 --- a/src/post_process/m_mpi_proxy.fpp +++ b/src/post_process/m_mpi_proxy.fpp @@ -34,7 +34,6 @@ contains ! Allocating and configuring the receive counts and the displacement vector variables used in variable-gather communication ! procedures. Note that these are only needed for either multidimensional runs that utilize the Silo database file format or ! for 1D simulations. - if ((format == 1 .and. n > 0) .or. n == 0) then allocate (recvcounts(0:num_procs - 1)) allocate (displs(0:num_procs - 1)) @@ -65,7 +64,6 @@ contains integer :: i !< Generic loop iterator integer :: ierr !< Generic flag used to identify and report MPI errors ! Logistics - call MPI_BCAST(case_dir, len(case_dir), MPI_CHARACTER, 0, MPI_COMM_WORLD, ierr) #:for VAR in [ 'm', 'n', 'p', 'm_glb', 'n_glb', 'p_glb', & @@ -87,11 +85,22 @@ contains & 'adv_n', 'ib', 'cfl_adap_dt', 'cfl_const_dt', 'cfl_dt', & & 'surface_tension', 'hyperelasticity', 'bubbles_lagrange', & & 'output_partial_domain', 'relativity', 'cont_damage', 'bc_io', & - & 'down_sample','fft_wrt', 'hyper_cleaning', 'ib_state_wrt'] + & 'down_sample','fft_wrt', 'hyper_cleaning', 'ib_state_wrt', & + & 'particles_lagrange' ] call MPI_BCAST(${VAR}$, 1, MPI_LOGICAL, 0, MPI_COMM_WORLD, ierr) #:endfor if (bubbles_lagrange) then + #:for VAR in ['lag_header', 'lag_txt_wrt', 'lag_db_wrt', 'lag_id_wrt', & + & 'lag_pos_wrt', 'lag_pos_prev_wrt', 'lag_vel_wrt', 'lag_rad_wrt', & + & 'lag_rvel_wrt', 'lag_r0_wrt', 'lag_rmax_wrt', 'lag_rmin_wrt', & + & 'lag_dphidt_wrt', 'lag_pres_wrt', 'lag_mv_wrt', 'lag_mg_wrt', & + & 'lag_betaT_wrt', 'lag_betaC_wrt'] + call MPI_BCAST(${VAR}$, 1, MPI_LOGICAL, 0, MPI_COMM_WORLD, ierr) + #:endfor + end if + + if (particles_lagrange) then #:for VAR in ['lag_header', 'lag_txt_wrt', 'lag_db_wrt', 'lag_id_wrt', & & 'lag_pos_wrt', 'lag_pos_prev_wrt', 'lag_vel_wrt', 'lag_rad_wrt', & & 'lag_rvel_wrt', 'lag_r0_wrt', 'lag_rmax_wrt', 'lag_rmin_wrt', & @@ -127,6 +136,13 @@ contains #:endfor end if + ! Subgrid particle parameters + if (particles_lagrange) then + #:for VAR in ['rho0ref_particle','cp_particle'] + call MPI_BCAST(particle_pp%${VAR}$, 1, mpi_p, 0, MPI_COMM_WORLD, ierr) + #:endfor + end if + #:for VAR in [ 'pref', 'rhoref', 'R0ref', 'poly_sigma', 'Web', 'Ca', & & 'Re_inv', 'Bx0', 'sigma', 't_save', 't_stop', & & 'x_output%beg', 'x_output%end', 'y_output%beg', & @@ -148,7 +164,6 @@ contains real(wp) :: ext_temp(0:num_procs - 1) ! Simulation is 3D - if (p > 0) then if (grid_geometry == 3) then ! Minimum spatial extent in the r-direction @@ -236,7 +251,6 @@ contains #ifdef MFC_MPI integer :: ierr !< Generic flag used to identify and report MPI errors ! Silo-HDF5 database format - if (format == 1) then call MPI_GATHERV(x_cc(0), m + 1, mpi_p, x_root_cc(0), recvcounts, displs, mpi_p, 0, MPI_COMM_WORLD, ierr) @@ -296,7 +310,6 @@ contains integer :: ierr !< Generic flag used to identify and report MPI errors ! Gathering the sub-domain flow variable data from all the processes and putting it back together for the entire ! computational domain on the process with rank 0 - call MPI_GATHERV(q_sf(0), m + 1, mpi_p, q_root_sf(0), recvcounts, displs, mpi_p, 0, MPI_COMM_WORLD, ierr) #endif diff --git a/src/post_process/m_start_up.fpp b/src/post_process/m_start_up.fpp index c65e4cf7cf..25a64a0597 100644 --- a/src/post_process/m_start_up.fpp +++ b/src/post_process/m_start_up.fpp @@ -70,7 +70,8 @@ contains & bubbles_lagrange, sim_data, hyperelasticity, Bx0, relativity, cont_damage, hyper_cleaning, num_bc_patches, igr, & & igr_order, down_sample, recon_type, muscl_order, lag_header, lag_txt_wrt, lag_db_wrt, lag_id_wrt, lag_pos_wrt, & & lag_pos_prev_wrt, lag_vel_wrt, lag_rad_wrt, lag_rvel_wrt, lag_r0_wrt, lag_rmax_wrt, lag_rmin_wrt, lag_dphidt_wrt, & - & lag_pres_wrt, lag_mv_wrt, lag_mg_wrt, lag_betaT_wrt, lag_betaC_wrt, alpha_rho_e_wrt, ib_state_wrt + & lag_pres_wrt, lag_mv_wrt, lag_mg_wrt, lag_betaT_wrt, lag_betaC_wrt, alpha_rho_e_wrt, ib_state_wrt, & + & particles_lagrange, particle_pp file_loc = 'post_process.inp' inquire (FILE=trim(file_loc), EXIST=file_check) @@ -724,8 +725,7 @@ contains end if end if - if (bubbles_lagrange) then - ! Void fraction field + if (bubbles_lagrange .or. particles_lagrange) then q_sf(:,:,:) = 1._wp - q_cons_vf(beta_idx)%sf(-offset_x%beg:m + offset_x%end,-offset_y%beg:n + offset_y%end, & & -offset_z%beg:p + offset_z%end) write (varname, '(A)') 'voidFraction' @@ -839,6 +839,9 @@ contains if (bubbles_euler .or. bubbles_lagrange) then call s_initialize_bubbles_model() end if + if (particles_lagrange) then + call s_initialize_particles_model() + end if if (num_procs > 1) then call s_initialize_mpi_proxy_module() call s_initialize_mpi_common_module() diff --git a/src/pre_process/m_global_parameters.fpp b/src/pre_process/m_global_parameters.fpp index 077262aece..db675c3cf6 100644 --- a/src/pre_process/m_global_parameters.fpp +++ b/src/pre_process/m_global_parameters.fpp @@ -41,14 +41,19 @@ module m_global_parameters integer :: num_vels !< Number of velocity components (different from num_dims for mhd) logical :: cyl_coord integer :: grid_geometry !< Cylindrical coordinates (either axisymmetric or full 3D) + !> Locations of cell-centers (cc) in x-, y- and z-directions, respectively real(wp), allocatable, dimension(:) :: x_cc, y_cc, z_cc + !> Locations of cell-boundaries (cb) in x-, y- and z-directions, respectively real(wp), allocatable, dimension(:) :: x_cb, y_cb, z_cb real(wp) :: dx, dy, dz !< Minimum cell-widths in the x-, y- and z-coordinate directions type(bounds_info) :: x_domain, y_domain, z_domain !< Locations of the domain bounds in the x-, y- and z-coordinate directions logical :: stretch_x, stretch_y, stretch_z !< Grid stretching flags for the x-, y- and z-coordinate directions - ! Grid stretching: a_x/a_y/a_z = rate, x_a/y_a/z_a = location + + ! Parameters of the grid stretching function for the x-, y- and z-coordinate directions. The "a" parameters are a measure of the + ! rate at which the grid is stretched while the remaining parameters are indicative of the location on the grid at which the + ! stretching begins. real(wp) :: a_x, a_y, a_z integer :: loops_x, loops_y, loops_z real(wp) :: x_a, y_a, z_a @@ -81,6 +86,7 @@ module m_global_parameters logical :: igr !< Use information geometric regularization integer :: igr_order !< IGR reconstruction order logical, parameter :: chemistry = .${chemistry}$. !< Chemistry modeling + ! Annotations of the structure, i.e. the organization, of the state vectors type(int_bounds_info) :: cont_idx !< Indexes of first & last continuity eqns. type(int_bounds_info) :: mom_idx !< Indexes of first & last momentum eqns. @@ -99,42 +105,68 @@ module m_global_parameters type(int_bounds_info) :: species_idx !< Indexes of first & last concentration eqns. integer :: damage_idx !< Index of damage state variable (D) for continuum damage model integer :: psi_idx !< Index of hyperbolic cleaning state variable for MHD + ! Cell Indices for the (local) interior points (O-m, O-n, 0-p). Stands for "InDices With BUFFer". type(int_bounds_info) :: idwint(1:3) - ! Cell indices (InDices With BUFFer): includes buffer except in pre_process - type(int_bounds_info) :: idwbuff(1:3) - type(int_bounds_info) :: bc_x, bc_y, bc_z !< Boundary conditions in the x-, y- and z-coordinate directions - integer :: shear_num !< Number of shear stress components - integer, dimension(3) :: shear_indices !< Indices of the stress components that represent shear stress - integer :: shear_BC_flip_num !< Number of shear stress components to reflect for boundary conditions - integer, dimension(3, 2) :: shear_BC_flip_indices !< Shear stress BC reflection indices (1:3, 1:shear_BC_flip_num) - logical :: parallel_io !< Format of the data files - logical :: file_per_process !< type of data output - integer :: precision !< Precision of output files - logical :: down_sample !< Down-sample the output data - logical :: mixlayer_vel_profile !< Set hyperbolic tangent streamwise velocity profile - real(wp) :: mixlayer_vel_coef !< Coefficient for the hyperbolic tangent streamwise velocity profile - logical :: mixlayer_perturb !< Superimpose instability waves to surrounding fluid flow - integer :: mixlayer_perturb_nk !< Number of Fourier modes for perturbation with mixlayer_perturb flag - real(wp) :: mixlayer_perturb_k0 !< Peak wavenumber for mixlayer perturbation (default: most unstable mode) + ! Cell Indices for the entire (local) domain. In simulation and post_process, this includes the buffer region. idwbuff and + ! idwint are the same otherwise. Stands for "InDices With BUFFer". + type(int_bounds_info) :: idwbuff(1:3) + + !> The order of the finite-difference (fd) approximations of the first-order derivatives that need to be evaluated when the CoM + !! or flow probe data files are to be written at each time step + integer :: fd_order + + !> The finite-difference number is given by MAX(1, fd_order/2). Essentially, it is a measure of the half-size of the + !! finite-difference stencil for the selected order of accuracy. + integer :: fd_number + + !> @name lagrangian subgrid bubble parameters + !> @{! + type(bubbles_lagrange_parameters) :: lag_params !< Lagrange bubbles' parameters + !> @} + + type(int_bounds_info) :: bc_x, bc_y, bc_z !< Boundary conditions in the x-, y- and z-coordinate directions + integer :: shear_num !< Number of shear stress components + integer, dimension(3) :: shear_indices !< Indices of the stress components that represent shear stress + integer :: shear_BC_flip_num !< Number of shear stress components to reflect for boundary conditions + !> Indices of shear stress components to reflect for boundary conditions. Size: (1:3, 1:shear_BC_flip_num) for (x/y/z, + !! [indices]) + integer, dimension(3, 2) :: shear_BC_flip_indices !< Shear stress BC reflection indices (1:3, 1:shear_BC_flip_num) + logical :: parallel_io !< Format of the data files + logical :: file_per_process !< type of data output + integer :: precision !< Precision of output files + logical :: down_sample !< Down-sample the output data + logical :: mixlayer_vel_profile !< Set hyperbolic tangent streamwise velocity profile + real(wp) :: mixlayer_vel_coef !< Coefficient for the hyperbolic tangent streamwise velocity profile + logical :: mixlayer_perturb !< Superimpose instability waves to surrounding fluid flow + integer :: mixlayer_perturb_nk !< Number of Fourier modes for perturbation with mixlayer_perturb flag + !> Peak wavenumber of prescribed energy spectra with mixlayer_perturb flag Default value (k0 = 0.4446) is most unstable mode + !! obtained from linear stability analysis See Michalke (1964, JFM) for details + real(wp) :: mixlayer_perturb_k0 !< Peak wavenumber for mixlayer perturbation (default: most unstable mode) logical :: simplex_perturb type(simplex_noise_params) :: simplex_params - real(wp) :: pi_fac !< Factor for artificial pi_inf + real(wp) :: pi_fac !< Factor for artificial pi_inf logical :: viscous logical :: bubbles_lagrange + logical :: particles_lagrange ! Perturb density of surrounding air so as to break symmetry of grid - logical :: perturb_flow - integer :: perturb_flow_fluid !< Fluid to be perturbed with perturb_flow flag - real(wp) :: perturb_flow_mag !< Magnitude of perturbation with perturb_flow flag - logical :: perturb_sph - integer :: perturb_sph_fluid !< Fluid to be perturbed with perturb_sph flag - real(wp), dimension(num_fluids_max) :: fluid_rho - logical :: elliptic_smoothing - integer :: elliptic_smoothing_iters - integer, allocatable, dimension(:) :: proc_coords !< Processor coordinates in MPI_CART_COMM - integer, allocatable, dimension(:) :: start_idx !< Starting cell-center index of local processor in global grid + logical :: perturb_flow + integer :: perturb_flow_fluid !< Fluid to be perturbed with perturb_flow flag + real(wp) :: perturb_flow_mag !< Magnitude of perturbation with perturb_flow flag + logical :: perturb_sph + integer :: perturb_sph_fluid !< Fluid to be perturbed with perturb_sph flag + real(wp), dimension(num_fluids_max) :: fluid_rho + logical :: elliptic_smoothing + integer :: elliptic_smoothing_iters + integer, allocatable, dimension(:) :: proc_coords !< Processor coordinates in MPI_CART_COMM + type(int_bounds_info), dimension(3) :: nidx + integer, allocatable, dimension(:,:,:) :: neighbor_ranks + !! Neighbor ranks + + integer, allocatable, dimension(:) :: start_idx !< Starting cell-center index of local processor in global grid + #ifdef MFC_MPI type(mpi_io_var), public :: MPI_IO_DATA character(LEN=name_len) :: mpiiofs @@ -142,18 +174,28 @@ module m_global_parameters #endif ! Initial Condition Parameters - integer :: num_patches !< Number of patches composing initial condition - type(ic_patch_parameters), dimension(num_patches_max) :: patch_icpp !< IC patch parameters (max: num_patches_max) - integer :: num_bc_patches !< Number of boundary condition patches - logical :: bc_io !< whether or not to save BC data - type(bc_patch_parameters), dimension(num_bc_patches_max) :: patch_bc !< Boundary condition patch parameters + integer :: num_patches !< Number of patches composing initial condition + + !> Database of the initial condition patch parameters (icpp) for each of the patches employed in the configuration of the + !! initial condition. Note that the maximum allowable number of patches, num_patches_max, may be changed in the module + !! m_derived_types.f90. + type(ic_patch_parameters), dimension(num_patches_max) :: patch_icpp !< IC patch parameters (max: num_patches_max) + integer :: num_bc_patches !< Number of boundary condition patches + logical :: bc_io !< whether or not to save BC data + !> Boundary condition patch parameters Database of the boundary condition patch parameters for each of the patches employed in + !! the configuration of the boundary conditions + type(bc_patch_parameters), dimension(num_bc_patches_max) :: patch_bc ! Fluids Physical Parameters + !> Database of the physical parameters of each of the fluids that is present in the flow. These include the stiffened gas + !! equation of state parameters, and the Reynolds numbers. type(physical_parameters), dimension(num_fluids_max) :: fluid_pp !< Stiffened gas EOS parameters and Reynolds numbers per fluid + ! Subgrid Bubble Parameters - type(subgrid_bubble_physical_parameters) :: bub_pp - real(wp) :: rhoref, pref !< Reference parameters for Tait EOS - type(chemistry_parameters) :: chem_params + type(subgrid_bubble_physical_parameters) :: bub_pp + type(subgrid_particle_physical_parameters) :: particle_pp + real(wp) :: rhoref, pref !< Reference parameters for Tait EOS + type(chemistry_parameters) :: chem_params !> @name Bubble modeling !> @{ integer :: nb @@ -173,6 +215,9 @@ module m_global_parameters integer :: Np type(ib_patch_parameters), dimension(num_patches_max) :: patch_ib !< Immersed boundary patch parameters type(vec3_dt), allocatable, dimension(:) :: airfoil_grid_u, airfoil_grid_l + !! Database of the immersed boundary patch parameters for each of the patches employed in the configuration of the initial + !! condition. Note that the maximum allowable number of patches, num_patches_max, may be changed in the module + !! m_derived_types.f90. !> @} !> @name Non-polytropic bubble gas compression @@ -187,6 +232,9 @@ module m_global_parameters real(wp), dimension(:), allocatable :: pb0, mass_g0, mass_v0, Pe_T, k_v, k_g real(wp), dimension(:), allocatable :: Re_trans_T, Re_trans_c, Im_trans_T, Im_trans_c, omegaN real(wp) :: R0ref, p0ref, rho0ref, T0ref, ss, pv, vd, mu_l, mu_v, mu_g, gam_v, gam_g, M_v, M_g, cp_v, cp_g, R_v, R_g + + ! Solid particle physical parameters + real(wp) :: cp_particle, rho0ref_particle !> @} !> @name Surface Tension Modeling @@ -210,10 +258,20 @@ module m_global_parameters integer, allocatable, dimension(:,:,:) :: logic_grid type(pres_field) :: pb type(pres_field) :: mv - real(wp) :: Bx0 !< Constant magnetic field in the x-direction (1D) - integer :: buff_size !< Number of ghost cells for boundary condition storage - logical :: fft_wrt - logical :: dummy !< AMDFlang workaround for case-optimization + GPU-kernel bug + real(wp) :: Bx0 !< Constant magnetic field in the x-direction (1D) + + !> The number of cells that are necessary to be able to store enough boundary conditions data to march the solution in the + !! physical computational domain to the next time-step. + integer :: buff_size !< Number of ghost cells for boundary condition storage + integer, allocatable :: beta_vars(:) !< Indices of variables to communicate for bubble/particle coupling + logical :: fft_wrt + !> AMDFlang workaround: keep a dummy logical to avoid a compiler case-optimization bug when a parameter+GPU-kernel conditional + !! is false + logical :: dummy !< AMDFlang workaround for case-optimization + GPU-kernel bug + + ! Variables for hardcoded initial conditions that are read from input files + character(LEN=2*path_len) :: interface_file + real(wp) :: normFac, normMag, g0_ic, p0_ic contains @@ -222,6 +280,7 @@ contains impure subroutine s_assign_default_values_to_user_inputs integer :: i !< Generic loop operator + ! Logistics case_dir = '.' @@ -322,6 +381,8 @@ contains elliptic_smoothing_iters = dflt_int elliptic_smoothing = .false. + particles_lagrange = .false. + fft_wrt = .false. dummy = .false. @@ -338,6 +399,27 @@ contains ! Initial condition parameters num_patches = dflt_int + fd_order = dflt_int + lag_params%cluster_type = dflt_int + lag_params%pressure_corrector = .false. + lag_params%smooth_type = dflt_int + lag_params%heatTransfer_model = .false. + lag_params%massTransfer_model = .false. + lag_params%write_bubbles = .false. + lag_params%write_bubbles_stats = .false. + lag_params%nBubs_glb = dflt_int + lag_params%vel_model = dflt_int + lag_params%drag_model = dflt_int + lag_params%epsilonb = 1._wp + lag_params%charwidth = dflt_real + lag_params%nParticles_glb = dflt_int + lag_params%qs_drag_model = dflt_int + lag_params%stokes_drag = dflt_int + lag_params%added_mass_model = dflt_int + lag_params%interpolation_order = dflt_int + lag_params%charNz = dflt_int + lag_params%valmaxvoid = dflt_real + do i = 1, num_patches_max patch_icpp(i)%geometry = dflt_int patch_icpp(i)%model_scale(:) = 1._wp @@ -540,6 +622,10 @@ contains bub_pp%R_v = dflt_real; R_v = dflt_real bub_pp%R_g = dflt_real; R_g = dflt_real + ! Subgrid particle parameters + particle_pp%rho0ref_particle = dflt_real + particle_pp%cp_particle = dflt_real + end subroutine s_assign_default_values_to_user_inputs !> Computation of parameters, allocation procedures, and/or any other tasks needed to properly setup the module @@ -797,6 +883,14 @@ contains end if end if + if (bubbles_lagrange) then + allocate (beta_vars(1:3)) + beta_vars(1:3) = [1, 2, 5] + else if (particles_lagrange) then + allocate (beta_vars(1:8)) + beta_vars(1:8) = [1, 2, 3, 4, 5, 6, 7, 8] + end if + if (chemistry) then species_idx%beg = sys_size + 1 species_idx%end = sys_size + num_species @@ -820,8 +914,10 @@ contains chemxb = species_idx%beg chemxe = species_idx%end + if (bubbles_lagrange .or. particles_lagrange) fd_number = max(1, fd_order/2) + call s_configure_coordinate_bounds(recon_type, weno_polyn, muscl_polyn, igr_order, buff_size, idwint, idwbuff, viscous, & - & bubbles_lagrange, m, n, p, num_dims, igr, ib) + & bubbles_lagrange, particles_lagrange, m, n, p, num_dims, igr, ib, fd_number) #ifdef MFC_MPI if (qbmm .and. .not. polytropic) then @@ -870,7 +966,7 @@ contains end subroutine s_initialize_global_parameters_module - !> Configure MPI parallel I/O settings and allocate processor coordinate arrays. + !> @brief Configures MPI parallel I/O settings and allocates processor coordinate arrays. impure subroutine s_initialize_parallel_io #ifdef MFC_MPI @@ -904,7 +1000,7 @@ contains end subroutine s_initialize_parallel_io - !> Deallocate all global grid, index, and equation-of-state parameter arrays. + !> @brief Deallocates all global grid, index, and equation-of-state parameter arrays. impure subroutine s_finalize_global_parameters_module integer :: i @@ -934,6 +1030,9 @@ contains end if #endif + if (allocated(neighbor_ranks)) deallocate (neighbor_ranks) + if (allocated(beta_vars)) deallocate (beta_vars) + end subroutine s_finalize_global_parameters_module end module m_global_parameters diff --git a/src/pre_process/m_mpi_proxy.fpp b/src/pre_process/m_mpi_proxy.fpp index e9545ce865..ae82433156 100644 --- a/src/pre_process/m_mpi_proxy.fpp +++ b/src/pre_process/m_mpi_proxy.fpp @@ -33,7 +33,7 @@ contains & 'perturb_sph_fluid', 'num_patches', 'thermal', 'nb', 'dist_type',& & 'relax_model', 'num_ibs', 'n_start', 'elliptic_smoothing_iters', & & 'num_bc_patches', 'mixlayer_perturb_nk', 'recon_type', & - & 'muscl_order', 'igr_order' ] + & 'muscl_order', 'igr_order', 'fd_order'] call MPI_BCAST(${VAR}$, 1, MPI_INTEGER, 0, MPI_COMM_WORLD, ierr) #:endfor @@ -45,7 +45,8 @@ contains & 'cfl_const_dt', 'cfl_dt', 'surface_tension', & & 'hyperelasticity', 'pre_stress', 'elliptic_smoothing', 'viscous',& & 'bubbles_lagrange', 'bc_io', 'mhd', 'relativity', 'cont_damage', & - & 'igr', 'down_sample', 'simplex_perturb','fft_wrt', 'hyper_cleaning' ] + & 'igr', 'down_sample', 'simplex_perturb','fft_wrt', 'hyper_cleaning',& + & 'particles_lagrange' ] call MPI_BCAST(${VAR}$, 1, MPI_LOGICAL, 0, MPI_COMM_WORLD, ierr) #:endfor call MPI_BCAST(fluid_rho(1), num_fluids_max, mpi_p, 0, MPI_COMM_WORLD, ierr) @@ -133,6 +134,21 @@ contains #:endfor end do + ! Variables from input files for hardcoded patches + call MPI_BCAST(interface_file, len(interface_file), MPI_CHARACTER, 0, MPI_COMM_WORLD, ierr) + call MPI_BCAST(normFac, 1, mpi_p, 0, MPI_COMM_WORLD, ierr) + call MPI_BCAST(normMag, 1, mpi_p, 0, MPI_COMM_WORLD, ierr) + call MPI_BCAST(g0_ic, 1, mpi_p, 0, MPI_COMM_WORLD, ierr) + call MPI_BCAST(p0_ic, 1, mpi_p, 0, MPI_COMM_WORLD, ierr) + + if (bubbles_euler .or. bubbles_lagrange) then + #:for VAR in [ 'R0ref','p0ref','rho0ref','T0ref', & + 'ss','pv','vd','mu_l','mu_v','mu_g','gam_v','gam_g', & + 'M_v','M_g','k_v','k_g','cp_v','cp_g','R_v','R_g'] + call MPI_BCAST(bub_pp%${VAR}$, 1, mpi_p, 0, MPI_COMM_WORLD, ierr) + #:endfor + end if + ! Simplex noise and fluid physical parameters do i = 1, num_fluids_max #:for VAR in [ 'gamma','pi_inf', 'G', 'cv', 'qv', 'qvp' ] @@ -147,15 +163,7 @@ contains call MPI_BCAST(simplex_params%perturb_dens_offset(i, j), 1, mpi_p, 0, MPI_COMM_WORLD, ierr) end do end do - ! Subgrid bubble parameters - if (bubbles_euler .or. bubbles_lagrange) then - #:for VAR in [ 'R0ref','p0ref','rho0ref','T0ref', & - 'ss','pv','vd','mu_l','mu_v','mu_g','gam_v','gam_g', & - 'M_v','M_g','k_v','k_g','cp_v','cp_g','R_v','R_g'] - call MPI_BCAST(bub_pp%${VAR}$, 1, mpi_p, 0, MPI_COMM_WORLD, ierr) - #:endfor - end if do i = 1, 3 call MPI_BCAST(simplex_params%perturb_vel(i), 1, MPI_LOGICAL, 0, MPI_COMM_WORLD, ierr) diff --git a/src/pre_process/m_start_up.fpp b/src/pre_process/m_start_up.fpp index a3a7c51270..551224dd6d 100644 --- a/src/pre_process/m_start_up.fpp +++ b/src/pre_process/m_start_up.fpp @@ -84,7 +84,8 @@ contains & ptgalpha_eps, ib, num_ibs, patch_ib, sigma, adv_n, cfl_adap_dt, cfl_const_dt, n_start, n_start_old, & & surface_tension, hyperelasticity, pre_stress, elliptic_smoothing, elliptic_smoothing_iters, viscous, & & bubbles_lagrange, num_bc_patches, patch_bc, Bx0, relativity, cont_damage, igr, igr_order, down_sample, recon_type, & - & muscl_order, hyper_cleaning, simplex_perturb, simplex_params, fft_wrt + & muscl_order, fft_wrt, fd_order, lag_params, simplex_perturb, simplex_params, interface_file, normFac, normMag, & + & g0_ic, p0_ic, hyper_cleaning, particles_lagrange, particle_pp file_loc = 'pre_process.inp' inquire (FILE=trim(file_loc), EXIST=file_check) @@ -489,6 +490,9 @@ contains if (bubbles_euler .or. bubbles_lagrange) then call s_initialize_bubbles_model() end if + if (particles_lagrange) then + call s_initialize_particles_model() + end if call s_initialize_mpi_common_module() call s_initialize_data_output_module() call s_initialize_variables_conversion_module() diff --git a/src/simulation/m_bubbles.fpp b/src/simulation/m_bubbles.fpp index 2ff5952827..b8f22aa318 100644 --- a/src/simulation/m_bubbles.fpp +++ b/src/simulation/m_bubbles.fpp @@ -13,6 +13,7 @@ module m_bubbles use m_mpi_proxy use m_variables_conversion use m_helper_basic + use m_bubbles_EL_kernels implicit none @@ -24,7 +25,7 @@ module m_bubbles contains !> Compute the bubble radial acceleration based on the selected bubble model - elemental function f_rddot(fRho, fP, fR, fV, fR0, fpb, fpbdot, alf, fntait, fBtait, f_bub_adv_src, f_divu, fCson) + function f_rddot(fRho, fP, fR, fV, fR0, fpb, fpbdot, alf, fntait, fBtait, f_bub_adv_src, f_divu, fCson) $:GPU_ROUTINE(parallelism='[seq]') real(wp), intent(in) :: fRho, fP, fR, fV, fR0, fpb, fpbdot, alf @@ -64,7 +65,7 @@ contains end function f_rddot !> Bubble wall pressure: stiffened gas with Laplace pressure and viscous stress - elemental function f_cpbw(fR0, fR, fV, fpb) + function f_cpbw(fR0, fR, fV, fpb) $:GPU_ROUTINE(parallelism='[seq]') real(wp), intent(in) :: fR0, fR, fV, fpb @@ -79,7 +80,7 @@ contains end function f_cpbw !> Compute the bubble enthalpy - elemental function f_H(fCpbw, fCpinf, fntait, fBtait) + function f_H(fCpbw, fCpinf, fntait, fBtait) $:GPU_ROUTINE(parallelism='[seq]') real(wp), intent(in) :: fCpbw, fCpinf, fntait, fBtait @@ -95,7 +96,7 @@ contains end function f_H !> Compute the sound speed for the bubble - elemental function f_cgas(fCpinf, fntait, fBtait, fH) + function f_cgas(fCpinf, fntait, fBtait, fH) $:GPU_ROUTINE(parallelism='[seq]') real(wp), intent(in) :: fCpinf, fntait, fBtait, fH @@ -111,7 +112,7 @@ contains end function f_cgas !> Compute the time derivative of the driving pressure - elemental function f_cpinfdot(fRho, fP, falf, fntait, fBtait, advsrc, divu) + function f_cpinfdot(fRho, fP, falf, fntait, fBtait, advsrc, divu) $:GPU_ROUTINE(parallelism='[seq]') real(wp), intent(in) :: fRho, fP, falf, fntait, fBtait, advsrc, divu @@ -131,7 +132,7 @@ contains end function f_cpinfdot !> Enthalpy derivative for Gilmore bubble model, Gilmore (1952) - elemental function f_Hdot(fCpbw, fCpinf, fCpinf_dot, fntait, fBtait, fR, fV, fR0, fpbdot) + function f_Hdot(fCpbw, fCpinf, fCpinf_dot, fntait, fBtait, fR, fV, fR0, fpbdot) $:GPU_ROUTINE(parallelism='[seq]') real(wp), intent(in) :: fCpbw, fCpinf, fCpinf_dot, fntait, fBtait @@ -153,7 +154,7 @@ contains end function f_Hdot !> Rayleigh-Plesset bubble radial acceleration - elemental function f_rddot_RP(fCp, fRho, fR, fV, fCpbw) + function f_rddot_RP(fCp, fRho, fR, fV, fCpbw) $:GPU_ROUTINE(parallelism='[seq]') real(wp), intent(in) :: fCp, fRho, fR, fV, fCpbw @@ -164,7 +165,7 @@ contains end function f_rddot_RP !> Compute the Gilmore bubble radial acceleration - elemental function f_rddot_G(fCpbw, fR, fV, fH, fHdot, fcgas, fntait, fBtait) + function f_rddot_G(fCpbw, fR, fV, fH, fHdot, fcgas, fntait, fBtait) $:GPU_ROUTINE(parallelism='[seq]') real(wp), intent(in) :: fCpbw, fR, fV, fH, fHdot @@ -181,7 +182,7 @@ contains end function f_rddot_G !> Keller-Miksis bubble wall pressure - elemental function f_cpbw_KM(fR0, fR, fV, fpb) + function f_cpbw_KM(fR0, fR, fV, fpb) $:GPU_ROUTINE(parallelism='[seq]') real(wp), intent(in) :: fR0, fR, fV, fpb @@ -200,7 +201,7 @@ contains end function f_cpbw_KM !> Keller-Miksis bubble radial acceleration - elemental function f_rddot_KM(fpbdot, fCp, fCpbw, fRho, fR, fV, fR0, fC) + function f_rddot_KM(fpbdot, fCp, fCpbw, fRho, fR, fV, fR0, fC) $:GPU_ROUTINE(parallelism='[seq]') real(wp), intent(in) :: fpbdot, fCp, fCpbw @@ -229,7 +230,7 @@ contains end function f_rddot_KM !> Compute bubble wall properties for vapor bubbles - elemental subroutine s_bwproperty(pb_in, iR0, chi_vw_out, k_mw_out, rho_mw_out) + subroutine s_bwproperty(pb_in, iR0, chi_vw_out, k_mw_out, rho_mw_out) $:GPU_ROUTINE(parallelism='[seq]') real(wp), intent(in) :: pb_in @@ -250,7 +251,7 @@ contains end subroutine s_bwproperty !> Compute the vapour flux - elemental subroutine s_vflux(fR, fV, fpb, fmass_v, iR0, vflux, fmass_g, fbeta_c, fR_m, fgamma_m) + subroutine s_vflux(fR, fV, fpb, fmass_v, iR0, vflux, fmass_g, fbeta_c, fR_m, fgamma_m) $:GPU_ROUTINE(parallelism='[seq]') real(wp), intent(in) :: fR @@ -298,8 +299,9 @@ contains end subroutine s_vflux !> Compute the time derivative of the internal bubble pressure - elemental function f_bpres_dot(fvflux, fR, fV, fpb, fmass_v, iR0, fbeta_t, fR_m, fgamma_m) + function f_bpres_dot(fvflux, fR, fV, fpb, fmass_v, iR0, fbeta_t, fR_m, fgamma_m) + !$DIR INLINENEVER f_bpres_dot $:GPU_ROUTINE(parallelism='[seq]') real(wp), intent(in) :: fvflux real(wp), intent(in) :: fR @@ -332,25 +334,29 @@ contains !> Adaptive time stepping routine for subgrid bubbles (See Heirer, E. Hairer S.P.Norsett G. Wanner, Solving Ordinary !! Differential Equations I, Chapter II.4) - subroutine s_advance_step(fRho, fP, fR, fV, fR0, fpb, fpbdot, alf, fntait, fBtait, f_bub_adv_src, f_divu, bub_id, fmass_v, & - - & fmass_g, fbeta_c, fbeta_t, fCson, adap_dt_stop) - $:GPU_ROUTINE(function_name='s_advance_step',parallelism='[seq]', cray_inline=True) + function f_advance_step(fRho, fP, fR, fV, fR0, fpb, fpbdot, alf, fntait, fBtait, f_bub_adv_src, f_divu, bub_id, fmass_v, & + & fmass_g, fbeta_c, fbeta_t, fCson, fRe, fPos, fVel, cell, q_prim_vf) result(adap_dt_stop) + $:GPU_ROUTINE(parallelism='[seq]') - real(wp), intent(inout) :: fR, fV, fpb, fmass_v - real(wp), intent(in) :: fRho, fP, fR0, fpbdot, alf - real(wp), intent(in) :: fntait, fBtait, f_bub_adv_src, f_divu - integer, intent(in) :: bub_id - real(wp), intent(in) :: fmass_g, fbeta_c, fbeta_t, fCson - integer, intent(inout) :: adap_dt_stop - real(wp), dimension(5) :: err !< Error estimates for adaptive time stepping - real(wp) :: t_new !< Updated time step size - real(wp) :: h0, h !< Time step size + real(wp), intent(inout) :: fR, fV, fpb, fmass_v + real(wp), intent(in) :: fRho, fP, fR0, fpbdot, alf + real(wp), intent(in) :: fntait, fBtait, f_bub_adv_src, f_divu + integer, intent(in) :: bub_id + real(wp), intent(in) :: fmass_g, fbeta_c, fbeta_t, fCson + real(wp), intent(inout), dimension(3), optional :: fPos, fVel + real(wp), intent(in), optional :: fRe + integer, intent(in), dimension(3), optional :: cell + type(scalar_field), intent(in), dimension(sys_size), optional :: q_prim_vf + real(wp), dimension(5) :: err !< Error estimates for adaptive time stepping + real(wp) :: t_new !< Updated time step size + real(wp) :: h0, h !< Time step size !> Bubble radius, radial velocity, and radial acceleration for the inner loop real(wp), dimension(4) :: myR_tmp1, myV_tmp1, myR_tmp2, myV_tmp2 real(wp), dimension(4) :: myPb_tmp1, myMv_tmp1, myPb_tmp2, myMv_tmp2 !< Gas pressure and vapor mass for the inner loop (EL) - real(wp) :: fR2, fV2, fpb2, fmass_v2 - integer :: iter_count + real(wp) :: fR2, fV2, fpb2, fmass_v2, f_bTemp + real(wp), dimension(3) :: vTemp, aTemp + integer :: adap_dt_stop + integer :: l, iter_count call s_initial_substep_h(fRho, fP, fR, fV, fR0, fpb, fpbdot, alf, fntait, fBtait, f_bub_adv_src, f_divu, fCson, h0) h = h0 @@ -416,6 +422,42 @@ contains ! Update pb and mass_v fpb = myPb_tmp1(4) fmass_v = myMv_tmp1(4) + + select case (lag_vel_model) + case (1) + do l = 1, num_dims + vTemp(l) = f_interpolate_velocity(fR, cell, l, q_prim_vf) + end do + do l = 1, num_dims + fVel(l) = vTemp(l) + fPos(l) = fPos(l) + h*vTemp(l) + end do + case (2) + do l = 1, num_dims + f_bTemp = f_get_bubble_force(fPos(l), fR, fV, fVel(l), fmass_g, fmass_v, fRe, fRho, cell, l, & + & q_prim_vf) + aTemp(l) = f_bTemp/(fmass_g + fmass_v) + end do + do l = 1, num_dims + fVel(l) = fVel(l) + h*aTemp(l) + fPos(l) = fPos(l) + h*fVel(l) + end do + case (3) + do l = 1, num_dims + f_bTemp = f_get_bubble_force(fPos(l), fR, fV, fVel(l), fmass_g, fmass_v, fRe, fRho, cell, l, & + & q_prim_vf) + aTemp(l) = 2._wp*f_bTemp/(fmass_g + fmass_v) - 3._wp*fV*fVel(l)/fR + end do + do l = 1, num_dims + fVel(l) = fVel(l) + h*aTemp(l) + fPos(l) = fPos(l) + h*fVel(l) + end do + case default + do l = 1, num_dims + fVel(l) = fVel(l) + fPos(l) = fPos(l) + end do + end select end if ! Update step size for the next sub-step @@ -438,7 +480,7 @@ contains if (iter_count >= adap_dt_max_iters) adap_dt_stop = 1 - end subroutine s_advance_step + end function f_advance_step !> Choose the initial time step size for the adaptive time stepping routine (See Heirer, E. Hairer S.P.Norsett G. Wanner, !! Solving Ordinary Differential Equations I, Chapter II.4) @@ -577,7 +619,8 @@ contains end subroutine s_advance_substep !> Changes of pressure and vapor mass in the lagrange bubbles. - elemental subroutine s_advance_EL(fR_tmp, fV_tmp, fPb_tmp, fMv_tmp, bub_id, fmass_g, fbeta_c, fbeta_t, fdPbdt_tmp, advance_EL) + !! @param fdMvdt_tmp Rate of change of the mass of vapor in the bubble + subroutine s_advance_EL(fR_tmp, fV_tmp, fPb_tmp, fMv_tmp, bub_id, fmass_g, fbeta_c, fbeta_t, fdPbdt_tmp, advance_EL) $:GPU_ROUTINE(parallelism='[seq]') real(wp), intent(in) :: fR_tmp, fV_tmp, fPb_tmp, fMv_tmp diff --git a/src/simulation/m_bubbles_EE.fpp b/src/simulation/m_bubbles_EE.fpp index b2c5f1fd97..145fcf6e41 100644 --- a/src/simulation/m_bubbles_EE.fpp +++ b/src/simulation/m_bubbles_EE.fpp @@ -159,7 +159,7 @@ contains real(wp) :: nbub !< Bubble number density real(wp) :: my_divu integer :: i, j, k, l, q, ii !< Loop variables - integer :: adap_dt_stop_max, adap_dt_stop !< Fail-safe exit if max iteration count reached + integer :: adap_dt_stop_sum, adap_dt_stop !< Fail-safe exit if max iteration count reached integer :: dmBub_id !< Dummy variables for unified subgrid bubble subroutines real(wp) :: dmMass_v, dmMass_n, dmBeta_c, dmBeta_t, dmCson @@ -181,10 +181,10 @@ contains end do $:END_GPU_PARALLEL_LOOP() - adap_dt_stop_max = 0 + adap_dt_stop_sum = 0 $:GPU_PARALLEL_LOOP(private='[j, k, l, Rtmp, Vtmp, myalpha_rho, myalpha, myR, myV, alf, myP, myRho, R2Vav, R3, nbub, & - & pb_local, mv_local, vflux, pbdot, rddot, n_tait, B_tait, my_divu]', collapse=3, & - & reduction = '[[adap_dt_stop_max]]', reductionOp = '[MAX]', copy = '[adap_dt_stop_max]') + & pb_local, mv_local, vflux, pbdot, rddot, n_tait, B_tait, & + & my_divu]', collapse=3, copy='[adap_dt_stop_sum]') do l = 0, p do k = 0, n do j = 0, m @@ -272,24 +272,25 @@ contains pb_local = 0._wp; mv_local = 0._wp; vflux = 0._wp; pbdot = 0._wp end if + adap_dt_stop = 0 + ! Adaptive time stepping if (adap_dt) then - adap_dt_stop = 0 - - call s_advance_step(myRho, myP, myR, myV, R0(q), pb_local, pbdot, alf, n_tait, B_tait, & - & bub_adv_src(j, k, l), divu_in%sf(j, k, l), dmBub_id, dmMass_v, dmMass_n, & - & dmBeta_c, dmBeta_t, dmCson, adap_dt_stop) + adap_dt_stop = f_advance_step(myRho, myP, myR, myV, R0(q), pb_local, pbdot, alf, n_tait, B_tait, & + & bub_adv_src(j, k, l), divu_in%sf(j, k, l), dmBub_id, dmMass_v, & + & dmMass_n, dmBeta_c, dmBeta_t, dmCson) q_cons_vf(rs(q))%sf(j, k, l) = nbub*myR q_cons_vf(vs(q))%sf(j, k, l) = nbub*myV - - adap_dt_stop_max = max(adap_dt_stop_max, adap_dt_stop) else rddot = f_rddot(myRho, myP, myR, myV, R0(q), pb_local, pbdot, alf, n_tait, B_tait, bub_adv_src(j, & & k, l), divu_in%sf(j, k, l), dmCson) bub_v_src(j, k, l, q) = nbub*rddot bub_r_src(j, k, l, q) = q_cons_vf(vs(q))%sf(j, k, l) end if + + $:GPU_ATOMIC(atomic='update') + adap_dt_stop_sum = adap_dt_stop_sum + adap_dt_stop end if end do end do @@ -297,7 +298,7 @@ contains end do $:END_GPU_PARALLEL_LOOP() - if (adap_dt .and. adap_dt_stop_max > 0) call s_mpi_abort("Adaptive time stepping failed to converge.") + if (adap_dt .and. adap_dt_stop_sum > 0) call s_mpi_abort("Adaptive time stepping failed to converge.") if (.not. adap_dt) then $:GPU_PARALLEL_LOOP(private='[i, k, l, q]', collapse=3) diff --git a/src/simulation/m_bubbles_EL.fpp b/src/simulation/m_bubbles_EL.fpp index 437dbe0db2..8a55d787ee 100644 --- a/src/simulation/m_bubbles_EL.fpp +++ b/src/simulation/m_bubbles_EL.fpp @@ -17,6 +17,9 @@ module m_bubbles_EL use m_helper_basic use m_sim_helpers use m_helper + use m_mpi_common + use m_ibm + use m_finite_differences implicit none @@ -57,20 +60,30 @@ module m_bubbles_EL integer, private :: lag_num_ts !< Number of time stages in the time-stepping scheme $:GPU_DECLARE(create='[lag_num_ts]') - integer :: nBubs !< Number of bubbles in the local domain real(wp) :: Rmax_glb, Rmin_glb !< Maximum and minimum bubbe size in the local domain !> Projection of the lagrangian particles in the Eulerian framework type(scalar_field), dimension(:), allocatable :: q_beta + type(scalar_field), dimension(:), allocatable :: kahan_comp !< Kahan compensation for q_beta accumulation integer :: q_beta_idx !< Size of the q_beta vector field - $:GPU_DECLARE(create='[nBubs, Rmax_glb, Rmin_glb, q_beta, q_beta_idx]') + + $:GPU_DECLARE(create='[Rmax_glb, Rmin_glb, q_beta, kahan_comp, q_beta_idx]') + + integer, parameter :: LAG_EVOL_ID = 11 ! File id for lag_bubbles_evol_*.dat + integer, parameter :: LAG_STATS_ID = 12 ! File id for stats_lag_bubbles_*.dat + integer, parameter :: LAG_VOID_ID = 13 ! File id for voidfraction.dat + integer, allocatable, dimension(:) :: keep_bubble + integer, allocatable, dimension(:,:) :: wrap_bubble_loc, wrap_bubble_dir + $:GPU_DECLARE(create='[keep_bubble]') + $:GPU_DECLARE(create='[wrap_bubble_loc, wrap_bubble_dir]') contains !> Initializes the lagrangian subgrid bubble solver - impure subroutine s_initialize_bubbles_EL_module(q_cons_vf) + impure subroutine s_initialize_bubbles_EL_module(q_cons_vf, bc_type) - type(scalar_field), dimension(sys_size), intent(inout) :: q_cons_vf - integer :: nBubs_glb, i + type(scalar_field), dimension(sys_size), intent(inout) :: q_cons_vf + type(integer_field), dimension(1:num_dims,1:2), intent(in) :: bc_type + integer :: nBubs_glb, i ! Setting number of time-stages for selected time-stepping scheme @@ -91,22 +104,36 @@ contains call s_mpi_abort('Please check the lag_params%solver_approach input') end if + pcomm_coords(1)%beg = x_cb(-1) + pcomm_coords(1)%end = x_cb(m) + $:GPU_UPDATE(device='[pcomm_coords(1)]') + if (n > 0) then + pcomm_coords(2)%beg = y_cb(-1) + pcomm_coords(2)%end = y_cb(n) + $:GPU_UPDATE(device='[pcomm_coords(2)]') + if (p > 0) then + pcomm_coords(3)%beg = z_cb(-1) + pcomm_coords(3)%end = z_cb(p) + $:GPU_UPDATE(device='[pcomm_coords(3)]') + end if + end if + $:GPU_UPDATE(device='[lag_num_ts, q_beta_idx]') @:ALLOCATE(q_beta(1:q_beta_idx)) + @:ALLOCATE(kahan_comp(1:q_beta_idx)) do i = 1, q_beta_idx @:ALLOCATE(q_beta(i)%sf(idwbuff(1)%beg:idwbuff(1)%end, idwbuff(2)%beg:idwbuff(2)%end, idwbuff(3)%beg:idwbuff(3)%end)) - end do - - do i = 1, q_beta_idx @:ACC_SETUP_SFs(q_beta(i)) + @:ALLOCATE(kahan_comp(i)%sf(idwbuff(1)%beg:idwbuff(1)%end, idwbuff(2)%beg:idwbuff(2)%end, & + & idwbuff(3)%beg:idwbuff(3)%end)) + @:ACC_SETUP_SFs(kahan_comp(i)) end do ! Allocating space for lagrangian variables nBubs_glb = lag_params%nBubs_glb - @:ALLOCATE(lag_id(1:nBubs_glb, 1:2)) @:ALLOCATE(bub_R0(1:nBubs_glb)) @:ALLOCATE(Rmax_stats(1:nBubs_glb)) @:ALLOCATE(Rmin_stats(1:nBubs_glb)) @@ -114,6 +141,7 @@ contains @:ALLOCATE(gas_betaT(1:nBubs_glb)) @:ALLOCATE(gas_betaC(1:nBubs_glb)) @:ALLOCATE(bub_dphidt(1:nBubs_glb)) + @:ALLOCATE(lag_id(1:nBubs_glb, 1:2)) @:ALLOCATE(gas_p(1:nBubs_glb, 1:2)) @:ALLOCATE(gas_mv(1:nBubs_glb, 1:2)) @:ALLOCATE(intfc_rad(1:nBubs_glb, 1:2)) @@ -129,23 +157,69 @@ contains @:ALLOCATE(mtn_dposdt(1:nBubs_glb, 1:3, 1:lag_num_ts)) @:ALLOCATE(mtn_dveldt(1:nBubs_glb, 1:3, 1:lag_num_ts)) + @:ALLOCATE(keep_bubble(1:nBubs_glb)) + @:ALLOCATE(wrap_bubble_loc(1:nBubs_glb, 1:num_dims), wrap_bubble_dir(1:nBubs_glb, 1:num_dims)) + if (adap_dt .and. f_is_default(adap_dt_tol)) adap_dt_tol = dflt_adap_dt_tol + if (num_procs > 1) call s_initialize_particles_mpi(lag_num_ts) + ! Starting bubbles - call s_read_input_bubbles(q_cons_vf) + if (lag_params%write_void_evol) call s_open_void_evol + if (lag_params%write_bubbles) call s_open_lag_bubble_evol() + if (lag_params%write_bubbles_stats) call s_open_lag_bubble_stats() + + if (lag_params%vel_model > 0) then + moving_lag_bubbles = .true. + lag_pressure_force = lag_params%pressure_force + lag_gravity_force = lag_params%gravity_force + lag_vel_model = lag_params%vel_model + lag_drag_model = lag_params%drag_model + end if + $:GPU_UPDATE(device='[moving_lag_bubbles, lag_pressure_force, lag_gravity_force, lag_vel_model, lag_drag_model]') + + ! Allocate cell-centered pressure gradient arrays and FD coefficients + if (lag_params%vel_model > 0 .and. lag_params%pressure_force) then + @:ALLOCATE(grad_p_x(0:m, 0:n, 0:p)) + @:ALLOCATE(fd_coeff_x_pgrad(-fd_number:fd_number, 0:m)) + call s_compute_finite_difference_coefficients(m, x_cc, fd_coeff_x_pgrad, buff_size, fd_number, fd_order) + $:GPU_UPDATE(device='[fd_coeff_x_pgrad]') + if (n > 0) then + @:ALLOCATE(grad_p_y(0:m, 0:n, 0:p)) + @:ALLOCATE(fd_coeff_y_pgrad(-fd_number:fd_number, 0:n)) + call s_compute_finite_difference_coefficients(n, y_cc, fd_coeff_y_pgrad, buff_size, fd_number, fd_order) + $:GPU_UPDATE(device='[fd_coeff_y_pgrad]') + end if + if (p > 0) then + @:ALLOCATE(grad_p_z(0:m, 0:n, 0:p)) + @:ALLOCATE(fd_coeff_z_pgrad(-fd_number:fd_number, 0:p)) + call s_compute_finite_difference_coefficients(p, z_cc, fd_coeff_z_pgrad, buff_size, fd_number, fd_order) + $:GPU_UPDATE(device='[fd_coeff_z_pgrad]') + end if + end if + + ! Allocate cell list arrays for atomic-free Gaussian smearing + @:ALLOCATE(cell_list_start(0:m, 0:n, 0:p)) + @:ALLOCATE(cell_list_count(0:m, 0:n, 0:p)) + @:ALLOCATE(cell_list_idx(1:lag_params%nBubs_glb)) + + call s_read_input_bubbles(q_cons_vf, bc_type) end subroutine s_initialize_bubbles_EL_module !> Read initial bubble data from input files - impure subroutine s_read_input_bubbles(q_cons_vf) + impure subroutine s_read_input_bubbles(q_cons_vf, bc_type) + + type(scalar_field), dimension(sys_size), intent(inout) :: q_cons_vf + type(integer_field), dimension(1:num_dims,1:2), intent(in) :: bc_type + real(wp), dimension(8) :: inputBubble + real(wp) :: qtime + integer :: id, bub_id, save_count + integer :: i, ios + logical :: file_exist, indomain + integer, dimension(3) :: cell + character(LEN=path_len + 2*name_len) :: path_D_dir - type(scalar_field), dimension(sys_size), intent(inout) :: q_cons_vf - real(wp), dimension(8) :: inputBubble - real(wp) :: qtime - integer :: id, bub_id, save_count - integer :: i, ios - logical :: file_exist, indomain - character(LEN=path_len + 2*name_len) :: path_D_dir ! Initialize number of particles bub_id = 0 @@ -162,9 +236,9 @@ contains if (save_count == 0) then if (proc_rank == 0) print *, 'Reading lagrange bubbles input file.' - inquire (file='input/lag_bubbles.dat', exist=file_exist) + call my_inquire(trim(lag_params%input_path), file_exist) if (file_exist) then - open (94, file='input/lag_bubbles.dat', form='formatted', iostat=ios) + open (94, file=trim(lag_params%input_path), form='formatted', iostat=ios) do while (ios == 0) read (94, *, iostat=ios) (inputBubble(i), i=1, 8) if (ios /= 0) cycle @@ -178,12 +252,12 @@ contains call s_add_bubbles(inputBubble, q_cons_vf, bub_id) lag_id(bub_id, 1) = id ! global ID lag_id(bub_id, 2) = bub_id ! local ID - nBubs = bub_id ! local number of bubbles + n_el_bubs_loc = bub_id ! local number of bubbles end if end do close (94) else - call s_mpi_abort("Initialize the lagrange bubbles in input/lag_bubbles.dat") + call s_mpi_abort("Initialize the lagrange bubbles in " // trim(lag_params%input_path)) end if else if (proc_rank == 0) print *, 'Restarting lagrange bubbles at save_count: ', save_count @@ -192,11 +266,21 @@ contains print *, " Lagrange bubbles running, in proc", proc_rank, "number:", bub_id, "/", id + if (num_procs > 1) then + call s_mpi_reduce_int_sum(n_el_bubs_loc, n_el_bubs_glb) + else + n_el_bubs_glb = n_el_bubs_loc + end if + + if (proc_rank == 0) then + if (n_el_bubs_glb == 0) call s_mpi_abort('No bubbles in the domain. Check ' // trim(lag_params%input_path)) + end if + $:GPU_UPDATE(device='[bubbles_lagrange, lag_params]') $:GPU_UPDATE(device='[lag_id, bub_R0, Rmax_stats, Rmin_stats, gas_mg, gas_betaT, gas_betaC, bub_dphidt, gas_p, gas_mv, & & intfc_rad, intfc_vel, mtn_pos, mtn_posPrev, mtn_vel, mtn_s, intfc_draddt, intfc_dveldt, gas_dpdt, & - & gas_dmvdt, mtn_dposdt, mtn_dveldt, nBubs]') + & gas_dmvdt, mtn_dposdt, mtn_dveldt, n_el_bubs_loc]') Rmax_glb = min(dflt_real, -dflt_real) Rmin_glb = max(dflt_real, -dflt_real) @@ -206,19 +290,22 @@ contains ! Populate temporal variables call s_transfer_data_to_tmp() - call s_smear_voidfraction() - - if (lag_params%write_bubbles) call s_write_lag_particles(qtime) + call s_smear_voidfraction(bc_type) if (save_count == 0) then ! Create ./D directory - write (path_D_dir, '(A,I0,A,I0)') trim(case_dir) // '/D' - call my_inquire(path_D_dir, file_exist) - if (.not. file_exist) call s_create_directory(trim(path_D_dir)) + if (proc_rank == 0) then + write (path_D_dir, '(A,I0,A,I0)') trim(case_dir) // '/D' + call my_inquire(trim(path_D_dir), file_exist) + if (.not. file_exist) call s_create_directory(trim(path_D_dir)) + end if + call s_mpi_barrier() call s_write_restart_lag_bubbles(save_count) ! Needed for post_processing - call s_write_void_evol(qtime) + if (lag_params%write_void_evol) call s_write_void_evol(qtime) end if + if (lag_params%write_bubbles) call s_write_lag_bubble_evol(qtime) + end subroutine s_read_input_bubbles !> Add a new bubble from input data for a fresh start @@ -256,7 +343,7 @@ contains mtn_posPrev(bub_id,1:3,1) = mtn_pos(bub_id,1:3,1) end if - cell = -buff_size + cell = fd_number - buff_size call s_locate_cell(mtn_pos(bub_id,1:3,1), cell, mtn_s(bub_id,1:3,1)) ! Check if the bubble is located in the ghost cell of a symmetric, or wall boundary @@ -349,7 +436,6 @@ contains integer :: i integer, dimension(:), allocatable :: proc_bubble_counts real(wp), dimension(1:1,1:lag_io_vars) :: dummy - dummy = 0._wp ! Construct file path @@ -431,7 +517,7 @@ contains call MPI_FILE_CLOSE(ifile, ierr) call MPI_TYPE_FREE(view, ierr) - nBubs = bub_id + n_el_bubs_loc = bub_id do i = 1, bub_id lag_id(i, 1) = int(MPI_IO_DATA_lag_bubbles(i, 1)) @@ -455,7 +541,7 @@ contains deallocate (MPI_IO_DATA_lag_bubbles) else - nBubs = 0 + n_el_bubs_loc = 0 call MPI_TYPE_CONTIGUOUS(0, mpi_p, view, ierr) call MPI_TYPE_COMMIT(view, ierr) @@ -484,16 +570,18 @@ contains end subroutine s_restart_bubbles !> Contains the bubble dynamics subroutines. - subroutine s_compute_bubble_EL_dynamics(q_prim_vf, stage) - - type(scalar_field), dimension(sys_size), intent(inout) :: q_prim_vf - integer, intent(in) :: stage - real(wp) :: myVapFlux - real(wp) :: preterm1, term2, paux, pint, Romega, term1_fac - real(wp) :: myR_m, mygamma_m, myPb, myMass_n, myMass_v - real(wp) :: myR, myV, myBeta_c, myBeta_t, myR0, myPbdot, myMvdot - real(wp) :: myPinf, aux1, aux2, myCson, myRho - real(wp) :: gamma, pi_inf, qv + subroutine s_compute_bubble_EL_dynamics(q_prim_vf, bc_type, stage) + + type(scalar_field), dimension(sys_size), intent(inout) :: q_prim_vf + type(integer_field), dimension(1:num_dims,1:2), intent(in) :: bc_type + integer, intent(in) :: stage + real(wp) :: myVapFlux + real(wp) :: preterm1, term2, paux, pint, Romega, term1_fac + real(wp) :: myR_m, mygamma_m, myPb, myMass_n, myMass_v + real(wp) :: myR, myV, myBeta_c, myBeta_t, myR0, myPbdot, myMvdot + real(wp) :: myPinf, aux1, aux2, myCson, myRho + real(wp), dimension(3) :: myPos, myVel + real(wp) :: gamma, pi_inf, qv, f_b, myRe #:if not MFC_CASE_OPTIMIZATION and USING_AMD real(wp), dimension(3) :: myalpha_rho, myalpha @@ -502,17 +590,16 @@ contains #:endif real(wp), dimension(2) :: Re integer, dimension(3) :: cell - integer :: adap_dt_stop_max, adap_dt_stop !< Fail-safe exit if max iteration count reached + integer :: adap_dt_stop_sum, adap_dt_stop !< Fail-safe exit if max iteration count reached real(wp) :: dmalf, dmntait, dmBtait, dm_bub_adv_src, dm_divu !< Dummy variables for unified subgrid bubble subroutines - integer :: i, k, l - - call nvtxStartRange("LAGRANGE-BUBBLE-DYNAMICS") + integer :: k, l ! Subgrid p_inf model based on Maeda and Colonius (2018). if (lag_params%pressure_corrector) then + call nvtxStartRange("LAGRANGE-BUBBLE-PINF-CORRECTION") ! Calculate velocity potentials (valid for one bubble per cell) $:GPU_PARALLEL_LOOP(private='[k, cell, paux, preterm1, term2, Romega, myR0, myR, myV, myPb, pint, term1_fac]') - do k = 1, nBubs + do k = 1, n_el_bubs_loc call s_get_pinf(k, q_prim_vf, 2, paux, cell, preterm1, term2, Romega) myR0 = bub_R0(k) myR = intfc_rad(k, 2) @@ -529,16 +616,24 @@ contains end if end do $:END_GPU_PARALLEL_LOOP() + call nvtxEndRange() + end if + + ! Precompute cell-centered pressure gradients for translational motion + if (moving_lag_bubbles .and. lag_pressure_force) then + call nvtxStartRange("LAGRANGE-BUBBLE-PRESSURE-GRADIENT") + call s_compute_pressure_gradients(q_prim_vf) + call nvtxEndRange() end if + call nvtxStartRange("LAGRANGE-BUBBLE-DYNAMICS") ! Radial motion model - adap_dt_stop_max = 0 - $:GPU_PARALLEL_LOOP(private='[k, i, myalpha_rho, myalpha, Re, cell, myVapFlux, preterm1, term2, paux, pint, Romega, & + adap_dt_stop_sum = 0 + $:GPU_PARALLEL_LOOP(private='[k, myalpha_rho, myalpha, Re, cell, myVapFlux, preterm1, term2, paux, pint, Romega, & & term1_fac, myR_m, mygamma_m, myPb, myMass_n, myMass_v, myR, myV, myBeta_c, myBeta_t, myR0, myPbdot, & & myMvdot, myPinf, aux1, aux2, myCson, myRho, gamma, pi_inf, qv, dmalf, dmntait, dmBtait, & - & dm_bub_adv_src, dm_divu, adap_dt_stop]', reduction='[[adap_dt_stop_max]]',reductionOp='[MAX]', & - & copy = '[adap_dt_stop_max]', copyin = '[stage]') - do k = 1, nBubs + & dm_bub_adv_src, dm_divu, adap_dt_stop, myPos, myVel]', copy='[adap_dt_stop_sum]',copyin='[stage]') + do k = 1, n_el_bubs_loc ! Keller-Miksis model ! Current bubble state @@ -550,6 +645,8 @@ contains myBeta_c = gas_betaC(k) myBeta_t = gas_betaT(k) myR0 = bub_R0(k) + myPos = mtn_pos(k,:,2) + myVel = mtn_vel(k,:,2) ! Vapor and heat fluxes call s_vflux(myR, myV, myPb, myMass_v, k, myVapFlux, myMass_n, myBeta_c, myR_m, mygamma_m) @@ -568,14 +665,20 @@ contains adap_dt_stop = 0 if (adap_dt) then - call s_advance_step(myRho, myPinf, myR, myV, myR0, myPb, myPbdot, dmalf, dmntait, dmBtait, dm_bub_adv_src, & - & dm_divu, k, myMass_v, myMass_n, myBeta_c, myBeta_t, myCson, adap_dt_stop) + mtn_posPrev(k,:,1) = myPos + + myRe = Re(1) + adap_dt_stop = f_advance_step(myRho, myPinf, myR, myV, myR0, myPb, myPbdot, dmalf, dmntait, dmBtait, & + & dm_bub_adv_src, dm_divu, k, myMass_v, myMass_n, myBeta_c, myBeta_t, myCson, myRe, & + & myPos, myVel, cell, q_prim_vf) ! Update bubble state intfc_rad(k, 1) = myR intfc_vel(k, 1) = myV gas_p(k, 1) = myPb gas_mv(k, 1) = myMass_v + mtn_pos(k,:,1) = myPos + mtn_vel(k,:,1) = myVel else ! Radial acceleration from bubble models intfc_dveldt(k, stage) = f_rddot(myRho, myPinf, myR, myV, myR0, myPb, myPbdot, dmalf, dmntait, dmBtait, & @@ -583,26 +686,46 @@ contains intfc_draddt(k, stage) = myV gas_dmvdt(k, stage) = myMvdot gas_dpdt(k, stage) = myPbdot + + if (moving_lag_bubbles) then + do l = 1, num_dims + select case (lag_vel_model) + case (1) + mtn_dposdt(k, l, stage) = f_interpolate_velocity(myPos(l), cell, l, q_prim_vf) + mtn_dveldt(k, l, stage) = 0._wp + case (2) + mtn_dposdt(k, l, stage) = myVel(l) + f_b = f_get_bubble_force(myPos(l), myR, myV, myVel(l), myMass_n, myMass_v, Re(1), myRho, cell, l, & + & q_prim_vf) + mtn_dveldt(k, l, stage) = f_b/(myMass_n + myMass_v) + case (3) + mtn_dposdt(k, l, stage) = myVel(l) + f_b = f_get_bubble_force(myPos(l), myR, myV, myVel(l), myMass_n, myMass_v, Re(1), myRho, cell, l, & + & q_prim_vf) + mtn_dveldt(k, l, stage) = 2._wp*f_b/(myMass_n + myMass_v) - 3._wp*myV*myVel(l)/myR + case default + mtn_dposdt(k, l, stage) = 0._wp + mtn_dveldt(k, l, stage) = 0._wp + end select + end do + end if end if - adap_dt_stop_max = max(adap_dt_stop_max, adap_dt_stop) + $:GPU_ATOMIC(atomic='update') + adap_dt_stop_sum = adap_dt_stop_sum + adap_dt_stop end do $:END_GPU_PARALLEL_LOOP() - - if (adap_dt .and. adap_dt_stop_max > 0) call s_mpi_abort("Adaptive time stepping failed to converge.") - ! Bubbles remain in a fixed position - $:GPU_PARALLEL_LOOP(collapse=2, private='[k, l]', copyin='[stage]') - do k = 1, nBubs - do l = 1, 3 - mtn_dposdt(k, l, stage) = 0._wp - mtn_dveldt(k, l, stage) = 0._wp - end do - end do - $:END_GPU_PARALLEL_LOOP() - call nvtxEndRange + if (adap_dt .and. adap_dt_stop_sum > 0) call s_mpi_abort("Adaptive time stepping failed to converge.") + + if (adap_dt) then + call s_transfer_data_to_tmp() + if (moving_lag_bubbles) call s_enforce_EL_bubbles_boundary_conditions(q_prim_vf) + call s_smear_voidfraction(bc_type) + end if + end subroutine s_compute_bubble_EL_dynamics !> Compute the Lagrangian bubble source terms and add them to the RHS @@ -613,87 +736,81 @@ contains type(scalar_field), dimension(sys_size), intent(inout) :: rhs_vf integer :: i, j, k, l - if (.not. adap_dt) call s_smear_voidfraction() - - if (lag_params%solver_approach == 2) then - ! (q / (1 - beta)) * d(beta)/dt source - if (p == 0) then - $:GPU_PARALLEL_LOOP(private='[i, j, k, l]', collapse=4) - do k = 0, p - do j = 0, n - do i = 0, m - do l = 1, E_idx - if (q_beta(1)%sf(i, j, k) > (1._wp - lag_params%valmaxvoid)) then - rhs_vf(l)%sf(i, j, k) = rhs_vf(l)%sf(i, j, k) + q_cons_vf(l)%sf(i, j, k)*(q_beta(2)%sf(i, j, & - & k) + q_beta(5)%sf(i, j, k)) - end if - end do + call nvtxStartRange("LAGRANGE-BUBBLE-EL-SOURCE") + if (lag_params%cluster_type >= 4) then + $:GPU_PARALLEL_LOOP(private='[i, j, k, l]', collapse=4) + do k = idwint(3)%beg, idwint(3)%end + do j = idwint(2)%beg, idwint(2)%end + do i = idwint(1)%beg, idwint(1)%end + do l = 1, E_idx + if (q_beta(1)%sf(i, j, k) > (1._wp - lag_params%valmaxvoid)) then + rhs_vf(l)%sf(i, j, k) = rhs_vf(l)%sf(i, j, k) + q_cons_vf(l)%sf(i, j, k)*(q_beta(2)%sf(i, j, & + & k) + q_beta(5)%sf(i, j, k)) + end if end do end do end do - $:END_GPU_PARALLEL_LOOP() - else - $:GPU_PARALLEL_LOOP(private='[i, j, k, l]', collapse=4) - do k = 0, p - do j = 0, n - do i = 0, m - do l = 1, E_idx - if (q_beta(1)%sf(i, j, k) > (1._wp - lag_params%valmaxvoid)) then - rhs_vf(l)%sf(i, j, k) = rhs_vf(l)%sf(i, j, k) + q_cons_vf(l)%sf(i, j, k)/q_beta(1)%sf(i, j, & - & k)*q_beta(2)%sf(i, j, k) - end if - end do + end do + $:END_GPU_PARALLEL_LOOP() + else + $:GPU_PARALLEL_LOOP(private='[i, j, k, l]', collapse=4) + do k = idwint(3)%beg, idwint(3)%end + do j = idwint(2)%beg, idwint(2)%end + do i = idwint(1)%beg, idwint(1)%end + do l = 1, E_idx + if (q_beta(1)%sf(i, j, k) > (1._wp - lag_params%valmaxvoid)) then + rhs_vf(l)%sf(i, j, k) = rhs_vf(l)%sf(i, j, k) + (q_cons_vf(l)%sf(i, j, k)/q_beta(1)%sf(i, j, & + & k))*q_beta(2)%sf(i, j, k) + end if end do end do end do - $:END_GPU_PARALLEL_LOOP() - end if + end do + $:END_GPU_PARALLEL_LOOP() + end if - do l = 1, num_dims - call s_gradient_dir(q_prim_vf(E_idx)%sf, q_beta(3)%sf, l) + do l = 1, num_dims + call s_gradient_dir(q_prim_vf(E_idx)%sf, q_beta(3)%sf, l) - ! (q / (1 - beta)) * d(beta)/dt source - $:GPU_PARALLEL_LOOP(private='[i, j, k]', collapse=3) - do k = 0, p - do j = 0, n - do i = 0, m - if (q_beta(1)%sf(i, j, k) > (1._wp - lag_params%valmaxvoid)) then - rhs_vf(contxe + l)%sf(i, j, k) = rhs_vf(contxe + l)%sf(i, j, k) - (1._wp - q_beta(1)%sf(i, j, & - & k))/q_beta(1)%sf(i, j, k)*q_beta(3)%sf(i, j, k) - end if - end do + $:GPU_PARALLEL_LOOP(private='[i, j, k]', collapse=3) + do k = idwint(3)%beg, idwint(3)%end + do j = idwint(2)%beg, idwint(2)%end + do i = idwint(1)%beg, idwint(1)%end + if (q_beta(1)%sf(i, j, k) > (1._wp - lag_params%valmaxvoid)) then + rhs_vf(contxe + l)%sf(i, j, k) = rhs_vf(contxe + l)%sf(i, j, k) - (1._wp - q_beta(1)%sf(i, j, & + & k))/q_beta(1)%sf(i, j, k)*q_beta(3)%sf(i, j, k) + end if end do end do - $:END_GPU_PARALLEL_LOOP() + end do + $:END_GPU_PARALLEL_LOOP() - ! source in energy - $:GPU_PARALLEL_LOOP(private='[i, j, k]', collapse=3) - do k = idwbuff(3)%beg, idwbuff(3)%end - do j = idwbuff(2)%beg, idwbuff(2)%end - do i = idwbuff(1)%beg, idwbuff(1)%end - q_beta(3)%sf(i, j, k) = q_prim_vf(E_idx)%sf(i, j, k)*q_prim_vf(contxe + l)%sf(i, j, k) - end do + $:GPU_PARALLEL_LOOP(private='[i, j, k]', collapse=3) + do k = idwbuff(3)%beg, idwbuff(3)%end + do j = idwbuff(2)%beg, idwbuff(2)%end + do i = idwbuff(1)%beg, idwbuff(1)%end + q_beta(3)%sf(i, j, k) = q_prim_vf(E_idx)%sf(i, j, k)*q_prim_vf(contxe + l)%sf(i, j, k) end do end do - $:END_GPU_PARALLEL_LOOP() + end do + $:END_GPU_PARALLEL_LOOP() - call s_gradient_dir(q_beta(3)%sf, q_beta(4)%sf, l) + call s_gradient_dir(q_beta(3)%sf, q_beta(4)%sf, l) - ! (beta / (1 - beta)) * d(Pu)/dl source - $:GPU_PARALLEL_LOOP(private='[i, j, k]', collapse=3) - do k = 0, p - do j = 0, n - do i = 0, m - if (q_beta(1)%sf(i, j, k) > (1._wp - lag_params%valmaxvoid)) then - rhs_vf(E_idx)%sf(i, j, k) = rhs_vf(E_idx)%sf(i, j, k) - q_beta(4)%sf(i, j, & - & k)*(1._wp - q_beta(1)%sf(i, j, k))/q_beta(1)%sf(i, j, k) - end if - end do + $:GPU_PARALLEL_LOOP(private='[i, j, k]', collapse=3) + do k = idwint(3)%beg, idwint(3)%end + do j = idwint(2)%beg, idwint(2)%end + do i = idwint(1)%beg, idwint(1)%end + if (q_beta(1)%sf(i, j, k) > (1._wp - lag_params%valmaxvoid)) then + rhs_vf(E_idx)%sf(i, j, k) = rhs_vf(E_idx)%sf(i, j, k) - q_beta(4)%sf(i, j, & + & k)*(1._wp - q_beta(1)%sf(i, j, k))/q_beta(1)%sf(i, j, k) + end if end do end do - $:END_GPU_PARALLEL_LOOP() end do - end if + $:END_GPU_PARALLEL_LOOP() + end do + call nvtxEndRange end subroutine s_compute_bubbles_EL_source @@ -726,25 +843,37 @@ contains end subroutine s_compute_cson_from_pinf !> Smear the bubble effects onto the Eulerian grid - subroutine s_smear_voidfraction() + subroutine s_smear_voidfraction(bc_type) - integer :: i, j, k, l - - call nvtxStartRange("BUBBLES-LAGRANGE-KERNELS") + type(integer_field), dimension(1:num_dims,1:2), intent(in) :: bc_type + integer :: i, j, k, l + call nvtxStartRange("BUBBLES-LAGRANGE-SMEARING") $:GPU_PARALLEL_LOOP(private='[i, j, k, l]', collapse=4) do i = 1, q_beta_idx do l = idwbuff(3)%beg, idwbuff(3)%end do k = idwbuff(2)%beg, idwbuff(2)%end do j = idwbuff(1)%beg, idwbuff(1)%end q_beta(i)%sf(j, k, l) = 0._wp + kahan_comp(i)%sf(j, k, l) = 0._wp end do end do end do end do $:END_GPU_PARALLEL_LOOP() - call s_smoothfunction(nBubs, intfc_rad, intfc_vel, mtn_s, mtn_pos, q_beta) + ! Build cell list before smearing (CPU-side counting sort) + call s_build_cell_list(n_el_bubs_loc, mtn_s) + + call s_smoothfunction(n_el_bubs_loc, intfc_rad, intfc_vel, mtn_s, mtn_pos, q_beta, kahan_comp) + + call nvtxStartRange("BUBBLES-LAGRANGE-BETA-COMM") + if (lag_params%cluster_type >= 4) then + call s_populate_beta_buffers(q_beta, bc_type, 3) + else + call s_populate_beta_buffers(q_beta, bc_type, 2) + end if + call nvtxEndRange ! Store 1-beta $:GPU_PARALLEL_LOOP(private='[j, k, l]', collapse=3) @@ -758,7 +887,6 @@ contains end do end do $:END_GPU_PARALLEL_LOOP() - call nvtxEndRange end subroutine s_smear_voidfraction @@ -773,91 +901,164 @@ contains real(wp), intent(out) :: f_pinfl integer, dimension(3), intent(out) :: cell real(wp), intent(out), optional :: preterm1, term2, Romega - real(wp), dimension(3) :: scoord, psi + real(wp), dimension(3) :: scoord, psi_pos, psi_x, psi_y, psi_z + real(wp) :: xi, eta, zeta real(wp) :: dc, vol, aux real(wp) :: volgas, term1, Rbeq, denom real(wp) :: charvol, charpres, charvol2, charpres2 integer, dimension(3) :: cellaux integer :: i, j, k integer :: smearGrid, smearGridz - logical :: celloutside - scoord = mtn_s(bub_id,1:3,2) f_pinfl = 0._wp !> Find current bubble cell - cell(:) = int(scoord(:)) - $:GPU_LOOP(parallelism='[seq]') - do i = 1, num_dims - if (scoord(i) < 0._wp) cell(i) = cell(i) - 1 - end do + if (moving_lag_bubbles) then + cell = fd_number - buff_size + call s_locate_cell(mtn_pos(bub_id,1:3,2), cell, mtn_s(bub_id,1:3,2)) + scoord = mtn_s(bub_id,1:3,2) + else + scoord = mtn_s(bub_id,1:3,2) + cell(:) = int(scoord(:)) + $:GPU_LOOP(parallelism='[seq]') + do i = 1, num_dims + if (scoord(i) < 0._wp) cell(i) = cell(i) - 1 + end do + end if if ((lag_params%cluster_type == 1)) then !> Getting p_cell in terms of only the current cell by interpolation !> Getting the cell volulme as Omega - if (p > 0) then - vol = dx(cell(1))*dy(cell(2))*dz(cell(3)) - else - if (cyl_coord) then - vol = dx(cell(1))*dy(cell(2))*y_cc(cell(2))*2._wp*pi + + if (fd_order == 2) then ! Bilinear interpolation + + if (p > 0) then + vol = dx(cell(1))*dy(cell(2))*dz(cell(3)) else - vol = dx(cell(1))*dy(cell(2))*lag_params%charwidth + if (cyl_coord) then + vol = dx(cell(1))*dy(cell(2))*y_cc(cell(2))*2._wp*pi + else + vol = dx(cell(1))*dy(cell(2))*lag_params%charwidth + end if end if - end if + !> Obtain bilinear interpolation coefficients, based on the current location of the bubble. - !> Obtain bilinear interpolation coefficients, based on the current location of the bubble. - psi(1) = (scoord(1) - real(cell(1)))*dx(cell(1)) + x_cb(cell(1) - 1) - if (cell(1) == (m + buff_size)) then - cell(1) = cell(1) - 1 - psi(1) = 1._wp - else if (cell(1) == (-buff_size)) then - psi(1) = 0._wp - else - if (psi(1) < x_cc(cell(1))) cell(1) = cell(1) - 1 - psi(1) = abs((psi(1) - x_cc(cell(1)))/(x_cc(cell(1) + 1) - x_cc(cell(1)))) - end if + psi_pos(1) = (scoord(1) - real(cell(1)))*dx(cell(1)) + x_cb(cell(1) - 1) + psi_pos(1) = abs((psi_pos(1) - x_cc(cell(1)))/(x_cc(cell(1) + 1) - x_cc(cell(1)))) - psi(2) = (scoord(2) - real(cell(2)))*dy(cell(2)) + y_cb(cell(2) - 1) - if (cell(2) == (n + buff_size)) then - cell(2) = cell(2) - 1 - psi(2) = 1._wp - else if (cell(2) == (-buff_size)) then - psi(2) = 0._wp - else - if (psi(2) < y_cc(cell(2))) cell(2) = cell(2) - 1 - psi(2) = abs((psi(2) - y_cc(cell(2)))/(y_cc(cell(2) + 1) - y_cc(cell(2)))) - end if + psi_pos(2) = (scoord(2) - real(cell(2)))*dy(cell(2)) + y_cb(cell(2) - 1) + psi_pos(2) = abs((psi_pos(2) - y_cc(cell(2)))/(y_cc(cell(2) + 1) - y_cc(cell(2)))) - if (p > 0) then - psi(3) = (scoord(3) - real(cell(3)))*dz(cell(3)) + z_cb(cell(3) - 1) - if (cell(3) == (p + buff_size)) then - cell(3) = cell(3) - 1 - psi(3) = 1._wp - else if (cell(3) == (-buff_size)) then - psi(3) = 0._wp + if (p > 0) then + psi_pos(3) = (scoord(3) - real(cell(3)))*dz(cell(3)) + z_cb(cell(3) - 1) + psi_pos(3) = abs((psi_pos(3) - z_cc(cell(3)))/(z_cc(cell(3) + 1) - z_cc(cell(3)))) else - if (psi(3) < z_cc(cell(3))) cell(3) = cell(3) - 1 - psi(3) = abs((psi(3) - z_cc(cell(3)))/(z_cc(cell(3) + 1) - z_cc(cell(3)))) + psi_pos(3) = 0._wp + end if + !> Perform bilinear interpolation + + ! X-direction basis functions + psi_x(1) = 1._wp - psi_pos(1) ! Left basis function + psi_x(2) = psi_pos(1) ! Right basis function + + ! Y-direction basis functions + psi_y(1) = 1._wp - psi_pos(2) ! Left basis function + psi_y(2) = psi_pos(2) ! Right basis function + + if (p > 0) then + ! Z-direction basis functions + psi_z(1) = 1._wp - psi_pos(3) ! Left basis function + psi_z(2) = psi_pos(3) ! Right basis function + else ! 3D + psi_z(1) = 1._wp + psi_z(2) = 0._wp + end if + + f_pinfl = 0._wp + + if (p == 0) then + do j = 1, 2 + do i = 1, 2 + f_pinfl = f_pinfl + q_prim_vf(E_idx)%sf(cell(1) + i - 1, cell(2) + j - 1, cell(3))*psi_x(i)*psi_y(j) + end do + end do + else + do k = 1, 2 + do j = 1, 2 + do i = 1, 2 + f_pinfl = f_pinfl + q_prim_vf(E_idx)%sf(cell(1) + i - 1, cell(2) + j - 1, & + & cell(3) + k - 1)*psi_x(i)*psi_y(j)*psi_z(k) + end do + end do + end do + end if + else if (fd_order == 4) then ! Biquadratic interpolation + if (p > 0) then + vol = dx(cell(1))*dy(cell(2))*dz(cell(3)) + else + if (cyl_coord) then + vol = dx(cell(1))*dy(cell(2))*y_cc(cell(2))*2._wp*pi + else + vol = dx(cell(1))*dy(cell(2))*lag_params%charwidth + end if + end if + + ! For biquadratic interpolation, we need coefficients for 3 points in each direction + psi_pos(1) = (scoord(1) - real(cell(1)))*dx(cell(1)) + x_cb(cell(1) - 1) + psi_pos(1) = (psi_pos(1) - x_cc(cell(1)))/(x_cc(cell(1) + 1) - x_cc(cell(1))) + + psi_pos(2) = (scoord(2) - real(cell(2)))*dy(cell(2)) + y_cb(cell(2) - 1) + psi_pos(2) = (psi_pos(2) - y_cc(cell(2)))/(y_cc(cell(2) + 1) - y_cc(cell(2))) + + if (p > 0) then + psi_pos(3) = (scoord(3) - real(cell(3)))*dz(cell(3)) + z_cb(cell(3) - 1) + psi_pos(3) = (psi_pos(3) - z_cc(cell(3)))/(z_cc(cell(3) + 1) - z_cc(cell(3))) + else + psi_pos(3) = 0._wp + end if + + ! X-direction basis functions + xi = 2._wp*psi_pos(1) - 1._wp ! Convert to [-1, 1] range + psi_x(1) = xi*(xi - 1._wp)/2._wp ! Left basis function + psi_x(2) = (1._wp - xi)*(1._wp + xi) ! Center basis function + psi_x(3) = xi*(xi + 1._wp)/2._wp ! Right basis function + + ! Y-direction basis functions + eta = 2._wp*psi_pos(2) - 1._wp ! Convert to [-1, 1] range + psi_y(1) = eta*(eta - 1._wp)/2._wp ! Left basis function + psi_y(2) = (1._wp - eta)*(1._wp + eta) ! Center basis function + psi_y(3) = eta*(eta + 1._wp)/2._wp ! Right basis function + + if (p > 0) then + ! Z-direction basis functions + zeta = 2._wp*psi_pos(3) - 1._wp ! Convert to [-1, 1] range + psi_z(1) = zeta*(zeta - 1._wp)/2._wp ! Left basis function + psi_z(2) = (1._wp - zeta)*(1._wp + zeta) ! Center basis function + psi_z(3) = zeta*(zeta + 1._wp)/2._wp ! Right basis function + else + psi_z(1) = 0._wp + psi_z(2) = 1._wp + psi_z(3) = 0._wp end if - else - psi(3) = 0._wp - end if - !> Perform bilinear interpolation - if (p == 0) then ! 2D - f_pinfl = q_prim_vf(E_idx)%sf(cell(1), cell(2), cell(3))*(1._wp - psi(1))*(1._wp - psi(2)) - f_pinfl = f_pinfl + q_prim_vf(E_idx)%sf(cell(1) + 1, cell(2), cell(3))*psi(1)*(1._wp - psi(2)) - f_pinfl = f_pinfl + q_prim_vf(E_idx)%sf(cell(1) + 1, cell(2) + 1, cell(3))*psi(1)*psi(2) - f_pinfl = f_pinfl + q_prim_vf(E_idx)%sf(cell(1), cell(2) + 1, cell(3))*(1._wp - psi(1))*psi(2) - else ! 3D - f_pinfl = q_prim_vf(E_idx)%sf(cell(1), cell(2), cell(3))*(1._wp - psi(1))*(1._wp - psi(2))*(1._wp - psi(3)) - f_pinfl = f_pinfl + q_prim_vf(E_idx)%sf(cell(1) + 1, cell(2), cell(3))*psi(1)*(1._wp - psi(2))*(1._wp - psi(3)) - f_pinfl = f_pinfl + q_prim_vf(E_idx)%sf(cell(1) + 1, cell(2) + 1, cell(3))*psi(1)*psi(2)*(1._wp - psi(3)) - f_pinfl = f_pinfl + q_prim_vf(E_idx)%sf(cell(1), cell(2) + 1, cell(3))*(1._wp - psi(1))*psi(2)*(1._wp - psi(3)) - f_pinfl = f_pinfl + q_prim_vf(E_idx)%sf(cell(1), cell(2), cell(3) + 1)*(1._wp - psi(1))*(1._wp - psi(2))*psi(3) - f_pinfl = f_pinfl + q_prim_vf(E_idx)%sf(cell(1) + 1, cell(2), cell(3) + 1)*psi(1)*(1._wp - psi(2))*psi(3) - f_pinfl = f_pinfl + q_prim_vf(E_idx)%sf(cell(1) + 1, cell(2) + 1, cell(3) + 1)*psi(1)*psi(2)*psi(3) - f_pinfl = f_pinfl + q_prim_vf(E_idx)%sf(cell(1), cell(2) + 1, cell(3) + 1)*(1._wp - psi(1))*psi(2)*psi(3) + f_pinfl = 0._wp + + if (p == 0) then ! 2D + do j = 1, 3 + do i = 1, 3 + f_pinfl = f_pinfl + q_prim_vf(E_idx)%sf(cell(1) + i - 2, cell(2) + j - 2, cell(3))*psi_x(i)*psi_y(j) + end do + end do + else + do k = 1, 3 + do j = 1, 3 + do i = 1, 3 + f_pinfl = f_pinfl + q_prim_vf(E_idx)%sf(cell(1) + i - 2, cell(2) + j - 2, & + & cell(3) + k - 2)*psi_x(i)*psi_y(j)*psi_z(k) + end do + end do + end do + end if end if ! R_Omega @@ -888,55 +1089,25 @@ contains if (p == 0) cellaux(3) = 0 !> check if the current cell is outside the computational domain or not (including ghost cells) - celloutside = .false. - if (num_dims == 2) then - if ((cellaux(1) < -buff_size) .or. (cellaux(2) < -buff_size)) then - celloutside = .true. - end if - if (cyl_coord .and. y_cc(cellaux(2)) < 0._wp) then - celloutside = .true. - end if - if ((cellaux(2) > n + buff_size) .or. (cellaux(1) > m + buff_size)) then - celloutside = .true. - end if + if (p > 0) then + vol = dx(cellaux(1))*dy(cellaux(2))*dz(cellaux(3)) else - if ((cellaux(3) < -buff_size) .or. (cellaux(1) < -buff_size) .or. (cellaux(2) < -buff_size)) then - celloutside = .true. - end if - - if ((cellaux(3) > p + buff_size) .or. (cellaux(2) > n + buff_size) .or. (cellaux(1) > m + buff_size)) & - & then - celloutside = .true. - end if - end if - if (.not. celloutside) then - if (cyl_coord .and. (p == 0) .and. (y_cc(cellaux(2)) < 0._wp)) then - celloutside = .true. - end if - end if - - if (.not. celloutside) then - !> Obtaining the cell volulme - if (p > 0) then - vol = dx(cellaux(1))*dy(cellaux(2))*dz(cellaux(3)) + if (cyl_coord) then + vol = dx(cellaux(1))*dy(cellaux(2))*y_cc(cellaux(2))*2._wp*pi else - if (cyl_coord) then - vol = dx(cellaux(1))*dy(cellaux(2))*y_cc(cellaux(2))*2._wp*pi - else - vol = dx(cellaux(1))*dy(cellaux(2))*lag_params%charwidth - end if + vol = dx(cellaux(1))*dy(cellaux(2))*lag_params%charwidth end if - !> Update values - charvol = charvol + vol - charpres = charpres + q_prim_vf(E_idx)%sf(cellaux(1), cellaux(2), cellaux(3))*vol - charvol2 = charvol2 + vol*q_beta(1)%sf(cellaux(1), cellaux(2), cellaux(3)) - charpres2 = charpres2 + q_prim_vf(E_idx)%sf(cellaux(1), cellaux(2), & - & cellaux(3))*vol*q_beta(1)%sf(cellaux(1), cellaux(2), cellaux(3)) end if + !> Obtaining the cell volulme + !> Update values + charvol = charvol + vol + charpres = charpres + q_prim_vf(E_idx)%sf(cellaux(1), cellaux(2), cellaux(3))*vol + charvol2 = charvol2 + vol*q_beta(1)%sf(cellaux(1), cellaux(2), cellaux(3)) + charpres2 = charpres2 + q_prim_vf(E_idx)%sf(cellaux(1), cellaux(2), & + & cellaux(3))*vol*q_beta(1)%sf(cellaux(1), cellaux(2), cellaux(3)) end do end do end do - f_pinfl = charpres2/charvol2 vol = charvol dc = (3._wp*abs(vol)/(4._wp*pi))**(1._wp/3._wp) @@ -967,116 +1138,148 @@ contains end subroutine s_get_pinf !> Update Lagrangian bubble variables using TVD Runge-Kutta time stepping - impure subroutine s_update_lagrange_tdv_rk(stage) + impure subroutine s_update_lagrange_tdv_rk(q_prim_vf, bc_type, stage) - integer, intent(in) :: stage - integer :: k + type(scalar_field), dimension(sys_size), intent(in) :: q_prim_vf + type(integer_field), dimension(1:num_dims,1:2), intent(in) :: bc_type + integer, intent(in) :: stage + integer :: k if (time_stepper == 1) then ! 1st order TVD RK $:GPU_PARALLEL_LOOP(private='[k]') - do k = 1, nBubs + do k = 1, n_el_bubs_loc ! u{1} = u{n} + dt * RHS{n} intfc_rad(k, 1) = intfc_rad(k, 1) + dt*intfc_draddt(k, 1) intfc_vel(k, 1) = intfc_vel(k, 1) + dt*intfc_dveldt(k, 1) - mtn_pos(k,1:3,1) = mtn_pos(k,1:3,1) + dt*mtn_dposdt(k,1:3,1) - mtn_vel(k,1:3,1) = mtn_vel(k,1:3,1) + dt*mtn_dveldt(k,1:3,1) gas_p(k, 1) = gas_p(k, 1) + dt*gas_dpdt(k, 1) gas_mv(k, 1) = gas_mv(k, 1) + dt*gas_dmvdt(k, 1) + if (moving_lag_bubbles) then + mtn_posPrev(k,1:3,1) = mtn_pos(k,1:3,1) + mtn_pos(k,1:3,1) = mtn_pos(k,1:3,1) + dt*mtn_dposdt(k,1:3,1) + mtn_vel(k,1:3,1) = mtn_vel(k,1:3,1) + dt*mtn_dveldt(k,1:3,1) + end if end do $:END_GPU_PARALLEL_LOOP() call s_transfer_data_to_tmp() - call s_write_void_evol(mytime) + if (moving_lag_bubbles) call s_enforce_EL_bubbles_boundary_conditions(q_prim_vf) + call s_smear_voidfraction(bc_type) + if (lag_params%write_void_evol) call s_write_void_evol(mytime) if (lag_params%write_bubbles_stats) call s_calculate_lag_bubble_stats() - if (lag_params%write_bubbles) then $:GPU_UPDATE(host='[gas_p, gas_mv, intfc_rad, intfc_vel]') - call s_write_lag_particles(mytime) + call s_write_lag_bubble_evol(mytime) end if else if (time_stepper == 2) then ! 2nd order TVD RK if (stage == 1) then $:GPU_PARALLEL_LOOP(private='[k]') - do k = 1, nBubs + do k = 1, n_el_bubs_loc ! u{1} = u{n} + dt * RHS{n} intfc_rad(k, 2) = intfc_rad(k, 1) + dt*intfc_draddt(k, 1) intfc_vel(k, 2) = intfc_vel(k, 1) + dt*intfc_dveldt(k, 1) - mtn_pos(k,1:3,2) = mtn_pos(k,1:3,1) + dt*mtn_dposdt(k,1:3,1) - mtn_vel(k,1:3,2) = mtn_vel(k,1:3,1) + dt*mtn_dveldt(k,1:3,1) gas_p(k, 2) = gas_p(k, 1) + dt*gas_dpdt(k, 1) gas_mv(k, 2) = gas_mv(k, 1) + dt*gas_dmvdt(k, 1) + if (moving_lag_bubbles) then + mtn_posPrev(k,1:3,2) = mtn_pos(k,1:3,1) + mtn_pos(k,1:3,2) = mtn_pos(k,1:3,1) + dt*mtn_dposdt(k,1:3,1) + mtn_vel(k,1:3,2) = mtn_vel(k,1:3,1) + dt*mtn_dveldt(k,1:3,1) + end if end do $:END_GPU_PARALLEL_LOOP() + + if (moving_lag_bubbles) call s_enforce_EL_bubbles_boundary_conditions(q_prim_vf) + call s_smear_voidfraction(bc_type) else if (stage == 2) then $:GPU_PARALLEL_LOOP(private='[k]') - do k = 1, nBubs + do k = 1, n_el_bubs_loc ! u{1} = u{n} + (1/2) * dt * (RHS{n} + RHS{1}) intfc_rad(k, 1) = intfc_rad(k, 1) + dt*(intfc_draddt(k, 1) + intfc_draddt(k, 2))/2._wp intfc_vel(k, 1) = intfc_vel(k, 1) + dt*(intfc_dveldt(k, 1) + intfc_dveldt(k, 2))/2._wp - mtn_pos(k,1:3,1) = mtn_pos(k,1:3,1) + dt*(mtn_dposdt(k,1:3,1) + mtn_dposdt(k,1:3,2))/2._wp - mtn_vel(k,1:3,1) = mtn_vel(k,1:3,1) + dt*(mtn_dveldt(k,1:3,1) + mtn_dveldt(k,1:3,2))/2._wp gas_p(k, 1) = gas_p(k, 1) + dt*(gas_dpdt(k, 1) + gas_dpdt(k, 2))/2._wp gas_mv(k, 1) = gas_mv(k, 1) + dt*(gas_dmvdt(k, 1) + gas_dmvdt(k, 2))/2._wp + if (moving_lag_bubbles) then + mtn_posPrev(k,1:3,1) = mtn_pos(k,1:3,2) + mtn_pos(k,1:3,1) = mtn_pos(k,1:3,1) + dt*(mtn_dposdt(k,1:3,1) + mtn_dposdt(k,1:3,2))/2._wp + mtn_vel(k,1:3,1) = mtn_vel(k,1:3,1) + dt*(mtn_dveldt(k,1:3,1) + mtn_dveldt(k,1:3,2))/2._wp + end if end do $:END_GPU_PARALLEL_LOOP() call s_transfer_data_to_tmp() - call s_write_void_evol(mytime) + if (moving_lag_bubbles) call s_enforce_EL_bubbles_boundary_conditions(q_prim_vf) + call s_smear_voidfraction(bc_type) + if (lag_params%write_void_evol) call s_write_void_evol(mytime) if (lag_params%write_bubbles_stats) call s_calculate_lag_bubble_stats() - if (lag_params%write_bubbles) then $:GPU_UPDATE(host='[gas_p, gas_mv, intfc_rad, intfc_vel]') - call s_write_lag_particles(mytime) + call s_write_lag_bubble_evol(mytime) end if end if else if (time_stepper == 3) then ! 3rd order TVD RK if (stage == 1) then $:GPU_PARALLEL_LOOP(private='[k]') - do k = 1, nBubs + do k = 1, n_el_bubs_loc ! u{1} = u{n} + dt * RHS{n} intfc_rad(k, 2) = intfc_rad(k, 1) + dt*intfc_draddt(k, 1) intfc_vel(k, 2) = intfc_vel(k, 1) + dt*intfc_dveldt(k, 1) - mtn_pos(k,1:3,2) = mtn_pos(k,1:3,1) + dt*mtn_dposdt(k,1:3,1) - mtn_vel(k,1:3,2) = mtn_vel(k,1:3,1) + dt*mtn_dveldt(k,1:3,1) gas_p(k, 2) = gas_p(k, 1) + dt*gas_dpdt(k, 1) gas_mv(k, 2) = gas_mv(k, 1) + dt*gas_dmvdt(k, 1) + if (moving_lag_bubbles) then + mtn_posPrev(k,1:3,2) = mtn_pos(k,1:3,1) + mtn_pos(k,1:3,2) = mtn_pos(k,1:3,1) + dt*mtn_dposdt(k,1:3,1) + mtn_vel(k,1:3,2) = mtn_vel(k,1:3,1) + dt*mtn_dveldt(k,1:3,1) + end if end do $:END_GPU_PARALLEL_LOOP() + + if (moving_lag_bubbles) call s_enforce_EL_bubbles_boundary_conditions(q_prim_vf) + call s_smear_voidfraction(bc_type) else if (stage == 2) then $:GPU_PARALLEL_LOOP(private='[k]') - do k = 1, nBubs + do k = 1, n_el_bubs_loc ! u{2} = u{n} + (1/4) * dt * [RHS{n} + RHS{1}] intfc_rad(k, 2) = intfc_rad(k, 1) + dt*(intfc_draddt(k, 1) + intfc_draddt(k, 2))/4._wp intfc_vel(k, 2) = intfc_vel(k, 1) + dt*(intfc_dveldt(k, 1) + intfc_dveldt(k, 2))/4._wp - mtn_pos(k,1:3,2) = mtn_pos(k,1:3,1) + dt*(mtn_dposdt(k,1:3,1) + mtn_dposdt(k,1:3,2))/4._wp - mtn_vel(k,1:3,2) = mtn_vel(k,1:3,1) + dt*(mtn_dveldt(k,1:3,1) + mtn_dveldt(k,1:3,2))/4._wp gas_p(k, 2) = gas_p(k, 1) + dt*(gas_dpdt(k, 1) + gas_dpdt(k, 2))/4._wp gas_mv(k, 2) = gas_mv(k, 1) + dt*(gas_dmvdt(k, 1) + gas_dmvdt(k, 2))/4._wp + if (moving_lag_bubbles) then + mtn_posPrev(k,1:3,2) = mtn_pos(k,1:3,2) + mtn_pos(k,1:3,2) = mtn_pos(k,1:3,1) + dt*(mtn_dposdt(k,1:3,1) + mtn_dposdt(k,1:3,2))/4._wp + mtn_vel(k,1:3,2) = mtn_vel(k,1:3,1) + dt*(mtn_dveldt(k,1:3,1) + mtn_dveldt(k,1:3,2))/4._wp + end if end do $:END_GPU_PARALLEL_LOOP() + + if (moving_lag_bubbles) call s_enforce_EL_bubbles_boundary_conditions(q_prim_vf) + call s_smear_voidfraction(bc_type) else if (stage == 3) then $:GPU_PARALLEL_LOOP(private='[k]') - do k = 1, nBubs + do k = 1, n_el_bubs_loc ! u{n+1} = u{n} + (2/3) * dt * [(1/4)* RHS{n} + (1/4)* RHS{1} + RHS{2}] intfc_rad(k, 1) = intfc_rad(k, 1) + (2._wp/3._wp)*dt*(intfc_draddt(k, 1)/4._wp + intfc_draddt(k, & & 2)/4._wp + intfc_draddt(k, 3)) intfc_vel(k, 1) = intfc_vel(k, 1) + (2._wp/3._wp)*dt*(intfc_dveldt(k, 1)/4._wp + intfc_dveldt(k, & & 2)/4._wp + intfc_dveldt(k, 3)) - mtn_pos(k,1:3,1) = mtn_pos(k,1:3,1) + (2._wp/3._wp)*dt*(mtn_dposdt(k,1:3,1)/4._wp + mtn_dposdt(k,1:3, & - & 2)/4._wp + mtn_dposdt(k,1:3,3)) - mtn_vel(k,1:3,1) = mtn_vel(k,1:3,1) + (2._wp/3._wp)*dt*(mtn_dveldt(k,1:3,1)/4._wp + mtn_dveldt(k,1:3, & - & 2)/4._wp + mtn_dveldt(k,1:3,3)) gas_p(k, 1) = gas_p(k, 1) + (2._wp/3._wp)*dt*(gas_dpdt(k, 1)/4._wp + gas_dpdt(k, 2)/4._wp + gas_dpdt(k, 3)) gas_mv(k, 1) = gas_mv(k, 1) + (2._wp/3._wp)*dt*(gas_dmvdt(k, 1)/4._wp + gas_dmvdt(k, 2)/4._wp + gas_dmvdt(k, 3)) + if (moving_lag_bubbles) then + mtn_posPrev(k,1:3,1) = mtn_pos(k,1:3,2) + mtn_pos(k,1:3,1) = mtn_pos(k,1:3,1) + (2._wp/3._wp)*dt*(mtn_dposdt(k,1:3,1)/4._wp + mtn_dposdt(k,1:3, & + & 2)/4._wp + mtn_dposdt(k,1:3,3)) + mtn_vel(k,1:3,1) = mtn_vel(k,1:3,1) + (2._wp/3._wp)*dt*(mtn_dveldt(k,1:3,1)/4._wp + mtn_dveldt(k,1:3, & + & 2)/4._wp + mtn_dveldt(k,1:3,3)) + end if end do $:END_GPU_PARALLEL_LOOP() call s_transfer_data_to_tmp() - call s_write_void_evol(mytime) + if (moving_lag_bubbles) call s_enforce_EL_bubbles_boundary_conditions(q_prim_vf) + call s_smear_voidfraction(bc_type) + if (lag_params%write_void_evol) call s_write_void_evol(mytime) if (lag_params%write_bubbles_stats) call s_calculate_lag_bubble_stats() - if (lag_params%write_bubbles) then $:GPU_UPDATE(host='[gas_p, gas_mv, gas_mg, intfc_rad, intfc_vel]') - call s_write_lag_particles(mytime) + call s_write_lag_bubble_evol(mytime) end if end if end if @@ -1084,8 +1287,185 @@ contains end subroutine s_update_lagrange_tdv_rk !> Locate the cell index for a given physical position + !> This subroutine enforces reflective and wall boundary conditions for EL bubbles + !! @param dest Destination for the bubble position update + impure subroutine s_enforce_EL_bubbles_boundary_conditions(q_prim_vf) + + type(scalar_field), dimension(sys_size), intent(in) :: q_prim_vf + integer :: k, i, q + integer :: patch_id, newBubs, new_idx + real(wp) :: offset + integer, dimension(3) :: cell + + call nvtxStartRange("LAG-BC") + call nvtxStartRange("LAG-BC-DEV2HOST") + $:GPU_UPDATE(host='[bub_R0, Rmax_stats, Rmin_stats, gas_mg, gas_betaT, gas_betaC, bub_dphidt, lag_id, gas_p, gas_mv, & + & intfc_rad, intfc_vel, mtn_pos, mtn_posPrev, mtn_vel, mtn_s, intfc_draddt, intfc_dveldt, gas_dpdt, & + & gas_dmvdt, mtn_dposdt, mtn_dveldt, keep_bubble, n_el_bubs_loc, wrap_bubble_dir, wrap_bubble_loc]') + call nvtxEndRange + + ! Handle MPI transfer of bubbles going to another processor's local domain + if (num_procs > 1) then + call nvtxStartRange("LAG-BC-TRANSFER-LIST") + call s_add_particles_to_transfer_list(n_el_bubs_loc, mtn_pos(:,:,2), mtn_posPrev(:,:,2)) + call nvtxEndRange + + call nvtxStartRange("LAG-BC-SENDRECV") + call s_mpi_sendrecv_particles(bub_R0, Rmax_stats, Rmin_stats, gas_mg, gas_betaT, gas_betaC, bub_dphidt, lag_id, & + & gas_p, gas_mv, intfc_rad, intfc_vel, mtn_pos, mtn_posPrev, mtn_vel, mtn_s, & + & intfc_draddt, intfc_dveldt, gas_dpdt, gas_dmvdt, mtn_dposdt, mtn_dveldt, lag_num_ts, & + & n_el_bubs_loc, 2) + call nvtxEndRange + end if + + call nvtxStartRange("LAG-BC-HOST2DEV") + $:GPU_UPDATE(device='[bub_R0, Rmax_stats, Rmin_stats, gas_mg, gas_betaT, gas_betaC, bub_dphidt, lag_id, gas_p, gas_mv, & + & intfc_rad, intfc_vel, mtn_pos, mtn_posPrev, mtn_vel, mtn_s, intfc_draddt, intfc_dveldt, gas_dpdt, & + & gas_dmvdt, mtn_dposdt, mtn_dveldt, n_el_bubs_loc]') + call nvtxEndRange + + $:GPU_PARALLEL_LOOP(private='[k, cell]') + do k = 1, n_el_bubs_loc + keep_bubble(k) = 1 + wrap_bubble_loc(k,:) = 0 + wrap_bubble_dir(k,:) = 0 + + if (any(bc_x%beg == (/BC_REFLECTIVE, BC_CHAR_SLIP_WALL, BC_SLIP_WALL, BC_NO_SLIP_WALL/)) .and. mtn_pos(k, 1, & + & 2) < x_cb(-1) + intfc_rad(k, 2)) then + mtn_pos(k, 1, 2) = x_cb(-1) + intfc_rad(k, 2) + else if (any(bc_x%end == (/BC_REFLECTIVE, BC_CHAR_SLIP_WALL, BC_SLIP_WALL, BC_NO_SLIP_WALL/)) .and. mtn_pos(k, 1, & + & 2) > x_cb(m) - intfc_rad(k, 2)) then + mtn_pos(k, 1, 2) = x_cb(m) - intfc_rad(k, 2) + else if (bc_x%beg == BC_PERIODIC .and. mtn_pos(k, 1, 2) < pcomm_coords(1)%beg .and. mtn_posPrev(k, 1, & + & 2) >= pcomm_coords(1)%beg) then + wrap_bubble_dir(k, 1) = 1 + wrap_bubble_loc(k, 1) = -1 + else if (bc_x%end == BC_PERIODIC .and. mtn_pos(k, 1, 2) > pcomm_coords(1)%end .and. mtn_posPrev(k, 1, & + & 2) <= pcomm_coords(1)%end) then + wrap_bubble_dir(k, 1) = 1 + wrap_bubble_loc(k, 1) = 1 + else if (mtn_pos(k, 1, 2) >= x_cb(m)) then + keep_bubble(k) = 0 + else if (mtn_pos(k, 1, 2) < x_cb(-1)) then + keep_bubble(k) = 0 + end if + + if (any(bc_y%beg == (/BC_REFLECTIVE, BC_CHAR_SLIP_WALL, BC_SLIP_WALL, BC_NO_SLIP_WALL/)) .and. mtn_pos(k, 2, & + & 2) < y_cb(-1) + intfc_rad(k, 2)) then + mtn_pos(k, 2, 2) = y_cb(-1) + intfc_rad(k, 2) + else if (any(bc_y%end == (/BC_REFLECTIVE, BC_CHAR_SLIP_WALL, BC_SLIP_WALL, BC_NO_SLIP_WALL/)) .and. mtn_pos(k, 2, & + & 2) > y_cb(n) - intfc_rad(k, 2)) then + mtn_pos(k, 2, 2) = y_cb(n) - intfc_rad(k, 2) + else if (bc_y%beg == BC_PERIODIC .and. mtn_pos(k, 2, 2) < pcomm_coords(2)%beg .and. mtn_posPrev(k, 2, & + & 2) >= pcomm_coords(2)%beg) then + wrap_bubble_dir(k, 2) = 1 + wrap_bubble_loc(k, 2) = -1 + else if (bc_y%end == BC_PERIODIC .and. mtn_pos(k, 2, 2) > pcomm_coords(2)%end .and. mtn_posPrev(k, 2, & + & 2) <= pcomm_coords(2)%end) then + wrap_bubble_dir(k, 2) = 1 + wrap_bubble_loc(k, 2) = 1 + else if (mtn_pos(k, 2, 2) >= y_cb(n)) then + keep_bubble(k) = 0 + else if (mtn_pos(k, 2, 2) < y_cb(-1)) then + keep_bubble(k) = 0 + end if + + if (p > 0) then + if (any(bc_z%beg == (/BC_REFLECTIVE, BC_CHAR_SLIP_WALL, BC_SLIP_WALL, BC_NO_SLIP_WALL/)) .and. mtn_pos(k, 3, & + & 2) < z_cb(-1) + intfc_rad(k, 2)) then + mtn_pos(k, 3, 2) = z_cb(-1) + intfc_rad(k, 2) + else if (any(bc_z%end == (/BC_REFLECTIVE, BC_CHAR_SLIP_WALL, BC_SLIP_WALL, BC_NO_SLIP_WALL/)) .and. mtn_pos(k, 3, & + & 2) > z_cb(p) - intfc_rad(k, 2)) then + mtn_pos(k, 3, 2) = z_cb(p) - intfc_rad(k, 2) + else if (bc_z%beg == BC_PERIODIC .and. mtn_pos(k, 3, 2) < pcomm_coords(3)%beg .and. mtn_posPrev(k, 3, & + & 2) >= pcomm_coords(3)%beg) then + wrap_bubble_dir(k, 3) = 1 + wrap_bubble_loc(k, 3) = -1 + else if (bc_z%end == BC_PERIODIC .and. mtn_pos(k, 3, 2) > pcomm_coords(3)%end .and. mtn_posPrev(k, 3, & + & 2) <= pcomm_coords(3)%end) then + wrap_bubble_dir(k, 3) = 1 + wrap_bubble_loc(k, 3) = 1 + else if (mtn_pos(k, 3, 2) >= z_cb(p)) then + keep_bubble(k) = 0 + else if (mtn_pos(k, 3, 2) < z_cb(-1)) then + keep_bubble(k) = 0 + end if + end if + + if (keep_bubble(k) == 1) then + ! Remove bubbles that are no longer in a liquid + cell = fd_number - buff_size + call s_locate_cell(mtn_pos(k,1:3,2), cell, mtn_s(k,1:3,2)) + + if (q_prim_vf(advxb)%sf(cell(1), cell(2), cell(3)) < (1._wp - lag_params%valmaxvoid)) then + keep_bubble(k) = 0 + end if + end if + end do + $:END_GPU_PARALLEL_LOOP() + + if (n_el_bubs_loc > 0) then + call nvtxStartRange("LAG-BC-DEV2HOST") + $:GPU_UPDATE(host='[bub_R0, Rmax_stats, Rmin_stats, gas_mg, gas_betaT, gas_betaC, bub_dphidt, lag_id, gas_p, gas_mv, & + & intfc_rad, intfc_vel, mtn_pos, mtn_posPrev, mtn_vel, mtn_s, intfc_draddt, intfc_dveldt, gas_dpdt, & + & gas_dmvdt, mtn_dposdt, mtn_dveldt, keep_bubble, n_el_bubs_loc, wrap_bubble_dir, wrap_bubble_loc]') + call nvtxEndRange + + newBubs = 0 + do k = 1, n_el_bubs_loc + if (keep_bubble(k) == 1) then + newBubs = newBubs + 1 + if (newBubs /= k) then + call s_copy_lag_bubble(newBubs, k) + wrap_bubble_dir(newBubs,:) = wrap_bubble_dir(k,:) + wrap_bubble_loc(newBubs,:) = wrap_bubble_loc(k,:) + end if + end if + end do + n_el_bubs_loc = newBubs + + ! Handle periodic wrapping of bubbles on same processor + do k = 1, n_el_bubs_loc + if (any(wrap_bubble_dir(k,:) == 1)) then + do i = 1, num_dims + if (wrap_bubble_dir(k, i) == 1) then + offset = glb_bounds(i)%end - glb_bounds(i)%beg + if (wrap_bubble_loc(k, i) == 1) then + do q = 1, 2 + mtn_pos(k, i, q) = mtn_pos(k, i, q) - offset + mtn_posPrev(k, i, q) = mtn_posPrev(k, i, q) - offset + end do + else if (wrap_bubble_loc(k, i) == -1) then + do q = 1, 2 + mtn_pos(k, i, q) = mtn_pos(k, i, q) + offset + mtn_posPrev(k, i, q) = mtn_posPrev(k, i, q) + offset + end do + end if + end if + end do + end if + end do + call nvtxStartRange("LAG-BC-HOST2DEV") + $:GPU_UPDATE(device='[bub_R0, Rmax_stats, Rmin_stats, gas_mg, gas_betaT, gas_betaC, bub_dphidt, lag_id, gas_p, & + & gas_mv, intfc_rad, intfc_vel, mtn_pos, mtn_posPrev, mtn_vel, mtn_s, intfc_draddt, intfc_dveldt, & + & gas_dpdt, gas_dmvdt, mtn_dposdt, mtn_dveldt, n_el_bubs_loc]') + call nvtxEndRange + end if + + $:GPU_PARALLEL_LOOP(private='[cell]') + do k = 1, n_el_bubs_loc + cell = fd_number - buff_size + call s_locate_cell(mtn_pos(k,1:3,2), cell, mtn_s(k,1:3,2)) + end do + + call nvtxEndRange + + end subroutine s_enforce_EL_bubbles_boundary_conditions + subroutine s_locate_cell(pos, cell, scoord) + $:GPU_ROUTINE(function_name='s_locate_cell',parallelism='[seq]', cray_inline=True) + real(wp), dimension(3), intent(in) :: pos real(wp), dimension(3), intent(out) :: scoord integer, dimension(3), intent(inout) :: cell @@ -1095,7 +1475,7 @@ contains cell(1) = cell(1) - 1 end do - do while (pos(1) > x_cb(cell(1))) + do while (pos(1) >= x_cb(cell(1))) cell(1) = cell(1) + 1 end do @@ -1103,7 +1483,7 @@ contains cell(2) = cell(2) - 1 end do - do while (pos(2) > y_cb(cell(2))) + do while (pos(2) >= y_cb(cell(2))) cell(2) = cell(2) + 1 end do @@ -1111,7 +1491,7 @@ contains do while (pos(3) < z_cb(cell(3) - 1)) cell(3) = cell(3) - 1 end do - do while (pos(3) > z_cb(cell(3))) + do while (pos(3) >= z_cb(cell(3))) cell(3) = cell(3) + 1 end do end if @@ -1138,7 +1518,7 @@ contains integer :: k $:GPU_PARALLEL_LOOP(private='[k]') - do k = 1, nBubs + do k = 1, n_el_bubs_loc gas_p(k, 2) = gas_p(k, 1) gas_mv(k, 2) = gas_mv(k, 1) intfc_rad(k, 2) = intfc_rad(k, 1) @@ -1162,22 +1542,23 @@ contains if (p == 0 .and. cyl_coord .neqv. .true.) then ! Defining a virtual z-axis that has the same dimensions as y-axis defined in the input file - particle_in_domain = ((pos_part(1) < x_cb(m + buff_size)) .and. (pos_part(1) >= x_cb(-buff_size - 1)) & - & .and. (pos_part(2) < y_cb(n + buff_size)) .and. (pos_part(2) >= y_cb(-buff_size - 1)) & - & .and. (pos_part(3) < lag_params%charwidth/2._wp) .and. (pos_part(3) >= & - & -lag_params%charwidth/2._wp)) + particle_in_domain = ((pos_part(1) < x_cb(m + buff_size - fd_number)) .and. (pos_part(1) >= x_cb(fd_number & + & - buff_size - 1)) .and. (pos_part(2) < y_cb(n + buff_size - fd_number)) .and. (pos_part(2) & + & >= y_cb(fd_number - buff_size - 1)) .and. (pos_part(3) < lag_params%charwidth/2._wp) & + & .and. (pos_part(3) > -lag_params%charwidth/2._wp)) else ! cyl_coord - particle_in_domain = ((pos_part(1) < x_cb(m + buff_size)) .and. (pos_part(1) >= x_cb(-buff_size - 1)) & - & .and. (abs(pos_part(2)) < y_cb(n + buff_size)) .and. (abs(pos_part(2)) >= max(y_cb(-buff_size & - & - 1), 0._wp))) + particle_in_domain = ((pos_part(1) < x_cb(m + buff_size - fd_number)) .and. (pos_part(1) >= x_cb(fd_number & + & - buff_size - 1)) .and. (abs(pos_part(2)) < y_cb(n + buff_size - fd_number)) & + & .and. (abs(pos_part(2)) >= max(y_cb(fd_number - buff_size - 1), 0._wp))) end if ! 3D if (p > 0) then - particle_in_domain = ((pos_part(1) < x_cb(m + buff_size)) .and. (pos_part(1) >= x_cb(-buff_size - 1)) & - & .and. (pos_part(2) < y_cb(n + buff_size)) .and. (pos_part(2) >= y_cb(-buff_size - 1)) & - & .and. (pos_part(3) < z_cb(p + buff_size)) .and. (pos_part(3) >= z_cb(-buff_size - 1))) + particle_in_domain = ((pos_part(1) < x_cb(m + buff_size - fd_number)) .and. (pos_part(1) >= x_cb(fd_number & + & - buff_size - 1)) .and. (pos_part(2) < y_cb(n + buff_size - fd_number)) .and. (pos_part(2) & + & >= y_cb(fd_number - buff_size - 1)) .and. (pos_part(3) < z_cb(p + buff_size - fd_number)) & + & .and. (pos_part(3) >= z_cb(fd_number - buff_size - 1))) end if ! For symmetric and wall boundary condition @@ -1281,7 +1662,34 @@ contains write (file_loc, '(A,I0,A)') 'lag_bubble_evol_', proc_rank, '.dat' file_loc = trim(case_dir) // '/D/' // trim(file_loc) - inquire (FILE=trim(file_loc), EXIST=file_exist) + call my_inquire(trim(file_loc), file_exist) + + if (precision == 1) then + FMT = "(A16,A14,8A16)" + else + FMT = "(A24,A14,8A24)" + end if + + if (.not. file_exist) then + open (LAG_EVOL_ID, FILE=trim(file_loc), form='formatted', position='rewind') + write (LAG_EVOL_ID, FMT) 'currentTime', 'particleID', 'x', 'y', 'z', 'coreVaporMass', 'coreVaporConcentration', & + & 'radius', 'interfaceVelocity', 'corePressure' + else + open (LAG_EVOL_ID, FILE=trim(file_loc), form='formatted', position='append') + end if + + end subroutine s_write_lag_particles + + !> @Brief Subroutine that opens the file to write the evolution of the lagrangian bubbles on each time step. + impure subroutine s_open_lag_bubble_evol() + + character(LEN=path_len + 2*name_len) :: file_loc + logical :: file_exist + character(LEN=25) :: FMT + + write (file_loc, '(A,I0,A)') 'lag_bubble_evol_', proc_rank, '.dat' + file_loc = trim(case_dir) // '/D/' // trim(file_loc) + call my_inquire(trim(file_loc), file_exist) if (precision == 1) then FMT = "(A16,A14,8A16)" @@ -1290,13 +1698,24 @@ contains end if if (.not. file_exist) then - open (11, FILE=trim(file_loc), form='formatted', position='rewind') - write (11, FMT) 'currentTime', 'particleID', 'x', 'y', 'z', 'coreVaporMass', 'coreVaporConcentration', 'radius', & - & 'interfaceVelocity', 'corePressure' + open (LAG_EVOL_ID, FILE=trim(file_loc), form='formatted', position='rewind') + write (LAG_EVOL_ID, FMT) 'currentTime', 'particleID', 'x', 'y', 'z', 'coreVaporMass', 'coreVaporConcentration', & + & 'radius', 'interfaceVelocity', 'corePressure' else - open (11, FILE=trim(file_loc), form='formatted', position='append') + open (LAG_EVOL_ID, FILE=trim(file_loc), form='formatted', position='append') end if + end subroutine s_open_lag_bubble_evol + + !! @param q_time Current time + impure subroutine s_write_lag_bubble_evol(qtime) + + real(wp), intent(in) :: qtime + integer :: k, ios + character(LEN=25) :: FMT + character(LEN=path_len + 2*name_len) :: file_loc, path + logical :: file_exist + if (precision == 1) then FMT = "(F16.8,I14,8F16.8)" else @@ -1304,37 +1723,49 @@ contains end if ! Cycle through list - do k = 1, nBubs - write (11, FMT) qtime, lag_id(k, 1), mtn_pos(k, 1, 1), mtn_pos(k, 2, 1), mtn_pos(k, 3, 1), gas_mv(k, 1), gas_mv(k, & - & 1)/(gas_mv(k, 1) + gas_mg(k)), intfc_rad(k, 1), intfc_vel(k, 1), gas_p(k, 1) + do k = 1, n_el_bubs_loc + write (LAG_EVOL_ID, FMT) qtime, lag_id(k, 1), mtn_pos(k, 1, 1), mtn_pos(k, 2, 1), mtn_pos(k, 3, 1), gas_mv(k, 1), & + & gas_mv(k, 1)/(gas_mv(k, 1) + gas_mg(k)), intfc_rad(k, 1), intfc_vel(k, 1), gas_p(k, 1) end do - close (11) + !> Write void fraction statistics at each time step - end subroutine s_write_lag_particles + end subroutine s_write_lag_bubble_evol - !> Write void fraction statistics at each time step - impure subroutine s_write_void_evol(qtime) + impure subroutine s_close_lag_bubble_evol + + close (LAG_EVOL_ID) + + end subroutine s_close_lag_bubble_evol + + subroutine s_open_void_evol - real(wp), intent(in) :: qtime - real(wp) :: volcell, voltot - real(wp) :: lag_void_max, lag_void_avg, lag_vol - real(wp) :: void_max_glb, void_avg_glb, vol_glb - integer :: i, j, k character(LEN=path_len + 2*name_len) :: file_loc logical :: file_exist if (proc_rank == 0) then write (file_loc, '(A)') 'voidfraction.dat' file_loc = trim(case_dir) // '/D/' // trim(file_loc) - inquire (FILE=trim(file_loc), EXIST=file_exist) + call my_inquire(trim(file_loc), file_exist) if (.not. file_exist) then - open (12, FILE=trim(file_loc), form='formatted', position='rewind') + open (LAG_VOID_ID, FILE=trim(file_loc), form='formatted', position='rewind') else - open (12, FILE=trim(file_loc), form='formatted', position='append') + open (LAG_VOID_ID, FILE=trim(file_loc), form='formatted', position='append') end if end if + end subroutine s_open_void_evol + + impure subroutine s_write_void_evol(qtime) + + real(wp), intent(in) :: qtime + real(wp) :: volcell, voltot + real(wp) :: lag_void_max, lag_void_avg, lag_vol + real(wp) :: void_max_glb, void_avg_glb, vol_glb + integer :: i, j, k + character(LEN=path_len + 2*name_len) :: file_loc + logical :: file_exist + lag_void_max = 0._wp lag_void_avg = 0._wp lag_vol = 0._wp @@ -1370,13 +1801,18 @@ contains if (lag_vol > 0._wp) lag_void_avg = lag_void_avg/lag_vol if (proc_rank == 0) then - write (12, '(6X,4e24.8)') qtime, lag_void_avg, lag_void_max, voltot - close (12) + write (LAG_VOID_ID, '(6X,4e24.8)') qtime, lag_void_avg, lag_void_max, voltot end if end subroutine s_write_void_evol !> Write restart files for the Lagrangian bubble solver + subroutine s_close_void_evol + + if (proc_rank == 0) close (LAG_VOID_ID) + + end subroutine s_close_void_evol + impure subroutine s_write_restart_lag_bubbles(t_step) ! Generic string used to store the address of a particular file @@ -1393,14 +1829,14 @@ contains integer(KIND=MPI_OFFSET_KIND) :: disp integer :: view integer, dimension(2) :: gsizes, lsizes, start_idx_part - integer, allocatable :: proc_bubble_counts(:) + integer, dimension(num_procs) :: part_order, part_ord_mpi + integer, dimension(num_procs) :: proc_bubble_counts real(wp), dimension(1:1,1:lag_io_vars) :: dummy - dummy = 0._wp bub_id = 0._wp - if (nBubs /= 0) then - do k = 1, nBubs + if (n_el_bubs_loc /= 0) then + do k = 1, n_el_bubs_loc if (particle_in_domain_physical(mtn_pos(k,1:3,1))) then bub_id = bub_id + 1 end if @@ -1409,8 +1845,6 @@ contains if (.not. parallel_io) return - allocate (proc_bubble_counts(num_procs)) - lsizes(1) = bub_id lsizes(2) = lag_io_vars @@ -1458,26 +1892,22 @@ contains if (bub_id > 0) then allocate (MPI_IO_DATA_lag_bubbles(max(1, bub_id),1:lag_io_vars)) - i = 1 - do k = 1, nBubs - if (particle_in_domain_physical(mtn_pos(k,1:3,1))) then - MPI_IO_DATA_lag_bubbles(i, 1) = real(lag_id(k, 1)) - MPI_IO_DATA_lag_bubbles(i,2:4) = mtn_pos(k,1:3,1) - MPI_IO_DATA_lag_bubbles(i,5:7) = mtn_posPrev(k,1:3,1) - MPI_IO_DATA_lag_bubbles(i,8:10) = mtn_vel(k,1:3,1) - MPI_IO_DATA_lag_bubbles(i, 11) = intfc_rad(k, 1) - MPI_IO_DATA_lag_bubbles(i, 12) = intfc_vel(k, 1) - MPI_IO_DATA_lag_bubbles(i, 13) = bub_R0(k) - MPI_IO_DATA_lag_bubbles(i, 14) = Rmax_stats(k) - MPI_IO_DATA_lag_bubbles(i, 15) = Rmin_stats(k) - MPI_IO_DATA_lag_bubbles(i, 16) = bub_dphidt(k) - MPI_IO_DATA_lag_bubbles(i, 17) = gas_p(k, 1) - MPI_IO_DATA_lag_bubbles(i, 18) = gas_mv(k, 1) - MPI_IO_DATA_lag_bubbles(i, 19) = gas_mg(k) - MPI_IO_DATA_lag_bubbles(i, 20) = gas_betaT(k) - MPI_IO_DATA_lag_bubbles(i, 21) = gas_betaC(k) - i = i + 1 - end if + do k = 1, n_el_bubs_loc + MPI_IO_DATA_lag_bubbles(k, 1) = real(lag_id(k, 1)) + MPI_IO_DATA_lag_bubbles(k,2:4) = mtn_pos(k,1:3,1) + MPI_IO_DATA_lag_bubbles(k,5:7) = mtn_posPrev(k,1:3,1) + MPI_IO_DATA_lag_bubbles(k,8:10) = mtn_vel(k,1:3,1) + MPI_IO_DATA_lag_bubbles(k, 11) = intfc_rad(k, 1) + MPI_IO_DATA_lag_bubbles(k, 12) = intfc_vel(k, 1) + MPI_IO_DATA_lag_bubbles(k, 13) = bub_R0(k) + MPI_IO_DATA_lag_bubbles(k, 14) = Rmax_stats(k) + MPI_IO_DATA_lag_bubbles(k, 15) = Rmin_stats(k) + MPI_IO_DATA_lag_bubbles(k, 16) = bub_dphidt(k) + MPI_IO_DATA_lag_bubbles(k, 17) = gas_p(k, 1) + MPI_IO_DATA_lag_bubbles(k, 18) = gas_mv(k, 1) + MPI_IO_DATA_lag_bubbles(k, 19) = gas_mg(k) + MPI_IO_DATA_lag_bubbles(k, 20) = gas_betaT(k) + MPI_IO_DATA_lag_bubbles(k, 21) = gas_betaC(k) end do call MPI_TYPE_CREATE_SUBARRAY(2, gsizes, lsizes, start_idx_part, MPI_ORDER_FORTRAN, mpi_p, view, ierr) @@ -1510,8 +1940,6 @@ contains call MPI_FILE_CLOSE(ifile, ierr) end if - - deallocate (proc_bubble_counts) #endif end subroutine s_write_restart_lag_bubbles @@ -1523,7 +1951,7 @@ contains $:GPU_PARALLEL_LOOP(private='[k]', reduction='[[Rmax_glb], [Rmin_glb]]', reductionOp='[MAX, MIN]', & & copy='[Rmax_glb, Rmin_glb]') - do k = 1, nBubs + do k = 1, n_el_bubs_loc Rmax_glb = max(Rmax_glb, intfc_rad(k, 1)/bub_R0(k)) Rmin_glb = min(Rmin_glb, intfc_rad(k, 1)/bub_R0(k)) Rmax_stats(k) = max(Rmax_stats(k), intfc_rad(k, 1)/bub_R0(k)) @@ -1534,16 +1962,15 @@ contains end subroutine s_calculate_lag_bubble_stats !> Write the maximum and minimum radius statistics for each bubble - impure subroutine s_write_lag_bubble_stats() + impure subroutine s_open_lag_bubble_stats() - integer :: k character(LEN=path_len + 2*name_len) :: file_loc - character(len=20) :: FMT + character(LEN=20) :: FMT + logical :: file_exist write (file_loc, '(A,I0,A)') 'stats_lag_bubbles_', proc_rank, '.dat' file_loc = trim(case_dir) // '/D/' // trim(file_loc) - - $:GPU_UPDATE(host='[Rmax_glb, Rmin_glb]') + call my_inquire(trim(file_loc), file_exist) if (precision == 1) then FMT = "(A10,A14,5A16)" @@ -1551,8 +1978,22 @@ contains FMT = "(A10,A14,5A24)" end if - open (13, FILE=trim(file_loc), form='formatted', position='rewind') - write (13, FMT) 'proc_rank', 'particleID', 'x', 'y', 'z', 'Rmax_glb', 'Rmin_glb' + if (.not. file_exist) then + open (LAG_STATS_ID, FILE=trim(file_loc), form='formatted', position='rewind') + write (LAG_STATS_ID, *) 'proc_rank, particleID, x, y, z, Rmax_glb, Rmin_glb' + else + open (LAG_STATS_ID, FILE=trim(file_loc), form='formatted', position='append') + end if + + end subroutine s_open_lag_bubble_stats + + impure subroutine s_write_lag_bubble_stats() + + integer :: k + character(LEN=path_len + 2*name_len) :: file_loc + character(LEN=20) :: FMT + + $:GPU_UPDATE(host='[Rmax_glb, Rmin_glb]') if (precision == 1) then FMT = "(I10,I14,5F16.8)" @@ -1560,59 +2001,64 @@ contains FMT = "(I10,I14,5F24.16)" end if - do k = 1, nBubs - write (13, FMT) proc_rank, lag_id(k, 1), mtn_pos(k, 1, 1), mtn_pos(k, 2, 1), mtn_pos(k, 3, 1), Rmax_stats(k), & - & Rmin_stats(k) + do k = 1, n_el_bubs_loc + write (LAG_STATS_ID, FMT) proc_rank, lag_id(k, 1), mtn_pos(k, 1, 1), mtn_pos(k, 2, 1), mtn_pos(k, 3, 1), & + & Rmax_stats(k), Rmin_stats(k) end do - close (13) - end subroutine s_write_lag_bubble_stats !> Remove a specific Lagrangian bubble when dt becomes too small - impure subroutine s_remove_lag_bubble(bub_id) - - integer, intent(in) :: bub_id - integer :: i - - $:GPU_LOOP(parallelism='[seq]') - do i = bub_id, nBubs - 1 - lag_id(i, 1) = lag_id(i + 1, 1) - bub_R0(i) = bub_R0(i + 1) - Rmax_stats(i) = Rmax_stats(i + 1) - Rmin_stats(i) = Rmin_stats(i + 1) - gas_mg(i) = gas_mg(i + 1) - gas_betaT(i) = gas_betaT(i + 1) - gas_betaC(i) = gas_betaC(i + 1) - bub_dphidt(i) = bub_dphidt(i + 1) - gas_p(i,1:2) = gas_p(i + 1,1:2) - gas_mv(i,1:2) = gas_mv(i + 1,1:2) - intfc_rad(i,1:2) = intfc_rad(i + 1,1:2) - intfc_vel(i,1:2) = intfc_vel(i + 1,1:2) - mtn_pos(i,1:3,1:2) = mtn_pos(i + 1,1:3,1:2) - mtn_posPrev(i,1:3,1:2) = mtn_posPrev(i + 1,1:3,1:2) - mtn_vel(i,1:3,1:2) = mtn_vel(i + 1,1:3,1:2) - mtn_s(i,1:3,1:2) = mtn_s(i + 1,1:3,1:2) - intfc_draddt(i,1:lag_num_ts) = intfc_draddt(i + 1,1:lag_num_ts) - intfc_dveldt(i,1:lag_num_ts) = intfc_dveldt(i + 1,1:lag_num_ts) - gas_dpdt(i,1:lag_num_ts) = gas_dpdt(i + 1,1:lag_num_ts) - gas_dmvdt(i,1:lag_num_ts) = gas_dmvdt(i + 1,1:lag_num_ts) - end do - - nBubs = nBubs - 1 - $:GPU_UPDATE(device='[nBubs]') - - end subroutine s_remove_lag_bubble - !> Finalize the Lagrangian bubble solver + subroutine s_close_lag_bubble_stats + + close (LAG_STATS_ID) + + end subroutine s_close_lag_bubble_stats + + impure subroutine s_copy_lag_bubble(dest, src) + + integer, intent(in) :: src, dest + + bub_R0(dest) = bub_R0(src) + Rmax_stats(dest) = Rmax_stats(src) + Rmin_stats(dest) = Rmin_stats(src) + gas_mg(dest) = gas_mg(src) + gas_betaT(dest) = gas_betaT(src) + gas_betaC(dest) = gas_betaC(src) + bub_dphidt(dest) = bub_dphidt(src) + lag_id(dest, 1) = lag_id(src, 1) + gas_p(dest,1:2) = gas_p(src,1:2) + gas_mv(dest,1:2) = gas_mv(src,1:2) + intfc_rad(dest,1:2) = intfc_rad(src,1:2) + intfc_vel(dest,1:2) = intfc_vel(src,1:2) + mtn_vel(dest,1:3,1:2) = mtn_vel(src,1:3,1:2) + mtn_s(dest,1:3,1:2) = mtn_s(src,1:3,1:2) + mtn_pos(dest,1:3,1:2) = mtn_pos(src,1:3,1:2) + mtn_posPrev(dest,1:3,1:2) = mtn_posPrev(src,1:3,1:2) + intfc_draddt(dest,1:lag_num_ts) = intfc_draddt(src,1:lag_num_ts) + intfc_dveldt(dest,1:lag_num_ts) = intfc_dveldt(src,1:lag_num_ts) + gas_dpdt(dest,1:lag_num_ts) = gas_dpdt(src,1:lag_num_ts) + gas_dmvdt(dest,1:lag_num_ts) = gas_dmvdt(src,1:lag_num_ts) + mtn_dposdt(dest,1:3,1:lag_num_ts) = mtn_dposdt(src,1:3,1:lag_num_ts) + mtn_dveldt(dest,1:3,1:lag_num_ts) = mtn_dveldt(src,1:3,1:lag_num_ts) + + end subroutine s_copy_lag_bubble + impure subroutine s_finalize_lagrangian_solver() integer :: i + if (lag_params%write_void_evol) call s_close_void_evol + if (lag_params%write_bubbles) call s_close_lag_bubble_evol() + if (lag_params%write_bubbles_stats) call s_close_lag_bubble_stats() + do i = 1, q_beta_idx @:DEALLOCATE(q_beta(i)%sf) + @:DEALLOCATE(kahan_comp(i)%sf) end do @:DEALLOCATE(q_beta) + @:DEALLOCATE(kahan_comp) ! Deallocating space @:DEALLOCATE(lag_id) @@ -1638,6 +2084,28 @@ contains @:DEALLOCATE(mtn_dposdt) @:DEALLOCATE(mtn_dveldt) + @:DEALLOCATE(keep_bubble) + @:DEALLOCATE(wrap_bubble_loc, wrap_bubble_dir) + + ! Deallocate pressure gradient arrays and FD coefficients + if (lag_params%vel_model > 0 .and. lag_params%pressure_force) then + @:DEALLOCATE(grad_p_x) + @:DEALLOCATE(fd_coeff_x_pgrad) + if (n > 0) then + @:DEALLOCATE(grad_p_y) + @:DEALLOCATE(fd_coeff_y_pgrad) + if (p > 0) then + @:DEALLOCATE(grad_p_z) + @:DEALLOCATE(fd_coeff_z_pgrad) + end if + end if + end if + + ! Deallocate cell list arrays + @:DEALLOCATE(cell_list_start) + @:DEALLOCATE(cell_list_count) + @:DEALLOCATE(cell_list_idx) + end subroutine s_finalize_lagrangian_solver end module m_bubbles_EL diff --git a/src/simulation/m_bubbles_EL_kernels.fpp b/src/simulation/m_bubbles_EL_kernels.fpp index f1f80980b0..caa6500512 100644 --- a/src/simulation/m_bubbles_EL_kernels.fpp +++ b/src/simulation/m_bubbles_EL_kernels.fpp @@ -11,166 +11,258 @@ module m_bubbles_EL_kernels implicit none + ! Cell-centered pressure gradients (precomputed for translational motion) + real(wp), allocatable, dimension(:,:,:) :: grad_p_x, grad_p_y, grad_p_z + $:GPU_DECLARE(create='[grad_p_x, grad_p_y, grad_p_z]') + + ! Finite-difference coefficients for pressure gradient computation + real(wp), allocatable, dimension(:,:) :: fd_coeff_x_pgrad + real(wp), allocatable, dimension(:,:) :: fd_coeff_y_pgrad + real(wp), allocatable, dimension(:,:) :: fd_coeff_z_pgrad + $:GPU_DECLARE(create='[fd_coeff_x_pgrad, fd_coeff_y_pgrad, fd_coeff_z_pgrad]') + + ! Cell list for bubble-to-cell mapping (rebuilt each RK stage before smearing) + integer, allocatable, dimension(:,:,:) :: cell_list_start ! (0:m, 0:n, 0:p) + integer, allocatable, dimension(:,:,:) :: cell_list_count ! (0:m, 0:n, 0:p) + integer, allocatable, dimension(:) :: cell_list_idx ! (1:nBubs_glb) sorted bubble indices + $:GPU_DECLARE(create='[cell_list_start, cell_list_count, cell_list_idx]') + contains !> Smear the Lagrangian bubble effects onto the Eulerian grid using the selected kernel - subroutine s_smoothfunction(nBubs, lbk_rad, lbk_vel, lbk_s, lbk_pos, updatedvar) + subroutine s_smoothfunction(nBubs, lbk_rad, lbk_vel, lbk_s, lbk_pos, updatedvar, kcomp) integer, intent(in) :: nBubs real(wp), dimension(1:lag_params%nBubs_glb,1:3,1:2), intent(in) :: lbk_s, lbk_pos real(wp), dimension(1:lag_params%nBubs_glb,1:2), intent(in) :: lbk_rad, lbk_vel type(scalar_field), dimension(:), intent(inout) :: updatedvar + type(scalar_field), dimension(:), intent(inout) :: kcomp smoothfunc:select case(lag_params%smooth_type) case (1) - call s_gaussian(nBubs, lbk_rad, lbk_vel, lbk_s, lbk_pos, updatedvar) + call s_gaussian(nBubs, lbk_rad, lbk_vel, lbk_s, lbk_pos, updatedvar, kcomp) case (2) - call s_deltafunc(nBubs, lbk_rad, lbk_vel, lbk_s, updatedvar) + call s_deltafunc(nBubs, lbk_rad, lbk_vel, lbk_s, updatedvar, kcomp) end select smoothfunc end subroutine s_smoothfunction !> Apply the delta kernel function to map bubble effects onto the containing cell - subroutine s_deltafunc(nBubs, lbk_rad, lbk_vel, lbk_s, updatedvar) + subroutine s_build_cell_list(nBubs, lbk_s) integer, intent(in) :: nBubs real(wp), dimension(1:lag_params%nBubs_glb,1:3,1:2), intent(in) :: lbk_s - real(wp), dimension(1:lag_params%nBubs_glb,1:2), intent(in) :: lbk_rad, lbk_vel - type(scalar_field), dimension(:), intent(inout) :: updatedvar - integer, dimension(3) :: cell - real(wp) :: strength_vel, strength_vol - real(wp) :: addFun1, addFun2, addFun3 - real(wp) :: volpart, Vol + integer :: l, ci, cj, ck, idx real(wp), dimension(3) :: s_coord - integer :: l - $:GPU_PARALLEL_LOOP(private='[l, s_coord, cell]') + ! Bring current bubble positions to host + + $:GPU_UPDATE(host='[lbk_s]') + + ! Pass 1: zero counts and count bubbles per cell + cell_list_count = 0 + do l = 1, nBubs + s_coord(1:3) = lbk_s(l,1:3,2) + ci = int(s_coord(1)) + cj = int(s_coord(2)) + ck = int(s_coord(3)) + ! Clamp to interior (bubbles should already be in [0:m,0:n,0:p]) + ci = max(0, min(ci, m)) + cj = max(0, min(cj, n)) + ck = max(0, min(ck, p)) + cell_list_count(ci, cj, ck) = cell_list_count(ci, cj, ck) + 1 + end do + + ! Prefix sum to compute start indices (1-based into cell_list_idx) + idx = 1 + do ck = 0, p + do cj = 0, n + do ci = 0, m + cell_list_start(ci, cj, ck) = idx + idx = idx + cell_list_count(ci, cj, ck) + end do + end do + end do + + cell_list_count = 0 do l = 1, nBubs - volpart = 4._wp/3._wp*pi*lbk_rad(l, 2)**3._wp s_coord(1:3) = lbk_s(l,1:3,2) - call s_get_cell(s_coord, cell) + ci = int(s_coord(1)) + cj = int(s_coord(2)) + ck = int(s_coord(3)) + ci = max(0, min(ci, m)) + cj = max(0, min(cj, n)) + ck = max(0, min(ck, p)) + cell_list_idx(cell_list_start(ci, cj, ck) + cell_list_count(ci, cj, ck)) = l + cell_list_count(ci, cj, ck) = cell_list_count(ci, cj, ck) + 1 + end do - strength_vol = volpart - strength_vel = 4._wp*pi*lbk_rad(l, 2)**2._wp*lbk_vel(l, 2) + ! Send cell list arrays to GPU + $:GPU_UPDATE(device='[cell_list_start, cell_list_count, cell_list_idx]') - if (num_dims == 2) then - Vol = dx(cell(1))*dy(cell(2))*lag_params%charwidth - if (cyl_coord) Vol = dx(cell(1))*dy(cell(2))*y_cc(cell(2))*2._wp*pi - else - Vol = dx(cell(1))*dy(cell(2))*dz(cell(3)) - end if + end subroutine s_build_cell_list - ! Update void fraction field - addFun1 = strength_vol/Vol - $:GPU_ATOMIC(atomic='update') - updatedvar(1)%sf(cell(1), cell(2), cell(3)) = updatedvar(1)%sf(cell(1), cell(2), cell(3)) + real(addFun1, kind=stp) - - ! Update time derivative of void fraction - addFun2 = strength_vel/Vol - $:GPU_ATOMIC(atomic='update') - updatedvar(2)%sf(cell(1), cell(2), cell(3)) = updatedvar(2)%sf(cell(1), cell(2), cell(3)) + real(addFun2, kind=stp) - - ! Product of two smeared functions Update void fraction * time derivative of void fraction - if (lag_params%cluster_type >= 4) then - addFun3 = (strength_vol*strength_vel)/Vol - $:GPU_ATOMIC(atomic='update') - updatedvar(5)%sf(cell(1), cell(2), cell(3)) = updatedvar(5)%sf(cell(1), cell(2), cell(3)) + real(addFun3, kind=stp) - end if + subroutine s_deltafunc(nBubs, lbk_rad, lbk_vel, lbk_s, updatedvar, kcomp) + + integer, intent(in) :: nBubs + real(wp), dimension(1:lag_params%nBubs_glb,1:3,1:2), intent(in) :: lbk_s + real(wp), dimension(1:lag_params%nBubs_glb,1:2), intent(in) :: lbk_rad, lbk_vel + type(scalar_field), dimension(:), intent(inout) :: updatedvar + type(scalar_field), dimension(:), intent(inout) :: kcomp + real(wp) :: strength_vel, strength_vol + real(wp) :: volpart, Vol + real(wp) :: y_kahan, t_kahan + integer :: i, j, k, lb, bub_idx + + $:GPU_PARALLEL_LOOP(collapse=3, & + & private='[i, j, k, lb, bub_idx, volpart, Vol, strength_vel, strength_vol, y_kahan, t_kahan]') + do k = 0, p + do j = 0, n + do i = 0, m + ! Cell volume + if (num_dims == 2) then + Vol = dx(i)*dy(j)*lag_params%charwidth + if (cyl_coord) Vol = dx(i)*dy(j)*y_cc(j)*2._wp*pi + else + Vol = dx(i)*dy(j)*dz(k) + end if + + ! Loop over bubbles in this cell + $:GPU_LOOP(parallelism='[seq]') + do lb = cell_list_start(i, j, k), cell_list_start(i, j, k) + cell_list_count(i, j, k) - 1 + bub_idx = cell_list_idx(lb) + + volpart = 4._wp/3._wp*pi*lbk_rad(bub_idx, 2)**3._wp + strength_vol = volpart + strength_vel = 4._wp*pi*lbk_rad(bub_idx, 2)**2._wp*lbk_vel(bub_idx, 2) + + ! Kahan summation for void fraction + y_kahan = real(strength_vol/Vol, kind=wp) - kcomp(1)%sf(i, j, k) + t_kahan = updatedvar(1)%sf(i, j, k) + y_kahan + kcomp(1)%sf(i, j, k) = (t_kahan - updatedvar(1)%sf(i, j, k)) - y_kahan + updatedvar(1)%sf(i, j, k) = t_kahan + + ! Kahan summation for time derivative of void fraction + y_kahan = real(strength_vel/Vol, kind=wp) - kcomp(2)%sf(i, j, k) + t_kahan = updatedvar(2)%sf(i, j, k) + y_kahan + kcomp(2)%sf(i, j, k) = (t_kahan - updatedvar(2)%sf(i, j, k)) - y_kahan + updatedvar(2)%sf(i, j, k) = t_kahan + + ! Product of two smeared functions + if (lag_params%cluster_type >= 4) then + y_kahan = real((strength_vol*strength_vel)/Vol, kind=wp) - kcomp(5)%sf(i, j, k) + t_kahan = updatedvar(5)%sf(i, j, k) + y_kahan + kcomp(5)%sf(i, j, k) = (t_kahan - updatedvar(5)%sf(i, j, k)) - y_kahan + updatedvar(5)%sf(i, j, k) = t_kahan + end if + end do + end do + end do end do $:END_GPU_PARALLEL_LOOP() end subroutine s_deltafunc !> Apply the Gaussian kernel function to smear bubble effects onto surrounding cells - subroutine s_gaussian(nBubs, lbk_rad, lbk_vel, lbk_s, lbk_pos, updatedvar) + subroutine s_gaussian(nBubs, lbk_rad, lbk_vel, lbk_s, lbk_pos, updatedvar, kcomp) integer, intent(in) :: nBubs real(wp), dimension(1:lag_params%nBubs_glb,1:3,1:2), intent(in) :: lbk_s, lbk_pos real(wp), dimension(1:lag_params%nBubs_glb,1:2), intent(in) :: lbk_rad, lbk_vel type(scalar_field), dimension(:), intent(inout) :: updatedvar - real(wp), dimension(3) :: center - integer, dimension(3) :: cell - real(wp) :: stddsv + type(scalar_field), dimension(:), intent(inout) :: kcomp + real(wp), dimension(3) :: center, nodecoord, s_coord + integer, dimension(3) :: cell, cellijk + real(wp) :: stddsv, volpart real(wp) :: strength_vel, strength_vol - real(wp), dimension(3) :: nodecoord - real(wp) :: addFun1, addFun2, addFun3 - real(wp) :: func, func2, volpart - integer, dimension(3) :: cellaux - real(wp), dimension(3) :: s_coord - integer :: l, i, j, k - logical :: celloutside - integer :: smearGrid, smearGridz - - smearGrid = mapCells - (-mapCells) + 1 ! Include the cell that contains the bubble (3+1+3) - smearGridz = smearGrid - if (p == 0) smearGridz = 1 - - $:GPU_PARALLEL_LOOP(private='[nodecoord, l, s_coord, cell, center]', copyin='[smearGrid, smearGridz]') - do l = 1, nBubs - nodecoord(1:3) = 0 - center(1:3) = 0._wp - volpart = 4._wp/3._wp*pi*lbk_rad(l, 2)**3._wp - s_coord(1:3) = lbk_s(l,1:3,2) - center(1:2) = lbk_pos(l,1:2,2) - if (p > 0) center(3) = lbk_pos(l, 3, 2) - call s_get_cell(s_coord, cell) - call s_compute_stddsv(cell, volpart, stddsv) - - strength_vol = volpart - strength_vel = 4._wp*pi*lbk_rad(l, 2)**2._wp*lbk_vel(l, 2) - - $:GPU_LOOP(collapse=3,private='[cellaux, nodecoord]') - do i = 1, smearGrid - do j = 1, smearGrid - do k = 1, smearGridz - cellaux(1) = cell(1) + i - (mapCells + 1) - cellaux(2) = cell(2) + j - (mapCells + 1) - cellaux(3) = cell(3) + k - (mapCells + 1) - if (p == 0) cellaux(3) = 0 - - ! Check if the cells intended to smear the bubbles in are in the computational domain and redefine the cells - ! for symmetric boundary - call s_check_celloutside(cellaux, celloutside) - - if (.not. celloutside) then - nodecoord(1) = x_cc(cellaux(1)) - nodecoord(2) = y_cc(cellaux(2)) - if (p > 0) nodecoord(3) = z_cc(cellaux(3)) - call s_applygaussian(center, cellaux, nodecoord, stddsv, 0._wp, func) - if (lag_params%cluster_type >= 4) call s_applygaussian(center, cellaux, nodecoord, stddsv, 1._wp, func2) - - ! Relocate cells for bubbles intersecting symmetric boundaries - if (any((/bc_x%beg, bc_x%end, bc_y%beg, bc_y%end, bc_z%beg, bc_z%end/) == BC_REFLECTIVE)) then - call s_shift_cell_symmetric_bc(cellaux, cell) - end if - else - func = 0._wp - func2 = 0._wp - cellaux(1) = cell(1) - cellaux(2) = cell(2) - cellaux(3) = cell(3) - if (p == 0) cellaux(3) = 0 - end if - - ! Update void fraction field - addFun1 = func*strength_vol - $:GPU_ATOMIC(atomic='update') - updatedvar(1)%sf(cellaux(1), cellaux(2), cellaux(3)) = updatedvar(1)%sf(cellaux(1), cellaux(2), & - & cellaux(3)) + real(addFun1, kind=stp) - - ! Update time derivative of void fraction - addFun2 = func*strength_vel - $:GPU_ATOMIC(atomic='update') - updatedvar(2)%sf(cellaux(1), cellaux(2), cellaux(3)) = updatedvar(2)%sf(cellaux(1), cellaux(2), & - & cellaux(3)) + real(addFun2, kind=stp) - - ! Product of two smeared functions Update void fraction * time derivative of void fraction - if (lag_params%cluster_type >= 4) then - addFun3 = func2*strength_vol*strength_vel - $:GPU_ATOMIC(atomic='update') - updatedvar(5)%sf(cellaux(1), cellaux(2), cellaux(3)) = updatedvar(5)%sf(cellaux(1), cellaux(2), & - & cellaux(3)) + real(addFun3, kind=stp) - end if + real(wp) :: func, func2 + real(wp) :: y_kahan, t_kahan + integer :: i, j, k, di, dj, dk, lb, bub_idx + integer :: di_beg, di_end, dj_beg, dj_end, dk_beg, dk_end + integer :: smear_x_beg, smear_x_end + integer :: smear_y_beg, smear_y_end + integer :: smear_z_beg, smear_z_end + + ! Extended grid range for smearing (includes buffer cells for MPI communication) + + smear_x_beg = -mapCells - 1 + smear_x_end = m + mapCells + 1 + smear_y_beg = merge(-mapCells - 1, 0, n > 0) + smear_y_end = merge(n + mapCells + 1, n, n > 0) + smear_z_beg = merge(-mapCells - 1, 0, p > 0) + smear_z_end = merge(p + mapCells + 1, p, p > 0) + + $:GPU_PARALLEL_LOOP(collapse=3, private='[i, j, k, di, dj, dk, lb, bub_idx, center, nodecoord, s_coord, cell, cellijk, & + & stddsv, volpart, strength_vel, strength_vol, func, func2, y_kahan, t_kahan, di_beg, di_end, dj_beg, & + & dj_end, dk_beg, dk_end]', copyin='[smear_x_beg, smear_x_end, smear_y_beg, smear_y_end, smear_z_beg, & + & smear_z_end]') + do k = smear_z_beg, smear_z_end + do j = smear_y_beg, smear_y_end + do i = smear_x_beg, smear_x_end + cellijk(1) = i + cellijk(2) = j + cellijk(3) = k + + nodecoord(1) = x_cc(i) + nodecoord(2) = y_cc(j) + nodecoord(3) = 0._wp + if (p > 0) nodecoord(3) = z_cc(k) + + ! Neighbor cell range clamped to interior [0:m, 0:n, 0:p] + di_beg = max(i - mapCells, 0) + di_end = min(i + mapCells, m) + dj_beg = max(j - mapCells, 0) + dj_end = min(j + mapCells, n) + dk_beg = max(k - mapCells, 0) + dk_end = min(k + mapCells, p) + + $:GPU_LOOP(parallelism='[seq]') + do dk = dk_beg, dk_end + $:GPU_LOOP(parallelism='[seq]') + do dj = dj_beg, dj_end + $:GPU_LOOP(parallelism='[seq]') + do di = di_beg, di_end + $:GPU_LOOP(parallelism='[seq]') + do lb = cell_list_start(di, dj, dk), cell_list_start(di, dj, dk) + cell_list_count(di, dj, dk) - 1 + bub_idx = cell_list_idx(lb) + + ! Bubble properties + volpart = 4._wp/3._wp*pi*lbk_rad(bub_idx, 2)**3._wp + s_coord(1:3) = lbk_s(bub_idx,1:3,2) + call s_get_cell(s_coord, cell) + call s_compute_stddsv(cell, volpart, stddsv) + + strength_vol = volpart + strength_vel = 4._wp*pi*lbk_rad(bub_idx, 2)**2._wp*lbk_vel(bub_idx, 2) + + center(1:2) = lbk_pos(bub_idx,1:2,2) + center(3) = 0._wp + if (p > 0) center(3) = lbk_pos(bub_idx, 3, 2) + + call s_applygaussian(center, cellijk, nodecoord, stddsv, 0._wp, func) + + ! Kahan summation for void fraction + y_kahan = real(func*strength_vol, kind=wp) - kcomp(1)%sf(i, j, k) + t_kahan = updatedvar(1)%sf(i, j, k) + y_kahan + kcomp(1)%sf(i, j, k) = (t_kahan - updatedvar(1)%sf(i, j, k)) - y_kahan + updatedvar(1)%sf(i, j, k) = t_kahan + + ! Kahan summation for time derivative of void fraction + y_kahan = real(func*strength_vel, kind=wp) - kcomp(2)%sf(i, j, k) + t_kahan = updatedvar(2)%sf(i, j, k) + y_kahan + kcomp(2)%sf(i, j, k) = (t_kahan - updatedvar(2)%sf(i, j, k)) - y_kahan + updatedvar(2)%sf(i, j, k) = t_kahan + + if (lag_params%cluster_type >= 4) then + call s_applygaussian(center, cellijk, nodecoord, stddsv, 1._wp, func2) + y_kahan = real(func2*strength_vol*strength_vel, kind=wp) - kcomp(5)%sf(i, j, k) + t_kahan = updatedvar(5)%sf(i, j, k) + y_kahan + kcomp(5)%sf(i, j, k) = (t_kahan - updatedvar(5)%sf(i, j, k)) - y_kahan + updatedvar(5)%sf(i, j, k) = t_kahan + end if + end do + end do + end do end do end do end do @@ -190,8 +282,9 @@ contains real(wp), intent(in) :: stddsv real(wp), intent(in) :: strength_idx real(wp), intent(out) :: func + integer :: i real(wp) :: distance - real(wp) :: theta, dtheta, L2, dzp, Lz2 + real(wp) :: theta, dtheta, L2, dzp, Lz2, zc real(wp) :: Nr, Nr_count distance = sqrt((center(1) - nodecoord(1))**2._wp + (center(2) - nodecoord(2))**2._wp + (center(3) - nodecoord(3))**2._wp) @@ -223,20 +316,15 @@ contains end do else !> 2D cartesian function: - ! We smear particles considering a virtual depth (lag_params%charwidth) - theta = 0._wp - Nr = ceiling(lag_params%charwidth/(y_cb(cellaux(2)) - y_cb(cellaux(2) - 1))) - Nr_count = 1._wp - mapCells*1._wp - dzp = y_cb(cellaux(2) + 1) - y_cb(cellaux(2)) - Lz2 = (center(3) - (dzp*(0.5_wp + Nr_count) - lag_params%charwidth/2._wp))**2._wp - distance = sqrt((center(1) - nodecoord(1))**2._wp + (center(2) - nodecoord(2))**2._wp + Lz2) - func = dzp/lag_params%charwidth*exp(-0.5_wp*(distance/stddsv)**2._wp)/(sqrt(2._wp*pi)*stddsv)**3._wp - do while (Nr_count < Nr - 1._wp + ((mapCells - 1)*1._wp)) - Nr_count = Nr_count + 1._wp - Lz2 = (center(3) - (dzp*(0.5_wp + Nr_count) - lag_params%charwidth/2._wp))**2._wp + ! We smear particles considering a virtual depth (lag_params%charwidth) with lag_params%charNz cells + dzp = (lag_params%charwidth/(lag_params%charNz + 1._wp)) + + func = 0._wp + do i = 0, lag_params%charNz + zc = (-lag_params%charwidth/2._wp + dzp*(0.5_wp + i)) ! Center of virtual cell i in z-direction + Lz2 = (center(3) - zc)**2._wp distance = sqrt((center(1) - nodecoord(1))**2._wp + (center(2) - nodecoord(2))**2._wp + Lz2) - func = func + dzp/lag_params%charwidth*exp(-0.5_wp*(distance/stddsv)**2._wp)/(sqrt(2._wp*pi)*stddsv) & - & **(3._wp*(strength_idx + 1._wp)) + func = func + dzp/lag_params%charwidth*exp(-0.5_wp*(distance/stddsv)**2._wp)/(sqrt(2._wp*pi)*stddsv)**3._wp end do end if end if @@ -338,7 +426,7 @@ contains end if !> Compute Standard deviaton - if (((volpart/charvol) > 0.5_wp*lag_params%valmaxvoid) .or. (lag_params%smooth_type == 1)) then + if ((volpart/charvol) > 0.5_wp*lag_params%valmaxvoid .or. (lag_params%smooth_type == 1)) then rad = (3._wp*volpart/(4._wp*pi))**(1._wp/3._wp) stddsv = 1._wp*lag_params%epsilonb*max(chardist, rad) else @@ -383,4 +471,216 @@ contains end subroutine s_get_cell + !! @param q_prim_vf Primitive variables (pressure is at index E_idx) + subroutine s_compute_pressure_gradients(q_prim_vf) + + type(scalar_field), dimension(sys_size), intent(in) :: q_prim_vf + integer :: i, j, k, r + + ! dp/dx at all cell centers + + $:GPU_PARALLEL_LOOP(private='[i, j, k, r]', collapse=3) + do k = 0, p + do j = 0, n + do i = 0, m + grad_p_x(i, j, k) = 0._wp + $:GPU_LOOP(parallelism='[seq]') + do r = -fd_number, fd_number + grad_p_x(i, j, k) = grad_p_x(i, j, k) + q_prim_vf(E_idx)%sf(i + r, j, k)*fd_coeff_x_pgrad(r, i) + end do + end do + end do + end do + $:END_GPU_PARALLEL_LOOP() + + ! dp/dy at all cell centers + if (n > 0) then + $:GPU_PARALLEL_LOOP(private='[i, j, k, r]', collapse=3) + do k = 0, p + do j = 0, n + do i = 0, m + grad_p_y(i, j, k) = 0._wp + $:GPU_LOOP(parallelism='[seq]') + do r = -fd_number, fd_number + grad_p_y(i, j, k) = grad_p_y(i, j, k) + q_prim_vf(E_idx)%sf(i, j + r, k)*fd_coeff_y_pgrad(r, j) + end do + end do + end do + end do + $:END_GPU_PARALLEL_LOOP() + end if + + ! dp/dz at all cell centers + if (p > 0) then + $:GPU_PARALLEL_LOOP(private='[i, j, k, r]', collapse=3) + do k = 0, p + do j = 0, n + do i = 0, m + grad_p_z(i, j, k) = 0._wp + $:GPU_LOOP(parallelism='[seq]') + do r = -fd_number, fd_number + grad_p_z(i, j, k) = grad_p_z(i, j, k) + q_prim_vf(E_idx)%sf(i, j, k + r)*fd_coeff_z_pgrad(r, k) + end do + end do + end do + end do + $:END_GPU_PARALLEL_LOOP() + end if + + end subroutine s_compute_pressure_gradients + + !! @param pos Position of the bubble in directiion i + !! @param cell Computational coordinates of the bubble + !! @param i Direction of the velocity (1: x, 2: y, 3: z) + !! @param q_prim_vf Eulerian field with primitive variables + !! @return v Interpolated velocity at the position of the bubble + function f_interpolate_velocity(pos, cell, i, q_prim_vf) result(v) + + $:GPU_ROUTINE(parallelism='[seq]') + real(wp), intent(in) :: pos + integer, dimension(3), intent(in) :: cell + integer, intent(in) :: i + type(scalar_field), dimension(sys_size), intent(in) :: q_prim_vf + real(wp) :: v + real(wp), dimension(fd_order + 1) :: xi, eta, L + + if (fd_order == 2) then + if (i == 1) then + xi(1) = x_cc(cell(1) - 1) + eta(1) = q_prim_vf(momxb)%sf(cell(1) - 1, cell(2), cell(3)) + xi(2) = x_cc(cell(1)) + eta(2) = q_prim_vf(momxb)%sf(cell(1), cell(2), cell(3)) + xi(3) = x_cc(cell(1) + 1) + eta(3) = q_prim_vf(momxb)%sf(cell(1) + 1, cell(2), cell(3)) + else if (i == 2) then + xi(1) = y_cc(cell(2) - 1) + eta(1) = q_prim_vf(momxb + 1)%sf(cell(1), cell(2) - 1, cell(3)) + xi(2) = y_cc(cell(2)) + eta(2) = q_prim_vf(momxb + 1)%sf(cell(1), cell(2), cell(3)) + xi(3) = y_cc(cell(2) + 1) + eta(3) = q_prim_vf(momxb + 1)%sf(cell(1), cell(2) + 1, cell(3)) + else if (i == 3) then + xi(1) = z_cc(cell(3) - 1) + eta(1) = q_prim_vf(momxe)%sf(cell(1), cell(2), cell(3) - 1) + xi(2) = z_cc(cell(3)) + eta(2) = q_prim_vf(momxe)%sf(cell(1), cell(2), cell(3)) + xi(3) = z_cc(cell(3) + 1) + eta(3) = q_prim_vf(momxe)%sf(cell(1), cell(2), cell(3) + 1) + end if + + L(1) = ((pos - xi(2))*(pos - xi(3)))/((xi(1) - xi(2))*(xi(1) - xi(3))) + L(2) = ((pos - xi(1))*(pos - xi(3)))/((xi(2) - xi(1))*(xi(2) - xi(3))) + L(3) = ((pos - xi(1))*(pos - xi(2)))/((xi(3) - xi(1))*(xi(3) - xi(2))) + + v = L(1)*eta(1) + L(2)*eta(2) + L(3)*eta(3) + else if (fd_order == 4) then + if (i == 1) then + xi(1) = x_cc(cell(1) - 2) + eta(1) = q_prim_vf(momxb)%sf(cell(1) - 2, cell(2), cell(3)) + xi(2) = x_cc(cell(1) - 1) + eta(2) = q_prim_vf(momxb)%sf(cell(1) - 1, cell(2), cell(3)) + xi(3) = x_cc(cell(1)) + eta(3) = q_prim_vf(momxb)%sf(cell(1), cell(2), cell(3)) + xi(4) = x_cc(cell(1) + 1) + eta(4) = q_prim_vf(momxb)%sf(cell(1) + 1, cell(2), cell(3)) + xi(5) = x_cc(cell(1) + 2) + eta(5) = q_prim_vf(momxb)%sf(cell(1) + 2, cell(2), cell(3)) + else if (i == 2) then + xi(1) = y_cc(cell(2) - 2) + eta(1) = q_prim_vf(momxb + 1)%sf(cell(1), cell(2) - 2, cell(3)) + xi(2) = y_cc(cell(2) - 1) + eta(2) = q_prim_vf(momxb + 1)%sf(cell(1), cell(2) - 1, cell(3)) + xi(3) = y_cc(cell(2)) + eta(3) = q_prim_vf(momxb + 1)%sf(cell(1), cell(2), cell(3)) + xi(4) = y_cc(cell(2) + 1) + eta(4) = q_prim_vf(momxb + 1)%sf(cell(1), cell(2) + 1, cell(3)) + xi(5) = y_cc(cell(2) + 2) + eta(5) = q_prim_vf(momxb + 1)%sf(cell(1), cell(2) + 2, cell(3)) + else if (i == 3) then + xi(1) = z_cc(cell(3) - 2) + eta(1) = q_prim_vf(momxe)%sf(cell(1), cell(2), cell(3) - 2) + xi(2) = z_cc(cell(3) - 1) + eta(2) = q_prim_vf(momxe)%sf(cell(1), cell(2), cell(3) - 1) + xi(3) = z_cc(cell(3)) + eta(3) = q_prim_vf(momxe)%sf(cell(1), cell(2), cell(3)) + xi(4) = z_cc(cell(3) + 1) + eta(4) = q_prim_vf(momxe)%sf(cell(1), cell(2), cell(3) + 1) + xi(5) = z_cc(cell(3) + 2) + eta(5) = q_prim_vf(momxe)%sf(cell(1), cell(2), cell(3) + 2) + end if + + L(1) = ((pos - xi(2))*(pos - xi(3))*(pos - xi(4))*(pos - xi(5)))/((xi(1) - xi(2))*(xi(1) - xi(3))*(xi(1) - xi(4)) & + & *(xi(2) - xi(5))) + L(2) = ((pos - xi(1))*(pos - xi(3))*(pos - xi(4))*(pos - xi(5)))/((xi(2) - xi(1))*(xi(2) - xi(3))*(xi(2) - xi(4)) & + & *(xi(2) - xi(5))) + L(3) = ((pos - xi(1))*(pos - xi(2))*(pos - xi(4))*(pos - xi(5)))/((xi(3) - xi(1))*(xi(3) - xi(2))*(xi(3) - xi(4)) & + & *(xi(3) - xi(5))) + L(4) = ((pos - xi(1))*(pos - xi(2))*(pos - xi(3))*(pos - xi(4)))/((xi(4) - xi(1))*(xi(4) - xi(2))*(xi(4) - xi(3)) & + & *(xi(4) - xi(5))) + L(5) = ((pos - xi(1))*(pos - xi(2))*(pos - xi(3))*(pos - xi(4)))/((xi(5) - xi(1))*(xi(5) - xi(2))*(xi(5) - xi(3)) & + & *(xi(5) - xi(4))) + + v = L(1)*eta(1) + L(2)*eta(2) + L(3)*eta(3) + L(4)*eta(4) + L(5)*eta(5) + end if + + end function f_interpolate_velocity + + !! @param pos Position of the bubble in direction i + !! @param rad Radius of the bubble + !! @param rdot Radial velocity of the bubble + !! @param vel Velocity of the bubble + !! @param mg Mass of the gas in the bubble + !! @param mv Mass of the liquid in the bubble + !! @param Re Reynolds number + !! @param rho Density of the fluid + !! @param cell Computational coordinates of the bubble + !! @param i Direction of the velocity (1: x, 2: y, 3: z) + !! @param q_prim_vf Eulerian field with primitive variables + !! @return a Acceleration of the bubble in direction i + function f_get_bubble_force(pos, rad, rdot, vel, mg, mv, Re, rho, cell, i, q_prim_vf) result(force) + + $:GPU_ROUTINE(parallelism='[seq]') + real(wp), intent(in) :: pos, rad, rdot, mg, mv, Re, rho, vel + integer, dimension(3), intent(in) :: cell + integer, intent(in) :: i + type(scalar_field), dimension(sys_size), intent(in) :: q_prim_vf + real(wp) :: dp, vol, force + real(wp) :: v_rel + + if (fd_order > 1) then + v_rel = vel - f_interpolate_velocity(pos, cell, i, q_prim_vf) + else + v_rel = vel - q_prim_vf(momxb + i - 1)%sf(cell(1), cell(2), cell(3)) + end if + + force = 0._wp + + if (lag_params%drag_model == 1) then ! Free slip Stokes drag + force = force - (4._wp*pi*rad*v_rel)/Re + else if (lag_params%drag_model == 2) then ! No slip Stokes drag + force = force - (6._wp*pi*rad*v_rel)/Re + else if (lag_params%drag_model == 3) then ! Levich drag + force = force - (12._wp*pi*rad*v_rel)/Re + end if + + if (lag_pressure_force) then + ! Use precomputed cell-centered pressure gradients + if (i == 1) then + dp = grad_p_x(cell(1), cell(2), cell(3)) + else if (i == 2) then + dp = grad_p_y(cell(1), cell(2), cell(3)) + else if (i == 3) then + dp = grad_p_z(cell(1), cell(2), cell(3)) + end if + + vol = (4._wp/3._wp)*pi*(rad**3._wp) + force = force - vol*dp + end if + + if (lag_params%gravity_force) then + force = force + (mg + mv)*accel_bf(i) + end if + + end function f_get_bubble_force + end module m_bubbles_EL_kernels diff --git a/src/simulation/m_compute_levelset.fpp b/src/simulation/m_compute_levelset.fpp index da1dcd9109..47dfd41e8c 100644 --- a/src/simulation/m_compute_levelset.fpp +++ b/src/simulation/m_compute_levelset.fpp @@ -89,8 +89,10 @@ contains radius = patch_ib(ib_patch_id)%radius - dist_vec(1) = x_cc(i) - patch_ib(ib_patch_id)%x_centroid - real(gp%x_periodicity, wp)*(x_domain%end - x_domain%beg) - dist_vec(2) = y_cc(j) - patch_ib(ib_patch_id)%y_centroid - real(gp%y_periodicity, wp)*(y_domain%end - y_domain%beg) + dist_vec(1) = x_cc(i) - patch_ib(ib_patch_id)%x_centroid - real(gp%x_periodicity, & + & wp)*(glb_bounds(1)%end - glb_bounds(1)%beg) + dist_vec(2) = y_cc(j) - patch_ib(ib_patch_id)%y_centroid - real(gp%y_periodicity, & + & wp)*(glb_bounds(2)%end - glb_bounds(2)%beg) dist_vec(3) = 0._wp dist = sqrt(sum(dist_vec**2)) @@ -116,12 +118,13 @@ contains real(wp), dimension(1:2) :: center real(wp), dimension(1:3,1:3) :: rotation, inverse_rotation integer :: i, j, k, ib_patch_id !< Loop index variables + ib_patch_id = gp%ib_patch_id i = gp%loc(1) j = gp%loc(2) - center(1) = patch_ib(ib_patch_id)%x_centroid + real(gp%x_periodicity, wp)*(x_domain%end - x_domain%beg) - center(2) = patch_ib(ib_patch_id)%y_centroid + real(gp%y_periodicity, wp)*(y_domain%end - y_domain%beg) + center(1) = patch_ib(ib_patch_id)%x_centroid + real(gp%x_periodicity, wp)*(glb_bounds(1)%end - glb_bounds(1)%beg) + center(2) = patch_ib(ib_patch_id)%y_centroid + real(gp%y_periodicity, wp)*(glb_bounds(2)%end - glb_bounds(2)%beg) inverse_rotation(:,:) = patch_ib(ib_patch_id)%rotation_matrix_inverse(:,:) rotation(:,:) = patch_ib(ib_patch_id)%rotation_matrix(:,:) offset(:) = patch_ib(ib_patch_id)%centroid_offset(:) @@ -201,9 +204,9 @@ contains j = gp%loc(2) l = gp%loc(3) - center(1) = patch_ib(ib_patch_id)%x_centroid + real(gp%x_periodicity, wp)*(x_domain%end - x_domain%beg) - center(2) = patch_ib(ib_patch_id)%y_centroid + real(gp%y_periodicity, wp)*(y_domain%end - y_domain%beg) - center(3) = patch_ib(ib_patch_id)%z_centroid + real(gp%z_periodicity, wp)*(z_domain%end - z_domain%beg) + center(1) = patch_ib(ib_patch_id)%x_centroid + real(gp%x_periodicity, wp)*(glb_bounds(1)%end - glb_bounds(1)%beg) + center(2) = patch_ib(ib_patch_id)%y_centroid + real(gp%y_periodicity, wp)*(glb_bounds(2)%end - glb_bounds(2)%beg) + center(3) = patch_ib(ib_patch_id)%z_centroid + real(gp%z_periodicity, wp)*(glb_bounds(3)%end - glb_bounds(3)%beg) lz = patch_ib(ib_patch_id)%length_z inverse_rotation(:,:) = patch_ib(ib_patch_id)%rotation_matrix_inverse(:,:) rotation(:,:) = patch_ib(ib_patch_id)%rotation_matrix(:,:) @@ -302,8 +305,8 @@ contains length_x = patch_ib(ib_patch_id)%length_x length_y = patch_ib(ib_patch_id)%length_y - center(1) = patch_ib(ib_patch_id)%x_centroid + real(gp%x_periodicity, wp)*(x_domain%end - x_domain%beg) - center(2) = patch_ib(ib_patch_id)%y_centroid + real(gp%y_periodicity, wp)*(y_domain%end - y_domain%beg) + center(1) = patch_ib(ib_patch_id)%x_centroid + real(gp%x_periodicity, wp)*(glb_bounds(1)%end - glb_bounds(1)%beg) + center(2) = patch_ib(ib_patch_id)%y_centroid + real(gp%y_periodicity, wp)*(glb_bounds(2)%end - glb_bounds(2)%beg) inverse_rotation(:,:) = patch_ib(ib_patch_id)%rotation_matrix_inverse(:,:) rotation(:,:) = patch_ib(ib_patch_id)%rotation_matrix(:,:) @@ -369,8 +372,8 @@ contains length_x = patch_ib(ib_patch_id)%length_x length_y = patch_ib(ib_patch_id)%length_y - center(1) = patch_ib(ib_patch_id)%x_centroid + real(gp%x_periodicity, wp)*(x_domain%end - x_domain%beg) - center(2) = patch_ib(ib_patch_id)%y_centroid + real(gp%y_periodicity, wp)*(y_domain%end - y_domain%beg) + center(1) = patch_ib(ib_patch_id)%x_centroid + real(gp%x_periodicity, wp)*(glb_bounds(1)%end - glb_bounds(1)%beg) + center(2) = patch_ib(ib_patch_id)%y_centroid + real(gp%y_periodicity, wp)*(glb_bounds(2)%end - glb_bounds(2)%beg) inverse_rotation(:,:) = patch_ib(ib_patch_id)%rotation_matrix_inverse(:,:) rotation(:,:) = patch_ib(ib_patch_id)%rotation_matrix(:,:) @@ -422,9 +425,9 @@ contains length_y = patch_ib(ib_patch_id)%length_y length_z = patch_ib(ib_patch_id)%length_z - center(1) = patch_ib(ib_patch_id)%x_centroid + real(gp%x_periodicity, wp)*(x_domain%end - x_domain%beg) - center(2) = patch_ib(ib_patch_id)%y_centroid + real(gp%y_periodicity, wp)*(y_domain%end - y_domain%beg) - center(3) = patch_ib(ib_patch_id)%z_centroid + real(gp%z_periodicity, wp)*(z_domain%end - z_domain%beg) + center(1) = patch_ib(ib_patch_id)%x_centroid + real(gp%x_periodicity, wp)*(glb_bounds(1)%end - glb_bounds(1)%beg) + center(2) = patch_ib(ib_patch_id)%y_centroid + real(gp%y_periodicity, wp)*(glb_bounds(2)%end - glb_bounds(2)%beg) + center(3) = patch_ib(ib_patch_id)%z_centroid + real(gp%z_periodicity, wp)*(glb_bounds(3)%end - glb_bounds(3)%beg) inverse_rotation(:,:) = patch_ib(ib_patch_id)%rotation_matrix_inverse(:,:) rotation(:,:) = patch_ib(ib_patch_id)%rotation_matrix(:,:) @@ -500,9 +503,9 @@ contains k = gp%loc(3) radius = patch_ib(ib_patch_id)%radius - periodicity(1) = real(gp%x_periodicity, wp)*(x_domain%end - x_domain%beg) - periodicity(2) = real(gp%y_periodicity, wp)*(y_domain%end - y_domain%beg) - periodicity(3) = real(gp%z_periodicity, wp)*(z_domain%end - z_domain%beg) + periodicity(1) = real(gp%x_periodicity, wp)*(glb_bounds(1)%end - glb_bounds(1)%beg) + periodicity(2) = real(gp%y_periodicity, wp)*(glb_bounds(2)%end - glb_bounds(2)%beg) + periodicity(3) = real(gp%z_periodicity, wp)*(glb_bounds(3)%end - glb_bounds(3)%beg) center(1) = patch_ib(ib_patch_id)%x_centroid center(2) = patch_ib(ib_patch_id)%y_centroid center(3) = patch_ib(ib_patch_id)%z_centroid @@ -542,9 +545,9 @@ contains k = gp%loc(3) radius = patch_ib(ib_patch_id)%radius - center(1) = patch_ib(ib_patch_id)%x_centroid + real(gp%x_periodicity, wp)*(x_domain%end - x_domain%beg) - center(2) = patch_ib(ib_patch_id)%y_centroid + real(gp%y_periodicity, wp)*(y_domain%end - y_domain%beg) - center(3) = patch_ib(ib_patch_id)%z_centroid + real(gp%z_periodicity, wp)*(z_domain%end - z_domain%beg) + center(1) = patch_ib(ib_patch_id)%x_centroid + real(gp%x_periodicity, wp)*(glb_bounds(1)%end - glb_bounds(1)%beg) + center(2) = patch_ib(ib_patch_id)%y_centroid + real(gp%y_periodicity, wp)*(glb_bounds(2)%end - glb_bounds(2)%beg) + center(3) = patch_ib(ib_patch_id)%z_centroid + real(gp%z_periodicity, wp)*(glb_bounds(3)%end - glb_bounds(3)%beg) length(1) = patch_ib(ib_patch_id)%length_x length(2) = patch_ib(ib_patch_id)%length_y length(3) = patch_ib(ib_patch_id)%length_z @@ -618,12 +621,12 @@ contains center = 0._wp if (.not. f_is_default(patch_ib(patch_id)%x_centroid)) center(1) = patch_ib(patch_id)%x_centroid + real(gp%x_periodicity, & - & wp)*(x_domain%end - x_domain%beg) + & wp)*(glb_bounds(1)%end - glb_bounds(1)%beg) if (.not. f_is_default(patch_ib(patch_id)%y_centroid)) center(2) = patch_ib(patch_id)%y_centroid + real(gp%y_periodicity, & - & wp)*(y_domain%end - y_domain%beg) + & wp)*(glb_bounds(2)%end - glb_bounds(2)%beg) if (p > 0) then if (.not. f_is_default(patch_ib(patch_id)%z_centroid)) center(3) = patch_ib(patch_id)%z_centroid & - & + real(gp%z_periodicity, wp)*(z_domain%end - z_domain%beg) + & + real(gp%z_periodicity, wp)*(glb_bounds(3)%end - glb_bounds(3)%beg) end if inverse_rotation(:,:) = patch_ib(patch_id)%rotation_matrix_inverse(:,:) diff --git a/src/simulation/m_data_output.fpp b/src/simulation/m_data_output.fpp index 086a218289..0104dbfddb 100644 --- a/src/simulation/m_data_output.fpp +++ b/src/simulation/m_data_output.fpp @@ -30,19 +30,8 @@ module m_data_output & s_finalize_data_output_module integer :: ib_state_unit = -1 !< I/O unit for IB state binary file - real(wp), allocatable, dimension(:,:,:) :: icfl_sf !< ICFL stability criterion - real(wp), allocatable, dimension(:,:,:) :: vcfl_sf !< VCFL stability criterion - real(wp), allocatable, dimension(:,:,:) :: ccfl_sf !< CCFL stability criterion - real(wp), allocatable, dimension(:,:,:) :: Rc_sf !< Rc stability criterion real(wp), public, allocatable, dimension(:,:) :: c_mass - $:GPU_DECLARE(create='[icfl_sf, vcfl_sf, ccfl_sf, Rc_sf, c_mass]') - - real(wp) :: icfl_max_loc, icfl_max_glb !< ICFL stability extrema on local and global grids - real(wp) :: vcfl_max_loc, vcfl_max_glb !< VCFL stability extrema on local and global grids - real(wp) :: ccfl_max_loc, ccfl_max_glb !< CCFL stability extrema on local and global grids - real(wp) :: Rc_min_loc, Rc_min_glb !< Rc stability extrema on local and global grids - $:GPU_DECLARE(create='[icfl_max_loc, icfl_max_glb, vcfl_max_loc, vcfl_max_glb]') - $:GPU_DECLARE(create='[ccfl_max_loc, ccfl_max_glb, Rc_min_loc, Rc_min_glb]') + $:GPU_DECLARE(create='[c_mass]') !> @name ICFL, VCFL, CCFL and Rc stability criteria extrema over all the time-steps !> @{ @@ -57,6 +46,12 @@ module m_data_output contains !> Write data files. Dispatch subroutine that replaces procedure pointer. + !! @param q_cons_vf Conservative variables + !! @param q_T_sf Temperature scalar field + !! @param q_prim_vf Primitive variables + !! @param t_step Current time step + !! @param bc_type Boundary condition type + !! @param beta Eulerian void fraction from lagrangian bubbles impure subroutine s_write_data_files(q_cons_vf, q_T_sf, q_prim_vf, t_step, bc_type, beta) type(scalar_field), dimension(sys_size), intent(inout) :: q_cons_vf @@ -74,13 +69,17 @@ contains end subroutine s_write_data_files - !> Open the run-time information file and write the stability criteria table header + !> The purpose of this subroutine is to open a new or pre- existing run-time information file and append to it the basic header + !! information relevant to current simulation. In general, this requires generating a table header for those stability criteria + !! which will be written at every time-step. impure subroutine s_open_run_time_information_file character(LEN=name_len), parameter :: file_name = 'run_time.inf' !< Name of the run-time information file character(LEN=path_len + name_len) :: file_path !< Relative path to a file in the case directory character(LEN=8) :: file_date !< Creation date of the run-time information file + ! Opening the run-time information file + file_path = trim(case_dir) // '/' // trim(file_name) open (3, FILE=trim(file_path), form='formatted', STATUS='replace') @@ -98,25 +97,32 @@ contains write (3, '(A)') ''; write (3, '(A)') '' + ! Generating table header for the stability criteria to be outputted write (3, '(13X,A9,13X,A10,13X,A10,13X,A10)', advance="no") trim('Time-step'), trim('dt'), trim('Time'), trim('ICFL Max') if (viscous) then write (3, '(13X,A10,13X,A16)', advance="no") trim('VCFL Max'), trim('Rc Min') end if + if (bubbles_lagrange) then + write (3, '(13X,A10)', advance="no") trim('N Bubbles') + end if + write (3, *) ! new line end subroutine s_open_run_time_information_file - !> Open center-of-mass data files for writing + !> This opens a formatted data file where the root processor can write out the CoM information impure subroutine s_open_com_files() character(len=path_len + 3*name_len) :: file_path !< Relative path to the CoM file in the case directory integer :: i !< Generic loop iterator do i = 1, num_fluids + ! Generating the relative path to the CoM data file write (file_path, '(A,I0,A)') '/fluid', i, '_com.dat' file_path = trim(case_dir) // trim(file_path) + ! Creating the formatted data file and setting up its structure open (i + 120, file=trim(file_path), form='formatted', position='append', status='unknown') if (n == 0) then write (i + 120, '(A)') ' Non-Dimensional Time ' // ' Total Mass ' // ' x-loc ' // ' Total Volume ' @@ -133,7 +139,7 @@ contains end subroutine s_open_com_files - !> Open flow probe data files for writing + !> This opens a formatted data file where the root processor can write out flow probe information impure subroutine s_open_probe_files character(LEN=path_len + 3*name_len) :: file_path !< Relative path to the probe data file in the case directory @@ -141,9 +147,11 @@ contains logical :: file_exist do i = 1, num_probes + ! Generating the relative path to the data file write (file_path, '(A,I0,A)') '/D/probe', i, '_prim.dat' file_path = trim(case_dir) // trim(file_path) + ! Creating the formatted data file and setting up its structure inquire (file=trim(file_path), exist=file_exist) if (file_exist) then @@ -164,7 +172,6 @@ contains end subroutine s_open_probe_files - !> Open the immersed boundary state file for binary output impure subroutine s_open_ib_state_file character(len=path_len + 2*name_len) :: file_loc @@ -177,7 +184,11 @@ contains end subroutine s_open_ib_state_file - !> Write stability criteria extrema to the run-time information file at the given time step + !> The goal of the procedure is to output to the run-time information file the stability criteria extrema in the entire + !! computational domain and at the given time-step. Moreover, the subroutine is also in charge of tracking these stability + !! criteria extrema over all time-steps. + !! @param q_prim_vf Cell-average primitive variables + !! @param t_step Current time step impure subroutine s_write_run_time_information(q_prim_vf, t_step) type(scalar_field), dimension(sys_size), intent(in) :: q_prim_vf @@ -191,19 +202,27 @@ contains real(wp), dimension(num_fluids) :: alpha !< Cell-avg. volume fraction real(wp), dimension(num_vels) :: vel !< Cell-avg. velocity #:endif - real(wp) :: vel_sum !< Cell-avg. velocity sum - real(wp) :: pres !< Cell-avg. pressure - real(wp) :: gamma !< Cell-avg. sp. heat ratio - real(wp) :: pi_inf !< Cell-avg. liquid stiffness function - real(wp) :: qv !< Cell-avg. internal energy reference value - real(wp) :: c !< Cell-avg. sound speed - real(wp) :: H !< Cell-avg. enthalpy - real(wp), dimension(2) :: Re !< Cell-avg. Reynolds numbers + real(wp) :: vel_sum !< Cell-avg. velocity sum + real(wp) :: pres !< Cell-avg. pressure + real(wp) :: gamma !< Cell-avg. sp. heat ratio + real(wp) :: pi_inf !< Cell-avg. liquid stiffness function + real(wp) :: qv !< Cell-avg. internal energy reference value + real(wp) :: c !< Cell-avg. sound speed + real(wp) :: H !< Cell-avg. enthalpy + real(wp), dimension(2) :: Re !< Cell-avg. Reynolds numbers integer :: j, k, l - + real(wp) :: icfl_max_loc, icfl_max_glb !< ICFL stability extrema on local and global grids + real(wp) :: vcfl_max_loc, vcfl_max_glb !< VCFL stability extrema on local and global grids + real(wp) :: ccfl_max_loc, ccfl_max_glb !< CCFL stability extrema on local and global grids + real(wp) :: Rc_min_loc, Rc_min_glb !< Rc stability extrema on local and global grids + real(wp) :: icfl, vcfl, Rc + + icfl_max_loc = 0._wp + vcfl_max_loc = 0._wp + Rc_min_loc = huge(1.0_wp) ! Computing Stability Criteria at Current Time-step - - $:GPU_PARALLEL_LOOP(collapse=3, private='[j, k, l, vel, alpha, Re, rho, vel_sum, pres, gamma, pi_inf, c, H, qv]') + $:GPU_PARALLEL_LOOP(collapse=3, private='[j, k, l, vel, alpha, Re, rho, vel_sum, pres, gamma, pi_inf, c, H, qv, icfl, & + & vcfl, Rc]', reduction='[[icfl_max_loc, vcfl_max_loc], [Rc_min_loc]]', reductionOp='[max, min]') do l = 0, p do k = 0, n do j = 0, m @@ -212,49 +231,32 @@ contains call s_compute_speed_of_sound(pres, rho, gamma, pi_inf, H, alpha, vel_sum, 0._wp, c, qv) if (viscous) then - call s_compute_stability_from_dt(vel, c, rho, Re, j, k, l, icfl_sf, vcfl_sf, Rc_sf) + call s_compute_stability_from_dt(vel, c, rho, Re, j, k, l, icfl, vcfl, Rc) else - call s_compute_stability_from_dt(vel, c, rho, Re, j, k, l, icfl_sf) + call s_compute_stability_from_dt(vel, c, rho, Re, j, k, l, icfl) end if + + icfl_max_loc = max(icfl_max_loc, icfl) + vcfl_max_loc = max(vcfl_max_loc, merge(vcfl, 0.0_wp, viscous)) + Rc_min_loc = min(Rc_min_loc, merge(Rc, huge(1.0_wp), viscous)) end do end do end do $:END_GPU_PARALLEL_LOOP() + ! end: Computing Stability Criteria at Current Time-step -#ifdef _CRAYFTN - $:GPU_UPDATE(host='[icfl_sf]') - - if (viscous) then - $:GPU_UPDATE(host='[vcfl_sf, Rc_sf]') - end if - - icfl_max_loc = maxval(icfl_sf) - - if (viscous) then - vcfl_max_loc = maxval(vcfl_sf) - Rc_min_loc = minval(Rc_sf) - end if -#else - #:call GPU_PARALLEL(copyout='[icfl_max_loc]', copyin='[icfl_sf]') - icfl_max_loc = maxval(icfl_sf) - #:endcall GPU_PARALLEL - if (viscous .or. dummy) then - #:call GPU_PARALLEL(copyout='[vcfl_max_loc, Rc_min_loc]', copyin='[vcfl_sf,Rc_sf]') - vcfl_max_loc = maxval(vcfl_sf) - Rc_min_loc = minval(Rc_sf) - #:endcall GPU_PARALLEL - end if -#endif - + ! Determining global stability criteria extrema at current time-step if (num_procs > 1) then - call s_mpi_reduce_stability_criteria_extrema(icfl_max_loc, vcfl_max_loc, Rc_min_loc, icfl_max_glb, vcfl_max_glb, & - & Rc_min_glb) + call s_mpi_reduce_stability_criteria_extrema(icfl_max_loc, vcfl_max_loc, Rc_min_loc, n_el_bubs_loc, icfl_max_glb, & + & vcfl_max_glb, Rc_min_glb, n_el_bubs_glb) else icfl_max_glb = icfl_max_loc if (viscous) vcfl_max_glb = vcfl_max_loc if (viscous) Rc_min_glb = Rc_min_loc + if (bubbles_lagrange) n_el_bubs_glb = n_el_bubs_loc end if + ! Determining the stability criteria extrema over all the time-steps if (icfl_max_glb > icfl_max) icfl_max = icfl_max_glb if (viscous) then @@ -262,6 +264,7 @@ contains if (Rc_min_glb < Rc_min) Rc_min = Rc_min_glb end if + ! Outputting global stability criteria extrema at current time-step if (proc_rank == 0) then write (3, '(13X,I9,13X,F10.6,13X,F10.6,13X,F10.6)', advance="no") t_step, dt, mytime, icfl_max_glb @@ -269,6 +272,10 @@ contains write (3, '(13X,F10.6,13X,ES16.6)', advance="no") vcfl_max_glb, Rc_min_glb end if + if (bubbles_lagrange) then + write (3, '(13X,I10)', advance="no") n_el_bubs_glb + end if + write (3, *) ! new line if (.not. f_approx_equal(icfl_max_glb, icfl_max_glb)) then @@ -286,13 +293,25 @@ contains call s_mpi_abort('VCFL is greater than 1.0. Exiting.') end if end if + + if (bubbles_lagrange) then + if (n_el_bubs_glb == 0) then + call s_mpi_abort('No Lagrangian bubbles remain in the domain. Exiting.') + end if + end if end if call s_mpi_barrier() end subroutine s_write_run_time_information - !> Write grid and conservative variable data files in serial format + !> The goal of this subroutine is to output the grid and conservative variables data files for given time-step. + !! @param q_cons_vf Cell-average conservative variables + !! @param q_T_sf Temperature scalar field + !! @param q_prim_vf Cell-average primitive variables + !! @param t_step Current time-step + !! @param bc_type Boundary condition type + !! @param beta Eulerian void fraction from lagrangian bubbles impure subroutine s_write_serial_data_files(q_cons_vf, q_T_sf, q_prim_vf, t_step, bc_type, beta) type(scalar_field), dimension(sys_size), intent(inout) :: q_cons_vf @@ -308,7 +327,11 @@ contains integer :: i, j, k, l, r real(wp) :: gamma, lit_gamma, pi_inf, qv !< Temporary EOS params + ! Creating or overwriting the time-step root directory + write (t_step_dir, '(A,I0,A,I0)') trim(case_dir) // '/p_all' + + ! Creating or overwriting the current time-step directory write (t_step_dir, '(a,i0,a,i0)') trim(case_dir) // '/p_all/p', proc_rank, '/', t_step file_path = trim(t_step_dir) // '/.' @@ -316,11 +339,13 @@ contains if (file_exist) call s_delete_directory(trim(t_step_dir)) call s_create_directory(trim(t_step_dir)) + ! Writing the grid data file in the x-direction file_path = trim(t_step_dir) // '/x_cb.dat' open (2, FILE=trim(file_path), form='unformatted', STATUS='new') write (2) x_cb(-1:m); close (2) + ! Writing the grid data files in the y- and z-directions if (n > 0) then file_path = trim(t_step_dir) // '/y_cb.dat' @@ -335,6 +360,7 @@ contains end if end if + ! Writing the conservative variables data files do i = 1, sys_size write (file_path, '(A,I0,A)') trim(t_step_dir) // '/q_cons_vf', i, '.dat' @@ -378,6 +404,11 @@ contains ! Writing the IB markers if (ib) then call s_write_serial_ib_data(t_step) + ! write (file_path, '(A,I0,A)') trim(t_step_dir)//'/ib.dat' + + ! open (2, FILE=trim(file_path), & FORM='unformatted', & STATUS='new') + + ! write (2) ib_markers%sf(0:m, 0:n, 0:p); close (2) end if gamma = gammas(1) @@ -391,6 +422,7 @@ contains FMT = "(2F40.14)" end if + ! writing an output directory write (t_step_dir, '(A,I0,A,I0)') trim(case_dir) // '/D' file_path = trim(t_step_dir) // '/.' @@ -409,6 +441,7 @@ contains end if end if + ! 1D if (n == 0 .and. p == 0) then if (model_eqns == 2 .and. (.not. igr)) then do i = 1, sys_size @@ -471,6 +504,7 @@ contains FMT = "(3F40.14)" end if + ! 2D if ((n > 0) .and. (p == 0)) then do i = 1, sys_size write (file_path, '(A,I0,A,I2.2,A,I6.6,A)') trim(t_step_dir) // '/cons.', i, '.', proc_rank, '.', t_step, '.dat' @@ -555,6 +589,7 @@ contains FMT = "(4F40.14)" end if + ! 3D if (p > 0) then do i = 1, sys_size write (file_path, '(A,I0,A,I2.2,A,I6.6,A)') trim(t_step_dir) // '/cons.', i, '.', proc_rank, '.', t_step, '.dat' @@ -648,7 +683,11 @@ contains end subroutine s_write_serial_data_files - !> Write grid and conservative variable data files in parallel via MPI I/O + !> The goal of this subroutine is to output the grid and conservative variables data files for given time-step. + !! @param q_cons_vf Cell-average conservative variables + !! @param t_step Current time-step + !! @param bc_type Boundary condition type + !! @param beta Eulerian void fraction from lagrangian bubbles impure subroutine s_write_parallel_data_files(q_cons_vf, t_step, bc_type, beta) type(scalar_field), dimension(sys_size), intent(inout) :: q_cons_vf @@ -669,6 +708,7 @@ contains character(len=10) :: t_step_string integer :: i !< Generic loop iterator integer :: alt_sys !< Altered system size for the lagrangian subgrid bubble model + ! Down sampling variables integer :: m_ds, n_ds, p_ds integer :: m_glb_ds, n_glb_ds, p_glb_ds @@ -687,6 +727,7 @@ contains if (file_per_process) then call s_int_to_str(t_step, t_step_string) + ! Initialize MPI data I/O if (down_sample) then call s_initialize_mpi_data_ds(q_cons_temp_ds) else @@ -708,8 +749,10 @@ contains call s_mpi_barrier() call DelayFileAccess(proc_rank) + ! Initialize MPI data I/O call s_initialize_mpi_data(q_cons_vf) + ! Open the file to write all flow variables write (file_loc, '(I0,A,i7.7,A)') t_step, '_', proc_rank, '.dat' file_loc = trim(case_dir) // '/restart_data/lustre_' // trim(t_step_string) // trim(mpiiofs) // trim(file_loc) inquire (FILE=trim(file_loc), EXIST=file_exist) @@ -719,17 +762,20 @@ contains call MPI_FILE_OPEN(MPI_COMM_SELF, file_loc, ior(MPI_MODE_WRONLY, MPI_MODE_CREATE), mpi_info_int, ifile, ierr) if (down_sample) then + ! Size of local arrays data_size = (m_ds + 3)*(n_ds + 3)*(p_ds + 3) m_glb_save = m_glb_ds + 1 n_glb_save = n_glb_ds + 1 p_glb_save = p_glb_ds + 1 else + ! Size of local arrays data_size = (m + 1)*(n + 1)*(p + 1) m_glb_save = m_glb + 1 n_glb_save = n_glb + 1 p_glb_save = p_glb + 1 end if + ! Resize some integers so MPI can write even the biggest files m_MOK = int(m_glb_save + 1, MPI_OFFSET_KIND) n_MOK = int(n_glb_save + 1, MPI_OFFSET_KIND) p_MOK = int(p_glb_save + 1, MPI_OFFSET_KIND) @@ -739,11 +785,13 @@ contains NVARS_MOK = int(sys_size, MPI_OFFSET_KIND) if (bubbles_euler) then + ! Write the data for each variable do i = 1, sys_size var_MOK = int(i, MPI_OFFSET_KIND) call MPI_FILE_WRITE_ALL(ifile, MPI_IO_DATA%var(i)%sf, data_size*mpi_io_type, mpi_io_p, status, ierr) end do + ! Write pb and mv for non-polytropic qbmm if (qbmm .and. .not. polytropic) then do i = sys_size + 1, sys_size + 2*nb*nnode var_MOK = int(i, MPI_OFFSET_KIND) @@ -769,6 +817,8 @@ contains call MPI_FILE_CLOSE(ifile, ierr) else + ! Initialize MPI data I/O + if (ib) then call s_initialize_mpi_data(q_cons_vf, ib_markers) else if (present(beta)) then @@ -785,8 +835,10 @@ contains end if call MPI_FILE_OPEN(MPI_COMM_WORLD, file_loc, ior(MPI_MODE_WRONLY, MPI_MODE_CREATE), mpi_info_int, ifile, ierr) + ! Size of local arrays data_size = (m + 1)*(n + 1)*(p + 1) + ! Resize some integers so MPI can write even the biggest files m_MOK = int(m_glb + 1, MPI_OFFSET_KIND) n_MOK = int(n_glb + 1, MPI_OFFSET_KIND) p_MOK = int(p_glb + 1, MPI_OFFSET_KIND) @@ -796,18 +848,22 @@ contains NVARS_MOK = int(alt_sys, MPI_OFFSET_KIND) if (bubbles_euler) then + ! Write the data for each variable do i = 1, sys_size var_MOK = int(i, MPI_OFFSET_KIND) + ! Initial displacement to skip at beginning of file disp = m_MOK*max(MOK, n_MOK)*max(MOK, p_MOK)*WP_MOK*(var_MOK - 1) call MPI_FILE_SET_VIEW(ifile, disp, mpi_p, MPI_IO_DATA%view(i), 'native', mpi_info_int, ierr) call MPI_FILE_WRITE_ALL(ifile, MPI_IO_DATA%var(i)%sf, data_size*mpi_io_type, mpi_io_p, status, ierr) end do + ! Write pb and mv for non-polytropic qbmm if (qbmm .and. .not. polytropic) then do i = sys_size + 1, sys_size + 2*nb*nnode var_MOK = int(i, MPI_OFFSET_KIND) + ! Initial displacement to skip at beginning of file disp = m_MOK*max(MOK, n_MOK)*max(MOK, p_MOK)*WP_MOK*(var_MOK - 1) call MPI_FILE_SET_VIEW(ifile, disp, mpi_p, MPI_IO_DATA%view(i), 'native', mpi_info_int, ierr) @@ -818,6 +874,7 @@ contains do i = 1, sys_size ! TODO: check if sys_size is correct var_MOK = int(i, MPI_OFFSET_KIND) + ! Initial displacement to skip at beginning of file disp = m_MOK*max(MOK, n_MOK)*max(MOK, p_MOK)*WP_MOK*(var_MOK - 1) call MPI_FILE_SET_VIEW(ifile, disp, mpi_p, MPI_IO_DATA%view(i), 'native', mpi_info_int, ierr) @@ -825,9 +882,11 @@ contains end do end if + ! Correction for the lagrangian subgrid bubble model if (present(beta)) then var_MOK = int(sys_size + 1, MPI_OFFSET_KIND) + ! Initial displacement to skip at beginning of file disp = m_MOK*max(MOK, n_MOK)*max(MOK, p_MOK)*WP_MOK*(var_MOK - 1) call MPI_FILE_SET_VIEW(ifile, disp, mpi_p, MPI_IO_DATA%view(sys_size + 1), 'native', mpi_info_int, ierr) @@ -836,21 +895,33 @@ contains call MPI_FILE_CLOSE(ifile, ierr) + ! Write ib data if (ib) then call s_write_parallel_ib_data(t_step) + ! write (file_loc, '(A)') 'ib.dat' file_loc = trim(case_dir)//'/restart_data'//trim(mpiiofs)//trim(file_loc) call + ! MPI_FILE_OPEN(MPI_COMM_WORLD, file_loc, ior(MPI_MODE_WRONLY, MPI_MODE_CREATE), & mpi_info_int, ifile, ierr) + + ! var_MOK = int(sys_size + 1, MPI_OFFSET_KIND) disp = m_MOK*max(MOK, n_MOK)*max(MOK, p_MOK)*WP_MOK*(var_MOK - 1 + + ! int(t_step/t_step_save)) + + ! call MPI_FILE_SET_VIEW(ifile, disp, MPI_INTEGER, MPI_IO_IB_DATA%view, & 'native', mpi_info_int, ierr) call + ! MPI_FILE_WRITE_ALL(ifile, MPI_IO_IB_DATA%var%sf, data_size, & MPI_INTEGER, status, ierr) call + ! MPI_FILE_CLOSE(ifile, ierr) end if end if #endif end subroutine s_write_parallel_data_files - !> Write immersed boundary marker data to a serial (per-processor) unformatted file + !> @brief Writes immersed boundary marker data to a serial (per-processor) unformatted file. subroutine s_write_serial_ib_data(time_step) integer, intent(in) :: time_step character(LEN=path_len + 2*name_len) :: file_path character(LEN=path_len + 2*name_len) :: t_step_dir + ! Creating or overwriting the time-step root directory + write (t_step_dir, '(A,I0,A,I0)') trim(case_dir) // '/p_all' write (t_step_dir, '(a,i0,a,i0)') trim(case_dir) // '/p_all/p', proc_rank, '/', time_step write (file_path, '(A,I0,A)') trim(t_step_dir) // '/ib_data.dat' @@ -862,7 +933,7 @@ contains end subroutine s_write_serial_ib_data - !> Write immersed boundary marker data in parallel using MPI I/O + !> @brief Writes immersed boundary marker data in parallel using MPI I/O. subroutine s_write_parallel_ib_data(time_step) integer, intent(in) :: time_step @@ -877,6 +948,7 @@ contains $:GPU_UPDATE(host='[ib_markers%sf]') + ! Size of local arrays data_size = (m + 1)*(n + 1)*(p + 1) m_MOK = int(m_glb + 1, MPI_OFFSET_KIND) n_MOK = int(n_glb + 1, MPI_OFFSET_KIND) @@ -899,7 +971,7 @@ contains end subroutine s_write_parallel_ib_data - !> Dispatch immersed boundary data output to the serial or parallel writer + !> @brief Dispatches immersed boundary data output to the serial or parallel writer. subroutine s_write_ib_data_file(time_step) integer, intent(in) :: time_step @@ -912,7 +984,7 @@ contains end subroutine s_write_ib_data_file - !> Write IB state records to D/ib_state.dat (rank 0 only) + !> @brief Writes IB state records to D/ib_state.dat. Must be called only on rank 0. impure subroutine s_write_ib_state_file() integer :: i @@ -924,7 +996,9 @@ contains end subroutine s_write_ib_state_file - !> Write center-of-mass data at the current time step + !> This writes a formatted data file where the root processor can write out the CoM information + !! @param t_step Current time-step + !! @param c_mass_in Center of mass information impure subroutine s_write_com_files(t_step, c_mass_in) integer, intent(in) :: t_step @@ -932,6 +1006,8 @@ contains integer :: i !< Generic loop iterator real(wp) :: nondim_time !< Non-dimensional time + ! Non-dimensional time calculation + if (t_step_old /= dflt_int) then nondim_time = real(t_step + t_step_old, wp)*dt else @@ -957,7 +1033,10 @@ contains end subroutine s_write_com_files - !> Write flow probe data at the current time step + !> This writes a formatted data file for the flow probe information + !! @param t_step Current time-step + !! @param q_cons_vf Conservative variables + !! @param accel_mag Acceleration magnitude information impure subroutine s_write_probe_files(t_step, q_cons_vf, accel_mag) integer, intent(in) :: t_step @@ -1004,6 +1083,7 @@ contains T = dflt_T_guess + ! Non-dimensional time calculation if (time_stepper == 23) then nondim_time = mytime else @@ -1015,6 +1095,7 @@ contains end if do i = 1, num_probes + ! Zeroing out flow variables for all processors rho = 0._wp do s = 1, num_vels vel(s) = 0._wp @@ -1041,6 +1122,7 @@ contains end do damage_state = 0._wp + ! Find probe location in terms of indices on a specific processor if (n == 0) then if ((probe(i)%x >= x_cb(-1)) .and. (probe(i)%x <= x_cb(m))) then do s = -1, m @@ -1494,17 +1576,21 @@ contains end subroutine s_write_probe_files - !> Write footer with stability criteria extrema and run-time to the information file, then close it + !> The goal of this subroutine is to write to the run-time information file basic footer information applicable to the current + !! computation and to close the file when done. The footer contains the stability criteria extrema over all of the time-steps + !! and the simulation run-time. impure subroutine s_close_run_time_information_file real(wp) :: run_time !< Run-time of the simulation + ! Writing the footer of and closing the run-time information file + write (3, '(A)') ' ' write (3, '(A)') '' write (3, '(A,F9.6)') 'ICFL Max: ', icfl_max if (viscous) write (3, '(A,F9.6)') 'VCFL Max: ', vcfl_max - if (viscous) write (3, '(A,F10.6)') 'Rc Min: ', Rc_min + if (viscous) write (3, '(A,ES16.6)') 'Rc Min: ', Rc_min call cpu_time(run_time) @@ -1537,28 +1623,25 @@ contains end subroutine s_close_probe_files - !> Close the immersed boundary state file impure subroutine s_close_ib_state_file close (ib_state_unit) end subroutine s_close_ib_state_file - !> Initialize the data output module + !> The computation of parameters, the allocation of memory, the association of pointers and/or the execution of any other + !! procedures that are necessary to setup the module. impure subroutine s_initialize_data_output_module integer :: i, m_ds, n_ds, p_ds + ! Allocating/initializing ICFL, VCFL, CCFL and Rc stability criteria + if (run_time_info) then - @:ALLOCATE(icfl_sf(0:m, 0:n, 0:p)) icfl_max = 0._wp - if (viscous) then - @:ALLOCATE(vcfl_sf(0:m, 0:n, 0:p)) - @:ALLOCATE(Rc_sf (0:m, 0:n, 0:p)) - vcfl_max = 0._wp - Rc_min = 1.e3_wp + Rc_min = 1.e12_wp end if end if @@ -1588,13 +1671,6 @@ contains @:DEALLOCATE(c_mass) end if - if (run_time_info) then - @:DEALLOCATE(icfl_sf) - if (viscous) then - @:DEALLOCATE(vcfl_sf, Rc_sf) - end if - end if - if (down_sample) then do i = 1, sys_size deallocate (q_cons_temp_ds(i)%sf) diff --git a/src/simulation/m_global_parameters.fpp b/src/simulation/m_global_parameters.fpp index 079d36ebc2..18687ea89b 100644 --- a/src/simulation/m_global_parameters.fpp +++ b/src/simulation/m_global_parameters.fpp @@ -14,6 +14,7 @@ module m_global_parameters use m_derived_types use m_helper_basic + ! $:USE_GPU_MODULE() implicit none @@ -26,8 +27,10 @@ module m_global_parameters character(LEN=path_len) :: case_dir !< Case folder location logical :: run_time_info !< Run-time output flag integer :: t_step_old !< Existing IC/grid folder + ! Computational Domain Parameters integer :: proc_rank !< Rank of the local processor + !> @name Number of cells in the x-, y- and z-directions, respectively !> @{ integer :: m, n, p @@ -51,20 +54,22 @@ module m_global_parameters !> @name Cell-boundary (CB) locations in the x-, y- and z-directions, respectively !> @{ real(wp), target, allocatable, dimension(:) :: x_cb, y_cb, z_cb + type(bounds_info), dimension(3) :: glb_bounds !> @} !> @name Cell-center (CC) locations in the x-, y- and z-directions, respectively !> @{ real(wp), target, allocatable, dimension(:) :: x_cc, y_cc, z_cc !> @} - ! type(bounds_info) :: x_domain, y_domain, z_domain !< Locations of the domain bounds in the x-, y- and z-coordinate directions + !> @name Cell-width distributions in the x-, y- and z-directions, respectively !> @{ real(wp), target, allocatable, dimension(:) :: dx, dy, dz !> @} real(wp) :: dt !< Size of the time-step - $:GPU_DECLARE(create='[x_cb, y_cb, z_cb, x_cc, y_cc, z_cc, dx, dy, dz, dt, m, n, p]') + + $:GPU_DECLARE(create='[x_cb, y_cb, z_cb, x_cc, y_cc, z_cc, dx, dy, dz, dt, m, n, p, glb_bounds]') !> @name Starting time-step iteration, stopping time-step iteration and the number of time-step iterations between successive !! solution backups, respectively @@ -81,6 +86,7 @@ module m_global_parameters logical :: cfl_adap_dt, cfl_const_dt, cfl_dt integer :: t_step_print !< Number of time-steps between printouts + ! Simulation Algorithm Parameters integer :: model_eqns !< Multicomponent flow model #:if MFC_CASE_OPTIMIZATION @@ -206,10 +212,12 @@ module m_global_parameters integer :: relax_model !< Relaxation model real(wp) :: palpha_eps !< trigger parameter for the p relaxation procedure, phase change model real(wp) :: ptgalpha_eps !< trigger parameter for the pTg relaxation procedure, phase change model + $:GPU_DECLARE(create='[relax, relax_model, palpha_eps, ptgalpha_eps]') - integer :: num_bc_patches - logical :: bc_io + integer :: num_bc_patches + logical :: bc_io + logical, dimension(3) :: periodic_bc !> @name Boundary conditions (BC) in the x-, y- and z-directions, respectively !> @{ type(int_bounds_info) :: bc_x, bc_y, bc_z @@ -221,18 +229,27 @@ module m_global_parameters #elif defined(MFC_OpenMP) $:GPU_DECLARE(create='[bc_x, bc_y, bc_z]') #endif - type(bounds_info) :: x_domain, y_domain, z_domain - $:GPU_DECLARE(create='[x_domain, y_domain, z_domain]') - real(wp) :: x_a, y_a, z_a - real(wp) :: x_b, y_b, z_b - logical :: parallel_io !< Format of the data files - logical :: file_per_process !< shared file or not when using parallel io - integer :: precision !< Precision of output files - logical :: down_sample !< down sample the output files + + logical :: parallel_io !< Format of the data files + logical :: file_per_process !< shared file or not when using parallel io + integer :: precision !< Precision of output files + logical :: down_sample !< down sample the output files $:GPU_DECLARE(create='[down_sample]') - integer, allocatable, dimension(:) :: proc_coords !< Processor coordinates in MPI_CART_COMM - integer, allocatable, dimension(:) :: start_idx !< Starting cell-center index of local processor in global grid + integer, allocatable, dimension(:) :: proc_coords !< Processor coordinates in MPI_CART_COMM + type(bounds_info), allocatable, dimension(:) :: pcomm_coords + $:GPU_DECLARE(create='[pcomm_coords]') + !! Coordinates for EL particle transfer + + type(bounds_info), allocatable, dimension(:) :: pcomm_coords_ghost + $:GPU_DECLARE(create='[pcomm_coords_ghost]') + !! Coordinates for EL particle transfer + + type(int_bounds_info), dimension(3) :: nidx !< Indices for neighboring processors + integer, allocatable, dimension(:,:,:) :: neighbor_ranks + !! Neighbor ranks + + integer, allocatable, dimension(:) :: start_idx !< Starting cell-center index of local processor in global grid type(mpi_io_var), public :: MPI_IO_DATA type(mpi_io_ib_var), public :: MPI_IO_IB_DATA type(mpi_io_airfoil_ib_var), public :: MPI_IO_airfoil_IB_DATA @@ -293,7 +310,9 @@ module m_global_parameters $:GPU_DECLARE(create='[Re_size, Re_size_max, Re_idx]') - ! WENO averaging flag: use arithmetic mean or unaltered WENO-reconstructed cell-boundary values + ! The WENO average (WA) flag regulates whether the calculation of any cell- average spatial derivatives is carried out in each + ! cell by utilizing the arithmetic mean of the left and right, WENO-reconstructed, cell-boundary values or simply, the unaltered + ! left and right, WENO-reconstructed, cell- boundary values. !> @{ real(wp) :: wa_flg !> @} @@ -311,24 +330,46 @@ module m_global_parameters $:GPU_DECLARE(create='[dir_idx, dir_flg, dir_idx_tau]') + !> The number of cells that are necessary to be able to store enough boundary conditions data to march the solution in the + !! physical computational domain to the next time-step. integer :: buff_size !< Number of ghost cells for boundary condition storage + $:GPU_DECLARE(create='[buff_size]') - integer :: shear_num !< Number of shear stress components - integer, dimension(3) :: shear_indices !< Indices of the stress components that represent shear stress - integer :: shear_BC_flip_num !< Number of shear stress components to reflect for boundary conditions + integer, allocatable :: beta_vars(:) !< Indices of variables to communicate for bubble/particle coupling + + $:GPU_DECLARE(create='[beta_vars]') + + integer :: shear_num !< Number of shear stress components + integer, dimension(3) :: shear_indices !< Indices of the stress components that represent shear stress + integer :: shear_BC_flip_num !< Number of shear stress components to reflect for boundary conditions + !> Indices of shear stress components to reflect for boundary conditions. Size: (1:3, 1:shear_BC_flip_num) for (x/y/z, + !! [indices]) integer, dimension(3, 2) :: shear_BC_flip_indices !< Shear stress BC reflection indices (1:3, 1:shear_BC_flip_num) + $:GPU_DECLARE(create='[shear_num, shear_indices, shear_BC_flip_num, shear_BC_flip_indices]') ! END: Simulation Algorithm Parameters ! Fluids Physical Parameters + !> Database of the physical parameters of each of the fluids that is present in the flow. These include the stiffened gas + !! equation of state parameters, and the Reynolds numbers. type(physical_parameters), dimension(num_fluids_max) :: fluid_pp !< Stiffened gas EOS parameters and Reynolds numbers per fluid + ! Subgrid Bubble Parameters type(subgrid_bubble_physical_parameters) :: bub_pp - integer :: fd_order !< Finite-difference order for CoM and flow probe derivatives - integer :: fd_number !< Finite-difference half-stencil size: MAX(1, fd_order/2) + + ! Subgrid Particle Parameters + type(subgrid_particle_physical_parameters) :: particle_pp + + !> The order of the finite-difference (fd) approximations of the first-order derivatives that need to be evaluated when the CoM + !! or flow probe data files are to be written at each time step + integer :: fd_order !< Finite-difference order for CoM and flow probe derivatives + + !> The finite-difference number is given by MAX(1, fd_order/2). Essentially, it is a measure of the half-size of the + !! finite-difference stencil for the selected order of accuracy. + integer :: fd_number !< Finite-difference half-stencil size: MAX(1, fd_order/2) $:GPU_DECLARE(create='[fd_order, fd_number]') logical :: probe_wrt @@ -352,6 +393,9 @@ module m_global_parameters type(ib_patch_parameters), dimension(num_patches_max) :: patch_ib !< Immersed boundary patch parameters type(vec3_dt), allocatable, dimension(:) :: airfoil_grid_u, airfoil_grid_l integer :: Np + !! Database of the immersed boundary patch parameters for each of the patches employed in the configuration of the initial + !! condition. Note that the maximum allowable number of patches, num_patches_max, may be changed in the module + !! m_derived_types.f90. $:GPU_DECLARE(create='[ib, num_ibs, patch_ib, Np, airfoil_grid_u, airfoil_grid_l]') !> @} @@ -429,6 +473,12 @@ module m_global_parameters $:GPU_DECLARE(create='[R0ref, p0ref, rho0ref, T0ref, ss, pv, vd, mu_l, mu_v, mu_g, gam_v, gam_g, M_v, M_g, cp_v, cp_g, R_v, R_g]') !> @} + !> @name Solid particle physical parameters + !> @{ + real(wp) :: cp_particle, rho0ref_particle + $:GPU_DECLARE(create='[rho0ref_particle, cp_particle]') + !> @} + !> @name Acoustic acoustic_source parameters !> @{ logical :: acoustic_source !< Acoustic source switch @@ -470,16 +520,31 @@ module m_global_parameters !> @name lagrangian subgrid bubble parameters !> @{! - logical :: bubbles_lagrange !< Lagrangian subgrid bubble model switch - type(bubbles_lagrange_parameters) :: lag_params !< Lagrange bubbles' parameters - $:GPU_DECLARE(create='[bubbles_lagrange, lag_params]') + logical :: bubbles_lagrange !< Lagrangian subgrid bubble model switch + logical :: particles_lagrange !< Lagrangian subgrid particle model switch + type(bubbles_lagrange_parameters) :: lag_params !< Lagrange bubbles' parameters + integer :: n_el_bubs_loc, n_el_bubs_glb !< Number of Lagrangian bubbles (local and global) + integer :: n_el_particles_loc, n_el_particles_glb !< Number of Lagrangian bubbles (local and global) + logical :: moving_lag_bubbles + logical :: moving_lag_particles + logical :: lag_pressure_force + logical :: lag_gravity_force + integer :: lag_vel_model, lag_drag_model + $:GPU_DECLARE(create='[bubbles_lagrange, lag_params, n_el_bubs_loc, n_el_bubs_glb]') + $:GPU_DECLARE(create='[particles_lagrange, n_el_particles_loc, n_el_particles_glb]') + $:GPU_DECLARE(create='[moving_lag_particles]') + $:GPU_DECLARE(create='[moving_lag_bubbles, lag_vel_model, lag_drag_model]') + $:GPU_DECLARE(create='[lag_pressure_force, lag_gravity_force]') !> @} real(wp) :: Bx0 !< Constant magnetic field in the x-direction (1D) $:GPU_DECLARE(create='[Bx0]') logical :: fft_wrt + !> AMDFlang workaround: keep a dummy logical to avoid a compiler case-optimization bug when a parameter+GPU-kernel conditional + !! is false logical :: dummy !< AMDFlang workaround for case-optimization + GPU-kernel bug + !> @name Continuum damage model parameters !> @{! real(wp) :: tau_star !< Stress threshold for continuum damage modeling @@ -502,6 +567,7 @@ contains impure subroutine s_assign_default_values_to_user_inputs integer :: i, j !< Generic loop iterator + ! Logistics case_dir = '.' @@ -596,6 +662,7 @@ contains num_bc_patches = 0 bc_io = .false. + periodic_bc = .false. bc_x%beg = dflt_int; bc_x%end = dflt_int bc_y%beg = dflt_int; bc_y%end = dflt_int @@ -608,9 +675,9 @@ contains #:endfor #:endfor - x_domain%beg = dflt_real; x_domain%end = dflt_real - y_domain%beg = dflt_real; y_domain%end = dflt_real - z_domain%beg = dflt_real; z_domain%end = dflt_real + glb_bounds(1)%beg = dflt_real; glb_bounds(1)%end = dflt_real + glb_bounds(2)%beg = dflt_real; glb_bounds(2)%end = dflt_real + glb_bounds(3)%beg = dflt_real; glb_bounds(3)%end = dflt_real ! Fluids physical parameters do i = 1, num_fluids_max @@ -645,6 +712,10 @@ contains bub_pp%R_v = dflt_real; R_v = dflt_real bub_pp%R_g = dflt_real; R_g = dflt_real + ! Subgrid particle parameters + particle_pp%rho0ref_particle = dflt_real + particle_pp%cp_particle = dflt_real + ! Tait EOS rhoref = dflt_real pref = dflt_real @@ -774,10 +845,29 @@ contains lag_params%massTransfer_model = .false. lag_params%write_bubbles = .false. lag_params%write_bubbles_stats = .false. + lag_params%write_void_evol = .false. lag_params%nBubs_glb = dflt_int + lag_params%vel_model = dflt_int + lag_params%drag_model = dflt_int + lag_params%pressure_force = .true. + lag_params%gravity_force = .false. lag_params%epsilonb = 1._wp lag_params%charwidth = dflt_real + lag_params%charNz = dflt_int lag_params%valmaxvoid = dflt_real + lag_params%input_path = 'input/lag_bubbles.dat' + lag_params%nParticles_glb = dflt_int + lag_params%qs_drag_model = dflt_int + lag_params%stokes_drag = dflt_int + lag_params%added_mass_model = dflt_int + lag_params%interpolation_order = dflt_int + lag_params%collision_force = .false. + + moving_lag_bubbles = .false. + lag_vel_model = dflt_int + + particles_lagrange = .false. + moving_lag_particles = .false. ! Continuum damage model tau_star = dflt_real @@ -837,7 +927,8 @@ contains end subroutine s_assign_default_values_to_user_inputs - !> Initialize the global parameters module + !> The computation of parameters, the allocation of memory, the association of pointers and/or the execution of any other + !! procedures that are necessary to setup the module. impure subroutine s_initialize_global_parameters_module integer :: i, j, k @@ -845,7 +936,6 @@ contains #:if not MFC_CASE_OPTIMIZATION ! Determining the degree of the WENO polynomials - if (recon_type == WENO_TYPE) then weno_polyn = (weno_order - 1)/2 if (teno) then @@ -863,7 +953,9 @@ contains $:GPU_UPDATE(device='[igr, igr_order, igr_iter_solver]') #:endif - ! Initialize counts: viscous fluids, surface-tension interfaces, curvature interfaces + ! Initializing the number of fluids for which viscous effects will be non-negligible, the number of distinctive material + ! interfaces for which surface tension will be important and also, the number of fluids for which the physical and geometric + ! curvatures of the interfaces will be computed Re_size = 0 Re_size_max = 0 @@ -894,7 +986,9 @@ contains E_idx = mom_idx%end + 1 if (igr) then - ! IGR: volume fractions after energy (N-1 for N fluids; skipped when num_fluids=1) + ! Volume fractions are stored in the indices immediately following the energy equation. IGR tracks a total of + ! (N-1) volume fractions for N fluids, hence the "-1" in adv_idx%end. If num_fluids = 1 then adv_idx%end < + ! adv_idx%beg, which skips all loops over the volume fractions since there is no volume fraction to track adv_idx%beg = E_idx + 1 ! Alpha for fluid 1 adv_idx%end = E_idx + num_fluids - 1 else @@ -1029,7 +1123,8 @@ contains end if end if - ! Count fluids with non-negligible viscous effects (Re > 0) + ! Determining the number of fluids for which the shear and the volume Reynolds numbers, e.g. viscous effects, are + ! important do i = 1, num_fluids if (fluid_pp(i)%Re(1) > 0) Re_size(1) = Re_size(1) + 1 if (fluid_pp(i)%Re(2) > 0) Re_size(2) = Re_size(2) + 1 @@ -1122,6 +1217,16 @@ contains ! END: Volume Fraction Model + if (bubbles_lagrange) then + @:ALLOCATE(beta_vars(1:3)) + beta_vars(1:3) = [1, 2, 5] + $:GPU_UPDATE(device='[beta_vars]') + else if (particles_lagrange) then + @:ALLOCATE(beta_vars(1:8)) + beta_vars(1:8) = [1, 2, 3, 4, 5, 6, 7, 8] + $:GPU_UPDATE(device='[beta_vars]') + end if + if (chemistry) then species_idx%beg = sys_size + 1 species_idx%end = sys_size + num_species @@ -1134,6 +1239,9 @@ contains else if (bubbles_lagrange) then allocate (MPI_IO_DATA%view(1:sys_size + 1)) allocate (MPI_IO_DATA%var(1:sys_size + 1)) + else if (particles_lagrange) then + allocate (MPI_IO_DATA%view(1:sys_size + 1)) + allocate (MPI_IO_DATA%var(1:sys_size + 1)) else allocate (MPI_IO_DATA%view(1:sys_size)) allocate (MPI_IO_DATA%var(1:sys_size)) @@ -1155,9 +1263,16 @@ contains allocate (MPI_IO_DATA%var(i)%sf(0:m,0:n,0:p)) MPI_IO_DATA%var(i)%sf => null() end do + else if (particles_lagrange) then + do i = 1, sys_size + 1 + allocate (MPI_IO_DATA%var(i)%sf(0:m,0:n,0:p)) + MPI_IO_DATA%var(i)%sf => null() + end do end if - ! Configure WENO averaging flag (arithmetic mean vs. unaltered values) + ! Configuring the WENO average flag that will be used to regulate whether any spatial derivatives are to computed in each + ! cell by using the arithmetic mean of left and right, WENO-reconstructed, cell-boundary values or otherwise, the unaltered + ! left and right, WENO-reconstructed, cell-boundary values wa_flg = 0._wp; if (weno_avg) wa_flg = 1._wp $:GPU_UPDATE(device='[wa_flg]') @@ -1169,20 +1284,16 @@ contains if (ib) allocate (MPI_IO_IB_DATA%var%sf(0:m,0:n,0:p)) Np = 0 - if (elasticity) then - fd_number = max(1, fd_order/2) - end if - + if (elasticity) fd_number = max(1, fd_order/2) if (mhd) then ! TODO merge with above; waiting for hyperelasticity PR fd_number = max(1, fd_order/2) end if - - if (probe_wrt) then - fd_number = max(1, fd_order/2) - end if + if (probe_wrt) fd_number = max(1, fd_order/2) + if (bubbles_lagrange) fd_number = max(1, fd_order/2) + if (particles_lagrange) fd_number = max(1, fd_order/2) call s_configure_coordinate_bounds(recon_type, weno_polyn, muscl_polyn, igr_order, buff_size, idwint, idwbuff, viscous, & - & bubbles_lagrange, m, n, p, num_dims, igr, ib) + & bubbles_lagrange, particles_lagrange, m, n, p, num_dims, igr, ib, fd_number) $:GPU_UPDATE(device='[idwint, idwbuff]') ! Configuring Coordinate Direction Indexes @@ -1295,6 +1406,8 @@ contains #:endif allocate (proc_coords(1:num_dims)) + @:ALLOCATE(pcomm_coords(1:num_dims)) + @:ALLOCATE(pcomm_coords_ghost(1:num_dims)) if (parallel_io .neqv. .true.) return @@ -1327,6 +1440,14 @@ contains end if deallocate (proc_coords) + + @:DEALLOCATE(pcomm_coords) + @:DEALLOCATE(pcomm_coords_ghost) + + if (bubbles_lagrange .or. particles_lagrange) then + @:DEALLOCATE(beta_vars) + end if + if (parallel_io) then deallocate (start_idx) @@ -1334,6 +1455,10 @@ contains do i = 1, sys_size + 1 MPI_IO_DATA%var(i)%sf => null() end do + else if (particles_lagrange) then + do i = 1, sys_size + 1 + MPI_IO_DATA%var(i)%sf => null() + end do else do i = 1, sys_size MPI_IO_DATA%var(i)%sf => null() @@ -1355,6 +1480,10 @@ contains if (p == 0) return @:DEALLOCATE(z_cb, z_cc, dz) + if (allocated(neighbor_ranks)) then + @:DEALLOCATE(neighbor_ranks) + end if + end subroutine s_finalize_global_parameters_module end module m_global_parameters diff --git a/src/simulation/m_ib_patches.fpp b/src/simulation/m_ib_patches.fpp index a7d8e45eee..41aeffec30 100644 --- a/src/simulation/m_ib_patches.fpp +++ b/src/simulation/m_ib_patches.fpp @@ -32,26 +32,26 @@ module m_ib_patches integer :: smooth_patch_id real(wp) :: smooth_coeff $:GPU_DECLARE(create='[smooth_patch_id, smooth_coeff]') - ! These variables are analogous in both meaning and use to the similarly named components in the ic_patch_parameters type (see - ! m_derived_types.f90 for additional details). They are employed as a means to more concisely perform the actions necessary to - ! lay out a particular patch on the grid. + !! These variables are analogous in both meaning and use to the similarly named components in the ic_patch_parameters type (see + !! m_derived_types.f90 for additional details). They are employed as a means to more concisely perform the actions necessary to + !! lay out a particular patch on the grid. real(wp) :: cart_x, cart_y, cart_z real(wp) :: sph_phi $:GPU_DECLARE(create='[cart_x, cart_y, cart_z, sph_phi]') - ! Variables to be used to hold cell locations in Cartesian coordinates if 3D simulation is using cylindrical coordinates + !! Variables to be used to hold cell locations in Cartesian coordinates if 3D simulation is using cylindrical coordinates type(bounds_info) :: x_boundary, y_boundary, z_boundary $:GPU_DECLARE(create='[x_boundary, y_boundary, z_boundary]') - ! These variables combine the centroid and length parameters associated with a particular patch to yield the locations of the - ! patch boundaries in the x-, y- and z-coordinate directions. They are used as a means to concisely perform the actions - ! necessary to lay out a particular patch on the grid. + !! These variables combine the centroid and length parameters associated with a particular patch to yield the locations of the + !! patch boundaries in the x-, y- and z-coordinate directions. They are used as a means to concisely perform the actions + !! necessary to lay out a particular patch on the grid. character(len=5) :: istr !< string to store int to string result for error checking contains - !> Apply all immersed boundary patch geometries to mark interior cells in the IB marker array + !> @brief Applies all immersed boundary patch geometries to mark interior cells in the IB marker array. impure subroutine s_apply_ib_patches(ib_markers) type(integer_field), intent(inout) :: ib_markers @@ -112,7 +112,12 @@ contains end subroutine s_apply_ib_patches - !> Mark cells inside a circular immersed boundary + !> The circular patch is a 2D geometry that may be used, for example, in creating a bubble or a droplet. The geometry of the + !! patch is well-defined when its centroid and radius are provided. Note that the circular patch DOES allow for the smoothing of + !! its boundary. + !! @param patch_id is the patch identifier + !! @param ib_markers Array to track patch ids + !! @param ib True if this patch is an immersed boundary subroutine s_ib_circle(patch_id, ib_markers, xp, yp) integer, intent(in) :: patch_id @@ -125,8 +130,8 @@ contains ! Transferring the circular patch's radius, centroid, smearing patch identity and smearing coefficient information - center(1) = patch_ib(patch_id)%x_centroid + real(xp, wp)*(x_domain%end - x_domain%beg) - center(2) = patch_ib(patch_id)%y_centroid + real(yp, wp)*(y_domain%end - y_domain%beg) + center(1) = patch_ib(patch_id)%x_centroid + real(xp, wp)*(glb_bounds(1)%end - glb_bounds(1)%beg) + center(2) = patch_ib(patch_id)%y_centroid + real(yp, wp)*(glb_bounds(2)%end - glb_bounds(2)%beg) radius = patch_ib(patch_id)%radius ! encode the periodicity information into the patch_id @@ -140,7 +145,8 @@ contains call get_bounding_indices(center(1) - radius, center(1) + radius, x_cc, il, ir) call get_bounding_indices(center(2) - radius, center(2) + radius, y_cc, jl, jr) - ! Assign primitive variables if circle covers cell and patch has write permission + ! Checking whether the circle covers a particular cell in the domain and verifying whether the current patch has permission + ! to write to that cell. If both queries check out, the primitive variables of the current patch are assigned to this cell. $:GPU_PARALLEL_LOOP(private='[i, j]', copyin='[encoded_patch_id, center, radius]', collapse=2) do j = jl, jr @@ -154,7 +160,9 @@ contains end subroutine s_ib_circle - !> Mark cells inside a 2D NACA 4-digit airfoil immersed boundary + !> @brief Marks cells inside a 2D NACA 4-digit airfoil immersed boundary using upper and lower surface grids. + !! @param patch_id is the patch identifier + !! @param ib_markers Array to track patch ids subroutine s_ib_airfoil(patch_id, ib_markers, xp, yp) integer, intent(in) :: patch_id @@ -169,8 +177,8 @@ contains real(wp), dimension(1:2) :: center !< x and y coordinates in local IB frame real(wp), dimension(1:3,1:3) :: inverse_rotation - center(1) = patch_ib(patch_id)%x_centroid + real(xp, wp)*(x_domain%end - x_domain%beg) - center(2) = patch_ib(patch_id)%y_centroid + real(yp, wp)*(y_domain%end - y_domain%beg) + center(1) = patch_ib(patch_id)%x_centroid + real(xp, wp)*(glb_bounds(1)%end - glb_bounds(1)%beg) + center(2) = patch_ib(patch_id)%y_centroid + real(yp, wp)*(glb_bounds(2)%end - glb_bounds(2)%beg) ca_in = patch_ib(patch_id)%c pa = patch_ib(patch_id)%p ma = patch_ib(patch_id)%m @@ -187,7 +195,7 @@ contains @:ALLOCATE(airfoil_grid_u(1:Np)) @:ALLOCATE(airfoil_grid_l(1:Np)) - ! TODO :: The below instantiations are already handled by the loop below + ! TODO :: The below instantiations are already handles by the loop below airfoil_grid_u(1)%x = 0._wp airfoil_grid_u(1)%y = 0._wp @@ -195,7 +203,7 @@ contains airfoil_grid_l(1)%y = 0._wp do i = 1, Np1 + Np2 - 1 - ! TODO :: This allocates the upper and lower airfoil arrays, and does not need to be performed each time the IB + ! TODO :: This allocated the upper and lower airfoil arrays, and does not need to be performed each time the IB ! markers are updated. Place this as a separate subroutine. if (i <= Np1) then xc = i*(pa*ca_in/Np1) @@ -277,11 +285,13 @@ contains end do if (f_approx_equal(airfoil_grid_u(k)%x, xy_local(1))) then if (xy_local(2) <= airfoil_grid_u(k)%y) then + !!IB ib_markers%sf(i, j, 0) = encoded_patch_id end if else f = (airfoil_grid_u(k)%x - xy_local(1))/(airfoil_grid_u(k)%x - airfoil_grid_u(k - 1)%x) if (xy_local(2) <= ((1._wp - f)*airfoil_grid_u(k)%y + f*airfoil_grid_u(k - 1)%y)) then + !!IB ib_markers%sf(i, j, 0) = encoded_patch_id end if end if @@ -292,12 +302,14 @@ contains end do if (f_approx_equal(airfoil_grid_l(k)%x, xy_local(1))) then if (xy_local(2) >= airfoil_grid_l(k)%y) then + !!IB ib_markers%sf(i, j, 0) = encoded_patch_id end if else f = (airfoil_grid_l(k)%x - xy_local(1))/(airfoil_grid_l(k)%x - airfoil_grid_l(k - 1)%x) if (xy_local(2) >= ((1._wp - f)*airfoil_grid_l(k)%y + f*airfoil_grid_l(k - 1)%y)) then + !!IB ib_markers%sf(i, j, 0) = encoded_patch_id end if end if @@ -309,7 +321,10 @@ contains end subroutine s_ib_airfoil - !> Mark cells inside a 3D extruded NACA 4-digit airfoil immersed boundary with finite span + !> @brief Marks cells inside a 3D extruded NACA 4-digit airfoil immersed boundary with finite span. + !! @param patch_id is the patch identifier + !! @param ib_markers Array to track patch ids + !! @param ib True if this patch is an immersed boundary subroutine s_ib_3D_airfoil(patch_id, ib_markers, xp, yp, zp) integer, intent(in) :: patch_id @@ -322,9 +337,9 @@ contains real(wp), dimension(1:3) :: xyz_local, center, offset !< x, y, z coordinates in local IB frame real(wp), dimension(1:3,1:3) :: inverse_rotation - center(1) = patch_ib(patch_id)%x_centroid + real(xp, wp)*(x_domain%end - x_domain%beg) - center(2) = patch_ib(patch_id)%y_centroid + real(yp, wp)*(y_domain%end - y_domain%beg) - center(3) = patch_ib(patch_id)%z_centroid + real(zp, wp)*(z_domain%end - z_domain%beg) + center(1) = patch_ib(patch_id)%x_centroid + real(xp, wp)*(glb_bounds(1)%end - glb_bounds(1)%beg) + center(2) = patch_ib(patch_id)%y_centroid + real(yp, wp)*(glb_bounds(2)%end - glb_bounds(2)%beg) + center(3) = patch_ib(patch_id)%z_centroid + real(zp, wp)*(glb_bounds(3)%end - glb_bounds(3)%beg) lz = patch_ib(patch_id)%length_z ca_in = patch_ib(patch_id)%c pa = patch_ib(patch_id)%p @@ -436,6 +451,7 @@ contains else f = (airfoil_grid_u(k)%x - xyz_local(1))/(airfoil_grid_u(k)%x - airfoil_grid_u(k - 1)%x) if (xyz_local(2) <= ((1._wp - f)*airfoil_grid_u(k)%y + f*airfoil_grid_u(k - 1)%y)) then + !!IB ib_markers%sf(i, j, l) = encoded_patch_id end if end if @@ -446,12 +462,14 @@ contains end do if (f_approx_equal(airfoil_grid_l(k)%x, xyz_local(1))) then if (xyz_local(2) >= airfoil_grid_l(k)%y) then + !!IB ib_markers%sf(i, j, l) = encoded_patch_id end if else f = (airfoil_grid_l(k)%x - xyz_local(1))/(airfoil_grid_l(k)%x - airfoil_grid_l(k - 1)%x) if (xyz_local(2) >= ((1._wp - f)*airfoil_grid_l(k)%y + f*airfoil_grid_l(k - 1)%y)) then + !!IB ib_markers%sf(i, j, l) = encoded_patch_id end if end if @@ -465,7 +483,13 @@ contains end subroutine s_ib_3D_airfoil - !> Mark cells inside a rectangular immersed boundary + !> The rectangular patch is a 2D geometry that may be used, for example, in creating a solid boundary, or pre-/post- shock + !! region, in alignment with the axes of the Cartesian coordinate system. The geometry of such a patch is well- defined when its + !! centroid and lengths in the x- and y- coordinate directions are provided. Please note that the rectangular patch DOES NOT + !! allow for the smoothing of its boundaries. + !! @param patch_id is the patch identifier + !! @param ib_markers Array to track patch ids + !! @param ib True if this patch is an immersed boundary subroutine s_ib_rectangle(patch_id, ib_markers, xp, yp) integer, intent(in) :: patch_id @@ -480,8 +504,8 @@ contains ! Transferring the rectangle's centroid and length information - center(1) = patch_ib(patch_id)%x_centroid + real(xp, wp)*(x_domain%end - x_domain%beg) - center(2) = patch_ib(patch_id)%y_centroid + real(yp, wp)*(y_domain%end - y_domain%beg) + center(1) = patch_ib(patch_id)%x_centroid + real(xp, wp)*(glb_bounds(1)%end - glb_bounds(1)%beg) + center(2) = patch_ib(patch_id)%y_centroid + real(yp, wp)*(glb_bounds(2)%end - glb_bounds(2)%beg) length(1) = patch_ib(patch_id)%length_x length(2) = patch_ib(patch_id)%length_y inverse_rotation(:,:) = patch_ib(patch_id)%rotation_matrix_inverse(:,:) @@ -498,7 +522,9 @@ contains call get_bounding_indices(center(1) - corner_distance, center(1) + corner_distance, x_cc, il, ir) call get_bounding_indices(center(2) - corner_distance, center(2) + corner_distance, y_cc, jl, jr) - ! Assign primitive variables if rectangle covers cell and patch has write permission + ! Checking whether the rectangle covers a particular cell in the domain and verifying whether the current patch has the + ! permission to write to that cell. If both queries check out, the primitive variables of the current patch are assigned to + ! this cell. $:GPU_PARALLEL_LOOP(private='[i, j, xy_local]', copyin='[encoded_patch_id, center, length, inverse_rotation, x_cc, & & y_cc]', collapse=2) do j = jl, jr @@ -518,12 +544,18 @@ contains end subroutine s_ib_rectangle - !> Mark cells inside a spherical immersed boundary + !> The spherical patch is a 3D geometry that may be used, for example, in creating a bubble or a droplet. The patch geometry is + !! well-defined when its centroid and radius are provided. Please note that the spherical patch DOES allow for the smoothing of + !! its boundary. + !! @param patch_id is the patch identifier + !! @param ib_markers Array to track patch ids + !! @param ib True if this patch is an immersed boundary subroutine s_ib_sphere(patch_id, ib_markers, xp, yp, zp) integer, intent(in) :: patch_id type(integer_field), intent(inout) :: ib_markers integer, intent(in) :: xp, yp, zp !< integers containing the periodicity projection information + ! Generic loop iterators integer :: i, j, k integer :: il, ir, jl, jr, kl, kr @@ -531,13 +563,14 @@ contains real(wp) :: radius real(wp), dimension(1:3) :: center - ! Variables to initialize the pressure field that corresponds to the bubble-collapse test case found in Tiwari et al. (2013) + !! Variables to initialize the pressure field that corresponds to the bubble-collapse test case found in Tiwari et al. + !! (2013) ! Transferring spherical patch's radius, centroid, smoothing patch identity and smoothing coefficient information - center(1) = patch_ib(patch_id)%x_centroid + real(xp, wp)*(x_domain%end - x_domain%beg) - center(2) = patch_ib(patch_id)%y_centroid + real(yp, wp)*(y_domain%end - y_domain%beg) - center(3) = patch_ib(patch_id)%z_centroid + real(zp, wp)*(z_domain%end - z_domain%beg) + center(1) = patch_ib(patch_id)%x_centroid + real(xp, wp)*(glb_bounds(1)%end - glb_bounds(1)%beg) + center(2) = patch_ib(patch_id)%y_centroid + real(yp, wp)*(glb_bounds(2)%end - glb_bounds(2)%beg) + center(3) = patch_ib(patch_id)%z_centroid + real(zp, wp)*(glb_bounds(3)%end - glb_bounds(3)%beg) radius = patch_ib(patch_id)%radius ! encode the periodicity information into the patch_id @@ -560,6 +593,7 @@ contains do k = kl, kr do j = jl, jr do i = il, ir + ! do i = -gp_layers, m+gp_layers if (grid_geometry == 3) then call s_convert_cylindrical_to_cartesian_coord(y_cc(j), z_cc(k)) else @@ -577,7 +611,12 @@ contains end subroutine s_ib_sphere - !> Mark cells inside a cuboidal immersed boundary + !> The cuboidal patch is a 3D geometry that may be used, for example, in creating a solid boundary, or pre-/post-shock region, + !! which is aligned with the axes of the Cartesian coordinate system. The geometry of such a patch is well- defined when its + !! centroid and lengths in the x-, y- and z-coordinate directions are provided. Please notice that the cuboidal patch DOES NOT + !! allow for the smearing of its boundaries. + !! @param patch_id is the patch identifier + !! @param ib_markers Array to track patch ids subroutine s_ib_cuboid(patch_id, ib_markers, xp, yp, zp) integer, intent(in) :: patch_id @@ -591,9 +630,9 @@ contains ! Transferring the cuboid's centroid and length information - center(1) = patch_ib(patch_id)%x_centroid + real(xp, wp)*(x_domain%end - x_domain%beg) - center(2) = patch_ib(patch_id)%y_centroid + real(yp, wp)*(y_domain%end - y_domain%beg) - center(3) = patch_ib(patch_id)%z_centroid + real(zp, wp)*(z_domain%end - z_domain%beg) + center(1) = patch_ib(patch_id)%x_centroid + real(xp, wp)*(glb_bounds(1)%end - glb_bounds(1)%beg) + center(2) = patch_ib(patch_id)%y_centroid + real(yp, wp)*(glb_bounds(2)%end - glb_bounds(2)%beg) + center(3) = patch_ib(patch_id)%z_centroid + real(zp, wp)*(glb_bounds(3)%end - glb_bounds(3)%beg) length(1) = patch_ib(patch_id)%length_x length(2) = patch_ib(patch_id)%length_y length(3) = patch_ib(patch_id)%length_z @@ -645,7 +684,13 @@ contains end subroutine s_ib_cuboid - !> Mark cells inside a cylindrical immersed boundary + !> The cylindrical patch is a 3D geometry that may be used, for example, in setting up a cylindrical solid boundary confinement, + !! like a blood vessel. The geometry of this patch is well-defined when the centroid, the radius and the length along the + !! cylinder's axis, parallel to the x-, y- or z-coordinate direction, are provided. Please note that the cylindrical patch DOES + !! allow for the smoothing of its lateral boundary. + !! @param patch_id is the patch identifier + !! @param ib_markers Array to track patch ids + !! @param ib True if this patch is an immersed boundary subroutine s_ib_cylinder(patch_id, ib_markers, xp, yp, zp) integer, intent(in) :: patch_id @@ -660,9 +705,9 @@ contains ! Transferring the cylindrical patch's centroid, length, radius, - center(1) = patch_ib(patch_id)%x_centroid + real(xp, wp)*(x_domain%end - x_domain%beg) - center(2) = patch_ib(patch_id)%y_centroid + real(yp, wp)*(y_domain%end - y_domain%beg) - center(3) = patch_ib(patch_id)%z_centroid + real(zp, wp)*(z_domain%end - z_domain%beg) + center(1) = patch_ib(patch_id)%x_centroid + real(xp, wp)*(glb_bounds(1)%end - glb_bounds(1)%beg) + center(2) = patch_ib(patch_id)%y_centroid + real(yp, wp)*(glb_bounds(2)%end - glb_bounds(2)%beg) + center(3) = patch_ib(patch_id)%z_centroid + real(zp, wp)*(glb_bounds(3)%end - glb_bounds(3)%beg) length(1) = patch_ib(patch_id)%length_x length(2) = patch_ib(patch_id)%length_y length(3) = patch_ib(patch_id)%length_z @@ -716,7 +761,7 @@ contains end subroutine s_ib_cylinder - !> Mark cells inside a 2D elliptical immersed boundary + !> @brief Marks cells inside a 2D elliptical immersed boundary defined by semi-axis lengths and rotation. subroutine s_ib_ellipse(patch_id, ib_markers, xp, yp) integer, intent(in) :: patch_id @@ -731,8 +776,8 @@ contains ! Transferring the ellipse's centroid and length information - center(1) = patch_ib(patch_id)%x_centroid + real(xp, wp)*(x_domain%end - x_domain%beg) - center(2) = patch_ib(patch_id)%y_centroid + real(yp, wp)*(y_domain%end - y_domain%beg) + center(1) = patch_ib(patch_id)%x_centroid + real(xp, wp)*(glb_bounds(1)%end - glb_bounds(1)%beg) + center(2) = patch_ib(patch_id)%y_centroid + real(yp, wp)*(glb_bounds(2)%end - glb_bounds(2)%beg) ellipse_coeffs(1) = 0.5_wp*patch_ib(patch_id)%length_x ellipse_coeffs(2) = 0.5_wp*patch_ib(patch_id)%length_y inverse_rotation(:,:) = patch_ib(patch_id)%rotation_matrix_inverse(:,:) @@ -769,6 +814,8 @@ contains end subroutine s_ib_ellipse !> The STL patch is a 2D geometry that is imported from an STL file. + !! @param patch_id is the patch identifier + !! @param ib_markers Array to track patch ids subroutine s_ib_model(patch_id, ib_markers, xp, yp) integer, intent(in) :: patch_id @@ -786,8 +833,8 @@ contains real(wp), dimension(1:3,1:3) :: inverse_rotation, rotation center = 0._wp - center(1) = patch_ib(patch_id)%x_centroid + real(xp, wp)*(x_domain%end - x_domain%beg) - center(2) = patch_ib(patch_id)%y_centroid + real(yp, wp)*(y_domain%end - y_domain%beg) + center(1) = patch_ib(patch_id)%x_centroid + real(xp, wp)*(glb_bounds(1)%end - glb_bounds(1)%beg) + center(2) = patch_ib(patch_id)%y_centroid + real(yp, wp)*(glb_bounds(2)%end - glb_bounds(2)%beg) inverse_rotation(:,:) = patch_ib(patch_id)%rotation_matrix_inverse(:,:) rotation(:,:) = patch_ib(patch_id)%rotation_matrix(:,:) offset(:) = patch_ib(patch_id)%centroid_offset(:) @@ -846,6 +893,8 @@ contains end subroutine s_ib_model !> The STL patch is a 3D geometry that is imported from an STL file. + !! @param patch_id is the patch identifier + !! @param ib_markers Array to track patch ids subroutine s_ib_3d_model(patch_id, ib_markers, xp, yp, zp) integer, intent(in) :: patch_id @@ -862,9 +911,9 @@ contains real(wp), dimension(1:3) :: bbox_min, bbox_max, local_corner, world_corner center = 0._wp - center(1) = patch_ib(patch_id)%x_centroid + real(xp, wp)*(x_domain%end - x_domain%beg) - center(2) = patch_ib(patch_id)%y_centroid + real(yp, wp)*(y_domain%end - y_domain%beg) - center(3) = patch_ib(patch_id)%z_centroid + real(zp, wp)*(z_domain%end - z_domain%beg) + center(1) = patch_ib(patch_id)%x_centroid + real(xp, wp)*(glb_bounds(1)%end - glb_bounds(1)%beg) + center(2) = patch_ib(patch_id)%y_centroid + real(yp, wp)*(glb_bounds(2)%end - glb_bounds(2)%beg) + center(3) = patch_ib(patch_id)%z_centroid + real(zp, wp)*(glb_bounds(3)%end - glb_bounds(3)%beg) inverse_rotation(:,:) = patch_ib(patch_id)%rotation_matrix_inverse(:,:) offset(:) = patch_ib(patch_id)%centroid_offset(:) spc = patch_ib(patch_id)%model_spc @@ -932,7 +981,7 @@ contains end subroutine s_ib_3d_model - !> Compute a rotation matrix for converting to the rotating frame of the boundary + !> Subroutine that computes a rotation matrix for converting to the rotating frame of the boundary subroutine s_update_ib_rotation_matrix(patch_id) integer, intent(in) :: patch_id @@ -978,7 +1027,7 @@ contains end subroutine s_update_ib_rotation_matrix - !> Convert cylindrical (r, theta) coordinates to Cartesian (y, z) + !> @brief Converts cylindrical (r, theta) coordinates to Cartesian (y, z) and stores in module variables. subroutine s_convert_cylindrical_to_cartesian_coord(cyl_y, cyl_z) $:GPU_ROUTINE(parallelism='[seq]') @@ -990,7 +1039,7 @@ contains end subroutine s_convert_cylindrical_to_cartesian_coord - !> Convert a 3D cylindrical coordinate vector (x, r, theta) to Cartesian (x, y, z) + !> @brief Converts a 3D cylindrical coordinate vector (x, r, theta) to Cartesian (x, y, z). pure function f_convert_cyl_to_cart(cyl) result(cart) $:GPU_ROUTINE(parallelism='[seq]') @@ -1002,7 +1051,7 @@ contains end function f_convert_cyl_to_cart - !> Convert cylindrical coordinates (x, r) to the spherical azimuthal angle phi + !> @brief Converts cylindrical coordinates (x, r) to the spherical azimuthal angle phi and stores in a module variable. subroutine s_convert_cylindrical_to_spherical_coord(cyl_x, cyl_y) $:GPU_ROUTINE(parallelism='[seq]') @@ -1052,7 +1101,7 @@ contains end subroutine get_bounding_indices - !> Encode the patch ID with a unique offset containing periodicity information + !> @brief encodes the patch id with a unique offset that contains information on how the IB marker wraps periodically subroutine s_encode_patch_periodicity(patch_id, x_periodicity, y_periodicity, z_periodicity, encoded_patch_id) integer, intent(in) :: patch_id, x_periodicity, y_periodicity, z_periodicity @@ -1070,7 +1119,7 @@ contains end subroutine s_encode_patch_periodicity - !> Decode the encoded ID to recover the original patch ID and periodicity + !> @brief decodes the encoded id to get out the original id and the way in which it is periodic subroutine s_decode_patch_periodicity(encoded_patch_id, patch_id, x_periodicity, y_periodicity, z_periodicity) $:GPU_ROUTINE(parallelism='[seq]') @@ -1096,7 +1145,7 @@ contains end subroutine s_decode_patch_periodicity - !> Determine the periodic wrapping bounds in each direction + !> @brief Determines if we should wrap periodically subroutine s_get_periodicities(xp_lower, xp_upper, yp_lower, yp_upper, zp_lower, zp_upper) integer, intent(out) :: xp_lower, xp_upper, yp_lower, yp_upper @@ -1104,33 +1153,26 @@ contains ! check domain wraps in x, y - #:for X in [('x'), ('y')] - ! check for periodicity - - if (bc_${X}$%beg == BC_PERIODIC) then - ${X}$p_lower = -1 - ${X}$p_upper = 1 - else - ! if it is not periodic, then both elements are 0 - ${X}$p_lower = 0 - ${X}$p_upper = 0 + #:for X, ID in [('x', 1), ('y', 2), ('z', 3)] + if (num_dims >= ${ID}$) then + ! check for periodicity + if (bc_${X}$%beg == BC_PERIODIC) then + ${X}$p_lower = -1 + ${X}$p_upper = 1 + else + ! if it is not periodic, then both elements are 0 + ${X}$p_lower = 0 + ${X}$p_upper = 0 + end if end if #:endfor - ! z only if 3D - if (present(zp_lower) .and. p /= 0) then - if (bc_z%beg == BC_PERIODIC) then - zp_lower = -1 - zp_upper = 1 - else - zp_lower = 0 - zp_upper = 0 - end if - end if - end subroutine s_get_periodicities !> Archimedes spiral function + !! @param myth Angle + !! @param offset Thickness + !! @param a Starting position pure elemental function f_r(myth, offset, a) $:GPU_ROUTINE(parallelism='[seq]') diff --git a/src/simulation/m_ibm.fpp b/src/simulation/m_ibm.fpp index 785bf2dec3..2ed45357ed 100644 --- a/src/simulation/m_ibm.fpp +++ b/src/simulation/m_ibm.fpp @@ -79,10 +79,11 @@ contains $:GPU_UPDATE(device='[patch_ib(1:num_ibs)]') ! GPU routines require updated cell centers - $:GPU_UPDATE(device='[num_ibs, x_cc, y_cc, dx, dy, x_domain, y_domain]') + $:GPU_UPDATE(device='[num_ibs, x_cc, y_cc, dx, dy]') if (p /= 0) then - $:GPU_UPDATE(device='[z_cc, dz, z_domain]') + $:GPU_UPDATE(device='[z_cc, dz]') end if + $:GPU_UPDATE(device='[glb_bounds]') ! allocate STL models call s_instantiate_STL_models() @@ -164,7 +165,6 @@ contains type(ghost_point) :: innerp ! set the Moving IBM interior conservative variables - $:GPU_PARALLEL_LOOP(private='[i, j, k, patch_id, rho]', copyin='[E_idx, momxb]', collapse=3) do l = 0, p do k = 0, n @@ -243,7 +243,7 @@ contains ! Pressure correction for moving IB: accounts for acceleration of IB surface q_prim_vf(E_idx)%sf(j, k, l) = q_prim_vf(E_idx)%sf(j, k, & & l) + pres_IP/(1._wp - 2._wp*abs(gp%levelset*alpha_rho_IP(q)/pres_IP) & - & *dot_product(patch_ib(patch_id) %force/patch_ib(patch_id)%mass, gp%levelset_norm)) + & *dot_product(patch_ib(patch_id)%force/patch_ib(patch_id)%mass, gp%levelset_norm)) end do end if @@ -450,12 +450,12 @@ contains print *, [x_cc(i), y_cc(j), z_cc(k)] end if print *, "We are searching in dimension ", dim, " for image point at ", ghost_points_in(q)%ip_loc(:) - print *, "Domain size: ", [x_cc(-buff_size), y_cc(-buff_size), z_cc(-buff_size)] + print *, "Domain size: " print *, "x: ", x_cc(-buff_size), " to: ", x_cc(m + buff_size - 1) print *, "y: ", y_cc(-buff_size), " to: ", y_cc(n + buff_size - 1) if (p /= 0) print *, "z: ", z_cc(-buff_size), " to: ", z_cc(p + buff_size - 1) print *, "Image point is located approximately ", & - & (ghost_points_in(q)%loc(dim) - ghost_points_in(q) %ip_loc(dim))/(s_cc(1) - s_cc(0)), & + & (ghost_points_in(q)%loc(dim) - ghost_points_in(q)%ip_loc(dim))/(s_cc(1) - s_cc(0)), & & " grid cells away" print *, "Levelset ", dist, " and Norm: ", norm(:) print *, & @@ -541,8 +541,7 @@ contains if (p == 0) gp_layers_z = 0 $:GPU_PARALLEL_LOOP(private='[i, j, k, ii, jj, kk, is_gp, local_idx, patch_id, encoded_patch_id, xp, yp, zp]', & - & copyin='[count, count_i, x_domain, y_domain, z_domain]', firstprivate='[gp_layers, gp_layers_z]', & - & collapse=3) + & copyin='[count, count_i, glb_bounds]', firstprivate='[gp_layers, gp_layers_z]', collapse=3) do i = 0, m do j = 0, n do k = 0, p @@ -576,26 +575,26 @@ contains ghost_points_in(local_idx)%z_periodicity = zp ghost_points_in(local_idx)%slip = patch_ib(patch_id)%slip - if ((x_cc(i) - dx(i)) < x_domain%beg) then + if ((x_cc(i) - dx(i)) < glb_bounds(1)%beg) then ghost_points_in(local_idx)%DB(1) = -1 - else if ((x_cc(i) + dx(i)) > x_domain%end) then + else if ((x_cc(i) + dx(i)) > glb_bounds(1)%end) then ghost_points_in(local_idx)%DB(1) = 1 else ghost_points_in(local_idx)%DB(1) = 0 end if - if ((y_cc(j) - dy(j)) < y_domain%beg) then + if ((y_cc(j) - dy(j)) < glb_bounds(2)%beg) then ghost_points_in(local_idx)%DB(2) = -1 - else if ((y_cc(j) + dy(j)) > y_domain%end) then + else if ((y_cc(j) + dy(j)) > glb_bounds(2)%end) then ghost_points_in(local_idx)%DB(2) = 1 else ghost_points_in(local_idx)%DB(2) = 0 end if if (p /= 0) then - if ((z_cc(k) - dz(k)) < z_domain%beg) then + if ((z_cc(k) - dz(k)) < glb_bounds(3)%beg) then ghost_points_in(local_idx)%DB(3) = -1 - else if ((z_cc(k) + dz(k)) > z_domain%end) then + else if ((z_cc(k) + dz(k)) > glb_bounds(3)%end) then ghost_points_in(local_idx)%DB(3) = 1 else ghost_points_in(local_idx)%DB(3) = 0 @@ -1132,8 +1131,8 @@ contains else ! we do not have an analytic moment of inertia calculation and need to approximate it directly via a sum count = 0 moment = 0._wp - cell_volume = (x_cc(1) - x_cc(0))*(y_cc(1) - y_cc(0)) - ! computed without grid stretching. Update in the loop to perform with stretching + cell_volume = (x_cc(1) - x_cc(0))*(y_cc(1) - y_cc(0)) & + & ! computed without grid stretching. Update in the loop to perform with stretching if (p /= 0) then cell_volume = cell_volume*(z_cc(1) - z_cc(0)) end if @@ -1184,35 +1183,21 @@ contains do patch_id = 1, num_ibs ! check domain wraps in x, y, - #:for X in [('x'), ('y')] - ! check for periodicity - if (bc_${X}$%beg == BC_PERIODIC) then - ! check if the boundary has left the domain, and then correct - if (patch_ib(patch_id)%${X}$_centroid < ${X}$_domain%beg) then - ! if the boundary exited "left", wrap it back around to the "right" - patch_ib(patch_id)%${X}$_centroid = patch_ib(patch_id)%${X}$_centroid + (${X}$_domain%end & - & - ${X}$_domain%beg) - else if (patch_ib(patch_id)%${X}$_centroid > ${X}$_domain%end) then - ! if the boundary exited "right", wrap it back around to the "left" - patch_ib(patch_id)%${X}$_centroid = patch_ib(patch_id)%${X}$_centroid - (${X}$_domain%end & - & - ${X}$_domain%beg) + #:for X, ID in [('x', 1), ('y', 2), ('z',3)] + if (num_dims >= ${ID}$) then + if (bc_${X}$%beg == BC_PERIODIC) then + if (patch_ib(patch_id)%${X}$_centroid < glb_bounds(${ID}$)%beg) then + patch_ib(patch_id)%${X}$_centroid = patch_ib(patch_id)%${X}$_centroid + (glb_bounds(${ID}$)%end & + & - glb_bounds(${ID}$)%beg) + else if (patch_ib(patch_id)%${X}$_centroid > glb_bounds(${ID}$)%end) then + patch_ib(patch_id)%${X}$_centroid = patch_ib(patch_id)%${X}$_centroid - (glb_bounds(${ID}$)%end & + & - glb_bounds(${ID}$)%beg) + end if end if end if #:endfor - - if (p /= 0) then - ! check for periodicity - if (bc_z%beg == BC_PERIODIC) then - ! check if the boundary has left the domain, and then correct - if (patch_ib(patch_id)%z_centroid < z_domain%beg) then - ! if the boundary exited "left", wrap it back around to the "right" - patch_ib(patch_id)%z_centroid = patch_ib(patch_id)%z_centroid + (z_domain%end - z_domain%beg) - else if (patch_ib(patch_id)%z_centroid > z_domain%end) then - ! if the boundary exited "right", wrap it back around to the "left" - patch_ib(patch_id)%z_centroid = patch_ib(patch_id)%z_centroid - (z_domain%end - z_domain%beg) - end if - end if - end if + ! check for periodicity check if the boundary has left the domain, and then correct if the boundary exited "left", wrap + ! it back around to the "right" if the boundary exited "right", wrap it back around to the "left" end do end subroutine s_wrap_periodic_ibs diff --git a/src/simulation/m_mpi_proxy.fpp b/src/simulation/m_mpi_proxy.fpp index a2b6c84326..a4708cce4d 100644 --- a/src/simulation/m_mpi_proxy.fpp +++ b/src/simulation/m_mpi_proxy.fpp @@ -27,6 +27,24 @@ module m_mpi_proxy integer :: i_halo_size $:GPU_DECLARE(create='[i_halo_size]') + integer, dimension(-1:1,-1:1,-1:1) :: p_send_counts, p_recv_counts + integer, dimension(:,:,:,:), allocatable :: p_send_ids + character(len=1), dimension(:), allocatable :: p_send_buff, p_recv_buff + integer :: p_buff_size, p_var_size + !! EL Bubbles communication variables + integer, parameter :: MAX_NEIGHBORS = 27 + integer :: send_requests(MAX_NEIGHBORS), recv_requests(MAX_NEIGHBORS) + integer :: recv_offsets(MAX_NEIGHBORS) + integer :: neighbor_list(MAX_NEIGHBORS, 3) + integer :: n_neighbors + $:GPU_DECLARE(create='[p_send_counts]') + integer, allocatable :: force_send_counts(:), force_recv_counts(:) + integer, allocatable :: force_send_ids(:,:) + integer, allocatable :: flat_send_ids(:) + real(wp), allocatable :: force_send_vals(:,:,:) + real(wp), allocatable :: flat_send_vals(:) + $:GPU_DECLARE(create='[force_send_counts, force_send_ids, force_send_vals]') + contains !> Initialize the MPI proxy module @@ -52,6 +70,79 @@ contains end subroutine s_initialize_mpi_proxy_module + !! @param lag_num_ts Number of stages in time-stepping scheme + subroutine s_initialize_particles_mpi(lag_num_ts) + + integer :: i, j, k + integer :: real_size, int_size, nReal, lag_num_ts + integer :: ierr !< Generic flag used to identify and report MPI errors + +#ifdef MFC_MPI + call MPI_Pack_size(1, mpi_p, MPI_COMM_WORLD, real_size, ierr) + call MPI_Pack_size(1, MPI_INTEGER, MPI_COMM_WORLD, int_size, ierr) + nReal = 7 + 16*2 + 10*lag_num_ts + p_var_size = nReal*real_size + int_size + p_buff_size = lag_params%nBubs_glb*p_var_size + @:ALLOCATE(p_send_buff(0:p_buff_size), p_recv_buff(0:p_buff_size)) + @:ALLOCATE(p_send_ids(nidx(1)%beg:nidx(1)%end, nidx(2)%beg:nidx(2)%end, nidx(3)%beg:nidx(3)%end, 0:lag_params%nBubs_glb)) + ! First, collect all neighbor information + n_neighbors = 0 + do k = nidx(3)%beg, nidx(3)%end + do j = nidx(2)%beg, nidx(2)%end + do i = nidx(1)%beg, nidx(1)%end + if (abs(i) + abs(j) + abs(k) /= 0) then + n_neighbors = n_neighbors + 1 + neighbor_list(n_neighbors, 1) = i + neighbor_list(n_neighbors, 2) = j + neighbor_list(n_neighbors, 3) = k + end if + end do + end do + end do +#endif + + end subroutine s_initialize_particles_mpi + + !! @param lag_num_ts Number of stages in time-stepping scheme + subroutine s_initialize_solid_particles_mpi(lag_num_ts) + + integer :: i, j, k + integer :: real_size, int_size, nReal, lag_num_ts + integer :: ierr !< Generic flag used to identify and report MPI errors + +#ifdef MFC_MPI + call MPI_Pack_size(1, mpi_p, MPI_COMM_WORLD, real_size, ierr) + call MPI_Pack_size(1, MPI_INTEGER, MPI_COMM_WORLD, int_size, ierr) + nReal = 7 + 13*2 + 7*lag_num_ts + p_var_size = (nReal*real_size + int_size) + p_buff_size = lag_params%nParticles_glb*p_var_size + @:ALLOCATE(p_send_buff(0:p_buff_size), p_recv_buff(0:p_buff_size)) + @:ALLOCATE(p_send_ids(nidx(1)%beg:nidx(1)%end, nidx(2)%beg:nidx(2)%end, nidx(3)%beg:nidx(3)%end, & + & 0:lag_params%nParticles_glb)) + ! First, collect all neighbor information + n_neighbors = 0 + do k = nidx(3)%beg, nidx(3)%end + do j = nidx(2)%beg, nidx(2)%end + do i = nidx(1)%beg, nidx(1)%end + if (abs(i) + abs(j) + abs(k) /= 0) then + n_neighbors = n_neighbors + 1 + neighbor_list(n_neighbors, 1) = i + neighbor_list(n_neighbors, 2) = j + neighbor_list(n_neighbors, 3) = k + end if + end do + end do + end do + @:ALLOCATE(force_send_counts(0:num_procs-1)) + @:ALLOCATE(force_recv_counts(0:num_procs-1)) + @:ALLOCATE(force_send_ids(0:num_procs-1, 1:lag_params%nParticles_glb)) + @:ALLOCATE(force_send_vals(0:num_procs-1, 1:lag_params%nParticles_glb, 1:3)) + @:ALLOCATE(flat_send_ids(1:lag_params%nParticles_glb)) + @:ALLOCATE(flat_send_vals(1:3*lag_params%nParticles_glb)) +#endif + + end subroutine s_initialize_solid_particles_mpi + !> Since only the processor with rank 0 reads and verifies the consistency of user inputs, these are initially not available to !! the other processors. Then, the purpose of this subroutine is to distribute the user inputs to the remaining processors in !! the communicator. @@ -93,7 +184,7 @@ contains & 'cfl_adap_dt', 'cfl_const_dt', 'cfl_dt', 'surface_tension', & & 'shear_stress', 'bulk_stress', 'bubbles_lagrange', & & 'hyperelasticity', 'down_sample', 'int_comp','fft_wrt', & - & 'hyper_cleaning', 'ib_state_wrt'] + & 'hyper_cleaning', 'ib_state_wrt', 'particles_lagrange' ] call MPI_BCAST(${VAR}$, 1, MPI_LOGICAL, 0, MPI_COMM_WORLD, ierr) #:endfor @@ -109,17 +200,40 @@ contains if (bubbles_lagrange) then #:for VAR in [ 'heatTransfer_model', 'massTransfer_model', 'pressure_corrector', & - & 'write_bubbles', 'write_bubbles_stats'] + & 'write_bubbles', 'write_bubbles_stats', 'write_void_evol', 'pressure_force', & + & 'gravity_force'] + call MPI_BCAST(lag_params%${VAR}$, 1, MPI_LOGICAL, 0, MPI_COMM_WORLD, ierr) + #:endfor + + #:for VAR in ['solver_approach', 'cluster_type', 'smooth_type', 'nBubs_glb', 'vel_model', & + & 'drag_model', 'charNz'] + call MPI_BCAST(lag_params%${VAR}$, 1, MPI_INTEGER, 0, MPI_COMM_WORLD, ierr) + #:endfor + + #:for VAR in ['epsilonb','charwidth','valmaxvoid'] + call MPI_BCAST(lag_params%${VAR}$, 1, mpi_p, 0, MPI_COMM_WORLD, ierr) + #:endfor + + call MPI_BCAST(lag_params%input_path, len(lag_params%input_path), MPI_CHARACTER, 0, MPI_COMM_WORLD, ierr) + end if + + if (particles_lagrange) then + #:for VAR in [ 'heatTransfer_model', 'massTransfer_model', 'pressure_corrector', & + & 'write_bubbles', 'write_bubbles_stats', 'write_void_evol', 'pressure_force', & + & 'gravity_force', 'collision_force'] call MPI_BCAST(lag_params%${VAR}$, 1, MPI_LOGICAL, 0, MPI_COMM_WORLD, ierr) #:endfor - #:for VAR in ['solver_approach', 'cluster_type', 'smooth_type', 'nBubs_glb'] + #:for VAR in ['solver_approach', 'cluster_type', 'smooth_type', 'nParticles_glb', 'vel_model', & + & 'drag_model', 'qs_drag_model', 'stokes_drag', 'added_mass_model', 'interpolation_order'] call MPI_BCAST(lag_params%${VAR}$, 1, MPI_INTEGER, 0, MPI_COMM_WORLD, ierr) #:endfor #:for VAR in ['epsilonb','charwidth','valmaxvoid'] call MPI_BCAST(lag_params%${VAR}$, 1, mpi_p, 0, MPI_COMM_WORLD, ierr) #:endfor + + call MPI_BCAST(lag_params%input_path, len(lag_params%input_path), MPI_CHARACTER, 0, MPI_COMM_WORLD, ierr) end if #:for VAR in [ 'dt','weno_eps','teno_CT','pref','rhoref','R0ref','Web','Ca', 'sigma', & @@ -128,9 +242,7 @@ contains & 'bc_y%vb1','bc_y%vb2','bc_y%vb3','bc_y%ve1','bc_y%ve2','bc_y%ve3', & & 'bc_z%vb1','bc_z%vb2','bc_z%vb3','bc_z%ve1','bc_z%ve2','bc_z%ve3', & & 'bc_x%pres_in','bc_x%pres_out','bc_y%pres_in','bc_y%pres_out', 'bc_z%pres_in','bc_z%pres_out', & - & 'x_domain%beg', 'x_domain%end', 'y_domain%beg', 'y_domain%end', & - & 'z_domain%beg', 'z_domain%end', 'x_a', 'x_b', 'y_a', 'y_b', 'z_a', & - & 'z_b', 't_stop', 't_save', 'cfl_target', 'Bx0', 'alf_factor', & + & 't_stop', 't_save', 'cfl_target', 'Bx0', 'alf_factor', & & 'tau_star', 'cont_damage_s', 'alpha_bar', 'adap_dt_tol', & & 'ic_eps', 'ic_beta', 'hyper_cleaning_speed', & & 'hyper_cleaning_tau' ] @@ -179,6 +291,12 @@ contains #:endfor end if + if (particles_lagrange) then + #:for VAR in [ 'rho0ref_particle','cp_particle'] + call MPI_BCAST(particle_pp%${VAR}$, 1, mpi_p, 0, MPI_COMM_WORLD, ierr) + #:endfor + end if + do i = 1, num_fluids_max #:for VAR in ['bc_x%alpha_rho_in','bc_x%alpha_in','bc_y%alpha_rho_in','bc_y%alpha_in','bc_z%alpha_rho_in', & & 'bc_z%alpha_in'] @@ -233,11 +351,1062 @@ contains call MPI_BCAST(nv_uvm_out_of_core, 1, MPI_LOGICAL, 0, MPI_COMM_WORLD, ierr) call MPI_BCAST(nv_uvm_igr_temps_on_gpu, 1, MPI_INTEGER, 0, MPI_COMM_WORLD, ierr) call MPI_BCAST(nv_uvm_pref_gpu, 1, MPI_LOGICAL, 0, MPI_COMM_WORLD, ierr) + + ! Extra BC Variable + call MPI_BCAST(periodic_bc, 3, MPI_LOGICAL, 0, MPI_COMM_WORLD, ierr) #endif end subroutine s_mpi_bcast_user_inputs !> Broadcast random phase numbers from rank 0 to all MPI processes + !> @brief Packs, exchanges, and unpacks immersed boundary marker buffers between neighboring MPI ranks. + subroutine s_mpi_sendrecv_ib_buffers(ib_markers, mpi_dir, pbc_loc) + + type(integer_field), intent(inout) :: ib_markers + integer, intent(in) :: mpi_dir, pbc_loc + integer :: i, j, k, l, r, q !< Generic loop iterators + integer :: buffer_counts(1:3), buffer_count + type(int_bounds_info) :: boundary_conditions(1:3) + integer :: beg_end(1:2), grid_dims(1:3) + integer :: dst_proc, src_proc, recv_tag, send_tag + logical :: beg_end_geq_0, qbmm_comm + integer :: pack_offset, unpack_offset + +#ifdef MFC_MPI + integer :: ierr !< Generic flag used to identify and report MPI errors + + call nvtxStartRange("IB-MARKER-COMM-PACKBUF") + + buffer_counts = (/buff_size*(n + 1)*(p + 1), buff_size*(m + 2*buff_size + 1)*(p + 1), & + & buff_size*(m + 2*buff_size + 1)*(n + 2*buff_size + 1)/) + + buffer_count = buffer_counts(mpi_dir) + boundary_conditions = (/bc_x, bc_y, bc_z/) + beg_end = (/boundary_conditions(mpi_dir)%beg, boundary_conditions(mpi_dir)%end/) + beg_end_geq_0 = beg_end(max(pbc_loc, 0) - pbc_loc + 1) >= 0 + + send_tag = f_logical_to_int(.not. f_xor(beg_end_geq_0, pbc_loc == 1)) + recv_tag = f_logical_to_int(pbc_loc == 1) + + dst_proc = beg_end(1 + f_logical_to_int(f_xor(pbc_loc == 1, beg_end_geq_0))) + src_proc = beg_end(1 + f_logical_to_int(pbc_loc == 1)) + + grid_dims = (/m, n, p/) + + pack_offset = 0 + if (f_xor(pbc_loc == 1, beg_end_geq_0)) then + pack_offset = grid_dims(mpi_dir) - buff_size + 1 + end if + + unpack_offset = 0 + if (pbc_loc == 1) then + unpack_offset = grid_dims(mpi_dir) + buff_size + 1 + end if + + ! Pack Buffer to Send + #:for mpi_dir in [1, 2, 3] + if (mpi_dir == ${mpi_dir}$) then + #:if mpi_dir == 1 + $:GPU_PARALLEL_LOOP(collapse=3,private='[j, k, l, r]') + do l = 0, p + do k = 0, n + do j = 0, buff_size - 1 + r = (j + buff_size*(k + (n + 1)*l)) + ib_buff_send(r) = ib_markers%sf(j + pack_offset, k, l) + end do + end do + end do + $:END_GPU_PARALLEL_LOOP() + #:elif mpi_dir == 2 + $:GPU_PARALLEL_LOOP(collapse=3,private='[j, k, l, r]') + do l = 0, p + do k = 0, buff_size - 1 + do j = -buff_size, m + buff_size + r = ((j + buff_size) + (m + 2*buff_size + 1)*(k + buff_size*l)) + ib_buff_send(r) = ib_markers%sf(j, k + pack_offset, l) + end do + end do + end do + $:END_GPU_PARALLEL_LOOP() + #:else + $:GPU_PARALLEL_LOOP(collapse=3,private='[j, k, l, r]') + do l = 0, buff_size - 1 + do k = -buff_size, n + buff_size + do j = -buff_size, m + buff_size + r = ((j + buff_size) + (m + 2*buff_size + 1)*((k + buff_size) + (n + 2*buff_size + 1)*l)) + ib_buff_send(r) = ib_markers%sf(j, k, l + pack_offset) + end do + end do + end do + $:END_GPU_PARALLEL_LOOP() + #:endif + end if + #:endfor + call nvtxEndRange ! Packbuf + + #:for rdma_mpi in [False, True] + if (rdma_mpi .eqv. ${'.true.' if rdma_mpi else '.false.'}$) then + #:if rdma_mpi + #:call GPU_HOST_DATA(use_device_addr='[ib_buff_send, ib_buff_recv]') + call nvtxStartRange("IB-MARKER-SENDRECV-RDMA") + call MPI_SENDRECV(ib_buff_send, buffer_count, MPI_INTEGER, dst_proc, send_tag, ib_buff_recv, & + & buffer_count, MPI_INTEGER, src_proc, recv_tag, MPI_COMM_WORLD, MPI_STATUS_IGNORE, ierr) + call nvtxEndRange + #:endcall GPU_HOST_DATA + $:GPU_WAIT() + #:else + call nvtxStartRange("IB-MARKER-DEV2HOST") + $:GPU_UPDATE(host='[ib_buff_send]') + call nvtxEndRange + + call nvtxStartRange("IB-MARKER-SENDRECV-NO-RMDA") + call MPI_SENDRECV(ib_buff_send, buffer_count, MPI_INTEGER, dst_proc, send_tag, ib_buff_recv, buffer_count, & + & MPI_INTEGER, src_proc, recv_tag, MPI_COMM_WORLD, MPI_STATUS_IGNORE, ierr) + call nvtxEndRange + + call nvtxStartRange("IB-MARKER-HOST2DEV") + $:GPU_UPDATE(device='[ib_buff_recv]') + call nvtxEndRange + #:endif + end if + #:endfor + + ! Unpack Received Buffer + call nvtxStartRange("IB-MARKER-COMM-UNPACKBUF") + #:for mpi_dir in [1, 2, 3] + if (mpi_dir == ${mpi_dir}$) then + #:if mpi_dir == 1 + $:GPU_PARALLEL_LOOP(collapse=3,private='[j, k, l, r]') + do l = 0, p + do k = 0, n + do j = -buff_size, -1 + r = (j + buff_size*((k + 1) + (n + 1)*l)) + ib_markers%sf(j + unpack_offset, k, l) = ib_buff_recv(r) + end do + end do + end do + $:END_GPU_PARALLEL_LOOP() + #:elif mpi_dir == 2 + $:GPU_PARALLEL_LOOP(collapse=3,private='[j, k, l, r]') + do l = 0, p + do k = -buff_size, -1 + do j = -buff_size, m + buff_size + r = ((j + buff_size) + (m + 2*buff_size + 1)*((k + buff_size) + buff_size*l)) + ib_markers%sf(j, k + unpack_offset, l) = ib_buff_recv(r) + end do + end do + end do + $:END_GPU_PARALLEL_LOOP() + #:else + ! Unpacking buffer from bc_z%beg + $:GPU_PARALLEL_LOOP(collapse=3,private='[j, k, l, r]') + do l = -buff_size, -1 + do k = -buff_size, n + buff_size + do j = -buff_size, m + buff_size + r = ((j + buff_size) + (m + 2*buff_size + 1)*((k + buff_size) + (n + 2*buff_size + 1)*(l & + & + buff_size))) + ib_markers%sf(j, k, l + unpack_offset) = ib_buff_recv(r) + end do + end do + end do + $:END_GPU_PARALLEL_LOOP() + #:endif + end if + #:endfor + call nvtxEndRange +#endif + + end subroutine s_mpi_sendrecv_ib_buffers + + !! @param nPart Current LOCAL number of particles + !! @param pos Current position of each particle + !! @param posPrev Previous position of each particle (optional, not used + !! for communication of initial condition) + impure subroutine s_add_particles_to_transfer_list(nBub, pos, posPrev, include_ghost) + + real(wp), dimension(:,:) :: pos, posPrev + integer :: bubID, nbub + integer :: i, j, k + logical, optional, intent(in) :: include_ghost + + do k = nidx(3)%beg, nidx(3)%end + do j = nidx(2)%beg, nidx(2)%end + do i = nidx(1)%beg, nidx(1)%end + p_send_counts(i, j, k) = 0 + end do + end do + end do + + do k = 1, nbub + if (f_crosses_boundary(k, 1, -1, pos, posPrev, include_ghost)) then + call s_add_particle_to_direction(k, -1, 0, 0) + if (n > 0) then + if (f_crosses_boundary(k, 2, -1, pos, posPrev, include_ghost)) then + call s_add_particle_to_direction(k, -1, -1, 0) + call s_add_particle_to_direction(k, 0, -1, 0) + if (p > 0) then + if (f_crosses_boundary(k, 3, -1, pos, posPrev, include_ghost)) then + call s_add_particle_to_direction(k, -1, -1, -1) + call s_add_particle_to_direction(k, 0, -1, -1) + call s_add_particle_to_direction(k, -1, 0, -1) + call s_add_particle_to_direction(k, 0, 0, -1) + else if (f_crosses_boundary(k, 3, 1, pos, posPrev, include_ghost)) then + call s_add_particle_to_direction(k, -1, -1, 1) + call s_add_particle_to_direction(k, 0, -1, 1) + call s_add_particle_to_direction(k, -1, 0, 1) + call s_add_particle_to_direction(k, 0, 0, 1) + end if + end if + else if (f_crosses_boundary(k, 2, 1, pos, posPrev, include_ghost)) then + call s_add_particle_to_direction(k, -1, 1, 0) + call s_add_particle_to_direction(k, 0, 1, 0) + if (p > 0) then + if (f_crosses_boundary(k, 3, -1, pos, posPrev, include_ghost)) then + call s_add_particle_to_direction(k, -1, 1, -1) + call s_add_particle_to_direction(k, 0, 1, -1) + call s_add_particle_to_direction(k, -1, 0, -1) + call s_add_particle_to_direction(k, 0, 0, -1) + else if (f_crosses_boundary(k, 3, 1, pos, posPrev, include_ghost)) then + call s_add_particle_to_direction(k, -1, 1, 1) + call s_add_particle_to_direction(k, 0, 1, 1) + call s_add_particle_to_direction(k, -1, 0, 1) + call s_add_particle_to_direction(k, 0, 0, 1) + end if + end if + else + if (p > 0) then + if (f_crosses_boundary(k, 3, -1, pos, posPrev, include_ghost)) then + call s_add_particle_to_direction(k, -1, 0, -1) + call s_add_particle_to_direction(k, 0, 0, -1) + else if (f_crosses_boundary(k, 3, 1, pos, posPrev, include_ghost)) then + call s_add_particle_to_direction(k, -1, 0, 1) + call s_add_particle_to_direction(k, 0, 0, 1) + end if + end if + end if + end if + else if (f_crosses_boundary(k, 1, 1, pos, posPrev, include_ghost)) then + call s_add_particle_to_direction(k, 1, 0, 0) + if (n > 0) then + if (f_crosses_boundary(k, 2, -1, pos, posPrev, include_ghost)) then + call s_add_particle_to_direction(k, 1, -1, 0) + call s_add_particle_to_direction(k, 0, -1, 0) + if (p > 0) then + if (f_crosses_boundary(k, 3, -1, pos, posPrev, include_ghost)) then + call s_add_particle_to_direction(k, 1, -1, -1) + call s_add_particle_to_direction(k, 0, -1, -1) + call s_add_particle_to_direction(k, 1, 0, -1) + call s_add_particle_to_direction(k, 0, 0, -1) + else if (f_crosses_boundary(k, 3, 1, pos, posPrev, include_ghost)) then + call s_add_particle_to_direction(k, 1, -1, 1) + call s_add_particle_to_direction(k, 0, -1, 1) + call s_add_particle_to_direction(k, 1, 0, 1) + call s_add_particle_to_direction(k, 0, 0, 1) + end if + end if + else if (f_crosses_boundary(k, 2, 1, pos, posPrev, include_ghost)) then + call s_add_particle_to_direction(k, 1, 1, 0) + call s_add_particle_to_direction(k, 0, 1, 0) + if (p > 0) then + if (f_crosses_boundary(k, 3, -1, pos, posPrev, include_ghost)) then + call s_add_particle_to_direction(k, 1, 1, -1) + call s_add_particle_to_direction(k, 0, 1, -1) + call s_add_particle_to_direction(k, 1, 0, -1) + call s_add_particle_to_direction(k, 0, 0, -1) + else if (f_crosses_boundary(k, 3, 1, pos, posPrev, include_ghost)) then + call s_add_particle_to_direction(k, 1, 1, 1) + call s_add_particle_to_direction(k, 0, 1, 1) + call s_add_particle_to_direction(k, 1, 0, 1) + call s_add_particle_to_direction(k, 0, 0, 1) + end if + end if + else + if (p > 0) then + if (f_crosses_boundary(k, 3, -1, pos, posPrev, include_ghost)) then + call s_add_particle_to_direction(k, 1, 0, -1) + call s_add_particle_to_direction(k, 0, 0, -1) + else if (f_crosses_boundary(k, 3, 1, pos, posPrev, include_ghost)) then + call s_add_particle_to_direction(k, 1, 0, 1) + call s_add_particle_to_direction(k, 0, 0, 1) + end if + end if + end if + end if + else if (f_crosses_boundary(k, 2, -1, pos, posPrev, include_ghost)) then + call s_add_particle_to_direction(k, 0, -1, 0) + if (p > 0) then + if (f_crosses_boundary(k, 3, -1, pos, posPrev, include_ghost)) then + call s_add_particle_to_direction(k, 0, -1, -1) + call s_add_particle_to_direction(k, 0, 0, -1) + else if (f_crosses_boundary(k, 3, 1, pos, posPrev, include_ghost)) then + call s_add_particle_to_direction(k, 0, -1, 1) + call s_add_particle_to_direction(k, 0, 0, 1) + end if + end if + else if (f_crosses_boundary(k, 2, 1, pos, posPrev, include_ghost)) then + call s_add_particle_to_direction(k, 0, 1, 0) + if (p > 0) then + if (f_crosses_boundary(k, 3, -1, pos, posPrev, include_ghost)) then + call s_add_particle_to_direction(k, 0, 1, -1) + call s_add_particle_to_direction(k, 0, 0, -1) + else if (f_crosses_boundary(k, 3, 1, pos, posPrev, include_ghost)) then + call s_add_particle_to_direction(k, 0, 1, 1) + call s_add_particle_to_direction(k, 0, 0, 1) + end if + end if + else if (p > 0) then + if (f_crosses_boundary(k, 3, -1, pos, posPrev, include_ghost)) then + call s_add_particle_to_direction(k, 0, 0, -1) + else if (f_crosses_boundary(k, 3, 1, pos, posPrev, include_ghost)) then + call s_add_particle_to_direction(k, 0, 0, 1) + end if + end if + end do + + contains + + logical function f_crosses_boundary(particle_id, dir, loc, pos, posPrev, include_ghost) + + integer, intent(in) :: particle_id, dir, loc + real(wp), dimension(:,:), intent(in) :: pos + real(wp), dimension(:,:), optional, intent(in) :: posPrev + logical, optional, intent(in) :: include_ghost + + if (present(include_ghost) .and. include_ghost) then + if (loc == -1) then ! Beginning of the domain + if (nidx(dir)%beg == 0) then + f_crosses_boundary = .false. + return + end if + + f_crosses_boundary = pos(particle_id, dir) < pcomm_coords_ghost(dir)%beg + else if (loc == 1) then ! End of the domain + if (nidx(dir)%end == 0) then + f_crosses_boundary = .false. + return + end if + + f_crosses_boundary = pos(particle_id, dir) > pcomm_coords_ghost(dir)%end + end if + else + if (loc == -1) then ! Beginning of the domain + if (nidx(dir)%beg == 0) then + f_crosses_boundary = .false. + return + end if + + f_crosses_boundary = (posPrev(particle_id, dir) >= pcomm_coords(dir)%beg .and. pos(particle_id, & + & dir) < pcomm_coords(dir)%beg) + else if (loc == 1) then ! End of the domain + if (nidx(dir)%end == 0) then + f_crosses_boundary = .false. + return + end if + + f_crosses_boundary = (posPrev(particle_id, dir) <= pcomm_coords(dir)%end .and. pos(particle_id, & + & dir) > pcomm_coords(dir)%end) + end if + end if + + end function f_crosses_boundary + + subroutine s_add_particle_to_direction(particle_id, dir_x, dir_y, dir_z) + + integer, intent(in) :: particle_id, dir_x, dir_y, dir_z + + p_send_ids(dir_x, dir_y, dir_z, p_send_counts(dir_x, dir_y, dir_z)) = particle_id + p_send_counts(dir_x, dir_y, dir_z) = p_send_counts(dir_x, dir_y, dir_z) + 1 + + end subroutine s_add_particle_to_direction + + end subroutine s_add_particles_to_transfer_list + + !! @param bub_R0 Initial radius of each bubble + !! @param Rmax_stats Maximum radius of each bubble + !! @param Rmin_stats Minimum radius of each bubble + !! @param gas_mg Mass of gas in each bubble + !! @param gas_betaT Heat flux model coefficient for each bubble + !! @param gas_betaC mass flux model coefficient for each bubble + !! @param bub_dphidt Subgrid velocity potential for each bubble + !! @param lag_id Global and local ID of each bubble + !! @param gas_p Pressure of the gas in each bubble + !! @param gas_mv Mass of vapor in each bubble + !! @param rad Radius of each bubble + !! @param rvel Radial velocity of each bubble + !! @param pos Position of each bubble + !! @param posPrev Previous position of each bubble + !! @param vel Velocity of each bubble + !! @param scoord Cell index in real format of each bubble + !! @param drad Radial velocity of each bubble + !! @param drvel Radial acceleration of each bubble + !! @param dgasp Time derivative of gas pressure in each bubble + !! @param dgasmv Time derivative of vapor mass in each bubble + !! @param dpos Time derivative of position of each bubble + !! @param dvel Time derivative of velocity of each bubble + !! @param lag_num_ts Number of stages in time-stepping scheme + !! @param nBubs Local number of bubbles + impure subroutine s_mpi_sendrecv_particles(bub_R0, Rmax_stats, Rmin_stats, gas_mg, gas_betaT, gas_betaC, bub_dphidt, lag_id, & + & gas_p, gas_mv, rad, rvel, pos, posPrev, vel, scoord, drad, drvel, dgasp, dgasmv, dpos, dvel, lag_num_ts, nbubs, dest) + + real(wp), dimension(:) :: bub_R0, Rmax_stats, Rmin_stats, gas_mg, gas_betaT, gas_betaC, bub_dphidt + integer, dimension(:,:) :: lag_id + real(wp), dimension(:,:) :: gas_p, gas_mv, rad, rvel, drad, drvel, dgasp, dgasmv + real(wp), dimension(:,:,:) :: pos, posPrev, vel, scoord, dpos, dvel + integer :: position, bub_id, lag_num_ts, tag, partner, send_tag, recv_tag, nbubs, p_recv_size, dest + integer :: i, j, k, l, q, r + integer :: req_send, req_recv, ierr !< Generic flag used to identify and report MPI errors + integer :: send_count, send_offset, recv_count, recv_offset + +#ifdef MFC_MPI + ! Phase 1: Exchange particle counts using non-blocking communication + send_count = 0 + recv_count = 0 + + ! Post all receives first + do l = 1, n_neighbors + i = neighbor_list(l, 1) + j = neighbor_list(l, 2) + k = neighbor_list(l, 3) + partner = neighbor_ranks(i, j, k) + recv_tag = neighbor_tag(i, j, k) + + recv_count = recv_count + 1 + call MPI_Irecv(p_recv_counts(i, j, k), 1, MPI_INTEGER, partner, recv_tag, MPI_COMM_WORLD, recv_requests(recv_count), & + & ierr) + end do + + ! Post all sends + do l = 1, n_neighbors + i = neighbor_list(l, 1) + j = neighbor_list(l, 2) + k = neighbor_list(l, 3) + partner = neighbor_ranks(i, j, k) + send_tag = neighbor_tag(-i, -j, -k) + + send_count = send_count + 1 + call MPI_Isend(p_send_counts(i, j, k), 1, MPI_INTEGER, partner, send_tag, MPI_COMM_WORLD, send_requests(send_count), & + & ierr) + end do + + ! Wait for all count exchanges to complete + if (recv_count > 0) then + call MPI_Waitall(recv_count, recv_requests(1:recv_count), MPI_STATUSES_IGNORE, ierr) + end if + if (send_count > 0) then + call MPI_Waitall(send_count, send_requests(1:send_count), MPI_STATUSES_IGNORE, ierr) + end if + + ! Phase 2: Exchange particle data using non-blocking communication + send_count = 0 + recv_count = 0 + + ! Post all receives for particle data first + recv_offset = 1 + do l = 1, n_neighbors + i = neighbor_list(l, 1) + j = neighbor_list(l, 2) + k = neighbor_list(l, 3) + + if (p_recv_counts(i, j, k) > 0) then + partner = neighbor_ranks(i, j, k) + p_recv_size = p_recv_counts(i, j, k)*p_var_size + recv_tag = neighbor_tag(i, j, k) + + recv_count = recv_count + 1 + call MPI_Irecv(p_recv_buff(recv_offset), p_recv_size, MPI_PACKED, partner, recv_tag, MPI_COMM_WORLD, & + & recv_requests(recv_count), ierr) + recv_offsets(l) = recv_offset + recv_offset = recv_offset + p_recv_size + end if + end do + + ! Pack and send particle data + send_offset = 0 + do l = 1, n_neighbors + i = neighbor_list(l, 1) + j = neighbor_list(l, 2) + k = neighbor_list(l, 3) + + if (p_send_counts(i, j, k) > 0 .and. abs(i) + abs(j) + abs(k) /= 0 .and. abs(i) + abs(j) + abs(k) /= 0) then + partner = neighbor_ranks(i, j, k) + send_tag = neighbor_tag(-i, -j, -k) + + ! Pack data for sending + position = 0 + do q = 0, p_send_counts(i, j, k) - 1 + bub_id = p_send_ids(i, j, k, q) + + call MPI_Pack(lag_id(bub_id, 1), 1, MPI_INTEGER, p_send_buff(send_offset), p_buff_size, position, & + & MPI_COMM_WORLD, ierr) + call MPI_Pack(bub_R0(bub_id), 1, mpi_p, p_send_buff(send_offset), p_buff_size, position, MPI_COMM_WORLD, ierr) + call MPI_Pack(Rmax_stats(bub_id), 1, mpi_p, p_send_buff(send_offset), p_buff_size, position, MPI_COMM_WORLD, & + & ierr) + call MPI_Pack(Rmin_stats(bub_id), 1, mpi_p, p_send_buff(send_offset), p_buff_size, position, MPI_COMM_WORLD, & + & ierr) + call MPI_Pack(gas_mg(bub_id), 1, mpi_p, p_send_buff(send_offset), p_buff_size, position, MPI_COMM_WORLD, ierr) + call MPI_Pack(gas_betaT(bub_id), 1, mpi_p, p_send_buff(send_offset), p_buff_size, position, MPI_COMM_WORLD, & + & ierr) + call MPI_Pack(gas_betaC(bub_id), 1, mpi_p, p_send_buff(send_offset), p_buff_size, position, MPI_COMM_WORLD, & + & ierr) + call MPI_Pack(bub_dphidt(bub_id), 1, mpi_p, p_send_buff(send_offset), p_buff_size, position, MPI_COMM_WORLD, & + & ierr) + do r = 1, 2 + call MPI_Pack(gas_p(bub_id, r), 1, mpi_p, p_send_buff(send_offset), p_buff_size, position, & + & MPI_COMM_WORLD, ierr) + call MPI_Pack(gas_mv(bub_id, r), 1, mpi_p, p_send_buff(send_offset), p_buff_size, position, & + & MPI_COMM_WORLD, ierr) + call MPI_Pack(rad(bub_id, r), 1, mpi_p, p_send_buff(send_offset), p_buff_size, position, MPI_COMM_WORLD, & + & ierr) + call MPI_Pack(rvel(bub_id, r), 1, mpi_p, p_send_buff(send_offset), p_buff_size, position, MPI_COMM_WORLD, & + & ierr) + call MPI_Pack(pos(bub_id,:,r), 3, mpi_p, p_send_buff(send_offset), p_buff_size, position, MPI_COMM_WORLD, & + & ierr) + call MPI_Pack(posPrev(bub_id,:,r), 3, mpi_p, p_send_buff(send_offset), p_buff_size, position, & + & MPI_COMM_WORLD, ierr) + call MPI_Pack(vel(bub_id,:,r), 3, mpi_p, p_send_buff(send_offset), p_buff_size, position, MPI_COMM_WORLD, & + & ierr) + call MPI_Pack(scoord(bub_id,:,r), 3, mpi_p, p_send_buff(send_offset), p_buff_size, position, & + & MPI_COMM_WORLD, ierr) + end do + do r = 1, lag_num_ts + call MPI_Pack(drad(bub_id, r), 1, mpi_p, p_send_buff(send_offset), p_buff_size, position, MPI_COMM_WORLD, & + & ierr) + call MPI_Pack(drvel(bub_id, r), 1, mpi_p, p_send_buff(send_offset), p_buff_size, position, & + & MPI_COMM_WORLD, ierr) + call MPI_Pack(dgasp(bub_id, r), 1, mpi_p, p_send_buff(send_offset), p_buff_size, position, & + & MPI_COMM_WORLD, ierr) + call MPI_Pack(dgasmv(bub_id, r), 1, mpi_p, p_send_buff(send_offset), p_buff_size, position, & + & MPI_COMM_WORLD, ierr) + call MPI_Pack(dpos(bub_id,:,r), 3, mpi_p, p_send_buff(send_offset), p_buff_size, position, & + & MPI_COMM_WORLD, ierr) + call MPI_Pack(dvel(bub_id,:,r), 3, mpi_p, p_send_buff(send_offset), p_buff_size, position, & + & MPI_COMM_WORLD, ierr) + end do + end do + + send_count = send_count + 1 + call MPI_Isend(p_send_buff(send_offset), position, MPI_PACKED, partner, send_tag, MPI_COMM_WORLD, & + & send_requests(send_count), ierr) + send_offset = send_offset + position + end if + end do + + ! Wait for all recvs for contiguous data to complete + call MPI_Waitall(recv_count, recv_requests(1:recv_count), MPI_STATUSES_IGNORE, ierr) + + ! Process received data as it arrives + do l = 1, n_neighbors + i = neighbor_list(l, 1) + j = neighbor_list(l, 2) + k = neighbor_list(l, 3) + + if (p_recv_counts(i, j, k) > 0 .and. abs(i) + abs(j) + abs(k) /= 0) then + p_recv_size = p_recv_counts(i, j, k)*p_var_size + recv_offset = recv_offsets(l) + + position = 0 + ! Unpack received data + do q = 0, p_recv_counts(i, j, k) - 1 + nbubs = nbubs + 1 + bub_id = nbubs + call MPI_Unpack(p_recv_buff(recv_offset), p_recv_size, position, lag_id(bub_id, 1), 1, MPI_INTEGER, & + & MPI_COMM_WORLD, ierr) + call MPI_Unpack(p_recv_buff(recv_offset), p_recv_size, position, bub_R0(bub_id), 1, mpi_p, MPI_COMM_WORLD, ierr) + call MPI_Unpack(p_recv_buff(recv_offset), p_recv_size, position, Rmax_stats(bub_id), 1, mpi_p, & + & MPI_COMM_WORLD, ierr) + call MPI_Unpack(p_recv_buff(recv_offset), p_recv_size, position, Rmin_stats(bub_id), 1, mpi_p, & + & MPI_COMM_WORLD, ierr) + call MPI_Unpack(p_recv_buff(recv_offset), p_recv_size, position, gas_mg(bub_id), 1, mpi_p, MPI_COMM_WORLD, ierr) + call MPI_Unpack(p_recv_buff(recv_offset), p_recv_size, position, gas_betaT(bub_id), 1, mpi_p, MPI_COMM_WORLD, & + & ierr) + call MPI_Unpack(p_recv_buff(recv_offset), p_recv_size, position, gas_betaC(bub_id), 1, mpi_p, MPI_COMM_WORLD, & + & ierr) + call MPI_Unpack(p_recv_buff(recv_offset), p_recv_size, position, bub_dphidt(bub_id), 1, mpi_p, & + & MPI_COMM_WORLD, ierr) + do r = 1, 2 + call MPI_Unpack(p_recv_buff(recv_offset), p_recv_size, position, gas_p(bub_id, r), 1, mpi_p, & + & MPI_COMM_WORLD, ierr) + call MPI_Unpack(p_recv_buff(recv_offset), p_recv_size, position, gas_mv(bub_id, r), 1, mpi_p, & + & MPI_COMM_WORLD, ierr) + call MPI_Unpack(p_recv_buff(recv_offset), p_recv_size, position, rad(bub_id, r), 1, mpi_p, & + & MPI_COMM_WORLD, ierr) + call MPI_Unpack(p_recv_buff(recv_offset), p_recv_size, position, rvel(bub_id, r), 1, mpi_p, & + & MPI_COMM_WORLD, ierr) + call MPI_Unpack(p_recv_buff(recv_offset), p_recv_size, position, pos(bub_id,:,r), 3, mpi_p, & + & MPI_COMM_WORLD, ierr) + call MPI_Unpack(p_recv_buff(recv_offset), p_recv_size, position, posPrev(bub_id,:,r), 3, mpi_p, & + & MPI_COMM_WORLD, ierr) + call MPI_Unpack(p_recv_buff(recv_offset), p_recv_size, position, vel(bub_id,:,r), 3, mpi_p, & + & MPI_COMM_WORLD, ierr) + call MPI_Unpack(p_recv_buff(recv_offset), p_recv_size, position, scoord(bub_id,:,r), 3, mpi_p, & + & MPI_COMM_WORLD, ierr) + end do + do r = 1, lag_num_ts + call MPI_Unpack(p_recv_buff(recv_offset), p_recv_size, position, drad(bub_id, r), 1, mpi_p, & + & MPI_COMM_WORLD, ierr) + call MPI_Unpack(p_recv_buff(recv_offset), p_recv_size, position, drvel(bub_id, r), 1, mpi_p, & + & MPI_COMM_WORLD, ierr) + call MPI_Unpack(p_recv_buff(recv_offset), p_recv_size, position, dgasp(bub_id, r), 1, mpi_p, & + & MPI_COMM_WORLD, ierr) + call MPI_Unpack(p_recv_buff(recv_offset), p_recv_size, position, dgasmv(bub_id, r), 1, mpi_p, & + & MPI_COMM_WORLD, ierr) + call MPI_Unpack(p_recv_buff(recv_offset), p_recv_size, position, dpos(bub_id,:,r), 3, mpi_p, & + & MPI_COMM_WORLD, ierr) + call MPI_Unpack(p_recv_buff(recv_offset), p_recv_size, position, dvel(bub_id,:,r), 3, mpi_p, & + & MPI_COMM_WORLD, ierr) + end do + lag_id(bub_id, 2) = bub_id + end do + recv_offset = recv_offset + p_recv_size + end if + end do + + ! Wait for all sends to complete + if (send_count > 0) then + call MPI_Waitall(send_count, send_requests(1:send_count), MPI_STATUSES_IGNORE, ierr) + end if +#endif + + if (any(periodic_bc)) then + call s_wrap_particle_positions(pos, posPrev, nbubs, dest) + end if + + end subroutine s_mpi_sendrecv_particles + + !! @param particle_R0 Initial radius of each particle + !! @param Rmax_stats Maximum radius of each particle + !! @param Rmin_stats Minimum radius of each particle + !! @param particle_mass Mass of each particle + !! @param f_p Force on each particle + !! @param lag_id Global and local ID of each particle + !! @param rad Radius of each particle + !! @param pos Position of each particle + !! @param posPrev Previous position of each particle + !! @param vel Velocity of each particle + !! @param scoord Cell index in real format of each particle + !! @param drad Time derivative of particle's radius + !! @param dpos Time derivative of position of each particle + !! @param dvel Time derivative of velocity of each particle + !! @param lag_num_ts Number of stages in time-stepping scheme + !! @param nParticles Local number of particles + impure subroutine s_mpi_sendrecv_solid_particles(p_owner_rank, particle_R0, Rmax_stats, Rmin_stats, particle_mass, f_p, & + & lag_id, rad, pos, posPrev, vel, scoord, drad, dpos, dvel, lag_num_ts, nParticles, dest) + + integer, dimension(:) :: p_owner_rank + real(wp), dimension(:) :: particle_R0, Rmax_stats, Rmin_stats, particle_mass + real(wp), dimension(:,:) :: f_p + integer, dimension(:,:) :: lag_id + real(wp), dimension(:,:) :: rad, drad + real(wp), dimension(:,:,:) :: pos, posPrev, vel, scoord, dpos, dvel + integer :: position, particle_id, lag_num_ts, tag, partner, send_tag, recv_tag, nParticles, p_recv_size, dest + integer :: i, j, k, l, q, r + integer :: req_send, req_recv, ierr !< Generic flag used to identify and report MPI errors + integer :: send_count, send_offset, recv_count, recv_offset + +#ifdef MFC_MPI + ! Phase 1: Exchange particle counts using non-blocking communication + send_count = 0 + recv_count = 0 + + ! Post all receives first + do l = 1, n_neighbors + i = neighbor_list(l, 1) + j = neighbor_list(l, 2) + k = neighbor_list(l, 3) + partner = neighbor_ranks(i, j, k) + recv_tag = neighbor_tag(i, j, k) + + recv_count = recv_count + 1 + call MPI_Irecv(p_recv_counts(i, j, k), 1, MPI_INTEGER, partner, recv_tag, MPI_COMM_WORLD, recv_requests(recv_count), & + & ierr) + end do + + ! Post all sends + do l = 1, n_neighbors + i = neighbor_list(l, 1) + j = neighbor_list(l, 2) + k = neighbor_list(l, 3) + partner = neighbor_ranks(i, j, k) + send_tag = neighbor_tag(-i, -j, -k) + + send_count = send_count + 1 + call MPI_Isend(p_send_counts(i, j, k), 1, MPI_INTEGER, partner, send_tag, MPI_COMM_WORLD, send_requests(send_count), & + & ierr) + end do + + ! Wait for all count exchanges to complete + if (recv_count > 0) then + call MPI_Waitall(recv_count, recv_requests(1:recv_count), MPI_STATUSES_IGNORE, ierr) + end if + if (send_count > 0) then + call MPI_Waitall(send_count, send_requests(1:send_count), MPI_STATUSES_IGNORE, ierr) + end if + + ! Phase 2: Exchange particle data using non-blocking communication + send_count = 0 + recv_count = 0 + + ! Post all receives for particle data first + recv_offset = 1 + do l = 1, n_neighbors + i = neighbor_list(l, 1) + j = neighbor_list(l, 2) + k = neighbor_list(l, 3) + + if (p_recv_counts(i, j, k) > 0) then + partner = neighbor_ranks(i, j, k) + p_recv_size = p_recv_counts(i, j, k)*p_var_size + recv_tag = neighbor_tag(i, j, k) + + recv_count = recv_count + 1 + call MPI_Irecv(p_recv_buff(recv_offset), p_recv_size, MPI_PACKED, partner, recv_tag, MPI_COMM_WORLD, & + & recv_requests(recv_count), ierr) + recv_offsets(l) = recv_offset + recv_offset = recv_offset + p_recv_size + end if + end do + + ! Pack and send particle data + send_offset = 0 + do l = 1, n_neighbors + i = neighbor_list(l, 1) + j = neighbor_list(l, 2) + k = neighbor_list(l, 3) + + if (p_send_counts(i, j, k) > 0 .and. abs(i) + abs(j) + abs(k) /= 0 .and. abs(i) + abs(j) + abs(k) /= 0) then + partner = neighbor_ranks(i, j, k) + send_tag = neighbor_tag(-i, -j, -k) + + ! Pack data for sending + position = 0 + do q = 0, p_send_counts(i, j, k) - 1 + particle_id = p_send_ids(i, j, k, q) + + call MPI_Pack(lag_id(particle_id, 1), 1, MPI_INTEGER, p_send_buff(send_offset), p_buff_size, position, & + & MPI_COMM_WORLD, ierr) + call MPI_Pack(particle_R0(particle_id), 1, mpi_p, p_send_buff(send_offset), p_buff_size, position, & + & MPI_COMM_WORLD, ierr) + call MPI_Pack(Rmax_stats(particle_id), 1, mpi_p, p_send_buff(send_offset), p_buff_size, position, & + & MPI_COMM_WORLD, ierr) + call MPI_Pack(Rmin_stats(particle_id), 1, mpi_p, p_send_buff(send_offset), p_buff_size, position, & + & MPI_COMM_WORLD, ierr) + call MPI_Pack(particle_mass(particle_id), 1, mpi_p, p_send_buff(send_offset), p_buff_size, position, & + & MPI_COMM_WORLD, ierr) + call MPI_Pack(f_p(particle_id,:), 3, mpi_p, p_send_buff(send_offset), p_buff_size, position, MPI_COMM_WORLD, & + & ierr) + do r = 1, 2 + call MPI_Pack(rad(particle_id, r), 1, mpi_p, p_send_buff(send_offset), p_buff_size, position, & + & MPI_COMM_WORLD, ierr) + call MPI_Pack(pos(particle_id,:,r), 3, mpi_p, p_send_buff(send_offset), p_buff_size, position, & + & MPI_COMM_WORLD, ierr) + call MPI_Pack(posPrev(particle_id,:,r), 3, mpi_p, p_send_buff(send_offset), p_buff_size, position, & + & MPI_COMM_WORLD, ierr) + call MPI_Pack(vel(particle_id,:,r), 3, mpi_p, p_send_buff(send_offset), p_buff_size, position, & + & MPI_COMM_WORLD, ierr) + call MPI_Pack(scoord(particle_id,:,r), 3, mpi_p, p_send_buff(send_offset), p_buff_size, position, & + & MPI_COMM_WORLD, ierr) + end do + do r = 1, lag_num_ts + call MPI_Pack(drad(particle_id, r), 1, mpi_p, p_send_buff(send_offset), p_buff_size, position, & + & MPI_COMM_WORLD, ierr) + call MPI_Pack(dpos(particle_id,:,r), 3, mpi_p, p_send_buff(send_offset), p_buff_size, position, & + & MPI_COMM_WORLD, ierr) + call MPI_Pack(dvel(particle_id,:,r), 3, mpi_p, p_send_buff(send_offset), p_buff_size, position, & + & MPI_COMM_WORLD, ierr) + end do + end do + + send_count = send_count + 1 + call MPI_Isend(p_send_buff(send_offset), position, MPI_PACKED, partner, send_tag, MPI_COMM_WORLD, & + & send_requests(send_count), ierr) + send_offset = send_offset + position + end if + end do + + ! Wait for all recvs for contiguous data to complete + call MPI_Waitall(recv_count, recv_requests(1:recv_count), MPI_STATUSES_IGNORE, ierr) + + ! Process received data as it arrives + do l = 1, n_neighbors + i = neighbor_list(l, 1) + j = neighbor_list(l, 2) + k = neighbor_list(l, 3) + + if (p_recv_counts(i, j, k) > 0 .and. abs(i) + abs(j) + abs(k) /= 0) then + p_recv_size = p_recv_counts(i, j, k)*p_var_size + recv_offset = recv_offsets(l) + + position = 0 + ! Unpack received data + do q = 0, p_recv_counts(i, j, k) - 1 + nParticles = nParticles + 1 + particle_id = nParticles + + p_owner_rank(particle_id) = neighbor_ranks(i, j, k) + + call MPI_Unpack(p_recv_buff(recv_offset), p_recv_size, position, lag_id(particle_id, 1), 1, MPI_INTEGER, & + & MPI_COMM_WORLD, ierr) + call MPI_Unpack(p_recv_buff(recv_offset), p_recv_size, position, particle_R0(particle_id), 1, mpi_p, & + & MPI_COMM_WORLD, ierr) + call MPI_Unpack(p_recv_buff(recv_offset), p_recv_size, position, Rmax_stats(particle_id), 1, mpi_p, & + & MPI_COMM_WORLD, ierr) + call MPI_Unpack(p_recv_buff(recv_offset), p_recv_size, position, Rmin_stats(particle_id), 1, mpi_p, & + & MPI_COMM_WORLD, ierr) + call MPI_Unpack(p_recv_buff(recv_offset), p_recv_size, position, particle_mass(particle_id), 1, mpi_p, & + & MPI_COMM_WORLD, ierr) + call MPI_Unpack(p_recv_buff(recv_offset), p_recv_size, position, f_p(particle_id,:), 3, mpi_p, & + & MPI_COMM_WORLD, ierr) + do r = 1, 2 + call MPI_Unpack(p_recv_buff(recv_offset), p_recv_size, position, rad(particle_id, r), 1, mpi_p, & + & MPI_COMM_WORLD, ierr) + call MPI_Unpack(p_recv_buff(recv_offset), p_recv_size, position, pos(particle_id,:,r), 3, mpi_p, & + & MPI_COMM_WORLD, ierr) + call MPI_Unpack(p_recv_buff(recv_offset), p_recv_size, position, posPrev(particle_id,:,r), 3, mpi_p, & + & MPI_COMM_WORLD, ierr) + call MPI_Unpack(p_recv_buff(recv_offset), p_recv_size, position, vel(particle_id,:,r), 3, mpi_p, & + & MPI_COMM_WORLD, ierr) + call MPI_Unpack(p_recv_buff(recv_offset), p_recv_size, position, scoord(particle_id,:,r), 3, mpi_p, & + & MPI_COMM_WORLD, ierr) + end do + do r = 1, lag_num_ts + call MPI_Unpack(p_recv_buff(recv_offset), p_recv_size, position, drad(particle_id, r), 1, mpi_p, & + & MPI_COMM_WORLD, ierr) + call MPI_Unpack(p_recv_buff(recv_offset), p_recv_size, position, dpos(particle_id,:,r), 3, mpi_p, & + & MPI_COMM_WORLD, ierr) + call MPI_Unpack(p_recv_buff(recv_offset), p_recv_size, position, dvel(particle_id,:,r), 3, mpi_p, & + & MPI_COMM_WORLD, ierr) + end do + lag_id(particle_id, 2) = particle_id + end do + recv_offset = recv_offset + p_recv_size + end if + end do + + ! Wait for all sends to complete + if (send_count > 0) then + call MPI_Waitall(send_count, send_requests(1:send_count), MPI_STATUSES_IGNORE, ierr) + end if +#endif + + if (any(periodic_bc)) then + call s_wrap_particle_positions(pos, posPrev, nParticles, dest) + end if + + end subroutine s_mpi_sendrecv_solid_particles + + !> This resets the collision force buffers + impure subroutine s_reset_force_buffers() + + force_send_counts = 0 + force_recv_counts = 0 + force_send_ids = 0 + force_send_vals = 0._wp + + $:GPU_UPDATE(device='[force_send_counts, force_send_ids, force_send_vals]') + + end subroutine s_reset_force_buffers + + !> This adds the forces to the buffer arrays for mpi transfer + impure subroutine s_add_force_to_send_buffer(dest_rank, gid, force) + + $:GPU_ROUTINE(function_name='s_add_force_to_send_buffer', parallelism='[seq]') + + integer, intent(in) :: dest_rank, gid + real(wp), intent(in), dimension(3) :: force + integer :: idx + + $:GPU_ATOMIC(atomic='capture') + force_send_counts(dest_rank) = force_send_counts(dest_rank) + 1 + idx = force_send_counts(dest_rank) + $:END_GPU_ATOMIC_CAPTURE() + + force_send_ids(dest_rank, idx) = gid + force_send_vals(dest_rank, idx, 1) = force(1) + force_send_vals(dest_rank, idx, 2) = force(2) + force_send_vals(dest_rank, idx, 3) = force(3) + + end subroutine s_add_force_to_send_buffer + + !> This communicates the collision forces across neighbor mpi ranks + impure subroutine s_transfer_collision_forces(total_recv, force_recv_ids, force_recv_vals) + + integer, intent(inout) :: total_recv + integer, intent(inout) :: force_recv_ids(:) + real(wp), intent(inout) :: force_recv_vals(:) + +#ifdef MFC_MPI + integer :: ierr !< Generic flag used to identify and report MPI errors + integer :: i, j, k, l, idx, total_send, recv_tag, send_tag, partner, recv_count, send_count + integer :: send_displs(0:num_procs - 1), recv_displs(0:num_procs - 1) + integer :: sendcounts_vals(0:num_procs - 1), recvcounts_vals(0:num_procs - 1) + integer :: senddispls_vals(0:num_procs - 1), recvdispls_vals(0:num_procs - 1) + ! Local request arrays sized for 2 requests per neighbor (IDs + values) + integer :: coll_send_requests(2*MAX_NEIGHBORS), coll_recv_requests(2*MAX_NEIGHBORS) + + $:GPU_UPDATE(host='[force_send_counts, force_send_ids, force_send_vals]') + + ! Phase 1: Exchange force counts with neighbors only + send_count = 0 + recv_count = 0 + + do l = 1, n_neighbors + i = neighbor_list(l, 1) + j = neighbor_list(l, 2) + k = neighbor_list(l, 3) + partner = neighbor_ranks(i, j, k) + recv_tag = neighbor_tag(i, j, k) + send_tag = neighbor_tag(-i, -j, -k) + + recv_count = recv_count + 1 + call MPI_Irecv(force_recv_counts(partner), 1, MPI_INTEGER, partner, recv_tag, MPI_COMM_WORLD, & + & recv_requests(recv_count), ierr) + + send_count = send_count + 1 + call MPI_Isend(force_send_counts(partner), 1, MPI_INTEGER, partner, send_tag, MPI_COMM_WORLD, & + & send_requests(send_count), ierr) + end do + + call MPI_Waitall(recv_count, recv_requests(1:recv_count), MPI_STATUSES_IGNORE, ierr) + call MPI_Waitall(send_count, send_requests(1:send_count), MPI_STATUSES_IGNORE, ierr) + + ! Compute displacements + send_displs(0) = 0 + recv_displs(0) = 0 + do i = 1, num_procs - 1 + send_displs(i) = send_displs(i - 1) + force_send_counts(i - 1) + recv_displs(i) = recv_displs(i - 1) + force_recv_counts(i - 1) + end do + + do i = 0, num_procs - 1 + sendcounts_vals(i) = 3*force_send_counts(i) + recvcounts_vals(i) = 3*force_recv_counts(i) + senddispls_vals(i) = 3*send_displs(i) + recvdispls_vals(i) = 3*recv_displs(i) + end do + + total_send = sum(force_send_counts) + total_recv = sum(force_recv_counts) + + ! Flatten send buffers + idx = 1 + do i = 0, num_procs - 1 + do j = 1, force_send_counts(i) + flat_send_ids(idx) = force_send_ids(i, j) + flat_send_vals(3*(idx - 1) + 1) = force_send_vals(i, j, 1) + flat_send_vals(3*(idx - 1) + 2) = force_send_vals(i, j, 2) + flat_send_vals(3*(idx - 1) + 3) = force_send_vals(i, j, 3) + idx = idx + 1 + end do + end do + + ! Phase 2: Exchange force data with neighbors only + send_count = 0 + recv_count = 0 + + do l = 1, n_neighbors + i = neighbor_list(l, 1) + j = neighbor_list(l, 2) + k = neighbor_list(l, 3) + partner = neighbor_ranks(i, j, k) + recv_tag = neighbor_tag(i, j, k) + send_tag = neighbor_tag(-i, -j, -k) + + if (force_recv_counts(partner) > 0) then + recv_count = recv_count + 1 + call MPI_Irecv(force_recv_ids(recv_displs(partner) + 1), force_recv_counts(partner), MPI_INTEGER, partner, & + & recv_tag, MPI_COMM_WORLD, coll_recv_requests(recv_count), ierr) + recv_count = recv_count + 1 + call MPI_Irecv(force_recv_vals(recvdispls_vals(partner) + 1), recvcounts_vals(partner), mpi_p, partner, & + & recv_tag + 1, MPI_COMM_WORLD, coll_recv_requests(recv_count), ierr) + end if + + if (force_send_counts(partner) > 0) then + send_count = send_count + 1 + call MPI_Isend(flat_send_ids(send_displs(partner) + 1), force_send_counts(partner), MPI_INTEGER, partner, & + & send_tag, MPI_COMM_WORLD, coll_send_requests(send_count), ierr) + send_count = send_count + 1 + call MPI_Isend(flat_send_vals(senddispls_vals(partner) + 1), sendcounts_vals(partner), mpi_p, partner, & + & send_tag + 1, MPI_COMM_WORLD, coll_send_requests(send_count), ierr) + end if + end do + + call MPI_Waitall(recv_count, coll_recv_requests(1:recv_count), MPI_STATUSES_IGNORE, ierr) + call MPI_Waitall(send_count, coll_send_requests(1:send_count), MPI_STATUSES_IGNORE, ierr) +#else + total_recv = 0 +#endif + + end subroutine s_transfer_collision_forces + + !! @param i, j, k Indices of the neighbor in the range [-1, 1] + !! @return tag Unique integer tag for the neighbor + integer function neighbor_tag(i, j, k) result(tag) + + integer, intent(in) :: i, j, k + + tag = (k + 1)*9 + (j + 1)*3 + (i + 1) + + end function neighbor_tag + + subroutine s_wrap_particle_positions(pos, posPrev, nbubs, dest) + + real(wp), dimension(:,:,:) :: pos, posPrev + integer :: nbubs, dest + integer :: i, q + real(wp) :: offset + + do i = 1, nbubs + if (periodic_bc(1)) then + offset = glb_bounds(1)%end - glb_bounds(1)%beg + if (pos(i, 1, dest) > x_cb(m + buff_size)) then + do q = 1, 2 + pos(i, 1, q) = pos(i, 1, q) - offset + posPrev(i, 1, q) = posPrev(i, 1, q) - offset + end do + end if + if (pos(i, 1, dest) < x_cb(-1 - buff_size)) then + do q = 1, 2 + pos(i, 1, q) = pos(i, 1, q) + offset + posPrev(i, 1, q) = posPrev(i, 1, q) + offset + end do + end if + end if + + if (periodic_bc(2)) then + offset = glb_bounds(2)%end - glb_bounds(2)%beg + if (pos(i, 2, dest) > y_cb(n + buff_size)) then + do q = 1, 2 + pos(i, 2, q) = pos(i, 2, q) - offset + posPrev(i, 2, q) = posPrev(i, 2, q) - offset + end do + end if + if (pos(i, 2, dest) < y_cb(-buff_size - 1)) then + do q = 1, 2 + pos(i, 2, q) = pos(i, 2, q) + offset + posPrev(i, 2, q) = posPrev(i, 2, q) + offset + end do + end if + end if + + if (periodic_bc(3)) then + offset = glb_bounds(3)%end - glb_bounds(3)%beg + if (pos(i, 3, dest) > z_cb(p + buff_size)) then + do q = 1, 2 + pos(i, 3, q) = pos(i, 3, q) - offset + posPrev(i, 3, q) = posPrev(i, 3, q) - offset + end do + end if + if (pos(i, 3, dest) < z_cb(-1 - buff_size)) then + do q = 1, 2 + pos(i, 3, q) = pos(i, 3, q) + offset + posPrev(i, 3, q) = posPrev(i, 3, q) + offset + end do + end if + end if + end do + + end subroutine s_wrap_particle_positions + impure subroutine s_mpi_send_random_number(phi_rn, num_freq) integer, intent(in) :: num_freq @@ -245,7 +1414,6 @@ contains #ifdef MFC_MPI integer :: ierr !< Generic flag used to identify and report MPI errors - call MPI_BCAST(phi_rn, num_freq, mpi_p, 0, MPI_COMM_WORLD, ierr) #endif diff --git a/src/simulation/m_particles_EL.fpp b/src/simulation/m_particles_EL.fpp new file mode 100644 index 0000000000..1674f07c6f --- /dev/null +++ b/src/simulation/m_particles_EL.fpp @@ -0,0 +1,2645 @@ +!> +!! @file m_particles_EL.fpp +!! @brief Contains module m_particles_EL + +#:include 'macros.fpp' + +!> @brief Euler-Lagrange solid particle solver with two-way coupling. +!! +!! Tracks non-deformable solid particles in compressible flow using Gaussian volume-averaging (Maeda & Colonius, J. Computational +!! Physics, 361, 2018). Supports multiple drag correlations, soft-sphere DEM collisions, pressure gradient and added mass forces. +!! Derived from the m_bubbles_EL module. Kernel functions are in m_particles_EL_kernels. +module m_particles_EL + + use m_global_parameters !< Definitions of the global parameters + use m_mpi_proxy !< Message passing interface (MPI) module proxy + use m_particles_EL_kernels !< Definitions of the kernel functions + use m_variables_conversion !< State variables type conversion procedures + use m_compile_specific + use m_boundary_common + use m_helper_basic !< Functions to compare floating point numbers + use m_sim_helpers + use m_helper + use m_mpi_common + use m_ibm + + implicit none + + real(wp) :: next_write_time + integer, allocatable, dimension(:,:) :: lag_part_id !< Global and local IDs + integer, allocatable, dimension(:) :: gid_to_local + real(wp), allocatable, dimension(:) :: particle_R0 !< Initial particle radius + real(wp), allocatable, dimension(:) :: Rmax_stats_part !< Maximum radius + real(wp), allocatable, dimension(:) :: Rmin_stats_part !< Minimum radius + $:GPU_DECLARE(create='[lag_part_id, gid_to_local, particle_R0, Rmax_stats_part, Rmin_stats_part]') + + real(wp), allocatable, dimension(:) :: particle_mass !< Particle Mass + $:GPU_DECLARE(create='[particle_mass]') + real(wp), allocatable, dimension(:) :: p_AM !< Particle Added Mass + $:GPU_DECLARE(create='[p_AM]') + + integer, allocatable, dimension(:) :: p_owner_rank !< MPI rank that owns this particle + $:GPU_DECLARE(create='[p_owner_rank]') + + integer, allocatable, dimension(:) :: linked_list !< particle cell linked list + $:GPU_DECLARE(create='[linked_list]') + + integer, allocatable, dimension(:,:,:) :: particle_head !< particle heads at each cell + $:GPU_DECLARE(create='[particle_head]') + + ! Particle state arrays use dimensions (nParticles_glb, component, stage): component: 1=x, 2=y, 3=z for position/velocity stage: + ! 1=committed state at current time level, 2=intermediate RK stage value + + ! (nPart, 1 -> actual val or 2 -> temp val) + real(wp), allocatable, dimension(:,:) :: particle_rad !< Particle radius + $:GPU_DECLARE(create='[particle_rad]') + + ! (nPart, 1-> x or 2->y or 3 ->z, 1 -> actual or 2 -> temporal val) + real(wp), allocatable, dimension(:,:,:) :: particle_pos !< Particle's position + real(wp), allocatable, dimension(:,:,:) :: particle_posPrev !< Particle's previous position + real(wp), allocatable, dimension(:,:,:) :: particle_vel !< Particle's velocity + real(wp), allocatable, dimension(:,:,:) :: particle_s !< Particle's computational cell position in real format + $:GPU_DECLARE(create='[particle_pos, particle_posPrev, particle_vel, particle_s]') + ! (nPart, 1-> x or 2->y or 3 ->z, time-stage) + real(wp), allocatable, dimension(:,:) :: particle_draddt !< Time derivative of particle's radius + real(wp), allocatable, dimension(:,:,:) :: particle_dposdt !< Time derivative of the particle's position + real(wp), allocatable, dimension(:,:,:) :: particle_dveldt !< Time derivative of the particle's velocity + $:GPU_DECLARE(create='[particle_draddt, particle_dposdt, particle_dveldt]') + + integer, private :: lag_num_ts !< Number of time stages in the time-stepping scheme + $:GPU_DECLARE(create='[lag_num_ts]') + + real(wp) :: Rmax_glb, Rmin_glb !< Global maximum and minimum R/R0 ratio across all particles + !> Eulerian projection of particle data (volume fraction, momentum, sources) + type(scalar_field), dimension(:), allocatable :: q_particles + integer :: q_particles_idx !< Size of the q vector field for particle cell (q)uantities + integer, parameter :: alphaf_id = 1 + integer, parameter :: alphaupx_id = 2 !< x particle momentum index + integer, parameter :: alphaupy_id = 3 !< y particle momentum index + integer, parameter :: alphaupz_id = 4 !< z particle momentum index + integer, parameter :: Smx_id = 5 + integer, parameter :: Smy_id = 6 + integer, parameter :: Smz_id = 7 + integer, parameter :: SE_id = 8 + + !> Interpolated Eulerian field gradients at particle locations + type(scalar_field), dimension(:), allocatable :: field_vars !< For cell quantities (field gradients, etc.) + integer, parameter :: dPx_id = 1 !< Spatial pressure gradient in x, y, and z + integer, parameter :: dPy_id = 2 + integer, parameter :: dPz_id = 3 + integer, parameter :: drhox_id = 4 !< Spatial density gradient in x, y, and z + integer, parameter :: drhoy_id = 5 + integer, parameter :: drhoz_id = 6 + integer, parameter :: dufx_id = 7 !< Spatial velocity gradient in x, y, and z + integer, parameter :: dufy_id = 8 + integer, parameter :: dufz_id = 9 + integer, parameter :: dalphafx_id = 10 !< Spatial fluid volume fraction gradient in x, y, and z + integer, parameter :: dalphafy_id = 11 + integer, parameter :: dalphafz_id = 12 + integer, parameter :: dalphap_upx_id = 13 !< Spatial particle momentum gradient in x, y, and z + integer, parameter :: dalphap_upy_id = 14 + integer, parameter :: dalphap_upz_id = 15 + integer, parameter :: nField_vars = 15 + type(scalar_field), dimension(:), allocatable :: weights_x_interp !< For precomputing weights + type(scalar_field), dimension(:), allocatable :: weights_y_interp !< For precomputing weights + type(scalar_field), dimension(:), allocatable :: weights_z_interp !< For precomputing weights + integer :: nWeights_interp + type(scalar_field), dimension(:), allocatable :: weights_x_grad !< For precomputing weights + type(scalar_field), dimension(:), allocatable :: weights_y_grad !< For precomputing weights + type(scalar_field), dimension(:), allocatable :: weights_z_grad !< For precomputing weights + integer :: nWeights_grad + + $:GPU_DECLARE(create='[Rmax_glb, Rmin_glb, q_particles, q_particles_idx, field_vars]') + $:GPU_DECLARE(create='[weights_x_interp, weights_y_interp, weights_z_interp, nWeights_interp]') + $:GPU_DECLARE(create='[weights_x_grad, weights_y_grad, weights_z_grad, nWeights_grad]') + + ! Particle Source terms for fluid coupling + real(wp), allocatable, dimension(:,:) :: f_p !< force on each particle + $:GPU_DECLARE(create='[f_p]') + + real(wp), allocatable, dimension(:) :: gSum !< gaussian sum for each particle + $:GPU_DECLARE(create='[gSum]') + + integer, allocatable :: force_recv_ids(:) !< ids of collision forces received from other ranks + real(wp), allocatable :: force_recv_vals(:) !< collision forces received from other ranks + $:GPU_DECLARE(create='[force_recv_ids, force_recv_vals]') + + integer, parameter :: LAG_EVOL_ID = 11 ! File id for lag_bubbles_evol_*.dat + integer, parameter :: LAG_STATS_ID = 12 ! File id for stats_lag_bubbles_*.dat + integer, parameter :: LAG_VOID_ID = 13 ! File id for voidfraction.dat + integer, allocatable, dimension(:) :: keep_bubble + integer, allocatable, dimension(:,:) :: wrap_bubble_loc, wrap_bubble_dir + $:GPU_DECLARE(create='[keep_bubble]') + $:GPU_DECLARE(create='[wrap_bubble_loc, wrap_bubble_dir]') + + integer :: error_flag ! Error flag for collisions + $:GPU_DECLARE(create='[error_flag]') + + integer, parameter :: ncc = 1 !< Number of collisions cells at boundaries + real(wp) :: eps_overlap = 1.e-12 + +contains + + !> Initializes the lagrangian subgrid particle solver + !! @param q_cons_vf Initial conservative variables + impure subroutine s_initialize_particles_EL_module(q_cons_vf, bc_type) + + type(scalar_field), dimension(sys_size), intent(inout) :: q_cons_vf + type(integer_field), dimension(1:num_dims,1:2), intent(in) :: bc_type + integer :: nParticles_glb, i, j, k, nf, l, npts + + ! PRIM TO CONS VARIABLES + real(wp) :: dyn_pres, pi_inf, qv, gamma, pres, T + real(wp) :: rhou, alpharhou, rho_f, alpharho + real(wp), dimension(3) :: fluid_vel + real(wp) :: rhoYks(1:num_species) + integer :: save_count + real(wp) :: qtime + real(wp) :: myR, func_sum + real(wp), dimension(3) :: myPos, myVel, myForce + integer, dimension(3) :: cell + logical :: only_beta + + only_beta = .true. + + next_write_time = 0._wp + + if (cfl_dt) then + save_count = n_start + qtime = n_start*t_save + else + save_count = t_step_start + qtime = t_step_start*dt + end if + + pi_inf = 0._wp + qv = 0._wp + gamma = gammas(1) + + ! Setting number of time-stages for selected time-stepping scheme + lag_num_ts = time_stepper + + ! Allocate space for the Eulerian fields needed to map the effect of the particles + if (lag_params%solver_approach == 1) then + ! One-way coupling + q_particles_idx = 1 ! For tracking volume fraction + else if (lag_params%solver_approach == 2) then + ! Two-way coupling + q_particles_idx = 8 ! For tracking volume fraction(1), x-mom(2), y-mom(3), z-mom(4), and energy(5) sources, and alpha_p u_p (x(6),y(7),z(8)) + else + call s_mpi_abort('Please check the lag_params%solver_approach input') + end if + + nWeights_interp = lag_params%interpolation_order + 1 + nWeights_grad = fd_order + 1 + + pcomm_coords(1)%beg = x_cb(-1) + pcomm_coords(1)%end = x_cb(m) + $:GPU_UPDATE(device='[pcomm_coords(1)]') + if (n > 0) then + pcomm_coords(2)%beg = y_cb(-1) + pcomm_coords(2)%end = y_cb(n) + $:GPU_UPDATE(device='[pcomm_coords(2)]') + if (p > 0) then + pcomm_coords(3)%beg = z_cb(-1) + pcomm_coords(3)%end = z_cb(p) + $:GPU_UPDATE(device='[pcomm_coords(3)]') + end if + end if + + pcomm_coords_ghost(1)%beg = x_cb(-1 + ncc) + pcomm_coords_ghost(1)%end = x_cb(m - ncc) + $:GPU_UPDATE(device='[pcomm_coords_ghost(1)]') + if (n > 0) then + pcomm_coords_ghost(2)%beg = y_cb(-1 + ncc) + pcomm_coords_ghost(2)%end = y_cb(n - ncc) + $:GPU_UPDATE(device='[pcomm_coords_ghost(2)]') + if (p > 0) then + pcomm_coords_ghost(3)%beg = z_cb(-1 + ncc) + pcomm_coords_ghost(3)%end = z_cb(p - ncc) + $:GPU_UPDATE(device='[pcomm_coords_ghost(3)]') + end if + end if + + $:GPU_UPDATE(device='[lag_num_ts, q_particles_idx]') + + @:ALLOCATE(q_particles(1:q_particles_idx)) + do i = 1, q_particles_idx + @:ALLOCATE(q_particles(i)%sf(idwbuff(1)%beg:idwbuff(1)%end, idwbuff(2)%beg:idwbuff(2)%end, & + & idwbuff(3)%beg:idwbuff(3)%end)) + @:ACC_SETUP_SFs(q_particles(i)) + end do + + @:ALLOCATE(field_vars(1:nField_vars)) + do i = 1, nField_vars + @:ALLOCATE(field_vars(i)%sf(idwbuff(1)%beg:idwbuff(1)%end, idwbuff(2)%beg:idwbuff(2)%end, & + & idwbuff(3)%beg:idwbuff(3)%end)) + @:ACC_SETUP_SFs(field_vars(i)) + end do + + @:ALLOCATE(weights_x_interp(1:nWeights_interp)) + do i = 1, nWeights_interp + @:ALLOCATE(weights_x_interp(i)%sf(idwbuff(1)%beg:idwbuff(1)%end,1:1,1:1)) + @:ACC_SETUP_SFs(weights_x_interp(i)) + end do + + @:ALLOCATE(weights_y_interp(1:nWeights_interp)) + do i = 1, nWeights_interp + @:ALLOCATE(weights_y_interp(i)%sf(idwbuff(2)%beg:idwbuff(2)%end,1:1,1:1)) + @:ACC_SETUP_SFs(weights_y_interp(i)) + end do + + @:ALLOCATE(weights_z_interp(1:nWeights_interp)) + do i = 1, nWeights_interp + @:ALLOCATE(weights_z_interp(i)%sf(idwbuff(3)%beg:idwbuff(3)%end,1:1,1:1)) + @:ACC_SETUP_SFs(weights_z_interp(i)) + end do + + @:ALLOCATE(weights_x_grad(1:nWeights_grad)) + do i = 1, nWeights_grad + @:ALLOCATE(weights_x_grad(i)%sf(idwbuff(1)%beg:idwbuff(1)%end,1:1,1:1)) + @:ACC_SETUP_SFs(weights_x_grad(i)) + end do + + @:ALLOCATE(weights_y_grad(1:nWeights_grad)) + do i = 1, nWeights_grad + @:ALLOCATE(weights_y_grad(i)%sf(idwbuff(2)%beg:idwbuff(2)%end,1:1,1:1)) + @:ACC_SETUP_SFs(weights_y_grad(i)) + end do + + @:ALLOCATE(weights_z_grad(1:nWeights_grad)) + do i = 1, nWeights_grad + @:ALLOCATE(weights_z_grad(i)%sf(idwbuff(3)%beg:idwbuff(3)%end,1:1,1:1)) + @:ACC_SETUP_SFs(weights_z_grad(i)) + end do + + ! Allocating space for lagrangian variables + nParticles_glb = lag_params%nParticles_glb + + @:ALLOCATE(lag_part_id(1:nParticles_glb, 1:2)) + @:ALLOCATE(gid_to_local(1:nParticles_glb)) + @:ALLOCATE(particle_R0(1:nParticles_glb)) + @:ALLOCATE(Rmax_stats_part(1:nParticles_glb)) + @:ALLOCATE(Rmin_stats_part(1:nParticles_glb)) + @:ALLOCATE(particle_mass(1:nParticles_glb)) + @:ALLOCATE(p_AM(1:nParticles_glb)) + @:ALLOCATE(p_owner_rank(1:nParticles_glb)) + @:ALLOCATE(particle_rad(1:nParticles_glb, 1:2)) + @:ALLOCATE(particle_pos(1:nParticles_glb, 1:3, 1:2)) + @:ALLOCATE(particle_posPrev(1:nParticles_glb, 1:3, 1:2)) + @:ALLOCATE(particle_vel(1:nParticles_glb, 1:3, 1:2)) + @:ALLOCATE(particle_s(1:nParticles_glb, 1:3, 1:2)) + @:ALLOCATE(particle_draddt(1:nParticles_glb, 1:lag_num_ts)) + @:ALLOCATE(particle_dposdt(1:nParticles_glb, 1:3, 1:lag_num_ts)) + @:ALLOCATE(particle_dveldt(1:nParticles_glb, 1:3, 1:lag_num_ts)) + @:ALLOCATE(f_p(1:nParticles_glb, 1:3)) + @:ALLOCATE(gSum(1:nParticles_glb)) + + @:ALLOCATE(linked_list(1:nParticles_glb)) + + @:ALLOCATE(particle_head(idwbuff(1)%beg:idwbuff(1)%end, idwbuff(2)%beg:idwbuff(2)%end, idwbuff(3)%beg:idwbuff(3)%end)) + + @:ALLOCATE(force_recv_ids(1:lag_params%nParticles_glb)) + @:ALLOCATE(force_recv_vals(1:3*lag_params%nParticles_glb)) + + @:ALLOCATE(keep_bubble(1:nParticles_glb)) + @:ALLOCATE(wrap_bubble_loc(1:nParticles_glb, 1:num_dims), wrap_bubble_dir(1:nParticles_glb, 1:num_dims)) + + if (adap_dt .and. f_is_default(adap_dt_tol)) adap_dt_tol = dflt_adap_dt_tol + + if (num_procs > 1) call s_initialize_solid_particles_mpi(lag_num_ts) + + ! Starting particles + if (lag_params%write_void_evol) call s_open_void_evol + if (lag_params%write_bubbles) call s_open_lag_bubble_evol() + if (lag_params%write_bubbles_stats) call s_open_lag_particle_stats() + + if (lag_params%vel_model > 0) then + moving_lag_particles = .true. + lag_pressure_force = lag_params%pressure_force + lag_gravity_force = lag_params%gravity_force + lag_vel_model = lag_params%vel_model + lag_drag_model = lag_params%drag_model + end if + + $:GPU_UPDATE(device='[moving_lag_particles, lag_pressure_force, lag_gravity_force, lag_vel_model, lag_drag_model]') + + ! Allocate cell list arrays for atomic-free Gaussian smearing + @:ALLOCATE(cell_list_start(0:m, 0:n, 0:p)) + @:ALLOCATE(cell_list_count(0:m, 0:n, 0:p)) + @:ALLOCATE(cell_list_idx(1:lag_params%nParticles_glb)) + + call s_read_input_particles(q_cons_vf, bc_type) + + call s_reset_cell_vars() + + $:GPU_PARALLEL_LOOP(private='[k, cell, myR, myPos, myVel, myForce, func_sum]',copyin='[only_beta]') + do k = 1, n_el_particles_loc + cell = fd_number - buff_size + call s_locate_cell(particle_pos(k,1:3,1), cell, particle_s(k,1:3,1)) + + myR = particle_R0(k) + myPos = particle_pos(k,1:3,1) + myVel = particle_vel(k,1:3,1) + myForce = f_p(k,:) + ! Compute the total gaussian contribution for each particle for normalization + call s_compute_gaussian_contribution(myR, myPos, cell, func_sum) + gSum(k) = func_sum + + call s_gaussian_atomic(myR, myVel, myPos, myForce, func_sum, cell, q_particles, only_beta) + end do + $:END_GPU_PARALLEL_LOOP() + + call s_finalize_beta_field(bc_type, only_beta) + + npts = (nWeights_interp - 1)/2 + call s_compute_barycentric_weights(npts) ! For interpolation + + npts = (nWeights_grad - 1)/2 + call s_compute_fornberg_fd_weights(npts) ! For finite differences + + if (lag_params%solver_approach == 2) then + if (save_count == 0) then + !> Correcting initial conditions so they account for particles + $:GPU_PARALLEL_LOOP(private='[i, j, k, dyn_pres, fluid_vel, rho_f, alpharho, rhou, alpharhou]', collapse=3, & + & copyin = '[pi_inf, qv, gamma, rhoYks]') + do k = idwint(3)%beg, idwint(3)%end + do j = idwint(2)%beg, idwint(2)%end + do i = idwint(1)%beg, idwint(1)%end + !!!!!!!!! Mass + do l = 1, num_fluids ! num_fluid is just 1 right now + rho_f = q_cons_vf(l)%sf(i, j, k) + alpharho = q_particles(alphaf_id)%sf(i, j, k)*rho_f + q_cons_vf(l)%sf(i, j, k) = alpharho + end do + + !!!!!!!!! Momentum + dyn_pres = 0._wp + do l = momxb, momxe + fluid_vel(l - momxb + 1) = q_cons_vf(l)%sf(i, j, k)/rho_f + rhou = q_cons_vf(l)%sf(i, j, k) + alpharhou = q_particles(alphaf_id)%sf(i, j, k)*rhou + q_cons_vf(l)%sf(i, j, k) = alpharhou + dyn_pres = dyn_pres + q_cons_vf(l)%sf(i, j, k)*fluid_vel(l - momxb + 1)/2._wp + end do + + !!!!!!!!!Energy + call s_compute_pressure(q_cons_vf(E_idx)%sf(i, j, k), q_cons_vf(alf_idx)%sf(i, j, k), dyn_pres, & + & pi_inf, gamma, alpharho, qv, rhoYks, pres, T) + + q_cons_vf(E_idx)%sf(i, j, k) = gamma*pres + dyn_pres + pi_inf + qv ! Updating energy in cons + end do + end do + end do + $:END_GPU_PARALLEL_LOOP() + end if + end if + + end subroutine s_initialize_particles_EL_module + + !> Initialize particle data from input file or generate initial conditions + !! @param q_cons_vf Conservative variables + impure subroutine s_read_input_particles(q_cons_vf, bc_type) + + type(scalar_field), dimension(sys_size), intent(inout) :: q_cons_vf + type(integer_field), dimension(1:num_dims,1:2), intent(in) :: bc_type + real(wp), dimension(8) :: inputParticle + real(wp) :: qtime + integer :: id, particle_id, save_count + integer :: i, ios + logical :: file_exist, indomain + integer, dimension(3) :: cell + character(LEN=path_len + 2*name_len) :: path_D_dir + + ! Initialize number of particles + + particle_id = 0 + id = 0 + + ! Read the input lag_bubble file or restart point + if (cfl_dt) then + save_count = n_start + qtime = n_start*t_save + else + save_count = t_step_start + qtime = t_step_start*dt + end if + + if (save_count == 0) then + if (proc_rank == 0) print *, 'Reading lagrange particles input file.' + call my_inquire(trim(lag_params%input_path), file_exist) + if (file_exist) then + open (94, file=trim(lag_params%input_path), form='formatted', iostat=ios) + do while (ios == 0) + read (94, *, iostat=ios) (inputParticle(i), i=1, 8) + if (ios /= 0) cycle + indomain = particle_in_domain_physical(inputParticle(1:3)) + id = id + 1 + if (id > lag_params%nParticles_glb .and. proc_rank == 0) then + call s_mpi_abort("Current number of particles is larger than nParticles_glb") + end if + if (indomain) then + particle_id = particle_id + 1 + call s_add_particles(inputParticle, q_cons_vf, particle_id) + lag_part_id(particle_id, 1) = id ! global ID + lag_part_id(particle_id, 2) = particle_id ! local ID + n_el_particles_loc = particle_id ! local number of particles + end if + end do + close (94) + else + call s_mpi_abort("Initialize the lagrange particles in " // trim(lag_params%input_path)) + end if + else + if (proc_rank == 0) print *, 'Restarting lagrange particles at save_count: ', save_count + call s_restart_bubbles(particle_id, save_count) + end if + + print *, " Lagrange parrticles running, in proc", proc_rank, "number:", particle_id, "/", id + + if (num_procs > 1) then + call s_mpi_reduce_int_sum(n_el_particles_loc, n_el_particles_glb) + else + n_el_particles_glb = n_el_particles_loc + end if + + if (proc_rank == 0) then + if (n_el_particles_glb == 0) call s_mpi_abort('No particles in the domain. Check ' // trim(lag_params%input_path)) + end if + + $:GPU_UPDATE(device='[particles_lagrange, lag_params]') + + $:GPU_UPDATE(device='[lag_part_id, particle_R0, Rmax_stats_part, Rmin_stats_part, particle_mass, f_p, p_AM, p_owner_rank, & + & gid_to_local, particle_rad, particle_pos, particle_posPrev, particle_vel, particle_s, particle_draddt, & + & particle_dposdt, particle_dveldt, n_el_particles_loc]') + + Rmax_glb = min(dflt_real, -dflt_real) + Rmin_glb = max(dflt_real, -dflt_real) + $:GPU_UPDATE(device='[Rmax_glb, Rmin_glb]') + + $:GPU_UPDATE(device='[dx, dy, dz, x_cb, x_cc, y_cb, y_cc, z_cb, z_cc]') + + ! Populate temporal variables + call s_transfer_data_to_tmp_particles() + + if (save_count == 0) then + ! Create ./D directory + if (proc_rank == 0) then + write (path_D_dir, '(A,I0,A,I0)') trim(case_dir) // '/D' + call my_inquire(trim(path_D_dir), file_exist) + if (.not. file_exist) call s_create_directory(trim(path_D_dir)) + end if + call s_mpi_barrier() + call s_write_restart_lag_particles(save_count) ! Needed for post_processing + if (lag_params%write_void_evol) call s_write_void_evol_particles(qtime) + end if + + if (lag_params%write_bubbles) call s_write_lag_particle_evol(qtime) + + end subroutine s_read_input_particles + + !> The purpose of this procedure is to obtain the information of the particles when starting fresh + !! @param inputPart Particle information + !! @param q_cons_vf Conservative variables + !! @param part_id Local id of the particle + impure subroutine s_add_particles(inputPart, q_cons_vf, part_id) + + type(scalar_field), dimension(sys_size), intent(in) :: q_cons_vf + real(wp), dimension(8), intent(in) :: inputPart + integer, intent(in) :: part_id + integer :: i + real(wp) :: pliq, volparticle, concvap, totalmass, kparticle, cpparticle + real(wp) :: omegaN_local, PeG, PeT, rhol, pcrit, qv, gamma, pi_inf, dynP + integer, dimension(3) :: cell + real(wp), dimension(2) :: Re + real(wp) :: massflag, heatflag, Re_trans, Im_trans, myR, func_sum + real(wp), dimension(3) :: myPos, myVel + + massflag = 0._wp + heatflag = 0._wp + if (lag_params%massTransfer_model) massflag = 1._wp + if (lag_params%heatTransfer_model) heatflag = 1._wp + + particle_R0(part_id) = inputPart(7) + Rmax_stats_part(part_id) = min(dflt_real, -dflt_real) + Rmin_stats_part(part_id) = max(dflt_real, -dflt_real) + particle_rad(part_id, 1) = inputPart(7) + particle_pos(part_id,1:3,1) = inputPart(1:3) + particle_posPrev(part_id,1:3,1) = particle_pos(part_id,1:3,1) + particle_vel(part_id,1:3,1) = inputPart(4:6) + + ! Initialize Particle Sources + f_p(part_id,1:3) = 0._wp + p_AM(part_id) = 0._wp + p_owner_rank(part_id) = proc_rank + gid_to_local(part_id) = -1 + + if (cyl_coord .and. p == 0) then + particle_pos(part_id, 2, 1) = sqrt(particle_pos(part_id, 2, 1)**2._wp + particle_pos(part_id, 3, 1)**2._wp) + ! Storing azimuthal angle (-Pi to Pi)) into the third coordinate variable + particle_pos(part_id, 3, 1) = atan2(inputPart(3), inputPart(2)) + particle_posPrev(part_id,1:3,1) = particle_pos(part_id,1:3,1) + end if + + cell = fd_number - buff_size + call s_locate_cell(particle_pos(part_id,1:3,1), cell, particle_s(part_id,1:3,1)) + + ! Check if the particle is located in the ghost cell of a symmetric, or wall boundary + if ((any(bc_x%beg == (/BC_REFLECTIVE, BC_CHAR_SLIP_WALL, BC_SLIP_WALL, & + & BC_NO_SLIP_WALL/)) .and. cell(1) < 0) .or. (any(bc_x%end == (/BC_REFLECTIVE, BC_CHAR_SLIP_WALL, BC_SLIP_WALL, & + & BC_NO_SLIP_WALL/)) .and. cell(1) > m) .or. (any(bc_y%beg == (/BC_REFLECTIVE, BC_CHAR_SLIP_WALL, BC_SLIP_WALL, & + & BC_NO_SLIP_WALL/)) .and. cell(2) < 0) .or. (any(bc_y%end == (/BC_REFLECTIVE, BC_CHAR_SLIP_WALL, BC_SLIP_WALL, & + & BC_NO_SLIP_WALL/)) .and. cell(2) > n)) then + call s_mpi_abort("Lagrange particle is in the ghost cells of a symmetric or wall boundary.") + end if + + if (p > 0) then + if ((any(bc_z%beg == (/BC_REFLECTIVE, BC_CHAR_SLIP_WALL, BC_SLIP_WALL, & + & BC_NO_SLIP_WALL/)) .and. cell(3) < 0) .or. (any(bc_z%end == (/BC_REFLECTIVE, BC_CHAR_SLIP_WALL, BC_SLIP_WALL, & + & BC_NO_SLIP_WALL/)) .and. cell(3) > p)) then + call s_mpi_abort("Lagrange particle is in the ghost cells of a symmetric or wall boundary.") + end if + end if + + ! Initial particle mass + volparticle = 4._wp/3._wp*pi*particle_R0(part_id)**3 ! volume + particle_mass(part_id) = volparticle*rho0ref_particle ! mass + if (particle_mass(part_id) <= 0._wp) then + call s_mpi_abort("The initial particle mass is negative or zero. Check the particle file.") + end if + + end subroutine s_add_particles + + !> Read particle data from a restart checkpoint + !! @param part_id Local ID of the particle + !! @param save_count File identifier + impure subroutine s_restart_bubbles(part_id, save_count) + + integer, intent(inout) :: part_id, save_count + character(LEN=path_len + 2*name_len) :: file_loc + real(wp) :: file_time, file_dt + integer :: file_num_procs, file_tot_part, tot_part + +#ifndef MFC_MPI + @:PROHIBIT(.true., "Lagrangian particle restart requires MPI (--mpi)") +#else + real(wp), dimension(20) :: inputvals + integer, dimension(MPI_STATUS_SIZE) :: status + integer(kind=MPI_OFFSET_KIND) :: disp + integer :: view + integer, dimension(3) :: cell + logical :: indomain, particle_file, file_exist + integer, dimension(2) :: gsizes, lsizes, start_idx_part + integer :: ifile, ierr, tot_data, id + integer :: i + integer, dimension(:), allocatable :: proc_particle_counts + real(wp), dimension(1:1,1:lag_io_vars) :: dummy + dummy = 0._wp + + ! Construct file path + write (file_loc, '(A,I0,A)') 'lag_bubbles_', save_count, '.dat' + file_loc = trim(case_dir) // '/restart_data' // trim(mpiiofs) // trim(file_loc) + + ! Check if file exists + inquire (FILE=trim(file_loc), EXIST=file_exist) + if (.not. file_exist) then + call s_mpi_abort('Restart file ' // trim(file_loc) // ' does not exist!') + end if + + if (.not. parallel_io) return + + if (proc_rank == 0) then + call MPI_FILE_OPEN(MPI_COMM_SELF, file_loc, MPI_MODE_RDONLY, mpi_info_int, ifile, ierr) + + call MPI_FILE_READ(ifile, file_tot_part, 1, MPI_INTEGER, status, ierr) + call MPI_FILE_READ(ifile, file_time, 1, mpi_p, status, ierr) + call MPI_FILE_READ(ifile, file_dt, 1, mpi_p, status, ierr) + call MPI_FILE_READ(ifile, file_num_procs, 1, MPI_INTEGER, status, ierr) + + call MPI_FILE_CLOSE(ifile, ierr) + end if + + call MPI_BCAST(file_tot_part, 1, MPI_INTEGER, 0, MPI_COMM_WORLD, ierr) + call MPI_BCAST(file_time, 1, mpi_p, 0, MPI_COMM_WORLD, ierr) + call MPI_BCAST(file_dt, 1, mpi_p, 0, MPI_COMM_WORLD, ierr) + call MPI_BCAST(file_num_procs, 1, MPI_INTEGER, 0, MPI_COMM_WORLD, ierr) + + allocate (proc_particle_counts(file_num_procs)) + + if (proc_rank == 0) then + call MPI_FILE_OPEN(MPI_COMM_SELF, file_loc, MPI_MODE_RDONLY, mpi_info_int, ifile, ierr) + + ! Skip to processor counts position + disp = int(sizeof(file_tot_part) + 2*sizeof(file_time) + sizeof(file_num_procs), MPI_OFFSET_KIND) + call MPI_FILE_SEEK(ifile, disp, MPI_SEEK_SET, ierr) + call MPI_FILE_READ(ifile, proc_particle_counts, file_num_procs, MPI_INTEGER, status, ierr) + + call MPI_FILE_CLOSE(ifile, ierr) + end if + + call MPI_BCAST(proc_particle_counts, file_num_procs, MPI_INTEGER, 0, MPI_COMM_WORLD, ierr) + + ! Set time variables from file + mytime = file_time + dt = file_dt + + part_id = proc_particle_counts(proc_rank + 1) + + start_idx_part(1) = 0 + do i = 1, proc_rank + start_idx_part(1) = start_idx_part(1) + proc_particle_counts(i) + end do + + start_idx_part(2) = 0 + lsizes(1) = part_id + lsizes(2) = lag_io_vars + + gsizes(1) = file_tot_part + gsizes(2) = lag_io_vars + + if (part_id > 0) then + allocate (MPI_IO_DATA_lag_bubbles(part_id,1:lag_io_vars)) + + call MPI_TYPE_CREATE_SUBARRAY(2, gsizes, lsizes, start_idx_part, MPI_ORDER_FORTRAN, mpi_p, view, ierr) + call MPI_TYPE_COMMIT(view, ierr) + + call MPI_FILE_OPEN(MPI_COMM_WORLD, file_loc, MPI_MODE_RDONLY, mpi_info_int, ifile, ierr) + + ! Skip extended header + disp = int(sizeof(file_tot_part) + 2*sizeof(file_time) + sizeof(file_num_procs) & + & + file_num_procs*sizeof(proc_particle_counts(1)), MPI_OFFSET_KIND) + call MPI_FILE_SET_VIEW(ifile, disp, mpi_p, view, 'native', mpi_info_int, ierr) + + call MPI_FILE_READ_ALL(ifile, MPI_IO_DATA_lag_bubbles, lag_io_vars*part_id, mpi_p, status, ierr) + + call MPI_FILE_CLOSE(ifile, ierr) + call MPI_TYPE_FREE(view, ierr) + + n_el_particles_loc = part_id + + do i = 1, part_id + lag_part_id(i, 1) = int(MPI_IO_DATA_lag_bubbles(i, 1)) + particle_pos(i,1:3,1) = MPI_IO_DATA_lag_bubbles(i,2:4) + particle_posPrev(i,1:3,1) = MPI_IO_DATA_lag_bubbles(i,5:7) + particle_vel(i,1:3,1) = MPI_IO_DATA_lag_bubbles(i,8:10) + particle_rad(i, 1) = MPI_IO_DATA_lag_bubbles(i, 11) + particle_R0(i) = MPI_IO_DATA_lag_bubbles(i, 13) + Rmax_stats_part(i) = MPI_IO_DATA_lag_bubbles(i, 14) + Rmin_stats_part(i) = MPI_IO_DATA_lag_bubbles(i, 15) + particle_mass(i) = MPI_IO_DATA_lag_bubbles(i, 19) + cell = -buff_size + call s_locate_cell(particle_pos(i,1:3,1), cell, particle_s(i,1:3,1)) + end do + + deallocate (MPI_IO_DATA_lag_bubbles) + else + n_el_particles_loc = 0 + + call MPI_TYPE_CONTIGUOUS(0, mpi_p, view, ierr) + call MPI_TYPE_COMMIT(view, ierr) + + call MPI_FILE_OPEN(MPI_COMM_WORLD, file_loc, MPI_MODE_RDONLY, mpi_info_int, ifile, ierr) + + ! Skip extended header + disp = int(sizeof(file_tot_part) + 2*sizeof(file_time) + sizeof(file_num_procs) & + & + file_num_procs*sizeof(proc_particle_counts(1)), MPI_OFFSET_KIND) + call MPI_FILE_SET_VIEW(ifile, disp, mpi_p, view, 'native', mpi_info_int, ierr) + + call MPI_FILE_READ_ALL(ifile, dummy, 0, mpi_p, status, ierr) + + call MPI_FILE_CLOSE(ifile, ierr) + call MPI_TYPE_FREE(view, ierr) + end if + + if (proc_rank == 0) then + write (*, '(A,I0,A,I0)') 'Read ', file_tot_part, ' particles from restart file at t_step = ', save_count + write (*, '(A,E15.7,A,E15.7)') 'Restart time = ', mytime, ', dt = ', dt + end if + + deallocate (proc_particle_counts) +#endif + + end subroutine s_restart_bubbles + + !> Contains the particle dynamics subroutines. + !! @param q_cons_vf Conservative variables + !! @param q_prim_vf Primitive variables + !! @param rhs_vf Calculated change of conservative variables + !! @param t_step Current time step + !! @param stage Current stage in the time-stepper algorithm + subroutine s_compute_particle_EL_dynamics(q_prim_vf, bc_type, stage, vL_x, vL_y, vL_z, vR_x, vR_y, vR_z, rhs_vf) + + type(scalar_field), dimension(sys_size), intent(in) :: q_prim_vf + type(integer_field), dimension(1:num_dims,1:2), intent(in) :: bc_type + type(scalar_field), dimension(sys_size), intent(in) :: rhs_vf + integer, intent(in) :: stage + real(wp), dimension(idwbuff(1)%beg:,idwbuff(2)%beg:,idwbuff(3)%beg:,1:), intent(inout) :: vL_x, vL_y, vL_z + real(wp), dimension(idwbuff(1)%beg:,idwbuff(2)%beg:,idwbuff(3)%beg:,1:), intent(inout) :: vR_x, vR_y, vR_z + integer, dimension(3) :: cell, cellijk + real(wp) :: myMass, myR, myBeta_c, myBeta_t, myR0, myRe, mydrhodt, myVolumeFrac, myGamma, rmass_add, func_sum + real(wp), dimension(3) :: myVel, myPos, force_vec, s_cell + logical :: only_beta + integer :: k, l, i, j + + only_beta = .false. + + if (lag_params%pressure_force .or. lag_params%added_mass_model > 0) then + do l = 1, num_dims + if (l == 1) then + call s_gradient_field(vL_x, vR_x, field_vars(dPx_id)%sf, l, E_idx) + else if (l == 2) then + call s_gradient_field(vL_y, vR_y, field_vars(dPy_id)%sf, l, E_idx) + else if (l == 3) then + call s_gradient_field(vL_z, vR_z, field_vars(dPz_id)%sf, l, E_idx) + end if + end do + end if + + if (lag_params%added_mass_model > 0) then + do l = 1, num_dims + if (l == 1) then + call s_gradient_field(vL_x, vR_x, field_vars(drhox_id)%sf, l, 1) + else if (l == 2) then + call s_gradient_field(vL_y, vR_y, field_vars(drhoy_id)%sf, l, 1) + else if (l == 3) then + call s_gradient_field(vL_z, vR_z, field_vars(drhoz_id)%sf, l, 1) + end if + end do + end if + + myGamma = (1._wp/fluid_pp(1)%gamma) + 1._wp + if (viscous) then + myRe = 1._wp/fluid_pp(1)%Re(1) + else + ! TODO: Wire to a fluid parameter for non-air flows + myRe = 1.845e-5_wp + end if + + call nvtxStartRange("LAGRANGE-PARTICLE-DYNAMICS") + + !> Compute Fluid-Particle Forces (drag/pressure/added mass) and convert to particle acceleration + $:GPU_PARALLEL_LOOP(private='[i, k, l, cell, s_cell, myMass, myR, myR0, myPos, myVel, myVolumeFrac, force_vec, rmass_add, & + & func_sum, mydrhodt]', copyin='[stage, myGamma, myRe, only_beta]') + do k = 1, n_el_particles_loc + f_p(k,:) = 0._wp + p_owner_rank(k) = proc_rank + + s_cell = particle_s(k,1:3,2) + cell = int(s_cell(:)) + do i = 1, num_dims + if (s_cell(i) < 0._wp) cell(i) = cell(i) - 1 + end do + + ! Current particle state + myMass = particle_mass(k) + myR = particle_rad(k, 2) + myR0 = particle_R0(k) + myPos = particle_pos(k,:,2) + myVel = particle_vel(k,:,2) + myVolumeFrac = 1._wp - q_particles(alphaf_id)%sf(cell(1), cell(2), cell(3)) + mydrhodt = rhs_vf(1)%sf(cell(1), cell(2), cell(3)) + + particle_dposdt(k,:,stage) = 0._wp + particle_dveldt(k,:,stage) = 0._wp + particle_draddt(k, stage) = 0._wp + + call s_get_particle_force(myPos, myR, myVel, myMass, myRe, myGamma, myVolumeFrac, mydrhodt, cell, q_prim_vf, & + & field_vars, weights_x_interp, weights_y_interp, weights_z_interp, force_vec, rmass_add) + + p_AM(k) = rMass_add + f_p(k,:) = f_p(k,:) + force_vec(:) + + if (.not. lag_params%collision_force) then + myMass = particle_mass(k) + p_AM(k) + myVel = particle_vel(k,:,2) + do l = 1, num_dims + particle_dposdt(k, l, stage) = myVel(l) + particle_dveldt(k, l, stage) = f_p(k, l)/myMass + particle_draddt(k, stage) = 0._wp + end do + end if + + if (lag_params%solver_approach == 2) then + func_sum = gSum(k) + call s_gaussian_atomic(myR, myVel, myPos, force_vec, func_sum, cell, q_particles, only_beta) + end if + end do + $:END_GPU_PARALLEL_LOOP() + + if (lag_params%solver_approach == 2) then + call s_finalize_beta_field(bc_type, only_beta) + end if + + call nvtxStartRange("LAGRANGE-PARTICLE-COLLISIONS") + if (lag_params%collision_force) then + !> Compute Particle-Particle collision forces + call s_compute_particle_EL_collisions(stage, bc_type) + + $:GPU_PARALLEL_LOOP(private='[k, l, myMass, myVel]') + do k = 1, n_el_particles_loc + myMass = particle_mass(k) + p_AM(k) + myVel = particle_vel(k,:,2) + do l = 1, num_dims + particle_dposdt(k, l, stage) = myVel(l) + particle_dveldt(k, l, stage) = f_p(k, l)/myMass + particle_draddt(k, stage) = 0._wp + end do + end do + $:END_GPU_PARALLEL_LOOP() + end if + call nvtxEndRange + + call nvtxEndRange + + end subroutine s_compute_particle_EL_dynamics + + !> Compute inter-particle collision forces using a soft-sphere DEM model. Uses a cell-based linked list for O(N) neighbor + !! search. The contact force model is a spring-dashpot (Hertzian stiffness with viscous damping). Forces on particles owned by + !! other MPI ranks are buffered for later transfer. + subroutine s_compute_particle_EL_collisions(stage, bc_type) + + integer, intent(in) :: stage + type(integer_field), dimension(1:num_dims,1:2), intent(in) :: bc_type + integer, dimension(3) :: cell + real(wp), dimension(3) :: s_cell + integer, dimension(3) :: cellaux + integer :: i, k, l, q, ip, jp, kp, ii, jj, kk + logical :: celloutside + real(wp) :: pidtksp2, ksp, nu1, nu2, Rp1, Rp2, E1, E2, Estar, cor, rmag, Rstar, dij, eta_n, kappa_n, mp1, mp2, dt_loc + real(wp), dimension(3) :: xp1, xp2, vp1, vp2, v_rel, rpij, nij, vnij, Fnpp_ij, force_vec + integer :: kpz + integer :: total_recv + integer :: glb_id, count + integer :: n_el_particles_loc_before_ghost + + if (num_procs > 1) then + n_el_particles_loc_before_ghost = n_el_particles_loc + call s_reset_force_buffers() + call s_add_ghost_particles() + end if + + kpz = 0 + if (num_dims == 3) kpz = 1 + + ksp = 10._wp ! Spring stiffness multiplier + nu1 = 0.35_wp ! Poisson's ratio, particle 1 (glass/steel-like) + nu2 = 0.35_wp ! Poisson's ratio, particle 2 + E1 = 1.e9_wp ! Young's modulus [Pa], particle 1 + E2 = 1.e9_wp ! Young's modulus [Pa], particle 2 + cor = 0.7_wp ! Coefficient of restitution + + pidtksp2 = (pi**2)/((dt*ksp)**2) + + Estar = 1._wp/(((1._wp - nu1**2)/E1) + ((1._wp - nu2**2)/E2)) + Estar = (4._wp/3._wp)*Estar + + call s_reset_linked_list() + + call nvtxStartRange("LAGRANGE-PARTICLE-COLLISIONS") + error_flag = 0 + $:GPU_UPDATE(device='[error_flag]') + + $:GPU_PARALLEL_LOOP(private='[i, k, cell, ip, jp, kp, Rp1, xp1, mp1, vp1, kk, jj, ii, cellaux, q, Rp2, xp2, mp2, vp2, & + & v_rel, Rstar, rpij, rmag, nij, vnij, dij, kappa_n, eta_n, Fnpp_ij, force_vec, s_cell, celloutside, & + & count]', copyin='[ksp, nu1, nu2, E1, E2, cor, pidtksp2, Estar, kpz]') + do k = 1, n_el_particles_loc + if (.not. particle_in_domain_physical(particle_pos(k,1:3,2))) then + cycle + end if + + s_cell = particle_s(k,1:3,2) + cell = int(s_cell(:)) + do i = 1, num_dims + if (s_cell(i) < 0._wp) cell(i) = cell(i) - 1 + end do + + ip = cell(1) + jp = cell(2) + kp = cell(3) + + Rp1 = particle_rad(k, 2) + xp1 = particle_pos(k,:,2) + mp1 = particle_mass(k) + vp1 = particle_vel(k,:,2) + + do kk = kp - kpz, kp + kpz + do jj = jp - 1, jp + 1 + do ii = ip - 1, ip + 1 + cellaux(1) = ii + cellaux(2) = jj + cellaux(3) = kk + + call s_check_celloutside_wbuff(cellaux, celloutside) + + if (.not. celloutside) then + q = particle_head(ii, jj, kk) + ! Traverse linked list in that cell + + count = 0 + do while (q /= -1) + count = count + 1 + if (count > n_el_particles_loc) then + $:GPU_ATOMIC(atomic='write') + error_flag = 1 + exit + end if + + if (lag_part_id(q, 1) > lag_part_id(k, 1)) then + Rp2 = particle_rad(q, 2) + xp2 = particle_pos(q,:,2) + mp2 = particle_mass(q) + vp2 = particle_vel(q,:,2) + v_rel = vp2 - vp1 + + Rstar = (Rp1*Rp2)/(Rp1 + Rp2) + rpij = xp2 - xp1 + rmag = sqrt(rpij(1)**2 + rpij(2)**2 + rpij(3)**2) + rmag = max(rmag, eps_overlap) + nij = rpij/rmag + vnij = dot_product(v_rel, nij)*nij + dij = (Rp1 + Rp2) - rmag + + if (dij > 0._wp) then + kappa_n = min((pidtksp2*mp1), (pidtksp2*mp2), (Estar*sqrt(Rstar)*sqrt(abs(dij)))) + + eta_n = ((-2._wp*sqrt(kappa_n)*log(cor))/sqrt((log(cor))**2 + pi**2)) & + & *(1._wp/sqrt((1._wp/mp1) + (1._wp/mp2))) + + Fnpp_ij = -kappa_n*dij*nij - eta_n*vnij + + f_p(k,:) = f_p(k,:) + Fnpp_ij + + if (p_owner_rank(q) == proc_rank) then + ! f_p(q, :) = f_p(q, :) - Fnpp_ij + + $:GPU_ATOMIC(atomic='update') + f_p(q, 1) = f_p(q, 1) - Fnpp_ij(1) + + $:GPU_ATOMIC(atomic='update') + f_p(q, 2) = f_p(q, 2) - Fnpp_ij(2) + + $:GPU_ATOMIC(atomic='update') + f_p(q, 3) = f_p(q, 3) - Fnpp_ij(3) + else + call s_add_force_to_send_buffer(p_owner_rank(q), lag_part_id(q, 1), -Fnpp_ij) + end if + end if + end if + + q = linked_list(q) + end do + end if + end do + end do + end do + + !> Check each local particle for wall collisions + + call s_compute_wall_collisions(xp1, vp1, Rp1, mp1, Estar, pidtksp2, cor, force_vec) + f_p(k,:) = f_p(k,:) + force_vec + end do + $:END_GPU_PARALLEL_LOOP() + + call nvtxEndRange + + $:GPU_UPDATE(host='[error_flag]') + if (error_flag == 1) then + call s_mpi_abort("Linked list infinite loop detected") + end if + + if (num_procs > 1) then + n_el_particles_loc = n_el_particles_loc_before_ghost + $:GPU_UPDATE(device='[n_el_particles_loc]') + + total_recv = 0 + force_recv_ids = 0 + force_recv_vals = 0._wp + + call s_transfer_collision_forces(total_recv, force_recv_ids, force_recv_vals) + + $:GPU_UPDATE(device = '[force_recv_ids, force_recv_vals]') + + $:GPU_PARALLEL_LOOP(private='[i, k]',copyin = '[total_recv]') + do i = 1, total_recv + k = gid_to_local(force_recv_ids(i)) + if (k > 0) then + $:GPU_ATOMIC(atomic='update') + f_p(k, 1) = f_p(k, 1) + force_recv_vals(3*(i - 1) + 1) + + $:GPU_ATOMIC(atomic='update') + f_p(k, 2) = f_p(k, 2) + force_recv_vals(3*(i - 1) + 2) + + $:GPU_ATOMIC(atomic='update') + f_p(k, 3) = f_p(k, 3) + force_recv_vals(3*(i - 1) + 3) + end if + end do + $:END_GPU_PARALLEL_LOOP() + end if + + end subroutine s_compute_particle_EL_collisions + + !> This subroutine checks for particles at solid walls to compute a collision force + subroutine s_compute_wall_collisions(pos, vel, rad, mass, Es, pidtksp, core, wcol_force) + + $:GPU_ROUTINE(function_name='s_compute_wall_collisions',parallelism='[seq]', cray_inline=True) + + real(wp), dimension(3), intent(in) :: pos, vel + real(wp), intent(in) :: rad, mass, Es, pidtksp, core + real(wp), dimension(3), intent(inout) :: wcol_force + real(wp) :: dij + + wcol_force = 0._wp + + ! Check for particles at solid boundaries + if (any(bc_x%beg == (/BC_REFLECTIVE, BC_CHAR_SLIP_WALL, BC_SLIP_WALL, BC_NO_SLIP_WALL/))) then + dij = rad - (pos(1) - x_cb(-1)) + + if (dij > 0._wp) then + call s_compute_wall_collision_force(dij, vel, rad, mass, Es, pidtksp, core, 1, 1._wp, wcol_force) + end if + end if + + if (any(bc_x%end == (/BC_REFLECTIVE, BC_CHAR_SLIP_WALL, BC_SLIP_WALL, BC_NO_SLIP_WALL/))) then + dij = rad - (x_cb(m) - pos(1)) + + if (dij > 0._wp) then + call s_compute_wall_collision_force(dij, vel, rad, mass, Es, pidtksp, core, 1, -1._wp, wcol_force) + end if + end if + + if (any(bc_y%beg == (/BC_REFLECTIVE, BC_CHAR_SLIP_WALL, BC_SLIP_WALL, BC_NO_SLIP_WALL/))) then + dij = rad - (pos(2) - y_cb(-1)) + + if (dij > 0._wp) then + call s_compute_wall_collision_force(dij, vel, rad, mass, Es, pidtksp, core, 2, 1._wp, wcol_force) + end if + end if + + if (any(bc_y%end == (/BC_REFLECTIVE, BC_CHAR_SLIP_WALL, BC_SLIP_WALL, BC_NO_SLIP_WALL/))) then + dij = rad - (y_cb(n) - pos(2)) + + if (dij > 0._wp) then + call s_compute_wall_collision_force(dij, vel, rad, mass, Es, pidtksp, core, 2, -1._wp, wcol_force) + end if + end if + + if (p > 0) then + if (any(bc_z%beg == (/BC_REFLECTIVE, BC_CHAR_SLIP_WALL, BC_SLIP_WALL, BC_NO_SLIP_WALL/))) then + dij = rad - (pos(3) - z_cb(-1)) + + if (dij > 0._wp) then + call s_compute_wall_collision_force(dij, vel, rad, mass, Es, pidtksp, core, 3, 1._wp, wcol_force) + end if + end if + + if (any(bc_z%end == (/BC_REFLECTIVE, BC_CHAR_SLIP_WALL, BC_SLIP_WALL, BC_NO_SLIP_WALL/))) then + dij = rad - (z_cb(p) - pos(3)) + + if (dij > 0._wp) then + call s_compute_wall_collision_force(dij, vel, rad, mass, Es, pidtksp, core, 3, -1._wp, wcol_force) + end if + end if + end if + + end subroutine s_compute_wall_collisions + + !> This subroutine computes the collision force with a solid wall + subroutine s_compute_wall_collision_force(dij, vel, rad, mass, Es, pidtksp, core, dir, normal, wcol_force) + + $:GPU_ROUTINE(function_name='s_compute_wall_collision_force',parallelism='[seq]', cray_inline=True) + + real(wp), dimension(3), intent(in) :: vel + real(wp), intent(in) :: dij, rad, mass, Es, pidtksp, core, normal + integer, intent(in) :: dir + real(wp), dimension(3), intent(inout) :: wcol_force + real(wp), dimension(3) :: nij, v_rel, vnij + real(wp) :: kappa_n, eta_n + + ! Normal points away from wall (into domain) + nij = 0._wp + nij(dir) = normal + + ! Relative velocity (wall has zero velocity) + v_rel = vel + vnij = dot_product(v_rel, nij)*nij + + ! Wall has infinite mass so use mp1 only + kappa_n = min((pidtksp*mass), (Es*sqrt(rad)*sqrt(abs(dij)))) + + eta_n = ((-2._wp*sqrt(kappa_n)*log(core))/sqrt((log(core))**2 + pi**2))*(1._wp/sqrt(1._wp/mass)) + + wcol_force = wcol_force + (kappa_n*dij*nij - eta_n*vnij) + + end subroutine s_compute_wall_collision_force + + !> This subroutine adds temporary ghost particles for collision purposes + subroutine s_add_ghost_particles() + + integer :: k, i, q + integer :: patch_id, newBubs + integer, dimension(3) :: cell + logical :: inc_ghost + + inc_ghost = .true. + + call nvtxStartRange("LAG-GHOSTADD") + call nvtxStartRange("LAG-GHOSTADD-DEV2HOST") + $:GPU_UPDATE(host='[p_owner_rank, particle_R0, Rmax_stats_part, Rmin_stats_part, particle_mass, f_p, lag_part_id, & + & particle_rad, particle_pos, particle_posPrev, particle_vel, particle_s, particle_draddt, particle_dposdt, & + & particle_dveldt, n_el_particles_loc, wrap_bubble_dir, wrap_bubble_loc]') + call nvtxEndRange + + ! Handle MPI transfer of particles going to another processor's local domain + if (num_procs > 1) then + call nvtxStartRange("LAG-GHOSTADD-TRANSFER-LIST") + call s_add_particles_to_transfer_list(n_el_particles_loc, particle_pos(:,:,2), particle_posPrev(:,:,2), inc_ghost) + call nvtxEndRange + + call nvtxStartRange("LAG-GHOSTADD-SENDRECV") + call s_mpi_sendrecv_solid_particles(p_owner_rank, particle_R0, Rmax_stats_part, Rmin_stats_part, particle_mass, f_p, & + & lag_part_id, particle_rad, particle_pos, particle_posPrev, particle_vel, & + & particle_s, particle_draddt, particle_dposdt, particle_dveldt, lag_num_ts, & + & n_el_particles_loc, 2) + call nvtxEndRange + end if + + call nvtxStartRange("LAG-GHOSTADD-HOST2DEV") + $:GPU_UPDATE(device='[p_owner_rank, particle_R0, Rmax_stats_part, Rmin_stats_part, particle_mass, f_p, lag_part_id, & + & particle_rad, particle_pos, particle_posPrev, particle_vel, particle_s, particle_draddt, particle_dposdt, & + & particle_dveldt, n_el_particles_loc]') + call nvtxEndRange + + call nvtxEndRange ! LAG-GHOSTADD + + $:GPU_PARALLEL_LOOP(private='[k, cell]') + do k = 1, n_el_particles_loc + cell = fd_number - buff_size + call s_locate_cell(particle_pos(k,1:3,2), cell, particle_s(k,1:3,2)) + end do + $:END_GPU_PARALLEL_LOOP() + + end subroutine s_add_ghost_particles + + !> The purpose of this subroutine is to check if the current cell is outside the computational domain or not (including ghost + !! cells). + !! @param cellaux Tested cell to smear the particle effect in. + !! @param celloutside If true, then cellaux is outside the computational domain. + subroutine s_check_celloutside_wbuff(cellaux, celloutside) + + $:GPU_ROUTINE(function_name='s_check_celloutside_wbuff',parallelism='[seq]', cray_inline=True) + + integer, dimension(3), intent(inout) :: cellaux + logical, intent(out) :: celloutside + + celloutside = .false. + + if (num_dims == 2) then + if ((cellaux(1) < -buff_size) .or. (cellaux(2) < -buff_size)) then + celloutside = .true. + end if + + if ((cellaux(1) > m + buff_size) .or. (cellaux(2) > n + buff_size)) then + celloutside = .true. + end if + else + if ((cellaux(1) < -buff_size) .or. (cellaux(2) < -buff_size) .or. (cellaux(3) < -buff_size)) then + celloutside = .true. + end if + + if ((cellaux(1) > m + buff_size) .or. (cellaux(2) > n + buff_size) .or. (cellaux(3) > p + buff_size)) then + celloutside = .true. + end if + end if + + end subroutine s_check_celloutside_wbuff + + !> Compute particle source terms for two-way Euler-Lagrange coupling (Maeda & Colonius, 2018) + !! @param q_cons_vf Conservative variables + !! @param q_prim_vf Primitive variables + !! @param rhs_vf Time derivative of the conservative variables + subroutine s_compute_particles_EL_source(q_cons_vf, q_prim_vf, rhs_vf, stage) + + type(scalar_field), dimension(sys_size), intent(inout) :: q_cons_vf + type(scalar_field), dimension(sys_size), intent(inout) :: q_prim_vf + type(scalar_field), dimension(sys_size), intent(inout) :: rhs_vf + integer, intent(in) :: stage + integer :: i, j, k, l, nf + real(wp) :: dalphapdt, alpha_f, udot_gradalpha + + ! Spatial derivative of the fluid volume fraction and eulerian particle momentum fields. + + do l = 1, num_dims + call s_gradient_dir_fornberg(q_particles(alphaf_id)%sf, field_vars(dalphafx_id + l - 1)%sf, l) + call s_gradient_dir_fornberg(q_particles(alphaupx_id + l - 1)%sf, field_vars(dalphap_upx_id + l - 1)%sf, l) + end do + + !> Apply particle sources to the Eulerian RHS + $:GPU_PARALLEL_LOOP(private='[i, j, k, alpha_f, dalphapdt, udot_gradalpha]', collapse=3) + do k = idwint(3)%beg, idwint(3)%end + do j = idwint(2)%beg, idwint(2)%end + do i = idwint(1)%beg, idwint(1)%end + if (q_particles(alphaf_id)%sf(i, j, k) > (1._wp - lag_params%valmaxvoid)) then + alpha_f = q_particles(alphaf_id)%sf(i, j, k) + + dalphapdt = 0._wp + udot_gradalpha = 0._wp + do l = 1, num_dims + dalphapdt = dalphapdt + field_vars(dalphap_upx_id + l - 1)%sf(i, j, k) + udot_gradalpha = udot_gradalpha + q_prim_vf(momxb + l - 1)%sf(i, j, & + & k)*field_vars(dalphafx_id + l - 1)%sf(i, j, k) + end do + dalphapdt = -dalphapdt + ! Add any contribution to dalphapdt from particles growing or shrinking + + !> Step 1: Source terms for volume fraction corrections + ! cons_var/alpha_f * (dalpha_p/dt - u dot grad(alpha_f)) + do l = 1, E_idx + rhs_vf(l)%sf(i, j, k) = rhs_vf(l)%sf(i, j, k) + (q_cons_vf(l)%sf(i, j, & + & k)/alpha_f)*(dalphapdt - udot_gradalpha) + end do + + ! momentum term -1/alpha_f * (p*grad(alpha_f) - Tau^v dot grad(alpha_f)) !Viscous term not implemented + do l = 1, num_dims + rhs_vf(momxb + l - 1)%sf(i, j, k) = rhs_vf(momxb + l - 1)%sf(i, j, & + & k) - ((1._wp/alpha_f)*(q_prim_vf(E_idx)%sf(i, j, k)*field_vars(dalphafx_id + l - 1)%sf(i, j, & + & k))) + end do + + ! energy term -1/alpha_f * (p*u dot grad(alpha_f) - (Tau^v dot u) dot grad(alpha_f)) !Viscous term not + ! implemented + rhs_vf(E_idx)%sf(i, j, k) = rhs_vf(E_idx)%sf(i, j, k) - ((1._wp/alpha_f)*(q_prim_vf(E_idx)%sf(i, j, & + & k)*udot_gradalpha)) + + !> Step 2: Add the drag/pressure/added mass forces to the fluid + rhs_vf(momxb)%sf(i, j, k) = rhs_vf(momxb)%sf(i, j, k) + q_particles(Smx_id)%sf(i, j, k)*(1._wp/alpha_f) + rhs_vf(momxb + 1)%sf(i, j, k) = rhs_vf(momxb + 1)%sf(i, j, k) + q_particles(Smy_id)%sf(i, j, & + & k)*(1._wp/alpha_f) + + ! Energy source + rhs_vf(E_idx)%sf(i, j, k) = rhs_vf(E_idx)%sf(i, j, k) + (q_particles(Smx_id)%sf(i, j, & + & k)*q_prim_vf(momxb)%sf(i, j, k) + q_particles(Smy_id)%sf(i, j, k)*q_prim_vf(momxb + 1)%sf(i, j, & + & k) + q_particles(SE_id)%sf(i, j, k))*(1._wp/alpha_f) + + if (num_dims == 3) then + rhs_vf(momxb + 2)%sf(i, j, k) = rhs_vf(momxb + 2)%sf(i, j, k) + q_particles(Smz_id)%sf(i, j, & + & k)*(1._wp/alpha_f) + ! Energy source + rhs_vf(E_idx)%sf(i, j, k) = rhs_vf(E_idx)%sf(i, j, k) + (q_particles(Smz_id)%sf(i, j, & + & k)*q_prim_vf(momxb + 2)%sf(i, j, k))*(1._wp/alpha_f) + end if + end if + end do + end do + end do + $:END_GPU_PARALLEL_LOOP() + + end subroutine s_compute_particles_EL_source + + !> Reset and rebuild the cell-based linked list for particle-to-cell mapping + subroutine s_reset_linked_list() + + integer :: j, k, l + + $:GPU_PARALLEL_LOOP(private='[j, k, l]', collapse=3) + do l = idwbuff(3)%beg, idwbuff(3)%end + do k = idwbuff(2)%beg, idwbuff(2)%end + do j = idwbuff(1)%beg, idwbuff(1)%end + particle_head(j, k, l) = -1 + end do + end do + end do + $:END_GPU_PARALLEL_LOOP() + + $:GPU_PARALLEL_LOOP(private='[k]') + do k = 1, n_el_particles_loc + linked_list(k) = -1 + end do + $:END_GPU_PARALLEL_LOOP() + + call s_build_linked_list() + + end subroutine s_reset_linked_list + + !> Zero all Eulerian field variables and particle projection arrays + subroutine s_reset_cell_vars() + + integer :: i, j, k, l + + $:GPU_PARALLEL_LOOP(private='[i, j, k, l]', collapse=4) + do i = 1, max(nField_vars, q_particles_idx) ! outermost is largest of the i-like dims + do l = idwbuff(3)%beg, idwbuff(3)%end + do k = idwbuff(2)%beg, idwbuff(2)%end + do j = idwbuff(1)%beg, idwbuff(1)%end + ! Zero field_vars if i <= nField_vars + if (i <= nField_vars) field_vars(i)%sf(j, k, l) = 0._wp + ! Zero q_particles if i <= q_particles_idx + if (i <= q_particles_idx) then + q_particles(i)%sf(j, k, l) = 0._wp + end if + end do + end do + end do + end do + $:END_GPU_PARALLEL_LOOP() + + end subroutine s_reset_cell_vars + + !> Finalize the particle volume fraction field after Gaussian smearing. Applies boundary conditions to the smeared field, then + !! converts accumulated particle volume alpha_p to fluid volume fraction alpha_f = 1 - alpha_p. + subroutine s_finalize_beta_field(bc_type, onlyBeta) + + type(integer_field), dimension(1:num_dims,1:2), intent(in) :: bc_type + integer :: j, k, l + logical, intent(in) :: onlyBeta + + call nvtxStartRange("PARTICLES-LAGRANGE-BETA-COMM") + if (onlyBeta) then + call s_populate_beta_buffers(q_particles, bc_type, 1) + else + call s_populate_beta_buffers(q_particles, bc_type, q_particles_idx) + end if + call nvtxEndRange + + ! Store 1-q_particles(1) + $:GPU_PARALLEL_LOOP(private='[j, k, l]', collapse=3) + do l = idwbuff(3)%beg, idwbuff(3)%end + do k = idwbuff(2)%beg, idwbuff(2)%end + do j = idwbuff(1)%beg, idwbuff(1)%end + q_particles(alphaf_id)%sf(j, k, l) = 1._wp - q_particles(alphaf_id)%sf(j, k, l) + ! Limiting void fraction given max value + q_particles(alphaf_id)%sf(j, k, l) = max(q_particles(alphaf_id)%sf(j, k, l), 1._wp - lag_params%valmaxvoid) + end do + end do + end do + $:END_GPU_PARALLEL_LOOP() + + end subroutine s_finalize_beta_field + + !> Build a cell-based linked list for particle-to-cell mapping. particle_head(i,j,k) points to the first particle in cell + !! (i,j,k). linked_list(k) points to the next particle in the same cell (-1 = end). + subroutine s_build_linked_list() + + integer :: k, glb_id, i + integer, dimension(3) :: cell + real(wp), dimension(3) :: s_cell + logical :: celloutside + + $:GPU_PARALLEL_LOOP(private='[i, k, cell, s_cell, glb_id, celloutside]') + do k = 1, n_el_particles_loc + glb_id = lag_part_id(k, 1) + gid_to_local(glb_id) = k + + s_cell = particle_s(k,1:3,2) + cell = int(s_cell(:)) + do i = 1, num_dims + if (s_cell(i) < 0._wp) cell(i) = cell(i) - 1 + end do + + call s_check_celloutside_wbuff(cell, celloutside) + + if (.not. celloutside) then + !!!!! Particle linked list building + $:GPU_ATOMIC(atomic='capture') + linked_list(k) = particle_head(cell(1), cell(2), cell(3)) + particle_head(cell(1), cell(2), cell(3)) = k + $:END_GPU_ATOMIC_CAPTURE() + end if + end do + $:END_GPU_PARALLEL_LOOP() + + end subroutine s_build_linked_list + + !> This subroutine updates the Lagrange variables using the tvd RK time steppers. The time derivative of the particle variables + !! must be stored at every stage to avoid precision errors. + !! @param stage Current tvd RK stage + impure subroutine s_update_lagrange_particles_tdv_rk(q_prim_vf, bc_type, stage) + + type(scalar_field), dimension(sys_size), intent(in) :: q_prim_vf + type(integer_field), dimension(1:num_dims,1:2), intent(in) :: bc_type + integer, intent(in) :: stage + integer :: k + + if (time_stepper == 1) then ! 1st order TVD RK + + $:GPU_PARALLEL_LOOP(private='[k]') + do k = 1, n_el_particles_loc + ! u{1} = u{n} + dt * RHS{n} + particle_rad(k, 1) = particle_rad(k, 1) + dt*particle_draddt(k, 1) + if (moving_lag_particles) then + particle_posPrev(k,1:3,1) = particle_pos(k,1:3,1) + particle_pos(k,1:3,1) = particle_pos(k,1:3,1) + dt*particle_dposdt(k,1:3,1) + particle_vel(k,1:3,1) = particle_vel(k,1:3,1) + dt*particle_dveldt(k,1:3,1) + end if + end do + $:END_GPU_PARALLEL_LOOP() + + call s_transfer_data_to_tmp_particles() + if (moving_lag_particles) call s_enforce_EL_particles_boundary_conditions(q_prim_vf, stage, bc_type) + if (lag_params%write_void_evol) call s_write_void_evol_particles(mytime) + if (lag_params%write_bubbles_stats) call s_calculate_lag_particle_stats() + if (lag_params%write_bubbles) then + ! $:GPU_UPDATE(host='[gas_p,gas_mv,particle_rad,intfc_vel]') + $:GPU_UPDATE(host='[particle_rad]') + call s_write_lag_particle_evol(mytime) + end if + else if (time_stepper == 2) then ! 2nd order TVD RK + if (stage == 1) then + $:GPU_PARALLEL_LOOP(private='[k]') + do k = 1, n_el_particles_loc + ! u{1} = u{n} + dt * RHS{n} + particle_rad(k, 2) = particle_rad(k, 1) + dt*particle_draddt(k, 1) + if (moving_lag_particles) then + particle_posPrev(k,1:3,2) = particle_pos(k,1:3,1) + particle_pos(k,1:3,2) = particle_pos(k,1:3,1) + dt*particle_dposdt(k,1:3,1) + particle_vel(k,1:3,2) = particle_vel(k,1:3,1) + dt*particle_dveldt(k,1:3,1) + end if + end do + $:END_GPU_PARALLEL_LOOP() + + if (moving_lag_particles) call s_enforce_EL_particles_boundary_conditions(q_prim_vf, stage, bc_type) + else if (stage == 2) then + $:GPU_PARALLEL_LOOP(private='[k]') + do k = 1, n_el_particles_loc + ! u{1} = u{n} + (1/2) * dt * (RHS{n} + RHS{1}) + particle_rad(k, 1) = particle_rad(k, 1) + dt*(particle_draddt(k, 1) + particle_draddt(k, 2))/2._wp + if (moving_lag_particles) then + particle_posPrev(k,1:3,1) = particle_pos(k,1:3,2) + particle_pos(k,1:3,1) = particle_pos(k,1:3,1) + dt*(particle_dposdt(k,1:3,1) + particle_dposdt(k,1:3, & + & 2))/2._wp + particle_vel(k,1:3,1) = particle_vel(k,1:3,1) + dt*(particle_dveldt(k,1:3,1) + particle_dveldt(k,1:3, & + & 2))/2._wp + end if + end do + $:END_GPU_PARALLEL_LOOP() + + call s_transfer_data_to_tmp_particles() + if (moving_lag_particles) call s_enforce_EL_particles_boundary_conditions(q_prim_vf, stage, bc_type) + if (lag_params%write_void_evol) call s_write_void_evol_particles(mytime) + if (lag_params%write_bubbles_stats) call s_calculate_lag_particle_stats() + if (lag_params%write_bubbles) then + $:GPU_UPDATE(host='[particle_rad]') + call s_write_lag_particle_evol(mytime) + end if + end if + else if (time_stepper == 3) then ! 3rd order TVD RK + if (stage == 1) then + $:GPU_PARALLEL_LOOP(private='[k]') + do k = 1, n_el_particles_loc + ! u{1} = u{n} + dt * RHS{n} + particle_rad(k, 2) = particle_rad(k, 1) + dt*particle_draddt(k, 1) + if (moving_lag_particles) then + particle_posPrev(k,1:3,2) = particle_pos(k,1:3,1) + particle_pos(k,1:3,2) = particle_pos(k,1:3,1) + dt*particle_dposdt(k,1:3,1) + particle_vel(k,1:3,2) = particle_vel(k,1:3,1) + dt*particle_dveldt(k,1:3,1) + end if + end do + $:END_GPU_PARALLEL_LOOP() + + if (moving_lag_particles) call s_enforce_EL_particles_boundary_conditions(q_prim_vf, stage, bc_type) + else if (stage == 2) then + $:GPU_PARALLEL_LOOP(private='[k]') + do k = 1, n_el_particles_loc + ! u{2} = u{n} + (1/4) * dt * [RHS{n} + RHS{1}] + particle_rad(k, 2) = particle_rad(k, 1) + dt*(particle_draddt(k, 1) + particle_draddt(k, 2))/4._wp + if (moving_lag_particles) then + particle_posPrev(k,1:3,2) = particle_pos(k,1:3,2) + particle_pos(k,1:3,2) = particle_pos(k,1:3,1) + dt*(particle_dposdt(k,1:3,1) + particle_dposdt(k,1:3, & + & 2))/4._wp + particle_vel(k,1:3,2) = particle_vel(k,1:3,1) + dt*(particle_dveldt(k,1:3,1) + particle_dveldt(k,1:3, & + & 2))/4._wp + end if + end do + $:END_GPU_PARALLEL_LOOP() + + if (moving_lag_particles) call s_enforce_EL_particles_boundary_conditions(q_prim_vf, stage, bc_type) + else if (stage == 3) then + $:GPU_PARALLEL_LOOP(private='[k]') + do k = 1, n_el_particles_loc + ! u{n+1} = u{n} + (2/3) * dt * [(1/4)* RHS{n} + (1/4)* RHS{1} + RHS{2}] + particle_rad(k, 1) = particle_rad(k, 1) + (2._wp/3._wp)*dt*(particle_draddt(k, 1)/4._wp + particle_draddt(k, & + & 2)/4._wp + particle_draddt(k, 3)) + if (moving_lag_particles) then + particle_posPrev(k,1:3,1) = particle_pos(k,1:3,2) + particle_pos(k,1:3,1) = particle_pos(k,1:3,1) + (2._wp/3._wp)*dt*(particle_dposdt(k,1:3, & + & 1)/4._wp + particle_dposdt(k,1:3,2)/4._wp + particle_dposdt(k,1:3,3)) + particle_vel(k,1:3,1) = particle_vel(k,1:3,1) + (2._wp/3._wp)*dt*(particle_dveldt(k,1:3, & + & 1)/4._wp + particle_dveldt(k,1:3,2)/4._wp + particle_dveldt(k,1:3,3)) + end if + end do + $:END_GPU_PARALLEL_LOOP() + + call s_transfer_data_to_tmp_particles() + if (moving_lag_particles) call s_enforce_EL_particles_boundary_conditions(q_prim_vf, stage, bc_type) + if (lag_params%write_void_evol) call s_write_void_evol_particles(mytime) + if (lag_params%write_bubbles_stats) call s_calculate_lag_particle_stats() + if (lag_params%write_bubbles .and. mytime >= next_write_time) then + $:GPU_UPDATE(host='[particle_mass, particle_rad]') + call s_write_lag_particle_evol(mytime) + next_write_time = next_write_time + t_save + end if + end if + end if + + end subroutine s_update_lagrange_particles_tdv_rk + + !> Enforce boundary conditions on Lagrangian particles. Phases: (1) GPU->host transfer, (2) MPI particle exchange with + !! neighbors, (3) host->GPU transfer, (4) per-particle BC (periodic wrap / reflect / remove), (5) compaction to remove deleted + !! particles, (6) re-smear onto Eulerian grid. + impure subroutine s_enforce_EL_particles_boundary_conditions(q_prim_vf, nstage, bc_type) + + type(scalar_field), dimension(sys_size), intent(in) :: q_prim_vf + type(integer_field), dimension(1:num_dims,1:2), intent(in) :: bc_type + integer, intent(in) :: nstage + real(wp) :: offset + integer :: k, i, q + integer :: patch_id, newBubs, new_idx + integer, dimension(3) :: cell + logical :: inc_ghost + real(wp) :: myR, func_sum + real(wp), dimension(3) :: myPos, myVel, myForce + logical :: only_beta + + inc_ghost = .false. + only_beta = .true. + + call nvtxStartRange("LAG-BC") + call nvtxStartRange("LAG-BC-DEV2HOST") + $:GPU_UPDATE(host='[p_owner_rank, particle_R0, Rmax_stats_part, Rmin_stats_part, particle_mass, f_p, lag_part_id, & + & particle_rad, particle_pos, particle_posPrev, particle_vel, particle_s, particle_draddt, particle_dposdt, & + & particle_dveldt, keep_bubble, n_el_particles_loc, wrap_bubble_dir, wrap_bubble_loc]') + call nvtxEndRange + + ! Handle MPI transfer of particles going to another processor's local domain + if (num_procs > 1) then + call nvtxStartRange("LAG-BC-TRANSFER-LIST") + call s_add_particles_to_transfer_list(n_el_particles_loc, particle_pos(:,:,2), particle_posPrev(:,:,2), inc_ghost) + call nvtxEndRange + + call nvtxStartRange("LAG-BC-SENDRECV") + call s_mpi_sendrecv_solid_particles(p_owner_rank, particle_R0, Rmax_stats_part, Rmin_stats_part, particle_mass, f_p, & + & lag_part_id, particle_rad, particle_pos, particle_posPrev, particle_vel, & + & particle_s, particle_draddt, particle_dposdt, particle_dveldt, lag_num_ts, & + & n_el_particles_loc, 2) + call nvtxEndRange + end if + + call nvtxStartRange("LAG-BC-HOST2DEV") + $:GPU_UPDATE(device='[p_owner_rank, particle_R0, Rmax_stats_part, Rmin_stats_part, particle_mass, f_p, lag_part_id, & + & particle_rad, particle_pos, particle_posPrev, particle_vel, particle_s, particle_draddt, particle_dposdt, & + & particle_dveldt, n_el_particles_loc]') + call nvtxEndRange + + $:GPU_PARALLEL_LOOP(private='[k, cell]',copyin='[nstage]') + do k = 1, n_el_particles_loc + keep_bubble(k) = 1 + wrap_bubble_loc(k,:) = 0 + wrap_bubble_dir(k,:) = 0 + + ! Relocate particles at solid boundaries and delete particles that leave buffer regions + if (any(bc_x%beg == (/BC_REFLECTIVE, BC_CHAR_SLIP_WALL, BC_SLIP_WALL, BC_NO_SLIP_WALL/)) .and. particle_pos(k, 1, & + & 2) < x_cb(-1) + eps_overlap*particle_rad(k, 2)) then + particle_pos(k, 1, 2) = x_cb(-1) + eps_overlap*particle_rad(k, 2) + if (nstage == lag_num_ts) then + particle_pos(k, 1, 1) = particle_pos(k, 1, 2) + end if + else if (any(bc_x%end == (/BC_REFLECTIVE, BC_CHAR_SLIP_WALL, BC_SLIP_WALL, BC_NO_SLIP_WALL/)) .and. particle_pos(k, & + & 1, 2) > x_cb(m) - eps_overlap*particle_rad(k, 2)) then + particle_pos(k, 1, 2) = x_cb(m) - eps_overlap*particle_rad(k, 2) + if (nstage == lag_num_ts) then + particle_pos(k, 1, 1) = particle_pos(k, 1, 2) + end if + else if (bc_x%beg == BC_PERIODIC .and. particle_pos(k, 1, 2) < pcomm_coords(1)%beg .and. particle_posPrev(k, 1, & + & 2) >= pcomm_coords(1)%beg) then + wrap_bubble_dir(k, 1) = 1 + wrap_bubble_loc(k, 1) = -1 + else if (bc_x%end == BC_PERIODIC .and. particle_pos(k, 1, 2) > pcomm_coords(1)%end .and. particle_posPrev(k, 1, & + & 2) <= pcomm_coords(1)%end) then + wrap_bubble_dir(k, 1) = 1 + wrap_bubble_loc(k, 1) = 1 + else if (particle_pos(k, 1, 2) >= x_cb(m)) then + keep_bubble(k) = 0 + else if (particle_pos(k, 1, 2) < x_cb(-1)) then + keep_bubble(k) = 0 + end if + + if (any(bc_y%beg == (/BC_REFLECTIVE, BC_CHAR_SLIP_WALL, BC_SLIP_WALL, BC_NO_SLIP_WALL/)) .and. particle_pos(k, 2, & + & 2) < y_cb(-1) + eps_overlap*particle_rad(k, 2)) then + particle_pos(k, 2, 2) = y_cb(-1) + eps_overlap*particle_rad(k, 2) + if (nstage == lag_num_ts) then + particle_pos(k, 2, 1) = particle_pos(k, 2, 2) + end if + else if (any(bc_y%end == (/BC_REFLECTIVE, BC_CHAR_SLIP_WALL, BC_SLIP_WALL, BC_NO_SLIP_WALL/)) .and. particle_pos(k, & + & 2, 2) > y_cb(n) - eps_overlap*particle_rad(k, 2)) then + particle_pos(k, 2, 2) = y_cb(n) - eps_overlap*particle_rad(k, 2) + if (nstage == lag_num_ts) then + particle_pos(k, 2, 1) = particle_pos(k, 2, 2) + end if + else if (bc_y%beg == BC_PERIODIC .and. particle_pos(k, 2, 2) < pcomm_coords(2)%beg .and. particle_posPrev(k, 2, & + & 2) >= pcomm_coords(2)%beg) then + wrap_bubble_dir(k, 2) = 1 + wrap_bubble_loc(k, 2) = -1 + else if (bc_y%end == BC_PERIODIC .and. particle_pos(k, 2, 2) > pcomm_coords(2)%end .and. particle_posPrev(k, 2, & + & 2) <= pcomm_coords(2)%end) then + wrap_bubble_dir(k, 2) = 1 + wrap_bubble_loc(k, 2) = 1 + else if (particle_pos(k, 2, 2) >= y_cb(n)) then + keep_bubble(k) = 0 + else if (particle_pos(k, 2, 2) < y_cb(-1)) then + keep_bubble(k) = 0 + end if + + if (p > 0) then + if (any(bc_z%beg == (/BC_REFLECTIVE, BC_CHAR_SLIP_WALL, BC_SLIP_WALL, BC_NO_SLIP_WALL/)) .and. particle_pos(k, 3, & + & 2) < z_cb(-1) + eps_overlap*particle_rad(k, 2)) then + particle_pos(k, 3, 2) = z_cb(-1) + eps_overlap*particle_rad(k, 2) + if (nstage == lag_num_ts) then + particle_pos(k, 3, 1) = particle_pos(k, 3, 2) + end if + else if (any(bc_z%end == (/BC_REFLECTIVE, BC_CHAR_SLIP_WALL, BC_SLIP_WALL, & + & BC_NO_SLIP_WALL/)) .and. particle_pos(k, 3, 2) > z_cb(p) - eps_overlap*particle_rad(k, 2)) then + particle_pos(k, 3, 2) = z_cb(p) - eps_overlap*particle_rad(k, 2) + if (nstage == lag_num_ts) then + particle_pos(k, 3, 1) = particle_pos(k, 3, 2) + end if + else if (bc_z%beg == BC_PERIODIC .and. particle_pos(k, 3, 2) < pcomm_coords(3)%beg .and. particle_posPrev(k, 3, & + & 2) >= pcomm_coords(3)%beg) then + wrap_bubble_dir(k, 3) = 1 + wrap_bubble_loc(k, 3) = -1 + else if (bc_z%end == BC_PERIODIC .and. particle_pos(k, 3, 2) > pcomm_coords(3)%end .and. particle_posPrev(k, 3, & + & 2) <= pcomm_coords(3)%end) then + wrap_bubble_dir(k, 3) = 1 + wrap_bubble_loc(k, 3) = 1 + else if (particle_pos(k, 3, 2) >= z_cb(p)) then + keep_bubble(k) = 0 + else if (particle_pos(k, 3, 2) < z_cb(-1)) then + keep_bubble(k) = 0 + end if + end if + + if (keep_bubble(k) == 1) then + ! Remove bubbles that are no longer in a liquid + cell = fd_number - buff_size + call s_locate_cell(particle_pos(k,1:3,2), cell, particle_s(k,1:3,2)) + + if (q_prim_vf(advxb)%sf(cell(1), cell(2), cell(3)) < (1._wp - lag_params%valmaxvoid)) then + keep_bubble(k) = 0 + end if + end if + end do + $:END_GPU_PARALLEL_LOOP() + + if (n_el_particles_loc > 0) then + call nvtxStartRange("LAG-BC") + call nvtxStartRange("LAG-BC-DEV2HOST") + $:GPU_UPDATE(host='[particle_R0, Rmax_stats_part, Rmin_stats_part, particle_mass, f_p, lag_part_id, particle_rad, & + & particle_pos, particle_posPrev, particle_vel, particle_s, particle_draddt, particle_dposdt, & + & particle_dveldt, keep_bubble, n_el_particles_loc, wrap_bubble_dir, wrap_bubble_loc]') + call nvtxEndRange + + newBubs = 0 + do k = 1, n_el_particles_loc + if (keep_bubble(k) == 1) then + newBubs = newBubs + 1 + if (newBubs /= k) then + call s_copy_lag_particle(newBubs, k) + wrap_bubble_dir(newBubs,:) = wrap_bubble_dir(k,:) + wrap_bubble_loc(newBubs,:) = wrap_bubble_loc(k,:) + end if + end if + end do + + n_el_particles_loc = newBubs + + ! Handle periodic wrapping of bubbles on same processor + newBubs = 0 + do k = 1, n_el_particles_loc + if (any(wrap_bubble_dir(k,:) == 1)) then + newBubs = newBubs + 1 + new_idx = n_el_particles_loc + newBubs + call s_copy_lag_particle(new_idx, k) + do i = 1, num_dims + if (wrap_bubble_dir(k, i) == 1) then + offset = glb_bounds(i)%end - glb_bounds(i)%beg + if (wrap_bubble_loc(k, i) == 1) then + do q = 1, 2 + particle_pos(new_idx, i, q) = particle_pos(new_idx, i, q) - offset + particle_posPrev(new_idx, i, q) = particle_posPrev(new_idx, i, q) - offset + end do + else if (wrap_bubble_loc(k, i) == -1) then + do q = 1, 2 + particle_pos(new_idx, i, q) = particle_pos(new_idx, i, q) + offset + particle_posPrev(new_idx, i, q) = particle_posPrev(new_idx, i, q) + offset + end do + end if + end if + end do + end if + end do + call nvtxStartRange("LAG-BC-HOST2DEV") + $:GPU_UPDATE(device='[particle_R0, Rmax_stats_part, Rmin_stats_part, particle_mass, f_p, lag_part_id, particle_rad, & + & particle_pos, particle_posPrev, particle_vel, particle_s, particle_draddt, particle_dposdt, & + & particle_dveldt, n_el_particles_loc]') + call nvtxEndRange + end if + + call s_reset_cell_vars() + + $:GPU_PARALLEL_LOOP(private='[cell, myR, myPos, myVel, myForce, func_sum]',copyin='[only_beta]') + do k = 1, n_el_particles_loc + myR = particle_rad(k, 2) + myPos = particle_pos(k,1:3,2) + myVel = particle_vel(k,1:3,2) + myForce = f_p(k,:) + + cell = fd_number - buff_size + call s_locate_cell(particle_pos(k,1:3,2), cell, particle_s(k,1:3,2)) + + ! Compute the total gaussian contribution for each particle for normalization + call s_compute_gaussian_contribution(myR, myPos, cell, func_sum) + gSum(k) = func_sum + + call s_gaussian_atomic(myR, myVel, myPos, myForce, func_sum, cell, q_particles, only_beta) + end do + $:END_GPU_PARALLEL_LOOP() + + ! Update void fraction and communicate buffers + call s_finalize_beta_field(bc_type, only_beta) + + call nvtxEndRange ! LAG-BC + + end subroutine s_enforce_EL_particles_boundary_conditions + + !> This subroutine returns the computational coordinate of the cell for the given position. + !! @param pos Input coordinates + !! @param cell Computational coordinate of the cell + !! @param scoord Calculated particle coordinates + subroutine s_locate_cell(pos, cell, scoord) + + $:GPU_ROUTINE(function_name='s_locate_cell',parallelism='[seq]', cray_inline=True) + + real(wp), dimension(3), intent(in) :: pos + real(wp), dimension(3), intent(out) :: scoord + integer, dimension(3), intent(inout) :: cell + integer :: i + + do while (pos(1) < x_cb(cell(1) - 1) .and. cell(1) > -buff_size) + cell(1) = cell(1) - 1 + end do + + do while (pos(1) >= x_cb(cell(1)) .and. cell(1) < m + buff_size) + cell(1) = cell(1) + 1 + end do + + do while (pos(2) < y_cb(cell(2) - 1) .and. cell(2) > -buff_size) + cell(2) = cell(2) - 1 + end do + + do while (pos(2) >= y_cb(cell(2)) .and. cell(2) < n + buff_size) + cell(2) = cell(2) + 1 + end do + + if (p > 0) then + do while (pos(3) < z_cb(cell(3) - 1) .and. cell(3) > -buff_size) + cell(3) = cell(3) - 1 + end do + do while (pos(3) >= z_cb(cell(3)) .and. cell(3) < p + buff_size) + cell(3) = cell(3) + 1 + end do + end if + + ! The numbering of the cell of which left boundary is the domain boundary is 0. if comp.coord of the pos is s, the real + ! coordinate of s is (the coordinate of the left boundary of the Floor(s)-th cell) + (s-(int(s))*(cell-width). In other + ! words, the coordinate of the center of the cell is x_cc(cell). + + ! coordinates in computational space + scoord(1) = cell(1) + (pos(1) - x_cb(cell(1) - 1))/dx(cell(1)) + scoord(2) = cell(2) + (pos(2) - y_cb(cell(2) - 1))/dy(cell(2)) + scoord(3) = 0._wp + if (p > 0) scoord(3) = cell(3) + (pos(3) - z_cb(cell(3) - 1))/dz(cell(3)) + cell(:) = int(scoord(:)) + do i = 1, num_dims + if (scoord(i) < 0._wp) cell(i) = cell(i) - 1 + end do + + end subroutine s_locate_cell + + !> This subroutine transfer data into the temporal variables. + impure subroutine s_transfer_data_to_tmp_particles() + + integer :: k + + $:GPU_PARALLEL_LOOP(private='[k]') + do k = 1, n_el_particles_loc + particle_rad(k, 2) = particle_rad(k, 1) + particle_pos(k,1:3,2) = particle_pos(k,1:3,1) + particle_posPrev(k,1:3,2) = particle_posPrev(k,1:3,1) + particle_vel(k,1:3,2) = particle_vel(k,1:3,1) + particle_s(k,1:3,2) = particle_s(k,1:3,1) + end do + $:END_GPU_PARALLEL_LOOP() + + end subroutine s_transfer_data_to_tmp_particles + + !> The purpose of this procedure is to determine if the global coordinates of the bubbles are present in the current MPI + !! processor (including ghost cells). + !! @param pos_part Spatial coordinates of the bubble + function particle_in_domain(pos_part) + + logical :: particle_in_domain + real(wp), dimension(3), intent(in) :: pos_part + + ! 2D + + if (p == 0 .and. cyl_coord .neqv. .true.) then + ! Defining a virtual z-axis that has the same dimensions as y-axis defined in the input file + particle_in_domain = ((pos_part(1) < x_cb(m + buff_size - fd_number)) .and. (pos_part(1) >= x_cb(fd_number & + & - buff_size - 1)) .and. (pos_part(2) < y_cb(n + buff_size - fd_number)) .and. (pos_part(2) & + & >= y_cb(fd_number - buff_size - 1)) .and. (pos_part(3) < lag_params%charwidth/2._wp) & + & .and. (pos_part(3) > -lag_params%charwidth/2._wp)) + else + ! cyl_coord + particle_in_domain = ((pos_part(1) < x_cb(m + buff_size - fd_number)) .and. (pos_part(1) >= x_cb(fd_number & + & - buff_size - 1)) .and. (abs(pos_part(2)) < y_cb(n + buff_size - fd_number)) & + & .and. (abs(pos_part(2)) >= max(y_cb(fd_number - buff_size - 1), 0._wp))) + end if + + ! 3D + if (p > 0) then + particle_in_domain = ((pos_part(1) < x_cb(m + buff_size - fd_number)) .and. (pos_part(1) >= x_cb(fd_number & + & - buff_size - 1)) .and. (pos_part(2) < y_cb(n + buff_size - fd_number)) .and. (pos_part(2) & + & >= y_cb(fd_number - buff_size - 1)) .and. (pos_part(3) < z_cb(p + buff_size - fd_number)) & + & .and. (pos_part(3) >= z_cb(fd_number - buff_size - 1))) + end if + + ! For symmetric and wall boundary condition + if (any(bc_x%beg == (/BC_REFLECTIVE, BC_CHAR_SLIP_WALL, BC_SLIP_WALL, BC_NO_SLIP_WALL/))) then + particle_in_domain = (particle_in_domain .and. (pos_part(1) >= x_cb(-1))) + end if + if (any(bc_x%end == (/BC_REFLECTIVE, BC_CHAR_SLIP_WALL, BC_SLIP_WALL, BC_NO_SLIP_WALL/))) then + particle_in_domain = (particle_in_domain .and. (pos_part(1) < x_cb(m))) + end if + if (any(bc_y%beg == (/BC_REFLECTIVE, BC_CHAR_SLIP_WALL, BC_SLIP_WALL, BC_NO_SLIP_WALL/)) .and. (.not. cyl_coord)) then + particle_in_domain = (particle_in_domain .and. (pos_part(2) >= y_cb(-1))) + end if + if (any(bc_y%end == (/BC_REFLECTIVE, BC_CHAR_SLIP_WALL, BC_SLIP_WALL, BC_NO_SLIP_WALL/)) .and. (.not. cyl_coord)) then + particle_in_domain = (particle_in_domain .and. (pos_part(2) < y_cb(n))) + end if + if (p > 0) then + if (any(bc_z%beg == (/BC_REFLECTIVE, BC_CHAR_SLIP_WALL, BC_SLIP_WALL, BC_NO_SLIP_WALL/))) then + particle_in_domain = (particle_in_domain .and. (pos_part(3) >= z_cb(-1))) + end if + if (any(bc_z%end == (/BC_REFLECTIVE, BC_CHAR_SLIP_WALL, BC_SLIP_WALL, BC_NO_SLIP_WALL/))) then + particle_in_domain = (particle_in_domain .and. (pos_part(3) < z_cb(p))) + end if + end if + + end function particle_in_domain + + !> Determine if a particle is located within the physical domain (excluding ghost cells) + !! @param pos_part Spatial coordinates of the particle + function particle_in_domain_physical(pos_part) + + $:GPU_ROUTINE(parallelism='[seq]') + + logical :: particle_in_domain_physical + real(wp), dimension(3), intent(in) :: pos_part + + particle_in_domain_physical = ((pos_part(1) < x_cb(m)) .and. (pos_part(1) >= x_cb(-1)) .and. (pos_part(2) < y_cb(n)) & + & .and. (pos_part(2) >= y_cb(-1))) + + if (p > 0) then + particle_in_domain_physical = (particle_in_domain_physical .and. (pos_part(3) < z_cb(p)) .and. (pos_part(3) & + & >= z_cb(-1))) + end if + + end function particle_in_domain_physical + + !> The purpose of this procedure is to calculate the gradient from reconstructed states along the x, y and z + !! @param vL_field left edge reconstructed values + !! @param vR_field right edge reconstructed values + !! @param dq Output gradient of q + !! @param dir Gradient spatial direction + !! @param field_var variable index for reconstructed states + subroutine s_gradient_field(vL_field, vR_field, dq, dir, field_var) + + real(stp), dimension(idwbuff(1)%beg:,idwbuff(2)%beg:,idwbuff(3)%beg:), intent(out) :: dq + real(wp), dimension(idwbuff(1)%beg:,idwbuff(2)%beg:,idwbuff(3)%beg:,1:), intent(in) :: vL_field + real(wp), dimension(idwbuff(1)%beg:,idwbuff(2)%beg:,idwbuff(3)%beg:,1:), intent(in) :: vR_field + integer, intent(in) :: dir, field_var + integer :: i, j, k + real(wp) :: mydx + + if (dir == 1) then + $:GPU_PARALLEL_LOOP(private='[i, j, k, mydx]', collapse=3,copyin='[dir, field_var]') + do k = idwbuff(3)%beg, idwbuff(3)%end + do j = idwbuff(2)%beg, idwbuff(2)%end + do i = idwbuff(1)%beg, idwbuff(1)%end + mydx = dx(i) + dq(i, j, k) = (vR_field(i, j, k, field_var) - vL_field(i, j, k, field_var))/mydx + end do + end do + end do + $:END_GPU_PARALLEL_LOOP() + else if (dir == 2) then + $:GPU_PARALLEL_LOOP(private='[i, j, k, mydx]', collapse=3,copyin='[dir, field_var]') + do k = idwbuff(3)%beg, idwbuff(3)%end + do j = idwbuff(1)%beg, idwbuff(1)%end + do i = idwbuff(2)%beg, idwbuff(2)%end + mydx = dy(i) + dq(j, i, k) = (vR_field(i, j, k, field_var) - vL_field(i, j, k, field_var))/mydx + end do + end do + end do + $:END_GPU_PARALLEL_LOOP() + else if (dir == 3) then + $:GPU_PARALLEL_LOOP(private='[i, j, k, mydx]', collapse=3,copyin='[dir, field_var]') + do k = idwbuff(1)%beg, idwbuff(1)%end + do j = idwbuff(2)%beg, idwbuff(2)%end + do i = idwbuff(3)%beg, idwbuff(3)%end + mydx = dz(i) + dq(k, j, i) = (vR_field(i, j, k, field_var) - vL_field(i, j, k, field_var))/mydx + end do + end do + end do + $:END_GPU_PARALLEL_LOOP() + end if + + end subroutine s_gradient_field + + !> The purpose of this procedure is to calculate the gradient of a scalar field along the x, y and z directions using Fornberg's + !! method + !! @param q Input scalar field + !! @param dq Output gradient of q + !! @param dir Gradient spatial direction + subroutine s_gradient_dir_fornberg(q, dq, dir) + + real(stp), dimension(idwbuff(1)%beg:,idwbuff(2)%beg:,idwbuff(3)%beg:), intent(in) :: q + real(stp), dimension(idwbuff(1)%beg:,idwbuff(2)%beg:,idwbuff(3)%beg:), intent(out) :: dq + integer, intent(in) :: dir + integer :: i, j, k, a, npts, s_idx + + npts = (nWeights_grad - 1)/2 + + if (dir == 1) then + $:GPU_PARALLEL_LOOP(private='[i, j, k, s_idx, a]', collapse=3,copyin='[npts]') + do k = idwbuff(3)%beg, idwbuff(3)%end + do j = idwbuff(2)%beg, idwbuff(2)%end + do i = idwbuff(1)%beg + 2, idwbuff(1)%end - 2 + dq(i, j, k) = 0._wp + do a = -npts, npts + s_idx = a + npts + 1 + dq(i, j, k) = dq(i, j, k) + weights_x_grad(s_idx)%sf(i, 1, 1)*q(i + a, j, k) + end do + end do + end do + end do + $:END_GPU_PARALLEL_LOOP() + else if (dir == 2) then + $:GPU_PARALLEL_LOOP(private='[i, j, k, s_idx, a]', collapse=3,copyin='[npts]') + do k = idwbuff(3)%beg, idwbuff(3)%end + do j = idwbuff(2)%beg + 2, idwbuff(2)%end - 2 + do i = idwbuff(1)%beg, idwbuff(1)%end + dq(i, j, k) = 0._wp + do a = -npts, npts + s_idx = a + npts + 1 + dq(i, j, k) = dq(i, j, k) + weights_y_grad(s_idx)%sf(j, 1, 1)*q(i, j + a, k) + end do + end do + end do + end do + $:END_GPU_PARALLEL_LOOP() + else if (dir == 3) then + $:GPU_PARALLEL_LOOP(private='[i, j, k, s_idx, a]', collapse=3,copyin='[npts]') + do k = idwbuff(3)%beg + 2, idwbuff(3)%end - 2 + do j = idwbuff(2)%beg, idwbuff(2)%end + do i = idwbuff(1)%beg, idwbuff(1)%end + dq(i, j, k) = 0._wp + do a = -npts, npts + s_idx = a + npts + 1 + dq(i, j, k) = dq(i, j, k) + weights_z_grad(s_idx)%sf(k, 1, 1)*q(i, j, k + a) + end do + end do + end do + end do + $:END_GPU_PARALLEL_LOOP() + end if + + end subroutine s_gradient_dir_fornberg + + !> The purpose of this procedure is to compute the Fornberg finite difference weights for derivatives (only done once at start + !! time) + impure subroutine s_compute_fornberg_fd_weights(npts) + + integer, intent(in) :: npts + integer :: i, j, k, a, m_order + integer :: s_idx + real(wp) :: x0, y0, z0 + real(wp) :: x_stencil(nWeights_grad) + real(wp) :: c(nWeights_grad,0:1) + + m_order = 1 ! first derivative + + $:GPU_PARALLEL_LOOP(private='[i, a, x_stencil, c, s_idx, x0]', copyin='[npts, m_order]') + do i = idwbuff(1)%beg + npts, idwbuff(1)%end - npts + do a = -npts, npts + s_idx = a + npts + 1 + x_stencil(s_idx) = x_cc(i + a) + end do + x0 = x_cc(i) + + call s_fornberg_weights(x0, x_stencil, nWeights_grad, m_order, c) + + do a = -npts, npts + s_idx = a + npts + 1 + weights_x_grad(s_idx)%sf(i, 1, 1) = c(s_idx, 1) + end do + end do + $:END_GPU_PARALLEL_LOOP() + + $:GPU_PARALLEL_LOOP(private='[j, a, x_stencil, c, s_idx, y0]', copyin='[npts, m_order]') + do j = idwbuff(2)%beg + npts, idwbuff(2)%end - npts + do a = -npts, npts + s_idx = a + npts + 1 + x_stencil(s_idx) = y_cc(j + a) + end do + y0 = y_cc(j) + + call s_fornberg_weights(y0, x_stencil, nWeights_grad, m_order, c) + + do a = -npts, npts + s_idx = a + npts + 1 + weights_y_grad(s_idx)%sf(j, 1, 1) = c(s_idx, 1) + end do + end do + $:END_GPU_PARALLEL_LOOP() + + if (num_dims == 3) then + $:GPU_PARALLEL_LOOP(private='[k, a, x_stencil, c, s_idx, z0]', copyin='[npts, m_order]') + do k = idwbuff(3)%beg + npts, idwbuff(3)%end - npts + do a = -npts, npts + s_idx = a + npts + 1 + x_stencil(s_idx) = z_cc(k + a) + end do + z0 = z_cc(k) + + call s_fornberg_weights(z0, x_stencil, nWeights_grad, m_order, c) + + do a = -npts, npts + s_idx = a + npts + 1 + weights_z_grad(s_idx)%sf(k, 1, 1) = c(s_idx, 1) + end do + end do + $:END_GPU_PARALLEL_LOOP() + end if + + end subroutine s_compute_fornberg_fd_weights + + !> The purpose of this procedure is to compute the Fornberg finite difference weights on a local stencil + subroutine s_fornberg_weights(x0, stencil, npts, m_order, coeffs) + + $:GPU_ROUTINE(parallelism='[seq]') + + integer, intent(in) :: npts ! number of stencil points + integer, intent(in) :: m_order ! highest derivative order + real(wp), intent(in) :: x0 ! evaluation point + real(wp), intent(in) :: stencil(npts) ! stencil coordinates + real(wp), intent(out) :: coeffs(npts,0:m_order) + integer :: i, j, k, mn + real(wp) :: c1, c2, c3, c4, c5 + + coeffs = 0.0_wp + c1 = 1.0_wp + c4 = stencil(1) - x0 + coeffs(1, 0) = 1.0_wp + + do i = 2, npts + mn = min(i - 1, m_order) + c2 = 1.0_wp + c5 = c4 + c4 = stencil(i) - x0 + + do j = 1, i - 1 + c3 = stencil(i) - stencil(j) + c2 = c2*c3 + + if (j == i - 1) then + do k = mn, 1, -1 + coeffs(i, k) = c1*(k*coeffs(i - 1, k - 1) - c5*coeffs(i - 1, k))/c2 + end do + coeffs(i, 0) = -c1*c5*coeffs(i - 1, 0)/c2 + end if + + do k = mn, 1, -1 + coeffs(j, k) = (c4*coeffs(j, k) - k*coeffs(j, k - 1))/c3 + end do + coeffs(j, 0) = c4*coeffs(j, 0)/c3 + end do + + c1 = c2 + end do + + end subroutine s_fornberg_weights + + !> The purpose of this procedure is to compute the barycentric weights for interpolation (only done once at start time) + impure subroutine s_compute_barycentric_weights(npts) + + integer, intent(in) :: npts + integer :: i, j, k, l, a, b + real(wp) :: prod_x, prod_y, prod_z, dx_loc, dy_loc, dz_loc + + $:GPU_PARALLEL_LOOP(private='[i, a, b, prod_x, dx_loc]', copyin = '[npts]') + do i = idwbuff(1)%beg + npts, idwbuff(1)%end - npts + do a = -npts, npts + prod_x = 1._wp + do b = -npts, npts + if (a /= b) then + dx_loc = x_cc(i + a) - x_cc(i + b) + prod_x = prod_x*dx_loc + end if + end do + weights_x_interp(a + npts + 1)%sf(i, 1, 1) = 1._wp/prod_x + end do + end do + $:END_GPU_PARALLEL_LOOP() + + $:GPU_PARALLEL_LOOP(private='[j, a, b, prod_y, dy_loc]', copyin = '[npts]') + do j = idwbuff(2)%beg + npts, idwbuff(2)%end - npts + do a = -npts, npts + prod_y = 1._wp + do b = -npts, npts + if (a /= b) then + dy_loc = y_cc(j + a) - y_cc(j + b) + prod_y = prod_y*dy_loc + end if + end do + weights_y_interp(a + npts + 1)%sf(j, 1, 1) = 1._wp/prod_y + end do + end do + $:END_GPU_PARALLEL_LOOP() + + if (num_dims == 3) then + $:GPU_PARALLEL_LOOP(private='[k, a, b, prod_z, dz_loc]', copyin = '[npts]') + do k = idwbuff(3)%beg + npts, idwbuff(3)%end - npts + do a = -npts, npts + prod_z = 1._wp + do b = -npts, npts + if (a /= b) then + dz_loc = z_cc(k + a) - z_cc(k + b) + prod_z = prod_z*dz_loc + end if + end do + weights_z_interp(a + npts + 1)%sf(k, 1, 1) = 1._wp/prod_z + end do + end do + end if + + end subroutine s_compute_barycentric_weights + + impure subroutine s_open_lag_bubble_evol + + character(LEN=path_len + 2*name_len) :: file_loc + logical :: file_exist + character(LEN=25) :: FMT + + write (file_loc, '(A,I0,A)') 'lag_bubble_evol_', proc_rank, '.dat' + file_loc = trim(case_dir) // '/D/' // trim(file_loc) + call my_inquire(trim(file_loc), file_exist) + + if (precision == 1) then + FMT = "(A16,A14,8A16)" + else + FMT = "(A24,A14,8A24)" + end if + + if (.not. file_exist) then + open (LAG_EVOL_ID, FILE=trim(file_loc), form='formatted', position='rewind') + write (LAG_EVOL_ID, FMT) 'currentTime', 'particleID', 'x', 'y', 'z', 'Vx', 'Vy', 'Vz', 'Fp_x', 'Fp_y', 'Fp_z', 'radius' + else + open (LAG_EVOL_ID, FILE=trim(file_loc), form='formatted', position='append') + end if + + end subroutine s_open_lag_bubble_evol + + !> Write particle evolution data at each output time step + !! @param qtime Current time + impure subroutine s_write_lag_particle_evol(qtime) + + real(wp), intent(in) :: qtime + integer :: k, ios + character(LEN=25) :: FMT + character(LEN=path_len + 2*name_len) :: file_loc, path + logical :: file_exist + + if (precision == 1) then + ! FMT = "(F16.8,I14,8F16.8)" + FMT = "(F16.8,I14,10F16.8)" + else + ! FMT = "(F24.16,I14,8F24.16)" + FMT = "(F24.16,I14,10F24.16)" + end if + + ! Cycle through list + do k = 1, n_el_particles_loc + write (LAG_EVOL_ID, FMT) qtime, lag_part_id(k, 1), particle_pos(k, 1, 1), particle_pos(k, 2, 1), particle_pos(k, 3, & + & 1), particle_vel(k, 1, 1), particle_vel(k, 2, 1), particle_vel(k, 3, 1), f_p(k, 1), f_p(k, 2), f_p(k, 3), & + & particle_rad(k, 1) + end do + + end subroutine s_write_lag_particle_evol + + impure subroutine s_close_lag_particle_evol + + close (LAG_EVOL_ID) + + end subroutine s_close_lag_particle_evol + + subroutine s_open_void_evol + + character(LEN=path_len + 2*name_len) :: file_loc + logical :: file_exist + + if (proc_rank == 0) then + write (file_loc, '(A)') 'voidfraction.dat' + file_loc = trim(case_dir) // '/D/' // trim(file_loc) + call my_inquire(trim(file_loc), file_exist) + if (.not. file_exist) then + open (LAG_VOID_ID, FILE=trim(file_loc), form='formatted', position='rewind') + ! write (12, *) 'currentTime, averageVoidFraction, ', & 'maximumVoidFraction, totalParticlesVolume' write (12, *) + ! 'The averageVoidFraction value does ', & 'not reflect the real void fraction in the cloud since the ', & 'cells + ! which do not have bubbles are not accounted' + else + open (LAG_VOID_ID, FILE=trim(file_loc), form='formatted', position='append') + end if + end if + + end subroutine s_open_void_evol + + !> Subroutine that writes some useful statistics related to the volume fraction of the particles (void fraction) in the + !! computatioational domain on each time step. + !! @param q_time Current time + impure subroutine s_write_void_evol_particles(qtime) + + real(wp), intent(in) :: qtime + real(wp) :: volcell, voltot + real(wp) :: lag_void_max, lag_void_avg, lag_vol + real(wp) :: void_max_glb, void_avg_glb, vol_glb + integer :: i, j, k + character(LEN=path_len + 2*name_len) :: file_loc + logical :: file_exist + + lag_void_max = 0._wp + lag_void_avg = 0._wp + lag_vol = 0._wp + $:GPU_PARALLEL_LOOP(private='[volcell]', collapse=3, reduction='[[lag_vol, lag_void_avg], [lag_void_max]]', & + & reductionOp='[+, MAX]', copy='[lag_vol, lag_void_avg, lag_void_max]') + do k = 0, p + do j = 0, n + do i = 0, m + lag_void_max = max(lag_void_max, 1._wp - q_particles(alphaf_id)%sf(i, j, k)) + call s_get_char_vol(i, j, k, volcell) + if ((1._wp - q_particles(alphaf_id)%sf(i, j, k)) > 5.0e-11_wp) then + lag_void_avg = lag_void_avg + (1._wp - q_particles(alphaf_id)%sf(i, j, k))*volcell + lag_vol = lag_vol + volcell + end if + end do + end do + end do + $:END_GPU_PARALLEL_LOOP() + +#ifdef MFC_MPI + if (num_procs > 1) then + call s_mpi_allreduce_max(lag_void_max, void_max_glb) + lag_void_max = void_max_glb + call s_mpi_allreduce_sum(lag_vol, vol_glb) + lag_vol = vol_glb + call s_mpi_allreduce_sum(lag_void_avg, void_avg_glb) + lag_void_avg = void_avg_glb + end if +#endif + voltot = lag_void_avg + ! This voidavg value does not reflect the real void fraction in the cloud since the cell which does not have bubbles are not + ! accounted + if (lag_vol > 0._wp) lag_void_avg = lag_void_avg/lag_vol + + if (proc_rank == 0) then + write (LAG_VOID_ID, '(6X,4e24.8)') qtime, lag_void_avg, lag_void_max, voltot + end if + + end subroutine s_write_void_evol_particles + + subroutine s_close_void_evol + + if (proc_rank == 0) close (LAG_VOID_ID) + + end subroutine s_close_void_evol + + !> Subroutine that writes the restarting files for the particles in the lagrangian solver. + !! @param t_step Current time step + impure subroutine s_write_restart_lag_particles(t_step) + + ! Generic string used to store the address of a particular file + integer, intent(in) :: t_step + character(LEN=path_len + 2*name_len) :: file_loc + logical :: file_exist + integer :: part_id, tot_part + integer :: i, k + +#ifdef MFC_MPI + ! For Parallel I/O + integer :: ifile, ierr + integer, dimension(MPI_STATUS_SIZE) :: status + integer(KIND=MPI_OFFSET_KIND) :: disp + integer :: view + integer, dimension(2) :: gsizes, lsizes, start_idx_part + integer, dimension(num_procs) :: part_order, part_ord_mpi + integer, dimension(num_procs) :: proc_particle_counts + real(wp), dimension(1:1,1:lag_io_vars) :: dummy + dummy = 0._wp + + part_id = 0 + if (n_el_particles_loc /= 0) then + do k = 1, n_el_particles_loc + if (particle_in_domain_physical(particle_pos(k,1:3,1))) then + part_id = part_id + 1 + end if + end do + end if + + if (.not. parallel_io) return + + lsizes(1) = part_id + lsizes(2) = lag_io_vars + + ! Total number of particles + call MPI_ALLREDUCE(part_id, tot_part, 1, MPI_integer, MPI_SUM, MPI_COMM_WORLD, ierr) + + call MPI_ALLGATHER(part_id, 1, MPI_INTEGER, proc_particle_counts, 1, MPI_INTEGER, MPI_COMM_WORLD, ierr) + + ! Calculate starting index for this processor's particles + call MPI_EXSCAN(lsizes(1), start_idx_part(1), 1, MPI_INTEGER, MPI_SUM, MPI_COMM_WORLD, ierr) + if (proc_rank == 0) start_idx_part(1) = 0 + start_idx_part(2) = 0 + + gsizes(1) = tot_part + gsizes(2) = lag_io_vars + + write (file_loc, '(A,I0,A)') 'lag_bubbles_', t_step, '.dat' + file_loc = trim(case_dir) // '/restart_data' // trim(mpiiofs) // trim(file_loc) + + ! Clean up existing file + if (proc_rank == 0) then + inquire (FILE=trim(file_loc), EXIST=file_exist) + if (file_exist) then + call MPI_FILE_DELETE(file_loc, mpi_info_int, ierr) + end if + end if + + call MPI_BARRIER(MPI_COMM_WORLD, ierr) + + if (proc_rank == 0) then + call MPI_FILE_OPEN(MPI_COMM_SELF, file_loc, ior(MPI_MODE_WRONLY, MPI_MODE_CREATE), mpi_info_int, ifile, ierr) + + ! Write header using MPI I/O for consistency + call MPI_FILE_WRITE(ifile, tot_part, 1, MPI_INTEGER, status, ierr) + call MPI_FILE_WRITE(ifile, mytime, 1, mpi_p, status, ierr) + call MPI_FILE_WRITE(ifile, dt, 1, mpi_p, status, ierr) + call MPI_FILE_WRITE(ifile, num_procs, 1, MPI_INTEGER, status, ierr) + call MPI_FILE_WRITE(ifile, proc_particle_counts, num_procs, MPI_INTEGER, status, ierr) + + call MPI_FILE_CLOSE(ifile, ierr) + end if + + call MPI_BARRIER(MPI_COMM_WORLD, ierr) + + if (part_id > 0) then + allocate (MPI_IO_DATA_lag_bubbles(max(1, part_id),1:lag_io_vars)) + + i = 1 + do k = 1, n_el_particles_loc + if (particle_in_domain_physical(particle_pos(k,1:3,1))) then + MPI_IO_DATA_lag_bubbles(i, 1) = real(lag_part_id(k, 1)) + MPI_IO_DATA_lag_bubbles(i,2:4) = particle_pos(k,1:3,1) + MPI_IO_DATA_lag_bubbles(i,5:7) = particle_posPrev(k,1:3,1) + MPI_IO_DATA_lag_bubbles(i,8:10) = particle_vel(k,1:3,1) + MPI_IO_DATA_lag_bubbles(i, 11) = particle_rad(k, 1) + MPI_IO_DATA_lag_bubbles(i, 13) = particle_R0(k) + MPI_IO_DATA_lag_bubbles(i, 14) = Rmax_stats_part(k) + MPI_IO_DATA_lag_bubbles(i, 15) = Rmin_stats_part(k) + MPI_IO_DATA_lag_bubbles(i, 19) = particle_mass(k) + i = i + 1 + end if + end do + + call MPI_TYPE_CREATE_SUBARRAY(2, gsizes, lsizes, start_idx_part, MPI_ORDER_FORTRAN, mpi_p, view, ierr) + call MPI_TYPE_COMMIT(view, ierr) + + call MPI_FILE_OPEN(MPI_COMM_WORLD, file_loc, ior(MPI_MODE_WRONLY, MPI_MODE_CREATE), mpi_info_int, ifile, ierr) + + ! Skip header (written by rank 0) + disp = int(sizeof(tot_part) + 2*sizeof(mytime) + sizeof(num_procs) + num_procs*sizeof(proc_particle_counts(1)), & + & MPI_OFFSET_KIND) + call MPI_FILE_SET_VIEW(ifile, disp, mpi_p, view, 'native', mpi_info_int, ierr) + + call MPI_FILE_WRITE_ALL(ifile, MPI_IO_DATA_lag_bubbles, lag_io_vars*part_id, mpi_p, status, ierr) + + call MPI_FILE_CLOSE(ifile, ierr) + + deallocate (MPI_IO_DATA_lag_bubbles) + else + call MPI_TYPE_CONTIGUOUS(0, mpi_p, view, ierr) + call MPI_TYPE_COMMIT(view, ierr) + + call MPI_FILE_OPEN(MPI_COMM_WORLD, file_loc, ior(MPI_MODE_WRONLY, MPI_MODE_CREATE), mpi_info_int, ifile, ierr) + + ! Skip header (written by rank 0) + disp = int(sizeof(tot_part) + 2*sizeof(mytime) + sizeof(num_procs) + num_procs*sizeof(proc_particle_counts(1)), & + & MPI_OFFSET_KIND) + call MPI_FILE_SET_VIEW(ifile, disp, mpi_p, view, 'native', mpi_info_int, ierr) + + call MPI_FILE_WRITE_ALL(ifile, dummy, 0, mpi_p, status, ierr) + + call MPI_FILE_CLOSE(ifile, ierr) + end if +#endif + + end subroutine s_write_restart_lag_particles + + !> Calculate global maximum and minimum R/R0 ratio across all particles. + subroutine s_calculate_lag_particle_stats() + + integer :: k + + $:GPU_PARALLEL_LOOP(private='[k]', reduction='[[Rmax_glb], [Rmin_glb]]', reductionOp='[MAX, MIN]', & + & copy='[Rmax_glb, Rmin_glb]') + do k = 1, n_el_particles_loc + Rmax_glb = max(Rmax_glb, particle_rad(k, 1)/particle_R0(k)) + Rmin_glb = min(Rmin_glb, particle_rad(k, 1)/particle_R0(k)) + Rmax_stats_part(k) = max(Rmax_stats_part(k), particle_rad(k, 1)/particle_R0(k)) + Rmin_stats_part(k) = min(Rmin_stats_part(k), particle_rad(k, 1)/particle_R0(k)) + end do + $:END_GPU_PARALLEL_LOOP() + + end subroutine s_calculate_lag_particle_stats + + impure subroutine s_open_lag_particle_stats() + + character(LEN=path_len + 2*name_len) :: file_loc + character(LEN=20) :: FMT + logical :: file_exist + + write (file_loc, '(A,I0,A)') 'stats_lag_bubbles_', proc_rank, '.dat' + file_loc = trim(case_dir) // '/D/' // trim(file_loc) + call my_inquire(trim(file_loc), file_exist) + + if (precision == 1) then + FMT = "(A10,A14,5A16)" + else + FMT = "(A10,A14,5A24)" + end if + + if (.not. file_exist) then + open (LAG_STATS_ID, FILE=trim(file_loc), form='formatted', position='rewind') + write (LAG_STATS_ID, *) 'proc_rank, particleID, x, y, z, Rmax_glb, Rmin_glb' + else + open (LAG_STATS_ID, FILE=trim(file_loc), form='formatted', position='append') + end if + + end subroutine s_open_lag_particle_stats + + !> Write particle radius statistics to file. + impure subroutine s_write_lag_particle_stats() + + integer :: k + character(LEN=path_len + 2*name_len) :: file_loc + character(LEN=20) :: FMT + + $:GPU_UPDATE(host='[Rmax_glb, Rmin_glb]') + + if (precision == 1) then + FMT = "(I10,I14,5F16.8)" + else + FMT = "(I10,I14,5F24.16)" + end if + + do k = 1, n_el_particles_loc + write (LAG_STATS_ID, FMT) proc_rank, lag_part_id(k, 1), particle_pos(k, 1, 1), particle_pos(k, 2, 1), particle_pos(k, & + & 3, 1), Rmax_stats_part(k), Rmin_stats_part(k) + end do + + end subroutine s_write_lag_particle_stats + + subroutine s_close_lag_particle_stats + + close (LAG_STATS_ID) + + end subroutine s_close_lag_particle_stats + + !> The purpose of this subroutine is to remove one specific particle if dt is too small. + !! @param part_id Particle id + impure subroutine s_copy_lag_particle(dest, src) + + integer, intent(in) :: src, dest + + particle_R0(dest) = particle_R0(src) + Rmax_stats_part(dest) = Rmax_stats_part(src) + Rmin_stats_part(dest) = Rmin_stats_part(src) + particle_mass(dest) = particle_mass(src) + lag_part_id(dest, 1) = lag_part_id(src, 1) + particle_rad(dest,1:2) = particle_rad(src,1:2) + particle_vel(dest,1:3,1:2) = particle_vel(src,1:3,1:2) + particle_s(dest,1:3,1:2) = particle_s(src,1:3,1:2) + particle_pos(dest,1:3,1:2) = particle_pos(src,1:3,1:2) + particle_posPrev(dest,1:3,1:2) = particle_posPrev(src,1:3,1:2) + particle_draddt(dest,1:lag_num_ts) = particle_draddt(src,1:lag_num_ts) + f_p(dest,1:3) = f_p(src,1:3) + particle_dposdt(dest,1:3,1:lag_num_ts) = particle_dposdt(src,1:3,1:lag_num_ts) + particle_dveldt(dest,1:3,1:lag_num_ts) = particle_dveldt(src,1:3,1:lag_num_ts) + + end subroutine s_copy_lag_particle + + !> The purpose of this subroutine is to deallocate variables + impure subroutine s_finalize_particle_lagrangian_solver() + + integer :: i + + if (lag_params%write_void_evol) call s_close_void_evol + if (lag_params%write_bubbles) call s_close_lag_particle_evol() + if (lag_params%write_bubbles_stats) call s_close_lag_particle_stats() + + do i = 1, q_particles_idx + @:DEALLOCATE(q_particles(i)%sf) + end do + @:DEALLOCATE(q_particles) + + do i = 1, nField_vars + @:DEALLOCATE(field_vars(i)%sf) + end do + @:DEALLOCATE(field_vars) + + do i = 1, nWeights_interp + @:DEALLOCATE(weights_x_interp(i)%sf) + end do + @:DEALLOCATE(weights_x_interp) + + do i = 1, nWeights_interp + @:DEALLOCATE(weights_y_interp(i)%sf) + end do + @:DEALLOCATE(weights_y_interp) + + do i = 1, nWeights_interp + @:DEALLOCATE(weights_z_interp(i)%sf) + end do + @:DEALLOCATE(weights_z_interp) + + do i = 1, nWeights_grad + @:DEALLOCATE(weights_x_grad(i)%sf) + end do + @:DEALLOCATE(weights_x_grad) + + do i = 1, nWeights_grad + @:DEALLOCATE(weights_y_grad(i)%sf) + end do + @:DEALLOCATE(weights_y_grad) + + do i = 1, nWeights_grad + @:DEALLOCATE(weights_z_grad(i)%sf) + end do + @:DEALLOCATE(weights_z_grad) + + ! Deallocating space + @:DEALLOCATE(lag_part_id) + @:DEALLOCATE(gid_to_local) + @:DEALLOCATE(particle_R0) + @:DEALLOCATE(Rmax_stats_part) + @:DEALLOCATE(Rmin_stats_part) + @:DEALLOCATE(particle_mass) + @:DEALLOCATE(p_AM) + @:DEALLOCATE(p_owner_rank) + @:DEALLOCATE(particle_rad) + @:DEALLOCATE(particle_pos) + @:DEALLOCATE(particle_posPrev) + @:DEALLOCATE(particle_vel) + @:DEALLOCATE(particle_s) + @:DEALLOCATE(particle_draddt) + @:DEALLOCATE(particle_dposdt) + @:DEALLOCATE(particle_dveldt) + @:DEALLOCATE(f_p) + @:DEALLOCATE(gSum) + + @:DEALLOCATE(force_recv_ids) + @:DEALLOCATE(force_recv_vals) + + @:DEALLOCATE(keep_bubble) + @:DEALLOCATE(wrap_bubble_loc, wrap_bubble_dir) + + @:DEALLOCATE(linked_list) + @:DEALLOCATE(particle_head) + + ! Deallocate cell list arrays + @:DEALLOCATE(cell_list_start) + @:DEALLOCATE(cell_list_count) + @:DEALLOCATE(cell_list_idx) + + end subroutine s_finalize_particle_lagrangian_solver + +end module m_particles_EL diff --git a/src/simulation/m_particles_EL_kernels.fpp b/src/simulation/m_particles_EL_kernels.fpp new file mode 100644 index 0000000000..08d2c22c8c --- /dev/null +++ b/src/simulation/m_particles_EL_kernels.fpp @@ -0,0 +1,904 @@ +!> +!! @file m_particles_EL_kernels.fpp +!! @brief Contains module m_particles_EL_kernels + +#:include 'macros.fpp' + +!> @brief This module contains kernel functions used to map the effect of the lagrangian particles in the Eulerian framework. +module m_particles_EL_kernels + + use m_mpi_proxy !< Message passing interface (MPI) module proxy + use ieee_arithmetic !< For checking NaN + + implicit none + + ! Cell list for particle-to-cell mapping (rebuilt each RK stage before smearing) + integer, allocatable, dimension(:,:,:) :: cell_list_start ! (0:m, 0:n, 0:p) + integer, allocatable, dimension(:,:,:) :: cell_list_count ! (0:m, 0:n, 0:p) + integer, allocatable, dimension(:) :: cell_list_idx ! (1:nParticles_glb) sorted particle indices + $:GPU_DECLARE(create='[cell_list_start, cell_list_count, cell_list_idx]') + +contains + + ! !> The purpose of this subroutine is to compute each particles total contribution to the gaussian for proper normalization + subroutine s_compute_gaussian_contribution(rad, pos, cell, func_s) + + $:GPU_ROUTINE(function_name='s_compute_gaussian_contribution',parallelism='[seq]', cray_inline=True) + + real(wp), intent(in) :: rad + real(wp), intent(in), dimension(3) :: pos + integer, intent(in), dimension(3) :: cell + real(wp), intent(out) :: func_s + real(wp) :: volpart, stddsv, Vol_loc, func + real(wp), dimension(3) :: nodecoord, center + integer :: ip, jp, kp, di, dj, dk, di_beg, di_end, dj_beg, dj_end, dk_beg, dk_end, mapCells_loc + integer, dimension(3) :: cellijk + + mapCells_loc = 1 + + volpart = (4._wp/3._wp)*pi*rad**3 + + call s_compute_stddsv(cell, volpart, stddsv) + + ip = cell(1) + jp = cell(2) + kp = cell(3) + + di_beg = ip - mapCells_loc + di_end = ip + mapCells_loc + dj_beg = jp - mapCells_loc + dj_end = jp + mapCells_loc + dk_beg = kp + dk_end = kp + + if (num_dims == 3) then + dk_beg = kp - mapCells_loc + dk_end = kp + mapCells_loc + end if + + func_s = 0._wp + do dk = dk_beg, dk_end + do dj = dj_beg, dj_end + do di = di_beg, di_end + nodecoord(1) = x_cc(di) + nodecoord(2) = y_cc(dj) + nodecoord(3) = 0._wp + if (p > 0) nodecoord(3) = z_cc(dk) + + cellijk(1) = di + cellijk(2) = dj + cellijk(3) = dk + + center(1:2) = pos(1:2) + center(3) = 0._wp + if (p > 0) center(3) = pos(3) + + Vol_loc = dx(cellijk(1))*dy(cellijk(2)) + if (num_dims == 3) Vol_loc = dx(cellijk(1))*dy(cellijk(2))*dz(cellijk(3)) + + call s_applygaussian(center, cellijk, nodecoord, stddsv, 0._wp, func) + + func_s = func_s + func*Vol_loc + end do + end do + end do + + end subroutine s_compute_gaussian_contribution + + !> The purpose of this subroutine is to compute the gaussian smearing of particle volume fraction and source terms with atomic + !! cell updates + subroutine s_gaussian_atomic(rad, vel, pos, force_p, gauSum, cell, updatedvar, onlyBeta) + + $:GPU_ROUTINE(function_name='s_gaussian_atomic',parallelism='[seq]', cray_inline=True) + + real(wp), intent(in) :: rad, gauSum + real(wp), intent(in), dimension(3) :: pos, vel, force_p + integer, intent(in), dimension(3) :: cell + type(scalar_field), dimension(:), intent(inout) :: updatedvar + real(wp) :: volpart, stddsv, Vol_loc, func, weight + real(wp) :: fp_x, fp_y, fp_z, vp_x, vp_y, vp_z + real(wp) :: addFun_alphap, addFun_alphap_vp_x, addFun_alphap_vp_y, addFun_alphap_vp_z + real(wp) :: addFun2_x, addFun2_y, addFun2_z, addFun_E + real(wp), dimension(3) :: nodecoord, center + integer :: ip, jp, kp, di, dj, dk, di_beg, di_end, dj_beg, dj_end, dk_beg, dk_end, mapCells_loc + integer, dimension(3) :: cellijk + logical, intent(in) :: onlyBeta + + mapCells_loc = 1 + + volpart = (4._wp/3._wp)*pi*rad**3 + + call s_compute_stddsv(cell, volpart, stddsv) + + ip = cell(1) + jp = cell(2) + kp = cell(3) + + di_beg = ip - mapCells_loc + di_end = ip + mapCells_loc + dj_beg = jp - mapCells_loc + dj_end = jp + mapCells_loc + dk_beg = kp + dk_end = kp + + if (num_dims == 3) then + dk_beg = kp - mapCells_loc + dk_end = kp + mapCells_loc + end if + + fp_x = -force_p(1) + fp_y = -force_p(2) + fp_z = -force_p(3) + + vp_x = vel(1) + vp_y = vel(2) + vp_z = vel(3) + + center(1:2) = pos(1:2) + center(3) = 0._wp + if (p > 0) center(3) = pos(3) + + do dk = dk_beg, dk_end + do dj = dj_beg, dj_end + do di = di_beg, di_end + nodecoord(1) = x_cc(di) + nodecoord(2) = y_cc(dj) + nodecoord(3) = 0._wp + if (p > 0) nodecoord(3) = z_cc(dk) + + cellijk(1) = di + cellijk(2) = dj + cellijk(3) = dk + + Vol_loc = dx(cellijk(1))*dy(cellijk(2)) + if (num_dims == 3) Vol_loc = Vol_loc*dz(cellijk(3)) + + call s_applygaussian(center, cellijk, nodecoord, stddsv, 0._wp, func) + + if (gauSum <= 0._wp) return + weight = func/gauSum + + addFun_alphap = weight*volpart + $:GPU_ATOMIC(atomic='update') + updatedvar(1)%sf(cellijk(1), cellijk(2), cellijk(3)) = updatedvar(1)%sf(cellijk(1), cellijk(2), & + & cellijk(3)) + real(addFun_alphap, kind=stp) + + if (lag_params%solver_approach == 2 .and. .not. onlyBeta) then + ! Update particle momentum field(x) + addFun_alphap_vp_x = weight*volpart*vp_x + $:GPU_ATOMIC(atomic='update') + updatedvar(2)%sf(cellijk(1), cellijk(2), cellijk(3)) = updatedvar(2)%sf(cellijk(1), cellijk(2), & + & cellijk(3)) + real(addFun_alphap_vp_x, kind=stp) + + ! Update particle momentum field(y) + addFun_alphap_vp_y = weight*volpart*vp_y + $:GPU_ATOMIC(atomic='update') + updatedvar(3)%sf(cellijk(1), cellijk(2), cellijk(3)) = updatedvar(3)%sf(cellijk(1), cellijk(2), & + & cellijk(3)) + real(addFun_alphap_vp_y, kind=stp) + + if (num_dims == 3) then + ! Update particle momentum field(z) + addFun_alphap_vp_z = weight*volpart*vp_z + $:GPU_ATOMIC(atomic='update') + updatedvar(4)%sf(cellijk(1), cellijk(2), cellijk(3)) = updatedvar(4)%sf(cellijk(1), cellijk(2), & + & cellijk(3)) + real(addFun_alphap_vp_z, kind=stp) + end if + + ! Update x-momentum source term + addFun2_x = weight*fp_x + $:GPU_ATOMIC(atomic='update') + updatedvar(5)%sf(cellijk(1), cellijk(2), cellijk(3)) = updatedvar(5)%sf(cellijk(1), cellijk(2), & + & cellijk(3)) + real(addFun2_x, kind=stp) + + ! Update y-momentum source term + addFun2_y = weight*fp_y + $:GPU_ATOMIC(atomic='update') + updatedvar(6)%sf(cellijk(1), cellijk(2), cellijk(3)) = updatedvar(6)%sf(cellijk(1), cellijk(2), & + & cellijk(3)) + real(addFun2_y, kind=stp) + + if (num_dims == 3) then + ! Update z-momentum source term + addFun2_z = weight*fp_z + $:GPU_ATOMIC(atomic='update') + updatedvar(7)%sf(cellijk(1), cellijk(2), cellijk(3)) = updatedvar(7)%sf(cellijk(1), cellijk(2), & + & cellijk(3)) + real(addFun2_z, kind=stp) + end if + + ! Update energy source term + addFun_E = 0._wp + $:GPU_ATOMIC(atomic='update') + updatedvar(8)%sf(cellijk(1), cellijk(2), cellijk(3)) = updatedvar(8)%sf(cellijk(1), cellijk(2), & + & cellijk(3)) + real(addFun_E, kind=stp) + end if + end do + end do + end do + + end subroutine s_gaussian_atomic + + !> The purpose of this subroutine is to apply the gaussian kernel function for each particle (Maeda and Colonius, 2018)). + subroutine s_applygaussian(center, cellaux, nodecoord, stddsv, strength_idx, func) + + $:GPU_ROUTINE(function_name='s_applygaussian',parallelism='[seq]', cray_inline=True) + + real(wp), dimension(3), intent(in) :: center + integer, dimension(3), intent(in) :: cellaux + real(wp), dimension(3), intent(in) :: nodecoord + real(wp), intent(in) :: stddsv + real(wp), intent(in) :: strength_idx + real(wp), intent(out) :: func + integer :: i + real(wp) :: distance + real(wp) :: theta, dtheta, L2, dzp, Lz2, zc + real(wp) :: Nr, Nr_count + + distance = sqrt((center(1) - nodecoord(1))**2._wp + (center(2) - nodecoord(2))**2._wp + (center(3) - nodecoord(3))**2._wp) + + if (num_dims == 3) then + !> 3D gaussian function + func = exp(-0.5_wp*(distance/stddsv)**2._wp)/(sqrt(2._wp*pi)*stddsv)**3._wp + else + if (cyl_coord) then + !> 2D cylindrical function: + ! We smear particles in the azimuthal direction for given r + theta = 0._wp + Nr = ceiling(2._wp*pi*nodecoord(2)/(y_cb(cellaux(2)) - y_cb(cellaux(2) - 1))) + dtheta = 2._wp*pi/Nr + L2 = center(2)**2._wp + nodecoord(2)**2._wp - 2._wp*center(2)*nodecoord(2)*cos(theta) + distance = sqrt((center(1) - nodecoord(1))**2._wp + L2) + ! Factor 2._wp is for symmetry (upper half of the 2D field (+r) is considered) + func = dtheta/2._wp/pi*exp(-0.5_wp*(distance/stddsv)**2._wp)/(sqrt(2._wp*pi)*stddsv)**3._wp + Nr_count = 0._wp + do while (Nr_count < Nr - 1._wp) + Nr_count = Nr_count + 1._wp + theta = Nr_count*dtheta + ! trigonometric relation + L2 = center(2)**2._wp + nodecoord(2)**2._wp - 2._wp*center(2)*nodecoord(2)*cos(theta) + distance = sqrt((center(1) - nodecoord(1))**2._wp + L2) + ! nodecoord(2)*dtheta is the azimuthal width of the cell + func = func + dtheta/2._wp/pi*exp(-0.5_wp*(distance/stddsv)**2._wp)/(sqrt(2._wp*pi)*stddsv) & + & **(3._wp*(strength_idx + 1._wp)) + end do + else + !> 2D cartesian function: Equation (48) from Maeda and Colonius 2018 + ! We smear particles considering a virtual depth (lag_params%charwidth) with lag_params%charNz cells + dzp = (lag_params%charwidth/(lag_params%charNz + 1._wp)) + + func = 0._wp + do i = 0, lag_params%charNz + zc = (-lag_params%charwidth/2._wp + dzp*(0.5_wp + i)) ! Center of virtual cell i in z-direction + Lz2 = (center(3) - zc)**2._wp + distance = sqrt((center(1) - nodecoord(1))**2._wp + (center(2) - nodecoord(2))**2._wp + Lz2) + func = func + dzp/lag_params%charwidth*exp(-0.5_wp*(distance/stddsv)**2._wp)/(sqrt(2._wp*pi)*stddsv)**3._wp + end do + end if + end if + + end subroutine s_applygaussian + + !> Calculates the standard deviation of the particle being smeared in the Eulerian framework. + !! @param cell Cell where the particle is located + !! @param volpart Volume of the particle + !! @param stddsv Standard deviaton + subroutine s_compute_stddsv(cell, volpart, stddsv) + + $:GPU_ROUTINE(function_name='s_compute_stddsv',parallelism='[seq]', cray_inline=True) + + integer, dimension(3), intent(in) :: cell + real(wp), intent(in) :: volpart + real(wp), intent(out) :: stddsv + real(wp) :: chardist, charvol + real(wp) :: rad + + !> Compute characteristic distance + chardist = sqrt(dx(cell(1))*dy(cell(2))) + if (p > 0) chardist = (dx(cell(1))*dy(cell(2))*dz(cell(3)))**(1._wp/3._wp) + + !> Compute characteristic volume + if (p > 0) then + charvol = dx(cell(1))*dy(cell(2))*dz(cell(3)) + else + if (cyl_coord) then + charvol = dx(cell(1))*dy(cell(2))*y_cc(cell(2))*2._wp*pi + else + charvol = dx(cell(1))*dy(cell(2))*lag_params%charwidth + end if + end if + + rad = (3._wp*volpart/(4._wp*pi))**(1._wp/3._wp) + stddsv = lag_params%epsilonb*max(chardist, rad) + + end subroutine s_compute_stddsv + + !> The purpose of this subroutine is to check if the current cell is outside the computational domain or not (including ghost + !! cells). + !! @param cellaux Tested cell to smear the particle effect in. + !! @param celloutside If true, then cellaux is outside the computational domain. + subroutine s_check_celloutside(cellaux, celloutside) + + $:GPU_ROUTINE(function_name='s_check_celloutside',parallelism='[seq]', cray_inline=True) + + integer, dimension(3), intent(inout) :: cellaux + logical, intent(out) :: celloutside + + celloutside = .false. + + if (num_dims == 2) then + if ((cellaux(1) < -buff_size) .or. (cellaux(2) < -buff_size)) then + celloutside = .true. + end if + + if ((cellaux(1) > m + buff_size) .or. (cellaux(2) > n + buff_size)) then + celloutside = .true. + end if + else + if ((cellaux(1) < -buff_size) .or. (cellaux(2) < -buff_size) .or. (cellaux(3) < -buff_size)) then + celloutside = .true. + end if + + if ((cellaux(1) > m + buff_size) .or. (cellaux(2) > n + buff_size) .or. (cellaux(3) > p + buff_size)) then + celloutside = .true. + end if + end if + + end subroutine s_check_celloutside + + !> This subroutine transforms the computational coordinates of the particle from real type into integer. + !! @param s Computational coordinates of the particle, real type + !! @param get_cell Computational coordinates of the particle, integer type + subroutine s_get_cell(s_cell, get_cell) + + $:GPU_ROUTINE(function_name='s_get_cell',parallelism='[seq]', cray_inline=True) + + real(wp), dimension(3), intent(in) :: s_cell + integer, dimension(3), intent(out) :: get_cell + integer :: i + + get_cell(:) = int(s_cell(:)) + do i = 1, num_dims + if (s_cell(i) < 0._wp) get_cell(i) = get_cell(i) - 1 + end do + + end subroutine s_get_cell + + !> The purpose of this procedure is to calculate the characteristic cell volume + !! @param cell Computational coordinates (x, y, z) + !! @param Charvol Characteristic volume + subroutine s_get_char_vol(cellx, celly, cellz, Charvol) + + $:GPU_ROUTINE(function_name='s_get_char_vol',parallelism='[seq]', cray_inline=True) + + integer, intent(in) :: cellx, celly, cellz + real(wp), intent(out) :: Charvol + + if (p > 0) then + Charvol = dx(cellx)*dy(celly)*dz(cellz) + else + if (cyl_coord) then + Charvol = dx(cellx)*dy(celly)*y_cc(celly)*2._wp*pi + else + Charvol = dx(cellx)*dy(celly)*lag_params%charwidth + end if + end if + + end subroutine s_get_char_vol + + !! This function calculates the force on a particle based on the pressure gradient, velocity, and drag model. + !! @param pos Position of the particle + !! @param rad Radius of the particle + !! @param vel_p Velocity of the particle + !! @param mass_p Particle mass + !! @param Re Viscosity! + !! @param rho Density of the fluid + !! @param vol_frac Particle Volume Fraction + !! @param cell Computational coordinates of the particle + !! @param q_prim_vf Eulerian field with primitive variables + !! @return a Acceleration of the particle in direction i + subroutine s_get_particle_force(pos, rad, vel_p, mass_p, Re, gamm, vol_frac, drhodt, cell, q_prim_vf, fieldvars, wx, wy, wz, & + & force, rmass_add) + $:GPU_ROUTINE(parallelism='[seq]') + real(wp), intent(in) :: rad, mass_p, Re, gamm, vol_frac, drhodt + real(wp), dimension(3), intent(in) :: pos + integer, dimension(3), intent(in) :: cell + real(wp), dimension(3), intent(in) :: vel_p + type(scalar_field), dimension(:), intent(in) :: fieldvars + type(scalar_field), dimension(:), intent(in) :: wx, wy, wz + type(scalar_field), dimension(sys_size), intent(in) :: q_prim_vf + real(wp), dimension(3), intent(out) :: force + real(wp), intent(out) :: rmass_add + real(wp) :: a, vol, rho_fluid, pressure_fluid + real(wp), dimension(3) :: v_rel, dp + real(wp), dimension(fd_order) :: xi, eta, L + real(wp) :: particle_diam, gas_mu, vmag, cson + real(wp) :: slip_velocity_x, slip_velocity_y, slip_velocity_z, beta + real(wp), dimension(3) :: fluid_vel + integer :: dir + + ! Added pass params + real(wp) :: mach, Cam, flux_f, flux_b, div_u, SDrho, vpgradrho + real(wp), dimension(3) :: rhoDuDt, grad_rho, fam + integer, dimension(3) :: p1 + + force = 0._wp + dp = 0._wp + grad_rho = 0._wp + fam = 0._wp + fluid_vel = 0._wp + v_rel = 0._wp + rhoDuDt = 0._wp + SDrho = 0._wp + ! div_u = 0._wp + + !!Interpolation - either even ordered barycentric or 0th order + if (lag_params%interpolation_order > 1) then + rho_fluid = f_interp_barycentric(pos, cell, q_prim_vf, 1, wx, wy, wz) + pressure_fluid = f_interp_barycentric(pos, cell, q_prim_vf, E_idx, wx, wy, wz) + do dir = 1, num_dims + if (lag_params%pressure_force .or. lag_params%added_mass_model > 0) then + dp(dir) = f_interp_barycentric(pos, cell, fieldvars, dir, wx, wy, wz) + end if + if (lag_params%added_mass_model > 0) then + grad_rho(dir) = f_interp_barycentric(pos, cell, fieldvars, 3 + dir, wx, wy, wz) + ! div_u = div_u + f_interp_barycentric(pos, cell, fieldvars, 6 + dir, wx, wy, wz) + end if + fluid_vel(dir) = f_interp_barycentric(pos, cell, q_prim_vf, momxb + dir - 1, wx, wy, wz) + end do + else + rho_fluid = q_prim_vf(1)%sf(cell(1), cell(2), cell(3)) + pressure_fluid = q_prim_vf(E_idx)%sf(cell(1), cell(2), cell(3)) + do dir = 1, num_dims + if (lag_params%pressure_force .or. lag_params%added_mass_model > 0) then + dp(dir) = fieldvars(dir)%sf(cell(1), cell(2), cell(3)) + end if + if (lag_params%added_mass_model > 0) then + grad_rho(dir) = fieldvars(3 + dir)%sf(cell(1), cell(2), cell(3)) + ! div_u = div_u + fieldvars(6 + dir)%sf(cell(1), cell(2), cell(3)) + end if + fluid_vel(dir) = q_prim_vf(momxb + dir - 1)%sf(cell(1), cell(2), cell(3)) + end do + end if + + v_rel = vel_p - fluid_vel + + if (lag_params%qs_drag_model > 0 .or. lag_params%added_mass_model > 0) then + ! Quasi-steady Drag Force Parameters + slip_velocity_x = fluid_vel(1) - vel_p(1) + slip_velocity_y = fluid_vel(2) - vel_p(2) + if (num_dims == 3) then + slip_velocity_z = fluid_vel(3) - vel_p(3) + vmag = sqrt(slip_velocity_x*slip_velocity_x + slip_velocity_y*slip_velocity_y + slip_velocity_z*slip_velocity_z) + else if (num_dims == 2) then + vmag = sqrt(slip_velocity_x*slip_velocity_x + slip_velocity_y*slip_velocity_y) + end if + particle_diam = rad*2._wp + if (rho_fluid > 0._wp) then + cson = sqrt((gamm*pressure_fluid)/rho_fluid) + else + cson = 1._wp + end if + gas_mu = Re + end if + + if (lag_params%added_mass_model > 0) then + rhoDuDt = -dp + vpgradrho = dot_product(vel_p, grad_rho) + SDrho = drhodt + fluid_vel(1)*grad_rho(1) + fluid_vel(2)*grad_rho(2) + fluid_vel(3)*grad_rho(3) + mach = vmag/cson + end if + + ! Step 1: Force component quasi-steady + if (lag_params%qs_drag_model == 1) then + beta = QS_Parmar(rho_fluid, cson, gas_mu, gamm, vmag, particle_diam, vol_frac) + force = force - beta*v_rel + else if (lag_params%qs_drag_model == 2) then + beta = QS_Osnes(rho_fluid, cson, gas_mu, gamm, vmag, particle_diam, vol_frac) + force = force - beta*v_rel + else if (lag_params%qs_drag_model == 3) then + beta = QS_ModifiedParmar(rho_fluid, cson, gas_mu, gamm, vmag, particle_diam, vol_frac) + force = force - beta*v_rel + else if (lag_params%qs_drag_model == 4) then + beta = QS_Gidaspow(rho_fluid, cson, gas_mu, gamm, vmag, particle_diam, vol_frac) + force = force - beta*v_rel + else + ! No Quasi-Steady drag + end if + + ! Step 1.1: Stokes drag + if (lag_params%stokes_drag == 1) then ! Free slip Stokes drag + force = force - 4._wp*pi*gas_mu*rad*v_rel + else if (lag_params%stokes_drag == 2) then ! No slip Stokes drag + force = force - 6._wp*pi*gas_mu*rad*v_rel + else + ! No stokes drag + end if + + ! Step 2: Pressure Gradient Force + if (lag_params%pressure_force) then + vol = (4._wp/3._wp)*pi*(rad**3._wp) + force = force - vol*dp + end if + + ! Step 3: Gravitational Force + if (lag_params%gravity_force) then + force = force + (mass_p)*accel_bf + end if + + ! Step 4: Added Mass Force + if (lag_params%added_mass_model == 1) then + vol = (4._wp/3._wp)*pi*(rad**3._wp) + if (mach > 0.6_wp) then + Cam = 1._wp + 1.8_wp*(0.6_wp**2) + 7.6_wp*(0.6_wp**4) + else + Cam = 1._wp + 1.8_wp*mach**2 + 7.6_wp*mach**4 + end if + + Cam = 0.5_wp*Cam*(1._wp + 0.68_wp*vol_frac**2) + rmass_add = rho_fluid*vol*Cam ! (1._wp-vol_frac)*rho_fluid*vol*Cam + + fam = Cam*vol*(vel_p*SDrho + rhoDuDt + fluid_vel*(vpgradrho)) + + do dir = 1, num_dims + if (.not. ieee_is_finite(fam(dir))) then + fam(dir) = 0._wp + rmass_add = 0._wp + end if + end do + force = force + fam + else + rmass_add = 0._wp + end if + + do dir = 1, num_dims + if (.not. ieee_is_finite(force(dir))) then + force(dir) = 0._wp + end if + end do + + end subroutine s_get_particle_force + + !> Interpolate an Eulerian field to a particle position using barycentric Lagrange interpolation with precomputed weights. Falls + !! back to nearest-cell value if the interpolant is non-finite. + !! @param pos Particle position + !! @param cell Grid cell containing the particle + !! @param field_vf Eulerian field to interpolate + !! @param field_index Component index in field_vf + function f_interp_barycentric(pos, cell, field_vf, field_index, wx, wy, wz) result(val) + + $:GPU_ROUTINE(parallelism='[seq]') + + real(wp), dimension(3), intent(in) :: pos + integer, dimension(3), intent(in) :: cell + type(scalar_field), dimension(:), intent(in) :: field_vf + type(scalar_field), dimension(:), intent(in) :: wx, wy, wz + integer, intent(in) :: field_index + integer :: i, j, k, ix, jy, kz, npts, npts_z, N, a, b + integer :: ix_count, jy_count, kz_count + real(wp) :: weight, numerator, denominator, xBar, eps + real(wp) :: val, local_min, local_max, prod_x, prod_y, prod_z + + i = cell(1) + j = cell(2) + k = cell(3) + + N = lag_params%interpolation_order + npts = N/2 + npts_z = npts + if (num_dims == 2) npts_z = 0 + eps = 1.e-12_wp + numerator = 0._wp + denominator = 0._wp + + ! if (abs(pos(1) - x_cc(i)) <= eps .and. & abs(pos(2) - y_cc(j)) <= eps .and. & abs(pos(3) - z_cc(k)) <= eps) then val = + ! field_vf(field_index)%sf(i, j, k) return end if + + ix_count = 0 + do ix = i - npts, i + npts + ix_count = ix_count + 1 + jy_count = 0 + do jy = j - npts, j + npts + jy_count = jy_count + 1 + kz_count = 0 + do kz = k - npts_z, k + npts_z + kz_count = kz_count + 1 + if (num_dims == 3) then + xBar = (pos(1) - x_cc(ix))*(pos(2) - y_cc(jy))*(pos(3) - z_cc(kz)) + weight = wx(ix_count)%sf(i, 1, 1)*wy(jy_count)%sf(j, 1, 1)*wz(kz_count)%sf(k, 1, 1) + else + xBar = (pos(1) - x_cc(ix))*(pos(2) - y_cc(jy)) + weight = wx(ix_count)%sf(i, 1, 1)*wy(jy_count)%sf(j, 1, 1) + end if + weight = weight/xBar + numerator = numerator + weight*field_vf(field_index)%sf(ix, jy, kz) + denominator = denominator + weight + end do + end do + end do + + val = numerator/denominator + + if (.not. ieee_is_finite(val)) then + val = field_vf(field_index)%sf(i, j, k) + else if (abs(val) <= eps) then + val = 0._wp + end if + + end function f_interp_barycentric + + ! Quasi-steady force (Re_p and Ma_p corrections): Improved Drag Correlation for Spheres and Application to Shock-Tube + ! Experiments - Parmar et al. (2010) - AIAA Journal + ! + ! Quasi-steady force (phi corrections): The Added Mass, Basset, and Viscous Drag Coefficients in Nondilute Bubbly Liquids + ! Undergoing Small-Amplitude Oscillatory Motion - Sangani et al. (1991) - Phys. Fluids A + function QS_Parmar(rho, cson, mu_fluid, gamma, vmag, dp, volume_fraction) result(beta) + + $:GPU_ROUTINE(parallelism='[seq]') + real(wp), intent(in) :: rho, cson, mu_fluid, gamma, vmag, dp, volume_fraction + real(wp) :: rcd1, rmacr, rcd_mcr, rcd_std, rmach_rat, rcd_M1 + real(wp) :: rcd_M2, C1, C2, C3, f1M, f2M, f3M, lrep, factor, cd, phi_corr + real(wp) :: beta + real(wp) :: rmachp, mp, phi, rep, re + + rmachp = vmag/cson + mp = max(rmachp, 0.01_wp) + phi = max(volume_fraction, 0.0001_wp) + rep = vmag*dp*rho/mu_fluid + re = max(rep, 0.1_wp) + + if (re < 1.e-14_wp) then + rcd1 = 1.0_wp + else + rmacr = 0.6_wp ! Critical rmachp no + rcd_mcr = (1._wp + 0.15_wp*re**(0.684_wp)) + (re/24.0_wp)*(0.513_wp/(1._wp + 483._wp/re**(0.669_wp))) + if (mp <= rmacr) then + rcd_std = (1._wp + 0.15_wp*re**(0.687_wp)) + (re/24.0_wp)*(0.42_wp/(1._wp + 42500._wp/re**(1.16_wp))) + rmach_rat = mp/rmacr + rcd1 = rcd_std + (rcd_mcr - rcd_std)*rmach_rat + else if (mp <= 1.0_wp) then + rcd_M1 = (1.0_wp + 0.118_wp*re**0.813_wp) + (re/24.0_wp)*0.69_wp/(1.0_wp + 3550.0_wp/re**0.793_wp) + C1 = 6.48_wp + C2 = 9.28_wp + C3 = 12.21_wp + f1M = -1.884_wp + 8.422_wp*mp - 13.70_wp*mp**2 + 8.162_wp*mp**3 + f2M = -2.228_wp + 10.35_wp*mp - 16.96_wp*mp**2 + 9.840_wp*mp**3 + f3M = 4.362_wp - 16.91_wp*mp + 19.84_wp*mp**2 - 6.296_wp*mp**3 + lrep = log(re) + factor = f1M*(lrep - C2)*(lrep - C3)/((C1 - C2)*(C1 - C3)) + f2M*(lrep - C1)*(lrep - C3)/((C2 - C1)*(C2 - C3)) & + & + f3M*(lrep - C1)*(lrep - C2)/((C3 - C1)*(C3 - C2)) + rcd1 = rcd_mcr + (rcd_M1 - rcd_mcr)*factor + else if (mp < 1.75_wp) then + rcd_M1 = (1.0_wp + 0.118_wp*re**0.813_wp) + (re/24.0_wp)*0.69_wp/(1.0_wp + 3550.0_wp/re**0.793_wp) + rcd_M2 = (1.0_wp + 0.107_wp*re**0.867_wp) + (re/24.0_wp)*0.646_wp/(1.0_wp + 861.0_wp/re**0.634_wp) + C1 = 6.48_wp + C2 = 8.93_wp + C3 = 12.21_wp + f1M = -2.963_wp + 4.392_wp*mp - 1.169_wp*mp**2 - 0.027_wp*mp**3 - 0.233_wp*exp((1.0_wp - mp)/0.011_wp) + f2M = -6.617_wp + 12.11_wp*mp - 6.501_wp*mp**2 + 1.182_wp*mp**3 - 0.174_wp*exp((1.0_wp - mp)/0.010_wp) + f3M = -5.866_wp + 11.57_wp*mp - 6.665_wp*mp**2 + 1.312_wp*mp**3 - 0.350_wp*exp((1.0_wp - mp)/0.012_wp) + lrep = log(re) + factor = f1M*(lrep - C2)*(lrep - C3)/((C1 - C2)*(C1 - C3)) + f2M*(lrep - C1)*(lrep - C3)/((C2 - C1)*(C2 - C3)) & + & + f3M*(lrep - C1)*(lrep - C2)/((C3 - C1)*(C3 - C2)) + rcd1 = rcd_M1 + (rcd_M2 - rcd_M1)*factor + else + rcd1 = (1.0_wp + 0.107_wp*re**0.867_wp) + (re/24.0_wp)*0.646_wp/(1.0_wp + 861.0_wp/re**0.634_wp) + end if ! mp + end if ! re + + ! Sangani's volume fraction correction for dilute random arrays Capping volume fraction at 0.5 + phi_corr = (1.0_wp + 5.94_wp*min(phi, 0.5_wp)) + + cd = (24.0_wp/re)*rcd1*phi_corr + + beta = rcd1*3.0_wp*pi*mu_fluid*dp + + beta = beta*phi_corr + + end function QS_Parmar + + ! Quasi-steady force (Re_p and Ma_p corrections): Improved Drag Correlation for Spheres and Application to Shock-Tube + ! Experiments - Parmar et al. (2010) - AIAA Journal + ! + ! Quasi-steady force (phi corrections): Sangani et al. (1991) volume fraction correction overshoots the drag coefficient. + ! + ! We adopt instead Osnes et al. (2023) volume fraction correction based on Tenneti et al. with one extra term. + ! + ! At Mach=0, the drag coefficient from this subroutine matches very well with the one calculated using the Osnes subroutine, for + ! various Reynolds numbers and volume fractions. + function QS_ModifiedParmar(rho, cson, mu_fluid, gamma, vmag, dp, volume_fraction) result(beta) + + $:GPU_ROUTINE(parallelism='[seq]') + real(wp), intent(in) :: rho, cson, mu_fluid, gamma, vmag, dp, volume_fraction + real(wp) :: rcd1, rmacr, rcd_mcr, rcd_std, rmach_rat, rcd_M1 + real(wp) :: rcd_M2, C1, C2, C3, f1M, f2M, f3M, lrep, factor, cd, phi_corr + real(wp) :: b1, b2, b3 + real(wp) :: beta + real(wp) :: rmachp, mp, phi, rep, re + + rmachp = vmag/cson + mp = max(rmachp, 0.01_wp) + phi = max(volume_fraction, 0.0001_wp) + rep = vmag*dp*rho/mu_fluid + re = max(rep, 0.1_wp) + + if (re < 1e-14_wp) then + rcd1 = 1.0_wp + else + rmacr = 0.6_wp ! Critical rmachp no. + rcd_mcr = (1._wp + 0.15_wp*re**(0.684_wp)) + (re/24.0_wp)*(0.513_wp/(1._wp + 483._wp/re**(0.669_wp))) + if (mp <= rmacr) then + rcd_std = (1._wp + 0.15_wp*re**(0.687_wp)) + (re/24.0_wp)*(0.42_wp/(1._wp + 42500._wp/re**(1.16_wp))) + rmach_rat = mp/rmacr + rcd1 = rcd_std + (rcd_mcr - rcd_std)*rmach_rat + else if (mp <= 1.0_wp) then + rcd_M1 = (1.0_wp + 0.118_wp*re**0.813_wp) + (re/24.0_wp)*0.69_wp/(1.0_wp + 3550.0_wp/re**0.793_wp) + C1 = 6.48_wp + C2 = 9.28_wp + C3 = 12.21_wp + f1M = -1.884_wp + 8.422_wp*mp - 13.70_wp*mp**2 + 8.162_wp*mp**3 + f2M = -2.228_wp + 10.35_wp*mp - 16.96_wp*mp**2 + 9.840_wp*mp**3 + f3M = 4.362_wp - 16.91_wp*mp + 19.84_wp*mp**2 - 6.296_wp*mp**3 + lrep = log(re) + factor = f1M*(lrep - C2)*(lrep - C3)/((C1 - C2)*(C1 - C3)) + f2M*(lrep - C1)*(lrep - C3)/((C2 - C1)*(C2 - C3)) & + & + f3M*(lrep - C1)*(lrep - C2)/((C3 - C1)*(C3 - C2)) + rcd1 = rcd_mcr + (rcd_M1 - rcd_mcr)*factor + else if (mp < 1.75_wp) then + rcd_M1 = (1.0_wp + 0.118_wp*re**0.813_wp) + (re/24.0_wp)*0.69_wp/(1.0_wp + 3550.0_wp/re**0.793_wp) + rcd_M2 = (1.0_wp + 0.107_wp*re**0.867_wp) + (re/24.0_wp)*0.646_wp/(1.0_wp + 861.0_wp/re**0.634_wp) + C1 = 6.48_wp + C2 = 8.93_wp + C3 = 12.21_wp + f1M = -2.963_wp + 4.392_wp*mp - 1.169_wp*mp**2 - 0.027_wp*mp**3 - 0.233_wp*exp((1.0_wp - mp)/0.011_wp) + f2M = -6.617_wp + 12.11_wp*mp - 6.501_wp*mp**2 + 1.182_wp*mp**3 - 0.174_wp*exp((1.0_wp - mp)/0.010_wp) + f3M = -5.866_wp + 11.57_wp*mp - 6.665_wp*mp**2 + 1.312_wp*mp**3 - 0.350_wp*exp((1.0_wp - mp)/0.012_wp) + lrep = log(re) + factor = f1M*(lrep - C2)*(lrep - C3)/((C1 - C2)*(C1 - C3)) + f2M*(lrep - C1)*(lrep - C3)/((C2 - C1)*(C2 - C3)) & + & + f3M*(lrep - C1)*(lrep - C2)/((C3 - C1)*(C3 - C2)) + rcd1 = rcd_M1 + (rcd_M2 - rcd_M1)*factor + else + rcd1 = (1.0_wp + 0.107_wp*re**0.867_wp) + (re/24.0_wp)*0.646_wp/(1.0_wp + 861.0_wp/re**0.634_wp) + end if ! mp + end if ! re + + ! Osnes's volume fraction correction + b1 = 5.81_wp*phi/((1.0_wp - phi)**2) + 0.48_wp*(phi**(1._wp/3._wp))/((1.0_wp - phi)**3) + + b2 = ((1.0_wp - phi)**2)*(phi**3)*re*(0.95_wp + 0.61_wp*(phi**3)/((1.0_wp - phi)**2)) + + b3 = min(sqrt(20.0_wp*mp), & + & 1.0_wp)*(5.65_wp*phi - 22.0_wp*(phi**2) + 23.4_wp*(phi**3))*(1._wp + tanh((mp - (0.65_wp - 0.24_wp*phi)) & + & /0.35_wp)) + + cd = (24.0_wp/re)*rcd1 + + cd = cd/(1.0_wp - phi) + b3 + (24.0_wp/re)*(1.0_wp - phi)*(b1 + b2) + + beta = 3.0_wp*pi*mu_fluid*dp*(re/24.0_wp)*cd + + end function QS_ModifiedParmar + + ! QS Force calculated as a function of Re, Ma and phi + ! + ! Use Osnes etal (2023) correlations A.N. Osnes, M. Vartdal, M. Khalloufi, J. Capecelatro, and S. Balachandar. Comprehensive + ! quasi-steady force correlations for compressible flow through random particle suspensions. International Journal of Multiphase + ! Flow, Vol. 165, 104485, (2023). doi: https://doi.org/10.1016/j.imultiphaseflow.2023.104485. + ! + ! E. Loth, J.T. Daspit, M. Jeong, T. Nagata, and T. Nonomura. Supersonic and hypersonic drag coefficients for a sphere. AIAA + ! Journal, Vol. 59(8), pp. 3261-3274, (2021). doi: https://doi.org/10.2514/1.J060153. + ! + ! NOTE: Re<45 Rarefied formula of Loth et al has been redefined by Balachandar to avoid singularity as Ma -> 0. + function QS_Osnes(rho, cson, mu_fluid, gamma, vmag, dp, volume_fraction) result(beta) + + $:GPU_ROUTINE(parallelism='[seq]') + real(wp), intent(in) :: rho, cson, mu_fluid, gamma, vmag, dp, volume_fraction + real(wp) :: rmachp, mp, phi, rep, re + real(wp) :: Knp, fKn, CD1, s, JM, CD2, cd_loth, CM, GM, HM, b1, b2, b3, cd, sgby2, JMt + real(wp) :: beta + + rmachp = vmag/cson + mp = max(rmachp, 0.01_wp) + phi = max(volume_fraction, 0.0001_wp) + rep = vmag*dp*rho/mu_fluid + re = max(rep, 0.1_wp) + + ! Loth's correlation + if (re <= 45.0_wp) then + ! Rarefied-dominated regime + Knp = sqrt(0.5_wp*pi*gamma)*mp/re + if (Knp > 0.01_wp) then + fKn = 1.0_wp/(1.0_wp + Knp*(2.514_wp + 0.8_wp*exp(-0.55_wp/Knp))) + else + fKn = 1.0_wp/(1.0_wp + Knp*(2.514_wp + 0.8_wp*exp(-0.55_wp/0.01_wp))) + end if + CD1 = (24.0_wp/re)*(1.0_wp + 0.15_wp*re**(0.687_wp))*fKn + s = mp*sqrt(0.5_wp*gamma) + sgby2 = sqrt(0.5_wp*gamma) + if (mp <= 1._wp) then + ! JMt = 2.26_wp*(mp**4) - 0.1_wp*(mp**3) + 0.14_wp*mp + JMt = 2.26_wp*(mp**4) + 0.14_wp*mp + else + JMt = 1.6_wp*(mp**4) + 0.25_wp*(mp**3) + 0.11_wp*(mp**2) + 0.44_wp*mp + end if + ! + ! Reformulated version of Loth et al. to avoid singularity at mp = 0 + ! + CD2 = (1.0_wp + 2.0_wp*(s**2))*exp(-s**2)*mp/((sgby2**3)*sqrt(pi)) + (4.0_wp*(s**4) + 4.0_wp*(s**2) - 1.0_wp)*erf(s) & + & /(2.0_wp*(sgby2**4)) + (2.0_wp*(mp**3)/(3.0_wp*sgby2))*sqrt(pi) + + CD2 = CD2/(1.0_wp + (((CD2/JMt) - 1.0_wp)*sqrt(re/45.0_wp))) + cd_loth = CD1/(1.0_wp + (mp**4)) + CD2/(1.0_wp + (mp**4)) + else + ! Compression-dominated regime TLJ: coefficients tweaked to get continuous values on the two branches at the critical + ! points + if (mp < 1.5_wp) then + CM = 1.65_wp + 0.65_wp*tanh(4._wp*mp - 3.4_wp) + else + ! CM = 2.18_wp - 0.13_wp*tanh(0.9_wp*mp - 2.7_wp) + CM = 2.18_wp - 0.12913149918318745_wp*tanh(0.9_wp*mp - 2.7_wp) + end if + if (mp < 0.8_wp) then + GM = 166.0_wp*(mp**3) + 3.29_wp*(mp**2) - 10.9_wp*mp + 20._wp + else + ! GM = 5.0_wp + 40._wp*(mp**(-3)) + GM = 5.0_wp + 47.809331200000017_wp*(mp**(-3)) + end if + if (mp < 1._wp) then + HM = 0.0239_wp*(mp**3) + 0.212_wp*(mp**2) - 0.074_wp*mp + 1._wp + else + ! HM = 0.93_wp + 1.0_wp / (3.5_wp + (mp**5)) + HM = 0.93967777777777772_wp + 1.0_wp/(3.5_wp + (mp**5)) + end if + + cd_loth = (24.0_wp/re)*(1._wp + 0.15_wp*(re**(0.687_wp)))*HM + 0.42_wp*CM/(1._wp + 42500._wp/re**(1.16_wp*CM) & + & + GM/sqrt(re)) + end if + + b1 = 5.81_wp*phi/((1.0_wp - phi)**2) + 0.48_wp*(phi**(1._wp/3._wp))/((1.0_wp - phi)**3) + + b2 = ((1.0_wp - phi)**2)*(phi**3)*re*(0.95_wp + 0.61_wp*(phi**3)/((1.0_wp - phi)**2)) + + b3 = min(sqrt(20.0_wp*mp), & + & 1.0_wp)*(5.65_wp*phi - 22.0_wp*(phi**2) + 23.4_wp*(phi**3))*(1._wp + tanh((mp - (0.65_wp - 0.24_wp*phi)) & + & /0.35_wp)) + + cd = cd_loth/(1.0_wp - phi) + b3 + (24.0_wp/re)*(1.0_wp - phi)*(b1 + b2) + + beta = 3.0_wp*pi*mu_fluid*dp*(re/24.0_wp)*cd + + end function QS_Osnes + + ! Subroutine for Quasi-Steady Drag Model of Gidaspow + ! + ! D. Gidaspow, Multiphase Flow and Fluidization (Academic Press, 1994) + ! + ! Note: Model is provided per cell volume. We convert that to per particle using the particle volume fraction and volume + function QS_Gidaspow(rho, cson, mu_fluid, gamma, vmag, dp, volume_fraction) result(beta) + + $:GPU_ROUTINE(parallelism='[seq]') + real(wp), intent(in) :: rho, cson, mu_fluid, gamma, vmag, dp, volume_fraction + real(wp) :: cd, phifRep, phif + real(wp) :: phi, rep, re + real(wp) :: beta + + rep = vmag*dp*rho/mu_fluid + phi = max(volume_fraction, 0.0001_wp) + phif = max(1._wp - volume_fraction, 0.0001_wp) + re = max(rep, 0.1_wp) + + phifRep = phif*re + + if (phifRep < 1000.0_wp) then + cd = 24.0_wp/phifRep*(1.0_wp + 0.15_wp*(phifRep)**0.687_wp) + else + cd = 0.44_wp + end if + + if (phif < 0.8_wp) then + beta = 150.0_wp*((phi**2)*mu_fluid)/(phif*dp**2) + 1.75_wp*(rho*phi*vmag/dp) + else + beta = 0.75_wp*cd*phi*rho*vmag/(dp*phif**1.65_wp) + end if + + beta = beta*(pi*dp**3)/(6.0_wp*phi) + + end function QS_Gidaspow + +end module m_particles_EL_kernels diff --git a/src/simulation/m_rhs.fpp b/src/simulation/m_rhs.fpp index 1f347a0289..e61da866a6 100644 --- a/src/simulation/m_rhs.fpp +++ b/src/simulation/m_rhs.fpp @@ -19,6 +19,7 @@ module m_rhs use m_cbc use m_bubbles_EE use m_bubbles_EL + use m_particles_EL use m_qbmm use m_hypoelastic use m_hyperelastic @@ -554,7 +555,6 @@ contains real(wp) :: t_start, t_finish integer :: id integer(kind=8) :: i, j, k, l, q !< Generic loop iterators - ! RHS: halo exchange -> reconstruct -> Riemann solve -> flux difference -> source terms call nvtxStartRange("COMPUTE-RHS") @@ -673,7 +673,6 @@ contains end if end if if ((.not. igr) .or. dummy) then ! Finite volume solve - ! Reconstructing Primitive/Conservative Variables call nvtxStartRange("RHS-WENO") @@ -751,6 +750,7 @@ contains irx%beg = 0; iry%beg = 0; irz%beg = -1 end if irx%end = m; iry%end = n; irz%end = p + ! Computing Riemann Solver Flux and Source Flux call nvtxStartRange("RHS-RIEMANN-SOLVER") call s_riemann_solver(qR_rsx_vf, qR_rsy_vf, qR_rsz_vf, dqR_prim_dx_n(id)%vf, dqR_prim_dy_n(id)%vf, & @@ -848,14 +848,31 @@ contains end if if (bubbles_lagrange) then - ! RHS additions for sub-grid bubbles_lagrange - call nvtxStartRange("RHS-EL-BUBBLES-SRC") - call s_compute_bubbles_EL_source(q_cons_qp%vf(1:sys_size), q_prim_qp%vf(1:sys_size), rhs_vf) - call nvtxEndRange - ! Compute bubble dynamics + ! RHS additions for sub-grid bubbles_lagrange Compute bubble dynamics if (.not. adap_dt) then call nvtxStartRange("RHS-EL-BUBBLES-DYN") - call s_compute_bubble_EL_dynamics(q_prim_qp%vf(1:sys_size), stage) + call s_compute_bubble_EL_dynamics(q_prim_qp%vf(1:sys_size), bc_type, stage) + call nvtxEndRange + end if + + if (lag_params%solver_approach == 2) then + call nvtxStartRange("RHS-EL-BUBBLES-SRC") + call s_compute_bubbles_EL_source(q_cons_qp%vf(1:sys_size), q_prim_qp%vf(1:sys_size), rhs_vf) + call nvtxEndRange + end if + end if + + if (particles_lagrange) then + ! Compute particle dynamics, forces, dvdt + call nvtxStartRange("RHS-EL-PARTICLES-DYN") + call s_compute_particle_EL_dynamics(q_prim_qp%vf(1:sys_size), bc_type, stage, qL_rsx_vf, qL_rsy_vf, qL_rsz_vf, & + & qR_rsx_vf, qR_rsy_vf, qR_rsz_vf, rhs_vf) + call nvtxEndRange + + ! RHS additions for sub-grid particles_lagrange + if (lag_params%solver_approach == 2) then + call nvtxStartRange("RHS-EL-PARTICLES-SRC") + call s_compute_particles_EL_source(q_cons_qp%vf(1:sys_size), q_prim_qp%vf(1:sys_size), rhs_vf, stage) call nvtxEndRange end if end if @@ -870,7 +887,7 @@ contains ! END: Additional physics and source terms - if (run_time_info .or. probe_wrt .or. ib .or. bubbles_lagrange) then + if (run_time_info .or. probe_wrt .or. ib .or. bubbles_lagrange .or. particles_lagrange) then if (.not. igr .or. dummy) then $:GPU_PARALLEL_LOOP(private='[i, j, k, l]', collapse=4) do i = 1, sys_size @@ -1010,7 +1027,7 @@ contains $:END_GPU_PARALLEL_LOOP() if (model_eqns == 3) then - $:GPU_PARALLEL_LOOP(collapse=4, private='[i_fluid_loop, k, l, q, inv_ds, advected_qty_val, pressure_val, & + $:GPU_PARALLEL_LOOP(collapse=4,private='[i_fluid_loop, k, l, q, inv_ds, advected_qty_val, pressure_val, & & flux_face1, flux_face2]') do l = 0, p do k = 0, n @@ -1106,7 +1123,7 @@ contains end if if (model_eqns == 3) then - $:GPU_PARALLEL_LOOP(collapse=4, private='[i_fluid_loop, k, l, q, inv_ds, advected_qty_val, pressure_val, & + $:GPU_PARALLEL_LOOP(collapse=4,private='[i_fluid_loop, k, l, q, inv_ds, advected_qty_val, pressure_val, & & flux_face1, flux_face2]') do k = 0, p do q = 0, n @@ -1133,7 +1150,6 @@ contains !> Add the advection source flux-difference terms for a single coordinate direction to the RHS subroutine s_add_directional_advection_source_terms(current_idir, rhs_vf_arg, q_cons_vf_arg, q_prim_vf_arg, & - & flux_src_n_vf_arg, Kterm_arg) integer, intent(in) :: current_idir type(scalar_field), dimension(sys_size), intent(inout) :: rhs_vf_arg diff --git a/src/simulation/m_sim_helpers.fpp b/src/simulation/m_sim_helpers.fpp index e20ec982fe..f20597d3ea 100644 --- a/src/simulation/m_sim_helpers.fpp +++ b/src/simulation/m_sim_helpers.fpp @@ -138,24 +138,25 @@ contains end subroutine s_compute_enthalpy !> Computes stability criterion for a specified dt - subroutine s_compute_stability_from_dt(vel, c, rho, Re_l, j, k, l, icfl_sf, vcfl_sf, Rc_sf) + !! @param icfl cell-centered inviscid cfl number + !! @param vcfl (optional) cell-centered viscous CFL number + !! @param Rc (optional) cell centered Rc + subroutine s_compute_stability_from_dt(vel, c, rho, Re_l, j, k, l, icfl, vcfl, Rc) $:GPU_ROUTINE(parallelism='[seq]') - real(wp), intent(in), dimension(num_vels) :: vel - real(wp), intent(in) :: c, rho - real(wp), dimension(0:m,0:n,0:p), intent(inout) :: icfl_sf - real(wp), dimension(0:m,0:n,0:p), intent(inout), optional :: vcfl_sf, Rc_sf - real(wp), dimension(2), intent(in) :: Re_l - integer, intent(in) :: j, k, l - real(wp) :: fltr_dtheta + real(wp), intent(in), dimension(num_vels) :: vel + real(wp), intent(in) :: c, rho + real(wp), intent(inout) :: icfl + real(wp), intent(inout), optional :: vcfl, Rc + real(wp), dimension(2), intent(in) :: Re_l + integer, intent(in) :: j, k, l + real(wp) :: fltr_dtheta ! Inviscid CFL calculation if (p > 0 .or. n > 0) then - ! 2D/3D - icfl_sf(j, k, l) = dt/f_compute_multidim_cfl_terms(vel, c, j, k, l) + icfl = dt/f_compute_multidim_cfl_terms(vel, c, j, k, l) else - ! 1D - icfl_sf(j, k, l) = (dt/dx(j))*(abs(vel(1)) + c) + icfl = (dt/dx(j))*(abs(vel(1)) + c) end if ! Viscous calculations @@ -165,23 +166,19 @@ contains ! 3D if (grid_geometry == 3) then fltr_dtheta = f_compute_filtered_dtheta(k, l) - vcfl_sf(j, k, l) = maxval(dt/Re_l/rho)/min(dx(j), dy(k), fltr_dtheta)**2._wp - Rc_sf(j, k, l) = min(dx(j)*(abs(vel(1)) + c), dy(k)*(abs(vel(2)) + c), & - & fltr_dtheta*(abs(vel(3)) + c))/maxval(1._wp/Re_l) + vcfl = maxval(dt/Re_l/rho)/min(dx(j), dy(k), fltr_dtheta)**2._wp + Rc = min(dx(j)*(abs(vel(1)) + c), dy(k)*(abs(vel(2)) + c), fltr_dtheta*(abs(vel(3)) + c))/maxval(1._wp/Re_l) else - vcfl_sf(j, k, l) = maxval(dt/Re_l/rho)/min(dx(j), dy(k), dz(l))**2._wp - Rc_sf(j, k, l) = min(dx(j)*(abs(vel(1)) + c), dy(k)*(abs(vel(2)) + c), & - & dz(l)*(abs(vel(3)) + c))/maxval(1._wp/Re_l) + vcfl = maxval(dt/Re_l/rho)/min(dx(j), dy(k), dz(l))**2._wp + Rc = min(dx(j)*(abs(vel(1)) + c), dy(k)*(abs(vel(2)) + c), dz(l)*(abs(vel(3)) + c))/maxval(1._wp/Re_l) end if #:endif else if (n > 0) then - ! 2D - vcfl_sf(j, k, l) = maxval(dt/Re_l/rho)/min(dx(j), dy(k))**2._wp - Rc_sf(j, k, l) = min(dx(j)*(abs(vel(1)) + c), dy(k)*(abs(vel(2)) + c))/maxval(1._wp/Re_l) + vcfl = maxval(dt/Re_l/rho)/min(dx(j), dy(k))**2._wp + Rc = min(dx(j)*(abs(vel(1)) + c), dy(k)*(abs(vel(2)) + c))/maxval(1._wp/Re_l) else - ! 1D - vcfl_sf(j, k, l) = maxval(dt/Re_l/rho)/dx(j)**2._wp - Rc_sf(j, k, l) = dx(j)*(abs(vel(1)) + c)/maxval(1._wp/Re_l) + vcfl = maxval(dt/Re_l/rho)/dx(j)**2._wp + Rc = dx(j)*(abs(vel(1)) + c)/maxval(1._wp/Re_l) end if end if @@ -191,13 +188,13 @@ contains subroutine s_compute_dt_from_cfl(vel, c, max_dt, rho, Re_l, j, k, l) $:GPU_ROUTINE(parallelism='[seq]') - real(wp), dimension(num_vels), intent(in) :: vel - real(wp), intent(in) :: c, rho - real(wp), dimension(0:m,0:n,0:p), intent(inout) :: max_dt - real(wp), dimension(2), intent(in) :: Re_l - integer, intent(in) :: j, k, l - real(wp) :: icfl_dt, vcfl_dt - real(wp) :: fltr_dtheta + real(wp), dimension(num_vels), intent(in) :: vel + real(wp), intent(in) :: c, rho + real(wp), intent(inout) :: max_dt + real(wp), dimension(2), intent(in) :: Re_l + integer, intent(in) :: j, k, l + real(wp) :: icfl_dt, vcfl_dt + real(wp) :: fltr_dtheta ! Inviscid CFL calculation if (p > 0 .or. n > 0) then @@ -227,10 +224,10 @@ contains end if end if - if (any(Re_size > 0)) then - max_dt(j, k, l) = min(icfl_dt, vcfl_dt) + if (viscous) then + max_dt = min(icfl_dt, vcfl_dt) else - max_dt(j, k, l) = icfl_dt + max_dt = icfl_dt end if end subroutine s_compute_dt_from_cfl diff --git a/src/simulation/m_start_up.fpp b/src/simulation/m_start_up.fpp index c3f38ef500..b93cd2a21d 100644 --- a/src/simulation/m_start_up.fpp +++ b/src/simulation/m_start_up.fpp @@ -31,6 +31,7 @@ module m_start_up use m_viscous use m_bubbles_EE use m_bubbles_EL + use m_particles_EL !< Lagrange particle dynamics routines use ieee_arithmetic use m_helper_basic use m_helper @@ -87,8 +88,6 @@ contains rdma_mpi, teno_CT, mp_weno, weno_avg, & riemann_solver, low_Mach, wave_speeds, avg_state, & bc_x, bc_y, bc_z, & - x_a, y_a, z_a, x_b, y_b, z_b, & - x_domain, y_domain, z_domain, & hypoelasticity, & ib, num_ibs, patch_ib, & ib_state_wrt, & @@ -110,7 +109,8 @@ contains & g_y, g_z, n_start, t_save, t_stop, cfl_adap_dt, cfl_const_dt, cfl_target, surface_tension, bubbles_lagrange, & & lag_params, hyperelasticity, R0ref, num_bc_patches, Bx0, cont_damage, tau_star, cont_damage_s, alpha_bar, & & hyper_cleaning, hyper_cleaning_speed, hyper_cleaning_tau, alf_factor, num_igr_iters, num_igr_warm_start_iters, & - & int_comp, ic_eps, ic_beta, nv_uvm_out_of_core, nv_uvm_igr_temps_on_gpu, nv_uvm_pref_gpu, down_sample, fft_wrt + & int_comp, ic_eps, ic_beta, nv_uvm_out_of_core, nv_uvm_igr_temps_on_gpu, nv_uvm_pref_gpu, down_sample, fft_wrt, & + & particles_lagrange, particle_pp inquire (FILE=trim(file_path), EXIST=file_exist) @@ -139,9 +139,13 @@ contains if (cfl_adap_dt .or. cfl_const_dt) cfl_dt = .true. - if (any((/bc_x%beg, bc_x%end, bc_y%beg, bc_y%end, bc_z%beg, bc_z%end/) == -17) .or. num_bc_patches > 0) then + if (any((/bc_x%beg, bc_x%end, bc_y%beg, bc_y%end, bc_z%beg, bc_z%end/) == BC_DIRICHLET) .or. num_bc_patches > 0) then bc_io = .true. end if + + if (bc_x%beg == BC_PERIODIC .and. bc_x%end == BC_PERIODIC) periodic_bc(1) = .true. + if (bc_y%beg == BC_PERIODIC .and. bc_y%end == BC_PERIODIC) periodic_bc(2) = .true. + if (bc_z%beg == BC_PERIODIC .and. bc_z%end == BC_PERIODIC) periodic_bc(3) = .true. else call s_mpi_abort(trim(file_path) // ' is missing. Exiting.') end if @@ -674,7 +678,6 @@ contains !> Collect per-process wall-clock times and write aggregate performance metrics to file impure subroutine s_save_performance_metrics(time_avg, time_final, io_time_avg, io_time_final, proc_time, io_proc_time, & - & file_exists) real(wp), intent(inout) :: time_avg, time_final @@ -796,7 +799,7 @@ contains if (bubbles_lagrange) then $:GPU_UPDATE(host='[lag_id, mtn_pos, mtn_posPrev, mtn_vel, intfc_rad, intfc_vel, bub_R0, Rmax_stats, Rmin_stats, & & bub_dphidt, gas_p, gas_mv, gas_mg, gas_betaT, gas_betaC]') - do i = 1, nBubs + do i = 1, n_el_bubs_loc if (ieee_is_nan(intfc_rad(i, 1)) .or. intfc_rad(i, 1) <= 0._wp) then call s_mpi_abort("Bubble radius is negative or NaN, please reduce dt.") end if @@ -807,6 +810,20 @@ contains $:GPU_UPDATE(host='[Rmax_stats, Rmin_stats, gas_p, gas_mv, intfc_vel]') call s_write_restart_lag_bubbles(save_count) ! parallel if (lag_params%write_bubbles_stats) call s_write_lag_bubble_stats() + else if (particles_lagrange) then + $:GPU_UPDATE(host='[lag_part_id, particle_pos, particle_posPrev, particle_vel, particle_rad, particle_R0, & + & Rmax_stats_part, Rmin_stats_part, particle_mass]') + do i = 1, n_el_particles_loc + if (ieee_is_nan(particle_rad(i, 1)) .or. particle_rad(i, 1) <= 0._wp) then + call s_mpi_abort("Particle radius is negative or NaN, please reduce dt.") + end if + end do + + $:GPU_UPDATE(host='[q_particles(1)%sf]') + call s_write_data_files(q_cons_ts(stor)%vf, q_T_sf, q_prim_vf, save_count, bc_type, q_particles(1)) + $:GPU_UPDATE(host='[Rmax_stats_part, Rmin_stats_part]') + call s_write_restart_lag_particles(save_count) ! parallel + if (lag_params%write_bubbles_stats) call s_write_lag_particle_stats() else call s_write_data_files(q_cons_ts(stor)%vf, q_T_sf, q_prim_vf, save_count, bc_type) end if @@ -848,6 +865,11 @@ contains if (bubbles_euler .or. bubbles_lagrange) then call s_initialize_bubbles_model() end if + + if (particles_lagrange) then + call s_initialize_particles_model() + end if + call s_initialize_mpi_common_module() call s_initialize_mpi_proxy_module() call s_initialize_variables_conversion_module() @@ -931,7 +953,9 @@ contains end if call s_initialize_derived_variables() - if (bubbles_lagrange) call s_initialize_bubbles_EL_module(q_cons_ts(1)%vf) + + if (bubbles_lagrange) call s_initialize_bubbles_EL_module(q_cons_ts(1)%vf, bc_type) + if (particles_lagrange) call s_initialize_particles_EL_module(q_cons_ts(1)%vf, bc_type) if (hypoelasticity) call s_initialize_hypoelastic_module() if (hyperelasticity) call s_initialize_hyperelastic_module() @@ -1052,6 +1076,10 @@ contains $:GPU_UPDATE(device='[bc_y%vb1, bc_y%vb2, bc_y%vb3, bc_y%ve1, bc_y%ve2, bc_y%ve3]') $:GPU_UPDATE(device='[bc_z%vb1, bc_z%vb2, bc_z%vb3, bc_z%ve1, bc_z%ve2, bc_z%ve3]') + $:GPU_UPDATE(device='[bc_x%beg, bc_x%end]') + $:GPU_UPDATE(device='[bc_y%beg, bc_y%end]') + $:GPU_UPDATE(device='[bc_z%beg, bc_z%end]') + $:GPU_UPDATE(device='[bc_x%grcbc_in, bc_x%grcbc_out, bc_x%grcbc_vel_out]') $:GPU_UPDATE(device='[bc_y%grcbc_in, bc_y%grcbc_out, bc_y%grcbc_vel_out]') $:GPU_UPDATE(device='[bc_z%grcbc_in, bc_z%grcbc_out, bc_z%grcbc_vel_out]') @@ -1105,6 +1133,7 @@ contains call s_finalize_boundary_common_module() if (relax) call s_finalize_relaxation_solver_module() if (bubbles_lagrange) call s_finalize_lagrangian_solver() + if (particles_lagrange) call s_finalize_particle_lagrangian_solver() if (viscous .and. (.not. igr)) then call s_finalize_viscous_module() end if diff --git a/src/simulation/m_time_steppers.fpp b/src/simulation/m_time_steppers.fpp index 4a741a4068..deb03ebe5a 100644 --- a/src/simulation/m_time_steppers.fpp +++ b/src/simulation/m_time_steppers.fpp @@ -15,6 +15,7 @@ module m_time_steppers use m_data_output use m_bubbles_EE use m_bubbles_EL + use m_particles_EL !< Lagrange particle dynamics routines use m_ibm use m_hyperelastic use m_mpi_proxy @@ -38,13 +39,12 @@ module m_time_steppers real(wp), allocatable, dimension(:,:,:,:,:) :: rhs_pb type(scalar_field) :: q_T_sf !< Cell-average temperature variables at the current time-stage real(wp), allocatable, dimension(:,:,:,:,:) :: rhs_mv - real(wp), allocatable, dimension(:,:,:) :: max_dt integer, private :: num_ts !< Number of time stages in the time-stepping scheme integer :: stor !< storage index real(wp), allocatable, dimension(:,:) :: rk_coef integer, private :: num_probe_ts - $:GPU_DECLARE(create='[q_cons_ts, q_prim_vf, q_T_sf, rhs_vf, q_prim_ts1, q_prim_ts2, rhs_mv, rhs_pb, max_dt, rk_coef, stor, bc_type]') + $:GPU_DECLARE(create='[q_cons_ts, q_prim_vf, q_T_sf, rhs_vf, q_prim_ts1, q_prim_ts2, rhs_mv, rhs_pb, rk_coef, stor, bc_type]') !> @cond #if defined(__NVCOMPILER_GPU_UNIFIED_MEM) @@ -72,7 +72,6 @@ contains #endif integer :: i, j !< Generic loop iterators ! Setting number of time-stages for selected time-stepping scheme - if (time_stepper == 1) then num_ts = 1 else if (any(time_stepper == (/2, 3/))) then @@ -399,10 +398,6 @@ contains call s_open_ib_state_file() end if - if (cfl_dt) then - @:ALLOCATE(max_dt(0:m, 0:n, 0:p)) - end if - ! Allocating arrays to store the bc types @:ALLOCATE(bc_type(1:num_dims,1:2)) @@ -497,7 +492,12 @@ contains end if end if - if (bubbles_lagrange .and. .not. adap_dt) call s_update_lagrange_tdv_rk(stage=s) + if (bubbles_lagrange .and. .not. adap_dt) call s_update_lagrange_tdv_rk(q_prim_vf, bc_type, stage=s) + + if (particles_lagrange) then + call s_update_lagrange_particles_tdv_rk(q_prim_vf, bc_type, stage=s) + end if + $:GPU_PARALLEL_LOOP(collapse=4) do i = 1, sys_size do l = 0, p @@ -601,23 +601,22 @@ contains integer, intent(in) :: stage type(vector_field) :: gm_alpha_qp - call s_convert_conservative_to_primitive_variables(q_cons_ts(1)%vf, q_T_sf, q_prim_vf, idwint) + call s_convert_conservative_to_primitive_variables(q_cons_ts(1)%vf, q_T_sf, q_prim_vf, idwbuff) if (bubbles_euler) then call s_compute_bubble_EE_source(q_cons_ts(1)%vf, q_prim_vf, rhs_vf, divu) call s_comp_alpha_from_n(q_cons_ts(1)%vf) else if (bubbles_lagrange) then call s_populate_variables_buffers(bc_type, q_prim_vf, pb_ts(1)%sf, mv_ts(1)%sf) - call s_compute_bubble_EL_dynamics(q_prim_vf, stage) - call s_transfer_data_to_tmp() - call s_smear_voidfraction() + call s_compute_bubble_EL_dynamics(q_prim_vf, bc_type, stage) + if (stage == 3) then if (lag_params%write_bubbles_stats) call s_calculate_lag_bubble_stats() if (lag_params%write_bubbles) then $:GPU_UPDATE(host='[gas_p, gas_mv, intfc_rad, intfc_vel]') - call s_write_lag_particles(mytime) + call s_write_lag_bubble_evol(mytime) end if - call s_write_void_evol(mytime) + if (lag_params%write_void_evol) call s_write_void_evol(mytime) end if end if @@ -644,6 +643,7 @@ contains real(wp) :: H !< Cell-avg. enthalpy real(wp), dimension(2) :: Re !< Cell-avg. Reynolds numbers type(vector_field) :: gm_alpha_qp + real(wp) :: max_dt real(wp) :: dt_local integer :: j, k, l !< Generic loop iterators @@ -651,7 +651,9 @@ contains call s_convert_conservative_to_primitive_variables(q_cons_ts(1)%vf, q_T_sf, q_prim_vf, idwint) end if - $:GPU_PARALLEL_LOOP(collapse=3, private='[vel, alpha, Re, rho, vel_sum, pres, gamma, pi_inf, c, H, qv]') + dt_local = huge(1.0_wp) + $:GPU_PARALLEL_LOOP(collapse=3, private='[vel, alpha, Re, rho, vel_sum, pres, gamma, pi_inf, c, H, qv]', & + & reduction='[[dt_local]]', reductionOp='[min]') do l = 0, p do k = 0, n do j = 0, m @@ -665,15 +667,12 @@ contains call s_compute_speed_of_sound(pres, rho, gamma, pi_inf, H, alpha, vel_sum, 0._wp, c, qv) call s_compute_dt_from_cfl(vel, c, max_dt, rho, Re, j, k, l) + dt_local = min(dt_local, max_dt) end do end do end do $:END_GPU_PARALLEL_LOOP() - #:call GPU_PARALLEL(copyout='[dt_local]', copyin='[max_dt]') - dt_local = minval(max_dt) - #:endcall GPU_PARALLEL - if (num_procs == 1) then dt = dt_local else @@ -754,8 +753,9 @@ contains ! update the angular velocity with the torque value patch_ib(i)%angular_vel = (patch_ib(i)%angular_vel*patch_ib(i)%moment) + (rk_coef(s, & & 3)*dt*patch_ib(i)%torque/rk_coef(s, 4)) ! add the torque to the angular momentum - call s_compute_moment_of_inertia(i, patch_ib(i)%angular_vel) - ! update the moment of inertia to be based on the direction of the angular momentum + call s_compute_moment_of_inertia(i, & + & patch_ib(i)%angular_vel) & + & ! update the moment of inertia to be based on the direction of the angular momentum patch_ib(i)%angular_vel = patch_ib(i)%angular_vel/patch_ib(i) & & %moment ! convert back to angular velocity with the new moment of inertia end if diff --git a/toolchain/mfc/params/definitions.py b/toolchain/mfc/params/definitions.py index 2f3631c228..a193d9df49 100644 --- a/toolchain/mfc/params/definitions.py +++ b/toolchain/mfc/params/definitions.py @@ -627,8 +627,8 @@ def get_value_label(param_name: str, value: int) -> str: }, # Bubbles "bubble_model": { - "choices": [1, 2, 3], - "value_labels": {1: "Gilmore", 2: "Keller-Miksis", 3: "Rayleigh-Plesset"}, + "choices": [0, 1, 2, 3], + "value_labels": {0: "Particle", 1: "Gilmore", 2: "Keller-Miksis", 3: "Rayleigh-Plesset"}, }, # Output "format": { @@ -880,6 +880,10 @@ def _load(): for n in ["polytropic", "bubbles_euler", "polydisperse", "qbmm", "bubbles_lagrange"]: _r(n, LOG, {"bubbles"}) + # Particles + for n in ["particles_lagrange"]: + _r(n, LOG, {"particles"}) + # Viscosity _r("viscous", LOG, {"viscosity"}) @@ -1053,6 +1057,13 @@ def _load(): _r(f"p_{d}", REAL, math=r"\f$\phi_" + d + r"\f$") _r(f"bf_{d}", LOG) + # Interfacial flow inputs + _r("normMag", REAL) + _r("p0_ic", REAL) + _r("g0_ic", REAL) + _r("normFac", REAL) + _r("interface_file", STR) + # INDEXED PARAMETERS # patch_icpp (10 patches) @@ -1149,10 +1160,12 @@ def _load(): ]: _r(f"bub_pp%{a}", REAL, {"bubbles"}, math=sym) + # particle_pp (particle properties) + for a in ["rho0ref_particle", "cp_particle"]: + _r(f"particle_pp%{a}", REAL, {"particles"}) + # patch_ib (immersed boundaries) — registered as indexed family for O(1) lookup. - # max_index is None so the parameter registry stays compact (no enumeration). - # The Fortran-side upper bound (num_patches_max in m_constants.fpp) is parsed - # and enforced by the case_validator, not by max_index here. + # max_index is sourced from Fortran's num_patches_max in m_constants.fpp. _ib_tags = {"ib"} _ib_attrs: Dict[str, tuple] = {} for a in ["geometry", "moving_ibm"]: @@ -1260,12 +1273,20 @@ def _load(): _r(f"simplex_params%perturb_vel_offset({d},{j})", REAL) # lag_params (Lagrangian bubbles) - for a in ["heatTransfer_model", "massTransfer_model", "pressure_corrector", "write_bubbles", "write_bubbles_stats"]: + for a in ["heatTransfer_model", "massTransfer_model", "pressure_corrector", "write_bubbles", "write_bubbles_stats", "pressure_force", "gravity_force", "write_void_evol"]: _r(f"lag_params%{a}", LOG, {"bubbles"}) - for a in ["solver_approach", "cluster_type", "smooth_type", "nBubs_glb"]: + for a in ["solver_approach", "cluster_type", "smooth_type", "nBubs_glb", "drag_model", "vel_model", "charNz"]: _r(f"lag_params%{a}", INT, {"bubbles"}) for a in ["epsilonb", "valmaxvoid", "charwidth", "c0", "rho0", "T0", "x0", "Thost"]: _r(f"lag_params%{a}", REAL, {"bubbles"}) + _r("lag_params%input_path", STR, {"bubbles"}) + + # --- lag_params (Lagrangian particles) --- + for a in ["nParticles_glb", "stokes_drag", "qs_drag_model", "added_mass_model", "interpolation_order"]: + _r(f"lag_params%{a}", INT, {"particles"}) + + for a in ["collision_force"]: + _r(f"lag_params%{a}", LOG, {"particles"}) # chem_params for a in ["diffusion", "reactions"]: diff --git a/toolchain/mfc/params/descriptions.py b/toolchain/mfc/params/descriptions.py index 7906b6d38d..2a15f8ed37 100644 --- a/toolchain/mfc/params/descriptions.py +++ b/toolchain/mfc/params/descriptions.py @@ -250,6 +250,14 @@ "lag_mg_wrt": "Write bubble gas mass", "lag_betaT_wrt": "Write bubble heat transfer coefficient", "lag_betaC_wrt": "Write bubble mass transfer coefficient", + # Interfacial flow parameters + "interface_file": "Path to interface geometry data file", + "normFac": "Interface normalization factor", + "normMag": "Interface normal magnitude", + "g0_ic": "Initial gas volume fraction for interfacial IC", + "p0_ic": "Initial pressure for interfacial IC", + # Particle parameters + "particles_lagrange": "Enable Lagrangian solid particle solver", } # Patterns for auto-generating descriptions of indexed parameters From 61a4b8037d0345dba4a4d874462082e8adb0692a Mon Sep 17 00:00:00 2001 From: Spencer Bryngelson Date: Thu, 26 Mar 2026 19:15:52 -0400 Subject: [PATCH 02/14] fix: add missing subgrid_particle_physical_parameters type --- src/common/m_derived_types.fpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/common/m_derived_types.fpp b/src/common/m_derived_types.fpp index b7e78c8f06..620569e96b 100644 --- a/src/common/m_derived_types.fpp +++ b/src/common/m_derived_types.fpp @@ -309,6 +309,12 @@ module m_derived_types real(wp) :: R_g !< gas constant of gas (bubble) end type subgrid_bubble_physical_parameters + !> Physical parameters for Lagrangian solid particles + type subgrid_particle_physical_parameters + real(wp) :: rho0ref_particle !< Reference particle density + real(wp) :: cp_particle !< Specific heat capacity of particle + end type subgrid_particle_physical_parameters + type mpi_io_airfoil_ib_var integer, dimension(2) :: view type(vec3_dt), allocatable, dimension(:) :: var From 8fd88cd1d110ce9027ab9061fb341fb0c269fc3b Mon Sep 17 00:00:00 2001 From: Spencer Bryngelson Date: Fri, 27 Mar 2026 09:30:24 -0400 Subject: [PATCH 03/14] Moving EL bubbles with MPI decomposition --- .ffmt_cache/hashes | 249 ++ .gitignore | 1 - docs/documentation/case.md | 12 +- examples/2D_moving_lag_bubs/case.py | 202 ++ examples/3D_lagrange_shbubcollapse/case.py | 1 + examples/3D_moving_lag_particles/case.py | 199 ++ misc/runners/common/rebalance-runners.sh | 10 - misc/runners/common/runner-lib.sh | 2 +- misc/runners/phoenix/config.sh | 1 + src/common/include/1dHardcodedIC.fpp | 34 +- src/common/include/2dHardcodedIC.fpp | 183 +- src/common/include/3dHardcodedIC.fpp | 237 +- src/common/include/ExtrusionHardcodedIC.fpp | 113 +- src/common/include/SharedHardcoded.fpp | 17 + src/common/include/acc_macros.fpp | 13 +- src/common/include/macros.fpp | 40 +- src/common/include/omp_macros.fpp | 33 +- src/common/include/parallel_macros.fpp | 81 +- src/common/m_boundary_common.fpp | 1502 +++++--- src/common/m_checker_common.fpp | 30 +- src/common/m_chemistry.fpp | 149 +- src/common/m_compile_specific.f90 | 54 +- src/common/m_constants.fpp | 145 +- src/common/m_delay_file_access.f90 | 19 +- src/common/m_derived_types.fpp | 567 +-- src/common/m_finite_differences.fpp | 90 +- src/common/m_helper.fpp | 412 ++- src/common/m_helper_basic.fpp | 97 +- src/common/m_model.fpp | 625 ++-- src/common/m_mpi_common.fpp | 1354 ++++++-- src/common/m_nvtx.f90 | 55 +- src/common/m_phase_change.fpp | 513 ++- src/common/m_precision_select.f90 | 10 +- src/common/m_variables_conversion.fpp | 860 +++-- src/post_process/m_checker.fpp | 15 +- src/post_process/m_data_input.f90 | 365 +- src/post_process/m_data_output.fpp | 1110 ++++-- src/post_process/m_derived_variables.fpp | 660 ++-- src/post_process/m_global_parameters.fpp | 492 +-- src/post_process/m_mpi_proxy.fpp | 273 +- src/post_process/m_start_up.fpp | 500 ++- src/post_process/p_main.fpp | 47 +- src/pre_process/m_assign_variables.fpp | 433 ++- src/pre_process/m_boundary_conditions.fpp | 93 +- src/pre_process/m_check_ib_patches.fpp | 251 +- src/pre_process/m_check_patches.fpp | 329 +- src/pre_process/m_checker.fpp | 13 +- src/pre_process/m_data_output.fpp | 390 ++- src/pre_process/m_global_parameters.fpp | 511 ++- src/pre_process/m_grid.f90 | 138 +- src/pre_process/m_icpp_patches.fpp | 1068 ++++-- src/pre_process/m_initial_condition.fpp | 135 +- src/pre_process/m_mpi_proxy.fpp | 34 +- src/pre_process/m_perturbation.fpp | 169 +- src/pre_process/m_simplex_noise.fpp | 146 +- src/pre_process/m_start_up.fpp | 538 ++- src/pre_process/p_main.f90 | 11 +- src/simulation/include/inline_capillary.fpp | 3 + src/simulation/include/inline_riemann.fpp | 40 +- src/simulation/m_acoustic_src.fpp | 388 ++- src/simulation/m_body_forces.fpp | 99 +- src/simulation/m_bubbles.fpp | 652 ++-- src/simulation/m_bubbles_EE.fpp | 154 +- src/simulation/m_bubbles_EL.fpp | 1963 +++++++---- src/simulation/m_bubbles_EL_kernels.fpp | 745 ++-- src/simulation/m_cbc.fpp | 938 +++-- src/simulation/m_checker.fpp | 49 +- src/simulation/m_compute_cbc.fpp | 120 +- src/simulation/m_compute_levelset.fpp | 348 +- src/simulation/m_data_output.fpp | 1204 ++++--- src/simulation/m_derived_variables.fpp | 334 +- src/simulation/m_fftw.fpp | 121 +- src/simulation/m_global_parameters.fpp | 845 +++-- src/simulation/m_hyperelastic.fpp | 187 +- src/simulation/m_hypoelastic.fpp | 335 +- src/simulation/m_ib_patches.fpp | 707 ++-- src/simulation/m_ibm.fpp | 615 ++-- src/simulation/m_igr.fpp | 1918 +++++----- src/simulation/m_mpi_proxy.fpp | 797 ++++- src/simulation/m_muscl.fpp | 188 +- src/simulation/m_pressure_relaxation.fpp | 87 +- src/simulation/m_qbmm.fpp | 1138 +++--- src/simulation/m_rhs.fpp | 1314 ++++--- src/simulation/m_riemann_solvers.fpp | 3459 +++++++++++-------- src/simulation/m_sim_helpers.fpp | 208 +- src/simulation/m_start_up.fpp | 641 ++-- src/simulation/m_surface_tension.fpp | 170 +- src/simulation/m_time_steppers.fpp | 525 +-- src/simulation/m_viscous.fpp | 811 +++-- src/simulation/m_weno.fpp | 1841 +++++----- src/simulation/p_main.fpp | 51 +- src/syscheck/syscheck.fpp | 1 + tests/016C1B8B/golden-metadata.txt | 94 +- tests/016C1B8B/golden.txt | 4 +- tests/2EE0C3AA/golden-metadata.txt | 175 +- tests/2EE0C3AA/golden.txt | 12 +- tests/3008BA80/golden-metadata.txt | 169 +- tests/3008BA80/golden.txt | 8 +- tests/CE7B0BC7/golden-metadata.txt | 98 +- tests/CE7B0BC7/golden.txt | 4 +- toolchain/bootstrap/format.sh | 57 +- toolchain/indenter.py | 83 + toolchain/mfc/params/definitions.py | 16 +- toolchain/mfc/params/descriptions.py | 18 +- toolchain/mfc/test/cases.py | 3 + toolchain/mfc/test/coverage.py | 3 +- toolchain/mfc/test/test_coverage_unit.py | 5 +- toolchain/modules | 4 +- toolchain/pyproject.toml | 2 +- 109 files changed, 25022 insertions(+), 14360 deletions(-) create mode 100644 .ffmt_cache/hashes create mode 100644 examples/2D_moving_lag_bubs/case.py create mode 100644 examples/3D_moving_lag_particles/case.py create mode 100644 src/common/include/SharedHardcoded.fpp create mode 100644 toolchain/indenter.py diff --git a/.ffmt_cache/hashes b/.ffmt_cache/hashes new file mode 100644 index 0000000000..4042be2e0a --- /dev/null +++ b/.ffmt_cache/hashes @@ -0,0 +1,249 @@ +10103916424136661533 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.YNbWNpe5YF/b/src/common/m_delay_file_access.f90 +10105209818380589033 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.UKcnsjaI4a/b/src/simulation/m_rhs.fpp +10105209818380589033 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.dhTNdaQgUC/b/src/simulation/m_rhs.fpp +10105209818380589033 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.erX3snVzaV/pr.fpp +10164694090871819377 src/common/m_constants.fpp +10547681541613149381 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.QwIzwEBHeU/b/src/simulation/m_compute_cbc.fpp +10547681541613149381 src/simulation/m_compute_cbc.fpp +1095557846383781790 src/pre_process/m_check_ib_patches.fpp +10971775388782938368 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.wXyGiacHHu/b/src/pre_process/m_initial_condition.fpp +11086768803786626714 src/post_process/m_start_up.fpp +1123613300469720145 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.NhWX9QvMiS/b/src/simulation/m_pressure_relaxation.fpp +11247271584116519044 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.5zMHO1bIjC/b/src/common/m_helper.fpp +11247271584116519044 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.UKcnsjaI4a/b/src/common/m_helper.fpp +11328367635707741672 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.fRp2cEQ9ib/b/src/pre_process/m_grid.f90 +11432400921178226204 src/simulation/m_ibm.fpp +11506244912723874882 src/simulation/m_muscl.fpp +1152355942436141718 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.yvB87OqER1/b/src/post_process/m_derived_variables.fpp +1162163686405901254 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.IXCiOAmlT9/b/src/simulation/m_bubbles.fpp +1162163686405901254 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.OMiiuUbkm3/pr.fpp +1162163686405901254 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.UKcnsjaI4a/b/src/simulation/m_bubbles.fpp +1162163686405901254 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.iJz2nMUb3Q/b/src/simulation/m_bubbles.fpp +11671852064421512331 src/simulation/m_bubbles.fpp +11754772473885935152 src/simulation/m_checker.fpp +1177935745597610133 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.KsaCosfP7l/b/src/simulation/m_surface_tension.fpp +11799777124238319529 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.p6vSsTKmTQ/b/src/common/include/ExtrusionHardcodedIC.fpp +11844429005742744406 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.p40EgjuOZ4/b/src/common/include/macros.fpp +11886921327637192006 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.rNk4nDDuiA/b/src/pre_process/m_assign_variables.fpp +11928143073477354808 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.ApVsay2rl0/b/src/common/m_chemistry.fpp +12064023182745758546 src/simulation/m_ib_patches.fpp +12065466121610630094 src/simulation/m_qbmm.fpp +1207923543607638260 src/simulation/m_bubbles_EE.fpp +12545196112158418286 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.4QCea7ntGd/b/src/common/m_constants.fpp +12545196112158418286 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.UKcnsjaI4a/b/src/common/m_constants.fpp +12545196112158418286 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.pHQFxfnpka/pr.fpp +12810014594504355113 src/common/m_chemistry.fpp +13010474331324068029 src/pre_process/m_check_patches.fpp +1302629992983287045 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.jlX0OxaJWC/b/src/common/include/2dHardcodedIC.fpp +13379422254557003055 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.tQPN4tJmBS/b/src/common/include/parallel_macros.fpp +13404712065072015994 src/common/include/1dHardcodedIC.fpp +13444615600554412704 src/pre_process/m_initial_condition.fpp +13737474862947549962 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.wBcCWjwdfh/b/src/common/include/1dHardcodedIC.fpp +13778436859709422582 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.ZQxwzOCdYP/b/src/pre_process/p_main.f90 +13798070750203827352 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.9oWQDBRzDO/b/src/simulation/m_data_output.fpp +13798070750203827352 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.BPphaiI0iT/b/src/simulation/m_data_output.fpp +13798070750203827352 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.FyLr7CvpOg/b/src/simulation/m_data_output.fpp +13798070750203827352 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.UKcnsjaI4a/b/src/simulation/m_data_output.fpp +13798070750203827352 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.czvPHMadlf/b/src/simulation/m_data_output.fpp +13798070750203827352 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.l4geGiBejN/b/src/simulation/m_data_output.fpp +13798070750203827352 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.mAWaP5Yqf6/pr.fpp +13798070750203827352 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.nW8Pq43Vvf/b/src/simulation/m_data_output.fpp +14038700267823699434 src/simulation/m_hypoelastic.fpp +14047356244834746872 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.xVza69symx/b/src/simulation/m_hyperelastic.fpp +14218853748338101619 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.F8v3PuEaEB/b/src/common/m_checker_common.fpp +14257682203105278348 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.CZPMCJMBJW/b/src/common/m_phase_change.fpp +14264799885104244614 src/common/m_mpi_common.fpp +14450336682570067792 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.1BExP6R8f9/b/src/simulation/m_acoustic_src.fpp +1453706485316947653 src/common/include/2dHardcodedIC.fpp +14633053619551717675 src/common/m_helper_basic.fpp +14636237826800124746 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.1geSh90r6o/b/src/pre_process/m_global_parameters.fpp +14636237826800124746 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.1nYoCE2Z93/b/src/pre_process/m_global_parameters.fpp +14636237826800124746 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.CF4oy4IF0z/b/src/pre_process/m_global_parameters.fpp +14636237826800124746 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.HVIH7qJvcV/b/src/pre_process/m_global_parameters.fpp +14636237826800124746 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.PjipPs9F6i/b/src/pre_process/m_global_parameters.fpp +14636237826800124746 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.QrrnxH74mE/pr.fpp +14636237826800124746 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.UKcnsjaI4a/b/src/pre_process/m_global_parameters.fpp +14636237826800124746 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.ketcpZUBhe/b/src/pre_process/m_global_parameters.fpp +14636237826800124746 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.kfAB4MRB1T/b/src/pre_process/m_global_parameters.fpp +14739644014569295158 src/common/include/SharedHardcoded.fpp +14954376616734417912 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.5wobk7aEG0/b/src/simulation/p_main.fpp +14999475271112169381 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.zed9MGw8lu/b/src/common/include/acc_macros.fpp +14999475271112169381 src/common/include/acc_macros.fpp +15049314966727887552 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.foNVQzeyQX/b/src/pre_process/m_simplex_noise.fpp +15110474130912937443 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.EOjTtcOp00/b/src/post_process/m_checker.fpp +15255403987111061930 src/simulation/m_igr.fpp +15338984378825505953 src/simulation/m_global_parameters.fpp +15343341342992294043 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.ZE1xLrrD4M/b/src/simulation/m_body_forces.fpp +15508824445404703824 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.DJdV0uDXkk/pr.fpp +15508824445404703824 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.UKcnsjaI4a/b/src/common/m_helper_basic.fpp +15508824445404703824 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.dpV8UkalaA/b/src/common/m_helper_basic.fpp +15573111593524903869 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.7rXfBv7i7f/b/src/simulation/m_qbmm.fpp +15615432817640526542 src/post_process/m_checker.fpp +15811265556360623843 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.6h5PDEc3xX/b/src/simulation/include/inline_capillary.fpp +15811265556360623843 src/simulation/include/inline_capillary.fpp +15842852871903378886 src/simulation/m_bubbles_EL.fpp +15941699165887750367 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.S0h68IhVLd/b/src/common/m_precision_select.f90 +16125650575599718923 src/common/include/macros.fpp +16165252533980060148 src/common/m_phase_change.fpp +16572865122016119827 src/post_process/p_main.fpp +16590815127468205830 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.wqmnQUCDbi/b/src/common/include/omp_macros.fpp +16590815127468205830 src/common/include/omp_macros.fpp +1663788838675579049 src/pre_process/m_perturbation.fpp +16666864254209086704 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.4QVjyhlBbR/b/src/simulation/m_ib_patches.fpp +16666864254209086704 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.EKTuvrJmZf/pr.fpp +16666864254209086704 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.UKcnsjaI4a/b/src/simulation/m_ib_patches.fpp +16667441275814153857 src/common/m_derived_types.fpp +1668812924145503864 src/pre_process/m_icpp_patches.fpp +16819660696315222173 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.wZ5g7DS74M/b/src/simulation/include/inline_riemann.fpp +16819660696315222173 src/simulation/include/inline_riemann.fpp +16863576169260976215 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.BtoC8sntqC/b/src/common/m_boundary_common.fpp +16863576169260976215 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.UKcnsjaI4a/b/src/common/m_boundary_common.fpp +16863576169260976215 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.WV8J0UVWWc/pr.fpp +16863576169260976215 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.tPbHdHuGzL/b/src/common/m_boundary_common.fpp +16921026541737365190 src/pre_process/m_data_output.fpp +17002367283301422912 src/post_process/m_data_output.fpp +17058020954763061075 src/simulation/m_derived_variables.fpp +17150360143499547248 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.GwPH1PymWU/b/src/pre_process/m_mpi_proxy.fpp +17150360143499547248 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.UKcnsjaI4a/b/src/pre_process/m_mpi_proxy.fpp +17374991166589206306 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.CKefDZblI8/b/src/simulation/m_muscl.fpp +17374991166589206306 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.UKcnsjaI4a/b/src/simulation/m_muscl.fpp +17374991166589206306 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.bThVXwVjHQ/pr.fpp +17474896583037663449 src/common/m_boundary_common.fpp +17475717397114845816 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.7vhQq2kOXS/b/src/pre_process/m_check_ib_patches.fpp +17489851833420935241 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.UKcnsjaI4a/b/src/pre_process/m_start_up.fpp +17489851833420935241 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.jKReiOTmE3/pr.fpp +17489851833420935241 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.pN7wf0OOXk/b/src/pre_process/m_start_up.fpp +17729534019838315074 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.5q1Y270gxY/b/src/post_process/m_global_parameters.fpp +17729534019838315074 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.UKcnsjaI4a/b/src/post_process/m_global_parameters.fpp +17729534019838315074 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.VmGqKfWL4e/b/src/post_process/m_global_parameters.fpp +17729534019838315074 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.fEo4jGidK0/pr.fpp +17747955368322546147 src/simulation/m_time_steppers.fpp +17924857709100145307 src/simulation/m_mpi_proxy.fpp +17932981799378708392 src/common/m_variables_conversion.fpp +17939937579085231691 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.1FlGgFgoLk/b/src/simulation/m_riemann_solvers.fpp +17952081853197839750 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.FM3hyTJcC1/b/src/post_process/p_main.fpp +18080888037678917285 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.UOicaksnAM/b/src/common/m_variables_conversion.fpp +18166547160227944552 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.04SRuU4uDG/b/src/simulation/m_sim_helpers.fpp +18166547160227944552 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.UH5isBDNLP/pr.fpp +18166547160227944552 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.UKcnsjaI4a/b/src/simulation/m_sim_helpers.fpp +18206858153626918909 src/post_process/m_mpi_proxy.fpp +18303915459629736231 src/simulation/m_bubbles_EL_kernels.fpp +18308153827535525888 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.LcZmBtbXI5/b/src/simulation/m_time_steppers.fpp +18308153827535525888 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.TMdfrAiUad/b/src/simulation/m_time_steppers.fpp +18308153827535525888 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.UKcnsjaI4a/b/src/simulation/m_time_steppers.fpp +18308153827535525888 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.zBXQoIJ9Ns/pr.fpp +18424647052757242046 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.90F2SuKdN3/b/src/simulation/m_igr.fpp +1878831292940939747 src/pre_process/m_boundary_conditions.fpp +1956361042530399503 src/pre_process/m_start_up.fpp +2089934286629799065 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.UKcnsjaI4a/b/src/simulation/m_bubbles_EE.fpp +2089934286629799065 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.ehVOiqSEna/b/src/simulation/m_bubbles_EE.fpp +2089934286629799065 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.mGbGtZnmMH/pr.fpp +2092302292714238550 src/pre_process/m_checker.fpp +2179692337769865707 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.UKcnsjaI4a/b/src/common/m_derived_types.fpp +2179692337769865707 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.ahYsbo4OkN/b/src/common/m_derived_types.fpp +2179692337769865707 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.u43jNT6Y9N/pr.fpp +2179692337769865707 /tmp/pr_derived.fpp +2180900767736986011 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.2wyV79dZFt/pr.fpp +2180900767736986011 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.9ywat4IE5E/b/src/simulation/m_ibm.fpp +2180900767736986011 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.UKcnsjaI4a/b/src/simulation/m_ibm.fpp +2238355401608193277 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.Xeee1w2Np4/b/src/post_process/m_start_up.fpp +2246088494097541240 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.6XVxKq1Gls/b/src/simulation/m_mpi_proxy.fpp +2246088494097541240 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.UKcnsjaI4a/b/src/simulation/m_mpi_proxy.fpp +2246088494097541240 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.bFnMb9Yj6X/pr.fpp +2275015924369440500 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.GyRQmToKip/b/src/simulation/m_bubbles_EL.fpp +2275015924369440500 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.QWfhmzAUhW/b/src/simulation/m_bubbles_EL.fpp +2275015924369440500 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.UKcnsjaI4a/b/src/simulation/m_bubbles_EL.fpp +2275015924369440500 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.sq9eLcwlqR/pr.fpp +2431245550782554100 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.IwOd4FjXKf/b/src/simulation/m_viscous.fpp +246952844057435839 src/pre_process/p_main.f90 +2525268250784412532 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.2moDi289m2/b/src/simulation/m_compute_levelset.fpp +2525268250784412532 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.UKcnsjaI4a/b/src/simulation/m_compute_levelset.fpp +2525268250784412532 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.fNlW6mq81s/pr.fpp +2551148861500766043 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.61vHeCBp3z/b/src/common/m_nvtx.f90 +2558082555087995757 src/pre_process/m_simplex_noise.fpp +2580392981306692199 src/common/m_checker_common.fpp +260403609643327097 src/common/m_delay_file_access.f90 +3177637622633093141 src/simulation/m_pressure_relaxation.fpp +330369965658929155 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.l3vlWwFtc6/b/src/pre_process/m_checker.fpp +3322818355154981622 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.zxtBRdLiDM/b/src/simulation/m_derived_variables.fpp +3420663690071121996 src/simulation/m_rhs.fpp +370939259527769189 src/pre_process/m_grid.f90 +3852216218768625740 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.ON0VZhypev/b/src/common/m_compile_specific.f90 +4271870002582174631 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.h1I7f50x8l/b/src/post_process/m_mpi_proxy.fpp +4316649851528138914 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.vJ4faZHES0/b/src/post_process/m_data_input.f90 +4318428400001911186 src/common/m_nvtx.f90 +47037120222980462 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.oFDAmDeZN7/b/src/simulation/m_fftw.fpp +4731308583521756677 src/pre_process/m_assign_variables.fpp +4769787692054280401 src/common/m_precision_select.f90 +4898418582330870284 src/simulation/m_data_output.fpp +4993379909229078812 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.RprlXGCudJ/b/src/simulation/m_checker.fpp +5143161135957632347 src/simulation/m_weno.fpp +541372253676220467 src/common/include/ExtrusionHardcodedIC.fpp +5442684352742972305 src/simulation/m_compute_levelset.fpp +5568409634376181500 src/common/m_compile_specific.f90 +5650096065662263890 src/simulation/m_cbc.fpp +5725362251714205830 src/post_process/m_global_parameters.fpp +5871828278470799827 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.hpU6ltVEIS/b/src/syscheck/syscheck.fpp +5871828278470799827 src/syscheck/syscheck.fpp +5928207121067860413 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.mpy7h1Q0k4/b/src/common/m_model.fpp +6137784461014282246 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.21jzdeIFZA/b/src/common/include/3dHardcodedIC.fpp +6137784461014282246 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.Ngtiv1vOCD/b/src/common/include/3dHardcodedIC.fpp +6137784461014282246 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.UKcnsjaI4a/b/src/common/include/3dHardcodedIC.fpp +6137784461014282246 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.aS6jzEPk9Y/b/src/common/include/3dHardcodedIC.fpp +6137784461014282246 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.b91atfZWFM/pr.fpp +6137784461014282246 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.ox5RwzwCDq/b/src/common/include/3dHardcodedIC.fpp +6137784461014282246 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.uHW6w2dKmd/b/src/common/include/3dHardcodedIC.fpp +6137784461014282246 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.unuGVybPf5/b/src/common/include/3dHardcodedIC.fpp +6211238564233770195 src/simulation/m_surface_tension.fpp +6240714802147004944 src/common/include/shared_parallel_macros.fpp +6266670715849348639 src/common/m_finite_differences.fpp +6276978915188096958 src/common/include/3dHardcodedIC.fpp +6310967954464841129 src/simulation/m_sim_helpers.fpp +6471948232201815663 src/common/include/parallel_macros.fpp +6927376021528420031 src/simulation/m_fftw.fpp +6938669613291679776 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.4o4LVAkqMP/b/src/common/m_finite_differences.fpp +6949123019557822621 src/common/m_helper.fpp +732149268206108348 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.2J0Z5N2qcF/b/src/simulation/m_weno.fpp +732149268206108348 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.2QXPygy8q1/pr_1646504.fpp +732149268206108348 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.D9KOPlN1LD/pr.fpp +732149268206108348 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.UKcnsjaI4a/b/src/simulation/m_weno.fpp +732149268206108348 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.xwrbhmKSBn/b/src/simulation/m_weno.fpp +7447400852528884671 src/post_process/m_derived_variables.fpp +7471514455985910739 src/simulation/m_start_up.fpp +7477197243973776229 src/simulation/m_riemann_solvers.fpp +7530723425281110009 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.A857NqLisR/b/src/simulation/m_cbc.fpp +7580365803335695134 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.WMlJs7jEPw/b/src/simulation/m_hypoelastic.fpp +7591413184552042268 src/simulation/m_hyperelastic.fpp +7723221865542041495 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.svITM8tMXS/b/src/pre_process/m_icpp_patches.fpp +7737322002952828776 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.UKcnsjaI4a/b/src/simulation/m_start_up.fpp +7737322002952828776 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.aYeUsTe6vQ/b/src/simulation/m_start_up.fpp +7737322002952828776 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.mGRII3r92Q/pr.fpp +8066276099644435316 src/post_process/m_data_input.f90 +8093344263636711422 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.CtULDFfiWw/pr.fpp +8093344263636711422 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.UKcnsjaI4a/b/src/simulation/m_bubbles_EL_kernels.fpp +8093344263636711422 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.u1zFhDbdg8/b/src/simulation/m_bubbles_EL_kernels.fpp +8258277022714838383 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.7MRd899dQW/b/src/simulation/m_global_parameters.fpp +8258277022714838383 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.Du4hJUphgy/b/src/simulation/m_global_parameters.fpp +8258277022714838383 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.M29f3SMb5C/pr.fpp +8258277022714838383 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.UKcnsjaI4a/b/src/simulation/m_global_parameters.fpp +8258277022714838383 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.cJ15SrprHl/b/src/simulation/m_global_parameters.fpp +8258277022714838383 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.yxQ0X6fv0o/b/src/simulation/m_global_parameters.fpp +8373688306336592140 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.tVW0Ag4HFB/b/src/pre_process/m_data_output.fpp +8384884432422989494 src/simulation/m_body_forces.fpp +8639686218598077333 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.fo85j8vdro/b/src/post_process/m_data_output.fpp +8655330804873794929 src/pre_process/m_mpi_proxy.fpp +8755329155192764099 src/pre_process/m_global_parameters.fpp +8835068673407070922 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.qfglItrwDK/b/src/pre_process/m_boundary_conditions.fpp +8870602128241043159 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.V53atDEagj/b/src/pre_process/m_check_patches.fpp +891279443899891679 src/simulation/m_acoustic_src.fpp +9370663205287462789 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.zoRoHcwA35/b/src/pre_process/m_perturbation.fpp +9374565448212229788 src/simulation/m_viscous.fpp +9419299607787709748 src/simulation/p_main.fpp +9606486790139625748 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.QCod6CiPeT/b/src/common/m_mpi_common.fpp +9606486790139625748 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.UKcnsjaI4a/b/src/common/m_mpi_common.fpp +9606486790139625748 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.Z9FK1bV094/b/src/common/m_mpi_common.fpp +9606486790139625748 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.dF9qaNUJjz/b/src/common/m_mpi_common.fpp +9606486790139625748 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.j1H2hZqcGd/pr.fpp +9606486790139625748 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.sBmtXp00OQ/b/src/common/m_mpi_common.fpp +9680365827169577304 src/common/m_model.fpp +9812035701611855679 /tmp/test_ffmt.fpp diff --git a/.gitignore b/.gitignore index aba54411e1..664b6c3083 100644 --- a/.gitignore +++ b/.gitignore @@ -113,4 +113,3 @@ benchmarks/*.png cce_*/ cce_*.log run_cce_*.sh -.ffmt_cache/ diff --git a/docs/documentation/case.md b/docs/documentation/case.md index ecdeb786d4..9e10485f58 100644 --- a/docs/documentation/case.md +++ b/docs/documentation/case.md @@ -266,6 +266,16 @@ Setup: Only requires specifying `init_dir` and filename pattern via `zeros_defau Implementation: All variables and file handling are managed in `src/common/include/ExtrusionHardcodedIC.fpp` with no manual grid configuration needed. Usage: Ideal for initializing simulations from lower-dimensional solutions, enabling users to add perturbations or modifications to the base extruded fields for flow instability studies. +The following parameters support hardcoded initial conditions that read interface data from files: + +| Parameter | Type | Description | +| ---: | :---: | :--- | +| `interface_file` | String | Path to interface geometry data file | +| `normFac` | Real | Interface normalization factor | +| `normMag` | Real | Interface normal magnitude | +| `g0_ic` | Real | Initial gas volume fraction for interfacial IC | +| `p0_ic` | Real | Initial pressure for interfacial IC | + #### Parameter Descriptions - `num_patches` defines the total number of patches defined in the domain. @@ -349,7 +359,7 @@ Definitions for currently implemented immersed boundary patch types are listed i - `c`, `t`, `p`, and `m` specify the parameters for a NACA airfoil. `m` is the maximum camber, `p` is the location of maximum camber, `c` is the coord length, and `t` is the thickness. -Additional details on this specification can be found in [NACA airfoil](https://en.wikipedia.org/wiki/NACA_airfoil). +Additional details on this specification can be found in [The Naca Airfoil Series](https://web.stanford.edu/~cantwell/AA200_Course_Material/The%20NACA%20airfoil%20series.pdf) - `slip` applies a slip boundary to the surface of the patch if true and a no-slip boundary condition to the surface if false. diff --git a/examples/2D_moving_lag_bubs/case.py b/examples/2D_moving_lag_bubs/case.py new file mode 100644 index 0000000000..8fe7ef8107 --- /dev/null +++ b/examples/2D_moving_lag_bubs/case.py @@ -0,0 +1,202 @@ +#!/usr/bin/env python3 +import argparse +import json +import math + +import numpy as np + +# Domain extents +xb = -2 +xe = 2 +yb = -2 +ye = 2 +cw = 0.05 # Characteristic width for 3D bubble cloud + +# Reference values for nondimensionalization +L0 = 1e-3 # length - m (min bubble radius) +rho0 = 950 # density - kg/m3 +c0 = 1449.0 # speed of sound - m/s +p0 = rho0 * c0 * c0 # pressure - Pa +T0 = 298 # temperature - K + +# Host properties (water) +gamma_host = 6.12 # Specific heat ratio +pi_inf_host = 3.43e8 # Stiffness - Pa +mu_host = 0.001 +c_host = 1449.0 # speed of sound - m/s +rho_host = 950 # density kg/m3 +T_host = 298 # temperature K + +# Lagrangian bubbles' properties +R_uni = 8314 # Universal gas constant - J/kmol/K +MW_g = 28.0 # Molar weight of the gas - kg/kmol +MW_v = 18.0 # Molar weight of the vapor - kg/kmol +gamma_g = 1.4 # Specific heat ratio of the gas +gamma_v = 1.333 # Specific heat ratio of the vapor +pv = 2350 # Vapor pressure of the host - Pa +cp_g = 1.0e3 # Specific heat of the gas - J/kg/K +cp_v = 2.1e3 # Specific heat of the vapor - J/kg/K +k_g = 0.025 # Thermal conductivity of the gas - W/m/K +k_v = 0.02 # Thermal conductivity of the vapor - W/m/K +diffVapor = 2.5e-5 # Diffusivity coefficient of the vapor - m2/s +sigBubble = 0.020 # Surface tension of the bubble - N/m +mu_g = 1.48e-5 +rho_g = 1 # density kg/m3 + +# Nondimmensionalization of domain size +xb = xb / L0 +xe = xe / L0 +yb = yb / L0 +ye = ye / L0 +cw = cw / L0 + +# patm = 1.0e05 # Atmospheric pressure - Pa +patm = 1e5 +g0 = 9.81 / (c0 * c0 / L0) + +# Patch prim vars +rho_host = rho_host / rho0 +rho_g = rho_g / rho0 +pres = patm / p0 + +# Timing +tend = 0.004 * c0 / L0 +tsave = tend / 50 # save time - sec + +c_host = math.sqrt(gamma_host * (pres + pi_inf_host / p0) / rho_host) +dx = (xe - xb) / (199 + 1) +dt = 0.05 * dx / c_host + +t_step_stop = int(tend / dt) +t_step_save = int(t_step_stop / 100) + +eps = 1e-8 + +# Configuration case dictionary +data = { + # Logistics + "run_time_info": "T", + # Computational Domain + "x_domain%beg": xb, + "x_domain%end": xe, + "y_domain%beg": yb, + "y_domain%end": ye, + "m": 199, + "n": 199, + "p": 0, + "cyl_coord": "F", + "dt": 1, + "t_step_start": 0, + "t_step_stop": 6000, + "t_step_save": 60, + "adap_dt": "T", + "adap_dt_max_iters": 1000, + # Simulation Algorithm + "model_eqns": 2, + "alt_soundspeed": "F", + "mixture_err": "F", + "mpp_lim": "T", + "time_stepper": 3, + "weno_order": 5, + "mapped_weno": "T", + "mp_weno": "T", + "avg_state": 2, + "weno_eps": 1e-16, + "riemann_solver": 2, + "wave_speeds": 1, + "bc_x%beg": -1, + "bc_x%end": -1, + "bc_y%beg": -1, + "bc_y%end": -1, + "num_patches": 2, + "num_fluids": 2, + # Database Structure Parameters + "format": 1, + "precision": 2, + "prim_vars_wrt": "T", + "parallel_io": "T", + "lag_db_wrt": "T", + "lag_pres_wrt": "T", + # Fluid Parameters Host + "fluid_pp(1)%gamma": 1.0 / (gamma_host - 1.0), + "fluid_pp(1)%pi_inf": gamma_host * (pi_inf_host / p0) / (gamma_host - 1.0), + # Fluid Parameters Gas + "fluid_pp(2)%gamma": 1.0 / (gamma_g - 1.0), + "fluid_pp(2)%pi_inf": 0.0e00, + # Bubble parameters + "bub_pp%R0ref": 1.0, + "bub_pp%p0ref": 1.0, + "bub_pp%rho0ref": 1.0, + "bub_pp%T0ref": 1.0, + "bub_pp%ss": sigBubble / (rho0 * L0 * c0 * c0), + "bub_pp%pv": pv / p0, + "bub_pp%vd": diffVapor / (L0 * c0), + "bub_pp%mu_l": mu_host / (rho0 * L0 * c0), + "bub_pp%gam_v": gamma_v, + "bub_pp%gam_g": gamma_g, + "bub_pp%M_v": MW_v, + "bub_pp%M_g": MW_g, + "bub_pp%k_v": k_v * (T0 / (L0 * rho0 * c0 * c0 * c0)), + "bub_pp%k_g": k_g * (T0 / (L0 * rho0 * c0 * c0 * c0)), + "bub_pp%cp_v": cp_v * (T0 / (c0 * c0)), + "bub_pp%cp_g": cp_g * (T0 / (c0 * c0)), + "bub_pp%R_v": (R_uni / MW_v) * (T0 / (c0 * c0)), + "bub_pp%R_g": (R_uni / MW_g) * (T0 / (c0 * c0)), + # Viscosity + "viscous": "T", + "fluid_pp(1)%Re(1)": 1.0 / (mu_host / (rho0 * c0 * L0)), + "fluid_pp(2)%Re(1)": 1.0 / (mu_g / (rho0 * c0 * L0)), + # Patch for background flow + "patch_icpp(1)%geometry": 3, + "patch_icpp(1)%x_centroid": (xb + xe) / 2, + "patch_icpp(1)%y_centroid": (yb + ye) / 2, + "patch_icpp(1)%length_x": (xe - xb), + "patch_icpp(1)%length_y": (ye - yb), + "patch_icpp(1)%vel(1)": 0, + "patch_icpp(1)%vel(2)": 0, + "patch_icpp(1)%pres": pres, + "patch_icpp(1)%alpha_rho(1)": (1 - eps) * rho_host, + "patch_icpp(1)%alpha_rho(2)": eps * rho_g, + "patch_icpp(1)%alpha(1)": 1 - eps, + "patch_icpp(1)%alpha(2)": eps, + # High pressure + "patch_icpp(2)%geometry": 2, + "patch_icpp(2)%alter_patch(1)": "T", + "patch_icpp(2)%smoothen": "T", + "patch_icpp(2)%smooth_patch_id": 1, + "patch_icpp(2)%smooth_coeff": 0.5, + "patch_icpp(2)%x_centroid": 0, + "patch_icpp(2)%y_centroid": 0, + "patch_icpp(2)%radius": 0.2 / L0, + "patch_icpp(2)%vel(1)": 0, + "patch_icpp(2)%vel(2)": 0, + "patch_icpp(2)%pres": 10 * pres, + "patch_icpp(2)%alpha_rho(1)": (1 - eps) * rho_host, + "patch_icpp(2)%alpha_rho(2)": eps * rho_g, + "patch_icpp(2)%alpha(1)": 1 - eps, + "patch_icpp(2)%alpha(2)": eps, + # Lagrangian Bubbles + "bubbles_lagrange": "T", + "fd_order": 4, + "bubble_model": 2, # (0) Particle (2) KM (3) RP + "thermal": 3, + "polytropic": "F", + "lag_params%nBubs_glb": 5000, # Max number of bubbles + "lag_params%vel_model": 2, + "lag_params%drag_model": 1, + "lag_params%solver_approach": 2, + "lag_params%cluster_type": 2, + "lag_params%pressure_corrector": "F", + "lag_params%smooth_type": 1, + "lag_params%epsilonb": 1.0, + "lag_params%valmaxvoid": 0.9, + "lag_params%write_bubbles": "T", + "lag_params%write_bubbles_stats": "T", + "lag_params%write_void_evol": "T", + "lag_params%charwidth": cw, + "lag_params%charNz": 10, +} + +mods = {} + +print(json.dumps({**data, **mods}, indent=4)) diff --git a/examples/3D_lagrange_shbubcollapse/case.py b/examples/3D_lagrange_shbubcollapse/case.py index 73e0b88f69..d78095b587 100644 --- a/examples/3D_lagrange_shbubcollapse/case.py +++ b/examples/3D_lagrange_shbubcollapse/case.py @@ -155,6 +155,7 @@ "lag_params%valmaxvoid": 0.9, "lag_params%write_bubbles": "F", "lag_params%write_bubbles_stats": "F", + "lag_params%write_void_evol": "T", # Bubble parameters "bub_pp%R0ref": 1.0, "bub_pp%p0ref": 1.0, diff --git a/examples/3D_moving_lag_particles/case.py b/examples/3D_moving_lag_particles/case.py new file mode 100644 index 0000000000..aac411908c --- /dev/null +++ b/examples/3D_moving_lag_particles/case.py @@ -0,0 +1,199 @@ +#!/usr/bin/env python3 +import argparse +import json +import math + +import numpy as np + +# Domain extents +xb = -2 +xe = 2 +yb = -2 +ye = 2 +zb = -2 +ze = 2 + +# Reference values for nondimensionalization +L0 = 1e-3 # length - m (min bubble radius) +rho0 = 950 # density - kg/m3 +c0 = 1449.0 # speed of sound - m/s +p0 = rho0 * c0 * c0 # pressure - Pa +T0 = 298 # temperature - K + +# Host properties (water) +gamma_host = 6.12 # Specific heat ratio +pi_inf_host = 3.43e8 # Stiffness - Pa +mu_host = 0.001 +c_host = 1449.0 # speed of sound - m/s +rho_host = 950 # density kg/m3 +T_host = 298 # temperature K + +# Lagrangian bubbles' properties +R_uni = 8314 # Universal gas constant - J/kmol/K +MW_g = 28.0 # Molar weight of the gas - kg/kmol +MW_v = 18.0 # Molar weight of the vapor - kg/kmol +gamma_g = 1.4 # Specific heat ratio of the gas +gamma_v = 1.333 # Specific heat ratio of the vapor +pv = 2350 # Vapor pressure of the host - Pa +cp_g = 1.0e3 # Specific heat of the gas - J/kg/K +cp_v = 2.1e3 # Specific heat of the vapor - J/kg/K +k_g = 0.025 # Thermal conductivity of the gas - W/m/K +k_v = 0.02 # Thermal conductivity of the vapor - W/m/K +diffVapor = 2.5e-5 # Diffusivity coefficient of the vapor - m2/s +sigBubble = 0.020 # Surface tension of the bubble - N/m +mu_g = 1.48e-5 +rho_g = 1 # density kg/m3 + +# Nondimmensionalization of domain size +xb = xb / L0 +xe = xe / L0 +yb = yb / L0 +ye = ye / L0 +zb = zb / L0 +ze = ze / L0 + +# patm = 1.0e05 # Atmospheric pressure - Pa +patm = 1e5 +g0 = 9.81 / (c0 * c0 / L0) + +# Patch prim vars +rho_host = rho_host / rho0 +rho_g = rho_g / rho0 +pres = patm / p0 + +# Timing +tend = 0.01 * c0 / L0 +tsave = tend / 50 # save time - sec +dt = (tend / 2000) * c0 / L0 + +# Configuration case dictionary +data = { + # Logistics + "run_time_info": "T", + # Computational Domain + "x_domain%beg": xb, + "x_domain%end": xe, + "y_domain%beg": yb, + "y_domain%end": ye, + "z_domain%beg": zb, + "z_domain%end": ze, + "m": 199, + "n": 199, + "p": 199, + "dt": 1.0, + "t_step_start": 0, + "t_step_stop": 10000, + "t_step_save": 100, + # Simulation Algorithm + "model_eqns": 2, + "alt_soundspeed": "F", + "mixture_err": "F", + "mpp_lim": "T", + "time_stepper": 3, + "weno_order": 5, + "mapped_weno": "T", + "mp_weno": "F", + "avg_state": 2, + "weno_eps": 1e-16, + "riemann_solver": 2, + "wave_speeds": 1, + "bc_x%beg": -1, + "bc_x%end": -1, + "bc_y%beg": -1, + "bc_y%end": -1, + "bc_z%beg": -1, + "bc_z%end": -1, + "num_patches": 2, + "num_fluids": 2, + # Database Structure Parameters + "format": 1, + "precision": 2, + "prim_vars_wrt": "T", + "parallel_io": "T", + "lag_db_wrt": "T", + "lag_rad_wrt": "T", + # Fluid Parameters Host + "fluid_pp(1)%gamma": 1.0 / (gamma_host - 1.0), + "fluid_pp(1)%pi_inf": gamma_host * (pi_inf_host / p0) / (gamma_host - 1.0), + # Fluid Parameters Gas + "fluid_pp(2)%gamma": 1.0 / (gamma_g - 1.0), + "fluid_pp(2)%pi_inf": 0.0e00, + # Bubble parameters + "bub_pp%R0ref": 1.0, + "bub_pp%p0ref": 1.0, + "bub_pp%rho0ref": 1.0, + "bub_pp%T0ref": 1.0, + "bub_pp%ss": sigBubble / (rho0 * L0 * c0 * c0), + "bub_pp%pv": pv / p0, + "bub_pp%vd": diffVapor / (L0 * c0), + "bub_pp%mu_l": mu_host / (rho0 * L0 * c0), + "bub_pp%gam_v": gamma_v, + "bub_pp%gam_g": gamma_g, + "bub_pp%M_v": MW_v, + "bub_pp%M_g": MW_g, + "bub_pp%k_v": k_v * (T0 / (L0 * rho0 * c0 * c0 * c0)), + "bub_pp%k_g": k_g * (T0 / (L0 * rho0 * c0 * c0 * c0)), + "bub_pp%cp_v": cp_v * (T0 / (c0 * c0)), + "bub_pp%cp_g": cp_g * (T0 / (c0 * c0)), + "bub_pp%R_v": (R_uni / MW_v) * (T0 / (c0 * c0)), + "bub_pp%R_g": (R_uni / MW_g) * (T0 / (c0 * c0)), + # Viscosity + "viscous": "T", + "fluid_pp(1)%Re(1)": 1.0 / (mu_host / (rho0 * c0 * L0)), + "fluid_pp(2)%Re(1)": 1.0 / (mu_g / (rho0 * c0 * L0)), + # Patch for background flow + "patch_icpp(1)%geometry": 9, + "patch_icpp(1)%x_centroid": (xb + xe) / 2, + "patch_icpp(1)%y_centroid": (yb + ye) / 2, + "patch_icpp(1)%z_centroid": (zb + ze) / 2, + "patch_icpp(1)%length_x": (xe - xb), + "patch_icpp(1)%length_y": (ye - yb), + "patch_icpp(1)%length_z": (ze - zb), + "patch_icpp(1)%vel(1)": 0, + "patch_icpp(1)%vel(2)": 0, + "patch_icpp(1)%vel(3)": 0, + "patch_icpp(1)%pres": pres, + "patch_icpp(1)%alpha_rho(1)": rho_host, + "patch_icpp(1)%alpha_rho(2)": rho_g, + "patch_icpp(1)%alpha(1)": 1, + "patch_icpp(1)%alpha(2)": 0, + # High pressure + "patch_icpp(2)%geometry": 8, + "patch_icpp(2)%alter_patch(1)": "T", + "patch_icpp(2)%x_centroid": 0, # 1.15/L0, + "patch_icpp(2)%y_centroid": 0, # 0.33/L0, + "patch_icpp(2)%z_centroid": 0, # 0.33/L0, + "patch_icpp(2)%radius": 0.2 / L0, + "patch_icpp(2)%vel(1)": 0, + "patch_icpp(2)%vel(2)": 0, + "patch_icpp(2)%vel(3)": 0, + "patch_icpp(2)%pres": 20 * pres, + "patch_icpp(2)%alpha_rho(1)": rho_host, + "patch_icpp(2)%alpha_rho(2)": rho_g, + "patch_icpp(2)%alpha(1)": 1, + "patch_icpp(2)%alpha(2)": 0, + # Lagrangian Bubbles + "bubbles_lagrange": "T", + "fd_order": 4, + "bubble_model": 2, + "thermal": 3, + "polytropic": "F", + "adap_dt": "T", + "adap_dt_max_iters": 500, + "lag_params%nBubs_glb": 10000, + "lag_params%vel_model": 2, + "lag_params%drag_model": 1, + "lag_params%solver_approach": 2, + "lag_params%cluster_type": 1, + "lag_params%pressure_corrector": "F", + "lag_params%smooth_type": 1, + "lag_params%epsilonb": 1.0, + "lag_params%valmaxvoid": 0.9, + "lag_params%write_bubbles": "T", + "lag_params%write_bubbles_stats": "T", + "lag_params%write_void_evol": "T", +} + +mods = {} + +print(json.dumps({**data, **mods}, indent=4)) diff --git a/misc/runners/common/rebalance-runners.sh b/misc/runners/common/rebalance-runners.sh index e94047ff85..20a20b0f7c 100644 --- a/misc/runners/common/rebalance-runners.sh +++ b/misc/runners/common/rebalance-runners.sh @@ -106,16 +106,6 @@ done # Add offline runners to be placed for i in "${offline[@]}"; do to_place+=("offline $i"); done -# Shuffle to_place so sequential runner numbers spread across nodes -# (avoids overloading one node when jobs arrive in number order) -shuffled=() -while [ ${#to_place[@]} -gt 0 ]; do - rand=$(( RANDOM % ${#to_place[@]} )) - shuffled+=("${to_place[$rand]}") - to_place=("${to_place[@]:0:$rand}" "${to_place[@]:$((rand+1))}") -done -to_place=("${shuffled[@]}") - # Assign to underloaded nodes moves=() for entry in "${to_place[@]}"; do diff --git a/misc/runners/common/runner-lib.sh b/misc/runners/common/runner-lib.sh index 21b7ce7083..810e1b8301 100755 --- a/misc/runners/common/runner-lib.sh +++ b/misc/runners/common/runner-lib.sh @@ -21,7 +21,7 @@ gh_list_runners() { # Get a registration token for new runners. gh_registration_token() { - gh api "orgs/$ORG/actions/runners/registration-token" -X POST --jq .token + gh api "orgs/$ORG/actions/runners/registration-token" --jq .token } # Get the latest runner binary version. diff --git a/misc/runners/phoenix/config.sh b/misc/runners/phoenix/config.sh index 8931219fbe..11826019c2 100755 --- a/misc/runners/phoenix/config.sh +++ b/misc/runners/phoenix/config.sh @@ -15,6 +15,7 @@ SSH_OPTS="-o ConnectTimeout=5" # Parent directories containing actions-runner-*/ installations on shared storage. RUNNER_PARENT_DIRS=( + /storage/scratch1/6/sbryngelson3/mfc-runners /storage/project/r-sbryngelson3-0/sbryngelson3/mfc-runners-2 ) diff --git a/src/common/include/1dHardcodedIC.fpp b/src/common/include/1dHardcodedIC.fpp index 562005ac32..4359528a3f 100644 --- a/src/common/include/1dHardcodedIC.fpp +++ b/src/common/include/1dHardcodedIC.fpp @@ -5,7 +5,7 @@ #:def Hardcoded1D() select case (patch_icpp(patch_id)%hcid) - case (150) ! 1D Smooth Alfven Case for MHD + case (150) ! 1D Smooth Alfven Case for MHD ! velocity q_prim_vf(momxb + 1)%sf(i, 0, 0) = 0.1_wp*sin(2._wp*pi*x_cc(i)) q_prim_vf(momxb + 2)%sf(i, 0, 0) = 0.1_wp*cos(2._wp*pi*x_cc(i)) @@ -13,21 +13,24 @@ ! magnetic field q_prim_vf(B_idx%end - 1)%sf(i, 0, 0) = 0.1_wp*sin(2._wp*pi*x_cc(i)) q_prim_vf(B_idx%end)%sf(i, 0, 0) = 0.1_wp*cos(2._wp*pi*x_cc(i)) - case (170) ! 1D profile from external data (e.g. Cantera, SDtoolbox) - ! This hardcoded case can be used to start a simulation with initial conditions given from a known 1D profile (e.g. Cantera, - ! SDtoolbox) + + case (170) + ! This hardcoded case can be used to start a simulation with initial conditions given from a known 1D profile (e.g. Cantera, SDtoolbox) @: HardcodedReadValues() - case (180) ! Shu-Osher problem - ! This is patch is hard-coded for test suite optimization used in the 1D_shuoser cases: "patch_icpp(2)%alpha_rho(1)": "1 + - ! 0.2*sin(5*x)" + + case (180) + ! This is patch is hard-coded for test suite optimization used in the + ! 1D_shuoser cases: "patch_icpp(2)%alpha_rho(1)": "1 + 0.2*sin(5*x)" if (patch_id == 2) then q_prim_vf(contxb + 0)%sf(i, 0, 0) = 1 + 0.2*sin(5*x_cc(i)) end if - case (181) ! Titarev-Torro problem - ! This is patch is hard-coded for test suite optimization used in the 1D_titarevtorro cases: "patch_icpp(2)%alpha_rho(1)": - ! "1 + 0.1*sin(20*x*pi)" + + case (181) + ! This is patch is hard-coded for test suite optimization used in the + ! 1D_titarevtorro cases: "patch_icpp(2)%alpha_rho(1)": "1 + 0.1*sin(20*x*pi)" q_prim_vf(contxb + 0)%sf(i, 0, 0) = 1 + 0.1*sin(20*x_cc(i)*pi) - case (182) ! Multi-component diffusion + + case (182) ! This patch is a hard-coded for test suite optimization (multiple component diffusion) x_mid_diffu = 0.05_wp/2.0_wp width_sq = (2.5_wp*10.0_wp**(-3.0_wp))**2 @@ -48,11 +51,16 @@ temp = (320.0_wp - 1350.0_wp)*profile_shape + 1350.0_wp - molar_mass_inv = y1/31.998_wp + y2/18.01508_wp + y3/16.04256_wp + y4/28.0134_wp + molar_mass_inv = y1/31.998_wp + & + y2/18.01508_wp + & + y3/16.04256_wp + & + y4/28.0134_wp q_prim_vf(contxb)%sf(i, 0, 0) = 1.01325_wp*(10.0_wp)**5/(temp*8.3144626_wp*1000.0_wp*molar_mass_inv) + case default call s_int_to_str(patch_id, iStr) - call s_mpi_abort("Invalid hcid specified for patch " // trim(iStr)) + call s_mpi_abort("Invalid hcid specified for patch "//trim(iStr)) end select + #:enddef diff --git a/src/common/include/2dHardcodedIC.fpp b/src/common/include/2dHardcodedIC.fpp index b2752228f0..a35633bca1 100644 --- a/src/common/include/2dHardcodedIC.fpp +++ b/src/common/include/2dHardcodedIC.fpp @@ -6,6 +6,7 @@ real(wp) :: factor real(wp) :: r0, alpha, r2 real(wp) :: sinA, cosA + real(wp) :: r_sq ! # 207 @@ -17,17 +18,21 @@ #:enddef #:def Hardcoded2D() - select case (patch_icpp(patch_id)%hcid) ! 2D_hardcoded_ic example case - case (200) ! Two-fluid cubic interface + + select case (patch_icpp(patch_id)%hcid) ! 2D_hardcoded_ic example case + + case (200) if (y_cc(j) <= (-x_cc(i)**3 + 1)**(1._wp/3._wp)) then ! Volume Fractions q_prim_vf(advxb)%sf(i, j, 0) = eps q_prim_vf(advxe)%sf(i, j, 0) = 1._wp - eps + ! Denssities q_prim_vf(contxb)%sf(i, j, 0) = eps*1000._wp q_prim_vf(contxe)%sf(i, j, 0) = (1._wp - eps)*1._wp + ! Pressure q_prim_vf(E_idx)%sf(i, j, 0) = 1000._wp end if - case (202) ! Gresho vortex (Gouasmi et al 2022 JCP) + case (202) ! Gresho vortex (Gouasmi et al 2022 JCP) r = ((x_cc(i) - 0.5_wp)**2 + (y_cc(j) - 0.5_wp)**2)**0.5_wp rmax = 0.2_wp @@ -48,7 +53,7 @@ q_prim_vf(momxe)%sf(i, j, 0) = 0._wp q_prim_vf(E_idx)%sf(i, j, 0) = p0 + umax**2*(-2 + 4*log(2._wp)) end if - case (203) ! Gresho vortex (Gouasmi et al 2022 JCP) with density correction + case (203) ! Gresho vortex (Gouasmi et al 2022 JCP) with density correction r = ((x_cc(i) - 0.5_wp)**2._wp + (y_cc(j) - 0.5_wp)**2)**0.5_wp rmax = 0.2_wp @@ -71,7 +76,7 @@ end if q_prim_vf(contxb)%sf(i, j, 0) = q_prim_vf(E_idx)%sf(i, j, 0)**(1._wp/gam) - case (204) ! Rayleigh-Taylor instability + case (204) ! Rayleigh-Taylor instability rhoH = 3._wp rhoL = 1._wp pRef = 1.e5_wp @@ -102,10 +107,11 @@ pInt = pref + rhoH*9.81_wp*(1.2_wp - intH) q_prim_vf(E_idx)%sf(i, j, 0) = pInt + rhoL*9.81_wp*(intH - y_cc(j)) end if - case (205) ! 2D lung wave interaction problem - h = 0.0_wp ! non dim origin y - lam = 1.0_wp ! non dim lambda - amp = patch_icpp(patch_id)%a(2) ! to be changed later! !non dim amplitude + + case (205) ! 2D lung wave interaction problem + h = 0.0_wp !non dim origin y + lam = 1.0_wp !non dim lambda + amp = patch_icpp(patch_id)%a(2) !to be changed later! !non dim amplitude intH = amp*sin(2*pi*x_cc(i)/lam - pi/2) + h @@ -116,26 +122,30 @@ q_prim_vf(advxb)%sf(i, j, 0) = patch_icpp(1)%alpha(1) q_prim_vf(advxe)%sf(i, j, 0) = patch_icpp(1)%alpha(2) end if - case (206) ! 2D lung wave interaction problem - horizontal domain - h = 0.0_wp ! non dim origin y - lam = 1.0_wp ! non dim lambda + + case (206) ! 2D lung wave interaction problem - horizontal domain + h = 0.0_wp !non dim origin y + lam = 1.0_wp !non dim lambda amp = patch_icpp(patch_id)%a(2) intL = amp*sin(2*pi*y_cc(j)/lam - pi/2) + h - if (x_cc(i) > intL) then ! this is the liquid + if (x_cc(i) > intL) then !this is the liquid q_prim_vf(contxb)%sf(i, j, 0) = patch_icpp(1)%alpha_rho(1) q_prim_vf(contxe)%sf(i, j, 0) = patch_icpp(1)%alpha_rho(2) q_prim_vf(E_idx)%sf(i, j, 0) = patch_icpp(1)%pres q_prim_vf(advxb)%sf(i, j, 0) = patch_icpp(1)%alpha(1) q_prim_vf(advxe)%sf(i, j, 0) = patch_icpp(1)%alpha(2) end if - case (207) ! Kelvin Helmholtz Instability + + case (207) ! Kelvin Helmholtz Instability sigma = 0.05_wp/sqrt(2.0_wp) gauss1 = exp(-(y_cc(j) - 0.75_wp)**2/(2.0_wp*sigma**2)) gauss2 = exp(-(y_cc(j) - 0.25_wp)**2/(2.0_wp*sigma**2)) - q_prim_vf(momxb + 1)%sf(i, j, 0) = 0.1_wp*sin(4.0_wp*pi*x_cc(i))*(gauss1 + gauss2) - case (208) ! Richtmeyer Meshkov Instability + q_prim_vf(momxb + 1)%sf(i, j, 0) = & + 0.1_wp*sin(4.0_wp*pi*x_cc(i))*(gauss1 + gauss2) + + case (208) ! Richtmeyer Meshkov Instability lam = 1.0_wp eps = 1.0e-6_wp ei = 5.0_wp @@ -150,20 +160,25 @@ q_prim_vf(advxb)%sf(i, j, 0) = alpha_sf6 q_prim_vf(advxe)%sf(i, j, 0) = alpha_air end if - case (250) ! MHD Orszag-Tang vortex - ! gamma = 5/3 rho = 25/(36*pi) p = 5/(12*pi) v = (-sin(2*pi*y), sin(2*pi*x), 0) B = (-sin(2*pi*y)/sqrt(4*pi), - ! sin(4*pi*x)/sqrt(4*pi), 0) + + case (250) ! MHD Orszag-Tang vortex + ! gamma = 5/3 + ! rho = 25/(36*pi) + ! p = 5/(12*pi) + ! v = (-sin(2*pi*y), sin(2*pi*x), 0) + ! B = (-sin(2*pi*y)/sqrt(4*pi), sin(4*pi*x)/sqrt(4*pi), 0) q_prim_vf(momxb)%sf(i, j, 0) = -sin(2._wp*pi*y_cc(j)) q_prim_vf(momxb + 1)%sf(i, j, 0) = sin(2._wp*pi*x_cc(i)) q_prim_vf(B_idx%beg)%sf(i, j, 0) = -sin(2._wp*pi*y_cc(j))/sqrt(4._wp*pi) q_prim_vf(B_idx%beg + 1)%sf(i, j, 0) = sin(4._wp*pi*x_cc(i))/sqrt(4._wp*pi) - case (251) ! RMHD Cylindrical Blast Wave [Mignone, 2006: Section 4.3.1] + + case (251) ! RMHD Cylindrical Blast Wave [Mignone, 2006: Section 4.3.1] if (x_cc(i)**2 + y_cc(j)**2 < 0.08_wp**2) then q_prim_vf(contxb)%sf(i, j, 0) = 0.01 q_prim_vf(E_idx)%sf(i, j, 0) = 1.0 - else if (x_cc(i)**2 + y_cc(j)**2 <= 1._wp**2) then + elseif (x_cc(i)**2 + y_cc(j)**2 <= 1._wp**2) then ! Linear interpolation between r=0.08 and r=1.0 factor = (1.0_wp - sqrt(x_cc(i)**2 + y_cc(j)**2))/(1.0_wp - 0.08_wp) q_prim_vf(contxb)%sf(i, j, 0) = 0.01_wp*factor + 1.e-4_wp*(1.0_wp - factor) @@ -174,21 +189,29 @@ end if ! case 252 is for the 2D MHD Rotor problem - case (252) ! 2D MHD Rotor Problem - ! Ambient conditions are set in the JSON file. This case imposes the dense, rotating cylinder. + case (252) ! 2D MHD Rotor Problem + ! Ambient conditions are set in the JSON file. + ! This case imposes the dense, rotating cylinder. ! - ! gamma = 1.4 Ambient medium (r > 0.1): rho = 1, p = 1, v = 0, B = (1,0,0) Rotor (r <= 0.1): rho = 10, p = 1 v has angular - ! velocity w=20, giving v_tan=2 at r=0.1 + ! gamma = 1.4 + ! Ambient medium (r > 0.1): + ! rho = 1, p = 1, v = 0, B = (1,0,0) + ! Rotor (r <= 0.1): + ! rho = 10, p = 1 + ! v has angular velocity w=20, giving v_tan=2 at r=0.1 ! Calculate distance squared from the center r_sq = (x_cc(i) - 0.5_wp)**2 + (y_cc(j) - 0.5_wp)**2 ! inner radius of 0.1 if (r_sq <= 0.1**2) then - ! -- Inside the rotor -- Set density uniformly to 10 + ! -- Inside the rotor -- + ! Set density uniformly to 10 q_prim_vf(contxb)%sf(i, j, 0) = 10._wp - ! Set vup constant rotation of rate v=2 v_x = -omega * (y - y_c) v_y = omega * (x - x_c) + ! Set vup constant rotation of rate v=2 + ! v_x = -omega * (y - y_c) + ! v_y = omega * (x - x_c) q_prim_vf(momxb)%sf(i, j, 0) = -20._wp*(y_cc(j) - 0.5_wp) q_prim_vf(momxb + 1)%sf(i, j, 0) = 20._wp*(x_cc(i) - 0.5_wp) @@ -200,9 +223,11 @@ q_prim_vf(momxb)%sf(i, j, 0) = -(2._wp/sqrt(r_sq))*(y_cc(j) - 0.5_wp)*(0.115_wp - sqrt(r_sq))/(0.015_wp) q_prim_vf(momxb + 1)%sf(i, j, 0) = (2._wp/sqrt(r_sq))*(x_cc(i) - 0.5_wp)*(0.115_wp - sqrt(r_sq))/(0.015_wp) end if - case (253) ! MHD Smooth Magnetic Vortex - ! Section 5.2 of Implicit hybridized discontinuous Galerkin methods for compressible magnetohydrodynamics C. Ciuca, P. - ! Fernandez, A. Christophe, N.C. Nguyen, J. Peraire + + case (253) ! MHD Smooth Magnetic Vortex + ! Section 5.2 of + ! Implicit hybridized discontinuous Galerkin methods for compressible magnetohydrodynamics + ! C. Ciuca, P. Fernandez, A. Christophe, N.C. Nguyen, J. Peraire ! velocity q_prim_vf(momxb)%sf(i, j, 0) = 1._wp - (y_cc(j)*exp(1 - (x_cc(i)**2 + y_cc(j)**2))/(2.*pi)) @@ -213,12 +238,13 @@ q_prim_vf(B_idx%beg + 1)%sf(i, j, 0) = x_cc(i)*exp(1 - (x_cc(i)**2 + y_cc(j)**2))/(2.*pi) ! pressure - q_prim_vf(E_idx)%sf(i, j, & - & 0) = 1._wp + (1 - 2._wp*(x_cc(i)**2 + y_cc(j)**2))*exp(1 - (x_cc(i)**2 + y_cc(j)**2))/((2._wp*pi)**3) + q_prim_vf(E_idx)%sf(i, j, 0) = 1._wp + (1 - 2._wp*(x_cc(i)**2 + y_cc(j)**2))*exp(1 - (x_cc(i)**2 + y_cc(j)**2))/((2._wp*pi)**3) + case (260) ! Gaussian Divergence Pulse - ! Bx(x) = 1 + C * erf((x-0.5)/\sigma) => \partialBx/\partialx = C * (2/\sqrt\pi) * exp[-((x-0.5)/\sigma)**2] * (1/\sigma) - ! Choose C = \epsilon * \sigma * \sqrt\pi / 2 => \partialBx/\partialx = \epsilon * exp[-((x-0.5)/\sigma)**2] \psi is - ! initialized to zero everywhere. + ! Bx(x) = 1 + C * erf((x-0.5)/σ) + ! ⇒ ∂Bx/∂x = C * (2/√π) * exp[-((x-0.5)/σ)**2] * (1/σ) + ! Choose C = ε * σ * √π / 2 ⇒ ∂Bx/∂x = ε * exp[-((x-0.5)/σ)**2] + ! ψ is initialized to zero everywhere. eps_mhd = patch_icpp(patch_id)%a(2) sigma = patch_icpp(patch_id)%a(3) @@ -226,6 +252,7 @@ ! B-field q_prim_vf(B_idx%beg)%sf(i, j, 0) = 1._wp + C_mhd*erf((x_cc(i) - 0.5_wp)/sigma) + case (261) ! Blob r0 = 1._wp/sqrt(8._wp) r2 = x_cc(i)**2 + y_cc(j)**2 @@ -234,11 +261,12 @@ if (alpha < 1) then q_prim_vf(B_idx%beg)%sf(i, j, 0) = 1._wp/sqrt(4._wp*pi)*(alpha**8 - 2._wp*alpha**4 + 1._wp) ! q_prim_vf(B_idx%beg)%sf(i,j,0) = 1._wp/sqrt(4000._wp*pi) * (4096._wp*r2**4 - 128._wp*r2**2 + 1._wp) - ! q_prim_vf(B_idx%beg)%sf(i,j,0) = 1._wp/(4._wp*pi) * (alpha**8 - 2._wp*alpha**4 + 1._wp) q_prim_vf(E_idx)%sf(i,j,0) = - ! 6._wp - q_prim_vf(B_idx%beg)%sf(i,j,0)**2/2._wp + ! q_prim_vf(B_idx%beg)%sf(i,j,0) = 1._wp/(4._wp*pi) * (alpha**8 - 2._wp*alpha**4 + 1._wp) + ! q_prim_vf(E_idx)%sf(i,j,0) = 6._wp - q_prim_vf(B_idx%beg)%sf(i,j,0)**2/2._wp end if + case (262) ! Tilted 2D MHD shock‐tube at α = arctan2 (≈63.4°) - ! rotate by \alpha = atan(2) + ! rotate by α = atan(2) alpha = atan(2._wp) cosA = cos(alpha) sinA = sin(alpha) @@ -246,68 +274,69 @@ r = x_cc(i)*cosA + y_cc(j)*sinA if (r <= 0.5_wp) then - ! LEFT state: \rho=1, v\parallel=+10, v\perp=0, p=20, B\parallel=B\perp=5/\sqrt(4\pi) + ! LEFT state: ρ=1, v∥=+10, v⊥=0, p=20, B∥=B⊥=5/√(4π) q_prim_vf(contxb)%sf(i, j, 0) = 1._wp q_prim_vf(momxb)%sf(i, j, 0) = 10._wp*cosA q_prim_vf(momxb + 1)%sf(i, j, 0) = 10._wp*sinA q_prim_vf(E_idx)%sf(i, j, 0) = 20._wp - q_prim_vf(B_idx%beg)%sf(i, j, 0) = (5._wp/sqrt(4._wp*pi))*cosA - (5._wp/sqrt(4._wp*pi))*sinA - q_prim_vf(B_idx%beg + 1)%sf(i, j, 0) = (5._wp/sqrt(4._wp*pi))*sinA + (5._wp/sqrt(4._wp*pi))*cosA + q_prim_vf(B_idx%beg)%sf(i, j, 0) = (5._wp/sqrt(4._wp*pi))*cosA & + - (5._wp/sqrt(4._wp*pi))*sinA + q_prim_vf(B_idx%beg + 1)%sf(i, j, 0) = (5._wp/sqrt(4._wp*pi))*sinA & + + (5._wp/sqrt(4._wp*pi))*cosA else - ! RIGHT state: \rho=1, v\parallel=-10, v\perp=0, p=1, B\parallel=B\perp=5/\sqrt(4\pi) + ! RIGHT state: ρ=1, v∥=−10, v⊥=0, p=1, B∥=B⊥=5/√(4π) q_prim_vf(contxb)%sf(i, j, 0) = 1._wp q_prim_vf(momxb)%sf(i, j, 0) = -10._wp*cosA q_prim_vf(momxb + 1)%sf(i, j, 0) = -10._wp*sinA q_prim_vf(E_idx)%sf(i, j, 0) = 1._wp - q_prim_vf(B_idx%beg)%sf(i, j, 0) = (5._wp/sqrt(4._wp*pi))*cosA - (5._wp/sqrt(4._wp*pi))*sinA - q_prim_vf(B_idx%beg + 1)%sf(i, j, 0) = (5._wp/sqrt(4._wp*pi))*sinA + (5._wp/sqrt(4._wp*pi))*cosA + q_prim_vf(B_idx%beg)%sf(i, j, 0) = (5._wp/sqrt(4._wp*pi))*cosA & + - (5._wp/sqrt(4._wp*pi))*sinA + q_prim_vf(B_idx%beg + 1)%sf(i, j, 0) = (5._wp/sqrt(4._wp*pi))*sinA & + + (5._wp/sqrt(4._wp*pi))*cosA end if ! v^z and B^z remain zero by default - case (270) ! 2D extrusion of 1D profile from external data + + case (270) ! This hardcoded case extrudes a 1D profile to initialize a 2D simulation domain @: HardcodedReadValues() - case (280) ! Isentropic vortex - ! This is patch is hard-coded for test suite optimization used in the 2D_isentropicvortex case: This analytic patch uses - ! geometry 2 + + case (280) + ! This is patch is hard-coded for test suite optimization used in the + ! 2D_isentropicvortex case: + ! This analytic patch uses geometry 2 if (patch_id == 1) then - q_prim_vf(E_idx)%sf(i, j, & - & 0) = 1.0*(1.0 - (1.0/1.0)*(5.0/(2.0*pi))*(5.0/(8.0*1.0*(1.4 + 1.0)*pi))*exp(2.0*1.0*(1.0 - (x_cc(i) & - & - patch_icpp(1)%x_centroid)**2.0 - (y_cc(j) - patch_icpp(1)%y_centroid)**2.0)))**(1.4 + 1.0) - q_prim_vf(contxb + 0)%sf(i, j, & - & 0) = 1.0*(1.0 - (1.0/1.0)*(5.0/(2.0*pi))*(5.0/(8.0*1.0*(1.4 + 1.0)*pi))*exp(2.0*1.0*(1.0 - (x_cc(i) & - & - patch_icpp(1)%x_centroid)**2.0 - (y_cc(j) - patch_icpp(1)%y_centroid)**2.0)))**1.4 - q_prim_vf(momxb + 0)%sf(i, j, & - & 0) = 0.0 + (y_cc(j) - patch_icpp(1)%y_centroid)*(5.0/(2.0*pi))*exp(1.0*(1.0 - (x_cc(i) - patch_icpp(1) & - & %x_centroid)**2.0 - (y_cc(j) - patch_icpp(1)%y_centroid)**2.0)) - q_prim_vf(momxb + 1)%sf(i, j, & - & 0) = 0.0 - (x_cc(i) - patch_icpp(1)%x_centroid)*(5.0/(2.0*pi))*exp(1.0*(1.0 - (x_cc(i) - patch_icpp(1) & - & %x_centroid)**2.0 - (y_cc(j) - patch_icpp(1)%y_centroid)**2.0)) + q_prim_vf(E_idx)%sf(i, j, 0) = 1.0*(1.0 - (1.0/1.0)*(5.0/(2.0*pi))*(5.0/(8.0*1.0*(1.4 + 1.0)*pi))*exp(2.0*1.0*(1.0 - (x_cc(i) - patch_icpp(1)%x_centroid)**2.0 - (y_cc(j) - patch_icpp(1)%y_centroid)**2.0)))**(1.4 + 1.0) + q_prim_vf(contxb + 0)%sf(i, j, 0) = 1.0*(1.0 - (1.0/1.0)*(5.0/(2.0*pi))*(5.0/(8.0*1.0*(1.4 + 1.0)*pi))*exp(2.0*1.0*(1.0 - (x_cc(i) - patch_icpp(1)%x_centroid)**2.0 - (y_cc(j) - patch_icpp(1)%y_centroid)**2.0)))**1.4 + q_prim_vf(momxb + 0)%sf(i, j, 0) = 0.0 + (y_cc(j) - patch_icpp(1)%y_centroid)*(5.0/(2.0*pi))*exp(1.0*(1.0 - (x_cc(i) - patch_icpp(1)%x_centroid)**2.0 - (y_cc(j) - patch_icpp(1)%y_centroid)**2.0)) + q_prim_vf(momxb + 1)%sf(i, j, 0) = 0.0 - (x_cc(i) - patch_icpp(1)%x_centroid)*(5.0/(2.0*pi))*exp(1.0*(1.0 - (x_cc(i) - patch_icpp(1)%x_centroid)**2.0 - (y_cc(j) - patch_icpp(1)%y_centroid)**2.0)) end if - case (281) ! Acoustic pulse - ! This is patch is hard-coded for test suite optimization used in the 2D_acoustic_pulse case: This analytic patch uses - ! geometry 2 + + case (281) + ! This is patch is hard-coded for test suite optimization used in the + ! 2D_acoustic_pulse case: + ! This analytic patch uses geometry 2 if (patch_id == 2) then - q_prim_vf(E_idx)%sf(i, j, & - & 0) = 101325*(1 - 0.5*(1.4 - 1)*(0.4)**2*exp(0.5*(1 - sqrt(x_cc(i)**2 + y_cc(j)**2))))**(1.4/(1.4 - 1)) - q_prim_vf(contxb + 0)%sf(i, j, & - & 0) = 1*(1 - 0.5*(1.4 - 1)*(0.4)**2*exp(0.5*(1 - sqrt(x_cc(i)**2 + y_cc(j)**2))))**(1/(1.4 - 1)) + q_prim_vf(E_idx)%sf(i, j, 0) = 101325*(1 - 0.5*(1.4 - 1)*(0.4)**2*exp(0.5*(1 - sqrt(x_cc(i)**2 + y_cc(j)**2))))**(1.4/(1.4 - 1)) + q_prim_vf(contxb + 0)%sf(i, j, 0) = 1*(1 - 0.5*(1.4 - 1)*(0.4)**2*exp(0.5*(1 - sqrt(x_cc(i)**2 + y_cc(j)**2))))**(1/(1.4 - 1)) end if - case (282) ! Zero-circulation vortex - ! This is patch is hard-coded for test suite optimization used in the 2D_zero_circ_vortex case: This analytic patch uses - ! geometry 2 + + case (282) + ! This is patch is hard-coded for test suite optimization used in the + ! 2D_zero_circ_vortex case: + ! This analytic patch uses geometry 2 if (patch_id == 2) then - q_prim_vf(E_idx)%sf(i, j, & - & 0) = 101325*(1 - 0.5*(1.4 - 1)*(0.1/0.3)**2*exp(0.5*(1 - sqrt(x_cc(i)**2 + y_cc(j)**2))))**(1.4/(1.4 - 1)) - q_prim_vf(contxb + 0)%sf(i, j, & - & 0) = 1*(1 - 0.5*(1.4 - 1)*(0.1/0.3)**2*exp(0.5*(1 - sqrt(x_cc(i)**2 + y_cc(j)**2))))**(1/(1.4 - 1)) - q_prim_vf(momxb + 0)%sf(i, j, & - & 0) = 112.99092883944267*(1 - (0.1/0.3))*y_cc(j)*exp(0.5*(1 - sqrt(x_cc(i)**2 + y_cc(j)**2))) + q_prim_vf(E_idx)%sf(i, j, 0) = 101325*(1 - 0.5*(1.4 - 1)*(0.1/0.3)**2*exp(0.5*(1 - sqrt(x_cc(i)**2 + y_cc(j)**2))))**(1.4/(1.4 - 1)) + q_prim_vf(contxb + 0)%sf(i, j, 0) = 1*(1 - 0.5*(1.4 - 1)*(0.1/0.3)**2*exp(0.5*(1 - sqrt(x_cc(i)**2 + y_cc(j)**2))))**(1/(1.4 - 1)) + q_prim_vf(momxb + 0)%sf(i, j, 0) = 112.99092883944267*(1 - (0.1/0.3))*y_cc(j)*exp(0.5*(1 - sqrt(x_cc(i)**2 + y_cc(j)**2))) q_prim_vf(momxb + 1)%sf(i, j, 0) = 112.99092883944267*((0.1/0.3))*x_cc(i)*exp(0.5*(1 - sqrt(x_cc(i)**2 + y_cc(j)**2))) end if + case default if (proc_rank == 0) then call s_int_to_str(patch_id, iStr) - call s_mpi_abort("Invalid hcid specified for patch " // trim(iStr)) + call s_mpi_abort("Invalid hcid specified for patch "//trim(iStr)) end if + end select + #:enddef diff --git a/src/common/include/3dHardcodedIC.fpp b/src/common/include/3dHardcodedIC.fpp index ec63047d72..359df5f80f 100644 --- a/src/common/include/3dHardcodedIC.fpp +++ b/src/common/include/3dHardcodedIC.fpp @@ -3,70 +3,143 @@ real(wp) :: rhoH, rhoL, pRef, pInt, h, lam, wl, amp, intH, alph, Mach real(wp) :: eps - ! IGR Jets Arrays to stor position and radii of jets from input file + ! IGR Jets + ! Arrays to stor position and radii of jets from input file real(wp), dimension(:), allocatable :: y_th_arr, z_th_arr, r_th_arr ! Variables to describe initial condition of jet - real(wp) :: r, ux_th, ux_am, p_th, p_am, rho_th, rho_am, y_th, z_th, r_th, eps_smooth - real(wp) :: rcut, xcut !< Intermediate variables for creating smooth initial condition - real(wp), dimension(0:n,0:p) :: rcut_arr - integer :: l, q, s !< Iterators for reading input files - integer :: start, end !< Ints to keep track of position in file - character(len=1000) :: line !< String to store line in file - character(len=25) :: value !< String to store value in line - integer :: NJet !< Number of jets + real(wp) :: r, ux_th, ux_am, p_th, p_am, rho_th, rho_am, y_th, z_th, r_th, eps_smooth + real(wp) :: rcut, xcut ! Intermediate variables for creating smooth initial condition + + real(wp), dimension(0:n, 0:p) :: rcut_arr + integer :: l, q, s ! Iterators for reading input files + integer :: start, end ! Ints to keep track of position in file + + character(len=100000) :: line ! String to store line in file + character(len=25) :: value ! String to store value in line + integer :: NJet ! Number of jets + + real(wp), allocatable, dimension(:, :) :: ih ! Array to store interface height in + logical :: file_exist ! Flag to check if file exists eps = 1e-9_wp if (patch_icpp(patch_id)%hcid == 303) then eps_smooth = 3._wp - open (unit=10, file="njet.txt", status="old", action="read") - read (10, *) NJet - close (10) - - allocate (y_th_arr(0:NJet - 1)) - allocate (z_th_arr(0:NJet - 1)) - allocate (r_th_arr(0:NJet - 1)) - - open (unit=10, file="jets.csv", status="old", action="read") - do q = 0, NJet - 1 - read (10, '(A)') line ! Read a full line as a string - start = 1 - - do l = 0, 2 - end = index(line(start:), ',') ! Find the next comma - if (end == 0) then - value = trim(adjustl(line(start:))) ! Last value in the line - else - value = trim(adjustl(line(start:start + end - 2))) ! Extract substring - start = start + end ! Move to next value - end if - if (l == 0) then - read (value, *) y_th_arr(q) ! Convert string to numeric value - else if (l == 1) then - read (value, *) z_th_arr(q) - else - read (value, *) r_th_arr(q) - end if + inquire (file="njet.txt", exist=file_exist) + if (file_exist) then + open (unit=10, file="njet.txt", status="old", action="read") + read (10, *) NJet + close (10) + else + call s_mpi_abort("Error: njet.txt file specified for hcid=303 does not exist") + end if + + @:ALLOCATE (y_th_arr(0:NJet - 1)) + @:ALLOCATE (z_th_arr(0:NJet - 1)) + @:ALLOCATE (r_th_arr(0:NJet - 1)) + + inquire (file="jets.csv", exist=file_exist) + if (file_exist) then + open (unit=10, file="jets.csv", status="old", action="read") + do q = 0, NJet - 1 + read (10, '(A)') line ! Read a full line as a string + start = 1 + + do l = 0, 2 + end = index(line(start:), ',') ! Find the next comma + if (end == 0) then + value = trim(adjustl(line(start:))) ! Last value in the line + else + value = trim(adjustl(line(start:start + end - 2))) ! Extract substring + start = start + end ! Move to next value + end if + if (l == 0) then + read (value, *) y_th_arr(q) ! Convert string to numeric value + elseif (l == 1) then + read (value, *) z_th_arr(q) + else + read (value, *) r_th_arr(q) + end if + end do end do - end do - close (10) - - do q = 0, p - do l = 0, n - rcut = 0._wp - do s = 0, NJet - 1 - r = sqrt((y_cc(l) - y_th_arr(s))**2._wp + (z_cc(q) - z_th_arr(s))**2._wp) - rcut = rcut + f_cut_on(r - r_th_arr(s), eps_smooth) + close (10) + + do q = 0, p + do l = 0, n + rcut = 0._wp + do s = 0, NJet - 1 + r = sqrt((y_cc(l) - y_th_arr(s))**2._wp + (z_cc(q) - z_th_arr(s))**2._wp) + rcut = rcut + f_cut_on(r - r_th_arr(s), eps_smooth) + end do + rcut_arr(l, q) = rcut end do - rcut_arr(l, q) = rcut end do - end do + else + call s_mpi_abort("Error: jets.csv file specified for hcid=303 does not exist") + end if + end if + + if (patch_icpp(patch_id)%hcid == 304) then + @:ALLOCATE(ih(0:n_glb, 0:p_glb)) + + if (interface_file == '.') then + call s_mpi_abort("Error: interface_file must be specified for hcid=304") + else + inquire (file=trim(interface_file), exist=file_exist) + if (file_exist) then + open (unit=10, file=trim(interface_file), status="old", action="read") + do i = 0, n_glb + read (10, '(A)') line ! Read a full line as a string + start = 1 + + do j = 0, p_glb + end = index(line(start:), ',') ! Find the next comma + if (end == 0) then + value = trim(adjustl(line(start:))) ! Last value in the line + else + value = trim(adjustl(line(start:start + end - 2))) ! Extract substring + start = start + end ! Move to next value + end if + read (value, *) ih(i, j) ! Convert string to numeric value + if (.not. f_is_default(normMag)) ih(i, j) = ih(i, j)*normMag + if (.not. f_is_default(normFac)) ih(i, j) = ih(i, j) + normFac + end do + end do + close (10) + else + call s_mpi_abort("Error: interface_file specified for hcid=304 does not exist") + end if + end if + end if + + if (patch_icpp(patch_id)%hcid == 305) then + @:ALLOCATE(ih(0:n_glb, 0:0)) + if (interface_file == '.') then + call s_mpi_abort("Error: interface_file must be specified for hcid=305") + else + inquire (file=trim(interface_file), exist=file_exist) + if (file_exist) then + open (unit=10, file=trim(interface_file), status="old", action="read") + do i = 0, n_glb + read (10, '(A)') line ! Read a full line as a string + value = trim(line) + read (value, *) ih(i, 0) ! Convert string to numeric value + if (.not. f_is_default(normMag)) ih(i, 0) = ih(i, 0)*normMag + if (.not. f_is_default(normFac)) ih(i, 0) = ih(i, 0) + normFac + end do + close (10) + else + call s_mpi_abort("Error: interface_file specified for hcid=305 does not exist") + end if + end if end if + #:enddef #:def Hardcoded3D() + select case (patch_icpp(patch_id)%hcid) - case (300) ! Rayleigh-Taylor instability + case (300) ! Rayleigh-Taylor instability rhoH = 3._wp rhoL = 1._wp pRef = 1.e5_wp @@ -97,7 +170,8 @@ pInt = pref + rhoH*9.81_wp*(1.2_wp - intH) q_prim_vf(E_idx)%sf(i, j, k) = pInt + rhoL*9.81_wp*(intH - y_cc(j)) end if - case (301) ! (3D lung geometry in X direction, |sin(*)+sin(*)|) + + case (301) ! (3D lung geometry in X direction, |sin(*)+sin(*)|) h = 0.0_wp lam = 1.0_wp amp = patch_icpp(patch_id)%a(2) @@ -109,7 +183,8 @@ q_prim_vf(advxb)%sf(i, j, k) = patch_icpp(1)%alpha(1) q_prim_vf(advxe)%sf(i, j, k) = patch_icpp(1)%alpha(2) end if - case (302) ! 3D Jet with IGR + + case (302) ! 3D Jet with IGR ux_th = 10*sqrt(1.4*0.4) ux_am = 0.0*sqrt(1.4) p_th = 2.0_wp @@ -139,7 +214,9 @@ end if q_prim_vf(E_idx)%sf(i, j, k) = p_th*rcut*xcut + p_am - case (303) ! 3D Multijet + + case (303) ! 3D Multijet + eps_smooth = 3.0_wp ux_th = 10*sqrt(1.4*0.4) ux_am = 2.5*sqrt(1.4*0.4) @@ -165,21 +242,63 @@ end if q_prim_vf(E_idx)%sf(i, j, k) = p_th*rcut*xcut + p_am - case (370) ! 3D extrusion of 2D profile from external data + + case (304) ! 3D Interface from file cartesian + + alph = 0.5_wp*(1 + (1._wp - 2._wp*eps)* & + tanh((ih(start_idx(2) + j, start_idx(3) + k) - x_cc(i))*(0.5_wp/dx))) + + q_prim_vf(advxb)%sf(i, j, k) = alph + q_prim_vf(advxe)%sf(i, j, k) = 1._wp - alph + + q_prim_vf(contxb)%sf(i, j, k) = q_prim_vf(advxb)%sf(i, j, k)*(950._wp/1000._wp) + q_prim_vf(contxe)%sf(i, j, k) = q_prim_vf(advxe)%sf(i, j, k)*(1._wp/1000._wp) + + !h = x_cc(i) - ih(start_idx(2) + j, start_idx(3) + k) + !q_prim_vf(momxb)%sf(i,j,k) = -1._wp * (ih(start_idx(2) + j, start_idx(3) + k) - normFac) * exp(-h * h / 1000) / 100._wp + + q_prim_vf(E_idx)%sf(i, j, k) = p0_ic + & + (q_prim_vf(contxb)%sf(i, j, k) + q_prim_vf(contxe)%sf(i, j, k))*g0_ic* & + (ih(start_idx(2) + j, start_idx(3) + k) - x_cc(i)) + + if (surface_tension) q_prim_vf(c_idx)%sf(i, j, k) = alph + + case (305) ! 3D Interface from file axisymmetric + + alph = 0.5_wp*(1 + (1._wp - 2._wp*eps)* & + tanh((ih(start_idx(2) + j, 0) - x_cc(i))*(0.01_wp/dx))) + + q_prim_vf(advxb)%sf(i, j, k) = alph + q_prim_vf(advxe)%sf(i, j, k) = 1._wp - alph + + q_prim_vf(contxb)%sf(i, j, k) = q_prim_vf(advxb)%sf(i, j, k)*1._wp + q_prim_vf(contxe)%sf(i, j, k) = q_prim_vf(advxe)%sf(i, j, k)*(1._wp/950._wp) + + q_prim_vf(E_idx)%sf(i, j, k) = p0_ic + & + (q_prim_vf(contxb)%sf(i, j, k) + q_prim_vf(contxe)%sf(i, j, k))*g0_ic* & + (ih(start_idx(1) + i, start_idx(3) + k) - y_cc(j)) + + if (surface_tension) q_prim_vf(c_idx)%sf(i, j, k) = alph + + case (370) ! This hardcoded case extrudes a 2D profile to initialize a 3D simulation domain @: HardcodedReadValues() - case (380) ! Taylor-Green vortex - ! This is patch is hard-coded for test suite optimization used in the 3D_TaylorGreenVortex case: This analytic patch used - ! geometry 9 + + case (380) + ! This is patch is hard-coded for test suite optimization used in the + ! 3D_TaylorGreenVortex case: + ! This analytic patch used geometry 9 Mach = 0.1 if (patch_id == 1) then - q_prim_vf(E_idx)%sf(i, j, & - & k) = 101325 + (Mach**2*376.636429464809**2/16)*(cos(2*x_cc(i)/1) + cos(2*y_cc(j)/1))*(cos(2*z_cc(k)/1) + 2) + q_prim_vf(E_idx)%sf(i, j, k) = 101325 + (Mach**2*376.636429464809**2/16)*(cos(2*x_cc(i)/1) + cos(2*y_cc(j)/1))*(cos(2*z_cc(k)/1) + 2) q_prim_vf(momxb + 0)%sf(i, j, k) = Mach*376.636429464809*sin(x_cc(i)/1)*cos(y_cc(j)/1)*sin(z_cc(k)/1) q_prim_vf(momxb + 1)%sf(i, j, k) = -Mach*376.636429464809*cos(x_cc(i)/1)*sin(y_cc(j)/1)*sin(z_cc(k)/1) end if + case default call s_int_to_str(patch_id, iStr) - call s_mpi_abort("Invalid hcid specified for patch " // trim(iStr)) + call s_mpi_abort("Invalid hcid specified for patch "//trim(iStr)) end select + #:enddef + diff --git a/src/common/include/ExtrusionHardcodedIC.fpp b/src/common/include/ExtrusionHardcodedIC.fpp index 07acc54a5e..264b227f21 100644 --- a/src/common/include/ExtrusionHardcodedIC.fpp +++ b/src/common/include/ExtrusionHardcodedIC.fpp @@ -1,70 +1,71 @@ -!> Allocate memory and read initial condition data for IC extrusion. +!> @brief Allocate memory and read initial condition data for IC extrusion. !> !> @details -!> This macro handles the complete initialization process for IC extrusion by: +!> This macro handles the complete initialization process for IC extrusion by: !> -!> **Memory Allocation:** -!> - stored_values(xRows, yRows, sys_size) - stores primitive variable data from files -!> - x_coords(nrows) - stores x-coordinates from input files -!> - y_coords(nrows) - stores y-coordinates from input files (3D case only) +!> **Memory Allocation:** +!> - stored_values(xRows, yRows, sys_size) - stores primitive variable data from files +!> - x_coords(nrows) - stores x-coordinates from input files +!> - y_coords(nrows) - stores y-coordinates from input files (3D case only) !> -!> **File Reading Operations:** -!> - Reads primitive variable data from multiple files with pattern: -!> `prim..00..dat` where timestep uses `zeros_default` padding -!> - Files are read from directory specified by `init_dir` parameter -!> - Supports 1D, 2D, and 3D computational domains +!> **File Reading Operations:** +!> - Reads primitive variable data from multiple files with pattern: +!> `prim..00..dat` where timestep uses `zeros_default` padding +!> - Files are read from directory specified by `init_dir` parameter +!> - Supports 1D, 2D, and 3D computational domains !> -!> **Grid Structure Detection:** -!> - 1D/2D: Counts lines in first file to determine xRows -!> - 3D: Analyzes coordinate patterns to determine xRows and yRows structure +!> **Grid Structure Detection:** +!> - 1D/2D: Counts lines in first file to determine xRows +!> - 3D: Analyzes coordinate patterns to determine xRows and yRows structure !> -!> **MPI Domain Mapping:** -!> - Calculates global_offset_x and global_offset_y for MPI subdomain positioning -!> - Maps file coordinates to local computational grid coordinates +!> **MPI Domain Mapping:** +!> - Calculates global_offset_x and global_offset_y for MPI subdomain positioning +!> - Maps file coordinates to local computational grid coordinates !> -!> **Data Assignment:** -!> - Populates q_prim_vf primitive variable arrays with file data -!> - Handles momentum component indexing with special treatment for momxe -!> - Sets momxe component to zero for 2D/3D cases +!> **Data Assignment:** +!> - Populates q_prim_vf primitive variable arrays with file data +!> - Handles momentum component indexing with special treatment for momxe +!> - Sets momxe component to zero for 2D/3D cases !> -!> **State Management:** -!> - Uses files_loaded flag to prevent redundant file operations -!> - Preserves data across multiple macro calls within same simulation +!> **State Management:** +!> - Uses files_loaded flag to prevent redundant file operations +!> - Preserves data across multiple macro calls within same simulation !> -!> @note File pattern uses `zeros_default` parameter (default: "000000") for timestep padding -!> @note Directory path is hardcoded in `init_dir` parameter - modify as needed -!> @warning Aborts execution if file reading errors occur. +!> @note File pattern uses `zeros_default` parameter (default: "000000") for timestep padding +!> @note Directory path is hardcoded in `init_dir` parameter - modify as needed +!> @warning Aborts execution if file reading errors occur. #:def HardcodedDimensionsExtrusion() - integer :: xRows, yRows, nRows, iix, iiy, max_files - integer :: f, iter, ios, ios2, unit, unit2, idx, idy, index_x, index_y, jump, line_count, ycount - real(wp) :: x_len, x_step, y_len, y_step - real(wp) :: dummy_x, dummy_y, dummy_z, x0, y0 - integer :: global_offset_x, global_offset_y !< MPI subdomain offset - real(wp) :: delta_x, delta_y - character(len=100), dimension(sys_size) :: fileNames !< Arrays to store all data from files - character(len=200) :: errmsg - real(wp), allocatable :: stored_values(:,:,:) - real(wp), allocatable :: x_coords(:), y_coords(:) - logical :: files_loaded = .false. - real(wp) :: domain_xstart, domain_xend, domain_ystart, domain_yend - character(len=*), parameter :: init_dir = "/home/MFC/FilesDirectory" !< For example /home/MFC/examples/1D_Shock/D/ - character(len=20) :: file_num_str !< For storing the file number as a string - character(len=20) :: zeros_part !< For the trailing zeros part - character(len=6), parameter :: zeros_default = "000000" !< Default zeros (can be changed) + integer :: xRows, yRows, nRows, iix, iiy, max_files + integer :: f, iter, ios, ios2, unit, unit2, idx, idy, index_x, index_y, jump, line_count, ycount + real(wp) :: x_len, x_step, y_len, y_step + real(wp) :: dummy_x, dummy_y, dummy_z, x0, y0 + integer :: global_offset_x, global_offset_y ! MPI subdomain offset + real(wp) :: delta_x, delta_y + character(len=100), dimension(sys_size) :: fileNames ! Arrays to store all data from files + character(len=200) :: errmsg + real(wp), allocatable :: stored_values(:, :, :) + real(wp), allocatable :: x_coords(:), y_coords(:) + logical :: files_loaded = .false. + real(wp) :: domain_xstart, domain_xend, domain_ystart, domain_yend + character(len=*), parameter :: init_dir = "/home/MFC/FilesDirectory" ! For example /home/MFC/examples/1D_Shock/D/ + character(len=20) :: file_num_str ! For storing the file number as a string + character(len=20) :: zeros_part ! For the trailing zeros part + character(len=6), parameter :: zeros_default = "000000" ! Default zeros (can be changed) #:enddef #:def HardcodedReadValues() + if (.not. files_loaded) then max_files = merge(sys_size, sys_size - 1, num_dims == 1) do f = 1, max_files write (file_num_str, '(I0)') f - fileNames(f) = trim(init_dir) // "prim." // trim(file_num_str) // ".00." // zeros_default // ".dat" + fileNames(f) = trim(init_dir)//"prim."//trim(file_num_str)//".00."//zeros_default//".dat" end do ! Common file reading setup open (newunit=unit2, file=trim(fileNames(1)), status='old', action='read', iostat=ios2) - if (ios2 /= 0) call s_mpi_abort("Error opening file: " // trim(fileNames(1))) + if (ios2 /= 0) call s_mpi_abort("Error opening file: "//trim(fileNames(1))) select case (num_dims) case (1, 2) ! 1D and 2D cases are similar @@ -81,16 +82,16 @@ yRows = 1 index_x = 0 if (num_dims == 2) index_x = i - @:ALLOCATE(x_coords(xRows), stored_values(xRows, 1, sys_size)) + @:ALLOCATE (x_coords(xRows), stored_values(xRows, 1, sys_size)) ! Read data from all files do f = 1, max_files open (newunit=unit, file=trim(fileNames(f)), status='old', action='read', iostat=ios) - if (ios /= 0) call s_mpi_abort("Error opening file: " // trim(fileNames(f))) + if (ios /= 0) call s_mpi_abort("Error opening file: "//trim(fileNames(f))) do iter = 1, xRows read (unit, *, iostat=ios) x_coords(iter), stored_values(iter, 1, f) - if (ios /= 0) call s_mpi_abort("Error reading file: " // trim(fileNames(f))) + if (ios /= 0) call s_mpi_abort("Error reading file: "//trim(fileNames(f))) end do close (unit) end do @@ -98,8 +99,10 @@ ! Calculate offsets domain_xstart = x_coords(1) x_step = x_cc(1) - x_cc(0) - delta_x = merge(x_cc(0) - domain_xstart + x_step/2.0, x_cc(index_x) - domain_xstart + x_step/2.0, num_dims == 1) + delta_x = merge(x_cc(0) - domain_xstart + x_step/2.0, & + x_cc(index_x) - domain_xstart + x_step/2.0, num_dims == 1) global_offset_x = nint(abs(delta_x)/x_step) + case (3) ! 3D case - determine grid structure ! Find yRows by counting rows with same x read (unit2, *, iostat=ios2) x0, y0, dummy_z @@ -128,7 +131,7 @@ close (unit2) xRows = nrows/yRows - @:ALLOCATE(x_coords(nrows), y_coords(nrows), stored_values(xRows, yRows, sys_size)) + @:ALLOCATE (x_coords(nrows), y_coords(nrows), stored_values(xRows, yRows, sys_size)) index_x = i index_y = j @@ -136,7 +139,7 @@ do f = 1, max_files open (newunit=unit, file=trim(fileNames(f)), status='old', action='read', iostat=ios) if (ios /= 0) then - if (f == 1) call s_mpi_abort("Error opening file: " // trim(fileNames(f))) + if (f == 1) call s_mpi_abort("Error opening file: "//trim(fileNames(f))) cycle end if @@ -174,6 +177,7 @@ do f = 1, sys_size q_prim_vf(f)%sf(i, 0, 0) = stored_values(idx, 1, f) end do + case (2) idx = i + 1 + global_offset_x - index_x do f = 1, sys_size - 1 @@ -181,6 +185,7 @@ q_prim_vf(f + jump)%sf(i, j, 0) = stored_values(idx, 1, f) end do q_prim_vf(momxe)%sf(i, j, 0) = 0.0_wp + case (3) idx = i + 1 + global_offset_x - index_x idy = j + 1 + global_offset_y - index_y @@ -194,11 +199,11 @@ #:def HardcodedDellacation() if (allocated(stored_values)) then - @:DEALLOCATE(stored_values) - @:DEALLOCATE(x_coords) + @:DEALLOCATE (stored_values) + @:DEALLOCATE (x_coords) end if if (allocated(y_coords)) then - @:DEALLOCATE(y_coords) + @:DEALLOCATE (y_coords) end if #:enddef diff --git a/src/common/include/SharedHardcoded.fpp b/src/common/include/SharedHardcoded.fpp new file mode 100644 index 0000000000..9ebd288c83 --- /dev/null +++ b/src/common/include/SharedHardcoded.fpp @@ -0,0 +1,17 @@ +#:def HardcodedDeallocation() + + if (allocated(stored_values)) then + @:DEALLOCATE (stored_values) + @:DEALLOCATE (x_coords) + end if + + if (allocated(y_coords)) then + @:DEALLOCATE (y_coords) + end if + + if (allocated(ih)) then + @:DEALLOCATE(ih) + end if + +#:enddef + diff --git a/src/common/include/acc_macros.fpp b/src/common/include/acc_macros.fpp index bd4284c01b..771ee976db 100644 --- a/src/common/include/acc_macros.fpp +++ b/src/common/include/acc_macros.fpp @@ -173,8 +173,7 @@ $:acc_directive #:enddef -#:def ACC_DECLARE(copy=None, copyin=None, copyinReadOnly=None, copyout=None, create=None, present=None, deviceptr=None, & - & link=None, extraAccArgs=None) +#:def ACC_DECLARE(copy=None, copyin=None, copyinReadOnly=None, copyout=None, create=None, present=None, deviceptr=None, link=None, extraAccArgs=None) #:set copy_val = GEN_COPY_STR(copy) #:set copyin_val = GEN_COPYIN_STR(copyin, False).strip('\n') + GEN_COPYIN_STR(copyinReadOnly, True).strip('\n') #:set copyout_val = GEN_COPYOUT_STR(copyout) @@ -191,14 +190,13 @@ $:acc_directive #:enddef -#:def ACC_LOOP(collapse=None, parallelism=None, data_dependency=None, reduction=None, reductionOp=None, private=None, & - & extraAccArgs=None) +#:def ACC_LOOP(collapse=None, parallelism=None, data_dependency=None, reduction=None, reductionOp=None, private=None, extraAccArgs=None) #:set collapse_val = GEN_COLLAPSE_STR(collapse) #:set parallelism_val = GEN_PARALLELISM_STR(parallelism) #:if data_dependency is not None #:assert isinstance(data_dependency, str) #:assert (data_dependency == 'auto' or data_dependency == 'independent') - #:set data_dependency_val = data_dependency + #:set data_dependency_val = data_dependency #:else #:set data_dependency_val = '' #:endif @@ -213,8 +211,7 @@ $:acc_directive #:enddef -#:def ACC_DATA(code, copy=None, copyin=None, copyinReadOnly=None, copyout=None, create=None, no_create=None, present=None, & - & deviceptr=None, attach=None, default=None, extraAccArgs=None) +#:def ACC_DATA(code, copy=None, copyin=None, copyinReadOnly=None, copyout=None, create=None, no_create=None, present=None, deviceptr=None, attach=None, default=None, extraAccArgs=None) #:assert code is not None #:assert isinstance(code, str) #:if code == '' or code.isspace() @@ -232,7 +229,7 @@ #:set extraAccArgs_val = GEN_EXTRA_ARGS_STR(extraAccArgs) #:set clause_val = copy_val.strip('\n') + copyin_val.strip('\n') + & & copyout_val.strip('\n') + create_val.strip('\n') + & - & no_create_val.strip('\n') + present_val.strip('\n') + & + & no_create_val.strip('\n') + present_val.strip('\n') + & & deviceptr_val.strip('\n') + attach_val.strip('\n') + & & default_val.strip('\n') #:set acc_directive = '!$acc data ' + clause_val + extraAccArgs_val.strip('\n') diff --git a/src/common/include/macros.fpp b/src/common/include/macros.fpp index 61c13886c5..03d812f53d 100644 --- a/src/common/include/macros.fpp +++ b/src/common/include/macros.fpp @@ -12,15 +12,20 @@ #endif #:enddef -! Caution: This macro requires the use of a binding script to set CUDA_VISIBLE_DEVICES, such that we have one GPU device per MPI -! rank. That's because for both cudaMemAdvise (preferred location) and cudaMemPrefetchAsync we use location = device_id = 0. For an -! example see misc/nvidia_uvm/bind.sh. NVIDIA unified memory page placement hint +! Caution: +! This macro requires the use of a binding script to set CUDA_VISIBLE_DEVICES, such that we have one GPU device per MPI rank. +! That's because for both cudaMemAdvise (preferred location) and cudaMemPrefetchAsync we use location = device_id = 0. +! For an example see misc/nvidia_uvm/bind.sh. #:def PREFER_GPU(*args) #ifdef MFC_SIMULATION #ifdef __NVCOMPILER_GPU_UNIFIED_MEM block - ! NVIDIA CUDA Fortran 25.3+: uses submodules (cuda_runtime_api, gpu_reductions, sort) See - ! https://docs.nvidia.com/hpc-sdk/compilers/cuda-fortran-prog-guide/index.html#fortran-host-modules +! Beginning in the 25.3 release, the structure of the cudafor module has been changed slightly. +! The module now includes, or “uses” 3 submodules: cuda_runtime_api, gpu_reductions, and sort. +! The cudafor functionality has not changed. But for new users, or users who have needed to +! work-around name conflicts in the module, it may be better to use cuda_runtime_api to expose +! interfaces to the CUDA runtime calls described in Chapter 4 of this guide. +! https://docs.nvidia.com/hpc-sdk/compilers/cuda-fortran-prog-guide/index.html#fortran-host-modules #if __NVCOMPILER_MAJOR__ < 25 || (__NVCOMPILER_MAJOR__ == 25 && __NVCOMPILER_MINOR__ < 3) use cudafor, gpu_sum => sum, gpu_maxval => maxval, gpu_minval => minval #else @@ -30,23 +35,24 @@ if (nv_uvm_pref_gpu) then #:for arg in args - ! print*, "Moving ${arg}$ to GPU => ", SHAPE(${arg}$) set preferred location GPU + !print*, "Moving ${arg}$ to GPU => ", SHAPE(${arg}$) + ! set preferred location GPU istat = cudaMemAdvise(c_devloc(${arg}$), SIZEOF(${arg}$), cudaMemAdviseSetPreferredLocation, 0) if (istat /= cudaSuccess) then write (*, "('Error code: ',I0, ': ')") istat - ! write(*,*) cudaGetErrorString(istat) + !write(*,*) cudaGetErrorString(istat) end if ! set accessed by CPU istat = cudaMemAdvise(c_devloc(${arg}$), SIZEOF(${arg}$), cudaMemAdviseSetAccessedBy, cudaCpuDeviceId) if (istat /= cudaSuccess) then write (*, "('Error code: ',I0, ': ')") istat - ! write(*,*) cudaGetErrorString(istat) + !write(*,*) cudaGetErrorString(istat) end if ! prefetch to GPU - physically populate memory pages istat = cudaMemPrefetchAsync(c_devloc(${arg}$), SIZEOF(${arg}$), 0, 0) if (istat /= cudaSuccess) then write (*, "('Error code: ',I0, ': ')") istat - ! write(*,*) cudaGetErrorString(istat) + !write(*,*) cudaGetErrorString(istat) end if #:endfor end if @@ -55,7 +61,6 @@ #endif #:enddef -! Allocate and create GPU device memory #:def ALLOCATE(*args) @:LOG({'@:ALLOCATE(${re.sub(' +', ' ', ', '.join(args))}$)'}) #:set allocated_variables = ', '.join(args) @@ -65,8 +70,7 @@ #:set s = a.rstrip() #:if s.endswith(')') #:set rev = s[::-1] - #:set pos = next(i for i, ch, d in ( (j, c, sum(1 if t==')' else -1 if t=='(' else 0 for t in rev[:j+1])) for j, & - & c in enumerate(rev) ) if ch == '(' and d == 0 ) + #:set pos = next(i for i, ch, d in ( (j, c, sum(1 if t==')' else -1 if t=='(' else 0 for t in rev[:j+1])) for j, c in enumerate(rev) ) if ch == '(' and d == 0 ) #:set s = s[:len(s)-1-pos] #:endif $:cleaned.append(s) @@ -75,7 +79,6 @@ $:GPU_ENTER_DATA(create='[' + joined + ']') #:enddef ALLOCATE -! Free GPU device memory and deallocate #:def DEALLOCATE(*args) @:LOG({'@:DEALLOCATE(${re.sub(' +', ' ', ', '.join(args))}$)'}) #:set allocated_variables = ', '.join(args) @@ -83,7 +86,6 @@ deallocate (${allocated_variables}$) #:enddef DEALLOCATE -! Cray-specific GPU pointer setup for vector fields #:def ACC_SETUP_VFs(*args) #ifdef _CRAYFTN block @@ -107,10 +109,10 @@ #endif #:enddef -! Cray-specific GPU pointer setup for scalar fields #:def ACC_SETUP_SFs(*args) #ifdef _CRAYFTN block + @:LOG({'@:ACC_SETUP_SFs(${', '.join(args)}$)'}) #:for arg in args @@ -123,10 +125,10 @@ #endif #:enddef -! Cray-specific GPU pointer setup for acoustic source spatials #:def ACC_SETUP_source_spatials(*args) #ifdef _CRAYFTN block + @:LOG({'@:ACC_SETUP_source_spatials(${', '.join(args)}$)'}) #:for arg in args @@ -144,6 +146,7 @@ $:GPU_ENTER_DATA(copyin=('[' + arg + '%xyz_to_r_ratios]')) end if #:endfor + end block #endif #:enddef @@ -156,8 +159,9 @@ #:def ASSERT(predicate, message = None) if (.not. (${predicate}$)) then - call s_mpi_abort("${_FILE_.split('/')[-1]}$:${_LINE_}$: " // "Assertion failed: ${predicate}$. " & - & // ${message or '"No error description."'}$) + call s_mpi_abort("${_FILE_.split('/')[-1]}$:${_LINE_}$: "// & + "Assertion failed: ${predicate}$. " & + //${message or '"No error description."'}$) end if #:enddef ! New line at end of file is required for FYPP diff --git a/src/common/include/omp_macros.fpp b/src/common/include/omp_macros.fpp index 7620e7607f..2e1df1dd8a 100644 --- a/src/common/include/omp_macros.fpp +++ b/src/common/include/omp_macros.fpp @@ -8,7 +8,7 @@ #:def OMP_MAP_STR(map_type, var_list) #:assert map_type is not None - #:assert isinstance(map_type, str) + #:assert isinstance(map_type, str) #:if var_list is not None #:set map_clause = 'map(' + map_type + ':' #:set map_val = GEN_CLAUSE(map_clause, var_list) @@ -85,13 +85,13 @@ #:enddef #! #:def OMP_ATTACH_STR(attach) -#! #:set attach_val = OMP_MAP_STR('always,to', attach) -#! $:attach_val + #! #:set attach_val = OMP_MAP_STR('always,to', attach) + #! $:attach_val #! #:enddef #! #:def OMP_DETACH_STR(detach) -#! #:set detach_val = OMP_MAP_STR('always,from', detach) -#! $:detach_val + #! #:set detach_val = OMP_MAP_STR('always,from', detach) + #! $:detach_val #! #:enddef #:def OMP_TO_STR(to) @@ -110,13 +110,13 @@ #:enddef #:def OMP_USE_DEVICE_ADDR_STR(use_device_addr) - #:set use_device_addr_val = GEN_PARENTHESES_CLAUSE('use_device_addr', use_device_addr) - $:use_device_addr_val + #:set use_device_addr_val = GEN_PARENTHESES_CLAUSE('use_device_addr', use_device_addr) + $:use_device_addr_val #:enddef #:def OMP_USE_DEVICE_PTR_STR(use_device_ptr) - #:set use_device_ptr_val = GEN_PARENTHESES_CLAUSE('use_device_ptr', use_device_ptr) - $:use_device_ptr_val + #:set use_device_ptr_val = GEN_PARENTHESES_CLAUSE('use_device_ptr', use_device_ptr) + $:use_device_ptr_val #:enddef #:def OMP_PARALLEL(code, private=None, default='present', firstprivate=None, reduction=None, reductionOp=None, & @@ -139,7 +139,7 @@ & copyout_val.strip('\n') + create_val.strip('\n') + & & no_create_val.strip('\n') + present_val.strip('\n') + & & deviceptr_val.strip('\n') + attach_val.strip('\n') - + #:set omp_clause_val = omp_clause_val.strip('\n') #:set omp_directive = '!$omp target teams ' + omp_clause_val + extraOmpArgs_val.strip('\n') @@ -153,7 +153,7 @@ & default='present', firstprivate=None, reduction=None, reductionOp=None, & & copy=None, copyin=None, copyinReadOnly=None, copyout=None, create=None, & & no_create=None, present=None, deviceptr=None, attach=None, extraOmpArgs=None) - + #:set collapse_val = GEN_COLLAPSE_STR(collapse) #:set parallelism_val = OMP_PARALLELISM_STR(parallelism) #:set default_val = OMP_DEFAULT_STR(default) @@ -191,6 +191,7 @@ #:enddef #:def END_OMP_PARALLEL_LOOP() + #:if MFC_COMPILER == NVIDIA_COMPILER_ID or MFC_COMPILER == PGI_COMPILER_ID #:set omp_end_directive = '!$omp end target teams loop' #:elif MFC_COMPILER == CCE_COMPILER_ID @@ -217,7 +218,7 @@ #:else #:set function_name_val = '' #:endif - + #:if MFC_COMPILER == AMD_COMPILER_ID #:set clause_val = '' #:else @@ -241,8 +242,7 @@ #:enddef #! Not fully implemented yet (ignores most args right now) -#:def OMP_LOOP(collapse=None, parallelism=None, data_dependency=None, reduction=None, reductionOp=None, private=None, & - & extraOmpArgs=None) +#:def OMP_LOOP(collapse=None, parallelism=None, data_dependency=None, reduction=None, reductionOp=None, private=None, extraOmpArgs=None) #:if MFC_COMPILER == NVIDIA_COMPILER_ID or MFC_COMPILER == PGI_COMPILER_ID #:set omp_directive = '!$omp loop bind(thread)' #:elif MFC_COMPILER == CCE_COMPILER_ID or MFC_COMPILER == AMD_COMPILER_ID @@ -253,8 +253,7 @@ $:omp_directive #:enddef -#:def OMP_DATA(code, copy=None, copyin=None, copyinReadOnly=None, copyout=None, create=None, no_create=None, present=None, & - & deviceptr=None, attach=None, default=None, extraOmpArgs=None) +#:def OMP_DATA(code, copy=None, copyin=None, copyinReadOnly=None, copyout=None, create=None, no_create=None, present=None, deviceptr=None, attach=None, default=None, extraOmpArgs=None) #:assert code is not None #:assert isinstance(code, str) #:if code == '' or code.isspace() @@ -272,7 +271,7 @@ #:set extraOmpArgs_val = GEN_EXTRA_ARGS_STR(extraOmpArgs) #:set clause_val = copy_val.strip('\n') + copyin_val.strip('\n') + & & copyout_val.strip('\n') + create_val.strip('\n') + & - & no_create_val.strip('\n') + present_val.strip('\n') + & + & no_create_val.strip('\n') + present_val.strip('\n') + & & deviceptr_val.strip('\n') + attach_val.strip('\n') + & & default_val.strip('\n') #:set omp_directive = '!$omp target data ' + clause_val + extraOmpArgs_val.strip('\n') diff --git a/src/common/include/parallel_macros.fpp b/src/common/include/parallel_macros.fpp index b1382ec49a..a13bcbdfcb 100644 --- a/src/common/include/parallel_macros.fpp +++ b/src/common/include/parallel_macros.fpp @@ -2,15 +2,12 @@ #:include 'omp_macros.fpp' #:include 'acc_macros.fpp' -! GPU parallel region (scalar reductions, maxval/minval) #:def GPU_PARALLEL(code, private=None, default='present', firstprivate=None, reduction=None, reductionOp=None, & & copy=None, copyin=None, copyinReadOnly=None, copyout=None, create=None, & & no_create=None, present=None, deviceptr=None, attach=None, extraAccArgs=None, extraOmpArgs=None) - #:set acc_code = ACC_PARALLEL(code, private, default, firstprivate, reduction, reductionOp, copy, copyin, copyinReadOnly, & - & copyout, create, no_create, present, deviceptr, attach, extraAccArgs) - #:set omp_code = OMP_PARALLEL(code, private, default, firstprivate, reduction, reductionOp, copy, copyin, copyinReadOnly, & - & copyout, create, no_create, present, deviceptr, attach, extraOmpArgs) + #:set acc_code = ACC_PARALLEL(code, private, default, firstprivate, reduction, reductionOp, copy, copyin, copyinReadOnly, copyout, create, no_create, present, deviceptr, attach, extraAccArgs) + #:set omp_code = OMP_PARALLEL(code, private, default, firstprivate, reduction, reductionOp, copy, copyin, copyinReadOnly, copyout, create, no_create, present, deviceptr, attach, extraOmpArgs) #if defined(MFC_OpenACC) $:acc_code @@ -19,30 +16,27 @@ #else $:code #endif + #:enddef -! GPU parallel loop over threads (most common GPU macro) #:def GPU_PARALLEL_LOOP(collapse=None, private=None, parallelism='[gang, vector]', & & default='present', firstprivate=None, reduction=None, reductionOp=None, & & copy=None, copyin=None, copyinReadOnly=None, copyout=None, create=None, & & no_create=None, present=None, deviceptr=None, attach=None, extraAccArgs=None, extraOmpArgs=None) - #:set acc_directive = ACC_PARALLEL_LOOP(collapse, private, parallelism, default, firstprivate, reduction, reductionOp, copy, & - & copyin, copyinReadOnly, copyout, create, no_create, present, deviceptr, attach, & - & extraAccArgs) - #:set omp_directive = OMP_PARALLEL_LOOP(collapse, private, parallelism, default, firstprivate, reduction, reductionOp, copy, & - & copyin, copyinReadOnly, copyout, create, no_create, present, deviceptr, attach, & - & extraOmpArgs) + #:set acc_directive = ACC_PARALLEL_LOOP(collapse, private, parallelism, default, firstprivate, reduction, reductionOp, copy, copyin, copyinReadOnly, copyout, create, no_create, present, deviceptr, attach, extraAccArgs) + #:set omp_directive = OMP_PARALLEL_LOOP(collapse, private, parallelism, default, firstprivate, reduction, reductionOp, copy, copyin, copyinReadOnly, copyout, create, no_create, present, deviceptr, attach, extraOmpArgs) #if defined(MFC_OpenACC) $:acc_directive #elif defined(MFC_OpenMP) $:omp_directive #endif + #:enddef -! Required closing for GPU_PARALLEL_LOOP #:def END_GPU_PARALLEL_LOOP() + #:set acc_end_directive = '!$acc end parallel loop' #:set omp_end_directive = END_OMP_PARALLEL_LOOP() @@ -51,16 +45,14 @@ #elif defined(MFC_OpenMP) $:omp_end_directive #endif + #:enddef -! Mark routine for device compilation -#:def GPU_ROUTINE(function_name=None, parallelism=None, nohost=False, cray_inline=False, cray_noinline=False, extraAccArgs=None, & - & extraOmpArgs=None) +#:def GPU_ROUTINE(function_name=None, parallelism=None, nohost=False, cray_inline=False, cray_noinline=False, extraAccArgs=None, extraOmpArgs=None) #:assert isinstance(cray_inline, bool) #:assert isinstance(cray_noinline, bool) #:assert not (cray_inline and cray_noinline), "cray_inline and cray_noinline are mutually exclusive" - #:set acc_directive = ACC_ROUTINE(function_name=function_name, parallelism=parallelism, nohost=nohost, & - & extraAccArgs=extraAccArgs) + #:set acc_directive = ACC_ROUTINE(function_name=function_name, parallelism=parallelism, nohost=nohost, extraAccArgs=extraAccArgs) #:set omp_directive = OMP_ROUTINE(function_name=function_name, nohost=nohost, extraOmpArgs=extraOmpArgs) #:if cray_noinline == True @@ -110,11 +102,8 @@ #:endif #:enddef -! Declare device-resident data -#:def GPU_DECLARE(copy=None, copyin=None, copyinReadOnly=None, copyout=None, create=None, present=None, deviceptr=None, & - & link=None, extraAccArgs=None, extraOmpArgs=None) - #:set acc_code = ACC_DECLARE(copy=copy, copyin=copyin, copyinReadOnly=copyinReadOnly, copyout=copyout, create=create, & - & present=present, deviceptr=deviceptr, link=link, extraAccArgs=None) +#:def GPU_DECLARE(copy=None, copyin=None, copyinReadOnly=None, copyout=None, create=None, present=None, deviceptr=None, link=None, extraAccArgs=None, extraOmpArgs=None) + #:set acc_code = ACC_DECLARE(copy=copy, copyin=copyin, copyinReadOnly=copyinReadOnly, copyout=copyout, create=create, present=present, deviceptr=deviceptr, link=link, extraAccArgs=None) #:assert copyout is None #:assert present is None #:assert deviceptr is None @@ -128,13 +117,9 @@ #endif #:enddef -! Inner loop within a GPU parallel region -#:def GPU_LOOP(collapse=None, parallelism=None, data_dependency=None, reduction=None, reductionOp=None, private=None, & - & extraAccArgs=None, extraOmpArgs=None) - #:set acc_code = ACC_LOOP(collapse=collapse, parallelism=parallelism, data_dependency=data_dependency, reduction=reduction, & - & reductionOp=reductionOp, private=private, extraAccArgs=extraAccArgs) - #:set omp_code = OMP_LOOP(collapse=collapse, parallelism=parallelism, data_dependency=data_dependency, reduction=reduction, & - & reductionOp=reductionOp, private=private, extraOmpArgs=extraOmpArgs) +#:def GPU_LOOP(collapse=None, parallelism=None, data_dependency=None, reduction=None, reductionOp=None, private=None, extraAccArgs=None, extraOmpArgs=None) + #:set acc_code = ACC_LOOP(collapse=collapse, parallelism=parallelism, data_dependency=data_dependency, reduction=reduction, reductionOp=reductionOp, private=private, extraAccArgs=extraAccArgs) + #:set omp_code = OMP_LOOP(collapse=collapse, parallelism=parallelism, data_dependency=data_dependency, reduction=reduction, reductionOp=reductionOp, private=private, extraOmpArgs=extraOmpArgs) #if defined(MFC_OpenACC) $:acc_code @@ -143,15 +128,9 @@ #endif #:enddef -! Scoped GPU data region -#:def GPU_DATA(code, copy=None, copyin=None, copyinReadOnly=None, copyout=None, create=None, no_create=None, present=None, & - & deviceptr=None, attach=None, default=None, extraAccArgs=None, extraOmpArgs=None) - #:set acc_code = ACC_DATA(code=code, copy=copy, copyin=copyin, copyinReadOnly=copyinReadOnly, copyout=copyout, create=create, & - & no_create=no_create, present=present, deviceptr=deviceptr, attach=attach, default=default, & - & extraAccArgs=extraAccArgs) - #:set omp_code = OMP_DATA(code=code, copy=copy, copyin=copyin, copyinReadOnly=copyinReadOnly, copyout=copyout, create=create, & - & no_create=no_create, present=present, deviceptr=deviceptr, attach=attach, default=default, & - & extraOmpArgs=extraOmpArgs) +#:def GPU_DATA(code, copy=None, copyin=None, copyinReadOnly=None, copyout=None, create=None, no_create=None, present=None, deviceptr=None, attach=None, default=None, extraAccArgs=None, extraOmpArgs=None) + #:set acc_code = ACC_DATA(code=code, copy=copy, copyin=copyin, copyinReadOnly=copyinReadOnly, copyout=copyout, create=create, no_create=no_create, present=present, deviceptr=deviceptr, attach=attach, default=default, extraAccArgs=extraAccArgs) + #:set omp_code = OMP_DATA(code=code, copy=copy, copyin=copyin, copyinReadOnly=copyinReadOnly, copyout=copyout, create=create, no_create=no_create, present=present, deviceptr=deviceptr, attach=attach, default=default, extraOmpArgs=extraOmpArgs) #if defined(MFC_OpenACC) $:acc_code @@ -162,8 +141,8 @@ #endif #:enddef -! Host code with device pointers (for MPI with GPU buffers) #:def GPU_HOST_DATA(code, use_device_addr=None, use_device_ptr=None, extraAccArgs=None, extraOmpArgs=None) + #:if use_device_addr is not None and use_device_ptr is not None #:set use_device_addr_end_index = len(use_device_addr) - 1 #:set use_device = use_device_addr + use_device_ptr @@ -179,8 +158,7 @@ #:set use_device = None #:endif #:set acc_code = ACC_HOST_DATA(code=code, use_device=use_device, extraAccArgs=extraAccArgs) - #:set omp_code = OMP_HOST_DATA(code=code, use_device_addr=use_device_addr, use_device_ptr=use_device_ptr, & - & extraOmpArgs=extraOmpArgs) + #:set omp_code = OMP_HOST_DATA(code=code, use_device_addr=use_device_addr, use_device_ptr=use_device_ptr, extraOmpArgs=extraOmpArgs) #if defined(MFC_OpenACC) $:acc_code @@ -191,12 +169,9 @@ #endif #:enddef -! Allocate device memory (unscoped) #:def GPU_ENTER_DATA(copyin=None, copyinReadOnly=None, create=None, attach=None, extraAccArgs=None, extraOmpArgs=None) - #:set acc_code = ACC_ENTER_DATA(copyin=copyin, copyinReadOnly=copyinReadOnly, create=create, attach=attach, & - & extraAccArgs=extraAccArgs) - #:set omp_code = OMP_ENTER_DATA(copyin=copyin, copyinReadOnly=copyinReadOnly, create=create, attach=attach, & - & extraOmpArgs=extraOmpArgs) + #:set acc_code = ACC_ENTER_DATA(copyin=copyin, copyinReadOnly=copyinReadOnly, create=create, attach=attach, extraAccArgs=extraAccArgs) + #:set omp_code = OMP_ENTER_DATA(copyin=copyin, copyinReadOnly=copyinReadOnly, create=create, attach=attach, extraOmpArgs=extraOmpArgs) #if defined(MFC_OpenACC) $:acc_code @@ -205,7 +180,6 @@ #endif #:enddef -! Free device memory #:def GPU_EXIT_DATA(copyout=None, delete=None, detach=None, extraAccArgs=None, extraOmpArgs=None) #:set acc_code = ACC_EXIT_DATA(copyout=copyout, delete=delete, detach=detach, extraAccArgs=extraAccArgs) #:set omp_code = OMP_EXIT_DATA(copyout=copyout, delete=delete, detach=detach, extraOmpArgs=extraOmpArgs) @@ -217,7 +191,6 @@ #endif #:enddef -! Atomic operation on device #:def GPU_ATOMIC(atomic, extraAccArgs=None, extraOmpArgs=None) #:set acc_code = ACC_ATOMIC(atomic=atomic, extraAccArgs=extraAccArgs) #:set omp_code = OMP_ATOMIC(atomic=atomic, extraOmpArgs=extraOmpArgs) @@ -229,7 +202,6 @@ #endif #:enddef -! End atomic capture block #:def END_GPU_ATOMIC_CAPTURE() #:set acc_end_directive = '!$acc end atomic' #:set omp_end_directive = '!$omp end atomic' @@ -240,7 +212,6 @@ #endif #:enddef -! Copy data between host and device #:def GPU_UPDATE(host=None, device=None, extraAccArgs=None, extraOmpArgs=None) #:set acc_code = ACC_UPDATE(host=host, device=device, extraAccArgs=extraAccArgs) #:set omp_code = OMP_UPDATE(host=host, device=device, extraOmpArgs=extraOmpArgs) @@ -252,7 +223,6 @@ #endif #:enddef -! Synchronization barrier #:def GPU_WAIT(extraAccArgs=None, extraOmpArgs=None) #:set acc_code = ACC_WAIT(extraAccArgs=extraAccArgs) #:set omp_code = OMP_WAIT(extraOmpArgs=extraOmpArgs) @@ -264,37 +234,34 @@ #endif #:enddef -! Import GPU library module (openacc or omp_lib) #:def USE_GPU_MODULE() + #if defined(MFC_OpenACC) use openacc #elif defined(MFC_OpenMP) use omp_lib #endif + #:enddef -! Emit code only for AMD compiler #:def DEF_AMD(code) #:if MFC_COMPILER == AMD_COMPILER_ID $:code #:endif #:enddef -! Emit code for non-Cray compilers #:def UNDEF_CCE(code) #:if MFC_COMPILER != CCE_COMPILER_ID $:code #:endif #:enddef -! Emit code only for Cray compiler #:def DEF_CCE(code) #:if MFC_COMPILER == CCE_COMPILER_ID $:code #:endif #:enddef -! Emit code for non-NVIDIA compilers #:def UNDEF_NVIDIA(code) #:if MFC_COMPILER != NVIDIA_COMPILER_ID and MFC_COMPILER != PGI_COMPILER_ID $:code diff --git a/src/common/m_boundary_common.fpp b/src/common/m_boundary_common.fpp index 918b0daea5..42b816d865 100644 --- a/src/common/m_boundary_common.fpp +++ b/src/common/m_boundary_common.fpp @@ -8,28 +8,44 @@ module m_boundary_common - use m_derived_types - use m_global_parameters + use m_derived_types !< Definitions of the derived types + + use m_global_parameters !< Definitions of the global parameters + use m_mpi_proxy + use m_constants + use m_delay_file_access + use m_compile_specific implicit none - type(scalar_field), dimension(:,:), allocatable :: bc_buffers + type(scalar_field), dimension(:, :), allocatable :: bc_buffers $:GPU_DECLARE(create='[bc_buffers]') + type(int_bounds_info), dimension(3) :: beta_bc_bounds + $:GPU_DECLARE(create='[beta_bc_bounds]') + #ifdef MFC_MPI - integer, dimension(1:3,1:2) :: MPI_BC_TYPE_TYPE - integer, dimension(1:3,1:2) :: MPI_BC_BUFFER_TYPE + integer, dimension(1:3, 1:2) :: MPI_BC_TYPE_TYPE + integer, dimension(1:3, 1:2) :: MPI_BC_BUFFER_TYPE #endif - private; public :: s_initialize_boundary_common_module, s_populate_variables_buffers, s_create_mpi_types, & - & s_populate_capillary_buffers, s_populate_F_igr_buffers, s_write_serial_boundary_condition_files, & - & s_write_parallel_boundary_condition_files, s_read_serial_boundary_condition_files, & - & s_read_parallel_boundary_condition_files, s_assign_default_bc_type, s_populate_grid_variables_buffers, & - & s_finalize_boundary_common_module + private; public :: s_initialize_boundary_common_module, & + s_populate_variables_buffers, & + s_populate_beta_buffers, & + s_create_mpi_types, & + s_populate_capillary_buffers, & + s_populate_F_igr_buffers, & + s_write_serial_boundary_condition_files, & + s_write_parallel_boundary_condition_files, & + s_read_serial_boundary_condition_files, & + s_read_parallel_boundary_condition_files, & + s_assign_default_bc_type, & + s_populate_grid_variables_buffers, & + s_finalize_boundary_common_module public :: bc_buffers @@ -39,7 +55,7 @@ module m_boundary_common contains - !> Allocate and set up boundary condition buffer arrays for all coordinate directions. + !> @brief Allocates and sets up boundary condition buffer arrays for all coordinate directions. impure subroutine s_initialize_boundary_common_module() integer :: i, j @@ -68,22 +84,40 @@ contains end do end if + if (bubbles_lagrange) then + beta_bc_bounds(1)%beg = -mapcells - 1 + beta_bc_bounds(1)%end = m + mapcells + 1 + ! n > 0 always for bubbles_lagrange + beta_bc_bounds(2)%beg = -mapcells - 1 + beta_bc_bounds(2)%end = n + mapcells + 1 + if (p == 0) then + beta_bc_bounds(3)%beg = 0 + beta_bc_bounds(3)%end = 0 + else + beta_bc_bounds(3)%beg = -mapcells - 1 + beta_bc_bounds(3)%end = p + mapcells + 1 + end if + end if + $:GPU_UPDATE(device='[beta_bc_bounds]') + end subroutine s_initialize_boundary_common_module - !> Populate the buffers of the primitive variables based on the selected boundary conditions. + !> The purpose of this procedure is to populate the buffers + !! of the primitive variables, depending on the selected + !! boundary conditions. impure subroutine s_populate_variables_buffers(bc_type, q_prim_vf, pb_in, mv_in) - type(scalar_field), dimension(sys_size), intent(inout) :: q_prim_vf - real(stp), optional, dimension(idwbuff(1)%beg:,idwbuff(2)%beg:,idwbuff(3)%beg:,1:,1:), intent(inout) :: pb_in, mv_in - type(integer_field), dimension(1:num_dims,1:2), intent(in) :: bc_type - integer :: k, l + type(scalar_field), dimension(sys_size), intent(inout) :: q_prim_vf + real(stp), optional, dimension(idwbuff(1)%beg:, idwbuff(2)%beg:, idwbuff(3)%beg:, 1:, 1:), intent(inout) :: pb_in, mv_in + type(integer_field), dimension(1:num_dims, 1:2), intent(in) :: bc_type - ! BC type codes defined in m_constants.fpp; non-negative values are MPI boundaries + integer :: k, l + ! Population of Buffers in x-direction if (bc_x%beg >= 0) then call s_mpi_sendrecv_variables_buffers(q_prim_vf, 1, -1, sys_size, pb_in, mv_in) else - $:GPU_PARALLEL_LOOP(private='[l, k]', collapse=2) + $:GPU_PARALLEL_LOOP(private='[l,k]', collapse=2) do l = 0, p do k = 0, n select case (int(bc_type(1, 1)%sf(0, k, l))) @@ -101,7 +135,8 @@ contains call s_dirichlet(q_prim_vf, 1, -1, k, l) end select - if (qbmm .and. (.not. polytropic) .and. (bc_type(1, 1)%sf(0, k, l) <= BC_GHOST_EXTRAP)) then + if (qbmm .and. (.not. polytropic) .and. & + (bc_type(1, 1)%sf(0, k, l) <= BC_GHOST_EXTRAP)) then call s_qbmm_extrapolation(1, -1, k, l, pb_in, mv_in) end if end do @@ -112,11 +147,11 @@ contains if (bc_x%end >= 0) then call s_mpi_sendrecv_variables_buffers(q_prim_vf, 1, 1, sys_size, pb_in, mv_in) else - $:GPU_PARALLEL_LOOP(private='[l, k]', collapse=2) + $:GPU_PARALLEL_LOOP(private='[l,k]', collapse=2) do l = 0, p do k = 0, n select case (int(bc_type(1, 2)%sf(0, k, l))) - case (BC_CHAR_SUP_OUTFLOW:BC_GHOST_EXTRAP) ! Ghost-cell extrap. BC at end + case (BC_CHAR_SUP_OUTFLOW:BC_GHOST_EXTRAP) ! Ghost-cell extrap. BC at end call s_ghost_cell_extrapolation(q_prim_vf, 1, 1, k, l) case (BC_REFLECTIVE) call s_symmetry(q_prim_vf, 1, 1, k, l, pb_in, mv_in) @@ -130,7 +165,8 @@ contains call s_dirichlet(q_prim_vf, 1, 1, k, l) end select - if (qbmm .and. (.not. polytropic) .and. (bc_type(1, 2)%sf(0, k, l) <= BC_GHOST_EXTRAP)) then + if (qbmm .and. (.not. polytropic) .and. & + (bc_type(1, 2)%sf(0, k, l) <= BC_GHOST_EXTRAP)) then call s_qbmm_extrapolation(1, 1, k, l, pb_in, mv_in) end if end do @@ -143,10 +179,11 @@ contains if (n == 0) return #:if not MFC_CASE_OPTIMIZATION or num_dims > 1 + if (bc_y%beg >= 0) then call s_mpi_sendrecv_variables_buffers(q_prim_vf, 2, -1, sys_size, pb_in, mv_in) else - $:GPU_PARALLEL_LOOP(private='[l, k]', collapse=2) + $:GPU_PARALLEL_LOOP(private='[l,k]', collapse=2) do l = 0, p do k = -buff_size, m + buff_size select case (int(bc_type(2, 1)%sf(k, 0, l))) @@ -166,8 +203,9 @@ contains call s_dirichlet(q_prim_vf, 2, -1, k, l) end select - if (qbmm .and. (.not. polytropic) .and. (bc_type(2, 1)%sf(k, 0, l) <= BC_GHOST_EXTRAP) .and. (bc_type(2, & - & 1)%sf(k, 0, l) /= BC_AXIS)) then + if (qbmm .and. (.not. polytropic) .and. & + (bc_type(2, 1)%sf(k, 0, l) <= BC_GHOST_EXTRAP) .and. & + (bc_type(2, 1)%sf(k, 0, l) /= BC_AXIS)) then call s_qbmm_extrapolation(2, -1, k, l, pb_in, mv_in) end if end do @@ -178,7 +216,7 @@ contains if (bc_y%end >= 0) then call s_mpi_sendrecv_variables_buffers(q_prim_vf, 2, 1, sys_size, pb_in, mv_in) else - $:GPU_PARALLEL_LOOP(private='[l, k]', collapse=2) + $:GPU_PARALLEL_LOOP(private='[l,k]', collapse=2) do l = 0, p do k = -buff_size, m + buff_size select case (int(bc_type(2, 2)%sf(k, 0, l))) @@ -196,13 +234,15 @@ contains call s_dirichlet(q_prim_vf, 2, 1, k, l) end select - if (qbmm .and. (.not. polytropic) .and. (bc_type(2, 2)%sf(k, 0, l) <= BC_GHOST_EXTRAP)) then + if (qbmm .and. (.not. polytropic) .and. & + (bc_type(2, 2)%sf(k, 0, l) <= BC_GHOST_EXTRAP)) then call s_qbmm_extrapolation(2, 1, k, l, pb_in, mv_in) end if end do end do $:END_GPU_PARALLEL_LOOP() end if + #:endif ! Population of Buffers in z-direction @@ -210,10 +250,11 @@ contains if (p == 0) return #:if not MFC_CASE_OPTIMIZATION or num_dims > 2 + if (bc_z%beg >= 0) then call s_mpi_sendrecv_variables_buffers(q_prim_vf, 3, -1, sys_size, pb_in, mv_in) else - $:GPU_PARALLEL_LOOP(private='[l, k]', collapse=2) + $:GPU_PARALLEL_LOOP(private='[l,k]', collapse=2) do l = -buff_size, n + buff_size do k = -buff_size, m + buff_size select case (int(bc_type(3, 1)%sf(k, l, 0))) @@ -231,7 +272,8 @@ contains call s_dirichlet(q_prim_vf, 3, -1, k, l) end select - if (qbmm .and. (.not. polytropic) .and. (bc_type(3, 1)%sf(k, l, 0) <= BC_GHOST_EXTRAP)) then + if (qbmm .and. (.not. polytropic) .and. & + (bc_type(3, 1)%sf(k, l, 0) <= BC_GHOST_EXTRAP)) then call s_qbmm_extrapolation(3, -1, k, l, pb_in, mv_in) end if end do @@ -242,7 +284,7 @@ contains if (bc_z%end >= 0) then call s_mpi_sendrecv_variables_buffers(q_prim_vf, 3, 1, sys_size, pb_in, mv_in) else - $:GPU_PARALLEL_LOOP(private='[l, k]', collapse=2) + $:GPU_PARALLEL_LOOP(private='[l,k]', collapse=2) do l = -buff_size, n + buff_size do k = -buff_size, m + buff_size select case (int(bc_type(3, 2)%sf(k, l, 0))) @@ -260,7 +302,8 @@ contains call s_dirichlet(q_prim_vf, 3, 1, k, l) end select - if (qbmm .and. (.not. polytropic) .and. (bc_type(3, 2)%sf(k, l, 0) <= BC_GHOST_EXTRAP)) then + if (qbmm .and. (.not. polytropic) .and. & + (bc_type(3, 2)%sf(k, l, 0) <= BC_GHOST_EXTRAP)) then call s_qbmm_extrapolation(3, 1, k, l, pb_in, mv_in) end if end do @@ -268,57 +311,65 @@ contains $:END_GPU_PARALLEL_LOOP() end if #:endif + ! END: Population of Buffers in z-direction end subroutine s_populate_variables_buffers - !> Fill ghost cells by copying the nearest boundary cell value along the specified direction. + !> @brief Fills ghost cells by copying the nearest boundary cell value along the specified direction. subroutine s_ghost_cell_extrapolation(q_prim_vf, bc_dir, bc_loc, k, l) - - $:GPU_ROUTINE(function_name='s_ghost_cell_extrapolation', parallelism='[seq]', cray_inline=True) + $:GPU_ROUTINE(function_name='s_ghost_cell_extrapolation', & + & parallelism='[seq]', cray_inline=True) type(scalar_field), dimension(sys_size), intent(inout) :: q_prim_vf - integer, intent(in) :: bc_dir, bc_loc - integer, intent(in) :: k, l - integer :: j, i + integer, intent(in) :: bc_dir, bc_loc + integer, intent(in) :: k, l - if (bc_dir == 1) then !< x-direction - if (bc_loc == -1) then ! bc_x%beg + integer :: j, i + + if (bc_dir == 1) then !< x-direction + if (bc_loc == -1) then !bc_x%beg do i = 1, sys_size do j = 1, buff_size - q_prim_vf(i)%sf(-j, k, l) = q_prim_vf(i)%sf(0, k, l) + q_prim_vf(i)%sf(-j, k, l) = & + q_prim_vf(i)%sf(0, k, l) end do end do - else !< bc_x%end + else !< bc_x%end do i = 1, sys_size do j = 1, buff_size - q_prim_vf(i)%sf(m + j, k, l) = q_prim_vf(i)%sf(m, k, l) + q_prim_vf(i)%sf(m + j, k, l) = & + q_prim_vf(i)%sf(m, k, l) end do end do end if - else if (bc_dir == 2) then !< y-direction - if (bc_loc == -1) then !< bc_y%beg + elseif (bc_dir == 2) then !< y-direction + if (bc_loc == -1) then !< bc_y%beg do i = 1, sys_size do j = 1, buff_size - q_prim_vf(i)%sf(k, -j, l) = q_prim_vf(i)%sf(k, 0, l) + q_prim_vf(i)%sf(k, -j, l) = & + q_prim_vf(i)%sf(k, 0, l) end do end do - else !< bc_y%end + else !< bc_y%end do i = 1, sys_size do j = 1, buff_size - q_prim_vf(i)%sf(k, n + j, l) = q_prim_vf(i)%sf(k, n, l) + q_prim_vf(i)%sf(k, n + j, l) = & + q_prim_vf(i)%sf(k, n, l) end do end do end if - else if (bc_dir == 3) then !< z-direction - if (bc_loc == -1) then !< bc_z%beg + elseif (bc_dir == 3) then !< z-direction + if (bc_loc == -1) then !< bc_z%beg do i = 1, sys_size do j = 1, buff_size - q_prim_vf(i)%sf(k, l, -j) = q_prim_vf(i)%sf(k, l, 0) + q_prim_vf(i)%sf(k, l, -j) = & + q_prim_vf(i)%sf(k, l, 0) end do end do - else !< bc_z%end + else !< bc_z%end do i = 1, sys_size do j = 1, buff_size - q_prim_vf(i)%sf(k, l, p + j) = q_prim_vf(i)%sf(k, l, p) + q_prim_vf(i)%sf(k, l, p + j) = & + q_prim_vf(i)%sf(k, l, p) end do end do end if @@ -326,107 +377,125 @@ contains end subroutine s_ghost_cell_extrapolation - !> Apply reflective (symmetry) boundary conditions by mirroring primitive variables and flipping the normal velocity component. + !> @brief Applies reflective (symmetry) boundary conditions by mirroring primitive variables and flipping the normal velocity component. subroutine s_symmetry(q_prim_vf, bc_dir, bc_loc, k, l, pb_in, mv_in) - $:GPU_ROUTINE(parallelism='[seq]') - type(scalar_field), dimension(sys_size), intent(inout) :: q_prim_vf - real(stp), optional, dimension(idwbuff(1)%beg:,idwbuff(2)%beg:,idwbuff(3)%beg:,1:,1:), intent(inout) :: pb_in, mv_in - integer, intent(in) :: bc_dir, bc_loc - integer, intent(in) :: k, l - integer :: j, q, i - - if (bc_dir == 1) then !< x-direction - if (bc_loc == -1) then !< bc_x%beg + type(scalar_field), dimension(sys_size), intent(inout) :: q_prim_vf + real(stp), optional, dimension(idwbuff(1)%beg:, idwbuff(2)%beg:, idwbuff(3)%beg:, 1:, 1:), intent(inout) :: pb_in, mv_in + integer, intent(in) :: bc_dir, bc_loc + integer, intent(in) :: k, l + + integer :: j, q, i + + if (bc_dir == 1) then !< x-direction + if (bc_loc == -1) then !< bc_x%beg do j = 1, buff_size do i = 1, contxe - q_prim_vf(i)%sf(-j, k, l) = q_prim_vf(i)%sf(j - 1, k, l) + q_prim_vf(i)%sf(-j, k, l) = & + q_prim_vf(i)%sf(j - 1, k, l) end do - q_prim_vf(momxb)%sf(-j, k, l) = -q_prim_vf(momxb)%sf(j - 1, k, l) + q_prim_vf(momxb)%sf(-j, k, l) = & + -q_prim_vf(momxb)%sf(j - 1, k, l) do i = momxb + 1, sys_size - q_prim_vf(i)%sf(-j, k, l) = q_prim_vf(i)%sf(j - 1, k, l) + q_prim_vf(i)%sf(-j, k, l) = & + q_prim_vf(i)%sf(j - 1, k, l) end do if (elasticity) then do i = 1, shear_BC_flip_num - q_prim_vf(shear_BC_flip_indices(1, i))%sf(-j, k, l) = -q_prim_vf(shear_BC_flip_indices(1, & - & i))%sf(j - 1, k, l) + q_prim_vf(shear_BC_flip_indices(1, i))%sf(-j, k, l) = & + -q_prim_vf(shear_BC_flip_indices(1, i))%sf(j - 1, k, l) end do end if if (hyperelasticity) then - q_prim_vf(xibeg)%sf(-j, k, l) = -q_prim_vf(xibeg)%sf(j - 1, k, l) + q_prim_vf(xibeg)%sf(-j, k, l) = & + -q_prim_vf(xibeg)%sf(j - 1, k, l) end if + end do if (qbmm .and. .not. polytropic) then do i = 1, nb do q = 1, nnode do j = 1, buff_size - pb_in(-j, k, l, q, i) = pb_in(j - 1, k, l, q, i) - mv_in(-j, k, l, q, i) = mv_in(j - 1, k, l, q, i) + pb_in(-j, k, l, q, i) = & + pb_in(j - 1, k, l, q, i) + mv_in(-j, k, l, q, i) = & + mv_in(j - 1, k, l, q, i) end do end do end do end if - else !< bc_x%end + else !< bc_x%end do j = 1, buff_size do i = 1, contxe - q_prim_vf(i)%sf(m + j, k, l) = q_prim_vf(i)%sf(m - (j - 1), k, l) + q_prim_vf(i)%sf(m + j, k, l) = & + q_prim_vf(i)%sf(m - (j - 1), k, l) end do - q_prim_vf(momxb)%sf(m + j, k, l) = -q_prim_vf(momxb)%sf(m - (j - 1), k, l) + q_prim_vf(momxb)%sf(m + j, k, l) = & + -q_prim_vf(momxb)%sf(m - (j - 1), k, l) do i = momxb + 1, sys_size - q_prim_vf(i)%sf(m + j, k, l) = q_prim_vf(i)%sf(m - (j - 1), k, l) + q_prim_vf(i)%sf(m + j, k, l) = & + q_prim_vf(i)%sf(m - (j - 1), k, l) end do if (elasticity) then do i = 1, shear_BC_flip_num - q_prim_vf(shear_BC_flip_indices(1, i))%sf(m + j, k, l) = -q_prim_vf(shear_BC_flip_indices(1, & - & i))%sf(m - (j - 1), k, l) + q_prim_vf(shear_BC_flip_indices(1, i))%sf(m + j, k, l) = & + -q_prim_vf(shear_BC_flip_indices(1, i))%sf(m - (j - 1), k, l) end do end if if (hyperelasticity) then - q_prim_vf(xibeg)%sf(m + j, k, l) = -q_prim_vf(xibeg)%sf(m - (j - 1), k, l) + q_prim_vf(xibeg)%sf(m + j, k, l) = & + -q_prim_vf(xibeg)%sf(m - (j - 1), k, l) end if end do if (qbmm .and. .not. polytropic) then + do i = 1, nb do q = 1, nnode do j = 1, buff_size - pb_in(m + j, k, l, q, i) = pb_in(m - (j - 1), k, l, q, i) - mv_in(m + j, k, l, q, i) = mv_in(m - (j - 1), k, l, q, i) + pb_in(m + j, k, l, q, i) = & + pb_in(m - (j - 1), k, l, q, i) + mv_in(m + j, k, l, q, i) = & + mv_in(m - (j - 1), k, l, q, i) end do end do end do end if end if - else if (bc_dir == 2) then !< y-direction - if (bc_loc == -1) then !< bc_y%beg + elseif (bc_dir == 2) then !< y-direction + if (bc_loc == -1) then !< bc_y%beg do j = 1, buff_size do i = 1, momxb - q_prim_vf(i)%sf(k, -j, l) = q_prim_vf(i)%sf(k, j - 1, l) + q_prim_vf(i)%sf(k, -j, l) = & + q_prim_vf(i)%sf(k, j - 1, l) end do - q_prim_vf(momxb + 1)%sf(k, -j, l) = -q_prim_vf(momxb + 1)%sf(k, j - 1, l) + q_prim_vf(momxb + 1)%sf(k, -j, l) = & + -q_prim_vf(momxb + 1)%sf(k, j - 1, l) do i = momxb + 2, sys_size - q_prim_vf(i)%sf(k, -j, l) = q_prim_vf(i)%sf(k, j - 1, l) + q_prim_vf(i)%sf(k, -j, l) = & + q_prim_vf(i)%sf(k, j - 1, l) end do if (elasticity) then do i = 1, shear_BC_flip_num - q_prim_vf(shear_BC_flip_indices(2, i))%sf(k, -j, l) = -q_prim_vf(shear_BC_flip_indices(2, i))%sf(k, & - & j - 1, l) + q_prim_vf(shear_BC_flip_indices(2, i))%sf(k, -j, l) = & + -q_prim_vf(shear_BC_flip_indices(2, i))%sf(k, j - 1, l) end do end if if (hyperelasticity) then - q_prim_vf(xibeg + 1)%sf(k, -j, l) = -q_prim_vf(xibeg + 1)%sf(k, j - 1, l) + q_prim_vf(xibeg + 1)%sf(k, -j, l) = & + -q_prim_vf(xibeg + 1)%sf(k, j - 1, l) end if end do @@ -434,33 +503,39 @@ contains do i = 1, nb do q = 1, nnode do j = 1, buff_size - pb_in(k, -j, l, q, i) = pb_in(k, j - 1, l, q, i) - mv_in(k, -j, l, q, i) = mv_in(k, j - 1, l, q, i) + pb_in(k, -j, l, q, i) = & + pb_in(k, j - 1, l, q, i) + mv_in(k, -j, l, q, i) = & + mv_in(k, j - 1, l, q, i) end do end do end do end if - else !< bc_y%end + else !< bc_y%end do j = 1, buff_size do i = 1, momxb - q_prim_vf(i)%sf(k, n + j, l) = q_prim_vf(i)%sf(k, n - (j - 1), l) + q_prim_vf(i)%sf(k, n + j, l) = & + q_prim_vf(i)%sf(k, n - (j - 1), l) end do - q_prim_vf(momxb + 1)%sf(k, n + j, l) = -q_prim_vf(momxb + 1)%sf(k, n - (j - 1), l) + q_prim_vf(momxb + 1)%sf(k, n + j, l) = & + -q_prim_vf(momxb + 1)%sf(k, n - (j - 1), l) do i = momxb + 2, sys_size - q_prim_vf(i)%sf(k, n + j, l) = q_prim_vf(i)%sf(k, n - (j - 1), l) + q_prim_vf(i)%sf(k, n + j, l) = & + q_prim_vf(i)%sf(k, n - (j - 1), l) end do if (elasticity) then do i = 1, shear_BC_flip_num - q_prim_vf(shear_BC_flip_indices(2, i))%sf(k, n + j, l) = -q_prim_vf(shear_BC_flip_indices(2, & - & i))%sf(k, n - (j - 1), l) + q_prim_vf(shear_BC_flip_indices(2, i))%sf(k, n + j, l) = & + -q_prim_vf(shear_BC_flip_indices(2, i))%sf(k, n - (j - 1), l) end do end if if (hyperelasticity) then - q_prim_vf(xibeg + 1)%sf(k, n + j, l) = -q_prim_vf(xibeg + 1)%sf(k, n - (j - 1), l) + q_prim_vf(xibeg + 1)%sf(k, n + j, l) = & + -q_prim_vf(xibeg + 1)%sf(k, n - (j - 1), l) end if end do @@ -468,35 +543,41 @@ contains do i = 1, nb do q = 1, nnode do j = 1, buff_size - pb_in(k, n + j, l, q, i) = pb_in(k, n - (j - 1), l, q, i) - mv_in(k, n + j, l, q, i) = mv_in(k, n - (j - 1), l, q, i) + pb_in(k, n + j, l, q, i) = & + pb_in(k, n - (j - 1), l, q, i) + mv_in(k, n + j, l, q, i) = & + mv_in(k, n - (j - 1), l, q, i) end do end do end do end if end if - else if (bc_dir == 3) then !< z-direction - if (bc_loc == -1) then !< bc_z%beg + elseif (bc_dir == 3) then !< z-direction + if (bc_loc == -1) then !< bc_z%beg do j = 1, buff_size do i = 1, momxb + 1 - q_prim_vf(i)%sf(k, l, -j) = q_prim_vf(i)%sf(k, l, j - 1) + q_prim_vf(i)%sf(k, l, -j) = & + q_prim_vf(i)%sf(k, l, j - 1) end do - q_prim_vf(momxe)%sf(k, l, -j) = -q_prim_vf(momxe)%sf(k, l, j - 1) + q_prim_vf(momxe)%sf(k, l, -j) = & + -q_prim_vf(momxe)%sf(k, l, j - 1) do i = E_idx, sys_size - q_prim_vf(i)%sf(k, l, -j) = q_prim_vf(i)%sf(k, l, j - 1) + q_prim_vf(i)%sf(k, l, -j) = & + q_prim_vf(i)%sf(k, l, j - 1) end do if (elasticity) then do i = 1, shear_BC_flip_num - q_prim_vf(shear_BC_flip_indices(3, i))%sf(k, l, -j) = -q_prim_vf(shear_BC_flip_indices(3, i))%sf(k, & - & l, j - 1) + q_prim_vf(shear_BC_flip_indices(3, i))%sf(k, l, -j) = & + -q_prim_vf(shear_BC_flip_indices(3, i))%sf(k, l, j - 1) end do end if if (hyperelasticity) then - q_prim_vf(xiend)%sf(k, l, -j) = -q_prim_vf(xiend)%sf(k, l, j - 1) + q_prim_vf(xiend)%sf(k, l, -j) = & + -q_prim_vf(xiend)%sf(k, l, j - 1) end if end do @@ -504,33 +585,39 @@ contains do i = 1, nb do q = 1, nnode do j = 1, buff_size - pb_in(k, l, -j, q, i) = pb_in(k, l, j - 1, q, i) - mv_in(k, l, -j, q, i) = mv_in(k, l, j - 1, q, i) + pb_in(k, l, -j, q, i) = & + pb_in(k, l, j - 1, q, i) + mv_in(k, l, -j, q, i) = & + mv_in(k, l, j - 1, q, i) end do end do end do end if - else !< bc_z%end + else !< bc_z%end do j = 1, buff_size do i = 1, momxb + 1 - q_prim_vf(i)%sf(k, l, p + j) = q_prim_vf(i)%sf(k, l, p - (j - 1)) + q_prim_vf(i)%sf(k, l, p + j) = & + q_prim_vf(i)%sf(k, l, p - (j - 1)) end do - q_prim_vf(momxe)%sf(k, l, p + j) = -q_prim_vf(momxe)%sf(k, l, p - (j - 1)) + q_prim_vf(momxe)%sf(k, l, p + j) = & + -q_prim_vf(momxe)%sf(k, l, p - (j - 1)) do i = E_idx, sys_size - q_prim_vf(i)%sf(k, l, p + j) = q_prim_vf(i)%sf(k, l, p - (j - 1)) + q_prim_vf(i)%sf(k, l, p + j) = & + q_prim_vf(i)%sf(k, l, p - (j - 1)) end do if (elasticity) then do i = 1, shear_BC_flip_num - q_prim_vf(shear_BC_flip_indices(3, i))%sf(k, l, p + j) = -q_prim_vf(shear_BC_flip_indices(3, & - & i))%sf(k, l, p - (j - 1)) + q_prim_vf(shear_BC_flip_indices(3, i))%sf(k, l, p + j) = & + -q_prim_vf(shear_BC_flip_indices(3, i))%sf(k, l, p - (j - 1)) end do end if if (hyperelasticity) then - q_prim_vf(xiend)%sf(k, l, p + j) = -q_prim_vf(xiend)%sf(k, l, p - (j - 1)) + q_prim_vf(xiend)%sf(k, l, p + j) = & + -q_prim_vf(xiend)%sf(k, l, p - (j - 1)) end if end do @@ -538,8 +625,10 @@ contains do i = 1, nb do q = 1, nnode do j = 1, buff_size - pb_in(k, l, p + j, q, i) = pb_in(k, l, p - (j - 1), q, i) - mv_in(k, l, p + j, q, i) = mv_in(k, l, p - (j - 1), q, i) + pb_in(k, l, p + j, q, i) = & + pb_in(k, l, p - (j - 1), q, i) + mv_in(k, l, p + j, q, i) = & + mv_in(k, l, p - (j - 1), q, i) end do end do end do @@ -549,21 +638,22 @@ contains end subroutine s_symmetry - !> Apply periodic boundary conditions by copying values from the opposite domain boundary. + !> @brief Applies periodic boundary conditions by copying values from the opposite domain boundary. subroutine s_periodic(q_prim_vf, bc_dir, bc_loc, k, l, pb_in, mv_in) - $:GPU_ROUTINE(parallelism='[seq]') - type(scalar_field), dimension(sys_size), intent(inout) :: q_prim_vf - real(stp), optional, dimension(idwbuff(1)%beg:,idwbuff(2)%beg:,idwbuff(3)%beg:,1:,1:), intent(inout) :: pb_in, mv_in - integer, intent(in) :: bc_dir, bc_loc - integer, intent(in) :: k, l - integer :: j, q, i - - if (bc_dir == 1) then !< x-direction - if (bc_loc == -1) then !< bc_x%beg + type(scalar_field), dimension(sys_size), intent(inout) :: q_prim_vf + real(stp), optional, dimension(idwbuff(1)%beg:, idwbuff(2)%beg:, idwbuff(3)%beg:, 1:, 1:), intent(inout) :: pb_in, mv_in + integer, intent(in) :: bc_dir, bc_loc + integer, intent(in) :: k, l + + integer :: j, q, i + + if (bc_dir == 1) then !< x-direction + if (bc_loc == -1) then !< bc_x%beg do i = 1, sys_size do j = 1, buff_size - q_prim_vf(i)%sf(-j, k, l) = q_prim_vf(i)%sf(m - (j - 1), k, l) + q_prim_vf(i)%sf(-j, k, l) = & + q_prim_vf(i)%sf(m - (j - 1), k, l) end do end do @@ -571,16 +661,19 @@ contains do i = 1, nb do q = 1, nnode do j = 1, buff_size - pb_in(-j, k, l, q, i) = pb_in(m - (j - 1), k, l, q, i) - mv_in(-j, k, l, q, i) = mv_in(m - (j - 1), k, l, q, i) + pb_in(-j, k, l, q, i) = & + pb_in(m - (j - 1), k, l, q, i) + mv_in(-j, k, l, q, i) = & + mv_in(m - (j - 1), k, l, q, i) end do end do end do end if - else !< bc_x%end + else !< bc_x%end do i = 1, sys_size do j = 1, buff_size - q_prim_vf(i)%sf(m + j, k, l) = q_prim_vf(i)%sf(j - 1, k, l) + q_prim_vf(i)%sf(m + j, k, l) = & + q_prim_vf(i)%sf(j - 1, k, l) end do end do @@ -588,18 +681,21 @@ contains do i = 1, nb do q = 1, nnode do j = 1, buff_size - pb_in(m + j, k, l, q, i) = pb_in(j - 1, k, l, q, i) - mv_in(m + j, k, l, q, i) = mv_in(j - 1, k, l, q, i) + pb_in(m + j, k, l, q, i) = & + pb_in(j - 1, k, l, q, i) + mv_in(m + j, k, l, q, i) = & + mv_in(j - 1, k, l, q, i) end do end do end do end if end if - else if (bc_dir == 2) then !< y-direction - if (bc_loc == -1) then !< bc_y%beg + elseif (bc_dir == 2) then !< y-direction + if (bc_loc == -1) then !< bc_y%beg do i = 1, sys_size do j = 1, buff_size - q_prim_vf(i)%sf(k, -j, l) = q_prim_vf(i)%sf(k, n - (j - 1), l) + q_prim_vf(i)%sf(k, -j, l) = & + q_prim_vf(i)%sf(k, n - (j - 1), l) end do end do @@ -607,16 +703,19 @@ contains do i = 1, nb do q = 1, nnode do j = 1, buff_size - pb_in(k, -j, l, q, i) = pb_in(k, n - (j - 1), l, q, i) - mv_in(k, -j, l, q, i) = mv_in(k, n - (j - 1), l, q, i) + pb_in(k, -j, l, q, i) = & + pb_in(k, n - (j - 1), l, q, i) + mv_in(k, -j, l, q, i) = & + mv_in(k, n - (j - 1), l, q, i) end do end do end do end if - else !< bc_y%end + else !< bc_y%end do i = 1, sys_size do j = 1, buff_size - q_prim_vf(i)%sf(k, n + j, l) = q_prim_vf(i)%sf(k, j - 1, l) + q_prim_vf(i)%sf(k, n + j, l) = & + q_prim_vf(i)%sf(k, j - 1, l) end do end do @@ -624,18 +723,21 @@ contains do i = 1, nb do q = 1, nnode do j = 1, buff_size - pb_in(k, n + j, l, q, i) = pb_in(k, (j - 1), l, q, i) - mv_in(k, n + j, l, q, i) = mv_in(k, (j - 1), l, q, i) + pb_in(k, n + j, l, q, i) = & + pb_in(k, (j - 1), l, q, i) + mv_in(k, n + j, l, q, i) = & + mv_in(k, (j - 1), l, q, i) end do end do end do end if end if - else if (bc_dir == 3) then !< z-direction - if (bc_loc == -1) then !< bc_z%beg + elseif (bc_dir == 3) then !< z-direction + if (bc_loc == -1) then !< bc_z%beg do i = 1, sys_size do j = 1, buff_size - q_prim_vf(i)%sf(k, l, -j) = q_prim_vf(i)%sf(k, l, p - (j - 1)) + q_prim_vf(i)%sf(k, l, -j) = & + q_prim_vf(i)%sf(k, l, p - (j - 1)) end do end do @@ -643,16 +745,19 @@ contains do i = 1, nb do q = 1, nnode do j = 1, buff_size - pb_in(k, l, -j, q, i) = pb_in(k, l, p - (j - 1), q, i) - mv_in(k, l, -j, q, i) = mv_in(k, l, p - (j - 1), q, i) + pb_in(k, l, -j, q, i) = & + pb_in(k, l, p - (j - 1), q, i) + mv_in(k, l, -j, q, i) = & + mv_in(k, l, p - (j - 1), q, i) end do end do end do end if - else !< bc_z%end + else !< bc_z%end do i = 1, sys_size do j = 1, buff_size - q_prim_vf(i)%sf(k, l, p + j) = q_prim_vf(i)%sf(k, l, j - 1) + q_prim_vf(i)%sf(k, l, p + j) = & + q_prim_vf(i)%sf(k, l, j - 1) end do end do @@ -660,8 +765,10 @@ contains do i = 1, nb do q = 1, nnode do j = 1, buff_size - pb_in(k, l, p + j, q, i) = pb_in(k, l, j - 1, q, i) - mv_in(k, l, p + j, q, i) = mv_in(k, l, j - 1, q, i) + pb_in(k, l, p + j, q, i) = & + pb_in(k, l, j - 1, q, i) + mv_in(k, l, p + j, q, i) = & + mv_in(k, l, j - 1, q, i) end do end do end do @@ -671,39 +778,47 @@ contains end subroutine s_periodic - !> Apply axis boundary conditions for cylindrical coordinates by reflecting values across the axis with azimuthal phase shift. + !> @brief Applies axis boundary conditions for cylindrical coordinates by reflecting values across the axis with azimuthal phase shift. subroutine s_axis(q_prim_vf, pb_in, mv_in, k, l) - $:GPU_ROUTINE(parallelism='[seq]') - type(scalar_field), dimension(sys_size), intent(inout) :: q_prim_vf - real(stp), dimension(idwbuff(1)%beg:,idwbuff(2)%beg:,idwbuff(3)%beg:,1:,1:), intent(inout) :: pb_in, mv_in - integer, intent(in) :: k, l - integer :: j, q, i + type(scalar_field), dimension(sys_size), intent(inout) :: q_prim_vf + real(stp), dimension(idwbuff(1)%beg:, idwbuff(2)%beg:, idwbuff(3)%beg:, 1:, 1:), intent(inout) :: pb_in, mv_in + integer, intent(in) :: k, l + + integer :: j, q, i do j = 1, buff_size if (z_cc(l) < pi) then do i = 1, momxb - q_prim_vf(i)%sf(k, -j, l) = q_prim_vf(i)%sf(k, j - 1, l + ((p + 1)/2)) + q_prim_vf(i)%sf(k, -j, l) = & + q_prim_vf(i)%sf(k, j - 1, l + ((p + 1)/2)) end do - q_prim_vf(momxb + 1)%sf(k, -j, l) = -q_prim_vf(momxb + 1)%sf(k, j - 1, l + ((p + 1)/2)) + q_prim_vf(momxb + 1)%sf(k, -j, l) = & + -q_prim_vf(momxb + 1)%sf(k, j - 1, l + ((p + 1)/2)) - q_prim_vf(momxe)%sf(k, -j, l) = -q_prim_vf(momxe)%sf(k, j - 1, l + ((p + 1)/2)) + q_prim_vf(momxe)%sf(k, -j, l) = & + -q_prim_vf(momxe)%sf(k, j - 1, l + ((p + 1)/2)) do i = E_idx, sys_size - q_prim_vf(i)%sf(k, -j, l) = q_prim_vf(i)%sf(k, j - 1, l + ((p + 1)/2)) + q_prim_vf(i)%sf(k, -j, l) = & + q_prim_vf(i)%sf(k, j - 1, l + ((p + 1)/2)) end do else do i = 1, momxb - q_prim_vf(i)%sf(k, -j, l) = q_prim_vf(i)%sf(k, j - 1, l - ((p + 1)/2)) + q_prim_vf(i)%sf(k, -j, l) = & + q_prim_vf(i)%sf(k, j - 1, l - ((p + 1)/2)) end do - q_prim_vf(momxb + 1)%sf(k, -j, l) = -q_prim_vf(momxb + 1)%sf(k, j - 1, l - ((p + 1)/2)) + q_prim_vf(momxb + 1)%sf(k, -j, l) = & + -q_prim_vf(momxb + 1)%sf(k, j - 1, l - ((p + 1)/2)) - q_prim_vf(momxe)%sf(k, -j, l) = -q_prim_vf(momxe)%sf(k, j - 1, l - ((p + 1)/2)) + q_prim_vf(momxe)%sf(k, -j, l) = & + -q_prim_vf(momxe)%sf(k, j - 1, l - ((p + 1)/2)) do i = E_idx, sys_size - q_prim_vf(i)%sf(k, -j, l) = q_prim_vf(i)%sf(k, j - 1, l - ((p + 1)/2)) + q_prim_vf(i)%sf(k, -j, l) = & + q_prim_vf(i)%sf(k, j - 1, l - ((p + 1)/2)) end do end if end do @@ -712,8 +827,10 @@ contains do i = 1, nb do q = 1, nnode do j = 1, buff_size - pb_in(k, -j, l, q, i) = pb_in(k, j - 1, l - ((p + 1)/2), q, i) - mv_in(k, -j, l, q, i) = mv_in(k, j - 1, l - ((p + 1)/2), q, i) + pb_in(k, -j, l, q, i) = & + pb_in(k, j - 1, l - ((p + 1)/2), q, i) + mv_in(k, -j, l, q, i) = & + mv_in(k, j - 1, l - ((p + 1)/2), q, i) end do end do end do @@ -721,77 +838,90 @@ contains end subroutine s_axis - !> Apply slip wall boundary conditions by extrapolating scalars and reflecting the wall-normal velocity component. + !> @brief Applies slip wall boundary conditions by extrapolating scalars and reflecting the wall-normal velocity component. subroutine s_slip_wall(q_prim_vf, bc_dir, bc_loc, k, l) - - $:GPU_ROUTINE(function_name='s_slip_wall',parallelism='[seq]', cray_inline=True) + $:GPU_ROUTINE(function_name='s_slip_wall',parallelism='[seq]', & + & cray_inline=True) type(scalar_field), dimension(sys_size), intent(inout) :: q_prim_vf - integer, intent(in) :: bc_dir, bc_loc - integer, intent(in) :: k, l - integer :: j, i + integer, intent(in) :: bc_dir, bc_loc + integer, intent(in) :: k, l + + integer :: j, i - if (bc_dir == 1) then !< x-direction - if (bc_loc == -1) then !< bc_x%beg + if (bc_dir == 1) then !< x-direction + if (bc_loc == -1) then !< bc_x%beg do i = 1, sys_size do j = 1, buff_size if (i == momxb) then - q_prim_vf(i)%sf(-j, k, l) = -q_prim_vf(i)%sf(j - 1, k, l) + 2._wp*bc_x%vb1 + q_prim_vf(i)%sf(-j, k, l) = & + -q_prim_vf(i)%sf(j - 1, k, l) + 2._wp*bc_x%vb1 else - q_prim_vf(i)%sf(-j, k, l) = q_prim_vf(i)%sf(0, k, l) + q_prim_vf(i)%sf(-j, k, l) = & + q_prim_vf(i)%sf(0, k, l) end if end do end do - else !< bc_x%end + else !< bc_x%end do i = 1, sys_size do j = 1, buff_size if (i == momxb) then - q_prim_vf(i)%sf(m + j, k, l) = -q_prim_vf(i)%sf(m - (j - 1), k, l) + 2._wp*bc_x%ve1 + q_prim_vf(i)%sf(m + j, k, l) = & + -q_prim_vf(i)%sf(m - (j - 1), k, l) + 2._wp*bc_x%ve1 else - q_prim_vf(i)%sf(m + j, k, l) = q_prim_vf(i)%sf(m, k, l) + q_prim_vf(i)%sf(m + j, k, l) = & + q_prim_vf(i)%sf(m, k, l) end if end do end do end if - else if (bc_dir == 2) then !< y-direction - if (bc_loc == -1) then !< bc_y%beg + elseif (bc_dir == 2) then !< y-direction + if (bc_loc == -1) then !< bc_y%beg do i = 1, sys_size do j = 1, buff_size if (i == momxb + 1) then - q_prim_vf(i)%sf(k, -j, l) = -q_prim_vf(i)%sf(k, j - 1, l) + 2._wp*bc_y%vb2 + q_prim_vf(i)%sf(k, -j, l) = & + -q_prim_vf(i)%sf(k, j - 1, l) + 2._wp*bc_y%vb2 else - q_prim_vf(i)%sf(k, -j, l) = q_prim_vf(i)%sf(k, 0, l) + q_prim_vf(i)%sf(k, -j, l) = & + q_prim_vf(i)%sf(k, 0, l) end if end do end do - else !< bc_y%end + else !< bc_y%end do i = 1, sys_size do j = 1, buff_size if (i == momxb + 1) then - q_prim_vf(i)%sf(k, n + j, l) = -q_prim_vf(i)%sf(k, n - (j - 1), l) + 2._wp*bc_y%ve2 + q_prim_vf(i)%sf(k, n + j, l) = & + -q_prim_vf(i)%sf(k, n - (j - 1), l) + 2._wp*bc_y%ve2 else - q_prim_vf(i)%sf(k, n + j, l) = q_prim_vf(i)%sf(k, n, l) + q_prim_vf(i)%sf(k, n + j, l) = & + q_prim_vf(i)%sf(k, n, l) end if end do end do end if - else if (bc_dir == 3) then !< z-direction - if (bc_loc == -1) then !< bc_z%beg + elseif (bc_dir == 3) then !< z-direction + if (bc_loc == -1) then !< bc_z%beg do i = 1, sys_size do j = 1, buff_size if (i == momxe) then - q_prim_vf(i)%sf(k, l, -j) = -q_prim_vf(i)%sf(k, l, j - 1) + 2._wp*bc_z%vb3 + q_prim_vf(i)%sf(k, l, -j) = & + -q_prim_vf(i)%sf(k, l, j - 1) + 2._wp*bc_z%vb3 else - q_prim_vf(i)%sf(k, l, -j) = q_prim_vf(i)%sf(k, l, 0) + q_prim_vf(i)%sf(k, l, -j) = & + q_prim_vf(i)%sf(k, l, 0) end if end do end do - else !< bc_z%end + else !< bc_z%end do i = 1, sys_size do j = 1, buff_size if (i == momxe) then - q_prim_vf(i)%sf(k, l, p + j) = -q_prim_vf(i)%sf(k, l, p - (j - 1)) + 2._wp*bc_z%ve3 + q_prim_vf(i)%sf(k, l, p + j) = & + -q_prim_vf(i)%sf(k, l, p - (j - 1)) + 2._wp*bc_z%ve3 else - q_prim_vf(i)%sf(k, l, p + j) = q_prim_vf(i)%sf(k, l, p) + q_prim_vf(i)%sf(k, l, p + j) = & + q_prim_vf(i)%sf(k, l, p) end if end do end do @@ -800,102 +930,127 @@ contains end subroutine s_slip_wall - !> Apply no-slip wall boundary conditions by reflecting and negating all velocity components at the wall. + !> @brief Applies no-slip wall boundary conditions by reflecting and negating all velocity components at the wall. subroutine s_no_slip_wall(q_prim_vf, bc_dir, bc_loc, k, l) - - $:GPU_ROUTINE(function_name='s_no_slip_wall',parallelism='[seq]', cray_inline=True) + $:GPU_ROUTINE(function_name='s_no_slip_wall',parallelism='[seq]', & + & cray_inline=True) type(scalar_field), dimension(sys_size), intent(inout) :: q_prim_vf - integer, intent(in) :: bc_dir, bc_loc - integer, intent(in) :: k, l - integer :: j, i + integer, intent(in) :: bc_dir, bc_loc + integer, intent(in) :: k, l + + integer :: j, i - if (bc_dir == 1) then !< x-direction - if (bc_loc == -1) then !< bc_x%beg + if (bc_dir == 1) then !< x-direction + if (bc_loc == -1) then !< bc_x%beg do i = 1, sys_size do j = 1, buff_size if (i == momxb) then - q_prim_vf(i)%sf(-j, k, l) = -q_prim_vf(i)%sf(j - 1, k, l) + 2._wp*bc_x%vb1 - else if (i == momxb + 1 .and. num_dims > 1) then - q_prim_vf(i)%sf(-j, k, l) = -q_prim_vf(i)%sf(j - 1, k, l) + 2._wp*bc_x%vb2 - else if (i == momxb + 2 .and. num_dims > 2) then - q_prim_vf(i)%sf(-j, k, l) = -q_prim_vf(i)%sf(j - 1, k, l) + 2._wp*bc_x%vb3 + q_prim_vf(i)%sf(-j, k, l) = & + -q_prim_vf(i)%sf(j - 1, k, l) + 2._wp*bc_x%vb1 + elseif (i == momxb + 1 .and. num_dims > 1) then + q_prim_vf(i)%sf(-j, k, l) = & + -q_prim_vf(i)%sf(j - 1, k, l) + 2._wp*bc_x%vb2 + elseif (i == momxb + 2 .and. num_dims > 2) then + q_prim_vf(i)%sf(-j, k, l) = & + -q_prim_vf(i)%sf(j - 1, k, l) + 2._wp*bc_x%vb3 else - q_prim_vf(i)%sf(-j, k, l) = q_prim_vf(i)%sf(0, k, l) + q_prim_vf(i)%sf(-j, k, l) = & + q_prim_vf(i)%sf(0, k, l) end if end do end do - else !< bc_x%end + else !< bc_x%end do i = 1, sys_size do j = 1, buff_size if (i == momxb) then - q_prim_vf(i)%sf(m + j, k, l) = -q_prim_vf(i)%sf(m - (j - 1), k, l) + 2._wp*bc_x%ve1 - else if (i == momxb + 1 .and. num_dims > 1) then - q_prim_vf(i)%sf(m + j, k, l) = -q_prim_vf(i)%sf(m - (j - 1), k, l) + 2._wp*bc_x%ve2 - else if (i == momxb + 2 .and. num_dims > 2) then - q_prim_vf(i)%sf(m + j, k, l) = -q_prim_vf(i)%sf(m - (j - 1), k, l) + 2._wp*bc_x%ve3 + q_prim_vf(i)%sf(m + j, k, l) = & + -q_prim_vf(i)%sf(m - (j - 1), k, l) + 2._wp*bc_x%ve1 + elseif (i == momxb + 1 .and. num_dims > 1) then + q_prim_vf(i)%sf(m + j, k, l) = & + -q_prim_vf(i)%sf(m - (j - 1), k, l) + 2._wp*bc_x%ve2 + elseif (i == momxb + 2 .and. num_dims > 2) then + q_prim_vf(i)%sf(m + j, k, l) = & + -q_prim_vf(i)%sf(m - (j - 1), k, l) + 2._wp*bc_x%ve3 else - q_prim_vf(i)%sf(m + j, k, l) = q_prim_vf(i)%sf(m, k, l) + q_prim_vf(i)%sf(m + j, k, l) = & + q_prim_vf(i)%sf(m, k, l) end if end do end do end if - else if (bc_dir == 2) then !< y-direction - if (bc_loc == -1) then !< bc_y%beg + elseif (bc_dir == 2) then !< y-direction + if (bc_loc == -1) then !< bc_y%beg do i = 1, sys_size do j = 1, buff_size if (i == momxb) then - q_prim_vf(i)%sf(k, -j, l) = -q_prim_vf(i)%sf(k, j - 1, l) + 2._wp*bc_y%vb1 - else if (i == momxb + 1 .and. num_dims > 1) then - q_prim_vf(i)%sf(k, -j, l) = -q_prim_vf(i)%sf(k, j - 1, l) + 2._wp*bc_y%vb2 - else if (i == momxb + 2 .and. num_dims > 2) then - q_prim_vf(i)%sf(k, -j, l) = -q_prim_vf(i)%sf(k, j - 1, l) + 2._wp*bc_y%vb3 + q_prim_vf(i)%sf(k, -j, l) = & + -q_prim_vf(i)%sf(k, j - 1, l) + 2._wp*bc_y%vb1 + elseif (i == momxb + 1 .and. num_dims > 1) then + q_prim_vf(i)%sf(k, -j, l) = & + -q_prim_vf(i)%sf(k, j - 1, l) + 2._wp*bc_y%vb2 + elseif (i == momxb + 2 .and. num_dims > 2) then + q_prim_vf(i)%sf(k, -j, l) = & + -q_prim_vf(i)%sf(k, j - 1, l) + 2._wp*bc_y%vb3 else - q_prim_vf(i)%sf(k, -j, l) = q_prim_vf(i)%sf(k, 0, l) + q_prim_vf(i)%sf(k, -j, l) = & + q_prim_vf(i)%sf(k, 0, l) end if end do end do - else !< bc_y%end + else !< bc_y%end do i = 1, sys_size do j = 1, buff_size if (i == momxb) then - q_prim_vf(i)%sf(k, n + j, l) = -q_prim_vf(i)%sf(k, n - (j - 1), l) + 2._wp*bc_y%ve1 - else if (i == momxb + 1 .and. num_dims > 1) then - q_prim_vf(i)%sf(k, n + j, l) = -q_prim_vf(i)%sf(k, n - (j - 1), l) + 2._wp*bc_y%ve2 - else if (i == momxb + 2 .and. num_dims > 2) then - q_prim_vf(i)%sf(k, n + j, l) = -q_prim_vf(i)%sf(k, n - (j - 1), l) + 2._wp*bc_y%ve3 + q_prim_vf(i)%sf(k, n + j, l) = & + -q_prim_vf(i)%sf(k, n - (j - 1), l) + 2._wp*bc_y%ve1 + elseif (i == momxb + 1 .and. num_dims > 1) then + q_prim_vf(i)%sf(k, n + j, l) = & + -q_prim_vf(i)%sf(k, n - (j - 1), l) + 2._wp*bc_y%ve2 + elseif (i == momxb + 2 .and. num_dims > 2) then + q_prim_vf(i)%sf(k, n + j, l) = & + -q_prim_vf(i)%sf(k, n - (j - 1), l) + 2._wp*bc_y%ve3 else - q_prim_vf(i)%sf(k, n + j, l) = q_prim_vf(i)%sf(k, n, l) + q_prim_vf(i)%sf(k, n + j, l) = & + q_prim_vf(i)%sf(k, n, l) end if end do end do end if - else if (bc_dir == 3) then !< z-direction - if (bc_loc == -1) then !< bc_z%beg + elseif (bc_dir == 3) then !< z-direction + if (bc_loc == -1) then !< bc_z%beg do i = 1, sys_size do j = 1, buff_size if (i == momxb) then - q_prim_vf(i)%sf(k, l, -j) = -q_prim_vf(i)%sf(k, l, j - 1) + 2._wp*bc_z%vb1 - else if (i == momxb + 1 .and. num_dims > 1) then - q_prim_vf(i)%sf(k, l, -j) = -q_prim_vf(i)%sf(k, l, j - 1) + 2._wp*bc_z%vb2 - else if (i == momxb + 2 .and. num_dims > 2) then - q_prim_vf(i)%sf(k, l, -j) = -q_prim_vf(i)%sf(k, l, j - 1) + 2._wp*bc_z%vb3 + q_prim_vf(i)%sf(k, l, -j) = & + -q_prim_vf(i)%sf(k, l, j - 1) + 2._wp*bc_z%vb1 + elseif (i == momxb + 1 .and. num_dims > 1) then + q_prim_vf(i)%sf(k, l, -j) = & + -q_prim_vf(i)%sf(k, l, j - 1) + 2._wp*bc_z%vb2 + elseif (i == momxb + 2 .and. num_dims > 2) then + q_prim_vf(i)%sf(k, l, -j) = & + -q_prim_vf(i)%sf(k, l, j - 1) + 2._wp*bc_z%vb3 else - q_prim_vf(i)%sf(k, l, -j) = q_prim_vf(i)%sf(k, l, 0) + q_prim_vf(i)%sf(k, l, -j) = & + q_prim_vf(i)%sf(k, l, 0) end if end do end do - else !< bc_z%end + else !< bc_z%end do i = 1, sys_size do j = 1, buff_size if (i == momxb) then - q_prim_vf(i)%sf(k, l, p + j) = -q_prim_vf(i)%sf(k, l, p - (j - 1)) + 2._wp*bc_z%ve1 - else if (i == momxb + 1 .and. num_dims > 1) then - q_prim_vf(i)%sf(k, l, p + j) = -q_prim_vf(i)%sf(k, l, p - (j - 1)) + 2._wp*bc_z%ve2 - else if (i == momxb + 2 .and. num_dims > 2) then - q_prim_vf(i)%sf(k, l, p + j) = -q_prim_vf(i)%sf(k, l, p - (j - 1)) + 2._wp*bc_z%ve3 + q_prim_vf(i)%sf(k, l, p + j) = & + -q_prim_vf(i)%sf(k, l, p - (j - 1)) + 2._wp*bc_z%ve1 + elseif (i == momxb + 1 .and. num_dims > 1) then + q_prim_vf(i)%sf(k, l, p + j) = & + -q_prim_vf(i)%sf(k, l, p - (j - 1)) + 2._wp*bc_z%ve2 + elseif (i == momxb + 2 .and. num_dims > 2) then + q_prim_vf(i)%sf(k, l, p + j) = & + -q_prim_vf(i)%sf(k, l, p - (j - 1)) + 2._wp*bc_z%ve3 else - q_prim_vf(i)%sf(k, l, p + j) = q_prim_vf(i)%sf(k, l, p) + q_prim_vf(i)%sf(k, l, p + j) = & + q_prim_vf(i)%sf(k, l, p) end if end do end do @@ -904,58 +1059,65 @@ contains end subroutine s_no_slip_wall - !> Apply Dirichlet boundary conditions by prescribing ghost cell values from stored boundary buffers. + !> @brief Applies Dirichlet boundary conditions by prescribing ghost cell values from stored boundary buffers. subroutine s_dirichlet(q_prim_vf, bc_dir, bc_loc, k, l) - - $:GPU_ROUTINE(function_name='s_dirichlet',parallelism='[seq]', cray_inline=True) + $:GPU_ROUTINE(function_name='s_dirichlet',parallelism='[seq]', & + & cray_inline=True) type(scalar_field), dimension(sys_size), intent(inout) :: q_prim_vf - integer, intent(in) :: bc_dir, bc_loc - integer, intent(in) :: k, l - integer :: j, i + integer, intent(in) :: bc_dir, bc_loc + integer, intent(in) :: k, l + + integer :: j, i #ifdef MFC_SIMULATION - if (bc_dir == 1) then !< x-direction - if (bc_loc == -1) then ! bc_x%beg + if (bc_dir == 1) then !< x-direction + if (bc_loc == -1) then !bc_x%beg do i = 1, sys_size do j = 1, buff_size - q_prim_vf(i)%sf(-j, k, l) = bc_buffers(1, 1)%sf(i, k, l) + q_prim_vf(i)%sf(-j, k, l) = & + bc_buffers(1, 1)%sf(i, k, l) end do end do - else !< bc_x%end + else !< bc_x%end do i = 1, sys_size do j = 1, buff_size - q_prim_vf(i)%sf(m + j, k, l) = bc_buffers(1, 2)%sf(i, k, l) + q_prim_vf(i)%sf(m + j, k, l) = & + bc_buffers(1, 2)%sf(i, k, l) end do end do end if - else if (bc_dir == 2) then !< y-direction + elseif (bc_dir == 2) then !< y-direction #:if not MFC_CASE_OPTIMIZATION or num_dims > 1 - if (bc_loc == -1) then !< bc_y%beg + if (bc_loc == -1) then !< bc_y%beg do i = 1, sys_size do j = 1, buff_size - q_prim_vf(i)%sf(k, -j, l) = bc_buffers(2, 1)%sf(k, i, l) + q_prim_vf(i)%sf(k, -j, l) = & + bc_buffers(2, 1)%sf(k, i, l) end do end do - else !< bc_y%end + else !< bc_y%end do i = 1, sys_size do j = 1, buff_size - q_prim_vf(i)%sf(k, n + j, l) = bc_buffers(2, 2)%sf(k, i, l) + q_prim_vf(i)%sf(k, n + j, l) = & + bc_buffers(2, 2)%sf(k, i, l) end do end do end if #:endif - else if (bc_dir == 3) then !< z-direction + elseif (bc_dir == 3) then !< z-direction #:if not MFC_CASE_OPTIMIZATION or num_dims > 2 - if (bc_loc == -1) then !< bc_z%beg + if (bc_loc == -1) then !< bc_z%beg do i = 1, sys_size do j = 1, buff_size - q_prim_vf(i)%sf(k, l, -j) = bc_buffers(3, 1)%sf(k, l, i) + q_prim_vf(i)%sf(k, l, -j) = & + bc_buffers(3, 1)%sf(k, l, i) end do end do - else !< bc_z%end + else !< bc_z%end do i = 1, sys_size do j = 1, buff_size - q_prim_vf(i)%sf(k, l, p + j) = bc_buffers(3, 2)%sf(k, l, i) + q_prim_vf(i)%sf(k, l, p + j) = & + bc_buffers(3, 2)%sf(k, l, i) end do end do end if @@ -967,17 +1129,17 @@ contains end subroutine s_dirichlet - !> Extrapolate QBMM bubble pressure and mass-vapor variables into ghost cells by copying boundary values. + !> @brief Extrapolates QBMM bubble pressure and mass-vapor variables into ghost cells by copying boundary values. subroutine s_qbmm_extrapolation(bc_dir, bc_loc, k, l, pb_in, mv_in) - $:GPU_ROUTINE(parallelism='[seq]') - real(stp), optional, dimension(idwbuff(1)%beg:,idwbuff(2)%beg:,idwbuff(3)%beg:,1:,1:), intent(inout) :: pb_in, mv_in - integer, intent(in) :: bc_dir, bc_loc - integer, intent(in) :: k, l - integer :: j, q, i + real(stp), optional, dimension(idwbuff(1)%beg:, idwbuff(2)%beg:, idwbuff(3)%beg:, 1:, 1:), intent(inout) :: pb_in, mv_in + integer, intent(in) :: bc_dir, bc_loc + integer, intent(in) :: k, l + + integer :: j, q, i - if (bc_dir == 1) then !< x-direction - if (bc_loc == -1) then ! bc_x%beg + if (bc_dir == 1) then !< x-direction + if (bc_loc == -1) then !bc_x%beg do i = 1, nb do q = 1, nnode do j = 1, buff_size @@ -986,7 +1148,7 @@ contains end do end do end do - else !< bc_x%end + else !< bc_x%end do i = 1, nb do q = 1, nnode do j = 1, buff_size @@ -996,8 +1158,8 @@ contains end do end do end if - else if (bc_dir == 2) then !< y-direction - if (bc_loc == -1) then !< bc_y%beg + elseif (bc_dir == 2) then !< y-direction + if (bc_loc == -1) then !< bc_y%beg do i = 1, nb do q = 1, nnode do j = 1, buff_size @@ -1006,7 +1168,7 @@ contains end do end do end do - else !< bc_y%end + else !< bc_y%end do i = 1, nb do q = 1, nnode do j = 1, buff_size @@ -1016,8 +1178,8 @@ contains end do end do end if - else if (bc_dir == 3) then !< z-direction - if (bc_loc == -1) then !< bc_z%beg + elseif (bc_dir == 3) then !< z-direction + if (bc_loc == -1) then !< bc_z%beg do i = 1, nb do q = 1, nnode do j = 1, buff_size @@ -1026,7 +1188,7 @@ contains end do end do end do - else !< bc_z%end + else !< bc_z%end do i = 1, nb do q = 1, nnode do j = 1, buff_size @@ -1040,19 +1202,411 @@ contains end subroutine s_qbmm_extrapolation - !> Populate ghost cell buffers for the color function and its divergence used in capillary surface tension. + impure subroutine s_populate_beta_buffers(q_beta, kahan_comp, bc_type, nvar) + + type(scalar_field), dimension(:), intent(inout) :: q_beta + type(scalar_field), dimension(:), intent(inout) :: kahan_comp + type(integer_field), dimension(1:num_dims, 1:2), intent(in) :: bc_type + integer, intent(in) :: nvar + + integer :: k, l + + !< x-direction + if (bc_x%beg < 0) then + $:GPU_PARALLEL_LOOP(private='[l,k]', collapse=2) + do l = beta_bc_bounds(3)%beg, beta_bc_bounds(3)%end + do k = beta_bc_bounds(2)%beg, beta_bc_bounds(2)%end + select case (bc_x%beg) + case (BC_PERIODIC) + call s_beta_periodic(q_beta, kahan_comp, 1, -1, k, l, nvar) + case (BC_REFLECTIVE) + call s_beta_reflective(q_beta, kahan_comp, 1, -1, k, l, nvar) + case default + end select + end do + end do + $:END_GPU_PARALLEL_LOOP() + end if + if (bc_x%beg >= 0 .or. bc_x%end >= 0) then + call s_mpi_reduce_beta_variables_buffers(q_beta, kahan_comp, 1, -1, nvar) + end if + + if (bc_x%end < 0) then + $:GPU_PARALLEL_LOOP(private='[l,k]', collapse=2) + do l = beta_bc_bounds(3)%beg, beta_bc_bounds(3)%end + do k = beta_bc_bounds(2)%beg, beta_bc_bounds(2)%end + select case (bc_x%end) + case (BC_PERIODIC) + call s_beta_periodic(q_beta, kahan_comp, 1, 1, k, l, nvar) + case (BC_REFLECTIVE) + call s_beta_reflective(q_beta, kahan_comp, 1, 1, k, l, nvar) + case default + end select + end do + end do + $:END_GPU_PARALLEL_LOOP() + end if + if (bc_x%beg >= 0 .or. bc_x%end >= 0) then + call s_mpi_reduce_beta_variables_buffers(q_beta, kahan_comp, 1, 1, nvar) + end if + + !< y-direction + if (bc_y%beg < 0) then + $:GPU_PARALLEL_LOOP(private='[l,k]', collapse=2) + do l = beta_bc_bounds(3)%beg, beta_bc_bounds(3)%end + do k = beta_bc_bounds(1)%beg, beta_bc_bounds(1)%end + select case (bc_y%beg) + case (BC_PERIODIC) + call s_beta_periodic(q_beta, kahan_comp, 2, -1, k, l, nvar) + case (BC_REFLECTIVE) + call s_beta_reflective(q_beta, kahan_comp, 2, -1, k, l, nvar) + case default + end select + end do + end do + $:END_GPU_PARALLEL_LOOP() + end if + if (bc_y%beg >= 0 .or. bc_y%end >= 0) then + call s_mpi_reduce_beta_variables_buffers(q_beta, kahan_comp, 2, -1, nvar) + end if + + if (bc_y%end < 0) then + $:GPU_PARALLEL_LOOP(private='[l,k]', collapse=2) + do l = beta_bc_bounds(3)%beg, beta_bc_bounds(3)%end + do k = beta_bc_bounds(1)%beg, beta_bc_bounds(1)%end + select case (bc_y%end) + case (BC_PERIODIC) + call s_beta_periodic(q_beta, kahan_comp, 2, 1, k, l, nvar) + case (BC_REFLECTIVE) + call s_beta_reflective(q_beta, kahan_comp, 2, 1, k, l, nvar) + case default + end select + end do + end do + $:END_GPU_PARALLEL_LOOP() + end if + if (bc_y%beg >= 0 .or. bc_y%end >= 0) then + call s_mpi_reduce_beta_variables_buffers(q_beta, kahan_comp, 2, 1, nvar) + end if + + if (num_dims == 2) return + + #:if not MFC_CASE_OPTIMIZATION or num_dims > 2 + !< z-direction + if (bc_z%beg < 0) then + $:GPU_PARALLEL_LOOP(private='[l,k]', collapse=2) + do l = beta_bc_bounds(2)%beg, beta_bc_bounds(2)%end + do k = beta_bc_bounds(1)%beg, beta_bc_bounds(1)%end + select case (bc_type(3, 1)%sf(k, l, 0)) + case (BC_PERIODIC) + call s_beta_periodic(q_beta, kahan_comp, 3, -1, k, l, nvar) + case (BC_REFLECTIVE) + call s_beta_reflective(q_beta, kahan_comp, 3, -1, k, l, nvar) + case default + end select + end do + end do + $:END_GPU_PARALLEL_LOOP() + end if + if (bc_z%beg >= 0 .or. bc_z%end >= 0) then + call s_mpi_reduce_beta_variables_buffers(q_beta, kahan_comp, 3, -1, nvar) + end if + + if (bc_z%end < 0) then + $:GPU_PARALLEL_LOOP(private='[l,k]', collapse=2) + do l = beta_bc_bounds(2)%beg, beta_bc_bounds(2)%end + do k = beta_bc_bounds(1)%beg, beta_bc_bounds(1)%end + select case (bc_type(3, 2)%sf(k, l, 0)) + case (BC_PERIODIC) + call s_beta_periodic(q_beta, kahan_comp, 3, 1, k, l, nvar) + case (BC_REFLECTIVE) + call s_beta_reflective(q_beta, kahan_comp, 3, 1, k, l, nvar) + case default + end select + end do + end do + $:END_GPU_PARALLEL_LOOP() + end if + if (bc_z%beg >= 0 .or. bc_z%end >= 0) then + call s_mpi_reduce_beta_variables_buffers(q_beta, kahan_comp, 3, 1, nvar) + end if + #:endif + + end subroutine s_populate_beta_buffers + + subroutine s_beta_periodic(q_beta, kahan_comp, bc_dir, bc_loc, k, l, nvar) + $:GPU_ROUTINE(function_name='s_beta_periodic', & + & parallelism='[seq]', cray_inline=True) + type(scalar_field), dimension(num_dims + 1), intent(inout) :: q_beta + type(scalar_field), dimension(num_dims + 1), intent(inout) :: kahan_comp + integer, intent(in) :: bc_dir, bc_loc + integer, intent(in) :: k, l + integer, intent(in) :: nvar + + integer :: j, i + real(wp) :: y_kahan, t_kahan + + if (bc_dir == 1) then !< x-direction + if (bc_loc == -1) then !bc_x%beg + do i = 1, nvar + do j = -mapCells - 1, mapCells + ! Kahan-compensated addition of ghost to interior + y_kahan = real(q_beta(beta_vars(i))%sf(m + j + 1, k, l), kind=wp) & + + kahan_comp(beta_vars(i))%sf(m + j + 1, k, l) & + - kahan_comp(beta_vars(i))%sf(j, k, l) + t_kahan = real(q_beta(beta_vars(i))%sf(j, k, l), kind=wp) + y_kahan + kahan_comp(beta_vars(i))%sf(j, k, l) = & + (t_kahan - q_beta(beta_vars(i))%sf(j, k, l)) - y_kahan + q_beta(beta_vars(i))%sf(j, k, l) = t_kahan + end do + end do + else !< bc_x%end + do i = 1, nvar + do j = -mapcells, mapcells + 1 + q_beta(beta_vars(i))%sf(m + j, k, l) = q_beta(beta_vars(i))%sf(j - 1, k, l) + kahan_comp(beta_vars(i))%sf(m + j, k, l) = kahan_comp(beta_vars(i))%sf(j - 1, k, l) + end do + end do + end if + elseif (bc_dir == 2) then !< y-direction + if (bc_loc == -1) then !< bc_y%beg + do i = 1, nvar + do j = -mapcells - 1, mapcells + y_kahan = real(q_beta(beta_vars(i))%sf(k, n + j + 1, l), kind=wp) & + + kahan_comp(beta_vars(i))%sf(k, n + j + 1, l) & + - kahan_comp(beta_vars(i))%sf(k, j, l) + t_kahan = real(q_beta(beta_vars(i))%sf(k, j, l), kind=wp) + y_kahan + kahan_comp(beta_vars(i))%sf(k, j, l) = & + (t_kahan - q_beta(beta_vars(i))%sf(k, j, l)) - y_kahan + q_beta(beta_vars(i))%sf(k, j, l) = t_kahan + end do + end do + else !< bc_y%end + do i = 1, nvar + do j = -mapcells, mapcells + 1 + q_beta(beta_vars(i))%sf(k, n + j, l) = q_beta(beta_vars(i))%sf(k, j - 1, l) + kahan_comp(beta_vars(i))%sf(k, n + j, l) = kahan_comp(beta_vars(i))%sf(k, j - 1, l) + end do + end do + end if + elseif (bc_dir == 3) then !< z-direction + if (bc_loc == -1) then !< bc_z%beg + do i = 1, nvar + do j = -mapcells - 1, mapcells + y_kahan = real(q_beta(beta_vars(i))%sf(k, l, p + j + 1), kind=wp) & + + kahan_comp(beta_vars(i))%sf(k, l, p + j + 1) & + - kahan_comp(beta_vars(i))%sf(k, l, j) + t_kahan = real(q_beta(beta_vars(i))%sf(k, l, j), kind=wp) + y_kahan + kahan_comp(beta_vars(i))%sf(k, l, j) = & + (t_kahan - q_beta(beta_vars(i))%sf(k, l, j)) - y_kahan + q_beta(beta_vars(i))%sf(k, l, j) = t_kahan + end do + end do + else !< bc_z%end + do i = 1, nvar + do j = -mapcells, mapcells + 1 + q_beta(beta_vars(i))%sf(k, l, p + j) = q_beta(beta_vars(i))%sf(k, l, j - 1) + kahan_comp(beta_vars(i))%sf(k, l, p + j) = kahan_comp(beta_vars(i))%sf(k, l, j - 1) + end do + end do + end if + end if + + end subroutine s_beta_periodic + + subroutine s_beta_extrapolation(q_beta, bc_dir, bc_loc, k, l, nvar) + $:GPU_ROUTINE(function_name='s_beta_extrapolation', & + & parallelism='[seq]', cray_inline=True) + type(scalar_field), dimension(num_dims + 1), intent(inout) :: q_beta + integer, intent(in) :: bc_dir, bc_loc + integer, intent(in) :: k, l + integer, intent(in) :: nvar + + integer :: j, i + + ! Set beta in buffer regions equal to zero + + if (bc_dir == 1) then !< x-direction + if (bc_loc == -1) then !bc_x%beg + do i = 1, nvar + do j = 1, buff_size + q_beta(beta_vars(i))%sf(-j, k, l) = 0._wp + end do + end do + else !< bc_x%end + do i = 1, nvar + do j = 1, buff_size + q_beta(beta_vars(i))%sf(m + j, k, l) = 0._wp + end do + end do + end if + elseif (bc_dir == 2) then !< y-direction + if (bc_loc == -1) then !< bc_y%beg + do i = 1, nvar + do j = 1, buff_size + q_beta(beta_vars(i))%sf(k, -j, l) = 0._wp + end do + end do + else !< bc_y%end + do i = 1, nvar + do j = 1, buff_size + q_beta(beta_vars(i))%sf(k, n + j, l) = 0._wp + end do + end do + end if + elseif (bc_dir == 3) then !< z-direction + if (bc_loc == -1) then !< bc_z%beg + do i = 1, nvar + do j = 1, buff_size + q_beta(beta_vars(i))%sf(k, l, -j) = 0._wp + end do + end do + else !< bc_z%end + do i = 1, nvar + do j = 1, buff_size + q_beta(beta_vars(i))%sf(k, l, p + j) = 0._wp + end do + end do + end if + end if + + end subroutine s_beta_extrapolation + + subroutine s_beta_reflective(q_beta, kahan_comp, bc_dir, bc_loc, k, l, nvar) + $:GPU_ROUTINE(function_name='s_beta_reflective', & + & parallelism='[seq]', cray_inline=True) + type(scalar_field), dimension(num_dims + 1), intent(inout) :: q_beta + type(scalar_field), dimension(num_dims + 1), intent(inout) :: kahan_comp + integer, intent(in) :: bc_dir, bc_loc + integer, intent(in) :: k, l + integer, intent(in) :: nvar + + integer :: j, i + real(wp) :: y_kahan, t_kahan + + ! Reflective BC for void fraction: + ! 1) Fold ghost-cell contributions back onto their mirror interior cells (Kahan) + ! 2) Set ghost cells = mirror of (now-folded) interior values + + if (bc_dir == 1) then !< x-direction + if (bc_loc == -1) then !< bc_x%beg + do i = 1, nvar + do j = 1, mapCells + 1 + y_kahan = real(q_beta(beta_vars(i))%sf(-j, k, l), kind=wp) & + + kahan_comp(beta_vars(i))%sf(-j, k, l) & + - kahan_comp(beta_vars(i))%sf(j - 1, k, l) + t_kahan = real(q_beta(beta_vars(i))%sf(j - 1, k, l), kind=wp) + y_kahan + kahan_comp(beta_vars(i))%sf(j - 1, k, l) = & + (t_kahan - q_beta(beta_vars(i))%sf(j - 1, k, l)) - y_kahan + q_beta(beta_vars(i))%sf(j - 1, k, l) = t_kahan + end do + do j = 1, mapCells + 1 + q_beta(beta_vars(i))%sf(-j, k, l) = q_beta(beta_vars(i))%sf(j - 1, k, l) + kahan_comp(beta_vars(i))%sf(-j, k, l) = kahan_comp(beta_vars(i))%sf(j - 1, k, l) + end do + end do + else !< bc_x%end + do i = 1, nvar + do j = 1, mapCells + 1 + y_kahan = real(q_beta(beta_vars(i))%sf(m + j, k, l), kind=wp) & + + kahan_comp(beta_vars(i))%sf(m + j, k, l) & + - kahan_comp(beta_vars(i))%sf(m - (j - 1), k, l) + t_kahan = real(q_beta(beta_vars(i))%sf(m - (j - 1), k, l), kind=wp) + y_kahan + kahan_comp(beta_vars(i))%sf(m - (j - 1), k, l) = & + (t_kahan - q_beta(beta_vars(i))%sf(m - (j - 1), k, l)) - y_kahan + q_beta(beta_vars(i))%sf(m - (j - 1), k, l) = t_kahan + end do + do j = 1, mapCells + 1 + q_beta(beta_vars(i))%sf(m + j, k, l) = q_beta(beta_vars(i))%sf(m - (j - 1), k, l) + kahan_comp(beta_vars(i))%sf(m + j, k, l) = kahan_comp(beta_vars(i))%sf(m - (j - 1), k, l) + end do + end do + end if + elseif (bc_dir == 2) then !< y-direction + if (bc_loc == -1) then !< bc_y%beg + do i = 1, nvar + do j = 1, mapCells + 1 + y_kahan = real(q_beta(beta_vars(i))%sf(k, -j, l), kind=wp) & + + kahan_comp(beta_vars(i))%sf(k, -j, l) & + - kahan_comp(beta_vars(i))%sf(k, j - 1, l) + t_kahan = real(q_beta(beta_vars(i))%sf(k, j - 1, l), kind=wp) + y_kahan + kahan_comp(beta_vars(i))%sf(k, j - 1, l) = & + (t_kahan - q_beta(beta_vars(i))%sf(k, j - 1, l)) - y_kahan + q_beta(beta_vars(i))%sf(k, j - 1, l) = t_kahan + end do + do j = 1, mapCells + 1 + q_beta(beta_vars(i))%sf(k, -j, l) = q_beta(beta_vars(i))%sf(k, j - 1, l) + kahan_comp(beta_vars(i))%sf(k, -j, l) = kahan_comp(beta_vars(i))%sf(k, j - 1, l) + end do + end do + else !< bc_y%end + do i = 1, nvar + do j = 1, mapCells + 1 + y_kahan = real(q_beta(beta_vars(i))%sf(k, n + j, l), kind=wp) & + + kahan_comp(beta_vars(i))%sf(k, n + j, l) & + - kahan_comp(beta_vars(i))%sf(k, n - (j - 1), l) + t_kahan = real(q_beta(beta_vars(i))%sf(k, n - (j - 1), l), kind=wp) + y_kahan + kahan_comp(beta_vars(i))%sf(k, n - (j - 1), l) = & + (t_kahan - q_beta(beta_vars(i))%sf(k, n - (j - 1), l)) - y_kahan + q_beta(beta_vars(i))%sf(k, n - (j - 1), l) = t_kahan + end do + do j = 1, mapCells + 1 + q_beta(beta_vars(i))%sf(k, n + j, l) = q_beta(beta_vars(i))%sf(k, n - (j - 1), l) + kahan_comp(beta_vars(i))%sf(k, n + j, l) = kahan_comp(beta_vars(i))%sf(k, n - (j - 1), l) + end do + end do + end if + elseif (bc_dir == 3) then !< z-direction + if (bc_loc == -1) then !< bc_z%beg + do i = 1, nvar + do j = 1, mapCells + 1 + y_kahan = real(q_beta(beta_vars(i))%sf(k, l, -j), kind=wp) & + + kahan_comp(beta_vars(i))%sf(k, l, -j) & + - kahan_comp(beta_vars(i))%sf(k, l, j - 1) + t_kahan = real(q_beta(beta_vars(i))%sf(k, l, j - 1), kind=wp) + y_kahan + kahan_comp(beta_vars(i))%sf(k, l, j - 1) = & + (t_kahan - q_beta(beta_vars(i))%sf(k, l, j - 1)) - y_kahan + q_beta(beta_vars(i))%sf(k, l, j - 1) = t_kahan + end do + do j = 1, mapCells + 1 + q_beta(beta_vars(i))%sf(k, l, -j) = q_beta(beta_vars(i))%sf(k, l, j - 1) + kahan_comp(beta_vars(i))%sf(k, l, -j) = kahan_comp(beta_vars(i))%sf(k, l, j - 1) + end do + end do + else !< bc_z%end + do i = 1, nvar + do j = 1, mapCells + 1 + y_kahan = real(q_beta(beta_vars(i))%sf(k, l, p + j), kind=wp) & + + kahan_comp(beta_vars(i))%sf(k, l, p + j) & + - kahan_comp(beta_vars(i))%sf(k, l, p - (j - 1)) + t_kahan = real(q_beta(beta_vars(i))%sf(k, l, p - (j - 1)), kind=wp) + y_kahan + kahan_comp(beta_vars(i))%sf(k, l, p - (j - 1)) = & + (t_kahan - q_beta(beta_vars(i))%sf(k, l, p - (j - 1))) - y_kahan + q_beta(beta_vars(i))%sf(k, l, p - (j - 1)) = t_kahan + end do + do j = 1, mapCells + 1 + q_beta(beta_vars(i))%sf(k, l, p + j) = q_beta(beta_vars(i))%sf(k, l, p - (j - 1)) + kahan_comp(beta_vars(i))%sf(k, l, p + j) = kahan_comp(beta_vars(i))%sf(k, l, p - (j - 1)) + end do + end do + end if + end if + + end subroutine s_beta_reflective + + !> @brief Populates ghost cell buffers for the color function and its divergence used in capillary surface tension. impure subroutine s_populate_capillary_buffers(c_divs, bc_type) type(scalar_field), dimension(num_dims + 1), intent(inout) :: c_divs - type(integer_field), dimension(1:num_dims,1:2), intent(in) :: bc_type - integer :: k, l + type(integer_field), dimension(1:num_dims, 1:2), intent(in) :: bc_type - !> x-direction + integer :: k, l + !< x-direction if (bc_x%beg >= 0) then call s_mpi_sendrecv_variables_buffers(c_divs, 1, -1, num_dims + 1) else - $:GPU_PARALLEL_LOOP(private='[l, k]', collapse=2) + $:GPU_PARALLEL_LOOP(private='[l,k]', collapse=2) do l = 0, p do k = 0, n select case (bc_type(1, 1)%sf(0, k, l)) @@ -1071,7 +1625,7 @@ contains if (bc_x%end >= 0) then call s_mpi_sendrecv_variables_buffers(c_divs, 1, 1, num_dims + 1) else - $:GPU_PARALLEL_LOOP(private='[l, k]', collapse=2) + $:GPU_PARALLEL_LOOP(private='[l,k]', collapse=2) do l = 0, p do k = 0, n select case (bc_type(1, 2)%sf(0, k, l)) @@ -1090,11 +1644,12 @@ contains if (n == 0) return #:if not MFC_CASE_OPTIMIZATION or num_dims > 1 - !> y-direction + + !< y-direction if (bc_y%beg >= 0) then call s_mpi_sendrecv_variables_buffers(c_divs, 2, -1, num_dims + 1) else - $:GPU_PARALLEL_LOOP(private='[l, k]', collapse=2) + $:GPU_PARALLEL_LOOP(private='[l,k]', collapse=2) do l = 0, p do k = -buff_size, m + buff_size select case (bc_type(2, 1)%sf(k, 0, l)) @@ -1113,7 +1668,7 @@ contains if (bc_y%end >= 0) then call s_mpi_sendrecv_variables_buffers(c_divs, 2, 1, num_dims + 1) else - $:GPU_PARALLEL_LOOP(private='[l, k]', collapse=2) + $:GPU_PARALLEL_LOOP(private='[l,k]', collapse=2) do l = 0, p do k = -buff_size, m + buff_size select case (bc_type(2, 2)%sf(k, 0, l)) @@ -1128,16 +1683,17 @@ contains end do $:END_GPU_PARALLEL_LOOP() end if + #:endif if (p == 0) return #:if not MFC_CASE_OPTIMIZATION or num_dims > 2 - !> z-direction + !< z-direction if (bc_z%beg >= 0) then call s_mpi_sendrecv_variables_buffers(c_divs, 3, -1, num_dims + 1) else - $:GPU_PARALLEL_LOOP(private='[l, k]', collapse=2) + $:GPU_PARALLEL_LOOP(private='[l,k]', collapse=2) do l = -buff_size, n + buff_size do k = -buff_size, m + buff_size select case (bc_type(3, 1)%sf(k, l, 0)) @@ -1156,7 +1712,7 @@ contains if (bc_z%end >= 0) then call s_mpi_sendrecv_variables_buffers(c_divs, 3, 1, num_dims + 1) else - $:GPU_PARALLEL_LOOP(private='[l, k]', collapse=2) + $:GPU_PARALLEL_LOOP(private='[l,k]', collapse=2) do l = -buff_size, n + buff_size do k = -buff_size, m + buff_size select case (bc_type(3, 2)%sf(k, l, 0)) @@ -1175,51 +1731,52 @@ contains end subroutine s_populate_capillary_buffers - !> Apply periodic boundary conditions to the color function and its divergence fields. + !> @brief Applies periodic boundary conditions to the color function and its divergence fields. subroutine s_color_function_periodic(c_divs, bc_dir, bc_loc, k, l) - - $:GPU_ROUTINE(function_name='s_color_function_periodic', parallelism='[seq]', cray_inline=True) + $:GPU_ROUTINE(function_name='s_color_function_periodic', & + & parallelism='[seq]', cray_inline=True) type(scalar_field), dimension(num_dims + 1), intent(inout) :: c_divs - integer, intent(in) :: bc_dir, bc_loc - integer, intent(in) :: k, l - integer :: j, i + integer, intent(in) :: bc_dir, bc_loc + integer, intent(in) :: k, l + + integer :: j, i - if (bc_dir == 1) then !< x-direction - if (bc_loc == -1) then ! bc_x%beg + if (bc_dir == 1) then !< x-direction + if (bc_loc == -1) then !bc_x%beg do i = 1, num_dims + 1 do j = 1, buff_size c_divs(i)%sf(-j, k, l) = c_divs(i)%sf(m - (j - 1), k, l) end do end do - else !< bc_x%end + else !< bc_x%end do i = 1, num_dims + 1 do j = 1, buff_size c_divs(i)%sf(m + j, k, l) = c_divs(i)%sf(j - 1, k, l) end do end do end if - else if (bc_dir == 2) then !< y-direction - if (bc_loc == -1) then !< bc_y%beg + elseif (bc_dir == 2) then !< y-direction + if (bc_loc == -1) then !< bc_y%beg do i = 1, num_dims + 1 do j = 1, buff_size c_divs(i)%sf(k, -j, l) = c_divs(i)%sf(k, n - (j - 1), l) end do end do - else !< bc_y%end + else !< bc_y%end do i = 1, num_dims + 1 do j = 1, buff_size c_divs(i)%sf(k, n + j, l) = c_divs(i)%sf(k, j - 1, l) end do end do end if - else if (bc_dir == 3) then !< z-direction - if (bc_loc == -1) then !< bc_z%beg + elseif (bc_dir == 3) then !< z-direction + if (bc_loc == -1) then !< bc_z%beg do i = 1, num_dims + 1 do j = 1, buff_size c_divs(i)%sf(k, l, -j) = c_divs(i)%sf(k, l, p - (j - 1)) end do end do - else !< bc_z%end + else !< bc_z%end do i = 1, num_dims + 1 do j = 1, buff_size c_divs(i)%sf(k, l, p + j) = c_divs(i)%sf(k, l, j - 1) @@ -1230,17 +1787,18 @@ contains end subroutine s_color_function_periodic - !> Apply reflective boundary conditions to the color function and its divergence fields. + !> @brief Applies reflective boundary conditions to the color function and its divergence fields. subroutine s_color_function_reflective(c_divs, bc_dir, bc_loc, k, l) - - $:GPU_ROUTINE(function_name='s_color_function_reflective', parallelism='[seq]', cray_inline=True) + $:GPU_ROUTINE(function_name='s_color_function_reflective', & + & parallelism='[seq]', cray_inline=True) type(scalar_field), dimension(num_dims + 1), intent(inout) :: c_divs - integer, intent(in) :: bc_dir, bc_loc - integer, intent(in) :: k, l - integer :: j, i + integer, intent(in) :: bc_dir, bc_loc + integer, intent(in) :: k, l + + integer :: j, i - if (bc_dir == 1) then !< x-direction - if (bc_loc == -1) then ! bc_x%beg + if (bc_dir == 1) then !< x-direction + if (bc_loc == -1) then !bc_x%beg do i = 1, num_dims + 1 do j = 1, buff_size if (i == bc_dir) then @@ -1250,7 +1808,7 @@ contains end if end do end do - else !< bc_x%end + else !< bc_x%end do i = 1, num_dims + 1 do j = 1, buff_size if (i == bc_dir) then @@ -1261,8 +1819,8 @@ contains end do end do end if - else if (bc_dir == 2) then !< y-direction - if (bc_loc == -1) then !< bc_y%beg + elseif (bc_dir == 2) then !< y-direction + if (bc_loc == -1) then !< bc_y%beg do i = 1, num_dims + 1 do j = 1, buff_size if (i == bc_dir) then @@ -1272,7 +1830,7 @@ contains end if end do end do - else !< bc_y%end + else !< bc_y%end do i = 1, num_dims + 1 do j = 1, buff_size if (i == bc_dir) then @@ -1283,8 +1841,8 @@ contains end do end do end if - else if (bc_dir == 3) then !< z-direction - if (bc_loc == -1) then !< bc_z%beg + elseif (bc_dir == 3) then !< z-direction + if (bc_loc == -1) then !< bc_z%beg do i = 1, num_dims + 1 do j = 1, buff_size if (i == bc_dir) then @@ -1294,7 +1852,7 @@ contains end if end do end do - else !< bc_z%end + else !< bc_z%end do i = 1, num_dims + 1 do j = 1, buff_size if (i == bc_dir) then @@ -1309,51 +1867,52 @@ contains end subroutine s_color_function_reflective - !> Extrapolate the color function and its divergence into ghost cells by copying boundary values. + !> @brief Extrapolates the color function and its divergence into ghost cells by copying boundary values. subroutine s_color_function_ghost_cell_extrapolation(c_divs, bc_dir, bc_loc, k, l) - - $:GPU_ROUTINE(function_name='s_color_function_ghost_cell_extrapolation', parallelism='[seq]', cray_inline=True) + $:GPU_ROUTINE(function_name='s_color_function_ghost_cell_extrapolation', & + & parallelism='[seq]', cray_inline=True) type(scalar_field), dimension(num_dims + 1), intent(inout) :: c_divs - integer, intent(in) :: bc_dir, bc_loc - integer, intent(in) :: k, l - integer :: j, i + integer, intent(in) :: bc_dir, bc_loc + integer, intent(in) :: k, l - if (bc_dir == 1) then !< x-direction - if (bc_loc == -1) then ! bc_x%beg + integer :: j, i + + if (bc_dir == 1) then !< x-direction + if (bc_loc == -1) then !bc_x%beg do i = 1, num_dims + 1 do j = 1, buff_size c_divs(i)%sf(-j, k, l) = c_divs(i)%sf(0, k, l) end do end do - else !< bc_x%end + else !< bc_x%end do i = 1, num_dims + 1 do j = 1, buff_size c_divs(i)%sf(m + j, k, l) = c_divs(i)%sf(m, k, l) end do end do end if - else if (bc_dir == 2) then !< y-direction - if (bc_loc == -1) then !< bc_y%beg + elseif (bc_dir == 2) then !< y-direction + if (bc_loc == -1) then !< bc_y%beg do i = 1, num_dims + 1 do j = 1, buff_size c_divs(i)%sf(k, -j, l) = c_divs(i)%sf(k, 0, l) end do end do - else !< bc_y%end + else !< bc_y%end do i = 1, num_dims + 1 do j = 1, buff_size c_divs(i)%sf(k, n + j, l) = c_divs(i)%sf(k, n, l) end do end do end if - else if (bc_dir == 3) then !< z-direction - if (bc_loc == -1) then !< bc_z%beg + elseif (bc_dir == 3) then !< z-direction + if (bc_loc == -1) then !< bc_z%beg do i = 1, num_dims + 1 do j = 1, buff_size c_divs(i)%sf(k, l, -j) = c_divs(i)%sf(k, l, 0) end do end do - else !< bc_z%end + else !< bc_z%end do i = 1, num_dims + 1 do j = 1, buff_size c_divs(i)%sf(k, l, p + j) = c_divs(i)%sf(k, l, p) @@ -1364,17 +1923,18 @@ contains end subroutine s_color_function_ghost_cell_extrapolation - !> Populate ghost cell buffers for the Jacobian scalar field used in the IGR elliptic solver. + !> @brief Populates ghost cell buffers for the Jacobian scalar field used in the IGR elliptic solver. impure subroutine s_populate_F_igr_buffers(bc_type, jac_sf) - type(integer_field), dimension(1:num_dims,1:2), intent(in) :: bc_type - type(scalar_field), dimension(1:), intent(inout) :: jac_sf - integer :: j, k, l + type(integer_field), dimension(1:num_dims, 1:2), intent(in) :: bc_type + type(scalar_field), dimension(1:), intent(inout) :: jac_sf + + integer :: j, k, l if (bc_x%beg >= 0) then call s_mpi_sendrecv_variables_buffers(jac_sf, 1, -1, 1) else - $:GPU_PARALLEL_LOOP(private='[l, k]', collapse=2) + $:GPU_PARALLEL_LOOP(private='[l,k]', collapse=2) do l = 0, p do k = 0, n select case (bc_type(1, 1)%sf(0, k, l)) @@ -1394,12 +1954,13 @@ contains end do end do $:END_GPU_PARALLEL_LOOP() + end if if (bc_x%end >= 0) then call s_mpi_sendrecv_variables_buffers(jac_sf, 1, 1, 1) else - $:GPU_PARALLEL_LOOP(private='[l, k]', collapse=2) + $:GPU_PARALLEL_LOOP(private='[l,k]', collapse=2) do l = 0, p do k = 0, n select case (bc_type(1, 2)%sf(0, k, l)) @@ -1419,15 +1980,17 @@ contains end do end do $:END_GPU_PARALLEL_LOOP() + end if #:if not MFC_CASE_OPTIMIZATION or num_dims > 1 + if (n == 0) then return else if (bc_y%beg >= 0) then call s_mpi_sendrecv_variables_buffers(jac_sf, 2, -1, 1) else - $:GPU_PARALLEL_LOOP(private='[l, k]', collapse=2) + $:GPU_PARALLEL_LOOP(private='[l,k]', collapse=2) do l = 0, p do k = idwbuff(1)%beg, idwbuff(1)%end select case (bc_type(2, 1)%sf(k, 0, l)) @@ -1447,12 +2010,13 @@ contains end do end do $:END_GPU_PARALLEL_LOOP() + end if if (bc_y%end >= 0) then call s_mpi_sendrecv_variables_buffers(jac_sf, 2, 1, 1) else - $:GPU_PARALLEL_LOOP(private='[l, k]', collapse=2) + $:GPU_PARALLEL_LOOP(private='[l,k]', collapse=2) do l = 0, p do k = idwbuff(1)%beg, idwbuff(1)%end select case (bc_type(2, 2)%sf(k, 0, l)) @@ -1473,6 +2037,7 @@ contains end do $:END_GPU_PARALLEL_LOOP() end if + #:endif #:if not MFC_CASE_OPTIMIZATION or num_dims > 2 @@ -1481,7 +2046,7 @@ contains else if (bc_z%beg >= 0) then call s_mpi_sendrecv_variables_buffers(jac_sf, 3, -1, 1) else - $:GPU_PARALLEL_LOOP(private='[l, k]', collapse=2) + $:GPU_PARALLEL_LOOP(private='[l,k]', collapse=2) do l = idwbuff(2)%beg, idwbuff(2)%end do k = idwbuff(1)%beg, idwbuff(1)%end select case (bc_type(3, 1)%sf(k, l, 0)) @@ -1506,7 +2071,7 @@ contains if (bc_z%end >= 0) then call s_mpi_sendrecv_variables_buffers(jac_sf, 3, 1, 1) else - $:GPU_PARALLEL_LOOP(private='[l, k]', collapse=2) + $:GPU_PARALLEL_LOOP(private='[l,k]', collapse=2) do l = idwbuff(2)%beg, idwbuff(2)%end do k = idwbuff(1)%beg, idwbuff(1)%end select case (bc_type(3, 2)%sf(k, l, 0)) @@ -1528,26 +2093,25 @@ contains $:END_GPU_PARALLEL_LOOP() end if #:endif - end subroutine s_populate_F_igr_buffers - !> Create MPI derived datatypes for boundary condition type arrays and buffer arrays used in parallel I/O. + !> @brief Creates MPI derived datatypes for boundary condition type arrays and buffer arrays used in parallel I/O. impure subroutine s_create_mpi_types(bc_type) - type(integer_field), dimension(1:num_dims,1:2), intent(in) :: bc_type + type(integer_field), dimension(1:num_dims, 1:2), intent(in) :: bc_type #ifdef MFC_MPI - integer :: dir, loc + integer :: dir, loc integer, dimension(3) :: sf_start_idx, sf_extents_loc - integer :: ierr + integer :: ierr do dir = 1, num_dims do loc = 1, 2 sf_start_idx = (/0, 0, 0/) sf_extents_loc = shape(bc_type(dir, loc)%sf) - call MPI_TYPE_CREATE_SUBARRAY(num_dims, sf_extents_loc, sf_extents_loc, sf_start_idx, MPI_ORDER_FORTRAN, & - & MPI_INTEGER, MPI_BC_TYPE_TYPE(dir, loc), ierr) + call MPI_TYPE_CREATE_SUBARRAY(num_dims, sf_extents_loc, sf_extents_loc, sf_start_idx, & + MPI_ORDER_FORTRAN, MPI_INTEGER, MPI_BC_TYPE_TYPE(dir, loc), ierr) call MPI_TYPE_COMMIT(MPI_BC_TYPE_TYPE(dir, loc), ierr) end do end do @@ -1558,24 +2122,26 @@ contains sf_extents_loc = shape(bc_buffers(dir, loc)%sf) call MPI_TYPE_CREATE_SUBARRAY(num_dims, sf_extents_loc*mpi_io_type, sf_extents_loc*mpi_io_type, sf_start_idx, & - & MPI_ORDER_FORTRAN, mpi_io_p, MPI_BC_BUFFER_TYPE(dir, loc), ierr) + MPI_ORDER_FORTRAN, mpi_io_p, MPI_BC_BUFFER_TYPE(dir, loc), ierr) call MPI_TYPE_COMMIT(MPI_BC_BUFFER_TYPE(dir, loc), ierr) end do end do #endif - end subroutine s_create_mpi_types - !> Write boundary condition type and buffer data to serial (unformatted) restart files. + !> @brief Writes boundary condition type and buffer data to serial (unformatted) restart files. subroutine s_write_serial_boundary_condition_files(q_prim_vf, bc_type, step_dirpath, old_grid_in) - type(scalar_field), dimension(sys_size), intent(in) :: q_prim_vf - type(integer_field), dimension(1:num_dims,1:2), intent(in) :: bc_type - logical, intent(in) :: old_grid_in - character(LEN=*), intent(in) :: step_dirpath - integer :: dir, loc, i - character(len=path_len) :: file_path - character(len=10) :: status + type(scalar_field), dimension(sys_size), intent(in) :: q_prim_vf + type(integer_field), dimension(1:num_dims, 1:2), intent(in) :: bc_type + logical, intent(in) :: old_grid_in + + character(LEN=*), intent(in) :: step_dirpath + + integer :: dir, loc, i + character(len=path_len) :: file_path + + character(len=10) :: status if (old_grid_in) then status = 'old' @@ -1585,8 +2151,8 @@ contains call s_pack_boundary_condition_buffers(q_prim_vf) - file_path = trim(step_dirpath) // '/bc_type.dat' - open (1, FILE=trim(file_path), form='unformatted', STATUS=status) + file_path = trim(step_dirpath)//'/bc_type.dat' + open (1, FILE=trim(file_path), FORM='unformatted', STATUS=status) do dir = 1, num_dims do loc = 1, 2 write (1) bc_type(dir, loc)%sf @@ -1594,8 +2160,8 @@ contains end do close (1) - file_path = trim(step_dirpath) // '/bc_buffers.dat' - open (1, FILE=trim(file_path), form='unformatted', STATUS=status) + file_path = trim(step_dirpath)//'/bc_buffers.dat' + open (1, FILE=trim(file_path), FORM='unformatted', STATUS=status) do dir = 1, num_dims do loc = 1, 2 write (1) bc_buffers(dir, loc)%sf @@ -1605,26 +2171,28 @@ contains end subroutine s_write_serial_boundary_condition_files - !> Write boundary condition type and buffer data to per-rank parallel files using MPI I/O. + !> @brief Writes boundary condition type and buffer data to per-rank parallel files using MPI I/O. subroutine s_write_parallel_boundary_condition_files(q_prim_vf, bc_type) - type(scalar_field), dimension(sys_size), intent(in) :: q_prim_vf - type(integer_field), dimension(1:num_dims,1:2), intent(in) :: bc_type - integer :: dir, loc - character(len=path_len) :: file_loc, file_path - character(len=10) :: status + type(scalar_field), dimension(sys_size), intent(in) :: q_prim_vf + type(integer_field), dimension(1:num_dims, 1:2), intent(in) :: bc_type + + integer :: dir, loc + character(len=path_len) :: file_loc, file_path + + character(len=10) :: status #ifdef MFC_MPI - integer :: ierr - integer :: file_id - integer :: offset + integer :: ierr + integer :: file_id + integer :: offset character(len=7) :: proc_rank_str - logical :: dir_check - integer :: nelements + logical :: dir_check + integer :: nelements call s_pack_boundary_condition_buffers(q_prim_vf) - file_loc = trim(case_dir) // '/restart_data/boundary_conditions' + file_loc = trim(case_dir)//'/restart_data/boundary_conditions' if (proc_rank == 0) then call my_inquire(file_loc, dir_check) if (dir_check .neqv. .true.) then @@ -1639,7 +2207,7 @@ contains call DelayFileAccess(proc_rank) write (proc_rank_str, '(I7.7)') proc_rank - file_path = trim(file_loc) // '/bc_' // trim(proc_rank_str) // '.dat' + file_path = trim(file_loc)//'/bc_'//trim(proc_rank_str)//'.dat' call MPI_File_open(MPI_COMM_SELF, trim(file_path), MPI_MODE_CREATE + MPI_MODE_WRONLY, MPI_INFO_NULL, file_id, ierr) offset = 0 @@ -1670,25 +2238,27 @@ contains end subroutine s_write_parallel_boundary_condition_files - !> Read boundary condition type and buffer data from serial (unformatted) restart files. + !> @brief Reads boundary condition type and buffer data from serial (unformatted) restart files. subroutine s_read_serial_boundary_condition_files(step_dirpath, bc_type) - character(LEN=*), intent(in) :: step_dirpath - type(integer_field), dimension(1:num_dims,1:2), intent(inout) :: bc_type - integer :: dir, loc - logical :: file_exist - character(len=path_len) :: file_path - character(len=10) :: status + character(LEN=*), intent(in) :: step_dirpath - ! Read bc_types + type(integer_field), dimension(1:num_dims, 1:2), intent(inout) :: bc_type + + integer :: dir, loc + logical :: file_exist + character(len=path_len) :: file_path + + character(len=10) :: status - file_path = trim(step_dirpath) // '/bc_type.dat' + ! Read bc_types + file_path = trim(step_dirpath)//'/bc_type.dat' inquire (FILE=trim(file_path), EXIST=file_exist) if (.not. file_exist) then - call s_mpi_abort(trim(file_path) // ' is missing. Exiting.') + call s_mpi_abort(trim(file_path)//' is missing. Exiting.') end if - open (1, FILE=trim(file_path), form='unformatted', STATUS='unknown') + open (1, FILE=trim(file_path), FORM='unformatted', STATUS='unknown') do dir = 1, num_dims do loc = 1, 2 read (1) bc_type(dir, loc)%sf @@ -1698,13 +2268,13 @@ contains close (1) ! Read bc_buffers - file_path = trim(step_dirpath) // '/bc_buffers.dat' + file_path = trim(step_dirpath)//'/bc_buffers.dat' inquire (FILE=trim(file_path), EXIST=file_exist) if (.not. file_exist) then - call s_mpi_abort(trim(file_path) // ' is missing. Exiting.') + call s_mpi_abort(trim(file_path)//' is missing. Exiting.') end if - open (1, FILE=trim(file_path), form='unformatted', STATUS='unknown') + open (1, FILE=trim(file_path), FORM='unformatted', STATUS='unknown') do dir = 1, num_dims do loc = 1, 2 read (1) bc_buffers(dir, loc)%sf @@ -1715,28 +2285,30 @@ contains end subroutine s_read_serial_boundary_condition_files - !> Read boundary condition type and buffer data from per-rank parallel files using MPI I/O. + !> @brief Reads boundary condition type and buffer data from per-rank parallel files using MPI I/O. subroutine s_read_parallel_boundary_condition_files(bc_type) - type(integer_field), dimension(1:num_dims,1:2), intent(inout) :: bc_type - integer :: dir, loc - character(len=path_len) :: file_loc, file_path - character(len=10) :: status + type(integer_field), dimension(1:num_dims, 1:2), intent(inout) :: bc_type + + integer :: dir, loc + character(len=path_len) :: file_loc, file_path + + character(len=10) :: status #ifdef MFC_MPI - integer :: ierr - integer :: file_id - integer :: offset + integer :: ierr + integer :: file_id + integer :: offset character(len=7) :: proc_rank_str - logical :: dir_check - integer :: nelements + logical :: dir_check + integer :: nelements - file_loc = trim(case_dir) // '/restart_data/boundary_conditions' + file_loc = trim(case_dir)//'/restart_data/boundary_conditions' if (proc_rank == 0) then call my_inquire(file_loc, dir_check) if (dir_check .neqv. .true.) then - call s_mpi_abort(trim(file_loc) // ' is missing. Exiting.') + call s_mpi_abort(trim(file_loc)//' is missing. Exiting.') end if end if @@ -1747,7 +2319,7 @@ contains call DelayFileAccess(proc_rank) write (proc_rank_str, '(I7.7)') proc_rank - file_path = trim(file_loc) // '/bc_' // trim(proc_rank_str) // '.dat' + file_path = trim(file_loc)//'/bc_'//trim(proc_rank_str)//'.dat' call MPI_File_open(MPI_COMM_SELF, trim(file_path), MPI_MODE_RDONLY, MPI_INFO_NULL, file_id, ierr) offset = 0 @@ -1780,11 +2352,11 @@ contains end subroutine s_read_parallel_boundary_condition_files - !> Pack primitive variable boundary slices into bc_buffers arrays for serialization. + !> @brief Packs primitive variable boundary slices into bc_buffers arrays for serialization. subroutine s_pack_boundary_condition_buffers(q_prim_vf) type(scalar_field), dimension(sys_size), intent(in) :: q_prim_vf - integer :: i, j, k + integer :: i, j, k do k = 0, p do j = 0, n @@ -1796,6 +2368,7 @@ contains end do #:if not MFC_CASE_OPTIMIZATION or num_dims > 1 + if (n > 0) then do k = 0, p do j = 1, sys_size @@ -1807,6 +2380,7 @@ contains end do #:if not MFC_CASE_OPTIMIZATION or num_dims > 2 + if (p > 0) then do k = 1, sys_size do j = 0, n @@ -1817,31 +2391,33 @@ contains end do end do end if + #:endif end if + #:endif end subroutine s_pack_boundary_condition_buffers - !> Initialize the per-cell boundary condition type arrays with the global default BC values. + !> @brief Initializes the per-cell boundary condition type arrays with the global default BC values. subroutine s_assign_default_bc_type(bc_type) - type(integer_field), dimension(1:num_dims,1:2), intent(in) :: bc_type + type(integer_field), dimension(1:num_dims, 1:2), intent(in) :: bc_type - bc_type(1, 1)%sf(:,:,:) = int(min(bc_x%beg, 0), kind=1) - bc_type(1, 2)%sf(:,:,:) = int(min(bc_x%end, 0), kind=1) - $:GPU_UPDATE(device='[bc_type(1, 1)%sf, bc_type(1, 2)%sf]') + bc_type(1, 1)%sf(:, :, :) = int(min(bc_x%beg, 0), kind=1) + bc_type(1, 2)%sf(:, :, :) = int(min(bc_x%end, 0), kind=1) + $:GPU_UPDATE(device='[bc_type(1,1)%sf,bc_type(1,2)%sf]') #:if not MFC_CASE_OPTIMIZATION or num_dims > 1 if (n > 0) then - bc_type(2, 1)%sf(:,:,:) = int(min(bc_y%beg, 0), kind=1) - bc_type(2, 2)%sf(:,:,:) = int(min(bc_y%end, 0), kind=1) - $:GPU_UPDATE(device='[bc_type(2, 1)%sf, bc_type(2, 2)%sf]') + bc_type(2, 1)%sf(:, :, :) = int(min(bc_y%beg, 0), kind=1) + bc_type(2, 2)%sf(:, :, :) = int(min(bc_y%end, 0), kind=1) + $:GPU_UPDATE(device='[bc_type(2,1)%sf,bc_type(2,2)%sf]') #:if not MFC_CASE_OPTIMIZATION or num_dims > 2 if (p > 0) then - bc_type(3, 1)%sf(:,:,:) = int(min(bc_z%beg, 0), kind=1) - bc_type(3, 2)%sf(:,:,:) = int(min(bc_z%end, 0), kind=1) - $:GPU_UPDATE(device='[bc_type(3, 1)%sf, bc_type(3, 2)%sf]') + bc_type(3, 1)%sf(:, :, :) = int(min(bc_z%beg, 0), kind=1) + bc_type(3, 2)%sf(:, :, :) = int(min(bc_z%end, 0), kind=1) + $:GPU_UPDATE(device='[bc_type(3,1)%sf,bc_type(3,2)%sf]') end if #:endif end if @@ -1849,19 +2425,45 @@ contains end subroutine s_assign_default_bc_type - !> Populate the buffers of the grid variables, which are constituted of the cell-boundary locations and cell-width - !! distributions, based on the boundary conditions. + !> The purpose of this subroutine is to populate the buffers + !! of the grid variables, which are constituted of the cell- + !! boundary locations and cell-width distributions, based on + !! the boundary conditions. subroutine s_populate_grid_variables_buffers - integer :: i + integer :: i !< Generic loop iterator #ifdef MFC_SIMULATION ! Required for compatibility between codes type(int_bounds_info) :: offset_x, offset_y, offset_z - offset_x%beg = buff_size; offset_x%end = buff_size offset_y%beg = buff_size; offset_y%end = buff_size offset_z%beg = buff_size; offset_z%end = buff_size + +#ifdef MFC_MPI + ! Populate global domain boundaries with stretched grids + call s_mpi_allreduce_min(x_cb(-1), glb_bounds(1)%beg) + call s_mpi_allreduce_max(x_cb(m), glb_bounds(1)%end) + + if (n > 0) then + call s_mpi_allreduce_min(y_cb(-1), glb_bounds(2)%beg) + call s_mpi_allreduce_max(y_cb(n), glb_bounds(2)%end) + if (p > 0) then + call s_mpi_allreduce_min(z_cb(-1), glb_bounds(3)%beg) + call s_mpi_allreduce_max(z_cb(p), glb_bounds(3)%end) + end if + end if +#else + glb_bounds(1)%beg = x_cb(-1); glb_bounds(1)%end = x_cb(m) + if (n > 0) then + glb_bounds(2)%beg = y_cb(-1); glb_bounds(2)%end = y_cb(n) + if (p > 0) then + glb_bounds(3)%beg = z_cb(-1); glb_bounds(3)%end = z_cb(p) + end if + end if +#endif + $:GPU_UPDATE(device='[glb_bounds]') + #endif #ifndef MFC_PRE_PROCESS @@ -1870,15 +2472,15 @@ contains ! Populating cell-width distribution buffer at bc_x%beg if (bc_x%beg >= 0) then call s_mpi_sendrecv_grid_variables_buffers(1, -1) - else if (bc_x%beg <= BC_GHOST_EXTRAP) then + elseif (bc_x%beg <= BC_GHOST_EXTRAP) then do i = 1, buff_size dx(-i) = dx(0) end do - else if (bc_x%beg == BC_REFLECTIVE) then + elseif (bc_x%beg == BC_REFLECTIVE) then do i = 1, buff_size dx(-i) = dx(i - 1) end do - else if (bc_x%beg == BC_PERIODIC) then + elseif (bc_x%beg == BC_PERIODIC) then do i = 1, buff_size dx(-i) = dx(m - (i - 1)) end do @@ -1896,15 +2498,15 @@ contains ! Populating the cell-width distribution buffer at bc_x%end if (bc_x%end >= 0) then call s_mpi_sendrecv_grid_variables_buffers(1, 1) - else if (bc_x%end <= BC_GHOST_EXTRAP) then + elseif (bc_x%end <= BC_GHOST_EXTRAP) then do i = 1, buff_size dx(m + i) = dx(m) end do - else if (bc_x%end == BC_REFLECTIVE) then + elseif (bc_x%end == BC_REFLECTIVE) then do i = 1, buff_size dx(m + i) = dx(m - (i - 1)) end do - else if (bc_x%end == BC_PERIODIC) then + elseif (bc_x%end == BC_PERIODIC) then do i = 1, buff_size dx(m + i) = dx(i - 1) end do @@ -1918,23 +2520,24 @@ contains do i = 1, buff_size x_cc(m + i) = x_cc(m + (i - 1)) + (dx(m + (i - 1)) + dx(m + i))/2._wp end do + ! END: Population of Buffers in x-direction ! Population of Buffers in y-direction ! Populating cell-width distribution buffer at bc_y%beg if (n == 0) then return - else if (bc_y%beg >= 0) then + elseif (bc_y%beg >= 0) then call s_mpi_sendrecv_grid_variables_buffers(2, -1) - else if (bc_y%beg <= BC_GHOST_EXTRAP .and. bc_y%beg /= BC_AXIS) then + elseif (bc_y%beg <= BC_GHOST_EXTRAP .and. bc_y%beg /= BC_AXIS) then do i = 1, buff_size dy(-i) = dy(0) end do - else if (bc_y%beg == BC_REFLECTIVE .or. bc_y%beg == BC_AXIS) then + elseif (bc_y%beg == BC_REFLECTIVE .or. bc_y%beg == BC_AXIS) then do i = 1, buff_size dy(-i) = dy(i - 1) end do - else if (bc_y%beg == BC_PERIODIC) then + elseif (bc_y%beg == BC_PERIODIC) then do i = 1, buff_size dy(-i) = dy(n - (i - 1)) end do @@ -1952,15 +2555,15 @@ contains ! Populating the cell-width distribution buffer at bc_y%end if (bc_y%end >= 0) then call s_mpi_sendrecv_grid_variables_buffers(2, 1) - else if (bc_y%end <= BC_GHOST_EXTRAP) then + elseif (bc_y%end <= BC_GHOST_EXTRAP) then do i = 1, buff_size dy(n + i) = dy(n) end do - else if (bc_y%end == BC_REFLECTIVE) then + elseif (bc_y%end == BC_REFLECTIVE) then do i = 1, buff_size dy(n + i) = dy(n - (i - 1)) end do - else if (bc_y%end == BC_PERIODIC) then + elseif (bc_y%end == BC_PERIODIC) then do i = 1, buff_size dy(n + i) = dy(i - 1) end do @@ -1974,23 +2577,24 @@ contains do i = 1, buff_size y_cc(n + i) = y_cc(n + (i - 1)) + (dy(n + (i - 1)) + dy(n + i))/2._wp end do + ! END: Population of Buffers in y-direction ! Population of Buffers in z-direction ! Populating cell-width distribution buffer at bc_z%beg if (p == 0) then return - else if (Bc_z%beg >= 0) then + elseif (Bc_z%beg >= 0) then call s_mpi_sendrecv_grid_variables_buffers(3, -1) - else if (bc_z%beg <= BC_GHOST_EXTRAP) then + elseif (bc_z%beg <= BC_GHOST_EXTRAP) then do i = 1, buff_size dz(-i) = dz(0) end do - else if (bc_z%beg == BC_REFLECTIVE) then + elseif (bc_z%beg == BC_REFLECTIVE) then do i = 1, buff_size dz(-i) = dz(i - 1) end do - else if (bc_z%beg == BC_PERIODIC) then + elseif (bc_z%beg == BC_PERIODIC) then do i = 1, buff_size dz(-i) = dz(p - (i - 1)) end do @@ -2008,15 +2612,15 @@ contains ! Populating the cell-width distribution buffer at bc_z%end if (bc_z%end >= 0) then call s_mpi_sendrecv_grid_variables_buffers(3, 1) - else if (bc_z%end <= BC_GHOST_EXTRAP) then + elseif (bc_z%end <= BC_GHOST_EXTRAP) then do i = 1, buff_size dz(p + i) = dz(p) end do - else if (bc_z%end == BC_REFLECTIVE) then + elseif (bc_z%end == BC_REFLECTIVE) then do i = 1, buff_size dz(p + i) = dz(p - (i - 1)) end do - else if (bc_z%end == BC_PERIODIC) then + elseif (bc_z%end == BC_PERIODIC) then do i = 1, buff_size dz(p + i) = dz(i - 1) end do @@ -2030,11 +2634,13 @@ contains do i = 1, buff_size z_cc(p + i) = z_cc(p + (i - 1)) + (dz(p + (i - 1)) + dz(p + i))/2._wp end do + ! END: Population of Buffers in z-direction + #endif end subroutine s_populate_grid_variables_buffers - !> Deallocate boundary condition buffer arrays allocated during module initialization. + !> @brief Deallocates boundary condition buffer arrays allocated during module initialization. subroutine s_finalize_boundary_common_module() if (bc_io) then diff --git a/src/common/m_checker_common.fpp b/src/common/m_checker_common.fpp index df71030ec9..2280828a3a 100644 --- a/src/common/m_checker_common.fpp +++ b/src/common/m_checker_common.fpp @@ -8,9 +8,12 @@ !> @brief Shared input validation checks for grid dimensions and AMD GPU compiler limits module m_checker_common - use m_global_parameters - use m_mpi_proxy - use m_helper_basic + use m_global_parameters !< Definitions of the global parameters + + use m_mpi_proxy !< Message passing interface (MPI) module proxy + + use m_helper_basic !< Functions to compare floating point numbers + use m_helper implicit none @@ -19,7 +22,8 @@ module m_checker_common contains - !> Checks compatibility of parameters in the input file. Used by all three stages + !> Checks compatibility of parameters in the input file. + !! Used by all three stages impure subroutine s_check_inputs_common #ifndef MFC_SIMULATION @@ -32,23 +36,23 @@ contains end subroutine s_check_inputs_common #ifndef MFC_SIMULATION - !> Verify that the total number of grid cells meets the minimum required by the number of dimensions and MPI ranks. - impure subroutine s_check_total_cells - character(len=18) :: numStr !< for int to string conversion - integer(kind=8) :: min_cells + !> @brief Verifies that the total number of grid cells meets the minimum required by the number of dimensions and MPI ranks. + impure subroutine s_check_total_cells + character(len=18) :: numStr !< for int to string conversion + integer(kind=8) :: min_cells min_cells = int(2, kind=8)**int(min(1, m) + min(1, n) + min(1, p), kind=8)*int(num_procs, kind=8) call s_int_to_str(2**(min(1, m) + min(1, n) + min(1, p))*num_procs, numStr) @:PROHIBIT(nGlobal < min_cells, & - & "Total number of cells must be at least (2^[number of dimensions])*num_procs, " // "which is currently " & - & // trim(numStr)) - + "Total number of cells must be at least (2^[number of dimensions])*num_procs, " // & + "which is currently "//trim(numStr)) end subroutine s_check_total_cells + #endif - !> Check that simulation parameters stay within AMD GPU compiler limits when case optimization is disabled. + !> @brief Checks that simulation parameters stay within AMD GPU compiler limits when case optimization is disabled. impure subroutine s_check_amd #:if not MFC_CASE_OPTIMIZATION @@ -60,5 +64,7 @@ contains end subroutine s_check_amd #ifndef MFC_POST_PROCESS + #endif + end module m_checker_common diff --git a/src/common/m_chemistry.fpp b/src/common/m_chemistry.fpp index 66f1e97923..d7ffbc3cfe 100644 --- a/src/common/m_chemistry.fpp +++ b/src/common/m_chemistry.fpp @@ -9,18 +9,21 @@ !> @brief Multi-species chemistry interface for thermodynamic properties, reaction rates, and transport coefficients module m_chemistry - use m_thermochem, only: num_species, molecular_weights, get_temperature, get_net_production_rates, get_mole_fractions, & - & get_species_binary_mass_diffusivities, get_species_mass_diffusivities_mixavg, gas_constant, & - & get_mixture_molecular_weight, get_mixture_energy_mass, get_mixture_thermal_conductivity_mixavg, & - & get_species_enthalpies_rt, get_mixture_viscosity_mixavg, get_mixture_specific_heat_cp_mass, get_mixture_enthalpy_mass + use m_thermochem, only: & + num_species, molecular_weights, get_temperature, get_net_production_rates, & + get_mole_fractions, get_species_binary_mass_diffusivities, & + get_species_mass_diffusivities_mixavg, gas_constant, get_mixture_molecular_weight, & + get_mixture_energy_mass, get_mixture_thermal_conductivity_mixavg, get_species_enthalpies_rt, & + get_mixture_viscosity_mixavg, get_mixture_specific_heat_cp_mass, get_mixture_enthalpy_mass use m_global_parameters implicit none #:if USING_AMD - real(wp) :: molecular_weights_nonparameter(10) = (/2.016, 1.008, 15.999, 31.998, 17.007, 18.015, 33.006, 34.014, 39.95, & - & 28.014/) + real(wp) :: molecular_weights_nonparameter(10) = & + (/2.016, 1.008, 15.999, 31.998, 17.007, 18.015, 33.006, & + 34.014, 39.95, 28.014/) $:GPU_DECLARE(create='[molecular_weights_nonparameter]') #:endif @@ -31,66 +34,75 @@ module m_chemistry contains - !> Compute mixture viscosities for left and right states and invert them for use as reciprocal Reynolds numbers. + !> @brief Computes mixture viscosities for left and right states and inverts them for use as reciprocal Reynolds numbers. subroutine compute_viscosity_and_inversion(T_L, Ys_L, T_R, Ys_R, Re_L, Re_R) - $:GPU_ROUTINE(function_name='compute_viscosity_and_inversion',parallelism='[seq]', cray_inline=True) + $:GPU_ROUTINE(function_name='compute_viscosity_and_inversion',parallelism='[seq]', & + & cray_inline=True) - real(wp), intent(inout) :: T_L, T_R, Re_L, Re_R + real(wp), intent(inout) :: T_L, T_R, Re_L, Re_R real(wp), dimension(num_species), intent(inout) :: Ys_R, Ys_L call get_mixture_viscosity_mixavg(T_L, Ys_L, Re_L) call get_mixture_viscosity_mixavg(T_R, Ys_R, Re_R) - ! Convert dynamic viscosity to inverse (MFC stores 1/mu for Reynolds number convention) Re_L = 1.0_wp/Re_L Re_R = 1.0_wp/Re_R end subroutine compute_viscosity_and_inversion - !> Initialize the temperature field from conservative variables by inverting the energy equation. + !> @brief Initializes the temperature field from conservative variables by inverting the energy equation. subroutine s_compute_q_T_sf(q_T_sf, q_cons_vf, bounds) - ! Initialize the temperature field at the start of the simulation to reasonable values. Temperature is computed the regular - ! way using the conservative variables. + ! Initialize the temperature field at the start of the simulation to + ! reasonable values. Temperature is computed the regular way using the + ! conservative variables. - type(scalar_field), intent(inout) :: q_T_sf + type(scalar_field), intent(inout) :: q_T_sf type(scalar_field), dimension(sys_size), intent(in) :: q_cons_vf - type(int_bounds_info), dimension(1:3), intent(in) :: bounds - integer :: x, y, z, eqn - real(wp) :: energy, T_in - real(wp), dimension(num_species) :: Ys + type(int_bounds_info), dimension(1:3), intent(in) :: bounds + + integer :: x, y, z, eqn + real(wp) :: energy, T_in + real(wp), dimension(num_species) :: Ys do z = bounds(3)%beg, bounds(3)%end do y = bounds(2)%beg, bounds(2)%end do x = bounds(1)%beg, bounds(1)%end do eqn = chemxb, chemxe - Ys(eqn - chemxb + 1) = q_cons_vf(eqn)%sf(x, y, z)/q_cons_vf(contxb)%sf(x, y, z) + Ys(eqn - chemxb + 1) = & + q_cons_vf(eqn)%sf(x, y, z)/q_cons_vf(contxb)%sf(x, y, z) end do - ! e = E - 1/2*|u|^2 cons. E_idx = \rho E cons. contxb = \rho (1-fluid model) cons. momxb + i = \rho u_i + ! e = E - 1/2*|u|^2 + ! cons. E_idx = \rho E + ! cons. contxb = \rho (1-fluid model) + ! cons. momxb + i = \rho u_i energy = q_cons_vf(E_idx)%sf(x, y, z)/q_cons_vf(contxb)%sf(x, y, z) do eqn = momxb, momxe - energy = energy - 0.5_wp*(q_cons_vf(eqn)%sf(x, y, z)/q_cons_vf(contxb)%sf(x, y, z))**2._wp + energy = energy - & + 0.5_wp*(q_cons_vf(eqn)%sf(x, y, z)/q_cons_vf(contxb)%sf(x, y, z))**2._wp end do T_in = real(q_T_sf%sf(x, y, z), kind=wp) call get_temperature(energy, dflt_T_guess, Ys, .true., T_in) q_T_sf%sf(x, y, z) = T_in + end do end do end do end subroutine s_compute_q_T_sf - !> Compute the temperature field from primitive variables using the ideal gas law and mixture molecular weight. + !> @brief Computes the temperature field from primitive variables using the ideal gas law and mixture molecular weight. subroutine s_compute_T_from_primitives(q_T_sf, q_prim_vf, bounds) - type(scalar_field), intent(inout) :: q_T_sf + type(scalar_field), intent(inout) :: q_T_sf type(scalar_field), dimension(sys_size), intent(in) :: q_prim_vf - type(int_bounds_info), dimension(1:3), intent(in) :: bounds - integer :: x, y, z, i - real(wp), dimension(num_species) :: Ys - real(wp) :: mix_mol_weight + type(int_bounds_info), dimension(1:3), intent(in) :: bounds + + integer :: x, y, z, i + real(wp), dimension(num_species) :: Ys + real(wp) :: mix_mol_weight do z = bounds(3)%beg, bounds(3)%end do y = bounds(2)%beg, bounds(2)%end @@ -107,18 +119,18 @@ contains end subroutine s_compute_T_from_primitives - !> Add chemical reaction source terms to the species transport RHS using net production rates. + !> @brief Adds chemical reaction source terms to the species transport RHS using net production rates. subroutine s_compute_chemistry_reaction_flux(rhs_vf, q_cons_qp, q_T_sf, q_prim_qp, bounds) type(scalar_field), dimension(sys_size), intent(inout) :: rhs_vf - type(scalar_field), intent(inout) :: q_T_sf + type(scalar_field), intent(inout) :: q_T_sf type(scalar_field), dimension(sys_size), intent(inout) :: q_cons_qp, q_prim_qp - type(int_bounds_info), dimension(1:3), intent(in) :: bounds - integer :: x, y, z - integer :: eqn - real(wp) :: T - real(wp) :: rho, omega_m + type(int_bounds_info), dimension(1:3), intent(in) :: bounds + integer :: x, y, z + integer :: eqn + real(wp) :: T + real(wp) :: rho, omega_m #:if not MFC_CASE_OPTIMIZATION and USING_AMD real(wp), dimension(10) :: Ys real(wp), dimension(10) :: omega @@ -131,6 +143,7 @@ contains do z = bounds(3)%beg, bounds(3)%end do y = bounds(2)%beg, bounds(2)%end do x = bounds(1)%beg, bounds(1)%end + $:GPU_LOOP(parallelism='[seq]') do eqn = chemxb, chemxe Ys(eqn - chemxb + 1) = q_prim_qp(eqn)%sf(x, y, z) @@ -149,7 +162,9 @@ contains omega_m = molecular_weights(eqn - chemxb + 1)*omega(eqn - chemxb + 1) #:endif rhs_vf(eqn)%sf(x, y, z) = rhs_vf(eqn)%sf(x, y, z) + omega_m + end do + end do end do end do @@ -157,14 +172,14 @@ contains end subroutine s_compute_chemistry_reaction_flux - !> Compute species mass diffusion fluxes at cell interfaces using mixture-averaged diffusivities. + !> @brief Computes species mass diffusion fluxes at cell interfaces using mixture-averaged diffusivities. subroutine s_compute_chemistry_diffusion_flux(idir, q_prim_qp, flux_src_vf, irx, iry, irz) - type(scalar_field), dimension(sys_size), intent(in) :: q_prim_qp + type(scalar_field), dimension(sys_size), intent(in) :: q_prim_qp type(scalar_field), dimension(sys_size), intent(inout) :: flux_src_vf - type(int_bounds_info), intent(in) :: irx, iry, irz - integer, intent(in) :: idir + type(int_bounds_info), intent(in) :: irx, iry, irz + integer, intent(in) :: idir #:if not MFC_CASE_OPTIMIZATION and USING_AMD real(wp), dimension(10) :: Xs_L, Xs_R, Xs_cell, Ys_L, Ys_R, Ys_cell real(wp), dimension(10) :: mass_diffusivities_mixavg1, mass_diffusivities_mixavg2 @@ -177,31 +192,29 @@ contains real(wp), dimension(num_species) :: Mass_Diffu_Flux, dYk_dxi #:endif - real(wp) :: Mass_Diffu_Energy - real(wp) :: MW_L, MW_R, MW_cell, Rgas_L, Rgas_R, T_L, T_R, P_L, P_R, rho_L, rho_R, rho_cell, rho_Vic - real(wp) :: lambda_L, lambda_R, lambda_Cell, dT_dxi, grid_spacing - real(wp) :: Cp_L, Cp_R - real(wp) :: diffusivity_L, diffusivity_R, diffusivity_cell - real(wp) :: hmix_L, hmix_R, dh_dxi - integer :: x, y, z, i, n, eqn + real(wp) :: Mass_Diffu_Energy + real(wp) :: MW_L, MW_R, MW_cell, Rgas_L, Rgas_R, T_L, T_R, P_L, P_R, rho_L, rho_R, rho_cell, rho_Vic + real(wp) :: lambda_L, lambda_R, lambda_Cell, dT_dxi, grid_spacing + real(wp) :: Cp_L, Cp_R + real(wp) :: diffusivity_L, diffusivity_R, diffusivity_cell + real(wp) :: hmix_L, hmix_R, dh_dxi + + integer :: x, y, z, i, n, eqn integer, dimension(3) :: offsets isc1 = irx; isc2 = iry; isc3 = irz - $:GPU_UPDATE(device='[isc1, isc2, isc3]') + $:GPU_UPDATE(device='[isc1,isc2,isc3]') if (chemistry .or. dummy) then + ! Set offsets based on direction using array indexing offsets = 0 offsets(idir) = 1 ! Model 1: Mixture-Average Transport if (chem_params%transport_model == 1) then ! Note: Added 'i' and 'eqn' to private list. - $:GPU_PARALLEL_LOOP(collapse=3, private='[x, y, z, i, eqn, Ys_L, Ys_R, Ys_cell, Xs_L, Xs_R, & - & mass_diffusivities_mixavg1, mass_diffusivities_mixavg2, mass_diffusivities_mixavg_Cell, & - & h_l, h_r, Xs_cell, h_k, dXk_dxi, Mass_Diffu_Flux, Mass_Diffu_Energy, MW_L, MW_R, MW_cell, & - & Rgas_L, Rgas_R, T_L, T_R, P_L, P_R, rho_L, rho_R, rho_cell, rho_Vic, lambda_L, lambda_R, & - & lambda_Cell, dT_dxi, grid_spacing]', copyin='[offsets]') + $:GPU_PARALLEL_LOOP(collapse=3, private='[x,y,z,i,eqn,Ys_L, Ys_R, Ys_cell, Xs_L, Xs_R, mass_diffusivities_mixavg1, mass_diffusivities_mixavg2, mass_diffusivities_mixavg_Cell, h_l, h_r, Xs_cell, h_k, dXk_dxi,Mass_Diffu_Flux, Mass_Diffu_Energy, MW_L, MW_R, MW_cell, Rgas_L, Rgas_R, T_L, T_R, P_L, P_R, rho_L, rho_R, rho_cell, rho_Vic, lambda_L, lambda_R, lambda_Cell, dT_dxi, grid_spacing]', copyin='[offsets]') do z = isc3%beg, isc3%end do y = isc2%beg, isc2%end do x = isc1%beg, isc1%end @@ -261,10 +274,8 @@ contains $:GPU_LOOP(parallelism='[seq]') do i = chemxb, chemxe #:if USING_AMD - h_l(i - chemxb + 1) = h_l(i - chemxb + 1)*gas_constant*T_L/molecular_weights_nonparameter(i & - & - chemxb + 1) - h_r(i - chemxb + 1) = h_r(i - chemxb + 1)*gas_constant*T_R/molecular_weights_nonparameter(i & - & - chemxb + 1) + h_l(i - chemxb + 1) = h_l(i - chemxb + 1)*gas_constant*T_L/molecular_weights_nonparameter(i - chemxb + 1) + h_r(i - chemxb + 1) = h_r(i - chemxb + 1)*gas_constant*T_R/molecular_weights_nonparameter(i - chemxb + 1) #:else h_l(i - chemxb + 1) = h_l(i - chemxb + 1)*gas_constant*T_L/molecular_weights(i - chemxb + 1) h_r(i - chemxb + 1) = h_r(i - chemxb + 1)*gas_constant*T_R/molecular_weights(i - chemxb + 1) @@ -277,8 +288,8 @@ contains ! Calculate mixture-averaged diffusivities $:GPU_LOOP(parallelism='[seq]') do i = chemxb, chemxe - mass_diffusivities_mixavg_Cell(i - chemxb + 1) = (mass_diffusivities_mixavg2(i - chemxb + 1) & - & + mass_diffusivities_mixavg1(i - chemxb + 1))/2.0_wp + mass_diffusivities_mixavg_Cell(i - chemxb + 1) = & + (mass_diffusivities_mixavg2(i - chemxb + 1) + mass_diffusivities_mixavg1(i - chemxb + 1))/2.0_wp end do lambda_Cell = 0.5_wp*(lambda_R + lambda_L) @@ -290,12 +301,11 @@ contains $:GPU_LOOP(parallelism='[seq]') do eqn = chemxb, chemxe #:if USING_AMD - Mass_Diffu_Flux(eqn - chemxb + 1) = rho_cell*mass_diffusivities_mixavg_Cell(eqn - chemxb + 1) & - & *molecular_weights_nonparameter(eqn - chemxb + 1)/MW_cell*dXk_dxi(eqn & - & - chemxb + 1) + Mass_Diffu_Flux(eqn - chemxb + 1) = rho_cell*mass_diffusivities_mixavg_Cell(eqn - chemxb + 1)* & + molecular_weights_nonparameter(eqn - chemxb + 1)/MW_cell*dXk_dxi(eqn - chemxb + 1) #:else - Mass_Diffu_Flux(eqn - chemxb + 1) = rho_cell*mass_diffusivities_mixavg_Cell(eqn - chemxb + 1) & - & *molecular_weights(eqn - chemxb + 1)/MW_cell*dXk_dxi(eqn - chemxb + 1) + Mass_Diffu_Flux(eqn - chemxb + 1) = rho_cell*mass_diffusivities_mixavg_Cell(eqn - chemxb + 1)* & + molecular_weights(eqn - chemxb + 1)/MW_cell*dXk_dxi(eqn - chemxb + 1) #:endif rho_Vic = rho_Vic + Mass_Diffu_Flux(eqn - chemxb + 1) Mass_Diffu_Energy = Mass_Diffu_Energy + h_k(eqn - chemxb + 1)*Mass_Diffu_Flux(eqn - chemxb + 1) @@ -305,8 +315,7 @@ contains $:GPU_LOOP(parallelism='[seq]') do eqn = chemxb, chemxe Mass_Diffu_Energy = Mass_Diffu_Energy - h_k(eqn - chemxb + 1)*Ys_cell(eqn - chemxb + 1)*rho_Vic - Mass_Diffu_Flux(eqn - chemxb + 1) = Mass_Diffu_Flux(eqn - chemxb + 1) - rho_Vic*Ys_cell(eqn & - & - chemxb + 1) + Mass_Diffu_Flux(eqn - chemxb + 1) = Mass_Diffu_Flux(eqn - chemxb + 1) - rho_Vic*Ys_cell(eqn - chemxb + 1) end do ! Add thermal conduction contribution @@ -327,10 +336,7 @@ contains ! Model 2: Unity Lewis Number else if (chem_params%transport_model == 2) then ! Note: Added ALL scalars and 'i'/'eqn' to private list to prevent race conditions. - $:GPU_PARALLEL_LOOP(collapse=3, private='[x, y, z, i, eqn, Ys_L, Ys_R, Ys_cell, dYk_dxi, Mass_Diffu_Flux, & - & grid_spacing, MW_L, MW_R, MW_cell, Rgas_L, Rgas_R, P_L, P_R, rho_L, rho_R, rho_cell, T_L, & - & T_R, Cp_L, Cp_R, hmix_L, hmix_R, dh_dxi, lambda_L, lambda_R, lambda_Cell, diffusivity_L, & - & diffusivity_R, diffusivity_cell, Mass_Diffu_Energy]', copyin='[offsets]') + $:GPU_PARALLEL_LOOP(collapse=3, private='[x,y,z,i,eqn,Ys_L, Ys_R, Ys_cell, dYk_dxi, Mass_Diffu_Flux, grid_spacing, MW_L, MW_R, MW_cell, Rgas_L, Rgas_R, P_L, P_R, rho_L, rho_R, rho_cell, T_L, T_R, Cp_L, Cp_R, hmix_L, hmix_R, dh_dxi, lambda_L, lambda_R, lambda_Cell, diffusivity_L, diffusivity_R, diffusivity_cell, Mass_Diffu_Energy]', copyin='[offsets]') do z = isc3%beg, isc3%end do y = isc2%beg, isc2%end do x = isc1%beg, isc1%end @@ -385,7 +391,8 @@ contains ! Calculate species properties and gradients $:GPU_LOOP(parallelism='[seq]') do i = chemxb, chemxe - dYk_dxi(i - chemxb + 1) = (Ys_R(i - chemxb + 1) - Ys_L(i - chemxb + 1))/grid_spacing + dYk_dxi(i - chemxb + 1) = (Ys_R(i - chemxb + 1) - & + Ys_L(i - chemxb + 1))/grid_spacing end do ! Calculate mixture-averaged diffusivities @@ -400,7 +407,9 @@ contains $:GPU_LOOP(parallelism='[seq]') do eqn = chemxb, chemxe - Mass_Diffu_Flux(eqn - chemxb + 1) = rho_cell*diffusivity_cell*dYk_dxi(eqn - chemxb + 1) + Mass_Diffu_Flux(eqn - chemxb + 1) = rho_cell* & + diffusivity_cell* & + dYk_dxi(eqn - chemxb + 1) end do Mass_Diffu_Energy = rho_cell*diffusivity_cell*dh_dxi diff --git a/src/common/m_compile_specific.f90 b/src/common/m_compile_specific.f90 index 9d79811320..6820ef3a9a 100644 --- a/src/common/m_compile_specific.f90 +++ b/src/common/m_compile_specific.f90 @@ -12,86 +12,82 @@ module m_compile_specific contains - !> Create a directory and all its parents if it does not exist + !> Creates a directory and all its parents if it does not exist + !! @param dir_name Directory path impure subroutine s_create_directory(dir_name) - character(LEN=*), intent(in) :: dir_name #ifdef _WIN32 - call system('mkdir "' // dir_name // '" 2> NUL') + call system('mkdir "'//dir_name//'" 2> NUL') #else - call system('mkdir -p "' // dir_name // '"') + call system('mkdir -p "'//dir_name//'"') #endif end subroutine s_create_directory - !> Delete a file at the given path using a platform-specific system command. + !> @brief Deletes a file at the given path using a platform-specific system command. impure subroutine s_delete_file(filepath) - character(LEN=*), intent(in) :: filepath #ifdef _WIN32 - call system('del "' // filepath // '"') + call system('del "'//filepath//'"') #else - call system('rm "' // filepath // '"') + call system('rm "'//filepath//'"') #endif end subroutine s_delete_file - !> Recursively delete a directory using a platform-specific system command. + !> @brief Recursively deletes a directory using a platform-specific system command. impure subroutine s_delete_directory(dir_name) - character(LEN=*), intent(in) :: dir_name #ifdef _WIN32 - call system('rmdir "' // dir_name // '" /s /q') + call system('rmdir "'//dir_name//'" /s /q') #else - call system('rm -r "' // dir_name // '"') + call system('rm -r "'//dir_name//'"') #endif end subroutine s_delete_directory - !> Inquires on the existence of a directory - !! @param dircheck Switch that indicates if directory exists + !> Inquires on the existence of a directory + !! @param fileloc File directory location + !! @param dircheck Switch that indicates if directory exists impure subroutine my_inquire(fileloc, dircheck) - character(LEN=*), intent(in) :: fileloc - logical, intent(inout) :: dircheck + logical, intent(inout) :: dircheck #ifdef __INTEL_COMPILER - inquire (DIRECTORY=trim(fileloc), EXIST=dircheck) ! Intel + inquire (DIRECTORY=trim(fileloc), EXIST=dircheck) !Intel #else - inquire (FILE=trim(fileloc), EXIST=dircheck) ! GCC + inquire (FILE=trim(fileloc), EXIST=dircheck) !GCC #endif end subroutine my_inquire - !> Retrieve the current working directory path via the GETCWD intrinsic. + !> @brief Retrieves the current working directory path via the GETCWD intrinsic. impure subroutine s_get_cwd(cwd) - character(LEN=*), intent(out) :: cwd call GETCWD(cwd) - end subroutine s_get_cwd - !> Extract the base filename from a directory path using the system basename command. + !> @brief Extracts the base filename from a directory path using the system basename command. impure subroutine s_get_basename(dirpath, basename) - - character(LEN=*), intent(in) :: dirpath + character(LEN=*), intent(in) :: dirpath character(LEN=*), intent(out) :: basename - integer :: iUnit - character(len=30) :: tmpfilepath + + integer :: iUnit + character(len=30) :: tmpfilepath write (tmpfilepath, '(A,I0)') 'basename_', proc_rank #ifdef _WIN32 - call system('for /F %i in ("' // trim(dirpath) // '") do @echo %~ni > ' // trim(tmpfilepath)) + call system('for /F %i in ("'//trim(dirpath)//'") do @echo %~ni > '//trim(tmpfilepath)) #else - call system('basename "' // trim(dirpath) // '" > ' // trim(tmpfilepath)) + call system('basename "'//trim(dirpath)//'" > '//trim(tmpfilepath)) #endif - open (newunit=iUnit, FILE=trim(tmpfilepath), form='formatted', STATUS='old') + open (newunit=iUnit, FILE=trim(tmpfilepath), FORM='formatted', STATUS='old') read (iUnit, '(A)') basename close (iUnit) diff --git a/src/common/m_constants.fpp b/src/common/m_constants.fpp index 8e01059691..75d5f1d6dd 100644 --- a/src/common/m_constants.fpp +++ b/src/common/m_constants.fpp @@ -7,89 +7,97 @@ module m_constants use m_precision_select - character, parameter :: dflt_char = ' ' !< Default string value - real(wp), parameter :: dflt_real = -1.e6_wp !< Default real value - real(wp), parameter :: sgm_eps = 1.e-16_wp !< Segmentation tolerance - real(wp), parameter :: Chem_Tolerance = 1.e-16_wp !< Speed of Sound Tolerance in Chemistry - real(wp), parameter :: small_alf = 1.e-11_wp !< Small alf tolerance - real(wp), parameter :: pi = 3.141592653589793_wp !< Pi - real(wp), parameter :: verysmall = 1.e-12_wp !< Very small number - !> Radius cutoff to avoid division by zero for 3D spherical harmonic patch (geometry 14) - real(wp), parameter :: small_radius = 1.e-32_wp - integer, parameter :: num_stcls_min = 5 !< Minimum # of stencils - integer, parameter :: path_len = 400 !< Maximum path length - integer, parameter :: name_len = 50 !< Maximum name length - integer, parameter :: dflt_int = -100 !< Default integer value - integer, parameter :: fourier_rings = 5 !< Fourier filter ring limit - integer, parameter :: num_fluids_max = 10 !< Maximum number of fluids in the simulation - integer, parameter :: num_probes_max = 10 !< Maximum number of flow probes in the simulation - integer, parameter :: num_patches_max = 1000 !< Maximum number of IC patches - integer, parameter :: num_bc_patches_max = 10 !< Maximum number of boundary condition patches - integer, parameter :: max_2d_fourier_modes = 10 !< Max Fourier mode index for 2D modal patch (geometry 13) - integer, parameter :: max_sph_harm_degree = 5 !< Max degree L for 3D spherical harmonic patch (geometry 14) - integer, parameter :: pathlen_max = 400 !< Maximum path length for STL/OBJ model files - integer, parameter :: nnode = 4 !< Number of QBMM nodes - integer, parameter :: dflt_num_igr_iters = 2 !< number of iterations for IGR elliptic solve - integer, parameter :: dflt_num_igr_warm_start_iters = 50 !< default number of iterations for IGR elliptic solve - real(wp), parameter :: dflt_alf_factor = 10._wp !< scaling factor for IGR alpha - integer, parameter :: gp_layers = 3 !< Number of ghost point layers for IBM - !> color function gradient magnitude at which to apply the surface tension fluxes - real(wp), parameter :: capillary_cutoff = 1.e-6 - !> Spatial support width of acoustic source, used in s_source_spatial - real(wp), parameter :: acoustic_spatial_support_width = 2.5_wp - real(wp), parameter :: dflt_vcfl_dt = 100._wp !< value of vcfl_dt when viscosity is off for computing adaptive timestep size - !> The constant to scale the spectral level at the lower frequency bound - real(wp), parameter :: broadband_spectral_level_constant = 20._wp - !> The spectral level constant to correct the magnitude at each frequency to ensure the source is overall broadband - real(wp), parameter :: broadband_spectral_level_growth_rate = 10._wp + character, parameter :: dflt_char = ' ' !< Default string value + + real(wp), parameter :: dflt_real = -1.e6_wp !< Default real value + real(wp), parameter :: sgm_eps = 1.e-16_wp !< Segmentation tolerance + real(wp), parameter :: Chem_Tolerance = 1.e-16_wp !< Speed of Sound Tolerance in Chemistry + real(wp), parameter :: small_alf = 1.e-11_wp !< Small alf tolerance + real(wp), parameter :: pi = 3.141592653589793_wp !< Pi + real(wp), parameter :: verysmall = 1.e-12_wp !< Very small number + real(wp), parameter :: small_radius = 1.e-32_wp !< Radius cutoff to avoid division by zero for 3D spherical harmonic patch (geometry 14) + + integer, parameter :: num_stcls_min = 5 !< Minimum # of stencils + integer, parameter :: path_len = 400 !< Maximum path length + integer, parameter :: name_len = 50 !< Maximum name length + integer, parameter :: dflt_int = -100 !< Default integer value + integer, parameter :: fourier_rings = 5 !< Fourier filter ring limit + integer, parameter :: num_fluids_max = 10 !< Maximum number of fluids in the simulation + integer, parameter :: num_probes_max = 10 !< Maximum number of flow probes in the simulation + integer, parameter :: num_patches_max = 1000 + integer, parameter :: num_bc_patches_max = 10 + integer, parameter :: max_2d_fourier_modes = 10 !< Max Fourier mode index for 2D modal patch (geometry 13) + integer, parameter :: max_sph_harm_degree = 5 !< Max degree L for 3D spherical harmonic patch (geometry 14) + integer, parameter :: pathlen_max = 400 + integer, parameter :: nnode = 4 !< Number of QBMM nodes + integer, parameter :: dflt_num_igr_iters = 2 !< number of iterations for IGR elliptic solve + integer, parameter :: dflt_num_igr_warm_start_iters = 50 !< default number of iterations for IGR elliptic solve + real(wp), parameter :: dflt_alf_factor = 10._wp !< scaling factor for IGR alpha + integer, parameter :: gp_layers = 3 !< Number of ghost point layers for IBM + real(wp), parameter :: capillary_cutoff = 1.e-6 !< color function gradient magnitude at which to apply the surface tension fluxes + real(wp), parameter :: acoustic_spatial_support_width = 2.5_wp !< Spatial support width of acoustic source, used in s_source_spatial + real(wp), parameter :: dflt_vcfl_dt = 100._wp !< value of vcfl_dt when viscosity is off for computing adaptive timestep size + real(wp), parameter :: broadband_spectral_level_constant = 20._wp !< The constant to scale the spectral level at the lower frequency bound + real(wp), parameter :: broadband_spectral_level_growth_rate = 10._wp !< The spectral level constant to correct the magnitude at each frequency to ensure the source is overall broadband + ! Reconstruction Types - integer, parameter :: WENO_TYPE = 1 !< Using WENO for reconstruction type - integer, parameter :: MUSCL_TYPE = 2 !< Using MUSCL for reconstruction type + integer, parameter :: WENO_TYPE = 1 !< Using WENO for reconstruction type + integer, parameter :: MUSCL_TYPE = 2 !< Using MUSCL for reconstruction type + ! Interface Compression - real(wp), parameter :: dflt_ic_eps = 1e-4_wp !< Ensure compression is only applied to surface cells in THINC - real(wp), parameter :: dflt_ic_beta = 1.6_wp !< Sharpness parameter's default value used in THINC - real(wp), parameter :: moncon_cutoff = 1e-8_wp !< Monotonicity constraint's limiter to prevent extremas in THINC + real(wp), parameter :: dflt_ic_eps = 1e-4_wp !< Ensure compression is only applied to surface cells in THINC + real(wp), parameter :: dflt_ic_beta = 1.6_wp !< Sharpness parameter's default value used in THINC + real(wp), parameter :: moncon_cutoff = 1e-8_wp !< Monotonicity constraint's limiter to prevent extremas in THINC + ! Chemistry - real(wp), parameter :: dflt_T_guess = 1200._wp !< Default guess for temperature (when a previous value is not available) + real(wp), parameter :: dflt_T_guess = 1200._wp ! Default guess for temperature (when a previous value is not available) ! IBM+STL interpolation constants - integer, parameter :: num_ray = 20 !< Default number of rays traced per cell - real(wp), parameter :: ray_tracing_threshold = 0.9_wp !< Threshold above which the cell is marked as the model patch - real(wp), parameter :: threshold_vector_zero = 1.e-10_wp !< Threshold to treat the component of a vector to be zero - real(wp), parameter :: threshold_edge_zero = 1.e-10_wp !< Threshold to treat two edges to be overlapped - real(wp), parameter :: initial_distance_buffer = 1.e12_wp !< Initialized levelset distance for the shortest path pair algorithm + integer, parameter :: num_ray = 20 !< Default number of rays traced per cell + real(wp), parameter :: ray_tracing_threshold = 0.9_wp !< Threshold above which the cell is marked as the model patch + real(wp), parameter :: threshold_vector_zero = 1.e-10_wp !< Threshold to treat the component of a vector to be zero + real(wp), parameter :: threshold_edge_zero = 1.e-10_wp !< Threshold to treat two edges to be overlapped + real(wp), parameter :: initial_distance_buffer = 1.e12_wp !< Initialized levelset distance for the shortest path pair algorithm + ! Lagrange bubbles constants - integer, parameter :: mapCells = 3 !< Number of cells around the bubble where the smoothening function will have effect - real(wp), parameter :: R_uni = 8314._wp !< Universal gas constant - J/kmol/K - integer, parameter :: lag_io_vars = 21 !< Number of variables per particle for MPI_IO + integer, parameter :: mapCells = 3 !< Number of cells around the bubble where the smoothening function will have effect + integer, parameter :: beta_vars(1:3) = [1, 2, 5] !< q_beta indices to communicate: 1=void fraction, 2=d(beta)/dt, 5=energy source + real(wp), parameter :: R_uni = 8314._wp !< Universal gas constant - J/kmol/K + integer, parameter :: lag_io_vars = 21 !< Number of variables per particle for MPI_IO ! Strang Splitting constants - real(wp), parameter :: dflt_adap_dt_tol = 1.e-4_wp !< Default tolerance for adaptive step size - integer, parameter :: dflt_adap_dt_max_iters = 100 !< Default max iteration for adaptive step size - ! Constants of the algorithm described by Heirer, E. Hairer, S. P.Norsett, G. Wanner, Solving Ordinary Differential Equations I, - ! Chapter II.4 to choose the initial time step size for the adaptive time stepping routine - real(wp), parameter :: threshold_first_guess = 1.e-5_wp !< Threshold for initial step size estimate - real(wp), parameter :: threshold_second_guess = 1.e-15_wp !< Threshold for refined step size estimate - real(wp), parameter :: scale_first_guess = 1.e-3_wp !< Scale factor for initial step size - real(wp), parameter :: scale_guess = 1.e-2_wp !< Scale factor for step size adjustment - real(wp), parameter :: small_guess = 1.e-6_wp !< Minimum initial step size + real(wp), parameter :: dflt_adap_dt_tol = 1.e-4_wp !< Default tolerance for adaptive step size + integer, parameter :: dflt_adap_dt_max_iters = 100 !< Default max iteration for adaptive step size + + ! Constants of the algorithm described by Heirer, E. Hairer, S. P.Nørsett, G. Wanner, Solving Ordinary Differential Equations I, Chapter II.4 + ! to choose the initial time step size for the adaptive time stepping routine + real(wp), parameter :: threshold_first_guess = 1.e-5_wp + real(wp), parameter :: threshold_second_guess = 1.e-15_wp + real(wp), parameter :: scale_first_guess = 1.e-3_wp + real(wp), parameter :: scale_guess = 1.e-2_wp + real(wp), parameter :: small_guess = 1.e-6_wp ! Relativity - !> Max Newton-Raphson iterations for relativistic primitive recovery integer, parameter :: relativity_cons_to_prim_max_iter = 100 - ! Linear congruential pseudo-random number generator parameters - integer, parameter :: modulus = 2**30 - 1 !< PRNG modulus - integer, parameter :: multiplier = 1664525 !< PRNG multiplier - integer, parameter :: increment = 1013904223 !< PRNG increment - integer, parameter :: amplifier = 3**13 !< PRNG amplifier for mixing - real(wp), parameter :: decimal_trim = 1.e5_wp !< PRNG decimal truncation factor + ! Pseudo-random number generator + integer, parameter :: modulus = 2**30 - 1 + integer, parameter :: multiplier = 1664525 + integer, parameter :: increment = 1013904223 + integer, parameter :: amplifier = 3**13 + real(wp), parameter :: decimal_trim = 1.e5_wp ! System constants - integer, parameter :: CASE_FILE_ERROR_CODE = 22 !< Exit code for case file validation errors + integer, parameter :: CASE_FILE_ERROR_CODE = 22 - ! Boundary condition enumeration Abbreviations CHAR - Characteristic NR - Non-reflecting SUB - subsonic SUP - supersonic FF - - ! Force-free CP - Constant pressure + ! Boundary condition enumeration + ! Abbreviations + ! CHAR - Characteristic + ! NR - Non-reflecting + ! SUB - subsonic + ! SUP - supersonic + ! FF - Force-free + ! CP - Constant pressure integer, parameter :: BC_PERIODIC = -1 integer, parameter :: BC_REFLECTIVE = -2 integer, parameter :: BC_GHOST_EXTRAP = -3 @@ -107,4 +115,5 @@ module m_constants integer, parameter :: BC_SLIP_WALL = -15 integer, parameter :: BC_NO_SLIP_WALL = -16 integer, parameter :: BC_DIRICHLET = -17 + end module m_constants diff --git a/src/common/m_delay_file_access.f90 b/src/common/m_delay_file_access.f90 index 0f154af46c..096bbbb6af 100644 --- a/src/common/m_delay_file_access.f90 +++ b/src/common/m_delay_file_access.f90 @@ -4,29 +4,30 @@ !> @brief Rank-staggered file access delays to prevent I/O contention on parallel file systems module m_delay_file_access - use m_precision_select - implicit none - private public :: DelayFileAccess - integer, private, parameter :: N_PROCESSES_FILE_ACCESS = 128, FILE_ACCESS_DELAY_UNIT = 10000 + integer, private, parameter :: & + N_PROCESSES_FILE_ACCESS = 128, & + FILE_ACCESS_DELAY_UNIT = 10000 contains - !> Introduce a rank-dependent busy-wait delay to stagger parallel file access and reduce I/O contention. + !> @brief Introduces a rank-dependent busy-wait delay to stagger parallel file access and reduce I/O contention. impure subroutine DelayFileAccess(ProcessRank) - integer, intent(in) :: ProcessRank - integer :: iDelay, nFileAccessDelayIterations - real(wp) :: Number, Dummy - nFileAccessDelayIterations = (ProcessRank/N_PROCESSES_FILE_ACCESS)*FILE_ACCESS_DELAY_UNIT + integer :: iDelay, nFileAccessDelayIterations + real(wp) :: Number, Dummy + + nFileAccessDelayIterations & + = (ProcessRank/N_PROCESSES_FILE_ACCESS)*FILE_ACCESS_DELAY_UNIT do iDelay = 1, nFileAccessDelayIterations + ! Wait my turn call random_number(Number) Dummy = Number*Number end do diff --git a/src/common/m_derived_types.fpp b/src/common/m_derived_types.fpp index 0c00de90d7..f4049a75af 100644 --- a/src/common/m_derived_types.fpp +++ b/src/common/m_derived_types.fpp @@ -7,7 +7,8 @@ !> @brief Shared derived types for field data, patch geometry, bubble dynamics, and MPI I/O structures module m_derived_types - use m_constants + use m_constants !< Constants + use m_precision_select use m_thermochem, only: num_species @@ -15,66 +16,66 @@ module m_derived_types !> Derived type adding the field position (fp) as an attribute type field_position - real(stp), allocatable, dimension(:,:,:) :: fp !< Field position + real(stp), allocatable, dimension(:, :, :) :: fp !< Field position end type field_position !> Derived type annexing a scalar field (SF) type scalar_field - real(stp), pointer, dimension(:,:,:) :: sf => null() + real(stp), pointer, dimension(:, :, :) :: sf => null() end type scalar_field !> Derived type for bubble variables pb and mv at quadrature nodes (qbmm) type pres_field - real(stp), pointer, dimension(:,:,:,:,:) :: sf => null() + real(stp), pointer, dimension(:, :, :, :, :) :: sf => null() end type pres_field !> Derived type annexing an integer scalar field (SF) type integer_field #ifdef MFC_MIXED_PRECISION - integer(kind=1), pointer, dimension(:,:,:) :: sf => null() + integer(kind=1), pointer, dimension(:, :, :) :: sf => null() #else - integer, pointer, dimension(:,:,:) :: sf => null() + integer, pointer, dimension(:, :, :) :: sf => null() #endif end type integer_field !> Derived type for levelset type levelset_field - real(stp), pointer, dimension(:,:,:,:) :: sf => null() + real(stp), pointer, dimension(:, :, :, :) :: sf => null() end type levelset_field !> Derived type for levelset norm type levelset_norm_field - real(stp), pointer, dimension(:,:,:,:,:) :: sf => null() + real(stp), pointer, dimension(:, :, :, :, :) :: sf => null() end type levelset_norm_field type mpi_io_var - integer, allocatable, dimension(:) :: view + integer, allocatable, dimension(:) :: view type(scalar_field), allocatable, dimension(:) :: var end type mpi_io_var type mpi_io_ib_var - integer :: view + integer :: view type(integer_field) :: var end type mpi_io_ib_var type mpi_io_levelset_var - integer :: view + integer :: view type(levelset_field) :: var end type mpi_io_levelset_var type mpi_io_levelset_norm_var - integer :: view + integer :: view type(levelset_norm_field) :: var end type mpi_io_levelset_norm_var !> Derived type annexing a vector field (VF) type vector_field - type(scalar_field), allocatable, dimension(:) :: vf !< Vector field + type(scalar_field), allocatable, dimension(:) :: vf !< Vector field end type vector_field - !> Generic 3-component vector (e.g., spatial coordinates or field components) Named _dt (derived types: x,y,z) to differentiate - !! from t_vec3 (3-component vector) - type vec3_dt ! dt for derived types + !> Generic 3-component vector (e.g., spatial coordinates or field components) + !! Named _dt (derived types: x,y,z) to differentiate from t_vec3 (3-component vector) + type vec3_dt ! dt for derived types real(wp) :: x real(wp) :: y real(wp) :: z @@ -94,28 +95,30 @@ module m_derived_types !> Integer bounds for variables type int_bounds_info - integer :: beg - integer :: end - real(wp) :: vb1 - real(wp) :: vb2 - real(wp) :: vb3 - real(wp) :: ve1 - real(wp) :: ve2 - real(wp) :: ve3 - real(wp) :: pres_in, pres_out - real(wp), dimension(3) :: vel_in, vel_out + integer :: beg + integer :: end + + real(wp) :: vb1 + real(wp) :: vb2 + real(wp) :: vb3 + real(wp) :: ve1 + real(wp) :: ve2 + real(wp) :: ve3 + real(wp) :: pres_in, pres_out + real(wp), dimension(3) :: vel_in, vel_out real(wp), dimension(num_fluids_max) :: alpha_rho_in, alpha_in - logical :: grcbc_in, grcbc_out, grcbc_vel_out + logical :: grcbc_in, grcbc_out, grcbc_vel_out + end type int_bounds_info type bc_patch_parameters - integer :: geometry - integer :: type - integer :: dir - integer :: loc + integer :: geometry + integer :: type + integer :: dir + integer :: loc real(wp), dimension(3) :: centroid real(wp), dimension(3) :: length - real(wp) :: radius + real(wp) :: radius end type bc_patch_parameters !> Derived type adding beginning (beg) and end bounds info as attributes @@ -126,265 +129,356 @@ module m_derived_types !> bounds for the bubble dynamic variables type bub_bounds_info - integer :: beg - integer :: end - integer, dimension(:), allocatable :: rs - integer, dimension(:), allocatable :: vs - integer, dimension(:), allocatable :: ps - integer, dimension(:), allocatable :: ms - integer, dimension(:,:), allocatable :: moms !< Moment indices for qbmm - integer, dimension(:,:,:), allocatable :: fullmom !< Moment indices for qbmm + integer :: beg + integer :: end + integer, dimension(:), allocatable :: rs + integer, dimension(:), allocatable :: vs + integer, dimension(:), allocatable :: ps + integer, dimension(:), allocatable :: ms + integer, dimension(:, :), allocatable :: moms !< Moment indices for qbmm + integer, dimension(:, :, :), allocatable :: fullmom !< Moment indices for qbmm end type bub_bounds_info !> Defines parameters for a Model Patch type ic_model_parameters - character(LEN=pathlen_max) :: filepath !< Path the STL file relative to case_dir. - real(wp), dimension(1:3) :: translate !< Translation of the STL object. - real(wp), dimension(1:3) :: scale !< Scale factor for the STL object. - real(wp), dimension(1:3) :: rotate !< Angle to rotate the STL object along each cartesian coordinate axis, in radians. - integer :: spc !< Number of samples per cell to use when discretizing the STL object. - real(wp) :: threshold !< Threshold to turn on smoothen STL patch. + character(LEN=pathlen_max) :: filepath !< + !! Path the STL file relative to case_dir. + + real(wp), dimension(1:3) :: translate !< + !! Translation of the STL object. + + real(wp), dimension(1:3) :: scale !< + !! Scale factor for the STL object. + + real(wp), dimension(1:3) :: rotate !< + !! Angle to rotate the STL object along each cartesian coordinate axis, + !! in radians. + + integer :: spc !< + !! Number of samples per cell to use when discretizing the STL object. + + real(wp) :: threshold !< + !! Threshold to turn on smoothen STL patch. end type ic_model_parameters type :: t_triangle - real(wp), dimension(1:3,1:3) :: v !< Vertices of the triangle - real(wp), dimension(1:3) :: n !< Normal vector + real(wp), dimension(1:3, 1:3) :: v ! Vertices of the triangle + real(wp), dimension(1:3) :: n ! Normal vector end type t_triangle type :: t_ray - real(wp), dimension(1:3) :: o !< Origin - real(wp), dimension(1:3) :: d !< Direction + real(wp), dimension(1:3) :: o ! Origin + real(wp), dimension(1:3) :: d ! Direction end type t_ray type :: t_bbox - real(wp), dimension(1:3) :: min !< Minimum coordinates - real(wp), dimension(1:3) :: max !< Maximum coordinates + real(wp), dimension(1:3) :: min ! Minimum coordinates + real(wp), dimension(1:3) :: max ! Maximum coordinates end type t_bbox type :: t_model - integer :: ntrs !< Number of triangles - type(t_triangle), allocatable :: trs(:) !< Triangles + integer :: ntrs ! Number of triangles + type(t_triangle), allocatable :: trs(:) ! Triangles + end type t_model type :: t_model_array ! Original CPU-side fields (unchanged) - type(t_model), allocatable :: model !< STL/OBJ geometry model - real(wp), allocatable, dimension(:,:,:) :: boundary_v !< Boundary vertices - real(wp), allocatable, dimension(:,:) :: interpolated_boundary_v !< Interpolated boundary vertices - integer :: boundary_edge_count !< Number of boundary edges - integer :: total_vertices !< Total vertex count - integer :: interpolate !< Interpolation flag + type(t_model), allocatable :: model + real(wp), allocatable, dimension(:, :, :) :: boundary_v + real(wp), allocatable, dimension(:, :) :: interpolated_boundary_v + integer :: boundary_edge_count + integer :: total_vertices + integer :: interpolate ! GPU-friendly flattened arrays - integer :: ntrs !< Copy of model%ntrs - real(wp), allocatable, dimension(:,:,:) :: trs_v !< Triangle vertices (3, 3, ntrs) - real(wp), allocatable, dimension(:,:) :: trs_n !< Triangle normals (3, ntrs) + integer :: ntrs ! copy of model%ntrs + real(wp), allocatable, dimension(:, :, :) :: trs_v ! (3, 3, ntrs) - triangle vertices + real(wp), allocatable, dimension(:, :) :: trs_n ! (3, ntrs) - triangle normals end type t_model_array - !> Derived type adding initial condition (ic) patch parameters as attributes NOTE: The requirements for the specification of the - !! above parameters are strongly dependent on both the choice of the multicomponent flow model as well as the choice of the - !! patch geometry. + !> Derived type adding initial condition (ic) patch parameters as attributes + !! NOTE: The requirements for the specification of the above parameters + !! are strongly dependent on both the choice of the multicomponent flow + !! model as well as the choice of the patch geometry. type ic_patch_parameters - integer :: geometry !< Type of geometry for the patch - real(wp) :: x_centroid, y_centroid, z_centroid !< Geometric center coordinates of the patch - real(wp) :: length_x, length_y, length_z !< Dimensions of the patch. x,y,z Lengths. - real(wp) :: radius !< Dimensions of the patch. radius. - real(wp), dimension(3) :: radii !< Elliptical/ellipsoidal patch radii in x, y, z - real(wp) :: epsilon, beta !< The isentropic vortex parameters for the amplitude of the disturbance and domain of influence. - real(wp), dimension(2:9) :: a !< Used by hardcoded IC and as temporary variables. + integer :: geometry !< Type of geometry for the patch + + real(wp) :: x_centroid, y_centroid, z_centroid !< + !! Location of the geometric center, i.e. the centroid, of the patch. It + !! is specified through its x-, y- and z-coordinates, respectively. + + real(wp) :: length_x, length_y, length_z !< Dimensions of the patch. x,y,z Lengths. + real(wp) :: radius !< Dimensions of the patch. radius. + + real(wp), dimension(3) :: radii !< + !! Vector indicating the various radii for the elliptical and ellipsoidal + !! patch geometries. It is specified through its x-, y-, and z-components + !! respectively. + + real(wp) :: epsilon, beta !< + !! The isentropic vortex parameters for the amplitude of the disturbance and + !! domain of influence. + + real(wp), dimension(2:9) :: a !< + !! Used by hardcoded IC and as temporary variables. + logical :: non_axis_sym ! Geometry 13 (2D modal Fourier): fourier_cos(n), fourier_sin(n) for mode n real(wp), dimension(1:max_2d_fourier_modes) :: fourier_cos, fourier_sin - logical :: modal_clip_r_to_min !< When true, clip boundary radius: R(theta) = max(R(theta), modal_r_min) (Non-exp form only) - real(wp) :: modal_r_min !< Minimum boundary radius when modal_clip_r_to_min is true (Non-exp form only) + logical :: modal_clip_r_to_min !< When true, clip boundary radius: R(theta) = max(R(theta), modal_r_min) (Non-exp form only) + real(wp) :: modal_r_min !< Minimum boundary radius when modal_clip_r_to_min is true (Non-exp form only) logical :: modal_use_exp_form !< When true, boundary = radius*exp(Fourier series) + ! Geometry 14 (3D spherical harmonic): sph_har_coeff(l,m) for real Y_lm - real(wp), dimension(0:max_sph_harm_degree,-max_sph_harm_degree:max_sph_harm_degree) :: sph_har_coeff - real(wp), dimension(3) :: normal !< Patch orientation normal vector (x, y, z) - logical, dimension(0:num_patches_max - 1) :: alter_patch !< Overwrite permissions for preceding patches - logical :: smoothen !< Whether patch boundaries are smoothed across cells - integer :: smooth_patch_id !< Identity (id) of the patch with which current patch is to get smoothed - real(wp) :: smooth_coeff !< Smoothing stencil size coefficient + real(wp), dimension(0:max_sph_harm_degree, -max_sph_harm_degree:max_sph_harm_degree) :: sph_har_coeff + + real(wp), dimension(3) :: normal !< + !! Normal vector indicating the orientation of the patch. It is specified + !! through its x-, y- and z-components, respectively. + + logical, dimension(0:num_patches_max - 1) :: alter_patch !< + + !! List of permissions that indicate to the current patch which preceding + !! patches it is allowed to overwrite when it is in process of being laid + !! out in the domain + + logical :: smoothen !< + !! Permission indicating to the current patch whether its boundaries will + !! be smoothed out across a few cells or whether they are to remain sharp + + integer :: smooth_patch_id !< + !! Identity (id) of the patch with which current patch is to get smoothed + + real(wp) :: smooth_coeff !< + !! Smoothing coefficient (coeff) for the size of the stencil of + !! cells across which boundaries of the current patch will be smeared out + real(wp), dimension(num_fluids_max) :: alpha_rho real(wp) :: rho real(wp), dimension(3) :: vel real(wp) :: pres real(wp), dimension(num_fluids_max) :: alpha real(wp) :: gamma - real(wp) :: pi_inf - real(wp) :: cv - real(wp) :: qv - real(wp) :: qvp !< Reference entropy per unit mass (SGEOS) - real(wp) :: Bx, By, Bz !< Magnetic field components; B%x is not used for 1D - real(wp), dimension(6) :: tau_e !< Elastic stresses added to primitive variables if hypoelasticity = True - real(wp) :: R0 !< Bubble size - real(wp) :: V0 !< Bubble velocity - real(wp) :: p0 !< Bubble size - real(wp) :: m0 !< Bubble velocity - integer :: hcid !< Hardcoded initial condition ID - real(wp) :: cf_val !< Color function value - real(wp) :: Y(1:num_species) !< Species mass fractions - - ! STL or OBJ model input parameter - character(LEN=pathlen_max) :: model_filepath !< Path the STL file relative to case_dir. - real(wp), dimension(1:3) :: model_translate !< Translation of the STL object. - real(wp), dimension(1:3) :: model_scale !< Scale factor for the STL object. - !> Angle to rotate the STL object along each cartesian coordinate axis, in radians. - real(wp), dimension(1:3) :: model_rotate - integer :: model_spc !< Number of samples per cell to use when discretizing the STL object. - real(wp) :: model_threshold !< Threshold to turn on smoothen STL patch. + real(wp) :: pi_inf !< + real(wp) :: cv !< + real(wp) :: qv !< + real(wp) :: qvp !< + + !! Primitive variables associated with the patch. In order, these include + !! the partial densities, density, velocity, pressure, volume fractions, + !! specific heat ratio function and the liquid stiffness function. + + real(wp) :: Bx, By, Bz !< + !! Magnetic field components; B%x is not used for 1D + + real(wp), dimension(6) :: tau_e !< + !! Elastic stresses added to primitive variables if hypoelasticity = True + + real(wp) :: R0 !< Bubble size + real(wp) :: V0 !< Bubble velocity + + real(wp) :: p0 !< Bubble size + real(wp) :: m0 !< Bubble velocity + + integer :: hcid + !! id for hard coded initial condition + + real(wp) :: cf_val !! color function value + real(wp) :: Y(1:num_species) + + !! STL or OBJ model input parameter + character(LEN=pathlen_max) :: model_filepath !< + !! Path the STL file relative to case_dir. + + real(wp), dimension(1:3) :: model_translate !< + !! Translation of the STL object. + + real(wp), dimension(1:3) :: model_scale !< + !! Scale factor for the STL object. + + real(wp), dimension(1:3) :: model_rotate !< + !! Angle to rotate the STL object along each cartesian coordinate axis, + !! in radians. + + integer :: model_spc !< + !! Number of samples per cell to use when discretizing the STL object. + + real(wp) :: model_threshold !< + !! Threshold to turn on smoothen STL patch. + end type ic_patch_parameters type ib_patch_parameters - integer :: geometry !< Type of geometry for the patch - real(wp) :: x_centroid, y_centroid, z_centroid !< Geometric center coordinates of the patch - !> Centroid locations of intermediate steps in the time_stepper module - real(wp) :: step_x_centroid, step_y_centroid, step_z_centroid - real(wp), dimension(1:3) :: centroid_offset !< offset of center of mass from computed cell center for odd-shaped IBs + integer :: geometry !< Type of geometry for the patch + + real(wp) :: x_centroid, y_centroid, z_centroid !< + !! Location of the geometric center, i.e. the centroid, of the patch. It + !! is specified through its x-, y- and z-coordinates, respectively. + real(wp) :: step_x_centroid, step_y_centroid, step_z_centroid !< + !! Centroid locations of intermediate steps in the time_stepper module + real(wp), dimension(1:3) :: centroid_offset ! offset of center of mass from computed cell center for odd-shaped IBs + real(wp), dimension(1:3) :: angles real(wp), dimension(1:3) :: step_angles - !> matrix that converts from IB reference frame to fluid reference frame - real(wp), dimension(1:3,1:3) :: rotation_matrix - !> matrix that converts from fluid reference frame to IB reference frame - real(wp), dimension(1:3,1:3) :: rotation_matrix_inverse - real(wp) :: c, p, t, m - real(wp) :: length_x, length_y, length_z !< Dimensions of the patch. x,y,z Lengths. - real(wp) :: radius !< Dimensions of the patch. radius. - real(wp) :: theta - logical :: slip - - ! STL or OBJ model input parameter - character(LEN=pathlen_max) :: model_filepath !< Path the STL file relative to case_dir. - real(wp), dimension(1:3) :: model_translate !< Translation of the STL object. - real(wp), dimension(1:3) :: model_scale !< Scale factor for the STL object. - !> Angle to rotate the STL object along each cartesian coordinate axis, in radians. - real(wp), dimension(1:3) :: model_rotate - integer :: model_spc !< Number of samples per cell to use when discretizing the STL object. - real(wp) :: model_threshold !< Threshold to turn on smoothen STL patch. Patch conditions for moving imersed boundaries - integer :: moving_ibm !< 0 for no moving, 1 for moving, 2 for moving on forced path - real(wp) :: mass, moment !< mass and moment of inertia of object used to compute forces in 2-way coupling - real(wp), dimension(1:3) :: force, torque !< vectors for the computed force and torque values applied to an IB + real(wp), dimension(1:3, 1:3) :: rotation_matrix !< matrix that converts from IB reference frame to fluid reference frame + real(wp), dimension(1:3, 1:3) :: rotation_matrix_inverse !< matrix that converts from fluid reference frame to IB reference frame + + real(wp) :: c, p, t, m + + real(wp) :: length_x, length_y, length_z !< Dimensions of the patch. x,y,z Lengths. + real(wp) :: radius !< Dimensions of the patch. radius. + real(wp) :: theta + + logical :: slip + + !! STL or OBJ model input parameter + character(LEN=pathlen_max) :: model_filepath !< + !! Path the STL file relative to case_dir. + + real(wp), dimension(1:3) :: model_translate !< + !! Translation of the STL object. + + real(wp), dimension(1:3) :: model_scale !< + !! Scale factor for the STL object. + + real(wp), dimension(1:3) :: model_rotate !< + !! Angle to rotate the STL object along each cartesian coordinate axis, + !! in radians. + + integer :: model_spc !< + !! Number of samples per cell to use when discretizing the STL object. + + real(wp) :: model_threshold !< + !! Threshold to turn on smoothen STL patch. + + !! Patch conditions for moving imersed boundaries + integer :: moving_ibm ! 0 for no moving, 1 for moving, 2 for moving on forced path + real(wp) :: mass, moment ! mass and moment of inertia of object used to compute forces in 2-way coupling + real(wp), dimension(1:3) :: force, torque ! vectors for the computed force and torque values applied to an IB real(wp), dimension(1:3) :: vel - real(wp), dimension(1:3) :: step_vel !< velocity array used to store intermediate steps in the time_stepper module + real(wp), dimension(1:3) :: step_vel ! velocity array used to store intermediate steps in the time_stepper module real(wp), dimension(1:3) :: angular_vel - real(wp), dimension(1:3) :: step_angular_vel !< velocity array used to store intermediate steps in the time_stepper module + real(wp), dimension(1:3) :: step_angular_vel ! velocity array used to store intermediate steps in the time_stepper module + end type ib_patch_parameters - !> Derived type annexing the physical parameters (PP) of the fluids. These include the specific heat ratio function and liquid - !! stiffness function. + !> Derived type annexing the physical parameters (PP) of the fluids. These + !! include the specific heat ratio function and liquid stiffness function. type physical_parameters - real(wp) :: gamma !< Sp. heat ratio - real(wp) :: pi_inf !< Liquid stiffness - real(wp), dimension(2) :: Re !< Reynolds number - real(wp) :: cv !< heat capacity - real(wp) :: qv !< reference energy per unit mass for SGEOS, q (see Le Metayer (2004)) - real(wp) :: qvp !< reference entropy per unit mass for SGEOS, q' (see Le Metayer (2004)) - real(wp) :: G + real(wp) :: gamma !< Sp. heat ratio + real(wp) :: pi_inf !< Liquid stiffness + real(wp), dimension(2) :: Re !< Reynolds number + real(wp) :: cv !< heat capacity + real(wp) :: qv !< reference energy per unit mass for SGEOS, q (see Le Metayer (2004)) + real(wp) :: qvp !< reference entropy per unit mass for SGEOS, q' (see Le Metayer (2004)) + real(wp) :: G end type physical_parameters !> Derived type annexing the physical parameters required for sub-grid bubble models type subgrid_bubble_physical_parameters - real(wp) :: R0ref !< reference bubble radius - real(wp) :: p0ref !< reference pressure - real(wp) :: rho0ref !< reference density - real(wp) :: T0ref !< reference temperature - real(wp) :: ss !< surface tension between host and gas (bubble) - real(wp) :: pv !< vapor pressure of host - real(wp) :: vd !< vapor diffusivity in gas (bubble) - real(wp) :: mu_l !< viscosity of host in liquid state - real(wp) :: mu_v !< viscosity of host in vapor state - real(wp) :: mu_g !< viscosity of gas (bubble) - real(wp) :: gam_v !< specific heat ratio of host in vapor state - real(wp) :: gam_g !< specific heat ratio of gas (bubble) - real(wp) :: M_v !< Molecular weight of host - real(wp) :: M_g !< Molecular weight of gas (bubble) - real(wp) :: k_v !< thermal conductivity of host in vapor state - real(wp) :: k_g !< thermal conductivity of gas (bubble) - real(wp) :: cp_v !< specific heat capacity in constant pressure of host in vapor state - real(wp) :: cp_g !< specific heat capacity in constant pressure of gas (bubble) - real(wp) :: R_v !< gas constant of host in vapor state - real(wp) :: R_g !< gas constant of gas (bubble) + real(wp) :: R0ref !< reference bubble radius + real(wp) :: p0ref !< reference pressure + real(wp) :: rho0ref !< reference density + real(wp) :: T0ref !< reference temperature + real(wp) :: ss !< surface tension between host and gas (bubble) + real(wp) :: pv !< vapor pressure of host + real(wp) :: vd !< vapor diffusivity in gas (bubble) + real(wp) :: mu_l !< viscosity of host in liquid state + real(wp) :: mu_v !< viscosity of host in vapor state + real(wp) :: mu_g !< viscosity of gas (bubble) + real(wp) :: gam_v !< specific heat ratio of host in vapor state + real(wp) :: gam_g !< specific heat ratio of gas (bubble) + real(wp) :: M_v !< Molecular weight of host + real(wp) :: M_g !< Molecular weight of gas (bubble) + real(wp) :: k_v !< thermal conductivity of host in vapor state + real(wp) :: k_g !< thermal conductivity of gas (bubble) + real(wp) :: cp_v !< specific heat capacity in constant pressure of host in vapor state + real(wp) :: cp_g !< specific heat capacity in constant pressure of gas (bubble) + real(wp) :: R_v !< gas constant of host in vapor state + real(wp) :: R_g !< gas constant of gas (bubble) end type subgrid_bubble_physical_parameters type mpi_io_airfoil_ib_var - integer, dimension(2) :: view + integer, dimension(2) :: view type(vec3_dt), allocatable, dimension(:) :: var end type mpi_io_airfoil_ib_var !> Derived type annexing integral regions type integral_parameters - real(wp) :: xmin !< Min. boundary first coordinate direction - real(wp) :: xmax !< Max. boundary first coordinate direction - real(wp) :: ymin !< Min. boundary second coordinate direction - real(wp) :: ymax !< Max. boundary second coordinate direction - real(wp) :: zmin !< Min. boundary third coordinate direction - real(wp) :: zmax !< Max. boundary third coordinate direction + real(wp) :: xmin !< Min. boundary first coordinate direction + real(wp) :: xmax !< Max. boundary first coordinate direction + real(wp) :: ymin !< Min. boundary second coordinate direction + real(wp) :: ymax !< Max. boundary second coordinate direction + real(wp) :: zmin !< Min. boundary third coordinate direction + real(wp) :: zmax !< Max. boundary third coordinate direction end type integral_parameters !> Acoustic source parameters type acoustic_parameters - integer :: pulse !< Type of pulse - integer :: support !< Type of support - logical :: dipole !< Whether the source is a dipole or monopole - real(wp), dimension(3) :: loc !< Physical location of acoustic source - real(wp) :: mag !< Acoustic pulse magnitude - real(wp) :: length !< Length of planar source (2D/3D) - real(wp) :: height !< Height of planar source (3D) - real(wp) :: wavelength !< Wave length of pulse - real(wp) :: frequency !< Frequency of pulse - real(wp) :: gauss_sigma_dist !< sigma of Gaussian pulse multiplied by speed of sound - real(wp) :: gauss_sigma_time !< sigma of Gaussian pulse - real(wp) :: npulse !< Number of cycles of pulse - real(wp) :: dir !< Direction of pulse - real(wp) :: delay !< Time-delay of pulse start - real(wp) :: foc_length !< Focal length of transducer - real(wp) :: aperture !< Aperture diameter of transducer - real(wp) :: element_spacing_angle !< Spacing between aperture elements in 2D acoustic array - !> Ratio of aperture element diameter to side length of polygon connecting their centers, in 3D acoustic array - real(wp) :: element_polygon_ratio - real(wp) :: rotate_angle !< Angle of rotation of the entire circular 3D acoustic array - real(wp) :: bb_bandwidth !< Bandwidth of each frequency in broadband wave - real(wp) :: bb_lowest_freq !< The lower frequency bound of broadband wave - integer :: num_elements !< Number of elements in the acoustic array - integer :: element_on !< Element in the acoustic array to turn on - integer :: bb_num_freq !< Number of frequencies in the broadband wave + integer :: pulse !< Type of pulse + integer :: support !< Type of support + logical :: dipole !< Whether the source is a dipole or monopole + real(wp), dimension(3) :: loc !< Physical location of acoustic source + real(wp) :: mag !< Acoustic pulse magnitude + real(wp) :: length !< Length of planar source (2D/3D) + real(wp) :: height !< Height of planar source (3D) + real(wp) :: wavelength !< Wave length of pulse + real(wp) :: frequency !< Frequency of pulse + real(wp) :: gauss_sigma_dist !< sigma of Gaussian pulse multiplied by speed of sound + real(wp) :: gauss_sigma_time !< sigma of Gaussian pulse + real(wp) :: npulse !< Number of cycles of pulse + real(wp) :: dir !< Direction of pulse + real(wp) :: delay !< Time-delay of pulse start + real(wp) :: foc_length ! < Focal length of transducer + real(wp) :: aperture ! < Aperture diameter of transducer + real(wp) :: element_spacing_angle !< Spacing between aperture elements in 2D acoustic array + real(wp) :: element_polygon_ratio !< Ratio of aperture element diameter to side length of polygon connecting their centers, in 3D acoustic array + real(wp) :: rotate_angle !< Angle of rotation of the entire circular 3D acoustic array + real(wp) :: bb_bandwidth !< Bandwidth of each frequency in broadband wave + real(wp) :: bb_lowest_freq !< The lower frequency bound of broadband wave + integer :: num_elements !< Number of elements in the acoustic array + integer :: element_on !< Element in the acoustic array to turn on + integer :: bb_num_freq !< Number of frequencies in the broadband wave end type acoustic_parameters !> Acoustic source source_spatial pre-calculated values type source_spatial_type - integer, pointer, dimension(:,:) :: coord => null() !< List of grid points indices with non-zero source_spatial values - real(wp), pointer, dimension(:) :: val => null() !< List of non-zero source_spatial values - real(wp), pointer, dimension(:) :: angle => null() !< List of angles with x-axis for mom source term vector - real(wp), pointer, dimension(:,:) :: xyz_to_r_ratios => null() !< List of [xyz]/r for mom source term vector + integer, pointer, dimension(:, :) :: coord => null() !< List of grid points indices with non-zero source_spatial values + real(wp), pointer, dimension(:) :: val => null() !< List of non-zero source_spatial values + real(wp), pointer, dimension(:) :: angle => null() !< List of angles with x-axis for mom source term vector + real(wp), pointer, dimension(:, :) :: xyz_to_r_ratios => null() !< List of [xyz]/r for mom source term vector + end type source_spatial_type !> Ghost Point for Immersed Boundaries type ghost_point - integer, dimension(3) :: loc !< Physical location of the ghost point - real(wp), dimension(3) :: ip_loc !< Physical location of the image point - integer, dimension(3) :: ip_grid !< Top left grid point of IP - real(wp), dimension(2, 2, 2) :: interp_coeffs !< Interpolation Coefficients of image point - integer :: ib_patch_id !< ID of the IB Patch the ghost point is part of - real(wp) :: levelset - real(wp), dimension(1:3) :: levelset_norm - logical :: slip - integer, dimension(3) :: DB - integer :: x_periodicity, y_periodicity, z_periodicity + integer, dimension(3) :: loc !< Physical location of the ghost point + real(wp), dimension(3) :: ip_loc !< Physical location of the image point + integer, dimension(3) :: ip_grid !< Top left grid point of IP + real(wp), dimension(2, 2, 2) :: interp_coeffs !< Interpolation Coefficients of image point + integer :: ib_patch_id !< ID of the IB Patch the ghost point is part of + real(wp) :: levelset + real(wp), dimension(1:3) :: levelset_norm + logical :: slip + integer, dimension(3) :: DB + integer :: x_periodicity, y_periodicity, z_periodicity end type ghost_point !> Species parameters type species_parameters - character(LEN=name_len) :: name !< Name of species + character(LEN=name_len) :: name !< Name of species end type species_parameters !> Chemistry parameters type chemistry_parameters - character(LEN=name_len) :: cantera_file !< Path to Cantera file - logical :: diffusion - logical :: reactions + character(LEN=name_len) :: cantera_file !< Path to Cantera file + + logical :: diffusion + logical :: reactions !> Method of determining gamma. !> gamma_method = 1: Ref. Section 2.3.1 Formulation of doi:10.7907/ZKW8-ES97. @@ -396,18 +490,26 @@ module m_derived_types !> Lagrangian bubble parameters type bubbles_lagrange_parameters - integer :: solver_approach !< 1: One-way coupling, 2: two-way coupling - integer :: cluster_type !< Cluster model to find p_inf - logical :: pressure_corrector !< Cell pressure correction term - integer :: smooth_type !< Smoothing function. 1: Gaussian, 2:Delta 3x3 - logical :: heatTransfer_model !< Activate HEAT transfer model at the bubble-liquid interface - logical :: massTransfer_model !< Activate MASS transfer model at the bubble-liquid interface - logical :: write_bubbles !< Write files to track the bubble evolution each time step - logical :: write_bubbles_stats !< Write the maximum and minimum radius of each bubble - integer :: nBubs_glb !< Global number of bubbles - real(wp) :: epsilonb !< Standard deviation scaling for the gaussian function - real(wp) :: charwidth !< Domain virtual depth (z direction, for 2D simulations) - real(wp) :: valmaxvoid !< Maximum void fraction permitted + integer :: solver_approach !< 1: One-way coupling, 2: two-way coupling + integer :: cluster_type !< Cluster model to find p_inf + logical :: pressure_corrector !< Cell pressure correction term + integer :: smooth_type !< Smoothing function. 1: Gaussian, 2:Delta 3x3 + logical :: heatTransfer_model !< Activate HEAT transfer model at the bubble-liquid interface + logical :: massTransfer_model !< Activate MASS transfer model at the bubble-liquid interface + logical :: write_void_evol !< Write files to track evolution of void fraction at each time step + logical :: write_bubbles !< Write files to track the bubble evolution each time step + logical :: write_bubbles_stats !< Write the maximum and minimum radius of each bubble + integer :: nBubs_glb !< Global number of bubbles + integer :: vel_model !< Particle velocity model + integer :: drag_model !< Particle drag model + logical :: pressure_force !< Include pressure force translational motion + logical :: gravity_force !< Include gravity force in translational motion + character(LEN=pathlen_max) :: input_path !< Path to lag_bubbles.dat + real(wp) :: epsilonb !< Standard deviation scaling for the gaussian function + real(wp) :: charwidth !< Domain virtual depth (z direction, for 2D simulations) + integer :: charNz !< Number of grid cells in characteristic depth + real(wp) :: valmaxvoid !< Maximum void fraction permitted + end type bubbles_lagrange_parameters !> Max and min number of cells in a direction of each combination of x-,y-, and z- @@ -417,13 +519,16 @@ module m_derived_types end type cell_num_bounds type simplex_noise_params - logical, dimension(3) :: perturb_vel - real(wp), dimension(3) :: perturb_vel_freq - real(wp), dimension(3) :: perturb_vel_scale - real(wp), dimension(3, 3) :: perturb_vel_offset - logical, dimension(1:num_fluids_max) :: perturb_dens - real(wp), dimension(1:num_fluids_max) :: perturb_dens_freq - real(wp), dimension(1:num_fluids_max) :: perturb_dens_scale - real(wp), dimension(1:num_fluids_max,3) :: perturb_dens_offset - end type simplex_noise_params + logical, dimension(3) :: perturb_vel + real(wp), dimension(3) :: perturb_vel_freq + real(wp), dimension(3) :: perturb_vel_scale + real(wp), dimension(3, 3) :: perturb_vel_offset + + logical, dimension(1:num_fluids_max) :: perturb_dens + real(wp), dimension(1:num_fluids_max) :: perturb_dens_freq + real(wp), dimension(1:num_fluids_max) :: perturb_dens_scale + real(wp), dimension(1:num_fluids_max, 3) :: perturb_dens_offset + end type + end module m_derived_types + diff --git a/src/common/m_finite_differences.fpp b/src/common/m_finite_differences.fpp index f26c203dcd..e44b6905c0 100644 --- a/src/common/m_finite_differences.fpp +++ b/src/common/m_finite_differences.fpp @@ -13,56 +13,51 @@ module m_finite_differences contains - !> Accumulate the finite-difference divergence of a vector field onto a scalar field. subroutine s_compute_fd_divergence(div, fields, ix_s, iy_s, iz_s) - type(scalar_field), intent(inout) :: div - type(scalar_field), intent(in) :: fields(1:3) - type(int_bounds_info), intent(in) :: ix_s, iy_s, iz_s - integer :: x, y, z !< Generic loop iterators - real(wp) :: divergence + type(scalar_field), intent(INOUT) :: div + type(scalar_field), intent(IN) :: fields(1:3) + type(int_bounds_info), intent(IN) :: ix_s, iy_s, iz_s - $:GPU_PARALLEL_LOOP(collapse=3, private='[x, y, z, divergence]') + integer :: x, y, z !< Generic loop iterators + + real(wp) :: divergence + + $:GPU_PARALLEL_LOOP(collapse=3, private='[x,y,z,divergence]') do x = ix_s%beg, ix_s%end do y = iy_s%beg, iy_s%end do z = iz_s%beg, iz_s%end + if (x == ix_s%beg) then - divergence = (-3._wp*fields(1)%sf(x, y, z) + 4._wp*fields(1)%sf(x + 1, y, z) - fields(1)%sf(x + 2, y, & - & z))/(x_cc(x + 2) - x_cc(x)) + divergence = (-3._wp*fields(1)%sf(x, y, z) + 4._wp*fields(1)%sf(x + 1, y, z) - fields(1)%sf(x + 2, y, z))/(x_cc(x + 2) - x_cc(x)) else if (x == ix_s%end) then - divergence = (+3._wp*fields(1)%sf(x, y, z) - 4._wp*fields(1)%sf(x - 1, y, z) + fields(1)%sf(x - 2, y, & - & z))/(x_cc(x) - x_cc(x - 2)) + divergence = (+3._wp*fields(1)%sf(x, y, z) - 4._wp*fields(1)%sf(x - 1, y, z) + fields(1)%sf(x - 2, y, z))/(x_cc(x) - x_cc(x - 2)) else divergence = (fields(1)%sf(x + 1, y, z) - fields(1)%sf(x - 1, y, z))/(x_cc(x + 1) - x_cc(x - 1)) end if if (n > 0) then if (y == iy_s%beg) then - divergence = divergence + (-3._wp*fields(2)%sf(x, y, z) + 4._wp*fields(2)%sf(x, y + 1, & - & z) - fields(2)%sf(x, y + 2, z))/(y_cc(y + 2) - y_cc(y)) + divergence = divergence + (-3._wp*fields(2)%sf(x, y, z) + 4._wp*fields(2)%sf(x, y + 1, z) - fields(2)%sf(x, y + 2, z))/(y_cc(y + 2) - y_cc(y)) else if (y == iy_s%end) then - divergence = divergence + (+3._wp*fields(2)%sf(x, y, z) - 4._wp*fields(2)%sf(x, y - 1, & - & z) + fields(2)%sf(x, y - 2, z))/(y_cc(y) - y_cc(y - 2)) + divergence = divergence + (+3._wp*fields(2)%sf(x, y, z) - 4._wp*fields(2)%sf(x, y - 1, z) + fields(2)%sf(x, y - 2, z))/(y_cc(y) - y_cc(y - 2)) else - divergence = divergence + (fields(2)%sf(x, y + 1, z) - fields(2)%sf(x, y - 1, & - & z))/(y_cc(y + 1) - y_cc(y - 1)) + divergence = divergence + (fields(2)%sf(x, y + 1, z) - fields(2)%sf(x, y - 1, z))/(y_cc(y + 1) - y_cc(y - 1)) end if end if if (p > 0) then if (z == iz_s%beg) then - divergence = divergence + (-3._wp*fields(3)%sf(x, y, z) + 4._wp*fields(3)%sf(x, y, & - & z + 1) - fields(3)%sf(x, y, z + 2))/(z_cc(z + 2) - z_cc(z)) + divergence = divergence + (-3._wp*fields(3)%sf(x, y, z) + 4._wp*fields(3)%sf(x, y, z + 1) - fields(3)%sf(x, y, z + 2))/(z_cc(z + 2) - z_cc(z)) else if (z == iz_s%end) then - divergence = divergence + (+3._wp*fields(3)%sf(x, y, z) - 4._wp*fields(3)%sf(x, y, & - & z - 1) + fields(3)%sf(x, y, z - 2))/(z_cc(z) - z_cc(z - 2)) + divergence = divergence + (+3._wp*fields(3)%sf(x, y, z) - 4._wp*fields(3)%sf(x, y, z - 1) + fields(3)%sf(x, y, z - 2))/(z_cc(z) - z_cc(z - 2)) else - divergence = divergence + (fields(3)%sf(x, y, z + 1) - fields(3)%sf(x, y, & - & z - 1))/(z_cc(z + 1) - z_cc(z - 1)) + divergence = divergence + (fields(3)%sf(x, y, z + 1) - fields(3)%sf(x, y, z - 1))/(z_cc(z + 1) - z_cc(z - 1)) end if end if div%sf(x, y, z) = div%sf(x, y, z) + divergence + end do end do end do @@ -70,21 +65,34 @@ contains end subroutine s_compute_fd_divergence - !> Compute the centered finite-difference coefficients for first-order spatial derivatives in the s-coordinate direction (x, y, - !! or z). Supports up to 4th order accuracy. - !! @param fd_coeff_s Finite-diff. coefficients in the s-coordinate direction - !! @param fd_number_in Finite-difference number - !! @param fd_order_in Finite-difference order of accuracy - !! @param offset_s Optional offset bounds in the s-coordinate direction - subroutine s_compute_finite_difference_coefficients(q, s_cc, fd_coeff_s, local_buff_size, fd_number_in, fd_order_in, offset_s) - - integer :: lB, lE !< loop bounds - integer, intent(in) :: q - integer, intent(in) :: local_buff_size, fd_number_in, fd_order_in - type(int_bounds_info), optional, intent(in) :: offset_s - real(wp), allocatable, dimension(:,:), intent(inout) :: fd_coeff_s - real(wp), dimension(-local_buff_size:q + local_buff_size), intent(in) :: s_cc - integer :: i !< Generic loop iterator + !> The purpose of this subroutine is to compute the finite- + !! difference coefficients for the centered schemes utilized + !! in computations of first order spatial derivatives in the + !! s-coordinate direction. The s-coordinate direction refers + !! to the x-, y- or z-coordinate direction, depending on the + !! subroutine's inputs. Note that coefficients of up to 4th + !! order accuracy are available. + !! @param q Number of cells in the s-coordinate direction + !! @param s_cc Locations of the cell-centers in the s-coordinate direction + !! @param fd_coeff_s Finite-diff. coefficients in the s-coordinate direction + !! @param local_buff_size Size of the local buffer + !! @param fd_number_in Finite-difference number + !! @param fd_order_in Finite-difference order of accuracy + !! @param offset_s Optional offset bounds in the s-coordinate direction + subroutine s_compute_finite_difference_coefficients(q, s_cc, fd_coeff_s, local_buff_size, & + fd_number_in, fd_order_in, offset_s) + + integer :: lB, lE !< loop bounds + integer, intent(IN) :: q + integer, intent(IN) :: local_buff_size, fd_number_in, fd_order_in + type(int_bounds_info), optional, intent(IN) :: offset_s + real(wp), allocatable, dimension(:, :), intent(INOUT) :: fd_coeff_s + + real(wp), & + dimension(-local_buff_size:q + local_buff_size), & + intent(IN) :: s_cc + + integer :: i !< Generic loop iterator if (present(offset_s)) then lB = -offset_s%beg @@ -96,7 +104,7 @@ contains #ifdef MFC_POST_PROCESS if (allocated(fd_coeff_s)) deallocate (fd_coeff_s) - allocate (fd_coeff_s(-fd_number_in:fd_number_in,lb:lE)) + allocate (fd_coeff_s(-fd_number_in:fd_number_in, lb:lE)) #endif ! Computing the 1st order finite-difference coefficients @@ -108,7 +116,7 @@ contains end do ! Computing the 2nd order finite-difference coefficients - else if (fd_order_in == 2) then + elseif (fd_order_in == 2) then do i = lB, lE fd_coeff_s(-1, i) = -1._wp/(s_cc(i + 1) - s_cc(i - 1)) fd_coeff_s(0, i) = 0._wp @@ -124,8 +132,10 @@ contains fd_coeff_s(1, i) = -fd_coeff_s(-1, i) fd_coeff_s(2, i) = -fd_coeff_s(-2, i) end do + end if end subroutine s_compute_finite_difference_coefficients end module m_finite_differences + diff --git a/src/common/m_helper.fpp b/src/common/m_helper.fpp index 4074530a8f..1941d119ec 100644 --- a/src/common/m_helper.fpp +++ b/src/common/m_helper.fpp @@ -8,58 +8,86 @@ !> @brief Utility routines for bubble model setup, coordinate transforms, array sampling, and special functions module m_helper - use m_derived_types - use m_global_parameters - use ieee_arithmetic !< For checking NaN + use m_derived_types !< Definitions of the derived types + + use m_global_parameters !< Definitions of the global parameters + + use ieee_arithmetic !< For checking NaN implicit none - private - public :: s_comp_n_from_prim, s_comp_n_from_cons, s_initialize_bubbles_model, s_initialize_nonpoly, s_simpson, s_transcoeff, & - & s_int_to_str, s_transform_vec, s_transform_triangle, s_transform_model, s_swap, f_cross, f_create_transform_matrix, & - & f_create_bbox, s_print_2D_array, f_xor, f_logical_to_int, associated_legendre, real_ylm, double_factorial, factorial, & - & f_cut_on, f_cut_off, s_downsample_data, s_upsample_data + private; + public :: s_comp_n_from_prim, & + s_comp_n_from_cons, & + s_initialize_bubbles_model, & + s_initialize_nonpoly, & + s_simpson, & + s_transcoeff, & + s_int_to_str, & + s_transform_vec, & + s_transform_triangle, & + s_transform_model, & + s_swap, & + f_cross, & + f_create_transform_matrix, & + f_create_bbox, & + s_print_2D_array, & + f_xor, & + f_logical_to_int, & + associated_legendre, & + real_ylm, & + double_factorial, & + factorial, & + f_cut_on, & + f_cut_off, & + s_downsample_data, & + s_upsample_data contains !> Computes the bubble number density n from the primitive variables + !! @param vftmp is the void fraction + !! @param Rtmp is the bubble radii + !! @param ntmp is the output number bubble density + !! @param weights is the quadrature weights subroutine s_comp_n_from_prim(vftmp, Rtmp, ntmp, weights) - $:GPU_ROUTINE(parallelism='[seq]') - real(wp), intent(in) :: vftmp + real(wp), intent(in) :: vftmp real(wp), dimension(nb), intent(in) :: Rtmp - real(wp), intent(out) :: ntmp + real(wp), intent(out) :: ntmp real(wp), dimension(nb), intent(in) :: weights - real(wp) :: R3 + + real(wp) :: R3 R3 = dot_product(weights, Rtmp**3._wp) ntmp = (3._wp/(4._wp*pi))*vftmp/R3 end subroutine s_comp_n_from_prim - !> Compute the bubble number density from the conservative void fraction and weighted bubble radii. + !> @brief Computes the bubble number density from the conservative void fraction and weighted bubble radii. subroutine s_comp_n_from_cons(vftmp, nRtmp, ntmp, weights) - $:GPU_ROUTINE(parallelism='[seq]') - real(wp), intent(in) :: vftmp + real(wp), intent(in) :: vftmp real(wp), dimension(nb), intent(in) :: nRtmp - real(wp), intent(out) :: ntmp + real(wp), intent(out) :: ntmp real(wp), dimension(nb), intent(in) :: weights - real(wp) :: nR3 + + real(wp) :: nR3 nR3 = dot_product(weights, nRtmp**3._wp) ntmp = sqrt((4._wp*pi/3._wp)*nR3/vftmp) end subroutine s_comp_n_from_cons - !> Print a 2D real array to standard output, optionally dividing each element by a given scalar. + !> @brief Prints a 2D real array to standard output, optionally dividing each element by a given scalar. impure subroutine s_print_2D_array(A, div) - real(wp), dimension(:,:), intent(in) :: A - real(wp), optional, intent(in) :: div - integer :: i, j - integer :: local_m, local_n - real(wp) :: c + real(wp), dimension(:, :), intent(in) :: A + real(wp), optional, intent(in) :: div + + integer :: i, j + integer :: local_m, local_n + real(wp) :: c local_m = size(A, 1) local_n = size(A, 2) @@ -82,7 +110,10 @@ contains end subroutine s_print_2D_array - !> Initialize bubble model arrays for Euler or Lagrangian bubbles with polytropic or non-polytropic gas. + !> + !! bubbles_euler + polytropic + !! bubbles_euler + non-polytropic + !! bubbles_lagrange + non-polytropic impure subroutine s_initialize_bubbles_model() ! Allocate memory @@ -112,11 +143,11 @@ contains end subroutine s_initialize_bubbles_model - !> Set bubble physical parameters and nondimensional numbers from the input configuration. + !> impure subroutine s_initialize_bubble_vars() R0ref = bub_pp%R0ref; p0ref = bub_pp%p0ref - rho0ref = bub_pp%rho0ref + rho0ref = bub_pp%rho0ref; ss = bub_pp%ss; pv = bub_pp%pv; vd = bub_pp%vd mu_l = bub_pp%mu_l; mu_v = bub_pp%mu_v; mu_g = bub_pp%mu_g gam_v = bub_pp%gam_v; gam_g = bub_pp%gam_g @@ -128,6 +159,7 @@ contains R_v = bub_pp%R_v; R_g = bub_pp%R_g Tw = bub_pp%T0ref end if + if (bubbles_lagrange) then cp_v = bub_pp%cp_v; cp_g = bub_pp%cp_g k_vl = bub_pp%k_v; k_gl = bub_pp%k_g @@ -167,29 +199,34 @@ contains !> Initializes non-polydisperse bubble modeling impure subroutine s_initialize_nonpoly() - - integer :: ir + integer :: ir real(wp), dimension(nb) :: chi_vw0, cp_m0, k_m0, rho_m0, x_vw, omegaN, rhol0 - real(wp), parameter :: k_poly = 1._wp !< polytropic index used to compute isothermal natural frequency - ! Chapman-Enskog transport coefficients for vapor-gas mixture, Ando JAS (2010) - phi_vg = (1._wp + sqrt(mu_v/mu_g)*(M_g/M_v)**(0.25_wp))**2/(sqrt(8._wp)*sqrt(1._wp + M_v/M_g)) - phi_gv = (1._wp + sqrt(mu_g/mu_v)*(M_v/M_g)**(0.25_wp))**2/(sqrt(8._wp)*sqrt(1._wp + M_g/M_v)) + real(wp), parameter :: k_poly = 1._wp !< + !! polytropic index used to compute isothermal natural frequency + + ! phi_vg & phi_gv (phi_gg = phi_vv = 1) (Eq. 2.22 in Ando 2010) + phi_vg = (1._wp + sqrt(mu_v/mu_g)*(M_g/M_v)**(0.25_wp))**2 & + /(sqrt(8._wp)*sqrt(1._wp + M_v/M_g)) + phi_gv = (1._wp + sqrt(mu_g/mu_v)*(M_v/M_g)**(0.25_wp))**2 & + /(sqrt(8._wp)*sqrt(1._wp + M_g/M_v)) - ! Initial internal bubble pressure (Euler number + Laplace pressure) + ! internal bubble pressure pb0 = Eu + 2._wp/Web/R0 - ! Vapor mass fraction at bubble wall, Ando JAS (2010) + ! mass fraction of vapor (Eq. 2.19 in Ando 2010) chi_vw0 = 1._wp/(1._wp + R_v/R_g*(pb0/pv - 1._wp)) - ! Mixture specific heat from mass-weighted vapor/gas contributions - cp_m0 = chi_vw0*R_v*gam_v/(gam_v - 1._wp) + (1._wp - chi_vw0)*R_g*gam_g/(gam_g - 1._wp) + ! specific heat for gas/vapor mixture + cp_m0 = chi_vw0*R_v*gam_v/(gam_v - 1._wp) & + + (1._wp - chi_vw0)*R_g*gam_g/(gam_g - 1._wp) ! mole fraction of vapor (Eq. 2.23 in Ando 2010) x_vw = M_g*chi_vw0/(M_v + (M_g - M_v)*chi_vw0) ! thermal conductivity for gas/vapor mixture (Eq. 2.21 in Ando 2010) - k_m0 = x_vw*k_v/(x_vw + (1._wp - x_vw)*phi_vg) + (1._wp - x_vw)*k_g/(x_vw*phi_gv + 1._wp - x_vw) + k_m0 = x_vw*k_v/(x_vw + (1._wp - x_vw)*phi_vg) & + + (1._wp - x_vw)*k_g/(x_vw*phi_gv + 1._wp - x_vw) k_g(:) = k_g(:)/k_m0(:) k_v(:) = k_v(:)/k_m0(:) @@ -203,44 +240,50 @@ contains ! Peclet numbers Pe_T(:) = rho_m0*cp_m0(:)/k_m0(:) - ! Bubble natural frequency, Ando JAS (2010) + ! natural frequencies (Eq. B.1) omegaN(:) = sqrt(3._wp*k_poly*Ca + 2._wp*(3._wp*k_poly - 1._wp)/(Web*R0))/R0/sqrt(rho0ref) do ir = 1, nb - call s_transcoeff(omegaN(ir)*R0(ir), Pe_T(ir)*R0(ir), Re_trans_T(ir), Im_trans_T(ir)) - call s_transcoeff(omegaN(ir)*R0(ir), Pe_c*R0(ir), Re_trans_c(ir), Im_trans_c(ir)) + call s_transcoeff(omegaN(ir)*R0(ir), Pe_T(ir)*R0(ir), & + Re_trans_T(ir), Im_trans_T(ir)) + call s_transcoeff(omegaN(ir)*R0(ir), Pe_c*R0(ir), & + Re_trans_c(ir), Im_trans_c(ir)) end do Im_trans_T = 0._wp end subroutine s_initialize_nonpoly !> Computes the transfer coefficient for the non-polytropic bubble compression process + !! @param omega natural frequencies + !! @param peclet Peclet number + !! @param Re_trans Real part of the transport coefficients + !! @param Im_trans Imaginary part of the transport coefficients elemental subroutine s_transcoeff(omega, peclet, Re_trans, Im_trans) - real(wp), intent(in) :: omega, peclet + real(wp), intent(in) :: omega, peclet real(wp), intent(out) :: Re_trans, Im_trans - complex(wp) :: imag, trans, c1, c2, c3 + + complex(wp) :: imag, trans, c1, c2, c3 imag = (0._wp, 1._wp) c1 = imag*omega*peclet c2 = sqrt(c1) - c3 = (exp(c2) - exp(-c2))/(exp(c2) + exp(-c2)) ! TANH(c2) - trans = ((c2/c3 - 1._wp)**(-1) - 3._wp/c1)**(-1) ! transfer function + c3 = (exp(c2) - exp(-c2))/(exp(c2) + exp(-c2)) ! TANH(c2) + trans = ((c2/c3 - 1._wp)**(-1) - 3._wp/c1)**(-1) ! transfer function Re_trans = trans Im_trans = aimag(trans) end subroutine s_transcoeff - !> Convert an integer to its trimmed string representation. + !> @brief Converts an integer to its trimmed string representation. elemental subroutine s_int_to_str(i, res) - integer, intent(in) :: i + integer, intent(in) :: i character(len=*), intent(inout) :: res write (res, '(I0)') i res = trim(res) - end subroutine s_int_to_str !> Computes the Simpson weights for quadrature @@ -248,9 +291,9 @@ contains real(wp), dimension(:), intent(inout) :: local_weight real(wp), dimension(:), intent(inout) :: local_R0 - integer :: ir - real(wp) :: R0mn, R0mx, dphi, tmp, sd - real(wp), dimension(nb) :: phi + integer :: ir + real(wp) :: R0mn, R0mx, dphi, tmp, sd + real(wp), dimension(nb) :: phi sd = poly_sigma R0mn = 0.8_wp*exp(-2.8_wp*sd) @@ -258,7 +301,8 @@ contains ! phi = ln( R0 ) & return R0 do ir = 1, nb - phi(ir) = log(R0mn) + (ir - 1._wp)*log(R0mx/R0mn)/(nb - 1._wp) + phi(ir) = log(R0mn) & + + (ir - 1._wp)*log(R0mx/R0mn)/(nb - 1._wp) local_R0(ir) = exp(phi(ir)) end do @@ -283,62 +327,89 @@ contains end subroutine s_simpson - !> Compute the cross product of two vectors. + !> This procedure computes the cross product of two vectors. + !! @param a First vector. + !! @param b Second vector. + !! @return The cross product of the two vectors. pure function f_cross(a, b) result(c) $:GPU_ROUTINE(parallelism='[seq]') real(wp), dimension(3), intent(in) :: a, b - real(wp), dimension(3) :: c + real(wp), dimension(3) :: c c(1) = a(2)*b(3) - a(3)*b(2) c(2) = a(3)*b(1) - a(1)*b(3) c(3) = a(1)*b(2) - a(2)*b(1) - end function f_cross - !> Swap two real numbers. + !> This procedure swaps two real numbers. + !! @param lhs Left-hand side. + !! @param rhs Right-hand side. elemental subroutine s_swap(lhs, rhs) real(wp), intent(inout) :: lhs, rhs - real(wp) :: ltemp + real(wp) :: ltemp ltemp = lhs lhs = rhs rhs = ltemp - end subroutine s_swap - !> Create a transformation matrix. + !> This procedure creates a transformation matrix. + !! @param param Parameters for the transformation. + !! @param center Optional center point for the transformation. + !! @return Transformation matrix. function f_create_transform_matrix(param, center) result(out_matrix) - type(ic_model_parameters), intent(in) :: param + type(ic_model_parameters), intent(in) :: param real(wp), dimension(1:3), optional, intent(in) :: center - real(wp), dimension(1:4,1:4) :: sc, rz, rx, ry, tr, t_back, t_to_origin, out_matrix - - sc = transpose(reshape([param%scale(1), 0._wp, 0._wp, 0._wp, 0._wp, param%scale(2), 0._wp, 0._wp, 0._wp, 0._wp, & - & param%scale(3), 0._wp, 0._wp, 0._wp, 0._wp, 1._wp], shape(sc))) - - rz = transpose(reshape([cos(param%rotate(3)), -sin(param%rotate(3)), 0._wp, 0._wp, sin(param%rotate(3)), & - & cos(param%rotate(3)), 0._wp, 0._wp, 0._wp, 0._wp, 1._wp, 0._wp, 0._wp, 0._wp, 0._wp, 1._wp], shape(rz))) - - rx = transpose(reshape([1._wp, 0._wp, 0._wp, 0._wp, 0._wp, cos(param%rotate(1)), -sin(param%rotate(1)), 0._wp, 0._wp, & - & sin(param%rotate(1)), cos(param%rotate(1)), 0._wp, 0._wp, 0._wp, 0._wp, 1._wp], shape(rx))) - - ry = transpose(reshape([cos(param%rotate(2)), 0._wp, sin(param%rotate(2)), 0._wp, 0._wp, 1._wp, 0._wp, 0._wp, & - & -sin(param%rotate(2)), 0._wp, cos(param%rotate(2)), 0._wp, 0._wp, 0._wp, 0._wp, 1._wp], shape(ry))) - - tr = transpose(reshape([1._wp, 0._wp, 0._wp, param%translate(1), 0._wp, 1._wp, 0._wp, param%translate(2), 0._wp, 0._wp, & - & 1._wp, param%translate(3), 0._wp, 0._wp, 0._wp, 1._wp], shape(tr))) + real(wp), dimension(1:4, 1:4) :: sc, rz, rx, ry, tr, t_back, t_to_origin, out_matrix + + sc = transpose(reshape([ & + param%scale(1), 0._wp, 0._wp, 0._wp, & + 0._wp, param%scale(2), 0._wp, 0._wp, & + 0._wp, 0._wp, param%scale(3), 0._wp, & + 0._wp, 0._wp, 0._wp, 1._wp], shape(sc))) + + rz = transpose(reshape([ & + cos(param%rotate(3)), -sin(param%rotate(3)), 0._wp, 0._wp, & + sin(param%rotate(3)), cos(param%rotate(3)), 0._wp, 0._wp, & + 0._wp, 0._wp, 1._wp, 0._wp, & + 0._wp, 0._wp, 0._wp, 1._wp], shape(rz))) + + rx = transpose(reshape([ & + 1._wp, 0._wp, 0._wp, 0._wp, & + 0._wp, cos(param%rotate(1)), -sin(param%rotate(1)), 0._wp, & + 0._wp, sin(param%rotate(1)), cos(param%rotate(1)), 0._wp, & + 0._wp, 0._wp, 0._wp, 1._wp], shape(rx))) + + ry = transpose(reshape([ & + cos(param%rotate(2)), 0._wp, sin(param%rotate(2)), 0._wp, & + 0._wp, 1._wp, 0._wp, 0._wp, & + -sin(param%rotate(2)), 0._wp, cos(param%rotate(2)), 0._wp, & + 0._wp, 0._wp, 0._wp, 1._wp], shape(ry))) + + tr = transpose(reshape([ & + 1._wp, 0._wp, 0._wp, param%translate(1), & + 0._wp, 1._wp, 0._wp, param%translate(2), & + 0._wp, 0._wp, 1._wp, param%translate(3), & + 0._wp, 0._wp, 0._wp, 1._wp], shape(tr))) if (present(center)) then ! Translation matrix to move center to the origin - t_to_origin = transpose(reshape([1._wp, 0._wp, 0._wp, -center(1), 0._wp, 1._wp, 0._wp, -center(2), 0._wp, 0._wp, & - & 1._wp, -center(3), 0._wp, 0._wp, 0._wp, 1._wp], shape(tr))) + t_to_origin = transpose(reshape([ & + 1._wp, 0._wp, 0._wp, -center(1), & + 0._wp, 1._wp, 0._wp, -center(2), & + 0._wp, 0._wp, 1._wp, -center(3), & + 0._wp, 0._wp, 0._wp, 1._wp], shape(tr))) ! Translation matrix to move center back to original position - t_back = transpose(reshape([1._wp, 0._wp, 0._wp, center(1), 0._wp, 1._wp, 0._wp, center(2), 0._wp, 0._wp, 1._wp, & - & center(3), 0._wp, 0._wp, 0._wp, 1._wp], shape(tr))) + t_back = transpose(reshape([ & + 1._wp, 0._wp, 0._wp, center(1), & + 0._wp, 1._wp, 0._wp, center(2), & + 0._wp, 0._wp, 1._wp, center(3), & + 0._wp, 0._wp, 0._wp, 1._wp], shape(tr))) out_matrix = matmul(tr, matmul(t_back, matmul(ry, matmul(rx, matmul(rz, matmul(sc, t_to_origin)))))) else @@ -347,39 +418,50 @@ contains end function f_create_transform_matrix - !> Transform a vector by a matrix. + !> This procedure transforms a vector by a matrix. + !! @param vec Vector to transform. + !! @param matrix Transformation matrix. subroutine s_transform_vec(vec, matrix) - real(wp), dimension(1:3), intent(inout) :: vec - real(wp), dimension(1:4,1:4), intent(in) :: matrix - real(wp), dimension(1:4) :: tmp + real(wp), dimension(1:3), intent(inout) :: vec + real(wp), dimension(1:4, 1:4), intent(in) :: matrix + + real(wp), dimension(1:4) :: tmp tmp = matmul(matrix, [vec(1), vec(2), vec(3), 1._wp]) vec = tmp(1:3) end subroutine s_transform_vec - !> Transform a triangle by a matrix, one vertex at a time. + !> This procedure transforms a triangle by a matrix, one vertex at a time. + !! @param triangle Triangle to transform. + !! @param matrix Transformation matrix. + !! @param matrix_n Normal transformation matrix. subroutine s_transform_triangle(triangle, matrix, matrix_n) - type(t_triangle), intent(inout) :: triangle - real(wp), dimension(1:4,1:4), intent(in) :: matrix, matrix_n - integer :: i + type(t_triangle), intent(inout) :: triangle + real(wp), dimension(1:4, 1:4), intent(in) :: matrix, matrix_n + + integer :: i do i = 1, 3 - call s_transform_vec(triangle%v(i,:), matrix) + call s_transform_vec(triangle%v(i, :), matrix) end do call s_transform_vec(triangle%n(1:3), matrix_n) end subroutine s_transform_triangle - !> Transform a model by a matrix, one triangle at a time. + !> This procedure transforms a model by a matrix, one triangle at a time. + !! @param model Model to transform. + !! @param matrix Transformation matrix. + !! @param matrix_n Normal transformation matrix. subroutine s_transform_model(model, matrix, matrix_n) - type(t_model), intent(inout) :: model - real(wp), dimension(1:4,1:4), intent(in) :: matrix, matrix_n - integer :: i + type(t_model), intent(inout) :: model + real(wp), dimension(1:4, 1:4), intent(in) :: matrix, matrix_n + + integer :: i do i = 1, size(model%trs) call s_transform_triangle(model%trs(i), matrix, matrix_n) @@ -387,12 +469,15 @@ contains end subroutine s_transform_model - !> Create a bounding box for a model. + !> This procedure creates a bounding box for a model. + !! @param model Model to create bounding box for. + !! @return Bounding box. function f_create_bbox(model) result(bbox) type(t_model), intent(in) :: model - type(t_bbox) :: bbox - integer :: i, j + type(t_bbox) :: bbox + + integer :: i, j if (size(model%trs) == 0) then bbox%min = 0._wp @@ -400,50 +485,52 @@ contains return end if - bbox%min = model%trs(1)%v(1,:) - bbox%max = model%trs(1)%v(1,:) + bbox%min = model%trs(1)%v(1, :) + bbox%max = model%trs(1)%v(1, :) do i = 1, size(model%trs) do j = 1, 3 - bbox%min = min(bbox%min, model%trs(i)%v(j,:)) - bbox%max = max(bbox%max, model%trs(i)%v(j,:)) + bbox%min = min(bbox%min, model%trs(i)%v(j, :)) + bbox%max = max(bbox%max, model%trs(i)%v(j, :)) end do end do end function f_create_bbox - !> Perform XOR on lhs and rhs. + !> This procedure performs xor on lhs and rhs. + !! @param lhs logical input. + !! @param rhs other logical input. + !! @return xored result. elemental function f_xor(lhs, rhs) result(res) logical, intent(in) :: lhs, rhs - logical :: res + logical :: res res = (lhs .and. .not. rhs) .or. (.not. lhs .and. rhs) - end function f_xor - !> Convert a logical to 1 or 0. + !> This procedure converts logical to 1 or 0. + !! @param predicate A Logical argument. + !! @return 1 if .true., 0 if .false.. elemental function f_logical_to_int(predicate) result(int) logical, intent(in) :: predicate - integer :: int + integer :: int if (predicate) then int = 1 else int = 0 end if - end function f_logical_to_int - !> Real spherical harmonic Y_lm(theta, phi). theta = polar angle from +z (acos(z/r)), phi = atan2(y,x). Uses associated Legendre - !! P_l^|m|(cos theta). Standard normalisation. + !> Real spherical harmonic Y_lm(theta, phi). theta = polar angle from +z (acos(z/r)), + !! phi = atan2(y,x). Uses associated Legendre P_l^|m|(cos theta). Standard normalisation. function real_ylm(theta, phi, l, m) result(Y) - - integer, intent(in) :: l, m + integer, intent(in) :: l, m real(wp), intent(in) :: theta, phi - real(wp) :: Y, x, prefac - integer :: m_abs + real(wp) :: Y, x, prefac + integer :: m_abs m_abs = abs(m) if (m_abs > l) then @@ -459,24 +546,24 @@ contains else Y = prefac*sqrt(2._wp)*associated_legendre(x, l, m_abs)*sin(m_abs*phi) end if - end function real_ylm - !> Associated Legendre polynomial P_l^m(x) (Ferrers function, Condon-Shortley phase). Valid for integer l >= 0, 0 <= m <= l, and - !! x in [-1,1]. Returns 0 for |m| > l or l < 0. Formulas: DLMF 14.10.3 (recurrence in degree), Wikipedia "Associated Legendre - !! polynomials" (P_l^l and P_l^{l-1} identities). Recurrence: (l-m)P_l^m = (2l-1)x P_{l-1}^m - (l+m-1)P_{l-2}^m. + !> Associated Legendre polynomial P_l^m(x) (Ferrers function, Condon-Shortley phase). + !! Valid for integer l >= 0, 0 <= m <= l, and x in [-1,1]. Returns 0 for |m| > l or l < 0. + !! Formulas: DLMF 14.10.3 (recurrence in degree), Wikipedia "Associated Legendre polynomials" + !! (P_l^l and P_l^{l-1} identities). Recurrence: (l-m)P_l^m = (2l-1)x P_{l-1}^m - (l+m-1)P_{l-2}^m. !! @param x argument (typically cos(theta)), should be in [-1,1] !! @param l degree (>= 0) !! @param m_order order (0 <= m_order <= l) + !! @return result_P P_l^m(x) recursive function associated_legendre(x, l, m_order) result(result_P) - integer, intent(in) :: l, m_order + integer, intent(in) :: l, m_order real(wp), intent(in) :: x - real(wp) :: result_P - real(wp) :: one_minus_x2 + real(wp) :: result_P + real(wp) :: one_minus_x2 ! Out-of-domain: P_l^m = 0 for |m| > l or l < 0 (standard convention) - if (l < 0 .or. m_order < 0 .or. m_order > l) then result_P = 0._wp return @@ -484,75 +571,89 @@ contains if (m_order <= 0 .and. l <= 0) then result_P = 1._wp - else if (l == 1 .and. m_order <= 0) then + elseif (l == 1 .and. m_order <= 0) then result_P = x - else if (l == 1 .and. m_order == 1) then + elseif (l == 1 .and. m_order == 1) then one_minus_x2 = max(0._wp, 1._wp - x**2) result_P = -sqrt(one_minus_x2) - else if (m_order == l) then + elseif (m_order == l) then ! P_l^l(x) = (-1)^l (2l-1)!! (1-x^2)^(l/2). Use real exponent for odd l one_minus_x2 = max(0._wp, 1._wp - x**2) result_P = (-1)**l*real(double_factorial(2*l - 1), wp)*one_minus_x2**(0.5_wp*real(l, wp)) - else if (m_order == l - 1) then + elseif (m_order == l - 1) then result_P = x*(2*l - 1)*associated_legendre(x, l - 1, l - 1) else - result_P = ((2*l - 1)*x*associated_legendre(x, l - 1, m_order) - (l + m_order - 1)*associated_legendre(x, l - 2, & - & m_order))/(l - m_order) + result_P = ((2*l - 1)*x*associated_legendre(x, l - 1, m_order) - (l + m_order - 1)*associated_legendre(x, l - 2, m_order))/(l - m_order) end if end function associated_legendre - !> Calculate the double factorial of an integer + !> This function calculates the double factorial value of an integer + !! @param n_in is the input integer + !! @return R is the double factorial value of n elemental function double_factorial(n_in) result(R_result) - integer, intent(in) :: n_in - integer, parameter :: int64_kind = selected_int_kind(18) !< 18 bytes for 64-bit integer + integer, intent(in) :: n_in + integer, parameter :: int64_kind = selected_int_kind(18) ! 18 bytes for 64-bit integer integer(kind=int64_kind) :: R_result - integer :: i + integer :: i R_result = product((/(i, i=n_in, 1, -2)/)) end function double_factorial - !> Calculate the factorial of an integer + !> The following function calculates the factorial value of an integer + !! @param n_in is the input integer + !! @return R is the factorial value of n elemental function factorial(n_in) result(R_result) - integer, intent(in) :: n_in - integer, parameter :: int64_kind = selected_int_kind(18) !< 18 bytes for 64-bit integer + integer, intent(in) :: n_in + integer, parameter :: int64_kind = selected_int_kind(18) ! 18 bytes for 64-bit integer integer(kind=int64_kind) :: R_result - integer :: i + + integer :: i R_result = product((/(i, i=n_in, 1, -1)/)) end function factorial - !> Calculate a smooth cut-on function that is zero for x values smaller than zero and goes to one, for generating smooth initial - !! conditions + !> This function calculates a smooth cut-on function that is zero for x values + !! smaller than zero and goes to one. It can be used for generating smooth + !! initial conditions + !! @param x is the input value + !! @param eps is the smoothing parameter + !! @return fx is the cut-on function evaluated at x function f_cut_on(x, eps) result(fx) real(wp), intent(in) :: x, eps - real(wp) :: fx + real(wp) :: fx fx = 1 - f_gx(x/eps)/(f_gx(x/eps) + f_gx(1 - x/eps)) end function f_cut_on - !> Calculate a smooth cut-off function that is one for x values smaller than zero and goes to zero, for generating smooth + !> This function calculates a smooth cut-off function that is one for x values + !! smaller than zero and goes to zero. It can be used for generating smooth !! initial conditions + !! @param x is the input value + !! @param eps is the smoothing parameter + !! @return fx is the cut-ff function evaluated at x function f_cut_off(x, eps) result(fx) real(wp), intent(in) :: x, eps - real(wp) :: fx + real(wp) :: fx fx = f_gx(x/eps)/(f_gx(x/eps) + f_gx(1 - x/eps)) end function f_cut_off - !> Helper function for f_cut_on and f_cut_off + !> This function is a helper function for the functions f_cut_on and f_cut_off + !! @param x is the input value + !! @return gx is the result function f_gx(x) result(gx) real(wp), intent(in) :: x - real(wp) :: gx + real(wp) :: gx if (x > 0) then gx = exp(-1._wp/x) @@ -562,14 +663,14 @@ contains end function f_gx - !> Downsample conservative variable fields by a factor of 3 in each direction using volume averaging. + !> @brief Downsamples conservative variable fields by a factor of 3 in each direction using volume averaging. subroutine s_downsample_data(q_cons_vf, q_cons_temp, m_ds, n_ds, p_ds, m_glb_ds, n_glb_ds, p_glb_ds) type(scalar_field), dimension(sys_size), intent(inout) :: q_cons_vf, q_cons_temp ! Down sampling variables - integer :: i, j, k, l - integer :: ix, iy, iz, x_id, y_id, z_id + integer :: i, j, k, l + integer :: ix, iy, iz, x_id, y_id, z_id integer, intent(inout) :: m_ds, n_ds, p_ds, m_glb_ds, n_glb_ds, p_glb_ds m_ds = int((m + 1)/3) - 1 @@ -592,8 +693,8 @@ contains do iz = -1, 1 do iy = -1, 1 do ix = -1, 1 - q_cons_temp(i)%sf(j, k, l) = q_cons_temp(i)%sf(j, k, & - & l) + (1._wp/27._wp)*q_cons_vf(i)%sf(x_id + ix, y_id + iy, z_id + iz) + q_cons_temp(i)%sf(j, k, l) = q_cons_temp(i)%sf(j, k, l) & + + (1._wp/27._wp)*q_cons_vf(i)%sf(x_id + ix, y_id + iy, z_id + iz) end do end do end do @@ -604,19 +705,20 @@ contains end subroutine s_downsample_data - !> Upsample conservative variable fields from a coarsened grid back to the original resolution using interpolation. + !> @brief Upsamples conservative variable fields from a coarsened grid back to the original resolution using interpolation. subroutine s_upsample_data(q_cons_vf, q_cons_temp) type(scalar_field), intent(inout), dimension(sys_size) :: q_cons_vf, q_cons_temp - integer :: i, j, k, l - integer :: ix, iy, iz - integer :: x_id, y_id, z_id - real(wp), dimension(4) :: temp + integer :: i, j, k, l + integer :: ix, iy, iz + integer :: x_id, y_id, z_id + real(wp), dimension(4) :: temp do l = 0, p do k = 0, n do j = 0, m do i = 1, sys_size + ix = int(j/3._wp) iy = int(k/3._wp) iz = int(l/3._wp) @@ -626,17 +728,15 @@ contains z_id = l - int(3*iz) - 1 temp(1) = (2._wp/3._wp)*q_cons_temp(i)%sf(ix, iy, iz) + (1._wp/3._wp)*q_cons_temp(i)%sf(ix + x_id, iy, iz) - temp(2) = (2._wp/3._wp)*q_cons_temp(i)%sf(ix, iy + y_id, iz) + (1._wp/3._wp)*q_cons_temp(i)%sf(ix + x_id, & - & iy + y_id, iz) + temp(2) = (2._wp/3._wp)*q_cons_temp(i)%sf(ix, iy + y_id, iz) + (1._wp/3._wp)*q_cons_temp(i)%sf(ix + x_id, iy + y_id, iz) temp(3) = (2._wp/3._wp)*temp(1) + (1._wp/3._wp)*temp(2) - temp(1) = (2._wp/3._wp)*q_cons_temp(i)%sf(ix, iy, iz + z_id) + (1._wp/3._wp)*q_cons_temp(i)%sf(ix + x_id, & - & iy, iz + z_id) - temp(2) = (2._wp/3._wp)*q_cons_temp(i)%sf(ix, iy + y_id, & - & iz + z_id) + (1._wp/3._wp)*q_cons_temp(i)%sf(ix + x_id, iy + y_id, iz + z_id) + temp(1) = (2._wp/3._wp)*q_cons_temp(i)%sf(ix, iy, iz + z_id) + (1._wp/3._wp)*q_cons_temp(i)%sf(ix + x_id, iy, iz + z_id) + temp(2) = (2._wp/3._wp)*q_cons_temp(i)%sf(ix, iy + y_id, iz + z_id) + (1._wp/3._wp)*q_cons_temp(i)%sf(ix + x_id, iy + y_id, iz + z_id) temp(4) = (2._wp/3._wp)*temp(1) + (1._wp/3._wp)*temp(2) q_cons_vf(i)%sf(j, k, l) = (2._wp/3._wp)*temp(3) + (1._wp/3._wp)*temp(4) + end do end do end do diff --git a/src/common/m_helper_basic.fpp b/src/common/m_helper_basic.fpp index 7208a451da..dcc0a86e69 100644 --- a/src/common/m_helper_basic.fpp +++ b/src/common/m_helper_basic.fpp @@ -7,24 +7,31 @@ !> @brief Basic floating-point utilities: approximate equality, default detection, and coordinate bounds module m_helper_basic - use m_derived_types + use m_derived_types !< Definitions of the derived types implicit none - private - public :: f_approx_equal, f_approx_in_array, f_is_default, f_all_default, f_is_integer, s_configure_coordinate_bounds, & - & s_update_cell_bounds + private; + public :: f_approx_equal, & + f_approx_in_array, & + f_is_default, & + f_all_default, & + f_is_integer, & + s_configure_coordinate_bounds, & + s_update_cell_bounds contains - !> Check if two floating point numbers of wp are within tolerance. + !> This procedure checks if two floating point numbers of wp are within tolerance. + !! @param a First number. + !! @param b Second number. !! @param tol_input Relative error (default = 1.e-10_wp). + !! @return Result of the comparison. logical elemental function f_approx_equal(a, b, tol_input) result(res) - $:GPU_ROUTINE(parallelism='[seq]') - real(wp), intent(in) :: a, b + real(wp), intent(in) :: a, b real(wp), optional, intent(in) :: tol_input - real(wp) :: tol + real(wp) :: tol if (present(tol_input)) then tol = tol_input @@ -39,19 +46,20 @@ contains else res = (abs(a - b)/min(abs(a) + abs(b), huge(a)) < tol) end if - end function f_approx_equal - !> Check if a wp value approximately matches any element of an array within tolerance. + !> This procedure checks if the point numbers of wp belongs to another array are within tolerance. + !! @param a First number. + !! @param b Array that contains several point numbers. !! @param tol_input Relative error (default = 1e-10_wp). + !! @return Result of the comparison. logical function f_approx_in_array(a, b, tol_input) result(res) - $:GPU_ROUTINE(parallelism='[seq]') - real(wp), intent(in) :: a - real(wp), intent(in) :: b(:) + real(wp), intent(in) :: a + real(wp), intent(in) :: b(:) real(wp), optional, intent(in) :: tol_input - real(wp) :: tol - integer :: i + real(wp) :: tol + integer :: i res = .false. @@ -67,68 +75,75 @@ contains exit end if end do - end function f_approx_in_array !> Checks if a real(wp) variable is of default value. + !! @param var Variable to check. logical elemental function f_is_default(var) result(res) - $:GPU_ROUTINE(parallelism='[seq]') real(wp), intent(in) :: var res = f_approx_equal(var, dflt_real) - end function f_is_default !> Checks if ALL elements of a real(wp) array are of default value. + !! @param var_array Array to check. logical function f_all_default(var_array) result(res) - real(wp), intent(in) :: var_array(:) res = all(f_is_default(var_array)) + !logical :: res_array(size(var_array)) + !integer :: i + + ! do i = 1, size(var_array) + ! res_array(i) = f_is_default(var_array(i)) + ! end do + + ! res = all(res_array) end function f_all_default !> Checks if a real(wp) variable is an integer. + !! @param var Variable to check. logical elemental function f_is_integer(var) result(res) - $:GPU_ROUTINE(parallelism='[seq]') real(wp), intent(in) :: var res = f_approx_equal(var, real(nint(var), wp)) - end function f_is_integer - !> Compute ghost-cell buffer size and set interior/buffered coordinate index bounds. - subroutine s_configure_coordinate_bounds(recon_type, weno_polyn, muscl_polyn, igr_order, buff_size, idwint, idwbuff, viscous, & - - & bubbles_lagrange, m, n, p, num_dims, igr, ib) + subroutine s_configure_coordinate_bounds(recon_type, weno_polyn, muscl_polyn, & + igr_order, buff_size, idwint, idwbuff, & + viscous, bubbles_lagrange, m, n, p, num_dims, & + igr, ib, fd_number) - integer, intent(in) :: recon_type, weno_polyn, muscl_polyn - integer, intent(in) :: m, n, p, num_dims, igr_order - integer, intent(inout) :: buff_size + integer, intent(in) :: recon_type, weno_polyn, muscl_polyn + integer, intent(in) :: m, n, p, num_dims, igr_order, fd_number + integer, intent(inout) :: buff_size type(int_bounds_info), dimension(3), intent(inout) :: idwint, idwbuff - logical, intent(in) :: viscous, bubbles_lagrange - logical, intent(in) :: igr - logical, intent(in) :: ib - - ! Determine ghost cell buffer size for boundary conditions - + logical, intent(in) :: viscous, bubbles_lagrange + logical, intent(in) :: igr + logical, intent(in) :: ib + + ! Determining the number of cells that are needed in order to store + ! sufficient boundary conditions data as to iterate the solution in + ! the physical computational domain from one time-step iteration to + ! the next one if (igr) then buff_size = (igr_order - 1)/2 + 2 - else if (recon_type == WENO_TYPE) then + elseif (recon_type == WENO_TYPE) then if (viscous) then buff_size = 2*weno_polyn + 2 else buff_size = weno_polyn + 2 end if - else if (recon_type == MUSCL_TYPE) then + elseif (recon_type == MUSCL_TYPE) then buff_size = muscl_polyn + 2 end if ! Correction for smearing function in the lagrangian subgrid bubble model if (bubbles_lagrange) then - buff_size = max(buff_size, 6) + buff_size = max(buff_size + fd_number, mapCells + 1 + fd_number) end if if (ib) then @@ -150,11 +165,13 @@ contains end subroutine s_configure_coordinate_bounds !> Updates the min and max number of cells in each set of axes - !! @param bounds Min and max values to update + !! @param bounds Min ans max values to update + !! @param m Number of cells in x-axis + !! @param n Number of cells in y-axis + !! @param p Number of cells in z-axis elemental subroutine s_update_cell_bounds(bounds, m, n, p) - type(cell_num_bounds), intent(out) :: bounds - integer, intent(in) :: m, n, p + integer, intent(in) :: m, n, p bounds%mn_max = max(m, n) bounds%np_max = max(n, p) diff --git a/src/common/m_model.fpp b/src/common/m_model.fpp index c88bffa7e6..9683f4caac 100644 --- a/src/common/m_model.fpp +++ b/src/common/m_model.fpp @@ -11,47 +11,58 @@ module m_model use m_helper use m_mpi_proxy use m_derived_types + use iso_c_binding, only: c_char, c_int32_t, c_int16_t, c_float implicit none private - public :: f_model_read, s_model_write, s_model_free, f_model_is_inside, models, gpu_ntrs, gpu_trs_v, gpu_trs_n, & - & gpu_boundary_v, gpu_boundary_edge_count, gpu_total_vertices, stl_bounding_boxes + public :: f_model_read, s_model_write, s_model_free, f_model_is_inside, models, gpu_ntrs, & + gpu_trs_v, gpu_trs_n, gpu_boundary_v, gpu_boundary_edge_count, & + gpu_total_vertices, stl_bounding_boxes ! Subroutines for STL immersed boundaries - public :: s_check_boundary, s_register_edge, f_model_is_inside_flat, s_distance_normals_3D, s_distance_normals_2D, & - & s_pack_model_for_gpu + public :: s_check_boundary, s_register_edge, f_model_is_inside_flat, & + s_distance_normals_3D, s_distance_normals_2D, s_pack_model_for_gpu #ifdef MFC_SIMULATION public :: s_instantiate_STL_models #endif - type(t_model_array), allocatable, target :: models(:) !< STL/OBJ models for IB markers and levelset - integer, allocatable :: gpu_ntrs(:) !< GPU-friendly flat arrays for STL model data - real(wp), allocatable, dimension(:,:,:,:) :: gpu_trs_v - real(wp), allocatable, dimension(:,:,:) :: gpu_trs_n - real(wp), allocatable, dimension(:,:,:,:) :: gpu_boundary_v - integer, allocatable :: gpu_boundary_edge_count(:) - integer, allocatable :: gpu_total_vertices(:) - real(wp), allocatable :: stl_bounding_boxes(:,:,:) - $:GPU_DECLARE(create='[gpu_ntrs, gpu_trs_v, gpu_trs_n, gpu_boundary_v, gpu_boundary_edge_count, gpu_total_vertices]') + !! array of STL models that can be allocated and then used in IB marker and levelset compute + type(t_model_array), allocatable, target :: models(:) + !! GPU-friendly flat arrays for STL model data + integer, allocatable :: gpu_ntrs(:) + real(wp), allocatable, dimension(:, :, :, :) :: gpu_trs_v + real(wp), allocatable, dimension(:, :, :) :: gpu_trs_n + real(wp), allocatable, dimension(:, :, :, :) :: gpu_boundary_v + integer, allocatable :: gpu_boundary_edge_count(:) + integer, allocatable :: gpu_total_vertices(:) + real(wp), allocatable :: stl_bounding_boxes(:, :, :) + $:GPU_DECLARE(create='[gpu_ntrs,gpu_trs_v,gpu_trs_n,gpu_boundary_v,gpu_boundary_edge_count,gpu_total_vertices]') contains - !> Read a binary STL file. + !> This procedure reads a binary STL file. + !! @param filepath Path to the STL file. + !! @param model The binary of the STL file. impure subroutine s_read_stl_binary(filepath, model) - character(LEN=*), intent(in) :: filepath - type(t_model), intent(out) :: model - integer :: i, iunit, iostat + character(LEN=*), intent(in) :: filepath + type(t_model), intent(out) :: model + + integer :: i, iunit, iostat + character(kind=c_char, len=80) :: header - integer(kind=c_int32_t) :: nTriangles - real(kind=c_float) :: normal(3), v(3, 3), v_norm - integer(kind=c_int16_t) :: attribute + integer(kind=c_int32_t) :: nTriangles - open (newunit=iunit, file=filepath, action='READ', form='UNFORMATTED', status='OLD', iostat=iostat, access='STREAM') + real(kind=c_float) :: normal(3), v(3, 3), v_norm + integer(kind=c_int16_t) :: attribute + + open (newunit=iunit, file=filepath, action='READ', & + form='UNFORMATTED', status='OLD', iostat=iostat, & + access='STREAM') if (iostat /= 0) then print *, "Error: could not open Binary STL file ", filepath @@ -72,7 +83,7 @@ contains allocate (model%trs(model%ntrs)) do i = 1, model%ntrs - read (iunit) normal(:), v(1,:), v(2,:), v(3,:), attribute + read (iunit) normal(:), v(1, :), v(2, :), v(3, :), attribute model%trs(i)%v = v model%trs(i)%n = normal @@ -84,19 +95,23 @@ contains end subroutine s_read_stl_binary - !> Read an ASCII STL file. + !> This procedure reads an ASCII STL file. + !! @param filepath Path to the STL file. + !! @param model the STL file. impure subroutine s_read_stl_ascii(filepath, model) - character(LEN=*), intent(in) :: filepath - type(t_model), intent(out) :: model - integer :: i, j, iunit, iostat - character(80) :: line, buffered_line - logical :: is_buffered - real(wp) :: normal(3), v_norm + type(t_model), intent(out) :: model + + integer :: i, j, iunit, iostat + character(80) :: line, buffered_line + logical :: is_buffered + real(wp) :: normal(3), v_norm is_buffered = .false. - open (newunit=iunit, file=filepath, action='READ', form='FORMATTED', status='OLD', iostat=iostat, access='STREAM') + open (newunit=iunit, file=filepath, action='READ', & + form='FORMATTED', status='OLD', iostat=iostat, & + access='STREAM') if (iostat /= 0) then print *, "Error: could not open ASCII STL file ", filepath @@ -165,7 +180,7 @@ contains end if call s_skip_ignored_lines(iunit, buffered_line, is_buffered) - read (line(7:), *) model%trs(i)%v(j,:) + read (line(7:), *) model%trs(i)%v(j, :) end do if (is_buffered) then @@ -189,18 +204,23 @@ contains i = i + 1 end do - end subroutine s_read_stl_ascii - !> Read an STL file. + !> This procedure reads an STL file. + !! @param filepath Path to the STL file. + !! @param model the STL file. impure subroutine s_read_stl(filepath, model) character(LEN=*), intent(in) :: filepath - type(t_model), intent(out) :: model - integer :: iunit, iostat - character(80) :: line + type(t_model), intent(out) :: model + + integer :: iunit, iostat - open (newunit=iunit, file=filepath, action='READ', form='FORMATTED', status='OLD', iostat=iostat, access='STREAM') + character(80) :: line + + open (newunit=iunit, file=filepath, action='READ', & + form='FORMATTED', status='OLD', iostat=iostat, & + access='STREAM') if (iostat /= 0) then print *, "Error: could not open STL file ", filepath @@ -220,16 +240,23 @@ contains end subroutine s_read_stl - !> Read an OBJ file. + !> This procedure reads an OBJ file. + !! @param filepath Path to the obj file. + !! @param model The obj file. impure subroutine s_read_obj(filepath, model) - character(LEN=*), intent(in) :: filepath - type(t_model), intent(out) :: model - integer :: i, j, k, l, iv3, iunit, iostat, nVertices - real(wp), dimension(1:3), allocatable :: vertices(:,:) - character(80) :: line + character(LEN=*), intent(in) :: filepath + type(t_model), intent(out) :: model + + integer :: i, j, k, l, iv3, iunit, iostat, nVertices + + real(wp), dimension(1:3), allocatable :: vertices(:, :) + + character(80) :: line - open (newunit=iunit, file=filepath, action='READ', form='FORMATTED', status='OLD', iostat=iostat, access='STREAM') + open (newunit=iunit, file=filepath, action='READ', & + form='FORMATTED', status='OLD', iostat=iostat, & + access='STREAM') if (iostat /= 0) then print *, "Error: could not open model file ", filepath @@ -252,7 +279,7 @@ contains rewind (iunit) - allocate (vertices(nVertices,1:3)) + allocate (vertices(nVertices, 1:3)) allocate (model%trs(model%ntrs)) i = 1 @@ -267,13 +294,13 @@ contains case ("vt") case ("l ") case ("v ") - read (line(3:), *) vertices(i,:) + read (line(3:), *) vertices(i, :) i = i + 1 case ("f ") read (line(3:), *) k, l, iv3 - model%trs(j)%v(1,:) = vertices(k,:) - model%trs(j)%v(2,:) = vertices(l,:) - model%trs(j)%v(3,:) = vertices(iv3,:) + model%trs(j)%v(1, :) = vertices(k, :) + model%trs(j)%v(2, :) = vertices(l, :) + model%trs(j)%v(3, :) = vertices(iv3, :) j = j + 1 case default print *, "Error: unknown line type in OBJ file ", filepath @@ -289,11 +316,14 @@ contains end subroutine s_read_obj - !> Read a mesh from a file. + !> This procedure reads a mesh from a file. + !! @param filepath Path to the file to read. + !! @return The model read from the file. impure function f_model_read(filepath) result(model) character(LEN=*), intent(in) :: filepath - type(t_model) :: model + + type(t_model) :: model select case (filepath(len(trim(filepath)) - 3:len(trim(filepath)))) case (".stl") @@ -308,18 +338,23 @@ contains end function f_model_read - !> Write a binary STL file. + !> This procedure writes a binary STL file. + !! @param filepath Path to the STL file. + !! @param model STL to write impure subroutine s_write_stl(filepath, model) - character(LEN=*), intent(in) :: filepath - type(t_model), intent(in) :: model - integer :: i, j, iunit, iostat + character(LEN=*), intent(in) :: filepath + type(t_model), intent(in) :: model + + integer :: i, j, iunit, iostat + character(kind=c_char, len=80), parameter :: header = "Model file written by MFC." - integer(kind=c_int32_t) :: nTriangles - real(wp) :: normal(3), v(3) - integer(kind=c_int16_t) :: attribute + integer(kind=c_int32_t) :: nTriangles + real(wp) :: normal(3), v(3) + integer(kind=c_int16_t) :: attribute - open (newunit=iunit, file=filepath, action='WRITE', form='UNFORMATTED', iostat=iostat, access='STREAM') + open (newunit=iunit, file=filepath, action='WRITE', & + form='UNFORMATTED', iostat=iostat, access='STREAM') if (iostat /= 0) then print *, "Error: could not open STL file ", filepath @@ -341,7 +376,7 @@ contains write (iunit) normal do j = 1, 3 - v = model%trs(i)%v(j,:) + v = model%trs(i)%v(j, :) write (iunit) v(:) end do @@ -353,15 +388,20 @@ contains end subroutine s_write_stl - !> Write an OBJ file. + !> This procedure writes an OBJ file. + !! @param filepath Path to the obj file. + !! @param model obj to write. impure subroutine s_write_obj(filepath, model) character(LEN=*), intent(in) :: filepath - type(t_model), intent(in) :: model - integer :: iunit, iostat - integer :: i, j + type(t_model), intent(in) :: model + + integer :: iunit, iostat - open (newunit=iunit, file=filepath, action='WRITE', form='FORMATTED', iostat=iostat, access='STREAM') + integer :: i, j + + open (newunit=iunit, file=filepath, action='WRITE', & + form='FORMATTED', iostat=iostat, access='STREAM') if (iostat /= 0) then print *, "Error: could not open OBJ file ", filepath @@ -373,22 +413,25 @@ contains do i = 1, model%ntrs do j = 1, 3 - write (iunit, '(A, " ", (f30.20), " ", (f30.20), " ", (f30.20))') "v", model%trs(i)%v(j, 1), model%trs(i)%v(j, & - & 2), model%trs(i)%v(j, 3) + write (iunit, '(A, " ", (f30.20), " ", (f30.20), " ", (f30.20))') & + "v", model%trs(i)%v(j, 1), model%trs(i)%v(j, 2), model%trs(i)%v(j, 3) end do - write (iunit, '(A, " ", I0, " ", I0, " ", I0)') "f", i*3 - 2, i*3 - 1, i*3 + write (iunit, '(A, " ", I0, " ", I0, " ", I0)') & + "f", i*3 - 2, i*3 - 1, i*3 end do close (iunit) end subroutine s_write_obj - !> Write a mesh to a file. + !> This procedure writes a binary STL file. + !! @param filepath Path to the file to write. + !! @param model Model to write. impure subroutine s_model_write(filepath, model) character(LEN=*), intent(in) :: filepath - type(t_model), intent(in) :: model + type(t_model), intent(in) :: model select case (filepath(len(trim(filepath)) - 3:len(trim(filepath)))) case (".stl") @@ -403,7 +446,7 @@ contains end subroutine s_model_write - !> Free the memory allocated for an STL mesh. + !> This procedure frees the memory allocated for an STL mesh. subroutine s_model_free(model) type(t_model), intent(inout) :: model @@ -412,13 +455,13 @@ contains end subroutine s_model_free - !> Read the next non-blank, non-comment line from an STL or OBJ model file. impure function f_read_line(iunit, line) result(bIsLine) - integer, intent(in) :: iunit + integer, intent(in) :: iunit character(80), intent(out) :: line - logical :: bIsLine - integer :: iostat + + logical :: bIsLine + integer :: iostat bIsLine = .true. @@ -441,13 +484,13 @@ contains end function f_read_line - !> Read the next non-comment line from a model file, using a buffered look-ahead mechanism. + !> @brief Reads the next non-comment line from a model file, using a buffered look-ahead mechanism. impure subroutine s_skip_ignored_lines(iunit, buffered_line, is_buffered) - - integer, intent(in) :: iunit + integer, intent(in) :: iunit character(80), intent(inout) :: buffered_line - logical, intent(inout) :: is_buffered - character(80) :: line + logical, intent(inout) :: is_buffered + + character(80) :: line if (is_buffered) then line = buffered_line @@ -458,44 +501,52 @@ contains buffered_line = line is_buffered = .true. - end subroutine s_skip_ignored_lines - !> Generate a pseudo-random number using a seed-based xorshift, replacing the Fortran intrinsic which is incompatible with GPU - !! routines + !> This function is used to replace the fortran random number + !! generator because the native generator is not compatible being called + !! from GPU routines/functions function f_model_random_number(seed) result(rval) ! $:GPU_ROUTINE(parallelism='[seq]') integer, intent(inout) :: seed - real(wp) :: rval + real(wp) :: rval seed = ieor(seed, ishft(seed, 13)) seed = ieor(seed, ishft(seed, -17)) seed = ieor(seed, ishft(seed, 5)) rval = abs(real(seed, wp))/real(huge(seed), wp) - end function f_model_random_number - !> Determine whether a point is inside a model using stochastic ray casting. + !> This procedure, recursively, finds whether a point is inside an octree. + !! @param model Model to search in. + !! @param point Point to test. + !! @param spacing Space around the point to search in (grid spacing). !! @param spc Number of samples per cell. + !! @return True if the point is inside the octree, false otherwise. impure function f_model_is_inside(model, point, spacing, spc) result(fraction) ! $:GPU_ROUTINE(parallelism='[seq]') - type(t_model), intent(in) :: model + type(t_model), intent(in) :: model real(wp), dimension(1:3), intent(in) :: point real(wp), dimension(1:3), intent(in) :: spacing - integer, intent(in) :: spc - real(wp) :: phi, theta - integer :: rand_seed - real(wp) :: fraction - type(t_ray) :: ray - integer :: i, j, k, nInOrOut, nHits - real(wp), dimension(1:spc,1:3) :: ray_origins, ray_dirs - - rand_seed = int(point(1)*73856093._wp) + int(point(2)*19349663._wp) + int(point(3)*83492791._wp) + integer, intent(in) :: spc + real(wp) :: phi, theta + integer :: rand_seed + + real(wp) :: fraction + + type(t_ray) :: ray + integer :: i, j, k, nInOrOut, nHits + + real(wp), dimension(1:spc, 1:3) :: ray_origins, ray_dirs + + rand_seed = int(point(1)*73856093._wp) + & + int(point(2)*19349663._wp) + & + int(point(3)*83492791._wp) if (rand_seed == 0) rand_seed = 1 ! generate our random collection or rays @@ -506,14 +557,14 @@ contains ! cast sample rays in all directions ray_dirs(i, k) = f_model_random_number(rand_seed) - 0.5_wp end do - ray_dirs(i,:) = ray_dirs(i,:)/sqrt(sum(ray_dirs(i,:)*ray_dirs(i,:))) + ray_dirs(i, :) = ray_dirs(i, :)/sqrt(sum(ray_dirs(i, :)*ray_dirs(i, :))) end do ! ray trace nInOrOut = 0 do i = 1, spc - ray%o = ray_origins(i,:) - ray%d = ray_dirs(i,:) + ray%o = ray_origins(i, :) + ray%d = ray_dirs(i, :) nHits = 0 do j = 1, model%ntrs @@ -523,7 +574,8 @@ contains end if end do - ! if the ray hits an odd number of triangles on its way out, then it must be on the inside of the model + ! if the ray hits an odd number of triangles on its way out, then + ! it must be on the inside of the model nInOrOut = nInOrOut + mod(nHits, 2) end do @@ -531,29 +583,38 @@ contains end function f_model_is_inside - !> Determine if a point is inside a surface using the generalized winding number (Jacobson et al., SIGGRAPH 2013). In 3D, sums - !! the solid angle subtended by each triangle (Van Oosterom-Strackee formula). In 2D (p==0), sums the signed angle subtended by - !! each boundary edge. Returns ~1.0 inside, ~0.0 outside. Unlike ray casting, this is robust to small triangles/edges and vertex - !! winding order. + !> This procedure determines if a point is inside a surface using + !! the generalized winding number (Jacobson et al., SIGGRAPH 2013). + !! In 3D, sums the solid angle subtended by each triangle (Van + !! Oosterom-Strackee formula). In 2D (p==0), sums the signed + !! angle subtended by each boundary edge. Returns ~1.0 inside, + !! ~0.0 outside. Unlike ray casting, this is robust to small + !! triangles/edges and vertex winding order. + !! @param ntrs Number of triangles in the model. + !! @param pid Patch ID of this model. + !! @param point Point to test. !! @return fraction Winding number (~1.0 inside, ~0.0 outside). function f_model_is_inside_flat(ntrs, pid, point) result(fraction) $:GPU_ROUTINE(parallelism='[seq]') - integer, intent(in) :: ntrs - integer, intent(in) :: pid + integer, intent(in) :: ntrs + integer, intent(in) :: pid real(wp), dimension(1:3), intent(in) :: point - real(wp) :: fraction - real(wp) :: r1(3), r2(3), r3(3) - real(wp) :: r1_mag, r2_mag, r3_mag - real(wp) :: numerator, denominator - real(wp) :: d1(2), d2(2) - integer :: q + + real(wp) :: fraction + + real(wp) :: r1(3), r2(3), r3(3) + real(wp) :: r1_mag, r2_mag, r3_mag + real(wp) :: numerator, denominator + real(wp) :: d1(2), d2(2) + integer :: q fraction = 0.0_wp if (p == 0) then - ! 2D winding number: sum signed angles subtended by each boundary edge at the query point. + ! 2D winding number: sum signed angles subtended by + ! each boundary edge at the query point. do q = 1, gpu_boundary_edge_count(pid) d1(1) = gpu_boundary_v(q, 1, 1, pid) - point(1) d1(2) = gpu_boundary_v(q, 1, 2, pid) - point(2) @@ -561,66 +622,82 @@ contains d2(2) = gpu_boundary_v(q, 2, 2, pid) - point(2) ! Signed angle = atan2(d1 x d2, d1 . d2) - fraction = fraction + atan2(d1(1)*d2(2) - d1(2)*d2(1), d1(1)*d2(1) + d1(2)*d2(2)) + fraction = fraction + atan2( & + d1(1)*d2(2) - d1(2)*d2(1), & + d1(1)*d2(1) + d1(2)*d2(2)) end do ! 2D winding number = total angle / (2*pi) fraction = fraction/(2.0_wp*acos(-1.0_wp)) else - ! 3D winding number: sum solid angles via Van Oosterom-Strackee formula. + ! 3D winding number: sum solid angles via Van + ! Oosterom-Strackee formula. do q = 1, ntrs - r1 = gpu_trs_v(1,:,q, pid) - point - r2 = gpu_trs_v(2,:,q, pid) - point - r3 = gpu_trs_v(3,:,q, pid) - point + r1 = gpu_trs_v(1, :, q, pid) - point + r2 = gpu_trs_v(2, :, q, pid) - point + r3 = gpu_trs_v(3, :, q, pid) - point r1_mag = sqrt(dot_product(r1, r1)) r2_mag = sqrt(dot_product(r2, r2)) r3_mag = sqrt(dot_product(r3, r3)) - ! Skip if query point is coincident with a vertex (magnitudes are zero/subnormal). + ! Skip if query point is coincident with a vertex + ! (magnitudes are zero/subnormal). if (r1_mag*r2_mag*r3_mag < tiny(1.0_wp)) cycle - ! tan(Omega/2) = numerator / denominator numerator = scalar triple product r1 . (r2 x r3) - numerator = r1(1)*(r2(2)*r3(3) - r2(3)*r3(2)) + r1(2)*(r2(3)*r3(1) - r2(1)*r3(3)) + r1(3)*(r2(1)*r3(2) - r2(2) & - & *r3(1)) + ! tan(Omega/2) = numerator / denominator + ! numerator = scalar triple product r1 . (r2 x r3) + numerator = r1(1)*(r2(2)*r3(3) - r2(3)*r3(2)) & + + r1(2)*(r2(3)*r3(1) - r2(1)*r3(3)) & + + r1(3)*(r2(1)*r3(2) - r2(2)*r3(1)) - denominator = r1_mag*r2_mag*r3_mag + dot_product(r1, r2)*r3_mag + dot_product(r2, r3)*r1_mag + dot_product(r3, & - & r1)*r2_mag + denominator = r1_mag*r2_mag*r3_mag & + + dot_product(r1, r2)*r3_mag & + + dot_product(r2, r3)*r1_mag & + + dot_product(r3, r1)*r2_mag fraction = fraction + atan2(numerator, denominator) end do - ! Each atan2 returns Omega/2 per triangle; divide by 2*pi to get winding number = sum(Omega)/(4*pi). + ! Each atan2 returns Omega/2 per triangle; divide + ! by 2*pi to get winding number = sum(Omega)/(4*pi). fraction = fraction/(2.0_wp*acos(-1.0_wp)) end if end function f_model_is_inside_flat - !> Check if a ray intersects a triangle using the Moller-Trumbore algorithm (barycentric coordinates). Unlike the previous - !! cross-product sign test, this is vertex winding-order independent. - !! @return 1 if the ray intersects the triangle, 0 otherwise. + !> This procedure checks if a ray intersects a triangle using the + !! Moller-Trumbore algorithm (barycentric coordinates). Unlike the + !! previous cross-product sign test, this is vertex winding-order + !! independent. + !! @param ray Ray. + !! @param triangle Triangle. + !! @return 1 if the ray intersects the triangle, 0 otherwise. function f_intersects_triangle(ray, triangle) result(intersects) $:GPU_ROUTINE(parallelism='[seq]') - type(t_ray), intent(in) :: ray + type(t_ray), intent(in) :: ray type(t_triangle), intent(in) :: triangle - integer :: intersects - real(wp) :: edge1(3), edge2(3), h(3), s(3), q(3) - real(wp) :: a, f, u, v, t + + integer :: intersects + + real(wp) :: edge1(3), edge2(3), h(3), s(3), q(3) + real(wp) :: a, f, u, v, t intersects = 0 - edge1 = triangle%v(2,:) - triangle%v(1,:) - edge2 = triangle%v(3,:) - triangle%v(1,:) + edge1 = triangle%v(2, :) - triangle%v(1, :) + edge2 = triangle%v(3, :) - triangle%v(1, :) h = f_cross(ray%d, edge2) a = dot_product(edge1, h) - ! Ray nearly parallel to triangle plane. In single precision builds epsilon(1.0) ~ 1.2e-7, so use 10*epsilon as a floor. + ! Ray nearly parallel to triangle plane. In single precision + ! builds epsilon(1.0) ~ 1.2e-7, so use 10*epsilon as a floor. if (abs(a) < max(1e-7_wp, 10.0_wp*epsilon(1.0_wp))) return f = 1.0_wp/a - s = ray%o - triangle%v(1,:) + s = ray%o - triangle%v(1, :) u = f*dot_product(s, h) if (u < 0.0_wp .or. u > 1.0_wp) return @@ -636,21 +713,24 @@ contains end function f_intersects_triangle - !> Check and label edges shared by two or more triangle facets of the 2D STL model. + !> This procedure checks and labels edges shared by two or more triangles facets of the 2D STL model. + !! @param model Model to search in. + !! @param boundary_vertex_count Output total boundary vertex count subroutine s_check_boundary(model, boundary_v, boundary_vertex_count, boundary_edge_count) type(t_model), intent(in) :: model - real(wp), allocatable, intent(out), dimension(:,:,:) :: boundary_v !< Output boundary vertices/normals - integer, intent(out) :: boundary_vertex_count, boundary_edge_count !< Output boundary vertex/edge count - integer :: i, j !< Model index iterator - integer :: edge_count, edge_index, store_index !< Boundary edge index iterator - real(wp), dimension(1:2,1:2) :: edge !< Edge end points buffer - real(wp), dimension(1:2) :: boundary_edge !< Boundary edge end points buffer - real(wp), dimension(1:(3*model%ntrs),1:2,1:2) :: temp_boundary_v !< Temporary boundary vertex buffer - integer, dimension(1:(3*model%ntrs)) :: edge_occurrence !< The manifoldness of the edges - real(wp) :: edgetan, initial, v_norm, xnormal, ynormal !< The manifoldness of the edges - ! Total number of edges in 2D STL + real(wp), allocatable, intent(out), dimension(:, :, :) :: boundary_v !< Output boundary vertices/normals + integer, intent(out) :: boundary_vertex_count, boundary_edge_count !< Output boundary vertex/edge count + + integer :: i, j !< Model index iterator + integer :: edge_count, edge_index, store_index !< Boundary edge index iterator + real(wp), dimension(1:2, 1:2) :: edge !< Edge end points buffer + real(wp), dimension(1:2) :: boundary_edge !< Boundary edge end points buffer + real(wp), dimension(1:(3*model%ntrs), 1:2, 1:2) :: temp_boundary_v !< Temporary boundary vertex buffer + integer, dimension(1:(3*model%ntrs)) :: edge_occurrence !< The manifoldness of the edges + real(wp) :: edgetan, initial, v_norm, xnormal, ynormal !< The manifoldness of the edges + ! Total number of edges in 2D STL edge_count = 3*model%ntrs ! Initialize edge_occurrence array to zero @@ -660,35 +740,35 @@ contains ! Collect all edges of all triangles and store them do i = 1, model%ntrs ! First edge (v1, v2) - edge(1,1:2) = model%trs(i)%v(1,1:2) - edge(2,1:2) = model%trs(i)%v(2,1:2) + edge(1, 1:2) = model%trs(i)%v(1, 1:2) + edge(2, 1:2) = model%trs(i)%v(2, 1:2) call s_register_edge(temp_boundary_v, edge, edge_index, edge_count) ! Second edge (v2, v3) - edge(1,1:2) = model%trs(i)%v(2,1:2) - edge(2,1:2) = model%trs(i)%v(3,1:2) + edge(1, 1:2) = model%trs(i)%v(2, 1:2) + edge(2, 1:2) = model%trs(i)%v(3, 1:2) call s_register_edge(temp_boundary_v, edge, edge_index, edge_count) ! Third edge (v3, v1) - edge(1,1:2) = model%trs(i)%v(3,1:2) - edge(2,1:2) = model%trs(i)%v(1,1:2) + edge(1, 1:2) = model%trs(i)%v(3, 1:2) + edge(2, 1:2) = model%trs(i)%v(1, 1:2) call s_register_edge(temp_boundary_v, edge, edge_index, edge_count) end do ! Check all edges and count repeated edges - $:GPU_PARALLEL_LOOP(private='[i, j]', copy='[temp_boundary_v, edge_occurrence]', collapse=2) + $:GPU_PARALLEL_LOOP(private='[i,j]', copy='[temp_boundary_v,edge_occurrence]', collapse=2) do i = 1, edge_count do j = 1, edge_count if (i /= j) then - if (((abs(temp_boundary_v(i, 1, 1) - temp_boundary_v(j, 1, & - & 1)) < threshold_edge_zero) .and. (abs(temp_boundary_v(i, 1, 2) - temp_boundary_v(j, 1, & - & 2)) < threshold_edge_zero) .and. (abs(temp_boundary_v(i, 2, 1) - temp_boundary_v(j, 2, & - & 1)) < threshold_edge_zero) .and. (abs(temp_boundary_v(i, 2, 2) - temp_boundary_v(j, 2, & - & 2)) < threshold_edge_zero)) .or. ((abs(temp_boundary_v(i, 1, 1) - temp_boundary_v(j, 2, & - & 1)) < threshold_edge_zero) .and. (abs(temp_boundary_v(i, 1, 2) - temp_boundary_v(j, 2, & - & 2)) < threshold_edge_zero) .and. (abs(temp_boundary_v(i, 2, 1) - temp_boundary_v(j, 1, & - & 1)) < threshold_edge_zero) .and. (abs(temp_boundary_v(i, 2, 2) - temp_boundary_v(j, 1, & - & 2)) < threshold_edge_zero))) then + if (((abs(temp_boundary_v(i, 1, 1) - temp_boundary_v(j, 1, 1)) < threshold_edge_zero) .and. & + (abs(temp_boundary_v(i, 1, 2) - temp_boundary_v(j, 1, 2)) < threshold_edge_zero) .and. & + (abs(temp_boundary_v(i, 2, 1) - temp_boundary_v(j, 2, 1)) < threshold_edge_zero) .and. & + (abs(temp_boundary_v(i, 2, 2) - temp_boundary_v(j, 2, 2)) < threshold_edge_zero)) .or. & + ((abs(temp_boundary_v(i, 1, 1) - temp_boundary_v(j, 2, 1)) < threshold_edge_zero) .and. & + (abs(temp_boundary_v(i, 1, 2) - temp_boundary_v(j, 2, 2)) < threshold_edge_zero) .and. & + (abs(temp_boundary_v(i, 2, 1) - temp_boundary_v(j, 1, 1)) < threshold_edge_zero) .and. & + (abs(temp_boundary_v(i, 2, 2) - temp_boundary_v(j, 1, 2)) < threshold_edge_zero))) then + $:GPU_ATOMIC(atomic='update') edge_occurrence(i) = edge_occurrence(i) + 1 end if @@ -709,15 +789,15 @@ contains end do ! Allocate the boundary_v array based on the number of boundary edges - allocate (boundary_v(boundary_edge_count,1:3,1:2)) + allocate (boundary_v(boundary_edge_count, 1:3, 1:2)) ! Store boundary vertices store_index = 0 do i = 1, edge_count if (edge_occurrence(i) == 0) then store_index = store_index + 1 - boundary_v(store_index, 1,1:2) = temp_boundary_v(i, 1,1:2) - boundary_v(store_index, 2,1:2) = temp_boundary_v(i, 2,1:2) + boundary_v(store_index, 1, 1:2) = temp_boundary_v(i, 1, 1:2) + boundary_v(store_index, 2, 1:2) = temp_boundary_v(i, 2, 1:2) end if end do @@ -748,59 +828,66 @@ contains end subroutine s_check_boundary - !> Append the edge end vertices to a temporary buffer. + !> This procedure appends the edge end vertices to a temporary buffer. subroutine s_register_edge(temp_boundary_v, edge, edge_index, edge_count) - integer, intent(inout) :: edge_index !< Edge index iterator - integer, intent(inout) :: edge_count !< Total number of edges - real(wp), intent(in), dimension(1:2,1:2) :: edge !< Edges end points to be registered - real(wp), dimension(1:edge_count,1:2,1:2), intent(inout) :: temp_boundary_v !< Temporary edge end vertex buffer - ! Increment edge index and store the edge + integer, intent(inout) :: edge_index !< Edge index iterator + integer, intent(inout) :: edge_count !< Total number of edges + real(wp), intent(in), dimension(1:2, 1:2) :: edge !< Edges end points to be registered + real(wp), dimension(1:edge_count, 1:2, 1:2), intent(inout) :: temp_boundary_v !< Temporary edge end vertex buffer + ! Increment edge index and store the edge edge_index = edge_index + 1 - temp_boundary_v(edge_index, 1,1:2) = edge(1,1:2) - temp_boundary_v(edge_index, 2,1:2) = edge(2,1:2) + temp_boundary_v(edge_index, 1, 1:2) = edge(1, 1:2) + temp_boundary_v(edge_index, 2, 1:2) = edge(2, 1:2) end subroutine s_register_edge - !> Determine the levelset distance and normals of 3D models by computing the exact closest point via projection onto triangle - !! surfaces. + !> This procedure determines the levelset distance and normals of 3D models + !! by computing the exact closest point via projection onto triangle surfaces. + !! @param ntrs Number of triangles for this patch + !! @param trs_v Flat GPU array of triangle vertices for all patches + !! @param trs_n Flat GPU array of triangle normals for all patches + !! @param pid Patch index into the arrays + !! @param point The cell center of the current levelset cell + !! @param normals Output levelset normals + !! @param distance Output levelset distance subroutine s_distance_normals_3D(ntrs, pid, point, normals, distance) - $:GPU_ROUTINE(parallelism='[seq]') - integer, intent(in) :: ntrs - integer, intent(in) :: pid - real(wp), dimension(1:3), intent(in) :: point + integer, intent(in) :: ntrs + integer, intent(in) :: pid + real(wp), dimension(1:3), intent(in) :: point real(wp), dimension(1:3), intent(out) :: normals - real(wp), intent(out) :: distance - integer :: i, j, l - real(wp) :: dist_min, dist_proj, dist_v, dist_e, t - real(wp) :: v1(1:3), v2(1:3), v3(1:3) - real(wp) :: e0(1:3), e1(1:3), pv(1:3) - real(wp) :: n(1:3), proj(1:3), norm_vec(1:3) - real(wp) :: d, ndot, denom, norm_mag - real(wp) :: u, v_bary, w - real(wp) :: l00, l01, l11, l20, l21 - real(wp) :: edge(1:3), pe(1:3) - real(wp) :: verts(1:3,1:3) + real(wp), intent(out) :: distance + + integer :: i, j, l + real(wp) :: dist_min, dist_proj, dist_v, dist_e, t + real(wp) :: v1(1:3), v2(1:3), v3(1:3) + real(wp) :: e0(1:3), e1(1:3), pv(1:3) + real(wp) :: n(1:3), proj(1:3), norm_vec(1:3) + real(wp) :: d, ndot, denom, norm_mag + real(wp) :: u, v_bary, w + real(wp) :: l00, l01, l11, l20, l21 + real(wp) :: edge(1:3), pe(1:3) + real(wp) :: verts(1:3, 1:3) dist_min = initial_distance_buffer normals = 0._wp do i = 1, ntrs ! Triangle vertices - v1(:) = gpu_trs_v(1,:,i, pid) - v2(:) = gpu_trs_v(2,:,i, pid) - v3(:) = gpu_trs_v(3,:,i, pid) + v1(:) = gpu_trs_v(1, :, i, pid) + v2(:) = gpu_trs_v(2, :, i, pid) + v3(:) = gpu_trs_v(3, :, i, pid) ! Triangle normal - n(:) = gpu_trs_n(:,i, pid) + n(:) = gpu_trs_n(:, i, pid) ! Project point onto triangle plane pv(:) = point(:) - v1(:) d = dot_product(pv, n) - if (abs(d) >= dist_min) cycle ! minimum distance is not small enough, no need to check validity + if (abs(d) >= dist_min) cycle ! minimum distance is not small enough, no need to check validity proj(:) = point(:) - d*n(:) ! Check if projection is inside triangle using barycentric coordinates @@ -829,7 +916,9 @@ contains ! If projection is inside triangle if (u >= 0._wp .and. v_bary >= 0._wp .and. w >= 0._wp) then - dist_proj = sqrt((point(1) - proj(1))**2 + (point(2) - proj(2))**2 + (point(3) - proj(3))**2) + dist_proj = sqrt((point(1) - proj(1))**2 + & + (point(2) - proj(2))**2 + & + (point(3) - proj(3))**2) if (dist_proj < dist_min) then dist_min = dist_proj @@ -837,20 +926,22 @@ contains end if else ! Projection outside triangle: check edges and vertices - verts(:,1) = v1(:) - verts(:,2) = v2(:) - verts(:,3) = v3(:) + verts(:, 1) = v1(:) + verts(:, 2) = v2(:) + verts(:, 3) = v3(:) ! Check three edges do j = 1, 3 - edge(:) = verts(:,mod(j, 3) + 1) - verts(:,j) - pe(:) = point(:) - verts(:,j) + edge(:) = verts(:, mod(j, 3) + 1) - verts(:, j) + pe(:) = point(:) - verts(:, j) t = dot_product(pe, edge)/max(dot_product(edge, edge), 1.e-30_wp) if (t >= 0._wp .and. t <= 1._wp) then - proj(:) = verts(:,j) + t*edge(:) - dist_e = sqrt((point(1) - proj(1))**2 + (point(2) - proj(2))**2 + (point(3) - proj(3))**2) + proj(:) = verts(:, j) + t*edge(:) + dist_e = sqrt((point(1) - proj(1))**2 + & + (point(2) - proj(2))**2 + & + (point(3) - proj(3))**2) if (dist_e < dist_min) then dist_min = dist_e @@ -864,22 +955,25 @@ contains end if end if else if (t < 0._wp) then - dist_v = sqrt((point(1) - verts(1, j))**2 + (point(2) - verts(2, j))**2 + (point(3) - verts(3, j))**2) + dist_v = sqrt((point(1) - verts(1, j))**2 + & + (point(2) - verts(2, j))**2 + & + (point(3) - verts(3, j))**2) if (dist_v < dist_min) then dist_min = dist_v - norm_vec(:) = verts(:,j) - point(:) + norm_vec(:) = verts(:, j) - point(:) norm_mag = sqrt(dot_product(norm_vec, norm_vec)) if (norm_mag > 0._wp) norm_vec = norm_vec/norm_mag normals(:) = norm_vec(:) end if else - dist_v = sqrt((point(1) - verts(1, mod(j, 3) + 1))**2 + (point(2) - verts(2, mod(j, & - & 3) + 1))**2 + (point(3) - verts(3, mod(j, 3) + 1))**2) + dist_v = sqrt((point(1) - verts(1, mod(j, 3) + 1))**2 + & + (point(2) - verts(2, mod(j, 3) + 1))**2 + & + (point(3) - verts(3, mod(j, 3) + 1))**2) if (dist_v < dist_min) then dist_min = dist_v - norm_vec(:) = verts(:,mod(j, 3) + 1) - point(:) + norm_vec(:) = verts(:, mod(j, 3) + 1) - point(:) norm_mag = sqrt(dot_product(norm_vec, norm_vec)) if (norm_mag > 0._wp) norm_vec = norm_vec/norm_mag normals(:) = norm_vec(:) @@ -893,21 +987,27 @@ contains end subroutine s_distance_normals_3D - !> Determine the levelset distance and normals of 2D models by computing the exact closest point via projection onto boundary - !! edges. + !> This procedure determines the levelset distance and normals of 2D models + !! by computing the exact closest point via projection onto boundary edges. + !! @param boundary_v Flat GPU array of boundary vertices/normals for all patches + !! @param pid Patch index into the boundary_v array + !! @param boundary_edge_count Total number of boundary edges for this patch + !! @param point The cell center of the current levelset cell + !! @param normals Output levelset normals + !! @param distance Output levelset distance subroutine s_distance_normals_2D(pid, boundary_edge_count, point, normals, distance) - $:GPU_ROUTINE(parallelism='[seq]') - integer, intent(in) :: pid - integer, intent(in) :: boundary_edge_count - real(wp), dimension(1:3), intent(in) :: point + integer, intent(in) :: pid + integer, intent(in) :: boundary_edge_count + real(wp), dimension(1:3), intent(in) :: point real(wp), dimension(1:3), intent(out) :: normals - real(wp), intent(out) :: distance - integer :: i - real(wp) :: dist_min, dist, t, norm_mag - real(wp) :: v1(1:2), v2(1:2), edge(1:2), pv(1:2) - real(wp) :: edge_len_sq, proj(1:2), norm(1:2), c + real(wp), intent(out) :: distance + + integer :: i + real(wp) :: dist_min, dist, t, norm_mag + real(wp) :: v1(1:2), v2(1:2), edge(1:2), pv(1:2) + real(wp) :: edge_len_sq, proj(1:2), norm(1:2), c dist_min = initial_distance_buffer normals = 0._wp @@ -939,12 +1039,12 @@ contains dist = sqrt((point(1) - proj(1))**2 + (point(2) - proj(2))**2) norm(1) = gpu_boundary_v(i, 3, 1, pid) norm(2) = gpu_boundary_v(i, 3, 2, pid) - else if (t < 0._wp) then ! negative t means that v1 is the closest point on the edge + else if (t < 0._wp) then ! negative t means that v1 is the closest point on the edge dist = sqrt((point(1) - v1(1))**2 + (point(2) - v1(2))**2) norm(1) = v1(1) - point(1) norm(2) = v1(2) - point(2) norm = norm/dist - else ! t > 1 means that v2 is the closest point on the line edge + else ! t > 1 means that v2 is the closest point on the line edge dist = sqrt((point(1) - v2(1))**2 + (point(2) - v2(2))**2) norm(1) = v2(1) - point(1) norm(2) = v2(2) - point(2) @@ -963,33 +1063,37 @@ contains end subroutine s_distance_normals_2D #ifdef MFC_SIMULATION - !> Load, transform, and register STL/OBJ immersed-boundary models onto the simulation grid. + subroutine s_instantiate_STL_models() ! Variables for IBM+STL - real(wp) :: normals(1:3) !< Boundary normal buffer - integer :: boundary_vertex_count, boundary_edge_count, total_vertices !< Boundary vertex - real(wp), allocatable, dimension(:,:,:) :: boundary_v !< Boundary vertex buffer - real(wp) :: dx_local, dy_local, dz_local !< Levelset distance buffer - integer :: i, j, k !< Generic loop iterators - integer :: patch_id - type(t_bbox) :: bbox, bbox_old - type(t_model) :: model - type(ic_model_parameters) :: params - real(wp) :: eta - real(wp), dimension(1:3) :: point, model_center - real(wp) :: grid_mm(1:3,1:2) - real(wp), dimension(1:4,1:4) :: transform, transform_n + real(wp) :: normals(1:3) !< Boundary normal buffer + integer :: boundary_vertex_count, boundary_edge_count, total_vertices !< Boundary vertex + real(wp), allocatable, dimension(:, :, :) :: boundary_v !< Boundary vertex buffer + real(wp) :: dx_local, dy_local, dz_local !< Levelset distance buffer + + integer :: i, j, k !< Generic loop iterators + integer :: patch_id + + type(t_bbox) :: bbox, bbox_old + type(t_model) :: model + type(ic_model_parameters) :: params + + real(wp) :: eta + real(wp), dimension(1:3) :: point, model_center + real(wp) :: grid_mm(1:3, 1:2) + + real(wp), dimension(1:4, 1:4) :: transform, transform_n dx_local = minval(dx); dy_local = minval(dy) if (p /= 0) dz_local = minval(dz) - allocate (stl_bounding_boxes(num_ibs,1:3,1:3)) + allocate (stl_bounding_boxes(num_ibs, 1:3, 1:3)) do patch_id = 1, num_ibs if (patch_ib(patch_id)%geometry == 5 .or. patch_ib(patch_id)%geometry == 12) then allocate (models(patch_id)%model) - print *, " * Reading model: " // trim(patch_ib(patch_id)%model_filepath) + print *, " * Reading model: "//trim(patch_ib(patch_id)%model_filepath) model = f_model_read(patch_ib(patch_id)%model_filepath) params%scale(:) = patch_ib(patch_id)%model_scale(:) @@ -1037,23 +1141,23 @@ contains write (*, "(A, 3(2X, F20.10))") " > Cen:", (bbox%min(1:3) + bbox%max(1:3))/2._wp write (*, "(A, 3(2X, F20.10))") " > Max:", bbox%max(1:3) - grid_mm(1,:) = (/minval(x_cc(0:m)) - 0.5_wp*dx_local, maxval(x_cc(0:m)) + 0.5_wp*dx_local/) - grid_mm(2,:) = (/minval(y_cc(0:n)) - 0.5_wp*dy_local, maxval(y_cc(0:n)) + 0.5_wp*dy_local/) + grid_mm(1, :) = (/minval(x_cc(0:m)) - 0.5_wp*dx_local, maxval(x_cc(0:m)) + 0.5_wp*dx_local/) + grid_mm(2, :) = (/minval(y_cc(0:n)) - 0.5_wp*dy_local, maxval(y_cc(0:n)) + 0.5_wp*dy_local/) if (p > 0) then - grid_mm(3,:) = (/minval(z_cc(0:p)) - 0.5_wp*dz_local, maxval(z_cc(0:p)) + 0.5_wp*dz_local/) + grid_mm(3, :) = (/minval(z_cc(0:p)) - 0.5_wp*dz_local, maxval(z_cc(0:p)) + 0.5_wp*dz_local/) else - grid_mm(3,:) = (/0._wp, 0._wp/) + grid_mm(3, :) = (/0._wp, 0._wp/) end if - write (*, "(A, 3(2X, F20.10))") " > Domain: Min:", grid_mm(:,1) - write (*, "(A, 3(2X, F20.10))") " > Cen:", (grid_mm(:,1) + grid_mm(:,2))/2._wp - write (*, "(A, 3(2X, F20.10))") " > Max:", grid_mm(:,2) + write (*, "(A, 3(2X, F20.10))") " > Domain: Min:", grid_mm(:, 1) + write (*, "(A, 3(2X, F20.10))") " > Cen:", (grid_mm(:, 1) + grid_mm(:, 2))/2._wp + write (*, "(A, 3(2X, F20.10))") " > Max:", grid_mm(:, 2) end if - stl_bounding_boxes(patch_id, 1,1:3) = [bbox%min(1), (bbox%min(1) + bbox%max(1))/2._wp, bbox%max(1)] - stl_bounding_boxes(patch_id, 2,1:3) = [bbox%min(2), (bbox%min(2) + bbox%max(2))/2._wp, bbox%max(2)] - stl_bounding_boxes(patch_id, 3,1:3) = [bbox%min(3), (bbox%min(3) + bbox%max(3))/2._wp, bbox%max(3)] + stl_bounding_boxes(patch_id, 1, 1:3) = [bbox%min(1), (bbox%min(1) + bbox%max(1))/2._wp, bbox%max(1)] + stl_bounding_boxes(patch_id, 2, 1:3) = [bbox%min(2), (bbox%min(2) + bbox%max(2))/2._wp, bbox%max(2)] + stl_bounding_boxes(patch_id, 3, 1:3) = [bbox%min(3), (bbox%min(3) + bbox%max(3))/2._wp, bbox%max(3)] models(patch_id)%model = model if (p == 0) then @@ -1105,14 +1209,15 @@ contains do pid = 1, num_ibs if (allocated(models(pid)%model)) then gpu_ntrs(pid) = models(pid)%ntrs - gpu_trs_v(:,:,1:models(pid)%ntrs,pid) = models(pid)%trs_v - gpu_trs_n(:,1:models(pid)%ntrs,pid) = models(pid)%trs_n + gpu_trs_v(:, :, 1:models(pid)%ntrs, pid) = models(pid)%trs_v + gpu_trs_n(:, 1:models(pid)%ntrs, pid) = models(pid)%trs_n gpu_boundary_edge_count(pid) = models(pid)%boundary_edge_count gpu_total_vertices(pid) = models(pid)%total_vertices end if if (allocated(models(pid)%boundary_v) .and. p == 0) then - gpu_boundary_v(1:size(models(pid)%boundary_v, 1),1:size(models(pid)%boundary_v, 2), & - & 1:size(models(pid)%boundary_v, 3),pid) = models(pid)%boundary_v + gpu_boundary_v(1:size(models(pid)%boundary_v, 1), & + 1:size(models(pid)%boundary_v, 2), & + 1:size(models(pid)%boundary_v, 3), pid) = models(pid)%boundary_v end if end do @@ -1124,23 +1229,21 @@ contains end block end subroutine s_instantiate_STL_models + #endif - !> Pack triangle vertices and normals from a model into flat arrays for GPU transfer. subroutine s_pack_model_for_gpu(ma) - type(t_model_array), intent(inout) :: ma - integer :: i + integer :: i ma%ntrs = ma%model%ntrs - allocate (ma%trs_v(1:3,1:3,1:ma%ntrs)) - allocate (ma%trs_n(1:3,1:ma%ntrs)) + allocate (ma%trs_v(1:3, 1:3, 1:ma%ntrs)) + allocate (ma%trs_n(1:3, 1:ma%ntrs)) do i = 1, ma%ntrs - ma%trs_v(:,:,i) = ma%model%trs(i)%v(:,:) - ma%trs_n(:,i) = ma%model%trs(i)%n(:) + ma%trs_v(:, :, i) = ma%model%trs(i)%v(:, :) + ma%trs_n(:, i) = ma%model%trs(i)%n(:) end do - - end subroutine s_pack_model_for_gpu + end subroutine end module m_model diff --git a/src/common/m_mpi_common.fpp b/src/common/m_mpi_common.fpp index 8a719f5758..882f032d8e 100644 --- a/src/common/m_mpi_common.fpp +++ b/src/common/m_mpi_common.fpp @@ -9,22 +9,40 @@ module m_mpi_common #ifdef MFC_MPI - use mpi !< Message passing interface (MPI) module + use mpi !< Message passing interface (MPI) module #endif - use m_derived_types - use m_global_parameters + use m_derived_types !< Definitions of the derived types + + use m_global_parameters !< Definitions of the global parameters + use m_helper + use ieee_arithmetic + use m_nvtx implicit none integer, private :: v_size $:GPU_DECLARE(create='[v_size]') + !! Generic flags used to identify and report MPI errors + + real(wp), private, allocatable, dimension(:) :: buff_send !< + !! This variable is utilized to pack and send the buffer of the cell-average + !! primitive variables, for a single computational domain boundary at the + !! time, to the relevant neighboring processor. + + real(wp), private, allocatable, dimension(:) :: buff_recv !< + !! buff_recv is utilized to receive and unpack the buffer of the cell- + !! average primitive variables, for a single computational domain boundary + !! at the time, from the relevant neighboring processor. + + type(int_bounds_info) :: comm_coords(3) + integer :: comm_size(3) + $:GPU_DECLARE(create='[comm_coords, comm_size]') + !! Variables for EL bubbles communication - real(wp), private, allocatable, dimension(:) :: buff_send !< Primitive variable send buffer for halo exchange - real(wp), private, allocatable, dimension(:) :: buff_recv !< Primitive variable receive buffer for halo exchange #ifndef __NVCOMPILER_GPU_UNIFIED_MEM $:GPU_DECLARE(create='[buff_send, buff_recv]') #endif @@ -34,12 +52,15 @@ module m_mpi_common contains - !> Initialize the module. + !> The computation of parameters, the allocation of memory, + !! the association of pointers and/or the execution of any + !! other procedures that are necessary to setup the module. impure subroutine s_initialize_mpi_common_module #ifdef MFC_MPI - ! Allocating buff_send/recv and. Please note that for the sake of simplicity, both variables are provided sufficient storage - ! to hold the largest buffer in the computational domain. + ! Allocating buff_send/recv and. Please note that for the sake of + ! simplicity, both variables are provided sufficient storage to hold + ! the largest buffer in the computational domain. if (qbmm .and. .not. polytropic) then v_size = sys_size + 2*nb*nnode @@ -49,10 +70,14 @@ contains if (n > 0) then if (p > 0) then - halo_size = nint(-1._wp + 1._wp*buff_size*(v_size)*(m + 2*buff_size + 1)*(n + 2*buff_size + 1)*(p + 2*buff_size & - & + 1)/(cells_bounds%mnp_min + 2*buff_size + 1)) + halo_size = nint(-1._wp + 1._wp*buff_size*(v_size)* & + & (m + 2*buff_size + 1)* & + & (n + 2*buff_size + 1)* & + & (p + 2*buff_size + 1)/ & + & (cells_bounds%mnp_min + 2*buff_size + 1)) else - halo_size = -1 + buff_size*(v_size)*(cells_bounds%mn_max + 2*buff_size + 1) + halo_size = -1 + buff_size*(v_size)* & + & (cells_bounds%mn_max + 2*buff_size + 1) end if else halo_size = -1 + buff_size*(v_size) @@ -71,41 +96,56 @@ contains end subroutine s_initialize_mpi_common_module - !> Initialize the MPI execution environment and query the number of processors and local rank. + !> The subroutine initializes the MPI execution environment + !! and queries both the number of processors which will be + !! available for the job and the local processor rank. impure subroutine s_mpi_initialize #ifdef MFC_MPI - integer :: ierr !< Generic flag used to identify and report MPI errors + integer :: ierr !< Generic flag used to identify and report MPI errors + ! Initializing the MPI environment call MPI_INIT(ierr) + ! Checking whether the MPI environment has been properly initialized if (ierr /= MPI_SUCCESS) then print '(A)', 'Unable to initialize MPI environment. Exiting.' call MPI_ABORT(MPI_COMM_WORLD, 1, ierr) end if + ! Querying the number of processors available for the job call MPI_COMM_SIZE(MPI_COMM_WORLD, num_procs, ierr) + ! Querying the rank of the local processor call MPI_COMM_RANK(MPI_COMM_WORLD, proc_rank, ierr) #else + ! Serial run only has 1 processor num_procs = 1 + ! Local processor rank is 0 proc_rank = 0 #endif end subroutine s_mpi_initialize - !> Set up MPI I/O data views and variable pointers for parallel file output. + !! @param q_cons_vf Conservative variables + !! @param ib_markers track if a cell is within the immersed boundary + !! @param beta Eulerian void fraction from lagrangian bubbles impure subroutine s_initialize_mpi_data(q_cons_vf, ib_markers, beta) type(scalar_field), dimension(sys_size), intent(in) :: q_cons_vf - type(integer_field), optional, intent(in) :: ib_markers - type(scalar_field), intent(in), optional :: beta - integer, dimension(num_dims) :: sizes_glb, sizes_loc - integer, dimension(1) :: airfoil_glb, airfoil_loc, airfoil_start + type(integer_field), optional, intent(in) :: ib_markers + type(scalar_field), intent(in), optional :: beta + + integer, dimension(num_dims) :: sizes_glb, sizes_loc + integer, dimension(1) :: airfoil_glb, airfoil_loc, airfoil_start #ifdef MFC_MPI + + ! Generic loop iterator integer :: i, j - integer :: ierr !< Generic flag used to identify and report MPI errors + integer :: ierr !< Generic flag used to identify and report MPI errors + + !Altered system size for the lagrangian subgrid bubble model integer :: alt_sys if (present(beta)) then @@ -115,23 +155,23 @@ contains end if do i = 1, sys_size - MPI_IO_DATA%var(i)%sf => q_cons_vf(i)%sf(0:m,0:n,0:p) + MPI_IO_DATA%var(i)%sf => q_cons_vf(i)%sf(0:m, 0:n, 0:p) end do if (present(beta)) then - MPI_IO_DATA%var(alt_sys)%sf => beta%sf(0:m,0:n,0:p) + MPI_IO_DATA%var(alt_sys)%sf => beta%sf(0:m, 0:n, 0:p) end if - ! Additional variables pb and mv for non-polytropic qbmm + !Additional variables pb and mv for non-polytropic qbmm if (qbmm .and. .not. polytropic) then do i = 1, nb do j = 1, nnode #ifdef MFC_PRE_PROCESS - MPI_IO_DATA%var(sys_size + (i - 1)*nnode + j)%sf => pb%sf(0:m,0:n,0:p,j, i) - MPI_IO_DATA%var(sys_size + (i - 1)*nnode + j + nb*nnode)%sf => mv%sf(0:m,0:n,0:p,j, i) + MPI_IO_DATA%var(sys_size + (i - 1)*nnode + j)%sf => pb%sf(0:m, 0:n, 0:p, j, i) + MPI_IO_DATA%var(sys_size + (i - 1)*nnode + j + nb*nnode)%sf => mv%sf(0:m, 0:n, 0:p, j, i) #elif defined (MFC_SIMULATION) - MPI_IO_DATA%var(sys_size + (i - 1)*nnode + j)%sf => pb_ts(1)%sf(0:m,0:n,0:p,j, i) - MPI_IO_DATA%var(sys_size + (i - 1)*nnode + j + nb*nnode)%sf => mv_ts(1)%sf(0:m,0:n,0:p,j, i) + MPI_IO_DATA%var(sys_size + (i - 1)*nnode + j)%sf => pb_ts(1)%sf(0:m, 0:n, 0:p, j, i) + MPI_IO_DATA%var(sys_size + (i - 1)*nnode + j + nb*nnode)%sf => mv_ts(1)%sf(0:m, 0:n, 0:p, j, i) #endif end do end do @@ -148,42 +188,49 @@ contains ! Define the view for each variable do i = 1, alt_sys - call MPI_TYPE_CREATE_SUBARRAY(num_dims, sizes_glb, sizes_loc, start_idx, MPI_ORDER_FORTRAN, mpi_p, & - & MPI_IO_DATA%view(i), ierr) + call MPI_TYPE_CREATE_SUBARRAY(num_dims, sizes_glb, sizes_loc, start_idx, & + MPI_ORDER_FORTRAN, mpi_p, MPI_IO_DATA%view(i), ierr) call MPI_TYPE_COMMIT(MPI_IO_DATA%view(i), ierr) end do #ifndef MFC_POST_PROCESS if (qbmm .and. .not. polytropic) then do i = sys_size + 1, sys_size + 2*nb*nnode - call MPI_TYPE_CREATE_SUBARRAY(num_dims, sizes_glb, sizes_loc, start_idx, MPI_ORDER_FORTRAN, mpi_p, & - & MPI_IO_DATA%view(i), ierr) + call MPI_TYPE_CREATE_SUBARRAY(num_dims, sizes_glb, sizes_loc, start_idx, & + MPI_ORDER_FORTRAN, mpi_p, MPI_IO_DATA%view(i), ierr) call MPI_TYPE_COMMIT(MPI_IO_DATA%view(i), ierr) + end do end if #endif #ifndef MFC_PRE_PROCESS if (present(ib_markers)) then - MPI_IO_IB_DATA%var%sf => ib_markers%sf(0:m,0:n,0:p) + MPI_IO_IB_DATA%var%sf => ib_markers%sf(0:m, 0:n, 0:p) - call MPI_TYPE_CREATE_SUBARRAY(num_dims, sizes_glb, sizes_loc, start_idx, MPI_ORDER_FORTRAN, MPI_INTEGER, & - & MPI_IO_IB_DATA%view, ierr) + call MPI_TYPE_CREATE_SUBARRAY(num_dims, sizes_glb, sizes_loc, start_idx, & + MPI_ORDER_FORTRAN, MPI_INTEGER, MPI_IO_IB_DATA%view, ierr) call MPI_TYPE_COMMIT(MPI_IO_IB_DATA%view, ierr) end if #endif + #endif end subroutine s_initialize_mpi_data - !> Set up MPI I/O data views for downsampled (coarsened) parallel file output. + !! @param q_cons_vf Conservative variables subroutine s_initialize_mpi_data_ds(q_cons_vf) - type(scalar_field), dimension(sys_size), intent(in) :: q_cons_vf - integer, dimension(num_dims) :: sizes_glb, sizes_loc - integer, dimension(3) :: sf_start_idx + type(scalar_field), & + dimension(sys_size), & + intent(in) :: q_cons_vf + + integer, dimension(num_dims) :: sizes_glb, sizes_loc + integer, dimension(3) :: sf_start_idx #ifdef MFC_MPI + + ! Generic loop iterator integer :: i, j, q, k, l, m_ds, n_ds, p_ds, ierr sf_start_idx = (/0, 0, 0/) @@ -200,7 +247,7 @@ contains #ifdef MFC_POST_PROCESS do i = 1, sys_size - MPI_IO_DATA%var(i)%sf => q_cons_vf(i)%sf(-1:m_ds + 1,-1:n_ds + 1,-1:p_ds + 1) + MPI_IO_DATA%var(i)%sf => q_cons_vf(i)%sf(-1:m_ds + 1, -1:n_ds + 1, -1:p_ds + 1) end do #endif ! Define global(g) and local(l) sizes for flow variables @@ -214,29 +261,32 @@ contains ! Define the view for each variable do i = 1, sys_size - call MPI_TYPE_CREATE_SUBARRAY(num_dims, sizes_loc, sizes_loc, sf_start_idx, MPI_ORDER_FORTRAN, mpi_p, & - & MPI_IO_DATA%view(i), ierr) + call MPI_TYPE_CREATE_SUBARRAY(num_dims, sizes_loc, sizes_loc, sf_start_idx, & + MPI_ORDER_FORTRAN, mpi_p, MPI_IO_DATA%view(i), ierr) call MPI_TYPE_COMMIT(MPI_IO_DATA%view(i), ierr) end do #endif end subroutine s_initialize_mpi_data_ds - !> Gather variable-length real vectors from all MPI ranks onto the root process. + !> @brief Gathers variable-length real vectors from all MPI ranks onto the root process. impure subroutine s_mpi_gather_data(my_vector, counts, gathered_vector, root) - integer, intent(in) :: counts !< Array of vector lengths for each process - real(wp), intent(in), dimension(counts) :: my_vector !< Input vector on each process - integer, intent(in) :: root !< Rank of the root process - real(wp), allocatable, intent(out) :: gathered_vector(:) !< Gathered vector on the root process - integer :: i - integer :: ierr !< Generic flag used to identify and report MPI errors - integer, allocatable :: recounts(:), displs(:) + integer, intent(in) :: counts ! Array of vector lengths for each process + real(wp), intent(in), dimension(counts) :: my_vector ! Input vector on each process + integer, intent(in) :: root ! Rank of the root process + real(wp), allocatable, intent(out) :: gathered_vector(:) ! Gathered vector on the root process + + integer :: i + integer :: ierr !< Generic flag used to identify and report MPI errors + integer, allocatable :: recounts(:), displs(:) #ifdef MFC_MPI + allocate (recounts(num_procs)) - call MPI_GATHER(counts, 1, MPI_INTEGER, recounts, 1, MPI_INTEGER, root, MPI_COMM_WORLD, ierr) + call MPI_GATHER(counts, 1, MPI_INTEGER, recounts, 1, MPI_INTEGER, root, & + MPI_COMM_WORLD, ierr) allocate (displs(size(recounts))) @@ -247,28 +297,28 @@ contains end do allocate (gathered_vector(sum(recounts))) - call MPI_GATHERV(my_vector, counts, mpi_p, gathered_vector, recounts, displs, mpi_p, root, MPI_COMM_WORLD, ierr) + call MPI_GATHERV(my_vector, counts, mpi_p, gathered_vector, recounts, displs, mpi_p, & + root, MPI_COMM_WORLD, ierr) #endif - end subroutine s_mpi_gather_data - !> Gather per-rank time step wall-clock times onto rank 0 for performance reporting. + !> @brief Gathers per-rank time step wall-clock times onto rank 0 for performance reporting. impure subroutine mpi_bcast_time_step_values(proc_time, time_avg) real(wp), dimension(0:num_procs - 1), intent(inout) :: proc_time - real(wp), intent(inout) :: time_avg + real(wp), intent(inout) :: time_avg #ifdef MFC_MPI - integer :: ierr !< Generic flag used to identify and report MPI errors + integer :: ierr !< Generic flag used to identify and report MPI errors call MPI_GATHER(time_avg, 1, mpi_p, proc_time(0), 1, mpi_p, 0, MPI_COMM_WORLD, ierr) + #endif end subroutine mpi_bcast_time_step_values - !> Print a case file error with the prohibited condition and message, then abort execution. + !> @brief Prints a case file error with the prohibited condition and message, then aborts execution. impure subroutine s_prohibit_abort(condition, message) - character(len=*), intent(in) :: condition, message print *, "" @@ -279,174 +329,309 @@ contains end if print *, "" call s_mpi_abort(code=CASE_FILE_ERROR_CODE) - end subroutine s_prohibit_abort - !> The goal of this subroutine is to determine the global extrema of the stability criteria in the computational domain. This is - !! performed by sifting through the local extrema of each stability criterion. Note that each of the local extrema is from a - !! single process, within its assigned section of the computational domain. Finally, note that the global extrema values are - !! only bookkeept on the rank 0 processor. - impure subroutine s_mpi_reduce_stability_criteria_extrema(icfl_max_loc, vcfl_max_loc, Rc_min_loc, icfl_max_glb, vcfl_max_glb, & - - & Rc_min_glb) + !> The goal of this subroutine is to determine the global + !! extrema of the stability criteria in the computational + !! domain. This is performed by sifting through the local + !! extrema of each stability criterion. Note that each of + !! the local extrema is from a single process, within its + !! assigned section of the computational domain. Finally, + !! note that the global extrema values are only bookkeept + !! on the rank 0 processor. + !! @param icfl_max_loc Local maximum ICFL stability criterion + !! @param vcfl_max_loc Local maximum VCFL stability criterion + !! @param Rc_min_loc Local minimum Rc stability criterion + !! @param icfl_max_glb Global maximum ICFL stability criterion + !! @param vcfl_max_glb Global maximum VCFL stability criterion + !! @param Rc_min_glb Global minimum Rc stability criterion + impure subroutine s_mpi_reduce_stability_criteria_extrema(icfl_max_loc, & + vcfl_max_loc, & + Rc_min_loc, & + bubs_loc, & + icfl_max_glb, & + vcfl_max_glb, & + Rc_min_glb, & + bubs_glb) + + real(wp), intent(in) :: icfl_max_loc + real(wp), intent(in) :: vcfl_max_loc + real(wp), intent(in) :: Rc_min_loc + integer, intent(in) :: bubs_loc - real(wp), intent(in) :: icfl_max_loc - real(wp), intent(in) :: vcfl_max_loc - real(wp), intent(in) :: Rc_min_loc real(wp), intent(out) :: icfl_max_glb real(wp), intent(out) :: vcfl_max_glb real(wp), intent(out) :: Rc_min_glb + integer, intent(out) :: bubs_glb #ifdef MFC_SIMULATION #ifdef MFC_MPI - integer :: ierr !< Generic flag used to identify and report MPI errors + integer :: ierr !< Generic flag used to identify and report MPI errors - call MPI_REDUCE(icfl_max_loc, icfl_max_glb, 1, mpi_p, MPI_MAX, 0, MPI_COMM_WORLD, ierr) + bubs_glb = 0 + + ! Reducing local extrema of ICFL, VCFL, CCFL and Rc numbers to their + ! global extrema and bookkeeping the results on the rank 0 processor + call MPI_REDUCE(icfl_max_loc, icfl_max_glb, 1, & + mpi_p, MPI_MAX, 0, & + MPI_COMM_WORLD, ierr) if (viscous) then - call MPI_REDUCE(vcfl_max_loc, vcfl_max_glb, 1, mpi_p, MPI_MAX, 0, MPI_COMM_WORLD, ierr) - call MPI_REDUCE(Rc_min_loc, Rc_min_glb, 1, mpi_p, MPI_MIN, 0, MPI_COMM_WORLD, ierr) + call MPI_REDUCE(vcfl_max_loc, vcfl_max_glb, 1, & + mpi_p, MPI_MAX, 0, & + MPI_COMM_WORLD, ierr) + call MPI_REDUCE(Rc_min_loc, Rc_min_glb, 1, & + mpi_p, MPI_MIN, 0, & + MPI_COMM_WORLD, ierr) + end if + + if (bubbles_lagrange) then + call MPI_REDUCE(bubs_loc, bubs_glb, 1, & + MPI_INTEGER, MPI_SUM, 0, & + MPI_COMM_WORLD, ierr) end if #else + icfl_max_glb = icfl_max_loc + bubs_glb = 0 if (viscous) then vcfl_max_glb = vcfl_max_loc Rc_min_glb = Rc_min_loc end if + + if (bubbles_lagrange) bubs_glb = bubs_loc #endif #endif end subroutine s_mpi_reduce_stability_criteria_extrema - !> Reduce a local real value to its global sum across all MPI ranks. + !> The following subroutine takes the inputted variable and + !! determines its sum on the entire computational domain. + !! @param var_loc holds the local value to be reduced among + !! all the processors in communicator. On output, the variable holds + !! the sum, reduced amongst all of the local values. + subroutine s_mpi_reduce_int_sum(var_loc, sum) + + integer, intent(in) :: var_loc + integer, intent(out) :: sum + +#ifdef MFC_MPI + integer :: ierr !< Generic flag used to identify and report MPI errors + + ! Performing reduction procedure and eventually storing its result + ! into the variable that was initially inputted into the subroutine + call MPI_REDUCE(var_loc, sum, 1, MPI_INTEGER, & + MPI_SUM, 0, MPI_COMM_WORLD, ierr) + +#else + sum = var_loc +#endif + + end subroutine s_mpi_reduce_int_sum + + !> The following subroutine takes the input local variable + !! from all processors and reduces to the sum of all + !! values. The reduced variable is recorded back onto the + !! original local variable on each processor. + !! @param var_loc Some variable containing the local value which should be + !! reduced amongst all the processors in the communicator. + !! @param var_glb The globally reduced value impure subroutine s_mpi_allreduce_sum(var_loc, var_glb) - real(wp), intent(in) :: var_loc + real(wp), intent(in) :: var_loc real(wp), intent(out) :: var_glb #ifdef MFC_MPI - integer :: ierr !< Generic flag used to identify and report MPI errors + integer :: ierr !< Generic flag used to identify and report MPI errors + + ! Performing the reduction procedure + call MPI_ALLREDUCE(var_loc, var_glb, 1, mpi_p, & + MPI_SUM, MPI_COMM_WORLD, ierr) - call MPI_ALLREDUCE(var_loc, var_glb, 1, mpi_p, MPI_SUM, MPI_COMM_WORLD, ierr) #endif end subroutine s_mpi_allreduce_sum - !> Reduce an array of vectors to their global sums across all MPI ranks. + !> This subroutine follows the behavior of the s_mpi_allreduce_sum subroutine + !> with the additional feature that it reduces an array of vectors. impure subroutine s_mpi_allreduce_vectors_sum(var_loc, var_glb, num_vectors, vector_length) - integer, intent(in) :: num_vectors, vector_length - real(wp), dimension(:,:), intent(in) :: var_loc - real(wp), dimension(:,:), intent(out) :: var_glb + integer, intent(in) :: num_vectors, vector_length + real(wp), dimension(:, :), intent(in) :: var_loc + real(wp), dimension(:, :), intent(out) :: var_glb #ifdef MFC_MPI - integer :: ierr !< Generic flag used to identify and report MPI errors + integer :: ierr !< Generic flag used to identify and report MPI errors + ! Performing the reduction procedure if (loc(var_loc) == loc(var_glb)) then - call MPI_Allreduce(MPI_IN_PLACE, var_glb, num_vectors*vector_length, mpi_p, MPI_SUM, MPI_COMM_WORLD, ierr) + call MPI_Allreduce(MPI_IN_PLACE, var_glb, num_vectors*vector_length, & + mpi_p, MPI_SUM, MPI_COMM_WORLD, ierr) else - call MPI_Allreduce(var_loc, var_glb, num_vectors*vector_length, mpi_p, MPI_SUM, MPI_COMM_WORLD, ierr) + call MPI_Allreduce(var_loc, var_glb, num_vectors*vector_length, & + mpi_p, MPI_SUM, MPI_COMM_WORLD, ierr) end if + #else - var_glb(1:num_vectors,1:vector_length) = var_loc(1:num_vectors,1:vector_length) + var_glb(1:num_vectors, 1:vector_length) = var_loc(1:num_vectors, 1:vector_length) #endif end subroutine s_mpi_allreduce_vectors_sum - !> Reduce a local integer value to its global sum across all MPI ranks. + !> The following subroutine takes the input local variable + !! from all processors and reduces to the sum of all + !! values. The reduced variable is recorded back onto the + !! original local variable on each processor. + !! @param var_loc Some variable containing the local value which should be + !! reduced amongst all the processors in the communicator. + !! @param var_glb The globally reduced value impure subroutine s_mpi_allreduce_integer_sum(var_loc, var_glb) - integer, intent(in) :: var_loc + integer, intent(in) :: var_loc integer, intent(out) :: var_glb #ifdef MFC_MPI - integer :: ierr !< Generic flag used to identify and report MPI errors + integer :: ierr !< Generic flag used to identify and report MPI errors - call MPI_ALLREDUCE(var_loc, var_glb, 1, MPI_INTEGER, MPI_SUM, MPI_COMM_WORLD, ierr) + ! Performing the reduction procedure + call MPI_ALLREDUCE(var_loc, var_glb, 1, MPI_INTEGER, & + MPI_SUM, MPI_COMM_WORLD, ierr) #else var_glb = var_loc #endif end subroutine s_mpi_allreduce_integer_sum - !> Reduce a local real value to its global minimum across all MPI ranks. + !> The following subroutine takes the input local variable + !! from all processors and reduces to the minimum of all + !! values. The reduced variable is recorded back onto the + !! original local variable on each processor. + !! @param var_loc Some variable containing the local value which should be + !! reduced amongst all the processors in the communicator. + !! @param var_glb The globally reduced value impure subroutine s_mpi_allreduce_min(var_loc, var_glb) - real(wp), intent(in) :: var_loc + real(wp), intent(in) :: var_loc real(wp), intent(out) :: var_glb #ifdef MFC_MPI - integer :: ierr !< Generic flag used to identify and report MPI errors + integer :: ierr !< Generic flag used to identify and report MPI errors + + ! Performing the reduction procedure + call MPI_ALLREDUCE(var_loc, var_glb, 1, mpi_p, & + MPI_MIN, MPI_COMM_WORLD, ierr) - call MPI_ALLREDUCE(var_loc, var_glb, 1, mpi_p, MPI_MIN, MPI_COMM_WORLD, ierr) #endif end subroutine s_mpi_allreduce_min - !> Reduce a local real value to its global maximum across all MPI ranks. + !> The following subroutine takes the input local variable + !! from all processors and reduces to the maximum of all + !! values. The reduced variable is recorded back onto the + !! original local variable on each processor. + !! @param var_loc Some variable containing the local value which should be + !! reduced amongst all the processors in the communicator. + !! @param var_glb The globally reduced value impure subroutine s_mpi_allreduce_max(var_loc, var_glb) - real(wp), intent(in) :: var_loc + real(wp), intent(in) :: var_loc real(wp), intent(out) :: var_glb #ifdef MFC_MPI - integer :: ierr !< Generic flag used to identify and report MPI errors + integer :: ierr !< Generic flag used to identify and report MPI errors + + ! Performing the reduction procedure + call MPI_ALLREDUCE(var_loc, var_glb, 1, mpi_p, & + MPI_MAX, MPI_COMM_WORLD, ierr) - call MPI_ALLREDUCE(var_loc, var_glb, 1, mpi_p, MPI_MAX, MPI_COMM_WORLD, ierr) #endif end subroutine s_mpi_allreduce_max - !> Reduce a local real value to its global minimum across all ranks + !> The following subroutine takes the inputted variable and + !! determines its minimum value on the entire computational + !! domain. The result is stored back into inputted variable. + !! @param var_loc holds the local value to be reduced among + !! all the processors in communicator. On output, the variable holds + !! the minimum value, reduced amongst all of the local values. impure subroutine s_mpi_reduce_min(var_loc) real(wp), intent(inout) :: var_loc #ifdef MFC_MPI - integer :: ierr !< Generic flag used to identify and report MPI errors + integer :: ierr !< Generic flag used to identify and report MPI errors + + ! Temporary storage variable that holds the reduced minimum value real(wp) :: var_glb - call MPI_REDUCE(var_loc, var_glb, 1, mpi_p, MPI_MIN, 0, MPI_COMM_WORLD, ierr) + ! Performing reduction procedure and eventually storing its result + ! into the variable that was initially inputted into the subroutine + call MPI_REDUCE(var_loc, var_glb, 1, mpi_p, & + MPI_MIN, 0, MPI_COMM_WORLD, ierr) - call MPI_BCAST(var_glb, 1, mpi_p, 0, MPI_COMM_WORLD, ierr) + call MPI_BCAST(var_glb, 1, mpi_p, & + 0, MPI_COMM_WORLD, ierr) var_loc = var_glb + #endif end subroutine s_mpi_reduce_min - !> Reduce a 2-element variable to its global maximum value with the owning processor rank (MPI_MAXLOC). - !> Reduce a local value to its global maximum with location (rank) across all ranks + !> The following subroutine takes the first element of the + !! 2-element inputted variable and determines its maximum + !! value on the entire computational domain. The result is + !! stored back into the first element of the variable while + !! the rank of the processor that is in charge of the sub- + !! domain containing the maximum is stored into the second + !! element of the variable. + !! @param var_loc On input, this variable holds the local value and processor rank, + !! which are to be reduced among all the processors in communicator. + !! On output, this variable holds the maximum value, reduced amongst + !! all of the local values, and the process rank to which the value + !! belongs. impure subroutine s_mpi_reduce_maxloc(var_loc) real(wp), dimension(2), intent(inout) :: var_loc #ifdef MFC_MPI - integer :: ierr !< Generic flag used to identify and report MPI errors - real(wp), dimension(2) :: var_glb !< Reduced (max value, rank) pair - call MPI_REDUCE(var_loc, var_glb, 1, mpi_2p, MPI_MAXLOC, 0, MPI_COMM_WORLD, ierr) + integer :: ierr !< Generic flag used to identify and report MPI errors + + real(wp), dimension(2) :: var_glb !< + !! Temporary storage variable that holds the reduced maximum value + !! and the rank of the processor with which the value is associated + + ! Performing reduction procedure and eventually storing its result + ! into the variable that was initially inputted into the subroutine + call MPI_REDUCE(var_loc, var_glb, 1, mpi_2p, & + MPI_MAXLOC, 0, MPI_COMM_WORLD, ierr) - call MPI_BCAST(var_glb, 1, mpi_2p, 0, MPI_COMM_WORLD, ierr) + call MPI_BCAST(var_glb, 1, mpi_2p, & + 0, MPI_COMM_WORLD, ierr) var_loc = var_glb + #endif end subroutine s_mpi_reduce_maxloc !> The subroutine terminates the MPI execution environment. + !! @param prnt error message to be printed + !! @param code optional exit code impure subroutine s_mpi_abort(prnt, code) character(len=*), intent(in), optional :: prnt - integer, intent(in), optional :: code + integer, intent(in), optional :: code #ifdef MFC_MPI - integer :: ierr !< Generic flag used to identify and report MPI errors + integer :: ierr !< Generic flag used to identify and report MPI errors #endif if (present(prnt)) then print *, prnt call flush (6) + end if #ifndef MFC_MPI @@ -456,6 +641,7 @@ contains stop 1 end if #else + ! Terminating the MPI environment if (present(code)) then call MPI_ABORT(MPI_COMM_WORLD, code, ierr) else @@ -465,13 +651,15 @@ contains end subroutine s_mpi_abort - !> Halts all processes until all have reached barrier. + !>Halts all processes until all have reached barrier. impure subroutine s_mpi_barrier #ifdef MFC_MPI - integer :: ierr !< Generic flag used to identify and report MPI errors + integer :: ierr !< Generic flag used to identify and report MPI errors + ! Calling MPI_BARRIER call MPI_BARRIER(MPI_COMM_WORLD, ierr) + #endif end subroutine s_mpi_barrier @@ -480,30 +668,48 @@ contains impure subroutine s_mpi_finalize #ifdef MFC_MPI - integer :: ierr !< Generic flag used to identify and report MPI errors + integer :: ierr !< Generic flag used to identify and report MPI errors + ! Finalizing the MPI environment call MPI_FINALIZE(ierr) + #endif end subroutine s_mpi_finalize - !> The goal of this procedure is to populate the buffers of the cell-average conservative variables by communicating with the - !! neighboring processors. - subroutine s_mpi_sendrecv_variables_buffers(q_comm, mpi_dir, pbc_loc, nVar, pb_in, mv_in) + !> The goal of this procedure is to populate the buffers of + !! the cell-average conservative variables by communicating + !! with the neighboring processors. + !! @param q_comm Cell-average conservative variables + !! @param mpi_dir MPI communication coordinate direction + !! @param pbc_loc Processor boundary condition (PBC) location + !! @param nVar Number of variables to communicate + !! @param pb_in Optional internal bubble pressure + !! @param mv_in Optional bubble mass velocity + subroutine s_mpi_sendrecv_variables_buffers(q_comm, & + mpi_dir, & + pbc_loc, & + nVar, & + pb_in, mv_in) type(scalar_field), dimension(1:), intent(inout) :: q_comm - real(stp), optional, dimension(idwbuff(1)%beg:,idwbuff(2)%beg:,idwbuff(3)%beg:,1:,1:), intent(inout) :: pb_in, mv_in + real(stp), optional, dimension(idwbuff(1)%beg:, idwbuff(2)%beg:, idwbuff(3)%beg:, 1:, 1:), intent(inout) :: pb_in, mv_in integer, intent(in) :: mpi_dir, pbc_loc, nVar - integer :: i, j, k, l, r, q !< Generic loop iterators + + integer :: i, j, k, l, r, q !< Generic loop iterators + integer :: buffer_counts(1:3), buffer_count + type(int_bounds_info) :: boundary_conditions(1:3) integer :: beg_end(1:2), grid_dims(1:3) integer :: dst_proc, src_proc, recv_tag, send_tag + logical :: beg_end_geq_0, qbmm_comm + integer :: pack_offset, unpack_offset #ifdef MFC_MPI - integer :: ierr !< Generic flag used to identify and report MPI errors + integer :: ierr !< Generic flag used to identify and report MPI errors call nvtxStartRange("RHS-COMM-PACKBUF") @@ -512,12 +718,18 @@ contains if (present(pb_in) .and. present(mv_in) .and. qbmm .and. .not. polytropic) then qbmm_comm = .true. v_size = nVar + 2*nb*nnode - buffer_counts = (/buff_size*v_size*(n + 1)*(p + 1), buff_size*v_size*(m + 2*buff_size + 1)*(p + 1), & - & buff_size*v_size*(m + 2*buff_size + 1)*(n + 2*buff_size + 1)/) + buffer_counts = (/ & + buff_size*v_size*(n + 1)*(p + 1), & + buff_size*v_size*(m + 2*buff_size + 1)*(p + 1), & + buff_size*v_size*(m + 2*buff_size + 1)*(n + 2*buff_size + 1) & + /) else v_size = nVar - buffer_counts = (/buff_size*v_size*(n + 1)*(p + 1), buff_size*v_size*(m + 2*buff_size + 1)*(p + 1), & - & buff_size*v_size*(m + 2*buff_size + 1)*(n + 2*buff_size + 1)/) + buffer_counts = (/ & + buff_size*v_size*(n + 1)*(p + 1), & + buff_size*v_size*(m + 2*buff_size + 1)*(p + 1), & + buff_size*v_size*(m + 2*buff_size + 1)*(n + 2*buff_size + 1) & + /) end if $:GPU_UPDATE(device='[v_size]') @@ -527,9 +739,12 @@ contains beg_end = (/boundary_conditions(mpi_dir)%beg, boundary_conditions(mpi_dir)%end/) beg_end_geq_0 = beg_end(max(pbc_loc, 0) - pbc_loc + 1) >= 0 - ! Implements: pbc_loc bc_x >= 0 -> [send/recv]_tag [dst/src]_proc -1 (=0) 0 -> [1,0] [0,0] | 0 0 [1,0] [beg,beg] -1 (=0) 1 - ! -> [0,0] [1,0] | 0 1 [0,0] [end,beg] +1 (=1) 0 -> [0,1] [1,1] | 1 0 [0,1] [end,end] +1 (=1) 1 -> [1,1] [0,1] | 1 1 [1,1] - ! [beg,end] + ! Implements: + ! pbc_loc bc_x >= 0 -> [send/recv]_tag [dst/src]_proc + ! -1 (=0) 0 -> [1,0] [0,0] | 0 0 [1,0] [beg,beg] + ! -1 (=0) 1 -> [0,0] [1,0] | 0 1 [0,0] [end,beg] + ! +1 (=1) 0 -> [0,1] [1,1] | 1 0 [0,1] [end,end] + ! +1 (=1) 1 -> [1,1] [0,1] | 1 1 [1,1] [beg,end] send_tag = f_logical_to_int(.not. f_xor(beg_end_geq_0, pbc_loc == 1)) recv_tag = f_logical_to_int(pbc_loc == 1) @@ -573,7 +788,8 @@ contains do j = 0, buff_size - 1 do i = nVar + 1, nVar + nnode do q = 1, nb - r = (i - 1) + (q - 1)*nnode + v_size*(j + buff_size*(k + (n + 1)*l)) + r = (i - 1) + (q - 1)*nnode + v_size* & + (j + buff_size*(k + (n + 1)*l)) buff_send(r) = real(pb_in(j + pack_offset, k, l, i - nVar, q), kind=wp) end do end do @@ -588,7 +804,8 @@ contains do j = 0, buff_size - 1 do i = nVar + 1, nVar + nnode do q = 1, nb - r = (i - 1) + (q - 1)*nnode + nb*nnode + v_size*(j + buff_size*(k + (n + 1)*l)) + r = (i - 1) + (q - 1)*nnode + nb*nnode + v_size* & + (j + buff_size*(k + (n + 1)*l)) buff_send(r) = real(mv_in(j + pack_offset, k, l, i - nVar, q), kind=wp) end do end do @@ -603,7 +820,9 @@ contains do l = 0, p do k = 0, buff_size - 1 do j = -buff_size, m + buff_size - r = (i - 1) + v_size*((j + buff_size) + (m + 2*buff_size + 1)*(k + buff_size*l)) + r = (i - 1) + v_size* & + ((j + buff_size) + (m + 2*buff_size + 1)* & + (k + buff_size*l)) buff_send(r) = real(q_comm(i)%sf(j, k + pack_offset, l), kind=wp) end do end do @@ -618,8 +837,9 @@ contains do k = 0, buff_size - 1 do j = -buff_size, m + buff_size do q = 1, nb - r = (i - 1) + (q - 1)*nnode + v_size*((j + buff_size) + (m + 2*buff_size + 1)*(k & - & + buff_size*l)) + r = (i - 1) + (q - 1)*nnode + v_size* & + ((j + buff_size) + (m + 2*buff_size + 1)* & + (k + buff_size*l)) buff_send(r) = real(pb_in(j, k + pack_offset, l, i - nVar, q), kind=wp) end do end do @@ -634,8 +854,9 @@ contains do k = 0, buff_size - 1 do j = -buff_size, m + buff_size do q = 1, nb - r = (i - 1) + (q - 1)*nnode + nb*nnode + v_size*((j + buff_size) + (m + 2*buff_size & - & + 1)*(k + buff_size*l)) + r = (i - 1) + (q - 1)*nnode + nb*nnode + v_size* & + ((j + buff_size) + (m + 2*buff_size + 1)* & + (k + buff_size*l)) buff_send(r) = real(mv_in(j, k + pack_offset, l, i - nVar, q), kind=wp) end do end do @@ -650,8 +871,9 @@ contains do l = 0, buff_size - 1 do k = -buff_size, n + buff_size do j = -buff_size, m + buff_size - r = (i - 1) + v_size*((j + buff_size) + (m + 2*buff_size + 1)*((k + buff_size) + (n & - & + 2*buff_size + 1)*l)) + r = (i - 1) + v_size* & + ((j + buff_size) + (m + 2*buff_size + 1)* & + ((k + buff_size) + (n + 2*buff_size + 1)*l)) buff_send(r) = real(q_comm(i)%sf(j, k, l + pack_offset), kind=wp) end do end do @@ -666,8 +888,9 @@ contains do k = -buff_size, n + buff_size do j = -buff_size, m + buff_size do q = 1, nb - r = (i - 1) + (q - 1)*nnode + v_size*((j + buff_size) + (m + 2*buff_size + 1)*((k & - & + buff_size) + (n + 2*buff_size + 1)*l)) + r = (i - 1) + (q - 1)*nnode + v_size* & + ((j + buff_size) + (m + 2*buff_size + 1)* & + ((k + buff_size) + (n + 2*buff_size + 1)*l)) buff_send(r) = real(pb_in(j, k, l + pack_offset, i - nVar, q), kind=wp) end do end do @@ -682,8 +905,9 @@ contains do k = -buff_size, n + buff_size do j = -buff_size, m + buff_size do q = 1, nb - r = (i - 1) + (q - 1)*nnode + nb*nnode + v_size*((j + buff_size) + (m + 2*buff_size & - & + 1)*((k + buff_size) + (n + 2*buff_size + 1)*l)) + r = (i - 1) + (q - 1)*nnode + nb*nnode + v_size* & + ((j + buff_size) + (m + 2*buff_size + 1)* & + ((k + buff_size) + (n + 2*buff_size + 1)*l)) buff_send(r) = real(mv_in(j, k, l + pack_offset, i - nVar, q), kind=wp) end do end do @@ -695,7 +919,7 @@ contains #:endif end if #:endfor - call nvtxEndRange ! Packbuf + call nvtxEndRange ! Packbuf ! Send/Recv #ifdef MFC_SIMULATION @@ -705,10 +929,13 @@ contains #:call GPU_HOST_DATA(use_device_addr='[buff_send, buff_recv]') call nvtxStartRange("RHS-COMM-SENDRECV-RDMA") - call MPI_SENDRECV(buff_send, buffer_count, mpi_p, dst_proc, send_tag, buff_recv, buffer_count, mpi_p, & - & src_proc, recv_tag, MPI_COMM_WORLD, MPI_STATUS_IGNORE, ierr) + call MPI_SENDRECV( & + buff_send, buffer_count, mpi_p, dst_proc, send_tag, & + buff_recv, buffer_count, mpi_p, src_proc, recv_tag, & + MPI_COMM_WORLD, MPI_STATUS_IGNORE, ierr) + + call nvtxEndRange ! RHS-MPI-SENDRECV-(NO)-RDMA - call nvtxEndRange ! RHS-MPI-SENDRECV-(NO)-RDMA #:endcall GPU_HOST_DATA $:GPU_WAIT() #:else @@ -717,10 +944,12 @@ contains call nvtxEndRange call nvtxStartRange("RHS-COMM-SENDRECV-NO-RMDA") - call MPI_SENDRECV(buff_send, buffer_count, mpi_p, dst_proc, send_tag, buff_recv, buffer_count, mpi_p, & - & src_proc, recv_tag, MPI_COMM_WORLD, MPI_STATUS_IGNORE, ierr) + call MPI_SENDRECV( & + buff_send, buffer_count, mpi_p, dst_proc, send_tag, & + buff_recv, buffer_count, mpi_p, src_proc, recv_tag, & + MPI_COMM_WORLD, MPI_STATUS_IGNORE, ierr) - call nvtxEndRange ! RHS-MPI-SENDRECV-(NO)-RDMA + call nvtxEndRange ! RHS-MPI-SENDRECV-(NO)-RDMA call nvtxStartRange("RHS-COMM-HOST2DEV") $:GPU_UPDATE(device='[buff_recv]') @@ -729,8 +958,10 @@ contains end if #:endfor #else - call MPI_SENDRECV(buff_send, buffer_count, mpi_p, dst_proc, send_tag, buff_recv, buffer_count, mpi_p, src_proc, recv_tag, & - & MPI_COMM_WORLD, MPI_STATUS_IGNORE, ierr) + call MPI_SENDRECV( & + buff_send, buffer_count, mpi_p, dst_proc, send_tag, & + buff_recv, buffer_count, mpi_p, src_proc, recv_tag, & + MPI_COMM_WORLD, MPI_STATUS_IGNORE, ierr) #endif ! Unpack Received Buffer @@ -743,7 +974,8 @@ contains do k = 0, n do j = -buff_size, -1 do i = 1, nVar - r = (i - 1) + v_size*(j + buff_size*((k + 1) + (n + 1)*l)) + r = (i - 1) + v_size* & + (j + buff_size*((k + 1) + (n + 1)*l)) q_comm(i)%sf(j + unpack_offset, k, l) = real(buff_recv(r), kind=stp) #if defined(__INTEL_COMPILER) if (ieee_is_nan(q_comm(i)%sf(j + unpack_offset, k, l))) then @@ -764,7 +996,8 @@ contains do j = -buff_size, -1 do i = nVar + 1, nVar + nnode do q = 1, nb - r = (i - 1) + (q - 1)*nnode + v_size*(j + buff_size*((k + 1) + (n + 1)*l)) + r = (i - 1) + (q - 1)*nnode + v_size* & + (j + buff_size*((k + 1) + (n + 1)*l)) pb_in(j + unpack_offset, k, l, i - nVar, q) = real(buff_recv(r), kind=stp) end do end do @@ -779,7 +1012,8 @@ contains do j = -buff_size, -1 do i = nVar + 1, nVar + nnode do q = 1, nb - r = (i - 1) + (q - 1)*nnode + nb*nnode + v_size*(j + buff_size*((k + 1) + (n + 1)*l)) + r = (i - 1) + (q - 1)*nnode + nb*nnode + v_size* & + (j + buff_size*((k + 1) + (n + 1)*l)) mv_in(j + unpack_offset, k, l, i - nVar, q) = real(buff_recv(r), kind=stp) end do end do @@ -794,7 +1028,9 @@ contains do l = 0, p do k = -buff_size, -1 do j = -buff_size, m + buff_size - r = (i - 1) + v_size*((j + buff_size) + (m + 2*buff_size + 1)*((k + buff_size) + buff_size*l)) + r = (i - 1) + v_size* & + ((j + buff_size) + (m + 2*buff_size + 1)* & + ((k + buff_size) + buff_size*l)) q_comm(i)%sf(j, k + unpack_offset, l) = real(buff_recv(r), kind=stp) #if defined(__INTEL_COMPILER) if (ieee_is_nan(q_comm(i)%sf(j, k + unpack_offset, l))) then @@ -815,8 +1051,9 @@ contains do k = -buff_size, -1 do j = -buff_size, m + buff_size do q = 1, nb - r = (i - 1) + (q - 1)*nnode + v_size*((j + buff_size) + (m + 2*buff_size + 1)*((k & - & + buff_size) + buff_size*l)) + r = (i - 1) + (q - 1)*nnode + v_size* & + ((j + buff_size) + (m + 2*buff_size + 1)* & + ((k + buff_size) + buff_size*l)) pb_in(j, k + unpack_offset, l, i - nVar, q) = real(buff_recv(r), kind=stp) end do end do @@ -831,8 +1068,9 @@ contains do k = -buff_size, -1 do j = -buff_size, m + buff_size do q = 1, nb - r = (i - 1) + (q - 1)*nnode + nb*nnode + v_size*((j + buff_size) + (m + 2*buff_size & - & + 1)*((k + buff_size) + buff_size*l)) + r = (i - 1) + (q - 1)*nnode + nb*nnode + v_size* & + ((j + buff_size) + (m + 2*buff_size + 1)* & + ((k + buff_size) + buff_size*l)) mv_in(j, k + unpack_offset, l, i - nVar, q) = real(buff_recv(r), kind=stp) end do end do @@ -842,13 +1080,16 @@ contains $:END_GPU_PARALLEL_LOOP() end if #:else + ! Unpacking buffer from bc_z%beg $:GPU_PARALLEL_LOOP(collapse=4,private='[r]') do i = 1, nVar do l = -buff_size, -1 do k = -buff_size, n + buff_size do j = -buff_size, m + buff_size - r = (i - 1) + v_size*((j + buff_size) + (m + 2*buff_size + 1)*((k + buff_size) + (n & - & + 2*buff_size + 1)*(l + buff_size))) + r = (i - 1) + v_size* & + ((j + buff_size) + (m + 2*buff_size + 1)* & + ((k + buff_size) + (n + 2*buff_size + 1)* & + (l + buff_size))) q_comm(i)%sf(j, k, l + unpack_offset) = real(buff_recv(r), kind=stp) #if defined(__INTEL_COMPILER) if (ieee_is_nan(q_comm(i)%sf(j, k, l + unpack_offset))) then @@ -869,8 +1110,10 @@ contains do k = -buff_size, n + buff_size do j = -buff_size, m + buff_size do q = 1, nb - r = (i - 1) + (q - 1)*nnode + v_size*((j + buff_size) + (m + 2*buff_size + 1)*((k & - & + buff_size) + (n + 2*buff_size + 1)*(l + buff_size))) + r = (i - 1) + (q - 1)*nnode + v_size* & + ((j + buff_size) + (m + 2*buff_size + 1)* & + ((k + buff_size) + (n + 2*buff_size + 1)* & + (l + buff_size))) pb_in(j, k, l + unpack_offset, i - nVar, q) = real(buff_recv(r), kind=stp) end do end do @@ -885,8 +1128,10 @@ contains do k = -buff_size, n + buff_size do j = -buff_size, m + buff_size do q = 1, nb - r = (i - 1) + (q - 1)*nnode + nb*nnode + v_size*((j + buff_size) + (m + 2*buff_size & - & + 1)*((k + buff_size) + (n + 2*buff_size + 1)*(l + buff_size))) + r = (i - 1) + (q - 1)*nnode + nb*nnode + v_size* & + ((j + buff_size) + (m + 2*buff_size + 1)* & + ((k + buff_size) + (n + 2*buff_size + 1)* & + (l + buff_size))) mv_in(j, k, l + unpack_offset, i - nVar, q) = real(buff_recv(r), kind=stp) end do end do @@ -903,19 +1148,331 @@ contains end subroutine s_mpi_sendrecv_variables_buffers - !> Decompose the computational domain among processors by balancing cells per rank in each coordinate direction. + !> The goal of this procedure is to populate the buffers of + !! the cell-average conservative variables by communicating + !! with the neighboring processors. + !! @param q_cons_vf Cell-average conservative variables + !! @param mpi_dir MPI communication coordinate direction + !! @param pbc_loc Processor boundary condition (PBC) location + subroutine s_mpi_reduce_beta_variables_buffers(q_comm, kahan_comp, & + mpi_dir, & + pbc_loc, & + nVar) + + type(scalar_field), dimension(1:), intent(inout) :: q_comm + type(scalar_field), dimension(1:), intent(inout) :: kahan_comp + integer, intent(in) :: mpi_dir, pbc_loc, nVar + + integer :: i, j, k, l, r, q !< Generic loop iterators + integer :: lb_size + + integer :: buffer_counts(1:3), buffer_count + + type(int_bounds_info) :: boundary_conditions(1:3) + integer :: beg_end(1:2), grid_dims(1:3) + integer :: dst_proc, src_proc, recv_tag, send_tag + + logical :: replace_buff + + integer :: pack_offset, unpack_offset + real(wp) :: y_kahan, t_kahan + +#ifdef MFC_MPI + integer :: ierr !< Generic flag used to identify and report MPI errors + + call nvtxStartRange("BETA-COMM-PACKBUF") + + ! Set bounds for each dimension + ! Always include the full buffer range for each existing dimension. + ! The Gaussian smearing kernel writes to buffer cells even at physical + ! boundaries, and these contributions must be communicated to neighbors + ! in other directions via ADD operations. + comm_coords(1)%beg = -mapcells - 1 + comm_coords(1)%end = m + mapcells + 1 + comm_coords(2)%beg = merge(-mapcells - 1, 0, n > 0) + comm_coords(2)%end = merge(n + mapcells + 1, n, n > 0) + comm_coords(3)%beg = merge(-mapcells - 1, 0, p > 0) + comm_coords(3)%end = merge(p + mapcells + 1, p, p > 0) + + ! Compute sizes + comm_size(1) = comm_coords(1)%end - comm_coords(1)%beg + 1 + comm_size(2) = comm_coords(2)%end - comm_coords(2)%beg + 1 + comm_size(3) = comm_coords(3)%end - comm_coords(3)%beg + 1 + + ! Buffer counts using the conditional sizes + v_size = nVar + lb_size = 2*(mapcells + 1) ! Size of the buffer region for beta variables (-mapcells - 1, mapcells) + buffer_counts = (/ & + lb_size*v_size*comm_size(2)*comm_size(3), & ! mpi_dir=1 + lb_size*v_size*comm_size(1)*comm_size(3), & ! mpi_dir=2 + lb_size*v_size*comm_size(1)*comm_size(2) & ! mpi_dir=3 + /) + + $:GPU_UPDATE(device='[v_size, comm_coords, comm_size]') + + buffer_count = buffer_counts(mpi_dir) + boundary_conditions = (/bc_x, bc_y, bc_z/) + beg_end = (/boundary_conditions(mpi_dir)%beg, boundary_conditions(mpi_dir)%end/) + grid_dims = (/m, n, p/) + + if (pbc_loc == -1) then + ! Phase 1: Rightward accumulation + ! Send END buffer to right neighbor, recv from left into BEG, ADD + pack_offset = grid_dims(mpi_dir) + 1 + unpack_offset = 0 + dst_proc = merge(beg_end(2), MPI_PROC_NULL, beg_end(2) >= 0) + src_proc = merge(beg_end(1), MPI_PROC_NULL, beg_end(1) >= 0) + send_tag = 0 + recv_tag = 0 + replace_buff = .false. + else + ! Phase 2: Leftward distribution + ! Send BEG buffer to left neighbor, recv from right into END, REPLACE + pack_offset = 0 + unpack_offset = grid_dims(mpi_dir) + 1 + dst_proc = merge(beg_end(1), MPI_PROC_NULL, beg_end(1) >= 0) + src_proc = merge(beg_end(2), MPI_PROC_NULL, beg_end(2) >= 0) + send_tag = 1 + recv_tag = 1 + replace_buff = .true. + end if + + ! Pack Buffer to Send + #:for mpi_dir in [1, 2, 3] + if (mpi_dir == ${mpi_dir}$) then + #:if mpi_dir == 1 + $:GPU_PARALLEL_LOOP(collapse=4,private='[r]') + do l = comm_coords(3)%beg, comm_coords(3)%end + do k = comm_coords(2)%beg, comm_coords(2)%end + do j = -mapcells - 1, mapcells + do i = 1, v_size + r = (i - 1) + v_size*( & + (j + mapcells + 1) + lb_size*( & + (k - comm_coords(2)%beg) + comm_size(2)* & + (l - comm_coords(3)%beg))) + buff_send(r) = real(q_comm(beta_vars(i))%sf(j + pack_offset, k, l), kind=wp) & + - real(kahan_comp(beta_vars(i))%sf(j + pack_offset, k, l), kind=wp) + end do + end do + end do + end do + $:END_GPU_PARALLEL_LOOP() + #:elif mpi_dir == 2 + $:GPU_PARALLEL_LOOP(collapse=4,private='[r]') + do i = 1, v_size + do l = comm_coords(3)%beg, comm_coords(3)%end + do k = -mapcells - 1, mapcells + do j = comm_coords(1)%beg, comm_coords(1)%end + r = (i - 1) + v_size*( & + (j - comm_coords(1)%beg) + comm_size(1)*( & + (k + mapcells + 1) + lb_size* & + (l - comm_coords(3)%beg))) + buff_send(r) = real(q_comm(beta_vars(i))%sf(j, k + pack_offset, l), kind=wp) & + - real(kahan_comp(beta_vars(i))%sf(j, k + pack_offset, l), kind=wp) + end do + end do + end do + end do + $:END_GPU_PARALLEL_LOOP() + #:else + $:GPU_PARALLEL_LOOP(collapse=4,private='[r]') + do i = 1, v_size + do l = -mapcells - 1, mapcells + do k = comm_coords(2)%beg, comm_coords(2)%end + do j = comm_coords(1)%beg, comm_coords(1)%end + r = (i - 1) + v_size*( & + (j - comm_coords(1)%beg) + comm_size(1)*( & + (k - comm_coords(2)%beg) + comm_size(2)* & + (l + mapcells + 1))) + buff_send(r) = real(q_comm(beta_vars(i))%sf(j, k, l + pack_offset), kind=wp) & + - real(kahan_comp(beta_vars(i))%sf(j, k, l + pack_offset), kind=wp) + end do + end do + end do + end do + $:END_GPU_PARALLEL_LOOP() + #:endif + end if + #:endfor + call nvtxEndRange ! Packbuf + + ! Send/Recv +#ifdef MFC_SIMULATION + #:for rdma_mpi in [False, True] + if (rdma_mpi .eqv. ${'.true.' if rdma_mpi else '.false.'}$) then + #:if rdma_mpi + #:call GPU_HOST_DATA(use_device_addr='[buff_send, buff_recv]') + call nvtxStartRange("BETA-COMM-SENDRECV-RDMA") + + call MPI_SENDRECV( & + buff_send, buffer_count, mpi_p, dst_proc, send_tag, & + buff_recv, buffer_count, mpi_p, src_proc, recv_tag, & + MPI_COMM_WORLD, MPI_STATUS_IGNORE, ierr) + + call nvtxEndRange ! BETA-MPI-SENDRECV-(NO)-RDMA + + #:endcall GPU_HOST_DATA + $:GPU_WAIT() + #:else + call nvtxStartRange("BETA-COMM-DEV2HOST") + $:GPU_UPDATE(host='[buff_send]') + call nvtxEndRange + call nvtxStartRange("BETA-COMM-SENDRECV-NO-RMDA") + + call MPI_SENDRECV( & + buff_send, buffer_count, mpi_p, dst_proc, send_tag, & + buff_recv, buffer_count, mpi_p, src_proc, recv_tag, & + MPI_COMM_WORLD, MPI_STATUS_IGNORE, ierr) + + call nvtxEndRange ! BETA-MPI-SENDRECV-(NO)-RDMA + + call nvtxStartRange("BETA-COMM-HOST2DEV") + $:GPU_UPDATE(device='[buff_recv]') + call nvtxEndRange + #:endif + end if + #:endfor +#else + call MPI_SENDRECV( & + buff_send, buffer_count, mpi_p, dst_proc, send_tag, & + buff_recv, buffer_count, mpi_p, src_proc, recv_tag, & + MPI_COMM_WORLD, MPI_STATUS_IGNORE, ierr) +#endif + + ! Unpack Received Buffer (skip if no source rank) + call nvtxStartRange("BETA-COMM-UNPACKBUF") + if (src_proc /= MPI_PROC_NULL) then + #:for mpi_dir in [1, 2, 3] + if (mpi_dir == ${mpi_dir}$) then + #:if mpi_dir == 1 + $:GPU_PARALLEL_LOOP(collapse=4,private='[r,y_kahan,t_kahan]',copyin='[replace_buff]') + do l = comm_coords(3)%beg, comm_coords(3)%end + do k = comm_coords(2)%beg, comm_coords(2)%end + do j = -mapcells - 1, mapcells + do i = 1, v_size + r = (i - 1) + v_size*( & + (j + mapcells + 1) + lb_size*( & + (k - comm_coords(2)%beg) + comm_size(2)* & + (l - comm_coords(3)%beg))) + if (replace_buff) then + q_comm(beta_vars(i))%sf(j + unpack_offset, k, l) = real(buff_recv(r), kind=stp) + kahan_comp(beta_vars(i))%sf(j + unpack_offset, k, l) = & + real(q_comm(beta_vars(i))%sf(j + unpack_offset, k, l), kind=wp) - buff_recv(r) + else + y_kahan = buff_recv(r) & + - real(kahan_comp(beta_vars(i))%sf(j + unpack_offset, k, l), kind=wp) + t_kahan = real(q_comm(beta_vars(i))%sf(j + unpack_offset, k, l), kind=wp) + y_kahan + kahan_comp(beta_vars(i))%sf(j + unpack_offset, k, l) = & + (t_kahan - q_comm(beta_vars(i))%sf(j + unpack_offset, k, l)) - y_kahan + q_comm(beta_vars(i))%sf(j + unpack_offset, k, l) = t_kahan + end if + end do + end do + end do + end do + $:END_GPU_PARALLEL_LOOP() + #:elif mpi_dir == 2 + $:GPU_PARALLEL_LOOP(collapse=4,private='[r,y_kahan,t_kahan]',copyin='[replace_buff]') + do i = 1, v_size + do l = comm_coords(3)%beg, comm_coords(3)%end + do k = -mapcells - 1, mapcells + do j = comm_coords(1)%beg, comm_coords(1)%end + r = (i - 1) + v_size*( & + (j - comm_coords(1)%beg) + comm_size(1)*( & + (k + mapcells + 1) + lb_size* & + (l - comm_coords(3)%beg))) + if (replace_buff) then + q_comm(beta_vars(i))%sf(j, k + unpack_offset, l) = real(buff_recv(r), kind=stp) + kahan_comp(beta_vars(i))%sf(j, k + unpack_offset, l) = & + real(q_comm(beta_vars(i))%sf(j, k + unpack_offset, l), kind=wp) - buff_recv(r) + else + y_kahan = buff_recv(r) & + - real(kahan_comp(beta_vars(i))%sf(j, k + unpack_offset, l), kind=wp) + t_kahan = real(q_comm(beta_vars(i))%sf(j, k + unpack_offset, l), kind=wp) + y_kahan + kahan_comp(beta_vars(i))%sf(j, k + unpack_offset, l) = & + (t_kahan - q_comm(beta_vars(i))%sf(j, k + unpack_offset, l)) - y_kahan + q_comm(beta_vars(i))%sf(j, k + unpack_offset, l) = t_kahan + end if + end do + end do + end do + end do + $:END_GPU_PARALLEL_LOOP() + #:else + $:GPU_PARALLEL_LOOP(collapse=4,private='[r,y_kahan,t_kahan]',copyin='[replace_buff]') + do i = 1, v_size + do l = -mapcells - 1, mapcells + do k = comm_coords(2)%beg, comm_coords(2)%end + do j = comm_coords(1)%beg, comm_coords(1)%end + r = (i - 1) + v_size*( & + (j - comm_coords(1)%beg) + comm_size(1)*( & + (k - comm_coords(2)%beg) + comm_size(2)* & + (l + mapcells + 1))) + if (replace_buff) then + q_comm(beta_vars(i))%sf(j, k, l + unpack_offset) = real(buff_recv(r), kind=stp) + kahan_comp(beta_vars(i))%sf(j, k, l + unpack_offset) = & + real(q_comm(beta_vars(i))%sf(j, k, l + unpack_offset), kind=wp) - buff_recv(r) + else + y_kahan = buff_recv(r) & + - real(kahan_comp(beta_vars(i))%sf(j, k, l + unpack_offset), kind=wp) + t_kahan = real(q_comm(beta_vars(i))%sf(j, k, l + unpack_offset), kind=wp) + y_kahan + kahan_comp(beta_vars(i))%sf(j, k, l + unpack_offset) = & + (t_kahan - q_comm(beta_vars(i))%sf(j, k, l + unpack_offset)) - y_kahan + q_comm(beta_vars(i))%sf(j, k, l + unpack_offset) = t_kahan + end if + end do + end do + end do + end do + $:END_GPU_PARALLEL_LOOP() + #:endif + end if + #:endfor + end if + call nvtxEndRange +#endif + + end subroutine s_mpi_reduce_beta_variables_buffers + + !> The purpose of this procedure is to optimally decompose + !! the computational domain among the available processors. + !! This is performed by attempting to award each processor, + !! in each of the coordinate directions, approximately the + !! same number of cells, and then recomputing the affected + !! global parameters. subroutine s_mpi_decompose_computational_domain #ifdef MFC_MPI - integer :: num_procs_x, num_procs_y, num_procs_z !< Optimal number of processors in the x-, y- and z-directions - !> Non-optimal number of processors in the x-, y- and z-directions - real(wp) :: tmp_num_procs_x, tmp_num_procs_y, tmp_num_procs_z - real(wp) :: fct_min !< Processor factorization (fct) minimization parameter - integer :: MPI_COMM_CART !< Cartesian processor topology communicator - integer :: rem_cells !< Remaining cells after distribution among processors - integer :: recon_order !< WENO or MUSCL reconstruction order - integer :: i, j !< Generic loop iterators - integer :: ierr !< Generic flag used to identify and report MPI errors + + integer :: num_procs_x, num_procs_y, num_procs_z !< + !! Optimal number of processors in the x-, y- and z-directions + + real(wp) :: tmp_num_procs_x, tmp_num_procs_y, tmp_num_procs_z !< + !! Non-optimal number of processors in the x-, y- and z-directions + + real(wp) :: fct_min !< + !! Processor factorization (fct) minimization parameter + + integer :: MPI_COMM_CART !< + !! Cartesian processor topology communicator + + integer :: rem_cells !< + !! Remaining number of cells, in a particular coordinate direction, + !! after the majority is divided up among the available processors + + integer :: recon_order !< + !! WENO or MUSCL reconstruction order + + integer :: i, j, k !< Generic loop iterators + integer :: ierr !< Generic flag used to identify and report MPI errors + + ! temp array to store neighbor rank coordinates + integer, dimension(1:num_dims) :: neighbor_coords + + ! Zeroing out communication needs for moving EL bubbles/particles + nidx(1)%beg = 0; nidx(1)%end = 0 + nidx(2)%beg = 0; nidx(2)%end = 0 + nidx(3)%beg = 0; nidx(3)%end = 0 if (recon_type == WENO_TYPE) then recon_order = weno_order @@ -936,8 +1493,10 @@ contains ! 3D Cartesian Processor Topology if (n > 0) then + if (p > 0) then if (fft_wrt) then + ! Initial estimate of optimal processor topology num_procs_x = 1 num_procs_y = 1 @@ -947,26 +1506,43 @@ contains ! Benchmarking the quality of this initial guess tmp_num_procs_y = num_procs_y tmp_num_procs_z = num_procs_z - fct_min = 10._wp*abs((n + 1)/tmp_num_procs_y - (p + 1)/tmp_num_procs_z) + fct_min = 10._wp*abs((n + 1)/tmp_num_procs_y & + - (p + 1)/tmp_num_procs_z) ! Optimization of the initial processor topology do i = 1, num_procs - if (mod(num_procs, i) == 0 .and. (n + 1)/i >= num_stcls_min*recon_order) then + + if (mod(num_procs, i) == 0 & + .and. & + (n + 1)/i >= num_stcls_min*recon_order) then + tmp_num_procs_y = i tmp_num_procs_z = num_procs/i - if (fct_min >= abs((n + 1)/tmp_num_procs_y - (p + 1)/tmp_num_procs_z) .and. (p + 1) & - & /tmp_num_procs_z >= num_stcls_min*recon_order) then + if (fct_min >= abs((n + 1)/tmp_num_procs_y & + - (p + 1)/tmp_num_procs_z) & + .and. & + (p + 1)/tmp_num_procs_z & + >= & + num_stcls_min*recon_order) then + num_procs_y = i num_procs_z = num_procs/i - fct_min = abs((n + 1)/tmp_num_procs_y - (p + 1)/tmp_num_procs_z) + fct_min = abs((n + 1)/tmp_num_procs_y & + - (p + 1)/tmp_num_procs_z) ierr = 0 + end if + end if + end do else + if (cyl_coord .and. p > 0) then - ! Pencil blocking for cylindrical coordinates (Fourier filter near axis) + ! Implement pencil processor blocking if using cylindrical coordinates so + ! that all cells in azimuthal direction are stored on a single processor. + ! This is necessary for efficient application of Fourier filter near axis. ! Initial values of the processor factorization optimization num_procs_x = 1 @@ -978,24 +1554,40 @@ contains tmp_num_procs_x = num_procs_x tmp_num_procs_y = num_procs_y tmp_num_procs_z = num_procs_z - fct_min = 10._wp*abs((m + 1)/tmp_num_procs_x - (n + 1)/tmp_num_procs_y) + fct_min = 10._wp*abs((m + 1)/tmp_num_procs_x & + - (n + 1)/tmp_num_procs_y) ! Searching for optimal computational domain distribution do i = 1, num_procs - if (mod(num_procs, i) == 0 .and. (m + 1)/i >= num_stcls_min*recon_order) then + + if (mod(num_procs, i) == 0 & + .and. & + (m + 1)/i >= num_stcls_min*recon_order) then + tmp_num_procs_x = i tmp_num_procs_y = num_procs/i - if (fct_min >= abs((m + 1)/tmp_num_procs_x - (n + 1)/tmp_num_procs_y) .and. (n + 1) & - & /tmp_num_procs_y >= num_stcls_min*recon_order) then + if (fct_min >= abs((m + 1)/tmp_num_procs_x & + - (n + 1)/tmp_num_procs_y) & + .and. & + (n + 1)/tmp_num_procs_y & + >= & + num_stcls_min*recon_order) then + num_procs_x = i num_procs_y = num_procs/i - fct_min = abs((m + 1)/tmp_num_procs_x - (n + 1)/tmp_num_procs_y) + fct_min = abs((m + 1)/tmp_num_procs_x & + - (n + 1)/tmp_num_procs_y) ierr = 0 + end if + end if + end do + else + ! Initial estimate of optimal processor topology num_procs_x = 1 num_procs_y = 1 @@ -1006,48 +1598,78 @@ contains tmp_num_procs_x = num_procs_x tmp_num_procs_y = num_procs_y tmp_num_procs_z = num_procs_z - fct_min = 10._wp*abs((m + 1)/tmp_num_procs_x - (n + 1)/tmp_num_procs_y) + 10._wp*abs((n + 1) & - & /tmp_num_procs_y - (p + 1)/tmp_num_procs_z) + fct_min = 10._wp*abs((m + 1)/tmp_num_procs_x & + - (n + 1)/tmp_num_procs_y) & + + 10._wp*abs((n + 1)/tmp_num_procs_y & + - (p + 1)/tmp_num_procs_z) ! Optimization of the initial processor topology do i = 1, num_procs - if (mod(num_procs, i) == 0 .and. (m + 1)/i >= num_stcls_min*recon_order) then + + if (mod(num_procs, i) == 0 & + .and. & + (m + 1)/i >= num_stcls_min*recon_order) then + do j = 1, num_procs/i - if (mod(num_procs/i, j) == 0 .and. (n + 1)/j >= num_stcls_min*recon_order) then + + if (mod(num_procs/i, j) == 0 & + .and. & + (n + 1)/j >= num_stcls_min*recon_order) then + tmp_num_procs_x = i tmp_num_procs_y = j tmp_num_procs_z = num_procs/(i*j) - if (fct_min >= abs((m + 1)/tmp_num_procs_x - (n + 1)/tmp_num_procs_y) + abs((n + 1) & - & /tmp_num_procs_y - (p + 1)/tmp_num_procs_z) .and. (p + 1) & - & /tmp_num_procs_z >= num_stcls_min*recon_order) then + if (fct_min >= abs((m + 1)/tmp_num_procs_x & + - (n + 1)/tmp_num_procs_y) & + + abs((n + 1)/tmp_num_procs_y & + - (p + 1)/tmp_num_procs_z) & + .and. & + (p + 1)/tmp_num_procs_z & + >= & + num_stcls_min*recon_order) & + then + num_procs_x = i num_procs_y = j num_procs_z = num_procs/(i*j) - fct_min = abs((m + 1)/tmp_num_procs_x - (n + 1)/tmp_num_procs_y) + abs((n + 1) & - & /tmp_num_procs_y - (p + 1)/tmp_num_procs_z) + fct_min = abs((m + 1)/tmp_num_procs_x & + - (n + 1)/tmp_num_procs_y) & + + abs((n + 1)/tmp_num_procs_y & + - (p + 1)/tmp_num_procs_z) ierr = 0 + end if + end if + end do + end if + end do + end if end if - ! Verifying that a valid decomposition of the computational domain has been established. If not, the simulation - ! exits. + ! Verifying that a valid decomposition of the computational + ! domain has been established. If not, the simulation exits. if (proc_rank == 0 .and. ierr == -1) then - call s_mpi_abort('Unsupported combination of values ' // 'of num_procs, m, n, p and ' & - & // 'weno/muscl/igr_order. Exiting.') + call s_mpi_abort('Unsupported combination of values '// & + 'of num_procs, m, n, p and '// & + 'weno/muscl/igr_order. Exiting.') end if ! Creating new communicator using the Cartesian topology - call MPI_CART_CREATE(MPI_COMM_WORLD, 3, (/num_procs_x, num_procs_y, num_procs_z/), (/.true., .true., .true./), & - & .false., MPI_COMM_CART, ierr) + call MPI_CART_CREATE(MPI_COMM_WORLD, 3, (/num_procs_x, & + num_procs_y, num_procs_z/), & + (/.true., .true., .true./), & + .false., MPI_COMM_CART, ierr) ! Finding the Cartesian coordinates of the local process - call MPI_CART_COORDS(MPI_COMM_CART, proc_rank, 3, proc_coords, ierr) + call MPI_CART_COORDS(MPI_COMM_CART, proc_rank, 3, & + proc_coords, ierr) + ! END: 3D Cartesian Processor Topology ! Global Parameters for z-direction @@ -1067,15 +1689,19 @@ contains ! Boundary condition at the beginning if (proc_coords(3) > 0 .or. (bc_z%beg == BC_PERIODIC .and. num_procs_z > 1)) then proc_coords(3) = proc_coords(3) - 1 - call MPI_CART_RANK(MPI_COMM_CART, proc_coords, bc_z%beg, ierr) + call MPI_CART_RANK(MPI_COMM_CART, proc_coords, & + bc_z%beg, ierr) proc_coords(3) = proc_coords(3) + 1 + nidx(3)%beg = -1 end if ! Boundary condition at the end if (proc_coords(3) < num_procs_z - 1 .or. (bc_z%end == BC_PERIODIC .and. num_procs_z > 1)) then proc_coords(3) = proc_coords(3) + 1 - call MPI_CART_RANK(MPI_COMM_CART, proc_coords, bc_z%end, ierr) + call MPI_CART_RANK(MPI_COMM_CART, proc_coords, & + bc_z%end, ierr) proc_coords(3) = proc_coords(3) - 1 + nidx(3)%end = 1 end if #ifdef MFC_POST_PROCESS @@ -1107,12 +1733,16 @@ contains dz = (z_domain%end - z_domain%beg)/real(p_glb + 1, wp) if (proc_coords(3) < rem_cells) then - z_domain%beg = z_domain%beg + dz*real((p + 1)*proc_coords(3)) - z_domain%end = z_domain%end - dz*real((p + 1)*(num_procs_z - proc_coords(3) - 1) - (num_procs_z & - & - rem_cells)) + z_domain%beg = z_domain%beg + dz*real((p + 1)* & + proc_coords(3)) + z_domain%end = z_domain%end - dz*real((p + 1)* & + (num_procs_z - proc_coords(3) - 1) & + - (num_procs_z - rem_cells)) else - z_domain%beg = z_domain%beg + dz*real((p + 1)*proc_coords(3) + rem_cells) - z_domain%end = z_domain%end - dz*real((p + 1)*(num_procs_z - proc_coords(3) - 1)) + z_domain%beg = z_domain%beg + dz*real((p + 1)* & + proc_coords(3) + rem_cells) + z_domain%end = z_domain%end - dz*real((p + 1)* & + (num_procs_z - proc_coords(3) - 1)) end if end if #endif @@ -1120,6 +1750,7 @@ contains ! 2D Cartesian Processor Topology else + ! Initial estimate of optimal processor topology num_procs_x = 1 num_procs_y = num_procs @@ -1128,38 +1759,58 @@ contains ! Benchmarking the quality of this initial guess tmp_num_procs_x = num_procs_x tmp_num_procs_y = num_procs_y - fct_min = 10._wp*abs((m + 1)/tmp_num_procs_x - (n + 1)/tmp_num_procs_y) + fct_min = 10._wp*abs((m + 1)/tmp_num_procs_x & + - (n + 1)/tmp_num_procs_y) ! Optimization of the initial processor topology do i = 1, num_procs - if (mod(num_procs, i) == 0 .and. (m + 1)/i >= num_stcls_min*recon_order) then + + if (mod(num_procs, i) == 0 & + .and. & + (m + 1)/i >= num_stcls_min*recon_order) then + tmp_num_procs_x = i tmp_num_procs_y = num_procs/i - if (fct_min >= abs((m + 1)/tmp_num_procs_x - (n + 1)/tmp_num_procs_y) .and. (n + 1) & - & /tmp_num_procs_y >= num_stcls_min*recon_order) then + if (fct_min >= abs((m + 1)/tmp_num_procs_x & + - (n + 1)/tmp_num_procs_y) & + .and. & + (n + 1)/tmp_num_procs_y & + >= & + num_stcls_min*recon_order) then + num_procs_x = i num_procs_y = num_procs/i - fct_min = abs((m + 1)/tmp_num_procs_x - (n + 1)/tmp_num_procs_y) + fct_min = abs((m + 1)/tmp_num_procs_x & + - (n + 1)/tmp_num_procs_y) ierr = 0 + end if + end if + end do - ! Verifying that a valid decomposition of the computational domain has been established. If not, the simulation - ! exits. + ! Verifying that a valid decomposition of the computational + ! domain has been established. If not, the simulation exits. if (proc_rank == 0 .and. ierr == -1) then - call s_mpi_abort('Unsupported combination of values ' // 'of num_procs, m, n and ' & - & // 'weno/muscl/igr_order. Exiting.') + call s_mpi_abort('Unsupported combination of values '// & + 'of num_procs, m, n and '// & + 'weno/muscl/igr_order. Exiting.') end if ! Creating new communicator using the Cartesian topology - call MPI_CART_CREATE(MPI_COMM_WORLD, 2, (/num_procs_x, num_procs_y/), (/.true., .true./), .false., MPI_COMM_CART, & - & ierr) + call MPI_CART_CREATE(MPI_COMM_WORLD, 2, (/num_procs_x, & + num_procs_y/), (/.true., & + .true./), .false., MPI_COMM_CART, & + ierr) ! Finding the Cartesian coordinates of the local process - call MPI_CART_COORDS(MPI_COMM_CART, proc_rank, 2, proc_coords, ierr) + call MPI_CART_COORDS(MPI_COMM_CART, proc_rank, 2, & + proc_coords, ierr) + end if + ! END: 2D Cartesian Processor Topology ! Global Parameters for y-direction @@ -1179,15 +1830,19 @@ contains ! Boundary condition at the beginning if (proc_coords(2) > 0 .or. (bc_y%beg == BC_PERIODIC .and. num_procs_y > 1)) then proc_coords(2) = proc_coords(2) - 1 - call MPI_CART_RANK(MPI_COMM_CART, proc_coords, bc_y%beg, ierr) + call MPI_CART_RANK(MPI_COMM_CART, proc_coords, & + bc_y%beg, ierr) proc_coords(2) = proc_coords(2) + 1 + nidx(2)%beg = -1 end if ! Boundary condition at the end if (proc_coords(2) < num_procs_y - 1 .or. (bc_y%end == BC_PERIODIC .and. num_procs_y > 1)) then proc_coords(2) = proc_coords(2) + 1 - call MPI_CART_RANK(MPI_COMM_CART, proc_coords, bc_y%end, ierr) + call MPI_CART_RANK(MPI_COMM_CART, proc_coords, & + bc_y%end, ierr) proc_coords(2) = proc_coords(2) - 1 + nidx(2)%end = 1 end if #ifdef MFC_POST_PROCESS @@ -1219,12 +1874,16 @@ contains dy = (y_domain%end - y_domain%beg)/real(n_glb + 1, wp) if (proc_coords(2) < rem_cells) then - y_domain%beg = y_domain%beg + dy*real((n + 1)*proc_coords(2)) - y_domain%end = y_domain%end - dy*real((n + 1)*(num_procs_y - proc_coords(2) - 1) - (num_procs_y & - & - rem_cells)) + y_domain%beg = y_domain%beg + dy*real((n + 1)* & + proc_coords(2)) + y_domain%end = y_domain%end - dy*real((n + 1)* & + (num_procs_y - proc_coords(2) - 1) & + - (num_procs_y - rem_cells)) else - y_domain%beg = y_domain%beg + dy*real((n + 1)*proc_coords(2) + rem_cells) - y_domain%end = y_domain%end - dy*real((n + 1)*(num_procs_y - proc_coords(2) - 1)) + y_domain%beg = y_domain%beg + dy*real((n + 1)* & + proc_coords(2) + rem_cells) + y_domain%end = y_domain%end - dy*real((n + 1)* & + (num_procs_y - proc_coords(2) - 1)) end if end if #endif @@ -1232,14 +1891,19 @@ contains ! 1D Cartesian Processor Topology else + ! Optimal processor topology num_procs_x = num_procs ! Creating new communicator using the Cartesian topology - call MPI_CART_CREATE(MPI_COMM_WORLD, 1, (/num_procs_x/), (/.true./), .false., MPI_COMM_CART, ierr) + call MPI_CART_CREATE(MPI_COMM_WORLD, 1, (/num_procs_x/), & + (/.true./), .false., MPI_COMM_CART, & + ierr) ! Finding the Cartesian coordinates of the local process - call MPI_CART_COORDS(MPI_COMM_CART, proc_rank, 1, proc_coords, ierr) + call MPI_CART_COORDS(MPI_COMM_CART, proc_rank, 1, & + proc_coords, ierr) + end if ! Global Parameters for x-direction @@ -1264,6 +1928,7 @@ contains proc_coords(1) = proc_coords(1) - 1 call MPI_CART_RANK(MPI_COMM_CART, proc_coords, bc_x%beg, ierr) proc_coords(1) = proc_coords(1) + 1 + nidx(1)%beg = -1 end if ! Boundary condition at the end @@ -1271,6 +1936,7 @@ contains proc_coords(1) = proc_coords(1) + 1 call MPI_CART_RANK(MPI_COMM_CART, proc_coords, bc_x%end, ierr) proc_coords(1) = proc_coords(1) - 1 + nidx(1)%end = 1 end if #ifdef MFC_POST_PROCESS @@ -1302,22 +1968,49 @@ contains dx = (x_domain%end - x_domain%beg)/real(m_glb + 1, wp) if (proc_coords(1) < rem_cells) then - x_domain%beg = x_domain%beg + dx*real((m + 1)*proc_coords(1)) - x_domain%end = x_domain%end - dx*real((m + 1)*(num_procs_x - proc_coords(1) - 1) - (num_procs_x - rem_cells)) + x_domain%beg = x_domain%beg + dx*real((m + 1)* & + proc_coords(1)) + x_domain%end = x_domain%end - dx*real((m + 1)* & + (num_procs_x - proc_coords(1) - 1) & + - (num_procs_x - rem_cells)) else - x_domain%beg = x_domain%beg + dx*real((m + 1)*proc_coords(1) + rem_cells) - x_domain%end = x_domain%end - dx*real((m + 1)*(num_procs_x - proc_coords(1) - 1)) + x_domain%beg = x_domain%beg + dx*real((m + 1)* & + proc_coords(1) + rem_cells) + x_domain%end = x_domain%end - dx*real((m + 1)* & + (num_procs_x - proc_coords(1) - 1)) end if end if #endif end if + + @:ALLOCATE(neighbor_ranks(nidx(1)%beg:nidx(1)%end, & + nidx(2)%beg:nidx(2)%end, & + nidx(3)%beg:nidx(3)%end)) + do k = nidx(3)%beg, nidx(3)%end + do j = nidx(2)%beg, nidx(2)%end + do i = nidx(1)%beg, nidx(1)%end + if (abs(i) + abs(j) + abs(k) > 0) then + neighbor_coords(1) = proc_coords(1) + i + if (num_dims > 1) neighbor_coords(2) = proc_coords(2) + j + if (num_dims > 2) neighbor_coords(3) = proc_coords(3) + k + call MPI_CART_RANK(MPI_COMM_CART, neighbor_coords, & + neighbor_ranks(i, j, k), ierr) + end if + end do + end do + end do #endif end subroutine s_mpi_decompose_computational_domain - !> The goal of this procedure is to populate the buffers of the grid variables by communicating with the neighboring processors. - !! Note that only the buffers of the cell-width distributions are handled in such a way. This is because the buffers of - !! cell-boundary locations may be calculated directly from those of the cell-width distributions. + !> The goal of this procedure is to populate the buffers of + !! the grid variables by communicating with the neighboring + !! processors. Note that only the buffers of the cell-width + !! distributions are handled in such a way. This is because + !! the buffers of cell-boundary locations may be calculated + !! directly from those of the cell-width distributions. + !! @param mpi_dir MPI communication coordinate direction + !! @param pbc_loc Processor boundary condition (PBC) location #ifndef MFC_PRE_PROCESS subroutine s_mpi_sendrecv_grid_variables_buffers(mpi_dir, pbc_loc) @@ -1325,66 +2018,171 @@ contains integer, intent(in) :: pbc_loc #ifdef MFC_MPI - integer :: ierr !< Generic flag used to identify and report MPI errors + integer :: ierr !< Generic flag used to identify and report MPI errors + ! MPI Communication in x-direction if (mpi_dir == 1) then - if (pbc_loc == -1) then ! PBC at the beginning - - if (bc_x%end >= 0) then ! PBC at the beginning and end - call MPI_SENDRECV(dx(m - buff_size + 1), buff_size, mpi_p, bc_x%end, 0, dx(-buff_size), buff_size, mpi_p, & - & bc_x%beg, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE, ierr) - else ! PBC at the beginning only - call MPI_SENDRECV(dx(0), buff_size, mpi_p, bc_x%beg, 1, dx(-buff_size), buff_size, mpi_p, bc_x%beg, 0, & - & MPI_COMM_WORLD, MPI_STATUS_IGNORE, ierr) + + if (pbc_loc == -1) then ! PBC at the beginning + + if (bc_x%end >= 0) then ! PBC at the beginning and end + + ! Send/receive buffer to/from bc_x%end/bc_x%beg + call MPI_SENDRECV( & + dx(m - buff_size + 1), buff_size, & + mpi_p, bc_x%end, 0, & + dx(-buff_size), buff_size, & + mpi_p, bc_x%beg, 0, & + MPI_COMM_WORLD, MPI_STATUS_IGNORE, ierr) + + else ! PBC at the beginning only + + ! Send/receive buffer to/from bc_x%beg/bc_x%beg + call MPI_SENDRECV( & + dx(0), buff_size, & + mpi_p, bc_x%beg, 1, & + dx(-buff_size), buff_size, & + mpi_p, bc_x%beg, 0, & + MPI_COMM_WORLD, MPI_STATUS_IGNORE, ierr) + end if - else ! PBC at the end - if (bc_x%beg >= 0) then ! PBC at the end and beginning - call MPI_SENDRECV(dx(0), buff_size, mpi_p, bc_x%beg, 1, dx(m + 1), buff_size, mpi_p, bc_x%end, 1, & - & MPI_COMM_WORLD, MPI_STATUS_IGNORE, ierr) - else ! PBC at the end only - call MPI_SENDRECV(dx(m - buff_size + 1), buff_size, mpi_p, bc_x%end, 0, dx(m + 1), buff_size, mpi_p, & - & bc_x%end, 1, MPI_COMM_WORLD, MPI_STATUS_IGNORE, ierr) + + else ! PBC at the end + + if (bc_x%beg >= 0) then ! PBC at the end and beginning + + ! Send/receive buffer to/from bc_x%beg/bc_x%end + call MPI_SENDRECV( & + dx(0), buff_size, & + mpi_p, bc_x%beg, 1, & + dx(m + 1), buff_size, & + mpi_p, bc_x%end, 1, & + MPI_COMM_WORLD, MPI_STATUS_IGNORE, ierr) + + else ! PBC at the end only + + ! Send/receive buffer to/from bc_x%end/bc_x%end + call MPI_SENDRECV( & + dx(m - buff_size + 1), buff_size, & + mpi_p, bc_x%end, 0, & + dx(m + 1), buff_size, & + mpi_p, bc_x%end, 1, & + MPI_COMM_WORLD, MPI_STATUS_IGNORE, ierr) + end if + end if - else if (mpi_dir == 2) then - if (pbc_loc == -1) then ! PBC at the beginning - - if (bc_y%end >= 0) then ! PBC at the beginning and end - call MPI_SENDRECV(dy(n - buff_size + 1), buff_size, mpi_p, bc_y%end, 0, dy(-buff_size), buff_size, mpi_p, & - & bc_y%beg, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE, ierr) - else ! PBC at the beginning only - call MPI_SENDRECV(dy(0), buff_size, mpi_p, bc_y%beg, 1, dy(-buff_size), buff_size, mpi_p, bc_y%beg, 0, & - & MPI_COMM_WORLD, MPI_STATUS_IGNORE, ierr) + ! END: MPI Communication in x-direction + + ! MPI Communication in y-direction + elseif (mpi_dir == 2) then + + if (pbc_loc == -1) then ! PBC at the beginning + + if (bc_y%end >= 0) then ! PBC at the beginning and end + + ! Send/receive buffer to/from bc_y%end/bc_y%beg + call MPI_SENDRECV( & + dy(n - buff_size + 1), buff_size, & + mpi_p, bc_y%end, 0, & + dy(-buff_size), buff_size, & + mpi_p, bc_y%beg, 0, & + MPI_COMM_WORLD, MPI_STATUS_IGNORE, ierr) + + else ! PBC at the beginning only + + ! Send/receive buffer to/from bc_y%beg/bc_y%beg + call MPI_SENDRECV( & + dy(0), buff_size, & + mpi_p, bc_y%beg, 1, & + dy(-buff_size), buff_size, & + mpi_p, bc_y%beg, 0, & + MPI_COMM_WORLD, MPI_STATUS_IGNORE, ierr) + end if - else ! PBC at the end - if (bc_y%beg >= 0) then ! PBC at the end and beginning - call MPI_SENDRECV(dy(0), buff_size, mpi_p, bc_y%beg, 1, dy(n + 1), buff_size, mpi_p, bc_y%end, 1, & - & MPI_COMM_WORLD, MPI_STATUS_IGNORE, ierr) - else ! PBC at the end only - call MPI_SENDRECV(dy(n - buff_size + 1), buff_size, mpi_p, bc_y%end, 0, dy(n + 1), buff_size, mpi_p, & - & bc_y%end, 1, MPI_COMM_WORLD, MPI_STATUS_IGNORE, ierr) + + else ! PBC at the end + + if (bc_y%beg >= 0) then ! PBC at the end and beginning + + ! Send/receive buffer to/from bc_y%beg/bc_y%end + call MPI_SENDRECV( & + dy(0), buff_size, & + mpi_p, bc_y%beg, 1, & + dy(n + 1), buff_size, & + mpi_p, bc_y%end, 1, & + MPI_COMM_WORLD, MPI_STATUS_IGNORE, ierr) + + else ! PBC at the end only + + ! Send/receive buffer to/from bc_y%end/bc_y%end + call MPI_SENDRECV( & + dy(n - buff_size + 1), buff_size, & + mpi_p, bc_y%end, 0, & + dy(n + 1), buff_size, & + mpi_p, bc_y%end, 1, & + MPI_COMM_WORLD, MPI_STATUS_IGNORE, ierr) + end if + end if + ! END: MPI Communication in y-direction + + ! MPI Communication in z-direction else - if (pbc_loc == -1) then ! PBC at the beginning - - if (bc_z%end >= 0) then ! PBC at the beginning and end - call MPI_SENDRECV(dz(p - buff_size + 1), buff_size, mpi_p, bc_z%end, 0, dz(-buff_size), buff_size, mpi_p, & - & bc_z%beg, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE, ierr) - else ! PBC at the beginning only - call MPI_SENDRECV(dz(0), buff_size, mpi_p, bc_z%beg, 1, dz(-buff_size), buff_size, mpi_p, bc_z%beg, 0, & - & MPI_COMM_WORLD, MPI_STATUS_IGNORE, ierr) + + if (pbc_loc == -1) then ! PBC at the beginning + + if (bc_z%end >= 0) then ! PBC at the beginning and end + + ! Send/receive buffer to/from bc_z%end/bc_z%beg + call MPI_SENDRECV( & + dz(p - buff_size + 1), buff_size, & + mpi_p, bc_z%end, 0, & + dz(-buff_size), buff_size, & + mpi_p, bc_z%beg, 0, & + MPI_COMM_WORLD, MPI_STATUS_IGNORE, ierr) + + else ! PBC at the beginning only + + ! Send/receive buffer to/from bc_z%beg/bc_z%beg + call MPI_SENDRECV( & + dz(0), buff_size, & + mpi_p, bc_z%beg, 1, & + dz(-buff_size), buff_size, & + mpi_p, bc_z%beg, 0, & + MPI_COMM_WORLD, MPI_STATUS_IGNORE, ierr) + end if - else ! PBC at the end - if (bc_z%beg >= 0) then ! PBC at the end and beginning - call MPI_SENDRECV(dz(0), buff_size, mpi_p, bc_z%beg, 1, dz(p + 1), buff_size, mpi_p, bc_z%end, 1, & - & MPI_COMM_WORLD, MPI_STATUS_IGNORE, ierr) - else ! PBC at the end only - call MPI_SENDRECV(dz(p - buff_size + 1), buff_size, mpi_p, bc_z%end, 0, dz(p + 1), buff_size, mpi_p, & - & bc_z%end, 1, MPI_COMM_WORLD, MPI_STATUS_IGNORE, ierr) + + else ! PBC at the end + + if (bc_z%beg >= 0) then ! PBC at the end and beginning + + ! Send/receive buffer to/from bc_z%beg/bc_z%end + call MPI_SENDRECV( & + dz(0), buff_size, & + mpi_p, bc_z%beg, 1, & + dz(p + 1), buff_size, & + mpi_p, bc_z%end, 1, & + MPI_COMM_WORLD, MPI_STATUS_IGNORE, ierr) + + else ! PBC at the end only + + ! Send/receive buffer to/from bc_z%end/bc_z%end + call MPI_SENDRECV( & + dz(p - buff_size + 1), buff_size, & + mpi_p, bc_z%end, 0, & + dz(p + 1), buff_size, & + mpi_p, bc_z%end, 1, & + MPI_COMM_WORLD, MPI_STATUS_IGNORE, ierr) + end if + end if + end if + ! END: MPI Communication in z-direction #endif end subroutine s_mpi_sendrecv_grid_variables_buffers diff --git a/src/common/m_nvtx.f90 b/src/common/m_nvtx.f90 index 66893c10d0..449401128b 100644 --- a/src/common/m_nvtx.f90 +++ b/src/common/m_nvtx.f90 @@ -9,63 +9,64 @@ module m_nvtx implicit none - integer, private :: col(7) = [int(Z'0000ff00'), int(Z'000000ff'), int(Z'00ffff00'), int(Z'00ff00ff'), int(Z'0000ffff'), & - & int(Z'00ff0000'), int(Z'00ffffff')] + integer, private :: col(7) = [ & + int(Z'0000ff00'), int(Z'000000ff'), int(Z'00ffff00'), & + int(Z'00ff00ff'), int(Z'0000ffff'), int(Z'00ff0000'), & + int(Z'00ffffff') & + ] character(len=256), private :: tempName type, bind(C) :: nvtxEventAttributes integer(c_int16_t) :: version = 1 - integer(c_int16_t) :: size = 48 ! - integer(c_int) :: category = 0 - integer(c_int) :: colorType = 1 !< NVTX_COLOR_ARGB = 1 - integer(c_int) :: color - integer(c_int) :: payloadType = 0 !< NVTX_PAYLOAD_UNKNOWN = 0 - integer(c_int) :: reserved0 - integer(c_int64_t) :: payload !< union uint,int,double - integer(c_int) :: messageType = 1 !< NVTX_MESSAGE_TYPE_ASCII = 1 - type(c_ptr) :: message !< ascii char + integer(c_int16_t) :: size = 48 ! + integer(c_int) :: category = 0 + integer(c_int) :: colorType = 1 ! NVTX_COLOR_ARGB = 1 + integer(c_int) :: color + integer(c_int) :: payloadType = 0 ! NVTX_PAYLOAD_UNKNOWN = 0 + integer(c_int) :: reserved0 + integer(c_int64_t) :: payload ! union uint,int,double + integer(c_int) :: messageType = 1 ! NVTX_MESSAGE_TYPE_ASCII = 1 + type(c_ptr) :: message ! ascii char end type nvtxEventAttributes #if defined(MFC_GPU) && defined(__PGI) + interface nvtxRangePush ! push range with custom label and standard color subroutine nvtxRangePushA(name) bind(C, name='nvtxRangePushA') - use iso_c_binding - character(kind=c_char, len=*), intent(in) :: name - + character(kind=c_char, len=*), intent(IN) :: name end subroutine nvtxRangePushA + ! push range with custom label and custom color subroutine nvtxRangePushEx(event) bind(C, name='nvtxRangePushEx') - use iso_c_binding import :: nvtxEventAttributes - type(nvtxEventAttributes), intent(in) :: event - + type(nvtxEventAttributes), intent(IN) :: event end subroutine nvtxRangePushEx end interface nvtxRangePush interface nvtxRangePop subroutine nvtxRangePop() bind(C, name='nvtxRangePop') - end subroutine nvtxRangePop end interface nvtxRangePop + #endif contains - !> Push a named NVTX range for GPU profiling, optionally with a color based on the given identifier. + !> @brief Pushes a named NVTX range for GPU profiling, optionally with a color based on the given identifier. subroutine nvtxStartRange(name, id) - - character(kind=c_char, len=*), intent(in) :: name - integer, intent(in), optional :: id - type(nvtxEventAttributes) :: event + character(kind=c_char, len=*), intent(IN) :: name + integer, intent(IN), optional :: id + type(nvtxEventAttributes) :: event #if defined(MFC_GPU) && defined(__PGI) - tempName = trim(name) // c_null_char + + tempName = trim(name)//c_null_char if (.not. present(id)) then call nvtxRangePush(tempName) @@ -74,17 +75,15 @@ subroutine nvtxStartRange(name, id) event%message = c_loc(tempName) call nvtxRangePushEx(event) end if -#endif +#endif end subroutine nvtxStartRange - !> Pop the current NVTX range to end the GPU profiling region. + !> @brief Pops the current NVTX range to end the GPU profiling region. subroutine nvtxEndRange - #if defined(MFC_GPU) && defined(__PGI) call nvtxRangePop #endif - end subroutine nvtxEndRange end module m_nvtx diff --git a/src/common/m_phase_change.fpp b/src/common/m_phase_change.fpp index 21926411db..ecd519e41c 100644 --- a/src/common/m_phase_change.fpp +++ b/src/common/m_phase_change.fpp @@ -9,26 +9,35 @@ module m_phase_change #ifndef MFC_POST_PROCESS - use m_derived_types - use m_global_parameters - use m_mpi_proxy - use m_variables_conversion + + use m_derived_types !< Definitions of the derived types + + use m_global_parameters !< Definitions of the global parameters + + use m_mpi_proxy !< Message passing interface (MPI) module proxy + + use m_variables_conversion !< State variables type conversion procedures + use ieee_arithmetic - use m_helper_basic + + use m_helper_basic !< Functions to compare floating point numbers implicit none - private - public :: s_initialize_phasechange_module, s_relaxation_solver, s_infinite_relaxation_k, s_finalize_relaxation_solver_module + private; + public :: s_initialize_phasechange_module, & + s_relaxation_solver, & + s_infinite_relaxation_k, & + s_finalize_relaxation_solver_module !> @name Parameters for the first order transition phase change !> @{ - integer, parameter :: max_iter = 1e8_wp !< max # of iterations - real(wp), parameter :: pCr = 4.94e7_wp !< Critical pressure of water [Pa] - real(wp), parameter :: TCr = 385.05_wp + 273.15_wp !< Critical temperature of water [K] - real(wp), parameter :: mixM = 1.0e-8_wp !< Mixture mass fraction threshold for triggering phase change - integer, parameter :: lp = 1 !< index for the liquid phase of the reacting fluid - integer, parameter :: vp = 2 !< index for the vapor phase of the reacting fluid + integer, parameter :: max_iter = 1e8_wp !< max # of iterations + real(wp), parameter :: pCr = 4.94e7_wp !< Critical water pressure + real(wp), parameter :: TCr = 385.05_wp + 273.15_wp !< Critical water temperature + real(wp), parameter :: mixM = 1.0e-8_wp !< threshold for 'mixture cell'. If Y < mixM, phase change does not happen + integer, parameter :: lp = 1 !< index for the liquid phase of the reacting fluid + integer, parameter :: vp = 2 !< index for the vapor phase of the reacting fluid !> @} !> @name Gibbs free energy phase change parameters @@ -36,46 +45,55 @@ module m_phase_change real(wp) :: A, B, C, D !> @} - $:GPU_DECLARE(create='[A, B, C, D]') + $:GPU_DECLARE(create='[A,B,C,D]') contains - !> Dispatch to the correct relaxation solver. Replaces the procedure pointer, which CCE is breaking on. + !> This subroutine should dispatch to the correct relaxation solver based + !! some parameter. It replaces the procedure pointer, which CCE + !! is breaking on. impure subroutine s_relaxation_solver(q_cons_vf) - type(scalar_field), dimension(sys_size), intent(inout) :: q_cons_vf - ! This is empty because in current master the procedure pointer was never assigned - + ! This is empty because in current master the procedure pointer + ! was never assigned @:ASSERT(.false., "s_relaxation_solver called but it currently does nothing") - end subroutine s_relaxation_solver - !> Initialize the phase change module by setting saturation curve coefficients for pT- or pTg-equilibrium + !> The purpose of this subroutine is to initialize the phase change module + !! by setting the parameters needed for phase change and + !! selecting the phase change module that will be used + !! (pT- or pTg-equilibrium) impure subroutine s_initialize_phasechange_module - - ! Saturation curve coefficients via stiffened gas EOS. Saurel et al. JCP (2008), Le Metayer et al. JFE (2004) - A = (gs_min(lp)*cvs(lp) - gs_min(vp)*cvs(vp) + qvps(vp) - qvps(lp))/((gs_min(vp) - 1.0_wp)*cvs(vp)) + ! variables used in the calculation of the saturation curves for fluids 1 and 2 + A = (gs_min(lp)*cvs(lp) - gs_min(vp)*cvs(vp) & + + qvps(vp) - qvps(lp))/((gs_min(vp) - 1.0_wp)*cvs(vp)) B = (qvs(lp) - qvs(vp))/((gs_min(vp) - 1.0_wp)*cvs(vp)) - C = (gs_min(vp)*cvs(vp) - gs_min(lp)*cvs(lp))/((gs_min(vp) - 1.0_wp)*cvs(vp)) + C = (gs_min(vp)*cvs(vp) - gs_min(lp)*cvs(lp)) & + /((gs_min(vp) - 1.0_wp)*cvs(vp)) - D = ((gs_min(lp) - 1.0_wp)*cvs(lp))/((gs_min(vp) - 1.0_wp)*cvs(vp)) + D = ((gs_min(lp) - 1.0_wp)*cvs(lp)) & + /((gs_min(vp) - 1.0_wp)*cvs(vp)) end subroutine s_initialize_phasechange_module - !> Apply pT- or pTg-equilibrium relaxation with mass depletion based on the incoming state conditions. + !> This subroutine is created to activate either the pT- (N fluids) or the + !! pTg-equilibrium (2 fluids for g-equilibrium) + !! model, also considering mass depletion, depending on the incoming + !! state conditions. + !! @param q_cons_vf Cell-average conservative variables subroutine s_infinite_relaxation_k(q_cons_vf) type(scalar_field), dimension(sys_size), intent(inout) :: q_cons_vf - real(wp) :: pS, pSOV, pSSL !< equilibrium pressure for mixture, overheated vapor, and subcooled liquid - real(wp) :: TS, TSOV, TSSL, TSatOV, TSatSL !< Equilibrium and saturation temperatures - real(wp) :: rhoe, dynE, rhos !< total internal energy, kinetic energy, and total entropy - real(wp) :: rho, rM, m1, m2, MCT !< total density, total reacting mass, individual reacting masses - real(wp) :: TvF !< total volume fraction + real(wp) :: pS, pSOV, pSSL !< equilibrium pressure for mixture, overheated vapor, and subcooled liquid + real(wp) :: TS, TSOV, TSSL, TSatOV, TSatSL !< equilibrium temperature for mixture, overheated vapor, and subcooled liquid. Saturation Temperatures at overheated vapor and subcooled liquid + real(wp) :: rhoe, dynE, rhos !< total internal energy, kinetic energy, and total entropy + real(wp) :: rho, rM, m1, m2, MCT !< total density, total reacting mass, individual reacting masses + real(wp) :: TvF !< total volume fraction + ! $:GPU_DECLARE(create='[pS,pSOV,pSSL,TS,TSOV,TSSL,TSatOV,TSatSL]') ! $:GPU_DECLARE(create='[rhoe,dynE,rhos,rho,rM,m1,m2,MCT,TvF]') - #:if not MFC_CASE_OPTIMIZATION and USING_AMD real(wp), dimension(3) :: p_infOV, p_infpT, p_infSL, sk, hk, gk, ek, rhok #:else @@ -83,31 +101,35 @@ contains #:endif ! $:GPU_DECLARE(create='[p_infOV,p_infpT,p_infSL,sk,hk,gk,ek,rhok]') - !> Generic loop iterators + !< Generic loop iterators integer :: i, j, k, l #ifdef _CRAYFTN #ifdef MFC_OpenACC - ! CCE 19 IPA workaround: prevent bring_routine_resident SIGSEGV DIR$ NOINLINE s_infinite_pt_relaxation_k DIR$ NOINLINE - ! s_infinite_ptg_relaxation_k DIR$ NOINLINE s_correct_partial_densities DIR$ NOINLINE s_TSat + ! CCE 19 IPA workaround: prevent bring_routine_resident SIGSEGV + !DIR$ NOINLINE s_infinite_pt_relaxation_k + !DIR$ NOINLINE s_infinite_ptg_relaxation_k + !DIR$ NOINLINE s_correct_partial_densities + !DIR$ NOINLINE s_TSat #endif #endif ! starting equilibrium solver - - $:GPU_PARALLEL_LOOP(collapse=3, private='[i, j, k, l, p_infOV, p_infpT, p_infSL, sk, hk, gk, ek, rhok, pS, pSOV, pSSL, & - & TS, TSOV, TSatOV, TSatSL, TSSL, rhoe, dynE, rhos, rho, rM, m1, m2, MCT, TvF]') + $:GPU_PARALLEL_LOOP(collapse=3, private='[i,j,k,l,p_infOV, p_infpT, p_infSL, sk, hk, gk, ek, rhok,pS, pSOV, pSSL, TS, TSOV, TSatOV, TSatSL, TSSL, rhoe, dynE, rhos, rho, rM, m1, m2, MCT, TvF]') do j = 0, m do k = 0, n do l = 0, p + rho = 0.0_wp; TvF = 0.0_wp $:GPU_LOOP(parallelism='[seq]') do i = 1, num_fluids + ! Mixture density rho = rho + q_cons_vf(i + contxb - 1)%sf(j, k, l) ! Total Volume Fraction TvF = TvF + q_cons_vf(i + advxb - 1)%sf(j, k, l) + end do ! calculating the total reacting mass for the phase change process. By hypothesis, this should not change @@ -127,26 +149,33 @@ contains dynE = 0.0_wp $:GPU_LOOP(parallelism='[seq]') do i = momxb, momxe + dynE = dynE + 5.0e-1_wp*q_cons_vf(i)%sf(j, k, l)**2/rho + end do - ! calculating the total energy that MUST be preserved throughout the pT- and pTg-relaxation procedures at each - ! of the cells. The internal energy is calculated as the total energy minus the kinetic energy to preserved its - ! value at sharp interfaces + ! calculating the total energy that MUST be preserved throughout the pT- and pTg-relaxation procedures + ! at each of the cells. The internal energy is calculated as the total energy minus the kinetic + ! energy to preserved its value at sharp interfaces rhoe = q_cons_vf(E_idx)%sf(j, k, l) - dynE - ! Calling pT-equilibrium for either finishing phase-change module, or as an IC for the pTg-equilibrium for this - ! case, MFL cannot be either 0 or 1, so I chose it to be 2 + ! Calling pT-equilibrium for either finishing phase-change module, or as an IC for the pTg-equilibrium + ! for this case, MFL cannot be either 0 or 1, so I chose it to be 2 call s_infinite_pt_relaxation_k(j, k, l, 2, pS, p_infpT, q_cons_vf, rhoe, TS) - ! Check if pTg-equilibrium needed; only partial densities require updating - if ((relax_model == 6) .and. ((q_cons_vf(lp + contxb - 1)%sf(j, k, & - & l) > mixM*rM) .and. (q_cons_vf(vp + contxb - 1)%sf(j, k, & - & l) > mixM*rM)) .and. (pS < pCr) .and. (TS < TCr)) then - ! Checking if phase change is needed, by checking whether the final solution is either subcoooled liquid or - ! overheated vapor. + ! check if pTg-equilibrium is required + ! NOTE that NOTHING else needs to be updated OTHER than the individual partial densities + ! given the outputs from the pT- and pTg-equilibrium solvers are just p and one of the partial masses + ! (pTg- case) + if ((relax_model == 6) .and. ((q_cons_vf(lp + contxb - 1)%sf(j, k, l) > mixM*rM) & + .and. (q_cons_vf(vp + contxb - 1)%sf(j, k, l) > mixM*rM)) & + .and. (pS < pCr) .and. (TS < TCr)) then + + ! Checking if phase change is needed, by checking whether the final solution is either subcoooled + ! liquid or overheated vapor. - ! overheated vapor case depleting the mass of liquid + ! overheated vapor case + ! depleting the mass of liquid q_cons_vf(lp + contxb - 1)%sf(j, k, l) = mixM*rM ! transferring the total mass to vapor @@ -158,7 +187,8 @@ contains ! calculating Saturation temperature call s_TSat(pSOV, TSatOV, TSOV) - ! subcooled liquid case transferring the total mass to liquid + ! subcooled liquid case + ! transferring the total mass to liquid q_cons_vf(lp + contxb - 1)%sf(j, k, l) = (1.0_wp - mixM)*rM ! depleting the mass of vapor @@ -172,6 +202,7 @@ contains ! checking the conditions for overheated vapor and subcooled liquide if (TSOV > TSatOV) then + ! Assigning pressure pS = pSOV @@ -183,7 +214,9 @@ contains ! correcting the vapor partial density q_cons_vf(vp + contxb - 1)%sf(j, k, l) = (1.0_wp - mixM)*rM - else if (TSSL < TSatSL) then + + elseif (TSSL < TSatSL) then + ! Assigning pressure pS = pSSL @@ -195,8 +228,11 @@ contains ! correcting the vapor partial density q_cons_vf(vp + contxb - 1)%sf(j, k, l) = mixM*rM + else - ! returning partial pressures to what they were from the homogeneous solver liquid + + ! returning partial pressures to what they were from the homogeneous solver + ! liquid q_cons_vf(lp + contxb - 1)%sf(j, k, l) = m1 ! vapor @@ -204,7 +240,9 @@ contains ! calling the pTg-equilibrium solver call s_infinite_ptg_relaxation_k(j, k, l, pS, p_infpT, rhoe, q_cons_vf, TS) + end if + end if ! Calculations AFTER equilibrium @@ -212,25 +250,31 @@ contains $:GPU_LOOP(parallelism='[seq]') do i = 1, num_fluids ! entropy - sk(i) = cvs(i)*log((TS**gs_min(i))/((pS + ps_inf(i))**(gs_min(i) - 1.0_wp))) + qvps(i) + sk(i) = cvs(i)*log((TS**gs_min(i)) & + /((pS + ps_inf(i))**(gs_min(i) - 1.0_wp))) + qvps(i) ! enthalpy - hk(i) = gs_min(i)*cvs(i)*TS + qvs(i) + hk(i) = gs_min(i)*cvs(i)*TS & + + qvs(i) ! Gibbs-free energy gk(i) = hk(i) - TS*sk(i) ! densities - rhok(i) = (pS + ps_inf(i))/((gs_min(i) - 1)*cvs(i)*TS) + rhok(i) = (pS + ps_inf(i)) & + /((gs_min(i) - 1)*cvs(i)*TS) ! internal energy - ek(i) = (pS + gs_min(i)*ps_inf(i))/(pS + ps_inf(i))*cvs(i)*TS + qvs(i) + ek(i) = (pS + gs_min(i) & + *ps_inf(i))/(pS + ps_inf(i)) & + *cvs(i)*TS + qvs(i) end do ! calculating volume fractions, internal energies, and total entropy rhos = 0.0_wp $:GPU_LOOP(parallelism='[seq]') do i = 1, num_fluids + ! volume fractions q_cons_vf(i + advxb - 1)%sf(j, k, l) = q_cons_vf(i + contxb - 1)%sf(j, k, l)/rhok(i) @@ -241,6 +285,7 @@ contains ! Total entropy rhos = rhos + q_cons_vf(i + contxb - 1)%sf(j, k, l)*sk(i) + end do end do end do @@ -249,22 +294,32 @@ contains end subroutine s_infinite_relaxation_k - !> Apply pT-equilibrium relaxation for N fluids - !! @param MFL flag: 0=gas, 1=liquid, 2=mixture + !> This auxiliary subroutine is created to activate the pT-equilibrium for N fluids + !! @param j generic loop iterator for x direction + !! @param k generic loop iterator for y direction + !! @param l generic loop iterator for z direction + !! @param MFL flag that tells whether the fluid is gas (0), liquid (1), or a mixture (2) + !! @param pS equilibrium pressure at the interface + !! @param p_infpT stiffness for the participating fluids under pT-equilibrium + !! @param q_cons_vf Cell-average conservative variables + !! @param rhoe mixture energy + !! @param TS equilibrium temperature at the interface subroutine s_infinite_pt_relaxation_k(j, k, l, MFL, pS, p_infpT, q_cons_vf, rhoe, TS) - - $:GPU_ROUTINE(function_name='s_infinite_pt_relaxation_k', parallelism='[seq]', cray_noinline=True) + $:GPU_ROUTINE(function_name='s_infinite_pt_relaxation_k', & + & parallelism='[seq]', cray_noinline=True) ! initializing variables - integer, intent(in) :: j, k, l, MFL - real(wp), intent(out) :: pS - real(wp), dimension(1:), intent(out) :: p_infpT + integer, intent(in) :: j, k, l, MFL + real(wp), intent(out) :: pS + real(wp), dimension(1:), intent(out) :: p_infpT type(scalar_field), dimension(sys_size), intent(in) :: q_cons_vf - real(wp), intent(in) :: rhoe - real(wp), intent(out) :: TS - real(wp) :: gp, gpp, hp, pO, mCP, mQ !< variables for the Newton Solver - real(wp) :: p_infpT_sum - integer :: i, ns !< generic loop iterators + real(wp), intent(in) :: rhoe + real(wp), intent(out) :: TS + real(wp) :: gp, gpp, hp, pO, mCP, mQ !< variables for the Newton Solver + real(wp) :: p_infpT_sum + + integer :: i, ns !< generic loop iterators + ! auxiliary variables for the pT-equilibrium solver mCP = 0.0_wp; mQ = 0.0_wp; p_infpT_sum = 0._wp $:GPU_LOOP(parallelism='[seq]') @@ -275,11 +330,13 @@ contains ! Performing tests before initializing the pT-equilibrium $:GPU_LOOP(parallelism='[seq]') do i = 1, num_fluids + ! sum of the total alpha*rho*cp of the system mCP = mCP + q_cons_vf(i + contxb - 1)%sf(j, k, l)*cvs(i)*gs_min(i) ! sum of the total alpha*rho*q of the system mQ = mQ + q_cons_vf(i + contxb - 1)%sf(j, k, l)*qvs(i) + end do #:if not MFC_CASE_OPTIMIZATION and USING_AMD @@ -293,8 +350,11 @@ contains ! Checking energy constraint if ((rhoe - mQ - minval(p_infpT)) < 0.0_wp) then + if ((MFL == 0) .or. (MFL == 1)) then - ! Assigning zero values for mass depletion cases pressure + + ! Assigning zero values for mass depletion cases + ! pressure pS = 0.0_wp ! temperature @@ -302,20 +362,22 @@ contains return end if + end if - ! calculating initial estimate for pressure in the pT-relaxation procedure. I will also use this variable to iterate over - ! the Newton's solver + ! calculating initial estimate for pressure in the pT-relaxation procedure. I will also use this variable to + ! iterate over the Newton's solver pO = 0.0_wp - ! Maybe improve this condition afterwards. As long as the initial guess is in between -min(ps_inf) and infinity, a solution - ! should be able to be found. + ! Maybe improve this condition afterwards. As long as the initial guess is in between -min(ps_inf) + ! and infinity, a solution should be able to be found. pS = 1.0e4_wp ! Newton Solver for the pT-equilibrium ns = 0 ! change this relative error metric. 1.e4_wp is just arbitrary do while ((abs(pS - pO) > palpha_eps) .and. (abs((pS - pO)/pO) > palpha_eps/1.e4_wp) .or. (ns == 0)) + ! increasing counter ns = ns + 1 @@ -326,16 +388,20 @@ contains gpp = 0.0_wp; gp = 0.0_wp; hp = 0.0_wp $:GPU_LOOP(parallelism='[seq]') do i = 1, num_fluids - gp = gp + (gs_min(i) - 1.0_wp)*q_cons_vf(i + contxb - 1)%sf(j, k, l)*cvs(i)*(rhoe + pS - mQ)/(mCP*(pS + p_infpT(i))) - gpp = gpp + (gs_min(i) - 1.0_wp)*q_cons_vf(i + contxb - 1)%sf(j, k, & - & l)*cvs(i)*(p_infpT(i) - rhoe + mQ)/(mCP*(pS + p_infpT(i))**2) + gp = gp + (gs_min(i) - 1.0_wp)*q_cons_vf(i + contxb - 1)%sf(j, k, l)*cvs(i) & + *(rhoe + pS - mQ)/(mCP*(pS + p_infpT(i))) + + gpp = gpp + (gs_min(i) - 1.0_wp)*q_cons_vf(i + contxb - 1)%sf(j, k, l)*cvs(i) & + *(p_infpT(i) - rhoe + mQ)/(mCP*(pS + p_infpT(i))**2) + end do hp = 1.0_wp/(rhoe + pS - mQ) + 1.0_wp/(pS + minval(p_infpT)) ! updating common pressure for the newton solver - pS = pO + ((1.0_wp - gp)/gpp)/(1.0_wp - (1.0_wp - gp + abs(1.0_wp - gp))/(2.0_wp*gpp)*hp) + pS = pO + ((1.0_wp - gp)/gpp)/(1.0_wp - (1.0_wp - gp + abs(1.0_wp - gp)) & + /(2.0_wp*gpp)*hp) end do ! common temperature @@ -343,32 +409,42 @@ contains end subroutine s_infinite_pt_relaxation_k - !> Apply pTg-equilibrium relaxation for N fluids under pT and 2 fluids under pTg-equilibrium. There is a final common p and T - !! during relaxation + !> This auxiliary subroutine is created to activate the pTg-equilibrium for N fluids under pT + !! and 2 fluids under pTg-equilibrium. There is a final common p and T during relaxation + !! @param j generic loop iterator for x direction + !! @param k generic loop iterator for y direction + !! @param l generic loop iterator for z direction + !! @param pS equilibrium pressure at the interface + !! @param p_infpT stiffness for the participating fluids under pT-equilibrium + !! @param rhoe mixture energy + !! @param q_cons_vf Cell-average conservative variables + !! @param TS equilibrium temperature at the interface subroutine s_infinite_ptg_relaxation_k(j, k, l, pS, p_infpT, rhoe, q_cons_vf, TS) + $:GPU_ROUTINE(function_name='s_infinite_ptg_relaxation_k', & + & parallelism='[seq]', cray_noinline=True) - $:GPU_ROUTINE(function_name='s_infinite_ptg_relaxation_k', parallelism='[seq]', cray_noinline=True) - - integer, intent(in) :: j, k, l - real(wp), intent(inout) :: pS - real(wp), dimension(1:), intent(in) :: p_infpT - real(wp), intent(in) :: rhoe + integer, intent(in) :: j, k, l + real(wp), intent(inout) :: pS + real(wp), dimension(1:), intent(in) :: p_infpT + real(wp), intent(in) :: rhoe type(scalar_field), dimension(sys_size), intent(inout) :: q_cons_vf - real(wp), intent(inout) :: TS + real(wp), intent(inout) :: TS #:if not MFC_CASE_OPTIMIZATION and USING_AMD - real(wp), dimension(3) :: p_infpTg !< stiffness for the participating fluids for pTg-equilibrium + real(wp), dimension(3) :: p_infpTg !< stiffness for the participating fluids for pTg-equilibrium #:else - real(wp), dimension(num_fluids) :: p_infpTg !< stiffness for the participating fluids for pTg-equilibrium + real(wp), dimension(num_fluids) :: p_infpTg !< stiffness for the participating fluids for pTg-equilibrium #:endif - real(wp), dimension(2, 2) :: Jac, InvJac, TJac !< matrices for the Newton Solver - real(wp), dimension(2) :: R2D, DeltamP !< residual and correction array - real(wp) :: Om !< underrelaxation factor - real(wp) :: mCP, mCPD, mCVGP, mCVGP2, mQ, mQD !< auxiliary variables for the pTg-solver - real(wp) :: ml, mT, dFdT, dTdm, dTdp + real(wp), dimension(2, 2) :: Jac, InvJac, TJac !< matrices for the Newton Solver + real(wp), dimension(2) :: R2D, DeltamP !< residual and correction array + real(wp) :: Om ! underrelaxation factor + real(wp) :: mCP, mCPD, mCVGP, mCVGP2, mQ, mQD ! auxiliary variables for the pTg-solver + real(wp) :: ml, mT, dFdT, dTdm, dTdp - !> Generic loop iterators + !< Generic loop iterators integer :: i, ns - ! pTg-equilibrium solution procedure Newton Solver parameters counter + ! pTg-equilibrium solution procedure + ! Newton Solver parameters + ! counter ns = 0 ! Relaxation factor @@ -376,45 +452,62 @@ contains p_infpTg = p_infpT - if (((pS < 0.0_wp) .and. ((q_cons_vf(lp + contxb - 1)%sf(j, k, l) + q_cons_vf(vp + contxb - 1)%sf(j, k, & - & l)) > ((rhoe - gs_min(lp)*ps_inf(lp)/(gs_min(lp) - 1))/qvs(lp)))) .or. ((pS >= 0.0_wp) .and. (pS < 1.0e-1_wp))) then + if (((pS < 0.0_wp) .and. ((q_cons_vf(lp + contxb - 1)%sf(j, k, l) & + + q_cons_vf(vp + contxb - 1)%sf(j, k, l)) > ((rhoe & + - gs_min(lp)*ps_inf(lp)/(gs_min(lp) - 1))/qvs(lp)))) .or. & + ((pS >= 0.0_wp) .and. (pS < 1.0e-1_wp))) then + ! improve this initial condition pS = 1.0e4_wp + end if - ! Loop until the solution for F(X) is satisfied Check whether I need to use both absolute and relative values for the - ! residual, and how to do it adequately. Dummy guess to start the pTg-equilibrium problem. improve this initial condition + ! Loop until the solution for F(X) is satisfied + ! Check whether I need to use both absolute and relative values + ! for the residual, and how to do it adequately. + ! Dummy guess to start the pTg-equilibrium problem. + ! improve this initial condition R2D(1) = 0.0_wp; R2D(2) = 0.0_wp DeltamP(1) = 0.0_wp; DeltamP(2) = 0.0_wp - do while (((sqrt(R2D(1)**2 + R2D(2)**2) > ptgalpha_eps) .and. ((sqrt(R2D(1)**2 + R2D(2)**2)/rhoe) > (ptgalpha_eps/1.e6_wp) & - & )) .or. (ns == 0)) + do while (((sqrt(R2D(1)**2 + R2D(2)**2) > ptgalpha_eps) & + .and. ((sqrt(R2D(1)**2 + R2D(2)**2)/rhoe) > (ptgalpha_eps/1.e6_wp))) & + .or. (ns == 0)) ! Updating counter for the iterative procedure ns = ns + 1 ! Auxiliary variables to help in the calculation of the residue mCP = 0.0_wp; mCPD = 0.0_wp; mCVGP = 0.0_wp; mCVGP2 = 0.0_wp; mQ = 0.0_wp; mQD = 0.0_wp - ! Those must be updated through the iterations, as they either depend on the partial masses for all fluids, or on the - ! equilibrium pressure + ! Those must be updated through the iterations, as they either depend on + ! the partial masses for all fluids, or on the equilibrium pressure $:GPU_LOOP(parallelism='[seq]') do i = 1, num_fluids + ! sum of the total alpha*rho*cp of the system - mCP = mCP + q_cons_vf(i + contxb - 1)%sf(j, k, l)*cvs(i)*gs_min(i) + mCP = mCP + q_cons_vf(i + contxb - 1)%sf(j, k, l) & + *cvs(i)*gs_min(i) ! sum of the total alpha*rho*q of the system mQ = mQ + q_cons_vf(i + contxb - 1)%sf(j, k, l)*qvs(i) - ! These auxiliary variables now need to be updated, as the partial densities now vary at every iteration + ! These auxiliary variables now need to be updated, as the partial densities now + ! vary at every iteration if ((i /= lp) .and. (i /= vp)) then - mCVGP = mCVGP + q_cons_vf(i + contxb - 1)%sf(j, k, l)*cvs(i)*(gs_min(i) - 1)/(pS + ps_inf(i)) - mCVGP2 = mCVGP2 + q_cons_vf(i + contxb - 1)%sf(j, k, l)*cvs(i)*(gs_min(i) - 1)/((pS + ps_inf(i))**2) + mCVGP = mCVGP + q_cons_vf(i + contxb - 1)%sf(j, k, l) & + *cvs(i)*(gs_min(i) - 1)/(pS + ps_inf(i)) + + mCVGP2 = mCVGP2 + q_cons_vf(i + contxb - 1)%sf(j, k, l) & + *cvs(i)*(gs_min(i) - 1)/((pS + ps_inf(i))**2) mQD = mQD + q_cons_vf(i + contxb - 1)%sf(j, k, l)*qvs(i) ! sum of the total alpha*rho*cp of the system - mCPD = mCPD + q_cons_vf(i + contxb - 1)%sf(j, k, l)*cvs(i)*gs_min(i) + mCPD = mCPD + q_cons_vf(i + contxb - 1)%sf(j, k, l)*cvs(i) & + *gs_min(i) + end if + end do ! calculating the (2D) Jacobian Matrix used in the solution of the pTg-quilibrium model @@ -423,41 +516,62 @@ contains ml = q_cons_vf(lp + contxb - 1)%sf(j, k, l) ! mass of the two participating fluids - mT = q_cons_vf(lp + contxb - 1)%sf(j, k, l) + q_cons_vf(vp + contxb - 1)%sf(j, k, l) - - TS = 1/(mT*cvs(vp)*(gs_min(vp) - 1)/(pS + ps_inf(vp)) + ml*(cvs(lp)*(gs_min(lp) - 1)/(pS + ps_inf(lp)) - cvs(vp) & - & *(gs_min(vp) - 1)/(pS + ps_inf(vp))) + mCVGP) - - dFdT = -(cvs(lp)*gs_min(lp) - cvs(vp)*gs_min(vp))*log(TS) - (qvps(lp) - qvps(vp)) + cvs(lp)*(gs_min(lp) - 1)*log(pS & - & + ps_inf(lp)) - cvs(vp)*(gs_min(vp) - 1)*log(pS + ps_inf(vp)) - - dTdm = -(cvs(lp)*(gs_min(lp) - 1)/(pS + ps_inf(lp)) - cvs(vp)*(gs_min(vp) - 1)/(pS + ps_inf(vp)))*TS**2 - - dTdp = (mT*cvs(vp)*(gs_min(vp) - 1)/(pS + ps_inf(vp))**2 + ml*(cvs(lp)*(gs_min(lp) - 1)/(pS + ps_inf(lp))**2 - cvs(vp) & - & *(gs_min(vp) - 1)/(pS + ps_inf(vp))**2) + mCVGP2)*TS**2 - - ! F = (F1,F2) is the function whose roots we are looking for x = (m1, p) are the independent variables. m1 = mass of the - ! first participant fluid, p = pressure F1 = 0 is the Gibbs free energy quality F2 = 0 is the enforcement of the - ! thermodynamic (total - kinectic) energy dF1dm + mT = q_cons_vf(lp + contxb - 1)%sf(j, k, l) & + + q_cons_vf(vp + contxb - 1)%sf(j, k, l) + + TS = 1/(mT*cvs(vp)*(gs_min(vp) - 1)/(pS + ps_inf(vp)) & + + ml*(cvs(lp)*(gs_min(lp) - 1)/(pS + ps_inf(lp)) & + - cvs(vp)*(gs_min(vp) - 1)/(pS + ps_inf(vp))) & + + mCVGP) + + dFdT = & + -(cvs(lp)*gs_min(lp) - cvs(vp)*gs_min(vp))*log(TS) & + - (qvps(lp) - qvps(vp)) & + + cvs(lp)*(gs_min(lp) - 1)*log(pS + ps_inf(lp)) & + - cvs(vp)*(gs_min(vp) - 1)*log(pS + ps_inf(vp)) + + dTdm = -(cvs(lp)*(gs_min(lp) - 1)/(pS + ps_inf(lp)) & + - cvs(vp)*(gs_min(vp) - 1)/(pS + ps_inf(vp)))*TS**2 + + dTdp = (mT*cvs(vp)*(gs_min(vp) - 1)/(pS + ps_inf(vp))**2 & + + ml*(cvs(lp)*(gs_min(lp) - 1)/(pS + ps_inf(lp))**2 & + - cvs(vp)*(gs_min(vp) - 1)/(pS + ps_inf(vp))**2) & + + mCVGP2)*TS**2 + + ! F = (F1,F2) is the function whose roots we are looking for + ! x = (m1, p) are the independent variables. m1 = mass of the first participant fluid, p = pressure + ! F1 = 0 is the Gibbs free energy quality + ! F2 = 0 is the enforcement of the thermodynamic (total - kinectic) energy + ! dF1dm Jac(1, 1) = dFdT*dTdm ! dF1dp - Jac(1, 2) = dFdT*dTdp + TS*(cvs(lp)*(gs_min(lp) - 1)/(pS + ps_inf(lp)) - cvs(vp)*(gs_min(vp) - 1)/(pS + ps_inf(vp))) + Jac(1, 2) = dFdT*dTdp + TS & + *(cvs(lp)*(gs_min(lp) - 1)/(pS + ps_inf(lp)) & + - cvs(vp)*(gs_min(vp) - 1)/(pS + ps_inf(vp))) ! dF2dm - Jac(2, & - & 1) = (qvs(vp) - qvs(lp) + (cvs(vp)*gs_min(vp) - cvs(lp)*gs_min(lp))/(ml*(cvs(lp)*(gs_min(lp) - 1)/(pS & - & + ps_inf(lp)) - cvs(vp)*(gs_min(vp) - 1)/(pS + ps_inf(vp))) + mT*cvs(vp)*(gs_min(vp) - 1)/(pS + ps_inf(vp)) & - & + mCVGP) - (ml*(cvs(vp)*gs_min(vp) - cvs(lp)*gs_min(lp)) - mT*cvs(vp)*gs_min(vp) - mCPD)*(cvs(lp)*(gs_min(lp) & - & - 1)/(pS + ps_inf(lp)) - cvs(vp)*(gs_min(vp) - 1)/(pS + ps_inf(vp)))/((ml*(cvs(lp)*(gs_min(lp) - 1)/(pS & - & + ps_inf(lp)) - cvs(vp)*(gs_min(vp) - 1)/(pS + ps_inf(vp))) + mT*cvs(vp)*(gs_min(vp) - 1)/(pS + ps_inf(vp)) & - & + mCVGP)**2))/1 + Jac(2, 1) = (qvs(vp) - qvs(lp) & + + (cvs(vp)*gs_min(vp) - cvs(lp)*gs_min(lp)) & + /(ml*(cvs(lp)*(gs_min(lp) - 1)/(pS + ps_inf(lp)) & + - cvs(vp)*(gs_min(vp) - 1)/(pS + ps_inf(vp))) & + + mT*cvs(vp)*(gs_min(vp) - 1)/(pS + ps_inf(vp)) + mCVGP) & + - (ml*(cvs(vp)*gs_min(vp) - cvs(lp)*gs_min(lp)) & + - mT*cvs(vp)*gs_min(vp) - mCPD) & + *(cvs(lp)*(gs_min(lp) - 1)/(pS + ps_inf(lp)) & + - cvs(vp)*(gs_min(vp) - 1)/(pS + ps_inf(vp))) & + /((ml*(cvs(lp)*(gs_min(lp) - 1)/(pS + ps_inf(lp)) & + - cvs(vp)*(gs_min(vp) - 1)/(pS + ps_inf(vp))) & + + mT*cvs(vp)*(gs_min(vp) - 1)/(pS + ps_inf(vp)) + mCVGP)**2))/1 ! dF2dp - Jac(2, & - & 2) = (1 + (ml*(cvs(vp)*gs_min(vp) - cvs(lp)*gs_min(lp)) - mT*cvs(vp)*gs_min(vp) - mCPD)*(ml*(cvs(lp)*(gs_min(lp) & - & - 1)/(pS + ps_inf(lp))**2 - cvs(vp)*(gs_min(vp) - 1)/(pS + ps_inf(vp))**2) + mT*cvs(vp)*(gs_min(vp) - 1)/(pS & - & + ps_inf(vp))**2 + mCVGP2)/(ml*(cvs(lp)*(gs_min(lp) - 1)/(pS + ps_inf(lp)) - cvs(vp)*(gs_min(vp) - 1)/(pS & - & + ps_inf(vp))) + mT*cvs(vp)*(gs_min(vp) - 1)/(pS + ps_inf(vp)) + mCVGP)**2)/1 + Jac(2, 2) = (1 + (ml*(cvs(vp)*gs_min(vp) - cvs(lp)*gs_min(lp)) & + - mT*cvs(vp)*gs_min(vp) - mCPD) & + *(ml*(cvs(lp)*(gs_min(lp) - 1)/(pS + ps_inf(lp))**2 & + - cvs(vp)*(gs_min(vp) - 1)/(pS + ps_inf(vp))**2) & + + mT*cvs(vp)*(gs_min(vp) - 1)/(pS + ps_inf(vp))**2 + mCVGP2) & + /(ml*(cvs(lp)*(gs_min(lp) - 1)/(pS + ps_inf(lp)) & + - cvs(vp)*(gs_min(vp) - 1)/(pS + ps_inf(vp))) & + + mT*cvs(vp)*(gs_min(vp) - 1)/(pS + ps_inf(vp)) + mCVGP)**2)/1 ! intermediate elements of J^{-1} InvJac(1, 1) = Jac(2, 2) @@ -478,7 +592,8 @@ contains DeltamP(1) = -1.0_wp*(InvJac(1, 1)*R2D(1) + InvJac(1, 2)*R2D(2)) DeltamP(2) = -1.0_wp*(InvJac(2, 1)*R2D(1) + InvJac(2, 2)*R2D(2)) - ! updating two reacting 'masses'. Recall that inert 'masses' do not change during the phase change liquid + ! updating two reacting 'masses'. Recall that inert 'masses' do not change during the phase change + ! liquid q_cons_vf(lp + contxb - 1)%sf(j, k, l) = q_cons_vf(lp + contxb - 1)%sf(j, k, l) + Om*DeltamP(1) ! gas @@ -487,91 +602,124 @@ contains ! updating pressure pS = pS + Om*DeltamP(2) - ! calculating residuals, which are (i) the difference between the Gibbs Free energy of the gas and the liquid and (ii) - ! the energy before and after the phase-change process. + ! calculating residuals, which are (i) the difference between the Gibbs Free energy of the gas and the liquid + ! and (ii) the energy before and after the phase-change process. ! mass of the reacting liquid ml = q_cons_vf(lp + contxb - 1)%sf(j, k, l) ! mass of the two participating fluids - mT = q_cons_vf(lp + contxb - 1)%sf(j, k, l) + q_cons_vf(vp + contxb - 1)%sf(j, k, l) + mT = q_cons_vf(lp + contxb - 1)%sf(j, k, l) & + + q_cons_vf(vp + contxb - 1)%sf(j, k, l) - TS = 1/(mT*cvs(vp)*(gs_min(vp) - 1)/(pS + ps_inf(vp)) + ml*(cvs(lp)*(gs_min(lp) - 1)/(pS + ps_inf(lp)) - cvs(vp) & - & *(gs_min(vp) - 1)/(pS + ps_inf(vp))) + mCVGP) + TS = 1/(mT*cvs(vp)*(gs_min(vp) - 1)/(pS + ps_inf(vp)) & + + ml*(cvs(lp)*(gs_min(lp) - 1)/(pS + ps_inf(lp)) & + - cvs(vp)*(gs_min(vp) - 1)/(pS + ps_inf(vp))) & + + mCVGP) ! Gibbs Free Energy Equality condition (DG) - R2D(1) = TS*((cvs(lp)*gs_min(lp) - cvs(vp)*gs_min(vp))*(1 - log(TS)) - (qvps(lp) - qvps(vp)) + cvs(lp)*(gs_min(lp) & - & - 1)*log(pS + ps_inf(lp)) - cvs(vp)*(gs_min(vp) - 1)*log(pS + ps_inf(vp))) + qvs(lp) - qvs(vp) + R2D(1) = TS*((cvs(lp)*gs_min(lp) - cvs(vp)*gs_min(vp)) & + *(1 - log(TS)) - (qvps(lp) - qvps(vp)) & + + cvs(lp)*(gs_min(lp) - 1)*log(pS + ps_inf(lp)) & + - cvs(vp)*(gs_min(vp) - 1)*log(pS + ps_inf(vp))) & + + qvs(lp) - qvs(vp) ! Constant Energy Process condition (DE) - R2D(2) = (rhoe + pS + ml*(qvs(vp) - qvs(lp)) - mT*qvs(vp) - mQD + (ml*(gs_min(vp)*cvs(vp) - gs_min(lp)*cvs(lp)) & - & - mT*gs_min(vp)*cvs(vp) - mCPD)/(ml*(cvs(lp)*(gs_min(lp) - 1)/(pS + ps_inf(lp)) - cvs(vp)*(gs_min(vp) - 1)/(pS & - & + ps_inf(vp))) + mT*cvs(vp)*(gs_min(vp) - 1)/(pS + ps_inf(vp)) + mCVGP))/1 + R2D(2) = (rhoe + pS & + + ml*(qvs(vp) - qvs(lp)) - mT*qvs(vp) - mQD & + + (ml*(gs_min(vp)*cvs(vp) - gs_min(lp)*cvs(lp)) & + - mT*gs_min(vp)*cvs(vp) - mCPD) & + /(ml*(cvs(lp)*(gs_min(lp) - 1)/(pS + ps_inf(lp)) & + - cvs(vp)*(gs_min(vp) - 1)/(pS + ps_inf(vp))) & + + mT*cvs(vp)*(gs_min(vp) - 1)/(pS + ps_inf(vp)) + mCVGP))/1 + end do ! common temperature TS = (rhoe + pS - mQ)/mCP - end subroutine s_infinite_ptg_relaxation_k - !> Correct the partial densities of the reacting fluids in case one of them is negative but their sum is positive. Inert phases - !! are not corrected at this moment + !> This auxiliary subroutine corrects the partial densities of the REACTING fluids in case one of them is negative + !! but their sum is positive. Inert phases are not corrected at this moment + !! @param MCT partial density correction parameter + !! @param q_cons_vf Cell-average conservative variables + !! @param rM sum of the reacting masses + !! @param j generic loop iterator for x direction + !! @param k generic loop iterator for y direction + !! @param l generic loop iterator for z direction subroutine s_correct_partial_densities(MCT, q_cons_vf, rM, j, k, l) - - $:GPU_ROUTINE(function_name='s_correct_partial_densities', parallelism='[seq]', cray_noinline=True) + $:GPU_ROUTINE(function_name='s_correct_partial_densities', & + & parallelism='[seq]', cray_noinline=True) !> @name variables for the correction of the reacting partial densities !> @{ - real(wp), intent(out) :: MCT + real(wp), intent(out) :: MCT type(scalar_field), dimension(sys_size), intent(inout) :: q_cons_vf - real(wp), intent(inout) :: rM - integer, intent(in) :: j, k, l + real(wp), intent(inout) :: rM + integer, intent(in) :: j, k, l !> @} if (rM < 0.0_wp) then - if ((q_cons_vf(lp + contxb - 1)%sf(j, k, l) >= -1.0_wp*mixM) .and. (q_cons_vf(vp + contxb - 1)%sf(j, k, & - & l) >= -1.0_wp*mixM)) then + + if ((q_cons_vf(lp + contxb - 1)%sf(j, k, l) >= -1.0_wp*mixM) .and. & + (q_cons_vf(vp + contxb - 1)%sf(j, k, l) >= -1.0_wp*mixM)) then + q_cons_vf(lp + contxb - 1)%sf(j, k, l) = 0.0_wp q_cons_vf(vp + contxb - 1)%sf(j, k, l) = 0.0_wp rM = q_cons_vf(lp + contxb - 1)%sf(j, k, l) + q_cons_vf(vp + contxb - 1)%sf(j, k, l) + end if + end if - ! TODO: Consider partitioning partial densities instead of absolute-value correction + ! Defining the correction in terms of an absolute value might not be the best practice. + ! Maybe a good way to do this is to partition the partial densities, giving a small percentage of the total reacting density MCT = 2*mixM ! correcting the partial densities of the reacting fluids. What to do for the nonreacting ones? if (q_cons_vf(lp + contxb - 1)%sf(j, k, l) < 0.0_wp) then + q_cons_vf(lp + contxb - 1)%sf(j, k, l) = MCT*rM q_cons_vf(vp + contxb - 1)%sf(j, k, l) = (1.0_wp - MCT)*rM - else if (q_cons_vf(vp + contxb - 1)%sf(j, k, l) < 0.0_wp) then + + elseif (q_cons_vf(vp + contxb - 1)%sf(j, k, l) < 0.0_wp) then + q_cons_vf(lp + contxb - 1)%sf(j, k, l) = (1.0_wp - MCT)*rM q_cons_vf(vp + contxb - 1)%sf(j, k, l) = MCT*rM - end if + end if end subroutine s_correct_partial_densities - !> Find the saturation temperature for a given saturation pressure using a Newton solver + !> This auxiliary subroutine finds the Saturation temperature for a given + !! saturation pressure through a newton solver + !! @param pSat Saturation Pressure + !! @param TSat Saturation Temperature + !! @param TSIn equilibrium Temperature elemental subroutine s_TSat(pSat, TSat, TSIn) + $:GPU_ROUTINE(function_name='s_TSat',parallelism='[seq]', & + & cray_noinline=True) - $:GPU_ROUTINE(function_name='s_TSat',parallelism='[seq]', cray_noinline=True) - - real(wp), intent(in) :: pSat + real(wp), intent(in) :: pSat real(wp), intent(out) :: TSat - real(wp), intent(in) :: TSIn - real(wp) :: dFdT, FT, Om !< auxiliary variables + real(wp), intent(in) :: TSIn + + real(wp) :: dFdT, FT, Om !< auxiliary variables + ! Generic loop iterators integer :: ns if ((f_approx_equal(pSat, 0.0_wp)) .and. (f_approx_equal(TSIn, 0.0_wp))) then + ! assigning Saturation temperature TSat = 0.0_wp + else - ! calculating initial estimate for temperature in the TSat procedure. I will also use this variable to iterate over the - ! Newton's solver + + ! calculating initial estimate for temperature in the TSat procedure. I will also use this variable to + ! iterate over the Newton's solver TSat = TSIn ! iteration counter @@ -580,8 +728,9 @@ contains ! underrelaxation factor Om = 1.0e-3_wp - ! FT must be initialized before the do while condition is evaluated. Fortran .or. is not short-circuit: abs(FT) is - ! always evaluated even when ns == 0, so FT must have a defined value here. + ! FT must be initialized before the do while condition is evaluated. + ! Fortran .or. is not short-circuit: abs(FT) is always evaluated even + ! when ns == 0, so FT must have a defined value here. FT = huge(1.0_wp) do while ((abs(FT) > ptgalpha_eps) .or. (ns == 0)) @@ -589,25 +738,33 @@ contains ns = ns + 1 ! calculating residual - FT = TSat*((cvs(lp)*gs_min(lp) - cvs(vp)*gs_min(vp))*(1 - log(TSat)) - (qvps(lp) - qvps(vp)) + cvs(lp)*(gs_min(lp) & - & - 1)*log(pSat + ps_inf(lp)) - cvs(vp)*(gs_min(vp) - 1)*log(pSat + ps_inf(vp))) + qvs(lp) - qvs(vp) + FT = TSat*((cvs(lp)*gs_min(lp) - cvs(vp)*gs_min(vp)) & + *(1 - log(TSat)) - (qvps(lp) - qvps(vp)) & + + cvs(lp)*(gs_min(lp) - 1)*log(pSat + ps_inf(lp)) & + - cvs(vp)*(gs_min(vp) - 1)*log(pSat + ps_inf(vp))) & + + qvs(lp) - qvs(vp) ! calculating the jacobian - dFdT = -(cvs(lp)*gs_min(lp) - cvs(vp)*gs_min(vp))*log(TSat) - (qvps(lp) - qvps(vp)) + cvs(lp)*(gs_min(lp) - 1) & - & *log(pSat + ps_inf(lp)) - cvs(vp)*(gs_min(vp) - 1)*log(pSat + ps_inf(vp)) + dFdT = & + -(cvs(lp)*gs_min(lp) - cvs(vp)*gs_min(vp))*log(TSat) & + - (qvps(lp) - qvps(vp)) & + + cvs(lp)*(gs_min(lp) - 1)*log(pSat + ps_inf(lp)) & + - cvs(vp)*(gs_min(vp) - 1)*log(pSat + ps_inf(vp)) ! updating saturation temperature TSat = TSat - Om*FT/dFdT if (abs(FT) <= ptgalpha_eps) exit end do + end if end subroutine s_TSat - !> Finalize the phase change module + !> This subroutine finalizes the phase change module impure subroutine s_finalize_relaxation_solver_module - end subroutine s_finalize_relaxation_solver_module + #endif + end module m_phase_change diff --git a/src/common/m_precision_select.f90 b/src/common/m_precision_select.f90 index 7c730cf303..9874ccd87f 100644 --- a/src/common/m_precision_select.f90 +++ b/src/common/m_precision_select.f90 @@ -7,22 +7,23 @@ module m_precision_select ! use, intrinsic :: iso_c_binding #ifdef MFC_MPI - use mpi !< Message passing interface (MPI) module + use mpi !< Message passing interface (MPI) module #endif implicit none ! Define the available precision types - integer, parameter :: half_precision = 2 !< selected_real_kind(3, 4) + integer, parameter :: half_precision = 2 ! selected_real_kind(3, 4) integer, parameter :: single_precision = selected_real_kind(6, 37) integer, parameter :: double_precision = selected_real_kind(15, 307) + integer, parameter :: hp = half_precision integer, parameter :: sp = single_precision integer, parameter :: dp = double_precision ! Set the working precision (wp) to single or double #ifdef MFC_SINGLE_PRECISION - integer, parameter :: wp = single_precision !< Change to single_precision if needed + integer, parameter :: wp = single_precision ! Change to single_precision if needed #else integer, parameter :: wp = double_precision #endif @@ -42,9 +43,10 @@ module m_precision_select ! MPI types per element. IE Real(kind=2) <=> 2 MPI_BYTE integer, parameter :: mpi_io_type = merge(2, 1, stp == half_precision) #else - integer, parameter :: mpi_p = -100 !< Default value when MPI is not used + integer, parameter :: mpi_p = -100 ! Default value when MPI is not used integer, parameter :: mpi_2p = -100 integer, parameter :: mpi_io_p = -100 integer, parameter :: mpi_io_type = -100 #endif + end module m_precision_select diff --git a/src/common/m_variables_conversion.fpp b/src/common/m_variables_conversion.fpp index 9fdae1258b..632c8df1b0 100644 --- a/src/common/m_variables_conversion.fpp +++ b/src/common/m_variables_conversion.fpp @@ -8,17 +8,23 @@ !> @brief Conservative-to-primitive variable conversion, mixture property evaluation, and pressure computation module m_variables_conversion - use m_derived_types - use m_global_parameters - use m_mpi_proxy - use m_helper_basic + use m_derived_types !< Definitions of the derived types + + use m_global_parameters !< Definitions of the global parameters + + use m_mpi_proxy !< Message passing interface (MPI) module proxy + + use m_helper_basic !< Functions to compare floating point numbers + use m_helper - use m_thermochem, only: num_species, get_temperature, get_pressure, gas_constant, get_mixture_molecular_weight, & - & get_mixture_energy_mass + + use m_thermochem, only: & + num_species, get_temperature, get_pressure, gas_constant, & + get_mixture_molecular_weight, get_mixture_energy_mass implicit none - private + private; public :: s_initialize_variables_conversion_module, & s_initialize_pb, & s_initialize_mv, & @@ -32,91 +38,122 @@ module m_variables_conversion s_compute_pressure, & s_compute_species_fraction, & #ifndef MFC_PRE_PROCESS - s_compute_speed_of_sound, & + s_compute_speed_of_sound, & s_compute_fast_magnetosonic_speed, & #endif - s_finalize_variables_conversion_module + s_finalize_variables_conversion_module - ! In simulation, gammas, pi_infs, and qvs are already declared in m_global_variables + !! In simulation, gammas, pi_infs, and qvs are already declared in m_global_variables #ifndef MFC_SIMULATION real(wp), allocatable, public, dimension(:) :: gammas, gs_min, pi_infs, ps_inf, cvs, qvs, qvps - $:GPU_DECLARE(create='[gammas, gs_min, pi_infs, ps_inf, cvs, qvs, qvps]') + $:GPU_DECLARE(create='[gammas,gs_min,pi_infs,ps_inf,cvs,qvs,qvps]') #endif - real(wp), allocatable, dimension(:) :: Gs_vc - integer, allocatable, dimension(:) :: bubrs_vc - real(wp), allocatable, dimension(:,:) :: Res_vc - $:GPU_DECLARE(create='[bubrs_vc, Gs_vc, Res_vc]') + real(wp), allocatable, dimension(:) :: Gs_vc + integer, allocatable, dimension(:) :: bubrs_vc + real(wp), allocatable, dimension(:, :) :: Res_vc + $:GPU_DECLARE(create='[bubrs_vc,Gs_vc,Res_vc]') integer :: is1b, is2b, is3b, is1e, is2e, is3e - $:GPU_DECLARE(create='[is1b, is2b, is3b, is1e, is2e, is3e]') + $:GPU_DECLARE(create='[is1b,is2b,is3b,is1e,is2e,is3e]') - real(wp), allocatable, dimension(:,:,:), public :: rho_sf !< Scalar density function - real(wp), allocatable, dimension(:,:,:), public :: gamma_sf !< Scalar sp. heat ratio function - real(wp), allocatable, dimension(:,:,:), public :: pi_inf_sf !< Scalar liquid stiffness function - real(wp), allocatable, dimension(:,:,:), public :: qv_sf !< Scalar liquid energy reference function + real(wp), allocatable, dimension(:, :, :), public :: rho_sf !< Scalar density function + real(wp), allocatable, dimension(:, :, :), public :: gamma_sf !< Scalar sp. heat ratio function + real(wp), allocatable, dimension(:, :, :), public :: pi_inf_sf !< Scalar liquid stiffness function + real(wp), allocatable, dimension(:, :, :), public :: qv_sf !< Scalar liquid energy reference function contains - !> Dispatch to the s_convert_mixture_to_mixture_variables and s_convert_species_to_mixture_variables subroutines. Replaces a - !! procedure pointer. - subroutine s_convert_to_mixture_variables(q_vf, i, j, k, rho, gamma, pi_inf, qv, Re_K, G_K, G) + !> Dispatch to the s_convert_mixture_to_mixture_variables + !! and s_convert_species_to_mixture_variables subroutines. + !! Replaces a procedure pointer. + !! @param q_vf Conservative or primitive variables + !! @param i First-coordinate cell index + !! @param j Second-coordinate cell index + !! @param k Third-coordinate cell index + !! @param rho Density + !! @param gamma Specific heat ratio function + !! @param pi_inf Liquid stiffness function + !! @param qv Fluid reference energy + !! @param Re_K Reynolds number (optional) + !! @param G_K Shear modulus (optional) + !! @param G Shear moduli of the fluids (optional) + subroutine s_convert_to_mixture_variables(q_vf, i, j, k, & + rho, gamma, pi_inf, qv, Re_K, G_K, G) - type(scalar_field), dimension(sys_size), intent(in) :: q_vf - integer, intent(in) :: i, j, k - real(wp), intent(out), target :: rho, gamma, pi_inf, qv - real(wp), optional, dimension(2), intent(out) :: Re_K - real(wp), optional, intent(out) :: G_K + type(scalar_field), dimension(sys_size), intent(in) :: q_vf + integer, intent(in) :: i, j, k + real(wp), intent(out), target :: rho, gamma, pi_inf, qv + real(wp), optional, dimension(2), intent(out) :: Re_K + real(wp), optional, intent(out) :: G_K real(wp), optional, dimension(num_fluids), intent(in) :: G - if (model_eqns == 1) then ! Gamma/pi_inf model - call s_convert_mixture_to_mixture_variables(q_vf, i, j, k, rho, gamma, pi_inf, qv) + if (model_eqns == 1) then ! Gamma/pi_inf model + call s_convert_mixture_to_mixture_variables(q_vf, i, j, k, & + rho, gamma, pi_inf, qv) + else ! Volume fraction model - call s_convert_species_to_mixture_variables(q_vf, i, j, k, rho, gamma, pi_inf, qv, Re_K, G_K, G) + call s_convert_species_to_mixture_variables(q_vf, i, j, k, & + rho, gamma, pi_inf, qv, Re_K, G_K, G) end if end subroutine s_convert_to_mixture_variables - !> Compute the pressure from the appropriate equation of state + !> This procedure conditionally calculates the appropriate pressure + !! @param energy Energy + !! @param alf Void Fraction + !! @param dyn_p Dynamic Pressure + !! @param pi_inf Liquid Stiffness + !! @param gamma Specific Heat Ratio + !! @param rho Density + !! @param qv fluid reference energy + !! @param rhoYks Species partial densities + !! @param pres Pressure to calculate + !! @param T Temperature + !! @param stress Shear Stress + !! @param mom Momentum + !! @param G Shear modulus (optional) + !! @param pres_mag Magnetic pressure (optional) subroutine s_compute_pressure(energy, alf, dyn_p, pi_inf, gamma, rho, qv, rhoYks, pres, T, stress, mom, G, pres_mag) - - $:GPU_ROUTINE(function_name='s_compute_pressure',parallelism='[seq]', cray_noinline=True) - - real(stp), intent(in) :: energy, alf - real(wp), intent(in) :: dyn_p - real(wp), intent(in) :: pi_inf, gamma, rho, qv - real(wp), intent(out) :: pres - real(wp), intent(inout) :: T + $:GPU_ROUTINE(function_name='s_compute_pressure',parallelism='[seq]', & + & cray_noinline=True) + + real(stp), intent(in) :: energy, alf + real(wp), intent(in) :: dyn_p + real(wp), intent(in) :: pi_inf, gamma, rho, qv + real(wp), intent(out) :: pres + real(wp), intent(inout) :: T real(stp), intent(in), optional :: stress, mom - real(wp), intent(in), optional :: G, pres_mag + real(wp), intent(in), optional :: G, pres_mag ! Chemistry real(wp), dimension(1:num_species), intent(in) :: rhoYks - real(wp), dimension(1:num_species) :: Y_rs - real(wp) :: E_e - real(wp) :: e_Per_Kg, Pdyn_Per_Kg - real(wp) :: T_guess - integer :: s !< Generic loop iterator + real(wp), dimension(1:num_species) :: Y_rs + real(wp) :: E_e + real(wp) :: e_Per_Kg, Pdyn_Per_Kg + real(wp) :: T_guess + + integer :: s !< Generic loop iterator + #:if not chemistry - ! Depending on model_eqns and bubbles_euler, the appropriate procedure for computing pressure is targeted by the - ! procedure pointer + ! Depending on model_eqns and bubbles_euler, the appropriate procedure + ! for computing pressure is targeted by the procedure pointer if (mhd) then - ! MHD pressure: subtract magnetic pressure from total energy pres = (energy - dyn_p - pi_inf - qv - pres_mag)/gamma - else if ((model_eqns /= 4) .and. (bubbles_euler .neqv. .true.)) then - ! Gamma/pi_inf model or five-equation model (Allaire et al. JCP 2002): p from mixture EOS + elseif ((model_eqns /= 4) .and. (bubbles_euler .neqv. .true.)) then pres = (energy - dyn_p - pi_inf - qv)/gamma else if ((model_eqns /= 4) .and. bubbles_euler) then - ! Bubble-augmented pressure with void fraction correction pres = ((energy - dyn_p)/(1._wp - alf) - pi_inf - qv)/gamma else - ! Four-equation model (Kapila et al. PoF 2001): Tait EOS inversion - pres = (pref + pi_inf)*(energy/(rhoref*(1 - alf)))**(1/gamma + 1) - pi_inf + pres = (pref + pi_inf)* & + (energy/ & + (rhoref*(1 - alf)) & + )**(1/gamma + 1) - pi_inf end if if (hypoelasticity .and. present(G)) then - ! Subtract elastic strain energy before computing pressure (hypoelastic model) + ! calculate elastic contribution to Energy E_e = 0._wp do s = stress_idx%beg, stress_idx%end if (G > 0) then @@ -128,10 +165,16 @@ contains end if end do - pres = (energy - 0.5_wp*(mom**2._wp)/rho - pi_inf - qv - E_e)/gamma + pres = ( & + energy - & + 0.5_wp*(mom**2._wp)/rho - & + pi_inf - qv - E_e & + )/gamma + end if + #:else - ! Reacting mixture pressure from temperature and species + Y_rs(:) = rhoYks(:)/rho e_Per_Kg = energy/rho Pdyn_Per_Kg = dyn_p/rho @@ -140,28 +183,41 @@ contains call get_temperature(e_Per_Kg - Pdyn_Per_Kg, T_guess, Y_rs, .true., T) call get_pressure(rho, T, Y_rs, pres) + #:endif end subroutine s_compute_pressure - !> Convert mixture variables to density, gamma, pi_inf, and qv for the gamma/pi_inf model. Given conservative or primitive - !! variables, transfers the density, specific heat ratio function and the liquid stiffness function from q_vf to rho, gamma and - !! pi_inf. - subroutine s_convert_mixture_to_mixture_variables(q_vf, i, j, k, rho, gamma, pi_inf, qv) + !> This subroutine is designed for the gamma/pi_inf model + !! and provided a set of either conservative or primitive + !! variables, transfers the density, specific heat ratio + !! function and the liquid stiffness function from q_vf to + !! rho, gamma and pi_inf. + !! @param q_vf conservative or primitive variables + !! @param i cell index to transfer mixture variables + !! @param j cell index to transfer mixture variables + !! @param k cell index to transfer mixture variables + !! @param rho density + !! @param gamma specific heat ratio function + !! @param pi_inf liquid stiffness + !! @param qv fluid reference energy + subroutine s_convert_mixture_to_mixture_variables(q_vf, i, j, k, & + rho, gamma, pi_inf, qv) type(scalar_field), dimension(sys_size), intent(in) :: q_vf - integer, intent(in) :: i, j, k - real(wp), intent(out), target :: rho - real(wp), intent(out), target :: gamma - real(wp), intent(out), target :: pi_inf - real(wp), intent(out), target :: qv + integer, intent(in) :: i, j, k - ! Transferring the density, the specific heat ratio function and the liquid stiffness function, respectively + real(wp), intent(out), target :: rho + real(wp), intent(out), target :: gamma + real(wp), intent(out), target :: pi_inf + real(wp), intent(out), target :: qv + ! Transferring the density, the specific heat ratio function and the + ! liquid stiffness function, respectively rho = q_vf(1)%sf(i, j, k) gamma = q_vf(gamma_idx)%sf(i, j, k) pi_inf = q_vf(pi_inf_idx)%sf(i, j, k) - qv = 0._wp ! keep this value nil for now. For future adjustment + qv = 0._wp ! keep this value nill for now. For future adjustment ! Post process requires rho_sf/gamma_sf/pi_inf_sf/qv_sf to also be updated #ifdef MFC_POST_PROCESS @@ -173,28 +229,48 @@ contains end subroutine s_convert_mixture_to_mixture_variables - !> Convert species volume fractions and partial densities to mixture density, gamma, pi_inf, and qv. Given conservative or - !! primitive variables, computes the density, the specific heat ratio function and the liquid stiffness function from q_vf and - !! stores the results into rho, gamma and pi_inf. - subroutine s_convert_species_to_mixture_variables(q_vf, k, l, r, rho, gamma, pi_inf, qv, Re_K, G_K, G) - - type(scalar_field), dimension(sys_size), intent(in) :: q_vf - integer, intent(in) :: k, l, r - real(wp), intent(out), target :: rho - real(wp), intent(out), target :: gamma - real(wp), intent(out), target :: pi_inf - real(wp), intent(out), target :: qv - real(wp), optional, dimension(2), intent(out) :: Re_K - real(wp), optional, intent(out) :: G_K - real(wp), dimension(num_fluids) :: alpha_rho_K, alpha_K + !> This subroutine is designed for the volume fraction model + !! and provided a set of either conservative or primitive + !! variables, computes the density, the specific heat ratio + !! function and the liquid stiffness function from q_vf and + !! stores the results into rho, gamma and pi_inf. + !! @param q_vf primitive variables + !! @param k Cell index + !! @param l Cell index + !! @param r Cell index + !! @param rho density + !! @param gamma specific heat ratio + !! @param pi_inf liquid stiffness + !! @param qv fluid reference energy + !! @param Re_K Reynolds number (optional) + !! @param G_K Shear modulus (optional) + !! @param G Shear moduli of the fluids (optional) + subroutine s_convert_species_to_mixture_variables(q_vf, k, l, r, rho, & + gamma, pi_inf, qv, Re_K, G_K, G) + + type(scalar_field), dimension(sys_size), intent(in) :: q_vf + + integer, intent(in) :: k, l, r + + real(wp), intent(out), target :: rho + real(wp), intent(out), target :: gamma + real(wp), intent(out), target :: pi_inf + real(wp), intent(out), target :: qv + + real(wp), optional, dimension(2), intent(out) :: Re_K + real(wp), optional, intent(out) :: G_K + real(wp), dimension(num_fluids) :: alpha_rho_K, alpha_K !< real(wp), optional, dimension(num_fluids), intent(in) :: G - integer :: i, j !< Generic loop iterator - ! Computing the density, the specific heat ratio function and the liquid stiffness function, respectively + integer :: i, j !< Generic loop iterator + + ! Computing the density, the specific heat ratio function and the + ! liquid stiffness function, respectively call s_compute_species_fraction(q_vf, k, l, r, alpha_rho_K, alpha_K) - ! Calculating the density, the specific heat ratio function, the liquid stiffness function, and the energy reference - ! function, respectively, from the species analogs + ! Calculating the density, the specific heat ratio function, the + ! liquid stiffness function, and the energy reference function, + ! respectively, from the species analogs if (num_fluids == 1 .and. bubbles_euler) then rho = alpha_rho_K(1) gamma = gammas(1) @@ -217,7 +293,8 @@ contains Re_K(i) = dflt_real; if (Re_size(i) > 0) Re_K(i) = 0._wp do j = 1, Re_size(i) - Re_K(i) = alpha_K(Re_idx(i, j))/fluid_pp(Re_idx(i, j))%Re(i) + Re_K(i) + Re_K(i) = alpha_K(Re_idx(i, j))/fluid_pp(Re_idx(i, j))%Re(i) & + + Re_K(i) end do Re_K(i) = 1._wp/max(Re_K(i), sgm_eps) @@ -243,25 +320,33 @@ contains end subroutine s_convert_species_to_mixture_variables - !> GPU-accelerated conversion of species volume fractions and partial densities to mixture density, gamma, pi_inf, and qv. - subroutine s_convert_species_to_mixture_variables_acc(rho_K, gamma_K, pi_inf_K, qv_K, alpha_K, alpha_rho_K, Re_K, G_K, G) - - $:GPU_ROUTINE(function_name='s_convert_species_to_mixture_variables_acc', parallelism='[seq]', cray_noinline=True) + !> @brief GPU-accelerated conversion of species volume fractions and partial densities to mixture density, gamma, pi_inf, and qv. + subroutine s_convert_species_to_mixture_variables_acc(rho_K, & + gamma_K, pi_inf_K, qv_K, & + alpha_K, alpha_rho_K, Re_K, & + G_K, G) + $:GPU_ROUTINE(function_name='s_convert_species_to_mixture_variables_acc', & + & parallelism='[seq]', cray_noinline=True) real(wp), intent(out) :: rho_K, gamma_K, pi_inf_K, qv_K #:if not MFC_CASE_OPTIMIZATION and USING_AMD - real(wp), dimension(3), intent(inout) :: alpha_rho_K, alpha_K + real(wp), dimension(3), intent(inout) :: alpha_rho_K, alpha_K !< real(wp), optional, dimension(3), intent(in) :: G #:else - real(wp), dimension(num_fluids), intent(inout) :: alpha_rho_K, alpha_K + real(wp), dimension(num_fluids), intent(inout) :: alpha_rho_K, alpha_K !< real(wp), optional, dimension(num_fluids), intent(in) :: G #:endif real(wp), dimension(2), intent(out) :: Re_K - real(wp), optional, intent(out) :: G_K - real(wp) :: alpha_K_sum - integer :: i, j !< Generic loop iterators + real(wp), optional, intent(out) :: G_K + real(wp) :: alpha_K_sum + + integer :: i, j !< Generic loop iterators + #ifdef MFC_SIMULATION - ! Constrain partial densities and volume fractions within physical bounds + ! Constraining the partial densities and the volume fractions within + ! their physical bounds to make sure that any mixture variables that + ! are derived from them result within the limits that are set by the + ! fluids physical parameters that make up the mixture if (num_fluids == 1 .and. bubbles_euler) then rho_K = alpha_rho_K(1) gamma_K = gammas(1) @@ -289,7 +374,8 @@ contains if (present(G_K)) then G_K = 0._wp do i = 1, num_fluids - ! TODO: change to use Gs_vc directly here? TODO: Make this change as well for GPUs + !TODO: change to use Gs_vc directly here? + !TODO: Make this changes as well for GPUs G_K = G_K + alpha_K(i)*G(i) end do G_K = max(0._wp, G_K) @@ -302,7 +388,8 @@ contains if (Re_size(i) > 0) Re_K(i) = 0._wp do j = 1, Re_size(i) - Re_K(i) = alpha_K(Re_idx(i, j))/Res_vc(i, j) + Re_K(i) + Re_K(i) = alpha_K(Re_idx(i, j))/Res_vc(i, j) & + + Re_K(i) end do Re_K(i) = 1._wp/max(Re_K(i), sgm_eps) @@ -312,12 +399,14 @@ contains end subroutine s_convert_species_to_mixture_variables_acc - !> Initialize the variables conversion module. + !> The computation of parameters, the allocation of memory, + !! the association of pointers and/or the execution of any + !! other procedures that are necessary to setup the module. impure subroutine s_initialize_variables_conversion_module integer :: i, j - $:GPU_ENTER_DATA(copyin='[is1b, is1e, is2b, is2e, is3b, is3e]') + $:GPU_ENTER_DATA(copyin='[is1b,is1e,is2b,is2e,is3b,is3e]') @:ALLOCATE(gammas (1:num_fluids)) @:ALLOCATE(gs_min (1:num_fluids)) @@ -338,9 +427,10 @@ contains qvs(i) = fluid_pp(i)%qv qvps(i) = fluid_pp(i)%qvp end do - $:GPU_UPDATE(device='[gammas, gs_min, pi_infs, ps_inf, cvs, qvs, qvps, Gs_vc]') + $:GPU_UPDATE(device='[gammas,gs_min,pi_infs,ps_inf,cvs,qvs,qvps,Gs_vc]') #ifdef MFC_SIMULATION + if (viscous) then @:ALLOCATE(Res_vc(1:2, 1:Re_size_max)) do i = 1, 2 @@ -349,7 +439,7 @@ contains end do end do - $:GPU_UPDATE(device='[Res_vc, Re_idx, Re_size]') + $:GPU_UPDATE(device='[Res_vc,Re_idx,Re_size]') end if #endif @@ -362,47 +452,80 @@ contains end if #ifdef MFC_POST_PROCESS - ! Allocating the density, the specific heat ratio function and the liquid stiffness function, respectively + ! Allocating the density, the specific heat ratio function and the + ! liquid stiffness function, respectively ! Simulation is at least 2D if (n > 0) then + ! Simulation is 3D if (p > 0) then - allocate (rho_sf(-buff_size:m + buff_size,-buff_size:n + buff_size,-buff_size:p + buff_size)) - allocate (gamma_sf(-buff_size:m + buff_size,-buff_size:n + buff_size,-buff_size:p + buff_size)) - allocate (pi_inf_sf(-buff_size:m + buff_size,-buff_size:n + buff_size,-buff_size:p + buff_size)) - allocate (qv_sf(-buff_size:m + buff_size,-buff_size:n + buff_size,-buff_size:p + buff_size)) + + allocate (rho_sf(-buff_size:m + buff_size, & + -buff_size:n + buff_size, & + -buff_size:p + buff_size)) + allocate (gamma_sf(-buff_size:m + buff_size, & + -buff_size:n + buff_size, & + -buff_size:p + buff_size)) + allocate (pi_inf_sf(-buff_size:m + buff_size, & + -buff_size:n + buff_size, & + -buff_size:p + buff_size)) + allocate (qv_sf(-buff_size:m + buff_size, & + -buff_size:n + buff_size, & + -buff_size:p + buff_size)) ! Simulation is 2D else - allocate (rho_sf(-buff_size:m + buff_size,-buff_size:n + buff_size,0:0)) - allocate (gamma_sf(-buff_size:m + buff_size,-buff_size:n + buff_size,0:0)) - allocate (pi_inf_sf(-buff_size:m + buff_size,-buff_size:n + buff_size,0:0)) - allocate (qv_sf(-buff_size:m + buff_size,-buff_size:n + buff_size,0:0)) + + allocate (rho_sf(-buff_size:m + buff_size, & + -buff_size:n + buff_size, & + 0:0)) + allocate (gamma_sf(-buff_size:m + buff_size, & + -buff_size:n + buff_size, & + 0:0)) + allocate (pi_inf_sf(-buff_size:m + buff_size, & + -buff_size:n + buff_size, & + 0:0)) + allocate (qv_sf(-buff_size:m + buff_size, & + -buff_size:n + buff_size, & + 0:0)) end if ! Simulation is 1D else - allocate (rho_sf(-buff_size:m + buff_size,0:0,0:0)) - allocate (gamma_sf(-buff_size:m + buff_size,0:0,0:0)) - allocate (pi_inf_sf(-buff_size:m + buff_size,0:0,0:0)) - allocate (qv_sf(-buff_size:m + buff_size,0:0,0:0)) + + allocate (rho_sf(-buff_size:m + buff_size, & + 0:0, & + 0:0)) + allocate (gamma_sf(-buff_size:m + buff_size, & + 0:0, & + 0:0)) + allocate (pi_inf_sf(-buff_size:m + buff_size, & + 0:0, & + 0:0)) + allocate (qv_sf(-buff_size:m + buff_size, & + 0:0, & + 0:0)) + end if #endif end subroutine s_initialize_variables_conversion_module - !> Initialize bubble mass-vapor values at quadrature nodes from the conserved moment statistics. + !> @brief Initializes bubble mass-vapor values at quadrature nodes from the conserved moment statistics. subroutine s_initialize_mv(qK_cons_vf, mv) - type(scalar_field), dimension(sys_size), intent(in) :: qK_cons_vf - real(stp), dimension(idwint(1)%beg:,idwint(2)%beg:,idwint(3)%beg:,1:,1:), intent(inout) :: mv - integer :: i, j, k, l - real(wp) :: mu, sig, nbub_sc + type(scalar_field), dimension(sys_size), intent(in) :: qK_cons_vf + + real(stp), dimension(idwint(1)%beg:, idwint(2)%beg:, idwint(3)%beg:, 1:, 1:), intent(inout) :: mv + + integer :: i, j, k, l + real(wp) :: mu, sig, nbub_sc do l = idwint(3)%beg, idwint(3)%end do k = idwint(2)%beg, idwint(2)%end do j = idwint(1)%beg, idwint(1)%end + nbub_sc = qK_cons_vf(bubxb)%sf(j, k, l) $:GPU_LOOP(parallelism='[seq]') @@ -415,24 +538,27 @@ contains mv(j, k, l, 3, i) = (mass_v0(i))*(mu + sig)**(3._wp)/(R0(i)**(3._wp)) mv(j, k, l, 4, i) = (mass_v0(i))*(mu + sig)**(3._wp)/(R0(i)**(3._wp)) end do + end do end do end do end subroutine s_initialize_mv - !> Initialize bubble internal pressures at quadrature nodes using isothermal relations from the Preston model. + !> @brief Initializes bubble internal pressures at quadrature nodes using isothermal relations from the Preston model. subroutine s_initialize_pb(qK_cons_vf, mv, pb) + type(scalar_field), dimension(sys_size), intent(in) :: qK_cons_vf + + real(stp), dimension(idwint(1)%beg:, idwint(2)%beg:, idwint(3)%beg:, 1:, 1:), intent(in) :: mv + real(stp), dimension(idwint(1)%beg:, idwint(2)%beg:, idwint(3)%beg:, 1:, 1:), intent(inout) :: pb - type(scalar_field), dimension(sys_size), intent(in) :: qK_cons_vf - real(stp), dimension(idwint(1)%beg:,idwint(2)%beg:,idwint(3)%beg:,1:,1:), intent(in) :: mv - real(stp), dimension(idwint(1)%beg:,idwint(2)%beg:,idwint(3)%beg:,1:,1:), intent(inout) :: pb - integer :: i, j, k, l - real(wp) :: mu, sig, nbub_sc + integer :: i, j, k, l + real(wp) :: mu, sig, nbub_sc do l = idwint(3)%beg, idwint(3)%end do k = idwint(2)%beg, idwint(2)%end do j = idwint(1)%beg, idwint(1)%end + nbub_sc = qK_cons_vf(bubxb)%sf(j, k, l) $:GPU_LOOP(parallelism='[seq]') @@ -440,15 +566,11 @@ contains mu = qK_cons_vf(bubxb + 1 + (i - 1)*nmom)%sf(j, k, l)/nbub_sc sig = (qK_cons_vf(bubxb + 3 + (i - 1)*nmom)%sf(j, k, l)/nbub_sc - mu**2)**0.5_wp - ! PRESTON (ISOTHERMAL) - pb(j, k, l, 1, i) = (pb0(i))*(R0(i)**(3._wp))*(mass_g0(i) + mv(j, k, l, 1, & - & i))/(mu - sig)**(3._wp)/(mass_g0(i) + mass_v0(i)) - pb(j, k, l, 2, i) = (pb0(i))*(R0(i)**(3._wp))*(mass_g0(i) + mv(j, k, l, 2, & - & i))/(mu - sig)**(3._wp)/(mass_g0(i) + mass_v0(i)) - pb(j, k, l, 3, i) = (pb0(i))*(R0(i)**(3._wp))*(mass_g0(i) + mv(j, k, l, 3, & - & i))/(mu + sig)**(3._wp)/(mass_g0(i) + mass_v0(i)) - pb(j, k, l, 4, i) = (pb0(i))*(R0(i)**(3._wp))*(mass_g0(i) + mv(j, k, l, 4, & - & i))/(mu + sig)**(3._wp)/(mass_g0(i) + mass_v0(i)) + !PRESTON (ISOTHERMAL) + pb(j, k, l, 1, i) = (pb0(i))*(R0(i)**(3._wp))*(mass_g0(i) + mv(j, k, l, 1, i))/(mu - sig)**(3._wp)/(mass_g0(i) + mass_v0(i)) + pb(j, k, l, 2, i) = (pb0(i))*(R0(i)**(3._wp))*(mass_g0(i) + mv(j, k, l, 2, i))/(mu - sig)**(3._wp)/(mass_g0(i) + mass_v0(i)) + pb(j, k, l, 3, i) = (pb0(i))*(R0(i)**(3._wp))*(mass_g0(i) + mv(j, k, l, 3, i))/(mu + sig)**(3._wp)/(mass_g0(i) + mass_v0(i)) + pb(j, k, l, 4, i) = (pb0(i))*(R0(i)**(3._wp))*(mass_g0(i) + mv(j, k, l, 4, i))/(mu + sig)**(3._wp)/(mass_g0(i) + mass_v0(i)) end do end do end do @@ -456,45 +578,55 @@ contains end subroutine s_initialize_pb - !> Convert conserved variables (rho*alpha, rho*u, E, alpha) to primitives (rho, u, p, alpha). Conversion depends on model_eqns: - !! each model has different variable sets and EOS. - subroutine s_convert_conservative_to_primitive_variables(qK_cons_vf, q_T_sf, qK_prim_vf, ibounds) - - type(scalar_field), dimension(sys_size), intent(in) :: qK_cons_vf - type(scalar_field), intent(inout) :: q_T_sf + !> The following procedure handles the conversion between + !! the conservative variables and the primitive variables. + !! @param qK_cons_vf Conservative variables + !! @param q_T_sf Temperature scalar field + !! @param qK_prim_vf Primitive variables + !! @param ibounds Index bounds in each coordinate direction + subroutine s_convert_conservative_to_primitive_variables(qK_cons_vf, & + q_T_sf, & + qK_prim_vf, & + ibounds) + + type(scalar_field), dimension(sys_size), intent(in) :: qK_cons_vf + type(scalar_field), intent(inout) :: q_T_sf type(scalar_field), dimension(sys_size), intent(inout) :: qK_prim_vf - type(int_bounds_info), dimension(1:3), intent(in) :: ibounds - + type(int_bounds_info), dimension(1:3), intent(in) :: ibounds #:if USING_AMD and not MFC_CASE_OPTIMIZATION real(wp), dimension(3) :: alpha_K, alpha_rho_K real(wp), dimension(3) :: nRtmp - real(wp) :: rhoYks(1:10) + real(wp) :: rhoYks(1:10) #:else real(wp), dimension(num_fluids) :: alpha_K, alpha_rho_K - real(wp), dimension(nb) :: nRtmp - real(wp) :: rhoYks(1:num_species) + real(wp), dimension(nb) :: nRtmp + real(wp) :: rhoYks(1:num_species) #:endif real(wp), dimension(2) :: Re_K - real(wp) :: rho_K, gamma_K, pi_inf_K, qv_K, dyn_pres_K - real(wp) :: vftmp, nbub_sc - real(wp) :: G_K - real(wp) :: pres - integer :: i, j, k, l !< Generic loop iterators - real(wp) :: T - real(wp) :: pres_mag - real(wp) :: Ga !< Lorentz factor (gamma in relativity) - real(wp) :: B2 !< Magnetic field magnitude squared - real(wp) :: B(3) !< Magnetic field components - real(wp) :: m2 !< Relativistic momentum magnitude squared - real(wp) :: S !< Dot product of the magnetic field and the relativistic momentum - real(wp) :: W, dW !< W := rho*v*Ga**2; f = f(W) in Newton-Raphson - real(wp) :: E, D !< Prim/Cons variables within Newton-Raphson iteration - real(wp) :: f, dGa_dW, dp_dW, df_dW !< Functions within Newton-Raphson iteration - integer :: iter !< Newton-Raphson iteration counter - - $:GPU_PARALLEL_LOOP(collapse=3, private='[alpha_K, alpha_rho_K, Re_K, nRtmp, rho_K, gamma_K, pi_inf_K, qv_K, dyn_pres_K, & - & rhoYks, B, pres, vftmp, nbub_sc, G_K, T, pres_mag, Ga, B2, m2, S, W, dW, E, D, f, dGa_dW, dp_dW, & - & df_dW, iter]') + real(wp) :: rho_K, gamma_K, pi_inf_K, qv_K, dyn_pres_K + + real(wp) :: vftmp, nbub_sc + + real(wp) :: G_K + + real(wp) :: pres + + integer :: i, j, k, l !< Generic loop iterators + + real(wp) :: T + real(wp) :: pres_mag + + real(wp) :: Ga ! Lorentz factor (gamma in relativity) + real(wp) :: B2 ! Magnetic field magnitude squared + real(wp) :: B(3) ! Magnetic field components + real(wp) :: m2 ! Relativistic momentum magnitude squared + real(wp) :: S ! Dot product of the magnetic field and the relativistic momentum + real(wp) :: W, dW ! W := rho*v*Ga**2; f = f(W) in Newton-Raphson + real(wp) :: E, D ! Prim/Cons variables within Newton-Raphson iteration + real(wp) :: f, dGa_dW, dp_dW, df_dW ! Functions within Newton-Raphson iteration + integer :: iter ! Newton-Raphson iteration counter + + $:GPU_PARALLEL_LOOP(collapse=3, private='[alpha_K, alpha_rho_K, Re_K, nRtmp, rho_K, gamma_K, pi_inf_K,qv_K, dyn_pres_K, rhoYks, B, pres, vftmp, nbub_sc, G_K, T, pres_mag, Ga, B2, m2, S, W, dW, E, D, f, dGa_dW, dp_dW, df_dW, iter ]') do l = ibounds(3)%beg, ibounds(3)%end do k = ibounds(2)%beg, ibounds(2)%end do j = ibounds(1)%beg, ibounds(1)%end @@ -506,24 +638,24 @@ contains #ifdef MFC_SIMULATION ! If in simulation, use acc mixture subroutines if (elasticity) then - call s_convert_species_to_mixture_variables_acc(rho_K, gamma_K, pi_inf_K, qv_K, alpha_K, alpha_rho_K, & - & Re_K, G_K, Gs_vc) + call s_convert_species_to_mixture_variables_acc(rho_K, gamma_K, pi_inf_K, qv_K, alpha_K, & + alpha_rho_K, Re_K, G_K, Gs_vc) else - call s_convert_species_to_mixture_variables_acc(rho_K, gamma_K, pi_inf_K, qv_K, alpha_K, alpha_rho_K, & - & Re_K) + call s_convert_species_to_mixture_variables_acc(rho_K, gamma_K, pi_inf_K, qv_K, & + alpha_K, alpha_rho_K, Re_K) end if #else ! If pre-processing, use non acc mixture subroutines if (elasticity) then - call s_convert_to_mixture_variables(qK_cons_vf, j, k, l, rho_K, gamma_K, pi_inf_K, qv_K, Re_K, G_K, & - & fluid_pp(:)%G) + call s_convert_to_mixture_variables(qK_cons_vf, j, k, l, & + rho_K, gamma_K, pi_inf_K, qv_K, Re_K, G_K, fluid_pp(:)%G) else - call s_convert_to_mixture_variables(qK_cons_vf, j, k, l, rho_K, gamma_K, pi_inf_K, qv_K) + call s_convert_to_mixture_variables(qK_cons_vf, j, k, l, & + rho_K, gamma_K, pi_inf_K, qv_K) end if #endif end if - ! Relativistic MHD primitive variable recovery, Mignone & Bodo A&A (2006) if (relativity) then if (n == 0) then B(1) = Bx0 @@ -560,24 +692,23 @@ contains W = E + D $:GPU_LOOP(parallelism='[seq]') do iter = 1, relativity_cons_to_prim_max_iter - ! Lorentz factor from total enthalpy and magnetic field Ga = (W + B2)*W/sqrt((W + B2)**2*W**2 - (m2*W**2 + S**2*(2*W + B2))) - ! Thermal pressure from EOS - pres = (W - D*Ga)/((gamma_K + 1)*Ga**2) + pres = (W - D*Ga)/((gamma_K + 1)*Ga**2) ! Thermal pressure from EOS f = W - pres + (1 - 1/(2*Ga**2))*B2 - S**2/(2*W**2) - E - D - ! The first equation below corrects a typo in (Mignone & Bodo, 2006) m2*W**2 -> 2*m2*W**2, which would - ! cancel with the 2* in other terms This corrected version is not used as the second equation - ! empirically converges faster. First equation is kept for further investigation. dGa_dW = -Ga**3 * ( - ! S**2*(3*W**2+3*W*B2+B2**2) + m2*W**2 ) / (W**3 * (W+B2)**3) ! first (corrected) - dGa_dW = -Ga**3*(2*S**2*(3*W**2 + 3*W*B2 + B2**2) + m2*W**2)/(2*W**3*(W + B2)**3) ! second (in paper) + ! The first equation below corrects a typo in (Mignone & Bodo, 2006) + ! m2*W**2 → 2*m2*W**2, which would cancel with the 2* in other terms + ! This corrected version is not used as the second equation empirically converges faster. + ! First equation is kept for further investigation. + ! dGa_dW = -Ga**3 * ( S**2*(3*W**2+3*W*B2+B2**2) + m2*W**2 ) / (W**3 * (W+B2)**3) ! first (corrected) + dGa_dW = -Ga**3*(2*S**2*(3*W**2 + 3*W*B2 + B2**2) + m2*W**2)/(2*W**3*(W + B2)**3) ! second (in paper) dp_dW = (Ga*(1 + D*dGa_dW) - 2*W*dGa_dW)/((gamma_K + 1)*Ga**3) df_dW = 1 - dp_dW + (B2/Ga**3)*dGa_dW + S**2/W**3 dW = -f/df_dW W = W + dW - if (abs(dW) < 1.e-12_wp*W) exit ! Relative convergence criterion + if (abs(dW) < 1.e-12_wp*W) exit end do ! Recalculate pressure using converged W @@ -589,18 +720,17 @@ contains do i = 1, 3 qK_prim_vf(momxb + i - 1)%sf(j, k, l) = (qK_cons_vf(momxb + i - 1)%sf(j, k, l) + (S/W)*B(i))/(W + B2) end do - qK_prim_vf(1)%sf(j, k, l) = D/Ga ! Hard-coded for single-component for now + qK_prim_vf(1)%sf(j, k, l) = D/Ga ! Hard-coded for single-component for now $:GPU_LOOP(parallelism='[seq]') do i = B_idx%beg, B_idx%end qK_prim_vf(i)%sf(j, k, l) = qK_cons_vf(i)%sf(j, k, l) end do - cycle ! skip all the non-relativistic conversions below + cycle ! skip all the non-relativistic conversions below end if if (chemistry) then - ! Reacting flow: recover density from species partial densities, compute mass fractions Y_k = rhoY_k / rho rho_K = 0._wp $:GPU_LOOP(parallelism='[seq]') do i = chemxb, chemxe @@ -617,7 +747,6 @@ contains qK_prim_vf(i)%sf(j, k, l) = max(0._wp, qK_cons_vf(i)%sf(j, k, l)/rho_K) end do else - ! Non-reacting: partial densities are directly primitive (alpha_i * rho_i) $:GPU_LOOP(parallelism='[seq]') do i = 1, contxe qK_prim_vf(i)%sf(j, k, l) = qK_cons_vf(i)%sf(j, k, l) @@ -628,15 +757,16 @@ contains rho_K = max(rho_K, sgm_eps) #endif - ! Recover velocity from momentum: u = rho*u / rho, and accumulate dynamic pressure 0.5*rho*|u|^2 $:GPU_LOOP(parallelism='[seq]') do i = momxb, momxe if (model_eqns /= 4) then - qK_prim_vf(i)%sf(j, k, l) = qK_cons_vf(i)%sf(j, k, l)/rho_K - dyn_pres_K = dyn_pres_K + 5.e-1_wp*qK_cons_vf(i)%sf(j, k, l)*qK_prim_vf(i)%sf(j, k, l) + qK_prim_vf(i)%sf(j, k, l) = qK_cons_vf(i)%sf(j, k, l) & + /rho_K + dyn_pres_K = dyn_pres_K + 5.e-1_wp*qK_cons_vf(i)%sf(j, k, l) & + *qK_prim_vf(i)%sf(j, k, l) else - ! Four-equation model (Kapila et al. PoF 2001): divide by total density q_cons(1) - qK_prim_vf(i)%sf(j, k, l) = qK_cons_vf(i)%sf(j, k, l)/qK_cons_vf(1)%sf(j, k, l) + qK_prim_vf(i)%sf(j, k, l) = qK_cons_vf(i)%sf(j, k, l) & + /qK_cons_vf(1)%sf(j, k, l) end if end do @@ -651,18 +781,18 @@ contains if (mhd) then if (n == 0) then - pres_mag = 0.5_wp*(Bx0**2 + qK_cons_vf(B_idx%beg)%sf(j, k, l)**2 + qK_cons_vf(B_idx%beg + 1)%sf(j, k, & - & l)**2) + pres_mag = 0.5_wp*(Bx0**2 + qK_cons_vf(B_idx%beg)%sf(j, k, l)**2 + qK_cons_vf(B_idx%beg + 1)%sf(j, k, l)**2) else - pres_mag = 0.5_wp*(qK_cons_vf(B_idx%beg)%sf(j, k, l)**2 + qK_cons_vf(B_idx%beg + 1)%sf(j, k, & - & l)**2 + qK_cons_vf(B_idx%beg + 2)%sf(j, k, l)**2) + pres_mag = 0.5_wp*(qK_cons_vf(B_idx%beg)%sf(j, k, l)**2 + qK_cons_vf(B_idx%beg + 1)%sf(j, k, l)**2 + qK_cons_vf(B_idx%beg + 2)%sf(j, k, l)**2) end if else pres_mag = 0._wp end if - call s_compute_pressure(qK_cons_vf(E_idx)%sf(j, k, l), qK_cons_vf(alf_idx)%sf(j, k, l), dyn_pres_K, pi_inf_K, & - & gamma_K, rho_K, qv_K, rhoYks, pres, T, pres_mag=pres_mag) + call s_compute_pressure(qK_cons_vf(E_idx)%sf(j, k, l), & + qK_cons_vf(alf_idx)%sf(j, k, l), & + dyn_pres_K, pi_inf_K, gamma_K, rho_K, & + qv_K, rhoYks, pres, T, pres_mag=pres_mag) qK_prim_vf(E_idx)%sf(j, k, l) = pres @@ -671,7 +801,6 @@ contains end if if (bubbles_euler) then - ! Recover bubble primitive variables: divide conserved moments by bubble number density $:GPU_LOOP(parallelism='[seq]') do i = 1, nb nRtmp(i) = qK_cons_vf(bubrs_vc(i))%sf(j, k, l) @@ -680,18 +809,19 @@ contains vftmp = qK_cons_vf(alf_idx)%sf(j, k, l) if (qbmm) then - ! Get nb (constant across all R0 bins) + !Get nb (constant across all R0 bins) nbub_sc = qK_cons_vf(bubxb)%sf(j, k, l) - ! Convert cons to prim + !Convert cons to prim $:GPU_LOOP(parallelism='[seq]') do i = bubxb, bubxe qK_prim_vf(i)%sf(j, k, l) = qK_cons_vf(i)%sf(j, k, l)/nbub_sc end do - ! Need to keep track of nb in the primitive variable list (converted back to true value before output) + !Need to keep track of nb in the primitive variable list (converted back to true value before output) #ifdef MFC_SIMULATION qK_prim_vf(bubxb)%sf(j, k, l) = qK_cons_vf(bubxb)%sf(j, k, l) #endif + else if (adv_n) then qK_prim_vf(n_idx)%sf(j, k, l) = qK_cons_vf(n_idx)%sf(j, k, l) @@ -727,12 +857,12 @@ contains do i = strxb, strxe ! subtracting elastic contribution for pressure calculation if (G_K > verysmall) then - qK_prim_vf(E_idx)%sf(j, k, l) = qK_prim_vf(E_idx)%sf(j, k, l) - ((qK_prim_vf(i)%sf(j, k, & - & l)**2._wp)/(4._wp*G_K))/gamma_K + qK_prim_vf(E_idx)%sf(j, k, l) = qK_prim_vf(E_idx)%sf(j, k, l) - & + ((qK_prim_vf(i)%sf(j, k, l)**2._wp)/(4._wp*G_K))/gamma_K ! Double for shear stresses if (any(i == shear_indices)) then - qK_prim_vf(E_idx)%sf(j, k, l) = qK_prim_vf(E_idx)%sf(j, k, l) - ((qK_prim_vf(i)%sf(j, k, & - & l)**2._wp)/(4._wp*G_K))/gamma_K + qK_prim_vf(E_idx)%sf(j, k, l) = qK_prim_vf(E_idx)%sf(j, k, l) - & + ((qK_prim_vf(i)%sf(j, k, l)**2._wp)/(4._wp*G_K))/gamma_K end if end if end do @@ -762,6 +892,7 @@ contains #ifdef MFC_POST_PROCESS if (bubbles_lagrange) qK_prim_vf(beta_idx)%sf(j, k, l) = qK_cons_vf(beta_idx)%sf(j, k, l) #endif + end do end do end do @@ -769,33 +900,41 @@ contains end subroutine s_convert_conservative_to_primitive_variables - !> Convert primitives (rho, u, p, alpha) to conserved variables (rho*alpha, rho*u, E, alpha). - impure subroutine s_convert_primitive_to_conservative_variables(q_prim_vf, q_cons_vf) + !> The following procedure handles the conversion between + !! the primitive variables and the conservative variables. + !! @param q_prim_vf Primitive variables + !! @param q_cons_vf Conservative variables + impure subroutine s_convert_primitive_to_conservative_variables(q_prim_vf, & + q_cons_vf) - type(scalar_field), dimension(sys_size), intent(in) :: q_prim_vf + type(scalar_field), dimension(sys_size), intent(in) :: q_prim_vf type(scalar_field), dimension(sys_size), intent(inout) :: q_cons_vf - ! Density, specific heat ratio function, liquid stiffness function and dynamic pressure, as defined in the incompressible - ! flow sense, respectively - real(wp) :: rho - real(wp) :: gamma - real(wp) :: pi_inf - real(wp) :: qv - real(wp) :: dyn_pres - real(wp) :: nbub, R3tmp - real(wp), dimension(nb) :: Rtmp - real(wp) :: G - real(wp), dimension(2) :: Re_K - integer :: i, j, k, l !< Generic loop iterators + ! Density, specific heat ratio function, liquid stiffness function + ! and dynamic pressure, as defined in the incompressible flow sense, + ! respectively + real(wp) :: rho + real(wp) :: gamma + real(wp) :: pi_inf + real(wp) :: qv + real(wp) :: dyn_pres + real(wp) :: nbub, R3tmp + real(wp), dimension(nb) :: Rtmp + real(wp) :: G + real(wp), dimension(2) :: Re_K + + integer :: i, j, k, l !< Generic loop iterators + real(wp), dimension(num_species) :: Ys - real(wp) :: e_mix, mix_mol_weight, T - real(wp) :: pres_mag - real(wp) :: Ga !< Lorentz factor (gamma in relativity) - real(wp) :: h !< relativistic enthalpy - real(wp) :: v2 !< Square of the velocity magnitude - real(wp) :: B2 !< Square of the magnetic field magnitude - real(wp) :: vdotB !< Dot product of the velocity and magnetic field vectors - real(wp) :: B(3) !< Magnetic field components + real(wp) :: e_mix, mix_mol_weight, T + real(wp) :: pres_mag + + real(wp) :: Ga ! Lorentz factor (gamma in relativity) + real(wp) :: h ! relativistic enthalpy + real(wp) :: v2 ! Square of the velocity magnitude + real(wp) :: B2 ! Square of the magnetic field magnitude + real(wp) :: vdotB ! Dot product of the velocity and magnetic field vectors + real(wp) :: B(3) ! Magnetic field components pres_mag = 0._wp @@ -806,8 +945,11 @@ contains do l = 0, p do k = 0, n do j = 0, m - ! Obtaining the density, specific heat ratio function and the liquid stiffness function, respectively - call s_convert_to_mixture_variables(q_prim_vf, j, k, l, rho, gamma, pi_inf, qv, Re_K, G, fluid_pp(:)%G) + + ! Obtaining the density, specific heat ratio function + ! and the liquid stiffness function, respectively + call s_convert_to_mixture_variables(q_prim_vf, j, k, l, & + rho, gamma, pi_inf, qv, Re_K, G, fluid_pp(:)%G) if (.not. igr .or. num_fluids > 1) then ! Transferring the advection equation(s) variable(s) @@ -817,6 +959,7 @@ contains end if if (relativity) then + if (n == 0) then B(1) = Bx0 B(2) = q_prim_vf(B_idx%beg)%sf(j, k, l) @@ -835,7 +978,7 @@ contains Ga = 1._wp/sqrt(1._wp - v2) - h = 1._wp + (gamma + 1)*q_prim_vf(E_idx)%sf(j, k, l)/rho ! Assume perfect gas for now + h = 1._wp + (gamma + 1)*q_prim_vf(E_idx)%sf(j, k, l)/rho ! Assume perfect gas for now B2 = 0._wp do i = B_idx%beg, B_idx%end @@ -853,10 +996,12 @@ contains end do do i = momxb, momxe - q_cons_vf(i)%sf(j, k, l) = (rho*h*Ga**2 + B2)*q_prim_vf(i)%sf(j, k, l) - vdotB*B(i - momxb + 1) + q_cons_vf(i)%sf(j, k, l) = (rho*h*Ga**2 + B2)*q_prim_vf(i)%sf(j, k, l) & + - vdotB*B(i - momxb + 1) end do - q_cons_vf(E_idx)%sf(j, k, l) = rho*h*Ga**2 - q_prim_vf(E_idx)%sf(j, k, l) + 0.5_wp*(B2 + v2*B2 - vdotB**2) + q_cons_vf(E_idx)%sf(j, k, l) = rho*h*Ga**2 - q_prim_vf(E_idx)%sf(j, k, l) & + + 0.5_wp*(B2 + v2*B2 - vdotB**2) ! Remove rest energy do i = 1, contxe q_cons_vf(E_idx)%sf(j, k, l) = q_cons_vf(E_idx)%sf(j, k, l) - q_cons_vf(i)%sf(j, k, l) @@ -866,7 +1011,8 @@ contains q_cons_vf(i)%sf(j, k, l) = q_prim_vf(i)%sf(j, k, l) end do - cycle ! skip all the non-relativistic conversions below + cycle ! skip all the non-relativistic conversions below + end if ! Transferring the continuity equation(s) variable(s) @@ -874,17 +1020,18 @@ contains q_cons_vf(i)%sf(j, k, l) = q_prim_vf(i)%sf(j, k, l) end do - ! Zeroing out the dynamic pressure since it is computed iteratively by cycling through the velocity equations + ! Zeroing out the dynamic pressure since it is computed + ! iteratively by cycling through the velocity equations dyn_pres = 0._wp ! Computing momenta and dynamic pressure from velocity do i = momxb, momxe q_cons_vf(i)%sf(j, k, l) = rho*q_prim_vf(i)%sf(j, k, l) - dyn_pres = dyn_pres + q_cons_vf(i)%sf(j, k, l)*q_prim_vf(i)%sf(j, k, l)/2._wp + dyn_pres = dyn_pres + q_cons_vf(i)%sf(j, k, l)* & + q_prim_vf(i)%sf(j, k, l)/2._wp end do if (chemistry) then - ! Reacting mixture: compute conserved energy from species mass fractions and temperature do i = chemxb, chemxe Ys(i - chemxb + 1) = q_prim_vf(i)%sf(j, k, l) q_cons_vf(i)%sf(j, k, l) = rho*q_prim_vf(i)%sf(j, k, l) @@ -894,38 +1041,41 @@ contains T = q_prim_vf(E_idx)%sf(j, k, l)*mix_mol_weight/(gas_constant*rho) call get_mixture_energy_mass(T, Ys, e_mix) - q_cons_vf(E_idx)%sf(j, k, l) = dyn_pres + rho*e_mix + q_cons_vf(E_idx)%sf(j, k, l) = & + dyn_pres + rho*e_mix else ! Computing the energy from the pressure if (mhd) then if (n == 0) then - pres_mag = 0.5_wp*(Bx0**2 + q_prim_vf(B_idx%beg)%sf(j, k, l)**2 + q_prim_vf(B_idx%beg + 1)%sf(j, & - & k, l)**2) + pres_mag = 0.5_wp*(Bx0**2 + q_prim_vf(B_idx%beg)%sf(j, k, l)**2 + q_prim_vf(B_idx%beg + 1)%sf(j, k, l)**2) else - pres_mag = 0.5_wp*(q_prim_vf(B_idx%beg)%sf(j, k, l)**2 + q_prim_vf(B_idx%beg + 1)%sf(j, k, & - & l)**2 + q_prim_vf(B_idx%beg + 2)%sf(j, k, l)**2) + pres_mag = 0.5_wp*(q_prim_vf(B_idx%beg)%sf(j, k, l)**2 + q_prim_vf(B_idx%beg + 1)%sf(j, k, l)**2 + q_prim_vf(B_idx%beg + 2)%sf(j, k, l)**2) end if - ! MHD energy includes magnetic pressure contribution - q_cons_vf(E_idx)%sf(j, k, l) = gamma*q_prim_vf(E_idx)%sf(j, k, l) + dyn_pres + pres_mag + pi_inf + qv - else if ((model_eqns /= 4) .and. (bubbles_euler .neqv. .true.)) then - ! Five-equation model (Allaire et al. JCP 2002): E = Gamma*p + 0.5*rho*|u|^2 + pi_inf + qv - q_cons_vf(E_idx)%sf(j, k, l) = gamma*q_prim_vf(E_idx)%sf(j, k, l) + dyn_pres + pi_inf + qv + q_cons_vf(E_idx)%sf(j, k, l) = & + gamma*q_prim_vf(E_idx)%sf(j, k, l) + dyn_pres + pres_mag & + + pi_inf + qv + elseif ((model_eqns /= 4) .and. (bubbles_euler .neqv. .true.)) then + ! E = Gamma*P + \rho u u /2 + \pi_inf + (\alpha\rho qv) + q_cons_vf(E_idx)%sf(j, k, l) = & + gamma*q_prim_vf(E_idx)%sf(j, k, l) + dyn_pres + pi_inf + qv else if ((model_eqns /= 4) .and. (bubbles_euler)) then - ! Bubble-augmented energy with void fraction correction - q_cons_vf(E_idx)%sf(j, k, l) = dyn_pres + (1._wp - q_prim_vf(alf_idx)%sf(j, k, & - & l))*(gamma*q_prim_vf(E_idx)%sf(j, k, l) + pi_inf) + ! \tilde{E} = dyn_pres + (1-\alf)(\Gamma p_l + \Pi_inf) + q_cons_vf(E_idx)%sf(j, k, l) = dyn_pres + & + (1._wp - q_prim_vf(alf_idx)%sf(j, k, l))* & + (gamma*q_prim_vf(E_idx)%sf(j, k, l) + pi_inf) else - ! Four-equation model (Kapila et al. PoF 2001): Tait EOS, no conserved energy variable + !Tait EOS, no conserved energy variable q_cons_vf(E_idx)%sf(j, k, l) = 0._wp end if end if - ! Six-equation model (Saurel et al. JCP 2009): compute per-phase internal energies + ! Computing the internal energies from the pressure and continuities if (model_eqns == 3) then do i = 1, num_fluids - q_cons_vf(i + intxb - 1)%sf(j, k, l) = q_cons_vf(i + advxb - 1)%sf(j, k, & - & l)*(gammas(i)*q_prim_vf(E_idx)%sf(j, k, & - & l) + pi_infs(i)) + q_cons_vf(i + contxb - 1)%sf(j, k, l)*qvs(i) + ! internal energy calculation for each of the fluids + q_cons_vf(i + intxb - 1)%sf(j, k, l) = q_cons_vf(i + advxb - 1)%sf(j, k, l)* & + (gammas(i)*q_prim_vf(E_idx)%sf(j, k, l) + pi_infs(i)) + & + q_cons_vf(i + contxb - 1)%sf(j, k, l)*qvs(i) end do end if @@ -943,13 +1093,13 @@ contains call s_comp_n_from_prim(real(q_prim_vf(alf_idx)%sf(j, k, l), kind=wp), Rtmp, nbub, weight) end if else - ! Initialize R3 averaging over R0 and R directions + !Initialize R3 averaging over R0 and R directions R3tmp = 0._wp do i = 1, nb R3tmp = R3tmp + weight(i)*0.5_wp*(Rtmp(i) + sigR)**3._wp R3tmp = R3tmp + weight(i)*0.5_wp*(Rtmp(i) - sigR)**3._wp end do - ! Initialize nb + !Initialize nb nbub = 3._wp*q_prim_vf(alf_idx)%sf(j, k, l)/(4._wp*pi*R3tmp) end if @@ -965,7 +1115,8 @@ contains end if if (elasticity) then - ! adding the elastic contribution Multiply \tau to \rho \tau + ! adding the elastic contribution + ! Multiply \tau to \rho \tau do i = strxb, strxe q_cons_vf(i)%sf(j, k, l) = rho*q_prim_vf(i)%sf(j, k, l) end do @@ -976,12 +1127,12 @@ contains do i = strxb, strxe ! adding elastic contribution if (G > verysmall) then - q_cons_vf(E_idx)%sf(j, k, l) = q_cons_vf(E_idx)%sf(j, k, l) + (q_prim_vf(i)%sf(j, k, & - & l)**2._wp)/(4._wp*G) + q_cons_vf(E_idx)%sf(j, k, l) = q_cons_vf(E_idx)%sf(j, k, l) + & + (q_prim_vf(i)%sf(j, k, l)**2._wp)/(4._wp*G) ! Double for shear stresses if (any(i == shear_indices)) then - q_cons_vf(E_idx)%sf(j, k, l) = q_cons_vf(E_idx)%sf(j, k, l) + (q_prim_vf(i)%sf(j, k, & - & l)**2._wp)/(4._wp*G) + q_cons_vf(E_idx)%sf(j, k, l) = q_cons_vf(E_idx)%sf(j, k, l) + & + (q_prim_vf(i)%sf(j, k, l)**2._wp)/(4._wp*G) end if end if end do @@ -1002,66 +1153,82 @@ contains if (cont_damage) q_cons_vf(damage_idx)%sf(j, k, l) = q_prim_vf(damage_idx)%sf(j, k, l) if (hyper_cleaning) q_cons_vf(psi_idx)%sf(j, k, l) = q_prim_vf(psi_idx)%sf(j, k, l) + end do end do end do #else if (proc_rank == 0) then - call s_mpi_abort('Conversion from primitive to ' // 'conservative variables not ' // 'implemented. Exiting.') + call s_mpi_abort('Conversion from primitive to '// & + 'conservative variables not '// & + 'implemented. Exiting.') end if #endif - end subroutine s_convert_primitive_to_conservative_variables - !> Convert primitive variables to Eulerian flux variables. - subroutine s_convert_primitive_to_flux_variables(qK_prim_vf, FK_vf, FK_src_vf, is1, is2, is3, s2b, s3b) - - integer, intent(in) :: s2b, s3b - real(wp), dimension(0:,idwbuff(2)%beg:,idwbuff(3)%beg:,1:), intent(in) :: qK_prim_vf - real(wp), dimension(0:,idwbuff(2)%beg:,idwbuff(3)%beg:,1:), intent(inout) :: FK_vf - real(wp), dimension(0:,idwbuff(2)%beg:,idwbuff(3)%beg:,advxb:), intent(inout) :: FK_src_vf - type(int_bounds_info), intent(in) :: is1, is2, is3 - - ! Partial densities, density, velocity, pressure, energy, advection variables, the specific heat ratio and liquid stiffness - ! functions, the shear and volume Reynolds numbers and the Weber numbers - + !> The following subroutine handles the conversion between + !! the primitive variables and the Eulerian flux variables. + !! @param qK_prim_vf Primitive variables + !! @param FK_vf Flux variables + !! @param FK_src_vf Flux source variables + !! @param is1 Index bounds in the first coordinate direction + !! @param is2 Index bounds in the second coordinate direction + !! @param is3 Index bounds in the third coordinate direction + !! @param s2b Starting boundary index in the second coordinate direction + !! @param s3b Starting boundary index in the third coordinate direction + subroutine s_convert_primitive_to_flux_variables(qK_prim_vf, & + FK_vf, & + FK_src_vf, & + is1, is2, is3, s2b, s3b) + + integer, intent(in) :: s2b, s3b + real(wp), dimension(0:, idwbuff(2)%beg:, idwbuff(3)%beg:, 1:), intent(in) :: qK_prim_vf + real(wp), dimension(0:, idwbuff(2)%beg:, idwbuff(3)%beg:, 1:), intent(inout) :: FK_vf + real(wp), dimension(0:, idwbuff(2)%beg:, idwbuff(3)%beg:, advxb:), intent(inout) :: FK_src_vf + + type(int_bounds_info), intent(in) :: is1, is2, is3 + + ! Partial densities, density, velocity, pressure, energy, advection + ! variables, the specific heat ratio and liquid stiffness functions, + ! the shear and volume Reynolds numbers and the Weber numbers #:if not MFC_CASE_OPTIMIZATION and USING_AMD - real(wp), dimension(3) :: alpha_rho_K - real(wp), dimension(3) :: alpha_K - real(wp), dimension(3) :: vel_K + real(wp), dimension(3) :: alpha_rho_K + real(wp), dimension(3) :: alpha_K + real(wp), dimension(3) :: vel_K real(wp), dimension(10) :: Y_K #:else - real(wp), dimension(num_fluids) :: alpha_rho_K - real(wp), dimension(num_fluids) :: alpha_K - real(wp), dimension(num_vels) :: vel_K + real(wp), dimension(num_fluids) :: alpha_rho_K + real(wp), dimension(num_fluids) :: alpha_K + real(wp), dimension(num_vels) :: vel_K real(wp), dimension(num_species) :: Y_K #:endif - real(wp) :: rho_K - real(wp) :: vel_K_sum - real(wp) :: pres_K - real(wp) :: E_K - real(wp) :: gamma_K - real(wp) :: pi_inf_K - real(wp) :: qv_K + real(wp) :: rho_K + real(wp) :: vel_K_sum + real(wp) :: pres_K + real(wp) :: E_K + real(wp) :: gamma_K + real(wp) :: pi_inf_K + real(wp) :: qv_K real(wp), dimension(2) :: Re_K - real(wp) :: G_K - real(wp) :: T_K, mix_mol_weight, R_gas - integer :: i, j, k, l !< Generic loop iterators + real(wp) :: G_K + real(wp) :: T_K, mix_mol_weight, R_gas + + integer :: i, j, k, l !< Generic loop iterators is1b = is1%beg; is1e = is1%end is2b = is2%beg; is2e = is2%end is3b = is3%beg; is3e = is3%end - $:GPU_UPDATE(device='[is1b, is2b, is3b, is1e, is2e, is3e]') + $:GPU_UPDATE(device='[is1b,is2b,is3b,is1e,is2e,is3e]') - ! Computing the flux variables from the primitive variables, without accounting for the contribution of either viscosity or - ! capillarity + ! Computing the flux variables from the primitive variables, without + ! accounting for the contribution of either viscosity or capillarity #ifdef MFC_SIMULATION - $:GPU_PARALLEL_LOOP(collapse=3, private='[alpha_rho_K, vel_K, alpha_K, Re_K, Y_K, rho_K, vel_K_sum, pres_K, E_K, gamma_K, & - & pi_inf_K, qv_K, G_K, T_K, mix_mol_weight, R_gas]') + $:GPU_PARALLEL_LOOP(collapse=3, private='[alpha_rho_K, vel_K, alpha_K, Re_K, Y_K, rho_K, vel_K_sum, pres_K, E_K, gamma_K, pi_inf_K, qv_K, G_K, T_K, mix_mol_weight, R_gas]') do l = is3b, is3e do k = is2b, is2e do j = is1b, is1e + $:GPU_LOOP(parallelism='[seq]') do i = 1, contxe alpha_rho_K(i) = qK_prim_vf(j, k, l, i) @@ -1085,10 +1252,12 @@ contains pres_K = qK_prim_vf(j, k, l, E_idx) if (elasticity) then - call s_convert_species_to_mixture_variables_acc(rho_K, gamma_K, pi_inf_K, qv_K, alpha_K, alpha_rho_K, & - & Re_K, G_K, Gs_vc) + call s_convert_species_to_mixture_variables_acc(rho_K, gamma_K, pi_inf_K, qv_K, & + alpha_K, alpha_rho_K, Re_K, & + G_K, Gs_vc) else - call s_convert_species_to_mixture_variables_acc(rho_K, gamma_K, pi_inf_K, qv_K, alpha_K, alpha_rho_K, Re_K) + call s_convert_species_to_mixture_variables_acc(rho_K, gamma_K, pi_inf_K, qv_K, & + alpha_K, alpha_rho_K, Re_K) end if ! Computing the energy from the pressure @@ -1098,7 +1267,7 @@ contains do i = chemxb, chemxe Y_K(i - chemxb + 1) = qK_prim_vf(j, k, l, i) end do - ! Computing the energy from the internal energy of the mixture + !Computing the energy from the internal energy of the mixture call get_mixture_molecular_weight(Y_k, mix_mol_weight) R_gas = gas_constant/mix_mol_weight T_K = pres_K/rho_K/R_gas @@ -1106,7 +1275,8 @@ contains E_K = rho_K*E_K + 5.e-1_wp*rho_K*vel_K_sum else ! Computing the energy from the pressure - E_K = gamma_K*pres_K + pi_inf_K + 5.e-1_wp*rho_K*vel_K_sum + qv_K + E_K = gamma_K*pres_K + pi_inf_K & + + 5.e-1_wp*rho_K*vel_K_sum + qv_K end if ! mass flux, this should be \alpha_i \rho_i u_i @@ -1117,7 +1287,10 @@ contains $:GPU_LOOP(parallelism='[seq]') do i = 1, num_vels - FK_vf(j, k, l, contxe + dir_idx(i)) = rho_K*vel_K(dir_idx(1))*vel_K(dir_idx(i)) + pres_K*dir_flg(dir_idx(i)) + FK_vf(j, k, l, contxe + dir_idx(i)) = & + rho_K*vel_K(dir_idx(1)) & + *vel_K(dir_idx(i)) & + + pres_K*dir_flg(dir_idx(i)) end do ! energy flux, u(E+p) @@ -1137,6 +1310,7 @@ contains FK_vf(j, k, l, i) = 0._wp FK_src_vf(j, k, l, i) = alpha_K(i - E_idx) end do + else ! Could be bubbles_euler! $:GPU_LOOP(parallelism='[seq]') @@ -1148,27 +1322,28 @@ contains do i = advxb, advxe FK_src_vf(j, k, l, i) = vel_K(dir_idx(1)) end do + end if + end do end do end do $:END_GPU_PARALLEL_LOOP() #endif - end subroutine s_convert_primitive_to_flux_variables - !> Compute partial densities and volume fractions + !> This subroutine computes partial densities and volume fractions subroutine s_compute_species_fraction(q_vf, k, l, r, alpha_rho_K, alpha_K) - - $:GPU_ROUTINE(function_name='s_compute_species_fraction', parallelism='[seq]', cray_noinline=True) + $:GPU_ROUTINE(function_name='s_compute_species_fraction', & + & parallelism='[seq]', cray_noinline=True) type(scalar_field), dimension(sys_size), intent(in) :: q_vf - integer, intent(in) :: k, l, r + integer, intent(in) :: k, l, r #:if not MFC_CASE_OPTIMIZATION and USING_AMD real(wp), dimension(3), intent(out) :: alpha_rho_K, alpha_K #:else real(wp), dimension(num_fluids), intent(out) :: alpha_rho_K, alpha_K #:endif - integer :: i + integer :: i real(wp) :: alpha_K_sum if (num_fluids == 1) then @@ -1208,10 +1383,11 @@ contains end subroutine s_compute_species_fraction - !> Deallocate fluid property arrays and post-processing fields allocated during module initialization. + !> @brief Deallocates fluid property arrays and post-processing fields allocated during module initialization. impure subroutine s_finalize_variables_conversion_module() - ! Deallocating the density, the specific heat ratio function and the liquid stiffness function + ! Deallocating the density, the specific heat ratio function and the + ! liquid stiffness function #ifdef MFC_POST_PROCESS deallocate (rho_sf, gamma_sf, pi_inf_sf, qv_sf) #endif @@ -1231,9 +1407,8 @@ contains end subroutine s_finalize_variables_conversion_module #ifndef MFC_PRE_PROCESS - !> Compute the speed of sound from thermodynamic state variables, supporting multiple equation-of-state models. + !> @brief Computes the speed of sound from thermodynamic state variables, supporting multiple equation-of-state models. subroutine s_compute_speed_of_sound(pres, rho, gamma, pi_inf, H, adv, vel_sum, c_c, c, qv) - $:GPU_ROUTINE(parallelism='[seq]') real(wp), intent(in) :: pres @@ -1244,39 +1419,49 @@ contains #:else real(wp), dimension(num_fluids), intent(in) :: adv #:endif - real(wp), intent(in) :: vel_sum - real(wp), intent(in) :: c_c + real(wp), intent(in) :: vel_sum + real(wp), intent(in) :: c_c real(wp), intent(out) :: c - real(wp) :: blkmod1, blkmod2 - integer :: q - if (chemistry) then ! Reacting mixture sound speed + real(wp) :: blkmod1, blkmod2 + + integer :: q + + if (chemistry) then if (avg_state == 1 .and. abs(c_c) > verysmall) then c = sqrt(c_c - (gamma - 1.0_wp)*(vel_sum - H)) else c = sqrt((1.0_wp + 1.0_wp/gamma)*pres/rho) end if - else if (relativity) then ! Relativistic sound speed + elseif (relativity) then + ! Only supports perfect gas for now c = sqrt((1._wp + 1._wp/gamma)*pres/rho/H) else - if (alt_soundspeed) then ! Wood's mixture sound speed via bulk moduli - blkmod1 = ((gammas(1) + 1._wp)*pres + pi_infs(1))/gammas(1) - blkmod2 = ((gammas(2) + 1._wp)*pres + pi_infs(2))/gammas(2) + if (alt_soundspeed) then + blkmod1 = ((gammas(1) + 1._wp)*pres + & + pi_infs(1))/gammas(1) + blkmod2 = ((gammas(2) + 1._wp)*pres + & + pi_infs(2))/gammas(2) c = (1._wp/(rho*(adv(1)/blkmod1 + adv(2)/blkmod2))) - else if (model_eqns == 3) then ! Six-equation model sound speed + elseif (model_eqns == 3) then c = 0._wp $:GPU_LOOP(parallelism='[seq]') do q = 1, num_fluids - c = c + adv(q)*gs_min(q)*(pres + pi_infs(q)/(gammas(q) + 1._wp)) + c = c + adv(q)*gs_min(q)* & + (pres + pi_infs(q)/(gammas(q) + 1._wp)) end do c = c/rho - else if (((model_eqns == 4) .or. (model_eqns == 2 .and. bubbles_euler))) then + elseif (((model_eqns == 4) .or. (model_eqns == 2 .and. bubbles_euler))) then ! Sound speed for bubble mixture to order O(\alpha) if (mpp_lim .and. (num_fluids > 1)) then - c = (1._wp/gamma + 1._wp)*(pres + pi_inf/(gamma + 1._wp))/rho + c = (1._wp/gamma + 1._wp)* & + (pres + pi_inf/(gamma + 1._wp))/rho else - c = (1._wp/gamma + 1._wp)*(pres + pi_inf/(gamma + 1._wp))/(rho*(1._wp - adv(num_fluids))) + c = & + (1._wp/gamma + 1._wp)* & + (pres + pi_inf/(gamma + 1._wp))/ & + (rho*(1._wp - adv(num_fluids))) end if else c = (H - 5.e-1*vel_sum - qv/rho)/gamma @@ -1288,21 +1473,21 @@ contains c = sqrt(c) end if end if - end subroutine s_compute_speed_of_sound #endif #ifndef MFC_PRE_PROCESS - !> Compute the fast magnetosonic wave speed from the sound speed, density, and magnetic field components. + !> @brief Computes the fast magnetosonic wave speed from the sound speed, density, and magnetic field components. subroutine s_compute_fast_magnetosonic_speed(rho, c, B, norm, c_fast, h) + $:GPU_ROUTINE(function_name='s_compute_fast_magnetosonic_speed', & + & parallelism='[seq]', cray_noinline=True) - $:GPU_ROUTINE(function_name='s_compute_fast_magnetosonic_speed', parallelism='[seq]', cray_noinline=True) - - real(wp), intent(in) :: B(3), rho, c - real(wp), intent(in) :: h !< only used for relativity + real(wp), intent(in) :: B(3), rho, c + real(wp), intent(in) :: h ! only used for relativity real(wp), intent(out) :: c_fast - integer, intent(in) :: norm - real(wp) :: B2, term, disc + integer, intent(in) :: norm + + real(wp) :: B2, term, disc B2 = sum(B**2) @@ -1326,4 +1511,5 @@ contains end subroutine s_compute_fast_magnetosonic_speed #endif + end module m_variables_conversion diff --git a/src/post_process/m_checker.fpp b/src/post_process/m_checker.fpp index c46bc8fd0b..13587887a8 100644 --- a/src/post_process/m_checker.fpp +++ b/src/post_process/m_checker.fpp @@ -7,9 +7,12 @@ !> @brief Validates post-process input parameters and output format consistency module m_checker - use m_global_parameters - use m_mpi_proxy - use m_helper_basic + use m_global_parameters !< Definitions of the global parameters + + use m_mpi_proxy !< Message passing interface (MPI) module proxy + + use m_helper_basic !< Functions to compare floating point numbers + use m_helper implicit none @@ -18,14 +21,13 @@ module m_checker contains - !> Checks compatibility of parameters in the input file. Used by the post_process stage + !> Checks compatibility of parameters in the input file. + !! Used by the post_process stage impure subroutine s_check_inputs - end subroutine s_check_inputs !> Checks constraints on fft_wrt impure subroutine s_check_inputs_fft - integer :: num_procs_y, num_procs_z @:PROHIBIT(fft_wrt .and. MOD(n_glb+1,n+1) /= 0, "FFT WRT requires n_glb to be divisible by num_procs_y") @@ -34,7 +36,6 @@ contains num_procs_z = (p_glb + 1)/(p + 1) @:PROHIBIT(fft_wrt .and. MOD(m_glb+1,num_procs_y) /= 0, "FFT WRT requires m_glb to be divisible by num_procs_y") @:PROHIBIT(fft_wrt .and. MOD(n_glb+1,num_procs_z) /= 0, "FFT WRT requires n_glb to be divisible by num_procs_z") - end subroutine s_check_inputs_fft end module m_checker diff --git a/src/post_process/m_data_input.f90 b/src/post_process/m_data_input.f90 index 3a75c391f2..be1bdcb2d2 100644 --- a/src/post_process/m_data_input.f90 +++ b/src/post_process/m_data_input.f90 @@ -6,25 +6,35 @@ module m_data_input #ifdef MFC_MPI - use mpi + use mpi !< Message passing interface (MPI) module #endif - use m_derived_types - use m_global_parameters - use m_mpi_proxy + use m_derived_types !< Definitions of the derived types + + use m_global_parameters !< Global parameters for the code + + use m_mpi_proxy !< Message passing interface (MPI) module proxy + use m_mpi_common + use m_compile_specific + use m_boundary_common + use m_helper implicit none - private; public :: s_initialize_data_input_module, s_read_data_files, s_read_serial_data_files, s_read_parallel_data_files, & - & s_finalize_data_input_module + private; public :: s_initialize_data_input_module, & + s_read_data_files, & + s_read_serial_data_files, & + s_read_parallel_data_files, & + s_finalize_data_input_module abstract interface !> Subroutine for reading data files + !! @param t_step Current time-step to input impure subroutine s_read_abstract_data_files(t_step) implicit none @@ -32,13 +42,23 @@ impure subroutine s_read_abstract_data_files(t_step) integer, intent(in) :: t_step end subroutine s_read_abstract_data_files + end interface - type(scalar_field), allocatable, dimension(:), public :: q_cons_vf !< Conservative variables - type(scalar_field), allocatable, dimension(:), public :: q_cons_temp - type(scalar_field), allocatable, dimension(:), public :: q_prim_vf !< Primitive variables - type(integer_field), allocatable, dimension(:,:), public :: bc_type !< Boundary condition identifiers - type(scalar_field), public :: q_T_sf !< Temperature field + type(scalar_field), allocatable, dimension(:), public :: q_cons_vf !< + !! Conservative variables + + type(scalar_field), allocatable, dimension(:), public :: q_cons_temp + + type(scalar_field), allocatable, dimension(:), public :: q_prim_vf !< + !! Primitive variables + + type(integer_field), allocatable, dimension(:, :), public :: bc_type !< + !! Boundary condition identifiers + + type(scalar_field), public :: q_T_sf !< + !! Temperature field + ! type(scalar_field), public :: ib_markers !< type(integer_field), public :: ib_markers @@ -47,49 +67,69 @@ end subroutine s_read_abstract_data_files contains !> Helper subroutine to read grid data files for a given direction + !! @param t_step_dir Directory containing the time-step data + !! @param direction Direction name ('x', 'y', 'z') + !! @param cb_array Cell boundary array to populate + !! @param d_array Cell width array to populate + !! @param cc_array Cell center array to populate + !! @param size_dim Size of the dimension impure subroutine s_read_grid_data_direction(t_step_dir, direction, cb_array, d_array, cc_array, size_dim) - character(len=*), intent(in) :: t_step_dir - character(len=1), intent(in) :: direction - real(wp), dimension(-1:), intent(out) :: cb_array - real(wp), dimension(0:), intent(out) :: d_array - real(wp), dimension(0:), intent(out) :: cc_array - integer, intent(in) :: size_dim + character(len=*), intent(in) :: t_step_dir + character(len=1), intent(in) :: direction + real(wp), dimension(-1:), intent(out) :: cb_array + real(wp), dimension(0:), intent(out) :: d_array + real(wp), dimension(0:), intent(out) :: cc_array + integer, intent(in) :: size_dim + character(LEN=len_trim(t_step_dir) + 10) :: file_loc - logical :: file_check + logical :: file_check - file_loc = trim(t_step_dir) // '/' // direction // '_cb.dat' + ! Checking whether direction_cb.dat exists + file_loc = trim(t_step_dir)//'/'//direction//'_cb.dat' inquire (FILE=trim(file_loc), EXIST=file_check) + ! Reading direction_cb.dat if it exists, exiting otherwise if (file_check) then - open (1, FILE=trim(file_loc), form='unformatted', STATUS='old', ACTION='read') + open (1, FILE=trim(file_loc), FORM='unformatted', & + STATUS='old', ACTION='read') read (1) cb_array(-1:size_dim) close (1) else - call s_mpi_abort('File ' // direction // '_cb.dat is missing in ' // trim(t_step_dir) // '. Exiting.') + call s_mpi_abort('File '//direction//'_cb.dat is missing in '// & + trim(t_step_dir)//'. Exiting.') end if + ! Computing the cell-width distribution d_array(0:size_dim) = cb_array(0:size_dim) - cb_array(-1:size_dim - 1) + + ! Computing the cell-center locations cc_array(0:size_dim) = cb_array(-1:size_dim - 1) + d_array(0:size_dim)/2._wp end subroutine s_read_grid_data_direction #ifdef MFC_MPI !> Helper subroutine to setup MPI data I/O parameters + !! @param data_size Local array size (output) + !! @param m_MOK, n_MOK, p_MOK MPI offset kinds for dimensions (output) + !! @param WP_MOK, MOK, str_MOK, NVARS_MOK Other MPI offset kinds (output) impure subroutine s_setup_mpi_io_params(data_size, m_MOK, n_MOK, p_MOK, WP_MOK, MOK, str_MOK, NVARS_MOK) - integer, intent(out) :: data_size + integer, intent(out) :: data_size integer(KIND=MPI_OFFSET_KIND), intent(out) :: m_MOK, n_MOK, p_MOK integer(KIND=MPI_OFFSET_KIND), intent(out) :: WP_MOK, MOK, str_MOK, NVARS_MOK + ! Initialize MPI data I/O if (ib) then call s_initialize_mpi_data(q_cons_vf, ib_markers) else call s_initialize_mpi_data(q_cons_vf) end if + ! Size of local arrays data_size = (m + 1)*(n + 1)*(p + 1) + ! Resize some integers so MPI can read even the biggest file m_MOK = int(m_glb + 1, MPI_OFFSET_KIND) n_MOK = int(n_glb + 1, MPI_OFFSET_KIND) p_MOK = int(p_glb + 1, MPI_OFFSET_KIND) @@ -102,26 +142,29 @@ end subroutine s_setup_mpi_io_params #endif !> Helper subroutine to read IB data files + !! @param file_loc_base Base file location for IB data + !! @param t_step Time step index impure subroutine s_read_ib_data_files(file_loc_base, t_step) - character(len=*), intent(in) :: file_loc_base - integer, intent(in), optional :: t_step + character(len=*), intent(in) :: file_loc_base + integer, intent(in), optional :: t_step + character(LEN=len_trim(file_loc_base) + 20) :: file_loc - logical :: file_exist - integer :: ifile, ierr, data_size, var_MOK + logical :: file_exist + integer :: ifile, ierr, data_size, var_MOK #ifdef MFC_MPI integer, dimension(MPI_STATUS_SIZE) :: status - integer(KIND=MPI_OFFSET_KIND) :: disp - integer :: m_MOK, n_MOK, p_MOK, MOK, WP_MOK, save_index -#endif + integer(KIND=MPI_OFFSET_KIND) :: disp + integer :: m_MOK, n_MOK, p_MOK, MOK, WP_MOK, save_index +#endif if (.not. ib) return if (parallel_io) then - write (file_loc, '(A)') trim(file_loc_base) // 'ib.dat' + write (file_loc, '(A)') trim(file_loc_base)//'ib.dat' else - write (file_loc, '(A)') trim(file_loc_base) // '/ib_data.dat' + write (file_loc, '(A)') trim(file_loc_base)//'/ib_data.dat' end if inquire (FILE=trim(file_loc), EXIST=file_exist) @@ -135,7 +178,7 @@ impure subroutine s_read_ib_data_files(file_loc_base, t_step) p_MOK = int(p_glb + 1, MPI_OFFSET_KIND) MOK = int(1._wp, MPI_OFFSET_KIND) WP_MOK = int(storage_size(0._stp)/8, MPI_OFFSET_KIND) - save_index = t_step/t_step_save ! get the number of saves done to this point + save_index = t_step/t_step_save ! get the number of saves done to this point data_size = (m + 1)*(n + 1)*(p + 1) var_MOK = int(sys_size + 1, MPI_OFFSET_KIND) @@ -145,64 +188,95 @@ impure subroutine s_read_ib_data_files(file_loc_base, t_step) disp = m_MOK*max(MOK, n_MOK)*max(MOK, p_MOK)*WP_MOK*(var_MOK - 1 + int(save_index, MPI_OFFSET_KIND)) end if - call MPI_FILE_SET_VIEW(ifile, disp, MPI_INTEGER, MPI_IO_IB_DATA%view, 'native', mpi_info_int, ierr) - call MPI_FILE_READ(ifile, MPI_IO_IB_DATA%var%sf, data_size, MPI_INTEGER, status, ierr) + call MPI_FILE_SET_VIEW(ifile, disp, MPI_INTEGER, MPI_IO_IB_DATA%view, & + 'native', mpi_info_int, ierr) + call MPI_FILE_READ(ifile, MPI_IO_IB_DATA%var%sf, data_size, & + MPI_INTEGER, status, ierr) call MPI_FILE_CLOSE(ifile, ierr) #endif else - open (2, FILE=trim(file_loc), form='unformatted', ACTION='read', STATUS='old') - read (2) ib_markers%sf(0:m,0:n,0:p) + open (2, FILE=trim(file_loc), & + FORM='unformatted', & + ACTION='read', & + STATUS='old') + read (2) ib_markers%sf(0:m, 0:n, 0:p) close (2) end if else - call s_mpi_abort('File ' // trim(file_loc) // ' is missing. Exiting.') + call s_mpi_abort('File '//trim(file_loc)//' is missing. Exiting.') end if end subroutine s_read_ib_data_files !> Helper subroutine to allocate field arrays for given dimensionality + !! @param local_start_idx Starting index for allocation + !! @param end_x End index for x dimension + !! @param end_y End index for y dimension + !! @param end_z End index for z dimension impure subroutine s_allocate_field_arrays(local_start_idx, end_x, end_y, end_z) integer, intent(in) :: local_start_idx, end_x, end_y, end_z - integer :: i + integer :: i do i = 1, sys_size - allocate (q_cons_vf(i)%sf(local_start_idx:end_x,local_start_idx:end_y,local_start_idx:end_z)) - allocate (q_prim_vf(i)%sf(local_start_idx:end_x,local_start_idx:end_y,local_start_idx:end_z)) + allocate (q_cons_vf(i)%sf(local_start_idx:end_x, local_start_idx:end_y, local_start_idx:end_z)) + allocate (q_prim_vf(i)%sf(local_start_idx:end_x, local_start_idx:end_y, local_start_idx:end_z)) end do if (ib) then - allocate (ib_markers%sf(local_start_idx:end_x,local_start_idx:end_y,local_start_idx:end_z)) + allocate (ib_markers%sf(local_start_idx:end_x, local_start_idx:end_y, local_start_idx:end_z)) end if if (chemistry) then - allocate (q_T_sf%sf(local_start_idx:end_x,local_start_idx:end_y,local_start_idx:end_z)) + allocate (q_T_sf%sf(local_start_idx:end_x, local_start_idx:end_y, local_start_idx:end_z)) end if end subroutine s_allocate_field_arrays - !> Read the raw data files present in the corresponding time-step directory and to populate the associated grid and conservative - !! variables. + !> This subroutine is called at each time-step that has to + !! be post-processed in order to read the raw data files + !! present in the corresponding time-step directory and to + !! populate the associated grid and conservative variables. + !! @param t_step Current time-step impure subroutine s_read_serial_data_files(t_step) - integer, intent(in) :: t_step - character(LEN=len_trim(case_dir) + 2*name_len) :: t_step_dir - character(LEN=len_trim(case_dir) + 3*name_len) :: file_loc - character(LEN=int(floor(log10(real(sys_size, wp)))) + 1) :: file_num - character(LEN=len_trim(case_dir) + 2*name_len) :: t_step_ib_dir - logical :: dir_check - logical :: file_check - integer :: i + integer, intent(in) :: t_step + + character(LEN=len_trim(case_dir) + 2*name_len) :: t_step_dir !< + !! Location of the time-step directory associated with t_step + + character(LEN=len_trim(case_dir) + 3*name_len) :: file_loc !< + !! Generic string used to store the location of a particular file + + character(LEN= & + int(floor(log10(real(sys_size, wp)))) + 1) :: file_num !< + !! Used to store the variable position, in character form, of the + !! currently manipulated conservative variable file + + character(LEN=len_trim(case_dir) + 2*name_len) :: t_step_ib_dir !< + !! Location of the time-step directory associated with t_step + logical :: dir_check !< + !! Generic logical used to test the existence of a particular folder + + logical :: file_check !< + !! Generic logical used to test the existence of a particular file + + integer :: i !< Generic loop iterator + + ! Setting location of time-step folder based on current time-step write (t_step_dir, '(A,I0,A,I0)') '/p_all/p', proc_rank, '/', t_step - t_step_dir = trim(case_dir) // trim(t_step_dir) + t_step_dir = trim(case_dir)//trim(t_step_dir) - file_loc = trim(t_step_dir) // '/.' + ! Inquiring as to the existence of the time-step directory + file_loc = trim(t_step_dir)//'/.' call my_inquire(file_loc, dir_check) + ! If the time-step directory is missing, the post-process exits. if (dir_check .neqv. .true.) then - call s_mpi_abort('Time-step folder ' // trim(t_step_dir) // ' is missing. Exiting.') + call s_mpi_abort('Time-step folder '//trim(t_step_dir)// & + ' is missing. Exiting.') end if if (bc_io) then @@ -211,6 +285,7 @@ impure subroutine s_read_serial_data_files(t_step) call s_assign_default_bc_type(bc_type) end if + ! Reading the Grid Data Files using helper subroutine call s_read_grid_data_direction(t_step_dir, 'x', x_cb, dx, x_cc, m) if (n > 0) then @@ -221,48 +296,69 @@ impure subroutine s_read_serial_data_files(t_step) end if end if + ! Reading the Conservative Variables Data Files do i = 1, sys_size + + ! Checking whether the data file associated with the variable + ! position of currently manipulated conservative variable exists write (file_num, '(I0)') i - file_loc = trim(t_step_dir) // '/q_cons_vf' // trim(file_num) // '.dat' + file_loc = trim(t_step_dir)//'/q_cons_vf'// & + trim(file_num)//'.dat' inquire (FILE=trim(file_loc), EXIST=file_check) + ! Reading the data file if it exists, exiting otherwise if (file_check) then - open (1, FILE=trim(file_loc), form='unformatted', STATUS='old', ACTION='read') - read (1) q_cons_vf(i)%sf(0:m,0:n,0:p) + open (1, FILE=trim(file_loc), FORM='unformatted', & + STATUS='old', ACTION='read') + read (1) q_cons_vf(i)%sf(0:m, 0:n, 0:p) close (1) else if (bubbles_lagrange .and. i == beta_idx) then - ! beta (Lagrangian void fraction) is not written by pre_process for t_step_start; initialize to zero. - q_cons_vf(i)%sf(0:m,0:n,0:p) = 0._wp + ! beta (Lagrangian void fraction) is not written by pre_process + ! for t_step_start; initialize to zero. + q_cons_vf(i)%sf(0:m, 0:n, 0:p) = 0._wp else - call s_mpi_abort('File q_cons_vf' // trim(file_num) // '.dat is missing in ' // trim(t_step_dir) // '. Exiting.') + call s_mpi_abort('File q_cons_vf'//trim(file_num)// & + '.dat is missing in '//trim(t_step_dir)// & + '. Exiting.') end if + end do + ! Reading IB data using helper subroutine call s_read_ib_data_files(t_step_dir) end subroutine s_read_serial_data_files - !> Parallel-read the raw data files present in the corresponding time-step directory and to populate the associated grid and - !! conservative variables. + !> This subroutine is called at each time-step that has to + !! be post-processed in order to parallel-read the raw data files + !! present in the corresponding time-step directory and to + !! populate the associated grid and conservative variables. + !! @param t_step Current time-step impure subroutine s_read_parallel_data_files(t_step) integer, intent(in) :: t_step #ifdef MFC_MPI - real(wp), allocatable, dimension(:) :: x_cb_glb, y_cb_glb, z_cb_glb - integer :: ifile, ierr, data_size, filetype, stride - integer, dimension(MPI_STATUS_SIZE) :: status - integer(KIND=MPI_OFFSET_KIND) :: disp - integer(KIND=MPI_OFFSET_KIND) :: m_MOK, n_MOK, p_MOK - integer(KIND=MPI_OFFSET_KIND) :: WP_MOK, var_MOK, str_MOK - integer(KIND=MPI_OFFSET_KIND) :: NVARS_MOK - integer(KIND=MPI_OFFSET_KIND) :: MOK - integer(kind=MPI_OFFSET_KIND) :: offset - real(wp) :: delx, dely, delz + + real(wp), allocatable, dimension(:) :: x_cb_glb, y_cb_glb, z_cb_glb + + integer :: ifile, ierr, data_size, filetype, stride + integer, dimension(MPI_STATUS_SIZE) :: status + + integer(KIND=MPI_OFFSET_KIND) :: disp + integer(KIND=MPI_OFFSET_KIND) :: m_MOK, n_MOK, p_MOK + integer(KIND=MPI_OFFSET_KIND) :: WP_MOK, var_MOK, str_MOK + integer(KIND=MPI_OFFSET_KIND) :: NVARS_MOK + integer(KIND=MPI_OFFSET_KIND) :: MOK + integer(kind=MPI_OFFSET_KIND) :: offset + real(wp) :: delx, dely, delz + character(LEN=path_len + 2*name_len) :: file_loc - logical :: file_exist - character(len=10) :: t_step_string - integer :: i + logical :: file_exist + + character(len=10) :: t_step_string + + integer :: i allocate (x_cb_glb(-1:m_glb)) allocate (y_cb_glb(-1:n_glb)) @@ -274,7 +370,8 @@ impure subroutine s_read_parallel_data_files(t_step) stride = 1 end if - file_loc = trim(case_dir) // '/restart_data' // trim(mpiiofs) // 'x_cb.dat' + ! Read in cell boundary locations in x-direction + file_loc = trim(case_dir)//'/restart_data'//trim(mpiiofs)//'x_cb.dat' inquire (FILE=trim(file_loc), EXIST=file_exist) if (file_exist) then @@ -290,15 +387,19 @@ impure subroutine s_read_parallel_data_files(t_step) call MPI_FILE_READ(ifile, x_cb_glb, data_size, mpi_p, status, ierr) call MPI_FILE_CLOSE(ifile, ierr) else - call s_mpi_abort('File ' // trim(file_loc) // ' is missing. Exiting.') + call s_mpi_abort('File '//trim(file_loc)//' is missing. Exiting.') end if + ! Assigning local cell boundary locations x_cb(-1:m) = x_cb_glb((start_idx(1) - 1):(start_idx(1) + m)) + ! Computing the cell width distribution dx(0:m) = x_cb(0:m) - x_cb(-1:m - 1) + ! Computing the cell center location x_cc(0:m) = x_cb(-1:m - 1) + dx(0:m)/2._wp if (n > 0) then - file_loc = trim(case_dir) // '/restart_data' // trim(mpiiofs) // 'y_cb.dat' + ! Read in cell boundary locations in y-direction + file_loc = trim(case_dir)//'/restart_data'//trim(mpiiofs)//'y_cb.dat' inquire (FILE=trim(file_loc), EXIST=file_exist) if (file_exist) then @@ -314,15 +415,19 @@ impure subroutine s_read_parallel_data_files(t_step) call MPI_FILE_READ(ifile, y_cb_glb, data_size, mpi_p, status, ierr) call MPI_FILE_CLOSE(ifile, ierr) else - call s_mpi_abort('File ' // trim(file_loc) // ' is missing. Exiting.') + call s_mpi_abort('File '//trim(file_loc)//' is missing. Exiting.') end if + ! Assigning local cell boundary locations y_cb(-1:n) = y_cb_glb((start_idx(2) - 1):(start_idx(2) + n)) + ! Computing the cell width distribution dy(0:n) = y_cb(0:n) - y_cb(-1:n - 1) + ! Computing the cell center location y_cc(0:n) = y_cb(-1:n - 1) + dy(0:n)/2._wp if (p > 0) then - file_loc = trim(case_dir) // '/restart_data' // trim(mpiiofs) // 'z_cb.dat' + ! Read in cell boundary locations in z-direction + file_loc = trim(case_dir)//'/restart_data'//trim(mpiiofs)//'z_cb.dat' inquire (FILE=trim(file_loc), EXIST=file_exist) if (file_exist) then @@ -338,11 +443,14 @@ impure subroutine s_read_parallel_data_files(t_step) call MPI_FILE_READ(ifile, z_cb_glb, data_size, mpi_p, status, ierr) call MPI_FILE_CLOSE(ifile, ierr) else - call s_mpi_abort('File ' // trim(file_loc) // ' is missing. Exiting.') + call s_mpi_abort('File '//trim(file_loc)//' is missing. Exiting.') end if + ! Assigning local cell boundary locations z_cb(-1:p) = z_cb_glb((start_idx(3) - 1):(start_idx(3) + p)) + ! Computing the cell width distribution dz(0:p) = z_cb(0:p) - z_cb(-1:p - 1) + ! Computing the cell center location z_cc(0:p) = z_cb(-1:p - 1) + dz(0:p)/2._wp end if end if @@ -356,29 +464,35 @@ impure subroutine s_read_parallel_data_files(t_step) else call s_assign_default_bc_type(bc_type) end if + #endif end subroutine s_read_parallel_data_files #ifdef MFC_MPI !> Helper subroutine to read parallel conservative variable data + !! @param t_step Current time-step + !! @param m_MOK, n_MOK, p_MOK MPI offset kinds for dimensions + !! @param WP_MOK, MOK, str_MOK, NVARS_MOK Other MPI offset kinds impure subroutine s_read_parallel_conservative_data(t_step, m_MOK, n_MOK, p_MOK, WP_MOK, MOK, str_MOK, NVARS_MOK) - integer, intent(in) :: t_step + integer, intent(in) :: t_step integer(KIND=MPI_OFFSET_KIND), intent(inout) :: m_MOK, n_MOK, p_MOK integer(KIND=MPI_OFFSET_KIND), intent(inout) :: WP_MOK, MOK, str_MOK, NVARS_MOK - integer :: ifile, ierr, data_size - integer, dimension(MPI_STATUS_SIZE) :: status - integer(KIND=MPI_OFFSET_KIND) :: disp, var_MOK - character(LEN=path_len + 2*name_len) :: file_loc - logical :: file_exist - character(len=10) :: t_step_string - integer :: i + + integer :: ifile, ierr, data_size + integer, dimension(MPI_STATUS_SIZE) :: status + integer(KIND=MPI_OFFSET_KIND) :: disp, var_MOK + character(LEN=path_len + 2*name_len) :: file_loc + logical :: file_exist + character(len=10) :: t_step_string + integer :: i if (file_per_process) then call s_int_to_str(t_step, t_step_string) + ! Open the file to read conservative variables write (file_loc, '(I0,A1,I7.7,A)') t_step, '_', proc_rank, '.dat' - file_loc = trim(case_dir) // '/restart_data/lustre_' // trim(t_step_string) // trim(mpiiofs) // trim(file_loc) + file_loc = trim(case_dir)//'/restart_data/lustre_'//trim(t_step_string)//trim(mpiiofs)//trim(file_loc) inquire (FILE=trim(file_loc), EXIST=file_exist) if (file_exist) then @@ -387,6 +501,7 @@ impure subroutine s_read_parallel_conservative_data(t_step, m_MOK, n_MOK, p_MOK, if (down_sample) then call s_initialize_mpi_data_ds(q_cons_temp) else + ! Initialize MPI data I/O if (ib) then call s_initialize_mpi_data(q_cons_vf, ib_markers) else @@ -395,11 +510,14 @@ impure subroutine s_read_parallel_conservative_data(t_step, m_MOK, n_MOK, p_MOK, end if if (down_sample) then + ! Size of local arrays data_size = (m + 3)*(n + 3)*(p + 3) else + ! Size of local arrays data_size = (m + 1)*(n + 1)*(p + 1) end if + ! Resize some integers so MPI can read even the biggest file m_MOK = int(m_glb + 1, MPI_OFFSET_KIND) n_MOK = int(n_glb + 1, MPI_OFFSET_KIND) p_MOK = int(p_glb + 1, MPI_OFFSET_KIND) @@ -408,15 +526,18 @@ impure subroutine s_read_parallel_conservative_data(t_step, m_MOK, n_MOK, p_MOK, str_MOK = int(name_len, MPI_OFFSET_KIND) NVARS_MOK = int(sys_size, MPI_OFFSET_KIND) + ! Read the data for each variable if (bubbles_euler .or. elasticity .or. mhd) then do i = 1, sys_size var_MOK = int(i, MPI_OFFSET_KIND) - call MPI_FILE_READ_ALL(ifile, MPI_IO_DATA%var(i)%sf, data_size*mpi_io_type, mpi_io_p, status, ierr) + call MPI_FILE_READ_ALL(ifile, MPI_IO_DATA%var(i)%sf, data_size*mpi_io_type, & + mpi_io_p, status, ierr) end do else do i = 1, sys_size var_MOK = int(i, MPI_OFFSET_KIND) - call MPI_FILE_READ_ALL(ifile, MPI_IO_DATA%var(i)%sf, data_size*mpi_io_type, mpi_io_p, status, ierr) + call MPI_FILE_READ_ALL(ifile, MPI_IO_DATA%var(i)%sf, data_size*mpi_io_type, & + mpi_io_p, status, ierr) end do end if @@ -425,17 +546,18 @@ impure subroutine s_read_parallel_conservative_data(t_step, m_MOK, n_MOK, p_MOK, if (down_sample) then do i = 1, sys_size - q_cons_vf(i)%sf(0:m,0:n,0:p) = q_cons_temp(i)%sf(0:m,0:n,0:p) + q_cons_vf(i)%sf(0:m, 0:n, 0:p) = q_cons_temp(i)%sf(0:m, 0:n, 0:p) end do end if - call s_read_ib_data_files(trim(case_dir) // '/restart_data' // trim(mpiiofs), t_step) + call s_read_ib_data_files(trim(case_dir)//'/restart_data'//trim(mpiiofs), t_step) else - call s_mpi_abort('File ' // trim(file_loc) // ' is missing. Exiting.') + call s_mpi_abort('File '//trim(file_loc)//' is missing. Exiting.') end if else + ! Open the file to read conservative variables write (file_loc, '(I0,A)') t_step, '.dat' - file_loc = trim(case_dir) // '/restart_data' // trim(mpiiofs) // trim(file_loc) + file_loc = trim(case_dir)//'/restart_data'//trim(mpiiofs)//trim(file_loc) inquire (FILE=trim(file_loc), EXIST=file_exist) if (file_exist) then @@ -443,61 +565,77 @@ impure subroutine s_read_parallel_conservative_data(t_step, m_MOK, n_MOK, p_MOK, call s_setup_mpi_io_params(data_size, m_MOK, n_MOK, p_MOK, WP_MOK, MOK, str_MOK, NVARS_MOK) + ! Read the data for each variable do i = 1, sys_size var_MOK = int(i, MPI_OFFSET_KIND) + ! Initial displacement to skip at beginning of file disp = m_MOK*max(MOK, n_MOK)*max(MOK, p_MOK)*WP_MOK*(var_MOK - 1) - call MPI_FILE_SET_VIEW(ifile, disp, mpi_p, MPI_IO_DATA%view(i), 'native', mpi_info_int, ierr) - call MPI_FILE_READ_ALL(ifile, MPI_IO_DATA%var(i)%sf, data_size*mpi_io_type, mpi_io_p, status, ierr) + call MPI_FILE_SET_VIEW(ifile, disp, mpi_p, MPI_IO_DATA%view(i), & + 'native', mpi_info_int, ierr) + call MPI_FILE_READ_ALL(ifile, MPI_IO_DATA%var(i)%sf, data_size*mpi_io_type, & + mpi_io_p, status, ierr) end do call s_mpi_barrier() call MPI_FILE_CLOSE(ifile, ierr) - call s_read_ib_data_files(trim(case_dir) // '/restart_data' // trim(mpiiofs), t_step) + call s_read_ib_data_files(trim(case_dir)//'/restart_data'//trim(mpiiofs), t_step) else - call s_mpi_abort('File ' // trim(file_loc) // ' is missing. Exiting.') + call s_mpi_abort('File '//trim(file_loc)//' is missing. Exiting.') end if end if - end subroutine s_read_parallel_conservative_data #endif - !> Computation of parameters, allocation procedures, and/or any other tasks needed to properly setup the module + !> Computation of parameters, allocation procedures, and/or + !! any other tasks needed to properly setup the module impure subroutine s_initialize_data_input_module - integer :: i + integer :: i !< Generic loop iterator + ! Allocating the parts of the conservative and primitive variables + ! that do not require the direct knowledge of the dimensionality of + ! the simulation allocate (q_cons_vf(1:sys_size)) allocate (q_prim_vf(1:sys_size)) allocate (q_cons_temp(1:sys_size)) + ! Allocating the parts of the conservative and primitive variables + ! that do require the direct knowledge of the dimensionality of + ! the simulation using helper subroutine + + ! Simulation is at least 2D if (n > 0) then + ! Simulation is 3D if (p > 0) then call s_allocate_field_arrays(-buff_size, m + buff_size, n + buff_size, p + buff_size) if (down_sample) then do i = 1, sys_size - allocate (q_cons_temp(i)%sf(-1:m + 1,-1:n + 1,-1:p + 1)) + allocate (q_cons_temp(i)%sf(-1:m + 1, -1:n + 1, -1:p + 1)) end do end if else + ! Simulation is 2D call s_allocate_field_arrays(-buff_size, m + buff_size, n + buff_size, 0) end if else + ! Simulation is 1D call s_allocate_field_arrays(-buff_size, m + buff_size, 0, 0) end if - allocate (bc_type(1:num_dims,1:2)) + ! Allocating arrays to store the bc types + allocate (bc_type(1:num_dims, 1:2)) - allocate (bc_type(1, 1)%sf(0:0,0:n,0:p)) - allocate (bc_type(1, 2)%sf(0:0,0:n,0:p)) + allocate (bc_type(1, 1)%sf(0:0, 0:n, 0:p)) + allocate (bc_type(1, 2)%sf(0:0, 0:n, 0:p)) if (n > 0) then - allocate (bc_type(2, 1)%sf(-buff_size:m + buff_size,0:0,0:p)) - allocate (bc_type(2, 2)%sf(-buff_size:m + buff_size,0:0,0:p)) + allocate (bc_type(2, 1)%sf(-buff_size:m + buff_size, 0:0, 0:p)) + allocate (bc_type(2, 2)%sf(-buff_size:m + buff_size, 0:0, 0:p)) if (p > 0) then - allocate (bc_type(3, 1)%sf(-buff_size:m + buff_size,-buff_size:n + buff_size,0:0)) - allocate (bc_type(3, 2)%sf(-buff_size:m + buff_size,-buff_size:n + buff_size,0:0)) + allocate (bc_type(3, 1)%sf(-buff_size:m + buff_size, -buff_size:n + buff_size, 0:0)) + allocate (bc_type(3, 2)%sf(-buff_size:m + buff_size, -buff_size:n + buff_size, 0:0)) end if end if @@ -512,8 +650,9 @@ end subroutine s_initialize_data_input_module !> Deallocation procedures for the module impure subroutine s_finalize_data_input_module - integer :: i + integer :: i !< Generic loop iterator + ! Deallocating the conservative and primitive variables do i = 1, sys_size deallocate (q_cons_vf(i)%sf) deallocate (q_prim_vf(i)%sf) diff --git a/src/post_process/m_data_output.fpp b/src/post_process/m_data_output.fpp index 0ac093288f..3251b3ac3b 100644 --- a/src/post_process/m_data_output.fpp +++ b/src/post_process/m_data_output.fpp @@ -5,129 +5,187 @@ !> @brief Writes post-processed grid and flow-variable data to Silo-HDF5 or binary database files module m_data_output - use m_derived_types - use m_global_parameters - use m_derived_variables - use m_mpi_proxy + use m_derived_types ! Definitions of the derived types + + use m_global_parameters ! Global parameters + + use m_derived_variables !< Procedures used to compute quantities derived + + use m_mpi_proxy ! Message passing interface (MPI) module proxy + use m_compile_specific + use m_helper + use m_variables_conversion implicit none - private; public :: s_initialize_data_output_module, s_define_output_region, s_open_formatted_database_file, & - & s_open_intf_data_file, s_open_energy_data_file, s_write_grid_to_formatted_database_file, & - & s_write_variable_to_formatted_database_file, s_write_lag_bubbles_results_to_text, & - & s_write_lag_bubbles_to_formatted_database_file, s_write_ib_state_files, s_write_intf_data_file, & - & s_write_energy_data_file, s_close_formatted_database_file, s_close_intf_data_file, s_close_energy_data_file, & - & s_finalize_data_output_module - - ! Include Silo-HDF5 interface library + private; public :: s_initialize_data_output_module, & + s_define_output_region, & + s_open_formatted_database_file, & + s_open_intf_data_file, & + s_open_energy_data_file, & + s_write_grid_to_formatted_database_file, & + s_write_variable_to_formatted_database_file, & + s_write_lag_bubbles_results_to_text, & + s_write_lag_bubbles_to_formatted_database_file, & + s_write_ib_state_files, & + s_write_intf_data_file, & + s_write_energy_data_file, & + s_close_formatted_database_file, & + s_close_intf_data_file, & + s_close_energy_data_file, & + s_finalize_data_output_module + + ! Including the Silo Fortran interface library that features the subroutines + ! and parameters that are required to write in the Silo-HDF5 database format + ! INCLUDE 'silo.inc' include 'silo_f9x.inc' - ! Flow variable storage; q_root_sf gathers to rank 0 in 1D parallel runs - real(wp), allocatable, dimension(:,:,:), public :: q_sf - real(wp), allocatable, dimension(:,:,:) :: q_root_sf - real(wp), allocatable, dimension(:,:,:) :: cyl_q_sf + ! Generic storage for flow variable(s) that are to be written to formatted + ! database file(s). Note that for 1D simulations, q_root_sf is employed to + ! gather the flow variable(s) from all sub-domains on to the root process. + ! If the run is not parallel, but serial, then q_root_sf is equal to q_sf. + real(wp), allocatable, dimension(:, :, :), public :: q_sf + real(wp), allocatable, dimension(:, :, :) :: q_root_sf + real(wp), allocatable, dimension(:, :, :) :: cyl_q_sf ! Single precision storage for flow variables - real(sp), allocatable, dimension(:,:,:), public :: q_sf_s - real(sp), allocatable, dimension(:,:,:) :: q_root_sf_s - real(sp), allocatable, dimension(:,:,:) :: cyl_q_sf_s - - ! Spatial and data extents for VisIt visualization - real(wp), allocatable, dimension(:,:) :: spatial_extents - real(wp), allocatable, dimension(:,:) :: data_extents - - ! Ghost zone layer sizes (lo/hi) for subdomain connectivity in VisIt + real(sp), allocatable, dimension(:, :, :), public :: q_sf_s + real(sp), allocatable, dimension(:, :, :) :: q_root_sf_s + real(sp), allocatable, dimension(:, :, :) :: cyl_q_sf_s + + ! The spatial and data extents array variables contain information about the + ! minimum and maximum values of the grid and flow variable(s), respectively. + ! The purpose of bookkeeping this information is to boost the visualization + ! of the Silo-HDF5 database file(s) in VisIt. + real(wp), allocatable, dimension(:, :) :: spatial_extents + real(wp), allocatable, dimension(:, :) :: data_extents + + ! The size of the ghost zone layer at beginning of each coordinate direction + ! (lo) and at end of each coordinate direction (hi). Adding this information + ! to Silo-HDF5 database file(s) is recommended since it supplies VisIt with + ! connectivity information between the sub-domains of a parallel data set. integer, allocatable, dimension(:) :: lo_offset integer, allocatable, dimension(:) :: hi_offset - ! Track cell-boundary count per active coordinate direction + ! For Silo-HDF5 database format, this variable is used to keep track of the + ! number of cell-boundaries, for the grid associated with the local process, + ! in each of the active coordinate directions. integer, allocatable, dimension(:) :: dims - ! Locations of various folders in the case's directory tree, associated with the choice of the formatted database format. These - ! include, in order, the location of the folder named after the selected formatted database format, and the locations of two - ! sub-directories of the latter, the first of which is named after the local processor rank, while the second is named 'root'. - ! The folder associated with the local processor rank contains only the data pertaining to the part of the domain taken care of - ! by the local processor. The root directory, on the other hand, will contain either the information about the connectivity - ! required to put the entire domain back together, or the actual data associated with the entire computational domain. This all + ! Locations of various folders in the case's directory tree, associated with + ! the choice of the formatted database format. These include, in order, the + ! location of the folder named after the selected formatted database format, + ! and the locations of two sub-directories of the latter, the first of which + ! is named after the local processor rank, while the second is named 'root'. + ! The folder associated with the local processor rank contains only the data + ! pertaining to the part of the domain taken care of by the local processor. + ! The root directory, on the other hand, will contain either the information + ! about the connectivity required to put the entire domain back together, or + ! the actual data associated with the entire computational domain. This all ! depends on dimensionality and the choice of the formatted database format. - character(LEN=path_len + name_len) :: dbdir + character(LEN=path_len + name_len) :: dbdir character(LEN=path_len + 2*name_len) :: proc_rank_dir character(LEN=path_len + 2*name_len) :: rootdir - ! Handles of the formatted database master/root file, slave/local processor file and options list. The list of options is - ! explicitly used in the Silo- HDF5 database format to provide additional details about the contents of a formatted database - ! file, such as the previously described spatial and data extents. + ! Handles of the formatted database master/root file, slave/local processor + ! file and options list. The list of options is explicitly used in the Silo- + ! HDF5 database format to provide additional details about the contents of a + ! formatted database file, such as the previously described spatial and data + ! extents. integer :: dbroot integer :: dbfile integer :: optlist - ! The total number of flow variable(s) to be stored in a formatted database file. Note that this is only needed when using the - ! Binary format. + ! The total number of flow variable(s) to be stored in a formatted database + ! file. Note that this is only needed when using the Binary format. integer :: dbvars - ! Generic error flags utilized in the handling, checking and the reporting of the input and output operations errors with a - ! formatted database file + ! Generic error flags utilized in the handling, checking and the reporting + ! of the input and output operations errors with a formatted database file integer, private :: err contains - !> Allocate storage arrays, configure output directories, and count flow variables for formatted database output. + !> @brief Allocate storage arrays, configure output directories, and count flow variables for formatted database output. impure subroutine s_initialize_data_output_module() + ! Description: Computation of parameters, allocation procedures, and/or + ! any other tasks needed to properly setup the module + ! Generic string used to store the location of a particular file character(LEN=len_trim(case_dir) + 2*name_len) :: file_loc - logical :: dir_check - integer :: i - allocate (q_sf(-offset_x%beg:m + offset_x%end,-offset_y%beg:n + offset_y%end,-offset_z%beg:p + offset_z%end)) + ! Generic logical used to test the existence of a particular folder + logical :: dir_check + + integer :: i + + ! Allocating the generic storage for the flow variable(s) that are + ! going to be written to the formatted database file(s). Note once + ! more that the root variable is only required for 1D computations. + allocate (q_sf(-offset_x%beg:m + offset_x%end, & + -offset_y%beg:n + offset_y%end, & + -offset_z%beg:p + offset_z%end)) if (grid_geometry == 3) then - allocate (cyl_q_sf(-offset_y%beg:n + offset_y%end,-offset_z%beg:p + offset_z%end,-offset_x%beg:m + offset_x%end)) + allocate (cyl_q_sf(-offset_y%beg:n + offset_y%end, & + -offset_z%beg:p + offset_z%end, & + -offset_x%beg:m + offset_x%end)) end if if (precision == 1) then - allocate (q_sf_s(-offset_x%beg:m + offset_x%end,-offset_y%beg:n + offset_y%end,-offset_z%beg:p + offset_z%end)) + allocate (q_sf_s(-offset_x%beg:m + offset_x%end, & + -offset_y%beg:n + offset_y%end, & + -offset_z%beg:p + offset_z%end)) if (grid_geometry == 3) then - allocate (cyl_q_sf_s(-offset_y%beg:n + offset_y%end,-offset_z%beg:p + offset_z%end,-offset_x%beg:m + offset_x%end)) + allocate (cyl_q_sf_s(-offset_y%beg:n + offset_y%end, & + -offset_z%beg:p + offset_z%end, & + -offset_x%beg:m + offset_x%end)) end if end if if (n == 0) then - allocate (q_root_sf(0:m_root,0:0,0:0)) + allocate (q_root_sf(0:m_root, 0:0, 0:0)) if (precision == 1) then - allocate (q_root_sf_s(0:m_root,0:0,0:0)) + allocate (q_root_sf_s(0:m_root, 0:0, 0:0)) end if end if - ! Allocating the spatial and data extents and also the variables for the offsets and the one bookkeeping the number of - ! cell-boundaries in each active coordinate direction. Note that all these variables are only needed by the Silo-HDF5 format - ! for multidimensional data. + ! Allocating the spatial and data extents and also the variables for + ! the offsets and the one bookkeeping the number of cell-boundaries + ! in each active coordinate direction. Note that all these variables + ! are only needed by the Silo-HDF5 format for multidimensional data. if (format == 1) then - allocate (data_extents(1:2,0:num_procs - 1)) + + allocate (data_extents(1:2, 0:num_procs - 1)) if (p > 0) then - allocate (spatial_extents(1:6,0:num_procs - 1)) + allocate (spatial_extents(1:6, 0:num_procs - 1)) allocate (lo_offset(1:3)) allocate (hi_offset(1:3)) allocate (dims(1:3)) - else if (n > 0) then - allocate (spatial_extents(1:4,0:num_procs - 1)) + elseif (n > 0) then + allocate (spatial_extents(1:4, 0:num_procs - 1)) allocate (lo_offset(1:2)) allocate (hi_offset(1:2)) allocate (dims(1:2)) else - allocate (spatial_extents(1:2,0:num_procs - 1)) + allocate (spatial_extents(1:2, 0:num_procs - 1)) allocate (lo_offset(1:1)) allocate (hi_offset(1:1)) allocate (dims(1:1)) end if + end if - ! The size of the ghost zone layer in each of the active coordinate directions was set in the module m_mpi_proxy.f90. The - ! results are now transferred to the local variables of this module when they are required by the Silo-HDF5 format, for - ! multidimensional data sets. With the same, latter, requirements, the variables bookkeeping the number of cell-boundaries - ! in each active coordinate direction are also set here. + ! The size of the ghost zone layer in each of the active coordinate + ! directions was set in the module m_mpi_proxy.f90. The results are + ! now transferred to the local variables of this module when they are + ! required by the Silo-HDF5 format, for multidimensional data sets. + ! With the same, latter, requirements, the variables bookkeeping the + ! number of cell-boundaries in each active coordinate direction are + ! also set here. if (format == 1) then if (p > 0) then if (grid_geometry == 3) then @@ -139,17 +197,20 @@ contains end if if (grid_geometry == 3) then - dims(:) = (/n + offset_y%beg + offset_y%end + 2, p + offset_z%beg + offset_z%end + 2, & - & m + offset_x%beg + offset_x%end + 2/) + dims(:) = (/n + offset_y%beg + offset_y%end + 2, & + p + offset_z%beg + offset_z%end + 2, & + m + offset_x%beg + offset_x%end + 2/) else - dims(:) = (/m + offset_x%beg + offset_x%end + 2, n + offset_y%beg + offset_y%end + 2, & - & p + offset_z%beg + offset_z%end + 2/) + dims(:) = (/m + offset_x%beg + offset_x%end + 2, & + n + offset_y%beg + offset_y%end + 2, & + p + offset_z%beg + offset_z%end + 2/) end if - else if (n > 0) then + elseif (n > 0) then lo_offset(:) = (/offset_x%beg, offset_y%beg/) hi_offset(:) = (/offset_x%end, offset_y%end/) - dims(:) = (/m + offset_x%beg + offset_x%end + 2, n + offset_y%beg + offset_y%end + 2/) + dims(:) = (/m + offset_x%beg + offset_x%end + 2, & + n + offset_y%beg + offset_y%end + 2/) else lo_offset(:) = (/offset_x%beg/) hi_offset(:) = (/offset_x%end/) @@ -157,38 +218,49 @@ contains end if end if + ! Generating Silo-HDF5 Directory Tree if (format == 1) then - dbdir = trim(case_dir) // '/silo_hdf5' + + ! Creating the directory associated with the local process + dbdir = trim(case_dir)//'/silo_hdf5' write (proc_rank_dir, '(A,I0)') '/p', proc_rank - proc_rank_dir = trim(dbdir) // trim(proc_rank_dir) + proc_rank_dir = trim(dbdir)//trim(proc_rank_dir) - file_loc = trim(proc_rank_dir) // '/.' + file_loc = trim(proc_rank_dir)//'/.' call my_inquire(file_loc, dir_check) if (dir_check .neqv. .true.) then call s_create_directory(trim(proc_rank_dir)) end if + ! Creating the directory associated with the root process if (proc_rank == 0) then - rootdir = trim(dbdir) // '/root' - file_loc = trim(rootdir) // '/.' + rootdir = trim(dbdir)//'/root' + + file_loc = trim(rootdir)//'/.' call my_inquire(file_loc, dir_check) if (dir_check .neqv. .true.) then call s_create_directory(trim(rootdir)) end if + end if + + ! Generating Binary Directory Tree + else - dbdir = trim(case_dir) // '/binary' + + ! Creating the directory associated with the local process + dbdir = trim(case_dir)//'/binary' write (proc_rank_dir, '(A,I0)') '/p', proc_rank - proc_rank_dir = trim(dbdir) // trim(proc_rank_dir) + proc_rank_dir = trim(dbdir)//trim(proc_rank_dir) - file_loc = trim(proc_rank_dir) // '/.' + file_loc = trim(proc_rank_dir)//'/.' call my_inquire(file_loc, dir_check) @@ -196,23 +268,27 @@ contains call s_create_directory(trim(proc_rank_dir)) end if + ! Creating the directory associated with the root process if (n == 0 .and. proc_rank == 0) then - rootdir = trim(dbdir) // '/root' - file_loc = trim(rootdir) // '/.' + rootdir = trim(dbdir)//'/root' + + file_loc = trim(rootdir)//'/.' call my_inquire(file_loc, dir_check) if (dir_check .neqv. .true.) then call s_create_directory(trim(rootdir)) end if + end if + end if - if (bubbles_lagrange) then ! Lagrangian solver + if (bubbles_lagrange) then !Lagrangian solver if (lag_txt_wrt) then - dbdir = trim(case_dir) // '/lag_bubbles_post_process' - file_loc = trim(dbdir) // '/.' + dbdir = trim(case_dir)//'/lag_bubbles_post_process' + file_loc = trim(dbdir)//'/.' call my_inquire(file_loc, dir_check) if (dir_check .neqv. .true.) then @@ -221,50 +297,74 @@ contains end if end if - ! Contrary to the Silo-HDF5 database format, handles of the Binary database master/root and slave/local process files are - ! perfectly static throughout post-process. Hence, they are set here so that they do not have to be repetitively computed in - ! later procedures. + ! Contrary to the Silo-HDF5 database format, handles of the Binary + ! database master/root and slave/local process files are perfectly + ! static throughout post-process. Hence, they are set here so that + ! they do not have to be repetitively computed in later procedures. if (format == 2) then if (n == 0 .and. proc_rank == 0) dbroot = 2 dbfile = 1 end if + ! Querying Number of Flow Variable(s) in Binary Output + if (format == 2) then + + ! Initializing the counter of the number of flow variable(s) to + ! be written to the formatted database file(s) dbvars = 0 + ! Partial densities if ((model_eqns == 2) .or. (model_eqns == 3)) then do i = 1, num_fluids - if (alpha_rho_wrt(i) .or. (cons_vars_wrt .or. prim_vars_wrt)) then + if (alpha_rho_wrt(i) & + .or. & + (cons_vars_wrt .or. prim_vars_wrt)) then dbvars = dbvars + 1 end if end do end if - if ((rho_wrt .or. (model_eqns == 1 .and. (cons_vars_wrt .or. prim_vars_wrt))) .and. (.not. relativity)) then + ! Density + if ((rho_wrt .or. (model_eqns == 1 .and. (cons_vars_wrt .or. prim_vars_wrt))) & + .and. (.not. relativity)) then dbvars = dbvars + 1 end if if (relativity .and. (rho_wrt .or. prim_vars_wrt)) dbvars = dbvars + 1 if (relativity .and. (rho_wrt .or. cons_vars_wrt)) dbvars = dbvars + 1 + ! Momentum do i = 1, E_idx - mom_idx%beg if (mom_wrt(i) .or. cons_vars_wrt) dbvars = dbvars + 1 end do + ! Velocity do i = 1, E_idx - mom_idx%beg if (vel_wrt(i) .or. prim_vars_wrt) dbvars = dbvars + 1 end do + ! Flux limiter function do i = 1, E_idx - mom_idx%beg if (flux_wrt(i)) dbvars = dbvars + 1 end do + ! Energy if (E_wrt .or. cons_vars_wrt) dbvars = dbvars + 1 + + ! Pressure if (pres_wrt .or. prim_vars_wrt) dbvars = dbvars + 1 + + ! Elastic stresses if (hypoelasticity) dbvars = dbvars + (num_dims*(num_dims + 1))/2 + + ! Damage state variable if (cont_damage) dbvars = dbvars + 1 + + ! Hyperbolic cleaning for MHD if (hyper_cleaning) dbvars = dbvars + 1 + ! Magnetic field if (mhd) then if (n == 0) then dbvars = dbvars + 2 @@ -273,57 +373,83 @@ contains end if end if + ! Volume fraction(s) if ((model_eqns == 2) .or. (model_eqns == 3)) then + do i = 1, num_fluids - 1 - if (alpha_wrt(i) .or. (cons_vars_wrt .or. prim_vars_wrt)) then + if (alpha_wrt(i) & + .or. & + (cons_vars_wrt .or. prim_vars_wrt)) then dbvars = dbvars + 1 end if end do - if (alpha_wrt(num_fluids) .or. (cons_vars_wrt .or. prim_vars_wrt)) then + if (alpha_wrt(num_fluids) & + .or. & + (cons_vars_wrt .or. prim_vars_wrt)) & + then dbvars = dbvars + 1 end if + end if - if (gamma_wrt .or. (model_eqns == 1 .and. (cons_vars_wrt .or. prim_vars_wrt))) then + ! Specific heat ratio function + if (gamma_wrt & + .or. & + (model_eqns == 1 .and. (cons_vars_wrt .or. prim_vars_wrt))) & + then dbvars = dbvars + 1 end if + ! Specific heat ratio if (heat_ratio_wrt) dbvars = dbvars + 1 - if (pi_inf_wrt .or. (model_eqns == 1 .and. (cons_vars_wrt .or. prim_vars_wrt))) then + ! Liquid stiffness function + if (pi_inf_wrt & + .or. & + (model_eqns == 1 .and. (cons_vars_wrt .or. prim_vars_wrt))) & + then dbvars = dbvars + 1 end if + ! Liquid stiffness if (pres_inf_wrt) dbvars = dbvars + 1 + + ! Speed of sound if (c_wrt) dbvars = dbvars + 1 + ! Vorticity if (p > 0) then do i = 1, num_vels if (omega_wrt(i)) dbvars = dbvars + 1 end do - else if (n > 0) then + elseif (n > 0) then do i = 1, num_vels if (omega_wrt(i)) dbvars = dbvars + 1 end do end if + ! Numerical Schlieren function if (schlieren_wrt) dbvars = dbvars + 1 + end if + ! END: Querying Number of Flow Variable(s) in Binary Output + end subroutine s_initialize_data_output_module - !> Compute the cell-index bounds for the user-specified partial output domain in each coordinate direction. + !> @brief Compute the cell-index bounds for the user-specified partial output domain in each coordinate direction. impure subroutine s_define_output_region integer :: i integer :: lower_bound, upper_bound #:for X, M in [('x', 'm'), ('y', 'n'), ('z', 'p')] - if (${M}$ == 0) return ! Early return for y or z if simulation is 1D or 2D + + if (${M}$ == 0) return ! Early return for y or z if simulation is 1D or 2D lower_bound = -offset_${X}$%beg - upper_bound = ${M}$ + offset_${X}$%end + upper_bound = ${M}$+offset_${X}$%end do i = lower_bound, upper_bound if (${X}$_cc(i) > ${X}$_output%beg) then @@ -344,63 +470,126 @@ contains ${X}$_output_idx%beg = 0 ${X}$_output_idx%end = 0 end if + #:endfor end subroutine s_define_output_region - !> Open (or create) the Silo-HDF5 or Binary formatted database slave and master files for a given time step. + !> @brief Open (or create) the Silo-HDF5 or Binary formatted database slave and master files for a given time step. impure subroutine s_open_formatted_database_file(t_step) - - integer, intent(in) :: t_step + ! Description: This subroutine opens a new formatted database file, or + ! replaces an old one, and readies it for the data storage + ! of the grid and the flow variable(s) associated with the + ! current time-step, t_step. This is performed by all the + ! local process(es). The root processor, in addition, must + ! also generate a master formatted database file whose job + ! will be to link, and thus combine, the data from all of + ! the local process(es). Note that for the Binary format, + ! this extra task that is assigned to the root process is + ! not performed in multidimensions. + + ! Time-step that is currently being post-processed + integer, intent(IN) :: t_step + + ! Generic string used to store the location of a particular file character(LEN=len_trim(case_dir) + 3*name_len) :: file_loc - integer :: ierr + + integer :: ierr !< Generic flag used to identify and report database errors + + ! Silo-HDF5 Database Format if (format == 1) then + + ! Generating the relative path to the formatted database slave + ! file, that is to be opened for the current time-step, t_step write (file_loc, '(A,I0,A)') '/', t_step, '.silo' - file_loc = trim(proc_rank_dir) // trim(file_loc) + file_loc = trim(proc_rank_dir)//trim(file_loc) - ierr = DBCREATE(trim(file_loc), len_trim(file_loc), DB_CLOBBER, DB_LOCAL, 'MFC v3.0', 8, DB_HDF5, dbfile) + ! Creating formatted database slave file at the above location + ! and setting up the structure of the file and its header info + ierr = DBCREATE(trim(file_loc), len_trim(file_loc), & + DB_CLOBBER, DB_LOCAL, 'MFC v3.0', 8, & + DB_HDF5, dbfile) + ! Verifying that the creation and setup process of the formatted + ! database slave file has been performed without errors. If this + ! is not the case, the post-process exits. if (dbfile == -1) then - call s_mpi_abort('Unable to create Silo-HDF5 database ' // 'slave file ' // trim(file_loc) // '. ' // 'Exiting.') + call s_mpi_abort('Unable to create Silo-HDF5 database '// & + 'slave file '//trim(file_loc)//'. '// & + 'Exiting.') end if + ! Next, analogous steps to the ones above are carried out by the + ! root process to create and setup the formatted database master + ! file. if (proc_rank == 0) then + write (file_loc, '(A,I0,A)') '/collection_', t_step, '.silo' - file_loc = trim(rootdir) // trim(file_loc) + file_loc = trim(rootdir)//trim(file_loc) - ierr = DBCREATE(trim(file_loc), len_trim(file_loc), DB_CLOBBER, DB_LOCAL, 'MFC v3.0', 8, DB_HDF5, dbroot) + ierr = DBCREATE(trim(file_loc), len_trim(file_loc), & + DB_CLOBBER, DB_LOCAL, 'MFC v3.0', 8, & + DB_HDF5, dbroot) if (dbroot == -1) then - call s_mpi_abort('Unable to create Silo-HDF5 database ' // 'master file ' // trim(file_loc) // '. ' & - & // 'Exiting.') + call s_mpi_abort('Unable to create Silo-HDF5 database '// & + 'master file '//trim(file_loc)//'. '// & + 'Exiting.') end if + end if + + ! Binary Database Format + else + + ! Generating the relative path to the formatted database slave + ! file, that is to be opened for the current time-step, t_step write (file_loc, '(A,I0,A)') '/', t_step, '.dat' - file_loc = trim(proc_rank_dir) // trim(file_loc) + file_loc = trim(proc_rank_dir)//trim(file_loc) - open (dbfile, IOSTAT=err, FILE=trim(file_loc), form='unformatted', STATUS='replace') + ! Creating the formatted database slave file, at the previously + ! precised relative path location, and setting up its structure + open (dbfile, IOSTAT=err, FILE=trim(file_loc), & + FORM='unformatted', STATUS='replace') + ! Verifying that the creation and setup process of the formatted + ! database slave file has been performed without errors. If this + ! is not the case, the post-process exits. if (err /= 0) then - call s_mpi_abort('Unable to create Binary database slave ' // 'file ' // trim(file_loc) // '. Exiting.') + call s_mpi_abort('Unable to create Binary database slave '// & + 'file '//trim(file_loc)//'. Exiting.') end if + ! Further defining the structure of the formatted database slave + ! file by describing in it the dimensionality of post-processed + ! data as well as the total number of flow variable(s) that will + ! eventually be stored in it if (output_partial_domain) then - write (dbfile) x_output_idx%end - x_output_idx%beg, y_output_idx%end - y_output_idx%beg, & - & z_output_idx%end - z_output_idx%beg, dbvars + write (dbfile) x_output_idx%end - x_output_idx%beg, & + y_output_idx%end - y_output_idx%beg, & + z_output_idx%end - z_output_idx%beg, & + dbvars else write (dbfile) m, n, p, dbvars end if + ! Next, analogous steps to the ones above are carried out by the + ! root process to create and setup the formatted database master + ! file. Note that this is only done in multidimensional cases. if (n == 0 .and. proc_rank == 0) then + write (file_loc, '(A,I0,A)') '/', t_step, '.dat' - file_loc = trim(rootdir) // trim(file_loc) + file_loc = trim(rootdir)//trim(file_loc) - open (dbroot, IOSTAT=err, FILE=trim(file_loc), form='unformatted', STATUS='replace') + open (dbroot, IOSTAT=err, FILE=trim(file_loc), & + FORM='unformatted', STATUS='replace') if (err /= 0) then - call s_mpi_abort('Unable to create Binary database ' // 'master file ' // trim(file_loc) // '. Exiting.') + call s_mpi_abort('Unable to create Binary database '// & + 'master file '//trim(file_loc)// & + '. Exiting.') end if if (output_partial_domain) then @@ -408,140 +597,221 @@ contains else write (dbroot) m_root, 0, 0, dbvars end if + end if + end if end subroutine s_open_formatted_database_file - !> Open the interface data file for appending extracted interface coordinates. + !> @brief Open the interface data file for appending extracted interface coordinates. impure subroutine s_open_intf_data_file() - character(LEN=path_len + 3*name_len) :: file_path + character(LEN=path_len + 3*name_len) :: file_path !< + !! Relative path to a file in the case directory write (file_path, '(A)') '/intf_data.dat' - file_path = trim(case_dir) // trim(file_path) + file_path = trim(case_dir)//trim(file_path) - open (211, FILE=trim(file_path), form='formatted', POSITION='append', STATUS='unknown') + ! Opening the simulation data file + open (211, FILE=trim(file_path), & + FORM='formatted', & + POSITION='append', & + STATUS='unknown') end subroutine s_open_intf_data_file - !> Open the energy data file for appending volume-integrated energy budget quantities. + !> @brief Open the energy data file for appending volume-integrated energy budget quantities. impure subroutine s_open_energy_data_file() - character(LEN=path_len + 3*name_len) :: file_path + character(LEN=path_len + 3*name_len) :: file_path !< + !! Relative path to a file in the case directory write (file_path, '(A)') '/eng_data.dat' - file_path = trim(case_dir) // trim(file_path) + file_path = trim(case_dir)//trim(file_path) - open (251, FILE=trim(file_path), form='formatted', POSITION='append', STATUS='unknown') + ! Opening the simulation data file + open (251, FILE=trim(file_path), & + FORM='formatted', & + POSITION='append', & + STATUS='unknown') end subroutine s_open_energy_data_file - !> Write the computational grid (cell-boundary coordinates) to the formatted database slave and master files. + !> @brief Write the computational grid (cell-boundary coordinates) to the formatted database slave and master files. impure subroutine s_write_grid_to_formatted_database_file(t_step) + ! Description: The general objective of this subroutine is to write the + ! necessary grid data to the formatted database file, for + ! the current time-step, t_step. The local processor will + ! write the grid data of the domain segment that it is in + ! charge of to the formatted database slave file. The root + ! process will additionally take care of linking that grid + ! data in the formatted database master file. In the Silo- + ! HDF5 database format, the spatial extents of each local + ! process grid are also written to the master file. In the + ! Binary format, note that no master file is maintained in + ! multidimensions. Finally, in 1D, no grid data is written + ! within this subroutine for the Silo-HDF5 format because + ! curve objects rather than quadrilateral meshes are used. + ! For curve objects, in contrast to the quadrilateral mesh + ! objects, the grid data is included side by side with the + ! flow variable data. Then, in this case, we take care of + ! writing both the grid and the flow variable data in the + ! subroutine s_write_variable_to_formatted_database_file. + + ! Time-step that is currently being post-processed + integer, intent(IN) :: t_step + + ! Bookkeeping variables storing the name and type of mesh that is + ! handled by the local processor(s). Note that due to an internal + ! NAG Fortran compiler problem, these two variables could not be + ! allocated dynamically. + character(LEN=4*name_len), dimension(num_procs) :: meshnames + integer, dimension(num_procs) :: meshtypes - integer, intent(in) :: t_step + ! Generic loop iterator + integer :: i - ! NAG compiler requires these to be statically sized - character(LEN=4*name_len), dimension(num_procs) :: meshnames - integer, dimension(num_procs) :: meshtypes - integer :: i - integer :: ierr + integer :: ierr !< Generic flag used to identify and report database errors + + ! Silo-HDF5 Database Format if (format == 1) then - ! For multidimensional data sets, the spatial extents of all of the grid(s) handled by the local processor(s) are - ! recorded so that they may be written, by root processor, to the formatted database master file. + + ! For multidimensional data sets, the spatial extents of all of + ! the grid(s) handled by the local processor(s) are recorded so + ! that they may be written, by root processor, to the formatted + ! database master file. if (num_procs > 1) then call s_mpi_gather_spatial_extents(spatial_extents) - else if (p > 0) then + elseif (p > 0) then if (grid_geometry == 3) then - spatial_extents(:,0) = (/minval(y_cb), minval(z_cb), minval(x_cb), maxval(y_cb), maxval(z_cb), maxval(x_cb)/) + spatial_extents(:, 0) = (/minval(y_cb), minval(z_cb), & + minval(x_cb), maxval(y_cb), & + maxval(z_cb), maxval(x_cb)/) else - spatial_extents(:,0) = (/minval(x_cb), minval(y_cb), minval(z_cb), maxval(x_cb), maxval(y_cb), maxval(z_cb)/) + spatial_extents(:, 0) = (/minval(x_cb), minval(y_cb), & + minval(z_cb), maxval(x_cb), & + maxval(y_cb), maxval(z_cb)/) end if - else if (n > 0) then - spatial_extents(:,0) = (/minval(x_cb), minval(y_cb), maxval(x_cb), maxval(y_cb)/) + elseif (n > 0) then + spatial_extents(:, 0) = (/minval(x_cb), minval(y_cb), & + maxval(x_cb), maxval(y_cb)/) else - spatial_extents(:,0) = (/minval(x_cb), maxval(x_cb)/) + spatial_extents(:, 0) = (/minval(x_cb), maxval(x_cb)/) end if - ! Next, the root processor proceeds to record all of the spatial extents in the formatted database master file. In - ! addition, it also records a sub-domain connectivity map so that the entire grid may be reassembled by looking at the - ! master file. + ! Next, the root processor proceeds to record all of the spatial + ! extents in the formatted database master file. In addition, it + ! also records a sub-domain connectivity map so that the entire + ! grid may be reassembled by looking at the master file. if (proc_rank == 0) then + do i = 1, num_procs - write (meshnames(i), '(A,I0,A,I0,A)') '../p', i - 1, '/', t_step, '.silo:rectilinear_grid' + write (meshnames(i), '(A,I0,A,I0,A)') '../p', i - 1, & + '/', t_step, '.silo:rectilinear_grid' end do meshtypes = DB_QUAD_RECT err = DBSET2DSTRLEN(len(meshnames(1))) err = DBMKOPTLIST(2, optlist) - err = DBADDIOPT(optlist, DBOPT_EXTENTS_SIZE, size(spatial_extents, 1)) + err = DBADDIOPT(optlist, DBOPT_EXTENTS_SIZE, & + size(spatial_extents, 1)) err = DBADDDOPT(optlist, DBOPT_EXTENTS, spatial_extents) - err = DBPUTMMESH(dbroot, 'rectilinear_grid', 16, num_procs, meshnames, len_trim(meshnames), meshtypes, optlist, & - & ierr) + err = DBPUTMMESH(dbroot, 'rectilinear_grid', 16, & + num_procs, meshnames, & + len_trim(meshnames), & + meshtypes, optlist, ierr) err = DBFREEOPTLIST(optlist) + end if - ! Finally, the local quadrilateral mesh, either 2D or 3D, along with its offsets that indicate the presence and size of - ! ghost zone layer(s), are put in the formatted database slave file. + ! Finally, the local quadrilateral mesh, either 2D or 3D, along + ! with its offsets that indicate the presence and size of ghost + ! zone layer(s), are put in the formatted database slave file. if (p > 0) then err = DBMKOPTLIST(2, optlist) err = DBADDIOPT(optlist, DBOPT_LO_OFFSET, lo_offset) err = DBADDIOPT(optlist, DBOPT_HI_OFFSET, hi_offset) if (grid_geometry == 3) then - err = DBPUTQM(dbfile, 'rectilinear_grid', 16, 'x', 1, 'y', 1, 'z', 1, y_cb, z_cb, x_cb, dims, 3, DB_DOUBLE, & - & DB_COLLINEAR, optlist, ierr) + err = DBPUTQM(dbfile, 'rectilinear_grid', 16, & + 'x', 1, 'y', 1, 'z', 1, & + y_cb, z_cb, x_cb, dims, 3, & + DB_DOUBLE, DB_COLLINEAR, & + optlist, ierr) else - err = DBPUTQM(dbfile, 'rectilinear_grid', 16, 'x', 1, 'y', 1, 'z', 1, x_cb, y_cb, z_cb, dims, 3, DB_DOUBLE, & - & DB_COLLINEAR, optlist, ierr) + err = DBPUTQM(dbfile, 'rectilinear_grid', 16, & + 'x', 1, 'y', 1, 'z', 1, & + x_cb, y_cb, z_cb, dims, 3, & + DB_DOUBLE, DB_COLLINEAR, & + optlist, ierr) end if err = DBFREEOPTLIST(optlist) - else if (n > 0) then + elseif (n > 0) then err = DBMKOPTLIST(2, optlist) err = DBADDIOPT(optlist, DBOPT_LO_OFFSET, lo_offset) err = DBADDIOPT(optlist, DBOPT_HI_OFFSET, hi_offset) - err = DBPUTQM(dbfile, 'rectilinear_grid', 16, 'x', 1, 'y', 1, 'z', 1, x_cb, y_cb, DB_F77NULL, dims, 2, DB_DOUBLE, & - & DB_COLLINEAR, optlist, ierr) + err = DBPUTQM(dbfile, 'rectilinear_grid', 16, & + 'x', 1, 'y', 1, 'z', 1, & + x_cb, y_cb, DB_F77NULL, dims, 2, & + DB_DOUBLE, DB_COLLINEAR, & + optlist, ierr) err = DBFREEOPTLIST(optlist) else err = DBMKOPTLIST(2, optlist) err = DBADDIOPT(optlist, DBOPT_LO_OFFSET, lo_offset) err = DBADDIOPT(optlist, DBOPT_HI_OFFSET, hi_offset) - err = DBPUTQM(dbfile, 'rectilinear_grid', 16, 'x', 1, 'y', 1, 'z', 1, x_cb, DB_F77NULL, DB_F77NULL, dims, 1, & - & DB_DOUBLE, DB_COLLINEAR, optlist, ierr) + err = DBPUTQM(dbfile, 'rectilinear_grid', 16, & + 'x', 1, 'y', 1, 'z', 1, & + x_cb, DB_F77NULL, DB_F77NULL, dims, 1, & + DB_DOUBLE, DB_COLLINEAR, & + optlist, ierr) err = DBFREEOPTLIST(optlist) end if - else if (format == 2) then - ! Multidimensional local grid data is written to the formatted database slave file. Recall that no master file to - ! maintained in multidimensions. + ! END: Silo-HDF5 Database Format + + ! Binary Database Format + + elseif (format == 2) then + + ! Multidimensional local grid data is written to the formatted + ! database slave file. Recall that no master file to maintained + ! in multidimensions. if (p > 0) then if (precision == 1) then - write (dbfile) real(x_cb, sp), real(y_cb, sp), real(z_cb, sp) + write (dbfile) real(x_cb, sp), & + real(y_cb, sp), & + real(z_cb, sp) else if (output_partial_domain) then - write (dbfile) x_cb(x_output_idx%beg - 1:x_output_idx%end), y_cb(y_output_idx%beg - 1:y_output_idx%end), & - & z_cb(z_output_idx%beg - 1:z_output_idx%end) + write (dbfile) x_cb(x_output_idx%beg - 1:x_output_idx%end), & + y_cb(y_output_idx%beg - 1:y_output_idx%end), & + z_cb(z_output_idx%beg - 1:z_output_idx%end) else write (dbfile) x_cb, y_cb, z_cb end if end if - else if (n > 0) then + + elseif (n > 0) then if (precision == 1) then - write (dbfile) real(x_cb, sp), real(y_cb, sp) + write (dbfile) real(x_cb, sp), & + real(y_cb, sp) else if (output_partial_domain) then - write (dbfile) x_cb(x_output_idx%beg - 1:x_output_idx%end), y_cb(y_output_idx%beg - 1:y_output_idx%end) + write (dbfile) x_cb(x_output_idx%beg - 1:x_output_idx%end), & + y_cb(y_output_idx%beg - 1:y_output_idx%end) else write (dbfile) x_cb, y_cb end if end if - ! One-dimensional local grid data is written to the formatted database slave file. In addition, the local grid data - ! is put together by the root process and written to the master file. + ! One-dimensional local grid data is written to the formatted + ! database slave file. In addition, the local grid data is put + ! together by the root process and written to the master file. else + if (precision == 1) then write (dbfile) real(x_cb, sp) else @@ -569,34 +839,69 @@ contains end if end if end if + end if + end if end subroutine s_write_grid_to_formatted_database_file - !> Write a single flow variable field to the formatted database slave and master files for a given time step. + !> @brief Write a single flow variable field to the formatted database slave and master files for a given time step. impure subroutine s_write_variable_to_formatted_database_file(varname, t_step) + ! Description: The goal of this subroutine is to write to the formatted + ! database file the flow variable at the current time-step, + ! t_step. The local process(es) write the part of the flow + ! variable that they handle to the formatted database slave + ! file. The root process, on the other hand, will also take + ! care of connecting all of the flow variable data in the + ! formatted database master file. In the Silo-HDF5 database + ! format, the extents of each local process flow variable + ! are also written to the master file. Note that in Binary + ! format, no master file is maintained in multidimensions. + ! Finally note that in 1D, grid data is also written within + ! this subroutine for Silo-HDF5 database format since curve + ! and not the quadrilateral variable objects are used, see + ! description of s_write_grid_to_formatted_database_file + ! for more details on this topic. + + ! Name of the flow variable, which will be written to the formatted + ! database file at the current time-step, t_step + character(LEN=*), intent(IN) :: varname + + ! Time-step that is currently being post-processed + integer, intent(IN) :: t_step + + ! Bookkeeping variables storing the name and type of flow variable + ! that is about to be handled by the local processor(s). Note that + ! due to an internal NAG Fortran compiler problem, these variables + ! could not be allocated dynamically. + character(LEN=4*name_len), dimension(num_procs) :: varnames + integer, dimension(num_procs) :: vartypes - character(LEN=*), intent(in) :: varname - integer, intent(in) :: t_step + ! Generic loop iterator + integer :: i, j, k - ! NAG compiler requires these to be statically sized - character(LEN=4*name_len), dimension(num_procs) :: varnames - integer, dimension(num_procs) :: vartypes - integer :: i, j, k - integer :: ierr + integer :: ierr !< Generic flag used to identify and report database errors + + ! Silo-HDF5 Database Format if (format == 1) then - ! Determining the extents of the flow variable on each local process and gathering all this information on root process + + ! Determining the extents of the flow variable on each local + ! process and gathering all this information on root process if (num_procs > 1) then call s_mpi_gather_data_extents(q_sf, data_extents) else - data_extents(:,0) = (/minval(q_sf), maxval(q_sf)/) + data_extents(:, 0) = (/minval(q_sf), maxval(q_sf)/) end if + ! Next, the root process proceeds to write the gathered flow + ! variable data extents to formatted database master file. if (proc_rank == 0) then + do i = 1, num_procs - write (varnames(i), '(A,I0,A,I0,A)') '../p', i - 1, '/', t_step, '.silo:' // trim(varname) + write (varnames(i), '(A,I0,A,I0,A)') '../p', i - 1, & + '/', t_step, '.silo:'//trim(varname) end do vartypes = DB_QUADVAR @@ -605,11 +910,17 @@ contains err = DBMKOPTLIST(2, optlist) err = DBADDIOPT(optlist, DBOPT_EXTENTS_SIZE, 2) err = DBADDDOPT(optlist, DBOPT_EXTENTS, data_extents) - err = DBPUTMVAR(dbroot, trim(varname), len_trim(varname), num_procs, varnames, len_trim(varnames), vartypes, & - & optlist, ierr) + err = DBPUTMVAR(dbroot, trim(varname), & + len_trim(varname), num_procs, & + varnames, len_trim(varnames), & + vartypes, optlist, ierr) err = DBFREEOPTLIST(optlist) + end if + ! Finally, each of the local processor(s) proceeds to write + ! the flow variable data that it is responsible for to the + ! formatted database slave file. if (wp == dp) then if (precision == 1) then do i = -offset_x%beg, m + offset_x%end @@ -639,7 +950,7 @@ contains end do end if end if - else if (wp == sp) then + elseif (wp == sp) then do i = -offset_x%beg, m + offset_x%end do j = -offset_y%beg, n + offset_y%end do k = -offset_z%beg, p + offset_z%end @@ -662,37 +973,62 @@ contains if (precision == ${PRECISION}$) then if (p > 0) then if (grid_geometry == 3) then - err = DBPUTQV1(dbfile, trim(varname), len_trim(varname), 'rectilinear_grid', 16, cyl_q_sf${SFX}$, & - & dims - 1, 3, DB_F77NULL, 0, ${DBT}$, DB_ZONECENT, DB_F77NULL, ierr) + err = DBPUTQV1(dbfile, trim(varname), & + len_trim(varname), & + 'rectilinear_grid', 16, & + cyl_q_sf${SFX}$, dims - 1, 3, DB_F77NULL, & + 0, ${DBT}$, DB_ZONECENT, & + DB_F77NULL, ierr) else - err = DBPUTQV1(dbfile, trim(varname), len_trim(varname), 'rectilinear_grid', 16, q_sf${SFX}$, & - & dims - 1, 3, DB_F77NULL, 0, ${DBT}$, DB_ZONECENT, DB_F77NULL, ierr) + err = DBPUTQV1(dbfile, trim(varname), & + len_trim(varname), & + 'rectilinear_grid', 16, & + q_sf${SFX}$, dims - 1, 3, DB_F77NULL, & + 0, ${DBT}$, DB_ZONECENT, & + DB_F77NULL, ierr) end if - else if (n > 0) then - err = DBPUTQV1(dbfile, trim(varname), len_trim(varname), 'rectilinear_grid', 16, q_sf${SFX}$, dims - 1, & - & 2, DB_F77NULL, 0, ${DBT}$, DB_ZONECENT, DB_F77NULL, ierr) + elseif (n > 0) then + err = DBPUTQV1(dbfile, trim(varname), & + len_trim(varname), & + 'rectilinear_grid', 16, & + q_sf${SFX}$, dims - 1, 2, DB_F77NULL, & + 0, ${DBT}$, DB_ZONECENT, & + DB_F77NULL, ierr) else - err = DBPUTQV1(dbfile, trim(varname), len_trim(varname), 'rectilinear_grid', 16, q_sf${SFX}$, dims - 1, & - & 1, DB_F77NULL, 0, ${DBT}$, DB_ZONECENT, DB_F77NULL, ierr) + err = DBPUTQV1(dbfile, trim(varname), & + len_trim(varname), & + 'rectilinear_grid', 16, & + q_sf${SFX}$, dims - 1, 1, DB_F77NULL, & + 0, ${DBT}$, DB_ZONECENT, & + DB_F77NULL, ierr) + end if end if #:endfor + + ! END: Silo-HDF5 Database Format + + ! Binary Database Format + else - ! Writing the name of the flow variable and its data, associated with the local processor, to the formatted database - ! slave file + + ! Writing the name of the flow variable and its data, associated + ! with the local processor, to the formatted database slave file if (precision == 1) then write (dbfile) varname, real(q_sf, wp) else write (dbfile) varname, q_sf end if - ! In 1D, the root process also takes care of gathering the flow variable data from all of the local processor(s) and - ! writes it to the formatted database master file. + ! In 1D, the root process also takes care of gathering the flow + ! variable data from all of the local processor(s) and writes it + ! to the formatted database master file. if (n == 0) then + if (num_procs > 1) then call s_mpi_defragment_1d_flow_variable(q_sf, q_root_sf) else - q_root_sf(:,:,:) = q_sf(:,:,:) + q_root_sf(:, :, :) = q_sf(:, :, :) end if if (proc_rank == 0) then @@ -702,50 +1038,58 @@ contains write (dbroot) varname, q_root_sf end if end if + end if + end if end subroutine s_write_variable_to_formatted_database_file - !> Write the post-processed results in the folder 'lag_bubbles_data' + !> Subroutine that writes the post processed results in the folder 'lag_bubbles_data' + !! @param t_step Current time step impure subroutine s_write_lag_bubbles_results_to_text(t_step) - integer, intent(in) :: t_step + integer, intent(in) :: t_step + character(len=len_trim(case_dir) + 3*name_len) :: file_loc - integer :: id + + integer :: id #ifdef MFC_MPI - real(wp), dimension(20) :: inputvals - real(wp) :: time_real - integer, dimension(MPI_STATUS_SIZE) :: status - integer(KIND=MPI_OFFSET_KIND) :: disp - integer :: view - logical :: lg_bub_file, file_exist - integer, dimension(2) :: gsizes, lsizes, start_idx_part - integer :: ifile - integer :: ierr - real(wp) :: file_time, file_dt - integer :: file_num_procs, file_tot_part, tot_part - integer :: i - integer, dimension(:), allocatable :: proc_bubble_counts - real(wp), dimension(1:1,1:lag_io_vars) :: lag_io_null + real(wp), dimension(20) :: inputvals + real(wp) :: time_real + integer, dimension(MPI_STATUS_SIZE) :: status + integer(KIND=MPI_OFFSET_KIND) :: disp + integer :: view + + logical :: lg_bub_file, file_exist + + integer, dimension(2) :: gsizes, lsizes, start_idx_part + integer :: ifile + integer :: ierr !< Generic flag used to identify and report MPI errors + real(wp) :: file_time, file_dt + integer :: file_num_procs, file_tot_part, tot_part + integer :: i + integer, dimension(:), allocatable :: proc_bubble_counts + real(wp), dimension(1:1, 1:lag_io_vars) :: lag_io_null lag_io_null = 0._wp ! Construct file path write (file_loc, '(A,I0,A)') 'lag_bubbles_', t_step, '.dat' - file_loc = trim(case_dir) // '/restart_data' // trim(mpiiofs) // trim(file_loc) + file_loc = trim(case_dir)//'/restart_data'//trim(mpiiofs)//trim(file_loc) ! Check if file exists inquire (FILE=trim(file_loc), EXIST=file_exist) if (.not. file_exist) then - call s_mpi_abort('Restart file ' // trim(file_loc) // ' does not exist!') + call s_mpi_abort('Restart file '//trim(file_loc)//' does not exist!') end if if (.not. parallel_io) return if (proc_rank == 0) then - call MPI_FILE_OPEN(MPI_COMM_SELF, file_loc, MPI_MODE_RDONLY, mpi_info_int, ifile, ierr) + call MPI_FILE_OPEN(MPI_COMM_SELF, file_loc, MPI_MODE_RDONLY, & + mpi_info_int, ifile, ierr) call MPI_FILE_READ(ifile, file_tot_part, 1, MPI_INTEGER, status, ierr) call MPI_FILE_READ(ifile, file_time, 1, mpi_p, status, ierr) @@ -764,10 +1108,12 @@ contains allocate (proc_bubble_counts(file_num_procs)) if (proc_rank == 0) then - call MPI_FILE_OPEN(MPI_COMM_SELF, file_loc, MPI_MODE_RDONLY, mpi_info_int, ifile, ierr) + call MPI_FILE_OPEN(MPI_COMM_SELF, file_loc, MPI_MODE_RDONLY, & + mpi_info_int, ifile, ierr) ! Skip to processor counts position - disp = int(sizeof(file_tot_part) + 2*sizeof(file_time) + sizeof(file_num_procs), MPI_OFFSET_KIND) + disp = int(sizeof(file_tot_part) + 2*sizeof(file_time) + sizeof(file_num_procs), & + MPI_OFFSET_KIND) call MPI_FILE_SEEK(ifile, disp, MPI_SEEK_SET, ierr) call MPI_FILE_READ(ifile, proc_bubble_counts, file_num_procs, MPI_INTEGER, status, ierr) @@ -783,21 +1129,25 @@ contains start_idx_part(1) = 0 start_idx_part(2) = 0 - call MPI_TYPE_CREATE_SUBARRAY(2, gsizes, lsizes, start_idx_part, MPI_ORDER_FORTRAN, mpi_p, view, ierr) + call MPI_TYPE_CREATE_SUBARRAY(2, gsizes, lsizes, start_idx_part, & + MPI_ORDER_FORTRAN, mpi_p, view, ierr) call MPI_TYPE_COMMIT(view, ierr) - call MPI_FILE_OPEN(MPI_COMM_WORLD, file_loc, MPI_MODE_RDONLY, mpi_info_int, ifile, ierr) + call MPI_FILE_OPEN(MPI_COMM_WORLD, file_loc, MPI_MODE_RDONLY, & + mpi_info_int, ifile, ierr) - disp = int(sizeof(file_tot_part) + 2*sizeof(file_time) + sizeof(file_num_procs) & - & + file_num_procs*sizeof(proc_bubble_counts(1)), MPI_OFFSET_KIND) - call MPI_FILE_SET_VIEW(ifile, disp, mpi_p, view, 'native', mpi_info_null, ierr) + disp = int(sizeof(file_tot_part) + 2*sizeof(file_time) + sizeof(file_num_procs) + & + file_num_procs*sizeof(proc_bubble_counts(1)), MPI_OFFSET_KIND) + call MPI_FILE_SET_VIEW(ifile, disp, mpi_p, view, & + 'native', mpi_info_null, ierr) - allocate (MPI_IO_DATA_lg_bubbles(file_tot_part,1:lag_io_vars)) + allocate (MPI_IO_DATA_lg_bubbles(file_tot_part, 1:lag_io_vars)) - call MPI_FILE_READ_ALL(ifile, MPI_IO_DATA_lg_bubbles, lag_io_vars*file_tot_part, mpi_p, status, ierr) + call MPI_FILE_READ_ALL(ifile, MPI_IO_DATA_lg_bubbles, lag_io_vars*file_tot_part, & + mpi_p, status, ierr) write (file_loc, '(A,I0,A)') 'lag_bubbles_post_process_', t_step, '.dat' - file_loc = trim(case_dir) // '/lag_bubbles_post_process/' // trim(file_loc) + file_loc = trim(case_dir)//'/lag_bubbles_post_process/'//trim(file_loc) if (proc_rank == 0) then open (unit=29, file=file_loc, form='formatted', position='rewind') @@ -824,16 +1174,13 @@ contains do i = 1, file_tot_part id = int(MPI_IO_DATA_lg_bubbles(i, 1)) - inputvals(1:20) = MPI_IO_DATA_lg_bubbles(i,2:21) + inputvals(1:20) = MPI_IO_DATA_lg_bubbles(i, 2:21) if (id > 0) then write (29, '(100(A))', advance='no') '' if (lag_id_wrt) write (29, '(I6, A)', advance='no') id, ', ' - if (lag_pos_wrt) write (29, '(3(E15.7, A))', advance='no') inputvals(1), ', ', inputvals(2), ', ', & - & inputvals(3), ', ' - if (lag_pos_prev_wrt) write (29, '(3(E15.7, A))', advance='no') inputvals(4), ', ', inputvals(5), ', ', & - & inputvals(6), ', ' - if (lag_vel_wrt) write (29, '(3(E15.7, A))', advance='no') inputvals(7), ', ', inputvals(8), ', ', & - & inputvals(9), ', ' + if (lag_pos_wrt) write (29, '(3(E15.7, A))', advance='no') inputvals(1), ', ', inputvals(2), ', ', inputvals(3), ', ' + if (lag_pos_prev_wrt) write (29, '(3(E15.7, A))', advance='no') inputvals(4), ', ', inputvals(5), ', ', inputvals(6), ', ' + if (lag_vel_wrt) write (29, '(3(E15.7, A))', advance='no') inputvals(7), ', ', inputvals(8), ', ', inputvals(9), ', ' if (lag_rad_wrt) write (29, '(E15.7, A)', advance='no') inputvals(10), ', ' if (lag_rvel_wrt) write (29, '(E15.7, A)', advance='no') inputvals(11), ', ' if (lag_r0_wrt) write (29, '(E15.7, A)', advance='no') inputvals(12), ', ' @@ -860,52 +1207,59 @@ contains end subroutine s_write_lag_bubbles_results_to_text - !> Read Lagrangian bubble restart data and write bubble positions and scalar fields to the Silo database. + !> @brief Read Lagrangian bubble restart data and write bubble positions and scalar fields to the Silo database. impure subroutine s_write_lag_bubbles_to_formatted_database_file(t_step) - integer, intent(in) :: t_step + integer, intent(in) :: t_step + character(len=len_trim(case_dir) + 3*name_len) :: file_loc - integer :: id + + integer :: id #ifdef MFC_MPI - real(wp), dimension(20) :: inputvals - real(wp) :: time_real - integer, dimension(MPI_STATUS_SIZE) :: status - integer(KIND=MPI_OFFSET_KIND) :: disp - integer :: view - logical :: lg_bub_file, file_exist - integer, dimension(2) :: gsizes, lsizes, start_idx_part - integer :: ifile, ierr, tot_data, valid_data, nBub - real(wp) :: file_time, file_dt - integer :: file_num_procs, file_tot_part - integer, dimension(:), allocatable :: proc_bubble_counts - real(wp), dimension(1:1,1:lag_io_vars) :: dummy + real(wp), dimension(20) :: inputvals + real(wp) :: time_real + integer, dimension(MPI_STATUS_SIZE) :: status + integer(KIND=MPI_OFFSET_KIND) :: disp + integer :: view + + logical :: lg_bub_file, file_exist + + integer, dimension(2) :: gsizes, lsizes, start_idx_part + integer :: ifile, ierr, tot_data, valid_data, nBub + real(wp) :: file_time, file_dt + integer :: file_num_procs, file_tot_part + integer, dimension(:), allocatable :: proc_bubble_counts + real(wp), dimension(1:1, 1:lag_io_vars) :: dummy character(LEN=4*name_len), dimension(num_procs) :: meshnames - integer, dimension(num_procs) :: meshtypes - real(wp) :: dummy_data - integer :: i, j - real(wp), dimension(:), allocatable :: bub_id - real(wp), dimension(:), allocatable :: px, py, pz, ppx, ppy, ppz, vx, vy, vz - real(wp), dimension(:), allocatable :: radius, rvel, rnot, rmax, rmin, dphidt - real(wp), dimension(:), allocatable :: pressure, mv, mg, betaT, betaC + integer, dimension(num_procs) :: meshtypes + real(wp) :: dummy_data + + integer :: i, j + + real(wp), dimension(:), allocatable :: bub_id + real(wp), dimension(:), allocatable :: px, py, pz, ppx, ppy, ppz, vx, vy, vz + real(wp), dimension(:), allocatable :: radius, rvel, rnot, rmax, rmin, dphidt + real(wp), dimension(:), allocatable :: pressure, mv, mg, betaT, betaC dummy = 0._wp dummy_data = 0._wp ! Construct file path write (file_loc, '(A,I0,A)') 'lag_bubbles_', t_step, '.dat' - file_loc = trim(case_dir) // '/restart_data' // trim(mpiiofs) // trim(file_loc) + file_loc = trim(case_dir)//'/restart_data'//trim(mpiiofs)//trim(file_loc) ! Check if file exists inquire (FILE=trim(file_loc), EXIST=file_exist) if (.not. file_exist) then - call s_mpi_abort('Restart file ' // trim(file_loc) // ' does not exist!') + call s_mpi_abort('Restart file '//trim(file_loc)//' does not exist!') end if if (.not. parallel_io) return if (proc_rank == 0) then - call MPI_FILE_OPEN(MPI_COMM_SELF, file_loc, MPI_MODE_RDONLY, mpi_info_int, ifile, ierr) + call MPI_FILE_OPEN(MPI_COMM_SELF, file_loc, MPI_MODE_RDONLY, & + mpi_info_int, ifile, ierr) call MPI_FILE_READ(ifile, file_tot_part, 1, MPI_INTEGER, status, ierr) call MPI_FILE_READ(ifile, file_time, 1, mpi_p, status, ierr) @@ -924,10 +1278,12 @@ contains allocate (proc_bubble_counts(file_num_procs)) if (proc_rank == 0) then - call MPI_FILE_OPEN(MPI_COMM_SELF, file_loc, MPI_MODE_RDONLY, mpi_info_int, ifile, ierr) + call MPI_FILE_OPEN(MPI_COMM_SELF, file_loc, MPI_MODE_RDONLY, & + mpi_info_int, ifile, ierr) ! Skip to processor counts position - disp = int(sizeof(file_tot_part) + 2*sizeof(file_time) + sizeof(file_num_procs), MPI_OFFSET_KIND) + disp = int(sizeof(file_tot_part) + 2*sizeof(file_time) + sizeof(file_num_procs), & + MPI_OFFSET_KIND) call MPI_FILE_SEEK(ifile, disp, MPI_SEEK_SET, ierr) call MPI_FILE_READ(ifile, proc_bubble_counts, file_num_procs, MPI_INTEGER, status, ierr) @@ -953,49 +1309,62 @@ contains gsizes(2) = lag_io_vars if (nBub > 0) then + #:for VAR in ['bub_id', 'px', 'py', 'pz', 'ppx', 'ppy', 'ppz', 'vx', 'vy', 'vz', & 'radius', 'rvel', 'rnot', 'rmax', 'rmin', 'dphidt', & 'pressure', 'mv', 'mg', 'betaT', 'betaC'] allocate (${VAR}$ (nBub)) #:endfor - allocate (MPI_IO_DATA_lg_bubbles(nBub,1:lag_io_vars)) + allocate (MPI_IO_DATA_lg_bubbles(nBub, 1:lag_io_vars)) - call MPI_TYPE_CREATE_SUBARRAY(2, gsizes, lsizes, start_idx_part, MPI_ORDER_FORTRAN, mpi_p, view, ierr) + call MPI_TYPE_CREATE_SUBARRAY(2, gsizes, lsizes, start_idx_part, & + MPI_ORDER_FORTRAN, mpi_p, view, ierr) call MPI_TYPE_COMMIT(view, ierr) - call MPI_FILE_OPEN(MPI_COMM_WORLD, file_loc, MPI_MODE_RDONLY, mpi_info_int, ifile, ierr) + call MPI_FILE_OPEN(MPI_COMM_WORLD, file_loc, MPI_MODE_RDONLY, & + mpi_info_int, ifile, ierr) ! Skip extended header - disp = int(sizeof(file_tot_part) + 2*sizeof(file_time) + sizeof(file_num_procs) & - & + file_num_procs*sizeof(proc_bubble_counts(1)), MPI_OFFSET_KIND) + disp = int(sizeof(file_tot_part) + 2*sizeof(file_time) + sizeof(file_num_procs) + & + file_num_procs*sizeof(proc_bubble_counts(1)), MPI_OFFSET_KIND) call MPI_FILE_SET_VIEW(ifile, disp, mpi_p, view, 'native', mpi_info_int, ierr) - call MPI_FILE_READ_ALL(ifile, MPI_IO_DATA_lg_bubbles, lag_io_vars*nBub, mpi_p, status, ierr) + call MPI_FILE_READ_ALL(ifile, MPI_IO_DATA_lg_bubbles, & + lag_io_vars*nBub, mpi_p, status, ierr) call MPI_FILE_CLOSE(ifile, ierr) call MPI_TYPE_FREE(view, ierr) - ! Extract data from MPI_IO_DATA_lg_bubbles array Adjust these indices based on your actual data layout + ! Extract data from MPI_IO_DATA_lg_bubbles array + ! Adjust these indices based on your actual data layout #:for VAR, IDX in [('bub_id', 1), ('px', 2), ('py',3), ('pz',4), ('ppx',5), ('ppy',6), ('ppz',7), & ('vx',8), ('vy',9), ('vz',10), ('radius',11), ('rvel',12), & ('rnot',13), ('rmax',14), ('rmin',15), ('dphidt',16), & ('pressure',17), ('mv',18), ('mg',19), ('betaT',20), ('betaC',21)] - ${VAR}$ (:) = MPI_IO_DATA_lg_bubbles(:,${IDX}$) + ${VAR}$ (:) = MPI_IO_DATA_lg_bubbles(:, ${IDX}$) #:endfor - ! Next, the root processor proceeds to record all of the spatial extents in the formatted database master file. In - ! addition, it also records a sub-domain connectivity map so that the entire grid may be reassembled by looking at the - ! master file. + ! Next, the root processor proceeds to record all of the spatial + ! extents in the formatted database master file. In addition, it + ! also records a sub-domain connectivity map so that the entire + ! grid may be reassembled by looking at the master file. if (proc_rank == 0) then + do i = 1, num_procs - write (meshnames(i), '(A,I0,A,I0,A)') '../p', i - 1, '/', t_step, '.silo:lag_bubbles' + write (meshnames(i), '(A,I0,A,I0,A)') '../p', i - 1, & + '/', t_step, '.silo:lag_bubbles' meshtypes(i) = DB_POINTMESH end do err = DBSET2DSTRLEN(len(meshnames(1))) - err = DBPUTMMESH(dbroot, 'lag_bubbles', 16, num_procs, meshnames, len_trim(meshnames), meshtypes, DB_F77NULL, ierr) + err = DBPUTMMESH(dbroot, 'lag_bubbles', 16, & + num_procs, meshnames, & + len_trim(meshnames), & + meshtypes, DB_F77NULL, ierr) end if - err = DBPUTPM(dbfile, 'lag_bubbles', 11, 3, px, py, pz, nBub, DB_DOUBLE, DB_F77NULL, ierr) + err = DBPUTPM(dbfile, 'lag_bubbles', 11, 3, & + px, py, pz, nBub, & + DB_DOUBLE, DB_F77NULL, ierr) if (lag_id_wrt) call s_write_lag_variable_to_formatted_database_file('part_id', t_step, bub_id, nBub) if (lag_vel_wrt) then @@ -1015,18 +1384,20 @@ contains if (lag_betaT_wrt) call s_write_lag_variable_to_formatted_database_file('part_betaT', t_step, betaT, nBub) if (lag_betaC_wrt) call s_write_lag_variable_to_formatted_database_file('part_betaC', t_step, betaC, nBub) - deallocate (bub_id, px, py, pz, ppx, ppy, ppz, vx, vy, vz, radius, rvel, rnot, rmax, rmin, dphidt, pressure, mv, mg, & - & betaT, betaC) + deallocate (bub_id, px, py, pz, ppx, ppy, ppz, vx, vy, vz, radius, & + rvel, rnot, rmax, rmin, dphidt, pressure, mv, mg, & + betaT, betaC) deallocate (MPI_IO_DATA_lg_bubbles) else call MPI_TYPE_CONTIGUOUS(0, mpi_p, view, ierr) call MPI_TYPE_COMMIT(view, ierr) - call MPI_FILE_OPEN(MPI_COMM_WORLD, file_loc, MPI_MODE_RDONLY, mpi_info_int, ifile, ierr) + call MPI_FILE_OPEN(MPI_COMM_WORLD, file_loc, MPI_MODE_RDONLY, & + mpi_info_int, ifile, ierr) ! Skip extended header - disp = int(sizeof(file_tot_part) + 2*sizeof(file_time) + sizeof(file_num_procs) & - & + file_num_procs*sizeof(proc_bubble_counts(1)), MPI_OFFSET_KIND) + disp = int(sizeof(file_tot_part) + 2*sizeof(file_time) + sizeof(file_num_procs) + & + file_num_procs*sizeof(proc_bubble_counts(1)), MPI_OFFSET_KIND) call MPI_FILE_SET_VIEW(ifile, disp, mpi_p, view, 'native', mpi_info_int, ierr) call MPI_FILE_READ_ALL(ifile, dummy, 0, mpi_p, status, ierr) @@ -1035,16 +1406,23 @@ contains call MPI_TYPE_FREE(view, ierr) if (proc_rank == 0) then + do i = 1, num_procs - write (meshnames(i), '(A,I0,A,I0,A)') '../p', i - 1, '/', t_step, '.silo:lag_bubbles' + write (meshnames(i), '(A,I0,A,I0,A)') '../p', i - 1, & + '/', t_step, '.silo:lag_bubbles' meshtypes(i) = DB_POINTMESH end do err = DBSET2DSTRLEN(len(meshnames(1))) - err = DBPUTMMESH(dbroot, 'lag_bubbles', 16, num_procs, meshnames, len_trim(meshnames), meshtypes, DB_F77NULL, ierr) + err = DBPUTMMESH(dbroot, 'lag_bubbles', 16, & + num_procs, meshnames, & + len_trim(meshnames), & + meshtypes, DB_F77NULL, ierr) end if err = DBSETEMPTYOK(1) - err = DBPUTPM(dbfile, 'lag_bubbles', 11, 3, dummy_data, dummy_data, dummy_data, 0, DB_DOUBLE, DB_F77NULL, ierr) + err = DBPUTPM(dbfile, 'lag_bubbles', 11, 3, & + dummy_data, dummy_data, dummy_data, 0, & + DB_DOUBLE, DB_F77NULL, ierr) if (lag_id_wrt) call s_write_lag_variable_to_formatted_database_file('part_id', t_step) if (lag_vel_wrt) then @@ -1064,95 +1442,110 @@ contains if (lag_betaT_wrt) call s_write_lag_variable_to_formatted_database_file('part_betaT', t_step) if (lag_betaC_wrt) call s_write_lag_variable_to_formatted_database_file('part_betaC', t_step) end if + #endif end subroutine s_write_lag_bubbles_to_formatted_database_file - !> Write a single Lagrangian bubble point-variable to the Silo database slave and master files. + !> @brief Write a single Lagrangian bubble point-variable to the Silo database slave and master files. subroutine s_write_lag_variable_to_formatted_database_file(varname, t_step, data, nBubs) - character(len=*), intent(in) :: varname - integer, intent(in) :: t_step + character(len=*), intent(in) :: varname + integer, intent(in) :: t_step real(wp), dimension(1:), intent(in), optional :: data - integer, intent(in), optional :: nBubs - character(len=64), dimension(num_procs) :: var_names - integer, dimension(num_procs) :: var_types - real(wp) :: dummy_data - integer :: ierr - integer :: i + integer, intent(in), optional :: nBubs + + character(len=64), dimension(num_procs) :: var_names + integer, dimension(num_procs) :: var_types + real(wp) :: dummy_data + + integer :: ierr !< Generic flag used to identify and report database errors + integer :: i dummy_data = 0._wp if (present(nBubs) .and. present(data)) then if (proc_rank == 0) then do i = 1, num_procs - write (var_names(i), '(A,I0,A,I0,A)') '../p', i - 1, '/', t_step, '.silo:' // trim(varname) + write (var_names(i), '(A,I0,A,I0,A)') '../p', i - 1, & + '/', t_step, '.silo:'//trim(varname) var_types(i) = DB_POINTVAR end do err = DBSET2DSTRLEN(len(var_names(1))) - err = DBPUTMVAR(dbroot, trim(varname), len_trim(varname), num_procs, var_names, len_trim(var_names), var_types, & - & DB_F77NULL, ierr) + err = DBPUTMVAR(dbroot, trim(varname), len_trim(varname), & + num_procs, var_names, & + len_trim(var_names), & + var_types, DB_F77NULL, ierr) end if - err = DBPUTPV1(dbfile, trim(varname), len_trim(varname), 'lag_bubbles', 11, data, nBubs, DB_DOUBLE, DB_F77NULL, ierr) + err = DBPUTPV1(dbfile, trim(varname), len_trim(varname), & + 'lag_bubbles', 11, data, nBubs, DB_DOUBLE, DB_F77NULL, ierr) else if (proc_rank == 0) then do i = 1, num_procs - write (var_names(i), '(A,I0,A,I0,A)') '../p', i - 1, '/', t_step, '.silo:' // trim(varname) + write (var_names(i), '(A,I0,A,I0,A)') '../p', i - 1, & + '/', t_step, '.silo:'//trim(varname) var_types(i) = DB_POINTVAR end do err = DBSET2DSTRLEN(len(var_names(1))) err = DBSETEMPTYOK(1) - err = DBPUTMVAR(dbroot, trim(varname), len_trim(varname), num_procs, var_names, len_trim(var_names), var_types, & - & DB_F77NULL, ierr) + err = DBPUTMVAR(dbroot, trim(varname), len_trim(varname), & + num_procs, var_names, & + len_trim(var_names), & + var_types, DB_F77NULL, ierr) end if err = DBSETEMPTYOK(1) - err = DBPUTPV1(dbfile, trim(varname), len_trim(varname), 'lag_bubbles', 11, dummy_data, 0, DB_DOUBLE, DB_F77NULL, ierr) + err = DBPUTPV1(dbfile, trim(varname), len_trim(varname), & + 'lag_bubbles', 11, dummy_data, 0, DB_DOUBLE, DB_F77NULL, ierr) end if end subroutine s_write_lag_variable_to_formatted_database_file - !> Convert the binary immersed-boundary state file to per-body formatted text files impure subroutine s_write_ib_state_files() character(len=len_trim(case_dir) + 4*name_len) :: in_file, out_file, file_loc - integer :: iu_in, ios, i, rec_id - integer, allocatable, dimension(:) :: iu_out - real(wp) :: rec_time - real(wp), dimension(3) :: rec_force, rec_torque - real(wp), dimension(3) :: rec_vel, rec_angular_vel - real(wp), dimension(3) :: rec_angles, rec_centroid - - file_loc = trim(case_dir) // '/D' - - in_file = trim(file_loc) // '/ib_state.dat' - open (newunit=iu_in, file=trim(in_file), form='unformatted', access='stream', status='old', action='read', iostat=ios) + integer :: iu_in, ios, i, rec_id + integer, allocatable, dimension(:) :: iu_out + real(wp) :: rec_time + real(wp), dimension(3) :: rec_force, rec_torque + real(wp), dimension(3) :: rec_vel, rec_angular_vel + real(wp), dimension(3) :: rec_angles, rec_centroid + + file_loc = trim(case_dir)//'/D' + + in_file = trim(file_loc)//'/ib_state.dat' + open (newunit=iu_in, file=trim(in_file), form='unformatted', access='stream', & + status='old', action='read', iostat=ios) if (ios /= 0) then - call s_mpi_abort('Cannot open IB state input file: ' // trim(in_file)) + call s_mpi_abort('Cannot open IB state input file: '//trim(in_file)) end if allocate (iu_out(num_ibs)) do i = 1, num_ibs - write (out_file, '(A,I0,A)') trim(file_loc) // '/ib_', i, '.txt' + write (out_file, '(A,I0,A)') trim(file_loc)//'/ib_', i, '.txt' open (newunit=iu_out(i), file=trim(out_file), form='formatted', status='replace', action='write', iostat=ios) if (ios /= 0) then - call s_mpi_abort('Cannot open IB state output file: ' // trim(out_file)) + call s_mpi_abort('Cannot open IB state output file: '//trim(out_file)) end if - write (iu_out(i), & - & '(A)') 'mytime fx fy fz Tau_x Tau_y Tau_z vx vy vz omega_x omega_y omega_z angle_x angle_y angle_z x_c y_c z_c' + write (iu_out(i), '(A)') & + 'mytime fx fy fz Tau_x Tau_y Tau_z vx vy vz omega_x omega_y omega_z angle_x angle_y angle_z x_c y_c z_c' end do do - read (iu_in, iostat=ios) rec_time, rec_id, rec_force, rec_torque, rec_vel, rec_angular_vel, rec_angles, & - & rec_centroid(1), rec_centroid(2), rec_centroid(3) + read (iu_in, iostat=ios) rec_time, rec_id, & + rec_force, rec_torque, rec_vel, rec_angular_vel, rec_angles, & + rec_centroid(1), rec_centroid(2), rec_centroid(3) if (ios /= 0) exit if (rec_id >= 1 .and. rec_id <= num_ibs) then - write (iu_out(rec_id), '(19(ES24.16E3,1X))') rec_time, rec_force(1), rec_force(2), rec_force(3), rec_torque(1), & - & rec_torque(2), rec_torque(3), rec_vel(1), rec_vel(2), rec_vel(3), rec_angular_vel(1), & - & rec_angular_vel(2), rec_angular_vel(3), rec_angles(1), rec_angles(2), rec_angles(3), rec_centroid(1), & - & rec_centroid(2), rec_centroid(3) + write (iu_out(rec_id), '(19(ES24.16E3,1X))') rec_time, & + rec_force(1), rec_force(2), rec_force(3), & + rec_torque(1), rec_torque(2), rec_torque(3), & + rec_vel(1), rec_vel(2), rec_vel(3), & + rec_angular_vel(1), rec_angular_vel(2), rec_angular_vel(3), & + rec_angles(1), rec_angles(2), rec_angles(3), & + rec_centroid(1), rec_centroid(2), rec_centroid(3) end if end do @@ -1164,12 +1557,12 @@ contains end subroutine s_write_ib_state_files - !> Extract the volume-fraction interface contour from primitive fields and write the coordinates to the interface data file. + !> @brief Extract the volume-fraction interface contour from primitive fields and write the coordinates to the interface data file. impure subroutine s_write_intf_data_file(q_prim_vf) - type(scalar_field), dimension(sys_size), intent(in) :: q_prim_vf - integer :: i, j, k, l, cent - integer :: counter, root !< number of data points extracted to fit shape to SH perturbations + type(scalar_field), dimension(sys_size), intent(IN) :: q_prim_vf + integer :: i, j, k, l, cent !< Generic loop iterators + integer :: counter, root !< number of data points extracted to fit shape to SH perturbations real(wp), allocatable :: x_td(:), y_td(:), x_d1(:), y_d1(:), y_d(:), x_d(:) real(wp) :: axp, axm, ayp, aym, tgp, euc_d, thres, maxalph_loc, maxalph_glb @@ -1205,8 +1598,8 @@ contains axm = q_prim_vf(E_idx + 2)%sf(j, k, cent) ayp = q_prim_vf(E_idx + 2)%sf(j, k + 1, cent) aym = q_prim_vf(E_idx + 2)%sf(j, k, cent) - if ((axp > thres .and. axm < thres) .or. (axp < thres .and. axm > thres) .or. (ayp > thres .and. aym < thres) & - & .or. (ayp < thres .and. aym > thres)) then + if ((axp > thres .and. axm < thres) .or. (axp < thres .and. axm > thres) & + .or. (ayp > thres .and. aym < thres) .or. (ayp < thres .and. aym > thres)) then if (counter == 0) then counter = counter + 1 x_d1(counter) = x_cc(j) @@ -1217,7 +1610,7 @@ contains euc_d = sqrt((x_cc(j) - x_d1(i))**2 + (y_cc(k) - y_d1(i))**2) if (euc_d < tgp) then exit - else if (i == counter) then + elseif (i == counter) then counter = counter + 1 x_d1(counter) = x_cc(j) y_d1(counter) = y_cc(k) @@ -1241,24 +1634,25 @@ contains if (proc_rank == 0) then do i = 1, size(x_td) if (i == size(x_td)) then - write (211, '(F12.9,1X,F12.9,1X,I4)') x_td(i), y_td(i), size(x_td) + write (211, '(F12.9,1X,F12.9,1X,I4)') & + x_td(i), y_td(i), size(x_td) else - write (211, '(F12.9,1X,F12.9,1X,F3.1)') x_td(i), y_td(i), 0._wp + write (211, '(F12.9,1X,F12.9,1X,F3.1)') & + x_td(i), y_td(i), 0._wp end if end do end if end subroutine s_write_intf_data_file - !> Compute volume-integrated kinetic, potential, and internal energies and write the energy budget to the energy data file. + !> @brief Compute volume-integrated kinetic, potential, and internal energies and write the energy budget to the energy data file. impure subroutine s_write_energy_data_file(q_prim_vf, q_cons_vf) - - type(scalar_field), dimension(sys_size), intent(in) :: q_prim_vf, q_cons_vf + type(scalar_field), dimension(sys_size), intent(IN) :: q_prim_vf, q_cons_vf real(wp) :: Elk, Egk, Elp, Egint, Vb, Vl, pres_av, Et real(wp) :: rho, pres, dV, tmp, gamma, pi_inf, MaxMa, MaxMa_glb, maxvel, c, Ma, H, qv real(wp), dimension(num_vels) :: vel real(wp), dimension(num_fluids) :: adv - integer :: i, j, k, l, s !< looping indices + integer :: i, j, k, l, s !looping indices Egk = 0._wp Elp = 0._wp @@ -1304,7 +1698,9 @@ contains H = ((gamma + 1._wp)*pres + pi_inf + qv)/rho - call s_compute_speed_of_sound(pres, rho, gamma, pi_inf, H, adv, 0._wp, 0._wp, c, qv) + call s_compute_speed_of_sound(pres, rho, & + gamma, pi_inf, & + H, adv, 0._wp, 0._wp, c, qv) Ma = maxvel/c if (Ma > MaxMa .and. (adv(1) > (1.0_wp - 1.0e-10_wp))) then @@ -1337,52 +1733,80 @@ contains Elp = pres_av/Vl*Vb if (proc_rank == 0) then - write (251, '(10X, 8F24.8)') Elp, Egint, Elk, Egk, Et, Vb, Vl, MaxMa_glb + write (251, '(10X, 8F24.8)') & + Elp, & + Egint, & + Elk, & + Egk, & + Et, & + Vb, & + Vl, & + MaxMa_glb end if end subroutine s_write_energy_data_file - !> Close the formatted database slave file and, for the root process, the master file. + !> @brief Close the formatted database slave file and, for the root process, the master file. impure subroutine s_close_formatted_database_file() - - integer :: ierr - + ! Description: The purpose of this subroutine is to close any formatted + ! database file(s) that may be opened at the time-step that + ! is currently being post-processed. The root process must + ! typically close two files, one associated with the local + ! sub-domain and the other with the entire domain. The non- + ! root process(es) must close one file, which is associated + ! with the local sub-domain. Note that for the Binary data- + ! base format and multidimensional data, the root process + ! only has to close the file associated with the local sub- + ! domain, because one associated with the entire domain is + ! not generated. + + integer :: ierr !< Generic flag used to identify and report database errors + + ! Silo-HDF5 database format if (format == 1) then ierr = DBCLOSE(dbfile) if (proc_rank == 0) ierr = DBCLOSE(dbroot) + + ! Binary database format else close (dbfile) if (n == 0 .and. proc_rank == 0) close (dbroot) + end if end subroutine s_close_formatted_database_file - !> Close the interface data file. + !> @brief Close the interface data file. impure subroutine s_close_intf_data_file() close (211) end subroutine s_close_intf_data_file - !> Close the energy data file. + !> @brief Close the energy data file. impure subroutine s_close_energy_data_file() close (251) end subroutine s_close_energy_data_file - !> Deallocate module arrays and release all data-output resources. + !> @brief Deallocate module arrays and release all data-output resources. impure subroutine s_finalize_data_output_module() + ! Description: Deallocation procedures for the module + ! Deallocating the generic storage employed for the flow variable(s) + ! that were written to the formatted database file(s). Note that the + ! root variable is only deallocated in the case of a 1D computation. deallocate (q_sf) if (n == 0) deallocate (q_root_sf) if (grid_geometry == 3) then deallocate (cyl_q_sf) end if - ! Deallocating spatial and data extents and also the variables for the offsets and the one bookkeeping the number of - ! cell-boundaries in each active coordinate direction. Note that all these variables were only needed by Silo-HDF5 format - ! for multidimensional data. + ! Deallocating spatial and data extents and also the variables for + ! the offsets and the one bookkeeping the number of cell-boundaries + ! in each active coordinate direction. Note that all these variables + ! were only needed by Silo-HDF5 format for multidimensional data. if (format == 1) then deallocate (spatial_extents) deallocate (data_extents) diff --git a/src/post_process/m_derived_variables.fpp b/src/post_process/m_derived_variables.fpp index daa9ca6dbf..0407d06485 100644 --- a/src/post_process/m_derived_variables.fpp +++ b/src/post_process/m_derived_variables.fpp @@ -6,54 +6,101 @@ module m_derived_variables - use m_derived_types - use m_global_parameters - use m_mpi_proxy - use m_helper_basic + use m_derived_types !< Definitions of the derived types + + use m_global_parameters !< Global parameters for the code + + use m_mpi_proxy !< Message passing interface (MPI) module proxy + + use m_helper_basic !< Functions to compare floating point numbers + use m_variables_conversion implicit none - private; public :: s_initialize_derived_variables_module, s_derive_specific_heat_ratio, s_derive_liquid_stiffness, & - & s_derive_sound_speed, s_derive_flux_limiter, s_derive_vorticity_component, s_derive_qm, s_derive_liutex, & - & s_derive_numerical_schlieren_function, s_compute_speed_of_sound, s_finalize_derived_variables_module - - real(wp), allocatable, dimension(:,:,:) :: gm_rho_sf !< Density gradient magnitude for numerical Schlieren - !> @name Finite-difference (fd) coefficients in x-, y- and z-coordinate directions. Note that because sufficient boundary - !! information is available for all the active coordinate directions, the centered family of the finite-difference schemes is - !! used. + private; public :: s_initialize_derived_variables_module, & + s_derive_specific_heat_ratio, & + s_derive_liquid_stiffness, & + s_derive_sound_speed, & + s_derive_flux_limiter, & + s_derive_vorticity_component, & + s_derive_qm, & + s_derive_liutex, & + s_derive_numerical_schlieren_function, & + s_compute_speed_of_sound, & + s_finalize_derived_variables_module + + real(wp), allocatable, dimension(:, :, :) :: gm_rho_sf !< + !! Gradient magnitude (gm) of the density for each cell of the computational + !! sub-domain. This variable is employed in the calculation of the numerical + !! Schlieren function. + + !> @name Finite-difference (fd) coefficients in x-, y- and z-coordinate directions. + !! Note that because sufficient boundary information is available for all the + !! active coordinate directions, the centered family of the finite-difference + !! schemes is used. !> @{ - real(wp), allocatable, dimension(:,:), public :: fd_coeff_x - real(wp), allocatable, dimension(:,:), public :: fd_coeff_y - real(wp), allocatable, dimension(:,:), public :: fd_coeff_z + real(wp), allocatable, dimension(:, :), public :: fd_coeff_x + real(wp), allocatable, dimension(:, :), public :: fd_coeff_y + real(wp), allocatable, dimension(:, :), public :: fd_coeff_z !> @} - integer, private :: flg !< Dimensionality flag: 1 = 3D dataset, 0 = otherwise + integer, private :: flg !< + !! Flagging (flg) variable used to annotate the dimensionality of the dataset + !! that is undergoing the post-process. A flag value of 1 indicates that the + !! dataset is 3D, while a flag value of 0 indicates that it is not. This flg + !! variable is necessary to avoid cycling through the third dimension of the + !! flow variable(s) when the simulation is not 3D and the size of the buffer + !! is non-zero. Note that a similar procedure does not have to be applied to + !! the second dimension since in 1D, the buffer size is always zero. contains - !> Computation of parameters, allocation procedures, and/or any other tasks needed to properly setup the module + !> Computation of parameters, allocation procedures, and/or + !! any other tasks needed to properly setup the module impure subroutine s_initialize_derived_variables_module - ! Allocate density gradient magnitude if Schlieren output requested + ! Allocating the gradient magnitude of the density variable provided + ! that numerical Schlieren function is outputted during post-process if (schlieren_wrt) then - allocate (gm_rho_sf(-offset_x%beg:m + offset_x%end,-offset_y%beg:n + offset_y%end,-offset_z%beg:p + offset_z%end)) + allocate (gm_rho_sf(-offset_x%beg:m + offset_x%end, & + -offset_y%beg:n + offset_y%end, & + -offset_z%beg:p + offset_z%end)) end if - ! Allocate FD coefficients (up to 4th order; higher orders need extension) + ! Allocating the variables which will store the coefficients of the + ! centered family of finite-difference schemes. Note that sufficient + ! space is allocated so that the coefficients up to any chosen order + ! of accuracy may be bookkept. However, if higher than fourth-order + ! accuracy coefficients are wanted, the formulae required to compute + ! these coefficients will have to be implemented in the subroutine + ! s_compute_finite_difference_coefficients. + ! Allocating centered finite-difference coefficients in x-direction if (omega_wrt(2) .or. omega_wrt(3) .or. schlieren_wrt .or. liutex_wrt) then - allocate (fd_coeff_x(-fd_number:fd_number,-offset_x%beg:m + offset_x%end)) + allocate (fd_coeff_x(-fd_number:fd_number, & + -offset_x%beg:m + offset_x%end)) end if - if (omega_wrt(1) .or. omega_wrt(3) .or. liutex_wrt .or. (n > 0 .and. schlieren_wrt)) then - allocate (fd_coeff_y(-fd_number:fd_number,-offset_y%beg:n + offset_y%end)) + ! Allocating centered finite-difference coefficients in y-direction + if (omega_wrt(1) .or. omega_wrt(3) .or. liutex_wrt & + .or. & + (n > 0 .and. schlieren_wrt)) then + allocate (fd_coeff_y(-fd_number:fd_number, & + -offset_y%beg:n + offset_y%end)) end if - if (omega_wrt(1) .or. omega_wrt(2) .or. liutex_wrt .or. (p > 0 .and. schlieren_wrt)) then - allocate (fd_coeff_z(-fd_number:fd_number,-offset_z%beg:p + offset_z%end)) + ! Allocating centered finite-difference coefficients in z-direction + if (omega_wrt(1) .or. omega_wrt(2) .or. liutex_wrt & + .or. & + (p > 0 .and. schlieren_wrt)) then + allocate (fd_coeff_z(-fd_number:fd_number, & + -offset_z%beg:p + offset_z%end)) end if + ! Annotating the dimensionality of the dataset undergoing the post- + ! process. A flag value of 1 indicates that the dataset is 3D, while + ! a flag value of 0 indicates that it is not. if (p > 0) then flg = 1 else @@ -62,14 +109,22 @@ contains end subroutine s_initialize_derived_variables_module - !> Derive the specific heat ratio from the specific heat ratio function gamma_sf. The latter is stored in the derived flow - !! quantity storage variable, q_sf. + !> This subroutine receives as input the specific heat ratio + !! function, gamma_sf, and derives from it the specific heat + !! ratio. The latter is stored in the derived flow quantity + !! storage variable, q_sf. + !! @param q_sf Specific heat ratio subroutine s_derive_specific_heat_ratio(q_sf) - real(wp), dimension(-offset_x%beg:m + offset_x%end,-offset_y%beg:n + offset_y%end,-offset_z%beg:p + offset_z%end), & - & intent(inout) :: q_sf + real(wp), & + dimension(-offset_x%beg:m + offset_x%end, & + -offset_y%beg:n + offset_y%end, & + -offset_z%beg:p + offset_z%end), & + intent(inout) :: q_sf - integer :: i, j, k + integer :: i, j, k !< Generic loop iterators + + ! Computing specific heat ratio from specific heat ratio function do k = -offset_z%beg, p + offset_z%end do j = -offset_y%beg, n + offset_y%end do i = -offset_x%beg, m + offset_x%end @@ -80,15 +135,24 @@ contains end subroutine s_derive_specific_heat_ratio - !> Compute the liquid stiffness from the specific heat ratio function gamma_sf and the liquid stiffness function pi_inf_sf, - !! respectively. These are used to calculate the values of the liquid stiffness, which are stored in the derived flow quantity - !! storage variable, q_sf. + !> This subroutine admits as inputs the specific heat ratio + !! function and the liquid stiffness function, gamma_sf and + !! pi_inf_sf, respectively. These are used to calculate the + !! values of the liquid stiffness, which are stored in the + !! derived flow quantity storage variable, q_sf. + !! @param q_sf Liquid stiffness subroutine s_derive_liquid_stiffness(q_sf) - real(wp), dimension(-offset_x%beg:m + offset_x%end,-offset_y%beg:n + offset_y%end,-offset_z%beg:p + offset_z%end), & - & intent(inout) :: q_sf + real(wp), & + dimension(-offset_x%beg:m + offset_x%end, & + -offset_y%beg:n + offset_y%end, & + -offset_z%beg:p + offset_z%end), & + intent(inout) :: q_sf - integer :: i, j, k + integer :: i, j, k !< Generic loop iterators + + ! Calculating the values of the liquid stiffness from those of the + ! specific heat ratio function and the liquid stiffness function do k = -offset_z%beg, p + offset_z%end do j = -offset_y%beg, n + offset_y%end do i = -offset_x%beg, m + offset_x%end @@ -99,30 +163,49 @@ contains end subroutine s_derive_liquid_stiffness - !> Compute the speed of sound from the primitive variables, density, specific heat ratio function, and liquid stiffness - !! function. It then computes from those variables the values of the speed of sound, which are stored in the derived flow - !! quantity storage variable, q_sf. + !> This subroutine admits as inputs the primitive variables, + !! the density, the specific heat ratio function and liquid + !! stiffness function. It then computes from those variables + !! the values of the speed of sound, which are stored in the + !! derived flow quantity storage variable, q_sf. + !! @param q_prim_vf Primitive variables + !! @param q_sf Speed of sound subroutine s_derive_sound_speed(q_prim_vf, q_sf) - type(scalar_field), dimension(sys_size), intent(in) :: q_prim_vf + type(scalar_field), & + dimension(sys_size), & + intent(in) :: q_prim_vf + + real(wp), & + dimension(-offset_x%beg:m + offset_x%end, & + -offset_y%beg:n + offset_y%end, & + -offset_z%beg:p + offset_z%end), & + intent(inout) :: q_sf - real(wp), dimension(-offset_x%beg:m + offset_x%end,-offset_y%beg:n + offset_y%end,-offset_z%beg:p + offset_z%end), & - & intent(inout) :: q_sf + integer :: i, j, k !< Generic loop iterators - integer :: i, j, k + ! Fluid bulk modulus for alternate sound speed real(wp) :: blkmod1, blkmod2 + ! Computing speed of sound values from those of pressure, density, + ! specific heat ratio function and the liquid stiffness function do k = -offset_z%beg, p + offset_z%end do j = -offset_y%beg, n + offset_y%end do i = -offset_x%beg, m + offset_x%end + + ! Compute mixture sound speed if (alt_soundspeed .neqv. .true.) then - q_sf(i, j, k) = (((gamma_sf(i, j, k) + 1._wp)*q_prim_vf(E_idx)%sf(i, j, k) + pi_inf_sf(i, j, & - & k))/(gamma_sf(i, j, k)*rho_sf(i, j, k))) + q_sf(i, j, k) = (((gamma_sf(i, j, k) + 1._wp)* & + q_prim_vf(E_idx)%sf(i, j, k) + & + pi_inf_sf(i, j, k))/(gamma_sf(i, j, k)* & + rho_sf(i, j, k))) else - blkmod1 = ((gammas(1) + 1._wp)*q_prim_vf(E_idx)%sf(i, j, k) + pi_infs(1))/gammas(1) - blkmod2 = ((gammas(2) + 1._wp)*q_prim_vf(E_idx)%sf(i, j, k) + pi_infs(2))/gammas(2) - q_sf(i, j, k) = (1._wp/(rho_sf(i, j, k)*(q_prim_vf(adv_idx%beg)%sf(i, j, & - & k)/blkmod1 + (1._wp - q_prim_vf(adv_idx%beg)%sf(i, j, k))/blkmod2))) + blkmod1 = ((gammas(1) + 1._wp)*q_prim_vf(E_idx)%sf(i, j, k) + & + pi_infs(1))/gammas(1) + blkmod2 = ((gammas(2) + 1._wp)*q_prim_vf(E_idx)%sf(i, j, k) + & + pi_infs(2))/gammas(2) + q_sf(i, j, k) = (1._wp/(rho_sf(i, j, k)*(q_prim_vf(adv_idx%beg)%sf(i, j, k)/blkmod1 + & + (1._wp - q_prim_vf(adv_idx%beg)%sf(i, j, k))/blkmod2))) end if if (mixture_err .and. q_sf(i, j, k) < 0._wp) then @@ -136,44 +219,66 @@ contains end subroutine s_derive_sound_speed - !> Derive the flux limiter at cell boundary i+1/2. This is an approximation because the velocity used to determine the upwind - !! direction is the velocity at the cell center i instead of the contact velocity at the cell boundary from the Riemann solver. + !> This subroutine derives the flux_limiter at cell boundary + !! i+1/2. This is an approximation because the velocity used + !! to determine the upwind direction is the velocity at the + !! cell center i instead of the contact velocity at the cell + !! boundary from the Riemann solver. + !! @param i Component indicator + !! @param q_prim_vf Primitive variables + !! @param q_sf Flux limiter subroutine s_derive_flux_limiter(i, q_prim_vf, q_sf) - integer, intent(in) :: i + integer, intent(in) :: i + type(scalar_field), dimension(sys_size), intent(in) :: q_prim_vf - real(wp), dimension(-offset_x%beg:m + offset_x%end,-offset_y%beg:n + offset_y%end,-offset_z%beg:p + offset_z%end), & - & intent(inout) :: q_sf + real(wp), dimension(-offset_x%beg:m + offset_x%end, & + -offset_y%beg:n + offset_y%end, & + -offset_z%beg:p + offset_z%end), & + intent(inout) :: q_sf + + real(wp) :: top, bottom, slope !< Flux limiter calcs + integer :: j, k, l !< Generic loop iterators - real(wp) :: top, bottom, slope - integer :: j, k, l do l = -offset_z%beg, p + offset_z%end do k = -offset_y%beg, n + offset_y%end do j = -offset_x%beg, m + offset_x%end if (i == 1) then if (q_prim_vf(cont_idx%end + i)%sf(j, k, l) >= 0._wp) then - top = q_prim_vf(adv_idx%beg)%sf(j, k, l) - q_prim_vf(adv_idx%beg)%sf(j - 1, k, l) - bottom = q_prim_vf(adv_idx%beg)%sf(j + 1, k, l) - q_prim_vf(adv_idx%beg)%sf(j, k, l) + top = q_prim_vf(adv_idx%beg)%sf(j, k, l) - & + q_prim_vf(adv_idx%beg)%sf(j - 1, k, l) + bottom = q_prim_vf(adv_idx%beg)%sf(j + 1, k, l) - & + q_prim_vf(adv_idx%beg)%sf(j, k, l) else - top = q_prim_vf(adv_idx%beg)%sf(j + 2, k, l) - q_prim_vf(adv_idx%beg)%sf(j + 1, k, l) - bottom = q_prim_vf(adv_idx%beg)%sf(j + 1, k, l) - q_prim_vf(adv_idx%beg)%sf(j, k, l) + top = q_prim_vf(adv_idx%beg)%sf(j + 2, k, l) - & + q_prim_vf(adv_idx%beg)%sf(j + 1, k, l) + bottom = q_prim_vf(adv_idx%beg)%sf(j + 1, k, l) - & + q_prim_vf(adv_idx%beg)%sf(j, k, l) end if - else if (i == 2) then + elseif (i == 2) then if (q_prim_vf(cont_idx%end + i)%sf(j, k, l) >= 0._wp) then - top = q_prim_vf(adv_idx%beg)%sf(j, k, l) - q_prim_vf(adv_idx%beg)%sf(j, k - 1, l) - bottom = q_prim_vf(adv_idx%beg)%sf(j, k + 1, l) - q_prim_vf(adv_idx%beg)%sf(j, k, l) + top = q_prim_vf(adv_idx%beg)%sf(j, k, l) - & + q_prim_vf(adv_idx%beg)%sf(j, k - 1, l) + bottom = q_prim_vf(adv_idx%beg)%sf(j, k + 1, l) - & + q_prim_vf(adv_idx%beg)%sf(j, k, l) else - top = q_prim_vf(adv_idx%beg)%sf(j, k + 2, l) - q_prim_vf(adv_idx%beg)%sf(j, k + 1, l) - bottom = q_prim_vf(adv_idx%beg)%sf(j, k + 1, l) - q_prim_vf(adv_idx%beg)%sf(j, k, l) + top = q_prim_vf(adv_idx%beg)%sf(j, k + 2, l) - & + q_prim_vf(adv_idx%beg)%sf(j, k + 1, l) + bottom = q_prim_vf(adv_idx%beg)%sf(j, k + 1, l) - & + q_prim_vf(adv_idx%beg)%sf(j, k, l) end if else if (q_prim_vf(cont_idx%end + i)%sf(j, k, l) >= 0._wp) then - top = q_prim_vf(adv_idx%beg)%sf(j, k, l) - q_prim_vf(adv_idx%beg)%sf(j, k, l - 1) - bottom = q_prim_vf(adv_idx%beg)%sf(j, k, l + 1) - q_prim_vf(adv_idx%beg)%sf(j, k, l) + top = q_prim_vf(adv_idx%beg)%sf(j, k, l) - & + q_prim_vf(adv_idx%beg)%sf(j, k, l - 1) + bottom = q_prim_vf(adv_idx%beg)%sf(j, k, l + 1) - & + q_prim_vf(adv_idx%beg)%sf(j, k, l) else - top = q_prim_vf(adv_idx%beg)%sf(j, k, l + 2) - q_prim_vf(adv_idx%beg)%sf(j, k, l + 1) - bottom = q_prim_vf(adv_idx%beg)%sf(j, k, l + 1) - q_prim_vf(adv_idx%beg)%sf(j, k, l) + top = q_prim_vf(adv_idx%beg)%sf(j, k, l + 2) - & + q_prim_vf(adv_idx%beg)%sf(j, k, l + 1) + bottom = q_prim_vf(adv_idx%beg)%sf(j, k, l + 1) - & + q_prim_vf(adv_idx%beg)%sf(j, k, l) end if end if @@ -182,58 +287,72 @@ contains if (f_approx_equal(top, bottom)) then slope = 1._wp + ! ELSEIF((top == 0._wp .AND. bottom /= 0._wp) & + ! .OR. & + ! (bottom == 0._wp .AND. top /= 0._wp)) THEN + ! slope = 0._wp else slope = (top*bottom)/(bottom**2._wp + 1.e-16_wp) end if - if (flux_lim == 1) then ! MINMOD (MM) + ! Flux limiter function + if (flux_lim == 1) then ! MINMOD (MM) q_sf(j, k, l) = max(0._wp, min(1._wp, slope)) - else if (flux_lim == 2) then ! MUSCL (MC) + elseif (flux_lim == 2) then ! MUSCL (MC) q_sf(j, k, l) = max(0._wp, min(2._wp*slope, 5.e-1_wp*(1._wp + slope), 2._wp)) - else if (flux_lim == 3) then ! OSPRE (OP) + elseif (flux_lim == 3) then ! OSPRE (OP) q_sf(j, k, l) = (15.e-1_wp*(slope**2._wp + slope))/(slope**2._wp + slope + 1._wp) - else if (flux_lim == 4) then ! SUPERBEE (SB) + elseif (flux_lim == 4) then ! SUPERBEE (SB) q_sf(j, k, l) = max(0._wp, min(1._wp, 2._wp*slope), min(slope, 2._wp)) - else if (flux_lim == 5) then ! SWEBY (SW) (beta = 1.5) + elseif (flux_lim == 5) then ! SWEBY (SW) (beta = 1.5) q_sf(j, k, l) = max(0._wp, min(15.e-1_wp*slope, 1._wp), min(slope, 15.e-1_wp)) - else if (flux_lim == 6) then ! VAN ALBADA (VA) + elseif (flux_lim == 6) then ! VAN ALBADA (VA) q_sf(j, k, l) = (slope**2._wp + slope)/(slope**2._wp + 1._wp) - else if (flux_lim == 7) then ! VAN LEER (VL) + elseif (flux_lim == 7) then ! VAN LEER (VL) q_sf(j, k, l) = (abs(slope) + slope)/(1._wp + abs(slope)) end if end do end do end do - end subroutine s_derive_flux_limiter - !> Solve Ax=b via Gaussian elimination with partial pivoting + !> Computes the solution to the linear system Ax=b w/ sol = x + !! @param A Input matrix + !! @param b right-hane-side + !! @param sol Solution + !! @param ndim Problem size subroutine s_solve_linear_system(A, b, sol, ndim) - integer, intent(in) :: ndim + integer, intent(in) :: ndim real(wp), dimension(ndim, ndim), intent(inout) :: A - real(wp), dimension(ndim), intent(inout) :: b - real(wp), dimension(ndim), intent(out) :: sol - integer :: i, j, k + real(wp), dimension(ndim), intent(inout) :: b + real(wp), dimension(ndim), intent(out) :: sol - ! Forward elimination with partial pivoting + !EXTERNAL DGESV + integer :: i, j, k + + ! Solve linear system using own linear solver (Thomson/Darter/Comet/Stampede) + ! Forward elimination do i = 1, ndim - j = i - 1 + maxloc(abs(A(i:ndim,i)), 1) - sol = A(i,:) - A(i,:) = A(j,:) - A(j,:) = sol + ! Pivoting + j = i - 1 + maxloc(abs(A(i:ndim, i)), 1) + sol = A(i, :) + A(i, :) = A(j, :) + A(j, :) = sol sol(1) = b(i) b(i) = b(j) b(j) = sol(1) + ! Elimination b(i) = b(i)/A(i, i) - A(i,:) = A(i,:)/A(i, i) + A(i, :) = A(i, :)/A(i, i) do k = i + 1, ndim b(k) = b(k) - A(k, i)*b(i) - A(k,:) = A(k,:) - A(k, i)*A(i,:) + A(k, :) = A(k, :) - A(k, i)*A(i, :) end do end do + ! Backward substitution do i = ndim, 1, -1 sol(i) = b(i) do k = i + 1, ndim @@ -243,64 +362,104 @@ contains end subroutine s_solve_linear_system - !> Compute the specified component of the vorticity from the primitive variables. From those inputs, it proceeds to calculate - !! values of the desired vorticity component, which are subsequently stored in derived flow quantity storage variable, q_sf. + !> This subroutine receives as inputs the indicator of the + !! component of the vorticity that should be outputted and + !! the primitive variables. From those inputs, it proceeds + !! to calculate values of the desired vorticity component, + !! which are subsequently stored in derived flow quantity + !! storage variable, q_sf. + !! @param i Vorticity component indicator + !! @param q_prim_vf Primitive variables + !! @param q_sf Vorticity component subroutine s_derive_vorticity_component(i, q_prim_vf, q_sf) - integer, intent(in) :: i - type(scalar_field), dimension(sys_size), intent(in) :: q_prim_vf + integer, intent(in) :: i - real(wp), dimension(-offset_x%beg:m + offset_x%end,-offset_y%beg:n + offset_y%end,-offset_z%beg:p + offset_z%end), & - & intent(inout) :: q_sf + type(scalar_field), & + dimension(sys_size), & + intent(in) :: q_prim_vf - integer :: j, k, l, r + real(wp), & + dimension(-offset_x%beg:m + offset_x%end, & + -offset_y%beg:n + offset_y%end, & + -offset_z%beg:p + offset_z%end), & + intent(inout) :: q_sf + + integer :: j, k, l, r !< Generic loop iterators + + ! Computing the vorticity component in the x-coordinate direction if (i == 1) then do l = -offset_z%beg, p + offset_z%end do k = -offset_y%beg, n + offset_y%end do j = -offset_x%beg, m + offset_x%end + q_sf(j, k, l) = 0._wp do r = -fd_number, fd_number if (grid_geometry == 3) then - q_sf(j, k, l) = q_sf(j, k, l) + 1._wp/y_cc(k)*(fd_coeff_y(r, & - & k)*y_cc(r + k)*q_prim_vf(mom_idx%end)%sf(j, r + k, l) - fd_coeff_z(r, & - & l)*q_prim_vf(mom_idx%beg + 1)%sf(j, k, r + l)) + q_sf(j, k, l) = & + q_sf(j, k, l) + 1._wp/y_cc(k)* & + (fd_coeff_y(r, k)*y_cc(r + k)* & + q_prim_vf(mom_idx%end)%sf(j, r + k, l) & + - fd_coeff_z(r, l)* & + q_prim_vf(mom_idx%beg + 1)%sf(j, k, r + l)) else - q_sf(j, k, l) = q_sf(j, k, l) + fd_coeff_y(r, k)*q_prim_vf(mom_idx%end)%sf(j, r + k, & - & l) - fd_coeff_z(r, l)*q_prim_vf(mom_idx%beg + 1)%sf(j, k, r + l) + q_sf(j, k, l) = & + q_sf(j, k, l) + fd_coeff_y(r, k)* & + q_prim_vf(mom_idx%end)%sf(j, r + k, l) & + - fd_coeff_z(r, l)* & + q_prim_vf(mom_idx%beg + 1)%sf(j, k, r + l) end if end do + end do end do end do - else if (i == 2) then + + ! Computing the vorticity component in the y-coordinate direction + elseif (i == 2) then do l = -offset_z%beg, p + offset_z%end do k = -offset_y%beg, n + offset_y%end do j = -offset_x%beg, m + offset_x%end + q_sf(j, k, l) = 0._wp do r = -fd_number, fd_number if (grid_geometry == 3) then - q_sf(j, k, l) = q_sf(j, k, l) + fd_coeff_z(r, l)/y_cc(k)*q_prim_vf(mom_idx%beg)%sf(j, k, & - & r + l) - fd_coeff_x(r, j)*q_prim_vf(mom_idx%end)%sf(r + j, k, l) + q_sf(j, k, l) = & + q_sf(j, k, l) + fd_coeff_z(r, l)/y_cc(k)* & + q_prim_vf(mom_idx%beg)%sf(j, k, r + l) & + - fd_coeff_x(r, j)* & + q_prim_vf(mom_idx%end)%sf(r + j, k, l) else - q_sf(j, k, l) = q_sf(j, k, l) + fd_coeff_z(r, l)*q_prim_vf(mom_idx%beg)%sf(j, k, & - & r + l) - fd_coeff_x(r, j)*q_prim_vf(mom_idx%end)%sf(r + j, k, l) + q_sf(j, k, l) = & + q_sf(j, k, l) + fd_coeff_z(r, l)* & + q_prim_vf(mom_idx%beg)%sf(j, k, r + l) & + - fd_coeff_x(r, j)* & + q_prim_vf(mom_idx%end)%sf(r + j, k, l) end if end do + end do end do end do + + ! Computing the vorticity component in the z-coordinate direction else do l = -offset_z%beg, p + offset_z%end do k = -offset_y%beg, n + offset_y%end do j = -offset_x%beg, m + offset_x%end + q_sf(j, k, l) = 0._wp do r = -fd_number, fd_number - q_sf(j, k, l) = q_sf(j, k, l) + fd_coeff_x(r, j)*q_prim_vf(mom_idx%beg + 1)%sf(r + j, k, & - & l) - fd_coeff_y(r, k)*q_prim_vf(mom_idx%beg)%sf(j, r + k, l) + q_sf(j, k, l) = & + q_sf(j, k, l) + fd_coeff_x(r, j)* & + q_prim_vf(mom_idx%beg + 1)%sf(r + j, k, l) & + - fd_coeff_y(r, k)* & + q_prim_vf(mom_idx%beg)%sf(j, r + k, l) end do + end do end do end do @@ -308,110 +467,156 @@ contains end subroutine s_derive_vorticity_component - !> Compute the Q_M criterion from the primitive variables. The Q_M function, which are subsequently stored in the derived flow - !! quantity storage variable, q_sf. + !> This subroutine gets as inputs the primitive variables. From those + !! inputs, it proceeds to calculate the value of the Q_M + !! function, which are subsequently stored in the derived flow + !! quantity storage variable, q_sf. + !! @param q_prim_vf Primitive variables + !! @param q_sf Q_M subroutine s_derive_qm(q_prim_vf, q_sf) + type(scalar_field), & + dimension(sys_size), & + intent(in) :: q_prim_vf - type(scalar_field), dimension(sys_size), intent(in) :: q_prim_vf + real(wp), & + dimension(-offset_x%beg:m + offset_x%end, & + -offset_y%beg:n + offset_y%end, & + -offset_z%beg:p + offset_z%end), & + intent(inout) :: q_sf + + real(wp), & + dimension(1:3, 1:3) :: q_jacobian_sf, S, S2, O, O2 - real(wp), dimension(-offset_x%beg:m + offset_x%end,-offset_y%beg:n + offset_y%end,-offset_z%beg:p + offset_z%end), & - & intent(inout) :: q_sf + real(wp) :: trS, Q, IIS + integer :: j, k, l, r, jj, kk !< Generic loop iterators - real(wp), dimension(1:3,1:3) :: q_jacobian_sf, S, S2, O, O2 - real(wp) :: trS, Q, IIS - integer :: j, k, l, r, jj, kk do l = -offset_z%beg, p + offset_z%end do k = -offset_y%beg, n + offset_y%end do j = -offset_x%beg, m + offset_x%end + ! Get velocity gradient tensor - q_jacobian_sf(:,:) = 0._wp + q_jacobian_sf(:, :) = 0._wp do r = -fd_number, fd_number do jj = 1, 3 ! d()/dx - q_jacobian_sf(jj, 1) = q_jacobian_sf(jj, 1) + fd_coeff_x(r, & - & j)*q_prim_vf(mom_idx%beg + jj - 1)%sf(r + j, k, l) + q_jacobian_sf(jj, 1) = & + q_jacobian_sf(jj, 1) + & + fd_coeff_x(r, j)* & + q_prim_vf(mom_idx%beg + jj - 1)%sf(r + j, k, l) ! d()/dy - q_jacobian_sf(jj, 2) = q_jacobian_sf(jj, 2) + fd_coeff_y(r, k)*q_prim_vf(mom_idx%beg + jj - 1)%sf(j, & - & r + k, l) + q_jacobian_sf(jj, 2) = & + q_jacobian_sf(jj, 2) + & + fd_coeff_y(r, k)* & + q_prim_vf(mom_idx%beg + jj - 1)%sf(j, r + k, l) ! d()/dz - q_jacobian_sf(jj, 3) = q_jacobian_sf(jj, 3) + fd_coeff_z(r, l)*q_prim_vf(mom_idx%beg + jj - 1)%sf(j, & - & k, r + l) + q_jacobian_sf(jj, 3) = & + q_jacobian_sf(jj, 3) + & + fd_coeff_z(r, l)* & + q_prim_vf(mom_idx%beg + jj - 1)%sf(j, k, r + l) end do end do - ! Decompose velocity gradient into symmetric strain-rate S and skew-symmetric rotation-rate O + ! Decompose J into asymmetric matrix, S, and a skew-symmetric matrix, O do jj = 1, 3 do kk = 1, 3 - S(jj, kk) = 0.5_wp*(q_jacobian_sf(jj, kk) + q_jacobian_sf(kk, jj)) - O(jj, kk) = 0.5_wp*(q_jacobian_sf(jj, kk) - q_jacobian_sf(kk, jj)) + S(jj, kk) = 0.5_wp* & + (q_jacobian_sf(jj, kk) + q_jacobian_sf(kk, jj)) + O(jj, kk) = 0.5_wp* & + (q_jacobian_sf(jj, kk) - q_jacobian_sf(kk, jj)) end do end do + ! Compute S2 = S*S' do jj = 1, 3 do kk = 1, 3 - O2(jj, kk) = O(jj, 1)*O(kk, 1) + O(jj, 2)*O(kk, 2) + O(jj, 3)*O(kk, 3) - S2(jj, kk) = S(jj, 1)*S(kk, 1) + S(jj, 2)*S(kk, 2) + S(jj, 3)*S(kk, 3) + O2(jj, kk) = O(jj, 1)*O(kk, 1) + & + O(jj, 2)*O(kk, 2) + & + O(jj, 3)*O(kk, 3) + S2(jj, kk) = S(jj, 1)*S(kk, 1) + & + S(jj, 2)*S(kk, 2) + & + S(jj, 3)*S(kk, 3) end do end do - ! Q-criterion: Q = (||O||^2 - ||S||^2)/2, Hunt et al. CTR (1988) - Q = 0.5_wp*((O2(1, 1) + O2(2, 2) + O2(3, 3)) - (S2(1, 1) + S2(2, 2) + S2(3, 3))) + ! Compute Q + Q = 0.5_wp*((O2(1, 1) + O2(2, 2) + O2(3, 3)) - & + (S2(1, 1) + S2(2, 2) + S2(3, 3))) trS = S(1, 1) + S(2, 2) + S(3, 3) - ! Second invariant of strain-rate tensor - IIS = 0.5_wp*((S(1, 1) + S(2, 2) + S(3, 3))**2 - (S2(1, 1) + S2(2, 2) + S2(3, 3))) + IIS = 0.5_wp*((S(1, 1) + S(2, 2) + S(3, 3))**2 - & + (S2(1, 1) + S2(2, 2) + S2(3, 3))) q_sf(j, k, l) = Q + IIS + end do end do end do end subroutine s_derive_qm - !> Compute the Liutex vector and its magnitude based on Xu et al. (2019). + !> This subroutine gets as inputs the primitive variables. From those + !! inputs, it proceeds to calculate the Liutex vector and its + !! magnitude based on Xu et al. (2019). + !! @param q_prim_vf Primitive variables impure subroutine s_derive_liutex(q_prim_vf, liutex_mag, liutex_axis) - - ! Liutex vortex identification via real eigenvector of velocity gradient, Xu et al. PoF (2019) - - integer, parameter :: nm = 3 - type(scalar_field), dimension(sys_size), intent(in) :: q_prim_vf - - !> Liutex magnitude - - real(wp), dimension(-offset_x%beg:m + offset_x%end,-offset_y%beg:n + offset_y%end,-offset_z%beg:p + offset_z%end), & - & intent(out) :: liutex_mag - !> Liutex rigid rotation axis - real(wp), dimension(-offset_x%beg:m + offset_x%end,-offset_y%beg:n + offset_y%end,-offset_z%beg:p + offset_z%end,nm), & - & intent(out) :: liutex_axis - character, parameter :: ivl = 'N' !< compute left eigenvectors - character, parameter :: ivr = 'V' !< compute right eigenvectors - real(wp), dimension(nm, nm) :: vgt !< velocity gradient tensor - real(wp), dimension(nm) :: lr, li !< real and imaginary parts of eigenvalues - real(wp), dimension(nm, nm) :: vl, vr !< left and right eigenvectors - integer, parameter :: lwork = 4*nm !< size of work array (4*nm recommended) - real(wp), dimension(lwork) :: work !< work array - integer :: info - real(wp), dimension(nm) :: eigvec !< real eigenvector - real(wp) :: eigvec_mag !< magnitude of real eigenvector - real(wp) :: omega_proj !< projection of vorticity on real eigenvector - real(wp) :: lci !< imaginary part of complex eigenvalue - real(wp) :: alpha - integer :: j, k, l, r, i - integer :: idx + integer, parameter :: nm = 3 + type(scalar_field), & + dimension(sys_size), & + intent(in) :: q_prim_vf + + real(wp), & + dimension(-offset_x%beg:m + offset_x%end, & + -offset_y%beg:n + offset_y%end, & + -offset_z%beg:p + offset_z%end), & + intent(out) :: liutex_mag !< Liutex magnitude + + real(wp), & + dimension(-offset_x%beg:m + offset_x%end, & + -offset_y%beg:n + offset_y%end, & + -offset_z%beg:p + offset_z%end, nm), & + intent(out) :: liutex_axis !< Liutex rigid rotation axis + + character, parameter :: ivl = 'N' !< compute left eigenvectors + character, parameter :: ivr = 'V' !< compute right eigenvectors + real(wp), dimension(nm, nm) :: vgt !< velocity gradient tensor + real(wp), dimension(nm) :: lr, li !< real and imaginary parts of eigenvalues + real(wp), dimension(nm, nm) :: vl, vr !< left and right eigenvectors + integer, parameter :: lwork = 4*nm !< size of work array (4*nm recommended) + real(wp), dimension(lwork) :: work !< work array + integer :: info + + real(wp), dimension(nm) :: eigvec !< real eigenvector + real(wp) :: eigvec_mag !< magnitude of real eigenvector + real(wp) :: omega_proj !< projection of vorticity on real eigenvector + real(wp) :: lci !< imaginary part of complex eigenvalue + real(wp) :: alpha + + integer :: j, k, l, r, i !< Generic loop iterators + integer :: idx do l = -offset_z%beg, p + offset_z%end do k = -offset_y%beg, n + offset_y%end do j = -offset_x%beg, m + offset_x%end + ! Get velocity gradient tensor (VGT) - vgt(:,:) = 0._wp + vgt(:, :) = 0._wp do r = -fd_number, fd_number do i = 1, 3 ! d()/dx - vgt(i, 1) = vgt(i, 1) + fd_coeff_x(r, j)*q_prim_vf(mom_idx%beg + i - 1)%sf(r + j, k, l) + vgt(i, 1) = & + vgt(i, 1) + & + fd_coeff_x(r, j)* & + q_prim_vf(mom_idx%beg + i - 1)%sf(r + j, k, l) ! d()/dy - vgt(i, 2) = vgt(i, 2) + fd_coeff_y(r, k)*q_prim_vf(mom_idx%beg + i - 1)%sf(j, r + k, l) + vgt(i, 2) = & + vgt(i, 2) + & + fd_coeff_y(r, k)* & + q_prim_vf(mom_idx%beg + i - 1)%sf(j, r + k, l) ! d()/dz - vgt(i, 3) = vgt(i, 3) + fd_coeff_z(r, l)*q_prim_vf(mom_idx%beg + i - 1)%sf(j, k, r + l) + vgt(i, 3) = & + vgt(i, 3) + & + fd_coeff_z(r, l)* & + q_prim_vf(mom_idx%beg + i - 1)%sf(j, k, r + l) end do end do @@ -422,17 +627,19 @@ contains call dgeev(ivl, ivr, nm, vgt, nm, lr, li, vl, nm, vr, nm, work, lwork, info) #endif - ! Find eigenvector with smallest imaginary eigenvalue (real eigenvector of VGT) + ! Find real eigenvector idx = 1 do r = 2, 3 if (abs(li(r)) < abs(li(idx))) then idx = r end if end do - eigvec = vr(:,idx) + eigvec = vr(:, idx) ! Normalize real eigenvector if it is effectively non-zero - eigvec_mag = sqrt(eigvec(1)**2._wp + eigvec(2)**2._wp + eigvec(3)**2._wp) + eigvec_mag = sqrt(eigvec(1)**2._wp & + + eigvec(2)**2._wp & + + eigvec(3)**2._wp) if (eigvec_mag > sgm_eps) then eigvec = eigvec/eigvec_mag else @@ -440,21 +647,22 @@ contains end if ! Compute vorticity projected on the eigenvector - omega_proj = (vgt(3, 2) - vgt(2, 3))*eigvec(1) + (vgt(1, 3) - vgt(3, 1))*eigvec(2) + (vgt(2, 1) - vgt(1, & - & 2))*eigvec(3) + omega_proj = (vgt(3, 2) - vgt(2, 3))*eigvec(1) & + + (vgt(1, 3) - vgt(3, 1))*eigvec(2) & + + (vgt(2, 1) - vgt(1, 2))*eigvec(3) - ! As eigenvector can have +/- signs, we can choose the sign so that omega_proj is positive + ! As eigenvector can have +/- signs, we can choose the sign + ! so that omega_proj is positive if (omega_proj < 0._wp) then eigvec = -eigvec omega_proj = -omega_proj end if - ! Imaginary eigenvalue of the complex conjugate pair (cyclic index selection) + ! Find imaginary part of complex eigenvalue lci = li(mod(idx, 3) + 1) - ! Discriminant: determines whether rotation dominates strain - alpha = omega_proj**2._wp - 4._wp*lci**2._wp - ! Liutex magnitude = omega_proj - sqrt(discriminant) when rotation dominates + ! Compute Liutex magnitude + alpha = omega_proj**2._wp - 4._wp*lci**2._wp ! (2*alpha)^2 if (alpha > 0._wp) then liutex_mag(j, k, l) = omega_proj - sqrt(alpha) else @@ -465,28 +673,50 @@ contains liutex_axis(j, k, l, 1) = eigvec(1) liutex_axis(j, k, l, 2) = eigvec(2) liutex_axis(j, k, l, 3) = eigvec(3) + end do end do end do end subroutine s_derive_liutex - !> Compute the values of the numerical Schlieren function, which are subsequently stored in the derived flow quantity storage - !! variable, q_sf. + !> This subroutine gets as inputs the conservative variables + !! and density. From those inputs, it proceeds to calculate + !! the values of the numerical Schlieren function, which are + !! subsequently stored in the derived flow quantity storage + !! variable, q_sf. + !! @param q_cons_vf Conservative variables + !! @param q_sf Numerical Schlieren function impure subroutine s_derive_numerical_schlieren_function(q_cons_vf, q_sf) - type(scalar_field), dimension(sys_size), intent(in) :: q_cons_vf + type(scalar_field), & + dimension(sys_size), & + intent(in) :: q_cons_vf + + real(wp), & + dimension(-offset_x%beg:m + offset_x%end, & + -offset_y%beg:n + offset_y%end, & + -offset_z%beg:p + offset_z%end), & + intent(inout) :: q_sf - real(wp), dimension(-offset_x%beg:m + offset_x%end,-offset_y%beg:n + offset_y%end,-offset_z%beg:p + offset_z%end), & - & intent(inout) :: q_sf + real(wp) :: drho_dx, drho_dy, drho_dz !< + !! Spatial derivatives of the density in the x-, y- and z-directions - real(wp) :: drho_dx, drho_dy, drho_dz !< Spatial derivatives of the density in the x-, y- and z-directions - real(wp), dimension(2) :: gm_rho_max !< Global (max gradient magnitude, rank) pair for density - integer :: i, j, k, l + real(wp), dimension(2) :: gm_rho_max !< + !! Maximum value of the gradient magnitude (gm) of the density field + !! in entire computational domain and not just the local sub-domain. + !! The first position in the variable contains the maximum value and + !! the second contains the rank of the processor on which it occurred. + integer :: i, j, k, l !< Generic loop iterators + + ! Computing Gradient Magnitude of Density + + ! Contributions from the x- and y-coordinate directions do l = -offset_z%beg, p + offset_z%end do k = -offset_y%beg, n + offset_y%end do j = -offset_x%beg, m + offset_x%end + drho_dx = 0._wp drho_dy = 0._wp @@ -496,73 +726,101 @@ contains end do gm_rho_sf(j, k, l) = drho_dx*drho_dx + drho_dy*drho_dy + end do end do end do + ! Contribution from the z-coordinate direction if (p > 0) then do l = -offset_z%beg, p + offset_z%end do k = -offset_y%beg, n + offset_y%end do j = -offset_x%beg, m + offset_x%end + drho_dz = 0._wp do i = -fd_number, fd_number if (grid_geometry == 3) then - drho_dz = drho_dz + fd_coeff_z(i, l)/y_cc(k)*rho_sf(j, k, i + l) + drho_dz = drho_dz + fd_coeff_z(i, l)/y_cc(k)* & + rho_sf(j, k, i + l) else - drho_dz = drho_dz + fd_coeff_z(i, l)*rho_sf(j, k, i + l) + drho_dz = drho_dz + fd_coeff_z(i, l)* & + rho_sf(j, k, i + l) end if end do - gm_rho_sf(j, k, l) = gm_rho_sf(j, k, l) + drho_dz*drho_dz + gm_rho_sf(j, k, l) = gm_rho_sf(j, k, l) & + + drho_dz*drho_dz + end do end do end do end if + ! Up until now, only the dot product of the gradient of the density + ! field has been calculated and stored in the gradient magnitude of + ! density variable. So now we proceed to take the square-root as to + ! complete the desired calculation. gm_rho_sf = sqrt(gm_rho_sf) + ! Determining the local maximum of the gradient magnitude of density + ! and bookkeeping the result, along with rank of the local processor gm_rho_max = (/maxval(gm_rho_sf), real(proc_rank, wp)/) + ! Comparing the local maximum gradient magnitude of the density on + ! this processor to the those computed on the remaining processors. + ! This allows for the global maximum to be computed and the rank of + ! the processor on which it has occurred to be recorded. if (num_procs > 1) call s_mpi_reduce_maxloc(gm_rho_max) - ! The form of the numerical Schlieren function depends on the choice of the multicomponent flow model. For the gamma/pi_inf - ! model, the exponential of the negative, normalized, gradient magnitude of the density is computed. For the volume fraction - ! model, the amplitude of the exponential's inside is also modulated with respect to the identity of the fluid in which the - ! function is evaluated. For more information, refer to Marquina and Mulet (2003). + ! Computing Numerical Schlieren Function - if (model_eqns == 1) then ! Gamma/pi_inf model + ! The form of the numerical Schlieren function depends on the choice + ! of the multicomponent flow model. For the gamma/pi_inf model, the + ! exponential of the negative, normalized, gradient magnitude of the + ! density is computed. For the volume fraction model, the amplitude + ! of the exponential's inside is also modulated with respect to the + ! identity of the fluid in which the function is evaluated. For more + ! information, refer to Marquina and Mulet (2003). + + if (model_eqns == 1) then ! Gamma/pi_inf model q_sf = -gm_rho_sf/gm_rho_max(1) - else ! Volume fraction model + + else ! Volume fraction model do l = -offset_z%beg, p + offset_z%end do k = -offset_y%beg, n + offset_y%end do j = -offset_x%beg, m + offset_x%end + q_sf(j, k, l) = 0._wp do i = 1, adv_idx%end - E_idx - q_sf(j, k, l) = q_sf(j, k, l) - schlieren_alpha(i)*q_cons_vf(i + E_idx)%sf(j, k, l)*gm_rho_sf(j, k, & - & l)/gm_rho_max(1) + q_sf(j, k, l) = & + q_sf(j, k, l) - schlieren_alpha(i)* & + q_cons_vf(i + E_idx)%sf(j, k, l)* & + gm_rho_sf(j, k, l)/gm_rho_max(1) end do end do end do end do end if - ! Up until now, only the inside of the exponential of the numerical Schlieren function has been evaluated and stored. Then, - ! to finish the computation, the exponential of the inside quantity is taken. + ! Up until now, only the inside of the exponential of the numerical + ! Schlieren function has been evaluated and stored. Then, to finish + ! the computation, the exponential of the inside quantity is taken. q_sf = exp(q_sf) end subroutine s_derive_numerical_schlieren_function - !> Deallocation procedures for the module + !> Deallocation procedures for the module impure subroutine s_finalize_derived_variables_module - ! Deallocating the variable containing the gradient magnitude of the density field provided that the numerical Schlieren - ! function was was outputted during the post-process + ! Deallocating the variable containing the gradient magnitude of the + ! density field provided that the numerical Schlieren function was + ! was outputted during the post-process if (schlieren_wrt) deallocate (gm_rho_sf) - ! Deallocating the variables that might have been used to bookkeep the finite-difference coefficients in the x-, y- and - ! z-directions + ! Deallocating the variables that might have been used to bookkeep + ! the finite-difference coefficients in the x-, y- and z-directions if (allocated(fd_coeff_x)) deallocate (fd_coeff_x) if (allocated(fd_coeff_y)) deallocate (fd_coeff_y) if (allocated(fd_coeff_z)) deallocate (fd_coeff_z) diff --git a/src/post_process/m_global_parameters.fpp b/src/post_process/m_global_parameters.fpp index 0530c31081..83aa0da561 100644 --- a/src/post_process/m_global_parameters.fpp +++ b/src/post_process/m_global_parameters.fpp @@ -8,24 +8,27 @@ module m_global_parameters #ifdef MFC_MPI - use mpi !< Message passing interface (MPI) module + use mpi !< Message passing interface (MPI) module #endif - use m_derived_types - use m_helper_basic + use m_derived_types !< Definitions of the derived types + + use m_helper_basic !< Functions to compare floating point numbers + use m_thermochem, only: num_species, species_names implicit none !> @name Logistics !> @{ - integer :: num_procs !< Number of processors - character(LEN=path_len) :: case_dir !< Case folder location + integer :: num_procs !< Number of processors + character(LEN=path_len) :: case_dir !< Case folder location !> @} ! Computational Domain Parameters - integer :: proc_rank !< Rank of the local processor + integer :: proc_rank !< Rank of the local processor + !> @name Number of cells in the x-, y- and z-coordinate directions !> @{ integer :: m, m_root @@ -35,7 +38,8 @@ module m_global_parameters !> @name Max and min number of cells in a direction of each combination of x-,y-, and z- type(cell_num_bounds) :: cells_bounds - integer(kind=8) :: nGlobal !< Total number of cells in global domain + + integer(kind=8) :: nGlobal ! Total number of cells in global domain !> @name Cylindrical coordinates (either axisymmetric or full 3D) !> @{ @@ -48,8 +52,9 @@ module m_global_parameters integer :: m_glb, n_glb, p_glb !> @} - integer :: num_dims !< Number of spatial dimensions - integer :: num_vels !< Number of velocity components (different from num_dims for mhd) + integer :: num_dims !< Number of spatial dimensions + integer :: num_vels !< Number of velocity components (different from num_dims for mhd) + !> @name Cell-boundary locations in the x-, y- and z-coordinate directions !> @{ real(wp), allocatable, dimension(:) :: x_cb, x_root_cb, y_cb, z_cb @@ -66,183 +71,240 @@ module m_global_parameters real(wp), allocatable, dimension(:) :: dx, dy, dz !> @} - integer :: buff_size !< Number of ghost cells for boundary condition storage + integer :: buff_size !< + !! Number of cells in buffer region. For the variables which feature a buffer + !! region, this region is used to store information outside the computational + !! domain based on the boundary conditions. + integer :: t_step_start !< First time-step directory integer :: t_step_stop !< Last time-step directory integer :: t_step_save !< Interval between consecutive time-step directory + !> @name IO options for adaptive time-stepping !> @{ - logical :: cfl_adap_dt, cfl_const_dt, cfl_dt + logical :: cfl_adap_dt, cfl_const_dt, cfl_dt real(wp) :: t_save real(wp) :: t_stop real(wp) :: cfl_target - integer :: n_save - integer :: n_start + integer :: n_save + integer :: n_start !> @} - ! NOTE: m_root, x_root_cb, x_root_cc = defragmented grid (1D only; equals m, x_cb, x_cc in serial) + ! NOTE: The variables m_root, x_root_cb and x_root_cc contain the grid data + ! of the defragmented computational domain. They are only used in 1D. For + ! serial simulations, they are equal to m, x_cb and x_cc, respectively. !> @name Simulation Algorithm Parameters !> @{ - integer :: model_eqns !< Multicomponent flow model - integer :: num_fluids !< Number of different fluids present in the flow - logical :: relax !< phase change - integer :: relax_model !< Phase change relaxation model - logical :: mpp_lim !< Maximum volume fraction limiter - integer :: sys_size !< Number of unknowns in the system of equations - integer :: recon_type !< Which type of reconstruction to use - integer :: weno_order !< Order of accuracy for the WENO reconstruction - integer :: muscl_order !< Order of accuracy for the MUSCL reconstruction - logical :: mixture_err !< Mixture error limiter - logical :: alt_soundspeed !< Alternate sound speed - logical :: mhd !< Magnetohydrodynamics - logical :: relativity !< Relativity for RMHD - logical :: hypoelasticity !< Turn hypoelasticity on - logical :: hyperelasticity !< Turn hyperelasticity on - logical :: elasticity !< elasticity modeling, true for hyper or hypo - integer :: b_size !< Number of components in the b tensor - integer :: tensor_size !< Number of components in the nonsymmetric tensor - logical :: cont_damage !< Continuum damage modeling - logical :: hyper_cleaning !< Hyperbolic cleaning for MHD - logical :: igr !< enable IGR - integer :: igr_order !< IGR reconstruction order - logical, parameter :: chemistry = .${chemistry}$. !< Chemistry modeling + integer :: model_eqns !< Multicomponent flow model + integer :: num_fluids !< Number of different fluids present in the flow + logical :: relax !< phase change + integer :: relax_model !< Phase change relaxation model + logical :: mpp_lim !< Maximum volume fraction limiter + integer :: sys_size !< Number of unknowns in the system of equations + integer :: recon_type !< Which type of reconstruction to use + integer :: weno_order !< Order of accuracy for the WENO reconstruction + integer :: muscl_order !< Order of accuracy for the MUSCL reconstruction + logical :: mixture_err !< Mixture error limiter + logical :: alt_soundspeed !< Alternate sound speed + logical :: mhd !< Magnetohydrodynamics + logical :: relativity !< Relativity for RMHD + logical :: hypoelasticity !< Turn hypoelasticity on + logical :: hyperelasticity !< Turn hyperelasticity on + logical :: elasticity !< elasticity modeling, true for hyper or hypo + integer :: b_size !< Number of components in the b tensor + integer :: tensor_size !< Number of components in the nonsymmetric tensor + logical :: cont_damage !< Continuum damage modeling + logical :: hyper_cleaning !< Hyperbolic cleaning for MHD + logical :: igr !< enable IGR + integer :: igr_order !< IGR reconstruction order + logical, parameter :: chemistry = .${chemistry}$. !< Chemistry modeling !> @} - integer :: avg_state !< Average state evaluation method + integer :: avg_state !< Average state evaluation method + !> @name Annotations of the structure, i.e. the organization, of the state vectors !> @{ type(int_bounds_info) :: cont_idx !< Indexes of first & last continuity eqns. type(int_bounds_info) :: mom_idx !< Indexes of first & last momentum eqns. - integer :: E_idx !< Index of energy equation - integer :: n_idx !< Index of number density - integer :: beta_idx !< Index of lagrange bubbles beta + integer :: E_idx !< Index of energy equation + integer :: n_idx !< Index of number density + integer :: beta_idx !< Index of lagrange bubbles beta type(int_bounds_info) :: adv_idx !< Indexes of first & last advection eqns. type(int_bounds_info) :: internalEnergies_idx !< Indexes of first & last internal energy eqns. type(bub_bounds_info) :: bub_idx !< Indexes of first & last bubble variable eqns. - integer :: gamma_idx !< Index of specific heat ratio func. eqn. - integer :: alf_idx !< Index of specific heat ratio func. eqn. - integer :: pi_inf_idx !< Index of liquid stiffness func. eqn. + integer :: gamma_idx !< Index of specific heat ratio func. eqn. + integer :: alf_idx !< Index of specific heat ratio func. eqn. + integer :: pi_inf_idx !< Index of liquid stiffness func. eqn. type(int_bounds_info) :: B_idx !< Indexes of first and last magnetic field eqns. type(int_bounds_info) :: stress_idx !< Indices of elastic stresses type(int_bounds_info) :: xi_idx !< Indexes of first and last reference map eqns. - integer :: c_idx !< Index of color function + integer :: c_idx !< Index of color function type(int_bounds_info) :: species_idx !< Indexes of first & last concentration eqns. - integer :: damage_idx !< Index of damage state variable (D) for continuum damage model - integer :: psi_idx !< Index of hyperbolic cleaning state variable for MHD + integer :: damage_idx !< Index of damage state variable (D) for continuum damage model + integer :: psi_idx !< Index of hyperbolic cleaning state variable for MHD !> @} - ! Cell Indices for the (local) interior points (O-m, O-n, 0-p). Stands for "InDices With BUFFer". + ! Cell Indices for the (local) interior points (O-m, O-n, 0-p). + ! Stands for "InDices With BUFFer". type(int_bounds_info) :: idwint(1:3) - ! Cell indices (InDices With BUFFer): includes buffer in simulation only + ! Cell Indices for the entire (local) domain. In simulation, this includes + ! the buffer region. idwbuff and idwint are the same otherwise. + ! Stands for "InDices With BUFFer". type(int_bounds_info) :: idwbuff(1:3) - integer :: num_bc_patches - logical :: bc_io + + integer :: num_bc_patches + logical :: bc_io !> @name Boundary conditions in the x-, y- and z-coordinate directions !> @{ type(int_bounds_info) :: bc_x, bc_y, bc_z !> @} - integer :: shear_num !< Number of shear stress components - integer, dimension(3) :: shear_indices !< Indices of the stress components that represent shear stress - integer :: shear_BC_flip_num !< Number of shear stress components to reflect for boundary conditions - integer, dimension(3, 2) :: shear_BC_flip_indices !< Shear stress BC reflection indices (1:3, 1:shear_BC_flip_num) - logical :: parallel_io !< Format of the data files - logical :: sim_data - logical :: file_per_process !< output format - integer, allocatable, dimension(:) :: proc_coords !< Processor coordinates in MPI_CART_COMM - integer, allocatable, dimension(:) :: start_idx !< Starting cell-center index of local processor in global grid - integer :: num_ibs !< Number of immersed boundaries + integer :: shear_num !! Number of shear stress components + integer, dimension(3) :: shear_indices !< + !! Indices of the stress components that represent shear stress + integer :: shear_BC_flip_num !< + !! Number of shear stress components to reflect for boundary conditions + integer, dimension(3, 2) :: shear_BC_flip_indices !< + !! Indices of shear stress components to reflect for boundary conditions. + !! Size: (1:3, 1:shear_BC_flip_num) for (x/y/z, [indices]) + + logical :: parallel_io !< Format of the data files + logical :: sim_data + logical :: file_per_process !< output format + + integer, allocatable, dimension(:) :: proc_coords !< + !! Processor coordinates in MPI_CART_COMM + + type(int_bounds_info), dimension(3) :: nidx + + integer, allocatable, dimension(:, :, :) :: neighbor_ranks + !! Neighbor processor ranks + + integer, allocatable, dimension(:) :: start_idx !< + !! Starting cell-center index of local processor in global grid + + integer :: num_ibs !< Number of immersed boundaries + #ifdef MFC_MPI - type(mpi_io_var), public :: MPI_IO_DATA - type(mpi_io_ib_var), public :: MPI_IO_IB_DATA - type(mpi_io_levelset_var), public :: MPI_IO_levelset_DATA - type(mpi_io_levelset_norm_var), public :: MPI_IO_levelsetnorm_DATA - real(wp), allocatable, dimension(:,:), public :: MPI_IO_DATA_lg_bubbles + + type(mpi_io_var), public :: MPI_IO_DATA + type(mpi_io_ib_var), public :: MPI_IO_IB_DATA + type(mpi_io_levelset_var), public :: MPI_IO_levelset_DATA + type(mpi_io_levelset_norm_var), public :: MPI_IO_levelsetnorm_DATA + real(wp), allocatable, dimension(:, :), public :: MPI_IO_DATA_lg_bubbles + #endif !> @name MPI info for parallel IO with Lustre file systems !> @{ character(LEN=name_len) :: mpiiofs - integer :: mpi_info_int + integer :: mpi_info_int !> @} - type(physical_parameters), dimension(num_fluids_max) :: fluid_pp !< Stiffened gas EOS parameters and Reynolds numbers per fluid + type(physical_parameters), dimension(num_fluids_max) :: fluid_pp !< + !! Database of the physical parameters of each of the fluids that is present + !! in the flow. These include the stiffened gas equation of state parameters, + !! and the Reynolds numbers. + ! Subgrid Bubble Parameters type(subgrid_bubble_physical_parameters) :: bub_pp - real(wp), allocatable, dimension(:) :: adv !< Advection variables + + real(wp), allocatable, dimension(:) :: adv !< Advection variables + ! Formatted Database File(s) Structure Parameters - integer :: format !< Format of the database file(s) - integer :: precision !< Floating point precision of the database file(s) - logical :: down_sample !< down sampling of the database file(s) - logical :: output_partial_domain !< Specify portion of domain to output for post-processing - type(bounds_info) :: x_output, y_output, z_output !< Portion of domain to output for post-processing - type(int_bounds_info) :: x_output_idx, y_output_idx, z_output_idx !< Indices of domain to output for post-processing - !> @name Size of the ghost zone layer in the x-, y- and z-coordinate directions. The definition of the ghost zone layers is only - !! necessary when using the Silo database file format in multidimensions. These zones provide VisIt with the subdomain - !! connectivity information that it requires in order to produce smooth plots. + integer :: format !< Format of the database file(s) + + integer :: precision !< Floating point precision of the database file(s) + logical :: down_sample !< down sampling of the database file(s) + + logical :: output_partial_domain !< Specify portion of domain to output for post-processing + + type(bounds_info) :: x_output, y_output, z_output !< Portion of domain to output for post-processing + type(int_bounds_info) :: x_output_idx, y_output_idx, z_output_idx !< Indices of domain to output for post-processing + + !> @name Size of the ghost zone layer in the x-, y- and z-coordinate directions. + !! The definition of the ghost zone layers is only necessary when using the + !! Silo database file format in multidimensions. These zones provide VisIt + !! with the subdomain connectivity information that it requires in order to + !! produce smooth plots. !> @{ type(int_bounds_info) :: offset_x, offset_y, offset_z !> @} - !> @name The list of all possible flow variables that may be written to a database file. It includes partial densities, density, - !! momentum, velocity, energy, pressure, volume fraction(s), specific heat ratio function, specific heat ratio, liquid stiffness - !! function, liquid stiffness, primitive variables, conservative variables, speed of sound, the vorticity, and the numerical - !! Schlieren function. + !> @name The list of all possible flow variables that may be written to a database + !! file. It includes partial densities, density, momentum, velocity, energy, + !! pressure, volume fraction(s), specific heat ratio function, specific heat + !! ratio, liquid stiffness function, liquid stiffness, primitive variables, + !! conservative variables, speed of sound, the vorticity, + !! and the numerical Schlieren function. !> @{ logical, dimension(num_fluids_max) :: alpha_rho_wrt - logical :: rho_wrt - logical, dimension(3) :: mom_wrt - logical, dimension(3) :: vel_wrt - integer :: flux_lim - logical, dimension(3) :: flux_wrt - logical :: E_wrt + logical :: rho_wrt + logical, dimension(3) :: mom_wrt + logical, dimension(3) :: vel_wrt + integer :: flux_lim + logical, dimension(3) :: flux_wrt + logical :: E_wrt logical, dimension(num_fluids_max) :: alpha_rho_e_wrt - logical :: fft_wrt - logical :: dummy !< AMDFlang workaround for case-optimization + GPU-kernel bug - logical :: pres_wrt + logical :: fft_wrt + logical :: dummy !< AMDFlang workaround: keep a dummy logical to avoid a compiler case-optimization bug when a parameter+GPU-kernel conditional is false + logical :: pres_wrt logical, dimension(num_fluids_max) :: alpha_wrt - logical :: gamma_wrt - logical :: heat_ratio_wrt - logical :: pi_inf_wrt - logical :: pres_inf_wrt - logical :: prim_vars_wrt - logical :: cons_vars_wrt - logical :: c_wrt - logical, dimension(3) :: omega_wrt - logical :: qm_wrt - logical :: liutex_wrt - logical :: schlieren_wrt - logical :: cf_wrt - logical :: ib - logical :: ib_state_wrt - logical :: chem_wrt_Y(1:num_species) - logical :: chem_wrt_T - logical :: lag_header - logical :: lag_txt_wrt - logical :: lag_db_wrt - logical :: lag_id_wrt - logical :: lag_pos_wrt - logical :: lag_pos_prev_wrt - logical :: lag_vel_wrt - logical :: lag_rad_wrt - logical :: lag_rvel_wrt - logical :: lag_r0_wrt - logical :: lag_rmax_wrt - logical :: lag_rmin_wrt - logical :: lag_dphidt_wrt - logical :: lag_pres_wrt - logical :: lag_mv_wrt - logical :: lag_mg_wrt - logical :: lag_betaT_wrt - logical :: lag_betaC_wrt + logical :: gamma_wrt + logical :: heat_ratio_wrt + logical :: pi_inf_wrt + logical :: pres_inf_wrt + logical :: prim_vars_wrt + logical :: cons_vars_wrt + logical :: c_wrt + logical, dimension(3) :: omega_wrt + logical :: qm_wrt + logical :: liutex_wrt + logical :: schlieren_wrt + logical :: cf_wrt + logical :: ib + logical :: ib_state_wrt + logical :: chem_wrt_Y(1:num_species) + logical :: chem_wrt_T + logical :: lag_header + logical :: lag_txt_wrt + logical :: lag_db_wrt + logical :: lag_id_wrt + logical :: lag_pos_wrt + logical :: lag_pos_prev_wrt + logical :: lag_vel_wrt + logical :: lag_rad_wrt + logical :: lag_rvel_wrt + logical :: lag_r0_wrt + logical :: lag_rmax_wrt + logical :: lag_rmin_wrt + logical :: lag_dphidt_wrt + logical :: lag_pres_wrt + logical :: lag_mv_wrt + logical :: lag_mg_wrt + logical :: lag_betaT_wrt + logical :: lag_betaC_wrt !> @} - real(wp), dimension(num_fluids_max) :: schlieren_alpha !< Per-fluid Schlieren intensity amplitude coefficients - integer :: fd_order !< Finite-difference order for vorticity and Schlieren derivatives - integer :: fd_number !< Finite-difference half-stencil size: MAX(1, fd_order/2) + real(wp), dimension(num_fluids_max) :: schlieren_alpha !< + !! Amplitude coefficients of the numerical Schlieren function that are used + !! to adjust the intensity of numerical Schlieren renderings for individual + !! fluids. This enables waves and interfaces of varying strengths and in all + !! of the fluids to be made simultaneously visible on a single plot. + + integer :: fd_order !< + !! The order of the finite-difference (fd) approximations of the first-order + !! derivatives that need to be evaluated when vorticity and/or the numerical + !! Schlieren function are to be outputted to the formatted database file(s). + + integer :: fd_number !< + !! The finite-difference number is given by MAX(1, fd_order/2). Essentially, + !! it is a measure of the half-size of the finite-difference stencil for the + !! selected order of accuracy. + !> @name Reference parameters for Tait EOS !> @{ real(wp) :: rhoref, pref @@ -264,7 +326,8 @@ module m_global_parameters real(wp) :: gam_m real(wp), dimension(:), allocatable :: pb0, mass_g0, mass_v0, Pe_T, k_v, k_g real(wp), dimension(:), allocatable :: Re_trans_T, Re_trans_c, Im_trans_T, Im_trans_c, omegaN - real(wp) :: R0ref, p0ref, rho0ref, T0ref, ss, pv, vd, mu_l, mu_v, mu_g, gam_v, gam_g, M_v, M_g, cp_v, cp_g, R_v, R_g + real(wp) :: R0ref, p0ref, rho0ref, T0ref, ss, pv, vd, mu_l, mu_v, mu_g, & + gam_v, gam_g, M_v, M_g, cp_v, cp_g, R_v, R_g real(wp) :: G real(wp) :: poly_sigma real(wp) :: sigR @@ -273,8 +336,9 @@ module m_global_parameters !> @name surface tension coefficient !> @{ + real(wp) :: sigma - logical :: surface_tension + logical :: surface_tension !> @} !> @name Index variables used for m_variables_conversion @@ -294,18 +358,20 @@ module m_global_parameters logical :: bubbles_lagrange !> @} - real(wp) :: Bx0 !< Constant magnetic field in the x-direction (1D) - real(wp) :: wall_time, wall_time_avg !< Wall time measurements + real(wp) :: Bx0 !< Constant magnetic field in the x-direction (1D) + + real(wp) :: wall_time, wall_time_avg !< Wall time measurements contains - !> Assigns default values to user inputs prior to reading them in. This allows for an easier consistency check of these - !! parameters once they are read from the input file. + !> Assigns default values to user inputs prior to reading + !! them in. This allows for an easier consistency check of + !! these parameters once they are read from the input file. impure subroutine s_assign_default_values_to_user_inputs - integer :: i !< Generic loop iterator - ! Logistics + integer :: i !< Generic loop iterator + ! Logistics case_dir = '.' ! Computational domain parameters @@ -391,8 +457,8 @@ contains bub_pp%gam_g = dflt_real; gam_g = dflt_real bub_pp%M_v = dflt_real; M_v = dflt_real bub_pp%M_g = dflt_real; M_g = dflt_real - bub_pp%k_v = dflt_real - bub_pp%k_g = dflt_real + bub_pp%k_v = dflt_real; + bub_pp%k_g = dflt_real; bub_pp%cp_v = dflt_real; cp_v = dflt_real bub_pp%cp_g = dflt_real; cp_g = dflt_real bub_pp%R_v = dflt_real; R_v = dflt_real @@ -495,22 +561,24 @@ contains end subroutine s_assign_default_values_to_user_inputs - !> Computation of parameters, allocation procedures, and/or any other tasks needed to properly setup the module + !> Computation of parameters, allocation procedures, and/or + !! any other tasks needed to properly setup the module impure subroutine s_initialize_global_parameters_module integer :: i, j, fac ! Setting m_root equal to m in the case of a 1D serial simulation - if (n == 0) m_root = m_glb ! Gamma/Pi_inf Model if (model_eqns == 1) then + ! Setting number of fluids num_fluids = 1 - ! Annotating structure of the state and flux vectors belonging to the system of equations defined by the selected number - ! of spatial dimensions and the gamma/pi_inf model + ! Annotating structure of the state and flux vectors belonging + ! to the system of equations defined by the selected number of + ! spatial dimensions and the gamma/pi_inf model cont_idx%beg = 1 cont_idx%end = cont_idx%beg mom_idx%beg = cont_idx%end + 1 @@ -524,8 +592,10 @@ contains ! Volume Fraction Model (5-equation model) else if (model_eqns == 2) then - ! Annotating structure of the state and flux vectors belonging to the system of equations defined by the selected number - ! of spatial dimensions and the volume fraction model + + ! Annotating structure of the state and flux vectors belonging + ! to the system of equations defined by the selected number of + ! spatial dimensions and the volume fraction model cont_idx%beg = 1 cont_idx%end = num_fluids mom_idx%beg = cont_idx%end + 1 @@ -533,14 +603,17 @@ contains E_idx = mom_idx%end + 1 if (igr) then - ! Volume fractions are stored in the indices immediately following the energy equation. IGR tracks a total of (N-1) - ! volume fractions for N fluids, hence the "-1" in adv_idx%end. If num_fluids = 1 then adv_idx%end < adv_idx%beg, - ! which skips all loops over the volume fractions since there is no volume fraction to track - adv_idx%beg = E_idx + 1 ! Alpha for fluid 1 + ! Volume fractions are stored in the indices immediately following + ! the energy equation. IGR tracks a total of (N-1) volume fractions + ! for N fluids, hence the "-1" in adv_idx%end. If num_fluids = 1 + ! then adv_idx%end < adv_idx%beg, which skips all loops over the + ! volume fractions since there is no volume fraction to track + adv_idx%beg = E_idx + 1 ! Alpha for fluid 1 adv_idx%end = E_idx + num_fluids - 1 else - ! Volume fractions are stored in the indices immediately following the energy equation. WENO/MUSCL + Riemann tracks - ! a total of (N) volume fractions for N fluids, hence the lack of "-1" in adv_idx%end + ! Volume fractions are stored in the indices immediately following + ! the energy equation. WENO/MUSCL + Riemann tracks a total of (N) + ! volume fractions for N fluids, hence the lack of "-1" in adv_idx%end adv_idx%beg = E_idx + 1 adv_idx%end = E_idx + num_fluids end if @@ -558,6 +631,7 @@ contains end if if (bubbles_euler) then + bub_idx%beg = sys_size + 1 if (qbmm) then bub_idx%end = adv_idx%end + nb*nmom @@ -606,25 +680,22 @@ contains end if end if - if (bubbles_lagrange) then - beta_idx = sys_size + 1 - sys_size = beta_idx - end if - if (mhd) then B_idx%beg = sys_size + 1 if (n == 0) then - B_idx%end = sys_size + 2 ! 1D: By, Bz + B_idx%end = sys_size + 2 ! 1D: By, Bz else - B_idx%end = sys_size + 3 ! 2D/3D: Bx, By, Bz + B_idx%end = sys_size + 3 ! 2D/3D: Bx, By, Bz end if sys_size = B_idx%end end if ! Volume Fraction Model (6-equation model) else if (model_eqns == 3) then - ! Annotating structure of the state and flux vectors belonging to the system of equations defined by the selected number - ! of spatial dimensions and the volume fraction model + + ! Annotating structure of the state and flux vectors belonging + ! to the system of equations defined by the selected number of + ! spatial dimensions and the volume fraction model cont_idx%beg = 1 cont_idx%end = num_fluids mom_idx%beg = cont_idx%end + 1 @@ -635,17 +706,18 @@ contains internalEnergies_idx%beg = adv_idx%end + 1 internalEnergies_idx%end = adv_idx%end + num_fluids sys_size = internalEnergies_idx%end - alf_idx = 1 ! dummy, cannot actually have a void fraction + alf_idx = 1 ! dummy, cannot actually have a void fraction + else if (model_eqns == 4) then - cont_idx%beg = 1 ! one continuity equation - cont_idx%end = 1 ! num_fluids - mom_idx%beg = cont_idx%end + 1 ! one momentum equation in each + cont_idx%beg = 1 ! one continuity equation + cont_idx%end = 1 !num_fluids + mom_idx%beg = cont_idx%end + 1 ! one momentum equation in each mom_idx%end = cont_idx%end + num_vels - E_idx = mom_idx%end + 1 ! one energy equation + E_idx = mom_idx%end + 1 ! one energy equation adv_idx%beg = E_idx + 1 - adv_idx%end = adv_idx%beg ! one volume advection equation + adv_idx%end = adv_idx%beg !one volume advection equation alf_idx = adv_idx%end - sys_size = alf_idx ! adv_idx%end + sys_size = alf_idx !adv_idx%end if (bubbles_euler) then bub_idx%beg = sys_size + 1 @@ -690,6 +762,7 @@ contains end if if (model_eqns == 2 .or. model_eqns == 3) then + if (hypoelasticity .or. hyperelasticity) then elasticity = .true. stress_idx%beg = sys_size + 1 @@ -705,16 +778,18 @@ contains shear_num = 1 shear_indices(1) = stress_idx%beg - 1 + 2 shear_BC_flip_num = 1 - shear_BC_flip_indices(1:2,1) = shear_indices(1) + shear_BC_flip_indices(1:2, 1) = shear_indices(1) ! Both x-dir and y-dir: flip tau_xy only else if (num_dims == 3) then shear_num = 3 shear_indices(1:3) = stress_idx%beg - 1 + (/2, 4, 5/) shear_BC_flip_num = 2 - shear_BC_flip_indices(1,1:2) = shear_indices((/1, 2/)) - shear_BC_flip_indices(2,1:2) = shear_indices((/1, 3/)) - shear_BC_flip_indices(3,1:2) = shear_indices((/2, 3/)) - ! x-dir: flip tau_xy and tau_xz y-dir: flip tau_xy and tau_yz z-dir: flip tau_xz and tau_yz + shear_BC_flip_indices(1, 1:2) = shear_indices((/1, 2/)) + shear_BC_flip_indices(2, 1:2) = shear_indices((/1, 3/)) + shear_BC_flip_indices(3, 1:2) = shear_indices((/2, 3/)) + ! x-dir: flip tau_xy and tau_xz + ! y-dir: flip tau_xy and tau_yz + ! z-dir: flip tau_xz and tau_yz end if end if @@ -733,6 +808,11 @@ contains sys_size = c_idx end if + if (bubbles_lagrange) then + beta_idx = sys_size + 1 + sys_size = beta_idx + end if + if (cont_damage) then damage_idx = sys_size + 1 sys_size = damage_idx @@ -746,6 +826,7 @@ contains else psi_idx = dflt_int end if + end if if (chemistry) then @@ -794,46 +875,58 @@ contains do i = 1, sys_size if (down_sample) then - allocate (MPI_IO_DATA%var(i)%sf(-1:m + 1,-1:n + 1,-1:p + 1)) + allocate (MPI_IO_DATA%var(i)%sf(-1:m + 1, -1:n + 1, -1:p + 1)) else - allocate (MPI_IO_DATA%var(i)%sf(0:m,0:n,0:p)) + allocate (MPI_IO_DATA%var(i)%sf(0:m, 0:n, 0:p)) end if MPI_IO_DATA%var(i)%sf => null() end do if (qbmm .and. .not. polytropic) then do i = sys_size + 1, sys_size + 2*nb*nnode - allocate (MPI_IO_DATA%var(i)%sf(0:m,0:n,0:p)) + allocate (MPI_IO_DATA%var(i)%sf(0:m, 0:n, 0:p)) MPI_IO_DATA%var(i)%sf => null() end do end if - if (ib) allocate (MPI_IO_IB_DATA%var%sf(0:m,0:n,0:p)) + if (ib) allocate (MPI_IO_IB_DATA%var%sf(0:m, 0:n, 0:p)) #endif - ! Size of the ghost zone layer is non-zero only when post-processing the raw simulation data of a parallel multidimensional - ! computation in the Silo-HDF5 format. If this is the case, one must also verify whether the raw simulation data is 2D or - ! 3D. In the 2D case, size of the z-coordinate direction ghost zone layer must be zeroed out. + ! Size of the ghost zone layer is non-zero only when post-processing + ! the raw simulation data of a parallel multidimensional computation + ! in the Silo-HDF5 format. If this is the case, one must also verify + ! whether the raw simulation data is 2D or 3D. In the 2D case, size + ! of the z-coordinate direction ghost zone layer must be zeroed out. if (num_procs == 1 .or. format /= 1) then + offset_x%beg = 0 offset_x%end = 0 offset_y%beg = 0 offset_y%end = 0 offset_z%beg = 0 offset_z%end = 0 - else if (n == 0) then + + elseif (n == 0) then + offset_y%beg = 0 offset_y%end = 0 offset_z%beg = 0 offset_z%end = 0 - else if (p == 0) then + + elseif (p == 0) then + offset_z%beg = 0 offset_z%end = 0 + end if - ! Determining the finite-difference number and the buffer size. Note that the size of the buffer is unrelated to the order - ! of the WENO scheme. Rather, it is directly dependent on maximum size of ghost zone layers and possibly the order of the - ! finite difference scheme used for the computation of vorticity and/or numerical Schlieren function. - buff_size = max(offset_x%beg, offset_x%end, offset_y%beg, offset_y%end, offset_z%beg, offset_z%end) + ! Determining the finite-difference number and the buffer size. Note + ! that the size of the buffer is unrelated to the order of the WENO + ! scheme. Rather, it is directly dependent on maximum size of ghost + ! zone layers and possibly the order of the finite difference scheme + ! used for the computation of vorticity and/or numerical Schlieren + ! function. + buff_size = max(offset_x%beg, offset_x%end, offset_y%beg, & + offset_y%end, offset_z%beg, offset_z%end) if (any(omega_wrt) .or. schlieren_wrt .or. qm_wrt .or. liutex_wrt) then fd_number = max(1, fd_order/2) @@ -862,6 +955,7 @@ contains ! Allocating grid variables in the y- and z-coordinate directions if (n > 0) then + allocate (y_cb(-1 - offset_y%beg:n + offset_y%end)) allocate (y_cc(-buff_size:n + buff_size)) allocate (dy(-buff_size:n + buff_size)) @@ -872,24 +966,26 @@ contains allocate (dz(-buff_size:p + buff_size)) end if - ! Allocating the grid variables, only used for the 1D simulations, and containing the defragmented computational domain - ! grid data + ! Allocating the grid variables, only used for the 1D simulations, + ! and containing the defragmented computational domain grid data else + allocate (x_root_cb(-1:m_root)) allocate (x_root_cc(0:m_root)) if (precision == 1) then allocate (x_root_cc_s(0:m_root)) end if + end if allocate (adv(num_fluids)) - if (cyl_coord .neqv. .true.) then ! Cartesian grid + if (cyl_coord .neqv. .true.) then ! Cartesian grid grid_geometry = 1 - else if (cyl_coord .and. p == 0) then ! Axisymmetric cylindrical grid + elseif (cyl_coord .and. p == 0) then ! Axisymmetric cylindrical grid grid_geometry = 2 - else ! Fully 3D cylindrical grid + else ! Fully 3D cylindrical grid grid_geometry = 3 end if @@ -899,7 +995,7 @@ contains impure subroutine s_initialize_parallel_io #ifdef MFC_MPI - integer :: ierr !< Generic flag used to identify and report MPI errors + integer :: ierr !< Generic flag used to identify and report MPI errors #endif num_dims = 1 + min(1, n) + min(1, p) @@ -915,16 +1011,20 @@ contains if (parallel_io .neqv. .true.) return #ifdef MFC_MPI + ! Option for Lustre file system (Darter/Comet/Stampede) write (mpiiofs, '(A)') '/lustre_' mpiiofs = trim(mpiiofs) call MPI_INFO_CREATE(mpi_info_int, ierr) call MPI_INFO_SET(mpi_info_int, 'romio_ds_write', 'disable', ierr) - ! Option for UNIX file system (Hooke/Thomson) WRITE(mpiiofs, '(A)') '/ufs_' mpiiofs = TRIM(mpiiofs) mpi_info_int = - ! MPI_INFO_NULL + ! Option for UNIX file system (Hooke/Thomson) + ! WRITE(mpiiofs, '(A)') '/ufs_' + ! mpiiofs = TRIM(mpiiofs) + ! mpi_info_int = MPI_INFO_NULL allocate (start_idx(1:num_dims)) + #endif end subroutine s_initialize_parallel_io @@ -935,7 +1035,6 @@ contains integer :: i ! Deallocating the grid variables for the x-coordinate direction - deallocate (x_cc, x_cb, dx) ! Deallocating grid variables for the y- and z-coordinate directions @@ -945,8 +1044,8 @@ contains deallocate (z_cc, z_cb, dz) end if else - ! Deallocating the grid variables, only used for the 1D simulations, and containing the defragmented computational - ! domain grid data + ! Deallocating the grid variables, only used for the 1D simulations, + ! and containing the defragmented computational domain grid data deallocate (x_root_cb, x_root_cc) end if @@ -955,6 +1054,7 @@ contains deallocate (adv) #ifdef MFC_MPI + if (parallel_io) then deallocate (start_idx) do i = 1, sys_size @@ -968,6 +1068,8 @@ contains if (ib) MPI_IO_IB_DATA%var%sf => null() #endif + if (allocated(neighbor_ranks)) deallocate (neighbor_ranks) + end subroutine s_finalize_global_parameters_module end module m_global_parameters diff --git a/src/post_process/m_mpi_proxy.fpp b/src/post_process/m_mpi_proxy.fpp index c91f140d39..d0a1311f4e 100644 --- a/src/post_process/m_mpi_proxy.fpp +++ b/src/post_process/m_mpi_proxy.fpp @@ -6,18 +6,22 @@ module m_mpi_proxy #ifdef MFC_MPI - use mpi !< Message passing interface (MPI) module + use mpi !< Message passing interface (MPI) module #endif - use m_derived_types - use m_global_parameters + use m_derived_types !< Definitions of the derived types + + use m_global_parameters !< Global parameters for the code + use m_mpi_common + use ieee_arithmetic implicit none - !> @name Receive counts and displacement vector variables, respectively, used in enabling MPI to gather varying amounts of data - !! from all processes to the root process + !> @name Receive counts and displacement vector variables, respectively, used in + !! enabling MPI to gather varying amounts of data from all processes to the + !! root process !> @{ integer, allocatable, dimension(:) :: recvcounts integer, allocatable, dimension(:) :: displs @@ -25,23 +29,28 @@ module m_mpi_proxy contains - !> Computation of parameters, allocation procedures, and/or any other tasks needed to properly setup the module + !> Computation of parameters, allocation procedures, and/or + !! any other tasks needed to properly setup the module impure subroutine s_initialize_mpi_proxy_module #ifdef MFC_MPI - integer :: i !< Generic loop iterator - integer :: ierr !< Generic flag used to identify and report MPI errors - ! Allocating and configuring the receive counts and the displacement vector variables used in variable-gather communication - ! procedures. Note that these are only needed for either multidimensional runs that utilize the Silo database file format or - ! for 1D simulations. + integer :: i !< Generic loop iterator + integer :: ierr !< Generic flag used to identify and report MPI errors + + ! Allocating and configuring the receive counts and the displacement + ! vector variables used in variable-gather communication procedures. + ! Note that these are only needed for either multidimensional runs + ! that utilize the Silo database file format or for 1D simulations. if ((format == 1 .and. n > 0) .or. n == 0) then + allocate (recvcounts(0:num_procs - 1)) allocate (displs(0:num_procs - 1)) if (n == 0) then - call MPI_GATHER(m + 1, 1, MPI_INTEGER, recvcounts(0), 1, MPI_INTEGER, 0, MPI_COMM_WORLD, ierr) - else if (proc_rank == 0) then + call MPI_GATHER(m + 1, 1, MPI_INTEGER, recvcounts(0), 1, & + MPI_INTEGER, 0, MPI_COMM_WORLD, ierr) + elseif (proc_rank == 0) then recvcounts = 1 end if @@ -52,20 +61,25 @@ contains displs(i) = displs(i - 1) + recvcounts(i - 1) end do end if + end if + #endif end subroutine s_initialize_mpi_proxy_module - !> Since only processor with rank 0 is in charge of reading and checking the consistency of the user provided inputs, these are - !! not available to the remaining processors. This subroutine is then in charge of broadcasting the required information. + !> Since only processor with rank 0 is in charge of reading + !! and checking the consistency of the user provided inputs, + !! these are not available to the remaining processors. This + !! subroutine is then in charge of broadcasting the required + !! information. impure subroutine s_mpi_bcast_user_inputs #ifdef MFC_MPI - integer :: i !< Generic loop iterator - integer :: ierr !< Generic flag used to identify and report MPI errors - ! Logistics + integer :: i !< Generic loop iterator + integer :: ierr !< Generic flag used to identify and report MPI errors + ! Logistics call MPI_BCAST(case_dir, len(case_dir), MPI_CHARACTER, 0, MPI_COMM_WORLD, ierr) #:for VAR in [ 'm', 'n', 'p', 'm_glb', 'n_glb', 'p_glb', & @@ -138,166 +152,248 @@ contains end subroutine s_mpi_bcast_user_inputs - !> Gather spatial extents from all ranks for Silo database metadata + !> This subroutine gathers the Silo database metadata for + !! the spatial extents in order to boost the performance of + !! the multidimensional visualization. + !! @param spatial_extents Spatial extents for each processor's sub-domain. First dimension + !! corresponds to the minimum and maximum values, respectively, while + !! the second dimension corresponds to the processor rank. impure subroutine s_mpi_gather_spatial_extents(spatial_extents) - real(wp), dimension(1:,0:), intent(inout) :: spatial_extents + real(wp), dimension(1:, 0:), intent(INOUT) :: spatial_extents #ifdef MFC_MPI - integer :: ierr !< Generic flag used to identify and report MPI errors + integer :: ierr !< Generic flag used to identify and report MPI errors real(wp) :: ext_temp(0:num_procs - 1) ! Simulation is 3D - if (p > 0) then if (grid_geometry == 3) then ! Minimum spatial extent in the r-direction - call MPI_GATHERV(minval(y_cb), 1, mpi_p, spatial_extents(1, 0), recvcounts, 6*displs, mpi_p, 0, MPI_COMM_WORLD, & - & ierr) + call MPI_GATHERV(minval(y_cb), 1, mpi_p, & + spatial_extents(1, 0), recvcounts, 6*displs, & + mpi_p, 0, MPI_COMM_WORLD, & + ierr) ! Minimum spatial extent in the theta-direction - call MPI_GATHERV(minval(z_cb), 1, mpi_p, spatial_extents(2, 0), recvcounts, 6*displs, mpi_p, 0, MPI_COMM_WORLD, & - & ierr) + call MPI_GATHERV(minval(z_cb), 1, mpi_p, & + spatial_extents(2, 0), recvcounts, 6*displs, & + mpi_p, 0, MPI_COMM_WORLD, & + ierr) ! Minimum spatial extent in the z-direction - call MPI_GATHERV(minval(x_cb), 1, mpi_p, spatial_extents(3, 0), recvcounts, 6*displs, mpi_p, 0, MPI_COMM_WORLD, & - & ierr) + call MPI_GATHERV(minval(x_cb), 1, mpi_p, & + spatial_extents(3, 0), recvcounts, 6*displs, & + mpi_p, 0, MPI_COMM_WORLD, & + ierr) ! Maximum spatial extent in the r-direction - call MPI_GATHERV(maxval(y_cb), 1, mpi_p, spatial_extents(4, 0), recvcounts, 6*displs, mpi_p, 0, MPI_COMM_WORLD, & - & ierr) + call MPI_GATHERV(maxval(y_cb), 1, mpi_p, & + spatial_extents(4, 0), recvcounts, 6*displs, & + mpi_p, 0, MPI_COMM_WORLD, & + ierr) ! Maximum spatial extent in the theta-direction - call MPI_GATHERV(maxval(z_cb), 1, mpi_p, spatial_extents(5, 0), recvcounts, 6*displs, mpi_p, 0, MPI_COMM_WORLD, & - & ierr) + call MPI_GATHERV(maxval(z_cb), 1, mpi_p, & + spatial_extents(5, 0), recvcounts, 6*displs, & + mpi_p, 0, MPI_COMM_WORLD, & + ierr) ! Maximum spatial extent in the z-direction - call MPI_GATHERV(maxval(x_cb), 1, mpi_p, spatial_extents(6, 0), recvcounts, 6*displs, mpi_p, 0, MPI_COMM_WORLD, & - & ierr) + call MPI_GATHERV(maxval(x_cb), 1, mpi_p, & + spatial_extents(6, 0), recvcounts, 6*displs, & + mpi_p, 0, MPI_COMM_WORLD, & + ierr) else ! Minimum spatial extent in the x-direction - call MPI_GATHERV(minval(x_cb), 1, mpi_p, spatial_extents(1, 0), recvcounts, 6*displs, mpi_p, 0, MPI_COMM_WORLD, & - & ierr) + call MPI_GATHERV(minval(x_cb), 1, mpi_p, & + spatial_extents(1, 0), recvcounts, 6*displs, & + mpi_p, 0, MPI_COMM_WORLD, & + ierr) ! Minimum spatial extent in the y-direction - call MPI_GATHERV(minval(y_cb), 1, mpi_p, spatial_extents(2, 0), recvcounts, 6*displs, mpi_p, 0, MPI_COMM_WORLD, & - & ierr) + call MPI_GATHERV(minval(y_cb), 1, mpi_p, & + spatial_extents(2, 0), recvcounts, 6*displs, & + mpi_p, 0, MPI_COMM_WORLD, & + ierr) ! Minimum spatial extent in the z-direction - call MPI_GATHERV(minval(z_cb), 1, mpi_p, spatial_extents(3, 0), recvcounts, 6*displs, mpi_p, 0, MPI_COMM_WORLD, & - & ierr) + call MPI_GATHERV(minval(z_cb), 1, mpi_p, & + spatial_extents(3, 0), recvcounts, 6*displs, & + mpi_p, 0, MPI_COMM_WORLD, & + ierr) ! Maximum spatial extent in the x-direction - call MPI_GATHERV(maxval(x_cb), 1, mpi_p, spatial_extents(4, 0), recvcounts, 6*displs, mpi_p, 0, MPI_COMM_WORLD, & - & ierr) + call MPI_GATHERV(maxval(x_cb), 1, mpi_p, & + spatial_extents(4, 0), recvcounts, 6*displs, & + mpi_p, 0, MPI_COMM_WORLD, & + ierr) ! Maximum spatial extent in the y-direction - call MPI_GATHERV(maxval(y_cb), 1, mpi_p, spatial_extents(5, 0), recvcounts, 6*displs, mpi_p, 0, MPI_COMM_WORLD, & - & ierr) + call MPI_GATHERV(maxval(y_cb), 1, mpi_p, & + spatial_extents(5, 0), recvcounts, 6*displs, & + mpi_p, 0, MPI_COMM_WORLD, & + ierr) ! Maximum spatial extent in the z-direction - call MPI_GATHERV(maxval(z_cb), 1, mpi_p, spatial_extents(6, 0), recvcounts, 6*displs, mpi_p, 0, MPI_COMM_WORLD, & - & ierr) + call MPI_GATHERV(maxval(z_cb), 1, mpi_p, & + spatial_extents(6, 0), recvcounts, 6*displs, & + mpi_p, 0, MPI_COMM_WORLD, & + ierr) end if ! Simulation is 2D - else if (n > 0) then + elseif (n > 0) then + ! Minimum spatial extent in the x-direction - call MPI_GATHERV(minval(x_cb), 1, mpi_p, spatial_extents(1, 0), recvcounts, 4*displs, mpi_p, 0, MPI_COMM_WORLD, ierr) + call MPI_GATHERV(minval(x_cb), 1, mpi_p, & + spatial_extents(1, 0), recvcounts, 4*displs, & + mpi_p, 0, MPI_COMM_WORLD, & + ierr) ! Minimum spatial extent in the y-direction - call MPI_GATHERV(minval(y_cb), 1, mpi_p, spatial_extents(2, 0), recvcounts, 4*displs, mpi_p, 0, MPI_COMM_WORLD, ierr) + call MPI_GATHERV(minval(y_cb), 1, mpi_p, & + spatial_extents(2, 0), recvcounts, 4*displs, & + mpi_p, 0, MPI_COMM_WORLD, & + ierr) ! Maximum spatial extent in the x-direction - call MPI_GATHERV(maxval(x_cb), 1, mpi_p, spatial_extents(3, 0), recvcounts, 4*displs, mpi_p, 0, MPI_COMM_WORLD, ierr) + call MPI_GATHERV(maxval(x_cb), 1, mpi_p, & + spatial_extents(3, 0), recvcounts, 4*displs, & + mpi_p, 0, MPI_COMM_WORLD, & + ierr) ! Maximum spatial extent in the y-direction - call MPI_GATHERV(maxval(y_cb), 1, mpi_p, spatial_extents(4, 0), recvcounts, 4*displs, mpi_p, 0, MPI_COMM_WORLD, ierr) + call MPI_GATHERV(maxval(y_cb), 1, mpi_p, & + spatial_extents(4, 0), recvcounts, 4*displs, & + mpi_p, 0, MPI_COMM_WORLD, & + ierr) ! Simulation is 1D else - ! For 1D, recvcounts/displs are sized for grid defragmentation (m+1 per rank), not for scalar gathers. Use MPI_GATHER - ! instead. + + ! For 1D, recvcounts/displs are sized for grid defragmentation + ! (m+1 per rank), not for scalar gathers. Use MPI_GATHER instead. ! Minimum spatial extent in the x-direction - call MPI_GATHER(minval(x_cb), 1, mpi_p, ext_temp, 1, mpi_p, 0, MPI_COMM_WORLD, ierr) - if (proc_rank == 0) spatial_extents(1,:) = ext_temp + call MPI_GATHER(minval(x_cb), 1, mpi_p, & + ext_temp, 1, mpi_p, 0, & + MPI_COMM_WORLD, ierr) + if (proc_rank == 0) spatial_extents(1, :) = ext_temp ! Maximum spatial extent in the x-direction - call MPI_GATHER(maxval(x_cb), 1, mpi_p, ext_temp, 1, mpi_p, 0, MPI_COMM_WORLD, ierr) - if (proc_rank == 0) spatial_extents(2,:) = ext_temp + call MPI_GATHER(maxval(x_cb), 1, mpi_p, & + ext_temp, 1, mpi_p, 0, & + MPI_COMM_WORLD, ierr) + if (proc_rank == 0) spatial_extents(2, :) = ext_temp end if + #endif end subroutine s_mpi_gather_spatial_extents - !> Collect the sub-domain cell-boundary or cell-center location data from all processors and put back together the grid of the - !! entire computational domain on the rank 0 processor. This is only done for 1D simulations. + !> This subroutine collects the sub-domain cell-boundary or + !! cell-center locations data from all of the processors and + !! puts back together the grid of the entire computational + !! domain on the rank 0 processor. This is only done for 1D + !! simulations. impure subroutine s_mpi_defragment_1d_grid_variable #ifdef MFC_MPI - integer :: ierr !< Generic flag used to identify and report MPI errors - ! Silo-HDF5 database format + integer :: ierr !< Generic flag used to identify and report MPI errors + ! Silo-HDF5 database format if (format == 1) then - call MPI_GATHERV(x_cc(0), m + 1, mpi_p, x_root_cc(0), recvcounts, displs, mpi_p, 0, MPI_COMM_WORLD, ierr) + + call MPI_GATHERV(x_cc(0), m + 1, mpi_p, & + x_root_cc(0), recvcounts, displs, & + mpi_p, 0, MPI_COMM_WORLD, & + ierr) ! Binary database format else - call MPI_GATHERV(x_cb(0), m + 1, mpi_p, x_root_cb(0), recvcounts, displs, mpi_p, 0, MPI_COMM_WORLD, ierr) + + call MPI_GATHERV(x_cb(0), m + 1, mpi_p, & + x_root_cb(0), recvcounts, displs, & + mpi_p, 0, MPI_COMM_WORLD, & + ierr) if (proc_rank == 0) x_root_cb(-1) = x_cb(-1) + end if + #endif end subroutine s_mpi_defragment_1d_grid_variable - !> Gather the Silo database metadata for the flow variable's extents to boost performance of the multidimensional visualization. - !! @param q_sf Flow variable on a single computational sub-domain + !> This subroutine gathers the Silo database metadata for + !! the flow variable's extents as to boost performance of + !! the multidimensional visualization. + !! @param q_sf Flow variable defined on a single computational sub-domain + !! @param data_extents The flow variable extents on each of the processor's sub-domain. + !! First dimension of array corresponds to the former's minimum and + !! maximum values, respectively, while second dimension corresponds + !! to each processor's rank. impure subroutine s_mpi_gather_data_extents(q_sf, data_extents) - real(wp), dimension(:,:,:), intent(in) :: q_sf - real(wp), dimension(1:2,0:num_procs - 1), intent(inout) :: data_extents + real(wp), dimension(:, :, :), intent(in) :: q_sf + real(wp), dimension(1:2, 0:num_procs - 1), intent(inout) :: data_extents #ifdef MFC_MPI - integer :: ierr !< Generic flag used to identify and report MPI errors + integer :: ierr !< Generic flag used to identify and report MPI errors real(wp) :: ext_temp(0:num_procs - 1) if (n > 0) then - ! Multi-D: recvcounts = 1, so strided MPI_GATHERV works correctly Minimum flow variable extent - call MPI_GATHERV(minval(q_sf), 1, mpi_p, data_extents(1, 0), recvcounts, 2*displs, mpi_p, 0, MPI_COMM_WORLD, ierr) + ! Multi-D: recvcounts = 1, so strided MPI_GATHERV works correctly + ! Minimum flow variable extent + call MPI_GATHERV(minval(q_sf), 1, mpi_p, & + data_extents(1, 0), recvcounts, 2*displs, & + mpi_p, 0, MPI_COMM_WORLD, ierr) ! Maximum flow variable extent - call MPI_GATHERV(maxval(q_sf), 1, mpi_p, data_extents(2, 0), recvcounts, 2*displs, mpi_p, 0, MPI_COMM_WORLD, ierr) + call MPI_GATHERV(maxval(q_sf), 1, mpi_p, & + data_extents(2, 0), recvcounts, 2*displs, & + mpi_p, 0, MPI_COMM_WORLD, ierr) else - ! 1D: recvcounts/displs are sized for grid defragmentation (m+1 per rank), not for scalar gathers. Use MPI_GATHER - ! instead. + ! 1D: recvcounts/displs are sized for grid defragmentation + ! (m+1 per rank), not for scalar gathers. Use MPI_GATHER instead. ! Minimum flow variable extent - call MPI_GATHER(minval(q_sf), 1, mpi_p, ext_temp, 1, mpi_p, 0, MPI_COMM_WORLD, ierr) - if (proc_rank == 0) data_extents(1,:) = ext_temp + call MPI_GATHER(minval(q_sf), 1, mpi_p, & + ext_temp, 1, mpi_p, 0, & + MPI_COMM_WORLD, ierr) + if (proc_rank == 0) data_extents(1, :) = ext_temp ! Maximum flow variable extent - call MPI_GATHER(maxval(q_sf), 1, mpi_p, ext_temp, 1, mpi_p, 0, MPI_COMM_WORLD, ierr) - if (proc_rank == 0) data_extents(2,:) = ext_temp + call MPI_GATHER(maxval(q_sf), 1, mpi_p, & + ext_temp, 1, mpi_p, 0, & + MPI_COMM_WORLD, ierr) + if (proc_rank == 0) data_extents(2, :) = ext_temp end if + #endif end subroutine s_mpi_gather_data_extents - !> Gather the sub-domain flow variable data from all processors and reassemble it for the entire computational domain on the - !! rank 0 processor. This is only done for 1D simulations. - !! @param q_sf Flow variable on a single computational sub-domain - !! @param q_root_sf Flow variable on the entire computational domain + !> This subroutine gathers the sub-domain flow variable data + !! from all of the processors and puts it back together for + !! the entire computational domain on the rank 0 processor. + !! This is only done for 1D simulations. + !! @param q_sf Flow variable defined on a single computational sub-domain + !! @param q_root_sf Flow variable defined on the entire computational domain impure subroutine s_mpi_defragment_1d_flow_variable(q_sf, q_root_sf) - real(wp), dimension(0:m), intent(in) :: q_sf + real(wp), dimension(0:m), intent(in) :: q_sf real(wp), dimension(0:m), intent(inout) :: q_root_sf #ifdef MFC_MPI - integer :: ierr !< Generic flag used to identify and report MPI errors - ! Gathering the sub-domain flow variable data from all the processes and putting it back together for the entire - ! computational domain on the process with rank 0 + integer :: ierr !< Generic flag used to identify and report MPI errors + + ! Gathering the sub-domain flow variable data from all the processes + ! and putting it back together for the entire computational domain + ! on the process with rank 0 + call MPI_GATHERV(q_sf(0), m + 1, mpi_p, & + q_root_sf(0), recvcounts, displs, & + mpi_p, 0, MPI_COMM_WORLD, ierr) - call MPI_GATHERV(q_sf(0), m + 1, mpi_p, q_root_sf(0), recvcounts, displs, mpi_p, 0, MPI_COMM_WORLD, ierr) #endif end subroutine s_mpi_defragment_1d_flow_variable @@ -306,11 +402,14 @@ contains impure subroutine s_finalize_mpi_proxy_module #ifdef MFC_MPI - ! Deallocating the receive counts and the displacement vector variables used in variable-gather communication procedures + + ! Deallocating the receive counts and the displacement vector + ! variables used in variable-gather communication procedures if ((format == 1 .and. n > 0) .or. n == 0) then deallocate (recvcounts) deallocate (displs) end if + #endif end subroutine s_finalize_mpi_proxy_module diff --git a/src/post_process/m_start_up.fpp b/src/post_process/m_start_up.fpp index c65e4cf7cf..7ae3dbfebe 100644 --- a/src/post_process/m_start_up.fpp +++ b/src/post_process/m_start_up.fpp @@ -8,82 +8,133 @@ module m_start_up + ! Dependencies + use, intrinsic :: iso_c_binding - use m_derived_types - use m_global_parameters - use m_mpi_proxy - use m_mpi_common - use m_boundary_common - use m_variables_conversion - use m_data_input - use m_data_output - use m_derived_variables + use m_derived_types !< Definitions of the derived types + + use m_global_parameters !< Global parameters for the code + + use m_mpi_proxy !< Message passing interface (MPI) module proxy + + use m_mpi_common !< Common MPI subroutines + + use m_boundary_common !< Common boundary conditions subroutines + + use m_variables_conversion !< Subroutines to change the state variables from + !! one form to another + + use m_data_input !< Procedures reading raw simulation data to fill + !! the conservative, primitive and grid variables + + use m_data_output !< Procedures that write the grid and chosen flow + !! variable(s) to the formatted database file(s) + + use m_derived_variables !< Procedures used to compute quantities derived + !! from the conservative and primitive variables use m_helper + use m_compile_specific + use m_checker_common + use m_checker + use m_thermochem, only: num_species, species_names + use m_finite_differences + use m_chemistry #ifdef MFC_MPI - use mpi + use mpi !< Message passing interface (MPI) module #endif implicit none include 'fftw3.f03' - type(c_ptr) :: fwd_plan_x, fwd_plan_y, fwd_plan_z - complex(c_double_complex), allocatable :: data_in(:), data_out(:) - complex(c_double_complex), allocatable :: data_cmplx(:,:,:), data_cmplx_y(:,:,:), data_cmplx_z(:,:,:) - real(wp), allocatable, dimension(:,:,:) :: En_real - real(wp), allocatable, dimension(:) :: En - integer :: num_procs_x, num_procs_y, num_procs_z - integer :: Nx, Ny, Nz, Nxloc, Nyloc, Nyloc2, Nzloc, Nf - integer :: ierr - integer :: MPI_COMM_CART, MPI_COMM_CART12, MPI_COMM_CART13 - integer, dimension(3) :: cart3d_coords - integer, dimension(2) :: cart2d12_coords, cart2d13_coords - integer :: proc_rank12, proc_rank13 + type(c_ptr) :: fwd_plan_x, fwd_plan_y, fwd_plan_z + complex(c_double_complex), allocatable :: data_in(:), data_out(:) + complex(c_double_complex), allocatable :: data_cmplx(:, :, :), data_cmplx_y(:, :, :), data_cmplx_z(:, :, :) + real(wp), allocatable, dimension(:, :, :) :: En_real + real(wp), allocatable, dimension(:) :: En + integer :: num_procs_x, num_procs_y, num_procs_z + integer :: Nx, Ny, Nz, Nxloc, Nyloc, Nyloc2, Nzloc, Nf + integer :: ierr + integer :: MPI_COMM_CART, MPI_COMM_CART12, MPI_COMM_CART13 + integer, dimension(3) :: cart3d_coords + integer, dimension(2) :: cart2d12_coords, cart2d13_coords + integer :: proc_rank12, proc_rank13 contains - !> Reads the configuration file post_process.inp, in order to populate parameters in module m_global_parameters.f90 with the - !! user provided inputs + !> Reads the configuration file post_process.inp, in order + !! to populate parameters in module m_global_parameters.f90 + !! with the user provided inputs impure subroutine s_read_input_file - character(LEN=name_len) :: file_loc - logical :: file_check - integer :: iostatus - character(len=1000) :: line - - namelist /user_inputs/ case_dir, m, n, p, t_step_start, t_step_stop, t_step_save, model_eqns, num_fluids, mpp_lim, & - & weno_order, bc_x, bc_y, bc_z, fluid_pp, bub_pp, format, precision, output_partial_domain, x_output, y_output, & - & z_output, hypoelasticity, G, mhd, chem_wrt_Y, chem_wrt_T, avg_state, alpha_rho_wrt, rho_wrt, mom_wrt, vel_wrt, & - & E_wrt, fft_wrt, pres_wrt, alpha_wrt, gamma_wrt, heat_ratio_wrt, pi_inf_wrt, pres_inf_wrt, cons_vars_wrt, & - & prim_vars_wrt, c_wrt, omega_wrt, qm_wrt, liutex_wrt, schlieren_wrt, schlieren_alpha, fd_order, mixture_err, & - & alt_soundspeed, flux_lim, flux_wrt, cyl_coord, parallel_io, rhoref, pref, bubbles_euler, qbmm, sigR, R0ref, nb, & - & polytropic, thermal, Ca, Web, Re_inv, polydisperse, poly_sigma, file_per_process, relax, relax_model, cf_wrt, & - & sigma, adv_n, ib, num_ibs, cfl_adap_dt, cfl_const_dt, t_save, t_stop, n_start, cfl_target, surface_tension, & - & bubbles_lagrange, sim_data, hyperelasticity, Bx0, relativity, cont_damage, hyper_cleaning, num_bc_patches, igr, & - & igr_order, down_sample, recon_type, muscl_order, lag_header, lag_txt_wrt, lag_db_wrt, lag_id_wrt, lag_pos_wrt, & - & lag_pos_prev_wrt, lag_vel_wrt, lag_rad_wrt, lag_rvel_wrt, lag_r0_wrt, lag_rmax_wrt, lag_rmin_wrt, lag_dphidt_wrt, & - & lag_pres_wrt, lag_mv_wrt, lag_mg_wrt, lag_betaT_wrt, lag_betaC_wrt, alpha_rho_e_wrt, ib_state_wrt - + character(LEN=name_len) :: file_loc !< + !! Generic string used to store the address of a particular file + + logical :: file_check !< + !! Generic logical used for the purpose of asserting whether a file + !! is or is not present in the designated location + + integer :: iostatus + !! Integer to check iostat of file read + + character(len=1000) :: line + + ! Namelist for all of the parameters to be inputted by the user + namelist /user_inputs/ case_dir, m, n, p, t_step_start, & + t_step_stop, t_step_save, model_eqns, & + num_fluids, mpp_lim, & + weno_order, bc_x, & + bc_y, bc_z, fluid_pp, bub_pp, format, precision, & + output_partial_domain, x_output, y_output, z_output, & + hypoelasticity, G, mhd, & + chem_wrt_Y, chem_wrt_T, avg_state, & + alpha_rho_wrt, rho_wrt, mom_wrt, vel_wrt, & + E_wrt, fft_wrt, pres_wrt, alpha_wrt, gamma_wrt, & + heat_ratio_wrt, pi_inf_wrt, pres_inf_wrt, & + cons_vars_wrt, prim_vars_wrt, c_wrt, & + omega_wrt, qm_wrt, liutex_wrt, schlieren_wrt, schlieren_alpha, & + fd_order, mixture_err, alt_soundspeed, & + flux_lim, flux_wrt, cyl_coord, & + parallel_io, rhoref, pref, bubbles_euler, qbmm, sigR, & + R0ref, nb, polytropic, thermal, Ca, Web, Re_inv, & + polydisperse, poly_sigma, file_per_process, relax, & + relax_model, cf_wrt, sigma, adv_n, ib, num_ibs, & + cfl_adap_dt, cfl_const_dt, t_save, t_stop, n_start, & + cfl_target, surface_tension, bubbles_lagrange, & + sim_data, hyperelasticity, Bx0, relativity, cont_damage, hyper_cleaning, & + num_bc_patches, igr, igr_order, down_sample, recon_type, & + muscl_order, lag_header, lag_txt_wrt, lag_db_wrt, & + lag_id_wrt, lag_pos_wrt, lag_pos_prev_wrt, lag_vel_wrt, & + lag_rad_wrt, lag_rvel_wrt, lag_r0_wrt, lag_rmax_wrt, & + lag_rmin_wrt, lag_dphidt_wrt, lag_pres_wrt, lag_mv_wrt, & + lag_mg_wrt, lag_betaT_wrt, lag_betaC_wrt, & + alpha_rho_e_wrt, ib_state_wrt + + ! Inquiring the status of the post_process.inp file file_loc = 'post_process.inp' inquire (FILE=trim(file_loc), EXIST=file_check) + ! Checking whether the input file is there. If it is, the input file + ! is read. If not, the program is terminated. if (file_check) then - open (1, FILE=trim(file_loc), form='formatted', STATUS='old', ACTION='read') + open (1, FILE=trim(file_loc), FORM='formatted', & + STATUS='old', ACTION='read') read (1, NML=user_inputs, iostat=iostatus) if (iostatus /= 0) then backspace (1) read (1, fmt='(A)') line - print *, 'Invalid line in namelist: ' // trim(line) - call s_mpi_abort('Invalid line in post_process.inp. It is ' // 'likely due to a datatype mismatch. Exiting.') + print *, 'Invalid line in namelist: '//trim(line) + call s_mpi_abort('Invalid line in post_process.inp. It is '// & + 'likely due to a datatype mismatch. Exiting.') end if close (1) @@ -96,6 +147,7 @@ contains p = int((p + 1)/3) - 1 end if + ! Store m,n,p into global m,n,p m_glb = m n_glb = n p_glb = p @@ -104,30 +156,40 @@ contains if (cfl_adap_dt .or. cfl_const_dt) cfl_dt = .true. - if (any((/bc_x%beg, bc_x%end, bc_y%beg, bc_y%end, bc_z%beg, bc_z%end/) == -17) .or. num_bc_patches > 0) then + if (any((/bc_x%beg, bc_x%end, bc_y%beg, bc_y%end, bc_z%beg, bc_z%end/) == -17) .or. & + num_bc_patches > 0) then bc_io = .true. end if + else call s_mpi_abort('File post_process.inp is missing. Exiting.') end if end subroutine s_read_input_file - !> Checking that the user inputs make sense, i.e. that the individual choices are compatible with the code's options and that - !! the combination of these choices results into a valid configuration for the post-process + !> Checking that the user inputs make sense, i.e. that the + !! individual choices are compatible with the code's options + !! and that the combination of these choices results into a + !! valid configuration for the post-process impure subroutine s_check_input_file - character(LEN=len_trim(case_dir)) :: file_loc - logical :: dir_check + character(LEN=len_trim(case_dir)) :: file_loc !< + !! Generic string used to store the address of a particular file + + logical :: dir_check !< + !! Logical variable used to test the existence of folders + ! Checking the existence of the case folder case_dir = adjustl(case_dir) - file_loc = trim(case_dir) // '/.' + file_loc = trim(case_dir)//'/.' call my_inquire(file_loc, dir_check) + ! Constraint on the location of the case directory if (dir_check .neqv. .true.) then - call s_mpi_abort('Unsupported choice for the value of ' // 'case_dir. Exiting.') + call s_mpi_abort('Unsupported choice for the value of '// & + 'case_dir. Exiting.') end if call s_check_inputs_common() @@ -135,53 +197,59 @@ contains end subroutine s_check_input_file - !> Load grid and conservative data for a time step, fill ghost-cell buffers, and convert to primitive variables. + !> @brief Load grid and conservative data for a time step, fill ghost-cell buffers, and convert to primitive variables. impure subroutine s_perform_time_step(t_step) integer, intent(inout) :: t_step - if (proc_rank == 0) then if (cfl_dt) then print '(" [", I3, "%] Saving ", I8, " of ", I0, " Time Avg = ", ES16.6, " Time/step = ", ES12.6, "")', & - & int(ceiling(100._wp*(real(t_step - n_start)/(n_save)))), t_step, n_save, wall_time_avg, wall_time + int(ceiling(100._wp*(real(t_step - n_start)/(n_save)))), & + t_step, n_save, wall_time_avg, wall_time else print '(" [", I3, "%] Saving ", I8, " of ", I0, " @ t_step = ", I8, " Time Avg = ", ES16.6, " Time/step = ", ES12.6, "")', & - & int(ceiling(100._wp*(real(t_step - t_step_start)/(t_step_stop - t_step_start + 1)))), & - & (t_step - t_step_start)/t_step_save + 1, (t_step_stop - t_step_start)/t_step_save + 1, t_step, & - & wall_time_avg, wall_time + int(ceiling(100._wp*(real(t_step - t_step_start)/(t_step_stop - t_step_start + 1)))), & + (t_step - t_step_start)/t_step_save + 1, & + (t_step_stop - t_step_start)/t_step_save + 1, & + t_step, wall_time_avg, wall_time end if end if + ! Populating the grid and conservative variables call s_read_data_files(t_step) + ! Populating the buffer regions of the grid and conservative variables if (buff_size > 0) then call s_populate_grid_variables_buffers() call s_populate_variables_buffers(bc_type, q_cons_vf) end if + ! Initialize the Temperature cache. if (chemistry) call s_compute_q_T_sf(q_T_sf, q_cons_vf, idwbuff) + ! Converting the conservative variables to the primitive ones call s_convert_conservative_to_primitive_variables(q_cons_vf, q_T_sf, q_prim_vf, idwbuff) end subroutine s_perform_time_step - !> Derive requested flow quantities from primitive variables and write them to the formatted database files. + !> @brief Derive requested flow quantities from primitive variables and write them to the formatted database files. impure subroutine s_save_data(t_step, varname, pres, c, H) - integer, intent(inout) :: t_step + integer, intent(inout) :: t_step character(LEN=name_len), intent(inout) :: varname - real(wp), intent(inout) :: pres, c, H - real(wp) :: theta1, theta2 - - real(wp), dimension(-offset_x%beg:m + offset_x%end,-offset_y%beg:n + offset_y%end, & - & -offset_z%beg:p + offset_z%end) :: liutex_mag - real(wp), dimension(-offset_x%beg:m + offset_x%end,-offset_y%beg:n + offset_y%end,-offset_z%beg:p + offset_z%end, & - & 3) :: liutex_axis - integer :: i, j, k, l, kx, ky, kz, kf, j_glb, k_glb, l_glb - real(wp) :: En_tot + real(wp), intent(inout) :: pres, c, H + real(wp) :: theta1, theta2 + real(wp), dimension(-offset_x%beg:m + offset_x%end, & + -offset_y%beg:n + offset_y%end, & + -offset_z%beg:p + offset_z%end) :: liutex_mag + real(wp), dimension(-offset_x%beg:m + offset_x%end, & + -offset_y%beg:n + offset_y%end, & + -offset_z%beg:p + offset_z%end, 3) :: liutex_axis + integer :: i, j, k, l, kx, ky, kz, kf, j_glb, k_glb, l_glb + real(wp) :: En_tot character(50) :: filename, dirname - logical :: file_exists, dir_exists - integer :: x_beg, x_end, y_beg, y_end, z_beg, z_end + logical :: file_exists, dir_exists + integer :: x_beg, x_end, y_beg, y_end, z_beg, z_end if (output_partial_domain) then call s_define_output_region @@ -200,6 +268,7 @@ contains z_end = offset_z%end + p end if + ! Opening a new formatted database file call s_open_formatted_database_file(t_step) if (sim_data .and. proc_rank == 0) then @@ -212,24 +281,35 @@ contains call s_write_energy_data_file(q_prim_vf, q_cons_vf) end if + ! Adding the grid to the formatted database file call s_write_grid_to_formatted_database_file(t_step) + ! Computing centered finite-difference coefficients in x-direction if (omega_wrt(2) .or. omega_wrt(3) .or. qm_wrt .or. liutex_wrt .or. schlieren_wrt) then - call s_compute_finite_difference_coefficients(m, x_cc, fd_coeff_x, buff_size, fd_number, fd_order, offset_x) + call s_compute_finite_difference_coefficients(m, x_cc, & + fd_coeff_x, buff_size, & + fd_number, fd_order, offset_x) end if + ! Computing centered finite-difference coefficients in y-direction if (omega_wrt(1) .or. omega_wrt(3) .or. qm_wrt .or. liutex_wrt .or. (n > 0 .and. schlieren_wrt)) then - call s_compute_finite_difference_coefficients(n, y_cc, fd_coeff_y, buff_size, fd_number, fd_order, offset_y) + call s_compute_finite_difference_coefficients(n, y_cc, & + fd_coeff_y, buff_size, & + fd_number, fd_order, offset_y) end if + ! Computing centered finite-difference coefficients in z-direction if (omega_wrt(1) .or. omega_wrt(2) .or. qm_wrt .or. liutex_wrt .or. (p > 0 .and. schlieren_wrt)) then - call s_compute_finite_difference_coefficients(p, z_cc, fd_coeff_z, buff_size, fd_number, fd_order, offset_z) + call s_compute_finite_difference_coefficients(p, z_cc, & + fd_coeff_z, buff_size, & + fd_number, fd_order, offset_z) end if + ! Adding the partial densities to the formatted database file if ((model_eqns == 2) .or. (model_eqns == 3) .or. (model_eqns == 4)) then do i = 1, num_fluids if (alpha_rho_wrt(i) .or. (cons_vars_wrt .or. prim_vars_wrt)) then - q_sf(:,:,:) = q_cons_vf(i)%sf(x_beg:x_end,y_beg:y_end,z_beg:z_end) + q_sf(:, :, :) = q_cons_vf(i)%sf(x_beg:x_end, y_beg:y_end, z_beg:z_end) if (model_eqns /= 4) then write (varname, '(A,I0)') 'alpha_rho', i else @@ -238,12 +318,14 @@ contains call s_write_variable_to_formatted_database_file(varname, t_step) varname(:) = ' ' + end if end do end if + ! Adding the density to the formatted database file if ((rho_wrt .or. (model_eqns == 1 .and. (cons_vars_wrt .or. prim_vars_wrt))) .and. (.not. relativity)) then - q_sf(:,:,:) = rho_sf(x_beg:x_end,y_beg:y_end,z_beg:z_end) + q_sf(:, :, :) = rho_sf(x_beg:x_end, y_beg:y_end, z_beg:z_end) write (varname, '(A)') 'rho' call s_write_variable_to_formatted_database_file(varname, t_step) @@ -251,7 +333,7 @@ contains end if if (relativity .and. (rho_wrt .or. prim_vars_wrt)) then - q_sf(:,:,:) = q_prim_vf(1)%sf(x_beg:x_end,y_beg:y_end,z_beg:z_end) + q_sf(:, :, :) = q_prim_vf(1)%sf(x_beg:x_end, y_beg:y_end, z_beg:z_end) write (varname, '(A)') 'rho' call s_write_variable_to_formatted_database_file(varname, t_step) @@ -259,47 +341,54 @@ contains end if if (relativity .and. (rho_wrt .or. cons_vars_wrt)) then - ! For relativistic flow, conservative and primitive densities are different Hard-coded single-component for now - q_sf(:,:,:) = q_cons_vf(1)%sf(x_beg:x_end,y_beg:y_end,z_beg:z_end) + ! For relativistic flow, conservative and primitive densities are different + ! Hard-coded single-component for now + q_sf(:, :, :) = q_cons_vf(1)%sf(x_beg:x_end, y_beg:y_end, z_beg:z_end) write (varname, '(A)') 'D' call s_write_variable_to_formatted_database_file(varname, t_step) varname(:) = ' ' end if + ! Adding the momentum to the formatted database file do i = 1, E_idx - mom_idx%beg if (mom_wrt(i) .or. cons_vars_wrt) then - q_sf(:,:,:) = q_cons_vf(i + cont_idx%end)%sf(x_beg:x_end,y_beg:y_end,z_beg:z_end) + q_sf(:, :, :) = q_cons_vf(i + cont_idx%end)%sf(x_beg:x_end, y_beg:y_end, z_beg:z_end) write (varname, '(A,I0)') 'mom', i call s_write_variable_to_formatted_database_file(varname, t_step) varname(:) = ' ' + end if end do + ! Adding the velocity to the formatted database file do i = 1, E_idx - mom_idx%beg if (vel_wrt(i) .or. prim_vars_wrt) then - q_sf(:,:,:) = q_prim_vf(i + cont_idx%end)%sf(x_beg:x_end,y_beg:y_end,z_beg:z_end) + q_sf(:, :, :) = q_prim_vf(i + cont_idx%end)%sf(x_beg:x_end, y_beg:y_end, z_beg:z_end) write (varname, '(A,I0)') 'vel', i call s_write_variable_to_formatted_database_file(varname, t_step) varname(:) = ' ' + end if end do + ! Adding the species' concentrations to the formatted database file if (chemistry) then do i = 1, num_species if (chem_wrt_Y(i) .or. prim_vars_wrt) then - q_sf(:,:,:) = q_prim_vf(chemxb + i - 1)%sf(x_beg:x_end,y_beg:y_end,z_beg:z_end) + q_sf(:, :, :) = q_prim_vf(chemxb + i - 1)%sf(x_beg:x_end, y_beg:y_end, z_beg:z_end) write (varname, '(A,A)') 'Y_', trim(species_names(i)) call s_write_variable_to_formatted_database_file(varname, t_step) varname(:) = ' ' + end if end do if (chem_wrt_T) then - q_sf(:,:,:) = q_T_sf%sf(x_beg:x_end,y_beg:y_end,z_beg:z_end) + q_sf(:, :, :) = q_T_sf%sf(x_beg:x_end, y_beg:y_end, z_beg:z_end) write (varname, '(A)') 'T' call s_write_variable_to_formatted_database_file(varname, t_step) @@ -307,8 +396,10 @@ contains end if end if + ! Adding the flux limiter function to the formatted database file do i = 1, E_idx - mom_idx%beg if (flux_wrt(i)) then + call s_derive_flux_limiter(i, q_prim_vf, q_sf) write (varname, '(A,I0)') 'flux', i @@ -318,18 +409,21 @@ contains end if end do + ! Adding the energy to the formatted database file if (E_wrt .or. cons_vars_wrt) then - q_sf(:,:,:) = q_cons_vf(E_idx)%sf(x_beg:x_end,y_beg:y_end,z_beg:z_end) + q_sf(:, :, :) = q_cons_vf(E_idx)%sf(x_beg:x_end, y_beg:y_end, z_beg:z_end) write (varname, '(A)') 'E' call s_write_variable_to_formatted_database_file(varname, t_step) varname(:) = ' ' + end if + ! Adding the individual energies to the formatted database file if (model_eqns == 3) then do i = 1, num_fluids if (alpha_rho_e_wrt(i) .or. cons_vars_wrt) then - q_sf = q_cons_vf(i + intxb - 1)%sf(x_beg:x_end,y_beg:y_end,z_beg:z_end) + q_sf = q_cons_vf(i + intxb - 1)%sf(x_beg:x_end, y_beg:y_end, z_beg:z_end) write (varname, '(A,I0)') 'alpha_rho_e', i call s_write_variable_to_formatted_database_file(varname, t_step) @@ -338,7 +432,9 @@ contains end do end if + !Adding Energy cascade FFT if (fft_wrt) then + do l = 0, p do k = 0, n do j = 0, m @@ -354,8 +450,7 @@ contains do l = 0, p do k = 0, n do j = 0, m - data_cmplx(j + 1, k + 1, l + 1) = cmplx(q_cons_vf(mom_idx%beg + 1)%sf(j, k, l)/q_cons_vf(1)%sf(j, k, l), & - & 0._wp) + data_cmplx(j + 1, k + 1, l + 1) = cmplx(q_cons_vf(mom_idx%beg + 1)%sf(j, k, l)/q_cons_vf(1)%sf(j, k, l), 0._wp) end do end do end do @@ -367,8 +462,7 @@ contains do l = 0, p do k = 0, n do j = 0, m - data_cmplx(j + 1, k + 1, l + 1) = cmplx(q_cons_vf(mom_idx%beg + 2)%sf(j, k, l)/q_cons_vf(1)%sf(j, k, l), & - & 0._wp) + data_cmplx(j + 1, k + 1, l + 1) = cmplx(q_cons_vf(mom_idx%beg + 2)%sf(j, k, l)/q_cons_vf(1)%sf(j, k, l), 0._wp) end do end do end do @@ -384,6 +478,7 @@ contains do l = 1, Nz do k = 1, Nyloc2 do j = 1, Nxloc + j_glb = j + cart3d_coords(2)*Nxloc k_glb = k + cart3d_coords(3)*Nyloc2 l_glb = l @@ -409,6 +504,7 @@ contains kf = nint(sqrt(kx**2._wp + ky**2._wp + kz**2._wp)) + 1 En(kf) = En(kf) + En_real(j, k, l) + end do end do end do @@ -441,11 +537,13 @@ contains end if end if end do + end if + ! Adding the magnetic field to the formatted database file if (mhd .and. prim_vars_wrt) then do i = B_idx%beg, B_idx%end - q_sf(:,:,:) = q_prim_vf(i)%sf(x_beg:x_end,y_beg:y_end,z_beg:z_end) + q_sf(:, :, :) = q_prim_vf(i)%sf(x_beg:x_end, y_beg:y_end, z_beg:z_end) ! 1D: output By, Bz if (n == 0) then @@ -458,7 +556,7 @@ contains else if (i == B_idx%beg) then write (varname, '(A)') 'Bx' - else if (i == B_idx%beg + 1) then + elseif (i == B_idx%beg + 1) then write (varname, '(A)') 'By' else write (varname, '(A)') 'Bz' @@ -470,10 +568,11 @@ contains end do end if + ! Adding the elastic shear stresses to the formatted database file if (elasticity) then do i = 1, stress_idx%end - stress_idx%beg + 1 if (prim_vars_wrt) then - q_sf(:,:,:) = q_prim_vf(i - 1 + stress_idx%beg)%sf(x_beg:x_end,y_beg:y_end,z_beg:z_end) + q_sf(:, :, :) = q_prim_vf(i - 1 + stress_idx%beg)%sf(x_beg:x_end, y_beg:y_end, z_beg:z_end) write (varname, '(A,I0)') 'tau', i call s_write_variable_to_formatted_database_file(varname, t_step) end if @@ -484,7 +583,7 @@ contains if (hyperelasticity) then do i = 1, xiend - xibeg + 1 if (prim_vars_wrt) then - q_sf(:,:,:) = q_prim_vf(i - 1 + xibeg)%sf(x_beg:x_end,y_beg:y_end,z_beg:z_end) + q_sf(:, :, :) = q_prim_vf(i - 1 + xibeg)%sf(x_beg:x_end, y_beg:y_end, z_beg:z_end) write (varname, '(A,I0)') 'xi', i call s_write_variable_to_formatted_database_file(varname, t_step) end if @@ -493,7 +592,7 @@ contains end if if (cont_damage) then - q_sf(:,:,:) = q_cons_vf(damage_idx)%sf(x_beg:x_end,y_beg:y_end,z_beg:z_end) + q_sf(:, :, :) = q_cons_vf(damage_idx)%sf(x_beg:x_end, y_beg:y_end, z_beg:z_end) write (varname, '(A)') 'damage_state' call s_write_variable_to_formatted_database_file(varname, t_step) @@ -501,33 +600,42 @@ contains end if if (hyper_cleaning) then - q_sf = q_cons_vf(psi_idx)%sf(x_beg:x_end,y_beg:y_end,z_beg:z_end) + q_sf = q_cons_vf(psi_idx)%sf(x_beg:x_end, y_beg:y_end, z_beg:z_end) write (varname, '(A)') 'psi' call s_write_variable_to_formatted_database_file(varname, t_step) varname(:) = ' ' end if + ! Adding the pressure to the formatted database file if (pres_wrt .or. prim_vars_wrt) then - q_sf(:,:,:) = q_prim_vf(E_idx)%sf(x_beg:x_end,y_beg:y_end,z_beg:z_end) + q_sf(:, :, :) = q_prim_vf(E_idx)%sf(x_beg:x_end, y_beg:y_end, z_beg:z_end) write (varname, '(A)') 'pres' call s_write_variable_to_formatted_database_file(varname, t_step) varname(:) = ' ' + end if - if (((model_eqns == 2) .and. (bubbles_euler .neqv. .true.)) .or. (model_eqns == 3)) then + ! Adding the volume fraction(s) to the formatted database file + if (((model_eqns == 2) .and. (bubbles_euler .neqv. .true.)) & + .or. (model_eqns == 3) & + ) then + do i = 1, num_fluids - 1 if (alpha_wrt(i) .or. (cons_vars_wrt .or. prim_vars_wrt)) then - q_sf(:,:,:) = q_cons_vf(i + E_idx)%sf(x_beg:x_end,y_beg:y_end,z_beg:z_end) + q_sf(:, :, :) = q_cons_vf(i + E_idx)%sf(x_beg:x_end, y_beg:y_end, z_beg:z_end) write (varname, '(A,I0)') 'alpha', i call s_write_variable_to_formatted_database_file(varname, t_step) varname(:) = ' ' + end if end do - if (alpha_wrt(num_fluids) .or. (cons_vars_wrt .or. prim_vars_wrt)) then + if (alpha_wrt(num_fluids) & + .or. & + (cons_vars_wrt .or. prim_vars_wrt)) then if (igr) then do k = z_beg, z_end do j = y_beg, y_end @@ -540,49 +648,66 @@ contains end do end do else - q_sf(:,:,:) = q_cons_vf(adv_idx%end)%sf(x_beg:x_end,y_beg:y_end,z_beg:z_end) + q_sf(:, :, :) = q_cons_vf(adv_idx%end)%sf(x_beg:x_end, y_beg:y_end, z_beg:z_end) end if write (varname, '(A,I0)') 'alpha', num_fluids call s_write_variable_to_formatted_database_file(varname, t_step) varname(:) = ' ' + end if + end if - if (gamma_wrt .or. (model_eqns == 1 .and. (cons_vars_wrt .or. prim_vars_wrt))) then - q_sf(:,:,:) = gamma_sf(x_beg:x_end,y_beg:y_end,z_beg:z_end) + ! Adding specific heat ratio function to formatted database file + if (gamma_wrt & + .or. & + (model_eqns == 1 .and. (cons_vars_wrt .or. prim_vars_wrt))) then + q_sf(:, :, :) = gamma_sf(x_beg:x_end, y_beg:y_end, z_beg:z_end) write (varname, '(A)') 'gamma' call s_write_variable_to_formatted_database_file(varname, t_step) varname(:) = ' ' + end if + ! Adding the specific heat ratio to the formatted database file if (heat_ratio_wrt) then + call s_derive_specific_heat_ratio(q_sf) write (varname, '(A)') 'heat_ratio' call s_write_variable_to_formatted_database_file(varname, t_step) varname(:) = ' ' + end if - if (pi_inf_wrt .or. (model_eqns == 1 .and. (cons_vars_wrt .or. prim_vars_wrt))) then - q_sf(:,:,:) = pi_inf_sf(x_beg:x_end,y_beg:y_end,z_beg:z_end) + ! Adding liquid stiffness function to formatted database file + if (pi_inf_wrt & + .or. & + (model_eqns == 1 .and. (cons_vars_wrt .or. prim_vars_wrt))) then + q_sf(:, :, :) = pi_inf_sf(x_beg:x_end, y_beg:y_end, z_beg:z_end) write (varname, '(A)') 'pi_inf' call s_write_variable_to_formatted_database_file(varname, t_step) varname(:) = ' ' + end if + ! Adding the liquid stiffness to the formatted database file if (pres_inf_wrt) then + call s_derive_liquid_stiffness(q_sf) write (varname, '(A)') 'pres_inf' call s_write_variable_to_formatted_database_file(varname, t_step) varname(:) = ' ' + end if + ! Adding the sound speed to the formatted database file if (c_wrt) then do k = -offset_z%beg, p + offset_z%end do j = -offset_y%beg, n + offset_y%end @@ -593,10 +718,12 @@ contains pres = q_prim_vf(E_idx)%sf(i, j, k) - H = ((gamma_sf(i, j, k) + 1._wp)*pres + pi_inf_sf(i, j, k) + qv_sf(i, j, k))/rho_sf(i, j, k) + H = ((gamma_sf(i, j, k) + 1._wp)*pres + & + pi_inf_sf(i, j, k) + qv_sf(i, j, k))/rho_sf(i, j, k) - call s_compute_speed_of_sound(pres, rho_sf(i, j, k), gamma_sf(i, j, k), pi_inf_sf(i, j, k), H, adv, & - & 0._wp, 0._wp, c, qv_sf(i, j, k)) + call s_compute_speed_of_sound(pres, rho_sf(i, j, k), & + gamma_sf(i, j, k), pi_inf_sf(i, j, k), & + H, adv, 0._wp, 0._wp, c, qv_sf(i, j, k)) q_sf(i, j, k) = c end do @@ -607,10 +734,13 @@ contains call s_write_variable_to_formatted_database_file(varname, t_step) varname(:) = ' ' + end if + ! Adding the vorticity to the formatted database file do i = 1, 3 if (omega_wrt(i)) then + call s_derive_vorticity_component(i, q_prim_vf, q_sf) write (varname, '(A,I0)') 'omega', i @@ -621,12 +751,12 @@ contains end do if (ib) then - q_sf(:,:,:) = real(ib_markers%sf(-offset_x%beg:m + offset_x%end,-offset_y%beg:n + offset_y%end, & - & -offset_z%beg:p + offset_z%end)) + q_sf(:, :, :) = real(ib_markers%sf(-offset_x%beg:m + offset_x%end, -offset_y%beg:n + offset_y%end, -offset_z%beg:p + offset_z%end)) varname = 'ib_markers' call s_write_variable_to_formatted_database_file(varname, t_step) end if + ! Adding Q_M to the formatted database file if (p > 0 .and. qm_wrt) then call s_derive_qm(q_prim_vf, q_sf) @@ -636,9 +766,13 @@ contains varname(:) = ' ' end if + ! Adding Liutex magnitude to the formatted database file if (liutex_wrt) then + + ! Compute Liutex vector and its magnitude call s_derive_liutex(q_prim_vf, liutex_mag, liutex_axis) + ! Liutex magnitude q_sf = liutex_mag write (varname, '(A)') 'liutex_mag' @@ -646,69 +780,78 @@ contains varname(:) = ' ' + ! Liutex axis do i = 1, 3 - q_sf = liutex_axis(:,:,:,i) + q_sf = liutex_axis(:, :, :, i) write (varname, '(A,I0)') 'liutex_axis', i call s_write_variable_to_formatted_database_file(varname, t_step) varname(:) = ' ' end do + end if + ! Adding numerical Schlieren function to formatted database file if (schlieren_wrt) then + call s_derive_numerical_schlieren_function(q_cons_vf, q_sf) write (varname, '(A)') 'schlieren' call s_write_variable_to_formatted_database_file(varname, t_step) varname(:) = ' ' + end if + ! Adding the color function to formatted database file if (cf_wrt) then - q_sf(:,:,:) = q_cons_vf(c_idx)%sf(x_beg:x_end,y_beg:y_end,z_beg:z_end) + q_sf(:, :, :) = q_cons_vf(c_idx)%sf(x_beg:x_end, y_beg:y_end, z_beg:z_end) write (varname, '(A,I0)') 'color_function' call s_write_variable_to_formatted_database_file(varname, t_step) varname(:) = ' ' + end if + ! Adding the volume fraction(s) to the formatted database file if (bubbles_euler) then do i = adv_idx%beg, adv_idx%end - q_sf(:,:,:) = q_cons_vf(i)%sf(x_beg:x_end,y_beg:y_end,z_beg:z_end) + q_sf(:, :, :) = q_cons_vf(i)%sf(x_beg:x_end, y_beg:y_end, z_beg:z_end) write (varname, '(A,I0)') 'alpha', i - E_idx call s_write_variable_to_formatted_database_file(varname, t_step) varname(:) = ' ' end do end if + ! Adding the bubble variables to the formatted database file if (bubbles_euler) then - ! nR + !nR do i = 1, nb - q_sf(:,:,:) = q_cons_vf(bub_idx%rs(i))%sf(x_beg:x_end,y_beg:y_end,z_beg:z_end) + q_sf(:, :, :) = q_cons_vf(bub_idx%rs(i))%sf(x_beg:x_end, y_beg:y_end, z_beg:z_end) write (varname, '(A,I3.3)') 'nR', i call s_write_variable_to_formatted_database_file(varname, t_step) varname(:) = ' ' end do - ! nRdot + !nRdot do i = 1, nb - q_sf(:,:,:) = q_cons_vf(bub_idx%vs(i))%sf(x_beg:x_end,y_beg:y_end,z_beg:z_end) + q_sf(:, :, :) = q_cons_vf(bub_idx%vs(i))%sf(x_beg:x_end, y_beg:y_end, z_beg:z_end) write (varname, '(A,I3.3)') 'nV', i call s_write_variable_to_formatted_database_file(varname, t_step) varname(:) = ' ' end do if ((polytropic .neqv. .true.) .and. (.not. qbmm)) then - ! nP + !nP do i = 1, nb - q_sf(:,:,:) = q_cons_vf(bub_idx%ps(i))%sf(x_beg:x_end,y_beg:y_end,z_beg:z_end) + q_sf(:, :, :) = q_cons_vf(bub_idx%ps(i))%sf(x_beg:x_end, y_beg:y_end, z_beg:z_end) write (varname, '(A,I3.3)') 'nP', i call s_write_variable_to_formatted_database_file(varname, t_step) varname(:) = ' ' end do - ! nM + !nM do i = 1, nb - q_sf(:,:,:) = q_cons_vf(bub_idx%ms(i))%sf(x_beg:x_end,y_beg:y_end,z_beg:z_end) + q_sf(:, :, :) = q_cons_vf(bub_idx%ms(i))%sf(x_beg:x_end, y_beg:y_end, z_beg:z_end) write (varname, '(A,I3.3)') 'nM', i call s_write_variable_to_formatted_database_file(varname, t_step) varname(:) = ' ' @@ -717,23 +860,26 @@ contains ! number density if (adv_n) then - q_sf(:,:,:) = q_cons_vf(n_idx)%sf(x_beg:x_end,y_beg:y_end,z_beg:z_end) + q_sf(:, :, :) = q_cons_vf(n_idx)%sf(x_beg:x_end, y_beg:y_end, z_beg:z_end) write (varname, '(A)') 'n' call s_write_variable_to_formatted_database_file(varname, t_step) varname(:) = ' ' end if end if + ! Adding the lagrangian subgrid variables to the formatted database file if (bubbles_lagrange) then - ! Void fraction field - q_sf(:,:,:) = 1._wp - q_cons_vf(beta_idx)%sf(-offset_x%beg:m + offset_x%end,-offset_y%beg:n + offset_y%end, & - & -offset_z%beg:p + offset_z%end) + !! Void fraction field + q_sf(:, :, :) = 1._wp - q_cons_vf(beta_idx)%sf( & + -offset_x%beg:m + offset_x%end, & + -offset_y%beg:n + offset_y%end, & + -offset_z%beg:p + offset_z%end) write (varname, '(A)') 'voidFraction' call s_write_variable_to_formatted_database_file(varname, t_step) varname(:) = ' ' - if (lag_txt_wrt) call s_write_lag_bubbles_results_to_text(t_step) ! text output - if (lag_db_wrt) call s_write_lag_bubbles_to_formatted_database_file(t_step) ! silo file output + if (lag_txt_wrt) call s_write_lag_bubbles_results_to_text(t_step) ! text output + if (lag_db_wrt) call s_write_lag_bubbles_to_formatted_database_file(t_step) ! silo file output end if if (sim_data .and. proc_rank == 0) then @@ -741,18 +887,19 @@ contains call s_close_energy_data_file() end if + ! Closing the formatted database file call s_close_formatted_database_file() end subroutine s_save_data - !> Transpose 3-D complex data from x-pencil to y-pencil layout via MPI_Alltoall. + !> @brief Transpose 3-D complex data from x-pencil to y-pencil layout via MPI_Alltoall. subroutine s_mpi_transpose_x2y - complex(c_double_complex), allocatable :: sendbuf(:), recvbuf(:) - integer :: dest_rank, src_rank - integer :: i, j, k, l + integer :: dest_rank, src_rank + integer :: i, j, k, l #ifdef MFC_MPI + allocate (sendbuf(Nx*Nyloc*Nzloc)) allocate (recvbuf(Nx*Nyloc*Nzloc)) @@ -760,22 +907,20 @@ contains do l = 1, Nzloc do k = 1, Nyloc do j = 1, Nxloc - sendbuf(j + (k - 1)*Nxloc + (l - 1)*Nxloc*Nyloc + dest_rank*Nxloc*Nyloc*Nzloc) = data_cmplx(j & - & + dest_rank*Nxloc, k, l) + sendbuf(j + (k - 1)*Nxloc + (l - 1)*Nxloc*Nyloc + dest_rank*Nxloc*Nyloc*Nzloc) = data_cmplx(j + dest_rank*Nxloc, k, l) end do end do end do end do - call MPI_Alltoall(sendbuf, Nxloc*Nyloc*Nzloc, MPI_C_DOUBLE_COMPLEX, recvbuf, Nxloc*Nyloc*Nzloc, MPI_C_DOUBLE_COMPLEX, & - & MPI_COMM_CART12, ierr) + call MPI_Alltoall(sendbuf, Nxloc*Nyloc*Nzloc, MPI_C_DOUBLE_COMPLEX, & + recvbuf, Nxloc*Nyloc*Nzloc, MPI_C_DOUBLE_COMPLEX, MPI_COMM_CART12, ierr) do src_rank = 0, num_procs_y - 1 do l = 1, Nzloc do k = 1, Nyloc do j = 1, Nxloc - data_cmplx_y(j, k + src_rank*Nyloc, & - & l) = recvbuf(j + (k - 1)*Nxloc + (l - 1)*Nxloc*Nyloc + src_rank*Nxloc*Nyloc*Nzloc) + data_cmplx_y(j, k + src_rank*Nyloc, l) = recvbuf(j + (k - 1)*Nxloc + (l - 1)*Nxloc*Nyloc + src_rank*Nxloc*Nyloc*Nzloc) end do end do end do @@ -783,18 +928,19 @@ contains deallocate (sendbuf) deallocate (recvbuf) + #endif end subroutine s_mpi_transpose_x2y - !> Transpose 3-D complex data from y-pencil to z-pencil layout via MPI_Alltoall. + !> @brief Transpose 3-D complex data from y-pencil to z-pencil layout via MPI_Alltoall. subroutine s_mpi_transpose_y2z - complex(c_double_complex), allocatable :: sendbuf(:), recvbuf(:) - integer :: dest_rank, src_rank - integer :: j, k, l + integer :: dest_rank, src_rank + integer :: j, k, l #ifdef MFC_MPI + allocate (sendbuf(Ny*Nxloc*Nzloc)) allocate (recvbuf(Ny*Nxloc*Nzloc)) @@ -802,23 +948,20 @@ contains do l = 1, Nzloc do j = 1, Nxloc do k = 1, Nyloc2 - sendbuf(k + (j - 1)*Nyloc2 + (l - 1)*(Nyloc2*Nxloc) + dest_rank*Nyloc2*Nxloc*Nzloc) = data_cmplx_y(j, & - & k + dest_rank*Nyloc2, l) + sendbuf(k + (j - 1)*Nyloc2 + (l - 1)*(Nyloc2*Nxloc) + dest_rank*Nyloc2*Nxloc*Nzloc) = data_cmplx_y(j, k + dest_rank*Nyloc2, l) end do end do end do end do - call MPI_Alltoall(sendbuf, Nyloc2*Nxloc*Nzloc, MPI_C_DOUBLE_COMPLEX, recvbuf, Nyloc2*Nxloc*Nzloc, MPI_C_DOUBLE_COMPLEX, & - & MPI_COMM_CART13, ierr) + call MPI_Alltoall(sendbuf, Nyloc2*Nxloc*Nzloc, MPI_C_DOUBLE_COMPLEX, & + recvbuf, Nyloc2*Nxloc*Nzloc, MPI_C_DOUBLE_COMPLEX, MPI_COMM_CART13, ierr) do src_rank = 0, num_procs_z - 1 do l = 1, Nzloc do j = 1, Nxloc do k = 1, Nyloc2 - data_cmplx_z(j, k, & - & l + src_rank*Nzloc) = recvbuf(k + (j - 1)*Nyloc2 + (l - 1)*(Nyloc2*Nxloc) & - & + src_rank*Nyloc2*Nxloc*Nzloc) + data_cmplx_z(j, k, l + src_rank*Nzloc) = recvbuf(k + (j - 1)*Nyloc2 + (l - 1)*(Nyloc2*Nxloc) + src_rank*Nyloc2*Nxloc*Nzloc) end do end do end do @@ -826,13 +969,15 @@ contains deallocate (sendbuf) deallocate (recvbuf) + #endif end subroutine s_mpi_transpose_y2z - !> Initialize all post-process sub-modules, set up I/O pointers, and prepare FFTW plans and MPI communicators. + !> @brief Initialize all post-process sub-modules, set up I/O pointers, and prepare FFTW plans and MPI communicators. impure subroutine s_initialize_modules - + ! Computation of parameters, allocation procedures, and/or any other tasks + ! needed to properly setup the modules integer :: size_n(1), inembed(1), onembed(1) call s_initialize_global_parameters_module() @@ -849,6 +994,7 @@ contains call s_initialize_derived_variables_module() call s_initialize_data_output_module() + ! Associate pointers for serial or parallel I/O if (parallel_io .neqv. .true.) then s_read_data_files => s_read_serial_data_files else @@ -857,6 +1003,7 @@ contains #ifdef MFC_MPI if (fft_wrt) then + num_procs_x = (m_glb + 1)/(m + 1) num_procs_y = (n_glb + 1)/(n + 1) num_procs_z = (p_glb + 1)/(p + 1) @@ -886,26 +1033,35 @@ contains inembed(1) = Nx onembed(1) = Nx - fwd_plan_x = fftw_plan_many_dft(1, size_n, Nyloc*Nzloc, data_in, inembed, 1, Nx, data_out, onembed, 1, Nx, & - & FFTW_FORWARD, FFTW_MEASURE) + fwd_plan_x = fftw_plan_many_dft(1, size_n, Nyloc*Nzloc, & + data_in, inembed, 1, Nx, & + data_out, onembed, 1, Nx, & + FFTW_FORWARD, FFTW_MEASURE) size_n(1) = Ny inembed(1) = Ny onembed(1) = Ny - fwd_plan_y = fftw_plan_many_dft(1, size_n, Nxloc*Nzloc, data_out, inembed, 1, Ny, data_in, onembed, 1, Ny, & - & FFTW_FORWARD, FFTW_MEASURE) + fwd_plan_y = fftw_plan_many_dft(1, size_n, Nxloc*Nzloc, & + data_out, inembed, 1, Ny, & + data_in, onembed, 1, Ny, & + FFTW_FORWARD, FFTW_MEASURE) size_n(1) = Nz inembed(1) = Nz onembed(1) = Nz - fwd_plan_z = fftw_plan_many_dft(1, size_n, Nxloc*Nyloc2, data_in, inembed, 1, Nz, data_out, onembed, 1, Nz, & - & FFTW_FORWARD, FFTW_MEASURE) + fwd_plan_z = fftw_plan_many_dft(1, size_n, Nxloc*Nyloc2, & + data_in, inembed, 1, Nz, & + data_out, onembed, 1, Nz, & + FFTW_FORWARD, FFTW_MEASURE) - call MPI_CART_CREATE(MPI_COMM_WORLD, 3, (/num_procs_x, num_procs_y, num_procs_z/), (/.true., .true., .true./), & - & .false., MPI_COMM_CART, ierr) - call MPI_CART_COORDS(MPI_COMM_CART, proc_rank, 3, cart3d_coords, ierr) + call MPI_CART_CREATE(MPI_COMM_WORLD, 3, (/num_procs_x, & + num_procs_y, num_procs_z/), & + (/.true., .true., .true./), & + .false., MPI_COMM_CART, ierr) + call MPI_CART_COORDS(MPI_COMM_CART, proc_rank, 3, & + cart3d_coords, ierr) call MPI_Cart_SUB(MPI_COMM_CART, (/.true., .true., .false./), MPI_COMM_CART12, ierr) call MPI_COMM_RANK(MPI_COMM_CART12, proc_rank12, ierr) @@ -914,17 +1070,18 @@ contains call MPI_Cart_SUB(MPI_COMM_CART, (/.true., .false., .true./), MPI_COMM_CART13, ierr) call MPI_COMM_RANK(MPI_COMM_CART13, proc_rank13, ierr) call MPI_CART_COORDS(MPI_COMM_CART13, proc_rank13, 2, cart2d13_coords, ierr) + end if #endif - end subroutine s_initialize_modules - !> Perform a distributed forward 3-D FFT using pencil decomposition with FFTW and MPI transposes. + !> @brief Perform a distributed forward 3-D FFT using pencil decomposition with FFTW and MPI transposes. subroutine s_mpi_FFT_fwd integer :: j, k, l #ifdef MFC_MPI + do l = 1, Nzloc do k = 1, Nyloc do j = 1, Nx @@ -982,17 +1139,23 @@ contains end do end do end do + #endif end subroutine s_mpi_FFT_fwd - !> Set up the MPI environment, read and broadcast user inputs, and decompose the computational domain. + !> @brief Set up the MPI environment, read and broadcast user inputs, and decompose the computational domain. impure subroutine s_initialize_mpi_domain num_dims = 1 + min(1, n) + min(1, p) + ! Initialization of the MPI environment call s_mpi_initialize() + ! Processor with rank 0 assigns default user input values prior to reading + ! those in from the input file. Next, the user inputs are read in and their + ! consistency is checked. The detection of any inconsistencies automatically + ! leads to the termination of the post-process. if (proc_rank == 0) then call s_assign_default_values_to_user_inputs() call s_read_input_file() @@ -1001,6 +1164,9 @@ contains print '(" Post-processing a ", I0, "x", I0, "x", I0, " case on ", I0, " rank(s)")', m, n, p, num_procs end if + ! Broadcasting the user inputs to all of the processors and performing the + ! parallel computational domain decomposition. Neither procedure has to be + ! carried out if the post-process is in fact not truly executed in parallel. call s_mpi_bcast_user_inputs() call s_initialize_parallel_io() call s_mpi_decompose_computational_domain() @@ -1008,11 +1174,16 @@ contains end subroutine s_initialize_mpi_domain - !> Destroy FFTW plans, free MPI communicators, and finalize all post-process sub-modules. + !> @brief Destroy FFTW plans, free MPI communicators, and finalize all post-process sub-modules. impure subroutine s_finalize_modules - + ! Disassociate pointers for serial and parallel I/O s_read_data_files => null() +! if (sim_data .and. proc_rank == 0) then +! call s_close_intf_data_file() +! call s_close_energy_data_file() +! end if + if (fft_wrt) then if (c_associated(fwd_plan_x)) call fftw_destroy_plan(fwd_plan_x) if (c_associated(fwd_plan_y)) call fftw_destroy_plan(fwd_plan_y) @@ -1035,6 +1206,7 @@ contains end if #endif + ! Deallocation procedures for the modules call s_finalize_data_output_module() call s_finalize_derived_variables_module() call s_finalize_data_input_module() @@ -1045,8 +1217,8 @@ contains end if call s_finalize_global_parameters_module() + ! Finalizing the MPI environment call s_mpi_finalize() - end subroutine s_finalize_modules end module m_start_up diff --git a/src/post_process/p_main.fpp b/src/post_process/p_main.fpp index 32d8dc2c7e..c325b649da 100644 --- a/src/post_process/p_main.fpp +++ b/src/post_process/p_main.fpp @@ -2,21 +2,31 @@ !! @file !! @brief Contains program p_main -!> Post-process raw simulation data into formatted database files (Silo-HDF5 or Binary) +!> @brief The post-process restructures raw unformatted data, outputted by +!! the simulation, into a formatted database, Silo-HDF5 or Binary, +!! chosen by the user. The user may also specify which variables to +!! include in the database. The choices range from any one of the +!! primitive and conservative variables, as well as quantities that +!! can be derived from those such as the unadvected volume fraction, +!! specific heat ratio, liquid stiffness, speed of sound, vorticity +!! and the numerical Schlieren function. program p_main - use m_global_parameters + use m_global_parameters !< Global parameters for the code use m_start_up implicit none - integer :: t_step !< Iterator for the main time-stepping loop - !> Generic storage for the name(s) of the flow variable(s) that will be added to the formatted database file(s) - character(LEN=name_len) :: varname - real(wp) :: pres - real(wp) :: c - real(wp) :: H - real(wp) :: start, finish + integer :: t_step !< Iterator for the main time-stepping loop + + character(LEN=name_len) :: varname !< + !! Generic storage for the name(s) of the flow variable(s) that will be added + !! to the formatted database file(s) + + real(wp) :: pres + real(wp) :: c + real(wp) :: H + real(wp) :: start, finish call s_initialize_mpi_domain() @@ -32,9 +42,12 @@ program p_main ! Time-Marching Loop do - ! If all time-steps are not ready to be post-processed and one rank is faster than another, the slower rank processing the - ! last available step might be killed when the faster rank attempts to process the first missing step, before the slower - ! rank finishes writing the last available step. To avoid this, we force synchronization here. + + ! If all time-steps are not ready to be post-processed and one rank is + ! faster than another, the slower rank processing the last available + ! step might be killed when the faster rank attempts to process the + ! first missing step, before the slower rank finishes writing the last + ! available step. To avoid this, we force synchronization here. call s_mpi_barrier() call cpu_time(start) @@ -58,10 +71,14 @@ program p_main exit end if else - ! Adjust time-step iterator to reach final step if needed, else exit + ! Modifies the time-step iterator so that it may reach the final time- + ! step to be post-processed, in the case that this one is not originally + ! attainable through constant incrementation from the first time-step. + ! This modification is performed upon reaching the final time-step. In + ! case that it is not needed, the post-processor is done and may exit. if ((t_step_stop - t_step) < t_step_save .and. t_step_stop /= t_step) then t_step = t_step_stop - t_step_save - else if (t_step == t_step_stop) then + elseif (t_step == t_step_stop) then exit end if end if @@ -72,6 +89,7 @@ program p_main ! Incrementing time-step iterator to next time-step to be post-processed t_step = t_step + t_step_save end if + end do ! END: Time-Marching Loop @@ -82,4 +100,5 @@ program p_main close (11) call s_finalize_modules() + end program p_main diff --git a/src/pre_process/m_assign_variables.fpp b/src/pre_process/m_assign_variables.fpp index e171097d4b..bfb6f9d159 100644 --- a/src/pre_process/m_assign_variables.fpp +++ b/src/pre_process/m_assign_variables.fpp @@ -8,10 +8,14 @@ !> @brief Assigns initial primitive variables to computational cells based on patch geometry module m_assign_variables - use m_derived_types - use m_global_parameters - use m_variables_conversion - use m_helper_basic + use m_derived_types ! Definitions of the derived types + + use m_global_parameters ! Global parameters for the code + + use m_variables_conversion ! Subroutines to change the state variables from + + use m_helper_basic !< Functions to compare floating point numbers + use m_thermochem, only: num_species, gas_constant, get_mixture_molecular_weight implicit none @@ -20,127 +24,193 @@ module m_assign_variables type(scalar_field) :: alf_sum - !> Pointer to mixture or species patch assignment routine - procedure(s_assign_patch_xxxxx_primitive_variables), pointer :: s_assign_patch_primitive_variables => null() - !> Abstract interface to the two subroutines that assign the patch primitive variables, either mixture or species, depending on - !! the subroutine, to a particular cell in the computational domain + procedure(s_assign_patch_xxxxx_primitive_variables), & + pointer :: s_assign_patch_primitive_variables => null() !< + !! Depending on the multicomponent flow model, this variable is a pointer to + !! either the subroutine s_assign_patch_mixture_primitive_variables, or the + !! subroutine s_assign_patch_species_primitive_variables + + !> Abstract interface to the two subroutines that assign the patch primitive + !! variables, either mixture or species, depending on the subroutine, to a + !! particular cell in the computational domain abstract interface - !> Skeleton of s_assign_patch_mixture_primitive_variables and s_assign_patch_species_primitive_variables - subroutine s_assign_patch_xxxxx_primitive_variables(patch_id, j, k, l, eta, q_prim_vf, patch_id_fp) + !> Skeleton of s_assign_patch_mixture_primitive_variables + !! and s_assign_patch_species_primitive_variables + !! @param patch_id is the patch identifier + !! @param j (x) cell index in which the mixture or species primitive variables from the indicated patch are assigned + !! @param k (y,th) cell index in which the mixture or species primitive variables from the indicated patch are assigned + !! @param l (z) cell index in which the mixture or species primitive variables from the indicated patch are assigned + !! @param eta pseudo volume fraction + !! @param q_prim_vf Primitive variables + !! @param patch_id_fp Array to track patch ids + subroutine s_assign_patch_xxxxx_primitive_variables(patch_id, j, k, l, & + eta, q_prim_vf, patch_id_fp) import :: scalar_field, sys_size, n, m, p, wp - integer, intent(in) :: patch_id - integer, intent(in) :: j, k, l - real(wp), intent(in) :: eta + integer, intent(in) :: patch_id + integer, intent(in) :: j, k, l + real(wp), intent(in) :: eta type(scalar_field), dimension(1:sys_size), intent(inout) :: q_prim_vf - #ifdef MFC_MIXED_PRECISION - integer(kind=1), dimension(0:m,0:n,0:p), intent(inout) :: patch_id_fp + integer(kind=1), dimension(0:m, 0:n, 0:p), intent(inout) :: patch_id_fp #else - integer, dimension(0:m,0:n,0:p), intent(inout) :: patch_id_fp + integer, dimension(0:m, 0:n, 0:p), intent(inout) :: patch_id_fp #endif end subroutine s_assign_patch_xxxxx_primitive_variables + end interface - private - public :: s_initialize_assign_variables_module, s_assign_patch_primitive_variables, & - & s_assign_patch_mixture_primitive_variables, s_assign_patch_species_primitive_variables, s_finalize_assign_variables_module + private; + public :: s_initialize_assign_variables_module, & + s_assign_patch_primitive_variables, & + s_assign_patch_mixture_primitive_variables, & + s_assign_patch_species_primitive_variables, & + s_finalize_assign_variables_module contains - !> Allocate volume fraction sum and set the patch primitive variable assignment procedure pointer. + !> @brief Allocates volume fraction sum and sets the patch primitive variable assignment procedure pointer. impure subroutine s_initialize_assign_variables_module if (.not. igr) then - allocate (alf_sum%sf(0:m,0:n,0:p)) + allocate (alf_sum%sf(0:m, 0:n, 0:p)) end if - ! Select procedure pointer based on multicomponent flow model + ! Depending on multicomponent flow model, the appropriate procedure + ! for assignment of the patch mixture or species primitive variables + ! to a cell in the domain is targeted by the procedure pointer - if (model_eqns == 1) then ! Gamma/pi_inf model - s_assign_patch_primitive_variables => s_assign_patch_mixture_primitive_variables - else ! Volume fraction model - s_assign_patch_primitive_variables => s_assign_patch_species_primitive_variables + if (model_eqns == 1) then ! Gamma/pi_inf model + s_assign_patch_primitive_variables => & + s_assign_patch_mixture_primitive_variables + else ! Volume fraction model + s_assign_patch_primitive_variables => & + s_assign_patch_species_primitive_variables end if end subroutine s_initialize_assign_variables_module - !> Assign the mixture primitive variables of the patch designated by the patch_id to the cell that is designated by the indexes - !! (j,k,l). In addition, the variable bookkeeping the patch identities in the entire domain is updated with the new assignment. - !! Note that if the smoothing of the patch's boundaries is employed, the ensuing primitive variables in the cell will be a type - !! of combination of the current patch's primitive variables with those of the smoothing patch. The specific details of the - !! combination may be found in Shyue's work (1998). - subroutine s_assign_patch_mixture_primitive_variables(patch_id, j, k, l, eta, q_prim_vf, patch_id_fp) - + !> This subroutine assigns the mixture primitive variables + !! of the patch designated by the patch_id, to the cell that + !! is designated by the indexes (j,k,l). In addition, the + !! variable bookkeeping the patch identities in the entire + !! domain is updated with the new assignment. Note that if + !! the smoothing of the patch's boundaries is employed, the + !! ensuing primitive variables in the cell will be a type of + !! combination of the current patch's primitive variables + !! with those of the smoothing patch. The specific details + !! of the combination may be found in Shyue's work (1998). + !! @param patch_id the patch identifier + !! @param j the x-dir node index + !! @param k the y-dir node index + !! @param l the z-dir node index + !! @param eta pseudo volume fraction + !! @param q_prim_vf Primitive variables + !! @param patch_id_fp Array to track patch ids + subroutine s_assign_patch_mixture_primitive_variables(patch_id, j, k, l, & + eta, q_prim_vf, patch_id_fp) $:GPU_ROUTINE(parallelism='[seq]') - integer, intent(in) :: patch_id - integer, intent(in) :: j, k, l - real(wp), intent(in) :: eta + integer, intent(in) :: patch_id + integer, intent(in) :: j, k, l + real(wp), intent(in) :: eta type(scalar_field), dimension(1:sys_size), intent(inout) :: q_prim_vf #ifdef MFC_MIXED_PRECISION - integer(kind=1), dimension(0:m,0:n,0:p), intent(inout) :: patch_id_fp + integer(kind=1), dimension(0:m, 0:n, 0:p), intent(inout) :: patch_id_fp #else - integer, dimension(0:m,0:n,0:p), intent(inout) :: patch_id_fp + integer, dimension(0:m, 0:n, 0:p), intent(inout) :: patch_id_fp #endif real(wp) :: Ys(1:num_species) - integer :: smooth_patch_id - integer :: i + integer :: smooth_patch_id + integer :: i !< generic loop operator + + ! Assigning the mixture primitive variables of a uniform state patch + + ! Transferring the identity of the smoothing patch smooth_patch_id = patch_icpp(patch_id)%smooth_patch_id - q_prim_vf(1)%sf(j, k, l) = eta*patch_icpp(patch_id)%rho + (1._wp - eta)*patch_icpp(smooth_patch_id)%rho + ! Density + q_prim_vf(1)%sf(j, k, l) = & + eta*patch_icpp(patch_id)%rho & + + (1._wp - eta)*patch_icpp(smooth_patch_id)%rho + ! Velocity do i = 1, E_idx - mom_idx%beg - q_prim_vf(i + 1)%sf(j, k, l) = 1._wp/q_prim_vf(1)%sf(j, k, & - & l)*(eta*patch_icpp(patch_id)%rho*patch_icpp(patch_id)%vel(i) + (1._wp - eta)*patch_icpp(smooth_patch_id) & - & %rho*patch_icpp(smooth_patch_id)%vel(i)) + q_prim_vf(i + 1)%sf(j, k, l) = & + 1._wp/q_prim_vf(1)%sf(j, k, l)* & + (eta*patch_icpp(patch_id)%rho & + *patch_icpp(patch_id)%vel(i) & + + (1._wp - eta)*patch_icpp(smooth_patch_id)%rho & + *patch_icpp(smooth_patch_id)%vel(i)) end do - q_prim_vf(gamma_idx)%sf(j, k, l) = eta*patch_icpp(patch_id)%gamma + (1._wp - eta)*patch_icpp(smooth_patch_id)%gamma - - q_prim_vf(E_idx)%sf(j, k, l) = 1._wp/q_prim_vf(gamma_idx)%sf(j, k, & - & l)*(eta*patch_icpp(patch_id)%gamma*patch_icpp(patch_id)%pres + (1._wp - eta)*patch_icpp(smooth_patch_id) & - & %gamma*patch_icpp(smooth_patch_id)%pres) - - q_prim_vf(pi_inf_idx)%sf(j, k, l) = eta*patch_icpp(patch_id)%pi_inf + (1._wp - eta)*patch_icpp(smooth_patch_id)%pi_inf - + ! Specific heat ratio function + q_prim_vf(gamma_idx)%sf(j, k, l) = & + eta*patch_icpp(patch_id)%gamma & + + (1._wp - eta)*patch_icpp(smooth_patch_id)%gamma + + ! Pressure + q_prim_vf(E_idx)%sf(j, k, l) = & + 1._wp/q_prim_vf(gamma_idx)%sf(j, k, l)* & + (eta*patch_icpp(patch_id)%gamma & + *patch_icpp(patch_id)%pres & + + (1._wp - eta)*patch_icpp(smooth_patch_id)%gamma & + *patch_icpp(smooth_patch_id)%pres) + + ! Liquid stiffness function + q_prim_vf(pi_inf_idx)%sf(j, k, l) = & + eta*patch_icpp(patch_id)%pi_inf & + + (1._wp - eta)*patch_icpp(smooth_patch_id)%pi_inf + + ! Species Concentrations if (chemistry) then block real(wp) :: sum, term + ! Accumulating the species concentrations sum = 0._wp do i = 1, num_species - term = eta*patch_icpp(patch_id)%Y(i) + (1._wp - eta)*patch_icpp(smooth_patch_id)%Y(i) + term = & + eta*patch_icpp(patch_id)%Y(i) & + + (1._wp - eta)*patch_icpp(smooth_patch_id)%Y(i) q_prim_vf(chemxb + i - 1)%sf(j, k, l) = term sum = sum + term end do sum = max(sum, verysmall) + ! Normalizing the species concentrations do i = 1, num_species - q_prim_vf(chemxb + i - 1)%sf(j, k, l) = q_prim_vf(chemxb + i - 1)%sf(j, k, l)/sum + q_prim_vf(chemxb + i - 1)%sf(j, k, l) = & + q_prim_vf(chemxb + i - 1)%sf(j, k, l)/sum Ys(i) = q_prim_vf(chemxb + i - 1)%sf(j, k, l) end do end block end if + ! Updating the patch identities bookkeeping variable if (1._wp - eta < 1.e-16_wp) patch_id_fp(j, k, l) = patch_id end subroutine s_assign_patch_mixture_primitive_variables - !> Apply a stable pressure perturbation following Ando's method for bubble-laden flows. + !> @brief Applies a stable pressure perturbation following Ando's method for bubble-laden flows. + !! @param j the x-dir node index + !! @param k the y-dir node index + !! @param l the z-dir node index + !! @param q_prim_vf Primitive variables subroutine s_perturb_primitive(j, k, l, q_prim_vf) - integer, intent(in) :: j, k, l + integer, intent(in) :: j, k, l type(scalar_field), dimension(1:sys_size), intent(inout) :: q_prim_vf - integer :: i - real(wp) :: pres_mag, loc, n_tait, B_tait, p0 - real(wp) :: R3bar, n0, ratio, nH, vfH, velH, rhoH, deno + + integer :: i + real(wp) :: pres_mag, loc, n_tait, B_tait, p0 + real(wp) :: R3bar, n0, ratio, nH, vfH, velH, rhoH, deno p0 = 101325._wp pres_mag = 1.e-1_wp @@ -154,8 +224,7 @@ contains if (qbmm) then do i = 1, nb - q_prim_vf(bubxb + 1 + (i - 1)*nmom)%sf(j, k, l) = q_prim_vf(bubxb + 1 + (i - 1)*nmom)%sf(j, k, & - & l)*((p0 - bub_pp%pv)/(q_prim_vf(E_idx)%sf(j, k, l)*p0 - bub_pp%pv))**(1._wp/3._wp) + q_prim_vf(bubxb + 1 + (i - 1)*nmom)%sf(j, k, l) = q_prim_vf(bubxb + 1 + (i - 1)*nmom)%sf(j, k, l)*((p0 - bub_pp%pv)/(q_prim_vf(E_idx)%sf(j, k, l)*p0 - bub_pp%pv))**(1._wp/3._wp) end do end if @@ -204,112 +273,152 @@ contains end subroutine s_perturb_primitive - !> Assign the species primitive variables, following s_assign_patch_species_primitive_variables with adaptation for - !! ensemble-averaged bubble modeling - impure subroutine s_assign_patch_species_primitive_variables(patch_id, j, k, l, eta, q_prim_vf, patch_id_fp) - + !> This subroutine assigns the species primitive variables. This follows + !! s_assign_patch_species_primitive_variables with adaptation for + !! ensemble-averaged bubble modeling + !! @param patch_id the patch identifier + !! @param j the x-dir node index + !! @param k the y-dir node index + !! @param l the z-dir node index + !! @param eta pseudo volume fraction + !! @param q_prim_vf Primitive variables + !! @param patch_id_fp Array to track patch ids + impure subroutine s_assign_patch_species_primitive_variables(patch_id, j, k, l, & + eta, q_prim_vf, patch_id_fp) $:GPU_ROUTINE(parallelism='[seq]') - integer, intent(in) :: patch_id - integer, intent(in) :: j, k, l + integer, intent(in) :: patch_id + integer, intent(in) :: j, k, l real(wp), intent(in) :: eta #ifdef MFC_MIXED_PRECISION - integer(kind=1), dimension(0:m,0:n,0:p), intent(inout) :: patch_id_fp + integer(kind=1), dimension(0:m, 0:n, 0:p), intent(inout) :: patch_id_fp #else - integer, dimension(0:m,0:n,0:p), intent(inout) :: patch_id_fp + integer, dimension(0:m, 0:n, 0:p), intent(inout) :: patch_id_fp #endif type(scalar_field), dimension(1:sys_size), intent(inout) :: q_prim_vf - ! Density, gamma, and liquid stiffness from current and smoothing patches - real(wp) :: rho !< density - real(wp) :: gamma - real(wp) :: lit_gamma !< specific heat ratio - real(wp) :: pi_inf !< stiffness from SEOS - real(wp) :: qv !< reference energy from SEOS - real(wp) :: orig_rho - real(wp) :: orig_gamma - real(wp) :: orig_pi_inf - real(wp) :: orig_qv - real(wp) :: muR, muV - real(wp) :: R3bar - real(wp) :: rcoord, theta, phi, xi_sph - real(wp), dimension(3) :: xi_cart - real(wp) :: Ys(1:num_species) - real(stp), dimension(sys_size) :: orig_prim_vf !< Vector to hold original values of cell for smoothing purposes - integer :: i - integer :: smooth_patch_id + ! Density, the specific heat ratio function and the liquid stiffness + ! function, respectively, obtained from the combination of primitive + ! variables of the current and smoothing patches + real(wp) :: rho !< density + real(wp) :: gamma + real(wp) :: lit_gamma !< specific heat ratio + real(wp) :: pi_inf !< stiffness from SEOS + real(wp) :: qv !< reference energy from SEOS + real(wp) :: orig_rho + real(wp) :: orig_gamma + real(wp) :: orig_pi_inf + real(wp) :: orig_qv + real(wp) :: muR, muV + real(wp) :: R3bar + real(wp) :: rcoord, theta, phi, xi_sph + real(wp), dimension(3) :: xi_cart + + real(wp) :: Ys(1:num_species) + + real(stp), dimension(sys_size) :: orig_prim_vf !< + !! Vector to hold original values of cell for smoothing purposes + integer :: i !< Generic loop iterator + integer :: smooth_patch_id + + ! Transferring the identity of the smoothing patch smooth_patch_id = patch_icpp(patch_id)%smooth_patch_id + ! Transferring original primitive variables do i = 1, sys_size orig_prim_vf(i) = q_prim_vf(i)%sf(j, k, l) end do if (mpp_lim .and. bubbles_euler) then - ! adjust volume fractions, according to modeled gas void fraction + !adjust volume fractions, according to modeled gas void fraction alf_sum%sf = 0._wp do i = adv_idx%beg, adv_idx%end - 1 alf_sum%sf = alf_sum%sf + q_prim_vf(i)%sf end do do i = adv_idx%beg, adv_idx%end - 1 - q_prim_vf(i)%sf = q_prim_vf(i)%sf*(1._wp - q_prim_vf(alf_idx)%sf)/alf_sum%sf + q_prim_vf(i)%sf = q_prim_vf(i)%sf*(1._wp - q_prim_vf(alf_idx)%sf) & + /alf_sum%sf end do end if - call s_convert_to_mixture_variables(q_prim_vf, j, k, l, orig_rho, orig_gamma, orig_pi_inf, orig_qv) + ! Computing Mixture Variables from Original Primitive Variables + ! call s_convert_species_to_mixture_variables( & + call s_convert_to_mixture_variables( & + q_prim_vf, j, k, l, & + orig_rho, & + orig_gamma, & + orig_pi_inf, orig_qv) + + ! Computing Mixture Variables of Current Patch if (.not. igr .or. num_fluids > 1) then + ! Volume fraction(s) do i = adv_idx%beg, adv_idx%end q_prim_vf(i)%sf(j, k, l) = patch_icpp(patch_id)%alpha(i - E_idx) end do end if if (mpp_lim .and. bubbles_euler) then - ! adjust volume fractions, according to modeled gas void fraction + !adjust volume fractions, according to modeled gas void fraction alf_sum%sf = 0._wp do i = adv_idx%beg, adv_idx%end - 1 alf_sum%sf = alf_sum%sf + q_prim_vf(i)%sf end do do i = adv_idx%beg, adv_idx%end - 1 - q_prim_vf(i)%sf = q_prim_vf(i)%sf*(1._wp - q_prim_vf(alf_idx)%sf)/alf_sum%sf + q_prim_vf(i)%sf = q_prim_vf(i)%sf*(1._wp - q_prim_vf(alf_idx)%sf) & + /alf_sum%sf end do end if + ! Partial densities if (model_eqns /= 4) then do i = 1, cont_idx%end q_prim_vf(i)%sf(j, k, l) = patch_icpp(patch_id)%alpha_rho(i) end do end if - call s_convert_to_mixture_variables(q_prim_vf, j, k, l, patch_icpp(patch_id)%rho, patch_icpp(patch_id)%gamma, & - & patch_icpp(patch_id)%pi_inf, patch_icpp(patch_id)%qv) + ! Density and the specific heat ratio and liquid stiffness functions + ! call s_convert_species_to_mixture_variables( & + call s_convert_to_mixture_variables( & + q_prim_vf, j, k, l, & + patch_icpp(patch_id)%rho, & + patch_icpp(patch_id)%gamma, & + patch_icpp(patch_id)%pi_inf, & + patch_icpp(patch_id)%qv) + + ! Computing Mixture Variables of Smoothing Patch if (model_eqns /= 4) then + ! Partial densities do i = 1, cont_idx%end q_prim_vf(i)%sf(j, k, l) = patch_icpp(smooth_patch_id)%alpha_rho(i) end do end if if (.not. igr .or. num_fluids > 1) then + ! Volume fraction(s) do i = adv_idx%beg, adv_idx%end q_prim_vf(i)%sf(j, k, l) = patch_icpp(smooth_patch_id)%alpha(i - E_idx) end do end if if (mpp_lim .and. bubbles_euler) then - ! adjust volume fractions, according to modeled gas void fraction + !adjust volume fractions, according to modeled gas void fraction alf_sum%sf = 0._wp do i = adv_idx%beg, adv_idx%end - 1 alf_sum%sf = alf_sum%sf + q_prim_vf(i)%sf end do do i = adv_idx%beg, adv_idx%end - 1 - q_prim_vf(i)%sf = q_prim_vf(i)%sf*(1._wp - q_prim_vf(alf_idx)%sf)/alf_sum%sf + q_prim_vf(i)%sf = q_prim_vf(i)%sf*(1._wp - q_prim_vf(alf_idx)%sf) & + /alf_sum%sf end do end if + ! Bubbles euler variables if (bubbles_euler) then do i = 1, nb muR = R0(i)*patch_icpp(smooth_patch_id)%r0/R0ref @@ -351,42 +460,67 @@ contains end if end if - call s_convert_to_mixture_variables(q_prim_vf, j, k, l, patch_icpp(smooth_patch_id)%rho, & - & patch_icpp(smooth_patch_id)%gamma, patch_icpp(smooth_patch_id)%pi_inf, & - & patch_icpp(smooth_patch_id)%qv) + ! Density and the specific heat ratio and liquid stiffness functions + ! call s_convert_species_to_mixture_variables( & + call s_convert_to_mixture_variables( & + q_prim_vf, j, k, l, & + patch_icpp(smooth_patch_id)%rho, & + patch_icpp(smooth_patch_id)%gamma, & + patch_icpp(smooth_patch_id)%pi_inf, & + patch_icpp(smooth_patch_id)%qv) - q_prim_vf(E_idx)%sf(j, k, l) = (eta*patch_icpp(patch_id)%pres + (1._wp - eta)*orig_prim_vf(E_idx)) + ! Pressure + q_prim_vf(E_idx)%sf(j, k, l) = & + (eta*patch_icpp(patch_id)%pres & + + (1._wp - eta)*orig_prim_vf(E_idx)) if (.not. igr .or. num_fluids > 1) then + ! Volume fractions \alpha do i = adv_idx%beg, adv_idx%end - q_prim_vf(i)%sf(j, k, l) = eta*patch_icpp(patch_id)%alpha(i - E_idx) + (1._wp - eta)*orig_prim_vf(i) + q_prim_vf(i)%sf(j, k, l) = & + eta*patch_icpp(patch_id)%alpha(i - E_idx) & + + (1._wp - eta)*orig_prim_vf(i) end do end if if (mhd) then - if (n == 0) then ! 1D: By, Bz - q_prim_vf(B_idx%beg)%sf(j, k, l) = eta*patch_icpp(patch_id)%By + (1._wp - eta)*orig_prim_vf(B_idx%beg) - q_prim_vf(B_idx%beg + 1)%sf(j, k, l) = eta*patch_icpp(patch_id)%Bz + (1._wp - eta)*orig_prim_vf(B_idx%beg + 1) - else ! 2D/3D: Bx, By, Bz - q_prim_vf(B_idx%beg)%sf(j, k, l) = eta*patch_icpp(patch_id)%Bx + (1._wp - eta)*orig_prim_vf(B_idx%beg) - q_prim_vf(B_idx%beg + 1)%sf(j, k, l) = eta*patch_icpp(patch_id)%By + (1._wp - eta)*orig_prim_vf(B_idx%beg + 1) - q_prim_vf(B_idx%beg + 2)%sf(j, k, l) = eta*patch_icpp(patch_id)%Bz + (1._wp - eta)*orig_prim_vf(B_idx%beg + 2) + if (n == 0) then ! 1D: By, Bz + q_prim_vf(B_idx%beg)%sf(j, k, l) = & + eta*patch_icpp(patch_id)%By & + + (1._wp - eta)*orig_prim_vf(B_idx%beg) + q_prim_vf(B_idx%beg + 1)%sf(j, k, l) = & + eta*patch_icpp(patch_id)%Bz & + + (1._wp - eta)*orig_prim_vf(B_idx%beg + 1) + else ! 2D/3D: Bx, By, Bz + q_prim_vf(B_idx%beg)%sf(j, k, l) = & + eta*patch_icpp(patch_id)%Bx & + + (1._wp - eta)*orig_prim_vf(B_idx%beg) + q_prim_vf(B_idx%beg + 1)%sf(j, k, l) = & + eta*patch_icpp(patch_id)%By & + + (1._wp - eta)*orig_prim_vf(B_idx%beg + 1) + q_prim_vf(B_idx%beg + 2)%sf(j, k, l) = & + eta*patch_icpp(patch_id)%Bz & + + (1._wp - eta)*orig_prim_vf(B_idx%beg + 2) end if end if + ! Elastic Shear Stress if (elasticity) then do i = 1, (stress_idx%end - stress_idx%beg) + 1 - q_prim_vf(i + stress_idx%beg - 1)%sf(j, k, & - & l) = (eta*patch_icpp(patch_id)%tau_e(i) + (1._wp - eta)*orig_prim_vf(i + stress_idx%beg - 1)) + q_prim_vf(i + stress_idx%beg - 1)%sf(j, k, l) = & + (eta*patch_icpp(patch_id)%tau_e(i) & + + (1._wp - eta)*orig_prim_vf(i + stress_idx%beg - 1)) end do end if + ! Elastic Shear Stress if (hyperelasticity) then - if (pre_stress) then ! pre stressed initial condition in spatial domain + + if (pre_stress) then ! pre stressed initial condition in spatial domain rcoord = sqrt((x_cc(j)**2 + y_cc(k)**2 + z_cc(l)**2)) theta = atan2(y_cc(k), x_cc(j)) phi = atan2(sqrt(x_cc(j)**2 + y_cc(k)**2), z_cc(l)) - ! spherical coord, assuming Rmax=1 + !spherical coord, assuming Rmax=1 xi_sph = (rcoord**3 - R0ref**3 + 1._wp)**(1._wp/3._wp) xi_cart(1) = xi_sph*sin(phi)*cos(theta) xi_cart(2) = xi_sph*sin(phi)*sin(theta) @@ -399,52 +533,67 @@ contains ! assigning the reference map to the q_prim vector field do i = 1, num_dims - q_prim_vf(i + xibeg - 1)%sf(j, k, l) = eta*xi_cart(i) + (1._wp - eta)*orig_prim_vf(i + xibeg - 1) + q_prim_vf(i + xibeg - 1)%sf(j, k, l) = eta*xi_cart(i) + & + (1._wp - eta)*orig_prim_vf(i + xibeg - 1) end do end if if (mpp_lim .and. bubbles_euler) then - ! adjust volume fractions, according to modeled gas void fraction + !adjust volume fractions, according to modeled gas void fraction alf_sum%sf = 0._wp do i = adv_idx%beg, adv_idx%end - 1 alf_sum%sf = alf_sum%sf + q_prim_vf(i)%sf end do do i = adv_idx%beg, adv_idx%end - 1 - q_prim_vf(i)%sf = q_prim_vf(i)%sf*(1._wp - q_prim_vf(alf_idx)%sf)/alf_sum%sf + q_prim_vf(i)%sf = q_prim_vf(i)%sf*(1._wp - q_prim_vf(alf_idx)%sf) & + /alf_sum%sf end do end if + ! Partial densities \alpha \rho if (model_eqns /= 4) then - ! mixture density is an input + !mixture density is an input do i = 1, cont_idx%end - q_prim_vf(i)%sf(j, k, l) = eta*patch_icpp(patch_id)%alpha_rho(i) + (1._wp - eta)*orig_prim_vf(i) + q_prim_vf(i)%sf(j, k, l) = & + eta*patch_icpp(patch_id)%alpha_rho(i) & + + (1._wp - eta)*orig_prim_vf(i) end do else - ! get mixture density from pressure via Tait EOS + !get mixture density from pressure via Tait EOS pi_inf = pi_infs(1) gamma = gammas(1) lit_gamma = gs_min(1) ! \rho = (( p_l + pi_inf)/( p_ref + pi_inf))**(1/little_gam) * rhoref(1-alf) - q_prim_vf(1)%sf(j, k, l) = (((q_prim_vf(E_idx)%sf(j, k, & - & l) + pi_inf)/(pref + pi_inf))**(1/lit_gamma))*rhoref*(1 - q_prim_vf(alf_idx)%sf(j, k, l)) + q_prim_vf(1)%sf(j, k, l) = & + (((q_prim_vf(E_idx)%sf(j, k, l) + pi_inf)/(pref + pi_inf))**(1/lit_gamma))* & + rhoref*(1 - q_prim_vf(alf_idx)%sf(j, k, l)) end if - call s_convert_to_mixture_variables(q_prim_vf, j, k, l, rho, gamma, pi_inf, qv) + ! Density and the specific heat ratio and liquid stiffness functions + ! call s_convert_species_to_mixture_variables(q_prim_vf, j, k, l, & + call s_convert_to_mixture_variables(q_prim_vf, j, k, l, & + rho, gamma, pi_inf, qv) + ! Velocity do i = 1, E_idx - mom_idx%beg - q_prim_vf(i + cont_idx%end)%sf(j, k, & - & l) = (eta*patch_icpp(patch_id)%vel(i) + (1._wp - eta)*orig_prim_vf(i + cont_idx%end)) + q_prim_vf(i + cont_idx%end)%sf(j, k, l) = & + (eta*patch_icpp(patch_id)%vel(i) & + + (1._wp - eta)*orig_prim_vf(i + cont_idx%end)) end do + ! Species Concentrations if (chemistry) then block real(wp) :: sum, term + ! Accumulating the species concentrations sum = 0._wp do i = 1, num_species - term = eta*patch_icpp(patch_id)%Y(i) + (1._wp - eta)*patch_icpp(smooth_patch_id)%Y(i) + term = & + eta*patch_icpp(patch_id)%Y(i) & + + (1._wp - eta)*patch_icpp(smooth_patch_id)%Y(i) q_prim_vf(chemxb + i - 1)%sf(j, k, l) = term sum = sum + term end do @@ -453,8 +602,10 @@ contains sum = 1._wp end if + ! Normalizing the species concentrations do i = 1, num_species - q_prim_vf(chemxb + i - 1)%sf(j, k, l) = q_prim_vf(chemxb + i - 1)%sf(j, k, l)/sum + q_prim_vf(chemxb + i - 1)%sf(j, k, l) = & + q_prim_vf(chemxb + i - 1)%sf(j, k, l)/sum Ys(i) = q_prim_vf(chemxb + i - 1)%sf(j, k, l) end do end block @@ -462,9 +613,9 @@ contains ! Set streamwise velocity to hyperbolic tangent function of y if (mixlayer_vel_profile) then - q_prim_vf(1 + cont_idx%end)%sf(j, k, & - & l) = (eta*patch_icpp(patch_id)%vel(1)*tanh(y_cc(k)*mixlayer_vel_coef) + (1._wp - eta)*orig_prim_vf(1 & - & + cont_idx%end)) + q_prim_vf(1 + cont_idx%end)%sf(j, k, l) = & + (eta*patch_icpp(patch_id)%vel(1)*tanh(y_cc(k)*mixlayer_vel_coef) & + + (1._wp - eta)*orig_prim_vf(1 + cont_idx%end)) end if ! Set partial pressures to mixture pressure for the 6-eqn model @@ -474,6 +625,7 @@ contains end do end if + ! Smoothed bubble variables if (bubbles_euler) then do i = 1, nb muR = R0(i)*patch_icpp(patch_id)%r0/R0ref @@ -503,6 +655,7 @@ contains q_prim_vf(bub_idx%ps(i))%sf(j, k, l) = patch_icpp(patch_id)%p0 q_prim_vf(bub_idx%ms(i))%sf(j, k, l) = patch_icpp(patch_id)%m0 end if + end if end do @@ -517,14 +670,15 @@ contains end if if (mpp_lim .and. bubbles_euler) then - ! adjust volume fractions, according to modeled gas void fraction + !adjust volume fractions, according to modeled gas void fraction alf_sum%sf = 0._wp do i = adv_idx%beg, adv_idx%end - 1 alf_sum%sf = alf_sum%sf + q_prim_vf(i)%sf end do do i = adv_idx%beg, adv_idx%end - 1 - q_prim_vf(i)%sf = q_prim_vf(i)%sf*(1._wp - q_prim_vf(alf_idx)%sf)/alf_sum%sf + q_prim_vf(i)%sf = q_prim_vf(i)%sf*(1._wp - q_prim_vf(alf_idx)%sf) & + /alf_sum%sf end do end if @@ -532,6 +686,7 @@ contains do i = 1, nb if (f_is_default(real(q_prim_vf(bub_idx%ps(i))%sf(j, k, l), kind=wp))) then q_prim_vf(bub_idx%ps(i))%sf(j, k, l) = pb0(i) + ! print *, 'setting to pb0' end if if (f_is_default(real(q_prim_vf(bub_idx%ms(i))%sf(j, k, l), kind=wp))) then q_prim_vf(bub_idx%ms(i))%sf(j, k, l) = mass_v0(i) @@ -540,16 +695,30 @@ contains end if if (surface_tension) then - q_prim_vf(c_idx)%sf(j, k, l) = eta*patch_icpp(patch_id)%cf_val + (1._wp - eta)*orig_prim_vf(c_idx) + q_prim_vf(c_idx)%sf(j, k, l) = eta*patch_icpp(patch_id)%cf_val + & + (1._wp - eta)*orig_prim_vf(c_idx) end if + ! Updating the patch identities bookkeeping variable if (1._wp - eta < 1.e-16_wp) patch_id_fp(j, k, l) = patch_id + ! if (j == 1) then + ! print *, (q_prim_vf(bub_idx%rs(i))%sf(j, k, l), i = 1, nb) + ! print *, (q_prim_vf(bub_idx%fullmom(i, 1, 0))%sf(j, k, l), i = 1, nb) + ! print *, (R0(i), i = 1, nb) + ! print *, patch_icpp(patch_id)%r0 + ! print *, (bub_idx%rs(i), i = 1, nb) + ! print *, (bub_idx%fullmom(i, 1, 0), i = 1, nb) + ! end if + end subroutine s_assign_patch_species_primitive_variables - !> Nullify the patch primitive variable assignment procedure pointer. + !> @brief Nullifies the patch primitive variable assignment procedure pointer. impure subroutine s_finalize_assign_variables_module + ! Nullifying procedure pointer to the subroutine assigning either + ! the patch mixture or species primitive variables to a cell in the + ! computational domain s_assign_patch_primitive_variables => null() end subroutine s_finalize_assign_variables_module diff --git a/src/pre_process/m_boundary_conditions.fpp b/src/pre_process/m_boundary_conditions.fpp index 70c3485a12..46cbbda47c 100644 --- a/src/pre_process/m_boundary_conditions.fpp +++ b/src/pre_process/m_boundary_conditions.fpp @@ -6,32 +6,36 @@ module m_boundary_conditions use m_derived_types + use m_global_parameters #ifdef MFC_MPI use mpi #endif use m_delay_file_access + use m_compile_specific + use m_boundary_common implicit none - real(wp) :: x_centroid, y_centroid, z_centroid - real(wp) :: length_x, length_y, length_z - real(wp) :: radius - type(bounds_info) :: x_boundary, y_boundary, z_boundary + real(wp) :: x_centroid, y_centroid, z_centroid + real(wp) :: length_x, length_y, length_z + real(wp) :: radius + type(bounds_info) :: x_boundary, y_boundary, z_boundary !< + private; public :: s_apply_boundary_patches contains - !> Apply a line-segment boundary condition patch along a domain edge in 2D. + !> @brief Applies a line-segment boundary condition patch along a domain edge in 2D. impure subroutine s_line_segment_bc(patch_id, bc_type) - type(integer_field), dimension(1:num_dims,1:2), intent(inout) :: bc_type - integer, intent(in) :: patch_id - integer :: j + type(integer_field), dimension(1:num_dims, 1:2), intent(inout) :: bc_type + integer, intent(in) :: patch_id - ! Patch is a line segment along y on the x-boundary face + integer :: j + ! Patch is a vertical line at x_beg or x_end if (patch_bc(patch_id)%dir == 1) then y_centroid = patch_bc(patch_id)%centroid(2) length_y = patch_bc(patch_id)%length(2) @@ -39,7 +43,7 @@ contains y_boundary%beg = y_centroid - 0.5_wp*length_y y_boundary%end = y_centroid + 0.5_wp*length_y - ! Apply patch if x boundary is a domain boundary + ! Patch is a vertical line at x_beg and x_beg is a domain boundary #:for BOUND, X, LOC, IDX in [('beg', '-i', -1, 1), ('end', 'm+i', 1, 2)] if (patch_bc(patch_id)%loc == ${LOC}$ .and. bc_x%${BOUND}$ < 0) then do j = 0, n @@ -51,7 +55,7 @@ contains #:endfor end if - ! Patch is a line segment along x on the y-boundary face + ! Patch is a vertical line at y_beg or y_end if (patch_bc(patch_id)%dir == 2) then x_centroid = patch_bc(patch_id)%centroid(1) length_x = patch_bc(patch_id)%length(1) @@ -59,7 +63,7 @@ contains x_boundary%beg = x_centroid - 0.5_wp*length_x x_boundary%end = x_centroid + 0.5_wp*length_x - ! Apply patch if y boundary is a domain boundary + ! Patch is a vertical line at x_beg and x_beg is a domain boundary #:for BOUND, Y, LOC, IDX in [('beg', '-i', -1, 1), ('end', 'n+i', 1, 2)] if (patch_bc(patch_id)%loc == ${LOC}$ .and. bc_y%${BOUND}$ < 0) then do j = 0, m @@ -73,13 +77,14 @@ contains end subroutine s_line_segment_bc - !> Apply a circular boundary condition patch on a domain face in 3D. + !> @brief Applies a circular boundary condition patch on a domain face in 3D. impure subroutine s_circle_bc(patch_id, bc_type) - type(integer_field), dimension(1:num_dims,1:2), intent(inout) :: bc_type - integer, intent(in) :: patch_id - integer :: j, k + type(integer_field), dimension(1:num_dims, 1:2), intent(inout) :: bc_type + integer, intent(in) :: patch_id + + integer :: j, k if (patch_bc(patch_id)%dir == 1) then y_centroid = patch_bc(patch_id)%centroid(2) z_centroid = patch_bc(patch_id)%centroid(3) @@ -89,7 +94,8 @@ contains if (patch_bc(patch_id)%loc == ${LOC}$ .and. bc_x%${BOUND}$ < 0) then do k = 0, p do j = 0, n - if ((z_cc(k) - z_centroid)**2._wp + (y_cc(j) - y_centroid)**2._wp <= radius**2._wp) then + if ((z_cc(k) - z_centroid)**2._wp + & + (y_cc(j) - y_centroid)**2._wp <= radius**2._wp) then bc_type(1, ${IDX}$)%sf(0, j, k) = patch_bc(patch_id)%type end if end do @@ -106,7 +112,8 @@ contains if (patch_bc(patch_id)%loc == ${LOC}$ .and. bc_y%${BOUND}$ < 0) then do k = 0, p do j = 0, m - if ((z_cc(k) - z_centroid)**2._wp + (x_cc(j) - x_centroid)**2._wp <= radius**2._wp) then + if ((z_cc(k) - z_centroid)**2._wp + & + (x_cc(j) - x_centroid)**2._wp <= radius**2._wp) then bc_type(2, ${IDX}$)%sf(j, 0, k) = patch_bc(patch_id)%type end if end do @@ -122,7 +129,8 @@ contains if (patch_bc(patch_id)%loc == ${LOC}$ .and. bc_z%${BOUND}$ < 0) then do k = 0, n do j = 0, m - if ((y_cc(k) - y_centroid)**2._wp + (x_cc(j) - x_centroid)**2._wp <= radius**2._wp) then + if ((y_cc(k) - y_centroid)**2._wp + & + (x_cc(j) - x_centroid)**2._wp <= radius**2._wp) then bc_type(3, ${IDX}$)%sf(j, k, 0) = patch_bc(patch_id)%type end if end do @@ -133,13 +141,13 @@ contains end subroutine s_circle_bc - !> Apply a rectangular boundary condition patch on a domain face in 3D. + !> @brief Applies a rectangular boundary condition patch on a domain face in 3D. impure subroutine s_rectangle_bc(patch_id, bc_type) - type(integer_field), dimension(1:num_dims,1:2), intent(inout) :: bc_type - integer, intent(in) :: patch_id - integer :: j, k + type(integer_field), dimension(1:num_dims, 1:2), intent(inout) :: bc_type + integer, intent(in) :: patch_id + integer :: j, k if (patch_bc(patch_id)%dir == 1) then y_centroid = patch_bc(patch_id)%centroid(2) z_centroid = patch_bc(patch_id)%centroid(3) @@ -151,13 +159,15 @@ contains z_boundary%beg = z_centroid - 0.5_wp*length_z z_boundary%end = z_centroid + 0.5_wp*length_z - ! Patch is a rectangle on the x-boundary face + ! Patch is a circle at x_beg and x_beg is a domain boundary #:for BOUND, X, LOC, IDX in [('beg', '-i', -1, 1), ('end', 'm+i', 1, 2)] if (patch_bc(patch_id)%loc == ${LOC}$ .and. bc_x%${BOUND}$ < 0) then do k = 0, p do j = 0, n - if (y_boundary%beg <= y_cc(j) .and. y_boundary%end >= y_cc(j) .and. z_boundary%beg <= z_cc(k) & - & .and. z_boundary%end >= z_cc(k)) then + if (y_boundary%beg <= y_cc(j) .and. & + y_boundary%end >= y_cc(j) .and. & + z_boundary%beg <= z_cc(k) .and. & + z_boundary%end >= z_cc(k)) then bc_type(1, ${IDX}$)%sf(0, j, k) = patch_bc(patch_id)%type end if end do @@ -176,13 +186,15 @@ contains z_boundary%beg = z_centroid - 0.5_wp*length_z z_boundary%end = z_centroid + 0.5_wp*length_z - ! Patch is a rectangle on the y-boundary face + ! Patch is a circle at y_beg and y_beg is a domain boundary #:for BOUND, Y, LOC, IDX in [('beg', '-i', -1, 1), ('end', 'n+i', 1, 2)] if (patch_bc(patch_id)%loc == ${LOC}$ .and. bc_y%${BOUND}$ < 0) then do k = 0, p do j = 0, m - if (x_boundary%beg <= x_cc(j) .and. x_boundary%end >= x_cc(j) .and. z_boundary%beg <= z_cc(k) & - & .and. z_boundary%end >= z_cc(k)) then + if (x_boundary%beg <= x_cc(j) .and. & + x_boundary%end >= x_cc(j) .and. & + z_boundary%beg <= z_cc(k) .and. & + z_boundary%end >= z_cc(k)) then bc_type(2, ${IDX}$)%sf(j, 0, k) = patch_bc(patch_id)%type end if end do @@ -205,8 +217,10 @@ contains if (patch_bc(patch_id)%loc == ${LOC}$ .and. bc_z%${BOUND}$ < 0) then do k = 0, n do j = 0, m - if (x_boundary%beg <= x_cc(j) .and. x_boundary%end >= x_cc(j) .and. y_boundary%beg <= y_cc(k) & - & .and. y_boundary%end >= y_cc(k)) then + if (x_boundary%beg <= x_cc(j) .and. & + x_boundary%end >= x_cc(j) .and. & + y_boundary%beg <= y_cc(k) .and. & + y_boundary%end >= y_cc(k)) then bc_type(3, ${IDX}$)%sf(j, k, 0) = patch_bc(patch_id)%type end if end do @@ -217,15 +231,14 @@ contains end subroutine s_rectangle_bc - !> Iterate over all boundary condition patches and dispatch them by geometry type. + !> @brief Iterates over all boundary condition patches and dispatches them by geometry type. impure subroutine s_apply_boundary_patches(q_prim_vf, bc_type) - type(scalar_field), dimension(sys_size) :: q_prim_vf - type(integer_field), dimension(1:num_dims,1:2) :: bc_type - integer :: i - - !> Apply 2D patches to 3D domain + type(scalar_field), dimension(sys_size) :: q_prim_vf + type(integer_field), dimension(1:num_dims, 1:2) :: bc_type + integer :: i + !< Apply 2D patches to 3D domain if (p > 0) then do i = 1, num_bc_patches if (proc_rank == 0) then @@ -234,12 +247,12 @@ contains if (patch_bc(i)%geometry == 2) then call s_circle_bc(i, bc_type) - else if (patch_bc(i)%geometry == 3) then + elseif (patch_bc(i)%geometry == 3) then call s_rectangle_bc(i, bc_type) end if end do - !> Apply 1D patches to 2D domain - else if (n > 0) then + !< Apply 1D patches to 2D domain + elseif (n > 0) then do i = 1, num_bc_patches if (proc_rank == 0) then print *, 'Processing boundary condition patch', i diff --git a/src/pre_process/m_check_ib_patches.fpp b/src/pre_process/m_check_ib_patches.fpp index 844d051716..ea481d2e91 100644 --- a/src/pre_process/m_check_ib_patches.fpp +++ b/src/pre_process/m_check_ib_patches.fpp @@ -8,36 +8,45 @@ module m_check_ib_patches - use m_derived_types - use m_global_parameters - use m_mpi_proxy - use m_data_output + use m_derived_types !< Definitions of the derived types + + use m_global_parameters !< Global parameters + + use m_mpi_proxy !< Message passing interface (MPI) module proxy + + use m_data_output !< Procedures to write the grid data and the + !! conservative variables to files + #ifdef MFC_MPI - use mpi !< Message passing interface (MPI) module + use mpi !< Message passing interface (MPI) module #endif use m_compile_specific - use m_helper_basic + + use m_helper_basic !< Functions to compare floating point numbers + use m_helper implicit none - private + private; public :: s_check_ib_patches character(len=10) :: iStr contains - !> Validate the geometry parameters of all active and inactive immersed boundary patches. + !> @brief Validates the geometry parameters of all active and inactive immersed boundary patches. impure subroutine s_check_ib_patches integer :: i do i = 1, num_patches_max if (i <= num_ibs) then + ! call s_check_patch_geometry(i) call s_int_to_str(i, iStr) - @:PROHIBIT(patch_ib(i)%geometry == dflt_int, "IB patch undefined. patch_ib("//trim(iStr)//")%geometry must be set.") + @:PROHIBIT(patch_ib(i)%geometry == dflt_int, "IB patch undefined. & + patch_ib("//trim(iStr)//")%geometry must be set.") ! Constraints on the geometric initial condition patch parameters if (patch_ib(i)%geometry == 2) then @@ -54,173 +63,265 @@ contains call s_check_3d_airfoil_ib_patch_geometry(i) else if (patch_ib(i)%geometry == 10) then call s_check_cylinder_ib_patch_geometry(i) - else if (patch_ib(i)%geometry == 5 .or. patch_ib(i)%geometry == 12) then + else if (patch_ib(i)%geometry == 5 .or. & + patch_ib(i)%geometry == 12) then call s_check_model_ib_patch_geometry(i) else if (patch_ib(i)%geometry == 6) then call s_check_ellipse_ib_patch_geometry(i) else call s_prohibit_abort("Invalid IB patch", & - & "patch_ib(" // trim(iStr) // ")%geometry must be " // "2-4, 8-10, 11 or 12.") + "patch_ib("//trim(iStr)//")%geometry must be "// & + "2-4, 8-10, 11 or 12.") end if else - @:PROHIBIT(patch_ib(i)%geometry /= dflt_int, & - & "Inactive IB patch defined. " // "patch_ib(" // trim(iStr) & - & // ")%geometry must not be set for inactive patches.") + @:PROHIBIT(patch_ib(i)%geometry /= dflt_int, "Inactive IB patch defined. "// & + "patch_ib("//trim(iStr)//")%geometry must not be set for inactive patches.") call s_check_inactive_ib_patch_geometry(i) end if end do end subroutine s_check_ib_patches - !> Verify that the geometric parameters of the circle patch have been consistently inputted. - + !> This subroutine verifies that the geometric parameters of + !! the circle patch have consistently been inputted by the + !! user. + !! @param patch_id Patch identifier impure subroutine s_check_circle_ib_patch_geometry(patch_id) integer, intent(in) :: patch_id call s_int_to_str(patch_id, iStr) - @:PROHIBIT(n == 0 .or. p > 0 .or. patch_ib(patch_id)%radius <= 0._wp .or. f_is_default(patch_ib(patch_id)%x_centroid) & - & .or. f_is_default(patch_ib(patch_id)%y_centroid), 'in circle IB patch ' // trim(iStr)) + @:PROHIBIT(n == 0 .or. p > 0 & + .or. patch_ib(patch_id)%radius <= 0._wp & + .or. f_is_default(patch_ib(patch_id)%x_centroid) & + .or. f_is_default(patch_ib(patch_id)%y_centroid), & + 'in circle IB patch '//trim(iStr)) end subroutine s_check_circle_ib_patch_geometry - !> Verify that the geometric parameters of the ellipse patch have been consistently inputted. - + !> This subroutine verifies that the geometric parameters of + !! the ellipse patch have consistently been inputted by the + !! user. + !! @param patch_id Patch identifier impure subroutine s_check_ellipse_ib_patch_geometry(patch_id) integer, intent(in) :: patch_id call s_int_to_str(patch_id, iStr) - @:PROHIBIT(n == 0 .or. p > 0 .or. patch_ib(patch_id)%length_x <= 0._wp .or. patch_ib(patch_id) & - & %length_y <= 0._wp .or. f_is_default(patch_ib(patch_id)%x_centroid) .or. f_is_default(patch_ib(patch_id) & - & %y_centroid), 'in ellipse IB patch ' // trim(iStr)) + @:PROHIBIT(n == 0 .or. p > 0 & + .or. patch_ib(patch_id)%length_x <= 0._wp & + .or. patch_ib(patch_id)%length_y <= 0._wp & + .or. f_is_default(patch_ib(patch_id)%x_centroid) & + .or. f_is_default(patch_ib(patch_id)%y_centroid), & + 'in ellipse IB patch '//trim(iStr)) end subroutine s_check_ellipse_ib_patch_geometry - !> Verify that the geometric parameters of the airfoil patch have been consistently inputted. - + !> This subroutine verifies that the geometric parameters of + !! the airfoil patch have consistently been inputted by the + !! user. + !! @param patch_id Patch identifier impure subroutine s_check_airfoil_ib_patch_geometry(patch_id) integer, intent(in) :: patch_id call s_int_to_str(patch_id, iStr) - @:PROHIBIT(n == 0 .or. p > 0 .or. patch_ib(patch_id)%c <= 0._wp .or. patch_ib(patch_id)%p <= 0._wp .or. patch_ib(patch_id) & - & %t <= 0._wp .or. patch_ib(patch_id)%m <= 0._wp .or. f_is_default(patch_ib(patch_id)%x_centroid) & - & .or. f_is_default(patch_ib(patch_id)%y_centroid), 'in airfoil IB patch ' // trim(iStr)) + @:PROHIBIT(n == 0 .or. p > 0 & + .or. patch_ib(patch_id)%c <= 0._wp & + .or. patch_ib(patch_id)%p <= 0._wp & + .or. patch_ib(patch_id)%t <= 0._wp & + .or. patch_ib(patch_id)%m <= 0._wp & + .or. f_is_default(patch_ib(patch_id)%x_centroid) & + .or. f_is_default(patch_ib(patch_id)%y_centroid), & + 'in airfoil IB patch '//trim(iStr)) end subroutine s_check_airfoil_ib_patch_geometry - !> Verify that the geometric parameters of the 3D airfoil patch have been consistently inputted. - + !> This subroutine verifies that the geometric parameters of + !! the 3d airfoil patch have consistently been inputted by the + !! user. + !! @param patch_id Patch identifier impure subroutine s_check_3d_airfoil_ib_patch_geometry(patch_id) integer, intent(in) :: patch_id call s_int_to_str(patch_id, iStr) - @:PROHIBIT(n == 0 .or. p == 0 .or. patch_ib(patch_id)%c <= 0._wp .or. patch_ib(patch_id) & - & %p <= 0._wp .or. patch_ib(patch_id)%t <= 0._wp .or. patch_ib(patch_id) & - & %m <= 0._wp .or. f_is_default(patch_ib(patch_id)%x_centroid) .or. f_is_default(patch_ib(patch_id)%y_centroid) & - & .or. f_is_default(patch_ib(patch_id)%z_centroid) .or. f_is_default(patch_ib(patch_id)%length_z), & - & 'in 3d airfoil IB patch ' // trim(iStr)) + @:PROHIBIT(n == 0 .or. p == 0 & + .or. patch_ib(patch_id)%c <= 0._wp & + .or. patch_ib(patch_id)%p <= 0._wp & + .or. patch_ib(patch_id)%t <= 0._wp & + .or. patch_ib(patch_id)%m <= 0._wp & + .or. f_is_default(patch_ib(patch_id)%x_centroid) & + .or. f_is_default(patch_ib(patch_id)%y_centroid) & + .or. f_is_default(patch_ib(patch_id)%z_centroid) & + .or. f_is_default(patch_ib(patch_id)%length_z), & + 'in 3d airfoil IB patch '//trim(iStr)) end subroutine s_check_3d_airfoil_ib_patch_geometry - !> Verify that the geometric parameters of the rectangle patch have been consistently inputted. - + !> This subroutine verifies that the geometric parameters of + !! the rectangle patch have consistently been inputted by + !! the user. + !! @param patch_id Patch identifier impure subroutine s_check_rectangle_ib_patch_geometry(patch_id) integer, intent(in) :: patch_id call s_int_to_str(patch_id, iStr) - @:PROHIBIT(n == 0 .or. p > 0 .or. f_is_default(patch_ib(patch_id)%x_centroid) .or. f_is_default(patch_ib(patch_id) & - & %y_centroid) .or. patch_ib(patch_id)%length_x <= 0._wp .or. patch_ib(patch_id)%length_y <= 0._wp, & - & 'in rectangle IB patch ' // trim(iStr)) + @:PROHIBIT(n == 0 .or. p > 0 & + .or. & + f_is_default(patch_ib(patch_id)%x_centroid) & + .or. & + f_is_default(patch_ib(patch_id)%y_centroid) & + .or. & + patch_ib(patch_id)%length_x <= 0._wp & + .or. & + patch_ib(patch_id)%length_y <= 0._wp, & + 'in rectangle IB patch '//trim(iStr)) end subroutine s_check_rectangle_ib_patch_geometry - !> Verify that the geometric parameters of the sphere patch have been consistently inputted. - + !> This subroutine verifies that the geometric parameters of + !! the sphere patch have consistently been inputted by + !! the user. + !! @param patch_id Patch identifier impure subroutine s_check_sphere_ib_patch_geometry(patch_id) integer, intent(in) :: patch_id call s_int_to_str(patch_id, iStr) - @:PROHIBIT(n == 0 .or. p == 0 .or. f_is_default(patch_ib(patch_id)%x_centroid) .or. f_is_default(patch_ib(patch_id) & - & %y_centroid) .or. f_is_default(patch_ib(patch_id)%z_centroid) .or. patch_ib(patch_id)%radius <= 0._wp, & - & 'in sphere IB patch ' // trim(iStr)) + @:PROHIBIT(n == 0 .or. p == 0 & + .or. & + f_is_default(patch_ib(patch_id)%x_centroid) & + .or. & + f_is_default(patch_ib(patch_id)%y_centroid) & + .or. & + f_is_default(patch_ib(patch_id)%z_centroid) & + .or. & + patch_ib(patch_id)%radius <= 0._wp, & + 'in sphere IB patch '//trim(iStr)) end subroutine s_check_sphere_ib_patch_geometry - !> Verify that the geometric parameters of the cuboid patch have been consistently inputted. - + !> This subroutine verifies that the geometric parameters of + !! the cuboid patch have consistently been inputted by + !! the user. + !! @param patch_id Patch identifier impure subroutine s_check_cuboid_ib_patch_geometry(patch_id) integer, intent(in) :: patch_id call s_int_to_str(patch_id, iStr) - @:PROHIBIT(n == 0 .or. p == 0 .or. f_is_default(patch_ib(patch_id)%x_centroid) .or. f_is_default(patch_ib(patch_id) & - & %y_centroid) .or. f_is_default(patch_ib(patch_id)%z_centroid) .or. patch_ib(patch_id) & - & %length_x <= 0._wp .or. patch_ib(patch_id)%length_y <= 0._wp .or. patch_ib(patch_id)%length_z <= 0._wp, & - & 'in cuboid IB patch ' // trim(iStr)) + @:PROHIBIT(n == 0 .or. p == 0 & + .or. & + f_is_default(patch_ib(patch_id)%x_centroid) & + .or. & + f_is_default(patch_ib(patch_id)%y_centroid) & + .or. & + f_is_default(patch_ib(patch_id)%z_centroid) & + .or. & + patch_ib(patch_id)%length_x <= 0._wp & + .or. & + patch_ib(patch_id)%length_y <= 0._wp & + .or. & + patch_ib(patch_id)%length_z <= 0._wp, & + 'in cuboid IB patch '//trim(iStr)) end subroutine s_check_cuboid_ib_patch_geometry - !> Verify that the geometric parameters of the cylinder patch have been consistently inputted. - + !> This subroutine verifies that the geometric parameters of + !! the cylinder patch have consistently been inputted by + !! the user. + !! @param patch_id Patch identifier impure subroutine s_check_cylinder_ib_patch_geometry(patch_id) integer, intent(in) :: patch_id call s_int_to_str(patch_id, iStr) - @:PROHIBIT(p == 0 .or. f_is_default(patch_ib(patch_id)%x_centroid) .or. f_is_default(patch_ib(patch_id)%y_centroid) & - & .or. f_is_default(patch_ib(patch_id)%z_centroid) .or. (patch_ib(patch_id) & - & %length_x <= 0._wp .and. patch_ib(patch_id)%length_y <= 0._wp .and. patch_ib(patch_id)%length_z <= 0._wp) & - & .or. patch_ib(patch_id)%radius <= 0._wp, 'in cylinder IB patch ' // trim(iStr)) - - @:PROHIBIT((patch_ib(patch_id)%length_x > 0._wp .and. ((.not. f_is_default(patch_ib(patch_id)%length_y)) & - & .or. (.not. f_is_default(patch_ib(patch_id)%length_z)))) .or. (patch_ib(patch_id) & - & %length_y > 0._wp .and. ((.not. f_is_default(patch_ib(patch_id)%length_x)) & - & .or. (.not. f_is_default(patch_ib(patch_id)%length_z)))) .or. (patch_ib(patch_id) & - & %length_z > 0._wp .and. ((.not. f_is_default(patch_ib(patch_id)%length_x)) & - & .or. (.not. f_is_default(patch_ib(patch_id)%length_y)))), 'in cylinder IB patch ' // trim(iStr)) + @:PROHIBIT(p == 0 & + .or. & + f_is_default(patch_ib(patch_id)%x_centroid) & + .or. & + f_is_default(patch_ib(patch_id)%y_centroid) & + .or. & + f_is_default(patch_ib(patch_id)%z_centroid) & + .or. & + (patch_ib(patch_id)%length_x <= 0._wp .and. & + patch_ib(patch_id)%length_y <= 0._wp .and. & + patch_ib(patch_id)%length_z <= 0._wp) & + .or. & + patch_ib(patch_id)%radius <= 0._wp, & + 'in cylinder IB patch '//trim(iStr)) + + @:PROHIBIT( & + (patch_ib(patch_id)%length_x > 0._wp .and. & + ((.not. f_is_default(patch_ib(patch_id)%length_y)) .or. & + (.not. f_is_default(patch_ib(patch_id)%length_z)))) & + .or. & + (patch_ib(patch_id)%length_y > 0._wp .and. & + ((.not. f_is_default(patch_ib(patch_id)%length_x)) .or. & + (.not. f_is_default(patch_ib(patch_id)%length_z)))) & + .or. & + (patch_ib(patch_id)%length_z > 0._wp .and. & + ((.not. f_is_default(patch_ib(patch_id)%length_x)) .or. & + (.not. f_is_default(patch_ib(patch_id)%length_y)))), & + 'in cylinder IB patch '//trim(iStr)) end subroutine s_check_cylinder_ib_patch_geometry - !> Verify that the geometric parameters of the model patch have been consistently inputted. - + !> This subroutine verifies that the geometric parameters of + !! the model patch have consistently been inputted by + !! the user. + !! @param patch_id Patch identifier impure subroutine s_check_model_ib_patch_geometry(patch_id) integer, intent(in) :: patch_id call s_int_to_str(patch_id, iStr) - @:PROHIBIT(patch_ib(patch_id)%model_filepath == dflt_char, 'Empty model file path for patch '//trim(iStr)) + @:PROHIBIT(patch_ib(patch_id)%model_filepath == dflt_char, & + 'Empty model file path for patch '//trim(iStr)) - @:PROHIBIT(patch_ib(patch_id)%model_scale(1) <= 0._wp .or. patch_ib(patch_id)%model_scale(2) & - & <= 0._wp .or. patch_ib(patch_id)%model_scale(3) <= 0._wp, 'Negative scale in model IB patch ' // trim(iStr)) + @:PROHIBIT(patch_ib(patch_id)%model_scale(1) <= 0._wp & + .or. & + patch_ib(patch_id)%model_scale(2) <= 0._wp & + .or. & + patch_ib(patch_id)%model_scale(3) <= 0._wp, & + 'Negative scale in model IB patch '//trim(iStr)) end subroutine s_check_model_ib_patch_geometry - !> Verify that inactive IB patch geometry parameters remain at defaults + !!> This subroutine verifies that the geometric parameters of + !! the inactive patch remain unaltered by the user inputs. + !! @param patch_id Patch identifier impure subroutine s_check_inactive_ib_patch_geometry(patch_id) integer, intent(in) :: patch_id call s_int_to_str(patch_id, iStr) - @:PROHIBIT((.not. f_is_default(patch_ib(patch_id)%x_centroid)) .or. (.not. f_is_default(patch_ib(patch_id)%y_centroid)) & - & .or. (.not. f_is_default(patch_ib(patch_id)%z_centroid)) .or. (.not. f_is_default(patch_ib(patch_id) & - & %length_x)) .or. (.not. f_is_default(patch_ib(patch_id)%length_y)) & - & .or. (.not. f_is_default(patch_ib(patch_id)%length_z)) .or. (.not. f_is_default(patch_ib(patch_id)%radius)), & - & 'in inactive IB patch ' // trim(iStr)) + @:PROHIBIT((.not. f_is_default(patch_ib(patch_id)%x_centroid)) & + .or. & + (.not. f_is_default(patch_ib(patch_id)%y_centroid)) & + .or. & + (.not. f_is_default(patch_ib(patch_id)%z_centroid)) & + .or. & + (.not. f_is_default(patch_ib(patch_id)%length_x)) & + .or. & + (.not. f_is_default(patch_ib(patch_id)%length_y)) & + .or. & + (.not. f_is_default(patch_ib(patch_id)%length_z)) & + .or. & + (.not. f_is_default(patch_ib(patch_id)%radius)), & + 'in inactive IB patch '//trim(iStr)) end subroutine s_check_inactive_ib_patch_geometry diff --git a/src/pre_process/m_check_patches.fpp b/src/pre_process/m_check_patches.fpp index adcb233f97..6725faba75 100644 --- a/src/pre_process/m_check_patches.fpp +++ b/src/pre_process/m_check_patches.fpp @@ -11,16 +11,23 @@ module m_check_patches ! Dependencies - use m_derived_types - use m_global_parameters - use m_mpi_proxy - use m_data_output + use m_derived_types !< Definitions of the derived types + + use m_global_parameters !< Global parameters for the code + + use m_mpi_proxy !< Message passing interface (MPI) module proxy + + use m_data_output !< Procedures to write the grid data and the + !! conservative variables to files + #ifdef MFC_MPI - use mpi !< Message passing interface (MPI) module + use mpi !< Message passing interface (MPI) module #endif use m_compile_specific - use m_helper_basic + + use m_helper_basic !< Functions to compare floating point numbers + use m_helper implicit none @@ -31,64 +38,64 @@ module m_check_patches contains - !> Validate the geometry parameters of all active and inactive initial condition patches. + !> @brief Validates the geometry parameters of all active and inactive initial condition patches. impure subroutine s_check_patches - integer :: i + integer :: i character(len=10) :: num_patches_str call s_int_to_str(num_patches, num_patches_str) do i = 1, num_patches_max if (i <= num_patches) then + ! call s_check_patch_geometry(i) call s_int_to_str(i, iStr) - @:PROHIBIT(patch_icpp(i)%geometry == 6, & - & "Invalid patch geometry number. " // "patch_icpp(" // trim(iStr) // ")%geometry is deprecated.") - @:PROHIBIT(patch_icpp(i)%geometry == 7, & - & "Invalid patch geometry number. " // "patch_icpp(" // trim(iStr) // ")%geometry is deprecated.") - @:PROHIBIT(patch_icpp(i)%geometry == 15, & - & "Invalid patch geometry number. " // "patch_icpp(" // trim(iStr) // ")%geometry is deprecated.") - @:PROHIBIT(patch_icpp(i)%geometry == dflt_int, & - & "Invalid patch geometry number. " // "patch_icpp(" // trim(iStr) // ")%geometry must be set.") + @:PROHIBIT(patch_icpp(i)%geometry == 6, "Invalid patch geometry number. "// & + "patch_icpp("//trim(iStr)//")%geometry is deprecated.") + @:PROHIBIT(patch_icpp(i)%geometry == 7, "Invalid patch geometry number. "// & + "patch_icpp("//trim(iStr)//")%geometry is deprecated.") + @:PROHIBIT(patch_icpp(i)%geometry == 15, "Invalid patch geometry number. "// & + "patch_icpp("//trim(iStr)//")%geometry is deprecated.") + @:PROHIBIT(patch_icpp(i)%geometry == dflt_int, "Invalid patch geometry number. "// & + "patch_icpp("//trim(iStr)//")%geometry must be set.") ! Constraints on the geometric initial condition patch parameters if (patch_icpp(i)%geometry == 1) then call s_check_line_segment_patch_geometry(i) - else if (patch_icpp(i)%geometry == 2) then + elseif (patch_icpp(i)%geometry == 2) then call s_check_circle_patch_geometry(i) - else if (patch_icpp(i)%geometry == 3) then + elseif (patch_icpp(i)%geometry == 3) then call s_check_rectangle_patch_geometry(i) - else if (patch_icpp(i)%geometry == 4) then + elseif (patch_icpp(i)%geometry == 4) then call s_check_line_sweep_patch_geometry(i) - else if (patch_icpp(i)%geometry == 5) then + elseif (patch_icpp(i)%geometry == 5) then call s_check_ellipse_patch_geometry(i) - else if (patch_icpp(i)%geometry == 8) then + elseif (patch_icpp(i)%geometry == 8) then call s_check_sphere_patch_geometry(i) - else if (patch_icpp(i)%geometry == 9) then + elseif (patch_icpp(i)%geometry == 9) then call s_check_cuboid_patch_geometry(i) - else if (patch_icpp(i)%geometry == 10) then + elseif (patch_icpp(i)%geometry == 10) then call s_check_cylinder_patch_geometry(i) - else if (patch_icpp(i)%geometry == 11) then + elseif (patch_icpp(i)%geometry == 11) then call s_check_plane_sweep_patch_geometry(i) - else if (patch_icpp(i)%geometry == 12) then + elseif (patch_icpp(i)%geometry == 12) then call s_check_ellipsoid_patch_geometry(i) - else if (patch_icpp(i)%geometry == 13) then + elseif (patch_icpp(i)%geometry == 13) then call s_check_2d_modal_patch_geometry(i) - else if (patch_icpp(i)%geometry == 14) then + elseif (patch_icpp(i)%geometry == 14) then call s_check_3d_spherical_harmonic_patch_geometry(i) - else if (patch_icpp(i)%geometry == 20) then + elseif (patch_icpp(i)%geometry == 20) then call s_check_2D_TaylorGreen_vortex_patch_geometry(i) - else if (patch_icpp(i)%geometry == 21) then + elseif (patch_icpp(i)%geometry == 21) then call s_check_model_geometry(i) else - call s_prohibit_abort("Invalid patch geometry number", & - & "patch_icpp(" // trim(iStr) // ")%geometry " // "must be between 1 and 21") + call s_prohibit_abort("Invalid patch geometry number", "patch_icpp("//trim(iStr)//")%geometry "// & + "must be between 1 and 21") end if else - @:PROHIBIT(patch_icpp(i)%geometry /= dflt_int, & - & "Inactive patch defined. " // "patch_icpp(" // trim(iStr) & - & // ")%geometry not be set for inactive patches. " // "Patch " // trim(iStr) & - & // " is inactive as the number of patches is " // trim(num_patches_str)) + @:PROHIBIT(patch_icpp(i)%geometry /= dflt_int, "Inactive patch defined. "// & + "patch_icpp("//trim(iStr)//")%geometry not be set for inactive patches. "// & + "Patch "//trim(iStr)//" is inactive as the number of patches is "//trim(num_patches_str)) call s_check_inactive_patch_geometry(i) end if end do @@ -104,10 +111,17 @@ contains ! Constraints on smoothing initial condition patch parameters do i = 1, num_patches - if (i > 1 .and. (patch_icpp(i)%geometry == 2 .or. patch_icpp(i)%geometry == 3 .or. patch_icpp(i) & - & %geometry == 4 .or. patch_icpp(i)%geometry == 5 .or. patch_icpp(i)%geometry == 8 .or. patch_icpp(i) & - & %geometry == 9 .or. patch_icpp(i)%geometry == 10 .or. patch_icpp(i)%geometry == 11 .or. patch_icpp(i) & - & %geometry == 12 .or. patch_icpp(i)%geometry == 13 .or. patch_icpp(i)%geometry == 14)) then + if (i > 1 .and. (patch_icpp(i)%geometry == 2 .or. & + patch_icpp(i)%geometry == 3 .or. & + patch_icpp(i)%geometry == 4 .or. & + patch_icpp(i)%geometry == 5 .or. & + patch_icpp(i)%geometry == 8 .or. & + patch_icpp(i)%geometry == 9 .or. & + patch_icpp(i)%geometry == 10 .or. & + patch_icpp(i)%geometry == 11 .or. & + patch_icpp(i)%geometry == 12 .or. & + patch_icpp(i)%geometry == 13 .or. & + patch_icpp(i)%geometry == 14)) then call s_check_supported_patch_smoothing(i) else call s_check_unsupported_patch_smoothing(i) @@ -125,26 +139,25 @@ contains end subroutine s_check_patches - !> Check the line segment patch input + !> This subroutine checks the line segment patch input + !! @param patch_id Patch identifier impure subroutine s_check_line_segment_patch_geometry(patch_id) integer, intent(in) :: patch_id - call s_int_to_str(patch_id, iStr) @:PROHIBIT(n > 0, "Line segment patch "//trim(iStr)//": n must be zero") - @:PROHIBIT(patch_icpp(patch_id)%length_x <= 0._wp, & - & "Line segment patch " // trim(iStr) // ": length_x must be greater than zero") + @:PROHIBIT(patch_icpp(patch_id)%length_x <= 0._wp, "Line segment patch "//trim(iStr)//": length_x must be greater than zero") @:PROHIBIT(f_is_default(patch_icpp(patch_id)%x_centroid), "Line segment patch "//trim(iStr)//": x_centroid must be set") @:PROHIBIT(cyl_coord, "Line segment patch "//trim(iStr)//": cyl_coord is not supported") end subroutine s_check_line_segment_patch_geometry - !> Check the circle patch input + !> This subroutine checks the circle patch input + !! @param patch_id Patch identifier impure subroutine s_check_circle_patch_geometry(patch_id) integer, intent(in) :: patch_id - call s_int_to_str(patch_id, iStr) @:PROHIBIT(n == 0, "Circle patch "//trim(iStr)//": n must be zero") @@ -155,11 +168,11 @@ contains end subroutine s_check_circle_patch_geometry - !> Check the rectangle patch input + !> This subroutine checks the rectangle patch input + !! @param patch_id Patch identifier impure subroutine s_check_rectangle_patch_geometry(patch_id) integer, intent(in) :: patch_id - call s_int_to_str(patch_id, iStr) @:PROHIBIT(n == 0, "Rectangle patch "//trim(iStr)//": n must be greater than zero") @@ -171,11 +184,11 @@ contains end subroutine s_check_rectangle_patch_geometry - !> Check the line sweep patch input + !> This subroutine checks the line sweep patch input + !! @param patch_id Patch identifier impure subroutine s_check_line_sweep_patch_geometry(patch_id) integer, intent(in) :: patch_id - call s_int_to_str(patch_id, iStr) @:PROHIBIT(n == 0, "Line sweep patch "//trim(iStr)//": n must be greater than zero") @@ -184,16 +197,15 @@ contains @:PROHIBIT(f_is_default(patch_icpp(patch_id)%y_centroid), "Line sweep patch "//trim(iStr)//": y_centroid must be set") @:PROHIBIT(f_is_default(patch_icpp(patch_id)%normal(1)), "Line sweep patch "//trim(iStr)//": normal(1) must be set") @:PROHIBIT(f_is_default(patch_icpp(patch_id)%normal(2)), "Line sweep patch "//trim(iStr)//": normal(2) must be set") - @:PROHIBIT(.not. f_is_default(patch_icpp(patch_id)%normal(3)), & - & "Line sweep patch " // trim(iStr) // ": normal(3) must not be set") + @:PROHIBIT(.not. f_is_default(patch_icpp(patch_id)%normal(3)), "Line sweep patch "//trim(iStr)//": normal(3) must not be set") end subroutine s_check_line_sweep_patch_geometry - !> Check the ellipse patch input + !> This subroutine checks the ellipse patch input + !! @param patch_id Patch identifier impure subroutine s_check_ellipse_patch_geometry(patch_id) integer, intent(in) :: patch_id - call s_int_to_str(patch_id, iStr) @:PROHIBIT(n == 0, "Ellipse patch "//trim(iStr)//": n must be greater than zero") @@ -206,33 +218,28 @@ contains end subroutine s_check_ellipse_patch_geometry - !> Check the model patch input + !> This subroutine checks the model patch input + !! @param patch_id Patch identifier impure subroutine s_check_2D_TaylorGreen_vortex_patch_geometry(patch_id) integer, intent(in) :: patch_id - call s_int_to_str(patch_id, iStr) @:PROHIBIT(n == 0, "Taylor Green vortex patch "//trim(iStr)//": n must be greater than zero") @:PROHIBIT(p > 0, "Taylor Green vortex patch "//trim(iStr)//": p must be zero") - @:PROHIBIT(f_is_default(patch_icpp(patch_id)%x_centroid), & - & "Taylor Green vortex patch " // trim(iStr) // ": x_centroid must be set") - @:PROHIBIT(f_is_default(patch_icpp(patch_id)%y_centroid), & - & "Taylor Green vortex patch " // trim(iStr) // ": y_centroid must be set") - @:PROHIBIT(patch_icpp(patch_id)%length_x <= 0._wp, & - & "Taylor Green vortex patch " // trim(iStr) // ": length_x must be greater than zero") - @:PROHIBIT(patch_icpp(patch_id)%length_y <= 0._wp, & - & "Taylor Green vortex patch " // trim(iStr) // ": length_y must be greater than zero") - @:PROHIBIT(patch_icpp(patch_id)%vel(2) <= 0._wp, & - & "Taylor Green vortex patch " // trim(iStr) // ": vel(2) must be greater than zero") + @:PROHIBIT(f_is_default(patch_icpp(patch_id)%x_centroid), "Taylor Green vortex patch "//trim(iStr)//": x_centroid must be set") + @:PROHIBIT(f_is_default(patch_icpp(patch_id)%y_centroid), "Taylor Green vortex patch "//trim(iStr)//": y_centroid must be set") + @:PROHIBIT(patch_icpp(patch_id)%length_x <= 0._wp, "Taylor Green vortex patch "//trim(iStr)//": length_x must be greater than zero") + @:PROHIBIT(patch_icpp(patch_id)%length_y <= 0._wp, "Taylor Green vortex patch "//trim(iStr)//": length_y must be greater than zero") + @:PROHIBIT(patch_icpp(patch_id)%vel(2) <= 0._wp, "Taylor Green vortex patch "//trim(iStr)//": vel(2) must be greater than zero") end subroutine s_check_2D_TaylorGreen_vortex_patch_geometry - !> Check the model patch input + !> This subroutine checks the model patch input + !! @param patch_id Patch identifier impure subroutine s_check_sphere_patch_geometry(patch_id) integer, intent(in) :: patch_id - call s_int_to_str(patch_id, iStr) @:PROHIBIT(p == 0, "Sphere patch "//trim(iStr)//": p must be greater than zero") @@ -243,9 +250,7 @@ contains end subroutine s_check_sphere_patch_geometry - !> Validate geometry parameters for a 2D modal (Fourier) patch impure subroutine s_check_2d_modal_patch_geometry(patch_id) - integer, intent(in) :: patch_id call s_int_to_str(patch_id, iStr) @@ -258,31 +263,25 @@ contains end subroutine s_check_2d_modal_patch_geometry - !> Validate geometry parameters for a 3D spherical harmonic patch impure subroutine s_check_3d_spherical_harmonic_patch_geometry(patch_id) - integer, intent(in) :: patch_id call s_int_to_str(patch_id, iStr) @:PROHIBIT(p == 0, "Spherical harmonic patch "//trim(iStr)//": p must be greater than zero") - @:PROHIBIT(patch_icpp(patch_id)%radius <= 0._wp, & - & "Spherical harmonic patch " // trim(iStr) // ": radius must be greater than zero") - @:PROHIBIT(f_is_default(patch_icpp(patch_id)%x_centroid), & - & "Spherical harmonic patch " // trim(iStr) // ": x_centroid must be set") - @:PROHIBIT(f_is_default(patch_icpp(patch_id)%y_centroid), & - & "Spherical harmonic patch " // trim(iStr) // ": y_centroid must be set") - @:PROHIBIT(f_is_default(patch_icpp(patch_id)%z_centroid), & - & "Spherical harmonic patch " // trim(iStr) // ": z_centroid must be set") + @:PROHIBIT(patch_icpp(patch_id)%radius <= 0._wp, "Spherical harmonic patch "//trim(iStr)//": radius must be greater than zero") + @:PROHIBIT(f_is_default(patch_icpp(patch_id)%x_centroid), "Spherical harmonic patch "//trim(iStr)//": x_centroid must be set") + @:PROHIBIT(f_is_default(patch_icpp(patch_id)%y_centroid), "Spherical harmonic patch "//trim(iStr)//": y_centroid must be set") + @:PROHIBIT(f_is_default(patch_icpp(patch_id)%z_centroid), "Spherical harmonic patch "//trim(iStr)//": z_centroid must be set") end subroutine s_check_3d_spherical_harmonic_patch_geometry - !> Check the model patch input + !> This subroutine checks the model patch input + !! @param patch_id Patch identifier impure subroutine s_check_cuboid_patch_geometry(patch_id) ! Patch identifier integer, intent(in) :: patch_id - call s_int_to_str(patch_id, iStr) @:PROHIBIT(p == 0, "Cuboid patch "//trim(iStr)//": p must be greater than zero") @@ -295,12 +294,12 @@ contains end subroutine s_check_cuboid_patch_geometry - !> Check the model patch input + !> This subroutine checks the model patch input + !! @param patch_id Patch identifier impure subroutine s_check_cylinder_patch_geometry(patch_id) ! Patch identifier integer, intent(in) :: patch_id - call s_int_to_str(patch_id, iStr) @:PROHIBIT(p == 0, "Cylinder patch "//trim(iStr)//": p must be greater than zero") @@ -310,25 +309,27 @@ contains @:PROHIBIT(patch_icpp(patch_id)%radius <= 0._wp, "Cylinder patch "//trim(iStr)//": radius must be greater than zero") ! Check if exactly one length is defined - @:PROHIBIT(count([patch_icpp(patch_id)%length_x > 0._wp, patch_icpp(patch_id)%length_y > 0._wp, & - & patch_icpp(patch_id)%length_z > 0._wp]) /= 1, & - & "Cylinder patch " // trim(iStr) & - & // ": Exactly one of length_x, length_y, or length_z must be defined and positive") + @:PROHIBIT(count([ & + patch_icpp(patch_id)%length_x > 0._wp, & + patch_icpp(patch_id)%length_y > 0._wp, & + patch_icpp(patch_id)%length_z > 0._wp & + ]) /= 1, "Cylinder patch "//trim(iStr)//": Exactly one of length_x, length_y, or length_z must be defined and positive") ! Ensure the defined length is positive - @:PROHIBIT((.not. f_is_default(patch_icpp(patch_id)%length_x) .and. patch_icpp(patch_id)%length_x <= 0._wp) & - & .or. (.not. f_is_default(patch_icpp(patch_id)%length_y) .and. patch_icpp(patch_id)%length_y <= 0._wp) & - & .or. (.not. f_is_default(patch_icpp(patch_id)%length_z) .and. patch_icpp(patch_id)%length_z <= 0._wp), & - & "Cylinder patch " // trim(iStr) // ": The defined length_{} must be greater than zero") + @:PROHIBIT( & + (.not. f_is_default(patch_icpp(patch_id)%length_x) .and. patch_icpp(patch_id)%length_x <= 0._wp) .or. & + (.not. f_is_default(patch_icpp(patch_id)%length_y) .and. patch_icpp(patch_id)%length_y <= 0._wp) .or. & + (.not. f_is_default(patch_icpp(patch_id)%length_z) .and. patch_icpp(patch_id)%length_z <= 0._wp), & + "Cylinder patch "//trim(iStr)//": The defined length_{} must be greater than zero") end subroutine s_check_cylinder_patch_geometry - !> Check the model patch input + !> This subroutine checks the model patch input + !! @param patch_id Patch identifier impure subroutine s_check_plane_sweep_patch_geometry(patch_id) ! Patch identifier integer, intent(in) :: patch_id - call s_int_to_str(patch_id, iStr) @:PROHIBIT(p == 0, "Plane sweep patch "//trim(iStr)//": p must be greater than zero") @@ -341,11 +342,11 @@ contains end subroutine s_check_plane_sweep_patch_geometry - !> Check the model patch input + !> This subroutine checks the model patch input + !! @param patch_id Patch identifier impure subroutine s_check_ellipsoid_patch_geometry(patch_id) integer, intent(in) :: patch_id - call s_int_to_str(patch_id, iStr) @:PROHIBIT(p == 0, "Ellipsoid patch "//trim(iStr)//": p must be greater than zero") @@ -358,19 +359,17 @@ contains end subroutine s_check_ellipsoid_patch_geometry - !> Verify that inactive patch geometry parameters remain at defaults + !!> This subroutine verifies that the geometric parameters of + !! the inactive patch remain unaltered by the user inputs. + !! @param patch_id Patch identifier impure subroutine s_check_inactive_patch_geometry(patch_id) integer, intent(in) :: patch_id - call s_int_to_str(patch_id, iStr) - @:PROHIBIT(.not. f_is_default(patch_icpp(patch_id)%x_centroid), & - & "Inactive patch " // trim(iStr) // ": x_centroid must not be set") - @:PROHIBIT(.not. f_is_default(patch_icpp(patch_id)%y_centroid), & - & "Inactive patch " // trim(iStr) // ": y_centroid must not be set") - @:PROHIBIT(.not. f_is_default(patch_icpp(patch_id)%z_centroid), & - & "Inactive patch " // trim(iStr) // ": z_centroid must not be set") + @:PROHIBIT(.not. f_is_default(patch_icpp(patch_id)%x_centroid), "Inactive patch "//trim(iStr)//": x_centroid must not be set") + @:PROHIBIT(.not. f_is_default(patch_icpp(patch_id)%y_centroid), "Inactive patch "//trim(iStr)//": y_centroid must not be set") + @:PROHIBIT(.not. f_is_default(patch_icpp(patch_id)%z_centroid), "Inactive patch "//trim(iStr)//": z_centroid must not be set") @:PROHIBIT(.not. f_is_default(patch_icpp(patch_id)%length_x), "Inactive patch "//trim(iStr)//": length_x must not be set") @:PROHIBIT(.not. f_is_default(patch_icpp(patch_id)%length_y), "Inactive patch "//trim(iStr)//": length_y must not be set") @:PROHIBIT(.not. f_is_default(patch_icpp(patch_id)%length_z), "Inactive patch "//trim(iStr)//": length_z must not be set") @@ -386,154 +385,168 @@ contains end subroutine s_check_inactive_patch_geometry - !> Verify the active patch's right to overwrite the preceding patches + !> This subroutine verifies the active patch's right to overwrite the preceding patches + !! @param patch_id Patch identifier impure subroutine s_check_active_patch_alteration_rights(patch_id) integer, intent(in) :: patch_id - call s_int_to_str(patch_id, iStr) @:PROHIBIT(.not. patch_icpp(patch_id)%alter_patch(0), "Patch "//trim(iStr)//": alter_patch(0) must be true") - @:PROHIBIT(any(patch_icpp(patch_id)%alter_patch(patch_id:)), & - & "Patch " // trim(iStr) // ":alter_patch(i) must be false for i >= " // trim(iStr) & - & // ". Only preceding patches can be altered") + @:PROHIBIT(any(patch_icpp(patch_id)%alter_patch(patch_id:)), "Patch "//trim(iStr)// & + ":alter_patch(i) must be false for i >= "//trim(iStr)//". Only preceding patches can be altered") end subroutine s_check_active_patch_alteration_rights - !> Verify that inactive patches cannot overwrite other patches + !> This subroutine verifies that inactive patches cannot overwrite other patches + !! @param patch_id Patch identifier impure subroutine s_check_inactive_patch_alteration_rights(patch_id) ! Patch identifier integer, intent(in) :: patch_id - call s_int_to_str(patch_id, iStr) @:PROHIBIT(.not. patch_icpp(patch_id)%alter_patch(0), "Inactive patch "//trim(iStr)//": cannot have alter_patch(0) altered") - @:PROHIBIT(any(patch_icpp(patch_id)%alter_patch(1:)), & - & "Inactive patch " // trim(iStr) // ": cannot have any alter_patch(i) enabled") + @:PROHIBIT(any(patch_icpp(patch_id)%alter_patch(1:)), "Inactive patch "//trim(iStr)//": cannot have any alter_patch(i) enabled") end subroutine s_check_inactive_patch_alteration_rights - !> Check the smoothing parameters + !> This subroutine checks the smoothing parameters + !! @param patch_id Patch identifier impure subroutine s_check_supported_patch_smoothing(patch_id) integer, intent(in) :: patch_id - call s_int_to_str(patch_id, iStr) if (patch_icpp(patch_id)%smoothen) then @:PROHIBIT(patch_icpp(patch_id)%smooth_patch_id >= patch_id, & - & "Smoothen enabled. Patch " // trim(iStr) // ": smooth_patch_id must be less than patch_id") + "Smoothen enabled. Patch "//trim(iStr)//": smooth_patch_id must be less than patch_id") @:PROHIBIT(patch_icpp(patch_id)%smooth_patch_id == 0, & - & "Smoothen enabled. Patch " // trim(iStr) // ": smooth_patch_id must be greater than zero") + "Smoothen enabled. Patch "//trim(iStr)//": smooth_patch_id must be greater than zero") @:PROHIBIT(patch_icpp(patch_id)%smooth_coeff <= 0._wp, & - & "Smoothen enabled. Patch " // trim(iStr) // ": smooth_coeff must be greater than zero") + "Smoothen enabled. Patch "//trim(iStr)//": smooth_coeff must be greater than zero") else @:PROHIBIT(patch_icpp(patch_id)%smooth_patch_id /= patch_id, & - & "Smoothen disabled. Patch " // trim(iStr) // ": smooth_patch_id must be equal to patch_id") + "Smoothen disabled. Patch "//trim(iStr)//": smooth_patch_id must be equal to patch_id") @:PROHIBIT(.not. f_is_default(patch_icpp(patch_id)%smooth_coeff), & - & "Smoothen disabled. Patch " // trim(iStr) // ": smooth_coeff must not be set") + "Smoothen disabled. Patch "//trim(iStr)//": smooth_coeff must not be set") end if end subroutine s_check_supported_patch_smoothing - !> Verify that inactive patches cannot be smoothed + !> This subroutine verifies that inactive patches cannot be smoothed + !! @param patch_id Patch identifier impure subroutine s_check_unsupported_patch_smoothing(patch_id) ! Patch identifier integer, intent(in) :: patch_id - call s_int_to_str(patch_id, iStr) - @:PROHIBIT(patch_icpp(patch_id)%smoothen, "Inactive patch "//trim(iStr)//": cannot have smoothen enabled") + @:PROHIBIT(patch_icpp(patch_id)%smoothen, & + "Inactive patch "//trim(iStr)//": cannot have smoothen enabled") @:PROHIBIT(patch_icpp(patch_id)%smooth_patch_id /= patch_id, & - & "Inactive patch " // trim(iStr) // ": smooth_patch_id must be equal to patch_id") + "Inactive patch "//trim(iStr)//": smooth_patch_id must be equal to patch_id") @:PROHIBIT(.not. f_is_default(patch_icpp(patch_id)%smooth_coeff), & - & "Inactive patch " // trim(iStr) // ": smooth_coeff must not be set") + "Inactive patch "//trim(iStr)//": smooth_coeff must not be set") end subroutine s_check_unsupported_patch_smoothing - !> Check the primitive variables + !> This subroutine checks the primitive variables + !! @param patch_id Patch identifier impure subroutine s_check_active_patch_primitive_variables(patch_id) - integer, intent(in) :: patch_id + integer, intent(in) :: patch_id + logical, dimension(3) :: is_set_B call s_int_to_str(patch_id, iStr) - @:PROHIBIT(f_is_default(patch_icpp(patch_id)%vel(1)), "Patch "//trim(iStr)//": vel(1) must be set") - @:PROHIBIT(n == 0 .and. (.not. f_is_default(patch_icpp(patch_id)%vel(2))) .and. (.not. f_approx_equal(patch_icpp(patch_id) & - & %vel(2), 0._wp)) .and. (.not. mhd), "Patch " // trim(iStr) // ": vel(2) must not be set when n = 0") - @:PROHIBIT(n > 0 .and. f_is_default(patch_icpp(patch_id)%vel(2)), "Patch "//trim(iStr)//": vel(2) must be set when n > 0") - @:PROHIBIT(p == 0 .and. (.not. f_is_default(patch_icpp(patch_id)%vel(3))) .and. (.not. f_approx_equal(patch_icpp(patch_id) & - & %vel(3), 0._wp)) .and. (.not. mhd), "Patch " // trim(iStr) // ": vel(3) must not be set when p = 0") - @:PROHIBIT(p > 0 .and. f_is_default(patch_icpp(patch_id)%vel(3)), "Patch "//trim(iStr)//": vel(3) must be set when p > 0") + @:PROHIBIT(f_is_default(patch_icpp(patch_id)%vel(1)), & + "Patch "//trim(iStr)//": vel(1) must be set") + @:PROHIBIT(n == 0 .and. (.not. f_is_default(patch_icpp(patch_id)%vel(2))) .and. (.not. f_approx_equal(patch_icpp(patch_id)%vel(2) , 0._wp)) .and. (.not. mhd), & + "Patch "//trim(iStr)//": vel(2) must not be set when n = 0") + @:PROHIBIT(n > 0 .and. f_is_default(patch_icpp(patch_id)%vel(2)), & + "Patch "//trim(iStr)//": vel(2) must be set when n > 0") + @:PROHIBIT(p == 0 .and. (.not. f_is_default(patch_icpp(patch_id)%vel(3))) .and. (.not. f_approx_equal(patch_icpp(patch_id)%vel(3) , 0._wp)) .and. (.not. mhd), & + "Patch "//trim(iStr)//": vel(3) must not be set when p = 0") + @:PROHIBIT(p > 0 .and. f_is_default(patch_icpp(patch_id)%vel(3)), & + "Patch "//trim(iStr)//": vel(3) must be set when p > 0") @:PROHIBIT(mhd .and. (f_is_default(patch_icpp(patch_id)%vel(2)) .or. f_is_default(patch_icpp(patch_id)%vel(3))), & - & "Patch " // trim(iStr) // ": All velocities (vel(1:3)) must be set when mhd = true") + "Patch "//trim(iStr)//": All velocities (vel(1:3)) must be set when mhd = true") @:PROHIBIT(model_eqns == 1 .and. patch_icpp(patch_id)%rho <= 0._wp, & - & "Patch " // trim(iStr) // ": rho must be greater than zero when model_eqns = 1") + "Patch "//trim(iStr)//": rho must be greater than zero when model_eqns = 1") @:PROHIBIT(model_eqns == 1 .and. patch_icpp(patch_id)%gamma <= 0._wp, & - & "Patch " // trim(iStr) // ": gamma must be greater than zero when model_eqns = 1") + "Patch "//trim(iStr)//": gamma must be greater than zero when model_eqns = 1") @:PROHIBIT(model_eqns == 1 .and. patch_icpp(patch_id)%pi_inf < 0._wp, & - & "Patch " // trim(iStr) // ": pi_inf must be greater than or equal to zero when model_eqns = 1") + "Patch "//trim(iStr)//": pi_inf must be greater than or equal to zero when model_eqns = 1") @:PROHIBIT(patch_icpp(patch_id)%geometry == 5 .and. patch_icpp(patch_id)%pi_inf > 0, & - & "Patch " // trim(iStr) // ": pi_inf must be less than or equal to zero when geometry = 5") + "Patch "//trim(iStr)//": pi_inf must be less than or equal to zero when geometry = 5") @:PROHIBIT(model_eqns == 2 .and. any(patch_icpp(patch_id)%alpha_rho(1:num_fluids) < 0._wp), & - & "Patch " // trim(iStr) & - & // ": alpha_rho(1:num_fluids) must be greater than or equal to zero when model_eqns = 2") + "Patch "//trim(iStr)//": alpha_rho(1:num_fluids) must be greater than or equal to zero when model_eqns = 2") is_set_B(1) = .not. f_is_default(patch_icpp(patch_id)%Bx) is_set_B(2) = .not. f_is_default(patch_icpp(patch_id)%By) is_set_B(3) = .not. f_is_default(patch_icpp(patch_id)%Bz) - @:PROHIBIT(.not. mhd .and. any(is_set_B), "Bx, By, and Bz must not be set if MHD is not enabled") + @:PROHIBIT(.not. mhd .and. any(is_set_B), & + "Bx, By, and Bz must not be set if MHD is not enabled") @:PROHIBIT(mhd .and. n == 0 .and. is_set_B(1), "Bx must not be set in 1D MHD simulations") @:PROHIBIT(mhd .and. n > 0 .and. .not. is_set_B(1), "Bx must be set in 2D/3D MHD simulations") @:PROHIBIT(mhd .and. .not. (is_set_B(2) .and. is_set_B(3)), "By and Bz must be set in all MHD simulations") if (model_eqns == 2 .and. num_fluids < num_fluids_max) then @:PROHIBIT(.not. f_all_default(patch_icpp(patch_id)%alpha_rho(num_fluids + 1:)), & - & "Patch " // trim(iStr) // ": alpha_rho(i) must not be set for i > num_fluids") + "Patch "//trim(iStr)//": alpha_rho(i) must not be set for i > num_fluids") @:PROHIBIT(.not. f_all_default(patch_icpp(patch_id)%alpha(num_fluids + 1:)), & - & "Patch " // trim(iStr) // ": alpha(i) must not be set for i > num_fluids") + "Patch "//trim(iStr)//": alpha(i) must not be set for i > num_fluids") @:PROHIBIT(f_is_default(patch_icpp(patch_id)%alpha(num_fluids)), & - & "Patch " // trim(iStr) // ": alpha(num_fluids) must be set") + "Patch "//trim(iStr)//": alpha(num_fluids) must be set") end if if (chemistry) then + !@:ASSERT(all(patch_icpp(patch_id)%Y(1:num_species) >= 0._wp), "Patch " // trim(iStr) // ".") + !@:ASSERT(any(patch_icpp(patch_id)%Y(1:num_species) > verysmall), "Patch " // trim(iStr) // ".") end if end subroutine s_check_active_patch_primitive_variables - !> Verify that the primitive variables associated with the given inactive patch remain unaltered by the user inputs. + !> This subroutine verifies that the primitive variables + !! associated with the given inactive patch remain unaltered + !! by the user inputs. + !! @param patch_id Patch identifier impure subroutine s_check_inactive_patch_primitive_variables(patch_id) integer, intent(in) :: patch_id - call s_int_to_str(patch_id, iStr) @:PROHIBIT(.not. f_all_default(patch_icpp(patch_id)%alpha_rho), & - & "Inactive patch " // trim(iStr) // ": alpha_rho must not be set") - @:PROHIBIT(.not. f_is_default(patch_icpp(patch_id)%rho), "Inactive patch "//trim(iStr)//": rho must not be set") - @:PROHIBIT(.not. f_all_default(patch_icpp(patch_id)%vel), "Inactive patch "//trim(iStr)//": vel must not be set") - @:PROHIBIT(.not. f_is_default(patch_icpp(patch_id)%pres), "Inactive patch "//trim(iStr)//": pres must not be set") - @:PROHIBIT(.not. f_all_default(patch_icpp(patch_id)%alpha), "Inactive patch "//trim(iStr)//": alpha must not be set") - @:PROHIBIT(.not. f_is_default(patch_icpp(patch_id)%gamma), "Inactive patch "//trim(iStr)//": gamma must not be set") - @:PROHIBIT(.not. f_is_default(patch_icpp(patch_id)%pi_inf), "Inactive patch "//trim(iStr)//": pi_inf must not be set") + "Inactive patch "//trim(iStr)//": alpha_rho must not be set") + @:PROHIBIT(.not. f_is_default(patch_icpp(patch_id)%rho), & + "Inactive patch "//trim(iStr)//": rho must not be set") + @:PROHIBIT(.not. f_all_default(patch_icpp(patch_id)%vel), & + "Inactive patch "//trim(iStr)//": vel must not be set") + @:PROHIBIT(.not. f_is_default(patch_icpp(patch_id)%pres), & + "Inactive patch "//trim(iStr)//": pres must not be set") + @:PROHIBIT(.not. f_all_default(patch_icpp(patch_id)%alpha), & + "Inactive patch "//trim(iStr)//": alpha must not be set") + @:PROHIBIT(.not. f_is_default(patch_icpp(patch_id)%gamma), & + "Inactive patch "//trim(iStr)//": gamma must not be set") + @:PROHIBIT(.not. f_is_default(patch_icpp(patch_id)%pi_inf), & + "Inactive patch "//trim(iStr)//": pi_inf must not be set") end subroutine s_check_inactive_patch_primitive_variables - !> Verify that the model file referenced by the given patch exists on disk. + !> @brief Verifies that the model file referenced by the given patch exists on disk. impure subroutine s_check_model_geometry(patch_id) integer, intent(in) :: patch_id - logical :: file_exists + + logical :: file_exists inquire (file=patch_icpp(patch_id)%model_filepath, exist=file_exists) - @:PROHIBIT(.not. file_exists, & - & "Model file " // trim(patch_icpp(patch_id)%model_filepath) // " requested by patch " // trim(iStr) & - & // " does not exist") + @:PROHIBIT(.not. file_exists, "Model file "//trim(patch_icpp(patch_id)%model_filepath)// & + " requested by patch "//trim(iStr)//" does not exist") end subroutine s_check_model_geometry diff --git a/src/pre_process/m_checker.fpp b/src/pre_process/m_checker.fpp index bd6ca48ee0..63ed19199b 100644 --- a/src/pre_process/m_checker.fpp +++ b/src/pre_process/m_checker.fpp @@ -7,9 +7,12 @@ !> @brief Checks pre-process input file parameters for compatibility and correctness module m_checker - use m_global_parameters - use m_mpi_proxy - use m_helper_basic + use m_global_parameters !< Definitions of the global parameters + + use m_mpi_proxy !< Message passing interface (MPI) module proxy + + use m_helper_basic !< Functions to compare floating point numbers + use m_helper implicit none @@ -18,9 +21,9 @@ module m_checker contains - !> Checks compatibility of parameters in the input file. Used by the pre_process stage + !> Checks compatibility of parameters in the input file. + !! Used by the pre_process stage impure subroutine s_check_inputs - end subroutine s_check_inputs end module m_checker diff --git a/src/pre_process/m_data_output.fpp b/src/pre_process/m_data_output.fpp index ab3257a77b..5dbc84ade8 100644 --- a/src/pre_process/m_data_output.fpp +++ b/src/pre_process/m_data_output.fpp @@ -5,70 +5,116 @@ !> @brief Writes grid and initial condition data to serial or parallel output files module m_data_output - use m_derived_types - use m_global_parameters + use m_derived_types !< Definitions of the derived types + + use m_global_parameters !< Global parameters for the code + use m_helper - use m_mpi_proxy + + use m_mpi_proxy !< Message passing interface (MPI) module proxy + #ifdef MFC_MPI - use mpi + use mpi !< Message passing interface (MPI) module #endif use m_compile_specific + use m_variables_conversion + use m_helper + use m_delay_file_access + use m_boundary_common + use m_boundary_conditions + use m_thermochem, only: species_names + use m_helper implicit none - private - public :: s_write_serial_data_files, s_write_parallel_data_files, s_write_data_files, s_initialize_data_output_module, & - & s_finalize_data_output_module + private; + public :: s_write_serial_data_files, & + s_write_parallel_data_files, & + s_write_data_files, & + s_initialize_data_output_module, & + s_finalize_data_output_module type(scalar_field), allocatable, dimension(:) :: q_cons_temp abstract interface - !> Interface for the conservative data + !> Interface for the conservative data + !! @param q_cons_vf Conservative variables impure subroutine s_write_abstract_data_files(q_cons_vf, q_prim_vf, bc_type) - import :: scalar_field, integer_field, sys_size, m, n, p, pres_field, num_dims + import :: scalar_field, integer_field, sys_size, m, n, p, & + pres_field, num_dims - type(scalar_field), dimension(sys_size), intent(inout) :: q_cons_vf, q_prim_vf - type(integer_field), dimension(1:num_dims,-1:1), intent(in) :: bc_type + ! Conservative variables + type(scalar_field), & + dimension(sys_size), & + intent(inout) :: q_cons_vf, q_prim_vf + + type(integer_field), & + dimension(1:num_dims, -1:1), & + intent(in) :: bc_type end subroutine s_write_abstract_data_files end interface - !> Time-step folder into which grid and initial condition data will be placed - character(LEN=path_len + 2*name_len), private :: t_step_dir - character(LEN=path_len + 2*name_len), public :: restart_dir !< Restart data folder + character(LEN=path_len + 2*name_len), private :: t_step_dir !< + !! Time-step folder into which grid and initial condition data will be placed + + character(LEN=path_len + 2*name_len), public :: restart_dir !< + !! Restart data folder + procedure(s_write_abstract_data_files), pointer :: s_write_data_files => null() contains - !> Writes grid and initial condition data files to the "0" time-step directory in the local processor rank folder + !> Writes grid and initial condition data files to the "0" + !! time-step directory in the local processor rank folder + !! @param q_cons_vf Conservative variables + !! @param q_prim_vf Primitive variables + !! @param bc_type Boundary condition types impure subroutine s_write_serial_data_files(q_cons_vf, q_prim_vf, bc_type) + type(scalar_field), & + dimension(sys_size), & + intent(inout) :: q_cons_vf, q_prim_vf + + ! BC types + type(integer_field), & + dimension(1:num_dims, -1:1), & + intent(in) :: bc_type + + logical :: file_exist !< checks if file exists + + character(LEN=15) :: FMT + character(LEN=3) :: status + + character(LEN= & + int(floor(log10(real(sys_size, wp)))) + 1) :: file_num !< Used to store + !! the number, in character form, of the currently + !! manipulated conservative variable data file + + character(LEN=len_trim(t_step_dir) + name_len) :: file_loc !< + !! Generic string used to store the address of a particular file + + integer :: i, j, k, l, r, c !< Generic loop iterator + integer :: t_step + + real(wp), dimension(nb) :: nRtmp !< Temporary bubble concentration + real(wp) :: nbub !< Temporary bubble number density + real(wp) :: gamma, lit_gamma, pi_inf, qv !< Temporary EOS params + real(wp) :: rho !< Temporary density + real(wp) :: pres, T !< Temporary pressure + + real(wp) :: rhoYks(1:num_species) !< Temporary species mass fractions - type(scalar_field), dimension(sys_size), intent(inout) :: q_cons_vf, q_prim_vf - type(integer_field), dimension(1:num_dims,-1:1), intent(in) :: bc_type - logical :: file_exist - character(LEN=15) :: FMT - character(LEN=3) :: status - character(LEN=int(floor(log10(real(sys_size, wp)))) + 1) :: file_num - character(LEN=len_trim(t_step_dir) + name_len) :: file_loc - integer :: i, j, k, l, r, c - integer :: t_step - real(wp), dimension(nb) :: nRtmp - real(wp) :: nbub - real(wp) :: gamma, lit_gamma, pi_inf, qv - real(wp) :: rho - real(wp) :: pres, T - real(wp) :: rhoYks(1:num_species) - real(wp) :: pres_mag + real(wp) :: pres_mag pres_mag = 0._wp @@ -76,6 +122,8 @@ contains t_step = 0 + ! Outputting the Locations of the Cell-boundaries + if (old_grid) then status = 'old' else @@ -90,40 +138,52 @@ contains end if end if - file_loc = trim(t_step_dir) // '/x_cb.dat' - open (1, FILE=trim(file_loc), form='unformatted', STATUS=status) + ! x-coordinate direction + file_loc = trim(t_step_dir)//'/x_cb.dat' + open (1, FILE=trim(file_loc), FORM='unformatted', STATUS=status) write (1) x_cb(-1:m) close (1) + ! y- and z-coordinate directions if (n > 0) then - file_loc = trim(t_step_dir) // '/y_cb.dat' - open (1, FILE=trim(file_loc), form='unformatted', STATUS=status) + ! y-coordinate direction + file_loc = trim(t_step_dir)//'/y_cb.dat' + open (1, FILE=trim(file_loc), FORM='unformatted', & + STATUS=status) write (1) y_cb(-1:n) close (1) + ! z-coordinate direction if (p > 0) then - file_loc = trim(t_step_dir) // '/z_cb.dat' - open (1, FILE=trim(file_loc), form='unformatted', STATUS=status) + file_loc = trim(t_step_dir)//'/z_cb.dat' + open (1, FILE=trim(file_loc), FORM='unformatted', & + STATUS=status) write (1) z_cb(-1:p) close (1) end if end if + ! Outputting Conservative Variables do i = 1, sys_size write (file_num, '(I0)') i - file_loc = trim(t_step_dir) // '/q_cons_vf' // trim(file_num) // '.dat' - open (1, FILE=trim(file_loc), form='unformatted', STATUS=status) - write (1) q_cons_vf(i)%sf(0:m,0:n,0:p) + file_loc = trim(t_step_dir)//'/q_cons_vf'//trim(file_num) & + //'.dat' + open (1, FILE=trim(file_loc), FORM='unformatted', & + STATUS=status) + write (1) q_cons_vf(i)%sf(0:m, 0:n, 0:p) close (1) end do + !Outputting pb and mv for non-polytropic qbmm if (qbmm .and. .not. polytropic) then do i = 1, nb do r = 1, nnode write (file_num, '(I0)') r + (i - 1)*nnode + sys_size - file_loc = trim(t_step_dir) // '/pb' // trim(file_num) // '.dat' - open (1, FILE=trim(file_loc), form='unformatted', STATUS=status) - write (1) pb%sf(:,:,:,r, i) + file_loc = trim(t_step_dir)//'/pb'//trim(file_num) & + //'.dat' + open (1, FILE=trim(file_loc), FORM='unformatted', & + STATUS=status) + write (1) pb%sf(:, :, :, r, i) close (1) end do end do @@ -131,9 +191,11 @@ contains do i = 1, nb do r = 1, nnode write (file_num, '(I0)') r + (i - 1)*nnode + sys_size - file_loc = trim(t_step_dir) // '/mv' // trim(file_num) // '.dat' - open (1, FILE=trim(file_loc), form='unformatted', STATUS=status) - write (1) mv%sf(:,:,:,r, i) + file_loc = trim(t_step_dir)//'/mv'//trim(file_num) & + //'.dat' + open (1, FILE=trim(file_loc), FORM='unformatted', & + STATUS=status) + write (1) mv%sf(:, :, :, r, i) close (1) end do end do @@ -150,8 +212,8 @@ contains FMT = "(2F40.14)" end if - write (t_step_dir, '(A,I0,A,I0)') trim(case_dir) // '/D' - file_loc = trim(t_step_dir) // '/.' + write (t_step_dir, '(A,I0,A,I0)') trim(case_dir)//'/D' + file_loc = trim(t_step_dir)//'/.' inquire (FILE=trim(file_loc), EXIST=file_exist) @@ -159,13 +221,15 @@ contains if (cfl_dt) t_step = n_start + !1D if (n == 0 .and. p == 0) then if (model_eqns == 2) then do i = 1, sys_size - write (file_loc, '(A,I0,A,I2.2,A,I6.6,A)') trim(t_step_dir) // '/prim.', i, '.', proc_rank, '.', t_step, '.dat' + write (file_loc, '(A,I0,A,I2.2,A,I6.6,A)') trim(t_step_dir)//'/prim.', i, '.', proc_rank, '.', t_step, '.dat' open (2, FILE=trim(file_loc)) do j = 0, m + if (chemistry) then do c = 1, num_species rhoYks(c) = q_cons_vf(chemxb + c - 1)%sf(j, 0, 0) @@ -178,34 +242,40 @@ contains if ((i >= chemxb) .and. (i <= chemxe)) then write (2, FMT) x_cb(j), q_cons_vf(i)%sf(j, 0, 0)/rho - else if (((i >= cont_idx%beg) .and. (i <= cont_idx%end)) .or. ((i >= adv_idx%beg) .and. (i <= adv_idx%end) & - & ) .or. ((i >= chemxb) .and. (i <= chemxe))) then + else if (((i >= cont_idx%beg) .and. (i <= cont_idx%end)) & + .or. & + ((i >= adv_idx%beg) .and. (i <= adv_idx%end)) & + .or. & + ((i >= chemxb) .and. (i <= chemxe)) & + ) then write (2, FMT) x_cb(j), q_cons_vf(i)%sf(j, 0, 0) - else if (i == mom_idx%beg) then ! u + else if (i == mom_idx%beg) then !u write (2, FMT) x_cb(j), q_cons_vf(mom_idx%beg)%sf(j, 0, 0)/rho - else if (i == stress_idx%beg) then ! tau_e + else if (i == stress_idx%beg) then !tau_e write (2, FMT) x_cb(j), q_cons_vf(stress_idx%beg)%sf(j, 0, 0)/rho - else if (i == E_idx) then ! p + else if (i == E_idx) then !p if (mhd) then - pres_mag = 0.5_wp*(Bx0**2 + q_cons_vf(B_idx%beg)%sf(j, 0, 0)**2 + q_cons_vf(B_idx%beg + 1)%sf(j, & - & 0, 0)**2) + pres_mag = 0.5_wp*(Bx0**2 + q_cons_vf(B_idx%beg)%sf(j, 0, 0)**2 + q_cons_vf(B_idx%beg + 1)%sf(j, 0, 0)**2) end if - call s_compute_pressure(q_cons_vf(E_idx)%sf(j, 0, 0), q_cons_vf(alf_idx)%sf(j, 0, 0), & - & 0.5_wp*(q_cons_vf(mom_idx%beg)%sf(j, 0, 0)**2._wp)/rho, pi_inf, gamma, rho, & - & qv, rhoYks, pres, T, pres_mag=pres_mag) + call s_compute_pressure( & + q_cons_vf(E_idx)%sf(j, 0, 0), & + q_cons_vf(alf_idx)%sf(j, 0, 0), & + 0.5_wp*(q_cons_vf(mom_idx%beg)%sf(j, 0, 0)**2._wp)/rho, & + pi_inf, gamma, rho, qv, rhoYks, pres, T, pres_mag=pres_mag) write (2, FMT) x_cb(j), pres else if (mhd) then - if (i == mom_idx%beg + 1) then ! v + if (i == mom_idx%beg + 1) then ! v write (2, FMT) x_cb(j), q_cons_vf(mom_idx%beg + 1)%sf(j, 0, 0)/rho - else if (i == mom_idx%beg + 2) then ! w + else if (i == mom_idx%beg + 2) then ! w write (2, FMT) x_cb(j), q_cons_vf(mom_idx%beg + 2)%sf(j, 0, 0)/rho - else if (i == B_idx%beg) then ! By + else if (i == B_idx%beg) then ! By write (2, FMT) x_cb(j), q_cons_vf(B_idx%beg)%sf(j, 0, 0)/rho - else if (i == B_idx%beg + 1) then ! Bz + else if (i == B_idx%beg + 1) then ! Bz write (2, FMT) x_cb(j), q_cons_vf(B_idx%beg + 1)%sf(j, 0, 0)/rho end if else if ((i >= bub_idx%beg) .and. (i <= bub_idx%end) .and. bubbles_euler) then + if (qbmm) then nbub = q_cons_vf(bubxb)%sf(j, 0, 0) else @@ -231,7 +301,7 @@ contains end if do i = 1, sys_size - write (file_loc, '(A,I0,A,I2.2,A,I6.6,A)') trim(t_step_dir) // '/cons.', i, '.', proc_rank, '.', t_step, '.dat' + write (file_loc, '(A,I0,A,I2.2,A,I6.6,A)') trim(t_step_dir)//'/cons.', i, '.', proc_rank, '.', t_step, '.dat' open (2, FILE=trim(file_loc)) do j = 0, m @@ -243,8 +313,7 @@ contains if (qbmm .and. .not. polytropic) then do i = 1, nb do r = 1, nnode - write (file_loc, '(A,I0,A,I0,A,I2.2,A,I6.6,A)') trim(t_step_dir) // '/pres.', i, '.', r, '.', proc_rank, & - & '.', t_step, '.dat' + write (file_loc, '(A,I0,A,I0,A,I2.2,A,I6.6,A)') trim(t_step_dir)//'/pres.', i, '.', r, '.', proc_rank, '.', t_step, '.dat' open (2, FILE=trim(file_loc)) do j = 0, m @@ -255,8 +324,7 @@ contains end do do i = 1, nb do r = 1, nnode - write (file_loc, '(A,I0,A,I0,A,I2.2,A,I6.6,A)') trim(t_step_dir) // '/mv.', i, '.', r, '.', proc_rank, & - & '.', t_step, '.dat' + write (file_loc, '(A,I0,A,I0,A,I2.2,A,I6.6,A)') trim(t_step_dir)//'/mv.', i, '.', r, '.', proc_rank, '.', t_step, '.dat' open (2, FILE=trim(file_loc)) do j = 0, m @@ -274,9 +342,10 @@ contains FMT = "(3F40.14)" end if + ! 2D if ((n > 0) .and. (p == 0)) then do i = 1, sys_size - write (file_loc, '(A,I0,A,I2.2,A,I6.6,A)') trim(t_step_dir) // '/cons.', i, '.', proc_rank, '.', t_step, '.dat' + write (file_loc, '(A,I0,A,I2.2,A,I6.6,A)') trim(t_step_dir)//'/cons.', i, '.', proc_rank, '.', t_step, '.dat' open (2, FILE=trim(file_loc)) do j = 0, m do k = 0, n @@ -290,8 +359,7 @@ contains if (qbmm .and. .not. polytropic) then do i = 1, nb do r = 1, nnode - write (file_loc, '(A,I0,A,I0,A,I2.2,A,I6.6,A)') trim(t_step_dir) // '/pres.', i, '.', r, '.', proc_rank, & - & '.', t_step, '.dat' + write (file_loc, '(A,I0,A,I0,A,I2.2,A,I6.6,A)') trim(t_step_dir)//'/pres.', i, '.', r, '.', proc_rank, '.', t_step, '.dat' open (2, FILE=trim(file_loc)) do j = 0, m @@ -304,8 +372,7 @@ contains end do do i = 1, nb do r = 1, nnode - write (file_loc, '(A,I0,A,I0,A,I2.2,A,I6.6,A)') trim(t_step_dir) // '/mv.', i, '.', r, '.', proc_rank, & - & '.', t_step, '.dat' + write (file_loc, '(A,I0,A,I0,A,I2.2,A,I6.6,A)') trim(t_step_dir)//'/mv.', i, '.', r, '.', proc_rank, '.', t_step, '.dat' open (2, FILE=trim(file_loc)) do j = 0, m @@ -325,9 +392,10 @@ contains FMT = "(4F40.14)" end if + ! 3D if (p > 0) then do i = 1, sys_size - write (file_loc, '(A,I0,A,I2.2,A,I6.6,A)') trim(t_step_dir) // '/cons.', i, '.', proc_rank, '.', t_step, '.dat' + write (file_loc, '(A,I0,A,I2.2,A,I6.6,A)') trim(t_step_dir)//'/cons.', i, '.', proc_rank, '.', t_step, '.dat' open (2, FILE=trim(file_loc)) do j = 0, m do k = 0, n @@ -344,8 +412,7 @@ contains if (qbmm .and. .not. polytropic) then do i = 1, nb do r = 1, nnode - write (file_loc, '(A,I0,A,I0,A,I2.2,A,I6.6,A)') trim(t_step_dir) // '/pres.', i, '.', r, '.', proc_rank, & - & '.', t_step, '.dat' + write (file_loc, '(A,I0,A,I0,A,I2.2,A,I6.6,A)') trim(t_step_dir)//'/pres.', i, '.', r, '.', proc_rank, '.', t_step, '.dat' open (2, FILE=trim(file_loc)) do j = 0, m @@ -360,8 +427,7 @@ contains end do do i = 1, nb do r = 1, nnode - write (file_loc, '(A,I0,A,I0,A,I2.2,A,I6.6,A)') trim(t_step_dir) // '/mv.', i, '.', r, '.', proc_rank, & - & '.', t_step, '.dat' + write (file_loc, '(A,I0,A,I0,A,I2.2,A,I6.6,A)') trim(t_step_dir)//'/mv.', i, '.', r, '.', proc_rank, '.', t_step, '.dat' open (2, FILE=trim(file_loc)) do j = 0, m @@ -379,27 +445,43 @@ contains end subroutine s_write_serial_data_files - !> Writes grid and initial condition data files in parallel to the "0" time-step directory in the local processor rank folder + !> Writes grid and initial condition data files in parallel to the "0" + !! time-step directory in the local processor rank folder + !! @param q_cons_vf Conservative variables + !! @param q_prim_vf Primitive variables + !! @param bc_type Boundary condition types impure subroutine s_write_parallel_data_files(q_cons_vf, q_prim_vf, bc_type) - type(scalar_field), dimension(sys_size), intent(inout) :: q_cons_vf, q_prim_vf - type(integer_field), dimension(1:num_dims,-1:1), intent(in) :: bc_type + ! Conservative variables + type(scalar_field), & + dimension(sys_size), & + intent(inout) :: q_cons_vf, q_prim_vf + + type(integer_field), & + dimension(1:num_dims, -1:1), & + intent(in) :: bc_type #ifdef MFC_MPI - integer :: ifile, ierr, data_size - integer, dimension(MPI_STATUS_SIZE) :: status - integer(KIND=MPI_OFFSET_KIND) :: disp - integer(KIND=MPI_OFFSET_KIND) :: m_MOK, n_MOK, p_MOK - integer(KIND=MPI_OFFSET_KIND) :: WP_MOK, var_MOK, str_MOK - integer(KIND=MPI_OFFSET_KIND) :: NVARS_MOK - integer(KIND=MPI_OFFSET_KIND) :: MOK + + integer :: ifile, ierr, data_size + integer, dimension(MPI_STATUS_SIZE) :: status + integer(KIND=MPI_OFFSET_KIND) :: disp + integer(KIND=MPI_OFFSET_KIND) :: m_MOK, n_MOK, p_MOK + integer(KIND=MPI_OFFSET_KIND) :: WP_MOK, var_MOK, str_MOK + integer(KIND=MPI_OFFSET_KIND) :: NVARS_MOK + integer(KIND=MPI_OFFSET_KIND) :: MOK + character(LEN=path_len + 2*name_len) :: file_loc - logical :: file_exist, dir_check - integer :: i, j, k, l - real(wp) :: loc_violations, glb_violations - integer :: m_ds, n_ds, p_ds - integer :: m_glb_ds, n_glb_ds, p_glb_ds - integer :: m_glb_save, n_glb_save, p_glb_save !< Size of array being saved + logical :: file_exist, dir_check + + ! Generic loop iterators + integer :: i, j, k, l + real(wp) :: loc_violations, glb_violations + + ! Downsample variables + integer :: m_ds, n_ds, p_ds + integer :: m_glb_ds, n_glb_ds, p_glb_ds + integer :: m_glb_save, n_glb_save, p_glb_save ! Size of array being saved loc_violations = 0._wp @@ -409,17 +491,17 @@ contains end if call s_mpi_allreduce_sum(loc_violations, glb_violations) if (proc_rank == 0 .and. nint(glb_violations) > 0) then - print *, & - & "WARNING: Attempting to downsample data but there are" & - & // "processors with local problem sizes that are not divisible by 3." + print *, "WARNING: Attempting to downsample data but there are"// & + "processors with local problem sizes that are not divisible by 3." end if call s_populate_variables_buffers(bc_type, q_cons_vf) - call s_downsample_data(q_cons_vf, q_cons_temp, m_ds, n_ds, p_ds, m_glb_ds, n_glb_ds, p_glb_ds) + call s_downsample_data(q_cons_vf, q_cons_temp, & + m_ds, n_ds, p_ds, m_glb_ds, n_glb_ds, p_glb_ds) end if if (file_per_process) then if (proc_rank == 0) then - file_loc = trim(case_dir) // '/restart_data/lustre_0' + file_loc = trim(case_dir)//'/restart_data/lustre_0' call my_inquire(file_loc, dir_check) if (dir_check .neqv. .true.) then call s_create_directory(trim(file_loc)) @@ -429,31 +511,36 @@ contains call s_mpi_barrier() call DelayFileAccess(proc_rank) + ! Initialize MPI data I/O if (down_sample) then call s_initialize_mpi_data_ds(q_cons_temp) else call s_initialize_mpi_data(q_cons_vf) end if + ! Open the file to write all flow variables if (cfl_dt) then write (file_loc, '(I0,A,i7.7,A)') n_start, '_', proc_rank, '.dat' else write (file_loc, '(I0,A,i7.7,A)') t_step_start, '_', proc_rank, '.dat' end if - file_loc = trim(restart_dir) // '/lustre_0' // trim(mpiiofs) // trim(file_loc) + file_loc = trim(restart_dir)//'/lustre_0'//trim(mpiiofs)//trim(file_loc) inquire (FILE=trim(file_loc), EXIST=file_exist) if (file_exist .and. proc_rank == 0) then call MPI_FILE_DELETE(file_loc, mpi_info_int, ierr) end if if (file_exist) call MPI_FILE_DELETE(file_loc, mpi_info_int, ierr) - call MPI_FILE_OPEN(MPI_COMM_SELF, file_loc, ior(MPI_MODE_WRONLY, MPI_MODE_CREATE), mpi_info_int, ifile, ierr) + call MPI_FILE_OPEN(MPI_COMM_SELF, file_loc, ior(MPI_MODE_WRONLY, MPI_MODE_CREATE), & + mpi_info_int, ifile, ierr) if (down_sample) then + ! Size of local arrays data_size = (m_ds + 3)*(n_ds + 3)*(p_ds + 3) m_glb_save = m_glb_ds + 3 n_glb_save = n_glb_ds + 3 p_glb_save = p_glb_ds + 3 else + ! Size of local arrays data_size = (m + 1)*(n + 1)*(p + 1) m_glb_save = m_glb + 1 n_glb_save = n_glb + 1 @@ -469,17 +556,21 @@ contains str_MOK = int(name_len, MPI_OFFSET_KIND) NVARS_MOK = int(sys_size, MPI_OFFSET_KIND) + ! Write the data for each variable if (bubbles_euler) then - do i = 1, sys_size + do i = 1, sys_size! adv_idx%end var_MOK = int(i, MPI_OFFSET_KIND) - call MPI_FILE_WRITE_ALL(ifile, MPI_IO_DATA%var(i)%sf, data_size*mpi_io_type, mpi_io_p, status, ierr) + call MPI_FILE_WRITE_ALL(ifile, MPI_IO_DATA%var(i)%sf, data_size*mpi_io_type, & + mpi_io_p, status, ierr) end do + !Additional variables pb and mv for non-polytropic qbmm if (qbmm .and. .not. polytropic) then do i = sys_size + 1, sys_size + 2*nb*nnode var_MOK = int(i, MPI_OFFSET_KIND) - call MPI_FILE_WRITE_ALL(ifile, MPI_IO_DATA%var(i)%sf, data_size*mpi_io_type, mpi_io_p, status, ierr) + call MPI_FILE_WRITE_ALL(ifile, MPI_IO_DATA%var(i)%sf, data_size*mpi_io_type, & + mpi_io_p, status, ierr) end do end if else @@ -487,33 +578,39 @@ contains do i = 1, sys_size var_MOK = int(i, MPI_OFFSET_KIND) - call MPI_FILE_WRITE_ALL(ifile, q_cons_temp(i)%sf, data_size*mpi_io_type, mpi_io_p, status, ierr) + call MPI_FILE_WRITE_ALL(ifile, q_cons_temp(i)%sf, data_size*mpi_io_type, & + mpi_io_p, status, ierr) end do else do i = 1, sys_size var_MOK = int(i, MPI_OFFSET_KIND) - call MPI_FILE_WRITE_ALL(ifile, MPI_IO_DATA%var(i)%sf, data_size*mpi_io_type, mpi_io_p, status, ierr) + call MPI_FILE_WRITE_ALL(ifile, MPI_IO_DATA%var(i)%sf, data_size*mpi_io_type, & + mpi_io_p, status, ierr) end do end if end if call MPI_FILE_CLOSE(ifile, ierr) + else call s_initialize_mpi_data(q_cons_vf) + ! Open the file to write all flow variables if (cfl_dt) then write (file_loc, '(I0,A)') n_start, '.dat' else write (file_loc, '(I0,A)') t_step_start, '.dat' end if - file_loc = trim(restart_dir) // trim(mpiiofs) // trim(file_loc) + file_loc = trim(restart_dir)//trim(mpiiofs)//trim(file_loc) inquire (FILE=trim(file_loc), EXIST=file_exist) if (file_exist .and. proc_rank == 0) then call MPI_FILE_DELETE(file_loc, mpi_info_int, ierr) end if - call MPI_FILE_OPEN(MPI_COMM_WORLD, file_loc, ior(MPI_MODE_WRONLY, MPI_MODE_CREATE), mpi_info_int, ifile, ierr) + call MPI_FILE_OPEN(MPI_COMM_WORLD, file_loc, ior(MPI_MODE_WRONLY, MPI_MODE_CREATE), & + mpi_info_int, ifile, ierr) + ! Size of local arrays data_size = (m + 1)*(n + 1)*(p + 1) ! Resize some integers so MPI can write even the biggest files @@ -525,34 +622,47 @@ contains str_MOK = int(name_len, MPI_OFFSET_KIND) NVARS_MOK = int(sys_size, MPI_OFFSET_KIND) + ! Write the data for each variable if (bubbles_euler) then - do i = 1, sys_size + do i = 1, sys_size! adv_idx%end var_MOK = int(i, MPI_OFFSET_KIND) + ! Initial displacement to skip at beginning of file disp = m_MOK*max(MOK, n_MOK)*max(MOK, p_MOK)*WP_MOK*(var_MOK - 1) - call MPI_FILE_SET_VIEW(ifile, disp, mpi_io_p, MPI_IO_DATA%view(i), 'native', mpi_info_int, ierr) - call MPI_FILE_WRITE_ALL(ifile, MPI_IO_DATA%var(i)%sf, data_size*mpi_io_type, mpi_io_p, status, ierr) + call MPI_FILE_SET_VIEW(ifile, disp, mpi_io_p, MPI_IO_DATA%view(i), & + 'native', mpi_info_int, ierr) + call MPI_FILE_WRITE_ALL(ifile, MPI_IO_DATA%var(i)%sf, data_size*mpi_io_type, & + mpi_io_p, status, ierr) end do + !Additional variables pb and mv for non-polytropic qbmm if (qbmm .and. .not. polytropic) then do i = sys_size + 1, sys_size + 2*nb*nnode var_MOK = int(i, MPI_OFFSET_KIND) + ! Initial displacement to skip at beginning of file disp = m_MOK*max(MOK, n_MOK)*max(MOK, p_MOK)*WP_MOK*(var_MOK - 1) - call MPI_FILE_SET_VIEW(ifile, disp, mpi_io_p, MPI_IO_DATA%view(i), 'native', mpi_info_int, ierr) - call MPI_FILE_WRITE_ALL(ifile, MPI_IO_DATA%var(i)%sf, data_size*mpi_io_type, mpi_io_p, status, ierr) + call MPI_FILE_SET_VIEW(ifile, disp, mpi_io_p, MPI_IO_DATA%view(i), & + 'native', mpi_info_int, ierr) + call MPI_FILE_WRITE_ALL(ifile, MPI_IO_DATA%var(i)%sf, data_size*mpi_io_type, & + mpi_io_p, status, ierr) end do end if else - do i = 1, sys_size + do i = 1, sys_size !TODO: check if this is right + ! do i = 1, adv_idx%end var_MOK = int(i, MPI_OFFSET_KIND) + ! Initial displacement to skip at beginning of file disp = m_MOK*max(MOK, n_MOK)*max(MOK, p_MOK)*WP_MOK*(var_MOK - 1) - call MPI_FILE_SET_VIEW(ifile, disp, mpi_io_p, MPI_IO_DATA%view(i), 'native', mpi_info_int, ierr) - call MPI_FILE_WRITE_ALL(ifile, MPI_IO_DATA%var(i)%sf, data_size*mpi_io_type, mpi_io_p, status, ierr) + call MPI_FILE_SET_VIEW(ifile, disp, mpi_io_p, MPI_IO_DATA%view(i), & + 'native', mpi_info_int, ierr) + call MPI_FILE_WRITE_ALL(ifile, MPI_IO_DATA%var(i)%sf, data_size*mpi_io_type, & + mpi_io_p, status, ierr) end do + end if call MPI_FILE_CLOSE(ifile, ierr) @@ -569,37 +679,50 @@ contains end subroutine s_write_parallel_data_files - !> Computation of parameters, allocation procedures, and/or any other tasks needed to properly setup the module + !> Computation of parameters, allocation procedures, and/or + !! any other tasks needed to properly setup the module impure subroutine s_initialize_data_output_module - + ! Generic string used to store the address of a particular file character(LEN=len_trim(case_dir) + 2*name_len) :: file_loc - character(len=15) :: temp - character(LEN=1), dimension(3), parameter :: coord = (/'x', 'y', 'z'/) - logical :: dir_check - integer :: i - integer :: m_ds, n_ds, p_ds + character(len=15) :: temp + character(LEN=1), dimension(3), parameter :: coord = (/'x', 'y', 'z'/) + + ! Generic logical used to check the existence of directories + logical :: dir_check + integer :: i + + integer :: m_ds, n_ds, p_ds !< down sample dimensions if (parallel_io .neqv. .true.) then + ! Setting the address of the time-step directory write (t_step_dir, '(A,I0,A)') '/p_all/p', proc_rank, '/0' - t_step_dir = trim(case_dir) // trim(t_step_dir) + t_step_dir = trim(case_dir)//trim(t_step_dir) + ! Checking the existence of the time-step directory, removing it, if + ! it exists, and creating a new copy. Note that if preexisting grid + ! and/or initial condition data are to be read in from the very same + ! location, then the above described steps are not executed here but + ! rather in the module m_start_up.f90. if (old_grid .neqv. .true.) then - file_loc = trim(t_step_dir) // '/' + + file_loc = trim(t_step_dir)//'/' call my_inquire(file_loc, dir_check) if (dir_check) call s_delete_directory(trim(t_step_dir)) call s_create_directory(trim(t_step_dir)) + end if s_write_data_files => s_write_serial_data_files else write (restart_dir, '(A)') '/restart_data' - restart_dir = trim(case_dir) // trim(restart_dir) + restart_dir = trim(case_dir)//trim(restart_dir) if ((old_grid .neqv. .true.) .and. (proc_rank == 0)) then - file_loc = trim(restart_dir) // '/' + + file_loc = trim(restart_dir)//'/' call my_inquire(file_loc, dir_check) if (dir_check) call s_delete_directory(trim(restart_dir)) @@ -609,6 +732,7 @@ contains call s_mpi_barrier() s_write_data_files => s_write_parallel_data_files + end if open (1, FILE='indices.dat', STATUS='unknown') @@ -620,23 +744,21 @@ contains write (1, '(A)') " " do i = contxb, contxe write (temp, '(I0)') i - contxb + 1 - write (1, '(I3,A20,A20)') i, "\alpha_{" // trim(temp) // "} \rho_{" // trim(temp) // "}", & - & "\alpha_{" // trim(temp) // "} \rho" + write (1, '(I3,A20,A20)') i, "\alpha_{"//trim(temp)//"} \rho_{"//trim(temp)//"}", "\alpha_{"//trim(temp)//"} \rho" end do do i = momxb, momxe - write (1, '(I3,A20,A20)') i, "\rho u_" // coord(i - momxb + 1), "u_" // coord(i - momxb + 1) + write (1, '(I3,A20,A20)') i, "\rho u_"//coord(i - momxb + 1), "u_"//coord(i - momxb + 1) end do do i = E_idx, E_idx write (1, '(I3,A20,A20)') i, "\rho U", "p" end do do i = advxb, advxe write (temp, '(I0)') i - contxb + 1 - write (1, '(I3,A20,A20)') i, "\alpha_{" // trim(temp) // "}", "\alpha_{" // trim(temp) // "}" + write (1, '(I3,A20,A20)') i, "\alpha_{"//trim(temp)//"}", "\alpha_{"//trim(temp)//"}" end do if (chemistry) then do i = 1, num_species - write (1, '(I3,A20,A20)') chemxb + i - 1, "Y_{" // trim(species_names(i)) // "} \rho", & - & "Y_{" // trim(species_names(i)) // "}" + write (1, '(I3,A20,A20)') chemxb + i - 1, "Y_{"//trim(species_names(i))//"} \rho", "Y_{"//trim(species_names(i))//"}" end do end if @@ -659,7 +781,7 @@ contains allocate (q_cons_temp(1:sys_size)) do i = 1, sys_size - allocate (q_cons_temp(i)%sf(-1:m_ds + 1,-1:n_ds + 1,-1:p_ds + 1)) + allocate (q_cons_temp(i)%sf(-1:m_ds + 1, -1:n_ds + 1, -1:p_ds + 1)) end do end if diff --git a/src/pre_process/m_global_parameters.fpp b/src/pre_process/m_global_parameters.fpp index 077262aece..93a49e8d63 100644 --- a/src/pre_process/m_global_parameters.fpp +++ b/src/pre_process/m_global_parameters.fpp @@ -8,171 +8,261 @@ module m_global_parameters #ifdef MFC_MPI - use mpi ! Message passing interface (MPI) module + use mpi ! Message passing interface (MPI) module #endif - use m_derived_types ! Definitions of the derived types - use m_helper_basic ! Functions to compare floating point numbers + use m_derived_types ! Definitions of the derived types + + use m_helper_basic ! Functions to compare floating point numbers + use m_thermochem, only: num_species implicit none ! Logistics - integer :: num_procs !< Number of processors - character(LEN=path_len) :: case_dir !< Case folder location - logical :: old_grid !< Use existing grid data - logical :: old_ic, non_axis_sym !< Use existing IC data - integer :: t_step_old, t_step_start !< Existing IC/grid folder - logical :: cfl_adap_dt, cfl_const_dt, cfl_dt - integer :: n_start, n_start_old + integer :: num_procs !< Number of processors + character(LEN=path_len) :: case_dir !< Case folder location + logical :: old_grid !< Use existing grid data + logical :: old_ic, non_axis_sym !< Use existing IC data + integer :: t_step_old, t_step_start !< Existing IC/grid folder + + logical :: cfl_adap_dt, cfl_const_dt, cfl_dt + integer :: n_start, n_start_old ! Computational Domain Parameters - integer :: proc_rank !< Rank of the local processor Number of cells in the x-, y- and z-coordinate directions + integer :: proc_rank !< Rank of the local processor + + !! Number of cells in the x-, y- and z-coordinate directions integer :: m integer :: n integer :: p !> @name Max and min number of cells in a direction of each combination of x-,y-, and z- type(cell_num_bounds) :: cells_bounds - integer(kind=8) :: nGlobal !< Global number of cells in the domain - integer :: m_glb, n_glb, p_glb !< Global number of cells in each direction - integer :: num_dims !< Number of spatial dimensions - integer :: num_vels !< Number of velocity components (different from num_dims for mhd) - logical :: cyl_coord - integer :: grid_geometry !< Cylindrical coordinates (either axisymmetric or full 3D) - !> Locations of cell-centers (cc) in x-, y- and z-directions, respectively - real(wp), allocatable, dimension(:) :: x_cc, y_cc, z_cc - !> Locations of cell-boundaries (cb) in x-, y- and z-directions, respectively - real(wp), allocatable, dimension(:) :: x_cb, y_cb, z_cb - real(wp) :: dx, dy, dz !< Minimum cell-widths in the x-, y- and z-coordinate directions - type(bounds_info) :: x_domain, y_domain, z_domain !< Locations of the domain bounds in the x-, y- and z-coordinate directions - logical :: stretch_x, stretch_y, stretch_z !< Grid stretching flags for the x-, y- and z-coordinate directions - ! Grid stretching: a_x/a_y/a_z = rate, x_a/y_a/z_a = location + + integer(kind=8) :: nGlobal !< Global number of cells in the domain + + integer :: m_glb, n_glb, p_glb !< Global number of cells in each direction + + integer :: num_dims !< Number of spatial dimensions + integer :: num_vels !< Number of velocity components (different from num_dims for mhd) + + logical :: cyl_coord + integer :: grid_geometry !< Cylindrical coordinates (either axisymmetric or full 3D) + + real(wp), allocatable, dimension(:) :: x_cc, y_cc, z_cc !< + !! Locations of cell-centers (cc) in x-, y- and z-directions, respectively + + real(wp), allocatable, dimension(:) :: x_cb, y_cb, z_cb !< + !! Locations of cell-boundaries (cb) in x-, y- and z-directions, respectively + + real(wp) :: dx, dy, dz !< + !! Minimum cell-widths in the x-, y- and z-coordinate directions + + type(bounds_info) :: x_domain, y_domain, z_domain !< + !! Locations of the domain bounds in the x-, y- and z-coordinate directions + + logical :: stretch_x, stretch_y, stretch_z !< + !! Grid stretching flags for the x-, y- and z-coordinate directions + + ! Parameters of the grid stretching function for the x-, y- and z-coordinate + ! directions. The "a" parameters are a measure of the rate at which the grid + ! is stretched while the remaining parameters are indicative of the location + ! on the grid at which the stretching begins. real(wp) :: a_x, a_y, a_z - integer :: loops_x, loops_y, loops_z + integer :: loops_x, loops_y, loops_z real(wp) :: x_a, y_a, z_a real(wp) :: x_b, y_b, z_b ! Simulation Algorithm Parameters - integer :: model_eqns !< Multicomponent flow model - logical :: relax !< activate phase change - integer :: relax_model !< Relax Model - real(wp) :: palpha_eps !< trigger parameter for the p relaxation procedure, phase change model - real(wp) :: ptgalpha_eps !< trigger parameter for the pTg relaxation procedure, phase change model - integer :: num_fluids !< Number of different fluids present in the flow - logical :: mpp_lim !< Alpha limiter - integer :: sys_size !< Number of unknowns in the system of equations - integer :: recon_type !< Reconstruction Type - integer :: weno_polyn !< Degree of the WENO polynomials (polyn) - integer :: muscl_polyn !< Degree of the MUSCL polynomials (polyn) - integer :: weno_order !< Order of accuracy for the WENO reconstruction - integer :: muscl_order !< Order of accuracy for the MUSCL reconstruction - logical :: hypoelasticity !< activate hypoelasticity - logical :: hyperelasticity !< activate hyperelasticity - logical :: elasticity !< elasticity modeling, true for hyper or hypo - logical :: mhd !< Magnetohydrodynamics - logical :: relativity !< Relativity for RMHD - integer :: b_size !< Number of components in the b tensor - integer :: tensor_size !< Number of components in the nonsymmetric tensor - logical :: pre_stress !< activate pre_stressed domain - logical :: cont_damage !< continuum damage modeling - logical :: hyper_cleaning !< Hyperbolic cleaning for MHD - logical :: igr !< Use information geometric regularization - integer :: igr_order !< IGR reconstruction order - logical, parameter :: chemistry = .${chemistry}$. !< Chemistry modeling + integer :: model_eqns !< Multicomponent flow model + logical :: relax !< activate phase change + integer :: relax_model !< Relax Model + real(wp) :: palpha_eps !< trigger parameter for the p relaxation procedure, phase change model + real(wp) :: ptgalpha_eps !< trigger parameter for the pTg relaxation procedure, phase change model + integer :: num_fluids !< Number of different fluids present in the flow + logical :: mpp_lim !< Alpha limiter + integer :: sys_size !< Number of unknowns in the system of equations + integer :: recon_type !< Reconstruction Type + integer :: weno_polyn !< Degree of the WENO polynomials (polyn) + integer :: muscl_polyn !< Degree of the MUSCL polynomials (polyn) + integer :: weno_order !< Order of accuracy for the WENO reconstruction + integer :: muscl_order !< Order of accuracy for the MUSCL reconstruction + logical :: hypoelasticity !< activate hypoelasticity + logical :: hyperelasticity !< activate hyperelasticity + logical :: elasticity !< elasticity modeling, true for hyper or hypo + logical :: mhd !< Magnetohydrodynamics + logical :: relativity !< Relativity for RMHD + integer :: b_size !< Number of components in the b tensor + integer :: tensor_size !< Number of components in the nonsymmetric tensor + logical :: pre_stress !< activate pre_stressed domain + logical :: cont_damage !< continuum damage modeling + logical :: hyper_cleaning !< Hyperbolic cleaning for MHD + logical :: igr !< Use information geometric regularization + integer :: igr_order !< IGR reconstruction order + logical, parameter :: chemistry = .${chemistry}$. !< Chemistry modeling + ! Annotations of the structure, i.e. the organization, of the state vectors type(int_bounds_info) :: cont_idx !< Indexes of first & last continuity eqns. type(int_bounds_info) :: mom_idx !< Indexes of first & last momentum eqns. - integer :: E_idx !< Index of total energy equation - integer :: alf_idx !< Index of void fraction - integer :: n_idx !< Index of number density + integer :: E_idx !< Index of total energy equation + integer :: alf_idx !< Index of void fraction + integer :: n_idx !< Index of number density type(int_bounds_info) :: adv_idx !< Indexes of first & last advection eqns. type(int_bounds_info) :: internalEnergies_idx !< Indexes of first & last internal energy eqns. type(bub_bounds_info) :: bub_idx !< Indexes of first & last bubble variable eqns. - integer :: gamma_idx !< Index of specific heat ratio func. eqn. - integer :: pi_inf_idx !< Index of liquid stiffness func. eqn. + integer :: gamma_idx !< Index of specific heat ratio func. eqn. + integer :: pi_inf_idx !< Index of liquid stiffness func. eqn. type(int_bounds_info) :: B_idx !< Indexes of first and last magnetic field eqns. type(int_bounds_info) :: stress_idx !< Indexes of elastic shear stress eqns. type(int_bounds_info) :: xi_idx !< Indexes of first and last reference map eqns. - integer :: c_idx !< Index of the color function + integer :: c_idx !< Index of the color function type(int_bounds_info) :: species_idx !< Indexes of first & last concentration eqns. - integer :: damage_idx !< Index of damage state variable (D) for continuum damage model - integer :: psi_idx !< Index of hyperbolic cleaning state variable for MHD - ! Cell Indices for the (local) interior points (O-m, O-n, 0-p). Stands for "InDices With BUFFer". + integer :: damage_idx !< Index of damage state variable (D) for continuum damage model + integer :: psi_idx !< Index of hyperbolic cleaning state variable for MHD + + ! Cell Indices for the (local) interior points (O-m, O-n, 0-p). + ! Stands for "InDices With BUFFer". type(int_bounds_info) :: idwint(1:3) - ! Cell indices (InDices With BUFFer): includes buffer except in pre_process - type(int_bounds_info) :: idwbuff(1:3) - type(int_bounds_info) :: bc_x, bc_y, bc_z !< Boundary conditions in the x-, y- and z-coordinate directions - integer :: shear_num !< Number of shear stress components - integer, dimension(3) :: shear_indices !< Indices of the stress components that represent shear stress - integer :: shear_BC_flip_num !< Number of shear stress components to reflect for boundary conditions - integer, dimension(3, 2) :: shear_BC_flip_indices !< Shear stress BC reflection indices (1:3, 1:shear_BC_flip_num) - logical :: parallel_io !< Format of the data files - logical :: file_per_process !< type of data output - integer :: precision !< Precision of output files - logical :: down_sample !< Down-sample the output data - logical :: mixlayer_vel_profile !< Set hyperbolic tangent streamwise velocity profile - real(wp) :: mixlayer_vel_coef !< Coefficient for the hyperbolic tangent streamwise velocity profile - logical :: mixlayer_perturb !< Superimpose instability waves to surrounding fluid flow - integer :: mixlayer_perturb_nk !< Number of Fourier modes for perturbation with mixlayer_perturb flag - real(wp) :: mixlayer_perturb_k0 !< Peak wavenumber for mixlayer perturbation (default: most unstable mode) - logical :: simplex_perturb + ! Cell Indices for the entire (local) domain. In simulation and post_process, + ! this includes the buffer region. idwbuff and idwint are the same otherwise. + ! Stands for "InDices With BUFFer". + type(int_bounds_info) :: idwbuff(1:3) + + integer :: fd_order !< + !! The order of the finite-difference (fd) approximations of the first-order + !! derivatives that need to be evaluated when the CoM or flow probe data + !! files are to be written at each time step + + integer :: fd_number !< + !! The finite-difference number is given by MAX(1, fd_order/2). Essentially, + !! it is a measure of the half-size of the finite-difference stencil for the + !! selected order of accuracy. + + !> @name lagrangian subgrid bubble parameters + !> @{! + type(bubbles_lagrange_parameters) :: lag_params !< Lagrange bubbles' parameters + !> @} + + type(int_bounds_info) :: bc_x, bc_y, bc_z !< + !! Boundary conditions in the x-, y- and z-coordinate directions + + integer :: shear_num !! Number of shear stress components + integer, dimension(3) :: shear_indices !< + !! Indices of the stress components that represent shear stress + integer :: shear_BC_flip_num !< + !! Number of shear stress components to reflect for boundary conditions + integer, dimension(3, 2) :: shear_BC_flip_indices !< + !! Indices of shear stress components to reflect for boundary conditions. + !! Size: (1:3, 1:shear_BC_flip_num) for (x/y/z, [indices]) + + logical :: parallel_io !< Format of the data files + logical :: file_per_process !< type of data output + integer :: precision !< Precision of output files + logical :: down_sample !< Down-sample the output data + + logical :: mixlayer_vel_profile !< Set hyperbolic tangent streamwise velocity profile + real(wp) :: mixlayer_vel_coef !< Coefficient for the hyperbolic tangent streamwise velocity profile + logical :: mixlayer_perturb !< Superimpose instability waves to surrounding fluid flow + integer :: mixlayer_perturb_nk !< Number of Fourier modes for perturbation with mixlayer_perturb flag + real(wp) :: mixlayer_perturb_k0 !< Peak wavenumber of prescribed energy spectra with mixlayer_perturb flag + !! Default value (k0 = 0.4446) is most unstable mode obtained from linear stability analysis + !! See Michalke (1964, JFM) for details + logical :: simplex_perturb type(simplex_noise_params) :: simplex_params - real(wp) :: pi_fac !< Factor for artificial pi_inf - logical :: viscous - logical :: bubbles_lagrange + + real(wp) :: pi_fac !< Factor for artificial pi_inf + + logical :: viscous + logical :: bubbles_lagrange ! Perturb density of surrounding air so as to break symmetry of grid - logical :: perturb_flow - integer :: perturb_flow_fluid !< Fluid to be perturbed with perturb_flow flag - real(wp) :: perturb_flow_mag !< Magnitude of perturbation with perturb_flow flag - logical :: perturb_sph - integer :: perturb_sph_fluid !< Fluid to be perturbed with perturb_sph flag + logical :: perturb_flow + integer :: perturb_flow_fluid !< Fluid to be perturbed with perturb_flow flag + real(wp) :: perturb_flow_mag !< Magnitude of perturbation with perturb_flow flag + logical :: perturb_sph + integer :: perturb_sph_fluid !< Fluid to be perturbed with perturb_sph flag real(wp), dimension(num_fluids_max) :: fluid_rho - logical :: elliptic_smoothing - integer :: elliptic_smoothing_iters - integer, allocatable, dimension(:) :: proc_coords !< Processor coordinates in MPI_CART_COMM - integer, allocatable, dimension(:) :: start_idx !< Starting cell-center index of local processor in global grid + + logical :: elliptic_smoothing + integer :: elliptic_smoothing_iters + + integer, allocatable, dimension(:) :: proc_coords !< + !! Processor coordinates in MPI_CART_COMM + + type(int_bounds_info), dimension(3) :: nidx + + integer, allocatable, dimension(:, :, :) :: neighbor_ranks + !! Neighbor ranks + + integer, allocatable, dimension(:) :: start_idx !< + !! Starting cell-center index of local processor in global grid + #ifdef MFC_MPI + type(mpi_io_var), public :: MPI_IO_DATA - character(LEN=name_len) :: mpiiofs - integer :: mpi_info_int !< MPI info for parallel IO with Lustre file systems + + character(LEN=name_len) :: mpiiofs + integer :: mpi_info_int !< + !! MPI info for parallel IO with Lustre file systems + #endif ! Initial Condition Parameters - integer :: num_patches !< Number of patches composing initial condition - type(ic_patch_parameters), dimension(num_patches_max) :: patch_icpp !< IC patch parameters (max: num_patches_max) - integer :: num_bc_patches !< Number of boundary condition patches - logical :: bc_io !< whether or not to save BC data - type(bc_patch_parameters), dimension(num_bc_patches_max) :: patch_bc !< Boundary condition patch parameters + integer :: num_patches !< Number of patches composing initial condition + + type(ic_patch_parameters), dimension(num_patches_max) :: patch_icpp !< + !! Database of the initial condition patch parameters (icpp) for each of the + !! patches employed in the configuration of the initial condition. Note that + !! the maximum allowable number of patches, num_patches_max, may be changed + !! in the module m_derived_types.f90. + + integer :: num_bc_patches !< Number of boundary condition patches + logical :: bc_io !< whether or not to save BC data + type(bc_patch_parameters), dimension(num_bc_patches_max) :: patch_bc + !! Database of the boundary condition patch parameters for each of the patches + !! employed in the configuration of the boundary conditions ! Fluids Physical Parameters - type(physical_parameters), dimension(num_fluids_max) :: fluid_pp !< Stiffened gas EOS parameters and Reynolds numbers per fluid + type(physical_parameters), dimension(num_fluids_max) :: fluid_pp !< + !! Database of the physical parameters of each of the fluids that is present + !! in the flow. These include the stiffened gas equation of state parameters, + !! and the Reynolds numbers. + ! Subgrid Bubble Parameters type(subgrid_bubble_physical_parameters) :: bub_pp - real(wp) :: rhoref, pref !< Reference parameters for Tait EOS - type(chemistry_parameters) :: chem_params + + real(wp) :: rhoref, pref !< Reference parameters for Tait EOS + + type(chemistry_parameters) :: chem_params !> @name Bubble modeling !> @{ - integer :: nb - real(wp) :: Ca, Web, Re_inv, Eu + integer :: nb + real(wp) :: Ca, Web, Re_inv, Eu real(wp), dimension(:), allocatable :: weight, R0 - logical :: bubbles_euler - logical :: qbmm !< Quadrature moment method - integer :: nmom !< Number of carried moments - real(wp) :: sigR, sigV, rhoRV !< standard deviations in R/V - logical :: adv_n !< Solve the number density equation and compute alpha from number density + logical :: bubbles_euler + logical :: qbmm !< Quadrature moment method + integer :: nmom !< Number of carried moments + real(wp) :: sigR, sigV, rhoRV !< standard deviations in R/V + logical :: adv_n !< Solve the number density equation and compute alpha from number density !> @} !> @name Immersed Boundaries !> @{ - logical :: ib !< Turn immersed boundaries on - integer :: num_ibs !< Number of immersed boundaries - integer :: Np - type(ib_patch_parameters), dimension(num_patches_max) :: patch_ib !< Immersed boundary patch parameters - type(vec3_dt), allocatable, dimension(:) :: airfoil_grid_u, airfoil_grid_l + logical :: ib !< Turn immersed boundaries on + integer :: num_ibs !< Number of immersed boundaries + integer :: Np + + type(ib_patch_parameters), dimension(num_patches_max) :: patch_ib + + type(vec3_dt), allocatable, dimension(:) :: airfoil_grid_u, airfoil_grid_l + !! Database of the immersed boundary patch parameters for each of the + !! patches employed in the configuration of the initial condition. Note that + !! the maximum allowable number of patches, num_patches_max, may be changed + !! in the module m_derived_types.f90. + !> @} !> @name Non-polytropic bubble gas compression @@ -180,19 +270,25 @@ module m_global_parameters logical :: polytropic logical :: polydisperse real(wp) :: poly_sigma - integer :: dist_type !< 1 = binormal, 2 = lognormal-normal - integer :: thermal !< 1 = adiabatic, 2 = isotherm, 3 = transfer + integer :: dist_type !1 = binormal, 2 = lognormal-normal + + integer :: thermal !1 = adiabatic, 2 = isotherm, 3 = transfer + real(wp) :: phi_vg, phi_gv, Pe_c, Tw, k_vl, k_gl real(wp) :: gam_m + real(wp), dimension(:), allocatable :: pb0, mass_g0, mass_v0, Pe_T, k_v, k_g real(wp), dimension(:), allocatable :: Re_trans_T, Re_trans_c, Im_trans_T, Im_trans_c, omegaN - real(wp) :: R0ref, p0ref, rho0ref, T0ref, ss, pv, vd, mu_l, mu_v, mu_g, gam_v, gam_g, M_v, M_g, cp_v, cp_g, R_v, R_g + + real(wp) :: R0ref, p0ref, rho0ref, T0ref, ss, pv, vd, mu_l, mu_v, mu_g, & + gam_v, gam_g, M_v, M_g, cp_v, cp_g, R_v, R_g + !> @} !> @name Surface Tension Modeling !> @{ real(wp) :: sigma - logical :: surface_tension + logical :: surface_tension !> @} !> @name Index variables used for m_variables_conversion @@ -207,23 +303,35 @@ module m_global_parameters integer :: chemxb, chemxe !> @} - integer, allocatable, dimension(:,:,:) :: logic_grid - type(pres_field) :: pb - type(pres_field) :: mv - real(wp) :: Bx0 !< Constant magnetic field in the x-direction (1D) - integer :: buff_size !< Number of ghost cells for boundary condition storage - logical :: fft_wrt - logical :: dummy !< AMDFlang workaround for case-optimization + GPU-kernel bug + integer, allocatable, dimension(:, :, :) :: logic_grid + + type(pres_field) :: pb + type(pres_field) :: mv + + real(wp) :: Bx0 !< Constant magnetic field in the x-direction (1D) + + integer :: buff_size !< + !! The number of cells that are necessary to be able to store enough boundary + !! conditions data to march the solution in the physical computational domain + !! to the next time-step. + + logical :: fft_wrt + logical :: dummy !< AMDFlang workaround: keep a dummy logical to avoid a compiler case-optimization bug when a parameter+GPU-kernel conditional is false + + ! Variables for hardcoded initial conditions that are read from input files + character(LEN=2*path_len) :: interface_file + real(wp) :: normFac, normMag, g0_ic, p0_ic contains - !> Assigns default values to user inputs prior to reading them in. This allows for an easier consistency check of these - !! parameters once they are read from the input file. + !> Assigns default values to user inputs prior to reading + !! them in. This allows for an easier consistency check of + !! these parameters once they are read from the input file. impure subroutine s_assign_default_values_to_user_inputs - integer :: i !< Generic loop operator - ! Logistics + integer :: i !< Generic loop operator + ! Logistics case_dir = '.' old_grid = .false. old_ic = .false. @@ -329,15 +437,34 @@ contains simplex_params%perturb_vel(:) = .false. simplex_params%perturb_vel_freq(:) = dflt_real simplex_params%perturb_vel_scale(:) = dflt_real - simplex_params%perturb_vel_offset(:,:) = dflt_real + simplex_params%perturb_vel_offset(:, :) = dflt_real simplex_params%perturb_dens(:) = .false. simplex_params%perturb_dens_freq(:) = dflt_real simplex_params%perturb_dens_scale(:) = dflt_real - simplex_params%perturb_dens_offset(:,:) = dflt_real + simplex_params%perturb_dens_offset(:, :) = dflt_real ! Initial condition parameters num_patches = dflt_int + fd_order = dflt_int + lag_params%cluster_type = dflt_int + lag_params%pressure_corrector = .false. + lag_params%smooth_type = dflt_int + lag_params%heatTransfer_model = .false. + lag_params%massTransfer_model = .false. + lag_params%write_bubbles = .false. + lag_params%write_bubbles_stats = .false. + lag_params%write_void_evol = .false. + lag_params%pressure_force = .false. + lag_params%gravity_force = .false. + lag_params%nBubs_glb = dflt_int + lag_params%vel_model = dflt_int + lag_params%drag_model = dflt_int + lag_params%epsilonb = 1._wp + lag_params%charwidth = dflt_real + lag_params%charNz = dflt_int + lag_params%valmaxvoid = dflt_real + do i = 1, num_patches_max patch_icpp(i)%geometry = dflt_int patch_icpp(i)%model_scale(:) = 1._wp @@ -389,9 +516,9 @@ contains patch_icpp(i)%modal_clip_r_to_min = .false. patch_icpp(i)%modal_r_min = 1.e-12_wp patch_icpp(i)%modal_use_exp_form = .false. - patch_icpp(i)%sph_har_coeff(:,:) = 0._wp + patch_icpp(i)%sph_har_coeff(:, :) = 0._wp - ! should get all of r0's and v0's + !should get all of r0's and v0's patch_icpp(i)%r0 = dflt_real patch_icpp(i)%v0 = dflt_real @@ -533,8 +660,8 @@ contains bub_pp%gam_g = dflt_real; gam_g = dflt_real bub_pp%M_v = dflt_real; M_v = dflt_real bub_pp%M_g = dflt_real; M_g = dflt_real - bub_pp%k_v = dflt_real - bub_pp%k_g = dflt_real + bub_pp%k_v = dflt_real; + bub_pp%k_g = dflt_real; bub_pp%cp_v = dflt_real; cp_v = dflt_real bub_pp%cp_g = dflt_real; cp_g = dflt_real bub_pp%R_v = dflt_real; R_v = dflt_real @@ -542,27 +669,31 @@ contains end subroutine s_assign_default_values_to_user_inputs - !> Computation of parameters, allocation procedures, and/or any other tasks needed to properly setup the module + !> Computation of parameters, allocation procedures, and/or + !! any other tasks needed to properly setup the module impure subroutine s_initialize_global_parameters_module integer :: i, j, fac if (recon_type == WENO_TYPE) then weno_polyn = (weno_order - 1)/2 - else if (recon_type == MUSCL_TYPE) then + elseif (recon_type == MUSCL_TYPE) then muscl_polyn = muscl_order end if - ! Determining the layout of the state vectors and overall size of the system of equations, given the dimensionality and - ! choice of the equations of motion + ! Determining the layout of the state vectors and overall size of + ! the system of equations, given the dimensionality and choice of + ! the equations of motion ! Gamma/Pi_inf Model if (model_eqns == 1) then + ! Setting number of fluids num_fluids = 1 - ! Annotating structure of the state and flux vectors belonging to the system of equations defined by the selected number - ! of spatial dimensions and the gamma/pi_inf model + ! Annotating structure of the state and flux vectors belonging + ! to the system of equations defined by the selected number of + ! spatial dimensions and the gamma/pi_inf model cont_idx%beg = 1 cont_idx%end = cont_idx%beg mom_idx%beg = cont_idx%end + 1 @@ -576,8 +707,10 @@ contains ! Volume Fraction Model (5-equation model) else if (model_eqns == 2) then - ! Annotating structure of the state and flux vectors belonging to the system of equations defined by the selected number - ! of spatial dimensions and the volume fraction model + + ! Annotating structure of the state and flux vectors belonging + ! to the system of equations defined by the selected number of + ! spatial dimensions and the volume fraction model cont_idx%beg = 1 cont_idx%end = num_fluids mom_idx%beg = cont_idx%end + 1 @@ -585,14 +718,17 @@ contains E_idx = mom_idx%end + 1 if (igr) then - ! Volume fractions are stored in the indices immediately following the energy equation. IGR tracks a total of (N-1) - ! volume fractions for N fluids, hence the "-1" in adv_idx%end. If num_fluids = 1 then adv_idx%end < adv_idx%beg, - ! which skips all loops over the volume fractions since there is no volume fraction to track + ! Volume fractions are stored in the indices immediately following + ! the energy equation. IGR tracks a total of (N-1) volume fractions + ! for N fluids, hence the "-1" in adv_idx%end. If num_fluids = 1 + ! then adv_idx%end < adv_idx%beg, which skips all loops over the + ! volume fractions since there is no volume fraction to track adv_idx%beg = E_idx + 1 adv_idx%end = E_idx + num_fluids - 1 else - ! Volume fractions are stored in the indices immediately following the energy equation. WENO/MUSCL + Riemann tracks - ! a total of (N) volume fractions for N fluids, hence the lack of "-1" in adv_idx%end + ! Volume fractions are stored in the indices immediately following + ! the energy equation. WENO/MUSCL + Riemann tracks a total of (N) + ! volume fractions for N fluids, hence the lack of "-1" in adv_idx%end adv_idx%beg = E_idx + 1 adv_idx%end = E_idx + num_fluids end if @@ -609,7 +745,7 @@ contains bub_idx%beg = sys_size + 1 if (qbmm) then if (nnode == 4) then - nmom = 6 !< Already set as a parameter + nmom = 6 !! Already set as a parameter end if bub_idx%end = adv_idx%end + nb*nmom else @@ -631,7 +767,7 @@ contains if (qbmm) then allocate (bub_idx%moms(nb, nmom)) - allocate (bub_idx%fullmom(nb,0:nmom,0:nmom)) + allocate (bub_idx%fullmom(nb, 0:nmom, 0:nmom)) do i = 1, nb do j = 1, nmom @@ -667,17 +803,19 @@ contains if (mhd) then B_idx%beg = sys_size + 1 if (n == 0) then - B_idx%end = sys_size + 2 ! 1D: By, Bz + B_idx%end = sys_size + 2 ! 1D: By, Bz else - B_idx%end = sys_size + 3 ! 2D/3D: Bx, By, Bz + B_idx%end = sys_size + 3 ! 2D/3D: Bx, By, Bz end if sys_size = B_idx%end end if ! Volume Fraction Model (6-equation model) else if (model_eqns == 3) then - ! Annotating structure of the state and flux vectors belonging to the system of equations defined by the selected number - ! of spatial dimensions and the volume fraction model + + ! Annotating structure of the state and flux vectors belonging + ! to the system of equations defined by the selected number of + ! spatial dimensions and the volume fraction model cont_idx%beg = 1 cont_idx%end = num_fluids mom_idx%beg = cont_idx%end + 1 @@ -688,17 +826,18 @@ contains internalEnergies_idx%beg = adv_idx%end + 1 internalEnergies_idx%end = adv_idx%end + num_fluids sys_size = internalEnergies_idx%end + else if (model_eqns == 4) then ! 4 equation model with subgrid bubbles_euler - cont_idx%beg = 1 ! one continuity equation - cont_idx%end = 1 ! num_fluids - mom_idx%beg = cont_idx%end + 1 ! one momentum equation in each direction + cont_idx%beg = 1 ! one continuity equation + cont_idx%end = 1 ! num_fluids + mom_idx%beg = cont_idx%end + 1 ! one momentum equation in each direction mom_idx%end = cont_idx%end + num_vels - E_idx = mom_idx%end + 1 ! one energy equation + E_idx = mom_idx%end + 1 ! one energy equation adv_idx%beg = E_idx + 1 - adv_idx%end = adv_idx%beg ! one volume advection equation + adv_idx%end = adv_idx%beg !one volume advection equation alf_idx = adv_idx%end - sys_size = alf_idx ! adv_idx%end + sys_size = alf_idx !adv_idx%end if (bubbles_euler) then bub_idx%beg = sys_size + 1 @@ -739,10 +878,12 @@ contains rhoref = 1._wp pref = 1._wp end if + end if end if if (model_eqns == 2 .or. model_eqns == 3) then + if (hypoelasticity .or. hyperelasticity) then elasticity = .true. stress_idx%beg = sys_size + 1 @@ -758,16 +899,18 @@ contains shear_num = 1 shear_indices(1) = stress_idx%beg - 1 + 2 shear_BC_flip_num = 1 - shear_BC_flip_indices(1:2,1) = shear_indices(1) + shear_BC_flip_indices(1:2, 1) = shear_indices(1) ! Both x-dir and y-dir: flip tau_xy only else if (num_dims == 3) then shear_num = 3 shear_indices(1:3) = stress_idx%beg - 1 + (/2, 4, 5/) shear_BC_flip_num = 2 - shear_BC_flip_indices(1,1:2) = shear_indices((/1, 2/)) - shear_BC_flip_indices(2,1:2) = shear_indices((/1, 3/)) - shear_BC_flip_indices(3,1:2) = shear_indices((/2, 3/)) - ! x-dir: flip tau_xy and tau_xz y-dir: flip tau_xy and tau_yz z-dir: flip tau_xz and tau_yz + shear_BC_flip_indices(1, 1:2) = shear_indices((/1, 2/)) + shear_BC_flip_indices(2, 1:2) = shear_indices((/1, 3/)) + shear_BC_flip_indices(3, 1:2) = shear_indices((/2, 3/)) + ! x-dir: flip tau_xy and tau_xz + ! y-dir: flip tau_xy and tau_yz + ! z-dir: flip tau_xz and tau_yz end if end if @@ -795,6 +938,7 @@ contains psi_idx = sys_size + 1 sys_size = psi_idx end if + end if if (chemistry) then @@ -820,10 +964,16 @@ contains chemxb = species_idx%beg chemxe = species_idx%end - call s_configure_coordinate_bounds(recon_type, weno_polyn, muscl_polyn, igr_order, buff_size, idwint, idwbuff, viscous, & - & bubbles_lagrange, m, n, p, num_dims, igr, ib) + if (bubbles_lagrange) fd_number = max(1, fd_order/2) + + call s_configure_coordinate_bounds(recon_type, weno_polyn, muscl_polyn, & + igr_order, buff_size, & + idwint, idwbuff, viscous, & + bubbles_lagrange, m, n, p, & + num_dims, igr, ib, fd_number) #ifdef MFC_MPI + if (qbmm .and. .not. polytropic) then allocate (MPI_IO_DATA%view(1:sys_size + 2*nb*nnode)) allocate (MPI_IO_DATA%var(1:sys_size + 2*nb*nnode)) @@ -834,13 +984,13 @@ contains if (.not. down_sample) then do i = 1, sys_size - allocate (MPI_IO_DATA%var(i)%sf(0:m,0:n,0:p)) + allocate (MPI_IO_DATA%var(i)%sf(0:m, 0:n, 0:p)) MPI_IO_DATA%var(i)%sf => null() end do end if if (qbmm .and. .not. polytropic) then do i = sys_size + 1, sys_size + 2*nb*nnode - allocate (MPI_IO_DATA%var(i)%sf(0:m,0:n,0:p)) + allocate (MPI_IO_DATA%var(i)%sf(0:m, 0:n, 0:p)) MPI_IO_DATA%var(i)%sf => null() end do end if @@ -856,25 +1006,25 @@ contains end if end if - if (cyl_coord .neqv. .true.) then ! Cartesian grid + if (cyl_coord .neqv. .true.) then ! Cartesian grid grid_geometry = 1 - else if (cyl_coord .and. p == 0) then ! Axisymmetric cylindrical grid + elseif (cyl_coord .and. p == 0) then ! Axisymmetric cylindrical grid grid_geometry = 2 - else ! Fully 3D cylindrical grid + else ! Fully 3D cylindrical grid grid_geometry = 3 end if if (.not. igr) then - allocate (logic_grid(0:m,0:n,0:p)) + allocate (logic_grid(0:m, 0:n, 0:p)) end if end subroutine s_initialize_global_parameters_module - !> Configure MPI parallel I/O settings and allocate processor coordinate arrays. + !> @brief Configures MPI parallel I/O settings and allocates processor coordinate arrays. impure subroutine s_initialize_parallel_io #ifdef MFC_MPI - integer :: ierr !< Generic flag used to identify and report MPI errors + integer :: ierr !< Generic flag used to identify and report MPI errors #endif num_dims = 1 + min(1, n) + min(1, p) @@ -890,27 +1040,30 @@ contains if (parallel_io .neqv. .true.) return #ifdef MFC_MPI + ! Option for Lustre file system (Darter/Comet/Stampede) write (mpiiofs, '(A)') '/lustre_' mpiiofs = trim(mpiiofs) call MPI_INFO_CREATE(mpi_info_int, ierr) call MPI_INFO_SET(mpi_info_int, 'romio_ds_write', 'disable', ierr) - ! Option for UNIX file system (Hooke/Thomson) WRITE(mpiiofs, '(A)') '/ufs_' mpiiofs = TRIM(mpiiofs) mpi_info_int = - ! MPI_INFO_NULL + ! Option for UNIX file system (Hooke/Thomson) + ! WRITE(mpiiofs, '(A)') '/ufs_' + ! mpiiofs = TRIM(mpiiofs) + ! mpi_info_int = MPI_INFO_NULL allocate (start_idx(1:num_dims)) + #endif end subroutine s_initialize_parallel_io - !> Deallocate all global grid, index, and equation-of-state parameter arrays. + !> @brief Deallocates all global grid, index, and equation-of-state parameter arrays. impure subroutine s_finalize_global_parameters_module integer :: i ! Deallocating grid variables for the x-direction - deallocate (x_cc, x_cb) ! Deallocating grid variables for the y- and z-directions if (n > 0) then @@ -923,6 +1076,7 @@ contains deallocate (proc_coords) #ifdef MFC_MPI + if (parallel_io) then deallocate (start_idx) do i = 1, sys_size @@ -932,8 +1086,11 @@ contains deallocate (MPI_IO_DATA%var) deallocate (MPI_IO_DATA%view) end if + #endif + if (allocated(neighbor_ranks)) deallocate (neighbor_ranks) + end subroutine s_finalize_global_parameters_module end module m_global_parameters diff --git a/src/pre_process/m_grid.f90 b/src/pre_process/m_grid.f90 index 77cb02cef2..6ea71bd592 100644 --- a/src/pre_process/m_grid.f90 +++ b/src/pre_process/m_grid.f90 @@ -5,39 +5,52 @@ !> @brief Generates uniform or stretched rectilinear grids with hyperbolic-tangent spacing module m_grid - use m_derived_types ! Definitions of the derived types - use m_global_parameters ! Global parameters for the code - use m_mpi_proxy ! Message passing interface (MPI) module proxy - use m_helper_basic + use m_derived_types ! Definitions of the derived types + + use m_global_parameters ! Global parameters for the code + + use m_mpi_proxy ! Message passing interface (MPI) module proxy + + use m_helper_basic !< Functions to compare floating point numbers + #ifdef MFC_MPI - use mpi ! Message passing interface (MPI) module + use mpi ! Message passing interface (MPI) module #endif implicit none - private - public :: s_initialize_grid_module, s_generate_grid, s_generate_serial_grid, s_generate_parallel_grid, s_finalize_grid_module + private; + public :: s_initialize_grid_module, & + s_generate_grid, & + s_generate_serial_grid, & + s_generate_parallel_grid, & + s_finalize_grid_module abstract interface - !> Abstract interface for generating a rectilinear computational grid. + !> @brief Abstract interface for generating a rectilinear computational grid. impure subroutine s_generate_abstract_grid end subroutine s_generate_abstract_grid + end interface procedure(s_generate_abstract_grid), pointer :: s_generate_grid => null() contains - !> Generate a uniform or stretched rectilinear grid in serial from user parameters. + !> The following subroutine generates either a uniform or + !! non-uniform rectilinear grid in serial, defined by the parameters + !! inputted by the user. The grid information is stored in + !! the grid variables containing coordinates of the cell- + !! centers and cell-boundaries. impure subroutine s_generate_serial_grid ! Generic loop iterator - integer :: i, j !< generic loop operators - real(wp) :: length !< domain lengths - ! Uniform grid: dx = (x_end - x_beg) / (m + 1) + integer :: i, j !< generic loop operators + real(wp) :: length !< domain lengths + ! Grid Generation in the x-direction dx = (x_domain%end - x_domain%beg)/real(m + 1, wp) do i = 0, m @@ -47,8 +60,8 @@ impure subroutine s_generate_serial_grid x_cb(m) = x_domain%end - ! Hyperbolic tangent grid stretching if (stretch_x) then + length = abs(x_cb(m) - x_cb(-1)) x_cb = x_cb/length x_a = x_a/length @@ -56,8 +69,10 @@ impure subroutine s_generate_serial_grid do j = 1, loops_x do i = -1, m - x_cb(i) = x_cb(i)/a_x*(a_x + log(cosh(a_x*(x_cb(i) - x_a))) + log(cosh(a_x*(x_cb(i) - x_b))) & - & - 2._wp*log(cosh(a_x*(x_b - x_a)/2._wp))) + x_cb(i) = x_cb(i)/a_x* & + (a_x + log(cosh(a_x*(x_cb(i) - x_a))) & + + log(cosh(a_x*(x_cb(i) - x_b))) & + - 2._wp*log(cosh(a_x*(x_b - x_a)/2._wp))) end do end do x_cb = x_cb*length @@ -67,13 +82,15 @@ impure subroutine s_generate_serial_grid dx = minval(x_cb(0:m) - x_cb(-1:m - 1)) print *, 'Stretched grid: min/max x grid: ', minval(x_cc(:)), maxval(x_cc(:)) if (num_procs > 1) call s_mpi_reduce_min(dx) + end if ! Grid Generation in the y-direction if (n == 0) return - ! Axisymmetric cylindrical grid (r, z): half-cell offset at r=0 axis if (grid_geometry == 2 .and. f_approx_equal(y_domain%beg, 0.0_wp)) then + !IF (grid_geometry == 2) THEN + dy = (y_domain%end - y_domain%beg)/real(2*n + 1, wp) y_cc(0) = y_domain%beg + 5.e-1_wp*dy @@ -83,19 +100,22 @@ impure subroutine s_generate_serial_grid y_cc(i) = y_domain%beg + 2._wp*dy*real(i, wp) y_cb(i - 1) = y_domain%beg + dy*real(2*i - 1, wp) end do + else + dy = (y_domain%end - y_domain%beg)/real(n + 1, wp) do i = 0, n y_cc(i) = y_domain%beg + 5.e-1_wp*dy*real(2*i + 1, wp) y_cb(i - 1) = y_domain%beg + dy*real(i, wp) end do + end if y_cb(n) = y_domain%end - ! Hyperbolic tangent grid stretching in y-direction if (stretch_y) then + length = abs(y_cb(n) - y_cb(-1)) y_cb = y_cb/length y_a = y_a/length @@ -103,8 +123,10 @@ impure subroutine s_generate_serial_grid do j = 1, loops_y do i = -1, n - y_cb(i) = y_cb(i)/a_y*(a_y + log(cosh(a_y*(y_cb(i) - y_a))) + log(cosh(a_y*(y_cb(i) - y_b))) & - & - 2._wp*log(cosh(a_y*(y_b - y_a)/2._wp))) + y_cb(i) = y_cb(i)/a_y* & + (a_y + log(cosh(a_y*(y_cb(i) - y_a))) & + + log(cosh(a_y*(y_cb(i) - y_b))) & + - 2._wp*log(cosh(a_y*(y_b - y_a)/2._wp))) end do end do @@ -114,6 +136,7 @@ impure subroutine s_generate_serial_grid dy = minval(y_cb(0:n) - y_cb(-1:n - 1)) if (num_procs > 1) call s_mpi_reduce_min(dy) + end if ! Grid Generation in the z-direction @@ -128,8 +151,8 @@ impure subroutine s_generate_serial_grid z_cb(p) = z_domain%end - ! Hyperbolic tangent grid stretching in z-direction if (stretch_z) then + length = abs(z_cb(p) - z_cb(-1)) z_cb = z_cb/length z_a = z_a/length @@ -137,8 +160,10 @@ impure subroutine s_generate_serial_grid do j = 1, loops_z do i = -1, p - z_cb(i) = z_cb(i)/a_z*(a_z + log(cosh(a_z*(z_cb(i) - z_a))) + log(cosh(a_z*(z_cb(i) - z_b))) & - & - 2._wp*log(cosh(a_z*(z_b - z_a)/2._wp))) + z_cb(i) = z_cb(i)/a_z* & + (a_z + log(cosh(a_z*(z_cb(i) - z_a))) & + + log(cosh(a_z*(z_cb(i) - z_b))) & + - 2._wp*log(cosh(a_z*(z_b - z_a)/2._wp))) end do end do @@ -148,33 +173,44 @@ impure subroutine s_generate_serial_grid dz = minval(z_cb(0:p) - z_cb(-1:p - 1)) if (num_procs > 1) call s_mpi_reduce_min(dz) + end if end subroutine s_generate_serial_grid - !> Generate a uniform or stretched rectilinear grid in parallel from user parameters. + !> The following subroutine generates either a uniform or + !! non-uniform rectilinear grid in parallel, defined by the parameters + !! inputted by the user. The grid information is stored in + !! the grid variables containing coordinates of the cell- + !! centers and cell-boundaries. impure subroutine s_generate_parallel_grid #ifdef MFC_MPI - real(wp) :: length !< domain lengths + + real(wp) :: length !< domain lengths + ! Locations of cell boundaries - real(wp), allocatable, dimension(:) :: x_cb_glb, y_cb_glb, z_cb_glb !< Locations of cell boundaries - character(LEN=path_len + name_len) :: file_loc !< Generic string used to store the address of a file - integer :: ifile, ierr, data_size + real(wp), allocatable, dimension(:) :: x_cb_glb, y_cb_glb, z_cb_glb !< + !! Locations of cell boundaries + + character(LEN=path_len + name_len) :: file_loc !< + !! Generic string used to store the address of a file + + integer :: ifile, ierr, data_size integer, dimension(MPI_STATUS_SIZE) :: status - integer :: i, j !< Generic loop integers + + integer :: i, j !< Generic loop integers allocate (x_cb_glb(-1:m_glb)) allocate (y_cb_glb(-1:n_glb)) allocate (z_cb_glb(-1:p_glb)) - ! Uniform grid: dx = (x_end - x_beg) / (m_glb + 1) + ! Grid generation in the x-direction dx = (x_domain%end - x_domain%beg)/real(m_glb + 1, wp) do i = 0, m_glb x_cb_glb(i - 1) = x_domain%beg + dx*real(i, wp) end do x_cb_glb(m_glb) = x_domain%end - ! Hyperbolic tangent grid stretching in x-direction (parallel version) if (stretch_x) then length = abs(x_cb_glb(m_glb) - x_cb_glb(-1)) @@ -185,17 +221,20 @@ impure subroutine s_generate_parallel_grid do j = 1, loops_x do i = -1, m_glb - x_cb_glb(i) = x_cb_glb(i)/a_x*(a_x + log(cosh(a_x*(x_cb_glb(i) - x_a))) + log(cosh(a_x*(x_cb_glb(i) - x_b))) & - & - 2._wp*log(cosh(a_x*(x_b - x_a)/2._wp))) + x_cb_glb(i) = x_cb_glb(i)/a_x* & + (a_x + log(cosh(a_x*(x_cb_glb(i) - x_a))) & + + log(cosh(a_x*(x_cb_glb(i) - x_b))) & + - 2._wp*log(cosh(a_x*(x_b - x_a)/2._wp))) end do end do x_cb_glb = x_cb_glb*length + end if ! Grid generation in the y-direction if (n_glb > 0) then - ! Axisymmetric cylindrical grid (r, z): half-cell offset at r=0 axis + if (grid_geometry == 2 .and. f_approx_equal(y_domain%beg, 0.0_wp)) then dy = (y_domain%end - y_domain%beg)/real(2*n_glb + 1, wp) y_cb_glb(-1) = y_domain%beg @@ -219,12 +258,15 @@ impure subroutine s_generate_parallel_grid do j = 1, loops_y do i = -1, n_glb - y_cb_glb(i) = y_cb_glb(i)/a_y*(a_y + log(cosh(a_y*(y_cb_glb(i) - y_a))) + log(cosh(a_y*(y_cb_glb(i) - y_b) & - & )) - 2._wp*log(cosh(a_y*(y_b - y_a)/2._wp))) + y_cb_glb(i) = y_cb_glb(i)/a_y* & + (a_y + log(cosh(a_y*(y_cb_glb(i) - y_a))) & + + log(cosh(a_y*(y_cb_glb(i) - y_b))) & + - 2._wp*log(cosh(a_y*(y_b - y_a)/2._wp))) end do end do y_cb_glb = y_cb_glb*length + end if ! Grid generation in the z-direction @@ -243,45 +285,53 @@ impure subroutine s_generate_parallel_grid do j = 1, loops_z do i = -1, p_glb - z_cb_glb(i) = z_cb_glb(i)/a_z*(a_z + log(cosh(a_z*(z_cb_glb(i) - z_a))) + log(cosh(a_z*(z_cb_glb(i) & - & - z_b))) - 2._wp*log(cosh(a_z*(z_b - z_a)/2._wp))) + z_cb_glb(i) = z_cb_glb(i)/a_z* & + (a_z + log(cosh(a_z*(z_cb_glb(i) - z_a))) & + + log(cosh(a_z*(z_cb_glb(i) - z_b))) & + - 2._wp*log(cosh(a_z*(z_b - z_a)/2._wp))) end do end do z_cb_glb = z_cb_glb*length + end if end if end if ! Write cell boundary locations to grid data files - file_loc = trim(case_dir) // '/restart_data' // trim(mpiiofs) // 'x_cb.dat' + file_loc = trim(case_dir)//'/restart_data'//trim(mpiiofs)//'x_cb.dat' data_size = m_glb + 2 - call MPI_FILE_OPEN(MPI_COMM_SELF, file_loc, ior(MPI_MODE_WRONLY, MPI_MODE_CREATE), mpi_info_int, ifile, ierr) + call MPI_FILE_OPEN(MPI_COMM_SELF, file_loc, ior(MPI_MODE_WRONLY, MPI_MODE_CREATE), & + mpi_info_int, ifile, ierr) call MPI_FILE_WRITE(ifile, x_cb_glb, data_size, mpi_p, status, ierr) call MPI_FILE_CLOSE(ifile, ierr) if (n > 0) then - file_loc = trim(case_dir) // '/restart_data' // trim(mpiiofs) // 'y_cb.dat' + file_loc = trim(case_dir)//'/restart_data'//trim(mpiiofs)//'y_cb.dat' data_size = n_glb + 2 - call MPI_FILE_OPEN(MPI_COMM_SELF, file_loc, ior(MPI_MODE_WRONLY, MPI_MODE_CREATE), mpi_info_int, ifile, ierr) + call MPI_FILE_OPEN(MPI_COMM_SELF, file_loc, ior(MPI_MODE_WRONLY, MPI_MODE_CREATE), & + mpi_info_int, ifile, ierr) call MPI_FILE_WRITE(ifile, y_cb_glb, data_size, mpi_p, status, ierr) call MPI_FILE_CLOSE(ifile, ierr) if (p > 0) then - file_loc = trim(case_dir) // '/restart_data' // trim(mpiiofs) // 'z_cb.dat' + file_loc = trim(case_dir)//'/restart_data'//trim(mpiiofs)//'z_cb.dat' data_size = p_glb + 2 - call MPI_FILE_OPEN(MPI_COMM_SELF, file_loc, ior(MPI_MODE_WRONLY, MPI_MODE_CREATE), mpi_info_int, ifile, ierr) + call MPI_FILE_OPEN(MPI_COMM_SELF, file_loc, ior(MPI_MODE_WRONLY, MPI_MODE_CREATE), & + mpi_info_int, ifile, ierr) call MPI_FILE_WRITE(ifile, z_cb_glb, data_size, mpi_p, status, ierr) call MPI_FILE_CLOSE(ifile, ierr) end if end if deallocate (x_cb_glb, y_cb_glb, z_cb_glb) + #endif end subroutine s_generate_parallel_grid - !> Computation of parameters, allocation procedures, and/or any other tasks needed to properly setup the module + !> Computation of parameters, allocation procedures, and/or + !! any other tasks needed to properly setup the module impure subroutine s_initialize_grid_module if (parallel_io .neqv. .true.) then diff --git a/src/pre_process/m_icpp_patches.fpp b/src/pre_process/m_icpp_patches.fpp index a565a1b0b3..25a88f36f9 100644 --- a/src/pre_process/m_icpp_patches.fpp +++ b/src/pre_process/m_icpp_patches.fpp @@ -12,49 +12,77 @@ !> @brief Constructs initial condition patch geometries (lines, circles, rectangles, spheres, etc.) on the grid module m_icpp_patches - use m_model ! Subroutine(s) related to STL files - use m_derived_types ! Definitions of the derived types - use m_global_parameters + use m_model ! Subroutine(s) related to STL files + + use m_derived_types ! Definitions of the derived types + + use m_global_parameters !< Definitions of the global parameters + use m_constants, only: max_2d_fourier_modes, max_sph_harm_degree, small_radius - use m_helper_basic + + use m_helper_basic !< Functions to compare floating point numbers + use m_helper + use m_mpi_common + use m_assign_variables + use m_mpi_common + use m_variables_conversion implicit none private; public :: s_apply_icpp_patches - real(wp) :: x_centroid, y_centroid, z_centroid - real(wp) :: length_x, length_y, length_z - integer :: smooth_patch_id - real(wp) :: smooth_coeff !< Smoothing coefficient (mirrors ic_patch_parameters%smooth_coeff) - real(wp) :: eta !< Pseudo volume fraction for patch boundary smoothing - real(wp) :: cart_x, cart_y, cart_z - real(wp) :: sph_phi !< Spherical phi for Cartesian conversion in cylindrical coordinates - type(bounds_info) :: x_boundary, y_boundary, z_boundary !< Patch boundary locations in x, y, z - character(len=5) :: istr !< string to store int to string result for error checking + real(wp) :: x_centroid, y_centroid, z_centroid + real(wp) :: length_x, length_y, length_z + + integer :: smooth_patch_id + real(wp) :: smooth_coeff !< + !! These variables are analogous in both meaning and use to the similarly + !! named components in the ic_patch_parameters type (see m_derived_types.f90 + !! for additional details). They are employed as a means to more concisely + !! perform the actions necessary to lay out a particular patch on the grid. + + real(wp) :: eta !< + !! In the case that smoothing of patch boundaries is enabled and the boundary + !! between two adjacent patches is to be smeared out, this variable's purpose + !! is to act as a pseudo volume fraction to indicate the contribution of each + !! patch toward the composition of a cell's fluid state. + + real(wp) :: cart_x, cart_y, cart_z + real(wp) :: sph_phi !< + !! Variables to be used to hold cell locations in Cartesian coordinates if + !! 3D simulation is using cylindrical coordinates + + type(bounds_info) :: x_boundary, y_boundary, z_boundary !< + !! These variables combine the centroid and length parameters associated with + !! a particular patch to yield the locations of the patch boundaries in the + !! x-, y- and z-coordinate directions. They are used as a means to concisely + !! perform the actions necessary to lay out a particular patch on the grid. + + character(len=5) :: istr ! string to store int to string result for error checking contains - !> Dispatch each initial condition patch to its geometry-specific initialization routine. + !> @brief Dispatches each initial condition patch to its geometry-specific initialization routine. impure subroutine s_apply_icpp_patches(patch_id_fp, q_prim_vf) type(scalar_field), dimension(1:sys_size), intent(inout) :: q_prim_vf - #ifdef MFC_MIXED_PRECISION - integer(kind=1), dimension(0:m,0:n,0:p), intent(inout) :: patch_id_fp + integer(kind=1), dimension(0:m, 0:n, 0:p), intent(inout) :: patch_id_fp #else - integer, dimension(0:m,0:n,0:p), intent(inout) :: patch_id_fp + integer, dimension(0:m, 0:n, 0:p), intent(inout) :: patch_id_fp #endif integer :: i ! 3D Patch Geometries - if (p > 0) then + do i = 1, num_patches + if (proc_rank == 0) then print *, 'Processing patch', i end if @@ -65,33 +93,35 @@ contains if (patch_icpp(i)%geometry == 8) then call s_icpp_sphere(i, patch_id_fp, q_prim_vf) ! Cuboidal patch - else if (patch_icpp(i)%geometry == 9) then + elseif (patch_icpp(i)%geometry == 9) then call s_icpp_cuboid(i, patch_id_fp, q_prim_vf) ! Cylindrical patch - else if (patch_icpp(i)%geometry == 10) then + elseif (patch_icpp(i)%geometry == 10) then call s_icpp_cylinder(i, patch_id_fp, q_prim_vf) ! Swept plane patch - else if (patch_icpp(i)%geometry == 11) then + elseif (patch_icpp(i)%geometry == 11) then call s_icpp_sweep_plane(i, patch_id_fp, q_prim_vf) ! Ellipsoidal patch - else if (patch_icpp(i)%geometry == 12) then + elseif (patch_icpp(i)%geometry == 12) then call s_icpp_ellipsoid(i, patch_id_fp, q_prim_vf) ! 3D spherical harmonic patch - else if (patch_icpp(i)%geometry == 14) then + elseif (patch_icpp(i)%geometry == 14) then call s_icpp_3d_spherical_harmonic(i, patch_id_fp, q_prim_vf) ! 3D Modified circular patch - else if (patch_icpp(i)%geometry == 19) then + elseif (patch_icpp(i)%geometry == 19) then call s_icpp_3dvarcircle(i, patch_id_fp, q_prim_vf) ! 3D STL patch - else if (patch_icpp(i)%geometry == 21) then + elseif (patch_icpp(i)%geometry == 21) then call s_icpp_model(i, patch_id_fp, q_prim_vf) end if end do !> @} ! 2D Patch Geometries - else if (n > 0) then + elseif (n > 0) then + do i = 1, num_patches + if (proc_rank == 0) then print *, 'Processing patch', i end if @@ -102,32 +132,32 @@ contains if (patch_icpp(i)%geometry == 2) then call s_icpp_circle(i, patch_id_fp, q_prim_vf) ! Rectangular patch - else if (patch_icpp(i)%geometry == 3) then + elseif (patch_icpp(i)%geometry == 3) then call s_icpp_rectangle(i, patch_id_fp, q_prim_vf) ! Swept line patch - else if (patch_icpp(i)%geometry == 4) then + elseif (patch_icpp(i)%geometry == 4) then call s_icpp_sweep_line(i, patch_id_fp, q_prim_vf) ! Elliptical patch - else if (patch_icpp(i)%geometry == 5) then + elseif (patch_icpp(i)%geometry == 5) then call s_icpp_ellipse(i, patch_id_fp, q_prim_vf) ! Unimplemented patch (formerly isentropic vortex) - else if (patch_icpp(i)%geometry == 6) then - call s_mpi_abort('This used to be the isentropic vortex patch, ' & - & // 'which no longer exists. See Examples. Exiting.') + elseif (patch_icpp(i)%geometry == 6) then + call s_mpi_abort('This used to be the isentropic vortex patch, '// & + 'which no longer exists. See Examples. Exiting.') ! 2D modal (Fourier) patch - else if (patch_icpp(i)%geometry == 13) then + elseif (patch_icpp(i)%geometry == 13) then call s_icpp_2d_modal(i, patch_id_fp, q_prim_vf) ! Spiral patch - else if (patch_icpp(i)%geometry == 17) then + elseif (patch_icpp(i)%geometry == 17) then call s_icpp_spiral(i, patch_id_fp, q_prim_vf) ! Modified circular patch - else if (patch_icpp(i)%geometry == 18) then + elseif (patch_icpp(i)%geometry == 18) then call s_icpp_varcircle(i, patch_id_fp, q_prim_vf) ! TaylorGreen vortex patch - else if (patch_icpp(i)%geometry == 20) then + elseif (patch_icpp(i)%geometry == 20) then call s_icpp_2D_TaylorGreen_vortex(i, patch_id_fp, q_prim_vf) ! STL patch - else if (patch_icpp(i)%geometry == 21) then + elseif (patch_icpp(i)%geometry == 21) then call s_icpp_model(i, patch_id_fp, q_prim_vf) end if !> @} @@ -135,7 +165,9 @@ contains ! 1D Patch Geometries else + do i = 1, num_patches + if (proc_rank == 0) then print *, 'Processing patch', i end if @@ -144,25 +176,31 @@ contains if (patch_icpp(i)%geometry == 1) then call s_icpp_line_segment(i, patch_id_fp, q_prim_vf) ! 1d analytical - else if (patch_icpp(i)%geometry == 16) then + elseif (patch_icpp(i)%geometry == 16) then call s_icpp_1d_bubble_pulse(i, patch_id_fp, q_prim_vf) end if end do + end if end subroutine s_apply_icpp_patches - !> The line segment patch is a 1D geometry that may be used, for example, in creating a Riemann problem. The geometry of the - !! patch is well-defined when its centroid and length in the x-coordinate direction are provided. Note that the line segment - !! patch DOES NOT allow for the smearing of its boundaries. + !> The line segment patch is a 1D geometry that may be used, + !! for example, in creating a Riemann problem. The geometry + !! of the patch is well-defined when its centroid and length + !! in the x-coordinate direction are provided. Note that the + !! line segment patch DOES NOT allow for the smearing of its + !! boundaries. + !! @param patch_id patch identifier + !! @param patch_id_fp Array to track patch ids + !! @param q_prim_vf Array of primitive variables subroutine s_icpp_line_segment(patch_id, patch_id_fp, q_prim_vf) integer, intent(in) :: patch_id - #ifdef MFC_MIXED_PRECISION - integer(kind=1), dimension(0:m,0:n,0:p), intent(inout) :: patch_id_fp + integer(kind=1), dimension(0:m, 0:n, 0:p), intent(inout) :: patch_id_fp #else - integer, dimension(0:m,0:n,0:p), intent(inout) :: patch_id_fp + integer, dimension(0:m, 0:n, 0:p), intent(inout) :: patch_id_fp #endif type(scalar_field), dimension(1:sys_size), intent(inout) :: q_prim_vf @@ -171,7 +209,6 @@ contains ! Placeholders for the cell boundary values real(wp) :: pi_inf, gamma, lit_gamma - @:HardcodedDimensionsExtrusion() @:Hardcoded1DVariables() @@ -185,18 +222,28 @@ contains x_centroid = patch_icpp(patch_id)%x_centroid length_x = patch_icpp(patch_id)%length_x - ! Computing the beginning and end x-coordinates of the line segment based on its centroid and length + ! Computing the beginning and end x-coordinates of the line segment + ! based on its centroid and length x_boundary%beg = x_centroid - 0.5_wp*length_x x_boundary%end = x_centroid + 0.5_wp*length_x - ! Set eta=1 (no smoothing for this patch type) + ! Since the line segment patch does not allow for its boundaries to + ! be smoothed out, the pseudo volume fraction is set to 1 to ensure + ! that only the current patch contributes to the fluid state in the + ! cells that this patch covers. eta = 1._wp - ! Assign patch vars if cell is covered and patch has write permission + ! Checking whether the line segment covers a particular cell in the + ! domain and verifying whether the current patch has the permission + ! to write to that cell. If both queries check out, the primitive + ! variables of the current patch are assigned to this cell. do i = 0, m - if (x_boundary%beg <= x_cc(i) .and. x_boundary%end >= x_cc(i) .and. patch_icpp(patch_id)%alter_patch(patch_id_fp(i, & - & 0, 0))) then - call s_assign_patch_primitive_variables(patch_id, i, 0, 0, eta, q_prim_vf, patch_id_fp) + if (x_boundary%beg <= x_cc(i) .and. & + x_boundary%end >= x_cc(i) .and. & + patch_icpp(patch_id)%alter_patch(patch_id_fp(i, 0, 0))) then + + call s_assign_patch_primitive_variables(patch_id, i, 0, 0, & + eta, q_prim_vf, patch_id_fp) @:analytical() @@ -207,32 +254,38 @@ contains ! Updating the patch identities bookkeeping variable if (1._wp - eta < sgm_eps) patch_id_fp(i, 0, 0) = patch_id + end if end do @:HardcodedDellacation() end subroutine s_icpp_line_segment - !> The spiral patch is a 2D geometry that may be used, The geometry of the patch is well-defined when its centroid and radius - !! are provided. Note that the circular patch DOES allow for the smoothing of its boundary. + !> The spiral patch is a 2D geometry that may be used, The geometry + !! of the patch is well-defined when its centroid and radius + !! are provided. Note that the circular patch DOES allow for + !! the smoothing of its boundary. + !! @param patch_id patch identifier + !! @param patch_id_fp Array to track patch ids + !! @param q_prim_vf Array of primitive variables impure subroutine s_icpp_spiral(patch_id, patch_id_fp, q_prim_vf) integer, intent(in) :: patch_id - #ifdef MFC_MIXED_PRECISION - integer(kind=1), dimension(0:m,0:n,0:p), intent(inout) :: patch_id_fp + integer(kind=1), dimension(0:m, 0:n, 0:p), intent(inout) :: patch_id_fp #else - integer, dimension(0:m,0:n,0:p), intent(inout) :: patch_id_fp + integer, dimension(0:m, 0:n, 0:p), intent(inout) :: patch_id_fp #endif type(scalar_field), dimension(1:sys_size), intent(inout) :: q_prim_vf - integer :: i, j, k !< Generic loop iterators - real(wp) :: th, thickness, nturns, mya - real(wp) :: spiral_x_min, spiral_x_max, spiral_y_min, spiral_y_max + integer :: i, j, k !< Generic loop iterators + real(wp) :: th, thickness, nturns, mya + real(wp) :: spiral_x_min, spiral_x_max, spiral_y_min, spiral_y_max @:HardcodedDimensionsExtrusion() @:Hardcoded2DVariables() - ! Transferring the circular patch's radius, centroid, smearing patch identity and smearing coefficient information + ! Transferring the circular patch's radius, centroid, smearing patch + ! identity and smearing coefficient information x_centroid = patch_icpp(patch_id)%x_centroid y_centroid = patch_icpp(patch_id)%y_centroid mya = patch_icpp(patch_id)%radius @@ -244,24 +297,29 @@ contains do k = 0, int(m*91*nturns) th = k/real(int(m*91._wp*nturns))*nturns*2._wp*pi - spiral_x_min = minval((/f_r(th, 0.0_wp, mya)*cos(th), f_r(th, thickness, mya)*cos(th)/)) - spiral_y_min = minval((/f_r(th, 0.0_wp, mya)*sin(th), f_r(th, thickness, mya)*sin(th)/)) + spiral_x_min = minval((/f_r(th, 0.0_wp, mya)*cos(th), & + f_r(th, thickness, mya)*cos(th)/)) + spiral_y_min = minval((/f_r(th, 0.0_wp, mya)*sin(th), & + f_r(th, thickness, mya)*sin(th)/)) - spiral_x_max = maxval((/f_r(th, 0.0_wp, mya)*cos(th), f_r(th, thickness, mya)*cos(th)/)) - spiral_y_max = maxval((/f_r(th, 0.0_wp, mya)*sin(th), f_r(th, thickness, mya)*sin(th)/)) + spiral_x_max = maxval((/f_r(th, 0.0_wp, mya)*cos(th), & + f_r(th, thickness, mya)*cos(th)/)) + spiral_y_max = maxval((/f_r(th, 0.0_wp, mya)*sin(th), & + f_r(th, thickness, mya)*sin(th)/)) - do j = 0, n; do i = 0, m - if ((x_cc(i) > spiral_x_min) .and. (x_cc(i) < spiral_x_max) .and. (y_cc(j) > spiral_y_min) .and. (y_cc(j) & - & < spiral_y_max)) then - logic_grid(i, j, 0) = 1 - end if - end do; end do + do j = 0, n; do i = 0, m; + if ((x_cc(i) > spiral_x_min) .and. (x_cc(i) < spiral_x_max) .and. & + (y_cc(j) > spiral_y_min) .and. (y_cc(j) < spiral_y_max)) then + logic_grid(i, j, 0) = 1 + end if + end do; end do end do do j = 0, n do i = 0, m if ((logic_grid(i, j, 0) == 1)) then - call s_assign_patch_primitive_variables(patch_id, i, j, 0, eta, q_prim_vf, patch_id_fp) + call s_assign_patch_primitive_variables(patch_id, i, j, 0, & + eta, q_prim_vf, patch_id_fp) @:analytical() if (patch_icpp(patch_id)%hcid /= dflt_int) then @@ -277,26 +335,32 @@ contains end subroutine s_icpp_spiral - !> The circular patch is a 2D geometry that may be used, for example, in creating a bubble or a droplet. The geometry of the - !! patch is well-defined when its centroid and radius are provided. Note that the circular patch DOES allow for the smoothing of - !! its boundary. + !> The circular patch is a 2D geometry that may be used, for + !! example, in creating a bubble or a droplet. The geometry + !! of the patch is well-defined when its centroid and radius + !! are provided. Note that the circular patch DOES allow for + !! the smoothing of its boundary. + !! @param patch_id is the patch identifier + !! @param patch_id_fp Array to track patch ids + !! @param q_prim_vf Array of primitive variables subroutine s_icpp_circle(patch_id, patch_id_fp, q_prim_vf) integer, intent(in) :: patch_id - #ifdef MFC_MIXED_PRECISION - integer(kind=1), dimension(0:m,0:n,0:p), intent(inout) :: patch_id_fp + integer(kind=1), dimension(0:m, 0:n, 0:p), intent(inout) :: patch_id_fp #else - integer, dimension(0:m,0:n,0:p), intent(inout) :: patch_id_fp + integer, dimension(0:m, 0:n, 0:p), intent(inout) :: patch_id_fp #endif type(scalar_field), dimension(1:sys_size), intent(inout) :: q_prim_vf - real(wp) :: radius - integer :: i, j, k !< Generic loop iterators + real(wp) :: radius + + integer :: i, j, k !< Generic loop iterators @:HardcodedDimensionsExtrusion() @:Hardcoded2DVariables() - ! Transferring the circular patch's radius, centroid, smearing patch identity and smearing coefficient information + ! Transferring the circular patch's radius, centroid, smearing patch + ! identity and smearing coefficient information x_centroid = patch_icpp(patch_id)%x_centroid y_centroid = patch_icpp(patch_id)%y_centroid @@ -304,27 +368,44 @@ contains smooth_patch_id = patch_icpp(patch_id)%smooth_patch_id smooth_coeff = patch_icpp(patch_id)%smooth_coeff - ! Initialize eta=1; modified if smoothing is enabled + ! Initializing the pseudo volume fraction value to 1. The value will + ! be modified as the patch is laid out on the grid, but only in the + ! case that smoothing of the circular patch's boundary is enabled. eta = 1._wp - ! Assign patch vars if cell is covered and patch has write permission + ! Checking whether the circle covers a particular cell in the domain + ! and verifying whether the current patch has permission to write to + ! that cell. If both queries check out, the primitive variables of + ! the current patch are assigned to this cell. do j = 0, n do i = 0, m + if (patch_icpp(patch_id)%smoothen) then - ! Smooth Heaviside via hyperbolic tangent; smooth_coeff controls interface sharpness - eta = tanh(smooth_coeff/min(dx, & - & dy)*(sqrt((x_cc(i) - x_centroid)**2 + (y_cc(j) - y_centroid)**2) - radius))*(-0.5_wp) + 0.5_wp + + eta = tanh(smooth_coeff/min(dx, dy)* & + (sqrt((x_cc(i) - x_centroid)**2 & + + (y_cc(j) - y_centroid)**2) & + - radius))*(-0.5_wp) + 0.5_wp + end if - if (((x_cc(i) - x_centroid)**2 + (y_cc(j) - y_centroid)**2 <= radius**2 .and. patch_icpp(patch_id) & - & %alter_patch(patch_id_fp(i, j, 0))) .or. patch_id_fp(i, j, 0) == smooth_patch_id) then - call s_assign_patch_primitive_variables(patch_id, i, j, 0, eta, q_prim_vf, patch_id_fp) + if (((x_cc(i) - x_centroid)**2 & + + (y_cc(j) - y_centroid)**2 <= radius**2 & + .and. & + patch_icpp(patch_id)%alter_patch(patch_id_fp(i, j, 0))) & + .or. & + patch_id_fp(i, j, 0) == smooth_patch_id) & + then + + call s_assign_patch_primitive_variables(patch_id, i, j, 0, & + eta, q_prim_vf, patch_id_fp) @:analytical() if (patch_icpp(patch_id)%hcid /= dflt_int) then @:Hardcoded2D() end if + end if end do end do @@ -332,27 +413,30 @@ contains end subroutine s_icpp_circle - !> The varcircle patch is a 2D geometry that may be used . It generatres an annulus + !> The varcircle patch is a 2D geometry that may be used + !! . It generatres an annulus + !! @param patch_id is the patch identifier + !! @param patch_id_fp Array to track patch ids + !! @param q_prim_vf Array of primitive variables subroutine s_icpp_varcircle(patch_id, patch_id_fp, q_prim_vf) ! Patch identifier integer, intent(in) :: patch_id - #ifdef MFC_MIXED_PRECISION - integer(kind=1), dimension(0:m,0:n,0:p), intent(inout) :: patch_id_fp + integer(kind=1), dimension(0:m, 0:n, 0:p), intent(inout) :: patch_id_fp #else - integer, dimension(0:m,0:n,0:p), intent(inout) :: patch_id_fp + integer, dimension(0:m, 0:n, 0:p), intent(inout) :: patch_id_fp #endif type(scalar_field), dimension(1:sys_size), intent(inout) :: q_prim_vf ! Generic loop iterators - integer :: i, j, k + integer :: i, j, k real(wp) :: radius, myr, thickness - @:HardcodedDimensionsExtrusion() @:Hardcoded2DVariables() - ! Transferring the circular patch's radius, centroid, smearing patch identity and smearing coefficient information + ! Transferring the circular patch's radius, centroid, smearing patch + ! identity and smearing coefficient information x_centroid = patch_icpp(patch_id)%x_centroid y_centroid = patch_icpp(patch_id)%y_centroid radius = patch_icpp(patch_id)%radius @@ -360,17 +444,26 @@ contains smooth_coeff = patch_icpp(patch_id)%smooth_coeff thickness = patch_icpp(patch_id)%epsilon - ! Initialize eta=1; modified if smoothing is enabled + ! Initializing the pseudo volume fraction value to 1. The value will + ! be modified as the patch is laid out on the grid, but only in the + ! case that smoothing of the circular patch's boundary is enabled. eta = 1._wp - ! Assign patch vars if cell is covered and patch has write permission + ! Checking whether the circle covers a particular cell in the domain + ! and verifying whether the current patch has permission to write to + ! that cell. If both queries check out, the primitive variables of + ! the current patch are assigned to this cell. do j = 0, n do i = 0, m - myr = sqrt((x_cc(i) - x_centroid)**2 + (y_cc(j) - y_centroid)**2) + myr = sqrt((x_cc(i) - x_centroid)**2 & + + (y_cc(j) - y_centroid)**2) - if (myr <= radius + thickness/2._wp .and. myr >= radius - thickness/2._wp .and. patch_icpp(patch_id) & - & %alter_patch(patch_id_fp(i, j, 0))) then - call s_assign_patch_primitive_variables(patch_id, i, j, 0, eta, q_prim_vf, patch_id_fp) + if (myr <= radius + thickness/2._wp .and. & + myr >= radius - thickness/2._wp .and. & + patch_icpp(patch_id)%alter_patch(patch_id_fp(i, j, 0))) then + + call s_assign_patch_primitive_variables(patch_id, i, j, 0, & + eta, q_prim_vf, patch_id_fp) @:analytical() if (patch_icpp(patch_id)%hcid /= dflt_int) then @@ -380,36 +473,39 @@ contains ! Updating the patch identities bookkeeping variable if (1._wp - eta < sgm_eps) patch_id_fp(i, j, 0) = patch_id - q_prim_vf(alf_idx)%sf(i, j, & - & 0) = patch_icpp(patch_id)%alpha(1)*exp(-0.5_wp*((myr - radius)**2._wp)/(thickness/3._wp)**2._wp) + q_prim_vf(alf_idx)%sf(i, j, 0) = patch_icpp(patch_id)%alpha(1)* & + exp(-0.5_wp*((myr - radius)**2._wp)/(thickness/3._wp)**2._wp) end if + end do end do @:HardcodedDellacation() end subroutine s_icpp_varcircle - !> Initialize a 3D variable-thickness circular annulus patch extruded along the z-axis. + !> @brief Initializes a 3D variable-thickness circular annulus patch extruded along the z-axis. + !! @param patch_id is the patch identifier + !! @param patch_id_fp Array to track patch ids + !! @param q_prim_vf Array of primitive variables subroutine s_icpp_3dvarcircle(patch_id, patch_id_fp, q_prim_vf) ! Patch identifier integer, intent(in) :: patch_id - #ifdef MFC_MIXED_PRECISION - integer(kind=1), dimension(0:m,0:n,0:p), intent(inout) :: patch_id_fp + integer(kind=1), dimension(0:m, 0:n, 0:p), intent(inout) :: patch_id_fp #else - integer, dimension(0:m,0:n,0:p), intent(inout) :: patch_id_fp + integer, dimension(0:m, 0:n, 0:p), intent(inout) :: patch_id_fp #endif type(scalar_field), dimension(1:sys_size), intent(inout) :: q_prim_vf ! Generic loop iterators - integer :: i, j, k + integer :: i, j, k real(wp) :: radius, myr, thickness - @:HardcodedDimensionsExtrusion() @:Hardcoded3DVariables() - ! Transferring the circular patch's radius, centroid, smearing patch identity and smearing coefficient information + ! Transferring the circular patch's radius, centroid, smearing patch + ! identity and smearing coefficient information x_centroid = patch_icpp(patch_id)%x_centroid y_centroid = patch_icpp(patch_id)%y_centroid z_centroid = patch_icpp(patch_id)%z_centroid @@ -419,20 +515,29 @@ contains smooth_coeff = patch_icpp(patch_id)%smooth_coeff thickness = patch_icpp(patch_id)%epsilon - ! Initialize eta=1; modified if smoothing is enabled + ! Initializing the pseudo volume fraction value to 1. The value will + ! be modified as the patch is laid out on the grid, but only in the + ! case that smoothing of the circular patch's boundary is enabled. eta = 1._wp ! write for all z - ! Assign patch vars if cell is covered and patch has write permission + ! Checking whether the circle covers a particular cell in the domain + ! and verifying whether the current patch has permission to write to + ! that cell. If both queries check out, the primitive variables of + ! the current patch are assigned to this cell. do k = 0, p do j = 0, n do i = 0, m - myr = sqrt((x_cc(i) - x_centroid)**2 + (y_cc(j) - y_centroid)**2) + myr = sqrt((x_cc(i) - x_centroid)**2 & + + (y_cc(j) - y_centroid)**2) - if (myr <= radius + thickness/2._wp .and. myr >= radius - thickness/2._wp .and. patch_icpp(patch_id) & - & %alter_patch(patch_id_fp(i, j, k))) then - call s_assign_patch_primitive_variables(patch_id, i, j, k, eta, q_prim_vf, patch_id_fp) + if (myr <= radius + thickness/2._wp .and. & + myr >= radius - thickness/2._wp .and. & + patch_icpp(patch_id)%alter_patch(patch_id_fp(i, j, k))) then + + call s_assign_patch_primitive_variables(patch_id, i, j, k, & + eta, q_prim_vf, patch_id_fp) @:analytical() if (patch_icpp(patch_id)%hcid /= dflt_int) then @@ -442,9 +547,10 @@ contains ! Updating the patch identities bookkeeping variable if (1._wp - eta < sgm_eps) patch_id_fp(i, j, k) = patch_id - q_prim_vf(alf_idx)%sf(i, j, & - & k) = patch_icpp(patch_id)%alpha(1)*exp(-0.5_wp*((myr - radius)**2._wp)/(thickness/3._wp)**2._wp) + q_prim_vf(alf_idx)%sf(i, j, k) = patch_icpp(patch_id)%alpha(1)* & + exp(-0.5_wp*((myr - radius)**2._wp)/(thickness/3._wp)**2._wp) end if + end do end do end do @@ -452,25 +558,30 @@ contains end subroutine s_icpp_3dvarcircle - !> The elliptical patch is a 2D geometry. The geometry of the patch is well-defined when its centroid and radii are provided. - !! Note that the elliptical patch DOES allow for the smoothing of its boundary + !> The elliptical patch is a 2D geometry. The geometry of + !! the patch is well-defined when its centroid and radii + !! are provided. Note that the elliptical patch DOES allow + !! for the smoothing of its boundary + !! @param patch_id is the patch identifier + !! @param patch_id_fp Array to track patch ids + !! @param q_prim_vf Array of primitive variables subroutine s_icpp_ellipse(patch_id, patch_id_fp, q_prim_vf) integer, intent(in) :: patch_id - #ifdef MFC_MIXED_PRECISION - integer(kind=1), dimension(0:m,0:n,0:p), intent(inout) :: patch_id_fp + integer(kind=1), dimension(0:m, 0:n, 0:p), intent(inout) :: patch_id_fp #else - integer, dimension(0:m,0:n,0:p), intent(inout) :: patch_id_fp + integer, dimension(0:m, 0:n, 0:p), intent(inout) :: patch_id_fp #endif type(scalar_field), dimension(1:sys_size), intent(inout) :: q_prim_vf - integer :: i, j, k !< Generic loop operators - real(wp) :: a, b + integer :: i, j, k !< Generic loop operators + real(wp) :: a, b @:HardcodedDimensionsExtrusion() @:Hardcoded2DVariables() - ! Transferring the elliptical patch's radii, centroid, smearing patch identity, and smearing coefficient information + ! Transferring the elliptical patch's radii, centroid, smearing + ! patch identity, and smearing coefficient information x_centroid = patch_icpp(patch_id)%x_centroid y_centroid = patch_icpp(patch_id)%y_centroid a = patch_icpp(patch_id)%radii(1) @@ -478,21 +589,36 @@ contains smooth_patch_id = patch_icpp(patch_id)%smooth_patch_id smooth_coeff = patch_icpp(patch_id)%smooth_coeff - ! Initialize eta=1; modified if smoothing is enabled + ! Initializing the pseudo volume fraction value to 1. The value + ! be modified as the patch is laid out on the grid, but only in + ! the case that smoothing of the elliptical patch's boundary is + ! enabled. eta = 1._wp - ! Assign patch vars if cell is covered and patch has write permission + ! Checking whether the ellipse covers a particular cell in the + ! domain and verifying whether the current patch has permission + ! to write to that cell. If both queries check out, the primitive + ! variables of the current patch are assigned to this cell. do j = 0, n do i = 0, m + if (patch_icpp(patch_id)%smoothen) then - eta = tanh(smooth_coeff/min(dx, & - & dy)*(sqrt(((x_cc(i) - x_centroid)/a)**2 + ((y_cc(j) - y_centroid)/b)**2) - 1._wp))*(-0.5_wp) & - & + 0.5_wp + eta = tanh(smooth_coeff/min(dx, dy)* & + (sqrt(((x_cc(i) - x_centroid)/a)**2 + & + ((y_cc(j) - y_centroid)/b)**2) & + - 1._wp))*(-0.5_wp) + 0.5_wp end if - if ((((x_cc(i) - x_centroid)/a)**2 + ((y_cc(j) - y_centroid)/b)**2 <= 1._wp .and. patch_icpp(patch_id) & - & %alter_patch(patch_id_fp(i, j, 0))) .or. patch_id_fp(i, j, 0) == smooth_patch_id) then - call s_assign_patch_primitive_variables(patch_id, i, j, 0, eta, q_prim_vf, patch_id_fp) + if ((((x_cc(i) - x_centroid)/a)**2 + & + ((y_cc(j) - y_centroid)/b)**2 <= 1._wp & + .and. & + patch_icpp(patch_id)%alter_patch(patch_id_fp(i, j, 0))) & + .or. & + patch_id_fp(i, j, 0) == smooth_patch_id) & + then + + call s_assign_patch_primitive_variables(patch_id, i, j, 0, & + eta, q_prim_vf, patch_id_fp) @:analytical() if (patch_icpp(patch_id)%hcid /= dflt_int) then @@ -508,28 +634,32 @@ contains end subroutine s_icpp_ellipse - !> The ellipsoidal patch is a 3D geometry. The geometry of the patch is well-defined when its centroid and radii are provided. - !! Note that the ellipsoidal patch DOES allow for the smoothing of its boundary + !> The ellipsoidal patch is a 3D geometry. The geometry of + !! the patch is well-defined when its centroid and radii + !! are provided. Note that the ellipsoidal patch DOES allow + !! for the smoothing of its boundary + !! @param patch_id is the patch identifier + !! @param patch_id_fp Array to track patch ids + !! @param q_prim_vf Array of primitive variables subroutine s_icpp_ellipsoid(patch_id, patch_id_fp, q_prim_vf) ! Patch identifier integer, intent(in) :: patch_id - #ifdef MFC_MIXED_PRECISION - integer(kind=1), dimension(0:m,0:n,0:p), intent(inout) :: patch_id_fp + integer(kind=1), dimension(0:m, 0:n, 0:p), intent(inout) :: patch_id_fp #else - integer, dimension(0:m,0:n,0:p), intent(inout) :: patch_id_fp + integer, dimension(0:m, 0:n, 0:p), intent(inout) :: patch_id_fp #endif type(scalar_field), dimension(1:sys_size), intent(inout) :: q_prim_vf ! Generic loop iterators - integer :: i, j, k + integer :: i, j, k real(wp) :: a, b, c - @:HardcodedDimensionsExtrusion() @:Hardcoded3DVariables() - ! Transferring the ellipsoidal patch's radii, centroid, smearing patch identity, and smearing coefficient information + ! Transferring the ellipsoidal patch's radii, centroid, smearing + ! patch identity, and smearing coefficient information x_centroid = patch_icpp(patch_id)%x_centroid y_centroid = patch_icpp(patch_id)%y_centroid z_centroid = patch_icpp(patch_id)%z_centroid @@ -539,13 +669,20 @@ contains smooth_patch_id = patch_icpp(patch_id)%smooth_patch_id smooth_coeff = patch_icpp(patch_id)%smooth_coeff - ! Initialize eta=1; modified if smoothing is enabled + ! Initializing the pseudo volume fraction value to 1. The value + ! be modified as the patch is laid out on the grid, but only in + ! the case that smoothing of the ellipsoidal patch's boundary is + ! enabled. eta = 1._wp - ! Assign patch vars if cell is covered and patch has write permission + ! Checking whether the ellipsoid covers a particular cell in the + ! domain and verifying whether the current patch has permission + ! to write to that cell. If both queries check out, the primitive + ! variables of the current patch are assigned to this cell. do k = 0, p do j = 0, n do i = 0, m + if (grid_geometry == 3) then call s_convert_cylindrical_to_cartesian_coord(y_cc(j), z_cc(k)) else @@ -554,15 +691,24 @@ contains end if if (patch_icpp(patch_id)%smoothen) then - eta = tanh(smooth_coeff/min(dx, dy, & - & dz)*(sqrt(((x_cc(i) - x_centroid)/a)**2 + ((cart_y - y_centroid)/b)**2 + ((cart_z & - & - z_centroid)/c)**2) - 1._wp))*(-0.5_wp) + 0.5_wp + eta = tanh(smooth_coeff/min(dx, dy, dz)* & + (sqrt(((x_cc(i) - x_centroid)/a)**2 + & + ((cart_y - y_centroid)/b)**2 + & + ((cart_z - z_centroid)/c)**2) & + - 1._wp))*(-0.5_wp) + 0.5_wp end if - if ((((x_cc(i) - x_centroid)/a)**2 + ((cart_y - y_centroid)/b)**2 + ((cart_z - z_centroid)/c) & - & **2 <= 1._wp .and. patch_icpp(patch_id)%alter_patch(patch_id_fp(i, j, k))) .or. patch_id_fp(i, j, & - & k) == smooth_patch_id) then - call s_assign_patch_primitive_variables(patch_id, i, j, k, eta, q_prim_vf, patch_id_fp) + if ((((x_cc(i) - x_centroid)/a)**2 + & + ((cart_y - y_centroid)/b)**2 + & + ((cart_z - z_centroid)/c)**2 <= 1._wp & + .and. & + patch_icpp(patch_id)%alter_patch(patch_id_fp(i, j, k))) & + .or. & + patch_id_fp(i, j, k) == smooth_patch_id) & + then + + call s_assign_patch_primitive_variables(patch_id, i, j, k, & + eta, q_prim_vf, patch_id_fp) @:analytical() if (patch_icpp(patch_id)%hcid /= dflt_int) then @@ -579,23 +725,29 @@ contains end subroutine s_icpp_ellipsoid - !> The rectangular patch is a 2D geometry that may be used, for example, in creating a solid boundary, or pre-/post- shock - !! region, in alignment with the axes of the Cartesian coordinate system. The geometry of such a patch is well- defined when its - !! centroid and lengths in the x- and y- coordinate directions are provided. Please note that the rectangular patch DOES NOT - !! allow for the smoothing of its boundaries. + !> The rectangular patch is a 2D geometry that may be used, + !! for example, in creating a solid boundary, or pre-/post- + !! shock region, in alignment with the axes of the Cartesian + !! coordinate system. The geometry of such a patch is well- + !! defined when its centroid and lengths in the x- and y- + !! coordinate directions are provided. Please note that the + !! rectangular patch DOES NOT allow for the smoothing of its + !! boundaries. + !! @param patch_id is the patch identifier + !! @param patch_id_fp Array to track patch ids + !! @param q_prim_vf Array of primitive variables subroutine s_icpp_rectangle(patch_id, patch_id_fp, q_prim_vf) integer, intent(in) :: patch_id - #ifdef MFC_MIXED_PRECISION - integer(kind=1), dimension(0:m,0:n,0:p), intent(inout) :: patch_id_fp + integer(kind=1), dimension(0:m, 0:n, 0:p), intent(inout) :: patch_id_fp #else - integer, dimension(0:m,0:n,0:p), intent(inout) :: patch_id_fp + integer, dimension(0:m, 0:n, 0:p), intent(inout) :: patch_id_fp #endif type(scalar_field), dimension(1:sys_size), intent(inout) :: q_prim_vf - integer :: i, j, k !< generic loop iterators - real(wp) :: pi_inf, gamma, lit_gamma !< Equation of state parameters + integer :: i, j, k !< generic loop iterators + real(wp) :: pi_inf, gamma, lit_gamma !< Equation of state parameters @:HardcodedDimensionsExtrusion() @:Hardcoded2DVariables() @@ -609,22 +761,34 @@ contains length_x = patch_icpp(patch_id)%length_x length_y = patch_icpp(patch_id)%length_y - ! Computing the beginning and the end x- and y-coordinates of the rectangle based on its centroid and lengths + ! Computing the beginning and the end x- and y-coordinates of the + ! rectangle based on its centroid and lengths x_boundary%beg = x_centroid - 0.5_wp*length_x x_boundary%end = x_centroid + 0.5_wp*length_x y_boundary%beg = y_centroid - 0.5_wp*length_y y_boundary%end = y_centroid + 0.5_wp*length_y - ! Set eta=1 (no smoothing for this patch type) + ! Since the rectangular patch does not allow for its boundaries to + ! be smoothed out, the pseudo volume fraction is set to 1 to ensure + ! that only the current patch contributes to the fluid state in the + ! cells that this patch covers. eta = 1._wp - ! Assign patch vars if cell is covered and patch has write permission + ! Checking whether the rectangle covers a particular cell in the + ! domain and verifying whether the current patch has the permission + ! to write to that cell. If both queries check out, the primitive + ! variables of the current patch are assigned to this cell. do j = 0, n do i = 0, m - if (x_boundary%beg <= x_cc(i) .and. x_boundary%end >= x_cc(i) .and. y_boundary%beg <= y_cc(j) & - & .and. y_boundary%end >= y_cc(j)) then - if (patch_icpp(patch_id)%alter_patch(patch_id_fp(i, j, 0))) then - call s_assign_patch_primitive_variables(patch_id, i, j, 0, eta, q_prim_vf, patch_id_fp) + if (x_boundary%beg <= x_cc(i) .and. & + x_boundary%end >= x_cc(i) .and. & + y_boundary%beg <= y_cc(j) .and. & + y_boundary%end >= y_cc(j)) then + if (patch_icpp(patch_id)%alter_patch(patch_id_fp(i, j, 0))) & + then + + call s_assign_patch_primitive_variables(patch_id, i, j, 0, & + eta, q_prim_vf, patch_id_fp) @:analytical() @@ -633,10 +797,10 @@ contains end if if ((q_prim_vf(1)%sf(i, j, 0) < 1.e-10) .and. (model_eqns == 4)) then - ! zero density, reassign according to Tait EOS - q_prim_vf(1)%sf(i, j, 0) = (((q_prim_vf(E_idx)%sf(i, j, & - & 0) + pi_inf)/(pref + pi_inf))**(1._wp/lit_gamma))*rhoref*(1._wp - q_prim_vf(alf_idx) & - & %sf(i, j, 0)) + !zero density, reassign according to Tait EOS + q_prim_vf(1)%sf(i, j, 0) = & + (((q_prim_vf(E_idx)%sf(i, j, 0) + pi_inf)/(pref + pi_inf))**(1._wp/lit_gamma))* & + rhoref*(1._wp - q_prim_vf(alf_idx)%sf(i, j, 0)) end if ! Updating the patch identities bookkeeping variable @@ -649,23 +813,28 @@ contains end subroutine s_icpp_rectangle - !> The swept line patch is a 2D geometry that may be used, for example, in creating a solid boundary, or pre-/post- shock - !! region, at an angle with respect to the axes of the Cartesian coordinate system. The geometry of the patch is well-defined - !! when its centroid and normal vector, aimed in the sweep direction, are provided. Note that the sweep line patch DOES allow - !! the smoothing of its boundary. + !> The swept line patch is a 2D geometry that may be used, + !! for example, in creating a solid boundary, or pre-/post- + !! shock region, at an angle with respect to the axes of the + !! Cartesian coordinate system. The geometry of the patch is + !! well-defined when its centroid and normal vector, aimed + !! in the sweep direction, are provided. Note that the sweep + !! line patch DOES allow the smoothing of its boundary. + !! @param patch_id is the patch identifier + !! @param patch_id_fp Array to track patch ids + !! @param q_prim_vf Array of primitive variables subroutine s_icpp_sweep_line(patch_id, patch_id_fp, q_prim_vf) integer, intent(in) :: patch_id - #ifdef MFC_MIXED_PRECISION - integer(kind=1), dimension(0:m,0:n,0:p), intent(inout) :: patch_id_fp + integer(kind=1), dimension(0:m, 0:n, 0:p), intent(inout) :: patch_id_fp #else - integer, dimension(0:m,0:n,0:p), intent(inout) :: patch_id_fp + integer, dimension(0:m, 0:n, 0:p), intent(inout) :: patch_id_fp #endif type(scalar_field), dimension(1:sys_size), intent(inout) :: q_prim_vf - integer :: i, j, k !< Generic loop operators - real(wp) :: a, b, c + integer :: i, j, k !< Generic loop operators + real(wp) :: a, b, c @:HardcodedDimensionsExtrusion() @:Hardcoded3DVariables() @@ -680,19 +849,32 @@ contains b = patch_icpp(patch_id)%normal(2) c = -a*x_centroid - b*y_centroid - ! Initialize eta=1; modified if smoothing is enabled + ! Initializing the pseudo volume fraction value to 1. The value will + ! be modified as the patch is laid out on the grid, but only in the + ! case that smoothing of the sweep line patch's boundary is enabled. eta = 1._wp - ! Assign patch vars if cell is covered and patch has write permission + ! Checking whether the region swept by the line covers a particular + ! cell in the domain and verifying whether the current patch has the + ! permission to write to that cell. If both queries check out, the + ! primitive variables of the current patch are written to this cell. do j = 0, n do i = 0, m + if (patch_icpp(patch_id)%smoothen) then - eta = 5.e-1_wp + 5.e-1_wp*tanh(smooth_coeff/min(dx, dy)*(a*x_cc(i) + b*y_cc(j) + c)/sqrt(a**2 + b**2)) + eta = 5.e-1_wp + 5.e-1_wp*tanh(smooth_coeff/min(dx, dy) & + *(a*x_cc(i) + b*y_cc(j) + c) & + /sqrt(a**2 + b**2)) end if - if ((a*x_cc(i) + b*y_cc(j) + c >= 0._wp .and. patch_icpp(patch_id)%alter_patch(patch_id_fp(i, j, & - & 0))) .or. patch_id_fp(i, j, 0) == smooth_patch_id) then - call s_assign_patch_primitive_variables(patch_id, i, j, 0, eta, q_prim_vf, patch_id_fp) + if ((a*x_cc(i) + b*y_cc(j) + c >= 0._wp & + .and. & + patch_icpp(patch_id)%alter_patch(patch_id_fp(i, j, 0))) & + .or. & + patch_id_fp(i, j, 0) == smooth_patch_id) & + then + call s_assign_patch_primitive_variables(patch_id, i, j, 0, & + eta, q_prim_vf, patch_id_fp) @:analytical() if (patch_icpp(patch_id)%hcid /= dflt_int) then @@ -702,28 +884,33 @@ contains ! Updating the patch identities bookkeeping variable if (1._wp - eta < sgm_eps) patch_id_fp(i, j, 0) = patch_id end if + end do end do @:HardcodedDellacation() end subroutine s_icpp_sweep_line - !> The Taylor Green vortex is 2D decaying vortex that may be used, for example, to verify the effects of viscous attenuation. - !! Geometry of the patch is well-defined when its centroid are provided. + !> The Taylor Green vortex is 2D decaying vortex that may be used, + !! for example, to verify the effects of viscous attenuation. + !! Geometry of the patch is well-defined when its centroid + !! are provided. + !! @param patch_id is the patch identifier + !! @param patch_id_fp Array to track patch ids + !! @param q_prim_vf Array of primitive variables subroutine s_icpp_2D_TaylorGreen_Vortex(patch_id, patch_id_fp, q_prim_vf) integer, intent(in) :: patch_id - #ifdef MFC_MIXED_PRECISION - integer(kind=1), dimension(0:m,0:n,0:p), intent(inout) :: patch_id_fp + integer(kind=1), dimension(0:m, 0:n, 0:p), intent(inout) :: patch_id_fp #else - integer, dimension(0:m,0:n,0:p), intent(inout) :: patch_id_fp + integer, dimension(0:m, 0:n, 0:p), intent(inout) :: patch_id_fp #endif type(scalar_field), dimension(1:sys_size), intent(inout) :: q_prim_vf - integer :: i, j, k !< generic loop iterators - real(wp) :: pi_inf, gamma, lit_gamma !< equation of state parameters - real(wp) :: L0, U0 !< Taylor Green Vortex parameters + integer :: i, j, k !< generic loop iterators + real(wp) :: pi_inf, gamma, lit_gamma !< equation of state parameters + real(wp) :: L0, U0 !< Taylor Green Vortex parameters @:HardcodedDimensionsExtrusion() @:Hardcoded2DVariables() @@ -737,24 +924,37 @@ contains length_x = patch_icpp(patch_id)%length_x length_y = patch_icpp(patch_id)%length_y - ! Computing the beginning and the end x- and y-coordinates of the patch based on its centroid and lengths + ! Computing the beginning and the end x- and y-coordinates + ! of the patch based on its centroid and lengths x_boundary%beg = x_centroid - 0.5_wp*length_x x_boundary%end = x_centroid + 0.5_wp*length_x y_boundary%beg = y_centroid - 0.5_wp*length_y y_boundary%end = y_centroid + 0.5_wp*length_y - ! Set eta=1 (no smoothing for this patch type) + ! Since the patch doesn't allow for its boundaries to be + ! smoothed out, the pseudo volume fraction is set to 1 to + ! ensure that only the current patch contributes to the fluid + ! state in the cells that this patch covers. eta = 1._wp ! U0 is the characteristic velocity of the vortex U0 = patch_icpp(patch_id)%vel(1) ! L0 is the characteristic length of the vortex L0 = patch_icpp(patch_id)%vel(2) - ! Assign patch vars if cell is covered and patch has write permission + ! Checking whether the patch covers a particular cell in the + ! domain and verifying whether the current patch has the + ! permission to write to that cell. If both queries check out, + ! the primitive variables of the current patch are assigned + ! to this cell. do j = 0, n do i = 0, m - if (x_boundary%beg <= x_cc(i) .and. x_boundary%end >= x_cc(i) .and. y_boundary%beg <= y_cc(j) & - & .and. y_boundary%end >= y_cc(j) .and. patch_icpp(patch_id)%alter_patch(patch_id_fp(i, j, 0))) then - call s_assign_patch_primitive_variables(patch_id, i, j, 0, eta, q_prim_vf, patch_id_fp) + if (x_boundary%beg <= x_cc(i) .and. & + x_boundary%end >= x_cc(i) .and. & + y_boundary%beg <= y_cc(j) .and. & + y_boundary%end >= y_cc(j) .and. & + patch_icpp(patch_id)%alter_patch(patch_id_fp(i, j, 0))) then + + call s_assign_patch_primitive_variables(patch_id, i, j, 0, & + eta, q_prim_vf, patch_id_fp) @:analytical() if (patch_icpp(patch_id)%hcid /= dflt_int) then @@ -767,9 +967,9 @@ contains ! Assign Parameters q_prim_vf(mom_idx%beg)%sf(i, j, 0) = U0*sin(x_cc(i)/L0)*cos(y_cc(j)/L0) q_prim_vf(mom_idx%end)%sf(i, j, 0) = -U0*cos(x_cc(i)/L0)*sin(y_cc(j)/L0) - q_prim_vf(E_idx)%sf(i, j, & - & 0) = patch_icpp(patch_id)%pres + (cos(2*x_cc(i))/L0 + cos(2*y_cc(j))/L0)*(q_prim_vf(1)%sf(i, j, & - & 0)*U0*U0)/16 + q_prim_vf(E_idx)%sf(i, j, 0) = patch_icpp(patch_id)%pres + (cos(2*x_cc(i))/L0 + & + cos(2*y_cc(j))/L0)* & + (q_prim_vf(1)%sf(i, j, 0)*U0*U0)/16 end if end do end do @@ -777,18 +977,20 @@ contains end subroutine s_icpp_2D_TaylorGreen_Vortex - !> Initialize a 1D bubble-pulse patch with analytical primitive variable profiles. + !> @brief Initializes a 1D bubble-pulse patch with analytical primitive variable profiles. + !! @param patch_id is the patch identifier + !! @param patch_id_fp Array to track patch ids + !! @param q_prim_vf Array of primitive variables subroutine s_icpp_1d_bubble_pulse(patch_id, patch_id_fp, q_prim_vf) - - ! Description: This patch assigns the primitive variables as analytical functions such that the code can be verified. + ! Description: This patch assigns the primitive variables as analytical + ! functions such that the code can be verified. ! Patch identifier integer, intent(in) :: patch_id - #ifdef MFC_MIXED_PRECISION - integer(kind=1), dimension(0:m,0:n,0:p), intent(inout) :: patch_id_fp + integer(kind=1), dimension(0:m, 0:n, 0:p), intent(inout) :: patch_id_fp #else - integer, dimension(0:m,0:n,0:p), intent(inout) :: patch_id_fp + integer, dimension(0:m, 0:n, 0:p), intent(inout) :: patch_id_fp #endif type(scalar_field), dimension(1:sys_size), intent(inout) :: q_prim_vf @@ -796,7 +998,6 @@ contains integer :: i, j, k ! Placeholders for the cell boundary values real(wp) :: pi_inf, gamma, lit_gamma - @:HardcodedDimensionsExtrusion() @:Hardcoded1DVariables() @@ -808,45 +1009,55 @@ contains x_centroid = patch_icpp(patch_id)%x_centroid length_x = patch_icpp(patch_id)%length_x - ! Computing the beginning and the end x- and y-coordinates of the patch based on its centroid and lengths + ! Computing the beginning and the end x- and y-coordinates + ! of the patch based on its centroid and lengths x_boundary%beg = x_centroid - 0.5_wp*length_x x_boundary%end = x_centroid + 0.5_wp*length_x - ! Set eta=1 (no smoothing for this patch type) + ! Since the patch doesn't allow for its boundaries to be + ! smoothed out, the pseudo volume fraction is set to 1 to + ! ensure that only the current patch contributes to the fluid + ! state in the cells that this patch covers. eta = 1._wp - ! Assign patch vars if cell is covered and patch has write permission + ! Checking whether the line segment covers a particular cell in the + ! domain and verifying whether the current patch has the permission + ! to write to that cell. If both queries check out, the primitive + ! variables of the current patch are assigned to this cell. do i = 0, m - if (x_boundary%beg <= x_cc(i) .and. x_boundary%end >= x_cc(i) .and. patch_icpp(patch_id)%alter_patch(patch_id_fp(i, & - & 0, 0))) then - call s_assign_patch_primitive_variables(patch_id, i, 0, 0, eta, q_prim_vf, patch_id_fp) + if (x_boundary%beg <= x_cc(i) .and. & + x_boundary%end >= x_cc(i) .and. & + patch_icpp(patch_id)%alter_patch(patch_id_fp(i, 0, 0))) then + + call s_assign_patch_primitive_variables(patch_id, i, 0, 0, & + eta, q_prim_vf, patch_id_fp) @:analytical() if (patch_icpp(patch_id)%hcid /= dflt_int) then @:Hardcoded1D() end if + end if end do @:HardcodedDellacation() end subroutine s_icpp_1D_bubble_pulse - !> 2D modal (Fourier) patch. theta = atan2(y - y_centroid, x - x_centroid). Additive (modal_use_exp_form false): R = radius + - !! sum_n [fourier_cos*cos(n*theta)+fourier_sin*sin(n*theta)]; coefficients are absolute (same units as radius). R is clipped to - !! max(R,0). If modal_clip_r_to_min, R = max(R, modal_r_min). Exponential (modal_use_exp_form true): R = radius*exp(sum); - !! coefficients are relative (dimensionless). + !> 2D modal (Fourier) patch. theta = atan2(y - y_centroid, x - x_centroid). + !! Additive (modal_use_exp_form false): R = radius + sum_n [fourier_cos*cos(n*theta)+fourier_sin*sin(n*theta)]; + !! coefficients are absolute (same units as radius). R is clipped to max(R,0). If modal_clip_r_to_min, R = max(R, modal_r_min). + !! Exponential (modal_use_exp_form true): R = radius*exp(sum); coefficients are relative (dimensionless). subroutine s_icpp_2d_modal(patch_id, patch_id_fp, q_prim_vf) - integer, intent(in) :: patch_id - #ifdef MFC_MIXED_PRECISION - integer(kind=1), dimension(0:m,0:n,0:p), intent(inout) :: patch_id_fp + integer(kind=1), dimension(0:m, 0:n, 0:p), intent(inout) :: patch_id_fp #else - integer, dimension(0:m,0:n,0:p), intent(inout) :: patch_id_fp + integer, dimension(0:m, 0:n, 0:p), intent(inout) :: patch_id_fp #endif type(scalar_field), dimension(1:sys_size), intent(inout) :: q_prim_vf - real(wp) :: r, theta, R_boundary, sum_series - integer :: i, j, nn + + real(wp) :: r, theta, R_boundary, sum_series + integer :: i, j, nn x_centroid = patch_icpp(patch_id)%x_centroid y_centroid = patch_icpp(patch_id)%y_centroid @@ -864,8 +1075,8 @@ contains end if sum_series = 0._wp do nn = 1, max_2d_fourier_modes - sum_series = sum_series + patch_icpp(patch_id)%fourier_cos(nn)*cos(real(nn, & - & wp)*theta) + patch_icpp(patch_id)%fourier_sin(nn)*sin(real(nn, wp)*theta) + sum_series = sum_series + patch_icpp(patch_id)%fourier_cos(nn)*cos(real(nn, wp)*theta) & + + patch_icpp(patch_id)%fourier_sin(nn)*sin(real(nn, wp)*theta) end do if (patch_icpp(patch_id)%modal_use_exp_form) then R_boundary = patch_icpp(patch_id)%radius*exp(sum_series) @@ -879,29 +1090,27 @@ contains if (patch_icpp(patch_id)%smoothen) then eta = 0.5_wp + 0.5_wp*tanh(smooth_coeff/min(dx, dy)*(R_boundary - r)) end if - if ((r <= R_boundary .and. patch_icpp(patch_id)%alter_patch(patch_id_fp(i, j, 0))) .or. patch_id_fp(i, j, & - & 0) == smooth_patch_id) then + if ((r <= R_boundary .and. patch_icpp(patch_id)%alter_patch(patch_id_fp(i, j, 0))) & + .or. patch_id_fp(i, j, 0) == smooth_patch_id) then call s_assign_patch_primitive_variables(patch_id, i, j, 0, eta, q_prim_vf, patch_id_fp) end if end do end do - end subroutine s_icpp_2d_modal - !> 3D spherical harmonic patch. Surface r = radius + sum_lm sph_har_coeff(l,m)*Y_lm(theta,phi). theta = acos(z/r), phi = - !! atan2(y,x) relative to centroid. + !> 3D spherical harmonic patch. Surface r = radius + sum_lm sph_har_coeff(l,m)*Y_lm(theta,phi). + !! theta = acos(z/r), phi = atan2(y,x) relative to centroid. subroutine s_icpp_3d_spherical_harmonic(patch_id, patch_id_fp, q_prim_vf) - integer, intent(in) :: patch_id - #ifdef MFC_MIXED_PRECISION - integer(kind=1), dimension(0:m,0:n,0:p), intent(inout) :: patch_id_fp + integer(kind=1), dimension(0:m, 0:n, 0:p), intent(inout) :: patch_id_fp #else - integer, dimension(0:m,0:n,0:p), intent(inout) :: patch_id_fp + integer, dimension(0:m, 0:n, 0:p), intent(inout) :: patch_id_fp #endif type(scalar_field), dimension(1:sys_size), intent(inout) :: q_prim_vf - real(wp) :: dx_loc, dy_loc, dz_loc, r, theta, phi, R_surface, eta_local - integer :: i, j, k, ll, mm + + real(wp) :: dx_loc, dy_loc, dz_loc, r, theta, phi, R_surface, eta_local + integer :: i, j, k, ll, mm x_centroid = patch_icpp(patch_id)%x_centroid y_centroid = patch_icpp(patch_id)%y_centroid @@ -941,40 +1150,44 @@ contains if (patch_icpp(patch_id)%smoothen) then eta_local = 0.5_wp + 0.5_wp*tanh(smooth_coeff/min(dx, dy, dz)*(R_surface - r)) end if - if ((r <= R_surface .and. patch_icpp(patch_id)%alter_patch(patch_id_fp(i, j, k))) .or. patch_id_fp(i, j, & - & k) == smooth_patch_id) then + if ((r <= R_surface .and. patch_icpp(patch_id)%alter_patch(patch_id_fp(i, j, k))) & + .or. patch_id_fp(i, j, k) == smooth_patch_id) then call s_assign_patch_primitive_variables(patch_id, i, j, k, eta_local, q_prim_vf, patch_id_fp) end if end do end do end do - end subroutine s_icpp_3d_spherical_harmonic - !> The spherical patch is a 3D geometry that may be used, for example, in creating a bubble or a droplet. The patch geometry is - !! well-defined when its centroid and radius are provided. Please note that the spherical patch DOES allow for the smoothing of - !! its boundary. + !> The spherical patch is a 3D geometry that may be used, + !! for example, in creating a bubble or a droplet. The patch + !! geometry is well-defined when its centroid and radius are + !! provided. Please note that the spherical patch DOES allow + !! for the smoothing of its boundary. + !! @param patch_id is the patch identifier + !! @param patch_id_fp Array to track patch ids + !! @param q_prim_vf Array of primitive variables subroutine s_icpp_sphere(patch_id, patch_id_fp, q_prim_vf) integer, intent(in) :: patch_id - #ifdef MFC_MIXED_PRECISION - integer(kind=1), dimension(0:m,0:n,0:p), intent(inout) :: patch_id_fp + integer(kind=1), dimension(0:m, 0:n, 0:p), intent(inout) :: patch_id_fp #else - integer, dimension(0:m,0:n,0:p), intent(inout) :: patch_id_fp + integer, dimension(0:m, 0:n, 0:p), intent(inout) :: patch_id_fp #endif type(scalar_field), dimension(1:sys_size), intent(inout) :: q_prim_vf ! Generic loop iterators - integer :: i, j, k + integer :: i, j, k real(wp) :: radius - @:HardcodedDimensionsExtrusion() @:Hardcoded3DVariables() - ! Variables to initialize the pressure field that corresponds to the bubble-collapse test case found in Tiwari et al. (2013) + !! Variables to initialize the pressure field that corresponds to the + !! bubble-collapse test case found in Tiwari et al. (2013) - ! Transferring spherical patch's radius, centroid, smoothing patch identity and smoothing coefficient information + ! Transferring spherical patch's radius, centroid, smoothing patch + ! identity and smoothing coefficient information x_centroid = patch_icpp(patch_id)%x_centroid y_centroid = patch_icpp(patch_id)%y_centroid z_centroid = patch_icpp(patch_id)%z_centroid @@ -982,13 +1195,19 @@ contains smooth_patch_id = patch_icpp(patch_id)%smooth_patch_id smooth_coeff = patch_icpp(patch_id)%smooth_coeff - ! Initialize eta=1; modified if smoothing is enabled + ! Initializing the pseudo volume fraction value to 1. The value will + ! be modified as the patch is laid out on the grid, but only in the + ! case that smoothing of the spherical patch's boundary is enabled. eta = 1._wp - ! Assign patch vars if cell is covered and patch has write permission + ! Checking whether the sphere covers a particular cell in the domain + ! and verifying whether the current patch has permission to write to + ! that cell. If both queries check out, the primitive variables of + ! the current patch are assigned to this cell. do k = 0, p do j = 0, n do i = 0, m + if (grid_geometry == 3) then call s_convert_cylindrical_to_cartesian_coord(y_cc(j), z_cc(k)) else @@ -997,20 +1216,27 @@ contains end if if (patch_icpp(patch_id)%smoothen) then - eta = tanh(smooth_coeff/min(dx, dy, & - & dz)*(sqrt((x_cc(i) - x_centroid)**2 + (cart_y - y_centroid)**2 + (cart_z - z_centroid)**2) & - & - radius))*(-0.5_wp) + 0.5_wp + eta = tanh(smooth_coeff/min(dx, dy, dz)* & + (sqrt((x_cc(i) - x_centroid)**2 & + + (cart_y - y_centroid)**2 & + + (cart_z - z_centroid)**2) & + - radius))*(-0.5_wp) + 0.5_wp end if - if ((((x_cc(i) - x_centroid)**2 + (cart_y - y_centroid)**2 + (cart_z - z_centroid)**2 <= radius**2) & - & .and. patch_icpp(patch_id)%alter_patch(patch_id_fp(i, j, k))) .or. patch_id_fp(i, j, & - & k) == smooth_patch_id) then - call s_assign_patch_primitive_variables(patch_id, i, j, k, eta, q_prim_vf, patch_id_fp) + if ((((x_cc(i) - x_centroid)**2 & + + (cart_y - y_centroid)**2 & + + (cart_z - z_centroid)**2 <= radius**2) .and. & + patch_icpp(patch_id)%alter_patch(patch_id_fp(i, j, k))) .or. & + patch_id_fp(i, j, k) == smooth_patch_id) then + + call s_assign_patch_primitive_variables(patch_id, i, j, k, & + eta, q_prim_vf, patch_id_fp) @:analytical() if (patch_icpp(patch_id)%hcid /= dflt_int) then @:Hardcoded3D() end if + end if end do end do @@ -1019,22 +1245,28 @@ contains end subroutine s_icpp_sphere - !> The cuboidal patch is a 3D geometry that may be used, for example, in creating a solid boundary, or pre-/post-shock region, - !! which is aligned with the axes of the Cartesian coordinate system. The geometry of such a patch is well- defined when its - !! centroid and lengths in the x-, y- and z-coordinate directions are provided. Please notice that the cuboidal patch DOES NOT - !! allow for the smearing of its boundaries. + !> The cuboidal patch is a 3D geometry that may be used, for + !! example, in creating a solid boundary, or pre-/post-shock + !! region, which is aligned with the axes of the Cartesian + !! coordinate system. The geometry of such a patch is well- + !! defined when its centroid and lengths in the x-, y- and + !! z-coordinate directions are provided. Please notice that + !! the cuboidal patch DOES NOT allow for the smearing of its + !! boundaries. + !! @param patch_id is the patch identifier + !! @param patch_id_fp Array to track patch ids + !! @param q_prim_vf Array of primitive variables subroutine s_icpp_cuboid(patch_id, patch_id_fp, q_prim_vf) integer, intent(in) :: patch_id - #ifdef MFC_MIXED_PRECISION - integer(kind=1), dimension(0:m,0:n,0:p), intent(inout) :: patch_id_fp + integer(kind=1), dimension(0:m, 0:n, 0:p), intent(inout) :: patch_id_fp #else - integer, dimension(0:m,0:n,0:p), intent(inout) :: patch_id_fp + integer, dimension(0:m, 0:n, 0:p), intent(inout) :: patch_id_fp #endif type(scalar_field), dimension(1:sys_size), intent(inout) :: q_prim_vf - integer :: i, j, k !< Generic loop iterators + integer :: i, j, k !< Generic loop iterators @:HardcodedDimensionsExtrusion() @:Hardcoded3DVariables() @@ -1046,7 +1278,8 @@ contains length_y = patch_icpp(patch_id)%length_y length_z = patch_icpp(patch_id)%length_z - ! Computing the beginning and the end x-, y- and z-coordinates of the cuboid based on its centroid and lengths + ! Computing the beginning and the end x-, y- and z-coordinates of + ! the cuboid based on its centroid and lengths x_boundary%beg = x_centroid - 0.5_wp*length_x x_boundary%end = x_centroid + 0.5_wp*length_x y_boundary%beg = y_centroid - 0.5_wp*length_y @@ -1054,13 +1287,20 @@ contains z_boundary%beg = z_centroid - 0.5_wp*length_z z_boundary%end = z_centroid + 0.5_wp*length_z - ! Set eta=1 (no smoothing for this patch type) + ! Since the cuboidal patch does not allow for its boundaries to get + ! smoothed out, the pseudo volume fraction is set to 1 to make sure + ! that only the current patch contributes to the fluid state in the + ! cells that this patch covers. eta = 1._wp - ! Assign patch vars if cell is covered and patch has write permission + ! Checking whether the cuboid covers a particular cell in the domain + ! and verifying whether the current patch has permission to write to + ! to that cell. If both queries check out, the primitive variables + ! of the current patch are assigned to this cell. do k = 0, p do j = 0, n do i = 0, m + if (grid_geometry == 3) then call s_convert_cylindrical_to_cartesian_coord(y_cc(j), z_cc(k)) else @@ -1068,10 +1308,17 @@ contains cart_z = z_cc(k) end if - if (x_boundary%beg <= x_cc(i) .and. x_boundary%end >= x_cc(i) & - & .and. y_boundary%beg <= cart_y .and. y_boundary%end >= cart_y .and. z_boundary%beg <= cart_z .and. z_boundary%end >= cart_z) then + if (x_boundary%beg <= x_cc(i) .and. & + x_boundary%end >= x_cc(i) .and. & + y_boundary%beg <= cart_y .and. & + y_boundary%end >= cart_y .and. & + z_boundary%beg <= cart_z .and. & + z_boundary%end >= cart_z) then + if (patch_icpp(patch_id)%alter_patch(patch_id_fp(i, j, k))) then - call s_assign_patch_primitive_variables(patch_id, i, j, k, eta, q_prim_vf, patch_id_fp) + + call s_assign_patch_primitive_variables(patch_id, i, j, k, & + eta, q_prim_vf, patch_id_fp) @:analytical() if (patch_icpp(patch_id)%hcid /= dflt_int) then @@ -1080,6 +1327,7 @@ contains ! Updating the patch identities bookkeeping variable if (1._wp - eta < sgm_eps) patch_id_fp(i, j, k) = patch_id + end if end if end do @@ -1089,28 +1337,34 @@ contains end subroutine s_icpp_cuboid - !> The cylindrical patch is a 3D geometry that may be used, for example, in setting up a cylindrical solid boundary confinement, - !! like a blood vessel. The geometry of this patch is well-defined when the centroid, the radius and the length along the - !! cylinder's axis, parallel to the x-, y- or z-coordinate direction, are provided. Please note that the cylindrical patch DOES - !! allow for the smoothing of its lateral boundary. + !> The cylindrical patch is a 3D geometry that may be used, + !! for example, in setting up a cylindrical solid boundary + !! confinement, like a blood vessel. The geometry of this + !! patch is well-defined when the centroid, the radius and + !! the length along the cylinder's axis, parallel to the x-, + !! y- or z-coordinate direction, are provided. Please note + !! that the cylindrical patch DOES allow for the smoothing + !! of its lateral boundary. + !! @param patch_id is the patch identifier + !! @param patch_id_fp Array to track patch ids + !! @param q_prim_vf Array of primitive variables subroutine s_icpp_cylinder(patch_id, patch_id_fp, q_prim_vf) integer, intent(in) :: patch_id - #ifdef MFC_MIXED_PRECISION - integer(kind=1), dimension(0:m,0:n,0:p), intent(inout) :: patch_id_fp + integer(kind=1), dimension(0:m, 0:n, 0:p), intent(inout) :: patch_id_fp #else - integer, dimension(0:m,0:n,0:p), intent(inout) :: patch_id_fp + integer, dimension(0:m, 0:n, 0:p), intent(inout) :: patch_id_fp #endif type(scalar_field), dimension(1:sys_size), intent(inout) :: q_prim_vf - integer :: i, j, k !< Generic loop iterators - real(wp) :: radius + integer :: i, j, k !< Generic loop iterators + real(wp) :: radius @:HardcodedDimensionsExtrusion() @:Hardcoded3DVariables() - ! Transferring the cylindrical patch's centroid, length, radius, smoothing patch identity and smoothing coefficient - ! information + ! Transferring the cylindrical patch's centroid, length, radius, + ! smoothing patch identity and smoothing coefficient information x_centroid = patch_icpp(patch_id)%x_centroid y_centroid = patch_icpp(patch_id)%y_centroid z_centroid = patch_icpp(patch_id)%z_centroid @@ -1121,7 +1375,8 @@ contains smooth_patch_id = patch_icpp(patch_id)%smooth_patch_id smooth_coeff = patch_icpp(patch_id)%smooth_coeff - ! Computing the beginning and the end x-, y- and z-coordinates of the cylinder based on its centroid and lengths + ! Computing the beginning and the end x-, y- and z-coordinates of + ! the cylinder based on its centroid and lengths x_boundary%beg = x_centroid - 0.5_wp*length_x x_boundary%end = x_centroid + 0.5_wp*length_x y_boundary%beg = y_centroid - 0.5_wp*length_y @@ -1129,13 +1384,19 @@ contains z_boundary%beg = z_centroid - 0.5_wp*length_z z_boundary%end = z_centroid + 0.5_wp*length_z - ! Initialize eta=1; modified if smoothing is enabled + ! Initializing the pseudo volume fraction value to 1. The value will + ! be modified as the patch is laid out on the grid, but only in the + ! case that smearing of the cylindrical patch's boundary is enabled. eta = 1._wp - ! Assign patch vars if cell is covered and patch has write permission + ! Checking whether the cylinder covers a particular cell in the + ! domain and verifying whether the current patch has the permission + ! to write to that cell. If both queries check out, the primitive + ! variables of the current patch are assigned to this cell. do k = 0, p do j = 0, n do i = 0, m + if (grid_geometry == 3) then call s_convert_cylindrical_to_cartesian_coord(y_cc(j), z_cc(k)) else @@ -1145,29 +1406,45 @@ contains if (patch_icpp(patch_id)%smoothen) then if (.not. f_is_default(length_x)) then - eta = tanh(smooth_coeff/min(dy, & - & dz)*(sqrt((cart_y - y_centroid)**2 + (cart_z - z_centroid)**2) - radius))*(-0.5_wp) & - & + 0.5_wp - else if (.not. f_is_default(length_y)) then - eta = tanh(smooth_coeff/min(dx, & - & dz)*(sqrt((x_cc(i) - x_centroid)**2 + (cart_z - z_centroid)**2) - radius))*(-0.5_wp) & - & + 0.5_wp + eta = tanh(smooth_coeff/min(dy, dz)* & + (sqrt((cart_y - y_centroid)**2 & + + (cart_z - z_centroid)**2) & + - radius))*(-0.5_wp) + 0.5_wp + elseif (.not. f_is_default(length_y)) then + eta = tanh(smooth_coeff/min(dx, dz)* & + (sqrt((x_cc(i) - x_centroid)**2 & + + (cart_z - z_centroid)**2) & + - radius))*(-0.5_wp) + 0.5_wp else - eta = tanh(smooth_coeff/min(dx, & - & dy)*(sqrt((x_cc(i) - x_centroid)**2 + (cart_y - y_centroid)**2) - radius))*(-0.5_wp) & - & + 0.5_wp + eta = tanh(smooth_coeff/min(dx, dy)* & + (sqrt((x_cc(i) - x_centroid)**2 & + + (cart_y - y_centroid)**2) & + - radius))*(-0.5_wp) + 0.5_wp end if end if - if (((.not. f_is_default(length_x) .and. (cart_y - y_centroid)**2 + (cart_z - z_centroid) & - & **2 <= radius**2 .and. x_boundary%beg <= x_cc(i) .and. x_boundary%end >= x_cc(i)) & - & .or. (.not. f_is_default(length_y) .and. (x_cc(i) - x_centroid)**2 + (cart_z - z_centroid) & - & **2 <= radius**2 .and. y_boundary%beg <= cart_y .and. y_boundary%end >= cart_y) & - & .or. (.not. f_is_default(length_z) .and. (x_cc(i) - x_centroid)**2 + (cart_y - y_centroid) & - & **2 <= radius**2 .and. z_boundary%beg <= cart_z .and. z_boundary%end >= cart_z) & - & .and. patch_icpp(patch_id)%alter_patch(patch_id_fp(i, j, k))) .or. patch_id_fp(i, j, & - & k) == smooth_patch_id) then - call s_assign_patch_primitive_variables(patch_id, i, j, k, eta, q_prim_vf, patch_id_fp) + if (((.not. f_is_default(length_x) .and. & + (cart_y - y_centroid)**2 & + + (cart_z - z_centroid)**2 <= radius**2 .and. & + x_boundary%beg <= x_cc(i) .and. & + x_boundary%end >= x_cc(i)) & + .or. & + (.not. f_is_default(length_y) .and. & + (x_cc(i) - x_centroid)**2 & + + (cart_z - z_centroid)**2 <= radius**2 .and. & + y_boundary%beg <= cart_y .and. & + y_boundary%end >= cart_y) & + .or. & + (.not. f_is_default(length_z) .and. & + (x_cc(i) - x_centroid)**2 & + + (cart_y - y_centroid)**2 <= radius**2 .and. & + z_boundary%beg <= cart_z .and. & + z_boundary%end >= cart_z) .and. & + patch_icpp(patch_id)%alter_patch(patch_id_fp(i, j, k))) .or. & + patch_id_fp(i, j, k) == smooth_patch_id) then + + call s_assign_patch_primitive_variables(patch_id, i, j, k, & + eta, q_prim_vf, patch_id_fp) @:analytical() if (patch_icpp(patch_id)%hcid /= dflt_int) then @@ -1184,23 +1461,28 @@ contains end subroutine s_icpp_cylinder - !> The swept plane patch is a 3D geometry that may be used, for example, in creating a solid boundary, or pre-/post- shock - !! region, at an angle with respect to the axes of the Cartesian coordinate system. The geometry of the patch is well-defined - !! when its centroid and normal vector, aimed in the sweep direction, are provided. Note that the sweep plane patch DOES allow - !! the smoothing of its boundary. + !> The swept plane patch is a 3D geometry that may be used, + !! for example, in creating a solid boundary, or pre-/post- + !! shock region, at an angle with respect to the axes of the + !! Cartesian coordinate system. The geometry of the patch is + !! well-defined when its centroid and normal vector, aimed + !! in the sweep direction, are provided. Note that the sweep + !! plane patch DOES allow the smoothing of its boundary. + !! @param patch_id is the patch identifier + !! @param patch_id_fp Array to track patch ids + !! @param q_prim_vf Primitive variables subroutine s_icpp_sweep_plane(patch_id, patch_id_fp, q_prim_vf) integer, intent(in) :: patch_id - #ifdef MFC_MIXED_PRECISION - integer(kind=1), dimension(0:m,0:n,0:p), intent(inout) :: patch_id_fp + integer(kind=1), dimension(0:m, 0:n, 0:p), intent(inout) :: patch_id_fp #else - integer, dimension(0:m,0:n,0:p), intent(inout) :: patch_id_fp + integer, dimension(0:m, 0:n, 0:p), intent(inout) :: patch_id_fp #endif type(scalar_field), dimension(1:sys_size), intent(inout) :: q_prim_vf - integer :: i, j, k !< Generic loop iterators - real(wp) :: a, b, c, d + integer :: i, j, k !< Generic loop iterators + real(wp) :: a, b, c, d @:HardcodedDimensionsExtrusion() @:Hardcoded3DVariables() @@ -1217,13 +1499,19 @@ contains c = patch_icpp(patch_id)%normal(3) d = -a*x_centroid - b*y_centroid - c*z_centroid - ! Initialize eta=1; modified if smoothing is enabled + ! Initializing the pseudo volume fraction value to 1. The value will + ! be modified as the patch is laid out on the grid, but only in the + ! case that smearing of the sweep plane patch's boundary is enabled. eta = 1._wp - ! Assign patch vars if cell is covered and patch has write permission + ! Checking whether the region swept by the plane covers a particular + ! cell in the domain and verifying whether the current patch has the + ! permission to write to that cell. If both queries check out, the + ! primitive variables of the current patch are written to this cell. do k = 0, p do j = 0, n do i = 0, m + if (grid_geometry == 3) then call s_convert_cylindrical_to_cartesian_coord(y_cc(j), z_cc(k)) else @@ -1232,13 +1520,22 @@ contains end if if (patch_icpp(patch_id)%smoothen) then - eta = 5.e-1_wp + 5.e-1_wp*tanh(smooth_coeff/min(dx, dy, & - & dz)*(a*x_cc(i) + b*cart_y + c*cart_z + d)/sqrt(a**2 + b**2 + c**2)) + eta = 5.e-1_wp + 5.e-1_wp*tanh(smooth_coeff/min(dx, dy, dz) & + *(a*x_cc(i) + & + b*cart_y + & + c*cart_z + d) & + /sqrt(a**2 + b**2 + c**2)) end if - if ((a*x_cc(i) + b*cart_y + c*cart_z + d >= 0._wp .and. patch_icpp(patch_id)%alter_patch(patch_id_fp(i, j, & - & k))) .or. patch_id_fp(i, j, k) == smooth_patch_id) then - call s_assign_patch_primitive_variables(patch_id, i, j, k, eta, q_prim_vf, patch_id_fp) + if ((a*x_cc(i) + b*cart_y + c*cart_z + d >= 0._wp & + .and. & + patch_icpp(patch_id)%alter_patch(patch_id_fp(i, j, k))) & + .or. & + patch_id_fp(i, j, k) == smooth_patch_id) & + then + + call s_assign_patch_primitive_variables(patch_id, i, j, k, & + eta, q_prim_vf, patch_id_fp) @:analytical() if (patch_icpp(patch_id)%hcid /= dflt_int) then @@ -1248,6 +1545,7 @@ contains ! Updating the patch identities bookkeeping variable if (1._wp - eta < sgm_eps) patch_id_fp(i, j, k) = patch_id end if + end do end do end do @@ -1256,35 +1554,43 @@ contains end subroutine s_icpp_sweep_plane !> The STL patch is a 2/3D geometry that is imported from an STL file. + !! @param patch_id is the patch identifier + !! @param patch_id_fp Array to track patch ids + !! @param q_prim_vf Primitive variables subroutine s_icpp_model(patch_id, patch_id_fp, q_prim_vf) integer, intent(in) :: patch_id - #ifdef MFC_MIXED_PRECISION - integer(kind=1), dimension(0:m,0:n,0:p), intent(inout) :: patch_id_fp + integer(kind=1), dimension(0:m, 0:n, 0:p), intent(inout) :: patch_id_fp #else - integer, dimension(0:m,0:n,0:p), intent(inout) :: patch_id_fp + integer, dimension(0:m, 0:n, 0:p), intent(inout) :: patch_id_fp #endif type(scalar_field), dimension(1:sys_size), intent(inout) :: q_prim_vf ! Variables for IBM+STL - real(wp) :: normals(1:3) !< Boundary normal buffer - integer :: boundary_vertex_count, boundary_edge_count, total_vertices !< Boundary vertex - real(wp), allocatable, dimension(:,:,:) :: boundary_v !< Boundary vertex buffer - real(wp) :: distance !< Levelset distance buffer - logical :: interpolate !< Logical variable to determine whether or not the model should be interpolated - integer :: i, j, k !< Generic loop iterators + real(wp) :: normals(1:3) !< Boundary normal buffer + integer :: boundary_vertex_count, boundary_edge_count, total_vertices !< Boundary vertex + real(wp), allocatable, dimension(:, :, :) :: boundary_v !< Boundary vertex buffer + real(wp) :: distance !< Levelset distance buffer + logical :: interpolate !< Logical variable to determine whether or not the model should be interpolated + + integer :: i, j, k !< Generic loop iterators + type(t_bbox) :: bbox, bbox_old type(t_model) :: model type(ic_model_parameters) :: params + real(wp), dimension(1:3) :: point, model_center - real(wp) :: grid_mm(1:3,1:2) + + real(wp) :: grid_mm(1:3, 1:2) + integer :: cell_num integer :: ncells - real(wp), dimension(1:4,1:4) :: transform, transform_n + + real(wp), dimension(1:4, 1:4) :: transform, transform_n if (proc_rank == 0) then - print *, " * Reading model: " // trim(patch_icpp(patch_id)%model_filepath) + print *, " * Reading model: "//trim(patch_icpp(patch_id)%model_filepath) end if model = f_model_read(patch_icpp(patch_id)%model_filepath) @@ -1328,49 +1634,57 @@ contains write (*, "(A, 3(2X, F20.10))") " > Cen:", (bbox%min(1:3) + bbox%max(1:3))/2._wp write (*, "(A, 3(2X, F20.10))") " > Max:", bbox%max(1:3) - grid_mm(1,:) = (/minval(x_cc) - 0.e5_wp*dx, maxval(x_cc) + 0.e5_wp*dx/) - grid_mm(2,:) = (/minval(y_cc) - 0.e5_wp*dy, maxval(y_cc) + 0.e5_wp*dy/) + !call s_model_write("__out__.stl", model) + !call s_model_write("__out__.obj", model) + + grid_mm(1, :) = (/minval(x_cc) - 0.e5_wp*dx, maxval(x_cc) + 0.e5_wp*dx/) + grid_mm(2, :) = (/minval(y_cc) - 0.e5_wp*dy, maxval(y_cc) + 0.e5_wp*dy/) if (p > 0) then - grid_mm(3,:) = (/minval(z_cc) - 0.e5_wp*dz, maxval(z_cc) + 0.e5_wp*dz/) + grid_mm(3, :) = (/minval(z_cc) - 0.e5_wp*dz, maxval(z_cc) + 0.e5_wp*dz/) else - grid_mm(3,:) = (/0._wp, 0._wp/) + grid_mm(3, :) = (/0._wp, 0._wp/) end if - write (*, "(A, 3(2X, F20.10))") " > Domain: Min:", grid_mm(:,1) - write (*, "(A, 3(2X, F20.10))") " > Cen:", (grid_mm(:,1) + grid_mm(:,2))/2._wp - write (*, "(A, 3(2X, F20.10))") " > Max:", grid_mm(:,2) + write (*, "(A, 3(2X, F20.10))") " > Domain: Min:", grid_mm(:, 1) + write (*, "(A, 3(2X, F20.10))") " > Cen:", (grid_mm(:, 1) + grid_mm(:, 2))/2._wp + write (*, "(A, 3(2X, F20.10))") " > Max:", grid_mm(:, 2) end if ncells = (m + 1)*(n + 1)*(p + 1) do i = 0, m; do j = 0, n; do k = 0, p - cell_num = i*(n + 1)*(p + 1) + j*(p + 1) + (k + 1) - if (proc_rank == 0 .and. mod(cell_num, ncells/100) == 0) then - write (*, "(A, I3, A)", advance="no") char(13) // " * Generating grid: ", nint(100*real(cell_num)/ncells), "%" - end if - point = (/x_cc(i), y_cc(j), 0._wp/) - if (p > 0) then - point(3) = z_cc(k) - end if + cell_num = i*(n + 1)*(p + 1) + j*(p + 1) + (k + 1) + if (proc_rank == 0 .and. mod(cell_num, ncells/100) == 0) then + write (*, "(A, I3, A)", advance="no") & + char(13)//" * Generating grid: ", & + nint(100*real(cell_num)/ncells), "%" + end if - if (grid_geometry == 3) then - point = f_convert_cyl_to_cart(point) - end if + point = (/x_cc(i), y_cc(j), 0._wp/) + if (p > 0) then + point(3) = z_cc(k) + end if - eta = f_model_is_inside(model, point, (/dx, dy, dz/), patch_icpp(patch_id)%model_spc) + if (grid_geometry == 3) then + point = f_convert_cyl_to_cart(point) + end if - if (eta > patch_icpp(patch_id)%model_threshold) then - eta = 1._wp - else if (.not. patch_icpp(patch_id)%smoothen) then - eta = 0._wp - end if + eta = f_model_is_inside(model, point, (/dx, dy, dz/), patch_icpp(patch_id)%model_spc) + + if (eta > patch_icpp(patch_id)%model_threshold) then + eta = 1._wp + else if (.not. patch_icpp(patch_id)%smoothen) then + eta = 0._wp + end if - call s_assign_patch_primitive_variables(patch_id, i, j, k, eta, q_prim_vf, patch_id_fp) + call s_assign_patch_primitive_variables(patch_id, i, j, k, & + eta, q_prim_vf, patch_id_fp) - ! Note: Should probably use *eta* to compute primitive variables if defining them analytically. - @:analytical() - end do; end do; end do + ! Note: Should probably use *eta* to compute primitive variables + ! if defining them analytically. + @:analytical() + end do; end do; end do if (proc_rank == 0) then print *, "" @@ -1381,9 +1695,8 @@ contains end subroutine s_icpp_model - !> Convert cylindrical (r, theta) coordinates to Cartesian (y, z) module variables. + !> @brief Converts cylindrical (r, theta) coordinates to Cartesian (y, z) module variables. subroutine s_convert_cylindrical_to_cartesian_coord(cyl_y, cyl_z) - $:GPU_ROUTINE(parallelism='[seq]') real(wp), intent(in) :: cyl_y, cyl_z @@ -1393,42 +1706,45 @@ contains end subroutine s_convert_cylindrical_to_cartesian_coord - !> Return a 3D Cartesian coordinate vector from a cylindrical (x, r, theta) input vector. + !> @brief Returns a 3D Cartesian coordinate vector from a cylindrical (x, r, theta) input vector. function f_convert_cyl_to_cart(cyl) result(cart) $:GPU_ROUTINE(parallelism='[seq]') real(wp), dimension(1:3), intent(in) :: cyl - real(wp), dimension(1:3) :: cart + real(wp), dimension(1:3) :: cart - cart = (/cyl(1), cyl(2)*sin(cyl(3)), cyl(2)*cos(cyl(3))/) + cart = (/cyl(1), & + cyl(2)*sin(cyl(3)), & + cyl(2)*cos(cyl(3))/) end function f_convert_cyl_to_cart - !> Compute the spherical azimuthal angle from cylindrical (x, r) coordinates. + !> @brief Computes the spherical azimuthal angle from cylindrical (x, r) coordinates. subroutine s_convert_cylindrical_to_spherical_coord(cyl_x, cyl_y) - $:GPU_ROUTINE(parallelism='[seq]') - real(wp), intent(in) :: cyl_x, cyl_y + real(wp), intent(IN) :: cyl_x, cyl_y sph_phi = atan(cyl_y/cyl_x) end subroutine s_convert_cylindrical_to_spherical_coord !> Archimedes spiral function + !! @param myth Angle + !! @param offset Thickness + !! @param a Starting position elemental function f_r(myth, offset, a) $:GPU_ROUTINE(parallelism='[seq]') real(wp), intent(in) :: myth, offset, a - real(wp) :: b - real(wp) :: f_r + real(wp) :: b + real(wp) :: f_r - ! r(th) = a + b*th + !r(th) = a + b*th b = 2._wp*a/(2._wp*pi) f_r = a + b*myth + offset - end function f_r end module m_icpp_patches diff --git a/src/pre_process/m_initial_condition.fpp b/src/pre_process/m_initial_condition.fpp index 0b5a6ba40a..45ad160af0 100644 --- a/src/pre_process/m_initial_condition.fpp +++ b/src/pre_process/m_initial_condition.fpp @@ -5,69 +5,104 @@ !> @brief Assembles initial conditions by layering prioritized patches via constructive solid geometry module m_initial_condition - use m_derived_types - use m_global_parameters - use m_mpi_proxy + use m_derived_types ! Definitions of the derived types + + use m_global_parameters ! Global parameters for the code + + use m_mpi_proxy !< Message passing interface (MPI) module proxy + use m_helper - use m_variables_conversion + + use m_variables_conversion ! Subroutines to change the state variables from + ! one form to another + use m_icpp_patches + use m_assign_variables - use m_perturbation + + use m_perturbation ! Subroutines to perturb initial flow fields + use m_chemistry + use m_boundary_conditions implicit none - ! NOTE: Abstract interface enables dynamic dispatch without repeated model_eqns checks - type(scalar_field), allocatable, dimension(:) :: q_prim_vf !< primitive variables - type(scalar_field), allocatable, dimension(:) :: q_cons_vf !< conservative variables - type(scalar_field) :: q_T_sf !< Temperature field - type(integer_field), dimension(:,:), allocatable :: bc_type !< bc_type fields - !> @cond + ! NOTE: The abstract interface allows for the declaration of a pointer to + ! a procedure such that the choice of the model equations does not have to + ! be queried every time the patch primitive variables are to be assigned in + ! a cell in the computational domain. + type(scalar_field), allocatable, dimension(:) :: q_prim_vf !< primitive variables + + type(scalar_field), allocatable, dimension(:) :: q_cons_vf !< conservative variables + + type(scalar_field) :: q_T_sf !< Temperature field + + type(integer_field), dimension(:, :), allocatable :: bc_type !< bc_type fields + +!> @cond #ifdef MFC_MIXED_PRECISION - integer(kind=1), allocatable, dimension(:,:,:) :: patch_id_fp + integer(kind=1), allocatable, dimension(:, :, :) :: patch_id_fp #else - !> @endcond - integer, allocatable, dimension(:,:,:) :: patch_id_fp - !> @cond +!> @endcond + integer, allocatable, dimension(:, :, :) :: patch_id_fp +!> @cond #endif - !> @endcond +!> @endcond contains - !> Computation of parameters, allocation procedures, and/or any other tasks needed to properly setup the module + !> Computation of parameters, allocation procedures, and/or + !! any other tasks needed to properly setup the module impure subroutine s_initialize_initial_condition_module - integer :: i, j, k, l + integer :: i, j, k, l !< generic loop iterators + ! Allocating the primitive and conservative variables allocate (q_prim_vf(1:sys_size)) allocate (q_cons_vf(1:sys_size)) do i = 1, sys_size - allocate (q_prim_vf(i)%sf(idwbuff(1)%beg:idwbuff(1)%end,idwbuff(2)%beg:idwbuff(2)%end,idwbuff(3)%beg:idwbuff(3)%end)) - allocate (q_cons_vf(i)%sf(idwbuff(1)%beg:idwbuff(1)%end,idwbuff(2)%beg:idwbuff(2)%end,idwbuff(3)%beg:idwbuff(3)%end)) + allocate (q_prim_vf(i)%sf(idwbuff(1)%beg:idwbuff(1)%end, & + idwbuff(2)%beg:idwbuff(2)%end, & + idwbuff(3)%beg:idwbuff(3)%end)) + allocate (q_cons_vf(i)%sf(idwbuff(1)%beg:idwbuff(1)%end, & + idwbuff(2)%beg:idwbuff(2)%end, & + idwbuff(3)%beg:idwbuff(3)%end)) end do if (chemistry) then - allocate (q_T_sf%sf(0:m,0:n,0:p)) + allocate (q_T_sf%sf(0:m, 0:n, 0:p)) end if - allocate (patch_id_fp(0:m,0:n,0:p)) + ! Allocating the patch identities bookkeeping variable + allocate (patch_id_fp(0:m, 0:n, 0:p)) if (qbmm .and. .not. polytropic) then - allocate (pb%sf(0:m,0:n,0:p,1:nnode,1:nb)) - allocate (mv%sf(0:m,0:n,0:p,1:nnode,1:nb)) + !Allocate bubble pressure pb and vapor mass mv for non-polytropic qbmm at all quad nodes and R0 bins + allocate (pb%sf(0:m, & + 0:n, & + 0:p, 1:nnode, 1:nb)) + allocate (mv%sf(0:m, & + 0:n, & + 0:p, 1:nnode, 1:nb)) end if + ! Setting default values for conservative and primitive variables so + ! that in the case that the initial condition is wrongly laid out on + ! the grid the simulation component will catch the problem on start- + ! up. The conservative variables do not need to be similarly treated + ! since they are computed directly from the primitive variables. do i = 1, sys_size - q_cons_vf(i)%sf = -1.e-6_stp ! real(dflt_real, kind=stp) ! TODO :: remove this magic number - q_prim_vf(i)%sf = -1.e-6_stp ! real(dflt_real, kind=stp) + q_cons_vf(i)%sf = -1.e-6_stp ! real(dflt_real, kind=stp) ! TODO :: remove this magic number + q_prim_vf(i)%sf = -1.e-6_stp ! real(dflt_real, kind=stp) end do - allocate (bc_type(1:num_dims,1:2)) + ! Allocating arrays to store the bc types + allocate (bc_type(1:num_dims, 1:2)) - allocate (bc_type(1, 1)%sf(0:0,0:n,0:p)) - allocate (bc_type(1, 2)%sf(0:0,0:n,0:p)) + allocate (bc_type(1, 1)%sf(0:0, 0:n, 0:p)) + allocate (bc_type(1, 2)%sf(0:0, 0:n, 0:p)) do l = 0, p do k = 0, n @@ -77,8 +112,8 @@ contains end do if (n > 0) then - allocate (bc_type(2, 1)%sf(-buff_size:m + buff_size,0:0,0:p)) - allocate (bc_type(2, 2)%sf(-buff_size:m + buff_size,0:0,0:p)) + allocate (bc_type(2, 1)%sf(-buff_size:m + buff_size, 0:0, 0:p)) + allocate (bc_type(2, 2)%sf(-buff_size:m + buff_size, 0:0, 0:p)) do l = 0, p do j = -buff_size, m + buff_size @@ -88,8 +123,8 @@ contains end do if (p > 0) then - allocate (bc_type(3, 1)%sf(-buff_size:m + buff_size,-buff_size:n + buff_size,0:0)) - allocate (bc_type(3, 2)%sf(-buff_size:m + buff_size,-buff_size:n + buff_size,0:0)) + allocate (bc_type(3, 1)%sf(-buff_size:m + buff_size, -buff_size:n + buff_size, 0:0)) + allocate (bc_type(3, 2)%sf(-buff_size:m + buff_size, -buff_size:n + buff_size, 0:0)) do k = -buff_size, n + buff_size do j = -buff_size, m + buff_size @@ -106,28 +141,38 @@ contains q_prim_vf(damage_idx)%sf = 0._wp end if - ! Initial hyper_cleaning state is always zero TODO more general + ! Initial hyper_cleaning state is always zero + ! TODO more general if (hyper_cleaning) then q_cons_vf(psi_idx)%sf = 0._wp q_prim_vf(psi_idx)%sf = 0._wp end if - ! Setting default values for patch identities bookkeeping variable. This is necessary to avoid any confusion in the - ! assessment of the extent of application that the overwrite permissions give a patch when it is being applied in the - ! domain. + ! Setting default values for patch identities bookkeeping variable. + ! This is necessary to avoid any confusion in the assessment of the + ! extent of application that the overwrite permissions give a patch + ! when it is being applied in the domain. patch_id_fp = 0 end subroutine s_initialize_initial_condition_module - !> Iterate over patches and, depending on the geometry type, call the related subroutine to setup the said geometry on the grid - !! using the primitive variables included with the patch parameters. The subroutine is complete once the primitive variables are - !! converted to conservative ones. + !> This subroutine peruses the patches and depending on the + !! type of geometry associated with a particular patch, it + !! calls the related subroutine to setup the said geometry + !! on the grid using the primitive variables included with + !! the patch parameters. The subroutine is complete once the + !! primitive variables are converted to conservative ones. impure subroutine s_generate_initial_condition integer :: i + ! Converting the conservative variables to the primitive ones given + ! preexisting initial condition data files were read in on start-up if (old_ic) then - call s_convert_conservative_to_primitive_variables(q_cons_vf, q_T_sf, q_prim_vf, idwbuff) + call s_convert_conservative_to_primitive_variables(q_cons_vf, & + q_T_sf, & + q_prim_vf, & + idwbuff) end if call s_apply_icpp_patches(patch_id_fp, q_prim_vf) @@ -140,22 +185,25 @@ contains if (simplex_perturb) call s_perturb_simplex(q_prim_vf) if (elliptic_smoothing) call s_elliptic_smoothing(q_prim_vf, bc_type) + ! Converting the primitive variables to the conservative ones call s_convert_primitive_to_conservative_variables(q_prim_vf, q_cons_vf) if (chemistry) call s_compute_T_from_primitives(q_T_sf, q_prim_vf, idwint) if (qbmm .and. .not. polytropic) then + !Initialize pb and mv call s_initialize_mv(q_cons_vf, mv%sf) call s_initialize_pb(q_cons_vf, mv%sf, pb%sf) end if end subroutine s_generate_initial_condition - !> Deallocation procedures for the module + !> Deallocation procedures for the module impure subroutine s_finalize_initial_condition_module - integer :: i + integer :: i !< Generic loop iterator + ! Dellocating the primitive and conservative variables do i = 1, sys_size deallocate (q_prim_vf(i)%sf) deallocate (q_cons_vf(i)%sf) @@ -168,6 +216,7 @@ contains deallocate (q_T_sf%sf) end if + ! Deallocating the patch identities bookkeeping variable deallocate (patch_id_fp) deallocate (bc_type(1, 1)%sf) diff --git a/src/pre_process/m_mpi_proxy.fpp b/src/pre_process/m_mpi_proxy.fpp index e9545ce865..d1db67180a 100644 --- a/src/pre_process/m_mpi_proxy.fpp +++ b/src/pre_process/m_mpi_proxy.fpp @@ -6,25 +6,35 @@ module m_mpi_proxy #ifdef MFC_MPI - use mpi + use mpi !< Message passing interface (MPI) module #endif use m_helper - use m_derived_types - use m_global_parameters + + use m_derived_types !< Definitions of the derived types + + use m_global_parameters !< Global parameters for the code + use m_mpi_common implicit none contains - !> Since only processor with rank 0 is in charge of reading and checking the consistency of the user provided inputs, these are - !! not available to the remaining processors. This subroutine is then in charge of broadcasting the required information. + !> Since only processor with rank 0 is in charge of reading + !! and checking the consistency of the user provided inputs, + !! these are not available to the remaining processors. This + !! subroutine is then in charge of broadcasting the required + !! information. impure subroutine s_mpi_bcast_user_inputs #ifdef MFC_MPI + + ! Generic loop iterator integer :: i, j + ! Generic flag used to identify and report MPI errors integer :: ierr + ! Logistics call MPI_BCAST(case_dir, len(case_dir), MPI_CHARACTER, 0, MPI_COMM_WORLD, ierr) #:for VAR in ['t_step_old', 't_step_start', 'm', 'n', 'p', 'm_glb', 'n_glb', 'p_glb', & @@ -33,7 +43,7 @@ contains & 'perturb_sph_fluid', 'num_patches', 'thermal', 'nb', 'dist_type',& & 'relax_model', 'num_ibs', 'n_start', 'elliptic_smoothing_iters', & & 'num_bc_patches', 'mixlayer_perturb_nk', 'recon_type', & - & 'muscl_order', 'igr_order' ] + & 'muscl_order', 'igr_order', 'fd_order'] call MPI_BCAST(${VAR}$, 1, MPI_INTEGER, 0, MPI_COMM_WORLD, ierr) #:endfor @@ -112,8 +122,8 @@ contains if (chemistry) then call MPI_BCAST(patch_icpp(i)%Y, size(patch_icpp(i)%Y), mpi_p, 0, MPI_COMM_WORLD, ierr) end if - ! Broadcast IB variables: patch_ib is indexed 1:num_patches_max, not 1:num_bc_patches_max, so these must live in the - ! num_patches_max loop. + ! Broadcast IB variables: patch_ib is indexed 1:num_patches_max, + ! not 1:num_bc_patches_max, so these must live in the num_patches_max loop. #:for VAR in ['vel', 'angular_vel', 'angles'] call MPI_BCAST(patch_ib(i)%${VAR}$, size(patch_ib(i)%${VAR}$), mpi_p, 0, MPI_COMM_WORLD, ierr) #:endfor @@ -133,6 +143,13 @@ contains #:endfor end do + ! Variables from input files for hardcoded patches + call MPI_BCAST(interface_file, len(interface_file), MPI_CHARACTER, 0, MPI_COMM_WORLD, ierr) + call MPI_BCAST(normFac, 1, mpi_p, 0, MPI_COMM_WORLD, ierr) + call MPI_BCAST(normMag, 1, mpi_p, 0, MPI_COMM_WORLD, ierr) + call MPI_BCAST(g0_ic, 1, mpi_p, 0, MPI_COMM_WORLD, ierr) + call MPI_BCAST(p0_ic, 1, mpi_p, 0, MPI_COMM_WORLD, ierr) + ! Simplex noise and fluid physical parameters do i = 1, num_fluids_max #:for VAR in [ 'gamma','pi_inf', 'G', 'cv', 'qv', 'qvp' ] @@ -166,6 +183,7 @@ contains call MPI_BCAST(simplex_params%perturb_vel_offset(i, j), 1, mpi_p, 0, MPI_COMM_WORLD, ierr) end do end do + #endif end subroutine s_mpi_bcast_user_inputs diff --git a/src/pre_process/m_perturbation.fpp b/src/pre_process/m_perturbation.fpp index f3096068c1..2093ea30dd 100644 --- a/src/pre_process/m_perturbation.fpp +++ b/src/pre_process/m_perturbation.fpp @@ -5,37 +5,43 @@ !> @brief Perturbs initial mean flow fields with random noise, mixing-layer instabilities, or simplex noise module m_perturbation - use m_derived_types - use m_global_parameters - use m_mpi_proxy - use m_boundary_common + use m_derived_types ! Definitions of the derived types + + use m_global_parameters ! Global parameters for the code + + use m_mpi_proxy !< Message passing interface (MPI) module proxy + + use m_boundary_common ! Boundary conditions module + use m_helper + use m_simplex_noise + use ieee_arithmetic implicit none - real(wp), allocatable, dimension(:,:,:,:) :: q_prim_temp + real(wp), allocatable, dimension(:, :, :, :) :: q_prim_temp contains - !> Allocate the temporary primitive variable array used by elliptic smoothing. + !> @brief Allocates the temporary primitive variable array used by elliptic smoothing. impure subroutine s_initialize_perturbation_module() if (elliptic_smoothing) then - allocate (q_prim_temp(0:m,0:n,0:p,1:sys_size)) + allocate (q_prim_temp(0:m, 0:n, 0:p, 1:sys_size)) end if end subroutine s_initialize_perturbation_module - !> Randomly perturb partial density fields at the interface of a spherical volume fraction region. + !> @brief Randomly perturbs partial density fields at the interface of a spherical volume fraction region. impure subroutine s_perturb_sphere(q_prim_vf) - type(scalar_field), dimension(sys_size), intent(inout) :: q_prim_vf - integer :: i, j, k, l - real(wp) :: perturb_alpha - real(wp) :: rand_real + integer :: i, j, k, l !< generic loop operators + + real(wp) :: perturb_alpha + real(wp) :: rand_real call random_seed() do k = 0, p @@ -45,12 +51,15 @@ contains perturb_alpha = q_prim_vf(E_idx + perturb_sph_fluid)%sf(i, j, k) - ! Perturb partial density fields to match perturbed volume fraction fields when the volume fraction is not near - ! 0 or 1 + ! Perturb partial density fields to match perturbed volume fraction fields + ! IF ((perturb_alpha >= 25e-2_wp) .AND. (perturb_alpha <= 75e-2_wp)) THEN if ((.not. f_approx_equal(perturb_alpha, 0._wp)) .and. (.not. f_approx_equal(perturb_alpha, 1._wp))) then + + ! Derive new partial densities do l = 1, num_fluids q_prim_vf(l)%sf(i, j, k) = q_prim_vf(E_idx + l)%sf(i, j, k)*fluid_rho(l) end do + end if end do end do @@ -58,16 +67,16 @@ contains end subroutine s_perturb_sphere - !> Add random noise to the velocity and void fraction of the surrounding flow field. + !> @brief Adds random noise to the velocity and void fraction of the surrounding flow field. impure subroutine s_perturb_surrounding_flow(q_prim_vf) - type(scalar_field), dimension(sys_size), intent(inout) :: q_prim_vf - integer :: i, j, k - real(wp) :: perturb_alpha - real(wp) :: rand_real + integer :: i, j, k !< generic loop iterators + real(wp) :: perturb_alpha + real(wp) :: rand_real call random_seed() + ! Perturb partial density or velocity of surrounding flow by some random small amount of noise do k = 0, p do j = 0, n do i = 0, m @@ -82,17 +91,17 @@ contains end do end do end do - end subroutine s_perturb_surrounding_flow - !> Iteratively smooth all primitive variable fields using a discrete elliptic (Laplacian) filter. + !> @brief Iteratively smooths all primitive variable fields using a discrete elliptic (Laplacian) filter. impure subroutine s_elliptic_smoothing(q_prim_vf, bc_type) - type(scalar_field), dimension(sys_size), intent(inout) :: q_prim_vf - type(integer_field), dimension(1:num_dims,1:2), intent(in) :: bc_type - integer :: i, j, k, l, q + type(scalar_field), dimension(sys_size), intent(inout) :: q_prim_vf + type(integer_field), dimension(1:num_dims, 1:2), intent(in) :: bc_type + integer :: i, j, k, l, q do q = 1, elliptic_smoothing_iters + ! Communication of buffer regions and apply boundary conditions call s_populate_variables_buffers(bc_type, q_prim_vf, pb%sf, mv%sf) @@ -100,17 +109,19 @@ contains if (n == 0) then do j = 0, m do i = 1, sys_size - q_prim_temp(j, 0, 0, i) = (1._wp/4._wp)*(q_prim_vf(i)%sf(j + 1, 0, 0) + q_prim_vf(i)%sf(j - 1, 0, & - & 0) + 2._wp*q_prim_vf(i)%sf(j, 0, 0)) + q_prim_temp(j, 0, 0, i) = (1._wp/4._wp)* & + (q_prim_vf(i)%sf(j + 1, 0, 0) + q_prim_vf(i)%sf(j - 1, 0, 0) + & + 2._wp*q_prim_vf(i)%sf(j, 0, 0)) end do end do else if (p == 0) then do k = 0, n do j = 0, m do i = 1, sys_size - q_prim_temp(j, k, 0, i) = (1._wp/8._wp)*(q_prim_vf(i)%sf(j + 1, k, 0) + q_prim_vf(i)%sf(j - 1, k, & - & 0) + q_prim_vf(i)%sf(j, k + 1, 0) + q_prim_vf(i)%sf(j, k - 1, & - & 0) + 4._wp*q_prim_vf(i)%sf(j, k, 0)) + q_prim_temp(j, k, 0, i) = (1._wp/8._wp)* & + (q_prim_vf(i)%sf(j + 1, k, 0) + q_prim_vf(i)%sf(j - 1, k, 0) + & + q_prim_vf(i)%sf(j, k + 1, 0) + q_prim_vf(i)%sf(j, k - 1, 0) + & + 4._wp*q_prim_vf(i)%sf(j, k, 0)) end do end do end do @@ -119,10 +130,11 @@ contains do k = 0, n do j = 0, m do i = 1, sys_size - q_prim_temp(j, k, l, i) = (1._wp/12._wp)*(q_prim_vf(i)%sf(j + 1, k, l) + q_prim_vf(i)%sf(j - 1, & - & k, l) + q_prim_vf(i)%sf(j, k + 1, l) + q_prim_vf(i)%sf(j, k - 1, & - & l) + q_prim_vf(i)%sf(j, k, l + 1) + q_prim_vf(i)%sf(j, k, & - & l - 1) + 6._wp*q_prim_vf(i)%sf(j, k, l)) + q_prim_temp(j, k, l, i) = (1._wp/12._wp)* & + (q_prim_vf(i)%sf(j + 1, k, l) + q_prim_vf(i)%sf(j - 1, k, l) + & + q_prim_vf(i)%sf(j, k + 1, l) + q_prim_vf(i)%sf(j, k - 1, l) + & + q_prim_vf(i)%sf(j, k, l + 1) + q_prim_vf(i)%sf(j, k, l - 1) + & + 6._wp*q_prim_vf(i)%sf(j, k, l)) end do end do end do @@ -143,15 +155,16 @@ contains end subroutine s_elliptic_smoothing - !> Perturb velocity and volume fraction fields using multi-octave simplex noise. + !> @brief Perturbs velocity and volume fraction fields using multi-octave simplex noise. subroutine s_perturb_simplex(q_prim_vf) type(scalar_field), dimension(sys_size), intent(inout) :: q_prim_vf - real(wp) :: mag, freq, scale, vel_rsm - real(wp), dimension(:,:), allocatable :: ofs - integer :: nOffsets - real(wp) :: xl, yl, zl - integer :: i, j, k, l, q + real(wp) :: mag, freq, scale, vel_rsm + real(wp), dimension(:, :), allocatable :: ofs + integer :: nOffsets + real(wp) :: xl, yl, zl + + integer :: i, j, k, l, q nOffsets = max(num_dims, num_fluids) @@ -176,7 +189,7 @@ contains yl = freq*(y_cc(k) + ofs(i, 2)) if (num_dims == 2) then mag = f_simplex2d(xl, yl) - else if (num_dims == 3) then + elseif (num_dims == 3) then zl = freq*(z_cc(l) + ofs(i, 3)) mag = f_simplex3d(xl, yl, zl) end if @@ -187,7 +200,8 @@ contains end do vel_rsm = sqrt(vel_rsm) - q_prim_vf(momxb + i - 1)%sf(j, k, l) = q_prim_vf(momxb + i - 1)%sf(j, k, l) + vel_rsm*scale*mag + q_prim_vf(momxb + i - 1)%sf(j, k, l) = q_prim_vf(momxb + i - 1)%sf(j, k, l) + & + vel_rsm*scale*mag end do end do end do @@ -213,12 +227,12 @@ contains yl = freq*(y_cc(k) + ofs(i, 2)) if (num_dims == 2) then mag = f_simplex2d(xl, yl) - else if (num_dims == 3) then + elseif (num_dims == 3) then zl = freq*(z_cc(l) + ofs(i, 3)) mag = f_simplex3d(xl, yl, zl) end if - q_prim_vf(contxb + i - 1)%sf(j, k, l) = q_prim_vf(contxb + i - 1)%sf(j, k, & - & l) + q_prim_vf(contxb + i - 1)%sf(j, k, l)*scale*mag + q_prim_vf(contxb + i - 1)%sf(j, k, l) = q_prim_vf(contxb + i - 1)%sf(j, k, l) + & + q_prim_vf(contxb + i - 1)%sf(j, k, l)*scale*mag end do end do end do @@ -229,17 +243,20 @@ contains end subroutine s_perturb_simplex - !> Compute velocity perturbations for a temporal mixing layer with a hyperbolic tangent mean streamwise velocity profile, using - !! an inverted version of the spectrum-based synthetic turbulence generation method proposed by Guo et al. (2023, JFM). + !> This subroutine computes velocity perturbations for a temporal mixing + !! layer with a hyperbolic tangent mean streamwise velocity + !! profile, using an inverted version of the spectrum-based + !! synthetic turbulence generation method proposed by + !! Guo et al. (2023, JFM). subroutine s_perturb_mixlayer(q_prim_vf) - type(scalar_field), dimension(sys_size), intent(inout) :: q_prim_vf - real(wp), dimension(mixlayer_perturb_nk) :: k, Ek - real(wp), dimension(3, 3) :: Rij, Lmat - real(wp), dimension(3) :: velfluc, sig_tmp, sig, khat, xi - real(wp) :: dk, alpha, Eksum, q, uu0, phi - integer :: i, j, l, r, ierr + real(wp), dimension(mixlayer_perturb_nk) :: k, Ek + real(wp), dimension(3, 3) :: Rij, Lmat + real(wp), dimension(3) :: velfluc, sig_tmp, sig, khat, xi + real(wp) :: dk, alpha, Eksum, q, uu0, phi + integer :: i, j, l, r, ierr + ! Initialize parameters dk = 1._wp/mixlayer_perturb_nk ! Compute prescribed energy spectra @@ -252,9 +269,11 @@ contains ! Main loop do r = 0, n - ! Compute prescribed Reynolds stress tensor with about half magnitude of its self-similar value - Rij(:,:) = 0._wp - uu0 = patch_icpp(1)%vel(1)**2._wp*(1._wp - tanh(y_cc(r)*mixlayer_vel_coef)**2._wp) + ! Compute prescribed Reynolds stress tensor with about half + ! magnitude of its self-similar value + Rij(:, :) = 0._wp + uu0 = patch_icpp(1)%vel(1)**2._wp & + *(1._wp - tanh(y_cc(r)*mixlayer_vel_coef)**2._wp) Rij(1, 1) = 0.05_wp*uu0 Rij(2, 2) = 0.03_wp*uu0 Rij(3, 3) = 0.03_wp*uu0 @@ -274,7 +293,8 @@ contains ! Compute perturbation for each Fourier component do i = 1, mixlayer_perturb_nk - ! Generate random numbers for unit wavevector khat, random unit vector xi, and random mode phase phi + ! Generate random numbers for unit wavevector khat, + ! random unit vector xi, and random mode phase phi if (proc_rank == 0) then call s_generate_random_perturbation(khat, xi, phi, i, y_cc(r)) end if @@ -307,15 +327,14 @@ contains end subroutine s_perturb_mixlayer - !> Generate deterministic pseudo-random wave vector, polarization, and phase for a perturbation mode. + !> @brief Generates deterministic pseudo-random wave vector, polarization, and phase for a perturbation mode. subroutine s_generate_random_perturbation(khat, xi, phi, ik, yloc) - - integer, intent(in) :: ik - real(wp), intent(in) :: yloc + integer, intent(in) :: ik + real(wp), intent(in) :: yloc real(wp), dimension(3), intent(out) :: khat, xi - real(wp), intent(out) :: phi - real(wp) :: theta, eta - integer :: seed, kfac, yfac + real(wp), intent(out) :: phi + real(wp) :: theta, eta + integer :: seed, kfac, yfac kfac = ik*amplifier yfac = nint((sin(yloc) + 1._wp)*amplifier) @@ -333,11 +352,10 @@ contains end subroutine s_generate_random_perturbation - !> Generate a unit vector uniformly distributed on the sphere from two random parameters. + !> @brief Generates a unit vector uniformly distributed on the sphere from two random parameters. function f_unit_vector(theta, eta) result(vec) - - real(wp), intent(in) :: theta, eta - real(wp) :: zeta, xi + real(wp), intent(in) :: theta, eta + real(wp) :: zeta, xi real(wp), dimension(3) :: vec xi = 2._wp*pi*theta @@ -348,24 +366,23 @@ contains end function f_unit_vector - !> Generate a pseudo-random number between 0 and 1 using a linear congruential generator. + !> This function generates a pseudo-random number between 0 and 1 based on + !! linear congruential generator. subroutine s_prng(var, seed) - integer, intent(inout) :: seed - real(wp), intent(out) :: var - integer :: i + real(wp), intent(out) :: var + integer :: i seed = mod(modmul(seed), modulus) var = seed/real(modulus, wp) end subroutine s_prng - !> Compute a modular multiplication step for the linear congruential pseudo-random number generator. + !> @brief Computes a modular multiplication step for the linear congruential pseudo-random number generator. function modmul(a) result(val) - integer, intent(in) :: a - integer :: val - real(wp) :: x, y + integer :: val + real(wp) :: x, y x = (multiplier/real(modulus, wp))*a + (increment/real(modulus, wp)) y = nint((x - floor(x))*decimal_trim)/decimal_trim @@ -373,7 +390,7 @@ contains end function modmul - !> Deallocate the temporary primitive variable array used by elliptic smoothing. + !> @brief Deallocates the temporary primitive variable array used by elliptic smoothing. impure subroutine s_finalize_perturbation_module() if (elliptic_smoothing) then diff --git a/src/pre_process/m_simplex_noise.fpp b/src/pre_process/m_simplex_noise.fpp index fb5ebcf226..5dacdda7b6 100644 --- a/src/pre_process/m_simplex_noise.fpp +++ b/src/pre_process/m_simplex_noise.fpp @@ -6,60 +6,85 @@ module m_simplex_noise use m_constants + use m_precision_select implicit none - private; public :: f_simplex3d, f_simplex2d - - integer, parameter :: p_vec(0:511) = [151, 160, 137, 91, 90, 15, 131, 13, 201, 95, 96, 53, 194, 233, 7, 225, 140, 36, 103, & - & 30, 69, 142, 8, 99, 37, 240, 21, 10, 23, 190, 6, 148, 247, 120, 234, 75, 0, 26, 197, 62, 94, & - & 252, 219, 203, 117, 35, 11, 32, 57, 177, 33, 88, 237, 149, 56, 87, 174, 20, 125, 136, 171, 168, & - & 68, 175, 74, 165, 71, 134, 139, 48, 27, 166, 77, 146, 158, 231, 83, 111, 229, 122, 60, 211, & - & 133, 230, 220, 105, 92, 41, 55, 46, 245, 40, 244, 102, 143, 54, 65, 25, 63, 161, 1, 216, 80, & - & 73, 209, 76, 132, 187, 208, 89, 18, 169, 200, 196, 135, 130, 116, 188, 159, 86, 164, 100, 109, & - & 198, 173, 186, 3, 64, 52, 217, 226, 250, 124, 123, 5, 202, 38, 147, 118, 126, 255, 82, 85, 212, & - & 207, 206, 59, 227, 47, 16, 58, 17, 182, 189, 28, 42, 223, 183, 170, 213, 119, 248, 152, 2, 44, & - & 154, 163, 70, 221, 153, 101, 155, 167, 43, 172, 9, 129, 22, 39, 253, 19, 98, 108, 110, 79, 113, & - & 224, 232, 178, 185, 112, 104, 218, 246, 97, 228, 251, 34, 242, 193, 238, 210, 144, 12, 191, & - & 179, 162, 241, 81, 51, 145, 235, 249, 14, 239, 107, 49, 192, 214, 31, 181, 199, 106, 157, 184, & - & 84, 204, 176, 115, 121, 50, 45, 127, 4, 150, 254, 138, 236, 205, 93, 222, 114, 67, 29, 24, 72, & - & 243, 141, 128, 195, 78, 66, 215, 61, 156, 180, 151, 160, 137, 91, 90, 15, 131, 13, 201, 95, 96, & - & 53, 194, 233, 7, 225, 140, 36, 103, 30, 69, 142, 8, 99, 37, 240, 21, 10, 23, 190, 6, 148, 247, & - & 120, 234, 75, 0, 26, 197, 62, 94, 252, 219, 203, 117, 35, 11, 32, 57, 177, 33, 88, 237, 149, & - & 56, 87, 174, 20, 125, 136, 171, 168, 68, 175, 74, 165, 71, 134, 139, 48, 27, 166, 77, 146, 158, & - & 231, 83, 111, 229, 122, 60, 211, 133, 230, 220, 105, 92, 41, 55, 46, 245, 40, 244, 102, 143, & - & 54, 65, 25, 63, 161, 1, 216, 80, 73, 209, 76, 132, 187, 208, 89, 18, 169, 200, 196, 135, 130, & - & 116, 188, 159, 86, 164, 100, 109, 198, 173, 186, 3, 64, 52, 217, 226, 250, 124, 123, 5, 202, & - & 38, 147, 118, 126, 255, 82, 85, 212, 207, 206, 59, 227, 47, 16, 58, 17, 182, 189, 28, 42, 223, & - & 183, 170, 213, 119, 248, 152, 2, 44, 154, 163, 70, 221, 153, 101, 155, 167, 43, 172, 9, 129, & - & 22, 39, 253, 19, 98, 108, 110, 79, 113, 224, 232, 178, 185, 112, 104, 218, 246, 97, 228, 251, & - & 34, 242, 193, 238, 210, 144, 12, 191, 179, 162, 241, 81, 51, 145, 235, 249, 14, 239, 107, 49, & - & 192, 214, 31, 181, 199, 106, 157, 184, 84, 204, 176, 115, 121, 50, 45, 127, 4, 150, 254, 138, & - & 236, 205, 93, 222, 114, 67, 29, 24, 72, 243, 141, 128, 195, 78, 66, 215, 61, 156, 180] - - real(wp), parameter :: grad3(12, 3) = reshape([1._wp, 1._wp, 0._wp, -1._wp, 1._wp, 0._wp, 1._wp, -1._wp, 0._wp, -1._wp, & - & -1._wp, 0._wp, 1._wp, 0._wp, 1._wp, -1._wp, 0._wp, 1._wp, 1._wp, 0._wp, -1._wp, -1._wp, 0._wp, -1._wp, 0._wp, 1._wp, & - & 1._wp, 0._wp, -1._wp, 1._wp, 0._wp, 1._wp, -1._wp, 0._wp, -1._wp, -1._wp], shape=[12, 3]) - - real(wp), parameter :: grad2(10, 2) = reshape([1._wp, 1._wp, -1._wp, 1._wp, 1._wp, -1._wp, -1._wp, -1._wp, 1._wp, 0._wp, & - & -1._wp, 0._wp, 0._wp, 1._wp, 0._wp, -1._wp, 1._wp, 1._wp, -1._wp, 1._wp], shape=[10, 2]) + private; public :: f_simplex3d, & + f_simplex2d + + integer, parameter :: p_vec(0:511) = [ & + 151, 160, 137, 91, 90, 15, 131, 13, 201, 95, 96, 53, 194, 233, 7, 225, 140, 36, 103, 30, & + 69, 142, 8, 99, 37, 240, 21, 10, 23, 190, 6, 148, 247, 120, 234, 75, 0, 26, 197, 62, 94, & + 252, 219, 203, 117, 35, 11, 32, 57, 177, 33, 88, 237, 149, 56, 87, 174, 20, 125, 136, & + 171, 168, 68, 175, 74, 165, 71, 134, 139, 48, 27, 166, 77, 146, 158, 231, 83, 111, 229, & + 122, 60, 211, 133, 230, 220, 105, 92, 41, 55, 46, 245, 40, 244, 102, 143, 54, 65, 25, 63, & + 161, 1, 216, 80, 73, 209, 76, 132, 187, 208, 89, 18, 169, 200, 196, 135, 130, 116, 188, & + 159, 86, 164, 100, 109, 198, 173, 186, 3, 64, 52, 217, 226, 250, 124, 123, 5, 202, 38, & + 147, 118, 126, 255, 82, 85, 212, 207, 206, 59, 227, 47, 16, 58, 17, 182, 189, 28, 42, 223, & + 183, 170, 213, 119, 248, 152, 2, 44, 154, 163, 70, 221, 153, 101, 155, 167, 43, 172, 9, & + 129, 22, 39, 253, 19, 98, 108, 110, 79, 113, 224, 232, 178, 185, 112, 104, 218, 246, 97, & + 228, 251, 34, 242, 193, 238, 210, 144, 12, 191, 179, 162, 241, 81, 51, 145, 235, 249, 14, & + 239, 107, 49, 192, 214, 31, 181, 199, 106, 157, 184, 84, 204, 176, 115, 121, 50, 45, 127, & + 4, 150, 254, 138, 236, 205, 93, 222, 114, 67, 29, 24, 72, 243, 141, 128, 195, 78, 66, 215, & + 61, 156, 180, & + 151, 160, 137, 91, 90, 15, 131, 13, 201, 95, 96, 53, 194, 233, 7, 225, 140, 36, 103, 30, & + 69, 142, 8, 99, 37, 240, 21, 10, 23, 190, 6, 148, 247, 120, 234, 75, 0, 26, 197, 62, 94, & + 252, 219, 203, 117, 35, 11, 32, 57, 177, 33, 88, 237, 149, 56, 87, 174, 20, 125, 136, & + 171, 168, 68, 175, 74, 165, 71, 134, 139, 48, 27, 166, 77, 146, 158, 231, 83, 111, 229, & + 122, 60, 211, 133, 230, 220, 105, 92, 41, 55, 46, 245, 40, 244, 102, 143, 54, 65, 25, 63, & + 161, 1, 216, 80, 73, 209, 76, 132, 187, 208, 89, 18, 169, 200, 196, 135, 130, 116, 188, & + 159, 86, 164, 100, 109, 198, 173, 186, 3, 64, 52, 217, 226, 250, 124, 123, 5, 202, 38, & + 147, 118, 126, 255, 82, 85, 212, 207, 206, 59, 227, 47, 16, 58, 17, 182, 189, 28, 42, 223, & + 183, 170, 213, 119, 248, 152, 2, 44, 154, 163, 70, 221, 153, 101, 155, 167, 43, 172, 9, & + 129, 22, 39, 253, 19, 98, 108, 110, 79, 113, 224, 232, 178, 185, 112, 104, 218, 246, 97, & + 228, 251, 34, 242, 193, 238, 210, 144, 12, 191, 179, 162, 241, 81, 51, 145, 235, 249, 14, & + 239, 107, 49, 192, 214, 31, 181, 199, 106, 157, 184, 84, 204, 176, 115, 121, 50, 45, 127, & + 4, 150, 254, 138, 236, 205, 93, 222, 114, 67, 29, 24, 72, 243, 141, 128, 195, 78, 66, 215, & + 61, 156, 180] + + real(wp), parameter :: grad3(12, 3) = reshape([ & + 1._wp, 1._wp, 0._wp, & + -1._wp, 1._wp, 0._wp, & + 1._wp, -1._wp, 0._wp, & + -1._wp, -1._wp, 0._wp, & + 1._wp, 0._wp, 1._wp, & + -1._wp, 0._wp, 1._wp, & + 1._wp, 0._wp, -1._wp, & + -1._wp, 0._wp, -1._wp, & + 0._wp, 1._wp, 1._wp, & + 0._wp, -1._wp, 1._wp, & + 0._wp, 1._wp, -1._wp, & + 0._wp, -1._wp, -1._wp], shape=[12, 3]) + + real(wp), parameter :: grad2(10, 2) = reshape([ & + 1._wp, 1._wp, & + -1._wp, 1._wp, & + 1._wp, -1._wp, & + -1._wp, -1._wp, & + 1._wp, 0._wp, & + -1._wp, 0._wp, & + 0._wp, 1._wp, & + 0._wp, -1._wp, & + 1._wp, 1._wp, & + -1._wp, 1._wp], shape=[10, 2]) contains - !> Evaluate 3D simplex noise at the given coordinates and return a value in [-1, 1]. + !> @brief Evaluates 3D simplex noise at the given coordinates and returns a value in [-1, 1]. function f_simplex3d(xin, yin, zin) result(n) real(wp), intent(in) :: xin, yin, zin - real(wp) :: n - real(wp) :: n0, n1, n2, n3 - real(wp) :: f3, g3 - real(wp) :: x0, y0, z0, x1, y1, z1, x2, y2, z2, x3, y3, z3 - integer :: i, j, k, i1, j1, k1, i2, j2, k2 - integer :: ii, jj, kk, gi0, gi1, gi2, gi3 - real(wp) :: s, t, r, t0, t1, t2, t3 - real(wp) :: g(3) - real(wp) :: x, y, z + real(wp) :: n + real(wp) :: n0, n1, n2, n3 + real(wp) :: f3, g3 + real(wp) :: x0, y0, z0, x1, y1, z1, x2, y2, z2, x3, y3, z3 + integer :: i, j, k, i1, j1, k1, i2, j2, k2 + integer :: ii, jj, kk, gi0, gi1, gi2, gi3 + real(wp) :: s, t, r, t0, t1, t2, t3 + real(wp) :: g(3) + real(wp) :: x, y, z f3 = 1._wp/3._wp g3 = 1._wp/6._wp @@ -117,7 +142,7 @@ contains n0 = 0._wp else t0 = t0*t0 - n0 = t0*t0*dot_product(grad3(gi0,:), [x0, y0, z0]) + n0 = t0*t0*dot_product(grad3(gi0, :), [x0, y0, z0]) end if t1 = 0.5_wp - x1*x1 - y1*y1 - z1*z1 @@ -125,7 +150,7 @@ contains n1 = 0._wp else t1 = t1*t1 - n1 = t1*t1*dot_product(grad3(gi1,:), [x1, y1, z1]) + n1 = t1*t1*dot_product(grad3(gi1, :), [x1, y1, z1]) end if t2 = 0.5_wp - x2*x2 - y2*y2 - z2*z2 @@ -133,7 +158,7 @@ contains n2 = 0._wp else t2 = t2*t2 - n2 = t2*t2*dot_product(grad3(gi2,:), [x2, y2, z2]) + n2 = t2*t2*dot_product(grad3(gi2, :), [x2, y2, z2]) end if t3 = 0.5_wp - x3*x3 - y3*y3 - z3*z3 @@ -141,24 +166,24 @@ contains n3 = 0._wp else t3 = t3*t3 - n3 = t3*t3*dot_product(grad3(gi3,:), [x3, y3, z3]) + n3 = t3*t3*dot_product(grad3(gi3, :), [x3, y3, z3]) end if n = 32._wp*(n0 + n1 + n2 + n3) end function f_simplex3d - !> Evaluate 2D simplex noise at the given coordinates and return a value in [-1, 1]. + !> @brief Evaluates 2D simplex noise at the given coordinates and returns a value in [-1, 1]. function f_simplex2d(xin, yin) result(n) real(wp), intent(in) :: xin, yin - real(wp) :: n - real(wp), parameter :: F2 = 0.5_wp*(sqrt(3._wp) - 1._wp) - real(wp), parameter :: G2 = (3._wp - sqrt(3._wp))/6._wp - integer :: i, j, ii, jj, gi0, gi1, gi2 - real(wp) :: s, t, x0, y0, x1, y1, x2, y2 - real(wp) :: t0, t1, t2, n0, n1, n2 - integer :: i1, j1 + real(wp) :: n + real(wp), parameter :: F2 = 0.5_wp*(sqrt(3._wp) - 1._wp) + real(wp), parameter :: G2 = (3._wp - sqrt(3._wp))/6._wp + integer :: i, j, ii, jj, gi0, gi1, gi2 + real(wp) :: s, t, x0, y0, x1, y1, x2, y2 + real(wp) :: t0, t1, t2, n0, n1, n2 + integer :: i1, j1 s = (xin + yin)*F2 i = floor(xin + s) @@ -215,15 +240,14 @@ contains end function f_simplex2d - !> Compute the dot product of a 2D gradient vector with the given offset coordinates. + !> @brief Computes the dot product of a 2D gradient vector with the given offset coordinates. function dot2(g, x, y) result(dot) - integer, intent(in) :: g + integer, intent(in) :: g real(wp), intent(in) :: x, y - real(wp) :: dot - + real(wp) :: dot dot = grad2(g + 1, 1)*x + grad2(g + 1, 2)*y - end function dot2 + end function end module m_simplex_noise diff --git a/src/pre_process/m_start_up.fpp b/src/pre_process/m_start_up.fpp index a3a7c51270..97387e9b4a 100644 --- a/src/pre_process/m_start_up.fpp +++ b/src/pre_process/m_start_up.fpp @@ -7,101 +7,173 @@ !> @brief Reads and validates user inputs, loads existing grid/IC data, and initializes pre-process modules module m_start_up - use m_derived_types - use m_global_parameters - use m_mpi_proxy + use m_derived_types !< Definitions of the derived types + + use m_global_parameters !< Global parameters for the code + + use m_mpi_proxy !< Message passing interface (MPI) module proxy + use m_mpi_common - use m_variables_conversion - use m_grid - use m_initial_condition - use m_data_output - use m_compile_specific + + use m_variables_conversion !< Subroutines to change the state variables from + !! one form to another + + use m_grid !< Procedures to generate (non-)uniform grids + + use m_initial_condition !< Procedures to generate initial condition + + use m_data_output !< Procedures to write the grid data and the + !! conservative variables to files + + use m_compile_specific !< Compile-specific procedures + use m_icpp_patches + use m_assign_variables - use m_phase_change - use m_helper_basic + + use m_phase_change !< Phase-change module + + use m_helper_basic !< Functions to compare floating point numbers + use m_helper #ifdef MFC_MPI - use mpi + use mpi !< Message passing interface (MPI) module #endif use m_check_patches + use m_check_ib_patches + use m_helper + use m_checker_common + use m_checker + use m_boundary_common + use m_boundary_conditions implicit none - private - public :: s_read_input_file, s_check_input_file, s_read_grid_data_files, s_read_ic_data_files, s_read_serial_grid_data_files, & - & s_read_serial_ic_data_files, s_read_parallel_grid_data_files, s_read_parallel_ic_data_files, s_check_grid_data_files, & - & s_initialize_modules, s_initialize_mpi_domain, s_finalize_modules, s_apply_initial_condition, s_save_data, s_read_grid + private; + public :: s_read_input_file, & + s_check_input_file, & + s_read_grid_data_files, & + s_read_ic_data_files, & + s_read_serial_grid_data_files, & + s_read_serial_ic_data_files, & + s_read_parallel_grid_data_files, & + s_read_parallel_ic_data_files, & + s_check_grid_data_files, & + s_initialize_modules, & + s_initialize_mpi_domain, & + s_finalize_modules, & + s_apply_initial_condition, & + s_save_data, s_read_grid abstract interface - !> Abstract interface for reading grid data files in serial or parallel. + !> @brief Abstract interface for reading grid data files in serial or parallel. impure subroutine s_read_abstract_grid_data_files end subroutine s_read_abstract_grid_data_files - !> Abstract interface for reading initial condition data files in serial or parallel. + !> @brief Abstract interface for reading initial condition data files in serial or parallel. + !! @param q_cons_vf Conservative variables impure subroutine s_read_abstract_ic_data_files(q_cons_vf_in) import :: scalar_field, integer_field, sys_size, pres_field - type(scalar_field), dimension(sys_size), intent(inout) :: q_cons_vf_in + type(scalar_field), & + dimension(sys_size), & + intent(inout) :: q_cons_vf_in end subroutine s_read_abstract_ic_data_files + end interface - character(LEN=path_len + name_len) :: proc_rank_dir !< Location of the folder associated with the rank of the local processor - character(LEN=path_len + 2*name_len), private :: t_step_dir !< Path to preexisting time-step folder for restart + character(LEN=path_len + name_len) :: proc_rank_dir !< + !! Location of the folder associated with the rank of the local processor + + character(LEN=path_len + 2*name_len), private :: t_step_dir !< + !! Possible location of time-step folder containing preexisting grid and/or + !! conservative variables data to be used as starting point for pre-process + procedure(s_read_abstract_grid_data_files), pointer :: s_read_grid_data_files => null() procedure(s_read_abstract_ic_data_files), pointer :: s_read_ic_data_files => null() contains - !> Reads the configuration file pre_process.inp, in order to populate the parameters in module m_global_parameters.f90 with the - !! user provided inputs + !> Reads the configuration file pre_process.inp, in order to + !! populate the parameters in module m_global_parameters.f90 + !! with the user provided inputs impure subroutine s_read_input_file - character(LEN=name_len) :: file_loc - logical :: file_check - integer :: iostatus - character(len=1000) :: line - - namelist /user_inputs/ case_dir, old_grid, old_ic, t_step_old, t_step_start, m, n, p, x_domain, y_domain, z_domain, & - & stretch_x, stretch_y, stretch_z, a_x, a_y, a_z, x_a, y_a, z_a, x_b, y_b, z_b, model_eqns, num_fluids, mpp_lim, & - & weno_order, bc_x, bc_y, bc_z, num_patches, hypoelasticity, mhd, patch_icpp, fluid_pp, bub_pp, precision, & - & parallel_io, mixlayer_vel_profile, mixlayer_vel_coef, mixlayer_perturb, mixlayer_perturb_nk, mixlayer_perturb_k0, & - & pi_fac, perturb_flow, perturb_flow_fluid, perturb_flow_mag, perturb_sph, perturb_sph_fluid, fluid_rho, cyl_coord, & - & loops_x, loops_y, loops_z, rhoref, pref, bubbles_euler, R0ref, nb, polytropic, thermal, Ca, Web, Re_inv, & - & polydisperse, poly_sigma, qbmm, sigR, sigV, dist_type, rhoRV, file_per_process, relax, relax_model, palpha_eps, & - & ptgalpha_eps, ib, num_ibs, patch_ib, sigma, adv_n, cfl_adap_dt, cfl_const_dt, n_start, n_start_old, & - & surface_tension, hyperelasticity, pre_stress, elliptic_smoothing, elliptic_smoothing_iters, viscous, & - & bubbles_lagrange, num_bc_patches, patch_bc, Bx0, relativity, cont_damage, igr, igr_order, down_sample, recon_type, & - & muscl_order, hyper_cleaning, simplex_perturb, simplex_params, fft_wrt - + character(LEN=name_len) :: file_loc !< + !! Generic string used to store the address of a particular file + + logical :: file_check !< + !! Generic logical used for the purpose of asserting whether a file + !! is or is not present in the designated location + + integer :: iostatus + !! Integer to check iostat of file read + + character(len=1000) :: line + + ! Namelist for all of the parameters to be inputted by the user + namelist /user_inputs/ case_dir, old_grid, old_ic, & + t_step_old, t_step_start, m, n, p, x_domain, y_domain, z_domain, & + stretch_x, stretch_y, stretch_z, a_x, a_y, & + a_z, x_a, y_a, z_a, x_b, y_b, z_b, & + model_eqns, num_fluids, mpp_lim, & + weno_order, bc_x, bc_y, bc_z, num_patches, & + hypoelasticity, mhd, patch_icpp, fluid_pp, bub_pp, & + precision, parallel_io, mixlayer_vel_profile, mixlayer_vel_coef, & + mixlayer_perturb, mixlayer_perturb_nk, mixlayer_perturb_k0, & + pi_fac, perturb_flow, perturb_flow_fluid, perturb_flow_mag, & + perturb_sph, perturb_sph_fluid, fluid_rho, & + cyl_coord, loops_x, loops_y, loops_z, & + rhoref, pref, bubbles_euler, R0ref, nb, & + polytropic, thermal, Ca, Web, Re_inv, & + polydisperse, poly_sigma, qbmm, & + sigR, sigV, dist_type, rhoRV, & + file_per_process, relax, relax_model, & + palpha_eps, ptgalpha_eps, ib, num_ibs, patch_ib, & + sigma, adv_n, cfl_adap_dt, cfl_const_dt, n_start, & + n_start_old, surface_tension, hyperelasticity, pre_stress, & + elliptic_smoothing, elliptic_smoothing_iters, & + viscous, bubbles_lagrange, num_bc_patches, & + patch_bc, Bx0, relativity, cont_damage, igr, igr_order, & + down_sample, recon_type, muscl_order, fft_wrt, & + fd_order, lag_params, simplex_perturb, simplex_params, & + interface_file, normFac, normMag, & + g0_ic, p0_ic, hyper_cleaning + + ! Inquiring the status of the pre_process.inp file file_loc = 'pre_process.inp' inquire (FILE=trim(file_loc), EXIST=file_check) + ! Checking whether the input file is there. If it is, the input file + ! is read. If not, the program is terminated. if (file_check) then - open (1, FILE=trim(file_loc), form='formatted', STATUS='old', ACTION='read') + open (1, FILE=trim(file_loc), FORM='formatted', & + STATUS='old', ACTION='read') read (1, NML=user_inputs, iostat=iostatus) if (iostatus /= 0) then backspace (1) read (1, fmt='(A)') line - print *, 'Invalid line in namelist: ' // trim(line) - call s_mpi_abort('Invalid line in pre_process.inp. It is ' // 'likely due to a datatype mismatch. Exiting.') + print *, 'Invalid line in namelist: '//trim(line) + call s_mpi_abort('Invalid line in pre_process.inp. It is '// & + 'likely due to a datatype mismatch. Exiting.') end if close (1) call s_update_cell_bounds(cells_bounds, m, n, p) + ! Store m,n,p into global m,n,p m_glb = m n_glb = n p_glb = p @@ -110,237 +182,360 @@ contains if (cfl_adap_dt .or. cfl_const_dt) cfl_dt = .true. - if (any((/bc_x%beg, bc_x%end, bc_y%beg, bc_y%end, bc_z%beg, bc_z%end/) == BC_DIRICHLET) .or. num_bc_patches > 0) then + if (any((/bc_x%beg, bc_x%end, bc_y%beg, bc_y%end, bc_z%beg, bc_z%end/) == BC_DIRICHLET) .or. & + num_bc_patches > 0) then bc_io = .true. end if + else call s_mpi_abort('File pre_process.inp is missing. Exiting.') end if end subroutine s_read_input_file - !> Checking that the user inputs make sense, i.e. that the individual choices are compatible with the code's options and that - !! the combination of these choices results into a valid configuration for the pre-process + !> Checking that the user inputs make sense, i.e. that the + !! individual choices are compatible with the code's options + !! and that the combination of these choices results into a + !! valid configuration for the pre-process impure subroutine s_check_input_file - character(LEN=len_trim(case_dir)) :: file_loc - logical :: dir_check + character(LEN=len_trim(case_dir)) :: file_loc !< + !! Generic string used to store the address of a particular file + logical :: dir_check !< + !! Logical variable used to test the existence of folders + + ! Checking the existence of the case folder case_dir = adjustl(case_dir) - file_loc = trim(case_dir) // '/.' + file_loc = trim(case_dir)//'/.' call my_inquire(file_loc, dir_check) if (dir_check .neqv. .true.) then print '(A)', 'WARNING: Ensure that compiler flags/choices in Makefiles match your compiler! ' print '(A)', 'WARNING: Ensure that preprocessor flags are enabled! ' - call s_mpi_abort('Unsupported choice for the value of case_dir.' // 'Exiting.') + call s_mpi_abort('Unsupported choice for the value of case_dir.'// & + 'Exiting.') end if call s_check_inputs_common() call s_check_inputs() + ! Check all the patch properties call s_check_patches() if (ib) call s_check_ib_patches() end subroutine s_check_input_file - !> The goal of this subroutine is to read in any preexisting grid data as well as based on the imported grid, complete the - !! necessary global computational domain parameters. + !> The goal of this subroutine is to read in any preexisting + !! grid data as well as based on the imported grid, complete + !! the necessary global computational domain parameters. impure subroutine s_read_serial_grid_data_files + ! Generic string used to store the address of a particular file character(LEN=len_trim(case_dir) + 3*name_len) :: file_loc - logical :: dir_check - logical :: file_check + ! Logical variable used to test the existence of folders + logical :: dir_check + + ! Generic logical used for the purpose of asserting whether a file + ! is or is not present in the designated location + logical :: file_check + + ! Setting address of the local processor rank and time-step directory write (proc_rank_dir, '(A,I0)') '/p_all/p', proc_rank - proc_rank_dir = trim(case_dir) // trim(proc_rank_dir) + proc_rank_dir = trim(case_dir)//trim(proc_rank_dir) write (t_step_dir, '(A,I0)') '/', t_step_start - t_step_dir = trim(proc_rank_dir) // trim(t_step_dir) + t_step_dir = trim(proc_rank_dir)//trim(t_step_dir) - file_loc = trim(t_step_dir) // '/.' + ! Inquiring as to the existence of the time-step directory + file_loc = trim(t_step_dir)//'/.' call my_inquire(file_loc, dir_check) + ! If the time-step directory is missing, the pre-process exits if (dir_check .neqv. .true.) then - call s_mpi_abort('Time-step folder ' // trim(t_step_dir) // ' is missing. Exiting.') + call s_mpi_abort('Time-step folder '//trim(t_step_dir)// & + ' is missing. Exiting.') end if - file_loc = trim(t_step_dir) // '/x_cb.dat' + ! Reading the Grid Data File for the x-direction + + ! Checking whether x_cb.dat exists + file_loc = trim(t_step_dir)//'/x_cb.dat' inquire (FILE=trim(file_loc), EXIST=file_check) + ! If it exists, x_cb.dat is read if (file_check) then - open (1, FILE=trim(file_loc), form='unformatted', STATUS='old', ACTION='read') + open (1, FILE=trim(file_loc), FORM='unformatted', & + STATUS='old', ACTION='read') read (1) x_cb(-1:m) close (1) else - call s_mpi_abort('File x_cb.dat is missing in ' // trim(t_step_dir) // '. Exiting.') + call s_mpi_abort('File x_cb.dat is missing in '// & + trim(t_step_dir)//'. Exiting.') end if + ! Computing cell-center locations x_cc(0:m) = (x_cb(0:m) + x_cb(-1:(m - 1)))/2._wp + ! Computing minimum cell-width dx = minval(x_cb(0:m) - x_cb(-1:m - 1)) if (num_procs > 1) call s_mpi_reduce_min(dx) + ! Setting locations of domain bounds x_domain%beg = x_cb(-1) x_domain%end = x_cb(m) + ! Reading the Grid Data File for the y-direction + if (n > 0) then - file_loc = trim(t_step_dir) // '/y_cb.dat' + + ! Checking whether y_cb.dat exists + file_loc = trim(t_step_dir)//'/y_cb.dat' inquire (FILE=trim(file_loc), EXIST=file_check) + ! If it exists, y_cb.dat is read if (file_check) then - open (1, FILE=trim(file_loc), form='unformatted', STATUS='old', ACTION='read') + open (1, FILE=trim(file_loc), FORM='unformatted', & + STATUS='old', ACTION='read') read (1) y_cb(-1:n) close (1) else - call s_mpi_abort('File y_cb.dat is missing in ' // trim(t_step_dir) // '. Exiting.') + call s_mpi_abort('File y_cb.dat is missing in '// & + trim(t_step_dir)//'. Exiting.') end if + ! Computing cell-center locations y_cc(0:n) = (y_cb(0:n) + y_cb(-1:(n - 1)))/2._wp + ! Computing minimum cell-width dy = minval(y_cb(0:n) - y_cb(-1:n - 1)) if (num_procs > 1) call s_mpi_reduce_min(dy) + ! Setting locations of domain bounds y_domain%beg = y_cb(-1) y_domain%end = y_cb(n) + ! Reading the Grid Data File for the z-direction if (p > 0) then - file_loc = trim(t_step_dir) // '/z_cb.dat' + + ! Checking whether z_cb.dat exists + file_loc = trim(t_step_dir)//'/z_cb.dat' inquire (FILE=trim(file_loc), EXIST=file_check) + ! If it exists, z_cb.dat is read if (file_check) then - open (1, FILE=trim(file_loc), form='unformatted', STATUS='old', ACTION='read') + open (1, FILE=trim(file_loc), FORM='unformatted', & + STATUS='old', ACTION='read') read (1) z_cb(-1:p) close (1) else - call s_mpi_abort('File z_cb.dat is missing in ' // trim(t_step_dir) // '. Exiting.') + call s_mpi_abort('File z_cb.dat is missing in '// & + trim(t_step_dir)//'. Exiting.') end if + ! Computing cell-center locations z_cc(0:p) = (z_cb(0:p) + z_cb(-1:(p - 1)))/2._wp + ! Computing minimum cell-width dz = minval(z_cb(0:p) - z_cb(-1:p - 1)) if (num_procs > 1) call s_mpi_reduce_min(dz) + ! Setting locations of domain bounds z_domain%beg = z_cb(-1) z_domain%end = z_cb(p) + end if + end if - ! Clean processor dir and create time-step dir (unless reading preexisting IC) + ! If only the preexisting grid data files are read in and there will + ! not be any preexisting initial condition data files imported, then + ! the directory associated with the rank of the local processor may + ! be cleaned to make room for the new pre-process data. In addition, + ! the time-step directory that will contain the new grid and initial + ! condition data are also generated. if (old_ic .neqv. .true.) then call s_delete_directory(trim(proc_rank_dir)) - call s_create_directory(trim(proc_rank_dir) // '/0') + call s_create_directory(trim(proc_rank_dir)//'/0') end if end subroutine s_read_serial_grid_data_files - !> Cell-boundary data are checked for consistency by looking at the (non-)uniform cell-width distributions for all the active - !! coordinate directions and making sure that all of the cell-widths are positively valued + !> Cell-boundary data are checked for consistency by looking + !! at the (non-)uniform cell-width distributions for all the + !! active coordinate directions and making sure that all of + !! the cell-widths are positively valued impure subroutine s_check_grid_data_files + ! Cell-boundary Data Consistency Check in x-direction + if (any(x_cb(0:m) - x_cb(-1:m - 1) <= 0._wp)) then - call s_mpi_abort('x_cb.dat in ' // trim(t_step_dir) // ' contains non-positive cell-spacings. Exiting.') + call s_mpi_abort('x_cb.dat in '//trim(t_step_dir)// & + ' contains non-positive cell-spacings. Exiting.') end if + ! Cell-boundary Data Consistency Check in y-direction + if (n > 0) then + if (any(y_cb(0:n) - y_cb(-1:n - 1) <= 0._wp)) then - call s_mpi_abort('y_cb.dat in ' // trim(t_step_dir) // ' contains non-positive cell-spacings. ' // 'Exiting.') + call s_mpi_abort('y_cb.dat in '//trim(t_step_dir)// & + ' contains non-positive cell-spacings. '// & + 'Exiting.') end if + ! Cell-boundary Data Consistency Check in z-direction + if (p > 0) then + if (any(z_cb(0:p) - z_cb(-1:p - 1) <= 0._wp)) then - call s_mpi_abort('z_cb.dat in ' // trim(t_step_dir) // ' contains non-positive cell-spacings' // ' .Exiting.') + call s_mpi_abort('z_cb.dat in '//trim(t_step_dir)// & + ' contains non-positive cell-spacings'// & + ' .Exiting.') end if + end if + end if end subroutine s_check_grid_data_files - !> The goal of this subroutine is to read in any preexisting initial condition data files so that they may be used by the - !! pre-process as a starting point in the creation of an all new initial condition. + !> The goal of this subroutine is to read in any preexisting + !! initial condition data files so that they may be used by + !! the pre-process as a starting point in the creation of an + !! all new initial condition. + !! @param q_cons_vf_in Conservative variables impure subroutine s_read_serial_ic_data_files(q_cons_vf_in) - type(scalar_field), dimension(sys_size), intent(inout) :: q_cons_vf_in - character(LEN=len_trim(case_dir) + 3*name_len) :: file_loc - character(LEN=int(floor(log10(real(sys_size, wp)))) + 1) :: file_num - logical :: file_check - integer :: i, r + type(scalar_field), & + dimension(sys_size), & + intent(inout) :: q_cons_vf_in + + character(LEN=len_trim(case_dir) + 3*name_len) :: file_loc !< + ! Generic string used to store the address of a particular file + + character(LEN= & + int(floor(log10(real(sys_size, wp)))) + 1) :: file_num !< + !! Used to store the variable position, in character form, of the + !! currently manipulated conservative variable file + + logical :: file_check !< + !! Generic logical used for the purpose of asserting whether a file + !! is or is not present in the designated location + integer :: i, r !< Generic loop iterator + + ! Reading the Conservative Variables Data Files do i = 1, sys_size + + ! Checking whether data file associated with variable position + ! of the currently manipulated conservative variable exists write (file_num, '(I0)') i - file_loc = trim(t_step_dir) // '/q_cons_vf' // trim(file_num) // '.dat' + file_loc = trim(t_step_dir)//'/q_cons_vf'// & + trim(file_num)//'.dat' inquire (FILE=trim(file_loc), EXIST=file_check) + ! If it exists, the data file is read if (file_check) then - open (1, FILE=trim(file_loc), form='unformatted', STATUS='old', ACTION='read') + open (1, FILE=trim(file_loc), FORM='unformatted', & + STATUS='old', ACTION='read') read (1) q_cons_vf_in(i)%sf close (1) else - call s_mpi_abort('File q_cons_vf' // trim(file_num) // '.dat is missing in ' // trim(t_step_dir) // '. Exiting.') + call s_mpi_abort('File q_cons_vf'//trim(file_num)// & + '.dat is missing in '//trim(t_step_dir)// & + '. Exiting.') end if + end do + !Read bubble variables pb and mv for non-polytropic qbmm if (qbmm .and. .not. polytropic) then do i = 1, nb do r = 1, nnode + ! Checking whether data file associated with variable position + ! of the currently manipulated bubble variable exists write (file_num, '(I0)') sys_size + r + (i - 1)*nnode - file_loc = trim(t_step_dir) // '/pb' // trim(file_num) // '.dat' + file_loc = trim(t_step_dir)//'/pb'// & + trim(file_num)//'.dat' inquire (FILE=trim(file_loc), EXIST=file_check) + ! If it exists, the data file is read if (file_check) then - open (1, FILE=trim(file_loc), form='unformatted', STATUS='old', ACTION='read') - read (1) pb%sf(:,:,:,r, i) + open (1, FILE=trim(file_loc), FORM='unformatted', & + STATUS='old', ACTION='read') + read (1) pb%sf(:, :, :, r, i) close (1) else - call s_mpi_abort('File pb' // trim(file_num) // '.dat is missing in ' // trim(t_step_dir) // '. Exiting.') + call s_mpi_abort('File pb'//trim(file_num)// & + '.dat is missing in '//trim(t_step_dir)// & + '. Exiting.') end if end do + end do do i = 1, nb do r = 1, nnode + ! Checking whether data file associated with variable position + ! of the currently manipulated bubble variable exists write (file_num, '(I0)') sys_size + r + (i - 1)*nnode - file_loc = trim(t_step_dir) // '/mv' // trim(file_num) // '.dat' + file_loc = trim(t_step_dir)//'/mv'// & + trim(file_num)//'.dat' inquire (FILE=trim(file_loc), EXIST=file_check) + ! If it exists, the data file is read if (file_check) then - open (1, FILE=trim(file_loc), form='unformatted', STATUS='old', ACTION='read') - read (1) mv%sf(:,:,:,r, i) + open (1, FILE=trim(file_loc), FORM='unformatted', & + STATUS='old', ACTION='read') + read (1) mv%sf(:, :, :, r, i) close (1) else - call s_mpi_abort('File mv' // trim(file_num) // '.dat is missing in ' // trim(t_step_dir) // '. Exiting.') + call s_mpi_abort('File mv'//trim(file_num)// & + '.dat is missing in '//trim(t_step_dir)// & + '. Exiting.') end if end do + end do end if - ! Since the preexisting grid and initial condition data files have been read in, the directory associated with the rank of - ! the local process may be cleaned out to make room for new pre-process data. In addition, the time-step folder that will - ! contain the new grid and initial condition data are also generated. + ! Since the preexisting grid and initial condition data files have + ! been read in, the directory associated with the rank of the local + ! process may be cleaned out to make room for new pre-process data. + ! In addition, the time-step folder that will contain the new grid + ! and initial condition data are also generated. call s_delete_directory(trim(proc_rank_dir)) - call s_create_directory(trim(proc_rank_dir) // '/0') + call s_create_directory(trim(proc_rank_dir)//'/0') end subroutine s_read_serial_ic_data_files - !> Cell-boundary data are checked for consistency by looking at the (non-)uniform cell-width distributions for all the active - !! coordinate directions and making sure that all of the cell-widths are positively valued + !> Cell-boundary data are checked for consistency by looking + !! at the (non-)uniform cell-width distributions for all the + !! active coordinate directions and making sure that all of + !! the cell-widths are positively valued impure subroutine s_read_parallel_grid_data_files #ifdef MFC_MPI - real(wp), allocatable, dimension(:) :: x_cb_glb, y_cb_glb, z_cb_glb - integer :: ifile, ierr, data_size - integer, dimension(MPI_STATUS_SIZE) :: status + + real(wp), allocatable, dimension(:) :: x_cb_glb, y_cb_glb, z_cb_glb + + integer :: ifile, ierr, data_size + integer, dimension(MPI_STATUS_SIZE) :: status + character(LEN=path_len + 2*name_len) :: file_loc - logical :: file_exist + logical :: file_exist allocate (x_cb_glb(-1:m_glb)) allocate (y_cb_glb(-1:n_glb)) allocate (z_cb_glb(-1:p_glb)) - file_loc = trim(case_dir) // '/restart_data' // trim(mpiiofs) // 'x_cb.dat' + ! Read in cell boundary locations in x-direction + file_loc = trim(case_dir)//'/restart_data'//trim(mpiiofs)//'x_cb.dat' inquire (FILE=trim(file_loc), EXIST=file_exist) if (file_exist) then @@ -349,18 +544,23 @@ contains call MPI_FILE_READ_ALL(ifile, x_cb_glb, data_size, mpi_p, status, ierr) call MPI_FILE_CLOSE(ifile, ierr) else - call s_mpi_abort('File ' // trim(file_loc) // ' is missing. Exiting. ') + call s_mpi_abort('File '//trim(file_loc)//' is missing. Exiting. ') end if + ! Assigning local cell boundary locations x_cb(-1:m) = x_cb_glb((start_idx(1) - 1):(start_idx(1) + m)) + ! Computing cell center locations x_cc(0:m) = (x_cb(0:m) + x_cb(-1:(m - 1)))/2._wp + ! Computing minimum cell width dx = minval(x_cb(0:m) - x_cb(-1:(m - 1))) if (num_procs > 1) call s_mpi_reduce_min(dx) + ! Setting locations of domain bounds x_domain%beg = x_cb(-1) x_domain%end = x_cb(m) if (n > 0) then - file_loc = trim(case_dir) // '/restart_data' // trim(mpiiofs) // 'y_cb.dat' + ! Read in cell boundary locations in y-direction + file_loc = trim(case_dir)//'/restart_data'//trim(mpiiofs)//'y_cb.dat' inquire (FILE=trim(file_loc), EXIST=file_exist) if (file_exist) then @@ -369,18 +569,23 @@ contains call MPI_FILE_READ_ALL(ifile, y_cb_glb, data_size, mpi_p, status, ierr) call MPI_FILE_CLOSE(ifile, ierr) else - call s_mpi_abort('File ' // trim(file_loc) // ' is missing. Exiting. ') + call s_mpi_abort('File '//trim(file_loc)//' is missing. Exiting. ') end if + ! Assigning local cell boundary locations y_cb(-1:n) = y_cb_glb((start_idx(2) - 1):(start_idx(2) + n)) + ! Computing cell center locations y_cc(0:n) = (y_cb(0:n) + y_cb(-1:(n - 1)))/2._wp + ! Computing minimum cell width dy = minval(y_cb(0:n) - y_cb(-1:(n - 1))) if (num_procs > 1) call s_mpi_reduce_min(dy) + ! Setting locations of domain bounds y_domain%beg = y_cb(-1) y_domain%end = y_cb(n) if (p > 0) then - file_loc = trim(case_dir) // '/restart_data' // trim(mpiiofs) // 'z_cb.dat' + ! Read in cell boundary locations in z-direction + file_loc = trim(case_dir)//'/restart_data'//trim(mpiiofs)//'z_cb.dat' inquire (FILE=trim(file_loc), EXIST=file_exist) if (file_exist) then @@ -389,47 +594,62 @@ contains call MPI_FILE_READ_ALL(ifile, z_cb_glb, data_size, mpi_p, status, ierr) call MPI_FILE_CLOSE(ifile, ierr) else - call s_mpi_abort('File ' // trim(file_loc) // ' is missing. Exiting. ') + call s_mpi_abort('File '//trim(file_loc)//' is missing. Exiting. ') end if + ! Assigning local cell boundary locations z_cb(-1:p) = z_cb_glb((start_idx(3) - 1):(start_idx(3) + p)) + ! Computing cell center locations z_cc(0:p) = (z_cb(0:p) + z_cb(-1:(p - 1)))/2._wp + ! Computing minimum cell width dz = minval(z_cb(0:p) - z_cb(-1:(p - 1))) if (num_procs > 1) call s_mpi_reduce_min(dz) + ! Setting locations of domain bounds z_domain%beg = z_cb(-1) z_domain%end = z_cb(p) + end if end if deallocate (x_cb_glb, y_cb_glb, z_cb_glb) + #endif end subroutine s_read_parallel_grid_data_files - !> The goal of this subroutine is to read in any preexisting initial condition data files so that they may be used by the - !! pre-process as a starting point in the creation of an all new initial condition. + !> The goal of this subroutine is to read in any preexisting + !! initial condition data files so that they may be used by + !! the pre-process as a starting point in the creation of an + !! all new initial condition. + !! @param q_cons_vf_in Conservative variables impure subroutine s_read_parallel_ic_data_files(q_cons_vf_in) - type(scalar_field), dimension(sys_size), intent(inout) :: q_cons_vf_in + type(scalar_field), & + dimension(sys_size), & + intent(inout) :: q_cons_vf_in #ifdef MFC_MPI - integer :: ifile, ierr, data_size - integer, dimension(MPI_STATUS_SIZE) :: status - integer(KIND=MPI_OFFSET_KIND) :: disp - integer(KIND=MPI_OFFSET_KIND) :: m_MOK, n_MOK, p_MOK - integer(KIND=MPI_OFFSET_KIND) :: WP_MOK, var_MOK, str_MOK - integer(KIND=MPI_OFFSET_KIND) :: NVARS_MOK - integer(KIND=MPI_OFFSET_KIND) :: MOK + + integer :: ifile, ierr, data_size + integer, dimension(MPI_STATUS_SIZE) :: status + integer(KIND=MPI_OFFSET_KIND) :: disp + integer(KIND=MPI_OFFSET_KIND) :: m_MOK, n_MOK, p_MOK + integer(KIND=MPI_OFFSET_KIND) :: WP_MOK, var_MOK, str_MOK + integer(KIND=MPI_OFFSET_KIND) :: NVARS_MOK + integer(KIND=MPI_OFFSET_KIND) :: MOK + character(LEN=path_len + 2*name_len) :: file_loc - logical :: file_exist - integer :: i + logical :: file_exist + integer :: i + + ! Open the file to read if (cfl_adap_dt) then write (file_loc, '(I0,A)') n_start, '.dat' else write (file_loc, '(I0,A)') t_step_start, '.dat' end if - file_loc = trim(restart_dir) // trim(mpiiofs) // trim(file_loc) + file_loc = trim(restart_dir)//trim(mpiiofs)//trim(file_loc) inquire (FILE=trim(file_loc), EXIST=file_exist) if (file_exist) then @@ -437,6 +657,7 @@ contains call s_initialize_mpi_data(q_cons_vf_in) + ! Size of local arrays data_size = (m + 1)*(n + 1)*(p + 1) ! Resize some integers so MPI can read even the biggest files @@ -448,14 +669,17 @@ contains str_MOK = int(name_len, MPI_OFFSET_KIND) NVARS_MOK = int(sys_size, MPI_OFFSET_KIND) + ! Read the data for each variable do i = 1, sys_size var_MOK = int(i, MPI_OFFSET_KIND) ! Initial displacement to skip at beginning of file disp = m_MOK*max(MOK, n_MOK)*max(MOK, p_MOK)*WP_MOK*(var_MOK - 1) - call MPI_FILE_SET_VIEW(ifile, disp, mpi_p, MPI_IO_DATA%view(i), 'native', mpi_info_int, ierr) - call MPI_FILE_READ(ifile, MPI_IO_DATA%var(i)%sf, data_size, mpi_p, status, ierr) + call MPI_FILE_SET_VIEW(ifile, disp, mpi_p, MPI_IO_DATA%view(i), & + 'native', mpi_info_int, ierr) + call MPI_FILE_READ(ifile, MPI_IO_DATA%var(i)%sf, data_size, & + mpi_p, status, ierr) end do if (qbmm .and. .not. polytropic) then @@ -465,26 +689,31 @@ contains ! Initial displacement to skip at beginning of file disp = m_MOK*max(MOK, n_MOK)*max(MOK, p_MOK)*WP_MOK*(var_MOK - 1) - call MPI_FILE_SET_VIEW(ifile, disp, mpi_p, MPI_IO_DATA%view(i), 'native', mpi_info_int, ierr) - call MPI_FILE_READ(ifile, MPI_IO_DATA%var(i)%sf, data_size, mpi_p, status, ierr) + call MPI_FILE_SET_VIEW(ifile, disp, mpi_p, MPI_IO_DATA%view(i), & + 'native', mpi_info_int, ierr) + call MPI_FILE_READ(ifile, MPI_IO_DATA%var(i)%sf, data_size, & + mpi_p, status, ierr) end do end if call s_mpi_barrier() call MPI_FILE_CLOSE(ifile, ierr) + else - call s_mpi_abort('File ' // trim(file_loc) // ' is missing. Exiting. ') + call s_mpi_abort('File '//trim(file_loc)//' is missing. Exiting. ') end if call s_mpi_barrier() + #endif end subroutine s_read_parallel_ic_data_files - !> Initialize all pre-process modules, allocate data structures, and set I/O procedure pointers. + !> @brief Initializes all pre-process modules, allocates data structures, and sets I/O procedure pointers. impure subroutine s_initialize_modules - + ! Computation of parameters, allocation procedures, and/or any other tasks + ! needed to properly setup the modules call s_initialize_global_parameters_module() if (bubbles_euler .or. bubbles_lagrange) then call s_initialize_bubbles_model() @@ -499,9 +728,11 @@ contains call s_initialize_boundary_common_module() if (relax) call s_initialize_phasechange_module() - ! Create the D directory if it doesn't exit, to store the serial data files + ! Create the D directory if it doesn't exit, to store + ! the serial data files call s_create_directory('D') + ! Associate pointers for serial or parallel I/O if (parallel_io .neqv. .true.) then s_generate_grid => s_generate_serial_grid s_read_grid_data_files => s_read_serial_grid_data_files @@ -516,7 +747,7 @@ contains end subroutine s_initialize_modules - !> Read an existing grid from data files or generate a new grid from user inputs. + !> @brief Reads an existing grid from data files or generates a new grid from user inputs. impure subroutine s_read_grid() if (old_grid) then @@ -535,13 +766,24 @@ contains end subroutine s_read_grid - !> Generate or read the initial condition, apply relaxation if needed, and write output data files. + !> @brief Generates or reads the initial condition, applies relaxation if needed, and writes output data files. impure subroutine s_apply_initial_condition(start, finish) real(wp), intent(inout) :: start, finish - integer :: j, k, l - real(wp) :: r2 + integer :: j, k, l + real(wp) :: r2 + + ! Setting up the grid and the initial condition. If the grid is read in from + ! preexisting grid data files, it is checked for consistency. If the grid is + ! not read in, it is generated from scratch according to the inputs provided + ! by the user. The initial condition may also be read in. It in turn is not + ! checked for consistency since it WILL further be edited by the pre-process + ! and also because it may be incomplete at the time it is read in. Finally, + ! when the grid and initial condition are completely setup, they are written + ! to their respective data files. + + ! Setting up grid and initial condition call cpu_time(start) if (old_ic) call s_read_ic_data_files(q_cons_vf) @@ -566,7 +808,8 @@ contains if (relax) then if (proc_rank == 0) then - print *, 'initial condition might have been altered due to enforcement of pTg-equilibrium (relax = "T" activated)' + print *, 'initial condition might have been altered due to enforcement of & +& pTg-equilibrium (relax = "T" activated)' end if call s_infinite_relaxation_k(q_cons_vf) @@ -575,15 +818,14 @@ contains call s_write_data_files(q_cons_vf, q_prim_vf, bc_type) call cpu_time(finish) - end subroutine s_apply_initial_condition - !> Gather processor timing data and write elapsed wall-clock time to a summary file. + !> @brief Gathers processor timing data and writes elapsed wall-clock time to a summary file. impure subroutine s_save_data(proc_time, time_avg, time_final, file_exists) real(wp), dimension(:), intent(inout) :: proc_time - real(wp), intent(inout) :: time_avg, time_final - logical, intent(inout) :: file_exists + real(wp), intent(inout) :: time_avg, time_final + logical, intent(inout) :: file_exists call s_mpi_barrier() @@ -611,14 +853,19 @@ contains close (1) end if end if - end subroutine s_save_data - !> Initialize MPI, read and validate user inputs on rank 0, and decompose the computational domain. + !> @brief Initializes MPI, reads and validates user inputs on rank 0, and decomposes the computational domain. impure subroutine s_initialize_mpi_domain + ! Initialization of the MPI environment call s_mpi_initialize() + ! Rank 0 processor assigns default values to user inputs prior to reading + ! those in from the input file. Next, the user inputs are read in and their + ! consistency is checked. The detection of any inconsistencies automatically + ! leads to the termination of the pre-process. + if (proc_rank == 0) then call s_assign_default_values_to_user_inputs() call s_read_input_file() @@ -627,22 +874,23 @@ contains print '(" Pre-processing a ", I0, "x", I0, "x", I0, " case on ", I0, " rank(s)")', m, n, p, num_procs end if - ! Broadcasting the user inputs to all of the processors and performing the parallel computational domain decomposition. - ! Neither procedure has to be carried out if pre-process is in fact not truly executed in parallel. + ! Broadcasting the user inputs to all of the processors and performing the + ! parallel computational domain decomposition. Neither procedure has to be + ! carried out if pre-process is in fact not truly executed in parallel. call s_mpi_bcast_user_inputs() call s_initialize_parallel_io() call s_mpi_decompose_computational_domain() - end subroutine s_initialize_mpi_domain - !> Finalize all pre-process modules, deallocate resources, and shut down MPI. + !> @brief Finalizes all pre-process modules, deallocates resources, and shuts down MPI. impure subroutine s_finalize_modules - + ! Disassociate pointers for serial and parallel I/O s_generate_grid => null() s_read_grid_data_files => null() s_read_ic_data_files => null() s_write_data_files => null() + ! Deallocation procedures for the modules call s_finalize_mpi_common_module() call s_finalize_grid_module() call s_finalize_variables_conversion_module() @@ -653,8 +901,8 @@ contains call s_finalize_boundary_common_module() if (relax) call s_finalize_relaxation_solver_module() call s_finalize_initial_condition_module() + ! Finalization of the MPI environment call s_mpi_finalize() - end subroutine s_finalize_modules end module m_start_up diff --git a/src/pre_process/p_main.f90 b/src/pre_process/p_main.f90 index e16ff68571..9197eecf8f 100644 --- a/src/pre_process/p_main.f90 +++ b/src/pre_process/p_main.f90 @@ -2,16 +2,18 @@ !! @file !! @brief Contains program p_main -!> @brief Set up the initial condition and grid data for the multicomponent flow code. +!> @brief This program takes care of setting up the initial condition and +!! grid data for the multicomponent flow code. program p_main - use m_global_parameters + use m_global_parameters !< Global parameters for the code + use m_start_up implicit none - logical :: file_exists - real(wp) :: start, finish, time_avg, time_final + logical :: file_exists + real(wp) :: start, finish, time_avg, time_final real(wp), allocatable, dimension(:) :: proc_time call random_seed() @@ -35,4 +37,5 @@ program p_main deallocate (proc_time) call s_finalize_modules() + end program p_main diff --git a/src/simulation/include/inline_capillary.fpp b/src/simulation/include/inline_capillary.fpp index ba62d99740..89e1aabaec 100644 --- a/src/simulation/include/inline_capillary.fpp +++ b/src/simulation/include/inline_capillary.fpp @@ -1,4 +1,5 @@ #:def compute_capillary_stress_tensor() + Omega(1, 1) = -sigma*(w2*w2 + w3*w3)/normW #:if not MFC_CASE_OPTIMIZATION or num_dims > 1 Omega(2, 1) = sigma*w1*w2/normW @@ -17,5 +18,7 @@ Omega(3, 3) = -sigma*(w1*w1 + w2*w2)/normW #:endif + end if + #:enddef compute_capillary_stress_tensor diff --git a/src/simulation/include/inline_riemann.fpp b/src/simulation/include/inline_riemann.fpp index aae4015292..d8d0cc87c7 100644 --- a/src/simulation/include/inline_riemann.fpp +++ b/src/simulation/include/inline_riemann.fpp @@ -9,25 +9,32 @@ H_avg = 5.e-1_wp*(H_L + H_R) gamma_avg = 5.e-1_wp*(gamma_L + gamma_R) qv_avg = 5.e-1_wp*(qv_L + qv_R) + #:enddef arithmetic_avg #:def roe_avg() + rho_avg = sqrt(rho_L*rho_R) vel_avg_rms = 0._wp $:GPU_LOOP(parallelism='[seq]') do i = 1, num_vels - vel_avg_rms = vel_avg_rms + (sqrt(rho_L)*vel_L(i) + sqrt(rho_R)*vel_R(i))**2._wp/(sqrt(rho_L) + sqrt(rho_R))**2._wp + vel_avg_rms = vel_avg_rms + (sqrt(rho_L)*vel_L(i) + sqrt(rho_R)*vel_R(i))**2._wp/ & + (sqrt(rho_L) + sqrt(rho_R))**2._wp end do - H_avg = (sqrt(rho_L)*H_L + sqrt(rho_R)*H_R)/(sqrt(rho_L) + sqrt(rho_R)) + H_avg = (sqrt(rho_L)*H_L + sqrt(rho_R)*H_R)/ & + (sqrt(rho_L) + sqrt(rho_R)) - gamma_avg = (sqrt(rho_L)*gamma_L + sqrt(rho_R)*gamma_R)/(sqrt(rho_L) + sqrt(rho_R)) + gamma_avg = (sqrt(rho_L)*gamma_L + sqrt(rho_R)*gamma_R)/ & + (sqrt(rho_L) + sqrt(rho_R)) - vel_avg_rms = (sqrt(rho_L)*vel_L(1) + sqrt(rho_R)*vel_R(1))**2._wp/(sqrt(rho_L) + sqrt(rho_R))**2._wp + vel_avg_rms = (sqrt(rho_L)*vel_L(1) + sqrt(rho_R)*vel_R(1))**2._wp/ & + (sqrt(rho_L) + sqrt(rho_R))**2._wp - qv_avg = (sqrt(rho_L)*qv_L + sqrt(rho_R)*qv_R)/(sqrt(rho_L) + sqrt(rho_R)) + qv_avg = (sqrt(rho_L)*qv_L + sqrt(rho_R)*qv_R)/ & + (sqrt(rho_L) + sqrt(rho_R)) if (chemistry) then eps = 0.001_wp @@ -50,8 +57,7 @@ if (abs(T_L - T_R) < eps) then ! Case when T_L and T_R are very close Cp_avg = sum(Yi_avg(:)*(0.5_wp*Cp_iL(:) + 0.5_wp*Cp_iR(:))*gas_constant/molecular_weights_nonparameter(:)) - Cv_avg = sum(Yi_avg(:)*((0.5_wp*Cp_iL(:) + 0.5_wp*Cp_iR(:))*gas_constant/molecular_weights_nonparameter(:) & - & - gas_constant/molecular_weights_nonparameter(:))) + Cv_avg = sum(Yi_avg(:)*((0.5_wp*Cp_iL(:) + 0.5_wp*Cp_iR(:))*gas_constant/molecular_weights_nonparameter(:) - gas_constant/molecular_weights_nonparameter(:))) else ! Normal calculation when T_L and T_R are sufficiently different Cp_avg = sum(Yi_avg(:)*(h_iR(:) - h_iL(:))/(T_R - T_L)) @@ -59,15 +65,13 @@ end if gamma_avg = Cp_avg/Cv_avg - Phi_avg(:) = (gamma_avg - 1._wp)*(vel_avg_rms/2.0_wp - h_avg_2(:)) & - & + gamma_avg*gas_constant/molecular_weights_nonparameter(:)*T_avg + Phi_avg(:) = (gamma_avg - 1._wp)*(vel_avg_rms/2.0_wp - h_avg_2(:)) + gamma_avg*gas_constant/molecular_weights_nonparameter(:)*T_avg c_sum_Yi_Phi = sum(Yi_avg(:)*Phi_avg(:)) #:else if (abs(T_L - T_R) < eps) then ! Case when T_L and T_R are very close Cp_avg = sum(Yi_avg(:)*(0.5_wp*Cp_iL(:) + 0.5_wp*Cp_iR(:))*gas_constant/molecular_weights(:)) - Cv_avg = sum(Yi_avg(:)*((0.5_wp*Cp_iL(:) + 0.5_wp*Cp_iR(:))*gas_constant/molecular_weights(:) & - & - gas_constant/molecular_weights(:))) + Cv_avg = sum(Yi_avg(:)*((0.5_wp*Cp_iL(:) + 0.5_wp*Cp_iR(:))*gas_constant/molecular_weights(:) - gas_constant/molecular_weights(:))) else ! Normal calculation when T_L and T_R are sufficiently different Cp_avg = sum(Yi_avg(:)*(h_iR(:) - h_iL(:))/(T_R - T_L)) @@ -78,10 +82,13 @@ Phi_avg(:) = (gamma_avg - 1._wp)*(vel_avg_rms/2.0_wp - h_avg_2(:)) + gamma_avg*gas_constant/molecular_weights(:)*T_avg c_sum_Yi_Phi = sum(Yi_avg(:)*Phi_avg(:)) #:endif + end if + #:enddef roe_avg #:def compute_average_state() + if (avg_state == 1) then @:roe_avg() end if @@ -89,23 +96,29 @@ if (avg_state == 2) then @:arithmetic_avg() end if + #:enddef compute_average_state #:def compute_low_Mach_correction() + if (riemann_solver == 1 .or. riemann_solver == 5) then + zcoef = min(1._wp, max(vel_L_rms**5.e-1_wp/c_L, vel_R_rms**5.e-1_wp/c_R)) pcorr = 0._wp if (low_Mach == 1) then pcorr = -(s_P - s_M)*(rho_L + rho_R)/8._wp*(zcoef - 1._wp) end if + else if (riemann_solver == 2) then zcoef = min(1._wp, max(vel_L_rms**5.e-1_wp/c_L, vel_R_rms**5.e-1_wp/c_R)) pcorr = 0._wp if (low_Mach == 1) then - pcorr = rho_L*rho_R*(s_L - vel_L(dir_idx(1)))*(s_R - vel_R(dir_idx(1)))*(vel_R(dir_idx(1)) - vel_L(dir_idx(1))) & - & /(rho_R*(s_R - vel_R(dir_idx(1))) - rho_L*(s_L - vel_L(dir_idx(1))))*(zcoef - 1._wp) + pcorr = rho_L*rho_R* & + (s_L - vel_L(dir_idx(1)))*(s_R - vel_R(dir_idx(1)))*(vel_R(dir_idx(1)) - vel_L(dir_idx(1)))/ & + (rho_R*(s_R - vel_R(dir_idx(1))) - rho_L*(s_L - vel_L(dir_idx(1))))* & + (zcoef - 1._wp) else if (low_Mach == 2) then vel_L_tmp = 5.e-1_wp*((vel_L(dir_idx(1)) + vel_R(dir_idx(1))) + zcoef*(vel_L(dir_idx(1)) - vel_R(dir_idx(1)))) vel_R_tmp = 5.e-1_wp*((vel_L(dir_idx(1)) + vel_R(dir_idx(1))) + zcoef*(vel_R(dir_idx(1)) - vel_L(dir_idx(1)))) @@ -113,4 +126,5 @@ vel_R(dir_idx(1)) = vel_R_tmp end if end if + #:enddef compute_low_Mach_correction diff --git a/src/simulation/m_acoustic_src.fpp b/src/simulation/m_acoustic_src.fpp index 41c897cfd3..5b021fecbf 100644 --- a/src/simulation/m_acoustic_src.fpp +++ b/src/simulation/m_acoustic_src.fpp @@ -4,73 +4,70 @@ #:include 'macros.fpp' -!> @brief One-way acoustic source injection, Maeda and Colonius JCP (2017) +!> @brief Applies acoustic pressure source terms including focused, planar, and broadband transducers module m_acoustic_src - use m_derived_types - use m_global_parameters - use m_bubbles - use m_variables_conversion - use m_helper_basic - use m_constants + use m_derived_types !< Definitions of the derived types - implicit none + use m_global_parameters !< Definitions of the global parameters + + use m_bubbles !< Bubble dynamic routines + + use m_variables_conversion !< State variables type conversion procedures + + use m_helper_basic !< Functions to compare floating point numbers + use m_constants !< Definitions of the constants + + implicit none private; public :: s_initialize_acoustic_src, s_precalculate_acoustic_spatial_sources, s_acoustic_src_calculations integer, allocatable, dimension(:) :: pulse, support - $:GPU_DECLARE(create='[pulse, support]') + $:GPU_DECLARE(create='[pulse,support]') logical, allocatable, dimension(:) :: dipole $:GPU_DECLARE(create='[dipole]') - real(wp), allocatable, target, dimension(:,:) :: loc_acoustic + real(wp), allocatable, target, dimension(:, :) :: loc_acoustic $:GPU_DECLARE(create='[loc_acoustic]') real(wp), allocatable, dimension(:) :: mag, length, height, wavelength, frequency real(wp), allocatable, dimension(:) :: gauss_sigma_dist, gauss_sigma_time, npulse, dir, delay - $:GPU_DECLARE(create='[mag, length, height, wavelength, frequency]') - $:GPU_DECLARE(create='[gauss_sigma_dist, gauss_sigma_time, npulse, dir, delay]') + $:GPU_DECLARE(create='[mag,length,height,wavelength,frequency]') + $:GPU_DECLARE(create='[gauss_sigma_dist,gauss_sigma_time,npulse,dir,delay]') real(wp), allocatable, dimension(:) :: foc_length, aperture - $:GPU_DECLARE(create='[foc_length, aperture]') + $:GPU_DECLARE(create='[foc_length,aperture]') real(wp), allocatable, dimension(:) :: element_spacing_angle, element_polygon_ratio, rotate_angle - $:GPU_DECLARE(create='[element_spacing_angle, element_polygon_ratio, rotate_angle]') + $:GPU_DECLARE(create='[element_spacing_angle,element_polygon_ratio,rotate_angle]') real(wp), allocatable, dimension(:) :: bb_bandwidth, bb_lowest_freq - $:GPU_DECLARE(create='[bb_bandwidth, bb_lowest_freq]') + $:GPU_DECLARE(create='[bb_bandwidth,bb_lowest_freq]') integer, allocatable, dimension(:) :: num_elements, element_on, bb_num_freq - $:GPU_DECLARE(create='[num_elements, element_on, bb_num_freq]') + $:GPU_DECLARE(create='[num_elements,element_on,bb_num_freq]') !> @name Acoustic source terms !> @{ - real(wp), allocatable, dimension(:,:,:) :: mass_src, e_src - real(wp), allocatable, dimension(:,:,:,:) :: mom_src + real(wp), allocatable, dimension(:, :, :) :: mass_src, e_src + real(wp), allocatable, dimension(:, :, :, :) :: mom_src !> @} - $:GPU_DECLARE(create='[mass_src, e_src, mom_src]') + $:GPU_DECLARE(create='[mass_src,e_src,mom_src]') - integer, dimension(:), allocatable :: source_spatials_num_points !< Number of non-zero source grid points for each source + integer, dimension(:), allocatable :: source_spatials_num_points !< Number of non-zero source grid points for each source $:GPU_DECLARE(create='[source_spatials_num_points]') - type(source_spatial_type), dimension(:), allocatable :: source_spatials !< Data of non-zero source grid points for each source + type(source_spatial_type), dimension(:), allocatable :: source_spatials !< Data of non-zero source grid points for each source $:GPU_DECLARE(create='[source_spatials]') contains - !> Initialize the acoustic source module + !> This subroutine initializes the acoustic source module impure subroutine s_initialize_acoustic_src + integer :: i, j !< generic loop variables - integer :: i, j !< generic loop variables - - @:ALLOCATE(loc_acoustic(1:3, 1:num_source), mag(1:num_source), dipole(1:num_source), support(1:num_source), & - & length(1:num_source), height(1:num_source), wavelength(1:num_source), frequency(1:num_source), & - & gauss_sigma_dist(1:num_source), gauss_sigma_time(1:num_source), foc_length(1:num_source), & - & aperture(1:num_source), npulse(1:num_source), pulse(1:num_source), dir(1:num_source), delay(1:num_source), & - & element_polygon_ratio(1:num_source), rotate_angle(1:num_source), element_spacing_angle(1:num_source), & - & num_elements(1:num_source), element_on(1:num_source), bb_num_freq(1:num_source), bb_bandwidth(1:num_source), & - & bb_lowest_freq(1:num_source)) + @:ALLOCATE(loc_acoustic(1:3, 1:num_source), mag(1:num_source), dipole(1:num_source), support(1:num_source), length(1:num_source), height(1:num_source), wavelength(1:num_source), frequency(1:num_source), gauss_sigma_dist(1:num_source), gauss_sigma_time(1:num_source), foc_length(1:num_source), aperture(1:num_source), npulse(1:num_source), pulse(1:num_source), dir(1:num_source), delay(1:num_source), element_polygon_ratio(1:num_source), rotate_angle(1:num_source), element_spacing_angle(1:num_source), num_elements(1:num_source), element_on(1:num_source), bb_num_freq(1:num_source), bb_bandwidth(1:num_source), bb_lowest_freq(1:num_source)) do i = 1, num_source do j = 1, 3 @@ -107,15 +104,18 @@ contains else rotate_angle(i) = acoustic(i)%rotate_angle end if - if (f_is_default(acoustic(i)%delay)) then ! m_checker guarantees acoustic(i)%delay is set for pulse = 2 (Gaussian) - delay(i) = 0._wp ! Defaults to zero for sine and square waves + if (f_is_default(acoustic(i)%delay)) then ! m_checker guarantees acoustic(i)%delay is set for pulse = 2 (Gaussian) + delay(i) = 0._wp ! Defaults to zero for sine and square waves else delay(i) = acoustic(i)%delay end if end do - $:GPU_UPDATE(device='[loc_acoustic, mag, dipole, support, length, height, wavelength, frequency, gauss_sigma_dist, & - & gauss_sigma_time, foc_length, aperture, npulse, pulse, dir, delay, element_polygon_ratio, rotate_angle, & - & element_spacing_angle, num_elements, element_on, bb_num_freq, bb_bandwidth, bb_lowest_freq]') + $:GPU_UPDATE(device='[loc_acoustic,mag,dipole,support,length, & + & height,wavelength,frequency,gauss_sigma_dist, & + & gauss_sigma_time,foc_length,aperture,npulse,pulse, & + & dir,delay,element_polygon_ratio,rotate_angle, & + & element_spacing_angle,num_elements,element_on, & + & bb_num_freq,bb_bandwidth,bb_lowest_freq]') @:ALLOCATE(mass_src(0:m, 0:n, 0:p)) @:ALLOCATE(mom_src(1:num_vels, 0:m, 0:n, 0:p)) @@ -123,11 +123,15 @@ contains end subroutine s_initialize_acoustic_src - !> Compute mass, momentum, and energy acoustic source terms and add to the RHS + !> This subroutine updates the rhs by computing the mass, mom, energy sources + !! @param q_cons_vf Conservative variables + !! @param q_prim_vf Primitive variables + !! @param rhs_vf rhs variables impure subroutine s_acoustic_src_calculations(q_cons_vf, q_prim_vf, rhs_vf) - type(scalar_field), dimension(sys_size), intent(inout) :: q_cons_vf !< Conservative variables - type(scalar_field), dimension(sys_size), intent(inout) :: q_prim_vf !< Primitive variables + type(scalar_field), dimension(sys_size), intent(inout) :: q_cons_vf !< Conservative variables + type(scalar_field), dimension(sys_size), intent(inout) :: q_prim_vf !< Primitive variables + type(scalar_field), dimension(sys_size), intent(inout) :: rhs_vf #:if not MFC_CASE_OPTIMIZATION and USING_AMD @@ -135,25 +139,28 @@ contains #:else real(wp), dimension(num_fluids) :: myalpha, myalpha_rho #:endif - real(wp) :: myRho, B_tait - real(wp) :: sim_time, c, small_gamma - real(wp) :: frequency_local, gauss_sigma_time_local - real(wp) :: mass_src_diff, mom_src_diff - real(wp) :: source_temporal - real(wp) :: period_BB !< period of each sine wave in broadband source - real(wp) :: sl_BB !< spectral level at each frequency - real(wp) :: ffre_BB !< source term corresponding to each frequency - real(wp) :: sum_BB !< total source term for the broadband wave - real(wp), allocatable, dimension(:) :: phi_rn !< random phase shift for each frequency - integer :: i, j, k, l, q !< generic loop variables - integer :: ai !< acoustic source index - integer :: num_points - logical :: freq_conv_flag, gauss_conv_flag - integer, parameter :: mass_label = 1, mom_label = 2 - - sim_time = mytime ! Accumulated time, correct under adaptive dt - - $:GPU_PARALLEL_LOOP(private='[j, k, l]', collapse=3) + real(wp) :: myRho, B_tait + real(wp) :: sim_time, c, small_gamma + real(wp) :: frequency_local, gauss_sigma_time_local + real(wp) :: mass_src_diff, mom_src_diff + real(wp) :: source_temporal + real(wp) :: period_BB !< period of each sine wave in broadband source + real(wp) :: sl_BB !< spectral level at each frequency + real(wp) :: ffre_BB !< source term corresponding to each frequency + real(wp) :: sum_BB !< total source term for the broadband wave + real(wp), allocatable, dimension(:) :: phi_rn !< random phase shift for each frequency + + integer :: i, j, k, l, q !< generic loop variables + integer :: ai !< acoustic source index + integer :: num_points + + logical :: freq_conv_flag, gauss_conv_flag + + integer, parameter :: mass_label = 1, mom_label = 2 + + sim_time = mytime ! Accumulated time, correct under adaptive dt + + $:GPU_PARALLEL_LOOP(private='[j,k,l]', collapse=3) do l = 0, p do k = 0, n do j = 0, m @@ -171,11 +178,12 @@ contains do ai = 1, num_source ! Skip if the pulse has not started yet for sine and square waves if (.not. (sim_time < delay(ai) .and. (pulse(ai) == 1 .or. pulse(ai) == 3))) then + ! Decide if frequency need to be converted from wavelength freq_conv_flag = f_is_default(frequency(ai)) gauss_conv_flag = f_is_default(gauss_sigma_time(ai)) - num_points = source_spatials_num_points(ai) ! Use scalar to force firstprivate to prevent GPU bug + num_points = source_spatials_num_points(ai) ! Use scalar to force firstprivate to prevent GPU bug ! Calculate the broadband source period_BB = 0._wp @@ -206,9 +214,7 @@ contains deallocate (phi_rn) - $:GPU_PARALLEL_LOOP(private='[myalpha, myalpha_rho, myRho, B_tait, c, small_gamma, frequency_local, & - & gauss_sigma_time_local, mass_src_diff, mom_src_diff, source_temporal, j, k, l, q]', & - & copyin = '[sum_BB, freq_conv_flag, gauss_conv_flag, sim_time]') + $:GPU_PARALLEL_LOOP(private='[myalpha,myalpha_rho, myRho, B_tait,c, small_gamma, frequency_local, gauss_sigma_time_local, mass_src_diff, mom_src_diff, source_temporal, j, k, l, q ]', copyin = '[sum_BB, freq_conv_flag, gauss_conv_flag, sim_time]') do i = 1, num_points j = source_spatials(ai)%coord(1, i) k = source_spatials(ai)%coord(2, i) @@ -257,28 +263,29 @@ contains if (pulse(ai) == 2) gauss_sigma_time_local = f_gauss_sigma_time_local(gauss_conv_flag, ai, c) ! Update momentum source term - call s_source_temporal(sim_time, c, ai, mom_label, frequency_local, gauss_sigma_time_local, source_temporal, & - & sum_BB) + call s_source_temporal(sim_time, c, ai, mom_label, frequency_local, gauss_sigma_time_local, source_temporal, sum_BB) mom_src_diff = source_temporal*source_spatials(ai)%val(i) - if (dipole(ai)) then ! Double amplitude & No momentum source term (only works for Planar) + if (dipole(ai)) then ! Double amplitude & No momentum source term (only works for Planar) mass_src(j, k, l) = mass_src(j, k, l) + 2._wp*mom_src_diff/c if (model_eqns /= 4) E_src(j, k, l) = E_src(j, k, l) + 2._wp*mom_src_diff*c/(small_gamma - 1._wp) cycle end if - if (n == 0) then ! 1D - mom_src(1, j, k, l) = mom_src(1, j, k, l) + mom_src_diff*sign(1._wp, dir(ai)) ! Left or right-going wave - else if (p == 0) then ! 2D - if (support(ai) < 5) then ! Planar + if (n == 0) then ! 1D + mom_src(1, j, k, l) = mom_src(1, j, k, l) + mom_src_diff*sign(1._wp, dir(ai)) ! Left or right-going wave + + elseif (p == 0) then ! 2D + if (support(ai) < 5) then ! Planar mom_src(1, j, k, l) = mom_src(1, j, k, l) + mom_src_diff*cos(dir(ai)) mom_src(2, j, k, l) = mom_src(2, j, k, l) + mom_src_diff*sin(dir(ai)) else mom_src(1, j, k, l) = mom_src(1, j, k, l) + mom_src_diff*cos(source_spatials(ai)%angle(i)) mom_src(2, j, k, l) = mom_src(2, j, k, l) + mom_src_diff*sin(source_spatials(ai)%angle(i)) end if - else ! 3D - if (support(ai) < 5) then ! Planar + + else ! 3D + if (support(ai) < 5) then ! Planar mom_src(1, j, k, l) = mom_src(1, j, k, l) + mom_src_diff*cos(dir(ai)) mom_src(2, j, k, l) = mom_src(2, j, k, l) + mom_src_diff*sin(dir(ai)) else @@ -289,13 +296,11 @@ contains end if ! Update mass source term - if (support(ai) < 5) then ! Planar + if (support(ai) < 5) then ! Planar mass_src_diff = mom_src_diff/c - else ! Spherical or cylindrical support - ! Mass source term must be calculated differently using a correction term for spherical and cylindrical - ! support - call s_source_temporal(sim_time, c, ai, mass_label, frequency_local, gauss_sigma_time_local, & - & source_temporal, sum_BB) + else ! Spherical or cylindrical support + ! Mass source term must be calculated differently using a correction term for spherical and cylindrical support + call s_source_temporal(sim_time, c, ai, mass_label, frequency_local, gauss_sigma_time_local, source_temporal, sum_BB) mass_src_diff = source_temporal*source_spatials(ai)%val(i) end if mass_src(j, k, l) = mass_src(j, k, l) + mass_src_diff @@ -304,13 +309,14 @@ contains if (model_eqns /= 4) then E_src(j, k, l) = E_src(j, k, l) + mass_src_diff*c**2._wp/(small_gamma - 1._wp) end if + end do $:END_GPU_PARALLEL_LOOP() end if end do ! Update the rhs variables - $:GPU_PARALLEL_LOOP(private='[j, k, l]',collapse=3) + $:GPU_PARALLEL_LOOP(private='[j,k,l]',collapse=3) do l = 0, p do k = 0, n do j = 0, m @@ -327,35 +333,41 @@ contains end do end do $:END_GPU_PARALLEL_LOOP() - end subroutine s_acoustic_src_calculations - !> Compute the temporally varying amplitude of the pulse + !> This subroutine gives the temporally varying amplitude of the pulse + !! @param sim_time Simulation time + !! @param c Sound speed + !! @param ai Acoustic source index + !! @param term_index Index of the term to be calculated (1: mass source, 2: momentum source) + !! @param frequency_local Frequency at the spatial location for sine and square waves + !! @param gauss_sigma_time_local sigma in time for Gaussian pulse + !! @param source Source term amplitude + !! @param sum_bb Sum of basis functions elemental subroutine s_source_temporal(sim_time, c, ai, term_index, frequency_local, gauss_sigma_time_local, source, sum_BB) - $:GPU_ROUTINE(parallelism='[seq]') - integer, intent(in) :: ai, term_index - real(wp), intent(in) :: sim_time, c, sum_BB - real(wp), intent(in) :: frequency_local, gauss_sigma_time_local + integer, intent(in) :: ai, term_index + real(wp), intent(in) :: sim_time, c, sum_BB + real(wp), intent(in) :: frequency_local, gauss_sigma_time_local real(wp), intent(out) :: source - real(wp) :: omega !< angular frequency - real(wp) :: sine_wave !< sine function for square wave - real(wp) :: foc_length_factor !< Scale amplitude with radius for spherical support + + real(wp) :: omega ! angular frequency + real(wp) :: sine_wave ! sine function for square wave + real(wp) :: foc_length_factor ! Scale amplitude with radius for spherical support ! i.e. Spherical support -> 1/r scaling; Cylindrical support -> 1/sqrt(r) [empirical correction: ^-0.5 -> ^-0.85] integer, parameter :: mass_label = 1 if (n == 0) then foc_length_factor = 1._wp - else if (p == 0 .and. (.not. cyl_coord)) then ! 2D axisymmetric case is physically 3D - foc_length_factor = foc_length(ai)**(-0.85_wp) ! Empirical correction + elseif (p == 0 .and. (.not. cyl_coord)) then ! 2D axisymmetric case is physically 3D + foc_length_factor = foc_length(ai)**(-0.85_wp); ! Empirical correction else - foc_length_factor = 1/foc_length(ai) + foc_length_factor = 1/foc_length(ai); end if source = 0._wp - ! Temporal waveform: sine, Gaussian pulse, square wave, or broadband - if (pulse(ai) == 1) then ! Sine wave + if (pulse(ai) == 1) then ! Sine wave if ((sim_time - delay(ai))*frequency_local > npulse(ai)) return omega = 2._wp*pi*frequency_local @@ -364,14 +376,17 @@ contains if (term_index == mass_label) then source = source/c + foc_length_factor*mag(ai)*(cos((sim_time - delay(ai))*omega) - 1._wp)/omega end if - else if (pulse(ai) == 2) then ! Gaussian pulse + + elseif (pulse(ai) == 2) then ! Gaussian pulse source = mag(ai)*exp(-0.5_wp*((sim_time - delay(ai))**2._wp)/(gauss_sigma_time_local**2._wp)) if (term_index == mass_label) then - source = source/c - foc_length_factor*mag(ai)*sqrt(pi/2)*gauss_sigma_time_local*(erf((sim_time - delay(ai)) & - & /(sqrt(2._wp)*gauss_sigma_time_local)) + 1) + source = source/c - & + foc_length_factor*mag(ai)*sqrt(pi/2)*gauss_sigma_time_local* & + (erf((sim_time - delay(ai))/(sqrt(2._wp)*gauss_sigma_time_local)) + 1) end if - else if (pulse(ai) == 3) then ! Square wave + + elseif (pulse(ai) == 3) then ! Square wave if ((sim_time - delay(ai))*frequency_local > npulse(ai)) return omega = 2._wp*pi*frequency_local @@ -382,24 +397,23 @@ contains if (abs(sine_wave) < 1.e-2_wp) then source = mag(ai)*sine_wave*1.e2_wp end if - else if (pulse(ai) == 4) then ! Broadband wave + + elseif (pulse(ai) == 4) then ! Broadband wave source = sum_BB end if - end subroutine s_source_temporal - !> Pre-compute non-zero spatial source weights before time-stepping + !> This subroutine identifies and precalculates the non-zero acoustic spatial sources before time-stepping impure subroutine s_precalculate_acoustic_spatial_sources - - integer :: j, k, l, ai - integer :: count - integer :: dim - real(wp) :: source_spatial, angle, xyz_to_r_ratios(3) + integer :: j, k, l, ai + integer :: count + integer :: dim + real(wp) :: source_spatial, angle, xyz_to_r_ratios(3) real(wp), parameter :: threshold = 1.e-10_wp if (n == 0) then dim = 1 - else if (p == 0) then + elseif (p == 0) then dim = 2 else dim = 3 @@ -414,7 +428,7 @@ contains do l = 0, p do k = 0, n do j = 0, m - call s_source_spatial(j, k, l, loc_acoustic(:,ai), ai, source_spatial, angle, xyz_to_r_ratios) + call s_source_spatial(j, k, l, loc_acoustic(:, ai), ai, source_spatial, angle, xyz_to_r_ratios) if (abs(source_spatial) < threshold) cycle count = count + 1 end do @@ -432,11 +446,11 @@ contains @:ACC_SETUP_source_spatials(source_spatials(ai)) ! Second pass: Store the values - count = 0 ! Reset counter + count = 0 ! Reset counter do l = 0, p do k = 0, n do j = 0, m - call s_source_spatial(j, k, l, loc_acoustic(:,ai), ai, source_spatial, angle, xyz_to_r_ratios) + call s_source_spatial(j, k, l, loc_acoustic(:, ai), ai, source_spatial, angle, xyz_to_r_ratios) if (abs(source_spatial) < threshold) cycle count = count + 1 source_spatials(ai)%coord(1, count) = j @@ -445,7 +459,7 @@ contains source_spatials(ai)%val(count) = source_spatial if (support(ai) >= 5) then if (dim == 2) source_spatials(ai)%angle(count) = angle - if (dim == 3) source_spatials(ai)%xyz_to_r_ratios(1:3,count) = xyz_to_r_ratios + if (dim == 3) source_spatials(ai)%xyz_to_r_ratios(1:3, count) = xyz_to_r_ratios end if end do end do @@ -465,30 +479,38 @@ contains $:GPU_UPDATE(device='[source_spatials(ai)%xyz_to_r_ratios]') end if end if + end do #ifdef MFC_DEBUG do ai = 1, num_source write (*, '(A,I2,A,I8,A)') 'Acoustic source ', ai, ' has ', source_spatials_num_points(ai), & - & ' grid points with non-zero source term' + ' grid points with non-zero source term' end do #endif end subroutine s_precalculate_acoustic_spatial_sources - !> Compute the spatial support of the acoustic source + !> This subroutine gives the spatial support of the acoustic source + !! @param j x-index + !! @param k y-index + !! @param l z-index + !! @param loc Nominal source term location + !! @param ai Acoustic source index + !! @param source Source term amplitude + !! @param angle Angle of the source term with respect to the x-axis (for 2D or 2D axisymmetric) + !! @param xyz_to_r_ratios Ratios of the [xyz]-component of the source term to the magnitude (for 3D) subroutine s_source_spatial(j, k, l, loc, ai, source, angle, xyz_to_r_ratios) - - integer, intent(in) :: j, k, l, ai + integer, intent(in) :: j, k, l, ai real(wp), dimension(3), intent(in) :: loc - real(wp), intent(out) :: source, angle, xyz_to_r_ratios(3) - real(wp) :: sig, r(3) + real(wp), intent(out) :: source, angle, xyz_to_r_ratios(3) - ! Calculate sig spatial support width + real(wp) :: sig, r(3) + ! Calculate sig spatial support width if (n == 0) then sig = dx(j) - else if (p == 0) then + elseif (p == 0) then sig = maxval((/dx(j), dy(k)/)) else sig = maxval((/dx(j), dy(k), dz(l)/)) @@ -502,53 +524,60 @@ contains if (any(support(ai) == (/1, 2, 3, 4/))) then call s_source_spatial_planar(ai, sig, r, source) - else if (any(support(ai) == (/5, 6, 7/))) then + elseif (any(support(ai) == (/5, 6, 7/))) then call s_source_spatial_transducer(ai, sig, r, source, angle, xyz_to_r_ratios) - else if (any(support(ai) == (/9, 10, 11/))) then + elseif (any(support(ai) == (/9, 10, 11/))) then call s_source_spatial_transducer_array(ai, sig, r, source, angle, xyz_to_r_ratios) end if - end subroutine s_source_spatial - !> Compute the spatial support for planar acoustic sources in 1D, 2D, and 3D + !> This subroutine calculates the spatial support for planar acoustic sources in 1D, 2D, and 3D + !! @param ai Acoustic source index + !! @param sig Sigma value for the Gaussian distribution + !! @param r Displacement from source to current point + !! @param source Source term amplitude subroutine s_source_spatial_planar(ai, sig, r, source) - - integer, intent(in) :: ai - real(wp), intent(in) :: sig, r(3) + integer, intent(in) :: ai + real(wp), intent(in) :: sig, r(3) real(wp), intent(out) :: source - real(wp) :: dist + + real(wp) :: dist source = 0._wp - ! Gaussian spatial pulse profile: exp(-0.5 * (d / sigma)^2) / (sqrt(2*pi) * sigma) - if (support(ai) == 1) then ! 1D + if (support(ai) == 1) then ! 1D source = 1._wp/(sqrt(2._wp*pi)*sig/2._wp)*exp(-0.5_wp*(r(1)/(sig/2._wp))**2._wp) - else if (support(ai) == 2 .or. support(ai) == 3) then ! 2D or 3D + + elseif (support(ai) == 2 .or. support(ai) == 3) then ! 2D or 3D ! If we let unit vector e = (cos(dir), sin(dir)), - dist = r(1)*cos(dir(ai)) + r(2)*sin(dir(ai)) ! dot(r,e) - if ((r(1) - dist*cos(dir(ai)))**2._wp + (r(2) - dist*sin(dir(ai)))**2._wp < 0.25_wp*length(ai)**2._wp) & - & then ! |r - dist*e| < length/2 - if (support(ai) /= 3 .or. abs(r(3)) < 0.25_wp*height(ai)) then ! additional height constraint for 3D + dist = r(1)*cos(dir(ai)) + r(2)*sin(dir(ai)) ! dot(r,e) + if ((r(1) - dist*cos(dir(ai)))**2._wp + (r(2) - dist*sin(dir(ai)))**2._wp < 0.25_wp*length(ai)**2._wp) then ! |r - dist*e| < length/2 + if (support(ai) /= 3 .or. abs(r(3)) < 0.25_wp*height(ai)) then ! additional height constraint for 3D source = 1._wp/(sqrt(2._wp*pi)*sig/2._wp)*exp(-0.5_wp*(dist/(sig/2._wp))**2._wp) end if end if end if - end subroutine s_source_spatial_planar - !> Compute the spatial support for a single transducer in 2D, 2D axisymmetric, and 3D + !> This subroutine calculates the spatial support for a single transducer in 2D, 2D axisymmetric, and 3D + !! @param ai Acoustic source index + !! @param sig Sigma value for the Gaussian distribution + !! @param r Displacement from source to current point + !! @param source Source term amplitude + !! @param angle Angle of the source term with respect to the x-axis (for 2D or 2D axisymmetric) + !! @param xyz_to_r_ratios Ratios of the [xyz]-component of the source term to the magnitude (for 3D) subroutine s_source_spatial_transducer(ai, sig, r, source, angle, xyz_to_r_ratios) - - integer, intent(in) :: ai - real(wp), intent(in) :: sig, r(3) + integer, intent(in) :: ai + real(wp), intent(in) :: sig, r(3) real(wp), intent(out) :: source, angle, xyz_to_r_ratios(3) - real(wp) :: current_angle, angle_half_aperture, dist, norm - source = 0._wp ! If not affected by transducer + real(wp) :: current_angle, angle_half_aperture, dist, norm + + source = 0._wp ! If not affected by transducer angle = 0._wp xyz_to_r_ratios = 0._wp - if (support(ai) == 5 .or. support(ai) == 6) then ! 2D or 2D axisymmetric + if (support(ai) == 5 .or. support(ai) == 6) then ! 2D or 2D axisymmetric current_angle = -atan(r(2)/(foc_length(ai) - r(1))) angle_half_aperture = asin((aperture(ai)/2._wp)/(foc_length(ai))) @@ -557,7 +586,8 @@ contains source = 1._wp/(sqrt(2._wp*pi)*sig/2._wp)*exp(-0.5_wp*(dist/(sig/2._wp))**2._wp) angle = -atan(r(2)/(foc_length(ai) - r(1))) end if - else if (support(ai) == 7) then ! 3D + + elseif (support(ai) == 7) then ! 3D current_angle = -atan(sqrt(r(2)**2 + r(3)**2)/(foc_length(ai) - r(1))) angle_half_aperture = asin((aperture(ai)/2._wp)/(foc_length(ai))) @@ -570,35 +600,41 @@ contains xyz_to_r_ratios(2) = -r(2)/norm xyz_to_r_ratios(3) = -r(3)/norm end if - end if + end if end subroutine s_source_spatial_transducer - !> Compute the spatial support for multiple transducers in 2D, 2D axisymmetric, and 3D + !> This subroutine calculates the spatial support for multiple transducers in 2D, 2D axisymmetric, and 3D + !! @param ai Acoustic source index + !! @param sig Sigma value for the Gaussian distribution + !! @param r Displacement from source to current point + !! @param source Source term amplitude + !! @param angle Angle of the source term with respect to the x-axis (for 2D or 2D axisymmetric) + !! @param xyz_to_r_ratios Ratios of the [xyz]-component of the source term to the magnitude (for 3D) subroutine s_source_spatial_transducer_array(ai, sig, r, source, angle, xyz_to_r_ratios) - - integer, intent(in) :: ai - real(wp), intent(in) :: sig, r(3) + integer, intent(in) :: ai + real(wp), intent(in) :: sig, r(3) real(wp), intent(out) :: source, angle, xyz_to_r_ratios(3) - integer :: elem, elem_min, elem_max - real(wp) :: current_angle, angle_half_aperture, angle_per_elem, dist - real(wp) :: angle_min, angle_max, norm - real(wp) :: poly_side_length, aperture_element_3D, angle_elem - real(wp) :: x2, y2, z2, x3, y3, z3, C, f, half_apert, dist_interp_to_elem_center - if (element_on(ai) == 0) then ! Full transducer + integer :: elem, elem_min, elem_max + real(wp) :: current_angle, angle_half_aperture, angle_per_elem, dist + real(wp) :: angle_min, angle_max, norm + real(wp) :: poly_side_length, aperture_element_3D, angle_elem + real(wp) :: x2, y2, z2, x3, y3, z3, C, f, half_apert, dist_interp_to_elem_center + + if (element_on(ai) == 0) then ! Full transducer elem_min = 1 elem_max = num_elements(ai) - else ! Transducer element specified + else ! Transducer element specified elem_min = element_on(ai) elem_max = element_on(ai) end if - source = 0._wp ! If not affected by any transducer element + source = 0._wp ! If not affected by any transducer element angle = 0._wp xyz_to_r_ratios = 0._wp - if (support(ai) == 9 .or. support(ai) == 10) then ! 2D or 2D axisymmetric + if (support(ai) == 9 .or. support(ai) == 10) then ! 2D or 2D axisymmetric current_angle = -atan(r(2)/(foc_length(ai) - r(1))) angle_half_aperture = asin((aperture(ai)/2._wp)/(foc_length(ai))) angle_per_elem = (2._wp*angle_half_aperture - (num_elements(ai) - 1._wp)*element_spacing_angle(ai))/num_elements(ai) @@ -611,10 +647,11 @@ contains if (current_angle > angle_min .and. current_angle < angle_max .and. r(1) < foc_length(ai)) then source = exp(-0.5_wp*(dist/(sig/2._wp))**2._wp)/(sqrt(2._wp*pi)*sig/2._wp) angle = current_angle - exit ! Assume elements don't overlap + exit ! Assume elements don't overlap end if end do - else if (support(ai) == 11) then ! 3D + + elseif (support(ai) == 11) then ! 3D poly_side_length = aperture(ai)*sin(pi/num_elements(ai)) aperture_element_3D = poly_side_length*element_polygon_ratio(ai) f = foc_length(ai) @@ -628,9 +665,9 @@ contains y2 = half_apert*cos(angle_elem) z2 = half_apert*sin(angle_elem) - ! Construct a plane normal to the line from the focal point to the elem center, Point 3 is the intercept of the - ! plane and the line from the focal point to the current location - C = f**2._wp/((r(1) - f)*(x2 - f) + r(2)*y2 + r(3)*z2) ! Constant for intermediate step + ! Construct a plane normal to the line from the focal point to the elem center, + ! Point 3 is the intercept of the plane and the line from the focal point to the current location + C = f**2._wp/((r(1) - f)*(x2 - f) + r(2)*y2 + r(3)*z2) ! Constant for intermediate step x3 = C*(r(1) - f) + f y3 = C*r(2) z3 = C*r(3) @@ -645,43 +682,48 @@ contains xyz_to_r_ratios(2) = -r(2)/norm xyz_to_r_ratios(3) = -r(3)/norm end if + end do - end if + end if end subroutine s_source_spatial_transducer_array - !> Convert wavelength to frequency + !> This function performs wavelength to frequency conversion + !! @param freq_conv_flag Determines if frequency is given or wavelength + !! @param ai Acoustic source index + !! @param c Speed of sound + !! @return frequency_local Converted frequency elemental function f_frequency_local(freq_conv_flag, ai, c) - $:GPU_ROUTINE(parallelism='[seq]') - logical, intent(in) :: freq_conv_flag - integer, intent(in) :: ai + logical, intent(in) :: freq_conv_flag + integer, intent(in) :: ai real(wp), intent(in) :: c - real(wp) :: f_frequency_local + real(wp) :: f_frequency_local if (freq_conv_flag) then f_frequency_local = c/wavelength(ai) else f_frequency_local = frequency(ai) end if - end function f_frequency_local - !> Convert Gaussian sigma from distance to time + !> This function performs Gaussian sigma dist to time conversion + !! @param gauss_conv_flag Determines if sigma_dist is given or sigma_time + !! @param c Speed of sound + !! @param ai Acoustic source index + !! @return gauss_sigma_time_local Converted Gaussian sigma time function f_gauss_sigma_time_local(gauss_conv_flag, ai, c) - $:GPU_ROUTINE(parallelism='[seq]') - logical, intent(in) :: gauss_conv_flag - integer, intent(in) :: ai + logical, intent(in) :: gauss_conv_flag + integer, intent(in) :: ai real(wp), intent(in) :: c - real(wp) :: f_gauss_sigma_time_local + real(wp) :: f_gauss_sigma_time_local if (gauss_conv_flag) then f_gauss_sigma_time_local = gauss_sigma_dist(ai)/c else f_gauss_sigma_time_local = gauss_sigma_time(ai) end if - end function f_gauss_sigma_time_local end module m_acoustic_src diff --git a/src/simulation/m_body_forces.fpp b/src/simulation/m_body_forces.fpp index 7200390c2c..1b9b1a209b 100644 --- a/src/simulation/m_body_forces.fpp +++ b/src/simulation/m_body_forces.fpp @@ -7,46 +7,62 @@ !> @brief Computes gravitational and user-defined body force source terms for the momentum equations module m_body_forces - use m_derived_types - use m_global_parameters + use m_derived_types !< Definitions of the derived types + + use m_global_parameters !< Definitions of the global parameters + use m_variables_conversion + use m_nvtx - ! $:USE_GPU_MODULE() +! $:USE_GPU_MODULE() implicit none - private - public :: s_compute_body_forces_rhs, s_initialize_body_forces_module, s_finalize_body_forces_module + private; + public :: s_compute_body_forces_rhs, & + s_initialize_body_forces_module, & + s_finalize_body_forces_module - real(wp), allocatable, dimension(:,:,:) :: rhoM + real(wp), allocatable, dimension(:, :, :) :: rhoM $:GPU_DECLARE(create='[rhoM]') contains - !> Initialize the body forces module + !> This subroutine initializes the module global array of mixture + !! densities in each grid cell impure subroutine s_initialize_body_forces_module + ! Simulation is at least 2D if (n > 0) then + ! Simulation is 3D if (p > 0) then - @:ALLOCATE(rhoM(-buff_size:buff_size + m, -buff_size:buff_size + n, -buff_size:buff_size + p)) + @:ALLOCATE (rhoM(-buff_size:buff_size + m, & + -buff_size:buff_size + n, & + -buff_size:buff_size + p)) + ! Simulation is 2D else - @:ALLOCATE(rhoM(-buff_size:buff_size + m, -buff_size:buff_size + n, 0:0)) + @:ALLOCATE (rhoM(-buff_size:buff_size + m, & + -buff_size:buff_size + n, & + 0:0)) end if + ! Simulation is 1D else - @:ALLOCATE(rhoM(-buff_size:buff_size + m, 0:0, 0:0)) + @:ALLOCATE (rhoM(-buff_size:buff_size + m, & + 0:0, & + 0:0)) end if end subroutine s_initialize_body_forces_module - !> Compute the acceleration at time t + !> This subroutine computes the acceleration at time t subroutine s_compute_acceleration(t) real(wp), intent(in) :: t #:for DIR, XYZ in [(1, 'x'), (2, 'y'), (3, 'z')] if (bf_${XYZ}$) then - accel_bf(${DIR}$) = g_${XYZ}$ + k_${XYZ}$*sin(w_${XYZ}$*t - p_${XYZ}$) + accel_bf(${DIR}$) = g_${XYZ}$+k_${XYZ}$*sin(w_${XYZ}$*t - p_${XYZ}$) end if #:endfor @@ -54,19 +70,22 @@ contains end subroutine s_compute_acceleration - !> Compute the mixture density at each cell center + !> This subroutine calculates the mixture density at each cell + !! center + !! @param q_cons_vf Conservative variables subroutine s_compute_mixture_density(q_cons_vf) type(scalar_field), dimension(sys_size), intent(in) :: q_cons_vf - integer :: i, j, k, l !< standard iterators + integer :: i, j, k, l !< standard iterators - $:GPU_PARALLEL_LOOP(private='[j, k, l]', collapse=3) + $:GPU_PARALLEL_LOOP(private='[j,k,l]', collapse=3) do l = 0, p do k = 0, n do j = 0, m rhoM(j, k, l) = 0._wp do i = 1, num_fluids - rhoM(j, k, l) = rhoM(j, k, l) + q_cons_vf(contxb + i - 1)%sf(j, k, l) + rhoM(j, k, l) = rhoM(j, k, l) + & + q_cons_vf(contxb + i - 1)%sf(j, k, l) end do end do end do @@ -75,18 +94,23 @@ contains end subroutine s_compute_mixture_density - !> Compute the body force source terms for momentum and energy equations + !> This subroutine calculates the source term due to body forces + !! so the system can be advanced in time + !! @param q_cons_vf Conservative variables + !! @param q_prim_vf Primitive variables + !! @param rhs_vf Right-hand side accumulator subroutine s_compute_body_forces_rhs(q_prim_vf, q_cons_vf, rhs_vf) - type(scalar_field), dimension(sys_size), intent(in) :: q_prim_vf - type(scalar_field), dimension(sys_size), intent(in) :: q_cons_vf + type(scalar_field), dimension(sys_size), intent(in) :: q_prim_vf + type(scalar_field), dimension(sys_size), intent(in) :: q_cons_vf type(scalar_field), dimension(sys_size), intent(inout) :: rhs_vf - integer :: i, j, k, l !< Loop variables + + integer :: i, j, k, l !< Loop variables call s_compute_acceleration(mytime) call s_compute_mixture_density(q_cons_vf) - $:GPU_PARALLEL_LOOP(private='[i, j, k, l]', collapse=4) + $:GPU_PARALLEL_LOOP(private='[i,j,k,l]', collapse=4) do i = momxb, E_idx do l = 0, p do k = 0, n @@ -98,51 +122,58 @@ contains end do $:END_GPU_PARALLEL_LOOP() - if (bf_x) then ! x-direction body forces + if (bf_x) then ! x-direction body forces - $:GPU_PARALLEL_LOOP(private='[j, k, l]', collapse=3) + $:GPU_PARALLEL_LOOP(private='[j,k,l]', collapse=3) do l = 0, p do k = 0, n do j = 0, m - rhs_vf(momxb)%sf(j, k, l) = rhs_vf(momxb)%sf(j, k, l) + rhoM(j, k, l)*accel_bf(1) - rhs_vf(E_idx)%sf(j, k, l) = rhs_vf(E_idx)%sf(j, k, l) + q_cons_vf(momxb)%sf(j, k, l)*accel_bf(1) + rhs_vf(momxb)%sf(j, k, l) = rhs_vf(momxb)%sf(j, k, l) + & + rhoM(j, k, l)*accel_bf(1) + rhs_vf(E_idx)%sf(j, k, l) = rhs_vf(E_idx)%sf(j, k, l) + & + q_cons_vf(momxb)%sf(j, k, l)*accel_bf(1) end do end do end do $:END_GPU_PARALLEL_LOOP() end if - if (bf_y) then ! y-direction body forces + if (bf_y) then ! y-direction body forces - $:GPU_PARALLEL_LOOP(private='[j, k, l]', collapse=3) + $:GPU_PARALLEL_LOOP(private='[j,k,l]', collapse=3) do l = 0, p do k = 0, n do j = 0, m - rhs_vf(momxb + 1)%sf(j, k, l) = rhs_vf(momxb + 1)%sf(j, k, l) + rhoM(j, k, l)*accel_bf(2) - rhs_vf(E_idx)%sf(j, k, l) = rhs_vf(E_idx)%sf(j, k, l) + q_cons_vf(momxb + 1)%sf(j, k, l)*accel_bf(2) + rhs_vf(momxb + 1)%sf(j, k, l) = rhs_vf(momxb + 1)%sf(j, k, l) + & + rhoM(j, k, l)*accel_bf(2) + rhs_vf(E_idx)%sf(j, k, l) = rhs_vf(E_idx)%sf(j, k, l) + & + q_cons_vf(momxb + 1)%sf(j, k, l)*accel_bf(2) end do end do end do $:END_GPU_PARALLEL_LOOP() end if - if (bf_z) then ! z-direction body forces + if (bf_z) then ! z-direction body forces - $:GPU_PARALLEL_LOOP(private='[j, k, l]', collapse=3) + $:GPU_PARALLEL_LOOP(private='[j,k,l]', collapse=3) do l = 0, p do k = 0, n do j = 0, m - rhs_vf(momxe)%sf(j, k, l) = rhs_vf(momxe)%sf(j, k, l) + rhoM(j, k, l)*accel_bf(3) - rhs_vf(E_idx)%sf(j, k, l) = rhs_vf(E_idx)%sf(j, k, l) + q_cons_vf(momxe)%sf(j, k, l)*accel_bf(3) + rhs_vf(momxe)%sf(j, k, l) = rhs_vf(momxe)%sf(j, k, l) + & + rhoM(j, k, l)*accel_bf(3) + rhs_vf(E_idx)%sf(j, k, l) = rhs_vf(E_idx)%sf(j, k, l) + & + q_cons_vf(momxe)%sf(j, k, l)*accel_bf(3) end do end do end do $:END_GPU_PARALLEL_LOOP() + end if end subroutine s_compute_body_forces_rhs - !> Finalize the body forces module + !> @brief Deallocates module variables used for body force computations. impure subroutine s_finalize_body_forces_module @:DEALLOCATE(rhoM) diff --git a/src/simulation/m_bubbles.fpp b/src/simulation/m_bubbles.fpp index 2ff5952827..cb2fb6a353 100644 --- a/src/simulation/m_bubbles.fpp +++ b/src/simulation/m_bubbles.fpp @@ -4,34 +4,52 @@ #:include 'macros.fpp' -!> @brief Shared bubble-dynamics procedures (radial acceleration, wall pressure, sound speed) for ensemble- and volume-averaged -!! models +!> @brief Shared bubble-dynamics procedures (radial acceleration, wall pressure, sound speed) for ensemble- and volume-averaged models module m_bubbles - use m_derived_types - use m_global_parameters - use m_mpi_proxy - use m_variables_conversion - use m_helper_basic + use m_derived_types !< Definitions of the derived types + + use m_global_parameters !< Definitions of the global parameters + + use m_mpi_proxy !< Message passing interface (MPI) module proxy + + use m_variables_conversion !< State variables type conversion procedures + + use m_helper_basic !< Functions to compare floating point numbers + + use m_bubbles_EL_kernels implicit none real(wp) :: chi_vw !< Bubble wall properties (Ando 2010) real(wp) :: k_mw !< Bubble wall properties (Ando 2010) real(wp) :: rho_mw !< Bubble wall properties (Ando 2010) - $:GPU_DECLARE(create='[chi_vw, k_mw, rho_mw]') + $:GPU_DECLARE(create='[chi_vw,k_mw,rho_mw]') contains - !> Compute the bubble radial acceleration based on the selected bubble model - elemental function f_rddot(fRho, fP, fR, fV, fR0, fpb, fpbdot, alf, fntait, fBtait, f_bub_adv_src, f_divu, fCson) - + !> Function that computes the bubble radial acceleration based on bubble models + !! @param fRho Current density + !! @param fP Current driving pressure + !! @param fR Current bubble radius + !! @param fV Current bubble velocity + !! @param fR0 Equilibrium bubble radius + !! @param fpb Internal bubble pressure + !! @param fpbdot Time-derivative of internal bubble pressure + !! @param alf bubble volume fraction + !! @param fntait Tait EOS parameter + !! @param fBtait Tait EOS parameter + !! @param f_bub_adv_src Source for bubble volume fraction + !! @param f_divu Divergence of velocity + !! @param fCson Speed of sound from fP (EL) + function f_rddot(fRho, fP, fR, fV, fR0, fpb, fpbdot, alf, fntait, fBtait, f_bub_adv_src, f_divu, fCson) $:GPU_ROUTINE(parallelism='[seq]') real(wp), intent(in) :: fRho, fP, fR, fV, fR0, fpb, fpbdot, alf real(wp), intent(in) :: fntait, fBtait, f_bub_adv_src, f_divu real(wp), intent(in) :: fCson - real(wp) :: fCpbw, fCpinf, fCpinf_dot, fH, fHdot, c_gas, c_liquid - real(wp) :: f_rddot + + real(wp) :: fCpbw, fCpinf, fCpinf_dot, fH, fHdot, c_gas, c_liquid + real(wp) :: f_rddot if (bubble_model == 1) then ! Gilmore bubbles @@ -63,12 +81,16 @@ contains end function f_rddot - !> Bubble wall pressure: stiffened gas with Laplace pressure and viscous stress - elemental function f_cpbw(fR0, fR, fV, fpb) - + !> Function that computes that bubble wall pressure for Gilmore bubbles + !! @param fR0 Equilibrium bubble radius + !! @param fR Current bubble radius + !! @param fV Current bubble velocity + !! @param fpb Internal bubble pressure + function f_cpbw(fR0, fR, fV, fpb) $:GPU_ROUTINE(parallelism='[seq]') real(wp), intent(in) :: fR0, fR, fV, fpb - real(wp) :: f_cpbw + + real(wp) :: f_cpbw if (polytropic) then f_cpbw = (Ca + 2._wp/Web/fR0)*((fR0/fR)**(3._wp*gam)) - Ca - 4._wp*Re_inv*fV/fR - 2._wp/(fR*Web) @@ -78,13 +100,17 @@ contains end function f_cpbw - !> Compute the bubble enthalpy - elemental function f_H(fCpbw, fCpinf, fntait, fBtait) - + !> Function that computes the bubble enthalpy + !! @param fCpbw Bubble wall pressure + !! @param fCpinf Driving bubble pressure + !! @param fntait Tait EOS parameter + !! @param fBtait Tait EOS parameter + function f_H(fCpbw, fCpinf, fntait, fBtait) $:GPU_ROUTINE(parallelism='[seq]') real(wp), intent(in) :: fCpbw, fCpinf, fntait, fBtait - real(wp) :: tmp1, tmp2, tmp3 - real(wp) :: f_H + + real(wp) :: tmp1, tmp2, tmp3 + real(wp) :: f_H tmp1 = (fntait - 1._wp)/fntait tmp2 = (fCpbw/(1._wp + fBtait) + 1._wp)**tmp1 @@ -94,13 +120,17 @@ contains end function f_H - !> Compute the sound speed for the bubble - elemental function f_cgas(fCpinf, fntait, fBtait, fH) - + !> Function that computes the sound speed for the bubble + !! @param fCpinf Driving bubble pressure + !! @param fntait Tait EOS parameter + !! @param fBtait Tait EOS parameter + !! @param fH Bubble enthalpy + function f_cgas(fCpinf, fntait, fBtait, fH) $:GPU_ROUTINE(parallelism='[seq]') real(wp), intent(in) :: fCpinf, fntait, fBtait, fH - real(wp) :: tmp - real(wp) :: f_cgas + + real(wp) :: tmp + real(wp) :: f_cgas ! get sound speed for Gilmore equations "C" -> c_gas tmp = (fCpinf/(1._wp + fBtait) + 1._wp)**((fntait - 1._wp)/fntait) @@ -110,15 +140,23 @@ contains end function f_cgas - !> Compute the time derivative of the driving pressure - elemental function f_cpinfdot(fRho, fP, falf, fntait, fBtait, advsrc, divu) - + !> Function that computes the time derivative of the driving pressure + !! @param fRho Local liquid density + !! @param fP Local pressure + !! @param falf Local void fraction + !! @param fntait Tait EOS parameter + !! @param fBtait Tait EOS parameter + !! @param advsrc Advection equation source term + !! @param divu Divergence of velocity + function f_cpinfdot(fRho, fP, falf, fntait, fBtait, advsrc, divu) $:GPU_ROUTINE(parallelism='[seq]') real(wp), intent(in) :: fRho, fP, falf, fntait, fBtait, advsrc, divu - real(wp) :: c2_liquid - real(wp) :: f_cpinfdot - ! get sound speed squared for liquid (only needed for pbdot) c_l^2 = gam (p+B) / (rho*(1-alf)) + real(wp) :: c2_liquid + real(wp) :: f_cpinfdot + + ! get sound speed squared for liquid (only needed for pbdot) + ! c_l^2 = gam (p+B) / (rho*(1-alf)) if (mpp_lim) then c2_liquid = fntait*(fP + fBtait)/fRho else @@ -130,14 +168,23 @@ contains end function f_cpinfdot - !> Enthalpy derivative for Gilmore bubble model, Gilmore (1952) - elemental function f_Hdot(fCpbw, fCpinf, fCpinf_dot, fntait, fBtait, fR, fV, fR0, fpbdot) - + !> Function that computes the time derivative of the enthalpy + !! @param fCpbw Bubble wall pressure + !! @param fCpinf Driving bubble pressure + !! @param fCpinf_dot Time derivative of the driving pressure + !! @param fntait Tait EOS parameter + !! @param fBtait Tait EOS parameter + !! @param fR Current bubble radius + !! @param fV Current bubble velocity + !! @param fR0 Equilibrium bubble radius + !! @param fpbdot Time derivative of the internal bubble pressure + function f_Hdot(fCpbw, fCpinf, fCpinf_dot, fntait, fBtait, fR, fV, fR0, fpbdot) $:GPU_ROUTINE(parallelism='[seq]') real(wp), intent(in) :: fCpbw, fCpinf, fCpinf_dot, fntait, fBtait real(wp), intent(in) :: fR, fV, fR0, fpbdot - real(wp) :: tmp1, tmp2 - real(wp) :: f_Hdot + + real(wp) :: tmp1, tmp2 + real(wp) :: f_Hdot if (polytropic) then tmp1 = (fR0/fR)**(3._wp*gam) @@ -147,49 +194,80 @@ contains end if tmp2 = (2._wp/Web + 4._wp*Re_inv*fV)*fV/(fR**2._wp) - f_Hdot = (fCpbw/(1._wp + fBtait) + 1._wp)**(-1._wp/fntait)*(tmp1 + tmp2) - (fCpinf/(1._wp + fBtait) + 1._wp) & - & **(-1._wp/fntait)*fCpinf_dot + f_Hdot = & + (fCpbw/(1._wp + fBtait) + 1._wp)**(-1._wp/fntait)*(tmp1 + tmp2) & + - (fCpinf/(1._wp + fBtait) + 1._wp)**(-1._wp/fntait)*fCpinf_dot - end function f_Hdot + ! Hdot = (Cpbw/(1+B) + 1)^(-1/n_tait)*(-3 gam)*(R0/R)^(3gam) V/R + !f_Hdot = ((fCpbw/(1._wp+fBtait)+1._wp)**(-1._wp/fntait))*(-3._wp)*gam * & + ! ( (fR0/fR)**(3._wp*gam ))*(fV/fR) - !> Rayleigh-Plesset bubble radial acceleration - elemental function f_rddot_RP(fCp, fRho, fR, fV, fCpbw) + ! Hdot = Hdot - (Cpinf/(1+B) + 1)^(-1/n_tait) Cpinfdot + !f_Hdot = f_Hdot - ((fCpinf/(1._wp+fBtait)+1._wp)**(-1._wp/fntait))*fCpinf_dot + end function f_Hdot + + !> Function that computes the bubble radial acceleration for Rayleigh-Plesset bubbles + !! @param fCp Driving pressure + !! @param fRho Current density + !! @param fR Current bubble radius + !! @param fV Current bubble velocity + !! @param fCpbw Boundary wall pressure + function f_rddot_RP(fCp, fRho, fR, fV, fCpbw) $:GPU_ROUTINE(parallelism='[seq]') real(wp), intent(in) :: fCp, fRho, fR, fV, fCpbw - real(wp) :: f_rddot_RP + + real(wp) :: f_rddot_RP + + !! rddot = (1/r) ( -3/2 rdot^2 + ((r0/r)^3\gamma - Cp)/rho ) + !! rddot = (1/r) ( -3/2 rdot^2 + (tmp1 - Cp)/rho ) + !! rddot = (1/r) ( tmp2 ) f_rddot_RP = (-1.5_wp*(fV**2._wp) + (fCpbw - fCp)/fRho)/fR end function f_rddot_RP - !> Compute the Gilmore bubble radial acceleration - elemental function f_rddot_G(fCpbw, fR, fV, fH, fHdot, fcgas, fntait, fBtait) - + !> Function that computes the bubble radial acceleration + !! @param fCpbw Bubble wall pressure + !! @param fR Current bubble radius + !! @param fV Current bubble velocity + !! @param fH Current enthalpy + !! @param fHdot Current time derivative of the enthalpy + !! @param fcgas Current gas sound speed + !! @param fntait Tait EOS parameter + !! @param fBtait Tait EOS parameter + function f_rddot_G(fCpbw, fR, fV, fH, fHdot, fcgas, fntait, fBtait) $:GPU_ROUTINE(parallelism='[seq]') real(wp), intent(in) :: fCpbw, fR, fV, fH, fHdot real(wp), intent(in) :: fcgas, fntait, fBtait - real(wp) :: tmp1, tmp2, tmp3 - real(wp) :: f_rddot_G + + real(wp) :: tmp1, tmp2, tmp3 + real(wp) :: f_rddot_G tmp1 = fV/fcgas - tmp2 = 1._wp + 4._wp*Re_inv/fcgas/fR*(fCpbw/(1._wp + fBtait) + 1._wp)**(-1._wp/fntait) - tmp3 = 1.5_wp*fV**2._wp*(tmp1/3._wp - 1._wp) + fH*(1._wp + tmp1) + fR*fHdot*(1._wp - tmp1)/fcgas + tmp2 = 1._wp + 4._wp*Re_inv/fcgas/fR*(fCpbw/(1._wp + fBtait) + 1._wp) & + **(-1._wp/fntait) + tmp3 = 1.5_wp*fV**2._wp*(tmp1/3._wp - 1._wp) + fH*(1._wp + tmp1) & + + fR*fHdot*(1._wp - tmp1)/fcgas f_rddot_G = tmp3/(fR*(1._wp - tmp1)*tmp2) end function f_rddot_G - !> Keller-Miksis bubble wall pressure - elemental function f_cpbw_KM(fR0, fR, fV, fpb) - + !> Function that computes the bubble wall pressure for Keller--Miksis bubbles + !! @param fR0 Equilibrium bubble radius + !! @param fR Current bubble radius + !! @param fV Current bubble velocity + !! @param fpb Internal bubble pressure + function f_cpbw_KM(fR0, fR, fV, fpb) $:GPU_ROUTINE(parallelism='[seq]') real(wp), intent(in) :: fR0, fR, fV, fpb - real(wp) :: f_cpbw_KM + real(wp) :: f_cpbw_KM if (polytropic) then f_cpbw_KM = Ca*((fR0/fR)**(3._wp*gam)) - Ca + Eu - if (.not. f_is_default(Web)) f_cpbw_KM = f_cpbw_KM + (2._wp/(Web*fR0))*((fR0/fR)**(3._wp*gam)) + if (.not. f_is_default(Web)) f_cpbw_KM = f_cpbw_KM + & + (2._wp/(Web*fR0))*((fR0/fR)**(3._wp*gam)) else f_cpbw_KM = fpb end if @@ -199,17 +277,26 @@ contains end function f_cpbw_KM - !> Keller-Miksis bubble radial acceleration - elemental function f_rddot_KM(fpbdot, fCp, fCpbw, fRho, fR, fV, fR0, fC) - + !> Function that computes the bubble radial acceleration for Keller--Miksis bubbles + !! @param fpbdot Time-derivative of internal bubble pressure + !! @param fCp Driving pressure + !! @param fCpbw Bubble wall pressure + !! @param fRho Current density + !! @param fR Current bubble radius + !! @param fV Current bubble velocity + !! @param fR0 Equilibrium bubble radius + !! @param fC Current sound speed + function f_rddot_KM(fpbdot, fCp, fCpbw, fRho, fR, fV, fR0, fC) $:GPU_ROUTINE(parallelism='[seq]') real(wp), intent(in) :: fpbdot, fCp, fCpbw real(wp), intent(in) :: fRho, fR, fV, fR0, fC - real(wp) :: tmp1, tmp2, cdot_star - real(wp) :: f_rddot_KM + + real(wp) :: tmp1, tmp2, cdot_star + real(wp) :: f_rddot_KM if (polytropic) then cdot_star = -3._wp*gam*Ca*((fR0/fR)**(3._wp*gam))*fV/fR - if (.not. f_is_default(Web)) cdot_star = cdot_star - 3._wp*gam*(2._wp/(Web*fR0))*((fR0/fR)**(3._wp*gam))*fV/fR + if (.not. f_is_default(Web)) cdot_star = cdot_star - & + 3._wp*gam*(2._wp/(Web*fR0))*((fR0/fR)**(3._wp*gam))*fV/fR else cdot_star = fpbdot end if @@ -218,7 +305,9 @@ contains if (.not. f_is_default(Re_inv)) cdot_star = cdot_star + 4._wp*Re_inv*((fV/fR)**2._wp) tmp1 = fV/fC - tmp2 = 1.5_wp*(fV**2._wp)*(tmp1/3._wp - 1._wp) + (1._wp + tmp1)*(fCpbw - fCp)/fRho + cdot_star*fR/(fRho*fC) + tmp2 = 1.5_wp*(fV**2._wp)*(tmp1/3._wp - 1._wp) + & + (1._wp + tmp1)*(fCpbw - fCp)/fRho + & + cdot_star*fR/(fRho*fC) if (f_is_default(Re_inv)) then f_rddot_KM = tmp2/(fR*(1._wp - tmp1)) @@ -228,45 +317,57 @@ contains end function f_rddot_KM - !> Compute bubble wall properties for vapor bubbles - elemental subroutine s_bwproperty(pb_in, iR0, chi_vw_out, k_mw_out, rho_mw_out) - + !> Subroutine that computes bubble wall properties for vapor bubbles + !! @param pb_in Internal bubble pressure + !! @param iR0 Current bubble size index + subroutine s_bwproperty(pb_in, iR0, chi_vw_out, k_mw_out, rho_mw_out) $:GPU_ROUTINE(parallelism='[seq]') - real(wp), intent(in) :: pb_in - integer, intent(in) :: iR0 + real(wp), intent(in) :: pb_in + integer, intent(in) :: iR0 real(wp), intent(out) :: chi_vw_out !< Bubble wall properties (Ando 2010) real(wp), intent(out) :: k_mw_out !< Bubble wall properties (Ando 2010) real(wp), intent(out) :: rho_mw_out !< Bubble wall properties (Ando 2010) - real(wp) :: x_vw + real(wp) :: x_vw ! mass fraction of vapor chi_vw_out = 1._wp/(1._wp + R_v/R_g*(pb_in/pv - 1._wp)) ! mole fraction of vapor & thermal conductivity of gas mixture x_vw = M_g*chi_vw_out/(M_v + (M_g - M_v)*chi_vw_out) - k_mw_out = x_vw*k_v(iR0)/(x_vw + (1._wp - x_vw)*phi_vg) + (1._wp - x_vw)*k_g(iR0)/(x_vw*phi_gv + 1._wp - x_vw) + k_mw_out = x_vw*k_v(iR0)/(x_vw + (1._wp - x_vw)*phi_vg) & + + (1._wp - x_vw)*k_g(iR0)/(x_vw*phi_gv + 1._wp - x_vw) ! gas mixture density rho_mw_out = pv/(chi_vw_out*R_v*Tw) end subroutine s_bwproperty - !> Compute the vapour flux - elemental subroutine s_vflux(fR, fV, fpb, fmass_v, iR0, vflux, fmass_g, fbeta_c, fR_m, fgamma_m) - + !> Function that computes the vapour flux + !! @param fR Current bubble radius + !! @param fV Current bubble velocity + !! @param fpb + !! @param fmass_v Current mass of vapour + !! @param iR0 Bubble size index (EE) or bubble identifier (EL) + !! @param vflux Computed vapour flux + !! @param fmass_g Current gas mass (EL) + !! @param fbeta_c Mass transfer coefficient (EL) + !! @param fR_m Mixture gas constant (EL) + !! @param fgamma_m Mixture gamma (EL) + subroutine s_vflux(fR, fV, fpb, fmass_v, iR0, vflux, fmass_g, fbeta_c, fR_m, fgamma_m) $:GPU_ROUTINE(parallelism='[seq]') - real(wp), intent(in) :: fR - real(wp), intent(in) :: fV - real(wp), intent(in) :: fpb - real(wp), intent(in) :: fmass_v - integer, intent(in) :: iR0 - real(wp), intent(out) :: vflux - real(wp), intent(in), optional :: fmass_g, fbeta_c + real(wp), intent(in) :: fR + real(wp), intent(in) :: fV + real(wp), intent(in) :: fpb + real(wp), intent(in) :: fmass_v + integer, intent(in) :: iR0 + real(wp), intent(out) :: vflux + real(wp), intent(in), optional :: fmass_g, fbeta_c real(wp), intent(out), optional :: fR_m, fgamma_m - real(wp) :: chi_bar - real(wp) :: rho_mw_lag - real(wp) :: grad_chi - real(wp) :: conc_v - if (thermal == 3) then ! transfer + real(wp) :: chi_bar + real(wp) :: rho_mw_lag + real(wp) :: grad_chi + real(wp) :: conc_v + + if (thermal == 3) then !transfer ! constant transfer model if (bubbles_lagrange) then ! Mixture properties (gas+vapor) in the bubble @@ -297,62 +398,103 @@ contains end subroutine s_vflux - !> Compute the time derivative of the internal bubble pressure - elemental function f_bpres_dot(fvflux, fR, fV, fpb, fmass_v, iR0, fbeta_t, fR_m, fgamma_m) - + !> Function that computes the time derivative of + !! the internal bubble pressure + !! @param fvflux Vapour flux + !! @param fR Current bubble radius + !! @param fV Current bubble velocity + !! @param fpb Current internal bubble pressure + !! @param fmass_v Current mass of vapour + !! @param iR0 Bubble size index (EE) or bubble identifier (EL) + !! @param fbeta_t Mass transfer coefficient (EL) + !! @param fR_m Mixture gas constant (EL) + !! @param fgamma_m Mixture gamma (EL) + function f_bpres_dot(fvflux, fR, fV, fpb, fmass_v, iR0, fbeta_t, fR_m, fgamma_m) + !$DIR INLINENEVER f_bpres_dot $:GPU_ROUTINE(parallelism='[seq]') - real(wp), intent(in) :: fvflux - real(wp), intent(in) :: fR - real(wp), intent(in) :: fV - real(wp), intent(in) :: fpb - real(wp), intent(in) :: fmass_v - integer, intent(in) :: iR0 + real(wp), intent(in) :: fvflux + real(wp), intent(in) :: fR + real(wp), intent(in) :: fV + real(wp), intent(in) :: fpb + real(wp), intent(in) :: fmass_v + integer, intent(in) :: iR0 real(wp), intent(in), optional :: fbeta_t, fR_m, fgamma_m - real(wp) :: T_bar - real(wp) :: grad_T - real(wp) :: f_bpres_dot - real(wp) :: heatflux + + real(wp) :: T_bar + real(wp) :: grad_T + real(wp) :: f_bpres_dot + real(wp) :: heatflux if (thermal == 3) then if (bubbles_lagrange) then T_bar = fpb*(4._wp/3._wp*pi*fR**3._wp)/fR_m grad_T = -fbeta_t*(T_bar - Tw) heatflux = (fgamma_m - 1._wp)/fgamma_m*grad_T/fR - f_bpres_dot = 3._wp*fgamma_m*(-fV*fpb + fvflux*R_v*Tw + heatflux)/fR + f_bpres_dot = 3._wp*fgamma_m*(-fV*fpb + fvflux*R_v*Tw & + + heatflux)/fR return end if - grad_T = -Re_trans_T(iR0)*((fpb/pb0(iR0))*(fR/R0(iR0))**3*(mass_g0(iR0) + mass_v0(iR0))/(mass_g0(iR0) + fmass_v) & - & - 1._wp) - f_bpres_dot = 3._wp*gam_m*(-fV*fpb + fvflux*R_v*Tw + pb0(iR0)*k_mw*grad_T/Pe_T(iR0)/fR)/fR + grad_T = -Re_trans_T(iR0)*((fpb/pb0(iR0))*(fR/R0(iR0))**3 & + *(mass_g0(iR0) + mass_v0(iR0))/(mass_g0(iR0) + fmass_v) - 1._wp) + f_bpres_dot = 3._wp*gam_m*(-fV*fpb + fvflux*R_v*Tw & + + pb0(iR0)*k_mw*grad_T/Pe_T(iR0)/fR)/fR else f_bpres_dot = -3._wp*gam_m*fV/fR*(fpb - pv) end if end function f_bpres_dot - !> Adaptive time stepping routine for subgrid bubbles (See Heirer, E. Hairer S.P.Norsett G. Wanner, Solving Ordinary - !! Differential Equations I, Chapter II.4) - subroutine s_advance_step(fRho, fP, fR, fV, fR0, fpb, fpbdot, alf, fntait, fBtait, f_bub_adv_src, f_divu, bub_id, fmass_v, & - - & fmass_g, fbeta_c, fbeta_t, fCson, adap_dt_stop) - $:GPU_ROUTINE(function_name='s_advance_step',parallelism='[seq]', cray_inline=True) + !> Adaptive time stepping routine for subgrid bubbles + !! (See Heirer, E. Hairer S.P.Nørsett G. Wanner, Solving Ordinary + !! Differential Equations I, Chapter II.4) + !! @param fRho Current density + !! @param fP Current driving pressure + !! @param fR Current bubble radius + !! @param fV Current bubble radial velocity + !! @param fR0 Equilibrium bubble radius + !! @param fpb Internal bubble pressure + !! @param fpbdot Time-derivative of internal bubble pressure + !! @param alf bubble volume fraction + !! @param fntait Tait EOS parameter + !! @param fBtait Tait EOS parameter + !! @param f_bub_adv_src Source for bubble volume fraction + !! @param f_divu Divergence of velocity + !! @param bub_id Bubble identifier (EL) + !! @param fmass_v Current mass of vapour (EL) + !! @param fmass_g Current mass of gas (EL) + !! @param fbeta_c Mass transfer coefficient (EL) + !! @param fbeta_t Heat transfer coefficient (EL) + !! @param fCson Speed of sound (EL) + !! @param adap_dt_stop Fail-safe exit if max iteration count reached + function f_advance_step(fRho, fP, fR, fV, fR0, fpb, fpbdot, alf, & + fntait, fBtait, f_bub_adv_src, f_divu, & + bub_id, fmass_v, fmass_g, fbeta_c, & + fbeta_t, fCson, fRe, fPos, & + fVel, cell, q_prim_vf) result(adap_dt_stop) + $:GPU_ROUTINE(parallelism='[seq]') real(wp), intent(inout) :: fR, fV, fpb, fmass_v - real(wp), intent(in) :: fRho, fP, fR0, fpbdot, alf - real(wp), intent(in) :: fntait, fBtait, f_bub_adv_src, f_divu - integer, intent(in) :: bub_id - real(wp), intent(in) :: fmass_g, fbeta_c, fbeta_t, fCson - integer, intent(inout) :: adap_dt_stop - real(wp), dimension(5) :: err !< Error estimates for adaptive time stepping - real(wp) :: t_new !< Updated time step size - real(wp) :: h0, h !< Time step size - !> Bubble radius, radial velocity, and radial acceleration for the inner loop - real(wp), dimension(4) :: myR_tmp1, myV_tmp1, myR_tmp2, myV_tmp2 - real(wp), dimension(4) :: myPb_tmp1, myMv_tmp1, myPb_tmp2, myMv_tmp2 !< Gas pressure and vapor mass for the inner loop (EL) - real(wp) :: fR2, fV2, fpb2, fmass_v2 - integer :: iter_count - - call s_initial_substep_h(fRho, fP, fR, fV, fR0, fpb, fpbdot, alf, fntait, fBtait, f_bub_adv_src, f_divu, fCson, h0) + real(wp), intent(in) :: fRho, fP, fR0, fpbdot, alf + real(wp), intent(in) :: fntait, fBtait, f_bub_adv_src, f_divu + integer, intent(in) :: bub_id + real(wp), intent(in) :: fmass_g, fbeta_c, fbeta_t, fCson + real(wp), intent(inout), dimension(3), optional :: fPos, fVel + real(wp), intent(in), optional :: fRe + integer, intent(in), dimension(3), optional :: cell + type(scalar_field), intent(in), dimension(sys_size), optional :: q_prim_vf + + real(wp), dimension(5) :: err !< Error estimates for adaptive time stepping + real(wp) :: t_new !< Updated time step size + real(wp) :: h0, h !< Time step size + real(wp), dimension(4) :: myR_tmp1, myV_tmp1, myR_tmp2, myV_tmp2 !< Bubble radius, radial velocity, and radial acceleration for the inner loop + real(wp), dimension(4) :: myPb_tmp1, myMv_tmp1, myPb_tmp2, myMv_tmp2 !< Gas pressure and vapor mass for the inner loop (EL) + real(wp) :: fR2, fV2, fpb2, fmass_v2, f_bTemp + real(wp), dimension(3) :: vTemp, aTemp + integer :: adap_dt_stop + integer :: l, iter_count + + call s_initial_substep_h(fRho, fP, fR, fV, fR0, fpb, fpbdot, alf, & + fntait, fBtait, f_bub_adv_src, f_divu, fCson, h0) h = h0 ! Advancing one step t_new = 0._wp @@ -366,21 +508,28 @@ contains ! Advancing one sub-step do while (iter_count < adap_dt_max_iters) + iter_count = iter_count + 1 ! Advance one sub-step - call s_advance_substep(err(1), fRho, fP, fR, fV, fR0, fpb, fpbdot, alf, fntait, fBtait, f_bub_adv_src, f_divu, & - & bub_id, fmass_v, fmass_g, fbeta_c, fbeta_t, fCson, h, myR_tmp1, myV_tmp1, myPb_tmp1, & - & myMv_tmp1) + call s_advance_substep(err(1), & + fRho, fP, fR, fV, fR0, fpb, fpbdot, alf, & + fntait, fBtait, f_bub_adv_src, f_divu, & + bub_id, fmass_v, fmass_g, fbeta_c, & + fbeta_t, fCson, h, & + myR_tmp1, myV_tmp1, myPb_tmp1, myMv_tmp1) if (err(1) > adap_dt_tol) then h = 0.25_wp*h cycle end if ! Advance one sub-step by advancing two half steps - call s_advance_substep(err(2), fRho, fP, fR, fV, fR0, fpb, fpbdot, alf, fntait, fBtait, f_bub_adv_src, f_divu, & - & bub_id, fmass_v, fmass_g, fbeta_c, fbeta_t, fCson, 0.5_wp*h, myR_tmp2, myV_tmp2, & - & myPb_tmp2, myMv_tmp2) + call s_advance_substep(err(2), & + fRho, fP, fR, fV, fR0, fpb, fpbdot, alf, & + fntait, fBtait, f_bub_adv_src, f_divu, & + bub_id, fmass_v, fmass_g, fbeta_c, & + fbeta_t, fCson, 0.5_wp*h, & + myR_tmp2, myV_tmp2, myPb_tmp2, myMv_tmp2) if (err(2) > adap_dt_tol) then h = 0.25_wp*h cycle @@ -389,9 +538,12 @@ contains fR2 = myR_tmp2(4); fV2 = myV_tmp2(4) fpb2 = myPb_tmp2(4); fmass_v2 = myMv_tmp2(4) - call s_advance_substep(err(3), fRho, fP, fR2, fV2, fR0, fpb2, fpbdot, alf, fntait, fBtait, f_bub_adv_src, f_divu, & - & bub_id, fmass_v2, fmass_g, fbeta_c, fbeta_t, fCson, 0.5_wp*h, myR_tmp2, myV_tmp2, & - & myPb_tmp2, myMv_tmp2) + call s_advance_substep(err(3), & + fRho, fP, fR2, fV2, fR0, fpb2, fpbdot, alf, & + fntait, fBtait, f_bub_adv_src, f_divu, & + bub_id, fmass_v2, fmass_g, fbeta_c, & + fbeta_t, fCson, 0.5_wp*h, & + myR_tmp2, myV_tmp2, myPb_tmp2, myMv_tmp2) if (err(3) > adap_dt_tol) then h = 0.5_wp*h cycle @@ -401,10 +553,15 @@ contains err(5) = abs((myV_tmp1(4) - myV_tmp2(4))/myV_tmp1(4)) if (abs(myV_tmp1(4)) < verysmall) err(5) = 0._wp - ! Determine acceptance/rejection and update step size Rule 1: err1, err2, err3 < tol Rule 2: myR_tmp1(4) > 0._wp - ! Rule 3: abs((myR_tmp1(4) - myR_tmp2(4))/fR) < tol Rule 4: abs((myV_tmp1(4) - myV_tmp2(4))/fV) < tol - if ((err(1) <= adap_dt_tol) .and. (err(2) <= adap_dt_tol) .and. (err(3) <= adap_dt_tol) .and. (err(4) & - & <= adap_dt_tol) .and. (err(5) <= adap_dt_tol) .and. myR_tmp1(4) > 0._wp) then + ! Determine acceptance/rejection and update step size + ! Rule 1: err1, err2, err3 < tol + ! Rule 2: myR_tmp1(4) > 0._wp + ! Rule 3: abs((myR_tmp1(4) - myR_tmp2(4))/fR) < tol + ! Rule 4: abs((myV_tmp1(4) - myV_tmp2(4))/fV) < tol + if ((err(1) <= adap_dt_tol) .and. (err(2) <= adap_dt_tol) .and. & + (err(3) <= adap_dt_tol) .and. (err(4) <= adap_dt_tol) .and. & + (err(5) <= adap_dt_tol) .and. myR_tmp1(4) > 0._wp) then + ! Accepted. Finalize the sub-step t_new = t_new + h @@ -416,6 +573,37 @@ contains ! Update pb and mass_v fpb = myPb_tmp1(4) fmass_v = myMv_tmp1(4) + + select case (lag_vel_model) + case (1) + do l = 1, num_dims + vTemp(l) = f_interpolate_velocity(fR, cell, l, q_prim_vf) + end do + do l = 1, num_dims + fVel(l) = vTemp(l) + fPos(l) = fPos(l) + h*vTemp(l) + end do + case (2) + do l = 1, num_dims + f_bTemp = f_get_bubble_force(fPos(l), fR, fV, fVel(l), fmass_g, fmass_v, & + fRe, fRho, cell, l, q_prim_vf) + aTemp(l) = f_bTemp/(fmass_g + fmass_v) + end do + do l = 1, num_dims + fVel(l) = fVel(l) + h*aTemp(l) + fPos(l) = fPos(l) + h*fVel(l) + end do + case (3) + do l = 1, num_dims + f_bTemp = f_get_bubble_force(fPos(l), fR, fV, fVel(l), fmass_g, fmass_v, & + fRe, fRho, cell, l, q_prim_vf) + aTemp(l) = 2._wp*f_bTemp/(fmass_g + fmass_v) - 3._wp*fV*fVel(l)/fR + end do + do l = 1, num_dims + fVel(l) = fVel(l) + h*aTemp(l) + fPos(l) = fPos(l) + h*fVel(l) + end do + end select end if ! Update step size for the next sub-step @@ -434,29 +622,53 @@ contains ! Exit the loop if the final time reached dt if (f_approx_equal(t_new, 0.5_wp*dt) .or. iter_count >= adap_dt_max_iters) exit + end do if (iter_count >= adap_dt_max_iters) adap_dt_stop = 1 - end subroutine s_advance_step + end function f_advance_step + + !> Choose the initial time step size for the adaptive time stepping routine + !! (See Heirer, E. Hairer S.P.Nørsett G. Wanner, Solving Ordinary + !! Differential Equations I, Chapter II.4) + !! @param fRho Current density + !! @param fP Current driving pressure + !! @param fR Current bubble radius + !! @param fV Current bubble velocity + !! @param fR0 Equilibrium bubble radius + !! @param fpb Internal bubble pressure + !! @param fpbdot Time-derivative of internal bubble pressure + !! @param alf bubble volume fraction + !! @param fntait Tait EOS parameter + !! @param fBtait Tait EOS parameter + !! @param f_bub_adv_src Source for bubble volume fraction + !! @param f_divu Divergence of velocity + !! @param fCson Speed of sound (EL) + !! @param h Time step size + subroutine s_initial_substep_h(fRho, fP, fR, fV, fR0, fpb, fpbdot, alf, & + fntait, fBtait, f_bub_adv_src, f_divu, & + fCson, h) + $:GPU_ROUTINE(function_name='s_initial_substep_h',parallelism='[seq]', & + & cray_inline=True) - !> Choose the initial time step size for the adaptive time stepping routine (See Heirer, E. Hairer S.P.Norsett G. Wanner, - !! Solving Ordinary Differential Equations I, Chapter II.4) - subroutine s_initial_substep_h(fRho, fP, fR, fV, fR0, fpb, fpbdot, alf, fntait, fBtait, f_bub_adv_src, f_divu, fCson, h) + real(wp), intent(in) :: fRho, fP, fR, fV, fR0, fpb, fpbdot, alf + real(wp), intent(in) :: fntait, fBtait, f_bub_adv_src, f_divu + real(wp), intent(in) :: fCson + real(wp), intent(out) :: h - $:GPU_ROUTINE(function_name='s_initial_substep_h',parallelism='[seq]', cray_inline=True) + real(wp), dimension(2) :: h_size !< Time step size (h0, h1) + real(wp), dimension(3) :: d_norms !< norms (d_0, d_1, d_2) + real(wp), dimension(2) :: myR_tmp, myV_tmp, myA_tmp !< Bubble radius, radial velocity, and radial acceleration - real(wp), intent(in) :: fRho, fP, fR, fV, fR0, fpb, fpbdot, alf - real(wp), intent(in) :: fntait, fBtait, f_bub_adv_src, f_divu - real(wp), intent(in) :: fCson - real(wp), intent(out) :: h - real(wp), dimension(2) :: h_size !< Time step size (h0, h1) - real(wp), dimension(3) :: d_norms !< norms (d_0, d_1, d_2) - real(wp), dimension(2) :: myR_tmp, myV_tmp, myA_tmp !< Bubble radius, radial velocity, and radial acceleration - ! Determine the starting time step Evaluate f(x0,y0) + ! Determine the starting time step + ! Evaluate f(x0,y0) myR_tmp(1) = fR myV_tmp(1) = fV - myA_tmp(1) = f_rddot(fRho, fP, myR_tmp(1), myV_tmp(1), fR0, fpb, fpbdot, alf, fntait, fBtait, f_bub_adv_src, f_divu, fCson) + myA_tmp(1) = f_rddot(fRho, fP, myR_tmp(1), myV_tmp(1), fR0, & + fpb, fpbdot, alf, fntait, fBtait, & + f_bub_adv_src, f_divu, & + fCson) ! Compute d_0 = ||y0|| and d_1 = ||f(x0,y0)|| d_norms(1) = sqrt((myR_tmp(1)**2._wp + myV_tmp(1)**2._wp)/2._wp) @@ -470,12 +682,16 @@ contains ! Evaluate f(x0+h0,y0+h0*f(x0,y0)) myR_tmp(2) = myR_tmp(1) + h_size(1)*myV_tmp(1) myV_tmp(2) = myV_tmp(1) + h_size(1)*myA_tmp(1) - myA_tmp(2) = f_rddot(fRho, fP, myR_tmp(2), myV_tmp(2), fR0, fpb, fpbdot, alf, fntait, fBtait, f_bub_adv_src, f_divu, fCson) + myA_tmp(2) = f_rddot(fRho, fP, myR_tmp(2), myV_tmp(2), fR0, & + fpb, fpbdot, alf, fntait, fBtait, & + f_bub_adv_src, f_divu, & + fCson) ! Compute d_2 = ||f(x0+h0,y0+h0*f(x0,y0))-f(x0,y0)||/h0 d_norms(3) = sqrt(((myV_tmp(2) - myV_tmp(1))**2._wp + (myA_tmp(2) - myA_tmp(1))**2._wp)/2._wp)/h_size(1) - ! Set h1 = (0.01/max(d_1,d_2))^{1/(p+1)} if max(d_1,d_2) < 1.e-15_wp, h_size(2) = max(1.e-6_wp, h0*1.e-3_wp) + ! Set h1 = (0.01/max(d_1,d_2))^{1/(p+1)} + ! if max(d_1,d_2) < 1.e-15_wp, h_size(2) = max(1.e-6_wp, h0*1.e-3_wp) if (max(d_norms(2), d_norms(3)) < threshold_second_guess) then h_size(2) = max(small_guess, h_size(1)*scale_first_guess) else @@ -486,20 +702,49 @@ contains end subroutine s_initial_substep_h - !> Integrate bubble variables over the given time step size, h, using a third-order accurate embedded Runge-Kutta scheme. - subroutine s_advance_substep(err, fRho, fP, fR, fV, fR0, fpb, fpbdot, alf, fntait, fBtait, f_bub_adv_src, f_divu, bub_id, & - - & fmass_v, fmass_g, fbeta_c, fbeta_t, fCson, h, myR_tmp, myV_tmp, myPb_tmp, myMv_tmp) - $:GPU_ROUTINE(function_name='s_advance_substep',parallelism='[seq]', cray_inline=True) - - real(wp), intent(out) :: err - real(wp), intent(in) :: fRho, fP, fR, fV, fR0, fpb, fpbdot, alf - real(wp), intent(in) :: fntait, fBtait, f_bub_adv_src, f_divu, h - integer, intent(in) :: bub_id - real(wp), intent(in) :: fmass_v, fmass_g, fbeta_c, fbeta_t, fCson + !> Integrate bubble variables over the given time step size, h, using a + !! third-order accurate embedded Runge–Kutta scheme. + !! @param err Estimated error + !! @param fRho Current density + !! @param fP Current driving pressure + !! @param fR Current bubble radius + !! @param fV Current bubble velocity + !! @param fR0 Equilibrium bubble radius + !! @param fpb Internal bubble pressure + !! @param fpbdot Time-derivative of internal bubble pressure + !! @param alf bubble volume fraction + !! @param fntait Tait EOS parameter + !! @param fBtait Tait EOS parameter + !! @param f_bub_adv_src Source for bubble volume fraction + !! @param f_divu Divergence of velocity + !! @param bub_id Bubble identifier (EL) + !! @param fmass_v Current mass of vapour (EL) + !! @param fmass_g Current mass of gas (EL) + !! @param fbeta_c Mass transfer coefficient (EL) + !! @param fbeta_t Heat transfer coefficient (EL) + !! @param fCson Speed of sound (EL) + !! @param h Time step size + !! @param myR_tmp Bubble radius at each stage + !! @param myV_tmp Bubble radial velocity at each stage + !! @param myPb_tmp Internal bubble pressure at each stage (EL) + !! @param myMv_tmp Mass of vapor in the bubble at each stage (EL) + subroutine s_advance_substep(err, fRho, fP, fR, fV, fR0, fpb, fpbdot, alf, & + fntait, fBtait, f_bub_adv_src, f_divu, & + bub_id, fmass_v, fmass_g, fbeta_c, & + fbeta_t, fCson, h, & + myR_tmp, myV_tmp, myPb_tmp, myMv_tmp) + $:GPU_ROUTINE(function_name='s_advance_substep',parallelism='[seq]', & + & cray_inline=True) + + real(wp), intent(out) :: err + real(wp), intent(in) :: fRho, fP, fR, fV, fR0, fpb, fpbdot, alf + real(wp), intent(in) :: fntait, fBtait, f_bub_adv_src, f_divu, h + integer, intent(in) :: bub_id + real(wp), intent(in) :: fmass_v, fmass_g, fbeta_c, fbeta_t, fCson real(wp), dimension(4), intent(out) :: myR_tmp, myV_tmp, myPb_tmp, myMv_tmp - real(wp), dimension(4) :: myA_tmp, mydPbdt_tmp, mydMvdt_tmp - real(wp) :: err_R, err_V + + real(wp), dimension(4) :: myA_tmp, mydPbdt_tmp, mydMvdt_tmp + real(wp) :: err_R, err_V myPb_tmp(1:4) = fpb mydPbdt_tmp(1:4) = fpbdot @@ -510,11 +755,13 @@ contains if (bubbles_lagrange) then myPb_tmp(1) = fpb myMv_tmp(1) = fmass_v - call s_advance_EL(myR_tmp(1), myV_tmp(1), myPb_tmp(1), myMv_tmp(1), bub_id, fmass_g, fbeta_c, fbeta_t, & - & mydPbdt_tmp(1), mydMvdt_tmp(1)) + call s_advance_EL(myR_tmp(1), myV_tmp(1), myPb_tmp(1), myMv_tmp(1), bub_id, & + fmass_g, fbeta_c, fbeta_t, mydPbdt_tmp(1), mydMvdt_tmp(1)) end if - myA_tmp(1) = f_rddot(fRho, fP, myR_tmp(1), myV_tmp(1), fR0, myPb_tmp(1), mydPbdt_tmp(1), alf, fntait, fBtait, & - & f_bub_adv_src, f_divu, fCson) + myA_tmp(1) = f_rddot(fRho, fP, myR_tmp(1), myV_tmp(1), fR0, & + myPb_tmp(1), mydPbdt_tmp(1), alf, fntait, fBtait, & + f_bub_adv_src, f_divu, & + fCson) ! Stage 1 myR_tmp(2) = myR_tmp(1) + h*myV_tmp(1) @@ -525,11 +772,13 @@ contains if (bubbles_lagrange) then myPb_tmp(2) = myPb_tmp(1) + h*mydPbdt_tmp(1) myMv_tmp(2) = myMv_tmp(1) + h*mydMvdt_tmp(1) - call s_advance_EL(myR_tmp(2), myV_tmp(2), myPb_tmp(2), myMv_tmp(2), bub_id, fmass_g, fbeta_c, fbeta_t, & - & mydPbdt_tmp(2), mydMvdt_tmp(2)) + call s_advance_EL(myR_tmp(2), myV_tmp(2), myPb_tmp(2), myMv_tmp(2), & + bub_id, fmass_g, fbeta_c, fbeta_t, mydPbdt_tmp(2), mydMvdt_tmp(2)) end if - myA_tmp(2) = f_rddot(fRho, fP, myR_tmp(2), myV_tmp(2), fR0, myPb_tmp(2), mydPbdt_tmp(2), alf, fntait, fBtait, & - & f_bub_adv_src, f_divu, fCson) + myA_tmp(2) = f_rddot(fRho, fP, myR_tmp(2), myV_tmp(2), fR0, & + myPb_tmp(2), mydPbdt_tmp(2), alf, fntait, fBtait, & + f_bub_adv_src, f_divu, & + fCson) ! Stage 2 myR_tmp(3) = myR_tmp(1) + (h/4._wp)*(myV_tmp(1) + myV_tmp(2)) @@ -540,11 +789,13 @@ contains if (bubbles_lagrange) then myPb_tmp(3) = myPb_tmp(1) + (h/4._wp)*(mydPbdt_tmp(1) + mydPbdt_tmp(2)) myMv_tmp(3) = myMv_tmp(1) + (h/4._wp)*(mydMvdt_tmp(1) + mydMvdt_tmp(2)) - call s_advance_EL(myR_tmp(3), myV_tmp(3), myPb_tmp(3), myMv_tmp(3), bub_id, fmass_g, fbeta_c, fbeta_t, & - & mydPbdt_tmp(3), mydMvdt_tmp(3)) + call s_advance_EL(myR_tmp(3), myV_tmp(3), myPb_tmp(3), myMv_tmp(3), & + bub_id, fmass_g, fbeta_c, fbeta_t, mydPbdt_tmp(3), mydMvdt_tmp(3)) end if - myA_tmp(3) = f_rddot(fRho, fP, myR_tmp(3), myV_tmp(3), fR0, myPb_tmp(3), mydPbdt_tmp(3), alf, fntait, fBtait, & - & f_bub_adv_src, f_divu, fCson) + myA_tmp(3) = f_rddot(fRho, fP, myR_tmp(3), myV_tmp(3), fR0, & + myPb_tmp(3), mydPbdt_tmp(3), alf, fntait, fBtait, & + f_bub_adv_src, f_divu, & + fCson) ! Stage 3 myR_tmp(4) = myR_tmp(1) + (h/6._wp)*(myV_tmp(1) + myV_tmp(2) + 4._wp*myV_tmp(3)) @@ -555,37 +806,52 @@ contains if (bubbles_lagrange) then myPb_tmp(4) = myPb_tmp(1) + (h/6._wp)*(mydPbdt_tmp(1) + mydPbdt_tmp(2) + 4._wp*mydPbdt_tmp(3)) myMv_tmp(4) = myMv_tmp(1) + (h/6._wp)*(mydMvdt_tmp(1) + mydMvdt_tmp(2) + 4._wp*mydMvdt_tmp(3)) - call s_advance_EL(myR_tmp(4), myV_tmp(4), myPb_tmp(4), myMv_tmp(4), bub_id, fmass_g, fbeta_c, fbeta_t, & - & mydPbdt_tmp(4), mydMvdt_tmp(4)) + call s_advance_EL(myR_tmp(4), myV_tmp(4), myPb_tmp(4), myMv_tmp(4), & + bub_id, fmass_g, fbeta_c, fbeta_t, mydPbdt_tmp(4), mydMvdt_tmp(4)) end if - myA_tmp(4) = f_rddot(fRho, fP, myR_tmp(4), myV_tmp(4), fR0, myPb_tmp(4), mydPbdt_tmp(4), alf, fntait, fBtait, & - & f_bub_adv_src, f_divu, fCson) + myA_tmp(4) = f_rddot(fRho, fP, myR_tmp(4), myV_tmp(4), fR0, & + myPb_tmp(4), mydPbdt_tmp(4), alf, fntait, fBtait, & + f_bub_adv_src, f_divu, & + fCson) ! Estimate error - err_R = (-5._wp*h/24._wp)*(myV_tmp(2) + myV_tmp(3) - 2._wp*myV_tmp(4))/max(abs(myR_tmp(1)), abs(myR_tmp(4))) - err_V = (-5._wp*h/24._wp)*(myA_tmp(2) + myA_tmp(3) - 2._wp*myA_tmp(4))/max(abs(myV_tmp(1)), abs(myV_tmp(4))) + err_R = (-5._wp*h/24._wp)*(myV_tmp(2) + myV_tmp(3) - 2._wp*myV_tmp(4)) & + /max(abs(myR_tmp(1)), abs(myR_tmp(4))) + err_V = (-5._wp*h/24._wp)*(myA_tmp(2) + myA_tmp(3) - 2._wp*myA_tmp(4)) & + /max(abs(myV_tmp(1)), abs(myV_tmp(4))) ! Error correction for non-oscillating bubbles if (max(abs(myV_tmp(1)), abs(myV_tmp(4))) < 1.e-12_wp) then err_V = 0._wp end if - if (bubbles_lagrange .and. f_approx_equal(myA_tmp(1), 0._wp) .and. f_approx_equal(myA_tmp(2), & - & 0._wp) .and. f_approx_equal(myA_tmp(3), 0._wp) .and. f_approx_equal(myA_tmp(4), 0._wp)) then + if (bubbles_lagrange .and. f_approx_equal(myA_tmp(1), 0._wp) .and. f_approx_equal(myA_tmp(2), 0._wp) .and. & + f_approx_equal(myA_tmp(3), 0._wp) .and. f_approx_equal(myA_tmp(4), 0._wp)) then err_V = 0._wp end if err = sqrt((err_R**2._wp + err_V**2._wp)/2._wp) end subroutine s_advance_substep - !> Changes of pressure and vapor mass in the lagrange bubbles. - elemental subroutine s_advance_EL(fR_tmp, fV_tmp, fPb_tmp, fMv_tmp, bub_id, fmass_g, fbeta_c, fbeta_t, fdPbdt_tmp, advance_EL) - + !> Changes of pressure and vapor mass in the lagrange bubbles. + !! @param fR_tmp Bubble radius + !! @param fV_tmp Bubble radial velocity + !! @param fPb_tmp Internal bubble pressure + !! @param fMv_tmp Mass of vapor in the bubble + !! @param bub_id Bubble identifier + !! @param fmass_g Current mass of gas + !! @param fbeta_c Mass transfer coefficient + !! @param fbeta_t Heat transfer coefficient + !! @param fdPbdt_tmp Rate of change of the internal bubble pressure + !! @param fdMvdt_tmp Rate of change of the mass of vapor in the bubble + !! @param advance_EL Rate of change of the mass of vapor in the bubble + subroutine s_advance_EL(fR_tmp, fV_tmp, fPb_tmp, fMv_tmp, bub_id, & + fmass_g, fbeta_c, fbeta_t, fdPbdt_tmp, advance_EL) $:GPU_ROUTINE(parallelism='[seq]') - real(wp), intent(in) :: fR_tmp, fV_tmp, fPb_tmp, fMv_tmp - real(wp), intent(in) :: fmass_g, fbeta_c, fbeta_t - integer, intent(in) :: bub_id + real(wp), intent(in) :: fR_tmp, fV_tmp, fPb_tmp, fMv_tmp + real(wp), intent(in) :: fmass_g, fbeta_c, fbeta_t + integer, intent(in) :: bub_id real(wp), intent(inout) :: fdPbdt_tmp - real(wp), intent(out) :: advance_EL - real(wp) :: fVapFlux, myR_m, mygamma_m + real(wp), intent(out) :: advance_EL + real(wp) :: fVapFlux, myR_m, mygamma_m call s_vflux(fR_tmp, fV_tmp, fPb_tmp, fMv_tmp, bub_id, fVapFlux, fmass_g, fbeta_c, myR_m, mygamma_m) fdPbdt_tmp = f_bpres_dot(fVapFlux, fR_tmp, fV_tmp, fPb_tmp, fMv_tmp, bub_id, fbeta_t, myR_m, mygamma_m) diff --git a/src/simulation/m_bubbles_EE.fpp b/src/simulation/m_bubbles_EE.fpp index b2c5f1fd97..a88d6bb20f 100644 --- a/src/simulation/m_bubbles_EE.fpp +++ b/src/simulation/m_bubbles_EE.fpp @@ -7,27 +7,31 @@ !> @brief Computes ensemble-averaged (Euler--Euler) bubble source terms for radius, velocity, pressure, and mass transfer module m_bubbles_EE - use m_derived_types - use m_global_parameters - use m_mpi_proxy - use m_variables_conversion - use m_bubbles + use m_derived_types !< Definitions of the derived types + + use m_global_parameters !< Definitions of the global parameters + + use m_mpi_proxy !< Message passing interface (MPI) module proxy + + use m_variables_conversion !< State variables type conversion procedures + + use m_bubbles !< General bubble dynamics procedures implicit none - real(wp), allocatable, dimension(:,:,:) :: bub_adv_src - real(wp), allocatable, dimension(:,:,:,:) :: bub_r_src, bub_v_src, bub_p_src, bub_m_src - $:GPU_DECLARE(create='[bub_adv_src, bub_r_src, bub_v_src, bub_p_src, bub_m_src]') + real(wp), allocatable, dimension(:, :, :) :: bub_adv_src + real(wp), allocatable, dimension(:, :, :, :) :: bub_r_src, bub_v_src, bub_p_src, bub_m_src + $:GPU_DECLARE(create='[bub_adv_src,bub_r_src,bub_v_src,bub_p_src,bub_m_src]') - type(scalar_field) :: divu !< matrix for div(u) + type(scalar_field) :: divu !< matrix for div(u) $:GPU_DECLARE(create='[divu]') integer, allocatable, dimension(:) :: rs, vs, ms, ps - $:GPU_DECLARE(create='[rs, vs, ms, ps]') + $:GPU_DECLARE(create='[rs,vs,ms,ps]') contains - !> Initialize the Euler-Euler bubble module + !> @brief Allocates and initializes arrays for the Euler-Euler bubble model. impure subroutine s_initialize_bubbles_EE_module integer :: l @@ -65,14 +69,14 @@ contains end subroutine s_initialize_bubbles_EE_module - !> Compute the bubble volume fraction alpha from the bubble number density + !> @brief Computes the bubble volume fraction alpha from the bubble number density. + !! @param q_cons_vf is the conservative variable subroutine s_comp_alpha_from_n(q_cons_vf) - type(scalar_field), dimension(sys_size), intent(inout) :: q_cons_vf - real(wp) :: nR3bar - integer(wp) :: i, j, k, l + real(wp) :: nR3bar + integer(wp) :: i, j, k, l - $:GPU_PARALLEL_LOOP(private='[i, j, k, l, nR3bar]', collapse=3) + $:GPU_PARALLEL_LOOP(private='[i,j,k,l,nR3bar]', collapse=3) do l = 0, p do k = 0, n do j = 0, m @@ -89,81 +93,101 @@ contains end subroutine s_comp_alpha_from_n - !> Compute the right-hand side for Euler-Euler bubble transport + !> Compute the right-hand side for Euler-Euler bubble transport + !! @param idir Direction index + !! @param q_prim_vf Primitive variables subroutine s_compute_bubbles_EE_rhs(idir, q_prim_vf, divu_in) - integer, intent(in) :: idir + integer, intent(in) :: idir type(scalar_field), dimension(sys_size), intent(in) :: q_prim_vf - type(scalar_field), intent(inout) :: divu_in !< matrix for div(u) - integer :: j, k, l + type(scalar_field), intent(inout) :: divu_in !< matrix for div(u) + + integer :: j, k, l if (idir == 1) then + if (.not. qbmm) then - $:GPU_PARALLEL_LOOP(private='[j, k, l]', collapse=3) + $:GPU_PARALLEL_LOOP(private='[j,k,l]', collapse=3) do l = 0, p do k = 0, n do j = 0, m divu_in%sf(j, k, l) = 0._wp - divu_in%sf(j, k, l) = 5.e-1_wp/dx(j)*(q_prim_vf(contxe + idir)%sf(j + 1, k, & - & l) - q_prim_vf(contxe + idir)%sf(j - 1, k, l)) + divu_in%sf(j, k, l) = & + 5.e-1_wp/dx(j)*(q_prim_vf(contxe + idir)%sf(j + 1, k, l) - & + q_prim_vf(contxe + idir)%sf(j - 1, k, l)) + end do end do end do $:END_GPU_PARALLEL_LOOP() end if - else if (idir == 2) then - $:GPU_PARALLEL_LOOP(private='[j, k, l]', collapse=3) + + elseif (idir == 2) then + + $:GPU_PARALLEL_LOOP(private='[j,k,l]', collapse=3) do l = 0, p do k = 0, n do j = 0, m - divu_in%sf(j, k, l) = divu_in%sf(j, k, l) + 5.e-1_wp/dy(k)*(q_prim_vf(contxe + idir)%sf(j, k + 1, & - & l) - q_prim_vf(contxe + idir)%sf(j, k - 1, l)) + divu_in%sf(j, k, l) = divu_in%sf(j, k, l) + & + 5.e-1_wp/dy(k)*(q_prim_vf(contxe + idir)%sf(j, k + 1, l) - & + q_prim_vf(contxe + idir)%sf(j, k - 1, l)) + end do end do end do $:END_GPU_PARALLEL_LOOP() - else if (idir == 3) then - $:GPU_PARALLEL_LOOP(private='[j, k, l]', collapse=3) + + elseif (idir == 3) then + + $:GPU_PARALLEL_LOOP(private='[j,k,l]', collapse=3) do l = 0, p do k = 0, n do j = 0, m - divu_in%sf(j, k, l) = divu_in%sf(j, k, l) + 5.e-1_wp/dz(l)*(q_prim_vf(contxe + idir)%sf(j, k, & - & l + 1) - q_prim_vf(contxe + idir)%sf(j, k, l - 1)) + divu_in%sf(j, k, l) = divu_in%sf(j, k, l) + & + 5.e-1_wp/dz(l)*(q_prim_vf(contxe + idir)%sf(j, k, l + 1) - & + q_prim_vf(contxe + idir)%sf(j, k, l - 1)) + end do end do end do $:END_GPU_PARALLEL_LOOP() + end if end subroutine s_compute_bubbles_EE_rhs - !> Compute the Euler-Euler bubble source terms + !> The purpose of this procedure is to compute the source terms + !! that are needed for the bubble modeling + !! @param q_prim_vf Primitive variables + !! @param q_cons_vf Conservative variables + !! @param rhs_vf Right-hand side variables impure subroutine s_compute_bubble_EE_source(q_cons_vf, q_prim_vf, rhs_vf, divu_in) - type(scalar_field), dimension(sys_size), intent(inout) :: q_cons_vf - type(scalar_field), dimension(sys_size), intent(in) :: q_prim_vf + type(scalar_field), dimension(sys_size), intent(in) :: q_prim_vf type(scalar_field), dimension(sys_size), intent(inout) :: rhs_vf - type(scalar_field), intent(in) :: divu_in !< matrix for div(u) - real(wp) :: rddot - real(wp) :: pb_local, mv_local, vflux, pbdot - real(wp) :: n_tait, B_tait + type(scalar_field), intent(in) :: divu_in !< matrix for div(u) + real(wp) :: rddot + real(wp) :: pb_local, mv_local, vflux, pbdot + real(wp) :: n_tait, B_tait #:if not MFC_CASE_OPTIMIZATION and USING_AMD real(wp), dimension(3) :: Rtmp, Vtmp real(wp), dimension(3) :: myalpha, myalpha_rho #:else - real(wp), dimension(nb) :: Rtmp, Vtmp + real(wp), dimension(nb) :: Rtmp, Vtmp real(wp), dimension(num_fluids) :: myalpha, myalpha_rho #:endif real(wp) :: myR, myV, alf, myP, myRho, R2Vav, R3 - real(wp) :: nbub !< Bubble number density + real(wp) :: nbub !< Bubble number density real(wp) :: my_divu - integer :: i, j, k, l, q, ii !< Loop variables - integer :: adap_dt_stop_max, adap_dt_stop !< Fail-safe exit if max iteration count reached - integer :: dmBub_id !< Dummy variables for unified subgrid bubble subroutines + + integer :: i, j, k, l, q, ii !< Loop variables + + integer :: adap_dt_stop_sum, adap_dt_stop !< Fail-safe exit if max iteration count reached + integer :: dmBub_id !< Dummy variables for unified subgrid bubble subroutines real(wp) :: dmMass_v, dmMass_n, dmBeta_c, dmBeta_t, dmCson - $:GPU_PARALLEL_LOOP(private='[j, k, l, q]', collapse=3) + $:GPU_PARALLEL_LOOP(private='[j,k,l,q]', collapse=3) do l = 0, p do k = 0, n do j = 0, m @@ -181,13 +205,13 @@ contains end do $:END_GPU_PARALLEL_LOOP() - adap_dt_stop_max = 0 - $:GPU_PARALLEL_LOOP(private='[j, k, l, Rtmp, Vtmp, myalpha_rho, myalpha, myR, myV, alf, myP, myRho, R2Vav, R3, nbub, & - & pb_local, mv_local, vflux, pbdot, rddot, n_tait, B_tait, my_divu]', collapse=3, & - & reduction = '[[adap_dt_stop_max]]', reductionOp = '[MAX]', copy = '[adap_dt_stop_max]') + adap_dt_stop_sum = 0 + $:GPU_PARALLEL_LOOP(private='[j,k,l,Rtmp, Vtmp, myalpha_rho, myalpha, myR, myV, alf, myP, myRho, R2Vav, R3, nbub, pb_local, mv_local, vflux, pbdot, rddot, n_tait, B_tait, my_divu, adap_dt_stop]', collapse=3, & + & copy='[adap_dt_stop_sum]') do l = 0, p do k = 0, n do j = 0, m + if (adv_n) then nbub = q_prim_vf(n_idx)%sf(j, k, l) else @@ -220,6 +244,7 @@ contains $:GPU_LOOP(parallelism='[seq]') do q = 1, nb + $:GPU_LOOP(parallelism='[seq]') do ii = 1, num_fluids myalpha_rho(ii) = q_cons_vf(ii)%sf(j, k, l) @@ -243,8 +268,8 @@ contains end do end if - n_tait = 1._wp/n_tait + 1._wp ! make this the usual little 'gamma' - B_tait = B_tait*(n_tait - 1)/n_tait ! make this the usual pi_inf + n_tait = 1._wp/n_tait + 1._wp !make this the usual little 'gamma' + B_tait = B_tait*(n_tait - 1)/n_tait ! make this the usual pi_inf myP = q_prim_vf(E_idx)%sf(j, k, l) alf = q_prim_vf(alf_idx)%sf(j, k, l) @@ -272,24 +297,31 @@ contains pb_local = 0._wp; mv_local = 0._wp; vflux = 0._wp; pbdot = 0._wp end if + adap_dt_stop = 0 + ! Adaptive time stepping if (adap_dt) then - adap_dt_stop = 0 - call s_advance_step(myRho, myP, myR, myV, R0(q), pb_local, pbdot, alf, n_tait, B_tait, & - & bub_adv_src(j, k, l), divu_in%sf(j, k, l), dmBub_id, dmMass_v, dmMass_n, & - & dmBeta_c, dmBeta_t, dmCson, adap_dt_stop) + adap_dt_stop = f_advance_step(myRho, myP, myR, myV, R0(q), & + pb_local, pbdot, alf, n_tait, B_tait, & + bub_adv_src(j, k, l), divu_in%sf(j, k, l), & + dmBub_id, dmMass_v, dmMass_n, dmBeta_c, & + dmBeta_t, dmCson) q_cons_vf(rs(q))%sf(j, k, l) = nbub*myR q_cons_vf(vs(q))%sf(j, k, l) = nbub*myV - adap_dt_stop_max = max(adap_dt_stop_max, adap_dt_stop) else - rddot = f_rddot(myRho, myP, myR, myV, R0(q), pb_local, pbdot, alf, n_tait, B_tait, bub_adv_src(j, & - & k, l), divu_in%sf(j, k, l), dmCson) + rddot = f_rddot(myRho, myP, myR, myV, R0(q), & + pb_local, pbdot, alf, n_tait, B_tait, & + bub_adv_src(j, k, l), divu_in%sf(j, k, l), & + dmCson) bub_v_src(j, k, l, q) = nbub*rddot bub_r_src(j, k, l, q) = q_cons_vf(vs(q))%sf(j, k, l) end if + + $:GPU_ATOMIC(atomic='update') + adap_dt_stop_sum = adap_dt_stop_sum + adap_dt_stop end if end do end do @@ -297,15 +329,16 @@ contains end do $:END_GPU_PARALLEL_LOOP() - if (adap_dt .and. adap_dt_stop_max > 0) call s_mpi_abort("Adaptive time stepping failed to converge.") + if (adap_dt .and. adap_dt_stop_sum > 0) call s_mpi_abort("Adaptive time stepping failed to converge.") if (.not. adap_dt) then - $:GPU_PARALLEL_LOOP(private='[i, k, l, q]', collapse=3) + $:GPU_PARALLEL_LOOP(private='[i,k,l,q]', collapse=3) do l = 0, p do q = 0, n do i = 0, m rhs_vf(alf_idx)%sf(i, q, l) = rhs_vf(alf_idx)%sf(i, q, l) + bub_adv_src(i, q, l) - if (num_fluids > 1) rhs_vf(advxb)%sf(i, q, l) = rhs_vf(advxb)%sf(i, q, l) - bub_adv_src(i, q, l) + if (num_fluids > 1) rhs_vf(advxb)%sf(i, q, l) = & + rhs_vf(advxb)%sf(i, q, l) - bub_adv_src(i, q, l) $:GPU_LOOP(parallelism='[seq]') do k = 1, nb rhs_vf(rs(k))%sf(i, q, l) = rhs_vf(rs(k))%sf(i, q, l) + bub_r_src(i, q, l, k) @@ -320,7 +353,6 @@ contains end do $:END_GPU_PARALLEL_LOOP() end if - end subroutine s_compute_bubble_EE_source end module m_bubbles_EE diff --git a/src/simulation/m_bubbles_EL.fpp b/src/simulation/m_bubbles_EL.fpp index 437dbe0db2..9e6b413db5 100644 --- a/src/simulation/m_bubbles_EL.fpp +++ b/src/simulation/m_bubbles_EL.fpp @@ -7,106 +7,151 @@ !> @brief Tracks Lagrangian bubbles and couples their dynamics to the Eulerian flow via volume averaging module m_bubbles_EL - use m_global_parameters - use m_mpi_proxy - use m_bubbles_EL_kernels - use m_bubbles - use m_variables_conversion + use m_global_parameters !< Definitions of the global parameters + + use m_mpi_proxy !< Message passing interface (MPI) module proxy + + use m_bubbles_EL_kernels !< Definitions of the kernel functions + + use m_bubbles !< General bubble dynamics procedures + + use m_variables_conversion !< State variables type conversion procedures + use m_compile_specific + use m_boundary_common - use m_helper_basic + + use m_helper_basic !< Functions to compare floating point numbers + use m_sim_helpers + use m_helper + use m_mpi_common + + use m_ibm + + use m_finite_differences + implicit none - ! (nBub) - integer, allocatable, dimension(:,:) :: lag_id !< Global and local IDs - real(wp), allocatable, dimension(:) :: bub_R0 !< Initial bubble radius - real(wp), allocatable, dimension(:) :: Rmax_stats !< Maximum radius - real(wp), allocatable, dimension(:) :: Rmin_stats !< Minimum radius + !(nBub) + integer, allocatable, dimension(:, :) :: lag_id !< Global and local IDs + real(wp), allocatable, dimension(:) :: bub_R0 !< Initial bubble radius + real(wp), allocatable, dimension(:) :: Rmax_stats !< Maximum radius + real(wp), allocatable, dimension(:) :: Rmin_stats !< Minimum radius $:GPU_DECLARE(create='[lag_id, bub_R0, Rmax_stats, Rmin_stats]') - real(wp), allocatable, dimension(:) :: gas_mg !< Bubble's gas mass - real(wp), allocatable, dimension(:) :: gas_betaT !< heatflux model (Preston et al., 2007) - real(wp), allocatable, dimension(:) :: gas_betaC !< massflux model (Preston et al., 2007) - real(wp), allocatable, dimension(:) :: bub_dphidt !< subgrid velocity potential (Maeda & Colonius, 2018) + real(wp), allocatable, dimension(:) :: gas_mg !< Bubble's gas mass + real(wp), allocatable, dimension(:) :: gas_betaT !< heatflux model (Preston et al., 2007) + real(wp), allocatable, dimension(:) :: gas_betaC !< massflux model (Preston et al., 2007) + real(wp), allocatable, dimension(:) :: bub_dphidt !< subgrid velocity potential (Maeda & Colonius, 2018) $:GPU_DECLARE(create='[gas_mg, gas_betaT, gas_betaC, bub_dphidt]') - ! (nBub, 1 -> actual val or 2 -> temp val) - real(wp), allocatable, dimension(:,:) :: gas_p !< Pressure in the bubble - real(wp), allocatable, dimension(:,:) :: gas_mv !< Vapor mass in the bubble - real(wp), allocatable, dimension(:,:) :: intfc_rad !< Bubble radius - real(wp), allocatable, dimension(:,:) :: intfc_vel !< Velocity of the bubble interface + !(nBub, 1 -> actual val or 2 -> temp val) + real(wp), allocatable, dimension(:, :) :: gas_p !< Pressure in the bubble + real(wp), allocatable, dimension(:, :) :: gas_mv !< Vapor mass in the bubble + real(wp), allocatable, dimension(:, :) :: intfc_rad !< Bubble radius + real(wp), allocatable, dimension(:, :) :: intfc_vel !< Velocity of the bubble interface $:GPU_DECLARE(create='[gas_p, gas_mv, intfc_rad, intfc_vel]') - ! (nBub, 1-> x or 2->y or 3 ->z, 1 -> actual or 2 -> temporal val) - real(wp), allocatable, dimension(:,:,:) :: mtn_pos !< Bubble's position - real(wp), allocatable, dimension(:,:,:) :: mtn_posPrev !< Bubble's previous position - real(wp), allocatable, dimension(:,:,:) :: mtn_vel !< Bubble's velocity - real(wp), allocatable, dimension(:,:,:) :: mtn_s !< Bubble's computational cell position in real format + !(nBub, 1-> x or 2->y or 3 ->z, 1 -> actual or 2 -> temporal val) + real(wp), allocatable, dimension(:, :, :) :: mtn_pos !< Bubble's position + real(wp), allocatable, dimension(:, :, :) :: mtn_posPrev !< Bubble's previous position + real(wp), allocatable, dimension(:, :, :) :: mtn_vel !< Bubble's velocity + real(wp), allocatable, dimension(:, :, :) :: mtn_s !< Bubble's computational cell position in real format $:GPU_DECLARE(create='[mtn_pos, mtn_posPrev, mtn_vel, mtn_s]') - ! (nBub, 1-> x or 2->y or 3 ->z, time-stage) - real(wp), allocatable, dimension(:,:) :: intfc_draddt !< Time derivative of bubble's radius - real(wp), allocatable, dimension(:,:) :: intfc_dveldt !< Time derivative of bubble's interface velocity - real(wp), allocatable, dimension(:,:) :: gas_dpdt !< Time derivative of gas pressure - real(wp), allocatable, dimension(:,:) :: gas_dmvdt !< Time derivative of the vapor mass in the bubble - real(wp), allocatable, dimension(:,:,:) :: mtn_dposdt !< Time derivative of the bubble's position - real(wp), allocatable, dimension(:,:,:) :: mtn_dveldt !< Time derivative of the bubble's velocity + !(nBub, 1-> x or 2->y or 3 ->z, time-stage) + real(wp), allocatable, dimension(:, :) :: intfc_draddt !< Time derivative of bubble's radius + real(wp), allocatable, dimension(:, :) :: intfc_dveldt !< Time derivative of bubble's interface velocity + real(wp), allocatable, dimension(:, :) :: gas_dpdt !< Time derivative of gas pressure + real(wp), allocatable, dimension(:, :) :: gas_dmvdt !< Time derivative of the vapor mass in the bubble + real(wp), allocatable, dimension(:, :, :) :: mtn_dposdt !< Time derivative of the bubble's position + real(wp), allocatable, dimension(:, :, :) :: mtn_dveldt !< Time derivative of the bubble's velocity $:GPU_DECLARE(create='[intfc_draddt, intfc_dveldt, gas_dpdt, gas_dmvdt, mtn_dposdt, mtn_dveldt]') - integer, private :: lag_num_ts !< Number of time stages in the time-stepping scheme + integer, private :: lag_num_ts !< Number of time stages in the time-stepping scheme + $:GPU_DECLARE(create='[lag_num_ts]') - integer :: nBubs !< Number of bubbles in the local domain - real(wp) :: Rmax_glb, Rmin_glb !< Maximum and minimum bubbe size in the local domain - !> Projection of the lagrangian particles in the Eulerian framework + real(wp) :: Rmax_glb, Rmin_glb !< Maximum and minimum bubble size in the local domain + !< Projection of the lagrangian particles in the Eulerian framework type(scalar_field), dimension(:), allocatable :: q_beta - integer :: q_beta_idx !< Size of the q_beta vector field - $:GPU_DECLARE(create='[nBubs, Rmax_glb, Rmin_glb, q_beta, q_beta_idx]') + type(scalar_field), dimension(:), allocatable :: kahan_comp !< Kahan compensation for q_beta accumulation + integer :: q_beta_idx !< Size of the q_beta vector field + + $:GPU_DECLARE(create='[Rmax_glb,Rmin_glb,q_beta,kahan_comp,q_beta_idx]') + + integer, parameter :: LAG_EVOL_ID = 11 ! File id for lag_bubbles_evol_*.dat + integer, parameter :: LAG_STATS_ID = 12 ! File id for stats_lag_bubbles_*.dat + integer, parameter :: LAG_VOID_ID = 13 ! File id for voidfraction.dat + + integer, allocatable, dimension(:) :: keep_bubble + integer, allocatable, dimension(:, :) :: wrap_bubble_loc, wrap_bubble_dir + $:GPU_DECLARE(create='[keep_bubble]') + $:GPU_DECLARE(create='[wrap_bubble_loc, wrap_bubble_dir]') contains !> Initializes the lagrangian subgrid bubble solver - impure subroutine s_initialize_bubbles_EL_module(q_cons_vf) + !! @param q_cons_vf Initial conservative variables + impure subroutine s_initialize_bubbles_EL_module(q_cons_vf, bc_type) type(scalar_field), dimension(sys_size), intent(inout) :: q_cons_vf - integer :: nBubs_glb, i + type(integer_field), dimension(1:num_dims, 1:2), intent(in) :: bc_type - ! Setting number of time-stages for selected time-stepping scheme + integer :: nBubs_glb, i + ! Setting number of time-stages for selected time-stepping scheme lag_num_ts = time_stepper ! Allocate space for the Eulerian fields needed to map the effect of the bubbles if (lag_params%solver_approach == 1) then ! One-way coupling q_beta_idx = 3 - else if (lag_params%solver_approach == 2) then + elseif (lag_params%solver_approach == 2) then ! Two-way coupling q_beta_idx = 4 if (p == 0) then - ! Subgrid noise model for 2D approximation + !Subgrid noise model for 2D approximation q_beta_idx = 6 end if else call s_mpi_abort('Please check the lag_params%solver_approach input') end if + pcomm_coords(1)%beg = x_cb(-1) + pcomm_coords(1)%end = x_cb(m) + $:GPU_UPDATE(device='[pcomm_coords(1)]') + if (n > 0) then + pcomm_coords(2)%beg = y_cb(-1) + pcomm_coords(2)%end = y_cb(n) + $:GPU_UPDATE(device='[pcomm_coords(2)]') + if (p > 0) then + pcomm_coords(3)%beg = z_cb(-1) + pcomm_coords(3)%end = z_cb(p) + $:GPU_UPDATE(device='[pcomm_coords(3)]') + end if + end if + $:GPU_UPDATE(device='[lag_num_ts, q_beta_idx]') @:ALLOCATE(q_beta(1:q_beta_idx)) + @:ALLOCATE(kahan_comp(1:q_beta_idx)) do i = 1, q_beta_idx - @:ALLOCATE(q_beta(i)%sf(idwbuff(1)%beg:idwbuff(1)%end, idwbuff(2)%beg:idwbuff(2)%end, idwbuff(3)%beg:idwbuff(3)%end)) - end do - - do i = 1, q_beta_idx + @:ALLOCATE(q_beta(i)%sf(idwbuff(1)%beg:idwbuff(1)%end, & + idwbuff(2)%beg:idwbuff(2)%end, & + idwbuff(3)%beg:idwbuff(3)%end)) @:ACC_SETUP_SFs(q_beta(i)) + @:ALLOCATE(kahan_comp(i)%sf(idwbuff(1)%beg:idwbuff(1)%end, & + idwbuff(2)%beg:idwbuff(2)%end, & + idwbuff(3)%beg:idwbuff(3)%end)) + @:ACC_SETUP_SFs(kahan_comp(i)) end do ! Allocating space for lagrangian variables nBubs_glb = lag_params%nBubs_glb - @:ALLOCATE(lag_id(1:nBubs_glb, 1:2)) @:ALLOCATE(bub_R0(1:nBubs_glb)) @:ALLOCATE(Rmax_stats(1:nBubs_glb)) @:ALLOCATE(Rmin_stats(1:nBubs_glb)) @@ -114,6 +159,7 @@ contains @:ALLOCATE(gas_betaT(1:nBubs_glb)) @:ALLOCATE(gas_betaC(1:nBubs_glb)) @:ALLOCATE(bub_dphidt(1:nBubs_glb)) + @:ALLOCATE(lag_id(1:nBubs_glb, 1:2)) @:ALLOCATE(gas_p(1:nBubs_glb, 1:2)) @:ALLOCATE(gas_mv(1:nBubs_glb, 1:2)) @:ALLOCATE(intfc_rad(1:nBubs_glb, 1:2)) @@ -129,25 +175,77 @@ contains @:ALLOCATE(mtn_dposdt(1:nBubs_glb, 1:3, 1:lag_num_ts)) @:ALLOCATE(mtn_dveldt(1:nBubs_glb, 1:3, 1:lag_num_ts)) + @:ALLOCATE(keep_bubble(1:nBubs_glb)) + @:ALLOCATE(wrap_bubble_loc(1:nBubs_glb, 1:num_dims), wrap_bubble_dir(1:nBubs_glb, 1:num_dims)) + if (adap_dt .and. f_is_default(adap_dt_tol)) adap_dt_tol = dflt_adap_dt_tol + if (num_procs > 1) call s_initialize_particles_mpi(lag_num_ts) + ! Starting bubbles - call s_read_input_bubbles(q_cons_vf) + if (lag_params%write_void_evol) call s_open_void_evol + if (lag_params%write_bubbles) call s_open_lag_bubble_evol() + if (lag_params%write_bubbles_stats) call s_open_lag_bubble_stats() + + if (lag_params%vel_model > 0) then + moving_lag_bubbles = .true. + lag_pressure_force = lag_params%pressure_force + lag_gravity_force = lag_params%gravity_force + lag_vel_model = lag_params%vel_model + lag_drag_model = lag_params%drag_model + end if + $:GPU_UPDATE(device='[moving_lag_bubbles, lag_pressure_force, & + & lag_gravity_force, lag_vel_model, lag_drag_model]') + + ! Allocate cell-centered pressure gradient arrays and FD coefficients + if (lag_params%vel_model > 0 .and. lag_params%pressure_force) then + @:ALLOCATE(grad_p_x(0:m, 0:n, 0:p)) + @:ALLOCATE(fd_coeff_x_pgrad(-fd_number:fd_number, 0:m)) + call s_compute_finite_difference_coefficients(m, x_cc, fd_coeff_x_pgrad, & + buff_size, fd_number, fd_order) + $:GPU_UPDATE(device='[fd_coeff_x_pgrad]') + if (n > 0) then + @:ALLOCATE(grad_p_y(0:m, 0:n, 0:p)) + @:ALLOCATE(fd_coeff_y_pgrad(-fd_number:fd_number, 0:n)) + call s_compute_finite_difference_coefficients(n, y_cc, fd_coeff_y_pgrad, & + buff_size, fd_number, fd_order) + $:GPU_UPDATE(device='[fd_coeff_y_pgrad]') + end if + if (p > 0) then + @:ALLOCATE(grad_p_z(0:m, 0:n, 0:p)) + @:ALLOCATE(fd_coeff_z_pgrad(-fd_number:fd_number, 0:p)) + call s_compute_finite_difference_coefficients(p, z_cc, fd_coeff_z_pgrad, & + buff_size, fd_number, fd_order) + $:GPU_UPDATE(device='[fd_coeff_z_pgrad]') + end if + end if + + ! Allocate cell list arrays for atomic-free Gaussian smearing + @:ALLOCATE(cell_list_start(0:m, 0:n, 0:p)) + @:ALLOCATE(cell_list_count(0:m, 0:n, 0:p)) + @:ALLOCATE(cell_list_idx(1:lag_params%nBubs_glb)) + + call s_read_input_bubbles(q_cons_vf, bc_type) end subroutine s_initialize_bubbles_EL_module - !> Read initial bubble data from input files - impure subroutine s_read_input_bubbles(q_cons_vf) + !> The purpose of this procedure is to obtain the initial bubbles' information + !! @param q_cons_vf Conservative variables + impure subroutine s_read_input_bubbles(q_cons_vf, bc_type) type(scalar_field), dimension(sys_size), intent(inout) :: q_cons_vf - real(wp), dimension(8) :: inputBubble - real(wp) :: qtime - integer :: id, bub_id, save_count - integer :: i, ios - logical :: file_exist, indomain - character(LEN=path_len + 2*name_len) :: path_D_dir - ! Initialize number of particles + type(integer_field), dimension(1:num_dims, 1:2), intent(in) :: bc_type + + real(wp), dimension(8) :: inputBubble + real(wp) :: qtime + integer :: id, bub_id, save_count + integer :: i, ios + logical :: file_exist, indomain + integer, dimension(3) :: cell + + character(LEN=path_len + 2*name_len) :: path_D_dir !< + ! Initialize number of particles bub_id = 0 id = 0 @@ -162,9 +260,9 @@ contains if (save_count == 0) then if (proc_rank == 0) print *, 'Reading lagrange bubbles input file.' - inquire (file='input/lag_bubbles.dat', exist=file_exist) + call my_inquire(trim(lag_params%input_path), file_exist) if (file_exist) then - open (94, file='input/lag_bubbles.dat', form='formatted', iostat=ios) + open (94, file=trim(lag_params%input_path), form='formatted', iostat=ios) do while (ios == 0) read (94, *, iostat=ios) (inputBubble(i), i=1, 8) if (ios /= 0) cycle @@ -176,14 +274,14 @@ contains if (indomain) then bub_id = bub_id + 1 call s_add_bubbles(inputBubble, q_cons_vf, bub_id) - lag_id(bub_id, 1) = id ! global ID - lag_id(bub_id, 2) = bub_id ! local ID - nBubs = bub_id ! local number of bubbles + lag_id(bub_id, 1) = id !global ID + lag_id(bub_id, 2) = bub_id !local ID + n_el_bubs_loc = bub_id ! local number of bubbles end if end do close (94) else - call s_mpi_abort("Initialize the lagrange bubbles in input/lag_bubbles.dat") + call s_mpi_abort("Initialize the lagrange bubbles in "//trim(lag_params%input_path)) end if else if (proc_rank == 0) print *, 'Restarting lagrange bubbles at save_count: ', save_count @@ -192,47 +290,66 @@ contains print *, " Lagrange bubbles running, in proc", proc_rank, "number:", bub_id, "/", id + if (num_procs > 1) then + call s_mpi_reduce_int_sum(n_el_bubs_loc, n_el_bubs_glb) + else + n_el_bubs_glb = n_el_bubs_loc + end if + + if (proc_rank == 0) then + if (n_el_bubs_glb == 0) call s_mpi_abort('No bubbles in the domain. Check '//trim(lag_params%input_path)) + end if + $:GPU_UPDATE(device='[bubbles_lagrange, lag_params]') - $:GPU_UPDATE(device='[lag_id, bub_R0, Rmax_stats, Rmin_stats, gas_mg, gas_betaT, gas_betaC, bub_dphidt, gas_p, gas_mv, & - & intfc_rad, intfc_vel, mtn_pos, mtn_posPrev, mtn_vel, mtn_s, intfc_draddt, intfc_dveldt, gas_dpdt, & - & gas_dmvdt, mtn_dposdt, mtn_dveldt, nBubs]') + $:GPU_UPDATE(device='[lag_id,bub_R0,Rmax_stats,Rmin_stats,gas_mg, & + & gas_betaT,gas_betaC,bub_dphidt,gas_p,gas_mv, & + & intfc_rad,intfc_vel,mtn_pos,mtn_posPrev,mtn_vel, & + & mtn_s,intfc_draddt,intfc_dveldt,gas_dpdt,gas_dmvdt, & + & mtn_dposdt,mtn_dveldt,n_el_bubs_loc]') Rmax_glb = min(dflt_real, -dflt_real) Rmin_glb = max(dflt_real, -dflt_real) $:GPU_UPDATE(device='[Rmax_glb, Rmin_glb]') - $:GPU_UPDATE(device='[dx, dy, dz, x_cb, x_cc, y_cb, y_cc, z_cb, z_cc]') + $:GPU_UPDATE(device='[dx,dy,dz,x_cb,x_cc,y_cb,y_cc,z_cb,z_cc]') - ! Populate temporal variables + !Populate temporal variables call s_transfer_data_to_tmp() - call s_smear_voidfraction() - - if (lag_params%write_bubbles) call s_write_lag_particles(qtime) + call s_smear_voidfraction(bc_type) if (save_count == 0) then ! Create ./D directory - write (path_D_dir, '(A,I0,A,I0)') trim(case_dir) // '/D' - call my_inquire(path_D_dir, file_exist) - if (.not. file_exist) call s_create_directory(trim(path_D_dir)) - call s_write_restart_lag_bubbles(save_count) ! Needed for post_processing - call s_write_void_evol(qtime) + if (proc_rank == 0) then + write (path_D_dir, '(A,I0,A,I0)') trim(case_dir)//'/D' + call my_inquire(trim(path_D_dir), file_exist) + if (.not. file_exist) call s_create_directory(trim(path_D_dir)) + end if + call s_mpi_barrier() + call s_write_restart_lag_bubbles(save_count) ! Needed for post_processing + if (lag_params%write_void_evol) call s_write_void_evol(qtime) end if + if (lag_params%write_bubbles) call s_write_lag_bubble_evol(qtime) + end subroutine s_read_input_bubbles - !> Add a new bubble from input data for a fresh start + !> The purpose of this procedure is to obtain the information of the bubbles when starting fresh + !! @param inputBubble Bubble information + !! @param q_cons_vf Conservative variables + !! @param bub_id Local id of the bubble impure subroutine s_add_bubbles(inputBubble, q_cons_vf, bub_id) type(scalar_field), dimension(sys_size), intent(in) :: q_cons_vf - real(wp), dimension(8), intent(in) :: inputBubble - integer, intent(in) :: bub_id - integer :: i - real(wp) :: pliq, volparticle, concvap, totalmass, kparticle, cpparticle - real(wp) :: omegaN_local, PeG, PeT, rhol, pcrit, qv, gamma, pi_inf, dynP - integer, dimension(3) :: cell - real(wp), dimension(2) :: Re - real(wp) :: massflag, heatflag, Re_trans, Im_trans + real(wp), dimension(8), intent(in) :: inputBubble + integer, intent(in) :: bub_id + integer :: i + + real(wp) :: pliq, volparticle, concvap, totalmass, kparticle, cpparticle + real(wp) :: omegaN_local, PeG, PeT, rhol, pcrit, qv, gamma, pi_inf, dynP + integer, dimension(3) :: cell + real(wp), dimension(2) :: Re + real(wp) :: massflag, heatflag, Re_trans, Im_trans massflag = 0._wp heatflag = 0._wp @@ -245,45 +362,45 @@ contains bub_dphidt(bub_id) = 0._wp intfc_rad(bub_id, 1) = inputBubble(7) intfc_vel(bub_id, 1) = inputBubble(8) - mtn_pos(bub_id,1:3,1) = inputBubble(1:3) - mtn_posPrev(bub_id,1:3,1) = mtn_pos(bub_id,1:3,1) - mtn_vel(bub_id,1:3,1) = inputBubble(4:6) + mtn_pos(bub_id, 1:3, 1) = inputBubble(1:3) + mtn_posPrev(bub_id, 1:3, 1) = mtn_pos(bub_id, 1:3, 1) + mtn_vel(bub_id, 1:3, 1) = inputBubble(4:6) if (cyl_coord .and. p == 0) then - mtn_pos(bub_id, 2, 1) = sqrt(mtn_pos(bub_id, 2, 1)**2._wp + mtn_pos(bub_id, 3, 1)**2._wp) - ! Storing azimuthal angle (-Pi to Pi)) into the third coordinate variable + mtn_pos(bub_id, 2, 1) = sqrt(mtn_pos(bub_id, 2, 1)**2._wp + & + mtn_pos(bub_id, 3, 1)**2._wp) + !Storing azimuthal angle (-Pi to Pi)) into the third coordinate variable mtn_pos(bub_id, 3, 1) = atan2(inputBubble(3), inputBubble(2)) - mtn_posPrev(bub_id,1:3,1) = mtn_pos(bub_id,1:3,1) + mtn_posPrev(bub_id, 1:3, 1) = mtn_pos(bub_id, 1:3, 1) end if - cell = -buff_size - call s_locate_cell(mtn_pos(bub_id,1:3,1), cell, mtn_s(bub_id,1:3,1)) + cell = fd_number - buff_size + call s_locate_cell(mtn_pos(bub_id, 1:3, 1), cell, mtn_s(bub_id, 1:3, 1)) ! Check if the bubble is located in the ghost cell of a symmetric, or wall boundary - if ((any(bc_x%beg == (/BC_REFLECTIVE, BC_CHAR_SLIP_WALL, BC_SLIP_WALL, & - & BC_NO_SLIP_WALL/)) .and. cell(1) < 0) .or. (any(bc_x%end == (/BC_REFLECTIVE, BC_CHAR_SLIP_WALL, BC_SLIP_WALL, & - & BC_NO_SLIP_WALL/)) .and. cell(1) > m) .or. (any(bc_y%beg == (/BC_REFLECTIVE, BC_CHAR_SLIP_WALL, BC_SLIP_WALL, & - & BC_NO_SLIP_WALL/)) .and. cell(2) < 0) .or. (any(bc_y%end == (/BC_REFLECTIVE, BC_CHAR_SLIP_WALL, BC_SLIP_WALL, & - & BC_NO_SLIP_WALL/)) .and. cell(2) > n)) then + if ((any(bc_x%beg == (/BC_REFLECTIVE, BC_CHAR_SLIP_WALL, BC_SLIP_WALL, BC_NO_SLIP_WALL/)) .and. cell(1) < 0) .or. & + (any(bc_x%end == (/BC_REFLECTIVE, BC_CHAR_SLIP_WALL, BC_SLIP_WALL, BC_NO_SLIP_WALL/)) .and. cell(1) > m) .or. & + (any(bc_y%beg == (/BC_REFLECTIVE, BC_CHAR_SLIP_WALL, BC_SLIP_WALL, BC_NO_SLIP_WALL/)) .and. cell(2) < 0) .or. & + (any(bc_y%end == (/BC_REFLECTIVE, BC_CHAR_SLIP_WALL, BC_SLIP_WALL, BC_NO_SLIP_WALL/)) .and. cell(2) > n)) then call s_mpi_abort("Lagrange bubble is in the ghost cells of a symmetric or wall boundary.") end if if (p > 0) then - if ((any(bc_z%beg == (/BC_REFLECTIVE, BC_CHAR_SLIP_WALL, BC_SLIP_WALL, & - & BC_NO_SLIP_WALL/)) .and. cell(3) < 0) .or. (any(bc_z%end == (/BC_REFLECTIVE, BC_CHAR_SLIP_WALL, BC_SLIP_WALL, & - & BC_NO_SLIP_WALL/)) .and. cell(3) > p)) then + if ((any(bc_z%beg == (/BC_REFLECTIVE, BC_CHAR_SLIP_WALL, BC_SLIP_WALL, BC_NO_SLIP_WALL/)) .and. cell(3) < 0) .or. & + (any(bc_z%end == (/BC_REFLECTIVE, BC_CHAR_SLIP_WALL, BC_SLIP_WALL, BC_NO_SLIP_WALL/)) .and. cell(3) > p)) then call s_mpi_abort("Lagrange bubble is in the ghost cells of a symmetric or wall boundary.") end if end if - call s_convert_to_mixture_variables(q_cons_vf, cell(1), cell(2), cell(3), rhol, gamma, pi_inf, qv, Re) + call s_convert_to_mixture_variables(q_cons_vf, cell(1), cell(2), cell(3), & + rhol, gamma, pi_inf, qv, Re) dynP = 0._wp do i = 1, num_dims dynP = dynP + 0.5_wp*q_cons_vf(contxe + i)%sf(cell(1), cell(2), cell(3))**2/rhol end do pliq = (q_cons_vf(E_idx)%sf(cell(1), cell(2), cell(3)) - dynP - pi_inf)/gamma - if (pliq < 0) print *, "Negative pressure", proc_rank, q_cons_vf(E_idx)%sf(cell(1), cell(2), cell(3)), pi_inf, gamma, & - & pliq, cell, dynP + if (pliq < 0) print *, "Negative pressure", proc_rank, & + q_cons_vf(E_idx)%sf(cell(1), cell(2), cell(3)), pi_inf, gamma, pliq, cell, dynP ! Initial particle pressure gas_p(bub_id, 1) = pliq + 2._wp*(1._wp/Web)/bub_R0(bub_id) @@ -295,13 +412,13 @@ contains end if ! Initial particle mass - volparticle = 4._wp/3._wp*pi*bub_R0(bub_id)**3._wp ! volume - gas_mv(bub_id, 1) = pv*volparticle*(1._wp/(R_v*Tw))*(massflag) ! vapermass - gas_mg(bub_id) = (gas_p(bub_id, 1) - pv*(massflag))*volparticle*(1._wp/(R_g*Tw)) ! gasmass + volparticle = 4._wp/3._wp*pi*bub_R0(bub_id)**3._wp ! volume + gas_mv(bub_id, 1) = pv*volparticle*(1._wp/(R_v*Tw))*(massflag) ! vapermass + gas_mg(bub_id) = (gas_p(bub_id, 1) - pv*(massflag))*volparticle*(1._wp/(R_g*Tw)) ! gasmass if (gas_mg(bub_id) <= 0._wp) then call s_mpi_abort("The initial mass of gas inside the bubble is negative. Check the initial conditions.") end if - totalmass = gas_mg(bub_id) + gas_mv(bub_id, 1) ! totalmass + totalmass = gas_mg(bub_id) + gas_mv(bub_id, 1) ! totalmass ! Bubble natural frequency concvap = gas_mv(bub_id, 1)/(gas_mv(bub_id, 1) + gas_mg(bub_id)) @@ -329,43 +446,49 @@ contains end subroutine s_add_bubbles - !> Restore bubble data from a restart file + !> The purpose of this procedure is to obtain the information of the bubbles from a restart point. + !! @param bub_id Local ID of the particle + !! @param save_count File identifier impure subroutine s_restart_bubbles(bub_id, save_count) - integer, intent(inout) :: bub_id, save_count + integer, intent(inout) :: bub_id, save_count + character(LEN=path_len + 2*name_len) :: file_loc - real(wp) :: file_time, file_dt - integer :: file_num_procs, file_tot_part, tot_part + real(wp) :: file_time, file_dt + integer :: file_num_procs, file_tot_part, tot_part #ifdef MFC_MPI - real(wp), dimension(20) :: inputvals - integer, dimension(MPI_STATUS_SIZE) :: status - integer(kind=MPI_OFFSET_KIND) :: disp - integer :: view - integer, dimension(3) :: cell - logical :: indomain, particle_file, file_exist - integer, dimension(2) :: gsizes, lsizes, start_idx_part - integer :: ifile, ierr, tot_data, id - integer :: i - integer, dimension(:), allocatable :: proc_bubble_counts - real(wp), dimension(1:1,1:lag_io_vars) :: dummy + real(wp), dimension(20) :: inputvals + integer, dimension(MPI_STATUS_SIZE) :: status + integer(kind=MPI_OFFSET_KIND) :: disp + integer :: view + + integer, dimension(3) :: cell + logical :: indomain, particle_file, file_exist + integer, dimension(2) :: gsizes, lsizes, start_idx_part + integer :: ifile, ierr, tot_data, id + integer :: i + + integer, dimension(:), allocatable :: proc_bubble_counts + real(wp), dimension(1:1, 1:lag_io_vars) :: dummy dummy = 0._wp ! Construct file path write (file_loc, '(A,I0,A)') 'lag_bubbles_', save_count, '.dat' - file_loc = trim(case_dir) // '/restart_data' // trim(mpiiofs) // trim(file_loc) + file_loc = trim(case_dir)//'/restart_data'//trim(mpiiofs)//trim(file_loc) ! Check if file exists inquire (FILE=trim(file_loc), EXIST=file_exist) if (.not. file_exist) then - call s_mpi_abort('Restart file ' // trim(file_loc) // ' does not exist!') + call s_mpi_abort('Restart file '//trim(file_loc)//' does not exist!') end if if (.not. parallel_io) return if (proc_rank == 0) then - call MPI_FILE_OPEN(MPI_COMM_SELF, file_loc, MPI_MODE_RDONLY, mpi_info_int, ifile, ierr) + call MPI_FILE_OPEN(MPI_COMM_SELF, file_loc, MPI_MODE_RDONLY, & + mpi_info_int, ifile, ierr) call MPI_FILE_READ(ifile, file_tot_part, 1, MPI_INTEGER, status, ierr) call MPI_FILE_READ(ifile, file_time, 1, mpi_p, status, ierr) @@ -383,10 +506,12 @@ contains allocate (proc_bubble_counts(file_num_procs)) if (proc_rank == 0) then - call MPI_FILE_OPEN(MPI_COMM_SELF, file_loc, MPI_MODE_RDONLY, mpi_info_int, ifile, ierr) + call MPI_FILE_OPEN(MPI_COMM_SELF, file_loc, MPI_MODE_RDONLY, & + mpi_info_int, ifile, ierr) ! Skip to processor counts position - disp = int(sizeof(file_tot_part) + 2*sizeof(file_time) + sizeof(file_num_procs), MPI_OFFSET_KIND) + disp = int(sizeof(file_tot_part) + 2*sizeof(file_time) + sizeof(file_num_procs), & + MPI_OFFSET_KIND) call MPI_FILE_SEEK(ifile, disp, MPI_SEEK_SET, ierr) call MPI_FILE_READ(ifile, proc_bubble_counts, file_num_procs, MPI_INTEGER, status, ierr) @@ -414,30 +539,34 @@ contains gsizes(2) = lag_io_vars if (bub_id > 0) then - allocate (MPI_IO_DATA_lag_bubbles(bub_id,1:lag_io_vars)) - call MPI_TYPE_CREATE_SUBARRAY(2, gsizes, lsizes, start_idx_part, MPI_ORDER_FORTRAN, mpi_p, view, ierr) + allocate (MPI_IO_DATA_lag_bubbles(bub_id, 1:lag_io_vars)) + + call MPI_TYPE_CREATE_SUBARRAY(2, gsizes, lsizes, start_idx_part, & + MPI_ORDER_FORTRAN, mpi_p, view, ierr) call MPI_TYPE_COMMIT(view, ierr) - call MPI_FILE_OPEN(MPI_COMM_WORLD, file_loc, MPI_MODE_RDONLY, mpi_info_int, ifile, ierr) + call MPI_FILE_OPEN(MPI_COMM_WORLD, file_loc, MPI_MODE_RDONLY, & + mpi_info_int, ifile, ierr) ! Skip extended header - disp = int(sizeof(file_tot_part) + 2*sizeof(file_time) + sizeof(file_num_procs) & - & + file_num_procs*sizeof(proc_bubble_counts(1)), MPI_OFFSET_KIND) + disp = int(sizeof(file_tot_part) + 2*sizeof(file_time) + sizeof(file_num_procs) + & + file_num_procs*sizeof(proc_bubble_counts(1)), MPI_OFFSET_KIND) call MPI_FILE_SET_VIEW(ifile, disp, mpi_p, view, 'native', mpi_info_int, ierr) - call MPI_FILE_READ_ALL(ifile, MPI_IO_DATA_lag_bubbles, lag_io_vars*bub_id, mpi_p, status, ierr) + call MPI_FILE_READ_ALL(ifile, MPI_IO_DATA_lag_bubbles, & + lag_io_vars*bub_id, mpi_p, status, ierr) call MPI_FILE_CLOSE(ifile, ierr) call MPI_TYPE_FREE(view, ierr) - nBubs = bub_id + n_el_bubs_loc = bub_id do i = 1, bub_id lag_id(i, 1) = int(MPI_IO_DATA_lag_bubbles(i, 1)) - mtn_pos(i,1:3,1) = MPI_IO_DATA_lag_bubbles(i,2:4) - mtn_posPrev(i,1:3,1) = MPI_IO_DATA_lag_bubbles(i,5:7) - mtn_vel(i,1:3,1) = MPI_IO_DATA_lag_bubbles(i,8:10) + mtn_pos(i, 1:3, 1) = MPI_IO_DATA_lag_bubbles(i, 2:4) + mtn_posPrev(i, 1:3, 1) = MPI_IO_DATA_lag_bubbles(i, 5:7) + mtn_vel(i, 1:3, 1) = MPI_IO_DATA_lag_bubbles(i, 8:10) intfc_rad(i, 1) = MPI_IO_DATA_lag_bubbles(i, 11) intfc_vel(i, 1) = MPI_IO_DATA_lag_bubbles(i, 12) bub_R0(i) = MPI_IO_DATA_lag_bubbles(i, 13) @@ -450,21 +579,23 @@ contains gas_betaT(i) = MPI_IO_DATA_lag_bubbles(i, 20) gas_betaC(i) = MPI_IO_DATA_lag_bubbles(i, 21) cell = -buff_size - call s_locate_cell(mtn_pos(i,1:3,1), cell, mtn_s(i,1:3,1)) + call s_locate_cell(mtn_pos(i, 1:3, 1), cell, mtn_s(i, 1:3, 1)) end do deallocate (MPI_IO_DATA_lag_bubbles) + else - nBubs = 0 + n_el_bubs_loc = 0 call MPI_TYPE_CONTIGUOUS(0, mpi_p, view, ierr) call MPI_TYPE_COMMIT(view, ierr) - call MPI_FILE_OPEN(MPI_COMM_WORLD, file_loc, MPI_MODE_RDONLY, mpi_info_int, ifile, ierr) + call MPI_FILE_OPEN(MPI_COMM_WORLD, file_loc, MPI_MODE_RDONLY, & + mpi_info_int, ifile, ierr) ! Skip extended header - disp = int(sizeof(file_tot_part) + 2*sizeof(file_time) + sizeof(file_num_procs) & - & + file_num_procs*sizeof(proc_bubble_counts(1)), MPI_OFFSET_KIND) + disp = int(sizeof(file_tot_part) + 2*sizeof(file_time) + sizeof(file_num_procs) + & + file_num_procs*sizeof(proc_bubble_counts(1)), MPI_OFFSET_KIND) call MPI_FILE_SET_VIEW(ifile, disp, mpi_p, view, 'native', mpi_info_int, ierr) call MPI_FILE_READ_ALL(ifile, dummy, 0, mpi_p, status, ierr) @@ -483,18 +614,22 @@ contains end subroutine s_restart_bubbles - !> Contains the bubble dynamics subroutines. - subroutine s_compute_bubble_EL_dynamics(q_prim_vf, stage) + !> Contains the bubble dynamics subroutines. + !! @param q_prim_vf Primitive variables + !! @param stage Current stage in the time-stepper algorithm + subroutine s_compute_bubble_EL_dynamics(q_prim_vf, bc_type, stage) type(scalar_field), dimension(sys_size), intent(inout) :: q_prim_vf - integer, intent(in) :: stage - real(wp) :: myVapFlux - real(wp) :: preterm1, term2, paux, pint, Romega, term1_fac - real(wp) :: myR_m, mygamma_m, myPb, myMass_n, myMass_v - real(wp) :: myR, myV, myBeta_c, myBeta_t, myR0, myPbdot, myMvdot - real(wp) :: myPinf, aux1, aux2, myCson, myRho - real(wp) :: gamma, pi_inf, qv + type(integer_field), dimension(1:num_dims, 1:2), intent(in) :: bc_type + integer, intent(in) :: stage + real(wp) :: myVapFlux + real(wp) :: preterm1, term2, paux, pint, Romega, term1_fac + real(wp) :: myR_m, mygamma_m, myPb, myMass_n, myMass_v + real(wp) :: myR, myV, myBeta_c, myBeta_t, myR0, myPbdot, myMvdot + real(wp) :: myPinf, aux1, aux2, myCson, myRho + real(wp), dimension(3) :: myPos, myVel + real(wp) :: gamma, pi_inf, qv, f_b, myRe #:if not MFC_CASE_OPTIMIZATION and USING_AMD real(wp), dimension(3) :: myalpha_rho, myalpha #:else @@ -502,17 +637,18 @@ contains #:endif real(wp), dimension(2) :: Re integer, dimension(3) :: cell - integer :: adap_dt_stop_max, adap_dt_stop !< Fail-safe exit if max iteration count reached - real(wp) :: dmalf, dmntait, dmBtait, dm_bub_adv_src, dm_divu !< Dummy variables for unified subgrid bubble subroutines - integer :: i, k, l - call nvtxStartRange("LAGRANGE-BUBBLE-DYNAMICS") + integer :: adap_dt_stop_sum, adap_dt_stop !< Fail-safe exit if max iteration count reached + real(wp) :: dmalf, dmntait, dmBtait, dm_bub_adv_src, dm_divu !< Dummy variables for unified subgrid bubble subroutines + + integer :: k, l ! Subgrid p_inf model based on Maeda and Colonius (2018). if (lag_params%pressure_corrector) then + call nvtxStartRange("LAGRANGE-BUBBLE-PINF-CORRECTION") ! Calculate velocity potentials (valid for one bubble per cell) - $:GPU_PARALLEL_LOOP(private='[k, cell, paux, preterm1, term2, Romega, myR0, myR, myV, myPb, pint, term1_fac]') - do k = 1, nBubs + $:GPU_PARALLEL_LOOP(private='[k,cell,paux,preterm1,term2,Romega,myR0,myR,myV,myPb,pint,term1_fac]') + do k = 1, n_el_bubs_loc call s_get_pinf(k, q_prim_vf, 2, paux, cell, preterm1, term2, Romega) myR0 = bub_R0(k) myR = intfc_rad(k, 2) @@ -522,23 +658,29 @@ contains pint = pint + 0.5_wp*myV**2._wp if (lag_params%cluster_type == 2) then bub_dphidt(k) = (paux - pint) + term2 - ! Accounting for the potential induced by the bubble averaged over the control volume Note that this is based on - ! the incompressible flow assumption near the bubble. + ! Accounting for the potential induced by the bubble averaged over the control volume + ! Note that this is based on the incompressible flow assumption near the bubble. term1_fac = 3._wp/2._wp*(myR*(Romega**2._wp - myR**2._wp))/(Romega**3._wp - myR**3._wp) bub_dphidt(k) = bub_dphidt(k)/(1._wp - term1_fac) end if end do $:END_GPU_PARALLEL_LOOP() + call nvtxEndRange() + end if + + ! Precompute cell-centered pressure gradients for translational motion + if (moving_lag_bubbles .and. lag_pressure_force) then + call nvtxStartRange("LAGRANGE-BUBBLE-PRESSURE-GRADIENT") + call s_compute_pressure_gradients(q_prim_vf) + call nvtxEndRange() end if + call nvtxStartRange("LAGRANGE-BUBBLE-DYNAMICS") ! Radial motion model - adap_dt_stop_max = 0 - $:GPU_PARALLEL_LOOP(private='[k, i, myalpha_rho, myalpha, Re, cell, myVapFlux, preterm1, term2, paux, pint, Romega, & - & term1_fac, myR_m, mygamma_m, myPb, myMass_n, myMass_v, myR, myV, myBeta_c, myBeta_t, myR0, myPbdot, & - & myMvdot, myPinf, aux1, aux2, myCson, myRho, gamma, pi_inf, qv, dmalf, dmntait, dmBtait, & - & dm_bub_adv_src, dm_divu, adap_dt_stop]', reduction='[[adap_dt_stop_max]]',reductionOp='[MAX]', & - & copy = '[adap_dt_stop_max]', copyin = '[stage]') - do k = 1, nBubs + adap_dt_stop_sum = 0 + $:GPU_PARALLEL_LOOP(private='[k,myalpha_rho,myalpha,Re,cell,myVapFlux,preterm1, term2, paux, pint, Romega,term1_fac,myR_m, mygamma_m, myPb, myMass_n, myMass_v,myR, myV, myBeta_c, myBeta_t, myR0, myPbdot, myMvdot,myPinf, aux1,aux2, myCson, myRho,gamma,pi_inf,qv,dmalf, dmntait, dmBtait, dm_bub_adv_src, dm_divu,adap_dt_stop,myPos,myVel]', & + & copy='[adap_dt_stop_sum]',copyin='[stage]') + do k = 1, n_el_bubs_loc ! Keller-Miksis model ! Current bubble state @@ -550,6 +692,8 @@ contains myBeta_c = gas_betaC(k) myBeta_t = gas_betaT(k) myR0 = bub_R0(k) + myPos = mtn_pos(k, :, 2) + myVel = mtn_vel(k, :, 2) ! Vapor and heat fluxes call s_vflux(myR, myV, myPb, myMass_v, k, myVapFlux, myMass_n, myBeta_c, myR_m, mygamma_m) @@ -561,152 +705,208 @@ contains ! Obtain liquid density and computing speed of sound from pinf call s_compute_species_fraction(q_prim_vf, cell(1), cell(2), cell(3), myalpha_rho, myalpha) - call s_convert_species_to_mixture_variables_acc(myRho, gamma, pi_inf, qv, myalpha, myalpha_rho, Re) + call s_convert_species_to_mixture_variables_acc(myRho, gamma, pi_inf, qv, myalpha, & + myalpha_rho, Re) call s_compute_cson_from_pinf(q_prim_vf, myPinf, cell, myRho, gamma, pi_inf, myCson) ! Adaptive time stepping adap_dt_stop = 0 if (adap_dt) then - call s_advance_step(myRho, myPinf, myR, myV, myR0, myPb, myPbdot, dmalf, dmntait, dmBtait, dm_bub_adv_src, & - & dm_divu, k, myMass_v, myMass_n, myBeta_c, myBeta_t, myCson, adap_dt_stop) + + mtn_posPrev(k, :, 1) = myPos + + myRe = Re(1) + adap_dt_stop = f_advance_step(myRho, myPinf, myR, myV, myR0, myPb, myPbdot, dmalf, & + dmntait, dmBtait, dm_bub_adv_src, dm_divu, & + k, myMass_v, myMass_n, myBeta_c, & + myBeta_t, myCson, myRe, & + myPos, myVel, cell, q_prim_vf) ! Update bubble state intfc_rad(k, 1) = myR intfc_vel(k, 1) = myV gas_p(k, 1) = myPb gas_mv(k, 1) = myMass_v + mtn_pos(k, :, 1) = myPos + mtn_vel(k, :, 1) = myVel + else ! Radial acceleration from bubble models - intfc_dveldt(k, stage) = f_rddot(myRho, myPinf, myR, myV, myR0, myPb, myPbdot, dmalf, dmntait, dmBtait, & - & dm_bub_adv_src, dm_divu, myCson) + intfc_dveldt(k, stage) = f_rddot(myRho, myPinf, myR, myV, myR0, & + myPb, myPbdot, dmalf, dmntait, dmBtait, & + dm_bub_adv_src, dm_divu, & + myCson) + intfc_draddt(k, stage) = myV gas_dmvdt(k, stage) = myMvdot gas_dpdt(k, stage) = myPbdot - end if - adap_dt_stop_max = max(adap_dt_stop_max, adap_dt_stop) - end do - $:END_GPU_PARALLEL_LOOP() + if (moving_lag_bubbles) then + do l = 1, num_dims + select case (lag_vel_model) + case (1) + mtn_dposdt(k, l, stage) = f_interpolate_velocity(myPos(l), & + cell, l, q_prim_vf) + mtn_dveldt(k, l, stage) = 0._wp + case (2) + mtn_dposdt(k, l, stage) = myVel(l) + f_b = f_get_bubble_force(myPos(l), & + myR, myV, myVel(l), & + myMass_n, myMass_v, & + Re(1), myRho, cell, l, q_prim_vf) + mtn_dveldt(k, l, stage) = f_b/(myMass_n + myMass_v) + case (3) + mtn_dposdt(k, l, stage) = myVel(l) + f_b = f_get_bubble_force(myPos(l), & + myR, myV, myVel(l), & + myMass_n, myMass_v, & + Re(1), myRho, cell, l, q_prim_vf) + mtn_dveldt(k, l, stage) = 2._wp*f_b/(myMass_n + myMass_v) - 3._wp*myV*myVel(l)/myR + case default + mtn_dposdt(k, l, stage) = 0._wp + mtn_dveldt(k, l, stage) = 0._wp + end select + end do + end if + end if - if (adap_dt .and. adap_dt_stop_max > 0) call s_mpi_abort("Adaptive time stepping failed to converge.") + $:GPU_ATOMIC(atomic='update') + adap_dt_stop_sum = adap_dt_stop_sum + adap_dt_stop - ! Bubbles remain in a fixed position - $:GPU_PARALLEL_LOOP(collapse=2, private='[k, l]', copyin='[stage]') - do k = 1, nBubs - do l = 1, 3 - mtn_dposdt(k, l, stage) = 0._wp - mtn_dveldt(k, l, stage) = 0._wp - end do end do $:END_GPU_PARALLEL_LOOP() - call nvtxEndRange + if (adap_dt .and. adap_dt_stop_sum > 0) call s_mpi_abort("Adaptive time stepping failed to converge.") + + if (adap_dt) then + call s_transfer_data_to_tmp() + if (moving_lag_bubbles) call s_enforce_EL_bubbles_boundary_conditions(q_prim_vf) + call s_smear_voidfraction(bc_type) + end if + end subroutine s_compute_bubble_EL_dynamics - !> Compute the Lagrangian bubble source terms and add them to the RHS + !> The purpose of this subroutine is to obtain the bubble source terms based on Maeda and Colonius (2018) + !! and add them to the RHS scalar field. + !! @param q_cons_vf Conservative variables + !! @param q_prim_vf Conservative variables + !! @param rhs_vf Time derivative of the conservative variables subroutine s_compute_bubbles_EL_source(q_cons_vf, q_prim_vf, rhs_vf) type(scalar_field), dimension(sys_size), intent(inout) :: q_cons_vf type(scalar_field), dimension(sys_size), intent(inout) :: q_prim_vf type(scalar_field), dimension(sys_size), intent(inout) :: rhs_vf - integer :: i, j, k, l - if (.not. adap_dt) call s_smear_voidfraction() + integer :: i, j, k, l - if (lag_params%solver_approach == 2) then - ! (q / (1 - beta)) * d(beta)/dt source - if (p == 0) then - $:GPU_PARALLEL_LOOP(private='[i, j, k, l]', collapse=4) - do k = 0, p - do j = 0, n - do i = 0, m - do l = 1, E_idx - if (q_beta(1)%sf(i, j, k) > (1._wp - lag_params%valmaxvoid)) then - rhs_vf(l)%sf(i, j, k) = rhs_vf(l)%sf(i, j, k) + q_cons_vf(l)%sf(i, j, k)*(q_beta(2)%sf(i, j, & - & k) + q_beta(5)%sf(i, j, k)) - end if - end do + call nvtxStartRange("LAGRANGE-BUBBLE-EL-SOURCE") + ! (q / (1 - beta)) * d(beta)/dt source + if (lag_params%cluster_type >= 4) then + $:GPU_PARALLEL_LOOP(private='[i,j,k,l]', collapse=4) + do k = idwint(3)%beg, idwint(3)%end + do j = idwint(2)%beg, idwint(2)%end + do i = idwint(1)%beg, idwint(1)%end + do l = 1, E_idx + if (q_beta(1)%sf(i, j, k) > (1._wp - lag_params%valmaxvoid)) then + rhs_vf(l)%sf(i, j, k) = rhs_vf(l)%sf(i, j, k) + & + q_cons_vf(l)%sf(i, j, k)*(q_beta(2)%sf(i, j, k) + & + q_beta(5)%sf(i, j, k)) + end if end do end do end do - $:END_GPU_PARALLEL_LOOP() - else - $:GPU_PARALLEL_LOOP(private='[i, j, k, l]', collapse=4) - do k = 0, p - do j = 0, n - do i = 0, m - do l = 1, E_idx - if (q_beta(1)%sf(i, j, k) > (1._wp - lag_params%valmaxvoid)) then - rhs_vf(l)%sf(i, j, k) = rhs_vf(l)%sf(i, j, k) + q_cons_vf(l)%sf(i, j, k)/q_beta(1)%sf(i, j, & - & k)*q_beta(2)%sf(i, j, k) - end if - end do + end do + $:END_GPU_PARALLEL_LOOP() + else + $:GPU_PARALLEL_LOOP(private='[i,j,k,l]', collapse=4) + do k = idwint(3)%beg, idwint(3)%end + do j = idwint(2)%beg, idwint(2)%end + do i = idwint(1)%beg, idwint(1)%end + do l = 1, E_idx + if (q_beta(1)%sf(i, j, k) > (1._wp - lag_params%valmaxvoid)) then + rhs_vf(l)%sf(i, j, k) = rhs_vf(l)%sf(i, j, k) + & + (q_cons_vf(l)%sf(i, j, k)/q_beta(1)%sf(i, j, k))* & + q_beta(2)%sf(i, j, k) + end if end do end do end do - $:END_GPU_PARALLEL_LOOP() - end if + end do + $:END_GPU_PARALLEL_LOOP() + end if - do l = 1, num_dims - call s_gradient_dir(q_prim_vf(E_idx)%sf, q_beta(3)%sf, l) + do l = 1, num_dims - ! (q / (1 - beta)) * d(beta)/dt source - $:GPU_PARALLEL_LOOP(private='[i, j, k]', collapse=3) - do k = 0, p - do j = 0, n - do i = 0, m - if (q_beta(1)%sf(i, j, k) > (1._wp - lag_params%valmaxvoid)) then - rhs_vf(contxe + l)%sf(i, j, k) = rhs_vf(contxe + l)%sf(i, j, k) - (1._wp - q_beta(1)%sf(i, j, & - & k))/q_beta(1)%sf(i, j, k)*q_beta(3)%sf(i, j, k) - end if - end do + call s_gradient_dir(q_prim_vf(E_idx)%sf, q_beta(3)%sf, l) + + ! (q / (1 - beta)) * d(beta)/dt source + $:GPU_PARALLEL_LOOP(private='[i,j,k]', collapse=3) + do k = idwint(3)%beg, idwint(3)%end + do j = idwint(2)%beg, idwint(2)%end + do i = idwint(1)%beg, idwint(1)%end + if (q_beta(1)%sf(i, j, k) > (1._wp - lag_params%valmaxvoid)) then + rhs_vf(contxe + l)%sf(i, j, k) = rhs_vf(contxe + l)%sf(i, j, k) - & + (1._wp - q_beta(1)%sf(i, j, k))/ & + q_beta(1)%sf(i, j, k)* & + q_beta(3)%sf(i, j, k) + end if end do end do - $:END_GPU_PARALLEL_LOOP() + end do + $:END_GPU_PARALLEL_LOOP() - ! source in energy - $:GPU_PARALLEL_LOOP(private='[i, j, k]', collapse=3) - do k = idwbuff(3)%beg, idwbuff(3)%end - do j = idwbuff(2)%beg, idwbuff(2)%end - do i = idwbuff(1)%beg, idwbuff(1)%end - q_beta(3)%sf(i, j, k) = q_prim_vf(E_idx)%sf(i, j, k)*q_prim_vf(contxe + l)%sf(i, j, k) - end do + !source in energy + $:GPU_PARALLEL_LOOP(private='[i,j,k]', collapse=3) + do k = idwbuff(3)%beg, idwbuff(3)%end + do j = idwbuff(2)%beg, idwbuff(2)%end + do i = idwbuff(1)%beg, idwbuff(1)%end + q_beta(3)%sf(i, j, k) = q_prim_vf(E_idx)%sf(i, j, k)*q_prim_vf(contxe + l)%sf(i, j, k) end do end do - $:END_GPU_PARALLEL_LOOP() - - call s_gradient_dir(q_beta(3)%sf, q_beta(4)%sf, l) + end do + $:END_GPU_PARALLEL_LOOP() - ! (beta / (1 - beta)) * d(Pu)/dl source - $:GPU_PARALLEL_LOOP(private='[i, j, k]', collapse=3) - do k = 0, p - do j = 0, n - do i = 0, m - if (q_beta(1)%sf(i, j, k) > (1._wp - lag_params%valmaxvoid)) then - rhs_vf(E_idx)%sf(i, j, k) = rhs_vf(E_idx)%sf(i, j, k) - q_beta(4)%sf(i, j, & - & k)*(1._wp - q_beta(1)%sf(i, j, k))/q_beta(1)%sf(i, j, k) - end if - end do + call s_gradient_dir(q_beta(3)%sf, q_beta(4)%sf, l) + + ! (beta / (1 - beta)) * d(Pu)/dl source + $:GPU_PARALLEL_LOOP(private='[i,j,k]', collapse=3) + do k = idwint(3)%beg, idwint(3)%end + do j = idwint(2)%beg, idwint(2)%end + do i = idwint(1)%beg, idwint(1)%end + if (q_beta(1)%sf(i, j, k) > (1._wp - lag_params%valmaxvoid)) then + rhs_vf(E_idx)%sf(i, j, k) = rhs_vf(E_idx)%sf(i, j, k) - & + q_beta(4)%sf(i, j, k)*(1._wp - q_beta(1)%sf(i, j, k))/ & + q_beta(1)%sf(i, j, k) + end if end do end do - $:END_GPU_PARALLEL_LOOP() end do - end if + $:END_GPU_PARALLEL_LOOP() + end do + call nvtxEndRange ! LAGRANGE-BUBBLE-EL-SOURCE end subroutine s_compute_bubbles_EL_source - !> Compute the speed of sound from a given driving pressure + !> This procedure computes the speed of sound from a given driving pressure + !! @param q_prim_vf Primitive variables + !! @param pinf Driving pressure + !! @param cell Bubble cell + !! @param rhol Liquid density + !! @param gamma Liquid specific heat ratio + !! @param pi_inf Liquid stiffness + !! @param cson Calculated speed of sound subroutine s_compute_cson_from_pinf(q_prim_vf, pinf, cell, rhol, gamma, pi_inf, cson) - - $:GPU_ROUTINE(function_name='s_compute_cson_from_pinf', parallelism='[seq]', cray_inline=True) + $:GPU_ROUTINE(function_name='s_compute_cson_from_pinf', & + & parallelism='[seq]', cray_inline=True) type(scalar_field), dimension(sys_size), intent(in) :: q_prim_vf - real(wp), intent(in) :: pinf, rhol, gamma, pi_inf - integer, dimension(3), intent(in) :: cell - real(wp), intent(out) :: cson - real(wp) :: E, H + real(wp), intent(in) :: pinf, rhol, gamma, pi_inf + integer, dimension(3), intent(in) :: cell + real(wp), intent(out) :: cson + + real(wp) :: E, H #:if not MFC_CASE_OPTIMIZATION and USING_AMD real(wp), dimension(3) :: vel #:else @@ -725,143 +925,251 @@ contains end subroutine s_compute_cson_from_pinf - !> Smear the bubble effects onto the Eulerian grid - subroutine s_smear_voidfraction() + !> The purpose of this subroutine is to smear the effect of the bubbles in the Eulerian framework + subroutine s_smear_voidfraction(bc_type) + type(integer_field), dimension(1:num_dims, 1:2), intent(in) :: bc_type integer :: i, j, k, l - call nvtxStartRange("BUBBLES-LAGRANGE-KERNELS") - - $:GPU_PARALLEL_LOOP(private='[i, j, k, l]', collapse=4) + call nvtxStartRange("BUBBLES-LAGRANGE-SMEARING") + $:GPU_PARALLEL_LOOP(private='[i,j,k,l]', collapse=4) do i = 1, q_beta_idx do l = idwbuff(3)%beg, idwbuff(3)%end do k = idwbuff(2)%beg, idwbuff(2)%end do j = idwbuff(1)%beg, idwbuff(1)%end q_beta(i)%sf(j, k, l) = 0._wp + kahan_comp(i)%sf(j, k, l) = 0._wp end do end do end do end do $:END_GPU_PARALLEL_LOOP() - call s_smoothfunction(nBubs, intfc_rad, intfc_vel, mtn_s, mtn_pos, q_beta) + ! Build cell list before smearing (CPU-side counting sort) + call s_build_cell_list(n_el_bubs_loc, mtn_s) + + call s_smoothfunction(n_el_bubs_loc, intfc_rad, intfc_vel, & + mtn_s, mtn_pos, q_beta, kahan_comp) + + call nvtxStartRange("BUBBLES-LAGRANGE-BETA-COMM") + if (lag_params%cluster_type >= 4) then + call s_populate_beta_buffers(q_beta, kahan_comp, bc_type, 3) + else + call s_populate_beta_buffers(q_beta, kahan_comp, bc_type, 2) + end if + call nvtxEndRange - ! Store 1-beta - $:GPU_PARALLEL_LOOP(private='[j, k, l]', collapse=3) + !Store 1-beta + $:GPU_PARALLEL_LOOP(private='[j,k,l]', collapse=3) do l = idwbuff(3)%beg, idwbuff(3)%end do k = idwbuff(2)%beg, idwbuff(2)%end do j = idwbuff(1)%beg, idwbuff(1)%end q_beta(1)%sf(j, k, l) = 1._wp - q_beta(1)%sf(j, k, l) ! Limiting void fraction given max value - q_beta(1)%sf(j, k, l) = max(q_beta(1)%sf(j, k, l), 1._wp - lag_params%valmaxvoid) + q_beta(1)%sf(j, k, l) = max(q_beta(1)%sf(j, k, l), & + 1._wp - lag_params%valmaxvoid) end do end do end do $:END_GPU_PARALLEL_LOOP() - - call nvtxEndRange + call nvtxEndRange ! BUBBLES-LAGRANGE-SMEARING end subroutine s_smear_voidfraction - !> Compute the bubble driving pressure p_inf + !> The purpose of this procedure is obtain the bubble driving pressure p_inf + !! @param bub_id Particle identifier + !! @param q_prim_vf Primitive variables + !! @param ptype 1: p at infinity, 2: averaged P at the bubble location + !! @param f_pinfl Driving pressure + !! @param cell Bubble cell + !! @param preterm1 Pre-computed term 1 + !! @param term2 Computed term 2 + !! @param Romega Control volume radius subroutine s_get_pinf(bub_id, q_prim_vf, ptype, f_pinfl, cell, preterm1, term2, Romega) + $:GPU_ROUTINE(function_name='s_get_pinf',parallelism='[seq]', & + & cray_inline=True) - $:GPU_ROUTINE(function_name='s_get_pinf',parallelism='[seq]', cray_inline=True) - - integer, intent(in) :: bub_id, ptype + integer, intent(in) :: bub_id, ptype type(scalar_field), dimension(sys_size), intent(in) :: q_prim_vf - real(wp), intent(out) :: f_pinfl - integer, dimension(3), intent(out) :: cell - real(wp), intent(out), optional :: preterm1, term2, Romega - real(wp), dimension(3) :: scoord, psi - real(wp) :: dc, vol, aux - real(wp) :: volgas, term1, Rbeq, denom - real(wp) :: charvol, charpres, charvol2, charpres2 - integer, dimension(3) :: cellaux - integer :: i, j, k - integer :: smearGrid, smearGridz - logical :: celloutside - - scoord = mtn_s(bub_id,1:3,2) + real(wp), intent(out) :: f_pinfl + integer, dimension(3), intent(out) :: cell + real(wp), intent(out), optional :: preterm1, term2, Romega + + real(wp), dimension(3) :: scoord, psi_pos, psi_x, psi_y, psi_z + real(wp) :: xi, eta, zeta + real(wp) :: dc, vol, aux + real(wp) :: volgas, term1, Rbeq, denom + real(wp) :: charvol, charpres, charvol2, charpres2 + integer, dimension(3) :: cellaux + integer :: i, j, k + integer :: smearGrid, smearGridz + f_pinfl = 0._wp - !> Find current bubble cell - cell(:) = int(scoord(:)) - $:GPU_LOOP(parallelism='[seq]') - do i = 1, num_dims - if (scoord(i) < 0._wp) cell(i) = cell(i) - 1 - end do + if (moving_lag_bubbles) then + cell = fd_number - buff_size + call s_locate_cell(mtn_pos(bub_id, 1:3, 2), cell, mtn_s(bub_id, 1:3, 2)) + scoord = mtn_s(bub_id, 1:3, 2) + else + scoord = mtn_s(bub_id, 1:3, 2) + cell(:) = int(scoord(:)) + $:GPU_LOOP(parallelism='[seq]') + do i = 1, num_dims + if (scoord(i) < 0._wp) cell(i) = cell(i) - 1 + end do + end if if ((lag_params%cluster_type == 1)) then - !> Getting p_cell in terms of only the current cell by interpolation - !> Getting the cell volulme as Omega - if (p > 0) then - vol = dx(cell(1))*dy(cell(2))*dz(cell(3)) - else - if (cyl_coord) then - vol = dx(cell(1))*dy(cell(2))*y_cc(cell(2))*2._wp*pi + !< Getting p_cell in terms of only the current cell by interpolation + + if (fd_order == 2) then ! Bilinear interpolation + + if (p > 0) then + vol = dx(cell(1))*dy(cell(2))*dz(cell(3)) else - vol = dx(cell(1))*dy(cell(2))*lag_params%charwidth + if (cyl_coord) then + vol = dx(cell(1))*dy(cell(2))*y_cc(cell(2))*2._wp*pi + else + vol = dx(cell(1))*dy(cell(2))*lag_params%charwidth + end if end if - end if - !> Obtain bilinear interpolation coefficients, based on the current location of the bubble. - psi(1) = (scoord(1) - real(cell(1)))*dx(cell(1)) + x_cb(cell(1) - 1) - if (cell(1) == (m + buff_size)) then - cell(1) = cell(1) - 1 - psi(1) = 1._wp - else if (cell(1) == (-buff_size)) then - psi(1) = 0._wp - else - if (psi(1) < x_cc(cell(1))) cell(1) = cell(1) - 1 - psi(1) = abs((psi(1) - x_cc(cell(1)))/(x_cc(cell(1) + 1) - x_cc(cell(1)))) - end if + !< Obtain bilinear interpolation coefficients, based on the current location of the bubble. + psi_pos(1) = (scoord(1) - real(cell(1)))*dx(cell(1)) + x_cb(cell(1) - 1) + psi_pos(1) = abs((psi_pos(1) - x_cc(cell(1)))/(x_cc(cell(1) + 1) - x_cc(cell(1)))) - psi(2) = (scoord(2) - real(cell(2)))*dy(cell(2)) + y_cb(cell(2) - 1) - if (cell(2) == (n + buff_size)) then - cell(2) = cell(2) - 1 - psi(2) = 1._wp - else if (cell(2) == (-buff_size)) then - psi(2) = 0._wp - else - if (psi(2) < y_cc(cell(2))) cell(2) = cell(2) - 1 - psi(2) = abs((psi(2) - y_cc(cell(2)))/(y_cc(cell(2) + 1) - y_cc(cell(2)))) - end if + psi_pos(2) = (scoord(2) - real(cell(2)))*dy(cell(2)) + y_cb(cell(2) - 1) + psi_pos(2) = abs((psi_pos(2) - y_cc(cell(2)))/(y_cc(cell(2) + 1) - y_cc(cell(2)))) - if (p > 0) then - psi(3) = (scoord(3) - real(cell(3)))*dz(cell(3)) + z_cb(cell(3) - 1) - if (cell(3) == (p + buff_size)) then - cell(3) = cell(3) - 1 - psi(3) = 1._wp - else if (cell(3) == (-buff_size)) then - psi(3) = 0._wp + if (p > 0) then + psi_pos(3) = (scoord(3) - real(cell(3)))*dz(cell(3)) + z_cb(cell(3) - 1) + psi_pos(3) = abs((psi_pos(3) - z_cc(cell(3)))/(z_cc(cell(3) + 1) - z_cc(cell(3)))) else - if (psi(3) < z_cc(cell(3))) cell(3) = cell(3) - 1 - psi(3) = abs((psi(3) - z_cc(cell(3)))/(z_cc(cell(3) + 1) - z_cc(cell(3)))) + psi_pos(3) = 0._wp end if - else - psi(3) = 0._wp - end if - !> Perform bilinear interpolation - if (p == 0) then ! 2D - f_pinfl = q_prim_vf(E_idx)%sf(cell(1), cell(2), cell(3))*(1._wp - psi(1))*(1._wp - psi(2)) - f_pinfl = f_pinfl + q_prim_vf(E_idx)%sf(cell(1) + 1, cell(2), cell(3))*psi(1)*(1._wp - psi(2)) - f_pinfl = f_pinfl + q_prim_vf(E_idx)%sf(cell(1) + 1, cell(2) + 1, cell(3))*psi(1)*psi(2) - f_pinfl = f_pinfl + q_prim_vf(E_idx)%sf(cell(1), cell(2) + 1, cell(3))*(1._wp - psi(1))*psi(2) - else ! 3D - f_pinfl = q_prim_vf(E_idx)%sf(cell(1), cell(2), cell(3))*(1._wp - psi(1))*(1._wp - psi(2))*(1._wp - psi(3)) - f_pinfl = f_pinfl + q_prim_vf(E_idx)%sf(cell(1) + 1, cell(2), cell(3))*psi(1)*(1._wp - psi(2))*(1._wp - psi(3)) - f_pinfl = f_pinfl + q_prim_vf(E_idx)%sf(cell(1) + 1, cell(2) + 1, cell(3))*psi(1)*psi(2)*(1._wp - psi(3)) - f_pinfl = f_pinfl + q_prim_vf(E_idx)%sf(cell(1), cell(2) + 1, cell(3))*(1._wp - psi(1))*psi(2)*(1._wp - psi(3)) - f_pinfl = f_pinfl + q_prim_vf(E_idx)%sf(cell(1), cell(2), cell(3) + 1)*(1._wp - psi(1))*(1._wp - psi(2))*psi(3) - f_pinfl = f_pinfl + q_prim_vf(E_idx)%sf(cell(1) + 1, cell(2), cell(3) + 1)*psi(1)*(1._wp - psi(2))*psi(3) - f_pinfl = f_pinfl + q_prim_vf(E_idx)%sf(cell(1) + 1, cell(2) + 1, cell(3) + 1)*psi(1)*psi(2)*psi(3) - f_pinfl = f_pinfl + q_prim_vf(E_idx)%sf(cell(1), cell(2) + 1, cell(3) + 1)*(1._wp - psi(1))*psi(2)*psi(3) + ! Calculate bilinear basis functions for each direction + ! For normalized coordinate xi in [0, 1], the two basis functions are: + ! phi_0(xi) = 1 - xi, phi_1(xi) = xi + + ! X-direction basis functions + psi_x(1) = 1._wp - psi_pos(1) ! Left basis function + psi_x(2) = psi_pos(1) ! Right basis function + + ! Y-direction basis functions + psi_y(1) = 1._wp - psi_pos(2) ! Left basis function + psi_y(2) = psi_pos(2) ! Right basis function + + if (p > 0) then + ! Z-direction basis functions + psi_z(1) = 1._wp - psi_pos(3) ! Left basis function + psi_z(2) = psi_pos(3) ! Right basis function + else + psi_z(1) = 1._wp + psi_z(2) = 0._wp + end if + + !< Perform bilinear interpolation + f_pinfl = 0._wp + + if (p == 0) then !2D - 4 point interpolation (2x2) + do j = 1, 2 + do i = 1, 2 + f_pinfl = f_pinfl + q_prim_vf(E_idx)%sf(cell(1) + i - 1, cell(2) + j - 1, cell(3))* & + psi_x(i)*psi_y(j) + end do + end do + else !3D - 8 point interpolation (2x2x2) + do k = 1, 2 + do j = 1, 2 + do i = 1, 2 + f_pinfl = f_pinfl + q_prim_vf(E_idx)%sf(cell(1) + i - 1, cell(2) + j - 1, cell(3) + k - 1)* & + psi_x(i)*psi_y(j)*psi_z(k) + end do + end do + end do + end if + + elseif (fd_order == 4) then ! Biquadratic interpolation + + if (p > 0) then + vol = dx(cell(1))*dy(cell(2))*dz(cell(3)) + else + if (cyl_coord) then + vol = dx(cell(1))*dy(cell(2))*y_cc(cell(2))*2._wp*pi + else + vol = dx(cell(1))*dy(cell(2))*lag_params%charwidth + end if + end if + + !< Obtain biquadratic interpolation coefficients, based on the current location of the bubble. + ! For biquadratic interpolation, we need coefficients for 3 points in each direction + psi_pos(1) = (scoord(1) - real(cell(1)))*dx(cell(1)) + x_cb(cell(1) - 1) + psi_pos(1) = (psi_pos(1) - x_cc(cell(1)))/(x_cc(cell(1) + 1) - x_cc(cell(1))) + + psi_pos(2) = (scoord(2) - real(cell(2)))*dy(cell(2)) + y_cb(cell(2) - 1) + psi_pos(2) = (psi_pos(2) - y_cc(cell(2)))/(y_cc(cell(2) + 1) - y_cc(cell(2))) + + if (p > 0) then + psi_pos(3) = (scoord(3) - real(cell(3)))*dz(cell(3)) + z_cb(cell(3) - 1) + psi_pos(3) = (psi_pos(3) - z_cc(cell(3)))/(z_cc(cell(3) + 1) - z_cc(cell(3))) + else + psi_pos(3) = 0._wp + end if + + ! Calculate biquadratic basis functions for each direction + ! For normalized coordinate xi in [-1, 1], the three basis functions are: + ! phi_0(xi) = xi*(xi-1)/2, phi_1(xi) = (1-xi)*(1+xi), phi_2(xi) = xi*(xi+1)/2 + + ! X-direction basis functions + xi = 2._wp*psi_pos(1) - 1._wp ! Convert to [-1, 1] range + psi_x(1) = xi*(xi - 1._wp)/2._wp ! Left basis function + psi_x(2) = (1._wp - xi)*(1._wp + xi) ! Center basis function + psi_x(3) = xi*(xi + 1._wp)/2._wp ! Right basis function + + ! Y-direction basis functions + eta = 2._wp*psi_pos(2) - 1._wp ! Convert to [-1, 1] range + psi_y(1) = eta*(eta - 1._wp)/2._wp ! Left basis function + psi_y(2) = (1._wp - eta)*(1._wp + eta) ! Center basis function + psi_y(3) = eta*(eta + 1._wp)/2._wp ! Right basis function + + if (p > 0) then + ! Z-direction basis functions + zeta = 2._wp*psi_pos(3) - 1._wp ! Convert to [-1, 1] range + psi_z(1) = zeta*(zeta - 1._wp)/2._wp ! Left basis function + psi_z(2) = (1._wp - zeta)*(1._wp + zeta) ! Center basis function + psi_z(3) = zeta*(zeta + 1._wp)/2._wp ! Right basis function + else + psi_z(1) = 0._wp + psi_z(2) = 1._wp + psi_z(3) = 0._wp + end if + + !< Perform biquadratic interpolation + f_pinfl = 0._wp + + if (p == 0) then !2D - 9 point interpolation (3x3) + do j = 1, 3 + do i = 1, 3 + f_pinfl = f_pinfl + q_prim_vf(E_idx)%sf(cell(1) + i - 2, cell(2) + j - 2, cell(3))* & + psi_x(i)*psi_y(j) + end do + end do + else !3D - 27 point interpolation (3x3x3) + do k = 1, 3 + do j = 1, 3 + do i = 1, 3 + f_pinfl = f_pinfl + q_prim_vf(E_idx)%sf(cell(1) + i - 2, cell(2) + j - 2, cell(3) + k - 2)* & + psi_x(i)*psi_y(j)*psi_z(k) + end do + end do + end do + end if end if - ! R_Omega + !R_Omega dc = (3._wp*vol/(4._wp*pi))**(1._wp/3._wp) + else if (lag_params%cluster_type >= 2) then ! Bubble dynamic closure from Maeda and Colonius (2018) @@ -887,215 +1195,425 @@ contains cellaux(3) = cell(3) + k - (mapCells + 1) if (p == 0) cellaux(3) = 0 - !> check if the current cell is outside the computational domain or not (including ghost cells) - celloutside = .false. - if (num_dims == 2) then - if ((cellaux(1) < -buff_size) .or. (cellaux(2) < -buff_size)) then - celloutside = .true. - end if - if (cyl_coord .and. y_cc(cellaux(2)) < 0._wp) then - celloutside = .true. - end if - if ((cellaux(2) > n + buff_size) .or. (cellaux(1) > m + buff_size)) then - celloutside = .true. - end if + !< Obtaining the cell volume + if (p > 0) then + vol = dx(cellaux(1))*dy(cellaux(2))*dz(cellaux(3)) else - if ((cellaux(3) < -buff_size) .or. (cellaux(1) < -buff_size) .or. (cellaux(2) < -buff_size)) then - celloutside = .true. - end if - - if ((cellaux(3) > p + buff_size) .or. (cellaux(2) > n + buff_size) .or. (cellaux(1) > m + buff_size)) & - & then - celloutside = .true. - end if - end if - if (.not. celloutside) then - if (cyl_coord .and. (p == 0) .and. (y_cc(cellaux(2)) < 0._wp)) then - celloutside = .true. - end if - end if - - if (.not. celloutside) then - !> Obtaining the cell volulme - if (p > 0) then - vol = dx(cellaux(1))*dy(cellaux(2))*dz(cellaux(3)) + if (cyl_coord) then + vol = dx(cellaux(1))*dy(cellaux(2))*y_cc(cellaux(2))*2._wp*pi else - if (cyl_coord) then - vol = dx(cellaux(1))*dy(cellaux(2))*y_cc(cellaux(2))*2._wp*pi - else - vol = dx(cellaux(1))*dy(cellaux(2))*lag_params%charwidth - end if + vol = dx(cellaux(1))*dy(cellaux(2))*lag_params%charwidth end if - !> Update values - charvol = charvol + vol - charpres = charpres + q_prim_vf(E_idx)%sf(cellaux(1), cellaux(2), cellaux(3))*vol - charvol2 = charvol2 + vol*q_beta(1)%sf(cellaux(1), cellaux(2), cellaux(3)) - charpres2 = charpres2 + q_prim_vf(E_idx)%sf(cellaux(1), cellaux(2), & - & cellaux(3))*vol*q_beta(1)%sf(cellaux(1), cellaux(2), cellaux(3)) end if + !< Update values + charvol = charvol + vol + charpres = charpres + q_prim_vf(E_idx)%sf(cellaux(1), cellaux(2), cellaux(3))*vol + charvol2 = charvol2 + vol*q_beta(1)%sf(cellaux(1), cellaux(2), cellaux(3)) + charpres2 = charpres2 + q_prim_vf(E_idx)%sf(cellaux(1), cellaux(2), cellaux(3)) & + *vol*q_beta(1)%sf(cellaux(1), cellaux(2), cellaux(3)) end do end do end do - f_pinfl = charpres2/charvol2 vol = charvol dc = (3._wp*abs(vol)/(4._wp*pi))**(1._wp/3._wp) + end if if (lag_params%pressure_corrector) then - ! Valid if only one bubble exists per cell + + !Valid if only one bubble exists per cell volgas = intfc_rad(bub_id, 2)**3._wp denom = intfc_rad(bub_id, 2)**2._wp term1 = bub_dphidt(bub_id)*intfc_rad(bub_id, 2)**2._wp term2 = intfc_vel(bub_id, 2)*intfc_rad(bub_id, 2)**2._wp - Rbeq = volgas**(1._wp/3._wp) ! surrogate bubble radius + Rbeq = volgas**(1._wp/3._wp) !surrogate bubble radius aux = dc**3._wp - Rbeq**3._wp term2 = term2/denom term2 = 3._wp/2._wp*term2**2._wp*Rbeq**3._wp*(1._wp - Rbeq/dc)/aux preterm1 = 3._wp/2._wp*Rbeq*(dc**2._wp - Rbeq**2._wp)/(aux*denom) - ! Control volume radius + !Control volume radius if (ptype == 2) Romega = dc ! Getting p_inf if (ptype == 1) then f_pinfl = f_pinfl + preterm1*term1 + term2 end if + end if end subroutine s_get_pinf - !> Update Lagrangian bubble variables using TVD Runge-Kutta time stepping - impure subroutine s_update_lagrange_tdv_rk(stage) + !> This subroutine updates the Lagrange variables using the tvd RK time steppers. + !! The time derivative of the bubble variables must be stored at every stage to avoid precision errors. + !! @param stage Current tvd RK stage + impure subroutine s_update_lagrange_tdv_rk(q_prim_vf, bc_type, stage) + type(scalar_field), dimension(sys_size), intent(in) :: q_prim_vf + type(integer_field), dimension(1:num_dims, 1:2), intent(in) :: bc_type integer, intent(in) :: stage - integer :: k - if (time_stepper == 1) then ! 1st order TVD RK + integer :: k + + if (time_stepper == 1) then ! 1st order TVD RK + $:GPU_PARALLEL_LOOP(private='[k]') - do k = 1, nBubs - ! u{1} = u{n} + dt * RHS{n} + do k = 1, n_el_bubs_loc + !u{1} = u{n} + dt * RHS{n} intfc_rad(k, 1) = intfc_rad(k, 1) + dt*intfc_draddt(k, 1) intfc_vel(k, 1) = intfc_vel(k, 1) + dt*intfc_dveldt(k, 1) - mtn_pos(k,1:3,1) = mtn_pos(k,1:3,1) + dt*mtn_dposdt(k,1:3,1) - mtn_vel(k,1:3,1) = mtn_vel(k,1:3,1) + dt*mtn_dveldt(k,1:3,1) gas_p(k, 1) = gas_p(k, 1) + dt*gas_dpdt(k, 1) gas_mv(k, 1) = gas_mv(k, 1) + dt*gas_dmvdt(k, 1) + if (moving_lag_bubbles) then + mtn_posPrev(k, 1:3, 1) = mtn_pos(k, 1:3, 1) + mtn_pos(k, 1:3, 1) = mtn_pos(k, 1:3, 1) + dt*mtn_dposdt(k, 1:3, 1) + mtn_vel(k, 1:3, 1) = mtn_vel(k, 1:3, 1) + dt*mtn_dveldt(k, 1:3, 1) + end if end do $:END_GPU_PARALLEL_LOOP() call s_transfer_data_to_tmp() - call s_write_void_evol(mytime) + if (moving_lag_bubbles) call s_enforce_EL_bubbles_boundary_conditions(q_prim_vf) + call s_smear_voidfraction(bc_type) + if (lag_params%write_void_evol) call s_write_void_evol(mytime) if (lag_params%write_bubbles_stats) call s_calculate_lag_bubble_stats() - if (lag_params%write_bubbles) then - $:GPU_UPDATE(host='[gas_p, gas_mv, intfc_rad, intfc_vel]') - call s_write_lag_particles(mytime) + $:GPU_UPDATE(host='[gas_p,gas_mv,intfc_rad,intfc_vel]') + call s_write_lag_bubble_evol(mytime) end if - else if (time_stepper == 2) then ! 2nd order TVD RK + + elseif (time_stepper == 2) then ! 2nd order TVD RK if (stage == 1) then + $:GPU_PARALLEL_LOOP(private='[k]') - do k = 1, nBubs - ! u{1} = u{n} + dt * RHS{n} + do k = 1, n_el_bubs_loc + !u{1} = u{n} + dt * RHS{n} intfc_rad(k, 2) = intfc_rad(k, 1) + dt*intfc_draddt(k, 1) intfc_vel(k, 2) = intfc_vel(k, 1) + dt*intfc_dveldt(k, 1) - mtn_pos(k,1:3,2) = mtn_pos(k,1:3,1) + dt*mtn_dposdt(k,1:3,1) - mtn_vel(k,1:3,2) = mtn_vel(k,1:3,1) + dt*mtn_dveldt(k,1:3,1) gas_p(k, 2) = gas_p(k, 1) + dt*gas_dpdt(k, 1) gas_mv(k, 2) = gas_mv(k, 1) + dt*gas_dmvdt(k, 1) + if (moving_lag_bubbles) then + mtn_posPrev(k, 1:3, 2) = mtn_pos(k, 1:3, 1) + mtn_pos(k, 1:3, 2) = mtn_pos(k, 1:3, 1) + dt*mtn_dposdt(k, 1:3, 1) + mtn_vel(k, 1:3, 2) = mtn_vel(k, 1:3, 1) + dt*mtn_dveldt(k, 1:3, 1) + end if end do $:END_GPU_PARALLEL_LOOP() - else if (stage == 2) then + + if (moving_lag_bubbles) call s_enforce_EL_bubbles_boundary_conditions(q_prim_vf) + call s_smear_voidfraction(bc_type) + + elseif (stage == 2) then + $:GPU_PARALLEL_LOOP(private='[k]') - do k = 1, nBubs - ! u{1} = u{n} + (1/2) * dt * (RHS{n} + RHS{1}) + do k = 1, n_el_bubs_loc + !u{1} = u{n} + (1/2) * dt * (RHS{n} + RHS{1}) intfc_rad(k, 1) = intfc_rad(k, 1) + dt*(intfc_draddt(k, 1) + intfc_draddt(k, 2))/2._wp intfc_vel(k, 1) = intfc_vel(k, 1) + dt*(intfc_dveldt(k, 1) + intfc_dveldt(k, 2))/2._wp - mtn_pos(k,1:3,1) = mtn_pos(k,1:3,1) + dt*(mtn_dposdt(k,1:3,1) + mtn_dposdt(k,1:3,2))/2._wp - mtn_vel(k,1:3,1) = mtn_vel(k,1:3,1) + dt*(mtn_dveldt(k,1:3,1) + mtn_dveldt(k,1:3,2))/2._wp gas_p(k, 1) = gas_p(k, 1) + dt*(gas_dpdt(k, 1) + gas_dpdt(k, 2))/2._wp gas_mv(k, 1) = gas_mv(k, 1) + dt*(gas_dmvdt(k, 1) + gas_dmvdt(k, 2))/2._wp + if (moving_lag_bubbles) then + mtn_posPrev(k, 1:3, 1) = mtn_pos(k, 1:3, 2) + mtn_pos(k, 1:3, 1) = mtn_pos(k, 1:3, 1) + dt*(mtn_dposdt(k, 1:3, 1) + mtn_dposdt(k, 1:3, 2))/2._wp + mtn_vel(k, 1:3, 1) = mtn_vel(k, 1:3, 1) + dt*(mtn_dveldt(k, 1:3, 1) + mtn_dveldt(k, 1:3, 2))/2._wp + end if end do $:END_GPU_PARALLEL_LOOP() call s_transfer_data_to_tmp() - call s_write_void_evol(mytime) + if (moving_lag_bubbles) call s_enforce_EL_bubbles_boundary_conditions(q_prim_vf) + call s_smear_voidfraction(bc_type) + if (lag_params%write_void_evol) call s_write_void_evol(mytime) if (lag_params%write_bubbles_stats) call s_calculate_lag_bubble_stats() - if (lag_params%write_bubbles) then - $:GPU_UPDATE(host='[gas_p, gas_mv, intfc_rad, intfc_vel]') - call s_write_lag_particles(mytime) + $:GPU_UPDATE(host='[gas_p,gas_mv,intfc_rad,intfc_vel]') + call s_write_lag_bubble_evol(mytime) end if + end if - else if (time_stepper == 3) then ! 3rd order TVD RK + + elseif (time_stepper == 3) then ! 3rd order TVD RK if (stage == 1) then + $:GPU_PARALLEL_LOOP(private='[k]') - do k = 1, nBubs - ! u{1} = u{n} + dt * RHS{n} + do k = 1, n_el_bubs_loc + !u{1} = u{n} + dt * RHS{n} intfc_rad(k, 2) = intfc_rad(k, 1) + dt*intfc_draddt(k, 1) intfc_vel(k, 2) = intfc_vel(k, 1) + dt*intfc_dveldt(k, 1) - mtn_pos(k,1:3,2) = mtn_pos(k,1:3,1) + dt*mtn_dposdt(k,1:3,1) - mtn_vel(k,1:3,2) = mtn_vel(k,1:3,1) + dt*mtn_dveldt(k,1:3,1) gas_p(k, 2) = gas_p(k, 1) + dt*gas_dpdt(k, 1) gas_mv(k, 2) = gas_mv(k, 1) + dt*gas_dmvdt(k, 1) + if (moving_lag_bubbles) then + mtn_posPrev(k, 1:3, 2) = mtn_pos(k, 1:3, 1) + mtn_pos(k, 1:3, 2) = mtn_pos(k, 1:3, 1) + dt*mtn_dposdt(k, 1:3, 1) + mtn_vel(k, 1:3, 2) = mtn_vel(k, 1:3, 1) + dt*mtn_dveldt(k, 1:3, 1) + end if end do $:END_GPU_PARALLEL_LOOP() - else if (stage == 2) then + + if (moving_lag_bubbles) call s_enforce_EL_bubbles_boundary_conditions(q_prim_vf) + call s_smear_voidfraction(bc_type) + + elseif (stage == 2) then + $:GPU_PARALLEL_LOOP(private='[k]') - do k = 1, nBubs - ! u{2} = u{n} + (1/4) * dt * [RHS{n} + RHS{1}] + do k = 1, n_el_bubs_loc + !u{2} = u{n} + (1/4) * dt * [RHS{n} + RHS{1}] intfc_rad(k, 2) = intfc_rad(k, 1) + dt*(intfc_draddt(k, 1) + intfc_draddt(k, 2))/4._wp intfc_vel(k, 2) = intfc_vel(k, 1) + dt*(intfc_dveldt(k, 1) + intfc_dveldt(k, 2))/4._wp - mtn_pos(k,1:3,2) = mtn_pos(k,1:3,1) + dt*(mtn_dposdt(k,1:3,1) + mtn_dposdt(k,1:3,2))/4._wp - mtn_vel(k,1:3,2) = mtn_vel(k,1:3,1) + dt*(mtn_dveldt(k,1:3,1) + mtn_dveldt(k,1:3,2))/4._wp gas_p(k, 2) = gas_p(k, 1) + dt*(gas_dpdt(k, 1) + gas_dpdt(k, 2))/4._wp gas_mv(k, 2) = gas_mv(k, 1) + dt*(gas_dmvdt(k, 1) + gas_dmvdt(k, 2))/4._wp + if (moving_lag_bubbles) then + mtn_posPrev(k, 1:3, 2) = mtn_pos(k, 1:3, 2) + mtn_pos(k, 1:3, 2) = mtn_pos(k, 1:3, 1) + dt*(mtn_dposdt(k, 1:3, 1) + mtn_dposdt(k, 1:3, 2))/4._wp + mtn_vel(k, 1:3, 2) = mtn_vel(k, 1:3, 1) + dt*(mtn_dveldt(k, 1:3, 1) + mtn_dveldt(k, 1:3, 2))/4._wp + end if end do $:END_GPU_PARALLEL_LOOP() - else if (stage == 3) then + + if (moving_lag_bubbles) call s_enforce_EL_bubbles_boundary_conditions(q_prim_vf) + call s_smear_voidfraction(bc_type) + + elseif (stage == 3) then + $:GPU_PARALLEL_LOOP(private='[k]') - do k = 1, nBubs - ! u{n+1} = u{n} + (2/3) * dt * [(1/4)* RHS{n} + (1/4)* RHS{1} + RHS{2}] - intfc_rad(k, 1) = intfc_rad(k, 1) + (2._wp/3._wp)*dt*(intfc_draddt(k, 1)/4._wp + intfc_draddt(k, & - & 2)/4._wp + intfc_draddt(k, 3)) - intfc_vel(k, 1) = intfc_vel(k, 1) + (2._wp/3._wp)*dt*(intfc_dveldt(k, 1)/4._wp + intfc_dveldt(k, & - & 2)/4._wp + intfc_dveldt(k, 3)) - mtn_pos(k,1:3,1) = mtn_pos(k,1:3,1) + (2._wp/3._wp)*dt*(mtn_dposdt(k,1:3,1)/4._wp + mtn_dposdt(k,1:3, & - & 2)/4._wp + mtn_dposdt(k,1:3,3)) - mtn_vel(k,1:3,1) = mtn_vel(k,1:3,1) + (2._wp/3._wp)*dt*(mtn_dveldt(k,1:3,1)/4._wp + mtn_dveldt(k,1:3, & - & 2)/4._wp + mtn_dveldt(k,1:3,3)) + do k = 1, n_el_bubs_loc + !u{n+1} = u{n} + (2/3) * dt * [(1/4)* RHS{n} + (1/4)* RHS{1} + RHS{2}] + intfc_rad(k, 1) = intfc_rad(k, 1) + (2._wp/3._wp)*dt*(intfc_draddt(k, 1)/4._wp + intfc_draddt(k, 2)/4._wp + intfc_draddt(k, 3)) + intfc_vel(k, 1) = intfc_vel(k, 1) + (2._wp/3._wp)*dt*(intfc_dveldt(k, 1)/4._wp + intfc_dveldt(k, 2)/4._wp + intfc_dveldt(k, 3)) gas_p(k, 1) = gas_p(k, 1) + (2._wp/3._wp)*dt*(gas_dpdt(k, 1)/4._wp + gas_dpdt(k, 2)/4._wp + gas_dpdt(k, 3)) gas_mv(k, 1) = gas_mv(k, 1) + (2._wp/3._wp)*dt*(gas_dmvdt(k, 1)/4._wp + gas_dmvdt(k, 2)/4._wp + gas_dmvdt(k, 3)) + if (moving_lag_bubbles) then + mtn_posPrev(k, 1:3, 1) = mtn_pos(k, 1:3, 2) + mtn_pos(k, 1:3, 1) = mtn_pos(k, 1:3, 1) + (2._wp/3._wp)*dt*(mtn_dposdt(k, 1:3, 1)/4._wp + mtn_dposdt(k, 1:3, 2)/4._wp + mtn_dposdt(k, 1:3, 3)) + mtn_vel(k, 1:3, 1) = mtn_vel(k, 1:3, 1) + (2._wp/3._wp)*dt*(mtn_dveldt(k, 1:3, 1)/4._wp + mtn_dveldt(k, 1:3, 2)/4._wp + mtn_dveldt(k, 1:3, 3)) + end if end do $:END_GPU_PARALLEL_LOOP() call s_transfer_data_to_tmp() - call s_write_void_evol(mytime) + if (moving_lag_bubbles) call s_enforce_EL_bubbles_boundary_conditions(q_prim_vf) + call s_smear_voidfraction(bc_type) + if (lag_params%write_void_evol) call s_write_void_evol(mytime) if (lag_params%write_bubbles_stats) call s_calculate_lag_bubble_stats() - if (lag_params%write_bubbles) then - $:GPU_UPDATE(host='[gas_p, gas_mv, gas_mg, intfc_rad, intfc_vel]') - call s_write_lag_particles(mytime) + $:GPU_UPDATE(host='[gas_p,gas_mv,gas_mg,intfc_rad,intfc_vel]') + call s_write_lag_bubble_evol(mytime) end if + end if + end if end subroutine s_update_lagrange_tdv_rk - !> Locate the cell index for a given physical position + !> This subroutine enforces reflective and wall boundary conditions for EL bubbles + !! @param dest Destination for the bubble position update + impure subroutine s_enforce_EL_bubbles_boundary_conditions(q_prim_vf) + + type(scalar_field), dimension(sys_size), intent(in) :: q_prim_vf + integer :: k, i, q + integer :: patch_id, newBubs, new_idx + real(wp) :: offset + integer, dimension(3) :: cell + + call nvtxStartRange("LAG-BC") + call nvtxStartRange("LAG-BC-DEV2HOST") + $:GPU_UPDATE(host='[bub_R0, Rmax_stats, Rmin_stats, gas_mg, gas_betaT, & + & gas_betaC, bub_dphidt, lag_id, gas_p, gas_mv, intfc_rad, intfc_vel, & + & mtn_pos, mtn_posPrev, mtn_vel, mtn_s, intfc_draddt, intfc_dveldt, & + & gas_dpdt, gas_dmvdt, mtn_dposdt, mtn_dveldt, keep_bubble, n_el_bubs_loc, & + & wrap_bubble_dir, wrap_bubble_loc]') + call nvtxEndRange + + ! Handle MPI transfer of bubbles going to another processor's local domain + if (num_procs > 1) then + call nvtxStartRange("LAG-BC-TRANSFER-LIST") + call s_add_particles_to_transfer_list(n_el_bubs_loc, mtn_pos(:, :, 2), mtn_posPrev(:, :, 2)) + call nvtxEndRange + + call nvtxStartRange("LAG-BC-SENDRECV") + call s_mpi_sendrecv_particles(bub_R0, Rmax_stats, Rmin_stats, gas_mg, gas_betaT, & + gas_betaC, bub_dphidt, lag_id, gas_p, gas_mv, & + intfc_rad, intfc_vel, mtn_pos, mtn_posPrev, mtn_vel, & + mtn_s, intfc_draddt, intfc_dveldt, gas_dpdt, & + gas_dmvdt, mtn_dposdt, mtn_dveldt, lag_num_ts, n_el_bubs_loc, & + 2) + call nvtxEndRange + end if + + call nvtxStartRange("LAG-BC-HOST2DEV") + $:GPU_UPDATE(device='[bub_R0, Rmax_stats, Rmin_stats, gas_mg, gas_betaT, & + & gas_betaC, bub_dphidt, lag_id, gas_p, gas_mv, intfc_rad, intfc_vel, & + & mtn_pos, mtn_posPrev, mtn_vel, mtn_s, intfc_draddt, intfc_dveldt, & + & gas_dpdt, gas_dmvdt, mtn_dposdt, mtn_dveldt, n_el_bubs_loc]') + call nvtxEndRange + + $:GPU_PARALLEL_LOOP(private='[k, cell]') + do k = 1, n_el_bubs_loc + keep_bubble(k) = 1 + wrap_bubble_loc(k, :) = 0 + wrap_bubble_dir(k, :) = 0 + + ! Relocate bubbles at solid boundaries and delete bubbles that leave + ! buffer regions + if (any(bc_x%beg == (/BC_REFLECTIVE, BC_CHAR_SLIP_WALL, BC_SLIP_WALL, BC_NO_SLIP_WALL/)) & + .and. mtn_pos(k, 1, 2) < x_cb(-1) + intfc_rad(k, 2)) then + mtn_pos(k, 1, 2) = x_cb(-1) + intfc_rad(k, 2) + elseif (any(bc_x%end == (/BC_REFLECTIVE, BC_CHAR_SLIP_WALL, BC_SLIP_WALL, BC_NO_SLIP_WALL/)) & + .and. mtn_pos(k, 1, 2) > x_cb(m) - intfc_rad(k, 2)) then + mtn_pos(k, 1, 2) = x_cb(m) - intfc_rad(k, 2) + elseif (bc_x%beg == BC_PERIODIC .and. mtn_pos(k, 1, 2) < pcomm_coords(1)%beg .and. & + mtn_posPrev(k, 1, 2) >= pcomm_coords(1)%beg) then + wrap_bubble_dir(k, 1) = 1 + wrap_bubble_loc(k, 1) = -1 + elseif (bc_x%end == BC_PERIODIC .and. mtn_pos(k, 1, 2) > pcomm_coords(1)%end .and. & + mtn_posPrev(k, 1, 2) <= pcomm_coords(1)%end) then + wrap_bubble_dir(k, 1) = 1 + wrap_bubble_loc(k, 1) = 1 + elseif (mtn_pos(k, 1, 2) >= x_cb(m)) then + keep_bubble(k) = 0 + elseif (mtn_pos(k, 1, 2) < x_cb(-1)) then + keep_bubble(k) = 0 + end if + + if (any(bc_y%beg == (/BC_REFLECTIVE, BC_CHAR_SLIP_WALL, BC_SLIP_WALL, BC_NO_SLIP_WALL/)) & + .and. mtn_pos(k, 2, 2) < y_cb(-1) + intfc_rad(k, 2)) then + mtn_pos(k, 2, 2) = y_cb(-1) + intfc_rad(k, 2) + else if (any(bc_y%end == (/BC_REFLECTIVE, BC_CHAR_SLIP_WALL, BC_SLIP_WALL, BC_NO_SLIP_WALL/)) & + .and. mtn_pos(k, 2, 2) > y_cb(n) - intfc_rad(k, 2)) then + mtn_pos(k, 2, 2) = y_cb(n) - intfc_rad(k, 2) + elseif (bc_y%beg == BC_PERIODIC .and. mtn_pos(k, 2, 2) < pcomm_coords(2)%beg .and. & + mtn_posPrev(k, 2, 2) >= pcomm_coords(2)%beg) then + wrap_bubble_dir(k, 2) = 1 + wrap_bubble_loc(k, 2) = -1 + elseif (bc_y%end == BC_PERIODIC .and. mtn_pos(k, 2, 2) > pcomm_coords(2)%end .and. & + mtn_posPrev(k, 2, 2) <= pcomm_coords(2)%end) then + wrap_bubble_dir(k, 2) = 1 + wrap_bubble_loc(k, 2) = 1 + elseif (mtn_pos(k, 2, 2) >= y_cb(n)) then + keep_bubble(k) = 0 + elseif (mtn_pos(k, 2, 2) < y_cb(-1)) then + keep_bubble(k) = 0 + end if + + if (p > 0) then + if (any(bc_z%beg == (/BC_REFLECTIVE, BC_CHAR_SLIP_WALL, BC_SLIP_WALL, BC_NO_SLIP_WALL/)) & + .and. mtn_pos(k, 3, 2) < z_cb(-1) + intfc_rad(k, 2)) then + mtn_pos(k, 3, 2) = z_cb(-1) + intfc_rad(k, 2) + else if (any(bc_z%end == (/BC_REFLECTIVE, BC_CHAR_SLIP_WALL, BC_SLIP_WALL, BC_NO_SLIP_WALL/)) & + .and. mtn_pos(k, 3, 2) > z_cb(p) - intfc_rad(k, 2)) then + mtn_pos(k, 3, 2) = z_cb(p) - intfc_rad(k, 2) + elseif (bc_z%beg == BC_PERIODIC .and. mtn_pos(k, 3, 2) < pcomm_coords(3)%beg .and. & + mtn_posPrev(k, 3, 2) >= pcomm_coords(3)%beg) then + wrap_bubble_dir(k, 3) = 1 + wrap_bubble_loc(k, 3) = -1 + elseif (bc_z%end == BC_PERIODIC .and. mtn_pos(k, 3, 2) > pcomm_coords(3)%end .and. & + mtn_posPrev(k, 3, 2) <= pcomm_coords(3)%end) then + wrap_bubble_dir(k, 3) = 1 + wrap_bubble_loc(k, 3) = 1 + elseif (mtn_pos(k, 3, 2) >= z_cb(p)) then + keep_bubble(k) = 0 + elseif (mtn_pos(k, 3, 2) < z_cb(-1)) then + keep_bubble(k) = 0 + end if + end if + + if (keep_bubble(k) == 1) then + ! Remove bubbles that are no longer in a liquid + cell = fd_number - buff_size + call s_locate_cell(mtn_pos(k, 1:3, 2), cell, mtn_s(k, 1:3, 2)) + + if (q_prim_vf(advxb)%sf(cell(1), cell(2), cell(3)) < (1._wp - lag_params%valmaxvoid)) then + keep_bubble(k) = 0 + end if + end if + end do + $:END_GPU_PARALLEL_LOOP() + + if (n_el_bubs_loc > 0) then + call nvtxStartRange("LAG-BC-DEV2HOST") + $:GPU_UPDATE(host='[bub_R0, Rmax_stats, Rmin_stats, gas_mg, gas_betaT, & + & gas_betaC, bub_dphidt, lag_id, gas_p, gas_mv, intfc_rad, intfc_vel, & + & mtn_pos, mtn_posPrev, mtn_vel, mtn_s, intfc_draddt, intfc_dveldt, & + & gas_dpdt, gas_dmvdt, mtn_dposdt, mtn_dveldt, keep_bubble, n_el_bubs_loc, & + & wrap_bubble_dir, wrap_bubble_loc]') + call nvtxEndRange + + newBubs = 0 + do k = 1, n_el_bubs_loc + if (keep_bubble(k) == 1) then + newBubs = newBubs + 1 + if (newBubs /= k) then + call s_copy_lag_bubble(newBubs, k) + wrap_bubble_dir(newBubs, :) = wrap_bubble_dir(k, :) + wrap_bubble_loc(newBubs, :) = wrap_bubble_loc(k, :) + end if + end if + end do + n_el_bubs_loc = newBubs + + ! Handle periodic wrapping of bubbles on same processor + do k = 1, n_el_bubs_loc + if (any(wrap_bubble_dir(k, :) == 1)) then + do i = 1, num_dims + if (wrap_bubble_dir(k, i) == 1) then + offset = glb_bounds(i)%end - glb_bounds(i)%beg + if (wrap_bubble_loc(k, i) == 1) then + do q = 1, 2 + mtn_pos(k, i, q) = mtn_pos(k, i, q) - offset + mtn_posPrev(k, i, q) = mtn_posPrev(k, i, q) - offset + end do + else if (wrap_bubble_loc(k, i) == -1) then + do q = 1, 2 + mtn_pos(k, i, q) = mtn_pos(k, i, q) + offset + mtn_posPrev(k, i, q) = mtn_posPrev(k, i, q) + offset + end do + end if + end if + end do + end if + end do + call nvtxStartRange("LAG-BC-HOST2DEV") + $:GPU_UPDATE(device='[bub_R0, Rmax_stats, Rmin_stats, gas_mg, gas_betaT, & + & gas_betaC, bub_dphidt, lag_id, gas_p, gas_mv, intfc_rad, intfc_vel, & + & mtn_pos, mtn_posPrev, mtn_vel, mtn_s, intfc_draddt, intfc_dveldt, & + & gas_dpdt, gas_dmvdt, mtn_dposdt, mtn_dveldt, n_el_bubs_loc]') + call nvtxEndRange + + end if + + $:GPU_PARALLEL_LOOP(private='[cell]') + do k = 1, n_el_bubs_loc + cell = fd_number - buff_size + call s_locate_cell(mtn_pos(k, 1:3, 2), cell, mtn_s(k, 1:3, 2)) + end do + $:END_GPU_PARALLEL_LOOP() + + call nvtxEndRange ! LAG-BC + + end subroutine s_enforce_EL_bubbles_boundary_conditions + + !> This subroutine returns the computational coordinate of the cell for the given position. + !! @param pos Input coordinates + !! @param cell Computational coordinate of the cell + !! @param scoord Calculated particle coordinates subroutine s_locate_cell(pos, cell, scoord) + $:GPU_ROUTINE(function_name='s_locate_cell',parallelism='[seq]', & + & cray_inline=True) - real(wp), dimension(3), intent(in) :: pos - real(wp), dimension(3), intent(out) :: scoord + real(wp), dimension(3), intent(in) :: pos + real(wp), dimension(3), intent(out) :: scoord integer, dimension(3), intent(inout) :: cell - integer :: i + + integer :: i do while (pos(1) < x_cb(cell(1) - 1)) cell(1) = cell(1) - 1 end do - do while (pos(1) > x_cb(cell(1))) + do while (pos(1) >= x_cb(cell(1))) cell(1) = cell(1) + 1 end do @@ -1103,7 +1621,7 @@ contains cell(2) = cell(2) - 1 end do - do while (pos(2) > y_cb(cell(2))) + do while (pos(2) >= y_cb(cell(2))) cell(2) = cell(2) + 1 end do @@ -1111,16 +1629,18 @@ contains do while (pos(3) < z_cb(cell(3) - 1)) cell(3) = cell(3) - 1 end do - do while (pos(3) > z_cb(cell(3))) + do while (pos(3) >= z_cb(cell(3))) cell(3) = cell(3) + 1 end do end if - ! The numbering of the cell of which left boundary is the domain boundary is 0. if comp.coord of the pos is s, the real - ! coordinate of s is (the coordinate of the left boundary of the Floor(s)-th cell) + (s-(int(s))*(cell-width). In other - ! words, the coordinate of the center of the cell is x_cc(cell). + ! The numbering of the cell of which left boundary is the domain boundary is 0. + ! if comp.coord of the pos is s, the real coordinate of s is + ! (the coordinate of the left boundary of the Floor(s)-th cell) + ! + (s-(int(s))*(cell-width). + ! In other words, the coordinate of the center of the cell is x_cc(cell). - ! coordinates in computational space + !coordinates in computational space scoord(1) = cell(1) + (pos(1) - x_cb(cell(1) - 1))/dx(cell(1)) scoord(2) = cell(2) + (pos(2) - y_cb(cell(2) - 1))/dy(cell(2)) scoord(3) = 0._wp @@ -1132,52 +1652,59 @@ contains end subroutine s_locate_cell - !> Transfer data into the temporal variables + !> This subroutine transfer data into the temporal variables. impure subroutine s_transfer_data_to_tmp() integer :: k $:GPU_PARALLEL_LOOP(private='[k]') - do k = 1, nBubs + do k = 1, n_el_bubs_loc gas_p(k, 2) = gas_p(k, 1) gas_mv(k, 2) = gas_mv(k, 1) intfc_rad(k, 2) = intfc_rad(k, 1) intfc_vel(k, 2) = intfc_vel(k, 1) - mtn_pos(k,1:3,2) = mtn_pos(k,1:3,1) - mtn_posPrev(k,1:3,2) = mtn_posPrev(k,1:3,1) - mtn_vel(k,1:3,2) = mtn_vel(k,1:3,1) - mtn_s(k,1:3,2) = mtn_s(k,1:3,1) + mtn_pos(k, 1:3, 2) = mtn_pos(k, 1:3, 1) + mtn_posPrev(k, 1:3, 2) = mtn_posPrev(k, 1:3, 1) + mtn_vel(k, 1:3, 2) = mtn_vel(k, 1:3, 1) + mtn_s(k, 1:3, 2) = mtn_s(k, 1:3, 1) end do $:END_GPU_PARALLEL_LOOP() end subroutine s_transfer_data_to_tmp - !> Determine if a bubble position lies within the current MPI subdomain including ghost cells + !> The purpose of this procedure is to determine if the global coordinates of the bubbles + !! are present in the current MPI processor (including ghost cells). + !! @param pos_part Spatial coordinates of the bubble function particle_in_domain(pos_part) - logical :: particle_in_domain + logical :: particle_in_domain real(wp), dimension(3), intent(in) :: pos_part ! 2D - if (p == 0 .and. cyl_coord .neqv. .true.) then - ! Defining a virtual z-axis that has the same dimensions as y-axis defined in the input file - particle_in_domain = ((pos_part(1) < x_cb(m + buff_size)) .and. (pos_part(1) >= x_cb(-buff_size - 1)) & - & .and. (pos_part(2) < y_cb(n + buff_size)) .and. (pos_part(2) >= y_cb(-buff_size - 1)) & - & .and. (pos_part(3) < lag_params%charwidth/2._wp) .and. (pos_part(3) >= & - & -lag_params%charwidth/2._wp)) + ! Defining a virtual z-axis that has the same dimensions as y-axis + ! defined in the input file + particle_in_domain = ((pos_part(1) < x_cb(m + buff_size - fd_number)) .and. & + (pos_part(1) >= x_cb(fd_number - buff_size - 1)) .and. & + (pos_part(2) < y_cb(n + buff_size - fd_number)) .and. & + (pos_part(2) >= y_cb(fd_number - buff_size - 1)) .and. & + (pos_part(3) < lag_params%charwidth/2._wp) .and. (pos_part(3) > -lag_params%charwidth/2._wp)) else ! cyl_coord - particle_in_domain = ((pos_part(1) < x_cb(m + buff_size)) .and. (pos_part(1) >= x_cb(-buff_size - 1)) & - & .and. (abs(pos_part(2)) < y_cb(n + buff_size)) .and. (abs(pos_part(2)) >= max(y_cb(-buff_size & - & - 1), 0._wp))) + particle_in_domain = ((pos_part(1) < x_cb(m + buff_size - fd_number)) .and. & + (pos_part(1) >= x_cb(fd_number - buff_size - 1)) .and. & + (abs(pos_part(2)) < y_cb(n + buff_size - fd_number)) .and. & + (abs(pos_part(2)) >= max(y_cb(fd_number - buff_size - 1), 0._wp))) end if ! 3D if (p > 0) then - particle_in_domain = ((pos_part(1) < x_cb(m + buff_size)) .and. (pos_part(1) >= x_cb(-buff_size - 1)) & - & .and. (pos_part(2) < y_cb(n + buff_size)) .and. (pos_part(2) >= y_cb(-buff_size - 1)) & - & .and. (pos_part(3) < z_cb(p + buff_size)) .and. (pos_part(3) >= z_cb(-buff_size - 1))) + particle_in_domain = ((pos_part(1) < x_cb(m + buff_size - fd_number)) .and. & + (pos_part(1) >= x_cb(fd_number - buff_size - 1)) .and. & + (pos_part(2) < y_cb(n + buff_size - fd_number)) .and. & + (pos_part(2) >= y_cb(fd_number - buff_size - 1)) .and. & + (pos_part(3) < z_cb(p + buff_size - fd_number)) .and. & + (pos_part(3) >= z_cb(fd_number - buff_size - 1))) end if ! For symmetric and wall boundary condition @@ -1204,64 +1731,76 @@ contains end function particle_in_domain - !> Determine if a Lagrangian bubble is within the physical domain excluding ghost cells + !> The purpose of this procedure is to determine if the lagrangian bubble is located in the + !! physical domain. The ghost cells are not part of the physical domain. + !! @param pos_part Spatial coordinates of the bubble function particle_in_domain_physical(pos_part) - logical :: particle_in_domain_physical + logical :: particle_in_domain_physical real(wp), dimension(3), intent(in) :: pos_part - particle_in_domain_physical = ((pos_part(1) < x_cb(m)) .and. (pos_part(1) >= x_cb(-1)) .and. (pos_part(2) < y_cb(n)) & - & .and. (pos_part(2) >= y_cb(-1))) + particle_in_domain_physical = ((pos_part(1) < x_cb(m)) .and. (pos_part(1) >= x_cb(-1)) .and. & + (pos_part(2) < y_cb(n)) .and. (pos_part(2) >= y_cb(-1))) if (p > 0) then - particle_in_domain_physical = (particle_in_domain_physical .and. (pos_part(3) < z_cb(p)) .and. (pos_part(3) & - & >= z_cb(-1))) + particle_in_domain_physical = (particle_in_domain_physical .and. (pos_part(3) < z_cb(p)) .and. (pos_part(3) >= z_cb(-1))) end if end function particle_in_domain_physical - !> Compute the gradient of a scalar field using second-order central differences on a non-uniform grid + !> The purpose of this procedure is to calculate the gradient of a scalar field along the x, y and z directions + !! following a second-order central difference considering uneven widths + !! @param q Input scalar field + !! @param dq Output gradient of q + !! @param dir Gradient spatial direction subroutine s_gradient_dir(q, dq, dir) - real(stp), dimension(idwbuff(1)%beg:,idwbuff(2)%beg:,idwbuff(3)%beg:), intent(inout) :: q, dq - integer, intent(in) :: dir - integer :: i, j, k + real(stp), dimension(idwbuff(1)%beg:, idwbuff(2)%beg:, idwbuff(3)%beg:), intent(inout) :: q, dq + integer, intent(in) :: dir + + integer :: i, j, k if (dir == 1) then ! Gradient in x dir. - $:GPU_PARALLEL_LOOP(private='[i, j, k]', collapse=3) + $:GPU_PARALLEL_LOOP(private='[i,j,k]', collapse=3) do k = 0, p do j = 0, n do i = 0, m - dq(i, j, k) = q(i, j, k)*(dx(i + 1) - dx(i - 1)) + q(i + 1, j, k)*(dx(i) + dx(i - 1)) - q(i - 1, j, & - & k)*(dx(i) + dx(i + 1)) - dq(i, j, k) = dq(i, j, k)/((dx(i) + dx(i - 1))*(dx(i) + dx(i + 1))) + dq(i, j, k) = q(i, j, k)*(dx(i + 1) - dx(i - 1)) & + + q(i + 1, j, k)*(dx(i) + dx(i - 1)) & + - q(i - 1, j, k)*(dx(i) + dx(i + 1)) + dq(i, j, k) = dq(i, j, k)/ & + ((dx(i) + dx(i - 1))*(dx(i) + dx(i + 1))) end do end do end do $:END_GPU_PARALLEL_LOOP() - else if (dir == 2) then + elseif (dir == 2) then ! Gradient in y dir. - $:GPU_PARALLEL_LOOP(private='[i, j, k]', collapse=3) + $:GPU_PARALLEL_LOOP(private='[i,j,k]', collapse=3) do k = 0, p do j = 0, n do i = 0, m - dq(i, j, k) = q(i, j, k)*(dy(j + 1) - dy(j - 1)) + q(i, j + 1, k)*(dy(j) + dy(j - 1)) - q(i, j - 1, & - & k)*(dy(j) + dy(j + 1)) - dq(i, j, k) = dq(i, j, k)/((dy(j) + dy(j - 1))*(dy(j) + dy(j + 1))) + dq(i, j, k) = q(i, j, k)*(dy(j + 1) - dy(j - 1)) & + + q(i, j + 1, k)*(dy(j) + dy(j - 1)) & + - q(i, j - 1, k)*(dy(j) + dy(j + 1)) + dq(i, j, k) = dq(i, j, k)/ & + ((dy(j) + dy(j - 1))*(dy(j) + dy(j + 1))) end do end do end do $:END_GPU_PARALLEL_LOOP() - else if (dir == 3) then + elseif (dir == 3) then ! Gradient in z dir. - $:GPU_PARALLEL_LOOP(private='[i, j, k]', collapse=3) + $:GPU_PARALLEL_LOOP(private='[i,j,k]', collapse=3) do k = 0, p do j = 0, n do i = 0, m - dq(i, j, k) = q(i, j, k)*(dz(k + 1) - dz(k - 1)) + q(i, j, k + 1)*(dz(k) + dz(k - 1)) - q(i, j, & - & k - 1)*(dz(k) + dz(k + 1)) - dq(i, j, k) = dq(i, j, k)/((dz(k) + dz(k - 1))*(dz(k) + dz(k + 1))) + dq(i, j, k) = q(i, j, k)*(dz(k + 1) - dz(k - 1)) & + + q(i, j, k + 1)*(dz(k) + dz(k - 1)) & + - q(i, j, k - 1)*(dz(k) + dz(k + 1)) + dq(i, j, k) = dq(i, j, k)/ & + ((dz(k) + dz(k - 1))*(dz(k) + dz(k + 1))) end do end do end do @@ -1270,18 +1809,48 @@ contains end subroutine s_gradient_dir - !> Write Lagrangian bubble state data at each time step + !> Subroutine that writes on each time step the changes of the lagrangian bubbles. + !! @param qtime Current time impure subroutine s_write_lag_particles(qtime) - real(wp), intent(in) :: qtime - integer :: k + real(wp), intent(in) :: qtime + integer :: k + character(LEN=path_len + 2*name_len) :: file_loc - logical :: file_exist - character(LEN=25) :: FMT + logical :: file_exist + character(LEN=25) :: FMT write (file_loc, '(A,I0,A)') 'lag_bubble_evol_', proc_rank, '.dat' - file_loc = trim(case_dir) // '/D/' // trim(file_loc) - inquire (FILE=trim(file_loc), EXIST=file_exist) + file_loc = trim(case_dir)//'/D/'//trim(file_loc) + call my_inquire(trim(file_loc), file_exist) + + if (precision == 1) then + FMT = "(A16,A14,8A16)" + else + FMT = "(A24,A14,8A24)" + end if + + if (.not. file_exist) then + open (LAG_EVOL_ID, FILE=trim(file_loc), FORM='formatted', position='rewind') + write (LAG_EVOL_ID, FMT) 'currentTime', 'particleID', 'x', 'y', 'z', & + 'coreVaporMass', 'coreVaporConcentration', 'radius', 'interfaceVelocity', & + 'corePressure' + else + open (LAG_EVOL_ID, FILE=trim(file_loc), FORM='formatted', position='append') + end if + + end subroutine s_write_lag_particles + + !> @Brief Subroutine that opens the file to write the evolution of the lagrangian bubbles on each time step. + impure subroutine s_open_lag_bubble_evol() + + character(LEN=path_len + 2*name_len) :: file_loc + logical :: file_exist + character(LEN=25) :: FMT + + write (file_loc, '(A,I0,A)') 'lag_bubble_evol_', proc_rank, '.dat' + file_loc = trim(case_dir)//'/D/'//trim(file_loc) + call my_inquire(trim(file_loc), file_exist) if (precision == 1) then FMT = "(A16,A14,8A16)" @@ -1290,13 +1859,27 @@ contains end if if (.not. file_exist) then - open (11, FILE=trim(file_loc), form='formatted', position='rewind') - write (11, FMT) 'currentTime', 'particleID', 'x', 'y', 'z', 'coreVaporMass', 'coreVaporConcentration', 'radius', & - & 'interfaceVelocity', 'corePressure' + open (LAG_EVOL_ID, FILE=trim(file_loc), FORM='formatted', position='rewind') + write (LAG_EVOL_ID, FMT) 'currentTime', 'particleID', 'x', 'y', 'z', & + 'coreVaporMass', 'coreVaporConcentration', 'radius', 'interfaceVelocity', & + 'corePressure' else - open (11, FILE=trim(file_loc), form='formatted', position='append') + open (LAG_EVOL_ID, FILE=trim(file_loc), FORM='formatted', position='append') end if + end subroutine s_open_lag_bubble_evol + + !> Subroutine that writes on each time step the changes of the lagrangian bubbles. + !! @param q_time Current time + impure subroutine s_write_lag_bubble_evol(qtime) + + real(wp), intent(in) :: qtime + integer :: k, ios + character(LEN=25) :: FMT + + character(LEN=path_len + 2*name_len) :: file_loc, path + logical :: file_exist + if (precision == 1) then FMT = "(F16.8,I14,8F16.8)" else @@ -1304,42 +1887,71 @@ contains end if ! Cycle through list - do k = 1, nBubs - write (11, FMT) qtime, lag_id(k, 1), mtn_pos(k, 1, 1), mtn_pos(k, 2, 1), mtn_pos(k, 3, 1), gas_mv(k, 1), gas_mv(k, & - & 1)/(gas_mv(k, 1) + gas_mg(k)), intfc_rad(k, 1), intfc_vel(k, 1), gas_p(k, 1) + do k = 1, n_el_bubs_loc + write (LAG_EVOL_ID, FMT) & + qtime, & + lag_id(k, 1), & + mtn_pos(k, 1, 1), & + mtn_pos(k, 2, 1), & + mtn_pos(k, 3, 1), & + gas_mv(k, 1), & + gas_mv(k, 1)/(gas_mv(k, 1) + gas_mg(k)), & + intfc_rad(k, 1), & + intfc_vel(k, 1), & + gas_p(k, 1) end do - close (11) + end subroutine s_write_lag_bubble_evol - end subroutine s_write_lag_particles + impure subroutine s_close_lag_bubble_evol - !> Write void fraction statistics at each time step - impure subroutine s_write_void_evol(qtime) + close (LAG_EVOL_ID) + + end subroutine s_close_lag_bubble_evol + + subroutine s_open_void_evol - real(wp), intent(in) :: qtime - real(wp) :: volcell, voltot - real(wp) :: lag_void_max, lag_void_avg, lag_vol - real(wp) :: void_max_glb, void_avg_glb, vol_glb - integer :: i, j, k character(LEN=path_len + 2*name_len) :: file_loc - logical :: file_exist + logical :: file_exist if (proc_rank == 0) then write (file_loc, '(A)') 'voidfraction.dat' - file_loc = trim(case_dir) // '/D/' // trim(file_loc) - inquire (FILE=trim(file_loc), EXIST=file_exist) + file_loc = trim(case_dir)//'/D/'//trim(file_loc) + call my_inquire(trim(file_loc), file_exist) if (.not. file_exist) then - open (12, FILE=trim(file_loc), form='formatted', position='rewind') + open (LAG_VOID_ID, FILE=trim(file_loc), FORM='formatted', position='rewind') + !write (12, *) 'currentTime, averageVoidFraction, ', & + ! 'maximumVoidFraction, totalParticlesVolume' + !write (12, *) 'The averageVoidFraction value does ', & + ! 'not reflect the real void fraction in the cloud since the ', & + ! 'cells which do not have bubbles are not accounted' else - open (12, FILE=trim(file_loc), form='formatted', position='append') + open (LAG_VOID_ID, FILE=trim(file_loc), FORM='formatted', position='append') end if end if + end subroutine s_open_void_evol + + !> Subroutine that writes some useful statistics related to the volume fraction + !! of the particles (void fraction) in the computational domain + !! on each time step. + !! @param qtime Current time + impure subroutine s_write_void_evol(qtime) + + real(wp), intent(in) :: qtime + real(wp) :: volcell, voltot + real(wp) :: lag_void_max, lag_void_avg, lag_vol + real(wp) :: void_max_glb, void_avg_glb, vol_glb + + integer :: i, j, k + + character(LEN=path_len + 2*name_len) :: file_loc + logical :: file_exist + lag_void_max = 0._wp lag_void_avg = 0._wp lag_vol = 0._wp - $:GPU_PARALLEL_LOOP(private='[volcell]', collapse=3, reduction='[[lag_vol, lag_void_avg], [lag_void_max]]', & - & reductionOp='[+, MAX]', copy='[lag_vol, lag_void_avg, lag_void_max]') + $:GPU_PARALLEL_LOOP(private='[volcell]', collapse=3, reduction='[[lag_vol, lag_void_avg], [lag_void_max]]', reductionOp='[+, MAX]', copy='[lag_vol, lag_void_avg, lag_void_max]') do k = 0, p do j = 0, n do i = 0, m @@ -1365,43 +1977,53 @@ contains end if #endif voltot = lag_void_avg - ! This voidavg value does not reflect the real void fraction in the cloud since the cell which does not have bubbles are not - ! accounted + ! This voidavg value does not reflect the real void fraction in the cloud + ! since the cell which does not have bubbles are not accounted if (lag_vol > 0._wp) lag_void_avg = lag_void_avg/lag_vol if (proc_rank == 0) then - write (12, '(6X,4e24.8)') qtime, lag_void_avg, lag_void_max, voltot - close (12) + write (LAG_VOID_ID, '(6X,4e24.8)') & + qtime, & + lag_void_avg, & + lag_void_max, & + voltot end if end subroutine s_write_void_evol - !> Write restart files for the Lagrangian bubble solver + subroutine s_close_void_evol + + if (proc_rank == 0) close (LAG_VOID_ID) + + end subroutine s_close_void_evol + + !> Subroutine that writes the restarting files for the particles in the lagrangian solver. + !! @param t_step Current time step impure subroutine s_write_restart_lag_bubbles(t_step) ! Generic string used to store the address of a particular file - integer, intent(in) :: t_step + integer, intent(in) :: t_step + character(LEN=path_len + 2*name_len) :: file_loc - logical :: file_exist - integer :: bub_id, tot_part - integer :: i, k + logical :: file_exist + integer :: bub_id, tot_part + integer :: i, k #ifdef MFC_MPI ! For Parallel I/O - integer :: ifile, ierr - integer, dimension(MPI_STATUS_SIZE) :: status - integer(KIND=MPI_OFFSET_KIND) :: disp - integer :: view - integer, dimension(2) :: gsizes, lsizes, start_idx_part - integer, allocatable :: proc_bubble_counts(:) - real(wp), dimension(1:1,1:lag_io_vars) :: dummy - + integer :: ifile, ierr + integer, dimension(MPI_STATUS_SIZE) :: status + integer(KIND=MPI_OFFSET_KIND) :: disp + integer :: view + integer, dimension(2) :: gsizes, lsizes, start_idx_part + integer, allocatable :: proc_bubble_counts(:) + real(wp), dimension(1:1, 1:lag_io_vars) :: dummy dummy = 0._wp bub_id = 0._wp - if (nBubs /= 0) then - do k = 1, nBubs - if (particle_in_domain_physical(mtn_pos(k,1:3,1))) then + if (n_el_bubs_loc /= 0) then + do k = 1, n_el_bubs_loc + if (particle_in_domain_physical(mtn_pos(k, 1:3, 1))) then bub_id = bub_id + 1 end if end do @@ -1415,9 +2037,11 @@ contains lsizes(2) = lag_io_vars ! Total number of particles - call MPI_ALLREDUCE(bub_id, tot_part, 1, MPI_integer, MPI_SUM, MPI_COMM_WORLD, ierr) + call MPI_ALLREDUCE(bub_id, tot_part, 1, MPI_integer, & + MPI_SUM, MPI_COMM_WORLD, ierr) - call MPI_ALLGATHER(bub_id, 1, MPI_INTEGER, proc_bubble_counts, 1, MPI_INTEGER, MPI_COMM_WORLD, ierr) + call MPI_ALLGATHER(bub_id, 1, MPI_INTEGER, proc_bubble_counts, 1, MPI_INTEGER, & + MPI_COMM_WORLD, ierr) ! Calculate starting index for this processor's particles call MPI_EXSCAN(lsizes(1), start_idx_part(1), 1, MPI_INTEGER, MPI_SUM, MPI_COMM_WORLD, ierr) @@ -1428,7 +2052,7 @@ contains gsizes(2) = lag_io_vars write (file_loc, '(A,I0,A)') 'lag_bubbles_', t_step, '.dat' - file_loc = trim(case_dir) // '/restart_data' // trim(mpiiofs) // trim(file_loc) + file_loc = trim(case_dir)//'/restart_data'//trim(mpiiofs)//trim(file_loc) ! Clean up existing file if (proc_rank == 0) then @@ -1441,7 +2065,9 @@ contains call MPI_BARRIER(MPI_COMM_WORLD, ierr) if (proc_rank == 0) then - call MPI_FILE_OPEN(MPI_COMM_SELF, file_loc, ior(MPI_MODE_WRONLY, MPI_MODE_CREATE), mpi_info_int, ifile, ierr) + call MPI_FILE_OPEN(MPI_COMM_SELF, file_loc, & + ior(MPI_MODE_WRONLY, MPI_MODE_CREATE), & + mpi_info_int, ifile, ierr) ! Write header using MPI I/O for consistency call MPI_FILE_WRITE(ifile, tot_part, 1, MPI_INTEGER, status, ierr) @@ -1456,54 +2082,60 @@ contains call MPI_BARRIER(MPI_COMM_WORLD, ierr) if (bub_id > 0) then - allocate (MPI_IO_DATA_lag_bubbles(max(1, bub_id),1:lag_io_vars)) - - i = 1 - do k = 1, nBubs - if (particle_in_domain_physical(mtn_pos(k,1:3,1))) then - MPI_IO_DATA_lag_bubbles(i, 1) = real(lag_id(k, 1)) - MPI_IO_DATA_lag_bubbles(i,2:4) = mtn_pos(k,1:3,1) - MPI_IO_DATA_lag_bubbles(i,5:7) = mtn_posPrev(k,1:3,1) - MPI_IO_DATA_lag_bubbles(i,8:10) = mtn_vel(k,1:3,1) - MPI_IO_DATA_lag_bubbles(i, 11) = intfc_rad(k, 1) - MPI_IO_DATA_lag_bubbles(i, 12) = intfc_vel(k, 1) - MPI_IO_DATA_lag_bubbles(i, 13) = bub_R0(k) - MPI_IO_DATA_lag_bubbles(i, 14) = Rmax_stats(k) - MPI_IO_DATA_lag_bubbles(i, 15) = Rmin_stats(k) - MPI_IO_DATA_lag_bubbles(i, 16) = bub_dphidt(k) - MPI_IO_DATA_lag_bubbles(i, 17) = gas_p(k, 1) - MPI_IO_DATA_lag_bubbles(i, 18) = gas_mv(k, 1) - MPI_IO_DATA_lag_bubbles(i, 19) = gas_mg(k) - MPI_IO_DATA_lag_bubbles(i, 20) = gas_betaT(k) - MPI_IO_DATA_lag_bubbles(i, 21) = gas_betaC(k) - i = i + 1 - end if + allocate (MPI_IO_DATA_lag_bubbles(max(1, bub_id), 1:lag_io_vars)) + + i = 0 + do k = 1, n_el_bubs_loc + if (.not. particle_in_domain_physical(mtn_pos(k, 1:3, 1))) cycle + i = i + 1 + MPI_IO_DATA_lag_bubbles(i, 1) = real(lag_id(k, 1)) + MPI_IO_DATA_lag_bubbles(i, 2:4) = mtn_pos(k, 1:3, 1) + MPI_IO_DATA_lag_bubbles(i, 5:7) = mtn_posPrev(k, 1:3, 1) + MPI_IO_DATA_lag_bubbles(i, 8:10) = mtn_vel(k, 1:3, 1) + MPI_IO_DATA_lag_bubbles(i, 11) = intfc_rad(k, 1) + MPI_IO_DATA_lag_bubbles(i, 12) = intfc_vel(k, 1) + MPI_IO_DATA_lag_bubbles(i, 13) = bub_R0(k) + MPI_IO_DATA_lag_bubbles(i, 14) = Rmax_stats(k) + MPI_IO_DATA_lag_bubbles(i, 15) = Rmin_stats(k) + MPI_IO_DATA_lag_bubbles(i, 16) = bub_dphidt(k) + MPI_IO_DATA_lag_bubbles(i, 17) = gas_p(k, 1) + MPI_IO_DATA_lag_bubbles(i, 18) = gas_mv(k, 1) + MPI_IO_DATA_lag_bubbles(i, 19) = gas_mg(k) + MPI_IO_DATA_lag_bubbles(i, 20) = gas_betaT(k) + MPI_IO_DATA_lag_bubbles(i, 21) = gas_betaC(k) end do - call MPI_TYPE_CREATE_SUBARRAY(2, gsizes, lsizes, start_idx_part, MPI_ORDER_FORTRAN, mpi_p, view, ierr) + call MPI_TYPE_CREATE_SUBARRAY(2, gsizes, lsizes, start_idx_part, & + MPI_ORDER_FORTRAN, mpi_p, view, ierr) call MPI_TYPE_COMMIT(view, ierr) - call MPI_FILE_OPEN(MPI_COMM_WORLD, file_loc, ior(MPI_MODE_WRONLY, MPI_MODE_CREATE), mpi_info_int, ifile, ierr) + call MPI_FILE_OPEN(MPI_COMM_WORLD, file_loc, & + ior(MPI_MODE_WRONLY, MPI_MODE_CREATE), & + mpi_info_int, ifile, ierr) ! Skip header (written by rank 0) - disp = int(sizeof(tot_part) + 2*sizeof(mytime) + sizeof(num_procs) + num_procs*sizeof(proc_bubble_counts(1)), & - & MPI_OFFSET_KIND) + disp = int(sizeof(tot_part) + 2*sizeof(mytime) + sizeof(num_procs) + & + num_procs*sizeof(proc_bubble_counts(1)), MPI_OFFSET_KIND) call MPI_FILE_SET_VIEW(ifile, disp, mpi_p, view, 'native', mpi_info_int, ierr) - call MPI_FILE_WRITE_ALL(ifile, MPI_IO_DATA_lag_bubbles, lag_io_vars*bub_id, mpi_p, status, ierr) + call MPI_FILE_WRITE_ALL(ifile, MPI_IO_DATA_lag_bubbles, & + lag_io_vars*bub_id, mpi_p, status, ierr) call MPI_FILE_CLOSE(ifile, ierr) deallocate (MPI_IO_DATA_lag_bubbles) + else call MPI_TYPE_CONTIGUOUS(0, mpi_p, view, ierr) call MPI_TYPE_COMMIT(view, ierr) - call MPI_FILE_OPEN(MPI_COMM_WORLD, file_loc, ior(MPI_MODE_WRONLY, MPI_MODE_CREATE), mpi_info_int, ifile, ierr) + call MPI_FILE_OPEN(MPI_COMM_WORLD, file_loc, & + ior(MPI_MODE_WRONLY, MPI_MODE_CREATE), & + mpi_info_int, ifile, ierr) ! Skip header (written by rank 0) - disp = int(sizeof(tot_part) + 2*sizeof(mytime) + sizeof(num_procs) + num_procs*sizeof(proc_bubble_counts(1)), & - & MPI_OFFSET_KIND) + disp = int(sizeof(tot_part) + 2*sizeof(mytime) + sizeof(num_procs) + & + num_procs*sizeof(proc_bubble_counts(1)), MPI_OFFSET_KIND) call MPI_FILE_SET_VIEW(ifile, disp, mpi_p, view, 'native', mpi_info_int, ierr) call MPI_FILE_WRITE_ALL(ifile, dummy, 0, mpi_p, status, ierr) @@ -1512,18 +2144,19 @@ contains end if deallocate (proc_bubble_counts) + #endif end subroutine s_write_restart_lag_bubbles - !> Compute the maximum and minimum radius of each bubble + !> This procedure calculates the maximum and minimum radius of each bubble. subroutine s_calculate_lag_bubble_stats() integer :: k - $:GPU_PARALLEL_LOOP(private='[k]', reduction='[[Rmax_glb], [Rmin_glb]]', reductionOp='[MAX, MIN]', & - & copy='[Rmax_glb, Rmin_glb]') - do k = 1, nBubs + $:GPU_PARALLEL_LOOP(private='[k]', reduction='[[Rmax_glb], [Rmin_glb]]', & + & reductionOp='[MAX, MIN]', copy='[Rmax_glb,Rmin_glb]') + do k = 1, n_el_bubs_loc Rmax_glb = max(Rmax_glb, intfc_rad(k, 1)/bub_R0(k)) Rmin_glb = min(Rmin_glb, intfc_rad(k, 1)/bub_R0(k)) Rmax_stats(k) = max(Rmax_stats(k), intfc_rad(k, 1)/bub_R0(k)) @@ -1533,17 +2166,15 @@ contains end subroutine s_calculate_lag_bubble_stats - !> Write the maximum and minimum radius statistics for each bubble - impure subroutine s_write_lag_bubble_stats() + impure subroutine s_open_lag_bubble_stats() - integer :: k character(LEN=path_len + 2*name_len) :: file_loc - character(len=20) :: FMT + character(LEN=20) :: FMT + logical :: file_exist write (file_loc, '(A,I0,A)') 'stats_lag_bubbles_', proc_rank, '.dat' - file_loc = trim(case_dir) // '/D/' // trim(file_loc) - - $:GPU_UPDATE(host='[Rmax_glb, Rmin_glb]') + file_loc = trim(case_dir)//'/D/'//trim(file_loc) + call my_inquire(trim(file_loc), file_exist) if (precision == 1) then FMT = "(A10,A14,5A16)" @@ -1551,70 +2182,97 @@ contains FMT = "(A10,A14,5A24)" end if - open (13, FILE=trim(file_loc), form='formatted', position='rewind') - write (13, FMT) 'proc_rank', 'particleID', 'x', 'y', 'z', 'Rmax_glb', 'Rmin_glb' - - if (precision == 1) then - FMT = "(I10,I14,5F16.8)" + if (.not. file_exist) then + open (LAG_STATS_ID, FILE=trim(file_loc), FORM='formatted', position='rewind') + write (LAG_STATS_ID, *) 'proc_rank, particleID, x, y, z, Rmax_glb, Rmin_glb' else - FMT = "(I10,I14,5F24.16)" + open (LAG_STATS_ID, FILE=trim(file_loc), FORM='formatted', position='append') end if - do k = 1, nBubs - write (13, FMT) proc_rank, lag_id(k, 1), mtn_pos(k, 1, 1), mtn_pos(k, 2, 1), mtn_pos(k, 3, 1), Rmax_stats(k), & - & Rmin_stats(k) - end do + end subroutine s_open_lag_bubble_stats - close (13) + !> Subroutine that writes the maximum and minimum radius of each bubble. + impure subroutine s_write_lag_bubble_stats() - end subroutine s_write_lag_bubble_stats + integer :: k + character(LEN=path_len + 2*name_len) :: file_loc + character(LEN=20) :: FMT - !> Remove a specific Lagrangian bubble when dt becomes too small - impure subroutine s_remove_lag_bubble(bub_id) + $:GPU_UPDATE(host='[Rmax_glb,Rmin_glb]') - integer, intent(in) :: bub_id - integer :: i + if (precision == 1) then + FMT = "(I10,I14,5F16.8)" + else + FMT = "(I10,I14,5F24.16)" + end if - $:GPU_LOOP(parallelism='[seq]') - do i = bub_id, nBubs - 1 - lag_id(i, 1) = lag_id(i + 1, 1) - bub_R0(i) = bub_R0(i + 1) - Rmax_stats(i) = Rmax_stats(i + 1) - Rmin_stats(i) = Rmin_stats(i + 1) - gas_mg(i) = gas_mg(i + 1) - gas_betaT(i) = gas_betaT(i + 1) - gas_betaC(i) = gas_betaC(i + 1) - bub_dphidt(i) = bub_dphidt(i + 1) - gas_p(i,1:2) = gas_p(i + 1,1:2) - gas_mv(i,1:2) = gas_mv(i + 1,1:2) - intfc_rad(i,1:2) = intfc_rad(i + 1,1:2) - intfc_vel(i,1:2) = intfc_vel(i + 1,1:2) - mtn_pos(i,1:3,1:2) = mtn_pos(i + 1,1:3,1:2) - mtn_posPrev(i,1:3,1:2) = mtn_posPrev(i + 1,1:3,1:2) - mtn_vel(i,1:3,1:2) = mtn_vel(i + 1,1:3,1:2) - mtn_s(i,1:3,1:2) = mtn_s(i + 1,1:3,1:2) - intfc_draddt(i,1:lag_num_ts) = intfc_draddt(i + 1,1:lag_num_ts) - intfc_dveldt(i,1:lag_num_ts) = intfc_dveldt(i + 1,1:lag_num_ts) - gas_dpdt(i,1:lag_num_ts) = gas_dpdt(i + 1,1:lag_num_ts) - gas_dmvdt(i,1:lag_num_ts) = gas_dmvdt(i + 1,1:lag_num_ts) + do k = 1, n_el_bubs_loc + write (LAG_STATS_ID, FMT) & + proc_rank, & + lag_id(k, 1), & + mtn_pos(k, 1, 1), & + mtn_pos(k, 2, 1), & + mtn_pos(k, 3, 1), & + Rmax_stats(k), & + Rmin_stats(k) end do - nBubs = nBubs - 1 - $:GPU_UPDATE(device='[nBubs]') - - end subroutine s_remove_lag_bubble + end subroutine s_write_lag_bubble_stats - !> Finalize the Lagrangian bubble solver + subroutine s_close_lag_bubble_stats + + close (LAG_STATS_ID) + + end subroutine s_close_lag_bubble_stats + + !> The purpose of this subroutine is to remove one specific particle if dt is too small. + !! @param bub_id Particle id + impure subroutine s_copy_lag_bubble(dest, src) + + integer, intent(in) :: src, dest + + bub_R0(dest) = bub_R0(src) + Rmax_stats(dest) = Rmax_stats(src) + Rmin_stats(dest) = Rmin_stats(src) + gas_mg(dest) = gas_mg(src) + gas_betaT(dest) = gas_betaT(src) + gas_betaC(dest) = gas_betaC(src) + bub_dphidt(dest) = bub_dphidt(src) + lag_id(dest, 1) = lag_id(src, 1) + gas_p(dest, 1:2) = gas_p(src, 1:2) + gas_mv(dest, 1:2) = gas_mv(src, 1:2) + intfc_rad(dest, 1:2) = intfc_rad(src, 1:2) + intfc_vel(dest, 1:2) = intfc_vel(src, 1:2) + mtn_vel(dest, 1:3, 1:2) = mtn_vel(src, 1:3, 1:2) + mtn_s(dest, 1:3, 1:2) = mtn_s(src, 1:3, 1:2) + mtn_pos(dest, 1:3, 1:2) = mtn_pos(src, 1:3, 1:2) + mtn_posPrev(dest, 1:3, 1:2) = mtn_posPrev(src, 1:3, 1:2) + intfc_draddt(dest, 1:lag_num_ts) = intfc_draddt(src, 1:lag_num_ts) + intfc_dveldt(dest, 1:lag_num_ts) = intfc_dveldt(src, 1:lag_num_ts) + gas_dpdt(dest, 1:lag_num_ts) = gas_dpdt(src, 1:lag_num_ts) + gas_dmvdt(dest, 1:lag_num_ts) = gas_dmvdt(src, 1:lag_num_ts) + mtn_dposdt(dest, 1:3, 1:lag_num_ts) = mtn_dposdt(src, 1:3, 1:lag_num_ts) + mtn_dveldt(dest, 1:3, 1:lag_num_ts) = mtn_dveldt(src, 1:3, 1:lag_num_ts) + + end subroutine s_copy_lag_bubble + + !> The purpose of this subroutine is to deallocate variables impure subroutine s_finalize_lagrangian_solver() integer :: i + if (lag_params%write_void_evol) call s_close_void_evol + if (lag_params%write_bubbles) call s_close_lag_bubble_evol() + if (lag_params%write_bubbles_stats) call s_close_lag_bubble_stats() + do i = 1, q_beta_idx @:DEALLOCATE(q_beta(i)%sf) + @:DEALLOCATE(kahan_comp(i)%sf) end do @:DEALLOCATE(q_beta) + @:DEALLOCATE(kahan_comp) - ! Deallocating space + !Deallocating space @:DEALLOCATE(lag_id) @:DEALLOCATE(bub_R0) @:DEALLOCATE(Rmax_stats) @@ -1638,6 +2296,29 @@ contains @:DEALLOCATE(mtn_dposdt) @:DEALLOCATE(mtn_dveldt) + @:DEALLOCATE(keep_bubble) + @:DEALLOCATE(wrap_bubble_loc, wrap_bubble_dir) + + ! Deallocate pressure gradient arrays and FD coefficients + if (lag_params%vel_model > 0 .and. lag_params%pressure_force) then + @:DEALLOCATE(grad_p_x) + @:DEALLOCATE(fd_coeff_x_pgrad) + if (n > 0) then + @:DEALLOCATE(grad_p_y) + @:DEALLOCATE(fd_coeff_y_pgrad) + if (p > 0) then + @:DEALLOCATE(grad_p_z) + @:DEALLOCATE(fd_coeff_z_pgrad) + end if + end if + end if + + ! Deallocate cell list arrays + @:DEALLOCATE(cell_list_start) + @:DEALLOCATE(cell_list_count) + @:DEALLOCATE(cell_list_idx) + end subroutine s_finalize_lagrangian_solver end module m_bubbles_EL + diff --git a/src/simulation/m_bubbles_EL_kernels.fpp b/src/simulation/m_bubbles_EL_kernels.fpp index f1f80980b0..6c4d92861f 100644 --- a/src/simulation/m_bubbles_EL_kernels.fpp +++ b/src/simulation/m_bubbles_EL_kernels.fpp @@ -7,171 +7,289 @@ !> @brief Kernel functions (Gaussian, delta) that smear Lagrangian bubble effects onto the Eulerian grid module m_bubbles_EL_kernels - use m_mpi_proxy + use m_mpi_proxy !< Message passing interface (MPI) module proxy implicit none -contains + ! Cell-centered pressure gradients (precomputed for translational motion) + real(wp), allocatable, dimension(:, :, :) :: grad_p_x, grad_p_y, grad_p_z + $:GPU_DECLARE(create='[grad_p_x, grad_p_y, grad_p_z]') + + ! Finite-difference coefficients for pressure gradient computation + real(wp), allocatable, dimension(:, :) :: fd_coeff_x_pgrad + real(wp), allocatable, dimension(:, :) :: fd_coeff_y_pgrad + real(wp), allocatable, dimension(:, :) :: fd_coeff_z_pgrad + $:GPU_DECLARE(create='[fd_coeff_x_pgrad, fd_coeff_y_pgrad, fd_coeff_z_pgrad]') - !> Smear the Lagrangian bubble effects onto the Eulerian grid using the selected kernel - subroutine s_smoothfunction(nBubs, lbk_rad, lbk_vel, lbk_s, lbk_pos, updatedvar) + ! Cell list for bubble-to-cell mapping (rebuilt each RK stage before smearing) + integer, allocatable, dimension(:, :, :) :: cell_list_start ! (0:m, 0:n, 0:p) + integer, allocatable, dimension(:, :, :) :: cell_list_count ! (0:m, 0:n, 0:p) + integer, allocatable, dimension(:) :: cell_list_idx ! (1:nBubs_glb) sorted bubble indices + $:GPU_DECLARE(create='[cell_list_start, cell_list_count, cell_list_idx]') - integer, intent(in) :: nBubs - real(wp), dimension(1:lag_params%nBubs_glb,1:3,1:2), intent(in) :: lbk_s, lbk_pos - real(wp), dimension(1:lag_params%nBubs_glb,1:2), intent(in) :: lbk_rad, lbk_vel - type(scalar_field), dimension(:), intent(inout) :: updatedvar +contains + + !> The purpose of this subroutine is to smear the strength of the lagrangian + !! bubbles into the Eulerian framework using different approaches. + !! @param nBubs Number of lagrangian bubbles in the current domain + !! @param lbk_rad Radius of the bubbles + !! @param lbk_vel Interface velocity of the bubbles + !! @param lbk_s Computational coordinates of the bubbles + !! @param lbk_pos Spatial coordinates of the bubbles + !! @param updatedvar Eulerian variable to be updated + subroutine s_smoothfunction(nBubs, lbk_rad, lbk_vel, lbk_s, lbk_pos, updatedvar, kcomp) + + integer, intent(in) :: nBubs + real(wp), dimension(1:lag_params%nBubs_glb, 1:3, 1:2), intent(in) :: lbk_s, lbk_pos + real(wp), dimension(1:lag_params%nBubs_glb, 1:2), intent(in) :: lbk_rad, lbk_vel + type(scalar_field), dimension(:), intent(inout) :: updatedvar + type(scalar_field), dimension(:), intent(inout) :: kcomp smoothfunc:select case(lag_params%smooth_type) case (1) - call s_gaussian(nBubs, lbk_rad, lbk_vel, lbk_s, lbk_pos, updatedvar) + call s_gaussian(nBubs, lbk_rad, lbk_vel, lbk_s, lbk_pos, updatedvar, kcomp) case (2) - call s_deltafunc(nBubs, lbk_rad, lbk_vel, lbk_s, updatedvar) + call s_deltafunc(nBubs, lbk_rad, lbk_vel, lbk_s, updatedvar, kcomp) end select smoothfunc end subroutine s_smoothfunction - !> Apply the delta kernel function to map bubble effects onto the containing cell - subroutine s_deltafunc(nBubs, lbk_rad, lbk_vel, lbk_s, updatedvar) - - integer, intent(in) :: nBubs - real(wp), dimension(1:lag_params%nBubs_glb,1:3,1:2), intent(in) :: lbk_s - real(wp), dimension(1:lag_params%nBubs_glb,1:2), intent(in) :: lbk_rad, lbk_vel - type(scalar_field), dimension(:), intent(inout) :: updatedvar - integer, dimension(3) :: cell - real(wp) :: strength_vel, strength_vol - real(wp) :: addFun1, addFun2, addFun3 - real(wp) :: volpart, Vol - real(wp), dimension(3) :: s_coord - integer :: l - - $:GPU_PARALLEL_LOOP(private='[l, s_coord, cell]') - do l = 1, nBubs - volpart = 4._wp/3._wp*pi*lbk_rad(l, 2)**3._wp - s_coord(1:3) = lbk_s(l,1:3,2) - call s_get_cell(s_coord, cell) + !> Builds a sorted cell list mapping each interior cell (0:m,0:n,0:p) to its + !! resident bubbles. Uses a counting-sort on the host (O(nBubs + N_cells)). + !! Must be called before s_gaussian each RK stage. + !! @param nBubs Number of lagrangian bubbles in the current domain + !! @param lbk_s Computational coordinates of the bubbles + subroutine s_build_cell_list(nBubs, lbk_s) - strength_vol = volpart - strength_vel = 4._wp*pi*lbk_rad(l, 2)**2._wp*lbk_vel(l, 2) + integer, intent(in) :: nBubs + real(wp), dimension(1:lag_params%nBubs_glb, 1:3, 1:2), intent(in) :: lbk_s - if (num_dims == 2) then - Vol = dx(cell(1))*dy(cell(2))*lag_params%charwidth - if (cyl_coord) Vol = dx(cell(1))*dy(cell(2))*y_cc(cell(2))*2._wp*pi - else - Vol = dx(cell(1))*dy(cell(2))*dz(cell(3)) - end if + integer :: l, ci, cj, ck, idx + real(wp), dimension(3) :: s_coord - ! Update void fraction field - addFun1 = strength_vol/Vol - $:GPU_ATOMIC(atomic='update') - updatedvar(1)%sf(cell(1), cell(2), cell(3)) = updatedvar(1)%sf(cell(1), cell(2), cell(3)) + real(addFun1, kind=stp) - - ! Update time derivative of void fraction - addFun2 = strength_vel/Vol - $:GPU_ATOMIC(atomic='update') - updatedvar(2)%sf(cell(1), cell(2), cell(3)) = updatedvar(2)%sf(cell(1), cell(2), cell(3)) + real(addFun2, kind=stp) - - ! Product of two smeared functions Update void fraction * time derivative of void fraction - if (lag_params%cluster_type >= 4) then - addFun3 = (strength_vol*strength_vel)/Vol - $:GPU_ATOMIC(atomic='update') - updatedvar(5)%sf(cell(1), cell(2), cell(3)) = updatedvar(5)%sf(cell(1), cell(2), cell(3)) + real(addFun3, kind=stp) - end if + ! Bring current bubble positions to host + $:GPU_UPDATE(host='[lbk_s]') + + ! Pass 1: zero counts and count bubbles per cell + cell_list_count = 0 + do l = 1, nBubs + s_coord(1:3) = lbk_s(l, 1:3, 2) + ci = int(s_coord(1)) + cj = int(s_coord(2)) + ck = int(s_coord(3)) + ! Clamp to interior (bubbles should already be in [0:m,0:n,0:p]) + ci = max(0, min(ci, m)) + cj = max(0, min(cj, n)) + ck = max(0, min(ck, p)) + cell_list_count(ci, cj, ck) = cell_list_count(ci, cj, ck) + 1 end do - $:END_GPU_PARALLEL_LOOP() - end subroutine s_deltafunc + ! Prefix sum to compute start indices (1-based into cell_list_idx) + idx = 1 + do ck = 0, p + do cj = 0, n + do ci = 0, m + cell_list_start(ci, cj, ck) = idx + idx = idx + cell_list_count(ci, cj, ck) + end do + end do + end do - !> Apply the Gaussian kernel function to smear bubble effects onto surrounding cells - subroutine s_gaussian(nBubs, lbk_rad, lbk_vel, lbk_s, lbk_pos, updatedvar) - - integer, intent(in) :: nBubs - real(wp), dimension(1:lag_params%nBubs_glb,1:3,1:2), intent(in) :: lbk_s, lbk_pos - real(wp), dimension(1:lag_params%nBubs_glb,1:2), intent(in) :: lbk_rad, lbk_vel - type(scalar_field), dimension(:), intent(inout) :: updatedvar - real(wp), dimension(3) :: center - integer, dimension(3) :: cell - real(wp) :: stddsv - real(wp) :: strength_vel, strength_vol - real(wp), dimension(3) :: nodecoord - real(wp) :: addFun1, addFun2, addFun3 - real(wp) :: func, func2, volpart - integer, dimension(3) :: cellaux - real(wp), dimension(3) :: s_coord - integer :: l, i, j, k - logical :: celloutside - integer :: smearGrid, smearGridz - - smearGrid = mapCells - (-mapCells) + 1 ! Include the cell that contains the bubble (3+1+3) - smearGridz = smearGrid - if (p == 0) smearGridz = 1 - - $:GPU_PARALLEL_LOOP(private='[nodecoord, l, s_coord, cell, center]', copyin='[smearGrid, smearGridz]') + ! Pass 2: place bubble indices into cell_list_idx + ! Temporarily reuse cell_list_count as a running offset + cell_list_count = 0 do l = 1, nBubs - nodecoord(1:3) = 0 - center(1:3) = 0._wp - volpart = 4._wp/3._wp*pi*lbk_rad(l, 2)**3._wp - s_coord(1:3) = lbk_s(l,1:3,2) - center(1:2) = lbk_pos(l,1:2,2) - if (p > 0) center(3) = lbk_pos(l, 3, 2) - call s_get_cell(s_coord, cell) - call s_compute_stddsv(cell, volpart, stddsv) - - strength_vol = volpart - strength_vel = 4._wp*pi*lbk_rad(l, 2)**2._wp*lbk_vel(l, 2) - - $:GPU_LOOP(collapse=3,private='[cellaux, nodecoord]') - do i = 1, smearGrid - do j = 1, smearGrid - do k = 1, smearGridz - cellaux(1) = cell(1) + i - (mapCells + 1) - cellaux(2) = cell(2) + j - (mapCells + 1) - cellaux(3) = cell(3) + k - (mapCells + 1) - if (p == 0) cellaux(3) = 0 - - ! Check if the cells intended to smear the bubbles in are in the computational domain and redefine the cells - ! for symmetric boundary - call s_check_celloutside(cellaux, celloutside) - - if (.not. celloutside) then - nodecoord(1) = x_cc(cellaux(1)) - nodecoord(2) = y_cc(cellaux(2)) - if (p > 0) nodecoord(3) = z_cc(cellaux(3)) - call s_applygaussian(center, cellaux, nodecoord, stddsv, 0._wp, func) - if (lag_params%cluster_type >= 4) call s_applygaussian(center, cellaux, nodecoord, stddsv, 1._wp, func2) - - ! Relocate cells for bubbles intersecting symmetric boundaries - if (any((/bc_x%beg, bc_x%end, bc_y%beg, bc_y%end, bc_z%beg, bc_z%end/) == BC_REFLECTIVE)) then - call s_shift_cell_symmetric_bc(cellaux, cell) - end if - else - func = 0._wp - func2 = 0._wp - cellaux(1) = cell(1) - cellaux(2) = cell(2) - cellaux(3) = cell(3) - if (p == 0) cellaux(3) = 0 + s_coord(1:3) = lbk_s(l, 1:3, 2) + ci = int(s_coord(1)) + cj = int(s_coord(2)) + ck = int(s_coord(3)) + ci = max(0, min(ci, m)) + cj = max(0, min(cj, n)) + ck = max(0, min(ck, p)) + cell_list_idx(cell_list_start(ci, cj, ck) + cell_list_count(ci, cj, ck)) = l + cell_list_count(ci, cj, ck) = cell_list_count(ci, cj, ck) + 1 + end do + + ! Send cell list arrays to GPU + $:GPU_UPDATE(device='[cell_list_start, cell_list_count, cell_list_idx]') + + end subroutine s_build_cell_list + + !> Cell-centric delta-function smearing using the cell list (no GPU atomics). + !! Each bubble only affects the cell it resides in. The outer GPU loop + !! iterates over interior cells and sums contributions from resident bubbles. + subroutine s_deltafunc(nBubs, lbk_rad, lbk_vel, lbk_s, updatedvar, kcomp) + + integer, intent(in) :: nBubs + real(wp), dimension(1:lag_params%nBubs_glb, 1:3, 1:2), intent(in) :: lbk_s + real(wp), dimension(1:lag_params%nBubs_glb, 1:2), intent(in) :: lbk_rad, lbk_vel + type(scalar_field), dimension(:), intent(inout) :: updatedvar + type(scalar_field), dimension(:), intent(inout) :: kcomp + + real(wp) :: strength_vel, strength_vol + real(wp) :: volpart, Vol + real(wp) :: y_kahan, t_kahan + integer :: i, j, k, lb, bub_idx + + $:GPU_PARALLEL_LOOP(collapse=3, private='[i,j,k,lb,bub_idx,volpart,Vol,strength_vel,strength_vol,y_kahan,t_kahan]') + do k = 0, p + do j = 0, n + do i = 0, m + + ! Cell volume + if (num_dims == 2) then + Vol = dx(i)*dy(j)*lag_params%charwidth + if (cyl_coord) Vol = dx(i)*dy(j)*y_cc(j)*2._wp*pi + else + Vol = dx(i)*dy(j)*dz(k) + end if + + ! Loop over bubbles in this cell + $:GPU_LOOP(parallelism='[seq]') + do lb = cell_list_start(i, j, k), & + cell_list_start(i, j, k) + cell_list_count(i, j, k) - 1 + + bub_idx = cell_list_idx(lb) + + volpart = 4._wp/3._wp*pi*lbk_rad(bub_idx, 2)**3._wp + strength_vol = volpart + strength_vel = 4._wp*pi*lbk_rad(bub_idx, 2)**2._wp*lbk_vel(bub_idx, 2) + + ! Kahan summation for void fraction + y_kahan = real(strength_vol/Vol, kind=wp) - kcomp(1)%sf(i, j, k) + t_kahan = updatedvar(1)%sf(i, j, k) + y_kahan + kcomp(1)%sf(i, j, k) = (t_kahan - updatedvar(1)%sf(i, j, k)) - y_kahan + updatedvar(1)%sf(i, j, k) = t_kahan + + ! Kahan summation for time derivative of void fraction + y_kahan = real(strength_vel/Vol, kind=wp) - kcomp(2)%sf(i, j, k) + t_kahan = updatedvar(2)%sf(i, j, k) + y_kahan + kcomp(2)%sf(i, j, k) = (t_kahan - updatedvar(2)%sf(i, j, k)) - y_kahan + updatedvar(2)%sf(i, j, k) = t_kahan + + ! Product of two smeared functions + if (lag_params%cluster_type >= 4) then + y_kahan = real((strength_vol*strength_vel)/Vol, kind=wp) - kcomp(5)%sf(i, j, k) + t_kahan = updatedvar(5)%sf(i, j, k) + y_kahan + kcomp(5)%sf(i, j, k) = (t_kahan - updatedvar(5)%sf(i, j, k)) - y_kahan + updatedvar(5)%sf(i, j, k) = t_kahan end if + end do - ! Update void fraction field - addFun1 = func*strength_vol - $:GPU_ATOMIC(atomic='update') - updatedvar(1)%sf(cellaux(1), cellaux(2), cellaux(3)) = updatedvar(1)%sf(cellaux(1), cellaux(2), & - & cellaux(3)) + real(addFun1, kind=stp) + end do + end do + end do + $:END_GPU_PARALLEL_LOOP() - ! Update time derivative of void fraction - addFun2 = func*strength_vel - $:GPU_ATOMIC(atomic='update') - updatedvar(2)%sf(cellaux(1), cellaux(2), cellaux(3)) = updatedvar(2)%sf(cellaux(1), cellaux(2), & - & cellaux(3)) + real(addFun2, kind=stp) + end subroutine s_deltafunc - ! Product of two smeared functions Update void fraction * time derivative of void fraction - if (lag_params%cluster_type >= 4) then - addFun3 = func2*strength_vol*strength_vel - $:GPU_ATOMIC(atomic='update') - updatedvar(5)%sf(cellaux(1), cellaux(2), cellaux(3)) = updatedvar(5)%sf(cellaux(1), cellaux(2), & - & cellaux(3)) + real(addFun3, kind=stp) - end if + !> Cell-centric gaussian smearing using the cell list (no GPU atomics). + !! Each grid cell accumulates contributions from nearby bubbles looked up + !! via cell_list_start/count/idx. + subroutine s_gaussian(nBubs, lbk_rad, lbk_vel, lbk_s, lbk_pos, updatedvar, kcomp) + + integer, intent(in) :: nBubs + real(wp), dimension(1:lag_params%nBubs_glb, 1:3, 1:2), intent(in) :: lbk_s, lbk_pos + real(wp), dimension(1:lag_params%nBubs_glb, 1:2), intent(in) :: lbk_rad, lbk_vel + type(scalar_field), dimension(:), intent(inout) :: updatedvar + type(scalar_field), dimension(:), intent(inout) :: kcomp + + real(wp), dimension(3) :: center, nodecoord, s_coord + integer, dimension(3) :: cell, cellijk + real(wp) :: stddsv, volpart + real(wp) :: strength_vel, strength_vol + real(wp) :: func, func2 + real(wp) :: y_kahan, t_kahan + integer :: i, j, k, di, dj, dk, lb, bub_idx + integer :: di_beg, di_end, dj_beg, dj_end, dk_beg, dk_end + integer :: smear_x_beg, smear_x_end + integer :: smear_y_beg, smear_y_end + integer :: smear_z_beg, smear_z_end + + ! Extended grid range for smearing (includes buffer cells for MPI communication) + smear_x_beg = -mapCells - 1 + smear_x_end = m + mapCells + 1 + smear_y_beg = merge(-mapCells - 1, 0, n > 0) + smear_y_end = merge(n + mapCells + 1, n, n > 0) + smear_z_beg = merge(-mapCells - 1, 0, p > 0) + smear_z_end = merge(p + mapCells + 1, p, p > 0) + + $:GPU_PARALLEL_LOOP(collapse=3, & + & private='[i,j,k,di,dj,dk,lb,bub_idx,center,nodecoord,s_coord,cell,cellijk,stddsv,volpart,strength_vel,strength_vol,func,func2,y_kahan,t_kahan,di_beg,di_end,dj_beg,dj_end,dk_beg,dk_end]', & + & copyin='[smear_x_beg,smear_x_end,smear_y_beg,smear_y_end,smear_z_beg,smear_z_end]') + do k = smear_z_beg, smear_z_end + do j = smear_y_beg, smear_y_end + do i = smear_x_beg, smear_x_end + + cellijk(1) = i + cellijk(2) = j + cellijk(3) = k + + nodecoord(1) = x_cc(i) + nodecoord(2) = y_cc(j) + nodecoord(3) = 0._wp + if (p > 0) nodecoord(3) = z_cc(k) + + ! Neighbor cell range clamped to interior [0:m, 0:n, 0:p] + di_beg = max(i - mapCells, 0) + di_end = min(i + mapCells, m) + dj_beg = max(j - mapCells, 0) + dj_end = min(j + mapCells, n) + dk_beg = max(k - mapCells, 0) + dk_end = min(k + mapCells, p) + + $:GPU_LOOP(parallelism='[seq]') + do dk = dk_beg, dk_end + $:GPU_LOOP(parallelism='[seq]') + do dj = dj_beg, dj_end + $:GPU_LOOP(parallelism='[seq]') + do di = di_beg, di_end + $:GPU_LOOP(parallelism='[seq]') + do lb = cell_list_start(di, dj, dk), & + cell_list_start(di, dj, dk) + cell_list_count(di, dj, dk) - 1 + + bub_idx = cell_list_idx(lb) + + ! Bubble properties + volpart = 4._wp/3._wp*pi*lbk_rad(bub_idx, 2)**3._wp + s_coord(1:3) = lbk_s(bub_idx, 1:3, 2) + call s_get_cell(s_coord, cell) + call s_compute_stddsv(cell, volpart, stddsv) + + strength_vol = volpart + strength_vel = 4._wp*pi*lbk_rad(bub_idx, 2)**2._wp*lbk_vel(bub_idx, 2) + + center(1:2) = lbk_pos(bub_idx, 1:2, 2) + center(3) = 0._wp + if (p > 0) center(3) = lbk_pos(bub_idx, 3, 2) + + call s_applygaussian(center, cellijk, nodecoord, stddsv, 0._wp, func) + + ! Kahan summation for void fraction + y_kahan = real(func*strength_vol, kind=wp) - kcomp(1)%sf(i, j, k) + t_kahan = updatedvar(1)%sf(i, j, k) + y_kahan + kcomp(1)%sf(i, j, k) = (t_kahan - updatedvar(1)%sf(i, j, k)) - y_kahan + updatedvar(1)%sf(i, j, k) = t_kahan + + ! Kahan summation for time derivative of void fraction + y_kahan = real(func*strength_vel, kind=wp) - kcomp(2)%sf(i, j, k) + t_kahan = updatedvar(2)%sf(i, j, k) + y_kahan + kcomp(2)%sf(i, j, k) = (t_kahan - updatedvar(2)%sf(i, j, k)) - y_kahan + updatedvar(2)%sf(i, j, k) = t_kahan + + if (lag_params%cluster_type >= 4) then + call s_applygaussian(center, cellijk, nodecoord, stddsv, 1._wp, func2) + y_kahan = real(func2*strength_vol*strength_vel, kind=wp) - kcomp(5)%sf(i, j, k) + t_kahan = updatedvar(5)%sf(i, j, k) + y_kahan + kcomp(5)%sf(i, j, k) = (t_kahan - updatedvar(5)%sf(i, j, k)) - y_kahan + updatedvar(5)%sf(i, j, k) = t_kahan + end if + + end do + end do + end do end do + end do end do end do @@ -179,29 +297,31 @@ contains end subroutine s_gaussian - !> Evaluate the Gaussian kernel at a grid node for a given bubble center + !> The purpose of this subroutine is to apply the gaussian kernel function for each bubble (Maeda and Colonius, 2018)). subroutine s_applygaussian(center, cellaux, nodecoord, stddsv, strength_idx, func) - - $:GPU_ROUTINE(function_name='s_applygaussian',parallelism='[seq]', cray_inline=True) + $:GPU_ROUTINE(function_name='s_applygaussian',parallelism='[seq]', & + & cray_inline=True) real(wp), dimension(3), intent(in) :: center - integer, dimension(3), intent(in) :: cellaux + integer, dimension(3), intent(in) :: cellaux real(wp), dimension(3), intent(in) :: nodecoord - real(wp), intent(in) :: stddsv - real(wp), intent(in) :: strength_idx - real(wp), intent(out) :: func - real(wp) :: distance - real(wp) :: theta, dtheta, L2, dzp, Lz2 - real(wp) :: Nr, Nr_count + real(wp), intent(in) :: stddsv + real(wp), intent(in) :: strength_idx + real(wp), intent(out) :: func + integer :: i + + real(wp) :: distance + real(wp) :: theta, dtheta, L2, dzp, Lz2, zc + real(wp) :: Nr, Nr_count distance = sqrt((center(1) - nodecoord(1))**2._wp + (center(2) - nodecoord(2))**2._wp + (center(3) - nodecoord(3))**2._wp) if (num_dims == 3) then - !> 3D gaussian function + !< 3D gaussian function func = exp(-0.5_wp*(distance/stddsv)**2._wp)/(sqrt(2._wp*pi)*stddsv)**3._wp else if (cyl_coord) then - !> 2D cylindrical function: + !< 2D cylindrical function: ! We smear particles in the azimuthal direction for given r theta = 0._wp Nr = ceiling(2._wp*pi*nodecoord(2)/(y_cb(cellaux(2)) - y_cb(cellaux(2) - 1))) @@ -218,38 +338,35 @@ contains L2 = center(2)**2._wp + nodecoord(2)**2._wp - 2._wp*center(2)*nodecoord(2)*cos(theta) distance = sqrt((center(1) - nodecoord(1))**2._wp + L2) ! nodecoord(2)*dtheta is the azimuthal width of the cell - func = func + dtheta/2._wp/pi*exp(-0.5_wp*(distance/stddsv)**2._wp)/(sqrt(2._wp*pi)*stddsv) & - & **(3._wp*(strength_idx + 1._wp)) + func = func + & + dtheta/2._wp/pi*exp(-0.5_wp*(distance/stddsv)**2._wp)/(sqrt(2._wp*pi)*stddsv)**(3._wp*(strength_idx + 1._wp)) end do else - !> 2D cartesian function: - ! We smear particles considering a virtual depth (lag_params%charwidth) - theta = 0._wp - Nr = ceiling(lag_params%charwidth/(y_cb(cellaux(2)) - y_cb(cellaux(2) - 1))) - Nr_count = 1._wp - mapCells*1._wp - dzp = y_cb(cellaux(2) + 1) - y_cb(cellaux(2)) - Lz2 = (center(3) - (dzp*(0.5_wp + Nr_count) - lag_params%charwidth/2._wp))**2._wp - distance = sqrt((center(1) - nodecoord(1))**2._wp + (center(2) - nodecoord(2))**2._wp + Lz2) - func = dzp/lag_params%charwidth*exp(-0.5_wp*(distance/stddsv)**2._wp)/(sqrt(2._wp*pi)*stddsv)**3._wp - do while (Nr_count < Nr - 1._wp + ((mapCells - 1)*1._wp)) - Nr_count = Nr_count + 1._wp - Lz2 = (center(3) - (dzp*(0.5_wp + Nr_count) - lag_params%charwidth/2._wp))**2._wp + !< 2D cartesian function: Equation (48) from Madea and Colonius 2018 + ! We smear particles considering a virtual depth (lag_params%charwidth) with lag_params%charNz cells + dzp = (lag_params%charwidth/(lag_params%charNz + 1._wp)) + + func = 0._wp + do i = 0, lag_params%charNz + zc = (-lag_params%charwidth/2._wp + dzp*(0.5_wp + i)) ! Center of virtual cell i in z-direction + Lz2 = (center(3) - zc)**2._wp distance = sqrt((center(1) - nodecoord(1))**2._wp + (center(2) - nodecoord(2))**2._wp + Lz2) - func = func + dzp/lag_params%charwidth*exp(-0.5_wp*(distance/stddsv)**2._wp)/(sqrt(2._wp*pi)*stddsv) & - & **(3._wp*(strength_idx + 1._wp)) + func = func + dzp/lag_params%charwidth*exp(-0.5_wp*(distance/stddsv)**2._wp)/(sqrt(2._wp*pi)*stddsv)**3._wp end do end if end if end subroutine s_applygaussian - !> Check if the current cell is outside the computational domain including ghost cells + !> The purpose of this subroutine is to check if the current cell is outside the computational domain or not (including ghost cells). + !! @param cellaux Tested cell to smear the bubble effect in. + !! @param celloutside If true, then cellaux is outside the computational domain. subroutine s_check_celloutside(cellaux, celloutside) - - $:GPU_ROUTINE(function_name='s_check_celloutside',parallelism='[seq]', cray_inline=True) + $:GPU_ROUTINE(function_name='s_check_celloutside',parallelism='[seq]', & + & cray_inline=True) integer, dimension(3), intent(inout) :: cellaux - logical, intent(out) :: celloutside + logical, intent(out) :: celloutside celloutside = .false. @@ -275,13 +392,15 @@ contains end subroutine s_check_celloutside - !> Relocate cells that intersect a symmetric boundary + !> This subroutine relocates the current cell, if it intersects a symmetric boundary. + !! @param cell Cell of the current bubble + !! @param cellaux Cell to map the bubble effect in. subroutine s_shift_cell_symmetric_bc(cellaux, cell) - - $:GPU_ROUTINE(function_name='s_shift_cell_symmetric_bc', parallelism='[seq]', cray_inline=True) + $:GPU_ROUTINE(function_name='s_shift_cell_symmetric_bc', & + & parallelism='[seq]', cray_inline=True) integer, dimension(3), intent(inout) :: cellaux - integer, dimension(3), intent(in) :: cell + integer, dimension(3), intent(in) :: cell ! x-dir if (bc_x%beg == BC_REFLECTIVE .and. (cell(1) <= mapCells - 1)) then @@ -291,7 +410,7 @@ contains cellaux(1) = cellaux(1) - (2*(cellaux(1) - m) - 1) end if - ! y-dir + !y-dir if (bc_y%beg == BC_REFLECTIVE .and. (cell(2) <= mapCells - 1)) then cellaux(2) = abs(cellaux(2)) - 1 end if @@ -300,7 +419,7 @@ contains end if if (p > 0) then - ! z-dir + !z-dir if (bc_z%beg == BC_REFLECTIVE .and. (cell(3) <= mapCells - 1)) then cellaux(3) = abs(cellaux(3)) - 1 end if @@ -312,21 +431,25 @@ contains end subroutine s_shift_cell_symmetric_bc !> Calculates the standard deviation of the bubble being smeared in the Eulerian framework. + !! @param cell Cell where the bubble is located + !! @param volpart Volume of the bubble + !! @param stddsv Standard deviaton subroutine s_compute_stddsv(cell, volpart, stddsv) - - $:GPU_ROUTINE(function_name='s_compute_stddsv',parallelism='[seq]', cray_inline=True) + $:GPU_ROUTINE(function_name='s_compute_stddsv',parallelism='[seq]', & + & cray_inline=True) integer, dimension(3), intent(in) :: cell - real(wp), intent(in) :: volpart - real(wp), intent(out) :: stddsv - real(wp) :: chardist, charvol - real(wp) :: rad + real(wp), intent(in) :: volpart + real(wp), intent(out) :: stddsv - !> Compute characteristic distance + real(wp) :: chardist, charvol + real(wp) :: rad + + !< Compute characteristic distance chardist = sqrt(dx(cell(1))*dy(cell(2))) if (p > 0) chardist = (dx(cell(1))*dy(cell(2))*dz(cell(3)))**(1._wp/3._wp) - !> Compute characteristic volume + !< Compute characteristic volume if (p > 0) then charvol = dx(cell(1))*dy(cell(2))*dz(cell(3)) else @@ -337,8 +460,8 @@ contains end if end if - !> Compute Standard deviaton - if (((volpart/charvol) > 0.5_wp*lag_params%valmaxvoid) .or. (lag_params%smooth_type == 1)) then + !< Compute Standard deviaton + if ((volpart/charvol) > 0.5_wp*lag_params%valmaxvoid .or. (lag_params%smooth_type == 1)) then rad = (3._wp*volpart/(4._wp*pi))**(1._wp/3._wp) stddsv = 1._wp*lag_params%epsilonb*max(chardist, rad) else @@ -347,12 +470,16 @@ contains end subroutine s_compute_stddsv - !> Compute the characteristic cell volume + !> The purpose of this procedure is to calculate the characteristic cell volume + !! @param cellx x-direction cell index + !! @param celly y-direction cell index + !! @param cellz z-direction cell index + !! @param Charvol Characteristic volume subroutine s_get_char_vol(cellx, celly, cellz, Charvol) + $:GPU_ROUTINE(function_name='s_get_char_vol',parallelism='[seq]', & + & cray_inline=True) - $:GPU_ROUTINE(function_name='s_get_char_vol',parallelism='[seq]', cray_inline=True) - - integer, intent(in) :: cellx, celly, cellz + integer, intent(in) :: cellx, celly, cellz real(wp), intent(out) :: Charvol if (p > 0) then @@ -367,14 +494,17 @@ contains end subroutine s_get_char_vol - !> Convert bubble computational coordinates from real to integer cell indices + !> This subroutine transforms the computational coordinates of the bubble from + !! real type into integer. + !! @param s_cell Computational coordinates of the bubble, real type + !! @param get_cell Computational coordinates of the bubble, integer type subroutine s_get_cell(s_cell, get_cell) - - $:GPU_ROUTINE(function_name='s_get_cell',parallelism='[seq]', cray_inline=True) + $:GPU_ROUTINE(function_name='s_get_cell',parallelism='[seq]', & + & cray_inline=True) real(wp), dimension(3), intent(in) :: s_cell integer, dimension(3), intent(out) :: get_cell - integer :: i + integer :: i get_cell(:) = int(s_cell(:)) do i = 1, num_dims @@ -383,4 +513,227 @@ contains end subroutine s_get_cell + !> Precomputes cell-centered pressure gradients (dp/dx, dp/dy, dp/dz) at all cell centers + !! using finite-difference coefficients of the specified order. This avoids + !! scattered memory accesses to the pressure field when computing translational + !! bubble forces. + !! @param q_prim_vf Primitive variables (pressure is at index E_idx) + subroutine s_compute_pressure_gradients(q_prim_vf) + + type(scalar_field), dimension(sys_size), intent(in) :: q_prim_vf + + integer :: i, j, k, r + + ! dp/dx at all cell centers + $:GPU_PARALLEL_LOOP(private='[i,j,k,r]', collapse=3) + do k = 0, p + do j = 0, n + do i = 0, m + grad_p_x(i, j, k) = 0._wp + $:GPU_LOOP(parallelism='[seq]') + do r = -fd_number, fd_number + grad_p_x(i, j, k) = grad_p_x(i, j, k) + & + q_prim_vf(E_idx)%sf(i + r, j, k)*fd_coeff_x_pgrad(r, i) + end do + end do + end do + end do + $:END_GPU_PARALLEL_LOOP() + + ! dp/dy at all cell centers + if (n > 0) then + $:GPU_PARALLEL_LOOP(private='[i,j,k,r]', collapse=3) + do k = 0, p + do j = 0, n + do i = 0, m + grad_p_y(i, j, k) = 0._wp + $:GPU_LOOP(parallelism='[seq]') + do r = -fd_number, fd_number + grad_p_y(i, j, k) = grad_p_y(i, j, k) + & + q_prim_vf(E_idx)%sf(i, j + r, k)*fd_coeff_y_pgrad(r, j) + end do + end do + end do + end do + $:END_GPU_PARALLEL_LOOP() + end if + + ! dp/dz at all cell centers + if (p > 0) then + $:GPU_PARALLEL_LOOP(private='[i,j,k,r]', collapse=3) + do k = 0, p + do j = 0, n + do i = 0, m + grad_p_z(i, j, k) = 0._wp + $:GPU_LOOP(parallelism='[seq]') + do r = -fd_number, fd_number + grad_p_z(i, j, k) = grad_p_z(i, j, k) + & + q_prim_vf(E_idx)%sf(i, j, k + r)*fd_coeff_z_pgrad(r, k) + end do + end do + end do + end do + $:END_GPU_PARALLEL_LOOP() + end if + + end subroutine s_compute_pressure_gradients + + !! This function interpolates the velocity of Eulerian field at the position + !! of the bubble. + !! @param pos Position of the bubble in directiion i + !! @param cell Computational coordinates of the bubble + !! @param i Direction of the velocity (1: x, 2: y, 3: z) + !! @param q_prim_vf Eulerian field with primitive variables + !! @return v Interpolated velocity at the position of the bubble + function f_interpolate_velocity(pos, cell, i, q_prim_vf) result(v) + $:GPU_ROUTINE(parallelism='[seq]') + real(wp), intent(in) :: pos + integer, dimension(3), intent(in) :: cell + integer, intent(in) :: i + type(scalar_field), dimension(sys_size), intent(in) :: q_prim_vf + + real(wp) :: v + real(wp), dimension(fd_order + 1) :: xi, eta, L + + if (fd_order == 2) then + if (i == 1) then + xi(1) = x_cc(cell(1) - 1) + eta(1) = q_prim_vf(momxb)%sf(cell(1) - 1, cell(2), cell(3)) + xi(2) = x_cc(cell(1)) + eta(2) = q_prim_vf(momxb)%sf(cell(1), cell(2), cell(3)) + xi(3) = x_cc(cell(1) + 1) + eta(3) = q_prim_vf(momxb)%sf(cell(1) + 1, cell(2), cell(3)) + elseif (i == 2) then + xi(1) = y_cc(cell(2) - 1) + eta(1) = q_prim_vf(momxb + 1)%sf(cell(1), cell(2) - 1, cell(3)) + xi(2) = y_cc(cell(2)) + eta(2) = q_prim_vf(momxb + 1)%sf(cell(1), cell(2), cell(3)) + xi(3) = y_cc(cell(2) + 1) + eta(3) = q_prim_vf(momxb + 1)%sf(cell(1), cell(2) + 1, cell(3)) + elseif (i == 3) then + xi(1) = z_cc(cell(3) - 1) + eta(1) = q_prim_vf(momxe)%sf(cell(1), cell(2), cell(3) - 1) + xi(2) = z_cc(cell(3)) + eta(2) = q_prim_vf(momxe)%sf(cell(1), cell(2), cell(3)) + xi(3) = z_cc(cell(3) + 1) + eta(3) = q_prim_vf(momxe)%sf(cell(1), cell(2), cell(3) + 1) + end if + + L(1) = ((pos - xi(2))*(pos - xi(3)))/((xi(1) - xi(2))*(xi(1) - xi(3))) + L(2) = ((pos - xi(1))*(pos - xi(3)))/((xi(2) - xi(1))*(xi(2) - xi(3))) + L(3) = ((pos - xi(1))*(pos - xi(2)))/((xi(3) - xi(1))*(xi(3) - xi(2))) + + v = L(1)*eta(1) + L(2)*eta(2) + L(3)*eta(3) + elseif (fd_order == 4) then + if (i == 1) then + xi(1) = x_cc(cell(1) - 2) + eta(1) = q_prim_vf(momxb)%sf(cell(1) - 2, cell(2), cell(3)) + xi(2) = x_cc(cell(1) - 1) + eta(2) = q_prim_vf(momxb)%sf(cell(1) - 1, cell(2), cell(3)) + xi(3) = x_cc(cell(1)) + eta(3) = q_prim_vf(momxb)%sf(cell(1), cell(2), cell(3)) + xi(4) = x_cc(cell(1) + 1) + eta(4) = q_prim_vf(momxb)%sf(cell(1) + 1, cell(2), cell(3)) + xi(5) = x_cc(cell(1) + 2) + eta(5) = q_prim_vf(momxb)%sf(cell(1) + 2, cell(2), cell(3)) + elseif (i == 2) then + xi(1) = y_cc(cell(2) - 2) + eta(1) = q_prim_vf(momxb + 1)%sf(cell(1), cell(2) - 2, cell(3)) + xi(2) = y_cc(cell(2) - 1) + eta(2) = q_prim_vf(momxb + 1)%sf(cell(1), cell(2) - 1, cell(3)) + xi(3) = y_cc(cell(2)) + eta(3) = q_prim_vf(momxb + 1)%sf(cell(1), cell(2), cell(3)) + xi(4) = y_cc(cell(2) + 1) + eta(4) = q_prim_vf(momxb + 1)%sf(cell(1), cell(2) + 1, cell(3)) + xi(5) = y_cc(cell(2) + 2) + eta(5) = q_prim_vf(momxb + 1)%sf(cell(1), cell(2) + 2, cell(3)) + elseif (i == 3) then + xi(1) = z_cc(cell(3) - 2) + eta(1) = q_prim_vf(momxe)%sf(cell(1), cell(2), cell(3) - 2) + xi(2) = z_cc(cell(3) - 1) + eta(2) = q_prim_vf(momxe)%sf(cell(1), cell(2), cell(3) - 1) + xi(3) = z_cc(cell(3)) + eta(3) = q_prim_vf(momxe)%sf(cell(1), cell(2), cell(3)) + xi(4) = z_cc(cell(3) + 1) + eta(4) = q_prim_vf(momxe)%sf(cell(1), cell(2), cell(3) + 1) + xi(5) = z_cc(cell(3) + 2) + eta(5) = q_prim_vf(momxe)%sf(cell(1), cell(2), cell(3) + 2) + end if + + L(1) = ((pos - xi(2))*(pos - xi(3))*(pos - xi(4))*(pos - xi(5)))/ & + ((xi(1) - xi(2))*(xi(1) - xi(3))*(xi(1) - xi(4))*(xi(1) - xi(5))) + L(2) = ((pos - xi(1))*(pos - xi(3))*(pos - xi(4))*(pos - xi(5)))/ & + ((xi(2) - xi(1))*(xi(2) - xi(3))*(xi(2) - xi(4))*(xi(2) - xi(5))) + L(3) = ((pos - xi(1))*(pos - xi(2))*(pos - xi(4))*(pos - xi(5)))/ & + ((xi(3) - xi(1))*(xi(3) - xi(2))*(xi(3) - xi(4))*(xi(3) - xi(5))) + L(4) = ((pos - xi(1))*(pos - xi(2))*(pos - xi(3))*(pos - xi(5)))/ & + ((xi(4) - xi(1))*(xi(4) - xi(2))*(xi(4) - xi(3))*(xi(4) - xi(5))) + L(5) = ((pos - xi(1))*(pos - xi(2))*(pos - xi(3))*(pos - xi(4)))/ & + ((xi(5) - xi(1))*(xi(5) - xi(2))*(xi(5) - xi(3))*(xi(5) - xi(4))) + + v = L(1)*eta(1) + L(2)*eta(2) + L(3)*eta(3) + L(4)*eta(4) + L(5)*eta(5) + end if + + end function f_interpolate_velocity + + !! This function calculates the force on a bubble + !! based on the pressure gradient, velocity, and drag model. + !! @param pos Position of the bubble in direction i + !! @param rad Radius of the bubble + !! @param rdot Radial velocity of the bubble + !! @param vel Velocity of the bubble + !! @param mg Mass of the gas in the bubble + !! @param mv Mass of the liquid in the bubble + !! @param Re Reynolds number + !! @param rho Density of the fluid + !! @param cell Computational coordinates of the bubble + !! @param i Direction of the velocity (1: x, 2: y, 3: z) + !! @param q_prim_vf Eulerian field with primitive variables + !! @return a Acceleration of the bubble in direction i + function f_get_bubble_force(pos, rad, rdot, vel, mg, mv, Re, rho, cell, i, q_prim_vf) result(force) + $:GPU_ROUTINE(parallelism='[seq]') + real(wp), intent(in) :: pos, rad, rdot, mg, mv, Re, rho, vel + integer, dimension(3), intent(in) :: cell + integer, intent(in) :: i + type(scalar_field), dimension(sys_size), intent(in) :: q_prim_vf + + real(wp) :: dp, vol, force + real(wp) :: v_rel + + if (fd_order > 1) then + v_rel = vel - f_interpolate_velocity(pos, cell, i, q_prim_vf) + else + v_rel = vel - q_prim_vf(momxb + i - 1)%sf(cell(1), cell(2), cell(3)) + end if + + force = 0._wp + + if (lag_params%drag_model == 1) then ! Free slip Stokes drag + force = force - (4._wp*pi*rad*v_rel)/Re + else if (lag_params%drag_model == 2) then ! No slip Stokes drag + force = force - (6._wp*pi*rad*v_rel)/Re + else if (lag_params%drag_model == 3) then ! Levich drag + force = force - (12._wp*pi*rad*v_rel)/Re + end if + + if (lag_pressure_force) then + ! Use precomputed cell-centered pressure gradients + if (i == 1) then + dp = grad_p_x(cell(1), cell(2), cell(3)) + elseif (i == 2) then + dp = grad_p_y(cell(1), cell(2), cell(3)) + elseif (i == 3) then + dp = grad_p_z(cell(1), cell(2), cell(3)) + end if + + vol = (4._wp/3._wp)*pi*(rad**3._wp) + force = force - vol*dp + end if + + if (lag_params%gravity_force) then + force = force + (mg + mv)*accel_bf(i) + end if + + end function f_get_bubble_force + end module m_bubbles_EL_kernels diff --git a/src/simulation/m_cbc.fpp b/src/simulation/m_cbc.fpp index 0e36c48fbf..f5f9cb4c30 100644 --- a/src/simulation/m_cbc.fpp +++ b/src/simulation/m_cbc.fpp @@ -8,90 +8,110 @@ module m_cbc - use m_derived_types - use m_global_parameters - use m_variables_conversion + use m_derived_types !< Definitions of the derived types + + use m_global_parameters !< Definitions of the global parameters + + use m_variables_conversion !< State variables type conversion procedures + use m_compute_cbc - use m_thermochem, only: get_mixture_energy_mass, get_mixture_specific_heat_cv_mass, get_mixture_specific_heat_cp_mass, & - & gas_constant, get_mixture_molecular_weight, get_species_enthalpies_rt, molecular_weights, get_species_specific_heats_r, & - & get_mole_fractions, get_species_specific_heats_r + + use m_thermochem, only: & + get_mixture_energy_mass, get_mixture_specific_heat_cv_mass, & + get_mixture_specific_heat_cp_mass, gas_constant, & + get_mixture_molecular_weight, get_species_enthalpies_rt, & + molecular_weights, get_species_specific_heats_r, & + get_mole_fractions, get_species_specific_heats_r #:if USING_AMD use m_chemistry, only: molecular_weights_nonparameter #:endif - implicit none private; public :: s_initialize_cbc_module, s_cbc, s_finalize_cbc_module - ! The cell-average primitive variables. They are obtained by reshaping (RS) q_prim_vf in the coordinate direction normal to the - ! domain boundary along which the CBC is applied. + !! The cell-average primitive variables. They are obtained by reshaping (RS) + !! q_prim_vf in the coordinate direction normal to the domain boundary along + !! which the CBC is applied. + + real(wp), allocatable, dimension(:, :, :, :) :: q_prim_rsx_vf + real(wp), allocatable, dimension(:, :, :, :) :: q_prim_rsy_vf + real(wp), allocatable, dimension(:, :, :, :) :: q_prim_rsz_vf + $:GPU_DECLARE(create='[q_prim_rsx_vf,q_prim_rsy_vf,q_prim_rsz_vf]') - real(wp), allocatable, dimension(:,:,:,:) :: q_prim_rsx_vf - real(wp), allocatable, dimension(:,:,:,:) :: q_prim_rsy_vf - real(wp), allocatable, dimension(:,:,:,:) :: q_prim_rsz_vf - $:GPU_DECLARE(create='[q_prim_rsx_vf, q_prim_rsy_vf, q_prim_rsz_vf]') + !! Cell-average fluxes (src - source). These are directly determined from the + !! cell-average primitive variables, q_prims_rs_vf, and not a Riemann solver. - ! Cell-average fluxes (src - source). These are directly determined from the cell-average primitive variables, q_prims_rs_vf, - ! and not a Riemann solver. + real(wp), allocatable, dimension(:, :, :, :) :: F_rsx_vf, F_src_rsx_vf !< + real(wp), allocatable, dimension(:, :, :, :) :: F_rsy_vf, F_src_rsy_vf !< + real(wp), allocatable, dimension(:, :, :, :) :: F_rsz_vf, F_src_rsz_vf !< + $:GPU_DECLARE(create='[F_rsx_vf,F_src_rsx_vf,F_rsy_vf,F_src_rsy_vf,F_rsz_vf,F_src_rsz_vf]') - real(wp), allocatable, dimension(:,:,:,:) :: F_rsx_vf, F_src_rsx_vf - real(wp), allocatable, dimension(:,:,:,:) :: F_rsy_vf, F_src_rsy_vf - real(wp), allocatable, dimension(:,:,:,:) :: F_rsz_vf, F_src_rsz_vf - $:GPU_DECLARE(create='[F_rsx_vf, F_src_rsx_vf, F_rsy_vf, F_src_rsy_vf, F_rsz_vf, F_src_rsz_vf]') + !! There is a CCE bug that is causing some subset of these variables to interfere + !! with variables of the same name in m_riemann_solvers.fpp, and giving this versions + !! unique "_l" names works around the bug. Other private module allocatable arrays + !! in `acc declare create` clauses don't have this problem, so we still need to + !! isolate this bug. - ! There is a CCE bug that is causing some subset of these variables to interfere with variables of the same name in - ! m_riemann_solvers.fpp, and giving this versions unique "_l" names works around the bug. Other private module allocatable - ! arrays in `acc declare create` clauses don't have this problem, so we still need to isolate this bug. + real(wp), allocatable, dimension(:, :, :, :) :: flux_rsx_vf_l, flux_src_rsx_vf_l !< + real(wp), allocatable, dimension(:, :, :, :) :: flux_rsy_vf_l, flux_src_rsy_vf_l + real(wp), allocatable, dimension(:, :, :, :) :: flux_rsz_vf_l, flux_src_rsz_vf_l + $:GPU_DECLARE(create='[flux_rsx_vf_l,flux_src_rsx_vf_l,flux_rsy_vf_l,flux_src_rsy_vf_l,flux_rsz_vf_l,flux_src_rsz_vf_l]') - real(wp), allocatable, dimension(:,:,:,:) :: flux_rsx_vf_l, flux_src_rsx_vf_l - real(wp), allocatable, dimension(:,:,:,:) :: flux_rsy_vf_l, flux_src_rsy_vf_l - real(wp), allocatable, dimension(:,:,:,:) :: flux_rsz_vf_l, flux_src_rsz_vf_l - $:GPU_DECLARE(create='[flux_rsx_vf_l, flux_src_rsx_vf_l, flux_rsy_vf_l, flux_src_rsy_vf_l, flux_rsz_vf_l, flux_src_rsz_vf_l]') + real(wp), allocatable, dimension(:) :: ds !< Cell-width distribution in the s-direction - real(wp), allocatable, dimension(:) :: ds !< Cell-width distribution in the s-direction ! CBC Coefficients - real(wp), allocatable, dimension(:,:) :: fd_coef_x !< Finite diff. coefficients x-dir - real(wp), allocatable, dimension(:,:) :: fd_coef_y !< Finite diff. coefficients y-dir - real(wp), allocatable, dimension(:,:) :: fd_coef_z !< Finite diff. coefficients, z-direction - ! Bug with NVHPC when using nullified pointers in a declare create real(wp), pointer, dimension(:, :) :: fd_coef => null() + real(wp), allocatable, dimension(:, :) :: fd_coef_x !< Finite diff. coefficients x-dir + real(wp), allocatable, dimension(:, :) :: fd_coef_y !< Finite diff. coefficients y-dir + real(wp), allocatable, dimension(:, :) :: fd_coef_z !< Finite diff. coefficients z-dir - real(wp), allocatable, dimension(:,:,:) :: pi_coef_x !< Polynomial interpolant coefficients in x-dir - real(wp), allocatable, dimension(:,:,:) :: pi_coef_y !< Polynomial interpolant coefficients in y-dir - real(wp), allocatable, dimension(:,:,:) :: pi_coef_z !< Polynomial interpolant coefficients in z-dir - $:GPU_DECLARE(create='[ds, fd_coef_x, fd_coef_y, fd_coef_z, pi_coef_x, pi_coef_y, pi_coef_z]') + !! The first dimension identifies the location of a coefficient in the FD + !! formula, while the last dimension denotes the location of the CBC. - ! The first dimension of the array identifies the polynomial, the second dimension identifies the position of its coefficients - ! and the last dimension denotes the location of the CBC. + ! Bug with NVHPC when using nullified pointers in a declare create + ! real(wp), pointer, dimension(:, :) :: fd_coef => null() - type(int_bounds_info) :: is1, is2, is3 !< Indical bounds in the s1-, s2- and s3-directions - $:GPU_DECLARE(create='[is1, is2, is3]') + real(wp), allocatable, dimension(:, :, :) :: pi_coef_x !< Polynomial interpolant coefficients in x-dir + real(wp), allocatable, dimension(:, :, :) :: pi_coef_y !< Polynomial interpolant coefficients in y-dir + real(wp), allocatable, dimension(:, :, :) :: pi_coef_z !< Polynomial interpolant coefficients in z-dir + + $:GPU_DECLARE(create='[ds,fd_coef_x,fd_coef_y,fd_coef_z,pi_coef_x,pi_coef_y,pi_coef_z]') + + !! The first dimension of the array identifies the polynomial, the + !! second dimension identifies the position of its coefficients and the last + !! dimension denotes the location of the CBC. + + type(int_bounds_info) :: is1, is2, is3 !< Indical bounds in the s1-, s2- and s3-directions + $:GPU_DECLARE(create='[is1,is2,is3]') integer :: dj integer :: bcxb, bcxe, bcyb, bcye, bczb, bcze integer :: cbc_dir, cbc_loc integer :: flux_cbc_index - $:GPU_DECLARE(create='[dj, bcxb, bcxe, bcyb, bcye, bczb, bcze]') - $:GPU_DECLARE(create='[cbc_dir, cbc_loc, flux_cbc_index]') + $:GPU_DECLARE(create='[dj,bcxb,bcxe,bcyb,bcye,bczb,bcze]') + $:GPU_DECLARE(create='[cbc_dir, cbc_loc,flux_cbc_index]') - ! GRCBC inputs for subsonic inflow and outflow conditions consisting of inflow velocities, pressure, density and void fraction - ! as well as outflow velocities and pressure + !! GRCBC inputs for subsonic inflow and outflow conditions consisting of + !! inflow velocities, pressure, density and void fraction as well as + !! outflow velocities and pressure - real(wp), allocatable, dimension(:) :: pres_in, pres_out, Del_in, Del_out - real(wp), allocatable, dimension(:,:) :: vel_in, vel_out - real(wp), allocatable, dimension(:,:) :: alpha_rho_in, alpha_in - $:GPU_DECLARE(create='[pres_in, pres_out, Del_in, Del_out]') - $:GPU_DECLARE(create='[vel_in, vel_out]') - $:GPU_DECLARE(create='[alpha_rho_in, alpha_in]') + real(wp), allocatable, dimension(:) :: pres_in, pres_out, Del_in, Del_out + real(wp), allocatable, dimension(:, :) :: vel_in, vel_out + real(wp), allocatable, dimension(:, :) :: alpha_rho_in, alpha_in + $:GPU_DECLARE(create='[pres_in,pres_out,Del_in,Del_out]') + $:GPU_DECLARE(create='[vel_in,vel_out]') + $:GPU_DECLARE(create='[alpha_rho_in,alpha_in]') contains - !> Initialize the CBC module + !> The computation of parameters, the allocation of memory, + !! the association of pointers and/or the execution of any + !! other procedures that are necessary to setup the module. impure subroutine s_initialize_cbc_module - integer :: i - logical :: is_cbc + integer :: i + logical :: is_cbc type(int_bounds_info) :: idx1, idx2 if (chemistry) then @@ -107,6 +127,7 @@ contains if (n == 0) then is2%beg = 0 + else is2%beg = -buff_size end if @@ -115,26 +136,41 @@ contains if (p == 0) then is3%beg = 0 + else is3%beg = -buff_size end if is3%end = p - is3%beg - @:ALLOCATE(q_prim_rsx_vf(0:buff_size, is2%beg:is2%end, is3%beg:is3%end, 1:sys_size)) + @:ALLOCATE(q_prim_rsx_vf(0:buff_size, & + is2%beg:is2%end, & + is3%beg:is3%end, 1:sys_size)) if (weno_order > 1 .or. muscl_order > 1) then - @:ALLOCATE(F_rsx_vf(0:buff_size, is2%beg:is2%end, is3%beg:is3%end, 1:flux_cbc_index)) - @:ALLOCATE(F_src_rsx_vf(0:buff_size, is2%beg:is2%end, is3%beg:is3%end, adv_idx%beg:adv_idx%end)) + @:ALLOCATE(F_rsx_vf(0:buff_size, & + is2%beg:is2%end, & + is3%beg:is3%end, 1:flux_cbc_index)) + + @:ALLOCATE(F_src_rsx_vf(0:buff_size, & + is2%beg:is2%end, & + is3%beg:is3%end, adv_idx%beg:adv_idx%end)) + end if - @:ALLOCATE(flux_rsx_vf_l(-1:buff_size, is2%beg:is2%end, is3%beg:is3%end, 1:flux_cbc_index)) + @:ALLOCATE(flux_rsx_vf_l(-1:buff_size, & + is2%beg:is2%end, & + is3%beg:is3%end, 1:flux_cbc_index)) - @:ALLOCATE(flux_src_rsx_vf_l(-1:buff_size, is2%beg:is2%end, is3%beg:is3%end, adv_idx%beg:adv_idx%end)) + @:ALLOCATE(flux_src_rsx_vf_l(-1:buff_size, & + is2%beg:is2%end, & + is3%beg:is3%end, adv_idx%beg:adv_idx%end)) if (n > 0) then + if (m == 0) then is2%beg = 0 + else is2%beg = -buff_size end if @@ -143,27 +179,43 @@ contains if (p == 0) then is3%beg = 0 + else is3%beg = -buff_size end if is3%end = p - is3%beg - @:ALLOCATE(q_prim_rsy_vf(0:buff_size, is2%beg:is2%end, is3%beg:is3%end, 1:sys_size)) + @:ALLOCATE(q_prim_rsy_vf(0:buff_size, & + is2%beg:is2%end, & + is3%beg:is3%end, 1:sys_size)) if (weno_order > 1 .or. muscl_order > 1) then - @:ALLOCATE(F_rsy_vf(0:buff_size, is2%beg:is2%end, is3%beg:is3%end, 1:flux_cbc_index)) - @:ALLOCATE(F_src_rsy_vf(0:buff_size, is2%beg:is2%end, is3%beg:is3%end, adv_idx%beg:adv_idx%end)) + @:ALLOCATE(F_rsy_vf(0:buff_size, & + is2%beg:is2%end, & + is3%beg:is3%end, 1:flux_cbc_index)) + + @:ALLOCATE(F_src_rsy_vf(0:buff_size, & + is2%beg:is2%end, & + is3%beg:is3%end, adv_idx%beg:adv_idx%end)) + end if - @:ALLOCATE(flux_rsy_vf_l(-1:buff_size, is2%beg:is2%end, is3%beg:is3%end, 1:flux_cbc_index)) + @:ALLOCATE(flux_rsy_vf_l(-1:buff_size, & + is2%beg:is2%end, & + is3%beg:is3%end, 1:flux_cbc_index)) + + @:ALLOCATE(flux_src_rsy_vf_l(-1:buff_size, & + is2%beg:is2%end, & + is3%beg:is3%end, adv_idx%beg:adv_idx%end)) - @:ALLOCATE(flux_src_rsy_vf_l(-1:buff_size, is2%beg:is2%end, is3%beg:is3%end, adv_idx%beg:adv_idx%end)) end if if (p > 0) then + if (n == 0) then is2%beg = 0 + else is2%beg = -buff_size end if @@ -172,22 +224,36 @@ contains if (m == 0) then is3%beg = 0 + else is3%beg = -buff_size end if is3%end = m - is3%beg - @:ALLOCATE(q_prim_rsz_vf(0:buff_size, is2%beg:is2%end, is3%beg:is3%end, 1:sys_size)) + @:ALLOCATE(q_prim_rsz_vf(0:buff_size, & + is2%beg:is2%end, & + is3%beg:is3%end, 1:sys_size)) if (weno_order > 1 .or. muscl_order > 1) then - @:ALLOCATE(F_rsz_vf(0:buff_size, is2%beg:is2%end, is3%beg:is3%end, 1:flux_cbc_index)) - @:ALLOCATE(F_src_rsz_vf(0:buff_size, is2%beg:is2%end, is3%beg:is3%end, adv_idx%beg:adv_idx%end)) + @:ALLOCATE(F_rsz_vf(0:buff_size, & + is2%beg:is2%end, & + is3%beg:is3%end, 1:flux_cbc_index)) + + @:ALLOCATE(F_src_rsz_vf(0:buff_size, & + is2%beg:is2%end, & + is3%beg:is3%end, adv_idx%beg:adv_idx%end)) + end if - @:ALLOCATE(flux_rsz_vf_l(-1:buff_size, is2%beg:is2%end, is3%beg:is3%end, 1:flux_cbc_index)) + @:ALLOCATE(flux_rsz_vf_l(-1:buff_size, & + is2%beg:is2%end, & + is3%beg:is3%end, 1:flux_cbc_index)) + + @:ALLOCATE(flux_src_rsz_vf_l(-1:buff_size, & + is2%beg:is2%end, & + is3%beg:is3%end, adv_idx%beg:adv_idx%end)) - @:ALLOCATE(flux_src_rsz_vf_l(-1:buff_size, is2%beg:is2%end, is3%beg:is3%end, adv_idx%beg:adv_idx%end)) end if ! Allocating the cell-width distribution in the s-direction @@ -206,6 +272,7 @@ contains end if ! Allocating/Computing CBC Coefficients in x-direction if (all((/bc_x%beg, bc_x%end/) <= -5) .and. all((/bc_x%beg, bc_x%end/) >= -13)) then + @:ALLOCATE(fd_coef_x(0:buff_size, -1:1)) if (weno_order > 1 .or. muscl_order > 1) then @@ -214,7 +281,9 @@ contains call s_compute_cbc_coefficients(1, -1) call s_compute_cbc_coefficients(1, 1) - else if (bc_x%beg <= -5 .and. bc_x%beg >= -13) then + + elseif (bc_x%beg <= -5 .and. bc_x%beg >= -13) then + @:ALLOCATE(fd_coef_x(0:buff_size, -1:-1)) if (weno_order > 1 .or. muscl_order > 1) then @@ -222,7 +291,9 @@ contains end if call s_compute_cbc_coefficients(1, -1) - else if (bc_x%end <= -5 .and. bc_x%end >= -13) then + + elseif (bc_x%end <= -5 .and. bc_x%end >= -13) then + @:ALLOCATE(fd_coef_x(0:buff_size, 1:1)) if (weno_order > 1 .or. muscl_order > 1) then @@ -230,11 +301,14 @@ contains end if call s_compute_cbc_coefficients(1, 1) + end if ! Allocating/Computing CBC Coefficients in y-direction if (n > 0) then + if (all((/bc_y%beg, bc_y%end/) <= -5) .and. all((/bc_y%beg, bc_y%end/) >= -13)) then + @:ALLOCATE(fd_coef_y(0:buff_size, -1:1)) if (weno_order > 1 .or. muscl_order > 1) then @@ -243,7 +317,9 @@ contains call s_compute_cbc_coefficients(2, -1) call s_compute_cbc_coefficients(2, 1) - else if (bc_y%beg <= -5 .and. bc_y%beg >= -13) then + + elseif (bc_y%beg <= -5 .and. bc_y%beg >= -13) then + @:ALLOCATE(fd_coef_y(0:buff_size, -1:-1)) if (weno_order > 1 .or. muscl_order > 1) then @@ -251,7 +327,9 @@ contains end if call s_compute_cbc_coefficients(2, -1) - else if (bc_y%end <= -5 .and. bc_y%end >= -13) then + + elseif (bc_y%end <= -5 .and. bc_y%end >= -13) then + @:ALLOCATE(fd_coef_y(0:buff_size, 1:1)) if (weno_order > 1 .or. muscl_order > 1) then @@ -259,12 +337,16 @@ contains end if call s_compute_cbc_coefficients(2, 1) + end if + end if ! Allocating/Computing CBC Coefficients in z-direction if (p > 0) then + if (all((/bc_z%beg, bc_z%end/) <= -5) .and. all((/bc_z%beg, bc_z%end/) >= -13)) then + @:ALLOCATE(fd_coef_z(0:buff_size, -1:1)) if (weno_order > 1 .or. muscl_order > 1) then @@ -273,7 +355,9 @@ contains call s_compute_cbc_coefficients(3, -1) call s_compute_cbc_coefficients(3, 1) - else if (bc_z%beg <= -5 .and. bc_z%beg >= -13) then + + elseif (bc_z%beg <= -5 .and. bc_z%beg >= -13) then + @:ALLOCATE(fd_coef_z(0:buff_size, -1:-1)) if (weno_order > 1 .or. muscl_order > 1) then @@ -281,7 +365,9 @@ contains end if call s_compute_cbc_coefficients(3, -1) - else if (bc_z%end <= -5 .and. bc_z%end >= -13) then + + elseif (bc_z%end <= -5 .and. bc_z%end >= -13) then + @:ALLOCATE(fd_coef_z(0:buff_size, 1:1)) if (weno_order > 1 .or. muscl_order > 1) then @@ -289,13 +375,16 @@ contains end if call s_compute_cbc_coefficients(3, 1) + end if + end if - $:GPU_UPDATE(device='[fd_coef_x, fd_coef_y, fd_coef_z, pi_coef_x, pi_coef_y, pi_coef_z]') + $:GPU_UPDATE(device='[fd_coef_x,fd_coef_y,fd_coef_z, & + & pi_coef_x,pi_coef_y,pi_coef_z]') - ! Associating the procedural pointer to the appropriate subroutine that will be utilized in the conversion to the mixture - ! variables + ! Associating the procedural pointer to the appropriate subroutine + ! that will be utilized in the conversion to the mixture variables bcxb = bc_x%beg bcxe = bc_x%end @@ -345,14 +434,17 @@ contains end do end if #:endfor - $:GPU_UPDATE(device='[vel_in, vel_out, pres_in, pres_out, Del_in, Del_out, alpha_rho_in, alpha_in]') + $:GPU_UPDATE(device='[vel_in,vel_out,pres_in,pres_out,Del_in,Del_out,alpha_rho_in,alpha_in]') end subroutine s_initialize_cbc_module - !> Compute CBC coefficients + !> Compute CBC coefficients + !! @param cbc_dir_in CBC coordinate direction + !! @param cbc_loc_in CBC coordinate location subroutine s_compute_cbc_coefficients(cbc_dir_in, cbc_loc_in) - - ! Compute grid-dependent CBC coefficients for given direction and location + ! Description: The purpose of this subroutine is to compute the grid + ! dependent FD and PI coefficients, or CBC coefficients, + ! provided the CBC coordinate direction and location. ! CBC coordinate direction and location integer, intent(in) :: cbc_dir_in, cbc_loc_in @@ -364,7 +456,6 @@ contains integer :: i ! Associating CBC coefficients pointers - call s_associate_cbc_coefficients_pointers(cbc_dir_in, cbc_loc_in) ! Determining the cell-boundary locations in the s-direction @@ -378,13 +469,15 @@ contains #:for CBC_DIR, XYZ in [(1, 'x'), (2, 'y'), (3, 'z')] if (cbc_dir_in == ${CBC_DIR}$ .and. recon_type == WENO_TYPE) then if (weno_order == 1) then - fd_coef_${XYZ}$ (:,cbc_loc_in) = 0._wp + + fd_coef_${XYZ}$ (:, cbc_loc_in) = 0._wp fd_coef_${XYZ}$ (0, cbc_loc_in) = -2._wp/(ds(0) + ds(1)) fd_coef_${XYZ}$ (1, cbc_loc_in) = -fd_coef_${XYZ}$ (0, cbc_loc_in) ! Computing CBC2 Coefficients - else if (weno_order == 3) then - fd_coef_${XYZ}$ (:,cbc_loc_in) = 0._wp + elseif (weno_order == 3) then + + fd_coef_${XYZ}$ (:, cbc_loc_in) = 0._wp fd_coef_${XYZ}$ (0, cbc_loc_in) = -6._wp/(3._wp*ds(0) + 2._wp*ds(1) - ds(2)) fd_coef_${XYZ}$ (1, cbc_loc_in) = -4._wp*fd_coef_${XYZ}$ (0, cbc_loc_in)/3._wp fd_coef_${XYZ}$ (2, cbc_loc_in) = fd_coef_${XYZ}$ (0, cbc_loc_in)/3._wp @@ -393,36 +486,49 @@ contains ! Computing CBC4 Coefficients else - fd_coef_${XYZ}$ (:,cbc_loc_in) = 0._wp - fd_coef_${XYZ}$ (0, & - & cbc_loc_in) = -50._wp/(25._wp*ds(0) + 2._wp*ds(1) - 1.e1_wp*ds(2) + 1.e1_wp*ds(3) & - & - 3._wp*ds(4)) + + fd_coef_${XYZ}$ (:, cbc_loc_in) = 0._wp + fd_coef_${XYZ}$ (0, cbc_loc_in) = -50._wp/(25._wp*ds(0) + 2._wp*ds(1) & + - 1.e1_wp*ds(2) + 1.e1_wp*ds(3) & + - 3._wp*ds(4)) fd_coef_${XYZ}$ (1, cbc_loc_in) = -48._wp*fd_coef_${XYZ}$ (0, cbc_loc_in)/25._wp fd_coef_${XYZ}$ (2, cbc_loc_in) = 36._wp*fd_coef_${XYZ}$ (0, cbc_loc_in)/25._wp fd_coef_${XYZ}$ (3, cbc_loc_in) = -16._wp*fd_coef_${XYZ}$ (0, cbc_loc_in)/25._wp fd_coef_${XYZ}$ (4, cbc_loc_in) = 3._wp*fd_coef_${XYZ}$ (0, cbc_loc_in)/25._wp - pi_coef_${XYZ}$ (0, 0, & - & cbc_loc_in) = ((s_cb(0) - s_cb(1))*(s_cb(1) - s_cb(2))*(s_cb(1) - s_cb(3)))/((s_cb(1) & - & - s_cb(4))*(s_cb(4) - s_cb(0))*(s_cb(4) - s_cb(2))) - pi_coef_${XYZ}$ (0, 1, & - & cbc_loc_in) = ((s_cb(1) - s_cb(0))*(s_cb(1) - s_cb(2))*((s_cb(1) - s_cb(3))*(s_cb(1) & - & - s_cb(3)) - (s_cb(0) - s_cb(4))*((s_cb(3) - s_cb(1)) + (s_cb(4) - s_cb(1)))))/((s_cb(0) & - & - s_cb(3))*(s_cb(1) - s_cb(3))*(s_cb(0) - s_cb(4))*(s_cb(1) - s_cb(4))) - pi_coef_${XYZ}$ (0, 2, & - & cbc_loc_in) = (s_cb(1) - s_cb(0))*((s_cb(1) - s_cb(2))*(s_cb(1) - s_cb(3)) + ((s_cb(0) & - & - s_cb(2)) + (s_cb(1) - s_cb(3)))*(s_cb(0) - s_cb(4)))/((s_cb(2) - s_cb(0))*(s_cb(0) & - & - s_cb(3))*(s_cb(0) - s_cb(4))) - pi_coef_${XYZ}$ (1, 0, & - & cbc_loc_in) = ((s_cb(0) - s_cb(2))*(s_cb(2) - s_cb(1))*(s_cb(2) - s_cb(3)))/((s_cb(2) & - & - s_cb(4))*(s_cb(4) - s_cb(0))*(s_cb(4) - s_cb(1))) - pi_coef_${XYZ}$ (1, 1, & - & cbc_loc_in) = ((s_cb(0) - s_cb(2))*(s_cb(1) - s_cb(2))*((s_cb(1) - s_cb(3))*(s_cb(2) & - & - s_cb(3)) + (s_cb(0) - s_cb(4))*((s_cb(1) - s_cb(3)) + (s_cb(2) - s_cb(4)))))/((s_cb(0) & - & - s_cb(3))*(s_cb(1) - s_cb(3))*(s_cb(0) - s_cb(4))*(s_cb(1) - s_cb(4))) - pi_coef_${XYZ}$ (1, 2, & - & cbc_loc_in) = ((s_cb(1) - s_cb(2))*(s_cb(2) - s_cb(3))*(s_cb(2) - s_cb(4)))/((s_cb(0) & - & - s_cb(2))*(s_cb(0) - s_cb(3))*(s_cb(0) - s_cb(4))) + pi_coef_${XYZ}$ (0, 0, cbc_loc_in) = & + ((s_cb(0) - s_cb(1))*(s_cb(1) - s_cb(2))* & + (s_cb(1) - s_cb(3)))/((s_cb(1) - s_cb(4))* & + (s_cb(4) - s_cb(0))*(s_cb(4) - s_cb(2))) + pi_coef_${XYZ}$ (0, 1, cbc_loc_in) = & + ((s_cb(1) - s_cb(0))*(s_cb(1) - s_cb(2))* & + ((s_cb(1) - s_cb(3))*(s_cb(1) - s_cb(3)) - & + (s_cb(0) - s_cb(4))*((s_cb(3) - s_cb(1)) + & + (s_cb(4) - s_cb(1)))))/ & + ((s_cb(0) - s_cb(3))*(s_cb(1) - s_cb(3))* & + (s_cb(0) - s_cb(4))*(s_cb(1) - s_cb(4))) + pi_coef_${XYZ}$ (0, 2, cbc_loc_in) = & + (s_cb(1) - s_cb(0))*((s_cb(1) - s_cb(2))* & + (s_cb(1) - s_cb(3)) + ((s_cb(0) - s_cb(2)) + & + (s_cb(1) - s_cb(3)))*(s_cb(0) - s_cb(4)))/ & + ((s_cb(2) - s_cb(0))*(s_cb(0) - s_cb(3))* & + (s_cb(0) - s_cb(4))) + pi_coef_${XYZ}$ (1, 0, cbc_loc_in) = & + ((s_cb(0) - s_cb(2))*(s_cb(2) - s_cb(1))* & + (s_cb(2) - s_cb(3)))/((s_cb(2) - s_cb(4))* & + (s_cb(4) - s_cb(0))*(s_cb(4) - s_cb(1))) + pi_coef_${XYZ}$ (1, 1, cbc_loc_in) = & + ((s_cb(0) - s_cb(2))*(s_cb(1) - s_cb(2))* & + ((s_cb(1) - s_cb(3))*(s_cb(2) - s_cb(3)) + & + (s_cb(0) - s_cb(4))*((s_cb(1) - s_cb(3)) + & + (s_cb(2) - s_cb(4)))))/ & + ((s_cb(0) - s_cb(3))*(s_cb(1) - s_cb(3))* & + (s_cb(0) - s_cb(4))*(s_cb(1) - s_cb(4))) + pi_coef_${XYZ}$ (1, 2, cbc_loc_in) = & + ((s_cb(1) - s_cb(2))*(s_cb(2) - s_cb(3))* & + (s_cb(2) - s_cb(4)))/((s_cb(0) - s_cb(2))* & + (s_cb(0) - s_cb(3))*(s_cb(0) - s_cb(4))) + end if end if #:endfor @@ -433,15 +539,23 @@ contains end subroutine s_compute_cbc_coefficients - !> Associate CBC finite-difference and polynomial-interpolation coefficients based on direction and boundary location + !> @brief Associates finite-difference and polynomial-interpolation CBC coefficients with targets based on coordinate direction and boundary location. + !! The goal of the procedure is to associate the FD and PI + !! coefficients, or CBC coefficients, with the appropriate + !! targets, based on the coordinate direction and location + !! of the CBC. + !! @param cbc_dir_in CBC coordinate direction + !! @param cbc_loc_in CBC coordinate location subroutine s_associate_cbc_coefficients_pointers(cbc_dir_in, cbc_loc_in) integer, intent(in) :: cbc_dir_in, cbc_loc_in - integer :: i !< Generic loop iterator - ! Associating CBC Coefficients in x-direction + integer :: i !< Generic loop iterator + + ! Associating CBC Coefficients in x-direction if (cbc_dir_in == 1) then - ! fd_coef => fd_coef_x; if (weno_order > 1) pi_coef => pi_coef_x + + !fd_coef => fd_coef_x; if (weno_order > 1) pi_coef => pi_coef_x if (cbc_loc_in == -1) then do i = 0, buff_size @@ -454,8 +568,9 @@ contains end if ! Associating CBC Coefficients in y-direction - else if (cbc_dir_in == 2) then - ! fd_coef => fd_coef_y; if (weno_order > 1) pi_coef => pi_coef_y + elseif (cbc_dir_in == 2) then + + !fd_coef => fd_coef_y; if (weno_order > 1) pi_coef => pi_coef_y if (cbc_loc_in == -1) then do i = 0, buff_size @@ -469,7 +584,8 @@ contains ! Associating CBC Coefficients in z-direction else - ! fd_coef => fd_coef_z; if (weno_order > 1) pi_coef => pi_coef_z + + !fd_coef => fd_coef_z; if (weno_order > 1) pi_coef => pi_coef_z if (cbc_loc_in == -1) then do i = 0, buff_size @@ -480,64 +596,90 @@ contains ds(i) = dz(p - i) end do end if + end if $:GPU_UPDATE(device='[ds]') end subroutine s_associate_cbc_coefficients_pointers - !> Apply characteristic boundary conditions by modifying fluxes near domain boundaries - subroutine s_cbc(q_prim_vf, flux_vf, flux_src_vf, cbc_dir_norm, cbc_loc_norm, ix, iy, iz) - - type(scalar_field), dimension(sys_size), intent(in) :: q_prim_vf - type(scalar_field), dimension(sys_size), intent(inout) :: flux_vf, flux_src_vf - integer, intent(in) :: cbc_dir_norm, cbc_loc_norm - type(int_bounds_info), intent(in) :: ix, iy, iz - real(wp) :: drho_dt - real(wp) :: dpres_dt - real(wp) :: dgamma_dt - real(wp) :: dpi_inf_dt - real(wp) :: dqv_dt - real(wp) :: dpres_ds - + !> The following is the implementation of the CBC based on + !! the work of Thompson (1987, 1990) on hyperbolic systems. + !! The CBC is indirectly applied in the computation of the + !! right-hand-side (RHS) near the relevant domain boundary + !! through the modification of the fluxes. + !! @param q_prim_vf Cell-average primitive variables + !! @param flux_vf Cell-boundary-average fluxes + !! @param flux_src_vf Cell-boundary-average flux sources + !! @param cbc_dir_norm CBC coordinate direction + !! @param cbc_loc_norm CBC coordinate location + !! @param ix Index bound in the first coordinate direction + !! @param iy Index bound in the second coordinate direction + !! @param iz Index bound in the third coordinate direction + subroutine s_cbc(q_prim_vf, flux_vf, flux_src_vf, & + cbc_dir_norm, cbc_loc_norm, & + ix, iy, iz) + + type(scalar_field), & + dimension(sys_size), & + intent(in) :: q_prim_vf + + type(scalar_field), & + dimension(sys_size), & + intent(inout) :: flux_vf, flux_src_vf + + integer, intent(in) :: cbc_dir_norm, cbc_loc_norm + + type(int_bounds_info), intent(in) :: ix, iy, iz + real(wp) :: drho_dt + real(wp) :: dpres_dt + real(wp) :: dgamma_dt + real(wp) :: dpi_inf_dt + real(wp) :: dqv_dt + real(wp) :: dpres_ds #:if USING_AMD real(wp), dimension(20) :: L #:else real(wp), dimension(sys_size) :: L #:endif #:if not MFC_CASE_OPTIMIZATION and USING_AMD - real(wp), dimension(3) :: alpha_rho, dalpha_rho_ds, mf - real(wp), dimension(3) :: vel, dvel_ds - real(wp), dimension(3) :: adv_local, dadv_ds - real(wp), dimension(3) :: dadv_dt - real(wp), dimension(3) :: dvel_dt - real(wp), dimension(3) :: dalpha_rho_dt + real(wp), dimension(3) :: alpha_rho, dalpha_rho_ds, mf + real(wp), dimension(3) :: vel, dvel_ds + real(wp), dimension(3) :: adv_local, dadv_ds + real(wp), dimension(3) :: dadv_dt + real(wp), dimension(3) :: dvel_dt + real(wp), dimension(3) :: dalpha_rho_dt real(wp), dimension(10) :: Ys, h_k, dYs_dt, dYs_ds, Xs, Gamma_i, Cp_i #:else - real(wp), dimension(num_fluids) :: alpha_rho, dalpha_rho_ds, mf - real(wp), dimension(num_vels) :: vel, dvel_ds - real(wp), dimension(num_fluids) :: adv_local, dadv_ds - real(wp), dimension(num_fluids) :: dadv_dt - real(wp), dimension(num_dims) :: dvel_dt - real(wp), dimension(num_fluids) :: dalpha_rho_dt + real(wp), dimension(num_fluids) :: alpha_rho, dalpha_rho_ds, mf + real(wp), dimension(num_vels) :: vel, dvel_ds + real(wp), dimension(num_fluids) :: adv_local, dadv_ds + real(wp), dimension(num_fluids) :: dadv_dt + real(wp), dimension(num_dims) :: dvel_dt + real(wp), dimension(num_fluids) :: dalpha_rho_dt real(wp), dimension(num_species) :: Ys, h_k, dYs_dt, dYs_ds, Xs, Gamma_i, Cp_i #:endif real(wp), dimension(2) :: Re_cbc real(wp), dimension(3) :: lambda - real(wp) :: rho !< Cell averaged density - real(wp) :: pres !< Cell averaged pressure - real(wp) :: E !< Cell averaged energy - real(wp) :: H !< Cell averaged enthalpy - real(wp) :: gamma !< Cell averaged specific heat ratio - real(wp) :: pi_inf !< Cell averaged liquid stiffness - real(wp) :: qv !< Cell averaged fluid reference energy - real(wp) :: c - real(wp) :: Ma - real(wp) :: T, sum_Enthalpies - real(wp) :: Cv, Cp, e_mix, Mw, R_gas - real(wp) :: vel_K_sum, vel_dv_dt_sum - integer :: i, j, k, r !< Generic loop iterators - ! Reshaping of inputted data and association of the FD and PI coefficients, or CBC coefficients, respectively, hinging on + + real(wp) :: rho !< Cell averaged density + real(wp) :: pres !< Cell averaged pressure + real(wp) :: E !< Cell averaged energy + real(wp) :: H !< Cell averaged enthalpy + real(wp) :: gamma !< Cell averaged specific heat ratio + real(wp) :: pi_inf !< Cell averaged liquid stiffness + real(wp) :: qv !< Cell averaged fluid reference energy + real(wp) :: c + real(wp) :: Ma + real(wp) :: T, sum_Enthalpies + real(wp) :: Cv, Cp, e_mix, Mw, R_gas + + real(wp) :: vel_K_sum, vel_dv_dt_sum + + integer :: i, j, k, r !< Generic loop iterators + + ! Reshaping of inputted data and association of the FD and PI + ! coefficients, or CBC coefficients, respectively, hinging on ! selected CBC coordinate direction cbc_dir = cbc_dir_norm @@ -545,34 +687,43 @@ contains $:GPU_UPDATE(device='[cbc_dir, cbc_loc]') - call s_initialize_cbc(q_prim_vf, flux_vf, flux_src_vf, ix, iy, iz) + call s_initialize_cbc(q_prim_vf, flux_vf, flux_src_vf, & + ix, iy, iz) call s_associate_cbc_coefficients_pointers(cbc_dir, cbc_loc) #:for CBC_DIR, XYZ in [(1, 'x'), (2, 'y'), (3, 'z')] if (cbc_dir == ${CBC_DIR}$ .and. recon_type == WENO_TYPE) then + ! PI2 of flux_rs_vf and flux_src_rs_vf at j = 1/2 if (weno_order == 3 .or. dummy) then - call s_convert_primitive_to_flux_variables(q_prim_rs${XYZ}$_vf, F_rs${XYZ}$_vf, F_src_rs${XYZ}$_vf, is1, is2, & - & is3, idwbuff(2)%beg, idwbuff(3)%beg) - $:GPU_PARALLEL_LOOP(private='[i, r, k]', collapse=3) + call s_convert_primitive_to_flux_variables(q_prim_rs${XYZ}$_vf, & + F_rs${XYZ}$_vf, & + F_src_rs${XYZ}$_vf, & + is1, is2, is3, idwbuff(2)%beg, idwbuff(3)%beg) + + $:GPU_PARALLEL_LOOP(private='[i,r,k]', collapse=3) do i = 1, flux_cbc_index do r = is3%beg, is3%end do k = is2%beg, is2%end - flux_rs${XYZ}$_vf_l(0, k, r, i) = F_rs${XYZ}$_vf(0, k, r, i) + pi_coef_${XYZ}$ (0, 0, & - & cbc_loc)*(F_rs${XYZ}$_vf(1, k, r, i) - F_rs${XYZ}$_vf(0, k, r, i)) + flux_rs${XYZ}$_vf_l(0, k, r, i) = F_rs${XYZ}$_vf(0, k, r, i) & + + pi_coef_${XYZ}$ (0, 0, cbc_loc)* & + (F_rs${XYZ}$_vf(1, k, r, i) - & + F_rs${XYZ}$_vf(0, k, r, i)) end do end do end do $:END_GPU_PARALLEL_LOOP() - $:GPU_PARALLEL_LOOP(private='[i, r, k]', collapse=3) + $:GPU_PARALLEL_LOOP(private='[i,r,k]', collapse=3) do i = advxb, advxe do r = is3%beg, is3%end do k = is2%beg, is2%end - flux_src_rs${XYZ}$_vf_l(0, k, r, i) = F_src_rs${XYZ}$_vf(0, k, r, i) + (F_src_rs${XYZ}$_vf(1, k, & - & r, i) - F_src_rs${XYZ}$_vf(0, k, r, i))*pi_coef_${XYZ}$ (0, 0, cbc_loc) + flux_src_rs${XYZ}$_vf_l(0, k, r, i) = F_src_rs${XYZ}$_vf(0, k, r, i) + & + (F_src_rs${XYZ}$_vf(1, k, r, i) - & + F_src_rs${XYZ}$_vf(0, k, r, i)) & + *pi_coef_${XYZ}$ (0, 0, cbc_loc) end do end do end do @@ -581,51 +732,60 @@ contains ! PI4 of flux_rs_vf and flux_src_rs_vf at j = 1/2, 3/2 if (weno_order == 5 .or. dummy) then - call s_convert_primitive_to_flux_variables(q_prim_rs${XYZ}$_vf, F_rs${XYZ}$_vf, F_src_rs${XYZ}$_vf, is1, is2, & - & is3, idwbuff(2)%beg, idwbuff(3)%beg) + call s_convert_primitive_to_flux_variables(q_prim_rs${XYZ}$_vf, & + F_rs${XYZ}$_vf, & + F_src_rs${XYZ}$_vf, & + is1, is2, is3, idwbuff(2)%beg, idwbuff(3)%beg) - $:GPU_PARALLEL_LOOP(private='[i, j, r, k]', collapse=4) + $:GPU_PARALLEL_LOOP(private='[i,j,r,k]', collapse=4) do i = 1, flux_cbc_index do j = 0, 1 do r = is3%beg, is3%end do k = is2%beg, is2%end - flux_rs${XYZ}$_vf_l(j, k, r, i) = F_rs${XYZ}$_vf(j, k, r, i) + pi_coef_${XYZ}$ (j, 0, & - & cbc_loc)*(F_rs${XYZ}$_vf(3, k, r, i) - F_rs${XYZ}$_vf(2, k, r, & - & i)) + pi_coef_${XYZ}$ (j, 1, cbc_loc)*(F_rs${XYZ}$_vf(2, k, r, & - & i) - F_rs${XYZ}$_vf(1, k, r, i)) + pi_coef_${XYZ}$ (j, 2, & - & cbc_loc)*(F_rs${XYZ}$_vf(1, k, r, i) - F_rs${XYZ}$_vf(0, k, r, i)) + flux_rs${XYZ}$_vf_l(j, k, r, i) = F_rs${XYZ}$_vf(j, k, r, i) & + + pi_coef_${XYZ}$ (j, 0, cbc_loc)* & + (F_rs${XYZ}$_vf(3, k, r, i) - & + F_rs${XYZ}$_vf(2, k, r, i)) & + + pi_coef_${XYZ}$ (j, 1, cbc_loc)* & + (F_rs${XYZ}$_vf(2, k, r, i) - & + F_rs${XYZ}$_vf(1, k, r, i)) & + + pi_coef_${XYZ}$ (j, 2, cbc_loc)* & + (F_rs${XYZ}$_vf(1, k, r, i) - & + F_rs${XYZ}$_vf(0, k, r, i)) end do end do end do end do $:END_GPU_PARALLEL_LOOP() - $:GPU_PARALLEL_LOOP(private='[i, j, r, k]', collapse=4) + $:GPU_PARALLEL_LOOP(private='[i,j,r,k]', collapse=4) do i = advxb, advxe do j = 0, 1 do r = is3%beg, is3%end do k = is2%beg, is2%end - flux_src_rs${XYZ}$_vf_l(j, k, r, i) = F_src_rs${XYZ}$_vf(j, k, r, i) + (F_src_rs${XYZ}$_vf(3, & - & k, r, i) - F_src_rs${XYZ}$_vf(2, k, r, i))*pi_coef_${XYZ}$ (j, 0, & - & cbc_loc) + (F_src_rs${XYZ}$_vf(2, k, r, i) - F_src_rs${XYZ}$_vf(1, & - & k, r, i))*pi_coef_${XYZ}$ (j, 1, cbc_loc) + (F_src_rs${XYZ}$_vf(1, & - & k, r, i) - F_src_rs${XYZ}$_vf(0, k, r, i))*pi_coef_${XYZ}$ (j, 2, & - & cbc_loc) + flux_src_rs${XYZ}$_vf_l(j, k, r, i) = F_src_rs${XYZ}$_vf(j, k, r, i) + & + (F_src_rs${XYZ}$_vf(3, k, r, i) - & + F_src_rs${XYZ}$_vf(2, k, r, i)) & + *pi_coef_${XYZ}$ (j, 0, cbc_loc) + & + (F_src_rs${XYZ}$_vf(2, k, r, i) - & + F_src_rs${XYZ}$_vf(1, k, r, i)) & + *pi_coef_${XYZ}$ (j, 1, cbc_loc) + & + (F_src_rs${XYZ}$_vf(1, k, r, i) - & + F_src_rs${XYZ}$_vf(0, k, r, i)) & + *pi_coef_${XYZ}$ (j, 2, cbc_loc) end do end do end do end do $:END_GPU_PARALLEL_LOOP() + end if ! FD2 or FD4 of RHS at j = 0 - $:GPU_PARALLEL_LOOP(collapse=2, private='[r, k, alpha_rho, vel, adv_local, mf, dvel_ds, dadv_ds, Re_cbc, & - & dalpha_rho_ds, dpres_ds, dvel_dt, dadv_dt, dalpha_rho_dt, L, lambda, Ys, dYs_dt, dYs_ds, & - & h_k, Cp_i, Gamma_i, Xs, drho_dt, dpres_dt, dpi_inf_dt, dqv_dt, dgamma_dt, rho, pres, E, H, & - & gamma, pi_inf, qv, c, Ma, T, sum_Enthalpies, Cv, Cp, e_mix, Mw, R_gas, vel_K_sum, & - & vel_dv_dt_sum, i, j]', copyin='[dir_idx]') + $:GPU_PARALLEL_LOOP(collapse=2, private='[r,k,alpha_rho, vel, adv_local, mf, dvel_ds, dadv_ds, Re_cbc, dalpha_rho_ds, dpres_ds, dvel_dt, dadv_dt, dalpha_rho_dt, L, lambda, Ys, dYs_dt, dYs_ds, h_k, Cp_i, Gamma_i, Xs, drho_dt, dpres_dt, dpi_inf_dt, dqv_dt, dgamma_dt, rho, pres, E, H, gamma, pi_inf, qv, c, Ma, T, sum_Enthalpies, Cv, Cp, e_mix, Mw, R_gas, vel_K_sum, vel_dv_dt_sum, i, j]', copyin='[dir_idx]') do r = is3%beg, is3%end do k = is2%beg, is2%end + ! Transferring the Primitive Variables $:GPU_LOOP(parallelism='[seq]') do i = 1, contxe @@ -716,26 +876,36 @@ contains $:GPU_LOOP(parallelism='[seq]') do j = 0, buff_size + $:GPU_LOOP(parallelism='[seq]') do i = 1, contxe - dalpha_rho_ds(i) = q_prim_rs${XYZ}$_vf(j, k, r, i)*fd_coef_${XYZ}$ (j, cbc_loc) + dalpha_rho_ds(i) + dalpha_rho_ds(i) = q_prim_rs${XYZ}$_vf(j, k, r, i)* & + fd_coef_${XYZ}$ (j, cbc_loc) + & + dalpha_rho_ds(i) end do $:GPU_LOOP(parallelism='[seq]') do i = 1, num_dims - dvel_ds(i) = q_prim_rs${XYZ}$_vf(j, k, r, contxe + i)*fd_coef_${XYZ}$ (j, cbc_loc) + dvel_ds(i) + dvel_ds(i) = q_prim_rs${XYZ}$_vf(j, k, r, contxe + i)* & + fd_coef_${XYZ}$ (j, cbc_loc) + & + dvel_ds(i) end do - dpres_ds = q_prim_rs${XYZ}$_vf(j, k, r, E_idx)*fd_coef_${XYZ}$ (j, cbc_loc) + dpres_ds + dpres_ds = q_prim_rs${XYZ}$_vf(j, k, r, E_idx)* & + fd_coef_${XYZ}$ (j, cbc_loc) + & + dpres_ds $:GPU_LOOP(parallelism='[seq]') do i = 1, advxe - E_idx - dadv_ds(i) = q_prim_rs${XYZ}$_vf(j, k, r, E_idx + i)*fd_coef_${XYZ}$ (j, cbc_loc) + dadv_ds(i) + dadv_ds(i) = q_prim_rs${XYZ}$_vf(j, k, r, E_idx + i)* & + fd_coef_${XYZ}$ (j, cbc_loc) + & + dadv_ds(i) end do if (chemistry) then $:GPU_LOOP(parallelism='[seq]') do i = 1, num_species - dYs_ds(i) = q_prim_rs${XYZ}$_vf(j, k, r, chemxb - 1 + i)*fd_coef_${XYZ}$ (j, & - & cbc_loc) + dYs_ds(i) + dYs_ds(i) = q_prim_rs${XYZ}$_vf(j, k, r, chemxb - 1 + i)* & + fd_coef_${XYZ}$ (j, cbc_loc) + & + dYs_ds(i) end do end if end do @@ -747,22 +917,20 @@ contains Ma = vel(dir_idx(1))/c - if ((cbc_loc == -1 .and. bc${XYZ}$b == BC_CHAR_SLIP_WALL) & - & .or. (cbc_loc == 1 .and. bc${XYZ}$e == BC_CHAR_SLIP_WALL)) then + if ((cbc_loc == -1 .and. bc${XYZ}$b == BC_CHAR_SLIP_WALL) .or. & + (cbc_loc == 1 .and. bc${XYZ}$e == BC_CHAR_SLIP_WALL)) then call s_compute_slip_wall_L(lambda, L, rho, c, dpres_ds, dvel_ds) - else if ((cbc_loc == -1 .and. bc${XYZ}$b == BC_CHAR_NR_SUB_BUFFER) & - & .or. (cbc_loc == 1 .and. bc${XYZ}$e == BC_CHAR_NR_SUB_BUFFER)) then - call s_compute_nonreflecting_subsonic_buffer_L(lambda, L, rho, c, mf, dalpha_rho_ds, dpres_ds, & - & dvel_ds, dadv_ds, dYs_ds) - else if ((cbc_loc == -1 .and. bc${XYZ}$b == BC_CHAR_NR_SUB_INFLOW) & - & .or. (cbc_loc == 1 .and. bc${XYZ}$e == BC_CHAR_NR_SUB_INFLOW)) then + else if ((cbc_loc == -1 .and. bc${XYZ}$b == BC_CHAR_NR_SUB_BUFFER) .or. & + (cbc_loc == 1 .and. bc${XYZ}$e == BC_CHAR_NR_SUB_BUFFER)) then + call s_compute_nonreflecting_subsonic_buffer_L(lambda, L, rho, c, mf, dalpha_rho_ds, dpres_ds, dvel_ds, dadv_ds, dYs_ds) + else if ((cbc_loc == -1 .and. bc${XYZ}$b == BC_CHAR_NR_SUB_INFLOW) .or. & + (cbc_loc == 1 .and. bc${XYZ}$e == BC_CHAR_NR_SUB_INFLOW)) then call s_compute_nonreflecting_subsonic_inflow_L(lambda, L, rho, c, dpres_ds, dvel_ds) ! Add GRCBC for Subsonic Inflow if (bc_${XYZ}$%grcbc_in) then $:GPU_LOOP(parallelism='[seq]') do i = 2, momxb - L(i) = c**3._wp*Ma*(alpha_rho(i - 1) - alpha_rho_in(i - 1, & - & ${CBC_DIR}$))/Del_in(${CBC_DIR}$) - c*Ma*(pres - pres_in(${CBC_DIR}$))/Del_in(${CBC_DIR}$) + L(i) = c**3._wp*Ma*(alpha_rho(i - 1) - alpha_rho_in(i - 1, ${CBC_DIR}$))/Del_in(${CBC_DIR}$) - c*Ma*(pres - pres_in(${CBC_DIR}$))/Del_in(${CBC_DIR}$) end do if (n > 0) then L(momxb + 1) = c*Ma*(vel(dir_idx(2)) - vel_in(${CBC_DIR}$, dir_idx(2)))/Del_in(${CBC_DIR}$) @@ -772,59 +940,56 @@ contains end if $:GPU_LOOP(parallelism='[seq]') do i = E_idx, advxe - 1 - L(i) = c*Ma*(adv_local(i + 1 - E_idx) - alpha_in(i + 1 - E_idx, & - & ${CBC_DIR}$))/Del_in(${CBC_DIR}$) + L(i) = c*Ma*(adv_local(i + 1 - E_idx) - alpha_in(i + 1 - E_idx, ${CBC_DIR}$))/Del_in(${CBC_DIR}$) end do - L(advxe) = rho*c**2._wp*(1._wp + Ma)*(vel(dir_idx(1)) + vel_in(${CBC_DIR}$, dir_idx(1))*sign(1, & - & cbc_loc))/Del_in(${CBC_DIR}$) + c*(1._wp + Ma)*(pres - pres_in(${CBC_DIR}$))/Del_in(${CBC_DIR}$) + L(advxe) = rho*c**2._wp*(1._wp + Ma)*(vel(dir_idx(1)) + vel_in(${CBC_DIR}$, dir_idx(1))*sign(1, cbc_loc))/Del_in(${CBC_DIR}$) + c*(1._wp + Ma)*(pres - pres_in(${CBC_DIR}$))/Del_in(${CBC_DIR}$) end if - else if ((cbc_loc == -1 .and. bc${XYZ}$b == BC_CHAR_NR_SUB_OUTFLOW) & - & .or. (cbc_loc == 1 .and. bc${XYZ}$e == BC_CHAR_NR_SUB_OUTFLOW)) then - call s_compute_nonreflecting_subsonic_outflow_L(lambda, L, rho, c, mf, dalpha_rho_ds, dpres_ds, & - & dvel_ds, dadv_ds, dYs_ds) + else if ((cbc_loc == -1 .and. bc${XYZ}$b == BC_CHAR_NR_SUB_OUTFLOW) .or. & + (cbc_loc == 1 .and. bc${XYZ}$e == BC_CHAR_NR_SUB_OUTFLOW)) then + call s_compute_nonreflecting_subsonic_outflow_L(lambda, L, rho, c, mf, dalpha_rho_ds, dpres_ds, dvel_ds, dadv_ds, dYs_ds) ! Add GRCBC for Subsonic Outflow (Pressure) if (bc_${XYZ}$%grcbc_out) then L(advxe) = c*(1._wp - Ma)*(pres - pres_out(${CBC_DIR}$))/Del_out(${CBC_DIR}$) ! Add GRCBC for Subsonic Outflow (Normal Velocity) if (bc_${XYZ}$%grcbc_vel_out) then - L(advxe) = L(advxe) + rho*c**2._wp*(1._wp - Ma)*(vel(dir_idx(1)) + vel_out(${CBC_DIR}$, & - & dir_idx(1))*sign(1, cbc_loc))/Del_out(${CBC_DIR}$) + L(advxe) = L(advxe) + rho*c**2._wp*(1._wp - Ma)*(vel(dir_idx(1)) + vel_out(${CBC_DIR}$, dir_idx(1))*sign(1, cbc_loc))/Del_out(${CBC_DIR}$) end if end if - else if ((cbc_loc == -1 .and. bc${XYZ}$b == BC_CHAR_FF_SUB_OUTFLOW) & - & .or. (cbc_loc == 1 .and. bc${XYZ}$e == BC_CHAR_FF_SUB_OUTFLOW)) then - call s_compute_force_free_subsonic_outflow_L(lambda, L, rho, c, mf, dalpha_rho_ds, dpres_ds, dvel_ds, & - & dadv_ds) - else if ((cbc_loc == -1 .and. bc${XYZ}$b == BC_CHAR_CP_SUB_OUTFLOW) & - & .or. (cbc_loc == 1 .and. bc${XYZ}$e == BC_CHAR_CP_SUB_OUTFLOW)) then - call s_compute_constant_pressure_subsonic_outflow_L(lambda, L, rho, c, mf, dalpha_rho_ds, dpres_ds, & - & dvel_ds, dadv_ds) - else if ((cbc_loc == -1 .and. bc${XYZ}$b == BC_CHAR_SUP_INFLOW) & - & .or. (cbc_loc == 1 .and. bc${XYZ}$e == BC_CHAR_SUP_INFLOW)) then + else if ((cbc_loc == -1 .and. bc${XYZ}$b == BC_CHAR_FF_SUB_OUTFLOW) .or. & + (cbc_loc == 1 .and. bc${XYZ}$e == BC_CHAR_FF_SUB_OUTFLOW)) then + call s_compute_force_free_subsonic_outflow_L(lambda, L, rho, c, mf, dalpha_rho_ds, dpres_ds, dvel_ds, dadv_ds) + else if ((cbc_loc == -1 .and. bc${XYZ}$b == BC_CHAR_CP_SUB_OUTFLOW) .or. & + (cbc_loc == 1 .and. bc${XYZ}$e == BC_CHAR_CP_SUB_OUTFLOW)) then + call s_compute_constant_pressure_subsonic_outflow_L(lambda, L, rho, c, mf, dalpha_rho_ds, dpres_ds, dvel_ds, dadv_ds) + else if ((cbc_loc == -1 .and. bc${XYZ}$b == BC_CHAR_SUP_INFLOW) .or. & + (cbc_loc == 1 .and. bc${XYZ}$e == BC_CHAR_SUP_INFLOW)) then call s_compute_supersonic_inflow_L(L) - else if ((cbc_loc == -1 .and. bc${XYZ}$b == BC_CHAR_SUP_OUTFLOW) & - & .or. (cbc_loc == 1 .and. bc${XYZ}$e == BC_CHAR_SUP_OUTFLOW)) then - call s_compute_supersonic_outflow_L(lambda, L, rho, c, mf, dalpha_rho_ds, dpres_ds, dvel_ds, dadv_ds, & - & dYs_ds) + else if ((cbc_loc == -1 .and. bc${XYZ}$b == BC_CHAR_SUP_OUTFLOW) .or. & + (cbc_loc == 1 .and. bc${XYZ}$e == BC_CHAR_SUP_OUTFLOW)) then + call s_compute_supersonic_outflow_L(lambda, L, rho, c, mf, dalpha_rho_ds, dpres_ds, dvel_ds, dadv_ds, dYs_ds) end if ! Be careful about the cylindrical coordinate! if (cyl_coord .and. cbc_dir == 2 .and. cbc_loc == 1) then - dpres_dt = -5.e-1_wp*(L(advxe) + L(1)) + rho*c*c*vel(dir_idx(1))/y_cc(n) + dpres_dt = -5.e-1_wp*(L(advxe) + L(1)) + rho*c*c*vel(dir_idx(1)) & + /y_cc(n) else dpres_dt = -5.e-1_wp*(L(advxe) + L(1)) end if $:GPU_LOOP(parallelism='[seq]') do i = 1, contxe - dalpha_rho_dt(i) = -(L(i + 1) - mf(i)*dpres_dt)/(c*c) + dalpha_rho_dt(i) = & + -(L(i + 1) - mf(i)*dpres_dt)/(c*c) end do $:GPU_LOOP(parallelism='[seq]') do i = 1, num_dims - dvel_dt(dir_idx(i)) = dir_flg(dir_idx(i))*(L(1) - L(advxe))/(2._wp*rho*c) + (dir_flg(dir_idx(i)) & - & - 1._wp)*L(momxb + i - 1) + dvel_dt(dir_idx(i)) = dir_flg(dir_idx(i))* & + (L(1) - L(advxe))/(2._wp*rho*c) + & + (dir_flg(dir_idx(i)) - 1._wp)* & + L(momxb + i - 1) end do vel_dv_dt_sum = 0._wp @@ -844,7 +1009,7 @@ contains if (cyl_coord .and. cbc_dir == 2 .and. cbc_loc == 1) then $:GPU_LOOP(parallelism='[seq]') do i = 1, advxe - E_idx - dadv_dt(i) = -L(momxe + i) ! + adv_local(i) * vel(dir_idx(1))/y_cc(n) + dadv_dt(i) = -L(momxe + i) !+ adv_local(i) * vel(dir_idx(1))/y_cc(n) end do else $:GPU_LOOP(parallelism='[seq]') @@ -874,43 +1039,47 @@ contains ! flux_rs_vf_l and flux_src_rs_vf_l at j = -1/2 $:GPU_LOOP(parallelism='[seq]') do i = 1, contxe - flux_rs${XYZ}$_vf_l(-1, k, r, i) = flux_rs${XYZ}$_vf_l(0, k, r, i) + ds(0)*dalpha_rho_dt(i) + flux_rs${XYZ}$_vf_l(-1, k, r, i) = flux_rs${XYZ}$_vf_l(0, k, r, i) & + + ds(0)*dalpha_rho_dt(i) end do $:GPU_LOOP(parallelism='[seq]') do i = momxb, momxe - flux_rs${XYZ}$_vf_l(-1, k, r, i) = flux_rs${XYZ}$_vf_l(0, k, r, & - & i) + ds(0)*(vel(i - contxe)*drho_dt + rho*dvel_dt(i - contxe)) + flux_rs${XYZ}$_vf_l(-1, k, r, i) = flux_rs${XYZ}$_vf_l(0, k, r, i) & + + ds(0)*(vel(i - contxe)*drho_dt & + + rho*dvel_dt(i - contxe)) end do if (chemistry) then - ! Evolution of LODI equation of energy for real gases adjusted to perfect gas, - ! doi:10.1006/jcph.2002.6990 + ! Evolution of LODI equation of energy for real gases adjusted to perfect gas, doi:10.1006/jcph.2002.6990 call get_species_enthalpies_rt(T, h_k) sum_Enthalpies = 0._wp $:GPU_LOOP(parallelism='[seq]') do i = 1, num_species + #:if USING_AMD h_k(i) = h_k(i)*gas_constant/molecular_weights_nonparameter(i)*T - sum_Enthalpies = sum_Enthalpies + (rho*h_k(i) - pres*Mw/molecular_weights_nonparameter(i) & - & *Cp/R_gas)*dYs_dt(i) + sum_Enthalpies = sum_Enthalpies + (rho*h_k(i) - pres*Mw/molecular_weights_nonparameter(i)*Cp/R_gas)*dYs_dt(i) #:else h_k(i) = h_k(i)*gas_constant/molecular_weights(i)*T sum_Enthalpies = sum_Enthalpies + (rho*h_k(i) - pres*Mw/molecular_weights(i)*Cp/R_gas)*dYs_dt(i) #:endif end do - flux_rs${XYZ}$_vf_l(-1, k, r, E_idx) = flux_rs${XYZ}$_vf_l(0, k, r, & - & E_idx) + ds(0)*((E/rho + pres/rho)*drho_dt + rho*vel_dv_dt_sum + Cp*T*L(2)/(c*c) & - & + sum_Enthalpies) + flux_rs${XYZ}$_vf_l(-1, k, r, E_idx) = flux_rs${XYZ}$_vf_l(0, k, r, E_idx) & + + ds(0)*((E/rho + pres/rho)*drho_dt + rho*vel_dv_dt_sum + Cp*T*L(2)/(c*c) + sum_Enthalpies) $:GPU_LOOP(parallelism='[seq]') do i = 1, num_species - flux_rs${XYZ}$_vf_l(-1, k, r, i - 1 + chemxb) = flux_rs${XYZ}$_vf_l(0, k, r, & - & chemxb + i - 1) + ds(0)*(drho_dt*Ys(i) + rho*dYs_dt(i)) + flux_rs${XYZ}$_vf_l(-1, k, r, i - 1 + chemxb) = flux_rs${XYZ}$_vf_l(0, k, r, chemxb + i - 1) & + + ds(0)*(drho_dt*Ys(i) + rho*dYs_dt(i)) end do else - flux_rs${XYZ}$_vf_l(-1, k, r, E_idx) = flux_rs${XYZ}$_vf_l(0, k, r, & - & E_idx) + ds(0)*(pres*dgamma_dt + gamma*dpres_dt + dpi_inf_dt + dqv_dt & - & + rho*vel_dv_dt_sum + 5.e-1_wp*drho_dt*vel_K_sum) + flux_rs${XYZ}$_vf_l(-1, k, r, E_idx) = flux_rs${XYZ}$_vf_l(0, k, r, E_idx) & + + ds(0)*(pres*dgamma_dt & + + gamma*dpres_dt & + + dpi_inf_dt & + + dqv_dt & + + rho*vel_dv_dt_sum & + + 5.e-1_wp*drho_dt*vel_K_sum) end if if (riemann_solver == 1) then @@ -921,23 +1090,31 @@ contains $:GPU_LOOP(parallelism='[seq]') do i = advxb, advxe - flux_src_rs${XYZ}$_vf_l(-1, k, r, i) = 1._wp/max(abs(vel(dir_idx(1))), sgm_eps)*sign(1._wp, & - & vel(dir_idx(1)))*(flux_rs${XYZ}$_vf_l(0, k, r, & - & i) + vel(dir_idx(1))*flux_src_rs${XYZ}$_vf_l(0, k, r, & - & i) + ds(0)*dadv_dt(i - E_idx)) + flux_src_rs${XYZ}$_vf_l(-1, k, r, i) = & + 1._wp/max(abs(vel(dir_idx(1))), sgm_eps) & + *sign(1._wp, vel(dir_idx(1))) & + *(flux_rs${XYZ}$_vf_l(0, k, r, i) & + + vel(dir_idx(1)) & + *flux_src_rs${XYZ}$_vf_l(0, k, r, i) & + + ds(0)*dadv_dt(i - E_idx)) end do + else + $:GPU_LOOP(parallelism='[seq]') do i = advxb, advxe - flux_rs${XYZ}$_vf_l(-1, k, r, i) = flux_rs${XYZ}$_vf_l(0, k, r, i) + ds(0)*dadv_dt(i - E_idx) + flux_rs${XYZ}$_vf_l(-1, k, r, i) = flux_rs${XYZ}$_vf_l(0, k, r, i) + & + ds(0)*dadv_dt(i - E_idx) end do $:GPU_LOOP(parallelism='[seq]') do i = advxb, advxe flux_src_rs${XYZ}$_vf_l(-1, k, r, i) = flux_src_rs${XYZ}$_vf_l(0, k, r, i) end do + end if ! END: flux_rs_vf_l and flux_src_rs_vf_l at j = -1/2 + end do end do $:END_GPU_PARALLEL_LOOP() @@ -946,19 +1123,37 @@ contains ! END: FD2 or FD4 of RHS at j = 0 - ! The reshaping of outputted data and disssociation of the FD and PI coefficients, or CBC coefficients, respectively, based - ! on selected CBC coordinate direction. + ! The reshaping of outputted data and disssociation of the FD and PI + ! coefficients, or CBC coefficients, respectively, based on selected + ! CBC coordinate direction. call s_finalize_cbc(flux_vf, flux_src_vf) - end subroutine s_cbc - !> Set up the selected CBC for the current boundary - subroutine s_initialize_cbc(q_prim_vf, flux_vf, flux_src_vf, ix, iy, iz) + !> The computation of parameters, the allocation of memory, + !! the association of pointers and/or the execution of any + !! other procedures that are required for the setup of the + !! selected CBC. + !! @param q_prim_vf Cell-average primitive variables + !! @param flux_vf Cell-boundary-average fluxes + !! @param flux_src_vf Cell-boundary-average flux sources + !! @param ix Index bound in the first coordinate direction + !! @param iy Index bound in the second coordinate direction + !! @param iz Index bound in the third coordinate direction + subroutine s_initialize_cbc(q_prim_vf, flux_vf, flux_src_vf, & + ix, iy, iz) + + type(scalar_field), & + dimension(sys_size), & + intent(in) :: q_prim_vf + + type(scalar_field), & + dimension(sys_size), & + intent(in) :: flux_vf, flux_src_vf + + type(int_bounds_info), intent(in) :: ix, iy, iz + + integer :: i, j, k, r !< Generic loop iterators - type(scalar_field), dimension(sys_size), intent(in) :: q_prim_vf - type(scalar_field), dimension(sys_size), intent(in) :: flux_vf, flux_src_vf - type(int_bounds_info), intent(in) :: ix, iy, iz - integer :: i, j, k, r !< Generic loop iterators ! Configuring the coordinate direction indexes and flags ! Determining the indicial shift based on CBC location @@ -968,7 +1163,7 @@ contains if (cbc_dir == 1) then is1%beg = 0; is1%end = buff_size; is2 = iy; is3 = iz dir_idx = (/1, 2, 3/); dir_flg = (/1._wp, 0._wp, 0._wp/) - else if (cbc_dir == 2) then + elseif (cbc_dir == 2) then is1%beg = 0; is1%end = buff_size; is2 = ix; is3 = iz dir_idx = (/2, 1, 3/); dir_flg = (/0._wp, 1._wp, 0._wp/) else @@ -977,74 +1172,83 @@ contains end if dj = max(0, cbc_loc) - $:GPU_UPDATE(device='[is1, is2, is3, dj]') - $:GPU_UPDATE(device='[dir_idx, dir_flg]') + $:GPU_UPDATE(device='[is1,is2,is3,dj]') + $:GPU_UPDATE(device='[dir_idx,dir_flg]') ! Reshaping Inputted Data in x-direction if (cbc_dir == 1) then - $:GPU_PARALLEL_LOOP(private='[i, j, k, r]', collapse=4) + + $:GPU_PARALLEL_LOOP(private='[i,j,k,r]', collapse=4) do i = 1, sys_size do r = is3%beg, is3%end do k = is2%beg, is2%end do j = 0, buff_size - q_prim_rsx_vf(j, k, r, i) = q_prim_vf(i)%sf(dj*(m - 2*j) + j, k, r) + q_prim_rsx_vf(j, k, r, i) = & + q_prim_vf(i)%sf(dj*(m - 2*j) + j, k, r) end do end do end do end do $:END_GPU_PARALLEL_LOOP() - $:GPU_PARALLEL_LOOP(private='[j, k, r]', collapse=3) + $:GPU_PARALLEL_LOOP(private='[j,k,r]', collapse=3) do r = is3%beg, is3%end do k = is2%beg, is2%end do j = 0, buff_size - q_prim_rsx_vf(j, k, r, momxb) = q_prim_vf(momxb)%sf(dj*(m - 2*j) + j, k, r)*sign(1._wp, -1._wp*cbc_loc) + q_prim_rsx_vf(j, k, r, momxb) = & + q_prim_vf(momxb)%sf(dj*(m - 2*j) + j, k, r)* & + sign(1._wp, -1._wp*cbc_loc) end do end do end do $:END_GPU_PARALLEL_LOOP() - $:GPU_PARALLEL_LOOP(private='[i, j, k, r]', collapse=4) + $:GPU_PARALLEL_LOOP(private='[i,j,k,r]', collapse=4) do i = 1, flux_cbc_index do r = is3%beg, is3%end do k = is2%beg, is2%end do j = -1, buff_size - flux_rsx_vf_l(j, k, r, i) = flux_vf(i)%sf(dj*((m - 1) - 2*j) + j, k, r)*sign(1._wp, -1._wp*cbc_loc) + flux_rsx_vf_l(j, k, r, i) = & + flux_vf(i)%sf(dj*((m - 1) - 2*j) + j, k, r)* & + sign(1._wp, -1._wp*cbc_loc) end do end do end do end do $:END_GPU_PARALLEL_LOOP() - $:GPU_PARALLEL_LOOP(private='[j, k, r]', collapse=3) + $:GPU_PARALLEL_LOOP(private='[j,k,r]', collapse=3) do r = is3%beg, is3%end do k = is2%beg, is2%end do j = -1, buff_size - flux_rsx_vf_l(j, k, r, momxb) = flux_vf(momxb)%sf(dj*((m - 1) - 2*j) + j, k, r) + flux_rsx_vf_l(j, k, r, momxb) = & + flux_vf(momxb)%sf(dj*((m - 1) - 2*j) + j, k, r) end do end do end do $:END_GPU_PARALLEL_LOOP() if (riemann_solver == 1) then - $:GPU_PARALLEL_LOOP(private='[i, j, k, r]', collapse=4) + $:GPU_PARALLEL_LOOP(private='[i,j,k,r]', collapse=4) do i = advxb, advxe do r = is3%beg, is3%end do k = is2%beg, is2%end do j = -1, buff_size - flux_src_rsx_vf_l(j, k, r, i) = flux_src_vf(i)%sf(dj*((m - 1) - 2*j) + j, k, r) + flux_src_rsx_vf_l(j, k, r, i) = & + flux_src_vf(i)%sf(dj*((m - 1) - 2*j) + j, k, r) end do end do end do end do $:END_GPU_PARALLEL_LOOP() else - $:GPU_PARALLEL_LOOP(private='[j, k, r]', collapse=3) + $:GPU_PARALLEL_LOOP(private='[j,k,r]', collapse=3) do r = is3%beg, is3%end do k = is2%beg, is2%end do j = -1, buff_size - flux_src_rsx_vf_l(j, k, r, advxb) = flux_src_vf(advxb)%sf(dj*((m - 1) - 2*j) + j, k, r)*sign(1._wp, & - & -1._wp*cbc_loc) + flux_src_rsx_vf_l(j, k, r, advxb) = & + flux_src_vf(advxb)%sf(dj*((m - 1) - 2*j) + j, k, r)* & + sign(1._wp, -1._wp*cbc_loc) end do end do end do @@ -1054,71 +1258,79 @@ contains ! END: Reshaping Inputted Data in x-direction ! Reshaping Inputted Data in y-direction - else if (cbc_dir == 2) then - $:GPU_PARALLEL_LOOP(private='[i, j, k, r]', collapse=4) + elseif (cbc_dir == 2) then + + $:GPU_PARALLEL_LOOP(private='[i,j,k,r]', collapse=4) do i = 1, sys_size do r = is3%beg, is3%end do k = is2%beg, is2%end do j = 0, buff_size - q_prim_rsy_vf(j, k, r, i) = q_prim_vf(i)%sf(k, dj*(n - 2*j) + j, r) + q_prim_rsy_vf(j, k, r, i) = & + q_prim_vf(i)%sf(k, dj*(n - 2*j) + j, r) end do end do end do end do $:END_GPU_PARALLEL_LOOP() - $:GPU_PARALLEL_LOOP(private='[j, k, r]', collapse=3) + $:GPU_PARALLEL_LOOP(private='[j,k,r]', collapse=3) do r = is3%beg, is3%end do k = is2%beg, is2%end do j = 0, buff_size - q_prim_rsy_vf(j, k, r, momxb + 1) = q_prim_vf(momxb + 1)%sf(k, dj*(n - 2*j) + j, r)*sign(1._wp, & - & -1._wp*cbc_loc) + q_prim_rsy_vf(j, k, r, momxb + 1) = & + q_prim_vf(momxb + 1)%sf(k, dj*(n - 2*j) + j, r)* & + sign(1._wp, -1._wp*cbc_loc) end do end do end do $:END_GPU_PARALLEL_LOOP() - $:GPU_PARALLEL_LOOP(private='[i, j, k, r]', collapse=4) + $:GPU_PARALLEL_LOOP(private='[i,j,k,r]', collapse=4) do i = 1, flux_cbc_index do r = is3%beg, is3%end do k = is2%beg, is2%end do j = -1, buff_size - flux_rsy_vf_l(j, k, r, i) = flux_vf(i)%sf(k, dj*((n - 1) - 2*j) + j, r)*sign(1._wp, -1._wp*cbc_loc) + flux_rsy_vf_l(j, k, r, i) = & + flux_vf(i)%sf(k, dj*((n - 1) - 2*j) + j, r)* & + sign(1._wp, -1._wp*cbc_loc) end do end do end do end do $:END_GPU_PARALLEL_LOOP() - $:GPU_PARALLEL_LOOP(private='[j, k, r]', collapse=3) + $:GPU_PARALLEL_LOOP(private='[j,k,r]', collapse=3) do r = is3%beg, is3%end do k = is2%beg, is2%end do j = -1, buff_size - flux_rsy_vf_l(j, k, r, momxb + 1) = flux_vf(momxb + 1)%sf(k, dj*((n - 1) - 2*j) + j, r) + flux_rsy_vf_l(j, k, r, momxb + 1) = & + flux_vf(momxb + 1)%sf(k, dj*((n - 1) - 2*j) + j, r) end do end do end do $:END_GPU_PARALLEL_LOOP() if (riemann_solver == 1) then - $:GPU_PARALLEL_LOOP(private='[i, j, k, r]', collapse=4) + $:GPU_PARALLEL_LOOP(private='[i,j,k,r]', collapse=4) do i = advxb, advxe do r = is3%beg, is3%end do k = is2%beg, is2%end do j = -1, buff_size - flux_src_rsy_vf_l(j, k, r, i) = flux_src_vf(i)%sf(k, dj*((n - 1) - 2*j) + j, r) + flux_src_rsy_vf_l(j, k, r, i) = & + flux_src_vf(i)%sf(k, dj*((n - 1) - 2*j) + j, r) end do end do end do end do $:END_GPU_PARALLEL_LOOP() else - $:GPU_PARALLEL_LOOP(private='[j, k, r]', collapse=3) + $:GPU_PARALLEL_LOOP(private='[j,k,r]', collapse=3) do r = is3%beg, is3%end do k = is2%beg, is2%end do j = -1, buff_size - flux_src_rsy_vf_l(j, k, r, advxb) = flux_src_vf(advxb)%sf(k, dj*((n - 1) - 2*j) + j, r)*sign(1._wp, & - & -1._wp*cbc_loc) + flux_src_rsy_vf_l(j, k, r, advxb) = & + flux_src_vf(advxb)%sf(k, dj*((n - 1) - 2*j) + j, r)* & + sign(1._wp, -1._wp*cbc_loc) end do end do end do @@ -1129,134 +1341,156 @@ contains ! Reshaping Inputted Data in z-direction else - $:GPU_PARALLEL_LOOP(private='[i, j, k, r]', collapse=4) + + $:GPU_PARALLEL_LOOP(private='[i,j,k,r]', collapse=4) do i = 1, sys_size do r = is3%beg, is3%end do k = is2%beg, is2%end do j = 0, buff_size - q_prim_rsz_vf(j, k, r, i) = q_prim_vf(i)%sf(r, k, dj*(p - 2*j) + j) + q_prim_rsz_vf(j, k, r, i) = & + q_prim_vf(i)%sf(r, k, dj*(p - 2*j) + j) end do end do end do end do $:END_GPU_PARALLEL_LOOP() - $:GPU_PARALLEL_LOOP(private='[j, k, r]', collapse=3) + $:GPU_PARALLEL_LOOP(private='[j,k,r]', collapse=3) do r = is3%beg, is3%end do k = is2%beg, is2%end do j = 0, buff_size - q_prim_rsz_vf(j, k, r, momxe) = q_prim_vf(momxe)%sf(r, k, dj*(p - 2*j) + j)*sign(1._wp, -1._wp*cbc_loc) + q_prim_rsz_vf(j, k, r, momxe) = & + q_prim_vf(momxe)%sf(r, k, dj*(p - 2*j) + j)* & + sign(1._wp, -1._wp*cbc_loc) end do end do end do $:END_GPU_PARALLEL_LOOP() - $:GPU_PARALLEL_LOOP(private='[i, j, k, r]', collapse=4) + $:GPU_PARALLEL_LOOP(private='[i,j,k,r]', collapse=4) do i = 1, flux_cbc_index do r = is3%beg, is3%end do k = is2%beg, is2%end do j = -1, buff_size - flux_rsz_vf_l(j, k, r, i) = flux_vf(i)%sf(r, k, dj*((p - 1) - 2*j) + j)*sign(1._wp, -1._wp*cbc_loc) + flux_rsz_vf_l(j, k, r, i) = & + flux_vf(i)%sf(r, k, dj*((p - 1) - 2*j) + j)* & + sign(1._wp, -1._wp*cbc_loc) end do end do end do end do $:END_GPU_PARALLEL_LOOP() - $:GPU_PARALLEL_LOOP(private='[j, k, r]', collapse=3) + $:GPU_PARALLEL_LOOP(private='[j,k,r]', collapse=3) do r = is3%beg, is3%end do k = is2%beg, is2%end do j = -1, buff_size - flux_rsz_vf_l(j, k, r, momxe) = flux_vf(momxe)%sf(r, k, dj*((p - 1) - 2*j) + j) + flux_rsz_vf_l(j, k, r, momxe) = & + flux_vf(momxe)%sf(r, k, dj*((p - 1) - 2*j) + j) end do end do end do $:END_GPU_PARALLEL_LOOP() if (riemann_solver == 1) then - $:GPU_PARALLEL_LOOP(private='[i, j, k, r]', collapse=4) + $:GPU_PARALLEL_LOOP(private='[i,j,k,r]', collapse=4) do i = advxb, advxe do r = is3%beg, is3%end do k = is2%beg, is2%end do j = -1, buff_size - flux_src_rsz_vf_l(j, k, r, i) = flux_src_vf(i)%sf(r, k, dj*((p - 1) - 2*j) + j) + flux_src_rsz_vf_l(j, k, r, i) = & + flux_src_vf(i)%sf(r, k, dj*((p - 1) - 2*j) + j) end do end do end do end do $:END_GPU_PARALLEL_LOOP() else - $:GPU_PARALLEL_LOOP(private='[j, k, r]', collapse=3) + $:GPU_PARALLEL_LOOP(private='[j,k,r]', collapse=3) do r = is3%beg, is3%end do k = is2%beg, is2%end do j = -1, buff_size - flux_src_rsz_vf_l(j, k, r, advxb) = flux_src_vf(advxb)%sf(r, k, dj*((p - 1) - 2*j) + j)*sign(1._wp, & - & -1._wp*cbc_loc) + flux_src_rsz_vf_l(j, k, r, advxb) = & + flux_src_vf(advxb)%sf(r, k, dj*((p - 1) - 2*j) + j)* & + sign(1._wp, -1._wp*cbc_loc) end do end do end do $:END_GPU_PARALLEL_LOOP() end if + end if ! END: Reshaping Inputted Data in z-direction - ! Association of the procedural pointer to the appropriate procedure that will be utilized in the evaluation of L variables - ! for the CBC + ! Association of the procedural pointer to the appropriate procedure + ! that will be utilized in the evaluation of L variables for the CBC end subroutine s_initialize_cbc - !> Deallocation and/or the disassociation procedures that are necessary in order to finalize the CBC application + !> Deallocation and/or the disassociation procedures that + !! are necessary in order to finalize the CBC application + !! @param flux_vf Cell-boundary-average fluxes + !! @param flux_src_vf Cell-boundary-average flux sources subroutine s_finalize_cbc(flux_vf, flux_src_vf) - type(scalar_field), dimension(sys_size), intent(inout) :: flux_vf, flux_src_vf - integer :: i, j, k, r !< Generic loop iterators - ! Determining the indicial shift based on CBC location + type(scalar_field), & + dimension(sys_size), & + intent(inout) :: flux_vf, flux_src_vf + + integer :: i, j, k, r !< Generic loop iterators + ! Determining the indicial shift based on CBC location dj = max(0, cbc_loc) $:GPU_UPDATE(device='[dj]') ! Reshaping Outputted Data in x-direction if (cbc_dir == 1) then - $:GPU_PARALLEL_LOOP(private='[i, j, k, r]', collapse=4) + + $:GPU_PARALLEL_LOOP(private='[i,j,k,r]', collapse=4) do i = 1, flux_cbc_index do r = is3%beg, is3%end do k = is2%beg, is2%end do j = -1, buff_size - flux_vf(i)%sf(dj*((m - 1) - 2*j) + j, k, r) = flux_rsx_vf_l(j, k, r, i)*sign(1._wp, -1._wp*cbc_loc) + flux_vf(i)%sf(dj*((m - 1) - 2*j) + j, k, r) = & + flux_rsx_vf_l(j, k, r, i)* & + sign(1._wp, -1._wp*cbc_loc) end do end do end do end do $:END_GPU_PARALLEL_LOOP() - $:GPU_PARALLEL_LOOP(private='[j, k, r]', collapse=3) + $:GPU_PARALLEL_LOOP(private='[j,k,r]', collapse=3) do r = is3%beg, is3%end do k = is2%beg, is2%end do j = -1, buff_size - flux_vf(momxb)%sf(dj*((m - 1) - 2*j) + j, k, r) = flux_rsx_vf_l(j, k, r, momxb) + flux_vf(momxb)%sf(dj*((m - 1) - 2*j) + j, k, r) = & + flux_rsx_vf_l(j, k, r, momxb) end do end do end do $:END_GPU_PARALLEL_LOOP() if (riemann_solver == 1) then - $:GPU_PARALLEL_LOOP(private='[i, j, k, r]', collapse=4) + $:GPU_PARALLEL_LOOP(private='[i,j,k,r]', collapse=4) do i = advxb, advxe do r = is3%beg, is3%end do k = is2%beg, is2%end do j = -1, buff_size - flux_src_vf(i)%sf(dj*((m - 1) - 2*j) + j, k, r) = flux_src_rsx_vf_l(j, k, r, i) + flux_src_vf(i)%sf(dj*((m - 1) - 2*j) + j, k, r) = & + flux_src_rsx_vf_l(j, k, r, i) end do end do end do end do $:END_GPU_PARALLEL_LOOP() else - $:GPU_PARALLEL_LOOP(private='[j, k, r]', collapse=3) + $:GPU_PARALLEL_LOOP(private='[j,k,r]', collapse=3) do r = is3%beg, is3%end do k = is2%beg, is2%end do j = -1, buff_size - flux_src_vf(advxb)%sf(dj*((m - 1) - 2*j) + j, k, r) = flux_src_rsx_vf_l(j, k, r, advxb)*sign(1._wp, & - & -1._wp*cbc_loc) + flux_src_vf(advxb)%sf(dj*((m - 1) - 2*j) + j, k, r) = & + flux_src_rsx_vf_l(j, k, r, advxb)* & + sign(1._wp, -1._wp*cbc_loc) end do end do end do @@ -1265,48 +1499,54 @@ contains ! END: Reshaping Outputted Data in x-direction ! Reshaping Outputted Data in y-direction - else if (cbc_dir == 2) then - $:GPU_PARALLEL_LOOP(private='[i, j, k, r]', collapse=4) + elseif (cbc_dir == 2) then + + $:GPU_PARALLEL_LOOP(private='[i,j,k,r]', collapse=4) do i = 1, flux_cbc_index do r = is3%beg, is3%end do k = is2%beg, is2%end do j = -1, buff_size - flux_vf(i)%sf(k, dj*((n - 1) - 2*j) + j, r) = flux_rsy_vf_l(j, k, r, i)*sign(1._wp, -1._wp*cbc_loc) + flux_vf(i)%sf(k, dj*((n - 1) - 2*j) + j, r) = & + flux_rsy_vf_l(j, k, r, i)* & + sign(1._wp, -1._wp*cbc_loc) end do end do end do end do $:END_GPU_PARALLEL_LOOP() - $:GPU_PARALLEL_LOOP(private='[j, k, r]', collapse=3) + $:GPU_PARALLEL_LOOP(private='[j,k,r]', collapse=3) do r = is3%beg, is3%end do k = is2%beg, is2%end do j = -1, buff_size - flux_vf(momxb + 1)%sf(k, dj*((n - 1) - 2*j) + j, r) = flux_rsy_vf_l(j, k, r, momxb + 1) + flux_vf(momxb + 1)%sf(k, dj*((n - 1) - 2*j) + j, r) = & + flux_rsy_vf_l(j, k, r, momxb + 1) end do end do end do $:END_GPU_PARALLEL_LOOP() if (riemann_solver == 1) then - $:GPU_PARALLEL_LOOP(private='[i, j, k, r]', collapse=4) + $:GPU_PARALLEL_LOOP(private='[i,j,k,r]', collapse=4) do i = advxb, advxe do r = is3%beg, is3%end do k = is2%beg, is2%end do j = -1, buff_size - flux_src_vf(i)%sf(k, dj*((n - 1) - 2*j) + j, r) = flux_src_rsy_vf_l(j, k, r, i) + flux_src_vf(i)%sf(k, dj*((n - 1) - 2*j) + j, r) = & + flux_src_rsy_vf_l(j, k, r, i) end do end do end do end do $:END_GPU_PARALLEL_LOOP() else - $:GPU_PARALLEL_LOOP(private='[j, k, r]', collapse=3) + $:GPU_PARALLEL_LOOP(private='[j,k,r]', collapse=3) do r = is3%beg, is3%end do k = is2%beg, is2%end do j = -1, buff_size - flux_src_vf(advxb)%sf(k, dj*((n - 1) - 2*j) + j, r) = flux_src_rsy_vf_l(j, k, r, advxb)*sign(1._wp, & - & -1._wp*cbc_loc) + flux_src_vf(advxb)%sf(k, dj*((n - 1) - 2*j) + j, r) = & + flux_src_rsy_vf_l(j, k, r, advxb)* & + sign(1._wp, -1._wp*cbc_loc) end do end do end do @@ -1317,58 +1557,65 @@ contains ! Reshaping Outputted Data in z-direction else - $:GPU_PARALLEL_LOOP(private='[i, j, k, r]', collapse=4) + + $:GPU_PARALLEL_LOOP(private='[i,j,k,r]', collapse=4) do i = 1, flux_cbc_index do r = is3%beg, is3%end do k = is2%beg, is2%end do j = -1, buff_size - flux_vf(i)%sf(r, k, dj*((p - 1) - 2*j) + j) = flux_rsz_vf_l(j, k, r, i)*sign(1._wp, -1._wp*cbc_loc) + flux_vf(i)%sf(r, k, dj*((p - 1) - 2*j) + j) = & + flux_rsz_vf_l(j, k, r, i)* & + sign(1._wp, -1._wp*cbc_loc) end do end do end do end do $:END_GPU_PARALLEL_LOOP() - $:GPU_PARALLEL_LOOP(private='[j, k, r]', collapse=3) + $:GPU_PARALLEL_LOOP(private='[j,k,r]', collapse=3) do r = is3%beg, is3%end do k = is2%beg, is2%end do j = -1, buff_size - flux_vf(momxe)%sf(r, k, dj*((p - 1) - 2*j) + j) = flux_rsz_vf_l(j, k, r, momxe) + flux_vf(momxe)%sf(r, k, dj*((p - 1) - 2*j) + j) = & + flux_rsz_vf_l(j, k, r, momxe) end do end do end do $:END_GPU_PARALLEL_LOOP() if (riemann_solver == 1) then - $:GPU_PARALLEL_LOOP(private='[i, j, k, r]', collapse=4) + $:GPU_PARALLEL_LOOP(private='[i,j,k,r]', collapse=4) do i = advxb, advxe do r = is3%beg, is3%end do k = is2%beg, is2%end do j = -1, buff_size - flux_src_vf(i)%sf(r, k, dj*((p - 1) - 2*j) + j) = flux_src_rsz_vf_l(j, k, r, i) + flux_src_vf(i)%sf(r, k, dj*((p - 1) - 2*j) + j) = & + flux_src_rsz_vf_l(j, k, r, i) end do end do end do end do $:END_GPU_PARALLEL_LOOP() else - $:GPU_PARALLEL_LOOP(private='[j, k, r]', collapse=3) + $:GPU_PARALLEL_LOOP(private='[j,k,r]', collapse=3) do r = is3%beg, is3%end do k = is2%beg, is2%end do j = -1, buff_size - flux_src_vf(advxb)%sf(r, k, dj*((p - 1) - 2*j) + j) = flux_src_rsz_vf_l(j, k, r, advxb)*sign(1._wp, & - & -1._wp*cbc_loc) + flux_src_vf(advxb)%sf(r, k, dj*((p - 1) - 2*j) + j) = & + flux_src_rsz_vf_l(j, k, r, advxb)* & + sign(1._wp, -1._wp*cbc_loc) end do end do end do $:END_GPU_PARALLEL_LOOP() end if + end if ! END: Reshaping Outputted Data in z-direction end subroutine s_finalize_cbc - !> Detect whether any domain boundary uses characteristic boundary conditions + !> @brief Detects whether any domain boundary uses characteristic boundary conditions. elemental subroutine s_any_cbc_boundaries(toggle) logical, intent(inout) :: toggle @@ -1421,8 +1668,9 @@ contains @:DEALLOCATE(vel_in, vel_out, pres_in, pres_out, Del_in, Del_out, alpha_rho_in, alpha_in) ! Deallocating CBC Coefficients in x-direction - if (all((/bc_x%beg, bc_x%end/) <= -5) .and. all((/bc_x%beg, & - & bc_x%end/) >= -13) .or. bc_x%beg <= -5 .and. bc_x%beg >= -13 .or. bc_x%end <= -5 .and. bc_x%end >= -13) then + if (all((/bc_x%beg, bc_x%end/) <= -5) .and. all((/bc_x%beg, bc_x%end/) >= -13) .or. & + bc_x%beg <= -5 .and. bc_x%beg >= -13 .or. & + bc_x%end <= -5 .and. bc_x%end >= -13) then @:DEALLOCATE(fd_coef_x) if (weno_order > 1 .or. muscl_order > 1) then @:DEALLOCATE(pi_coef_x) @@ -1431,8 +1679,9 @@ contains ! Deallocating CBC Coefficients in y-direction if (n > 0) then - if (all((/bc_y%beg, bc_y%end/) <= -5) .and. all((/bc_y%beg, & - & bc_y%end/) >= -13) .or. bc_y%beg <= -5 .and. bc_y%beg >= -13 .or. bc_y%end <= -5 .and. bc_y%end >= -13) then + if (all((/bc_y%beg, bc_y%end/) <= -5) .and. all((/bc_y%beg, bc_y%end/) >= -13) .or. & + bc_y%beg <= -5 .and. bc_y%beg >= -13 .or. & + bc_y%end <= -5 .and. bc_y%end >= -13) then @:DEALLOCATE(fd_coef_y) if (weno_order > 1) then @:DEALLOCATE(pi_coef_y) @@ -1442,8 +1691,9 @@ contains ! Deallocating CBC Coefficients in z-direction if (p > 0) then - if (all((/bc_z%beg, bc_z%end/) <= -5) .and. all((/bc_z%beg, & - & bc_z%end/) >= -13) .or. bc_z%beg <= -5 .and. bc_z%beg >= -13 .or. bc_z%end <= -5 .and. bc_z%end >= -13) then + if (all((/bc_z%beg, bc_z%end/) <= -5) .and. all((/bc_z%beg, bc_z%end/) >= -13) .or. & + bc_z%beg <= -5 .and. bc_z%beg >= -13 .or. & + bc_z%end <= -5 .and. bc_z%end >= -13) then @:DEALLOCATE(fd_coef_z) if (weno_order > 1) then @:DEALLOCATE(pi_coef_z) diff --git a/src/simulation/m_checker.fpp b/src/simulation/m_checker.fpp index 478f778c84..5543cba645 100644 --- a/src/simulation/m_checker.fpp +++ b/src/simulation/m_checker.fpp @@ -8,10 +8,13 @@ !> @brief Validates simulation input parameters for consistency and supported configurations module m_checker - use m_global_parameters - use m_mpi_proxy + use m_global_parameters !< Definitions of the global parameters + + use m_mpi_proxy !< Message passing interface (MPI) module proxy + use m_helper - use m_helper_basic + + use m_helper_basic !< Functions to compare floating point numbers implicit none @@ -19,7 +22,8 @@ module m_checker contains - !> Checks compatibility of parameters in the input file. Used by the simulation stage + !> Checks compatibility of parameters in the input file. + !! Used by the simulation stage impure subroutine s_check_inputs call s_check_inputs_compilers @@ -42,66 +46,51 @@ contains !> Checks constraints on compiler options impure subroutine s_check_inputs_compilers - #if !defined(MFC_OpenACC) && !(defined(__PGI) || defined(_CRAYFTN)) @:PROHIBIT(rdma_mpi, "Unsupported value of rdma_mpi for the current compiler") #endif - end subroutine s_check_inputs_compilers !> Checks constraints on WENO scheme parameters impure subroutine s_check_inputs_weno - - character(len=5) :: numStr !< for int to string conversion + character(len=5) :: numStr !< for int to string conversion call s_int_to_str(num_stcls_min*weno_order, numStr) @:PROHIBIT(m + 1 < num_stcls_min*weno_order, & - & "m must be greater than or equal to (num_stcls_min*weno_order - 1), whose value is " // trim(numStr)) + "m must be greater than or equal to (num_stcls_min*weno_order - 1), whose value is "//trim(numStr)) @:PROHIBIT(n + 1 < min(1, n)*num_stcls_min*weno_order, & - & "For 2D simulation, n must be greater than or equal to (num_stcls_min*weno_order - 1), whose value is " & - & // trim(numStr)) + "For 2D simulation, n must be greater than or equal to (num_stcls_min*weno_order - 1), whose value is "//trim(numStr)) @:PROHIBIT(p + 1 < min(1, p)*num_stcls_min*weno_order, & - & "For 3D simulation, p must be greater than or equal to (num_stcls_min*weno_order - 1), whose value is " & - & // trim(numStr)) - + "For 3D simulation, p must be greater than or equal to (num_stcls_min*weno_order - 1), whose value is "//trim(numStr)) end subroutine s_check_inputs_weno - !> Validate that the grid resolution is sufficient for the MUSCL reconstruction order + !> @brief Validates that the grid resolution is sufficient for the MUSCL reconstruction order. impure subroutine s_check_inputs_muscl - - character(len=5) :: numStr !< for int to string conversion + character(len=5) :: numStr !< for int to string conversion call s_int_to_str(num_stcls_min*muscl_order, numStr) @:PROHIBIT(m + 1 < num_stcls_min*muscl_order, & - & "m must be greater than or equal to (num_stcls_min*muscl_order - 1), whose value is " // trim(numStr)) + "m must be greater than or equal to (num_stcls_min*muscl_order - 1), whose value is "//trim(numStr)) @:PROHIBIT(n + 1 < min(1, n)*num_stcls_min*muscl_order, & - & "For 2D simulation, n must be greater than or equal to (num_stcls_min*muscl_order - 1), whose value is " & - & // trim(numStr)) + "For 2D simulation, n must be greater than or equal to (num_stcls_min*muscl_order - 1), whose value is "//trim(numStr)) @:PROHIBIT(p + 1 < min(1, p)*num_stcls_min*muscl_order, & - & "For 3D simulation, p must be greater than or equal to (num_stcls_min*muscl_order - 1), whose value is " & - & // trim(numStr)) - + "For 3D simulation, p must be greater than or equal to (num_stcls_min*muscl_order - 1), whose value is "//trim(numStr)) end subroutine s_check_inputs_muscl !> Checks constraints on time stepping parameters impure subroutine s_check_inputs_time_stepping - if (.not. cfl_dt) then @:PROHIBIT(dt <= 0) end if - end subroutine s_check_inputs_time_stepping - !> Validate NVIDIA unified virtual memory configuration parameters impure subroutine s_check_inputs_nvidia_uvm - #ifdef __NVCOMPILER_GPU_UNIFIED_MEM @:PROHIBIT(nv_uvm_igr_temps_on_gpu > 3 .or. nv_uvm_igr_temps_on_gpu < 0, & - & "nv_uvm_igr_temps_on_gpu must be in the range [0, 3]") + "nv_uvm_igr_temps_on_gpu must be in the range [0, 3]") @:PROHIBIT(nv_uvm_igr_temps_on_gpu == 3 .and. igr_iter_solver == 2, & - & "nv_uvm_igr_temps_on_gpu must be in the range [0, 2] for igr_iter_solver == 2") + "nv_uvm_igr_temps_on_gpu must be in the range [0, 2] for igr_iter_solver == 2") #endif - end subroutine s_check_inputs_nvidia_uvm end module m_checker diff --git a/src/simulation/m_compute_cbc.fpp b/src/simulation/m_compute_cbc.fpp index cbeac697af..bb7c59ac5f 100644 --- a/src/simulation/m_compute_cbc.fpp +++ b/src/simulation/m_compute_cbc.fpp @@ -6,23 +6,24 @@ !> @brief Characteristic boundary condition (CBC) computations for subsonic inflow, outflow, and slip walls module m_compute_cbc - use m_global_parameters - implicit none - private; public :: s_compute_slip_wall_L, s_compute_nonreflecting_subsonic_buffer_L, & - & s_compute_nonreflecting_subsonic_inflow_L, s_compute_nonreflecting_subsonic_outflow_L, & - & s_compute_force_free_subsonic_outflow_L, s_compute_constant_pressure_subsonic_outflow_L, s_compute_supersonic_inflow_L, & - & s_compute_supersonic_outflow_L + private; public :: s_compute_slip_wall_L, & + s_compute_nonreflecting_subsonic_buffer_L, & + s_compute_nonreflecting_subsonic_inflow_L, & + s_compute_nonreflecting_subsonic_outflow_L, & + s_compute_force_free_subsonic_outflow_L, & + s_compute_constant_pressure_subsonic_outflow_L, & + s_compute_supersonic_inflow_L, & + s_compute_supersonic_outflow_L contains !> Base L1 calculation function f_base_L1(lambda, rho, c, dpres_ds, dvel_ds) result(L1) - $:GPU_ROUTINE(parallelism='[seq]') real(wp), dimension(3), intent(in) :: lambda - real(wp), intent(in) :: rho, c, dpres_ds + real(wp), intent(in) :: rho, c, dpres_ds #:if not MFC_CASE_OPTIMIZATION and USING_AMD real(wp), dimension(3), intent(in) :: dvel_ds #:else @@ -30,12 +31,10 @@ contains #:endif real(wp) :: L1 L1 = lambda(1)*(dpres_ds - rho*c*dvel_ds(dir_idx(1))) - end function f_base_L1 !> Fill density L variables subroutine s_fill_density_L(L, lambda_factor, lambda2, c, mf, dalpha_rho_ds, dpres_ds) - $:GPU_ROUTINE(parallelism='[seq]') #:if USING_AMD real(wp), dimension(20), intent(inout) :: L @@ -49,18 +48,16 @@ contains #:endif real(wp), intent(in) :: lambda_factor, lambda2, c real(wp), intent(in) :: dpres_ds - integer :: i + integer :: i ! $:GPU_LOOP(parallelism='[seq]') do i = 2, momxb L(i) = lambda_factor*lambda2*(c*c*dalpha_rho_ds(i - 1) - mf(i - 1)*dpres_ds) end do - end subroutine s_fill_density_L !> Fill velocity L variables subroutine s_fill_velocity_L(L, lambda_factor, lambda2, dvel_ds) - $:GPU_ROUTINE(parallelism='[seq]') #:if USING_AMD real(wp), dimension(20), intent(inout) :: L @@ -73,18 +70,16 @@ contains real(wp), dimension(num_dims), intent(in) :: dvel_ds #:endif real(wp), intent(in) :: lambda_factor, lambda2 - integer :: i + integer :: i ! $:GPU_LOOP(parallelism='[seq]') do i = momxb + 1, momxe L(i) = lambda_factor*lambda2*dvel_ds(dir_idx(i - contxe)) end do - end subroutine s_fill_velocity_L !> Fill advection L variables subroutine s_fill_advection_L(L, lambda_factor, lambda2, dadv_ds) - $:GPU_ROUTINE(parallelism='[seq]') #:if USING_AMD real(wp), dimension(20), intent(inout) :: L @@ -97,18 +92,16 @@ contains real(wp), dimension(num_fluids), intent(in) :: dadv_ds #:endif real(wp), intent(in) :: lambda_factor, lambda2 - integer :: i + integer :: i ! $:GPU_LOOP(parallelism='[seq]') do i = E_idx, advxe - 1 L(i) = lambda_factor*lambda2*dadv_ds(i - momxe) end do - end subroutine s_fill_advection_L !> Fill chemistry L variables subroutine s_fill_chemistry_L(L, lambda_factor, lambda2, dYs_ds) - $:GPU_ROUTINE(parallelism='[seq]') #:if USING_AMD real(wp), dimension(20), intent(inout) :: L @@ -121,7 +114,7 @@ contains real(wp), dimension(num_species), intent(in) :: dYs_ds #:endif real(wp), intent(in) :: lambda_factor, lambda2 - integer :: i + integer :: i if (.not. chemistry) return @@ -129,13 +122,12 @@ contains do i = chemxb, chemxe L(i) = lambda_factor*lambda2*dYs_ds(i - chemxb + 1) end do - end subroutine s_fill_chemistry_L !> Slip wall CBC (Thompson 1990, pg. 451) subroutine s_compute_slip_wall_L(lambda, L, rho, c, dpres_ds, dvel_ds) - - $:GPU_ROUTINE(function_name='s_compute_slip_wall_L',parallelism='[seq]', cray_inline=True) + $:GPU_ROUTINE(function_name='s_compute_slip_wall_L',parallelism='[seq]', & + & cray_inline=True) real(wp), dimension(3), intent(in) :: lambda #:if USING_AMD @@ -149,18 +141,17 @@ contains real(wp), dimension(num_dims), intent(in) :: dvel_ds #:endif real(wp), intent(in) :: rho, c, dpres_ds - integer :: i + integer :: i L(1) = f_base_L1(lambda, rho, c, dpres_ds, dvel_ds) L(2:advxe - 1) = 0._wp L(advxe) = L(1) - end subroutine s_compute_slip_wall_L !> Nonreflecting subsonic buffer CBC (Thompson 1987, pg. 13) subroutine s_compute_nonreflecting_subsonic_buffer_L(lambda, L, rho, c, mf, dalpha_rho_ds, dpres_ds, dvel_ds, dadv_ds, dYs_ds) - - $:GPU_ROUTINE(function_name='s_compute_nonreflecting_subsonic_buffer_L', parallelism='[seq]', cray_inline=True) + $:GPU_ROUTINE(function_name='s_compute_nonreflecting_subsonic_buffer_L', & + & parallelism='[seq]', cray_inline=True) real(wp), dimension(3), intent(in) :: lambda #:if USING_AMD @@ -169,19 +160,20 @@ contains real(wp), dimension(sys_size), intent(inout) :: L #:endif #:if not MFC_CASE_OPTIMIZATION and USING_AMD - real(wp), dimension(3), intent(in) :: mf, dalpha_rho_ds - real(wp), dimension(3), intent(in) :: dvel_ds - real(wp), dimension(3), intent(in) :: dadv_ds + real(wp), dimension(3), intent(in) :: mf, dalpha_rho_ds + real(wp), dimension(3), intent(in) :: dvel_ds + real(wp), dimension(3), intent(in) :: dadv_ds real(wp), dimension(10), intent(in) :: dYs_ds #:else - real(wp), dimension(num_fluids), intent(in) :: mf, dalpha_rho_ds - real(wp), dimension(num_dims), intent(in) :: dvel_ds - real(wp), dimension(num_fluids), intent(in) :: dadv_ds + real(wp), dimension(num_fluids), intent(in) :: mf, dalpha_rho_ds + real(wp), dimension(num_dims), intent(in) :: dvel_ds + real(wp), dimension(num_fluids), intent(in) :: dadv_ds real(wp), dimension(num_species), intent(in) :: dYs_ds #:endif real(wp), intent(in) :: rho, c real(wp), intent(in) :: dpres_ds - real(wp) :: lambda_factor + + real(wp) :: lambda_factor lambda_factor = (5.e-1_wp - 5.e-1_wp*sign(1._wp, lambda(1))) L(1) = lambda_factor*lambda(1)*(dpres_ds - rho*c*dvel_ds(dir_idx(1))) @@ -194,13 +186,12 @@ contains lambda_factor = (5.e-1_wp - 5.e-1_wp*sign(1._wp, lambda(3))) L(advxe) = lambda_factor*lambda(3)*(dpres_ds + rho*c*dvel_ds(dir_idx(1))) - end subroutine s_compute_nonreflecting_subsonic_buffer_L !> Nonreflecting subsonic inflow CBC (Thompson 1990, pg. 455) subroutine s_compute_nonreflecting_subsonic_inflow_L(lambda, L, rho, c, dpres_ds, dvel_ds) - - $:GPU_ROUTINE(function_name='s_compute_nonreflecting_subsonic_inflow_L', parallelism='[seq]', cray_inline=True) + $:GPU_ROUTINE(function_name='s_compute_nonreflecting_subsonic_inflow_L', & + & parallelism='[seq]', cray_inline=True) real(wp), dimension(3), intent(in) :: lambda #:if USING_AMD @@ -218,13 +209,12 @@ contains L(1) = f_base_L1(lambda, rho, c, dpres_ds, dvel_ds) L(2:advxe) = 0._wp if (chemistry) L(chemxb:chemxe) = 0._wp - end subroutine s_compute_nonreflecting_subsonic_inflow_L !> Nonreflecting subsonic outflow CBC (Thompson 1990, pg. 454) subroutine s_compute_nonreflecting_subsonic_outflow_L(lambda, L, rho, c, mf, dalpha_rho_ds, dpres_ds, dvel_ds, dadv_ds, dYs_ds) - - $:GPU_ROUTINE(function_name='s_compute_nonreflecting_subsonic_outflow_L', parallelism='[seq]', cray_inline=True) + $:GPU_ROUTINE(function_name='s_compute_nonreflecting_subsonic_outflow_L', & + & parallelism='[seq]', cray_inline=True) real(wp), dimension(3), intent(in) :: lambda #:if USING_AMD @@ -233,14 +223,14 @@ contains real(wp), dimension(sys_size), intent(inout) :: L #:endif #:if not MFC_CASE_OPTIMIZATION and USING_AMD - real(wp), dimension(3), intent(in) :: mf, dalpha_rho_ds - real(wp), dimension(3), intent(in) :: dvel_ds - real(wp), dimension(3), intent(in) :: dadv_ds + real(wp), dimension(3), intent(in) :: mf, dalpha_rho_ds + real(wp), dimension(3), intent(in) :: dvel_ds + real(wp), dimension(3), intent(in) :: dadv_ds real(wp), dimension(10), intent(in) :: dYs_ds #:else - real(wp), dimension(num_fluids), intent(in) :: mf, dalpha_rho_ds - real(wp), dimension(num_dims), intent(in) :: dvel_ds - real(wp), dimension(num_fluids), intent(in) :: dadv_ds + real(wp), dimension(num_fluids), intent(in) :: mf, dalpha_rho_ds + real(wp), dimension(num_dims), intent(in) :: dvel_ds + real(wp), dimension(num_fluids), intent(in) :: dadv_ds real(wp), dimension(num_species), intent(in) :: dYs_ds #:endif real(wp), intent(in) :: rho, c @@ -252,13 +242,12 @@ contains call s_fill_advection_L(L, 1._wp, lambda(2), dadv_ds) call s_fill_chemistry_L(L, 1._wp, lambda(2), dYs_ds) L(advxe) = 0._wp - end subroutine s_compute_nonreflecting_subsonic_outflow_L !> Force-free subsonic outflow CBC (Thompson 1990, pg. 454) subroutine s_compute_force_free_subsonic_outflow_L(lambda, L, rho, c, mf, dalpha_rho_ds, dpres_ds, dvel_ds, dadv_ds) - - $:GPU_ROUTINE(function_name='s_compute_force_free_subsonic_outflow_L', parallelism='[seq]', cray_inline=True) + $:GPU_ROUTINE(function_name='s_compute_force_free_subsonic_outflow_L', & + & parallelism='[seq]', cray_inline=True) real(wp), dimension(3), intent(in) :: lambda #:if USING_AMD @@ -272,7 +261,7 @@ contains real(wp), dimension(3), intent(in) :: dadv_ds #:else real(wp), dimension(num_fluids), intent(in) :: mf, dalpha_rho_ds - real(wp), dimension(num_dims), intent(in) :: dvel_ds + real(wp), dimension(num_dims), intent(in) :: dvel_ds real(wp), dimension(num_fluids), intent(in) :: dadv_ds #:endif real(wp), intent(in) :: rho, c @@ -283,13 +272,12 @@ contains call s_fill_velocity_L(L, 1._wp, lambda(2), dvel_ds) call s_fill_advection_L(L, 1._wp, lambda(2), dadv_ds) L(advxe) = L(1) + 2._wp*rho*c*lambda(2)*dvel_ds(dir_idx(1)) - end subroutine s_compute_force_free_subsonic_outflow_L !> Constant pressure subsonic outflow CBC (Thompson 1990, pg. 455) subroutine s_compute_constant_pressure_subsonic_outflow_L(lambda, L, rho, c, mf, dalpha_rho_ds, dpres_ds, dvel_ds, dadv_ds) - - $:GPU_ROUTINE(function_name='s_compute_constant_pressure_subsonic_outflow_L', parallelism='[seq]', cray_inline=True) + $:GPU_ROUTINE(function_name='s_compute_constant_pressure_subsonic_outflow_L', & + & parallelism='[seq]', cray_inline=True) real(wp), dimension(3), intent(in) :: lambda #:if USING_AMD @@ -303,7 +291,7 @@ contains real(wp), dimension(3), intent(in) :: dadv_ds #:else real(wp), dimension(num_fluids), intent(in) :: mf, dalpha_rho_ds - real(wp), dimension(num_dims), intent(in) :: dvel_ds + real(wp), dimension(num_dims), intent(in) :: dvel_ds real(wp), dimension(num_fluids), intent(in) :: dadv_ds #:endif real(wp), intent(in) :: rho, c @@ -314,13 +302,12 @@ contains call s_fill_velocity_L(L, 1._wp, lambda(2), dvel_ds) call s_fill_advection_L(L, 1._wp, lambda(2), dadv_ds) L(advxe) = -L(1) - end subroutine s_compute_constant_pressure_subsonic_outflow_L !> Supersonic inflow CBC (Thompson 1990, pg. 453) subroutine s_compute_supersonic_inflow_L(L) - - $:GPU_ROUTINE(function_name='s_compute_supersonic_inflow_L', parallelism='[seq]', cray_inline=True) + $:GPU_ROUTINE(function_name='s_compute_supersonic_inflow_L', & + & parallelism='[seq]', cray_inline=True) #:if USING_AMD real(wp), dimension(20), intent(inout) :: L #:else @@ -328,13 +315,12 @@ contains #:endif L(1:advxe) = 0._wp if (chemistry) L(chemxb:chemxe) = 0._wp - end subroutine s_compute_supersonic_inflow_L !> Supersonic outflow CBC (Thompson 1990, pg. 453) subroutine s_compute_supersonic_outflow_L(lambda, L, rho, c, mf, dalpha_rho_ds, dpres_ds, dvel_ds, dadv_ds, dYs_ds) - - $:GPU_ROUTINE(function_name='s_compute_supersonic_outflow_L', parallelism='[seq]', cray_inline=True) + $:GPU_ROUTINE(function_name='s_compute_supersonic_outflow_L', & + & parallelism='[seq]', cray_inline=True) real(wp), dimension(3), intent(in) :: lambda #:if USING_AMD @@ -343,14 +329,14 @@ contains real(wp), dimension(sys_size), intent(inout) :: L #:endif #:if not MFC_CASE_OPTIMIZATION and USING_AMD - real(wp), dimension(3), intent(in) :: mf, dalpha_rho_ds - real(wp), dimension(3), intent(in) :: dvel_ds - real(wp), dimension(3), intent(in) :: dadv_ds + real(wp), dimension(3), intent(in) :: mf, dalpha_rho_ds + real(wp), dimension(3), intent(in) :: dvel_ds + real(wp), dimension(3), intent(in) :: dadv_ds real(wp), dimension(10), intent(in) :: dYs_ds #:else - real(wp), dimension(num_fluids), intent(in) :: mf, dalpha_rho_ds - real(wp), dimension(num_dims), intent(in) :: dvel_ds - real(wp), dimension(num_fluids), intent(in) :: dadv_ds + real(wp), dimension(num_fluids), intent(in) :: mf, dalpha_rho_ds + real(wp), dimension(num_dims), intent(in) :: dvel_ds + real(wp), dimension(num_fluids), intent(in) :: dadv_ds real(wp), dimension(num_species), intent(in) :: dYs_ds #:endif real(wp), intent(in) :: rho, c @@ -362,7 +348,5 @@ contains call s_fill_advection_L(L, 1._wp, lambda(2), dadv_ds) call s_fill_chemistry_L(L, 1._wp, lambda(2), dYs_ds) L(advxe) = lambda(3)*(dpres_ds + rho*c*dvel_ds(dir_idx(1))) - end subroutine s_compute_supersonic_outflow_L - end module m_compute_cbc diff --git a/src/simulation/m_compute_levelset.fpp b/src/simulation/m_compute_levelset.fpp index da1dcd9109..f5d07f9e58 100644 --- a/src/simulation/m_compute_levelset.fpp +++ b/src/simulation/m_compute_levelset.fpp @@ -7,12 +7,17 @@ !> @brief Computes signed-distance level-set fields and surface normals for immersed-boundary patch geometries module m_compute_levelset - use m_ib_patches - use m_model - use m_derived_types - use m_global_parameters - use m_mpi_proxy - use m_helper_basic + use m_ib_patches !< The IB patch parameters + + use m_model !< Subroutine(s) related to STL files + + use m_derived_types !< Definitions of the derived types + + use m_global_parameters !< Definitions of the global parameters + + use m_mpi_proxy !< Message passing interface (MPI) module proxy + + use m_helper_basic !< Functions to compare floating point numbers implicit none @@ -20,77 +25,85 @@ module m_compute_levelset contains - !> Dispatch level-set distance and normal computations for all ghost points based on patch geometry type + !> @brief Dispatches level-set distance and normal computations for all ghost points based on their patch geometry type. impure subroutine s_apply_levelset(gps, num_gps) type(ghost_point), dimension(:), intent(inout) :: gps - integer, intent(in) :: num_gps - integer :: i, patch_id, patch_geometry + integer, intent(in) :: num_gps - ! 3D Patch Geometries + integer :: i, patch_id, patch_geometry + ! 3D Patch Geometries if (p > 0) then - $:GPU_PARALLEL_LOOP(private='[i, patch_id, patch_geometry]', copy='[gps]', copyin='[patch_ib(1:num_ibs), Np]') + + $:GPU_PARALLEL_LOOP(private='[i,patch_id,patch_geometry]', copy='[gps]', copyin='[patch_ib(1:num_ibs),Np]') do i = 1, num_gps + patch_id = gps(i)%ib_patch_id patch_geometry = patch_ib(patch_id)%geometry if (patch_geometry == 8) then call s_sphere_levelset(gps(i)) - else if (patch_geometry == 9) then + elseif (patch_geometry == 9) then call s_cuboid_levelset(gps(i)) - else if (patch_geometry == 10) then + elseif (patch_geometry == 10) then call s_cylinder_levelset(gps(i)) - else if (patch_geometry == 11) then + elseif (patch_geometry == 11) then call s_3d_airfoil_levelset(gps(i)) - else if (patch_geometry == 12) then + elseif (patch_geometry == 12) then call s_model_levelset(gps(i)) end if end do $:END_GPU_PARALLEL_LOOP() ! 2D Patch Geometries - else if (n > 0) then - $:GPU_PARALLEL_LOOP(private='[i, patch_id, patch_geometry]', copy='[gps]', copyin='[Np, patch_ib(1:num_ibs)]') + elseif (n > 0) then + + $:GPU_PARALLEL_LOOP(private='[i,patch_id,patch_geometry]', copy='[gps]', copyin='[Np,patch_ib(1:num_ibs)]') do i = 1, num_gps + patch_id = gps(i)%ib_patch_id patch_geometry = patch_ib(patch_id)%geometry if (patch_geometry == 2) then call s_circle_levelset(gps(i)) - else if (patch_geometry == 3) then + elseif (patch_geometry == 3) then call s_rectangle_levelset(gps(i)) - else if (patch_geometry == 4) then + elseif (patch_geometry == 4) then call s_airfoil_levelset(gps(i)) - else if (patch_geometry == 5) then + elseif (patch_geometry == 5) then call s_model_levelset(gps(i)) - else if (patch_geometry == 6) then + elseif (patch_geometry == 6) then call s_ellipse_levelset(gps(i)) end if end do $:END_GPU_PARALLEL_LOOP() + end if end subroutine s_apply_levelset - !> Compute the signed distance and outward normal from a ghost point to a circular immersed boundary + !> @brief Computes the signed distance and outward normal from a ghost point to a circular immersed boundary. subroutine s_circle_levelset(gp) $:GPU_ROUTINE(parallelism='[seq]') type(ghost_point), intent(inout) :: gp - real(wp) :: radius, dist - real(wp), dimension(2) :: center - real(wp), dimension(3) :: dist_vec - integer :: i, j, ib_patch_id !< Loop index variables + + real(wp) :: radius, dist + real(wp), dimension(2) :: center + real(wp), dimension(3) :: dist_vec + + integer :: i, j, ib_patch_id !< Loop index variables + ib_patch_id = gp%ib_patch_id i = gp%loc(1) j = gp%loc(2) radius = patch_ib(ib_patch_id)%radius - dist_vec(1) = x_cc(i) - patch_ib(ib_patch_id)%x_centroid - real(gp%x_periodicity, wp)*(x_domain%end - x_domain%beg) - dist_vec(2) = y_cc(j) - patch_ib(ib_patch_id)%y_centroid - real(gp%y_periodicity, wp)*(y_domain%end - y_domain%beg) + dist_vec(1) = x_cc(i) - patch_ib(ib_patch_id)%x_centroid - real(gp%x_periodicity, wp)*(glb_bounds(1)%end - glb_bounds(1)%beg) + dist_vec(2) = y_cc(j) - patch_ib(ib_patch_id)%y_centroid - real(gp%y_periodicity, wp)*(glb_bounds(2)%end - glb_bounds(2)%beg) dist_vec(3) = 0._wp dist = sqrt(sum(dist_vec**2)) @@ -103,32 +116,36 @@ contains end subroutine s_circle_levelset - !> Compute the signed distance and outward normal from a ghost point to a 2D NACA airfoil surface + !> @brief Computes the signed distance and outward normal from a ghost point to a 2D NACA airfoil surface. subroutine s_airfoil_levelset(gp) $:GPU_ROUTINE(parallelism='[seq]') type(ghost_point), intent(inout) :: gp - real(wp) :: dist, global_dist - integer :: global_id - real(wp), dimension(3) :: dist_vec - real(wp), dimension(1:3) :: xy_local, offset !< x and y coordinates in local IB frame - real(wp), dimension(1:2) :: center - real(wp), dimension(1:3,1:3) :: rotation, inverse_rotation - integer :: i, j, k, ib_patch_id !< Loop index variables + + real(wp) :: dist, global_dist + integer :: global_id + real(wp), dimension(3) :: dist_vec + + real(wp), dimension(1:3) :: xy_local, offset !< x and y coordinates in local IB frame + real(wp), dimension(1:2) :: center + real(wp), dimension(1:3, 1:3) :: rotation, inverse_rotation + + integer :: i, j, k, ib_patch_id !< Loop index variables + ib_patch_id = gp%ib_patch_id i = gp%loc(1) j = gp%loc(2) - center(1) = patch_ib(ib_patch_id)%x_centroid + real(gp%x_periodicity, wp)*(x_domain%end - x_domain%beg) - center(2) = patch_ib(ib_patch_id)%y_centroid + real(gp%y_periodicity, wp)*(y_domain%end - y_domain%beg) - inverse_rotation(:,:) = patch_ib(ib_patch_id)%rotation_matrix_inverse(:,:) - rotation(:,:) = patch_ib(ib_patch_id)%rotation_matrix(:,:) + center(1) = patch_ib(ib_patch_id)%x_centroid + real(gp%x_periodicity, wp)*(glb_bounds(1)%end - glb_bounds(1)%beg) + center(2) = patch_ib(ib_patch_id)%y_centroid + real(gp%y_periodicity, wp)*(glb_bounds(2)%end - glb_bounds(2)%beg) + inverse_rotation(:, :) = patch_ib(ib_patch_id)%rotation_matrix_inverse(:, :) + rotation(:, :) = patch_ib(ib_patch_id)%rotation_matrix(:, :) offset(:) = patch_ib(ib_patch_id)%centroid_offset(:) - xy_local = [x_cc(i) - center(1), y_cc(j) - center(2), 0._wp] ! get coordinate frame centered on IB - xy_local = matmul(inverse_rotation, xy_local) ! rotate the frame into the IB's coordinate - xy_local = xy_local - offset ! airfoils are a patch that require a centroid offset + xy_local = [x_cc(i) - center(1), y_cc(j) - center(2), 0._wp] ! get coordinate frame centered on IB + xy_local = matmul(inverse_rotation, xy_local) ! rotate the frame into the IB's coordinate + xy_local = xy_local - offset ! airfoils are a patch that require a centroid offset if (xy_local(2) >= 0._wp) then ! finds the location on the airfoil grid with the minimum distance (closest) @@ -177,44 +194,49 @@ contains if (f_approx_equal(dist, 0._wp)) then gp%levelset_norm = 0._wp else - gp%levelset_norm = matmul(rotation, dist_vec(:))/dist ! convert the normal vector back to global grid coordinates + gp%levelset_norm = matmul(rotation, dist_vec(:))/dist ! convert the normal vector back to global grid coordinates end if end subroutine s_airfoil_levelset - !> Compute the signed distance and outward normal from a ghost point to a 3D extruded airfoil surface + !> @brief Computes the signed distance and outward normal from a ghost point to a 3D extruded airfoil surface including spanwise end caps. subroutine s_3d_airfoil_levelset(gp) $:GPU_ROUTINE(parallelism='[seq]') type(ghost_point), intent(inout) :: gp - real(wp) :: dist, dist_surf, dist_side, global_dist - integer :: global_id - real(wp) :: lz, z_max, z_min - real(wp), dimension(3) :: dist_vec - real(wp), dimension(1:3) :: xyz_local, center, offset, normal !< x, y, z coordinates in local IB frame - real(wp), dimension(1:3,1:3) :: rotation, inverse_rotation - real(wp) :: length_z - integer :: i, j, k, l, ib_patch_id !< Loop index variables + + real(wp) :: dist, dist_surf, dist_side, global_dist + integer :: global_id + real(wp) :: lz, z_max, z_min + real(wp), dimension(3) :: dist_vec + + real(wp), dimension(1:3) :: xyz_local, center, offset, normal !< x, y, z coordinates in local IB frame + real(wp), dimension(1:3, 1:3) :: rotation, inverse_rotation + + real(wp) :: length_z + + integer :: i, j, k, l, ib_patch_id !< Loop index variables + ib_patch_id = gp%ib_patch_id i = gp%loc(1) j = gp%loc(2) l = gp%loc(3) - center(1) = patch_ib(ib_patch_id)%x_centroid + real(gp%x_periodicity, wp)*(x_domain%end - x_domain%beg) - center(2) = patch_ib(ib_patch_id)%y_centroid + real(gp%y_periodicity, wp)*(y_domain%end - y_domain%beg) - center(3) = patch_ib(ib_patch_id)%z_centroid + real(gp%z_periodicity, wp)*(z_domain%end - z_domain%beg) + center(1) = patch_ib(ib_patch_id)%x_centroid + real(gp%x_periodicity, wp)*(glb_bounds(1)%end - glb_bounds(1)%beg) + center(2) = patch_ib(ib_patch_id)%y_centroid + real(gp%y_periodicity, wp)*(glb_bounds(2)%end - glb_bounds(2)%beg) + center(3) = patch_ib(ib_patch_id)%z_centroid + real(gp%z_periodicity, wp)*(glb_bounds(3)%end - glb_bounds(3)%beg) lz = patch_ib(ib_patch_id)%length_z - inverse_rotation(:,:) = patch_ib(ib_patch_id)%rotation_matrix_inverse(:,:) - rotation(:,:) = patch_ib(ib_patch_id)%rotation_matrix(:,:) + inverse_rotation(:, :) = patch_ib(ib_patch_id)%rotation_matrix_inverse(:, :) + rotation(:, :) = patch_ib(ib_patch_id)%rotation_matrix(:, :) offset(:) = patch_ib(ib_patch_id)%centroid_offset(:) z_max = lz/2 z_min = -lz/2 xyz_local = [x_cc(i), y_cc(j), z_cc(l)] - center - xyz_local = matmul(inverse_rotation, xyz_local) ! rotate the frame into the IB's coordinates - xyz_local = xyz_local - offset ! airfoils are a patch that require a centroid offset + xyz_local = matmul(inverse_rotation, xyz_local) ! rotate the frame into the IB's coordinates + xyz_local = xyz_local - offset ! airfoils are a patch that require a centroid offset if (xyz_local(2) >= 0._wp) then do k = 1, Np @@ -280,32 +302,36 @@ contains end subroutine s_3d_airfoil_levelset - !> Subroutine for computing the levelset values at a ghost point belonging to the rectangle IB + !> Subroutine for computing the levelset values at a ghost point belonging to the rectangle IB subroutine s_rectangle_levelset(gp) $:GPU_ROUTINE(parallelism='[seq]') type(ghost_point), intent(inout) :: gp - real(wp) :: top_right(2), bottom_left(2) - real(wp) :: min_dist - real(wp) :: side_dists(4) - real(wp) :: length_x, length_y - real(wp), dimension(1:3) :: xy_local, dist_vec !< x and y coordinates in local IB frame - real(wp), dimension(2) :: center !< x and y coordinates in local IB frame - real(wp), dimension(1:3,1:3) :: rotation, inverse_rotation - integer :: i, j, k !< Loop index variables - integer :: idx !< Shortest path direction indicator - integer :: ib_patch_id !< patch ID + + real(wp) :: top_right(2), bottom_left(2) + real(wp) :: min_dist + real(wp) :: side_dists(4) + + real(wp) :: length_x, length_y + real(wp), dimension(1:3) :: xy_local, dist_vec !< x and y coordinates in local IB frame + real(wp), dimension(2) :: center !< x and y coordinates in local IB frame + real(wp), dimension(1:3, 1:3) :: rotation, inverse_rotation + + integer :: i, j, k !< Loop index variables + integer :: idx !< Shortest path direction indicator + integer :: ib_patch_id !< patch ID + ib_patch_id = gp%ib_patch_id i = gp%loc(1) j = gp%loc(2) length_x = patch_ib(ib_patch_id)%length_x length_y = patch_ib(ib_patch_id)%length_y - center(1) = patch_ib(ib_patch_id)%x_centroid + real(gp%x_periodicity, wp)*(x_domain%end - x_domain%beg) - center(2) = patch_ib(ib_patch_id)%y_centroid + real(gp%y_periodicity, wp)*(y_domain%end - y_domain%beg) - inverse_rotation(:,:) = patch_ib(ib_patch_id)%rotation_matrix_inverse(:,:) - rotation(:,:) = patch_ib(ib_patch_id)%rotation_matrix(:,:) + center(1) = patch_ib(ib_patch_id)%x_centroid + real(gp%x_periodicity, wp)*(glb_bounds(1)%end - glb_bounds(1)%beg) + center(2) = patch_ib(ib_patch_id)%y_centroid + real(gp%y_periodicity, wp)*(glb_bounds(2)%end - glb_bounds(2)%beg) + inverse_rotation(:, :) = patch_ib(ib_patch_id)%rotation_matrix_inverse(:, :) + rotation(:, :) = patch_ib(ib_patch_id)%rotation_matrix(:, :) top_right(1) = length_x/2 top_right(2) = length_y/2 @@ -348,31 +374,35 @@ contains end subroutine s_rectangle_levelset - !> Compute the signed distance and outward normal from a ghost point to an elliptical immersed boundary + !> @brief Computes the signed distance and outward normal from a ghost point to an elliptical immersed boundary via a quadratic projection. subroutine s_ellipse_levelset(gp) $:GPU_ROUTINE(parallelism='[seq]') type(ghost_point), intent(inout) :: gp - real(wp) :: ellipse_coeffs(2) !< a and b in the ellipse equation - real(wp) :: quadratic_coeffs(3) !< A, B, C in the quadratic equation to compute levelset - real(wp) :: length_x, length_y - real(wp), dimension(1:3) :: xy_local, normal_vector !< x and y coordinates in local IB frame - real(wp), dimension(2) :: center !< x and y coordinates in local IB frame - real(wp), dimension(1:3,1:3) :: rotation, inverse_rotation - integer :: i, j, k !< Loop index variables - integer :: idx !< Shortest path direction indicator - integer :: ib_patch_id !< patch ID + + real(wp) :: ellipse_coeffs(2) ! a and b in the ellipse equation + real(wp) :: quadratic_coeffs(3) ! A, B, C in the quadratic equation to compute levelset + + real(wp) :: length_x, length_y + real(wp), dimension(1:3) :: xy_local, normal_vector !< x and y coordinates in local IB frame + real(wp), dimension(2) :: center !< x and y coordinates in local IB frame + real(wp), dimension(1:3, 1:3) :: rotation, inverse_rotation + + integer :: i, j, k !< Loop index variables + integer :: idx !< Shortest path direction indicator + integer :: ib_patch_id !< patch ID + ib_patch_id = gp%ib_patch_id i = gp%loc(1) j = gp%loc(2) length_x = patch_ib(ib_patch_id)%length_x length_y = patch_ib(ib_patch_id)%length_y - center(1) = patch_ib(ib_patch_id)%x_centroid + real(gp%x_periodicity, wp)*(x_domain%end - x_domain%beg) - center(2) = patch_ib(ib_patch_id)%y_centroid + real(gp%y_periodicity, wp)*(y_domain%end - y_domain%beg) - inverse_rotation(:,:) = patch_ib(ib_patch_id)%rotation_matrix_inverse(:,:) - rotation(:,:) = patch_ib(ib_patch_id)%rotation_matrix(:,:) + center(1) = patch_ib(ib_patch_id)%x_centroid + real(gp%x_periodicity, wp)*(glb_bounds(1)%end - glb_bounds(1)%beg) + center(2) = patch_ib(ib_patch_id)%y_centroid + real(gp%y_periodicity, wp)*(glb_bounds(2)%end - glb_bounds(2)%beg) + inverse_rotation(:, :) = patch_ib(ib_patch_id)%rotation_matrix_inverse(:, :) + rotation(:, :) = patch_ib(ib_patch_id)%rotation_matrix(:, :) ellipse_coeffs(1) = 0.5_wp*length_x ellipse_coeffs(2) = 0.5_wp*length_y @@ -381,38 +411,39 @@ contains xy_local = matmul(inverse_rotation, xy_local) normal_vector = xy_local - normal_vector(2) = normal_vector(2)*(ellipse_coeffs(1)/ellipse_coeffs(2)) & - & **2._wp ! get the normal direction via the coordinate transformation method - normal_vector = normal_vector/sqrt(dot_product(normal_vector, normal_vector)) ! normalize the vector - gp%levelset_norm = matmul(rotation, normal_vector) ! save after rotating the vector to the global frame + normal_vector(2) = normal_vector(2)*(ellipse_coeffs(1)/ellipse_coeffs(2))**2._wp ! get the normal direction via the coordinate transformation method + normal_vector = normal_vector/sqrt(dot_product(normal_vector, normal_vector)) ! normalize the vector + gp%levelset_norm = matmul(rotation, normal_vector) ! save after rotating the vector to the global frame ! use the normal vector to set up the quadratic equation for the levelset, using A, B, and C in indices 1, 2, and 3 quadratic_coeffs(1) = (normal_vector(1)/ellipse_coeffs(1))**2 + (normal_vector(2)/ellipse_coeffs(2))**2 - quadratic_coeffs(2) = 2._wp*((xy_local(1)*normal_vector(1)/(ellipse_coeffs(1)**2)) + (xy_local(2)*normal_vector(2) & - & /(ellipse_coeffs(2)**2))) + quadratic_coeffs(2) = 2._wp*((xy_local(1)*normal_vector(1)/(ellipse_coeffs(1)**2)) + (xy_local(2)*normal_vector(2)/(ellipse_coeffs(2)**2))) quadratic_coeffs(3) = (xy_local(1)/ellipse_coeffs(1))**2._wp + (xy_local(2)/ellipse_coeffs(2))**2._wp - 1._wp ! compute the levelset with the quadratic equation [ -B + sqrt(B^2 - 4AC) ] / 2A - gp%levelset = -0.5_wp*(-quadratic_coeffs(2) + sqrt(quadratic_coeffs(2)**2._wp - 4._wp*quadratic_coeffs(1) & - & *quadratic_coeffs(3)))/quadratic_coeffs(1) + gp%levelset = -0.5_wp*(-quadratic_coeffs(2) + sqrt(quadratic_coeffs(2)**2._wp - 4._wp*quadratic_coeffs(1)*quadratic_coeffs(3)))/quadratic_coeffs(1) end subroutine s_ellipse_levelset - !> Compute the signed distance and outward normal from a ghost point to a cuboid immersed boundary + !> @brief Computes the signed distance and outward normal from a ghost point to the nearest face of a cuboid immersed boundary. subroutine s_cuboid_levelset(gp) $:GPU_ROUTINE(parallelism='[seq]') type(ghost_point), intent(inout) :: gp - real(wp) :: Right, Left, Bottom, Top, Front, Back - real(wp) :: min_dist - real(wp) :: dist_left, dist_right, dist_bottom, dist_top, dist_back, dist_front - real(wp), dimension(3) :: center - real(wp) :: length_x, length_y, length_z - real(wp), dimension(1:3) :: xyz_local, dist_vec !< x and y coordinates in local IB frame - real(wp), dimension(1:3,1:3) :: rotation, inverse_rotation - integer :: i, j, k !< Loop index variables - integer :: ib_patch_id !< patch ID + + real(wp) :: Right, Left, Bottom, Top, Front, Back + real(wp) :: min_dist + real(wp) :: dist_left, dist_right, dist_bottom, dist_top, dist_back, dist_front + + real(wp), dimension(3) :: center + real(wp) :: length_x, length_y, length_z + real(wp), dimension(1:3) :: xyz_local, dist_vec !< x and y coordinates in local IB frame + real(wp), dimension(1:3, 1:3) :: rotation, inverse_rotation + + integer :: i, j, k !< Loop index variables + integer :: ib_patch_id !< patch ID + ib_patch_id = gp%ib_patch_id i = gp%loc(1) j = gp%loc(2) @@ -422,12 +453,12 @@ contains length_y = patch_ib(ib_patch_id)%length_y length_z = patch_ib(ib_patch_id)%length_z - center(1) = patch_ib(ib_patch_id)%x_centroid + real(gp%x_periodicity, wp)*(x_domain%end - x_domain%beg) - center(2) = patch_ib(ib_patch_id)%y_centroid + real(gp%y_periodicity, wp)*(y_domain%end - y_domain%beg) - center(3) = patch_ib(ib_patch_id)%z_centroid + real(gp%z_periodicity, wp)*(z_domain%end - z_domain%beg) + center(1) = patch_ib(ib_patch_id)%x_centroid + real(gp%x_periodicity, wp)*(glb_bounds(1)%end - glb_bounds(1)%beg) + center(2) = patch_ib(ib_patch_id)%y_centroid + real(gp%y_periodicity, wp)*(glb_bounds(2)%end - glb_bounds(2)%beg) + center(3) = patch_ib(ib_patch_id)%z_centroid + real(gp%z_periodicity, wp)*(glb_bounds(3)%end - glb_bounds(3)%beg) - inverse_rotation(:,:) = patch_ib(ib_patch_id)%rotation_matrix_inverse(:,:) - rotation(:,:) = patch_ib(ib_patch_id)%rotation_matrix(:,:) + inverse_rotation(:, :) = patch_ib(ib_patch_id)%rotation_matrix_inverse(:, :) + rotation(:, :) = patch_ib(ib_patch_id)%rotation_matrix(:, :) Right = length_x/2 Left = -length_x/2 @@ -436,8 +467,8 @@ contains Front = length_z/2 Back = -length_z/2 - xyz_local = [x_cc(i), y_cc(j), z_cc(k)] - center ! get coordinate frame centered on IB - xyz_local = matmul(inverse_rotation, xyz_local) ! rotate the frame into the IB's coordinate + xyz_local = [x_cc(i), y_cc(j), z_cc(k)] - center ! get coordinate frame centered on IB + xyz_local = matmul(inverse_rotation, xyz_local) ! rotate the frame into the IB's coordinate dist_left = Left - xyz_local(1) dist_right = xyz_local(1) - Right @@ -446,7 +477,8 @@ contains dist_back = Back - xyz_local(3) dist_front = xyz_local(3) - Front - min_dist = min(abs(dist_left), abs(dist_right), abs(dist_bottom), abs(dist_top), abs(dist_back), abs(dist_front)) + min_dist = min(abs(dist_left), abs(dist_right), abs(dist_bottom), & + abs(dist_top), abs(dist_back), abs(dist_front)) dist_vec = 0._wp if (f_approx_equal(min_dist, abs(dist_left))) then @@ -485,24 +517,27 @@ contains end subroutine s_cuboid_levelset - !> Compute the signed distance and outward normal from a ghost point to a spherical immersed boundary + !> @brief Computes the signed distance and outward normal from a ghost point to a spherical immersed boundary. subroutine s_sphere_levelset(gp) $:GPU_ROUTINE(parallelism='[seq]') type(ghost_point), intent(inout) :: gp - real(wp) :: radius, dist - real(wp), dimension(3) :: dist_vec, center, periodicity - integer :: i, j, k, ib_patch_id !< Loop index variables + + real(wp) :: radius, dist + real(wp), dimension(3) :: dist_vec, center, periodicity + + integer :: i, j, k, ib_patch_id !< Loop index variables + ib_patch_id = gp%ib_patch_id i = gp%loc(1) j = gp%loc(2) k = gp%loc(3) radius = patch_ib(ib_patch_id)%radius - periodicity(1) = real(gp%x_periodicity, wp)*(x_domain%end - x_domain%beg) - periodicity(2) = real(gp%y_periodicity, wp)*(y_domain%end - y_domain%beg) - periodicity(3) = real(gp%z_periodicity, wp)*(z_domain%end - z_domain%beg) + periodicity(1) = real(gp%x_periodicity, wp)*(glb_bounds(1)%end - glb_bounds(1)%beg) + periodicity(2) = real(gp%y_periodicity, wp)*(glb_bounds(2)%end - glb_bounds(2)%beg) + periodicity(3) = real(gp%z_periodicity, wp)*(glb_bounds(3)%end - glb_bounds(3)%beg) center(1) = patch_ib(ib_patch_id)%x_centroid center(2) = patch_ib(ib_patch_id)%y_centroid center(3) = patch_ib(ib_patch_id)%z_centroid @@ -521,20 +556,22 @@ contains end subroutine s_sphere_levelset - !> Compute the signed distance and outward normal from a ghost point to a cylindrical immersed boundary + !> @brief Computes the signed distance and outward normal from a ghost point to a cylindrical immersed boundary surface and end caps. subroutine s_cylinder_levelset(gp) $:GPU_ROUTINE(parallelism='[seq]') type(ghost_point), intent(inout) :: gp - real(wp) :: radius - real(wp), dimension(3) :: dist_sides_vec, dist_surface_vec, length - real(wp), dimension(2) :: boundary - real(wp) :: dist_side, dist_surface, side_pos - integer :: i, j, k !< Loop index variables - integer :: ib_patch_id !< patch ID - real(wp), dimension(1:3) :: xyz_local, center !< x and y coordinates in local IB frame - real(wp), dimension(1:3,1:3) :: rotation, inverse_rotation + + real(wp) :: radius + real(wp), dimension(3) :: dist_sides_vec, dist_surface_vec, length + real(wp), dimension(2) :: boundary + real(wp) :: dist_side, dist_surface, side_pos + integer :: i, j, k !< Loop index variables + integer :: ib_patch_id !< patch ID + + real(wp), dimension(1:3) :: xyz_local, center !< x and y coordinates in local IB frame + real(wp), dimension(1:3, 1:3) :: rotation, inverse_rotation ib_patch_id = gp%ib_patch_id i = gp%loc(1) @@ -542,15 +579,15 @@ contains k = gp%loc(3) radius = patch_ib(ib_patch_id)%radius - center(1) = patch_ib(ib_patch_id)%x_centroid + real(gp%x_periodicity, wp)*(x_domain%end - x_domain%beg) - center(2) = patch_ib(ib_patch_id)%y_centroid + real(gp%y_periodicity, wp)*(y_domain%end - y_domain%beg) - center(3) = patch_ib(ib_patch_id)%z_centroid + real(gp%z_periodicity, wp)*(z_domain%end - z_domain%beg) + center(1) = patch_ib(ib_patch_id)%x_centroid + real(gp%x_periodicity, wp)*(glb_bounds(1)%end - glb_bounds(1)%beg) + center(2) = patch_ib(ib_patch_id)%y_centroid + real(gp%y_periodicity, wp)*(glb_bounds(2)%end - glb_bounds(2)%beg) + center(3) = patch_ib(ib_patch_id)%z_centroid + real(gp%z_periodicity, wp)*(glb_bounds(3)%end - glb_bounds(3)%beg) length(1) = patch_ib(ib_patch_id)%length_x length(2) = patch_ib(ib_patch_id)%length_y length(3) = patch_ib(ib_patch_id)%length_z - inverse_rotation(:,:) = patch_ib(ib_patch_id)%rotation_matrix_inverse(:,:) - rotation(:,:) = patch_ib(ib_patch_id)%rotation_matrix(:,:) + inverse_rotation(:, :) = patch_ib(ib_patch_id)%rotation_matrix_inverse(:, :) + rotation(:, :) = patch_ib(ib_patch_id)%rotation_matrix(:, :) if (.not. f_approx_equal(length(1), 0._wp)) then boundary(1) = -0.5_wp*length(1) @@ -569,14 +606,16 @@ contains dist_surface_vec = (/1, 1, 0/) end if - xyz_local = [x_cc(i), y_cc(j), z_cc(k)] - center ! get coordinate frame centered on IB - xyz_local = matmul(inverse_rotation, xyz_local) ! rotate the frame into the IB's coordinates + xyz_local = [x_cc(i), y_cc(j), z_cc(k)] - center ! get coordinate frame centered on IB + xyz_local = matmul(inverse_rotation, xyz_local) ! rotate the frame into the IB's coordinates ! get distance to flat edge of cylinder side_pos = dot_product(xyz_local, dist_sides_vec) - dist_side = min(abs(side_pos - boundary(1)), abs(boundary(2) - side_pos)) + dist_side = min(abs(side_pos - boundary(1)), & + abs(boundary(2) - side_pos)) ! get distance to curved side of cylinder - dist_surface = norm2(xyz_local*dist_surface_vec) - radius + dist_surface = norm2(xyz_local*dist_surface_vec) & + - radius if (dist_side < abs(dist_surface)) then ! if the closest edge is flat @@ -596,16 +635,18 @@ contains end subroutine s_cylinder_levelset !> The STL patch is a 2/3D geometry that is imported from an STL file. + !! @param gp Ghost point to compute levelset for subroutine s_model_levelset(gp) $:GPU_ROUTINE(parallelism='[seq]') type(ghost_point), intent(inout) :: gp - integer :: i, j, k, patch_id, boundary_edge_count, total_vertices - real(wp), dimension(1:3) :: center, xyz_local - real(wp) :: normals(1:3) !< Boundary normal buffer - real(wp) :: distance - real(wp), dimension(1:3,1:3) :: inverse_rotation, rotation + + integer :: i, j, k, patch_id, boundary_edge_count, total_vertices + real(wp), dimension(1:3) :: center, xyz_local + real(wp) :: normals(1:3) !< Boundary normal buffer + real(wp) :: distance + real(wp), dimension(1:3, 1:3) :: inverse_rotation, rotation patch_id = gp%ib_patch_id i = gp%loc(1) @@ -617,17 +658,14 @@ contains total_vertices = gpu_total_vertices(patch_id) center = 0._wp - if (.not. f_is_default(patch_ib(patch_id)%x_centroid)) center(1) = patch_ib(patch_id)%x_centroid + real(gp%x_periodicity, & - & wp)*(x_domain%end - x_domain%beg) - if (.not. f_is_default(patch_ib(patch_id)%y_centroid)) center(2) = patch_ib(patch_id)%y_centroid + real(gp%y_periodicity, & - & wp)*(y_domain%end - y_domain%beg) + if (.not. f_is_default(patch_ib(patch_id)%x_centroid)) center(1) = patch_ib(patch_id)%x_centroid + real(gp%x_periodicity, wp)*(glb_bounds(1)%end - glb_bounds(1)%beg) + if (.not. f_is_default(patch_ib(patch_id)%y_centroid)) center(2) = patch_ib(patch_id)%y_centroid + real(gp%y_periodicity, wp)*(glb_bounds(2)%end - glb_bounds(2)%beg) if (p > 0) then - if (.not. f_is_default(patch_ib(patch_id)%z_centroid)) center(3) = patch_ib(patch_id)%z_centroid & - & + real(gp%z_periodicity, wp)*(z_domain%end - z_domain%beg) + if (.not. f_is_default(patch_ib(patch_id)%z_centroid)) center(3) = patch_ib(patch_id)%z_centroid + real(gp%z_periodicity, wp)*(glb_bounds(3)%end - glb_bounds(3)%beg) end if - inverse_rotation(:,:) = patch_ib(patch_id)%rotation_matrix_inverse(:,:) - rotation(:,:) = patch_ib(patch_id)%rotation_matrix(:,:) + inverse_rotation(:, :) = patch_ib(patch_id)%rotation_matrix_inverse(:, :) + rotation(:, :) = patch_ib(patch_id)%rotation_matrix(:, :) ! determine where we are located in space xyz_local = (/x_cc(i) - center(1), y_cc(j) - center(2), 0._wp/) @@ -649,7 +687,9 @@ contains gp%levelset_norm = matmul(rotation, normals(1:3)) else ! 2D models - call s_distance_normals_2D(patch_id, boundary_edge_count, xyz_local, normals, distance) + call s_distance_normals_2D(patch_id, & + boundary_edge_count, & + xyz_local, normals, distance) gp%levelset = -abs(distance) gp%levelset_norm = matmul(rotation, normals(1:3)) end if diff --git a/src/simulation/m_data_output.fpp b/src/simulation/m_data_output.fpp index 086a218289..58b5c4cd1a 100644 --- a/src/simulation/m_data_output.fpp +++ b/src/simulation/m_data_output.fpp @@ -8,48 +8,61 @@ !> @brief Writes solution data, run-time stability diagnostics (ICFL, VCFL, CCFL, Rc), and probe/center-of-mass files module m_data_output - use m_derived_types - use m_global_parameters - use m_mpi_proxy - use m_variables_conversion + use m_derived_types !< Definitions of the derived types + + use m_global_parameters !< Definitions of the global parameters + + use m_mpi_proxy !< Message passing interface (MPI) module proxy + + use m_variables_conversion !< State variables type conversion procedures + use m_compile_specific + use m_helper - use m_helper_basic + + use m_helper_basic !< Functions to compare floating point numbers + use m_sim_helpers + use m_delay_file_access + use m_ibm + use m_boundary_common implicit none - private - public :: s_initialize_data_output_module, s_open_run_time_information_file, s_open_com_files, s_open_probe_files, & - & s_open_ib_state_file, s_write_run_time_information, s_write_data_files, s_write_serial_data_files, & - & s_write_parallel_data_files, s_write_ib_data_file, s_write_com_files, s_write_probe_files, s_write_ib_state_file, & - & s_close_run_time_information_file, s_close_com_files, s_close_probe_files, s_close_ib_state_file, & - & s_finalize_data_output_module - - integer :: ib_state_unit = -1 !< I/O unit for IB state binary file - real(wp), allocatable, dimension(:,:,:) :: icfl_sf !< ICFL stability criterion - real(wp), allocatable, dimension(:,:,:) :: vcfl_sf !< VCFL stability criterion - real(wp), allocatable, dimension(:,:,:) :: ccfl_sf !< CCFL stability criterion - real(wp), allocatable, dimension(:,:,:) :: Rc_sf !< Rc stability criterion - real(wp), public, allocatable, dimension(:,:) :: c_mass - $:GPU_DECLARE(create='[icfl_sf, vcfl_sf, ccfl_sf, Rc_sf, c_mass]') - - real(wp) :: icfl_max_loc, icfl_max_glb !< ICFL stability extrema on local and global grids - real(wp) :: vcfl_max_loc, vcfl_max_glb !< VCFL stability extrema on local and global grids - real(wp) :: ccfl_max_loc, ccfl_max_glb !< CCFL stability extrema on local and global grids - real(wp) :: Rc_min_loc, Rc_min_glb !< Rc stability extrema on local and global grids - $:GPU_DECLARE(create='[icfl_max_loc, icfl_max_glb, vcfl_max_loc, vcfl_max_glb]') - $:GPU_DECLARE(create='[ccfl_max_loc, ccfl_max_glb, Rc_min_loc, Rc_min_glb]') + private; + public :: s_initialize_data_output_module, & + s_open_run_time_information_file, & + s_open_com_files, & + s_open_probe_files, & + s_open_ib_state_file, & + s_write_run_time_information, & + s_write_data_files, & + s_write_serial_data_files, & + s_write_parallel_data_files, & + s_write_ib_data_file, & + s_write_com_files, & + s_write_probe_files, & + s_write_ib_state_file, & + s_close_run_time_information_file, & + s_close_com_files, & + s_close_probe_files, & + s_close_ib_state_file, & + s_finalize_data_output_module + + integer :: ib_state_unit = -1 !< I/O unit for IB state binary file + + real(wp), public, allocatable, dimension(:, :) :: c_mass + $:GPU_DECLARE(create='[c_mass]') !> @name ICFL, VCFL, CCFL and Rc stability criteria extrema over all the time-steps !> @{ - real(wp) :: icfl_max !< ICFL criterion maximum - real(wp) :: vcfl_max !< VCFL criterion maximum - real(wp) :: ccfl_max !< CCFL criterion maximum - real(wp) :: Rc_min !< Rc criterion maximum + real(wp) :: icfl_max !< ICFL criterion maximum + real(wp) :: vcfl_max !< VCFL criterion maximum + real(wp) :: ccfl_max !< CCFL criterion maximum + real(wp) :: Rc_min !< Rc criterion maximum !> @} type(scalar_field), allocatable, dimension(:) :: q_cons_temp_ds @@ -57,14 +70,33 @@ module m_data_output contains !> Write data files. Dispatch subroutine that replaces procedure pointer. + !! @param q_cons_vf Conservative variables + !! @param q_T_sf Temperature scalar field + !! @param q_prim_vf Primitive variables + !! @param t_step Current time step + !! @param bc_type Boundary condition type + !! @param beta Eulerian void fraction from lagrangian bubbles impure subroutine s_write_data_files(q_cons_vf, q_T_sf, q_prim_vf, t_step, bc_type, beta) - type(scalar_field), dimension(sys_size), intent(inout) :: q_cons_vf - type(scalar_field), intent(inout) :: q_T_sf - type(scalar_field), dimension(sys_size), intent(inout) :: q_prim_vf - integer, intent(in) :: t_step - type(scalar_field), intent(inout), optional :: beta - type(integer_field), dimension(1:num_dims,-1:1), intent(in) :: bc_type + type(scalar_field), & + dimension(sys_size), & + intent(inout) :: q_cons_vf + + type(scalar_field), & + intent(inout) :: q_T_sf + + type(scalar_field), & + dimension(sys_size), & + intent(inout) :: q_prim_vf + + integer, intent(in) :: t_step + + type(scalar_field), & + intent(inout), optional :: beta + + type(integer_field), & + dimension(1:num_dims, -1:1), & + intent(in) :: bc_type if (.not. parallel_io) then call s_write_serial_data_files(q_cons_vf, q_T_sf, q_prim_vf, t_step, bc_type, beta) @@ -74,136 +106,207 @@ contains end subroutine s_write_data_files - !> Open the run-time information file and write the stability criteria table header + !> The purpose of this subroutine is to open a new or pre- + !! existing run-time information file and append to it the + !! basic header information relevant to current simulation. + !! In general, this requires generating a table header for + !! those stability criteria which will be written at every + !! time-step. impure subroutine s_open_run_time_information_file - character(LEN=name_len), parameter :: file_name = 'run_time.inf' !< Name of the run-time information file - character(LEN=path_len + name_len) :: file_path !< Relative path to a file in the case directory - character(LEN=8) :: file_date !< Creation date of the run-time information file + character(LEN=name_len), parameter :: file_name = 'run_time.inf' !< + !! Name of the run-time information file + + character(LEN=path_len + name_len) :: file_path !< + !! Relative path to a file in the case directory + + character(LEN=8) :: file_date !< + !! Creation date of the run-time information file - file_path = trim(case_dir) // '/' // trim(file_name) + ! Opening the run-time information file + file_path = trim(case_dir)//'/'//trim(file_name) - open (3, FILE=trim(file_path), form='formatted', STATUS='replace') + open (3, FILE=trim(file_path), & + FORM='formatted', & + STATUS='replace') - write (3, '(A)') 'Description: Stability information at ' // 'each time-step of the simulation. This' - write (3, '(13X,A)') 'data is composed of the inviscid ' // 'Courant-Friedrichs-Lewy (ICFL)' - write (3, '(13X,A)') 'number, the viscous CFL (VCFL) number, ' // 'the capillary CFL (CCFL)' - write (3, '(13X,A)') 'number and the cell Reynolds (Rc) ' // 'number. Please note that only' - write (3, '(13X,A)') 'those stability conditions pertinent ' // 'to the physics included in' + write (3, '(A)') 'Description: Stability information at '// & + 'each time-step of the simulation. This' + write (3, '(13X,A)') 'data is composed of the inviscid '// & + 'Courant-Friedrichs-Lewy (ICFL)' + write (3, '(13X,A)') 'number, the viscous CFL (VCFL) number, '// & + 'the capillary CFL (CCFL)' + write (3, '(13X,A)') 'number and the cell Reynolds (Rc) '// & + 'number. Please note that only' + write (3, '(13X,A)') 'those stability conditions pertinent '// & + 'to the physics included in' write (3, '(13X,A)') 'the current computation are displayed.' call date_and_time(DATE=file_date) - write (3, '(A)') 'Date: ' // file_date(5:6) // '/' // file_date(7:8) // '/' // file_date(3:4) + write (3, '(A)') 'Date: '//file_date(5:6)//'/'// & + file_date(7:8)//'/'// & + file_date(3:4) write (3, '(A)') ''; write (3, '(A)') '' - write (3, '(13X,A9,13X,A10,13X,A10,13X,A10)', advance="no") trim('Time-step'), trim('dt'), trim('Time'), trim('ICFL Max') + ! Generating table header for the stability criteria to be outputted + write (3, '(13X,A9,13X,A10,13X,A10,13X,A10)', advance="no") & + trim('Time-step'), trim('dt'), trim('Time'), trim('ICFL Max') if (viscous) then - write (3, '(13X,A10,13X,A16)', advance="no") trim('VCFL Max'), trim('Rc Min') + write (3, '(13X,A10,13X,A16)', advance="no") & + trim('VCFL Max'), trim('Rc Min') end if - write (3, *) ! new line + if (bubbles_lagrange) then + write (3, '(13X,A10)', advance="no") trim('N Bubbles') + end if + + write (3, *) ! new line end subroutine s_open_run_time_information_file - !> Open center-of-mass data files for writing + !> This opens a formatted data file where the root processor + !! can write out the CoM information impure subroutine s_open_com_files() - character(len=path_len + 3*name_len) :: file_path !< Relative path to the CoM file in the case directory - integer :: i !< Generic loop iterator + character(len=path_len + 3*name_len) :: file_path !< + !! Relative path to the CoM file in the case directory + integer :: i !< Generic loop iterator do i = 1, num_fluids + ! Generating the relative path to the CoM data file write (file_path, '(A,I0,A)') '/fluid', i, '_com.dat' - file_path = trim(case_dir) // trim(file_path) - open (i + 120, file=trim(file_path), form='formatted', position='append', status='unknown') + file_path = trim(case_dir)//trim(file_path) + ! Creating the formatted data file and setting up its + ! structure + open (i + 120, file=trim(file_path), & + form='formatted', & + position='append', & + status='unknown') if (n == 0) then - write (i + 120, '(A)') ' Non-Dimensional Time ' // ' Total Mass ' // ' x-loc ' // ' Total Volume ' - else if (p == 0) then - write (i + 120, & - & '(A)') ' Non-Dimensional Time ' // ' Total Mass ' // ' x-loc ' // ' y-loc ' & - & // ' Total Volume ' + write (i + 120, '(A)') ' Non-Dimensional Time '// & + ' Total Mass '// & + ' x-loc '// & + ' Total Volume ' + elseif (p == 0) then + write (i + 120, '(A)') ' Non-Dimensional Time '// & + ' Total Mass '// & + ' x-loc '// & + ' y-loc '// & + ' Total Volume ' else - write (i + 120, & - & '(A)') ' Non-Dimensional Time ' // ' Total Mass ' // ' x-loc ' // ' y-loc ' // ' z-loc ' & - & // ' Total Volume ' + write (i + 120, '(A)') ' Non-Dimensional Time '// & + ' Total Mass '// & + ' x-loc '// & + ' y-loc '// & + ' z-loc '// & + ' Total Volume ' end if end do - end subroutine s_open_com_files - !> Open flow probe data files for writing + !> This opens a formatted data file where the root processor + !! can write out flow probe information impure subroutine s_open_probe_files - character(LEN=path_len + 3*name_len) :: file_path !< Relative path to the probe data file in the case directory - integer :: i !< Generic loop iterator - logical :: file_exist + character(LEN=path_len + 3*name_len) :: file_path !< + !! Relative path to the probe data file in the case directory + + integer :: i !< Generic loop iterator + logical :: file_exist do i = 1, num_probes + ! Generating the relative path to the data file write (file_path, '(A,I0,A)') '/D/probe', i, '_prim.dat' - file_path = trim(case_dir) // trim(file_path) + file_path = trim(case_dir)//trim(file_path) + ! Creating the formatted data file and setting up its + ! structure inquire (file=trim(file_path), exist=file_exist) if (file_exist) then - open (i + 30, FILE=trim(file_path), form='formatted', STATUS='old', POSITION='append') + open (i + 30, FILE=trim(file_path), & + FORM='formatted', & + STATUS='old', & + POSITION='append') else - open (i + 30, FILE=trim(file_path), form='formatted', STATUS='unknown') + open (i + 30, FILE=trim(file_path), & + FORM='formatted', & + STATUS='unknown') end if end do if (integral_wrt) then do i = 1, num_integrals write (file_path, '(A,I0,A)') '/D/integral', i, '_prim.dat' - file_path = trim(case_dir) // trim(file_path) + file_path = trim(case_dir)//trim(file_path) - open (i + 70, FILE=trim(file_path), form='formatted', POSITION='append', STATUS='unknown') + open (i + 70, FILE=trim(file_path), & + FORM='formatted', & + POSITION='append', & + STATUS='unknown') end do end if end subroutine s_open_probe_files - !> Open the immersed boundary state file for binary output impure subroutine s_open_ib_state_file - character(len=path_len + 2*name_len) :: file_loc - integer :: ios + integer :: ios write (file_loc, '(A)') 'ib_state.dat' - file_loc = trim(case_dir) // '/D/' // trim(file_loc) - open (newunit=ib_state_unit, file=trim(file_loc), form='unformatted', access='stream', status='replace', iostat=ios) - if (ios /= 0) call s_mpi_abort('Cannot open IB state output file: ' // trim(file_loc)) - + file_loc = trim(case_dir)//'/D/'//trim(file_loc) + open (newunit=ib_state_unit, file=trim(file_loc), & + form='unformatted', & + access='stream', & + status='replace', & + iostat=ios) + if (ios /= 0) call s_mpi_abort('Cannot open IB state output file: '//trim(file_loc)) end subroutine s_open_ib_state_file - !> Write stability criteria extrema to the run-time information file at the given time step + !> The goal of the procedure is to output to the run-time + !! information file the stability criteria extrema in the + !! entire computational domain and at the given time-step. + !! Moreover, the subroutine is also in charge of tracking + !! these stability criteria extrema over all time-steps. + !! @param q_prim_vf Cell-average primitive variables + !! @param t_step Current time step impure subroutine s_write_run_time_information(q_prim_vf, t_step) type(scalar_field), dimension(sys_size), intent(in) :: q_prim_vf - integer, intent(in) :: t_step - real(wp) :: rho !< Cell-avg. density + integer, intent(in) :: t_step + real(wp) :: rho !< Cell-avg. density #:if not MFC_CASE_OPTIMIZATION and USING_AMD - real(wp), dimension(3) :: alpha !< Cell-avg. volume fraction - real(wp), dimension(3) :: vel !< Cell-avg. velocity + real(wp), dimension(3) :: alpha !< Cell-avg. volume fraction + real(wp), dimension(3) :: vel !< Cell-avg. velocity #:else - real(wp), dimension(num_fluids) :: alpha !< Cell-avg. volume fraction - real(wp), dimension(num_vels) :: vel !< Cell-avg. velocity + real(wp), dimension(num_fluids) :: alpha !< Cell-avg. volume fraction + real(wp), dimension(num_vels) :: vel !< Cell-avg. velocity #:endif - real(wp) :: vel_sum !< Cell-avg. velocity sum - real(wp) :: pres !< Cell-avg. pressure - real(wp) :: gamma !< Cell-avg. sp. heat ratio - real(wp) :: pi_inf !< Cell-avg. liquid stiffness function - real(wp) :: qv !< Cell-avg. internal energy reference value - real(wp) :: c !< Cell-avg. sound speed - real(wp) :: H !< Cell-avg. enthalpy - real(wp), dimension(2) :: Re !< Cell-avg. Reynolds numbers - integer :: j, k, l - + real(wp) :: vel_sum !< Cell-avg. velocity sum + real(wp) :: pres !< Cell-avg. pressure + real(wp) :: gamma !< Cell-avg. sp. heat ratio + real(wp) :: pi_inf !< Cell-avg. liquid stiffness function + real(wp) :: qv !< Cell-avg. internal energy reference value + real(wp) :: c !< Cell-avg. sound speed + real(wp) :: H !< Cell-avg. enthalpy + real(wp), dimension(2) :: Re !< Cell-avg. Reynolds numbers + integer :: j, k, l + real(wp) :: icfl_max_loc, icfl_max_glb !< ICFL stability extrema on local and global grids + real(wp) :: vcfl_max_loc, vcfl_max_glb !< VCFL stability extrema on local and global grids + real(wp) :: ccfl_max_loc, ccfl_max_glb !< CCFL stability extrema on local and global grids + real(wp) :: Rc_min_loc, Rc_min_glb !< Rc stability extrema on local and global grids + real(wp) :: icfl, vcfl, Rc + + icfl_max_loc = 0._wp + vcfl_max_loc = 0._wp + Rc_min_loc = huge(1.0_wp) ! Computing Stability Criteria at Current Time-step - - $:GPU_PARALLEL_LOOP(collapse=3, private='[j, k, l, vel, alpha, Re, rho, vel_sum, pres, gamma, pi_inf, c, H, qv]') + $:GPU_PARALLEL_LOOP(collapse=3, private='[j,k,l,vel, alpha, Re, rho, vel_sum, pres, gamma, pi_inf, c, H, qv, icfl, vcfl, Rc]', & + & reduction='[[icfl_max_loc,vcfl_max_loc],[Rc_min_loc]]', reductionOp='[max,min]') do l = 0, p do k = 0, n do j = 0, m @@ -212,49 +315,38 @@ contains call s_compute_speed_of_sound(pres, rho, gamma, pi_inf, H, alpha, vel_sum, 0._wp, c, qv) if (viscous) then - call s_compute_stability_from_dt(vel, c, rho, Re, j, k, l, icfl_sf, vcfl_sf, Rc_sf) + call s_compute_stability_from_dt(vel, c, rho, Re, j, k, l, icfl, vcfl, Rc) else - call s_compute_stability_from_dt(vel, c, rho, Re, j, k, l, icfl_sf) + call s_compute_stability_from_dt(vel, c, rho, Re, j, k, l, icfl) end if + + icfl_max_loc = max(icfl_max_loc, icfl) + vcfl_max_loc = max(vcfl_max_loc, merge(vcfl, 0.0_wp, viscous)) + Rc_min_loc = min(Rc_min_loc, merge(Rc, huge(1.0_wp), viscous)) end do end do end do $:END_GPU_PARALLEL_LOOP() + ! end: Computing Stability Criteria at Current Time-step -#ifdef _CRAYFTN - $:GPU_UPDATE(host='[icfl_sf]') - - if (viscous) then - $:GPU_UPDATE(host='[vcfl_sf, Rc_sf]') - end if - - icfl_max_loc = maxval(icfl_sf) - - if (viscous) then - vcfl_max_loc = maxval(vcfl_sf) - Rc_min_loc = minval(Rc_sf) - end if -#else - #:call GPU_PARALLEL(copyout='[icfl_max_loc]', copyin='[icfl_sf]') - icfl_max_loc = maxval(icfl_sf) - #:endcall GPU_PARALLEL - if (viscous .or. dummy) then - #:call GPU_PARALLEL(copyout='[vcfl_max_loc, Rc_min_loc]', copyin='[vcfl_sf,Rc_sf]') - vcfl_max_loc = maxval(vcfl_sf) - Rc_min_loc = minval(Rc_sf) - #:endcall GPU_PARALLEL - end if -#endif - + ! Determining global stability criteria extrema at current time-step if (num_procs > 1) then - call s_mpi_reduce_stability_criteria_extrema(icfl_max_loc, vcfl_max_loc, Rc_min_loc, icfl_max_glb, vcfl_max_glb, & - & Rc_min_glb) + call s_mpi_reduce_stability_criteria_extrema(icfl_max_loc, & + vcfl_max_loc, & + Rc_min_loc, & + n_el_bubs_loc, & + icfl_max_glb, & + vcfl_max_glb, & + Rc_min_glb, & + n_el_bubs_glb) else icfl_max_glb = icfl_max_loc if (viscous) vcfl_max_glb = vcfl_max_loc if (viscous) Rc_min_glb = Rc_min_loc + if (bubbles_lagrange) n_el_bubs_glb = n_el_bubs_loc end if + ! Determining the stability criteria extrema over all the time-steps if (icfl_max_glb > icfl_max) icfl_max = icfl_max_glb if (viscous) then @@ -262,18 +354,26 @@ contains if (Rc_min_glb < Rc_min) Rc_min = Rc_min_glb end if + ! Outputting global stability criteria extrema at current time-step if (proc_rank == 0) then - write (3, '(13X,I9,13X,F10.6,13X,F10.6,13X,F10.6)', advance="no") t_step, dt, mytime, icfl_max_glb + write (3, '(13X,I9,13X,F10.6,13X,F10.6,13X,F10.6)', advance="no") & + t_step, dt, mytime, icfl_max_glb if (viscous) then - write (3, '(13X,F10.6,13X,ES16.6)', advance="no") vcfl_max_glb, Rc_min_glb + write (3, '(13X,F10.6,13X,ES16.6)', advance="no") & + vcfl_max_glb, & + Rc_min_glb end if - write (3, *) ! new line + if (bubbles_lagrange) then + write (3, '(13X,I10)', advance="no") n_el_bubs_glb + end if + + write (3, *) ! new line if (.not. f_approx_equal(icfl_max_glb, icfl_max_glb)) then call s_mpi_abort('ICFL is NaN. Exiting.') - else if (icfl_max_glb > 1._wp) then + elseif (icfl_max_glb > 1._wp) then print *, 'icfl', icfl_max_glb call s_mpi_abort('ICFL is greater than 1.0. Exiting.') end if @@ -281,18 +381,31 @@ contains if (viscous) then if (.not. f_approx_equal(vcfl_max_glb, vcfl_max_glb)) then call s_mpi_abort('VCFL is NaN. Exiting.') - else if (vcfl_max_glb > 1._wp) then + elseif (vcfl_max_glb > 1._wp) then print *, 'vcfl', vcfl_max_glb call s_mpi_abort('VCFL is greater than 1.0. Exiting.') end if end if + + if (bubbles_lagrange) then + if (n_el_bubs_glb == 0) then + call s_mpi_abort('No Lagrangian bubbles remain in the domain. Exiting.') + end if + end if end if call s_mpi_barrier() end subroutine s_write_run_time_information - !> Write grid and conservative variable data files in serial format + !> The goal of this subroutine is to output the grid and + !! conservative variables data files for given time-step. + !! @param q_cons_vf Cell-average conservative variables + !! @param q_T_sf Temperature scalar field + !! @param q_prim_vf Cell-average primitive variables + !! @param t_step Current time-step + !! @param bc_type Boundary condition type + !! @param beta Eulerian void fraction from lagrangian bubbles impure subroutine s_write_serial_data_files(q_cons_vf, q_T_sf, q_prim_vf, t_step, bc_type, beta) type(scalar_field), dimension(sys_size), intent(inout) :: q_cons_vf @@ -300,77 +413,115 @@ contains type(scalar_field), dimension(sys_size), intent(inout) :: q_prim_vf integer, intent(in) :: t_step type(scalar_field), intent(inout), optional :: beta - type(integer_field), dimension(1:num_dims,-1:1), intent(in) :: bc_type - character(LEN=path_len + 2*name_len) :: t_step_dir !< Relative path to the current time-step directory - character(LEN=path_len + 3*name_len) :: file_path !< Relative path to the grid and conservative variables data files - logical :: file_exist !< Logical used to check existence of current time-step directory + type(integer_field), dimension(1:num_dims, -1:1), intent(in) :: bc_type + + character(LEN=path_len + 2*name_len) :: t_step_dir !< + !! Relative path to the current time-step directory + + character(LEN=path_len + 3*name_len) :: file_path !< + !! Relative path to the grid and conservative variables data files + + logical :: file_exist !< + !! Logical used to check existence of current time-step directory + character(LEN=15) :: FMT + integer :: i, j, k, l, r - real(wp) :: gamma, lit_gamma, pi_inf, qv !< Temporary EOS params - write (t_step_dir, '(A,I0,A,I0)') trim(case_dir) // '/p_all' - write (t_step_dir, '(a,i0,a,i0)') trim(case_dir) // '/p_all/p', proc_rank, '/', t_step + real(wp) :: gamma, lit_gamma, pi_inf, qv !< Temporary EOS params + + ! Creating or overwriting the time-step root directory + write (t_step_dir, '(A,I0,A,I0)') trim(case_dir)//'/p_all' + + ! Creating or overwriting the current time-step directory + write (t_step_dir, '(a,i0,a,i0)') trim(case_dir)//'/p_all/p', & + proc_rank, '/', t_step - file_path = trim(t_step_dir) // '/.' + file_path = trim(t_step_dir)//'/.' call my_inquire(file_path, file_exist) if (file_exist) call s_delete_directory(trim(t_step_dir)) call s_create_directory(trim(t_step_dir)) - file_path = trim(t_step_dir) // '/x_cb.dat' + ! Writing the grid data file in the x-direction + file_path = trim(t_step_dir)//'/x_cb.dat' - open (2, FILE=trim(file_path), form='unformatted', STATUS='new') + open (2, FILE=trim(file_path), & + FORM='unformatted', & + STATUS='new') write (2) x_cb(-1:m); close (2) + ! Writing the grid data files in the y- and z-directions if (n > 0) then - file_path = trim(t_step_dir) // '/y_cb.dat' - open (2, FILE=trim(file_path), form='unformatted', STATUS='new') + file_path = trim(t_step_dir)//'/y_cb.dat' + + open (2, FILE=trim(file_path), & + FORM='unformatted', & + STATUS='new') write (2) y_cb(-1:n); close (2) if (p > 0) then - file_path = trim(t_step_dir) // '/z_cb.dat' - open (2, FILE=trim(file_path), form='unformatted', STATUS='new') + file_path = trim(t_step_dir)//'/z_cb.dat' + + open (2, FILE=trim(file_path), & + FORM='unformatted', & + STATUS='new') write (2) z_cb(-1:p); close (2) + end if + end if + ! Writing the conservative variables data files do i = 1, sys_size - write (file_path, '(A,I0,A)') trim(t_step_dir) // '/q_cons_vf', i, '.dat' + write (file_path, '(A,I0,A)') trim(t_step_dir)//'/q_cons_vf', & + i, '.dat' - open (2, FILE=trim(file_path), form='unformatted', STATUS='new') + open (2, FILE=trim(file_path), & + FORM='unformatted', & + STATUS='new') - write (2) q_cons_vf(i)%sf(0:m,0:n,0:p); close (2) + write (2) q_cons_vf(i)%sf(0:m, 0:n, 0:p); close (2) end do - ! Lagrangian beta (void fraction) written as q_cons_vf(sys_size+1) to match the parallel I/O path and allow post_process to - ! read it. + ! Lagrangian beta (void fraction) written as q_cons_vf(sys_size+1) to + ! match the parallel I/O path and allow post_process to read it. if (bubbles_lagrange) then - write (file_path, '(A,I0,A)') trim(t_step_dir) // '/q_cons_vf', sys_size + 1, '.dat' + write (file_path, '(A,I0,A)') trim(t_step_dir)//'/q_cons_vf', & + sys_size + 1, '.dat' - open (2, FILE=trim(file_path), form='unformatted', STATUS='new') + open (2, FILE=trim(file_path), & + FORM='unformatted', & + STATUS='new') - write (2) beta%sf(0:m,0:n,0:p); close (2) + write (2) beta%sf(0:m, 0:n, 0:p); close (2) end if if (qbmm .and. .not. polytropic) then do i = 1, nb do r = 1, nnode - write (file_path, '(A,I0,A)') trim(t_step_dir) // '/pb', sys_size + (i - 1)*nnode + r, '.dat' + write (file_path, '(A,I0,A)') trim(t_step_dir)//'/pb', & + sys_size + (i - 1)*nnode + r, '.dat' - open (2, FILE=trim(file_path), form='unformatted', STATUS='new') + open (2, FILE=trim(file_path), & + FORM='unformatted', & + STATUS='new') - write (2) pb_ts(1)%sf(0:m,0:n,0:p,r, i); close (2) + write (2) pb_ts(1)%sf(0:m, 0:n, 0:p, r, i); close (2) end do end do do i = 1, nb do r = 1, nnode - write (file_path, '(A,I0,A)') trim(t_step_dir) // '/mv', sys_size + (i - 1)*nnode + r, '.dat' + write (file_path, '(A,I0,A)') trim(t_step_dir)//'/mv', & + sys_size + (i - 1)*nnode + r, '.dat' - open (2, FILE=trim(file_path), form='unformatted', STATUS='new') + open (2, FILE=trim(file_path), & + FORM='unformatted', & + STATUS='new') - write (2) mv_ts(1)%sf(0:m,0:n,0:p,r, i); close (2) + write (2) mv_ts(1)%sf(0:m, 0:n, 0:p, r, i); close (2) end do end do end if @@ -378,6 +529,13 @@ contains ! Writing the IB markers if (ib) then call s_write_serial_ib_data(t_step) + ! write (file_path, '(A,I0,A)') trim(t_step_dir)//'/ib.dat' + + ! open (2, FILE=trim(file_path), & + ! FORM='unformatted', & + ! STATUS='new') + + ! write (2) ib_markers%sf(0:m, 0:n, 0:p); close (2) end if gamma = gammas(1) @@ -391,8 +549,9 @@ contains FMT = "(2F40.14)" end if - write (t_step_dir, '(A,I0,A,I0)') trim(case_dir) // '/D' - file_path = trim(t_step_dir) // '/.' + ! writing an output directory + write (t_step_dir, '(A,I0,A,I0)') trim(case_dir)//'/D' + file_path = trim(t_step_dir)//'/.' inquire (FILE=trim(file_path), EXIST=file_exist) @@ -401,7 +560,7 @@ contains if ((prim_vars_wrt .or. (n == 0 .and. p == 0)) .and. (.not. igr)) then call s_convert_conservative_to_primitive_variables(q_cons_vf, q_T_sf, q_prim_vf, idwint) do i = 1, sys_size - $:GPU_UPDATE(host='[q_prim_vf(i)%sf(:, :, :)]') + $:GPU_UPDATE(host='[q_prim_vf(i)%sf(:,:,:)]') end do ! q_prim_vf(bubxb) stores the value of nb needed in riemann solvers, so replace with true primitive value (=1._wp) if (qbmm) then @@ -409,10 +568,12 @@ contains end if end if + !1D if (n == 0 .and. p == 0) then + if (model_eqns == 2 .and. (.not. igr)) then do i = 1, sys_size - write (file_path, '(A,I0,A,I2.2,A,I6.6,A)') trim(t_step_dir) // '/prim.', i, '.', proc_rank, '.', t_step, '.dat' + write (file_path, '(A,I0,A,I2.2,A,I6.6,A)') trim(t_step_dir)//'/prim.', i, '.', proc_rank, '.', t_step, '.dat' open (2, FILE=trim(file_path)) do j = 0, m @@ -428,7 +589,7 @@ contains end if do i = 1, sys_size - write (file_path, '(A,I0,A,I2.2,A,I6.6,A)') trim(t_step_dir) // '/cons.', i, '.', proc_rank, '.', t_step, '.dat' + write (file_path, '(A,I0,A,I2.2,A,I6.6,A)') trim(t_step_dir)//'/cons.', i, '.', proc_rank, '.', t_step, '.dat' open (2, FILE=trim(file_path)) do j = 0, m @@ -440,8 +601,7 @@ contains if (qbmm .and. .not. polytropic) then do i = 1, nb do r = 1, nnode - write (file_path, '(A,I0,A,I0,A,I2.2,A,I6.6,A)') trim(t_step_dir) // '/pres.', i, '.', r, '.', proc_rank, & - & '.', t_step, '.dat' + write (file_path, '(A,I0,A,I0,A,I2.2,A,I6.6,A)') trim(t_step_dir)//'/pres.', i, '.', r, '.', proc_rank, '.', t_step, '.dat' open (2, FILE=trim(file_path)) do j = 0, m @@ -452,8 +612,7 @@ contains end do do i = 1, nb do r = 1, nnode - write (file_path, '(A,I0,A,I0,A,I2.2,A,I6.6,A)') trim(t_step_dir) // '/mv.', i, '.', r, '.', proc_rank, & - & '.', t_step, '.dat' + write (file_path, '(A,I0,A,I0,A,I2.2,A,I6.6,A)') trim(t_step_dir)//'/mv.', i, '.', r, '.', proc_rank, '.', t_step, '.dat' open (2, FILE=trim(file_path)) do j = 0, m @@ -471,9 +630,10 @@ contains FMT = "(3F40.14)" end if + ! 2D if ((n > 0) .and. (p == 0)) then do i = 1, sys_size - write (file_path, '(A,I0,A,I2.2,A,I6.6,A)') trim(t_step_dir) // '/cons.', i, '.', proc_rank, '.', t_step, '.dat' + write (file_path, '(A,I0,A,I2.2,A,I6.6,A)') trim(t_step_dir)//'/cons.', i, '.', proc_rank, '.', t_step, '.dat' open (2, FILE=trim(file_path)) do j = 0, m do k = 0, n @@ -485,7 +645,7 @@ contains end do if (present(beta)) then - write (file_path, '(A,I0,A,I2.2,A,I6.6,A)') trim(t_step_dir) // '/beta.', i, '.', proc_rank, '.', t_step, '.dat' + write (file_path, '(A,I0,A,I2.2,A,I6.6,A)') trim(t_step_dir)//'/beta.', i, '.', proc_rank, '.', t_step, '.dat' open (2, FILE=trim(file_path)) do j = 0, m do k = 0, n @@ -499,8 +659,7 @@ contains if (qbmm .and. .not. polytropic) then do i = 1, nb do r = 1, nnode - write (file_path, '(A,I0,A,I0,A,I2.2,A,I6.6,A)') trim(t_step_dir) // '/pres.', i, '.', r, '.', proc_rank, & - & '.', t_step, '.dat' + write (file_path, '(A,I0,A,I0,A,I2.2,A,I6.6,A)') trim(t_step_dir)//'/pres.', i, '.', r, '.', proc_rank, '.', t_step, '.dat' open (2, FILE=trim(file_path)) do j = 0, m @@ -513,8 +672,7 @@ contains end do do i = 1, nb do r = 1, nnode - write (file_path, '(A,I0,A,I0,A,I2.2,A,I6.6,A)') trim(t_step_dir) // '/mv.', i, '.', r, '.', proc_rank, & - & '.', t_step, '.dat' + write (file_path, '(A,I0,A,I0,A,I2.2,A,I6.6,A)') trim(t_step_dir)//'/mv.', i, '.', r, '.', proc_rank, '.', t_step, '.dat' open (2, FILE=trim(file_path)) do j = 0, m @@ -529,14 +687,16 @@ contains if (prim_vars_wrt .and. (.not. igr)) then do i = 1, sys_size - write (file_path, '(A,I0,A,I2.2,A,I6.6,A)') trim(t_step_dir) // '/prim.', i, '.', proc_rank, '.', t_step, '.dat' + write (file_path, '(A,I0,A,I2.2,A,I6.6,A)') trim(t_step_dir)//'/prim.', i, '.', proc_rank, '.', t_step, '.dat' open (2, FILE=trim(file_path)) do j = 0, m do k = 0, n - if (((i >= cont_idx%beg) .and. (i <= cont_idx%end)) .or. ((i >= adv_idx%beg) .and. (i <= adv_idx%end)) & - & ) then + if (((i >= cont_idx%beg) .and. (i <= cont_idx%end)) & + .or. & + ((i >= adv_idx%beg) .and. (i <= adv_idx%end)) & + ) then write (2, FMT) x_cb(j), y_cb(k), q_cons_vf(i)%sf(j, k, 0) else write (2, FMT) x_cb(j), y_cb(k), q_prim_vf(i)%sf(j, k, 0) @@ -555,9 +715,10 @@ contains FMT = "(4F40.14)" end if + ! 3D if (p > 0) then do i = 1, sys_size - write (file_path, '(A,I0,A,I2.2,A,I6.6,A)') trim(t_step_dir) // '/cons.', i, '.', proc_rank, '.', t_step, '.dat' + write (file_path, '(A,I0,A,I2.2,A,I6.6,A)') trim(t_step_dir)//'/cons.', i, '.', proc_rank, '.', t_step, '.dat' open (2, FILE=trim(file_path)) do j = 0, m do k = 0, n @@ -572,7 +733,7 @@ contains end do if (present(beta)) then - write (file_path, '(A,I0,A,I2.2,A,I6.6,A)') trim(t_step_dir) // '/beta.', i, '.', proc_rank, '.', t_step, '.dat' + write (file_path, '(A,I0,A,I2.2,A,I6.6,A)') trim(t_step_dir)//'/beta.', i, '.', proc_rank, '.', t_step, '.dat' open (2, FILE=trim(file_path)) do j = 0, m do k = 0, n @@ -589,8 +750,7 @@ contains if (qbmm .and. .not. polytropic) then do i = 1, nb do r = 1, nnode - write (file_path, '(A,I0,A,I0,A,I2.2,A,I6.6,A)') trim(t_step_dir) // '/pres.', i, '.', r, '.', proc_rank, & - & '.', t_step, '.dat' + write (file_path, '(A,I0,A,I0,A,I2.2,A,I6.6,A)') trim(t_step_dir)//'/pres.', i, '.', r, '.', proc_rank, '.', t_step, '.dat' open (2, FILE=trim(file_path)) do j = 0, m @@ -605,8 +765,7 @@ contains end do do i = 1, nb do r = 1, nnode - write (file_path, '(A,I0,A,I0,A,I2.2,A,I6.6,A)') trim(t_step_dir) // '/mv.', i, '.', r, '.', proc_rank, & - & '.', t_step, '.dat' + write (file_path, '(A,I0,A,I0,A,I2.2,A,I6.6,A)') trim(t_step_dir)//'/mv.', i, '.', r, '.', proc_rank, '.', t_step, '.dat' open (2, FILE=trim(file_path)) do j = 0, m @@ -623,15 +782,19 @@ contains if (prim_vars_wrt .and. (.not. igr)) then do i = 1, sys_size - write (file_path, '(A,I0,A,I2.2,A,I6.6,A)') trim(t_step_dir) // '/prim.', i, '.', proc_rank, '.', t_step, '.dat' + write (file_path, '(A,I0,A,I2.2,A,I6.6,A)') trim(t_step_dir)//'/prim.', i, '.', proc_rank, '.', t_step, '.dat' open (2, FILE=trim(file_path)) do j = 0, m do k = 0, n do l = 0, p - if (((i >= cont_idx%beg) .and. (i <= cont_idx%end)) .or. ((i >= adv_idx%beg) & - & .and. (i <= adv_idx%end)) .or. ((i >= chemxb) .and. (i <= chemxe))) then + if (((i >= cont_idx%beg) .and. (i <= cont_idx%end)) & + .or. & + ((i >= adv_idx%beg) .and. (i <= adv_idx%end)) & + .or. & + ((i >= chemxb) .and. (i <= chemxe)) & + ) then write (2, FMT) x_cb(j), y_cb(k), z_cb(l), q_cons_vf(i)%sf(j, k, l) else write (2, FMT) x_cb(j), y_cb(k), z_cb(l), q_prim_vf(i)%sf(j, k, l) @@ -648,34 +811,47 @@ contains end subroutine s_write_serial_data_files - !> Write grid and conservative variable data files in parallel via MPI I/O + !> The goal of this subroutine is to output the grid and + !! conservative variables data files for given time-step. + !! @param q_cons_vf Cell-average conservative variables + !! @param t_step Current time-step + !! @param bc_type Boundary condition type + !! @param beta Eulerian void fraction from lagrangian bubbles impure subroutine s_write_parallel_data_files(q_cons_vf, t_step, bc_type, beta) - type(scalar_field), dimension(sys_size), intent(inout) :: q_cons_vf - integer, intent(in) :: t_step - type(scalar_field), intent(inout), optional :: beta - type(integer_field), dimension(1:num_dims,-1:1), intent(in) :: bc_type + type(scalar_field), dimension(sys_size), intent(inout) :: q_cons_vf + integer, intent(in) :: t_step + type(scalar_field), intent(inout), optional :: beta + type(integer_field), & + dimension(1:num_dims, -1:1), & + intent(in) :: bc_type #ifdef MFC_MPI - integer :: ifile, ierr, data_size - integer, dimension(MPI_STATUS_SIZE) :: status - integer(kind=MPI_OFFSET_kind) :: disp - integer(kind=MPI_OFFSET_kind) :: m_MOK, n_MOK, p_MOK - integer(kind=MPI_OFFSET_kind) :: WP_MOK, var_MOK, str_MOK - integer(kind=MPI_OFFSET_kind) :: NVARS_MOK - integer(kind=MPI_OFFSET_kind) :: MOK + + integer :: ifile, ierr, data_size + integer, dimension(MPI_STATUS_SIZE) :: status + integer(kind=MPI_OFFSET_kind) :: disp + integer(kind=MPI_OFFSET_kind) :: m_MOK, n_MOK, p_MOK + integer(kind=MPI_OFFSET_kind) :: WP_MOK, var_MOK, str_MOK + integer(kind=MPI_OFFSET_kind) :: NVARS_MOK + integer(kind=MPI_OFFSET_kind) :: MOK + character(LEN=path_len + 2*name_len) :: file_loc - logical :: file_exist, dir_check - character(len=10) :: t_step_string - integer :: i !< Generic loop iterator - integer :: alt_sys !< Altered system size for the lagrangian subgrid bubble model + logical :: file_exist, dir_check + character(len=10) :: t_step_string + + integer :: i !< Generic loop iterator + + integer :: alt_sys !< Altered system size for the lagrangian subgrid bubble model + ! Down sampling variables integer :: m_ds, n_ds, p_ds integer :: m_glb_ds, n_glb_ds, p_glb_ds - integer :: m_glb_save, n_glb_save, p_glb_save !< Global save size + integer :: m_glb_save, n_glb_save, p_glb_save ! Global save size if (down_sample) then - call s_downsample_data(q_cons_vf, q_cons_temp_ds, m_ds, n_ds, p_ds, m_glb_ds, n_glb_ds, p_glb_ds) + call s_downsample_data(q_cons_vf, q_cons_temp_ds, & + m_ds, n_ds, p_ds, m_glb_ds, n_glb_ds, p_glb_ds) end if if (present(beta)) then @@ -685,8 +861,10 @@ contains end if if (file_per_process) then + call s_int_to_str(t_step, t_step_string) + ! Initialize MPI data I/O if (down_sample) then call s_initialize_mpi_data_ds(q_cons_temp_ds) else @@ -698,7 +876,7 @@ contains end if if (proc_rank == 0) then - file_loc = trim(case_dir) // '/restart_data/lustre_' // trim(t_step_string) + file_loc = trim(case_dir)//'/restart_data/lustre_'//trim(t_step_string) call my_inquire(file_loc, dir_check) if (dir_check .neqv. .true.) then call s_create_directory(trim(file_loc)) @@ -708,28 +886,34 @@ contains call s_mpi_barrier() call DelayFileAccess(proc_rank) + ! Initialize MPI data I/O call s_initialize_mpi_data(q_cons_vf) + ! Open the file to write all flow variables write (file_loc, '(I0,A,i7.7,A)') t_step, '_', proc_rank, '.dat' - file_loc = trim(case_dir) // '/restart_data/lustre_' // trim(t_step_string) // trim(mpiiofs) // trim(file_loc) + file_loc = trim(case_dir)//'/restart_data/lustre_'//trim(t_step_string)//trim(mpiiofs)//trim(file_loc) inquire (FILE=trim(file_loc), EXIST=file_exist) if (file_exist .and. proc_rank == 0) then call MPI_FILE_DELETE(file_loc, mpi_info_int, ierr) end if - call MPI_FILE_OPEN(MPI_COMM_SELF, file_loc, ior(MPI_MODE_WRONLY, MPI_MODE_CREATE), mpi_info_int, ifile, ierr) + call MPI_FILE_OPEN(MPI_COMM_SELF, file_loc, ior(MPI_MODE_WRONLY, MPI_MODE_CREATE), & + mpi_info_int, ifile, ierr) if (down_sample) then + ! Size of local arrays data_size = (m_ds + 3)*(n_ds + 3)*(p_ds + 3) m_glb_save = m_glb_ds + 1 n_glb_save = n_glb_ds + 1 p_glb_save = p_glb_ds + 1 else + ! Size of local arrays data_size = (m + 1)*(n + 1)*(p + 1) m_glb_save = m_glb + 1 n_glb_save = n_glb + 1 p_glb_save = p_glb + 1 end if + ! Resize some integers so MPI can write even the biggest files m_MOK = int(m_glb_save + 1, MPI_OFFSET_KIND) n_MOK = int(n_glb_save + 1, MPI_OFFSET_KIND) p_MOK = int(p_glb_save + 1, MPI_OFFSET_KIND) @@ -739,54 +923,65 @@ contains NVARS_MOK = int(sys_size, MPI_OFFSET_KIND) if (bubbles_euler) then + ! Write the data for each variable do i = 1, sys_size var_MOK = int(i, MPI_OFFSET_KIND) - call MPI_FILE_WRITE_ALL(ifile, MPI_IO_DATA%var(i)%sf, data_size*mpi_io_type, mpi_io_p, status, ierr) + call MPI_FILE_WRITE_ALL(ifile, MPI_IO_DATA%var(i)%sf, data_size*mpi_io_type, & + mpi_io_p, status, ierr) end do + !Write pb and mv for non-polytropic qbmm if (qbmm .and. .not. polytropic) then do i = sys_size + 1, sys_size + 2*nb*nnode var_MOK = int(i, MPI_OFFSET_KIND) - call MPI_FILE_WRITE_ALL(ifile, MPI_IO_DATA%var(i)%sf, data_size*mpi_io_type, mpi_io_p, status, ierr) + call MPI_FILE_WRITE_ALL(ifile, MPI_IO_DATA%var(i)%sf, data_size*mpi_io_type, & + mpi_io_p, status, ierr) end do end if else if (down_sample) then - do i = 1, sys_size ! TODO: check if sys_size is correct + do i = 1, sys_size !TODO: check if correct (sys_size var_MOK = int(i, MPI_OFFSET_KIND) - call MPI_FILE_WRITE_ALL(ifile, q_cons_temp_ds(i)%sf, data_size*mpi_io_type, mpi_io_p, status, ierr) + call MPI_FILE_WRITE_ALL(ifile, q_cons_temp_ds(i)%sf, data_size*mpi_io_type, & + mpi_io_p, status, ierr) end do else - do i = 1, sys_size ! TODO: check if sys_size is correct + do i = 1, sys_size !TODO: check if correct (sys_size var_MOK = int(i, MPI_OFFSET_KIND) - call MPI_FILE_WRITE_ALL(ifile, MPI_IO_DATA%var(i)%sf, data_size*mpi_io_type, mpi_io_p, status, ierr) + call MPI_FILE_WRITE_ALL(ifile, MPI_IO_DATA%var(i)%sf, data_size*mpi_io_type, & + mpi_io_p, status, ierr) end do end if end if call MPI_FILE_CLOSE(ifile, ierr) else + ! Initialize MPI data I/O + if (ib) then call s_initialize_mpi_data(q_cons_vf, ib_markers) - else if (present(beta)) then + elseif (present(beta)) then call s_initialize_mpi_data(q_cons_vf, beta=beta) else call s_initialize_mpi_data(q_cons_vf) end if write (file_loc, '(I0,A)') t_step, '.dat' - file_loc = trim(case_dir) // '/restart_data' // trim(mpiiofs) // trim(file_loc) + file_loc = trim(case_dir)//'/restart_data'//trim(mpiiofs)//trim(file_loc) inquire (FILE=trim(file_loc), EXIST=file_exist) if (file_exist .and. proc_rank == 0) then call MPI_FILE_DELETE(file_loc, mpi_info_int, ierr) end if - call MPI_FILE_OPEN(MPI_COMM_WORLD, file_loc, ior(MPI_MODE_WRONLY, MPI_MODE_CREATE), mpi_info_int, ifile, ierr) + call MPI_FILE_OPEN(MPI_COMM_WORLD, file_loc, ior(MPI_MODE_WRONLY, MPI_MODE_CREATE), & + mpi_info_int, ifile, ierr) + ! Size of local arrays data_size = (m + 1)*(n + 1)*(p + 1) + ! Resize some integers so MPI can write even the biggest files m_MOK = int(m_glb + 1, MPI_OFFSET_KIND) n_MOK = int(n_glb + 1, MPI_OFFSET_KIND) p_MOK = int(p_glb + 1, MPI_OFFSET_KIND) @@ -796,87 +991,123 @@ contains NVARS_MOK = int(alt_sys, MPI_OFFSET_KIND) if (bubbles_euler) then + ! Write the data for each variable do i = 1, sys_size var_MOK = int(i, MPI_OFFSET_KIND) + ! Initial displacement to skip at beginning of file disp = m_MOK*max(MOK, n_MOK)*max(MOK, p_MOK)*WP_MOK*(var_MOK - 1) - call MPI_FILE_SET_VIEW(ifile, disp, mpi_p, MPI_IO_DATA%view(i), 'native', mpi_info_int, ierr) - call MPI_FILE_WRITE_ALL(ifile, MPI_IO_DATA%var(i)%sf, data_size*mpi_io_type, mpi_io_p, status, ierr) + call MPI_FILE_SET_VIEW(ifile, disp, mpi_p, MPI_IO_DATA%view(i), & + 'native', mpi_info_int, ierr) + call MPI_FILE_WRITE_ALL(ifile, MPI_IO_DATA%var(i)%sf, data_size*mpi_io_type, & + mpi_io_p, status, ierr) end do + !Write pb and mv for non-polytropic qbmm if (qbmm .and. .not. polytropic) then do i = sys_size + 1, sys_size + 2*nb*nnode var_MOK = int(i, MPI_OFFSET_KIND) + ! Initial displacement to skip at beginning of file disp = m_MOK*max(MOK, n_MOK)*max(MOK, p_MOK)*WP_MOK*(var_MOK - 1) - call MPI_FILE_SET_VIEW(ifile, disp, mpi_p, MPI_IO_DATA%view(i), 'native', mpi_info_int, ierr) - call MPI_FILE_WRITE_ALL(ifile, MPI_IO_DATA%var(i)%sf, data_size*mpi_io_type, mpi_io_p, status, ierr) + call MPI_FILE_SET_VIEW(ifile, disp, mpi_p, MPI_IO_DATA%view(i), & + 'native', mpi_info_int, ierr) + call MPI_FILE_WRITE_ALL(ifile, MPI_IO_DATA%var(i)%sf, data_size*mpi_io_type, & + mpi_io_p, status, ierr) end do end if else - do i = 1, sys_size ! TODO: check if sys_size is correct + do i = 1, sys_size !TODO: check if correct (sys_size var_MOK = int(i, MPI_OFFSET_KIND) + ! Initial displacement to skip at beginning of file disp = m_MOK*max(MOK, n_MOK)*max(MOK, p_MOK)*WP_MOK*(var_MOK - 1) - call MPI_FILE_SET_VIEW(ifile, disp, mpi_p, MPI_IO_DATA%view(i), 'native', mpi_info_int, ierr) - call MPI_FILE_WRITE_ALL(ifile, MPI_IO_DATA%var(i)%sf, data_size*mpi_io_type, mpi_io_p, status, ierr) + call MPI_FILE_SET_VIEW(ifile, disp, mpi_p, MPI_IO_DATA%view(i), & + 'native', mpi_info_int, ierr) + call MPI_FILE_WRITE_ALL(ifile, MPI_IO_DATA%var(i)%sf, data_size*mpi_io_type, & + mpi_io_p, status, ierr) end do end if + ! Correction for the lagrangian subgrid bubble model if (present(beta)) then var_MOK = int(sys_size + 1, MPI_OFFSET_KIND) + ! Initial displacement to skip at beginning of file disp = m_MOK*max(MOK, n_MOK)*max(MOK, p_MOK)*WP_MOK*(var_MOK - 1) - call MPI_FILE_SET_VIEW(ifile, disp, mpi_p, MPI_IO_DATA%view(sys_size + 1), 'native', mpi_info_int, ierr) - call MPI_FILE_WRITE_ALL(ifile, MPI_IO_DATA%var(sys_size + 1)%sf, data_size*mpi_io_type, mpi_io_p, status, ierr) + call MPI_FILE_SET_VIEW(ifile, disp, mpi_p, MPI_IO_DATA%view(sys_size + 1), & + 'native', mpi_info_int, ierr) + call MPI_FILE_WRITE_ALL(ifile, MPI_IO_DATA%var(sys_size + 1)%sf, data_size*mpi_io_type, & + mpi_io_p, status, ierr) end if call MPI_FILE_CLOSE(ifile, ierr) + !Write ib data if (ib) then call s_write_parallel_ib_data(t_step) + ! write (file_loc, '(A)') 'ib.dat' + ! file_loc = trim(case_dir)//'/restart_data'//trim(mpiiofs)//trim(file_loc) + ! call MPI_FILE_OPEN(MPI_COMM_WORLD, file_loc, ior(MPI_MODE_WRONLY, MPI_MODE_CREATE), & + ! mpi_info_int, ifile, ierr) + + ! var_MOK = int(sys_size + 1, MPI_OFFSET_KIND) + ! disp = m_MOK*max(MOK, n_MOK)*max(MOK, p_MOK)*WP_MOK*(var_MOK - 1 + int(t_step/t_step_save)) + + ! call MPI_FILE_SET_VIEW(ifile, disp, MPI_INTEGER, MPI_IO_IB_DATA%view, & + ! 'native', mpi_info_int, ierr) + ! call MPI_FILE_WRITE_ALL(ifile, MPI_IO_IB_DATA%var%sf, data_size, & + ! MPI_INTEGER, status, ierr) + ! call MPI_FILE_CLOSE(ifile, ierr) end if + end if #endif end subroutine s_write_parallel_data_files - !> Write immersed boundary marker data to a serial (per-processor) unformatted file + !> @brief Writes immersed boundary marker data to a serial (per-processor) unformatted file. subroutine s_write_serial_ib_data(time_step) - integer, intent(in) :: time_step + integer, intent(in) :: time_step character(LEN=path_len + 2*name_len) :: file_path character(LEN=path_len + 2*name_len) :: t_step_dir - write (t_step_dir, '(A,I0,A,I0)') trim(case_dir) // '/p_all' - write (t_step_dir, '(a,i0,a,i0)') trim(case_dir) // '/p_all/p', proc_rank, '/', time_step - write (file_path, '(A,I0,A)') trim(t_step_dir) // '/ib_data.dat' + ! Creating or overwriting the time-step root directory + write (t_step_dir, '(A,I0,A,I0)') trim(case_dir)//'/p_all' + write (t_step_dir, '(a,i0,a,i0)') trim(case_dir)//'/p_all/p', & + proc_rank, '/', time_step + write (file_path, '(A,I0,A)') trim(t_step_dir)//'/ib_data.dat' - open (2, FILE=trim(file_path), form='unformatted', STATUS='new') + open (2, FILE=trim(file_path), & + FORM='unformatted', & + STATUS='new') $:GPU_UPDATE(host='[ib_markers%sf]') - write (2) ib_markers%sf(0:m,0:n,0:p); close (2) + write (2) ib_markers%sf(0:m, 0:n, 0:p); close (2) - end subroutine s_write_serial_ib_data + end subroutine - !> Write immersed boundary marker data in parallel using MPI I/O + !> @brief Writes immersed boundary marker data in parallel using MPI I/O. subroutine s_write_parallel_ib_data(time_step) integer, intent(in) :: time_step #ifdef MFC_MPI + character(LEN=path_len + 2*name_len) :: file_loc - integer(kind=MPI_OFFSET_kind) :: disp - integer(kind=MPI_OFFSET_kind) :: m_MOK, n_MOK, p_MOK - integer(kind=MPI_OFFSET_kind) :: WP_MOK, var_MOK, MOK - integer :: ifile, ierr, data_size - integer, dimension(MPI_STATUS_SIZE) :: status + integer(kind=MPI_OFFSET_kind) :: disp + integer(kind=MPI_OFFSET_kind) :: m_MOK, n_MOK, p_MOK + integer(kind=MPI_OFFSET_kind) :: WP_MOK, var_MOK, MOK + integer :: ifile, ierr, data_size + integer, dimension(MPI_STATUS_SIZE) :: status $:GPU_UPDATE(host='[ib_markers%sf]') + ! Size of local arrays data_size = (m + 1)*(n + 1)*(p + 1) m_MOK = int(m_glb + 1, MPI_OFFSET_KIND) n_MOK = int(n_glb + 1, MPI_OFFSET_KIND) @@ -885,21 +1116,25 @@ contains MOK = int(1._wp, MPI_OFFSET_KIND) write (file_loc, '(A)') 'ib.dat' - file_loc = trim(case_dir) // '/restart_data' // trim(mpiiofs) // trim(file_loc) - call MPI_FILE_OPEN(MPI_COMM_WORLD, file_loc, ior(MPI_MODE_WRONLY, MPI_MODE_CREATE), mpi_info_int, ifile, ierr) + file_loc = trim(case_dir)//'/restart_data'//trim(mpiiofs)//trim(file_loc) + call MPI_FILE_OPEN(MPI_COMM_WORLD, file_loc, ior(MPI_MODE_WRONLY, MPI_MODE_CREATE), & + mpi_info_int, ifile, ierr) var_MOK = int(sys_size + 1, MPI_OFFSET_KIND) disp = m_MOK*max(MOK, n_MOK)*max(MOK, p_MOK)*WP_MOK*(var_MOK - 1 + int(time_step/t_step_save)) if (time_step == 0) disp = 0 - call MPI_FILE_SET_VIEW(ifile, disp, MPI_INTEGER, MPI_IO_IB_DATA%view, 'native', mpi_info_int, ierr) - call MPI_FILE_WRITE_ALL(ifile, MPI_IO_IB_DATA%var%sf, data_size, MPI_INTEGER, status, ierr) + call MPI_FILE_SET_VIEW(ifile, disp, MPI_INTEGER, MPI_IO_IB_DATA%view, & + 'native', mpi_info_int, ierr) + call MPI_FILE_WRITE_ALL(ifile, MPI_IO_IB_DATA%var%sf, data_size, & + MPI_INTEGER, status, ierr) call MPI_FILE_CLOSE(ifile, ierr) + #endif end subroutine s_write_parallel_ib_data - !> Dispatch immersed boundary data output to the serial or parallel writer + !> @brief Dispatches immersed boundary data output to the serial or parallel writer. subroutine s_write_ib_data_file(time_step) integer, intent(in) :: time_step @@ -912,26 +1147,37 @@ contains end subroutine s_write_ib_data_file - !> Write IB state records to D/ib_state.dat (rank 0 only) + !> @brief Writes IB state records to D/ib_state.dat. Must be called only on rank 0. impure subroutine s_write_ib_state_file() integer :: i do i = 1, num_ibs - write (ib_state_unit) mytime, i, patch_ib(i)%force, patch_ib(i)%torque, patch_ib(i)%vel, patch_ib(i)%angular_vel, & - & patch_ib(i)%angles, patch_ib(i)%x_centroid, patch_ib(i)%y_centroid, patch_ib(i)%z_centroid + write (ib_state_unit) mytime, i, & + patch_ib(i)%force, & + patch_ib(i)%torque, & + patch_ib(i)%vel, & + patch_ib(i)%angular_vel, & + patch_ib(i)%angles, & + patch_ib(i)%x_centroid, & + patch_ib(i)%y_centroid, & + patch_ib(i)%z_centroid end do end subroutine s_write_ib_state_file - !> Write center-of-mass data at the current time step + !> This writes a formatted data file where the root processor + !! can write out the CoM information + !! @param t_step Current time-step + !! @param c_mass_in Center of mass information impure subroutine s_write_com_files(t_step, c_mass_in) - integer, intent(in) :: t_step + integer, intent(in) :: t_step real(wp), dimension(num_fluids, 5), intent(in) :: c_mass_in - integer :: i !< Generic loop iterator - real(wp) :: nondim_time !< Non-dimensional time + integer :: i !< Generic loop iterator + real(wp) :: nondim_time !< Non-dimensional time + ! Non-dimensional time calculation if (t_step_old /= dflt_int) then nondim_time = real(t_step + t_step_old, wp)*dt else @@ -939,71 +1185,97 @@ contains end if if (proc_rank == 0) then - if (n == 0) then - do i = 1, num_fluids - write (i + 120, '(6X,4F24.12)') nondim_time, c_mass_in(i, 1), c_mass_in(i, 2), c_mass_in(i, 5) + if (n == 0) then ! 1D simulation + do i = 1, num_fluids ! Loop through fluids + write (i + 120, '(6X,4F24.12)') & + nondim_time, & + c_mass_in(i, 1), & + c_mass_in(i, 2), & + c_mass_in(i, 5) end do - else if (p == 0) then - do i = 1, num_fluids - write (i + 120, '(6X,5F24.12)') nondim_time, c_mass_in(i, 1), c_mass_in(i, 2), c_mass_in(i, 3), c_mass_in(i, 5) + elseif (p == 0) then ! 2D simulation + do i = 1, num_fluids ! Loop through fluids + write (i + 120, '(6X,5F24.12)') & + nondim_time, & + c_mass_in(i, 1), & + c_mass_in(i, 2), & + c_mass_in(i, 3), & + c_mass_in(i, 5) end do - else - do i = 1, num_fluids - write (i + 120, '(6X,6F24.12)') nondim_time, c_mass_in(i, 1), c_mass_in(i, 2), c_mass_in(i, 3), c_mass_in(i, & - & 4), c_mass_in(i, 5) + else ! 3D simulation + do i = 1, num_fluids ! Loop through fluids + write (i + 120, '(6X,6F24.12)') & + nondim_time, & + c_mass_in(i, 1), & + c_mass_in(i, 2), & + c_mass_in(i, 3), & + c_mass_in(i, 4), & + c_mass_in(i, 5) end do end if end if end subroutine s_write_com_files - !> Write flow probe data at the current time step + !> This writes a formatted data file for the flow probe information + !! @param t_step Current time-step + !! @param q_cons_vf Conservative variables + !! @param accel_mag Acceleration magnitude information impure subroutine s_write_probe_files(t_step, q_cons_vf, accel_mag) - integer, intent(in) :: t_step + integer, intent(in) :: t_step type(scalar_field), dimension(sys_size), intent(in) :: q_cons_vf - real(wp), dimension(0:m,0:n,0:p), intent(in) :: accel_mag - real(wp), dimension(-1:m) :: distx - real(wp), dimension(-1:n) :: disty - real(wp), dimension(-1:p) :: distz - - ! The cell-averaged partial densities, density, velocity, pressure, volume fractions, specific heat ratio function, liquid - ! stiffness function, and sound speed. - real(wp) :: lit_gamma, nbub - real(wp) :: rho - real(wp), dimension(num_vels) :: vel - real(wp) :: pres - real(wp) :: ptilde - real(wp) :: ptot - real(wp) :: alf - real(wp) :: alfgr + real(wp), dimension(0:m, 0:n, 0:p), intent(in) :: accel_mag + + real(wp), dimension(-1:m) :: distx + real(wp), dimension(-1:n) :: disty + real(wp), dimension(-1:p) :: distz + + ! The cell-averaged partial densities, density, velocity, pressure, + ! volume fractions, specific heat ratio function, liquid stiffness + ! function, and sound speed. + real(wp) :: lit_gamma, nbub + real(wp) :: rho + real(wp), dimension(num_vels) :: vel + real(wp) :: pres + real(wp) :: ptilde + real(wp) :: ptot + real(wp) :: alf + real(wp) :: alfgr real(wp), dimension(num_fluids) :: alpha - real(wp) :: gamma - real(wp) :: pi_inf - real(wp) :: qv - real(wp) :: c - real(wp) :: M00, M10, M01, M20, M11, M02 - real(wp) :: varR, varV - real(wp), dimension(Nb) :: nR, R, nRdot, Rdot - real(wp) :: nR3 - real(wp) :: accel - real(wp) :: int_pres - real(wp) :: max_pres - real(wp), dimension(2) :: Re - real(wp), dimension(6) :: tau_e - real(wp) :: G_local - real(wp) :: dyn_p, T - real(wp) :: damage_state - integer :: i, j, k, l, s, d !< Generic loop iterator - real(wp) :: nondim_time !< Non-dimensional time - real(wp) :: tmp !< Temporary variable to store quantity for mpi_allreduce - integer :: npts !< Number of included integral points - real(wp) :: rad, thickness !< For integral quantities - logical :: trigger !< For integral quantities - real(wp) :: rhoYks(1:num_species) + real(wp) :: gamma + real(wp) :: pi_inf + real(wp) :: qv + real(wp) :: c + real(wp) :: M00, M10, M01, M20, M11, M02 + real(wp) :: varR, varV + real(wp), dimension(Nb) :: nR, R, nRdot, Rdot + real(wp) :: nR3 + real(wp) :: accel + real(wp) :: int_pres + real(wp) :: max_pres + real(wp), dimension(2) :: Re + real(wp), dimension(6) :: tau_e + real(wp) :: G_local + real(wp) :: dyn_p, T + real(wp) :: damage_state + + integer :: i, j, k, l, s, d !< Generic loop iterator + + real(wp) :: nondim_time !< Non-dimensional time + + real(wp) :: tmp !< + !! Temporary variable to store quantity for mpi_allreduce + + integer :: npts !< Number of included integral points + real(wp) :: rad, thickness !< For integral quantities + logical :: trigger !< For integral quantities + + real(wp) :: rhoYks(1:num_species) T = dflt_T_guess + ! Non-dimensional time calculation if (time_stepper == 23) then nondim_time = mytime else @@ -1015,6 +1287,7 @@ contains end if do i = 1, num_probes + ! Zeroing out flow variables for all processors rho = 0._wp do s = 1, num_vels vel(s) = 0._wp @@ -1041,14 +1314,16 @@ contains end do damage_state = 0._wp - if (n == 0) then + ! Find probe location in terms of indices on a + ! specific processor + if (n == 0) then ! 1D simulation if ((probe(i)%x >= x_cb(-1)) .and. (probe(i)%x <= x_cb(m))) then do s = -1, m distx(s) = x_cb(s) - probe(i)%x if (distx(s) < 0._wp) distx(s) = 1000._wp end do j = minloc(distx, 1) - if (j == 1) j = 2 ! Pick first point if probe is at edge + if (j == 1) j = 2 ! Pick first point if probe is at edge k = 0 l = 0 @@ -1060,10 +1335,12 @@ contains ! Computing/Sharing necessary state variables if (elasticity) then - call s_convert_to_mixture_variables(q_cons_vf, j - 2, k, l, rho, gamma, pi_inf, qv, Re, G_local, & - & fluid_pp(:)%G) + call s_convert_to_mixture_variables(q_cons_vf, j - 2, k, l, & + rho, gamma, pi_inf, qv, & + Re, G_local, fluid_pp(:)%G) else - call s_convert_to_mixture_variables(q_cons_vf, j - 2, k, l, rho, gamma, pi_inf, qv) + call s_convert_to_mixture_variables(q_cons_vf, j - 2, k, l, & + rho, gamma, pi_inf, qv) end if do s = 1, num_vels vel(s) = q_cons_vf(cont_idx%end + s)%sf(j - 2, k, l)/rho @@ -1077,12 +1354,17 @@ contains G_local = G_local*max((1._wp - damage_state), 0._wp) end if - call s_compute_pressure(q_cons_vf(1)%sf(j - 2, k, l), q_cons_vf(alf_idx)%sf(j - 2, k, l), dyn_p, pi_inf, & - & gamma, rho, qv, rhoYks(:), pres, T, q_cons_vf(stress_idx%beg)%sf(j - 2, k, l), & - & q_cons_vf(mom_idx%beg)%sf(j - 2, k, l), G_local) + call s_compute_pressure( & + q_cons_vf(1)%sf(j - 2, k, l), & + q_cons_vf(alf_idx)%sf(j - 2, k, l), & + dyn_p, pi_inf, gamma, rho, qv, rhoYks(:), pres, T, & + q_cons_vf(stress_idx%beg)%sf(j - 2, k, l), & + q_cons_vf(mom_idx%beg)%sf(j - 2, k, l), G_local) else - call s_compute_pressure(q_cons_vf(E_idx)%sf(j - 2, k, l), q_cons_vf(alf_idx)%sf(j - 2, k, l), dyn_p, & - & pi_inf, gamma, rho, qv, rhoYks, pres, T) + call s_compute_pressure( & + q_cons_vf(E_idx)%sf(j - 2, k, l), & + q_cons_vf(alf_idx)%sf(j - 2, k, l), & + dyn_p, pi_inf, gamma, rho, qv, rhoYks, pres, T) end if if (model_eqns == 4) then @@ -1139,12 +1421,12 @@ contains end if ! Compute mixture sound Speed - call s_compute_speed_of_sound(pres, rho, gamma, pi_inf, ((gamma + 1._wp)*pres + pi_inf)/rho, alpha, 0._wp, & - & 0._wp, c, qv) + call s_compute_speed_of_sound(pres, rho, gamma, pi_inf, & + ((gamma + 1._wp)*pres + pi_inf)/rho, alpha, 0._wp, 0._wp, c, qv) accel = accel_mag(j - 2, k, l) end if - else if (p == 0) then + elseif (p == 0) then ! 2D simulation if (chemistry) then do d = 1, num_species rhoYks(d) = q_cons_vf(chemxb + d - 1)%sf(j - 2, k - 2, l) @@ -1163,13 +1445,14 @@ contains end do j = minloc(distx, 1) k = minloc(disty, 1) - if (j == 1) j = 2 ! Pick first point if probe is at edge - if (k == 1) k = 2 ! Pick first point if probe is at edge + if (j == 1) j = 2 ! Pick first point if probe is at edge + if (k == 1) k = 2 ! Pick first point if probe is at edge l = 0 ! Computing/Sharing necessary state variables - call s_convert_to_mixture_variables(q_cons_vf, j - 2, k - 2, l, rho, gamma, pi_inf, qv, Re, G_local, & - & fluid_pp(:)%G) + call s_convert_to_mixture_variables(q_cons_vf, j - 2, k - 2, l, & + rho, gamma, pi_inf, qv, & + Re, G_local, fluid_pp(:)%G) do s = 1, num_vels vel(s) = q_cons_vf(cont_idx%end + s)%sf(j - 2, k - 2, l)/rho end do @@ -1182,13 +1465,20 @@ contains G_local = G_local*max((1._wp - damage_state), 0._wp) end if - call s_compute_pressure(q_cons_vf(1)%sf(j - 2, k - 2, l), q_cons_vf(alf_idx)%sf(j - 2, k - 2, l), & - & dyn_p, pi_inf, gamma, rho, qv, rhoYks, pres, T, & - & q_cons_vf(stress_idx%beg)%sf(j - 2, k - 2, l), & - & q_cons_vf(mom_idx%beg)%sf(j - 2, k - 2, l), G_local) + call s_compute_pressure( & + q_cons_vf(1)%sf(j - 2, k - 2, l), & + q_cons_vf(alf_idx)%sf(j - 2, k - 2, l), & + dyn_p, pi_inf, gamma, rho, qv, & + rhoYks, & + pres, & + T, & + q_cons_vf(stress_idx%beg)%sf(j - 2, k - 2, l), & + q_cons_vf(mom_idx%beg)%sf(j - 2, k - 2, l), G_local) else - call s_compute_pressure(q_cons_vf(E_idx)%sf(j - 2, k - 2, l), q_cons_vf(alf_idx)%sf(j - 2, k - 2, l), & - & dyn_p, pi_inf, gamma, rho, qv, rhoYks, pres, T) + call s_compute_pressure(q_cons_vf(E_idx)%sf(j - 2, k - 2, l), & + q_cons_vf(alf_idx)%sf(j - 2, k - 2, l), & + dyn_p, pi_inf, gamma, rho, qv, & + rhoYks, pres, T) end if if (model_eqns == 4) then @@ -1221,11 +1511,12 @@ contains Rdot(:) = nRdot(:)/nbub end if ! Compute mixture sound speed - call s_compute_speed_of_sound(pres, rho, gamma, pi_inf, ((gamma + 1._wp)*pres + pi_inf)/rho, alpha, & - & 0._wp, 0._wp, c, qv) + call s_compute_speed_of_sound(pres, rho, gamma, pi_inf, & + ((gamma + 1._wp)*pres + pi_inf)/rho, alpha, 0._wp, 0._wp, c, qv) + end if end if - else + else ! 3D if ((probe(i)%x >= x_cb(-1)) .and. (probe(i)%x <= x_cb(m))) then if ((probe(i)%y >= y_cb(-1)) .and. (probe(i)%y <= y_cb(n))) then if ((probe(i)%z >= z_cb(-1)) .and. (probe(i)%z <= z_cb(p))) then @@ -1244,13 +1535,14 @@ contains j = minloc(distx, 1) k = minloc(disty, 1) l = minloc(distz, 1) - if (j == 1) j = 2 ! Pick first point if probe is at edge - if (k == 1) k = 2 ! Pick first point if probe is at edge - if (l == 1) l = 2 ! Pick first point if probe is at edge + if (j == 1) j = 2 ! Pick first point if probe is at edge + if (k == 1) k = 2 ! Pick first point if probe is at edge + if (l == 1) l = 2 ! Pick first point if probe is at edge ! Computing/Sharing necessary state variables - call s_convert_to_mixture_variables(q_cons_vf, j - 2, k - 2, l - 2, rho, gamma, pi_inf, qv, Re, & - & G_local, fluid_pp(:)%G) + call s_convert_to_mixture_variables(q_cons_vf, j - 2, k - 2, l - 2, & + rho, gamma, pi_inf, qv, & + Re, G_local, fluid_pp(:)%G) do s = 1, num_vels vel(s) = q_cons_vf(cont_idx%end + s)%sf(j - 2, k - 2, l - 2)/rho end do @@ -1269,18 +1561,23 @@ contains G_local = G_local*max((1._wp - damage_state), 0._wp) end if - call s_compute_pressure(q_cons_vf(1)%sf(j - 2, k - 2, l - 2), q_cons_vf(alf_idx)%sf(j - 2, k - 2, & - & l - 2), dyn_p, pi_inf, gamma, rho, qv, rhoYks, pres, T, & - & q_cons_vf(stress_idx%beg)%sf(j - 2, k - 2, l - 2), & - & q_cons_vf(mom_idx%beg)%sf(j - 2, k - 2, l - 2), G_local) + call s_compute_pressure( & + q_cons_vf(1)%sf(j - 2, k - 2, l - 2), & + q_cons_vf(alf_idx)%sf(j - 2, k - 2, l - 2), & + dyn_p, pi_inf, gamma, rho, qv, & + rhoYks, pres, T, & + q_cons_vf(stress_idx%beg)%sf(j - 2, k - 2, l - 2), & + q_cons_vf(mom_idx%beg)%sf(j - 2, k - 2, l - 2), G_local) else - call s_compute_pressure(q_cons_vf(E_idx)%sf(j - 2, k - 2, l - 2), q_cons_vf(alf_idx)%sf(j - 2, & - & k - 2, l - 2), dyn_p, pi_inf, gamma, rho, qv, rhoYks, pres, T) + call s_compute_pressure(q_cons_vf(E_idx)%sf(j - 2, k - 2, l - 2), & + q_cons_vf(alf_idx)%sf(j - 2, k - 2, l - 2), & + dyn_p, pi_inf, gamma, rho, qv, & + rhoYks, pres, T) end if ! Compute mixture sound speed - call s_compute_speed_of_sound(pres, rho, gamma, pi_inf, ((gamma + 1._wp)*pres + pi_inf)/rho, alpha, & - & 0._wp, 0._wp, c, qv) + call s_compute_speed_of_sound(pres, rho, gamma, pi_inf, & + ((gamma + 1._wp)*pres + pi_inf)/rho, alpha, 0._wp, 0._wp, c, qv) accel = accel_mag(j - 2, k - 2, l - 2) end if @@ -1328,53 +1625,134 @@ contains if (n == 0) then if (bubbles_euler .and. (num_fluids <= 2)) then if (qbmm) then - write (i + 30, '(6x,f12.6,14f28.16)') nondim_time, rho, vel(1), pres, alf, R(1), Rdot(1), nR(1), & - & nRdot(1), varR, varV, M10, M01, M20, M02 + write (i + 30, '(6x,f12.6,14f28.16)') & + nondim_time, & + rho, & + vel(1), & + pres, & + alf, & + R(1), & + Rdot(1), & + nR(1), & + nRdot(1), & + varR, & + varV, & + M10, & + M01, & + M20, & + M02 else - write (i + 30, '(6x,f12.6,8f24.8)') nondim_time, rho, vel(1), pres, alf, R(1), Rdot(1), nR(1), nRdot(1) - ! ptilde, & ptot + write (i + 30, '(6x,f12.6,8f24.8)') & + nondim_time, & + rho, & + vel(1), & + pres, & + alf, & + R(1), & + Rdot(1), & + nR(1), & + nRdot(1) + ! ptilde, & + ! ptot end if else if (bubbles_euler .and. (num_fluids == 3)) then - write (i + 30, & - & '(6x,f12.6,f24.8,f24.8,f24.8,f24.8,f24.8,' // 'f24.8,f24.8,f24.8,f24.8,f24.8, f24.8)') & - & nondim_time, rho, vel(1), pres, alf, alfgr, nR(1), nRdot(1), R(1), Rdot(1), ptilde, ptot + write (i + 30, '(6x,f12.6,f24.8,f24.8,f24.8,f24.8,f24.8,'// & + 'f24.8,f24.8,f24.8,f24.8,f24.8, f24.8)') & + nondim_time, & + rho, & + vel(1), & + pres, & + alf, & + alfgr, & + nR(1), & + nRdot(1), & + R(1), & + Rdot(1), & + ptilde, & + ptot else if (bubbles_euler .and. num_fluids == 4) then - write (i + 30, & - & '(6x,f12.6,f24.8,f24.8,f24.8,f24.8,' // 'f24.8,f24.8,f24.8,f24.8,f24.8,f24.8,f24.8,f24.8,f24.8)') & - & nondim_time, q_cons_vf(1)%sf(j - 2, 0, 0), q_cons_vf(2)%sf(j - 2, 0, 0), q_cons_vf(3)%sf(j - 2, & - & 0, 0), q_cons_vf(4)%sf(j - 2, 0, 0), q_cons_vf(5)%sf(j - 2, 0, 0), q_cons_vf(6)%sf(j - 2, 0, 0), & - & q_cons_vf(7)%sf(j - 2, 0, 0), q_cons_vf(8)%sf(j - 2, 0, 0), q_cons_vf(9)%sf(j - 2, 0, 0), & - & q_cons_vf(10)%sf(j - 2, 0, 0), nbub, R(1), Rdot(1) + write (i + 30, '(6x,f12.6,f24.8,f24.8,f24.8,f24.8,'// & + 'f24.8,f24.8,f24.8,f24.8,f24.8,f24.8,f24.8,f24.8,f24.8)') & + nondim_time, & + q_cons_vf(1)%sf(j - 2, 0, 0), & + q_cons_vf(2)%sf(j - 2, 0, 0), & + q_cons_vf(3)%sf(j - 2, 0, 0), & + q_cons_vf(4)%sf(j - 2, 0, 0), & + q_cons_vf(5)%sf(j - 2, 0, 0), & + q_cons_vf(6)%sf(j - 2, 0, 0), & + q_cons_vf(7)%sf(j - 2, 0, 0), & + q_cons_vf(8)%sf(j - 2, 0, 0), & + q_cons_vf(9)%sf(j - 2, 0, 0), & + q_cons_vf(10)%sf(j - 2, 0, 0), & + nbub, & + R(1), & + Rdot(1) else - write (i + 30, '(6X,F12.6,F24.8,F24.8,F24.8)') nondim_time, rho, vel(1), pres + write (i + 30, '(6X,F12.6,F24.8,F24.8,F24.8)') & + nondim_time, & + rho, & + vel(1), & + pres end if - else if (p == 0) then + elseif (p == 0) then if (bubbles_euler) then #:if not MFC_CASE_OPTIMIZATION or num_dims > 1 - write (i + 30, '(6X,10F24.8)') nondim_time, rho, vel(1), vel(2), pres, alf, nR(1), nRdot(1), R(1), & - & Rdot(1) + write (i + 30, '(6X,10F24.8)') & + nondim_time, & + rho, & + vel(1), & + vel(2), & + pres, & + alf, & + nR(1), & + nRdot(1), & + R(1), & + Rdot(1) #:endif else if (elasticity) then #:if not MFC_CASE_OPTIMIZATION or num_dims > 1 - write (i + 30, '(6X,F12.6,F24.8,F24.8,F24.8,F24.8,' // 'F24.8,F24.8,F24.8)') nondim_time, rho, & - & vel(1), vel(2), pres, tau_e(1), tau_e(2), tau_e(3) + write (i + 30, '(6X,F12.6,F24.8,F24.8,F24.8,F24.8,'// & + 'F24.8,F24.8,F24.8)') & + nondim_time, & + rho, & + vel(1), & + vel(2), & + pres, & + tau_e(1), & + tau_e(2), & + tau_e(3) #:endif else - write (i + 30, '(6X,F12.6,F24.8,F24.8,F24.8)') nondim_time, rho, vel(1), pres + write (i + 30, '(6X,F12.6,F24.8,F24.8,F24.8)') & + nondim_time, & + rho, & + vel(1), & + pres print *, 'time =', nondim_time, 'rho =', rho, 'pres =', pres end if else #:if not MFC_CASE_OPTIMIZATION or num_dims > 2 - write (i + 30, & - & '(6X,F12.6,F24.8,F24.8,F24.8,F24.8,' // 'F24.8,F24.8,F24.8,F24.8,F24.8,' // 'F24.8)') & - & nondim_time, rho, vel(1), vel(2), vel(3), pres, gamma, pi_inf, qv, c, accel + write (i + 30, '(6X,F12.6,F24.8,F24.8,F24.8,F24.8,'// & + 'F24.8,F24.8,F24.8,F24.8,F24.8,'// & + 'F24.8)') & + nondim_time, & + rho, & + vel(1), & + vel(2), & + vel(3), & + pres, & + gamma, & + pi_inf, & + qv, & + c, & + accel #:endif end if end if end do if (integral_wrt .and. bubbles_euler) then - if (n == 0) then + if (n == 0) then ! 1D simulation do i = 1, num_integrals int_pres = 0._wp max_pres = 0._wp @@ -1393,13 +1771,18 @@ contains if ((integral(i)%xmin <= x_cb(j)) .and. (integral(i)%xmax >= x_cb(j))) then npts = npts + 1 - call s_convert_to_mixture_variables(q_cons_vf, j, k, l, rho, gamma, pi_inf, qv, Re) + call s_convert_to_mixture_variables(q_cons_vf, j, k, l, & + rho, gamma, pi_inf, qv, Re) do s = 1, num_vels vel(s) = q_cons_vf(cont_idx%end + s)%sf(j, k, l)/rho end do - pres = ((q_cons_vf(E_idx)%sf(j, k, l) - 0.5_wp*(q_cons_vf(mom_idx%beg)%sf(j, k, & - & l)**2._wp)/rho)/(1._wp - q_cons_vf(alf_idx)%sf(j, k, l)) - pi_inf - qv)/gamma + pres = ( & + (q_cons_vf(E_idx)%sf(j, k, l) - & + 0.5_wp*(q_cons_vf(mom_idx%beg)%sf(j, k, l)**2._wp)/rho)/ & + (1._wp - q_cons_vf(alf_idx)%sf(j, k, l)) - & + pi_inf - qv & + )/gamma int_pres = int_pres + (pres - 1._wp)**2._wp end if end do @@ -1412,11 +1795,12 @@ contains if (proc_rank == 0) then if (bubbles_euler .and. (num_fluids <= 2)) then - write (i + 70, '(6x,f12.6,f24.8)') nondim_time, int_pres + write (i + 70, '(6x,f12.6,f24.8)') & + nondim_time, int_pres end if end if end do - else if (p == 0) then + elseif (p == 0) then if (num_integrals /= 3) then call s_mpi_abort('Incorrect number of integrals') end if @@ -1433,15 +1817,18 @@ contains do k = 1, n trigger = .false. if (i == 1) then - ! inner portion - if (sqrt(x_cb(j)**2._wp + y_cb(k)**2._wp) < (rad - 0.5_wp*thickness)) trigger = .true. - else if (i == 2) then - ! net region - if (sqrt(x_cb(j)**2._wp + y_cb(k)**2._wp) > (rad - 0.5_wp*thickness) .and. sqrt(x_cb(j)**2._wp & - & + y_cb(k)**2._wp) < (rad + 0.5_wp*thickness)) trigger = .true. - else if (i == 3) then - ! everything else - if (sqrt(x_cb(j)**2._wp + y_cb(k)**2._wp) > (rad + 0.5_wp*thickness)) trigger = .true. + !inner portion + if (sqrt(x_cb(j)**2._wp + y_cb(k)**2._wp) < (rad - 0.5_wp*thickness)) & + trigger = .true. + elseif (i == 2) then + !net region + if (sqrt(x_cb(j)**2._wp + y_cb(k)**2._wp) > (rad - 0.5_wp*thickness) .and. & + sqrt(x_cb(j)**2._wp + y_cb(k)**2._wp) < (rad + 0.5_wp*thickness)) & + trigger = .true. + elseif (i == 3) then + !everything else + if (sqrt(x_cb(j)**2._wp + y_cb(k)**2._wp) > (rad + 0.5_wp*thickness)) & + trigger = .true. end if pres = 0._wp @@ -1456,16 +1843,22 @@ contains if (trigger) then npts = npts + 1 - call s_convert_to_mixture_variables(q_cons_vf, j, k, l, rho, gamma, pi_inf, qv, Re) + call s_convert_to_mixture_variables(q_cons_vf, j, k, l, & + rho, gamma, pi_inf, qv, Re) do s = 1, num_vels vel(s) = q_cons_vf(cont_idx%end + s)%sf(j, k, l)/rho end do - pres = ((q_cons_vf(E_idx)%sf(j, k, l) - 0.5_wp*(q_cons_vf(mom_idx%beg)%sf(j, k, & - & l)**2._wp)/rho)/(1._wp - q_cons_vf(alf_idx)%sf(j, k, l)) - pi_inf - qv)/gamma + pres = ( & + (q_cons_vf(E_idx)%sf(j, k, l) - & + 0.5_wp*(q_cons_vf(mom_idx%beg)%sf(j, k, l)**2._wp)/rho)/ & + (1._wp - q_cons_vf(alf_idx)%sf(j, k, l)) - & + pi_inf - qv & + )/gamma int_pres = int_pres + abs(pres - 1._wp) max_pres = max(max_pres, abs(pres - 1._wp)) end if + end do end do @@ -1485,7 +1878,8 @@ contains if (proc_rank == 0) then if (bubbles_euler .and. (num_fluids <= 2)) then - write (i + 70, '(6x,f12.6,f24.8,f24.8)') nondim_time, int_pres, max_pres + write (i + 70, '(6x,f12.6,f24.8,f24.8)') & + nondim_time, int_pres, max_pres end if end if end do @@ -1494,17 +1888,22 @@ contains end subroutine s_write_probe_files - !> Write footer with stability criteria extrema and run-time to the information file, then close it + !> The goal of this subroutine is to write to the run-time + !! information file basic footer information applicable to + !! the current computation and to close the file when done. + !! The footer contains the stability criteria extrema over + !! all of the time-steps and the simulation run-time. impure subroutine s_close_run_time_information_file - real(wp) :: run_time !< Run-time of the simulation + real(wp) :: run_time !< Run-time of the simulation + ! Writing the footer of and closing the run-time information file write (3, '(A)') ' ' write (3, '(A)') '' write (3, '(A,F9.6)') 'ICFL Max: ', icfl_max if (viscous) write (3, '(A,F9.6)') 'VCFL Max: ', vcfl_max - if (viscous) write (3, '(A,F10.6)') 'Rc Min: ', Rc_min + if (viscous) write (3, '(A,ES16.6)') 'Rc Min: ', Rc_min call cpu_time(run_time) @@ -1518,8 +1917,7 @@ contains !> Closes communication files impure subroutine s_close_com_files() - integer :: i !< Generic loop iterator - + integer :: i !< Generic loop iterator do i = 1, num_fluids close (i + 120) end do @@ -1529,7 +1927,7 @@ contains !> Closes probe files impure subroutine s_close_probe_files - integer :: i !< Generic loop iterator + integer :: i !< Generic loop iterator do i = 1, num_probes close (i + 30) @@ -1537,28 +1935,25 @@ contains end subroutine s_close_probe_files - !> Close the immersed boundary state file impure subroutine s_close_ib_state_file close (ib_state_unit) end subroutine s_close_ib_state_file - !> Initialize the data output module + !> The computation of parameters, the allocation of memory, + !! the association of pointers and/or the execution of any + !! other procedures that are necessary to setup the module. impure subroutine s_initialize_data_output_module integer :: i, m_ds, n_ds, p_ds + ! Allocating/initializing ICFL, VCFL, CCFL and Rc stability criteria if (run_time_info) then - @:ALLOCATE(icfl_sf(0:m, 0:n, 0:p)) icfl_max = 0._wp - if (viscous) then - @:ALLOCATE(vcfl_sf(0:m, 0:n, 0:p)) - @:ALLOCATE(Rc_sf (0:m, 0:n, 0:p)) - vcfl_max = 0._wp - Rc_min = 1.e3_wp + Rc_min = 1.e12_wp end if end if @@ -1573,7 +1968,7 @@ contains allocate (q_cons_temp_ds(1:sys_size)) do i = 1, sys_size - allocate (q_cons_temp_ds(i)%sf(-1:m_ds + 1,-1:n_ds + 1,-1:p_ds + 1)) + allocate (q_cons_temp_ds(i)%sf(-1:m_ds + 1, -1:n_ds + 1, -1:p_ds + 1)) end do end if @@ -1588,13 +1983,6 @@ contains @:DEALLOCATE(c_mass) end if - if (run_time_info) then - @:DEALLOCATE(icfl_sf) - if (viscous) then - @:DEALLOCATE(vcfl_sf, Rc_sf) - end if - end if - if (down_sample) then do i = 1, sys_size deallocate (q_cons_temp_ds(i)%sf) diff --git a/src/simulation/m_derived_variables.fpp b/src/simulation/m_derived_variables.fpp index d0be1a8426..53a8396cbf 100644 --- a/src/simulation/m_derived_variables.fpp +++ b/src/simulation/m_derived_variables.fpp @@ -2,52 +2,65 @@ !! @file !! @brief Contains module m_derived_variables -!> @brief Derives diagnostic flow quantities (vorticity, speed of sound, numerical Schlieren, etc.) from conservative and primitive -!! variables +!> @brief Derives diagnostic flow quantities (vorticity, speed of sound, numerical Schlieren, etc.) from conservative and primitive variables #:include 'macros.fpp' module m_derived_variables - use m_derived_types - use m_global_parameters - use m_mpi_proxy - use m_data_output + use m_derived_types !< Definitions of the derived types + + use m_global_parameters !< Global parameters for the code + + use m_mpi_proxy !< Message passing interface (MPI) module proxy + + use m_data_output !< Data output module + use m_compile_specific + use m_helper + use m_finite_differences implicit none - private; public :: s_initialize_derived_variables_module, s_initialize_derived_variables, s_compute_derived_variables, & - & s_finalize_derived_variables_module + private; public :: s_initialize_derived_variables_module, & + s_initialize_derived_variables, & + s_compute_derived_variables, & + s_finalize_derived_variables_module - !> @name Finite-difference coefficients Finite-difference (fd) coefficients in x-, y- and z-coordinate directions. Note that - !! because sufficient boundary information is available for all the active coordinate directions, the centered family of the - !! finite-difference schemes is used. + !> @name Finite-difference coefficients + !! Finite-difference (fd) coefficients in x-, y- and z-coordinate directions. + !! Note that because sufficient boundary information is available for all the + !! active coordinate directions, the centered family of the finite-difference + !! schemes is used. !> @{ - real(wp), public, allocatable, dimension(:,:) :: fd_coeff_x - real(wp), public, allocatable, dimension(:,:) :: fd_coeff_y - real(wp), public, allocatable, dimension(:,:) :: fd_coeff_z + real(wp), public, allocatable, dimension(:, :) :: fd_coeff_x + real(wp), public, allocatable, dimension(:, :) :: fd_coeff_y + real(wp), public, allocatable, dimension(:, :) :: fd_coeff_z !> @} - $:GPU_DECLARE(create='[fd_coeff_x, fd_coeff_y, fd_coeff_z]') + $:GPU_DECLARE(create='[fd_coeff_x,fd_coeff_y,fd_coeff_z]') ! @name Variables for computing acceleration !> @{ - real(wp), public, allocatable, dimension(:,:,:) :: accel_mag - real(wp), public, allocatable, dimension(:,:,:) :: x_accel, y_accel, z_accel + real(wp), public, allocatable, dimension(:, :, :) :: accel_mag + real(wp), public, allocatable, dimension(:, :, :) :: x_accel, y_accel, z_accel !> @} - $:GPU_DECLARE(create='[accel_mag, x_accel, y_accel, z_accel]') + $:GPU_DECLARE(create='[accel_mag,x_accel,y_accel,z_accel]') contains - !> Computation of parameters, allocation procedures, and/or any other tasks needed to properly setup the module + !> Computation of parameters, allocation procedures, and/or + !! any other tasks needed to properly setup the module impure subroutine s_initialize_derived_variables_module - ! Allocating the variables which will store the coefficients of the centered family of finite-difference schemes. Note that - ! sufficient space is allocated so that the coefficients up to any chosen order of accuracy may be bookkept. However, if - ! higher than fourth-order accuracy coefficients are wanted, the formulae required to compute these coefficients will have - ! to be implemented in the subroutine s_compute_finite_difference_coefficients. + ! Allocating the variables which will store the coefficients of the + ! centered family of finite-difference schemes. Note that sufficient + ! space is allocated so that the coefficients up to any chosen order + ! of accuracy may be bookkept. However, if higher than fourth-order + ! accuracy coefficients are wanted, the formulae required to compute + ! these coefficients will have to be implemented in the subroutine + ! s_compute_finite_difference_coefficients. ! Allocating centered finite-difference coefficients if (probe_wrt) then @@ -81,15 +94,18 @@ contains call s_open_com_files() end if ! Computing centered finite difference coefficients - call s_compute_finite_difference_coefficients(m, x_cc, fd_coeff_x, buff_size, fd_number, fd_order) + call s_compute_finite_difference_coefficients(m, x_cc, fd_coeff_x, buff_size, & + fd_number, fd_order) $:GPU_UPDATE(device='[fd_coeff_x]') if (n > 0) then - call s_compute_finite_difference_coefficients(n, y_cc, fd_coeff_y, buff_size, fd_number, fd_order) + call s_compute_finite_difference_coefficients(n, y_cc, fd_coeff_y, buff_size, & + fd_number, fd_order) $:GPU_UPDATE(device='[fd_coeff_y]') end if if (p > 0) then - call s_compute_finite_difference_coefficients(p, z_cc, fd_coeff_z, buff_size, fd_number, fd_order) + call s_compute_finite_difference_coefficients(p, z_cc, fd_coeff_z, buff_size, & + fd_number, fd_order) $:GPU_UPDATE(device='[fd_coeff_z]') end if end if @@ -97,32 +113,49 @@ contains end subroutine s_initialize_derived_variables !> Writes coherent body information, communication files, and probes. + !! @param t_step Current time-step + !! @param q_cons_vf Conservative variables + !! @param q_prim_ts1 Primitive variables at time-stage 1 + !! @param q_prim_ts2 Primitive variables at time-stage 2 subroutine s_compute_derived_variables(t_step, q_cons_vf, q_prim_ts1, q_prim_ts2) - integer, intent(in) :: t_step + integer, intent(in) :: t_step type(scalar_field), dimension(:), intent(inout) :: q_cons_vf type(vector_field), dimension(:), intent(inout) :: q_prim_ts1, q_prim_ts2 - integer :: i, j, k !< Generic loop iterators + integer :: i, j, k !< Generic loop iterators if (probe_wrt) then - call s_derive_acceleration_component(1, q_prim_ts1(1)%vf, q_prim_ts1(2)%vf, q_prim_ts2(1)%vf, q_prim_ts2(2)%vf, x_accel) + call s_derive_acceleration_component(1, q_prim_ts1(1)%vf, & + q_prim_ts1(2)%vf, & + q_prim_ts2(1)%vf, & + q_prim_ts2(2)%vf, & + x_accel) if (n > 0) then - call s_derive_acceleration_component(2, q_prim_ts1(1)%vf, q_prim_ts1(2)%vf, q_prim_ts2(1)%vf, q_prim_ts2(2)%vf, & - & y_accel) + call s_derive_acceleration_component(2, q_prim_ts1(1)%vf, & + q_prim_ts1(2)%vf, & + q_prim_ts2(1)%vf, & + q_prim_ts2(2)%vf, & + y_accel) end if if (p > 0) then - call s_derive_acceleration_component(3, q_prim_ts1(1)%vf, q_prim_ts1(2)%vf, q_prim_ts2(1)%vf, q_prim_ts2(2)%vf, & - & z_accel) + call s_derive_acceleration_component(3, q_prim_ts1(1)%vf, & + q_prim_ts1(2)%vf, & + q_prim_ts2(1)%vf, & + q_prim_ts2(2)%vf, & + z_accel) end if - $:GPU_PARALLEL_LOOP(private='[i, j, k]', collapse=3) + $:GPU_PARALLEL_LOOP(private='[i,j,k]', collapse=3) do k = 0, p do j = 0, n do i = 0, m if (p > 0) then - accel_mag(i, j, k) = sqrt(x_accel(i, j, k)**2._wp + y_accel(i, j, k)**2._wp + z_accel(i, j, k)**2._wp) - else if (n > 0) then - accel_mag(i, j, k) = sqrt(x_accel(i, j, k)**2._wp + y_accel(i, j, k)**2._wp) + accel_mag(i, j, k) = sqrt(x_accel(i, j, k)**2._wp + & + y_accel(i, j, k)**2._wp + & + z_accel(i, j, k)**2._wp) + elseif (n > 0) then + accel_mag(i, j, k) = sqrt(x_accel(i, j, k)**2._wp + & + y_accel(i, j, k)**2._wp) else accel_mag(i, j, k) = x_accel(i, j, k) end if @@ -142,52 +175,72 @@ contains end subroutine s_compute_derived_variables - !> Compute a component of the acceleration field from the primitive variables - subroutine s_derive_acceleration_component(i, q_prim_vf0, q_prim_vf1, q_prim_vf2, q_prim_vf3, q_sf) + !> This subroutine receives as inputs the indicator of the + !! component of the acceleration that should be outputted and + !! the primitive variables. From those inputs, it proceeds + !! to calculate values of the desired acceleration component, + !! which are subsequently stored in derived flow quantity + !! storage variable, q_sf. + !! @param i Acceleration component indicator + !! @param q_prim_vf0 Primitive variables + !! @param q_prim_vf1 Primitive variables + !! @param q_prim_vf2 Primitive variables + !! @param q_prim_vf3 Primitive variables + !! @param q_sf Acceleration component + subroutine s_derive_acceleration_component(i, q_prim_vf0, q_prim_vf1, & + q_prim_vf2, q_prim_vf3, q_sf) + + integer, intent(in) :: i - integer, intent(in) :: i type(scalar_field), dimension(sys_size), intent(in) :: q_prim_vf0 type(scalar_field), dimension(sys_size), intent(in) :: q_prim_vf1 type(scalar_field), dimension(sys_size), intent(in) :: q_prim_vf2 type(scalar_field), dimension(sys_size), intent(in) :: q_prim_vf3 - real(wp), dimension(0:m,0:n,0:p), intent(out) :: q_sf - integer :: j, k, l, r !< Generic loop iterators - ! Computing the acceleration component in the x-coordinate direction + real(wp), dimension(0:m, 0:n, 0:p), intent(out) :: q_sf + + integer :: j, k, l, r !< Generic loop iterators + + ! Computing the acceleration component in the x-coordinate direction if (i == 1) then - $:GPU_PARALLEL_LOOP(private='[j, k, l]', collapse=3) + $:GPU_PARALLEL_LOOP(private='[j,k,l]', collapse=3) do l = 0, p do k = 0, n do j = 0, m - q_sf(j, k, l) = (11._wp*q_prim_vf0(momxb)%sf(j, k, l) - 18._wp*q_prim_vf1(momxb)%sf(j, k, & - & l) + 9._wp*q_prim_vf2(momxb)%sf(j, k, l) - 2._wp*q_prim_vf3(momxb)%sf(j, k, l))/(6._wp*dt) + q_sf(j, k, l) = (11._wp*q_prim_vf0(momxb)%sf(j, k, l) & + - 18._wp*q_prim_vf1(momxb)%sf(j, k, l) & + + 9._wp*q_prim_vf2(momxb)%sf(j, k, l) & + - 2._wp*q_prim_vf3(momxb)%sf(j, k, l))/(6._wp*dt) end do end do end do $:END_GPU_PARALLEL_LOOP() if (n == 0) then - $:GPU_PARALLEL_LOOP(private='[j, k, l, r]', collapse=4) + $:GPU_PARALLEL_LOOP(private='[j,k,l,r]', collapse=4) do l = 0, p do k = 0, n do j = 0, m do r = -fd_number, fd_number - q_sf(j, k, l) = q_sf(j, k, l) + q_prim_vf0(momxb)%sf(j, k, l)*fd_coeff_x(r, & - & j)*q_prim_vf0(momxb)%sf(r + j, k, l) + q_sf(j, k, l) = q_sf(j, k, l) & + + q_prim_vf0(momxb)%sf(j, k, l)*fd_coeff_x(r, j)* & + q_prim_vf0(momxb)%sf(r + j, k, l) end do end do end do end do $:END_GPU_PARALLEL_LOOP() - else if (p == 0) then - $:GPU_PARALLEL_LOOP(private='[j, k, l, r]', collapse=4) + elseif (p == 0) then + $:GPU_PARALLEL_LOOP(private='[j,k,l,r]', collapse=4) do l = 0, p do k = 0, n do j = 0, m do r = -fd_number, fd_number - q_sf(j, k, l) = q_sf(j, k, l) + q_prim_vf0(momxb)%sf(j, k, l)*fd_coeff_x(r, & - & j)*q_prim_vf0(momxb)%sf(r + j, k, l) + q_prim_vf0(momxb + 1)%sf(j, k, l)*fd_coeff_y(r, & - & k)*q_prim_vf0(momxb)%sf(j, r + k, l) + q_sf(j, k, l) = q_sf(j, k, l) & + + q_prim_vf0(momxb)%sf(j, k, l)*fd_coeff_x(r, j)* & + q_prim_vf0(momxb)%sf(r + j, k, l) & + + q_prim_vf0(momxb + 1)%sf(j, k, l)*fd_coeff_y(r, k)* & + q_prim_vf0(momxb)%sf(j, r + k, l) end do end do end do @@ -195,30 +248,36 @@ contains $:END_GPU_PARALLEL_LOOP() else if (grid_geometry == 3) then - $:GPU_PARALLEL_LOOP(private='[j, k, l, r]', collapse=4) + $:GPU_PARALLEL_LOOP(private='[j,k,l,r]', collapse=4) do l = 0, p do k = 0, n do j = 0, m do r = -fd_number, fd_number - q_sf(j, k, l) = q_sf(j, k, l) + q_prim_vf0(momxb)%sf(j, k, l)*fd_coeff_x(r, & - & j)*q_prim_vf0(momxb)%sf(r + j, k, l) + q_prim_vf0(momxb + 1)%sf(j, k, l)*fd_coeff_y(r, & - & k)*q_prim_vf0(momxb)%sf(j, r + k, l) + q_prim_vf0(momxe)%sf(j, k, l)*fd_coeff_z(r, & - & l)*q_prim_vf0(momxb)%sf(j, k, r + l)/y_cc(k) + q_sf(j, k, l) = q_sf(j, k, l) & + + q_prim_vf0(momxb)%sf(j, k, l)*fd_coeff_x(r, j)* & + q_prim_vf0(momxb)%sf(r + j, k, l) & + + q_prim_vf0(momxb + 1)%sf(j, k, l)*fd_coeff_y(r, k)* & + q_prim_vf0(momxb)%sf(j, r + k, l) & + + q_prim_vf0(momxe)%sf(j, k, l)*fd_coeff_z(r, l)* & + q_prim_vf0(momxb)%sf(j, k, r + l)/y_cc(k) end do end do end do end do $:END_GPU_PARALLEL_LOOP() else - $:GPU_PARALLEL_LOOP(private='[j, k, l, r]', collapse=4) + $:GPU_PARALLEL_LOOP(private='[j,k,l,r]', collapse=4) do l = 0, p do k = 0, n do j = 0, m do r = -fd_number, fd_number - q_sf(j, k, l) = q_sf(j, k, l) + q_prim_vf0(momxb)%sf(j, k, l)*fd_coeff_x(r, & - & j)*q_prim_vf0(momxb)%sf(r + j, k, l) + q_prim_vf0(momxb + 1)%sf(j, k, l)*fd_coeff_y(r, & - & k)*q_prim_vf0(momxb)%sf(j, r + k, l) + q_prim_vf0(momxe)%sf(j, k, l)*fd_coeff_z(r, & - & l)*q_prim_vf0(momxb)%sf(j, k, r + l) + q_sf(j, k, l) = q_sf(j, k, l) & + + q_prim_vf0(momxb)%sf(j, k, l)*fd_coeff_x(r, j)* & + q_prim_vf0(momxb)%sf(r + j, k, l) & + + q_prim_vf0(momxb + 1)%sf(j, k, l)*fd_coeff_y(r, k)* & + q_prim_vf0(momxb)%sf(j, r + k, l) & + + q_prim_vf0(momxe)%sf(j, k, l)*fd_coeff_z(r, l)* & + q_prim_vf0(momxb)%sf(j, k, r + l) end do end do end do @@ -227,27 +286,31 @@ contains end if end if ! Computing the acceleration component in the y-coordinate direction - else if (i == 2) then - $:GPU_PARALLEL_LOOP(private='[j, k, l]', collapse=3) + elseif (i == 2) then + $:GPU_PARALLEL_LOOP(private='[j,k,l]', collapse=3) do l = 0, p do k = 0, n do j = 0, m - q_sf(j, k, l) = (11._wp*q_prim_vf0(momxb + 1)%sf(j, k, l) - 18._wp*q_prim_vf1(momxb + 1)%sf(j, k, & - & l) + 9._wp*q_prim_vf2(momxb + 1)%sf(j, k, l) - 2._wp*q_prim_vf3(momxb + 1)%sf(j, k, l))/(6._wp*dt) + q_sf(j, k, l) = (11._wp*q_prim_vf0(momxb + 1)%sf(j, k, l) & + - 18._wp*q_prim_vf1(momxb + 1)%sf(j, k, l) & + + 9._wp*q_prim_vf2(momxb + 1)%sf(j, k, l) & + - 2._wp*q_prim_vf3(momxb + 1)%sf(j, k, l))/(6._wp*dt) end do end do end do $:END_GPU_PARALLEL_LOOP() if (p == 0) then - $:GPU_PARALLEL_LOOP(private='[j, k, l, r]', collapse=4) + $:GPU_PARALLEL_LOOP(private='[j,k,l,r]', collapse=4) do l = 0, p do k = 0, n do j = 0, m do r = -fd_number, fd_number - q_sf(j, k, l) = q_sf(j, k, l) + q_prim_vf0(momxb)%sf(j, k, l)*fd_coeff_x(r, & - & j)*q_prim_vf0(momxb + 1)%sf(r + j, k, l) + q_prim_vf0(momxb + 1)%sf(j, k, l)*fd_coeff_y(r, & - & k)*q_prim_vf0(momxb + 1)%sf(j, r + k, l) + q_sf(j, k, l) = q_sf(j, k, l) & + + q_prim_vf0(momxb)%sf(j, k, l)*fd_coeff_x(r, j)* & + q_prim_vf0(momxb + 1)%sf(r + j, k, l) & + + q_prim_vf0(momxb + 1)%sf(j, k, l)*fd_coeff_y(r, k)* & + q_prim_vf0(momxb + 1)%sf(j, r + k, l) end do end do end do @@ -255,31 +318,37 @@ contains $:END_GPU_PARALLEL_LOOP() else if (grid_geometry == 3) then - $:GPU_PARALLEL_LOOP(private='[j, k, l, r]', collapse=4) + $:GPU_PARALLEL_LOOP(private='[j,k,l,r]', collapse=4) do l = 0, p do k = 0, n do j = 0, m do r = -fd_number, fd_number - q_sf(j, k, l) = q_sf(j, k, l) + q_prim_vf0(momxb)%sf(j, k, l)*fd_coeff_x(r, & - & j)*q_prim_vf0(momxb + 1)%sf(r + j, k, l) + q_prim_vf0(momxb + 1)%sf(j, k, & - & l)*fd_coeff_y(r, k)*q_prim_vf0(momxb + 1)%sf(j, r + k, l) + q_prim_vf0(momxe)%sf(j, k, & - & l)*fd_coeff_z(r, l)*q_prim_vf0(momxb + 1)%sf(j, k, & - & r + l)/y_cc(k) - (q_prim_vf0(momxe)%sf(j, k, l)**2._wp)/y_cc(k) + q_sf(j, k, l) = q_sf(j, k, l) & + + q_prim_vf0(momxb)%sf(j, k, l)*fd_coeff_x(r, j)* & + q_prim_vf0(momxb + 1)%sf(r + j, k, l) & + + q_prim_vf0(momxb + 1)%sf(j, k, l)*fd_coeff_y(r, k)* & + q_prim_vf0(momxb + 1)%sf(j, r + k, l) & + + q_prim_vf0(momxe)%sf(j, k, l)*fd_coeff_z(r, l)* & + q_prim_vf0(momxb + 1)%sf(j, k, r + l)/y_cc(k) & + - (q_prim_vf0(momxe)%sf(j, k, l)**2._wp)/y_cc(k) end do end do end do end do $:END_GPU_PARALLEL_LOOP() else - $:GPU_PARALLEL_LOOP(private='[j, k, l, r]', collapse=4) + $:GPU_PARALLEL_LOOP(private='[j,k,l,r]', collapse=4) do l = 0, p do k = 0, n do j = 0, m do r = -fd_number, fd_number - q_sf(j, k, l) = q_sf(j, k, l) + q_prim_vf0(momxb)%sf(j, k, l)*fd_coeff_x(r, & - & j)*q_prim_vf0(momxb + 1)%sf(r + j, k, l) + q_prim_vf0(momxb + 1)%sf(j, k, & - & l)*fd_coeff_y(r, k)*q_prim_vf0(momxb + 1)%sf(j, r + k, l) + q_prim_vf0(momxe)%sf(j, k, & - & l)*fd_coeff_z(r, l)*q_prim_vf0(momxb + 1)%sf(j, k, r + l) + q_sf(j, k, l) = q_sf(j, k, l) & + + q_prim_vf0(momxb)%sf(j, k, l)*fd_coeff_x(r, j)* & + q_prim_vf0(momxb + 1)%sf(r + j, k, l) & + + q_prim_vf0(momxb + 1)%sf(j, k, l)*fd_coeff_y(r, k)* & + q_prim_vf0(momxb + 1)%sf(j, r + k, l) & + + q_prim_vf0(momxe)%sf(j, k, l)*fd_coeff_z(r, l)* & + q_prim_vf0(momxb + 1)%sf(j, k, r + l) end do end do end do @@ -289,43 +358,52 @@ contains end if ! Computing the acceleration component in the z-coordinate direction else - $:GPU_PARALLEL_LOOP(private='[j, k, l]', collapse=3) + $:GPU_PARALLEL_LOOP(private='[j,k,l]', collapse=3) do l = 0, p do k = 0, n do j = 0, m - q_sf(j, k, l) = (11._wp*q_prim_vf0(momxe)%sf(j, k, l) - 18._wp*q_prim_vf1(momxe)%sf(j, k, & - & l) + 9._wp*q_prim_vf2(momxe)%sf(j, k, l) - 2._wp*q_prim_vf3(momxe)%sf(j, k, l))/(6._wp*dt) + q_sf(j, k, l) = (11._wp*q_prim_vf0(momxe)%sf(j, k, l) & + - 18._wp*q_prim_vf1(momxe)%sf(j, k, l) & + + 9._wp*q_prim_vf2(momxe)%sf(j, k, l) & + - 2._wp*q_prim_vf3(momxe)%sf(j, k, l))/(6._wp*dt) end do end do end do $:END_GPU_PARALLEL_LOOP() if (grid_geometry == 3) then - $:GPU_PARALLEL_LOOP(private='[j, k, l, r]', collapse=4) + $:GPU_PARALLEL_LOOP(private='[j,k,l,r]', collapse=4) do l = 0, p do k = 0, n do j = 0, m do r = -fd_number, fd_number - q_sf(j, k, l) = q_sf(j, k, l) + q_prim_vf0(momxb)%sf(j, k, l)*fd_coeff_x(r, & - & j)*q_prim_vf0(momxe)%sf(r + j, k, l) + q_prim_vf0(momxb + 1)%sf(j, k, l)*fd_coeff_y(r, & - & k)*q_prim_vf0(momxe)%sf(j, r + k, l) + q_prim_vf0(momxe)%sf(j, k, l)*fd_coeff_z(r, & - & l)*q_prim_vf0(momxe)%sf(j, k, r + l)/y_cc(k) + (q_prim_vf0(momxe)%sf(j, k, & - & l)*q_prim_vf0(momxb + 1)%sf(j, k, l))/y_cc(k) + q_sf(j, k, l) = q_sf(j, k, l) & + + q_prim_vf0(momxb)%sf(j, k, l)*fd_coeff_x(r, j)* & + q_prim_vf0(momxe)%sf(r + j, k, l) & + + q_prim_vf0(momxb + 1)%sf(j, k, l)*fd_coeff_y(r, k)* & + q_prim_vf0(momxe)%sf(j, r + k, l) & + + q_prim_vf0(momxe)%sf(j, k, l)*fd_coeff_z(r, l)* & + q_prim_vf0(momxe)%sf(j, k, r + l)/y_cc(k) & + + (q_prim_vf0(momxe)%sf(j, k, l)* & + q_prim_vf0(momxb + 1)%sf(j, k, l))/y_cc(k) end do end do end do end do $:END_GPU_PARALLEL_LOOP() else - $:GPU_PARALLEL_LOOP(private='[j, k, l, r]', collapse=4) + $:GPU_PARALLEL_LOOP(private='[j,k,l,r]', collapse=4) do l = 0, p do k = 0, n do j = 0, m do r = -fd_number, fd_number - q_sf(j, k, l) = q_sf(j, k, l) + q_prim_vf0(momxb)%sf(j, k, l)*fd_coeff_x(r, & - & j)*q_prim_vf0(momxe)%sf(r + j, k, l) + q_prim_vf0(momxb + 1)%sf(j, k, l)*fd_coeff_y(r, & - & k)*q_prim_vf0(momxe)%sf(j, r + k, l) + q_prim_vf0(momxe)%sf(j, k, l)*fd_coeff_z(r, & - & l)*q_prim_vf0(momxe)%sf(j, k, r + l) + q_sf(j, k, l) = q_sf(j, k, l) & + + q_prim_vf0(momxb)%sf(j, k, l)*fd_coeff_x(r, j)* & + q_prim_vf0(momxe)%sf(r + j, k, l) & + + q_prim_vf0(momxb + 1)%sf(j, k, l)*fd_coeff_y(r, k)* & + q_prim_vf0(momxe)%sf(j, r + k, l) & + + q_prim_vf0(momxe)%sf(j, k, l)*fd_coeff_z(r, l)* & + q_prim_vf0(momxe)%sf(j, k, r + l) end do end do end do @@ -336,26 +414,31 @@ contains end subroutine s_derive_acceleration_component - !> Compute the center of mass for each fluid from the primitive variables + !> This subroutine is used together with the volume fraction + !! model and when called upon, it computes the location of + !! of the center of mass for each fluid from the inputted + !! primitive variables, q_prim_vf. The computed location + !! is then written to a formatted data file by the root process. + !! @param q_vf Primitive variables + !! @param c_m Mass,x-location,y-location,z-location impure subroutine s_derive_center_of_mass(q_vf, c_m) + type(scalar_field), dimension(sys_size), intent(IN) :: q_vf + real(wp), dimension(1:num_fluids, 1:5), intent(INOUT) :: c_m + integer :: i, j, k, l !< Generic loop iterators + real(wp) :: tmp, tmp_out !< Temporary variable to store quantity for mpi_allreduce + real(wp) :: dV !< Discrete cell volume - type(scalar_field), dimension(sys_size), intent(in) :: q_vf - real(wp), dimension(1:num_fluids,1:5), intent(inout) :: c_m - integer :: i, j, k, l !< Generic loop iterators - real(wp) :: tmp, tmp_out !< Temporary variable to store quantity for mpi_allreduce - real(wp) :: dV !< Discrete cell volume - - c_m(:,:) = 0.0_wp + c_m(:, :) = 0.0_wp $:GPU_UPDATE(device='[c_m]') - if (n == 0) then ! 1D simulation - $:GPU_PARALLEL_LOOP(collapse=3,private='[j, k, l, dV]') - do l = 0, p ! Loop over grid + if (n == 0) then !1D simulation + $:GPU_PARALLEL_LOOP(collapse=3,private='[j,k,l,dV]') + do l = 0, p !Loop over grid do k = 0, n do j = 0, m $:GPU_LOOP(parallelism='[seq]') - do i = 1, num_fluids ! Loop over individual fluids + do i = 1, num_fluids !Loop over individual fluids dV = dx(j) ! Mass $:GPU_ATOMIC(atomic='update') @@ -371,13 +454,13 @@ contains end do end do $:END_GPU_PARALLEL_LOOP() - else if (p == 0) then ! 2D simulation - $:GPU_PARALLEL_LOOP(collapse=3,private='[j, k, l, dV]') - do l = 0, p ! Loop over grid + elseif (p == 0) then !2D simulation + $:GPU_PARALLEL_LOOP(collapse=3,private='[j,k,l,dV]') + do l = 0, p !Loop over grid do k = 0, n do j = 0, m $:GPU_LOOP(parallelism='[seq]') - do i = 1, num_fluids ! Loop over individual fluids + do i = 1, num_fluids !Loop over individual fluids dV = dx(j)*dy(k) ! Mass $:GPU_ATOMIC(atomic='update') @@ -396,13 +479,14 @@ contains end do end do $:END_GPU_PARALLEL_LOOP() - else ! 3D simulation - $:GPU_PARALLEL_LOOP(collapse=3,private='[j, k, l, dV]') - do l = 0, p ! Loop over grid + else !3D simulation + $:GPU_PARALLEL_LOOP(collapse=3,private='[j,k,l,dV]') + do l = 0, p !Loop over grid do k = 0, n do j = 0, m $:GPU_LOOP(parallelism='[seq]') - do i = 1, num_fluids ! Loop over individual fluids + do i = 1, num_fluids !Loop over individual fluids + dV = dx(j)*dy(k)*dz(l) ! Mass $:GPU_ATOMIC(atomic='update') @@ -428,8 +512,8 @@ contains $:GPU_UPDATE(host='[c_m]') - if (n == 0) then ! 1D simulation - do i = 1, num_fluids ! Loop over individual fluids + if (n == 0) then !1D simulation + do i = 1, num_fluids !Loop over individual fluids ! Sum all components across all processors using MPI_ALLREDUCE if (num_procs > 1) then tmp = c_m(i, 1) @@ -445,8 +529,8 @@ contains ! Compute quotients c_m(i, 2) = c_m(i, 2)/c_m(i, 1) end do - else if (p == 0) then ! 2D simulation - do i = 1, num_fluids ! Loop over individual fluids + elseif (p == 0) then !2D simulation + do i = 1, num_fluids !Loop over individual fluids ! Sum all components across all processors using MPI_ALLREDUCE if (num_procs > 1) then tmp = c_m(i, 1) @@ -466,8 +550,8 @@ contains c_m(i, 2) = c_m(i, 2)/c_m(i, 1) c_m(i, 3) = c_m(i, 3)/c_m(i, 1) end do - else ! 3D simulation - do i = 1, num_fluids ! Loop over individual fluids + else !3D simulation + do i = 1, num_fluids !Loop over individual fluids ! Sum all components across all processors using MPI_ALLREDUCE if (num_procs > 1) then tmp = c_m(i, 1) @@ -516,8 +600,8 @@ contains end if end if - ! Deallocating the variables that might have been used to bookkeep the finite-difference coefficients in the x-, y- and - ! z-directions + ! Deallocating the variables that might have been used to bookkeep + ! the finite-difference coefficients in the x-, y- and z-directions if (allocated(fd_coeff_x)) deallocate (fd_coeff_x) if (allocated(fd_coeff_y)) deallocate (fd_coeff_y) if (allocated(fd_coeff_z)) deallocate (fd_coeff_z) diff --git a/src/simulation/m_fftw.fpp b/src/simulation/m_fftw.fpp index 38005f76ca..661767e13c 100644 --- a/src/simulation/m_fftw.fpp +++ b/src/simulation/m_fftw.fpp @@ -6,12 +6,14 @@ !> @brief Forward and inverse FFT wrappers (FFTW/cuFFT/hipFFT) for azimuthal Fourier filtering in cylindrical geometries module m_fftw - use, intrinsic :: iso_c_binding - use m_derived_types - use m_global_parameters - use m_mpi_proxy + use m_derived_types !< Definitions of the derived types + + use m_global_parameters !< Definitions of the global parameters + + use m_mpi_proxy !< Message passing interface (MPI) module proxy + #if defined(MFC_GPU) && defined(__PGI) use cufft #elif defined(MFC_GPU) @@ -22,48 +24,59 @@ module m_fftw implicit none - private; public :: s_initialize_fftw_module, s_apply_fourier_filter, s_finalize_fftw_module + private; public :: s_initialize_fftw_module, & + s_apply_fourier_filter, & + s_finalize_fftw_module #if !defined(MFC_GPU) include 'fftw3.f03' #endif - type(c_ptr) :: fwd_plan, bwd_plan - type(c_ptr) :: fftw_real_data, fftw_cmplx_data, fftw_fltr_cmplx_data - integer :: real_size, cmplx_size, x_size, batch_size, Nfq - real(c_double), pointer :: data_real(:) !< Real data - complex(c_double_complex), pointer :: data_cmplx(:) !< Complex data in Fourier space - complex(c_double_complex), pointer :: data_fltr_cmplx(:) !< Filtered complex data in Fourier space + type(c_ptr) :: fwd_plan, bwd_plan + type(c_ptr) :: fftw_real_data, fftw_cmplx_data, fftw_fltr_cmplx_data + integer :: real_size, cmplx_size, x_size, batch_size, Nfq + + real(c_double), pointer :: data_real(:) !< Real data + + complex(c_double_complex), pointer :: data_cmplx(:) !< + !! Complex data in Fourier space + + complex(c_double_complex), pointer :: data_fltr_cmplx(:) !< + !! Filtered complex data in Fourier space + #if defined(MFC_GPU) - $:GPU_DECLARE(create='[real_size, cmplx_size, x_size, batch_size, Nfq]') + $:GPU_DECLARE(create='[real_size,cmplx_size,x_size,batch_size,Nfq]') - real(dp), allocatable, target :: data_real_gpu(:) + real(dp), allocatable, target :: data_real_gpu(:) complex(dp), allocatable, target :: data_cmplx_gpu(:) complex(dp), allocatable, target :: data_fltr_cmplx_gpu(:) - $:GPU_DECLARE(create='[data_real_gpu, data_cmplx_gpu, data_fltr_cmplx_gpu]') + $:GPU_DECLARE(create='[data_real_gpu,data_cmplx_gpu,data_fltr_cmplx_gpu]') - !> @cond +!> @cond #if defined(__PGI) integer :: fwd_plan_gpu, bwd_plan_gpu #else - !> @endcond +!> @endcond type(c_ptr) :: fwd_plan_gpu, bwd_plan_gpu - !> @cond +!> @cond #endif - !> @endcond +!> @endcond integer, allocatable :: gpu_fft_size(:), iembed(:), oembed(:) - integer :: istride, ostride, idist, odist, rank + + integer :: istride, ostride, idist, odist, rank #endif contains - !> Initialize the FFTW module + !> The purpose of this subroutine is to create the fftw plan + !! that will be used in the forward and backward DFTs when + !! applying the Fourier filter in the azimuthal direction. impure subroutine s_initialize_fftw_module - integer :: ierr !< Generic flag used to identify and report GPU errors - ! Size of input array going into DFT + integer :: ierr !< Generic flag used to identify and report GPU errors + ! Size of input array going into DFT real_size = p + 1 ! Size of output array coming out of DFT cmplx_size = (p + 1)/2 + 1 @@ -73,13 +86,14 @@ contains #if defined(MFC_GPU) rank = 1; istride = 1; ostride = 1 + allocate (gpu_fft_size(1:rank), iembed(1:rank), oembed(1:rank)) - gpu_fft_size(1) = real_size + gpu_fft_size(1) = real_size; iembed(1) = 0 oembed(1) = 0 - $:GPU_ENTER_DATA(copyin='[real_size, cmplx_size, x_size, sys_size, batch_size, Nfq]') - $:GPU_UPDATE(device='[real_size, cmplx_size, x_size, sys_size, batch_size]') + $:GPU_ENTER_DATA(copyin='[real_size,cmplx_size,x_size,sys_size,batch_size,Nfq]') + $:GPU_UPDATE(device='[real_size,cmplx_size,x_size,sys_size,batch_size]') #else ! Allocate input and output DFT data sizes fftw_real_data = fftw_alloc_real(int(real_size, c_size_t)) @@ -101,30 +115,32 @@ contains @:ALLOCATE(data_fltr_cmplx_gpu(1:cmplx_size*x_size*sys_size)) #if defined(__PGI) - ierr = cufftPlanMany(fwd_plan_gpu, rank, gpu_fft_size, iembed, istride, real_size, oembed, ostride, cmplx_size, & - & CUFFT_D2Z, batch_size) - ierr = cufftPlanMany(bwd_plan_gpu, rank, gpu_fft_size, iembed, istride, cmplx_size, oembed, ostride, real_size, & - & CUFFT_Z2D, batch_size) + ierr = cufftPlanMany(fwd_plan_gpu, rank, gpu_fft_size, iembed, istride, real_size, oembed, ostride, cmplx_size, CUFFT_D2Z, batch_size) + ierr = cufftPlanMany(bwd_plan_gpu, rank, gpu_fft_size, iembed, istride, cmplx_size, oembed, ostride, real_size, CUFFT_Z2D, batch_size) #else - ierr = hipfftPlanMany(fwd_plan_gpu, rank, gpu_fft_size, iembed, istride, real_size, oembed, ostride, cmplx_size, & - & HIPFFT_D2Z, batch_size) - ierr = hipfftPlanMany(bwd_plan_gpu, rank, gpu_fft_size, iembed, istride, cmplx_size, oembed, ostride, real_size, & - & HIPFFT_Z2D, batch_size) + ierr = hipfftPlanMany(fwd_plan_gpu, rank, gpu_fft_size, iembed, istride, real_size, oembed, ostride, cmplx_size, HIPFFT_D2Z, batch_size) + ierr = hipfftPlanMany(bwd_plan_gpu, rank, gpu_fft_size, iembed, istride, cmplx_size, oembed, ostride, real_size, HIPFFT_Z2D, batch_size) #endif + #endif end subroutine s_initialize_fftw_module - !> Apply a Fourier low-pass filter in the azimuthal direction to remove high-frequency content + !> The purpose of this subroutine is to apply a Fourier low- + !! pass filter to the flow variables in the azimuthal direction + !! to remove the high-frequency content. This alleviates the + !! restrictive CFL condition arising from cells near the axis. + !! @param q_cons_vf Conservative variables impure subroutine s_apply_fourier_filter(q_cons_vf) type(scalar_field), dimension(sys_size), intent(inout) :: q_cons_vf - integer :: i, j, k, l !< Generic loop iterators - integer :: ierr !< Generic flag used to identify and report GPU errors - ! Restrict filter to processors that have cells adjacent to axis + integer :: i, j, k, l !< Generic loop iterators + integer :: ierr !< Generic flag used to identify and report GPU errors + ! Restrict filter to processors that have cells adjacent to axis if (bc_y%beg >= 0) return #if defined(MFC_GPU) + $:GPU_PARALLEL_LOOP(collapse=3) do k = 1, sys_size do j = 0, m @@ -160,8 +176,7 @@ contains do k = 1, sys_size do j = 0, m do l = 1, Nfq - data_fltr_cmplx_gpu(l + j*cmplx_size + (k - 1)*cmplx_size*x_size) = data_cmplx_gpu(l + j*cmplx_size + (k - 1) & - & *cmplx_size*x_size) + data_fltr_cmplx_gpu(l + j*cmplx_size + (k - 1)*cmplx_size*x_size) = data_cmplx_gpu(l + j*cmplx_size + (k - 1)*cmplx_size*x_size) end do end do end do @@ -180,8 +195,7 @@ contains do k = 1, sys_size do j = 0, m do l = 0, p - data_real_gpu(l + j*real_size + 1 + (k - 1)*real_size*x_size) = data_real_gpu(l + j*real_size + 1 + (k - 1) & - & *real_size*x_size)/real(real_size, dp) + data_real_gpu(l + j*real_size + 1 + (k - 1)*real_size*x_size) = data_real_gpu(l + j*real_size + 1 + (k - 1)*real_size*x_size)/real(real_size, dp) q_cons_vf(k)%sf(j, 0, l) = data_real_gpu(l + j*real_size + 1 + (k - 1)*real_size*x_size) end do end do @@ -189,6 +203,7 @@ contains $:END_GPU_PARALLEL_LOOP() do i = 1, fourier_rings + $:GPU_PARALLEL_LOOP(collapse=3) do k = 1, sys_size do j = 0, m @@ -225,8 +240,7 @@ contains do k = 1, sys_size do j = 0, m do l = 1, Nfq - data_fltr_cmplx_gpu(l + j*cmplx_size + (k - 1)*cmplx_size*x_size) = data_cmplx_gpu(l + j*cmplx_size + (k & - & - 1)*cmplx_size*x_size) + data_fltr_cmplx_gpu(l + j*cmplx_size + (k - 1)*cmplx_size*x_size) = data_cmplx_gpu(l + j*cmplx_size + (k - 1)*cmplx_size*x_size) end do end do end do @@ -245,25 +259,25 @@ contains do k = 1, sys_size do j = 0, m do l = 0, p - data_real_gpu(l + j*real_size + 1 + (k - 1)*real_size*x_size) = data_real_gpu(l + j*real_size + 1 + (k & - & - 1)*real_size*x_size)/real(real_size, dp) + data_real_gpu(l + j*real_size + 1 + (k - 1)*real_size*x_size) = data_real_gpu(l + j*real_size + 1 + (k - 1)*real_size*x_size)/real(real_size, dp) q_cons_vf(k)%sf(j, i, l) = data_real_gpu(l + j*real_size + 1 + (k - 1)*real_size*x_size) end do end do end do $:END_GPU_PARALLEL_LOOP() end do + #else Nfq = 3 do j = 0, m do k = 1, sys_size data_fltr_cmplx(:) = (0_dp, 0_dp) - data_real(1:p + 1) = q_cons_vf(k)%sf(j, 0,0:p) + data_real(1:p + 1) = q_cons_vf(k)%sf(j, 0, 0:p) call fftw_execute_dft_r2c(fwd_plan, data_real, data_cmplx) data_fltr_cmplx(1:Nfq) = data_cmplx(1:Nfq) call fftw_execute_dft_c2r(bwd_plan, data_fltr_cmplx, data_real) data_real(:) = data_real(:)/real(real_size, dp) - q_cons_vf(k)%sf(j, 0,0:p) = data_real(1:p + 1) + q_cons_vf(k)%sf(j, 0, 0:p) = data_real(1:p + 1) end do end do @@ -273,12 +287,12 @@ contains do j = 0, m do k = 1, sys_size data_fltr_cmplx(:) = (0_dp, 0_dp) - data_real(1:p + 1) = q_cons_vf(k)%sf(j, i,0:p) + data_real(1:p + 1) = q_cons_vf(k)%sf(j, i, 0:p) call fftw_execute_dft_r2c(fwd_plan, data_real, data_cmplx) data_fltr_cmplx(1:Nfq) = data_cmplx(1:Nfq) call fftw_execute_dft_c2r(bwd_plan, data_fltr_cmplx, data_real) data_real(:) = data_real(:)/real(real_size, dp) - q_cons_vf(k)%sf(j, i,0:p) = data_real(1:p + 1) + q_cons_vf(k)%sf(j, i, 0:p) = data_real(1:p + 1) end do end do end do @@ -286,14 +300,16 @@ contains end subroutine s_apply_fourier_filter - !> Finalize the FFTW module + !> The purpose of this subroutine is to destroy the fftw plan + !! that will be used in the forward and backward DFTs when + !! applying the Fourier filter in the azimuthal direction. impure subroutine s_finalize_fftw_module #if defined(MFC_GPU) - integer :: ierr !< Generic flag used to identify and report GPU errors - + integer :: ierr !< Generic flag used to identify and report GPU errors @:DEALLOCATE(data_real_gpu, data_fltr_cmplx_gpu, data_cmplx_gpu) #if defined(__PGI) + ierr = cufftDestroy(fwd_plan_gpu) ierr = cufftDestroy(bwd_plan_gpu) #else @@ -310,5 +326,4 @@ contains #endif end subroutine s_finalize_fftw_module - end module m_fftw diff --git a/src/simulation/m_global_parameters.fpp b/src/simulation/m_global_parameters.fpp index 079d36ebc2..9d3d018b3b 100644 --- a/src/simulation/m_global_parameters.fpp +++ b/src/simulation/m_global_parameters.fpp @@ -9,11 +9,13 @@ module m_global_parameters #ifdef MFC_MPI - use mpi !< Message passing interface (MPI) module + use mpi !< Message passing interface (MPI) module #endif - use m_derived_types - use m_helper_basic + use m_derived_types !< Definitions of the derived types + + use m_helper_basic !< Functions to compare floating point numbers + ! $:USE_GPU_MODULE() implicit none @@ -22,12 +24,14 @@ module m_global_parameters real(wp) :: wall_time_avg = 0 ! Logistics - integer :: num_procs !< Number of processors - character(LEN=path_len) :: case_dir !< Case folder location - logical :: run_time_info !< Run-time output flag - integer :: t_step_old !< Existing IC/grid folder + integer :: num_procs !< Number of processors + character(LEN=path_len) :: case_dir !< Case folder location + logical :: run_time_info !< Run-time output flag + integer :: t_step_old !< Existing IC/grid folder + ! Computational Domain Parameters - integer :: proc_rank !< Rank of the local processor + integer :: proc_rank !< Rank of the local processor + !> @name Number of cells in the x-, y- and z-directions, respectively !> @{ integer :: m, n, p @@ -46,138 +50,144 @@ module m_global_parameters logical :: cyl_coord integer :: grid_geometry !> @} - $:GPU_DECLARE(create='[cyl_coord, grid_geometry]') + $:GPU_DECLARE(create='[cyl_coord,grid_geometry]') !> @name Cell-boundary (CB) locations in the x-, y- and z-directions, respectively !> @{ real(wp), target, allocatable, dimension(:) :: x_cb, y_cb, z_cb + type(bounds_info), dimension(3) :: glb_bounds !< !> @} !> @name Cell-center (CC) locations in the x-, y- and z-directions, respectively !> @{ real(wp), target, allocatable, dimension(:) :: x_cc, y_cc, z_cc !> @} - ! type(bounds_info) :: x_domain, y_domain, z_domain !< Locations of the domain bounds in the x-, y- and z-coordinate directions + !> @name Cell-width distributions in the x-, y- and z-directions, respectively !> @{ real(wp), target, allocatable, dimension(:) :: dx, dy, dz !> @} - real(wp) :: dt !< Size of the time-step - $:GPU_DECLARE(create='[x_cb, y_cb, z_cb, x_cc, y_cc, z_cc, dx, dy, dz, dt, m, n, p]') + real(wp) :: dt !< Size of the time-step + + $:GPU_DECLARE(create='[x_cb,y_cb,z_cb,x_cc,y_cc,z_cc,dx,dy,dz,dt,m,n,p,glb_bounds]') - !> @name Starting time-step iteration, stopping time-step iteration and the number of time-step iterations between successive - !! solution backups, respectively + !> @name Starting time-step iteration, stopping time-step iteration and the number + !! of time-step iterations between successive solution backups, respectively !> @{ integer :: t_step_start, t_step_stop, t_step_save !> @} - !> @name Starting time, stopping time, and time between backups, simulation time, and prescribed cfl respectively + !> @name Starting time, stopping time, and time between backups, simulation time, + !! and prescribed cfl respectively !> @{ real(wp) :: t_stop, t_save, cfl_target - integer :: n_start + integer :: n_start !> @} $:GPU_DECLARE(create='[cfl_target]') logical :: cfl_adap_dt, cfl_const_dt, cfl_dt - integer :: t_step_print !< Number of time-steps between printouts + + integer :: t_step_print !< Number of time-steps between printouts + ! Simulation Algorithm Parameters - integer :: model_eqns !< Multicomponent flow model + integer :: model_eqns !< Multicomponent flow model #:if MFC_CASE_OPTIMIZATION - integer, parameter :: num_dims = ${num_dims}$ !< Number of spatial dimensions - integer, parameter :: num_vels = ${num_vels}$ !< Number of velocity components (different from num_dims for mhd) + integer, parameter :: num_dims = ${num_dims}$ !< Number of spatial dimensions + integer, parameter :: num_vels = ${num_vels}$ !< Number of velocity components (different from num_dims for mhd) #:else - integer :: num_dims !< Number of spatial dimensions - integer :: num_vels !< Number of velocity components (different from num_dims for mhd) + integer :: num_dims !< Number of spatial dimensions + integer :: num_vels !< Number of velocity components (different from num_dims for mhd) #:endif - logical :: mpp_lim !< Mixture physical parameters (MPP) limits - integer :: time_stepper !< Time-stepper algorithm + logical :: mpp_lim !< Mixture physical parameters (MPP) limits + integer :: time_stepper !< Time-stepper algorithm logical :: prim_vars_wrt #:if MFC_CASE_OPTIMIZATION - integer, parameter :: recon_type = ${recon_type}$ !< Reconstruction type - integer, parameter :: weno_polyn = ${weno_polyn}$ !< Degree of the WENO polynomials (polyn) - integer, parameter :: muscl_polyn = ${muscl_polyn}$ !< Degree of the MUSCL polynomials (polyn) - integer, parameter :: weno_order = ${weno_order}$ !< Order of the WENO reconstruction - integer, parameter :: muscl_order = ${muscl_order}$ !< Order of the MUSCL order - !> Number of stencils for WENO reconstruction (only different from weno_polyn for TENO(>5)) - integer, parameter :: weno_num_stencils = ${weno_num_stencils}$ - integer, parameter :: muscl_lim = ${muscl_lim}$ !< MUSCL Limiter - integer, parameter :: num_fluids = ${num_fluids}$ !< number of fluids in the simulation - logical, parameter :: wenojs = (${wenojs}$ /= 0) !< WENO-JS (default) - logical, parameter :: mapped_weno = (${mapped_weno}$ /= 0) !< WENO-M (WENO with mapping of nonlinear weights) - logical, parameter :: wenoz = (${wenoz}$ /= 0) !< WENO-Z - logical, parameter :: teno = (${teno}$ /= 0) !< TENO (Targeted ENO) - real(wp), parameter :: wenoz_q = ${wenoz_q}$ !< Power constant for WENO-Z - logical, parameter :: mhd = (${mhd}$ /= 0) !< Magnetohydrodynamics - logical, parameter :: relativity = (${relativity}$ /= 0) !< Relativity (only for MHD) - integer, parameter :: igr_iter_solver = ${igr_iter_solver}$ !< IGR elliptic solver - integer, parameter :: igr_order = ${igr_order}$ !< Reconstruction order for IGR - logical, parameter :: igr = (${igr}$ /= 0) !< use information geometric regularization - logical, parameter :: igr_pres_lim = (${igr_pres_lim}$ /= 0) !< Limit to positive pressures for IGR - logical, parameter :: viscous = (${viscous}$ /= 0) !< Viscous effects + integer, parameter :: recon_type = ${recon_type}$ !< Reconstruction type + integer, parameter :: weno_polyn = ${weno_polyn}$ !< Degree of the WENO polynomials (polyn) + integer, parameter :: muscl_polyn = ${muscl_polyn}$ !< Degree of the MUSCL polynomials (polyn) + integer, parameter :: weno_order = ${weno_order}$ !< Order of the WENO reconstruction + integer, parameter :: muscl_order = ${muscl_order}$ !< Order of the MUSCL order + integer, parameter :: weno_num_stencils = ${weno_num_stencils}$ !< Number of stencils for WENO reconstruction (only different from weno_polyn for TENO(>5)) + integer, parameter :: muscl_lim = ${muscl_lim}$ !< MUSCL Limiter + integer, parameter :: num_fluids = ${num_fluids}$ !< number of fluids in the simulation + logical, parameter :: wenojs = (${wenojs}$ /= 0) !< WENO-JS (default) + logical, parameter :: mapped_weno = (${mapped_weno}$ /= 0) !< WENO-M (WENO with mapping of nonlinear weights) + logical, parameter :: wenoz = (${wenoz}$ /= 0) !< WENO-Z + logical, parameter :: teno = (${teno}$ /= 0) !< TENO (Targeted ENO) + real(wp), parameter :: wenoz_q = ${wenoz_q}$ !< Power constant for WENO-Z + logical, parameter :: mhd = (${mhd}$ /= 0) !< Magnetohydrodynamics + logical, parameter :: relativity = (${relativity}$ /= 0) !< Relativity (only for MHD) + integer, parameter :: igr_iter_solver = ${igr_iter_solver}$ !< IGR elliptic solver + integer, parameter :: igr_order = ${igr_order}$ !< Reconstruction order for IGR + logical, parameter :: igr = (${igr}$ /= 0) !< use information geometric regularization + logical, parameter :: igr_pres_lim = (${igr_pres_lim}$ /= 0)!< Limit to positive pressures for IGR + logical, parameter :: viscous = (${viscous}$ /= 0) !< Viscous effects #:else - integer :: recon_type !< Reconstruction Type - integer :: weno_polyn !< Degree of the WENO polynomials (polyn) - integer :: muscl_polyn !< Degree of the MUSCL polynomials (polyn)i - integer :: weno_order !< Order of the WENO reconstruction - integer :: muscl_order !< Order of the MUSCL reconstruction - integer :: weno_num_stencils !< Number of stencils for WENO reconstruction (only different from weno_polyn for TENO(>5)) - integer :: muscl_lim !< MUSCL Limiter - integer :: num_fluids !< number of fluids in the simulation - logical :: wenojs !< WENO-JS (default) - logical :: mapped_weno !< WENO-M (WENO with mapping of nonlinear weights) - logical :: wenoz !< WENO-Z - logical :: teno !< TENO (Targeted ENO) - real(wp) :: wenoz_q !< Power constant for WENO-Z - logical :: mhd !< Magnetohydrodynamics - logical :: relativity !< Relativity (only for MHD) - integer :: igr_iter_solver !< IGR elliptic solver - integer :: igr_order !< Reconstruction order for IGR - logical :: igr !< Use information geometric regularization - logical :: igr_pres_lim !< Limit to positive pressures for IGR - logical :: viscous !< Viscous effects + integer :: recon_type !< Reconstruction Type + integer :: weno_polyn !< Degree of the WENO polynomials (polyn) + integer :: muscl_polyn !< Degree of the MUSCL polynomials (polyn)i + integer :: weno_order !< Order of the WENO reconstruction + integer :: muscl_order !< Order of the MUSCL reconstruction + integer :: weno_num_stencils !< Number of stencils for WENO reconstruction (only different from weno_polyn for TENO(>5)) + integer :: muscl_lim !< MUSCL Limiter + integer :: num_fluids !< number of fluids in the simulation + logical :: wenojs !< WENO-JS (default) + logical :: mapped_weno !< WENO-M (WENO with mapping of nonlinear weights) + logical :: wenoz !< WENO-Z + logical :: teno !< TENO (Targeted ENO) + real(wp) :: wenoz_q !< Power constant for WENO-Z + logical :: mhd !< Magnetohydrodynamics + logical :: relativity !< Relativity (only for MHD) + integer :: igr_iter_solver!< IGR elliptic solver + integer :: igr_order !< Reconstruction order for IGR + logical :: igr !< Use information geometric regularization + logical :: igr_pres_lim !< Limit to positive pressures for IGR + logical :: viscous !< Viscous effects #:endif !> @name Variables for our of core IGR computation on NVIDIA !> @{ - logical :: nv_uvm_out_of_core !< Enable out-of-core storage of q_cons_ts(2) in timestepping (default FALSE) - integer :: nv_uvm_igr_temps_on_gpu !< 0 => jac, jac_rhs, and jac_old on CPU - ! 1 => jac on GPU, jac_rhs and jac_old on CPU 2 => jac and jac_rhs on GPU, jac_old on CPU 3 => jac, jac_rhs, and jac_old on GPU - ! (default) - logical :: nv_uvm_pref_gpu !< Enable explicit gpu memory hints (default FALSE) + logical :: nv_uvm_out_of_core ! Enable out-of-core storage of q_cons_ts(2) in timestepping (default FALSE) + integer :: nv_uvm_igr_temps_on_gpu ! 0 => jac, jac_rhs, and jac_old on CPU + ! 1 => jac on GPU, jac_rhs and jac_old on CPU + ! 2 => jac and jac_rhs on GPU, jac_old on CPU + ! 3 => jac, jac_rhs, and jac_old on GPU (default) + logical :: nv_uvm_pref_gpu ! Enable explicit gpu memory hints (default FALSE) !> @} - real(wp) :: weno_eps !< Binding for the WENO nonlinear weights - real(wp) :: teno_CT !< Smoothness threshold for TENO - logical :: mp_weno !< Monotonicity preserving (MP) WENO - logical :: weno_avg !< Average left/right cell-boundary states - logical :: weno_Re_flux !< WENO reconstruct velocity gradients for viscous stress tensor - integer :: riemann_solver !< Riemann solver algorithm - integer :: low_Mach !< Low Mach number fix to HLLC Riemann solver - integer :: wave_speeds !< Wave speeds estimation method - integer :: avg_state !< Average state evaluation method - logical :: alt_soundspeed !< Alternate mixture sound speed - logical :: null_weights !< Null undesired WENO weights - logical :: mixture_err !< Mixture properties correction - logical :: hypoelasticity !< hypoelasticity modeling - logical :: hyperelasticity !< hyperelasticity modeling - logical :: int_comp !< THINC interface compression - real(wp) :: ic_eps !< THINC Epsilon to compress on surface cells - real(wp) :: ic_beta !< THINC Sharpness Parameter - integer :: hyper_model !< hyperelasticity solver algorithm - logical :: elasticity !< elasticity modeling, true for hyper or hypo - logical, parameter :: chemistry = .${chemistry}$. !< Chemistry modeling - logical :: shear_stress !< Shear stresses - logical :: bulk_stress !< Bulk stresses - logical :: cont_damage !< Continuum damage modeling - logical :: hyper_cleaning !< Hyperbolic cleaning for MHD for divB=0 - integer :: num_igr_iters !< number of iterations for elliptic solve - integer :: num_igr_warm_start_iters !< number of warm start iterations for elliptic solve - real(wp) :: alf_factor !< alpha factor for IGR - logical :: bodyForces - logical :: bf_x, bf_y, bf_z !< body force toggle in three directions - !> amplitude, frequency, and phase shift sinusoid in each direction + real(wp) :: weno_eps !< Binding for the WENO nonlinear weights + real(wp) :: teno_CT !< Smoothness threshold for TENO + logical :: mp_weno !< Monotonicity preserving (MP) WENO + logical :: weno_avg ! Average left/right cell-boundary states + logical :: weno_Re_flux !< WENO reconstruct velocity gradients for viscous stress tensor + integer :: riemann_solver !< Riemann solver algorithm + integer :: low_Mach !< Low Mach number fix to HLLC Riemann solver + integer :: wave_speeds !< Wave speeds estimation method + integer :: avg_state !< Average state evaluation method + logical :: alt_soundspeed !< Alternate mixture sound speed + logical :: null_weights !< Null undesired WENO weights + logical :: mixture_err !< Mixture properties correction + logical :: hypoelasticity !< hypoelasticity modeling + logical :: hyperelasticity !< hyperelasticity modeling + logical :: int_comp !< THINC interface compression + real(wp) :: ic_eps !< THINC Epsilon to compress on surface cells + real(wp) :: ic_beta !< THINC Sharpness Parameter + integer :: hyper_model !< hyperelasticity solver algorithm + logical :: elasticity !< elasticity modeling, true for hyper or hypo + logical, parameter :: chemistry = .${chemistry}$. !< Chemistry modeling + logical :: shear_stress !< Shear stresses + logical :: bulk_stress !< Bulk stresses + logical :: cont_damage !< Continuum damage modeling + logical :: hyper_cleaning !< Hyperbolic cleaning for MHD for divB=0 + integer :: num_igr_iters !< number of iterations for elliptic solve + integer :: num_igr_warm_start_iters !< number of warm start iterations for elliptic solve + real(wp) :: alf_factor !< alpha factor for IGR + + logical :: bodyForces + logical :: bf_x, bf_y, bf_z !< body force toggle in three directions + !< amplitude, frequency, and phase shift sinusoid in each direction #:for dir in {'x', 'y', 'z'} #:for param in {'k','w','p','g'} real(wp) :: ${param}$_${dir}$ @@ -190,26 +200,29 @@ module m_global_parameters integer :: cpu_start, cpu_end, cpu_rate #:if not MFC_CASE_OPTIMIZATION - $:GPU_DECLARE(create='[num_dims, num_vels, weno_polyn, weno_order]') - $:GPU_DECLARE(create='[weno_num_stencils, num_fluids, wenojs]') - $:GPU_DECLARE(create='[mapped_weno, wenoz, teno, wenoz_q, mhd, relativity]') - $:GPU_DECLARE(create='[igr_iter_solver, igr_order, viscous, igr_pres_lim, igr]') + $:GPU_DECLARE(create='[num_dims,num_vels,weno_polyn,weno_order]') + $:GPU_DECLARE(create='[weno_num_stencils,num_fluids,wenojs]') + $:GPU_DECLARE(create='[mapped_weno, wenoz,teno,wenoz_q,mhd,relativity]') + $:GPU_DECLARE(create='[igr_iter_solver,igr_order,viscous,igr_pres_lim,igr]') $:GPU_DECLARE(create='[recon_type, muscl_order, muscl_polyn, muscl_lim]') #:endif - $:GPU_DECLARE(create='[mpp_lim, model_eqns, mixture_err, alt_soundspeed]') - $:GPU_DECLARE(create='[avg_state, mp_weno, weno_eps, teno_CT, hypoelasticity]') - $:GPU_DECLARE(create='[hyperelasticity, hyper_model, elasticity, low_Mach]') - $:GPU_DECLARE(create='[shear_stress, bulk_stress, cont_damage, hyper_cleaning]') + $:GPU_DECLARE(create='[mpp_lim,model_eqns,mixture_err,alt_soundspeed]') + $:GPU_DECLARE(create='[avg_state,mp_weno,weno_eps,teno_CT,hypoelasticity]') + $:GPU_DECLARE(create='[hyperelasticity,hyper_model,elasticity,low_Mach]') + $:GPU_DECLARE(create='[shear_stress,bulk_stress,cont_damage,hyper_cleaning]') - logical :: relax !< activate phase change - integer :: relax_model !< Relaxation model - real(wp) :: palpha_eps !< trigger parameter for the p relaxation procedure, phase change model - real(wp) :: ptgalpha_eps !< trigger parameter for the pTg relaxation procedure, phase change model - $:GPU_DECLARE(create='[relax, relax_model, palpha_eps, ptgalpha_eps]') + logical :: relax !< activate phase change + integer :: relax_model !< Relaxation model + real(wp) :: palpha_eps !< trigger parameter for the p relaxation procedure, phase change model + real(wp) :: ptgalpha_eps !< trigger parameter for the pTg relaxation procedure, phase change model + + $:GPU_DECLARE(create='[relax, relax_model, palpha_eps,ptgalpha_eps]') integer :: num_bc_patches logical :: bc_io + logical, dimension(3) :: periodic_bc + !> @name Boundary conditions (BC) in the x-, y- and z-directions, respectively !> @{ type(int_bounds_info) :: bc_x, bc_y, bc_z @@ -221,192 +234,239 @@ module m_global_parameters #elif defined(MFC_OpenMP) $:GPU_DECLARE(create='[bc_x, bc_y, bc_z]') #endif - type(bounds_info) :: x_domain, y_domain, z_domain - $:GPU_DECLARE(create='[x_domain, y_domain, z_domain]') - real(wp) :: x_a, y_a, z_a - real(wp) :: x_b, y_b, z_b - logical :: parallel_io !< Format of the data files - logical :: file_per_process !< shared file or not when using parallel io - integer :: precision !< Precision of output files - logical :: down_sample !< down sample the output files + + logical :: parallel_io !< Format of the data files + logical :: file_per_process !< shared file or not when using parallel io + integer :: precision !< Precision of output files + logical :: down_sample !< down sample the output files $:GPU_DECLARE(create='[down_sample]') - integer, allocatable, dimension(:) :: proc_coords !< Processor coordinates in MPI_CART_COMM - integer, allocatable, dimension(:) :: start_idx !< Starting cell-center index of local processor in global grid - type(mpi_io_var), public :: MPI_IO_DATA - type(mpi_io_ib_var), public :: MPI_IO_IB_DATA - type(mpi_io_airfoil_ib_var), public :: MPI_IO_airfoil_IB_DATA - type(mpi_io_levelset_var), public :: MPI_IO_levelset_DATA - type(mpi_io_levelset_norm_var), public :: MPI_IO_levelsetnorm_DATA - real(wp), allocatable, dimension(:,:), public :: MPI_IO_DATA_lag_bubbles + integer, allocatable, dimension(:) :: proc_coords !< + !! Processor coordinates in MPI_CART_COMM + + type(bounds_info), allocatable, dimension(:) :: pcomm_coords + $:GPU_DECLARE(create='[pcomm_coords]') + !! Coordinates for EL particle transfer + + type(int_bounds_info), dimension(3) :: nidx !< Indices for neighboring processors + + integer, allocatable, dimension(:, :, :) :: neighbor_ranks + !! Neighbor ranks + + integer, allocatable, dimension(:) :: start_idx !< + !! Starting cell-center index of local processor in global grid + + type(mpi_io_var), public :: MPI_IO_DATA + type(mpi_io_ib_var), public :: MPI_IO_IB_DATA + type(mpi_io_airfoil_ib_var), public :: MPI_IO_airfoil_IB_DATA + type(mpi_io_levelset_var), public :: MPI_IO_levelset_DATA + type(mpi_io_levelset_norm_var), public :: MPI_IO_levelsetnorm_DATA + real(wp), allocatable, dimension(:, :), public :: MPI_IO_DATA_lag_bubbles !> @name MPI info for parallel IO with Lustre file systems !> @{ character(LEN=name_len) :: mpiiofs - integer :: mpi_info_int + integer :: mpi_info_int !> @} - !> @name Annotations of the structure of the state and flux vectors in terms of the size and the configuration of the system of - !! equations to which they belong + !> @name Annotations of the structure of the state and flux vectors in terms of the + !! size and the configuration of the system of equations to which they belong !> @{ - integer :: sys_size !< Number of unknowns in system of eqns. - type(int_bounds_info) :: cont_idx !< Indexes of first & last continuity eqns. - type(int_bounds_info) :: mom_idx !< Indexes of first & last momentum eqns. - integer :: E_idx !< Index of energy equation - integer :: n_idx !< Index of number density - type(int_bounds_info) :: adv_idx !< Indexes of first & last advection eqns. - type(int_bounds_info) :: internalEnergies_idx !< Indexes of first & last internal energy eqns. - type(bub_bounds_info) :: bub_idx !< Indexes of first & last bubble variable eqns. - integer :: alf_idx !< Index of void fraction - integer :: gamma_idx !< Index of specific heat ratio func. eqn. - integer :: pi_inf_idx !< Index of liquid stiffness func. eqn. - type(int_bounds_info) :: B_idx !< Indexes of first and last magnetic field eqns. - type(int_bounds_info) :: stress_idx !< Indexes of first and last shear stress eqns. - type(int_bounds_info) :: xi_idx !< Indexes of first and last reference map eqns. - integer :: b_size !< Number of elements in the symmetric b tensor, plus one - integer :: tensor_size !< Number of elements in the full tensor plus one - type(int_bounds_info) :: species_idx !< Indexes of first & last concentration eqns. - integer :: c_idx !< Index of color function - integer :: damage_idx !< Index of damage state variable (D) for continuum damage model - integer :: psi_idx !< Index of hyperbolic cleaning state variable for MHD + integer :: sys_size !< Number of unknowns in system of eqns. + type(int_bounds_info) :: cont_idx !< Indexes of first & last continuity eqns. + type(int_bounds_info) :: mom_idx !< Indexes of first & last momentum eqns. + integer :: E_idx !< Index of energy equation + integer :: n_idx !< Index of number density + type(int_bounds_info) :: adv_idx !< Indexes of first & last advection eqns. + type(int_bounds_info) :: internalEnergies_idx !< Indexes of first & last internal energy eqns. + type(bub_bounds_info) :: bub_idx !< Indexes of first & last bubble variable eqns. + integer :: alf_idx !< Index of void fraction + integer :: gamma_idx !< Index of specific heat ratio func. eqn. + integer :: pi_inf_idx !< Index of liquid stiffness func. eqn. + type(int_bounds_info) :: B_idx !< Indexes of first and last magnetic field eqns. + type(int_bounds_info) :: stress_idx !< Indexes of first and last shear stress eqns. + type(int_bounds_info) :: xi_idx !< Indexes of first and last reference map eqns. + integer :: b_size !< Number of elements in the symmetric b tensor, plus one + integer :: tensor_size !< Number of elements in the full tensor plus one + type(int_bounds_info) :: species_idx !< Indexes of first & last concentration eqns. + integer :: c_idx !< Index of color function + integer :: damage_idx !< Index of damage state variable (D) for continuum damage model + integer :: psi_idx !< Index of hyperbolic cleaning state variable for MHD !> @} - $:GPU_DECLARE(create='[sys_size, E_idx, n_idx, bub_idx, alf_idx, gamma_idx]') - $:GPU_DECLARE(create='[pi_inf_idx, B_idx, stress_idx, xi_idx, b_size]') - $:GPU_DECLARE(create='[tensor_size, species_idx, c_idx]') + $:GPU_DECLARE(create='[sys_size,E_idx,n_idx,bub_idx,alf_idx,gamma_idx]') + $:GPU_DECLARE(create='[pi_inf_idx,B_idx,stress_idx,xi_idx,b_size]') + $:GPU_DECLARE(create='[tensor_size,species_idx,c_idx]') - ! Cell Indices for the (local) interior points (O-m, O-n, 0-p). Stands for "InDices With INTerior". + ! Cell Indices for the (local) interior points (O-m, O-n, 0-p). + ! Stands for "InDices With INTerior". type(int_bounds_info) :: idwint(1:3) $:GPU_DECLARE(create='[idwint]') - ! Cell Indices for the entire (local) domain. In simulation and post_process, this includes the buffer region. idwbuff and - ! idwint are the same otherwise. Stands for "InDices With BUFFer". + ! Cell Indices for the entire (local) domain. In simulation and post_process, + ! this includes the buffer region. idwbuff and idwint are the same otherwise. + ! Stands for "InDices With BUFFer". type(int_bounds_info) :: idwbuff(1:3) $:GPU_DECLARE(create='[idwbuff]') - !> @name The number of fluids, along with their identifying indexes, respectively, for which viscous effects, e.g. the shear - !! and/or the volume Reynolds (Re) numbers, will be non-negligible. + !> @name The number of fluids, along with their identifying indexes, respectively, + !! for which viscous effects, e.g. the shear and/or the volume Reynolds (Re) + !! numbers, will be non-negligible. !> @{ - integer, dimension(2) :: Re_size - integer :: Re_size_max - integer, allocatable, dimension(:,:) :: Re_idx + integer, dimension(2) :: Re_size + integer :: Re_size_max + integer, allocatable, dimension(:, :) :: Re_idx !> @} - $:GPU_DECLARE(create='[Re_size, Re_size_max, Re_idx]') + $:GPU_DECLARE(create='[Re_size,Re_size_max,Re_idx]') - ! WENO averaging flag: use arithmetic mean or unaltered WENO-reconstructed cell-boundary values + ! The WENO average (WA) flag regulates whether the calculation of any cell- + ! average spatial derivatives is carried out in each cell by utilizing the + ! arithmetic mean of the left and right, WENO-reconstructed, cell-boundary + ! values or simply, the unaltered left and right, WENO-reconstructed, cell- + ! boundary values. !> @{ real(wp) :: wa_flg !> @} $:GPU_DECLARE(create='[wa_flg]') - !> @name The coordinate direction indexes and flags (flg), respectively, for which the configurations will be determined with - !! respect to a working direction and that will be used to isolate the contributions, in that direction, in the dimensionally - !! split system of equations. + !> @name The coordinate direction indexes and flags (flg), respectively, for which + !! the configurations will be determined with respect to a working direction + !! and that will be used to isolate the contributions, in that direction, in + !! the dimensionally split system of equations. !> @{ - integer, dimension(3) :: dir_idx + integer, dimension(3) :: dir_idx real(wp), dimension(3) :: dir_flg - integer, dimension(3) :: dir_idx_tau !< used for hypoelasticity=true + integer, dimension(3) :: dir_idx_tau !!used for hypoelasticity=true !> @} - $:GPU_DECLARE(create='[dir_idx, dir_flg, dir_idx_tau]') + $:GPU_DECLARE(create='[dir_idx,dir_flg,dir_idx_tau]') + + integer :: buff_size !< + !! The number of cells that are necessary to be able to store enough boundary + !! conditions data to march the solution in the physical computational domain + !! to the next time-step. - integer :: buff_size !< Number of ghost cells for boundary condition storage $:GPU_DECLARE(create='[buff_size]') - integer :: shear_num !< Number of shear stress components - integer, dimension(3) :: shear_indices !< Indices of the stress components that represent shear stress - integer :: shear_BC_flip_num !< Number of shear stress components to reflect for boundary conditions - integer, dimension(3, 2) :: shear_BC_flip_indices !< Shear stress BC reflection indices (1:3, 1:shear_BC_flip_num) - $:GPU_DECLARE(create='[shear_num, shear_indices, shear_BC_flip_num, shear_BC_flip_indices]') + integer :: shear_num !! Number of shear stress components + integer, dimension(3) :: shear_indices !< + !! Indices of the stress components that represent shear stress + integer :: shear_BC_flip_num !< + !! Number of shear stress components to reflect for boundary conditions + integer, dimension(3, 2) :: shear_BC_flip_indices !< + !! Indices of shear stress components to reflect for boundary conditions. + !! Size: (1:3, 1:shear_BC_flip_num) for (x/y/z, [indices]) + + $:GPU_DECLARE(create='[shear_num,shear_indices,shear_BC_flip_num,shear_BC_flip_indices]') ! END: Simulation Algorithm Parameters ! Fluids Physical Parameters - type(physical_parameters), dimension(num_fluids_max) :: fluid_pp !< Stiffened gas EOS parameters and Reynolds numbers per fluid + type(physical_parameters), dimension(num_fluids_max) :: fluid_pp !< + !! Database of the physical parameters of each of the fluids that is present + !! in the flow. These include the stiffened gas equation of state parameters, + !! and the Reynolds numbers. + ! Subgrid Bubble Parameters type(subgrid_bubble_physical_parameters) :: bub_pp - integer :: fd_order !< Finite-difference order for CoM and flow probe derivatives - integer :: fd_number !< Finite-difference half-stencil size: MAX(1, fd_order/2) - $:GPU_DECLARE(create='[fd_order, fd_number]') - - logical :: probe_wrt - logical :: integral_wrt - integer :: num_probes - integer :: num_integrals - type(vec3_dt), dimension(num_probes_max) :: probe + + integer :: fd_order !< + !! The order of the finite-difference (fd) approximations of the first-order + !! derivatives that need to be evaluated when the CoM or flow probe data + !! files are to be written at each time step + + integer :: fd_number !< + !! The finite-difference number is given by MAX(1, fd_order/2). Essentially, + !! it is a measure of the half-size of the finite-difference stencil for the + !! selected order of accuracy. + $:GPU_DECLARE(create='[fd_order,fd_number]') + + logical :: probe_wrt + logical :: integral_wrt + integer :: num_probes + integer :: num_integrals + type(vec3_dt), dimension(num_probes_max) :: probe type(integral_parameters), dimension(num_probes_max) :: integral !> @name Reference density and pressure for Tait EOS !> @{ real(wp) :: rhoref, pref !> @} - $:GPU_DECLARE(create='[rhoref, pref]') + $:GPU_DECLARE(create='[rhoref,pref]') !> @name Immersed Boundaries !> @{ - logical :: ib - integer :: num_ibs - logical :: ib_state_wrt - type(ib_patch_parameters), dimension(num_patches_max) :: patch_ib !< Immersed boundary patch parameters - type(vec3_dt), allocatable, dimension(:) :: airfoil_grid_u, airfoil_grid_l - integer :: Np - - $:GPU_DECLARE(create='[ib, num_ibs, patch_ib, Np, airfoil_grid_u, airfoil_grid_l]') + logical :: ib + integer :: num_ibs + logical :: ib_state_wrt + + type(ib_patch_parameters), dimension(num_patches_max) :: patch_ib + type(vec3_dt), allocatable, dimension(:) :: airfoil_grid_u, airfoil_grid_l + integer :: Np + !! Database of the immersed boundary patch parameters for each of the + !! patches employed in the configuration of the initial condition. Note that + !! the maximum allowable number of patches, num_patches_max, may be changed + !! in the module m_derived_types.f90. + + $:GPU_DECLARE(create='[ib,num_ibs,patch_ib,Np,airfoil_grid_u,airfoil_grid_l]') !> @} !> @name Bubble modeling !> @{ #:if MFC_CASE_OPTIMIZATION - integer, parameter :: nb = ${nb}$ !< Number of eq. bubble sizes + integer, parameter :: nb = ${nb}$ !< Number of eq. bubble sizes #:else - integer :: nb !< Number of eq. bubble sizes + integer :: nb !< Number of eq. bubble sizes #:endif - real(wp) :: Eu !< Euler number - real(wp) :: Ca !< Cavitation number - real(wp) :: Web !< Weber number - real(wp) :: Re_inv !< Inverse Reynolds number - $:GPU_DECLARE(create='[Eu, Ca, Web, Re_inv]') - - real(wp), dimension(:), allocatable :: weight !< Simpson quadrature weights - real(wp), dimension(:), allocatable :: R0 !< Bubble sizes - $:GPU_DECLARE(create='[weight, R0]') - - logical :: bubbles_euler !< Bubbles euler on/off - logical :: polytropic !< Polytropic switch - logical :: polydisperse !< Polydisperse bubbles - $:GPU_DECLARE(create='[bubbles_euler, polytropic, polydisperse]') - - logical :: adv_n !< Solve the number density equation and compute alpha from number density - logical :: adap_dt !< Adaptive step size control - real(wp) :: adap_dt_tol !< Tolerance to control adaptive step size - integer :: adap_dt_max_iters !< Maximum number of iterations - $:GPU_DECLARE(create='[adv_n, adap_dt, adap_dt_tol, adap_dt_max_iters]') - - integer :: bubble_model !< Gilmore or Keller--Miksis bubble model - integer :: thermal !< Thermal behavior. 1 = adiabatic, 2 = isotherm, 3 = transfer - $:GPU_DECLARE(create='[bubble_model, thermal]') - - real(wp), allocatable, dimension(:,:,:) :: ptil !< Pressure modification - real(wp) :: poly_sigma !< log normal sigma for polydisperse PDF + real(wp) :: Eu !< Euler number + real(wp) :: Ca !< Cavitation number + real(wp) :: Web !< Weber number + real(wp) :: Re_inv !< Inverse Reynolds number + $:GPU_DECLARE(create='[Eu,Ca,Web,Re_inv]') + + real(wp), dimension(:), allocatable :: weight !< Simpson quadrature weights + real(wp), dimension(:), allocatable :: R0 !< Bubble sizes + $:GPU_DECLARE(create='[weight,R0]') + + logical :: bubbles_euler !< Bubbles euler on/off + logical :: polytropic !< Polytropic switch + logical :: polydisperse !< Polydisperse bubbles + $:GPU_DECLARE(create='[bubbles_euler,polytropic,polydisperse]') + + logical :: adv_n !< Solve the number density equation and compute alpha from number density + logical :: adap_dt !< Adaptive step size control + real(wp) :: adap_dt_tol !< Tolerance to control adaptive step size + integer :: adap_dt_max_iters !< Maximum number of iterations + $:GPU_DECLARE(create='[adv_n,adap_dt,adap_dt_tol,adap_dt_max_iters]') + + integer :: bubble_model !< Gilmore or Keller--Miksis bubble model + integer :: thermal !< Thermal behavior. 1 = adiabatic, 2 = isotherm, 3 = transfer + $:GPU_DECLARE(create='[bubble_model,thermal]') + + real(wp), allocatable, dimension(:, :, :) :: ptil !< Pressure modification + + real(wp) :: poly_sigma !< log normal sigma for polydisperse PDF $:GPU_DECLARE(create='[ptil, poly_sigma]') - logical :: qbmm !< Quadrature moment method - integer, parameter :: nmom = 6 !< Number of carried moments per R0 location - integer :: nmomsp !< Number of moments required by ensemble-averaging - integer :: nmomtot !< Total number of carried moments moments/transport equations - real(wp) :: pi_fac !< Factor for artificial pi_inf - $:GPU_DECLARE(create='[qbmm, nmomsp, nmomtot, pi_fac]') + logical :: qbmm !< Quadrature moment method + integer, parameter :: nmom = 6 !< Number of carried moments per R0 location + integer :: nmomsp !< Number of moments required by ensemble-averaging + integer :: nmomtot !< Total number of carried moments moments/transport equations + + real(wp) :: pi_fac !< Factor for artificial pi_inf + $:GPU_DECLARE(create='[qbmm, nmomsp,nmomtot,pi_fac]') #:if not MFC_CASE_OPTIMIZATION $:GPU_DECLARE(create='[nb]') #:endif - type(scalar_field), allocatable, dimension(:) :: mom_sp - type(scalar_field), allocatable, dimension(:,:,:) :: mom_3d - $:GPU_DECLARE(create='[mom_sp, mom_3d]') + type(scalar_field), allocatable, dimension(:) :: mom_sp + type(scalar_field), allocatable, dimension(:, :, :) :: mom_3d + $:GPU_DECLARE(create='[mom_sp,mom_3d]') + !> @} type(chemistry_parameters) :: chem_params @@ -415,33 +475,36 @@ module m_global_parameters !> @name Physical bubble parameters (see Ando 2010, Preston 2007) !> @{ real(wp) :: phi_vg, phi_gv, Pe_c, Tw, k_vl, k_gl - $:GPU_DECLARE(create='[phi_vg, phi_gv, Pe_c, Tw, k_vl, k_gl]') + $:GPU_DECLARE(create='[phi_vg,phi_gv,Pe_c,Tw,k_vl,k_gl]') real(wp), dimension(:), allocatable :: pb0, mass_g0, mass_v0, Pe_T, k_v, k_g real(wp), dimension(:), allocatable :: Re_trans_T, Re_trans_c, Im_trans_T, Im_trans_c, omegaN - $:GPU_DECLARE(create='[pb0, mass_g0, mass_v0, Pe_T, k_v, k_g]') - $:GPU_DECLARE(create='[Re_trans_T, Re_trans_c, Im_trans_T, Im_trans_c, omegaN]') + $:GPU_DECLARE(create='[pb0,mass_g0,mass_v0,Pe_T,k_v,k_g]') + $:GPU_DECLARE(create='[Re_trans_T,Re_trans_c,Im_trans_T,Im_trans_c,omegaN]') real(wp) :: gam, gam_m - $:GPU_DECLARE(create='[gam, gam_m]') + $:GPU_DECLARE(create='[gam,gam_m]') - real(wp) :: R0ref, p0ref, rho0ref, T0ref, ss, pv, vd, mu_l, mu_v, mu_g, gam_v, gam_g, M_v, M_g, cp_v, cp_g, R_v, R_g - $:GPU_DECLARE(create='[R0ref, p0ref, rho0ref, T0ref, ss, pv, vd, mu_l, mu_v, mu_g, gam_v, gam_g, M_v, M_g, cp_v, cp_g, R_v, R_g]') + real(wp) :: R0ref, p0ref, rho0ref, T0ref, ss, pv, vd, mu_l, mu_v, mu_g, & + gam_v, gam_g, M_v, M_g, cp_v, cp_g, R_v, R_g + $:GPU_DECLARE(create='[R0ref, p0ref, rho0ref, T0ref, ss, pv, vd, mu_l, mu_v, mu_g, & + gam_v, gam_g, M_v, M_g, cp_v, cp_g, R_v, R_g]') !> @} !> @name Acoustic acoustic_source parameters !> @{ - logical :: acoustic_source !< Acoustic source switch - type(acoustic_parameters), dimension(num_probes_max) :: acoustic !< Acoustic source parameters - integer :: num_source !< Number of acoustic sources + logical :: acoustic_source !< Acoustic source switch + type(acoustic_parameters), dimension(num_probes_max) :: acoustic !< Acoustic source parameters + integer :: num_source !< Number of acoustic sources !> @} - $:GPU_DECLARE(create='[acoustic_source, acoustic, num_source]') + $:GPU_DECLARE(create='[acoustic_source,acoustic,num_source]') !> @name Surface tension parameters !> @{ + real(wp) :: sigma - logical :: surface_tension - $:GPU_DECLARE(create='[sigma, surface_tension]') + logical :: surface_tension + $:GPU_DECLARE(create='[sigma,surface_tension]') !> @} integer :: momxb, momxe @@ -452,58 +515,70 @@ module m_global_parameters integer :: strxb, strxe integer :: chemxb, chemxe integer :: xibeg, xiend - $:GPU_DECLARE(create='[momxb, momxe, advxb, advxe, contxb, contxe]') - $:GPU_DECLARE(create='[intxb, intxe, bubxb, bubxe]') - $:GPU_DECLARE(create='[strxb, strxe, chemxb, chemxe]') - $:GPU_DECLARE(create='[xibeg, xiend]') + $:GPU_DECLARE(create='[momxb,momxe,advxb,advxe,contxb,contxe]') + $:GPU_DECLARE(create='[intxb,intxe, bubxb,bubxe]') + $:GPU_DECLARE(create='[strxb,strxe,chemxb,chemxe]') + $:GPU_DECLARE(create='[xibeg,xiend]') real(wp), allocatable, dimension(:) :: gammas, gs_min, pi_infs, ps_inf, cvs, qvs, qvps - $:GPU_DECLARE(create='[gammas, gs_min, pi_infs, ps_inf, cvs, qvs, qvps]') + $:GPU_DECLARE(create='[gammas,gs_min,pi_infs,ps_inf,cvs,qvs,qvps]') + + real(wp) :: mytime !< Current simulation time + real(wp) :: finaltime !< Final simulation time + + logical :: rdma_mpi - real(wp) :: mytime !< Current simulation time - real(wp) :: finaltime !< Final simulation time - logical :: rdma_mpi type(pres_field), allocatable, dimension(:) :: pb_ts + type(pres_field), allocatable, dimension(:) :: mv_ts - $:GPU_DECLARE(create='[pb_ts, mv_ts]') + $:GPU_DECLARE(create='[pb_ts,mv_ts]') !> @name lagrangian subgrid bubble parameters !> @{! - logical :: bubbles_lagrange !< Lagrangian subgrid bubble model switch - type(bubbles_lagrange_parameters) :: lag_params !< Lagrange bubbles' parameters - $:GPU_DECLARE(create='[bubbles_lagrange, lag_params]') + logical :: bubbles_lagrange !< Lagrangian subgrid bubble model switch + type(bubbles_lagrange_parameters) :: lag_params !< Lagrange bubbles' parameters + integer :: n_el_bubs_loc, n_el_bubs_glb !< Number of Lagrangian bubbles (local and global) + logical :: moving_lag_bubbles + logical :: lag_pressure_force + logical :: lag_gravity_force + integer :: lag_vel_model, lag_drag_model + $:GPU_DECLARE(create='[bubbles_lagrange,lag_params,n_el_bubs_loc,n_el_bubs_glb]') + $:GPU_DECLARE(create='[moving_lag_bubbles, lag_vel_model, lag_drag_model]') + $:GPU_DECLARE(create='[lag_pressure_force,lag_gravity_force]') !> @} - real(wp) :: Bx0 !< Constant magnetic field in the x-direction (1D) + real(wp) :: Bx0 !< Constant magnetic field in the x-direction (1D) $:GPU_DECLARE(create='[Bx0]') logical :: fft_wrt - logical :: dummy !< AMDFlang workaround for case-optimization + GPU-kernel bug + logical :: dummy !< AMDFlang workaround: keep a dummy logical to avoid a compiler case-optimization bug when a parameter+GPU-kernel conditional is false + !> @name Continuum damage model parameters !> @{! - real(wp) :: tau_star !< Stress threshold for continuum damage modeling - real(wp) :: cont_damage_s !< Exponent s for continuum damage modeling - real(wp) :: alpha_bar !< Damage rate factor for continuum damage modeling - $:GPU_DECLARE(create='[tau_star, cont_damage_s, alpha_bar]') + real(wp) :: tau_star !< Stress threshold for continuum damage modeling + real(wp) :: cont_damage_s !< Exponent s for continuum damage modeling + real(wp) :: alpha_bar !< Damage rate factor for continuum damage modeling + $:GPU_DECLARE(create='[tau_star,cont_damage_s,alpha_bar]') !> @} !> @name MHD Hyperbolic cleaning parameters !> @{! - real(wp) :: hyper_cleaning_speed !< Hyperbolic cleaning wave speed (c_h) - real(wp) :: hyper_cleaning_tau !< Hyperbolic cleaning tau + real(wp) :: hyper_cleaning_speed !< Hyperbolic cleaning wave speed (c_h) + real(wp) :: hyper_cleaning_tau !< Hyperbolic cleaning tau $:GPU_DECLARE(create='[hyper_cleaning_speed, hyper_cleaning_tau]') !> @} contains - !> Assigns default values to the user inputs before reading them in. This enables for an easier consistency check of these - !! parameters once they are read from the input file. + !> Assigns default values to the user inputs before reading + !! them in. This enables for an easier consistency check of + !! these parameters once they are read from the input file. impure subroutine s_assign_default_values_to_user_inputs - integer :: i, j !< Generic loop iterator - ! Logistics + integer :: i, j !< Generic loop iterator + ! Logistics case_dir = '.' run_time_info = .false. t_step_old = dflt_int @@ -532,7 +607,7 @@ contains ! NVIDIA UVM options nv_uvm_out_of_core = .false. - nv_uvm_igr_temps_on_gpu = 3 ! => jac, jac_rhs, and jac_old on GPU (default) + nv_uvm_igr_temps_on_gpu = 3 ! => jac, jac_rhs, and jac_old on GPU (default) nv_uvm_pref_gpu = .false. ! Simulation algorithm parameters @@ -596,6 +671,7 @@ contains num_bc_patches = 0 bc_io = .false. + periodic_bc = .false. bc_x%beg = dflt_int; bc_x%end = dflt_int bc_y%beg = dflt_int; bc_y%end = dflt_int @@ -608,9 +684,9 @@ contains #:endfor #:endfor - x_domain%beg = dflt_real; x_domain%end = dflt_real - y_domain%beg = dflt_real; y_domain%end = dflt_real - z_domain%beg = dflt_real; z_domain%end = dflt_real + glb_bounds(1)%beg = dflt_real; glb_bounds(1)%end = dflt_real + glb_bounds(2)%beg = dflt_real; glb_bounds(2)%end = dflt_real + glb_bounds(3)%beg = dflt_real; glb_bounds(3)%end = dflt_real ! Fluids physical parameters do i = 1, num_fluids_max @@ -638,8 +714,8 @@ contains bub_pp%gam_g = dflt_real; gam_g = dflt_real bub_pp%M_v = dflt_real; M_v = dflt_real bub_pp%M_g = dflt_real; M_g = dflt_real - bub_pp%k_v = dflt_real - bub_pp%k_g = dflt_real + bub_pp%k_v = dflt_real; + bub_pp%k_g = dflt_real; bub_pp%cp_v = dflt_real; cp_v = dflt_real bub_pp%cp_g = dflt_real; cp_g = dflt_real bub_pp%R_v = dflt_real; R_v = dflt_real @@ -697,7 +773,7 @@ contains bodyForces = .false. bf_x = .false.; bf_y = .false.; bf_z = .false. - !> amplitude, frequency, and phase shift sinusoid in each direction + !< amplitude, frequency, and phase shift sinusoid in each direction #:for dir in {'x', 'y', 'z'} #:for param in {'k','w','p','g'} ${param}$_${dir}$ = dflt_real @@ -774,10 +850,19 @@ contains lag_params%massTransfer_model = .false. lag_params%write_bubbles = .false. lag_params%write_bubbles_stats = .false. + lag_params%write_void_evol = .false. lag_params%nBubs_glb = dflt_int + lag_params%vel_model = dflt_int + lag_params%drag_model = dflt_int + lag_params%pressure_force = .true. + lag_params%gravity_force = .false. lag_params%epsilonb = 1._wp lag_params%charwidth = dflt_real + lag_params%charNz = dflt_int lag_params%valmaxvoid = dflt_real + lag_params%input_path = 'input/lag_bubbles.dat' + moving_lag_bubbles = .false. + lag_vel_model = dflt_int ! Continuum damage model tau_star = dflt_real @@ -837,7 +922,9 @@ contains end subroutine s_assign_default_values_to_user_inputs - !> Initialize the global parameters module + !> The computation of parameters, the allocation of memory, + !! the association of pointers and/or the execution of any + !! other procedures that are necessary to setup the module. impure subroutine s_initialize_global_parameters_module integer :: i, j, k @@ -845,7 +932,6 @@ contains #:if not MFC_CASE_OPTIMIZATION ! Determining the degree of the WENO polynomials - if (recon_type == WENO_TYPE) then weno_polyn = (weno_order - 1)/2 if (teno) then @@ -853,24 +939,30 @@ contains else weno_num_stencils = weno_polyn end if - else if (recon_type == MUSCL_TYPE) then + elseif (recon_type == MUSCL_TYPE) then muscl_polyn = muscl_order end if $:GPU_UPDATE(device='[weno_polyn, muscl_polyn]') $:GPU_UPDATE(device='[weno_num_stencils]') $:GPU_UPDATE(device='[nb]') - $:GPU_UPDATE(device='[num_dims, num_vels, num_fluids]') - $:GPU_UPDATE(device='[igr, igr_order, igr_iter_solver]') + $:GPU_UPDATE(device='[num_dims,num_vels,num_fluids]') + $:GPU_UPDATE(device='[igr,igr_order,igr_iter_solver]') #:endif - ! Initialize counts: viscous fluids, surface-tension interfaces, curvature interfaces + ! Initializing the number of fluids for which viscous effects will + ! be non-negligible, the number of distinctive material interfaces + ! for which surface tension will be important and also, the number + ! of fluids for which the physical and geometric curvatures of the + ! interfaces will be computed Re_size = 0 Re_size_max = 0 ! Gamma/Pi_inf Model if (model_eqns == 1) then - ! Annotating structure of the state and flux vectors belonging to the system of equations defined by the selected number - ! of spatial dimensions and the gamma/pi_inf model + + ! Annotating structure of the state and flux vectors belonging + ! to the system of equations defined by the selected number of + ! spatial dimensions and the gamma/pi_inf model cont_idx%beg = 1 cont_idx%end = cont_idx%beg mom_idx%beg = cont_idx%end + 1 @@ -884,8 +976,10 @@ contains ! Volume Fraction Model else - ! Annotating structure of the state and flux vectors belonging to the system of equations defined by the selected number - ! of spatial dimensions and the volume fraction model + + ! Annotating structure of the state and flux vectors belonging + ! to the system of equations defined by the selected number of + ! spatial dimensions and the volume fraction model if (model_eqns == 2) then cont_idx%beg = 1 cont_idx%end = num_fluids @@ -894,12 +988,17 @@ contains E_idx = mom_idx%end + 1 if (igr) then - ! IGR: volume fractions after energy (N-1 for N fluids; skipped when num_fluids=1) - adv_idx%beg = E_idx + 1 ! Alpha for fluid 1 + ! Volume fractions are stored in the indices immediately following + ! the energy equation. IGR tracks a total of (N-1) volume fractions + ! for N fluids, hence the "-1" in adv_idx%end. If num_fluids = 1 + ! then adv_idx%end < adv_idx%beg, which skips all loops over the + ! volume fractions since there is no volume fraction to track + adv_idx%beg = E_idx + 1 ! Alpha for fluid 1 adv_idx%end = E_idx + num_fluids - 1 else - ! Volume fractions are stored in the indices immediately following the energy equation. WENO/MUSCL + Riemann - ! tracks a total of (N) volume fractions for N fluids, hence the lack of "-1" in adv_idx%end + ! Volume fractions are stored in the indices immediately following + ! the energy equation. WENO/MUSCL + Riemann tracks a total of (N) + ! volume fractions for N fluids, hence the lack of "-1" in adv_idx%end adv_idx%beg = E_idx + 1 adv_idx%end = E_idx + num_fluids end if @@ -915,7 +1014,7 @@ contains if (bubbles_euler) then bub_idx%beg = sys_size + 1 if (qbmm) then - nmomsp = 4 ! number of special moments + nmomsp = 4 !number of special moments if (nnode == 4) then ! nmom = 6 : It is already a parameter nmomtot = nmom*nb @@ -949,6 +1048,7 @@ contains bub_idx%rs(i) = bub_idx%moms(i, 2) bub_idx%vs(i) = bub_idx%moms(i, 3) end do + else do i = 1, nb if (.not. polytropic) then @@ -971,12 +1071,13 @@ contains if (mhd) then B_idx%beg = sys_size + 1 if (n == 0) then - B_idx%end = sys_size + 2 ! 1D: By, Bz + B_idx%end = sys_size + 2 ! 1D: By, Bz else - B_idx%end = sys_size + 3 ! 2D/3D: Bx, By, Bz + B_idx%end = sys_size + 3 ! 2D/3D: Bx, By, Bz end if sys_size = B_idx%end end if + else if (model_eqns == 3) then cont_idx%beg = 1 cont_idx%end = num_fluids @@ -989,14 +1090,15 @@ contains internalEnergies_idx%beg = adv_idx%end + 1 internalEnergies_idx%end = adv_idx%end + num_fluids sys_size = internalEnergies_idx%end + else if (model_eqns == 4) then - cont_idx%beg = 1 ! one continuity equation - cont_idx%end = 1 ! num_fluids - mom_idx%beg = cont_idx%end + 1 ! one momentum equation in each direction + cont_idx%beg = 1 ! one continuity equation + cont_idx%end = 1 !num_fluids + mom_idx%beg = cont_idx%end + 1 ! one momentum equation in each direction mom_idx%end = cont_idx%end + num_vels - E_idx = mom_idx%end + 1 ! one energy equation + E_idx = mom_idx%end + 1 ! one energy equation adv_idx%beg = E_idx + 1 - adv_idx%end = adv_idx%beg ! one volume advection equation + adv_idx%end = adv_idx%beg !one volume advection equation alf_idx = adv_idx%end sys_size = adv_idx%end @@ -1029,7 +1131,8 @@ contains end if end if - ! Count fluids with non-negligible viscous effects (Re > 0) + ! Determining the number of fluids for which the shear and the + ! volume Reynolds numbers, e.g. viscous effects, are important do i = 1, num_fluids if (fluid_pp(i)%Re(1) > 0) Re_size(1) = Re_size(1) + 1 if (fluid_pp(i)%Re(2) > 0) Re_size(2) = Re_size(2) + 1 @@ -1040,11 +1143,12 @@ contains Re_size_max = maxval(Re_size) - $:GPU_UPDATE(device='[Re_size, Re_size_max, shear_stress, bulk_stress]') + $:GPU_UPDATE(device='[Re_size,Re_size_max,shear_stress,bulk_stress]') - ! Bookkeeping the indexes of any viscous fluids and any pairs of fluids whose interface will support effects of surface - ! tension + ! Bookkeeping the indexes of any viscous fluids and any pairs of + ! fluids whose interface will support effects of surface tension if (viscous) then + @:ALLOCATE(Re_idx(1:2, 1:Re_size_max)) k = 0 @@ -1060,10 +1164,13 @@ contains k = k + 1; Re_idx(2, k) = i end if end do + end if + end if if (model_eqns == 2 .or. model_eqns == 3) then + if (hypoelasticity .or. hyperelasticity) then elasticity = .true. stress_idx%beg = sys_size + 1 @@ -1079,18 +1186,20 @@ contains shear_num = 1 shear_indices(1) = stress_idx%beg - 1 + 2 shear_BC_flip_num = 1 - shear_BC_flip_indices(1:2,1) = shear_indices(1) + shear_BC_flip_indices(1:2, 1) = shear_indices(1) ! Both x-dir and y-dir: flip tau_xy only else if (num_dims == 3) then shear_num = 3 shear_indices(1:3) = stress_idx%beg - 1 + (/2, 4, 5/) shear_BC_flip_num = 2 - shear_BC_flip_indices(1,1:2) = shear_indices((/1, 2/)) - shear_BC_flip_indices(2,1:2) = shear_indices((/1, 3/)) - shear_BC_flip_indices(3,1:2) = shear_indices((/2, 3/)) - ! x-dir: flip tau_xy and tau_xz y-dir: flip tau_xy and tau_yz z-dir: flip tau_xz and tau_yz + shear_BC_flip_indices(1, 1:2) = shear_indices((/1, 2/)) + shear_BC_flip_indices(2, 1:2) = shear_indices((/1, 3/)) + shear_BC_flip_indices(3, 1:2) = shear_indices((/2, 3/)) + ! x-dir: flip tau_xy and tau_xz + ! y-dir: flip tau_xy and tau_yz + ! z-dir: flip tau_xz and tau_yz end if - $:GPU_UPDATE(device='[shear_num, shear_indices, shear_BC_flip_num, shear_BC_flip_indices]') + $:GPU_UPDATE(device='[shear_num,shear_indices,shear_BC_flip_num,shear_BC_flip_indices]') end if if (hyperelasticity) then @@ -1118,6 +1227,7 @@ contains psi_idx = sys_size + 1 sys_size = psi_idx end if + end if ! END: Volume Fraction Model @@ -1131,7 +1241,7 @@ contains if (bubbles_euler .and. qbmm .and. .not. polytropic) then allocate (MPI_IO_DATA%view(1:sys_size + 2*nb*nnode)) allocate (MPI_IO_DATA%var(1:sys_size + 2*nb*nnode)) - else if (bubbles_lagrange) then + elseif (bubbles_lagrange) then allocate (MPI_IO_DATA%view(1:sys_size + 1)) allocate (MPI_IO_DATA%var(1:sys_size + 1)) else @@ -1141,23 +1251,27 @@ contains if (.not. down_sample) then do i = 1, sys_size - allocate (MPI_IO_DATA%var(i)%sf(0:m,0:n,0:p)) + allocate (MPI_IO_DATA%var(i)%sf(0:m, 0:n, 0:p)) MPI_IO_DATA%var(i)%sf => null() end do end if if (bubbles_euler .and. qbmm .and. .not. polytropic) then do i = sys_size + 1, sys_size + 2*nb*nnode - allocate (MPI_IO_DATA%var(i)%sf(0:m,0:n,0:p)) + allocate (MPI_IO_DATA%var(i)%sf(0:m, 0:n, 0:p)) MPI_IO_DATA%var(i)%sf => null() end do - else if (bubbles_lagrange) then + elseif (bubbles_lagrange) then do i = 1, sys_size + 1 - allocate (MPI_IO_DATA%var(i)%sf(0:m,0:n,0:p)) + allocate (MPI_IO_DATA%var(i)%sf(0:m, 0:n, 0:p)) MPI_IO_DATA%var(i)%sf => null() end do end if - ! Configure WENO averaging flag (arithmetic mean vs. unaltered values) + ! Configuring the WENO average flag that will be used to regulate + ! whether any spatial derivatives are to computed in each cell by + ! using the arithmetic mean of left and right, WENO-reconstructed, + ! cell-boundary values or otherwise, the unaltered left and right, + ! WENO-reconstructed, cell-boundary values wa_flg = 0._wp; if (weno_avg) wa_flg = 1._wp $:GPU_UPDATE(device='[wa_flg]') @@ -1166,37 +1280,38 @@ contains wenojs = .not. (mapped_weno .or. wenoz .or. teno) #:endif - if (ib) allocate (MPI_IO_IB_DATA%var%sf(0:m,0:n,0:p)) + if (ib) allocate (MPI_IO_IB_DATA%var%sf(0:m, 0:n, 0:p)) Np = 0 - if (elasticity) then + if (elasticity) fd_number = max(1, fd_order/2) + if (mhd) then ! TODO merge with above; waiting for hyperelasticity PR fd_number = max(1, fd_order/2) end if - - if (mhd) then ! TODO merge with above; waiting for hyperelasticity PR - fd_number = max(1, fd_order/2) - end if - - if (probe_wrt) then - fd_number = max(1, fd_order/2) - end if - - call s_configure_coordinate_bounds(recon_type, weno_polyn, muscl_polyn, igr_order, buff_size, idwint, idwbuff, viscous, & - & bubbles_lagrange, m, n, p, num_dims, igr, ib) + if (probe_wrt) fd_number = max(1, fd_order/2) + if (bubbles_lagrange) fd_number = max(1, fd_order/2) + + call s_configure_coordinate_bounds(recon_type, weno_polyn, muscl_polyn, & + igr_order, buff_size, & + idwint, idwbuff, viscous, & + bubbles_lagrange, m, n, p, & + num_dims, igr, ib, fd_number) $:GPU_UPDATE(device='[idwint, idwbuff]') ! Configuring Coordinate Direction Indexes if (bubbles_euler) then - @:ALLOCATE(ptil( idwbuff(1)%beg:idwbuff(1)%end, idwbuff(2)%beg:idwbuff(2)%end, idwbuff(3)%beg:idwbuff(3)%end)) + @:ALLOCATE(ptil(& + & idwbuff(1)%beg:idwbuff(1)%end, & + & idwbuff(2)%beg:idwbuff(2)%end, & + & idwbuff(3)%beg:idwbuff(3)%end)) end if $:GPU_UPDATE(device='[fd_order, fd_number]') - if (cyl_coord .neqv. .true.) then ! Cartesian grid + if (cyl_coord .neqv. .true.) then ! Cartesian grid grid_geometry = 1 - else if (cyl_coord .and. p == 0) then ! Axisymmetric cylindrical grid + elseif (cyl_coord .and. p == 0) then ! Axisymmetric cylindrical grid grid_geometry = 2 - else ! Fully 3D cylindrical grid + else ! Fully 3D cylindrical grid grid_geometry = 3 end if @@ -1217,39 +1332,44 @@ contains chemxb = species_idx%beg chemxe = species_idx%end - $:GPU_UPDATE(device='[momxb, momxe, advxb, advxe, contxb, contxe, bubxb, bubxe, intxb, intxe, sys_size, buff_size, E_idx, & - & alf_idx, n_idx, adv_n, adap_dt, pi_fac, strxb, strxe, chemxb, chemxe, c_idx, adap_dt_tol, & - & adap_dt_max_iters]') - $:GPU_UPDATE(device='[b_size, xibeg, xiend, tensor_size]') + $:GPU_UPDATE(device='[momxb,momxe,advxb,advxe,contxb,contxe, & + & bubxb,bubxe,intxb,intxe,sys_size,buff_size,E_idx, & + & alf_idx,n_idx,adv_n,adap_dt,pi_fac,strxb,strxe, & + & chemxb,chemxe,c_idx,adap_dt_tol,adap_dt_max_iters]') + $:GPU_UPDATE(device='[b_size,xibeg,xiend,tensor_size]') $:GPU_UPDATE(device='[species_idx]') - $:GPU_UPDATE(device='[cfl_target, m, n, p]') + $:GPU_UPDATE(device='[cfl_target,m,n,p]') - $:GPU_UPDATE(device='[alt_soundspeed, acoustic_source, num_source]') - $:GPU_UPDATE(device='[dt, sys_size, buff_size, pref, rhoref, gamma_idx, pi_inf_idx, E_idx, alf_idx, stress_idx, mpp_lim, & - & bubbles_euler, hypoelasticity, alt_soundspeed, avg_state, model_eqns, mixture_err, grid_geometry, & - & cyl_coord, mp_weno, weno_eps, teno_CT, hyperelasticity, hyper_model, elasticity, xi_idx, B_idx, low_Mach]') + $:GPU_UPDATE(device='[alt_soundspeed,acoustic_source,num_source]') + $:GPU_UPDATE(device='[dt,sys_size,buff_size,pref,rhoref, & + & gamma_idx,pi_inf_idx,E_idx,alf_idx,stress_idx, & + & mpp_lim,bubbles_euler,hypoelasticity,alt_soundspeed, & + & avg_state,model_eqns, & + & mixture_err,grid_geometry,cyl_coord,mp_weno,weno_eps, & + & teno_CT,hyperelasticity,hyper_model,elasticity,xi_idx, & + & B_idx,low_Mach]') $:GPU_UPDATE(device='[Bx0]') $:GPU_UPDATE(device='[chem_params]') - $:GPU_UPDATE(device='[cont_damage, tau_star, cont_damage_s, alpha_bar]') + $:GPU_UPDATE(device='[cont_damage,tau_star,cont_damage_s,alpha_bar]') $:GPU_UPDATE(device='[hyper_cleaning, hyper_cleaning_speed, hyper_cleaning_tau]') #:if not MFC_CASE_OPTIMIZATION - $:GPU_UPDATE(device='[wenojs, mapped_weno, wenoz, teno]') + $:GPU_UPDATE(device='[wenojs,mapped_weno,wenoz,teno]') $:GPU_UPDATE(device='[wenoz_q]') $:GPU_UPDATE(device='[mhd, relativity]') $:GPU_UPDATE(device='[muscl_order, muscl_lim]') $:GPU_UPDATE(device='[igr, igr_order]') - $:GPU_UPDATE(device='[num_fluids, num_dims, viscous, num_vels, nb, muscl_lim]') + $:GPU_UPDATE(device='[num_fluids,num_dims,viscous,num_vels,nb,muscl_lim]') #:endif - $:GPU_UPDATE(device='[dir_idx, dir_flg, dir_idx_tau]') + $:GPU_UPDATE(device='[dir_idx,dir_flg,dir_idx_tau]') - $:GPU_UPDATE(device='[relax, relax_model, palpha_eps, ptgalpha_eps]') + $:GPU_UPDATE(device='[relax,relax_model,palpha_eps,ptgalpha_eps]') ! Allocating grid variables for the x-, y- and z-directions @:ALLOCATE(x_cb(-1 - buff_size:m + buff_size)) @@ -1259,7 +1379,7 @@ contains @:PREFER_GPU(x_cc) @:PREFER_GPU(dx) - if (n == 0) return + if (n == 0) return; @:ALLOCATE(y_cb(-1 - buff_size:n + buff_size)) @:ALLOCATE(y_cc(-buff_size:n + buff_size)) @:ALLOCATE(dy(-buff_size:n + buff_size)) @@ -1267,7 +1387,7 @@ contains @:PREFER_GPU(y_cc) @:PREFER_GPU(dy) - if (p == 0) return + if (p == 0) return; @:ALLOCATE(z_cb(-1 - buff_size:p + buff_size)) @:ALLOCATE(z_cc(-buff_size:p + buff_size)) @:ALLOCATE(dz(-buff_size:p + buff_size)) @@ -1281,7 +1401,7 @@ contains impure subroutine s_initialize_parallel_io #ifdef MFC_MPI - integer :: ierr !< Generic flag used to identify and report MPI errors + integer :: ierr !< Generic flag used to identify and report MPI errors #endif #:if not MFC_CASE_OPTIMIZATION @@ -1296,9 +1416,12 @@ contains allocate (proc_coords(1:num_dims)) + @:ALLOCATE(pcomm_coords(1:num_dims)) + if (parallel_io .neqv. .true.) return #ifdef MFC_MPI + ! Option for Lustre file system (Darter/Comet/Stampede) write (mpiiofs, '(A)') '/lustre_' mpiiofs = trim(mpiiofs) @@ -1306,10 +1429,13 @@ contains call MPI_INFO_CREATE(mpi_info_int, ierr) call MPI_INFO_SET(mpi_info_int, 'romio_ds_write', 'disable', ierr) - ! Option for UNIX file system (Hooke/Thomson) WRITE(mpiiofs, '(A)') '/ufs_' mpiiofs = TRIM(mpiiofs) mpi_info_int = - ! MPI_INFO_NULL + ! Option for UNIX file system (Hooke/Thomson) + ! WRITE(mpiiofs, '(A)') '/ufs_' + ! mpiiofs = TRIM(mpiiofs) + ! mpi_info_int = MPI_INFO_NULL allocate (start_idx(1:num_dims)) + #endif end subroutine s_initialize_parallel_io @@ -1319,14 +1445,17 @@ contains integer :: i - ! Deallocating the variables bookkeeping the indexes of any viscous fluids and any pairs of fluids whose interfaces - ! supported effects of surface tension - + ! Deallocating the variables bookkeeping the indexes of any viscous + ! fluids and any pairs of fluids whose interfaces supported effects + ! of surface tension if (viscous) then @:DEALLOCATE(Re_idx) end if deallocate (proc_coords) + + @:DEALLOCATE(pcomm_coords) + if (parallel_io) then deallocate (start_idx) @@ -1349,12 +1478,16 @@ contains ! Deallocating grid variables for the x-, y- and z-directions @:DEALLOCATE(x_cb, x_cc, dx) - if (n == 0) return + if (n == 0) return; @:DEALLOCATE(y_cb, y_cc, dy) - if (p == 0) return + if (p == 0) return; @:DEALLOCATE(z_cb, z_cc, dz) + if (allocated(neighbor_ranks)) then + @:DEALLOCATE(neighbor_ranks) + end if + end subroutine s_finalize_global_parameters_module end module m_global_parameters diff --git a/src/simulation/m_hyperelastic.fpp b/src/simulation/m_hyperelastic.fpp index 22c2aace73..e687244280 100644 --- a/src/simulation/m_hyperelastic.fpp +++ b/src/simulation/m_hyperelastic.fpp @@ -8,33 +8,42 @@ module m_hyperelastic - use m_derived_types - use m_global_parameters - use m_variables_conversion + use m_derived_types !< Definitions of the derived types + + use m_global_parameters !< Definitions of the global parameters + + use m_variables_conversion !< State variables type conversion procedures + use m_finite_differences implicit none - private; public :: s_hyperelastic_rmt_stress_update, s_initialize_hyperelastic_module, s_finalize_hyperelastic_module + private; public :: s_hyperelastic_rmt_stress_update, & + s_initialize_hyperelastic_module, & + s_finalize_hyperelastic_module - ! The btensor at the cell-interior Gaussian quadrature points. These tensor is needed to be calculated once and make the code - ! DRY. - type(vector_field) :: btensor + !! The btensor at the cell-interior Gaussian quadrature points. + !! These tensor is needed to be calculated once and make the code DRY. + type(vector_field) :: btensor !< $:GPU_DECLARE(create='[btensor]') - real(wp), allocatable, dimension(:,:) :: fd_coeff_x_hyper - real(wp), allocatable, dimension(:,:) :: fd_coeff_y_hyper - real(wp), allocatable, dimension(:,:) :: fd_coeff_z_hyper - $:GPU_DECLARE(create='[fd_coeff_x_hyper, fd_coeff_y_hyper, fd_coeff_z_hyper]') + real(wp), allocatable, dimension(:, :) :: fd_coeff_x_hyper + real(wp), allocatable, dimension(:, :) :: fd_coeff_y_hyper + real(wp), allocatable, dimension(:, :) :: fd_coeff_z_hyper + $:GPU_DECLARE(create='[fd_coeff_x_hyper,fd_coeff_y_hyper, fd_coeff_z_hyper]') real(wp), allocatable, dimension(:) :: Gs_hyper $:GPU_DECLARE(create='[Gs_hyper]') contains - !> Initialize the hyperelastic module + !> The following subroutine handles the calculation of the btensor. + !! The calculation of the btensor takes qprimvf. + !! calculate the grad_xi, grad_xi is a nxn tensor + !! calculate the inverse of grad_xi to obtain F, F is a nxn tensor + !! calculate the FFtranspose to obtain the btensor, btensor is nxn tensor + !! btensor is symmetric, save the data space impure subroutine s_initialize_hyperelastic_module - - integer :: i !< generic iterator + integer :: i !< generic iterator @:ALLOCATE(btensor%vf(1:b_size)) do i = 1, b_size @@ -58,25 +67,34 @@ contains end if ! Computing centered finite difference coefficients - call s_compute_finite_difference_coefficients(m, x_cc, fd_coeff_x_hyper, buff_size, fd_number, fd_order) + call s_compute_finite_difference_coefficients(m, x_cc, fd_coeff_x_hyper, buff_size, & + fd_number, fd_order) $:GPU_UPDATE(device='[fd_coeff_x_hyper]') if (n > 0) then - call s_compute_finite_difference_coefficients(n, y_cc, fd_coeff_y_hyper, buff_size, fd_number, fd_order) + call s_compute_finite_difference_coefficients(n, y_cc, fd_coeff_y_hyper, buff_size, & + fd_number, fd_order) $:GPU_UPDATE(device='[fd_coeff_y_hyper]') end if if (p > 0) then - call s_compute_finite_difference_coefficients(p, z_cc, fd_coeff_z_hyper, buff_size, fd_number, fd_order) + call s_compute_finite_difference_coefficients(p, z_cc, fd_coeff_z_hyper, buff_size, & + fd_number, fd_order) $:GPU_UPDATE(device='[fd_coeff_z_hyper]') end if end subroutine s_initialize_hyperelastic_module - !> Compute the left Cauchy-Green deformation tensor and update the hyperelastic stress + !> The following subroutine handles the calculation of the btensor. + !! The calculation of the btensor takes qprimvf. + !! @param q_cons_vf Conservative variables + !! @param q_prim_vf Primitive variables + !! calculate the grad_xi, grad_xi is a nxn tensor + !! calculate the inverse of grad_xi to obtain F, F is a nxn tensor + !! calculate the FFtranspose to obtain the btensor, btensor is nxn tensor + !! btensor is symmetric, save the data space subroutine s_hyperelastic_rmt_stress_update(q_cons_vf, q_prim_vf) type(scalar_field), dimension(sys_size), intent(inout) :: q_cons_vf type(scalar_field), dimension(sys_size), intent(inout) :: q_prim_vf - #:if USING_AMD real(wp), dimension(10) :: tensora, tensorb #:else @@ -89,30 +107,34 @@ contains real(wp), dimension(num_fluids) :: alpha_k, alpha_rho_k #:endif real(wp), dimension(2) :: Re - real(wp) :: rho, gamma, pi_inf, qv - real(wp) :: G_local - integer :: j, k, l, i, r + real(wp) :: rho, gamma, pi_inf, qv + real(wp) :: G_local + integer :: j, k, l, i, r - $:GPU_PARALLEL_LOOP(collapse=3, & - & private='[i, j, k, l, alpha_K, alpha_rho_K, rho, gamma, pi_inf, qv, G_local, Re, tensora, tensorb]') + $:GPU_PARALLEL_LOOP(collapse=3, private='[i,j,k,l,alpha_K, alpha_rho_K, rho, gamma, pi_inf, qv, G_local, Re, tensora, tensorb]') do l = 0, p do k = 0, n do j = 0, m + call s_compute_species_fraction(q_cons_vf, j, k, l, alpha_rho_k, alpha_k) ! If in simulation, use acc mixture subroutines - call s_convert_species_to_mixture_variables_acc(rho, gamma, pi_inf, qv, alpha_k, alpha_rho_k, Re, G_local, & - & Gs_hyper) + call s_convert_species_to_mixture_variables_acc(rho, gamma, pi_inf, qv, alpha_k, & + alpha_rho_k, Re, G_local, Gs_hyper) rho = max(rho, sgm_eps) G_local = max(G_local, sgm_eps) + !if ( G_local <= verysmall ) G_K = 0._wp if (G_local > verysmall) then $:GPU_LOOP(parallelism='[seq]') do i = 1, tensor_size tensora(i) = 0._wp end do - ! STEP 1: computing the grad_xi tensor using finite differences grad_xi definition / organization number for - ! the tensor 1-3: dxix_dx, dxiy_dx, dxiz_dx 4-6 : dxix_dy, dxiy_dy, dxiz_dy 7-9 : dxix_dz, dxiy_dz, dxiz_dz + ! STEP 1: computing the grad_xi tensor using finite differences + ! grad_xi definition / organization + ! number for the tensor 1-3: dxix_dx, dxiy_dx, dxiz_dx + ! 4-6 : dxix_dy, dxiy_dy, dxiz_dy + ! 7-9 : dxix_dz, dxiy_dz, dxiz_dz $:GPU_LOOP(parallelism='[seq]') do r = -fd_number, fd_number ! derivatives in the x-direction @@ -140,11 +162,13 @@ contains tensorb(9) = tensora(1)*tensora(5) - tensora(2)*tensora(4) ! STEP 2b: computing the determinant of the grad_xi tensor - tensorb(tensor_size) = tensora(1)*(tensora(5)*tensora(9) - tensora(6)*tensora(8)) - tensora(2)*(tensora(4) & - & *tensora(9) - tensora(6)*tensora(7)) + tensora(3)*(tensora(4)*tensora(8) - tensora(5)*tensora(7)) + tensorb(tensor_size) = tensora(1)*(tensora(5)*tensora(9) - tensora(6)*tensora(8)) & + - tensora(2)*(tensora(4)*tensora(9) - tensora(6)*tensora(7)) & + + tensora(3)*(tensora(4)*tensora(8) - tensora(5)*tensora(7)) if (tensorb(tensor_size) > verysmall) then - ! STEP 2c: computing the inverse of grad_xi tensor = F tensorb is the adjoint, tensora becomes F + ! STEP 2c: computing the inverse of grad_xi tensor = F + ! tensorb is the adjoint, tensora becomes F $:GPU_LOOP(parallelism='[seq]') do i = 1, tensor_size - 1 tensora(i) = tensorb(i)/tensorb(tensor_size) @@ -169,16 +193,17 @@ contains ! STEP 5a: updating the Cauchy stress primitive scalar field if (hyper_model == 1) then call s_neoHookean_cauchy_solver(btensor%vf, q_prim_vf, G_local, j, k, l) - else if (hyper_model == 2) then + elseif (hyper_model == 2) then call s_Mooney_Rivlin_cauchy_solver(btensor%vf, q_prim_vf, G_local, j, k, l) end if ! STEP 5b: updating the pressure field - q_prim_vf(E_idx)%sf(j, k, l) = q_prim_vf(E_idx)%sf(j, k, l) - G_local*q_prim_vf(xiend + 1)%sf(j, k, & - & l)/gamma + q_prim_vf(E_idx)%sf(j, k, l) = q_prim_vf(E_idx)%sf(j, k, l) - & + G_local*q_prim_vf(xiend + 1)%sf(j, k, l)/gamma ! STEP 5c: updating the Cauchy stress conservative scalar field $:GPU_LOOP(parallelism='[seq]') do i = 1, b_size - 1 - q_cons_vf(strxb + i - 1)%sf(j, k, l) = rho*q_prim_vf(strxb + i - 1)%sf(j, k, l) + q_cons_vf(strxb + i - 1)%sf(j, k, l) = & + rho*q_prim_vf(strxb + i - 1)%sf(j, k, l) end do end if end if @@ -186,72 +211,102 @@ contains end do end do $:END_GPU_PARALLEL_LOOP() - end subroutine s_hyperelastic_rmt_stress_update - !> Compute the neo-Hookean Cauchy stress from the left Cauchy-Green tensor + !> The following subroutine handles the calculation of the btensor. + !! The calculation of the btensor takes qprimvf. + !! @param btensor_in Left Cauchy-Green deformation tensor + !! @param q_prim_vf Primitive variables + !! @param G_param Elastic shear modulus + !! @param j x-direction cell index + !! @param k y-direction cell index + !! @param l z-direction cell index + !! calculate the grad_xi, grad_xi is a nxn tensor + !! calculate the inverse of grad_xi to obtain F, F is a nxn tensor + !! calculate the FFtranspose to obtain the btensor, btensor is nxn tensor + !! btensor is symmetric, save the data space subroutine s_neoHookean_cauchy_solver(btensor_in, q_prim_vf, G_param, j, k, l) - $:GPU_ROUTINE(parallelism='[seq]') type(scalar_field), dimension(sys_size), intent(inout) :: q_prim_vf - type(scalar_field), dimension(b_size), intent(inout) :: btensor_in - real(wp), intent(in) :: G_param - integer, intent(in) :: j, k, l - real(wp) :: trace - real(wp), parameter :: f13 = 1._wp/3._wp - integer :: i !< Generic loop iterators + type(scalar_field), dimension(b_size), intent(inout) :: btensor_in + real(wp), intent(in) :: G_param + integer, intent(in) :: j, k, l + + real(wp) :: trace + real(wp), parameter :: f13 = 1._wp/3._wp + integer :: i !< Generic loop iterators + ! tensor is the symmetric tensor & calculate the trace of the tensor trace = btensor_in(1)%sf(j, k, l) + btensor_in(3)%sf(j, k, l) + btensor_in(6)%sf(j, k, l) - ! Deviatoric left Cauchy-Green tensor: dev(b) = b - (tr(b)/3)*I + ! calculate the deviatoric of the tensor #:for IJ in [1,3,6] btensor_in(${IJ}$)%sf(j, k, l) = btensor_in(${IJ}$)%sf(j, k, l) - f13*trace #:endfor - ! dividing by the jacobian for neo-Hookean model setting the tensor to the stresses for riemann solver + ! dividing by the jacobian for neo-Hookean model + ! setting the tensor to the stresses for riemann solver $:GPU_LOOP(parallelism='[seq]') do i = 1, b_size - 1 - q_prim_vf(strxb + i - 1)%sf(j, k, l) = G_param*btensor_in(i)%sf(j, k, l)/btensor_in(b_size)%sf(j, k, l) + q_prim_vf(strxb + i - 1)%sf(j, k, l) = & + G_param*btensor_in(i)%sf(j, k, l)/btensor_in(b_size)%sf(j, k, l) end do - ! First invariant strain energy: W = G/2 * (I1 - 3), neo-Hookean model - q_prim_vf(xiend + 1)%sf(j, k, l) = 0.5_wp*(trace - 3.0_wp)/btensor_in(b_size)%sf(j, k, l) + ! compute the invariant without the elastic modulus + q_prim_vf(xiend + 1)%sf(j, k, l) = & + 0.5_wp*(trace - 3.0_wp)/btensor_in(b_size)%sf(j, k, l) end subroutine s_neoHookean_cauchy_solver - !> Compute the Mooney-Rivlin Cauchy stress from the left Cauchy-Green tensor + !> The following subroutine handles the calculation of the btensor. + !! The calculation of the btensor takes qprimvf. + !! @param btensor_in Left Cauchy-Green deformation tensor + !! @param q_prim_vf Primitive variables + !! @param G_param Elastic shear modulus + !! @param j x-direction cell index + !! @param k y-direction cell index + !! @param l z-direction cell index + !! calculate the grad_xi, grad_xi is a nxn tensor + !! calculate the inverse of grad_xi to obtain F, F is a nxn tensor + !! calculate the FFtranspose to obtain the btensor, btensor is nxn tensor + !! btensor is symmetric, save the data space subroutine s_Mooney_Rivlin_cauchy_solver(btensor_in, q_prim_vf, G_param, j, k, l) - $:GPU_ROUTINE(parallelism='[seq]') type(scalar_field), dimension(sys_size), intent(inout) :: q_prim_vf - type(scalar_field), dimension(b_size), intent(inout) :: btensor_in - real(wp), intent(in) :: G_param - integer, intent(in) :: j, k, l - real(wp) :: trace - real(wp), parameter :: f13 = 1._wp/3._wp - integer :: i !< Generic loop iterators - ! TODO: Make 1D and 2D capable + type(scalar_field), dimension(b_size), intent(inout) :: btensor_in + real(wp), intent(in) :: G_param + integer, intent(in) :: j, k, l + + real(wp) :: trace + real(wp), parameter :: f13 = 1._wp/3._wp + integer :: i !< Generic loop iterators + + !TODO Make this 1D and 2D capable + ! tensor is the symmetric tensor & calculate the trace of the tensor trace = btensor_in(1)%sf(j, k, l) + btensor_in(3)%sf(j, k, l) + btensor_in(6)%sf(j, k, l) - ! Deviatoric left Cauchy-Green tensor: dev(b) = b - (tr(b)/3)*I + ! calculate the deviatoric of the tensor btensor_in(1)%sf(j, k, l) = btensor_in(1)%sf(j, k, l) - f13*trace btensor_in(3)%sf(j, k, l) = btensor_in(3)%sf(j, k, l) - f13*trace btensor_in(6)%sf(j, k, l) = btensor_in(6)%sf(j, k, l) - f13*trace - ! dividing by the jacobian for neo-Hookean model setting the tensor to the stresses for riemann solver + ! dividing by the jacobian for neo-Hookean model + ! setting the tensor to the stresses for riemann solver $:GPU_LOOP(parallelism='[seq]') do i = 1, b_size - 1 - q_prim_vf(strxb + i - 1)%sf(j, k, l) = G_param*btensor_in(i)%sf(j, k, l)/btensor_in(b_size)%sf(j, k, l) + q_prim_vf(strxb + i - 1)%sf(j, k, l) = & + G_param*btensor_in(i)%sf(j, k, l)/btensor_in(b_size)%sf(j, k, l) end do - ! First invariant strain energy: W = G/2 * (I1 - 3), neo-Hookean model - q_prim_vf(xiend + 1)%sf(j, k, l) = 0.5_wp*(trace - 3.0_wp)/btensor_in(b_size)%sf(j, k, l) + ! compute the invariant without the elastic modulus + q_prim_vf(xiend + 1)%sf(j, k, l) = & + 0.5_wp*(trace - 3.0_wp)/btensor_in(b_size)%sf(j, k, l) end subroutine s_Mooney_Rivlin_cauchy_solver - !> Finalize the hyperelastic module + !> @brief Deallocates memory for hyperelastic deformation tensor and finite-difference coefficients. impure subroutine s_finalize_hyperelastic_module() - integer :: i !< iterator - ! Deallocating memory + integer :: i !< iterator + ! Deallocating memory do i = 1, b_size @:DEALLOCATE(btensor%vf(i)%sf) end do diff --git a/src/simulation/m_hypoelastic.fpp b/src/simulation/m_hypoelastic.fpp index d38741934e..8ee46b1ba8 100644 --- a/src/simulation/m_hypoelastic.fpp +++ b/src/simulation/m_hypoelastic.fpp @@ -7,35 +7,37 @@ !> @brief Computes hypoelastic stress-rate source terms and damage-state evolution module m_hypoelastic - use m_derived_types - use m_global_parameters + use m_derived_types !< Definitions of the derived types + use m_global_parameters !< Definitions of the global parameters use m_finite_differences use m_helper implicit none - private; public :: s_initialize_hypoelastic_module, s_finalize_hypoelastic_module, s_compute_hypoelastic_rhs, & - & s_compute_damage_state + private; public :: s_initialize_hypoelastic_module, & + s_finalize_hypoelastic_module, & + s_compute_hypoelastic_rhs, & + s_compute_damage_state real(wp), allocatable, dimension(:) :: Gs_hypo $:GPU_DECLARE(create='[Gs_hypo]') - real(wp), allocatable, dimension(:,:,:) :: du_dx_hypo, du_dy_hypo, du_dz_hypo - real(wp), allocatable, dimension(:,:,:) :: dv_dx_hypo, dv_dy_hypo, dv_dz_hypo - real(wp), allocatable, dimension(:,:,:) :: dw_dx_hypo, dw_dy_hypo, dw_dz_hypo - $:GPU_DECLARE(create='[du_dx_hypo, du_dy_hypo, du_dz_hypo, dv_dx_hypo, dv_dy_hypo, dv_dz_hypo, dw_dx_hypo, dw_dy_hypo, dw_dz_hypo]') + real(wp), allocatable, dimension(:, :, :) :: du_dx_hypo, du_dy_hypo, du_dz_hypo + real(wp), allocatable, dimension(:, :, :) :: dv_dx_hypo, dv_dy_hypo, dv_dz_hypo + real(wp), allocatable, dimension(:, :, :) :: dw_dx_hypo, dw_dy_hypo, dw_dz_hypo + $:GPU_DECLARE(create='[du_dx_hypo,du_dy_hypo,du_dz_hypo,dv_dx_hypo,dv_dy_hypo,dv_dz_hypo,dw_dx_hypo,dw_dy_hypo,dw_dz_hypo]') - real(wp), allocatable, dimension(:,:,:) :: rho_K_field, G_K_field - $:GPU_DECLARE(create='[rho_K_field, G_K_field]') + real(wp), allocatable, dimension(:, :, :) :: rho_K_field, G_K_field + $:GPU_DECLARE(create='[rho_K_field,G_K_field]') - real(wp), allocatable, dimension(:,:) :: fd_coeff_x_hypo - real(wp), allocatable, dimension(:,:) :: fd_coeff_y_hypo - real(wp), allocatable, dimension(:,:) :: fd_coeff_z_hypo - $:GPU_DECLARE(create='[fd_coeff_x_hypo, fd_coeff_y_hypo, fd_coeff_z_hypo]') + real(wp), allocatable, dimension(:, :) :: fd_coeff_x_hypo + real(wp), allocatable, dimension(:, :) :: fd_coeff_y_hypo + real(wp), allocatable, dimension(:, :) :: fd_coeff_z_hypo + $:GPU_DECLARE(create='[fd_coeff_x_hypo,fd_coeff_y_hypo,fd_coeff_z_hypo]') contains - !> Initialize the hypoelastic module + !> @brief Allocates arrays and computes finite-difference coefficients for the hypoelastic stress model. impure subroutine s_initialize_hypoelastic_module integer :: i @@ -65,33 +67,43 @@ contains end if ! Computing centered finite difference coefficients - call s_compute_finite_difference_coefficients(m, x_cc, fd_coeff_x_hypo, buff_size, fd_number, fd_order) + call s_compute_finite_difference_coefficients(m, x_cc, fd_coeff_x_hypo, buff_size, & + fd_number, fd_order) $:GPU_UPDATE(device='[fd_coeff_x_hypo]') if (n > 0) then - call s_compute_finite_difference_coefficients(n, y_cc, fd_coeff_y_hypo, buff_size, fd_number, fd_order) + call s_compute_finite_difference_coefficients(n, y_cc, fd_coeff_y_hypo, buff_size, & + fd_number, fd_order) $:GPU_UPDATE(device='[fd_coeff_y_hypo]') end if if (p > 0) then - call s_compute_finite_difference_coefficients(p, z_cc, fd_coeff_z_hypo, buff_size, fd_number, fd_order) + call s_compute_finite_difference_coefficients(p, z_cc, fd_coeff_z_hypo, buff_size, & + fd_number, fd_order) $:GPU_UPDATE(device='[fd_coeff_z_hypo]') end if end subroutine s_initialize_hypoelastic_module - !> Compute the hypoelastic stress source terms + !> The purpose of this procedure is to compute the source terms + !! that are needed for the elastic stress equations + !! @param idir Dimension splitting index + !! @param q_prim_vf Primitive variables + !! @param rhs_vf rhs variables subroutine s_compute_hypoelastic_rhs(idir, q_prim_vf, rhs_vf) - integer, intent(in) :: idir - type(scalar_field), dimension(sys_size), intent(in) :: q_prim_vf + integer, intent(in) :: idir + type(scalar_field), dimension(sys_size), intent(in) :: q_prim_vf type(scalar_field), dimension(sys_size), intent(inout) :: rhs_vf - real(wp) :: rho_K, G_K - integer :: i, k, l, q, r !< Loop variables - integer :: ndirs !< Number of coordinate directions + + real(wp) :: rho_K, G_K + + integer :: i, k, l, q, r !< Loop variables + integer :: ndirs !< Number of coordinate directions ndirs = 1; if (n > 0) ndirs = 2; if (p > 0) ndirs = 3 if (idir == 1) then - ! calculate velocity gradients + rho_K and G_K TODO: re-organize these loops one by one for GPU efficiency if possible? + ! calculate velocity gradients + rho_K and G_K + ! TODO: re-organize these loops one by one for GPU efficiency if possible? $:GPU_PARALLEL_LOOP(collapse=3) do q = 0, p @@ -109,8 +121,10 @@ contains do k = 0, m $:GPU_LOOP(parallelism='[seq]') do r = -fd_number, fd_number - du_dx_hypo(k, l, q) = du_dx_hypo(k, l, q) + q_prim_vf(momxb)%sf(k + r, l, q)*fd_coeff_x_hypo(r, k) + du_dx_hypo(k, l, q) = du_dx_hypo(k, l, q) & + + q_prim_vf(momxb)%sf(k + r, l, q)*fd_coeff_x_hypo(r, k) end do + end do end do end do @@ -133,11 +147,12 @@ contains do k = 0, m $:GPU_LOOP(parallelism='[seq]') do r = -fd_number, fd_number - du_dy_hypo(k, l, q) = du_dy_hypo(k, l, q) + q_prim_vf(momxb)%sf(k, l + r, q)*fd_coeff_y_hypo(r, l) - dv_dx_hypo(k, l, q) = dv_dx_hypo(k, l, q) + q_prim_vf(momxb + 1)%sf(k + r, l, & - & q)*fd_coeff_x_hypo(r, k) - dv_dy_hypo(k, l, q) = dv_dy_hypo(k, l, q) + q_prim_vf(momxb + 1)%sf(k, l + r, & - & q)*fd_coeff_y_hypo(r, l) + du_dy_hypo(k, l, q) = du_dy_hypo(k, l, q) & + + q_prim_vf(momxb)%sf(k, l + r, q)*fd_coeff_y_hypo(r, l) + dv_dx_hypo(k, l, q) = dv_dx_hypo(k, l, q) & + + q_prim_vf(momxb + 1)%sf(k + r, l, q)*fd_coeff_x_hypo(r, k) + dv_dy_hypo(k, l, q) = dv_dy_hypo(k, l, q) & + + q_prim_vf(momxb + 1)%sf(k, l + r, q)*fd_coeff_y_hypo(r, l) end do end do end do @@ -146,12 +161,13 @@ contains ! 3D if (ndirs == 3) then + $:GPU_PARALLEL_LOOP(collapse=3) do q = 0, p do l = 0, n do k = 0, m - du_dz_hypo(k, l, q) = 0._wp; dv_dz_hypo(k, l, q) = 0._wp; dw_dx_hypo(k, l, q) = 0._wp - dw_dy_hypo(k, l, q) = 0._wp; dw_dz_hypo(k, l, q) = 0._wp + du_dz_hypo(k, l, q) = 0._wp; dv_dz_hypo(k, l, q) = 0._wp; dw_dx_hypo(k, l, q) = 0._wp; + dw_dy_hypo(k, l, q) = 0._wp; dw_dz_hypo(k, l, q) = 0._wp; end do end do end do @@ -163,16 +179,16 @@ contains do k = 0, m $:GPU_LOOP(parallelism='[seq]') do r = -fd_number, fd_number - du_dz_hypo(k, l, q) = du_dz_hypo(k, l, q) + q_prim_vf(momxb)%sf(k, l, & - & q + r)*fd_coeff_z_hypo(r, q) - dv_dz_hypo(k, l, q) = dv_dz_hypo(k, l, q) + q_prim_vf(momxb + 1)%sf(k, l, & - & q + r)*fd_coeff_z_hypo(r, q) - dw_dx_hypo(k, l, q) = dw_dx_hypo(k, l, q) + q_prim_vf(momxe)%sf(k + r, l, & - & q)*fd_coeff_x_hypo(r, k) - dw_dy_hypo(k, l, q) = dw_dy_hypo(k, l, q) + q_prim_vf(momxe)%sf(k, l + r, & - & q)*fd_coeff_y_hypo(r, l) - dw_dz_hypo(k, l, q) = dw_dz_hypo(k, l, q) + q_prim_vf(momxe)%sf(k, l, & - & q + r)*fd_coeff_z_hypo(r, q) + du_dz_hypo(k, l, q) = du_dz_hypo(k, l, q) & + + q_prim_vf(momxb)%sf(k, l, q + r)*fd_coeff_z_hypo(r, q) + dv_dz_hypo(k, l, q) = dv_dz_hypo(k, l, q) & + + q_prim_vf(momxb + 1)%sf(k, l, q + r)*fd_coeff_z_hypo(r, q) + dw_dx_hypo(k, l, q) = dw_dx_hypo(k, l, q) & + + q_prim_vf(momxe)%sf(k + r, l, q)*fd_coeff_x_hypo(r, k) + dw_dy_hypo(k, l, q) = dw_dy_hypo(k, l, q) & + + q_prim_vf(momxe)%sf(k, l + r, q)*fd_coeff_y_hypo(r, l) + dw_dz_hypo(k, l, q) = dw_dz_hypo(k, l, q) & + + q_prim_vf(momxe)%sf(k, l, q + r)*fd_coeff_z_hypo(r, q) end do end do end do @@ -187,17 +203,16 @@ contains do k = 0, m rho_K = 0._wp; G_K = 0._wp do i = 1, num_fluids - rho_K = rho_K + q_prim_vf(i)%sf(k, l, q) ! alpha_rho_K(1) - G_K = G_K + q_prim_vf(advxb - 1 + i)%sf(k, l, q)*Gs_hypo(i) ! alpha_K(1) * Gs_hypo(1) + rho_K = rho_K + q_prim_vf(i)%sf(k, l, q) !alpha_rho_K(1) + G_K = G_K + q_prim_vf(advxb - 1 + i)%sf(k, l, q)*Gs_hypo(i) !alpha_K(1) * Gs_hypo(1) end do - ! Continuum damage: (1-D) scales effective stiffness, D in [0,1] if (cont_damage) G_K = G_K*max((1._wp - q_prim_vf(damage_idx)%sf(k, l, q)), 0._wp) rho_K_field(k, l, q) = rho_K G_K_field(k, l, q) = G_K - ! TODO: take this out if not needed + !TODO: take this out if not needed if (G_K < verysmall) then G_K_field(k, l, q) = 0 end if @@ -211,85 +226,114 @@ contains do q = 0, p do l = 0, n do k = 0, m - rhs_vf(strxb)%sf(k, l, q) = rhs_vf(strxb)%sf(k, l, q) + rho_K_field(k, l, q)*((4._wp*G_K_field(k, l, & - & q)/3._wp) + q_prim_vf(strxb)%sf(k, l, q))*du_dx_hypo(k, l, q) + rhs_vf(strxb)%sf(k, l, q) = & + rhs_vf(strxb)%sf(k, l, q) + rho_K_field(k, l, q)* & + ((4._wp*G_K_field(k, l, q)/3._wp) + & + q_prim_vf(strxb)%sf(k, l, q))* & + du_dx_hypo(k, l, q) end do end do end do $:END_GPU_PARALLEL_LOOP() - else if (idir == 2) then + + elseif (idir == 2) then $:GPU_PARALLEL_LOOP(collapse=3) do q = 0, p do l = 0, n do k = 0, m - rhs_vf(strxb)%sf(k, l, q) = rhs_vf(strxb)%sf(k, l, q) + rho_K_field(k, l, q)*(q_prim_vf(strxb + 1)%sf(k, & - & l, q)*du_dy_hypo(k, l, q) + q_prim_vf(strxb + 1)%sf(k, l, q)*du_dy_hypo(k, l, & - & q) - q_prim_vf(strxb)%sf(k, l, q)*dv_dy_hypo(k, l, q) - 2._wp*G_K_field(k, l, & - & q)*(1._wp/3._wp)*dv_dy_hypo(k, l, q)) - - rhs_vf(strxb + 1)%sf(k, l, q) = rhs_vf(strxb + 1)%sf(k, l, q) + rho_K_field(k, l, & - & q)*(q_prim_vf(strxb + 1)%sf(k, l, q)*du_dx_hypo(k, l, q) + q_prim_vf(strxb)%sf(k, l, & - & q)*dv_dx_hypo(k, l, q) - q_prim_vf(strxb + 1)%sf(k, l, q)*du_dx_hypo(k, l, & - & q) + q_prim_vf(strxb + 2)%sf(k, l, q)*du_dy_hypo(k, l, q) + q_prim_vf(strxb + 1)%sf(k, l, & - & q)*dv_dy_hypo(k, l, q) - q_prim_vf(strxb + 1)%sf(k, l, q)*dv_dy_hypo(k, l, & - & q) + 2._wp*G_K_field(k, l, q)*(1._wp/2._wp)*(du_dy_hypo(k, l, q) + dv_dx_hypo(k, l, q))) - - rhs_vf(strxb + 2)%sf(k, l, q) = rhs_vf(strxb + 2)%sf(k, l, q) + rho_K_field(k, l, & - & q)*(q_prim_vf(strxb + 1)%sf(k, l, q)*dv_dx_hypo(k, l, q) + q_prim_vf(strxb + 1)%sf(k, l, & - & q)*dv_dx_hypo(k, l, q) - q_prim_vf(strxb + 2)%sf(k, l, q)*du_dx_hypo(k, l, & - & q) + q_prim_vf(strxb + 2)%sf(k, l, q)*dv_dy_hypo(k, l, q) + q_prim_vf(strxb + 2)%sf(k, l, & - & q)*dv_dy_hypo(k, l, q) - q_prim_vf(strxb + 2)%sf(k, l, q)*dv_dy_hypo(k, l, & - & q) + 2._wp*G_K_field(k, l, q)*(dv_dy_hypo(k, l, q) - (1._wp/3._wp)*(du_dx_hypo(k, l, & - & q) + dv_dy_hypo(k, l, q)))) + rhs_vf(strxb)%sf(k, l, q) = rhs_vf(strxb)%sf(k, l, q) + rho_K_field(k, l, q)* & + (q_prim_vf(strxb + 1)%sf(k, l, q)*du_dy_hypo(k, l, q) + & + q_prim_vf(strxb + 1)%sf(k, l, q)*du_dy_hypo(k, l, q) - & + q_prim_vf(strxb)%sf(k, l, q)*dv_dy_hypo(k, l, q) - & + 2._wp*G_K_field(k, l, q)*(1._wp/3._wp)*dv_dy_hypo(k, l, q)) + + rhs_vf(strxb + 1)%sf(k, l, q) = rhs_vf(strxb + 1)%sf(k, l, q) + rho_K_field(k, l, q)* & + (q_prim_vf(strxb + 1)%sf(k, l, q)*du_dx_hypo(k, l, q) + & + q_prim_vf(strxb)%sf(k, l, q)*dv_dx_hypo(k, l, q) - & + q_prim_vf(strxb + 1)%sf(k, l, q)*du_dx_hypo(k, l, q) + & + q_prim_vf(strxb + 2)%sf(k, l, q)*du_dy_hypo(k, l, q) + & + q_prim_vf(strxb + 1)%sf(k, l, q)*dv_dy_hypo(k, l, q) - & + q_prim_vf(strxb + 1)%sf(k, l, q)*dv_dy_hypo(k, l, q) + & + 2._wp*G_K_field(k, l, q)*(1._wp/2._wp)*(du_dy_hypo(k, l, q) + & + dv_dx_hypo(k, l, q))) + + rhs_vf(strxb + 2)%sf(k, l, q) = rhs_vf(strxb + 2)%sf(k, l, q) + rho_K_field(k, l, q)* & + (q_prim_vf(strxb + 1)%sf(k, l, q)*dv_dx_hypo(k, l, q) + & + q_prim_vf(strxb + 1)%sf(k, l, q)*dv_dx_hypo(k, l, q) - & + q_prim_vf(strxb + 2)%sf(k, l, q)*du_dx_hypo(k, l, q) + & + q_prim_vf(strxb + 2)%sf(k, l, q)*dv_dy_hypo(k, l, q) + & + q_prim_vf(strxb + 2)%sf(k, l, q)*dv_dy_hypo(k, l, q) - & + q_prim_vf(strxb + 2)%sf(k, l, q)*dv_dy_hypo(k, l, q) + & + 2._wp*G_K_field(k, l, q)*(dv_dy_hypo(k, l, q) - (1._wp/3._wp)* & + (du_dx_hypo(k, l, q) + & + dv_dy_hypo(k, l, q)))) end do end do end do $:END_GPU_PARALLEL_LOOP() - else if (idir == 3) then + + elseif (idir == 3) then $:GPU_PARALLEL_LOOP(collapse=3) do q = 0, p do l = 0, n do k = 0, m - rhs_vf(strxb)%sf(k, l, q) = rhs_vf(strxb)%sf(k, l, q) + rho_K_field(k, l, q)*(q_prim_vf(strxb + 3)%sf(k, & - & l, q)*du_dz_hypo(k, l, q) + q_prim_vf(strxb + 3)%sf(k, l, q)*du_dz_hypo(k, l, & - & q) - q_prim_vf(strxb)%sf(k, l, q)*dw_dz_hypo(k, l, q) - 2._wp*G_K_field(k, l, & - & q)*(1._wp/3._wp)*dw_dz_hypo(k, l, q)) - - rhs_vf(strxb + 1)%sf(k, l, q) = rhs_vf(strxb + 1)%sf(k, l, q) + rho_K_field(k, l, & - & q)*(q_prim_vf(strxb + 4)%sf(k, l, q)*du_dz_hypo(k, l, q) + q_prim_vf(strxb + 3)%sf(k, l, & - & q)*dv_dz_hypo(k, l, q) - q_prim_vf(strxb + 1)%sf(k, l, q)*dw_dz_hypo(k, l, q)) - - rhs_vf(strxb + 2)%sf(k, l, q) = rhs_vf(strxb + 2)%sf(k, l, q) + rho_K_field(k, l, & - & q)*(q_prim_vf(strxb + 4)%sf(k, l, q)*dv_dz_hypo(k, l, q) + q_prim_vf(strxb + 4)%sf(k, l, & - & q)*dv_dz_hypo(k, l, q) - q_prim_vf(strxb + 2)%sf(k, l, q)*dw_dz_hypo(k, l, & - & q) - 2._wp*G_K_field(k, l, q)*(1._wp/3._wp)*dw_dz_hypo(k, l, q)) - - rhs_vf(strxb + 3)%sf(k, l, q) = rhs_vf(strxb + 3)%sf(k, l, q) + rho_K_field(k, l, & - & q)*(q_prim_vf(strxb + 3)%sf(k, l, q)*du_dx_hypo(k, l, q) + q_prim_vf(strxb)%sf(k, l, & - & q)*dw_dx_hypo(k, l, q) - q_prim_vf(strxb + 3)%sf(k, l, q)*du_dx_hypo(k, l, & - & q) + q_prim_vf(strxb + 4)%sf(k, l, q)*du_dy_hypo(k, l, q) + q_prim_vf(strxb + 1)%sf(k, l, & - & q)*dw_dy_hypo(k, l, q) - q_prim_vf(strxb + 3)%sf(k, l, q)*dv_dy_hypo(k, l, & - & q) + q_prim_vf(strxb + 5)%sf(k, l, q)*du_dz_hypo(k, l, q) + q_prim_vf(strxb + 3)%sf(k, l, & - & q)*dw_dz_hypo(k, l, q) - q_prim_vf(strxb + 3)%sf(k, l, q)*dw_dz_hypo(k, l, & - & q) + 2._wp*G_K_field(k, l, q)*(1._wp/2._wp)*(du_dz_hypo(k, l, q) + dw_dx_hypo(k, l, q))) - - rhs_vf(strxb + 4)%sf(k, l, q) = rhs_vf(strxb + 4)%sf(k, l, q) + rho_K_field(k, l, & - & q)*(q_prim_vf(strxb + 3)%sf(k, l, q)*dv_dx_hypo(k, l, q) + q_prim_vf(strxb + 1)%sf(k, l, & - & q)*dw_dx_hypo(k, l, q) - q_prim_vf(strxb + 4)%sf(k, l, q)*du_dx_hypo(k, l, & - & q) + q_prim_vf(strxb + 4)%sf(k, l, q)*dv_dy_hypo(k, l, q) + q_prim_vf(strxb + 2)%sf(k, l, & - & q)*dw_dy_hypo(k, l, q) - q_prim_vf(strxb + 4)%sf(k, l, q)*dv_dy_hypo(k, l, & - & q) + q_prim_vf(strxb + 5)%sf(k, l, q)*dv_dz_hypo(k, l, q) + q_prim_vf(strxb + 4)%sf(k, l, & - & q)*dw_dz_hypo(k, l, q) - q_prim_vf(strxb + 4)%sf(k, l, q)*dw_dz_hypo(k, l, & - & q) + 2._wp*G_K_field(k, l, q)*(1._wp/2._wp)*(dv_dz_hypo(k, l, q) + dw_dy_hypo(k, l, q))) - - rhs_vf(strxe)%sf(k, l, q) = rhs_vf(strxe)%sf(k, l, q) + rho_K_field(k, l, q)*(q_prim_vf(strxe - 2)%sf(k, & - & l, q)*dw_dx_hypo(k, l, q) + q_prim_vf(strxe - 2)%sf(k, l, q)*dw_dx_hypo(k, l, & - & q) - q_prim_vf(strxe)%sf(k, l, q)*du_dx_hypo(k, l, q) + q_prim_vf(strxe - 1)%sf(k, l, & - & q)*dw_dy_hypo(k, l, q) + q_prim_vf(strxe - 1)%sf(k, l, q)*dw_dy_hypo(k, l, & - & q) - q_prim_vf(strxe)%sf(k, l, q)*dv_dy_hypo(k, l, q) + q_prim_vf(strxe)%sf(k, l, & - & q)*dw_dz_hypo(k, l, q) + q_prim_vf(strxe)%sf(k, l, q)*dw_dz_hypo(k, l, & - & q) - q_prim_vf(strxe)%sf(k, l, q)*dw_dz_hypo(k, l, q) + 2._wp*G_K_field(k, l, q)*(dw_dz_hypo(k, & - & l, q) - (1._wp/3._wp)*(du_dx_hypo(k, l, q) + dv_dy_hypo(k, l, q) + dw_dz_hypo(k, l, q)))) + rhs_vf(strxb)%sf(k, l, q) = rhs_vf(strxb)%sf(k, l, q) + rho_K_field(k, l, q)* & + (q_prim_vf(strxb + 3)%sf(k, l, q)*du_dz_hypo(k, l, q) + & + q_prim_vf(strxb + 3)%sf(k, l, q)*du_dz_hypo(k, l, q) - & + q_prim_vf(strxb)%sf(k, l, q)*dw_dz_hypo(k, l, q) - & + 2._wp*G_K_field(k, l, q)*(1._wp/3._wp)*dw_dz_hypo(k, l, q)) + + rhs_vf(strxb + 1)%sf(k, l, q) = rhs_vf(strxb + 1)%sf(k, l, q) + rho_K_field(k, l, q)* & + (q_prim_vf(strxb + 4)%sf(k, l, q)*du_dz_hypo(k, l, q) + & + q_prim_vf(strxb + 3)%sf(k, l, q)*dv_dz_hypo(k, l, q) - & + q_prim_vf(strxb + 1)%sf(k, l, q)*dw_dz_hypo(k, l, q)) + + rhs_vf(strxb + 2)%sf(k, l, q) = rhs_vf(strxb + 2)%sf(k, l, q) + rho_K_field(k, l, q)* & + (q_prim_vf(strxb + 4)%sf(k, l, q)*dv_dz_hypo(k, l, q) + & + q_prim_vf(strxb + 4)%sf(k, l, q)*dv_dz_hypo(k, l, q) - & + q_prim_vf(strxb + 2)%sf(k, l, q)*dw_dz_hypo(k, l, q) - & + 2._wp*G_K_field(k, l, q)*(1._wp/3._wp)*dw_dz_hypo(k, l, q)) + + rhs_vf(strxb + 3)%sf(k, l, q) = rhs_vf(strxb + 3)%sf(k, l, q) + rho_K_field(k, l, q)* & + (q_prim_vf(strxb + 3)%sf(k, l, q)*du_dx_hypo(k, l, q) + & + q_prim_vf(strxb)%sf(k, l, q)*dw_dx_hypo(k, l, q) - & + q_prim_vf(strxb + 3)%sf(k, l, q)*du_dx_hypo(k, l, q) + & + q_prim_vf(strxb + 4)%sf(k, l, q)*du_dy_hypo(k, l, q) + & + q_prim_vf(strxb + 1)%sf(k, l, q)*dw_dy_hypo(k, l, q) - & + q_prim_vf(strxb + 3)%sf(k, l, q)*dv_dy_hypo(k, l, q) + & + q_prim_vf(strxb + 5)%sf(k, l, q)*du_dz_hypo(k, l, q) + & + q_prim_vf(strxb + 3)%sf(k, l, q)*dw_dz_hypo(k, l, q) - & + q_prim_vf(strxb + 3)%sf(k, l, q)*dw_dz_hypo(k, l, q) + & + 2._wp*G_K_field(k, l, q)*(1._wp/2._wp)*(du_dz_hypo(k, l, q) + & + dw_dx_hypo(k, l, q))) + + rhs_vf(strxb + 4)%sf(k, l, q) = rhs_vf(strxb + 4)%sf(k, l, q) + rho_K_field(k, l, q)* & + (q_prim_vf(strxb + 3)%sf(k, l, q)*dv_dx_hypo(k, l, q) + & + q_prim_vf(strxb + 1)%sf(k, l, q)*dw_dx_hypo(k, l, q) - & + q_prim_vf(strxb + 4)%sf(k, l, q)*du_dx_hypo(k, l, q) + & + q_prim_vf(strxb + 4)%sf(k, l, q)*dv_dy_hypo(k, l, q) + & + q_prim_vf(strxb + 2)%sf(k, l, q)*dw_dy_hypo(k, l, q) - & + q_prim_vf(strxb + 4)%sf(k, l, q)*dv_dy_hypo(k, l, q) + & + q_prim_vf(strxb + 5)%sf(k, l, q)*dv_dz_hypo(k, l, q) + & + q_prim_vf(strxb + 4)%sf(k, l, q)*dw_dz_hypo(k, l, q) - & + q_prim_vf(strxb + 4)%sf(k, l, q)*dw_dz_hypo(k, l, q) + & + 2._wp*G_K_field(k, l, q)*(1._wp/2._wp)*(dv_dz_hypo(k, l, q) + & + dw_dy_hypo(k, l, q))) + + rhs_vf(strxe)%sf(k, l, q) = rhs_vf(strxe)%sf(k, l, q) + rho_K_field(k, l, q)* & + (q_prim_vf(strxe - 2)%sf(k, l, q)*dw_dx_hypo(k, l, q) + & + q_prim_vf(strxe - 2)%sf(k, l, q)*dw_dx_hypo(k, l, q) - & + q_prim_vf(strxe)%sf(k, l, q)*du_dx_hypo(k, l, q) + & + q_prim_vf(strxe - 1)%sf(k, l, q)*dw_dy_hypo(k, l, q) + & + q_prim_vf(strxe - 1)%sf(k, l, q)*dw_dy_hypo(k, l, q) - & + q_prim_vf(strxe)%sf(k, l, q)*dv_dy_hypo(k, l, q) + & + q_prim_vf(strxe)%sf(k, l, q)*dw_dz_hypo(k, l, q) + & + q_prim_vf(strxe)%sf(k, l, q)*dw_dz_hypo(k, l, q) - & + q_prim_vf(strxe)%sf(k, l, q)*dw_dz_hypo(k, l, q) + & + 2._wp*G_K_field(k, l, q)*(dw_dz_hypo(k, l, q) - (1._wp/3._wp)* & + (du_dx_hypo(k, l, q) + & + dv_dy_hypo(k, l, q) + & + dw_dz_hypo(k, l, q)))) end do end do end do @@ -297,38 +341,42 @@ contains end if if (cyl_coord .and. idir == 2) then + $:GPU_PARALLEL_LOOP(collapse=3) do q = 0, p do l = 0, n do k = 0, m ! S_xx -= rho * v/r * (tau_xx + 2/3*G) - rhs_vf(strxb)%sf(k, l, q) = rhs_vf(strxb)%sf(k, l, q) - rho_K_field(k, l, q)*q_prim_vf(momxb + 1)%sf(k, & - & l, q)/y_cc(l)*(q_prim_vf(strxb)%sf(k, l, q) + (2._wp/3._wp)*G_K_field(k, l, q)) ! tau_xx + 2/3*G + rhs_vf(strxb)%sf(k, l, q) = rhs_vf(strxb)%sf(k, l, q) - & + rho_K_field(k, l, q)*q_prim_vf(momxb + 1)%sf(k, l, q)/y_cc(l)* & + (q_prim_vf(strxb)%sf(k, l, q) + (2._wp/3._wp)*G_K_field(k, l, q)) ! tau_xx + 2/3*G ! S_xr -= rho * v/r * tau_xr - rhs_vf(strxb + 1)%sf(k, l, q) = rhs_vf(strxb + 1)%sf(k, l, q) - rho_K_field(k, l, & - & q)*q_prim_vf(momxb + 1)%sf(k, l, q)/y_cc(l)*q_prim_vf(strxb + 1)%sf(k, l, q) ! tau_xx + rhs_vf(strxb + 1)%sf(k, l, q) = rhs_vf(strxb + 1)%sf(k, l, q) - & + rho_K_field(k, l, q)*q_prim_vf(momxb + 1)%sf(k, l, q)/y_cc(l)* & + q_prim_vf(strxb + 1)%sf(k, l, q) ! tau_xx ! S_rr -= rho * v/r * (tau_rr + 2/3*G) - rhs_vf(strxb + 2)%sf(k, l, q) = rhs_vf(strxb + 2)%sf(k, l, q) - rho_K_field(k, l, & - & q)*q_prim_vf(momxb + 1)%sf(k, l, q)/y_cc(l)*(q_prim_vf(strxb + 2)%sf(k, l, & - & q) + (2._wp/3._wp)*G_K_field(k, l, q)) ! tau_rr + 2/3*G + rhs_vf(strxb + 2)%sf(k, l, q) = rhs_vf(strxb + 2)%sf(k, l, q) - & + rho_K_field(k, l, q)*q_prim_vf(momxb + 1)%sf(k, l, q)/y_cc(l)* & + (q_prim_vf(strxb + 2)%sf(k, l, q) + (2._wp/3._wp)*G_K_field(k, l, q)) ! tau_rr + 2/3*G ! S_thetatheta += rho * ( -(tau_thetatheta + 2/3*G)*(du/dx + dv/dr + v/r) + 2*(tau_thetatheta + G)*v/r ) - rhs_vf(strxb + 3)%sf(k, l, q) = rhs_vf(strxb + 3)%sf(k, l, q) + rho_K_field(k, l, & - & q)*(-(q_prim_vf(strxb + 3)%sf(k, l, q) + (2._wp/3._wp)*G_K_field(k, l, q))*(du_dx_hypo(k, l, & - & q) + dv_dy_hypo(k, l, q) + q_prim_vf(momxb + 1)%sf(k, l, & - & q)/y_cc(l)) + 2._wp*(q_prim_vf(strxb + 3)%sf(k, l, q) + G_K_field(k, l, & - & q))*q_prim_vf(momxb + 1)%sf(k, l, q)/y_cc(l)) + rhs_vf(strxb + 3)%sf(k, l, q) = rhs_vf(strxb + 3)%sf(k, l, q) + & + rho_K_field(k, l, q)*( & + -(q_prim_vf(strxb + 3)%sf(k, l, q) + (2._wp/3._wp)*G_K_field(k, l, q))* & + (du_dx_hypo(k, l, q) + dv_dy_hypo(k, l, q) + q_prim_vf(momxb + 1)%sf(k, l, q)/y_cc(l)) & + + 2._wp*(q_prim_vf(strxb + 3)%sf(k, l, q) + G_K_field(k, l, q))*q_prim_vf(momxb + 1)%sf(k, l, q)/y_cc(l)) end do end do end do $:END_GPU_PARALLEL_LOOP() + end if end subroutine s_compute_hypoelastic_rhs - !> Finalize the hypoelastic module + !> @brief Deallocates arrays used by the hypoelastic stress module. impure subroutine s_finalize_hypoelastic_module() @:DEALLOCATE(Gs_hypo) @@ -346,41 +394,42 @@ contains end subroutine s_finalize_hypoelastic_module - !> Compute the continuum damage source term from the principal stress state + !> @brief Computes the continuum damage source term from the principal stress state. subroutine s_compute_damage_state(q_cons_vf, rhs_vf) - type(scalar_field), dimension(sys_size), intent(in) :: q_cons_vf + type(scalar_field), dimension(sys_size), intent(in) :: q_cons_vf type(scalar_field), dimension(sys_size), intent(inout) :: rhs_vf - real(wp) :: tau_p !< principal stress - real(wp) :: tau_xx, tau_xy, tau_yy, tau_zz, tau_yz, tau_xz - real(wp) :: I1, I2, I3, argument, phi, sqrt_term_1, sqrt_term_2, temp - integer :: q, l, k + + real(wp) :: tau_p ! principal stress + real(wp) :: tau_xx, tau_xy, tau_yy, tau_zz, tau_yz, tau_xz + real(wp) :: I1, I2, I3, argument, phi, sqrt_term_1, sqrt_term_2, temp + integer :: q, l, k if (n == 0) then l = 0; q = 0 $:GPU_PARALLEL_LOOP() do k = 0, m - rhs_vf(damage_idx)%sf(k, l, q) = (alpha_bar*max(abs(real(q_cons_vf(stress_idx%beg)%sf(k, l, q), & - & kind=wp)) - tau_star, 0._wp))**cont_damage_s + rhs_vf(damage_idx)%sf(k, l, q) = (alpha_bar*max(abs(real(q_cons_vf(stress_idx%beg)%sf(k, l, q), kind=wp)) - tau_star, 0._wp))**cont_damage_s end do $:END_GPU_PARALLEL_LOOP() - else if (p == 0) then + elseif (p == 0) then q = 0 $:GPU_PARALLEL_LOOP(collapse=2, private='[tau_p]') do l = 0, n do k = 0, m ! Maximum principal stress - tau_p = 0.5_wp*(q_cons_vf(stress_idx%beg)%sf(k, l, q) + q_cons_vf(stress_idx%beg + 2)%sf(k, l, & - & q)) + sqrt((q_cons_vf(stress_idx%beg)%sf(k, l, q) - q_cons_vf(stress_idx%beg + 2)%sf(k, l, & - & q))**2.0_wp + 4._wp*q_cons_vf(stress_idx%beg + 1)%sf(k, l, q)**2.0_wp)/2._wp + tau_p = 0.5_wp*(q_cons_vf(stress_idx%beg)%sf(k, l, q) + & + q_cons_vf(stress_idx%beg + 2)%sf(k, l, q)) + & + sqrt((q_cons_vf(stress_idx%beg)%sf(k, l, q) - & + q_cons_vf(stress_idx%beg + 2)%sf(k, l, q))**2.0_wp + & + 4._wp*q_cons_vf(stress_idx%beg + 1)%sf(k, l, q)**2.0_wp)/2._wp rhs_vf(damage_idx)%sf(k, l, q) = (alpha_bar*max(tau_p - tau_star, 0._wp))**cont_damage_s end do end do $:END_GPU_PARALLEL_LOOP() else - $:GPU_PARALLEL_LOOP(collapse=3, private='[tau_xx, tau_xy, tau_yy, tau_xz, tau_yz, tau_zz, I1, I2, I3, temp, & - & sqrt_term_1, sqrt_term_2, argument, phi, tau_p]') + $:GPU_PARALLEL_LOOP(collapse=3, private='[tau_xx, tau_xy, tau_yy, tau_xz, tau_yz, tau_zz, I1, I2, I3, temp, sqrt_term_1, sqrt_term_2, argument, phi, tau_p]') do q = 0, p do l = 0, n do k = 0, m @@ -393,15 +442,17 @@ contains ! Invariants of the stress tensor I1 = tau_xx + tau_yy + tau_zz - I2 = tau_xx*tau_yy + tau_xx*tau_zz + tau_yy*tau_zz - (tau_xy**2.0_wp + tau_xz**2.0_wp + tau_yz**2.0_wp) - I3 = tau_xx*tau_yy*tau_zz + 2.0_wp*tau_xy*tau_xz*tau_yz - tau_xx*tau_yz**2.0_wp - tau_yy*tau_xz**2.0_wp & - & - tau_zz*tau_xy**2.0_wp + I2 = tau_xx*tau_yy + tau_xx*tau_zz + tau_yy*tau_zz - & + (tau_xy**2.0_wp + tau_xz**2.0_wp + tau_yz**2.0_wp) + I3 = tau_xx*tau_yy*tau_zz + 2.0_wp*tau_xy*tau_xz*tau_yz - & + tau_xx*tau_yz**2.0_wp - tau_yy*tau_xz**2.0_wp - tau_zz*tau_xy**2.0_wp ! Maximum principal stress temp = I1**2.0_wp - 3.0_wp*I2 sqrt_term_1 = sqrt(max(temp, 0.0_wp)) - if (sqrt_term_1 > verysmall) then ! Avoid 0/0 - argument = (2.0_wp*I1*I1*I1 - 9.0_wp*I1*I2 + 27.0_wp*I3)/(2.0_wp*sqrt_term_1*sqrt_term_1*sqrt_term_1) + if (sqrt_term_1 > verysmall) then ! Avoid 0/0 + argument = (2.0_wp*I1*I1*I1 - 9.0_wp*I1*I2 + 27.0_wp*I3)/ & + (2.0_wp*sqrt_term_1*sqrt_term_1*sqrt_term_1) if (argument > 1.0_wp) argument = 1.0_wp if (argument < -1.0_wp) argument = -1.0_wp phi = acos(argument) diff --git a/src/simulation/m_ib_patches.fpp b/src/simulation/m_ib_patches.fpp index a7d8e45eee..12fcccbf3c 100644 --- a/src/simulation/m_ib_patches.fpp +++ b/src/simulation/m_ib_patches.fpp @@ -12,55 +12,63 @@ !> @brief Immersed boundary patch geometry constructors for 2D and 3D shapes module m_ib_patches - use m_model ! Subroutine(s) related to STL files - use m_derived_types ! Definitions of the derived types - use m_global_parameters - use m_helper_basic + use m_model ! Subroutine(s) related to STL files + + use m_derived_types ! Definitions of the derived types + + use m_global_parameters !< Definitions of the global parameters + + use m_helper_basic !< Functions to compare floating point numbers + use m_helper + use m_mpi_common implicit none - private; public :: s_apply_ib_patches, s_update_ib_rotation_matrix, f_convert_cyl_to_cart, s_instantiate_STL_models, & - & s_decode_patch_periodicity + private; public :: s_apply_ib_patches, s_update_ib_rotation_matrix, f_convert_cyl_to_cart, s_instantiate_STL_models, s_decode_patch_periodicity real(wp) :: x_centroid, y_centroid, z_centroid real(wp) :: length_x, length_y, length_z $:GPU_DECLARE(create='[x_centroid, y_centroid, z_centroid]') $:GPU_DECLARE(create='[length_x, length_y, length_z]') - integer :: smooth_patch_id + integer :: smooth_patch_id real(wp) :: smooth_coeff $:GPU_DECLARE(create='[smooth_patch_id, smooth_coeff]') - ! These variables are analogous in both meaning and use to the similarly named components in the ic_patch_parameters type (see - ! m_derived_types.f90 for additional details). They are employed as a means to more concisely perform the actions necessary to - ! lay out a particular patch on the grid. + !! These variables are analogous in both meaning and use to the similarly + !! named components in the ic_patch_parameters type (see m_derived_types.f90 + !! for additional details). They are employed as a means to more concisely + !! perform the actions necessary to lay out a particular patch on the grid. real(wp) :: cart_x, cart_y, cart_z - real(wp) :: sph_phi + real(wp) :: sph_phi !< $:GPU_DECLARE(create='[cart_x, cart_y, cart_z, sph_phi]') - ! Variables to be used to hold cell locations in Cartesian coordinates if 3D simulation is using cylindrical coordinates + !! Variables to be used to hold cell locations in Cartesian coordinates if + !! 3D simulation is using cylindrical coordinates type(bounds_info) :: x_boundary, y_boundary, z_boundary $:GPU_DECLARE(create='[x_boundary, y_boundary, z_boundary]') - ! These variables combine the centroid and length parameters associated with a particular patch to yield the locations of the - ! patch boundaries in the x-, y- and z-coordinate directions. They are used as a means to concisely perform the actions - ! necessary to lay out a particular patch on the grid. + !! These variables combine the centroid and length parameters associated with + !! a particular patch to yield the locations of the patch boundaries in the + !! x-, y- and z-coordinate directions. They are used as a means to concisely + !! perform the actions necessary to lay out a particular patch on the grid. - character(len=5) :: istr !< string to store int to string result for error checking + character(len=5) :: istr ! string to store int to string result for error checking contains - !> Apply all immersed boundary patch geometries to mark interior cells in the IB marker array + !> @brief Applies all immersed boundary patch geometries to mark interior cells in the IB marker array. impure subroutine s_apply_ib_patches(ib_markers) type(integer_field), intent(inout) :: ib_markers - integer :: i, xp, yp, zp !< iterators - integer :: xp_lower, xp_upper, yp_lower, yp_upper, zp_lower, zp_upper !< periodic bounds - ! 3D Patch Geometries + integer :: i, xp, yp, zp ! iterators + integer :: xp_lower, xp_upper, yp_lower, yp_upper, zp_lower, zp_upper ! periodic bounds + ! 3D Patch Geometries if (p > 0) then + !> IB Patches !> @{ call s_get_periodicities(xp_lower, xp_upper, yp_lower, yp_upper, zp_lower, zp_upper) @@ -70,13 +78,13 @@ contains do i = 1, num_ibs if (patch_ib(i)%geometry == 8) then call s_ib_sphere(i, ib_markers, xp, yp, zp) - else if (patch_ib(i)%geometry == 9) then + elseif (patch_ib(i)%geometry == 9) then call s_ib_cuboid(i, ib_markers, xp, yp, zp) - else if (patch_ib(i)%geometry == 10) then + elseif (patch_ib(i)%geometry == 10) then call s_ib_cylinder(i, ib_markers, xp, yp, zp) - else if (patch_ib(i)%geometry == 11) then + elseif (patch_ib(i)%geometry == 11) then call s_ib_3D_airfoil(i, ib_markers, xp, yp, zp) - else if (patch_ib(i)%geometry == 12) then + elseif (patch_ib(i)%geometry == 12) then call s_ib_3d_model(i, ib_markers, xp, yp, zp) end if end do @@ -86,7 +94,8 @@ contains !> @} ! 2D Patch Geometries - else if (n > 0) then + elseif (n > 0) then + !> IB Patches !> @{ call s_get_periodicities(xp_lower, xp_upper, yp_lower, yp_upper) @@ -95,38 +104,47 @@ contains do i = 1, num_ibs if (patch_ib(i)%geometry == 2) then call s_ib_circle(i, ib_markers, xp, yp) - else if (patch_ib(i)%geometry == 3) then + elseif (patch_ib(i)%geometry == 3) then call s_ib_rectangle(i, ib_markers, xp, yp) - else if (patch_ib(i)%geometry == 4) then + elseif (patch_ib(i)%geometry == 4) then call s_ib_airfoil(i, ib_markers, xp, yp) - else if (patch_ib(i)%geometry == 5) then + elseif (patch_ib(i)%geometry == 5) then call s_ib_model(i, ib_markers, xp, yp) - else if (patch_ib(i)%geometry == 6) then + elseif (patch_ib(i)%geometry == 6) then call s_ib_ellipse(i, ib_markers, xp, yp) end if end do end do end do !> @} + end if end subroutine s_apply_ib_patches - !> Mark cells inside a circular immersed boundary + !> The circular patch is a 2D geometry that may be used, for + !! example, in creating a bubble or a droplet. The geometry + !! of the patch is well-defined when its centroid and radius + !! are provided. Note that the circular patch DOES allow for + !! the smoothing of its boundary. + !! @param patch_id is the patch identifier + !! @param ib_markers Array to track patch ids + !! @param ib True if this patch is an immersed boundary subroutine s_ib_circle(patch_id, ib_markers, xp, yp) - integer, intent(in) :: patch_id - integer, intent(in) :: xp, yp !< integers containing the periodicity projection information + integer, intent(in) :: patch_id + integer, intent(in) :: xp, yp !< integers containing the periodicity projection information type(integer_field), intent(inout) :: ib_markers - real(wp), dimension(1:2) :: center - real(wp) :: radius - integer :: i, j, il, ir, jl, jr !< Generic loop iterators - integer :: encoded_patch_id - ! Transferring the circular patch's radius, centroid, smearing patch identity and smearing coefficient information + real(wp), dimension(1:2) :: center + real(wp) :: radius + integer :: i, j, il, ir, jl, jr !< Generic loop iterators + integer :: encoded_patch_id - center(1) = patch_ib(patch_id)%x_centroid + real(xp, wp)*(x_domain%end - x_domain%beg) - center(2) = patch_ib(patch_id)%y_centroid + real(yp, wp)*(y_domain%end - y_domain%beg) + ! Transferring the circular patch's radius, centroid, smearing patch + ! identity and smearing coefficient information + center(1) = patch_ib(patch_id)%x_centroid + real(xp, wp)*(glb_bounds(1)%end - glb_bounds(1)%beg) + center(2) = patch_ib(patch_id)%y_centroid + real(yp, wp)*(glb_bounds(2)%end - glb_bounds(2)%beg) radius = patch_ib(patch_id)%radius ! encode the periodicity information into the patch_id @@ -140,12 +158,18 @@ contains call get_bounding_indices(center(1) - radius, center(1) + radius, x_cc, il, ir) call get_bounding_indices(center(2) - radius, center(2) + radius, y_cc, jl, jr) - ! Assign primitive variables if circle covers cell and patch has write permission + ! Checking whether the circle covers a particular cell in the domain + ! and verifying whether the current patch has permission to write to + ! that cell. If both queries check out, the primitive variables of + ! the current patch are assigned to this cell. - $:GPU_PARALLEL_LOOP(private='[i, j]', copyin='[encoded_patch_id, center, radius]', collapse=2) + $:GPU_PARALLEL_LOOP(private='[i,j]',& + & copyin='[encoded_patch_id,center,radius]', collapse=2) do j = jl, jr do i = il, ir - if ((x_cc(i) - center(1))**2 + (y_cc(j) - center(2))**2 <= radius**2) then + if ((x_cc(i) - center(1))**2 & + + (y_cc(j) - center(2))**2 <= radius**2) & + then ib_markers%sf(i, j, 0) = encoded_patch_id end if end do @@ -154,28 +178,32 @@ contains end subroutine s_ib_circle - !> Mark cells inside a 2D NACA 4-digit airfoil immersed boundary + !> @brief Marks cells inside a 2D NACA 4-digit airfoil immersed boundary using upper and lower surface grids. + !! @param patch_id is the patch identifier + !! @param ib_markers Array to track patch ids subroutine s_ib_airfoil(patch_id, ib_markers, xp, yp) - integer, intent(in) :: patch_id + integer, intent(in) :: patch_id type(integer_field), intent(inout) :: ib_markers - integer, intent(in) :: xp, yp !< integers containing the periodicity projection information - real(wp) :: f, ca_in, pa, ma, ta - real(wp) :: xa, yt, xu, yu, xl, yl, xc, yc, dycdxc, sin_c, cos_c - integer :: i, j, k, il, ir, jl, jr - integer :: Np1, Np2 - integer :: encoded_patch_id - real(wp), dimension(1:3) :: xy_local, offset !< x and y coordinates in local IB frame - real(wp), dimension(1:2) :: center !< x and y coordinates in local IB frame - real(wp), dimension(1:3,1:3) :: inverse_rotation - - center(1) = patch_ib(patch_id)%x_centroid + real(xp, wp)*(x_domain%end - x_domain%beg) - center(2) = patch_ib(patch_id)%y_centroid + real(yp, wp)*(y_domain%end - y_domain%beg) + integer, intent(in) :: xp, yp !< integers containing the periodicity projection information + + real(wp) :: f, ca_in, pa, ma, ta + real(wp) :: xa, yt, xu, yu, xl, yl, xc, yc, dycdxc, sin_c, cos_c + integer :: i, j, k, il, ir, jl, jr + integer :: Np1, Np2 + integer :: encoded_patch_id + + real(wp), dimension(1:3) :: xy_local, offset !< x and y coordinates in local IB frame + real(wp), dimension(1:2) :: center !< x and y coordinates in local IB frame + real(wp), dimension(1:3, 1:3) :: inverse_rotation + + center(1) = patch_ib(patch_id)%x_centroid + real(xp, wp)*(glb_bounds(1)%end - glb_bounds(1)%beg) + center(2) = patch_ib(patch_id)%y_centroid + real(yp, wp)*(glb_bounds(2)%end - glb_bounds(2)%beg) ca_in = patch_ib(patch_id)%c pa = patch_ib(patch_id)%p ma = patch_ib(patch_id)%m ta = patch_ib(patch_id)%t - inverse_rotation(:,:) = patch_ib(patch_id)%rotation_matrix_inverse(:,:) + inverse_rotation(:, :) = patch_ib(patch_id)%rotation_matrix_inverse(:, :) offset(:) = patch_ib(patch_id)%centroid_offset(:) Np1 = int((pa*ca_in/dx(0))*20) @@ -187,7 +215,7 @@ contains @:ALLOCATE(airfoil_grid_u(1:Np)) @:ALLOCATE(airfoil_grid_l(1:Np)) - ! TODO :: The below instantiations are already handled by the loop below + ! TODO :: The below instantiations are already handles by the loop below airfoil_grid_u(1)%x = 0._wp airfoil_grid_u(1)%y = 0._wp @@ -195,8 +223,7 @@ contains airfoil_grid_l(1)%y = 0._wp do i = 1, Np1 + Np2 - 1 - ! TODO :: This allocates the upper and lower airfoil arrays, and does not need to be performed each time the IB - ! markers are updated. Place this as a separate subroutine. + ! TODO :: This allocated the upper and lower airfoil arrays, and does not need to be performed each time the IB markers are updated. Place this as a separate subroutine. if (i <= Np1) then xc = i*(pa*ca_in/Np1) xa = xc/ca_in @@ -230,6 +257,7 @@ contains airfoil_grid_l(i + 1)%x = xl airfoil_grid_l(i + 1)%y = yl + end do airfoil_grid_u(Np)%x = ca_in @@ -238,7 +266,8 @@ contains airfoil_grid_l(Np)%x = ca_in airfoil_grid_l(Np)%y = 0._wp - $:GPU_UPDATE(device='[airfoil_grid_l, airfoil_grid_u]') + $:GPU_UPDATE(device='[airfoil_grid_l,airfoil_grid_u]') + end if ! encode the periodicity information into the patch_id @@ -253,13 +282,13 @@ contains call get_bounding_indices(center(1) - ca_in, center(1) + ca_in, x_cc, il, ir) call get_bounding_indices(center(2) - ca_in, center(2) + ca_in, y_cc, jl, jr) - $:GPU_PARALLEL_LOOP(private='[i, j, xy_local, k, f]', copyin='[encoded_patch_id, center, inverse_rotation, offset, ma, & - & ca_in, airfoil_grid_u, airfoil_grid_l]', collapse=2) + $:GPU_PARALLEL_LOOP(private='[i,j,xy_local,k,f]', & + & copyin='[encoded_patch_id,center,inverse_rotation,offset,ma,ca_in,airfoil_grid_u,airfoil_grid_l]', collapse=2) do j = jl, jr do i = il, ir - xy_local = [x_cc(i) - center(1), y_cc(j) - center(2), 0._wp] ! get coordinate frame centered on IB - xy_local = matmul(inverse_rotation, xy_local) ! rotate the frame into the IB's coordinates - xy_local = xy_local - offset ! airfoils are a patch that require a centroid offset + xy_local = [x_cc(i) - center(1), y_cc(j) - center(2), 0._wp] ! get coordinate frame centered on IB + xy_local = matmul(inverse_rotation, xy_local) ! rotate the frame into the IB's coordinates + xy_local = xy_local - offset ! airfoils are a patch that require a centroid offset if (xy_local(1) >= 0._wp .and. xy_local(1) <= ca_in) then xa = xy_local(1)/ca_in @@ -277,11 +306,13 @@ contains end do if (f_approx_equal(airfoil_grid_u(k)%x, xy_local(1))) then if (xy_local(2) <= airfoil_grid_u(k)%y) then + !!IB ib_markers%sf(i, j, 0) = encoded_patch_id end if else f = (airfoil_grid_u(k)%x - xy_local(1))/(airfoil_grid_u(k)%x - airfoil_grid_u(k - 1)%x) if (xy_local(2) <= ((1._wp - f)*airfoil_grid_u(k)%y + f*airfoil_grid_u(k - 1)%y)) then + !!IB ib_markers%sf(i, j, 0) = encoded_patch_id end if end if @@ -292,12 +323,14 @@ contains end do if (f_approx_equal(airfoil_grid_l(k)%x, xy_local(1))) then if (xy_local(2) >= airfoil_grid_l(k)%y) then + !!IB ib_markers%sf(i, j, 0) = encoded_patch_id end if else f = (airfoil_grid_l(k)%x - xy_local(1))/(airfoil_grid_l(k)%x - airfoil_grid_l(k - 1)%x) if (xy_local(2) >= ((1._wp - f)*airfoil_grid_l(k)%y + f*airfoil_grid_l(k - 1)%y)) then + !!IB ib_markers%sf(i, j, 0) = encoded_patch_id end if end if @@ -309,28 +342,33 @@ contains end subroutine s_ib_airfoil - !> Mark cells inside a 3D extruded NACA 4-digit airfoil immersed boundary with finite span + !> @brief Marks cells inside a 3D extruded NACA 4-digit airfoil immersed boundary with finite span. + !! @param patch_id is the patch identifier + !! @param ib_markers Array to track patch ids + !! @param ib True if this patch is an immersed boundary subroutine s_ib_3D_airfoil(patch_id, ib_markers, xp, yp, zp) integer, intent(in) :: patch_id type(integer_field), intent(inout) :: ib_markers - integer, intent(in) :: xp, yp, zp !< integers containing the periodicity projection information + integer, intent(in) :: xp, yp, zp !< integers containing the periodicity projection information + real(wp) :: lz, z_max, z_min, f, ca_in, pa, ma, ta, xa, yt, xu, yu, xl, yl, xc, yc, dycdxc, sin_c, cos_c integer :: i, j, k, l, il, ir, jl, jr, ll, lr integer :: Np1, Np2 integer :: encoded_patch_id - real(wp), dimension(1:3) :: xyz_local, center, offset !< x, y, z coordinates in local IB frame - real(wp), dimension(1:3,1:3) :: inverse_rotation - center(1) = patch_ib(patch_id)%x_centroid + real(xp, wp)*(x_domain%end - x_domain%beg) - center(2) = patch_ib(patch_id)%y_centroid + real(yp, wp)*(y_domain%end - y_domain%beg) - center(3) = patch_ib(patch_id)%z_centroid + real(zp, wp)*(z_domain%end - z_domain%beg) + real(wp), dimension(1:3) :: xyz_local, center, offset !< x, y, z coordinates in local IB frame + real(wp), dimension(1:3, 1:3) :: inverse_rotation + + center(1) = patch_ib(patch_id)%x_centroid + real(xp, wp)*(glb_bounds(1)%end - glb_bounds(1)%beg) + center(2) = patch_ib(patch_id)%y_centroid + real(yp, wp)*(glb_bounds(2)%end - glb_bounds(2)%beg) + center(3) = patch_ib(patch_id)%z_centroid + real(zp, wp)*(glb_bounds(3)%end - glb_bounds(3)%beg) lz = patch_ib(patch_id)%length_z ca_in = patch_ib(patch_id)%c pa = patch_ib(patch_id)%p ma = patch_ib(patch_id)%m ta = patch_ib(patch_id)%t - inverse_rotation(:,:) = patch_ib(patch_id)%rotation_matrix_inverse(:,:) + inverse_rotation(:, :) = patch_ib(patch_id)%rotation_matrix_inverse(:, :) offset(:) = patch_ib(patch_id)%centroid_offset(:) z_max = lz/2 @@ -342,6 +380,7 @@ contains $:GPU_UPDATE(device='[Np]') if (.not. allocated(airfoil_grid_u)) then + @:ALLOCATE(airfoil_grid_u(1:Np)) @:ALLOCATE(airfoil_grid_l(1:Np)) @@ -385,6 +424,7 @@ contains airfoil_grid_l(i + 1)%x = xl airfoil_grid_l(i + 1)%y = yl + end do airfoil_grid_u(Np)%x = ca_in @@ -393,7 +433,7 @@ contains airfoil_grid_l(Np)%x = ca_in airfoil_grid_l(Np)%y = 0._wp - $:GPU_UPDATE(device='[airfoil_grid_l, airfoil_grid_u]') + $:GPU_UPDATE(device='[airfoil_grid_l,airfoil_grid_u]') end if ! encode the periodicity information into the patch_id @@ -411,17 +451,17 @@ contains call get_bounding_indices(center(2) - ca_in, center(2) + ca_in, y_cc, jl, jr) call get_bounding_indices(center(3) - ca_in, center(3) + ca_in, z_cc, ll, lr) - $:GPU_PARALLEL_LOOP(private='[i, j, l, xyz_local, k, f]', copyin='[encoded_patch_id, center, inverse_rotation, offset, & - & ma, ca_in, airfoil_grid_u, airfoil_grid_l, z_min, z_max]', collapse=3) + $:GPU_PARALLEL_LOOP(private='[i,j,l,xyz_local,k,f]',& + & copyin='[encoded_patch_id,center,inverse_rotation,offset,ma,ca_in,airfoil_grid_u,airfoil_grid_l,z_min,z_max]', collapse=3) do l = ll, lr do j = jl, jr do i = il, ir - xyz_local = [x_cc(i) - center(1), y_cc(j) - center(2), & - & z_cc(l) - center(3)] ! get coordinate frame centered on IB - xyz_local = matmul(inverse_rotation, xyz_local) ! rotate the frame into the IB's coordinates - xyz_local = xyz_local - offset ! airfoils are a patch that require a centroid offset + xyz_local = [x_cc(i) - center(1), y_cc(j) - center(2), z_cc(l) - center(3)] ! get coordinate frame centered on IB + xyz_local = matmul(inverse_rotation, xyz_local) ! rotate the frame into the IB's coordinates + xyz_local = xyz_local - offset ! airfoils are a patch that require a centroid offset if (xyz_local(3) >= z_min .and. xyz_local(3) <= z_max) then + if (xyz_local(1) >= 0._wp .and. xyz_local(1) <= ca_in) then if (xyz_local(2) >= 0._wp) then k = 1 @@ -430,12 +470,13 @@ contains end do if (f_approx_equal(airfoil_grid_u(k)%x, xyz_local(1))) then if (xyz_local(2) <= airfoil_grid_u(k)%y) then - ! IB + !IB ib_markers%sf(i, j, l) = encoded_patch_id end if else f = (airfoil_grid_u(k)%x - xyz_local(1))/(airfoil_grid_u(k)%x - airfoil_grid_u(k - 1)%x) if (xyz_local(2) <= ((1._wp - f)*airfoil_grid_u(k)%y + f*airfoil_grid_u(k - 1)%y)) then + !!IB ib_markers%sf(i, j, l) = encoded_patch_id end if end if @@ -446,12 +487,14 @@ contains end do if (f_approx_equal(airfoil_grid_l(k)%x, xyz_local(1))) then if (xyz_local(2) >= airfoil_grid_l(k)%y) then + !!IB ib_markers%sf(i, j, l) = encoded_patch_id end if else f = (airfoil_grid_l(k)%x - xyz_local(1))/(airfoil_grid_l(k)%x - airfoil_grid_l(k - 1)%x) if (xyz_local(2) >= ((1._wp - f)*airfoil_grid_l(k)%y + f*airfoil_grid_l(k - 1)%y)) then + !!IB ib_markers%sf(i, j, l) = encoded_patch_id end if end if @@ -465,26 +508,36 @@ contains end subroutine s_ib_3D_airfoil - !> Mark cells inside a rectangular immersed boundary + !> The rectangular patch is a 2D geometry that may be used, + !! for example, in creating a solid boundary, or pre-/post- + !! shock region, in alignment with the axes of the Cartesian + !! coordinate system. The geometry of such a patch is well- + !! defined when its centroid and lengths in the x- and y- + !! coordinate directions are provided. Please note that the + !! rectangular patch DOES NOT allow for the smoothing of its + !! boundaries. + !! @param patch_id is the patch identifier + !! @param ib_markers Array to track patch ids + !! @param ib True if this patch is an immersed boundary subroutine s_ib_rectangle(patch_id, ib_markers, xp, yp) - integer, intent(in) :: patch_id + integer, intent(in) :: patch_id type(integer_field), intent(inout) :: ib_markers - integer, intent(in) :: xp, yp !< integers containing the periodicity projection information - integer :: i, j, il, ir, jl, jr !< generic loop iterators - integer :: encoded_patch_id - real(wp) :: corner_distance !< Equation of state parameters - real(wp), dimension(1:3) :: xy_local !< x and y coordinates in local IB frame - real(wp), dimension(1:2) :: length, center !< x and y coordinates in local IB frame - real(wp), dimension(1:3,1:3) :: inverse_rotation + integer, intent(in) :: xp, yp !< integers containing the periodicity projection information - ! Transferring the rectangle's centroid and length information + integer :: i, j, il, ir, jl, jr !< generic loop iterators + integer :: encoded_patch_id + real(wp) :: corner_distance !< Equation of state parameters + real(wp), dimension(1:3) :: xy_local !< x and y coordinates in local IB frame + real(wp), dimension(1:2) :: length, center !< x and y coordinates in local IB frame + real(wp), dimension(1:3, 1:3) :: inverse_rotation - center(1) = patch_ib(patch_id)%x_centroid + real(xp, wp)*(x_domain%end - x_domain%beg) - center(2) = patch_ib(patch_id)%y_centroid + real(yp, wp)*(y_domain%end - y_domain%beg) + ! Transferring the rectangle's centroid and length information + center(1) = patch_ib(patch_id)%x_centroid + real(xp, wp)*(glb_bounds(1)%end - glb_bounds(1)%beg) + center(2) = patch_ib(patch_id)%y_centroid + real(yp, wp)*(glb_bounds(2)%end - glb_bounds(2)%beg) length(1) = patch_ib(patch_id)%length_x length(2) = patch_ib(patch_id)%length_y - inverse_rotation(:,:) = patch_ib(patch_id)%rotation_matrix_inverse(:,:) + inverse_rotation(:, :) = patch_ib(patch_id)%rotation_matrix_inverse(:, :) ! encode the periodicity information into the patch_id call s_encode_patch_periodicity(patch_id, xp, yp, 0, encoded_patch_id) @@ -494,23 +547,30 @@ contains jl = -gp_layers - 1 ir = m + gp_layers + 1 jr = n + gp_layers + 1 - corner_distance = sqrt(dot_product(length, length))/2._wp ! maximum distance any marker can be from the center + corner_distance = sqrt(dot_product(length, length))/2._wp ! maximum distance any marker can be from the center call get_bounding_indices(center(1) - corner_distance, center(1) + corner_distance, x_cc, il, ir) call get_bounding_indices(center(2) - corner_distance, center(2) + corner_distance, y_cc, jl, jr) - ! Assign primitive variables if rectangle covers cell and patch has write permission - $:GPU_PARALLEL_LOOP(private='[i, j, xy_local]', copyin='[encoded_patch_id, center, length, inverse_rotation, x_cc, & - & y_cc]', collapse=2) + ! Checking whether the rectangle covers a particular cell in the + ! domain and verifying whether the current patch has the permission + ! to write to that cell. If both queries check out, the primitive + ! variables of the current patch are assigned to this cell. + $:GPU_PARALLEL_LOOP(private='[i,j, xy_local]',& + & copyin='[encoded_patch_id,center,length,inverse_rotation,x_cc,y_cc]', collapse=2) do j = jl, jr do i = il, ir ! get the x and y coordinates in the local IB frame xy_local = [x_cc(i) - center(1), y_cc(j) - center(2), 0._wp] xy_local = matmul(inverse_rotation, xy_local) - if (-0.5_wp*length(1) <= xy_local(1) .and. 0.5_wp*length(1) >= xy_local(1) .and. -0.5_wp*length(2) <= xy_local(2) & - & .and. 0.5_wp*length(2) >= xy_local(2)) then + if (-0.5_wp*length(1) <= xy_local(1) .and. & + 0.5_wp*length(1) >= xy_local(1) .and. & + -0.5_wp*length(2) <= xy_local(2) .and. & + 0.5_wp*length(2) >= xy_local(2)) then + ! Updating the patch identities bookkeeping variable ib_markers%sf(i, j, 0) = encoded_patch_id + end if end do end do @@ -518,26 +578,35 @@ contains end subroutine s_ib_rectangle - !> Mark cells inside a spherical immersed boundary + !> The spherical patch is a 3D geometry that may be used, + !! for example, in creating a bubble or a droplet. The patch + !! geometry is well-defined when its centroid and radius are + !! provided. Please note that the spherical patch DOES allow + !! for the smoothing of its boundary. + !! @param patch_id is the patch identifier + !! @param ib_markers Array to track patch ids + !! @param ib True if this patch is an immersed boundary subroutine s_ib_sphere(patch_id, ib_markers, xp, yp, zp) - integer, intent(in) :: patch_id + integer, intent(in) :: patch_id type(integer_field), intent(inout) :: ib_markers - integer, intent(in) :: xp, yp, zp !< integers containing the periodicity projection information + integer, intent(in) :: xp, yp, zp !< integers containing the periodicity projection information + ! Generic loop iterators - integer :: i, j, k - integer :: il, ir, jl, jr, kl, kr - integer :: encoded_patch_id - real(wp) :: radius + integer :: i, j, k + integer :: il, ir, jl, jr, kl, kr + integer :: encoded_patch_id + real(wp) :: radius real(wp), dimension(1:3) :: center - ! Variables to initialize the pressure field that corresponds to the bubble-collapse test case found in Tiwari et al. (2013) + !! Variables to initialize the pressure field that corresponds to the + !! bubble-collapse test case found in Tiwari et al. (2013) - ! Transferring spherical patch's radius, centroid, smoothing patch identity and smoothing coefficient information - - center(1) = patch_ib(patch_id)%x_centroid + real(xp, wp)*(x_domain%end - x_domain%beg) - center(2) = patch_ib(patch_id)%y_centroid + real(yp, wp)*(y_domain%end - y_domain%beg) - center(3) = patch_ib(patch_id)%z_centroid + real(zp, wp)*(z_domain%end - z_domain%beg) + ! Transferring spherical patch's radius, centroid, smoothing patch + ! identity and smoothing coefficient information + center(1) = patch_ib(patch_id)%x_centroid + real(xp, wp)*(glb_bounds(1)%end - glb_bounds(1)%beg) + center(2) = patch_ib(patch_id)%y_centroid + real(yp, wp)*(glb_bounds(2)%end - glb_bounds(2)%beg) + center(3) = patch_ib(patch_id)%z_centroid + real(zp, wp)*(glb_bounds(3)%end - glb_bounds(3)%beg) radius = patch_ib(patch_id)%radius ! encode the periodicity information into the patch_id @@ -554,12 +623,16 @@ contains call get_bounding_indices(center(2) - radius, center(2) + radius, y_cc, jl, jr) call get_bounding_indices(center(3) - radius, center(3) + radius, z_cc, kl, kr) - ! Checking whether the sphere covers a particular cell in the domain and verifying whether the current patch has permission - ! to write to that cell. If both queries check out, the primitive variables of the current patch are assigned to this cell. - $:GPU_PARALLEL_LOOP(private='[i, j, k, cart_y, cart_z]', copyin='[encoded_patch_id, center, radius]', collapse=3) + ! Checking whether the sphere covers a particular cell in the domain + ! and verifying whether the current patch has permission to write to + ! that cell. If both queries check out, the primitive variables of + ! the current patch are assigned to this cell. + $:GPU_PARALLEL_LOOP(private='[i,j,k,cart_y,cart_z]',& + & copyin='[encoded_patch_id,center,radius]', collapse=3) do k = kl, kr do j = jl, jr do i = il, ir + ! do i = -gp_layers, m+gp_layers if (grid_geometry == 3) then call s_convert_cylindrical_to_cartesian_coord(y_cc(j), z_cc(k)) else @@ -567,7 +640,9 @@ contains cart_z = z_cc(k) end if ! Updating the patch identities bookkeeping variable - if (((x_cc(i) - center(1))**2 + (cart_y - center(2))**2 + (cart_z - center(3))**2 <= radius**2)) then + if (((x_cc(i) - center(1))**2 & + + (cart_y - center(2))**2 & + + (cart_z - center(3))**2 <= radius**2)) then ib_markers%sf(i, j, k) = encoded_patch_id end if end do @@ -577,27 +652,36 @@ contains end subroutine s_ib_sphere - !> Mark cells inside a cuboidal immersed boundary + !> The cuboidal patch is a 3D geometry that may be used, for + !! example, in creating a solid boundary, or pre-/post-shock + !! region, which is aligned with the axes of the Cartesian + !! coordinate system. The geometry of such a patch is well- + !! defined when its centroid and lengths in the x-, y- and + !! z-coordinate directions are provided. Please notice that + !! the cuboidal patch DOES NOT allow for the smearing of its + !! boundaries. + !! @param patch_id is the patch identifier + !! @param ib_markers Array to track patch ids subroutine s_ib_cuboid(patch_id, ib_markers, xp, yp, zp) - integer, intent(in) :: patch_id + integer, intent(in) :: patch_id type(integer_field), intent(inout) :: ib_markers - integer, intent(in) :: xp, yp, zp !< integers containing the periodicity projection information - integer :: i, j, k, ir, il, jr, jl, kr, kl !< Generic loop iterators - integer :: encoded_patch_id - real(wp), dimension(1:3) :: xyz_local, center, length !< x and y coordinates in local IB frame - real(wp), dimension(1:3,1:3) :: inverse_rotation - real(wp) :: corner_distance + integer, intent(in) :: xp, yp, zp !< integers containing the periodicity projection information - ! Transferring the cuboid's centroid and length information + integer :: i, j, k, ir, il, jr, jl, kr, kl !< Generic loop iterators + integer :: encoded_patch_id + real(wp), dimension(1:3) :: xyz_local, center, length !< x and y coordinates in local IB frame + real(wp), dimension(1:3, 1:3) :: inverse_rotation + real(wp) :: corner_distance - center(1) = patch_ib(patch_id)%x_centroid + real(xp, wp)*(x_domain%end - x_domain%beg) - center(2) = patch_ib(patch_id)%y_centroid + real(yp, wp)*(y_domain%end - y_domain%beg) - center(3) = patch_ib(patch_id)%z_centroid + real(zp, wp)*(z_domain%end - z_domain%beg) + ! Transferring the cuboid's centroid and length information + center(1) = patch_ib(patch_id)%x_centroid + real(xp, wp)*(glb_bounds(1)%end - glb_bounds(1)%beg) + center(2) = patch_ib(patch_id)%y_centroid + real(yp, wp)*(glb_bounds(2)%end - glb_bounds(2)%beg) + center(3) = patch_ib(patch_id)%z_centroid + real(zp, wp)*(glb_bounds(3)%end - glb_bounds(3)%beg) length(1) = patch_ib(patch_id)%length_x length(2) = patch_ib(patch_id)%length_y length(3) = patch_ib(patch_id)%length_z - inverse_rotation(:,:) = patch_ib(patch_id)%rotation_matrix_inverse(:,:) + inverse_rotation(:, :) = patch_ib(patch_id)%rotation_matrix_inverse(:, :) ! encode the periodicity information into the patch_id call s_encode_patch_periodicity(patch_id, xp, yp, zp, encoded_patch_id) @@ -609,19 +693,21 @@ contains ir = m + gp_layers + 1 jr = n + gp_layers + 1 kr = p + gp_layers + 1 - corner_distance = sqrt(dot_product(length, length))/2._wp ! maximum distance any marker can be from the center + corner_distance = sqrt(dot_product(length, length))/2._wp ! maximum distance any marker can be from the center call get_bounding_indices(center(1) - corner_distance, center(1) + corner_distance, x_cc, il, ir) call get_bounding_indices(center(2) - corner_distance, center(2) + corner_distance, y_cc, jl, jr) call get_bounding_indices(center(3) - corner_distance, center(3) + corner_distance, z_cc, kl, kr) - ! Checking whether the cuboid covers a particular cell in the domain and verifying whether the current patch has permission - ! to write to to that cell. If both queries check out, the primitive variables of the current patch are assigned to this - ! cell. - $:GPU_PARALLEL_LOOP(private='[i, j, k, xyz_local, cart_y, cart_z]', copyin='[encoded_patch_id, center, length, & - & inverse_rotation]', collapse=3) + ! Checking whether the cuboid covers a particular cell in the domain + ! and verifying whether the current patch has permission to write to + ! to that cell. If both queries check out, the primitive variables + ! of the current patch are assigned to this cell. + $:GPU_PARALLEL_LOOP(private='[i,j,k,xyz_local,cart_y,cart_z]',& + & copyin='[encoded_patch_id,center,length,inverse_rotation]', collapse=3) do k = kl, kr do j = jl, jr do i = il, ir + if (grid_geometry == 3) then ! TODO :: This does not work and is not covered by any tests. This should be fixed call s_convert_cylindrical_to_cartesian_coord(y_cc(j), z_cc(k)) @@ -629,12 +715,16 @@ contains cart_y = y_cc(j) cart_z = z_cc(k) end if - xyz_local = [x_cc(i), cart_y, cart_z] - center ! get coordinate frame centered on IB - xyz_local = matmul(inverse_rotation, xyz_local) ! rotate the frame into the IB's coordinates + xyz_local = [x_cc(i), cart_y, cart_z] - center ! get coordinate frame centered on IB + xyz_local = matmul(inverse_rotation, xyz_local) ! rotate the frame into the IB's coordinates + + if (-0.5*length(1) <= xyz_local(1) .and. & + 0.5*length(1) >= xyz_local(1) .and. & + -0.5*length(2) <= xyz_local(2) .and. & + 0.5*length(2) >= xyz_local(2) .and. & + -0.5*length(3) <= xyz_local(3) .and. & + 0.5*length(3) >= xyz_local(3)) then - if (-0.5*length(1) <= xyz_local(1) .and. 0.5*length(1) >= xyz_local(1) .and. -0.5*length(2) <= xyz_local(2) & - & .and. 0.5*length(2) >= xyz_local(2) .and. -0.5*length(3) <= xyz_local(3) .and. 0.5*length(3) & - & >= xyz_local(3)) then ! Updating the patch identities bookkeeping variable ib_markers%sf(i, j, k) = encoded_patch_id end if @@ -645,29 +735,39 @@ contains end subroutine s_ib_cuboid - !> Mark cells inside a cylindrical immersed boundary + !> The cylindrical patch is a 3D geometry that may be used, + !! for example, in setting up a cylindrical solid boundary + !! confinement, like a blood vessel. The geometry of this + !! patch is well-defined when the centroid, the radius and + !! the length along the cylinder's axis, parallel to the x-, + !! y- or z-coordinate direction, are provided. Please note + !! that the cylindrical patch DOES allow for the smoothing + !! of its lateral boundary. + !! @param patch_id is the patch identifier + !! @param ib_markers Array to track patch ids + !! @param ib True if this patch is an immersed boundary subroutine s_ib_cylinder(patch_id, ib_markers, xp, yp, zp) - integer, intent(in) :: patch_id + integer, intent(in) :: patch_id type(integer_field), intent(inout) :: ib_markers - integer, intent(in) :: xp, yp, zp !< integers containing the periodicity projection information - integer :: i, j, k, il, ir, jl, jr, kl, kr !< Generic loop iterators - integer :: encoded_patch_id - real(wp) :: radius - real(wp), dimension(1:3) :: xyz_local, center, length !< x and y coordinates in local IB frame - real(wp), dimension(1:3,1:3) :: inverse_rotation - real(wp) :: corner_distance + integer, intent(in) :: xp, yp, zp !< integers containing the periodicity projection information - ! Transferring the cylindrical patch's centroid, length, radius, + integer :: i, j, k, il, ir, jl, jr, kl, kr !< Generic loop iterators + integer :: encoded_patch_id + real(wp) :: radius + real(wp), dimension(1:3) :: xyz_local, center, length !< x and y coordinates in local IB frame + real(wp), dimension(1:3, 1:3) :: inverse_rotation + real(wp) :: corner_distance - center(1) = patch_ib(patch_id)%x_centroid + real(xp, wp)*(x_domain%end - x_domain%beg) - center(2) = patch_ib(patch_id)%y_centroid + real(yp, wp)*(y_domain%end - y_domain%beg) - center(3) = patch_ib(patch_id)%z_centroid + real(zp, wp)*(z_domain%end - z_domain%beg) + ! Transferring the cylindrical patch's centroid, length, radius, + center(1) = patch_ib(patch_id)%x_centroid + real(xp, wp)*(glb_bounds(1)%end - glb_bounds(1)%beg) + center(2) = patch_ib(patch_id)%y_centroid + real(yp, wp)*(glb_bounds(2)%end - glb_bounds(2)%beg) + center(3) = patch_ib(patch_id)%z_centroid + real(zp, wp)*(glb_bounds(3)%end - glb_bounds(3)%beg) length(1) = patch_ib(patch_id)%length_x length(2) = patch_ib(patch_id)%length_y length(3) = patch_ib(patch_id)%length_z radius = patch_ib(patch_id)%radius - inverse_rotation(:,:) = patch_ib(patch_id)%rotation_matrix_inverse(:,:) + inverse_rotation(:, :) = patch_ib(patch_id)%rotation_matrix_inverse(:, :) ! encode the periodicity information into the patch_id call s_encode_patch_periodicity(patch_id, xp, yp, zp, encoded_patch_id) @@ -678,34 +778,48 @@ contains ir = m + gp_layers + 1 jr = n + gp_layers + 1 kr = p + gp_layers + 1 - corner_distance = sqrt(radius**2 + maxval(length)**2) ! distance to rim of cylinder + corner_distance = sqrt(radius**2 + maxval(length)**2) ! distance to rim of cylinder call get_bounding_indices(center(1) - corner_distance, center(1) + corner_distance, x_cc, il, ir) call get_bounding_indices(center(2) - corner_distance, center(2) + corner_distance, y_cc, jl, jr) call get_bounding_indices(center(3) - corner_distance, center(3) + corner_distance, z_cc, kl, kr) - ! Checking whether the cylinder covers a particular cell in the domain and verifying whether the current patch has the - ! permission to write to that cell. If both queries check out, the primitive variables of the current patch are assigned to - ! this cell. - $:GPU_PARALLEL_LOOP(private='[i, j, k, xyz_local, cart_y, cart_z]', copyin='[encoded_patch_id, center, length, radius, & - & inverse_rotation]', collapse=3) + ! Checking whether the cylinder covers a particular cell in the + ! domain and verifying whether the current patch has the permission + ! to write to that cell. If both queries check out, the primitive + ! variables of the current patch are assigned to this cell. + $:GPU_PARALLEL_LOOP(private='[i,j,k,xyz_local,cart_y,cart_z]',& + & copyin='[encoded_patch_id,center,length,radius,inverse_rotation]', collapse=3) do k = kl, kr do j = jl, jr do i = il, ir + if (grid_geometry == 3) then call s_convert_cylindrical_to_cartesian_coord(y_cc(j), z_cc(k)) else cart_y = y_cc(j) cart_z = z_cc(k) end if - xyz_local = [x_cc(i), cart_y, cart_z] - center ! get coordinate frame centered on IB - xyz_local = matmul(inverse_rotation, xyz_local) ! rotate the frame into the IB's coordinates - - if (((.not. f_is_default(length(1)) .and. xyz_local(2)**2 + xyz_local(3)**2 <= radius**2 .and. & - & -0.5_wp*length(1) <= xyz_local(1) .and. 0.5_wp*length(1) >= xyz_local(1)) & - & .or. (.not. f_is_default(length(2)) .and. xyz_local(1)**2 + xyz_local(3)**2 <= radius**2 .and. & - & -0.5_wp*length(2) <= xyz_local(2) .and. 0.5_wp*length(2) >= xyz_local(2)) & - & .or. (.not. f_is_default(length(3)) .and. xyz_local(1)**2 + xyz_local(2)**2 <= radius**2 .and. & - & -0.5_wp*length(3) <= xyz_local(3) .and. 0.5_wp*length(3) >= xyz_local(3)))) then + xyz_local = [x_cc(i), cart_y, cart_z] - center ! get coordinate frame centered on IB + xyz_local = matmul(inverse_rotation, xyz_local) ! rotate the frame into the IB's coordinates + + if (((.not. f_is_default(length(1)) .and. & + xyz_local(2)**2 & + + xyz_local(3)**2 <= radius**2 .and. & + -0.5_wp*length(1) <= xyz_local(1) .and. & + 0.5_wp*length(1) >= xyz_local(1)) & + .or. & + (.not. f_is_default(length(2)) .and. & + xyz_local(1)**2 & + + xyz_local(3)**2 <= radius**2 .and. & + -0.5_wp*length(2) <= xyz_local(2) .and. & + 0.5_wp*length(2) >= xyz_local(2)) & + .or. & + (.not. f_is_default(length(3)) .and. & + xyz_local(1)**2 & + + xyz_local(2)**2 <= radius**2 .and. & + -0.5_wp*length(3) <= xyz_local(3) .and. & + 0.5_wp*length(3) >= xyz_local(3)))) then + ! Updating the patch identities bookkeeping variable ib_markers%sf(i, j, k) = encoded_patch_id end if @@ -716,26 +830,26 @@ contains end subroutine s_ib_cylinder - !> Mark cells inside a 2D elliptical immersed boundary + !> @brief Marks cells inside a 2D elliptical immersed boundary defined by semi-axis lengths and rotation. subroutine s_ib_ellipse(patch_id, ib_markers, xp, yp) - integer, intent(in) :: patch_id + integer, intent(in) :: patch_id type(integer_field), intent(inout) :: ib_markers - integer, intent(in) :: xp, yp !< integers containing the periodicity projection information - integer :: i, j, il, ir, jl, jr !< Generic loop iterators - integer :: encoded_patch_id - real(wp), dimension(1:3) :: xy_local !< x and y coordinates in local IB frame - real(wp), dimension(1:2) :: ellipse_coeffs !< a and b in the ellipse coefficients - real(wp), dimension(1:2) :: center !< x and y coordinates in local IB frame - real(wp), dimension(1:3,1:3) :: inverse_rotation + integer, intent(in) :: xp, yp !< integers containing the periodicity projection information - ! Transferring the ellipse's centroid and length information + integer :: i, j, il, ir, jl, jr !< Generic loop iterators + integer :: encoded_patch_id + real(wp), dimension(1:3) :: xy_local !< x and y coordinates in local IB frame + real(wp), dimension(1:2) :: ellipse_coeffs !< a and b in the ellipse coefficients + real(wp), dimension(1:2) :: center !< x and y coordinates in local IB frame + real(wp), dimension(1:3, 1:3) :: inverse_rotation - center(1) = patch_ib(patch_id)%x_centroid + real(xp, wp)*(x_domain%end - x_domain%beg) - center(2) = patch_ib(patch_id)%y_centroid + real(yp, wp)*(y_domain%end - y_domain%beg) + ! Transferring the ellipse's centroid and length information + center(1) = patch_ib(patch_id)%x_centroid + real(xp, wp)*(glb_bounds(1)%end - glb_bounds(1)%beg) + center(2) = patch_ib(patch_id)%y_centroid + real(yp, wp)*(glb_bounds(2)%end - glb_bounds(2)%beg) ellipse_coeffs(1) = 0.5_wp*patch_ib(patch_id)%length_x ellipse_coeffs(2) = 0.5_wp*patch_ib(patch_id)%length_y - inverse_rotation(:,:) = patch_ib(patch_id)%rotation_matrix_inverse(:,:) + inverse_rotation(:, :) = patch_ib(patch_id)%rotation_matrix_inverse(:, :) ! encode the periodicity information into the patch_id call s_encode_patch_periodicity(patch_id, xp, yp, 0, encoded_patch_id) @@ -748,9 +862,10 @@ contains call get_bounding_indices(center(1) - maxval(ellipse_coeffs)*2._wp, center(1) + maxval(ellipse_coeffs)*2._wp, x_cc, il, ir) call get_bounding_indices(center(2) - maxval(ellipse_coeffs)*2._wp, center(2) + maxval(ellipse_coeffs)*2._wp, y_cc, jl, jr) - ! Checking whether the ellipse covers a particular cell in the domain - $:GPU_PARALLEL_LOOP(private='[i, j, xy_local]', copyin='[encoded_patch_id, center, ellipse_coeffs, inverse_rotation, & - & x_cc, y_cc]', collapse=2) + ! Checking whether the ellipse covers a particular cell in the + ! domain + $:GPU_PARALLEL_LOOP(private='[i,j, xy_local]',& + & copyin='[encoded_patch_id,center,ellipse_coeffs,inverse_rotation,x_cc,y_cc]', collapse=2) do j = jl, jr do i = il, ir ! get the x and y coordinates in the local IB frame @@ -769,27 +884,31 @@ contains end subroutine s_ib_ellipse !> The STL patch is a 2D geometry that is imported from an STL file. + !! @param patch_id is the patch identifier + !! @param ib_markers Array to track patch ids subroutine s_ib_model(patch_id, ib_markers, xp, yp) - integer, intent(in) :: patch_id + integer, intent(in) :: patch_id type(integer_field), intent(inout) :: ib_markers - integer, intent(in) :: xp, yp !< integers containing the periodicity projection information - integer :: i, j, k, il, ir, jl, jr !< Generic loop iterators - integer :: spc, encoded_patch_id - integer :: cx, cy - real(wp) :: lx(2), ly(2) - real(wp), dimension(1:2) :: bbox_min, bbox_max - real(wp), dimension(1:3) :: local_corner, world_corner - real(wp) :: eta, threshold - real(wp), dimension(1:3) :: point, local_point, offset - real(wp), dimension(1:3) :: center, xy_local - real(wp), dimension(1:3,1:3) :: inverse_rotation, rotation + integer, intent(in) :: xp, yp !< integers containing the periodicity projection information + + integer :: i, j, k, il, ir, jl, jr !< Generic loop iterators + integer :: spc, encoded_patch_id + integer :: cx, cy + real(wp) :: lx(2), ly(2) + real(wp), dimension(1:2) :: bbox_min, bbox_max + real(wp), dimension(1:3) :: local_corner, world_corner + + real(wp) :: eta, threshold + real(wp), dimension(1:3) :: point, local_point, offset + real(wp), dimension(1:3) :: center, xy_local + real(wp), dimension(1:3, 1:3) :: inverse_rotation, rotation center = 0._wp - center(1) = patch_ib(patch_id)%x_centroid + real(xp, wp)*(x_domain%end - x_domain%beg) - center(2) = patch_ib(patch_id)%y_centroid + real(yp, wp)*(y_domain%end - y_domain%beg) - inverse_rotation(:,:) = patch_ib(patch_id)%rotation_matrix_inverse(:,:) - rotation(:,:) = patch_ib(patch_id)%rotation_matrix(:,:) + center(1) = patch_ib(patch_id)%x_centroid + real(xp, wp)*(glb_bounds(1)%end - glb_bounds(1)%beg) + center(2) = patch_ib(patch_id)%y_centroid + real(yp, wp)*(glb_bounds(2)%end - glb_bounds(2)%beg) + inverse_rotation(:, :) = patch_ib(patch_id)%rotation_matrix_inverse(:, :) + rotation(:, :) = patch_ib(patch_id)%rotation_matrix(:, :) offset(:) = patch_ib(patch_id)%centroid_offset(:) spc = patch_ib(patch_id)%model_spc threshold = patch_ib(patch_id)%model_threshold @@ -810,7 +929,8 @@ contains bbox_min = 1e12 bbox_max = -1e12 - ! Enumerate all 8 corners of the local bounding box, rotate to world space, track world-space AABB + ! Enumerate all 8 corners of the local bounding box, + ! rotate to world space, track world-space AABB do cx = 1, 2 do cy = 1, 2 local_corner = [lx(cx), ly(cy), 0._wp] @@ -825,15 +945,16 @@ contains call get_bounding_indices(bbox_min(1), bbox_max(1), x_cc, il, ir) call get_bounding_indices(bbox_min(2), bbox_max(2), y_cc, jl, jr) - $:GPU_PARALLEL_LOOP(private='[i, j, xy_local, eta]', copyin='[patch_id, encoded_patch_id, center, inverse_rotation, & - & offset, spc, threshold]', collapse=2) + $:GPU_PARALLEL_LOOP(private='[i,j, xy_local, eta]',& + & copyin='[patch_id,encoded_patch_id,center,inverse_rotation, offset, spc, threshold]', collapse=2) do i = il, ir do j = jl, jr xy_local = [x_cc(i) - center(1), y_cc(j) - center(2), 0._wp] xy_local = matmul(inverse_rotation, xy_local) xy_local = xy_local - offset - eta = f_model_is_inside_flat(gpu_ntrs(patch_id), patch_id, xy_local) + eta = f_model_is_inside_flat(gpu_ntrs(patch_id), & + patch_id, xy_local) ! Reading STL boundary vertices and compute the levelset and levelset_norm if (eta > threshold) then @@ -846,30 +967,34 @@ contains end subroutine s_ib_model !> The STL patch is a 3D geometry that is imported from an STL file. + !! @param patch_id is the patch identifier + !! @param ib_markers Array to track patch ids subroutine s_ib_3d_model(patch_id, ib_markers, xp, yp, zp) - integer, intent(in) :: patch_id + integer, intent(in) :: patch_id type(integer_field), intent(inout) :: ib_markers - integer, intent(in) :: xp, yp, zp !< integers containing the periodicity projection information - integer :: i, j, k, il, ir, jl, jr, kl, kr !< Generic loop iterators - integer :: spc, encoded_patch_id - real(wp) :: eta, threshold, corner_distance - real(wp), dimension(1:3) :: point, local_point, offset - real(wp), dimension(1:3) :: center, xyz_local - real(wp), dimension(1:3,1:3) :: inverse_rotation, rotation - integer :: cx, cy, cz - real(wp) :: lx(2), ly(2), lz(2) - real(wp), dimension(1:3) :: bbox_min, bbox_max, local_corner, world_corner + integer, intent(in) :: xp, yp, zp !< integers containing the periodicity projection information + + integer :: i, j, k, il, ir, jl, jr, kl, kr !< Generic loop iterators + integer :: spc, encoded_patch_id + + real(wp) :: eta, threshold, corner_distance + real(wp), dimension(1:3) :: point, local_point, offset + real(wp), dimension(1:3) :: center, xyz_local + real(wp), dimension(1:3, 1:3) :: inverse_rotation, rotation + integer :: cx, cy, cz + real(wp) :: lx(2), ly(2), lz(2) + real(wp), dimension(1:3) :: bbox_min, bbox_max, local_corner, world_corner center = 0._wp - center(1) = patch_ib(patch_id)%x_centroid + real(xp, wp)*(x_domain%end - x_domain%beg) - center(2) = patch_ib(patch_id)%y_centroid + real(yp, wp)*(y_domain%end - y_domain%beg) - center(3) = patch_ib(patch_id)%z_centroid + real(zp, wp)*(z_domain%end - z_domain%beg) - inverse_rotation(:,:) = patch_ib(patch_id)%rotation_matrix_inverse(:,:) + center(1) = patch_ib(patch_id)%x_centroid + real(xp, wp)*(glb_bounds(1)%end - glb_bounds(1)%beg) + center(2) = patch_ib(patch_id)%y_centroid + real(yp, wp)*(glb_bounds(2)%end - glb_bounds(2)%beg) + center(3) = patch_ib(patch_id)%z_centroid + real(zp, wp)*(glb_bounds(3)%end - glb_bounds(3)%beg) + inverse_rotation(:, :) = patch_ib(patch_id)%rotation_matrix_inverse(:, :) offset(:) = patch_ib(patch_id)%centroid_offset(:) spc = patch_ib(patch_id)%model_spc threshold = patch_ib(patch_id)%model_threshold - rotation(:,:) = patch_ib(patch_id)%rotation_matrix(:,:) + rotation(:, :) = patch_ib(patch_id)%rotation_matrix(:, :) ! encode the periodicity information into the patch_id call s_encode_patch_periodicity(patch_id, xp, yp, zp, encoded_patch_id) @@ -891,7 +1016,8 @@ contains bbox_min = 1e12 bbox_max = -1e12 - ! Enumerate all 8 corners of the local bounding box, rotate to world space, track world-space AABB + ! Enumerate all 8 corners of the local bounding box, + ! rotate to world space, track world-space AABB do cx = 1, 2 do cy = 1, 2 do cz = 1, 2 @@ -911,8 +1037,8 @@ contains call get_bounding_indices(bbox_min(2), bbox_max(2), y_cc, jl, jr) call get_bounding_indices(bbox_min(3), bbox_max(3), z_cc, kl, kr) - $:GPU_PARALLEL_LOOP(private='[i, j, k, xyz_local, eta]', copyin='[patch_id, encoded_patch_id, center, inverse_rotation, & - & offset, spc, threshold]', collapse=3) + $:GPU_PARALLEL_LOOP(private='[i,j,k, xyz_local, eta]',& + & copyin='[patch_id,encoded_patch_id,center,inverse_rotation, offset, spc, threshold]', collapse=3) do i = il, ir do j = jl, jr do k = kl, kr @@ -920,7 +1046,8 @@ contains xyz_local = matmul(inverse_rotation, xyz_local) xyz_local = xyz_local - offset - eta = f_model_is_inside_flat(gpu_ntrs(patch_id), patch_id, xyz_local) + eta = f_model_is_inside_flat(gpu_ntrs(patch_id), & + patch_id, xyz_local) if (eta > patch_ib(patch_id)%model_threshold) then ib_markers%sf(i, j, k) = encoded_patch_id @@ -932,55 +1059,53 @@ contains end subroutine s_ib_3d_model - !> Compute a rotation matrix for converting to the rotating frame of the boundary + !> Subroutine that computes a rotation matrix for converting to the rotating frame of the boundary subroutine s_update_ib_rotation_matrix(patch_id) - integer, intent(in) :: patch_id - integer :: i + integer, intent(in) :: patch_id + integer :: i + real(wp), dimension(3, 3, 3) :: rotation - real(wp) :: angle + real(wp) :: angle ! construct the x, y, and z rotation matrices - if (num_dims == 3) then ! also compute the x and y axes in 3D angle = patch_ib(patch_id)%angles(1) - rotation(1, 1,:) = [1._wp, 0._wp, 0._wp] - rotation(1, 2,:) = [0._wp, cos(angle), -sin(angle)] - rotation(1, 3,:) = [0._wp, sin(angle), cos(angle)] + rotation(1, 1, :) = [1._wp, 0._wp, 0._wp] + rotation(1, 2, :) = [0._wp, cos(angle), -sin(angle)] + rotation(1, 3, :) = [0._wp, sin(angle), cos(angle)] angle = patch_ib(patch_id)%angles(2) - rotation(2, 1,:) = [cos(angle), 0._wp, sin(angle)] - rotation(2, 2,:) = [0._wp, 1._wp, 0._wp] - rotation(2, 3,:) = [-sin(angle), 0._wp, cos(angle)] + rotation(2, 1, :) = [cos(angle), 0._wp, sin(angle)] + rotation(2, 2, :) = [0._wp, 1._wp, 0._wp] + rotation(2, 3, :) = [-sin(angle), 0._wp, cos(angle)] ! apply the y rotation to the x rotation - patch_ib(patch_id)%rotation_matrix(:,:) = matmul(rotation(1,:,:), rotation(2,:,:)) - patch_ib(patch_id)%rotation_matrix_inverse(:,:) = matmul(transpose(rotation(2,:,:)), transpose(rotation(1,:,:))) + patch_ib(patch_id)%rotation_matrix(:, :) = matmul(rotation(1, :, :), rotation(2, :, :)) + patch_ib(patch_id)%rotation_matrix_inverse(:, :) = matmul(transpose(rotation(2, :, :)), transpose(rotation(1, :, :))) end if ! z component first, since it applies in 2D and 3D angle = patch_ib(patch_id)%angles(3) - rotation(3, 1,:) = [cos(angle), -sin(angle), 0._wp] - rotation(3, 2,:) = [sin(angle), cos(angle), 0._wp] - rotation(3, 3,:) = [0._wp, 0._wp, 1._wp] + rotation(3, 1, :) = [cos(angle), -sin(angle), 0._wp] + rotation(3, 2, :) = [sin(angle), cos(angle), 0._wp] + rotation(3, 3, :) = [0._wp, 0._wp, 1._wp] if (num_dims == 3) then ! apply the z rotation to the xy rotation in 3D - patch_ib(patch_id)%rotation_matrix(:,:) = matmul(patch_ib(patch_id)%rotation_matrix(:,:), rotation(3,:,:)) - patch_ib(patch_id)%rotation_matrix_inverse(:,:) = matmul(transpose(rotation(3,:,:)), & - & patch_ib(patch_id)%rotation_matrix_inverse(:,:)) + patch_ib(patch_id)%rotation_matrix(:, :) = matmul(patch_ib(patch_id)%rotation_matrix(:, :), rotation(3, :, :)) + patch_ib(patch_id)%rotation_matrix_inverse(:, :) = matmul(transpose(rotation(3, :, :)), patch_ib(patch_id)%rotation_matrix_inverse(:, :)) else ! write out only the z rotation in 2D - patch_ib(patch_id)%rotation_matrix(:,:) = rotation(3,:,:) - patch_ib(patch_id)%rotation_matrix_inverse(:,:) = transpose(rotation(3,:,:)) + patch_ib(patch_id)%rotation_matrix(:, :) = rotation(3, :, :) + patch_ib(patch_id)%rotation_matrix_inverse(:, :) = transpose(rotation(3, :, :)) end if end subroutine s_update_ib_rotation_matrix - !> Convert cylindrical (r, theta) coordinates to Cartesian (y, z) + !> @brief Converts cylindrical (r, theta) coordinates to Cartesian (y, z) and stores in module variables. subroutine s_convert_cylindrical_to_cartesian_coord(cyl_y, cyl_z) - $:GPU_ROUTINE(parallelism='[seq]') real(wp), intent(in) :: cyl_y, cyl_z @@ -990,24 +1115,25 @@ contains end subroutine s_convert_cylindrical_to_cartesian_coord - !> Convert a 3D cylindrical coordinate vector (x, r, theta) to Cartesian (x, y, z) + !> @brief Converts a 3D cylindrical coordinate vector (x, r, theta) to Cartesian (x, y, z). pure function f_convert_cyl_to_cart(cyl) result(cart) $:GPU_ROUTINE(parallelism='[seq]') real(wp), dimension(1:3), intent(in) :: cyl - real(wp), dimension(1:3) :: cart + real(wp), dimension(1:3) :: cart - cart = (/cyl(1), cyl(2)*sin(cyl(3)), cyl(2)*cos(cyl(3))/) + cart = (/cyl(1), & + cyl(2)*sin(cyl(3)), & + cyl(2)*cos(cyl(3))/) end function f_convert_cyl_to_cart - !> Convert cylindrical coordinates (x, r) to the spherical azimuthal angle phi + !> @brief Converts cylindrical coordinates (x, r) to the spherical azimuthal angle phi and stores in a module variable. subroutine s_convert_cylindrical_to_spherical_coord(cyl_x, cyl_y) - $:GPU_ROUTINE(parallelism='[seq]') - real(wp), intent(in) :: cyl_x, cyl_y + real(wp), intent(IN) :: cyl_x, cyl_y sph_phi = atan(cyl_y/cyl_x) @@ -1015,10 +1141,11 @@ contains subroutine get_bounding_indices(left_bound, right_bound, cell_centers, left_index, right_index) - real(wp), intent(in) :: left_bound, right_bound - integer, intent(inout) :: left_index, right_index + real(wp), intent(in) :: left_bound, right_bound + integer, intent(inout) :: left_index, right_index real(wp), dimension(-buff_size:), intent(in) :: cell_centers - integer :: itr_left, itr_middle, itr_right + + integer :: itr_left, itr_middle, itr_right itr_left = left_index itr_right = right_index @@ -1052,12 +1179,13 @@ contains end subroutine get_bounding_indices - !> Encode the patch ID with a unique offset containing periodicity information + !> @brief encodes the patch id with a unique offset that contains information on how the IB marker wraps periodically subroutine s_encode_patch_periodicity(patch_id, x_periodicity, y_periodicity, z_periodicity, encoded_patch_id) - integer, intent(in) :: patch_id, x_periodicity, y_periodicity, z_periodicity + integer, intent(in) :: patch_id, x_periodicity, y_periodicity, z_periodicity integer, intent(out) :: encoded_patch_id - integer :: temp_x_per, temp_y_per, temp_z_per, offset + + integer :: temp_x_per, temp_y_per, temp_z_per, offset encoded_patch_id = patch_id @@ -1070,14 +1198,15 @@ contains end subroutine s_encode_patch_periodicity - !> Decode the encoded ID to recover the original patch ID and periodicity + !> @brief decodes the encoded id to get out the original id and the way in which it is periodic subroutine s_decode_patch_periodicity(encoded_patch_id, patch_id, x_periodicity, y_periodicity, z_periodicity) $:GPU_ROUTINE(parallelism='[seq]') - integer, intent(in) :: encoded_patch_id + integer, intent(in) :: encoded_patch_id integer, intent(out) :: patch_id, x_periodicity, y_periodicity, z_periodicity - integer :: offset, remainder, xp, yp, zp, base + + integer :: offset, remainder, xp, yp, zp, base base = num_ibs + 1 @@ -1096,53 +1225,43 @@ contains end subroutine s_decode_patch_periodicity - !> Determine the periodic wrapping bounds in each direction + !> @brief Determines if we should wrap periodically subroutine s_get_periodicities(xp_lower, xp_upper, yp_lower, yp_upper, zp_lower, zp_upper) - integer, intent(out) :: xp_lower, xp_upper, yp_lower, yp_upper + integer, intent(out) :: xp_lower, xp_upper, yp_lower, yp_upper integer, intent(out), optional :: zp_lower, zp_upper ! check domain wraps in x, y - - #:for X in [('x'), ('y')] - ! check for periodicity - - if (bc_${X}$%beg == BC_PERIODIC) then - ${X}$p_lower = -1 - ${X}$p_upper = 1 - else - ! if it is not periodic, then both elements are 0 - ${X}$p_lower = 0 - ${X}$p_upper = 0 + #:for X, ID in [('x', 1), ('y', 2), ('z', 3)] + if (num_dims >= ${ID}$) then + ! check for periodicity + if (bc_${X}$%beg == BC_PERIODIC) then + ${X}$p_lower = -1 + ${X}$p_upper = 1 + else + !if it is not periodic, then both elements are 0 + ${X}$p_lower = 0 + ${X}$p_upper = 0 + end if end if #:endfor - ! z only if 3D - if (present(zp_lower) .and. p /= 0) then - if (bc_z%beg == BC_PERIODIC) then - zp_lower = -1 - zp_upper = 1 - else - zp_lower = 0 - zp_upper = 0 - end if - end if - end subroutine s_get_periodicities !> Archimedes spiral function + !! @param myth Angle + !! @param offset Thickness + !! @param a Starting position pure elemental function f_r(myth, offset, a) - $:GPU_ROUTINE(parallelism='[seq]') real(wp), intent(in) :: myth, offset, a - real(wp) :: b - real(wp) :: f_r + real(wp) :: b + real(wp) :: f_r - ! r(th) = a + b*th + !r(th) = a + b*th b = 2._wp*a/(2._wp*pi) f_r = a + b*myth + offset - end function f_r end module m_ib_patches diff --git a/src/simulation/m_ibm.fpp b/src/simulation/m_ibm.fpp index 785bf2dec3..109babdf68 100644 --- a/src/simulation/m_ibm.fpp +++ b/src/simulation/m_ibm.fpp @@ -4,27 +4,42 @@ #:include 'macros.fpp' -!> @brief Ghost-node immersed boundary method: locates ghost/image points, computes interpolation coefficients, and corrects the -!! flow state +!> @brief Ghost-node immersed boundary method: locates ghost/image points, computes interpolation coefficients, and corrects the flow state module m_ibm - use m_derived_types - use m_global_parameters - use m_mpi_proxy - use m_variables_conversion + use m_derived_types !< Definitions of the derived types + + use m_global_parameters !< Definitions of the global parameters + + use m_mpi_proxy !< Message passing interface (MPI) module proxy + + use m_variables_conversion !< State variables type conversion procedures + use m_helper - use m_helper_basic + + use m_helper_basic !< Functions to compare floating point numbers + use m_constants + use m_compute_levelset + use m_ib_patches + use m_viscous + use m_model implicit none - private :: s_compute_image_points, s_compute_interpolation_coeffs, s_interpolate_image_point, s_find_ghost_points, & - & s_find_num_ghost_points - ; public :: s_initialize_ibm_module, s_ibm_setup, s_ibm_correct_state, s_finalize_ibm_module + private :: s_compute_image_points, & + s_compute_interpolation_coeffs, & + s_interpolate_image_point, & + s_find_ghost_points, & + s_find_num_ghost_points + ; public :: s_initialize_ibm_module, & + s_ibm_setup, & + s_ibm_correct_state, & + s_finalize_ibm_module type(integer_field), public :: ib_markers $:GPU_DECLARE(create='[ib_markers]') @@ -32,9 +47,9 @@ module m_ibm type(ghost_point), dimension(:), allocatable :: ghost_points $:GPU_DECLARE(create='[ghost_points]') - integer :: num_gps !< Number of ghost points + integer :: num_gps !< Number of ghost points #if defined(MFC_OpenACC) - $:GPU_DECLARE(create='[gp_layers, num_gps]') + $:GPU_DECLARE(create='[gp_layers,num_gps]') #elif defined(MFC_OpenMP) $:GPU_DECLARE(create='[num_gps]') #endif @@ -42,13 +57,15 @@ module m_ibm contains - !> Allocates memory for the variables in the IBM module + !> Allocates memory for the variables in the IBM module impure subroutine s_initialize_ibm_module() if (p > 0) then - @:ALLOCATE(ib_markers%sf(-buff_size:m+buff_size, -buff_size:n+buff_size, -buff_size:p+buff_size)) + @:ALLOCATE(ib_markers%sf(-buff_size:m+buff_size, & + -buff_size:n+buff_size, -buff_size:p+buff_size)) else - @:ALLOCATE(ib_markers%sf(-buff_size:m+buff_size, -buff_size:n+buff_size, 0:0)) + @:ALLOCATE(ib_markers%sf(-buff_size:m+buff_size, & + -buff_size:n+buff_size, 0:0)) end if @:ALLOCATE(models(num_ibs)) @@ -59,7 +76,8 @@ contains end subroutine s_initialize_ibm_module - !> Initializes the values of various IBM variables, such as ghost points and image points. + !> Initializes the values of various IBM variables, such as ghost points and + !! image points. impure subroutine s_ibm_setup() integer :: i, j, k @@ -79,10 +97,11 @@ contains $:GPU_UPDATE(device='[patch_ib(1:num_ibs)]') ! GPU routines require updated cell centers - $:GPU_UPDATE(device='[num_ibs, x_cc, y_cc, dx, dy, x_domain, y_domain]') + $:GPU_UPDATE(device='[num_ibs, x_cc, y_cc, dx, dy]') if (p /= 0) then - $:GPU_UPDATE(device='[z_cc, dz, z_domain]') + $:GPU_UPDATE(device='[z_cc, dz]') end if + $:GPU_UPDATE(device='[glb_bounds]') ! allocate STL models call s_instantiate_STL_models() @@ -93,7 +112,7 @@ contains call s_apply_ib_patches(ib_markers) $:GPU_UPDATE(host='[ib_markers%sf]') do i = 1, num_ibs - if (patch_ib(i)%moving_ibm /= 0) call s_compute_centroid_offset(i) ! offsets are computed after IB markers are generated + if (patch_ib(i)%moving_ibm /= 0) call s_compute_centroid_offset(i) ! offsets are computed after IB markers are generated $:GPU_UPDATE(device='[patch_ib(i)]') end do @@ -111,7 +130,6 @@ contains @:ALLOCATE(ghost_points(1:max_num_gps)) $:GPU_ENTER_DATA(copyin='[ghost_points]') - ! Ghost-cell IBM, Tseng & Ferziger JCP (2003), Mittal & Iaccarino ARFM (2005) call s_find_ghost_points(ghost_points) call s_apply_levelset(ghost_points, num_gps) @@ -122,50 +140,60 @@ contains end subroutine s_ibm_setup - !> Update the conservative variables at the ghost points + !> Subroutine that updates the conservative variables at the ghost points + !! @param pb_in Internal bubble pressure + !! @param mv_in Mass of vapor in bubble subroutine s_ibm_correct_state(q_cons_vf, q_prim_vf, pb_in, mv_in) - type(scalar_field), dimension(sys_size), intent(inout) :: q_cons_vf !< Primitive Variables - type(scalar_field), dimension(sys_size), intent(inout) :: q_prim_vf !< Primitive Variables - real(stp), dimension(idwbuff(1)%beg:,idwbuff(2)%beg:,idwbuff(3)%beg:,1:,1:), optional, intent(inout) :: pb_in, mv_in - integer :: i, j, k, l, q, r !< Iterator variables - integer :: patch_id !< Patch ID of ghost point - real(wp) :: rho, gamma, pi_inf, dyn_pres !< Mixture variables + type(scalar_field), & + dimension(sys_size), & + intent(INOUT) :: q_cons_vf !< Primitive Variables + + type(scalar_field), & + dimension(sys_size), & + intent(INOUT) :: q_prim_vf !< Primitive Variables + + real(stp), dimension(idwbuff(1)%beg:, idwbuff(2)%beg:, idwbuff(3)%beg:, 1:, 1:), optional, intent(INOUT) :: pb_in, mv_in + + integer :: i, j, k, l, q, r!< Iterator variables + integer :: patch_id !< Patch ID of ghost point + real(wp) :: rho, gamma, pi_inf, dyn_pres !< Mixture variables real(wp), dimension(2) :: Re_K real(wp) :: G_K real(wp) :: qv_K + real(wp) :: pres_IP real(wp), dimension(3) :: vel_IP, vel_norm_IP real(wp) :: c_IP - #:if not MFC_CASE_OPTIMIZATION and USING_AMD - real(wp), dimension(3) :: Gs - real(wp), dimension(3) :: alpha_rho_IP, alpha_IP - real(wp), dimension(3) :: r_IP, v_IP, pb_IP, mv_IP + real(wp), dimension(3) :: Gs + real(wp), dimension(3) :: alpha_rho_IP, alpha_IP + real(wp), dimension(3) :: r_IP, v_IP, pb_IP, mv_IP real(wp), dimension(18) :: nmom_IP real(wp), dimension(12) :: presb_IP, massv_IP #:else real(wp), dimension(num_fluids) :: Gs real(wp), dimension(num_fluids) :: alpha_rho_IP, alpha_IP - real(wp), dimension(nb) :: r_IP, v_IP, pb_IP, mv_IP - real(wp), dimension(nb*nmom) :: nmom_IP - real(wp), dimension(nb*nnode) :: presb_IP, massv_IP + real(wp), dimension(nb) :: r_IP, v_IP, pb_IP, mv_IP + real(wp), dimension(nb*nmom) :: nmom_IP + real(wp), dimension(nb*nnode) :: presb_IP, massv_IP #:endif - ! Primitive variables at the image point associated with a ghost point, interpolated from surrounding fluid cells. - - real(wp), dimension(3) :: norm !< Normal vector from GP to IP - real(wp), dimension(3) :: physical_loc !< Physical loc of GP - real(wp), dimension(3) :: vel_g !< Velocity of GP - real(wp), dimension(3) :: radial_vector !< vector from centroid to ghost point - real(wp), dimension(3) :: rotation_velocity !< speed of the ghost point due to rotation - real(wp) :: nbub - real(wp) :: buf - type(ghost_point) :: gp - type(ghost_point) :: innerp + !! Primitive variables at the image point associated with a ghost point, + !! interpolated from surrounding fluid cells. - ! set the Moving IBM interior conservative variables + real(wp), dimension(3) :: norm !< Normal vector from GP to IP + real(wp), dimension(3) :: physical_loc !< Physical loc of GP + real(wp), dimension(3) :: vel_g !< Velocity of GP + real(wp), dimension(3) :: radial_vector !< vector from centroid to ghost point + real(wp), dimension(3) :: rotation_velocity !< speed of the ghost point due to rotation + + real(wp) :: nbub + real(wp) :: buf + type(ghost_point) :: gp + type(ghost_point) :: innerp - $:GPU_PARALLEL_LOOP(private='[i, j, k, patch_id, rho]', copyin='[E_idx, momxb]', collapse=3) + ! set the Moving IBM interior conservative variables + $:GPU_PARALLEL_LOOP(private='[i,j,k,patch_id,rho]', copyin='[E_idx,momxb]', collapse=3) do l = 0, p do k = 0, n do j = 0, m @@ -189,10 +217,9 @@ contains $:END_GPU_PARALLEL_LOOP() if (num_gps > 0) then - $:GPU_PARALLEL_LOOP(private='[i, physical_loc, dyn_pres, alpha_rho_IP, alpha_IP, pres_IP, vel_IP, vel_g, vel_norm_IP, & - & r_IP, v_IP, pb_IP, mv_IP, nmom_IP, presb_IP, massv_IP, rho, gamma, pi_inf, Re_K, G_K, Gs, gp, & - & innerp, norm, buf, radial_vector, rotation_velocity, j, k, l, q, qv_K, c_IP, nbub, patch_id]') + $:GPU_PARALLEL_LOOP(private='[i,physical_loc,dyn_pres,alpha_rho_IP, alpha_IP,pres_IP,vel_IP,vel_g,vel_norm_IP,r_IP, v_IP,pb_IP,mv_IP,nmom_IP,presb_IP,massv_IP,rho, gamma,pi_inf,Re_K,G_K,Gs,gp,innerp,norm,buf, radial_vector, rotation_velocity, j,k,l,q,qv_K,c_IP,nbub,patch_id]') do i = 1, num_gps + gp = ghost_points(i) j = gp%loc(1) k = gp%loc(2) @@ -206,18 +233,22 @@ contains physical_loc = [x_cc(j), y_cc(k), 0._wp] end if - ! Interpolate primitive variables at image point associated w/ GP + !Interpolate primitive variables at image point associated w/ GP if (bubbles_euler .and. .not. qbmm) then - call s_interpolate_image_point(q_prim_vf, gp, alpha_rho_IP, alpha_IP, pres_IP, vel_IP, c_IP, r_IP, v_IP, & - & pb_IP, mv_IP) + call s_interpolate_image_point(q_prim_vf, gp, & + alpha_rho_IP, alpha_IP, pres_IP, vel_IP, c_IP, & + r_IP, v_IP, pb_IP, mv_IP) else if (qbmm .and. polytropic) then - call s_interpolate_image_point(q_prim_vf, gp, alpha_rho_IP, alpha_IP, pres_IP, vel_IP, c_IP, r_IP, v_IP, & - & pb_IP, mv_IP, nmom_IP) + call s_interpolate_image_point(q_prim_vf, gp, & + alpha_rho_IP, alpha_IP, pres_IP, vel_IP, c_IP, & + r_IP, v_IP, pb_IP, mv_IP, nmom_IP) else if (qbmm .and. .not. polytropic) then - call s_interpolate_image_point(q_prim_vf, gp, alpha_rho_IP, alpha_IP, pres_IP, vel_IP, c_IP, r_IP, v_IP, & - & pb_IP, mv_IP, nmom_IP, pb_in, mv_in, presb_IP, massv_IP) + call s_interpolate_image_point(q_prim_vf, gp, & + alpha_rho_IP, alpha_IP, pres_IP, vel_IP, c_IP, & + r_IP, v_IP, pb_IP, mv_IP, nmom_IP, pb_in, mv_in, presb_IP, massv_IP) else - call s_interpolate_image_point(q_prim_vf, gp, alpha_rho_IP, alpha_IP, pres_IP, vel_IP, c_IP) + call s_interpolate_image_point(q_prim_vf, gp, & + alpha_rho_IP, alpha_IP, pres_IP, vel_IP, c_IP) end if dyn_pres = 0._wp @@ -240,20 +271,19 @@ contains q_prim_vf(E_idx)%sf(j, k, l) = 0._wp $:GPU_LOOP(parallelism='[seq]') do q = 1, num_fluids - ! Pressure correction for moving IB: accounts for acceleration of IB surface - q_prim_vf(E_idx)%sf(j, k, l) = q_prim_vf(E_idx)%sf(j, k, & - & l) + pres_IP/(1._wp - 2._wp*abs(gp%levelset*alpha_rho_IP(q)/pres_IP) & - & *dot_product(patch_ib(patch_id) %force/patch_ib(patch_id)%mass, gp%levelset_norm)) + ! Se the pressure inside a moving immersed boundary based upon the pressure of the image point. acceleration, and normal vector direction + q_prim_vf(E_idx)%sf(j, k, l) = q_prim_vf(E_idx)%sf(j, k, l) + pres_IP/(1._wp - 2._wp*abs(gp%levelset*alpha_rho_IP(q)/pres_IP)*dot_product(patch_ib(patch_id)%force/patch_ib(patch_id)%mass, gp%levelset_norm)) end do end if if (model_eqns /= 4) then ! If in simulation, use acc mixture subroutines if (elasticity) then - call s_convert_species_to_mixture_variables_acc(rho, gamma, pi_inf, qv_K, alpha_IP, alpha_rho_IP, Re_K, & - & G_K, Gs) + call s_convert_species_to_mixture_variables_acc(rho, gamma, pi_inf, qv_K, alpha_IP, & + alpha_rho_IP, Re_K, G_K, Gs) else - call s_convert_species_to_mixture_variables_acc(rho, gamma, pi_inf, qv_K, alpha_IP, alpha_rho_IP, Re_K) + call s_convert_species_to_mixture_variables_acc(rho, gamma, pi_inf, qv_K, alpha_IP, & + alpha_rho_IP, Re_K) end if end if @@ -266,10 +296,9 @@ contains vel_g = vel_IP - vel_norm_IP if (patch_ib(patch_id)%moving_ibm /= 0) then ! compute the linear velocity of the ghost point due to rotation - radial_vector = physical_loc - [patch_ib(patch_id)%x_centroid, patch_ib(patch_id)%y_centroid, & - & patch_ib(patch_id)%z_centroid] - call s_cross_product(matmul(patch_ib(patch_id)%rotation_matrix, patch_ib(patch_id)%angular_vel), & - & radial_vector, rotation_velocity) + radial_vector = physical_loc - [patch_ib(patch_id)%x_centroid, & + patch_ib(patch_id)%y_centroid, patch_ib(patch_id)%z_centroid] + call s_cross_product(matmul(patch_ib(patch_id)%rotation_matrix, patch_ib(patch_id)%angular_vel), radial_vector, rotation_velocity) ! add only the component of the IB's motion that is normal to the surface vel_g = vel_g + sum((patch_ib(patch_id)%vel + rotation_velocity)*norm)*norm @@ -280,16 +309,14 @@ contains vel_g = 0._wp else ! get the vector that points from the centroid to the ghost - radial_vector = physical_loc - [patch_ib(patch_id)%x_centroid, patch_ib(patch_id)%y_centroid, & - & patch_ib(patch_id)%z_centroid] - ! convert the angular velocity from the inertial reference frame to the fluids frame, then convert to linear - ! velocity - call s_cross_product(matmul(patch_ib(patch_id)%rotation_matrix, patch_ib(patch_id)%angular_vel), & - & radial_vector, rotation_velocity) + radial_vector = physical_loc - [patch_ib(patch_id)%x_centroid, & + patch_ib(patch_id)%y_centroid, patch_ib(patch_id)%z_centroid] + ! convert the angular velocity from the inertial reference frame to the fluids frame, then convert to linear velocity + call s_cross_product(matmul(patch_ib(patch_id)%rotation_matrix, patch_ib(patch_id)%angular_vel), radial_vector, rotation_velocity) do q = 1, 3 ! if mibm is 1 or 2, then the boundary may be moving - vel_g(q) = patch_ib(patch_id)%vel(q) ! add the linear velocity - vel_g(q) = vel_g(q) + rotation_velocity(q) ! add the rotational velocity + vel_g(q) = patch_ib(patch_id)%vel(q) ! add the linear velocity + vel_g(q) = vel_g(q) + rotation_velocity(q) ! add the rotational velocity end do end if end if @@ -298,7 +325,8 @@ contains $:GPU_LOOP(parallelism='[seq]') do q = momxb, momxe q_cons_vf(q)%sf(j, k, l) = rho*vel_g(q - momxb + 1) - dyn_pres = dyn_pres + q_cons_vf(q)%sf(j, k, l)*vel_g(q - momxb + 1)/2._wp + dyn_pres = dyn_pres + q_cons_vf(q)%sf(j, k, l)* & + vel_g(q - momxb + 1)/2._wp end do ! Set continuity and adv vars @@ -336,6 +364,7 @@ contains end if if (qbmm) then + nbub = nmom_IP(1) $:GPU_LOOP(parallelism='[seq]') do q = 1, nb*nmom @@ -362,7 +391,8 @@ contains if (model_eqns == 3) then $:GPU_LOOP(parallelism='[seq]') do q = intxb, intxe - q_cons_vf(q)%sf(j, k, l) = alpha_IP(q - intxb + 1)*(gammas(q - intxb + 1)*pres_IP + pi_infs(q - intxb + 1)) + q_cons_vf(q)%sf(j, k, l) = alpha_IP(q - intxb + 1)*(gammas(q - intxb + 1)*pres_IP & + + pi_infs(q - intxb + 1)) end do end if end do @@ -371,28 +401,30 @@ contains end subroutine s_ibm_correct_state - !> Compute the image points for each ghost point + !> Function that computes the image points for each ghost point + !! @param ghost_points_in Ghost Points impure subroutine s_compute_image_points(ghost_points_in) - type(ghost_point), dimension(num_gps), intent(inout) :: ghost_points_in - real(wp) :: dist - real(wp), dimension(3) :: norm - real(wp), dimension(3) :: physical_loc - real(wp) :: temp_loc - real(wp), pointer, dimension(:) :: s_cc => null() - integer :: bound - type(ghost_point) :: gp - integer :: q, dim !< Iterator variables - integer :: i, j, k, l !< Location indexes - integer :: patch_id !< IB Patch ID - integer :: dir - integer :: index - logical :: bounds_error + type(ghost_point), dimension(num_gps), intent(INOUT) :: ghost_points_in + + real(wp) :: dist + real(wp), dimension(3) :: norm + real(wp), dimension(3) :: physical_loc + real(wp) :: temp_loc + real(wp), pointer, dimension(:) :: s_cc => null() + integer :: bound + type(ghost_point) :: gp + + integer :: q, dim !< Iterator variables + integer :: i, j, k, l !< Location indexes + integer :: patch_id !< IB Patch ID + integer :: dir + integer :: index + logical :: bounds_error bounds_error = .false. - $:GPU_PARALLEL_LOOP(private='[q, gp, i, j, k, physical_loc, patch_id, dist, norm, dim, bound, dir, index, temp_loc, & - & s_cc]', copy='[bounds_error]') + $:GPU_PARALLEL_LOOP(private='[q,gp,i,j,k,physical_loc,patch_id,dist,norm,dim,bound,dir,index,temp_loc,s_cc]', copy='[bounds_error]') do q = 1, num_gps gp = ghost_points_in(q) i = gp%loc(1) @@ -414,11 +446,12 @@ contains ! Find the closest grid point to the image point do dim = 1, num_dims + ! s_cc points to the dim array we need if (dim == 1) then s_cc => x_cc bound = m + buff_size - 1 - else if (dim == 2) then + elseif (dim == 2) then s_cc => y_cc bound = n + buff_size - 1 else @@ -438,7 +471,8 @@ contains index = ghost_points_in(q)%loc(dim) temp_loc = ghost_points_in(q)%ip_loc(dim) - do while ((temp_loc < s_cc(index) .or. temp_loc > s_cc(index + 1)) .and. (.not. bounds_error)) + do while ((temp_loc < s_cc(index) & + .or. temp_loc > s_cc(index + 1)) .and. (.not. bounds_error)) index = index + dir if (index < -buff_size .or. index > bound) then #if !defined(MFC_OpenACC) && !defined(MFC_OpenMP) @@ -450,16 +484,13 @@ contains print *, [x_cc(i), y_cc(j), z_cc(k)] end if print *, "We are searching in dimension ", dim, " for image point at ", ghost_points_in(q)%ip_loc(:) - print *, "Domain size: ", [x_cc(-buff_size), y_cc(-buff_size), z_cc(-buff_size)] + print *, "Domain size: " print *, "x: ", x_cc(-buff_size), " to: ", x_cc(m + buff_size - 1) print *, "y: ", y_cc(-buff_size), " to: ", y_cc(n + buff_size - 1) if (p /= 0) print *, "z: ", z_cc(-buff_size), " to: ", z_cc(p + buff_size - 1) - print *, "Image point is located approximately ", & - & (ghost_points_in(q)%loc(dim) - ghost_points_in(q) %ip_loc(dim))/(s_cc(1) - s_cc(0)), & - & " grid cells away" + print *, "Image point is located approximately ", (ghost_points_in(q)%loc(dim) - ghost_points_in(q)%ip_loc(dim))/(s_cc(1) - s_cc(0)), " grid cells away" print *, "Levelset ", dist, " and Norm: ", norm(:) - print *, & - & "A short term fix may include increasing buff_size further in m_helper_basic (currently set to a minimum of 10)" + print *, "A short term fix may include increasing buff_size further in m_helper_basic (currently set to a minimum of 10)" #endif bounds_error = .true. end if @@ -480,20 +511,21 @@ contains end subroutine s_compute_image_points - !> Count the number of ghost points for memory allocation + !> Subroutine that finds the number of ghost points, used for allocating + !! memory. subroutine s_find_num_ghost_points(num_gps_out) integer, intent(out) :: num_gps_out - integer :: i, j, k, ii, jj, kk, gp_layers_z !< Iterator variables - integer :: num_gps_local !< local copies of the gp count to support GPU compute - logical :: is_gp + + integer :: i, j, k, ii, jj, kk, gp_layers_z !< Iterator variables + integer :: num_gps_local !< local copies of the gp count to support GPU compute + logical :: is_gp num_gps_local = 0 gp_layers_z = gp_layers if (p == 0) gp_layers_z = 0 - $:GPU_PARALLEL_LOOP(private='[i, j, k, ii, jj, kk, is_gp]', copy='[num_gps_local]', firstprivate='[gp_layers, & - & gp_layers_z]', collapse=3) + $:GPU_PARALLEL_LOOP(private='[i,j,k,ii,jj,kk,is_gp]', copy='[num_gps_local]', firstprivate='[gp_layers,gp_layers_z]', collapse=3) do i = 0, m do j = 0, n do k = 0, p @@ -525,24 +557,22 @@ contains end subroutine s_find_num_ghost_points - !> Locate all ghost points in the domain + !> Function that finds the ghost points subroutine s_find_ghost_points(ghost_points_in) - type(ghost_point), dimension(num_gps), intent(inout) :: ghost_points_in - integer :: i, j, k, ii, jj, kk, gp_layers_z !< Iterator variables - integer :: xp, yp, zp !< periodicities - integer :: count, count_i, local_idx - integer :: patch_id, encoded_patch_id - logical :: is_gp + type(ghost_point), dimension(num_gps), intent(INOUT) :: ghost_points_in + integer :: i, j, k, ii, jj, kk, gp_layers_z !< Iterator variables + integer :: xp, yp, zp !< periodicities + integer :: count, count_i, local_idx + integer :: patch_id, encoded_patch_id + logical :: is_gp count = 0 count_i = 0 gp_layers_z = gp_layers if (p == 0) gp_layers_z = 0 - $:GPU_PARALLEL_LOOP(private='[i, j, k, ii, jj, kk, is_gp, local_idx, patch_id, encoded_patch_id, xp, yp, zp]', & - & copyin='[count, count_i, x_domain, y_domain, z_domain]', firstprivate='[gp_layers, gp_layers_z]', & - & collapse=3) + $:GPU_PARALLEL_LOOP(private='[i,j,k,ii,jj,kk,is_gp,local_idx,patch_id,encoded_patch_id,xp,yp,zp]', copyin='[count,count_i,glb_bounds]', firstprivate='[gp_layers,gp_layers_z]', collapse=3) do i = 0, m do j = 0, n do k = 0, p @@ -576,26 +606,26 @@ contains ghost_points_in(local_idx)%z_periodicity = zp ghost_points_in(local_idx)%slip = patch_ib(patch_id)%slip - if ((x_cc(i) - dx(i)) < x_domain%beg) then + if ((x_cc(i) - dx(i)) < glb_bounds(1)%beg) then ghost_points_in(local_idx)%DB(1) = -1 - else if ((x_cc(i) + dx(i)) > x_domain%end) then + else if ((x_cc(i) + dx(i)) > glb_bounds(1)%end) then ghost_points_in(local_idx)%DB(1) = 1 else ghost_points_in(local_idx)%DB(1) = 0 end if - if ((y_cc(j) - dy(j)) < y_domain%beg) then + if ((y_cc(j) - dy(j)) < glb_bounds(2)%beg) then ghost_points_in(local_idx)%DB(2) = -1 - else if ((y_cc(j) + dy(j)) > y_domain%end) then + else if ((y_cc(j) + dy(j)) > glb_bounds(2)%end) then ghost_points_in(local_idx)%DB(2) = 1 else ghost_points_in(local_idx)%DB(2) = 0 end if if (p /= 0) then - if ((z_cc(k) - dz(k)) < z_domain%beg) then + if ((z_cc(k) - dz(k)) < glb_bounds(3)%beg) then ghost_points_in(local_idx)%DB(3) = -1 - else if ((z_cc(k) + dz(k)) > z_domain%end) then + else if ((z_cc(k) + dz(k)) > glb_bounds(3)%end) then ghost_points_in(local_idx)%DB(3) = 1 else ghost_points_in(local_idx)%DB(3) = 0 @@ -610,21 +640,22 @@ contains end subroutine s_find_ghost_points - !> Compute the interpolation coefficients for image points + !> Function that computes the interpolation coefficients of image points subroutine s_compute_interpolation_coeffs(ghost_points_in) - type(ghost_point), dimension(num_gps), intent(inout) :: ghost_points_in - real(wp), dimension(2, 2, 2) :: dist - real(wp), dimension(2, 2, 2) :: alpha - real(wp), dimension(2, 2, 2) :: interp_coeffs - real(wp) :: buf - real(wp), dimension(2, 2, 2) :: eta - type(ghost_point) :: gp - integer :: q, i, j, k, ii, jj, kk !< Grid indexes and iterators - integer :: patch_id - logical :: is_cell_center - - $:GPU_PARALLEL_LOOP(private='[q, i, j, k, ii, jj, kk, dist, buf, gp, interp_coeffs, eta, alpha, patch_id, is_cell_center]') + type(ghost_point), dimension(num_gps), intent(INOUT) :: ghost_points_in + + real(wp), dimension(2, 2, 2) :: dist + real(wp), dimension(2, 2, 2) :: alpha + real(wp), dimension(2, 2, 2) :: interp_coeffs + real(wp) :: buf + real(wp), dimension(2, 2, 2) :: eta + type(ghost_point) :: gp + integer :: q, i, j, k, ii, jj, kk !< Grid indexes and iterators + integer :: patch_id + logical is_cell_center + + $:GPU_PARALLEL_LOOP(private='[q,i,j,k,ii,jj,kk,dist,buf,gp,interp_coeffs,eta,alpha,patch_id,is_cell_center]') do q = 1, num_gps gp = ghost_points_in(q) ! Get the interpolation points @@ -633,7 +664,7 @@ contains if (p /= 0) then k = gp%ip_grid(3) else - k = 0 + k = 0; end if ! get the distance to a cell in each direction @@ -642,12 +673,15 @@ contains do ii = 0, 1 do jj = 0, 1 if (p == 0) then - dist(1 + ii, 1 + jj, 1) = sqrt((x_cc(i + ii) - gp%ip_loc(1))**2 + (y_cc(j + jj) - gp%ip_loc(2))**2) + dist(1 + ii, 1 + jj, 1) = sqrt( & + (x_cc(i + ii) - gp%ip_loc(1))**2 + & + (y_cc(j + jj) - gp%ip_loc(2))**2) else do kk = 0, 1 - dist(1 + ii, 1 + jj, & - & 1 + kk) = sqrt((x_cc(i + ii) - gp%ip_loc(1))**2 + (y_cc(j + jj) - gp%ip_loc(2))**2 + (z_cc(k & - & + kk) - gp%ip_loc(3))**2) + dist(1 + ii, 1 + jj, 1 + kk) = sqrt( & + (x_cc(i + ii) - gp%ip_loc(1))**2 + & + (y_cc(j + jj) - gp%ip_loc(2))**2 + & + (z_cc(k + kk) - gp%ip_loc(3))**2) end do end if end do @@ -684,15 +718,16 @@ contains if (ib_markers%sf(i + 1, j + 1, k) /= 0) alpha(2, 2, 1) = 0._wp if (p == 0) then - eta(:,:,1) = 1._wp/dist(:,:,1)**2 - buf = sum(alpha(:,:,1)*eta(:,:,1)) + eta(:, :, 1) = 1._wp/dist(:, :, 1)**2 + buf = sum(alpha(:, :, 1)*eta(:, :, 1)) if (buf > 0._wp) then - interp_coeffs(:,:,1) = alpha(:,:,1)*eta(:,:,1)/buf + interp_coeffs(:, :, 1) = alpha(:, :, 1)*eta(:, :, 1)/buf else - buf = sum(eta(:,:,1)) - interp_coeffs(:,:,1) = eta(:,:,1)/buf + buf = sum(eta(:, :, 1)) + interp_coeffs(:, :, 1) = eta(:, :, 1)/buf end if else + if (ib_markers%sf(i, j, k + 1) /= 0) alpha(1, 1, 2) = 0._wp if (ib_markers%sf(i + 1, j, k + 1) /= 0) alpha(2, 1, 2) = 0._wp if (ib_markers%sf(i, j + 1, k + 1) /= 0) alpha(1, 2, 2) = 0._wp @@ -707,6 +742,7 @@ contains interp_coeffs = eta/buf end if end if + end if ghost_points_in(q)%interp_coeffs = interp_coeffs @@ -715,28 +751,50 @@ contains end subroutine s_compute_interpolation_coeffs - !> Interpolate primitive variables to a ghost point's image point using bilinear or trilinear interpolation - subroutine s_interpolate_image_point(q_prim_vf, gp, alpha_rho_IP, alpha_IP, pres_IP, vel_IP, c_IP, r_IP, v_IP, pb_IP, mv_IP, & - - & nmom_IP, pb_in, mv_in, presb_IP, massv_IP) + !> Function that uses the interpolation coefficients and the current state + !! at the cell centers in order to estimate the state at the image point + !! @param gp Ghost point data structure + !> @brief Interpolates primitive variables from the fluid domain to a ghost point's image point using bilinear or trilinear interpolation. + !! @param alpha_rho_IP Partial density at image point + !! @param alpha_IP Volume fraction at image point + !! @param pres_IP Pressure at image point + !! @param vel_IP Velocity at image point + !! @param c_IP Speed of sound at image point + !! @param r_IP Bubble radius at image point + !! @param v_IP Bubble radial velocity at image point + !! @param pb_IP Bubble pressure at image point + !! @param mv_IP Bubble vapor mass at image point + !! @param nmom_IP Bubble moment at image point + !! @param pb_in Internal bubble pressure array + !! @param mv_in Mass of vapor in bubble array + !! @param presb_IP Bubble node pressure at image point + !! @param massv_IP Bubble node vapor mass at image point + subroutine s_interpolate_image_point(q_prim_vf, gp, alpha_rho_IP, alpha_IP, & + pres_IP, vel_IP, c_IP, r_IP, v_IP, pb_IP, & + mv_IP, nmom_IP, pb_in, mv_in, presb_IP, massv_IP) $:GPU_ROUTINE(parallelism='[seq]') - type(scalar_field), dimension(sys_size), intent(in) :: q_prim_vf !< Primitive Variables - real(stp), optional, dimension(idwbuff(1)%beg:,idwbuff(2)%beg:,idwbuff(3)%beg:,1:,1:), intent(in) :: pb_in, mv_in - type(ghost_point), intent(in) :: gp - real(wp), intent(inout) :: pres_IP - real(wp), dimension(3), intent(inout) :: vel_IP - real(wp), intent(inout) :: c_IP + type(scalar_field), & + dimension(sys_size), & + intent(IN) :: q_prim_vf !< Primitive Variables + + real(stp), optional, dimension(idwbuff(1)%beg:, idwbuff(2)%beg:, idwbuff(3)%beg:, 1:, 1:), intent(IN) :: pb_in, mv_in + + type(ghost_point), intent(IN) :: gp + real(wp), intent(INOUT) :: pres_IP + real(wp), dimension(3), intent(INOUT) :: vel_IP + real(wp), intent(INOUT) :: c_IP #:if not MFC_CASE_OPTIMIZATION and USING_AMD - real(wp), dimension(3), intent(inout) :: alpha_IP, alpha_rho_IP + real(wp), dimension(3), intent(INOUT) :: alpha_IP, alpha_rho_IP #:else - real(wp), dimension(num_fluids), intent(inout) :: alpha_IP, alpha_rho_IP + real(wp), dimension(num_fluids), intent(INOUT) :: alpha_IP, alpha_rho_IP #:endif - real(wp), optional, dimension(:), intent(inout) :: r_IP, v_IP, pb_IP, mv_IP - real(wp), optional, dimension(:), intent(inout) :: nmom_IP - real(wp), optional, dimension(:), intent(inout) :: presb_IP, massv_IP - integer :: i, j, k, l, q !< Iterator variables - integer :: i1, i2, j1, j2, k1, k2 !< Iterator variables - real(wp) :: coeff + real(wp), optional, dimension(:), intent(INOUT) :: r_IP, v_IP, pb_IP, mv_IP + real(wp), optional, dimension(:), intent(INOUT) :: nmom_IP + real(wp), optional, dimension(:), intent(INOUT) :: presb_IP, massv_IP + + integer :: i, j, k, l, q !< Iterator variables + integer :: i1, i2, j1, j2, k1, k2 !< Iterator variables + real(wp) :: coeff i1 = gp%ip_grid(1); i2 = i1 + 1 j1 = gp%ip_grid(2); j2 = j1 + 1 @@ -777,19 +835,24 @@ contains do j = j1, j2 $:GPU_LOOP(parallelism='[seq]') do k = k1, k2 + coeff = gp%interp_coeffs(i - i1 + 1, j - j1 + 1, k - k1 + 1) - pres_IP = pres_IP + coeff*q_prim_vf(E_idx)%sf(i, j, k) + pres_IP = pres_IP + coeff* & + q_prim_vf(E_idx)%sf(i, j, k) $:GPU_LOOP(parallelism='[seq]') do q = momxb, momxe - vel_IP(q + 1 - momxb) = vel_IP(q + 1 - momxb) + coeff*q_prim_vf(q)%sf(i, j, k) + vel_IP(q + 1 - momxb) = vel_IP(q + 1 - momxb) + coeff* & + q_prim_vf(q)%sf(i, j, k) end do $:GPU_LOOP(parallelism='[seq]') do l = contxb, contxe - alpha_rho_IP(l) = alpha_rho_IP(l) + coeff*q_prim_vf(l)%sf(i, j, k) - alpha_IP(l) = alpha_IP(l) + coeff*q_prim_vf(advxb + l - 1)%sf(i, j, k) + alpha_rho_IP(l) = alpha_rho_IP(l) + coeff* & + q_prim_vf(l)%sf(i, j, k) + alpha_IP(l) = alpha_IP(l) + coeff* & + q_prim_vf(advxb + l - 1)%sf(i, j, k) end do if (surface_tension) then @@ -818,14 +881,16 @@ contains if (.not. polytropic) then do q = 1, nb do l = 1, nnode - presb_IP((q - 1)*nnode + l) = presb_IP((q - 1)*nnode + l) + coeff*real(pb_in(i, j, k, l, q), & - & kind=wp) - massv_IP((q - 1)*nnode + l) = massv_IP((q - 1)*nnode + l) + coeff*real(mv_in(i, j, k, l, q), & - & kind=wp) + presb_IP((q - 1)*nnode + l) = presb_IP((q - 1)*nnode + l) + & + coeff*real(pb_in(i, j, k, l, q), kind=wp) + massv_IP((q - 1)*nnode + l) = massv_IP((q - 1)*nnode + l) + & + coeff*real(mv_in(i, j, k, l, q), kind=wp) end do end do end if + end if + end do end do end do @@ -837,16 +902,17 @@ contains impure subroutine s_update_mib(num_ibs) integer, intent(in) :: num_ibs - integer :: i, j, k, ierr, z_gp_layers + + integer :: i, j, k, ierr, z_gp_layers call nvtxStartRange("UPDATE-MIBM") ! Clears the existing immersed boundary indices z_gp_layers = 0; if (p /= 0) z_gp_layers = gp_layers + 1 - $:GPU_PARALLEL_LOOP(private='[i, j, k]') + $:GPU_PARALLEL_LOOP(private='[i,j,k]') do i = -gp_layers - 1, m + gp_layers + 1; do j = -gp_layers - 1, n + gp_layers + 1; do k = -z_gp_layers, p + z_gp_layers - ib_markers%sf(i, j, k) = 0._wp - end do; end do; end do + ib_markers%sf(i, j, k) = 0._wp + end do; end do; end do $:END_GPU_PARALLEL_LOOP() ! recalulcate the rotation matrix based upon the new angles @@ -879,18 +945,20 @@ contains end subroutine s_update_mib - !> Compute pressure and viscous forces and torques on immersed bodies via volume integration + !> @brief Computes pressure and viscous forces and torques on immersed bodies via a volume integration method. subroutine s_compute_ib_forces(q_prim_vf, fluid_pp) - type(scalar_field), dimension(1:sys_size), intent(in) :: q_prim_vf + ! real(wp), dimension(idwbuff(1)%beg:idwbuff(1)%end, & + ! idwbuff(2)%beg:idwbuff(2)%end, & + ! idwbuff(3)%beg:idwbuff(3)%end), intent(in) :: pressure + type(scalar_field), dimension(1:sys_size), intent(in) :: q_prim_vf type(physical_parameters), dimension(1:num_fluids), intent(in) :: fluid_pp - integer :: gp_id, i, j, k, l, q, ib_idx, fluid_idx - real(wp), dimension(num_ibs, 3) :: forces, torques - real(wp), dimension(1:3,1:3) :: viscous_stress_div, viscous_stress_div_1, & - & viscous_stress_div_2 ! viscous stress tensor with temp vectors to hold divergence calculations - real(wp), dimension(1:3) :: local_force_contribution, radial_vector, local_torque_contribution, vel - real(wp) :: cell_volume, dx, dy, dz, dynamic_viscosity + integer :: gp_id, i, j, k, l, q, ib_idx, fluid_idx + real(wp), dimension(num_ibs, 3) :: forces, torques + real(wp), dimension(1:3, 1:3) :: viscous_stress_div, viscous_stress_div_1, viscous_stress_div_2 ! viscous stress tensor with temp vectors to hold divergence calculations + real(wp), dimension(1:3) :: local_force_contribution, radial_vector, local_torque_contribution, vel + real(wp) :: cell_volume, dx, dy, dz, dynamic_viscosity #:if not MFC_CASE_OPTIMIZATION and USING_AMD real(wp), dimension(3) :: dynamic_viscosities #:else @@ -912,10 +980,7 @@ contains end do end if - $:GPU_PARALLEL_LOOP(private='[ib_idx, fluid_idx, radial_vector, local_force_contribution, cell_volume, & - & local_torque_contribution, dynamic_viscosity, viscous_stress_div, viscous_stress_div_1, & - & viscous_stress_div_2, dx, dy, dz]', copy='[forces, torques]', copyin='[ib_markers, patch_ib, & - & dynamic_viscosities]', collapse=3) + $:GPU_PARALLEL_LOOP(private='[ib_idx,fluid_idx, radial_vector,local_force_contribution,cell_volume,local_torque_contribution, dynamic_viscosity, viscous_stress_div, viscous_stress_div_1, viscous_stress_div_2, dx, dy, dz]', copy='[forces,torques]', copyin='[ib_markers,patch_ib,dynamic_viscosities]', collapse=3) do i = 0, m do j = 0, n do k = 0, p @@ -923,30 +988,23 @@ contains if (ib_idx /= 0) then ! get the vector pointing to the grid cell from the IB centroid if (num_dims == 3) then - radial_vector = [x_cc(i), y_cc(j), z_cc(k)] - [patch_ib(ib_idx)%x_centroid, & - & patch_ib(ib_idx)%y_centroid, patch_ib(ib_idx)%z_centroid] + radial_vector = [x_cc(i), y_cc(j), z_cc(k)] - [patch_ib(ib_idx)%x_centroid, patch_ib(ib_idx)%y_centroid, patch_ib(ib_idx)%z_centroid] else - radial_vector = [x_cc(i), y_cc(j), 0._wp] - [patch_ib(ib_idx)%x_centroid, & - & patch_ib(ib_idx)%y_centroid, 0._wp] + radial_vector = [x_cc(i), y_cc(j), 0._wp] - [patch_ib(ib_idx)%x_centroid, patch_ib(ib_idx)%y_centroid, 0._wp] end if dx = x_cc(i + 1) - x_cc(i) dy = y_cc(j + 1) - y_cc(j) local_force_contribution(:) = 0._wp do fluid_idx = 0, num_fluids - 1 - ! Get the pressure contribution to force via a finite difference to compute the 2D components of the - ! gradient of the pressure and cell volume - local_force_contribution(1) = local_force_contribution(1) - (q_prim_vf(E_idx + fluid_idx)%sf(i + 1, & - & j, k) - q_prim_vf(E_idx + fluid_idx)%sf(i - 1, j, & - & k))/(2._wp*dx) ! force is the negative pressure gradient - local_force_contribution(2) = local_force_contribution(2) - (q_prim_vf(E_idx + fluid_idx)%sf(i, & - & j + 1, k) - q_prim_vf(E_idx + fluid_idx)%sf(i, j - 1, k))/(2._wp*dy) + ! Get the pressure contribution to force via a finite difference to compute the 2D components of the gradient of the pressure and cell volume + local_force_contribution(1) = local_force_contribution(1) - (q_prim_vf(E_idx + fluid_idx)%sf(i + 1, j, k) - q_prim_vf(E_idx + fluid_idx)%sf(i - 1, j, k))/(2._wp*dx) ! force is the negative pressure gradient + local_force_contribution(2) = local_force_contribution(2) - (q_prim_vf(E_idx + fluid_idx)%sf(i, j + 1, k) - q_prim_vf(E_idx + fluid_idx)%sf(i, j - 1, k))/(2._wp*dy) cell_volume = abs(dx*dy) ! add the 3D component of the pressure gradient, if we are working in 3 dimensions if (num_dims == 3) then dz = z_cc(k + 1) - z_cc(k) - local_force_contribution(3) = local_force_contribution(3) - (q_prim_vf(E_idx + fluid_idx)%sf(i, & - & j, k + 1) - q_prim_vf(E_idx + fluid_idx)%sf(i, j, k - 1))/(2._wp*dz) + local_force_contribution(3) = local_force_contribution(3) - (q_prim_vf(E_idx + fluid_idx)%sf(i, j, k + 1) - q_prim_vf(E_idx + fluid_idx)%sf(i, j, k - 1))/(2._wp*dz) cell_volume = abs(cell_volume*dz) end if end do @@ -957,35 +1015,27 @@ contains dynamic_viscosity = 0._wp do fluid_idx = 1, num_fluids ! local dynamic viscosity is the dynamic viscosity of the fluid times alpha of the fluid - dynamic_viscosity = dynamic_viscosity + (q_prim_vf(fluid_idx + advxb - 1)%sf(i, j, & - & k)*dynamic_viscosities(fluid_idx)) + dynamic_viscosity = dynamic_viscosity + (q_prim_vf(fluid_idx + advxb - 1)%sf(i, j, k)*dynamic_viscosities(fluid_idx)) end do ! get the linear force components first call s_compute_viscous_stress_tensor(viscous_stress_div_1, q_prim_vf, dynamic_viscosity, i - 1, j, k) call s_compute_viscous_stress_tensor(viscous_stress_div_2, q_prim_vf, dynamic_viscosity, i + 1, j, k) - viscous_stress_div(1,1:3) = (viscous_stress_div_2(1,1:3) - viscous_stress_div_1(1, & - & 1:3))/(2._wp*dx) ! get x derivative of the first-row of viscous stress tensor - local_force_contribution(1:3) = local_force_contribution(1:3) + viscous_stress_div(1, & - & 1:3) ! add the x components of the divergence to the force + viscous_stress_div(1, 1:3) = (viscous_stress_div_2(1, 1:3) - viscous_stress_div_1(1, 1:3))/(2._wp*dx) ! get x derivative of the first-row of viscous stress tensor + local_force_contribution(1:3) = local_force_contribution(1:3) + viscous_stress_div(1, 1:3) ! add the x components of the divergence to the force call s_compute_viscous_stress_tensor(viscous_stress_div_1, q_prim_vf, dynamic_viscosity, i, j - 1, k) call s_compute_viscous_stress_tensor(viscous_stress_div_2, q_prim_vf, dynamic_viscosity, i, j + 1, k) - viscous_stress_div(2,1:3) = (viscous_stress_div_2(2,1:3) - viscous_stress_div_1(2, & - & 1:3))/(2._wp*dy) ! get y derivative of the second-row of viscous stress tensor - local_force_contribution(1:3) = local_force_contribution(1:3) + viscous_stress_div(2, & - & 1:3) ! add the y components of the divergence to the force + viscous_stress_div(2, 1:3) = (viscous_stress_div_2(2, 1:3) - viscous_stress_div_1(2, 1:3))/(2._wp*dy) ! get y derivative of the second-row of viscous stress tensor + local_force_contribution(1:3) = local_force_contribution(1:3) + viscous_stress_div(2, 1:3) ! add the y components of the divergence to the force if (num_dims == 3) then - call s_compute_viscous_stress_tensor(viscous_stress_div_1, q_prim_vf, dynamic_viscosity, i, j, & - & k - 1) - call s_compute_viscous_stress_tensor(viscous_stress_div_2, q_prim_vf, dynamic_viscosity, i, j, & - & k + 1) - viscous_stress_div(3,1:3) = (viscous_stress_div_2(3,1:3) - viscous_stress_div_1(3, & - & 1:3))/(2._wp*dz) ! get z derivative of the third-row of viscous stress tensor - local_force_contribution(1:3) = local_force_contribution(1:3) + viscous_stress_div(3, & - & 1:3) ! add the z components of the divergence to the force + call s_compute_viscous_stress_tensor(viscous_stress_div_1, q_prim_vf, dynamic_viscosity, i, j, k - 1) + call s_compute_viscous_stress_tensor(viscous_stress_div_2, q_prim_vf, dynamic_viscosity, i, j, k + 1) + viscous_stress_div(3, 1:3) = (viscous_stress_div_2(3, 1:3) - viscous_stress_div_1(3, 1:3))/(2._wp*dz) ! get z derivative of the third-row of viscous stress tensor + local_force_contribution(1:3) = local_force_contribution(1:3) + viscous_stress_div(3, 1:3) ! add the z components of the divergence to the force end if + end if call s_cross_product(radial_vector, local_force_contribution, local_torque_contribution) @@ -1022,16 +1072,15 @@ contains ! apply the summed forces do i = 1, num_ibs - patch_ib(i)%force(:) = forces(i,:) - patch_ib(i)%torque(:) = matmul(patch_ib(i)%rotation_matrix_inverse, torques(i, & - & :)) ! torques must be converted to the local coordinates of the IB + patch_ib(i)%force(:) = forces(i, :) + patch_ib(i)%torque(:) = matmul(patch_ib(i)%rotation_matrix_inverse, torques(i, :)) ! torques must be converted to the local coordinates of the IB end do call nvtxEndRange end subroutine s_compute_ib_forces - !> Finalize the IBM module + !> Subroutine to deallocate memory reserved for the IBM module impure subroutine s_finalize_ibm_module() @:DEALLOCATE(ib_markers%sf) @@ -1046,14 +1095,17 @@ contains !> These patches include things like NACA airfoils and STL models subroutine s_compute_centroid_offset(ib_marker) - integer, intent(in) :: ib_marker - integer :: i, j, k, num_cells, num_cells_local + integer, intent(in) :: ib_marker + + integer :: i, j, k, num_cells, num_cells_local real(wp), dimension(1:3) :: center_of_mass, center_of_mass_local ! Offset only needs to be computes for specific geometries + if (patch_ib(ib_marker)%geometry == 4 .or. & + patch_ib(ib_marker)%geometry == 5 .or. & + patch_ib(ib_marker)%geometry == 11 .or. & + patch_ib(ib_marker)%geometry == 12) then - if (patch_ib(ib_marker)%geometry == 4 .or. patch_ib(ib_marker)%geometry == 5 .or. patch_ib(ib_marker) & - & %geometry == 11 .or. patch_ib(ib_marker)%geometry == 12) then center_of_mass_local = [0._wp, 0._wp, 0._wp] num_cells_local = 0 @@ -1082,31 +1134,31 @@ contains return end if - ! assign the centroid offset as a vector pointing from the true COM to the "centroid" in the input file and replace the - ! current centroid - patch_ib(ib_marker)%centroid_offset = [patch_ib(ib_marker)%x_centroid, patch_ib(ib_marker)%y_centroid, & - & patch_ib(ib_marker)%z_centroid] - center_of_mass + ! assign the centroid offset as a vector pointing from the true COM to the "centroid" in the input file and replace the current centroid + patch_ib(ib_marker)%centroid_offset = [patch_ib(ib_marker)%x_centroid, patch_ib(ib_marker)%y_centroid, patch_ib(ib_marker)%z_centroid] & + - center_of_mass patch_ib(ib_marker)%x_centroid = center_of_mass(1) patch_ib(ib_marker)%y_centroid = center_of_mass(2) patch_ib(ib_marker)%z_centroid = center_of_mass(3) ! rotate the centroid offset back into the local coords of the IB - patch_ib(ib_marker)%centroid_offset = matmul(patch_ib(ib_marker)%rotation_matrix_inverse, & - & patch_ib(ib_marker)%centroid_offset) + patch_ib(ib_marker)%centroid_offset = matmul(patch_ib(ib_marker)%rotation_matrix_inverse, patch_ib(ib_marker)%centroid_offset) else patch_ib(ib_marker)%centroid_offset(:) = [0._wp, 0._wp, 0._wp] end if end subroutine s_compute_centroid_offset - !> Computes the moment of inertia for an immersed boundary + !> Computes the moment of inertia for an immersed boundary + !! @param ib_marker Immersed boundary marker index subroutine s_compute_moment_of_inertia(ib_marker, axis) - real(wp), dimension(3), intent(in) :: axis !< the axis about which we compute the moment. Only required in 3D. - integer, intent(in) :: ib_marker - real(wp) :: moment, distance_to_axis, cell_volume - real(wp), dimension(3) :: position, closest_point_along_axis, vector_to_axis, normal_axis - integer :: i, j, k, count + real(wp), dimension(3), intent(in) :: axis !< the axis about which we compute the moment. Only required in 3D. + integer, intent(in) :: ib_marker + + real(wp) :: moment, distance_to_axis, cell_volume + real(wp), dimension(3) :: position, closest_point_along_axis, vector_to_axis, normal_axis + integer :: i, j, k, count if (p == 0) then normal_axis = [0, 0, 1] @@ -1119,47 +1171,42 @@ contains end if ! if the IB is in 2D or a 3D sphere, we can compute this exactly - if (patch_ib(ib_marker)%geometry == 2) then ! circle + if (patch_ib(ib_marker)%geometry == 2) then ! circle patch_ib(ib_marker)%moment = 0.5_wp*patch_ib(ib_marker)%mass*(patch_ib(ib_marker)%radius)**2 - else if (patch_ib(ib_marker)%geometry == 3) then ! rectangle - patch_ib(ib_marker)%moment = patch_ib(ib_marker)%mass*(patch_ib(ib_marker)%length_x**2 + patch_ib(ib_marker) & - & %length_y**2)/6._wp - else if (patch_ib(ib_marker)%geometry == 6) then ! ellipse - patch_ib(ib_marker)%moment = 0.0625_wp*patch_ib(ib_marker)%mass*(patch_ib(ib_marker)%length_x**2 + patch_ib(ib_marker) & - & %length_y**2) - else if (patch_ib(ib_marker)%geometry == 8) then ! sphere + elseif (patch_ib(ib_marker)%geometry == 3) then ! rectangle + patch_ib(ib_marker)%moment = patch_ib(ib_marker)%mass*(patch_ib(ib_marker)%length_x**2 + patch_ib(ib_marker)%length_y**2)/6._wp + elseif (patch_ib(ib_marker)%geometry == 6) then ! ellipse + patch_ib(ib_marker)%moment = 0.0625_wp*patch_ib(ib_marker)%mass*(patch_ib(ib_marker)%length_x**2 + patch_ib(ib_marker)%length_y**2) + elseif (patch_ib(ib_marker)%geometry == 8) then ! sphere patch_ib(ib_marker)%moment = 0.4*patch_ib(ib_marker)%mass*(patch_ib(ib_marker)%radius)**2 - else ! we do not have an analytic moment of inertia calculation and need to approximate it directly via a sum + + else ! we do not have an analytic moment of inertia calculation and need to approximate it directly via a sum count = 0 moment = 0._wp - cell_volume = (x_cc(1) - x_cc(0))*(y_cc(1) - y_cc(0)) - ! computed without grid stretching. Update in the loop to perform with stretching + cell_volume = (x_cc(1) - x_cc(0))*(y_cc(1) - y_cc(0)) ! computed without grid stretching. Update in the loop to perform with stretching if (p /= 0) then cell_volume = cell_volume*(z_cc(1) - z_cc(0)) end if - $:GPU_PARALLEL_LOOP(private='[position, closest_point_along_axis, vector_to_axis, distance_to_axis]', copy='[moment, & - & count]', copyin='[ib_marker, cell_volume, normal_axis]', collapse=3) + $:GPU_PARALLEL_LOOP(private='[position,closest_point_along_axis,vector_to_axis,distance_to_axis]', copy='[moment,count]', copyin='[ib_marker,cell_volume,normal_axis]', collapse=3) do i = 0, m do j = 0, n do k = 0, p if (ib_markers%sf(i, j, k) == ib_marker) then $:GPU_ATOMIC(atomic='update') - count = count + 1 ! increment the count of total cells in the boundary + count = count + 1 ! increment the count of total cells in the boundary ! get the position in local coordinates so that the axis passes through 0, 0, 0 if (p == 0) then - position = [x_cc(i), y_cc(j), 0._wp] - [patch_ib(ib_marker)%x_centroid, & - & patch_ib(ib_marker)%y_centroid, 0._wp] + position = [x_cc(i), y_cc(j), 0._wp] - [patch_ib(ib_marker)%x_centroid, patch_ib(ib_marker)%y_centroid, 0._wp] else - position = [x_cc(i), y_cc(j), z_cc(k)] - [patch_ib(ib_marker)%x_centroid, & - & patch_ib(ib_marker)%y_centroid, patch_ib(ib_marker)%z_centroid] + position = [x_cc(i), y_cc(j), z_cc(k)] - [patch_ib(ib_marker)%x_centroid, patch_ib(ib_marker)%y_centroid, patch_ib(ib_marker)%z_centroid] end if ! project the position along the axis to find the closest distance to the rotation axis closest_point_along_axis = normal_axis*dot_product(normal_axis, position) vector_to_axis = position - closest_point_along_axis - distance_to_axis = dot_product(vector_to_axis, vector_to_axis) ! saves the distance to the axis squared + distance_to_axis = dot_product(vector_to_axis, vector_to_axis) ! saves the distance to the axis squared ! compute the position component of the moment $:GPU_ATOMIC(atomic='update') @@ -1177,57 +1224,41 @@ contains end subroutine s_compute_moment_of_inertia - !> Wrap immersed boundary positions across periodic domain boundaries + !> @brief Checks for periodic boundary conditions in all directions, and if so, moves patch location if it left the domain subroutine s_wrap_periodic_ibs() integer :: patch_id do patch_id = 1, num_ibs ! check domain wraps in x, y, - #:for X in [('x'), ('y')] - ! check for periodicity - if (bc_${X}$%beg == BC_PERIODIC) then - ! check if the boundary has left the domain, and then correct - if (patch_ib(patch_id)%${X}$_centroid < ${X}$_domain%beg) then - ! if the boundary exited "left", wrap it back around to the "right" - patch_ib(patch_id)%${X}$_centroid = patch_ib(patch_id)%${X}$_centroid + (${X}$_domain%end & - & - ${X}$_domain%beg) - else if (patch_ib(patch_id)%${X}$_centroid > ${X}$_domain%end) then - ! if the boundary exited "right", wrap it back around to the "left" - patch_ib(patch_id)%${X}$_centroid = patch_ib(patch_id)%${X}$_centroid - (${X}$_domain%end & - & - ${X}$_domain%beg) + #:for X, ID in [('x', 1), ('y', 2), ('z',3)] + if (num_dims >= ${ID}$) then + ! check for periodicity + if (bc_${X}$%beg == BC_PERIODIC) then + ! check if the boundary has left the domain, and then correct + if (patch_ib(patch_id)%${X}$_centroid < glb_bounds(${ID}$)%beg) then + ! if the boundary exited "left", wrap it back around to the "right" + patch_ib(patch_id)%${X}$_centroid = patch_ib(patch_id)%${X}$_centroid + (glb_bounds(${ID}$)%end - glb_bounds(${ID}$)%beg) + else if (patch_ib(patch_id)%${X}$_centroid > glb_bounds(${ID}$)%end) then + ! if the boundary exited "right", wrap it back around to the "left" + patch_ib(patch_id)%${X}$_centroid = patch_ib(patch_id)%${X}$_centroid - (glb_bounds(${ID}$)%end - glb_bounds(${ID}$)%beg) + end if end if end if #:endfor - - if (p /= 0) then - ! check for periodicity - if (bc_z%beg == BC_PERIODIC) then - ! check if the boundary has left the domain, and then correct - if (patch_ib(patch_id)%z_centroid < z_domain%beg) then - ! if the boundary exited "left", wrap it back around to the "right" - patch_ib(patch_id)%z_centroid = patch_ib(patch_id)%z_centroid + (z_domain%end - z_domain%beg) - else if (patch_ib(patch_id)%z_centroid > z_domain%end) then - ! if the boundary exited "right", wrap it back around to the "left" - patch_ib(patch_id)%z_centroid = patch_ib(patch_id)%z_centroid - (z_domain%end - z_domain%beg) - end if - end if - end if end do end subroutine s_wrap_periodic_ibs - !> Compute the cross product c = a x b of two 3D vectors + !> @brief Computes the cross product c = a x b of two 3D vectors. subroutine s_cross_product(a, b, c) - $:GPU_ROUTINE(parallelism='[seq]') - real(wp), intent(in) :: a(3), b(3) + real(wp), intent(in) :: a(3), b(3) real(wp), intent(out) :: c(3) c(1) = a(2)*b(3) - a(3)*b(2) c(2) = a(3)*b(1) - a(1)*b(3) c(3) = a(1)*b(2) - a(2)*b(1) - end subroutine s_cross_product end module m_ibm diff --git a/src/simulation/m_igr.fpp b/src/simulation/m_igr.fpp index 7d0f18cb26..78956ef803 100644 --- a/src/simulation/m_igr.fpp +++ b/src/simulation/m_igr.fpp @@ -8,37 +8,46 @@ !> @brief Iterative ghost rasterization (IGR) for sharp immersed boundary treatment module m_igr - use m_derived_types + use m_derived_types !< Definitions of the derived types + use m_global_parameters + use m_variables_conversion + use m_mpi_proxy + use m_helper + use m_boundary_common implicit none - private; public :: s_initialize_igr_module, s_igr_iterative_solve, s_igr_riemann_solver, s_igr_sigma_x, s_igr_flux_add, & - & s_finalize_igr_module + private; public :: s_initialize_igr_module, & + s_igr_iterative_solve, & + s_igr_riemann_solver, & + s_igr_sigma_x, & + s_igr_flux_add, & + s_finalize_igr_module - !> @cond +!> @cond #ifdef __NVCOMPILER_GPU_UNIFIED_MEM - integer, dimension(3) :: nv_uvm_temp_on_gpu - real(wp), pointer, contiguous, dimension(:,:,:) :: jac, jac_rhs, jac_old - real(wp), allocatable, dimension(:,:,:), pinned, target :: jac_host - real(wp), allocatable, dimension(:,:,:), pinned, target :: jac_rhs_host - real(wp), allocatable, dimension(:,:,:), pinned, target :: jac_old_host + integer, dimension(3) :: nv_uvm_temp_on_gpu + real(wp), pointer, contiguous, dimension(:, :, :) :: jac, jac_rhs, jac_old + real(wp), allocatable, dimension(:, :, :), pinned, target :: jac_host + real(wp), allocatable, dimension(:, :, :), pinned, target :: jac_rhs_host + real(wp), allocatable, dimension(:, :, :), pinned, target :: jac_old_host #else - !> @endcond - real(wp), allocatable, target, dimension(:,:,:) :: jac - real(wp), allocatable, dimension(:,:,:) :: jac_rhs, jac_old +!> @endcond + real(wp), allocatable, target, dimension(:, :, :) :: jac + real(wp), allocatable, dimension(:, :, :) :: jac_rhs, jac_old $:GPU_DECLARE(create='[jac, jac_rhs, jac_old]') - !> @cond +!> @cond #endif - !> @endcond +!> @endcond type(scalar_field), dimension(1) :: jac_sf $:GPU_DECLARE(create='[jac_sf]') - real(wp), allocatable, dimension(:,:) :: Res_igr + real(wp), allocatable, dimension(:, :) :: Res_igr $:GPU_DECLARE(create='[Res_igr]') real(wp) :: alf_igr @@ -56,22 +65,64 @@ module m_igr integer, parameter :: vidxe = 3 #if defined(MFC_OpenMP) - real(wp) :: coeff_L(-1:3) = [-3._wp/60._wp, 27._wp/60._wp, 47._wp/60._wp, -13._wp/60._wp, 2._wp/60._wp] - real(wp) :: coeff_R(-2:2) = [2._wp/60._wp, -13._wp/60._wp, 47._wp/60._wp, 27._wp/60._wp, -3._wp/60._wp] + real(wp) :: coeff_L(-1:3) = [ & + -3._wp/60._wp, & ! Index -1 + 27._wp/60._wp, & ! Index 0 + 47._wp/60._wp, & ! Index 1 + -13._wp/60._wp, & ! Index 2 + 2._wp/60._wp & ! Index 3 + ] + + real(wp) :: coeff_R(-2:2) = [ & + 2._wp/60._wp, & ! Index -2 + -13._wp/60._wp, & ! Index -1 + 47._wp/60._wp, & ! Index 0 + 27._wp/60._wp, & ! Index 1 + -3._wp/60._wp & ! Index 2 + ] #else - real(wp), parameter :: coeff_L(-1:3) = [-3._wp/60._wp, 27._wp/60._wp, 47._wp/60._wp, -13._wp/60._wp, 2._wp/60._wp] - real(wp), parameter :: coeff_R(-2:2) = [2._wp/60._wp, -13._wp/60._wp, 47._wp/60._wp, 27._wp/60._wp, -3._wp/60._wp] + real(wp), parameter :: coeff_L(-1:3) = [ & + -3._wp/60._wp, & ! Index -1 + 27._wp/60._wp, & ! Index 0 + 47._wp/60._wp, & ! Index 1 + -13._wp/60._wp, & ! Index 2 + 2._wp/60._wp & ! Index 3 + ] + + real(wp), parameter :: coeff_R(-2:2) = [ & + 2._wp/60._wp, & ! Index -2 + -13._wp/60._wp, & ! Index -1 + 47._wp/60._wp, & ! Index 0 + 27._wp/60._wp, & ! Index 1 + -3._wp/60._wp & ! Index 2 + ] #endif #:elif igr_order == 3 integer, parameter :: vidxb = -1 integer, parameter :: vidxe = 2 #if defined(MFC_OpenMP) - real(wp) :: coeff_L(0:2) = [2._wp/6._wp, 5._wp/6._wp, -1._wp/6._wp] - real(wp) :: coeff_R(-1:1) = [-1._wp/6._wp, 5._wp/6._wp, 2._wp/6._wp] + real(wp) :: coeff_L(0:2) = [ & + 2._wp/6._wp, & ! Index 0 + 5._wp/6._wp, & ! Index 1 + -1._wp/6._wp & ! Index 2 + ] + real(wp) :: coeff_R(-1:1) = [ & + -1._wp/6._wp, & ! Index -1 + 5._wp/6._wp, & ! Index 0 + 2._wp/6._wp & ! Index 1 + ] #else - real(wp), parameter :: coeff_L(0:2) = [2._wp/6._wp, 5._wp/6._wp, -1._wp/6._wp] - real(wp), parameter :: coeff_R(-1:1) = [-1._wp/6._wp, 5._wp/6._wp, 2._wp/6._wp] + real(wp), parameter :: coeff_L(0:2) = [ & + 2._wp/6._wp, & ! Index 0 + 5._wp/6._wp, & ! Index 1 + -1._wp/6._wp & ! Index 2 + ] + real(wp), parameter :: coeff_R(-1:1) = [ & + -1._wp/6._wp, & ! Index -1 + 5._wp/6._wp, & ! Index 0 + 2._wp/6._wp & ! Index 1 + ] #endif #:endif @@ -84,7 +135,7 @@ module m_igr contains - !> Initialize the IGR module + !> @brief Allocates and initializes arrays, coefficients, and GPU data structures for the implicit gradient reconstruction module. subroutine s_initialize_igr_module() if (viscous) then @@ -100,11 +151,15 @@ contains end if #ifndef __NVCOMPILER_GPU_UNIFIED_MEM - @:ALLOCATE(jac(idwbuff(1)%beg:idwbuff(1)%end, idwbuff(2)%beg:idwbuff(2)%end, idwbuff(3)%beg:idwbuff(3)%end)) + @:ALLOCATE(jac(idwbuff(1)%beg:idwbuff(1)%end, & + idwbuff(2)%beg:idwbuff(2)%end, & + idwbuff(3)%beg:idwbuff(3)%end)) @:ALLOCATE(jac_rhs(-1:m,-1:n,-1:p)) - if (igr_iter_solver == 1) then ! Jacobi iteration - @:ALLOCATE(jac_old(idwbuff(1)%beg:idwbuff(1)%end, idwbuff(2)%beg:idwbuff(2)%end, idwbuff(3)%beg:idwbuff(3)%end)) + if (igr_iter_solver == 1) then ! Jacobi iteration + @:ALLOCATE(jac_old(idwbuff(1)%beg:idwbuff(1)%end, & + idwbuff(2)%beg:idwbuff(2)%end, & + idwbuff(3)%beg:idwbuff(3)%end)) end if #else ! create map @@ -112,36 +167,47 @@ contains nv_uvm_temp_on_gpu(1:nv_uvm_igr_temps_on_gpu) = 1 if (nv_uvm_temp_on_gpu(1) == 1) then - @:ALLOCATE(jac(idwbuff(1)%beg:idwbuff(1)%end, idwbuff(2)%beg:idwbuff(2)%end, idwbuff(3)%beg:idwbuff(3)%end)) + @:ALLOCATE(jac(idwbuff(1)%beg:idwbuff(1)%end, & + idwbuff(2)%beg:idwbuff(2)%end, & + idwbuff(3)%beg:idwbuff(3)%end)) @:PREFER_GPU(jac) else - allocate (jac_host(idwbuff(1)%beg:idwbuff(1)%end,idwbuff(2)%beg:idwbuff(2)%end,idwbuff(3)%beg:idwbuff(3)%end)) + allocate (jac_host(idwbuff(1)%beg:idwbuff(1)%end, & + idwbuff(2)%beg:idwbuff(2)%end, & + idwbuff(3)%beg:idwbuff(3)%end)) - jac(idwbuff(1)%beg:idwbuff(1)%end,idwbuff(2)%beg:idwbuff(2)%end,idwbuff(3)%beg:idwbuff(3)%end) => jac_host(:,:,:) + jac(idwbuff(1)%beg:idwbuff(1)%end, & + idwbuff(2)%beg:idwbuff(2)%end, & + idwbuff(3)%beg:idwbuff(3)%end) => jac_host(:, :, :) end if if (nv_uvm_temp_on_gpu(2) == 1) then @:ALLOCATE(jac_rhs(-1:m,-1:n,-1:p)) @:PREFER_GPU(jac_rhs) else - allocate (jac_rhs_host(-1:m,-1:n,-1:p)) - jac_rhs(-1:m,-1:n,-1:p) => jac_rhs_host(:,:,:) + allocate (jac_rhs_host(-1:m, -1:n, -1:p)) + jac_rhs(-1:m, -1:n, -1:p) => jac_rhs_host(:, :, :) end if - if (igr_iter_solver == 1) then ! Jacobi iteration + if (igr_iter_solver == 1) then ! Jacobi iteration if (nv_uvm_temp_on_gpu(3) == 1) then - @:ALLOCATE(jac_old(idwbuff(1)%beg:idwbuff(1)%end, idwbuff(2)%beg:idwbuff(2)%end, idwbuff(3)%beg:idwbuff(3)%end)) + @:ALLOCATE(jac_old(idwbuff(1)%beg:idwbuff(1)%end, & + idwbuff(2)%beg:idwbuff(2)%end, & + idwbuff(3)%beg:idwbuff(3)%end)) @:PREFER_GPU(jac_old) else - allocate (jac_old_host(idwbuff(1)%beg:idwbuff(1)%end,idwbuff(2)%beg:idwbuff(2)%end,idwbuff(3)%beg:idwbuff(3)%end)) + allocate (jac_old_host(idwbuff(1)%beg:idwbuff(1)%end, & + idwbuff(2)%beg:idwbuff(2)%end, & + idwbuff(3)%beg:idwbuff(3)%end)) - jac_old(idwbuff(1)%beg:idwbuff(1)%end,idwbuff(2)%beg:idwbuff(2)%end, & - & idwbuff(3)%beg:idwbuff(3)%end) => jac_old_host(:,:,:) + jac_old(idwbuff(1)%beg:idwbuff(1)%end, & + idwbuff(2)%beg:idwbuff(2)%end, & + idwbuff(3)%beg:idwbuff(3)%end) => jac_old_host(:, :, :) end if end if #endif - $:GPU_PARALLEL_LOOP(private='[j, k, l]', collapse=3) + $:GPU_PARALLEL_LOOP(private='[j,k,l]', collapse=3) do l = idwbuff(3)%beg, idwbuff(3)%end do k = idwbuff(2)%beg, idwbuff(2)%end do j = idwbuff(1)%beg, idwbuff(1)%end @@ -161,7 +227,7 @@ contains #:if not MFC_CASE_OPTIMIZATION if (igr_order == 3) then - vidxb = -1; vidxe = 2 + vidxb = -1; vidxe = 2; $:GPU_UPDATE(device='[vidxb, vidxe]') @:ALLOCATE(coeff_L(0:2)) @@ -173,8 +239,9 @@ contains coeff_R(1) = (2._wp/6._wp) coeff_R(0) = (5._wp/6._wp) coeff_R(-1) = (-1._wp/6._wp) - else if (igr_order == 5) then - vidxb = -2; vidxe = 3 + + elseif (igr_order == 5) then + vidxb = -2; vidxe = 3; $:GPU_UPDATE(device='[vidxb, vidxe]') @:ALLOCATE(coeff_L(-1:3)) @@ -206,18 +273,18 @@ contains end subroutine s_initialize_igr_module - !> Iteratively solve the implicit gradient reconstruction system + !> @brief Iteratively solves the implicit gradient reconstruction system using Jacobi or Gauss-Seidel relaxation. subroutine s_igr_iterative_solve(q_cons_vf, bc_type, t_step) - #ifdef _CRAYFTN - ! DIR$ OPTIMIZE (-haggress) + !DIR$ OPTIMIZE (-haggress) #endif - type(scalar_field), dimension(sys_size), intent(inout) :: q_cons_vf - type(integer_field), dimension(1:num_dims,1:2), intent(in) :: bc_type - integer, intent(in) :: t_step - real(wp) :: rho_rx, rho_ry, rho_rz, rho_lx, rho_ly, rho_lz - real(wp) :: fd_coeff - integer :: num_iters + type(scalar_field), dimension(sys_size), intent(inout) :: q_cons_vf + type(integer_field), dimension(1:num_dims, 1:2), intent(in) :: bc_type + integer, intent(in) :: t_step + + real(wp) :: rho_rx, rho_ry, rho_rz, rho_lx, rho_ly, rho_lz + real(wp) :: fd_coeff + integer :: num_iters if (t_step == t_step_start) then num_iters = num_igr_warm_start_iters @@ -226,7 +293,7 @@ contains end if do q = 1, num_iters - $:GPU_PARALLEL_LOOP(collapse=3, private='[j, k, l, rho_lx, rho_rx, rho_ly, rho_ry, rho_lz, rho_rz, fd_coeff]') + $:GPU_PARALLEL_LOOP(collapse=3, private='[j,k,l,rho_lx, rho_rx, rho_ly, rho_ry, rho_lz, rho_rz, fd_coeff]') do l = 0, p do k = 0, n do j = 0, m @@ -251,38 +318,39 @@ contains fd_coeff = fd_coeff + q_cons_vf(i)%sf(j, k, l) end do - fd_coeff = 1._wp/fd_coeff + alf_igr*((1._wp/dx(j)**2._wp)*(1._wp/rho_lx + 1._wp/rho_rx) + (1._wp/dy(k) & - & **2._wp)*(1._wp/rho_ly + 1._wp/rho_ry)) + fd_coeff = 1._wp/fd_coeff + alf_igr* & + ((1._wp/dx(j)**2._wp)*(1._wp/rho_lx + 1._wp/rho_rx) + & + (1._wp/dy(k)**2._wp)*(1._wp/rho_ly + 1._wp/rho_ry)) if (num_dims == 3) then fd_coeff = fd_coeff + alf_igr*(1._wp/dz(l)**2._wp)*(1._wp/rho_lz + 1._wp/rho_rz) end if - if (igr_iter_solver == 1) then ! Jacobi iteration + if (igr_iter_solver == 1) then ! Jacobi iteration if (num_dims == 3) then - jac(j, k, l) = real((alf_igr/fd_coeff)*((1._wp/dx(j)**2._wp)*(jac_old(j - 1, k, & - & l)/rho_lx + jac_old(j + 1, k, l)/rho_rx) + (1._wp/dy(k)**2._wp)*(jac_old(j, k - 1, & - & l)/rho_ly + jac_old(j, k + 1, l)/rho_ry) + (1._wp/dz(l)**2._wp)*(jac_old(j, k, & - & l - 1)/rho_lz + jac_old(j, k, l + 1)/rho_rz)) + real(jac_rhs(j, k, l), kind=wp)/fd_coeff, & - & kind=stp) + jac(j, k, l) = real((alf_igr/fd_coeff)* & + ((1._wp/dx(j)**2._wp)*(jac_old(j - 1, k, l)/rho_lx + jac_old(j + 1, k, l)/rho_rx) + & + (1._wp/dy(k)**2._wp)*(jac_old(j, k - 1, l)/rho_ly + jac_old(j, k + 1, l)/rho_ry) + & + (1._wp/dz(l)**2._wp)*(jac_old(j, k, l - 1)/rho_lz + jac_old(j, k, l + 1)/rho_rz)) + & + real(jac_rhs(j, k, l), kind=wp)/fd_coeff, kind=stp) else - jac(j, k, l) = real((alf_igr/fd_coeff)*((1._wp/dx(j)**2._wp)*(real(jac_old(j - 1, k, l), & - & kind=wp)/rho_lx + real(jac_old(j + 1, k, l), & - & kind=wp)/rho_rx) + (1._wp/dy(k)**2._wp)*(real(jac_old(j, k - 1, l), & - & kind=wp)/rho_ly + real(jac_old(j, k + 1, l), kind=wp)/rho_ry)) + real(jac_rhs(j, k, l), & - & kind=wp)/fd_coeff, kind=stp) + jac(j, k, l) = real((alf_igr/fd_coeff)* & + ((1._wp/dx(j)**2._wp)*(real(jac_old(j - 1, k, l), kind=wp)/rho_lx + real(jac_old(j + 1, k, l), kind=wp)/rho_rx) + & + (1._wp/dy(k)**2._wp)*(real(jac_old(j, k - 1, l), kind=wp)/rho_ly + real(jac_old(j, k + 1, l), kind=wp)/rho_ry)) + & + real(jac_rhs(j, k, l), kind=wp)/fd_coeff, kind=stp) end if - else ! Gauss Seidel iteration + else ! Gauss Seidel iteration if (num_dims == 3) then - jac(j, k, l) = real((alf_igr/fd_coeff)*((1._wp/dx(j)**2._wp)*(jac(j - 1, k, & - & l)/rho_lx + jac(j + 1, k, l)/rho_rx) + (1._wp/dy(k)**2._wp)*(jac(j, k - 1, & - & l)/rho_ly + jac(j, k + 1, l)/rho_ry) + (1._wp/dz(l)**2._wp)*(jac(j, k, & - & l - 1)/rho_lz + jac(j, k, l + 1)/rho_rz)) + real(jac_rhs(j, k, l), kind=wp)/fd_coeff, & - & kind=stp) + jac(j, k, l) = real((alf_igr/fd_coeff)* & + ((1._wp/dx(j)**2._wp)*(jac(j - 1, k, l)/rho_lx + jac(j + 1, k, l)/rho_rx) + & + (1._wp/dy(k)**2._wp)*(jac(j, k - 1, l)/rho_ly + jac(j, k + 1, l)/rho_ry) + & + (1._wp/dz(l)**2._wp)*(jac(j, k, l - 1)/rho_lz + jac(j, k, l + 1)/rho_rz)) + & + real(jac_rhs(j, k, l), kind=wp)/fd_coeff, kind=stp) else - jac(j, k, l) = real((alf_igr/fd_coeff)*((1._wp/dx(j)**2._wp)*(jac(j - 1, k, & - & l)/rho_lx + jac(j + 1, k, l)/rho_rx) + (1._wp/dy(k)**2._wp)*(jac(j, k - 1, & - & l)/rho_ly + jac(j, k + 1, l)/rho_ry)) + real(jac_rhs(j, k, l), kind=wp)/fd_coeff, kind=stp) + jac(j, k, l) = real((alf_igr/fd_coeff)* & + ((1._wp/dx(j)**2._wp)*(jac(j - 1, k, l)/rho_lx + jac(j + 1, k, l)/rho_rx) + & + (1._wp/dy(k)**2._wp)*(jac(j, k - 1, l)/rho_ly + jac(j, k + 1, l)/rho_ry)) + & + real(jac_rhs(j, k, l), kind=wp)/fd_coeff, kind=stp) end if end if end do @@ -292,8 +360,8 @@ contains call s_populate_F_igr_buffers(bc_type, jac_sf) - if (igr_iter_solver == 1 .or. dummy) then ! Jacobi iteration - $:GPU_PARALLEL_LOOP(private='[j, k, l]', collapse=3) + if (igr_iter_solver == 1 .or. dummy) then ! Jacobi iteration + $:GPU_PARALLEL_LOOP(private='[j,k,l]', collapse=3) do l = idwbuff(3)%beg, idwbuff(3)%end do k = idwbuff(2)%beg, idwbuff(2)%end do j = idwbuff(1)%beg, idwbuff(1)%end @@ -307,25 +375,30 @@ contains end subroutine s_igr_iterative_solve - !> Compute the IGR viscous stress contribution in the x-direction and accumulate into the RHS + !> @brief Computes the IGR viscous stress contribution in the x-direction and accumulates it into the RHS. subroutine s_igr_sigma_x(q_cons_vf, rhs_vf) - #ifdef _CRAYFTN - ! DIR$ OPTIMIZE (-haggress) + !DIR$ OPTIMIZE (-haggress) #endif - type(scalar_field), dimension(sys_size), intent(inout) :: rhs_vf - type(scalar_field), dimension(sys_size), intent(inout) :: q_cons_vf - real(wp) :: F_L, vel_L, rho_L, F_R, vel_R, rho_R + type(scalar_field), & + dimension(sys_size), & + intent(inout) :: rhs_vf + type(scalar_field), & + dimension(sys_size), & + intent(inout) :: q_cons_vf + + real(wp) :: F_L, vel_L, rho_L, F_R, vel_R, rho_R #:if not MFC_CASE_OPTIMIZATION real(wp), dimension(num_fluids_max) :: alpha_rho_L, alpha_rho_R #:else real(wp), dimension(num_fluids) :: alpha_rho_L, alpha_rho_R #:endif - $:GPU_PARALLEL_LOOP(collapse=3, private='[j, k, l, F_L, vel_L, alpha_rho_L, F_R, vel_R, alpha_rho_R, rho_L, rho_R]') + $:GPU_PARALLEL_LOOP(collapse=3, private='[j,k,l,F_L, vel_L, alpha_rho_L, F_R, vel_R, alpha_rho_R, rho_L, rho_R]') do l = 0, p do k = 0, n do j = -1, m + F_L = 0._wp; F_R = 0._wp vel_L = 0._wp; vel_R = 0._wp rho_L = 0._wp; rho_R = 0._wp @@ -369,16 +442,17 @@ contains #:for LR in ['L', 'R'] $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb)%sf(j + 1, k, l) = rhs_vf(momxb)%sf(j + 1, k, & - & l) + real(0.5_wp*dt*F_${LR}$*(1._wp/dx(j + 1)), kind=stp) + rhs_vf(momxb)%sf(j + 1, k, l) = rhs_vf(momxb)%sf(j + 1, k, l) + & + real(0.5_wp*dt*F_${LR}$*(1._wp/dx(j + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(E_idx)%sf(j + 1, k, l) = rhs_vf(E_idx)%sf(j + 1, k, & - & l) + real(0.5_wp*dt*vel_${LR}$*F_${LR}$*(1._wp/dx(j + 1)), kind=stp) + rhs_vf(E_idx)%sf(j + 1, k, l) = rhs_vf(E_idx)%sf(j + 1, k, l) + & + real(0.5_wp*dt*vel_${LR}$*F_${LR}$*(1._wp/dx(j + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb)%sf(j, k, l) = rhs_vf(momxb)%sf(j, k, l) - real(0.5_wp*dt*F_${LR}$*(1._wp/dx(j)), kind=stp) + rhs_vf(momxb)%sf(j, k, l) = rhs_vf(momxb)%sf(j, k, l) - & + real(0.5_wp*dt*F_${LR}$*(1._wp/dx(j)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(E_idx)%sf(j, k, l) = rhs_vf(E_idx)%sf(j, k, l) - real(0.5_wp*dt*vel_${LR}$*F_${LR}$*(1._wp/dx(j)), & - & kind=stp) + rhs_vf(E_idx)%sf(j, k, l) = rhs_vf(E_idx)%sf(j, k, l) - & + real(0.5_wp*dt*vel_${LR}$*F_${LR}$*(1._wp/dx(j)), kind=stp) #:endfor end do end do @@ -387,54 +461,57 @@ contains end subroutine s_igr_sigma_x - !> Evaluate the approximate Riemann solver for the IGR scheme along a given direction + !> @brief Evaluates the approximate Riemann solver for the IGR scheme along a given coordinate direction. subroutine s_igr_riemann_solver(q_cons_vf, rhs_vf, idir) - #ifdef _CRAYFTN - ! DIR$ OPTIMIZE (-haggress) + !DIR$ OPTIMIZE (-haggress) #endif - type(scalar_field), dimension(sys_size), intent(inout) :: rhs_vf - type(scalar_field), dimension(sys_size), intent(inout) :: q_cons_vf - integer, intent(in) :: idir - real(wp) :: cfl - real(wp) :: rho_L, gamma_L, pi_inf_L, E_L, mu_L, F_L, pres_L - real(wp) :: rho_R, gamma_R, pi_inf_R, E_R, mu_R, F_R, pres_R - real(wp), dimension(3) :: vflux_L_arr, vflux_R_arr - real(wp), dimension(-1:1) :: rho_sf_small + type(scalar_field), & + dimension(sys_size), & + intent(inout) :: rhs_vf + type(scalar_field), & + dimension(sys_size), & + intent(inout) :: q_cons_vf + integer, intent(in) :: idir + + real(wp) :: cfl + real(wp) :: rho_L, gamma_L, pi_inf_L, E_L, mu_L, F_L, pres_L + real(wp) :: rho_R, gamma_R, pi_inf_R, E_R, mu_R, F_R, pres_R + real(wp), dimension(3) :: vflux_L_arr, vflux_R_arr + real(wp), dimension(-1:1) :: rho_sf_small #:if not MFC_CASE_OPTIMIZATION real(wp), dimension(num_fluids_max) :: alpha_rho_L, alpha_L, alpha_R, alpha_rho_R - real(wp), dimension(3) :: vel_L, vel_R - real(wp), dimension(3, 3) :: dvel - real(wp), dimension(3) :: dvel_small + real(wp), dimension(3) :: vel_L, vel_R + real(wp), dimension(3, 3) :: dvel + real(wp), dimension(3) :: dvel_small #:else - real(wp), dimension(num_fluids) :: alpha_rho_L, alpha_L, alpha_R, alpha_rho_R - real(wp), dimension(num_dims) :: vel_L, vel_R + real(wp), dimension(num_fluids) :: alpha_rho_L, alpha_L, alpha_R, alpha_rho_R + real(wp), dimension(num_dims) :: vel_L, vel_R real(wp), dimension(num_dims, num_dims) :: dvel - real(wp), dimension(num_dims) :: dvel_small + real(wp), dimension(num_dims) :: dvel_small #:endif if (idir == 1) then if (p == 0) then #:if not MFC_CASE_OPTIMIZATION or num_dims > 1 - $:GPU_PARALLEL_LOOP(collapse=3, private='[j, k, l, rho_L, rho_R, gamma_L, gamma_R, pi_inf_L, pi_inf_R, mu_L, & - & mu_R, vel_L, vel_R, pres_L, pres_R, alpha_L, alpha_R, alpha_rho_L, alpha_rho_R, F_L, & - & F_R, E_L, E_R, cfl, dvel, dvel_small, rho_sf_small, vflux_L_arr, vflux_R_arr]') + $:GPU_PARALLEL_LOOP(collapse=3, private='[j,k,l,rho_L, rho_R, gamma_L, gamma_R, pi_inf_L, pi_inf_R, mu_L, mu_R, vel_L, vel_R, pres_L, pres_R, alpha_L, alpha_R, alpha_rho_L, alpha_rho_R, F_L, F_R, E_L, E_R, cfl, dvel, dvel_small, rho_sf_small, vflux_L_arr, vflux_R_arr]') do l = 0, p do k = 0, n do j = -1, m + vflux_L_arr = 0._wp vflux_R_arr = 0._wp #:if MFC_CASE_OPTIMIZATION #:if igr_order == 5 - ! DIR$ unroll 6 + !DIR$ unroll 6 #:elif igr_order == 3 - ! DIR$ unroll 4 + !DIR$ unroll 4 #:endif #:endif $:GPU_LOOP(parallelism='[seq]') do q = vidxb, vidxe - ! x-direction contributions + !x-direction contributions $:GPU_LOOP(parallelism='[seq]') do i = -1, 1 rho_L = 0._wp @@ -445,10 +522,12 @@ contains rho_sf_small(i) = rho_L end do - dvel_small(1) = (1/(2._wp*dx(j)))*(1._wp*q_cons_vf(momxb)%sf(j + 1 + q, k, & - & l)/rho_sf_small(1) - 1._wp*q_cons_vf(momxb)%sf(j - 1 + q, k, l)/rho_sf_small(-1)) - dvel_small(2) = (1/(2._wp*dx(j)))*(q_cons_vf(momxb + 1)%sf(j + 1 + q, k, & - & l)/rho_sf_small(1) - q_cons_vf(momxb + 1)%sf(j - 1 + q, k, l)/rho_sf_small(-1)) + dvel_small(1) = (1/(2._wp*dx(j)))*( & + 1._wp*q_cons_vf(momxb)%sf(j + 1 + q, k, l)/rho_sf_small(1) - & + 1._wp*q_cons_vf(momxb)%sf(j - 1 + q, k, l)/rho_sf_small(-1)) + dvel_small(2) = (1/(2._wp*dx(j)))*( & + q_cons_vf(momxb + 1)%sf(j + 1 + q, k, l)/rho_sf_small(1) - & + q_cons_vf(momxb + 1)%sf(j - 1 + q, k, l)/rho_sf_small(-1)) if (q == 0) then $:GPU_LOOP(parallelism='[seq]') @@ -466,7 +545,7 @@ contains vflux_R_arr(3) = vflux_R_arr(3) + coeff_R(q)*(4._wp*dvel_small(1))/3._wp end if - ! y-direction contributions + !y-direction contributions $:GPU_LOOP(parallelism='[seq]') do i = -1, 1 rho_L = 0._wp @@ -477,10 +556,12 @@ contains rho_sf_small(i) = rho_L end do - dvel_small(1) = (1/(2._wp*dy(k)))*(q_cons_vf(momxb)%sf(j + q, k + 1, & - & l)/rho_sf_small(1) - q_cons_vf(momxb)%sf(j + q, k - 1, l)/rho_sf_small(-1)) - dvel_small(2) = (1/(2._wp*dy(k)))*(q_cons_vf(momxb + 1)%sf(j + q, k + 1, & - & l)/rho_sf_small(1) - q_cons_vf(momxb + 1)%sf(j + q, k - 1, l)/rho_sf_small(-1)) + dvel_small(1) = (1/(2._wp*dy(k)))*( & + q_cons_vf(momxb)%sf(j + q, k + 1, l)/rho_sf_small(1) - & + q_cons_vf(momxb)%sf(j + q, k - 1, l)/rho_sf_small(-1)) + dvel_small(2) = (1/(2._wp*dy(k)))*( & + q_cons_vf(momxb + 1)%sf(j + q, k + 1, l)/rho_sf_small(1) - & + q_cons_vf(momxb + 1)%sf(j + q, k - 1, l)/rho_sf_small(-1)) if (q == 0) then $:GPU_LOOP(parallelism='[seq]') @@ -499,8 +580,9 @@ contains end if if (q == 0) then - jac_rhs(j, k, l) = real(alf_igr*(2._wp*(dvel(1, 2)*dvel(2, 1)) + dvel(1, & - & 1)**2._wp + dvel(2, 2)**2._wp + (dvel(1, 1) + dvel(2, 2))**2._wp), kind=stp) + jac_rhs(j, k, l) = real(alf_igr*(2._wp*(dvel(1, 2)*dvel(2, 1)) & + + dvel(1, 1)**2._wp + dvel(2, 2)**2._wp & + + (dvel(1, 1) + dvel(2, 2))**2._wp), kind=stp) end if end do @@ -562,6 +644,7 @@ contains end do if (num_fluids > 1) then + alpha_L(num_fluids) = 1._wp alpha_R(num_fluids) = 1._wp @@ -602,60 +685,60 @@ contains end do $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb + 1)%sf(j + 1, k, l) = rhs_vf(momxb + 1)%sf(j + 1, k, & - & l) - real(0.5_wp*dt*mu_L*vflux_L_arr(1)*(1._wp/dx(j + 1)), kind=stp) + rhs_vf(momxb + 1)%sf(j + 1, k, l) = rhs_vf(momxb + 1)%sf(j + 1, k, l) - & + real(0.5_wp*dt*mu_L*vflux_L_arr(1)*(1._wp/dx(j + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(E_idx)%sf(j + 1, k, l) = rhs_vf(E_idx)%sf(j + 1, k, & - & l) - real(0.5_wp*dt*mu_L*vflux_L_arr(1)*vel_L(2)*(1._wp/dx(j + 1)), kind=stp) + rhs_vf(E_idx)%sf(j + 1, k, l) = rhs_vf(E_idx)%sf(j + 1, k, l) - & + real(0.5_wp*dt*mu_L*vflux_L_arr(1)*vel_L(2)*(1._wp/dx(j + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb + 1)%sf(j, k, l) = rhs_vf(momxb + 1)%sf(j, k, & - & l) + real(0.5_wp*dt*mu_L*vflux_L_arr(1)*(1._wp/dx(j)), kind=stp) + rhs_vf(momxb + 1)%sf(j, k, l) = rhs_vf(momxb + 1)%sf(j, k, l) + & + real(0.5_wp*dt*mu_L*vflux_L_arr(1)*(1._wp/dx(j)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(E_idx)%sf(j, k, l) = rhs_vf(E_idx)%sf(j, k, & - & l) + real(0.5_wp*dt*mu_L*vflux_L_arr(1)*vel_L(2)*(1._wp/dx(j)), kind=stp) + rhs_vf(E_idx)%sf(j, k, l) = rhs_vf(E_idx)%sf(j, k, l) + & + real(0.5_wp*dt*mu_L*vflux_L_arr(1)*vel_L(2)*(1._wp/dx(j)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb + 1)%sf(j + 1, k, l) = rhs_vf(momxb + 1)%sf(j + 1, k, & - & l) - real(0.5_wp*dt*mu_R*vflux_R_arr(1)*(1._wp/dx(j + 1)), kind=stp) + rhs_vf(momxb + 1)%sf(j + 1, k, l) = rhs_vf(momxb + 1)%sf(j + 1, k, l) - & + real(0.5_wp*dt*mu_R*vflux_R_arr(1)*(1._wp/dx(j + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(E_idx)%sf(j + 1, k, l) = rhs_vf(E_idx)%sf(j + 1, k, & - & l) - real(0.5_wp*dt*mu_R*vflux_R_arr(1)*vel_R(2)*(1._wp/dx(j + 1)), kind=stp) + rhs_vf(E_idx)%sf(j + 1, k, l) = rhs_vf(E_idx)%sf(j + 1, k, l) - & + real(0.5_wp*dt*mu_R*vflux_R_arr(1)*vel_R(2)*(1._wp/dx(j + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb + 1)%sf(j, k, l) = rhs_vf(momxb + 1)%sf(j, k, & - & l) + real(0.5_wp*dt*mu_R*vflux_R_arr(1)*(1._wp/dx(j)), kind=stp) + rhs_vf(momxb + 1)%sf(j, k, l) = rhs_vf(momxb + 1)%sf(j, k, l) + & + real(0.5_wp*dt*mu_R*vflux_R_arr(1)*(1._wp/dx(j)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(E_idx)%sf(j, k, l) = rhs_vf(E_idx)%sf(j, k, & - & l) + real(0.5_wp*dt*mu_R*vflux_R_arr(1)*vel_R(2)*(1._wp/dx(j)), kind=stp) + rhs_vf(E_idx)%sf(j, k, l) = rhs_vf(E_idx)%sf(j, k, l) + & + real(0.5_wp*dt*mu_R*vflux_R_arr(1)*vel_R(2)*(1._wp/dx(j)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb)%sf(j + 1, k, l) = rhs_vf(momxb)%sf(j + 1, k, & - & l) - real(0.5_wp*dt*mu_L*vflux_L_arr(3)*(1._wp/dx(j + 1)), kind=stp) + rhs_vf(momxb)%sf(j + 1, k, l) = rhs_vf(momxb)%sf(j + 1, k, l) - & + real(0.5_wp*dt*mu_L*vflux_L_arr(3)*(1._wp/dx(j + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(E_idx)%sf(j + 1, k, l) = rhs_vf(E_idx)%sf(j + 1, k, & - & l) - real(0.5_wp*dt*mu_L*vflux_L_arr(3)*vel_L(1)*(1._wp/dx(j + 1)), kind=stp) + rhs_vf(E_idx)%sf(j + 1, k, l) = rhs_vf(E_idx)%sf(j + 1, k, l) - & + real(0.5_wp*dt*mu_L*vflux_L_arr(3)*vel_L(1)*(1._wp/dx(j + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb)%sf(j, k, l) = rhs_vf(momxb)%sf(j, k, & - & l) + real(0.5_wp*dt*mu_L*vflux_L_arr(3)*(1._wp/dx(j)), kind=stp) + rhs_vf(momxb)%sf(j, k, l) = rhs_vf(momxb)%sf(j, k, l) + & + real(0.5_wp*dt*mu_L*vflux_L_arr(3)*(1._wp/dx(j)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(E_idx)%sf(j, k, l) = rhs_vf(E_idx)%sf(j, k, & - & l) + real(0.5_wp*dt*mu_L*vflux_L_arr(3)*vel_L(1)*(1._wp/dx(j)), kind=stp) + rhs_vf(E_idx)%sf(j, k, l) = rhs_vf(E_idx)%sf(j, k, l) + & + real(0.5_wp*dt*mu_L*vflux_L_arr(3)*vel_L(1)*(1._wp/dx(j)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb)%sf(j + 1, k, l) = rhs_vf(momxb)%sf(j + 1, k, & - & l) - real(0.5_wp*dt*mu_R*vflux_R_arr(3)*(1._wp/dx(j + 1)), kind=stp) + rhs_vf(momxb)%sf(j + 1, k, l) = rhs_vf(momxb)%sf(j + 1, k, l) - & + real(0.5_wp*dt*mu_R*vflux_R_arr(3)*(1._wp/dx(j + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(E_idx)%sf(j + 1, k, l) = rhs_vf(E_idx)%sf(j + 1, k, & - & l) - real(0.5_wp*dt*mu_R*vflux_R_arr(3)*vel_R(1)*(1._wp/dx(j + 1)), kind=stp) + rhs_vf(E_idx)%sf(j + 1, k, l) = rhs_vf(E_idx)%sf(j + 1, k, l) - & + real(0.5_wp*dt*mu_R*vflux_R_arr(3)*vel_R(1)*(1._wp/dx(j + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb)%sf(j, k, l) = rhs_vf(momxb)%sf(j, k, & - & l) + real(0.5_wp*dt*mu_R*vflux_R_arr(3)*(1._wp/dx(j)), kind=stp) + rhs_vf(momxb)%sf(j, k, l) = rhs_vf(momxb)%sf(j, k, l) + & + real(0.5_wp*dt*mu_R*vflux_R_arr(3)*(1._wp/dx(j)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(E_idx)%sf(j, k, l) = rhs_vf(E_idx)%sf(j, k, & - & l) + real(0.5_wp*dt*mu_R*vflux_R_arr(3)*vel_R(1)*(1._wp/dx(j)), kind=stp) + rhs_vf(E_idx)%sf(j, k, l) = rhs_vf(E_idx)%sf(j, k, l) + & + real(0.5_wp*dt*mu_R*vflux_R_arr(3)*vel_R(1)*(1._wp/dx(j)), kind=stp) end if E_L = 0._wp; E_R = 0._wp @@ -670,143 +753,157 @@ contains E_R = E_R + coeff_R(q)*q_cons_vf(E_idx)%sf(j + q, k, l) end do - call s_get_derived_states(E_L, gamma_L, pi_inf_L, rho_L, vel_L, E_R, gamma_R, pi_inf_R, rho_R, & - & vel_R, pres_L, pres_R, cfl) + call s_get_derived_states(E_L, gamma_L, pi_inf_L, rho_L, vel_L, & + E_R, gamma_R, pi_inf_R, rho_R, vel_R, & + pres_L, pres_R, cfl) do i = 1, num_fluids $:GPU_ATOMIC(atomic='update') - rhs_vf(i)%sf(j + 1, k, l) = rhs_vf(i)%sf(j + 1, k, & - & l) + real((0.5_wp*dt*(alpha_rho_L(i)*vel_L(1))*(1._wp/dx(j + 1)) & - & - 0.5_wp*dt*cfl*(alpha_rho_L(i))*(1._wp/dx(j + 1))), kind=stp) + rhs_vf(i)%sf(j + 1, k, l) = rhs_vf(i)%sf(j + 1, k, l) + & + real((0.5_wp*dt*(alpha_rho_L(i)* & + vel_L(1))*(1._wp/dx(j + 1)) - & + 0.5_wp*dt*cfl*(alpha_rho_L(i))*(1._wp/dx(j + 1))), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(i)%sf(j, k, l) = rhs_vf(i)%sf(j, k, & - & l) - real((0.5_wp*dt*(alpha_rho_L(i)*vel_L(1))*(1._wp/dx(j)) & - & - 0.5_wp*dt*cfl*(alpha_rho_L(i))*(1._wp/dx(j))), kind=stp) + rhs_vf(i)%sf(j, k, l) = rhs_vf(i)%sf(j, k, l) - & + real((0.5_wp*dt*(alpha_rho_L(i)* & + vel_L(1))*(1._wp/dx(j)) - & + 0.5_wp*dt*cfl*(alpha_rho_L(i))*(1._wp/dx(j))), kind=stp) end do if (num_fluids > 1) then $:GPU_LOOP(parallelism='[seq]') do i = 1, num_fluids - 1 $:GPU_ATOMIC(atomic='update') - rhs_vf(advxb + i - 1)%sf(j + 1, k, l) = rhs_vf(advxb + i - 1)%sf(j + 1, k, & - & l) + real((0.5_wp*dt*(alpha_L(i)*vel_L(1))*(1._wp/dx(j + 1)) & - & - 0.5_wp*dt*cfl*(alpha_L(i))*(1._wp/dx(j + 1))), kind=stp) + rhs_vf(advxb + i - 1)%sf(j + 1, k, l) = rhs_vf(advxb + i - 1)%sf(j + 1, k, l) + & + real((0.5_wp*dt*(alpha_L(i)* & + vel_L(1))*(1._wp/dx(j + 1)) - & + 0.5_wp*dt*cfl*(alpha_L(i))*(1._wp/dx(j + 1))), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(advxb + i - 1)%sf(j + 1, k, l) = rhs_vf(advxb + i - 1)%sf(j + 1, k, & - & l) - real((0.5_wp*dt*q_cons_vf(advxb + i - 1)%sf(j + 1, k, & - & l)*vel_L(1)*(1._wp/dx(j + 1))), kind=stp) + rhs_vf(advxb + i - 1)%sf(j + 1, k, l) = rhs_vf(advxb + i - 1)%sf(j + 1, k, l) & + - real((0.5_wp*dt*q_cons_vf(advxb + i - 1)%sf(j + 1, k, l)*vel_L(1)*(1._wp/dx(j + 1))), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(advxb + i - 1)%sf(j, k, l) = rhs_vf(advxb + i - 1)%sf(j, k, & - & l) - real((0.5_wp*dt*(alpha_L(i)*vel_L(1))*(1._wp/dx(j)) & - & - 0.5_wp*dt*cfl*(alpha_L(i))*(1._wp/dx(j))), kind=stp) + rhs_vf(advxb + i - 1)%sf(j, k, l) = rhs_vf(advxb + i - 1)%sf(j, k, l) - & + real((0.5_wp*dt*(alpha_L(i)* & + vel_L(1))*(1._wp/dx(j)) - & + 0.5_wp*dt*cfl*(alpha_L(i))*(1._wp/dx(j))), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(advxb + i - 1)%sf(j, k, l) = rhs_vf(advxb + i - 1)%sf(j, k, & - & l) + real((0.5_wp*dt*q_cons_vf(advxb + i - 1)%sf(j, k, & - & l)*vel_L(1)*(1._wp/dx(j))), kind=stp) + rhs_vf(advxb + i - 1)%sf(j, k, l) = rhs_vf(advxb + i - 1)%sf(j, k, l) & + + real((0.5_wp*dt*q_cons_vf(advxb + i - 1)%sf(j, k, l)*vel_L(1)*(1._wp/dx(j))), kind=stp) end do end if $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb)%sf(j + 1, k, l) = rhs_vf(momxb)%sf(j + 1, k, & - & l) + real((0.5_wp*dt*(rho_L*(vel_L(1))**2.0 + pres_L)*(1._wp/dx(j + 1)) & - & - 0.5_wp*dt*cfl*(rho_L*vel_L(1))*(1._wp/dx(j + 1))), kind=stp) + rhs_vf(momxb)%sf(j + 1, k, l) = rhs_vf(momxb)%sf(j + 1, k, l) + & + real((0.5_wp*dt*(rho_L*(vel_L(1))**2.0 + & + pres_L)*(1._wp/dx(j + 1)) - & + 0.5_wp*dt*cfl*(rho_L*vel_L(1))*(1._wp/dx(j + 1))), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb + 1)%sf(j + 1, k, l) = rhs_vf(momxb + 1)%sf(j + 1, k, & - & l) + real((0.5_wp*dt*rho_L*vel_L(1)*vel_L(2)*(1._wp/dx(j + 1)) & - & - 0.5_wp*dt*cfl*(rho_L*vel_L(2))*(1._wp/dx(j + 1))), kind=stp) + rhs_vf(momxb + 1)%sf(j + 1, k, l) = rhs_vf(momxb + 1)%sf(j + 1, k, l) + & + real((0.5_wp*dt*rho_L*vel_L(1)*vel_L(2)*(1._wp/dx(j + 1)) - & + 0.5_wp*dt*cfl*(rho_L*vel_L(2))*(1._wp/dx(j + 1))), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(E_idx)%sf(j + 1, k, l) = rhs_vf(E_idx)%sf(j + 1, k, & - & l) + real((0.5_wp*dt*(vel_L(1)*(E_L + pres_L))*(1._wp/dx(j + 1)) - 0.5_wp*dt*cfl*(E_L) & - & *(1._wp/dx(j + 1))), kind=stp) + rhs_vf(E_idx)%sf(j + 1, k, l) = rhs_vf(E_idx)%sf(j + 1, k, l) + & + real((0.5_wp*dt*(vel_L(1)*(E_L + & + pres_L))*(1._wp/dx(j + 1)) - & + 0.5_wp*dt*cfl*(E_L)*(1._wp/dx(j + 1))), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb)%sf(j, k, l) = rhs_vf(momxb)%sf(j, k, & - & l) - real((0.5_wp*dt*(rho_L*(vel_L(1))**2.0 + pres_L)*(1._wp/dx(j)) & - & - 0.5_wp*dt*cfl*(rho_L*vel_L(1))*(1._wp/dx(j))), kind=stp) + rhs_vf(momxb)%sf(j, k, l) = rhs_vf(momxb)%sf(j, k, l) - & + real((0.5_wp*dt*(rho_L*(vel_L(1))**2.0 + & + pres_L)*(1._wp/dx(j)) - & + 0.5_wp*dt*cfl*(rho_L*vel_L(1))*(1._wp/dx(j))), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb + 1)%sf(j, k, l) = rhs_vf(momxb + 1)%sf(j, k, & - & l) - real((0.5_wp*dt*rho_L*vel_L(1)*vel_L(2)*(1._wp/dx(j)) & - & - 0.5_wp*dt*cfl*(rho_L*vel_L(2))*(1._wp/dx(j))), kind=stp) + rhs_vf(momxb + 1)%sf(j, k, l) = rhs_vf(momxb + 1)%sf(j, k, l) - & + real((0.5_wp*dt*rho_L*vel_L(1)*vel_L(2)*(1._wp/dx(j)) - & + 0.5_wp*dt*cfl*(rho_L*vel_L(2))*(1._wp/dx(j))), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(E_idx)%sf(j, k, l) = rhs_vf(E_idx)%sf(j, k, & - & l) - real((0.5_wp*dt*(vel_L(1)*(E_L + pres_L))*(1._wp/dx(j)) - 0.5_wp*dt*cfl*(E_L) & - & *(1._wp/dx(j))), kind=stp) + rhs_vf(E_idx)%sf(j, k, l) = rhs_vf(E_idx)%sf(j, k, l) - & + real((0.5_wp*dt*(vel_L(1)*(E_L + & + pres_L))*(1._wp/dx(j)) - & + 0.5_wp*dt*cfl*(E_L)*(1._wp/dx(j))), kind=stp) $:GPU_LOOP(parallelism='[seq]') do i = 1, num_fluids $:GPU_ATOMIC(atomic='update') - rhs_vf(i)%sf(j + 1, k, l) = rhs_vf(i)%sf(j + 1, k, & - & l) + real((0.5_wp*dt*(alpha_rho_R(i)*vel_R(1))*(1._wp/dx(j + 1)) & - & + 0.5_wp*dt*cfl*(alpha_rho_R(i))*(1._wp/dx(j + 1))), kind=stp) + rhs_vf(i)%sf(j + 1, k, l) = rhs_vf(i)%sf(j + 1, k, l) + & + real((0.5_wp*dt*(alpha_rho_R(i)* & + vel_R(1))*(1._wp/dx(j + 1)) + & + 0.5_wp*dt*cfl*(alpha_rho_R(i))*(1._wp/dx(j + 1))), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(i)%sf(j, k, l) = rhs_vf(i)%sf(j, k, & - & l) - real((0.5_wp*dt*(alpha_rho_R(i)*vel_R(1))*(1._wp/dx(j)) & - & + 0.5_wp*dt*cfl*(alpha_rho_R(i))*(1._wp/dx(j))), kind=stp) + rhs_vf(i)%sf(j, k, l) = rhs_vf(i)%sf(j, k, l) - & + real((0.5_wp*dt*(alpha_rho_R(i)* & + vel_R(1))*(1._wp/dx(j)) + & + 0.5_wp*dt*cfl*(alpha_rho_R(i))*(1._wp/dx(j))), kind=stp) end do if (num_fluids > 1) then $:GPU_LOOP(parallelism='[seq]') do i = 1, num_fluids - 1 $:GPU_ATOMIC(atomic='update') - rhs_vf(advxb + i - 1)%sf(j + 1, k, l) = rhs_vf(advxb + i - 1)%sf(j + 1, k, & - & l) + real((0.5_wp*dt*(alpha_R(i)*vel_R(1))*(1._wp/dx(j + 1)) & - & + 0.5_wp*dt*cfl*(alpha_R(i))*(1._wp/dx(j + 1))), kind=stp) + rhs_vf(advxb + i - 1)%sf(j + 1, k, l) = rhs_vf(advxb + i - 1)%sf(j + 1, k, l) + & + real((0.5_wp*dt*(alpha_R(i)* & + vel_R(1))*(1._wp/dx(j + 1)) + & + 0.5_wp*dt*cfl*(alpha_R(i))*(1._wp/dx(j + 1))), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(advxb + i - 1)%sf(j + 1, k, l) = rhs_vf(advxb + i - 1)%sf(j + 1, k, & - & l) - real((0.5_wp*dt*q_cons_vf(advxb + i - 1)%sf(j + 1, k, & - & l)*vel_R(1)*(1._wp/dx(j + 1))), kind=stp) + rhs_vf(advxb + i - 1)%sf(j + 1, k, l) = rhs_vf(advxb + i - 1)%sf(j + 1, k, l) & + - real((0.5_wp*dt*q_cons_vf(advxb + i - 1)%sf(j + 1, k, l)*vel_R(1)*(1._wp/dx(j + 1))), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(advxb + i - 1)%sf(j, k, l) = rhs_vf(advxb + i - 1)%sf(j, k, & - & l) - real((0.5_wp*dt*(alpha_R(i)*vel_R(1))*(1._wp/dx(j)) & - & + 0.5_wp*dt*cfl*(alpha_R(i))*(1._wp/dx(j))), kind=stp) + rhs_vf(advxb + i - 1)%sf(j, k, l) = rhs_vf(advxb + i - 1)%sf(j, k, l) - & + real((0.5_wp*dt*(alpha_R(i)* & + vel_R(1))*(1._wp/dx(j)) + & + 0.5_wp*dt*cfl*(alpha_R(i))*(1._wp/dx(j))), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(advxb + i - 1)%sf(j, k, l) = rhs_vf(advxb + i - 1)%sf(j, k, & - & l) + real((0.5_wp*dt*q_cons_vf(advxb + i - 1)%sf(j, k, & - & l)*vel_R(1)*(1._wp/dx(j))), kind=stp) + rhs_vf(advxb + i - 1)%sf(j, k, l) = rhs_vf(advxb + i - 1)%sf(j, k, l) & + + real((0.5_wp*dt*q_cons_vf(advxb + i - 1)%sf(j, k, l)*vel_R(1)*(1._wp/dx(j))), kind=stp) end do end if $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb)%sf(j + 1, k, l) = rhs_vf(momxb)%sf(j + 1, k, & - & l) + real((0.5_wp*dt*(rho_R*(vel_R(1))**2.0 + pres_R)*(1._wp/dx(j + 1)) & - & + 0.5_wp*dt*cfl*(rho_R*vel_R(1))*(1._wp/dx(j + 1))), kind=stp) + rhs_vf(momxb)%sf(j + 1, k, l) = rhs_vf(momxb)%sf(j + 1, k, l) + & + real((0.5_wp*dt*(rho_R*(vel_R(1))**2.0 + & + pres_R)*(1._wp/dx(j + 1)) + & + 0.5_wp*dt*cfl*(rho_R*vel_R(1))*(1._wp/dx(j + 1))), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb + 1)%sf(j + 1, k, l) = rhs_vf(momxb + 1)%sf(j + 1, k, & - & l) + real((0.5_wp*dt*rho_R*vel_R(1)*vel_R(2)*(1._wp/dx(j + 1)) & - & + 0.5_wp*dt*cfl*(rho_R*vel_R(2))*(1._wp/dx(j + 1))), kind=stp) + rhs_vf(momxb + 1)%sf(j + 1, k, l) = rhs_vf(momxb + 1)%sf(j + 1, k, l) + & + real((0.5_wp*dt*rho_R*vel_R(1)*vel_R(2)*(1._wp/dx(j + 1)) + & + 0.5_wp*dt*cfl*(rho_R*vel_R(2))*(1._wp/dx(j + 1))), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(E_idx)%sf(j + 1, k, l) = rhs_vf(E_idx)%sf(j + 1, k, & - & l) + real((0.5_wp*dt*(vel_R(1)*(E_R + pres_R))*(1._wp/dx(j + 1)) + 0.5_wp*dt*cfl*(E_R) & - & *(1._wp/dx(j + 1))), kind=stp) + rhs_vf(E_idx)%sf(j + 1, k, l) = rhs_vf(E_idx)%sf(j + 1, k, l) + & + real((0.5_wp*dt*(vel_R(1)*(E_R + & + pres_R))*(1._wp/dx(j + 1)) + & + 0.5_wp*dt*cfl*(E_R)*(1._wp/dx(j + 1))), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb)%sf(j, k, l) = rhs_vf(momxb)%sf(j, k, & - & l) - real((0.5_wp*dt*(rho_R*(vel_R(1))**2.0 + pres_R)*(1._wp/dx(j)) & - & + 0.5_wp*dt*cfl*(rho_R*vel_R(1))*(1._wp/dx(j))), kind=stp) + rhs_vf(momxb)%sf(j, k, l) = rhs_vf(momxb)%sf(j, k, l) - & + real((0.5_wp*dt*(rho_R*(vel_R(1))**2.0 + & + pres_R)*(1._wp/dx(j)) + & + 0.5_wp*dt*cfl*(rho_R*vel_R(1))*(1._wp/dx(j))), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb + 1)%sf(j, k, l) = rhs_vf(momxb + 1)%sf(j, k, & - & l) - real((0.5_wp*dt*rho_R*vel_R(1)*vel_R(2)*(1._wp/dx(j)) & - & + 0.5_wp*dt*cfl*(rho_R*vel_R(2))*(1._wp/dx(j))), kind=stp) + rhs_vf(momxb + 1)%sf(j, k, l) = rhs_vf(momxb + 1)%sf(j, k, l) - & + real((0.5_wp*dt*rho_R*vel_R(1)*vel_R(2)*(1._wp/dx(j)) + & + 0.5_wp*dt*cfl*(rho_R*vel_R(2))*(1._wp/dx(j))), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(E_idx)%sf(j, k, l) = rhs_vf(E_idx)%sf(j, k, & - & l) - real((0.5_wp*dt*(vel_R(1)*(E_R + pres_R))*(1._wp/dx(j)) + 0.5_wp*dt*cfl*(E_R) & - & *(1._wp/dx(j))), kind=stp) + rhs_vf(E_idx)%sf(j, k, l) = rhs_vf(E_idx)%sf(j, k, l) - & + real((0.5_wp*dt*(vel_R(1)*(E_R + & + pres_R))*(1._wp/dx(j)) + & + 0.5_wp*dt*cfl*(E_R)*(1._wp/dx(j))), kind=stp) + end do end do end do @@ -814,25 +911,25 @@ contains #:endif else #:if not MFC_CASE_OPTIMIZATION or num_dims > 2 - $:GPU_PARALLEL_LOOP(collapse=3, private='[j, k, l, rho_L, rho_R, gamma_L, gamma_R, pi_inf_L, pi_inf_R, mu_L, & - & mu_R, vel_L, vel_R, pres_L, pres_R, alpha_L, alpha_R, alpha_rho_L, alpha_rho_R, F_L, & - & F_R, E_L, E_R, cfl, dvel, dvel_small, rho_sf_small, vflux_L_arr, vflux_R_arr]') + $:GPU_PARALLEL_LOOP(collapse=3, private='[j,k,l,rho_L, rho_R, gamma_L, gamma_R, pi_inf_L, pi_inf_R, mu_L, mu_R, vel_L, vel_R, pres_L, pres_R, alpha_L, alpha_R, alpha_rho_L, alpha_rho_R, F_L, F_R, E_L, E_R, cfl, dvel, dvel_small, rho_sf_small, vflux_L_arr, vflux_R_arr]') do l = 0, p do k = 0, n do j = -1, m + vflux_L_arr = 0._wp vflux_R_arr = 0._wp #:if MFC_CASE_OPTIMIZATION #:if igr_order == 5 - ! DIR$ unroll 6 + !DIR$ unroll 6 #:elif igr_order == 3 - ! DIR$ unroll 4 + !DIR$ unroll 4 #:endif #:endif $:GPU_LOOP(parallelism='[seq]') do q = vidxb, vidxe - ! x-direction contributions + + !x-direction contributions $:GPU_LOOP(parallelism='[seq]') do i = -1, 1 rho_L = 0._wp @@ -843,12 +940,15 @@ contains rho_sf_small(i) = rho_L end do - dvel_small(1) = (1/(2._wp*dx(j)))*(q_cons_vf(momxb)%sf(j + 1 + q, k, & - & l)/rho_sf_small(1) - q_cons_vf(momxb)%sf(j - 1 + q, k, l)/rho_sf_small(-1)) - dvel_small(2) = (1/(2._wp*dx(j)))*(q_cons_vf(momxb + 1)%sf(j + 1 + q, k, & - & l)/rho_sf_small(1) - q_cons_vf(momxb + 1)%sf(j - 1 + q, k, l)/rho_sf_small(-1)) - dvel_small(3) = (1/(2._wp*dx(j)))*(q_cons_vf(momxb + 2)%sf(j + 1 + q, k, & - & l)/rho_sf_small(1) - q_cons_vf(momxb + 2)%sf(j - 1 + q, k, l)/rho_sf_small(-1)) + dvel_small(1) = (1/(2._wp*dx(j)))*( & + q_cons_vf(momxb)%sf(j + 1 + q, k, l)/rho_sf_small(1) - & + q_cons_vf(momxb)%sf(j - 1 + q, k, l)/rho_sf_small(-1)) + dvel_small(2) = (1/(2._wp*dx(j)))*( & + q_cons_vf(momxb + 1)%sf(j + 1 + q, k, l)/rho_sf_small(1) - & + q_cons_vf(momxb + 1)%sf(j - 1 + q, k, l)/rho_sf_small(-1)) + dvel_small(3) = (1/(2._wp*dx(j)))*( & + q_cons_vf(momxb + 2)%sf(j + 1 + q, k, l)/rho_sf_small(1) - & + q_cons_vf(momxb + 2)%sf(j - 1 + q, k, l)/rho_sf_small(-1)) if (q == 0) then $:GPU_LOOP(parallelism='[seq]') @@ -868,7 +968,7 @@ contains vflux_R_arr(3) = vflux_R_arr(3) + coeff_R(q)*(4._wp*dvel_small(1))/3._wp end if - ! y-direction contributions + !y-direction contributions $:GPU_LOOP(parallelism='[seq]') do i = -1, 1 rho_L = 0._wp @@ -879,12 +979,15 @@ contains rho_sf_small(i) = rho_L end do - dvel_small(1) = (1/(2._wp*dy(k)))*(q_cons_vf(momxb)%sf(j + q, k + 1, & - & l)/rho_sf_small(1) - q_cons_vf(momxb)%sf(j + q, k - 1, l)/rho_sf_small(-1)) - dvel_small(2) = (1/(2._wp*dy(k)))*(q_cons_vf(momxb + 1)%sf(j + q, k + 1, & - & l)/rho_sf_small(1) - q_cons_vf(momxb + 1)%sf(j + q, k - 1, l)/rho_sf_small(-1)) - if (q == 0) dvel_small(3) = (1/(2._wp*dy(k)))*(q_cons_vf(momxb + 2)%sf(j + q, k + 1, & - & l)/rho_sf_small(1) - q_cons_vf(momxb + 2)%sf(j + q, k - 1, l)/rho_sf_small(-1)) + dvel_small(1) = (1/(2._wp*dy(k)))*( & + q_cons_vf(momxb)%sf(j + q, k + 1, l)/rho_sf_small(1) - & + q_cons_vf(momxb)%sf(j + q, k - 1, l)/rho_sf_small(-1)) + dvel_small(2) = (1/(2._wp*dy(k)))*( & + q_cons_vf(momxb + 1)%sf(j + q, k + 1, l)/rho_sf_small(1) - & + q_cons_vf(momxb + 1)%sf(j + q, k - 1, l)/rho_sf_small(-1)) + if (q == 0) dvel_small(3) = (1/(2._wp*dy(k)))*( & + q_cons_vf(momxb + 2)%sf(j + q, k + 1, l)/rho_sf_small(1) - & + q_cons_vf(momxb + 2)%sf(j + q, k - 1, l)/rho_sf_small(-1)) if (q == 0) then $:GPU_LOOP(parallelism='[seq]') do i = 1, num_dims @@ -901,7 +1004,7 @@ contains vflux_R_arr(3) = vflux_R_arr(3) + coeff_R(q)*(-2._wp*dvel_small(2))/3._wp end if - ! z-direction contributions + !z-direction contributions $:GPU_LOOP(parallelism='[seq]') do i = -1, 1 rho_L = 0._wp @@ -912,12 +1015,15 @@ contains rho_sf_small(i) = rho_L end do - dvel_small(1) = (1/(2._wp*dz(l)))*(q_cons_vf(momxb)%sf(j + q, k, & - & l + 1)/rho_sf_small(1) - q_cons_vf(momxb)%sf(j + q, k, l - 1)/rho_sf_small(-1)) - if (q == 0) dvel_small(2) = (1/(2._wp*dz(l)))*(q_cons_vf(momxb + 1)%sf(j + q, k, & - & l + 1)/rho_sf_small(1) - q_cons_vf(momxb + 1)%sf(j + q, k, l - 1)/rho_sf_small(-1)) - dvel_small(3) = (1/(2._wp*dz(l)))*(q_cons_vf(momxb + 2)%sf(j + q, k, & - & l + 1)/rho_sf_small(1) - q_cons_vf(momxb + 2)%sf(j + q, k, l - 1)/rho_sf_small(-1)) + dvel_small(1) = (1/(2._wp*dz(l)))*( & + q_cons_vf(momxb)%sf(j + q, k, l + 1)/rho_sf_small(1) - & + q_cons_vf(momxb)%sf(j + q, k, l - 1)/rho_sf_small(-1)) + if (q == 0) dvel_small(2) = (1/(2._wp*dz(l)))*( & + q_cons_vf(momxb + 1)%sf(j + q, k, l + 1)/rho_sf_small(1) - & + q_cons_vf(momxb + 1)%sf(j + q, k, l - 1)/rho_sf_small(-1)) + dvel_small(3) = (1/(2._wp*dz(l)))*( & + q_cons_vf(momxb + 2)%sf(j + q, k, l + 1)/rho_sf_small(1) - & + q_cons_vf(momxb + 2)%sf(j + q, k, l - 1)/rho_sf_small(-1)) if (q == 0) then $:GPU_LOOP(parallelism='[seq]') do i = 1, num_dims @@ -935,9 +1041,12 @@ contains end if if (q == 0) then - jac_rhs(j, k, l) = real(alf_igr*(2._wp*(dvel(1, 2)*dvel(2, 1) + dvel(1, 3)*dvel(3, & - & 1) + dvel(2, 3)*dvel(3, 2)) + dvel(1, 1)**2._wp + dvel(2, 2)**2._wp + dvel(3, & - & 3)**2._wp + (dvel(1, 1) + dvel(2, 2) + dvel(3, 3))**2._wp), kind=stp) + jac_rhs(j, k, l) = real(alf_igr*(2._wp*(dvel(1, 2)*dvel(2, 1) & + + dvel(1, 3)*dvel(3, 1) & + + dvel(2, 3)*dvel(3, 2)) & + + dvel(1, 1)**2._wp + dvel(2, 2)**2._wp & + + dvel(3, 3)**2._wp & + + (dvel(1, 1) + dvel(2, 2) + dvel(3, 3))**2._wp), kind=stp) end if end do @@ -999,6 +1108,7 @@ contains end do if (num_fluids > 1) then + alpha_L(num_fluids) = 1._wp alpha_R(num_fluids) = 1._wp @@ -1040,88 +1150,88 @@ contains end do $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb + 1)%sf(j + 1, k, l) = rhs_vf(momxb + 1)%sf(j + 1, k, & - & l) - real(0.5_wp*dt*mu_L*vflux_L_arr(1)*(1._wp/dx(j + 1)), kind=stp) + rhs_vf(momxb + 1)%sf(j + 1, k, l) = rhs_vf(momxb + 1)%sf(j + 1, k, l) - & + real(0.5_wp*dt*mu_L*vflux_L_arr(1)*(1._wp/dx(j + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(E_idx)%sf(j + 1, k, l) = rhs_vf(E_idx)%sf(j + 1, k, & - & l) - real(0.5_wp*dt*mu_L*vflux_L_arr(1)*vel_L(2)*(1._wp/dx(j + 1)), kind=stp) + rhs_vf(E_idx)%sf(j + 1, k, l) = rhs_vf(E_idx)%sf(j + 1, k, l) - & + real(0.5_wp*dt*mu_L*vflux_L_arr(1)*vel_L(2)*(1._wp/dx(j + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb + 1)%sf(j, k, l) = rhs_vf(momxb + 1)%sf(j, k, & - & l) + real(0.5_wp*dt*mu_L*vflux_L_arr(1)*(1._wp/dx(j)), kind=stp) + rhs_vf(momxb + 1)%sf(j, k, l) = rhs_vf(momxb + 1)%sf(j, k, l) + & + real(0.5_wp*dt*mu_L*vflux_L_arr(1)*(1._wp/dx(j)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(E_idx)%sf(j, k, l) = rhs_vf(E_idx)%sf(j, k, & - & l) + real(0.5_wp*dt*mu_L*vflux_L_arr(1)*vel_L(2)*(1._wp/dx(j)), kind=stp) + rhs_vf(E_idx)%sf(j, k, l) = rhs_vf(E_idx)%sf(j, k, l) + & + real(0.5_wp*dt*mu_L*vflux_L_arr(1)*vel_L(2)*(1._wp/dx(j)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb + 1)%sf(j + 1, k, l) = rhs_vf(momxb + 1)%sf(j + 1, k, & - & l) - real(0.5_wp*dt*mu_R*vflux_R_arr(1)*(1._wp/dx(j + 1)), kind=stp) + rhs_vf(momxb + 1)%sf(j + 1, k, l) = rhs_vf(momxb + 1)%sf(j + 1, k, l) - & + real(0.5_wp*dt*mu_R*vflux_R_arr(1)*(1._wp/dx(j + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(E_idx)%sf(j + 1, k, l) = rhs_vf(E_idx)%sf(j + 1, k, & - & l) - real(0.5_wp*dt*mu_R*vflux_R_arr(1)*vel_R(2)*(1._wp/dx(j + 1)), kind=stp) + rhs_vf(E_idx)%sf(j + 1, k, l) = rhs_vf(E_idx)%sf(j + 1, k, l) - & + real(0.5_wp*dt*mu_R*vflux_R_arr(1)*vel_R(2)*(1._wp/dx(j + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb + 1)%sf(j, k, l) = rhs_vf(momxb + 1)%sf(j, k, & - & l) + real(0.5_wp*dt*mu_R*vflux_R_arr(1)*(1._wp/dx(j)), kind=stp) + rhs_vf(momxb + 1)%sf(j, k, l) = rhs_vf(momxb + 1)%sf(j, k, l) + & + real(0.5_wp*dt*mu_R*vflux_R_arr(1)*(1._wp/dx(j)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(E_idx)%sf(j, k, l) = rhs_vf(E_idx)%sf(j, k, & - & l) + real(0.5_wp*dt*mu_R*vflux_R_arr(1)*vel_R(2)*(1._wp/dx(j)), kind=stp) + rhs_vf(E_idx)%sf(j, k, l) = rhs_vf(E_idx)%sf(j, k, l) + & + real(0.5_wp*dt*mu_R*vflux_R_arr(1)*vel_R(2)*(1._wp/dx(j)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb + 2)%sf(j + 1, k, l) = rhs_vf(momxb + 2)%sf(j + 1, k, & - & l) - real(0.5_wp*dt*mu_L*vflux_L_arr(2)*(1._wp/dx(j + 1)), kind=stp) + rhs_vf(momxb + 2)%sf(j + 1, k, l) = rhs_vf(momxb + 2)%sf(j + 1, k, l) - & + real(0.5_wp*dt*mu_L*vflux_L_arr(2)*(1._wp/dx(j + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(E_idx)%sf(j + 1, k, l) = rhs_vf(E_idx)%sf(j + 1, k, & - & l) - real(0.5_wp*dt*mu_L*vflux_L_arr(2)*vel_L(3)*(1._wp/dx(j + 1)), kind=stp) + rhs_vf(E_idx)%sf(j + 1, k, l) = rhs_vf(E_idx)%sf(j + 1, k, l) - & + real(0.5_wp*dt*mu_L*vflux_L_arr(2)*vel_L(3)*(1._wp/dx(j + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb + 2)%sf(j, k, l) = rhs_vf(momxb + 2)%sf(j, k, & - & l) + real(0.5_wp*dt*mu_L*vflux_L_arr(2)*(1._wp/dx(j)), kind=stp) + rhs_vf(momxb + 2)%sf(j, k, l) = rhs_vf(momxb + 2)%sf(j, k, l) + & + real(0.5_wp*dt*mu_L*vflux_L_arr(2)*(1._wp/dx(j)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(E_idx)%sf(j, k, l) = rhs_vf(E_idx)%sf(j, k, & - & l) + real(0.5_wp*dt*mu_L*vflux_L_arr(2)*vel_L(3)*(1._wp/dx(j)), kind=stp) + rhs_vf(E_idx)%sf(j, k, l) = rhs_vf(E_idx)%sf(j, k, l) + & + real(0.5_wp*dt*mu_L*vflux_L_arr(2)*vel_L(3)*(1._wp/dx(j)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb + 2)%sf(j + 1, k, l) = rhs_vf(momxb + 2)%sf(j + 1, k, & - & l) - real(0.5_wp*dt*mu_R*vflux_R_arr(2)*(1._wp/dx(j + 1)), kind=stp) + rhs_vf(momxb + 2)%sf(j + 1, k, l) = rhs_vf(momxb + 2)%sf(j + 1, k, l) - & + real(0.5_wp*dt*mu_R*vflux_R_arr(2)*(1._wp/dx(j + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(E_idx)%sf(j + 1, k, l) = rhs_vf(E_idx)%sf(j + 1, k, & - & l) - real(0.5_wp*dt*mu_R*vflux_R_arr(2)*vel_R(3)*(1._wp/dx(j + 1)), kind=stp) + rhs_vf(E_idx)%sf(j + 1, k, l) = rhs_vf(E_idx)%sf(j + 1, k, l) - & + real(0.5_wp*dt*mu_R*vflux_R_arr(2)*vel_R(3)*(1._wp/dx(j + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb + 2)%sf(j, k, l) = rhs_vf(momxb + 2)%sf(j, k, & - & l) + real(0.5_wp*dt*mu_R*vflux_R_arr(2)*(1._wp/dx(j)), kind=stp) + rhs_vf(momxb + 2)%sf(j, k, l) = rhs_vf(momxb + 2)%sf(j, k, l) + & + real(0.5_wp*dt*mu_R*vflux_R_arr(2)*(1._wp/dx(j)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(E_idx)%sf(j, k, l) = rhs_vf(E_idx)%sf(j, k, & - & l) + real(0.5_wp*dt*mu_R*vflux_R_arr(2)*vel_R(3)*(1._wp/dx(j)), kind=stp) + rhs_vf(E_idx)%sf(j, k, l) = rhs_vf(E_idx)%sf(j, k, l) + & + real(0.5_wp*dt*mu_R*vflux_R_arr(2)*vel_R(3)*(1._wp/dx(j)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb)%sf(j + 1, k, l) = rhs_vf(momxb)%sf(j + 1, k, & - & l) - real(0.5_wp*dt*mu_L*vflux_L_arr(3)*(1._wp/dx(j + 1)), kind=stp) + rhs_vf(momxb)%sf(j + 1, k, l) = rhs_vf(momxb)%sf(j + 1, k, l) - & + real(0.5_wp*dt*mu_L*vflux_L_arr(3)*(1._wp/dx(j + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(E_idx)%sf(j + 1, k, l) = rhs_vf(E_idx)%sf(j + 1, k, & - & l) - real(0.5_wp*dt*mu_L*vflux_L_arr(3)*vel_L(1)*(1._wp/dx(j + 1)), kind=stp) + rhs_vf(E_idx)%sf(j + 1, k, l) = rhs_vf(E_idx)%sf(j + 1, k, l) - & + real(0.5_wp*dt*mu_L*vflux_L_arr(3)*vel_L(1)*(1._wp/dx(j + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb)%sf(j, k, l) = rhs_vf(momxb)%sf(j, k, & - & l) + real(0.5_wp*dt*mu_L*vflux_L_arr(3)*(1._wp/dx(j)), kind=stp) + rhs_vf(momxb)%sf(j, k, l) = rhs_vf(momxb)%sf(j, k, l) + & + real(0.5_wp*dt*mu_L*vflux_L_arr(3)*(1._wp/dx(j)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(E_idx)%sf(j, k, l) = rhs_vf(E_idx)%sf(j, k, & - & l) + real(0.5_wp*dt*mu_L*vflux_L_arr(3)*vel_L(1)*(1._wp/dx(j)), kind=stp) + rhs_vf(E_idx)%sf(j, k, l) = rhs_vf(E_idx)%sf(j, k, l) + & + real(0.5_wp*dt*mu_L*vflux_L_arr(3)*vel_L(1)*(1._wp/dx(j)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb)%sf(j + 1, k, l) = rhs_vf(momxb)%sf(j + 1, k, & - & l) - real(0.5_wp*dt*mu_R*vflux_R_arr(3)*(1._wp/dx(j + 1)), kind=stp) + rhs_vf(momxb)%sf(j + 1, k, l) = rhs_vf(momxb)%sf(j + 1, k, l) - & + real(0.5_wp*dt*mu_R*vflux_R_arr(3)*(1._wp/dx(j + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(E_idx)%sf(j + 1, k, l) = rhs_vf(E_idx)%sf(j + 1, k, & - & l) - real(0.5_wp*dt*mu_R*vflux_R_arr(3)*vel_R(1)*(1._wp/dx(j + 1)), kind=stp) + rhs_vf(E_idx)%sf(j + 1, k, l) = rhs_vf(E_idx)%sf(j + 1, k, l) - & + real(0.5_wp*dt*mu_R*vflux_R_arr(3)*vel_R(1)*(1._wp/dx(j + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb)%sf(j, k, l) = rhs_vf(momxb)%sf(j, k, & - & l) + real(0.5_wp*dt*mu_R*vflux_R_arr(3)*(1._wp/dx(j)), kind=stp) + rhs_vf(momxb)%sf(j, k, l) = rhs_vf(momxb)%sf(j, k, l) + & + real(0.5_wp*dt*mu_R*vflux_R_arr(3)*(1._wp/dx(j)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(E_idx)%sf(j, k, l) = rhs_vf(E_idx)%sf(j, k, & - & l) + real(0.5_wp*dt*mu_R*vflux_R_arr(3)*vel_R(1)*(1._wp/dx(j)), kind=stp) + rhs_vf(E_idx)%sf(j, k, l) = rhs_vf(E_idx)%sf(j, k, l) + & + real(0.5_wp*dt*mu_R*vflux_R_arr(3)*vel_R(1)*(1._wp/dx(j)), kind=stp) end if E_L = 0._wp; E_R = 0._wp @@ -1136,164 +1246,178 @@ contains E_R = E_R + coeff_R(q)*q_cons_vf(E_idx)%sf(j + q, k, l) end do - call s_get_derived_states(E_L, gamma_L, pi_inf_L, rho_L, vel_L, E_R, gamma_R, pi_inf_R, rho_R, & - & vel_R, pres_L, pres_R, cfl) + call s_get_derived_states(E_L, gamma_L, pi_inf_L, rho_L, vel_L, & + E_R, gamma_R, pi_inf_R, rho_R, vel_R, & + pres_L, pres_R, cfl) $:GPU_LOOP(parallelism='[seq]') do i = 1, num_fluids $:GPU_ATOMIC(atomic='update') - rhs_vf(i)%sf(j + 1, k, l) = rhs_vf(i)%sf(j + 1, k, & - & l) + real((0.5_wp*dt*(alpha_rho_L(i)*vel_L(1))*(1._wp/dx(j + 1)) & - & - 0.5_wp*dt*cfl*(alpha_rho_L(i))*(1._wp/dx(j + 1))), kind=stp) + rhs_vf(i)%sf(j + 1, k, l) = rhs_vf(i)%sf(j + 1, k, l) + & + real((0.5_wp*dt*(alpha_rho_L(i)* & + vel_L(1))*(1._wp/dx(j + 1)) - & + 0.5_wp*dt*cfl*(alpha_rho_L(i))*(1._wp/dx(j + 1))), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(i)%sf(j, k, l) = rhs_vf(i)%sf(j, k, & - & l) - real((0.5_wp*dt*(alpha_rho_L(i)*vel_L(1))*(1._wp/dx(j)) & - & - 0.5_wp*dt*cfl*(alpha_rho_L(i))*(1._wp/dx(j))), kind=stp) + rhs_vf(i)%sf(j, k, l) = rhs_vf(i)%sf(j, k, l) - & + real((0.5_wp*dt*(alpha_rho_L(i)* & + vel_L(1))*(1._wp/dx(j)) - & + 0.5_wp*dt*cfl*(alpha_rho_L(i))*(1._wp/dx(j))), kind=stp) end do if (num_fluids > 1) then $:GPU_LOOP(parallelism='[seq]') do i = 1, num_fluids - 1 $:GPU_ATOMIC(atomic='update') - rhs_vf(advxb + i - 1)%sf(j + 1, k, l) = rhs_vf(advxb + i - 1)%sf(j + 1, k, & - & l) + real((0.5_wp*dt*(alpha_L(i)*vel_L(1))*(1._wp/dx(j + 1)) & - & - 0.5_wp*dt*cfl*(alpha_L(i))*(1._wp/dx(j + 1))), kind=stp) + rhs_vf(advxb + i - 1)%sf(j + 1, k, l) = rhs_vf(advxb + i - 1)%sf(j + 1, k, l) + & + real((0.5_wp*dt*(alpha_L(i)* & + vel_L(1))*(1._wp/dx(j + 1)) - & + 0.5_wp*dt*cfl*(alpha_L(i))*(1._wp/dx(j + 1))), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(advxb + i - 1)%sf(j + 1, k, l) = rhs_vf(advxb + i - 1)%sf(j + 1, k, & - & l) - real(0.5_wp*dt*q_cons_vf(advxb + i - 1)%sf(j + 1, k, & - & l)*vel_L(1)*(1._wp/dx(j + 1)), kind=stp) + rhs_vf(advxb + i - 1)%sf(j + 1, k, l) = rhs_vf(advxb + i - 1)%sf(j + 1, k, l) & + - real(0.5_wp*dt*q_cons_vf(advxb + i - 1)%sf(j + 1, k, l)*vel_L(1)*(1._wp/dx(j + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(advxb + i - 1)%sf(j, k, l) = rhs_vf(advxb + i - 1)%sf(j, k, & - & l) - real(0.5_wp*dt*(alpha_L(i)*vel_L(1))*(1._wp/dx(j)) & - & - 0.5_wp*dt*cfl*(alpha_L(i))*(1._wp/dx(j)), kind=stp) + rhs_vf(advxb + i - 1)%sf(j, k, l) = rhs_vf(advxb + i - 1)%sf(j, k, l) - & + real(0.5_wp*dt*(alpha_L(i)* & + vel_L(1))*(1._wp/dx(j)) - & + 0.5_wp*dt*cfl*(alpha_L(i))*(1._wp/dx(j)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(advxb + i - 1)%sf(j, k, l) = rhs_vf(advxb + i - 1)%sf(j, k, & - & l) + real(0.5_wp*dt*q_cons_vf(advxb + i - 1)%sf(j, k, l)*vel_L(1)*(1._wp/dx(j)), & - & kind=stp) + rhs_vf(advxb + i - 1)%sf(j, k, l) = rhs_vf(advxb + i - 1)%sf(j, k, l) & + + real(0.5_wp*dt*q_cons_vf(advxb + i - 1)%sf(j, k, l)*vel_L(1)*(1._wp/dx(j)), kind=stp) end do end if $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb)%sf(j + 1, k, l) = rhs_vf(momxb)%sf(j + 1, k, & - & l) + real((0.5_wp*dt*(rho_L*(vel_L(1))**2.0 + pres_L)*(1._wp/dx(j + 1)) & - & - 0.5_wp*dt*cfl*(rho_L*vel_L(1))*(1._wp/dx(j + 1))), kind=stp) + rhs_vf(momxb)%sf(j + 1, k, l) = rhs_vf(momxb)%sf(j + 1, k, l) + & + real((0.5_wp*dt*(rho_L*(vel_L(1))**2.0 + & + pres_L)*(1._wp/dx(j + 1)) - & + 0.5_wp*dt*cfl*(rho_L*vel_L(1))*(1._wp/dx(j + 1))), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb + 1)%sf(j + 1, k, l) = rhs_vf(momxb + 1)%sf(j + 1, k, & - & l) + real((0.5_wp*dt*rho_L*vel_L(1)*vel_L(2)*(1._wp/dx(j + 1)) & - & - 0.5_wp*dt*cfl*(rho_L*vel_L(2))*(1._wp/dx(j + 1))), kind=stp) + rhs_vf(momxb + 1)%sf(j + 1, k, l) = rhs_vf(momxb + 1)%sf(j + 1, k, l) + & + real((0.5_wp*dt*rho_L*vel_L(1)*vel_L(2)*(1._wp/dx(j + 1)) - & + 0.5_wp*dt*cfl*(rho_L*vel_L(2))*(1._wp/dx(j + 1))), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb + 2)%sf(j + 1, k, l) = rhs_vf(momxb + 2)%sf(j + 1, k, & - & l) + real((0.5_wp*dt*rho_L*vel_L(1)*vel_L(3)*(1._wp/dx(j + 1)) & - & - 0.5_wp*dt*cfl*(rho_L*vel_L(3))*(1._wp/dx(j + 1))), kind=stp) + rhs_vf(momxb + 2)%sf(j + 1, k, l) = rhs_vf(momxb + 2)%sf(j + 1, k, l) + & + real((0.5_wp*dt*rho_L*vel_L(1)*vel_L(3)*(1._wp/dx(j + 1)) - & + 0.5_wp*dt*cfl*(rho_L*vel_L(3))*(1._wp/dx(j + 1))), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(E_idx)%sf(j + 1, k, l) = rhs_vf(E_idx)%sf(j + 1, k, & - & l) + real((0.5_wp*dt*(vel_L(1)*(E_L + pres_L))*(1._wp/dx(j + 1)) - 0.5_wp*dt*cfl*(E_L) & - & *(1._wp/dx(j + 1))), kind=stp) + rhs_vf(E_idx)%sf(j + 1, k, l) = rhs_vf(E_idx)%sf(j + 1, k, l) + & + real((0.5_wp*dt*(vel_L(1)*(E_L + & + pres_L))*(1._wp/dx(j + 1)) - & + 0.5_wp*dt*cfl*(E_L)*(1._wp/dx(j + 1))), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb)%sf(j, k, l) = rhs_vf(momxb)%sf(j, k, & - & l) - real((0.5_wp*dt*(rho_L*(vel_L(1))**2.0 + pres_L)*(1._wp/dx(j)) & - & - 0.5_wp*dt*cfl*(rho_L*vel_L(1))*(1._wp/dx(j))), kind=stp) + rhs_vf(momxb)%sf(j, k, l) = rhs_vf(momxb)%sf(j, k, l) - & + real((0.5_wp*dt*(rho_L*(vel_L(1))**2.0 + & + pres_L)*(1._wp/dx(j)) - & + 0.5_wp*dt*cfl*(rho_L*vel_L(1))*(1._wp/dx(j))), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb + 1)%sf(j, k, l) = rhs_vf(momxb + 1)%sf(j, k, & - & l) - real((0.5_wp*dt*rho_L*vel_L(1)*vel_L(2)*(1._wp/dx(j)) & - & - 0.5_wp*dt*cfl*(rho_L*vel_L(2))*(1._wp/dx(j))), kind=stp) + rhs_vf(momxb + 1)%sf(j, k, l) = rhs_vf(momxb + 1)%sf(j, k, l) - & + real((0.5_wp*dt*rho_L*vel_L(1)*vel_L(2)*(1._wp/dx(j)) - & + 0.5_wp*dt*cfl*(rho_L*vel_L(2))*(1._wp/dx(j))), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb + 2)%sf(j, k, l) = rhs_vf(momxb + 2)%sf(j, k, & - & l) - real((0.5_wp*dt*rho_L*vel_L(1)*vel_L(3)*(1._wp/dx(j)) & - & - 0.5_wp*dt*cfl*(rho_L*vel_L(3))*(1._wp/dx(j))), kind=stp) + rhs_vf(momxb + 2)%sf(j, k, l) = rhs_vf(momxb + 2)%sf(j, k, l) - & + real((0.5_wp*dt*rho_L*vel_L(1)*vel_L(3)*(1._wp/dx(j)) - & + 0.5_wp*dt*cfl*(rho_L*vel_L(3))*(1._wp/dx(j))), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(E_idx)%sf(j, k, l) = rhs_vf(E_idx)%sf(j, k, & - & l) - real((0.5_wp*dt*(vel_L(1)*(E_L + pres_L))*(1._wp/dx(j)) - 0.5_wp*dt*cfl*(E_L) & - & *(1._wp/dx(j))), kind=stp) + rhs_vf(E_idx)%sf(j, k, l) = rhs_vf(E_idx)%sf(j, k, l) - & + real((0.5_wp*dt*(vel_L(1)*(E_L + & + pres_L))*(1._wp/dx(j)) - & + 0.5_wp*dt*cfl*(E_L)*(1._wp/dx(j))), kind=stp) $:GPU_LOOP(parallelism='[seq]') do i = 1, num_fluids $:GPU_ATOMIC(atomic='update') - rhs_vf(i)%sf(j + 1, k, l) = rhs_vf(i)%sf(j + 1, k, & - & l) + real((0.5_wp*dt*(alpha_rho_R(i)*vel_R(1))*(1._wp/dx(j + 1)) & - & + 0.5_wp*dt*cfl*(alpha_rho_R(i))*(1._wp/dx(j + 1))), kind=stp) + rhs_vf(i)%sf(j + 1, k, l) = rhs_vf(i)%sf(j + 1, k, l) + & + real((0.5_wp*dt*(alpha_rho_R(i)* & + vel_R(1))*(1._wp/dx(j + 1)) + & + 0.5_wp*dt*cfl*(alpha_rho_R(i))*(1._wp/dx(j + 1))), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(i)%sf(j, k, l) = rhs_vf(i)%sf(j, k, & - & l) - real((0.5_wp*dt*(alpha_rho_R(i)*vel_R(1))*(1._wp/dx(j)) & - & + 0.5_wp*dt*cfl*(alpha_rho_R(i))*(1._wp/dx(j))), kind=stp) + rhs_vf(i)%sf(j, k, l) = rhs_vf(i)%sf(j, k, l) - & + real((0.5_wp*dt*(alpha_rho_R(i)* & + vel_R(1))*(1._wp/dx(j)) + & + 0.5_wp*dt*cfl*(alpha_rho_R(i))*(1._wp/dx(j))), kind=stp) end do if (num_fluids > 1) then $:GPU_LOOP(parallelism='[seq]') do i = 1, num_fluids - 1 $:GPU_ATOMIC(atomic='update') - rhs_vf(advxb + i - 1)%sf(j + 1, k, l) = rhs_vf(advxb + i - 1)%sf(j + 1, k, & - & l) + real((0.5_wp*dt*(alpha_R(i)*vel_R(1))*(1._wp/dx(j + 1)) & - & + 0.5_wp*dt*cfl*(alpha_R(i))*(1._wp/dx(j + 1))), kind=stp) + rhs_vf(advxb + i - 1)%sf(j + 1, k, l) = rhs_vf(advxb + i - 1)%sf(j + 1, k, l) + & + real((0.5_wp*dt*(alpha_R(i)* & + vel_R(1))*(1._wp/dx(j + 1)) + & + 0.5_wp*dt*cfl*(alpha_R(i))*(1._wp/dx(j + 1))), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(advxb + i - 1)%sf(j + 1, k, l) = rhs_vf(advxb + i - 1)%sf(j + 1, k, & - & l) - real((0.5_wp*dt*q_cons_vf(advxb + i - 1)%sf(j + 1, k, & - & l)*vel_R(1)*(1._wp/dx(j + 1))), kind=stp) + rhs_vf(advxb + i - 1)%sf(j + 1, k, l) = rhs_vf(advxb + i - 1)%sf(j + 1, k, l) & + - real((0.5_wp*dt*q_cons_vf(advxb + i - 1)%sf(j + 1, k, l)*vel_R(1)*(1._wp/dx(j + 1))), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(advxb + i - 1)%sf(j, k, l) = rhs_vf(advxb + i - 1)%sf(j, k, & - & l) - real((0.5_wp*dt*(alpha_R(i)*vel_R(1))*(1._wp/dx(j)) & - & + 0.5_wp*dt*cfl*(alpha_R(i))*(1._wp/dx(j))), kind=stp) + rhs_vf(advxb + i - 1)%sf(j, k, l) = rhs_vf(advxb + i - 1)%sf(j, k, l) - & + real((0.5_wp*dt*(alpha_R(i)* & + vel_R(1))*(1._wp/dx(j)) + & + 0.5_wp*dt*cfl*(alpha_R(i))*(1._wp/dx(j))), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(advxb + i - 1)%sf(j, k, l) = rhs_vf(advxb + i - 1)%sf(j, k, & - & l) + real((0.5_wp*dt*q_cons_vf(advxb + i - 1)%sf(j, k, & - & l)*vel_R(1)*(1._wp/dx(j))), kind=stp) + rhs_vf(advxb + i - 1)%sf(j, k, l) = rhs_vf(advxb + i - 1)%sf(j, k, l) & + + real((0.5_wp*dt*q_cons_vf(advxb + i - 1)%sf(j, k, l)*vel_R(1)*(1._wp/dx(j))), kind=stp) end do end if $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb)%sf(j + 1, k, l) = rhs_vf(momxb)%sf(j + 1, k, & - & l) + real((0.5_wp*dt*(rho_R*(vel_R(1))**2.0 + pres_R)*(1._wp/dx(j + 1)) & - & + 0.5_wp*dt*cfl*(rho_R*vel_R(1))*(1._wp/dx(j + 1))), kind=stp) + rhs_vf(momxb)%sf(j + 1, k, l) = rhs_vf(momxb)%sf(j + 1, k, l) + & + real((0.5_wp*dt*(rho_R*(vel_R(1))**2.0 + & + pres_R)*(1._wp/dx(j + 1)) + & + 0.5_wp*dt*cfl*(rho_R*vel_R(1))*(1._wp/dx(j + 1))), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb + 1)%sf(j + 1, k, l) = rhs_vf(momxb + 1)%sf(j + 1, k, & - & l) + real((0.5_wp*dt*rho_R*vel_R(1)*vel_R(2)*(1._wp/dx(j + 1)) & - & + 0.5_wp*dt*cfl*(rho_R*vel_R(2))*(1._wp/dx(j + 1))), kind=stp) + rhs_vf(momxb + 1)%sf(j + 1, k, l) = rhs_vf(momxb + 1)%sf(j + 1, k, l) + & + real((0.5_wp*dt*rho_R*vel_R(1)*vel_R(2)*(1._wp/dx(j + 1)) + & + 0.5_wp*dt*cfl*(rho_R*vel_R(2))*(1._wp/dx(j + 1))), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb + 2)%sf(j + 1, k, l) = rhs_vf(momxb + 2)%sf(j + 1, k, & - & l) + real((0.5_wp*dt*rho_R*vel_R(1)*vel_R(3)*(1._wp/dx(j + 1)) & - & + 0.5_wp*dt*cfl*(rho_R*vel_R(3))*(1._wp/dx(j + 1))), kind=stp) + rhs_vf(momxb + 2)%sf(j + 1, k, l) = rhs_vf(momxb + 2)%sf(j + 1, k, l) + & + real((0.5_wp*dt*rho_R*vel_R(1)*vel_R(3)*(1._wp/dx(j + 1)) + & + 0.5_wp*dt*cfl*(rho_R*vel_R(3))*(1._wp/dx(j + 1))), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(E_idx)%sf(j + 1, k, l) = rhs_vf(E_idx)%sf(j + 1, k, & - & l) + real((0.5_wp*dt*(vel_R(1)*(E_R + pres_R))*(1._wp/dx(j + 1)) + 0.5_wp*dt*cfl*(E_R) & - & *(1._wp/dx(j + 1))), kind=stp) + rhs_vf(E_idx)%sf(j + 1, k, l) = rhs_vf(E_idx)%sf(j + 1, k, l) + & + real((0.5_wp*dt*(vel_R(1)*(E_R + & + pres_R))*(1._wp/dx(j + 1)) + & + 0.5_wp*dt*cfl*(E_R)*(1._wp/dx(j + 1))), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb)%sf(j, k, l) = rhs_vf(momxb)%sf(j, k, & - & l) - real((0.5_wp*dt*(rho_R*(vel_R(1))**2.0 + pres_R)*(1._wp/dx(j)) & - & + 0.5_wp*dt*cfl*(rho_R*vel_R(1))*(1._wp/dx(j))), kind=stp) + rhs_vf(momxb)%sf(j, k, l) = rhs_vf(momxb)%sf(j, k, l) - & + real((0.5_wp*dt*(rho_R*(vel_R(1))**2.0 + & + pres_R)*(1._wp/dx(j)) + & + 0.5_wp*dt*cfl*(rho_R*vel_R(1))*(1._wp/dx(j))), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb + 1)%sf(j, k, l) = rhs_vf(momxb + 1)%sf(j, k, & - & l) - real((0.5_wp*dt*rho_R*vel_R(1)*vel_R(2)*(1._wp/dx(j)) & - & + 0.5_wp*dt*cfl*(rho_R*vel_R(2))*(1._wp/dx(j))), kind=stp) + rhs_vf(momxb + 1)%sf(j, k, l) = rhs_vf(momxb + 1)%sf(j, k, l) - & + real((0.5_wp*dt*rho_R*vel_R(1)*vel_R(2)*(1._wp/dx(j)) + & + 0.5_wp*dt*cfl*(rho_R*vel_R(2))*(1._wp/dx(j))), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb + 2)%sf(j, k, l) = rhs_vf(momxb + 2)%sf(j, k, & - & l) - real((0.5_wp*dt*rho_R*vel_R(1)*vel_R(3)*(1._wp/dx(j)) & - & + 0.5_wp*dt*cfl*(rho_R*vel_R(3))*(1._wp/dx(j))), kind=stp) + rhs_vf(momxb + 2)%sf(j, k, l) = rhs_vf(momxb + 2)%sf(j, k, l) - & + real((0.5_wp*dt*rho_R*vel_R(1)*vel_R(3)*(1._wp/dx(j)) + & + 0.5_wp*dt*cfl*(rho_R*vel_R(3))*(1._wp/dx(j))), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(E_idx)%sf(j, k, l) = rhs_vf(E_idx)%sf(j, k, & - & l) - real((0.5_wp*dt*(vel_R(1)*(E_R + pres_R))*(1._wp/dx(j)) + 0.5_wp*dt*cfl*(E_R) & - & *(1._wp/dx(j))), kind=stp) + rhs_vf(E_idx)%sf(j, k, l) = rhs_vf(E_idx)%sf(j, k, l) - & + real((0.5_wp*dt*(vel_R(1)*(E_R + & + pres_R))*(1._wp/dx(j)) + & + 0.5_wp*dt*cfl*(E_R)*(1._wp/dx(j))), kind=stp) + end do end do end do @@ -1303,26 +1427,26 @@ contains else if (idir == 2) then if (p == 0) then #:if not MFC_CASE_OPTIMIZATION or num_dims > 1 - $:GPU_PARALLEL_LOOP(collapse=3, private='[j, k, l, rho_L, rho_R, gamma_L, gamma_R, pi_inf_L, pi_inf_R, mu_L, & - & mu_R, vel_L, vel_R, pres_L, pres_R, alpha_L, alpha_R, alpha_rho_L, alpha_rho_R, F_L, & - & F_R, E_L, E_R, cfl, dvel_small, rho_sf_small, vflux_L_arr, vflux_R_arr]') + $:GPU_PARALLEL_LOOP(collapse=3, private='[j,k,l,rho_L, rho_R, gamma_L, gamma_R, pi_inf_L, pi_inf_R, mu_L, mu_R, vel_L, vel_R, pres_L, pres_R, alpha_L, alpha_R, alpha_rho_L, alpha_rho_R, F_L, F_R, E_L, E_R, cfl, dvel_small, rho_sf_small, vflux_L_arr, vflux_R_arr]') do l = 0, p do k = -1, n do j = 0, m + if (viscous) then vflux_L_arr = 0._wp vflux_R_arr = 0._wp #:if MFC_CASE_OPTIMIZATION #:if igr_order == 5 - ! DIR$ unroll 6 + !DIR$ unroll 6 #:elif igr_order == 3 - ! DIR$ unroll 4 + !DIR$ unroll 4 #:endif #:endif $:GPU_LOOP(parallelism='[seq]') do q = vidxb, vidxe - ! x-direction contributions + + !x-direction contributions $:GPU_LOOP(parallelism='[seq]') do i = -1, 1 rho_L = 0._wp @@ -1333,10 +1457,12 @@ contains rho_sf_small(i) = rho_L end do - dvel_small(1) = (1/(2._wp*dx(j)))*(q_cons_vf(momxb)%sf(j + 1, k + q, & - & l)/rho_sf_small(1) - q_cons_vf(momxb)%sf(j - 1, k + q, l)/rho_sf_small(-1)) - dvel_small(2) = (1/(2._wp*dx(j)))*(q_cons_vf(momxb + 1)%sf(j + 1, k + q, & - & l)/rho_sf_small(1) - q_cons_vf(momxb + 1)%sf(j - 1, k + q, l)/rho_sf_small(-1)) + dvel_small(1) = (1/(2._wp*dx(j)))*( & + q_cons_vf(momxb)%sf(j + 1, k + q, l)/rho_sf_small(1) - & + q_cons_vf(momxb)%sf(j - 1, k + q, l)/rho_sf_small(-1)) + dvel_small(2) = (1/(2._wp*dx(j)))*( & + q_cons_vf(momxb + 1)%sf(j + 1, k + q, l)/rho_sf_small(1) - & + q_cons_vf(momxb + 1)%sf(j - 1, k + q, l)/rho_sf_small(-1)) if (q > vidxb) then vflux_L_arr(1) = vflux_L_arr(1) + coeff_L(q)*(dvel_small(2)) @@ -1347,7 +1473,7 @@ contains vflux_R_arr(3) = vflux_R_arr(3) + coeff_R(q)*(-2._wp*dvel_small(1))/3._wp end if - ! y-direction contributions + !y-direction contributions $:GPU_LOOP(parallelism='[seq]') do i = -1, 1 rho_L = 0._wp @@ -1358,10 +1484,12 @@ contains rho_sf_small(i) = rho_L end do - dvel_small(1) = (1/(2._wp*dy(k)))*(q_cons_vf(momxb)%sf(j, k + 1 + q, & - & l)/rho_sf_small(1) - q_cons_vf(momxb)%sf(j, k - 1 + q, l)/rho_sf_small(-1)) - dvel_small(2) = (1/(2._wp*dy(k)))*(q_cons_vf(momxb + 1)%sf(j, k + 1 + q, & - & l)/rho_sf_small(1) - q_cons_vf(momxb + 1)%sf(j, k - 1 + q, l)/rho_sf_small(-1)) + dvel_small(1) = (1/(2._wp*dy(k)))*( & + q_cons_vf(momxb)%sf(j, k + 1 + q, l)/rho_sf_small(1) - & + q_cons_vf(momxb)%sf(j, k - 1 + q, l)/rho_sf_small(-1)) + dvel_small(2) = (1/(2._wp*dy(k)))*( & + q_cons_vf(momxb + 1)%sf(j, k + 1 + q, l)/rho_sf_small(1) - & + q_cons_vf(momxb + 1)%sf(j, k - 1 + q, l)/rho_sf_small(-1)) if (q > vidxb) then vflux_L_arr(1) = vflux_L_arr(1) + coeff_L(q)*(dvel_small(1)) @@ -1432,6 +1560,7 @@ contains end do if (num_fluids > 1) then + alpha_L(num_fluids) = 1._wp alpha_R(num_fluids) = 1._wp @@ -1473,60 +1602,60 @@ contains end do $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb)%sf(j, k + 1, l) = rhs_vf(momxb)%sf(j, k + 1, & - & l) - real(0.5_wp*dt*mu_L*vflux_L_arr(1)*(1._wp/dy(k + 1)), kind=stp) + rhs_vf(momxb)%sf(j, k + 1, l) = rhs_vf(momxb)%sf(j, k + 1, l) - & + real(0.5_wp*dt*mu_L*vflux_L_arr(1)*(1._wp/dy(k + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(E_idx)%sf(j, k + 1, l) = rhs_vf(E_idx)%sf(j, k + 1, & - & l) - real(0.5_wp*dt*mu_L*vflux_L_arr(1)*vel_L(1)*(1._wp/dy(k + 1)), kind=stp) + rhs_vf(E_idx)%sf(j, k + 1, l) = rhs_vf(E_idx)%sf(j, k + 1, l) - & + real(0.5_wp*dt*mu_L*vflux_L_arr(1)*vel_L(1)*(1._wp/dy(k + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb)%sf(j, k, l) = rhs_vf(momxb)%sf(j, k, & - & l) + real(0.5_wp*dt*mu_L*vflux_L_arr(1)*(1._wp/dy(k)), kind=stp) + rhs_vf(momxb)%sf(j, k, l) = rhs_vf(momxb)%sf(j, k, l) + & + real(0.5_wp*dt*mu_L*vflux_L_arr(1)*(1._wp/dy(k)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(E_idx)%sf(j, k, l) = rhs_vf(E_idx)%sf(j, k, & - & l) + real(0.5_wp*dt*mu_L*vflux_L_arr(1)*vel_L(1)*(1._wp/dy(k)), kind=stp) + rhs_vf(E_idx)%sf(j, k, l) = rhs_vf(E_idx)%sf(j, k, l) + & + real(0.5_wp*dt*mu_L*vflux_L_arr(1)*vel_L(1)*(1._wp/dy(k)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb)%sf(j, k + 1, l) = rhs_vf(momxb)%sf(j, k + 1, & - & l) - real(0.5_wp*dt*mu_R*vflux_R_arr(1)*(1._wp/dy(k + 1)), kind=stp) + rhs_vf(momxb)%sf(j, k + 1, l) = rhs_vf(momxb)%sf(j, k + 1, l) - & + real(0.5_wp*dt*mu_R*vflux_R_arr(1)*(1._wp/dy(k + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(E_idx)%sf(j, k + 1, l) = rhs_vf(E_idx)%sf(j, k + 1, & - & l) - real(0.5_wp*dt*mu_R*vflux_R_arr(1)*vel_R(1)*(1._wp/dy(k + 1)), kind=stp) + rhs_vf(E_idx)%sf(j, k + 1, l) = rhs_vf(E_idx)%sf(j, k + 1, l) - & + real(0.5_wp*dt*mu_R*vflux_R_arr(1)*vel_R(1)*(1._wp/dy(k + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb)%sf(j, k, l) = rhs_vf(momxb)%sf(j, k, & - & l) + real(0.5_wp*dt*mu_R*vflux_R_arr(1)*(1._wp/dy(k)), kind=stp) + rhs_vf(momxb)%sf(j, k, l) = rhs_vf(momxb)%sf(j, k, l) + & + real(0.5_wp*dt*mu_R*vflux_R_arr(1)*(1._wp/dy(k)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(E_idx)%sf(j, k, l) = rhs_vf(E_idx)%sf(j, k, & - & l) + real(0.5_wp*dt*mu_R*vflux_R_arr(1)*vel_R(1)*(1._wp/dy(k)), kind=stp) + rhs_vf(E_idx)%sf(j, k, l) = rhs_vf(E_idx)%sf(j, k, l) + & + real(0.5_wp*dt*mu_R*vflux_R_arr(1)*vel_R(1)*(1._wp/dy(k)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb + 1)%sf(j, k + 1, l) = rhs_vf(momxb + 1)%sf(j, k + 1, & - & l) - real(0.5_wp*dt*mu_L*vflux_L_arr(3)*(1._wp/dy(k + 1)), kind=stp) + rhs_vf(momxb + 1)%sf(j, k + 1, l) = rhs_vf(momxb + 1)%sf(j, k + 1, l) - & + real(0.5_wp*dt*mu_L*vflux_L_arr(3)*(1._wp/dy(k + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(E_idx)%sf(j, k + 1, l) = rhs_vf(E_idx)%sf(j, k + 1, & - & l) - real(0.5_wp*dt*mu_L*vflux_L_arr(3)*vel_L(2)*(1._wp/dy(k + 1)), kind=stp) + rhs_vf(E_idx)%sf(j, k + 1, l) = rhs_vf(E_idx)%sf(j, k + 1, l) - & + real(0.5_wp*dt*mu_L*vflux_L_arr(3)*vel_L(2)*(1._wp/dy(k + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb + 1)%sf(j, k, l) = rhs_vf(momxb + 1)%sf(j, k, & - & l) + real(0.5_wp*dt*mu_L*vflux_L_arr(3)*(1._wp/dy(k)), kind=stp) + rhs_vf(momxb + 1)%sf(j, k, l) = rhs_vf(momxb + 1)%sf(j, k, l) + & + real(0.5_wp*dt*mu_L*vflux_L_arr(3)*(1._wp/dy(k)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(E_idx)%sf(j, k, l) = rhs_vf(E_idx)%sf(j, k, & - & l) + real(0.5_wp*dt*mu_L*vflux_L_arr(3)*vel_L(2)*(1._wp/dy(k)), kind=stp) + rhs_vf(E_idx)%sf(j, k, l) = rhs_vf(E_idx)%sf(j, k, l) + & + real(0.5_wp*dt*mu_L*vflux_L_arr(3)*vel_L(2)*(1._wp/dy(k)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb + 1)%sf(j, k + 1, l) = rhs_vf(momxb + 1)%sf(j, k + 1, & - & l) - real(0.5_wp*dt*mu_R*vflux_R_arr(3)*(1._wp/dy(k + 1)), kind=stp) + rhs_vf(momxb + 1)%sf(j, k + 1, l) = rhs_vf(momxb + 1)%sf(j, k + 1, l) - & + real(0.5_wp*dt*mu_R*vflux_R_arr(3)*(1._wp/dy(k + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(E_idx)%sf(j, k + 1, l) = rhs_vf(E_idx)%sf(j, k + 1, & - & l) - real(0.5_wp*dt*mu_R*vflux_R_arr(3)*vel_R(2)*(1._wp/dy(k + 1)), kind=stp) + rhs_vf(E_idx)%sf(j, k + 1, l) = rhs_vf(E_idx)%sf(j, k + 1, l) - & + real(0.5_wp*dt*mu_R*vflux_R_arr(3)*vel_R(2)*(1._wp/dy(k + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb + 1)%sf(j, k, l) = rhs_vf(momxb + 1)%sf(j, k, & - & l) + real(0.5_wp*dt*mu_R*vflux_R_arr(3)*(1._wp/dy(k)), kind=stp) + rhs_vf(momxb + 1)%sf(j, k, l) = rhs_vf(momxb + 1)%sf(j, k, l) + & + real(0.5_wp*dt*mu_R*vflux_R_arr(3)*(1._wp/dy(k)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(E_idx)%sf(j, k, l) = rhs_vf(E_idx)%sf(j, k, & - & l) + real(0.5_wp*dt*mu_R*vflux_R_arr(3)*vel_R(2)*(1._wp/dy(k)), kind=stp) + rhs_vf(E_idx)%sf(j, k, l) = rhs_vf(E_idx)%sf(j, k, l) + & + real(0.5_wp*dt*mu_R*vflux_R_arr(3)*vel_R(2)*(1._wp/dy(k)), kind=stp) end if E_L = 0._wp; E_R = 0._wp @@ -1544,137 +1673,150 @@ contains F_R = F_R + coeff_R(q)*jac(j, k + q, l) end do - call s_get_derived_states(E_L, gamma_L, pi_inf_L, rho_L, vel_L, E_R, gamma_R, pi_inf_R, rho_R, & - & vel_R, pres_L, pres_R, cfl) + call s_get_derived_states(E_L, gamma_L, pi_inf_L, rho_L, vel_L, & + E_R, gamma_R, pi_inf_R, rho_R, vel_R, & + pres_L, pres_R, cfl) $:GPU_LOOP(parallelism='[seq]') do i = 1, num_fluids $:GPU_ATOMIC(atomic='update') - rhs_vf(i)%sf(j, k + 1, l) = rhs_vf(i)%sf(j, k + 1, & - & l) + real(0.5_wp*dt*(alpha_rho_L(i)*vel_L(2))*(1._wp/dy(k + 1)) & - & - 0.5_wp*dt*cfl*(alpha_rho_L(i))*(1._wp/dy(k + 1)), kind=stp) + rhs_vf(i)%sf(j, k + 1, l) = rhs_vf(i)%sf(j, k + 1, l) + & + real(0.5_wp*dt*(alpha_rho_L(i)* & + vel_L(2))*(1._wp/dy(k + 1)) - & + 0.5_wp*dt*cfl*(alpha_rho_L(i))*(1._wp/dy(k + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(i)%sf(j, k, l) = rhs_vf(i)%sf(j, k, & - & l) - real(0.5_wp*dt*(alpha_rho_L(i)*vel_L(2))*(1._wp/dy(k)) & - & - 0.5_wp*dt*cfl*(alpha_rho_L(i))*(1._wp/dy(k)), kind=stp) + rhs_vf(i)%sf(j, k, l) = rhs_vf(i)%sf(j, k, l) - & + real(0.5_wp*dt*(alpha_rho_L(i)* & + vel_L(2))*(1._wp/dy(k)) - & + 0.5_wp*dt*cfl*(alpha_rho_L(i))*(1._wp/dy(k)), kind=stp) end do if (num_fluids > 1) then $:GPU_LOOP(parallelism='[seq]') do i = 1, num_fluids - 1 $:GPU_ATOMIC(atomic='update') - rhs_vf(advxb + i - 1)%sf(j, k + 1, l) = rhs_vf(advxb + i - 1)%sf(j, k + 1, & - & l) + real(0.5_wp*dt*(alpha_L(i)*vel_L(2))*(1._wp/dy(k + 1)) & - & - 0.5_wp*dt*cfl*(alpha_L(i))*(1._wp/dy(k + 1)), kind=stp) + rhs_vf(advxb + i - 1)%sf(j, k + 1, l) = rhs_vf(advxb + i - 1)%sf(j, k + 1, l) + & + real(0.5_wp*dt*(alpha_L(i)* & + vel_L(2))*(1._wp/dy(k + 1)) - & + 0.5_wp*dt*cfl*(alpha_L(i))*(1._wp/dy(k + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(advxb + i - 1)%sf(j, k + 1, l) = rhs_vf(advxb + i - 1)%sf(j, k + 1, & - & l) - real(0.5_wp*dt*q_cons_vf(advxb + i - 1)%sf(j, k + 1, & - & l)*vel_L(2)*(1._wp/dy(k + 1)), kind=stp) + rhs_vf(advxb + i - 1)%sf(j, k + 1, l) = rhs_vf(advxb + i - 1)%sf(j, k + 1, l) & + - real(0.5_wp*dt*q_cons_vf(advxb + i - 1)%sf(j, k + 1, l)*vel_L(2)*(1._wp/dy(k + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(advxb + i - 1)%sf(j, k, l) = rhs_vf(advxb + i - 1)%sf(j, k, & - & l) - real(0.5_wp*dt*(alpha_L(i)*vel_L(2))*(1._wp/dy(k)) & - & - 0.5_wp*dt*cfl*(alpha_L(i))*(1._wp/dy(k)), kind=stp) + rhs_vf(advxb + i - 1)%sf(j, k, l) = rhs_vf(advxb + i - 1)%sf(j, k, l) - & + real(0.5_wp*dt*(alpha_L(i)* & + vel_L(2))*(1._wp/dy(k)) - & + 0.5_wp*dt*cfl*(alpha_L(i))*(1._wp/dy(k)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(advxb + i - 1)%sf(j, k, l) = rhs_vf(advxb + i - 1)%sf(j, k, & - & l) + real(0.5_wp*dt*q_cons_vf(advxb + i - 1)%sf(j, k, l)*vel_L(2)*(1._wp/dy(k)), & - & kind=stp) + rhs_vf(advxb + i - 1)%sf(j, k, l) = rhs_vf(advxb + i - 1)%sf(j, k, l) & + + real(0.5_wp*dt*q_cons_vf(advxb + i - 1)%sf(j, k, l)*vel_L(2)*(1._wp/dy(k)), kind=stp) end do end if $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb + 1)%sf(j, k + 1, l) = rhs_vf(momxb + 1)%sf(j, k + 1, & - & l) + real(0.5_wp*dt*(rho_L*(vel_L(2))**2.0 + pres_L + F_L)*(1._wp/dy(k + 1)) & - & - 0.5_wp*dt*cfl*(rho_L*vel_L(2))*(1._wp/dy(k + 1)), kind=stp) + rhs_vf(momxb + 1)%sf(j, k + 1, l) = rhs_vf(momxb + 1)%sf(j, k + 1, l) + & + real(0.5_wp*dt*(rho_L*(vel_L(2))**2.0 + & + pres_L + F_L)*(1._wp/dy(k + 1)) - & + 0.5_wp*dt*cfl*(rho_L*vel_L(2))*(1._wp/dy(k + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb)%sf(j, k + 1, l) = rhs_vf(momxb)%sf(j, k + 1, & - & l) + real(0.5_wp*dt*rho_L*vel_L(1)*vel_L(2)*(1._wp/dy(k + 1)) & - & - 0.5_wp*dt*cfl*(rho_L*vel_L(1))*(1._wp/dy(k + 1)), kind=stp) + rhs_vf(momxb)%sf(j, k + 1, l) = rhs_vf(momxb)%sf(j, k + 1, l) + & + real(0.5_wp*dt*rho_L*vel_L(1)*vel_L(2)*(1._wp/dy(k + 1)) - & + 0.5_wp*dt*cfl*(rho_L*vel_L(1))*(1._wp/dy(k + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(E_idx)%sf(j, k + 1, l) = rhs_vf(E_idx)%sf(j, k + 1, & - & l) + real(0.5_wp*dt*(vel_L(2)*(E_L + pres_L + F_L))*(1._wp/dy(k + 1)) & - & - 0.5_wp*dt*cfl*(E_L)*(1._wp/dy(k + 1)), kind=stp) + rhs_vf(E_idx)%sf(j, k + 1, l) = rhs_vf(E_idx)%sf(j, k + 1, l) + & + real(0.5_wp*dt*(vel_L(2)*(E_L + & + pres_L + F_L))*(1._wp/dy(k + 1)) - & + 0.5_wp*dt*cfl*(E_L)*(1._wp/dy(k + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb + 1)%sf(j, k, l) = rhs_vf(momxb + 1)%sf(j, k, & - & l) - real(0.5_wp*dt*(rho_L*(vel_L(2))**2.0 + pres_L + F_L)*(1._wp/dy(k)) & - & - 0.5_wp*dt*cfl*(rho_L*vel_L(2))*(1._wp/dy(k)), kind=stp) + rhs_vf(momxb + 1)%sf(j, k, l) = rhs_vf(momxb + 1)%sf(j, k, l) - & + real(0.5_wp*dt*(rho_L*(vel_L(2))**2.0 + & + pres_L + F_L)*(1._wp/dy(k)) - & + 0.5_wp*dt*cfl*(rho_L*vel_L(2))*(1._wp/dy(k)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb)%sf(j, k, l) = rhs_vf(momxb)%sf(j, k, & - & l) - real(0.5_wp*dt*rho_L*vel_L(1)*vel_L(2)*(1._wp/dy(k)) - 0.5_wp*dt*cfl*(rho_L*vel_L(1) & - & )*(1._wp/dy(k)), kind=stp) + rhs_vf(momxb)%sf(j, k, l) = rhs_vf(momxb)%sf(j, k, l) - & + real(0.5_wp*dt*rho_L*vel_L(1)*vel_L(2)*(1._wp/dy(k)) - & + 0.5_wp*dt*cfl*(rho_L*vel_L(1))*(1._wp/dy(k)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(E_idx)%sf(j, k, l) = rhs_vf(E_idx)%sf(j, k, & - & l) - real(0.5_wp*dt*(vel_L(2)*(E_L + pres_L + F_L))*(1._wp/dy(k)) - 0.5_wp*dt*cfl*(E_L) & - & *(1._wp/dy(k)), kind=stp) + rhs_vf(E_idx)%sf(j, k, l) = rhs_vf(E_idx)%sf(j, k, l) - & + real(0.5_wp*dt*(vel_L(2)*(E_L + & + pres_L + F_L))*(1._wp/dy(k)) - & + 0.5_wp*dt*cfl*(E_L)*(1._wp/dy(k)), kind=stp) $:GPU_LOOP(parallelism='[seq]') do i = 1, num_fluids $:GPU_ATOMIC(atomic='update') - rhs_vf(i)%sf(j, k + 1, l) = rhs_vf(i)%sf(j, k + 1, & - & l) + real(0.5_wp*dt*(alpha_rho_R(i)*vel_R(2))*(1._wp/dy(k + 1)) & - & + 0.5_wp*dt*cfl*(alpha_rho_R(i))*(1._wp/dy(k + 1)), kind=stp) + rhs_vf(i)%sf(j, k + 1, l) = rhs_vf(i)%sf(j, k + 1, l) + & + real(0.5_wp*dt*(alpha_rho_R(i)* & + vel_R(2))*(1._wp/dy(k + 1)) + & + 0.5_wp*dt*cfl*(alpha_rho_R(i))*(1._wp/dy(k + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(i)%sf(j, k, l) = rhs_vf(i)%sf(j, k, & - & l) - real(0.5_wp*dt*(alpha_rho_R(i)*vel_R(2))*(1._wp/dy(k)) & - & + 0.5_wp*dt*cfl*(alpha_rho_R(i))*(1._wp/dy(k)), kind=stp) + rhs_vf(i)%sf(j, k, l) = rhs_vf(i)%sf(j, k, l) - & + real(0.5_wp*dt*(alpha_rho_R(i)* & + vel_R(2))*(1._wp/dy(k)) + & + 0.5_wp*dt*cfl*(alpha_rho_R(i))*(1._wp/dy(k)), kind=stp) end do if (num_fluids > 1) then $:GPU_LOOP(parallelism='[seq]') do i = 1, num_fluids - 1 $:GPU_ATOMIC(atomic='update') - rhs_vf(advxb + i - 1)%sf(j, k + 1, l) = rhs_vf(advxb + i - 1)%sf(j, k + 1, & - & l) + real(0.5_wp*dt*(alpha_R(i)*vel_R(2))*(1._wp/dy(k + 1)) & - & + 0.5_wp*dt*cfl*(alpha_R(i))*(1._wp/dy(k + 1)), kind=stp) + rhs_vf(advxb + i - 1)%sf(j, k + 1, l) = rhs_vf(advxb + i - 1)%sf(j, k + 1, l) + & + real(0.5_wp*dt*(alpha_R(i)* & + vel_R(2))*(1._wp/dy(k + 1)) + & + 0.5_wp*dt*cfl*(alpha_R(i))*(1._wp/dy(k + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(advxb + i - 1)%sf(j, k + 1, l) = rhs_vf(advxb + i - 1)%sf(j, k + 1, & - & l) - real(0.5_wp*dt*q_cons_vf(advxb + i - 1)%sf(j, k + 1, & - & l)*vel_R(2)*(1._wp/dy(k + 1)), kind=stp) + rhs_vf(advxb + i - 1)%sf(j, k + 1, l) = rhs_vf(advxb + i - 1)%sf(j, k + 1, l) & + - real(0.5_wp*dt*q_cons_vf(advxb + i - 1)%sf(j, k + 1, l)*vel_R(2)*(1._wp/dy(k + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(advxb + i - 1)%sf(j, k, l) = rhs_vf(advxb + i - 1)%sf(j, k, & - & l) - real(0.5_wp*dt*(alpha_R(i)*vel_R(2))*(1._wp/dy(k)) & - & + 0.5_wp*dt*cfl*(alpha_R(i))*(1._wp/dy(k)), kind=stp) + rhs_vf(advxb + i - 1)%sf(j, k, l) = rhs_vf(advxb + i - 1)%sf(j, k, l) - & + real(0.5_wp*dt*(alpha_R(i)* & + vel_R(2))*(1._wp/dy(k)) + & + 0.5_wp*dt*cfl*(alpha_R(i))*(1._wp/dy(k)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(advxb + i - 1)%sf(j, k, l) = rhs_vf(advxb + i - 1)%sf(j, k, & - & l) + real(0.5_wp*dt*q_cons_vf(advxb + i - 1)%sf(j, k, l)*vel_R(2)*(1._wp/dy(k)), & - & kind=stp) + rhs_vf(advxb + i - 1)%sf(j, k, l) = rhs_vf(advxb + i - 1)%sf(j, k, l) & + + real(0.5_wp*dt*q_cons_vf(advxb + i - 1)%sf(j, k, l)*vel_R(2)*(1._wp/dy(k)), kind=stp) end do end if $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb + 1)%sf(j, k + 1, l) = rhs_vf(momxb + 1)%sf(j, k + 1, & - & l) + real(0.5_wp*dt*(rho_R*(vel_R(2))**2.0 + pres_R + F_R)*(1._wp/dy(k + 1)) & - & + 0.5_wp*dt*cfl*(rho_R*vel_R(2))*(1._wp/dy(k + 1)), kind=stp) - $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb)%sf(j, k + 1, l) = rhs_vf(momxb)%sf(j, k + 1, & - & l) + real(0.5_wp*dt*rho_R*vel_R(2)*vel_R(1)*(1._wp/dy(k + 1)) & - & + 0.5_wp*dt*cfl*(rho_R*vel_R(1))*(1._wp/dy(k + 1)), kind=stp) - $:GPU_ATOMIC(atomic='update') - rhs_vf(E_idx)%sf(j, k + 1, l) = rhs_vf(E_idx)%sf(j, k + 1, & - & l) + real(0.5_wp*dt*(vel_R(2)*(E_R + pres_R + F_R))*(1._wp/dy(k + 1)) & - & + 0.5_wp*dt*cfl*(E_R)*(1._wp/dy(k + 1)), kind=stp) - $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb + 1)%sf(j, k, l) = rhs_vf(momxb + 1)%sf(j, k, & - & l) - real(0.5_wp*dt*(rho_R*(vel_R(2))**2.0 + pres_R + F_R)*(1._wp/dy(k)) & - & + 0.5_wp*dt*cfl*(rho_R*vel_R(2))*(1._wp/dy(k)), kind=stp) - $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb)%sf(j, k, l) = rhs_vf(momxb)%sf(j, k, & - & l) - real(0.5_wp*dt*rho_R*vel_R(2)*vel_R(1)*(1._wp/dy(k)) + 0.5_wp*dt*cfl*(rho_R*vel_R(1) & - & )*(1._wp/dy(k)), kind=stp) - $:GPU_ATOMIC(atomic='update') - rhs_vf(E_idx)%sf(j, k, l) = rhs_vf(E_idx)%sf(j, k, & - & l) - real(0.5_wp*dt*(vel_R(2)*(E_R + pres_R + F_R))*(1._wp/dy(k)) + 0.5_wp*dt*cfl*(E_R) & - & *(1._wp/dy(k)), kind=stp) + rhs_vf(momxb + 1)%sf(j, k + 1, l) = rhs_vf(momxb + 1)%sf(j, k + 1, l) + & + real(0.5_wp*dt*(rho_R*(vel_R(2))**2.0 + & + pres_R + F_R)*(1._wp/dy(k + 1)) + & + 0.5_wp*dt*cfl*(rho_R*vel_R(2))*(1._wp/dy(k + 1)), kind=stp) + $:GPU_ATOMIC(atomic='update') + rhs_vf(momxb)%sf(j, k + 1, l) = rhs_vf(momxb)%sf(j, k + 1, l) + & + real(0.5_wp*dt*rho_R*vel_R(2)*vel_R(1)*(1._wp/dy(k + 1)) + & + 0.5_wp*dt*cfl*(rho_R*vel_R(1))*(1._wp/dy(k + 1)), kind=stp) + $:GPU_ATOMIC(atomic='update') + rhs_vf(E_idx)%sf(j, k + 1, l) = rhs_vf(E_idx)%sf(j, k + 1, l) + & + real(0.5_wp*dt*(vel_R(2)*(E_R + & + pres_R + F_R))*(1._wp/dy(k + 1)) + & + 0.5_wp*dt*cfl*(E_R)*(1._wp/dy(k + 1)), kind=stp) + $:GPU_ATOMIC(atomic='update') + rhs_vf(momxb + 1)%sf(j, k, l) = rhs_vf(momxb + 1)%sf(j, k, l) - & + real(0.5_wp*dt*(rho_R*(vel_R(2))**2.0 + & + pres_R + F_R)*(1._wp/dy(k)) + & + 0.5_wp*dt*cfl*(rho_R*vel_R(2))*(1._wp/dy(k)), kind=stp) + $:GPU_ATOMIC(atomic='update') + rhs_vf(momxb)%sf(j, k, l) = rhs_vf(momxb)%sf(j, k, l) - & + real(0.5_wp*dt*rho_R*vel_R(2)*vel_R(1)*(1._wp/dy(k)) + & + 0.5_wp*dt*cfl*(rho_R*vel_R(1))*(1._wp/dy(k)), kind=stp) + $:GPU_ATOMIC(atomic='update') + rhs_vf(E_idx)%sf(j, k, l) = rhs_vf(E_idx)%sf(j, k, l) - & + real(0.5_wp*dt*(vel_R(2)*(E_R + & + pres_R + F_R))*(1._wp/dy(k)) + & + 0.5_wp*dt*cfl*(E_R)*(1._wp/dy(k)), kind=stp) end do end do end do @@ -1682,26 +1824,26 @@ contains #:endif else #:if not MFC_CASE_OPTIMIZATION or num_dims > 2 - $:GPU_PARALLEL_LOOP(collapse=3, private='[j, k, l, rho_L, rho_R, gamma_L, gamma_R, pi_inf_L, pi_inf_R, mu_L, & - & mu_R, vel_L, vel_R, pres_L, pres_R, alpha_L, alpha_R, alpha_rho_L, alpha_rho_R, F_L, & - & F_R, E_L, E_R, cfl, dvel_small, rho_sf_small, vflux_L_arr, vflux_R_arr]') + $:GPU_PARALLEL_LOOP(collapse=3, private='[j,k,l,rho_L, rho_R, gamma_L, gamma_R, pi_inf_L, pi_inf_R, mu_L, mu_R, vel_L, vel_R, pres_L, pres_R, alpha_L, alpha_R, alpha_rho_L, alpha_rho_R, F_L, F_R, E_L, E_R, cfl, dvel_small, rho_sf_small, vflux_L_arr, vflux_R_arr]') do l = 0, p do k = -1, n do j = 0, m + if (viscous) then vflux_L_arr = 0._wp vflux_R_arr = 0._wp #:if MFC_CASE_OPTIMIZATION #:if igr_order == 5 - ! DIR$ unroll 6 + !DIR$ unroll 6 #:elif igr_order == 3 - ! DIR$ unroll 4 + !DIR$ unroll 4 #:endif #:endif $:GPU_LOOP(parallelism='[seq]') do q = vidxb, vidxe - ! x-direction contributions + + !x-direction contributions $:GPU_LOOP(parallelism='[seq]') do i = -1, 1 rho_L = 0._wp @@ -1712,10 +1854,12 @@ contains rho_sf_small(i) = rho_L end do - dvel_small(1) = (1/(2._wp*dx(j)))*(q_cons_vf(momxb)%sf(j + 1, k + q, & - & l)/rho_sf_small(1) - q_cons_vf(momxb)%sf(j - 1, k + q, l)/rho_sf_small(-1)) - dvel_small(2) = (1/(2._wp*dx(j)))*(q_cons_vf(momxb + 1)%sf(j + 1, k + q, & - & l)/rho_sf_small(1) - q_cons_vf(momxb + 1)%sf(j - 1, k + q, l)/rho_sf_small(-1)) + dvel_small(1) = (1/(2._wp*dx(j)))*( & + q_cons_vf(momxb)%sf(j + 1, k + q, l)/rho_sf_small(1) - & + q_cons_vf(momxb)%sf(j - 1, k + q, l)/rho_sf_small(-1)) + dvel_small(2) = (1/(2._wp*dx(j)))*( & + q_cons_vf(momxb + 1)%sf(j + 1, k + q, l)/rho_sf_small(1) - & + q_cons_vf(momxb + 1)%sf(j - 1, k + q, l)/rho_sf_small(-1)) if (q > vidxb) then vflux_L_arr(1) = vflux_L_arr(1) + coeff_L(q)*(dvel_small(2)) @@ -1726,7 +1870,7 @@ contains vflux_R_arr(3) = vflux_R_arr(3) + coeff_R(q)*(-2._wp*dvel_small(1))/3._wp end if - ! y-direction contributions + !y-direction contributions $:GPU_LOOP(parallelism='[seq]') do i = -1, 1 rho_L = 0._wp @@ -1737,12 +1881,15 @@ contains rho_sf_small(i) = rho_L end do - dvel_small(1) = (1/(2._wp*dy(k)))*(q_cons_vf(momxb)%sf(j, k + 1 + q, & - & l)/rho_sf_small(1) - q_cons_vf(momxb)%sf(j, k - 1 + q, l)/rho_sf_small(-1)) - dvel_small(2) = (1/(2._wp*dy(k)))*(q_cons_vf(momxb + 1)%sf(j, k + 1 + q, & - & l)/rho_sf_small(1) - q_cons_vf(momxb + 1)%sf(j, k - 1 + q, l)/rho_sf_small(-1)) - dvel_small(3) = (1/(2._wp*dy(k)))*(q_cons_vf(momxb + 2)%sf(j, k + 1 + q, & - & l)/rho_sf_small(1) - q_cons_vf(momxb + 2)%sf(j, k - 1 + q, l)/rho_sf_small(-1)) + dvel_small(1) = (1/(2._wp*dy(k)))*( & + q_cons_vf(momxb)%sf(j, k + 1 + q, l)/rho_sf_small(1) - & + q_cons_vf(momxb)%sf(j, k - 1 + q, l)/rho_sf_small(-1)) + dvel_small(2) = (1/(2._wp*dy(k)))*( & + q_cons_vf(momxb + 1)%sf(j, k + 1 + q, l)/rho_sf_small(1) - & + q_cons_vf(momxb + 1)%sf(j, k - 1 + q, l)/rho_sf_small(-1)) + dvel_small(3) = (1/(2._wp*dy(k)))*( & + q_cons_vf(momxb + 2)%sf(j, k + 1 + q, l)/rho_sf_small(1) - & + q_cons_vf(momxb + 2)%sf(j, k - 1 + q, l)/rho_sf_small(-1)) if (q > vidxb) then vflux_L_arr(1) = vflux_L_arr(1) + coeff_L(q)*(dvel_small(1)) @@ -1755,7 +1902,7 @@ contains vflux_R_arr(3) = vflux_R_arr(3) + coeff_R(q)*(4._wp*dvel_small(2))/3._wp end if - ! z-direction contributions + !z-direction contributions $:GPU_LOOP(parallelism='[seq]') do i = -1, 1 rho_L = 0._wp @@ -1766,12 +1913,12 @@ contains rho_sf_small(i) = rho_L end do - dvel_small(2) = (1/(2._wp*dz(l)))*(q_cons_vf(momxb + 1)%sf(j, k + q, & - & l + 1)/rho_sf_small(1) - q_cons_vf(momxb + 1)%sf(j, k + q, & - & l - 1)/rho_sf_small(-1)) - dvel_small(3) = (1/(2._wp*dz(l)))*(q_cons_vf(momxb + 2)%sf(j, k + q, & - & l + 1)/rho_sf_small(1) - q_cons_vf(momxb + 2)%sf(j, k + q, & - & l - 1)/rho_sf_small(-1)) + dvel_small(2) = (1/(2._wp*dz(l)))*( & + q_cons_vf(momxb + 1)%sf(j, k + q, l + 1)/rho_sf_small(1) - & + q_cons_vf(momxb + 1)%sf(j, k + q, l - 1)/rho_sf_small(-1)) + dvel_small(3) = (1/(2._wp*dz(l)))*( & + q_cons_vf(momxb + 2)%sf(j, k + q, l + 1)/rho_sf_small(1) - & + q_cons_vf(momxb + 2)%sf(j, k + q, l - 1)/rho_sf_small(-1)) if (q > vidxb) then vflux_L_arr(2) = vflux_L_arr(2) + coeff_L(q)*(dvel_small(2)) vflux_L_arr(3) = vflux_L_arr(3) + coeff_L(q)*(-2._wp*dvel_small(3))/3._wp @@ -1841,6 +1988,7 @@ contains end do if (num_fluids > 1) then + alpha_L(num_fluids) = 1._wp alpha_R(num_fluids) = 1._wp @@ -1882,88 +2030,88 @@ contains end do $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb)%sf(j, k + 1, l) = rhs_vf(momxb)%sf(j, k + 1, & - & l) - real(0.5_wp*dt*mu_L*vflux_L_arr(1)*(1._wp/dy(k + 1)), kind=stp) + rhs_vf(momxb)%sf(j, k + 1, l) = rhs_vf(momxb)%sf(j, k + 1, l) - & + real(0.5_wp*dt*mu_L*vflux_L_arr(1)*(1._wp/dy(k + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(E_idx)%sf(j, k + 1, l) = rhs_vf(E_idx)%sf(j, k + 1, & - & l) - real(0.5_wp*dt*mu_L*vflux_L_arr(1)*vel_L(1)*(1._wp/dy(k + 1)), kind=stp) + rhs_vf(E_idx)%sf(j, k + 1, l) = rhs_vf(E_idx)%sf(j, k + 1, l) - & + real(0.5_wp*dt*mu_L*vflux_L_arr(1)*vel_L(1)*(1._wp/dy(k + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb)%sf(j, k, l) = rhs_vf(momxb)%sf(j, k, & - & l) + real(0.5_wp*dt*mu_L*vflux_L_arr(1)*(1._wp/dy(k)), kind=stp) + rhs_vf(momxb)%sf(j, k, l) = rhs_vf(momxb)%sf(j, k, l) + & + real(0.5_wp*dt*mu_L*vflux_L_arr(1)*(1._wp/dy(k)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(E_idx)%sf(j, k, l) = rhs_vf(E_idx)%sf(j, k, & - & l) + real(0.5_wp*dt*mu_L*vflux_L_arr(1)*vel_L(1)*(1._wp/dy(k)), kind=stp) + rhs_vf(E_idx)%sf(j, k, l) = rhs_vf(E_idx)%sf(j, k, l) + & + real(0.5_wp*dt*mu_L*vflux_L_arr(1)*vel_L(1)*(1._wp/dy(k)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb)%sf(j, k + 1, l) = rhs_vf(momxb)%sf(j, k + 1, & - & l) - real(0.5_wp*dt*mu_R*vflux_R_arr(1)*(1._wp/dy(k + 1)), kind=stp) + rhs_vf(momxb)%sf(j, k + 1, l) = rhs_vf(momxb)%sf(j, k + 1, l) - & + real(0.5_wp*dt*mu_R*vflux_R_arr(1)*(1._wp/dy(k + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(E_idx)%sf(j, k + 1, l) = rhs_vf(E_idx)%sf(j, k + 1, & - & l) - real(0.5_wp*dt*mu_R*vflux_R_arr(1)*vel_R(1)*(1._wp/dy(k + 1)), kind=stp) + rhs_vf(E_idx)%sf(j, k + 1, l) = rhs_vf(E_idx)%sf(j, k + 1, l) - & + real(0.5_wp*dt*mu_R*vflux_R_arr(1)*vel_R(1)*(1._wp/dy(k + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb)%sf(j, k, l) = rhs_vf(momxb)%sf(j, k, & - & l) + real(0.5_wp*dt*mu_R*vflux_R_arr(1)*(1._wp/dy(k)), kind=stp) + rhs_vf(momxb)%sf(j, k, l) = rhs_vf(momxb)%sf(j, k, l) + & + real(0.5_wp*dt*mu_R*vflux_R_arr(1)*(1._wp/dy(k)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(E_idx)%sf(j, k, l) = rhs_vf(E_idx)%sf(j, k, & - & l) + real(0.5_wp*dt*mu_R*vflux_R_arr(1)*vel_R(1)*(1._wp/dy(k)), kind=stp) + rhs_vf(E_idx)%sf(j, k, l) = rhs_vf(E_idx)%sf(j, k, l) + & + real(0.5_wp*dt*mu_R*vflux_R_arr(1)*vel_R(1)*(1._wp/dy(k)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb + 2)%sf(j, k + 1, l) = rhs_vf(momxb + 2)%sf(j, k + 1, & - & l) - real(0.5_wp*dt*mu_L*vflux_L_arr(2)*(1._wp/dy(k + 1)), kind=stp) + rhs_vf(momxb + 2)%sf(j, k + 1, l) = rhs_vf(momxb + 2)%sf(j, k + 1, l) - & + real(0.5_wp*dt*mu_L*vflux_L_arr(2)*(1._wp/dy(k + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(E_idx)%sf(j, k + 1, l) = rhs_vf(E_idx)%sf(j, k + 1, & - & l) - real(0.5_wp*dt*mu_L*vflux_L_arr(2)*vel_L(3)*(1._wp/dy(k + 1)), kind=stp) + rhs_vf(E_idx)%sf(j, k + 1, l) = rhs_vf(E_idx)%sf(j, k + 1, l) - & + real(0.5_wp*dt*mu_L*vflux_L_arr(2)*vel_L(3)*(1._wp/dy(k + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb + 2)%sf(j, k, l) = rhs_vf(momxb + 2)%sf(j, k, & - & l) + real(0.5_wp*dt*mu_L*vflux_L_arr(2)*(1._wp/dy(k)), kind=stp) + rhs_vf(momxb + 2)%sf(j, k, l) = rhs_vf(momxb + 2)%sf(j, k, l) + & + real(0.5_wp*dt*mu_L*vflux_L_arr(2)*(1._wp/dy(k)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(E_idx)%sf(j, k, l) = rhs_vf(E_idx)%sf(j, k, & - & l) + real(0.5_wp*dt*mu_L*vflux_L_arr(2)*vel_L(3)*(1._wp/dy(k)), kind=stp) + rhs_vf(E_idx)%sf(j, k, l) = rhs_vf(E_idx)%sf(j, k, l) + & + real(0.5_wp*dt*mu_L*vflux_L_arr(2)*vel_L(3)*(1._wp/dy(k)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb + 2)%sf(j, k + 1, l) = rhs_vf(momxb + 2)%sf(j, k + 1, & - & l) - real(0.5_wp*dt*mu_R*vflux_R_arr(2)*(1._wp/dy(k + 1)), kind=stp) + rhs_vf(momxb + 2)%sf(j, k + 1, l) = rhs_vf(momxb + 2)%sf(j, k + 1, l) - & + real(0.5_wp*dt*mu_R*vflux_R_arr(2)*(1._wp/dy(k + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(E_idx)%sf(j, k + 1, l) = rhs_vf(E_idx)%sf(j, k + 1, & - & l) - real(0.5_wp*dt*mu_R*vflux_R_arr(2)*vel_R(3)*(1._wp/dy(k + 1)), kind=stp) + rhs_vf(E_idx)%sf(j, k + 1, l) = rhs_vf(E_idx)%sf(j, k + 1, l) - & + real(0.5_wp*dt*mu_R*vflux_R_arr(2)*vel_R(3)*(1._wp/dy(k + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb + 2)%sf(j, k, l) = rhs_vf(momxb + 2)%sf(j, k, & - & l) + real(0.5_wp*dt*mu_R*vflux_R_arr(2)*(1._wp/dy(k)), kind=stp) + rhs_vf(momxb + 2)%sf(j, k, l) = rhs_vf(momxb + 2)%sf(j, k, l) + & + real(0.5_wp*dt*mu_R*vflux_R_arr(2)*(1._wp/dy(k)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(E_idx)%sf(j, k, l) = rhs_vf(E_idx)%sf(j, k, & - & l) + real(0.5_wp*dt*mu_R*vflux_R_arr(2)*vel_R(3)*(1._wp/dy(k)), kind=stp) + rhs_vf(E_idx)%sf(j, k, l) = rhs_vf(E_idx)%sf(j, k, l) + & + real(0.5_wp*dt*mu_R*vflux_R_arr(2)*vel_R(3)*(1._wp/dy(k)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb + 1)%sf(j, k + 1, l) = rhs_vf(momxb + 1)%sf(j, k + 1, & - & l) - real(0.5_wp*dt*mu_L*vflux_L_arr(3)*(1._wp/dy(k + 1)), kind=stp) + rhs_vf(momxb + 1)%sf(j, k + 1, l) = rhs_vf(momxb + 1)%sf(j, k + 1, l) - & + real(0.5_wp*dt*mu_L*vflux_L_arr(3)*(1._wp/dy(k + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(E_idx)%sf(j, k + 1, l) = rhs_vf(E_idx)%sf(j, k + 1, & - & l) - real(0.5_wp*dt*mu_L*vflux_L_arr(3)*vel_L(2)*(1._wp/dy(k + 1)), kind=stp) + rhs_vf(E_idx)%sf(j, k + 1, l) = rhs_vf(E_idx)%sf(j, k + 1, l) - & + real(0.5_wp*dt*mu_L*vflux_L_arr(3)*vel_L(2)*(1._wp/dy(k + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb + 1)%sf(j, k, l) = rhs_vf(momxb + 1)%sf(j, k, & - & l) + real(0.5_wp*dt*mu_L*vflux_L_arr(3)*(1._wp/dy(k)), kind=stp) + rhs_vf(momxb + 1)%sf(j, k, l) = rhs_vf(momxb + 1)%sf(j, k, l) + & + real(0.5_wp*dt*mu_L*vflux_L_arr(3)*(1._wp/dy(k)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(E_idx)%sf(j, k, l) = rhs_vf(E_idx)%sf(j, k, & - & l) + real(0.5_wp*dt*mu_L*vflux_L_arr(3)*vel_L(2)*(1._wp/dy(k)), kind=stp) + rhs_vf(E_idx)%sf(j, k, l) = rhs_vf(E_idx)%sf(j, k, l) + & + real(0.5_wp*dt*mu_L*vflux_L_arr(3)*vel_L(2)*(1._wp/dy(k)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb + 1)%sf(j, k + 1, l) = rhs_vf(momxb + 1)%sf(j, k + 1, & - & l) - real(0.5_wp*dt*mu_R*vflux_R_arr(3)*(1._wp/dy(k + 1)), kind=stp) + rhs_vf(momxb + 1)%sf(j, k + 1, l) = rhs_vf(momxb + 1)%sf(j, k + 1, l) - & + real(0.5_wp*dt*mu_R*vflux_R_arr(3)*(1._wp/dy(k + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(E_idx)%sf(j, k + 1, l) = rhs_vf(E_idx)%sf(j, k + 1, & - & l) - real(0.5_wp*dt*mu_R*vflux_R_arr(3)*vel_R(2)*(1._wp/dy(k + 1)), kind=stp) + rhs_vf(E_idx)%sf(j, k + 1, l) = rhs_vf(E_idx)%sf(j, k + 1, l) - & + real(0.5_wp*dt*mu_R*vflux_R_arr(3)*vel_R(2)*(1._wp/dy(k + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb + 1)%sf(j, k, l) = rhs_vf(momxb + 1)%sf(j, k, & - & l) + real(0.5_wp*dt*mu_R*vflux_R_arr(3)*(1._wp/dy(k)), kind=stp) + rhs_vf(momxb + 1)%sf(j, k, l) = rhs_vf(momxb + 1)%sf(j, k, l) + & + real(0.5_wp*dt*mu_R*vflux_R_arr(3)*(1._wp/dy(k)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(E_idx)%sf(j, k, l) = rhs_vf(E_idx)%sf(j, k, & - & l) + real(0.5_wp*dt*mu_R*vflux_R_arr(3)*vel_R(2)*(1._wp/dy(k)), kind=stp) + rhs_vf(E_idx)%sf(j, k, l) = rhs_vf(E_idx)%sf(j, k, l) + & + real(0.5_wp*dt*mu_R*vflux_R_arr(3)*vel_R(2)*(1._wp/dy(k)), kind=stp) end if E_L = 0._wp; E_R = 0._wp @@ -1981,192 +2129,206 @@ contains F_R = F_R + coeff_R(q)*jac(j, k + q, l) end do - call s_get_derived_states(E_L, gamma_L, pi_inf_L, rho_L, vel_L, E_R, gamma_R, pi_inf_R, rho_R, & - & vel_R, pres_L, pres_R, cfl) + call s_get_derived_states(E_L, gamma_L, pi_inf_L, rho_L, vel_L, & + E_R, gamma_R, pi_inf_R, rho_R, vel_R, & + pres_L, pres_R, cfl) $:GPU_LOOP(parallelism='[seq]') do i = 1, num_fluids $:GPU_ATOMIC(atomic='update') - rhs_vf(i)%sf(j, k + 1, l) = rhs_vf(i)%sf(j, k + 1, & - & l) + real(0.5_wp*dt*(alpha_rho_L(i)*vel_L(2))*(1._wp/dy(k + 1)) & - & - 0.5_wp*dt*cfl*(alpha_rho_L(i))*(1._wp/dy(k + 1)), kind=stp) + rhs_vf(i)%sf(j, k + 1, l) = rhs_vf(i)%sf(j, k + 1, l) + & + real(0.5_wp*dt*(alpha_rho_L(i)* & + vel_L(2))*(1._wp/dy(k + 1)) - & + 0.5_wp*dt*cfl*(alpha_rho_L(i))*(1._wp/dy(k + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(i)%sf(j, k, l) = rhs_vf(i)%sf(j, k, & - & l) - real(0.5_wp*dt*(alpha_rho_L(i)*vel_L(2))*(1._wp/dy(k)) & - & - 0.5_wp*dt*cfl*(alpha_rho_L(i))*(1._wp/dy(k)), kind=stp) + rhs_vf(i)%sf(j, k, l) = rhs_vf(i)%sf(j, k, l) - & + real(0.5_wp*dt*(alpha_rho_L(i)* & + vel_L(2))*(1._wp/dy(k)) - & + 0.5_wp*dt*cfl*(alpha_rho_L(i))*(1._wp/dy(k)), kind=stp) end do if (num_fluids > 1) then $:GPU_LOOP(parallelism='[seq]') do i = 1, num_fluids - 1 $:GPU_ATOMIC(atomic='update') - rhs_vf(advxb + i - 1)%sf(j, k + 1, l) = rhs_vf(advxb + i - 1)%sf(j, k + 1, & - & l) + real(0.5_wp*dt*(alpha_L(i)*vel_L(2))*(1._wp/dy(k + 1)) & - & - 0.5_wp*dt*cfl*(alpha_L(i))*(1._wp/dy(k + 1)), kind=stp) + rhs_vf(advxb + i - 1)%sf(j, k + 1, l) = rhs_vf(advxb + i - 1)%sf(j, k + 1, l) + & + real(0.5_wp*dt*(alpha_L(i)* & + vel_L(2))*(1._wp/dy(k + 1)) - & + 0.5_wp*dt*cfl*(alpha_L(i))*(1._wp/dy(k + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(advxb + i - 1)%sf(j, k + 1, l) = rhs_vf(advxb + i - 1)%sf(j, k + 1, & - & l) - real(0.5_wp*dt*q_cons_vf(advxb + i - 1)%sf(j, k + 1, & - & l)*vel_L(2)*(1._wp/dy(k + 1)), kind=stp) + rhs_vf(advxb + i - 1)%sf(j, k + 1, l) = rhs_vf(advxb + i - 1)%sf(j, k + 1, l) & + - real(0.5_wp*dt*q_cons_vf(advxb + i - 1)%sf(j, k + 1, l)*vel_L(2)*(1._wp/dy(k + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(advxb + i - 1)%sf(j, k, l) = rhs_vf(advxb + i - 1)%sf(j, k, & - & l) - real(0.5_wp*dt*(alpha_L(i)*vel_L(2))*(1._wp/dy(k)) & - & - 0.5_wp*dt*cfl*(alpha_L(i))*(1._wp/dy(k)), kind=stp) + rhs_vf(advxb + i - 1)%sf(j, k, l) = rhs_vf(advxb + i - 1)%sf(j, k, l) - & + real(0.5_wp*dt*(alpha_L(i)* & + vel_L(2))*(1._wp/dy(k)) - & + 0.5_wp*dt*cfl*(alpha_L(i))*(1._wp/dy(k)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(advxb + i - 1)%sf(j, k, l) = rhs_vf(advxb + i - 1)%sf(j, k, & - & l) + real(0.5_wp*dt*q_cons_vf(advxb + i - 1)%sf(j, k, l)*vel_L(2)*(1._wp/dy(k)), & - & kind=stp) + rhs_vf(advxb + i - 1)%sf(j, k, l) = rhs_vf(advxb + i - 1)%sf(j, k, l) & + + real(0.5_wp*dt*q_cons_vf(advxb + i - 1)%sf(j, k, l)*vel_L(2)*(1._wp/dy(k)), kind=stp) end do end if $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb + 1)%sf(j, k + 1, l) = rhs_vf(momxb + 1)%sf(j, k + 1, & - & l) + real(0.5_wp*dt*(rho_L*(vel_L(2))**2.0 + pres_L + F_L)*(1._wp/dy(k + 1)) & - & - 0.5_wp*dt*cfl*(rho_L*vel_L(2))*(1._wp/dy(k + 1)), kind=stp) + rhs_vf(momxb + 1)%sf(j, k + 1, l) = rhs_vf(momxb + 1)%sf(j, k + 1, l) + & + real(0.5_wp*dt*(rho_L*(vel_L(2))**2.0 + & + pres_L + F_L)*(1._wp/dy(k + 1)) - & + 0.5_wp*dt*cfl*(rho_L*vel_L(2))*(1._wp/dy(k + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb)%sf(j, k + 1, l) = rhs_vf(momxb)%sf(j, k + 1, & - & l) + real(0.5_wp*dt*rho_L*vel_L(1)*vel_L(2)*(1._wp/dy(k + 1)) & - & - 0.5_wp*dt*cfl*(rho_L*vel_L(1))*(1._wp/dy(k + 1)), kind=stp) + rhs_vf(momxb)%sf(j, k + 1, l) = rhs_vf(momxb)%sf(j, k + 1, l) + & + real(0.5_wp*dt*rho_L*vel_L(1)*vel_L(2)*(1._wp/dy(k + 1)) - & + 0.5_wp*dt*cfl*(rho_L*vel_L(1))*(1._wp/dy(k + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb + 2)%sf(j, k + 1, l) = rhs_vf(momxb + 2)%sf(j, k + 1, & - & l) + real(0.5_wp*dt*rho_L*vel_L(3)*vel_L(2)*(1._wp/dy(k + 1)) & - & - 0.5_wp*dt*cfl*(rho_L*vel_L(3))*(1._wp/dy(k + 1)), kind=stp) + rhs_vf(momxb + 2)%sf(j, k + 1, l) = rhs_vf(momxb + 2)%sf(j, k + 1, l) + & + real(0.5_wp*dt*rho_L*vel_L(3)*vel_L(2)*(1._wp/dy(k + 1)) - & + 0.5_wp*dt*cfl*(rho_L*vel_L(3))*(1._wp/dy(k + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(E_idx)%sf(j, k + 1, l) = rhs_vf(E_idx)%sf(j, k + 1, & - & l) + real(0.5_wp*dt*(vel_L(2)*(E_L + pres_L + F_L))*(1._wp/dy(k + 1)) & - & - 0.5_wp*dt*cfl*(E_L)*(1._wp/dy(k + 1)), kind=stp) + rhs_vf(E_idx)%sf(j, k + 1, l) = rhs_vf(E_idx)%sf(j, k + 1, l) + & + real(0.5_wp*dt*(vel_L(2)*(E_L + & + pres_L + F_L))*(1._wp/dy(k + 1)) - & + 0.5_wp*dt*cfl*(E_L)*(1._wp/dy(k + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb + 1)%sf(j, k, l) = rhs_vf(momxb + 1)%sf(j, k, & - & l) - real(0.5_wp*dt*(rho_L*(vel_L(2))**2.0 + pres_L + F_L)*(1._wp/dy(k)) & - & - 0.5_wp*dt*cfl*(rho_L*vel_L(2))*(1._wp/dy(k)), kind=stp) + rhs_vf(momxb + 1)%sf(j, k, l) = rhs_vf(momxb + 1)%sf(j, k, l) - & + real(0.5_wp*dt*(rho_L*(vel_L(2))**2.0 + & + pres_L + F_L)*(1._wp/dy(k)) - & + 0.5_wp*dt*cfl*(rho_L*vel_L(2))*(1._wp/dy(k)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb)%sf(j, k, l) = rhs_vf(momxb)%sf(j, k, & - & l) - real(0.5_wp*dt*rho_L*vel_L(1)*vel_L(2)*(1._wp/dy(k)) - 0.5_wp*dt*cfl*(rho_L*vel_L(1) & - & )*(1._wp/dy(k)), kind=stp) + rhs_vf(momxb)%sf(j, k, l) = rhs_vf(momxb)%sf(j, k, l) - & + real(0.5_wp*dt*rho_L*vel_L(1)*vel_L(2)*(1._wp/dy(k)) - & + 0.5_wp*dt*cfl*(rho_L*vel_L(1))*(1._wp/dy(k)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb + 2)%sf(j, k, l) = rhs_vf(momxb + 2)%sf(j, k, & - & l) - real(0.5_wp*dt*rho_L*vel_L(3)*vel_L(2)*(1._wp/dy(k)) - 0.5_wp*dt*cfl*(rho_L*vel_L(3) & - & )*(1._wp/dy(k)), kind=stp) + rhs_vf(momxb + 2)%sf(j, k, l) = rhs_vf(momxb + 2)%sf(j, k, l) - & + real(0.5_wp*dt*rho_L*vel_L(3)*vel_L(2)*(1._wp/dy(k)) - & + 0.5_wp*dt*cfl*(rho_L*vel_L(3))*(1._wp/dy(k)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(E_idx)%sf(j, k, l) = rhs_vf(E_idx)%sf(j, k, & - & l) - real(0.5_wp*dt*(vel_L(2)*(E_L + pres_L + F_L))*(1._wp/dy(k)) - 0.5_wp*dt*cfl*(E_L) & - & *(1._wp/dy(k)), kind=stp) + rhs_vf(E_idx)%sf(j, k, l) = rhs_vf(E_idx)%sf(j, k, l) - & + real(0.5_wp*dt*(vel_L(2)*(E_L + & + pres_L + F_L))*(1._wp/dy(k)) - & + 0.5_wp*dt*cfl*(E_L)*(1._wp/dy(k)), kind=stp) $:GPU_LOOP(parallelism='[seq]') do i = 1, num_fluids $:GPU_ATOMIC(atomic='update') - rhs_vf(i)%sf(j, k + 1, l) = rhs_vf(i)%sf(j, k + 1, & - & l) + real(0.5_wp*dt*(alpha_rho_R(i)*vel_R(2))*(1._wp/dy(k + 1)) & - & + 0.5_wp*dt*cfl*(alpha_rho_R(i))*(1._wp/dy(k + 1)), kind=stp) + rhs_vf(i)%sf(j, k + 1, l) = rhs_vf(i)%sf(j, k + 1, l) + & + real(0.5_wp*dt*(alpha_rho_R(i)* & + vel_R(2))*(1._wp/dy(k + 1)) + & + 0.5_wp*dt*cfl*(alpha_rho_R(i))*(1._wp/dy(k + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(i)%sf(j, k, l) = rhs_vf(i)%sf(j, k, & - & l) - real(0.5_wp*dt*(alpha_rho_R(i)*vel_R(2))*(1._wp/dy(k)) & - & + 0.5_wp*dt*cfl*(alpha_rho_R(i))*(1._wp/dy(k)), kind=stp) + rhs_vf(i)%sf(j, k, l) = rhs_vf(i)%sf(j, k, l) - & + real(0.5_wp*dt*(alpha_rho_R(i)* & + vel_R(2))*(1._wp/dy(k)) + & + 0.5_wp*dt*cfl*(alpha_rho_R(i))*(1._wp/dy(k)), kind=stp) end do if (num_fluids > 1) then $:GPU_LOOP(parallelism='[seq]') do i = 1, num_fluids - 1 $:GPU_ATOMIC(atomic='update') - rhs_vf(advxb + i - 1)%sf(j, k + 1, l) = rhs_vf(advxb + i - 1)%sf(j, k + 1, & - & l) + real(0.5_wp*dt*(alpha_R(i)*vel_R(2))*(1._wp/dy(k + 1)) & - & + 0.5_wp*dt*cfl*(alpha_R(i))*(1._wp/dy(k + 1)), kind=stp) + rhs_vf(advxb + i - 1)%sf(j, k + 1, l) = rhs_vf(advxb + i - 1)%sf(j, k + 1, l) + & + real(0.5_wp*dt*(alpha_R(i)* & + vel_R(2))*(1._wp/dy(k + 1)) + & + 0.5_wp*dt*cfl*(alpha_R(i))*(1._wp/dy(k + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(advxb + i - 1)%sf(j, k + 1, l) = rhs_vf(advxb + i - 1)%sf(j, k + 1, & - & l) - real(0.5_wp*dt*q_cons_vf(advxb + i - 1)%sf(j, k + 1, & - & l)*vel_R(2)*(1._wp/dy(k + 1)), kind=stp) + rhs_vf(advxb + i - 1)%sf(j, k + 1, l) = rhs_vf(advxb + i - 1)%sf(j, k + 1, l) & + - real(0.5_wp*dt*q_cons_vf(advxb + i - 1)%sf(j, k + 1, l)*vel_R(2)*(1._wp/dy(k + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(advxb + i - 1)%sf(j, k, l) = rhs_vf(advxb + i - 1)%sf(j, k, & - & l) - real(0.5_wp*dt*(alpha_R(i)*vel_R(2))*(1._wp/dy(k)) & - & + 0.5_wp*dt*cfl*(alpha_R(i))*(1._wp/dy(k)), kind=stp) + rhs_vf(advxb + i - 1)%sf(j, k, l) = rhs_vf(advxb + i - 1)%sf(j, k, l) - & + real(0.5_wp*dt*(alpha_R(i)* & + vel_R(2))*(1._wp/dy(k)) + & + 0.5_wp*dt*cfl*(alpha_R(i))*(1._wp/dy(k)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(advxb + i - 1)%sf(j, k, l) = rhs_vf(advxb + i - 1)%sf(j, k, & - & l) + real(0.5_wp*dt*q_cons_vf(advxb + i - 1)%sf(j, k, l)*vel_R(2)*(1._wp/dy(k)), & - & kind=stp) + rhs_vf(advxb + i - 1)%sf(j, k, l) = rhs_vf(advxb + i - 1)%sf(j, k, l) & + + real(0.5_wp*dt*q_cons_vf(advxb + i - 1)%sf(j, k, l)*vel_R(2)*(1._wp/dy(k)), kind=stp) end do end if $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb + 1)%sf(j, k + 1, l) = rhs_vf(momxb + 1)%sf(j, k + 1, & - & l) + real(0.5_wp*dt*(rho_R*(vel_R(2))**2.0 + pres_R + F_R)*(1._wp/dy(k + 1)) & - & + 0.5_wp*dt*cfl*(rho_R*vel_R(2))*(1._wp/dy(k + 1)), kind=stp) + rhs_vf(momxb + 1)%sf(j, k + 1, l) = rhs_vf(momxb + 1)%sf(j, k + 1, l) + & + real(0.5_wp*dt*(rho_R*(vel_R(2))**2.0 + & + pres_R + F_R)*(1._wp/dy(k + 1)) + & + 0.5_wp*dt*cfl*(rho_R*vel_R(2))*(1._wp/dy(k + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb)%sf(j, k + 1, l) = rhs_vf(momxb)%sf(j, k + 1, & - & l) + real(0.5_wp*dt*rho_R*vel_R(2)*vel_R(1)*(1._wp/dy(k + 1)) & - & + 0.5_wp*dt*cfl*(rho_R*vel_R(1))*(1._wp/dy(k + 1)), kind=stp) + rhs_vf(momxb)%sf(j, k + 1, l) = rhs_vf(momxb)%sf(j, k + 1, l) + & + real(0.5_wp*dt*rho_R*vel_R(2)*vel_R(1)*(1._wp/dy(k + 1)) + & + 0.5_wp*dt*cfl*(rho_R*vel_R(1))*(1._wp/dy(k + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb + 2)%sf(j, k + 1, l) = rhs_vf(momxb + 2)%sf(j, k + 1, & - & l) + real(0.5_wp*dt*rho_R*vel_R(2)*vel_R(3)*(1._wp/dy(k + 1)) & - & + 0.5_wp*dt*cfl*(rho_R*vel_R(3))*(1._wp/dy(k + 1)), kind=stp) + rhs_vf(momxb + 2)%sf(j, k + 1, l) = rhs_vf(momxb + 2)%sf(j, k + 1, l) + & + real(0.5_wp*dt*rho_R*vel_R(2)*vel_R(3)*(1._wp/dy(k + 1)) + & + 0.5_wp*dt*cfl*(rho_R*vel_R(3))*(1._wp/dy(k + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(E_idx)%sf(j, k + 1, l) = rhs_vf(E_idx)%sf(j, k + 1, & - & l) + real(0.5_wp*dt*(vel_R(2)*(E_R + pres_R + F_R))*(1._wp/dy(k + 1)) & - & + 0.5_wp*dt*cfl*(E_R)*(1._wp/dy(k + 1)), kind=stp) + rhs_vf(E_idx)%sf(j, k + 1, l) = rhs_vf(E_idx)%sf(j, k + 1, l) + & + real(0.5_wp*dt*(vel_R(2)*(E_R + & + pres_R + F_R))*(1._wp/dy(k + 1)) + & + 0.5_wp*dt*cfl*(E_R)*(1._wp/dy(k + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb + 1)%sf(j, k, l) = rhs_vf(momxb + 1)%sf(j, k, & - & l) - real(0.5_wp*dt*(rho_R*(vel_R(2))**2.0 + pres_R + F_R)*(1._wp/dy(k)) & - & + 0.5_wp*dt*cfl*(rho_R*vel_R(2))*(1._wp/dy(k)), kind=stp) + rhs_vf(momxb + 1)%sf(j, k, l) = rhs_vf(momxb + 1)%sf(j, k, l) - & + real(0.5_wp*dt*(rho_R*(vel_R(2))**2.0 + & + pres_R + F_R)*(1._wp/dy(k)) + & + 0.5_wp*dt*cfl*(rho_R*vel_R(2))*(1._wp/dy(k)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb)%sf(j, k, l) = rhs_vf(momxb)%sf(j, k, & - & l) - real(0.5_wp*dt*rho_R*vel_R(2)*vel_R(1)*(1._wp/dy(k)) + 0.5_wp*dt*cfl*(rho_R*vel_R(1) & - & )*(1._wp/dy(k)), kind=stp) + rhs_vf(momxb)%sf(j, k, l) = rhs_vf(momxb)%sf(j, k, l) - & + real(0.5_wp*dt*rho_R*vel_R(2)*vel_R(1)*(1._wp/dy(k)) + & + 0.5_wp*dt*cfl*(rho_R*vel_R(1))*(1._wp/dy(k)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb + 2)%sf(j, k, l) = rhs_vf(momxb + 2)%sf(j, k, & - & l) - real(0.5_wp*dt*rho_R*vel_R(2)*vel_R(3)*(1._wp/dy(k)) + 0.5_wp*dt*cfl*(rho_R*vel_R(3) & - & )*(1._wp/dy(k)), kind=stp) + rhs_vf(momxb + 2)%sf(j, k, l) = rhs_vf(momxb + 2)%sf(j, k, l) - & + real(0.5_wp*dt*rho_R*vel_R(2)*vel_R(3)*(1._wp/dy(k)) + & + 0.5_wp*dt*cfl*(rho_R*vel_R(3))*(1._wp/dy(k)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(E_idx)%sf(j, k, l) = rhs_vf(E_idx)%sf(j, k, & - & l) - real(0.5_wp*dt*(vel_R(2)*(E_R + pres_R + F_R))*(1._wp/dy(k)) + 0.5_wp*dt*cfl*(E_R) & - & *(1._wp/dy(k)), kind=stp) + rhs_vf(E_idx)%sf(j, k, l) = rhs_vf(E_idx)%sf(j, k, l) - & + real(0.5_wp*dt*(vel_R(2)*(E_R + & + pres_R + F_R))*(1._wp/dy(k)) + & + 0.5_wp*dt*cfl*(E_R)*(1._wp/dy(k)), kind=stp) + end do end do end do $:END_GPU_PARALLEL_LOOP() #:endif end if - else if (idir == 3) then + elseif (idir == 3) then #:if not MFC_CASE_OPTIMIZATION or num_dims > 2 - $:GPU_PARALLEL_LOOP(collapse=3, private='[j, k, l, rho_L, rho_R, gamma_L, gamma_R, pi_inf_L, pi_inf_R, mu_L, & - & mu_R, vel_L, vel_R, pres_L, pres_R, alpha_L, alpha_R, alpha_rho_L, alpha_rho_R, F_L, F_R, & - & E_L, E_R, cfl, dvel_small, rho_sf_small, vflux_L_arr, vflux_R_arr]') + $:GPU_PARALLEL_LOOP(collapse=3, private='[j,k,l,rho_L, rho_R, gamma_L, gamma_R, pi_inf_L, pi_inf_R, mu_L, mu_R, vel_L, vel_R, pres_L, pres_R, alpha_L, alpha_R, alpha_rho_L, alpha_rho_R, F_L, F_R, E_L, E_R, cfl, dvel_small, rho_sf_small, vflux_L_arr, vflux_R_arr]') do l = -1, p do k = 0, n do j = 0, m + if (viscous) then vflux_L_arr = 0._wp vflux_R_arr = 0._wp #:if MFC_CASE_OPTIMIZATION #:if igr_order == 5 - ! DIR$ unroll 6 + !DIR$ unroll 6 #:elif igr_order == 3 - ! DIR$ unroll 4 + !DIR$ unroll 4 #:endif #:endif $:GPU_LOOP(parallelism='[seq]') do q = vidxb, vidxe - ! x-direction contributions + + !x-direction contributions $:GPU_LOOP(parallelism='[seq]') do i = -1, 1 rho_L = 0._wp @@ -2177,10 +2339,12 @@ contains rho_sf_small(i) = rho_L end do - dvel_small(1) = (1/(2._wp*dx(j)))*(q_cons_vf(momxb)%sf(j + 1, k, & - & l + q)/rho_sf_small(1) - q_cons_vf(momxb)%sf(j - 1, k, l + q)/rho_sf_small(-1)) - dvel_small(3) = (1/(2._wp*dx(j)))*(q_cons_vf(momxb + 2)%sf(j + 1, k, & - & l + q)/rho_sf_small(1) - q_cons_vf(momxb + 2)%sf(j - 1, k, l + q)/rho_sf_small(-1)) + dvel_small(1) = (1/(2._wp*dx(j)))*( & + q_cons_vf(momxb)%sf(j + 1, k, l + q)/rho_sf_small(1) - & + q_cons_vf(momxb)%sf(j - 1, k, l + q)/rho_sf_small(-1)) + dvel_small(3) = (1/(2._wp*dx(j)))*( & + q_cons_vf(momxb + 2)%sf(j + 1, k, l + q)/rho_sf_small(1) - & + q_cons_vf(momxb + 2)%sf(j - 1, k, l + q)/rho_sf_small(-1)) if (q > vidxb) then vflux_L_arr(1) = vflux_L_arr(1) + coeff_L(q)*(dvel_small(3)) @@ -2191,7 +2355,7 @@ contains vflux_R_arr(3) = vflux_R_arr(3) + coeff_R(q)*(-2._wp*dvel_small(1))/3._wp end if - ! y-direction contributions + !y-direction contributions $:GPU_LOOP(parallelism='[seq]') do i = -1, 1 rho_L = 0._wp @@ -2202,10 +2366,12 @@ contains rho_sf_small(i) = rho_L end do - dvel_small(2) = (1/(2._wp*dy(k)))*(q_cons_vf(momxb + 1)%sf(j, k + 1, & - & l + q)/rho_sf_small(1) - q_cons_vf(momxb + 1)%sf(j, k - 1, l + q)/rho_sf_small(-1)) - dvel_small(3) = (1/(2._wp*dy(k)))*(q_cons_vf(momxb + 2)%sf(j, k + 1, & - & l + q)/rho_sf_small(1) - q_cons_vf(momxb + 2)%sf(j, k - 1, l + q)/rho_sf_small(-1)) + dvel_small(2) = (1/(2._wp*dy(k)))*( & + q_cons_vf(momxb + 1)%sf(j, k + 1, l + q)/rho_sf_small(1) - & + q_cons_vf(momxb + 1)%sf(j, k - 1, l + q)/rho_sf_small(-1)) + dvel_small(3) = (1/(2._wp*dy(k)))*( & + q_cons_vf(momxb + 2)%sf(j, k + 1, l + q)/rho_sf_small(1) - & + q_cons_vf(momxb + 2)%sf(j, k - 1, l + q)/rho_sf_small(-1)) if (q > vidxb) then vflux_L_arr(2) = vflux_L_arr(2) + coeff_L(q)*(dvel_small(3)) @@ -2216,7 +2382,7 @@ contains vflux_R_arr(3) = vflux_R_arr(3) + coeff_R(q)*(-2._wp*dvel_small(2))/3._wp end if - ! z-direction contributions + !z-direction contributions $:GPU_LOOP(parallelism='[seq]') do i = -1, 1 rho_L = 0._wp @@ -2226,14 +2392,15 @@ contains end do rho_sf_small(i) = rho_L end do - dvel_small(1) = (1/(2._wp*dz(l)))*(q_cons_vf(momxb)%sf(j, k, & - & l + 1 + q)/rho_sf_small(1) - q_cons_vf(momxb)%sf(j, k, l - 1 + q)/rho_sf_small(-1)) - dvel_small(2) = (1/(2._wp*dz(l)))*(q_cons_vf(momxb + 1)%sf(j, k, & - & l + 1 + q)/rho_sf_small(1) - q_cons_vf(momxb + 1)%sf(j, k, & - & l - 1 + q)/rho_sf_small(-1)) - dvel_small(3) = (1/(2._wp*dz(l)))*(q_cons_vf(momxb + 2)%sf(j, k, & - & l + 1 + q)/rho_sf_small(1) - q_cons_vf(momxb + 2)%sf(j, k, & - & l - 1 + q)/rho_sf_small(-1)) + dvel_small(1) = (1/(2._wp*dz(l)))*( & + q_cons_vf(momxb)%sf(j, k, l + 1 + q)/rho_sf_small(1) - & + q_cons_vf(momxb)%sf(j, k, l - 1 + q)/rho_sf_small(-1)) + dvel_small(2) = (1/(2._wp*dz(l)))*( & + q_cons_vf(momxb + 1)%sf(j, k, l + 1 + q)/rho_sf_small(1) - & + q_cons_vf(momxb + 1)%sf(j, k, l - 1 + q)/rho_sf_small(-1)) + dvel_small(3) = (1/(2._wp*dz(l)))*( & + q_cons_vf(momxb + 2)%sf(j, k, l + 1 + q)/rho_sf_small(1) - & + q_cons_vf(momxb + 2)%sf(j, k, l - 1 + q)/rho_sf_small(-1)) if (q > vidxb) then vflux_L_arr(1) = vflux_L_arr(1) + coeff_L(q)*(dvel_small(1)) vflux_L_arr(2) = vflux_L_arr(2) + coeff_L(q)*(dvel_small(2)) @@ -2306,6 +2473,7 @@ contains end do if (num_fluids > 1) then + alpha_L(num_fluids) = 1._wp alpha_R(num_fluids) = 1._wp @@ -2347,88 +2515,88 @@ contains end do $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb)%sf(j, k, l + 1) = rhs_vf(momxb)%sf(j, k, & - & l + 1) - real(0.5_wp*dt*mu_L*vflux_L_arr(1)*(1._wp/dz(l + 1)), kind=stp) + rhs_vf(momxb)%sf(j, k, l + 1) = rhs_vf(momxb)%sf(j, k, l + 1) - & + real(0.5_wp*dt*mu_L*vflux_L_arr(1)*(1._wp/dz(l + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(E_idx)%sf(j, k, l + 1) = rhs_vf(E_idx)%sf(j, k, & - & l + 1) - real(0.5_wp*dt*mu_L*vflux_L_arr(1)*vel_L(1)*(1._wp/dz(l + 1)), kind=stp) + rhs_vf(E_idx)%sf(j, k, l + 1) = rhs_vf(E_idx)%sf(j, k, l + 1) - & + real(0.5_wp*dt*mu_L*vflux_L_arr(1)*vel_L(1)*(1._wp/dz(l + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb)%sf(j, k, l) = rhs_vf(momxb)%sf(j, k, & - & l) + real(0.5_wp*dt*mu_L*vflux_L_arr(1)*(1._wp/dz(l)), kind=stp) + rhs_vf(momxb)%sf(j, k, l) = rhs_vf(momxb)%sf(j, k, l) + & + real(0.5_wp*dt*mu_L*vflux_L_arr(1)*(1._wp/dz(l)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(E_idx)%sf(j, k, l) = rhs_vf(E_idx)%sf(j, k, & - & l) + real(0.5_wp*dt*mu_L*vflux_L_arr(1)*vel_L(1)*(1._wp/dz(l)), kind=stp) + rhs_vf(E_idx)%sf(j, k, l) = rhs_vf(E_idx)%sf(j, k, l) + & + real(0.5_wp*dt*mu_L*vflux_L_arr(1)*vel_L(1)*(1._wp/dz(l)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb)%sf(j, k, l + 1) = rhs_vf(momxb)%sf(j, k, & - & l + 1) - real(0.5_wp*dt*mu_R*vflux_R_arr(1)*(1._wp/dz(l + 1)), kind=stp) + rhs_vf(momxb)%sf(j, k, l + 1) = rhs_vf(momxb)%sf(j, k, l + 1) - & + real(0.5_wp*dt*mu_R*vflux_R_arr(1)*(1._wp/dz(l + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(E_idx)%sf(j, k, l + 1) = rhs_vf(E_idx)%sf(j, k, & - & l + 1) - real(0.5_wp*dt*mu_R*vflux_R_arr(1)*vel_R(1)*(1._wp/dz(l + 1)), kind=stp) + rhs_vf(E_idx)%sf(j, k, l + 1) = rhs_vf(E_idx)%sf(j, k, l + 1) - & + real(0.5_wp*dt*mu_R*vflux_R_arr(1)*vel_R(1)*(1._wp/dz(l + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb)%sf(j, k, l) = rhs_vf(momxb)%sf(j, k, & - & l) + real(0.5_wp*dt*mu_R*vflux_R_arr(1)*(1._wp/dz(l)), kind=stp) + rhs_vf(momxb)%sf(j, k, l) = rhs_vf(momxb)%sf(j, k, l) + & + real(0.5_wp*dt*mu_R*vflux_R_arr(1)*(1._wp/dz(l)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(E_idx)%sf(j, k, l) = rhs_vf(E_idx)%sf(j, k, & - & l) + real(0.5_wp*dt*mu_R*vflux_R_arr(1)*vel_R(1)*(1._wp/dz(l)), kind=stp) + rhs_vf(E_idx)%sf(j, k, l) = rhs_vf(E_idx)%sf(j, k, l) + & + real(0.5_wp*dt*mu_R*vflux_R_arr(1)*vel_R(1)*(1._wp/dz(l)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb + 1)%sf(j, k, l + 1) = rhs_vf(momxb + 1)%sf(j, k, & - & l + 1) - real(0.5_wp*dt*mu_L*vflux_L_arr(2)*(1._wp/dz(l + 1)), kind=stp) + rhs_vf(momxb + 1)%sf(j, k, l + 1) = rhs_vf(momxb + 1)%sf(j, k, l + 1) - & + real(0.5_wp*dt*mu_L*vflux_L_arr(2)*(1._wp/dz(l + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(E_idx)%sf(j, k, l + 1) = rhs_vf(E_idx)%sf(j, k, & - & l + 1) - real(0.5_wp*dt*mu_L*vflux_L_arr(2)*vel_L(2)*(1._wp/dz(l + 1)), kind=stp) + rhs_vf(E_idx)%sf(j, k, l + 1) = rhs_vf(E_idx)%sf(j, k, l + 1) - & + real(0.5_wp*dt*mu_L*vflux_L_arr(2)*vel_L(2)*(1._wp/dz(l + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb + 1)%sf(j, k, l) = rhs_vf(momxb + 1)%sf(j, k, & - & l) + real(0.5_wp*dt*mu_L*vflux_L_arr(2)*(1._wp/dz(l)), kind=stp) + rhs_vf(momxb + 1)%sf(j, k, l) = rhs_vf(momxb + 1)%sf(j, k, l) + & + real(0.5_wp*dt*mu_L*vflux_L_arr(2)*(1._wp/dz(l)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(E_idx)%sf(j, k, l) = rhs_vf(E_idx)%sf(j, k, & - & l) + real(0.5_wp*dt*mu_L*vflux_L_arr(2)*vel_L(2)*(1._wp/dz(l)), kind=stp) + rhs_vf(E_idx)%sf(j, k, l) = rhs_vf(E_idx)%sf(j, k, l) + & + real(0.5_wp*dt*mu_L*vflux_L_arr(2)*vel_L(2)*(1._wp/dz(l)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb + 1)%sf(j, k, l + 1) = rhs_vf(momxb + 1)%sf(j, k, & - & l + 1) - real(0.5_wp*dt*mu_R*vflux_R_arr(2)*(1._wp/dz(l + 1)), kind=stp) + rhs_vf(momxb + 1)%sf(j, k, l + 1) = rhs_vf(momxb + 1)%sf(j, k, l + 1) - & + real(0.5_wp*dt*mu_R*vflux_R_arr(2)*(1._wp/dz(l + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(E_idx)%sf(j, k, l + 1) = rhs_vf(E_idx)%sf(j, k, & - & l + 1) - real(0.5_wp*dt*mu_R*vflux_R_arr(2)*vel_R(2)*(1._wp/dz(l + 1)), kind=stp) + rhs_vf(E_idx)%sf(j, k, l + 1) = rhs_vf(E_idx)%sf(j, k, l + 1) - & + real(0.5_wp*dt*mu_R*vflux_R_arr(2)*vel_R(2)*(1._wp/dz(l + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb + 1)%sf(j, k, l) = rhs_vf(momxb + 1)%sf(j, k, & - & l) + real(0.5_wp*dt*mu_R*vflux_R_arr(2)*(1._wp/dz(l)), kind=stp) + rhs_vf(momxb + 1)%sf(j, k, l) = rhs_vf(momxb + 1)%sf(j, k, l) + & + real(0.5_wp*dt*mu_R*vflux_R_arr(2)*(1._wp/dz(l)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(E_idx)%sf(j, k, l) = rhs_vf(E_idx)%sf(j, k, & - & l) + real(0.5_wp*dt*mu_R*vflux_R_arr(2)*vel_R(2)*(1._wp/dz(l)), kind=stp) + rhs_vf(E_idx)%sf(j, k, l) = rhs_vf(E_idx)%sf(j, k, l) + & + real(0.5_wp*dt*mu_R*vflux_R_arr(2)*vel_R(2)*(1._wp/dz(l)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb + 2)%sf(j, k, l + 1) = rhs_vf(momxb + 2)%sf(j, k, & - & l + 1) - real(0.5_wp*dt*mu_L*vflux_L_arr(3)*(1._wp/dz(l + 1)), kind=stp) + rhs_vf(momxb + 2)%sf(j, k, l + 1) = rhs_vf(momxb + 2)%sf(j, k, l + 1) - & + real(0.5_wp*dt*mu_L*vflux_L_arr(3)*(1._wp/dz(l + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(E_idx)%sf(j, k, l + 1) = rhs_vf(E_idx)%sf(j, k, & - & l + 1) - real(0.5_wp*dt*mu_L*vflux_L_arr(3)*vel_L(3)*(1._wp/dz(l + 1)), kind=stp) + rhs_vf(E_idx)%sf(j, k, l + 1) = rhs_vf(E_idx)%sf(j, k, l + 1) - & + real(0.5_wp*dt*mu_L*vflux_L_arr(3)*vel_L(3)*(1._wp/dz(l + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb + 2)%sf(j, k, l) = rhs_vf(momxb + 2)%sf(j, k, & - & l) + real(0.5_wp*dt*mu_L*vflux_L_arr(3)*(1._wp/dz(l)), kind=stp) + rhs_vf(momxb + 2)%sf(j, k, l) = rhs_vf(momxb + 2)%sf(j, k, l) + & + real(0.5_wp*dt*mu_L*vflux_L_arr(3)*(1._wp/dz(l)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(E_idx)%sf(j, k, l) = rhs_vf(E_idx)%sf(j, k, & - & l) + real(0.5_wp*dt*mu_L*vflux_L_arr(3)*vel_L(3)*(1._wp/dz(l)), kind=stp) + rhs_vf(E_idx)%sf(j, k, l) = rhs_vf(E_idx)%sf(j, k, l) + & + real(0.5_wp*dt*mu_L*vflux_L_arr(3)*vel_L(3)*(1._wp/dz(l)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb + 2)%sf(j, k, l + 1) = rhs_vf(momxb + 2)%sf(j, k, & - & l + 1) - real(0.5_wp*dt*mu_R*vflux_R_arr(3)*(1._wp/dz(l + 1)), kind=stp) + rhs_vf(momxb + 2)%sf(j, k, l + 1) = rhs_vf(momxb + 2)%sf(j, k, l + 1) - & + real(0.5_wp*dt*mu_R*vflux_R_arr(3)*(1._wp/dz(l + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(E_idx)%sf(j, k, l + 1) = rhs_vf(E_idx)%sf(j, k, & - & l + 1) - real(0.5_wp*dt*mu_R*vflux_R_arr(3)*vel_R(3)*(1._wp/dz(l + 1)), kind=stp) + rhs_vf(E_idx)%sf(j, k, l + 1) = rhs_vf(E_idx)%sf(j, k, l + 1) - & + real(0.5_wp*dt*mu_R*vflux_R_arr(3)*vel_R(3)*(1._wp/dz(l + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb + 2)%sf(j, k, l) = rhs_vf(momxb + 2)%sf(j, k, & - & l) + real(0.5_wp*dt*mu_R*vflux_R_arr(3)*(1._wp/dz(l)), kind=stp) + rhs_vf(momxb + 2)%sf(j, k, l) = rhs_vf(momxb + 2)%sf(j, k, l) + & + real(0.5_wp*dt*mu_R*vflux_R_arr(3)*(1._wp/dz(l)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(E_idx)%sf(j, k, l) = rhs_vf(E_idx)%sf(j, k, & - & l) + real(0.5_wp*dt*mu_R*vflux_R_arr(3)*vel_R(3)*(1._wp/dz(l)), kind=stp) + rhs_vf(E_idx)%sf(j, k, l) = rhs_vf(E_idx)%sf(j, k, l) + & + real(0.5_wp*dt*mu_R*vflux_R_arr(3)*vel_R(3)*(1._wp/dz(l)), kind=stp) end if E_L = 0._wp; E_R = 0._wp @@ -2446,164 +2614,178 @@ contains F_R = F_R + coeff_R(q)*jac(j, k, l + q) end do - call s_get_derived_states(E_L, gamma_L, pi_inf_L, rho_L, vel_L, E_R, gamma_R, pi_inf_R, rho_R, vel_R, & - & pres_L, pres_R, cfl) + call s_get_derived_states(E_L, gamma_L, pi_inf_L, rho_L, vel_L, & + E_R, gamma_R, pi_inf_R, rho_R, vel_R, & + pres_L, pres_R, cfl) $:GPU_LOOP(parallelism='[seq]') do i = 1, num_fluids $:GPU_ATOMIC(atomic='update') - rhs_vf(i)%sf(j, k, l + 1) = rhs_vf(i)%sf(j, k, & - & l + 1) + real(0.5_wp*dt*(alpha_rho_L(i)*vel_L(3))*(1._wp/dz(l + 1)) & - & - 0.5_wp*dt*cfl*(alpha_rho_L(i))*(1._wp/dz(l + 1)), kind=stp) + rhs_vf(i)%sf(j, k, l + 1) = rhs_vf(i)%sf(j, k, l + 1) + & + real(0.5_wp*dt*(alpha_rho_L(i)* & + vel_L(3))*(1._wp/dz(l + 1)) - & + 0.5_wp*dt*cfl*(alpha_rho_L(i))*(1._wp/dz(l + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(i)%sf(j, k, l) = rhs_vf(i)%sf(j, k, & - & l) - real(0.5_wp*dt*(alpha_rho_L(i)*vel_L(3))*(1._wp/dz(l)) & - & - 0.5_wp*dt*cfl*(alpha_rho_L(i))*(1._wp/dz(l)), kind=stp) + rhs_vf(i)%sf(j, k, l) = rhs_vf(i)%sf(j, k, l) - & + real(0.5_wp*dt*(alpha_rho_L(i)* & + vel_L(3))*(1._wp/dz(l)) - & + 0.5_wp*dt*cfl*(alpha_rho_L(i))*(1._wp/dz(l)), kind=stp) end do if (num_fluids > 1) then $:GPU_LOOP(parallelism='[seq]') do i = 1, num_fluids - 1 $:GPU_ATOMIC(atomic='update') - rhs_vf(advxb + i - 1)%sf(j, k, l + 1) = rhs_vf(advxb + i - 1)%sf(j, k, & - & l + 1) + real(0.5_wp*dt*(alpha_L(i)*vel_L(3))*(1._wp/dz(l + 1)) & - & - 0.5_wp*dt*cfl*(alpha_L(i))*(1._wp/dz(l + 1)), kind=stp) + rhs_vf(advxb + i - 1)%sf(j, k, l + 1) = rhs_vf(advxb + i - 1)%sf(j, k, l + 1) + & + real(0.5_wp*dt*(alpha_L(i)* & + vel_L(3))*(1._wp/dz(l + 1)) - & + 0.5_wp*dt*cfl*(alpha_L(i))*(1._wp/dz(l + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(advxb + i - 1)%sf(j, k, l + 1) = rhs_vf(advxb + i - 1)%sf(j, k, & - & l + 1) - real(0.5_wp*dt*q_cons_vf(advxb + i - 1)%sf(j, k, & - & l + 1)*vel_L(3)*(1._wp/dz(l + 1)), kind=stp) + rhs_vf(advxb + i - 1)%sf(j, k, l + 1) = rhs_vf(advxb + i - 1)%sf(j, k, l + 1) & + - real(0.5_wp*dt*q_cons_vf(advxb + i - 1)%sf(j, k, l + 1)*vel_L(3)*(1._wp/dz(l + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(advxb + i - 1)%sf(j, k, l) = rhs_vf(advxb + i - 1)%sf(j, k, & - & l) - real(0.5_wp*dt*(alpha_L(i)*vel_L(3))*(1._wp/dz(l)) - 0.5_wp*dt*cfl*(alpha_L(i)) & - & *(1._wp/dz(l)), kind=stp) + rhs_vf(advxb + i - 1)%sf(j, k, l) = rhs_vf(advxb + i - 1)%sf(j, k, l) - & + real(0.5_wp*dt*(alpha_L(i)* & + vel_L(3))*(1._wp/dz(l)) - & + 0.5_wp*dt*cfl*(alpha_L(i))*(1._wp/dz(l)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(advxb + i - 1)%sf(j, k, l) = rhs_vf(advxb + i - 1)%sf(j, k, & - & l) + real(0.5_wp*dt*q_cons_vf(advxb + i - 1)%sf(j, k, l)*vel_L(3)*(1._wp/dz(l)), & - & kind=stp) + rhs_vf(advxb + i - 1)%sf(j, k, l) = rhs_vf(advxb + i - 1)%sf(j, k, l) & + + real(0.5_wp*dt*q_cons_vf(advxb + i - 1)%sf(j, k, l)*vel_L(3)*(1._wp/dz(l)), kind=stp) end do end if $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb + 2)%sf(j, k, l + 1) = rhs_vf(momxb + 2)%sf(j, k, & - & l + 1) + real(0.5_wp*dt*(rho_L*(vel_L(3))**2.0 + pres_L + F_L)*(1._wp/dz(l + 1)) & - & - 0.5_wp*dt*cfl*(rho_L*vel_L(3))*(1._wp/dz(l + 1)), kind=stp) + rhs_vf(momxb + 2)%sf(j, k, l + 1) = rhs_vf(momxb + 2)%sf(j, k, l + 1) + & + real(0.5_wp*dt*(rho_L*(vel_L(3))**2.0 + & + pres_L + F_L)*(1._wp/dz(l + 1)) - & + 0.5_wp*dt*cfl*(rho_L*vel_L(3))*(1._wp/dz(l + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb)%sf(j, k, l + 1) = rhs_vf(momxb)%sf(j, k, & - & l + 1) + real(0.5_wp*dt*rho_L*vel_L(1)*vel_L(3)*(1._wp/dz(l + 1)) & - & - 0.5_wp*dt*cfl*(rho_L*vel_L(1))*(1._wp/dz(l + 1)), kind=stp) + rhs_vf(momxb)%sf(j, k, l + 1) = rhs_vf(momxb)%sf(j, k, l + 1) + & + real(0.5_wp*dt*rho_L*vel_L(1)*vel_L(3)*(1._wp/dz(l + 1)) - & + 0.5_wp*dt*cfl*(rho_L*vel_L(1))*(1._wp/dz(l + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb + 1)%sf(j, k, l + 1) = rhs_vf(momxb + 1)%sf(j, k, & - & l + 1) + real(0.5_wp*dt*rho_L*vel_L(2)*vel_L(3)*(1._wp/dz(l + 1)) & - & - 0.5_wp*dt*cfl*(rho_L*vel_L(2))*(1._wp/dz(l + 1)), kind=stp) + rhs_vf(momxb + 1)%sf(j, k, l + 1) = rhs_vf(momxb + 1)%sf(j, k, l + 1) + & + real(0.5_wp*dt*rho_L*vel_L(2)*vel_L(3)*(1._wp/dz(l + 1)) - & + 0.5_wp*dt*cfl*(rho_L*vel_L(2))*(1._wp/dz(l + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(E_idx)%sf(j, k, l + 1) = rhs_vf(E_idx)%sf(j, k, & - & l + 1) + real(0.5_wp*dt*(vel_L(3)*(E_L + pres_L + F_L))*(1._wp/dz(l + 1)) & - & - 0.5_wp*dt*cfl*(E_L)*(1._wp/dz(l + 1)), kind=stp) + rhs_vf(E_idx)%sf(j, k, l + 1) = rhs_vf(E_idx)%sf(j, k, l + 1) + & + real(0.5_wp*dt*(vel_L(3)*(E_L + & + pres_L + F_L))*(1._wp/dz(l + 1)) - & + 0.5_wp*dt*cfl*(E_L)*(1._wp/dz(l + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb + 2)%sf(j, k, l) = rhs_vf(momxb + 2)%sf(j, k, & - & l) - real(0.5_wp*dt*(rho_L*(vel_L(3))**2.0 + pres_L + F_L)*(1._wp/dz(l)) & - & - 0.5_wp*dt*cfl*(rho_L*vel_L(3))*(1._wp/dz(l)), kind=stp) + rhs_vf(momxb + 2)%sf(j, k, l) = rhs_vf(momxb + 2)%sf(j, k, l) - & + real(0.5_wp*dt*(rho_L*(vel_L(3))**2.0 + & + pres_L + F_L)*(1._wp/dz(l)) - & + 0.5_wp*dt*cfl*(rho_L*vel_L(3))*(1._wp/dz(l)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb)%sf(j, k, l) = rhs_vf(momxb)%sf(j, k, & - & l) - real(0.5_wp*dt*rho_L*vel_L(1)*vel_L(3)*(1._wp/dz(l)) - 0.5_wp*dt*cfl*(rho_L*vel_L(1)) & - & *(1._wp/dz(l)), kind=stp) + rhs_vf(momxb)%sf(j, k, l) = rhs_vf(momxb)%sf(j, k, l) - & + real(0.5_wp*dt*rho_L*vel_L(1)*vel_L(3)*(1._wp/dz(l)) - & + 0.5_wp*dt*cfl*(rho_L*vel_L(1))*(1._wp/dz(l)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb + 1)%sf(j, k, l) = rhs_vf(momxb + 1)%sf(j, k, & - & l) - real(0.5_wp*dt*rho_L*vel_L(2)*vel_L(3)*(1._wp/dz(l)) - 0.5_wp*dt*cfl*(rho_L*vel_L(2)) & - & *(1._wp/dz(l)), kind=stp) + rhs_vf(momxb + 1)%sf(j, k, l) = rhs_vf(momxb + 1)%sf(j, k, l) - & + real(0.5_wp*dt*rho_L*vel_L(2)*vel_L(3)*(1._wp/dz(l)) - & + 0.5_wp*dt*cfl*(rho_L*vel_L(2))*(1._wp/dz(l)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(E_idx)%sf(j, k, l) = rhs_vf(E_idx)%sf(j, k, & - & l) - real(0.5_wp*dt*(vel_L(3)*(E_L + pres_L + F_L))*(1._wp/dz(l)) - 0.5_wp*dt*cfl*(E_L) & - & *(1._wp/dz(l)), kind=stp) + rhs_vf(E_idx)%sf(j, k, l) = rhs_vf(E_idx)%sf(j, k, l) - & + real(0.5_wp*dt*(vel_L(3)*(E_L + & + pres_L + F_L))*(1._wp/dz(l)) - & + 0.5_wp*dt*cfl*(E_L)*(1._wp/dz(l)), kind=stp) $:GPU_LOOP(parallelism='[seq]') do i = 1, num_fluids $:GPU_ATOMIC(atomic='update') - rhs_vf(i)%sf(j, k, l + 1) = rhs_vf(i)%sf(j, k, & - & l + 1) + real(0.5_wp*dt*(alpha_rho_R(i)*vel_R(3))*(1._wp/dz(l + 1)) & - & + 0.5_wp*dt*cfl*(alpha_rho_R(i))*(1._wp/dz(l + 1)), kind=stp) + rhs_vf(i)%sf(j, k, l + 1) = rhs_vf(i)%sf(j, k, l + 1) + & + real(0.5_wp*dt*(alpha_rho_R(i)* & + vel_R(3))*(1._wp/dz(l + 1)) + & + 0.5_wp*dt*cfl*(alpha_rho_R(i))*(1._wp/dz(l + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(i)%sf(j, k, l) = rhs_vf(i)%sf(j, k, & - & l) - real(0.5_wp*dt*(alpha_rho_R(i)*vel_R(3))*(1._wp/dz(l)) & - & + 0.5_wp*dt*cfl*(alpha_rho_R(i))*(1._wp/dz(l)), kind=stp) + rhs_vf(i)%sf(j, k, l) = rhs_vf(i)%sf(j, k, l) - & + real(0.5_wp*dt*(alpha_rho_R(i)* & + vel_R(3))*(1._wp/dz(l)) + & + 0.5_wp*dt*cfl*(alpha_rho_R(i))*(1._wp/dz(l)), kind=stp) end do if (num_fluids > 1) then $:GPU_LOOP(parallelism='[seq]') do i = 1, num_fluids - 1 $:GPU_ATOMIC(atomic='update') - rhs_vf(advxb + i - 1)%sf(j, k, l + 1) = rhs_vf(advxb + i - 1)%sf(j, k, & - & l + 1) + real(0.5_wp*dt*(alpha_R(i)*vel_R(3))*(1._wp/dz(l + 1)) & - & + 0.5_wp*dt*cfl*(alpha_R(i))*(1._wp/dz(l + 1)), kind=stp) + rhs_vf(advxb + i - 1)%sf(j, k, l + 1) = rhs_vf(advxb + i - 1)%sf(j, k, l + 1) + & + real(0.5_wp*dt*(alpha_R(i)* & + vel_R(3))*(1._wp/dz(l + 1)) + & + 0.5_wp*dt*cfl*(alpha_R(i))*(1._wp/dz(l + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(advxb + i - 1)%sf(j, k, l + 1) = rhs_vf(advxb + i - 1)%sf(j, k, & - & l + 1) - real(0.5_wp*dt*q_cons_vf(advxb + i - 1)%sf(j, k, & - & l + 1)*vel_R(3)*(1._wp/dz(l + 1)), kind=stp) + rhs_vf(advxb + i - 1)%sf(j, k, l + 1) = rhs_vf(advxb + i - 1)%sf(j, k, l + 1) & + - real(0.5_wp*dt*q_cons_vf(advxb + i - 1)%sf(j, k, l + 1)*vel_R(3)*(1._wp/dz(l + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(advxb + i - 1)%sf(j, k, l) = rhs_vf(advxb + i - 1)%sf(j, k, & - & l) - real(0.5_wp*dt*(alpha_R(i)*vel_R(3))*(1._wp/dz(l)) + 0.5_wp*dt*cfl*(alpha_R(i)) & - & *(1._wp/dz(l)), kind=stp) + rhs_vf(advxb + i - 1)%sf(j, k, l) = rhs_vf(advxb + i - 1)%sf(j, k, l) - & + real(0.5_wp*dt*(alpha_R(i)* & + vel_R(3))*(1._wp/dz(l)) + & + 0.5_wp*dt*cfl*(alpha_R(i))*(1._wp/dz(l)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(advxb + i - 1)%sf(j, k, l) = rhs_vf(advxb + i - 1)%sf(j, k, & - & l) + real(0.5_wp*dt*q_cons_vf(advxb + i - 1)%sf(j, k, l)*vel_R(3)*(1._wp/dz(l)), & - & kind=stp) + rhs_vf(advxb + i - 1)%sf(j, k, l) = rhs_vf(advxb + i - 1)%sf(j, k, l) & + + real(0.5_wp*dt*q_cons_vf(advxb + i - 1)%sf(j, k, l)*vel_R(3)*(1._wp/dz(l)), kind=stp) end do end if $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb + 2)%sf(j, k, l + 1) = rhs_vf(momxb + 2)%sf(j, k, & - & l + 1) + real(0.5_wp*dt*(rho_R*(vel_R(3))**2.0 + pres_R + F_R)*(1._wp/dz(l + 1)) & - & + 0.5_wp*dt*cfl*(rho_R*vel_R(3))*(1._wp/dz(l + 1)), kind=stp) + rhs_vf(momxb + 2)%sf(j, k, l + 1) = rhs_vf(momxb + 2)%sf(j, k, l + 1) + & + real(0.5_wp*dt*(rho_R*(vel_R(3))**2.0 + & + pres_R + F_R)*(1._wp/dz(l + 1)) + & + 0.5_wp*dt*cfl*(rho_R*vel_R(3))*(1._wp/dz(l + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb)%sf(j, k, l + 1) = rhs_vf(momxb)%sf(j, k, & - & l + 1) + real(0.5_wp*dt*rho_R*vel_R(1)*vel_R(3)*(1._wp/dz(l + 1)) & - & + 0.5_wp*dt*cfl*(rho_R*vel_R(1))*(1._wp/dz(l + 1)), kind=stp) + rhs_vf(momxb)%sf(j, k, l + 1) = rhs_vf(momxb)%sf(j, k, l + 1) + & + real(0.5_wp*dt*rho_R*vel_R(1)*vel_R(3)*(1._wp/dz(l + 1)) + & + 0.5_wp*dt*cfl*(rho_R*vel_R(1))*(1._wp/dz(l + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb + 1)%sf(j, k, l + 1) = rhs_vf(momxb + 1)%sf(j, k, & - & l + 1) + real(0.5_wp*dt*rho_R*vel_R(2)*vel_R(3)*(1._wp/dz(l + 1)) & - & + 0.5_wp*dt*cfl*(rho_R*vel_R(2))*(1._wp/dz(l + 1)), kind=stp) + rhs_vf(momxb + 1)%sf(j, k, l + 1) = rhs_vf(momxb + 1)%sf(j, k, l + 1) + & + real(0.5_wp*dt*rho_R*vel_R(2)*vel_R(3)*(1._wp/dz(l + 1)) + & + 0.5_wp*dt*cfl*(rho_R*vel_R(2))*(1._wp/dz(l + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(E_idx)%sf(j, k, l + 1) = rhs_vf(E_idx)%sf(j, k, & - & l + 1) + real(0.5_wp*dt*(vel_R(3)*(E_R + pres_R + F_R))*(1._wp/dz(l + 1)) & - & + 0.5_wp*dt*cfl*(E_R)*(1._wp/dz(l + 1)), kind=stp) + rhs_vf(E_idx)%sf(j, k, l + 1) = rhs_vf(E_idx)%sf(j, k, l + 1) + & + real(0.5_wp*dt*(vel_R(3)*(E_R + & + pres_R + F_R))*(1._wp/dz(l + 1)) + & + 0.5_wp*dt*cfl*(E_R)*(1._wp/dz(l + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb + 2)%sf(j, k, l) = rhs_vf(momxb + 2)%sf(j, k, & - & l) - real(0.5_wp*dt*(rho_R*(vel_R(3))**2.0 + pres_R + F_R)*(1._wp/dz(l)) & - & + 0.5_wp*dt*cfl*(rho_R*vel_R(3))*(1._wp/dz(l)), kind=stp) + rhs_vf(momxb + 2)%sf(j, k, l) = rhs_vf(momxb + 2)%sf(j, k, l) - & + real(0.5_wp*dt*(rho_R*(vel_R(3))**2.0 + & + pres_R + F_R)*(1._wp/dz(l)) + & + 0.5_wp*dt*cfl*(rho_R*vel_R(3))*(1._wp/dz(l)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb)%sf(j, k, l) = rhs_vf(momxb)%sf(j, k, & - & l) - real(0.5_wp*dt*rho_R*vel_R(1)*vel_R(3)*(1._wp/dz(l)) + 0.5_wp*dt*cfl*(rho_R*vel_R(1)) & - & *(1._wp/dz(l)), kind=stp) + rhs_vf(momxb)%sf(j, k, l) = rhs_vf(momxb)%sf(j, k, l) - & + real(0.5_wp*dt*rho_R*vel_R(1)*vel_R(3)*(1._wp/dz(l)) + & + 0.5_wp*dt*cfl*(rho_R*vel_R(1))*(1._wp/dz(l)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb + 1)%sf(j, k, l) = rhs_vf(momxb + 1)%sf(j, k, & - & l) - real(0.5_wp*dt*rho_R*vel_R(2)*vel_R(3)*(1._wp/dz(l)) + 0.5_wp*dt*cfl*(rho_R*vel_R(2)) & - & *(1._wp/dz(l)), kind=stp) + rhs_vf(momxb + 1)%sf(j, k, l) = rhs_vf(momxb + 1)%sf(j, k, l) - & + real(0.5_wp*dt*rho_R*vel_R(2)*vel_R(3)*(1._wp/dz(l)) + & + 0.5_wp*dt*cfl*(rho_R*vel_R(2))*(1._wp/dz(l)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(E_idx)%sf(j, k, l) = rhs_vf(E_idx)%sf(j, k, & - & l) - real(0.5_wp*dt*(vel_R(3)*(E_R + pres_R + F_R))*(1._wp/dz(l)) + 0.5_wp*dt*cfl*(E_R) & - & *(1._wp/dz(l)), kind=stp) + rhs_vf(E_idx)%sf(j, k, l) = rhs_vf(E_idx)%sf(j, k, l) - & + real(0.5_wp*dt*(vel_R(3)*(E_R + & + pres_R + F_R))*(1._wp/dz(l)) + & + 0.5_wp*dt*cfl*(E_R)*(1._wp/dz(l)), kind=stp) + end do end do end do @@ -2613,16 +2795,18 @@ contains end subroutine s_igr_riemann_solver - !> Compute pressure and maximum wavespeed from left and right reconstructed states - subroutine s_get_derived_states(E_L, gamma_L, pi_inf_L, rho_L, vel_L, E_R, gamma_R, pi_inf_R, rho_R, vel_R, pres_L, pres_R, cfl) - + !> @brief Computes pressure and maximum wavespeed from left and right reconstructed states for the IGR Riemann solver. + subroutine s_get_derived_states(E_L, gamma_L, pi_inf_L, rho_L, vel_L, & + E_R, gamma_R, pi_inf_R, rho_R, vel_R, & + pres_L, pres_R, cfl) $:GPU_ROUTINE(parallelism='[seq]') - real(wp), intent(in) :: E_L, gamma_L, pi_inf_L, rho_L - real(wp), intent(in) :: E_R, gamma_R, pi_inf_R, rho_R + real(wp), intent(in) :: E_L, gamma_L, pi_inf_L, rho_L + real(wp), intent(in) :: E_R, gamma_R, pi_inf_R, rho_R real(wp), dimension(num_dims), intent(in) :: vel_L, vel_R - real(wp), intent(out) :: pres_L, pres_R, cfl - real(wp) :: a_L, a_R + real(wp), intent(out) :: pres_L, pres_R, cfl + + real(wp) :: a_L, a_R if (num_dims == 2) then pres_L = (E_L - pi_inf_L - 0.5_wp*rho_L*(vel_L(1)**2._wp + vel_L(2)**2._wp))/gamma_L @@ -2636,8 +2820,10 @@ contains a_L = sqrt((pres_L*(1._wp/gamma_L + 1._wp) + pi_inf_L/gamma_L)/rho_L) a_R = sqrt((pres_R*(1._wp/gamma_R + 1._wp) + pi_inf_R/gamma_R)/rho_R) - cfl = max(sqrt(vel_L(1)**2._wp + vel_L(2)**2._wp), sqrt(vel_R(1)**2._wp + vel_R(2)**2._wp)) + max(a_L, a_R) - else if (num_dims == 3) then + cfl = max(sqrt(vel_L(1)**2._wp + vel_L(2)**2._wp), & + sqrt(vel_R(1)**2._wp + vel_R(2)**2._wp)) + & + max(a_L, a_R) + elseif (num_dims == 3) then #:if not MFC_CASE_OPTIMIZATION or num_dims > 2 pres_L = (E_L - pi_inf_L - 0.5_wp*rho_L*(vel_L(1)**2._wp + vel_L(2)**2._wp + vel_L(3)**2._wp))/gamma_L pres_R = (E_R - pi_inf_R - 0.5_wp*rho_R*(vel_R(1)**2._wp + vel_R(2)**2._wp + vel_R(3)**2._wp))/gamma_R @@ -2651,51 +2837,61 @@ contains a_R = sqrt((pres_R*(1._wp/gamma_R + 1._wp) + pi_inf_R/gamma_R)/rho_R) cfl = max(sqrt(vel_L(1)**2._wp + vel_L(2)**2._wp + vel_L(3)**2._wp), & - & sqrt(vel_R(1)**2._wp + vel_R(2)**2._wp + vel_R(3)**2._wp)) + max(a_L, a_R) + sqrt(vel_R(1)**2._wp + vel_R(2)**2._wp + vel_R(3)**2._wp)) + & + max(a_L, a_R) #:endif end if end subroutine s_get_derived_states - !> Accumulate the IGR numerical flux divergence into the RHS along the specified direction + !> @brief Accumulates the IGR numerical flux divergence into the right-hand side along the specified coordinate direction. subroutine s_igr_flux_add(q_cons_vf, rhs_vf, flux_vf, idir) - type(scalar_field), dimension(sys_size), intent(inout) :: q_cons_vf, flux_vf, rhs_vf - integer, intent(in) :: idir + type(scalar_field), & + dimension(sys_size), & + intent(inout) :: q_cons_vf, flux_vf, rhs_vf + + integer, intent(in) :: idir if (idir == 1) then - $:GPU_PARALLEL_LOOP(private='[i, j, k, l]', collapse=4) + $:GPU_PARALLEL_LOOP(private='[i,j,k,l]', collapse=4) do i = 1, sys_size do l = 0, p do k = 0, n do j = 0, m - rhs_vf(i)%sf(j, k, l) = 1._wp/dx(j)*(flux_vf(i)%sf(j - 1, k, l) - flux_vf(i)%sf(j, k, l)) + rhs_vf(i)%sf(j, k, l) = 1._wp/dx(j)* & + (flux_vf(i)%sf(j - 1, k, l) & + - flux_vf(i)%sf(j, k, l)) end do end do end do end do $:END_GPU_PARALLEL_LOOP() - else if (idir == 2) then - $:GPU_PARALLEL_LOOP(private='[i, j, k, l]', collapse=4) + elseif (idir == 2) then + $:GPU_PARALLEL_LOOP(private='[i,j,k,l]', collapse=4) do i = 1, sys_size do l = 0, p do k = 0, n do j = 0, m - rhs_vf(i)%sf(j, k, l) = rhs_vf(i)%sf(j, k, l) + 1._wp/dy(k)*(flux_vf(i)%sf(j, k - 1, & - & l) - flux_vf(i)%sf(j, k, l)) + rhs_vf(i)%sf(j, k, l) = & + rhs_vf(i)%sf(j, k, l) + 1._wp/dy(k)* & + (flux_vf(i)%sf(j, k - 1, l) & + - flux_vf(i)%sf(j, k, l)) end do end do end do end do $:END_GPU_PARALLEL_LOOP() - else if (idir == 3) then - $:GPU_PARALLEL_LOOP(private='[i, j, k, l]', collapse=4) + elseif (idir == 3) then + $:GPU_PARALLEL_LOOP(private='[i,j,k,l]', collapse=4) do i = 1, sys_size do l = 0, p do k = 0, n do j = 0, m - rhs_vf(i)%sf(j, k, l) = rhs_vf(i)%sf(j, k, l) + 1._wp/dz(l)*(flux_vf(i)%sf(j, k, & - & l - 1) - flux_vf(i)%sf(j, k, l)) + rhs_vf(i)%sf(j, k, l) = & + rhs_vf(i)%sf(j, k, l) + 1._wp/dz(l)* & + (flux_vf(i)%sf(j, k, l - 1) & + - flux_vf(i)%sf(j, k, l)) end do end do end do @@ -2705,7 +2901,7 @@ contains end subroutine s_igr_flux_add - !> Finalize the IGR module + !> @brief Deallocates all arrays and GPU resources allocated by the IGR module. subroutine s_finalize_igr_module() if (viscous) then @@ -2715,7 +2911,7 @@ contains #ifndef __NVCOMPILER_GPU_UNIFIED_MEM @:DEALLOCATE(jac, jac_rhs) - if (igr_iter_solver == 1) then ! Jacobi iteration + if (igr_iter_solver == 1) then ! Jacobi iteration @:DEALLOCATE(jac_old) end if #else @@ -2733,7 +2929,7 @@ contains deallocate (jac_rhs_host) end if - if (igr_iter_solver == 1) then ! Jacobi iteration + if (igr_iter_solver == 1) then ! Jacobi iteration if (nv_uvm_temp_on_gpu(3) == 1) then @:DEALLOCATE(jac_old) else diff --git a/src/simulation/m_mpi_proxy.fpp b/src/simulation/m_mpi_proxy.fpp index a2b6c84326..3bc731306f 100644 --- a/src/simulation/m_mpi_proxy.fpp +++ b/src/simulation/m_mpi_proxy.fpp @@ -9,37 +9,67 @@ module m_mpi_proxy #ifdef MFC_MPI - use mpi !< Message passing interface (MPI) module + use mpi !< Message passing interface (MPI) module #endif - use m_helper_basic + use m_helper_basic !< Functions to compare floating point numbers + use m_helper - use m_derived_types - use m_global_parameters + + use m_derived_types !< Definitions of the derived types + + use m_global_parameters !< Definitions of the global parameters + use m_mpi_common + use m_nvtx + use ieee_arithmetic implicit none - integer, private, allocatable, dimension(:) :: ib_buff_send !< IB marker send buffer for halo exchange - integer, private, allocatable, dimension(:) :: ib_buff_recv !< IB marker receive buffer for halo exchange - integer :: i_halo_size + integer, private, allocatable, dimension(:) :: ib_buff_send !< + !! This variable is utilized to pack and send the buffer of the immersed + !! boundary markers, for a single computational domain boundary at the + !! time, to the relevant neighboring processor. + + integer, private, allocatable, dimension(:) :: ib_buff_recv !< + !! q_cons_buff_recv is utilized to receive and unpack the buffer of the + !! immersed boundary markers, for a single computational domain boundary + !! at the time, from the relevant neighboring processor. + + integer :: i_halo_size $:GPU_DECLARE(create='[i_halo_size]') + integer, dimension(-1:1, -1:1, -1:1) :: p_send_counts, p_recv_counts + integer, dimension(:, :, :, :), allocatable :: p_send_ids + character(len=1), dimension(:), allocatable :: p_send_buff, p_recv_buff + integer :: p_buff_size, p_var_size + !! EL Bubbles communication variables + integer, parameter :: MAX_NEIGHBORS = 27 + integer :: send_requests(MAX_NEIGHBORS), recv_requests(MAX_NEIGHBORS) + integer :: recv_offsets(MAX_NEIGHBORS) + integer :: neighbor_list(MAX_NEIGHBORS, 3) + integer :: n_neighbors + $:GPU_DECLARE(create='[p_send_counts]') + contains - !> Initialize the MPI proxy module + !> @brief Allocates immersed boundary communication buffers for MPI halo exchanges. subroutine s_initialize_mpi_proxy_module() #ifdef MFC_MPI if (ib) then if (n > 0) then if (p > 0) then - i_halo_size = -1 + buff_size*(m + 2*buff_size + 1)*(n + 2*buff_size + 1)*(p + 2*buff_size + 1) & - & /(cells_bounds%mnp_min + 2*buff_size + 1) + i_halo_size = -1 + buff_size* & + & (m + 2*buff_size + 1)* & + & (n + 2*buff_size + 1)* & + & (p + 2*buff_size + 1)/ & + & (cells_bounds%mnp_min + 2*buff_size + 1) else - i_halo_size = -1 + buff_size*(cells_bounds%mn_max + 2*buff_size + 1) + i_halo_size = -1 + buff_size* & + & (cells_bounds%mn_max + 2*buff_size + 1) end if else i_halo_size = -1 + buff_size @@ -52,14 +82,53 @@ contains end subroutine s_initialize_mpi_proxy_module - !> Since only the processor with rank 0 reads and verifies the consistency of user inputs, these are initially not available to - !! the other processors. Then, the purpose of this subroutine is to distribute the user inputs to the remaining processors in - !! the communicator. + !! This subroutine initializes the MPI buffers and variables + !! required for the particle communication. + !! @param lag_num_ts Number of stages in time-stepping scheme + subroutine s_initialize_particles_mpi(lag_num_ts) + + integer, intent(in) :: lag_num_ts + integer :: i, j, k + integer :: real_size, int_size, nReal + integer :: ierr !< Generic flag used to identify and report MPI errors + +#ifdef MFC_MPI + call MPI_Pack_size(1, mpi_p, MPI_COMM_WORLD, real_size, ierr) + call MPI_Pack_size(1, MPI_INTEGER, MPI_COMM_WORLD, int_size, ierr) + nReal = 7 + 16*2 + 10*lag_num_ts + p_var_size = nReal*real_size + int_size + p_buff_size = lag_params%nBubs_glb*p_var_size + @:ALLOCATE(p_send_buff(0:p_buff_size), p_recv_buff(0:p_buff_size)) + @:ALLOCATE(p_send_ids(nidx(1)%beg:nidx(1)%end, nidx(2)%beg:nidx(2)%end, nidx(3)%beg:nidx(3)%end, 0:lag_params%nBubs_glb)) + ! First, collect all neighbor information + n_neighbors = 0 + do k = nidx(3)%beg, nidx(3)%end + do j = nidx(2)%beg, nidx(2)%end + do i = nidx(1)%beg, nidx(1)%end + if (abs(i) + abs(j) + abs(k) /= 0) then + n_neighbors = n_neighbors + 1 + neighbor_list(n_neighbors, 1) = i + neighbor_list(n_neighbors, 2) = j + neighbor_list(n_neighbors, 3) = k + end if + end do + end do + end do +#endif + + end subroutine s_initialize_particles_mpi + + !> Since only the processor with rank 0 reads and verifies + !! the consistency of user inputs, these are initially not + !! available to the other processors. Then, the purpose of + !! this subroutine is to distribute the user inputs to the + !! remaining processors in the communicator. impure subroutine s_mpi_bcast_user_inputs() #ifdef MFC_MPI - integer :: i, j !< Generic loop iterator - integer :: ierr !< Generic flag used to identify and report MPI errors + + integer :: i, j !< Generic loop iterator + integer :: ierr !< Generic flag used to identify and report MPI errors call MPI_BCAST(case_dir, len(case_dir), MPI_CHARACTER, 0, MPI_COMM_WORLD, ierr) @@ -109,17 +178,21 @@ contains if (bubbles_lagrange) then #:for VAR in [ 'heatTransfer_model', 'massTransfer_model', 'pressure_corrector', & - & 'write_bubbles', 'write_bubbles_stats'] + & 'write_bubbles', 'write_bubbles_stats', 'write_void_evol', 'pressure_force', & + & 'gravity_force'] call MPI_BCAST(lag_params%${VAR}$, 1, MPI_LOGICAL, 0, MPI_COMM_WORLD, ierr) #:endfor - #:for VAR in ['solver_approach', 'cluster_type', 'smooth_type', 'nBubs_glb'] + #:for VAR in ['solver_approach', 'cluster_type', 'smooth_type', 'nBubs_glb', 'vel_model', & + & 'drag_model', 'charNz'] call MPI_BCAST(lag_params%${VAR}$, 1, MPI_INTEGER, 0, MPI_COMM_WORLD, ierr) #:endfor #:for VAR in ['epsilonb','charwidth','valmaxvoid'] call MPI_BCAST(lag_params%${VAR}$, 1, mpi_p, 0, MPI_COMM_WORLD, ierr) #:endfor + + call MPI_BCAST(lag_params%input_path, len(lag_params%input_path), MPI_CHARACTER, 0, MPI_COMM_WORLD, ierr) end if #:for VAR in [ 'dt','weno_eps','teno_CT','pref','rhoref','R0ref','Web','Ca', 'sigma', & @@ -128,9 +201,7 @@ contains & 'bc_y%vb1','bc_y%vb2','bc_y%vb3','bc_y%ve1','bc_y%ve2','bc_y%ve3', & & 'bc_z%vb1','bc_z%vb2','bc_z%vb3','bc_z%ve1','bc_z%ve2','bc_z%ve3', & & 'bc_x%pres_in','bc_x%pres_out','bc_y%pres_in','bc_y%pres_out', 'bc_z%pres_in','bc_z%pres_out', & - & 'x_domain%beg', 'x_domain%end', 'y_domain%beg', 'y_domain%end', & - & 'z_domain%beg', 'z_domain%end', 'x_a', 'x_b', 'y_a', 'y_b', 'z_a', & - & 'z_b', 't_stop', 't_save', 'cfl_target', 'Bx0', 'alf_factor', & + & 't_stop', 't_save', 'cfl_target', 'Bx0', 'alf_factor', & & 'tau_star', 'cont_damage_s', 'alpha_bar', 'adap_dt_tol', & & 'ic_eps', 'ic_beta', 'hyper_cleaning_speed', & & 'hyper_cleaning_tau' ] @@ -180,8 +251,7 @@ contains end if do i = 1, num_fluids_max - #:for VAR in ['bc_x%alpha_rho_in','bc_x%alpha_in','bc_y%alpha_rho_in','bc_y%alpha_in','bc_z%alpha_rho_in', & - & 'bc_z%alpha_in'] + #:for VAR in ['bc_x%alpha_rho_in','bc_x%alpha_in','bc_y%alpha_rho_in','bc_y%alpha_in','bc_z%alpha_rho_in','bc_z%alpha_in'] call MPI_BCAST(${VAR}$ (i), 1, mpi_p, 0, MPI_COMM_WORLD, ierr) #:endfor end do @@ -233,31 +303,700 @@ contains call MPI_BCAST(nv_uvm_out_of_core, 1, MPI_LOGICAL, 0, MPI_COMM_WORLD, ierr) call MPI_BCAST(nv_uvm_igr_temps_on_gpu, 1, MPI_INTEGER, 0, MPI_COMM_WORLD, ierr) call MPI_BCAST(nv_uvm_pref_gpu, 1, MPI_LOGICAL, 0, MPI_COMM_WORLD, ierr) + + ! Extra BC Variable + call MPI_BCAST(periodic_bc, 3, MPI_LOGICAL, 0, MPI_COMM_WORLD, ierr) + #endif end subroutine s_mpi_bcast_user_inputs - !> Broadcast random phase numbers from rank 0 to all MPI processes - impure subroutine s_mpi_send_random_number(phi_rn, num_freq) + !> @brief Packs, exchanges, and unpacks immersed boundary marker buffers between neighboring MPI ranks. + subroutine s_mpi_sendrecv_ib_buffers(ib_markers, mpi_dir, pbc_loc) - integer, intent(in) :: num_freq - real(wp), intent(inout), dimension(1:num_freq) :: phi_rn + type(integer_field), intent(inout) :: ib_markers + + integer, intent(in) :: mpi_dir, pbc_loc + + integer :: i, j, k, l, r, q !< Generic loop iterators + + integer :: buffer_counts(1:3), buffer_count + + type(int_bounds_info) :: boundary_conditions(1:3) + integer :: beg_end(1:2), grid_dims(1:3) + integer :: dst_proc, src_proc, recv_tag, send_tag + + logical :: beg_end_geq_0, qbmm_comm + + integer :: pack_offset, unpack_offset #ifdef MFC_MPI - integer :: ierr !< Generic flag used to identify and report MPI errors + integer :: ierr !< Generic flag used to identify and report MPI errors + + call nvtxStartRange("IB-MARKER-COMM-PACKBUF") + + buffer_counts = (/ & + buff_size*(n + 1)*(p + 1), & + buff_size*(m + 2*buff_size + 1)*(p + 1), & + buff_size*(m + 2*buff_size + 1)*(n + 2*buff_size + 1) & + /) + buffer_count = buffer_counts(mpi_dir) + boundary_conditions = (/bc_x, bc_y, bc_z/) + beg_end = (/boundary_conditions(mpi_dir)%beg, boundary_conditions(mpi_dir)%end/) + beg_end_geq_0 = beg_end(max(pbc_loc, 0) - pbc_loc + 1) >= 0 + + ! Implements: + ! pbc_loc bc_x >= 0 -> [send/recv]_tag [dst/src]_proc + ! -1 (=0) 0 -> [1,0] [0,0] | 0 0 [1,0] [beg,beg] + ! -1 (=0) 1 -> [0,0] [1,0] | 0 1 [0,0] [end,beg] + ! +1 (=1) 0 -> [0,1] [1,1] | 1 0 [0,1] [end,end] + ! +1 (=1) 1 -> [1,1] [0,1] | 1 1 [1,1] [beg,end] + + send_tag = f_logical_to_int(.not. f_xor(beg_end_geq_0, pbc_loc == 1)) + recv_tag = f_logical_to_int(pbc_loc == 1) + + dst_proc = beg_end(1 + f_logical_to_int(f_xor(pbc_loc == 1, beg_end_geq_0))) + src_proc = beg_end(1 + f_logical_to_int(pbc_loc == 1)) + + grid_dims = (/m, n, p/) + + pack_offset = 0 + if (f_xor(pbc_loc == 1, beg_end_geq_0)) then + pack_offset = grid_dims(mpi_dir) - buff_size + 1 + end if + + unpack_offset = 0 + if (pbc_loc == 1) then + unpack_offset = grid_dims(mpi_dir) + buff_size + 1 + end if + + ! Pack Buffer to Send + #:for mpi_dir in [1, 2, 3] + if (mpi_dir == ${mpi_dir}$) then + #:if mpi_dir == 1 + $:GPU_PARALLEL_LOOP(collapse=3,private='[j,k,l,r]') + do l = 0, p + do k = 0, n + do j = 0, buff_size - 1 + r = (j + buff_size*(k + (n + 1)*l)) + ib_buff_send(r) = ib_markers%sf(j + pack_offset, k, l) + end do + end do + end do + $:END_GPU_PARALLEL_LOOP() + #:elif mpi_dir == 2 + $:GPU_PARALLEL_LOOP(collapse=3,private='[j,k,l,r]') + do l = 0, p + do k = 0, buff_size - 1 + do j = -buff_size, m + buff_size + r = ((j + buff_size) + (m + 2*buff_size + 1)* & + (k + buff_size*l)) + ib_buff_send(r) = ib_markers%sf(j, k + pack_offset, l) + end do + end do + end do + $:END_GPU_PARALLEL_LOOP() + #:else + $:GPU_PARALLEL_LOOP(collapse=3,private='[j,k,l,r]') + do l = 0, buff_size - 1 + do k = -buff_size, n + buff_size + do j = -buff_size, m + buff_size + r = ((j + buff_size) + (m + 2*buff_size + 1)* & + ((k + buff_size) + (n + 2*buff_size + 1)*l)) + ib_buff_send(r) = ib_markers%sf(j, k, l + pack_offset) + end do + end do + end do + $:END_GPU_PARALLEL_LOOP() + #:endif + end if + #:endfor + call nvtxEndRange ! Packbuf + + #:for rdma_mpi in [False, True] + if (rdma_mpi .eqv. ${'.true.' if rdma_mpi else '.false.'}$) then + #:if rdma_mpi + #:call GPU_HOST_DATA(use_device_addr='[ib_buff_send, ib_buff_recv]') + + call nvtxStartRange("IB-MARKER-SENDRECV-RDMA") + call MPI_SENDRECV( & + ib_buff_send, buffer_count, MPI_INTEGER, dst_proc, send_tag, & + ib_buff_recv, buffer_count, MPI_INTEGER, src_proc, recv_tag, & + MPI_COMM_WORLD, MPI_STATUS_IGNORE, ierr) + call nvtxEndRange + + #:endcall GPU_HOST_DATA + $:GPU_WAIT() + #:else + call nvtxStartRange("IB-MARKER-DEV2HOST") + $:GPU_UPDATE(host='[ib_buff_send]') + call nvtxEndRange + + call nvtxStartRange("IB-MARKER-SENDRECV-NO-RMDA") + call MPI_SENDRECV( & + ib_buff_send, buffer_count, MPI_INTEGER, dst_proc, send_tag, & + ib_buff_recv, buffer_count, MPI_INTEGER, src_proc, recv_tag, & + MPI_COMM_WORLD, MPI_STATUS_IGNORE, ierr) + call nvtxEndRange + + call nvtxStartRange("IB-MARKER-HOST2DEV") + $:GPU_UPDATE(device='[ib_buff_recv]') + call nvtxEndRange + #:endif + end if + #:endfor + + ! Unpack Received Buffer + call nvtxStartRange("IB-MARKER-COMM-UNPACKBUF") + #:for mpi_dir in [1, 2, 3] + if (mpi_dir == ${mpi_dir}$) then + #:if mpi_dir == 1 + $:GPU_PARALLEL_LOOP(collapse=3,private='[j,k,l,r]') + do l = 0, p + do k = 0, n + do j = -buff_size, -1 + r = (j + buff_size*((k + 1) + (n + 1)*l)) + ib_markers%sf(j + unpack_offset, k, l) = ib_buff_recv(r) + end do + end do + end do + $:END_GPU_PARALLEL_LOOP() + #:elif mpi_dir == 2 + $:GPU_PARALLEL_LOOP(collapse=3,private='[j,k,l,r]') + do l = 0, p + do k = -buff_size, -1 + do j = -buff_size, m + buff_size + r = ((j + buff_size) + (m + 2*buff_size + 1)* & + ((k + buff_size) + buff_size*l)) + ib_markers%sf(j, k + unpack_offset, l) = ib_buff_recv(r) + end do + end do + end do + $:END_GPU_PARALLEL_LOOP() + #:else + ! Unpacking buffer from bc_z%beg + $:GPU_PARALLEL_LOOP(collapse=3,private='[j,k,l,r]') + do l = -buff_size, -1 + do k = -buff_size, n + buff_size + do j = -buff_size, m + buff_size + r = ((j + buff_size) + (m + 2*buff_size + 1)* & + ((k + buff_size) + (n + 2*buff_size + 1)* & + (l + buff_size))) + ib_markers%sf(j, k, l + unpack_offset) = ib_buff_recv(r) + end do + end do + end do + $:END_GPU_PARALLEL_LOOP() + #:endif + end if + #:endfor + call nvtxEndRange +#endif + + end subroutine s_mpi_sendrecv_ib_buffers + + !> This subroutine adds particles to the transfer list for the MPI + !! communication. + !! @param nBub Current LOCAL number of bubbles + !! @param pos Current position of each bubble + !! @param posPrev Previous position of each bubble (optional, not used + !! for communication of initial condition) + impure subroutine s_add_particles_to_transfer_list(nBub, pos, posPrev) + + integer, intent(in) :: nBub + real(wp), dimension(:, :), intent(in) :: pos, posPrev + integer :: bubID + integer :: i, j, k + + do k = nidx(3)%beg, nidx(3)%end + do j = nidx(2)%beg, nidx(2)%end + do i = nidx(1)%beg, nidx(1)%end + p_send_counts(i, j, k) = 0 + end do + end do + end do + + do k = 1, nbub + if (f_crosses_boundary(k, 1, -1, pos, posPrev)) then + call s_add_particle_to_direction(k, -1, 0, 0) + if (n > 0) then + if (f_crosses_boundary(k, 2, -1, pos, posPrev)) then + call s_add_particle_to_direction(k, -1, -1, 0) + call s_add_particle_to_direction(k, 0, -1, 0) + if (p > 0) then + if (f_crosses_boundary(k, 3, -1, pos, posPrev)) then + call s_add_particle_to_direction(k, -1, -1, -1) + call s_add_particle_to_direction(k, 0, -1, -1) + call s_add_particle_to_direction(k, -1, 0, -1) + call s_add_particle_to_direction(k, 0, 0, -1) + elseif (f_crosses_boundary(k, 3, 1, pos, posPrev)) then + call s_add_particle_to_direction(k, -1, -1, 1) + call s_add_particle_to_direction(k, 0, -1, 1) + call s_add_particle_to_direction(k, -1, 0, 1) + call s_add_particle_to_direction(k, 0, 0, 1) + end if + end if + elseif (f_crosses_boundary(k, 2, 1, pos, posPrev)) then + call s_add_particle_to_direction(k, -1, 1, 0) + call s_add_particle_to_direction(k, 0, 1, 0) + if (p > 0) then + if (f_crosses_boundary(k, 3, -1, pos, posPrev)) then + call s_add_particle_to_direction(k, -1, 1, -1) + call s_add_particle_to_direction(k, 0, 1, -1) + call s_add_particle_to_direction(k, -1, 0, -1) + call s_add_particle_to_direction(k, 0, 0, -1) + elseif (f_crosses_boundary(k, 3, 1, pos, posPrev)) then + call s_add_particle_to_direction(k, -1, 1, 1) + call s_add_particle_to_direction(k, 0, 1, 1) + call s_add_particle_to_direction(k, -1, 0, 1) + call s_add_particle_to_direction(k, 0, 0, 1) + end if + end if + else + if (p > 0) then + if (f_crosses_boundary(k, 3, -1, pos, posPrev)) then + call s_add_particle_to_direction(k, -1, 0, -1) + call s_add_particle_to_direction(k, 0, 0, -1) + elseif (f_crosses_boundary(k, 3, 1, pos, posPrev)) then + call s_add_particle_to_direction(k, -1, 0, 1) + call s_add_particle_to_direction(k, 0, 0, 1) + end if + end if + end if + end if + elseif (f_crosses_boundary(k, 1, 1, pos, posPrev)) then + call s_add_particle_to_direction(k, 1, 0, 0) + if (n > 0) then + if (f_crosses_boundary(k, 2, -1, pos, posPrev)) then + call s_add_particle_to_direction(k, 1, -1, 0) + call s_add_particle_to_direction(k, 0, -1, 0) + if (p > 0) then + if (f_crosses_boundary(k, 3, -1, pos, posPrev)) then + call s_add_particle_to_direction(k, 1, -1, -1) + call s_add_particle_to_direction(k, 0, -1, -1) + call s_add_particle_to_direction(k, 1, 0, -1) + call s_add_particle_to_direction(k, 0, 0, -1) + elseif (f_crosses_boundary(k, 3, 1, pos, posPrev)) then + call s_add_particle_to_direction(k, 1, -1, 1) + call s_add_particle_to_direction(k, 0, -1, 1) + call s_add_particle_to_direction(k, 1, 0, 1) + call s_add_particle_to_direction(k, 0, 0, 1) + end if + end if + elseif (f_crosses_boundary(k, 2, 1, pos, posPrev)) then + call s_add_particle_to_direction(k, 1, 1, 0) + call s_add_particle_to_direction(k, 0, 1, 0) + if (p > 0) then + if (f_crosses_boundary(k, 3, -1, pos, posPrev)) then + call s_add_particle_to_direction(k, 1, 1, -1) + call s_add_particle_to_direction(k, 0, 1, -1) + call s_add_particle_to_direction(k, 1, 0, -1) + call s_add_particle_to_direction(k, 0, 0, -1) + elseif (f_crosses_boundary(k, 3, 1, pos, posPrev)) then + call s_add_particle_to_direction(k, 1, 1, 1) + call s_add_particle_to_direction(k, 0, 1, 1) + call s_add_particle_to_direction(k, 1, 0, 1) + call s_add_particle_to_direction(k, 0, 0, 1) + end if + end if + else + if (p > 0) then + if (f_crosses_boundary(k, 3, -1, pos, posPrev)) then + call s_add_particle_to_direction(k, 1, 0, -1) + call s_add_particle_to_direction(k, 0, 0, -1) + elseif (f_crosses_boundary(k, 3, 1, pos, posPrev)) then + call s_add_particle_to_direction(k, 1, 0, 1) + call s_add_particle_to_direction(k, 0, 0, 1) + end if + end if + end if + end if + elseif (f_crosses_boundary(k, 2, -1, pos, posPrev)) then + call s_add_particle_to_direction(k, 0, -1, 0) + if (p > 0) then + if (f_crosses_boundary(k, 3, -1, pos, posPrev)) then + call s_add_particle_to_direction(k, 0, -1, -1) + call s_add_particle_to_direction(k, 0, 0, -1) + elseif (f_crosses_boundary(k, 3, 1, pos, posPrev)) then + call s_add_particle_to_direction(k, 0, -1, 1) + call s_add_particle_to_direction(k, 0, 0, 1) + end if + end if + elseif (f_crosses_boundary(k, 2, 1, pos, posPrev)) then + call s_add_particle_to_direction(k, 0, 1, 0) + if (p > 0) then + if (f_crosses_boundary(k, 3, -1, pos, posPrev)) then + call s_add_particle_to_direction(k, 0, 1, -1) + call s_add_particle_to_direction(k, 0, 0, -1) + elseif (f_crosses_boundary(k, 3, 1, pos, posPrev)) then + call s_add_particle_to_direction(k, 0, 1, 1) + call s_add_particle_to_direction(k, 0, 0, 1) + end if + end if + elseif (p > 0) then + if (f_crosses_boundary(k, 3, -1, pos, posPrev)) then + call s_add_particle_to_direction(k, 0, 0, -1) + elseif (f_crosses_boundary(k, 3, 1, pos, posPrev)) then + call s_add_particle_to_direction(k, 0, 0, 1) + end if + end if + + end do + + contains + + logical function f_crosses_boundary(particle_id, dir, loc, pos, posPrev) + + integer, intent(in) :: particle_id, dir, loc + real(wp), dimension(:, :), intent(in) :: pos + real(wp), dimension(:, :), optional, intent(in) :: posPrev + + if (loc == -1) then ! Beginning of the domain + if (nidx(dir)%beg == 0) then + f_crosses_boundary = .false. + return + end if + + f_crosses_boundary = (posPrev(particle_id, dir) >= pcomm_coords(dir)%beg .and. & + pos(particle_id, dir) < pcomm_coords(dir)%beg) + elseif (loc == 1) then ! End of the domain + if (nidx(dir)%end == 0) then + f_crosses_boundary = .false. + return + end if + + f_crosses_boundary = (posPrev(particle_id, dir) <= pcomm_coords(dir)%end .and. & + pos(particle_id, dir) > pcomm_coords(dir)%end) + end if + + end function f_crosses_boundary + + subroutine s_add_particle_to_direction(particle_id, dir_x, dir_y, dir_z) + + integer, intent(in) :: particle_id, dir_x, dir_y, dir_z + + p_send_ids(dir_x, dir_y, dir_z, p_send_counts(dir_x, dir_y, dir_z)) = particle_id + p_send_counts(dir_x, dir_y, dir_z) = p_send_counts(dir_x, dir_y, dir_z) + 1 + + end subroutine s_add_particle_to_direction + + end subroutine s_add_particles_to_transfer_list + + !> This subroutine performs the MPI communication for lagrangian particles/ + !! bubbles. + !! @param bub_R0 Initial radius of each bubble + !! @param Rmax_stats Maximum radius of each bubble + !! @param Rmin_stats Minimum radius of each bubble + !! @param gas_mg Mass of gas in each bubble + !! @param gas_betaT Heat flux model coefficient for each bubble + !! @param gas_betaC mass flux model coefficient for each bubble + !! @param bub_dphidt Subgrid velocity potential for each bubble + !! @param lag_id Global and local ID of each bubble + !! @param gas_p Pressure of the gas in each bubble + !! @param gas_mv Mass of vapor in each bubble + !! @param rad Radius of each bubble + !! @param rvel Radial velocity of each bubble + !! @param pos Position of each bubble + !! @param posPrev Previous position of each bubble + !! @param vel Velocity of each bubble + !! @param scoord Cell index in real format of each bubble + !! @param drad Radial velocity of each bubble + !! @param drvel Radial acceleration of each bubble + !! @param dgasp Time derivative of gas pressure in each bubble + !! @param dgasmv Time derivative of vapor mass in each bubble + !! @param dpos Time derivative of position of each bubble + !! @param dvel Time derivative of velocity of each bubble + !! @param lag_num_ts Number of stages in time-stepping scheme + !! @param nBubs Local number of bubbles + impure subroutine s_mpi_sendrecv_particles(bub_R0, Rmax_stats, Rmin_stats, gas_mg, gas_betaT, & + gas_betaC, bub_dphidt, lag_id, gas_p, gas_mv, rad, & + rvel, pos, posPrev, vel, scoord, drad, drvel, dgasp, & + dgasmv, dpos, dvel, lag_num_ts, nbubs, dest) + + real(wp), dimension(:) :: bub_R0, Rmax_stats, Rmin_stats, gas_mg, gas_betaT, gas_betaC, bub_dphidt + integer, dimension(:, :) :: lag_id + real(wp), dimension(:, :) :: gas_p, gas_mv, rad, rvel, drad, drvel, dgasp, dgasmv + real(wp), dimension(:, :, :) :: pos, posPrev, vel, scoord, dpos, dvel + integer :: position, bub_id, lag_num_ts, tag, partner, send_tag, recv_tag, nbubs, p_recv_size, dest + + integer :: i, j, k, l, q, r + integer :: req_send, req_recv, ierr !< Generic flag used to identify and report MPI errors + integer :: send_count, send_offset, recv_count, recv_offset + +#ifdef MFC_MPI + ! Phase 1: Exchange particle counts using non-blocking communication + send_count = 0 + recv_count = 0 + + ! Post all receives first + do l = 1, n_neighbors + i = neighbor_list(l, 1) + j = neighbor_list(l, 2) + k = neighbor_list(l, 3) + partner = neighbor_ranks(i, j, k) + recv_tag = neighbor_tag(i, j, k) + + recv_count = recv_count + 1 + call MPI_Irecv(p_recv_counts(i, j, k), 1, MPI_INTEGER, partner, recv_tag, & + MPI_COMM_WORLD, recv_requests(recv_count), ierr) + end do + + ! Post all sends + do l = 1, n_neighbors + i = neighbor_list(l, 1) + j = neighbor_list(l, 2) + k = neighbor_list(l, 3) + partner = neighbor_ranks(i, j, k) + send_tag = neighbor_tag(-i, -j, -k) + + send_count = send_count + 1 + call MPI_Isend(p_send_counts(i, j, k), 1, MPI_INTEGER, partner, send_tag, & + MPI_COMM_WORLD, send_requests(send_count), ierr) + end do + + ! Wait for all count exchanges to complete + if (recv_count > 0) then + call MPI_Waitall(recv_count, recv_requests(1:recv_count), MPI_STATUSES_IGNORE, ierr) + end if + if (send_count > 0) then + call MPI_Waitall(send_count, send_requests(1:send_count), MPI_STATUSES_IGNORE, ierr) + end if + + ! Phase 2: Exchange particle data using non-blocking communication + send_count = 0 + recv_count = 0 + + ! Post all receives for particle data first + recv_offset = 1 + do l = 1, n_neighbors + i = neighbor_list(l, 1) + j = neighbor_list(l, 2) + k = neighbor_list(l, 3) + + if (p_recv_counts(i, j, k) > 0) then + partner = neighbor_ranks(i, j, k) + p_recv_size = p_recv_counts(i, j, k)*p_var_size + recv_tag = neighbor_tag(i, j, k) + + recv_count = recv_count + 1 + call MPI_Irecv(p_recv_buff(recv_offset), p_recv_size, MPI_PACKED, partner, recv_tag, & + MPI_COMM_WORLD, recv_requests(recv_count), ierr) + recv_offsets(l) = recv_offset + recv_offset = recv_offset + p_recv_size + end if + end do + + ! Pack and send particle data + send_offset = 0 + do l = 1, n_neighbors + i = neighbor_list(l, 1) + j = neighbor_list(l, 2) + k = neighbor_list(l, 3) + + if (p_send_counts(i, j, k) > 0 .and. abs(i) + abs(j) + abs(k) /= 0 .and. abs(i) + abs(j) + abs(k) /= 0) then + partner = neighbor_ranks(i, j, k) + send_tag = neighbor_tag(-i, -j, -k) + + ! Pack data for sending + position = 0 + do q = 0, p_send_counts(i, j, k) - 1 + bub_id = p_send_ids(i, j, k, q) + + call MPI_Pack(lag_id(bub_id, 1), 1, MPI_INTEGER, p_send_buff(send_offset), p_buff_size, position, MPI_COMM_WORLD, ierr) + call MPI_Pack(bub_R0(bub_id), 1, mpi_p, p_send_buff(send_offset), p_buff_size, position, MPI_COMM_WORLD, ierr) + call MPI_Pack(Rmax_stats(bub_id), 1, mpi_p, p_send_buff(send_offset), p_buff_size, position, MPI_COMM_WORLD, ierr) + call MPI_Pack(Rmin_stats(bub_id), 1, mpi_p, p_send_buff(send_offset), p_buff_size, position, MPI_COMM_WORLD, ierr) + call MPI_Pack(gas_mg(bub_id), 1, mpi_p, p_send_buff(send_offset), p_buff_size, position, MPI_COMM_WORLD, ierr) + call MPI_Pack(gas_betaT(bub_id), 1, mpi_p, p_send_buff(send_offset), p_buff_size, position, MPI_COMM_WORLD, ierr) + call MPI_Pack(gas_betaC(bub_id), 1, mpi_p, p_send_buff(send_offset), p_buff_size, position, MPI_COMM_WORLD, ierr) + call MPI_Pack(bub_dphidt(bub_id), 1, mpi_p, p_send_buff(send_offset), p_buff_size, position, MPI_COMM_WORLD, ierr) + do r = 1, 2 + call MPI_Pack(gas_p(bub_id, r), 1, mpi_p, p_send_buff(send_offset), p_buff_size, position, MPI_COMM_WORLD, ierr) + call MPI_Pack(gas_mv(bub_id, r), 1, mpi_p, p_send_buff(send_offset), p_buff_size, position, MPI_COMM_WORLD, ierr) + call MPI_Pack(rad(bub_id, r), 1, mpi_p, p_send_buff(send_offset), p_buff_size, position, MPI_COMM_WORLD, ierr) + call MPI_Pack(rvel(bub_id, r), 1, mpi_p, p_send_buff(send_offset), p_buff_size, position, MPI_COMM_WORLD, ierr) + call MPI_Pack(pos(bub_id, :, r), 3, mpi_p, p_send_buff(send_offset), p_buff_size, position, MPI_COMM_WORLD, ierr) + call MPI_Pack(posPrev(bub_id, :, r), 3, mpi_p, p_send_buff(send_offset), p_buff_size, position, MPI_COMM_WORLD, ierr) + call MPI_Pack(vel(bub_id, :, r), 3, mpi_p, p_send_buff(send_offset), p_buff_size, position, MPI_COMM_WORLD, ierr) + call MPI_Pack(scoord(bub_id, :, r), 3, mpi_p, p_send_buff(send_offset), p_buff_size, position, MPI_COMM_WORLD, ierr) + end do + do r = 1, lag_num_ts + call MPI_Pack(drad(bub_id, r), 1, mpi_p, p_send_buff(send_offset), p_buff_size, position, MPI_COMM_WORLD, ierr) + call MPI_Pack(drvel(bub_id, r), 1, mpi_p, p_send_buff(send_offset), p_buff_size, position, MPI_COMM_WORLD, ierr) + call MPI_Pack(dgasp(bub_id, r), 1, mpi_p, p_send_buff(send_offset), p_buff_size, position, MPI_COMM_WORLD, ierr) + call MPI_Pack(dgasmv(bub_id, r), 1, mpi_p, p_send_buff(send_offset), p_buff_size, position, MPI_COMM_WORLD, ierr) + call MPI_Pack(dpos(bub_id, :, r), 3, mpi_p, p_send_buff(send_offset), p_buff_size, position, MPI_COMM_WORLD, ierr) + call MPI_Pack(dvel(bub_id, :, r), 3, mpi_p, p_send_buff(send_offset), p_buff_size, position, MPI_COMM_WORLD, ierr) + end do + end do + + send_count = send_count + 1 + call MPI_Isend(p_send_buff(send_offset), position, MPI_PACKED, partner, send_tag, & + MPI_COMM_WORLD, send_requests(send_count), ierr) + send_offset = send_offset + position + end if + end do + + ! Wait for all recvs for contiguous data to complete + call MPI_Waitall(recv_count, recv_requests(1:recv_count), MPI_STATUSES_IGNORE, ierr) + + ! Process received data as it arrives + do l = 1, n_neighbors + i = neighbor_list(l, 1) + j = neighbor_list(l, 2) + k = neighbor_list(l, 3) + + if (p_recv_counts(i, j, k) > 0 .and. abs(i) + abs(j) + abs(k) /= 0) then + p_recv_size = p_recv_counts(i, j, k)*p_var_size + recv_offset = recv_offsets(l) + + position = 0 + ! Unpack received data + do q = 0, p_recv_counts(i, j, k) - 1 + nbubs = nbubs + 1 + bub_id = nbubs + call MPI_Unpack(p_recv_buff(recv_offset), p_recv_size, position, lag_id(bub_id, 1), 1, MPI_INTEGER, MPI_COMM_WORLD, ierr) + call MPI_Unpack(p_recv_buff(recv_offset), p_recv_size, position, bub_R0(bub_id), 1, mpi_p, MPI_COMM_WORLD, ierr) + call MPI_Unpack(p_recv_buff(recv_offset), p_recv_size, position, Rmax_stats(bub_id), 1, mpi_p, MPI_COMM_WORLD, ierr) + call MPI_Unpack(p_recv_buff(recv_offset), p_recv_size, position, Rmin_stats(bub_id), 1, mpi_p, MPI_COMM_WORLD, ierr) + call MPI_Unpack(p_recv_buff(recv_offset), p_recv_size, position, gas_mg(bub_id), 1, mpi_p, MPI_COMM_WORLD, ierr) + call MPI_Unpack(p_recv_buff(recv_offset), p_recv_size, position, gas_betaT(bub_id), 1, mpi_p, MPI_COMM_WORLD, ierr) + call MPI_Unpack(p_recv_buff(recv_offset), p_recv_size, position, gas_betaC(bub_id), 1, mpi_p, MPI_COMM_WORLD, ierr) + call MPI_Unpack(p_recv_buff(recv_offset), p_recv_size, position, bub_dphidt(bub_id), 1, mpi_p, MPI_COMM_WORLD, ierr) + do r = 1, 2 + call MPI_Unpack(p_recv_buff(recv_offset), p_recv_size, position, gas_p(bub_id, r), 1, mpi_p, MPI_COMM_WORLD, ierr) + call MPI_Unpack(p_recv_buff(recv_offset), p_recv_size, position, gas_mv(bub_id, r), 1, mpi_p, MPI_COMM_WORLD, ierr) + call MPI_Unpack(p_recv_buff(recv_offset), p_recv_size, position, rad(bub_id, r), 1, mpi_p, MPI_COMM_WORLD, ierr) + call MPI_Unpack(p_recv_buff(recv_offset), p_recv_size, position, rvel(bub_id, r), 1, mpi_p, MPI_COMM_WORLD, ierr) + call MPI_Unpack(p_recv_buff(recv_offset), p_recv_size, position, pos(bub_id, :, r), 3, mpi_p, MPI_COMM_WORLD, ierr) + call MPI_Unpack(p_recv_buff(recv_offset), p_recv_size, position, posPrev(bub_id, :, r), 3, mpi_p, MPI_COMM_WORLD, ierr) + call MPI_Unpack(p_recv_buff(recv_offset), p_recv_size, position, vel(bub_id, :, r), 3, mpi_p, MPI_COMM_WORLD, ierr) + call MPI_Unpack(p_recv_buff(recv_offset), p_recv_size, position, scoord(bub_id, :, r), 3, mpi_p, MPI_COMM_WORLD, ierr) + end do + do r = 1, lag_num_ts + call MPI_Unpack(p_recv_buff(recv_offset), p_recv_size, position, drad(bub_id, r), 1, mpi_p, MPI_COMM_WORLD, ierr) + call MPI_Unpack(p_recv_buff(recv_offset), p_recv_size, position, drvel(bub_id, r), 1, mpi_p, MPI_COMM_WORLD, ierr) + call MPI_Unpack(p_recv_buff(recv_offset), p_recv_size, position, dgasp(bub_id, r), 1, mpi_p, MPI_COMM_WORLD, ierr) + call MPI_Unpack(p_recv_buff(recv_offset), p_recv_size, position, dgasmv(bub_id, r), 1, mpi_p, MPI_COMM_WORLD, ierr) + call MPI_Unpack(p_recv_buff(recv_offset), p_recv_size, position, dpos(bub_id, :, r), 3, mpi_p, MPI_COMM_WORLD, ierr) + call MPI_Unpack(p_recv_buff(recv_offset), p_recv_size, position, dvel(bub_id, :, r), 3, mpi_p, MPI_COMM_WORLD, ierr) + end do + lag_id(bub_id, 2) = bub_id + end do + recv_offset = recv_offset + p_recv_size + end if + + end do + + ! Wait for all sends to complete + if (send_count > 0) then + call MPI_Waitall(send_count, send_requests(1:send_count), MPI_STATUSES_IGNORE, ierr) + end if +#endif + + if (any(periodic_bc)) then + call s_wrap_particle_positions(pos, posPrev, nbubs, dest) + end if + + end subroutine s_mpi_sendrecv_particles + + !! This function returns a unique tag for each neighbor based on its position + !! relative to the current process. + !! @param i, j, k Indices of the neighbor in the range [-1, 1] + !! @return tag Unique integer tag for the neighbor + integer function neighbor_tag(i, j, k) result(tag) + + integer, intent(in) :: i, j, k + + tag = (k + 1)*9 + (j + 1)*3 + (i + 1) + + end function neighbor_tag + + subroutine s_wrap_particle_positions(pos, posPrev, nbubs, dest) + + real(wp), dimension(:, :, :) :: pos, posPrev + integer :: nbubs, dest + integer :: i, q + real(wp) :: offset + + do i = 1, nbubs + if (periodic_bc(1)) then + offset = glb_bounds(1)%end - glb_bounds(1)%beg + if (pos(i, 1, dest) > x_cb(m + buff_size)) then + do q = 1, 2 + pos(i, 1, q) = pos(i, 1, q) - offset + posPrev(i, 1, q) = posPrev(i, 1, q) - offset + end do + end if + if (pos(i, 1, dest) < x_cb(-1 - buff_size)) then + do q = 1, 2 + pos(i, 1, q) = pos(i, 1, q) + offset + posPrev(i, 1, q) = posPrev(i, 1, q) + offset + end do + end if + end if + + if (periodic_bc(2)) then + offset = glb_bounds(2)%end - glb_bounds(2)%beg + if (pos(i, 2, dest) > y_cb(n + buff_size)) then + do q = 1, 2 + pos(i, 2, q) = pos(i, 2, q) - offset + posPrev(i, 2, q) = posPrev(i, 2, q) - offset + end do + end if + if (pos(i, 2, dest) < y_cb(-buff_size - 1)) then + do q = 1, 2 + pos(i, 2, q) = pos(i, 2, q) + offset + posPrev(i, 2, q) = posPrev(i, 2, q) + offset + end do + end if + end if + + if (periodic_bc(3)) then + offset = glb_bounds(3)%end - glb_bounds(3)%beg + if (pos(i, 3, dest) > z_cb(p + buff_size)) then + do q = 1, 2 + pos(i, 3, q) = pos(i, 3, q) - offset + posPrev(i, 3, q) = posPrev(i, 3, q) - offset + end do + end if + if (pos(i, 3, dest) < z_cb(-1 - buff_size)) then + do q = 1, 2 + pos(i, 3, q) = pos(i, 3, q) + offset + posPrev(i, 3, q) = posPrev(i, 3, q) + offset + end do + end if + end if + end do + + end subroutine s_wrap_particle_positions + + !> @brief Broadcasts random phase numbers from rank 0 to all MPI processes. + impure subroutine s_mpi_send_random_number(phi_rn, num_freq) + integer, intent(in) :: num_freq + real(wp), intent(inout), dimension(1:num_freq) :: phi_rn + +#ifdef MFC_MPI + integer :: ierr !< Generic flag used to identify and report MPI errors call MPI_BCAST(phi_rn, num_freq, mpi_p, 0, MPI_COMM_WORLD, ierr) #endif end subroutine s_mpi_send_random_number - !> Finalize the MPI proxy module + !> @brief Deallocates immersed boundary MPI communication buffers. subroutine s_finalize_mpi_proxy_module() #ifdef MFC_MPI if (ib) then @:DEALLOCATE(ib_buff_send, ib_buff_recv) end if + + ! Particle MPI buffers are only allocated when num_procs > 1 + if (allocated(p_send_buff)) then + @:DEALLOCATE(p_send_buff, p_recv_buff) + @:DEALLOCATE(p_send_ids) + end if #endif end subroutine s_finalize_mpi_proxy_module diff --git a/src/simulation/m_muscl.fpp b/src/simulation/m_muscl.fpp index 5c9e844ec6..739800f93a 100644 --- a/src/simulation/m_muscl.fpp +++ b/src/simulation/m_muscl.fpp @@ -7,37 +7,45 @@ !> @brief MUSCL reconstruction with interface sharpening for contact-preserving advection module m_muscl - use m_derived_types - use m_global_parameters - use m_variables_conversion + use m_derived_types !< Definitions of the derived types + + use m_global_parameters !< Definitions of the global parameters + + use m_variables_conversion !< State variables type conversion procedures + #ifdef MFC_OpenACC use openacc #endif use m_mpi_proxy + use m_helper - private; public :: s_initialize_muscl_module, s_muscl, s_finalize_muscl_module, s_interface_compression + private; public :: s_initialize_muscl_module, & + s_muscl, & + s_finalize_muscl_module, & + s_interface_compression integer :: v_size $:GPU_DECLARE(create='[v_size]') type(int_bounds_info) :: is1_muscl, is2_muscl, is3_muscl - $:GPU_DECLARE(create='[is1_muscl, is2_muscl, is3_muscl]') - - !> @name The cell-average variables that will be MUSCL-reconstructed. Formerly, they are stored in v_vf. However, they are - !! transferred to v_rs_wsL and v_rs_wsR as to be reshaped (RS) and/or characteristically decomposed. The reshaping allows the - !! muscl procedure to be independent of the coordinate direction of the reconstruction. Lastly, notice that the left (L) and - !! right (R) results of the characteristic decomposition are stored in custom-constructed muscl- stencils (WS) that are annexed - !! to each position of a given scalar field. + $:GPU_DECLARE(create='[is1_muscl,is2_muscl,is3_muscl]') + + !> @name The cell-average variables that will be MUSCL-reconstructed. Formerly, they + !! are stored in v_vf. However, they are transferred to v_rs_wsL and v_rs_wsR + !! as to be reshaped (RS) and/or characteristically decomposed. The reshaping + !! allows the muscl procedure to be independent of the coordinate direction of + !! the reconstruction. Lastly, notice that the left (L) and right (R) results + !! of the characteristic decomposition are stored in custom-constructed muscl- + !! stencils (WS) that are annexed to each position of a given scalar field. !> @{ - real(wp), allocatable, dimension(:,:,:,:) :: v_rs_ws_x_muscl, v_rs_ws_y_muscl, v_rs_ws_z_muscl + real(wp), allocatable, dimension(:, :, :, :) :: v_rs_ws_x_muscl, v_rs_ws_y_muscl, v_rs_ws_z_muscl !> @} - $:GPU_DECLARE(create='[v_rs_ws_x_muscl, v_rs_ws_y_muscl, v_rs_ws_z_muscl]') + $:GPU_DECLARE(create='[v_rs_ws_x_muscl,v_rs_ws_y_muscl,v_rs_ws_z_muscl]') contains - !> Allocate and initialize MUSCL reconstruction working arrays subroutine s_initialize_muscl_module() ! Initializing in x-direction @@ -45,7 +53,7 @@ contains if (n == 0) then is2_muscl%beg = 0 else - is2_muscl%beg = -buff_size + is2_muscl%beg = -buff_size; end if is2_muscl%end = n - is2_muscl%beg @@ -58,8 +66,8 @@ contains is3_muscl%end = p - is3_muscl%beg - @:ALLOCATE(v_rs_ws_x_muscl(is1_muscl%beg:is1_muscl%end, is2_muscl%beg:is2_muscl%end, is3_muscl%beg:is3_muscl%end, & - & 1:sys_size)) + @:ALLOCATE(v_rs_ws_x_muscl(is1_muscl%beg:is1_muscl%end, & + is2_muscl%beg:is2_muscl%end, is3_muscl%beg:is3_muscl%end, 1:sys_size)) if (n == 0) return @@ -75,8 +83,8 @@ contains is3_muscl%end = p - is3_muscl%beg - @:ALLOCATE(v_rs_ws_y_muscl(is2_muscl%beg:is2_muscl%end, is1_muscl%beg:is1_muscl%end, is3_muscl%beg:is3_muscl%end, & - & 1:sys_size)) + @:ALLOCATE(v_rs_ws_y_muscl(is2_muscl%beg:is2_muscl%end, & + is1_muscl%beg:is1_muscl%end, is3_muscl%beg:is3_muscl%end, 1:sys_size)) if (p == 0) return @@ -85,29 +93,31 @@ contains is1_muscl%beg = -buff_size; is1_muscl%end = m - is1_muscl%beg is3_muscl%beg = -buff_size; is3_muscl%end = p - is3_muscl%beg - @:ALLOCATE(v_rs_ws_z_muscl(is3_muscl%beg:is3_muscl%end, is2_muscl%beg:is2_muscl%end, is1_muscl%beg:is1_muscl%end, & - & 1:sys_size)) + @:ALLOCATE(v_rs_ws_z_muscl(is3_muscl%beg:is3_muscl%end, & + is2_muscl%beg:is2_muscl%end, is1_muscl%beg:is1_muscl%end, 1:sys_size)) end subroutine s_initialize_muscl_module - !> Perform MUSCL reconstruction of left and right cell-boundary values from cell-averaged variables - subroutine s_muscl(v_vf, vL_rs_vf_x, vL_rs_vf_y, vL_rs_vf_z, vR_rs_vf_x, vR_rs_vf_y, vR_rs_vf_z, muscl_dir, is1_muscl_d, & - - & is2_muscl_d, is3_muscl_d) - - type(scalar_field), dimension(1:), intent(in) :: v_vf - real(wp), dimension(idwbuff(1)%beg:,idwbuff(2)%beg:,idwbuff(3)%beg:,1:), intent(inout) :: vL_rs_vf_x, vL_rs_vf_y, & - & vL_rs_vf_z, vR_rs_vf_x, vR_rs_vf_y, vR_rs_vf_z - integer, intent(in) :: muscl_dir + !> @brief Performs MUSCL reconstruction of left and right cell-boundary values from cell-averaged variables. + subroutine s_muscl(v_vf, vL_rs_vf_x, vL_rs_vf_y, vL_rs_vf_z, vR_rs_vf_x, vR_rs_vf_y, vR_rs_vf_z, & + muscl_dir, & + is1_muscl_d, is2_muscl_d, is3_muscl_d) + + type(scalar_field), dimension(1:), intent(in) :: v_vf + real(wp), dimension(idwbuff(1)%beg:, idwbuff(2)%beg:, idwbuff(3)%beg:, 1:), intent(inout) :: & + vL_rs_vf_x, vL_rs_vf_y, & + vL_rs_vf_z, vR_rs_vf_x, & + vR_rs_vf_y, vR_rs_vf_z + integer, intent(in) :: muscl_dir type(int_bounds_info), intent(in) :: is1_muscl_d, is2_muscl_d, is3_muscl_d - integer :: j, k, l, i - real(wp) :: slopeL, slopeR, slope + integer :: j, k, l, i + real(wp) :: slopeL, slopeR, slope is1_muscl = is1_muscl_d is2_muscl = is2_muscl_d is3_muscl = is3_muscl_d - $:GPU_UPDATE(device='[is1_muscl, is2_muscl, is3_muscl]') + $:GPU_UPDATE(device='[is1_muscl,is2_muscl,is3_muscl]') if (muscl_order /= 1 .or. dummy) then call s_initialize_muscl(v_vf, muscl_dir) @@ -128,7 +138,7 @@ contains end do $:END_GPU_PARALLEL_LOOP() else if (muscl_dir == 2) then - $:GPU_PARALLEL_LOOP(private='[i, j, k, l]', collapse=4) + $:GPU_PARALLEL_LOOP(private='[i,j,k,l]', collapse=4) do i = 1, ubound(v_vf, 1) do l = is3_muscl%beg, is3_muscl%end do k = is2_muscl%beg, is2_muscl%end @@ -141,7 +151,7 @@ contains end do $:END_GPU_PARALLEL_LOOP() else if (muscl_dir == 3) then - $:GPU_PARALLEL_LOOP(private='[i, j, k, l]', collapse=4) + $:GPU_PARALLEL_LOOP(private='[i,j,k,l]', collapse=4) do i = 1, ubound(v_vf, 1) do l = is3_muscl%beg, is3_muscl%end do k = is2_muscl%beg, is2_muscl%end @@ -160,47 +170,52 @@ contains ! MUSCL Reconstruction #:for MUSCL_DIR, XYZ in [(1, 'x'), (2, 'y'), (3, 'z')] if (muscl_dir == ${MUSCL_DIR}$) then - $:GPU_PARALLEL_LOOP(collapse=4,private='[i, j, k, l, slopeL, slopeR, slope]') + $:GPU_PARALLEL_LOOP(collapse=4,private='[i,j,k,l,slopeL,slopeR,slope]') do l = is3_muscl%beg, is3_muscl%end do k = is2_muscl%beg, is2_muscl%end do j = is1_muscl%beg, is1_muscl%end do i = 1, v_size - slopeL = v_rs_ws_${XYZ}$_muscl(j + 1, k, l, i) - v_rs_ws_${XYZ}$_muscl(j, k, l, i) - slopeR = v_rs_ws_${XYZ}$_muscl(j, k, l, i) - v_rs_ws_${XYZ}$_muscl(j - 1, k, l, i) + + slopeL = v_rs_ws_${XYZ}$_muscl(j + 1, k, l, i) - & + v_rs_ws_${XYZ}$_muscl(j, k, l, i) + slopeR = v_rs_ws_${XYZ}$_muscl(j, k, l, i) - & + v_rs_ws_${XYZ}$_muscl(j - 1, k, l, i) slope = 0._wp - if (muscl_lim == 1) then ! minmod + if (muscl_lim == 1) then ! minmod if (slopeL*slopeR > 1e-9_wp) then slope = min(abs(slopeL), abs(slopeR)) end if if (slopeL < 0._wp) slope = -slope - else if (muscl_lim == 2) then ! MC + elseif (muscl_lim == 2) then ! MC if (slopeL*slopeR > 1e-9_wp) then slope = min(2._wp*abs(slopeL), 2._wp*abs(slopeR)) slope = min(slope, 5e-1_wp*(abs(slopeL) + abs(slopeR))) end if if (slopeL < 0._wp) slope = -slope - else if (muscl_lim == 3) then ! Van Albada - if (abs(slopeL) > 1e-6_wp .and. abs(slopeR) > 1e-6_wp .and. abs(slopeL + slopeR) & - & > 1e-6_wp .and. slopeL*slopeR > 1e-6_wp) then + elseif (muscl_lim == 3) then ! Van Albada + if (abs(slopeL) > 1e-6_wp .and. abs(slopeR) > 1e-6_wp .and. & + abs(slopeL + slopeR) > 1e-6_wp .and. slopeL*slopeR > 1e-6_wp) then slope = ((slopeL + slopeR)*slopeL*slopeR)/(slopeL**2._wp + slopeR**2._wp) end if - else if (muscl_lim == 4) then ! Van Leer + elseif (muscl_lim == 4) then ! Van Leer if (abs(slopeL + slopeR) > 1.e-6_wp .and. slopeL*slopeR > 1.e-6_wp) then slope = 2._wp*slopeL*slopeR/(slopeL + slopeR) end if - else if (muscl_lim == 5) then ! SUPERBEE + elseif (muscl_lim == 5) then ! SUPERBEE if (slopeL*slopeR > 1e-6_wp) then - slope = -1._wp*min(-min(2._wp*abs(slopeL), abs(slopeR)), -min(abs(slopeL), & - & 2._wp*abs(slopeR))) + slope = -1._wp*min(-min(2._wp*abs(slopeL), abs(slopeR)), -min(abs(slopeL), 2._wp*abs(slopeR))) end if end if ! reconstruct from left side - vL_rs_vf_${XYZ}$ (j, k, l, i) = v_rs_ws_${XYZ}$_muscl(j, k, l, i) - (5.e-1_wp*slope) + vL_rs_vf_${XYZ}$ (j, k, l, i) = & + v_rs_ws_${XYZ}$_muscl(j, k, l, i) - (5.e-1_wp*slope) ! reconstruct from the right side - vR_rs_vf_${XYZ}$ (j, k, l, i) = v_rs_ws_${XYZ}$_muscl(j, k, l, i) + (5.e-1_wp*slope) + vR_rs_vf_${XYZ}$ (j, k, l, i) = & + v_rs_ws_${XYZ}$_muscl(j, k, l, i) + (5.e-1_wp*slope) + end do end do end do @@ -210,38 +225,45 @@ contains #:endfor end if - if (int_comp) then - call s_interface_compression(vL_rs_vf_x, vL_rs_vf_y, vL_rs_vf_z, vR_rs_vf_x, vR_rs_vf_y, vR_rs_vf_z, muscl_dir, & - & is1_muscl_d, is2_muscl_d, is3_muscl_d) + if (int_comp .and. v_size >= advxe) then + call s_interface_compression(vL_rs_vf_x, vL_rs_vf_y, vL_rs_vf_z, & + vR_rs_vf_x, vR_rs_vf_y, vR_rs_vf_z, & + muscl_dir, is1_muscl_d, is2_muscl_d, is3_muscl_d) end if end subroutine s_muscl - !> Apply THINC interface-compression to sharpen volume-fraction reconstructions at material interfaces - subroutine s_interface_compression(vL_rs_vf_x, vL_rs_vf_y, vL_rs_vf_z, vR_rs_vf_x, vR_rs_vf_y, vR_rs_vf_z, muscl_dir, & + !> @brief Applies THINC interface-compression to sharpen volume-fraction reconstructions at material interfaces. + subroutine s_interface_compression(vL_rs_vf_x, vL_rs_vf_y, vL_rs_vf_z, vR_rs_vf_x, vR_rs_vf_y, vR_rs_vf_z, & + muscl_dir, & + is1_muscl_d, is2_muscl_d, is3_muscl_d) - & is1_muscl_d, is2_muscl_d, is3_muscl_d) - - real(wp), dimension(idwbuff(1)%beg:,idwbuff(2)%beg:,idwbuff(3)%beg:,1:), intent(inout) :: vL_rs_vf_x, vL_rs_vf_y, & - & vL_rs_vf_z, vR_rs_vf_x, vR_rs_vf_y, vR_rs_vf_z - integer, intent(in) :: muscl_dir + real(wp), dimension(idwbuff(1)%beg:, idwbuff(2)%beg:, idwbuff(3)%beg:, 1:), intent(inout) :: & + vL_rs_vf_x, vL_rs_vf_y, & + vL_rs_vf_z, vR_rs_vf_x, & + vR_rs_vf_y, vR_rs_vf_z + integer, intent(in) :: muscl_dir type(int_bounds_info), intent(in) :: is1_muscl_d, is2_muscl_d, is3_muscl_d - integer :: j, k, l - real(wp) :: aCL, aCR, aC, aTHINC, qmin, qmax, A, B, C, sign, moncon + + integer :: j, k, l + + real(wp) :: aCL, aCR, aC, aTHINC, qmin, qmax, A, B, C, sign, moncon #:for MUSCL_DIR, XYZ in [(1, 'x'), (2, 'y'), (3, 'z')] if (muscl_dir == ${MUSCL_DIR}$) then - $:GPU_PARALLEL_LOOP(collapse=3,private='[j, k, l, aCL, aC, aCR, aTHINC, moncon, sign, qmin, qmax]') + + $:GPU_PARALLEL_LOOP(collapse=3,private='[j,k,l,aCL,aC,aCR,aTHINC,moncon,sign,qmin,qmax]') do l = is3_muscl%beg, is3_muscl%end do k = is2_muscl%beg, is2_muscl%end do j = is1_muscl%beg, is1_muscl%end + aCL = v_rs_ws_${XYZ}$_muscl(j - 1, k, l, advxb) aC = v_rs_ws_${XYZ}$_muscl(j, k, l, advxb) aCR = v_rs_ws_${XYZ}$_muscl(j + 1, k, l, advxb) moncon = (aCR - aC)*(aC - aCL) - if (aC >= ic_eps .and. aC <= 1._wp - ic_eps .and. moncon > moncon_cutoff) then ! Interface cell + if (aC >= ic_eps .and. aC <= 1._wp - ic_eps .and. moncon > moncon_cutoff) then ! Interface cell if (aCR - aCL > 0._wp) then sign = 1._wp @@ -260,10 +282,10 @@ contains aTHINC = qmin + 5e-1_wp*qmax*(1._wp + sign*A) if (aTHINC < ic_eps) aTHINC = ic_eps if (aTHINC > 1 - ic_eps) aTHINC = 1 - ic_eps - vL_rs_vf_${XYZ}$ (j, k, l, contxb) = vL_rs_vf_${XYZ}$ (j, k, l, contxb)/vL_rs_vf_${XYZ}$ (j, k, & - & l, advxb)*aTHINC - vL_rs_vf_${XYZ}$ (j, k, l, contxe) = vL_rs_vf_${XYZ}$ (j, k, l, & - & contxe)/(1._wp - vL_rs_vf_${XYZ}$ (j, k, l, advxb))*(1._wp - aTHINC) + vL_rs_vf_${XYZ}$ (j, k, l, contxb) = vL_rs_vf_${XYZ}$ (j, k, l, contxb)/ & + vL_rs_vf_${XYZ}$ (j, k, l, advxb)*aTHINC + vL_rs_vf_${XYZ}$ (j, k, l, contxe) = vL_rs_vf_${XYZ}$ (j, k, l, contxe)/ & + (1._wp - vL_rs_vf_${XYZ}$ (j, k, l, advxb))*(1._wp - aTHINC) vL_rs_vf_${XYZ}$ (j, k, l, advxb) = aTHINC vL_rs_vf_${XYZ}$ (j, k, l, advxe) = 1 - aTHINC @@ -271,13 +293,15 @@ contains aTHINC = qmin + 5e-1_wp*qmax*(1._wp + sign*(tanh(ic_beta) + A)/(1._wp + A*tanh(ic_beta))) if (aTHINC < ic_eps) aTHINC = ic_eps if (aTHINC > 1 - ic_eps) aTHINC = 1 - ic_eps - vR_rs_vf_${XYZ}$ (j, k, l, contxb) = vL_rs_vf_${XYZ}$ (j, k, l, contxb)/vL_rs_vf_${XYZ}$ (j, k, & - & l, advxb)*aTHINC - vR_rs_vf_${XYZ}$ (j, k, l, contxe) = vL_rs_vf_${XYZ}$ (j, k, l, & - & contxe)/(1._wp - vL_rs_vf_${XYZ}$ (j, k, l, advxb))*(1._wp - aTHINC) + vR_rs_vf_${XYZ}$ (j, k, l, contxb) = vL_rs_vf_${XYZ}$ (j, k, l, contxb)/ & + vL_rs_vf_${XYZ}$ (j, k, l, advxb)*aTHINC + vR_rs_vf_${XYZ}$ (j, k, l, contxe) = vL_rs_vf_${XYZ}$ (j, k, l, contxe)/ & + (1._wp - vL_rs_vf_${XYZ}$ (j, k, l, advxb))*(1._wp - aTHINC) vR_rs_vf_${XYZ}$ (j, k, l, advxb) = aTHINC vR_rs_vf_${XYZ}$ (j, k, l, advxe) = 1 - aTHINC + end if + end do end do end do @@ -287,19 +311,24 @@ contains end subroutine s_interface_compression - !> Reshape cell-averaged variable data into direction-local work arrays for MUSCL reconstruction + !> @brief Reshapes cell-averaged variable data into direction-local work arrays for MUSCL reconstruction. subroutine s_initialize_muscl(v_vf, muscl_dir) type(scalar_field), dimension(:), intent(in) :: v_vf - integer, intent(in) :: muscl_dir - integer :: j, k, l, q !< Generic loop iterators - ! Determine MUSCL-reconstructed variables and map coordinate directions + integer, intent(in) :: muscl_dir + integer :: j, k, l, q !< Generic loop iterators + + ! Determining the number of cell-average variables which will be + ! muscl-reconstructed and mapping their indical bounds in the x-, + ! y- and z-directions to those in the s1-, s2- and s3-directions + ! as to reshape the inputted data in the coordinate direction of + ! the muscl reconstruction v_size = ubound(v_vf, 1) $:GPU_UPDATE(device='[v_size]') if (muscl_dir == 1) then - $:GPU_PARALLEL_LOOP(private='[j, k, l, q]', collapse=4) + $:GPU_PARALLEL_LOOP(private='[j,k,l,q]', collapse=4) do j = 1, v_size do q = is3_muscl%beg, is3_muscl%end do l = is2_muscl%beg, is2_muscl%end @@ -316,7 +345,7 @@ contains if (n == 0) return if (muscl_dir == 2) then - $:GPU_PARALLEL_LOOP(private='[j, k, l, q]', collapse=4) + $:GPU_PARALLEL_LOOP(private='[j,k,l,q]', collapse=4) do j = 1, v_size do q = is3_muscl%beg, is3_muscl%end do l = is2_muscl%beg, is2_muscl%end @@ -332,7 +361,7 @@ contains ! Reshaping/Projecting onto Characteristic Fields in z-direction if (p == 0) return if (muscl_dir == 3) then - $:GPU_PARALLEL_LOOP(private='[j, k, l, q]', collapse=4) + $:GPU_PARALLEL_LOOP(private='[j,k,l,q]', collapse=4) do j = 1, v_size do q = is3_muscl%beg, is3_muscl%end do l = is2_muscl%beg, is2_muscl%end @@ -347,7 +376,7 @@ contains end subroutine s_initialize_muscl - !> Finalize the MUSCL module + !> @brief Deallocates the MUSCL direction-local work arrays. subroutine s_finalize_muscl_module() @:DEALLOCATE(v_rs_ws_x_muscl) @@ -361,5 +390,4 @@ contains @:DEALLOCATE(v_rs_ws_z_muscl) end subroutine s_finalize_muscl_module - end module m_muscl diff --git a/src/simulation/m_pressure_relaxation.fpp b/src/simulation/m_pressure_relaxation.fpp index 7786ce4afe..69689de06c 100644 --- a/src/simulation/m_pressure_relaxation.fpp +++ b/src/simulation/m_pressure_relaxation.fpp @@ -5,19 +5,19 @@ #:include 'case.fpp' #:include 'macros.fpp' -!> @brief Pressure relaxation for the six-equation multi-component model via Newton--Raphson equilibration and volume-fraction -!! correction +!> @brief Pressure relaxation for the six-equation multi-component model via Newton--Raphson equilibration and volume-fraction correction module m_pressure_relaxation - use m_derived_types - use m_global_parameters + use m_derived_types !< Definitions of the derived types + use m_global_parameters !< Definitions of the global parameters implicit none - private; public :: s_pressure_relaxation_procedure, s_initialize_pressure_relaxation_module, & - & s_finalize_pressure_relaxation_module + private; public :: s_pressure_relaxation_procedure, & + s_initialize_pressure_relaxation_module, & + s_finalize_pressure_relaxation_module - real(wp), allocatable, dimension(:,:) :: Res_pr + real(wp), allocatable, dimension(:, :) :: Res_pr $:GPU_DECLARE(create='[Res_pr]') contains @@ -49,12 +49,13 @@ contains end subroutine s_finalize_pressure_relaxation_module !> The main pressure relaxation procedure + !! @param q_cons_vf Cell-average conservative variables subroutine s_pressure_relaxation_procedure(q_cons_vf) type(scalar_field), dimension(sys_size), intent(inout) :: q_cons_vf - integer :: j, k, l + integer :: j, k, l - $:GPU_PARALLEL_LOOP(private='[j, k, l]', collapse=3) + $:GPU_PARALLEL_LOOP(private='[j,k,l]', collapse=3) do l = 0, p do k = 0, n do j = 0, m @@ -68,11 +69,10 @@ contains !> Process pressure relaxation for a single cell subroutine s_relax_cell_pressure(q_cons_vf, j, k, l) - $:GPU_ROUTINE(parallelism='[seq]') type(scalar_field), dimension(sys_size), intent(inout) :: q_cons_vf - integer, intent(in) :: j, k, l + integer, intent(in) :: j, k, l ! Volume fraction correction if (mpp_lim) call s_correct_volume_fractions(q_cons_vf, j, k, l) @@ -89,12 +89,11 @@ contains !> Check if pressure relaxation is needed for this cell logical function s_needs_pressure_relaxation(q_cons_vf, j, k, l) - $:GPU_ROUTINE(parallelism='[seq]') type(scalar_field), dimension(sys_size), intent(in) :: q_cons_vf - integer, intent(in) :: j, k, l - integer :: i + integer, intent(in) :: j, k, l + integer :: i s_needs_pressure_relaxation = .true. $:GPU_LOOP(parallelism='[seq]') @@ -108,23 +107,24 @@ contains !> Correct volume fractions to physical bounds subroutine s_correct_volume_fractions(q_cons_vf, j, k, l) - $:GPU_ROUTINE(parallelism='[seq]') type(scalar_field), dimension(sys_size), intent(inout) :: q_cons_vf - integer, intent(in) :: j, k, l - real(wp) :: sum_alpha - integer :: i + integer, intent(in) :: j, k, l + real(wp) :: sum_alpha + integer :: i sum_alpha = 0._wp $:GPU_LOOP(parallelism='[seq]') do i = 1, num_fluids - if ((q_cons_vf(i + contxb - 1)%sf(j, k, l) < 0._wp) .or. (q_cons_vf(i + advxb - 1)%sf(j, k, l) < 0._wp)) then + if ((q_cons_vf(i + contxb - 1)%sf(j, k, l) < 0._wp) .or. & + (q_cons_vf(i + advxb - 1)%sf(j, k, l) < 0._wp)) then q_cons_vf(i + contxb - 1)%sf(j, k, l) = 0._wp q_cons_vf(i + advxb - 1)%sf(j, k, l) = 0._wp q_cons_vf(i + intxb - 1)%sf(j, k, l) = 0._wp end if - if (q_cons_vf(i + advxb - 1)%sf(j, k, l) > 1._wp) q_cons_vf(i + advxb - 1)%sf(j, k, l) = 1._wp + if (q_cons_vf(i + advxb - 1)%sf(j, k, l) > 1._wp) & + q_cons_vf(i + advxb - 1)%sf(j, k, l) = 1._wp sum_alpha = sum_alpha + q_cons_vf(i + advxb - 1)%sf(j, k, l) end do @@ -137,30 +137,30 @@ contains !> Main pressure equilibration using Newton-Raphson subroutine s_equilibrate_pressure(q_cons_vf, j, k, l) - $:GPU_ROUTINE(parallelism='[seq]') type(scalar_field), dimension(sys_size), intent(inout) :: q_cons_vf - integer, intent(in) :: j, k, l - real(wp) :: pres_relax, f_pres, df_pres + integer, intent(in) :: j, k, l + + real(wp) :: pres_relax, f_pres, df_pres #:if not MFC_CASE_OPTIMIZATION and USING_AMD real(wp), dimension(3) :: pres_K_init, rho_K_s #:else real(wp), dimension(num_fluids) :: pres_K_init, rho_K_s #:endif integer, parameter :: MAX_ITER = 50 - ! Pressure relaxation convergence tolerance real(wp), parameter :: TOLERANCE = 1.e-10_wp - integer :: iter, i + integer :: iter, i ! Initialize pressures pres_relax = 0._wp $:GPU_LOOP(parallelism='[seq]') do i = 1, num_fluids if (q_cons_vf(i + advxb - 1)%sf(j, k, l) > sgm_eps) then - pres_K_init(i) = (q_cons_vf(i + intxb - 1)%sf(j, k, l)/q_cons_vf(i + advxb - 1)%sf(j, k, l) - pi_infs(i))/gammas(i) - if (pres_K_init(i) <= -(1._wp - 1.e-8_wp)*ps_inf(i) + 1.e-8_wp) pres_K_init(i) = -(1._wp - 1.e-8_wp)*ps_inf(i) & - & + 1.e-8_wp + pres_K_init(i) = (q_cons_vf(i + intxb - 1)%sf(j, k, l)/ & + q_cons_vf(i + advxb - 1)%sf(j, k, l) - pi_infs(i))/gammas(i) + if (pres_K_init(i) <= -(1._wp - 1.e-8_wp)*ps_inf(i) + 1.e-8_wp) & + pres_K_init(i) = -(1._wp - 1.e-8_wp)*ps_inf(i) + 1.e-8_wp else pres_K_init(i) = 0._wp end if @@ -177,8 +177,8 @@ contains ! Enforce pressure bounds do i = 1, num_fluids - if (pres_relax <= -(1._wp - 1.e-8_wp)*ps_inf(i) + 1.e-8_wp) pres_relax = -(1._wp - 1.e-8_wp)*ps_inf(i) & - & + 1.e-8_wp + if (pres_relax <= -(1._wp - 1.e-8_wp)*ps_inf(i) + 1.e-8_wp) & + pres_relax = -(1._wp - 1.e-8_wp)*ps_inf(i) + 1.e-8_wp end do ! Newton-Raphson step @@ -187,11 +187,13 @@ contains $:GPU_LOOP(parallelism='[seq]') do i = 1, num_fluids if (q_cons_vf(i + advxb - 1)%sf(j, k, l) > sgm_eps) then - ! Isentropic relation: rho = rho0 * (p/p0)^(1/gamma), Saurel et al. JFM (2009) - rho_K_s(i) = q_cons_vf(i + contxb - 1)%sf(j, k, l)/max(q_cons_vf(i + advxb - 1)%sf(j, k, l), & - & sgm_eps)*((pres_relax + ps_inf(i))/(pres_K_init(i) + ps_inf(i)))**(1._wp/gs_min(i)) + rho_K_s(i) = q_cons_vf(i + contxb - 1)%sf(j, k, l)/ & + max(q_cons_vf(i + advxb - 1)%sf(j, k, l), sgm_eps) & + *((pres_relax + ps_inf(i))/(pres_K_init(i) + & + ps_inf(i)))**(1._wp/gs_min(i)) f_pres = f_pres + q_cons_vf(i + contxb - 1)%sf(j, k, l)/rho_K_s(i) - df_pres = df_pres - q_cons_vf(i + contxb - 1)%sf(j, k, l)/(gs_min(i)*rho_K_s(i)*(pres_relax + ps_inf(i))) + df_pres = df_pres - q_cons_vf(i + contxb - 1)%sf(j, k, l) & + /(gs_min(i)*rho_K_s(i)*(pres_relax + ps_inf(i))) end if end do end if @@ -200,27 +202,26 @@ contains ! Update volume fractions $:GPU_LOOP(parallelism='[seq]') do i = 1, num_fluids - if (q_cons_vf(i + advxb - 1)%sf(j, k, l) > sgm_eps) q_cons_vf(i + advxb - 1)%sf(j, k, & - & l) = q_cons_vf(i + contxb - 1)%sf(j, k, l)/rho_K_s(i) + if (q_cons_vf(i + advxb - 1)%sf(j, k, l) > sgm_eps) & + q_cons_vf(i + advxb - 1)%sf(j, k, l) = q_cons_vf(i + contxb - 1)%sf(j, k, l)/rho_K_s(i) end do end subroutine s_equilibrate_pressure !> Correct internal energies using equilibrated pressure subroutine s_correct_internal_energies(q_cons_vf, j, k, l) - $:GPU_ROUTINE(parallelism='[seq]') type(scalar_field), dimension(sys_size), intent(inout) :: q_cons_vf - integer, intent(in) :: j, k, l + integer, intent(in) :: j, k, l #:if not MFC_CASE_OPTIMIZATION and USING_AMD real(wp), dimension(2) :: alpha_rho, alpha #:else real(wp), dimension(num_fluids) :: alpha_rho, alpha #:endif - real(wp) :: rho, dyn_pres, gamma, pi_inf, pres_relax, sum_alpha + real(wp) :: rho, dyn_pres, gamma, pi_inf, pres_relax, sum_alpha real(wp), dimension(2) :: Re - integer :: i, q + integer :: i, q $:GPU_LOOP(parallelism='[seq]') do i = 1, num_fluids @@ -290,14 +291,16 @@ contains dyn_pres = 0._wp $:GPU_LOOP(parallelism='[seq]') do i = momxb, momxe - dyn_pres = dyn_pres + 5.e-1_wp*q_cons_vf(i)%sf(j, k, l)*q_cons_vf(i)%sf(j, k, l)/max(rho, sgm_eps) + dyn_pres = dyn_pres + 5.e-1_wp*q_cons_vf(i)%sf(j, k, l)* & + q_cons_vf(i)%sf(j, k, l)/max(rho, sgm_eps) end do pres_relax = (q_cons_vf(E_idx)%sf(j, k, l) - dyn_pres - pi_inf)/gamma $:GPU_LOOP(parallelism='[seq]') do i = 1, num_fluids - q_cons_vf(i + intxb - 1)%sf(j, k, l) = q_cons_vf(i + advxb - 1)%sf(j, k, l)*(gammas(i)*pres_relax + pi_infs(i)) + q_cons_vf(i + intxb - 1)%sf(j, k, l) = & + q_cons_vf(i + advxb - 1)%sf(j, k, l)*(gammas(i)*pres_relax + pi_infs(i)) end do end subroutine s_correct_internal_energies diff --git a/src/simulation/m_qbmm.fpp b/src/simulation/m_qbmm.fpp index e32fd92954..d081b8f83e 100644 --- a/src/simulation/m_qbmm.fpp +++ b/src/simulation/m_qbmm.fpp @@ -8,18 +8,23 @@ !> @brief Quadrature-based moment methods (QBMM) for polydisperse bubble moment inversion and transport module m_qbmm - use m_derived_types - use m_global_parameters - use m_mpi_proxy - use m_variables_conversion - use m_helper_basic + use m_derived_types !< Definitions of the derived types + + use m_global_parameters !< Definitions of the global parameters + + use m_mpi_proxy !< Message passing interface (MPI) module proxy + + use m_variables_conversion !< State variables type conversion procedures + + use m_helper_basic !< Functions to compare floating point numbers + use m_helper implicit none private; public :: s_initialize_qbmm_module, s_mom_inv, s_coeff, s_compute_qbmm_rhs - real(wp), allocatable, dimension(:,:,:,:,:) :: momrhs + real(wp), allocatable, dimension(:, :, :, :, :) :: momrhs $:GPU_DECLARE(create='[momrhs]') #:if MFC_CASE_OPTIMIZATION @@ -30,20 +35,21 @@ module m_qbmm #:endif type(int_bounds_info) :: is1_qbmm, is2_qbmm, is3_qbmm - $:GPU_DECLARE(create='[is1_qbmm, is2_qbmm, is3_qbmm]') + $:GPU_DECLARE(create='[is1_qbmm,is2_qbmm,is3_qbmm]') - integer, allocatable, dimension(:) :: bubrs_qbmm - integer, allocatable, dimension(:,:) :: bubmoms - $:GPU_DECLARE(create='[bubrs_qbmm, bubmoms]') + integer, allocatable, dimension(:) :: bubrs_qbmm + integer, allocatable, dimension(:, :) :: bubmoms + $:GPU_DECLARE(create='[bubrs_qbmm,bubmoms]') contains - !> Initialize the QBMM module + !> @brief Allocates and initializes moment coefficient arrays for the QBMM module. impure subroutine s_initialize_qbmm_module integer :: i1, i2, q, i, j #:if not MFC_CASE_OPTIMIZATION + if (bubble_model == 2) then ! Keller-Miksis without viscosity/surface tension nterms = 32 @@ -54,330 +60,336 @@ contains $:GPU_ENTER_DATA(copyin='[nterms]') $:GPU_UPDATE(device='[nterms]') + #:endif @:ALLOCATE(momrhs(1:3, 0:2, 0:2, 1:nterms, 1:nb)) momrhs = 0._wp - ! Assigns the required RHS moments for moment transport equations The rhs%(:,3) is only to be used for R0 quadrature, not - ! for computing X/Y indices Accounts for different governing equations in polytropic and non-polytropic models + ! Assigns the required RHS moments for moment transport equations + ! The rhs%(:,3) is only to be used for R0 quadrature, not for computing X/Y indices + ! Accounts for different governing equations in polytropic and non-polytropic models if (.not. polytropic) then do q = 1, nb do i1 = 0, 2; do i2 = 0, 2 - if ((i1 + i2) <= 2) then - if (bubble_model == 3) then - momrhs(1, i1, i2, 1, q) = -1._wp + i1 - momrhs(2, i1, i2, 1, q) = -1._wp + i2 - momrhs(3, i1, i2, 1, q) = 0._wp + if ((i1 + i2) <= 2) then + if (bubble_model == 3) then + momrhs(1, i1, i2, 1, q) = -1._wp + i1 + momrhs(2, i1, i2, 1, q) = -1._wp + i2 + momrhs(3, i1, i2, 1, q) = 0._wp + + momrhs(1, i1, i2, 2, q) = -1._wp + i1 + momrhs(2, i1, i2, 2, q) = 1._wp + i2 + momrhs(3, i1, i2, 2, q) = 0._wp + + momrhs(1, i1, i2, 3, q) = -1._wp + i1 + momrhs(2, i1, i2, 3, q) = -1._wp + i2 + momrhs(3, i1, i2, 3, q) = 0._wp + + momrhs(1, i1, i2, 4, q) = -1._wp + i1 + momrhs(2, i1, i2, 4, q) = 1._wp + i2 + momrhs(3, i1, i2, 4, q) = 0._wp + + if (.not. f_is_default(Re_inv)) then + ! add viscosity + momrhs(1, i1, i2, 5, q) = -2._wp + i1 + momrhs(2, i1, i2, 5, q) = i2 + momrhs(3, i1, i2, 5, q) = 0._wp + end if + + if (.not. f_is_default(Web)) then + ! add surface tension + momrhs(1, i1, i2, 6, q) = -2._wp + i1 + momrhs(2, i1, i2, 6, q) = -1._wp + i2 + momrhs(3, i1, i2, 6, q) = 0._wp + end if - momrhs(1, i1, i2, 2, q) = -1._wp + i1 - momrhs(2, i1, i2, 2, q) = 1._wp + i2 - momrhs(3, i1, i2, 2, q) = 0._wp + momrhs(1, i1, i2, 7, q) = -1._wp + i1 + momrhs(2, i1, i2, 7, q) = -1._wp + i2 + momrhs(3, i1, i2, 7, q) = 0._wp - momrhs(1, i1, i2, 3, q) = -1._wp + i1 - momrhs(2, i1, i2, 3, q) = -1._wp + i2 - momrhs(3, i1, i2, 3, q) = 0._wp + else if (bubble_model == 2) then + ! KM with approximation of 1/(1-V/C) = 1+V/C + momrhs(1, i1, i2, 1, q) = -1._wp + i1 + momrhs(2, i1, i2, 1, q) = 1._wp + i2 + momrhs(3, i1, i2, 1, q) = 0._wp - momrhs(1, i1, i2, 4, q) = -1._wp + i1 - momrhs(2, i1, i2, 4, q) = 1._wp + i2 - momrhs(3, i1, i2, 4, q) = 0._wp + momrhs(1, i1, i2, 2, q) = -1._wp + i1 + momrhs(2, i1, i2, 2, q) = 2._wp + i2 + momrhs(3, i1, i2, 2, q) = 0._wp - if (.not. f_is_default(Re_inv)) then - ! add viscosity - momrhs(1, i1, i2, 5, q) = -2._wp + i1 + momrhs(1, i1, i2, 3, q) = -1._wp + i1 + momrhs(2, i1, i2, 3, q) = 3._wp + i2 + momrhs(3, i1, i2, 3, q) = 0._wp + + momrhs(1, i1, i2, 4, q) = -1._wp + i1 + momrhs(2, i1, i2, 4, q) = -1._wp + i2 + momrhs(3, i1, i2, 4, q) = 0._wp + + momrhs(1, i1, i2, 5, q) = -1._wp + i1 momrhs(2, i1, i2, 5, q) = i2 momrhs(3, i1, i2, 5, q) = 0._wp - end if - if (.not. f_is_default(Web)) then - ! add surface tension - momrhs(1, i1, i2, 6, q) = -2._wp + i1 - momrhs(2, i1, i2, 6, q) = -1._wp + i2 + momrhs(1, i1, i2, 6, q) = -1._wp + i1 + momrhs(2, i1, i2, 6, q) = 1._wp + i2 momrhs(3, i1, i2, 6, q) = 0._wp - end if - momrhs(1, i1, i2, 7, q) = -1._wp + i1 - momrhs(2, i1, i2, 7, q) = -1._wp + i2 - momrhs(3, i1, i2, 7, q) = 0._wp - else if (bubble_model == 2) then - ! KM with approximation of 1/(1-V/C) = 1+V/C - momrhs(1, i1, i2, 1, q) = -1._wp + i1 - momrhs(2, i1, i2, 1, q) = 1._wp + i2 - momrhs(3, i1, i2, 1, q) = 0._wp + momrhs(1, i1, i2, 7, q) = -1._wp + i1 + momrhs(2, i1, i2, 7, q) = -1._wp + i2 + momrhs(3, i1, i2, 7, q) = 0._wp + + momrhs(1, i1, i2, 8, q) = -1._wp + i1 + momrhs(2, i1, i2, 8, q) = i2 + momrhs(3, i1, i2, 8, q) = 0._wp + + momrhs(1, i1, i2, 9, q) = -1._wp + i1 + momrhs(2, i1, i2, 9, q) = 1._wp + i2 + momrhs(3, i1, i2, 9, q) = 0._wp + + momrhs(1, i1, i2, 10, q) = -1._wp + i1 + momrhs(2, i1, i2, 10, q) = i2 + momrhs(3, i1, i2, 10, q) = 0._wp + + momrhs(1, i1, i2, 11, q) = -1._wp + i1 + momrhs(2, i1, i2, 11, q) = 1._wp + i2 + momrhs(3, i1, i2, 11, q) = 0._wp + + momrhs(1, i1, i2, 12, q) = -1._wp + i1 + momrhs(2, i1, i2, 12, q) = 1._wp + i2 + momrhs(3, i1, i2, 12, q) = 0._wp + + momrhs(1, i1, i2, 13, q) = -1._wp + i1 + momrhs(2, i1, i2, 13, q) = -1._wp + i2 + momrhs(3, i1, i2, 13, q) = 0._wp + + momrhs(1, i1, i2, 14, q) = -1._wp + i1 + momrhs(2, i1, i2, 14, q) = i2 + momrhs(3, i1, i2, 14, q) = 0._wp + + momrhs(1, i1, i2, 15, q) = -1._wp + i1 + momrhs(2, i1, i2, 15, q) = 1._wp + i2 + momrhs(3, i1, i2, 15, q) = 0._wp + + momrhs(1, i1, i2, 16, q) = -2._wp + i1 + momrhs(2, i1, i2, 16, q) = i2 + momrhs(3, i1, i2, 16, q) = 0._wp - momrhs(1, i1, i2, 2, q) = -1._wp + i1 - momrhs(2, i1, i2, 2, q) = 2._wp + i2 - momrhs(3, i1, i2, 2, q) = 0._wp + momrhs(1, i1, i2, 17, q) = -2._wp + i1 + momrhs(2, i1, i2, 17, q) = -1._wp + i2 + momrhs(3, i1, i2, 17, q) = 0._wp - momrhs(1, i1, i2, 3, q) = -1._wp + i1 - momrhs(2, i1, i2, 3, q) = 3._wp + i2 - momrhs(3, i1, i2, 3, q) = 0._wp + momrhs(1, i1, i2, 18, q) = -2._wp + i1 + momrhs(2, i1, i2, 18, q) = 1._wp + i2 + momrhs(3, i1, i2, 18, q) = 0._wp - momrhs(1, i1, i2, 4, q) = -1._wp + i1 - momrhs(2, i1, i2, 4, q) = -1._wp + i2 - momrhs(3, i1, i2, 4, q) = 0._wp + momrhs(1, i1, i2, 19, q) = -2._wp + i1 + momrhs(2, i1, i2, 19, q) = 2._wp + i2 + momrhs(3, i1, i2, 19, q) = 0._wp - momrhs(1, i1, i2, 5, q) = -1._wp + i1 - momrhs(2, i1, i2, 5, q) = i2 - momrhs(3, i1, i2, 5, q) = 0._wp + momrhs(1, i1, i2, 20, q) = -2._wp + i1 + momrhs(2, i1, i2, 20, q) = -1._wp + i2 + momrhs(3, i1, i2, 20, q) = 0._wp - momrhs(1, i1, i2, 6, q) = -1._wp + i1 - momrhs(2, i1, i2, 6, q) = 1._wp + i2 - momrhs(3, i1, i2, 6, q) = 0._wp + momrhs(1, i1, i2, 21, q) = -2._wp + i1 + momrhs(2, i1, i2, 21, q) = i2 + momrhs(3, i1, i2, 21, q) = 0._wp - momrhs(1, i1, i2, 7, q) = -1._wp + i1 - momrhs(2, i1, i2, 7, q) = -1._wp + i2 - momrhs(3, i1, i2, 7, q) = 0._wp - - momrhs(1, i1, i2, 8, q) = -1._wp + i1 - momrhs(2, i1, i2, 8, q) = i2 - momrhs(3, i1, i2, 8, q) = 0._wp - - momrhs(1, i1, i2, 9, q) = -1._wp + i1 - momrhs(2, i1, i2, 9, q) = 1._wp + i2 - momrhs(3, i1, i2, 9, q) = 0._wp - - momrhs(1, i1, i2, 10, q) = -1._wp + i1 - momrhs(2, i1, i2, 10, q) = i2 - momrhs(3, i1, i2, 10, q) = 0._wp - - momrhs(1, i1, i2, 11, q) = -1._wp + i1 - momrhs(2, i1, i2, 11, q) = 1._wp + i2 - momrhs(3, i1, i2, 11, q) = 0._wp - - momrhs(1, i1, i2, 12, q) = -1._wp + i1 - momrhs(2, i1, i2, 12, q) = 1._wp + i2 - momrhs(3, i1, i2, 12, q) = 0._wp - - momrhs(1, i1, i2, 13, q) = -1._wp + i1 - momrhs(2, i1, i2, 13, q) = -1._wp + i2 - momrhs(3, i1, i2, 13, q) = 0._wp - - momrhs(1, i1, i2, 14, q) = -1._wp + i1 - momrhs(2, i1, i2, 14, q) = i2 - momrhs(3, i1, i2, 14, q) = 0._wp - - momrhs(1, i1, i2, 15, q) = -1._wp + i1 - momrhs(2, i1, i2, 15, q) = 1._wp + i2 - momrhs(3, i1, i2, 15, q) = 0._wp - - momrhs(1, i1, i2, 16, q) = -2._wp + i1 - momrhs(2, i1, i2, 16, q) = i2 - momrhs(3, i1, i2, 16, q) = 0._wp - - momrhs(1, i1, i2, 17, q) = -2._wp + i1 - momrhs(2, i1, i2, 17, q) = -1._wp + i2 - momrhs(3, i1, i2, 17, q) = 0._wp - - momrhs(1, i1, i2, 18, q) = -2._wp + i1 - momrhs(2, i1, i2, 18, q) = 1._wp + i2 - momrhs(3, i1, i2, 18, q) = 0._wp - - momrhs(1, i1, i2, 19, q) = -2._wp + i1 - momrhs(2, i1, i2, 19, q) = 2._wp + i2 - momrhs(3, i1, i2, 19, q) = 0._wp - - momrhs(1, i1, i2, 20, q) = -2._wp + i1 - momrhs(2, i1, i2, 20, q) = -1._wp + i2 - momrhs(3, i1, i2, 20, q) = 0._wp - - momrhs(1, i1, i2, 21, q) = -2._wp + i1 - momrhs(2, i1, i2, 21, q) = i2 - momrhs(3, i1, i2, 21, q) = 0._wp - - momrhs(1, i1, i2, 22, q) = -2._wp + i1 - momrhs(2, i1, i2, 22, q) = -1._wp + i2 - momrhs(3, i1, i2, 22, q) = 0._wp - - momrhs(1, i1, i2, 23, q) = -2._wp + i1 - momrhs(2, i1, i2, 23, q) = i2 - momrhs(3, i1, i2, 23, q) = 0._wp - - momrhs(1, i1, i2, 24, q) = -3._wp + i1 - momrhs(2, i1, i2, 24, q) = i2 - momrhs(3, i1, i2, 24, q) = 0._wp - - momrhs(1, i1, i2, 25, q) = -3._wp + i1 - momrhs(2, i1, i2, 25, q) = -1._wp + i2 - momrhs(3, i1, i2, 25, q) = 0._wp - - momrhs(1, i1, i2, 26, q) = -2._wp + i1 - momrhs(2, i1, i2, 26, q) = i2 - momrhs(3, i1, i2, 26, q) = 0._wp + momrhs(1, i1, i2, 22, q) = -2._wp + i1 + momrhs(2, i1, i2, 22, q) = -1._wp + i2 + momrhs(3, i1, i2, 22, q) = 0._wp - momrhs(1, i1, i2, 27, q) = -1._wp + i1 - momrhs(2, i1, i2, 27, q) = -1._wp + i2 - momrhs(3, i1, i2, 27, q) = 0._wp + momrhs(1, i1, i2, 23, q) = -2._wp + i1 + momrhs(2, i1, i2, 23, q) = i2 + momrhs(3, i1, i2, 23, q) = 0._wp - momrhs(1, i1, i2, 28, q) = -1._wp + i1 - momrhs(2, i1, i2, 28, q) = i2 - momrhs(3, i1, i2, 28, q) = 0._wp + momrhs(1, i1, i2, 24, q) = -3._wp + i1 + momrhs(2, i1, i2, 24, q) = i2 + momrhs(3, i1, i2, 24, q) = 0._wp - momrhs(1, i1, i2, 29, q) = -2._wp + i1 - momrhs(2, i1, i2, 29, q) = i2 - momrhs(3, i1, i2, 29, q) = 0._wp + momrhs(1, i1, i2, 25, q) = -3._wp + i1 + momrhs(2, i1, i2, 25, q) = -1._wp + i2 + momrhs(3, i1, i2, 25, q) = 0._wp - momrhs(1, i1, i2, 30, q) = -1._wp + i1 - momrhs(2, i1, i2, 30, q) = -1._wp + i2 - momrhs(3, i1, i2, 30, q) = 0._wp + momrhs(1, i1, i2, 26, q) = -2._wp + i1 + momrhs(2, i1, i2, 26, q) = i2 + momrhs(3, i1, i2, 26, q) = 0._wp - momrhs(1, i1, i2, 31, q) = -1._wp + i1 - momrhs(2, i1, i2, 31, q) = i2 - momrhs(3, i1, i2, 31, q) = 0._wp + momrhs(1, i1, i2, 27, q) = -1._wp + i1 + momrhs(2, i1, i2, 27, q) = -1._wp + i2 + momrhs(3, i1, i2, 27, q) = 0._wp - momrhs(1, i1, i2, 32, q) = -2._wp + i1 - momrhs(2, i1, i2, 32, q) = i2 - momrhs(3, i1, i2, 32, q) = 0._wp + momrhs(1, i1, i2, 28, q) = -1._wp + i1 + momrhs(2, i1, i2, 28, q) = i2 + momrhs(3, i1, i2, 28, q) = 0._wp + + momrhs(1, i1, i2, 29, q) = -2._wp + i1 + momrhs(2, i1, i2, 29, q) = i2 + momrhs(3, i1, i2, 29, q) = 0._wp + + momrhs(1, i1, i2, 30, q) = -1._wp + i1 + momrhs(2, i1, i2, 30, q) = -1._wp + i2 + momrhs(3, i1, i2, 30, q) = 0._wp + + momrhs(1, i1, i2, 31, q) = -1._wp + i1 + momrhs(2, i1, i2, 31, q) = i2 + momrhs(3, i1, i2, 31, q) = 0._wp + + momrhs(1, i1, i2, 32, q) = -2._wp + i1 + momrhs(2, i1, i2, 32, q) = i2 + momrhs(3, i1, i2, 32, q) = 0._wp + end if end if - end if - end do; end do + end do; end do end do + else do q = 1, nb do i1 = 0, 2; do i2 = 0, 2 - if ((i1 + i2) <= 2) then - if (bubble_model == 3) then - momrhs(1, i1, i2, 1, q) = -1._wp + i1 - momrhs(2, i1, i2, 1, q) = -1._wp + i2 - momrhs(3, i1, i2, 1, q) = 0._wp + if ((i1 + i2) <= 2) then + if (bubble_model == 3) then + momrhs(1, i1, i2, 1, q) = -1._wp + i1 + momrhs(2, i1, i2, 1, q) = -1._wp + i2 + momrhs(3, i1, i2, 1, q) = 0._wp + + momrhs(1, i1, i2, 2, q) = -1._wp + i1 + momrhs(2, i1, i2, 2, q) = 1._wp + i2 + momrhs(3, i1, i2, 2, q) = 0._wp + + momrhs(1, i1, i2, 3, q) = -1._wp + i1 - 3._wp*gam + momrhs(2, i1, i2, 3, q) = -1._wp + i2 + momrhs(3, i1, i2, 3, q) = 3._wp*gam + + momrhs(1, i1, i2, 4, q) = -1._wp + i1 + momrhs(2, i1, i2, 4, q) = 1._wp + i2 + momrhs(3, i1, i2, 4, q) = 0._wp + + if (.not. f_is_default(Re_inv)) then + ! add viscosity + momrhs(1, i1, i2, 5, q) = -2._wp + i1 + momrhs(2, i1, i2, 5, q) = i2 + momrhs(3, i1, i2, 5, q) = 0._wp + end if + + if (.not. f_is_default(Web)) then + ! add surface tension + momrhs(1, i1, i2, 6, q) = -2._wp + i1 + momrhs(2, i1, i2, 6, q) = -1._wp + i2 + momrhs(3, i1, i2, 6, q) = 0._wp + end if - momrhs(1, i1, i2, 2, q) = -1._wp + i1 - momrhs(2, i1, i2, 2, q) = 1._wp + i2 - momrhs(3, i1, i2, 2, q) = 0._wp + momrhs(1, i1, i2, 7, q) = -1._wp + i1 + momrhs(2, i1, i2, 7, q) = -1._wp + i2 + momrhs(3, i1, i2, 7, q) = 0._wp - momrhs(1, i1, i2, 3, q) = -1._wp + i1 - 3._wp*gam - momrhs(2, i1, i2, 3, q) = -1._wp + i2 - momrhs(3, i1, i2, 3, q) = 3._wp*gam + else if (bubble_model == 2) then + ! KM with approximation of 1/(1-V/C) = 1+V/C + momrhs(1, i1, i2, 1, q) = -1._wp + i1 + momrhs(2, i1, i2, 1, q) = 1._wp + i2 + momrhs(3, i1, i2, 1, q) = 0._wp - momrhs(1, i1, i2, 4, q) = -1._wp + i1 - momrhs(2, i1, i2, 4, q) = 1._wp + i2 - momrhs(3, i1, i2, 4, q) = 0._wp + momrhs(1, i1, i2, 2, q) = -1._wp + i1 + momrhs(2, i1, i2, 2, q) = 2._wp + i2 + momrhs(3, i1, i2, 2, q) = 0._wp - if (.not. f_is_default(Re_inv)) then - ! add viscosity - momrhs(1, i1, i2, 5, q) = -2._wp + i1 + momrhs(1, i1, i2, 3, q) = -1._wp + i1 + momrhs(2, i1, i2, 3, q) = 3._wp + i2 + momrhs(3, i1, i2, 3, q) = 0._wp + + momrhs(1, i1, i2, 4, q) = -1._wp + i1 + momrhs(2, i1, i2, 4, q) = -1._wp + i2 + momrhs(3, i1, i2, 4, q) = 0._wp + + momrhs(1, i1, i2, 5, q) = -1._wp + i1 momrhs(2, i1, i2, 5, q) = i2 momrhs(3, i1, i2, 5, q) = 0._wp - end if - if (.not. f_is_default(Web)) then - ! add surface tension - momrhs(1, i1, i2, 6, q) = -2._wp + i1 - momrhs(2, i1, i2, 6, q) = -1._wp + i2 + momrhs(1, i1, i2, 6, q) = -1._wp + i1 + momrhs(2, i1, i2, 6, q) = 1._wp + i2 momrhs(3, i1, i2, 6, q) = 0._wp - end if - momrhs(1, i1, i2, 7, q) = -1._wp + i1 - momrhs(2, i1, i2, 7, q) = -1._wp + i2 - momrhs(3, i1, i2, 7, q) = 0._wp - else if (bubble_model == 2) then - ! KM with approximation of 1/(1-V/C) = 1+V/C - momrhs(1, i1, i2, 1, q) = -1._wp + i1 - momrhs(2, i1, i2, 1, q) = 1._wp + i2 - momrhs(3, i1, i2, 1, q) = 0._wp - - momrhs(1, i1, i2, 2, q) = -1._wp + i1 - momrhs(2, i1, i2, 2, q) = 2._wp + i2 - momrhs(3, i1, i2, 2, q) = 0._wp - - momrhs(1, i1, i2, 3, q) = -1._wp + i1 - momrhs(2, i1, i2, 3, q) = 3._wp + i2 - momrhs(3, i1, i2, 3, q) = 0._wp - - momrhs(1, i1, i2, 4, q) = -1._wp + i1 - momrhs(2, i1, i2, 4, q) = -1._wp + i2 - momrhs(3, i1, i2, 4, q) = 0._wp - - momrhs(1, i1, i2, 5, q) = -1._wp + i1 - momrhs(2, i1, i2, 5, q) = i2 - momrhs(3, i1, i2, 5, q) = 0._wp - - momrhs(1, i1, i2, 6, q) = -1._wp + i1 - momrhs(2, i1, i2, 6, q) = 1._wp + i2 - momrhs(3, i1, i2, 6, q) = 0._wp - - momrhs(1, i1, i2, 7, q) = -1._wp + i1 - 3._wp*gam - momrhs(2, i1, i2, 7, q) = -1._wp + i2 - momrhs(3, i1, i2, 7, q) = 3._wp*gam - - momrhs(1, i1, i2, 8, q) = -1._wp + i1 - 3._wp*gam - momrhs(2, i1, i2, 8, q) = i2 - momrhs(3, i1, i2, 8, q) = 3._wp*gam - - momrhs(1, i1, i2, 9, q) = -1._wp + i1 - 3._wp*gam - momrhs(2, i1, i2, 9, q) = 1._wp + i2 - momrhs(3, i1, i2, 9, q) = 3._wp*gam - - momrhs(1, i1, i2, 10, q) = -1._wp + i1 - 3._wp*gam - momrhs(2, i1, i2, 10, q) = i2 - momrhs(3, i1, i2, 10, q) = 3._wp*gam - - momrhs(1, i1, i2, 11, q) = -1._wp + i1 - 3._wp*gam - momrhs(2, i1, i2, 11, q) = 1._wp + i2 - momrhs(3, i1, i2, 11, q) = 3._wp*gam - - momrhs(1, i1, i2, 12, q) = -1._wp + i1 - momrhs(2, i1, i2, 12, q) = 1._wp + i2 - momrhs(3, i1, i2, 12, q) = 0._wp - - momrhs(1, i1, i2, 13, q) = -1._wp + i1 - momrhs(2, i1, i2, 13, q) = -1._wp + i2 - momrhs(3, i1, i2, 13, q) = 0._wp - - momrhs(1, i1, i2, 14, q) = -1._wp + i1 - momrhs(2, i1, i2, 14, q) = i2 - momrhs(3, i1, i2, 14, q) = 0._wp - - momrhs(1, i1, i2, 15, q) = -1._wp + i1 - momrhs(2, i1, i2, 15, q) = 1._wp + i2 - momrhs(3, i1, i2, 15, q) = 0._wp - - momrhs(1, i1, i2, 16, q) = -2._wp + i1 - momrhs(2, i1, i2, 16, q) = i2 - momrhs(3, i1, i2, 16, q) = 0._wp - - momrhs(1, i1, i2, 17, q) = -2._wp + i1 - momrhs(2, i1, i2, 17, q) = -1._wp + i2 - momrhs(3, i1, i2, 17, q) = 0._wp - - momrhs(1, i1, i2, 18, q) = -2._wp + i1 - momrhs(2, i1, i2, 18, q) = 1._wp + i2 - momrhs(3, i1, i2, 18, q) = 0._wp - - momrhs(1, i1, i2, 19, q) = -2._wp + i1 - momrhs(2, i1, i2, 19, q) = 2._wp + i2 - momrhs(3, i1, i2, 19, q) = 0._wp - - momrhs(1, i1, i2, 20, q) = -2._wp + i1 - momrhs(2, i1, i2, 20, q) = -1._wp + i2 - momrhs(3, i1, i2, 20, q) = 0._wp - - momrhs(1, i1, i2, 21, q) = -2._wp + i1 - momrhs(2, i1, i2, 21, q) = i2 - momrhs(3, i1, i2, 21, q) = 0._wp - - momrhs(1, i1, i2, 22, q) = -2._wp + i1 - 3._wp*gam - momrhs(2, i1, i2, 22, q) = -1._wp + i2 - momrhs(3, i1, i2, 22, q) = 3._wp*gam - - momrhs(1, i1, i2, 23, q) = -2._wp + i1 - 3._wp*gam - momrhs(2, i1, i2, 23, q) = i2 - momrhs(3, i1, i2, 23, q) = 3._wp*gam - - momrhs(1, i1, i2, 24, q) = -3._wp + i1 - momrhs(2, i1, i2, 24, q) = i2 - momrhs(3, i1, i2, 24, q) = 0._wp - - momrhs(1, i1, i2, 25, q) = -3._wp + i1 - momrhs(2, i1, i2, 25, q) = -1._wp + i2 - momrhs(3, i1, i2, 25, q) = 0._wp - - momrhs(1, i1, i2, 26, q) = -2._wp + i1 - 3._wp*gam - momrhs(2, i1, i2, 26, q) = i2 - momrhs(3, i1, i2, 26, q) = 3._wp*gam + momrhs(1, i1, i2, 7, q) = -1._wp + i1 - 3._wp*gam + momrhs(2, i1, i2, 7, q) = -1._wp + i2 + momrhs(3, i1, i2, 7, q) = 3._wp*gam + + momrhs(1, i1, i2, 8, q) = -1._wp + i1 - 3._wp*gam + momrhs(2, i1, i2, 8, q) = i2 + momrhs(3, i1, i2, 8, q) = 3._wp*gam + + momrhs(1, i1, i2, 9, q) = -1._wp + i1 - 3._wp*gam + momrhs(2, i1, i2, 9, q) = 1._wp + i2 + momrhs(3, i1, i2, 9, q) = 3._wp*gam + + momrhs(1, i1, i2, 10, q) = -1._wp + i1 - 3._wp*gam + momrhs(2, i1, i2, 10, q) = i2 + momrhs(3, i1, i2, 10, q) = 3._wp*gam + + momrhs(1, i1, i2, 11, q) = -1._wp + i1 - 3._wp*gam + momrhs(2, i1, i2, 11, q) = 1._wp + i2 + momrhs(3, i1, i2, 11, q) = 3._wp*gam + + momrhs(1, i1, i2, 12, q) = -1._wp + i1 + momrhs(2, i1, i2, 12, q) = 1._wp + i2 + momrhs(3, i1, i2, 12, q) = 0._wp + + momrhs(1, i1, i2, 13, q) = -1._wp + i1 + momrhs(2, i1, i2, 13, q) = -1._wp + i2 + momrhs(3, i1, i2, 13, q) = 0._wp + + momrhs(1, i1, i2, 14, q) = -1._wp + i1 + momrhs(2, i1, i2, 14, q) = i2 + momrhs(3, i1, i2, 14, q) = 0._wp + + momrhs(1, i1, i2, 15, q) = -1._wp + i1 + momrhs(2, i1, i2, 15, q) = 1._wp + i2 + momrhs(3, i1, i2, 15, q) = 0._wp + + momrhs(1, i1, i2, 16, q) = -2._wp + i1 + momrhs(2, i1, i2, 16, q) = i2 + momrhs(3, i1, i2, 16, q) = 0._wp + + momrhs(1, i1, i2, 17, q) = -2._wp + i1 + momrhs(2, i1, i2, 17, q) = -1._wp + i2 + momrhs(3, i1, i2, 17, q) = 0._wp + + momrhs(1, i1, i2, 18, q) = -2._wp + i1 + momrhs(2, i1, i2, 18, q) = 1._wp + i2 + momrhs(3, i1, i2, 18, q) = 0._wp + + momrhs(1, i1, i2, 19, q) = -2._wp + i1 + momrhs(2, i1, i2, 19, q) = 2._wp + i2 + momrhs(3, i1, i2, 19, q) = 0._wp + + momrhs(1, i1, i2, 20, q) = -2._wp + i1 + momrhs(2, i1, i2, 20, q) = -1._wp + i2 + momrhs(3, i1, i2, 20, q) = 0._wp + + momrhs(1, i1, i2, 21, q) = -2._wp + i1 + momrhs(2, i1, i2, 21, q) = i2 + momrhs(3, i1, i2, 21, q) = 0._wp + + momrhs(1, i1, i2, 22, q) = -2._wp + i1 - 3._wp*gam + momrhs(2, i1, i2, 22, q) = -1._wp + i2 + momrhs(3, i1, i2, 22, q) = 3._wp*gam + + momrhs(1, i1, i2, 23, q) = -2._wp + i1 - 3._wp*gam + momrhs(2, i1, i2, 23, q) = i2 + momrhs(3, i1, i2, 23, q) = 3._wp*gam + + momrhs(1, i1, i2, 24, q) = -3._wp + i1 + momrhs(2, i1, i2, 24, q) = i2 + momrhs(3, i1, i2, 24, q) = 0._wp + + momrhs(1, i1, i2, 25, q) = -3._wp + i1 + momrhs(2, i1, i2, 25, q) = -1._wp + i2 + momrhs(3, i1, i2, 25, q) = 0._wp + + momrhs(1, i1, i2, 26, q) = -2._wp + i1 - 3._wp*gam + momrhs(2, i1, i2, 26, q) = i2 + momrhs(3, i1, i2, 26, q) = 3._wp*gam + + end if end if - end if - end do; end do + end do; end do end do end if @@ -400,21 +412,19 @@ contains end subroutine s_initialize_qbmm_module - !> Compute the QBMM right-hand side source terms for bubble moment transport equations + !> @brief Computes the QBMM right-hand side source terms for bubble moment transport equations. subroutine s_compute_qbmm_rhs(idir, q_cons_vf, q_prim_vf, rhs_vf, flux_n_vf, pb, rhs_pb) - integer, intent(in) :: idir - type(scalar_field), dimension(sys_size), intent(in) :: q_cons_vf, q_prim_vf - type(scalar_field), dimension(sys_size), intent(inout) :: rhs_vf - type(scalar_field), dimension(sys_size), intent(in) :: flux_n_vf - real(stp), dimension(idwbuff(1)%beg:,idwbuff(2)%beg:,idwbuff(3)%beg:,1:,1:), intent(inout) :: pb - - real(wp), dimension(idwbuff(1)%beg:,idwbuff(2)%beg:,idwbuff(3)%beg:,1:,1:), & - & intent(inout) :: rhs_pb ! TODO :: I think that this should be stp as well. + integer, intent(in) :: idir + type(scalar_field), dimension(sys_size), intent(in) :: q_cons_vf, q_prim_vf + type(scalar_field), dimension(sys_size), intent(inout) :: rhs_vf + type(scalar_field), dimension(sys_size), intent(in) :: flux_n_vf + real(stp), dimension(idwbuff(1)%beg:, idwbuff(2)%beg:, idwbuff(3)%beg:, 1:, 1:), intent(inout) :: pb + real(wp), dimension(idwbuff(1)%beg:, idwbuff(2)%beg:, idwbuff(3)%beg:, 1:, 1:), intent(inout) :: rhs_pb ! TODO :: I think that this should be stp as well. - integer :: i, j, k, l, q + integer :: i, j, k, l, q real(wp) :: nb_q, nb_dot, R, R2, nR, nR2, nR_dot, nR2_dot, var, AX - logical :: is_axisym + logical :: is_axisym select case (idir) case (1) @@ -426,7 +436,7 @@ contains end select if (.not. polytropic) then - $:GPU_PARALLEL_LOOP(collapse=5,private='[i, j, k, l, q, nb_q, nR, nR2, R, R2, nb_dot, nR_dot, nR2_dot, var, AX]') + $:GPU_PARALLEL_LOOP(collapse=5,private='[i,j,k,l,q,nb_q,nR,nR2,R,R2,nb_dot,nR_dot,nR2_dot,var,AX]') do i = 1, nb do q = 1, nnode do l = 0, p @@ -446,109 +456,80 @@ contains select case (idir) case (1) - nb_dot = flux_n_vf(bubxb + (i - 1)*nmom)%sf(j - 1, k, & - & l) - flux_n_vf(bubxb + (i - 1)*nmom)%sf(j, k, l) - nR_dot = flux_n_vf(bubxb + 1 + (i - 1)*nmom)%sf(j - 1, k, & - & l) - flux_n_vf(bubxb + 1 + (i - 1)*nmom)%sf(j, k, l) - nR2_dot = flux_n_vf(bubxb + 3 + (i - 1)*nmom)%sf(j - 1, k, & - & l) - flux_n_vf(bubxb + 3 + (i - 1)*nmom)%sf(j, k, l) - rhs_pb(j, k, l, q, i) = rhs_pb(j, k, l, q, & - & i) - 3._wp*gam/(dx(j)*AX*nb_q**2)*(nR_dot*nb_q - nR*nb_dot)*(pb(j, k, l, q, i)) + nb_dot = flux_n_vf(bubxb + (i - 1)*nmom)%sf(j - 1, k, l) - flux_n_vf(bubxb + (i - 1)*nmom)%sf(j, k, l) + nR_dot = flux_n_vf(bubxb + 1 + (i - 1)*nmom)%sf(j - 1, k, l) - flux_n_vf(bubxb + 1 + (i - 1)*nmom)%sf(j, k, l) + nR2_dot = flux_n_vf(bubxb + 3 + (i - 1)*nmom)%sf(j - 1, k, l) - flux_n_vf(bubxb + 3 + (i - 1)*nmom)%sf(j, k, l) + rhs_pb(j, k, l, q, i) = rhs_pb(j, k, l, q, i) - 3._wp*gam/(dx(j)*AX*nb_q**2)* & + (nR_dot*nb_q - nR*nb_dot)*(pb(j, k, l, q, i)) case (2) - nb_dot = flux_n_vf(bubxb + (i - 1)*nmom)%sf(j, k - 1, & - & l) - flux_n_vf(bubxb + (i - 1)*nmom)%sf(j, k, l) - nR_dot = flux_n_vf(bubxb + 1 + (i - 1)*nmom)%sf(j, k - 1, & - & l) - flux_n_vf(bubxb + 1 + (i - 1)*nmom)%sf(j, k, l) - nR2_dot = flux_n_vf(bubxb + 3 + (i - 1)*nmom)%sf(j, k - 1, & - & l) - flux_n_vf(bubxb + 3 + (i - 1)*nmom)%sf(j, k, l) - rhs_pb(j, k, l, q, i) = rhs_pb(j, k, l, q, & - & i) - 3._wp*gam/(dy(k)*AX*nb_q**2)*(nR_dot*nb_q - nR*nb_dot)*(pb(j, k, l, q, i)) + nb_dot = flux_n_vf(bubxb + (i - 1)*nmom)%sf(j, k - 1, l) - flux_n_vf(bubxb + (i - 1)*nmom)%sf(j, k, l) + nR_dot = flux_n_vf(bubxb + 1 + (i - 1)*nmom)%sf(j, k - 1, l) - flux_n_vf(bubxb + 1 + (i - 1)*nmom)%sf(j, k, l) + nR2_dot = flux_n_vf(bubxb + 3 + (i - 1)*nmom)%sf(j, k - 1, l) - flux_n_vf(bubxb + 3 + (i - 1)*nmom)%sf(j, k, l) + rhs_pb(j, k, l, q, i) = rhs_pb(j, k, l, q, i) - 3._wp*gam/(dy(k)*AX*nb_q**2)* & + (nR_dot*nb_q - nR*nb_dot)*(pb(j, k, l, q, i)) case (3) if (is_axisym) then - nb_dot = q_prim_vf(contxe + idir)%sf(j, k, l)*(flux_n_vf(bubxb + (i - 1)*nmom)%sf(j, k, & - & l - 1) - flux_n_vf(bubxb + (i - 1)*nmom)%sf(j, k, l)) - nR_dot = q_prim_vf(contxe + idir)%sf(j, k, l)*(flux_n_vf(bubxb + 1 + (i - 1)*nmom)%sf(j, & - & k, l - 1) - flux_n_vf(bubxb + 1 + (i - 1)*nmom)%sf(j, k, l)) - nR2_dot = q_prim_vf(contxe + idir)%sf(j, k, l)*(flux_n_vf(bubxb + 3 + (i - 1)*nmom)%sf(j, & - & k, l - 1) - flux_n_vf(bubxb + 3 + (i - 1)*nmom)%sf(j, k, l)) - rhs_pb(j, k, l, q, i) = rhs_pb(j, k, l, q, & - & i) - 3._wp*gam/(dz(l)*y_cc(k)*AX*nb_q**2)*(nR_dot*nb_q - nR*nb_dot)*(pb(j, k, l, & - & q, i)) + nb_dot = q_prim_vf(contxe + idir)%sf(j, k, l)*(flux_n_vf(bubxb + (i - 1)*nmom)%sf(j, k, l - 1) - flux_n_vf(bubxb + (i - 1)*nmom)%sf(j, k, l)) + nR_dot = q_prim_vf(contxe + idir)%sf(j, k, l)*(flux_n_vf(bubxb + 1 + (i - 1)*nmom)%sf(j, k, l - 1) - flux_n_vf(bubxb + 1 + (i - 1)*nmom)%sf(j, k, l)) + nR2_dot = q_prim_vf(contxe + idir)%sf(j, k, l)*(flux_n_vf(bubxb + 3 + (i - 1)*nmom)%sf(j, k, l - 1) - flux_n_vf(bubxb + 3 + (i - 1)*nmom)%sf(j, k, l)) + rhs_pb(j, k, l, q, i) = rhs_pb(j, k, l, q, i) - 3._wp*gam/(dz(l)*y_cc(k)*AX*nb_q**2)* & + (nR_dot*nb_q - nR*nb_dot)*(pb(j, k, l, q, i)) else - nb_dot = flux_n_vf(bubxb + (i - 1)*nmom)%sf(j, k, & - & l - 1) - flux_n_vf(bubxb + (i - 1)*nmom)%sf(j, k, l) - nR_dot = flux_n_vf(bubxb + 1 + (i - 1)*nmom)%sf(j, k, & - & l - 1) - flux_n_vf(bubxb + 1 + (i - 1)*nmom)%sf(j, k, l) - nR2_dot = flux_n_vf(bubxb + 3 + (i - 1)*nmom)%sf(j, k, & - & l - 1) - flux_n_vf(bubxb + 3 + (i - 1)*nmom)%sf(j, k, l) - rhs_pb(j, k, l, q, i) = rhs_pb(j, k, l, q, & - & i) - 3._wp*gam/(dz(l)*AX*nb_q**2)*(nR_dot*nb_q - nR*nb_dot)*(pb(j, k, l, q, i)) + nb_dot = flux_n_vf(bubxb + (i - 1)*nmom)%sf(j, k, l - 1) - flux_n_vf(bubxb + (i - 1)*nmom)%sf(j, k, l) + nR_dot = flux_n_vf(bubxb + 1 + (i - 1)*nmom)%sf(j, k, l - 1) - flux_n_vf(bubxb + 1 + (i - 1)*nmom)%sf(j, k, l) + nR2_dot = flux_n_vf(bubxb + 3 + (i - 1)*nmom)%sf(j, k, l - 1) - flux_n_vf(bubxb + 3 + (i - 1)*nmom)%sf(j, k, l) + rhs_pb(j, k, l, q, i) = rhs_pb(j, k, l, q, i) - 3._wp*gam/(dz(l)*AX*nb_q**2)* & + (nR_dot*nb_q - nR*nb_dot)*(pb(j, k, l, q, i)) end if end select if (q <= 2) then select case (idir) case (1) - rhs_pb(j, k, l, q, i) = rhs_pb(j, k, l, q, & - & i) + 3._wp*gam/(dx(j)*AX*nb_q**2*sqrt(var)*2._wp)*(nR2_dot*nb_q - nR2*nb_dot) & - & *(pb(j, k, l, q, i)) - rhs_pb(j, k, l, q, i) = rhs_pb(j, k, l, q, & - & i) + 3._wp*gam/(dx(j)*AX*nb_q**2*sqrt(var)*2._wp)*(-2._wp*(nR/nb_q)*(nR_dot*nb_q & - & - nR*nb_dot))*(pb(j, k, l, q, i)) + rhs_pb(j, k, l, q, i) = rhs_pb(j, k, l, q, i) + 3._wp*gam/(dx(j)*AX*nb_q**2*sqrt(var)*2._wp)* & + (nR2_dot*nb_q - nR2*nb_dot)*(pb(j, k, l, q, i)) + rhs_pb(j, k, l, q, i) = rhs_pb(j, k, l, q, i) + 3._wp*gam/(dx(j)*AX*nb_q**2*sqrt(var)*2._wp)* & + (-2._wp*(nR/nb_q)*(nR_dot*nb_q - nR*nb_dot))*(pb(j, k, l, q, i)) case (2) - rhs_pb(j, k, l, q, i) = rhs_pb(j, k, l, q, & - & i) + 3._wp*gam/(dy(k)*AX*nb_q**2*sqrt(var)*2._wp)*(nR2_dot*nb_q - nR2*nb_dot) & - & *(pb(j, k, l, q, i)) - rhs_pb(j, k, l, q, i) = rhs_pb(j, k, l, q, & - & i) + 3._wp*gam/(dy(k)*AX*nb_q**2*sqrt(var)*2._wp)*(-2._wp*(nR/nb_q)*(nR_dot*nb_q & - & - nR*nb_dot))*(pb(j, k, l, q, i)) + rhs_pb(j, k, l, q, i) = rhs_pb(j, k, l, q, i) + 3._wp*gam/(dy(k)*AX*nb_q**2*sqrt(var)*2._wp)* & + (nR2_dot*nb_q - nR2*nb_dot)*(pb(j, k, l, q, i)) + rhs_pb(j, k, l, q, i) = rhs_pb(j, k, l, q, i) + 3._wp*gam/(dy(k)*AX*nb_q**2*sqrt(var)*2._wp)* & + (-2._wp*(nR/nb_q)*(nR_dot*nb_q - nR*nb_dot))*(pb(j, k, l, q, i)) case (3) if (is_axisym) then - rhs_pb(j, k, l, q, i) = rhs_pb(j, k, l, q, & - & i) + 3._wp*gam/(dz(l)*y_cc(k)*AX*nb_q**2*sqrt(var)*2._wp)*(nR2_dot*nb_q & - & - nR2*nb_dot)*(pb(j, k, l, q, i)) - rhs_pb(j, k, l, q, i) = rhs_pb(j, k, l, q, & - & i) + 3._wp*gam/(dz(l)*y_cc(k)*AX*nb_q**2*sqrt(var)*2._wp)*(-2._wp*(nR/nb_q) & - & *(nR_dot*nb_q - nR*nb_dot))*(pb(j, k, l, q, i)) + rhs_pb(j, k, l, q, i) = rhs_pb(j, k, l, q, i) + 3._wp*gam/(dz(l)*y_cc(k)*AX*nb_q**2*sqrt(var)*2._wp)* & + (nR2_dot*nb_q - nR2*nb_dot)*(pb(j, k, l, q, i)) + rhs_pb(j, k, l, q, i) = rhs_pb(j, k, l, q, i) + 3._wp*gam/(dz(l)*y_cc(k)*AX*nb_q**2*sqrt(var)*2._wp)* & + (-2._wp*(nR/nb_q)*(nR_dot*nb_q - nR*nb_dot))*(pb(j, k, l, q, i)) else - rhs_pb(j, k, l, q, i) = rhs_pb(j, k, l, q, & - & i) + 3._wp*gam/(dz(l)*AX*nb_q**2*sqrt(var)*2._wp)*(nR2_dot*nb_q - nR2*nb_dot) & - & *(pb(j, k, l, q, i)) - rhs_pb(j, k, l, q, i) = rhs_pb(j, k, l, q, & - & i) + 3._wp*gam/(dz(l)*AX*nb_q**2*sqrt(var)*2._wp)*(-2._wp*(nR/nb_q) & - & *(nR_dot*nb_q - nR*nb_dot))*(pb(j, k, l, q, i)) + rhs_pb(j, k, l, q, i) = rhs_pb(j, k, l, q, i) + 3._wp*gam/(dz(l)*AX*nb_q**2*sqrt(var)*2._wp)* & + (nR2_dot*nb_q - nR2*nb_dot)*(pb(j, k, l, q, i)) + rhs_pb(j, k, l, q, i) = rhs_pb(j, k, l, q, i) + 3._wp*gam/(dz(l)*AX*nb_q**2*sqrt(var)*2._wp)* & + (-2._wp*(nR/nb_q)*(nR_dot*nb_q - nR*nb_dot))*(pb(j, k, l, q, i)) end if end select else select case (idir) case (1) - rhs_pb(j, k, l, q, i) = rhs_pb(j, k, l, q, & - & i) - 3._wp*gam/(dx(j)*AX*nb_q**2*sqrt(var)*2._wp)*(nR2_dot*nb_q - nR2*nb_dot) & - & *(pb(j, k, l, q, i)) - rhs_pb(j, k, l, q, i) = rhs_pb(j, k, l, q, & - & i) - 3._wp*gam/(dx(j)*AX*nb_q**2*sqrt(var)*2._wp)*(-2._wp*(nR/nb_q)*(nR_dot*nb_q & - & - nR*nb_dot))*(pb(j, k, l, q, i)) + rhs_pb(j, k, l, q, i) = rhs_pb(j, k, l, q, i) - 3._wp*gam/(dx(j)*AX*nb_q**2*sqrt(var)*2._wp)* & + (nR2_dot*nb_q - nR2*nb_dot)*(pb(j, k, l, q, i)) + rhs_pb(j, k, l, q, i) = rhs_pb(j, k, l, q, i) - 3._wp*gam/(dx(j)*AX*nb_q**2*sqrt(var)*2._wp)* & + (-2._wp*(nR/nb_q)*(nR_dot*nb_q - nR*nb_dot))*(pb(j, k, l, q, i)) case (2) - rhs_pb(j, k, l, q, i) = rhs_pb(j, k, l, q, & - & i) - 3._wp*gam/(dy(k)*AX*nb_q**2*sqrt(var)*2._wp)*(nR2_dot*nb_q - nR2*nb_dot) & - & *(pb(j, k, l, q, i)) - rhs_pb(j, k, l, q, i) = rhs_pb(j, k, l, q, & - & i) - 3._wp*gam/(dy(k)*AX*nb_q**2*sqrt(var)*2._wp)*(-2._wp*(nR/nb_q)*(nR_dot*nb_q & - & - nR*nb_dot))*(pb(j, k, l, q, i)) + rhs_pb(j, k, l, q, i) = rhs_pb(j, k, l, q, i) - 3._wp*gam/(dy(k)*AX*nb_q**2*sqrt(var)*2._wp)* & + (nR2_dot*nb_q - nR2*nb_dot)*(pb(j, k, l, q, i)) + rhs_pb(j, k, l, q, i) = rhs_pb(j, k, l, q, i) - 3._wp*gam/(dy(k)*AX*nb_q**2*sqrt(var)*2._wp)* & + (-2._wp*(nR/nb_q)*(nR_dot*nb_q - nR*nb_dot))*(pb(j, k, l, q, i)) case (3) if (is_axisym) then - rhs_pb(j, k, l, q, i) = rhs_pb(j, k, l, q, & - & i) - 3._wp*gam/(dz(l)*y_cc(k)*AX*nb_q**2*sqrt(var)*2._wp)*(nR2_dot*nb_q & - & - nR2*nb_dot)*(pb(j, k, l, q, i)) - rhs_pb(j, k, l, q, i) = rhs_pb(j, k, l, q, & - & i) - 3._wp*gam/(dz(l)*y_cc(k)*AX*nb_q**2*sqrt(var)*2._wp)*(-2._wp*(nR/nb_q) & - & *(nR_dot*nb_q - nR*nb_dot))*(pb(j, k, l, q, i)) + rhs_pb(j, k, l, q, i) = rhs_pb(j, k, l, q, i) - 3._wp*gam/(dz(l)*y_cc(k)*AX*nb_q**2*sqrt(var)*2._wp)* & + (nR2_dot*nb_q - nR2*nb_dot)*(pb(j, k, l, q, i)) + rhs_pb(j, k, l, q, i) = rhs_pb(j, k, l, q, i) - 3._wp*gam/(dz(l)*y_cc(k)*AX*nb_q**2*sqrt(var)*2._wp)* & + (-2._wp*(nR/nb_q)*(nR_dot*nb_q - nR*nb_dot))*(pb(j, k, l, q, i)) else - rhs_pb(j, k, l, q, i) = rhs_pb(j, k, l, q, & - & i) - 3._wp*gam/(dz(l)*AX*nb_q**2*sqrt(var)*2._wp)*(nR2_dot*nb_q - nR2*nb_dot) & - & *(pb(j, k, l, q, i)) - rhs_pb(j, k, l, q, i) = rhs_pb(j, k, l, q, & - & i) - 3._wp*gam/(dz(l)*AX*nb_q**2*sqrt(var)*2._wp)*(-2._wp*(nR/nb_q) & - & *(nR_dot*nb_q - nR*nb_dot))*(pb(j, k, l, q, i)) + rhs_pb(j, k, l, q, i) = rhs_pb(j, k, l, q, i) - 3._wp*gam/(dz(l)*AX*nb_q**2*sqrt(var)*2._wp)* & + (nR2_dot*nb_q - nR2*nb_dot)*(pb(j, k, l, q, i)) + rhs_pb(j, k, l, q, i) = rhs_pb(j, k, l, q, i) - 3._wp*gam/(dz(l)*AX*nb_q**2*sqrt(var)*2._wp)* & + (-2._wp*(nR/nb_q)*(nR_dot*nb_q - nR*nb_dot))*(pb(j, k, l, q, i)) end if end select end if @@ -562,7 +543,7 @@ contains ! The following block is not repeated and is left as is if (idir == 1) then - $:GPU_PARALLEL_LOOP(private='[i, l, q]', collapse=3) + $:GPU_PARALLEL_LOOP(private='[i,l,q]', collapse=3) do l = 0, p do q = 0, n do i = 0, m @@ -586,191 +567,189 @@ contains end subroutine s_compute_qbmm_rhs - !> Build the coefficient array for the non-polytropic bubble model + !> @brief Builds the coefficient array for the non-polytropic bubble model. subroutine s_coeff_nonpoly(pres, rho, c, coeffs) - - $:GPU_ROUTINE(function_name='s_coeff_nonpoly',parallelism='[seq]', cray_inline=True) + $:GPU_ROUTINE(function_name='s_coeff_nonpoly',parallelism='[seq]', & + & cray_inline=True) real(wp), intent(in) :: pres, rho, c #:if USING_AMD - real(wp), dimension(32,0:2,0:2), intent(out) :: coeffs + real(wp), dimension(32, 0:2, 0:2), intent(out) :: coeffs #:else - real(wp), dimension(nterms,0:2,0:2), intent(out) :: coeffs + real(wp), dimension(nterms, 0:2, 0:2), intent(out) :: coeffs #:endif integer :: i1, i2 - coeffs(:,:,:) = 0._wp + coeffs(:, :, :) = 0._wp do i2 = 0, 2; do i1 = 0, 2 - if ((i1 + i2) <= 2) then - if (bubble_model == 3) then - #:if not MFC_CASE_OPTIMIZATION or nterms > 1 - ! RPE - coeffs(1, i1, i2) = -1._wp*i2*pres/rho - coeffs(2, i1, i2) = -3._wp*i2/2._wp - coeffs(3, i1, i2) = i2/rho - coeffs(4, i1, i2) = i1 - if (.not. f_is_default(Re_inv)) coeffs(5, i1, i2) = -4._wp*i2*Re_inv/rho - if (.not. f_is_default(Web)) coeffs(6, i1, i2) = -2._wp*i2/Web/rho - coeffs(7, i1, i2) = 0._wp - #:endif - else if (bubble_model == 2) then - ! KM with approximation of 1/(1-V/C) = 1+V/C - #:if not MFC_CASE_OPTIMIZATION or nterms > 7 - coeffs(1, i1, i2) = -3._wp*i2/2._wp - coeffs(2, i1, i2) = -i2/c - coeffs(3, i1, i2) = i2/(2._wp*c*c) - coeffs(4, i1, i2) = -i2*pres/rho - coeffs(5, i1, i2) = -2._wp*i2*pres/(c*rho) - coeffs(6, i1, i2) = -i2*pres/(c*c*rho) - coeffs(7, i1, i2) = i2/rho - coeffs(8, i1, i2) = 2._wp*i2/(c*rho) - coeffs(9, i1, i2) = i2/(c*c*rho) - coeffs(10, i1, i2) = -3._wp*i2*gam/(c*rho) - coeffs(11, i1, i2) = -3._wp*i2*gam/(c*c*rho) - coeffs(12, i1, i2) = i1 - coeffs(13, i1, i2) = 0._wp - coeffs(14, i1, i2) = 0._wp - coeffs(15, i1, i2) = 0._wp - if (.not. f_is_default(Re_inv)) coeffs(16, i1, i2) = -i2*4._wp*Re_inv/rho - if (.not. f_is_default(Web)) coeffs(17, i1, i2) = -i2*2._wp/Web/rho - if (.not. f_is_default(Re_inv)) then - coeffs(18, i1, i2) = i2*6._wp*Re_inv/(rho*c) - coeffs(19, i1, i2) = -i2*2._wp*Re_inv/(rho*c*c) - coeffs(20, i1, i2) = i2*4._wp*pres*Re_inv/(rho*rho*c) - coeffs(21, i1, i2) = i2*4._wp*pres*Re_inv/(rho*rho*c*c) - coeffs(22, i1, i2) = -i2*4._wp*Re_inv/(rho*rho*c) - coeffs(23, i1, i2) = -i2*4._wp*Re_inv/(rho*rho*c*c) - coeffs(24, i1, i2) = i2*16._wp*Re_inv*Re_inv/(rho*rho*c) - if (.not. f_is_default(Web)) then - coeffs(25, i1, i2) = i2*8._wp*Re_inv/Web/(rho*rho*c) + if ((i1 + i2) <= 2) then + if (bubble_model == 3) then + #:if not MFC_CASE_OPTIMIZATION or nterms > 1 + ! RPE + coeffs(1, i1, i2) = -1._wp*i2*pres/rho + coeffs(2, i1, i2) = -3._wp*i2/2._wp + coeffs(3, i1, i2) = i2/rho + coeffs(4, i1, i2) = i1 + if (.not. f_is_default(Re_inv)) coeffs(5, i1, i2) = -4._wp*i2*Re_inv/rho + if (.not. f_is_default(Web)) coeffs(6, i1, i2) = -2._wp*i2/Web/rho + coeffs(7, i1, i2) = 0._wp + #:endif + else if (bubble_model == 2) then + ! KM with approximation of 1/(1-V/C) = 1+V/C + #:if not MFC_CASE_OPTIMIZATION or nterms > 7 + coeffs(1, i1, i2) = -3._wp*i2/2._wp + coeffs(2, i1, i2) = -i2/c + coeffs(3, i1, i2) = i2/(2._wp*c*c) + coeffs(4, i1, i2) = -i2*pres/rho + coeffs(5, i1, i2) = -2._wp*i2*pres/(c*rho) + coeffs(6, i1, i2) = -i2*pres/(c*c*rho) + coeffs(7, i1, i2) = i2/rho + coeffs(8, i1, i2) = 2._wp*i2/(c*rho) + coeffs(9, i1, i2) = i2/(c*c*rho) + coeffs(10, i1, i2) = -3._wp*i2*gam/(c*rho) + coeffs(11, i1, i2) = -3._wp*i2*gam/(c*c*rho) + coeffs(12, i1, i2) = i1 + coeffs(13, i1, i2) = 0._wp + coeffs(14, i1, i2) = 0._wp + coeffs(15, i1, i2) = 0._wp + if (.not. f_is_default(Re_inv)) coeffs(16, i1, i2) = -i2*4._wp*Re_inv/rho + if (.not. f_is_default(Web)) coeffs(17, i1, i2) = -i2*2._wp/Web/rho + if (.not. f_is_default(Re_inv)) then + coeffs(18, i1, i2) = i2*6._wp*Re_inv/(rho*c) + coeffs(19, i1, i2) = -i2*2._wp*Re_inv/(rho*c*c) + coeffs(20, i1, i2) = i2*4._wp*pres*Re_inv/(rho*rho*c) + coeffs(21, i1, i2) = i2*4._wp*pres*Re_inv/(rho*rho*c*c) + coeffs(22, i1, i2) = -i2*4._wp*Re_inv/(rho*rho*c) + coeffs(23, i1, i2) = -i2*4._wp*Re_inv/(rho*rho*c*c) + coeffs(24, i1, i2) = i2*16._wp*Re_inv*Re_inv/(rho*rho*c) + if (.not. f_is_default(Web)) then + coeffs(25, i1, i2) = i2*8._wp*Re_inv/Web/(rho*rho*c) + end if + coeffs(26, i1, i2) = -12._wp*i2*gam*Re_inv/(rho*rho*c*c) end if - coeffs(26, i1, i2) = -12._wp*i2*gam*Re_inv/(rho*rho*c*c) - end if - coeffs(27, i1, i2) = 3._wp*i2*gam*R_v*Tw/(c*rho) - coeffs(28, i1, i2) = 3._wp*i2*gam*R_v*Tw/(c*c*rho) - if (.not. f_is_default(Re_inv)) then - coeffs(29, i1, i2) = 12._wp*i2*gam*R_v*Tw*Re_inv/(rho*rho*c*c) - end if - coeffs(30, i1, i2) = 3._wp*i2*gam/(c*rho) - coeffs(31, i1, i2) = 3._wp*i2*gam/(c*c*rho) - if (.not. f_is_default(Re_inv)) then - coeffs(32, i1, i2) = 12._wp*i2*gam*Re_inv/(rho*rho*c*c) - end if - #:endif + coeffs(27, i1, i2) = 3._wp*i2*gam*R_v*Tw/(c*rho) + coeffs(28, i1, i2) = 3._wp*i2*gam*R_v*Tw/(c*c*rho) + if (.not. f_is_default(Re_inv)) then + coeffs(29, i1, i2) = 12._wp*i2*gam*R_v*Tw*Re_inv/(rho*rho*c*c) + end if + coeffs(30, i1, i2) = 3._wp*i2*gam/(c*rho) + coeffs(31, i1, i2) = 3._wp*i2*gam/(c*c*rho) + if (.not. f_is_default(Re_inv)) then + coeffs(32, i1, i2) = 12._wp*i2*gam*Re_inv/(rho*rho*c*c) + end if + #:endif + end if end if - end if - end do; end do + end do; end do end subroutine s_coeff_nonpoly - !> Build the coefficient array for the polytropic bubble model + !> @brief Builds the coefficient array for the polytropic bubble model. subroutine s_coeff(pres, rho, c, coeffs) - - $:GPU_ROUTINE(function_name='s_coeff',parallelism='[seq]', cray_inline=True) + $:GPU_ROUTINE(function_name='s_coeff',parallelism='[seq]', & + & cray_inline=True) real(wp), intent(in) :: pres, rho, c #:if USING_AMD - real(wp), dimension(32,0:2,0:2), intent(out) :: coeffs + real(wp), dimension(32, 0:2, 0:2), intent(out) :: coeffs #:else - real(wp), dimension(nterms,0:2,0:2), intent(out) :: coeffs + real(wp), dimension(nterms, 0:2, 0:2), intent(out) :: coeffs #:endif integer :: i1, i2 - coeffs(:,:,:) = 0._wp + coeffs(:, :, :) = 0._wp do i2 = 0, 2; do i1 = 0, 2 - if ((i1 + i2) <= 2) then - if (bubble_model == 3) then - ! RPE - #:if not MFC_CASE_OPTIMIZATION or nterms > 1 - coeffs(1, i1, i2) = -1._wp*i2*pres/rho - coeffs(2, i1, i2) = -3._wp*i2/2._wp - coeffs(3, i1, i2) = i2/rho - coeffs(4, i1, i2) = i1 - if (.not. f_is_default(Re_inv)) coeffs(5, i1, i2) = -4._wp*i2*Re_inv/rho - if (.not. f_is_default(Web)) coeffs(6, i1, i2) = -2._wp*i2/Web/rho - coeffs(7, i1, i2) = i2*pv/rho - #:endif - else if (bubble_model == 2) then - ! KM with approximation of 1/(1-V/C) = 1+V/C - #:if not MFC_CASE_OPTIMIZATION or nterms > 7 - coeffs(1, i1, i2) = -3._wp*i2/2._wp - coeffs(2, i1, i2) = -i2/c - coeffs(3, i1, i2) = i2/(2._wp*c*c) - coeffs(4, i1, i2) = -i2*pres/rho - coeffs(5, i1, i2) = -2._wp*i2*pres/(c*rho) - coeffs(6, i1, i2) = -i2*pres/(c*c*rho) - coeffs(7, i1, i2) = i2/rho - coeffs(8, i1, i2) = 2._wp*i2/(c*rho) - coeffs(9, i1, i2) = i2/(c*c*rho) - coeffs(10, i1, i2) = -3._wp*i2*gam/(c*rho) - coeffs(11, i1, i2) = -3._wp*i2*gam/(c*c*rho) - coeffs(12, i1, i2) = i1 - coeffs(13, i1, i2) = i2*(pv)/rho - coeffs(14, i1, i2) = 2._wp*i2*(pv)/(c*rho) - coeffs(15, i1, i2) = i2*(pv)/(c*c*rho) - if (.not. f_is_default(Re_inv)) coeffs(16, i1, i2) = -i2*4._wp*Re_inv/rho - if (.not. f_is_default(Web)) coeffs(17, i1, i2) = -i2*2._wp/Web/rho - if (.not. f_is_default(Re_inv)) then - coeffs(18, i1, i2) = i2*6._wp*Re_inv/(rho*c) - coeffs(19, i1, i2) = -i2*2._wp*Re_inv/(rho*c*c) - coeffs(20, i1, i2) = i2*4._wp*pres*Re_inv/(rho*rho*c) - coeffs(21, i1, i2) = i2*4._wp*pres*Re_inv/(rho*rho*c*c) - coeffs(22, i1, i2) = -i2*4._wp*Re_inv/(rho*rho*c) - coeffs(23, i1, i2) = -i2*4._wp*Re_inv/(rho*rho*c*c) - coeffs(24, i1, i2) = i2*16._wp*Re_inv*Re_inv/(rho*rho*c) - if (.not. f_is_default(Web)) then - coeffs(25, i1, i2) = i2*8._wp*Re_inv/Web/(rho*rho*c) + if ((i1 + i2) <= 2) then + if (bubble_model == 3) then + ! RPE + #:if not MFC_CASE_OPTIMIZATION or nterms > 1 + coeffs(1, i1, i2) = -1._wp*i2*pres/rho + coeffs(2, i1, i2) = -3._wp*i2/2._wp + coeffs(3, i1, i2) = i2/rho + coeffs(4, i1, i2) = i1 + if (.not. f_is_default(Re_inv)) coeffs(5, i1, i2) = -4._wp*i2*Re_inv/rho + if (.not. f_is_default(Web)) coeffs(6, i1, i2) = -2._wp*i2/Web/rho + coeffs(7, i1, i2) = i2*pv/rho + #:endif + else if (bubble_model == 2) then + ! KM with approximation of 1/(1-V/C) = 1+V/C + #:if not MFC_CASE_OPTIMIZATION or nterms > 7 + coeffs(1, i1, i2) = -3._wp*i2/2._wp + coeffs(2, i1, i2) = -i2/c + coeffs(3, i1, i2) = i2/(2._wp*c*c) + coeffs(4, i1, i2) = -i2*pres/rho + coeffs(5, i1, i2) = -2._wp*i2*pres/(c*rho) + coeffs(6, i1, i2) = -i2*pres/(c*c*rho) + coeffs(7, i1, i2) = i2/rho + coeffs(8, i1, i2) = 2._wp*i2/(c*rho) + coeffs(9, i1, i2) = i2/(c*c*rho) + coeffs(10, i1, i2) = -3._wp*i2*gam/(c*rho) + coeffs(11, i1, i2) = -3._wp*i2*gam/(c*c*rho) + coeffs(12, i1, i2) = i1 + coeffs(13, i1, i2) = i2*(pv)/rho + coeffs(14, i1, i2) = 2._wp*i2*(pv)/(c*rho) + coeffs(15, i1, i2) = i2*(pv)/(c*c*rho) + if (.not. f_is_default(Re_inv)) coeffs(16, i1, i2) = -i2*4._wp*Re_inv/rho + if (.not. f_is_default(Web)) coeffs(17, i1, i2) = -i2*2._wp/Web/rho + if (.not. f_is_default(Re_inv)) then + coeffs(18, i1, i2) = i2*6._wp*Re_inv/(rho*c) + coeffs(19, i1, i2) = -i2*2._wp*Re_inv/(rho*c*c) + coeffs(20, i1, i2) = i2*4._wp*pres*Re_inv/(rho*rho*c) + coeffs(21, i1, i2) = i2*4._wp*pres*Re_inv/(rho*rho*c*c) + coeffs(22, i1, i2) = -i2*4._wp*Re_inv/(rho*rho*c) + coeffs(23, i1, i2) = -i2*4._wp*Re_inv/(rho*rho*c*c) + coeffs(24, i1, i2) = i2*16._wp*Re_inv*Re_inv/(rho*rho*c) + if (.not. f_is_default(Web)) then + coeffs(25, i1, i2) = i2*8._wp*Re_inv/Web/(rho*rho*c) + end if + coeffs(26, i1, i2) = -12._wp*i2*gam*Re_inv/(rho*rho*c*c) end if - coeffs(26, i1, i2) = -12._wp*i2*gam*Re_inv/(rho*rho*c*c) - end if - #:endif + #:endif + end if end if - end if - end do; end do + end do; end do end subroutine s_coeff - !> Perform moment inversion to recover quadrature weights and abscissas and evaluate bubble source terms + !> @brief Performs moment inversion to recover quadrature weights and abscissas and evaluates bubble source terms. subroutine s_mom_inv(q_cons_vf, q_prim_vf, momsp, moms3d, pb, rhs_pb, mv, rhs_mv, ix, iy, iz) - type(scalar_field), dimension(:), intent(inout) :: q_cons_vf, q_prim_vf - type(scalar_field), dimension(:), intent(inout) :: momsp - type(scalar_field), dimension(0:,0:,:), intent(inout) :: moms3d - real(stp), dimension(idwbuff(1)%beg:,idwbuff(2)%beg:,idwbuff(3)%beg:,1:,1:), intent(inout) :: pb - real(wp), dimension(idwbuff(1)%beg:,idwbuff(2)%beg:,idwbuff(3)%beg:,1:,1:), intent(inout) :: rhs_pb - real(stp), dimension(idwbuff(1)%beg:,idwbuff(2)%beg:,idwbuff(3)%beg:,1:,1:), intent(inout) :: mv - real(wp), dimension(idwbuff(1)%beg:,idwbuff(2)%beg:,idwbuff(3)%beg:,1:,1:), intent(inout) :: rhs_mv - type(int_bounds_info), intent(in) :: ix, iy, iz - + type(scalar_field), dimension(:), intent(inout) :: q_cons_vf, q_prim_vf + type(scalar_field), dimension(:), intent(inout) :: momsp + type(scalar_field), dimension(0:, 0:, :), intent(inout) :: moms3d + real(stp), dimension(idwbuff(1)%beg:, idwbuff(2)%beg:, idwbuff(3)%beg:, 1:, 1:), intent(inout) :: pb + real(wp), dimension(idwbuff(1)%beg:, idwbuff(2)%beg:, idwbuff(3)%beg:, 1:, 1:), intent(inout) :: rhs_pb + real(stp), dimension(idwbuff(1)%beg:, idwbuff(2)%beg:, idwbuff(3)%beg:, 1:, 1:), intent(inout) :: mv + real(wp), dimension(idwbuff(1)%beg:, idwbuff(2)%beg:, idwbuff(3)%beg:, 1:, 1:), intent(inout) :: rhs_mv + type(int_bounds_info), intent(in) :: ix, iy, iz #:if not MFC_CASE_OPTIMIZATION and USING_AMD - real(wp), dimension(6) :: moms, msum + real(wp), dimension(6) :: moms, msum real(wp), dimension(4, 3) :: wght, abscX, abscY, wght_pb, wght_mv, wght_ht, ht #:else - real(wp), dimension(nmom) :: moms, msum + real(wp), dimension(nmom) :: moms, msum real(wp), dimension(nnode, nb) :: wght, abscX, abscY, wght_pb, wght_mv, wght_ht, ht #:endif #:if USING_AMD - real(wp), dimension(32,0:2,0:2) :: coeff + real(wp), dimension(32, 0:2, 0:2) :: coeff #:else - real(wp), dimension(nterms,0:2,0:2) :: coeff + real(wp), dimension(nterms, 0:2, 0:2) :: coeff #:endif real(wp) :: pres, rho, nbub, c, alf, momsum, drdt, drdt2, chi_vw, x_vw, rho_mw, k_mw, grad_T real(wp) :: n_tait, B_tait - integer :: id1, id2, id3, i1, i2, j, q, r + integer :: id1, id2, id3, i1, i2, j, q, r is1_qbmm = ix; is2_qbmm = iy; is3_qbmm = iz - $:GPU_UPDATE(device='[is1_qbmm, is2_qbmm, is3_qbmm]') + $:GPU_UPDATE(device='[is1_qbmm,is2_qbmm,is3_qbmm]') - $:GPU_PARALLEL_LOOP(collapse=3, private='[id1, id2, id3, moms, msum, wght, abscX, abscY, wght_pb, wght_mv, wght_ht, & - & coeff, ht, r, q, n_tait, B_tait, pres, rho, nbub, c, alf, momsum, drdt, drdt2, chi_vw, x_vw, & - & rho_mw, k_mw, grad_T, i1, i2, j]') + $:GPU_PARALLEL_LOOP(collapse=3, private='[id1,id2,id3,moms, msum, wght, abscX, abscY, wght_pb, wght_mv, wght_ht, coeff, ht, r, q, n_tait, B_tait, pres, rho, nbub, c, alf, momsum, drdt, drdt2, chi_vw, x_vw, rho_mw, k_mw, grad_T, i1, i2, j]') do id3 = is3_qbmm%beg, is3_qbmm%end do id2 = is2_qbmm%beg, is2_qbmm%end do id1 = is1_qbmm%beg, is1_qbmm%end + alf = q_prim_vf(alf_idx)%sf(id1, id2, id3) pres = q_prim_vf(E_idx)%sf(id1, id2, id3) rho = q_prim_vf(contxb)%sf(id1, id2, id3) @@ -794,7 +773,7 @@ contains moms(r) = q_prim_vf(bubmoms(q, r))%sf(id1, id2, id3) end do moms(1) = 1._wp - call s_chyqmom(moms, wght(:,q), abscX(:,q), abscY(:,q)) + call s_chyqmom(moms, wght(:, q), abscX(:, q), abscY(:, q)) if (polytropic) then $:GPU_LOOP(parallelism='[seq]') @@ -806,16 +785,11 @@ contains do j = 1, nnode chi_vw = 1._wp/(1._wp + R_v/R_g*(pb(id1, id2, id3, j, q)/pv - 1._wp)) x_vw = M_g*chi_vw/(M_v + (M_g - M_v)*chi_vw) - k_mw = x_vw*k_v(q)/(x_vw + (1._wp - x_vw)*phi_vg) + (1._wp - x_vw)*k_g(q)/(x_vw*phi_gv & - & + 1._wp - x_vw) + k_mw = x_vw*k_v(q)/(x_vw + (1._wp - x_vw)*phi_vg) + (1._wp - x_vw)*k_g(q)/(x_vw*phi_gv + 1._wp - x_vw) rho_mw = pv/(chi_vw*R_v*Tw) - rhs_mv(id1, id2, id3, j, q) = -Re_trans_c(q)*((mv(id1, id2, id3, j, q)/(mv(id1, id2, id3, j, & - & q) + mass_g0(q))) - chi_vw) - rhs_mv(id1, id2, id3, j, q) = rho_mw*rhs_mv(id1, id2, id3, j, & - & q)/Pe_c/(1._wp - chi_vw)/abscX(j, q) - grad_T = -Re_trans_T(q)*((pb(id1, id2, id3, j, q)/pb0(q))*(abscX(j, & - & q)/R0(q))**3*(mass_g0(q) + mass_v0(q))/(mass_g0(q) + mv(id1, id2, id3, & - & j, q)) - 1._wp) + rhs_mv(id1, id2, id3, j, q) = -Re_trans_c(q)*((mv(id1, id2, id3, j, q)/(mv(id1, id2, id3, j, q) + mass_g0(q))) - chi_vw) + rhs_mv(id1, id2, id3, j, q) = rho_mw*rhs_mv(id1, id2, id3, j, q)/Pe_c/(1._wp - chi_vw)/abscX(j, q) + grad_T = -Re_trans_T(q)*((pb(id1, id2, id3, j, q)/pb0(q))*(abscX(j, q)/R0(q))**3*(mass_g0(q) + mass_v0(q))/(mass_g0(q) + mv(id1, id2, id3, j, q)) - 1._wp) ht(j, q) = pb0(q)*k_mw*grad_T/Pe_T(q)/abscX(j, q) wght_pb(j, q) = wght(j, q)*(pb(id1, id2, id3, j, q)) wght_mv(j, q) = wght(j, q)*(rhs_mv(id1, id2, id3, j, q)) @@ -836,32 +810,19 @@ contains select case (bubble_model) case (3) if (j == 3) then - momsum = momsum + coeff(j, i1, i2)*(R0(q)**momrhs(3, i1, i2, j, & - & q))*f_quad2D(abscX(:,q), abscY(:,q), wght_pb(:,q), & - & momrhs(:,i1, i2, j, q)) + momsum = momsum + coeff(j, i1, i2)*(R0(q)**momrhs(3, i1, i2, j, q))*f_quad2D(abscX(:, q), abscY(:, q), wght_pb(:, q), momrhs(:, i1, i2, j, q)) else - momsum = momsum + coeff(j, i1, i2)*(R0(q)**momrhs(3, i1, i2, j, & - & q))*f_quad2D(abscX(:,q), abscY(:,q), wght(:,q), & - & momrhs(:,i1, i2, j, q)) + momsum = momsum + coeff(j, i1, i2)*(R0(q)**momrhs(3, i1, i2, j, q))*f_quad2D(abscX(:, q), abscY(:, q), wght(:, q), momrhs(:, i1, i2, j, q)) end if case (2) - if ((j >= 7 .and. j <= 9) .or. (j >= 22 .and. j <= 23) & - & .or. (j >= 10 .and. j <= 11) .or. (j == 26)) then - momsum = momsum + coeff(j, i1, i2)*(R0(q)**momrhs(3, i1, i2, j, & - & q))*f_quad2D(abscX(:,q), abscY(:,q), wght_pb(:,q), & - & momrhs(:,i1, i2, j, q)) + if ((j >= 7 .and. j <= 9) .or. (j >= 22 .and. j <= 23) .or. (j >= 10 .and. j <= 11) .or. (j == 26)) then + momsum = momsum + coeff(j, i1, i2)*(R0(q)**momrhs(3, i1, i2, j, q))*f_quad2D(abscX(:, q), abscY(:, q), wght_pb(:, q), momrhs(:, i1, i2, j, q)) else if ((j >= 27 .and. j <= 29) .and. (.not. polytropic)) then - momsum = momsum + coeff(j, i1, i2)*(R0(q)**momrhs(3, i1, i2, j, & - & q))*f_quad2D(abscX(:,q), abscY(:,q), wght_mv(:,q), & - & momrhs(:,i1, i2, j, q)) + momsum = momsum + coeff(j, i1, i2)*(R0(q)**momrhs(3, i1, i2, j, q))*f_quad2D(abscX(:, q), abscY(:, q), wght_mv(:, q), momrhs(:, i1, i2, j, q)) else if ((j >= 30 .and. j <= 32) .and. (.not. polytropic)) then - momsum = momsum + coeff(j, i1, i2)*(R0(q)**momrhs(3, i1, i2, j, & - & q))*f_quad2D(abscX(:,q), abscY(:,q), wght_ht(:,q), & - & momrhs(:,i1, i2, j, q)) + momsum = momsum + coeff(j, i1, i2)*(R0(q)**momrhs(3, i1, i2, j, q))*f_quad2D(abscX(:, q), abscY(:, q), wght_ht(:, q), momrhs(:, i1, i2, j, q)) else - momsum = momsum + coeff(j, i1, i2)*(R0(q)**momrhs(3, i1, i2, j, & - & q))*f_quad2D(abscX(:,q), abscY(:,q), wght(:,q), & - & momrhs(:,i1, i2, j, q)) + momsum = momsum + coeff(j, i1, i2)*(R0(q)**momrhs(3, i1, i2, j, q))*f_quad2D(abscX(:, q), abscY(:, q), wght(:, q), momrhs(:, i1, i2, j, q)) end if end select end do @@ -877,15 +838,14 @@ contains $:GPU_LOOP(parallelism='[seq]') do j = 1, nnode drdt = msum(2) - drdt2 = merge(-1._wp, 1._wp, j == 1 .or. j == 2)/(2._wp*sqrt(merge(moms(4) - moms(2)**2._wp, & - & sgm_eps, moms(4) - moms(2)**2._wp > 0._wp))) + drdt2 = merge(-1._wp, 1._wp, j == 1 .or. j == 2)/(2._wp*sqrt(merge(moms(4) - moms(2)**2._wp, sgm_eps, moms(4) - moms(2)**2._wp > 0._wp))) drdt2 = drdt2*(msum(3) - 2._wp*moms(2)*msum(2)) drdt = drdt + drdt2 rhs_pb(id1, id2, id3, j, q) = (-3._wp*gam*drdt/abscX(j, q))*(pb(id1, id2, id3, j, q)) - rhs_pb(id1, id2, id3, j, q) = rhs_pb(id1, id2, id3, j, q) + (3._wp*gam/abscX(j, & - & q))*rhs_mv(id1, id2, id3, j, q)*R_v*Tw + rhs_pb(id1, id2, id3, j, q) = rhs_pb(id1, id2, id3, j, q) + (3._wp*gam/abscX(j, q))*rhs_mv(id1, id2, id3, j, q)*R_v*Tw rhs_pb(id1, id2, id3, j, q) = rhs_pb(id1, id2, id3, j, q) + (3._wp*gam/abscX(j, q))*ht(j, q) rhs_mv(id1, id2, id3, j, q) = rhs_mv(id1, id2, id3, j, q)*(4._wp*pi*abscX(j, q)**2._wp) + end do end if end do @@ -898,14 +858,9 @@ contains momsp(4)%sf(id1, id2, id3) = 1._wp else if (polytropic) then - momsp(4)%sf(id1, id2, id3) = f_quad(abscX, abscY, wght_pb, 3._wp*(1._wp - gam), 0._wp, & - & 3._wp*gam) + pv*f_quad(abscX, abscY, wght, 3._wp, 0._wp, & - & 0._wp) - 4._wp*Re_inv*f_quad(abscX, abscY, wght, 2._wp, 1._wp, & - & 0._wp) - (2._wp/Web)*f_quad(abscX, abscY, wght, 2._wp, 0._wp, 0._wp) + momsp(4)%sf(id1, id2, id3) = f_quad(abscX, abscY, wght_pb, 3._wp*(1._wp - gam), 0._wp, 3._wp*gam) + pv*f_quad(abscX, abscY, wght, 3._wp, 0._wp, 0._wp) - 4._wp*Re_inv*f_quad(abscX, abscY, wght, 2._wp, 1._wp, 0._wp) - (2._wp/Web)*f_quad(abscX, abscY, wght, 2._wp, 0._wp, 0._wp) else - momsp(4)%sf(id1, id2, id3) = f_quad(abscX, abscY, wght_pb, 3._wp, 0._wp, & - & 0._wp) - 4._wp*Re_inv*f_quad(abscX, abscY, wght, 2._wp, 1._wp, & - & 0._wp) - (2._wp/Web)*f_quad(abscX, abscY, wght, 2._wp, 0._wp, 0._wp) + momsp(4)%sf(id1, id2, id3) = f_quad(abscX, abscY, wght_pb, 3._wp, 0._wp, 0._wp) - 4._wp*Re_inv*f_quad(abscX, abscY, wght, 2._wp, 1._wp, 0._wp) - (2._wp/Web)*f_quad(abscX, abscY, wght, 2._wp, 0._wp, 0._wp) end if end if else @@ -930,15 +885,15 @@ contains $:END_GPU_PARALLEL_LOOP() contains - !> Select the polytropic or non-polytropic coefficient routine + !> @brief Selects the polytropic or non-polytropic coefficient routine. subroutine s_coeff_selector(pres, rho, c, coeff, polytropic) - - $:GPU_ROUTINE(function_name='s_coeff_selector',parallelism='[seq]', cray_inline=True) + $:GPU_ROUTINE(function_name='s_coeff_selector',parallelism='[seq]', & + & cray_inline=True) real(wp), intent(in) :: pres, rho, c #:if USING_AMD - real(wp), dimension(32,0:2,0:2), intent(out) :: coeff + real(wp), dimension(32, 0:2, 0:2), intent(out) :: coeff #:else - real(wp), dimension(nterms,0:2,0:2), intent(out) :: coeff + real(wp), dimension(nterms, 0:2, 0:2), intent(out) :: coeff #:endif logical, intent(in) :: polytropic if (polytropic) then @@ -946,23 +901,22 @@ contains else call s_coeff_nonpoly(pres, rho, c, coeff) end if - end subroutine s_coeff_selector - !> Perform CHyQMOM inversion for bivariate moments + !> @brief Performs conditional hyperbolic QMOM (CHyQMOM) inversion for bivariate moments. subroutine s_chyqmom(momin, wght, abscX, abscY) + $:GPU_ROUTINE(function_name='s_chyqmom',parallelism='[seq]', & + & cray_inline=True) - $:GPU_ROUTINE(function_name='s_chyqmom',parallelism='[seq]', cray_inline=True) - - real(wp), dimension(nmom), intent(in) :: momin + real(wp), dimension(nmom), intent(in) :: momin real(wp), dimension(nnode), intent(inout) :: wght, abscX, abscY ! Local variables - real(wp), dimension(0:2,0:2) :: moms - real(wp), dimension(3) :: M1, M3 - real(wp), dimension(2) :: myrho, myrho3, up, up3, Vf - real(wp) :: bu, bv, d20, d11, d_02, c20, c11, c02 - real(wp) :: mu2, vp21, vp22, rho21, rho22 + real(wp), dimension(0:2, 0:2) :: moms + real(wp), dimension(3) :: M1, M3 + real(wp), dimension(2) :: myrho, myrho3, up, up3, Vf + real(wp) :: bu, bv, d20, d11, d_02, c20, c11, c02 + real(wp) :: mu2, vp21, vp22, rho21, rho22 ! Assign moments to 2D array for clarity moms(0, 0) = momin(1) @@ -1008,29 +962,29 @@ contains end subroutine s_chyqmom - !> Perform HyQMOM inversion for univariate moments + !> @brief Performs hyperbolic QMOM (HyQMOM) inversion for univariate moments. subroutine s_hyqmom(frho, fup, fmom) - - $:GPU_ROUTINE(function_name='s_hyqmom',parallelism='[seq]', cray_inline=True) + $:GPU_ROUTINE(function_name='s_hyqmom',parallelism='[seq]', & + & cray_inline=True) real(wp), dimension(2), intent(inout) :: frho, fup - real(wp), dimension(3), intent(in) :: fmom - real(wp) :: bu, d2, c2 + real(wp), dimension(3), intent(in) :: fmom + + real(wp) :: bu, d2, c2 bu = fmom(2)/fmom(1) d2 = fmom(3)/fmom(1) c2 = d2 - bu**2._wp - frho(1) = fmom(1)/2._wp - frho(2) = fmom(1)/2._wp + frho(1) = fmom(1)/2._wp; + frho(2) = fmom(1)/2._wp; c2 = maxval((/c2, sgm_eps/)) fup(1) = bu - sqrt(c2) fup(2) = bu + sqrt(c2) end subroutine s_hyqmom - !> Evaluate a weighted quadrature sum over all bubble size bins and nodes + !> @brief Evaluates a weighted quadrature sum over all bubble size bins and nodes. function f_quad(abscX, abscY, wght_in, q, r, s) - $:GPU_ROUTINE(parallelism='[seq]') #:if not MFC_CASE_OPTIMIZATION and USING_AMD real(wp), dimension(4, 3), intent(in) :: abscX, abscY, wght_in @@ -1038,8 +992,9 @@ contains real(wp), dimension(nnode, nb), intent(in) :: abscX, abscY, wght_in #:endif real(wp), intent(in) :: q, r, s - real(wp) :: f_quad_RV, f_quad - integer :: i, i1 + + real(wp) :: f_quad_RV, f_quad + integer :: i, i1 f_quad = 0._wp $:GPU_LOOP(parallelism='[seq]') @@ -1054,9 +1009,8 @@ contains end function f_quad - !> Evaluate a weighted 2D quadrature sum over quadrature nodes for a single size bin + !> @brief Evaluates a weighted 2D quadrature sum over quadrature nodes for a single size bin. function f_quad2D(abscX, abscY, wght_in, pow) - $:GPU_ROUTINE(parallelism='[seq]') #:if not MFC_CASE_OPTIMIZATION and USING_AMD real(wp), dimension(4), intent(in) :: abscX, abscY, wght_in @@ -1064,15 +1018,15 @@ contains real(wp), dimension(nnode), intent(in) :: abscX, abscY, wght_in #:endif real(wp), dimension(3), intent(in) :: pow - real(wp) :: f_quad2D - integer :: i + + real(wp) :: f_quad2D + integer :: i f_quad2D = 0._wp $:GPU_LOOP(parallelism='[seq]') do i = 1, nnode f_quad2D = f_quad2D + wght_in(i)*(abscX(i)**pow(1))*(abscY(i)**pow(2)) end do - end function f_quad2D end subroutine s_mom_inv diff --git a/src/simulation/m_rhs.fpp b/src/simulation/m_rhs.fpp index 1f347a0289..0b0d29d53b 100644 --- a/src/simulation/m_rhs.fpp +++ b/src/simulation/m_rhs.fpp @@ -5,109 +5,150 @@ #:include 'case.fpp' #:include 'macros.fpp' -!> @brief Assembles the right-hand side of the governing equations using finite-volume flux differencing, Riemann solvers, and -!! physical source terms +!> @brief Assembles the right-hand side of the governing equations using finite-volume flux differencing, Riemann solvers, and physical source terms module m_rhs - use m_derived_types - use m_global_parameters - use m_mpi_proxy - use m_variables_conversion - use m_weno - use m_muscl - use m_riemann_solvers - use m_cbc - use m_bubbles_EE + use m_derived_types !< Definitions of the derived types + + use m_global_parameters !< Definitions of the global parameters + + use m_mpi_proxy !< Message passing interface (MPI) module proxy + + use m_variables_conversion !< State variables type conversion procedures + + use m_weno !< Weighted and essentially non-oscillatory (WENO) + !! schemes for spatial reconstruction of variables + + use m_muscl !< Monotonic Upstream-centered (MUSCL) + !! schemes for conservation laws + + use m_riemann_solvers !< Exact and approximate Riemann problem solvers + + use m_cbc !< Characteristic boundary conditions (CBC) + + use m_bubbles_EE !< Ensemble-averaged bubble dynamics routines + use m_bubbles_EL - use m_qbmm + + use m_qbmm !< Moment inversion + use m_hypoelastic + use m_hyperelastic + use m_acoustic_src + use m_viscous + use m_ibm + use m_nvtx + use m_boundary_common + use m_helper + use m_surface_tension + use m_body_forces + use m_chemistry + use m_igr + use m_pressure_relaxation implicit none - private; public :: s_initialize_rhs_module, s_compute_rhs, s_finalize_rhs_module + private; public :: s_initialize_rhs_module, & + s_compute_rhs, & + s_finalize_rhs_module - type(vector_field) :: q_cons_qp !< WENO-reconstructed cell-average conservative variables at quadrature points + !! This variable contains the WENO-reconstructed values of the cell-average + !! conservative variables, which are located in q_cons_vf, at cell-interior + !! Gaussian quadrature points (QP). + type(vector_field) :: q_cons_qp !< $:GPU_DECLARE(create='[q_cons_qp]') - type(vector_field) :: q_prim_qp !< Primitive variables at cell-interior quadrature points + !! The primitive variables at cell-interior Gaussian quadrature points. These + !! are calculated from the conservative variables and gradient magnitude (GM) + !! of the volume fractions, q_cons_qp and gm_alpha_qp, respectively. + type(vector_field) :: q_prim_qp !< $:GPU_DECLARE(create='[q_prim_qp]') - !> @name The first-order spatial derivatives of the primitive variables at cell- interior Gaussian quadrature points. These are - !! WENO-reconstructed from their respective cell-average values, obtained through the application of the divergence theorem on - !! the integral-average cell-boundary values of the primitive variables, located in qK_prim_n, where K = L or R. + !> @name The first-order spatial derivatives of the primitive variables at cell- + !! interior Gaussian quadrature points. These are WENO-reconstructed from + !! their respective cell-average values, obtained through the application + !! of the divergence theorem on the integral-average cell-boundary values + !! of the primitive variables, located in qK_prim_n, where K = L or R. !> @{ type(vector_field), allocatable, dimension(:) :: dq_prim_dx_qp, dq_prim_dy_qp, dq_prim_dz_qp - $:GPU_DECLARE(create='[dq_prim_dx_qp, dq_prim_dy_qp, dq_prim_dz_qp]') + $:GPU_DECLARE(create='[dq_prim_dx_qp,dq_prim_dy_qp,dq_prim_dz_qp]') !> @} - !> @name The left and right WENO-reconstructed cell-boundary values of the cell- average first-order spatial derivatives of the - !! primitive variables. The cell-average of the first-order spatial derivatives may be found in the variables dq_prim_ds_qp, - !! where s = x, y or z. + !> @name The left and right WENO-reconstructed cell-boundary values of the cell- + !! average first-order spatial derivatives of the primitive variables. The + !! cell-average of the first-order spatial derivatives may be found in the + !! variables dq_prim_ds_qp, where s = x, y or z. !> @{ type(vector_field), allocatable, dimension(:) :: dqL_prim_dx_n, dqL_prim_dy_n, dqL_prim_dz_n type(vector_field), allocatable, dimension(:) :: dqR_prim_dx_n, dqR_prim_dy_n, dqR_prim_dz_n #if defined(MFC_OpenACC) - $:GPU_DECLARE(create='[dqL_prim_dx_n, dqL_prim_dy_n, dqL_prim_dz_n]') - $:GPU_DECLARE(create='[dqR_prim_dx_n, dqR_prim_dy_n, dqR_prim_dz_n]') + $:GPU_DECLARE(create='[dqL_prim_dx_n,dqL_prim_dy_n,dqL_prim_dz_n]') + $:GPU_DECLARE(create='[dqR_prim_dx_n,dqR_prim_dy_n,dqR_prim_dz_n]') #endif !> @} type(scalar_field), allocatable, dimension(:) :: tau_Re_vf $:GPU_DECLARE(create='[tau_Re_vf]') - type(vector_field) :: gm_alpha_qp !< Volume fraction gradient magnitudes at cell-interior quadrature points + type(vector_field) :: gm_alpha_qp !< + !! The gradient magnitude of the volume fractions at cell-interior Gaussian + !! quadrature points. gm_alpha_qp is calculated from individual first-order + !! spatial derivatives located in dq_prim_ds_qp. + $:GPU_DECLARE(create='[gm_alpha_qp]') - !> @name The left and right WENO-reconstructed cell-boundary values of the cell- average gradient magnitude of volume fractions, - !! located in gm_alpha_qp. + !> @name The left and right WENO-reconstructed cell-boundary values of the cell- + !! average gradient magnitude of volume fractions, located in gm_alpha_qp. !> @{ type(vector_field), allocatable, dimension(:) :: gm_alphaL_n type(vector_field), allocatable, dimension(:) :: gm_alphaR_n #if defined(MFC_OpenACC) - $:GPU_DECLARE(create='[gm_alphaL_n, gm_alphaR_n]') + $:GPU_DECLARE(create='[gm_alphaL_n,gm_alphaR_n]') #endif !> @} - !> @name The cell-boundary values of the fluxes (src - source, gsrc - geometrical source). These are computed by applying the - !! chosen Riemann problem solver .on the left and right cell-boundary values of the primitive variables + !> @name The cell-boundary values of the fluxes (src - source, gsrc - geometrical + !! source). These are computed by applying the chosen Riemann problem solver + !! .on the left and right cell-boundary values of the primitive variables !> @{ type(vector_field), allocatable, dimension(:) :: flux_n type(vector_field), allocatable, dimension(:) :: flux_src_n type(vector_field), allocatable, dimension(:) :: flux_gsrc_n #if defined(MFC_OpenACC) - $:GPU_DECLARE(create='[flux_n, flux_src_n, flux_gsrc_n]') + $:GPU_DECLARE(create='[flux_n,flux_src_n,flux_gsrc_n]') #endif + !> @} type(vector_field), allocatable, dimension(:) :: qL_prim, qR_prim #if defined(MFC_OpenACC) - $:GPU_DECLARE(create='[qL_prim, qR_prim]') + $:GPU_DECLARE(create='[qL_prim,qR_prim]') #endif - type(int_bounds_info) :: iv !< Vector field indical bounds + type(int_bounds_info) :: iv !< Vector field indical bounds $:GPU_DECLARE(create='[iv]') !> @name Indical bounds in the x-, y- and z-directions !> @{ type(int_bounds_info) :: irx, iry, irz - $:GPU_DECLARE(create='[irx, iry, irz]') + $:GPU_DECLARE(create='[irx,iry,irz]') type(int_bounds_info) :: is1, is2, is3 !> @} - $:GPU_DECLARE(create='[is1, is2, is3]') + $:GPU_DECLARE(create='[is1,is2,is3]') !> @name Saved fluxes for testing !> @{ @@ -115,22 +156,24 @@ module m_rhs !> @} $:GPU_DECLARE(create='[alf_sum]') - real(wp), allocatable, dimension(:,:,:) :: blkmod1, blkmod2, alpha1, alpha2, Kterm - real(wp), allocatable, dimension(:,:,:,:) :: qL_rsx_vf, qL_rsy_vf, qL_rsz_vf, qR_rsx_vf, qR_rsy_vf, qR_rsz_vf - real(wp), allocatable, dimension(:,:,:,:) :: dqL_rsx_vf, dqL_rsy_vf, dqL_rsz_vf, dqR_rsx_vf, dqR_rsy_vf, dqR_rsz_vf - $:GPU_DECLARE(create='[blkmod1, blkmod2, alpha1, alpha2, Kterm]') - $:GPU_DECLARE(create='[qL_rsx_vf, qL_rsy_vf, qL_rsz_vf, qR_rsx_vf, qR_rsy_vf, qR_rsz_vf]') - $:GPU_DECLARE(create='[dqL_rsx_vf, dqL_rsy_vf, dqL_rsz_vf, dqR_rsx_vf, dqR_rsy_vf, dqR_rsz_vf]') + real(wp), allocatable, dimension(:, :, :) :: blkmod1, blkmod2, alpha1, alpha2, Kterm + real(wp), allocatable, dimension(:, :, :, :) :: qL_rsx_vf, qL_rsy_vf, qL_rsz_vf, qR_rsx_vf, qR_rsy_vf, qR_rsz_vf + real(wp), allocatable, dimension(:, :, :, :) :: dqL_rsx_vf, dqL_rsy_vf, dqL_rsz_vf, dqR_rsx_vf, dqR_rsy_vf, dqR_rsz_vf + $:GPU_DECLARE(create='[blkmod1,blkmod2,alpha1,alpha2,Kterm]') + $:GPU_DECLARE(create='[qL_rsx_vf,qL_rsy_vf,qL_rsz_vf,qR_rsx_vf,qR_rsy_vf,qR_rsz_vf]') + $:GPU_DECLARE(create='[dqL_rsx_vf,dqL_rsy_vf,dqL_rsz_vf,dqR_rsx_vf,dqR_rsy_vf,dqR_rsz_vf]') - real(wp), allocatable, dimension(:,:,:) :: nbub !< Bubble number density + real(wp), allocatable, dimension(:, :, :) :: nbub !< Bubble number density $:GPU_DECLARE(create='[nbub]') contains - !> Initialize the RHS module + !> The computation of parameters, the allocation of memory, + !! the association of pointers and/or the execution of any + !! other procedures that are necessary to setup the module. impure subroutine s_initialize_rhs_module - integer :: i, j, k, l, id !< Generic loop iterators + integer :: i, j, k, l, id !< Generic loop iterators $:GPU_ENTER_DATA(copyin='[idwbuff]') $:GPU_UPDATE(device='[idwbuff]') @@ -140,27 +183,26 @@ contains if (.not. igr) then do l = 1, sys_size - @:ALLOCATE(q_cons_qp%vf(l)%sf(idwbuff(1)%beg:idwbuff(1)%end, idwbuff(2)%beg:idwbuff(2)%end, & - & idwbuff(3)%beg:idwbuff(3)%end)) + @:ALLOCATE(q_cons_qp%vf(l)%sf(idwbuff(1)%beg:idwbuff(1)%end, idwbuff(2)%beg:idwbuff(2)%end, idwbuff(3)%beg:idwbuff(3)%end)) end do do l = mom_idx%beg, E_idx - @:ALLOCATE(q_prim_qp%vf(l)%sf(idwbuff(1)%beg:idwbuff(1)%end, idwbuff(2)%beg:idwbuff(2)%end, & - & idwbuff(3)%beg:idwbuff(3)%end)) + @:ALLOCATE(q_prim_qp%vf(l)%sf(idwbuff(1)%beg:idwbuff(1)%end, idwbuff(2)%beg:idwbuff(2)%end, idwbuff(3)%beg:idwbuff(3)%end)) end do + end if if (surface_tension) then - ! This assumes that the color function advection equation is the last equation. If this changes then this logic will + ! This assumes that the color function advection equation is + ! the last equation. If this changes then this logic will ! need updated do l = adv_idx%end + 1, sys_size - 1 - @:ALLOCATE(q_prim_qp%vf(l)%sf(idwbuff(1)%beg:idwbuff(1)%end, idwbuff(2)%beg:idwbuff(2)%end, & - & idwbuff(3)%beg:idwbuff(3)%end)) + @:ALLOCATE(q_prim_qp%vf(l)%sf(idwbuff(1)%beg:idwbuff(1)%end, idwbuff(2)%beg:idwbuff(2)%end, idwbuff(3)%beg:idwbuff(3)%end)) end do else do l = adv_idx%end + 1, sys_size - @:ALLOCATE(q_prim_qp%vf(l)%sf(idwbuff(1)%beg:idwbuff(1)%end, idwbuff(2)%beg:idwbuff(2)%end, & - & idwbuff(3)%beg:idwbuff(3)%end)) + @:ALLOCATE(q_prim_qp%vf(l)%sf(idwbuff(1)%beg:idwbuff(1)%end, idwbuff(2)%beg:idwbuff(2)%end, idwbuff(3)%beg:idwbuff(3)%end)) end do + end if if (.not. igr) then @@ -169,8 +211,7 @@ contains do l = 1, cont_idx%end if (relativity) then ! Cons and Prim densities are different for relativity - @:ALLOCATE(q_prim_qp%vf(l)%sf(idwbuff(1)%beg:idwbuff(1)%end, idwbuff(2)%beg:idwbuff(2)%end, & - & idwbuff(3)%beg:idwbuff(3)%end)) + @:ALLOCATE(q_prim_qp%vf(l)%sf(idwbuff(1)%beg:idwbuff(1)%end, idwbuff(2)%beg:idwbuff(2)%end, idwbuff(3)%beg:idwbuff(3)%end)) else q_prim_qp%vf(l)%sf => q_cons_qp%vf(l)%sf $:GPU_ENTER_DATA(copyin='[q_prim_qp%vf(l)%sf]') @@ -186,66 +227,87 @@ contains end if if (surface_tension) then - q_prim_qp%vf(c_idx)%sf => q_cons_qp%vf(c_idx)%sf + q_prim_qp%vf(c_idx)%sf => & + q_cons_qp%vf(c_idx)%sf $:GPU_ENTER_DATA(copyin='[q_prim_qp%vf(c_idx)%sf]') $:GPU_ENTER_DATA(attach='[q_prim_qp%vf(c_idx)%sf]') end if if (hyper_cleaning) then - q_prim_qp%vf(psi_idx)%sf => q_cons_qp%vf(psi_idx)%sf + q_prim_qp%vf(psi_idx)%sf => & + q_cons_qp%vf(psi_idx)%sf $:GPU_ENTER_DATA(copyin='[q_prim_qp%vf(psi_idx)%sf]') $:GPU_ENTER_DATA(attach='[q_prim_qp%vf(psi_idx)%sf]') end if + ! Allocation/Association of flux_n, flux_src_n, and flux_gsrc_n if (.not. igr) then @:ALLOCATE(flux_n(1:num_dims)) @:ALLOCATE(flux_src_n(1:num_dims)) @:ALLOCATE(flux_gsrc_n(1:num_dims)) do i = 1, num_dims + @:ALLOCATE(flux_n(i)%vf(1:sys_size)) @:ALLOCATE(flux_src_n(i)%vf(1:sys_size)) @:ALLOCATE(flux_gsrc_n(i)%vf(1:sys_size)) if (i == 1) then do l = 1, sys_size - @:ALLOCATE(flux_n(i)%vf(l)%sf(idwbuff(1)%beg:idwbuff(1)%end, idwbuff(2)%beg:idwbuff(2)%end, & - & idwbuff(3)%beg:idwbuff(3)%end)) - @:ALLOCATE(flux_gsrc_n(i)%vf(l)%sf(idwbuff(1)%beg:idwbuff(1)%end, idwbuff(2)%beg:idwbuff(2)%end, & - & idwbuff(3)%beg:idwbuff(3)%end)) + @:ALLOCATE(flux_n(i)%vf(l)%sf( & + & idwbuff(1)%beg:idwbuff(1)%end, & + & idwbuff(2)%beg:idwbuff(2)%end, & + & idwbuff(3)%beg:idwbuff(3)%end)) + @:ALLOCATE(flux_gsrc_n(i)%vf(l)%sf( & + & idwbuff(1)%beg:idwbuff(1)%end, & + & idwbuff(2)%beg:idwbuff(2)%end, & + & idwbuff(3)%beg:idwbuff(3)%end)) end do if (viscous .or. surface_tension) then do l = mom_idx%beg, E_idx - @:ALLOCATE(flux_src_n(i)%vf(l)%sf(idwbuff(1)%beg:idwbuff(1)%end, idwbuff(2)%beg:idwbuff(2)%end, & - & idwbuff(3)%beg:idwbuff(3)%end)) + @:ALLOCATE(flux_src_n(i)%vf(l)%sf( & + & idwbuff(1)%beg:idwbuff(1)%end, & + & idwbuff(2)%beg:idwbuff(2)%end, & + & idwbuff(3)%beg:idwbuff(3)%end)) end do end if - @:ALLOCATE(flux_src_n(i)%vf(adv_idx%beg)%sf(idwbuff(1)%beg:idwbuff(1)%end, idwbuff(2)%beg:idwbuff(2)%end, & - & idwbuff(3)%beg:idwbuff(3)%end)) + @:ALLOCATE(flux_src_n(i)%vf(adv_idx%beg)%sf( & + & idwbuff(1)%beg:idwbuff(1)%end, & + & idwbuff(2)%beg:idwbuff(2)%end, & + & idwbuff(3)%beg:idwbuff(3)%end)) if (riemann_solver == 1 .or. riemann_solver == 4) then do l = adv_idx%beg + 1, adv_idx%end - @:ALLOCATE(flux_src_n(i)%vf(l)%sf(idwbuff(1)%beg:idwbuff(1)%end, idwbuff(2)%beg:idwbuff(2)%end, & - & idwbuff(3)%beg:idwbuff(3)%end)) + @:ALLOCATE(flux_src_n(i)%vf(l)%sf( & + & idwbuff(1)%beg:idwbuff(1)%end, & + & idwbuff(2)%beg:idwbuff(2)%end, & + & idwbuff(3)%beg:idwbuff(3)%end)) end do end if if (chemistry) then do l = chemxb, chemxe - @:ALLOCATE(flux_src_n(i)%vf(l)%sf(idwbuff(1)%beg:idwbuff(1)%end, idwbuff(2)%beg:idwbuff(2)%end, & - & idwbuff(3)%beg:idwbuff(3)%end)) + @:ALLOCATE(flux_src_n(i)%vf(l)%sf( & + & idwbuff(1)%beg:idwbuff(1)%end, & + & idwbuff(2)%beg:idwbuff(2)%end, & + & idwbuff(3)%beg:idwbuff(3)%end)) end do if (chem_params%diffusion .and. .not. viscous) then - @:ALLOCATE(flux_src_n(i)%vf(E_idx)%sf(idwbuff(1)%beg:idwbuff(1)%end, idwbuff(2)%beg:idwbuff(2)%end, & - & idwbuff(3)%beg:idwbuff(3)%end)) + @:ALLOCATE(flux_src_n(i)%vf(E_idx)%sf( & + & idwbuff(1)%beg:idwbuff(1)%end, & + & idwbuff(2)%beg:idwbuff(2)%end, & + & idwbuff(3)%beg:idwbuff(3)%end)) end if end if + else do l = 1, sys_size - @:ALLOCATE(flux_gsrc_n(i)%vf(l)%sf(idwbuff(1)%beg:idwbuff(1)%end, idwbuff(2)%beg:idwbuff(2)%end, & - & idwbuff(3)%beg:idwbuff(3)%end)) + @:ALLOCATE(flux_gsrc_n(i)%vf(l)%sf( & + idwbuff(1)%beg:idwbuff(1)%end, & + idwbuff(2)%beg:idwbuff(2)%end, & + idwbuff(3)%beg:idwbuff(3)%end)) end do end if @@ -267,10 +329,14 @@ contains $:GPU_ENTER_DATA(attach='[flux_src_n(i)%vf(l)%sf]') end do end if + end do + ! END: Allocation/Association of flux_n, flux_src_n, and flux_gsrc_n end if if ((.not. igr) .or. dummy) then + + ! Allocation of dq_prim_ds_qp @:ALLOCATE(dq_prim_dx_qp(1:1)) @:ALLOCATE(dq_prim_dy_qp(1:1)) @:ALLOCATE(dq_prim_dz_qp(1:1)) @@ -278,6 +344,7 @@ contains @:ALLOCATE(qL_prim(1:num_dims)) @:ALLOCATE(qR_prim(1:num_dims)) + ! Allocation/Association of dqK_prim_ds_n @:ALLOCATE(dqL_prim_dx_n(1:num_dims)) @:ALLOCATE(dqL_prim_dy_n(1:num_dims)) @:ALLOCATE(dqL_prim_dz_n(1:num_dims)) @@ -289,41 +356,41 @@ contains @:ALLOCATE(qL_prim(i)%vf(1:sys_size)) @:ALLOCATE(qR_prim(i)%vf(1:sys_size)) do l = mom_idx%beg, mom_idx%end - @:ALLOCATE(qL_prim(i)%vf(l)%sf(idwbuff(1)%beg:idwbuff(1)%end, idwbuff(2)%beg:idwbuff(2)%end, & - & idwbuff(3)%beg:idwbuff(3)%end)) - @:ALLOCATE(qR_prim(i)%vf(l)%sf(idwbuff(1)%beg:idwbuff(1)%end, idwbuff(2)%beg:idwbuff(2)%end, & - & idwbuff(3)%beg:idwbuff(3)%end)) + @:ALLOCATE(qL_prim(i)%vf(l)%sf(idwbuff(1)%beg:idwbuff(1)%end, idwbuff(2)%beg:idwbuff(2)%end, idwbuff(3)%beg:idwbuff(3)%end)) + @:ALLOCATE(qR_prim(i)%vf(l)%sf(idwbuff(1)%beg:idwbuff(1)%end, idwbuff(2)%beg:idwbuff(2)%end, idwbuff(3)%beg:idwbuff(3)%end)) end do @:ACC_SETUP_VFs(qL_prim(i), qR_prim(i)) end do - @:ALLOCATE(qL_rsx_vf(idwbuff(1)%beg:idwbuff(1)%end, idwbuff(2)%beg:idwbuff(2)%end, idwbuff(3)%beg:idwbuff(3)%end, & - & 1:sys_size)) - @:ALLOCATE(qR_rsx_vf(idwbuff(1)%beg:idwbuff(1)%end, idwbuff(2)%beg:idwbuff(2)%end, idwbuff(3)%beg:idwbuff(3)%end, & - & 1:sys_size)) + @:ALLOCATE(qL_rsx_vf(idwbuff(1)%beg:idwbuff(1)%end, & + idwbuff(2)%beg:idwbuff(2)%end, idwbuff(3)%beg:idwbuff(3)%end, 1:sys_size)) + @:ALLOCATE(qR_rsx_vf(idwbuff(1)%beg:idwbuff(1)%end, & + idwbuff(2)%beg:idwbuff(2)%end, idwbuff(3)%beg:idwbuff(3)%end, 1:sys_size)) if (n > 0) then - @:ALLOCATE(qL_rsy_vf(idwbuff(2)%beg:idwbuff(2)%end, idwbuff(1)%beg:idwbuff(1)%end, idwbuff(3)%beg:idwbuff(3)%end, & - & 1:sys_size)) - @:ALLOCATE(qR_rsy_vf(idwbuff(2)%beg:idwbuff(2)%end, idwbuff(1)%beg:idwbuff(1)%end, idwbuff(3)%beg:idwbuff(3)%end, & - & 1:sys_size)) + + @:ALLOCATE(qL_rsy_vf(idwbuff(2)%beg:idwbuff(2)%end, & + idwbuff(1)%beg:idwbuff(1)%end, idwbuff(3)%beg:idwbuff(3)%end, 1:sys_size)) + @:ALLOCATE(qR_rsy_vf(idwbuff(2)%beg:idwbuff(2)%end, & + idwbuff(1)%beg:idwbuff(1)%end, idwbuff(3)%beg:idwbuff(3)%end, 1:sys_size)) else - @:ALLOCATE(qL_rsy_vf(idwbuff(1)%beg:idwbuff(1)%end, idwbuff(2)%beg:idwbuff(2)%end, idwbuff(3)%beg:idwbuff(3)%end, & - & 1:sys_size)) - @:ALLOCATE(qR_rsy_vf(idwbuff(1)%beg:idwbuff(1)%end, idwbuff(2)%beg:idwbuff(2)%end, idwbuff(3)%beg:idwbuff(3)%end, & - & 1:sys_size)) + @:ALLOCATE(qL_rsy_vf(idwbuff(1)%beg:idwbuff(1)%end, & + idwbuff(2)%beg:idwbuff(2)%end, idwbuff(3)%beg:idwbuff(3)%end, 1:sys_size)) + @:ALLOCATE(qR_rsy_vf(idwbuff(1)%beg:idwbuff(1)%end, & + idwbuff(2)%beg:idwbuff(2)%end, idwbuff(3)%beg:idwbuff(3)%end, 1:sys_size)) end if if (p > 0) then - @:ALLOCATE(qL_rsz_vf(idwbuff(3)%beg:idwbuff(3)%end, idwbuff(2)%beg:idwbuff(2)%end, idwbuff(1)%beg:idwbuff(1)%end, & - & 1:sys_size)) - @:ALLOCATE(qR_rsz_vf(idwbuff(3)%beg:idwbuff(3)%end, idwbuff(2)%beg:idwbuff(2)%end, idwbuff(1)%beg:idwbuff(1)%end, & - & 1:sys_size)) + @:ALLOCATE(qL_rsz_vf(idwbuff(3)%beg:idwbuff(3)%end, & + idwbuff(2)%beg:idwbuff(2)%end, idwbuff(1)%beg:idwbuff(1)%end, 1:sys_size)) + @:ALLOCATE(qR_rsz_vf(idwbuff(3)%beg:idwbuff(3)%end, & + idwbuff(2)%beg:idwbuff(2)%end, idwbuff(1)%beg:idwbuff(1)%end, 1:sys_size)) else - @:ALLOCATE(qL_rsz_vf(idwbuff(1)%beg:idwbuff(1)%end, idwbuff(2)%beg:idwbuff(2)%end, idwbuff(3)%beg:idwbuff(3)%end, & - & 1:sys_size)) - @:ALLOCATE(qR_rsz_vf(idwbuff(1)%beg:idwbuff(1)%end, idwbuff(2)%beg:idwbuff(2)%end, idwbuff(3)%beg:idwbuff(3)%end, & - & 1:sys_size)) + @:ALLOCATE(qL_rsz_vf(idwbuff(1)%beg:idwbuff(1)%end, & + idwbuff(2)%beg:idwbuff(2)%end, idwbuff(3)%beg:idwbuff(3)%end, 1:sys_size)) + @:ALLOCATE(qR_rsz_vf(idwbuff(1)%beg:idwbuff(1)%end, & + idwbuff(2)%beg:idwbuff(2)%end, idwbuff(3)%beg:idwbuff(3)%end, 1:sys_size)) + end if if (.not. viscous) then @@ -349,14 +416,17 @@ contains end if if (viscous) then + @:ALLOCATE(tau_Re_vf(1:sys_size)) do i = 1, num_dims - @:ALLOCATE(tau_Re_vf(cont_idx%end + i)%sf(idwbuff(1)%beg:idwbuff(1)%end, idwbuff(2)%beg:idwbuff(2)%end, & - & idwbuff(3)%beg:idwbuff(3)%end)) + @:ALLOCATE(tau_Re_vf(cont_idx%end + i)%sf(idwbuff(1)%beg:idwbuff(1)%end, & + & idwbuff(2)%beg:idwbuff(2)%end, & + & idwbuff(3)%beg:idwbuff(3)%end)) @:ACC_SETUP_SFs(tau_Re_vf(cont_idx%end + i)) end do - @:ALLOCATE(tau_Re_vf(E_idx)%sf(idwbuff(1)%beg:idwbuff(1)%end, idwbuff(2)%beg:idwbuff(2)%end, & - & idwbuff(3)%beg:idwbuff(3)%end)) + @:ALLOCATE(tau_Re_vf(E_idx)%sf(idwbuff(1)%beg:idwbuff(1)%end, & + & idwbuff(2)%beg:idwbuff(2)%end, & + & idwbuff(3)%beg:idwbuff(3)%end)) @:ACC_SETUP_SFs(tau_Re_vf(E_idx)) @:ALLOCATE(dq_prim_dx_qp(1)%vf(1:sys_size)) @@ -364,27 +434,36 @@ contains @:ALLOCATE(dq_prim_dz_qp(1)%vf(1:sys_size)) do l = mom_idx%beg, mom_idx%end - @:ALLOCATE(dq_prim_dx_qp(1)%vf(l)%sf(idwbuff(1)%beg:idwbuff(1)%end, idwbuff(2)%beg:idwbuff(2)%end, & - & idwbuff(3)%beg:idwbuff(3)%end)) + @:ALLOCATE(dq_prim_dx_qp(1)%vf(l)%sf( & + & idwbuff(1)%beg:idwbuff(1)%end, & + & idwbuff(2)%beg:idwbuff(2)%end, & + & idwbuff(3)%beg:idwbuff(3)%end)) end do @:ACC_SETUP_VFs(dq_prim_dx_qp(1)) if (n > 0) then + do l = mom_idx%beg, mom_idx%end - @:ALLOCATE(dq_prim_dy_qp(1)%vf(l)%sf(idwbuff(1)%beg:idwbuff(1)%end, idwbuff(2)%beg:idwbuff(2)%end, & - & idwbuff(3)%beg:idwbuff(3)%end)) + @:ALLOCATE(dq_prim_dy_qp(1)%vf(l)%sf( & + & idwbuff(1)%beg:idwbuff(1)%end, & + & idwbuff(2)%beg:idwbuff(2)%end, & + & idwbuff(3)%beg:idwbuff(3)%end)) end do @:ACC_SETUP_VFs(dq_prim_dy_qp(1)) if (p > 0) then + do l = mom_idx%beg, mom_idx%end - @:ALLOCATE(dq_prim_dz_qp(1)%vf(l)%sf(idwbuff(1)%beg:idwbuff(1)%end, idwbuff(2)%beg:idwbuff(2)%end, & - & idwbuff(3)%beg:idwbuff(3)%end)) + @:ALLOCATE(dq_prim_dz_qp(1)%vf(l)%sf( & + & idwbuff(1)%beg:idwbuff(1)%end, & + & idwbuff(2)%beg:idwbuff(2)%end, & + & idwbuff(3)%beg:idwbuff(3)%end)) end do @:ACC_SETUP_VFs(dq_prim_dz_qp(1)) end if + end if do i = 1, num_dims @@ -397,28 +476,41 @@ contains end do do i = 1, num_dims + do l = mom_idx%beg, mom_idx%end - @:ALLOCATE(dqL_prim_dx_n(i)%vf(l)%sf(idwbuff(1)%beg:idwbuff(1)%end, idwbuff(2)%beg:idwbuff(2)%end, & - & idwbuff(3)%beg:idwbuff(3)%end)) - @:ALLOCATE(dqR_prim_dx_n(i)%vf(l)%sf(idwbuff(1)%beg:idwbuff(1)%end, idwbuff(2)%beg:idwbuff(2)%end, & - & idwbuff(3)%beg:idwbuff(3)%end)) + @:ALLOCATE(dqL_prim_dx_n(i)%vf(l)%sf( & + & idwbuff(1)%beg:idwbuff(1)%end, & + & idwbuff(2)%beg:idwbuff(2)%end, & + & idwbuff(3)%beg:idwbuff(3)%end)) + @:ALLOCATE(dqR_prim_dx_n(i)%vf(l)%sf( & + & idwbuff(1)%beg:idwbuff(1)%end, & + & idwbuff(2)%beg:idwbuff(2)%end, & + & idwbuff(3)%beg:idwbuff(3)%end)) end do if (n > 0) then do l = mom_idx%beg, mom_idx%end - @:ALLOCATE(dqL_prim_dy_n(i)%vf(l)%sf(idwbuff(1)%beg:idwbuff(1)%end, idwbuff(2)%beg:idwbuff(2)%end, & - & idwbuff(3)%beg:idwbuff(3)%end)) - @:ALLOCATE(dqR_prim_dy_n(i)%vf(l)%sf(idwbuff(1)%beg:idwbuff(1)%end, idwbuff(2)%beg:idwbuff(2)%end, & - & idwbuff(3)%beg:idwbuff(3)%end)) + @:ALLOCATE(dqL_prim_dy_n(i)%vf(l)%sf( & + & idwbuff(1)%beg:idwbuff(1)%end, & + & idwbuff(2)%beg:idwbuff(2)%end, & + & idwbuff(3)%beg:idwbuff(3)%end)) + @:ALLOCATE(dqR_prim_dy_n(i)%vf(l)%sf( & + & idwbuff(1)%beg:idwbuff(1)%end, & + & idwbuff(2)%beg:idwbuff(2)%end, & + & idwbuff(3)%beg:idwbuff(3)%end)) end do end if if (p > 0) then do l = mom_idx%beg, mom_idx%end - @:ALLOCATE(dqL_prim_dz_n(i)%vf(l)%sf(idwbuff(1)%beg:idwbuff(1)%end, idwbuff(2)%beg:idwbuff(2)%end, & - & idwbuff(3)%beg:idwbuff(3)%end)) - @:ALLOCATE(dqR_prim_dz_n(i)%vf(l)%sf(idwbuff(1)%beg:idwbuff(1)%end, idwbuff(2)%beg:idwbuff(2)%end, & - & idwbuff(3)%beg:idwbuff(3)%end)) + @:ALLOCATE(dqL_prim_dz_n(i)%vf(l)%sf( & + & idwbuff(1)%beg:idwbuff(1)%end, & + & idwbuff(2)%beg:idwbuff(2)%end, & + & idwbuff(3)%beg:idwbuff(3)%end)) + @:ALLOCATE(dqR_prim_dz_n(i)%vf(l)%sf( & + & idwbuff(1)%beg:idwbuff(1)%end, & + & idwbuff(2)%beg:idwbuff(2)%end, & + & idwbuff(3)%beg:idwbuff(3)%end)) end do end if @@ -427,35 +519,36 @@ contains end do if (weno_Re_flux) then - @:ALLOCATE(dqL_rsx_vf(idwbuff(1)%beg:idwbuff(1)%end, idwbuff(2)%beg:idwbuff(2)%end, & - & idwbuff(3)%beg:idwbuff(3)%end, mom_idx%beg:mom_idx%end)) - @:ALLOCATE(dqR_rsx_vf(idwbuff(1)%beg:idwbuff(1)%end, idwbuff(2)%beg:idwbuff(2)%end, & - & idwbuff(3)%beg:idwbuff(3)%end, mom_idx%beg:mom_idx%end)) + @:ALLOCATE(dqL_rsx_vf(idwbuff(1)%beg:idwbuff(1)%end, & + idwbuff(2)%beg:idwbuff(2)%end, idwbuff(3)%beg:idwbuff(3)%end, mom_idx%beg:mom_idx%end)) + @:ALLOCATE(dqR_rsx_vf(idwbuff(1)%beg:idwbuff(1)%end, & + idwbuff(2)%beg:idwbuff(2)%end, idwbuff(3)%beg:idwbuff(3)%end, mom_idx%beg:mom_idx%end)) if (n > 0) then - @:ALLOCATE(dqL_rsy_vf(idwbuff(2)%beg:idwbuff(2)%end, idwbuff(1)%beg:idwbuff(1)%end, & - & idwbuff(3)%beg:idwbuff(3)%end, mom_idx%beg:mom_idx%end)) - @:ALLOCATE(dqR_rsy_vf(idwbuff(2)%beg:idwbuff(2)%end, idwbuff(1)%beg:idwbuff(1)%end, & - & idwbuff(3)%beg:idwbuff(3)%end, mom_idx%beg:mom_idx%end)) + @:ALLOCATE(dqL_rsy_vf(idwbuff(2)%beg:idwbuff(2)%end, & + idwbuff(1)%beg:idwbuff(1)%end, idwbuff(3)%beg:idwbuff(3)%end, mom_idx%beg:mom_idx%end)) + @:ALLOCATE(dqR_rsy_vf(idwbuff(2)%beg:idwbuff(2)%end, & + idwbuff(1)%beg:idwbuff(1)%end, idwbuff(3)%beg:idwbuff(3)%end, mom_idx%beg:mom_idx%end)) else - @:ALLOCATE(dqL_rsy_vf(idwbuff(1)%beg:idwbuff(1)%end, idwbuff(2)%beg:idwbuff(2)%end, & - & idwbuff(3)%beg:idwbuff(3)%end, mom_idx%beg:mom_idx%end)) - @:ALLOCATE(dqR_rsy_vf(idwbuff(1)%beg:idwbuff(1)%end, idwbuff(2)%beg:idwbuff(2)%end, & - & idwbuff(3)%beg:idwbuff(3)%end, mom_idx%beg:mom_idx%end)) + @:ALLOCATE(dqL_rsy_vf(idwbuff(1)%beg:idwbuff(1)%end, & + idwbuff(2)%beg:idwbuff(2)%end, idwbuff(3)%beg:idwbuff(3)%end, mom_idx%beg:mom_idx%end)) + @:ALLOCATE(dqR_rsy_vf(idwbuff(1)%beg:idwbuff(1)%end, & + idwbuff(2)%beg:idwbuff(2)%end, idwbuff(3)%beg:idwbuff(3)%end, mom_idx%beg:mom_idx%end)) end if if (p > 0) then - @:ALLOCATE(dqL_rsz_vf(idwbuff(3)%beg:idwbuff(3)%end, idwbuff(2)%beg:idwbuff(2)%end, & - & idwbuff(1)%beg:idwbuff(1)%end, mom_idx%beg:mom_idx%end)) - @:ALLOCATE(dqR_rsz_vf(idwbuff(3)%beg:idwbuff(3)%end, idwbuff(2)%beg:idwbuff(2)%end, & - & idwbuff(1)%beg:idwbuff(1)%end, mom_idx%beg:mom_idx%end)) + @:ALLOCATE(dqL_rsz_vf(idwbuff(3)%beg:idwbuff(3)%end, & + idwbuff(2)%beg:idwbuff(2)%end, idwbuff(1)%beg:idwbuff(1)%end, mom_idx%beg:mom_idx%end)) + @:ALLOCATE(dqR_rsz_vf(idwbuff(3)%beg:idwbuff(3)%end, & + idwbuff(2)%beg:idwbuff(2)%end, idwbuff(1)%beg:idwbuff(1)%end, mom_idx%beg:mom_idx%end)) else - @:ALLOCATE(dqL_rsz_vf(idwbuff(1)%beg:idwbuff(1)%end, idwbuff(2)%beg:idwbuff(2)%end, & - & idwbuff(3)%beg:idwbuff(3)%end, mom_idx%beg:mom_idx%end)) - @:ALLOCATE(dqR_rsz_vf(idwbuff(1)%beg:idwbuff(1)%end, idwbuff(2)%beg:idwbuff(2)%end, & - & idwbuff(3)%beg:idwbuff(3)%end, mom_idx%beg:mom_idx%end)) + @:ALLOCATE(dqL_rsz_vf(idwbuff(1)%beg:idwbuff(1)%end, & + idwbuff(2)%beg:idwbuff(2)%end, idwbuff(3)%beg:idwbuff(3)%end, mom_idx%beg:mom_idx%end)) + @:ALLOCATE(dqR_rsz_vf(idwbuff(1)%beg:idwbuff(1)%end, & + idwbuff(2)%beg:idwbuff(2)%end, idwbuff(3)%beg:idwbuff(3)%end, mom_idx%beg:mom_idx%end)) end if - end if ! end allocation for weno_Re_flux + end if ! end allocation for weno_Re_flux + else @:ALLOCATE(dq_prim_dx_qp(1)%vf(1:sys_size)) @:ALLOCATE(dq_prim_dy_qp(1)%vf(1:sys_size)) @@ -473,9 +566,9 @@ contains end if end if end do - end if ! end allocation of viscous variables + end if ! end allocation of viscous variables - $:GPU_PARALLEL_LOOP(private='[i, j, k, l, id]', collapse=4) + $:GPU_PARALLEL_LOOP(private='[i,j,k,l,id]', collapse=4) do id = 1, num_dims do i = 1, sys_size do l = idwbuff(3)%beg, idwbuff(3)%end @@ -488,7 +581,8 @@ contains end do end do $:END_GPU_PARALLEL_LOOP() - end if ! end allocation for .not. igr + + end if ! end allocation for .not. igr if (qbmm) then @:ALLOCATE(mom_sp(1:nmomsp), mom_3d(0:2, 0:2, nb)) @@ -496,16 +590,20 @@ contains do i = 0, 2 do j = 0, 2 do k = 1, nb - @:ALLOCATE(mom_3d(i, j, k)%sf(idwbuff(1)%beg:idwbuff(1)%end, idwbuff(2)%beg:idwbuff(2)%end, & - & idwbuff(3)%beg:idwbuff(3)%end)) + @:ALLOCATE(mom_3d(i, j, k)%sf( & + & idwbuff(1)%beg:idwbuff(1)%end, & + & idwbuff(2)%beg:idwbuff(2)%end, & + & idwbuff(3)%beg:idwbuff(3)%end)) @:ACC_SETUP_SFs(mom_3d(i, j, k)) end do end do end do do i = 1, nmomsp - @:ALLOCATE(mom_sp(i)%sf(idwbuff(1)%beg:idwbuff(1)%end, idwbuff(2)%beg:idwbuff(2)%end, & - & idwbuff(3)%beg:idwbuff(3)%end)) + @:ALLOCATE(mom_sp(i)%sf( & + & idwbuff(1)%beg:idwbuff(1)%end, & + & idwbuff(2)%beg:idwbuff(2)%end, & + & idwbuff(3)%beg:idwbuff(3)%end)) @:ACC_SETUP_SFs(mom_sp(i)) end do end if @@ -513,14 +611,16 @@ contains if (mpp_lim .and. bubbles_euler) then @:ALLOCATE(alf_sum%sf(idwbuff(1)%beg:idwbuff(1)%end, idwbuff(2)%beg:idwbuff(2)%end, idwbuff(3)%beg:idwbuff(3)%end)) end if + ! END: Allocation/Association of qK_cons_n and qK_prim_n + + ! Allocation of gm_alphaK_n if (.not. igr) then @:ALLOCATE(gm_alphaL_n(1:num_dims)) @:ALLOCATE(gm_alphaR_n(1:num_dims)) end if if (alt_soundspeed) then - @:ALLOCATE(blkmod1(0:m, 0:n, 0:p), blkmod2(0:m, 0:n, 0:p), alpha1(0:m, 0:n, 0:p), alpha2(0:m, 0:n, 0:p), Kterm(0:m, & - & 0:n, 0:p)) + @:ALLOCATE(blkmod1(0:m, 0:n, 0:p), blkmod2(0:m, 0:n, 0:p), alpha1(0:m, 0:n, 0:p), alpha2(0:m, 0:n, 0:p), Kterm(0:m, 0:n, 0:p)) end if call s_initialize_pressure_relaxation_module @@ -531,31 +631,25 @@ contains end subroutine s_initialize_rhs_module - !> Compute the right-hand side of the semi-discrete governing equations for a single time stage - impure subroutine s_compute_rhs(q_cons_vf, q_T_sf, q_prim_vf, bc_type, rhs_vf, pb_in, rhs_pb, mv_in, rhs_mv, t_step, & + !> @brief Computes the right-hand side of the semi-discrete governing equations for a single time stage. + impure subroutine s_compute_rhs(q_cons_vf, q_T_sf, q_prim_vf, bc_type, rhs_vf, pb_in, rhs_pb, mv_in, rhs_mv, t_step, time_avg, stage) - & time_avg, stage) - - type(scalar_field), dimension(sys_size), intent(inout) :: q_cons_vf - type(scalar_field), intent(inout) :: q_T_sf - type(scalar_field), dimension(sys_size), intent(inout) :: q_prim_vf - type(integer_field), dimension(1:num_dims,1:2), intent(in) :: bc_type - type(scalar_field), dimension(sys_size), intent(inout) :: rhs_vf - real(stp), dimension(idwbuff(1)%beg:,idwbuff(2)%beg:,idwbuff(3)%beg:,1:,1:), intent(inout) :: pb_in - - real(wp), dimension(idwbuff(1)%beg:,idwbuff(2)%beg:,idwbuff(3)%beg:,1:,1:), & - & intent(inout) & - & :: rhs_pb ! TODO :: I think these other two variables need to be stp as well, but it doesn't compile like that right now - real(stp), dimension(idwbuff(1)%beg:,idwbuff(2)%beg:,idwbuff(3)%beg:,1:,1:), intent(inout) :: mv_in - real(wp), dimension(idwbuff(1)%beg:,idwbuff(2)%beg:,idwbuff(3)%beg:,1:,1:), intent(inout) :: rhs_mv + type(scalar_field), dimension(sys_size), intent(inout) :: q_cons_vf + type(scalar_field), intent(inout) :: q_T_sf + type(scalar_field), dimension(sys_size), intent(inout) :: q_prim_vf + type(integer_field), dimension(1:num_dims, 1:2), intent(in) :: bc_type + type(scalar_field), dimension(sys_size), intent(inout) :: rhs_vf + real(stp), dimension(idwbuff(1)%beg:, idwbuff(2)%beg:, idwbuff(3)%beg:, 1:, 1:), intent(inout) :: pb_in + real(wp), dimension(idwbuff(1)%beg:, idwbuff(2)%beg:, idwbuff(3)%beg:, 1:, 1:), intent(inout) :: rhs_pb ! TODO :: I think these other two variables need to be stp as well, but it doesn't compile like that right now + real(stp), dimension(idwbuff(1)%beg:, idwbuff(2)%beg:, idwbuff(3)%beg:, 1:, 1:), intent(inout) :: mv_in + real(wp), dimension(idwbuff(1)%beg:, idwbuff(2)%beg:, idwbuff(3)%beg:, 1:, 1:), intent(inout) :: rhs_mv integer, intent(in) :: t_step real(wp), intent(inout) :: time_avg integer, intent(in) :: stage + real(wp) :: t_start, t_finish integer :: id - integer(kind=8) :: i, j, k, l, q !< Generic loop iterators - - ! RHS: halo exchange -> reconstruct -> Riemann solve -> flux difference -> source terms + integer(kind=8) :: i, j, k, l, q !< Generic loop iterators call nvtxStartRange("COMPUTE-RHS") @@ -563,7 +657,7 @@ contains if (.not. igr .or. dummy) then ! Association/Population of Working Variables - $:GPU_PARALLEL_LOOP(private='[i, j, k, l]', collapse=4) + $:GPU_PARALLEL_LOOP(private='[i,j,k,l]', collapse=4) do i = 1, sys_size do l = idwbuff(3)%beg, idwbuff(3)%end do k = idwbuff(2)%beg, idwbuff(2)%end @@ -578,7 +672,7 @@ contains ! Converting Conservative to Primitive Variables if (mpp_lim .and. bubbles_euler) then - $:GPU_PARALLEL_LOOP(private='[j, k, l]', collapse=3) + $:GPU_PARALLEL_LOOP(private='[j,k,l]', collapse=3) do l = idwbuff(3)%beg, idwbuff(3)%end do k = idwbuff(2)%beg, idwbuff(2)%end do j = idwbuff(1)%beg, idwbuff(1)%end @@ -589,8 +683,8 @@ contains end do $:GPU_LOOP(parallelism='[seq]') do i = advxb, advxe - 1 - q_cons_qp%vf(i)%sf(j, k, l) = q_cons_qp%vf(i)%sf(j, k, l)*(1._wp - q_cons_qp%vf(alf_idx)%sf(j, k, & - & l))/alf_sum%sf(j, k, l) + q_cons_qp%vf(i)%sf(j, k, l) = q_cons_qp%vf(i)%sf(j, k, l)*(1._wp - q_cons_qp%vf(alf_idx)%sf(j, k, l)) & + /alf_sum%sf(j, k, l) end do end do end do @@ -606,7 +700,11 @@ contains end if if (.not. igr .or. dummy) then call nvtxStartRange("RHS-CONVERT") - call s_convert_conservative_to_primitive_variables(q_cons_qp%vf, q_T_sf, q_prim_qp%vf, idwint) + call s_convert_conservative_to_primitive_variables( & + q_cons_qp%vf, & + q_T_sf, & + q_prim_qp%vf, & + idwint) call nvtxEndRange call nvtxStartRange("RHS-COMMUNICATION") @@ -624,14 +722,19 @@ contains if (t_step == t_step_stop) return end if - if (qbmm) call s_mom_inv(q_cons_qp%vf, q_prim_qp%vf, mom_sp, mom_3d, pb_in, rhs_pb, mv_in, rhs_mv, idwbuff(1), & - & idwbuff(2), idwbuff(3)) + if (qbmm) call s_mom_inv(q_cons_qp%vf, q_prim_qp%vf, mom_sp, mom_3d, pb_in, rhs_pb, mv_in, rhs_mv, idwbuff(1), idwbuff(2), idwbuff(3)) if ((viscous .and. .not. igr) .or. dummy) then call nvtxStartRange("RHS-VISCOUS") - call s_get_viscous(qL_rsx_vf, qL_rsy_vf, qL_rsz_vf, dqL_prim_dx_n, dqL_prim_dy_n, dqL_prim_dz_n, qL_prim, qR_rsx_vf, & - & qR_rsy_vf, qR_rsz_vf, dqR_prim_dx_n, dqR_prim_dy_n, dqR_prim_dz_n, qR_prim, q_prim_qp, & - & dq_prim_dx_qp, dq_prim_dy_qp, dq_prim_dz_qp, idwbuff(1), idwbuff(2), idwbuff(3)) + call s_get_viscous(qL_rsx_vf, qL_rsy_vf, qL_rsz_vf, & + dqL_prim_dx_n, dqL_prim_dy_n, dqL_prim_dz_n, & + qL_prim, & + qR_rsx_vf, qR_rsy_vf, qR_rsz_vf, & + dqR_prim_dx_n, dqR_prim_dy_n, dqR_prim_dz_n, & + qR_prim, & + q_prim_qp, & + dq_prim_dx_qp, dq_prim_dy_qp, dq_prim_dz_qp, & + idwbuff(1), idwbuff(2), idwbuff(3)) call nvtxEndRange end if @@ -641,11 +744,13 @@ contains call nvtxEndRange end if - ! Loop over coordinate directions for dimensional splitting + ! Dimensional Splitting Loop do id = 1, num_dims + if (igr .or. dummy) then + if (id == 1) then - $:GPU_PARALLEL_LOOP(private='[i, j, k, l]', collapse=4) + $:GPU_PARALLEL_LOOP(private='[i,j,k,l]', collapse=4) do l = -1, p + 1 do k = -1, n + 1 do j = -1, m + 1 @@ -672,7 +777,7 @@ contains call nvtxEndRange end if end if - if ((.not. igr) .or. dummy) then ! Finite volume solve + if ((.not. igr) .or. dummy) then! Finite volume solve ! Reconstructing Primitive/Conservative Variables call nvtxStartRange("RHS-WENO") @@ -681,92 +786,153 @@ contains if (all(Re_size == 0)) then ! Reconstruct densitiess iv%beg = 1; iv%end = sys_size - call s_reconstruct_cell_boundary_values(q_prim_qp%vf(1:sys_size), qL_rsx_vf, qL_rsy_vf, qL_rsz_vf, & - & qR_rsx_vf, qR_rsy_vf, qR_rsz_vf, id) + call s_reconstruct_cell_boundary_values( & + q_prim_qp%vf(1:sys_size), & + qL_rsx_vf, qL_rsy_vf, qL_rsz_vf, & + qR_rsx_vf, qR_rsy_vf, qR_rsz_vf, & + id) else iv%beg = 1; iv%end = contxe - call s_reconstruct_cell_boundary_values(q_prim_qp%vf(iv%beg:iv%end), qL_rsx_vf, qL_rsy_vf, qL_rsz_vf, & - & qR_rsx_vf, qR_rsy_vf, qR_rsz_vf, id) + call s_reconstruct_cell_boundary_values( & + q_prim_qp%vf(iv%beg:iv%end), & + qL_rsx_vf, qL_rsy_vf, qL_rsz_vf, & + qR_rsx_vf, qR_rsy_vf, qR_rsz_vf, & + id) iv%beg = E_idx; iv%end = sys_size - call s_reconstruct_cell_boundary_values(q_prim_qp%vf(iv%beg:iv%end), qL_rsx_vf, qL_rsy_vf, qL_rsz_vf, & - & qR_rsx_vf, qR_rsy_vf, qR_rsz_vf, id) + call s_reconstruct_cell_boundary_values( & + q_prim_qp%vf(iv%beg:iv%end), & + qL_rsx_vf, qL_rsy_vf, qL_rsz_vf, & + qR_rsx_vf, qR_rsy_vf, qR_rsz_vf, & + id) end if + else if (all(Re_size == 0)) then iv%beg = 1; iv%end = E_idx - 1 - call s_reconstruct_cell_boundary_values(q_prim_qp%vf(iv%beg:iv%end), qL_rsx_vf, qL_rsy_vf, qL_rsz_vf, & - & qR_rsx_vf, qR_rsy_vf, qR_rsz_vf, id) + call s_reconstruct_cell_boundary_values( & + q_prim_qp%vf(iv%beg:iv%end), & + qL_rsx_vf, qL_rsy_vf, qL_rsz_vf, & + qR_rsx_vf, qR_rsy_vf, qR_rsz_vf, & + id) iv%beg = E_idx; iv%end = E_idx - call s_reconstruct_cell_boundary_values_first_order(q_prim_qp%vf(E_idx), qL_rsx_vf, qL_rsy_vf, qL_rsz_vf, & - & qR_rsx_vf, qR_rsy_vf, qR_rsz_vf, id) + call s_reconstruct_cell_boundary_values_first_order( & + q_prim_qp%vf(E_idx), & + qL_rsx_vf, qL_rsy_vf, qL_rsz_vf, & + qR_rsx_vf, qR_rsy_vf, qR_rsz_vf, & + id) iv%beg = E_idx + 1; iv%end = sys_size - call s_reconstruct_cell_boundary_values(q_prim_qp%vf(iv%beg:iv%end), qL_rsx_vf, qL_rsy_vf, qL_rsz_vf, & - & qR_rsx_vf, qR_rsy_vf, qR_rsz_vf, id) + call s_reconstruct_cell_boundary_values( & + q_prim_qp%vf(iv%beg:iv%end), & + qL_rsx_vf, qL_rsy_vf, qL_rsz_vf, & + qR_rsx_vf, qR_rsy_vf, qR_rsz_vf, & + id) else iv%beg = 1; iv%end = contxe - call s_reconstruct_cell_boundary_values(q_prim_qp%vf(iv%beg:iv%end), qL_rsx_vf, qL_rsy_vf, qL_rsz_vf, & - & qR_rsx_vf, qR_rsy_vf, qR_rsz_vf, id) + call s_reconstruct_cell_boundary_values( & + q_prim_qp%vf(iv%beg:iv%end), & + qL_rsx_vf, qL_rsy_vf, qL_rsz_vf, & + qR_rsx_vf, qR_rsy_vf, qR_rsz_vf, & + id) iv%beg = E_idx; iv%end = E_idx - call s_reconstruct_cell_boundary_values_first_order(q_prim_qp%vf(E_idx), qL_rsx_vf, qL_rsy_vf, qL_rsz_vf, & - & qR_rsx_vf, qR_rsy_vf, qR_rsz_vf, id) + call s_reconstruct_cell_boundary_values_first_order( & + q_prim_qp%vf(E_idx), & + qL_rsx_vf, qL_rsy_vf, qL_rsz_vf, & + qR_rsx_vf, qR_rsy_vf, qR_rsz_vf, & + id) iv%beg = E_idx + 1; iv%end = sys_size - call s_reconstruct_cell_boundary_values(q_prim_qp%vf(iv%beg:iv%end), qL_rsx_vf, qL_rsy_vf, qL_rsz_vf, & - & qR_rsx_vf, qR_rsy_vf, qR_rsz_vf, id) + call s_reconstruct_cell_boundary_values( & + q_prim_qp%vf(iv%beg:iv%end), & + qL_rsx_vf, qL_rsy_vf, qL_rsz_vf, & + qR_rsx_vf, qR_rsy_vf, qR_rsz_vf, & + id) end if + end if ! Reconstruct viscous derivatives for viscosity if (weno_Re_flux) then iv%beg = momxb; iv%end = momxe - call s_reconstruct_cell_boundary_values_visc_deriv(dq_prim_dx_qp(1)%vf(iv%beg:iv%end), dqL_rsx_vf, & - & dqL_rsy_vf, dqL_rsz_vf, dqR_rsx_vf, dqR_rsy_vf, dqR_rsz_vf, id, dqL_prim_dx_n(id)%vf(iv%beg:iv%end), & - & dqR_prim_dx_n(id)%vf(iv%beg:iv%end), idwbuff(1), idwbuff(2), idwbuff(3)) + call s_reconstruct_cell_boundary_values_visc_deriv( & + dq_prim_dx_qp(1)%vf(iv%beg:iv%end), & + dqL_rsx_vf, dqL_rsy_vf, dqL_rsz_vf, & + dqR_rsx_vf, dqR_rsy_vf, dqR_rsz_vf, & + id, dqL_prim_dx_n(id)%vf(iv%beg:iv%end), dqR_prim_dx_n(id)%vf(iv%beg:iv%end), & + idwbuff(1), idwbuff(2), idwbuff(3)) if (n > 0) then - call s_reconstruct_cell_boundary_values_visc_deriv(dq_prim_dy_qp(1)%vf(iv%beg:iv%end), dqL_rsx_vf, & - & dqL_rsy_vf, dqL_rsz_vf, dqR_rsx_vf, dqR_rsy_vf, dqR_rsz_vf, id, & - & dqL_prim_dy_n(id)%vf(iv%beg:iv%end), dqR_prim_dy_n(id)%vf(iv%beg:iv%end), idwbuff(1), idwbuff(2), & - & idwbuff(3)) + call s_reconstruct_cell_boundary_values_visc_deriv( & + dq_prim_dy_qp(1)%vf(iv%beg:iv%end), & + dqL_rsx_vf, dqL_rsy_vf, dqL_rsz_vf, & + dqR_rsx_vf, dqR_rsy_vf, dqR_rsz_vf, & + id, dqL_prim_dy_n(id)%vf(iv%beg:iv%end), dqR_prim_dy_n(id)%vf(iv%beg:iv%end), & + idwbuff(1), idwbuff(2), idwbuff(3)) if (p > 0) then - call s_reconstruct_cell_boundary_values_visc_deriv(dq_prim_dz_qp(1)%vf(iv%beg:iv%end), dqL_rsx_vf, & - & dqL_rsy_vf, dqL_rsz_vf, dqR_rsx_vf, dqR_rsy_vf, dqR_rsz_vf, id, & - & dqL_prim_dz_n(id)%vf(iv%beg:iv%end), dqR_prim_dz_n(id)%vf(iv%beg:iv%end), idwbuff(1), & - & idwbuff(2), idwbuff(3)) + call s_reconstruct_cell_boundary_values_visc_deriv( & + dq_prim_dz_qp(1)%vf(iv%beg:iv%end), & + dqL_rsx_vf, dqL_rsy_vf, dqL_rsz_vf, & + dqR_rsx_vf, dqR_rsy_vf, dqR_rsz_vf, & + id, dqL_prim_dz_n(id)%vf(iv%beg:iv%end), dqR_prim_dz_n(id)%vf(iv%beg:iv%end), & + idwbuff(1), idwbuff(2), idwbuff(3)) end if end if end if - call nvtxEndRange ! WENO + call nvtxEndRange ! WENO ! Configuring Coordinate Direction Indexes if (id == 1) then irx%beg = -1; iry%beg = 0; irz%beg = 0 - else if (id == 2) then + elseif (id == 2) then irx%beg = 0; iry%beg = -1; irz%beg = 0 else irx%beg = 0; iry%beg = 0; irz%beg = -1 end if irx%end = m; iry%end = n; irz%end = p - ! Computing Riemann Solver Flux and Source Flux + ! $:GPU_UPDATE(host='[qL_rsx_vf,qR_rsx_vf]') + ! print *, "L", qL_rsx_vf(100:300, 0, 0, 1) + ! print *, "R", qR_rsx_vf(100:300, 0, 0, 1) + + !Computing Riemann Solver Flux and Source Flux call nvtxStartRange("RHS-RIEMANN-SOLVER") - call s_riemann_solver(qR_rsx_vf, qR_rsy_vf, qR_rsz_vf, dqR_prim_dx_n(id)%vf, dqR_prim_dy_n(id)%vf, & - & dqR_prim_dz_n(id)%vf, qR_prim(id)%vf, qL_rsx_vf, qL_rsy_vf, qL_rsz_vf, & - & dqL_prim_dx_n(id)%vf, dqL_prim_dy_n(id)%vf, dqL_prim_dz_n(id)%vf, qL_prim(id)%vf, & - & q_prim_qp%vf, flux_n(id)%vf, flux_src_n(id)%vf, flux_gsrc_n(id)%vf, id, irx, iry, irz) + call s_riemann_solver(qR_rsx_vf, qR_rsy_vf, qR_rsz_vf, & + dqR_prim_dx_n(id)%vf, & + dqR_prim_dy_n(id)%vf, & + dqR_prim_dz_n(id)%vf, & + qR_prim(id)%vf, & + qL_rsx_vf, qL_rsy_vf, qL_rsz_vf, & + dqL_prim_dx_n(id)%vf, & + dqL_prim_dy_n(id)%vf, & + dqL_prim_dz_n(id)%vf, & + qL_prim(id)%vf, & + q_prim_qp%vf, & + flux_n(id)%vf, & + flux_src_n(id)%vf, & + flux_gsrc_n(id)%vf, & + id, irx, iry, irz) call nvtxEndRange - ! Additional physics and source terms RHS addition for advection source + !$:GPU_UPDATE(host='[flux_n(1)%vf(1)%sf]') + !print *, "FLUX", flux_n(1)%vf(1)%sf(100:300, 0, 0) + + ! Additional physics and source terms + ! RHS addition for advection source call nvtxStartRange("RHS-ADVECTION-SRC") - call s_compute_advection_source_term(id, rhs_vf, q_cons_qp, q_prim_qp, flux_src_n(id)) + call s_compute_advection_source_term(id, & + rhs_vf, & + q_cons_qp, & + q_prim_qp, & + flux_src_n(id)) call nvtxEndRange ! RHS additions for hypoelasticity call nvtxStartRange("RHS-HYPOELASTICITY") - if (hypoelasticity) call s_compute_hypoelastic_rhs(id, q_prim_qp%vf, rhs_vf) + if (hypoelasticity) call s_compute_hypoelastic_rhs(id, & + q_prim_qp%vf, & + rhs_vf) call nvtxEndRange ! RHS for diffusion @@ -776,15 +942,20 @@ contains call nvtxEndRange end if - ! Viscous stress contribution to RHS + ! RHS additions for viscosity if (viscous .or. surface_tension .or. chem_params%diffusion) then call nvtxStartRange("RHS-ADD-PHYSICS") - call s_compute_additional_physics_rhs(id, q_prim_qp%vf, rhs_vf, flux_src_n(id)%vf, dq_prim_dx_qp(1)%vf, & - & dq_prim_dy_qp(1)%vf, dq_prim_dz_qp(1)%vf) + call s_compute_additional_physics_rhs(id, & + q_prim_qp%vf, & + rhs_vf, & + flux_src_n(id)%vf, & + dq_prim_dx_qp(1)%vf, & + dq_prim_dy_qp(1)%vf, & + dq_prim_dz_qp(1)%vf) call nvtxEndRange end if - ! Bubble dynamics source terms + ! RHS additions for sub-grid bubbles_euler if (bubbles_euler) then call nvtxStartRange("RHS-BUBBLES-COMPUTE") call s_compute_bubbles_EE_rhs(id, q_prim_qp%vf, divu) @@ -794,18 +965,24 @@ contains ! RHS additions for qbmm bubbles if (qbmm) then call nvtxStartRange("RHS-QBMM") - call s_compute_qbmm_rhs(id, q_cons_qp%vf, q_prim_qp%vf, rhs_vf, flux_n(id)%vf, pb_in, rhs_pb) + call s_compute_qbmm_rhs(id, & + q_cons_qp%vf, & + q_prim_qp%vf, & + rhs_vf, & + flux_n(id)%vf, & + pb_in, & + rhs_pb) call nvtxEndRange end if ! END: Additional physics and source terms if (hyper_cleaning) then - $:GPU_PARALLEL_LOOP(private='[j, k, l]', collapse=3) + $:GPU_PARALLEL_LOOP(private='[j,k,l]', collapse=3) do l = 0, p do k = 0, n do j = 0, m - rhs_vf(psi_idx)%sf(j, k, l) = rhs_vf(psi_idx)%sf(j, k, l) - q_prim_vf(psi_idx)%sf(j, k, & - & l)/hyper_cleaning_tau + rhs_vf(psi_idx)%sf(j, k, l) = rhs_vf(psi_idx)%sf(j, k, l) - & + q_prim_vf(psi_idx)%sf(j, k, l)/hyper_cleaning_tau end do end do end do @@ -818,7 +995,7 @@ contains ! END: Dimensional Splitting Loop if (ib) then - $:GPU_PARALLEL_LOOP(private='[i, j, k, l]', collapse=3) + $:GPU_PARALLEL_LOOP(private='[i,j,k,l]', collapse=3) do l = 0, p do k = 0, n do j = 0, m @@ -833,29 +1010,45 @@ contains $:END_GPU_PARALLEL_LOOP() end if - ! Additional Physics and Source Terms Additions for acoustic_source + ! Additional Physics and Source Terms + ! Additions for acoustic_source if (acoustic_source) then call nvtxStartRange("RHS-ACOUSTIC-SRC") - call s_acoustic_src_calculations(q_cons_qp%vf(1:sys_size), q_prim_qp%vf(1:sys_size), rhs_vf) + call s_acoustic_src_calculations(q_cons_qp%vf(1:sys_size), & + q_prim_qp%vf(1:sys_size), & + rhs_vf) call nvtxEndRange end if ! Add bubbles source term if (bubbles_euler .and. (.not. adap_dt) .and. (.not. qbmm)) then call nvtxStartRange("RHS-BUBBLES-SRC") - call s_compute_bubble_EE_source(q_cons_qp%vf(1:sys_size), q_prim_qp%vf(1:sys_size), rhs_vf, divu) + call s_compute_bubble_EE_source( & + q_cons_qp%vf(1:sys_size), & + q_prim_qp%vf(1:sys_size), & + rhs_vf, & + divu) call nvtxEndRange end if if (bubbles_lagrange) then - ! RHS additions for sub-grid bubbles_lagrange - call nvtxStartRange("RHS-EL-BUBBLES-SRC") - call s_compute_bubbles_EL_source(q_cons_qp%vf(1:sys_size), q_prim_qp%vf(1:sys_size), rhs_vf) - call nvtxEndRange ! Compute bubble dynamics if (.not. adap_dt) then call nvtxStartRange("RHS-EL-BUBBLES-DYN") - call s_compute_bubble_EL_dynamics(q_prim_qp%vf(1:sys_size), stage) + call s_compute_bubble_EL_dynamics( & + q_prim_qp%vf(1:sys_size), & + bc_type, & + stage) + call nvtxEndRange + end if + + ! RHS additions for sub-grid bubbles_lagrange + if (lag_params%solver_approach == 2) then + call nvtxStartRange("RHS-EL-BUBBLES-SRC") + call s_compute_bubbles_EL_source( & + q_cons_qp%vf(1:sys_size), & + q_prim_qp%vf(1:sys_size), & + rhs_vf) call nvtxEndRange end if end if @@ -872,7 +1065,7 @@ contains if (run_time_info .or. probe_wrt .or. ib .or. bubbles_lagrange) then if (.not. igr .or. dummy) then - $:GPU_PARALLEL_LOOP(private='[i, j, k, l]', collapse=4) + $:GPU_PARALLEL_LOOP(private='[i,j,k,l]', collapse=4) do i = 1, sys_size do l = idwbuff(3)%beg, idwbuff(3)%end do k = idwbuff(2)%beg, idwbuff(2)%end @@ -898,7 +1091,7 @@ contains end subroutine s_compute_rhs - !> Accumulate advection source contributions from a given coordinate direction into the RHS + !> @brief Accumulates advection source contributions from a given coordinate direction into the RHS. subroutine s_compute_advection_source_term(idir, rhs_vf, q_cons_vf, q_prim_vf, flux_src_n_vf) integer, intent(in) :: idir @@ -906,21 +1099,23 @@ contains type(vector_field), intent(inout) :: q_cons_vf type(vector_field), intent(inout) :: q_prim_vf type(vector_field), intent(inout) :: flux_src_n_vf - integer :: j, k, l, q !< Loop iterators from original, meaning varies - integer :: k_loop, l_loop, q_loop !< Standardized spatial loop iterators 0:m, 0:n, 0:p + + integer :: j, k, l, q ! Loop iterators from original, meaning varies + integer :: k_loop, l_loop, q_loop ! Standardized spatial loop iterators 0:m, 0:n, 0:p integer :: i_fluid_loop + real(wp) :: inv_ds, flux_face1, flux_face2 real(wp) :: advected_qty_val, pressure_val, velocity_val if (alt_soundspeed) then - $:GPU_PARALLEL_LOOP(private='[k_loop, l_loop, q_loop]', collapse=3) + $:GPU_PARALLEL_LOOP(private='[k_loop,l_loop,q_loop]', collapse=3) do q_loop = 0, p do l_loop = 0, n do k_loop = 0, m - blkmod1(k_loop, l_loop, q_loop) = ((gammas(1) + 1._wp)*q_prim_vf%vf(E_idx)%sf(k_loop, l_loop, & - & q_loop) + pi_infs(1))/gammas(1) - blkmod2(k_loop, l_loop, q_loop) = ((gammas(2) + 1._wp)*q_prim_vf%vf(E_idx)%sf(k_loop, l_loop, & - & q_loop) + pi_infs(2))/gammas(2) + blkmod1(k_loop, l_loop, q_loop) = ((gammas(1) + 1._wp)*q_prim_vf%vf(E_idx)%sf(k_loop, l_loop, q_loop) + & + pi_infs(1))/gammas(1) + blkmod2(k_loop, l_loop, q_loop) = ((gammas(2) + 1._wp)*q_prim_vf%vf(E_idx)%sf(k_loop, l_loop, q_loop) + & + pi_infs(2))/gammas(2) alpha1(k_loop, l_loop, q_loop) = q_cons_vf%vf(advxb)%sf(k_loop, l_loop, q_loop) if (bubbles_euler) then @@ -929,10 +1124,10 @@ contains alpha2(k_loop, l_loop, q_loop) = q_cons_vf%vf(advxe)%sf(k_loop, l_loop, q_loop) end if - Kterm(k_loop, l_loop, q_loop) = alpha1(k_loop, l_loop, q_loop)*alpha2(k_loop, l_loop, & - & q_loop)*(blkmod2(k_loop, l_loop, q_loop) - blkmod1(k_loop, l_loop, q_loop))/(alpha1(k_loop, & - & l_loop, q_loop)*blkmod2(k_loop, l_loop, q_loop) + alpha2(k_loop, l_loop, q_loop)*blkmod1(k_loop, & - & l_loop, q_loop)) + Kterm(k_loop, l_loop, q_loop) = alpha1(k_loop, l_loop, q_loop)*alpha2(k_loop, l_loop, q_loop)* & + (blkmod2(k_loop, l_loop, q_loop) - blkmod1(k_loop, l_loop, q_loop))/ & + (alpha1(k_loop, l_loop, q_loop)*blkmod2(k_loop, l_loop, q_loop) + & + alpha2(k_loop, l_loop, q_loop)*blkmod1(k_loop, l_loop, q_loop)) end do end do end do @@ -948,7 +1143,7 @@ contains call s_cbc(q_prim_vf%vf, flux_n(idir)%vf, flux_src_n_vf%vf, idir, 1, irx, iry, irz) end if - $:GPU_PARALLEL_LOOP(collapse=4,private='[j, k_loop, l_loop, q_loop, inv_ds, flux_face1, flux_face2]') + $:GPU_PARALLEL_LOOP(collapse=4,private='[j,k_loop,l_loop,q_loop,inv_ds,flux_face1,flux_face2]') do j = 1, sys_size do q_loop = 0, p do l_loop = 0, n @@ -964,8 +1159,7 @@ contains $:END_GPU_PARALLEL_LOOP() if (model_eqns == 3) then - $:GPU_PARALLEL_LOOP(collapse=4,private='[i_fluid_loop, k_loop, l_loop, q_loop, inv_ds, advected_qty_val, & - & pressure_val, flux_face1, flux_face2]') + $:GPU_PARALLEL_LOOP(collapse=4,private='[i_fluid_loop,k_loop,l_loop,q_loop,inv_ds,advected_qty_val, pressure_val,flux_face1,flux_face2]') do q_loop = 0, p do l_loop = 0, n do k_loop = 0, m @@ -975,9 +1169,9 @@ contains pressure_val = q_prim_vf%vf(E_idx)%sf(k_loop, l_loop, q_loop) flux_face1 = flux_src_n_vf%vf(advxb)%sf(k_loop, l_loop, q_loop) flux_face2 = flux_src_n_vf%vf(advxb)%sf(k_loop - 1, l_loop, q_loop) - rhs_vf(i_fluid_loop + intxb - 1)%sf(k_loop, l_loop, & - & q_loop) = rhs_vf(i_fluid_loop + intxb - 1)%sf(k_loop, l_loop, & - & q_loop) - inv_ds*advected_qty_val*pressure_val*(flux_face1 - flux_face2) + rhs_vf(i_fluid_loop + intxb - 1)%sf(k_loop, l_loop, q_loop) = & + rhs_vf(i_fluid_loop + intxb - 1)%sf(k_loop, l_loop, q_loop) - & + inv_ds*advected_qty_val*pressure_val*(flux_face1 - flux_face2) end do end do end do @@ -986,7 +1180,8 @@ contains end if call s_add_directional_advection_source_terms(idir, rhs_vf, q_cons_vf, q_prim_vf, flux_src_n_vf, Kterm) - case (2) ! y-direction + + case (2) ! y-direction if (bc_y%beg <= BC_CHAR_SLIP_WALL .and. bc_y%beg >= BC_CHAR_SUP_OUTFLOW) then call s_cbc(q_prim_vf%vf, flux_n(idir)%vf, flux_src_n_vf%vf, idir, -1, irx, iry, irz) end if @@ -994,7 +1189,7 @@ contains call s_cbc(q_prim_vf%vf, flux_n(idir)%vf, flux_src_n_vf%vf, idir, 1, irx, iry, irz) end if - $:GPU_PARALLEL_LOOP(collapse=4,private='[j, k, l, q, inv_ds, flux_face1, flux_face2]') + $:GPU_PARALLEL_LOOP(collapse=4,private='[j,k,l,q,inv_ds,flux_face1,flux_face2]') do j = 1, sys_size do l = 0, p do k = 0, n @@ -1010,8 +1205,7 @@ contains $:END_GPU_PARALLEL_LOOP() if (model_eqns == 3) then - $:GPU_PARALLEL_LOOP(collapse=4, private='[i_fluid_loop, k, l, q, inv_ds, advected_qty_val, pressure_val, & - & flux_face1, flux_face2]') + $:GPU_PARALLEL_LOOP(collapse=4,private='[i_fluid_loop,k,l,q,inv_ds,advected_qty_val, pressure_val,flux_face1,flux_face2]') do l = 0, p do k = 0, n do q = 0, m @@ -1021,11 +1215,13 @@ contains pressure_val = q_prim_vf%vf(E_idx)%sf(q, k, l) flux_face1 = flux_src_n_vf%vf(advxb)%sf(q, k, l) flux_face2 = flux_src_n_vf%vf(advxb)%sf(q, k - 1, l) - rhs_vf(i_fluid_loop + intxb - 1)%sf(q, k, l) = rhs_vf(i_fluid_loop + intxb - 1)%sf(q, k, & - & l) - inv_ds*advected_qty_val*pressure_val*(flux_face1 - flux_face2) + rhs_vf(i_fluid_loop + intxb - 1)%sf(q, k, l) = & + rhs_vf(i_fluid_loop + intxb - 1)%sf(q, k, l) - & + inv_ds*advected_qty_val*pressure_val*(flux_face1 - flux_face2) if (cyl_coord) then - rhs_vf(i_fluid_loop + intxb - 1)%sf(q, k, l) = rhs_vf(i_fluid_loop + intxb - 1)%sf(q, k, & - & l) - 5.e-1_wp/y_cc(k)*advected_qty_val*pressure_val*(flux_face1 + flux_face2) + rhs_vf(i_fluid_loop + intxb - 1)%sf(q, k, l) = & + rhs_vf(i_fluid_loop + intxb - 1)%sf(q, k, l) - & + 5.e-1_wp/y_cc(k)*advected_qty_val*pressure_val*(flux_face1 + flux_face2) end if end do end do @@ -1035,14 +1231,15 @@ contains end if if (cyl_coord) then - $:GPU_PARALLEL_LOOP(collapse=4,private='[j, k, l, q, flux_face1, flux_face2]') + $:GPU_PARALLEL_LOOP(collapse=4,private='[j,k,l,q,flux_face1,flux_face2]') do j = 1, sys_size do l = 0, p do k = 0, n do q = 0, m flux_face1 = flux_gsrc_n(2)%vf(j)%sf(q, k - 1, l) flux_face2 = flux_gsrc_n(2)%vf(j)%sf(q, k, l) - rhs_vf(j)%sf(q, k, l) = rhs_vf(j)%sf(q, k, l) - 5.e-1_wp/y_cc(k)*(flux_face1 + flux_face2) + rhs_vf(j)%sf(q, k, l) = rhs_vf(j)%sf(q, k, l) - & + 5.e-1_wp/y_cc(k)*(flux_face1 + flux_face2) end do end do end do @@ -1051,7 +1248,8 @@ contains end if call s_add_directional_advection_source_terms(idir, rhs_vf, q_cons_vf, q_prim_vf, flux_src_n_vf, Kterm) - case (3) ! z-direction + + case (3) ! z-direction if (bc_z%beg <= BC_CHAR_SLIP_WALL .and. bc_z%beg >= BC_CHAR_SUP_OUTFLOW) then call s_cbc(q_prim_vf%vf, flux_n(idir)%vf, flux_src_n_vf%vf, idir, -1, irx, iry, irz) end if @@ -1059,8 +1257,8 @@ contains call s_cbc(q_prim_vf%vf, flux_n(idir)%vf, flux_src_n_vf%vf, idir, 1, irx, iry, irz) end if - if (grid_geometry == 3) then ! Cylindrical Coordinates - $:GPU_PARALLEL_LOOP(collapse=4,private='[j, k, l, q, inv_ds, velocity_val, flux_face1, flux_face2]') + if (grid_geometry == 3) then ! Cylindrical Coordinates + $:GPU_PARALLEL_LOOP(collapse=4,private='[j,k,l,q,inv_ds,velocity_val,flux_face1,flux_face2]') do j = 1, sys_size do k = 0, p do q = 0, n @@ -1069,27 +1267,29 @@ contains velocity_val = q_prim_vf%vf(contxe + idir)%sf(l, q, k) flux_face1 = flux_n(3)%vf(j)%sf(l, q, k - 1) flux_face2 = flux_n(3)%vf(j)%sf(l, q, k) - rhs_vf(j)%sf(l, q, k) = rhs_vf(j)%sf(l, q, k) + inv_ds*velocity_val*(flux_face1 - flux_face2) + rhs_vf(j)%sf(l, q, k) = rhs_vf(j)%sf(l, q, k) + & + inv_ds*velocity_val*(flux_face1 - flux_face2) end do end do end do end do $:END_GPU_PARALLEL_LOOP() - $:GPU_PARALLEL_LOOP(collapse=4,private='[j, k, l, q, flux_face1, flux_face2]') + $:GPU_PARALLEL_LOOP(collapse=4,private='[j,k,l,q,flux_face1,flux_face2]') do j = 1, sys_size do k = 0, p do q = 0, n do l = 0, m flux_face1 = flux_gsrc_n(3)%vf(j)%sf(l, q, k - 1) flux_face2 = flux_gsrc_n(3)%vf(j)%sf(l, q, k) - rhs_vf(j)%sf(l, q, k) = rhs_vf(j)%sf(l, q, k) - 5.e-1_wp/y_cc(q)*(flux_face1 + flux_face2) + rhs_vf(j)%sf(l, q, k) = rhs_vf(j)%sf(l, q, k) - & + 5.e-1_wp/y_cc(q)*(flux_face1 + flux_face2) end do end do end do end do $:END_GPU_PARALLEL_LOOP() - else ! Cartesian Coordinates - $:GPU_PARALLEL_LOOP(collapse=4,private='[j, k, l, q, inv_ds, flux_face1, flux_face2]') + else ! Cartesian Coordinates + $:GPU_PARALLEL_LOOP(collapse=4,private='[j,k,l,q,inv_ds,flux_face1,flux_face2]') do j = 1, sys_size do k = 0, p do q = 0, n @@ -1106,8 +1306,7 @@ contains end if if (model_eqns == 3) then - $:GPU_PARALLEL_LOOP(collapse=4, private='[i_fluid_loop, k, l, q, inv_ds, advected_qty_val, pressure_val, & - & flux_face1, flux_face2]') + $:GPU_PARALLEL_LOOP(collapse=4,private='[i_fluid_loop,k,l,q,inv_ds,advected_qty_val, pressure_val,flux_face1,flux_face2]') do k = 0, p do q = 0, n do l = 0, m @@ -1117,8 +1316,9 @@ contains pressure_val = q_prim_vf%vf(E_idx)%sf(l, q, k) flux_face1 = flux_src_n_vf%vf(advxb)%sf(l, q, k) flux_face2 = flux_src_n_vf%vf(advxb)%sf(l, q, k - 1) - rhs_vf(i_fluid_loop + intxb - 1)%sf(l, q, k) = rhs_vf(i_fluid_loop + intxb - 1)%sf(l, q, & - & k) - inv_ds*advected_qty_val*pressure_val*(flux_face1 - flux_face2) + rhs_vf(i_fluid_loop + intxb - 1)%sf(l, q, k) = & + rhs_vf(i_fluid_loop + intxb - 1)%sf(l, q, k) - & + inv_ds*advected_qty_val*pressure_val*(flux_face1 - flux_face2) end do end do end do @@ -1127,172 +1327,165 @@ contains end if call s_add_directional_advection_source_terms(idir, rhs_vf, q_cons_vf, q_prim_vf, flux_src_n_vf, Kterm) + end select contains - !> Add the advection source flux-difference terms for a single coordinate direction to the RHS - subroutine s_add_directional_advection_source_terms(current_idir, rhs_vf_arg, q_cons_vf_arg, q_prim_vf_arg, & - - & flux_src_n_vf_arg, Kterm_arg) - integer, intent(in) :: current_idir + !> @brief Adds the advection source flux-difference terms for a single coordinate direction to the RHS. + subroutine s_add_directional_advection_source_terms(current_idir, rhs_vf_arg, q_cons_vf_arg, & + q_prim_vf_arg, flux_src_n_vf_arg, Kterm_arg) + integer, intent(in) :: current_idir type(scalar_field), dimension(sys_size), intent(inout) :: rhs_vf_arg - type(vector_field), intent(in) :: q_cons_vf_arg - type(vector_field), intent(in) :: q_prim_vf_arg - type(vector_field), intent(in) :: flux_src_n_vf_arg + type(vector_field), intent(in) :: q_cons_vf_arg + type(vector_field), intent(in) :: q_prim_vf_arg + type(vector_field), intent(in) :: flux_src_n_vf_arg ! CORRECTED DECLARATION FOR Kterm_arg: - real(wp), allocatable, dimension(:,:,:), intent(in) :: Kterm_arg - integer :: j_adv, k_idx, l_idx, q_idx - real(wp) :: local_inv_ds, local_term_coeff, local_flux1, local_flux2 - real(wp) :: local_q_cons_val, local_k_term_val - logical :: use_standard_riemann + real(wp), allocatable, dimension(:, :, :), intent(in) :: Kterm_arg + + integer :: j_adv, k_idx, l_idx, q_idx + real(wp) :: local_inv_ds, local_term_coeff, local_flux1, local_flux2 + real(wp) :: local_q_cons_val, local_k_term_val + logical :: use_standard_riemann select case (current_idir) - case (1) ! x-direction + case (1) ! x-direction use_standard_riemann = (riemann_solver == 1 .or. riemann_solver == 4) if (use_standard_riemann) then - $:GPU_PARALLEL_LOOP(collapse=4,private='[j_adv, k_idx, l_idx, q_idx, local_inv_ds, local_term_coeff, & - & local_flux1, local_flux2]') + $:GPU_PARALLEL_LOOP(collapse=4,private='[j_adv,k_idx,l_idx,q_idx,local_inv_ds, local_term_coeff,local_flux1,local_flux2]') do j_adv = advxb, advxe - do q_idx = 0, p ! z_extent - do l_idx = 0, n ! y_extent - do k_idx = 0, m ! x_extent + do q_idx = 0, p ! z_extent + do l_idx = 0, n ! y_extent + do k_idx = 0, m ! x_extent local_inv_ds = 1._wp/dx(k_idx) local_term_coeff = q_prim_vf_arg%vf(contxe + current_idir)%sf(k_idx, l_idx, q_idx) local_flux1 = flux_src_n_vf_arg%vf(j_adv)%sf(k_idx - 1, l_idx, q_idx) local_flux2 = flux_src_n_vf_arg%vf(j_adv)%sf(k_idx, l_idx, q_idx) - rhs_vf_arg(j_adv)%sf(k_idx, l_idx, q_idx) = rhs_vf_arg(j_adv)%sf(k_idx, l_idx, & - & q_idx) + local_inv_ds*local_term_coeff*(local_flux1 - local_flux2) + rhs_vf_arg(j_adv)%sf(k_idx, l_idx, q_idx) = rhs_vf_arg(j_adv)%sf(k_idx, l_idx, q_idx) + & + local_inv_ds*local_term_coeff*(local_flux1 - local_flux2) end do end do end do end do $:END_GPU_PARALLEL_LOOP() - else ! Other Riemann solvers + else ! Other Riemann solvers if (alt_soundspeed) then if (bubbles_euler .neqv. .true.) then - $:GPU_PARALLEL_LOOP(collapse=3, private='[k_idx, l_idx, q_idx, local_inv_ds, local_q_cons_val, & - & local_k_term_val, local_term_coeff, local_flux1, local_flux2]') + $:GPU_PARALLEL_LOOP(collapse=3, private='[k_idx,l_idx,q_idx,local_inv_ds, local_q_cons_val, local_k_term_val, local_term_coeff, local_flux1, local_flux2]') do q_idx = 0, p; do l_idx = 0, n; do k_idx = 0, m - local_inv_ds = 1._wp/dx(k_idx) - local_q_cons_val = q_cons_vf_arg%vf(advxe)%sf(k_idx, l_idx, q_idx) - local_k_term_val = Kterm_arg(k_idx, l_idx, q_idx) ! Access is safe due to outer alt_soundspeed check - local_term_coeff = local_q_cons_val - local_k_term_val - local_flux1 = flux_src_n_vf_arg%vf(advxe)%sf(k_idx, l_idx, q_idx) - local_flux2 = flux_src_n_vf_arg%vf(advxe)%sf(k_idx - 1, l_idx, q_idx) - rhs_vf_arg(advxe)%sf(k_idx, l_idx, q_idx) = rhs_vf_arg(advxe)%sf(k_idx, l_idx, & - & q_idx) + local_inv_ds*local_term_coeff*(local_flux1 - local_flux2) - end do; end do; end do + local_inv_ds = 1._wp/dx(k_idx) + local_q_cons_val = q_cons_vf_arg%vf(advxe)%sf(k_idx, l_idx, q_idx) + local_k_term_val = Kterm_arg(k_idx, l_idx, q_idx) ! Access is safe due to outer alt_soundspeed check + local_term_coeff = local_q_cons_val - local_k_term_val + local_flux1 = flux_src_n_vf_arg%vf(advxe)%sf(k_idx, l_idx, q_idx) + local_flux2 = flux_src_n_vf_arg%vf(advxe)%sf(k_idx - 1, l_idx, q_idx) + rhs_vf_arg(advxe)%sf(k_idx, l_idx, q_idx) = rhs_vf_arg(advxe)%sf(k_idx, l_idx, q_idx) + & + local_inv_ds*local_term_coeff*(local_flux1 - local_flux2) + end do; end do; end do $:END_GPU_PARALLEL_LOOP() - $:GPU_PARALLEL_LOOP(collapse=3, private='[k_idx, l_idx, q_idx, local_inv_ds, local_q_cons_val, & - & local_k_term_val, local_term_coeff, local_flux1, local_flux2]') + $:GPU_PARALLEL_LOOP(collapse=3, private='[k_idx,l_idx,q_idx,local_inv_ds,local_q_cons_val, local_k_term_val,local_term_coeff, local_flux1, local_flux2]') do q_idx = 0, p; do l_idx = 0, n; do k_idx = 0, m - local_inv_ds = 1._wp/dx(k_idx) - local_q_cons_val = q_cons_vf_arg%vf(advxb)%sf(k_idx, l_idx, q_idx) - local_k_term_val = Kterm_arg(k_idx, l_idx, q_idx) ! Access is safe - local_term_coeff = local_q_cons_val + local_k_term_val - local_flux1 = flux_src_n_vf_arg%vf(advxb)%sf(k_idx, l_idx, q_idx) - local_flux2 = flux_src_n_vf_arg%vf(advxb)%sf(k_idx - 1, l_idx, q_idx) - rhs_vf_arg(advxb)%sf(k_idx, l_idx, q_idx) = rhs_vf_arg(advxb)%sf(k_idx, l_idx, & - & q_idx) + local_inv_ds*local_term_coeff*(local_flux1 - local_flux2) - end do; end do; end do + local_inv_ds = 1._wp/dx(k_idx) + local_q_cons_val = q_cons_vf_arg%vf(advxb)%sf(k_idx, l_idx, q_idx) + local_k_term_val = Kterm_arg(k_idx, l_idx, q_idx) ! Access is safe + local_term_coeff = local_q_cons_val + local_k_term_val + local_flux1 = flux_src_n_vf_arg%vf(advxb)%sf(k_idx, l_idx, q_idx) + local_flux2 = flux_src_n_vf_arg%vf(advxb)%sf(k_idx - 1, l_idx, q_idx) + rhs_vf_arg(advxb)%sf(k_idx, l_idx, q_idx) = rhs_vf_arg(advxb)%sf(k_idx, l_idx, q_idx) + & + local_inv_ds*local_term_coeff*(local_flux1 - local_flux2) + end do; end do; end do $:END_GPU_PARALLEL_LOOP() end if - else ! NOT alt_soundspeed - $:GPU_PARALLEL_LOOP(collapse=4,private='[j_adv, k_idx, l_idx, q_idx, local_inv_ds, local_term_coeff, & - & local_flux1, local_flux2]') + else ! NOT alt_soundspeed + $:GPU_PARALLEL_LOOP(collapse=4,private='[j_adv,k_idx,l_idx,q_idx,local_inv_ds, local_term_coeff,local_flux1,local_flux2]') do j_adv = advxb, advxe do q_idx = 0, p; do l_idx = 0, n; do k_idx = 0, m - local_inv_ds = 1._wp/dx(k_idx) - local_term_coeff = q_cons_vf_arg%vf(j_adv)%sf(k_idx, l_idx, q_idx) - local_flux1 = flux_src_n_vf_arg%vf(j_adv)%sf(k_idx, l_idx, q_idx) - local_flux2 = flux_src_n_vf_arg%vf(j_adv)%sf(k_idx - 1, l_idx, q_idx) - rhs_vf_arg(j_adv)%sf(k_idx, l_idx, q_idx) = rhs_vf_arg(j_adv)%sf(k_idx, l_idx, & - & q_idx) + local_inv_ds*local_term_coeff*(local_flux1 - local_flux2) - end do; end do; end do + local_inv_ds = 1._wp/dx(k_idx) + local_term_coeff = q_cons_vf_arg%vf(j_adv)%sf(k_idx, l_idx, q_idx) + local_flux1 = flux_src_n_vf_arg%vf(j_adv)%sf(k_idx, l_idx, q_idx) + local_flux2 = flux_src_n_vf_arg%vf(j_adv)%sf(k_idx - 1, l_idx, q_idx) + rhs_vf_arg(j_adv)%sf(k_idx, l_idx, q_idx) = rhs_vf_arg(j_adv)%sf(k_idx, l_idx, q_idx) + & + local_inv_ds*local_term_coeff*(local_flux1 - local_flux2) + end do; end do; end do end do $:END_GPU_PARALLEL_LOOP() end if end if - case (2) - ! y-direction: loops q_idx (x), k_idx (y), l_idx (z); sf(q_idx, k_idx, l_idx); dy(k_idx); Kterm(q_idx,k_idx,l_idx) + + case (2) ! y-direction: loops q_idx (x), k_idx (y), l_idx (z); sf(q_idx, k_idx, l_idx); dy(k_idx); Kterm(q_idx,k_idx,l_idx) use_standard_riemann = (riemann_solver == 1 .or. riemann_solver == 4) if (use_standard_riemann) then - $:GPU_PARALLEL_LOOP(collapse=4,private='[j_adv, k_idx, l_idx, q_idx, local_inv_ds, local_term_coeff, & - & local_flux1, local_flux2]') + $:GPU_PARALLEL_LOOP(collapse=4,private='[j_adv,k_idx,l_idx,q_idx,local_inv_ds, local_term_coeff,local_flux1,local_flux2]') do j_adv = advxb, advxe - do l_idx = 0, p ! z_extent - do k_idx = 0, n ! y_extent - do q_idx = 0, m ! x_extent + do l_idx = 0, p ! z_extent + do k_idx = 0, n ! y_extent + do q_idx = 0, m ! x_extent local_inv_ds = 1._wp/dy(k_idx) local_term_coeff = q_prim_vf_arg%vf(contxe + current_idir)%sf(q_idx, k_idx, l_idx) local_flux1 = flux_src_n_vf_arg%vf(j_adv)%sf(q_idx, k_idx - 1, l_idx) local_flux2 = flux_src_n_vf_arg%vf(j_adv)%sf(q_idx, k_idx, l_idx) - rhs_vf_arg(j_adv)%sf(q_idx, k_idx, l_idx) = rhs_vf_arg(j_adv)%sf(q_idx, k_idx, & - & l_idx) + local_inv_ds*local_term_coeff*(local_flux1 - local_flux2) + rhs_vf_arg(j_adv)%sf(q_idx, k_idx, l_idx) = rhs_vf_arg(j_adv)%sf(q_idx, k_idx, l_idx) + & + local_inv_ds*local_term_coeff*(local_flux1 - local_flux2) end do end do end do end do $:END_GPU_PARALLEL_LOOP() - else ! Other Riemann solvers + else ! Other Riemann solvers if (alt_soundspeed) then if (bubbles_euler .neqv. .true.) then - $:GPU_PARALLEL_LOOP(collapse=3, private='[k_idx, l_idx, q_idx, local_inv_ds, local_q_cons_val, & - & local_k_term_val, local_term_coeff, local_flux1, local_flux2]') + $:GPU_PARALLEL_LOOP(collapse=3, private='[k_idx,l_idx,q_idx,local_inv_ds, local_q_cons_val, local_k_term_val, local_term_coeff, local_flux1, local_flux2]') do l_idx = 0, p; do k_idx = 0, n; do q_idx = 0, m - local_inv_ds = 1._wp/dy(k_idx) - local_q_cons_val = q_cons_vf_arg%vf(advxe)%sf(q_idx, k_idx, l_idx) - local_k_term_val = Kterm_arg(q_idx, k_idx, l_idx) ! Access is safe - local_term_coeff = local_q_cons_val - local_k_term_val - local_flux1 = flux_src_n_vf_arg%vf(advxe)%sf(q_idx, k_idx, l_idx) - local_flux2 = flux_src_n_vf_arg%vf(advxe)%sf(q_idx, k_idx - 1, l_idx) - rhs_vf_arg(advxe)%sf(q_idx, k_idx, l_idx) = rhs_vf_arg(advxe)%sf(q_idx, k_idx, & - & l_idx) + local_inv_ds*local_term_coeff*(local_flux1 - local_flux2) - if (cyl_coord) then - rhs_vf_arg(advxe)%sf(q_idx, k_idx, l_idx) = rhs_vf_arg(advxe)%sf(q_idx, k_idx, & - & l_idx) - (local_k_term_val/(2._wp*y_cc(k_idx)))*(local_flux1 + local_flux2) - end if - end do; end do; end do + local_inv_ds = 1._wp/dy(k_idx) + local_q_cons_val = q_cons_vf_arg%vf(advxe)%sf(q_idx, k_idx, l_idx) + local_k_term_val = Kterm_arg(q_idx, k_idx, l_idx) ! Access is safe + local_term_coeff = local_q_cons_val - local_k_term_val + local_flux1 = flux_src_n_vf_arg%vf(advxe)%sf(q_idx, k_idx, l_idx) + local_flux2 = flux_src_n_vf_arg%vf(advxe)%sf(q_idx, k_idx - 1, l_idx) + rhs_vf_arg(advxe)%sf(q_idx, k_idx, l_idx) = rhs_vf_arg(advxe)%sf(q_idx, k_idx, l_idx) + & + local_inv_ds*local_term_coeff*(local_flux1 - local_flux2) + if (cyl_coord) then + rhs_vf_arg(advxe)%sf(q_idx, k_idx, l_idx) = rhs_vf_arg(advxe)%sf(q_idx, k_idx, l_idx) - & + (local_k_term_val/(2._wp*y_cc(k_idx)))*(local_flux1 + local_flux2) + end if + end do; end do; end do $:END_GPU_PARALLEL_LOOP() - $:GPU_PARALLEL_LOOP(collapse=3, private='[k_idx, l_idx, q_idx, local_inv_ds, local_q_cons_val, & - & local_k_term_val, local_term_coeff, local_flux1, local_flux2]') + $:GPU_PARALLEL_LOOP(collapse=3, private='[k_idx,l_idx,q_idx,local_inv_ds, local_q_cons_val, local_k_term_val,local_term_coeff, local_flux1, local_flux2]') do l_idx = 0, p; do k_idx = 0, n; do q_idx = 0, m - local_inv_ds = 1._wp/dy(k_idx) - local_q_cons_val = q_cons_vf_arg%vf(advxb)%sf(q_idx, k_idx, l_idx) - local_k_term_val = Kterm_arg(q_idx, k_idx, l_idx) ! Access is safe - local_term_coeff = local_q_cons_val + local_k_term_val - local_flux1 = flux_src_n_vf_arg%vf(advxb)%sf(q_idx, k_idx, l_idx) - local_flux2 = flux_src_n_vf_arg%vf(advxb)%sf(q_idx, k_idx - 1, l_idx) - rhs_vf_arg(advxb)%sf(q_idx, k_idx, l_idx) = rhs_vf_arg(advxb)%sf(q_idx, k_idx, & - & l_idx) + local_inv_ds*local_term_coeff*(local_flux1 - local_flux2) - if (cyl_coord) then - rhs_vf_arg(advxb)%sf(q_idx, k_idx, l_idx) = rhs_vf_arg(advxb)%sf(q_idx, k_idx, & - & l_idx) + (local_k_term_val/(2._wp*y_cc(k_idx)))*(local_flux1 + local_flux2) - end if - end do; end do; end do + local_inv_ds = 1._wp/dy(k_idx) + local_q_cons_val = q_cons_vf_arg%vf(advxb)%sf(q_idx, k_idx, l_idx) + local_k_term_val = Kterm_arg(q_idx, k_idx, l_idx) ! Access is safe + local_term_coeff = local_q_cons_val + local_k_term_val + local_flux1 = flux_src_n_vf_arg%vf(advxb)%sf(q_idx, k_idx, l_idx) + local_flux2 = flux_src_n_vf_arg%vf(advxb)%sf(q_idx, k_idx - 1, l_idx) + rhs_vf_arg(advxb)%sf(q_idx, k_idx, l_idx) = rhs_vf_arg(advxb)%sf(q_idx, k_idx, l_idx) + & + local_inv_ds*local_term_coeff*(local_flux1 - local_flux2) + if (cyl_coord) then + rhs_vf_arg(advxb)%sf(q_idx, k_idx, l_idx) = rhs_vf_arg(advxb)%sf(q_idx, k_idx, l_idx) + & + (local_k_term_val/(2._wp*y_cc(k_idx)))*(local_flux1 + local_flux2) + end if + end do; end do; end do $:END_GPU_PARALLEL_LOOP() end if - else ! NOT alt_soundspeed - $:GPU_PARALLEL_LOOP(collapse=4,private='[j_adv, k_idx, l_idx, q_idx, local_inv_ds, local_term_coeff, & - & local_flux1, local_flux2]') + else ! NOT alt_soundspeed + $:GPU_PARALLEL_LOOP(collapse=4,private='[j_adv,k_idx,l_idx,q_idx,local_inv_ds, local_term_coeff,local_flux1,local_flux2]') do j_adv = advxb, advxe do l_idx = 0, p; do k_idx = 0, n; do q_idx = 0, m - local_inv_ds = 1._wp/dy(k_idx) - local_term_coeff = q_cons_vf_arg%vf(j_adv)%sf(q_idx, k_idx, l_idx) - local_flux1 = flux_src_n_vf_arg%vf(j_adv)%sf(q_idx, k_idx, l_idx) - local_flux2 = flux_src_n_vf_arg%vf(j_adv)%sf(q_idx, k_idx - 1, l_idx) - rhs_vf_arg(j_adv)%sf(q_idx, k_idx, l_idx) = rhs_vf_arg(j_adv)%sf(q_idx, k_idx, & - & l_idx) + local_inv_ds*local_term_coeff*(local_flux1 - local_flux2) - end do; end do; end do + local_inv_ds = 1._wp/dy(k_idx) + local_term_coeff = q_cons_vf_arg%vf(j_adv)%sf(q_idx, k_idx, l_idx) + local_flux1 = flux_src_n_vf_arg%vf(j_adv)%sf(q_idx, k_idx, l_idx) + local_flux2 = flux_src_n_vf_arg%vf(j_adv)%sf(q_idx, k_idx - 1, l_idx) + rhs_vf_arg(j_adv)%sf(q_idx, k_idx, l_idx) = rhs_vf_arg(j_adv)%sf(q_idx, k_idx, l_idx) + & + local_inv_ds*local_term_coeff*(local_flux1 - local_flux2) + end do; end do; end do end do $:END_GPU_PARALLEL_LOOP() end if end if - case (3) - ! z-direction: loops l_idx (x), q_idx (y), k_idx (z); sf(l_idx, q_idx, k_idx); dz(k_idx); Kterm(l_idx,q_idx,k_idx) + + case (3) ! z-direction: loops l_idx (x), q_idx (y), k_idx (z); sf(l_idx, q_idx, k_idx); dz(k_idx); Kterm(l_idx,q_idx,k_idx) if (grid_geometry == 3) then use_standard_riemann = (riemann_solver == 1) else @@ -1300,95 +1493,95 @@ contains end if if (use_standard_riemann) then - $:GPU_PARALLEL_LOOP(collapse=4,private='[j_adv, k_idx, l_idx, q_idx, local_inv_ds, local_term_coeff, & - & local_flux1, local_flux2]') + $:GPU_PARALLEL_LOOP(collapse=4,private='[j_adv,k_idx,l_idx,q_idx,local_inv_ds, local_term_coeff,local_flux1,local_flux2]') do j_adv = advxb, advxe - do k_idx = 0, p ! z_extent - do q_idx = 0, n ! y_extent - do l_idx = 0, m ! x_extent + do k_idx = 0, p ! z_extent + do q_idx = 0, n ! y_extent + do l_idx = 0, m ! x_extent local_inv_ds = 1._wp/dz(k_idx) local_term_coeff = q_prim_vf_arg%vf(contxe + current_idir)%sf(l_idx, q_idx, k_idx) local_flux1 = flux_src_n_vf_arg%vf(j_adv)%sf(l_idx, q_idx, k_idx - 1) local_flux2 = flux_src_n_vf_arg%vf(j_adv)%sf(l_idx, q_idx, k_idx) - rhs_vf_arg(j_adv)%sf(l_idx, q_idx, k_idx) = rhs_vf_arg(j_adv)%sf(l_idx, q_idx, & - & k_idx) + local_inv_ds*local_term_coeff*(local_flux1 - local_flux2) + rhs_vf_arg(j_adv)%sf(l_idx, q_idx, k_idx) = rhs_vf_arg(j_adv)%sf(l_idx, q_idx, k_idx) + & + local_inv_ds*local_term_coeff*(local_flux1 - local_flux2) end do end do end do end do $:END_GPU_PARALLEL_LOOP() - else ! Other Riemann solvers + else ! Other Riemann solvers if (alt_soundspeed) then if (bubbles_euler .neqv. .true.) then - $:GPU_PARALLEL_LOOP(collapse=3, private='[k_idx, l_idx, q_idx, local_inv_ds, local_q_cons_val, & - & local_k_term_val, local_term_coeff, local_flux1, local_flux2]') + $:GPU_PARALLEL_LOOP(collapse=3, private='[k_idx,l_idx,q_idx,local_inv_ds,local_q_cons_val, local_k_term_val, local_term_coeff, local_flux1, local_flux2]') do k_idx = 0, p; do q_idx = 0, n; do l_idx = 0, m - local_inv_ds = 1._wp/dz(k_idx) - local_q_cons_val = q_cons_vf_arg%vf(advxe)%sf(l_idx, q_idx, k_idx) - local_k_term_val = Kterm_arg(l_idx, q_idx, k_idx) ! Access is safe - local_term_coeff = local_q_cons_val - local_k_term_val - local_flux1 = flux_src_n_vf_arg%vf(advxe)%sf(l_idx, q_idx, k_idx) - local_flux2 = flux_src_n_vf_arg%vf(advxe)%sf(l_idx, q_idx, k_idx - 1) - rhs_vf_arg(advxe)%sf(l_idx, q_idx, k_idx) = rhs_vf_arg(advxe)%sf(l_idx, q_idx, & - & k_idx) + local_inv_ds*local_term_coeff*(local_flux1 - local_flux2) - end do; end do; end do + local_inv_ds = 1._wp/dz(k_idx) + local_q_cons_val = q_cons_vf_arg%vf(advxe)%sf(l_idx, q_idx, k_idx) + local_k_term_val = Kterm_arg(l_idx, q_idx, k_idx) ! Access is safe + local_term_coeff = local_q_cons_val - local_k_term_val + local_flux1 = flux_src_n_vf_arg%vf(advxe)%sf(l_idx, q_idx, k_idx) + local_flux2 = flux_src_n_vf_arg%vf(advxe)%sf(l_idx, q_idx, k_idx - 1) + rhs_vf_arg(advxe)%sf(l_idx, q_idx, k_idx) = rhs_vf_arg(advxe)%sf(l_idx, q_idx, k_idx) + & + local_inv_ds*local_term_coeff*(local_flux1 - local_flux2) + end do; end do; end do $:END_GPU_PARALLEL_LOOP() - $:GPU_PARALLEL_LOOP(collapse=3, private='[k_idx, l_idx, q_idx, local_inv_ds, local_q_cons_val, & - & local_k_term_val, local_term_coeff, local_flux1, local_flux2]') + $:GPU_PARALLEL_LOOP(collapse=3, private='[k_idx,l_idx,q_idx,local_inv_ds, local_q_cons_val, local_k_term_val, local_term_coeff, local_flux1, local_flux2]') do k_idx = 0, p; do q_idx = 0, n; do l_idx = 0, m - local_inv_ds = 1._wp/dz(k_idx) - local_q_cons_val = q_cons_vf_arg%vf(advxb)%sf(l_idx, q_idx, k_idx) - local_k_term_val = Kterm_arg(l_idx, q_idx, k_idx) ! Access is safe - local_term_coeff = local_q_cons_val + local_k_term_val - local_flux1 = flux_src_n_vf_arg%vf(advxb)%sf(l_idx, q_idx, k_idx) - local_flux2 = flux_src_n_vf_arg%vf(advxb)%sf(l_idx, q_idx, k_idx - 1) - rhs_vf_arg(advxb)%sf(l_idx, q_idx, k_idx) = rhs_vf_arg(advxb)%sf(l_idx, q_idx, & - & k_idx) + local_inv_ds*local_term_coeff*(local_flux1 - local_flux2) - end do; end do; end do + local_inv_ds = 1._wp/dz(k_idx) + local_q_cons_val = q_cons_vf_arg%vf(advxb)%sf(l_idx, q_idx, k_idx) + local_k_term_val = Kterm_arg(l_idx, q_idx, k_idx) ! Access is safe + local_term_coeff = local_q_cons_val + local_k_term_val + local_flux1 = flux_src_n_vf_arg%vf(advxb)%sf(l_idx, q_idx, k_idx) + local_flux2 = flux_src_n_vf_arg%vf(advxb)%sf(l_idx, q_idx, k_idx - 1) + rhs_vf_arg(advxb)%sf(l_idx, q_idx, k_idx) = rhs_vf_arg(advxb)%sf(l_idx, q_idx, k_idx) + & + local_inv_ds*local_term_coeff*(local_flux1 - local_flux2) + end do; end do; end do $:END_GPU_PARALLEL_LOOP() end if - else ! NOT alt_soundspeed - $:GPU_PARALLEL_LOOP(collapse=4, private='[j_adv, k_idx, l_idx, q_idx, local_inv_ds, local_term_coeff, & - & local_flux1, local_flux2]') + else ! NOT alt_soundspeed + $:GPU_PARALLEL_LOOP(collapse=4, private='[j_adv,k_idx,l_idx,q_idx,local_inv_ds, local_term_coeff,local_flux1,local_flux2]') do j_adv = advxb, advxe do k_idx = 0, p; do q_idx = 0, n; do l_idx = 0, m - local_inv_ds = 1._wp/dz(k_idx) - local_term_coeff = q_cons_vf_arg%vf(j_adv)%sf(l_idx, q_idx, k_idx) - local_flux1 = flux_src_n_vf_arg%vf(j_adv)%sf(l_idx, q_idx, k_idx) - local_flux2 = flux_src_n_vf_arg%vf(j_adv)%sf(l_idx, q_idx, k_idx - 1) - rhs_vf_arg(j_adv)%sf(l_idx, q_idx, k_idx) = rhs_vf_arg(j_adv)%sf(l_idx, q_idx, & - & k_idx) + local_inv_ds*local_term_coeff*(local_flux1 - local_flux2) - end do; end do; end do + local_inv_ds = 1._wp/dz(k_idx) + local_term_coeff = q_cons_vf_arg%vf(j_adv)%sf(l_idx, q_idx, k_idx) + local_flux1 = flux_src_n_vf_arg%vf(j_adv)%sf(l_idx, q_idx, k_idx) + local_flux2 = flux_src_n_vf_arg%vf(j_adv)%sf(l_idx, q_idx, k_idx - 1) + rhs_vf_arg(j_adv)%sf(l_idx, q_idx, k_idx) = rhs_vf_arg(j_adv)%sf(l_idx, q_idx, k_idx) + & + local_inv_ds*local_term_coeff*(local_flux1 - local_flux2) + end do; end do; end do end do $:END_GPU_PARALLEL_LOOP() end if end if end select - end subroutine s_add_directional_advection_source_terms end subroutine s_compute_advection_source_term - !> Add viscous, surface-tension, and species-diffusion source flux contributions to the RHS for a given direction - subroutine s_compute_additional_physics_rhs(idir, q_prim_vf, rhs_vf, flux_src_n_in, dq_prim_dx_vf, dq_prim_dy_vf, dq_prim_dz_vf) + !> @brief Adds viscous, surface-tension, and species-diffusion source flux contributions to the RHS for a given direction. + subroutine s_compute_additional_physics_rhs(idir, q_prim_vf, rhs_vf, flux_src_n_in, & + dq_prim_dx_vf, dq_prim_dy_vf, dq_prim_dz_vf) - integer, intent(in) :: idir - type(scalar_field), dimension(sys_size), intent(in) :: q_prim_vf + integer, intent(in) :: idir + type(scalar_field), dimension(sys_size), intent(in) :: q_prim_vf type(scalar_field), dimension(sys_size), intent(inout) :: rhs_vf - type(scalar_field), dimension(sys_size), intent(in) :: flux_src_n_in - type(scalar_field), dimension(sys_size), intent(in) :: dq_prim_dx_vf, dq_prim_dy_vf, dq_prim_dz_vf - integer :: i, j, k, l + type(scalar_field), dimension(sys_size), intent(in) :: flux_src_n_in + type(scalar_field), dimension(sys_size), intent(in) :: dq_prim_dx_vf, dq_prim_dy_vf, dq_prim_dz_vf + + integer :: i, j, k, l - if (idir == 1) then ! x-direction + if (idir == 1) then ! x-direction if (surface_tension) then - $:GPU_PARALLEL_LOOP(private='[j, k, l]', collapse=3) + $:GPU_PARALLEL_LOOP(private='[j,k,l]', collapse=3) do l = 0, p do k = 0, n do j = 0, m - rhs_vf(c_idx)%sf(j, k, l) = rhs_vf(c_idx)%sf(j, k, l) + 1._wp/dx(j)*q_prim_vf(c_idx)%sf(j, k, & - & l)*(flux_src_n_in(advxb)%sf(j, k, l) - flux_src_n_in(advxb)%sf(j - 1, k, l)) + rhs_vf(c_idx)%sf(j, k, l) = & + rhs_vf(c_idx)%sf(j, k, l) + 1._wp/dx(j)* & + q_prim_vf(c_idx)%sf(j, k, l)* & + (flux_src_n_in(advxb)%sf(j, k, l) - & + flux_src_n_in(advxb)%sf(j - 1, k, l)) end do end do end do @@ -1396,29 +1589,34 @@ contains end if if ((surface_tension .or. viscous) .or. chem_params%diffusion) then - $:GPU_PARALLEL_LOOP(private='[j, k, l]', collapse=3) + $:GPU_PARALLEL_LOOP(private='[j,k,l]', collapse=3) do l = 0, p do k = 0, n do j = 0, m if (surface_tension .or. viscous) then $:GPU_LOOP(parallelism='[seq]') do i = momxb, E_idx - rhs_vf(i)%sf(j, k, l) = rhs_vf(i)%sf(j, k, l) + 1._wp/dx(j)*(flux_src_n_in(i)%sf(j - 1, k, & - & l) - flux_src_n_in(i)%sf(j, k, l)) + rhs_vf(i)%sf(j, k, l) = & + rhs_vf(i)%sf(j, k, l) + 1._wp/dx(j)* & + (flux_src_n_in(i)%sf(j - 1, k, l) & + - flux_src_n_in(i)%sf(j, k, l)) end do end if if (chem_params%diffusion) then $:GPU_LOOP(parallelism='[seq]') do i = chemxb, chemxe - rhs_vf(i)%sf(j, k, l) = rhs_vf(i)%sf(j, k, l) + 1._wp/dx(j)*(flux_src_n_in(i)%sf(j - 1, k, & - & l) - flux_src_n_in(i)%sf(j, k, l)) + rhs_vf(i)%sf(j, k, l) = & + rhs_vf(i)%sf(j, k, l) + 1._wp/dx(j)* & + (flux_src_n_in(i)%sf(j - 1, k, l) & + - flux_src_n_in(i)%sf(j, k, l)) end do if (.not. viscous) then - rhs_vf(E_idx)%sf(j, k, l) = rhs_vf(E_idx)%sf(j, k, & - & l) + 1._wp/dx(j)*(flux_src_n_in(E_idx)%sf(j - 1, k, l) - flux_src_n_in(E_idx)%sf(j, & - & k, l)) + rhs_vf(E_idx)%sf(j, k, l) = & + rhs_vf(E_idx)%sf(j, k, l) + 1._wp/dx(j)* & + (flux_src_n_in(E_idx)%sf(j - 1, k, l) & + - flux_src_n_in(E_idx)%sf(j, k, l)) end if end if end do @@ -1426,14 +1624,19 @@ contains end do $:END_GPU_PARALLEL_LOOP() end if - else if (idir == 2) then ! y-direction + + elseif (idir == 2) then ! y-direction + if (surface_tension) then - $:GPU_PARALLEL_LOOP(private='[j, k, l]', collapse=3) + $:GPU_PARALLEL_LOOP(private='[j,k,l]', collapse=3) do l = 0, p do k = 0, n do j = 0, m - rhs_vf(c_idx)%sf(j, k, l) = rhs_vf(c_idx)%sf(j, k, l) + 1._wp/dy(k)*q_prim_vf(c_idx)%sf(j, k, & - & l)*(flux_src_n_in(advxb)%sf(j, k, l) - flux_src_n_in(advxb)%sf(j, k - 1, l)) + rhs_vf(c_idx)%sf(j, k, l) = & + rhs_vf(c_idx)%sf(j, k, l) + 1._wp/dy(k)* & + q_prim_vf(c_idx)%sf(j, k, l)* & + (flux_src_n_in(advxb)%sf(j, k, l) - & + flux_src_n_in(advxb)%sf(j, k - 1, l)) end do end do end do @@ -1443,65 +1646,83 @@ contains if (cyl_coord .and. ((bc_y%beg == -2) .or. (bc_y%beg == -14))) then if (viscous .or. dummy) then if (p > 0) then - call s_compute_viscous_stress_cylindrical_boundary(q_prim_vf, dq_prim_dx_vf(mom_idx%beg:mom_idx%end), & - & dq_prim_dy_vf(mom_idx%beg:mom_idx%end), dq_prim_dz_vf(mom_idx%beg:mom_idx%end), tau_Re_vf, & - & idwbuff(1), idwbuff(2), idwbuff(3)) + call s_compute_viscous_stress_cylindrical_boundary(q_prim_vf, & + dq_prim_dx_vf(mom_idx%beg:mom_idx%end), & + dq_prim_dy_vf(mom_idx%beg:mom_idx%end), & + dq_prim_dz_vf(mom_idx%beg:mom_idx%end), & + tau_Re_vf, & + idwbuff(1), idwbuff(2), idwbuff(3)) else - call s_compute_viscous_stress_cylindrical_boundary(q_prim_vf, dq_prim_dx_vf(mom_idx%beg:mom_idx%end), & - & dq_prim_dy_vf(mom_idx%beg:mom_idx%end), dq_prim_dz_vf(mom_idx%beg:mom_idx%end), tau_Re_vf, & - & idwbuff(1), idwbuff(2), idwbuff(3)) + call s_compute_viscous_stress_cylindrical_boundary(q_prim_vf, & + dq_prim_dx_vf(mom_idx%beg:mom_idx%end), & + dq_prim_dy_vf(mom_idx%beg:mom_idx%end), & + dq_prim_dz_vf(mom_idx%beg:mom_idx%end), & + tau_Re_vf, & + idwbuff(1), idwbuff(2), idwbuff(3)) end if - $:GPU_PARALLEL_LOOP(private='[i, j, l]', collapse=2) + $:GPU_PARALLEL_LOOP(private='[i,j,l]', collapse=2) do l = 0, p do j = 0, m $:GPU_LOOP(parallelism='[seq]') do i = momxb, E_idx - rhs_vf(i)%sf(j, 0, l) = rhs_vf(i)%sf(j, 0, l) + 1._wp/(y_cc(1) - y_cc(-1))*(tau_Re_vf(i)%sf(j, & - & -1, l) - tau_Re_vf(i)%sf(j, 1, l)) + rhs_vf(i)%sf(j, 0, l) = & + rhs_vf(i)%sf(j, 0, l) + 1._wp/(y_cc(1) - y_cc(-1))* & + (tau_Re_vf(i)%sf(j, -1, l) & + - tau_Re_vf(i)%sf(j, 1, l)) end do end do end do $:END_GPU_PARALLEL_LOOP() + end if - $:GPU_PARALLEL_LOOP(private='[i, j, k, l]', collapse=3) + $:GPU_PARALLEL_LOOP(private='[i,j,k,l]', collapse=3) do l = 0, p do k = 1, n do j = 0, m $:GPU_LOOP(parallelism='[seq]') do i = momxb, E_idx - rhs_vf(i)%sf(j, k, l) = rhs_vf(i)%sf(j, k, l) + 1._wp/dy(k)*(flux_src_n_in(i)%sf(j, k - 1, & - & l) - flux_src_n_in(i)%sf(j, k, l)) + rhs_vf(i)%sf(j, k, l) = & + rhs_vf(i)%sf(j, k, l) + 1._wp/dy(k)* & + (flux_src_n_in(i)%sf(j, k - 1, l) & + - flux_src_n_in(i)%sf(j, k, l)) end do end do end do end do $:END_GPU_PARALLEL_LOOP() + else + if ((surface_tension .or. viscous) .or. chem_params%diffusion) then - $:GPU_PARALLEL_LOOP(private='[i, j, k, l]', collapse=3) + $:GPU_PARALLEL_LOOP(private='[i,j,k,l]', collapse=3) do l = 0, p do k = 0, n do j = 0, m if (surface_tension .or. viscous) then $:GPU_LOOP(parallelism='[seq]') do i = momxb, E_idx - rhs_vf(i)%sf(j, k, l) = rhs_vf(i)%sf(j, k, l) + 1._wp/dy(k)*(flux_src_n_in(i)%sf(j, & - & k - 1, l) - flux_src_n_in(i)%sf(j, k, l)) + rhs_vf(i)%sf(j, k, l) = & + rhs_vf(i)%sf(j, k, l) + 1._wp/dy(k)* & + (flux_src_n_in(i)%sf(j, k - 1, l) & + - flux_src_n_in(i)%sf(j, k, l)) end do end if if (chem_params%diffusion) then $:GPU_LOOP(parallelism='[seq]') do i = chemxb, chemxe - rhs_vf(i)%sf(j, k, l) = rhs_vf(i)%sf(j, k, l) + 1._wp/dy(k)*(flux_src_n_in(i)%sf(j, & - & k - 1, l) - flux_src_n_in(i)%sf(j, k, l)) + rhs_vf(i)%sf(j, k, l) = & + rhs_vf(i)%sf(j, k, l) + 1._wp/dy(k)* & + (flux_src_n_in(i)%sf(j, k - 1, l) & + - flux_src_n_in(i)%sf(j, k, l)) end do if (.not. viscous) then - rhs_vf(E_idx)%sf(j, k, l) = rhs_vf(E_idx)%sf(j, k, & - & l) + 1._wp/dy(k)*(flux_src_n_in(E_idx)%sf(j, k - 1, & - & l) - flux_src_n_in(E_idx)%sf(j, k, l)) + rhs_vf(E_idx)%sf(j, k, l) = & + rhs_vf(E_idx)%sf(j, k, l) + 1._wp/dy(k)* & + (flux_src_n_in(E_idx)%sf(j, k - 1, l) & + - flux_src_n_in(E_idx)%sf(j, k, l)) end if end if end do @@ -1511,17 +1732,21 @@ contains end if end if - ! Applying the geometrical viscous Riemann source fluxes calculated as average of values at cell boundaries + ! Applying the geometrical viscous Riemann source fluxes calculated as average + ! of values at cell boundaries if (cyl_coord) then if ((bc_y%beg == -2) .or. (bc_y%beg == -14)) then - $:GPU_PARALLEL_LOOP(private='[i, j, k, l]', collapse=3) + + $:GPU_PARALLEL_LOOP(private='[i,j,k,l]', collapse=3) do l = 0, p do k = 1, n do j = 0, m $:GPU_LOOP(parallelism='[seq]') do i = momxb, E_idx - rhs_vf(i)%sf(j, k, l) = rhs_vf(i)%sf(j, k, l) - 5.e-1_wp/y_cc(k)*(flux_src_n_in(i)%sf(j, & - & k - 1, l) + flux_src_n_in(i)%sf(j, k, l)) + rhs_vf(i)%sf(j, k, l) = & + rhs_vf(i)%sf(j, k, l) - 5.e-1_wp/y_cc(k)* & + (flux_src_n_in(i)%sf(j, k - 1, l) & + + flux_src_n_in(i)%sf(j, k, l)) end do end do end do @@ -1529,26 +1754,31 @@ contains $:END_GPU_PARALLEL_LOOP() if (viscous .or. dummy) then - $:GPU_PARALLEL_LOOP(private='[i, j, l]', collapse=2) + $:GPU_PARALLEL_LOOP(private='[i,j,l]', collapse=2) do l = 0, p do j = 0, m $:GPU_LOOP(parallelism='[seq]') do i = momxb, E_idx - rhs_vf(i)%sf(j, 0, l) = rhs_vf(i)%sf(j, 0, l) - 1._wp/y_cc(0)*tau_Re_vf(i)%sf(j, 0, l) + rhs_vf(i)%sf(j, 0, l) = & + rhs_vf(i)%sf(j, 0, l) - 1._wp/y_cc(0)* & + tau_Re_vf(i)%sf(j, 0, l) end do end do end do $:END_GPU_PARALLEL_LOOP() end if else - $:GPU_PARALLEL_LOOP(private='[i, j, k, l]', collapse=3) + + $:GPU_PARALLEL_LOOP(private='[i,j,k,l]', collapse=3) do l = 0, p do k = 0, n do j = 0, m $:GPU_LOOP(parallelism='[seq]') do i = momxb, E_idx - rhs_vf(i)%sf(j, k, l) = rhs_vf(i)%sf(j, k, l) - 5.e-1_wp/y_cc(k)*(flux_src_n_in(i)%sf(j, & - & k - 1, l) + flux_src_n_in(i)%sf(j, k, l)) + rhs_vf(i)%sf(j, k, l) = & + rhs_vf(i)%sf(j, k, l) - 5.e-1_wp/y_cc(k)* & + (flux_src_n_in(i)%sf(j, k - 1, l) & + + flux_src_n_in(i)%sf(j, k, l)) end do end do end do @@ -1556,14 +1786,19 @@ contains $:END_GPU_PARALLEL_LOOP() end if end if - else if (idir == 3) then ! z-direction + + elseif (idir == 3) then ! z-direction + if (surface_tension) then - $:GPU_PARALLEL_LOOP(private='[j, k, l]', collapse=3) + $:GPU_PARALLEL_LOOP(private='[j,k,l]', collapse=3) do l = 0, p do k = 0, n do j = 0, m - rhs_vf(c_idx)%sf(j, k, l) = rhs_vf(c_idx)%sf(j, k, l) + 1._wp/dz(l)*q_prim_vf(c_idx)%sf(j, k, & - & l)*(flux_src_n_in(advxb)%sf(j, k, l) - flux_src_n_in(advxb)%sf(j, k, l - 1)) + rhs_vf(c_idx)%sf(j, k, l) = & + rhs_vf(c_idx)%sf(j, k, l) + 1._wp/dz(l)* & + q_prim_vf(c_idx)%sf(j, k, l)* & + (flux_src_n_in(advxb)%sf(j, k, l) - & + flux_src_n_in(advxb)%sf(j, k, l - 1)) end do end do end do @@ -1571,28 +1806,33 @@ contains end if if ((surface_tension .or. viscous) .or. chem_params%diffusion) then - $:GPU_PARALLEL_LOOP(private='[i, j, k, l]', collapse=3) + $:GPU_PARALLEL_LOOP(private='[i,j,k,l]', collapse=3) do l = 0, p do k = 0, n do j = 0, m if (surface_tension .or. viscous) then $:GPU_LOOP(parallelism='[seq]') do i = momxb, E_idx - rhs_vf(i)%sf(j, k, l) = rhs_vf(i)%sf(j, k, l) + 1._wp/dz(l)*(flux_src_n_in(i)%sf(j, k, & - & l - 1) - flux_src_n_in(i)%sf(j, k, l)) + rhs_vf(i)%sf(j, k, l) = & + rhs_vf(i)%sf(j, k, l) + 1._wp/dz(l)* & + (flux_src_n_in(i)%sf(j, k, l - 1) & + - flux_src_n_in(i)%sf(j, k, l)) end do end if if (chem_params%diffusion) then $:GPU_LOOP(parallelism='[seq]') do i = chemxb, chemxe - rhs_vf(i)%sf(j, k, l) = rhs_vf(i)%sf(j, k, l) + 1._wp/dz(l)*(flux_src_n_in(i)%sf(j, k, & - & l - 1) - flux_src_n_in(i)%sf(j, k, l)) + rhs_vf(i)%sf(j, k, l) = & + rhs_vf(i)%sf(j, k, l) + 1._wp/dz(l)* & + (flux_src_n_in(i)%sf(j, k, l - 1) & + - flux_src_n_in(i)%sf(j, k, l)) end do if (.not. viscous) then - rhs_vf(E_idx)%sf(j, k, l) = rhs_vf(E_idx)%sf(j, k, & - & l) + 1._wp/dz(l)*(flux_src_n_in(E_idx)%sf(j, k, l - 1) - flux_src_n_in(E_idx)%sf(j, & - & k, l)) + rhs_vf(E_idx)%sf(j, k, l) = & + rhs_vf(E_idx)%sf(j, k, l) + 1._wp/dz(l)* & + (flux_src_n_in(E_idx)%sf(j, k, l - 1) & + - flux_src_n_in(E_idx)%sf(j, k, l)) end if end if end do @@ -1602,15 +1842,19 @@ contains end if if (grid_geometry == 3) then - $:GPU_PARALLEL_LOOP(private='[j, k, l]', collapse=3) + $:GPU_PARALLEL_LOOP(private='[j,k,l]', collapse=3) do l = 0, p do k = 0, n do j = 0, m - rhs_vf(momxb + 1)%sf(j, k, l) = rhs_vf(momxb + 1)%sf(j, k, l) + 5.e-1_wp*(flux_src_n_in(momxe)%sf(j, & - & k, l - 1) + flux_src_n_in(momxe)%sf(j, k, l)) - - rhs_vf(momxe)%sf(j, k, l) = rhs_vf(momxe)%sf(j, k, l) - 5.e-1_wp*(flux_src_n_in(momxb + 1)%sf(j, k, & - & l - 1) + flux_src_n_in(momxb + 1)%sf(j, k, l)) + rhs_vf(momxb + 1)%sf(j, k, l) = & + rhs_vf(momxb + 1)%sf(j, k, l) + 5.e-1_wp* & + (flux_src_n_in(momxe)%sf(j, k, l - 1) & + + flux_src_n_in(momxe)%sf(j, k, l)) + + rhs_vf(momxe)%sf(j, k, l) = & + rhs_vf(momxe)%sf(j, k, l) - 5.e-1_wp* & + (flux_src_n_in(momxb + 1)%sf(j, k, l - 1) & + + flux_src_n_in(momxb + 1)%sf(j, k, l)) end do end do end do @@ -1620,14 +1864,28 @@ contains end subroutine s_compute_additional_physics_rhs - !> Reconstruct left and right cell-boundary values from cell-averaged variables - subroutine s_reconstruct_cell_boundary_values(v_vf, vL_x, vL_y, vL_z, vR_x, vR_y, vR_z, norm_dir) + !> The purpose of this subroutine is to WENO-reconstruct the + !! left and the right cell-boundary values, including values + !! at the Gaussian quadrature points, from the cell-averaged + !! variables. + !! @param v_vf Cell-average variables + !! @param vL_x Left reconstructed cell-boundary values in x + !! @param vL_y Left reconstructed cell-boundary values in y + !! @param vL_z Left reconstructed cell-boundary values in z + !! @param vR_x Right reconstructed cell-boundary values in x + !! @param vR_y Right reconstructed cell-boundary values in y + !! @param vR_z Right reconstructed cell-boundary values in z + !! @param norm_dir Splitting coordinate direction + subroutine s_reconstruct_cell_boundary_values(v_vf, vL_x, vL_y, vL_z, vR_x, vR_y, vR_z, & + norm_dir) type(scalar_field), dimension(iv%beg:iv%end), intent(in) :: v_vf - real(wp), dimension(idwbuff(1)%beg:,idwbuff(2)%beg:,idwbuff(3)%beg:,1:), intent(inout) :: vL_x, vL_y, vL_z - real(wp), dimension(idwbuff(1)%beg:,idwbuff(2)%beg:,idwbuff(3)%beg:,1:), intent(inout) :: vR_x, vR_y, vR_z + real(wp), dimension(idwbuff(1)%beg:, idwbuff(2)%beg:, idwbuff(3)%beg:, 1:), intent(inout) :: vL_x, vL_y, vL_z + real(wp), dimension(idwbuff(1)%beg:, idwbuff(2)%beg:, idwbuff(3)%beg:, 1:), intent(inout) :: vR_x, vR_y, vR_z integer, intent(in) :: norm_dir - integer :: recon_dir !< Coordinate direction of the reconstruction + + integer :: recon_dir !< Coordinate direction of the reconstruction + integer :: i, j, k, l #:for SCHEME, TYPE in [('weno','WENO_TYPE'), ('muscl','MUSCL_TYPE')] @@ -1637,10 +1895,12 @@ contains is1 = idwbuff(1); is2 = idwbuff(2); is3 = idwbuff(3) recon_dir = 1; is1%beg = is1%beg + ${SCHEME}$_polyn is1%end = is1%end - ${SCHEME}$_polyn - else if (norm_dir == 2) then + + elseif (norm_dir == 2) then is1 = idwbuff(2); is2 = idwbuff(1); is3 = idwbuff(3) recon_dir = 2; is1%beg = is1%beg + ${SCHEME}$_polyn is1%end = is1%end - ${SCHEME}$_polyn + else is1 = idwbuff(3); is2 = idwbuff(2); is3 = idwbuff(1) recon_dir = 3; is1%beg = is1%beg + ${SCHEME}$_polyn @@ -1649,31 +1909,38 @@ contains if (n > 0) then if (p > 0) then - call s_${SCHEME}$ (v_vf(iv%beg:iv%end), vL_x(:,:,:,iv%beg:iv%end), vL_y(:,:,:,iv%beg:iv%end), vL_z(:,:,:, & - & iv%beg:iv%end), vR_x(:,:,:,iv%beg:iv%end), vR_y(:,:,:,iv%beg:iv%end), vR_z(:,:,:, & - & iv%beg:iv%end), recon_dir, is1, is2, is3) + call s_${SCHEME}$ (v_vf(iv%beg:iv%end), & + vL_x(:, :, :, iv%beg:iv%end), vL_y(:, :, :, iv%beg:iv%end), vL_z(:, :, :, iv%beg:iv%end), vR_x(:, :, :, iv%beg:iv%end), vR_y(:, :, :, iv%beg:iv%end), vR_z(:, :, :, iv%beg:iv%end), & + recon_dir, & + is1, is2, is3) else - call s_${SCHEME}$ (v_vf(iv%beg:iv%end), vL_x(:,:,:,iv%beg:iv%end), vL_y(:,:,:,iv%beg:iv%end), vL_z(:,:,:, & - & :), vR_x(:,:,:,iv%beg:iv%end), vR_y(:,:,:,iv%beg:iv%end), vR_z(:,:,:,:), recon_dir, & - & is1, is2, is3) + call s_${SCHEME}$ (v_vf(iv%beg:iv%end), & + vL_x(:, :, :, iv%beg:iv%end), vL_y(:, :, :, iv%beg:iv%end), vL_z(:, :, :, :), vR_x(:, :, :, iv%beg:iv%end), vR_y(:, :, :, iv%beg:iv%end), vR_z(:, :, :, :), & + recon_dir, & + is1, is2, is3) end if else - call s_${SCHEME}$ (v_vf(iv%beg:iv%end), vL_x(:,:,:,iv%beg:iv%end), vL_y(:,:,:,:), vL_z(:,:,:,:), vR_x(:,:,:, & - & iv%beg:iv%end), vR_y(:,:,:,:), vR_z(:,:,:,:), recon_dir, is1, is2, is3) + + call s_${SCHEME}$ (v_vf(iv%beg:iv%end), & + vL_x(:, :, :, iv%beg:iv%end), vL_y(:, :, :, :), vL_z(:, :, :, :), vR_x(:, :, :, iv%beg:iv%end), vR_y(:, :, :, :), vR_z(:, :, :, :), & + recon_dir, & + is1, is2, is3) end if end if #:endfor - end subroutine s_reconstruct_cell_boundary_values - !> Perform first-order (piecewise constant) reconstruction of left and right cell-boundary values - subroutine s_reconstruct_cell_boundary_values_first_order(v_vf, vL_x, vL_y, vL_z, vR_x, vR_y, vR_z, norm_dir) + !> @brief Performs first-order (piecewise constant) reconstruction of left and right cell-boundary values. + subroutine s_reconstruct_cell_boundary_values_first_order(v_vf, vL_x, vL_y, vL_z, vR_x, vR_y, vR_z, & + norm_dir) type(scalar_field), dimension(iv%beg:iv%end), intent(in) :: v_vf - real(wp), dimension(idwbuff(1)%beg:,idwbuff(2)%beg:,idwbuff(3)%beg:,1:), intent(inout) :: vL_x, vL_y, vL_z - real(wp), dimension(idwbuff(1)%beg:,idwbuff(2)%beg:,idwbuff(3)%beg:,1:), intent(inout) :: vR_x, vR_y, vR_z + real(wp), dimension(idwbuff(1)%beg:, idwbuff(2)%beg:, idwbuff(3)%beg:, 1:), intent(inout) :: vL_x, vL_y, vL_z + real(wp), dimension(idwbuff(1)%beg:, idwbuff(2)%beg:, idwbuff(3)%beg:, 1:), intent(inout) :: vR_x, vR_y, vR_z integer, intent(in) :: norm_dir - integer :: recon_dir !< Coordinate direction of the WENO reconstruction + + integer :: recon_dir !< Coordinate direction of the WENO reconstruction + integer :: i, j, k, l ! Reconstruction in s1-direction @@ -1683,22 +1950,25 @@ contains is1 = idwbuff(1); is2 = idwbuff(2); is3 = idwbuff(3) recon_dir = 1; is1%beg = is1%beg + ${SCHEME}$_polyn is1%end = is1%end - ${SCHEME}$_polyn - else if (norm_dir == 2) then + + elseif (norm_dir == 2) then is1 = idwbuff(2); is2 = idwbuff(1); is3 = idwbuff(3) recon_dir = 2; is1%beg = is1%beg + ${SCHEME}$_polyn is1%end = is1%end - ${SCHEME}$_polyn + else is1 = idwbuff(3); is2 = idwbuff(2); is3 = idwbuff(1) recon_dir = 3; is1%beg = is1%beg + ${SCHEME}$_polyn is1%end = is1%end - ${SCHEME}$_polyn + end if - $:GPU_UPDATE(device='[is1, is2, is3, iv]') + $:GPU_UPDATE(device='[is1,is2,is3,iv]') end if #:endfor if (recon_dir == 1) then - $:GPU_PARALLEL_LOOP(private='[i, j, k, l]', collapse=4) + $:GPU_PARALLEL_LOOP(private='[i,j,k,l]', collapse=4) do i = iv%beg, iv%end do l = is3%beg, is3%end do k = is2%beg, is2%end @@ -1711,7 +1981,7 @@ contains end do $:END_GPU_PARALLEL_LOOP() else if (recon_dir == 2) then - $:GPU_PARALLEL_LOOP(private='[i, j, k, l]', collapse=4) + $:GPU_PARALLEL_LOOP(private='[i,j,k,l]', collapse=4) do i = iv%beg, iv%end do l = is3%beg, is3%end do k = is2%beg, is2%end @@ -1724,7 +1994,7 @@ contains end do $:END_GPU_PARALLEL_LOOP() else if (recon_dir == 3) then - $:GPU_PARALLEL_LOOP(private='[i, j, k, l]', collapse=4) + $:GPU_PARALLEL_LOOP(private='[i,j,k,l]', collapse=4) do i = iv%beg, iv%end do l = is3%beg, is3%end do k = is2%beg, is2%end @@ -1787,6 +2057,7 @@ contains end do if (n > 0) then + do l = mom_idx%beg, mom_idx%end @:DEALLOCATE(dq_prim_dy_qp(1)%vf(l)%sf) end do @@ -1796,6 +2067,7 @@ contains @:DEALLOCATE(dq_prim_dz_qp(1)%vf(l)%sf) end do end if + end if @:DEALLOCATE(dq_prim_dx_qp(1)%vf) @@ -1803,6 +2075,7 @@ contains @:DEALLOCATE(dq_prim_dz_qp(1)%vf) do i = num_dims, 1, -1 + do l = mom_idx%beg, mom_idx%end @:DEALLOCATE(dqL_prim_dx_n(i)%vf(l)%sf) @:DEALLOCATE(dqR_prim_dx_n(i)%vf(l)%sf) @@ -1905,3 +2178,4 @@ contains end subroutine s_finalize_rhs_module end module m_rhs + diff --git a/src/simulation/m_riemann_solvers.fpp b/src/simulation/m_riemann_solvers.fpp index 72055ef4ab..c28354d84e 100644 --- a/src/simulation/m_riemann_solvers.fpp +++ b/src/simulation/m_riemann_solvers.fpp @@ -10,17 +10,29 @@ module m_riemann_solvers - use m_derived_types - use m_global_parameters - use m_mpi_proxy - use m_variables_conversion - use m_bubbles + use m_derived_types !< Definitions of the derived types + + use m_global_parameters !< Definitions of the global parameters + + use m_mpi_proxy !< Message passing interface (MPI) module proxy + + use m_variables_conversion !< State variables type conversion procedures + + use m_bubbles !< To get the bubble wall pressure function + use m_bubbles_EE - use m_surface_tension - use m_helper_basic + + use m_surface_tension !< To get the capillary fluxes + + use m_helper_basic !< Functions to compare floating point numbers + use m_chemistry - use m_thermochem, only: gas_constant, get_mixture_molecular_weight, get_mixture_specific_heat_cv_mass, & - & get_mixture_energy_mass, get_species_specific_heats_r, get_species_enthalpies_rt, get_mixture_specific_heat_cp_mass + + use m_thermochem, only: & + gas_constant, get_mixture_molecular_weight, & + get_mixture_specific_heat_cv_mass, get_mixture_energy_mass, & + get_species_specific_heats_r, get_species_enthalpies_rt, & + get_mixture_specific_heat_cp_mass #:if USING_AMD use m_chemistry, only: molecular_weights_nonparameter @@ -28,44 +40,54 @@ module m_riemann_solvers implicit none - private; public :: s_initialize_riemann_solvers_module, s_riemann_solver, s_hll_riemann_solver, s_hllc_riemann_solver, & - & s_hlld_riemann_solver, s_lf_riemann_solver, s_finalize_riemann_solvers_module - - !> The cell-boundary values of the fluxes (src - source) that are computed through the chosen Riemann problem solver, and the - !! direct evaluation of source terms, by using the left and right states given in qK_prim_rs_vf, dqK_prim_ds_vf where ds = dx, - !! dy or dz. + private; public :: s_initialize_riemann_solvers_module, & + s_riemann_solver, & + s_hll_riemann_solver, & + s_hllc_riemann_solver, & + s_hlld_riemann_solver, & + s_lf_riemann_solver, & + s_finalize_riemann_solvers_module + + !> The cell-boundary values of the fluxes (src - source) that are computed + !! through the chosen Riemann problem solver, and the direct evaluation of + !! source terms, by using the left and right states given in qK_prim_rs_vf, + !! dqK_prim_ds_vf where ds = dx, dy or dz. !> @{ - real(wp), allocatable, dimension(:,:,:,:) :: flux_rsx_vf, flux_src_rsx_vf - real(wp), allocatable, dimension(:,:,:,:) :: flux_rsy_vf, flux_src_rsy_vf - real(wp), allocatable, dimension(:,:,:,:) :: flux_rsz_vf, flux_src_rsz_vf - $:GPU_DECLARE(create='[flux_rsx_vf, flux_src_rsx_vf, flux_rsy_vf, flux_src_rsy_vf, flux_rsz_vf, flux_src_rsz_vf]') + + real(wp), allocatable, dimension(:, :, :, :) :: flux_rsx_vf, flux_src_rsx_vf + real(wp), allocatable, dimension(:, :, :, :) :: flux_rsy_vf, flux_src_rsy_vf + real(wp), allocatable, dimension(:, :, :, :) :: flux_rsz_vf, flux_src_rsz_vf + $:GPU_DECLARE(create='[flux_rsx_vf,flux_src_rsx_vf,flux_rsy_vf,flux_src_rsy_vf,flux_rsz_vf,flux_src_rsz_vf]') !> @} - !> The cell-boundary values of the geometrical source flux that are computed through the chosen Riemann problem solver by using - !! the left and right states given in qK_prim_rs_vf. Currently 2D axisymmetric for inviscid only. + !> The cell-boundary values of the geometrical source flux that are computed + !! through the chosen Riemann problem solver by using the left and right + !! states given in qK_prim_rs_vf. Currently 2D axisymmetric for inviscid only. !> @{ - real(wp), allocatable, dimension(:,:,:,:) :: flux_gsrc_rsx_vf - real(wp), allocatable, dimension(:,:,:,:) :: flux_gsrc_rsy_vf - real(wp), allocatable, dimension(:,:,:,:) :: flux_gsrc_rsz_vf - $:GPU_DECLARE(create='[flux_gsrc_rsx_vf, flux_gsrc_rsy_vf, flux_gsrc_rsz_vf]') + + real(wp), allocatable, dimension(:, :, :, :) :: flux_gsrc_rsx_vf !< + real(wp), allocatable, dimension(:, :, :, :) :: flux_gsrc_rsy_vf !< + real(wp), allocatable, dimension(:, :, :, :) :: flux_gsrc_rsz_vf !< + $:GPU_DECLARE(create='[flux_gsrc_rsx_vf,flux_gsrc_rsy_vf,flux_gsrc_rsz_vf]') !> @} - ! Cell-boundary velocity from Riemann solution; used for source flux + ! The cell-boundary values of the velocity. vel_src_rs_vf is determined as + ! part of Riemann problem solution and is used to evaluate the source flux. - real(wp), allocatable, dimension(:,:,:,:) :: vel_src_rsx_vf - real(wp), allocatable, dimension(:,:,:,:) :: vel_src_rsy_vf - real(wp), allocatable, dimension(:,:,:,:) :: vel_src_rsz_vf - $:GPU_DECLARE(create='[vel_src_rsx_vf, vel_src_rsy_vf, vel_src_rsz_vf]') + real(wp), allocatable, dimension(:, :, :, :) :: vel_src_rsx_vf + real(wp), allocatable, dimension(:, :, :, :) :: vel_src_rsy_vf + real(wp), allocatable, dimension(:, :, :, :) :: vel_src_rsz_vf + $:GPU_DECLARE(create='[vel_src_rsx_vf,vel_src_rsy_vf,vel_src_rsz_vf]') - real(wp), allocatable, dimension(:,:,:,:) :: mom_sp_rsx_vf - real(wp), allocatable, dimension(:,:,:,:) :: mom_sp_rsy_vf - real(wp), allocatable, dimension(:,:,:,:) :: mom_sp_rsz_vf - $:GPU_DECLARE(create='[mom_sp_rsx_vf, mom_sp_rsy_vf, mom_sp_rsz_vf]') + real(wp), allocatable, dimension(:, :, :, :) :: mom_sp_rsx_vf + real(wp), allocatable, dimension(:, :, :, :) :: mom_sp_rsy_vf + real(wp), allocatable, dimension(:, :, :, :) :: mom_sp_rsz_vf + $:GPU_DECLARE(create='[mom_sp_rsx_vf,mom_sp_rsy_vf,mom_sp_rsz_vf]') - real(wp), allocatable, dimension(:,:,:,:) :: Re_avg_rsx_vf - real(wp), allocatable, dimension(:,:,:,:) :: Re_avg_rsy_vf - real(wp), allocatable, dimension(:,:,:,:) :: Re_avg_rsz_vf - $:GPU_DECLARE(create='[Re_avg_rsx_vf, Re_avg_rsy_vf, Re_avg_rsz_vf]') + real(wp), allocatable, dimension(:, :, :, :) :: Re_avg_rsx_vf + real(wp), allocatable, dimension(:, :, :, :) :: Re_avg_rsy_vf + real(wp), allocatable, dimension(:, :, :, :) :: Re_avg_rsz_vf + $:GPU_DECLARE(create='[Re_avg_rsx_vf,Re_avg_rsy_vf,Re_avg_rsz_vf]') !> @name Indical bounds in the s1-, s2- and s3-directions !> @{ @@ -73,162 +95,273 @@ module m_riemann_solvers type(int_bounds_info) :: isx, isy, isz !> @} - $:GPU_DECLARE(create='[is1, is2, is3, isx, isy, isz]') + $:GPU_DECLARE(create='[is1,is2,is3,isx,isy,isz]') real(wp), allocatable, dimension(:) :: Gs_rs $:GPU_DECLARE(create='[Gs_rs]') - real(wp), allocatable, dimension(:,:) :: Res_gs + real(wp), allocatable, dimension(:, :) :: Res_gs $:GPU_DECLARE(create='[Res_gs]') contains - !> Dispatch to the subroutines that are utilized to compute the Riemann problem solution. For additional information please - !! reference: 1) s_hll_riemann_solver 2) s_hllc_riemann_solver 3) s_exact_riemann_solver 4) s_hlld_riemann_solver - subroutine s_riemann_solver(qL_prim_rsx_vf, qL_prim_rsy_vf, qL_prim_rsz_vf, dqL_prim_dx_vf, dqL_prim_dy_vf, dqL_prim_dz_vf, & - - & qL_prim_vf, qR_prim_rsx_vf, qR_prim_rsy_vf, qR_prim_rsz_vf, dqR_prim_dx_vf, dqR_prim_dy_vf, dqR_prim_dz_vf, qR_prim_vf, & - & q_prim_vf, flux_vf, flux_src_vf, flux_gsrc_vf, norm_dir, ix, iy, iz) - - real(wp), dimension(idwbuff(1)%beg:,idwbuff(2)%beg:,idwbuff(3)%beg:,1:), intent(inout) :: qL_prim_rsx_vf, qL_prim_rsy_vf, & - & qL_prim_rsz_vf, qR_prim_rsx_vf, qR_prim_rsy_vf, qR_prim_rsz_vf - type(scalar_field), dimension(sys_size), intent(in) :: q_prim_vf - type(scalar_field), allocatable, dimension(:), intent(inout) :: qL_prim_vf, qR_prim_vf - type(scalar_field), allocatable, dimension(:), intent(inout) :: dqL_prim_dx_vf, dqR_prim_dx_vf, dqL_prim_dy_vf, & - & dqR_prim_dy_vf, dqL_prim_dz_vf, dqR_prim_dz_vf - - type(scalar_field), dimension(sys_size), intent(inout) :: flux_vf, flux_src_vf, flux_gsrc_vf - integer, intent(in) :: norm_dir - type(int_bounds_info), intent(in) :: ix, iy, iz + !> Dispatch to the subroutines that are utilized to compute the + !! Riemann problem solution. For additional information please reference: + !! 1) s_hll_riemann_solver + !! 2) s_hllc_riemann_solver + !! 3) s_exact_riemann_solver + !! 4) s_hlld_riemann_solver + !! @param qL_prim_rsx_vf Left WENO-reconstructed cell-boundary values (x-dir) + !! @param qL_prim_rsy_vf Left WENO-reconstructed cell-boundary values (y-dir) + !! @param qL_prim_rsz_vf Left WENO-reconstructed cell-boundary values (z-dir) + !! @param dqL_prim_dx_vf The left WENO-reconstructed cell-boundary values of the + !! first-order x-dir spatial derivatives + !! @param dqL_prim_dy_vf The left WENO-reconstructed cell-boundary values of the + !! first-order y-dir spatial derivatives + !! @param dqL_prim_dz_vf The left WENO-reconstructed cell-boundary values of the + !! first-order z-dir spatial derivatives + !! @param qL_prim_vf The left WENO-reconstructed cell-boundary values of the + !! cell-average primitive variables + !! @param qR_prim_rsx_vf Right WENO-reconstructed cell-boundary values (x-dir) + !! @param qR_prim_rsy_vf Right WENO-reconstructed cell-boundary values (y-dir) + !! @param qR_prim_rsz_vf Right WENO-reconstructed cell-boundary values (z-dir) + !! @param dqR_prim_dx_vf The right WENO-reconstructed cell-boundary values of the + !! first-order x-dir spatial derivatives + !! @param dqR_prim_dy_vf The right WENO-reconstructed cell-boundary values of the + !! first-order y-dir spatial derivatives + !! @param dqR_prim_dz_vf The right WENO-reconstructed cell-boundary values of the + !! first-order z-dir spatial derivatives + !! @param qR_prim_vf The right WENO-reconstructed cell-boundary values of the + !! cell-average primitive variables + !! @param q_prim_vf Cell-averaged primitive variables + !! @param flux_vf Intra-cell fluxes + !! @param flux_src_vf Intra-cell fluxes sources + !! @param flux_gsrc_vf Intra-cell geometric fluxes sources + !! @param norm_dir Dir. splitting direction + !! @param ix Index bounds in the x-dir + !! @param iy Index bounds in the y-dir + !! @param iz Index bounds in the z-dir + subroutine s_riemann_solver(qL_prim_rsx_vf, qL_prim_rsy_vf, qL_prim_rsz_vf, dqL_prim_dx_vf, & + dqL_prim_dy_vf, & + dqL_prim_dz_vf, & + qL_prim_vf, & + qR_prim_rsx_vf, qR_prim_rsy_vf, qR_prim_rsz_vf, dqR_prim_dx_vf, & + dqR_prim_dy_vf, & + dqR_prim_dz_vf, & + qR_prim_vf, & + q_prim_vf, & + flux_vf, flux_src_vf, & + flux_gsrc_vf, & + norm_dir, ix, iy, iz) + + real(wp), dimension(idwbuff(1)%beg:, idwbuff(2)%beg:, idwbuff(3)%beg:, 1:), intent(INOUT) :: qL_prim_rsx_vf, qL_prim_rsy_vf, qL_prim_rsz_vf, qR_prim_rsx_vf, qR_prim_rsy_vf, qR_prim_rsz_vf + type(scalar_field), dimension(sys_size), intent(IN) :: q_prim_vf + + type(scalar_field), allocatable, dimension(:), intent(INOUT) :: qL_prim_vf, qR_prim_vf + + type(scalar_field), & + allocatable, dimension(:), & + intent(INOUT) :: dqL_prim_dx_vf, dqR_prim_dx_vf, & + dqL_prim_dy_vf, dqR_prim_dy_vf, & + dqL_prim_dz_vf, dqR_prim_dz_vf + + type(scalar_field), & + dimension(sys_size), & + intent(INOUT) :: flux_vf, flux_src_vf, flux_gsrc_vf + + integer, intent(IN) :: norm_dir + + type(int_bounds_info), intent(IN) :: ix, iy, iz #:for NAME, NUM in [('hll', 1), ('hllc', 2), ('hlld', 4), ('lf', 5)] if (riemann_solver == ${NUM}$) then - call s_${NAME}$_riemann_solver(qL_prim_rsx_vf, qL_prim_rsy_vf, qL_prim_rsz_vf, dqL_prim_dx_vf, dqL_prim_dy_vf, & - & dqL_prim_dz_vf, qL_prim_vf, qR_prim_rsx_vf, qR_prim_rsy_vf, qR_prim_rsz_vf, & - & dqR_prim_dx_vf, dqR_prim_dy_vf, dqR_prim_dz_vf, qR_prim_vf, q_prim_vf, flux_vf, & - & flux_src_vf, flux_gsrc_vf, norm_dir, ix, iy, iz) + call s_${NAME}$_riemann_solver(qL_prim_rsx_vf, qL_prim_rsy_vf, qL_prim_rsz_vf, dqL_prim_dx_vf, & + dqL_prim_dy_vf, & + dqL_prim_dz_vf, & + qL_prim_vf, & + qR_prim_rsx_vf, qR_prim_rsy_vf, qR_prim_rsz_vf, dqR_prim_dx_vf, & + dqR_prim_dy_vf, & + dqR_prim_dz_vf, & + qR_prim_vf, & + q_prim_vf, & + flux_vf, flux_src_vf, & + flux_gsrc_vf, & + norm_dir, ix, iy, iz) end if #:endfor end subroutine s_riemann_solver - !> Dispatch to the subroutines that are utilized to compute the viscous source fluxes for either Cartesian or cylindrical - !! geometries. For more information please refer to: 1) s_compute_cartesian_viscous_source_flux 2) - !! s_compute_cylindrical_viscous_source_flux - subroutine s_compute_viscous_source_flux(velL_vf, dvelL_dx_vf, dvelL_dy_vf, dvelL_dz_vf, velR_vf, dvelR_dx_vf, dvelR_dy_vf, & - - & dvelR_dz_vf, flux_src_vf, norm_dir, ix, iy, iz) - - type(scalar_field), dimension(num_vels), intent(in) :: velL_vf, velR_vf, dvelL_dx_vf, dvelR_dx_vf, dvelL_dy_vf, & - & dvelR_dy_vf, dvelL_dz_vf, dvelR_dz_vf - - type(scalar_field), dimension(sys_size), intent(inout) :: flux_src_vf - integer, intent(in) :: norm_dir - type(int_bounds_info), intent(in) :: ix, iy, iz + !> Dispatch to the subroutines that are utilized to compute + !! the viscous source fluxes for either Cartesian or cylindrical geometries. + !! For more information please refer to: + !! 1) s_compute_cartesian_viscous_source_flux + !! 2) s_compute_cylindrical_viscous_source_flux + subroutine s_compute_viscous_source_flux(velL_vf, & + dvelL_dx_vf, & + dvelL_dy_vf, & + dvelL_dz_vf, & + velR_vf, & + dvelR_dx_vf, & + dvelR_dy_vf, & + dvelR_dz_vf, & + flux_src_vf, & + norm_dir, & + ix, iy, iz) + + type(scalar_field), & + dimension(num_vels), & + intent(IN) :: velL_vf, velR_vf, & + dvelL_dx_vf, dvelR_dx_vf, & + dvelL_dy_vf, dvelR_dy_vf, & + dvelL_dz_vf, dvelR_dz_vf + + type(scalar_field), & + dimension(sys_size), & + intent(INOUT) :: flux_src_vf + + integer, intent(IN) :: norm_dir + + type(int_bounds_info), intent(IN) :: ix, iy, iz if (grid_geometry == 3) then - call s_compute_cylindrical_viscous_source_flux(velL_vf, dvelL_dx_vf, dvelL_dy_vf, dvelL_dz_vf, velR_vf, dvelR_dx_vf, & - & dvelR_dy_vf, dvelR_dz_vf, flux_src_vf, norm_dir, ix, iy, iz) + call s_compute_cylindrical_viscous_source_flux(velL_vf, & + dvelL_dx_vf, & + dvelL_dy_vf, & + dvelL_dz_vf, & + velR_vf, & + dvelR_dx_vf, & + dvelR_dy_vf, & + dvelR_dz_vf, & + flux_src_vf, & + norm_dir, & + ix, iy, iz) else - call s_compute_cartesian_viscous_source_flux(dvelL_dx_vf, dvelL_dy_vf, dvelL_dz_vf, dvelR_dx_vf, dvelR_dy_vf, & - & dvelR_dz_vf, flux_src_vf, norm_dir) + call s_compute_cartesian_viscous_source_flux(dvelL_dx_vf, & + dvelL_dy_vf, & + dvelL_dz_vf, & + dvelR_dx_vf, & + dvelR_dy_vf, & + dvelR_dz_vf, & + flux_src_vf, & + norm_dir) end if - end subroutine s_compute_viscous_source_flux - !> HLL approximate Riemann solver, Harten et al. SIAM Review (1983) - subroutine s_hll_riemann_solver(qL_prim_rsx_vf, qL_prim_rsy_vf, qL_prim_rsz_vf, dqL_prim_dx_vf, dqL_prim_dy_vf, & - - & dqL_prim_dz_vf, qL_prim_vf, qR_prim_rsx_vf, qR_prim_rsy_vf, qR_prim_rsz_vf, dqR_prim_dx_vf, dqR_prim_dy_vf, & - & dqR_prim_dz_vf, qR_prim_vf, q_prim_vf, flux_vf, flux_src_vf, flux_gsrc_vf, norm_dir, ix, iy, iz) + !> @brief Computes intercell fluxes using the Harten-Lax-van Leer (HLL) approximate Riemann solver. + subroutine s_hll_riemann_solver(qL_prim_rsx_vf, qL_prim_rsy_vf, qL_prim_rsz_vf, dqL_prim_dx_vf, & + dqL_prim_dy_vf, & + dqL_prim_dz_vf, & + qL_prim_vf, & + qR_prim_rsx_vf, qR_prim_rsy_vf, qR_prim_rsz_vf, dqR_prim_dx_vf, & + dqR_prim_dy_vf, & + dqR_prim_dz_vf, & + qR_prim_vf, & + q_prim_vf, & + flux_vf, flux_src_vf, & + flux_gsrc_vf, & + norm_dir, ix, iy, iz) + + real(wp), dimension(idwbuff(1)%beg:, idwbuff(2)%beg:, idwbuff(3)%beg:, 1:), intent(inout) :: qL_prim_rsx_vf, qL_prim_rsy_vf, qL_prim_rsz_vf, qR_prim_rsx_vf, qR_prim_rsy_vf, qR_prim_rsz_vf + type(scalar_field), dimension(sys_size), intent(in) :: q_prim_vf - real(wp), dimension(idwbuff(1)%beg:,idwbuff(2)%beg:,idwbuff(3)%beg:,1:), intent(inout) :: qL_prim_rsx_vf, qL_prim_rsy_vf, & - & qL_prim_rsz_vf, qR_prim_rsx_vf, qR_prim_rsy_vf, qR_prim_rsz_vf - type(scalar_field), dimension(sys_size), intent(in) :: q_prim_vf type(scalar_field), allocatable, dimension(:), intent(inout) :: qL_prim_vf, qR_prim_vf - type(scalar_field), allocatable, dimension(:), intent(inout) :: dqL_prim_dx_vf, dqR_prim_dx_vf, dqL_prim_dy_vf, & - & dqR_prim_dy_vf, dqL_prim_dz_vf, dqR_prim_dz_vf + + type(scalar_field), & + allocatable, dimension(:), & + intent(inout) :: dqL_prim_dx_vf, dqR_prim_dx_vf, & + dqL_prim_dy_vf, dqR_prim_dy_vf, & + dqL_prim_dz_vf, dqR_prim_dz_vf ! Intercell fluxes - type(scalar_field), dimension(sys_size), intent(inout) :: flux_vf, flux_src_vf, flux_gsrc_vf - real(wp) :: flux_tau_L, flux_tau_R - integer, intent(in) :: norm_dir - type(int_bounds_info), intent(in) :: ix, iy, iz + type(scalar_field), & + dimension(sys_size), & + intent(inout) :: flux_vf, flux_src_vf, flux_gsrc_vf + real(wp) :: flux_tau_L, flux_tau_R + integer, intent(in) :: norm_dir + type(int_bounds_info), intent(in) :: ix, iy, iz #:if not MFC_CASE_OPTIMIZATION and USING_AMD - real(wp), dimension(3) :: alpha_rho_L, alpha_rho_R - real(wp), dimension(3) :: vel_L, vel_R - real(wp), dimension(3) :: alpha_L, alpha_R + real(wp), dimension(3) :: alpha_rho_L, alpha_rho_R + real(wp), dimension(3) :: vel_L, vel_R + real(wp), dimension(3) :: alpha_L, alpha_R real(wp), dimension(10) :: Ys_L, Ys_R real(wp), dimension(10) :: Cp_iL, Cp_iR, Xs_L, Xs_R, Gamma_iL, Gamma_iR real(wp), dimension(10) :: Yi_avg, Phi_avg, h_iL, h_iR, h_avg_2 #:else - real(wp), dimension(num_fluids) :: alpha_rho_L, alpha_rho_R - real(wp), dimension(num_vels) :: vel_L, vel_R - real(wp), dimension(num_fluids) :: alpha_L, alpha_R + real(wp), dimension(num_fluids) :: alpha_rho_L, alpha_rho_R + real(wp), dimension(num_vels) :: vel_L, vel_R + real(wp), dimension(num_fluids) :: alpha_L, alpha_R real(wp), dimension(num_species) :: Ys_L, Ys_R real(wp), dimension(num_species) :: Cp_iL, Cp_iR, Xs_L, Xs_R, Gamma_iL, Gamma_iR real(wp), dimension(num_species) :: Yi_avg, Phi_avg, h_iL, h_iR, h_avg_2 #:endif - real(wp) :: rho_L, rho_R - real(wp) :: pres_L, pres_R - real(wp) :: E_L, E_R - real(wp) :: H_L, H_R - real(wp) :: Cp_avg, Cv_avg, T_avg, eps, c_sum_Yi_Phi - real(wp) :: T_L, T_R - real(wp) :: Y_L, Y_R - real(wp) :: MW_L, MW_R - real(wp) :: R_gas_L, R_gas_R - real(wp) :: Cp_L, Cp_R - real(wp) :: Cv_L, Cv_R - real(wp) :: Gamm_L, Gamm_R - real(wp) :: gamma_L, gamma_R - real(wp) :: pi_inf_L, pi_inf_R - real(wp) :: qv_L, qv_R - real(wp) :: c_L, c_R - real(wp), dimension(6) :: tau_e_L, tau_e_R - real(wp) :: G_L, G_R - real(wp), dimension(2) :: Re_L, Re_R - real(wp), dimension(3) :: xi_field_L, xi_field_R - real(wp) :: rho_avg - real(wp) :: H_avg - real(wp) :: qv_avg - real(wp) :: gamma_avg - real(wp) :: c_avg - real(wp) :: s_L, s_R, s_M, s_P, s_S - real(wp) :: xi_M, xi_P - real(wp) :: ptilde_L, ptilde_R - real(wp) :: vel_L_rms, vel_R_rms, vel_avg_rms - real(wp) :: vel_L_tmp, vel_R_tmp - real(wp) :: Ms_L, Ms_R, pres_SL, pres_SR - real(wp) :: alpha_L_sum, alpha_R_sum - real(wp) :: zcoef, pcorr !< low Mach number correction - type(riemann_states) :: c_fast, pres_mag + real(wp) :: rho_L, rho_R + real(wp) :: pres_L, pres_R + real(wp) :: E_L, E_R + real(wp) :: H_L, H_R + real(wp) :: Cp_avg, Cv_avg, T_avg, eps, c_sum_Yi_Phi + real(wp) :: T_L, T_R + real(wp) :: Y_L, Y_R + real(wp) :: MW_L, MW_R + real(wp) :: R_gas_L, R_gas_R + real(wp) :: Cp_L, Cp_R + real(wp) :: Cv_L, Cv_R + real(wp) :: Gamm_L, Gamm_R + real(wp) :: gamma_L, gamma_R + real(wp) :: pi_inf_L, pi_inf_R + real(wp) :: qv_L, qv_R + real(wp) :: c_L, c_R + real(wp), dimension(6) :: tau_e_L, tau_e_R + real(wp) :: G_L, G_R + real(wp), dimension(2) :: Re_L, Re_R + real(wp), dimension(3) :: xi_field_L, xi_field_R + + real(wp) :: rho_avg + real(wp) :: H_avg + real(wp) :: qv_avg + real(wp) :: gamma_avg + real(wp) :: c_avg + + real(wp) :: s_L, s_R, s_M, s_P, s_S + real(wp) :: xi_M, xi_P + + real(wp) :: ptilde_L, ptilde_R + real(wp) :: vel_L_rms, vel_R_rms, vel_avg_rms + real(wp) :: vel_L_tmp, vel_R_tmp + real(wp) :: Ms_L, Ms_R, pres_SL, pres_SR + real(wp) :: alpha_L_sum, alpha_R_sum + real(wp) :: zcoef, pcorr !< low Mach number correction + + type(riemann_states) :: c_fast, pres_mag type(riemann_states_vec3) :: B - type(riemann_states) :: Ga !< Gamma (Lorentz factor) - type(riemann_states) :: vdotB, B2 - type(riemann_states_vec3) :: b4 !< 4-magnetic field components (spatial: b4x, b4y, b4z) - type(riemann_states_vec3) :: cm !< Conservative momentum variables - integer :: i, j, k, l, q !< Generic loop iterators - ! Populating the buffers of the left and right Riemann problem states variables, based on the choice of boundary conditions - call s_populate_riemann_states_variables_buffers(qL_prim_rsx_vf, qL_prim_rsy_vf, qL_prim_rsz_vf, dqL_prim_dx_vf, & - & dqL_prim_dy_vf, dqL_prim_dz_vf, qR_prim_rsx_vf, qR_prim_rsy_vf, qR_prim_rsz_vf, dqR_prim_dx_vf, dqR_prim_dy_vf, & - & dqR_prim_dz_vf, norm_dir, ix, iy, iz) + type(riemann_states) :: Ga ! Gamma (Lorentz factor) + type(riemann_states) :: vdotB, B2 + type(riemann_states_vec3) :: b4 ! 4-magnetic field components (spatial: b4x, b4y, b4z) + type(riemann_states_vec3) :: cm ! Conservative momentum variables + + integer :: i, j, k, l, q !< Generic loop iterators + + ! Populating the buffers of the left and right Riemann problem + ! states variables, based on the choice of boundary conditions + call s_populate_riemann_states_variables_buffers( & + qL_prim_rsx_vf, qL_prim_rsy_vf, qL_prim_rsz_vf, dqL_prim_dx_vf, & + dqL_prim_dy_vf, & + dqL_prim_dz_vf, & + qR_prim_rsx_vf, qR_prim_rsy_vf, qR_prim_rsz_vf, dqR_prim_dx_vf, & + dqR_prim_dy_vf, & + dqR_prim_dz_vf, & + norm_dir, ix, iy, iz) ! Reshaping inputted data based on dimensional splitting direction - call s_initialize_riemann_solver(flux_src_vf, norm_dir) + call s_initialize_riemann_solver( & + flux_src_vf, & + norm_dir) #:for NORM_DIR, XYZ in [(1, 'x'), (2, 'y'), (3, 'z')] + if (norm_dir == ${NORM_DIR}$) then - $:GPU_PARALLEL_LOOP(collapse=3, private='[i, j, k, l, q, alpha_rho_L, alpha_rho_R, vel_L, vel_R, alpha_L, & - & alpha_R, tau_e_L, tau_e_R, Re_L, Re_R, s_L, s_R, s_S, Ys_L, Ys_R, xi_field_L, xi_field_R, & - & Cp_iL, Cp_iR, Xs_L, Xs_R, Gamma_iL, Gamma_iR, Yi_avg, Phi_avg, h_iL, h_iR, h_avg_2, c_fast, & - & pres_mag, B, Ga, vdotB, B2, b4, cm, pcorr, zcoef, vel_L_tmp, vel_R_tmp, rho_L, rho_R, & - & pres_L, pres_R, E_L, E_R, H_L, H_R, Cp_avg, Cv_avg, T_avg, eps, c_sum_Yi_Phi, T_L, T_R, & - & Y_L, Y_R, MW_L, MW_R, R_gas_L, R_gas_R, Cp_L, Cp_R, Cv_L, Cv_R, Gamm_L, Gamm_R, gamma_L, & - & gamma_R, pi_inf_L, pi_inf_R, qv_L, qv_R, qv_avg, c_L, c_R, G_L, G_R, rho_avg, H_avg, c_avg, & - & gamma_avg, ptilde_L, ptilde_R, vel_L_rms, vel_R_rms, vel_avg_rms, Ms_L, Ms_R, pres_SL, & - & pres_SR, alpha_L_sum, alpha_R_sum, flux_tau_L, flux_tau_R]', copyin='[norm_dir]') + $:GPU_PARALLEL_LOOP(collapse=3, private='[i,j,k,l,q,alpha_rho_L,alpha_rho_R,vel_L,vel_R,alpha_L,alpha_R,tau_e_L,tau_e_R,Re_L,Re_R,s_L,s_R,s_S,Ys_L,Ys_R,xi_field_L, xi_field_R, Cp_iL, Cp_iR, Xs_L, Xs_R, Gamma_iL, Gamma_iR, Yi_avg, Phi_avg, h_iL, h_iR, h_avg_2, c_fast, pres_mag, B, Ga, vdotB, B2, b4, cm, pcorr, zcoef, vel_L_tmp, vel_R_tmp, rho_L, rho_R, pres_L, pres_R, E_L, E_R, H_L, H_R, Cp_avg, Cv_avg, T_avg, eps, c_sum_Yi_Phi, T_L, T_R, Y_L, Y_R, MW_L, MW_R, R_gas_L, R_gas_R, Cp_L, Cp_R, Cv_L, Cv_R, Gamm_L, Gamm_R, gamma_L, gamma_R, pi_inf_L, pi_inf_R, qv_L, qv_R, qv_avg, c_L, c_R, G_L, G_R, rho_avg, H_avg, c_avg, gamma_avg, ptilde_L, ptilde_R, vel_L_rms, vel_R_rms, vel_avg_rms, Ms_L, Ms_R, pres_SL, pres_SR, alpha_L_sum, alpha_R_sum, flux_tau_L, flux_tau_R]', copyin='[norm_dir]') do l = is3%beg, is3%end do k = is2%beg, is2%end do j = is1%beg, is1%end @@ -258,14 +391,14 @@ contains pres_R = qR_prim_rs${XYZ}$_vf(j + 1, k, l, E_idx) if (mhd) then - if (n == 0) then ! 1D: constant Bx; By, Bz as variables + if (n == 0) then ! 1D: constant Bx; By, Bz as variables B%L(1) = Bx0 B%R(1) = Bx0 B%L(2) = qL_prim_rs${XYZ}$_vf(j, k, l, B_idx%beg) B%R(2) = qR_prim_rs${XYZ}$_vf(j + 1, k, l, B_idx%beg) B%L(3) = qL_prim_rs${XYZ}$_vf(j, k, l, B_idx%beg + 1) B%R(3) = qR_prim_rs${XYZ}$_vf(j + 1, k, l, B_idx%beg + 1) - else ! 2D/3D: Bx, By, Bz as variables + else ! 2D/3D: Bx, By, Bz as variables B%L(1) = qL_prim_rs${XYZ}$_vf(j, k, l, B_idx%beg) B%R(1) = qR_prim_rs${XYZ}$_vf(j + 1, k, l, B_idx%beg) B%L(2) = qL_prim_rs${XYZ}$_vf(j, k, l, B_idx%beg + 1) @@ -330,8 +463,10 @@ contains $:GPU_LOOP(parallelism='[seq]') do q = 1, Re_size(i) - Re_L(i) = alpha_L(Re_idx(i, q))/Res_gs(i, q) + Re_L(i) - Re_R(i) = alpha_R(Re_idx(i, q))/Res_gs(i, q) + Re_R(i) + Re_L(i) = alpha_L(Re_idx(i, q))/Res_gs(i, q) & + + Re_L(i) + Re_R(i) = alpha_R(Re_idx(i, q))/Res_gs(i, q) & + + Re_R(i) end do Re_L(i) = 1._wp/max(Re_L(i), sgm_eps) @@ -391,7 +526,7 @@ contains E_R = rho_R*E_R + 5.e-1*rho_R*vel_R_rms H_L = (E_L + pres_L)/rho_L H_R = (E_R + pres_R)/rho_R - else if (mhd .and. relativity) then + elseif (mhd .and. relativity) then Ga%L = 1._wp/sqrt(1._wp - vel_L_rms) Ga%R = 1._wp/sqrt(1._wp - vel_R_rms) #:if not MFC_CASE_OPTIMIZATION or num_dims > 2 @@ -417,17 +552,15 @@ contains E_L = rho_L*H_L*Ga%L**2 - pres_L + 0.5_wp*(B2%L + vel_L_rms*B2%L - vdotB%L**2._wp) - rho_L*Ga%L E_R = rho_R*H_R*Ga%R**2 - pres_R + 0.5_wp*(B2%R + vel_R_rms*B2%R - vdotB%R**2._wp) - rho_R*Ga%R - else if (mhd .and. .not. relativity) then + elseif (mhd .and. .not. relativity) then #:if not MFC_CASE_OPTIMIZATION or num_dims > 2 pres_mag%L = 0.5_wp*(B%L(1)**2._wp + B%L(2)**2._wp + B%L(3)**2._wp) pres_mag%R = 0.5_wp*(B%R(1)**2._wp + B%R(2)**2._wp + B%R(3)**2._wp) #:endif E_L = gamma_L*pres_L + pi_inf_L + 0.5_wp*rho_L*vel_L_rms + qv_L + pres_mag%L - E_R = gamma_R*pres_R + pi_inf_R + 0.5_wp*rho_R*vel_R_rms + qv_R & - & + pres_mag%R ! includes magnetic energy + E_R = gamma_R*pres_R + pi_inf_R + 0.5_wp*rho_R*vel_R_rms + qv_R + pres_mag%R ! includes magnetic energy H_L = (E_L + pres_L - pres_mag%L)/rho_L - H_R = (E_R + pres_R - pres_mag%R) & - & /rho_R ! stagnation enthalpy here excludes magnetic energy (only used to find speed of sound) + H_R = (E_R + pres_R - pres_mag%R)/rho_R ! stagnation enthalpy here excludes magnetic energy (only used to find speed of sound) else E_L = gamma_L*pres_L + pi_inf_L + 5.e-1*rho_L*vel_L_rms + qv_L E_R = gamma_R*pres_R + pi_inf_R + 5.e-1*rho_R*vel_R_rms + qv_R @@ -454,7 +587,8 @@ contains do i = 1, strxe - strxb + 1 tau_e_L(i) = qL_prim_rs${XYZ}$_vf(j, k, l, strxb - 1 + i) tau_e_R(i) = qR_prim_rs${XYZ}$_vf(j + 1, k, l, strxb - 1 + i) - ! Elastic contribution to energy if G large enough TODO take out if statement if stable without + ! Elastic contribution to energy if G large enough + !TODO take out if statement if stable without if ((G_L > 1000) .and. (G_R > 1000)) then E_L = E_L + (tau_e_L(i)*tau_e_L(i))/(4._wp*G_L) E_R = E_R + (tau_e_R(i)*tau_e_R(i))/(4._wp*G_R) @@ -467,19 +601,51 @@ contains end do end if + ! elastic energy update + !if ( hyperelasticity ) then + ! G_L = 0._wp + ! G_R = 0._wp + ! + ! $:GPU_LOOP(parallelism='[seq]') + ! do i = 1, num_fluids + ! G_L = G_L + alpha_L(i)*Gs_rs(i) + ! G_R = G_R + alpha_R(i)*Gs_rs(i) + ! end do + ! ! Elastic contribution to energy if G large enough + ! if ((G_L > 1.e-3_wp) .and. (G_R > 1.e-3_wp)) then + ! E_L = E_L + G_L*qL_prim_rs${XYZ}$_vf(j, k, l, xiend + 1) + ! E_R = E_R + G_R*qR_prim_rs${XYZ}$_vf(j + 1, k, l, xiend + 1) + ! $:GPU_LOOP(parallelism='[seq]') + ! do i = 1, b_size-1 + ! tau_e_L(i) = G_L*qL_prim_rs${XYZ}$_vf(j, k, l, strxb - 1 + i) + ! tau_e_R(i) = G_R*qR_prim_rs${XYZ}$_vf(j + 1, k, l, strxb - 1 + i) + ! end do + ! $:GPU_LOOP(parallelism='[seq]') + ! do i = 1, b_size-1 + ! tau_e_L(i) = 0._wp + ! tau_e_R(i) = 0._wp + ! end do + ! $:GPU_LOOP(parallelism='[seq]') + ! do i = 1, num_dims + ! xi_field_L(i) = qL_prim_rs${XYZ}$_vf(j, k, l, xibeg - 1 + i) + ! xi_field_R(i) = qR_prim_rs${XYZ}$_vf(j + 1, k, l, xibeg - 1 + i) + ! end do + ! end if + !end if + @:compute_average_state() - call s_compute_speed_of_sound(pres_L, rho_L, gamma_L, pi_inf_L, H_L, alpha_L, vel_L_rms, 0._wp, c_L, & - & qv_L) + call s_compute_speed_of_sound(pres_L, rho_L, gamma_L, pi_inf_L, H_L, alpha_L, & + vel_L_rms, 0._wp, c_L, qv_L) - call s_compute_speed_of_sound(pres_R, rho_R, gamma_R, pi_inf_R, H_R, alpha_R, vel_R_rms, 0._wp, c_R, & - & qv_R) + call s_compute_speed_of_sound(pres_R, rho_R, gamma_R, pi_inf_R, H_R, alpha_R, & + vel_R_rms, 0._wp, c_R, qv_R) !> The computation of c_avg does not require all the variables, and therefore the non '_avg' ! variables are placeholders to call the subroutine. - call s_compute_speed_of_sound(pres_R, rho_avg, gamma_avg, pi_inf_R, H_avg, alpha_R, vel_avg_rms, & - & c_sum_Yi_Phi, c_avg, qv_avg) + call s_compute_speed_of_sound(pres_R, rho_avg, gamma_avg, pi_inf_R, H_avg, alpha_R, & + vel_avg_rms, c_sum_Yi_Phi, c_avg, qv_avg) if (mhd) then call s_compute_fast_magnetosonic_speed(rho_L, c_L, B%L, norm_dir, c_fast%L, H_L) @@ -496,68 +662,77 @@ contains end do end if - ! Wave speed estimates (wave_speeds=1: direct, wave_speeds=2: pressure-based) if (wave_speeds == 1) then if (mhd) then - ! MHD: use fast magnetosonic speed s_L = min(vel_L(dir_idx(1)) - c_fast%L, vel_R(dir_idx(1)) - c_fast%R) s_R = max(vel_R(dir_idx(1)) + c_fast%R, vel_L(dir_idx(1)) + c_fast%L) - else if (hypoelasticity) then - ! Elastic wave speed, Rodriguez et al. JCP (2019) - s_L = min(vel_L(dir_idx(1)) - sqrt(c_L*c_L + (((4._wp*G_L)/3._wp) + tau_e_L(dir_idx_tau(1))) & - & /rho_L), & - & vel_R(dir_idx(1)) - sqrt(c_R*c_R + (((4._wp*G_R)/3._wp) + tau_e_R(dir_idx_tau(1))) & - & /rho_R)) - s_R = max(vel_R(dir_idx(1)) + sqrt(c_R*c_R + (((4._wp*G_R)/3._wp) + tau_e_R(dir_idx_tau(1))) & - & /rho_R), & - & vel_L(dir_idx(1)) + sqrt(c_L*c_L + (((4._wp*G_L)/3._wp) + tau_e_L(dir_idx_tau(1))) & - & /rho_L)) + elseif (hypoelasticity) then + s_L = min(vel_L(dir_idx(1)) - sqrt(c_L*c_L + & + (((4._wp*G_L)/3._wp) + & + tau_e_L(dir_idx_tau(1)))/rho_L) & + , vel_R(dir_idx(1)) - sqrt(c_R*c_R + & + (((4._wp*G_R)/3._wp) + & + tau_e_R(dir_idx_tau(1)))/rho_R)) + s_R = max(vel_R(dir_idx(1)) + sqrt(c_R*c_R + & + (((4._wp*G_R)/3._wp) + & + tau_e_R(dir_idx_tau(1)))/rho_R) & + , vel_L(dir_idx(1)) + sqrt(c_L*c_L + & + (((4._wp*G_L)/3._wp) + & + tau_e_L(dir_idx_tau(1)))/rho_L)) else if (hyperelasticity) then - s_L = min(vel_L(dir_idx(1)) - sqrt(c_L*c_L + (4._wp*G_L/3._wp)/rho_L), & - & vel_R(dir_idx(1)) - sqrt(c_R*c_R + (4._wp*G_R/3._wp)/rho_R)) - s_R = max(vel_R(dir_idx(1)) + sqrt(c_R*c_R + (4._wp*G_R/3._wp)/rho_R), & - & vel_L(dir_idx(1)) + sqrt(c_L*c_L + (4._wp*G_L/3._wp)/rho_L)) + s_L = min(vel_L(dir_idx(1)) - sqrt(c_L*c_L + (4._wp*G_L/3._wp)/rho_L) & + , vel_R(dir_idx(1)) - sqrt(c_R*c_R + (4._wp*G_R/3._wp)/rho_R)) + s_R = max(vel_R(dir_idx(1)) + sqrt(c_R*c_R + (4._wp*G_R/3._wp)/rho_R) & + , vel_L(dir_idx(1)) + sqrt(c_L*c_L + (4._wp*G_L/3._wp)/rho_L)) else s_L = min(vel_L(dir_idx(1)) - c_L, vel_R(dir_idx(1)) - c_R) s_R = max(vel_R(dir_idx(1)) + c_R, vel_L(dir_idx(1)) + c_L) end if if (hyper_cleaning) then - ! Dedner GLM divergence cleaning, Dedner et al. JCP (2002) + ! Dedner GLM: (B_n, psi) subsystem has eigenvalues +/- c_h in the lab frame. s_L = min(s_L, -hyper_cleaning_speed) s_R = max(s_R, hyper_cleaning_speed) end if - s_S = (pres_R - pres_L + rho_L*vel_L(dir_idx(1))*(s_L - vel_L(dir_idx(1))) & - & - rho_R*vel_R(dir_idx(1))*(s_R - vel_R(dir_idx(1))))/(rho_L*(s_L - vel_L(dir_idx(1))) & - & - rho_R*(s_R - vel_R(dir_idx(1)))) - else if (wave_speeds == 2) then - pres_SL = 5.e-1_wp*(pres_L + pres_R + rho_avg*c_avg*(vel_L(dir_idx(1)) - vel_R(dir_idx(1)))) + s_S = (pres_R - pres_L + rho_L*vel_L(dir_idx(1))* & + (s_L - vel_L(dir_idx(1))) - & + rho_R*vel_R(dir_idx(1))* & + (s_R - vel_R(dir_idx(1)))) & + /(rho_L*(s_L - vel_L(dir_idx(1))) - & + rho_R*(s_R - vel_R(dir_idx(1)))) + elseif (wave_speeds == 2) then + pres_SL = 5.e-1_wp*(pres_L + pres_R + rho_avg*c_avg* & + (vel_L(dir_idx(1)) - & + vel_R(dir_idx(1)))) pres_SR = pres_SL - ! Low Mach correction: Thornber et al. JCP (2008) - Ms_L = max(1._wp, & - & sqrt(1._wp + ((5.e-1_wp + gamma_L)/(1._wp + gamma_L))*(pres_SL/pres_L - 1._wp) & - & *pres_L/((pres_L + pi_inf_L/(1._wp + gamma_L))))) - Ms_R = max(1._wp, & - & sqrt(1._wp + ((5.e-1_wp + gamma_R)/(1._wp + gamma_R))*(pres_SR/pres_R - 1._wp) & - & *pres_R/((pres_R + pi_inf_R/(1._wp + gamma_R))))) + Ms_L = max(1._wp, sqrt(1._wp + ((5.e-1_wp + gamma_L)/(1._wp + gamma_L))* & + (pres_SL/pres_L - 1._wp)*pres_L/ & + ((pres_L + pi_inf_L/(1._wp + gamma_L))))) + Ms_R = max(1._wp, sqrt(1._wp + ((5.e-1_wp + gamma_R)/(1._wp + gamma_R))* & + (pres_SR/pres_R - 1._wp)*pres_R/ & + ((pres_R + pi_inf_R/(1._wp + gamma_R))))) s_L = vel_L(dir_idx(1)) - c_L*Ms_L s_R = vel_R(dir_idx(1)) + c_R*Ms_R - s_S = 5.e-1_wp*((vel_L(dir_idx(1)) + vel_R(dir_idx(1))) + (pres_L - pres_R)/(rho_avg*c_avg)) + s_S = 5.e-1_wp*((vel_L(dir_idx(1)) + vel_R(dir_idx(1))) + & + (pres_L - pres_R)/ & + (rho_avg*c_avg)) end if s_M = min(0._wp, s_L); s_P = max(0._wp, s_R) - xi_M = (5.e-1_wp + sign(5.e-1_wp, s_L)) + (5.e-1_wp - sign(5.e-1_wp, s_L))*(5.e-1_wp + sign(5.e-1_wp, & - & s_R)) - xi_P = (5.e-1_wp - sign(5.e-1_wp, s_R)) + (5.e-1_wp - sign(5.e-1_wp, s_L))*(5.e-1_wp + sign(5.e-1_wp, & - & s_R)) + xi_M = (5.e-1_wp + sign(5.e-1_wp, s_L)) & + + (5.e-1_wp - sign(5.e-1_wp, s_L)) & + *(5.e-1_wp + sign(5.e-1_wp, s_R)) + xi_P = (5.e-1_wp - sign(5.e-1_wp, s_R)) & + + (5.e-1_wp - sign(5.e-1_wp, s_L)) & + *(5.e-1_wp + sign(5.e-1_wp, s_R)) - ! HLL intercell flux: F* = (s_R*F_L - s_L*F_R + s_L*s_R*(U_R - U_L)) / (s_R - s_L) Low Mach correction + ! Low Mach correction if (low_Mach == 1) then @:compute_low_Mach_correction() else @@ -568,17 +743,22 @@ contains if (.not. relativity) then $:GPU_LOOP(parallelism='[seq]') do i = 1, contxe - flux_rs${XYZ}$_vf(j, k, l, & - & i) = (s_M*alpha_rho_R(i)*vel_R(norm_dir) - s_P*alpha_rho_L(i) & - & *vel_L(norm_dir) + s_M*s_P*(alpha_rho_L(i) - alpha_rho_R(i)))/(s_M - s_P) + flux_rs${XYZ}$_vf(j, k, l, i) = & + (s_M*alpha_rho_R(i)*vel_R(norm_dir) & + - s_P*alpha_rho_L(i)*vel_L(norm_dir) & + + s_M*s_P*(alpha_rho_L(i) & + - alpha_rho_R(i))) & + /(s_M - s_P) end do - else if (relativity) then + elseif (relativity) then $:GPU_LOOP(parallelism='[seq]') do i = 1, contxe - flux_rs${XYZ}$_vf(j, k, l, & - & i) = (s_M*Ga%R*alpha_rho_R(i)*vel_R(norm_dir) - s_P*Ga%L*alpha_rho_L(i) & - & *vel_L(norm_dir) + s_M*s_P*(Ga%L*alpha_rho_L(i) - Ga%R*alpha_rho_R(i))) & - & /(s_M - s_P) + flux_rs${XYZ}$_vf(j, k, l, i) = & + (s_M*Ga%R*alpha_rho_R(i)*vel_R(norm_dir) & + - s_P*Ga%L*alpha_rho_L(i)*vel_L(norm_dir) & + + s_M*s_P*(Ga%L*alpha_rho_L(i) & + - Ga%R*alpha_rho_R(i))) & + /(s_M - s_P) end do end if @@ -586,54 +766,78 @@ contains if (mhd .and. (.not. relativity)) then $:GPU_LOOP(parallelism='[seq]') do i = 1, 3 - ! Flux of rho*v_i in the ${XYZ}$ direction = rho * v_i * v_${XYZ}$ - B_i * B_${XYZ}$ + - ! delta_(${XYZ}$,i) * p_tot - flux_rs${XYZ}$_vf(j, k, l, & - & contxe + i) = (s_M*(rho_R*vel_R(i)*vel_R(norm_dir) - B%R(i)*B%R(norm_dir) & - & + dir_flg(i)*(pres_R + pres_mag%R)) - s_P*(rho_L*vel_L(i)*vel_L(norm_dir) & - & - B%L(i)*B%L(norm_dir) + dir_flg(i)*(pres_L + pres_mag%L)) & - & + s_M*s_P*(rho_L*vel_L(i) - rho_R*vel_R(i)))/(s_M - s_P) + ! Flux of rho*v_i in the ${XYZ}$ direction + ! = rho * v_i * v_${XYZ}$ - B_i * B_${XYZ}$ + delta_(${XYZ}$,i) * p_tot + flux_rs${XYZ}$_vf(j, k, l, contxe + i) = & + (s_M*(rho_R*vel_R(i)*vel_R(norm_dir) & + - B%R(i)*B%R(norm_dir) & + + dir_flg(i)*(pres_R + pres_mag%R)) & + - s_P*(rho_L*vel_L(i)*vel_L(norm_dir) & + - B%L(i)*B%L(norm_dir) & + + dir_flg(i)*(pres_L + pres_mag%L)) & + + s_M*s_P*(rho_L*vel_L(i) - rho_R*vel_R(i))) & + /(s_M - s_P) end do - else if (mhd .and. relativity) then + elseif (mhd .and. relativity) then $:GPU_LOOP(parallelism='[seq]') do i = 1, 3 - ! Flux of m_i in the ${XYZ}$ direction = m_i * v_${XYZ}$ - b_i/Gamma * B_${XYZ}$ + - ! delta_(${XYZ}$,i) * p_tot - flux_rs${XYZ}$_vf(j, k, l, & - & contxe + i) = (s_M*(cm%R(i)*vel_R(norm_dir) - b4%R(i)/Ga%R*B%R(norm_dir) & - & + dir_flg(i)*(pres_R + pres_mag%R)) - s_P*(cm%L(i)*vel_L(norm_dir) & - & - b4%L(i)/Ga%L*B%L(norm_dir) + dir_flg(i)*(pres_L + pres_mag%L)) & - & + s_M*s_P*(cm%L(i) - cm%R(i)))/(s_M - s_P) + ! Flux of m_i in the ${XYZ}$ direction + ! = m_i * v_${XYZ}$ - b_i/Gamma * B_${XYZ}$ + delta_(${XYZ}$,i) * p_tot + flux_rs${XYZ}$_vf(j, k, l, contxe + i) = & + (s_M*(cm%R(i)*vel_R(norm_dir) & + - b4%R(i)/Ga%R*B%R(norm_dir) & + + dir_flg(i)*(pres_R + pres_mag%R)) & + - s_P*(cm%L(i)*vel_L(norm_dir) & + - b4%L(i)/Ga%L*B%L(norm_dir) & + + dir_flg(i)*(pres_L + pres_mag%L)) & + + s_M*s_P*(cm%L(i) - cm%R(i))) & + /(s_M - s_P) end do - else if (bubbles_euler) then + elseif (bubbles_euler) then $:GPU_LOOP(parallelism='[seq]') do i = 1, num_vels - flux_rs${XYZ}$_vf(j, k, l, & - & contxe + dir_idx(i)) = (s_M*(rho_R*vel_R(dir_idx(1))*vel_R(dir_idx(i)) & - & + dir_flg(dir_idx(i))*(pres_R - ptilde_R)) - s_P*(rho_L*vel_L(dir_idx(1)) & - & *vel_L(dir_idx(i)) + dir_flg(dir_idx(i))*(pres_L - ptilde_L)) & - & + s_M*s_P*(rho_L*vel_L(dir_idx(i)) - rho_R*vel_R(dir_idx(i))))/(s_M - s_P) & - & + (s_M/s_L)*(s_P/s_R)*pcorr*(vel_R(dir_idx(i)) - vel_L(dir_idx(i))) + flux_rs${XYZ}$_vf(j, k, l, contxe + dir_idx(i)) = & + (s_M*(rho_R*vel_R(dir_idx(1)) & + *vel_R(dir_idx(i)) & + + dir_flg(dir_idx(i))*(pres_R - ptilde_R)) & + - s_P*(rho_L*vel_L(dir_idx(1)) & + *vel_L(dir_idx(i)) & + + dir_flg(dir_idx(i))*(pres_L - ptilde_L)) & + + s_M*s_P*(rho_L*vel_L(dir_idx(i)) & + - rho_R*vel_R(dir_idx(i)))) & + /(s_M - s_P) & + + (s_M/s_L)*(s_P/s_R)*pcorr*(vel_R(dir_idx(i)) - vel_L(dir_idx(i))) end do else if (hypoelasticity) then $:GPU_LOOP(parallelism='[seq]') do i = 1, num_vels - flux_rs${XYZ}$_vf(j, k, l, & - & contxe + dir_idx(i)) = (s_M*(rho_R*vel_R(dir_idx(1))*vel_R(dir_idx(i)) & - & + dir_flg(dir_idx(i))*pres_R - tau_e_R(dir_idx_tau(i))) & - & - s_P*(rho_L*vel_L(dir_idx(1))*vel_L(dir_idx(i)) + dir_flg(dir_idx(i)) & - & *pres_L - tau_e_L(dir_idx_tau(i))) + s_M*s_P*(rho_L*vel_L(dir_idx(i)) & - & - rho_R*vel_R(dir_idx(i))))/(s_M - s_P) + flux_rs${XYZ}$_vf(j, k, l, contxe + dir_idx(i)) = & + (s_M*(rho_R*vel_R(dir_idx(1)) & + *vel_R(dir_idx(i)) & + + dir_flg(dir_idx(i))*pres_R & + - tau_e_R(dir_idx_tau(i))) & + - s_P*(rho_L*vel_L(dir_idx(1)) & + *vel_L(dir_idx(i)) & + + dir_flg(dir_idx(i))*pres_L & + - tau_e_L(dir_idx_tau(i))) & + + s_M*s_P*(rho_L*vel_L(dir_idx(i)) & + - rho_R*vel_R(dir_idx(i)))) & + /(s_M - s_P) end do else $:GPU_LOOP(parallelism='[seq]') do i = 1, num_vels - flux_rs${XYZ}$_vf(j, k, l, & - & contxe + dir_idx(i)) = (s_M*(rho_R*vel_R(dir_idx(1))*vel_R(dir_idx(i)) & - & + dir_flg(dir_idx(i))*pres_R) - s_P*(rho_L*vel_L(dir_idx(1)) & - & *vel_L(dir_idx(i)) + dir_flg(dir_idx(i))*pres_L) & - & + s_M*s_P*(rho_L*vel_L(dir_idx(i)) - rho_R*vel_R(dir_idx(i))))/(s_M - s_P) & - & + (s_M/s_L)*(s_P/s_R)*pcorr*(vel_R(dir_idx(i)) - vel_L(dir_idx(i))) + flux_rs${XYZ}$_vf(j, k, l, contxe + dir_idx(i)) = & + (s_M*(rho_R*vel_R(dir_idx(1)) & + *vel_R(dir_idx(i)) & + + dir_flg(dir_idx(i))*pres_R) & + - s_P*(rho_L*vel_L(dir_idx(1)) & + *vel_L(dir_idx(i)) & + + dir_flg(dir_idx(i))*pres_L) & + + s_M*s_P*(rho_L*vel_L(dir_idx(i)) & + - rho_R*vel_R(dir_idx(i)))) & + /(s_M - s_P) & + + (s_M/s_L)*(s_P/s_R)*pcorr*(vel_R(dir_idx(i)) - vel_L(dir_idx(i))) end do end if @@ -641,24 +845,27 @@ contains if (mhd .and. (.not. relativity)) then ! energy flux = (E + p + p_mag) * v_${XYZ}$ - B_${XYZ}$ * (v_x*B_x + v_y*B_y + v_z*B_z) #:if not MFC_CASE_OPTIMIZATION or num_dims > 2 - flux_rs${XYZ}$_vf(j, k, l, & - & E_idx) = (s_M*(vel_R(norm_dir)*(E_R + pres_R + pres_mag%R) - B%R(norm_dir) & - & *(vel_R(1)*B%R(1) + vel_R(2)*B%R(2) + vel_R(3)*B%R(3))) & - & - s_P*(vel_L(norm_dir)*(E_L + pres_L + pres_mag%L) - B%L(norm_dir) & - & *(vel_L(1)*B%L(1) + vel_L(2)*B%L(2) + vel_L(3)*B%L(3))) + s_M*s_P*(E_L & - & - E_R))/(s_M - s_P) + flux_rs${XYZ}$_vf(j, k, l, E_idx) = & + (s_M*(vel_R(norm_dir)*(E_R + pres_R + pres_mag%R) - B%R(norm_dir)*(vel_R(1)*B%R(1) + vel_R(2)*B%R(2) + vel_R(3)*B%R(3))) & + - s_P*(vel_L(norm_dir)*(E_L + pres_L + pres_mag%L) - B%L(norm_dir)*(vel_L(1)*B%L(1) + vel_L(2)*B%L(2) + vel_L(3)*B%L(3))) & + + s_M*s_P*(E_L - E_R)) & + /(s_M - s_P) #:endif - else if (mhd .and. relativity) then - ! energy flux = m_${XYZ}$ - mass flux Hard-coded for single-component for now - flux_rs${XYZ}$_vf(j, k, l, & - & E_idx) = (s_M*(cm%R(norm_dir) - Ga%R*alpha_rho_R(1)*vel_R(norm_dir)) & - & - s_P*(cm%L(norm_dir) - Ga%L*alpha_rho_L(1)*vel_L(norm_dir)) + s_M*s_P*(E_L & - & - E_R))/(s_M - s_P) + elseif (mhd .and. relativity) then + ! energy flux = m_${XYZ}$ - mass flux + ! Hard-coded for single-component for now + flux_rs${XYZ}$_vf(j, k, l, E_idx) = & + (s_M*(cm%R(norm_dir) - Ga%R*alpha_rho_R(1)*vel_R(norm_dir)) & + - s_P*(cm%L(norm_dir) - Ga%L*alpha_rho_L(1)*vel_L(norm_dir)) & + + s_M*s_P*(E_L - E_R)) & + /(s_M - s_P) else if (bubbles_euler) then - flux_rs${XYZ}$_vf(j, k, l, & - & E_idx) = (s_M*vel_R(dir_idx(1))*(E_R + pres_R - ptilde_R) & - & - s_P*vel_L(dir_idx(1))*(E_L + pres_L - ptilde_L) + s_M*s_P*(E_L - E_R))/(s_M & - & - s_P) + (s_M/s_L)*(s_P/s_R)*pcorr*(vel_R_rms - vel_L_rms)/2._wp + flux_rs${XYZ}$_vf(j, k, l, E_idx) = & + (s_M*vel_R(dir_idx(1))*(E_R + pres_R - ptilde_R) & + - s_P*vel_L(dir_idx(1))*(E_L + pres_L - ptilde_L) & + + s_M*s_P*(E_L - E_R)) & + /(s_M - s_P) & + + (s_M/s_L)*(s_P/s_R)*pcorr*(vel_R_rms - vel_L_rms)/2._wp else if (hypoelasticity) then flux_tau_L = 0._wp; flux_tau_R = 0._wp $:GPU_LOOP(parallelism='[seq]') @@ -666,34 +873,44 @@ contains flux_tau_L = flux_tau_L + tau_e_L(dir_idx_tau(i))*vel_L(dir_idx(i)) flux_tau_R = flux_tau_R + tau_e_R(dir_idx_tau(i))*vel_R(dir_idx(i)) end do - flux_rs${XYZ}$_vf(j, k, l, & - & E_idx) = (s_M*(vel_R(dir_idx(1))*(E_R + pres_R) - flux_tau_R) & - & - s_P*(vel_L(dir_idx(1))*(E_L + pres_L) - flux_tau_L) + s_M*s_P*(E_L - E_R)) & - & /(s_M - s_P) + flux_rs${XYZ}$_vf(j, k, l, E_idx) = & + (s_M*(vel_R(dir_idx(1))*(E_R + pres_R) - flux_tau_R) & + - s_P*(vel_L(dir_idx(1))*(E_L + pres_L) - flux_tau_L) & + + s_M*s_P*(E_L - E_R))/(s_M - s_P) else - flux_rs${XYZ}$_vf(j, k, l, & - & E_idx) = (s_M*vel_R(dir_idx(1))*(E_R + pres_R) - s_P*vel_L(dir_idx(1))*(E_L & - & + pres_L) + s_M*s_P*(E_L - E_R))/(s_M - s_P) + (s_M/s_L)*(s_P/s_R) & - & *pcorr*(vel_R_rms - vel_L_rms)/2._wp + flux_rs${XYZ}$_vf(j, k, l, E_idx) = & + (s_M*vel_R(dir_idx(1))*(E_R + pres_R) & + - s_P*vel_L(dir_idx(1))*(E_L + pres_L) & + + s_M*s_P*(E_L - E_R)) & + /(s_M - s_P) & + + (s_M/s_L)*(s_P/s_R)*pcorr*(vel_R_rms - vel_L_rms)/2._wp end if ! Elastic Stresses if (hypoelasticity) then - do i = 1, strxe - strxb + 1 ! TODO: this indexing may be slow - flux_rs${XYZ}$_vf(j, k, l, & - & strxb - 1 + i) = (s_M*(rho_R*vel_R(dir_idx(1))*tau_e_R(i)) & - & - s_P*(rho_L*vel_L(dir_idx(1))*tau_e_L(i)) + s_M*s_P*(rho_L*tau_e_L(i) & - & - rho_R*tau_e_R(i)))/(s_M - s_P) + do i = 1, strxe - strxb + 1 !TODO: this indexing may be slow + flux_rs${XYZ}$_vf(j, k, l, strxb - 1 + i) = & + (s_M*(rho_R*vel_R(dir_idx(1)) & + *tau_e_R(i)) & + - s_P*(rho_L*vel_L(dir_idx(1)) & + *tau_e_L(i)) & + + s_M*s_P*(rho_L*tau_e_L(i) & + - rho_R*tau_e_R(i))) & + /(s_M - s_P) end do end if - ! Advection flux and source: interface velocity for volume fraction transport + ! Advection $:GPU_LOOP(parallelism='[seq]') do i = advxb, advxe - flux_rs${XYZ}$_vf(j, k, l, i) = (qL_prim_rs${XYZ}$_vf(j, k, l, i) - qR_prim_rs${XYZ}$_vf(j + 1, & - & k, l, i))*s_M*s_P/(s_M - s_P) - flux_src_rs${XYZ}$_vf(j, k, l, i) = (s_M*qR_prim_rs${XYZ}$_vf(j + 1, k, l, & - & i) - s_P*qL_prim_rs${XYZ}$_vf(j, k, l, i))/(s_M - s_P) + flux_rs${XYZ}$_vf(j, k, l, i) = & + (qL_prim_rs${XYZ}$_vf(j, k, l, i) & + - qR_prim_rs${XYZ}$_vf(j + 1, k, l, i)) & + *s_M*s_P/(s_M - s_P) + flux_src_rs${XYZ}$_vf(j, k, l, i) = & + (s_M*qR_prim_rs${XYZ}$_vf(j + 1, k, l, i) & + - s_P*qL_prim_rs${XYZ}$_vf(j, k, l, i)) & + /(s_M - s_P) end do if (bubbles_euler) then @@ -709,50 +926,43 @@ contains Y_L = qL_prim_rs${XYZ}$_vf(j, k, l, i) Y_R = qR_prim_rs${XYZ}$_vf(j + 1, k, l, i) - flux_rs${XYZ}$_vf(j, k, l, & - & i) = (s_M*Y_R*rho_R*vel_R(dir_idx(1)) - s_P*Y_L*rho_L*vel_L(dir_idx(1)) & - & + s_M*s_P*(Y_L*rho_L - Y_R*rho_R))/(s_M - s_P) + flux_rs${XYZ}$_vf(j, k, l, i) = (s_M*Y_R*rho_R*vel_R(dir_idx(1)) & + - s_P*Y_L*rho_L*vel_L(dir_idx(1)) & + + s_M*s_P*(Y_L*rho_L - Y_R*rho_R)) & + /(s_M - s_P) flux_src_rs${XYZ}$_vf(j, k, l, i) = 0._wp end do end if - ! MHD: magnetic flux and Maxwell stress contributions if (mhd) then - if (n == 0) then ! 1D: d/dx flux only & Bx = Bx0 = const. - ! B_y flux = v_x * B_y - v_y * Bx0 B_z flux = v_x * B_z - v_z * Bx0 + if (n == 0) then ! 1D: d/dx flux only & Bx = Bx0 = const. + ! B_y flux = v_x * B_y - v_y * Bx0 + ! B_z flux = v_x * B_z - v_z * Bx0 $:GPU_LOOP(parallelism='[seq]') do i = 0, 1 - flux_rsx_vf(j, k, l, & - & B_idx%beg + i) = (s_M*(vel_R(1)*B%R(2 + i) - vel_R(2 + i)*Bx0) & - & - s_P*(vel_L(1)*B%L(2 + i) - vel_L(2 + i)*Bx0) + s_M*s_P*(B%L(2 + i) & - & - B%R(2 + i)))/(s_M - s_P) + flux_rsx_vf(j, k, l, B_idx%beg + i) = (s_M*(vel_R(1)*B%R(2 + i) - vel_R(2 + i)*Bx0) & + - s_P*(vel_L(1)*B%L(2 + i) - vel_L(2 + i)*Bx0) & + + s_M*s_P*(B%L(2 + i) - B%R(2 + i)))/(s_M - s_P) end do - else ! 2D/3D: Bx, By, Bz /= const. but zero flux component in the same direction - ! B_x d/d${XYZ}$ flux = (1 - delta(x,${XYZ}$)) * (v_${XYZ}$ * B_x - v_x * B_${XYZ}$) B_y - ! d/d${XYZ}$ flux = (1 - delta(y,${XYZ}$)) * (v_${XYZ}$ * B_y - v_y * B_${XYZ}$) B_z d/d${XYZ}$ - ! flux = (1 - delta(z,${XYZ}$)) * (v_${XYZ}$ * B_z - v_z * B_${XYZ}$) + else ! 2D/3D: Bx, By, Bz /= const. but zero flux component in the same direction + ! B_x d/d${XYZ}$ flux = (1 - delta(x,${XYZ}$)) * (v_${XYZ}$ * B_x - v_x * B_${XYZ}$) + ! B_y d/d${XYZ}$ flux = (1 - delta(y,${XYZ}$)) * (v_${XYZ}$ * B_y - v_y * B_${XYZ}$) + ! B_z d/d${XYZ}$ flux = (1 - delta(z,${XYZ}$)) * (v_${XYZ}$ * B_z - v_z * B_${XYZ}$) $:GPU_LOOP(parallelism='[seq]') do i = 0, 2 - flux_rs${XYZ}$_vf(j, k, l, & - & B_idx%beg + i) = (s_M*(vel_R(dir_idx(1))*B%R(i + 1) - vel_R(i + 1) & - & *B%R(norm_dir)) - s_P*(vel_L(dir_idx(1))*B%L(i + 1) - vel_L(i + 1) & - & *B%L(norm_dir)) + s_M*s_P*(B%L(i + 1) - B%R(i + 1)))/(s_M - s_P) + flux_rs${XYZ}$_vf(j, k, l, B_idx%beg + i) = (s_M*(vel_R(dir_idx(1))*B%R(i + 1) - vel_R(i + 1)*B%R(norm_dir)) - & + s_P*(vel_L(dir_idx(1))*B%L(i + 1) - vel_L(i + 1)*B%L(norm_dir)) + & + s_M*s_P*(B%L(i + 1) - B%R(i + 1)))/(s_M - s_P) end do if (hyper_cleaning) then ! propagate magnetic field divergence as a wave - flux_rs${XYZ}$_vf(j, k, l, B_idx%beg + norm_dir - 1) = flux_rs${XYZ}$_vf(j, k, l, & - & B_idx%beg + norm_dir - 1) + (s_M*qR_prim_rs${XYZ}$_vf(j + 1, k, l, & - & psi_idx) - s_P*qL_prim_rs${XYZ}$_vf(j, k, l, psi_idx))/(s_M - s_P) - - flux_rs${XYZ}$_vf(j, k, l, & - & psi_idx) = (hyper_cleaning_speed**2*(s_M*B%R(norm_dir) & - & - s_P*B%L(norm_dir)) + s_M*s_P*(qL_prim_rs${XYZ}$_vf(j, k, l, & - & psi_idx) - qR_prim_rs${XYZ}$_vf(j + 1, k, l, psi_idx)))/(s_M - s_P) + flux_rs${XYZ}$_vf(j, k, l, B_idx%beg + norm_dir - 1) = flux_rs${XYZ}$_vf(j, k, l, B_idx%beg + norm_dir - 1) + & + (s_M*qR_prim_rs${XYZ}$_vf(j + 1, k, l, psi_idx) - s_P*qL_prim_rs${XYZ}$_vf(j, k, l, psi_idx))/(s_M - s_P) + + flux_rs${XYZ}$_vf(j, k, l, psi_idx) = (hyper_cleaning_speed**2*(s_M*B%R(norm_dir) - s_P*B%L(norm_dir)) + s_M*s_P*(qL_prim_rs${XYZ}$_vf(j, k, l, psi_idx) - qR_prim_rs${XYZ}$_vf(j + 1, k, l, psi_idx)))/(s_M - s_P) else - flux_rs${XYZ}$_vf(j, k, l, & - & B_idx%beg + norm_dir - 1) & - & = 0._wp ! Without hyperbolic cleaning, make sure flux of B_normal is identically zero + flux_rs${XYZ}$_vf(j, k, l, B_idx%beg + norm_dir - 1) = 0._wp ! Without hyperbolic cleaning, make sure flux of B_normal is identically zero end if end if flux_src_rs${XYZ}$_vf(j, k, l, advxb) = 0._wp @@ -760,14 +970,15 @@ contains #:if (NORM_DIR == 2) if (cyl_coord) then - ! Substituting the advective flux into the inviscid geometrical source flux + !Substituting the advective flux into the inviscid geometrical source flux $:GPU_LOOP(parallelism='[seq]') do i = 1, E_idx flux_gsrc_rs${XYZ}$_vf(j, k, l, i) = flux_rs${XYZ}$_vf(j, k, l, i) end do ! Recalculating the radial momentum geometric source flux - flux_gsrc_rs${XYZ}$_vf(j, k, l, contxe + 2) = flux_rs${XYZ}$_vf(j, k, l, & - & contxe + 2) - (s_M*pres_R - s_P*pres_L)/(s_M - s_P) + flux_gsrc_rs${XYZ}$_vf(j, k, l, contxe + 2) = & + flux_rs${XYZ}$_vf(j, k, l, contxe + 2) & + - (s_M*pres_R - s_P*pres_L)/(s_M - s_P) ! Geometrical source of the void fraction(s) is zero $:GPU_LOOP(parallelism='[seq]') do i = advxb, advxe @@ -777,8 +988,10 @@ contains if (cyl_coord .and. hypoelasticity) then ! += tau_sigmasigma using HLL - flux_gsrc_rs${XYZ}$_vf(j, k, l, contxe + 2) = flux_gsrc_rs${XYZ}$_vf(j, k, l, & - & contxe + 2) + (s_M*tau_e_R(4) - s_P*tau_e_L(4))/(s_M - s_P) + flux_gsrc_rs${XYZ}$_vf(j, k, l, contxe + 2) = & + flux_gsrc_rs${XYZ}$_vf(j, k, l, contxe + 2) + & + (s_M*tau_e_R(4) - s_P*tau_e_L(4)) & + /(s_M - s_P) $:GPU_LOOP(parallelism='[seq]') do i = strxb, strxe @@ -786,129 +999,165 @@ contains end do end if #:endif + end do end do end do $:END_GPU_PARALLEL_LOOP() end if + #:endfor if (viscous .or. dummy) then if (weno_Re_flux) then - call s_compute_viscous_source_flux(qL_prim_vf(momxb:momxe), dqL_prim_dx_vf(momxb:momxe), & - & dqL_prim_dy_vf(momxb:momxe), dqL_prim_dz_vf(momxb:momxe), & - & qR_prim_vf(momxb:momxe), dqR_prim_dx_vf(momxb:momxe), & - & dqR_prim_dy_vf(momxb:momxe), dqR_prim_dz_vf(momxb:momxe), flux_src_vf, & - & norm_dir, ix, iy, iz) + + call s_compute_viscous_source_flux( & + qL_prim_vf(momxb:momxe), & + dqL_prim_dx_vf(momxb:momxe), & + dqL_prim_dy_vf(momxb:momxe), & + dqL_prim_dz_vf(momxb:momxe), & + qR_prim_vf(momxb:momxe), & + dqR_prim_dx_vf(momxb:momxe), & + dqR_prim_dy_vf(momxb:momxe), & + dqR_prim_dz_vf(momxb:momxe), & + flux_src_vf, norm_dir, ix, iy, iz) else - call s_compute_viscous_source_flux(q_prim_vf(momxb:momxe), dqL_prim_dx_vf(momxb:momxe), & - & dqL_prim_dy_vf(momxb:momxe), dqL_prim_dz_vf(momxb:momxe), & - & q_prim_vf(momxb:momxe), dqR_prim_dx_vf(momxb:momxe), & - & dqR_prim_dy_vf(momxb:momxe), dqR_prim_dz_vf(momxb:momxe), flux_src_vf, & - & norm_dir, ix, iy, iz) + call s_compute_viscous_source_flux( & + q_prim_vf(momxb:momxe), & + dqL_prim_dx_vf(momxb:momxe), & + dqL_prim_dy_vf(momxb:momxe), & + dqL_prim_dz_vf(momxb:momxe), & + q_prim_vf(momxb:momxe), & + dqR_prim_dx_vf(momxb:momxe), & + dqR_prim_dy_vf(momxb:momxe), & + dqR_prim_dz_vf(momxb:momxe), & + flux_src_vf, norm_dir, ix, iy, iz) end if end if - call s_finalize_riemann_solver(flux_vf, flux_src_vf, flux_gsrc_vf, norm_dir) + call s_finalize_riemann_solver(flux_vf, flux_src_vf, & + flux_gsrc_vf, & + norm_dir) end subroutine s_hll_riemann_solver - !> Lax-Friedrichs (Rusanov) approximate Riemann solver - subroutine s_lf_riemann_solver(qL_prim_rsx_vf, qL_prim_rsy_vf, qL_prim_rsz_vf, dqL_prim_dx_vf, dqL_prim_dy_vf, & + !> @brief Computes intercell fluxes using the Lax-Friedrichs (LF) approximate Riemann solver. + subroutine s_lf_riemann_solver(qL_prim_rsx_vf, qL_prim_rsy_vf, qL_prim_rsz_vf, dqL_prim_dx_vf, & + dqL_prim_dy_vf, & + dqL_prim_dz_vf, & + qL_prim_vf, & + qR_prim_rsx_vf, qR_prim_rsy_vf, qR_prim_rsz_vf, dqR_prim_dx_vf, & + dqR_prim_dy_vf, & + dqR_prim_dz_vf, & + qR_prim_vf, & + q_prim_vf, & + flux_vf, flux_src_vf, & + flux_gsrc_vf, & + norm_dir, ix, iy, iz) + + real(wp), dimension(idwbuff(1)%beg:, idwbuff(2)%beg:, idwbuff(3)%beg:, 1:), intent(inout) :: qL_prim_rsx_vf, qL_prim_rsy_vf, qL_prim_rsz_vf, qR_prim_rsx_vf, qR_prim_rsy_vf, qR_prim_rsz_vf + type(scalar_field), dimension(sys_size), intent(in) :: q_prim_vf - & dqL_prim_dz_vf, qL_prim_vf, qR_prim_rsx_vf, qR_prim_rsy_vf, qR_prim_rsz_vf, dqR_prim_dx_vf, dqR_prim_dy_vf, & - & dqR_prim_dz_vf, qR_prim_vf, q_prim_vf, flux_vf, flux_src_vf, flux_gsrc_vf, norm_dir, ix, iy, iz) - - real(wp), dimension(idwbuff(1)%beg:,idwbuff(2)%beg:,idwbuff(3)%beg:,1:), intent(inout) :: qL_prim_rsx_vf, qL_prim_rsy_vf, & - & qL_prim_rsz_vf, qR_prim_rsx_vf, qR_prim_rsy_vf, qR_prim_rsz_vf - type(scalar_field), dimension(sys_size), intent(in) :: q_prim_vf type(scalar_field), allocatable, dimension(:), intent(inout) :: qL_prim_vf, qR_prim_vf - type(scalar_field), allocatable, dimension(:), intent(inout) :: dqL_prim_dx_vf, dqR_prim_dx_vf, dqL_prim_dy_vf, & - & dqR_prim_dy_vf, dqL_prim_dz_vf, dqR_prim_dz_vf + + type(scalar_field), & + allocatable, dimension(:), & + intent(inout) :: dqL_prim_dx_vf, dqR_prim_dx_vf, & + dqL_prim_dy_vf, dqR_prim_dy_vf, & + dqL_prim_dz_vf, dqR_prim_dz_vf ! Intercell fluxes - type(scalar_field), dimension(sys_size), intent(inout) :: flux_vf, flux_src_vf, flux_gsrc_vf - real(wp) :: flux_tau_L, flux_tau_R - integer, intent(in) :: norm_dir - type(int_bounds_info), intent(in) :: ix, iy, iz + type(scalar_field), & + dimension(sys_size), & + intent(inout) :: flux_vf, flux_src_vf, flux_gsrc_vf + real(wp) :: flux_tau_L, flux_tau_R + integer, intent(in) :: norm_dir + type(int_bounds_info), intent(in) :: ix, iy, iz #:if not MFC_CASE_OPTIMIZATION and USING_AMD - real(wp), dimension(3) :: alpha_rho_L, alpha_rho_R - real(wp), dimension(3) :: vel_L, vel_R - real(wp), dimension(3) :: alpha_L, alpha_R - real(wp), dimension(10) :: Ys_L, Ys_R - real(wp), dimension(10) :: Cp_iL, Cp_iR, Xs_L, Xs_R, Gamma_iL, Gamma_iR - real(wp), dimension(10) :: Yi_avg, Phi_avg, h_iL, h_iR, h_avg_2 - real(wp), dimension(3, 3) :: vel_grad_L, vel_grad_R !< Averaged velocity gradient tensor `d(vel_i)/d(coord_j)`. + real(wp), dimension(3) :: alpha_rho_L, alpha_rho_R + real(wp), dimension(3) :: vel_L, vel_R + real(wp), dimension(3) :: alpha_L, alpha_R + real(wp), dimension(10) :: Ys_L, Ys_R + real(wp), dimension(10) :: Cp_iL, Cp_iR, Xs_L, Xs_R, Gamma_iL, Gamma_iR + real(wp), dimension(10) :: Yi_avg, Phi_avg, h_iL, h_iR, h_avg_2 + real(wp), dimension(3, 3) :: vel_grad_L, vel_grad_R !< Averaged velocity gradient tensor `d(vel_i)/d(coord_j)`. #:else - real(wp), dimension(num_fluids) :: alpha_rho_L, alpha_rho_R - real(wp), dimension(num_vels) :: vel_L, vel_R - real(wp), dimension(num_fluids) :: alpha_L, alpha_R + real(wp), dimension(num_fluids) :: alpha_rho_L, alpha_rho_R + real(wp), dimension(num_vels) :: vel_L, vel_R + real(wp), dimension(num_fluids) :: alpha_L, alpha_R real(wp), dimension(num_species) :: Ys_L, Ys_R real(wp), dimension(num_species) :: Cp_iL, Cp_iR, Xs_L, Xs_R, Gamma_iL, Gamma_iR real(wp), dimension(num_species) :: Yi_avg, Phi_avg, h_iL, h_iR, h_avg_2 - !> Averaged velocity gradient tensor `d(vel_i)/d(coord_j)`. - real(wp), dimension(num_dims, num_dims) :: vel_grad_L, vel_grad_R + real(wp), dimension(num_dims, num_dims) :: vel_grad_L, vel_grad_R !< Averaged velocity gradient tensor `d(vel_i)/d(coord_j)`. #:endif - real(wp) :: rho_L, rho_R - real(wp) :: pres_L, pres_R - real(wp) :: E_L, E_R - real(wp) :: H_L, H_R - real(wp) :: Cp_avg, Cv_avg, T_avg, eps, c_sum_Yi_Phi - real(wp) :: T_L, T_R - real(wp) :: Y_L, Y_R - real(wp) :: MW_L, MW_R - real(wp) :: R_gas_L, R_gas_R - real(wp) :: Cp_L, Cp_R - real(wp) :: Cv_L, Cv_R - real(wp) :: Gamm_L, Gamm_R - real(wp) :: gamma_L, gamma_R - real(wp) :: pi_inf_L, pi_inf_R - real(wp) :: qv_L, qv_R - real(wp) :: c_L, c_R - real(wp), dimension(6) :: tau_e_L, tau_e_R - real(wp) :: G_L, G_R - real(wp), dimension(2) :: Re_L, Re_R - real(wp), dimension(3) :: xi_field_L, xi_field_R - real(wp) :: rho_avg - real(wp) :: H_avg - real(wp) :: gamma_avg - real(wp) :: c_avg - real(wp) :: s_L, s_R, s_M, s_P, s_S - real(wp) :: xi_M, xi_P - real(wp) :: ptilde_L, ptilde_R - real(wp) :: vel_L_rms, vel_R_rms, vel_avg_rms - real(wp) :: vel_L_tmp, vel_R_tmp - real(wp) :: Ms_L, Ms_R, pres_SL, pres_SR - real(wp) :: alpha_L_sum, alpha_R_sum - real(wp) :: zcoef, pcorr !< low Mach number correction - type(riemann_states) :: c_fast, pres_mag + real(wp) :: rho_L, rho_R + + real(wp) :: pres_L, pres_R + real(wp) :: E_L, E_R + real(wp) :: H_L, H_R + real(wp) :: Cp_avg, Cv_avg, T_avg, eps, c_sum_Yi_Phi + real(wp) :: T_L, T_R + real(wp) :: Y_L, Y_R + real(wp) :: MW_L, MW_R + real(wp) :: R_gas_L, R_gas_R + real(wp) :: Cp_L, Cp_R + real(wp) :: Cv_L, Cv_R + real(wp) :: Gamm_L, Gamm_R + real(wp) :: gamma_L, gamma_R + real(wp) :: pi_inf_L, pi_inf_R + real(wp) :: qv_L, qv_R + real(wp) :: c_L, c_R + real(wp), dimension(6) :: tau_e_L, tau_e_R + real(wp) :: G_L, G_R + real(wp), dimension(2) :: Re_L, Re_R + real(wp), dimension(3) :: xi_field_L, xi_field_R + + real(wp) :: rho_avg + real(wp) :: H_avg + real(wp) :: gamma_avg + real(wp) :: c_avg + + real(wp) :: s_L, s_R, s_M, s_P, s_S + real(wp) :: xi_M, xi_P + + real(wp) :: ptilde_L, ptilde_R + real(wp) :: vel_L_rms, vel_R_rms, vel_avg_rms + real(wp) :: vel_L_tmp, vel_R_tmp + real(wp) :: Ms_L, Ms_R, pres_SL, pres_SR + real(wp) :: alpha_L_sum, alpha_R_sum + real(wp) :: zcoef, pcorr !< low Mach number correction + + type(riemann_states) :: c_fast, pres_mag type(riemann_states_vec3) :: B - type(riemann_states) :: Ga !< Gamma (Lorentz factor) - type(riemann_states) :: vdotB, B2 - type(riemann_states_vec3) :: b4 !< 4-magnetic field components (spatial: b4x, b4y, b4z) - type(riemann_states_vec3) :: cm !< Conservative momentum variables - integer :: i, j, k, l, q !< Generic loop iterators - integer, dimension(3) :: idx_right_phys !< Physical (j,k,l) indices for right state. - ! Populating the buffers of the left and right Riemann problem states variables, based on the choice of boundary conditions - - call s_populate_riemann_states_variables_buffers(qL_prim_rsx_vf, qL_prim_rsy_vf, qL_prim_rsz_vf, dqL_prim_dx_vf, & - & dqL_prim_dy_vf, dqL_prim_dz_vf, qR_prim_rsx_vf, qR_prim_rsy_vf, qR_prim_rsz_vf, dqR_prim_dx_vf, dqR_prim_dy_vf, & - & dqR_prim_dz_vf, norm_dir, ix, iy, iz) + + type(riemann_states) :: Ga ! Gamma (Lorentz factor) + type(riemann_states) :: vdotB, B2 + type(riemann_states_vec3) :: b4 ! 4-magnetic field components (spatial: b4x, b4y, b4z) + type(riemann_states_vec3) :: cm ! Conservative momentum variables + + integer :: i, j, k, l, q !< Generic loop iterators + integer, dimension(3) :: idx_right_phys !< Physical (j,k,l) indices for right state. + + ! Populating the buffers of the left and right Riemann problem + ! states variables, based on the choice of boundary conditions + call s_populate_riemann_states_variables_buffers( & + qL_prim_rsx_vf, qL_prim_rsy_vf, qL_prim_rsz_vf, dqL_prim_dx_vf, & + dqL_prim_dy_vf, & + dqL_prim_dz_vf, & + qR_prim_rsx_vf, qR_prim_rsy_vf, qR_prim_rsz_vf, dqR_prim_dx_vf, & + dqR_prim_dy_vf, & + dqR_prim_dz_vf, & + norm_dir, ix, iy, iz) ! Reshaping inputted data based on dimensional splitting direction - call s_initialize_riemann_solver(flux_src_vf, norm_dir) + call s_initialize_riemann_solver( & + flux_src_vf, & + norm_dir) #:for NORM_DIR, XYZ in [(1, 'x'), (2, 'y'), (3, 'z')] + if (norm_dir == ${NORM_DIR}$) then - $:GPU_PARALLEL_LOOP(collapse=3, private='[i, j, k, l, q, alpha_rho_L, alpha_rho_R, vel_L, vel_R, alpha_L, & - & alpha_R, tau_e_L, tau_e_R, G_L, G_R, Re_L, Re_R, rho_avg, h_avg, gamma_avg, s_L, s_R, s_S, & - & Ys_L, Ys_R, xi_field_L, xi_field_R, Cp_iL, Cp_iR, Xs_L, Xs_R, Gamma_iL, Gamma_iR, Yi_avg, & - & Phi_avg, h_iL, h_iR, h_avg_2, c_fast, pres_mag, B, Ga, vdotB, B2, b4, cm, pcorr, zcoef, & - & vel_grad_L, vel_grad_R, idx_right_phys, vel_L_rms, vel_R_rms, vel_avg_rms, vel_L_tmp, & - & vel_R_tmp, Ms_L, Ms_R, pres_SL, pres_SR, alpha_L_sum, alpha_R_sum, c_avg, pres_L, pres_R, & - & rho_L, rho_R, gamma_L, gamma_R, pi_inf_L, pi_inf_R, qv_L, qv_R, c_L, c_R, E_L, E_R, H_L, & - & H_R, ptilde_L, ptilde_R, s_M, s_P, xi_M, xi_P, Cp_avg, Cv_avg, T_avg, eps, c_sum_Yi_Phi, & - & Cp_L, Cp_R, Cv_L, Cv_R, R_gas_L, R_gas_R, MW_L, MW_R, T_L, T_R, Y_L, Y_R]') + $:GPU_PARALLEL_LOOP(collapse=3, private='[i,j,k,l, q, alpha_rho_L,alpha_rho_R,vel_L,vel_R,alpha_L,alpha_R,tau_e_L,tau_e_R,G_L,G_R,Re_L,Re_R,rho_avg,h_avg,gamma_avg,s_L,s_R,s_S,Ys_L,Ys_R,xi_field_L,xi_field_R,Cp_iL,Cp_iR,Xs_L,Xs_R,Gamma_iL,Gamma_iR,Yi_avg,Phi_avg,h_iL,h_iR,h_avg_2,c_fast,pres_mag,B,Ga,vdotB,B2,b4,cm,pcorr,zcoef,vel_grad_L,vel_grad_R,idx_right_phys,vel_L_rms,vel_R_rms,vel_avg_rms,vel_L_tmp,vel_R_tmp,Ms_L,Ms_R,pres_SL,pres_SR,alpha_L_sum,alpha_R_sum,c_avg,pres_L,pres_R,rho_L,rho_R,gamma_L,gamma_R,pi_inf_L,pi_inf_R,qv_L,qv_R,c_L,c_R,E_L,E_R,H_L,H_R,ptilde_L,ptilde_R,s_M,s_P,xi_M,xi_P,Cp_avg,Cv_avg,T_avg,eps,c_sum_Yi_Phi,Cp_L,Cp_R,Cv_L,Cv_R,R_gas_L,R_gas_R,MW_L,MW_R,T_L,T_R,Y_L,Y_R]') do l = is3%beg, is3%end do k = is2%beg, is2%end do j = is1%beg, is1%end @@ -938,14 +1187,14 @@ contains pres_R = qR_prim_rs${XYZ}$_vf(j + 1, k, l, E_idx) if (mhd) then - if (n == 0) then ! 1D: constant Bx; By, Bz as variables + if (n == 0) then ! 1D: constant Bx; By, Bz as variables B%L(1) = Bx0 B%R(1) = Bx0 B%L(2) = qL_prim_rs${XYZ}$_vf(j, k, l, B_idx%beg) B%R(2) = qR_prim_rs${XYZ}$_vf(j + 1, k, l, B_idx%beg) B%L(3) = qL_prim_rs${XYZ}$_vf(j, k, l, B_idx%beg + 1) B%R(3) = qR_prim_rs${XYZ}$_vf(j + 1, k, l, B_idx%beg + 1) - else ! 2D/3D: Bx, By, Bz as variables + else ! 2D/3D: Bx, By, Bz as variables B%L(1) = qL_prim_rs${XYZ}$_vf(j, k, l, B_idx%beg) B%R(1) = qR_prim_rs${XYZ}$_vf(j + 1, k, l, B_idx%beg) B%L(2) = qL_prim_rs${XYZ}$_vf(j, k, l, B_idx%beg + 1) @@ -1010,8 +1259,10 @@ contains $:GPU_LOOP(parallelism='[seq]') do q = 1, Re_size(i) - Re_L(i) = alpha_L(Re_idx(i, q))/Res_gs(i, q) + Re_L(i) - Re_R(i) = alpha_R(Re_idx(i, q))/Res_gs(i, q) + Re_R(i) + Re_L(i) = alpha_L(Re_idx(i, q))/Res_gs(i, q) & + + Re_L(i) + Re_R(i) = alpha_R(Re_idx(i, q))/Res_gs(i, q) & + + Re_R(i) end do Re_L(i) = 1._wp/max(Re_L(i), sgm_eps) @@ -1072,7 +1323,7 @@ contains E_R = rho_R*E_R + 5.e-1*rho_R*vel_R_rms H_L = (E_L + pres_L)/rho_L H_R = (E_R + pres_R)/rho_R - else if (mhd .and. relativity) then + elseif (mhd .and. relativity) then #:if not MFC_CASE_OPTIMIZATION or num_dims > 2 Ga%L = 1._wp/sqrt(1._wp - vel_L_rms) Ga%R = 1._wp/sqrt(1._wp - vel_R_rms) @@ -1097,15 +1348,13 @@ contains E_L = rho_L*H_L*Ga%L**2 - pres_L + 0.5_wp*(B2%L + vel_L_rms*B2%L - vdotB%L**2._wp) - rho_L*Ga%L E_R = rho_R*H_R*Ga%R**2 - pres_R + 0.5_wp*(B2%R + vel_R_rms*B2%R - vdotB%R**2._wp) - rho_R*Ga%R #:endif - else if (mhd .and. .not. relativity) then + elseif (mhd .and. .not. relativity) then pres_mag%L = 0.5_wp*(B%L(1)**2._wp + B%L(2)**2._wp + B%L(3)**2._wp) pres_mag%R = 0.5_wp*(B%R(1)**2._wp + B%R(2)**2._wp + B%R(3)**2._wp) E_L = gamma_L*pres_L + pi_inf_L + 0.5_wp*rho_L*vel_L_rms + qv_L + pres_mag%L - E_R = gamma_R*pres_R + pi_inf_R + 0.5_wp*rho_R*vel_R_rms + qv_R & - & + pres_mag%R ! includes magnetic energy + E_R = gamma_R*pres_R + pi_inf_R + 0.5_wp*rho_R*vel_R_rms + qv_R + pres_mag%R ! includes magnetic energy H_L = (E_L + pres_L - pres_mag%L)/rho_L - H_R = (E_R + pres_R - pres_mag%R) & - & /rho_R ! stagnation enthalpy here excludes magnetic energy (only used to find speed of sound) + H_R = (E_R + pres_R - pres_mag%R)/rho_R ! stagnation enthalpy here excludes magnetic energy (only used to find speed of sound) else E_L = gamma_L*pres_L + pi_inf_L + 5.e-1*rho_L*vel_L_rms + qv_L E_R = gamma_R*pres_R + pi_inf_R + 5.e-1*rho_R*vel_R_rms + qv_R @@ -1131,7 +1380,8 @@ contains do i = 1, strxe - strxb + 1 tau_e_L(i) = qL_prim_rs${XYZ}$_vf(j, k, l, strxb - 1 + i) tau_e_R(i) = qR_prim_rs${XYZ}$_vf(j + 1, k, l, strxb - 1 + i) - ! Elastic contribution to energy if G large enough TODO take out if statement if stable without + ! Elastic contribution to energy if G large enough + !TODO take out if statement if stable without if ((G_L > 1000) .and. (G_R > 1000)) then E_L = E_L + (tau_e_L(i)*tau_e_L(i))/(4._wp*G_L) E_R = E_R + (tau_e_R(i)*tau_e_R(i))/(4._wp*G_R) @@ -1144,11 +1394,11 @@ contains end do end if - call s_compute_speed_of_sound(pres_L, rho_L, gamma_L, pi_inf_L, H_L, alpha_L, vel_L_rms, 0._wp, c_L, & - & qv_L) + call s_compute_speed_of_sound(pres_L, rho_L, gamma_L, pi_inf_L, H_L, alpha_L, & + vel_L_rms, 0._wp, c_L, qv_L) - call s_compute_speed_of_sound(pres_R, rho_R, gamma_R, pi_inf_R, H_R, alpha_R, vel_R_rms, 0._wp, c_R, & - & qv_R) + call s_compute_speed_of_sound(pres_R, rho_R, gamma_R, pi_inf_R, H_R, alpha_R, & + vel_R_rms, 0._wp, c_R, qv_R) if (mhd) then call s_compute_fast_magnetosonic_speed(rho_L, c_L, B%L, norm_dir, c_fast%L, H_L) @@ -1183,17 +1433,22 @@ contains if (.not. relativity) then $:GPU_LOOP(parallelism='[seq]') do i = 1, contxe - flux_rs${XYZ}$_vf(j, k, l, & - & i) = (s_M*alpha_rho_R(i)*vel_R(norm_dir) - s_P*alpha_rho_L(i) & - & *vel_L(norm_dir) + s_M*s_P*(alpha_rho_L(i) - alpha_rho_R(i)))/(s_M - s_P) + flux_rs${XYZ}$_vf(j, k, l, i) = & + (s_M*alpha_rho_R(i)*vel_R(norm_dir) & + - s_P*alpha_rho_L(i)*vel_L(norm_dir) & + + s_M*s_P*(alpha_rho_L(i) & + - alpha_rho_R(i))) & + /(s_M - s_P) end do - else if (relativity) then + elseif (relativity) then $:GPU_LOOP(parallelism='[seq]') do i = 1, contxe - flux_rs${XYZ}$_vf(j, k, l, & - & i) = (s_M*Ga%R*alpha_rho_R(i)*vel_R(norm_dir) - s_P*Ga%L*alpha_rho_L(i) & - & *vel_L(norm_dir) + s_M*s_P*(Ga%L*alpha_rho_L(i) - Ga%R*alpha_rho_R(i))) & - & /(s_M - s_P) + flux_rs${XYZ}$_vf(j, k, l, i) = & + (s_M*Ga%R*alpha_rho_R(i)*vel_R(norm_dir) & + - s_P*Ga%L*alpha_rho_L(i)*vel_L(norm_dir) & + + s_M*s_P*(Ga%L*alpha_rho_L(i) & + - Ga%R*alpha_rho_R(i))) & + /(s_M - s_P) end do end if @@ -1201,54 +1456,78 @@ contains if (mhd .and. (.not. relativity)) then $:GPU_LOOP(parallelism='[seq]') do i = 1, 3 - ! Flux of rho*v_i in the ${XYZ}$ direction = rho * v_i * v_${XYZ}$ - B_i * B_${XYZ}$ + - ! delta_(${XYZ}$,i) * p_tot - flux_rs${XYZ}$_vf(j, k, l, & - & contxe + i) = (s_M*(rho_R*vel_R(i)*vel_R(norm_dir) - B%R(i)*B%R(norm_dir) & - & + dir_flg(i)*(pres_R + pres_mag%R)) - s_P*(rho_L*vel_L(i)*vel_L(norm_dir) & - & - B%L(i)*B%L(norm_dir) + dir_flg(i)*(pres_L + pres_mag%L)) & - & + s_M*s_P*(rho_L*vel_L(i) - rho_R*vel_R(i)))/(s_M - s_P) + ! Flux of rho*v_i in the ${XYZ}$ direction + ! = rho * v_i * v_${XYZ}$ - B_i * B_${XYZ}$ + delta_(${XYZ}$,i) * p_tot + flux_rs${XYZ}$_vf(j, k, l, contxe + i) = & + (s_M*(rho_R*vel_R(i)*vel_R(norm_dir) & + - B%R(i)*B%R(norm_dir) & + + dir_flg(i)*(pres_R + pres_mag%R)) & + - s_P*(rho_L*vel_L(i)*vel_L(norm_dir) & + - B%L(i)*B%L(norm_dir) & + + dir_flg(i)*(pres_L + pres_mag%L)) & + + s_M*s_P*(rho_L*vel_L(i) - rho_R*vel_R(i))) & + /(s_M - s_P) end do - else if (mhd .and. relativity) then + elseif (mhd .and. relativity) then $:GPU_LOOP(parallelism='[seq]') do i = 1, 3 - ! Flux of m_i in the ${XYZ}$ direction = m_i * v_${XYZ}$ - b_i/Gamma * B_${XYZ}$ + - ! delta_(${XYZ}$,i) * p_tot - flux_rs${XYZ}$_vf(j, k, l, & - & contxe + i) = (s_M*(cm%R(i)*vel_R(norm_dir) - b4%R(i)/Ga%R*B%R(norm_dir) & - & + dir_flg(i)*(pres_R + pres_mag%R)) - s_P*(cm%L(i)*vel_L(norm_dir) & - & - b4%L(i)/Ga%L*B%L(norm_dir) + dir_flg(i)*(pres_L + pres_mag%L)) & - & + s_M*s_P*(cm%L(i) - cm%R(i)))/(s_M - s_P) + ! Flux of m_i in the ${XYZ}$ direction + ! = m_i * v_${XYZ}$ - b_i/Gamma * B_${XYZ}$ + delta_(${XYZ}$,i) * p_tot + flux_rs${XYZ}$_vf(j, k, l, contxe + i) = & + (s_M*(cm%R(i)*vel_R(norm_dir) & + - b4%R(i)/Ga%R*B%R(norm_dir) & + + dir_flg(i)*(pres_R + pres_mag%R)) & + - s_P*(cm%L(i)*vel_L(norm_dir) & + - b4%L(i)/Ga%L*B%L(norm_dir) & + + dir_flg(i)*(pres_L + pres_mag%L)) & + + s_M*s_P*(cm%L(i) - cm%R(i))) & + /(s_M - s_P) end do - else if (bubbles_euler) then + elseif (bubbles_euler) then $:GPU_LOOP(parallelism='[seq]') do i = 1, num_vels - flux_rs${XYZ}$_vf(j, k, l, & - & contxe + dir_idx(i)) = (s_M*(rho_R*vel_R(dir_idx(1))*vel_R(dir_idx(i)) & - & + dir_flg(dir_idx(i))*(pres_R - ptilde_R)) - s_P*(rho_L*vel_L(dir_idx(1)) & - & *vel_L(dir_idx(i)) + dir_flg(dir_idx(i))*(pres_L - ptilde_L)) & - & + s_M*s_P*(rho_L*vel_L(dir_idx(i)) - rho_R*vel_R(dir_idx(i))))/(s_M - s_P) & - & + (s_M/s_L)*(s_P/s_R)*pcorr*(vel_R(dir_idx(i)) - vel_L(dir_idx(i))) + flux_rs${XYZ}$_vf(j, k, l, contxe + dir_idx(i)) = & + (s_M*(rho_R*vel_R(dir_idx(1)) & + *vel_R(dir_idx(i)) & + + dir_flg(dir_idx(i))*(pres_R - ptilde_R)) & + - s_P*(rho_L*vel_L(dir_idx(1)) & + *vel_L(dir_idx(i)) & + + dir_flg(dir_idx(i))*(pres_L - ptilde_L)) & + + s_M*s_P*(rho_L*vel_L(dir_idx(i)) & + - rho_R*vel_R(dir_idx(i)))) & + /(s_M - s_P) & + + (s_M/s_L)*(s_P/s_R)*pcorr*(vel_R(dir_idx(i)) - vel_L(dir_idx(i))) end do else if (hypoelasticity) then $:GPU_LOOP(parallelism='[seq]') do i = 1, num_vels - flux_rs${XYZ}$_vf(j, k, l, & - & contxe + dir_idx(i)) = (s_M*(rho_R*vel_R(dir_idx(1))*vel_R(dir_idx(i)) & - & + dir_flg(dir_idx(i))*pres_R - tau_e_R(dir_idx_tau(i))) & - & - s_P*(rho_L*vel_L(dir_idx(1))*vel_L(dir_idx(i)) + dir_flg(dir_idx(i)) & - & *pres_L - tau_e_L(dir_idx_tau(i))) + s_M*s_P*(rho_L*vel_L(dir_idx(i)) & - & - rho_R*vel_R(dir_idx(i))))/(s_M - s_P) + flux_rs${XYZ}$_vf(j, k, l, contxe + dir_idx(i)) = & + (s_M*(rho_R*vel_R(dir_idx(1)) & + *vel_R(dir_idx(i)) & + + dir_flg(dir_idx(i))*pres_R & + - tau_e_R(dir_idx_tau(i))) & + - s_P*(rho_L*vel_L(dir_idx(1)) & + *vel_L(dir_idx(i)) & + + dir_flg(dir_idx(i))*pres_L & + - tau_e_L(dir_idx_tau(i))) & + + s_M*s_P*(rho_L*vel_L(dir_idx(i)) & + - rho_R*vel_R(dir_idx(i)))) & + /(s_M - s_P) end do else $:GPU_LOOP(parallelism='[seq]') do i = 1, num_vels - flux_rs${XYZ}$_vf(j, k, l, & - & contxe + dir_idx(i)) = (s_M*(rho_R*vel_R(dir_idx(1))*vel_R(dir_idx(i)) & - & + dir_flg(dir_idx(i))*pres_R) - s_P*(rho_L*vel_L(dir_idx(1)) & - & *vel_L(dir_idx(i)) + dir_flg(dir_idx(i))*pres_L) & - & + s_M*s_P*(rho_L*vel_L(dir_idx(i)) - rho_R*vel_R(dir_idx(i))))/(s_M - s_P) & - & + (s_M/s_L)*(s_P/s_R)*pcorr*(vel_R(dir_idx(i)) - vel_L(dir_idx(i))) + flux_rs${XYZ}$_vf(j, k, l, contxe + dir_idx(i)) = & + (s_M*(rho_R*vel_R(dir_idx(1)) & + *vel_R(dir_idx(i)) & + + dir_flg(dir_idx(i))*pres_R) & + - s_P*(rho_L*vel_L(dir_idx(1)) & + *vel_L(dir_idx(i)) & + + dir_flg(dir_idx(i))*pres_L) & + + s_M*s_P*(rho_L*vel_L(dir_idx(i)) & + - rho_R*vel_R(dir_idx(i)))) & + /(s_M - s_P) & + + (s_M/s_L)*(s_P/s_R)*pcorr*(vel_R(dir_idx(i)) - vel_L(dir_idx(i))) end do end if @@ -1256,24 +1535,27 @@ contains if (mhd .and. (.not. relativity)) then ! energy flux = (E + p + p_mag) * v_${XYZ}$ - B_${XYZ}$ * (v_x*B_x + v_y*B_y + v_z*B_z) #:if not MFC_CASE_OPTIMIZATION or num_dims > 1 - flux_rs${XYZ}$_vf(j, k, l, & - & E_idx) = (s_M*(vel_R(norm_dir)*(E_R + pres_R + pres_mag%R) - B%R(norm_dir) & - & *(vel_R(1)*B%R(1) + vel_R(2)*B%R(2) + vel_R(3)*B%R(3))) & - & - s_P*(vel_L(norm_dir)*(E_L + pres_L + pres_mag%L) - B%L(norm_dir) & - & *(vel_L(1)*B%L(1) + vel_L(2)*B%L(2) + vel_L(3)*B%L(3))) + s_M*s_P*(E_L & - & - E_R))/(s_M - s_P) + flux_rs${XYZ}$_vf(j, k, l, E_idx) = & + (s_M*(vel_R(norm_dir)*(E_R + pres_R + pres_mag%R) - B%R(norm_dir)*(vel_R(1)*B%R(1) + vel_R(2)*B%R(2) + vel_R(3)*B%R(3))) & + - s_P*(vel_L(norm_dir)*(E_L + pres_L + pres_mag%L) - B%L(norm_dir)*(vel_L(1)*B%L(1) + vel_L(2)*B%L(2) + vel_L(3)*B%L(3))) & + + s_M*s_P*(E_L - E_R)) & + /(s_M - s_P) #:endif - else if (mhd .and. relativity) then - ! energy flux = m_${XYZ}$ - mass flux Hard-coded for single-component for now - flux_rs${XYZ}$_vf(j, k, l, & - & E_idx) = (s_M*(cm%R(norm_dir) - Ga%R*alpha_rho_R(1)*vel_R(norm_dir)) & - & - s_P*(cm%L(norm_dir) - Ga%L*alpha_rho_L(1)*vel_L(norm_dir)) + s_M*s_P*(E_L & - & - E_R))/(s_M - s_P) + elseif (mhd .and. relativity) then + ! energy flux = m_${XYZ}$ - mass flux + ! Hard-coded for single-component for now + flux_rs${XYZ}$_vf(j, k, l, E_idx) = & + (s_M*(cm%R(norm_dir) - Ga%R*alpha_rho_R(1)*vel_R(norm_dir)) & + - s_P*(cm%L(norm_dir) - Ga%L*alpha_rho_L(1)*vel_L(norm_dir)) & + + s_M*s_P*(E_L - E_R)) & + /(s_M - s_P) else if (bubbles_euler) then - flux_rs${XYZ}$_vf(j, k, l, & - & E_idx) = (s_M*vel_R(dir_idx(1))*(E_R + pres_R - ptilde_R) & - & - s_P*vel_L(dir_idx(1))*(E_L + pres_L - ptilde_L) + s_M*s_P*(E_L - E_R))/(s_M & - & - s_P) + (s_M/s_L)*(s_P/s_R)*pcorr*(vel_R_rms - vel_L_rms)/2._wp + flux_rs${XYZ}$_vf(j, k, l, E_idx) = & + (s_M*vel_R(dir_idx(1))*(E_R + pres_R - ptilde_R) & + - s_P*vel_L(dir_idx(1))*(E_L + pres_L - ptilde_L) & + + s_M*s_P*(E_L - E_R)) & + /(s_M - s_P) & + + (s_M/s_L)*(s_P/s_R)*pcorr*(vel_R_rms - vel_L_rms)/2._wp else if (hypoelasticity) then flux_tau_L = 0._wp; flux_tau_R = 0._wp $:GPU_LOOP(parallelism='[seq]') @@ -1281,34 +1563,44 @@ contains flux_tau_L = flux_tau_L + tau_e_L(dir_idx_tau(i))*vel_L(dir_idx(i)) flux_tau_R = flux_tau_R + tau_e_R(dir_idx_tau(i))*vel_R(dir_idx(i)) end do - flux_rs${XYZ}$_vf(j, k, l, & - & E_idx) = (s_M*(vel_R(dir_idx(1))*(E_R + pres_R) - flux_tau_R) & - & - s_P*(vel_L(dir_idx(1))*(E_L + pres_L) - flux_tau_L) + s_M*s_P*(E_L - E_R)) & - & /(s_M - s_P) + flux_rs${XYZ}$_vf(j, k, l, E_idx) = & + (s_M*(vel_R(dir_idx(1))*(E_R + pres_R) - flux_tau_R) & + - s_P*(vel_L(dir_idx(1))*(E_L + pres_L) - flux_tau_L) & + + s_M*s_P*(E_L - E_R))/(s_M - s_P) else - flux_rs${XYZ}$_vf(j, k, l, & - & E_idx) = (s_M*vel_R(dir_idx(1))*(E_R + pres_R) - s_P*vel_L(dir_idx(1))*(E_L & - & + pres_L) + s_M*s_P*(E_L - E_R))/(s_M - s_P) + (s_M/s_L)*(s_P/s_R) & - & *pcorr*(vel_R_rms - vel_L_rms)/2._wp + flux_rs${XYZ}$_vf(j, k, l, E_idx) = & + (s_M*vel_R(dir_idx(1))*(E_R + pres_R) & + - s_P*vel_L(dir_idx(1))*(E_L + pres_L) & + + s_M*s_P*(E_L - E_R)) & + /(s_M - s_P) & + + (s_M/s_L)*(s_P/s_R)*pcorr*(vel_R_rms - vel_L_rms)/2._wp end if ! Elastic Stresses if (hypoelasticity) then - do i = 1, strxe - strxb + 1 ! TODO: this indexing may be slow - flux_rs${XYZ}$_vf(j, k, l, & - & strxb - 1 + i) = (s_M*(rho_R*vel_R(dir_idx(1))*tau_e_R(i)) & - & - s_P*(rho_L*vel_L(dir_idx(1))*tau_e_L(i)) + s_M*s_P*(rho_L*tau_e_L(i) & - & - rho_R*tau_e_R(i)))/(s_M - s_P) + do i = 1, strxe - strxb + 1 !TODO: this indexing may be slow + flux_rs${XYZ}$_vf(j, k, l, strxb - 1 + i) = & + (s_M*(rho_R*vel_R(dir_idx(1)) & + *tau_e_R(i)) & + - s_P*(rho_L*vel_L(dir_idx(1)) & + *tau_e_L(i)) & + + s_M*s_P*(rho_L*tau_e_L(i) & + - rho_R*tau_e_R(i))) & + /(s_M - s_P) end do end if - ! Advection flux and source: interface velocity for volume fraction transport + ! Advection $:GPU_LOOP(parallelism='[seq]') do i = advxb, advxe - flux_rs${XYZ}$_vf(j, k, l, i) = (qL_prim_rs${XYZ}$_vf(j, k, l, i) - qR_prim_rs${XYZ}$_vf(j + 1, & - & k, l, i))*s_M*s_P/(s_M - s_P) - flux_src_rs${XYZ}$_vf(j, k, l, i) = (s_M*qR_prim_rs${XYZ}$_vf(j + 1, k, l, & - & i) - s_P*qL_prim_rs${XYZ}$_vf(j, k, l, i))/(s_M - s_P) + flux_rs${XYZ}$_vf(j, k, l, i) = & + (qL_prim_rs${XYZ}$_vf(j, k, l, i) & + - qR_prim_rs${XYZ}$_vf(j + 1, k, l, i)) & + *s_M*s_P/(s_M - s_P) + flux_src_rs${XYZ}$_vf(j, k, l, i) = & + (s_M*qR_prim_rs${XYZ}$_vf(j + 1, k, l, i) & + - s_P*qL_prim_rs${XYZ}$_vf(j, k, l, i)) & + /(s_M - s_P) end do if (bubbles_euler) then @@ -1324,35 +1616,34 @@ contains Y_L = qL_prim_rs${XYZ}$_vf(j, k, l, i) Y_R = qR_prim_rs${XYZ}$_vf(j + 1, k, l, i) - flux_rs${XYZ}$_vf(j, k, l, & - & i) = (s_M*Y_R*rho_R*vel_R(dir_idx(1)) - s_P*Y_L*rho_L*vel_L(dir_idx(1)) & - & + s_M*s_P*(Y_L*rho_L - Y_R*rho_R))/(s_M - s_P) + flux_rs${XYZ}$_vf(j, k, l, i) = (s_M*Y_R*rho_R*vel_R(dir_idx(1)) & + - s_P*Y_L*rho_L*vel_L(dir_idx(1)) & + + s_M*s_P*(Y_L*rho_L - Y_R*rho_R)) & + /(s_M - s_P) flux_src_rs${XYZ}$_vf(j, k, l, i) = 0._wp end do end if - ! MHD: magnetic flux and Maxwell stress contributions if (mhd) then - if (n == 0) then ! 1D: d/dx flux only & Bx = Bx0 = const. - ! B_y flux = v_x * B_y - v_y * Bx0 B_z flux = v_x * B_z - v_z * Bx0 + if (n == 0) then ! 1D: d/dx flux only & Bx = Bx0 = const. + ! B_y flux = v_x * B_y - v_y * Bx0 + ! B_z flux = v_x * B_z - v_z * Bx0 $:GPU_LOOP(parallelism='[seq]') do i = 0, 1 - flux_rsx_vf(j, k, l, & - & B_idx%beg + i) = (s_M*(vel_R(1)*B%R(2 + i) - vel_R(2 + i)*Bx0) & - & - s_P*(vel_L(1)*B%L(2 + i) - vel_L(2 + i)*Bx0) + s_M*s_P*(B%L(2 + i) & - & - B%R(2 + i)))/(s_M - s_P) + flux_rsx_vf(j, k, l, B_idx%beg + i) = (s_M*(vel_R(1)*B%R(2 + i) - vel_R(2 + i)*Bx0) & + - s_P*(vel_L(1)*B%L(2 + i) - vel_L(2 + i)*Bx0) & + + s_M*s_P*(B%L(2 + i) - B%R(2 + i)))/(s_M - s_P) end do - else ! 2D/3D: Bx, By, Bz /= const. but zero flux component in the same direction - ! B_x d/d${XYZ}$ flux = (1 - delta(x,${XYZ}$)) * (v_${XYZ}$ * B_x - v_x * B_${XYZ}$) B_y - ! d/d${XYZ}$ flux = (1 - delta(y,${XYZ}$)) * (v_${XYZ}$ * B_y - v_y * B_${XYZ}$) B_z d/d${XYZ}$ - ! flux = (1 - delta(z,${XYZ}$)) * (v_${XYZ}$ * B_z - v_z * B_${XYZ}$) + else ! 2D/3D: Bx, By, Bz /= const. but zero flux component in the same direction + ! B_x d/d${XYZ}$ flux = (1 - delta(x,${XYZ}$)) * (v_${XYZ}$ * B_x - v_x * B_${XYZ}$) + ! B_y d/d${XYZ}$ flux = (1 - delta(y,${XYZ}$)) * (v_${XYZ}$ * B_y - v_y * B_${XYZ}$) + ! B_z d/d${XYZ}$ flux = (1 - delta(z,${XYZ}$)) * (v_${XYZ}$ * B_z - v_z * B_${XYZ}$) $:GPU_LOOP(parallelism='[seq]') do i = 0, 2 - flux_rs${XYZ}$_vf(j, k, l, & - & B_idx%beg + i) = (1 - dir_flg(i + 1))*(s_M*(vel_R(dir_idx(1))*B%R(i & - & + 1) - vel_R(i + 1)*B%R(norm_dir)) - s_P*(vel_L(dir_idx(1))*B%L(i + 1) & - & - vel_L(i + 1)*B%L(norm_dir)) + s_M*s_P*(B%L(i + 1) - B%R(i + 1))) & - & /(s_M - s_P) + flux_rs${XYZ}$_vf(j, k, l, B_idx%beg + i) = (1 - dir_flg(i + 1))*( & + s_M*(vel_R(dir_idx(1))*B%R(i + 1) - vel_R(i + 1)*B%R(norm_dir)) - & + s_P*(vel_L(dir_idx(1))*B%L(i + 1) - vel_L(i + 1)*B%L(norm_dir)) + & + s_M*s_P*(B%L(i + 1) - B%R(i + 1)))/(s_M - s_P) end do end if flux_src_rs${XYZ}$_vf(j, k, l, advxb) = 0._wp @@ -1360,14 +1651,15 @@ contains #:if (NORM_DIR == 2) if (cyl_coord) then - ! Substituting the advective flux into the inviscid geometrical source flux + !Substituting the advective flux into the inviscid geometrical source flux $:GPU_LOOP(parallelism='[seq]') do i = 1, E_idx flux_gsrc_rs${XYZ}$_vf(j, k, l, i) = flux_rs${XYZ}$_vf(j, k, l, i) end do ! Recalculating the radial momentum geometric source flux - flux_gsrc_rs${XYZ}$_vf(j, k, l, contxe + 2) = flux_rs${XYZ}$_vf(j, k, l, & - & contxe + 2) - (s_M*pres_R - s_P*pres_L)/(s_M - s_P) + flux_gsrc_rs${XYZ}$_vf(j, k, l, contxe + 2) = & + flux_rs${XYZ}$_vf(j, k, l, contxe + 2) & + - (s_M*pres_R - s_P*pres_L)/(s_M - s_P) ! Geometrical source of the void fraction(s) is zero $:GPU_LOOP(parallelism='[seq]') do i = advxb, advxe @@ -1377,8 +1669,10 @@ contains if (cyl_coord .and. hypoelasticity) then ! += tau_sigmasigma using HLL - flux_gsrc_rs${XYZ}$_vf(j, k, l, contxe + 2) = flux_gsrc_rs${XYZ}$_vf(j, k, l, & - & contxe + 2) + (s_M*tau_e_R(4) - s_P*tau_e_L(4))/(s_M - s_P) + flux_gsrc_rs${XYZ}$_vf(j, k, l, contxe + 2) = & + flux_gsrc_rs${XYZ}$_vf(j, k, l, contxe + 2) + & + (s_M*tau_e_R(4) - s_P*tau_e_L(4)) & + /(s_M - s_P) $:GPU_LOOP(parallelism='[seq]') do i = strxb, strxe @@ -1391,11 +1685,11 @@ contains end do $:END_GPU_PARALLEL_LOOP() end if + #:endfor if (viscous .or. dummy) then - $:GPU_PARALLEL_LOOP(collapse=3, private='[i, j, k, l, idx_right_phys, vel_grad_L, vel_grad_R, alpha_L, alpha_R, & - & vel_L, vel_R, Re_L, Re_R]', copyin='[norm_dir]') + $:GPU_PARALLEL_LOOP(collapse=3, private='[i,j,k,l, idx_right_phys, vel_grad_L, vel_grad_R, alpha_L, alpha_R, vel_L, vel_R, Re_L, Re_R]', copyin='[norm_dir]') do l = isz%beg, isz%end do k = isy%beg, isy%end do j = isx%beg, isx%end @@ -1451,8 +1745,10 @@ contains $:GPU_LOOP(parallelism='[seq]') do q = 1, Re_size(i) - Re_L(i) = alpha_L(Re_idx(i, q))/Res_gs(i, q) + Re_L(i) - Re_R(i) = alpha_R(Re_idx(i, q))/Res_gs(i, q) + Re_R(i) + Re_L(i) = alpha_L(Re_idx(i, q))/Res_gs(i, q) & + + Re_L(i) + Re_R(i) = alpha_R(Re_idx(i, q))/Res_gs(i, q) & + + Re_R(i) end do Re_L(i) = 1._wp/max(Re_L(i), sgm_eps) @@ -1460,244 +1756,231 @@ contains end do if (shear_stress) then + $:GPU_LOOP(parallelism='[seq]') do i = 1, num_dims vel_grad_L(i, 1) = (dqL_prim_dx_vf(momxb + i - 1)%sf(j, k, l)/Re_L(1)) - vel_grad_R(i, 1) = (dqR_prim_dx_vf(momxb + i - 1)%sf(idx_right_phys(1), idx_right_phys(2), & - & idx_right_phys(3))/Re_R(1)) + vel_grad_R(i, 1) = (dqR_prim_dx_vf(momxb + i - 1)%sf(idx_right_phys(1), idx_right_phys(2), idx_right_phys(3))/Re_R(1)) #:if not MFC_CASE_OPTIMIZATION or num_dims > 1 if (num_dims > 1) then vel_grad_L(i, 2) = (dqL_prim_dy_vf(momxb + i - 1)%sf(j, k, l)/Re_L(1)) - vel_grad_R(i, 2) = (dqR_prim_dy_vf(momxb + i - 1)%sf(idx_right_phys(1), & - & idx_right_phys(2), idx_right_phys(3))/Re_R(1)) + vel_grad_R(i, 2) = (dqR_prim_dy_vf(momxb + i - 1)%sf(idx_right_phys(1), idx_right_phys(2), idx_right_phys(3))/Re_R(1)) end if #:if not MFC_CASE_OPTIMIZATION or num_dims > 2 if (num_dims > 2) then vel_grad_L(i, 3) = (dqL_prim_dz_vf(momxb + i - 1)%sf(j, k, l)/Re_L(1)) - vel_grad_R(i, 3) = (dqR_prim_dz_vf(momxb + i - 1)%sf(idx_right_phys(1), & - & idx_right_phys(2), idx_right_phys(3))/Re_R(1)) + vel_grad_R(i, 3) = (dqR_prim_dz_vf(momxb + i - 1)%sf(idx_right_phys(1), idx_right_phys(2), idx_right_phys(3))/Re_R(1)) end if #:endif #:endif end do if (norm_dir == 1) then - flux_src_vf(momxb)%sf(j, k, l) = flux_src_vf(momxb)%sf(j, k, & - & l) - (4._wp/3._wp)*0.5_wp*(vel_grad_L(1, 1) + vel_grad_R(1, 1)) - flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, & - & l) - (4._wp/3._wp)*0.5_wp*(vel_grad_L(1, 1)*vel_L(1) + vel_grad_R(1, 1)*vel_R(1)) + flux_src_vf(momxb)%sf(j, k, l) = flux_src_vf(momxb)%sf(j, k, l) - (4._wp/3._wp)*0.5_wp*(vel_grad_L(1, 1) + vel_grad_R(1, 1)) + flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, l) - (4._wp/3._wp)*0.5_wp*(vel_grad_L(1, 1)*vel_L(1) + vel_grad_R(1, 1)*vel_R(1)) #:if not MFC_CASE_OPTIMIZATION or num_dims > 1 if (num_dims > 1) then - flux_src_vf(momxb)%sf(j, k, l) = flux_src_vf(momxb)%sf(j, k, & - & l) - (-2._wp/3._wp)*0.5_wp*(vel_grad_L(2, 2) + vel_grad_R(2, 2)) - flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, & - & l) - (-2._wp/3._wp)*0.5_wp*(vel_grad_L(2, 2)*vel_L(1) + vel_grad_R(2, & - & 2)*vel_R(1)) - - flux_src_vf(momxb + 1)%sf(j, k, l) = flux_src_vf(momxb + 1)%sf(j, k, & - & l) - 0.5_wp*(vel_grad_L(1, 2) + vel_grad_R(1, 2)) - 0.5_wp*(vel_grad_L(2, & - & 1) + vel_grad_R(2, 1)) - flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, l) - 0.5_wp*(vel_grad_L(1, & - & 2)*vel_L(2) + vel_grad_R(1, 2)*vel_R(2)) - 0.5_wp*(vel_grad_L(2, & - & 1)*vel_L(2) + vel_grad_R(2, 1)*vel_R(2)) + flux_src_vf(momxb)%sf(j, k, l) = flux_src_vf(momxb)%sf(j, k, l) - (-2._wp/3._wp)*0.5_wp*(vel_grad_L(2, 2) + vel_grad_R(2, 2)) + flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, l) - (-2._wp/3._wp)*0.5_wp*(vel_grad_L(2, 2)*vel_L(1) + vel_grad_R(2, 2)*vel_R(1)) + + flux_src_vf(momxb + 1)%sf(j, k, l) = flux_src_vf(momxb + 1)%sf(j, k, l) - 0.5_wp*(vel_grad_L(1, 2) + vel_grad_R(1, 2)) - 0.5_wp*(vel_grad_L(2, 1) + vel_grad_R(2, 1)) + flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, l) - 0.5_wp*(vel_grad_L(1, 2)*vel_L(2) + vel_grad_R(1, 2)*vel_R(2)) - 0.5_wp*(vel_grad_L(2, 1)*vel_L(2) + vel_grad_R(2, 1)*vel_R(2)) #:if not MFC_CASE_OPTIMIZATION or num_dims > 2 if (num_dims > 2) then - flux_src_vf(momxb)%sf(j, k, l) = flux_src_vf(momxb)%sf(j, k, & - & l) - (-2._wp/3._wp)*0.5_wp*(vel_grad_L(3, 3) + vel_grad_R(3, 3)) - flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, & - & l) - (-2._wp/3._wp)*0.5_wp*(vel_grad_L(3, & - & 3)*vel_L(1) + vel_grad_R(3, 3)*vel_R(1)) - - flux_src_vf(momxb + 2)%sf(j, k, l) = flux_src_vf(momxb + 2)%sf(j, k, & - & l) - 0.5_wp*(vel_grad_L(1, 3) + vel_grad_R(1, & - & 3)) - 0.5_wp*(vel_grad_L(3, 1) + vel_grad_R(3, 1)) - flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, & - & l) - 0.5_wp*(vel_grad_L(1, 3)*vel_L(3) + vel_grad_R(1, & - & 3)*vel_R(3)) - 0.5_wp*(vel_grad_L(3, 1)*vel_L(3) + vel_grad_R(3, & - & 1)*vel_R(3)) + flux_src_vf(momxb)%sf(j, k, l) = flux_src_vf(momxb)%sf(j, k, l) - (-2._wp/3._wp)*0.5_wp*(vel_grad_L(3, 3) + vel_grad_R(3, 3)) + flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, l) - (-2._wp/3._wp)*0.5_wp*(vel_grad_L(3, 3)*vel_L(1) + vel_grad_R(3, 3)*vel_R(1)) + + flux_src_vf(momxb + 2)%sf(j, k, l) = flux_src_vf(momxb + 2)%sf(j, k, l) - 0.5_wp*(vel_grad_L(1, 3) + vel_grad_R(1, 3)) - 0.5_wp*(vel_grad_L(3, 1) + vel_grad_R(3, 1)) + flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, l) - 0.5_wp*(vel_grad_L(1, 3)*vel_L(3) + vel_grad_R(1, 3)*vel_R(3)) - 0.5_wp*(vel_grad_L(3, 1)*vel_L(3) + vel_grad_R(3, 1)*vel_R(3)) end if #:endif end if #:endif + else if (norm_dir == 2) then #:if not MFC_CASE_OPTIMIZATION or num_dims > 1 - flux_src_vf(momxb + 1)%sf(j, k, l) = flux_src_vf(momxb + 1)%sf(j, k, & - & l) - (-2._wp/3._wp)*0.5_wp*(vel_grad_L(1, 1) + vel_grad_R(1, 1)) - flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, & - & l) - (-2._wp/3._wp)*0.5_wp*(vel_grad_L(1, 1)*vel_L(2) + vel_grad_R(1, 1)*vel_R(2)) - - flux_src_vf(momxb + 1)%sf(j, k, l) = flux_src_vf(momxb + 1)%sf(j, k, & - & l) - (4._wp/3._wp)*0.5_wp*(vel_grad_L(2, 2) + vel_grad_R(2, 2)) - flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, & - & l) - (4._wp/3._wp)*0.5_wp*(vel_grad_L(2, 2)*vel_L(2) + vel_grad_R(2, 2)*vel_R(2)) - - flux_src_vf(momxb)%sf(j, k, l) = flux_src_vf(momxb)%sf(j, k, l) - 0.5_wp*(vel_grad_L(1, & - & 2) + vel_grad_R(1, 2)) - 0.5_wp*(vel_grad_L(2, 1) + vel_grad_R(2, 1)) - flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, l) - 0.5_wp*(vel_grad_L(1, & - & 2)*vel_L(1) + vel_grad_R(1, 2)*vel_R(1)) - 0.5_wp*(vel_grad_L(2, & - & 1)*vel_L(1) + vel_grad_R(2, 1)*vel_R(1)) + flux_src_vf(momxb + 1)%sf(j, k, l) = flux_src_vf(momxb + 1)%sf(j, k, l) - (-2._wp/3._wp)*0.5_wp*(vel_grad_L(1, 1) + vel_grad_R(1, 1)) + flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, l) - (-2._wp/3._wp)*0.5_wp*(vel_grad_L(1, 1)*vel_L(2) + vel_grad_R(1, 1)*vel_R(2)) + + flux_src_vf(momxb + 1)%sf(j, k, l) = flux_src_vf(momxb + 1)%sf(j, k, l) - (4._wp/3._wp)*0.5_wp*(vel_grad_L(2, 2) + vel_grad_R(2, 2)) + flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, l) - (4._wp/3._wp)*0.5_wp*(vel_grad_L(2, 2)*vel_L(2) + vel_grad_R(2, 2)*vel_R(2)) + + flux_src_vf(momxb)%sf(j, k, l) = flux_src_vf(momxb)%sf(j, k, l) - 0.5_wp*(vel_grad_L(1, 2) + vel_grad_R(1, 2)) - 0.5_wp*(vel_grad_L(2, 1) + vel_grad_R(2, 1)) + flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, l) - 0.5_wp*(vel_grad_L(1, 2)*vel_L(1) + vel_grad_R(1, 2)*vel_R(1)) - 0.5_wp*(vel_grad_L(2, 1)*vel_L(1) + vel_grad_R(2, 1)*vel_R(1)) #:if not MFC_CASE_OPTIMIZATION or num_dims > 2 if (num_dims > 2) then - flux_src_vf(momxb + 1)%sf(j, k, l) = flux_src_vf(momxb + 1)%sf(j, k, & - & l) - (-2._wp/3._wp)*0.5_wp*(vel_grad_L(3, 3) + vel_grad_R(3, 3)) - flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, & - & l) - (-2._wp/3._wp)*0.5_wp*(vel_grad_L(3, 3)*vel_L(2) + vel_grad_R(3, & - & 3)*vel_R(2)) - - flux_src_vf(momxb + 2)%sf(j, k, l) = flux_src_vf(momxb + 2)%sf(j, k, & - & l) - 0.5_wp*(vel_grad_L(2, 3) + vel_grad_R(2, & - & 3)) - 0.5_wp*(vel_grad_L(3, 2) + vel_grad_R(3, 2)) - flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, & - & l) - 0.5_wp*(vel_grad_L(2, 3)*vel_L(3) + vel_grad_R(2, & - & 3)*vel_R(3)) - 0.5_wp*(vel_grad_L(3, 2)*vel_L(3) + vel_grad_R(3, & - & 2)*vel_R(3)) + flux_src_vf(momxb + 1)%sf(j, k, l) = flux_src_vf(momxb + 1)%sf(j, k, l) - (-2._wp/3._wp)*0.5_wp*(vel_grad_L(3, 3) + vel_grad_R(3, 3)) + flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, l) - (-2._wp/3._wp)*0.5_wp*(vel_grad_L(3, 3)*vel_L(2) + vel_grad_R(3, 3)*vel_R(2)) + + flux_src_vf(momxb + 2)%sf(j, k, l) = flux_src_vf(momxb + 2)%sf(j, k, l) - 0.5_wp*(vel_grad_L(2, 3) + vel_grad_R(2, 3)) - 0.5_wp*(vel_grad_L(3, 2) + vel_grad_R(3, 2)) + flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, l) - 0.5_wp*(vel_grad_L(2, 3)*vel_L(3) + vel_grad_R(2, 3)*vel_R(3)) - 0.5_wp*(vel_grad_L(3, 2)*vel_L(3) + vel_grad_R(3, 2)*vel_R(3)) end if #:endif #:endif else #:if not MFC_CASE_OPTIMIZATION or num_dims > 2 - flux_src_vf(momxb + 2)%sf(j, k, l) = flux_src_vf(momxb + 2)%sf(j, k, & - & l) - (-2._wp/3._wp)*0.5_wp*(vel_grad_L(1, 1) + vel_grad_R(1, 1)) - flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, & - & l) - (-2._wp/3._wp)*0.5_wp*(vel_grad_L(1, 1)*vel_L(3) + vel_grad_R(1, 1)*vel_R(3)) - - flux_src_vf(momxb + 2)%sf(j, k, l) = flux_src_vf(momxb + 2)%sf(j, k, & - & l) - (-2._wp/3._wp)*0.5_wp*(vel_grad_L(2, 2) + vel_grad_R(2, 2)) - flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, & - & l) - (-2._wp/3._wp)*0.5_wp*(vel_grad_L(2, 2)*vel_L(3) + vel_grad_R(2, 2)*vel_R(3)) - - flux_src_vf(momxb)%sf(j, k, l) = flux_src_vf(momxb)%sf(j, k, l) - 0.5_wp*(vel_grad_L(1, & - & 3) + vel_grad_R(1, 3)) - 0.5_wp*(vel_grad_L(3, 1) + vel_grad_R(3, 1)) - flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, l) - 0.5_wp*(vel_grad_L(1, & - & 3)*vel_L(1) + vel_grad_R(1, 3)*vel_R(1)) - 0.5_wp*(vel_grad_L(3, & - & 1)*vel_L(1) + vel_grad_R(3, 1)*vel_R(1)) - - flux_src_vf(momxb + 2)%sf(j, k, l) = flux_src_vf(momxb + 2)%sf(j, k, & - & l) - (4._wp/3._wp)*0.5_wp*(vel_grad_L(3, 3) + vel_grad_R(3, 3)) - flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, & - & l) - (4._wp/3._wp)*0.5_wp*(vel_grad_L(3, 3)*vel_L(3) + vel_grad_R(3, 3)*vel_R(3)) - - flux_src_vf(momxb + 1)%sf(j, k, l) = flux_src_vf(momxb + 1)%sf(j, k, & - & l) - 0.5_wp*(vel_grad_L(2, 3) + vel_grad_R(2, 3)) - 0.5_wp*(vel_grad_L(3, & - & 2) + vel_grad_R(3, 2)) - flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, l) - 0.5_wp*(vel_grad_L(2, & - & 3)*vel_L(2) + vel_grad_R(2, 3)*vel_R(2)) - 0.5_wp*(vel_grad_L(3, & - & 2)*vel_L(2) + vel_grad_R(3, 2)*vel_R(2)) + flux_src_vf(momxb + 2)%sf(j, k, l) = flux_src_vf(momxb + 2)%sf(j, k, l) - (-2._wp/3._wp)*0.5_wp*(vel_grad_L(1, 1) + vel_grad_R(1, 1)) + flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, l) - (-2._wp/3._wp)*0.5_wp*(vel_grad_L(1, 1)*vel_L(3) + vel_grad_R(1, 1)*vel_R(3)) + + flux_src_vf(momxb + 2)%sf(j, k, l) = flux_src_vf(momxb + 2)%sf(j, k, l) - (-2._wp/3._wp)*0.5_wp*(vel_grad_L(2, 2) + vel_grad_R(2, 2)) + flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, l) - (-2._wp/3._wp)*0.5_wp*(vel_grad_L(2, 2)*vel_L(3) + vel_grad_R(2, 2)*vel_R(3)) + + flux_src_vf(momxb)%sf(j, k, l) = flux_src_vf(momxb)%sf(j, k, l) - 0.5_wp*(vel_grad_L(1, 3) + vel_grad_R(1, 3)) - 0.5_wp*(vel_grad_L(3, 1) + vel_grad_R(3, 1)) + flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, l) - 0.5_wp*(vel_grad_L(1, 3)*vel_L(1) + vel_grad_R(1, 3)*vel_R(1)) - 0.5_wp*(vel_grad_L(3, 1)*vel_L(1) + vel_grad_R(3, 1)*vel_R(1)) + + flux_src_vf(momxb + 2)%sf(j, k, l) = flux_src_vf(momxb + 2)%sf(j, k, l) - (4._wp/3._wp)*0.5_wp*(vel_grad_L(3, 3) + vel_grad_R(3, 3)) + flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, l) - (4._wp/3._wp)*0.5_wp*(vel_grad_L(3, 3)*vel_L(3) + vel_grad_R(3, 3)*vel_R(3)) + + flux_src_vf(momxb + 1)%sf(j, k, l) = flux_src_vf(momxb + 1)%sf(j, k, l) - 0.5_wp*(vel_grad_L(2, 3) + vel_grad_R(2, 3)) - 0.5_wp*(vel_grad_L(3, 2) + vel_grad_R(3, 2)) + flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, l) - 0.5_wp*(vel_grad_L(2, 3)*vel_L(2) + vel_grad_R(2, 3)*vel_R(2)) - 0.5_wp*(vel_grad_L(3, 2)*vel_L(2) + vel_grad_R(3, 2)*vel_R(2)) #:endif end if end if if (bulk_stress) then + $:GPU_LOOP(parallelism='[seq]') do i = 1, num_dims vel_grad_L(i, 1) = (dqL_prim_dx_vf(momxb + i - 1)%sf(j, k, l)/Re_L(2)) - vel_grad_R(i, 1) = (dqR_prim_dx_vf(momxb + i - 1)%sf(idx_right_phys(1), idx_right_phys(2), & - & idx_right_phys(3))/Re_R(2)) + vel_grad_R(i, 1) = (dqR_prim_dx_vf(momxb + i - 1)%sf(idx_right_phys(1), idx_right_phys(2), idx_right_phys(3))/Re_R(2)) #:if not MFC_CASE_OPTIMIZATION or num_dims > 1 if (num_dims > 1) then vel_grad_L(i, 2) = (dqL_prim_dy_vf(momxb + i - 1)%sf(j, k, l)/Re_L(2)) - vel_grad_R(i, 2) = (dqR_prim_dy_vf(momxb + i - 1)%sf(idx_right_phys(1), & - & idx_right_phys(2), idx_right_phys(3))/Re_R(2)) + vel_grad_R(i, 2) = (dqR_prim_dy_vf(momxb + i - 1)%sf(idx_right_phys(1), idx_right_phys(2), idx_right_phys(3))/Re_R(2)) end if #:endif #:if not MFC_CASE_OPTIMIZATION or num_dims > 2 if (num_dims > 2) then vel_grad_L(i, 3) = (dqL_prim_dz_vf(momxb + i - 1)%sf(j, k, l)/Re_L(2)) - vel_grad_R(i, 3) = (dqR_prim_dz_vf(momxb + i - 1)%sf(idx_right_phys(1), & - & idx_right_phys(2), idx_right_phys(3))/Re_R(2)) + vel_grad_R(i, 3) = (dqR_prim_dz_vf(momxb + i - 1)%sf(idx_right_phys(1), idx_right_phys(2), idx_right_phys(3))/Re_R(2)) end if #:endif end do if (norm_dir == 1) then - flux_src_vf(momxb)%sf(j, k, l) = flux_src_vf(momxb)%sf(j, k, l) - 0.5_wp*(vel_grad_L(1, & - & 1) + vel_grad_R(1, 1)) - flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, l) - 0.5_wp*(vel_grad_L(1, & - & 1)*vel_L(1) + vel_grad_R(1, 1)*vel_R(1)) + flux_src_vf(momxb)%sf(j, k, l) = flux_src_vf(momxb)%sf(j, k, l) - 0.5_wp*(vel_grad_L(1, 1) + vel_grad_R(1, 1)) + flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, l) - 0.5_wp*(vel_grad_L(1, 1)*vel_L(1) + vel_grad_R(1, 1)*vel_R(1)) #:if not MFC_CASE_OPTIMIZATION or num_dims > 1 if (num_dims > 1) then - flux_src_vf(momxb)%sf(j, k, l) = flux_src_vf(momxb)%sf(j, k, l) - 0.5_wp*(vel_grad_L(2, & - & 2) + vel_grad_R(2, 2)) - flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, l) - 0.5_wp*(vel_grad_L(2, & - & 2)*vel_L(1) + vel_grad_R(2, 2)*vel_R(1)) + flux_src_vf(momxb)%sf(j, k, l) = flux_src_vf(momxb)%sf(j, k, l) - 0.5_wp*(vel_grad_L(2, 2) + vel_grad_R(2, 2)) + flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, l) - 0.5_wp*(vel_grad_L(2, 2)*vel_L(1) + vel_grad_R(2, 2)*vel_R(1)) #:if not MFC_CASE_OPTIMIZATION or num_dims > 2 if (num_dims > 2) then - flux_src_vf(momxb)%sf(j, k, l) = flux_src_vf(momxb)%sf(j, k, & - & l) - 0.5_wp*(vel_grad_L(3, 3) + vel_grad_R(3, 3)) - flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, & - & l) - 0.5_wp*(vel_grad_L(3, 3)*vel_L(1) + vel_grad_R(3, 3)*vel_R(1)) + flux_src_vf(momxb)%sf(j, k, l) = flux_src_vf(momxb)%sf(j, k, l) - 0.5_wp*(vel_grad_L(3, 3) + vel_grad_R(3, 3)) + flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, l) - 0.5_wp*(vel_grad_L(3, 3)*vel_L(1) + vel_grad_R(3, 3)*vel_R(1)) end if #:endif end if #:endif + else if (norm_dir == 2) then #:if not MFC_CASE_OPTIMIZATION or num_dims > 1 - flux_src_vf(momxb + 1)%sf(j, k, l) = flux_src_vf(momxb + 1)%sf(j, k, & - & l) - 0.5_wp*(vel_grad_L(1, 1) + vel_grad_R(1, 1)) - flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, l) - 0.5_wp*(vel_grad_L(1, & - & 1)*vel_L(2) + vel_grad_R(1, 1)*vel_R(2)) + flux_src_vf(momxb + 1)%sf(j, k, l) = flux_src_vf(momxb + 1)%sf(j, k, l) - 0.5_wp*(vel_grad_L(1, 1) + vel_grad_R(1, 1)) + flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, l) - 0.5_wp*(vel_grad_L(1, 1)*vel_L(2) + vel_grad_R(1, 1)*vel_R(2)) - flux_src_vf(momxb + 1)%sf(j, k, l) = flux_src_vf(momxb + 1)%sf(j, k, & - & l) - 0.5_wp*(vel_grad_L(2, 2) + vel_grad_R(2, 2)) - flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, l) - 0.5_wp*(vel_grad_L(2, & - & 2)*vel_L(2) + vel_grad_R(2, 2)*vel_R(2)) + flux_src_vf(momxb + 1)%sf(j, k, l) = flux_src_vf(momxb + 1)%sf(j, k, l) - 0.5_wp*(vel_grad_L(2, 2) + vel_grad_R(2, 2)) + flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, l) - 0.5_wp*(vel_grad_L(2, 2)*vel_L(2) + vel_grad_R(2, 2)*vel_R(2)) #:if not MFC_CASE_OPTIMIZATION or num_dims > 2 if (num_dims > 2) then - flux_src_vf(momxb + 1)%sf(j, k, l) = flux_src_vf(momxb + 1)%sf(j, k, & - & l) - 0.5_wp*(vel_grad_L(3, 3) + vel_grad_R(3, 3)) - flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, & - & l) - 0.5_wp*(vel_grad_L(3, 3)*vel_L(2) + vel_grad_R(3, 3)*vel_R(2)) + flux_src_vf(momxb + 1)%sf(j, k, l) = flux_src_vf(momxb + 1)%sf(j, k, l) - 0.5_wp*(vel_grad_L(3, 3) + vel_grad_R(3, 3)) + flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, l) - 0.5_wp*(vel_grad_L(3, 3)*vel_L(2) + vel_grad_R(3, 3)*vel_R(2)) end if #:endif #:endif else #:if not MFC_CASE_OPTIMIZATION or num_dims > 2 - flux_src_vf(momxb + 2)%sf(j, k, l) = flux_src_vf(momxb + 2)%sf(j, k, & - & l) - 0.5_wp*(vel_grad_L(1, 1) + vel_grad_R(1, 1)) - flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, l) - 0.5_wp*(vel_grad_L(1, & - & 1)*vel_L(3) + vel_grad_R(1, 1)*vel_R(3)) - - flux_src_vf(momxb + 2)%sf(j, k, l) = flux_src_vf(momxb + 2)%sf(j, k, & - & l) - 0.5_wp*(vel_grad_L(2, 2) + vel_grad_R(2, 2)) - flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, l) - 0.5_wp*(vel_grad_L(2, & - & 2)*vel_L(3) + vel_grad_R(2, 2)*vel_R(3)) - - flux_src_vf(momxb + 2)%sf(j, k, l) = flux_src_vf(momxb + 2)%sf(j, k, & - & l) - 0.5_wp*(vel_grad_L(3, 3) + vel_grad_R(3, 3)) - flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, l) - 0.5_wp*(vel_grad_L(3, & - & 3)*vel_L(3) + vel_grad_R(3, 3)*vel_R(3)) + flux_src_vf(momxb + 2)%sf(j, k, l) = flux_src_vf(momxb + 2)%sf(j, k, l) - 0.5_wp*(vel_grad_L(1, 1) + vel_grad_R(1, 1)) + flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, l) - 0.5_wp*(vel_grad_L(1, 1)*vel_L(3) + vel_grad_R(1, 1)*vel_R(3)) + + flux_src_vf(momxb + 2)%sf(j, k, l) = flux_src_vf(momxb + 2)%sf(j, k, l) - 0.5_wp*(vel_grad_L(2, 2) + vel_grad_R(2, 2)) + flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, l) - 0.5_wp*(vel_grad_L(2, 2)*vel_L(3) + vel_grad_R(2, 2)*vel_R(3)) + + flux_src_vf(momxb + 2)%sf(j, k, l) = flux_src_vf(momxb + 2)%sf(j, k, l) - 0.5_wp*(vel_grad_L(3, 3) + vel_grad_R(3, 3)) + flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, l) - 0.5_wp*(vel_grad_L(3, 3)*vel_L(3) + vel_grad_R(3, 3)*vel_R(3)) #:endif end if + end if end do end do end do $:END_GPU_PARALLEL_LOOP() + end if - call s_finalize_riemann_solver(flux_vf, flux_src_vf, flux_gsrc_vf, norm_dir) + call s_finalize_riemann_solver(flux_vf, flux_src_vf, & + flux_gsrc_vf, & + norm_dir) end subroutine s_lf_riemann_solver - !> HLLC Riemann solver with contact restoration, Toro et al. Shock Waves (1994) - subroutine s_hllc_riemann_solver(qL_prim_rsx_vf, qL_prim_rsy_vf, qL_prim_rsz_vf, dqL_prim_dx_vf, dqL_prim_dy_vf, & - - & dqL_prim_dz_vf, qL_prim_vf, qR_prim_rsx_vf, qR_prim_rsy_vf, qR_prim_rsz_vf, dqR_prim_dx_vf, dqR_prim_dy_vf, & - & dqR_prim_dz_vf, qR_prim_vf, q_prim_vf, flux_vf, flux_src_vf, flux_gsrc_vf, norm_dir, ix, iy, iz) - - real(wp), dimension(idwbuff(1)%beg:,idwbuff(2)%beg:,idwbuff(3)%beg:,1:), intent(inout) :: qL_prim_rsx_vf, qL_prim_rsy_vf, & - & qL_prim_rsz_vf, qR_prim_rsx_vf, qR_prim_rsy_vf, qR_prim_rsz_vf - type(scalar_field), dimension(sys_size), intent(in) :: q_prim_vf + !> This procedure is the implementation of the Harten, Lax, + !! van Leer, and contact (HLLC) approximate Riemann solver, + !! see Toro (1999) and Johnsen (2007). The viscous and the + !! surface tension effects have been included by modifying + !! the exact Riemann solver of Perigaud and Saurel (2005). + !! @param qL_prim_rsx_vf Left WENO-reconstructed cell-boundary values (x-dir) + !! @param qL_prim_rsy_vf Left WENO-reconstructed cell-boundary values (y-dir) + !! @param qL_prim_rsz_vf Left WENO-reconstructed cell-boundary values (z-dir) + !! @param dqL_prim_dx_vf The left WENO-reconstructed cell-boundary values of the + !! first-order x-dir spatial derivatives + !! @param dqL_prim_dy_vf The left WENO-reconstructed cell-boundary values of the + !! first-order y-dir spatial derivatives + !! @param dqL_prim_dz_vf The left WENO-reconstructed cell-boundary values of the + !! first-order z-dir spatial derivatives + !! @param qL_prim_vf The left WENO-reconstructed cell-boundary values of the + !! cell-average primitive variables + !! @param qR_prim_rsx_vf Right WENO-reconstructed cell-boundary values (x-dir) + !! @param qR_prim_rsy_vf Right WENO-reconstructed cell-boundary values (y-dir) + !! @param qR_prim_rsz_vf Right WENO-reconstructed cell-boundary values (z-dir) + !! @param dqR_prim_dx_vf The right WENO-reconstructed cell-boundary values of the + !! first-order x-dir spatial derivatives + !! @param dqR_prim_dy_vf The right WENO-reconstructed cell-boundary values of the + !! first-order y-dir spatial derivatives + !! @param dqR_prim_dz_vf The right WENO-reconstructed cell-boundary values of the + !! first-order z-dir spatial derivatives + !! @param qR_prim_vf The right WENO-reconstructed cell-boundary values of the + !! cell-average primitive variables + !! @param q_prim_vf Cell-averaged primitive variables + !! @param flux_vf Intra-cell fluxes + !! @param flux_src_vf Intra-cell fluxes sources + !! @param flux_gsrc_vf Intra-cell geometric fluxes sources + !! @param norm_dir Dir. splitting direction + !! @param ix Index bounds in the x-dir + !! @param iy Index bounds in the y-dir + !! @param iz Index bounds in the z-dir + subroutine s_hllc_riemann_solver(qL_prim_rsx_vf, qL_prim_rsy_vf, qL_prim_rsz_vf, dqL_prim_dx_vf, & + dqL_prim_dy_vf, & + dqL_prim_dz_vf, & + qL_prim_vf, & + qR_prim_rsx_vf, qR_prim_rsy_vf, qR_prim_rsz_vf, dqR_prim_dx_vf, & + dqR_prim_dy_vf, & + dqR_prim_dz_vf, & + qR_prim_vf, & + q_prim_vf, & + flux_vf, flux_src_vf, & + flux_gsrc_vf, & + norm_dir, ix, iy, iz) + + real(wp), dimension(idwbuff(1)%beg:, idwbuff(2)%beg:, idwbuff(3)%beg:, 1:), intent(inout) :: qL_prim_rsx_vf, qL_prim_rsy_vf, qL_prim_rsz_vf, qR_prim_rsx_vf, qR_prim_rsy_vf, qR_prim_rsz_vf + type(scalar_field), dimension(sys_size), intent(in) :: q_prim_vf type(scalar_field), allocatable, dimension(:), intent(inout) :: qL_prim_vf, qR_prim_vf - type(scalar_field), allocatable, dimension(:), intent(inout) :: dqL_prim_dx_vf, dqR_prim_dx_vf, dqL_prim_dy_vf, & - & dqR_prim_dy_vf, dqL_prim_dz_vf, dqR_prim_dz_vf + + type(scalar_field), & + allocatable, dimension(:), & + intent(inout) :: dqL_prim_dx_vf, dqR_prim_dx_vf, & + dqL_prim_dy_vf, dqR_prim_dy_vf, & + dqL_prim_dz_vf, dqR_prim_dz_vf ! Intercell fluxes - type(scalar_field), dimension(sys_size), intent(inout) :: flux_vf, flux_src_vf, flux_gsrc_vf - integer, intent(in) :: norm_dir - type(int_bounds_info), intent(in) :: ix, iy, iz + type(scalar_field), & + dimension(sys_size), & + intent(inout) :: flux_vf, flux_src_vf, flux_gsrc_vf + + integer, intent(in) :: norm_dir + type(int_bounds_info), intent(in) :: ix, iy, iz #:if not MFC_CASE_OPTIMIZATION and USING_AMD real(wp), dimension(3) :: alpha_rho_L, alpha_rho_R @@ -1706,7 +1989,7 @@ contains #:else real(wp), dimension(num_fluids) :: alpha_rho_L, alpha_rho_R real(wp), dimension(num_fluids) :: alpha_L, alpha_R - real(wp), dimension(num_dims) :: vel_L, vel_R + real(wp), dimension(num_dims) :: vel_L, vel_R #:endif real(wp) :: rho_L, rho_R @@ -1720,28 +2003,30 @@ contains real(wp), dimension(num_species) :: Ys_L, Ys_R, Xs_L, Xs_R, Gamma_iL, Gamma_iR, Cp_iL, Cp_iR real(wp), dimension(num_species) :: Yi_avg, Phi_avg, h_iL, h_iR, h_avg_2 #:endif - real(wp) :: Cp_avg, Cv_avg, T_avg, c_sum_Yi_Phi, eps - real(wp) :: T_L, T_R - real(wp) :: MW_L, MW_R - real(wp) :: R_gas_L, R_gas_R - real(wp) :: Cp_L, Cp_R - real(wp) :: Cv_L, Cv_R - real(wp) :: Gamm_L, Gamm_R - real(wp) :: Y_L, Y_R - real(wp) :: gamma_L, gamma_R - real(wp) :: pi_inf_L, pi_inf_R - real(wp) :: qv_L, qv_R - real(wp) :: c_L, c_R + real(wp) :: Cp_avg, Cv_avg, T_avg, c_sum_Yi_Phi, eps + real(wp) :: T_L, T_R + real(wp) :: MW_L, MW_R + real(wp) :: R_gas_L, R_gas_R + real(wp) :: Cp_L, Cp_R + real(wp) :: Cv_L, Cv_R + real(wp) :: Gamm_L, Gamm_R + real(wp) :: Y_L, Y_R + real(wp) :: gamma_L, gamma_R + real(wp) :: pi_inf_L, pi_inf_R + real(wp) :: qv_L, qv_R + real(wp) :: c_L, c_R real(wp), dimension(2) :: Re_L, Re_R - real(wp) :: rho_avg - real(wp) :: H_avg - real(wp) :: gamma_avg - real(wp) :: qv_avg - real(wp) :: c_avg - real(wp) :: s_L, s_R, s_M, s_P, s_S - real(wp) :: xi_L, xi_R !< Left and right wave speeds functions - real(wp) :: xi_M, xi_P - real(wp) :: xi_MP, xi_PP + + real(wp) :: rho_avg + real(wp) :: H_avg + real(wp) :: gamma_avg + real(wp) :: qv_avg + real(wp) :: c_avg + + real(wp) :: s_L, s_R, s_M, s_P, s_S + real(wp) :: xi_L, xi_R !< Left and right wave speeds functions + real(wp) :: xi_M, xi_P + real(wp) :: xi_MP, xi_PP #:if not MFC_CASE_OPTIMIZATION and USING_AMD real(wp), dimension(3) :: R0_L, R0_R real(wp), dimension(3) :: V0_L, V0_R @@ -1754,11 +2039,13 @@ contains real(wp), dimension(nb) :: pbw_L, pbw_R #:endif - real(wp) :: alpha_L_sum, alpha_R_sum, nbub_L, nbub_R - real(wp) :: ptilde_L, ptilde_R - real(wp) :: PbwR3Lbar, PbwR3Rbar - real(wp) :: R3Lbar, R3Rbar - real(wp) :: R3V2Lbar, R3V2Rbar + real(wp) :: alpha_L_sum, alpha_R_sum, nbub_L, nbub_R + real(wp) :: ptilde_L, ptilde_R + + real(wp) :: PbwR3Lbar, PbwR3Rbar + real(wp) :: R3Lbar, R3Rbar + real(wp) :: R3V2Lbar, R3V2Rbar + real(wp), dimension(6) :: tau_e_L, tau_e_R #:if not MFC_CASE_OPTIMIZATION and USING_AMD real(wp), dimension(3) :: xi_field_L, xi_field_R @@ -1766,41 +2053,46 @@ contains real(wp), dimension(num_dims) :: xi_field_L, xi_field_R #:endif real(wp) :: G_L, G_R + real(wp) :: vel_L_rms, vel_R_rms, vel_avg_rms real(wp) :: vel_L_tmp, vel_R_tmp real(wp) :: rho_Star, E_Star, p_Star, p_K_Star, vel_K_star real(wp) :: pres_SL, pres_SR, Ms_L, Ms_R real(wp) :: flux_ene_e - real(wp) :: zcoef, pcorr !< low Mach number correction - integer :: Re_max, i, j, k, l, q !< Generic loop iterators - ! Populating the buffers of the left and right Riemann problem states variables, based on the choice of boundary conditions + real(wp) :: zcoef, pcorr !< low Mach number correction - call s_populate_riemann_states_variables_buffers(qL_prim_rsx_vf, qL_prim_rsy_vf, qL_prim_rsz_vf, dqL_prim_dx_vf, & - & dqL_prim_dy_vf, dqL_prim_dz_vf, qR_prim_rsx_vf, qR_prim_rsy_vf, qR_prim_rsz_vf, dqR_prim_dx_vf, dqR_prim_dy_vf, & - & dqR_prim_dz_vf, norm_dir, ix, iy, iz) + integer :: Re_max, i, j, k, l, q !< Generic loop iterators + + ! Populating the buffers of the left and right Riemann problem + ! states variables, based on the choice of boundary conditions + + call s_populate_riemann_states_variables_buffers( & + qL_prim_rsx_vf, qL_prim_rsy_vf, qL_prim_rsz_vf, dqL_prim_dx_vf, & + dqL_prim_dy_vf, & + dqL_prim_dz_vf, & + qR_prim_rsx_vf, qR_prim_rsy_vf, qR_prim_rsz_vf, dqR_prim_dx_vf, & + dqR_prim_dy_vf, & + dqR_prim_dz_vf, & + norm_dir, ix, iy, iz) ! Reshaping inputted data based on dimensional splitting direction - call s_initialize_riemann_solver(flux_src_vf, norm_dir) + call s_initialize_riemann_solver( & + flux_src_vf, & + norm_dir) #:for NORM_DIR, XYZ in [(1, 'x'), (2, 'y'), (3, 'z')] + if (norm_dir == ${NORM_DIR}$) then - ! 6-EQUATION MODEL WITH HLLC HLLC star-state flux with contact wave speed s_S + + ! 6-EQUATION MODEL WITH HLLC if (model_eqns == 3) then - ! 6-equation model (model_eqns=3): separate phasic internal energies - $:GPU_PARALLEL_LOOP(collapse=3, private='[i, j, k, l, q, vel_L, vel_R, Re_L, Re_R, alpha_L, alpha_R, Ys_L, & - & Ys_R, Xs_L, Xs_R, Gamma_iL, Gamma_iR, Cp_iL, Cp_iR, Yi_avg, Phi_avg, h_iL, h_iR, & - & h_avg_2, tau_e_L, tau_e_R, flux_ene_e, xi_field_L, xi_field_R, pcorr, zcoef, rho_L, & - & rho_R, pres_L, pres_R, E_L, E_R, H_L, H_R, Cp_avg, Cv_avg, T_avg, eps, c_sum_Yi_Phi, & - & T_L, T_R, Y_L, Y_R, MW_L, MW_R, R_gas_L, R_gas_R, Cp_L, Cp_R, Cv_L, Cv_R, Gamm_L, & - & Gamm_R, gamma_L, gamma_R, pi_inf_L, pi_inf_R, qv_L, qv_R, qv_avg, c_L, c_R, G_L, G_R, & - & rho_avg, H_avg, c_avg, gamma_avg, ptilde_L, ptilde_R, vel_L_rms, vel_R_rms, & - & vel_avg_rms, vel_L_tmp, vel_R_tmp, Ms_L, Ms_R, pres_SL, pres_SR, alpha_L_sum, & - & alpha_R_sum, rho_Star, E_Star, p_Star, p_K_Star, vel_K_star, s_L, s_R, s_M, s_P, s_S, & - & xi_M, xi_P, xi_L, xi_R, xi_MP, xi_PP]') + !ME3 + $:GPU_PARALLEL_LOOP(collapse=3, private='[i,j,k,l, q, vel_L, vel_R, Re_L, Re_R, alpha_L, alpha_R, Ys_L, Ys_R, Xs_L, Xs_R, Gamma_iL, Gamma_iR, Cp_iL, Cp_iR, Yi_avg, Phi_avg, h_iL, h_iR, h_avg_2, tau_e_L, tau_e_R, flux_ene_e, xi_field_L, xi_field_R, pcorr, zcoef, rho_L, rho_R, pres_L, pres_R, E_L, E_R, H_L, H_R, Cp_avg, Cv_avg, T_avg, eps, c_sum_Yi_Phi, T_L, T_R, Y_L, Y_R, MW_L, MW_R, R_gas_L, R_gas_R, Cp_L, Cp_R, Cv_L, Cv_R, Gamm_L, Gamm_R, gamma_L, gamma_R, pi_inf_L, pi_inf_R, qv_L, qv_R, qv_avg, c_L, c_R, G_L, G_R, rho_avg, H_avg, c_avg, gamma_avg, ptilde_L, ptilde_R, vel_L_rms, vel_R_rms, vel_avg_rms, vel_L_tmp, vel_R_tmp, Ms_L, Ms_R, pres_SL, pres_SR, alpha_L_sum, alpha_R_sum, rho_Star, E_Star, p_Star, p_K_Star, vel_K_star, s_L, s_R, s_M, s_P, s_S, xi_M, xi_P, xi_L, xi_R, xi_MP, xi_PP]') do l = is3%beg, is3%end do k = is2%beg, is2%end do j = is1%beg, is1%end + vel_L_rms = 0._wp; vel_R_rms = 0._wp rho_L = 0._wp; rho_R = 0._wp gamma_L = 0._wp; gamma_R = 0._wp @@ -1836,25 +2128,21 @@ contains $:GPU_LOOP(parallelism='[seq]') do i = 1, num_fluids qL_prim_rs${XYZ}$_vf(j, k, l, i) = max(0._wp, qL_prim_rs${XYZ}$_vf(j, k, l, i)) - qL_prim_rs${XYZ}$_vf(j, k, l, E_idx + i) = min(max(0._wp, qL_prim_rs${XYZ}$_vf(j, k, l, & - & E_idx + i)), 1._wp) + qL_prim_rs${XYZ}$_vf(j, k, l, E_idx + i) = min(max(0._wp, qL_prim_rs${XYZ}$_vf(j, k, l, E_idx + i)), 1._wp) alpha_L_sum = alpha_L_sum + qL_prim_rs${XYZ}$_vf(j, k, l, E_idx + i) end do $:GPU_LOOP(parallelism='[seq]') do i = 1, num_fluids qR_prim_rs${XYZ}$_vf(j + 1, k, l, i) = max(0._wp, qR_prim_rs${XYZ}$_vf(j + 1, k, l, i)) - qR_prim_rs${XYZ}$_vf(j + 1, k, l, E_idx + i) = min(max(0._wp, qR_prim_rs${XYZ}$_vf(j + 1, & - & k, l, E_idx + i)), 1._wp) + qR_prim_rs${XYZ}$_vf(j + 1, k, l, E_idx + i) = min(max(0._wp, qR_prim_rs${XYZ}$_vf(j + 1, k, l, E_idx + i)), 1._wp) alpha_R_sum = alpha_R_sum + qR_prim_rs${XYZ}$_vf(j + 1, k, l, E_idx + i) end do $:GPU_LOOP(parallelism='[seq]') do i = 1, num_fluids - qL_prim_rs${XYZ}$_vf(j, k, l, E_idx + i) = qL_prim_rs${XYZ}$_vf(j, k, l, & - & E_idx + i)/max(alpha_L_sum, sgm_eps) - qR_prim_rs${XYZ}$_vf(j + 1, k, l, E_idx + i) = qR_prim_rs${XYZ}$_vf(j + 1, k, l, & - & E_idx + i)/max(alpha_R_sum, sgm_eps) + qL_prim_rs${XYZ}$_vf(j, k, l, E_idx + i) = qL_prim_rs${XYZ}$_vf(j, k, l, E_idx + i)/max(alpha_L_sum, sgm_eps) + qR_prim_rs${XYZ}$_vf(j + 1, k, l, E_idx + i) = qR_prim_rs${XYZ}$_vf(j + 1, k, l, E_idx + i)/max(alpha_R_sum, sgm_eps) end do end if @@ -1883,8 +2171,10 @@ contains if (Re_size(i) > 0) Re_R(i) = 0._wp $:GPU_LOOP(parallelism='[seq]') do q = 1, Re_size(i) - Re_L(i) = qL_prim_rs${XYZ}$_vf(j, k, l, E_idx + Re_idx(i, q))/Res_gs(i, q) + Re_L(i) - Re_R(i) = qR_prim_rs${XYZ}$_vf(j + 1, k, l, E_idx + Re_idx(i, q))/Res_gs(i, q) + Re_R(i) + Re_L(i) = qL_prim_rs${XYZ}$_vf(j, k, l, E_idx + Re_idx(i, q))/Res_gs(i, q) & + + Re_L(i) + Re_R(i) = qR_prim_rs${XYZ}$_vf(j + 1, k, l, E_idx + Re_idx(i, q))/Res_gs(i, q) & + + Re_R(i) end do Re_L(i) = 1._wp/max(Re_L(i), sgm_eps) Re_R(i) = 1._wp/max(Re_R(i), sgm_eps) @@ -1922,14 +2212,14 @@ contains end do end if - ! Hyperelastic stress contribution: strain energy added to total energy + ! ENERGY ADJUSTMENTS FOR HYPERELASTIC ENERGY if (hyperelasticity) then $:GPU_LOOP(parallelism='[seq]') do i = 1, num_dims xi_field_L(i) = qL_prim_rs${XYZ}$_vf(j, k, l, xibeg - 1 + i) xi_field_R(i) = qR_prim_rs${XYZ}$_vf(j + 1, k, l, xibeg - 1 + i) end do - G_L = 0._wp; G_R = 0._wp + G_L = 0._wp; G_R = 0._wp; $:GPU_LOOP(parallelism='[seq]') do i = 1, num_fluids ! Mixture left and right shear modulus @@ -1953,16 +2243,16 @@ contains @:compute_average_state() - call s_compute_speed_of_sound(pres_L, rho_L, gamma_L, pi_inf_L, H_L, alpha_L, vel_L_rms, 0._wp, & - & c_L, qv_L) + call s_compute_speed_of_sound(pres_L, rho_L, gamma_L, pi_inf_L, H_L, alpha_L, & + vel_L_rms, 0._wp, c_L, qv_L) - call s_compute_speed_of_sound(pres_R, rho_R, gamma_R, pi_inf_R, H_R, alpha_R, vel_R_rms, 0._wp, & - & c_R, qv_R) + call s_compute_speed_of_sound(pres_R, rho_R, gamma_R, pi_inf_R, H_R, alpha_R, & + vel_R_rms, 0._wp, c_R, qv_R) !> The computation of c_avg does not require all the variables, and therefore the non '_avg' ! variables are placeholders to call the subroutine. - call s_compute_speed_of_sound(pres_R, rho_avg, gamma_avg, pi_inf_R, H_avg, alpha_R, vel_avg_rms, & - & 0._wp, c_avg, qv_avg) + call s_compute_speed_of_sound(pres_R, rho_avg, gamma_avg, pi_inf_R, H_avg, alpha_R, & + vel_avg_rms, 0._wp, c_avg, qv_avg) if (viscous) then $:GPU_LOOP(parallelism='[seq]') @@ -1979,70 +2269,77 @@ contains ! COMPUTING THE DIRECT WAVE SPEEDS if (wave_speeds == 1) then if (elasticity) then - ! Elastic wave speed, Rodriguez et al. JCP (2019) - s_L = min(vel_L(dir_idx(1)) - sqrt(c_L*c_L + (((4._wp*G_L)/3._wp) + tau_e_L(dir_idx_tau(1) & - & ))/rho_L), & - & vel_R(dir_idx(1)) - sqrt(c_R*c_R + (((4._wp*G_R)/3._wp) & - & + tau_e_R(dir_idx_tau(1)))/rho_R)) - s_R = max(vel_R(dir_idx(1)) + sqrt(c_R*c_R + (((4._wp*G_R)/3._wp) + tau_e_R(dir_idx_tau(1) & - & ))/rho_R), & - & vel_L(dir_idx(1)) + sqrt(c_L*c_L + (((4._wp*G_L)/3._wp) & - & + tau_e_L(dir_idx_tau(1)))/rho_L)) - s_S = (pres_R - tau_e_R(dir_idx_tau(1)) - pres_L + tau_e_L(dir_idx_tau(1)) & - & + rho_L*vel_L(dir_idx(1))*(s_L - vel_L(dir_idx(1))) - rho_R*vel_R(dir_idx(1)) & - & *(s_R - vel_R(dir_idx(1))))/(rho_L*(s_L - vel_L(dir_idx(1))) - rho_R*(s_R & - & - vel_R(dir_idx(1)))) + s_L = min(vel_L(dir_idx(1)) - sqrt(c_L*c_L + & + (((4._wp*G_L)/3._wp) + tau_e_L(dir_idx_tau(1)))/rho_L), vel_R(dir_idx(1)) - sqrt(c_R*c_R + & + (((4._wp*G_R)/3._wp) + tau_e_R(dir_idx_tau(1)))/rho_R)) + s_R = max(vel_R(dir_idx(1)) + sqrt(c_R*c_R + & + (((4._wp*G_R)/3._wp) + tau_e_R(dir_idx_tau(1)))/rho_R), vel_L(dir_idx(1)) + sqrt(c_L*c_L + & + (((4._wp*G_L)/3._wp) + tau_e_L(dir_idx_tau(1)))/rho_L)) + s_S = (pres_R - tau_e_R(dir_idx_tau(1)) - pres_L + & + tau_e_L(dir_idx_tau(1)) + rho_L*vel_L(dir_idx(1))*(s_L - vel_L(dir_idx(1))) - & + rho_R*vel_R(dir_idx(1))*(s_R - vel_R(dir_idx(1))))/(rho_L*(s_L - vel_L(dir_idx(1))) - & + rho_R*(s_R - vel_R(dir_idx(1)))) else s_L = min(vel_L(dir_idx(1)) - c_L, vel_R(dir_idx(1)) - c_R) s_R = max(vel_R(dir_idx(1)) + c_R, vel_L(dir_idx(1)) + c_L) - s_S = (pres_R - pres_L + rho_L*vel_L(dir_idx(1))*(s_L - vel_L(dir_idx(1))) & - & - rho_R*vel_R(dir_idx(1))*(s_R - vel_R(dir_idx(1))))/(rho_L*(s_L & - & - vel_L(dir_idx(1))) - rho_R*(s_R - vel_R(dir_idx(1)))) + s_S = (pres_R - pres_L + rho_L*vel_L(dir_idx(1))* & + (s_L - vel_L(dir_idx(1))) - rho_R*vel_R(dir_idx(1))*(s_R - vel_R(dir_idx(1)))) & + /(rho_L*(s_L - vel_L(dir_idx(1))) - rho_R*(s_R - vel_R(dir_idx(1)))) + end if - else if (wave_speeds == 2) then - pres_SL = 5.e-1_wp*(pres_L + pres_R + rho_avg*c_avg*(vel_L(dir_idx(1)) - vel_R(dir_idx(1)))) + elseif (wave_speeds == 2) then + pres_SL = 5.e-1_wp*(pres_L + pres_R + rho_avg*c_avg* & + (vel_L(dir_idx(1)) - & + vel_R(dir_idx(1)))) pres_SR = pres_SL - ! Low Mach correction: Thornber et al. JCP (2008) - Ms_L = max(1._wp, & - & sqrt(1._wp + ((5.e-1_wp + gamma_L)/(1._wp + gamma_L))*(pres_SL/pres_L - 1._wp) & - & *pres_L/((pres_L + pi_inf_L/(1._wp + gamma_L))))) - Ms_R = max(1._wp, & - & sqrt(1._wp + ((5.e-1_wp + gamma_R)/(1._wp + gamma_R))*(pres_SR/pres_R - 1._wp) & - & *pres_R/((pres_R + pi_inf_R/(1._wp + gamma_R))))) + Ms_L = max(1._wp, sqrt(1._wp + ((5.e-1_wp + gamma_L)/(1._wp + gamma_L))* & + (pres_SL/pres_L - 1._wp)*pres_L/ & + ((pres_L + pi_inf_L/(1._wp + gamma_L))))) + Ms_R = max(1._wp, sqrt(1._wp + ((5.e-1_wp + gamma_R)/(1._wp + gamma_R))* & + (pres_SR/pres_R - 1._wp)*pres_R/ & + ((pres_R + pi_inf_R/(1._wp + gamma_R))))) s_L = vel_L(dir_idx(1)) - c_L*Ms_L s_R = vel_R(dir_idx(1)) + c_R*Ms_R - s_S = 5.e-1_wp*((vel_L(dir_idx(1)) + vel_R(dir_idx(1))) + (pres_L - pres_R)/(rho_avg*c_avg)) + s_S = 5.e-1_wp*((vel_L(dir_idx(1)) + vel_R(dir_idx(1))) + & + (pres_L - pres_R)/ & + (rho_avg*c_avg)) end if - ! follows Einfeldt et al. s_M/P = min/max(0.,s_L/R) + ! follows Einfeldt et al. + ! s_M/P = min/max(0.,s_L/R) s_M = min(0._wp, s_L); s_P = max(0._wp, s_R) - ! goes with q_star_L/R = xi_L/R * (variable) xi_L/R = ( ( s_L/R - u_L/R )/(s_L/R - s_star) ) + ! goes with q_star_L/R = xi_L/R * (variable) + ! xi_L/R = ( ( s_L/R - u_L/R )/(s_L/R - s_star) ) xi_L = (s_L - vel_L(dir_idx(1)))/(s_L - s_S) xi_R = (s_R - vel_R(dir_idx(1)))/(s_R - s_S) - ! goes with numerical star velocity in x/y/z directions xi_P/M = 0.5 +/m sgn(0.5,s_star) + ! goes with numerical star velocity in x/y/z directions + ! xi_P/M = 0.5 +/m sgn(0.5,s_star) xi_M = (5.e-1_wp + sign(0.5_wp, s_S)) xi_P = (5.e-1_wp - sign(0.5_wp, s_S)) - ! goes with the numerical velocity in x/y/z directions xi_P/M (pressure) = min/max(0. sgn(1,sL/sR)) + ! goes with the numerical velocity in x/y/z directions + ! xi_P/M (pressure) = min/max(0. sgn(1,sL/sR)) xi_MP = -min(0._wp, sign(1._wp, s_L)) xi_PP = max(0._wp, sign(1._wp, s_R)) - E_star = xi_M*(E_L + xi_MP*(xi_L*(E_L + (s_S - vel_L(dir_idx(1)))*(rho_L*s_S + pres_L/(s_L & - & - vel_L(dir_idx(1))))) - E_L)) + xi_P*(E_R + xi_PP*(xi_R*(E_R + (s_S & - & - vel_R(dir_idx(1)))*(rho_R*s_S + pres_R/(s_R - vel_R(dir_idx(1))))) - E_R)) - p_Star = xi_M*(pres_L + xi_MP*(rho_L*(s_L - vel_L(dir_idx(1)))*(s_S - vel_L(dir_idx(1))))) & - & + xi_P*(pres_R + xi_PP*(rho_R*(s_R - vel_R(dir_idx(1)))*(s_S - vel_R(dir_idx(1))))) + E_star = xi_M*(E_L + xi_MP*(xi_L*(E_L + (s_S - vel_L(dir_idx(1)))* & + (rho_L*s_S + pres_L/(s_L - vel_L(dir_idx(1))))) - E_L)) + & + xi_P*(E_R + xi_PP*(xi_R*(E_R + (s_S - vel_R(dir_idx(1)))* & + (rho_R*s_S + pres_R/(s_R - vel_R(dir_idx(1))))) - E_R)) + p_Star = xi_M*(pres_L + xi_MP*(rho_L*(s_L - vel_L(dir_idx(1)))*(s_S - vel_L(dir_idx(1))))) + & + xi_P*(pres_R + xi_PP*(rho_R*(s_R - vel_R(dir_idx(1)))*(s_S - vel_R(dir_idx(1))))) - rho_Star = xi_M*(rho_L*(xi_MP*xi_L + 1._wp - xi_MP)) + xi_P*(rho_R*(xi_PP*xi_R + 1._wp - xi_PP)) + rho_Star = xi_M*(rho_L*(xi_MP*xi_L + 1._wp - xi_MP)) + & + xi_P*(rho_R*(xi_PP*xi_R + 1._wp - xi_PP)) - vel_K_Star = vel_L(dir_idx(1))*(1._wp - xi_MP) + xi_MP*vel_R(dir_idx(1)) + xi_MP*xi_PP*(s_S & - & - vel_R(dir_idx(1))) + vel_K_Star = vel_L(dir_idx(1))*(1._wp - xi_MP) + xi_MP*vel_R(dir_idx(1)) + & + xi_MP*xi_PP*(s_S - vel_R(dir_idx(1))) ! Low Mach correction if (low_Mach == 1) then @@ -2051,42 +2348,44 @@ contains pcorr = 0._wp end if - ! COMPUTING FLUXES MASS FLUX. + ! COMPUTING FLUXES + ! MASS FLUX. $:GPU_LOOP(parallelism='[seq]') do i = 1, contxe - flux_rs${XYZ}$_vf(j, k, l, i) = xi_M*qL_prim_rs${XYZ}$_vf(j, k, l, & - & i)*(vel_L(dir_idx(1)) + s_M*(xi_L - 1._wp)) + xi_P*qR_prim_rs${XYZ}$_vf(j & - & + 1, k, l, i)*(vel_R(dir_idx(1)) + s_P*(xi_R - 1._wp)) + flux_rs${XYZ}$_vf(j, k, l, i) = & + xi_M*qL_prim_rs${XYZ}$_vf(j, k, l, i)*(vel_L(dir_idx(1)) + s_M*(xi_L - 1._wp)) + & + xi_P*qR_prim_rs${XYZ}$_vf(j + 1, k, l, i)*(vel_R(dir_idx(1)) + s_P*(xi_R - 1._wp)) end do - ! MOMENTUM FLUX. f = \rho u u - \sigma, q = \rho u, q_star = \xi * \rho*(s_star, v, w) + ! MOMENTUM FLUX. + ! f = \rho u u - \sigma, q = \rho u, q_star = \xi * \rho*(s_star, v, w) $:GPU_LOOP(parallelism='[seq]') do i = 1, num_dims - flux_rs${XYZ}$_vf(j, k, l, & - & contxe + dir_idx(i)) = rho_Star*vel_K_Star*(dir_flg(dir_idx(i)) & - & *vel_K_Star + (1._wp - dir_flg(dir_idx(i)))*(xi_M*vel_L(dir_idx(i)) & - & + xi_P*vel_R(dir_idx(i)))) + dir_flg(dir_idx(i))*p_Star + (s_M/s_L) & - & *(s_P/s_R)*dir_flg(dir_idx(i))*pcorr + flux_rs${XYZ}$_vf(j, k, l, contxe + dir_idx(i)) = rho_Star*vel_K_Star* & + (dir_flg(dir_idx(i))*vel_K_Star + (1._wp - dir_flg(dir_idx(i)))*(xi_M*vel_L(dir_idx(i)) + xi_P*vel_R(dir_idx(i)))) + dir_flg(dir_idx(i))*p_Star & + + (s_M/s_L)*(s_P/s_R)*dir_flg(dir_idx(i))*pcorr end do - ! ENERGY FLUX. f = u*(E-\sigma), q = E, q_star = \xi*E+(s-u)(\rho s_star - \sigma/(s-u)) - flux_rs${XYZ}$_vf(j, k, l, E_idx) = (E_star + p_Star)*vel_K_Star + (s_M/s_L)*(s_P/s_R)*pcorr*s_S + ! ENERGY FLUX. + ! f = u*(E-\sigma), q = E, q_star = \xi*E+(s-u)(\rho s_star - \sigma/(s-u)) + flux_rs${XYZ}$_vf(j, k, l, E_idx) = (E_star + p_Star)*vel_K_Star & + + (s_M/s_L)*(s_P/s_R)*pcorr*s_S ! ELASTICITY. Elastic shear stress additions for the momentum and energy flux if (elasticity) then - flux_ene_e = 0._wp + flux_ene_e = 0._wp; $:GPU_LOOP(parallelism='[seq]') do i = 1, num_dims ! MOMENTUM ELASTIC FLUX. - flux_rs${XYZ}$_vf(j, k, l, contxe + dir_idx(i)) = flux_rs${XYZ}$_vf(j, k, l, & - & contxe + dir_idx(i)) - xi_M*tau_e_L(dir_idx_tau(i)) & - & - xi_P*tau_e_R(dir_idx_tau(i)) + flux_rs${XYZ}$_vf(j, k, l, contxe + dir_idx(i)) = & + flux_rs${XYZ}$_vf(j, k, l, contxe + dir_idx(i)) & + - xi_M*tau_e_L(dir_idx_tau(i)) - xi_P*tau_e_R(dir_idx_tau(i)) ! ENERGY ELASTIC FLUX. - flux_ene_e = flux_ene_e - xi_M*(vel_L(dir_idx(i))*tau_e_L(dir_idx_tau(i)) & - & + s_M*(xi_L*((s_S - vel_L(i))*(tau_e_L(dir_idx_tau(i)) & - & /(s_L - vel_L(i)))))) - xi_P*(vel_R(dir_idx(i)) & - & *tau_e_R(dir_idx_tau(i)) + s_P*(xi_R*((s_S - vel_R(i)) & - & *(tau_e_R(dir_idx_tau(i))/(s_R - vel_R(i)))))) + flux_ene_e = flux_ene_e - & + xi_M*(vel_L(dir_idx(i))*tau_e_L(dir_idx_tau(i)) + & + s_M*(xi_L*((s_S - vel_L(i))*(tau_e_L(dir_idx_tau(i))/(s_L - vel_L(i)))))) - & + xi_P*(vel_R(dir_idx(i))*tau_e_R(dir_idx_tau(i)) + & + s_P*(xi_R*((s_S - vel_R(i))*(tau_e_R(dir_idx_tau(i))/(s_R - vel_R(i)))))) end do flux_rs${XYZ}$_vf(j, k, l, E_idx) = flux_rs${XYZ}$_vf(j, k, l, E_idx) + flux_ene_e end if @@ -2094,38 +2393,34 @@ contains ! VOLUME FRACTION FLUX. $:GPU_LOOP(parallelism='[seq]') do i = advxb, advxe - flux_rs${XYZ}$_vf(j, k, l, i) = xi_M*qL_prim_rs${XYZ}$_vf(j, k, l, & - & i)*s_S + xi_P*qR_prim_rs${XYZ}$_vf(j + 1, k, l, i)*s_S + flux_rs${XYZ}$_vf(j, k, l, i) = & + xi_M*qL_prim_rs${XYZ}$_vf(j, k, l, i)*s_S + & + xi_P*qR_prim_rs${XYZ}$_vf(j + 1, k, l, i)*s_S end do - ! Advection velocity source: interface velocity for volume fraction transport + ! SOURCE TERM FOR VOLUME FRACTION ADVECTION FLUX. $:GPU_LOOP(parallelism='[seq]') do i = 1, num_dims - vel_src_rs${XYZ}$_vf(j, k, l, & - & dir_idx(i)) = xi_M*(vel_L(dir_idx(i)) + dir_flg(dir_idx(i)) & - & *(s_S*(xi_MP*(xi_L - 1) + 1) - vel_L(dir_idx(i)))) & - & + xi_P*(vel_R(dir_idx(i)) + dir_flg(dir_idx(i))*(s_S*(xi_PP*(xi_R - 1) & - & + 1) - vel_R(dir_idx(i)))) + vel_src_rs${XYZ}$_vf(j, k, l, dir_idx(i)) = & + xi_M*(vel_L(dir_idx(i)) + dir_flg(dir_idx(i))*(s_S*(xi_MP*(xi_L - 1) + 1) - vel_L(dir_idx(i)))) + & + xi_P*(vel_R(dir_idx(i)) + dir_flg(dir_idx(i))*(s_S*(xi_PP*(xi_R - 1) + 1) - vel_R(dir_idx(i)))) end do - ! INTERNAL ENERGIES ADVECTION FLUX. K-th pressure and velocity in preparation for the internal - ! energy flux + ! INTERNAL ENERGIES ADVECTION FLUX. + ! K-th pressure and velocity in preparation for the internal energy flux $:GPU_LOOP(parallelism='[seq]') do i = 1, num_fluids - p_K_Star = xi_M*(xi_MP*((pres_L + pi_infs(i)/(1._wp + gammas(i)))*xi_L**(1._wp/gammas(i) & - & + 1._wp) - pi_infs(i)/(1._wp + gammas(i)) - pres_L) + pres_L) & - & + xi_P*(xi_PP*((pres_R + pi_infs(i)/(1._wp + gammas(i))) & - & *xi_R**(1._wp/gammas(i) + 1._wp) - pi_infs(i)/(1._wp + gammas(i)) - pres_R) & - & + pres_R) - - flux_rs${XYZ}$_vf(j, k, l, i + intxb - 1) = ((xi_M*qL_prim_rs${XYZ}$_vf(j, k, l, & - & i + advxb - 1) + xi_P*qR_prim_rs${XYZ}$_vf(j + 1, k, l, & - & i + advxb - 1))*(gammas(i)*p_K_Star + pi_infs(i)) & - & + (xi_M*qL_prim_rs${XYZ}$_vf(j, k, l, & - & i + contxb - 1) + xi_P*qR_prim_rs${XYZ}$_vf(j + 1, k, l, & - & i + contxb - 1))*qvs(i))*vel_K_Star + (s_M/s_L)*(s_P/s_R) & - & *pcorr*s_S*(xi_M*qL_prim_rs${XYZ}$_vf(j, k, l, & - & i + advxb - 1) + xi_P*qR_prim_rs${XYZ}$_vf(j + 1, k, l, i + advxb - 1)) + p_K_Star = xi_M*(xi_MP*((pres_L + pi_infs(i)/(1._wp + gammas(i)))* & + xi_L**(1._wp/gammas(i) + 1._wp) - pi_infs(i)/(1._wp + gammas(i)) - pres_L) + pres_L) + & + xi_P*(xi_PP*((pres_R + pi_infs(i)/(1._wp + gammas(i)))* & + xi_R**(1._wp/gammas(i) + 1._wp) - pi_infs(i)/(1._wp + gammas(i)) - pres_R) + pres_R) + + flux_rs${XYZ}$_vf(j, k, l, i + intxb - 1) = & + ((xi_M*qL_prim_rs${XYZ}$_vf(j, k, l, i + advxb - 1) + xi_P*qR_prim_rs${XYZ}$_vf(j + 1, k, l, i + advxb - 1))* & + (gammas(i)*p_K_Star + pi_infs(i)) + & + (xi_M*qL_prim_rs${XYZ}$_vf(j, k, l, i + contxb - 1) + xi_P*qR_prim_rs${XYZ}$_vf(j + 1, k, l, i + contxb - 1))* & + qvs(i))*vel_K_Star & + + (s_M/s_L)*(s_P/s_R)*pcorr*s_S*(xi_M*qL_prim_rs${XYZ}$_vf(j, k, l, i + advxb - 1) + xi_P*qR_prim_rs${XYZ}$_vf(j + 1, k, l, i + advxb - 1)) end do flux_src_rs${XYZ}$_vf(j, k, l, advxb) = vel_src_rs${XYZ}$_vf(j, k, l, dir_idx(1)) @@ -2134,34 +2429,35 @@ contains if (hypoelasticity) then $:GPU_LOOP(parallelism='[seq]') do i = 1, strxe - strxb + 1 - flux_rs${XYZ}$_vf(j, k, l, & - & strxb - 1 + i) = xi_M*(s_S/(s_L - s_S))*(s_L*rho_L*tau_e_L(i) & - & - rho_L*vel_L(dir_idx(1))*tau_e_L(i)) + xi_P*(s_S/(s_R - s_S)) & - & *(s_R*rho_R*tau_e_R(i) - rho_R*vel_R(dir_idx(1))*tau_e_R(i)) + flux_rs${XYZ}$_vf(j, k, l, strxb - 1 + i) = & + xi_M*(s_S/(s_L - s_S))*(s_L*rho_L*tau_e_L(i) - rho_L*vel_L(dir_idx(1))*tau_e_L(i)) + & + xi_P*(s_S/(s_R - s_S))*(s_R*rho_R*tau_e_R(i) - rho_R*vel_R(dir_idx(1))*tau_e_R(i)) end do end if - ! Hyperelastic reference map flux for material deformation tracking + ! REFERENCE MAP FLUX. if (hyperelasticity) then $:GPU_LOOP(parallelism='[seq]') do i = 1, num_dims - flux_rs${XYZ}$_vf(j, k, l, & - & xibeg - 1 + i) = xi_M*(s_S/(s_L - s_S))*(s_L*rho_L*xi_field_L(i) & - & - rho_L*vel_L(dir_idx(1))*xi_field_L(i)) + xi_P*(s_S/(s_R - s_S)) & - & *(s_R*rho_R*xi_field_R(i) - rho_R*vel_R(dir_idx(1))*xi_field_R(i)) + flux_rs${XYZ}$_vf(j, k, l, xibeg - 1 + i) = & + xi_M*(s_S/(s_L - s_S))*(s_L*rho_L*xi_field_L(i) & + - rho_L*vel_L(dir_idx(1))*xi_field_L(i)) + & + xi_P*(s_S/(s_R - s_S))*(s_R*rho_R*xi_field_R(i) & + - rho_R*vel_R(dir_idx(1))*xi_field_R(i)) end do end if ! COLOR FUNCTION FLUX if (surface_tension) then - flux_rs${XYZ}$_vf(j, k, l, c_idx) = (xi_M*qL_prim_rs${XYZ}$_vf(j, k, l, & - & c_idx) + xi_P*qR_prim_rs${XYZ}$_vf(j + 1, k, l, c_idx))*s_S + flux_rs${XYZ}$_vf(j, k, l, c_idx) = & + (xi_M*qL_prim_rs${XYZ}$_vf(j, k, l, c_idx) + & + xi_P*qR_prim_rs${XYZ}$_vf(j + 1, k, l, c_idx))*s_S end if ! Geometrical source flux for cylindrical coordinates #:if (NORM_DIR == 2) if (cyl_coord) then - ! Substituting the advective flux into the inviscid geometrical source flux + !Substituting the advective flux into the inviscid geometrical source flux $:GPU_LOOP(parallelism='[seq]') do i = 1, E_idx flux_gsrc_rs${XYZ}$_vf(j, k, l, i) = flux_rs${XYZ}$_vf(j, k, l, i) @@ -2171,8 +2467,8 @@ contains flux_gsrc_rs${XYZ}$_vf(j, k, l, i) = flux_rs${XYZ}$_vf(j, k, l, i) end do ! Recalculating the radial momentum geometric source flux - flux_gsrc_rs${XYZ}$_vf(j, k, l, momxb - 1 + dir_idx(1)) = flux_gsrc_rs${XYZ}$_vf(j, k, l, & - & momxb - 1 + dir_idx(1)) - p_Star + flux_gsrc_rs${XYZ}$_vf(j, k, l, momxb - 1 + dir_idx(1)) = & + flux_gsrc_rs${XYZ}$_vf(j, k, l, momxb - 1 + dir_idx(1)) - p_Star ! Geometrical source of the void fraction(s) is zero $:GPU_LOOP(parallelism='[seq]') do i = advxb, advxe @@ -2186,29 +2482,25 @@ contains do i = 1, sys_size flux_gsrc_rs${XYZ}$_vf(j, k, l, i) = 0._wp end do - flux_gsrc_rs${XYZ}$_vf(j, k, l, momxb - 1 + dir_idx(1)) = flux_gsrc_rs${XYZ}$_vf(j, k, l, & - & momxb - 1 + dir_idx(1)) - p_Star + flux_gsrc_rs${XYZ}$_vf(j, k, l, momxb - 1 + dir_idx(1)) = & + flux_gsrc_rs${XYZ}$_vf(j, k, l, momxb - 1 + dir_idx(1)) - p_Star flux_gsrc_rs${XYZ}$_vf(j, k, l, momxe) = flux_rs${XYZ}$_vf(j, k, l, momxb + 1) end if #:endif + end do end do end do $:END_GPU_PARALLEL_LOOP() - else if (model_eqns == 4) then - ! 4-equation model (model_eqns=4): single pressure, velocity equilibrium - $:GPU_PARALLEL_LOOP(collapse=3, private='[i, q, alpha_rho_L, alpha_rho_R, vel_L, vel_R, alpha_L, alpha_R, & - & nbub_L, nbub_R, rho_L, rho_R, pres_L, pres_R, E_L, E_R, H_L, H_R, Cp_avg, Cv_avg, & - & T_avg, eps, c_sum_Yi_Phi, T_L, T_R, Y_L, Y_R, MW_L, MW_R, R_gas_L, R_gas_R, Cp_L, Cp_R, & - & Gamm_L, Gamm_R, gamma_L, gamma_R, pi_inf_L, pi_inf_R, qv_L, qv_R, qv_avg, c_L, c_R, & - & G_L, G_R, rho_avg, H_avg, c_avg, gamma_avg, ptilde_L, ptilde_R, vel_L_rms, vel_R_rms, & - & vel_avg_rms, vel_L_tmp, vel_R_tmp, Ms_L, Ms_R, pres_SL, pres_SR, alpha_L_sum, & - & alpha_R_sum, rho_Star, E_Star, p_Star, p_K_Star, vel_K_star, s_L, s_R, s_M, s_P, s_S, & - & xi_M, xi_P, xi_L, xi_R, xi_MP, xi_PP]') + + elseif (model_eqns == 4) then + !ME4 + $:GPU_PARALLEL_LOOP(collapse=3, private='[i, q, alpha_rho_L, alpha_rho_R, vel_L, vel_R, alpha_L, alpha_R, nbub_L, nbub_R, rho_L, rho_R, pres_L, pres_R, E_L, E_R, H_L, H_R, Cp_avg, Cv_avg, T_avg, eps, c_sum_Yi_Phi, T_L, T_R, Y_L, Y_R, MW_L, MW_R, R_gas_L, R_gas_R, Cp_L, Cp_R, Gamm_L, Gamm_R, gamma_L, gamma_R, pi_inf_L, pi_inf_R, qv_L, qv_R, qv_avg,c_L, c_R, G_L, G_R, rho_avg, H_avg, c_avg, gamma_avg, ptilde_L, ptilde_R, vel_L_rms, vel_R_rms, vel_avg_rms, vel_L_tmp, vel_R_tmp, Ms_L, Ms_R, pres_SL, pres_SR, alpha_L_sum, alpha_R_sum, rho_Star, E_Star, p_Star, p_K_Star, vel_K_star, s_L, s_R, s_M, s_P, s_S, xi_M, xi_P, xi_L, xi_R, xi_MP, xi_PP]') do l = is3%beg, is3%end do k = is2%beg, is2%end do j = is1%beg, is1%end + vel_L_rms = 0._wp; vel_R_rms = 0._wp rho_L = 0._wp; rho_R = 0._wp gamma_L = 0._wp; gamma_R = 0._wp @@ -2264,98 +2556,120 @@ contains @:compute_average_state() - call s_compute_speed_of_sound(pres_L, rho_L, gamma_L, pi_inf_L, H_L, alpha_L, vel_L_rms, 0._wp, & - & c_L, qv_L) + call s_compute_speed_of_sound(pres_L, rho_L, gamma_L, pi_inf_L, H_L, alpha_L, & + vel_L_rms, 0._wp, c_L, qv_L) - call s_compute_speed_of_sound(pres_R, rho_R, gamma_R, pi_inf_R, H_R, alpha_R, vel_R_rms, 0._wp, & - & c_R, qv_R) + call s_compute_speed_of_sound(pres_R, rho_R, gamma_R, pi_inf_R, H_R, alpha_R, & + vel_R_rms, 0._wp, c_R, qv_R) !> The computation of c_avg does not require all the variables, and therefore the non '_avg' ! variables are placeholders to call the subroutine. - call s_compute_speed_of_sound(pres_R, rho_avg, gamma_avg, pi_inf_R, H_avg, alpha_R, vel_avg_rms, & - & 0._wp, c_avg, qv_avg) + call s_compute_speed_of_sound(pres_R, rho_avg, gamma_avg, pi_inf_R, H_avg, alpha_R, & + vel_avg_rms, 0._wp, c_avg, qv_avg) if (wave_speeds == 1) then s_L = min(vel_L(dir_idx(1)) - c_L, vel_R(dir_idx(1)) - c_R) s_R = max(vel_R(dir_idx(1)) + c_R, vel_L(dir_idx(1)) + c_L) - s_S = (pres_R - pres_L + rho_L*vel_L(dir_idx(1))*(s_L - vel_L(dir_idx(1))) & - & - rho_R*vel_R(dir_idx(1))*(s_R - vel_R(dir_idx(1))))/(rho_L*(s_L - vel_L(dir_idx(1))) & - & - rho_R*(s_R - vel_R(dir_idx(1)))) - else if (wave_speeds == 2) then - pres_SL = 5.e-1_wp*(pres_L + pres_R + rho_avg*c_avg*(vel_L(dir_idx(1)) - vel_R(dir_idx(1)))) + s_S = (pres_R - pres_L + rho_L*vel_L(dir_idx(1))* & + (s_L - vel_L(dir_idx(1))) - & + rho_R*vel_R(dir_idx(1))* & + (s_R - vel_R(dir_idx(1)))) & + /(rho_L*(s_L - vel_L(dir_idx(1))) - & + rho_R*(s_R - vel_R(dir_idx(1)))) + elseif (wave_speeds == 2) then + pres_SL = 5.e-1_wp*(pres_L + pres_R + rho_avg*c_avg* & + (vel_L(dir_idx(1)) - & + vel_R(dir_idx(1)))) pres_SR = pres_SL - ! Low Mach correction: Thornber et al. JCP (2008) - Ms_L = max(1._wp, & - & sqrt(1._wp + ((5.e-1_wp + gamma_L)/(1._wp + gamma_L))*(pres_SL/pres_L - 1._wp) & - & *pres_L/((pres_L + pi_inf_L/(1._wp + gamma_L))))) - Ms_R = max(1._wp, & - & sqrt(1._wp + ((5.e-1_wp + gamma_R)/(1._wp + gamma_R))*(pres_SR/pres_R - 1._wp) & - & *pres_R/((pres_R + pi_inf_R/(1._wp + gamma_R))))) + Ms_L = max(1._wp, sqrt(1._wp + ((5.e-1_wp + gamma_L)/(1._wp + gamma_L))* & + (pres_SL/pres_L - 1._wp)*pres_L/ & + ((pres_L + pi_inf_L/(1._wp + gamma_L))))) + Ms_R = max(1._wp, sqrt(1._wp + ((5.e-1_wp + gamma_R)/(1._wp + gamma_R))* & + (pres_SR/pres_R - 1._wp)*pres_R/ & + ((pres_R + pi_inf_R/(1._wp + gamma_R))))) s_L = vel_L(dir_idx(1)) - c_L*Ms_L s_R = vel_R(dir_idx(1)) + c_R*Ms_R - s_S = 5.e-1_wp*((vel_L(dir_idx(1)) + vel_R(dir_idx(1))) + (pres_L - pres_R)/(rho_avg*c_avg)) + s_S = 5.e-1_wp*((vel_L(dir_idx(1)) + vel_R(dir_idx(1))) + & + (pres_L - pres_R)/ & + (rho_avg*c_avg)) end if - ! follows Einfeldt et al. s_M/P = min/max(0.,s_L/R) + ! follows Einfeldt et al. + ! s_M/P = min/max(0.,s_L/R) s_M = min(0._wp, s_L); s_P = max(0._wp, s_R) - ! goes with q_star_L/R = xi_L/R * (variable) xi_L/R = ( ( s_L/R - u_L/R )/(s_L/R - s_star) ) + ! goes with q_star_L/R = xi_L/R * (variable) + ! xi_L/R = ( ( s_L/R - u_L/R )/(s_L/R - s_star) ) xi_L = (s_L - vel_L(dir_idx(1)))/(s_L - s_S) xi_R = (s_R - vel_R(dir_idx(1)))/(s_R - s_S) - ! goes with numerical velocity in x/y/z directions xi_P/M = 0.5 +/m sgn(0.5,s_star) + ! goes with numerical velocity in x/y/z directions + ! xi_P/M = 0.5 +/m sgn(0.5,s_star) xi_M = (5.e-1_wp + sign(5.e-1_wp, s_S)) xi_P = (5.e-1_wp - sign(5.e-1_wp, s_S)) $:GPU_LOOP(parallelism='[seq]') do i = 1, contxe - flux_rs${XYZ}$_vf(j, k, l, & - & i) = xi_M*alpha_rho_L(i)*(vel_L(dir_idx(1)) + s_M*(xi_L - 1._wp)) & - & + xi_P*alpha_rho_R(i)*(vel_R(dir_idx(1)) + s_P*(xi_R - 1._wp)) + flux_rs${XYZ}$_vf(j, k, l, i) = & + xi_M*alpha_rho_L(i) & + *(vel_L(dir_idx(1)) + s_M*(xi_L - 1._wp)) & + + xi_P*alpha_rho_R(i) & + *(vel_R(dir_idx(1)) + s_P*(xi_R - 1._wp)) end do - ! Momentum flux. f = \rho u u + p I, q = \rho u, q_star = \xi * \rho*(s_star, v, w) + ! Momentum flux. + ! f = \rho u u + p I, q = \rho u, q_star = \xi * \rho*(s_star, v, w) $:GPU_LOOP(parallelism='[seq]') do i = 1, num_dims - flux_rs${XYZ}$_vf(j, k, l, & - & contxe + dir_idx(i)) = xi_M*(rho_L*(vel_L(dir_idx(1))*vel_L(dir_idx(i)) & - & + s_M*(xi_L*(dir_flg(dir_idx(i))*s_S + (1._wp - dir_flg(dir_idx(i))) & - & *vel_L(dir_idx(i))) - vel_L(dir_idx(i)))) + dir_flg(dir_idx(i))*pres_L) & - & + xi_P*(rho_R*(vel_R(dir_idx(1))*vel_R(dir_idx(i)) & - & + s_P*(xi_R*(dir_flg(dir_idx(i))*s_S + (1._wp - dir_flg(dir_idx(i))) & - & *vel_R(dir_idx(i))) - vel_R(dir_idx(i)))) + dir_flg(dir_idx(i))*pres_R) + flux_rs${XYZ}$_vf(j, k, l, contxe + dir_idx(i)) = & + xi_M*(rho_L*(vel_L(dir_idx(1))* & + vel_L(dir_idx(i)) + & + s_M*(xi_L*(dir_flg(dir_idx(i))*s_S + & + (1._wp - dir_flg(dir_idx(i)))* & + vel_L(dir_idx(i))) - vel_L(dir_idx(i)))) + & + dir_flg(dir_idx(i))*pres_L) & + + xi_P*(rho_R*(vel_R(dir_idx(1))* & + vel_R(dir_idx(i)) + & + s_P*(xi_R*(dir_flg(dir_idx(i))*s_S + & + (1._wp - dir_flg(dir_idx(i)))* & + vel_R(dir_idx(i))) - vel_R(dir_idx(i)))) + & + dir_flg(dir_idx(i))*pres_R) end do if (bubbles_euler) then ! Put p_tilde in $:GPU_LOOP(parallelism='[seq]') do i = 1, num_dims - flux_rs${XYZ}$_vf(j, k, l, contxe + dir_idx(i)) = flux_rs${XYZ}$_vf(j, k, l, & - & contxe + dir_idx(i)) + xi_M*(dir_flg(dir_idx(i))*(-1._wp*ptilde_L)) & - & + xi_P*(dir_flg(dir_idx(i))*(-1._wp*ptilde_R)) + flux_rs${XYZ}$_vf(j, k, l, contxe + dir_idx(i)) = & + flux_rs${XYZ}$_vf(j, k, l, contxe + dir_idx(i)) + & + xi_M*(dir_flg(dir_idx(i))*(-1._wp*ptilde_L)) & + + xi_P*(dir_flg(dir_idx(i))*(-1._wp*ptilde_R)) end do end if flux_rs${XYZ}$_vf(j, k, l, E_idx) = 0._wp $:GPU_LOOP(parallelism='[seq]') - do i = alf_idx, alf_idx ! only advect the void fraction - flux_rs${XYZ}$_vf(j, k, l, i) = xi_M*qL_prim_rs${XYZ}$_vf(j, k, l, & - & i)*(vel_L(dir_idx(1)) + s_M*(xi_L - 1._wp)) + xi_P*qR_prim_rs${XYZ}$_vf(j & - & + 1, k, l, i)*(vel_R(dir_idx(1)) + s_P*(xi_R - 1._wp)) + do i = alf_idx, alf_idx !only advect the void fraction + flux_rs${XYZ}$_vf(j, k, l, i) = & + xi_M*qL_prim_rs${XYZ}$_vf(j, k, l, i) & + *(vel_L(dir_idx(1)) + s_M*(xi_L - 1._wp)) & + + xi_P*qR_prim_rs${XYZ}$_vf(j + 1, k, l, i) & + *(vel_R(dir_idx(1)) + s_P*(xi_R - 1._wp)) end do - ! Advection velocity source: interface velocity for volume fraction transport + ! Source for volume fraction advection equation $:GPU_LOOP(parallelism='[seq]') do i = 1, num_dims + vel_src_rs${XYZ}$_vf(j, k, l, dir_idx(i)) = 0._wp - ! IF ( (model_eqns == 4) .or. (num_fluids==1) ) vel_src_rs_vf(dir_idx(i))%sf(j,k,l) = 0._wp + !IF ( (model_eqns == 4) .or. (num_fluids==1) ) vel_src_rs_vf(dir_idx(i))%sf(j,k,l) = 0._wp end do flux_src_rs${XYZ}$_vf(j, k, l, advxb) = vel_src_rs${XYZ}$_vf(j, k, l, dir_idx(1)) @@ -2364,10 +2678,11 @@ contains if (bubbles_euler) then $:GPU_LOOP(parallelism='[seq]') do i = bubxb, bubxe - flux_rs${XYZ}$_vf(j, k, l, i) = xi_M*nbub_L*qL_prim_rs${XYZ}$_vf(j, k, l, & - & i)*(vel_L(dir_idx(1)) + s_M*(xi_L - 1._wp)) & - & + xi_P*nbub_R*qR_prim_rs${XYZ}$_vf(j + 1, k, l, & - & i)*(vel_R(dir_idx(1)) + s_P*(xi_R - 1._wp)) + flux_rs${XYZ}$_vf(j, k, l, i) = & + xi_M*nbub_L*qL_prim_rs${XYZ}$_vf(j, k, l, i) & + *(vel_L(dir_idx(1)) + s_M*(xi_L - 1._wp)) & + + xi_P*nbub_R*qR_prim_rs${XYZ}$_vf(j + 1, k, l, i) & + *(vel_R(dir_idx(1)) + s_P*(xi_R - 1._wp)) end do end if @@ -2381,13 +2696,17 @@ contains flux_gsrc_rs${XYZ}$_vf(j, k, l, i) = flux_rs${XYZ}$_vf(j, k, l, i) end do ! Recalculating the radial momentum geometric source flux - flux_gsrc_rs${XYZ}$_vf(j, k, l, & - & contxe + dir_idx(1)) = xi_M*(rho_L*(vel_L(dir_idx(1)) & - & *vel_L(dir_idx(1)) + s_M*(xi_L*(dir_flg(dir_idx(1))*s_S + (1._wp & - & - dir_flg(dir_idx(1)))*vel_L(dir_idx(1))) - vel_L(dir_idx(1))))) & - & + xi_P*(rho_R*(vel_R(dir_idx(1))*vel_R(dir_idx(1)) & - & + s_P*(xi_R*(dir_flg(dir_idx(1))*s_S + (1._wp & - & - dir_flg(dir_idx(1)))*vel_R(dir_idx(1))) - vel_R(dir_idx(1))))) + flux_gsrc_rs${XYZ}$_vf(j, k, l, contxe + dir_idx(1)) = & + xi_M*(rho_L*(vel_L(dir_idx(1))* & + vel_L(dir_idx(1)) + & + s_M*(xi_L*(dir_flg(dir_idx(1))*s_S + & + (1._wp - dir_flg(dir_idx(1)))* & + vel_L(dir_idx(1))) - vel_L(dir_idx(1))))) & + + xi_P*(rho_R*(vel_R(dir_idx(1))* & + vel_R(dir_idx(1)) + & + s_P*(xi_R*(dir_flg(dir_idx(1))*s_S + & + (1._wp - dir_flg(dir_idx(1)))* & + vel_R(dir_idx(1))) - vel_R(dir_idx(1))))) ! Geometrical source of the void fraction(s) is zero $:GPU_LOOP(parallelism='[seq]') do i = advxb, advxe @@ -2401,13 +2720,17 @@ contains do i = 1, sys_size flux_gsrc_rs${XYZ}$_vf(j, k, l, i) = 0._wp end do - flux_gsrc_rs${XYZ}$_vf(j, k, l, & - & momxb + 1) = -xi_M*(rho_L*(vel_L(dir_idx(1))*vel_L(dir_idx(1)) & - & + s_M*(xi_L*(dir_flg(dir_idx(1))*s_S + (1._wp & - & - dir_flg(dir_idx(1)))*vel_L(dir_idx(1))) - vel_L(dir_idx(1))))) & - & - xi_P*(rho_R*(vel_R(dir_idx(1))*vel_R(dir_idx(1)) & - & + s_P*(xi_R*(dir_flg(dir_idx(1))*s_S + (1._wp & - & - dir_flg(dir_idx(1)))*vel_R(dir_idx(1))) - vel_R(dir_idx(1))))) + flux_gsrc_rs${XYZ}$_vf(j, k, l, momxb + 1) = & + -xi_M*(rho_L*(vel_L(dir_idx(1))* & + vel_L(dir_idx(1)) + & + s_M*(xi_L*(dir_flg(dir_idx(1))*s_S + & + (1._wp - dir_flg(dir_idx(1)))* & + vel_L(dir_idx(1))) - vel_L(dir_idx(1))))) & + - xi_P*(rho_R*(vel_R(dir_idx(1))* & + vel_R(dir_idx(1)) + & + s_P*(xi_R*(dir_flg(dir_idx(1))*s_S + & + (1._wp - dir_flg(dir_idx(1)))* & + vel_R(dir_idx(1))) - vel_R(dir_idx(1))))) flux_gsrc_rs${XYZ}$_vf(j, k, l, momxe) = flux_rs${XYZ}$_vf(j, k, l, momxb + 1) end if #:endif @@ -2415,18 +2738,13 @@ contains end do end do $:END_GPU_PARALLEL_LOOP() - else if (model_eqns == 2 .and. bubbles_euler) then - ! 5-equation model with Euler-Euler bubble dynamics - $:GPU_PARALLEL_LOOP(collapse=3, private='[i, q, R0_L, R0_R, V0_L, V0_R, P0_L, P0_R, pbw_L, pbw_R, vel_L, & - & vel_R, rho_avg, alpha_L, alpha_R, h_avg, gamma_avg, Re_L, Re_R, pcorr, zcoef, rho_L, & - & rho_R, pres_L, pres_R, E_L, E_R, H_L, H_R, gamma_L, gamma_R, pi_inf_L, pi_inf_R, qv_L, & - & qv_R, qv_avg, c_L, c_R, c_avg, vel_L_rms, vel_R_rms, vel_avg_rms, vel_L_tmp, vel_R_tmp, & - & Ms_L, Ms_R, pres_SL, pres_SR, alpha_L_sum, alpha_R_sum, s_L, s_R, s_M, s_P, s_S, xi_M, & - & xi_P, xi_L, xi_R, xi_MP, xi_PP, nbub_L, nbub_R, PbwR3Lbar, PbwR3Rbar, R3Lbar, R3Rbar, & - & R3V2Lbar, R3V2Rbar]') + + elseif (model_eqns == 2 .and. bubbles_euler) then + $:GPU_PARALLEL_LOOP(collapse=3, private='[i, q, R0_L, R0_R, V0_L, V0_R, P0_L, P0_R, pbw_L, pbw_R, vel_L, vel_R, rho_avg, alpha_L, alpha_R, h_avg, gamma_avg, Re_L, Re_R, pcorr, zcoef, rho_L, rho_R, pres_L, pres_R, E_L, E_R, H_L, H_R, gamma_L, gamma_R, pi_inf_L, pi_inf_R, qv_L, qv_R, qv_avg, c_L, c_R, c_avg, vel_L_rms, vel_R_rms, vel_avg_rms, vel_L_tmp, vel_R_tmp, Ms_L, Ms_R, pres_SL, pres_SR, alpha_L_sum, alpha_R_sum, s_L, s_R, s_M, s_P, s_S, xi_M, xi_P, xi_L, xi_R, xi_MP, xi_PP, nbub_L, nbub_R, PbwR3Lbar, PbwR3Rbar, R3Lbar, R3Rbar, R3V2Lbar, R3V2Rbar]') do l = is3%beg, is3%end do k = is2%beg, is2%end do j = is1%beg, is1%end + vel_L_rms = 0._wp; vel_R_rms = 0._wp rho_L = 0._wp; rho_R = 0._wp gamma_L = 0._wp; gamma_R = 0._wp @@ -2486,7 +2804,7 @@ contains end if if (viscous) then - if (num_fluids == 1) then ! Need to consider case with num_fluids >= 2 + if (num_fluids == 1) then ! Need to consider case with num_fluids >= 2 $:GPU_LOOP(parallelism='[seq]') do i = 1, 2 Re_L(i) = dflt_real @@ -2497,14 +2815,15 @@ contains $:GPU_LOOP(parallelism='[seq]') do q = 1, Re_size(i) - Re_L(i) = (1._wp - qL_prim_rs${XYZ}$_vf(j, k, l, E_idx + Re_idx(i, q)))/Res_gs(i, & - & q) + Re_L(i) - Re_R(i) = (1._wp - qR_prim_rs${XYZ}$_vf(j + 1, k, l, E_idx + Re_idx(i, & - & q)))/Res_gs(i, q) + Re_R(i) + Re_L(i) = (1._wp - qL_prim_rs${XYZ}$_vf(j, k, l, E_idx + Re_idx(i, q)))/Res_gs(i, q) & + + Re_L(i) + Re_R(i) = (1._wp - qR_prim_rs${XYZ}$_vf(j + 1, k, l, E_idx + Re_idx(i, q)))/Res_gs(i, q) & + + Re_R(i) end do Re_L(i) = 1._wp/max(Re_L(i), sgm_eps) Re_R(i) = 1._wp/max(Re_R(i), sgm_eps) + end do end if end if @@ -2549,7 +2868,7 @@ contains nbub_R = (3._wp/(4._wp*pi))*qR_prim_rs${XYZ}$_vf(j + 1, k, l, E_idx + num_fluids)/nbub_R end if else - ! nb stored in 0th moment of first R0 bin in variable conversion module + !nb stored in 0th moment of first R0 bin in variable conversion module nbub_L = qL_prim_rs${XYZ}$_vf(j, k, l, bubxb) nbub_R = qR_prim_rs${XYZ}$_vf(j + 1, k, l, bubxb) end if @@ -2572,6 +2891,7 @@ contains R3V2Lbar = mom_sp_rs${XYZ}$_vf(j, k, l, 3) R3V2Rbar = mom_sp_rs${XYZ}$_vf(j + 1, k, l, 3) else + PbwR3Lbar = 0._wp PbwR3Rbar = 0._wp @@ -2604,18 +2924,19 @@ contains do i = 1, num_dims vel_avg_rms = vel_avg_rms + (5.e-1_wp*(vel_L(i) + vel_R(i)))**2._wp end do + end if - call s_compute_speed_of_sound(pres_L, rho_L, gamma_L, pi_inf_L, H_L, alpha_L, vel_L_rms, 0._wp, & - & c_L, qv_L) + call s_compute_speed_of_sound(pres_L, rho_L, gamma_L, pi_inf_L, H_L, alpha_L, & + vel_L_rms, 0._wp, c_L, qv_L) - call s_compute_speed_of_sound(pres_R, rho_R, gamma_R, pi_inf_R, H_R, alpha_R, vel_R_rms, 0._wp, & - & c_R, qv_R) + call s_compute_speed_of_sound(pres_R, rho_R, gamma_R, pi_inf_R, H_R, alpha_R, & + vel_R_rms, 0._wp, c_R, qv_R) !> The computation of c_avg does not require all the variables, and therefore the non '_avg' ! variables are placeholders to call the subroutine. - call s_compute_speed_of_sound(pres_R, rho_avg, gamma_avg, pi_inf_R, H_avg, alpha_R, vel_avg_rms, & - & 0._wp, c_avg, qv_avg) + call s_compute_speed_of_sound(pres_R, rho_avg, gamma_avg, pi_inf_R, H_avg, alpha_R, & + vel_avg_rms, 0._wp, c_avg, qv_avg) if (viscous) then $:GPU_LOOP(parallelism='[seq]') @@ -2633,36 +2954,45 @@ contains s_L = min(vel_L(dir_idx(1)) - c_L, vel_R(dir_idx(1)) - c_R) s_R = max(vel_R(dir_idx(1)) + c_R, vel_L(dir_idx(1)) + c_L) - s_S = (pres_R - pres_L + rho_L*vel_L(dir_idx(1))*(s_L - vel_L(dir_idx(1))) & - & - rho_R*vel_R(dir_idx(1))*(s_R - vel_R(dir_idx(1))))/(rho_L*(s_L - vel_L(dir_idx(1))) & - & - rho_R*(s_R - vel_R(dir_idx(1)))) - else if (wave_speeds == 2) then - pres_SL = 5.e-1_wp*(pres_L + pres_R + rho_avg*c_avg*(vel_L(dir_idx(1)) - vel_R(dir_idx(1)))) + s_S = (pres_R - pres_L + rho_L*vel_L(dir_idx(1))* & + (s_L - vel_L(dir_idx(1))) - & + rho_R*vel_R(dir_idx(1))* & + (s_R - vel_R(dir_idx(1)))) & + /(rho_L*(s_L - vel_L(dir_idx(1))) - & + rho_R*(s_R - vel_R(dir_idx(1)))) + elseif (wave_speeds == 2) then + pres_SL = 5.e-1_wp*(pres_L + pres_R + rho_avg*c_avg* & + (vel_L(dir_idx(1)) - & + vel_R(dir_idx(1)))) pres_SR = pres_SL - ! Low Mach correction: Thornber et al. JCP (2008) - Ms_L = max(1._wp, & - & sqrt(1._wp + ((5.e-1_wp + gamma_L)/(1._wp + gamma_L))*(pres_SL/pres_L - 1._wp) & - & *pres_L/((pres_L + pi_inf_L/(1._wp + gamma_L))))) - Ms_R = max(1._wp, & - & sqrt(1._wp + ((5.e-1_wp + gamma_R)/(1._wp + gamma_R))*(pres_SR/pres_R - 1._wp) & - & *pres_R/((pres_R + pi_inf_R/(1._wp + gamma_R))))) + Ms_L = max(1._wp, sqrt(1._wp + ((5.e-1_wp + gamma_L)/(1._wp + gamma_L))* & + (pres_SL/pres_L - 1._wp)*pres_L/ & + ((pres_L + pi_inf_L/(1._wp + gamma_L))))) + Ms_R = max(1._wp, sqrt(1._wp + ((5.e-1_wp + gamma_R)/(1._wp + gamma_R))* & + (pres_SR/pres_R - 1._wp)*pres_R/ & + ((pres_R + pi_inf_R/(1._wp + gamma_R))))) s_L = vel_L(dir_idx(1)) - c_L*Ms_L s_R = vel_R(dir_idx(1)) + c_R*Ms_R - s_S = 5.e-1_wp*((vel_L(dir_idx(1)) + vel_R(dir_idx(1))) + (pres_L - pres_R)/(rho_avg*c_avg)) + s_S = 5.e-1_wp*((vel_L(dir_idx(1)) + vel_R(dir_idx(1))) + & + (pres_L - pres_R)/ & + (rho_avg*c_avg)) end if - ! follows Einfeldt et al. s_M/P = min/max(0.,s_L/R) + ! follows Einfeldt et al. + ! s_M/P = min/max(0.,s_L/R) s_M = min(0._wp, s_L); s_P = max(0._wp, s_R) - ! goes with q_star_L/R = xi_L/R * (variable) xi_L/R = ( ( s_L/R - u_L/R )/(s_L/R - s_star) ) + ! goes with q_star_L/R = xi_L/R * (variable) + ! xi_L/R = ( ( s_L/R - u_L/R )/(s_L/R - s_star) ) xi_L = (s_L - vel_L(dir_idx(1)))/(s_L - s_S) xi_R = (s_R - vel_R(dir_idx(1)))/(s_R - s_S) - ! goes with numerical velocity in x/y/z directions xi_P/M = 0.5 +/m sgn(0.5,s_star) + ! goes with numerical velocity in x/y/z directions + ! xi_P/M = 0.5 +/m sgn(0.5,s_star) xi_M = (5.e-1_wp + sign(5.e-1_wp, s_S)) xi_P = (5.e-1_wp - sign(5.e-1_wp, s_S)) @@ -2675,9 +3005,11 @@ contains $:GPU_LOOP(parallelism='[seq]') do i = 1, contxe - flux_rs${XYZ}$_vf(j, k, l, i) = xi_M*qL_prim_rs${XYZ}$_vf(j, k, l, & - & i)*(vel_L(dir_idx(1)) + s_M*(xi_L - 1._wp)) + xi_P*qR_prim_rs${XYZ}$_vf(j & - & + 1, k, l, i)*(vel_R(dir_idx(1)) + s_P*(xi_R - 1._wp)) + flux_rs${XYZ}$_vf(j, k, l, i) = & + xi_M*qL_prim_rs${XYZ}$_vf(j, k, l, i) & + *(vel_L(dir_idx(1)) + s_M*(xi_L - 1._wp)) & + + xi_P*qR_prim_rs${XYZ}$_vf(j + 1, k, l, i) & + *(vel_R(dir_idx(1)) + s_P*(xi_R - 1._wp)) end do if (bubbles_euler .and. (num_fluids > 1)) then @@ -2685,7 +3017,8 @@ contains flux_rs${XYZ}$_vf(j, k, l, contxe) = 0._wp end if - ! Momentum flux. f = \rho u u + p I, q = \rho u, q_star = \xi * \rho*(s_star, v, w) + ! Momentum flux. + ! f = \rho u u + p I, q = \rho u, q_star = \xi * \rho*(s_star, v, w) ! Include p_tilde @@ -2693,53 +3026,71 @@ contains if (alpha_L(num_fluids) < small_alf .or. R3Lbar < small_alf) then pres_L = pres_L - alpha_L(num_fluids)*pres_L else - pres_L = pres_L - alpha_L(num_fluids)*(pres_L - PbwR3Lbar/R3Lbar - rho_L*R3V2Lbar/R3Lbar) + pres_L = pres_L - alpha_L(num_fluids)*(pres_L - PbwR3Lbar/R3Lbar - & + rho_L*R3V2Lbar/R3Lbar) end if if (alpha_R(num_fluids) < small_alf .or. R3Rbar < small_alf) then pres_R = pres_R - alpha_R(num_fluids)*pres_R else - pres_R = pres_R - alpha_R(num_fluids)*(pres_R - PbwR3Rbar/R3Rbar - rho_R*R3V2Rbar/R3Rbar) + pres_R = pres_R - alpha_R(num_fluids)*(pres_R - PbwR3Rbar/R3Rbar - & + rho_R*R3V2Rbar/R3Rbar) end if end if $:GPU_LOOP(parallelism='[seq]') do i = 1, num_dims - flux_rs${XYZ}$_vf(j, k, l, & - & contxe + dir_idx(i)) = xi_M*(rho_L*(vel_L(dir_idx(1))*vel_L(dir_idx(i)) & - & + s_M*(xi_L*(dir_flg(dir_idx(i))*s_S + (1._wp - dir_flg(dir_idx(i))) & - & *vel_L(dir_idx(i))) - vel_L(dir_idx(i)))) + dir_flg(dir_idx(i))*(pres_L)) & - & + xi_P*(rho_R*(vel_R(dir_idx(1))*vel_R(dir_idx(i)) & - & + s_P*(xi_R*(dir_flg(dir_idx(i))*s_S + (1._wp - dir_flg(dir_idx(i))) & - & *vel_R(dir_idx(i))) - vel_R(dir_idx(i)))) + dir_flg(dir_idx(i))*(pres_R)) & - & + (s_M/s_L)*(s_P/s_R)*dir_flg(dir_idx(i))*pcorr + flux_rs${XYZ}$_vf(j, k, l, contxe + dir_idx(i)) = & + xi_M*(rho_L*(vel_L(dir_idx(1))* & + vel_L(dir_idx(i)) + & + s_M*(xi_L*(dir_flg(dir_idx(i))*s_S + & + (1._wp - dir_flg(dir_idx(i)))* & + vel_L(dir_idx(i))) - vel_L(dir_idx(i)))) + & + dir_flg(dir_idx(i))*(pres_L)) & + + xi_P*(rho_R*(vel_R(dir_idx(1))* & + vel_R(dir_idx(i)) + & + s_P*(xi_R*(dir_flg(dir_idx(i))*s_S + & + (1._wp - dir_flg(dir_idx(i)))* & + vel_R(dir_idx(i))) - vel_R(dir_idx(i)))) + & + dir_flg(dir_idx(i))*(pres_R)) & + + (s_M/s_L)*(s_P/s_R)*dir_flg(dir_idx(i))*pcorr end do - ! Energy flux. f = u*(E+p), q = E, q_star = \xi*E+(s-u)(\rho s_star + p/(s-u)) - flux_rs${XYZ}$_vf(j, k, l, & - & E_idx) = xi_M*(vel_L(dir_idx(1))*(E_L + pres_L) + s_M*(xi_L*(E_L + (s_S & - & - vel_L(dir_idx(1)))*(rho_L*s_S + (pres_L)/(s_L - vel_L(dir_idx(1))))) - E_L)) & - & + xi_P*(vel_R(dir_idx(1))*(E_R + pres_R) + s_P*(xi_R*(E_R + (s_S & - & - vel_R(dir_idx(1)))*(rho_R*s_S + (pres_R)/(s_R - vel_R(dir_idx(1))))) - E_R)) & - & + (s_M/s_L)*(s_P/s_R)*pcorr*s_S + ! Energy flux. + ! f = u*(E+p), q = E, q_star = \xi*E+(s-u)(\rho s_star + p/(s-u)) + flux_rs${XYZ}$_vf(j, k, l, E_idx) = & + xi_M*(vel_L(dir_idx(1))*(E_L + pres_L) + & + s_M*(xi_L*(E_L + (s_S - vel_L(dir_idx(1)))* & + (rho_L*s_S + (pres_L)/ & + (s_L - vel_L(dir_idx(1))))) - E_L)) & + + xi_P*(vel_R(dir_idx(1))*(E_R + pres_R) + & + s_P*(xi_R*(E_R + (s_S - vel_R(dir_idx(1)))* & + (rho_R*s_S + (pres_R)/ & + (s_R - vel_R(dir_idx(1))))) - E_R)) & + + (s_M/s_L)*(s_P/s_R)*pcorr*s_S ! Volume fraction flux $:GPU_LOOP(parallelism='[seq]') do i = advxb, advxe - flux_rs${XYZ}$_vf(j, k, l, i) = xi_M*qL_prim_rs${XYZ}$_vf(j, k, l, & - & i)*(vel_L(dir_idx(1)) + s_M*(xi_L - 1._wp)) + xi_P*qR_prim_rs${XYZ}$_vf(j & - & + 1, k, l, i)*(vel_R(dir_idx(1)) + s_P*(xi_R - 1._wp)) + flux_rs${XYZ}$_vf(j, k, l, i) = & + xi_M*qL_prim_rs${XYZ}$_vf(j, k, l, i) & + *(vel_L(dir_idx(1)) + s_M*(xi_L - 1._wp)) & + + xi_P*qR_prim_rs${XYZ}$_vf(j + 1, k, l, i) & + *(vel_R(dir_idx(1)) + s_P*(xi_R - 1._wp)) end do - ! Advection velocity source: interface velocity for volume fraction transport + ! Source for volume fraction advection equation $:GPU_LOOP(parallelism='[seq]') do i = 1, num_dims - vel_src_rs${XYZ}$_vf(j, k, l, & - & dir_idx(i)) = xi_M*(vel_L(dir_idx(i)) + dir_flg(dir_idx(i))*s_M*(xi_L & - & - 1._wp)) + xi_P*(vel_R(dir_idx(i)) + dir_flg(dir_idx(i))*s_P*(xi_R & - & - 1._wp)) - - ! IF ( (model_eqns == 4) .or. (num_fluids==1) ) vel_src_rs_vf(dir_idx(i))%sf(j,k,l) = 0._wp + vel_src_rs${XYZ}$_vf(j, k, l, dir_idx(i)) = & + xi_M*(vel_L(dir_idx(i)) + & + dir_flg(dir_idx(i))* & + s_M*(xi_L - 1._wp)) & + + xi_P*(vel_R(dir_idx(i)) + & + dir_flg(dir_idx(i))* & + s_P*(xi_R - 1._wp)) + + !IF ( (model_eqns == 4) .or. (num_fluids==1) ) vel_src_rs_vf(dir_idx(i))%sf(j,k,l) = 0._wp end do flux_src_rs${XYZ}$_vf(j, k, l, advxb) = vel_src_rs${XYZ}$_vf(j, k, l, dir_idx(1)) @@ -2747,22 +3098,27 @@ contains ! Add advection flux for bubble variables $:GPU_LOOP(parallelism='[seq]') do i = bubxb, bubxe - flux_rs${XYZ}$_vf(j, k, l, i) = xi_M*nbub_L*qL_prim_rs${XYZ}$_vf(j, k, l, & - & i)*(vel_L(dir_idx(1)) + s_M*(xi_L - 1._wp)) & - & + xi_P*nbub_R*qR_prim_rs${XYZ}$_vf(j + 1, k, l, & - & i)*(vel_R(dir_idx(1)) + s_P*(xi_R - 1._wp)) + flux_rs${XYZ}$_vf(j, k, l, i) = & + xi_M*nbub_L*qL_prim_rs${XYZ}$_vf(j, k, l, i) & + *(vel_L(dir_idx(1)) + s_M*(xi_L - 1._wp)) & + + xi_P*nbub_R*qR_prim_rs${XYZ}$_vf(j + 1, k, l, i) & + *(vel_R(dir_idx(1)) + s_P*(xi_R - 1._wp)) end do if (qbmm) then - flux_rs${XYZ}$_vf(j, k, l, & - & bubxb) = xi_M*nbub_L*(vel_L(dir_idx(1)) + s_M*(xi_L - 1._wp)) & - & + xi_P*nbub_R*(vel_R(dir_idx(1)) + s_P*(xi_R - 1._wp)) + flux_rs${XYZ}$_vf(j, k, l, bubxb) = & + xi_M*nbub_L & + *(vel_L(dir_idx(1)) + s_M*(xi_L - 1._wp)) & + + xi_P*nbub_R & + *(vel_R(dir_idx(1)) + s_P*(xi_R - 1._wp)) end if if (adv_n) then - flux_rs${XYZ}$_vf(j, k, l, & - & n_idx) = xi_M*nbub_L*(vel_L(dir_idx(1)) + s_M*(xi_L - 1._wp)) & - & + xi_P*nbub_R*(vel_R(dir_idx(1)) + s_P*(xi_R - 1._wp)) + flux_rs${XYZ}$_vf(j, k, l, n_idx) = & + xi_M*nbub_L & + *(vel_L(dir_idx(1)) + s_M*(xi_L - 1._wp)) & + + xi_P*nbub_R & + *(vel_R(dir_idx(1)) + s_P*(xi_R - 1._wp)) end if ! Geometrical source flux for cylindrical coordinates @@ -2774,13 +3130,17 @@ contains flux_gsrc_rs${XYZ}$_vf(j, k, l, i) = flux_rs${XYZ}$_vf(j, k, l, i) end do ! Recalculating the radial momentum geometric source flux - flux_gsrc_rs${XYZ}$_vf(j, k, l, & - & contxe + dir_idx(1)) = xi_M*(rho_L*(vel_L(dir_idx(1)) & - & *vel_L(dir_idx(1)) + s_M*(xi_L*(dir_flg(dir_idx(1))*s_S + (1._wp & - & - dir_flg(dir_idx(1)))*vel_L(dir_idx(1))) - vel_L(dir_idx(1))))) & - & + xi_P*(rho_R*(vel_R(dir_idx(1))*vel_R(dir_idx(1)) & - & + s_P*(xi_R*(dir_flg(dir_idx(1))*s_S + (1._wp & - & - dir_flg(dir_idx(1)))*vel_R(dir_idx(1))) - vel_R(dir_idx(1))))) + flux_gsrc_rs${XYZ}$_vf(j, k, l, contxe + dir_idx(1)) = & + xi_M*(rho_L*(vel_L(dir_idx(1))* & + vel_L(dir_idx(1)) + & + s_M*(xi_L*(dir_flg(dir_idx(1))*s_S + & + (1._wp - dir_flg(dir_idx(1)))* & + vel_L(dir_idx(1))) - vel_L(dir_idx(1))))) & + + xi_P*(rho_R*(vel_R(dir_idx(1))* & + vel_R(dir_idx(1)) + & + s_P*(xi_R*(dir_flg(dir_idx(1))*s_S + & + (1._wp - dir_flg(dir_idx(1)))* & + vel_R(dir_idx(1))) - vel_R(dir_idx(1))))) ! Geometrical source of the void fraction(s) is zero $:GPU_LOOP(parallelism='[seq]') do i = advxb, advxe @@ -2795,14 +3155,19 @@ contains flux_gsrc_rs${XYZ}$_vf(j, k, l, i) = 0._wp end do - flux_gsrc_rs${XYZ}$_vf(j, k, l, & - & momxb + 1) = -xi_M*(rho_L*(vel_L(dir_idx(1))*vel_L(dir_idx(1)) & - & + s_M*(xi_L*(dir_flg(dir_idx(1))*s_S + (1._wp & - & - dir_flg(dir_idx(1)))*vel_L(dir_idx(1))) - vel_L(dir_idx(1))))) & - & - xi_P*(rho_R*(vel_R(dir_idx(1))*vel_R(dir_idx(1)) & - & + s_P*(xi_R*(dir_flg(dir_idx(1))*s_S + (1._wp & - & - dir_flg(dir_idx(1)))*vel_R(dir_idx(1))) - vel_R(dir_idx(1))))) + flux_gsrc_rs${XYZ}$_vf(j, k, l, momxb + 1) = & + -xi_M*(rho_L*(vel_L(dir_idx(1))* & + vel_L(dir_idx(1)) + & + s_M*(xi_L*(dir_flg(dir_idx(1))*s_S + & + (1._wp - dir_flg(dir_idx(1)))* & + vel_L(dir_idx(1))) - vel_L(dir_idx(1))))) & + - xi_P*(rho_R*(vel_R(dir_idx(1))* & + vel_R(dir_idx(1)) + & + s_P*(xi_R*(dir_flg(dir_idx(1))*s_S + & + (1._wp - dir_flg(dir_idx(1)))* & + vel_R(dir_idx(1))) - vel_R(dir_idx(1))))) flux_gsrc_rs${XYZ}$_vf(j, k, l, momxe) = flux_rs${XYZ}$_vf(j, k, l, momxb + 1) + end if #:endif end do @@ -2810,18 +3175,12 @@ contains end do $:END_GPU_PARALLEL_LOOP() else - ! 5-equation model (model_eqns=2): mixture total energy, volume fraction advection - $:GPU_PARALLEL_LOOP(collapse=3, private='[Re_max, i, q, T_L, T_R, vel_L_rms, vel_R_rms, pres_L, pres_R, & - & rho_L, gamma_L, pi_inf_L, qv_L, rho_R, gamma_R, pi_inf_R, qv_R, alpha_L_sum, & - & alpha_R_sum, E_L, E_R, MW_L, MW_R, R_gas_L, R_gas_R, Cp_L, Cp_R, Cv_L, Cv_R, Gamm_L, & - & Gamm_R, Y_L, Y_R, H_L, H_R, qv_avg, rho_avg, gamma_avg, H_avg, c_L, c_R, c_avg, s_P, & - & s_M, xi_P, xi_M, xi_L, xi_R, Ms_L, Ms_R, pres_SL, pres_SR, vel_L, vel_R, Re_L, Re_R, & - & alpha_L, alpha_R, s_L, s_R, s_S, vel_avg_rms, pcorr, zcoef, vel_L_tmp, vel_R_tmp, Ys_L, & - & Ys_R, Xs_L, Xs_R, Gamma_iL, Gamma_iR, Cp_iL, Cp_iR, tau_e_L, tau_e_R, xi_field_L, & - & xi_field_R, Yi_avg, Phi_avg, h_iL, h_iR, h_avg_2, G_L, G_R]', copyin='[is1, is2, is3]') + ! 5-EQUATION MODEL WITH HLLC + $:GPU_PARALLEL_LOOP(collapse=3, private='[Re_max, i, q, T_L, T_R, vel_L_rms, vel_R_rms, pres_L, pres_R, rho_L, gamma_L, pi_inf_L, qv_L, rho_R, gamma_R, pi_inf_R, qv_R, alpha_L_sum, alpha_R_sum, E_L, E_R, MW_L, MW_R, R_gas_L, R_gas_R, Cp_L, Cp_R, Cv_L, Cv_R, Gamm_L, Gamm_R, Y_L, Y_R, H_L, H_R, qv_avg, rho_avg, gamma_avg, H_avg, c_L, c_R, c_avg, s_P, s_M, xi_P, xi_M, xi_L, xi_R, Ms_L, Ms_R, pres_SL, pres_SR, vel_L, vel_R, Re_L, Re_R, alpha_L, alpha_R, s_L, s_R, s_S, vel_avg_rms, pcorr, zcoef, vel_L_tmp, vel_R_tmp, Ys_L, Ys_R, Xs_L, Xs_R, Gamma_iL, Gamma_iR, Cp_iL, Cp_iR, tau_e_L, tau_e_R, xi_field_L, xi_field_R, Yi_avg,Phi_avg, h_iL, h_iR, h_avg_2, G_L, G_R]', copyin='[is1, is2, is3]') do l = is3%beg, is3%end do k = is2%beg, is2%end do j = is1%beg, is1%end + vel_L_rms = 0._wp; vel_R_rms = 0._wp rho_L = 0._wp; rho_R = 0._wp gamma_L = 0._wp; gamma_R = 0._wp @@ -2846,26 +3205,23 @@ contains pres_L = qL_prim_rs${XYZ}$_vf(j, k, l, E_idx) pres_R = qR_prim_rs${XYZ}$_vf(j + 1, k, l, E_idx) - ! Change this by splitting it into the cases present in the bubbles_euler + ! Change this by splitting it into the cases + ! present in the bubbles_euler if (mpp_lim) then $:GPU_LOOP(parallelism='[seq]') do i = 1, num_fluids qL_prim_rs${XYZ}$_vf(j, k, l, i) = max(0._wp, qL_prim_rs${XYZ}$_vf(j, k, l, i)) - qL_prim_rs${XYZ}$_vf(j, k, l, E_idx + i) = min(max(0._wp, qL_prim_rs${XYZ}$_vf(j, k, l, & - & E_idx + i)), 1._wp) + qL_prim_rs${XYZ}$_vf(j, k, l, E_idx + i) = min(max(0._wp, qL_prim_rs${XYZ}$_vf(j, k, l, E_idx + i)), 1._wp) qR_prim_rs${XYZ}$_vf(j + 1, k, l, i) = max(0._wp, qR_prim_rs${XYZ}$_vf(j + 1, k, l, i)) - qR_prim_rs${XYZ}$_vf(j + 1, k, l, E_idx + i) = min(max(0._wp, qR_prim_rs${XYZ}$_vf(j + 1, & - & k, l, E_idx + i)), 1._wp) + qR_prim_rs${XYZ}$_vf(j + 1, k, l, E_idx + i) = min(max(0._wp, qR_prim_rs${XYZ}$_vf(j + 1, k, l, E_idx + i)), 1._wp) alpha_L_sum = alpha_L_sum + qL_prim_rs${XYZ}$_vf(j, k, l, E_idx + i) alpha_R_sum = alpha_R_sum + qR_prim_rs${XYZ}$_vf(j + 1, k, l, E_idx + i) end do $:GPU_LOOP(parallelism='[seq]') do i = 1, num_fluids - qL_prim_rs${XYZ}$_vf(j, k, l, E_idx + i) = qL_prim_rs${XYZ}$_vf(j, k, l, & - & E_idx + i)/max(alpha_L_sum, sgm_eps) - qR_prim_rs${XYZ}$_vf(j + 1, k, l, E_idx + i) = qR_prim_rs${XYZ}$_vf(j + 1, k, l, & - & E_idx + i)/max(alpha_R_sum, sgm_eps) + qL_prim_rs${XYZ}$_vf(j, k, l, E_idx + i) = qL_prim_rs${XYZ}$_vf(j, k, l, E_idx + i)/max(alpha_L_sum, sgm_eps) + qR_prim_rs${XYZ}$_vf(j + 1, k, l, E_idx + i) = qR_prim_rs${XYZ}$_vf(j + 1, k, l, E_idx + i)/max(alpha_R_sum, sgm_eps) end do end if @@ -2894,8 +3250,10 @@ contains $:GPU_LOOP(parallelism='[seq]') do q = 1, Re_size(i) - Re_L(i) = alpha_L(Re_idx(i, q))/Res_gs(i, q) + Re_L(i) - Re_R(i) = alpha_R(Re_idx(i, q))/Res_gs(i, q) + Re_R(i) + Re_L(i) = alpha_L(Re_idx(i, q))/Res_gs(i, q) & + + Re_L(i) + Re_R(i) = alpha_R(Re_idx(i, q))/Res_gs(i, q) & + + Re_R(i) end do Re_L(i) = 1._wp/max(Re_L(i), sgm_eps) @@ -2993,7 +3351,7 @@ contains end do end if - ! Hyperelastic stress contribution: strain energy added to total energy + ! ENERGY ADJUSTMENTS FOR HYPERELASTIC ENERGY if (hyperelasticity) then $:GPU_LOOP(parallelism='[seq]') do i = 1, num_dims @@ -3025,16 +3383,16 @@ contains @:compute_average_state() - call s_compute_speed_of_sound(pres_L, rho_L, gamma_L, pi_inf_L, H_L, alpha_L, vel_L_rms, 0._wp, & - & c_L, qv_L) + call s_compute_speed_of_sound(pres_L, rho_L, gamma_L, pi_inf_L, H_L, alpha_L, & + vel_L_rms, 0._wp, c_L, qv_L) - call s_compute_speed_of_sound(pres_R, rho_R, gamma_R, pi_inf_R, H_R, alpha_R, vel_R_rms, 0._wp, & - & c_R, qv_R) + call s_compute_speed_of_sound(pres_R, rho_R, gamma_R, pi_inf_R, H_R, alpha_R, & + vel_R_rms, 0._wp, c_R, qv_R) !> The computation of c_avg does not require all the variables, and therefore the non '_avg' ! variables are placeholders to call the subroutine. - call s_compute_speed_of_sound(pres_R, rho_avg, gamma_avg, pi_inf_R, H_avg, alpha_R, vel_avg_rms, & - & c_sum_Yi_Phi, c_avg, qv_avg) + call s_compute_speed_of_sound(pres_R, rho_avg, gamma_avg, pi_inf_R, H_avg, alpha_R, & + vel_avg_rms, c_sum_Yi_Phi, c_avg, qv_avg) if (viscous) then if (chemistry) then @@ -3053,53 +3411,57 @@ contains if (wave_speeds == 1) then if (elasticity) then - ! Elastic wave speed, Rodriguez et al. JCP (2019) - s_L = min(vel_L(dir_idx(1)) - sqrt(c_L*c_L + (((4._wp*G_L)/3._wp) + tau_e_L(dir_idx_tau(1) & - & ))/rho_L), & - & vel_R(dir_idx(1)) - sqrt(c_R*c_R + (((4._wp*G_R)/3._wp) & - & + tau_e_R(dir_idx_tau(1)))/rho_R)) - s_R = max(vel_R(dir_idx(1)) + sqrt(c_R*c_R + (((4._wp*G_R)/3._wp) + tau_e_R(dir_idx_tau(1) & - & ))/rho_R), & - & vel_L(dir_idx(1)) + sqrt(c_L*c_L + (((4._wp*G_L)/3._wp) & - & + tau_e_L(dir_idx_tau(1)))/rho_L)) - s_S = (pres_R - tau_e_R(dir_idx_tau(1)) - pres_L + tau_e_L(dir_idx_tau(1)) & - & + rho_L*vel_L(dir_idx(1))*(s_L - vel_L(dir_idx(1))) - rho_R*vel_R(dir_idx(1)) & - & *(s_R - vel_R(dir_idx(1))))/(rho_L*(s_L - vel_L(dir_idx(1))) - rho_R*(s_R & - & - vel_R(dir_idx(1)))) + s_L = min(vel_L(dir_idx(1)) - sqrt(c_L*c_L + & + (((4._wp*G_L)/3._wp) + tau_e_L(dir_idx_tau(1)))/rho_L), vel_R(dir_idx(1)) - sqrt(c_R*c_R + & + (((4._wp*G_R)/3._wp) + tau_e_R(dir_idx_tau(1)))/rho_R)) + s_R = max(vel_R(dir_idx(1)) + sqrt(c_R*c_R + & + (((4._wp*G_R)/3._wp) + tau_e_R(dir_idx_tau(1)))/rho_R), vel_L(dir_idx(1)) + sqrt(c_L*c_L + & + (((4._wp*G_L)/3._wp) + tau_e_L(dir_idx_tau(1)))/rho_L)) + s_S = (pres_R - tau_e_R(dir_idx_tau(1)) - pres_L + & + tau_e_L(dir_idx_tau(1)) + rho_L*vel_L(dir_idx(1))*(s_L - vel_L(dir_idx(1))) - & + rho_R*vel_R(dir_idx(1))*(s_R - vel_R(dir_idx(1))))/(rho_L*(s_L - vel_L(dir_idx(1))) - & + rho_R*(s_R - vel_R(dir_idx(1)))) else s_L = min(vel_L(dir_idx(1)) - c_L, vel_R(dir_idx(1)) - c_R) s_R = max(vel_R(dir_idx(1)) + c_R, vel_L(dir_idx(1)) + c_L) - s_S = (pres_R - pres_L + rho_L*vel_L(dir_idx(1))*(s_L - vel_L(dir_idx(1))) & - & - rho_R*vel_R(dir_idx(1))*(s_R - vel_R(dir_idx(1))))/(rho_L*(s_L & - & - vel_L(dir_idx(1))) - rho_R*(s_R - vel_R(dir_idx(1)))) + s_S = (pres_R - pres_L + rho_L*vel_L(dir_idx(1))* & + (s_L - vel_L(dir_idx(1))) - rho_R*vel_R(dir_idx(1))*(s_R - vel_R(dir_idx(1)))) & + /(rho_L*(s_L - vel_L(dir_idx(1))) - rho_R*(s_R - vel_R(dir_idx(1)))) + end if - else if (wave_speeds == 2) then - pres_SL = 5.e-1_wp*(pres_L + pres_R + rho_avg*c_avg*(vel_L(dir_idx(1)) - vel_R(dir_idx(1)))) + elseif (wave_speeds == 2) then + pres_SL = 5.e-1_wp*(pres_L + pres_R + rho_avg*c_avg* & + (vel_L(dir_idx(1)) - & + vel_R(dir_idx(1)))) pres_SR = pres_SL - ! Low Mach correction: Thornber et al. JCP (2008) - Ms_L = max(1._wp, & - & sqrt(1._wp + ((5.e-1_wp + gamma_L)/(1._wp + gamma_L))*(pres_SL/pres_L - 1._wp) & - & *pres_L/((pres_L + pi_inf_L/(1._wp + gamma_L))))) - Ms_R = max(1._wp, & - & sqrt(1._wp + ((5.e-1_wp + gamma_R)/(1._wp + gamma_R))*(pres_SR/pres_R - 1._wp) & - & *pres_R/((pres_R + pi_inf_R/(1._wp + gamma_R))))) + Ms_L = max(1._wp, sqrt(1._wp + ((5.e-1_wp + gamma_L)/(1._wp + gamma_L))* & + (pres_SL/pres_L - 1._wp)*pres_L/ & + ((pres_L + pi_inf_L/(1._wp + gamma_L))))) + Ms_R = max(1._wp, sqrt(1._wp + ((5.e-1_wp + gamma_R)/(1._wp + gamma_R))* & + (pres_SR/pres_R - 1._wp)*pres_R/ & + ((pres_R + pi_inf_R/(1._wp + gamma_R))))) s_L = vel_L(dir_idx(1)) - c_L*Ms_L s_R = vel_R(dir_idx(1)) + c_R*Ms_R - s_S = 5.e-1_wp*((vel_L(dir_idx(1)) + vel_R(dir_idx(1))) + (pres_L - pres_R)/(rho_avg*c_avg)) + s_S = 5.e-1_wp*((vel_L(dir_idx(1)) + vel_R(dir_idx(1))) + & + (pres_L - pres_R)/ & + (rho_avg*c_avg)) end if - ! follows Einfeldt et al. s_M/P = min/max(0.,s_L/R) + ! follows Einfeldt et al. + ! s_M/P = min/max(0.,s_L/R) s_M = min(0._wp, s_L); s_P = max(0._wp, s_R) - ! goes with q_star_L/R = xi_L/R * (variable) xi_L/R = ( ( s_L/R - u_L/R )/(s_L/R - s_star) ) + ! goes with q_star_L/R = xi_L/R * (variable) + ! xi_L/R = ( ( s_L/R - u_L/R )/(s_L/R - s_star) ) xi_L = (s_L - vel_L(dir_idx(1)))/(s_L - s_S) xi_R = (s_R - vel_R(dir_idx(1)))/(s_R - s_S) - ! goes with numerical velocity in x/y/z directions xi_P/M = 0.5 +/m sgn(0.5,s_star) + ! goes with numerical velocity in x/y/z directions + ! xi_P/M = 0.5 +/m sgn(0.5,s_star) xi_M = (5.e-1_wp + sign(5.e-1_wp, s_S)) xi_P = (5.e-1_wp - sign(5.e-1_wp, s_S)) @@ -3110,34 +3472,49 @@ contains pcorr = 0._wp end if - ! COMPUTING THE HLLC FLUXES MASS FLUX. + ! COMPUTING THE HLLC FLUXES + ! MASS FLUX. $:GPU_LOOP(parallelism='[seq]') do i = 1, contxe - flux_rs${XYZ}$_vf(j, k, l, i) = xi_M*qL_prim_rs${XYZ}$_vf(j, k, l, & - & i)*(vel_L(dir_idx(1)) + s_M*(xi_L - 1._wp)) + xi_P*qR_prim_rs${XYZ}$_vf(j & - & + 1, k, l, i)*(vel_R(dir_idx(1)) + s_P*(xi_R - 1._wp)) + flux_rs${XYZ}$_vf(j, k, l, i) = & + xi_M*qL_prim_rs${XYZ}$_vf(j, k, l, i) & + *(vel_L(dir_idx(1)) + s_M*(xi_L - 1._wp)) & + + xi_P*qR_prim_rs${XYZ}$_vf(j + 1, k, l, i) & + *(vel_R(dir_idx(1)) + s_P*(xi_R - 1._wp)) end do - ! MOMENTUM FLUX. f = \rho u u - \sigma, q = \rho u, q_star = \xi * \rho*(s_star, v, w) + ! MOMENTUM FLUX. + ! f = \rho u u - \sigma, q = \rho u, q_star = \xi * \rho*(s_star, v, w) $:GPU_LOOP(parallelism='[seq]') do i = 1, num_dims - flux_rs${XYZ}$_vf(j, k, l, & - & contxe + dir_idx(i)) = xi_M*(rho_L*(vel_L(dir_idx(1))*vel_L(dir_idx(i)) & - & + s_M*(xi_L*(dir_flg(dir_idx(i))*s_S + (1._wp - dir_flg(dir_idx(i))) & - & *vel_L(dir_idx(i))) - vel_L(dir_idx(i)))) + dir_flg(dir_idx(i))*(pres_L)) & - & + xi_P*(rho_R*(vel_R(dir_idx(1))*vel_R(dir_idx(i)) & - & + s_P*(xi_R*(dir_flg(dir_idx(i))*s_S + (1._wp - dir_flg(dir_idx(i))) & - & *vel_R(dir_idx(i))) - vel_R(dir_idx(i)))) + dir_flg(dir_idx(i))*(pres_R)) & - & + (s_M/s_L)*(s_P/s_R)*dir_flg(dir_idx(i))*pcorr + flux_rs${XYZ}$_vf(j, k, l, contxe + dir_idx(i)) = & + xi_M*(rho_L*(vel_L(dir_idx(1))* & + vel_L(dir_idx(i)) + & + s_M*(xi_L*(dir_flg(dir_idx(i))*s_S + & + (1._wp - dir_flg(dir_idx(i)))* & + vel_L(dir_idx(i))) - vel_L(dir_idx(i)))) + & + dir_flg(dir_idx(i))*(pres_L)) & + + xi_P*(rho_R*(vel_R(dir_idx(1))* & + vel_R(dir_idx(i)) + & + s_P*(xi_R*(dir_flg(dir_idx(i))*s_S + & + (1._wp - dir_flg(dir_idx(i)))* & + vel_R(dir_idx(i))) - vel_R(dir_idx(i)))) + & + dir_flg(dir_idx(i))*(pres_R)) & + + (s_M/s_L)*(s_P/s_R)*dir_flg(dir_idx(i))*pcorr end do - ! ENERGY FLUX. f = u*(E-\sigma), q = E, q_star = \xi*E+(s-u)(\rho s_star - \sigma/(s-u)) - flux_rs${XYZ}$_vf(j, k, l, & - & E_idx) = xi_M*(vel_L(dir_idx(1))*(E_L + pres_L) + s_M*(xi_L*(E_L + (s_S & - & - vel_L(dir_idx(1)))*(rho_L*s_S + pres_L/(s_L - vel_L(dir_idx(1))))) - E_L)) & - & + xi_P*(vel_R(dir_idx(1))*(E_R + pres_R) + s_P*(xi_R*(E_R + (s_S & - & - vel_R(dir_idx(1)))*(rho_R*s_S + pres_R/(s_R - vel_R(dir_idx(1))))) - E_R)) & - & + (s_M/s_L)*(s_P/s_R)*pcorr*s_S + ! ENERGY FLUX. + ! f = u*(E-\sigma), q = E, q_star = \xi*E+(s-u)(\rho s_star - \sigma/(s-u)) + flux_rs${XYZ}$_vf(j, k, l, E_idx) = & + xi_M*(vel_L(dir_idx(1))*(E_L + pres_L) + & + s_M*(xi_L*(E_L + (s_S - vel_L(dir_idx(1)))* & + (rho_L*s_S + pres_L/ & + (s_L - vel_L(dir_idx(1))))) - E_L)) & + + xi_P*(vel_R(dir_idx(1))*(E_R + pres_R) + & + s_P*(xi_R*(E_R + (s_S - vel_R(dir_idx(1)))* & + (rho_R*s_S + pres_R/ & + (s_R - vel_R(dir_idx(1))))) - E_R)) & + + (s_M/s_L)*(s_P/s_R)*pcorr*s_S ! ELASTICITY. Elastic shear stress additions for the momentum and energy flux if (elasticity) then @@ -3145,15 +3522,15 @@ contains $:GPU_LOOP(parallelism='[seq]') do i = 1, num_dims ! MOMENTUM ELASTIC FLUX. - flux_rs${XYZ}$_vf(j, k, l, contxe + dir_idx(i)) = flux_rs${XYZ}$_vf(j, k, l, & - & contxe + dir_idx(i)) - xi_M*tau_e_L(dir_idx_tau(i)) & - & - xi_P*tau_e_R(dir_idx_tau(i)) + flux_rs${XYZ}$_vf(j, k, l, contxe + dir_idx(i)) = & + flux_rs${XYZ}$_vf(j, k, l, contxe + dir_idx(i)) & + - xi_M*tau_e_L(dir_idx_tau(i)) - xi_P*tau_e_R(dir_idx_tau(i)) ! ENERGY ELASTIC FLUX. - flux_ene_e = flux_ene_e - xi_M*(vel_L(dir_idx(i))*tau_e_L(dir_idx_tau(i)) & - & + s_M*(xi_L*((s_S - vel_L(i))*(tau_e_L(dir_idx_tau(i)) & - & /(s_L - vel_L(i)))))) - xi_P*(vel_R(dir_idx(i)) & - & *tau_e_R(dir_idx_tau(i)) + s_P*(xi_R*((s_S - vel_R(i)) & - & *(tau_e_R(dir_idx_tau(i))/(s_R - vel_R(i)))))) + flux_ene_e = flux_ene_e - & + xi_M*(vel_L(dir_idx(i))*tau_e_L(dir_idx_tau(i)) + & + s_M*(xi_L*((s_S - vel_L(i))*(tau_e_L(dir_idx_tau(i))/(s_L - vel_L(i)))))) - & + xi_P*(vel_R(dir_idx(i))*tau_e_R(dir_idx_tau(i)) + & + s_P*(xi_R*((s_S - vel_R(i))*(tau_e_R(dir_idx_tau(i))/(s_R - vel_R(i)))))) end do flux_rs${XYZ}$_vf(j, k, l, E_idx) = flux_rs${XYZ}$_vf(j, k, l, E_idx) + flux_ene_e end if @@ -3162,46 +3539,52 @@ contains if (hypoelasticity) then $:GPU_LOOP(parallelism='[seq]') do i = 1, strxe - strxb + 1 - flux_rs${XYZ}$_vf(j, k, l, & - & strxb - 1 + i) = xi_M*(s_S/(s_L - s_S))*(s_L*rho_L*tau_e_L(i) & - & - rho_L*vel_L(dir_idx(1))*tau_e_L(i)) + xi_P*(s_S/(s_R - s_S)) & - & *(s_R*rho_R*tau_e_R(i) - rho_R*vel_R(dir_idx(1))*tau_e_R(i)) + flux_rs${XYZ}$_vf(j, k, l, strxb - 1 + i) = & + xi_M*(s_S/(s_L - s_S))*(s_L*rho_L*tau_e_L(i) - rho_L*vel_L(dir_idx(1))*tau_e_L(i)) + & + xi_P*(s_S/(s_R - s_S))*(s_R*rho_R*tau_e_R(i) - rho_R*vel_R(dir_idx(1))*tau_e_R(i)) end do end if ! VOLUME FRACTION FLUX. $:GPU_LOOP(parallelism='[seq]') do i = advxb, advxe - flux_rs${XYZ}$_vf(j, k, l, i) = xi_M*qL_prim_rs${XYZ}$_vf(j, k, l, & - & i)*(vel_L(dir_idx(1)) + s_M*(xi_L - 1._wp)) + xi_P*qR_prim_rs${XYZ}$_vf(j & - & + 1, k, l, i)*(vel_R(dir_idx(1)) + s_P*(xi_R - 1._wp)) + flux_rs${XYZ}$_vf(j, k, l, i) = & + xi_M*qL_prim_rs${XYZ}$_vf(j, k, l, i) & + *(vel_L(dir_idx(1)) + s_M*(xi_L - 1._wp)) & + + xi_P*qR_prim_rs${XYZ}$_vf(j + 1, k, l, i) & + *(vel_R(dir_idx(1)) + s_P*(xi_R - 1._wp)) end do ! VOLUME FRACTION SOURCE FLUX. $:GPU_LOOP(parallelism='[seq]') do i = 1, num_dims - vel_src_rs${XYZ}$_vf(j, k, l, & - & dir_idx(i)) = xi_M*(vel_L(dir_idx(i)) + dir_flg(dir_idx(i))*s_M*(xi_L & - & - 1._wp)) + xi_P*(vel_R(dir_idx(i)) + dir_flg(dir_idx(i))*s_P*(xi_R & - & - 1._wp)) + vel_src_rs${XYZ}$_vf(j, k, l, dir_idx(i)) = & + xi_M*(vel_L(dir_idx(i)) + & + dir_flg(dir_idx(i))* & + s_M*(xi_L - 1._wp)) & + + xi_P*(vel_R(dir_idx(i)) + & + dir_flg(dir_idx(i))* & + s_P*(xi_R - 1._wp)) end do ! COLOR FUNCTION FLUX if (surface_tension) then - flux_rs${XYZ}$_vf(j, k, l, c_idx) = xi_M*qL_prim_rs${XYZ}$_vf(j, k, l, & - & c_idx)*(vel_L(dir_idx(1)) + s_M*(xi_L - 1._wp)) & - & + xi_P*qR_prim_rs${XYZ}$_vf(j + 1, k, l, & - & c_idx)*(vel_R(dir_idx(1)) + s_P*(xi_R - 1._wp)) + flux_rs${XYZ}$_vf(j, k, l, c_idx) = & + xi_M*qL_prim_rs${XYZ}$_vf(j, k, l, c_idx) & + *(vel_L(dir_idx(1)) + s_M*(xi_L - 1._wp)) & + + xi_P*qR_prim_rs${XYZ}$_vf(j + 1, k, l, c_idx) & + *(vel_R(dir_idx(1)) + s_P*(xi_R - 1._wp)) end if - ! Hyperelastic reference map flux for material deformation tracking + ! REFERENCE MAP FLUX. if (hyperelasticity) then $:GPU_LOOP(parallelism='[seq]') do i = 1, num_dims - flux_rs${XYZ}$_vf(j, k, l, & - & xibeg - 1 + i) = xi_M*(s_S/(s_L - s_S))*(s_L*rho_L*xi_field_L(i) & - & - rho_L*vel_L(dir_idx(1))*xi_field_L(i)) + xi_P*(s_S/(s_R - s_S)) & - & *(s_R*rho_R*xi_field_R(i) - rho_R*vel_R(dir_idx(1))*xi_field_R(i)) + flux_rs${XYZ}$_vf(j, k, l, xibeg - 1 + i) = & + xi_M*(s_S/(s_L - s_S))*(s_L*rho_L*xi_field_L(i) & + - rho_L*vel_L(dir_idx(1))*xi_field_L(i)) + & + xi_P*(s_S/(s_R - s_S))*(s_R*rho_R*xi_field_R(i) & + - rho_R*vel_R(dir_idx(1))*xi_field_R(i)) end do end if @@ -3213,9 +3596,8 @@ contains Y_L = qL_prim_rs${XYZ}$_vf(j, k, l, i) Y_R = qR_prim_rs${XYZ}$_vf(j + 1, k, l, i) - flux_rs${XYZ}$_vf(j, k, l, & - & i) = xi_M*rho_L*Y_L*(vel_L(dir_idx(1)) + s_M*(xi_L - 1._wp)) & - & + xi_P*rho_R*Y_R*(vel_R(dir_idx(1)) + s_P*(xi_R - 1._wp)) + flux_rs${XYZ}$_vf(j, k, l, i) = xi_M*rho_L*Y_L*(vel_L(dir_idx(1)) + s_M*(xi_L - 1._wp)) & + + xi_P*rho_R*Y_R*(vel_R(dir_idx(1)) + s_P*(xi_R - 1._wp)) flux_src_rs${XYZ}$_vf(j, k, l, i) = 0.0_wp end do end if @@ -3223,19 +3605,23 @@ contains ! Geometrical source flux for cylindrical coordinates #:if (NORM_DIR == 2) if (cyl_coord) then - ! Substituting the advective flux into the inviscid geometrical source flux + !Substituting the advective flux into the inviscid geometrical source flux $:GPU_LOOP(parallelism='[seq]') do i = 1, E_idx flux_gsrc_rs${XYZ}$_vf(j, k, l, i) = flux_rs${XYZ}$_vf(j, k, l, i) end do ! Recalculating the radial momentum geometric source flux - flux_gsrc_rs${XYZ}$_vf(j, k, l, & - & contxe + dir_idx(1)) = xi_M*(rho_L*(vel_L(dir_idx(1)) & - & *vel_L(dir_idx(1)) + s_M*(xi_L*(dir_flg(dir_idx(1))*s_S + (1._wp & - & - dir_flg(dir_idx(1)))*vel_L(dir_idx(1))) - vel_L(dir_idx(1))))) & - & + xi_P*(rho_R*(vel_R(dir_idx(1))*vel_R(dir_idx(1)) & - & + s_P*(xi_R*(dir_flg(dir_idx(1))*s_S + (1._wp & - & - dir_flg(dir_idx(1)))*vel_R(dir_idx(1))) - vel_R(dir_idx(1))))) + flux_gsrc_rs${XYZ}$_vf(j, k, l, contxe + dir_idx(1)) = & + xi_M*(rho_L*(vel_L(dir_idx(1))* & + vel_L(dir_idx(1)) + & + s_M*(xi_L*(dir_flg(dir_idx(1))*s_S + & + (1._wp - dir_flg(dir_idx(1)))* & + vel_L(dir_idx(1))) - vel_L(dir_idx(1))))) & + + xi_P*(rho_R*(vel_R(dir_idx(1))* & + vel_R(dir_idx(1)) + & + s_P*(xi_R*(dir_flg(dir_idx(1))*s_S + & + (1._wp - dir_flg(dir_idx(1)))* & + vel_R(dir_idx(1))) - vel_R(dir_idx(1))))) ! Geometrical source of the void fraction(s) is zero $:GPU_LOOP(parallelism='[seq]') do i = advxb, advxe @@ -3250,16 +3636,22 @@ contains flux_gsrc_rs${XYZ}$_vf(j, k, l, i) = 0._wp end do - flux_gsrc_rs${XYZ}$_vf(j, k, l, & - & momxb + 1) = -xi_M*(rho_L*(vel_L(dir_idx(1))*vel_L(dir_idx(1)) & - & + s_M*(xi_L*(dir_flg(dir_idx(1))*s_S + (1._wp & - & - dir_flg(dir_idx(1)))*vel_L(dir_idx(1))) - vel_L(dir_idx(1))))) & - & - xi_P*(rho_R*(vel_R(dir_idx(1))*vel_R(dir_idx(1)) & - & + s_P*(xi_R*(dir_flg(dir_idx(1))*s_S + (1._wp & - & - dir_flg(dir_idx(1)))*vel_R(dir_idx(1))) - vel_R(dir_idx(1))))) + flux_gsrc_rs${XYZ}$_vf(j, k, l, momxb + 1) = & + -xi_M*(rho_L*(vel_L(dir_idx(1))* & + vel_L(dir_idx(1)) + & + s_M*(xi_L*(dir_flg(dir_idx(1))*s_S + & + (1._wp - dir_flg(dir_idx(1)))* & + vel_L(dir_idx(1))) - vel_L(dir_idx(1))))) & + - xi_P*(rho_R*(vel_R(dir_idx(1))* & + vel_R(dir_idx(1)) + & + s_P*(xi_R*(dir_flg(dir_idx(1))*s_S + & + (1._wp - dir_flg(dir_idx(1)))* & + vel_R(dir_idx(1))) - vel_R(dir_idx(1))))) flux_gsrc_rs${XYZ}$_vf(j, k, l, momxe) = flux_rs${XYZ}$_vf(j, k, l, momxb + 1) + end if #:endif + end do end do end do @@ -3271,93 +3663,120 @@ contains if (viscous .or. dummy) then if (weno_Re_flux) then - call s_compute_viscous_source_flux(qL_prim_vf(momxb:momxe), dqL_prim_dx_vf(momxb:momxe), & - & dqL_prim_dy_vf(momxb:momxe), dqL_prim_dz_vf(momxb:momxe), & - & qR_prim_vf(momxb:momxe), dqR_prim_dx_vf(momxb:momxe), & - & dqR_prim_dy_vf(momxb:momxe), dqR_prim_dz_vf(momxb:momxe), flux_src_vf, & - & norm_dir, ix, iy, iz) + call s_compute_viscous_source_flux( & + qL_prim_vf(momxb:momxe), & + dqL_prim_dx_vf(momxb:momxe), & + dqL_prim_dy_vf(momxb:momxe), & + dqL_prim_dz_vf(momxb:momxe), & + qR_prim_vf(momxb:momxe), & + dqR_prim_dx_vf(momxb:momxe), & + dqR_prim_dy_vf(momxb:momxe), & + dqR_prim_dz_vf(momxb:momxe), & + flux_src_vf, norm_dir, ix, iy, iz) else - call s_compute_viscous_source_flux(q_prim_vf(momxb:momxe), dqL_prim_dx_vf(momxb:momxe), & - & dqL_prim_dy_vf(momxb:momxe), dqL_prim_dz_vf(momxb:momxe), & - & q_prim_vf(momxb:momxe), dqR_prim_dx_vf(momxb:momxe), & - & dqR_prim_dy_vf(momxb:momxe), dqR_prim_dz_vf(momxb:momxe), flux_src_vf, & - & norm_dir, ix, iy, iz) + call s_compute_viscous_source_flux( & + q_prim_vf(momxb:momxe), & + dqL_prim_dx_vf(momxb:momxe), & + dqL_prim_dy_vf(momxb:momxe), & + dqL_prim_dz_vf(momxb:momxe), & + q_prim_vf(momxb:momxe), & + dqR_prim_dx_vf(momxb:momxe), & + dqR_prim_dy_vf(momxb:momxe), & + dqR_prim_dz_vf(momxb:momxe), & + flux_src_vf, norm_dir, ix, iy, iz) end if end if if (surface_tension) then - call s_compute_capillary_source_flux(vel_src_rsx_vf, vel_src_rsy_vf, vel_src_rsz_vf, flux_src_vf, norm_dir, isx, isy, & - & isz) + call s_compute_capillary_source_flux( & + vel_src_rsx_vf, & + vel_src_rsy_vf, & + vel_src_rsz_vf, & + flux_src_vf, & + norm_dir, isx, isy, isz) end if - call s_finalize_riemann_solver(flux_vf, flux_src_vf, flux_gsrc_vf, norm_dir) + call s_finalize_riemann_solver(flux_vf, flux_src_vf, & + flux_gsrc_vf, & + norm_dir) end subroutine s_hllc_riemann_solver - !> HLLD Riemann solver for MHD, Miyoshi & Kusano JCP (2005) - subroutine s_hlld_riemann_solver(qL_prim_rsx_vf, qL_prim_rsy_vf, qL_prim_rsz_vf, dqL_prim_dx_vf, dqL_prim_dy_vf, & - - & dqL_prim_dz_vf, qL_prim_vf, qR_prim_rsx_vf, qR_prim_rsy_vf, qR_prim_rsz_vf, dqR_prim_dx_vf, dqR_prim_dy_vf, & - & dqR_prim_dz_vf, qR_prim_vf, q_prim_vf, flux_vf, flux_src_vf, flux_gsrc_vf, norm_dir, ix, iy, iz) + !> HLLD Riemann solver resolves 5 of the 7 waves of MHD equations: + !! 1 entropy wave, 2 Alfvén waves, 2 fast magnetosonic waves. + subroutine s_hlld_riemann_solver(qL_prim_rsx_vf, qL_prim_rsy_vf, qL_prim_rsz_vf, & + dqL_prim_dx_vf, dqL_prim_dy_vf, dqL_prim_dz_vf, & + qL_prim_vf, & + qR_prim_rsx_vf, qR_prim_rsy_vf, qR_prim_rsz_vf, & + dqR_prim_dx_vf, dqR_prim_dy_vf, dqR_prim_dz_vf, & + qR_prim_vf, & + q_prim_vf, & + flux_vf, flux_src_vf, flux_gsrc_vf, & + norm_dir, ix, iy, iz) + + real(wp), dimension(idwbuff(1)%beg:, idwbuff(2)%beg:, idwbuff(3)%beg:, 1:), intent(inout) :: qL_prim_rsx_vf, qL_prim_rsy_vf, qL_prim_rsz_vf, & + qR_prim_rsx_vf, qR_prim_rsy_vf, qR_prim_rsz_vf + + type(scalar_field), allocatable, dimension(:), intent(inout) :: dqL_prim_dx_vf, dqR_prim_dx_vf, & + dqL_prim_dy_vf, dqR_prim_dy_vf, & + dqL_prim_dz_vf, dqR_prim_dz_vf - real(wp), dimension(idwbuff(1)%beg:,idwbuff(2)%beg:,idwbuff(3)%beg:,1:), intent(inout) :: qL_prim_rsx_vf, qL_prim_rsy_vf, & - & qL_prim_rsz_vf, qR_prim_rsx_vf, qR_prim_rsy_vf, qR_prim_rsz_vf + type(scalar_field), allocatable, dimension(:), intent(inout) :: qL_prim_vf, qR_prim_vf - type(scalar_field), allocatable, dimension(:), intent(inout) :: dqL_prim_dx_vf, dqR_prim_dx_vf, dqL_prim_dy_vf, & - & dqR_prim_dy_vf, dqL_prim_dz_vf, dqR_prim_dz_vf + type(scalar_field), dimension(sys_size), intent(in) :: q_prim_vf + type(scalar_field), dimension(sys_size), intent(inout) :: flux_vf, flux_src_vf, flux_gsrc_vf - type(scalar_field), allocatable, dimension(:), intent(inout) :: qL_prim_vf, qR_prim_vf - type(scalar_field), dimension(sys_size), intent(in) :: q_prim_vf - type(scalar_field), dimension(sys_size), intent(inout) :: flux_vf, flux_src_vf, flux_gsrc_vf - integer, intent(in) :: norm_dir - type(int_bounds_info), intent(in) :: ix, iy, iz + integer, intent(in) :: norm_dir + type(int_bounds_info), intent(in) :: ix, iy, iz ! Local variables: - #:if not MFC_CASE_OPTIMIZATION and USING_AMD real(wp), dimension(3) :: alpha_L, alpha_R, alpha_rho_L, alpha_rho_R #:else real(wp), dimension(num_fluids) :: alpha_L, alpha_R, alpha_rho_L, alpha_rho_R #:endif type(riemann_states_vec3) :: vel - type(riemann_states) :: rho, pres, E, H_no_mag - type(riemann_states) :: gamma, pi_inf, qv - type(riemann_states) :: vel_rms + type(riemann_states) :: rho, pres, E, H_no_mag + type(riemann_states) :: gamma, pi_inf, qv + type(riemann_states) :: vel_rms + type(riemann_states_vec3) :: B - type(riemann_states) :: c, c_fast, pres_mag + type(riemann_states) :: c, c_fast, pres_mag ! HLLD speeds and intermediate state variables: - real(wp) :: s_L, s_R, s_M, s_starL, s_starR - real(wp) :: pTot_L, pTot_R, p_star, rhoL_star, rhoR_star, E_starL, E_starR + real(wp) :: s_L, s_R, s_M, s_starL, s_starR + real(wp) :: pTot_L, pTot_R, p_star, rhoL_star, rhoR_star, E_starL, E_starR + real(wp), dimension(7) :: U_L, U_R, U_starL, U_starR, U_doubleL, U_doubleR real(wp), dimension(7) :: F_L, F_R, F_starL, F_starR, F_hlld - ! Indices for U and F: (rho, rho*vel(1), rho*vel(2), rho*vel(3), By, Bz, E) Note: vel and B are permutated, so vel(1) is the - ! normal velocity, and x is the normal direction Note: Bx is omitted as the magnetic flux is always zero in the normal - ! direction + ! Indices for U and F: (rho, rho*vel(1), rho*vel(2), rho*vel(3), By, Bz, E) + ! Note: vel and B are permutated, so vel(1) is the normal velocity, and x is the normal direction + ! Note: Bx is omitted as the magnetic flux is always zero in the normal direction real(wp) :: sqrt_rhoL_star, sqrt_rhoR_star, denom_ds, sign_Bx real(wp) :: vL_star, vR_star, wL_star, wR_star real(wp) :: v_double, w_double, By_double, Bz_double, E_doubleL, E_doubleR, E_double - integer :: i, j, k, l - call s_populate_riemann_states_variables_buffers(qL_prim_rsx_vf, qL_prim_rsy_vf, qL_prim_rsz_vf, dqL_prim_dx_vf, & - & dqL_prim_dy_vf, dqL_prim_dz_vf, qR_prim_rsx_vf, qR_prim_rsy_vf, qR_prim_rsz_vf, dqR_prim_dx_vf, dqR_prim_dy_vf, & - & dqR_prim_dz_vf, norm_dir, ix, iy, iz) + integer :: i, j, k, l - call s_initialize_riemann_solver(flux_src_vf, norm_dir) + call s_populate_riemann_states_variables_buffers( & + qL_prim_rsx_vf, qL_prim_rsy_vf, qL_prim_rsz_vf, dqL_prim_dx_vf, & + dqL_prim_dy_vf, dqL_prim_dz_vf, & + qR_prim_rsx_vf, qR_prim_rsy_vf, qR_prim_rsz_vf, dqR_prim_dx_vf, & + dqR_prim_dy_vf, dqR_prim_dz_vf, & + norm_dir, ix, iy, iz) + + call s_initialize_riemann_solver( & + flux_src_vf, norm_dir) #:for NORM_DIR, XYZ in [(1, 'x'), (2, 'y'), (3, 'z')] if (norm_dir == ${NORM_DIR}$) then - $:GPU_PARALLEL_LOOP(collapse=3, private='[alpha_rho_L, alpha_rho_R, vel, alpha_L, alpha_R, rho, pres, E, & - & H_no_mag, gamma, pi_inf, qv, vel_rms, B, c, c_fast, pres_mag, U_L, U_R, U_starL, U_starR, & - & U_doubleL, U_doubleR, F_L, F_R, F_starL, F_starR, F_hlld, s_L, s_R, s_M, s_starL, s_starR, & - & pTot_L, pTot_R, p_star, rhoL_star, rhoR_star, E_starL, E_starR, sqrt_rhoL_star, & - & sqrt_rhoR_star, denom_ds, sign_Bx, vL_star, vR_star, wL_star, wR_star, v_double, w_double, & - & By_double, Bz_double, E_doubleL, E_doubleR, E_double]', copyin='[norm_dir]') + $:GPU_PARALLEL_LOOP(collapse=3, private='[alpha_rho_L, alpha_rho_R, vel, alpha_L, alpha_R, rho, pres,E, H_no_mag, gamma, pi_inf, qv, vel_rms, B, c, c_fast, pres_mag, U_L, U_R, U_starL, U_starR, U_doubleL, U_doubleR, F_L, F_R, F_starL, F_starR, F_hlld, s_L, s_R, s_M, s_starL, s_starR, pTot_L, pTot_R, p_star, rhoL_star, rhoR_star, E_starL, E_starR, sqrt_rhoL_star, sqrt_rhoR_star, denom_ds, sign_Bx, vL_star, vR_star, wL_star, wR_star, v_double, w_double, By_double, Bz_double, E_doubleL, E_doubleR, E_double]', copyin='[norm_dir]') do l = is3%beg, is3%end do k = is2%beg, is2%end do j = is1%beg, is1%end + ! (1) Extract the left/right primitive states do i = 1, contxe alpha_rho_L(i) = qL_prim_rs${XYZ}$_vf(j, k, l, i) @@ -3383,18 +3802,16 @@ contains ! NOTE: unlike HLL, Bx, By, Bz are permutated by dir_idx for simpler logic if (mhd) then - if (n == 0) then ! 1D: constant Bx; By, Bz as variables; only in x so not permutated - B%L = [Bx0, qL_prim_rs${XYZ}$_vf(j, k, l, B_idx%beg), qL_prim_rs${XYZ}$_vf(j, k, l, & - & B_idx%beg + 1)] - B%R = [Bx0, qR_prim_rs${XYZ}$_vf(j + 1, k, l, B_idx%beg), qR_prim_rs${XYZ}$_vf(j + 1, k, l, & - & B_idx%beg + 1)] - else ! 2D/3D: Bx, By, Bz as variables - B%L = [qL_prim_rs${XYZ}$_vf(j, k, l, B_idx%beg + dir_idx(1) - 1), qL_prim_rs${XYZ}$_vf(j, k, & - & l, B_idx%beg + dir_idx(2) - 1), qL_prim_rs${XYZ}$_vf(j, k, l, & - & B_idx%beg + dir_idx(3) - 1)] + if (n == 0) then ! 1D: constant Bx; By, Bz as variables; only in x so not permutated + B%L = [Bx0, qL_prim_rs${XYZ}$_vf(j, k, l, B_idx%beg), qL_prim_rs${XYZ}$_vf(j, k, l, B_idx%beg + 1)] + B%R = [Bx0, qR_prim_rs${XYZ}$_vf(j + 1, k, l, B_idx%beg), qR_prim_rs${XYZ}$_vf(j + 1, k, l, B_idx%beg + 1)] + else ! 2D/3D: Bx, By, Bz as variables + B%L = [qL_prim_rs${XYZ}$_vf(j, k, l, B_idx%beg + dir_idx(1) - 1), & + qL_prim_rs${XYZ}$_vf(j, k, l, B_idx%beg + dir_idx(2) - 1), & + qL_prim_rs${XYZ}$_vf(j, k, l, B_idx%beg + dir_idx(3) - 1)] B%R = [qR_prim_rs${XYZ}$_vf(j + 1, k, l, B_idx%beg + dir_idx(1) - 1), & - & qR_prim_rs${XYZ}$_vf(j + 1, k, l, B_idx%beg + dir_idx(2) - 1), & - & qR_prim_rs${XYZ}$_vf(j + 1, k, l, B_idx%beg + dir_idx(3) - 1)] + qR_prim_rs${XYZ}$_vf(j + 1, k, l, B_idx%beg + dir_idx(2) - 1), & + qR_prim_rs${XYZ}$_vf(j + 1, k, l, B_idx%beg + dir_idx(3) - 1)] end if end if @@ -3417,16 +3834,13 @@ contains pres_mag%L = 0.5_wp*sum(B%L**2._wp) pres_mag%R = 0.5_wp*sum(B%R**2._wp) E%L = gamma%L*pres%L + pi_inf%L + 0.5_wp*rho%L*vel_rms%L + qv%L + pres_mag%L - E%R = gamma%R*pres%R + pi_inf%R + 0.5_wp*rho%R*vel_rms%R + qv%R + pres_mag%R ! includes magnetic energy + E%R = gamma%R*pres%R + pi_inf%R + 0.5_wp*rho%R*vel_rms%R + qv%R + pres_mag%R ! includes magnetic energy H_no_mag%L = (E%L + pres%L - pres_mag%L)/rho%L - H_no_mag%R = (E%R + pres%R - pres_mag%R) & - & /rho%R ! stagnation enthalpy here excludes magnetic energy (only used to find speed of sound) + H_no_mag%R = (E%R + pres%R - pres_mag%R)/rho%R ! stagnation enthalpy here excludes magnetic energy (only used to find speed of sound) ! (2) Compute fast wave speeds - call s_compute_speed_of_sound(pres%L, rho%L, gamma%L, pi_inf%L, H_no_mag%L, alpha_L, vel_rms%L, & - & 0._wp, c%L, qv%L) - call s_compute_speed_of_sound(pres%R, rho%R, gamma%R, pi_inf%R, H_no_mag%R, alpha_R, vel_rms%R, & - & 0._wp, c%R, qv%R) + call s_compute_speed_of_sound(pres%L, rho%L, gamma%L, pi_inf%L, H_no_mag%L, alpha_L, vel_rms%L, 0._wp, c%L, qv%L) + call s_compute_speed_of_sound(pres%R, rho%R, gamma%R, pi_inf%R, H_no_mag%R, alpha_R, vel_rms%R, 0._wp, c%R, qv%R) call s_compute_fast_magnetosonic_speed(rho%L, c%L, B%L, norm_dir, c_fast%L, H_no_mag%L) call s_compute_fast_magnetosonic_speed(rho%R, c%R, B%R, norm_dir, c_fast%R, H_no_mag%R) @@ -3437,8 +3851,9 @@ contains pTot_L = pres%L + pres_mag%L pTot_R = pres%R + pres_mag%R - s_M = (((s_R - vel%R(1))*rho%R*vel%R(1) - (s_L - vel%L(1))*rho%L*vel%L(1) - pTot_R + pTot_L)/((s_R & - & - vel%R(1))*rho%R - (s_L - vel%L(1))*rho%L)) + s_M = (((s_R - vel%R(1))*rho%R*vel%R(1) - & + (s_L - vel%L(1))*rho%L*vel%L(1) - pTot_R + pTot_L)/ & + ((s_R - vel%R(1))*rho%R - (s_L - vel%L(1))*rho%L)) ! (4) Compute star state variables rhoL_star = rho%L*(s_L - vel%L(1))/(s_L - s_M) @@ -3465,39 +3880,33 @@ contains F_R(3:4) = U_R(2)*vel%R(2:3) - B%R(1)*B%R(2:3) F_R(5:6) = vel%R(1)*B%R(2:3) - vel%R(2:3)*B%R(1) F_R(7) = (E%R + pTot_R)*vel%R(1) - B%R(1)*(vel%R(1)*B%R(1) + vel%R(2)*B%R(2) + vel%R(3)*B%R(3)) - ! HLLD star-state fluxes via HLL jump relation + ! Compute the star flux using HLL relation F_starL = F_L + s_L*(U_starL - U_L) F_starR = F_R + s_R*(U_starR - U_R) - ! Alfven wave speeds bounding the rotational discontinuities + ! Compute the rotational (Alfvén) speeds s_starL = s_M - abs(B%L(1))/sqrt(rhoL_star) s_starR = s_M + abs(B%L(1))/sqrt(rhoR_star) - ! HLLD double-star (intermediate) states across rotational discontinuities + ! Compute the double–star states [Miyoshi Eqns. (59)-(62)] sqrt_rhoL_star = sqrt(rhoL_star); sqrt_rhoR_star = sqrt(rhoR_star) vL_star = vel%L(2); wL_star = vel%L(3) vR_star = vel%R(2); wR_star = vel%R(3) - ! (6) Compute the double-star states [Miyoshi Eqns. (59)-(62)] + ! (6) Compute the double–star states [Miyoshi Eqns. (59)-(62)] denom_ds = sqrt_rhoL_star + sqrt_rhoR_star sign_Bx = sign(1._wp, B%L(1)) v_double = (sqrt_rhoL_star*vL_star + sqrt_rhoR_star*vR_star + (B%R(2) - B%L(2))*sign_Bx)/denom_ds w_double = (sqrt_rhoL_star*wL_star + sqrt_rhoR_star*wR_star + (B%R(3) - B%L(3))*sign_Bx)/denom_ds - By_double = (sqrt_rhoL_star*B%R(2) + sqrt_rhoR_star*B%L(2) + sqrt_rhoL_star*sqrt_rhoR_star*(vR_star & - & - vL_star)*sign_Bx)/denom_ds - Bz_double = (sqrt_rhoL_star*B%R(3) + sqrt_rhoR_star*B%L(3) + sqrt_rhoL_star*sqrt_rhoR_star*(wR_star & - & - wL_star)*sign_Bx)/denom_ds - - E_doubleL = E_starL - sqrt_rhoL_star*((vL_star*B%L(2) + wL_star*B%L(3)) - (v_double*By_double & - & + w_double*Bz_double))*sign_Bx - E_doubleR = E_starR + sqrt_rhoR_star*((vR_star*B%R(2) + wR_star*B%R(3)) - (v_double*By_double & - & + w_double*Bz_double))*sign_Bx + By_double = (sqrt_rhoL_star*B%R(2) + sqrt_rhoR_star*B%L(2) + sqrt_rhoL_star*sqrt_rhoR_star*(vR_star - vL_star)*sign_Bx)/denom_ds + Bz_double = (sqrt_rhoL_star*B%R(3) + sqrt_rhoR_star*B%L(3) + sqrt_rhoL_star*sqrt_rhoR_star*(wR_star - wL_star)*sign_Bx)/denom_ds + + E_doubleL = E_starL - sqrt_rhoL_star*((vL_star*B%L(2) + wL_star*B%L(3)) - (v_double*By_double + w_double*Bz_double))*sign_Bx + E_doubleR = E_starR + sqrt_rhoR_star*((vR_star*B%R(2) + wR_star*B%R(3)) - (v_double*By_double + w_double*Bz_double))*sign_Bx E_double = 0.5_wp*(E_doubleL + E_doubleR) - U_doubleL = [rhoL_star, rhoL_star*s_M, rhoL_star*v_double, rhoL_star*w_double, By_double, Bz_double, & - & E_double] - U_doubleR = [rhoR_star, rhoR_star*s_M, rhoR_star*v_double, rhoR_star*w_double, By_double, Bz_double, & - & E_double] + U_doubleL = [rhoL_star, rhoL_star*s_M, rhoL_star*v_double, rhoL_star*w_double, By_double, Bz_double, E_double] + U_doubleR = [rhoR_star, rhoR_star*s_M, rhoR_star*v_double, rhoR_star*w_double, By_double, Bz_double, E_double] - ! Select HLLD flux region + ! (11) Choose HLLD flux based on wave-speed regions if (0.0_wp <= s_L) then F_hlld = F_L else if (0.0_wp <= s_starL) then @@ -3512,8 +3921,9 @@ contains F_hlld = F_R end if - ! (12) Write HLLD flux to output arrays - flux_rs${XYZ}$_vf(j, k, l, 1) = F_hlld(1) ! TODO multi-component + ! (12) Reorder and write temporary variables to the flux array + ! Mass + flux_rs${XYZ}$_vf(j, k, l, 1) = F_hlld(1) ! TODO multi-component ! Momentum flux_rs${XYZ}$_vf(j, k, l, contxe + dir_idx(1)) = F_hlld(2) flux_rs${XYZ}$_vf(j, k, l, contxe + dir_idx(2)) = F_hlld(3) @@ -3528,10 +3938,10 @@ contains end if ! Energy flux_rs${XYZ}$_vf(j, k, l, E_idx) = F_hlld(7) - ! Volume fractions + ! Partial fraction $:GPU_LOOP(parallelism='[seq]') do i = advxb, advxe - flux_rs${XYZ}$_vf(j, k, l, i) = 0._wp ! TODO multi-component (zero for now) + flux_rs${XYZ}$_vf(j, k, l, i) = 0._wp ! TODO multi-component (zero for now) end do flux_src_rs${XYZ}$_vf(j, k, l, advxb) = 0._wp @@ -3542,15 +3952,18 @@ contains end if #:endfor - call s_finalize_riemann_solver(flux_vf, flux_src_vf, flux_gsrc_vf, norm_dir) - + call s_finalize_riemann_solver(flux_vf, flux_src_vf, flux_gsrc_vf, & + norm_dir) end subroutine s_hlld_riemann_solver - !> Initialize the Riemann solvers module + !> The computation of parameters, the allocation of memory, + !! the association of pointers and/or the execution of any + !! other procedures that are necessary to setup the module. impure subroutine s_initialize_riemann_solvers_module - ! Allocating the variables that will be utilized to formulate the left, right, and average states of the Riemann problem, as - ! well the Riemann problem solution + ! Allocating the variables that will be utilized to formulate the + ! left, right, and average states of the Riemann problem, as well + ! the Riemann problem solution integer :: i, j @:ALLOCATE(Gs_rs(1:num_fluids)) @@ -3570,24 +3983,34 @@ contains Res_gs(i, j) = fluid_pp(Re_idx(i, j))%Re(i) end do end do - $:GPU_UPDATE(device='[Res_gs, Re_idx, Re_size]') + $:GPU_UPDATE(device='[Res_gs,Re_idx,Re_size]') end if - $:GPU_ENTER_DATA(copyin='[is1, is2, is3, isx, isy, isz]') + $:GPU_ENTER_DATA(copyin='[is1,is2,is3,isx,isy,isz]') is1%beg = -1; is2%beg = 0; is3%beg = 0 is1%end = m; is2%end = n; is3%end = p - @:ALLOCATE(flux_rsx_vf(is1%beg:is1%end, is2%beg:is2%end, is3%beg:is3%end, 1:sys_size)) - @:ALLOCATE(flux_gsrc_rsx_vf(is1%beg:is1%end, is2%beg:is2%end, is3%beg:is3%end, 1:sys_size)) - @:ALLOCATE(flux_src_rsx_vf(is1%beg:is1%end, is2%beg:is2%end, is3%beg:is3%end, advxb:sys_size)) - @:ALLOCATE(vel_src_rsx_vf(is1%beg:is1%end, is2%beg:is2%end, is3%beg:is3%end, 1:num_vels)) + @:ALLOCATE(flux_rsx_vf(is1%beg:is1%end, & + is2%beg:is2%end, & + is3%beg:is3%end, 1:sys_size)) + @:ALLOCATE(flux_gsrc_rsx_vf(is1%beg:is1%end, & + is2%beg:is2%end, & + is3%beg:is3%end, 1:sys_size)) + @:ALLOCATE(flux_src_rsx_vf(is1%beg:is1%end, & + is2%beg:is2%end, & + is3%beg:is3%end, advxb:sys_size)) + @:ALLOCATE(vel_src_rsx_vf(is1%beg:is1%end, & + is2%beg:is2%end, & + is3%beg:is3%end, 1:num_vels)) if (qbmm) then @:ALLOCATE(mom_sp_rsx_vf(is1%beg:is1%end + 1, is2%beg:is2%end, is3%beg:is3%end, 1:4)) end if if (viscous) then - @:ALLOCATE(Re_avg_rsx_vf(is1%beg:is1%end, is2%beg:is2%end, is3%beg:is3%end, 1:2)) + @:ALLOCATE(Re_avg_rsx_vf(is1%beg:is1%end, & + is2%beg:is2%end, & + is3%beg:is3%end, 1:2)) end if if (n == 0) return @@ -3595,17 +4018,27 @@ contains is1%beg = -1; is2%beg = 0; is3%beg = 0 is1%end = n; is2%end = m; is3%end = p - @:ALLOCATE(flux_rsy_vf(is1%beg:is1%end, is2%beg:is2%end, is3%beg:is3%end, 1:sys_size)) - @:ALLOCATE(flux_gsrc_rsy_vf(is1%beg:is1%end, is2%beg:is2%end, is3%beg:is3%end, 1:sys_size)) - @:ALLOCATE(flux_src_rsy_vf(is1%beg:is1%end, is2%beg:is2%end, is3%beg:is3%end, advxb:sys_size)) - @:ALLOCATE(vel_src_rsy_vf(is1%beg:is1%end, is2%beg:is2%end, is3%beg:is3%end, 1:num_vels)) + @:ALLOCATE(flux_rsy_vf(is1%beg:is1%end, & + is2%beg:is2%end, & + is3%beg:is3%end, 1:sys_size)) + @:ALLOCATE(flux_gsrc_rsy_vf(is1%beg:is1%end, & + is2%beg:is2%end, & + is3%beg:is3%end, 1:sys_size)) + @:ALLOCATE(flux_src_rsy_vf(is1%beg:is1%end, & + is2%beg:is2%end, & + is3%beg:is3%end, advxb:sys_size)) + @:ALLOCATE(vel_src_rsy_vf(is1%beg:is1%end, & + is2%beg:is2%end, & + is3%beg:is3%end, 1:num_vels)) if (qbmm) then @:ALLOCATE(mom_sp_rsy_vf(is1%beg:is1%end + 1, is2%beg:is2%end, is3%beg:is3%end, 1:4)) end if if (viscous) then - @:ALLOCATE(Re_avg_rsy_vf(is1%beg:is1%end, is2%beg:is2%end, is3%beg:is3%end, 1:2)) + @:ALLOCATE(Re_avg_rsy_vf(is1%beg:is1%end, & + is2%beg:is2%end, & + is3%beg:is3%end, 1:2)) end if if (p == 0) return @@ -3613,41 +4046,82 @@ contains is1%beg = -1; is2%beg = 0; is3%beg = 0 is1%end = p; is2%end = n; is3%end = m - @:ALLOCATE(flux_rsz_vf(is1%beg:is1%end, is2%beg:is2%end, is3%beg:is3%end, 1:sys_size)) - @:ALLOCATE(flux_gsrc_rsz_vf(is1%beg:is1%end, is2%beg:is2%end, is3%beg:is3%end, 1:sys_size)) - @:ALLOCATE(flux_src_rsz_vf(is1%beg:is1%end, is2%beg:is2%end, is3%beg:is3%end, advxb:sys_size)) - @:ALLOCATE(vel_src_rsz_vf(is1%beg:is1%end, is2%beg:is2%end, is3%beg:is3%end, 1:num_vels)) + @:ALLOCATE(flux_rsz_vf(is1%beg:is1%end, & + is2%beg:is2%end, & + is3%beg:is3%end, 1:sys_size)) + @:ALLOCATE(flux_gsrc_rsz_vf(is1%beg:is1%end, & + is2%beg:is2%end, & + is3%beg:is3%end, 1:sys_size)) + @:ALLOCATE(flux_src_rsz_vf(is1%beg:is1%end, & + is2%beg:is2%end, & + is3%beg:is3%end, advxb:sys_size)) + @:ALLOCATE(vel_src_rsz_vf(is1%beg:is1%end, & + is2%beg:is2%end, & + is3%beg:is3%end, 1:num_vels)) if (qbmm) then @:ALLOCATE(mom_sp_rsz_vf(is1%beg:is1%end + 1, is2%beg:is2%end, is3%beg:is3%end, 1:4)) end if if (viscous) then - @:ALLOCATE(Re_avg_rsz_vf(is1%beg:is1%end, is2%beg:is2%end, is3%beg:is3%end, 1:2)) + @:ALLOCATE(Re_avg_rsz_vf(is1%beg:is1%end, & + is2%beg:is2%end, & + is3%beg:is3%end, 1:2)) end if end subroutine s_initialize_riemann_solvers_module - !> Populate the left and right Riemann state variable buffers based on boundary conditions - subroutine s_populate_riemann_states_variables_buffers(qL_prim_rsx_vf, qL_prim_rsy_vf, qL_prim_rsz_vf, dqL_prim_dx_vf, & - - & dqL_prim_dy_vf, dqL_prim_dz_vf, qR_prim_rsx_vf, qR_prim_rsy_vf, qR_prim_rsz_vf, dqR_prim_dx_vf, dqR_prim_dy_vf, & - & dqR_prim_dz_vf, norm_dir, ix, iy, iz) - - real(wp), dimension(idwbuff(1)%beg:,idwbuff(2)%beg:,idwbuff(3)%beg:,1:), intent(inout) :: qL_prim_rsx_vf, qL_prim_rsy_vf, & - & qL_prim_rsz_vf, qR_prim_rsx_vf, qR_prim_rsy_vf, qR_prim_rsz_vf - - type(scalar_field), allocatable, dimension(:), intent(inout) :: dqL_prim_dx_vf, dqR_prim_dx_vf, dqL_prim_dy_vf, & - & dqR_prim_dy_vf, dqL_prim_dz_vf, dqR_prim_dz_vf - - integer, intent(in) :: norm_dir + !> The purpose of this subroutine is to populate the buffers + !! of the left and right Riemann states variables, depending + !! on the boundary conditions. + !! @param qL_prim_rsx_vf Left WENO-reconstructed cell-boundary values (x-dir) + !! @param qL_prim_rsy_vf Left WENO-reconstructed cell-boundary values (y-dir) + !! @param qL_prim_rsz_vf Left WENO-reconstructed cell-boundary values (z-dir) + !! @param dqL_prim_dx_vf The left WENO-reconstructed cell-boundary values of the + !! first-order x-dir spatial derivatives + !! @param dqL_prim_dy_vf The left WENO-reconstructed cell-boundary values of the + !! first-order y-dir spatial derivatives + !! @param dqL_prim_dz_vf The left WENO-reconstructed cell-boundary values of the + !! first-order z-dir spatial derivatives + !! @param qR_prim_rsx_vf Right WENO-reconstructed cell-boundary values (x-dir) + !! @param qR_prim_rsy_vf Right WENO-reconstructed cell-boundary values (y-dir) + !! @param qR_prim_rsz_vf Right WENO-reconstructed cell-boundary values (z-dir) + !! @param dqR_prim_dx_vf The right WENO-reconstructed cell-boundary values of the + !! first-order x-dir spatial derivatives + !! @param dqR_prim_dy_vf The right WENO-reconstructed cell-boundary values of the + !! first-order y-dir spatial derivatives + !! @param dqR_prim_dz_vf The right WENO-reconstructed cell-boundary values of the + !! first-order z-dir spatial derivatives + !! @param norm_dir Dir. splitting direction + !! @param ix Index bounds in the x-dir + !! @param iy Index bounds in the y-dir + !! @param iz Index bounds in the z-dir + subroutine s_populate_riemann_states_variables_buffers( & + qL_prim_rsx_vf, qL_prim_rsy_vf, qL_prim_rsz_vf, dqL_prim_dx_vf, & + dqL_prim_dy_vf, & + dqL_prim_dz_vf, & + qR_prim_rsx_vf, qR_prim_rsy_vf, qR_prim_rsz_vf, dqR_prim_dx_vf, & + dqR_prim_dy_vf, & + dqR_prim_dz_vf, & + norm_dir, ix, iy, iz) + + real(wp), dimension(idwbuff(1)%beg:, idwbuff(2)%beg:, idwbuff(3)%beg:, 1:), intent(inout) :: qL_prim_rsx_vf, qL_prim_rsy_vf, qL_prim_rsz_vf, qR_prim_rsx_vf, qR_prim_rsy_vf, qR_prim_rsz_vf + + type(scalar_field), & + allocatable, dimension(:), & + intent(inout) :: dqL_prim_dx_vf, dqR_prim_dx_vf, & + dqL_prim_dy_vf, dqR_prim_dy_vf, & + dqL_prim_dz_vf, dqR_prim_dz_vf + + integer, intent(in) :: norm_dir type(int_bounds_info), intent(in) :: ix, iy, iz - integer :: i, j, k, l !< Generic loop iterator + + integer :: i, j, k, l !< Generic loop iterator if (norm_dir == 1) then is1 = ix; is2 = iy; is3 = iz dir_idx = (/1, 2, 3/); dir_flg = (/1._wp, 0._wp, 0._wp/) - else if (norm_dir == 2) then + elseif (norm_dir == 2) then is1 = iy; is2 = ix; is3 = iz dir_idx = (/2, 1, 3/); dir_flg = (/0._wp, 1._wp, 0._wp/) else @@ -3655,7 +4129,7 @@ contains dir_idx = (/3, 1, 2/); dir_flg = (/0._wp, 0._wp, 1._wp/) end if - $:GPU_UPDATE(device='[is1, is2, is3]') + $:GPU_UPDATE(device='[is1,is2,is3]') if (elasticity) then if (norm_dir == 1) then @@ -3669,18 +4143,20 @@ contains isx = ix; isy = iy; isz = iz ! for stuff in the same module - $:GPU_UPDATE(device='[isx, isy, isz]') + $:GPU_UPDATE(device='[isx,isy,isz]') ! for stuff in different modules - $:GPU_UPDATE(device='[dir_idx, dir_flg, dir_idx_tau]') + $:GPU_UPDATE(device='[dir_idx,dir_flg,dir_idx_tau]') ! Population of Buffers in x-direction if (norm_dir == 1) then - if (bc_x%beg == BC_RIEMANN_EXTRAP) then ! Riemann state extrap. BC at beginning + + if (bc_x%beg == BC_RIEMANN_EXTRAP) then ! Riemann state extrap. BC at beginning $:GPU_PARALLEL_LOOP(collapse=3) do i = 1, sys_size do l = is3%beg, is3%end do k = is2%beg, is2%end - qL_prim_rsx_vf(-1, k, l, i) = qR_prim_rsx_vf(0, k, l, i) + qL_prim_rsx_vf(-1, k, l, i) = & + qR_prim_rsx_vf(0, k, l, i) end do end do end do @@ -3691,7 +4167,9 @@ contains do i = momxb, momxe do l = isz%beg, isz%end do k = isy%beg, isy%end - dqL_prim_dx_vf(i)%sf(-1, k, l) = dqR_prim_dx_vf(i)%sf(0, k, l) + + dqL_prim_dx_vf(i)%sf(-1, k, l) = & + dqR_prim_dx_vf(i)%sf(0, k, l) end do end do end do @@ -3702,7 +4180,9 @@ contains do i = momxb, momxe do l = isz%beg, isz%end do k = isy%beg, isy%end - dqL_prim_dy_vf(i)%sf(-1, k, l) = dqR_prim_dy_vf(i)%sf(0, k, l) + + dqL_prim_dy_vf(i)%sf(-1, k, l) = & + dqR_prim_dy_vf(i)%sf(0, k, l) end do end do end do @@ -3713,34 +4193,43 @@ contains do i = momxb, momxe do l = isz%beg, isz%end do k = isy%beg, isy%end - dqL_prim_dz_vf(i)%sf(-1, k, l) = dqR_prim_dz_vf(i)%sf(0, k, l) + + dqL_prim_dz_vf(i)%sf(-1, k, l) = & + dqR_prim_dz_vf(i)%sf(0, k, l) end do end do end do $:END_GPU_PARALLEL_LOOP() end if + end if + end if + end if - if (bc_x%end == BC_RIEMANN_EXTRAP) then ! Riemann state extrap. BC at end + if (bc_x%end == BC_RIEMANN_EXTRAP) then ! Riemann state extrap. BC at end $:GPU_PARALLEL_LOOP(collapse=3) do i = 1, sys_size do l = is3%beg, is3%end do k = is2%beg, is2%end - qR_prim_rsx_vf(m + 1, k, l, i) = qL_prim_rsx_vf(m, k, l, i) + qR_prim_rsx_vf(m + 1, k, l, i) = & + qL_prim_rsx_vf(m, k, l, i) end do end do end do $:END_GPU_PARALLEL_LOOP() if (viscous .or. dummy) then + $:GPU_PARALLEL_LOOP(collapse=3) do i = momxb, momxe do l = isz%beg, isz%end do k = isy%beg, isy%end - dqR_prim_dx_vf(i)%sf(m + 1, k, l) = dqL_prim_dx_vf(i)%sf(m, k, l) + + dqR_prim_dx_vf(i)%sf(m + 1, k, l) = & + dqL_prim_dx_vf(i)%sf(m, k, l) end do end do end do @@ -3751,7 +4240,9 @@ contains do i = momxb, momxe do l = isz%beg, isz%end do k = isy%beg, isy%end - dqR_prim_dy_vf(i)%sf(m + 1, k, l) = dqL_prim_dy_vf(i)%sf(m, k, l) + + dqR_prim_dy_vf(i)%sf(m + 1, k, l) = & + dqL_prim_dy_vf(i)%sf(m, k, l) end do end do end do @@ -3762,36 +4253,45 @@ contains do i = momxb, momxe do l = isz%beg, isz%end do k = isy%beg, isy%end - dqR_prim_dz_vf(i)%sf(m + 1, k, l) = dqL_prim_dz_vf(i)%sf(m, k, l) + + dqR_prim_dz_vf(i)%sf(m + 1, k, l) = & + dqL_prim_dz_vf(i)%sf(m, k, l) end do end do end do $:END_GPU_PARALLEL_LOOP() end if + end if + end if + end if ! END: Population of Buffers in x-direction ! Population of Buffers in y-direction - else if (norm_dir == 2) then - if (bc_y%beg == BC_RIEMANN_EXTRAP) then ! Riemann state extrap. BC at beginning + elseif (norm_dir == 2) then + + if (bc_y%beg == BC_RIEMANN_EXTRAP) then ! Riemann state extrap. BC at beginning $:GPU_PARALLEL_LOOP(collapse=3) do i = 1, sys_size do l = is3%beg, is3%end do k = is2%beg, is2%end - qL_prim_rsy_vf(-1, k, l, i) = qR_prim_rsy_vf(0, k, l, i) + qL_prim_rsy_vf(-1, k, l, i) = & + qR_prim_rsy_vf(0, k, l, i) end do end do end do $:END_GPU_PARALLEL_LOOP() if (viscous .or. dummy) then + $:GPU_PARALLEL_LOOP(collapse=3) do i = momxb, momxe do l = isz%beg, isz%end do j = isx%beg, isx%end - dqL_prim_dx_vf(i)%sf(j, -1, l) = dqR_prim_dx_vf(i)%sf(j, 0, l) + dqL_prim_dx_vf(i)%sf(j, -1, l) = & + dqR_prim_dx_vf(i)%sf(j, 0, l) end do end do end do @@ -3801,7 +4301,8 @@ contains do i = momxb, momxe do l = isz%beg, isz%end do j = isx%beg, isx%end - dqL_prim_dy_vf(i)%sf(j, -1, l) = dqR_prim_dy_vf(i)%sf(j, 0, l) + dqL_prim_dy_vf(i)%sf(j, -1, l) = & + dqR_prim_dy_vf(i)%sf(j, 0, l) end do end do end do @@ -3812,33 +4313,39 @@ contains do i = momxb, momxe do l = isz%beg, isz%end do j = isx%beg, isx%end - dqL_prim_dz_vf(i)%sf(j, -1, l) = dqR_prim_dz_vf(i)%sf(j, 0, l) + dqL_prim_dz_vf(i)%sf(j, -1, l) = & + dqR_prim_dz_vf(i)%sf(j, 0, l) end do end do end do $:END_GPU_PARALLEL_LOOP() end if + end if + end if - if (bc_y%end == BC_RIEMANN_EXTRAP) then ! Riemann state extrap. BC at end + if (bc_y%end == BC_RIEMANN_EXTRAP) then ! Riemann state extrap. BC at end $:GPU_PARALLEL_LOOP(collapse=3) do i = 1, sys_size do l = is3%beg, is3%end do k = is2%beg, is2%end - qR_prim_rsy_vf(n + 1, k, l, i) = qL_prim_rsy_vf(n, k, l, i) + qR_prim_rsy_vf(n + 1, k, l, i) = & + qL_prim_rsy_vf(n, k, l, i) end do end do end do $:END_GPU_PARALLEL_LOOP() if (viscous .or. dummy) then + $:GPU_PARALLEL_LOOP(collapse=3) do i = momxb, momxe do l = isz%beg, isz%end do j = isx%beg, isx%end - dqR_prim_dx_vf(i)%sf(j, n + 1, l) = dqL_prim_dx_vf(i)%sf(j, n, l) + dqR_prim_dx_vf(i)%sf(j, n + 1, l) = & + dqL_prim_dx_vf(i)%sf(j, n, l) end do end do end do @@ -3848,7 +4355,8 @@ contains do i = momxb, momxe do l = isz%beg, isz%end do j = isx%beg, isx%end - dqR_prim_dy_vf(i)%sf(j, n + 1, l) = dqL_prim_dy_vf(i)%sf(j, n, l) + dqR_prim_dy_vf(i)%sf(j, n + 1, l) = & + dqL_prim_dy_vf(i)%sf(j, n, l) end do end do end do @@ -3859,24 +4367,29 @@ contains do i = momxb, momxe do l = isz%beg, isz%end do j = isx%beg, isx%end - dqR_prim_dz_vf(i)%sf(j, n + 1, l) = dqL_prim_dz_vf(i)%sf(j, n, l) + dqR_prim_dz_vf(i)%sf(j, n + 1, l) = & + dqL_prim_dz_vf(i)%sf(j, n, l) end do end do end do $:END_GPU_PARALLEL_LOOP() end if + end if + end if ! END: Population of Buffers in y-direction ! Population of Buffers in z-direction else - if (bc_z%beg == BC_RIEMANN_EXTRAP) then ! Riemann state extrap. BC at beginning + + if (bc_z%beg == BC_RIEMANN_EXTRAP) then ! Riemann state extrap. BC at beginning $:GPU_PARALLEL_LOOP(collapse=3) do i = 1, sys_size do l = is3%beg, is3%end do k = is2%beg, is2%end - qL_prim_rsz_vf(-1, k, l, i) = qR_prim_rsz_vf(0, k, l, i) + qL_prim_rsz_vf(-1, k, l, i) = & + qR_prim_rsz_vf(0, k, l, i) end do end do end do @@ -3887,7 +4400,8 @@ contains do i = momxb, momxe do k = isy%beg, isy%end do j = isx%beg, isx%end - dqL_prim_dx_vf(i)%sf(j, k, -1) = dqR_prim_dx_vf(i)%sf(j, k, 0) + dqL_prim_dx_vf(i)%sf(j, k, -1) = & + dqR_prim_dx_vf(i)%sf(j, k, 0) end do end do end do @@ -3896,7 +4410,8 @@ contains do i = momxb, momxe do k = isy%beg, isy%end do j = isx%beg, isx%end - dqL_prim_dy_vf(i)%sf(j, k, -1) = dqR_prim_dy_vf(i)%sf(j, k, 0) + dqL_prim_dy_vf(i)%sf(j, k, -1) = & + dqR_prim_dy_vf(i)%sf(j, k, 0) end do end do end do @@ -3905,21 +4420,24 @@ contains do i = momxb, momxe do k = isy%beg, isy%end do j = isx%beg, isx%end - dqL_prim_dz_vf(i)%sf(j, k, -1) = dqR_prim_dz_vf(i)%sf(j, k, 0) + dqL_prim_dz_vf(i)%sf(j, k, -1) = & + dqR_prim_dz_vf(i)%sf(j, k, 0) end do end do end do $:END_GPU_PARALLEL_LOOP() end if + end if - if (bc_z%end == BC_RIEMANN_EXTRAP) then ! Riemann state extrap. BC at end + if (bc_z%end == BC_RIEMANN_EXTRAP) then ! Riemann state extrap. BC at end $:GPU_PARALLEL_LOOP(collapse=3) do i = 1, sys_size do l = is3%beg, is3%end do k = is2%beg, is2%end - qR_prim_rsz_vf(p + 1, k, l, i) = qL_prim_rsz_vf(p, k, l, i) + qR_prim_rsz_vf(p + 1, k, l, i) = & + qL_prim_rsz_vf(p, k, l, i) end do end do end do @@ -3930,7 +4448,8 @@ contains do i = momxb, momxe do k = isy%beg, isy%end do j = isx%beg, isx%end - dqR_prim_dx_vf(i)%sf(j, k, p + 1) = dqL_prim_dx_vf(i)%sf(j, k, p) + dqR_prim_dx_vf(i)%sf(j, k, p + 1) = & + dqL_prim_dx_vf(i)%sf(j, k, p) end do end do end do @@ -3940,7 +4459,8 @@ contains do i = momxb, momxe do k = isy%beg, isy%end do j = isx%beg, isx%end - dqR_prim_dy_vf(i)%sf(j, k, p + 1) = dqL_prim_dy_vf(i)%sf(j, k, p) + dqR_prim_dy_vf(i)%sf(j, k, p + 1) = & + dqL_prim_dy_vf(i)%sf(j, k, p) end do end do end do @@ -3950,29 +4470,45 @@ contains do i = momxb, momxe do k = isy%beg, isy%end do j = isx%beg, isx%end - dqR_prim_dz_vf(i)%sf(j, k, p + 1) = dqL_prim_dz_vf(i)%sf(j, k, p) + dqR_prim_dz_vf(i)%sf(j, k, p + 1) = & + dqL_prim_dz_vf(i)%sf(j, k, p) end do end do end do $:END_GPU_PARALLEL_LOOP() end if + end if + end if ! END: Population of Buffers in z-direction end subroutine s_populate_riemann_states_variables_buffers - !> Set up the chosen Riemann solver algorithm for the current direction - subroutine s_initialize_riemann_solver(flux_src_vf, norm_dir) + !> The computation of parameters, the allocation of memory, + !! the association of pointers and/or the execution of any + !! other procedures needed to configure the chosen Riemann + !! solver algorithm. + !! @param flux_src_vf Intra-cell fluxes sources + !! @param norm_dir Dir. splitting direction + subroutine s_initialize_riemann_solver( & + flux_src_vf, & + norm_dir) - type(scalar_field), dimension(sys_size), intent(inout) :: flux_src_vf - integer, intent(in) :: norm_dir - integer :: i, j, k, l !< Generic loop iterators + type(scalar_field), & + dimension(sys_size), & + intent(inout) :: flux_src_vf + + integer, intent(in) :: norm_dir + + integer :: i, j, k, l ! Generic loop iterators ! Reshaping Inputted Data in x-direction if (norm_dir == 1) then + if (viscous .or. (surface_tension) .or. dummy) then + $:GPU_PARALLEL_LOOP(collapse=4) do i = momxb, E_idx do l = is3%beg, is3%end @@ -4017,7 +4553,8 @@ contains end if ! Reshaping Inputted Data in y-direction - else if (norm_dir == 2) then + elseif (norm_dir == 2) then + if (viscous .or. (surface_tension) .or. dummy) then $:GPU_PARALLEL_LOOP(collapse=4) do i = momxb, E_idx @@ -4064,6 +4601,7 @@ contains ! Reshaping Inputted Data in z-direction else + if (viscous .or. (surface_tension) .or. dummy) then $:GPU_PARALLEL_LOOP(collapse=4) do i = momxb, E_idx @@ -4107,79 +4645,95 @@ contains end do $:END_GPU_PARALLEL_LOOP() end if + end if end subroutine s_initialize_riemann_solver - !> Compute cylindrical viscous source flux contributions for momentum and energy - subroutine s_compute_cylindrical_viscous_source_flux(velL_vf, dvelL_dx_vf, dvelL_dy_vf, dvelL_dz_vf, velR_vf, dvelR_dx_vf, & - - & dvelR_dy_vf, dvelR_dz_vf, flux_src_vf, norm_dir, ix, iy, iz) - - type(scalar_field), dimension(num_dims), intent(in) :: velL_vf, velR_vf - type(scalar_field), dimension(num_dims), intent(in) :: dvelL_dx_vf, dvelR_dx_vf - type(scalar_field), dimension(num_dims), intent(in) :: dvelL_dy_vf, dvelR_dy_vf - type(scalar_field), dimension(num_dims), intent(in) :: dvelL_dz_vf, dvelR_dz_vf + !> @brief Computes cylindrical viscous source flux contributions for momentum and energy. + !! Calculates Cartesian components of the stress tensor using averaged velocity derivatives + !! and cylindrical geometric factors, then updates `flux_src_vf`. + !! Assumes x-dir is axial (z_cyl), y-dir is radial (r_cyl), z-dir is azimuthal (theta_cyl for derivatives). + !! @param[in] velL_vf Left boundary velocity (\f$v_x, v_y, v_z\f$) (num_dims scalar_field). + !! @param[in] dvelL_dx_vf Left boundary \f$\partial v_i/\partial x\f$ (num_dims scalar_field). + !! @param[in] dvelL_dy_vf Left boundary \f$\partial v_i/\partial y\f$ (num_dims scalar_field). + !! @param[in] dvelL_dz_vf Left boundary \f$\partial v_i/\partial z\f$ (num_dims scalar_field). + !! @param[in] velR_vf Right boundary velocity (\f$v_x, v_y, v_z\f$) (num_dims scalar_field). + !! @param[in] dvelR_dx_vf Right boundary \f$\partial v_i/\partial x\f$ (num_dims scalar_field). + !! @param[in] dvelR_dy_vf Right boundary \f$\partial v_i/\partial y\f$ (num_dims scalar_field). + !! @param[in] dvelR_dz_vf Right boundary \f$\partial v_i/\partial z\f$ (num_dims scalar_field). + !! @param[inout] flux_src_vf Intercell source flux array to update (sys_size scalar_field). + !! @param[in] norm_dir Interface normal direction (1=x-face, 2=y-face, 3=z-face). + !! @param[in] ix Global X-direction loop bounds (int_bounds_info). + !! @param[in] iy Global Y-direction loop bounds (int_bounds_info). + !! @param[in] iz Global Z-direction loop bounds (int_bounds_info). + subroutine s_compute_cylindrical_viscous_source_flux(velL_vf, & + dvelL_dx_vf, dvelL_dy_vf, dvelL_dz_vf, & + velR_vf, & + dvelR_dx_vf, dvelR_dy_vf, dvelR_dz_vf, & + flux_src_vf, norm_dir, ix, iy, iz) + + type(scalar_field), dimension(num_dims), intent(in) :: velL_vf, velR_vf + type(scalar_field), dimension(num_dims), intent(in) :: dvelL_dx_vf, dvelR_dx_vf + type(scalar_field), dimension(num_dims), intent(in) :: dvelL_dy_vf, dvelR_dy_vf + type(scalar_field), dimension(num_dims), intent(in) :: dvelL_dz_vf, dvelR_dz_vf type(scalar_field), dimension(sys_size), intent(inout) :: flux_src_vf - integer, intent(in) :: norm_dir - type(int_bounds_info), intent(in) :: ix, iy, iz + integer, intent(in) :: norm_dir + type(int_bounds_info), intent(in) :: ix, iy, iz ! Local variables - #:if not MFC_CASE_OPTIMIZATION and USING_AMD - real(wp), dimension(3) :: avg_v_int !< Averaged interface velocity (\f$v_x, v_y, v_z\f$) (grid directions). - real(wp), dimension(3) :: avg_dvdx_int !< Averaged interface \f$\partial v_i/\partial x\f$ (grid dir 1). - real(wp), dimension(3) :: avg_dvdy_int !< Averaged interface \f$\partial v_i/\partial y\f$ (grid dir 2). - real(wp), dimension(3) :: avg_dvdz_int !< Averaged interface \f$\partial v_i/\partial z\f$ (grid dir 3). - real(wp), dimension(3) :: vel_src_int !< Interface velocity (\f$v_1,v_2,v_3\f$) (grid directions) for viscous work. - - !> Shear stress vector (\f$\sigma_{N1}, \sigma_{N2}, \sigma_{N3}\f$) on N-face (grid directions). - real(wp), dimension(3) :: stress_vector_shear + real(wp), dimension(3) :: avg_v_int !!< Averaged interface velocity (\f$v_x, v_y, v_z\f$) (grid directions). + real(wp), dimension(3) :: avg_dvdx_int !!< Averaged interface \f$\partial v_i/\partial x\f$ (grid dir 1). + real(wp), dimension(3) :: avg_dvdy_int !!< Averaged interface \f$\partial v_i/\partial y\f$ (grid dir 2). + real(wp), dimension(3) :: avg_dvdz_int !!< Averaged interface \f$\partial v_i/\partial z\f$ (grid dir 3). + real(wp), dimension(3) :: vel_src_int !!< Interface velocity (\f$v_1,v_2,v_3\f$) (grid directions) for viscous work. + real(wp), dimension(3) :: stress_vector_shear !!< Shear stress vector (\f$\sigma_{N1}, \sigma_{N2}, \sigma_{N3}\f$) on N-face (grid directions). #:else - real(wp), dimension(num_dims) :: avg_v_int !< Averaged interface velocity (\f$v_x, v_y, v_z\f$) (grid directions). - real(wp), dimension(num_dims) :: avg_dvdx_int !< Averaged interface \f$\partial v_i/\partial x\f$ (grid dir 1). - real(wp), dimension(num_dims) :: avg_dvdy_int !< Averaged interface \f$\partial v_i/\partial y\f$ (grid dir 2). - real(wp), dimension(num_dims) :: avg_dvdz_int !< Averaged interface \f$\partial v_i/\partial z\f$ (grid dir 3). - !> Interface velocity (\f$v_1,v_2,v_3\f$) (grid directions) for viscous work. - real(wp), dimension(num_dims) :: vel_src_int - !> Shear stress vector (\f$\sigma_{N1}, \sigma_{N2}, \sigma_{N3}\f$) on N-face (grid directions). - real(wp), dimension(num_dims) :: stress_vector_shear + real(wp), dimension(num_dims) :: avg_v_int !!< Averaged interface velocity (\f$v_x, v_y, v_z\f$) (grid directions). + real(wp), dimension(num_dims) :: avg_dvdx_int !!< Averaged interface \f$\partial v_i/\partial x\f$ (grid dir 1). + real(wp), dimension(num_dims) :: avg_dvdy_int !!< Averaged interface \f$\partial v_i/\partial y\f$ (grid dir 2). + real(wp), dimension(num_dims) :: avg_dvdz_int !!< Averaged interface \f$\partial v_i/\partial z\f$ (grid dir 3). + real(wp), dimension(num_dims) :: vel_src_int !!< Interface velocity (\f$v_1,v_2,v_3\f$) (grid directions) for viscous work. + real(wp), dimension(num_dims) :: stress_vector_shear !!< Shear stress vector (\f$\sigma_{N1}, \sigma_{N2}, \sigma_{N3}\f$) on N-face (grid directions). #:endif - real(wp) :: stress_normal_bulk !< Normal bulk stress component \f$\sigma_{NN}\f$ on N-face. - real(wp) :: Re_s, Re_b !< Effective interface shear and bulk Reynolds numbers. - real(wp) :: r_eff !< Effective radius at interface for cylindrical terms. - real(wp) :: div_v_term_const !< Common term \f$-(2/3)(\nabla \cdot \mathbf{v}) / \text{Re}_s\f$ for shear stress diagonal. - real(wp) :: divergence_cyl !< Full divergence \f$\nabla \cdot \mathbf{v}\f$ in cylindrical coordinates. - integer :: j, k, l !< Loop iterators for \f$x, y, z\f$ grid directions. - integer :: i_vel !< Loop iterator for velocity components. - integer :: idx_rp(3) !< Indices \f$(j,k,l)\f$ of 'right' point for averaging. - - $:GPU_PARALLEL_LOOP(collapse=3, private='[idx_rp, avg_v_int, avg_dvdx_int, avg_dvdy_int, avg_dvdz_int, Re_s, Re_b, & - & vel_src_int, r_eff, divergence_cyl, stress_vector_shear, stress_normal_bulk, div_v_term_const]') + real(wp) :: stress_normal_bulk !!< Normal bulk stress component \f$\sigma_{NN}\f$ on N-face. + + real(wp) :: Re_s, Re_b !!< Effective interface shear and bulk Reynolds numbers. + real(wp) :: r_eff !!< Effective radius at interface for cylindrical terms. + real(wp) :: div_v_term_const !!< Common term \f$-(2/3)(\nabla \cdot \mathbf{v}) / \text{Re}_s\f$ for shear stress diagonal. + real(wp) :: divergence_cyl !!< Full divergence \f$\nabla \cdot \mathbf{v}\f$ in cylindrical coordinates. + + integer :: j, k, l !!< Loop iterators for \f$x, y, z\f$ grid directions. + integer :: i_vel !!< Loop iterator for velocity components. + integer :: idx_rp(3) !!< Indices \f$(j,k,l)\f$ of 'right' point for averaging. + + $:GPU_PARALLEL_LOOP(collapse=3, private='[idx_rp, avg_v_int, avg_dvdx_int, avg_dvdy_int, avg_dvdz_int, Re_s, Re_b, vel_src_int, r_eff, divergence_cyl, stress_vector_shear, stress_normal_bulk, div_v_term_const]') do l = iz%beg, iz%end do k = iy%beg, iy%end do j = ix%beg, ix%end + ! Determine indices for the 'right' state for averaging across the interface idx_rp = [j, k, l] idx_rp(norm_dir) = idx_rp(norm_dir) + 1 - ! Average velocities and their derivatives at the interface For cylindrical: x-dir ~ axial (z_cyl), y-dir ~ - ! radial (r_cyl), z-dir ~ azimuthal (theta_cyl) + ! Average velocities and their derivatives at the interface + ! For cylindrical: x-dir ~ axial (z_cyl), y-dir ~ radial (r_cyl), z-dir ~ azimuthal (theta_cyl) $:GPU_LOOP(parallelism='[seq]') do i_vel = 1, num_dims avg_v_int(i_vel) = 0.5_wp*(velL_vf(i_vel)%sf(j, k, l) + velR_vf(i_vel)%sf(idx_rp(1), idx_rp(2), idx_rp(3))) - avg_dvdx_int(i_vel) = 0.5_wp*(dvelL_dx_vf(i_vel)%sf(j, k, l) + dvelR_dx_vf(i_vel)%sf(idx_rp(1), & - & idx_rp(2), idx_rp(3))) + avg_dvdx_int(i_vel) = 0.5_wp*(dvelL_dx_vf(i_vel)%sf(j, k, l) + & + dvelR_dx_vf(i_vel)%sf(idx_rp(1), idx_rp(2), idx_rp(3))) if (num_dims > 1) then - avg_dvdy_int(i_vel) = 0.5_wp*(dvelL_dy_vf(i_vel)%sf(j, k, l) + dvelR_dy_vf(i_vel)%sf(idx_rp(1), & - & idx_rp(2), idx_rp(3))) + avg_dvdy_int(i_vel) = 0.5_wp*(dvelL_dy_vf(i_vel)%sf(j, k, l) + & + dvelR_dy_vf(i_vel)%sf(idx_rp(1), idx_rp(2), idx_rp(3))) else avg_dvdy_int(i_vel) = 0.0_wp end if if (num_dims > 2) then - avg_dvdz_int(i_vel) = 0.5_wp*(dvelL_dz_vf(i_vel)%sf(j, k, l) + dvelR_dz_vf(i_vel)%sf(idx_rp(1), & - & idx_rp(2), idx_rp(3))) + avg_dvdz_int(i_vel) = 0.5_wp*(dvelL_dz_vf(i_vel)%sf(j, k, l) + & + dvelR_dz_vf(i_vel)%sf(idx_rp(1), idx_rp(2), idx_rp(3))) else avg_dvdz_int(i_vel) = 0.0_wp end if @@ -4187,20 +4741,20 @@ contains ! Get Re numbers and interface velocity for viscous work select case (norm_dir) - case (1) ! x-face (axial face in z_cyl direction) + case (1) ! x-face (axial face in z_cyl direction) Re_s = Re_avg_rsx_vf(j, k, l, 1) Re_b = Re_avg_rsx_vf(j, k, l, 2) - vel_src_int = vel_src_rsx_vf(j, k, l,1:num_dims) + vel_src_int = vel_src_rsx_vf(j, k, l, 1:num_dims) r_eff = y_cc(k) - case (2) ! y-face (radial face in r_cyl direction) + case (2) ! y-face (radial face in r_cyl direction) Re_s = Re_avg_rsy_vf(k, j, l, 1) Re_b = Re_avg_rsy_vf(k, j, l, 2) - vel_src_int = vel_src_rsy_vf(k, j, l,1:num_dims) + vel_src_int = vel_src_rsy_vf(k, j, l, 1:num_dims) r_eff = y_cb(k) - case (3) ! z-face (azimuthal face in theta_cyl direction) + case (3) ! z-face (azimuthal face in theta_cyl direction) Re_s = Re_avg_rsz_vf(l, k, j, 1) Re_b = Re_avg_rsz_vf(l, k, j, 2) - vel_src_int = vel_src_rsz_vf(l, k, j,1:num_dims) + vel_src_int = vel_src_rsz_vf(l, k, j, 1:num_dims) r_eff = y_cc(k) end select @@ -4221,7 +4775,7 @@ contains div_v_term_const = -(2.0_wp/3.0_wp)*divergence_cyl/Re_s select case (norm_dir) - case (1) ! X-face (axial normal, z_cyl) + case (1) ! X-face (axial normal, z_cyl) stress_vector_shear(1) = (2.0_wp*avg_dvdx_int(1))/Re_s + div_v_term_const if (num_dims > 1) then #:if not MFC_CASE_OPTIMIZATION or num_dims > 1 @@ -4233,48 +4787,44 @@ contains stress_vector_shear(3) = (avg_dvdz_int(1)/r_eff + avg_dvdx_int(3))/Re_s #:endif end if - case (2) ! Y-face (radial normal, r_cyl) + case (2) ! Y-face (radial normal, r_cyl) if (num_dims > 1) then #:if not MFC_CASE_OPTIMIZATION or num_dims > 1 stress_vector_shear(1) = (avg_dvdy_int(1) + avg_dvdx_int(2))/Re_s stress_vector_shear(2) = (2.0_wp*avg_dvdy_int(2))/Re_s + div_v_term_const if (num_dims > 2) then #:if not MFC_CASE_OPTIMIZATION or num_dims > 2 - stress_vector_shear(3) = (avg_dvdz_int(2)/r_eff - avg_v_int(3)/r_eff + avg_dvdy_int(3) & - & )/Re_s + stress_vector_shear(3) = (avg_dvdz_int(2)/r_eff - avg_v_int(3)/r_eff + avg_dvdy_int(3))/Re_s #:endif end if #:endif else stress_vector_shear(1) = (2.0_wp*avg_dvdx_int(1))/Re_s + div_v_term_const end if - case (3) ! Z-face (azimuthal normal, theta_cyl) + case (3) ! Z-face (azimuthal normal, theta_cyl) if (num_dims > 2) then #:if not MFC_CASE_OPTIMIZATION or num_dims > 2 stress_vector_shear(1) = (avg_dvdz_int(1)/r_eff + avg_dvdx_int(3))/Re_s stress_vector_shear(2) = (avg_dvdz_int(2)/r_eff - avg_v_int(3)/r_eff + avg_dvdy_int(3))/Re_s - stress_vector_shear(3) = (2.0_wp*(avg_dvdz_int(3)/r_eff + avg_v_int(2)/r_eff))/Re_s & - & + div_v_term_const + stress_vector_shear(3) = (2.0_wp*(avg_dvdz_int(3)/r_eff + avg_v_int(2)/r_eff))/Re_s + div_v_term_const #:endif end if end select $:GPU_LOOP(parallelism='[seq]') do i_vel = 1, num_dims - flux_src_vf(momxb + i_vel - 1)%sf(j, k, l) = flux_src_vf(momxb + i_vel - 1)%sf(j, k, & - & l) - stress_vector_shear(i_vel) - flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, & - & l) - vel_src_int(i_vel)*stress_vector_shear(i_vel) + flux_src_vf(momxb + i_vel - 1)%sf(j, k, l) = flux_src_vf(momxb + i_vel - 1)%sf(j, k, l) - stress_vector_shear(i_vel) + flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, l) - vel_src_int(i_vel)*stress_vector_shear(i_vel) end do end if if (bulk_stress) then stress_normal_bulk = divergence_cyl/Re_b - flux_src_vf(momxb + norm_dir - 1)%sf(j, k, l) = flux_src_vf(momxb + norm_dir - 1)%sf(j, k, & - & l) - stress_normal_bulk + flux_src_vf(momxb + norm_dir - 1)%sf(j, k, l) = flux_src_vf(momxb + norm_dir - 1)%sf(j, k, l) - stress_normal_bulk flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, l) - vel_src_int(norm_dir)*stress_normal_bulk end if + end do end do end do @@ -4282,46 +4832,63 @@ contains end subroutine s_compute_cylindrical_viscous_source_flux - !> Compute Cartesian viscous source flux contributions for momentum and energy - subroutine s_compute_cartesian_viscous_source_flux(dvelL_dx_vf, dvelL_dy_vf, dvelL_dz_vf, dvelR_dx_vf, dvelR_dy_vf, & - - & dvelR_dz_vf, flux_src_vf, norm_dir) + !> @brief Computes Cartesian viscous source flux contributions for momentum and energy. + !! Calculates averaged velocity gradients, gets Re and interface velocities, + !! calls helpers for shear/bulk stress, then updates `flux_src_vf`. + !! @param[in] dvelL_dx_vf Left boundary d(vel)/dx (num_dims scalar_field). + !! @param[in] dvelL_dy_vf Left boundary d(vel)/dy (num_dims scalar_field). + !! @param[in] dvelL_dz_vf Left boundary d(vel)/dz (num_dims scalar_field). + !! @param[in] dvelR_dx_vf Right boundary d(vel)/dx (num_dims scalar_field). + !! @param[in] dvelR_dy_vf Right boundary d(vel)/dy (num_dims scalar_field). + !! @param[in] dvelR_dz_vf Right boundary d(vel)/dz (num_dims scalar_field). + !! @param[inout] flux_src_vf Intercell source flux array to update (sys_size scalar_field). + !! @param[in] norm_dir Interface normal direction (1=x, 2=y, 3=z). + subroutine s_compute_cartesian_viscous_source_flux(dvelL_dx_vf, & + dvelL_dy_vf, & + dvelL_dz_vf, & + dvelR_dx_vf, & + dvelR_dy_vf, & + dvelR_dz_vf, & + flux_src_vf, & + norm_dir) ! Arguments - type(scalar_field), dimension(num_dims), intent(in) :: dvelL_dx_vf, dvelR_dx_vf - type(scalar_field), dimension(num_dims), intent(in) :: dvelL_dy_vf, dvelR_dy_vf - type(scalar_field), dimension(num_dims), intent(in) :: dvelL_dz_vf, dvelR_dz_vf + type(scalar_field), dimension(num_dims), intent(in) :: dvelL_dx_vf, dvelR_dx_vf + type(scalar_field), dimension(num_dims), intent(in) :: dvelL_dy_vf, dvelR_dy_vf + type(scalar_field), dimension(num_dims), intent(in) :: dvelL_dz_vf, dvelR_dz_vf type(scalar_field), dimension(sys_size), intent(inout) :: flux_src_vf - integer, intent(in) :: norm_dir + integer, intent(in) :: norm_dir ! Local variables - #:if not MFC_CASE_OPTIMIZATION and USING_AMD - real(wp), dimension(3, 3) :: vel_grad_avg !< Averaged velocity gradient tensor `d(vel_i)/d(coord_j)`. - real(wp), dimension(3, 3) :: current_tau_shear !< Current shear stress tensor. - real(wp), dimension(3, 3) :: current_tau_bulk !< Current bulk stress tensor. - real(wp), dimension(3) :: vel_src_at_interface !< Interface velocities (u,v,w) for viscous work. + real(wp), dimension(3, 3) :: vel_grad_avg !< Averaged velocity gradient tensor `d(vel_i)/d(coord_j)`. + real(wp), dimension(3, 3) :: current_tau_shear !< Current shear stress tensor. + real(wp), dimension(3, 3) :: current_tau_bulk !< Current bulk stress tensor. + real(wp), dimension(3) :: vel_src_at_interface !< Interface velocities (u,v,w) for viscous work. #:else - real(wp), dimension(num_dims, num_dims) :: vel_grad_avg !< Averaged velocity gradient tensor `d(vel_i)/d(coord_j)`. - real(wp), dimension(num_dims, num_dims) :: current_tau_shear !< Current shear stress tensor. - real(wp), dimension(num_dims, num_dims) :: current_tau_bulk !< Current bulk stress tensor. - real(wp), dimension(num_dims) :: vel_src_at_interface !< Interface velocities (u,v,w) for viscous work. + real(wp), dimension(num_dims, num_dims) :: vel_grad_avg !< Averaged velocity gradient tensor `d(vel_i)/d(coord_j)`. + real(wp), dimension(num_dims, num_dims) :: current_tau_shear !< Current shear stress tensor. + real(wp), dimension(num_dims, num_dims) :: current_tau_bulk !< Current bulk stress tensor. + real(wp), dimension(num_dims) :: vel_src_at_interface !< Interface velocities (u,v,w) for viscous work. #:endif - integer, dimension(3) :: idx_right_phys !< Physical (j,k,l) indices for right state. - real(wp) :: Re_shear !< Interface shear Reynolds number. - real(wp) :: Re_bulk !< Interface bulk Reynolds number. - integer :: j_loop !< Physical x-index loop iterator. - integer :: k_loop !< Physical y-index loop iterator. - integer :: l_loop !< Physical z-index loop iterator. - integer :: i_dim !< Generic dimension/component iterator. - integer :: vel_comp_idx !< Velocity component iterator (1=u, 2=v, 3=w). - real(wp) :: divergence_v !< Velocity divergence at interface. - - $:GPU_PARALLEL_LOOP(collapse=3, private='[idx_right_phys, vel_grad_avg, current_tau_shear, current_tau_bulk, & - & vel_src_at_interface, Re_shear, Re_bulk, divergence_v, i_dim, vel_comp_idx]') + integer, dimension(3) :: idx_right_phys !< Physical (j,k,l) indices for right state. + + real(wp) :: Re_shear !< Interface shear Reynolds number. + real(wp) :: Re_bulk !< Interface bulk Reynolds number. + + integer :: j_loop !< Physical x-index loop iterator. + integer :: k_loop !< Physical y-index loop iterator. + integer :: l_loop !< Physical z-index loop iterator. + integer :: i_dim !< Generic dimension/component iterator. + integer :: vel_comp_idx !< Velocity component iterator (1=u, 2=v, 3=w). + + real(wp) :: divergence_v !< Velocity divergence at interface. + + $:GPU_PARALLEL_LOOP(collapse=3, private='[idx_right_phys, vel_grad_avg, current_tau_shear, current_tau_bulk, vel_src_at_interface, Re_shear, Re_bulk, divergence_v, i_dim, vel_comp_idx]') do l_loop = isz%beg, isz%end do k_loop = isy%beg, isy%end do j_loop = isx%beg, isx%end + idx_right_phys(1) = j_loop idx_right_phys(2) = k_loop idx_right_phys(3) = l_loop @@ -4329,21 +4896,18 @@ contains vel_grad_avg = 0.0_wp do vel_comp_idx = 1, num_dims - vel_grad_avg(vel_comp_idx, 1) = 0.5_wp*(dvelL_dx_vf(vel_comp_idx)%sf(j_loop, k_loop, & - & l_loop) + dvelR_dx_vf(vel_comp_idx)%sf(idx_right_phys(1), idx_right_phys(2), & - & idx_right_phys(3))) + vel_grad_avg(vel_comp_idx, 1) = 0.5_wp*(dvelL_dx_vf(vel_comp_idx)%sf(j_loop, k_loop, l_loop) + & + dvelR_dx_vf(vel_comp_idx)%sf(idx_right_phys(1), idx_right_phys(2), idx_right_phys(3))) if (num_dims > 1) then #:if not MFC_CASE_OPTIMIZATION or num_dims > 1 - vel_grad_avg(vel_comp_idx, 2) = 0.5_wp*(dvelL_dy_vf(vel_comp_idx)%sf(j_loop, k_loop, & - & l_loop) + dvelR_dy_vf(vel_comp_idx)%sf(idx_right_phys(1), idx_right_phys(2), & - & idx_right_phys(3))) + vel_grad_avg(vel_comp_idx, 2) = 0.5_wp*(dvelL_dy_vf(vel_comp_idx)%sf(j_loop, k_loop, l_loop) + & + dvelR_dy_vf(vel_comp_idx)%sf(idx_right_phys(1), idx_right_phys(2), idx_right_phys(3))) #:endif end if if (num_dims > 2) then #:if not MFC_CASE_OPTIMIZATION or num_dims > 2 - vel_grad_avg(vel_comp_idx, 3) = 0.5_wp*(dvelL_dz_vf(vel_comp_idx)%sf(j_loop, k_loop, & - & l_loop) + dvelR_dz_vf(vel_comp_idx)%sf(idx_right_phys(1), idx_right_phys(2), & - & idx_right_phys(3))) + vel_grad_avg(vel_comp_idx, 3) = 0.5_wp*(dvelL_dz_vf(vel_comp_idx)%sf(j_loop, k_loop, l_loop) + & + dvelR_dz_vf(vel_comp_idx)%sf(idx_right_phys(1), idx_right_phys(2), idx_right_phys(3))) #:endif end if end do @@ -4379,11 +4943,12 @@ contains call s_calculate_shear_stress_tensor(vel_grad_avg, Re_shear, divergence_v, current_tau_shear) do i_dim = 1, num_dims - flux_src_vf(momxb + i_dim - 1)%sf(j_loop, k_loop, l_loop) = flux_src_vf(momxb + i_dim - 1)%sf(j_loop, & - & k_loop, l_loop) - current_tau_shear(norm_dir, i_dim) + flux_src_vf(momxb + i_dim - 1)%sf(j_loop, k_loop, l_loop) = & + flux_src_vf(momxb + i_dim - 1)%sf(j_loop, k_loop, l_loop) - current_tau_shear(norm_dir, i_dim) - flux_src_vf(E_idx)%sf(j_loop, k_loop, l_loop) = flux_src_vf(E_idx)%sf(j_loop, k_loop, & - & l_loop) - vel_src_at_interface(i_dim)*current_tau_shear(norm_dir, i_dim) + flux_src_vf(E_idx)%sf(j_loop, k_loop, l_loop) = & + flux_src_vf(E_idx)%sf(j_loop, k_loop, l_loop) - & + vel_src_at_interface(i_dim)*current_tau_shear(norm_dir, i_dim) end do end if @@ -4392,13 +4957,15 @@ contains call s_calculate_bulk_stress_tensor(Re_bulk, divergence_v, current_tau_bulk) do i_dim = 1, num_dims - flux_src_vf(momxb + i_dim - 1)%sf(j_loop, k_loop, l_loop) = flux_src_vf(momxb + i_dim - 1)%sf(j_loop, & - & k_loop, l_loop) - current_tau_bulk(norm_dir, i_dim) + flux_src_vf(momxb + i_dim - 1)%sf(j_loop, k_loop, l_loop) = & + flux_src_vf(momxb + i_dim - 1)%sf(j_loop, k_loop, l_loop) - current_tau_bulk(norm_dir, i_dim) - flux_src_vf(E_idx)%sf(j_loop, k_loop, l_loop) = flux_src_vf(E_idx)%sf(j_loop, k_loop, & - & l_loop) - vel_src_at_interface(i_dim)*current_tau_bulk(norm_dir, i_dim) + flux_src_vf(E_idx)%sf(j_loop, k_loop, l_loop) = & + flux_src_vf(E_idx)%sf(j_loop, k_loop, l_loop) - & + vel_src_at_interface(i_dim)*current_tau_bulk(norm_dir, i_dim) end do end if + end do end do end do @@ -4406,41 +4973,50 @@ contains end subroutine s_compute_cartesian_viscous_source_flux - !> Compute shear stress tensor components + !> @brief Calculates shear stress tensor components. + !! tau_ij_shear = ( (dui/dxj + duj/dxi) - (2/3)*(div_v)*delta_ij ) / Re_shear + !! @param[in] vel_grad_avg Averaged velocity gradient tensor (d(vel_i)/d(coord_j)). + !! @param[in] Re_shear Shear Reynolds number. + !! @param[in] divergence_v Velocity divergence (du/dx + dv/dy + dw/dz). + !! @param[out] tau_shear_out Calculated shear stress tensor (stress on i-face, j-direction). subroutine s_calculate_shear_stress_tensor(vel_grad_avg, Re_shear, divergence_v, tau_shear_out) - $:GPU_ROUTINE(parallelism='[seq]') ! Arguments #:if not MFC_CASE_OPTIMIZATION and USING_AMD - real(wp), dimension(3, 3), intent(in) :: vel_grad_avg + real(wp), dimension(3, 3), intent(in) :: vel_grad_avg real(wp), dimension(3, 3), intent(out) :: tau_shear_out #:else - real(wp), dimension(num_dims, num_dims), intent(in) :: vel_grad_avg + real(wp), dimension(num_dims, num_dims), intent(in) :: vel_grad_avg real(wp), dimension(num_dims, num_dims), intent(out) :: tau_shear_out #:endif real(wp), intent(in) :: Re_shear real(wp), intent(in) :: divergence_v ! Local variables - integer :: i_dim !< Loop iterator for face normal. - integer :: j_dim !< Loop iterator for force component direction. + integer :: i_dim !< Loop iterator for face normal. + integer :: j_dim !< Loop iterator for force component direction. + tau_shear_out = 0.0_wp do i_dim = 1, num_dims do j_dim = 1, num_dims tau_shear_out(i_dim, j_dim) = (vel_grad_avg(j_dim, i_dim) + vel_grad_avg(i_dim, j_dim))/Re_shear if (i_dim == j_dim) then - tau_shear_out(i_dim, j_dim) = tau_shear_out(i_dim, j_dim) - (2.0_wp/3.0_wp)*divergence_v/Re_shear + tau_shear_out(i_dim, j_dim) = tau_shear_out(i_dim, j_dim) - & + (2.0_wp/3.0_wp)*divergence_v/Re_shear end if end do end do end subroutine s_calculate_shear_stress_tensor - !> Compute bulk stress tensor components (diagonal only) + !> @brief Calculates bulk stress tensor components (diagonal only). + !! tau_ii_bulk = (div_v) / Re_bulk. Off-diagonals are zero. + !! @param[in] Re_bulk Bulk Reynolds number. + !! @param[in] divergence_v Velocity divergence (du/dx + dv/dy + dw/dz). + !! @param[out] tau_bulk_out Calculated bulk stress tensor (stress on i-face, i-direction). subroutine s_calculate_bulk_stress_tensor(Re_bulk, divergence_v, tau_bulk_out) - $:GPU_ROUTINE(parallelism='[seq]') ! Arguments @@ -4453,7 +5029,8 @@ contains #:endif ! Local variables - integer :: i_dim !< Loop iterator for diagonal components. + integer :: i_dim !< Loop iterator for diagonal components. + tau_bulk_out = 0.0_wp do i_dim = 1, num_dims @@ -4462,21 +5039,33 @@ contains end subroutine s_calculate_bulk_stress_tensor - !> Deallocation and/or disassociation procedures that are needed to finalize the selected Riemann problem solver - subroutine s_finalize_riemann_solver(flux_vf, flux_src_vf, flux_gsrc_vf, norm_dir) + !> Deallocation and/or disassociation procedures that are + !! needed to finalize the selected Riemann problem solver + !! @param flux_vf Intercell fluxes + !! @param flux_src_vf Intercell source fluxes + !! @param flux_gsrc_vf Intercell geometric source fluxes + !! @param norm_dir Dimensional splitting coordinate direction + subroutine s_finalize_riemann_solver(flux_vf, flux_src_vf, & + flux_gsrc_vf, & + norm_dir) - type(scalar_field), dimension(sys_size), intent(inout) :: flux_vf, flux_src_vf, flux_gsrc_vf - integer, intent(in) :: norm_dir - integer :: i, j, k, l !< Generic loop iterators - ! Reshaping Outputted Data in y-direction + type(scalar_field), & + dimension(sys_size), & + intent(inout) :: flux_vf, flux_src_vf, flux_gsrc_vf + + integer, intent(in) :: norm_dir + integer :: i, j, k, l !< Generic loop iterators + + ! Reshaping Outputted Data in y-direction if (norm_dir == 2) then $:GPU_PARALLEL_LOOP(collapse=4) do i = 1, sys_size do l = is3%beg, is3%end do j = is1%beg, is1%end do k = is2%beg, is2%end - flux_vf(i)%sf(k, j, l) = flux_rsy_vf(j, k, l, i) + flux_vf(i)%sf(k, j, l) = & + flux_rsy_vf(j, k, l, i) end do end do end do @@ -4489,7 +5078,8 @@ contains do l = is3%beg, is3%end do j = is1%beg, is1%end do k = is2%beg, is2%end - flux_gsrc_vf(i)%sf(k, j, l) = flux_gsrc_rsy_vf(j, k, l, i) + flux_gsrc_vf(i)%sf(k, j, l) = & + flux_gsrc_rsy_vf(j, k, l, i) end do end do end do @@ -4501,7 +5091,8 @@ contains do l = is3%beg, is3%end do j = is1%beg, is1%end do k = is2%beg, is2%end - flux_src_vf(advxb)%sf(k, j, l) = flux_src_rsy_vf(j, k, l, advxb) + flux_src_vf(advxb)%sf(k, j, l) = & + flux_src_rsy_vf(j, k, l, advxb) end do end do end do @@ -4513,21 +5104,25 @@ contains do l = is3%beg, is3%end do j = is1%beg, is1%end do k = is2%beg, is2%end - flux_src_vf(i)%sf(k, j, l) = flux_src_rsy_vf(j, k, l, i) + flux_src_vf(i)%sf(k, j, l) = & + flux_src_rsy_vf(j, k, l, i) end do end do end do end do $:END_GPU_PARALLEL_LOOP() + end if ! Reshaping Outputted Data in z-direction - else if (norm_dir == 3) then + elseif (norm_dir == 3) then $:GPU_PARALLEL_LOOP(collapse=4) do i = 1, sys_size do j = is1%beg, is1%end do k = is2%beg, is2%end do l = is3%beg, is3%end - flux_vf(i)%sf(l, k, j) = flux_rsz_vf(j, k, l, i) + + flux_vf(i)%sf(l, k, j) = & + flux_rsz_vf(j, k, l, i) end do end do end do @@ -4539,7 +5134,9 @@ contains do j = is1%beg, is1%end do k = is2%beg, is2%end do l = is3%beg, is3%end - flux_gsrc_vf(i)%sf(l, k, j) = flux_gsrc_rsz_vf(j, k, l, i) + + flux_gsrc_vf(i)%sf(l, k, j) = & + flux_gsrc_rsz_vf(j, k, l, i) end do end do end do @@ -4551,7 +5148,8 @@ contains do j = is1%beg, is1%end do k = is2%beg, is2%end do l = is3%beg, is3%end - flux_src_vf(advxb)%sf(l, k, j) = flux_src_rsz_vf(j, k, l, advxb) + flux_src_vf(advxb)%sf(l, k, j) = & + flux_src_rsz_vf(j, k, l, advxb) end do end do end do @@ -4563,20 +5161,23 @@ contains do j = is1%beg, is1%end do k = is2%beg, is2%end do l = is3%beg, is3%end - flux_src_vf(i)%sf(l, k, j) = flux_src_rsz_vf(j, k, l, i) + flux_src_vf(i)%sf(l, k, j) = & + flux_src_rsz_vf(j, k, l, i) end do end do end do end do $:END_GPU_PARALLEL_LOOP() + end if - else if (norm_dir == 1) then + elseif (norm_dir == 1) then $:GPU_PARALLEL_LOOP(collapse=4) do i = 1, sys_size do l = is3%beg, is3%end do k = is2%beg, is2%end do j = is1%beg, is1%end - flux_vf(i)%sf(j, k, l) = flux_rsx_vf(j, k, l, i) + flux_vf(i)%sf(j, k, l) = & + flux_rsx_vf(j, k, l, i) end do end do end do @@ -4587,7 +5188,8 @@ contains do l = is3%beg, is3%end do k = is2%beg, is2%end do j = is1%beg, is1%end - flux_src_vf(advxb)%sf(j, k, l) = flux_src_rsx_vf(j, k, l, advxb) + flux_src_vf(advxb)%sf(j, k, l) = & + flux_src_rsx_vf(j, k, l, advxb) end do end do end do @@ -4599,7 +5201,8 @@ contains do l = is3%beg, is3%end do k = is2%beg, is2%end do j = is1%beg, is1%end - flux_src_vf(i)%sf(j, k, l) = flux_src_rsx_vf(j, k, l, i) + flux_src_vf(i)%sf(j, k, l) = & + flux_src_rsx_vf(j, k, l, i) end do end do end do diff --git a/src/simulation/m_sim_helpers.fpp b/src/simulation/m_sim_helpers.fpp index e20ec982fe..f8e8526ced 100644 --- a/src/simulation/m_sim_helpers.fpp +++ b/src/simulation/m_sim_helpers.fpp @@ -8,28 +8,34 @@ !> @brief Simulation helper routines for enthalpy computation, CFL calculation, and stability checks module m_sim_helpers - use m_derived_types + use m_derived_types !< Definitions of the derived types + use m_global_parameters + use m_variables_conversion implicit none - private; public :: s_compute_enthalpy, s_compute_stability_from_dt, s_compute_dt_from_cfl + private; public :: s_compute_enthalpy, & + s_compute_stability_from_dt, & + s_compute_dt_from_cfl contains !> Computes the modified dtheta for Fourier filtering in azimuthal direction + !! @param k y coordinate index + !! @param l z coordinate index + !! @return fltr_dtheta Modified dtheta value for cylindrical coordinates function f_compute_filtered_dtheta(k, l) result(fltr_dtheta) - $:GPU_ROUTINE(parallelism='[seq]') integer, intent(in) :: k, l - real(wp) :: fltr_dtheta - integer :: Nfq + real(wp) :: fltr_dtheta + integer :: Nfq if (grid_geometry == 3) then if (k == 0) then fltr_dtheta = 2._wp*pi*y_cb(0)/3._wp - else if (k <= fourier_rings) then + elseif (k <= fourier_rings) then Nfq = min(floor(2._wp*real(k, wp)*pi), (p + 1)/2 + 1) fltr_dtheta = 2._wp*pi*y_cb(k - 1)/real(Nfq, wp) else @@ -38,41 +44,63 @@ contains else fltr_dtheta = 0._wp end if - end function f_compute_filtered_dtheta !> Computes inviscid CFL terms for multi-dimensional cases (2D/3D only) + !! @param vel directional velocities + !! @param c mixture speed of sound + !! @param j x coordinate index + !! @param k y coordinate index + !! @param l z coordinate index + !! @return cfl_terms computed CFL terms for 2D/3D cases function f_compute_multidim_cfl_terms(vel, c, j, k, l) result(cfl_terms) - $:GPU_ROUTINE(parallelism='[seq]') real(wp), dimension(num_vels), intent(in) :: vel - real(wp), intent(in) :: c - integer, intent(in) :: j, k, l - real(wp) :: cfl_terms - real(wp) :: fltr_dtheta + real(wp), intent(in) :: c + integer, intent(in) :: j, k, l + real(wp) :: cfl_terms + real(wp) :: fltr_dtheta fltr_dtheta = f_compute_filtered_dtheta(k, l) if (p > 0) then - ! 3D + !3D #:if not MFC_CASE_OPTIMIZATION or num_dims > 2 if (grid_geometry == 3) then - cfl_terms = min(dx(j)/(abs(vel(1)) + c), dy(k)/(abs(vel(2)) + c), fltr_dtheta/(abs(vel(3)) + c)) + cfl_terms = min(dx(j)/(abs(vel(1)) + c), & + dy(k)/(abs(vel(2)) + c), & + fltr_dtheta/(abs(vel(3)) + c)) else - cfl_terms = min(dx(j)/(abs(vel(1)) + c), dy(k)/(abs(vel(2)) + c), dz(l)/(abs(vel(3)) + c)) + cfl_terms = min(dx(j)/(abs(vel(1)) + c), & + dy(k)/(abs(vel(2)) + c), & + dz(l)/(abs(vel(3)) + c)) end if #:endif else - ! 2D - cfl_terms = min(dx(j)/(abs(vel(1)) + c), dy(k)/(abs(vel(2)) + c)) + !2D + cfl_terms = min(dx(j)/(abs(vel(1)) + c), & + dy(k)/(abs(vel(2)) + c)) end if - end function f_compute_multidim_cfl_terms !> Computes enthalpy + !! @param q_prim_vf cell centered primitive variables + !! @param pres mixture pressure + !! @param rho mixture density + !! @param gamma mixture gamma + !! @param pi_inf mixture pi_inf + !! @param Re mixture reynolds number + !! @param H mixture enthalpy + !! @param alpha component alphas + !! @param vel directional velocities + !! @param vel_sum squard sum of velocity components + !! @param qv Fluid reference energy + !! @param j x index + !! @param k y index + !! @param l z index subroutine s_compute_enthalpy(q_prim_vf, pres, rho, gamma, pi_inf, Re, H, alpha, vel, vel_sum, qv, j, k, l) - - $:GPU_ROUTINE(function_name='s_compute_enthalpy',parallelism='[seq]', cray_inline=True) + $:GPU_ROUTINE(function_name='s_compute_enthalpy',parallelism='[seq]', & + & cray_inline=True) type(scalar_field), intent(in), dimension(sys_size) :: q_prim_vf #:if not MFC_CASE_OPTIMIZATION and USING_AMD @@ -80,11 +108,11 @@ contains real(wp), intent(inout), dimension(3) :: vel #:else real(wp), intent(inout), dimension(num_fluids) :: alpha - real(wp), intent(inout), dimension(num_vels) :: vel + real(wp), intent(inout), dimension(num_vels) :: vel #:endif - real(wp), intent(inout) :: rho, gamma, pi_inf, vel_sum, H, pres - real(wp), intent(out) :: qv - integer, intent(in) :: j, k, l + real(wp), intent(inout) :: rho, gamma, pi_inf, vel_sum, H, pres + real(wp), intent(out) :: qv + integer, intent(in) :: j, k, l real(wp), dimension(2), intent(inout) :: Re #:if not MFC_CASE_OPTIMIZATION and USING_AMD real(wp), dimension(3) :: alpha_rho, Gs @@ -92,12 +120,14 @@ contains real(wp), dimension(num_fluids) :: alpha_rho, Gs #:endif real(wp) :: E, G_local - integer :: i + + integer :: i call s_compute_species_fraction(q_prim_vf, j, k, l, alpha_rho, alpha) if (elasticity) then - call s_convert_species_to_mixture_variables_acc(rho, gamma, pi_inf, qv, alpha, alpha_rho, Re, G_local, Gs) + call s_convert_species_to_mixture_variables_acc(rho, gamma, pi_inf, qv, alpha, & + alpha_rho, Re, G_local, Gs) else call s_convert_species_to_mixture_variables_acc(rho, gamma, pi_inf, qv, alpha, alpha_rho, Re) end if @@ -138,99 +168,117 @@ contains end subroutine s_compute_enthalpy !> Computes stability criterion for a specified dt - subroutine s_compute_stability_from_dt(vel, c, rho, Re_l, j, k, l, icfl_sf, vcfl_sf, Rc_sf) - + !! @param vel directional velocities + !! @param c mixture speed of sound + !! @param rho Density + !! @param Re_l mixture Reynolds number + !! @param j x index + !! @param k y index + !! @param l z index + !! @param icfl cell-centered inviscid cfl number + !! @param vcfl (optional) cell-centered viscous CFL number + !! @param Rc (optional) cell centered Rc + subroutine s_compute_stability_from_dt(vel, c, rho, Re_l, j, k, l, icfl, vcfl, Rc) $:GPU_ROUTINE(parallelism='[seq]') - real(wp), intent(in), dimension(num_vels) :: vel - real(wp), intent(in) :: c, rho - real(wp), dimension(0:m,0:n,0:p), intent(inout) :: icfl_sf - real(wp), dimension(0:m,0:n,0:p), intent(inout), optional :: vcfl_sf, Rc_sf - real(wp), dimension(2), intent(in) :: Re_l - integer, intent(in) :: j, k, l - real(wp) :: fltr_dtheta + real(wp), intent(in), dimension(num_vels) :: vel + real(wp), intent(in) :: c, rho + real(wp), intent(inout) :: icfl + real(wp), intent(inout), optional :: vcfl, Rc + real(wp), dimension(2), intent(in) :: Re_l + integer, intent(in) :: j, k, l + + real(wp) :: fltr_dtheta ! Inviscid CFL calculation - if (p > 0 .or. n > 0) then - ! 2D/3D - icfl_sf(j, k, l) = dt/f_compute_multidim_cfl_terms(vel, c, j, k, l) - else - ! 1D - icfl_sf(j, k, l) = (dt/dx(j))*(abs(vel(1)) + c) + if (p > 0 .or. n > 0) then ! 2D/3D + icfl = dt/f_compute_multidim_cfl_terms(vel, c, j, k, l) + else ! 1D + icfl = (dt/dx(j))*(abs(vel(1)) + c) end if ! Viscous calculations if (viscous) then - if (p > 0) then + if (p > 0) then !3D #:if not MFC_CASE_OPTIMIZATION or num_dims > 2 - ! 3D if (grid_geometry == 3) then fltr_dtheta = f_compute_filtered_dtheta(k, l) - vcfl_sf(j, k, l) = maxval(dt/Re_l/rho)/min(dx(j), dy(k), fltr_dtheta)**2._wp - Rc_sf(j, k, l) = min(dx(j)*(abs(vel(1)) + c), dy(k)*(abs(vel(2)) + c), & - & fltr_dtheta*(abs(vel(3)) + c))/maxval(1._wp/Re_l) + vcfl = maxval(dt/Re_l/rho) & + /min(dx(j), dy(k), fltr_dtheta)**2._wp + Rc = min(dx(j)*(abs(vel(1)) + c), & + dy(k)*(abs(vel(2)) + c), & + fltr_dtheta*(abs(vel(3)) + c)) & + /maxval(1._wp/Re_l) else - vcfl_sf(j, k, l) = maxval(dt/Re_l/rho)/min(dx(j), dy(k), dz(l))**2._wp - Rc_sf(j, k, l) = min(dx(j)*(abs(vel(1)) + c), dy(k)*(abs(vel(2)) + c), & - & dz(l)*(abs(vel(3)) + c))/maxval(1._wp/Re_l) + vcfl = maxval(dt/Re_l/rho) & + /min(dx(j), dy(k), dz(l))**2._wp + Rc = min(dx(j)*(abs(vel(1)) + c), & + dy(k)*(abs(vel(2)) + c), & + dz(l)*(abs(vel(3)) + c)) & + /maxval(1._wp/Re_l) end if #:endif - else if (n > 0) then - ! 2D - vcfl_sf(j, k, l) = maxval(dt/Re_l/rho)/min(dx(j), dy(k))**2._wp - Rc_sf(j, k, l) = min(dx(j)*(abs(vel(1)) + c), dy(k)*(abs(vel(2)) + c))/maxval(1._wp/Re_l) - else - ! 1D - vcfl_sf(j, k, l) = maxval(dt/Re_l/rho)/dx(j)**2._wp - Rc_sf(j, k, l) = dx(j)*(abs(vel(1)) + c)/maxval(1._wp/Re_l) + elseif (n > 0) then !2D + vcfl = maxval(dt/Re_l/rho)/min(dx(j), dy(k))**2._wp + Rc = min(dx(j)*(abs(vel(1)) + c), & + dy(k)*(abs(vel(2)) + c)) & + /maxval(1._wp/Re_l) + else !1D + vcfl = maxval(dt/Re_l/rho)/dx(j)**2._wp + Rc = dx(j)*(abs(vel(1)) + c)/maxval(1._wp/Re_l) end if end if end subroutine s_compute_stability_from_dt !> Computes dt for a specified CFL number + !! @param vel directional velocities + !! @param c Speed of sound + !! @param max_dt cell centered maximum dt + !! @param rho cell centered density + !! @param Re_l cell centered Reynolds number + !! @param j x coordinate + !! @param k y coordinate + !! @param l z coordinate subroutine s_compute_dt_from_cfl(vel, c, max_dt, rho, Re_l, j, k, l) - $:GPU_ROUTINE(parallelism='[seq]') - real(wp), dimension(num_vels), intent(in) :: vel - real(wp), intent(in) :: c, rho - real(wp), dimension(0:m,0:n,0:p), intent(inout) :: max_dt - real(wp), dimension(2), intent(in) :: Re_l - integer, intent(in) :: j, k, l - real(wp) :: icfl_dt, vcfl_dt - real(wp) :: fltr_dtheta + real(wp), dimension(num_vels), intent(in) :: vel + real(wp), intent(in) :: c, rho + real(wp), intent(inout) :: max_dt + real(wp), dimension(2), intent(in) :: Re_l + integer, intent(in) :: j, k, l + + real(wp) :: icfl_dt, vcfl_dt + real(wp) :: fltr_dtheta ! Inviscid CFL calculation - if (p > 0 .or. n > 0) then - ! 2D/3D cases + if (p > 0 .or. n > 0) then ! 2D/3D cases icfl_dt = cfl_target*f_compute_multidim_cfl_terms(vel, c, j, k, l) - else - ! 1D case + else ! 1D cases icfl_dt = cfl_target*(dx(j)/(abs(vel(1)) + c)) end if ! Viscous calculations if (viscous) then - if (p > 0) then - ! 3D + if (p > 0) then !3D if (grid_geometry == 3) then fltr_dtheta = f_compute_filtered_dtheta(k, l) - vcfl_dt = cfl_target*(min(dx(j), dy(k), fltr_dtheta)**2._wp)/maxval(1/(rho*Re_l)) + vcfl_dt = cfl_target*(min(dx(j), dy(k), fltr_dtheta)**2._wp) & + /maxval(1/(rho*Re_l)) else - vcfl_dt = cfl_target*(min(dx(j), dy(k), dz(l))**2._wp)/maxval(1/(rho*Re_l)) + vcfl_dt = cfl_target*(min(dx(j), dy(k), dz(l))**2._wp) & + /maxval(1/(rho*Re_l)) end if - else if (n > 0) then - ! 2D + elseif (n > 0) then !2D vcfl_dt = cfl_target*(min(dx(j), dy(k))**2._wp)/maxval((1/Re_l)/rho) - else - ! 1D + else !1D vcfl_dt = cfl_target*(dx(j)**2._wp)/maxval(1/(rho*Re_l)) end if end if - if (any(Re_size > 0)) then - max_dt(j, k, l) = min(icfl_dt, vcfl_dt) + if (viscous) then + max_dt = min(icfl_dt, vcfl_dt) else - max_dt(j, k, l) = icfl_dt + max_dt = icfl_dt end if end subroutine s_compute_dt_from_cfl diff --git a/src/simulation/m_start_up.fpp b/src/simulation/m_start_up.fpp index c3f38ef500..9ee99b273e 100644 --- a/src/simulation/m_start_up.fpp +++ b/src/simulation/m_start_up.fpp @@ -8,60 +8,106 @@ !> @brief Reads input files, loads initial conditions and grid data, and orchestrates solver initialization and finalization module m_start_up - use m_derived_types - use m_global_parameters - use m_mpi_proxy + use m_derived_types !< Definitions of the derived types + + use m_global_parameters !< Definitions of the global parameters + + use m_mpi_proxy !< Message passing interface (MPI) module proxy + use m_mpi_common - use m_variables_conversion - use m_weno - use m_muscl - use m_riemann_solvers - use m_cbc + + use m_variables_conversion !< State variables type conversion procedures + + use m_weno !< Weighted and essentially non-oscillatory (WENO) + !! schemes for spatial reconstruction of variables + + use m_muscl !< Monotonic Upstream-centered (MUSCL) + !! schemes for convservation laws + + use m_riemann_solvers !< Exact and approximate Riemann problem solvers + + use m_cbc !< Characteristic boundary conditions (CBC) + use m_boundary_common - use m_acoustic_src - use m_rhs - use m_chemistry - use m_data_output - use m_time_steppers - use m_qbmm - use m_derived_variables + + use m_acoustic_src !< Acoustic source calculations + + use m_rhs !< Right-hand-side (RHS) evaluation procedures + + use m_chemistry !< Chemistry module + + use m_data_output !< Run-time info & solution data output procedures + + use m_time_steppers !< Time-stepping algorithms + + use m_qbmm !< Quadrature MOM + + use m_derived_variables !< Procedures used to compute quantities derived + !! from the conservative and primitive variables use m_hypoelastic + use m_hyperelastic - use m_phase_change + + use m_phase_change !< Phase-change module + use m_viscous - use m_bubbles_EE - use m_bubbles_EL + + use m_bubbles_EE !< Ensemble-averaged bubble dynamics routines + + use m_bubbles_EL !< Lagrange bubble dynamics routines + use ieee_arithmetic - use m_helper_basic + + use m_helper_basic !< Functions to compare floating point numbers + use m_helper $:USE_GPU_MODULE() use m_nvtx + use m_ibm + use m_compile_specific + use m_checker_common + use m_checker + use m_surface_tension + use m_body_forces + use m_sim_helpers + use m_igr implicit none - private; public :: s_read_input_file, s_check_input_file, s_read_data_files, s_read_serial_data_files, & - & s_read_parallel_data_files, s_initialize_internal_energy_equations, s_initialize_modules, s_initialize_gpu_vars, & - & s_initialize_mpi_domain, s_finalize_modules, s_perform_time_step, s_save_data, s_save_performance_metrics + private; public :: s_read_input_file, & + s_check_input_file, & + s_read_data_files, & + s_read_serial_data_files, & + s_read_parallel_data_files, & + s_initialize_internal_energy_equations, & + s_initialize_modules, s_initialize_gpu_vars, & + s_initialize_mpi_domain, s_finalize_modules, & + s_perform_time_step, s_save_data, & + s_save_performance_metrics type(scalar_field), allocatable, dimension(:) :: q_cons_temp - real(wp) :: dt_init + + real(wp) :: dt_init contains !> Read data files. Dispatch subroutine that replaces procedure pointer. + !! @param q_cons_vf Conservative variables impure subroutine s_read_data_files(q_cons_vf) - type(scalar_field), dimension(sys_size), intent(inout) :: q_cons_vf + type(scalar_field), & + dimension(sys_size), & + intent(inout) :: q_cons_vf if (.not. parallel_io) then call s_read_serial_data_files(q_cons_vf) @@ -71,24 +117,29 @@ contains end subroutine s_read_data_files - !> Verify the input file exists and read it + !> The purpose of this procedure is to first verify that an + !! input file has been made available by the user. Provided + !! that this is so, the input file is then read in. impure subroutine s_read_input_file + ! Relative path to the input file provided by the user character(LEN=name_len), parameter :: file_path = './simulation.inp' - logical :: file_exist !< Logical used to check the existence of the input file - integer :: iostatus - ! Integer to check iostat of file read + + logical :: file_exist !< + !! Logical used to check the existence of the input file + + integer :: iostatus + !! Integer to check iostat of file read character(len=1000) :: line + ! Namelist of the global parameters which may be specified by user namelist /user_inputs/ case_dir, run_time_info, m, n, p, dt, & t_step_start, t_step_stop, t_step_save, t_step_print, & model_eqns, mpp_lim, time_stepper, weno_eps, & rdma_mpi, teno_CT, mp_weno, weno_avg, & riemann_solver, low_Mach, wave_speeds, avg_state, & bc_x, bc_y, bc_z, & - x_a, y_a, z_a, x_b, y_b, z_b, & - x_domain, y_domain, z_domain, & hypoelasticity, & ib, num_ibs, patch_ib, & ib_state_wrt, & @@ -98,31 +149,50 @@ contains null_weights, precision, parallel_io, cyl_coord, & rhoref, pref, bubbles_euler, bubble_model, & R0ref, chem_params, & - #:if not MFC_CASE_OPTIMIZATION +#:if not MFC_CASE_OPTIMIZATION nb, mapped_weno, wenoz, teno, wenoz_q, weno_order, & num_fluids, mhd, relativity, igr_order, viscous, & igr_iter_solver, igr, igr_pres_lim, & recon_type, muscl_order, muscl_lim, & - #:endif - Ca, Web, Re_inv, acoustic_source, acoustic, num_source, polytropic, thermal, integral, integral_wrt, num_integrals, & - & polydisperse, poly_sigma, qbmm, relax, relax_model, palpha_eps, ptgalpha_eps, file_per_process, sigma, pi_fac, & - & adv_n, adap_dt, adap_dt_tol, adap_dt_max_iters, bf_x, bf_y, bf_z, k_x, k_y, k_z, w_x, w_y, w_z, p_x, p_y, p_z, g_x, & - & g_y, g_z, n_start, t_save, t_stop, cfl_adap_dt, cfl_const_dt, cfl_target, surface_tension, bubbles_lagrange, & - & lag_params, hyperelasticity, R0ref, num_bc_patches, Bx0, cont_damage, tau_star, cont_damage_s, alpha_bar, & - & hyper_cleaning, hyper_cleaning_speed, hyper_cleaning_tau, alf_factor, num_igr_iters, num_igr_warm_start_iters, & - & int_comp, ic_eps, ic_beta, nv_uvm_out_of_core, nv_uvm_igr_temps_on_gpu, nv_uvm_pref_gpu, down_sample, fft_wrt - +#:endif + Ca, Web, Re_inv, & + acoustic_source, acoustic, num_source, & + polytropic, thermal, & + integral, integral_wrt, num_integrals, & + polydisperse, poly_sigma, qbmm, & + relax, relax_model, & + palpha_eps, ptgalpha_eps, & + file_per_process, sigma, & + pi_fac, adv_n, adap_dt, adap_dt_tol, adap_dt_max_iters, & + bf_x, bf_y, bf_z, & + k_x, k_y, k_z, w_x, w_y, w_z, p_x, p_y, p_z, & + g_x, g_y, g_z, n_start, t_save, t_stop, & + cfl_adap_dt, cfl_const_dt, cfl_target, & + surface_tension, bubbles_lagrange, lag_params, & + hyperelasticity, R0ref, num_bc_patches, Bx0, & + cont_damage, tau_star, cont_damage_s, alpha_bar, & + hyper_cleaning, hyper_cleaning_speed, hyper_cleaning_tau, & + alf_factor, num_igr_iters, num_igr_warm_start_iters, & + int_comp, ic_eps, ic_beta, nv_uvm_out_of_core, & + nv_uvm_igr_temps_on_gpu, nv_uvm_pref_gpu, down_sample, fft_wrt + + ! Checking that an input file has been provided by the user. If it + ! has, then the input file is read in, otherwise, simulation exits. inquire (FILE=trim(file_path), EXIST=file_exist) if (file_exist) then - open (1, FILE=trim(file_path), form='formatted', ACTION='read', STATUS='old') + open (1, FILE=trim(file_path), & + FORM='formatted', & + ACTION='read', & + STATUS='old') read (1, NML=user_inputs, iostat=iostatus) if (iostatus /= 0) then backspace (1) read (1, fmt='(A)') line - print *, 'Invalid line in namelist: ' // trim(line) - call s_mpi_abort('Invalid line in simulation.inp. It is ' // 'likely due to a datatype mismatch. Exiting.') + print *, 'Invalid line in namelist: '//trim(line) + call s_mpi_abort('Invalid line in simulation.inp. It is '// & + 'likely due to a datatype mismatch. Exiting.') end if close (1) @@ -131,6 +201,7 @@ contains bodyForces = .true. end if + ! Store m,n,p into global m,n,p m_glb = m n_glb = n p_glb = p @@ -139,27 +210,39 @@ contains if (cfl_adap_dt .or. cfl_const_dt) cfl_dt = .true. - if (any((/bc_x%beg, bc_x%end, bc_y%beg, bc_y%end, bc_z%beg, bc_z%end/) == -17) .or. num_bc_patches > 0) then + if (any((/bc_x%beg, bc_x%end, bc_y%beg, bc_y%end, bc_z%beg, bc_z%end/) == BC_DIRICHLET) .or. & + num_bc_patches > 0) then bc_io = .true. end if + + if (bc_x%beg == BC_PERIODIC .and. bc_x%end == BC_PERIODIC) periodic_bc(1) = .true. + if (bc_y%beg == BC_PERIODIC .and. bc_y%end == BC_PERIODIC) periodic_bc(2) = .true. + if (bc_z%beg == BC_PERIODIC .and. bc_z%end == BC_PERIODIC) periodic_bc(3) = .true. + else - call s_mpi_abort(trim(file_path) // ' is missing. Exiting.') + call s_mpi_abort(trim(file_path)//' is missing. Exiting.') end if end subroutine s_read_input_file - !> Validate that all user-provided inputs form a consistent simulation configuration + !> The goal of this procedure is to verify that each of the + !! user provided inputs is valid and that their combination + !! constitutes a meaningful configuration for the simulation. impure subroutine s_check_input_file + ! Relative path to the current directory file in the case directory character(LEN=path_len) :: file_path - logical :: file_exist - file_path = trim(case_dir) // '/.' + ! Logical used to check the existence of the current directory file + logical :: file_exist + + ! Logistics + file_path = trim(case_dir)//'/.' call my_inquire(file_path, file_exist) if (file_exist .neqv. .true.) then - call s_mpi_abort(trim(file_path) // ' is missing. Exiting.') + call s_mpi_abort(trim(file_path)//' is missing. Exiting.') end if call s_check_inputs_common() @@ -167,26 +250,38 @@ contains end subroutine s_check_input_file - !> Read serial initial condition and grid data files and compute cell-width distributions + !> @brief Reads serial initial condition and grid data files and computes cell-width distributions. + !! @param q_cons_vf Cell-averaged conservative variables impure subroutine s_read_serial_data_files(q_cons_vf) - type(scalar_field), dimension(sys_size), intent(inout) :: q_cons_vf - character(LEN=path_len + 2*name_len) :: t_step_dir !< Relative path to the starting time-step directory - character(LEN=path_len + 3*name_len) :: file_path !< Relative path to the grid and conservative variables data files - logical :: file_exist - integer :: i, r + type(scalar_field), dimension(sys_size), intent(INOUT) :: q_cons_vf + + character(LEN=path_len + 2*name_len) :: t_step_dir !< + !! Relative path to the starting time-step directory + + character(LEN=path_len + 3*name_len) :: file_path !< + !! Relative path to the grid and conservative variables data files + logical :: file_exist !< + ! Logical used to check the existence of the data files + + integer :: i, r !< Generic loop iterator + + ! Confirming that the directory from which the initial condition and + ! the grid data files are to be read in exists and exiting otherwise if (cfl_dt) then - write (t_step_dir, '(A,I0,A,I0)') trim(case_dir) // '/p_all/p', proc_rank, '/', n_start + write (t_step_dir, '(A,I0,A,I0)') & + trim(case_dir)//'/p_all/p', proc_rank, '/', n_start else - write (t_step_dir, '(A,I0,A,I0)') trim(case_dir) // '/p_all/p', proc_rank, '/', t_step_start + write (t_step_dir, '(A,I0,A,I0)') & + trim(case_dir)//'/p_all/p', proc_rank, '/', t_step_start end if - file_path = trim(t_step_dir) // '/.' + file_path = trim(t_step_dir)//'/.' call my_inquire(file_path, file_exist) if (file_exist .neqv. .true.) then - call s_mpi_abort(trim(file_path) // ' is missing. Exiting.') + call s_mpi_abort(trim(file_path)//' is missing. Exiting.') end if if (bc_io) then @@ -195,15 +290,19 @@ contains call s_assign_default_bc_type(bc_type) end if - file_path = trim(t_step_dir) // '/x_cb.dat' + ! Cell-boundary Locations in x-direction + file_path = trim(t_step_dir)//'/x_cb.dat' inquire (FILE=trim(file_path), EXIST=file_exist) if (file_exist) then - open (2, FILE=trim(file_path), form='unformatted', ACTION='read', STATUS='old') + open (2, FILE=trim(file_path), & + FORM='unformatted', & + ACTION='read', & + STATUS='old') read (2) x_cb(-1:m); close (2) else - call s_mpi_abort(trim(file_path) // ' is missing. Exiting.') + call s_mpi_abort(trim(file_path)//' is missing. Exiting.') end if dx(0:m) = x_cb(0:m) - x_cb(-1:m - 1) @@ -212,52 +311,67 @@ contains if (ib) then do i = 1, num_ibs if (patch_ib(i)%c > 0) then - Np = int((patch_ib(i)%p*patch_ib(i)%c/dx(0))*20) + int(((patch_ib(i)%c - patch_ib(i)%p*patch_ib(i)%c)/dx(0)) & - & *20) + 1 + Np = int((patch_ib(i)%p*patch_ib(i)%c/dx(0))*20) + int(((patch_ib(i)%c - patch_ib(i)%p*patch_ib(i)%c)/dx(0))*20) + 1 end if end do end if + ! Cell-boundary Locations in y-direction if (n > 0) then - file_path = trim(t_step_dir) // '/y_cb.dat' + + file_path = trim(t_step_dir)//'/y_cb.dat' inquire (FILE=trim(file_path), EXIST=file_exist) if (file_exist) then - open (2, FILE=trim(file_path), form='unformatted', ACTION='read', STATUS='old') + open (2, FILE=trim(file_path), & + FORM='unformatted', & + ACTION='read', & + STATUS='old') read (2) y_cb(-1:n); close (2) else - call s_mpi_abort(trim(file_path) // ' is missing. Exiting.') + call s_mpi_abort(trim(file_path)//' is missing. Exiting.') end if dy(0:n) = y_cb(0:n) - y_cb(-1:n - 1) y_cc(0:n) = y_cb(-1:n - 1) + dy(0:n)/2._wp + end if + ! Cell-boundary Locations in z-direction if (p > 0) then - file_path = trim(t_step_dir) // '/z_cb.dat' + + file_path = trim(t_step_dir)//'/z_cb.dat' inquire (FILE=trim(file_path), EXIST=file_exist) if (file_exist) then - open (2, FILE=trim(file_path), form='unformatted', ACTION='read', STATUS='old') + open (2, FILE=trim(file_path), & + FORM='unformatted', & + ACTION='read', & + STATUS='old') read (2) z_cb(-1:p); close (2) else - call s_mpi_abort(trim(file_path) // ' is missing. Exiting.') + call s_mpi_abort(trim(file_path)//' is missing. Exiting.') end if dz(0:p) = z_cb(0:p) - z_cb(-1:p - 1) z_cc(0:p) = z_cb(-1:p - 1) + dz(0:p)/2._wp + end if do i = 1, sys_size - write (file_path, '(A,I0,A)') trim(t_step_dir) // '/q_cons_vf', i, '.dat' + write (file_path, '(A,I0,A)') & + trim(t_step_dir)//'/q_cons_vf', i, '.dat' inquire (FILE=trim(file_path), EXIST=file_exist) if (file_exist) then - open (2, FILE=trim(file_path), form='unformatted', ACTION='read', STATUS='old') - read (2) q_cons_vf(i)%sf(0:m,0:n,0:p); close (2) + open (2, FILE=trim(file_path), & + FORM='unformatted', & + ACTION='read', & + STATUS='old') + read (2) q_cons_vf(i)%sf(0:m, 0:n, 0:p); close (2) else - call s_mpi_abort(trim(file_path) // ' is missing. Exiting.') + call s_mpi_abort(trim(file_path)//' is missing. Exiting.') end if end do @@ -266,25 +380,33 @@ contains if (qbmm .and. .not. polytropic) then do i = 1, nb do r = 1, nnode - write (file_path, '(A,I0,A)') trim(t_step_dir) // '/pb', sys_size + (i - 1)*nnode + r, '.dat' + write (file_path, '(A,I0,A)') & + trim(t_step_dir)//'/pb', sys_size + (i - 1)*nnode + r, '.dat' inquire (FILE=trim(file_path), EXIST=file_exist) if (file_exist) then - open (2, FILE=trim(file_path), form='unformatted', ACTION='read', STATUS='old') - read (2) pb_ts(1)%sf(0:m,0:n,0:p,r, i); close (2) + open (2, FILE=trim(file_path), & + FORM='unformatted', & + ACTION='read', & + STATUS='old') + read (2) pb_ts(1)%sf(0:m, 0:n, 0:p, r, i); close (2) else - call s_mpi_abort(trim(file_path) // ' is missing. Exiting.') + call s_mpi_abort(trim(file_path)//' is missing. Exiting.') end if end do end do do i = 1, nb do r = 1, nnode - write (file_path, '(A,I0,A)') trim(t_step_dir) // '/mv', sys_size + (i - 1)*nnode + r, '.dat' + write (file_path, '(A,I0,A)') & + trim(t_step_dir)//'/mv', sys_size + (i - 1)*nnode + r, '.dat' inquire (FILE=trim(file_path), EXIST=file_exist) if (file_exist) then - open (2, FILE=trim(file_path), form='unformatted', ACTION='read', STATUS='old') - read (2) mv_ts(1)%sf(0:m,0:n,0:p,r, i); close (2) + open (2, FILE=trim(file_path), & + FORM='unformatted', & + ACTION='read', & + STATUS='old') + read (2) mv_ts(1)%sf(0:m, 0:n, 0:p, r, i); close (2) else - call s_mpi_abort(trim(file_path) // ' is missing. Exiting.') + call s_mpi_abort(trim(file_path)//' is missing. Exiting.') end if end do end do @@ -293,35 +415,44 @@ contains end subroutine s_read_serial_data_files - !> Read parallel initial condition and grid data files via MPI I/O + !> @brief Reads parallel initial condition and grid data files via MPI I/O. + !! @param q_cons_vf Conservative variables impure subroutine s_read_parallel_data_files(q_cons_vf) - type(scalar_field), dimension(sys_size), intent(inout) :: q_cons_vf + type(scalar_field), & + dimension(sys_size), & + intent(INOUT) :: q_cons_vf #ifdef MFC_MPI - real(wp), allocatable, dimension(:) :: x_cb_glb, y_cb_glb, z_cb_glb - integer :: ifile, ierr, data_size - integer, dimension(MPI_STATUS_SIZE) :: status - integer(KIND=MPI_OFFSET_KIND) :: disp - integer(KIND=MPI_OFFSET_KIND) :: m_MOK, n_MOK, p_MOK - integer(KIND=MPI_OFFSET_KIND) :: WP_MOK, var_MOK, str_MOK - integer(KIND=MPI_OFFSET_KIND) :: NVARS_MOK - integer(KIND=MPI_OFFSET_KIND) :: MOK + + real(wp), allocatable, dimension(:) :: x_cb_glb, y_cb_glb, z_cb_glb + + integer :: ifile, ierr, data_size + integer, dimension(MPI_STATUS_SIZE) :: status + integer(KIND=MPI_OFFSET_KIND) :: disp + integer(KIND=MPI_OFFSET_KIND) :: m_MOK, n_MOK, p_MOK + integer(KIND=MPI_OFFSET_KIND) :: WP_MOK, var_MOK, str_MOK + integer(KIND=MPI_OFFSET_KIND) :: NVARS_MOK + integer(KIND=MPI_OFFSET_KIND) :: MOK + character(LEN=path_len + 2*name_len) :: file_loc - logical :: file_exist - character(len=10) :: t_step_start_string - integer :: i, j + logical :: file_exist + + character(len=10) :: t_step_start_string + + integer :: i, j ! Downsampled data variables integer :: m_ds, n_ds, p_ds integer :: m_glb_ds, n_glb_ds, p_glb_ds - integer :: m_glb_read, n_glb_read, p_glb_read !< data size of read + integer :: m_glb_read, n_glb_read, p_glb_read ! data size of read allocate (x_cb_glb(-1:m_glb)) allocate (y_cb_glb(-1:n_glb)) allocate (z_cb_glb(-1:p_glb)) - file_loc = trim(case_dir) // '/restart_data' // trim(mpiiofs) // 'x_cb.dat' + ! Read in cell boundary locations in x-direction + file_loc = trim(case_dir)//'/restart_data'//trim(mpiiofs)//'x_cb.dat' inquire (FILE=trim(file_loc), EXIST=file_exist) if (down_sample) then @@ -340,25 +471,28 @@ contains call MPI_FILE_READ(ifile, x_cb_glb, data_size, mpi_p, status, ierr) call MPI_FILE_CLOSE(ifile, ierr) else - call s_mpi_abort('File ' // trim(file_loc) // ' is missing. Exiting.') + call s_mpi_abort('File '//trim(file_loc)//' is missing. Exiting.') end if + ! Assigning local cell boundary locations x_cb(-1:m) = x_cb_glb((start_idx(1) - 1):(start_idx(1) + m)) + ! Computing the cell width distribution dx(0:m) = x_cb(0:m) - x_cb(-1:m - 1) + ! Computing the cell center locations x_cc(0:m) = x_cb(-1:m - 1) + dx(0:m)/2._wp if (ib) then do i = 1, num_ibs if (patch_ib(i)%c > 0) then - Np = int((patch_ib(i)%p*patch_ib(i)%c/dx(0))*20) + int(((patch_ib(i)%c - patch_ib(i)%p*patch_ib(i)%c)/dx(0)) & - & *20) + 1 + Np = int((patch_ib(i)%p*patch_ib(i)%c/dx(0))*20) + int(((patch_ib(i)%c - patch_ib(i)%p*patch_ib(i)%c)/dx(0))*20) + 1 allocate (MPI_IO_airfoil_IB_DATA%var(1:2*Np)) end if end do end if if (n > 0) then - file_loc = trim(case_dir) // '/restart_data' // trim(mpiiofs) // 'y_cb.dat' + ! Read in cell boundary locations in y-direction + file_loc = trim(case_dir)//'/restart_data'//trim(mpiiofs)//'y_cb.dat' inquire (FILE=trim(file_loc), EXIST=file_exist) if (file_exist) then @@ -367,15 +501,19 @@ contains call MPI_FILE_READ(ifile, y_cb_glb, data_size, mpi_p, status, ierr) call MPI_FILE_CLOSE(ifile, ierr) else - call s_mpi_abort('File ' // trim(file_loc) // ' is missing. Exiting.') + call s_mpi_abort('File '//trim(file_loc)//' is missing. Exiting.') end if + ! Assigning local cell boundary locations y_cb(-1:n) = y_cb_glb((start_idx(2) - 1):(start_idx(2) + n)) + ! Computing the cell width distribution dy(0:n) = y_cb(0:n) - y_cb(-1:n - 1) + ! Computing the cell center locations y_cc(0:n) = y_cb(-1:n - 1) + dy(0:n)/2._wp if (p > 0) then - file_loc = trim(case_dir) // '/restart_data' // trim(mpiiofs) // 'z_cb.dat' + ! Read in cell boundary locations in z-direction + file_loc = trim(case_dir)//'/restart_data'//trim(mpiiofs)//'z_cb.dat' inquire (FILE=trim(file_loc), EXIST=file_exist) if (file_exist) then @@ -384,12 +522,16 @@ contains call MPI_FILE_READ(ifile, z_cb_glb, data_size, mpi_p, status, ierr) call MPI_FILE_CLOSE(ifile, ierr) else - call s_mpi_abort('File ' // trim(file_loc) // 'is missing. Exiting.') + call s_mpi_abort('File '//trim(file_loc)//'is missing. Exiting.') end if + ! Assigning local cell boundary locations z_cb(-1:p) = z_cb_glb((start_idx(3) - 1):(start_idx(3) + p)) + ! Computing the cell width distribution dz(0:p) = z_cb(0:p) - z_cb(-1:p - 1) + ! Computing the cell center locations z_cc(0:p) = z_cb(-1:p - 1) + dz(0:p)/2._wp + end if end if @@ -401,12 +543,13 @@ contains call s_int_to_str(t_step_start, t_step_start_string) write (file_loc, '(I0,A1,I7.7,A)') t_step_start, '_', proc_rank, '.dat' end if - file_loc = trim(case_dir) // '/restart_data/lustre_' // trim(t_step_start_string) // trim(mpiiofs) // trim(file_loc) + file_loc = trim(case_dir)//'/restart_data/lustre_'//trim(t_step_start_string)//trim(mpiiofs)//trim(file_loc) inquire (FILE=trim(file_loc), EXIST=file_exist) if (file_exist) then call MPI_FILE_OPEN(MPI_COMM_SELF, file_loc, MPI_MODE_RDONLY, mpi_info_int, ifile, ierr) + ! Initialize MPI data I/O if (down_sample) then call s_initialize_mpi_data_ds(q_cons_vf) else @@ -418,17 +561,20 @@ contains end if if (down_sample) then + ! Size of local arrays data_size = (m_ds + 3)*(n_ds + 3)*(p_ds + 3) m_glb_read = m_glb_ds + 1 n_glb_read = n_glb_ds + 1 p_glb_read = p_glb_ds + 1 else + ! Size of local arrays data_size = (m + 1)*(n + 1)*(p + 1) m_glb_read = m_glb + 1 n_glb_read = n_glb + 1 p_glb_read = p_glb + 1 end if + ! Resize some integers so MPI can read even the biggest file m_MOK = int(m_glb_read + 1, MPI_OFFSET_KIND) n_MOK = int(m_glb_read + 1, MPI_OFFSET_KIND) p_MOK = int(m_glb_read + 1, MPI_OFFSET_KIND) @@ -437,18 +583,21 @@ contains str_MOK = int(name_len, MPI_OFFSET_KIND) NVARS_MOK = int(sys_size, MPI_OFFSET_KIND) + ! Read the data for each variable if (bubbles_euler .or. elasticity) then - do i = 1, sys_size ! adv_idx%end + do i = 1, sys_size!adv_idx%end var_MOK = int(i, MPI_OFFSET_KIND) - call MPI_FILE_READ(ifile, MPI_IO_DATA%var(i)%sf, data_size*mpi_io_type, mpi_io_p, status, ierr) + call MPI_FILE_READ(ifile, MPI_IO_DATA%var(i)%sf, data_size*mpi_io_type, & + mpi_io_p, status, ierr) end do - ! Read pb and mv for non-polytropic qbmm + !Read pb and mv for non-polytropic qbmm if (qbmm .and. .not. polytropic) then do i = sys_size + 1, sys_size + 2*nb*nnode var_MOK = int(i, MPI_OFFSET_KIND) - call MPI_FILE_READ(ifile, MPI_IO_DATA%var(i)%sf, data_size*mpi_io_type, mpi_io_p, status, ierr) + call MPI_FILE_READ(ifile, MPI_IO_DATA%var(i)%sf, data_size*mpi_io_type, & + mpi_io_p, status, ierr) end do end if else @@ -456,13 +605,15 @@ contains do i = 1, sys_size var_MOK = int(i, MPI_OFFSET_KIND) - call MPI_FILE_READ(ifile, q_cons_temp(i)%sf, data_size*mpi_io_type, mpi_io_p, status, ierr) + call MPI_FILE_READ(ifile, q_cons_temp(i)%sf, data_size*mpi_io_type, & + mpi_io_p, status, ierr) end do else do i = 1, sys_size var_MOK = int(i, MPI_OFFSET_KIND) - call MPI_FILE_READ(ifile, MPI_IO_DATA%var(i)%sf, data_size*mpi_io_type, mpi_io_p, status, ierr) + call MPI_FILE_READ(ifile, MPI_IO_DATA%var(i)%sf, data_size*mpi_io_type, & + mpi_io_p, status, ierr) end do end if end if @@ -470,29 +621,37 @@ contains call s_mpi_barrier() call MPI_FILE_CLOSE(ifile, ierr) + else - call s_mpi_abort('File ' // trim(file_loc) // ' is missing. Exiting.') + call s_mpi_abort('File '//trim(file_loc)//' is missing. Exiting.') end if else + ! Open the file to read conservative variables if (cfl_dt) then write (file_loc, '(I0,A)') n_start, '.dat' else write (file_loc, '(I0,A)') t_step_start, '.dat' end if - file_loc = trim(case_dir) // '/restart_data' // trim(mpiiofs) // trim(file_loc) + file_loc = trim(case_dir)//'/restart_data'//trim(mpiiofs)//trim(file_loc) inquire (FILE=trim(file_loc), EXIST=file_exist) if (file_exist) then call MPI_FILE_OPEN(MPI_COMM_WORLD, file_loc, MPI_MODE_RDONLY, mpi_info_int, ifile, ierr) + ! Initialize MPI data I/O + if (ib) then call s_initialize_mpi_data(q_cons_vf, ib_markers) else + call s_initialize_mpi_data(q_cons_vf) + end if + ! Size of local arrays data_size = (m + 1)*(n + 1)*(p + 1) + ! Resize some integers so MPI can read even the biggest file m_MOK = int(m_glb + 1, MPI_OFFSET_KIND) n_MOK = int(n_glb + 1, MPI_OFFSET_KIND) p_MOK = int(p_glb + 1, MPI_OFFSET_KIND) @@ -501,41 +660,53 @@ contains str_MOK = int(name_len, MPI_OFFSET_KIND) NVARS_MOK = int(sys_size, MPI_OFFSET_KIND) + ! Read the data for each variable if (bubbles_euler .or. elasticity) then - do i = 1, sys_size ! adv_idx%end + do i = 1, sys_size !adv_idx%end var_MOK = int(i, MPI_OFFSET_KIND) + ! Initial displacement to skip at beginning of file disp = m_MOK*max(MOK, n_MOK)*max(MOK, p_MOK)*WP_MOK*(var_MOK - 1) - call MPI_FILE_SET_VIEW(ifile, disp, mpi_io_p, MPI_IO_DATA%view(i), 'native', mpi_info_int, ierr) - call MPI_FILE_READ(ifile, MPI_IO_DATA%var(i)%sf, data_size*mpi_io_type, mpi_io_p, status, ierr) + call MPI_FILE_SET_VIEW(ifile, disp, mpi_io_p, MPI_IO_DATA%view(i), & + 'native', mpi_info_int, ierr) + call MPI_FILE_READ(ifile, MPI_IO_DATA%var(i)%sf, data_size*mpi_io_type, & + mpi_io_p, status, ierr) end do - ! Read pb and mv for non-polytropic qbmm + !Read pb and mv for non-polytropic qbmm if (qbmm .and. .not. polytropic) then do i = sys_size + 1, sys_size + 2*nb*nnode var_MOK = int(i, MPI_OFFSET_KIND) + ! Initial displacement to skip at beginning of file disp = m_MOK*max(MOK, n_MOK)*max(MOK, p_MOK)*WP_MOK*(var_MOK - 1) - call MPI_FILE_SET_VIEW(ifile, disp, mpi_io_p, MPI_IO_DATA%view(i), 'native', mpi_info_int, ierr) - call MPI_FILE_READ(ifile, MPI_IO_DATA%var(i)%sf, data_size*mpi_io_type, mpi_io_p, status, ierr) + call MPI_FILE_SET_VIEW(ifile, disp, mpi_io_p, MPI_IO_DATA%view(i), & + 'native', mpi_info_int, ierr) + call MPI_FILE_READ(ifile, MPI_IO_DATA%var(i)%sf, data_size*mpi_io_type, & + mpi_io_p, status, ierr) end do end if else do i = 1, sys_size var_MOK = int(i, MPI_OFFSET_KIND) + ! Initial displacement to skip at beginning of file disp = m_MOK*max(MOK, n_MOK)*max(MOK, p_MOK)*WP_MOK*(var_MOK - 1) - call MPI_FILE_SET_VIEW(ifile, disp, mpi_io_p, MPI_IO_DATA%view(i), 'native', mpi_info_int, ierr) - call MPI_FILE_READ_ALL(ifile, MPI_IO_DATA%var(i)%sf, data_size*mpi_io_type, mpi_io_p, status, ierr) + call MPI_FILE_SET_VIEW(ifile, disp, mpi_io_p, MPI_IO_DATA%view(i), & + 'native', mpi_info_int, ierr) + call MPI_FILE_READ_ALL(ifile, MPI_IO_DATA%var(i)%sf, data_size*mpi_io_type, & + mpi_io_p, status, ierr) end do end if call s_mpi_barrier() call MPI_FILE_CLOSE(ifile, ierr) + else - call s_mpi_abort('File ' // trim(file_loc) // ' is missing. Exiting.') + call s_mpi_abort('File '//trim(file_loc)//' is missing. Exiting.') end if + end if deallocate (x_cb_glb, y_cb_glb, z_cb_glb) @@ -545,24 +716,33 @@ contains else call s_assign_default_bc_type(bc_type) end if + #endif end subroutine s_read_parallel_data_files - !> Initialize internal-energy equations from phase mass, mixture momentum, and total energy + !> The purpose of this procedure is to initialize the + !! values of the internal-energy equations of each phase + !! from the mass of each phase, the mixture momentum and + !! mixture-total-energy equations. + !! @param v_vf conservative variables subroutine s_initialize_internal_energy_equations(v_vf) type(scalar_field), dimension(sys_size), intent(inout) :: v_vf - real(wp) :: rho - real(wp) :: dyn_pres - real(wp) :: gamma - real(wp) :: pi_inf - real(wp) :: qv - real(wp), dimension(2) :: Re - real(wp) :: pres, T - integer :: i, j, k, l, c - real(wp), dimension(num_species) :: rhoYks - real(wp) :: pres_mag + + real(wp) :: rho + real(wp) :: dyn_pres + real(wp) :: gamma + real(wp) :: pi_inf + real(wp) :: qv + real(wp), dimension(2) :: Re + real(wp) :: pres, T + + integer :: i, j, k, l, c + + real(wp), dimension(num_species) :: rhoYks + + real(wp) :: pres_mag pres_mag = 0._wp @@ -571,11 +751,13 @@ contains do j = 0, m do k = 0, n do l = 0, p + call s_convert_to_mixture_variables(v_vf, j, k, l, rho, gamma, pi_inf, qv, Re) dyn_pres = 0._wp do i = mom_idx%beg, mom_idx%end - dyn_pres = dyn_pres + 5.e-1_wp*v_vf(i)%sf(j, k, l)*v_vf(i)%sf(j, k, l)/max(rho, sgm_eps) + dyn_pres = dyn_pres + 5.e-1_wp*v_vf(i)%sf(j, k, l)*v_vf(i)%sf(j, k, l) & + /max(rho, sgm_eps) end do if (chemistry) then @@ -588,30 +770,30 @@ contains if (n == 0) then pres_mag = 0.5_wp*(Bx0**2 + v_vf(B_idx%beg)%sf(j, k, l)**2 + v_vf(B_idx%beg + 1)%sf(j, k, l)**2) else - pres_mag = 0.5_wp*(v_vf(B_idx%beg)%sf(j, k, l)**2 + v_vf(B_idx%beg + 1)%sf(j, k, & - & l)**2 + v_vf(B_idx%beg + 2)%sf(j, k, l)**2) + pres_mag = 0.5_wp*(v_vf(B_idx%beg)%sf(j, k, l)**2 + v_vf(B_idx%beg + 1)%sf(j, k, l)**2 + v_vf(B_idx%beg + 2)%sf(j, k, l)**2) end if end if - call s_compute_pressure(v_vf(E_idx)%sf(j, k, l), 0._stp, dyn_pres, pi_inf, gamma, rho, qv, rhoYks, pres, T, & - & pres_mag=pres_mag) + call s_compute_pressure(v_vf(E_idx)%sf(j, k, l), 0._stp, & + dyn_pres, pi_inf, gamma, rho, qv, rhoYks, pres, T, pres_mag=pres_mag) do i = 1, num_fluids - v_vf(i + intxb - 1)%sf(j, k, l) = v_vf(i + advxb - 1)%sf(j, k, & - & l)*(gammas(i)*pres + pi_infs(i)) + v_vf(i + contxb - 1)%sf(j, k, l)*qvs(i) + v_vf(i + intxb - 1)%sf(j, k, l) = v_vf(i + advxb - 1)%sf(j, k, l)*(gammas(i)*pres + pi_infs(i)) & + + v_vf(i + contxb - 1)%sf(j, k, l)*qvs(i) end do + end do end do end do end subroutine s_initialize_internal_energy_equations - !> Advance the simulation by one time step, handling CFL-based dt and time-stepper dispatch + !> @brief Advances the simulation by one time step, handling CFL-based dt and time-stepper dispatch. impure subroutine s_perform_time_step(t_step, time_avg) - - integer, intent(inout) :: t_step + integer, intent(inout) :: t_step real(wp), intent(inout) :: time_avg - integer :: i + + integer :: i if (cfl_dt) then if (cfl_const_dt .and. t_step == 0) call s_compute_dt() @@ -641,13 +823,22 @@ contains if (cfl_dt) then if (proc_rank == 0 .and. mod(t_step - t_step_start, t_step_print) == 0) then print '(" [", I3, "%] Time ", ES16.6, " dt = ", ES16.6, " @ Time Step = ", I8, " Time Avg = ", ES16.6, " Time/step = ", ES12.6, "")', & - & int(ceiling(100._wp*(mytime/t_stop))), mytime, dt, t_step, wall_time_avg, wall_time + int(ceiling(100._wp*(mytime/t_stop))), & + mytime, & + dt, & + t_step, & + wall_time_avg, & + wall_time end if else if (proc_rank == 0 .and. mod(t_step - t_step_start, t_step_print) == 0) then print '(" [", I3, "%] Time step ", I8, " of ", I0, " @ t_step = ", I8, " Time Avg = ", ES12.6, " Time/step= ", ES12.6, "")', & - & int(ceiling(100._wp*(real(t_step - t_step_start)/(t_step_stop - t_step_start + 1)))), & - & t_step - t_step_start + 1, t_step_stop - t_step_start + 1, t_step, wall_time_avg, wall_time + int(ceiling(100._wp*(real(t_step - t_step_start)/(t_step_stop - t_step_start + 1)))), & + t_step - t_step_start + 1, & + t_step_stop - t_step_start + 1, & + t_step, & + wall_time_avg, & + wall_time end if end if @@ -672,17 +863,16 @@ contains end subroutine s_perform_time_step - !> Collect per-process wall-clock times and write aggregate performance metrics to file - impure subroutine s_save_performance_metrics(time_avg, time_final, io_time_avg, io_time_final, proc_time, io_proc_time, & - - & file_exists) + !> @brief Collects per-process wall-clock times and writes aggregate performance metrics to file. + impure subroutine s_save_performance_metrics(time_avg, time_final, io_time_avg, io_time_final, proc_time, io_proc_time, file_exists) - real(wp), intent(inout) :: time_avg, time_final - real(wp), intent(inout) :: io_time_avg, io_time_final + real(wp), intent(inout) :: time_avg, time_final + real(wp), intent(inout) :: io_time_avg, io_time_final real(wp), dimension(:), intent(inout) :: proc_time real(wp), dimension(:), intent(inout) :: io_proc_time - logical, intent(inout) :: file_exists - real(wp) :: grind_time + logical, intent(inout) :: file_exists + + real(wp) :: grind_time call s_mpi_barrier() @@ -703,8 +893,9 @@ contains io_time_final = maxval(io_proc_time) end if - grind_time = time_final*1.0e9_wp/(real(sys_size, wp)*real(maxval((/1, m_glb/)), wp)*real(maxval((/1, n_glb/)), & - & wp)*real(maxval((/1, p_glb/)), wp)) + grind_time = time_final*1.0e9_wp/ & + (real(sys_size, wp)*real(maxval((/1, m_glb/)), wp)* & + real(maxval((/1, n_glb/)), wp)*real(maxval((/1, p_glb/)), wp)) print *, "Performance:", grind_time, "ns/gp/eq/rhs" inquire (FILE='time_data.dat', EXIST=file_exists) @@ -729,19 +920,21 @@ contains write (1, '(I10, F15.8)') num_procs, io_time_final close (1) + end if end subroutine s_save_performance_metrics - !> Save conservative variable data to disk at the current time step + !> @brief Saves conservative variable data to disk at the current time step. impure subroutine s_save_data(t_step, start, finish, io_time_avg, nt) - - integer, intent(inout) :: t_step + integer, intent(inout) :: t_step real(wp), intent(inout) :: start, finish, io_time_avg - integer, intent(inout) :: nt - integer(kind=8) :: i, j, k, l - integer :: stor - integer :: save_count + integer, intent(inout) :: nt + + integer(kind=8) :: i, j, k, l + integer :: stor + + integer :: save_count if (down_sample) then call s_populate_variables_buffers(bc_type, q_cons_ts(1)%vf) @@ -755,7 +948,8 @@ contains do l = idwbuff(3)%beg, idwbuff(3)%end do k = idwbuff(2)%beg, idwbuff(2)%end do j = idwbuff(1)%beg, idwbuff(1)%end - q_cons_ts(2)%vf(i)%sf(j, k, l) = q_cons_ts(1)%vf(i)%sf(j, k, l) + q_cons_ts(2)%vf(i)%sf(j, k, l) = & + q_cons_ts(1)%vf(i)%sf(j, k, l) end do end do end do @@ -794,9 +988,10 @@ contains end if if (bubbles_lagrange) then - $:GPU_UPDATE(host='[lag_id, mtn_pos, mtn_posPrev, mtn_vel, intfc_rad, intfc_vel, bub_R0, Rmax_stats, Rmin_stats, & - & bub_dphidt, gas_p, gas_mv, gas_mg, gas_betaT, gas_betaC]') - do i = 1, nBubs + $:GPU_UPDATE(host='[lag_id, mtn_pos, mtn_posPrev, mtn_vel, intfc_rad, & + & intfc_vel, bub_R0, Rmax_stats, Rmin_stats, bub_dphidt, gas_p, & + & gas_mv, gas_mg, gas_betaT, gas_betaC]') + do i = 1, n_el_bubs_loc if (ieee_is_nan(intfc_rad(i, 1)) .or. intfc_rad(i, 1) <= 0._wp) then call s_mpi_abort("Bubble radius is negative or NaN, please reduce dt.") end if @@ -804,8 +999,8 @@ contains $:GPU_UPDATE(host='[q_beta(1)%sf]') call s_write_data_files(q_cons_ts(stor)%vf, q_T_sf, q_prim_vf, save_count, bc_type, q_beta(1)) - $:GPU_UPDATE(host='[Rmax_stats, Rmin_stats, gas_p, gas_mv, intfc_vel]') - call s_write_restart_lag_bubbles(save_count) ! parallel + $:GPU_UPDATE(host='[Rmax_stats,Rmin_stats,gas_p,gas_mv,intfc_vel]') + call s_write_restart_lag_bubbles(save_count) !parallel if (lag_params%write_bubbles_stats) call s_write_lag_bubble_stats() else call s_write_data_files(q_cons_ts(stor)%vf, q_T_sf, q_prim_vf, save_count, bc_type) @@ -827,22 +1022,18 @@ contains end subroutine s_save_data - !> Initialize all simulation sub-modules in the required dependency order + !> @brief Initializes all simulation sub-modules in the required dependency order. impure subroutine s_initialize_modules - integer :: m_ds, n_ds, p_ds - integer :: i, j, k, l, x_id, y_id, z_id, ix, iy, iz + integer :: m_ds, n_ds, p_ds + integer :: i, j, k, l, x_id, y_id, z_id, ix, iy, iz real(wp) :: temp1, temp2, temp3, temp4 call s_initialize_global_parameters_module() #:if USING_AMD #:for BC in {-5, -6, -7, -8, -9, -10, -11, -12, -13} - @:PROHIBIT(any((/bc_x%beg, bc_x%end, bc_y%beg, bc_y%end, bc_z%beg, & - & bc_z%end/) == ${BC}$) .and. adv_idx%end > 20 .and. (.not. chemistry), & - & "CBC module with AMD compiler requires adv_idx%end <= 20 when case optimization is turned off") - @:PROHIBIT(any((/bc_x%beg, bc_x%end, bc_y%beg, bc_y%end, bc_z%beg, & - & bc_z%end/) == ${BC}$) .and. sys_size > 20 .and. (chemistry), & - & "CBC module with AMD compiler and chemistry requires sys_size <= 20 when case optimization is turned off") + @:PROHIBIT(any((/bc_x%beg, bc_x%end, bc_y%beg, bc_y%end, bc_z%beg, bc_z%end/) == ${BC}$) .and. adv_idx%end > 20 .and. (.not. chemistry), "CBC module with AMD compiler requires adv_idx%end <= 20 when case optimization is turned off") + @:PROHIBIT(any((/bc_x%beg, bc_x%end, bc_y%beg, bc_y%end, bc_z%beg, bc_z%end/) == ${BC}$) .and. sys_size > 20 .and. (chemistry), "CBC module with AMD compiler and chemistry requires sys_size <= 20 when case optimization is turned off") #:endfor #:endif if (bubbles_euler .or. bubbles_lagrange) then @@ -884,10 +1075,11 @@ contains allocate (q_cons_temp(1:sys_size)) do i = 1, sys_size - allocate (q_cons_temp(i)%sf(-1:m_ds + 1,-1:n_ds + 1,-1:p_ds + 1)) + allocate (q_cons_temp(i)%sf(-1:m_ds + 1, -1:n_ds + 1, -1:p_ds + 1)) end do end if + ! Reading in the user provided initial condition and grid data if (down_sample) then call s_read_data_files(q_cons_temp) call s_upsample_data(q_cons_ts(1)%vf, q_cons_temp) @@ -902,6 +1094,7 @@ contains call s_read_data_files(q_cons_ts(1)%vf) end if + ! Populating the buffers of the grid variables using the boundary conditions call s_populate_grid_variables_buffers() if (model_eqns == 3) call s_initialize_internal_energy_equations(q_cons_ts(1)%vf) @@ -915,15 +1108,16 @@ contains ! Initialize the Temperature cache. if (chemistry) call s_compute_q_T_sf(q_T_sf, q_cons_ts(1)%vf, idwint) - ! Computation of parameters, allocation of memory, association of pointers, and/or execution of any other tasks that are - ! needed to properly configure the modules. The preparations below DO DEPEND on the grid being complete. + ! Computation of parameters, allocation of memory, association of pointers, + ! and/or execution of any other tasks that are needed to properly configure + ! the modules. The preparations below DO DEPEND on the grid being complete. if (igr .or. dummy) then call s_initialize_igr_module() end if if (.not. igr .or. dummy) then if (recon_type == WENO_TYPE) then call s_initialize_weno_module() - else if (recon_type == MUSCL_TYPE) then + elseif (recon_type == MUSCL_TYPE) then call s_initialize_muscl_module() end if call s_initialize_cbc_module() @@ -931,22 +1125,19 @@ contains end if call s_initialize_derived_variables() - if (bubbles_lagrange) call s_initialize_bubbles_EL_module(q_cons_ts(1)%vf) - + if (bubbles_lagrange) call s_initialize_bubbles_EL_module(q_cons_ts(1)%vf, bc_type) if (hypoelasticity) call s_initialize_hypoelastic_module() if (hyperelasticity) call s_initialize_hyperelastic_module() end subroutine s_initialize_modules - !> Set up the MPI execution environment, bind GPUs, and decompose the computational domain + !> @brief Sets up the MPI execution environment, binds GPUs, and decomposes the computational domain. impure subroutine s_initialize_mpi_domain - integer :: ierr - #ifdef MFC_GPU real(wp) :: starttime, endtime - integer :: num_devices, local_size, num_nodes, ppn, my_device_num - integer :: dev, devNum, local_rank + integer :: num_devices, local_size, num_nodes, ppn, my_device_num + integer :: dev, devNum, local_rank #ifdef MFC_MPI integer :: local_comm #endif @@ -955,14 +1146,18 @@ contains #endif #endif + ! Initializing MPI execution environment + call s_mpi_initialize() + ! Bind GPUs if OpenACC is enabled #ifdef MFC_GPU #ifndef MFC_MPI local_size = 1 local_rank = 0 #else - call MPI_Comm_split_type(MPI_COMM_WORLD, MPI_COMM_TYPE_SHARED, 0, MPI_INFO_NULL, local_comm, ierr) + call MPI_Comm_split_type(MPI_COMM_WORLD, MPI_COMM_TYPE_SHARED, 0, & + MPI_INFO_NULL, local_comm, ierr) call MPI_Comm_size(local_comm, local_size, ierr) call MPI_Comm_rank(local_comm, local_rank, ierr) #endif @@ -979,20 +1174,24 @@ contains #endif #endif + ! The rank 0 processor assigns default values to the user inputs prior to + ! reading them in from the input file. Next, the user inputs are read and + ! their consistency is checked. The identification of any inconsistencies + ! will result in the termination of the simulation. if (proc_rank == 0) then call s_assign_default_values_to_user_inputs() call s_read_input_file() call s_check_input_file() print '(" Simulating a ", A, " ", I0, "x", I0, "x", I0, " case on ", I0, " rank(s) ", A, ".")', & - #:if not MFC_CASE_OPTIMIZATION +#:if not MFC_CASE_OPTIMIZATION "regular", & - #:else +#:else "case-optimized", & - #:endif - m, n, p, num_procs, & +#:endif + m, n, p, num_procs, & #if defined(MFC_OpenACC) - "with OpenACC offloading" + "with OpenACC offloading" #elif defined(MFC_OpenMP) "with OpenMP offloading" #else @@ -1000,6 +1199,10 @@ contains #endif end if + ! Broadcasting the user inputs to all of the processors and performing the + ! parallel computational domain decomposition. Neither procedure has to be + ! carried out if the simulation is in fact not truly executed in parallel. + call s_mpi_bcast_user_inputs() call s_initialize_parallel_io() @@ -1008,11 +1211,10 @@ contains end subroutine s_initialize_mpi_domain - !> Transfer initial conservative variable and model parameter data to the GPU device + !> @brief Transfers initial conservative variable and model parameter data to the GPU device. subroutine s_initialize_gpu_vars - integer :: i - + !Update GPU DATA if (.not. down_sample) then do i = 1, sys_size $:GPU_UPDATE(device='[q_cons_ts(1)%vf(i)%sf]') @@ -1020,7 +1222,7 @@ contains end if if (qbmm .and. .not. polytropic) then - $:GPU_UPDATE(device='[pb_ts(1)%sf, mv_ts(1)%sf]') + $:GPU_UPDATE(device='[pb_ts(1)%sf,mv_ts(1)%sf]') end if if (chemistry) then $:GPU_UPDATE(device='[q_T_sf%sf]') @@ -1028,33 +1230,36 @@ contains $:GPU_UPDATE(device='[chem_params]') - $:GPU_UPDATE(device='[R0ref, p0ref, rho0ref, ss, pv, vd, mu_l, mu_v, mu_g, gam_v, gam_g, M_v, M_g, R_v, R_g, Tw, cp_v, & - & cp_g, k_vl, k_gl, gam, gam_m, Eu, Ca, Web, Re_inv, Pe_c, phi_vg, phi_gv, omegaN, bubbles_euler, & - & polytropic, polydisperse, qbmm, ptil, bubble_model, thermal, poly_sigma, adv_n, adap_dt, adap_dt_tol, & - & adap_dt_max_iters, n_idx, pi_fac, low_Mach]') + $:GPU_UPDATE(device='[R0ref,p0ref,rho0ref,ss,pv,vd,mu_l,mu_v,mu_g, & + & gam_v,gam_g,M_v,M_g,R_v,R_g,Tw,cp_v,cp_g,k_vl,k_gl, & + & gam, gam_m,Eu,Ca,Web,Re_inv,Pe_c,phi_vg,phi_gv,omegaN, & + & bubbles_euler,polytropic,polydisperse,qbmm, & + & ptil,bubble_model,thermal,poly_sigma,adv_n,adap_dt, & + & adap_dt_tol,adap_dt_max_iters,n_idx,pi_fac,low_Mach]') if (bubbles_euler) then - $:GPU_UPDATE(device='[weight, R0]') + $:GPU_UPDATE(device='[weight,R0]') if (.not. polytropic) then - $:GPU_UPDATE(device='[pb0, Pe_T, k_g, k_v, mass_g0, mass_v0, Re_trans_T, Re_trans_c, Im_trans_T, Im_trans_c]') + $:GPU_UPDATE(device='[pb0,Pe_T,k_g,k_v,mass_g0,mass_v0, & + & Re_trans_T,Re_trans_c,Im_trans_T,Im_trans_c]') else if (qbmm) then $:GPU_UPDATE(device='[pb0]') end if end if - $:GPU_UPDATE(device='[adv_n, adap_dt, adap_dt_tol, adap_dt_max_iters, n_idx, pi_fac, low_Mach]') + $:GPU_UPDATE(device='[adv_n,adap_dt,adap_dt_tol,adap_dt_max_iters,n_idx,pi_fac,low_Mach]') $:GPU_UPDATE(device='[acoustic_source, num_source]') $:GPU_UPDATE(device='[sigma, surface_tension]') - $:GPU_UPDATE(device='[dx, dy, dz, x_cb, x_cc, y_cb, y_cc, z_cb, z_cc]') - $:GPU_UPDATE(device='[bc_x%vb1, bc_x%vb2, bc_x%vb3, bc_x%ve1, bc_x%ve2, bc_x%ve3]') - $:GPU_UPDATE(device='[bc_y%vb1, bc_y%vb2, bc_y%vb3, bc_y%ve1, bc_y%ve2, bc_y%ve3]') - $:GPU_UPDATE(device='[bc_z%vb1, bc_z%vb2, bc_z%vb3, bc_z%ve1, bc_z%ve2, bc_z%ve3]') + $:GPU_UPDATE(device='[dx,dy,dz,x_cb,x_cc,y_cb,y_cc,z_cb,z_cc]') + $:GPU_UPDATE(device='[bc_x%vb1,bc_x%vb2,bc_x%vb3,bc_x%ve1,bc_x%ve2,bc_x%ve3]') + $:GPU_UPDATE(device='[bc_y%vb1,bc_y%vb2,bc_y%vb3,bc_y%ve1,bc_y%ve2,bc_y%ve3]') + $:GPU_UPDATE(device='[bc_z%vb1,bc_z%vb2,bc_z%vb3,bc_z%ve1,bc_z%ve2,bc_z%ve3]') - $:GPU_UPDATE(device='[bc_x%grcbc_in, bc_x%grcbc_out, bc_x%grcbc_vel_out]') - $:GPU_UPDATE(device='[bc_y%grcbc_in, bc_y%grcbc_out, bc_y%grcbc_vel_out]') - $:GPU_UPDATE(device='[bc_z%grcbc_in, bc_z%grcbc_out, bc_z%grcbc_vel_out]') + $:GPU_UPDATE(device='[bc_x%grcbc_in,bc_x%grcbc_out,bc_x%grcbc_vel_out]') + $:GPU_UPDATE(device='[bc_y%grcbc_in,bc_y%grcbc_out,bc_y%grcbc_vel_out]') + $:GPU_UPDATE(device='[bc_z%grcbc_in,bc_z%grcbc_out,bc_z%grcbc_vel_out]') $:GPU_UPDATE(device='[relax, relax_model]') if (relax) then @@ -1065,7 +1270,7 @@ contains $:GPU_UPDATE(device='[ib_markers%sf]') end if #:if not MFC_CASE_OPTIMIZATION - $:GPU_UPDATE(device='[igr, nb, igr_order]') + $:GPU_UPDATE(device='[igr,nb,igr_order]') #:endif #:if USING_AMD block @@ -1078,7 +1283,7 @@ contains end subroutine s_initialize_gpu_vars - !> Finalize and deallocate all simulation sub-modules in reverse initialization order + !> @brief Finalizes and deallocates all simulation sub-modules in reverse initialization order. impure subroutine s_finalize_modules call s_finalize_time_steppers_module() @@ -1094,7 +1299,7 @@ contains call s_finalize_riemann_solvers_module() if (recon_type == WENO_TYPE) then call s_finalize_weno_module() - else if (recon_type == MUSCL_TYPE) then + elseif (recon_type == MUSCL_TYPE) then call s_finalize_muscl_module() end if end if @@ -1113,8 +1318,8 @@ contains if (surface_tension) call s_finalize_surface_tension_module() if (bodyForces) call s_finalize_body_forces_module() + ! Terminating MPI execution environment call s_mpi_finalize() - end subroutine s_finalize_modules end module m_start_up diff --git a/src/simulation/m_surface_tension.fpp b/src/simulation/m_surface_tension.fpp index 4ceb4038ba..c67375bc01 100644 --- a/src/simulation/m_surface_tension.fpp +++ b/src/simulation/m_surface_tension.fpp @@ -9,19 +9,29 @@ !> @brief Computes capillary source fluxes and color-function gradients for the diffuse-interface surface tension model module m_surface_tension - use m_derived_types - use m_global_parameters - use m_mpi_proxy + use m_derived_types !< Definitions of the derived types + + use m_global_parameters !< Definitions of the global parameters + + use m_mpi_proxy !< Message passing interface (MPI) module proxy + use m_variables_conversion + use m_weno - use m_muscl + + use m_muscl !< Monotonic Upstream-centered (MUSCL) + !! schemes for conservation laws + use m_helper + use m_boundary_common implicit none - private; public :: s_initialize_surface_tension_module, s_compute_capillary_source_flux, s_get_capillary, & - & s_finalize_surface_tension_module + private; public :: s_initialize_surface_tension_module, & + s_compute_capillary_source_flux, & + s_get_capillary, & + s_finalize_surface_tension_module !> @name color function gradient components and magnitude !> @{ @@ -31,16 +41,15 @@ module m_surface_tension !> @name cell boundary reconstructed gradient components and magnitude !> @{ - real(wp), allocatable, dimension(:,:,:,:) :: gL_x, gR_x, gL_y, gR_y, gL_z, gR_z + real(wp), allocatable, dimension(:, :, :, :) :: gL_x, gR_x, gL_y, gR_y, gL_z, gR_z !> @} - $:GPU_DECLARE(create='[gL_x, gR_x, gL_y, gR_y, gL_z, gR_z]') + $:GPU_DECLARE(create='[gL_x,gR_x,gL_y,gR_y,gL_z,gR_z]') type(int_bounds_info) :: is1, is2, is3, iv - $:GPU_DECLARE(create='[is1, is2, is3, iv]') + $:GPU_DECLARE(create='[is1,is2,is3,iv]') contains - !> Allocate and initialize surface tension module arrays impure subroutine s_initialize_surface_tension_module integer :: j @@ -59,24 +68,25 @@ contains @:ALLOCATE(gR_y(idwbuff(2)%beg:idwbuff(2)%end, idwbuff(1)%beg:idwbuff(1)%end, idwbuff(3)%beg:idwbuff(3)%end, num_dims + 1)) if (p > 0) then - @:ALLOCATE(gL_z(idwbuff(3)%beg:idwbuff(3)%end, idwbuff(2)%beg:idwbuff(2)%end, idwbuff(1)%beg:idwbuff(1)%end, & - & num_dims + 1)) - @:ALLOCATE(gR_z(idwbuff(3)%beg:idwbuff(3)%end, idwbuff(2)%beg:idwbuff(2)%end, idwbuff(1)%beg:idwbuff(1)%end, & - & num_dims + 1)) + @:ALLOCATE(gL_z(idwbuff(3)%beg:idwbuff(3)%end, idwbuff(2)%beg:idwbuff(2)%end, idwbuff(1)%beg:idwbuff(1)%end, num_dims + 1)) + @:ALLOCATE(gR_z(idwbuff(3)%beg:idwbuff(3)%end, idwbuff(2)%beg:idwbuff(2)%end, idwbuff(1)%beg:idwbuff(1)%end, num_dims + 1)) end if - end subroutine s_initialize_surface_tension_module - !> Compute the capillary source flux from reconstructed color-gradient fields - subroutine s_compute_capillary_source_flux(vSrc_rsx_vf, vSrc_rsy_vf, vSrc_rsz_vf, flux_src_vf, id, isx, isy, isz) - - real(wp), dimension(-1:,0:,0:,1:), intent(in) :: vSrc_rsx_vf - real(wp), dimension(-1:,0:,0:,1:), intent(in) :: vSrc_rsy_vf - real(wp), dimension(-1:,0:,0:,1:), intent(in) :: vSrc_rsz_vf - type(scalar_field), dimension(sys_size), intent(inout) :: flux_src_vf - integer, intent(in) :: id - type(int_bounds_info), intent(in) :: isx, isy, isz - + !> @brief Computes the capillary (surface-tension) source flux from reconstructed color-gradient fields. + subroutine s_compute_capillary_source_flux( & + vSrc_rsx_vf, vSrc_rsy_vf, vSrc_rsz_vf, & + flux_src_vf, & + id, isx, isy, isz) + + real(wp), dimension(-1:, 0:, 0:, 1:), intent(in) :: vSrc_rsx_vf + real(wp), dimension(-1:, 0:, 0:, 1:), intent(in) :: vSrc_rsy_vf + real(wp), dimension(-1:, 0:, 0:, 1:), intent(in) :: vSrc_rsz_vf + type(scalar_field), & + dimension(sys_size), & + intent(inout) :: flux_src_vf + integer, intent(in) :: id + type(int_bounds_info), intent(in) :: isx, isy, isz #:if not MFC_CASE_OPTIMIZATION and USING_AMD real(wp), dimension(3, 3) :: Omega #:else @@ -84,13 +94,14 @@ contains #:endif real(wp) :: w1L, w1R, w2L, w2R, w3L, w3R, w1, w2, w3 real(wp) :: normWL, normWR, normW - integer :: j, k, l, i + integer :: j, k, l, i if (id == 1) then $:GPU_PARALLEL_LOOP(collapse=3, private='[Omega, w1L, w2L, w3L, w1R, w2R, w3R, w1, w2, w3, normWL, normWR, normW]') do l = isz%beg, isz%end do k = isy%beg, isy%end do j = isx%beg, isx%end + w1L = gL_x(j, k, l, 1) w2L = gL_x(j, k, l, 2) w3L = 0._wp @@ -113,26 +124,30 @@ contains @:compute_capillary_stress_tensor() do i = 1, num_dims - flux_src_vf(momxb + i - 1)%sf(j, k, l) = flux_src_vf(momxb + i - 1)%sf(j, k, l) + Omega(1, i) - flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, l) + Omega(1, i)*vSrc_rsx_vf(j, k, & - & l, i) + flux_src_vf(momxb + i - 1)%sf(j, k, l) = & + flux_src_vf(momxb + i - 1)%sf(j, k, l) + Omega(1, i) + + flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, l) + & + Omega(1, i)*vSrc_rsx_vf(j, k, l, i) + end do - ! Continuum surface force capillary stress, Schmidmayer et al. JCP (2017) - flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, l) + sigma*c_divs(num_dims + 1)%sf(j, k, & - & l)*vSrc_rsx_vf(j, k, l, 1) + flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, l) + & + sigma*c_divs(num_dims + 1)%sf(j, k, l)*vSrc_rsx_vf(j, k, l, 1) end if end do end do end do $:END_GPU_PARALLEL_LOOP() - else if (id == 2) then + + elseif (id == 2) then #:if not MFC_CASE_OPTIMIZATION or num_dims > 1 $:GPU_PARALLEL_LOOP(collapse=3, private='[Omega, w1L, w2L, w3L, w1R, w2R, w3R, w1, w2, w3, normWL, normWR, normW]') do l = isz%beg, isz%end do k = isy%beg, isy%end do j = isx%beg, isx%end + w1L = gL_y(k, j, l, 1) w2L = gL_y(k, j, l, 2) w3L = 0._wp @@ -155,26 +170,32 @@ contains @:compute_capillary_stress_tensor() do i = 1, num_dims - flux_src_vf(momxb + i - 1)%sf(j, k, l) = flux_src_vf(momxb + i - 1)%sf(j, k, l) + Omega(2, i) - flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, l) + Omega(2, i)*vSrc_rsy_vf(k, & - & j, l, i) + flux_src_vf(momxb + i - 1)%sf(j, k, l) = & + flux_src_vf(momxb + i - 1)%sf(j, k, l) + Omega(2, i) + + flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, l) + & + Omega(2, i)*vSrc_rsy_vf(k, j, l, i) + end do - flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, & - & l) + sigma*c_divs(num_dims + 1)%sf(j, k, l)*vSrc_rsy_vf(k, j, l, 2) + flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, l) + & + sigma*c_divs(num_dims + 1)%sf(j, k, l)*vSrc_rsy_vf(k, j, l, 2) end if end do end do end do $:END_GPU_PARALLEL_LOOP() #:endif - else if (id == 3) then + + elseif (id == 3) then #:if not MFC_CASE_OPTIMIZATION or num_dims > 2 + $:GPU_PARALLEL_LOOP(collapse=3, private='[Omega, w1L, w2L, w3L, w1R, w2R, w3R, w1, w2, w3, normWL, normWR, normW]') do l = isz%beg, isz%end do k = isy%beg, isy%end do j = isx%beg, isx%end + w1L = gL_z(l, k, j, 1) w2L = gL_z(l, k, j, 2) w3L = 0._wp @@ -197,14 +218,17 @@ contains @:compute_capillary_stress_tensor() do i = 1, num_dims - flux_src_vf(momxb + i - 1)%sf(j, k, l) = flux_src_vf(momxb + i - 1)%sf(j, k, l) + Omega(3, i) - flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, l) + Omega(3, i)*vSrc_rsz_vf(l, & - & k, j, i) + flux_src_vf(momxb + i - 1)%sf(j, k, l) = & + flux_src_vf(momxb + i - 1)%sf(j, k, l) + Omega(3, i) + + flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, l) + & + Omega(3, i)*vSrc_rsz_vf(l, k, j, i) + end do - flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, & - & l) + sigma*c_divs(num_dims + 1)%sf(j, k, l)*vSrc_rsz_vf(l, k, j, 3) + flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, l) + & + sigma*c_divs(num_dims + 1)%sf(j, k, l)*vSrc_rsz_vf(l, k, j, 3) end if end do end do @@ -215,13 +239,14 @@ contains end subroutine s_compute_capillary_source_flux - !> Compute color-function gradients and reconstruct them at cell boundaries + !> @brief Computes color-function gradients and their norms, then reconstructs them at cell boundaries. impure subroutine s_get_capillary(q_prim_vf, bc_type) - type(scalar_field), dimension(sys_size), intent(in) :: q_prim_vf - type(integer_field), dimension(1:num_dims,1:2), intent(in) :: bc_type - type(int_bounds_info) :: isx, isy, isz - integer :: j, k, l, i + type(scalar_field), dimension(sys_size), intent(in) :: q_prim_vf + type(integer_field), dimension(1:num_dims, 1:2), intent(in) :: bc_type + + type(int_bounds_info) :: isx, isy, isz + integer :: j, k, l, i isx%beg = -1; isy%beg = 0; isz%beg = 0 @@ -234,8 +259,8 @@ contains do l = 0, p do k = 0, n do j = 0, m - c_divs(1)%sf(j, k, l) = 1._wp/(x_cc(j + 1) - x_cc(j - 1))*(q_prim_vf(c_idx)%sf(j + 1, k, & - & l) - q_prim_vf(c_idx)%sf(j - 1, k, l)) + c_divs(1)%sf(j, k, l) = 1._wp/(x_cc(j + 1) - x_cc(j - 1))* & + (q_prim_vf(c_idx)%sf(j + 1, k, l) - q_prim_vf(c_idx)%sf(j - 1, k, l)) end do end do end do @@ -245,8 +270,8 @@ contains do l = 0, p do k = 0, n do j = 0, m - c_divs(2)%sf(j, k, l) = 1._wp/(y_cc(k + 1) - y_cc(k - 1))*(q_prim_vf(c_idx)%sf(j, k + 1, & - & l) - q_prim_vf(c_idx)%sf(j, k - 1, l)) + c_divs(2)%sf(j, k, l) = 1._wp/(y_cc(k + 1) - y_cc(k - 1))* & + (q_prim_vf(c_idx)%sf(j, k + 1, l) - q_prim_vf(c_idx)%sf(j, k - 1, l)) end do end do end do @@ -257,8 +282,8 @@ contains do l = 0, p do k = 0, n do j = 0, m - c_divs(3)%sf(j, k, l) = 1._wp/(z_cc(l + 1) - z_cc(l - 1))*(q_prim_vf(c_idx)%sf(j, k, & - & l + 1) - q_prim_vf(c_idx)%sf(j, k, l - 1)) + c_divs(3)%sf(j, k, l) = 1._wp/(z_cc(l + 1) - z_cc(l - 1))* & + (q_prim_vf(c_idx)%sf(j, k, l + 1) - q_prim_vf(c_idx)%sf(j, k, l - 1)) end do end do end do @@ -272,10 +297,14 @@ contains c_divs(num_dims + 1)%sf(j, k, l) = 0._wp $:GPU_LOOP(parallelism='[seq]') do i = 1, num_dims - c_divs(num_dims + 1)%sf(j, k, l) = c_divs(num_dims + 1)%sf(j, k, l) + c_divs(i)%sf(j, k, l)**2._wp + c_divs(num_dims + 1)%sf(j, k, l) = & + c_divs(num_dims + 1)%sf(j, k, l) + & + c_divs(i)%sf(j, k, l)**2._wp end do - - c_divs(num_dims + 1)%sf(j, k, l) = sqrt(real(c_divs(num_dims + 1)%sf(j, k, l), kind=wp)) + !c_divs(num_dims + 1)%sf(j, k, l) = & + !sqrt(c_divs(num_dims + 1)%sf(j, k, l)) + c_divs(num_dims + 1)%sf(j, k, l) = & + sqrt(real(c_divs(num_dims + 1)%sf(j, k, l), kind=wp)) end do end do end do @@ -292,14 +321,17 @@ contains end subroutine s_get_capillary - !> Reconstruct left and right cell-boundary values of capillary variables - subroutine s_reconstruct_cell_boundary_values_capillary(v_vf, vL_x, vL_y, vL_z, vR_x, vR_y, vR_z, norm_dir) - + !> @brief Reconstructs left and right cell-boundary values of capillary (color-gradient) variables using WENO or MUSCL. + subroutine s_reconstruct_cell_boundary_values_capillary(v_vf, vL_x, vL_y, vL_z, vR_x, vR_y, vR_z, & + norm_dir) type(scalar_field), dimension(iv%beg:iv%end), intent(in) :: v_vf - real(wp), dimension(idwbuff(1)%beg:,idwbuff(2)%beg:,idwbuff(3)%beg:,iv%beg:), intent(out) :: vL_x, vL_y, vL_z - real(wp), dimension(idwbuff(1)%beg:,idwbuff(2)%beg:,idwbuff(3)%beg:,iv%beg:), intent(out) :: vR_x, vR_y, vR_z + + real(wp), dimension(idwbuff(1)%beg:, idwbuff(2)%beg:, idwbuff(3)%beg:, iv%beg:), intent(out) :: vL_x, vL_y, vL_z + real(wp), dimension(idwbuff(1)%beg:, idwbuff(2)%beg:, idwbuff(3)%beg:, iv%beg:), intent(out) :: vR_x, vR_y, vR_z integer, intent(in) :: norm_dir - integer :: recon_dir !< Coordinate direction of the reconstruction + + integer :: recon_dir !< Coordinate direction of the reconstruction + integer :: i, j, k, l #:for SCHEME, TYPE in [('weno', 'WENO_TYPE'),('muscl', 'MUSCL_TYPE')] @@ -310,17 +342,20 @@ contains is1 = idwbuff(1); is2 = idwbuff(2); is3 = idwbuff(3) recon_dir = 1; is1%beg = is1%beg + ${SCHEME}$_polyn is1%end = is1%end - ${SCHEME}$_polyn - else if (norm_dir == 2) then + + elseif (norm_dir == 2) then is1 = idwbuff(2); is2 = idwbuff(1); is3 = idwbuff(3) recon_dir = 2; is1%beg = is1%beg + ${SCHEME}$_polyn is1%end = is1%end - ${SCHEME}$_polyn + else is1 = idwbuff(3); is2 = idwbuff(2); is3 = idwbuff(1) recon_dir = 3; is1%beg = is1%beg + ${SCHEME}$_polyn is1%end = is1%end - ${SCHEME}$_polyn + end if - $:GPU_UPDATE(device='[is1, is2, is3, iv]') + $:GPU_UPDATE(device='[is1,is2,is3,iv]') end if #:endfor @@ -367,9 +402,8 @@ contains end subroutine s_reconstruct_cell_boundary_values_capillary - !> Finalize the surface tension module + !> @brief Deallocates the color-gradient divergence and reconstructed boundary arrays for surface tension. impure subroutine s_finalize_surface_tension_module - integer :: j do j = 1, num_dims diff --git a/src/simulation/m_time_steppers.fpp b/src/simulation/m_time_steppers.fpp index 4a741a4068..cc17df07f1 100644 --- a/src/simulation/m_time_steppers.fpp +++ b/src/simulation/m_time_steppers.fpp @@ -8,60 +8,92 @@ !> @brief Total-variation-diminishing (TVD) Runge--Kutta time integrators (1st-, 2nd-, and 3rd-order SSP) module m_time_steppers - use m_derived_types - use m_global_parameters - use m_rhs - use m_pressure_relaxation - use m_data_output - use m_bubbles_EE - use m_bubbles_EL + use m_derived_types !< Definitions of the derived types + + use m_global_parameters !< Definitions of the global parameters + + use m_rhs !< Right-hane-side (RHS) evaluation procedures + + use m_pressure_relaxation !< Pressure relaxation procedures + + use m_data_output !< Run-time info & solution data output procedures + + use m_bubbles_EE !< Ensemble-averaged bubble dynamics routines + + use m_bubbles_EL !< Lagrange bubble dynamics routines + use m_ibm + use m_hyperelastic - use m_mpi_proxy + + use m_mpi_proxy !< Message passing interface (MPI) module proxy + use m_boundary_common + use m_helper + use m_sim_helpers + use m_fftw + use m_nvtx + use m_thermochem, only: num_species + use m_body_forces + use m_derived_variables implicit none - type(vector_field), allocatable, dimension(:) :: q_cons_ts !< Cell-average conservative variables at each time-stage (TS) - type(scalar_field), allocatable, dimension(:) :: q_prim_vf !< Cell-average primitive variables at the current time-stage - type(scalar_field), allocatable, dimension(:) :: rhs_vf !< Cell-average RHS variables at the current time-stage - type(integer_field), allocatable, dimension(:,:) :: bc_type !< Boundary condition identifiers - !> Cell-average primitive variables at consecutive TIMESTEPS - type(vector_field), allocatable, dimension(:) :: q_prim_ts1, q_prim_ts2 - real(wp), allocatable, dimension(:,:,:,:,:) :: rhs_pb - type(scalar_field) :: q_T_sf !< Cell-average temperature variables at the current time-stage - real(wp), allocatable, dimension(:,:,:,:,:) :: rhs_mv - real(wp), allocatable, dimension(:,:,:) :: max_dt - integer, private :: num_ts !< Number of time stages in the time-stepping scheme - integer :: stor !< storage index - real(wp), allocatable, dimension(:,:) :: rk_coef - integer, private :: num_probe_ts - - $:GPU_DECLARE(create='[q_cons_ts, q_prim_vf, q_T_sf, rhs_vf, q_prim_ts1, q_prim_ts2, rhs_mv, rhs_pb, max_dt, rk_coef, stor, bc_type]') - - !> @cond + type(vector_field), allocatable, dimension(:) :: q_cons_ts !< + !! Cell-average conservative variables at each time-stage (TS) + + type(scalar_field), allocatable, dimension(:) :: q_prim_vf !< + !! Cell-average primitive variables at the current time-stage + + type(scalar_field), allocatable, dimension(:) :: rhs_vf !< + !! Cell-average RHS variables at the current time-stage + + type(integer_field), allocatable, dimension(:, :) :: bc_type !< + !! Boundary condition identifiers + + type(vector_field), allocatable, dimension(:) :: q_prim_ts1, q_prim_ts2 !< + !! Cell-average primitive variables at consecutive TIMESTEPS + + real(wp), allocatable, dimension(:, :, :, :, :) :: rhs_pb + + type(scalar_field) :: q_T_sf !< + !! Cell-average temperature variables at the current time-stage + + real(wp), allocatable, dimension(:, :, :, :, :) :: rhs_mv + + integer, private :: num_ts !< + !! Number of time stages in the time-stepping scheme + + integer :: stor !< storage index + real(wp), allocatable, dimension(:, :) :: rk_coef + integer, private :: num_probe_ts + + $:GPU_DECLARE(create='[q_cons_ts,q_prim_vf,q_T_sf,rhs_vf,q_prim_ts1,q_prim_ts2,rhs_mv,rhs_pb,rk_coef,stor,bc_type]') + +!> @cond #if defined(__NVCOMPILER_GPU_UNIFIED_MEM) - real(stp), allocatable, dimension(:,:,:,:), pinned, target :: q_cons_ts_pool_host + real(stp), allocatable, dimension(:, :, :, :), pinned, target :: q_cons_ts_pool_host #elif defined(FRONTIER_UNIFIED) - real(stp), pointer, contiguous, dimension(:,:,:,:) :: q_cons_ts_pool_host, q_cons_ts_pool_device - integer(kind=8) :: pool_dims(4), pool_starts(4) - integer(kind=8) :: pool_size - type(c_ptr) :: cptr_host, cptr_device + real(stp), pointer, contiguous, dimension(:, :, :, :) :: q_cons_ts_pool_host, q_cons_ts_pool_device + integer(kind=8) :: pool_dims(4), pool_starts(4) + integer(kind=8) :: pool_size + type(c_ptr) :: cptr_host, cptr_device #endif - !> @endcond +!> @endcond contains - !> Initialize the time steppers module + !> The computation of parameters, the allocation of memory, + !! the association of pointers and/or the execution of any + !! other procedures that are necessary to setup the module. impure subroutine s_initialize_time_steppers_module - #ifdef FRONTIER_UNIFIED use hipfort use hipfort_hipmalloc @@ -70,12 +102,12 @@ contains use openacc #endif #endif - integer :: i, j !< Generic loop iterators - ! Setting number of time-stages for selected time-stepping scheme + integer :: i, j !< Generic loop iterators + ! Setting number of time-stages for selected time-stepping scheme if (time_stepper == 1) then num_ts = 1 - else if (any(time_stepper == (/2, 3/))) then + elseif (any(time_stepper == (/2, 3/))) then num_ts = 2 end if @@ -92,27 +124,32 @@ contains @:PREFER_GPU(q_cons_ts(i)%vf) end do - !> @cond +!> @cond #if defined(__NVCOMPILER_GPU_UNIFIED_MEM) if (num_ts == 2 .and. nv_uvm_out_of_core) then ! host allocation for q_cons_ts(2)%vf(j)%sf for all j - allocate (q_cons_ts_pool_host(idwbuff(1)%beg:idwbuff(1)%end,idwbuff(2)%beg:idwbuff(2)%end, & - & idwbuff(3)%beg:idwbuff(3)%end,1:sys_size)) + allocate (q_cons_ts_pool_host(idwbuff(1)%beg:idwbuff(1)%end, & + idwbuff(2)%beg:idwbuff(2)%end, & + idwbuff(3)%beg:idwbuff(3)%end, & + 1:sys_size)) end if do j = 1, sys_size ! q_cons_ts(1) lives on the device - @:ALLOCATE(q_cons_ts(1)%vf(j)%sf(idwbuff(1)%beg:idwbuff(1)%end, idwbuff(2)%beg:idwbuff(2)%end, & - & idwbuff(3)%beg:idwbuff(3)%end)) + @:ALLOCATE(q_cons_ts(1)%vf(j)%sf(idwbuff(1)%beg:idwbuff(1)%end, & + idwbuff(2)%beg:idwbuff(2)%end, & + idwbuff(3)%beg:idwbuff(3)%end)) @:PREFER_GPU(q_cons_ts(1)%vf(j)%sf) if (num_ts == 2) then if (nv_uvm_out_of_core) then ! q_cons_ts(2) lives on the host - q_cons_ts(2)%vf(j)%sf(idwbuff(1)%beg:idwbuff(1)%end,idwbuff(2)%beg:idwbuff(2)%end, & - & idwbuff(3)%beg:idwbuff(3)%end) => q_cons_ts_pool_host(:,:,:,j) + q_cons_ts(2)%vf(j)%sf(idwbuff(1)%beg:idwbuff(1)%end, & + idwbuff(2)%beg:idwbuff(2)%end, & + idwbuff(3)%beg:idwbuff(3)%end) => q_cons_ts_pool_host(:, :, :, j) else - @:ALLOCATE(q_cons_ts(2)%vf(j)%sf(idwbuff(1)%beg:idwbuff(1)%end, idwbuff(2)%beg:idwbuff(2)%end, & - & idwbuff(3)%beg:idwbuff(3)%end)) + @:ALLOCATE(q_cons_ts(2)%vf(j)%sf(idwbuff(1)%beg:idwbuff(1)%end, & + idwbuff(2)%beg:idwbuff(2)%end, & + idwbuff(3)%beg:idwbuff(3)%end)) @:PREFER_GPU(q_cons_ts(2)%vf(j)%sf) end if end if @@ -122,7 +159,8 @@ contains @:ACC_SETUP_VFs(q_cons_ts(i)) end do #elif defined(FRONTIER_UNIFIED) - ! Allocate to memory regions using hip calls that we will attach pointers to + ! Allocate to memory regions using hip calls + ! that we will attach pointers to do i = 1, 3 pool_dims(i) = idwbuff(i)%end - idwbuff(i)%beg + 1 pool_starts(i) = idwbuff(i)%beg @@ -130,15 +168,14 @@ contains pool_dims(4) = sys_size pool_starts(4) = 1 #ifdef MFC_MIXED_PRECISION - pool_size = 1_8*(idwbuff(1)%end - idwbuff(1)%beg + 1)*(idwbuff(2)%end - idwbuff(2)%beg + 1)*(idwbuff(3)%end - idwbuff(3) & - & %beg + 1)*sys_size + pool_size = 1_8*(idwbuff(1)%end - idwbuff(1)%beg + 1)*(idwbuff(2)%end - idwbuff(2)%beg + 1)*(idwbuff(3)%end - idwbuff(3)%beg + 1)*sys_size call hipCheck(hipMalloc_(cptr_device, pool_size*2_8)) call c_f_pointer(cptr_device, q_cons_ts_pool_device, shape=pool_dims) - q_cons_ts_pool_device(idwbuff(1)%beg:,idwbuff(2)%beg:,idwbuff(3)%beg:,1:) => q_cons_ts_pool_device + q_cons_ts_pool_device(idwbuff(1)%beg:, idwbuff(2)%beg:, idwbuff(3)%beg:, 1:) => q_cons_ts_pool_device call hipCheck(hipMallocManaged_(cptr_host, pool_size*2_8, hipMemAttachGlobal)) call c_f_pointer(cptr_host, q_cons_ts_pool_host, shape=pool_dims) - q_cons_ts_pool_host(idwbuff(1)%beg:,idwbuff(2)%beg:,idwbuff(3)%beg:,1:) => q_cons_ts_pool_host + q_cons_ts_pool_host(idwbuff(1)%beg:, idwbuff(2)%beg:, idwbuff(3)%beg:, 1:) => q_cons_ts_pool_host #else ! Doing hipMalloc then mapping should be most performant call hipCheck(hipMalloc(q_cons_ts_pool_device, dims8=pool_dims, lbounds8=pool_starts)) @@ -146,26 +183,27 @@ contains #if defined(MFC_OpenACC) call acc_map_data(q_cons_ts_pool_device, c_loc(q_cons_ts_pool_device), c_sizeof(q_cons_ts_pool_device)) #endif - ! CCE see it can access this and will leave it on the host. It will stay on the host so long as HSA_XNACK=1 NOTE: WE CANNOT - ! DO ATOMICS INTO THIS MEMORY. We have to change a property to use atomics here Otherwise leaving this as fine-grained will - ! actually help performance since it can't be cached in GPU L2 + ! CCE see it can access this and will leave it on the host. It will stay on the host so long as HSA_XNACK=1 + ! NOTE: WE CANNOT DO ATOMICS INTO THIS MEMORY. We have to change a property to use atomics here + ! Otherwise leaving this as fine-grained will actually help performance since it can't be cached in GPU L2 if (num_ts == 2) then call hipCheck(hipMallocManaged(q_cons_ts_pool_host, dims8=pool_dims, lbounds8=pool_starts, flags=hipMemAttachGlobal)) #if defined(MFC_OpenMP) - call hipCheck(hipMemAdvise(c_loc(q_cons_ts_pool_host), c_sizeof(q_cons_ts_pool_host), & - & hipMemAdviseSetPreferredLocation, -1)) + call hipCheck(hipMemAdvise(c_loc(q_cons_ts_pool_host), c_sizeof(q_cons_ts_pool_host), hipMemAdviseSetPreferredLocation, -1)) #endif end if #endif do j = 1, sys_size ! q_cons_ts(1) lives on the device - q_cons_ts(1)%vf(j)%sf(idwbuff(1)%beg:idwbuff(1)%end,idwbuff(2)%beg:idwbuff(2)%end, & - & idwbuff(3)%beg:idwbuff(3)%end) => q_cons_ts_pool_device(:,:,:,j) + q_cons_ts(1)%vf(j)%sf(idwbuff(1)%beg:idwbuff(1)%end, & + idwbuff(2)%beg:idwbuff(2)%end, & + idwbuff(3)%beg:idwbuff(3)%end) => q_cons_ts_pool_device(:, :, :, j) if (num_ts == 2) then ! q_cons_ts(2) lives on the host - q_cons_ts(2)%vf(j)%sf(idwbuff(1)%beg:idwbuff(1)%end,idwbuff(2)%beg:idwbuff(2)%end, & - & idwbuff(3)%beg:idwbuff(3)%end) => q_cons_ts_pool_host(:,:,:,j) + q_cons_ts(2)%vf(j)%sf(idwbuff(1)%beg:idwbuff(1)%end, & + idwbuff(2)%beg:idwbuff(2)%end, & + idwbuff(3)%beg:idwbuff(3)%end) => q_cons_ts_pool_host(:, :, :, j) end if end do @@ -176,17 +214,18 @@ contains end do end do #else - !> @endcond +!> @endcond do i = 1, num_ts do j = 1, sys_size - @:ALLOCATE(q_cons_ts(i)%vf(j)%sf(idwbuff(1)%beg:idwbuff(1)%end, idwbuff(2)%beg:idwbuff(2)%end, & - & idwbuff(3)%beg:idwbuff(3)%end)) + @:ALLOCATE(q_cons_ts(i)%vf(j)%sf(idwbuff(1)%beg:idwbuff(1)%end, & + idwbuff(2)%beg:idwbuff(2)%end, & + idwbuff(3)%beg:idwbuff(3)%end)) end do @:ACC_SETUP_VFs(q_cons_ts(i)) end do - !> @cond +!> @cond #endif - !> @endcond +!> @endcond ! Allocating the cell-average primitive ts variables if (probe_wrt) then @@ -198,8 +237,9 @@ contains do i = 1, num_probe_ts do j = 1, sys_size - @:ALLOCATE(q_prim_ts1(i)%vf(j)%sf(idwbuff(1)%beg:idwbuff(1)%end, idwbuff(2)%beg:idwbuff(2)%end, & - & idwbuff(3)%beg:idwbuff(3)%end)) + @:ALLOCATE(q_prim_ts1(i)%vf(j)%sf(idwbuff(1)%beg:idwbuff(1)%end, & + idwbuff(2)%beg:idwbuff(2)%end, & + idwbuff(3)%beg:idwbuff(3)%end)) end do @:ACC_SETUP_VFs(q_prim_ts1(i)) end do @@ -212,8 +252,9 @@ contains do i = 1, num_probe_ts do j = 1, sys_size - @:ALLOCATE(q_prim_ts2(i)%vf(j)%sf(idwbuff(1)%beg:idwbuff(1)%end, idwbuff(2)%beg:idwbuff(2)%end, & - & idwbuff(3)%beg:idwbuff(3)%end)) + @:ALLOCATE(q_prim_ts2(i)%vf(j)%sf(idwbuff(1)%beg:idwbuff(1)%end, & + idwbuff(2)%beg:idwbuff(2)%end, & + idwbuff(3)%beg:idwbuff(3)%end)) end do @:ACC_SETUP_VFs(q_prim_ts2(i)) end do @@ -224,110 +265,129 @@ contains if (.not. igr) then do i = 1, adv_idx%end - @:ALLOCATE(q_prim_vf(i)%sf(idwbuff(1)%beg:idwbuff(1)%end, idwbuff(2)%beg:idwbuff(2)%end, & - & idwbuff(3)%beg:idwbuff(3)%end)) + @:ALLOCATE(q_prim_vf(i)%sf(idwbuff(1)%beg:idwbuff(1)%end, & + idwbuff(2)%beg:idwbuff(2)%end, & + idwbuff(3)%beg:idwbuff(3)%end)) @:ACC_SETUP_SFs(q_prim_vf(i)) end do if (bubbles_euler) then do i = bub_idx%beg, bub_idx%end - @:ALLOCATE(q_prim_vf(i)%sf(idwbuff(1)%beg:idwbuff(1)%end, idwbuff(2)%beg:idwbuff(2)%end, & - & idwbuff(3)%beg:idwbuff(3)%end)) + @:ALLOCATE(q_prim_vf(i)%sf(idwbuff(1)%beg:idwbuff(1)%end, & + idwbuff(2)%beg:idwbuff(2)%end, & + idwbuff(3)%beg:idwbuff(3)%end)) @:ACC_SETUP_SFs(q_prim_vf(i)) end do if (adv_n) then - @:ALLOCATE(q_prim_vf(n_idx)%sf(idwbuff(1)%beg:idwbuff(1)%end, idwbuff(2)%beg:idwbuff(2)%end, & - & idwbuff(3)%beg:idwbuff(3)%end)) + @:ALLOCATE(q_prim_vf(n_idx)%sf(idwbuff(1)%beg:idwbuff(1)%end, & + idwbuff(2)%beg:idwbuff(2)%end, & + idwbuff(3)%beg:idwbuff(3)%end)) @:ACC_SETUP_SFs(q_prim_vf(n_idx)) end if end if if (mhd) then do i = B_idx%beg, B_idx%end - @:ALLOCATE(q_prim_vf(i)%sf(idwbuff(1)%beg:idwbuff(1)%end, idwbuff(2)%beg:idwbuff(2)%end, & - & idwbuff(3)%beg:idwbuff(3)%end)) + @:ALLOCATE(q_prim_vf(i)%sf(idwbuff(1)%beg:idwbuff(1)%end, & + idwbuff(2)%beg:idwbuff(2)%end, & + idwbuff(3)%beg:idwbuff(3)%end)) @:ACC_SETUP_SFs(q_prim_vf(i)) end do end if if (elasticity) then do i = stress_idx%beg, stress_idx%end - @:ALLOCATE(q_prim_vf(i)%sf(idwbuff(1)%beg:idwbuff(1)%end, idwbuff(2)%beg:idwbuff(2)%end, & - & idwbuff(3)%beg:idwbuff(3)%end)) + @:ALLOCATE(q_prim_vf(i)%sf(idwbuff(1)%beg:idwbuff(1)%end, & + idwbuff(2)%beg:idwbuff(2)%end, & + idwbuff(3)%beg:idwbuff(3)%end)) @:ACC_SETUP_SFs(q_prim_vf(i)) end do end if if (hyperelasticity) then do i = xibeg, xiend + 1 - @:ALLOCATE(q_prim_vf(i)%sf(idwbuff(1)%beg:idwbuff(1)%end, idwbuff(2)%beg:idwbuff(2)%end, & - & idwbuff(3)%beg:idwbuff(3)%end)) + @:ALLOCATE(q_prim_vf(i)%sf(idwbuff(1)%beg:idwbuff(1)%end, & + idwbuff(2)%beg:idwbuff(2)%end, & + idwbuff(3)%beg:idwbuff(3)%end)) @:ACC_SETUP_SFs(q_prim_vf(i)) end do end if if (cont_damage) then - @:ALLOCATE(q_prim_vf(damage_idx)%sf(idwbuff(1)%beg:idwbuff(1)%end, idwbuff(2)%beg:idwbuff(2)%end, & - & idwbuff(3)%beg:idwbuff(3)%end)) + @:ALLOCATE(q_prim_vf(damage_idx)%sf(idwbuff(1)%beg:idwbuff(1)%end, & + idwbuff(2)%beg:idwbuff(2)%end, & + idwbuff(3)%beg:idwbuff(3)%end)) @:ACC_SETUP_SFs(q_prim_vf(damage_idx)) end if if (hyper_cleaning) then - @:ALLOCATE(q_prim_vf(psi_idx)%sf(idwbuff(1)%beg:idwbuff(1)%end, idwbuff(2)%beg:idwbuff(2)%end, & - & idwbuff(3)%beg:idwbuff(3)%end)) + @:ALLOCATE(q_prim_vf(psi_idx)%sf(idwbuff(1)%beg:idwbuff(1)%end, & + idwbuff(2)%beg:idwbuff(2)%end, & + idwbuff(3)%beg:idwbuff(3)%end)) @:ACC_SETUP_SFs(q_prim_vf(psi_idx)) end if if (model_eqns == 3) then do i = internalEnergies_idx%beg, internalEnergies_idx%end - @:ALLOCATE(q_prim_vf(i)%sf(idwbuff(1)%beg:idwbuff(1)%end, idwbuff(2)%beg:idwbuff(2)%end, & - & idwbuff(3)%beg:idwbuff(3)%end)) + @:ALLOCATE(q_prim_vf(i)%sf(idwbuff(1)%beg:idwbuff(1)%end, & + idwbuff(2)%beg:idwbuff(2)%end, & + idwbuff(3)%beg:idwbuff(3)%end)) @:ACC_SETUP_SFs(q_prim_vf(i)) end do end if if (surface_tension) then - @:ALLOCATE(q_prim_vf(c_idx)%sf(idwbuff(1)%beg:idwbuff(1)%end, idwbuff(2)%beg:idwbuff(2)%end, & - & idwbuff(3)%beg:idwbuff(3)%end)) + @:ALLOCATE(q_prim_vf(c_idx)%sf(idwbuff(1)%beg:idwbuff(1)%end, & + idwbuff(2)%beg:idwbuff(2)%end, & + idwbuff(3)%beg:idwbuff(3)%end)) @:ACC_SETUP_SFs(q_prim_vf(c_idx)) end if if (chemistry) then do i = chemxb, chemxe - @:ALLOCATE(q_prim_vf(i)%sf(idwbuff(1)%beg:idwbuff(1)%end, idwbuff(2)%beg:idwbuff(2)%end, & - & idwbuff(3)%beg:idwbuff(3)%end)) + @:ALLOCATE(q_prim_vf(i)%sf(idwbuff(1)%beg:idwbuff(1)%end, & + idwbuff(2)%beg:idwbuff(2)%end, & + idwbuff(3)%beg:idwbuff(3)%end)) @:ACC_SETUP_SFs(q_prim_vf(i)) end do - @:ALLOCATE(q_T_sf%sf(idwbuff(1)%beg:idwbuff(1)%end, idwbuff(2)%beg:idwbuff(2)%end, idwbuff(3)%beg:idwbuff(3)%end)) + @:ALLOCATE(q_T_sf%sf(idwbuff(1)%beg:idwbuff(1)%end, & + idwbuff(2)%beg:idwbuff(2)%end, & + idwbuff(3)%beg:idwbuff(3)%end)) @:ACC_SETUP_SFs(q_T_sf) end if end if @:ALLOCATE(pb_ts(1:2)) - ! Initialize bubble variables pb and mv at all quadrature nodes for all R0 bins + !Initialize bubble variables pb and mv at all quadrature nodes for all R0 bins if (qbmm .and. (.not. polytropic)) then - @:ALLOCATE(pb_ts(1)%sf(idwbuff(1)%beg:idwbuff(1)%end, idwbuff(2)%beg:idwbuff(2)%end, idwbuff(3)%beg:idwbuff(3)%end, & - & 1:nnode, 1:nb)) + @:ALLOCATE(pb_ts(1)%sf(idwbuff(1)%beg:idwbuff(1)%end, & + idwbuff(2)%beg:idwbuff(2)%end, & + idwbuff(3)%beg:idwbuff(3)%end, 1:nnode, 1:nb)) @:ACC_SETUP_SFs(pb_ts(1)) - @:ALLOCATE(pb_ts(2)%sf(idwbuff(1)%beg:idwbuff(1)%end, idwbuff(2)%beg:idwbuff(2)%end, idwbuff(3)%beg:idwbuff(3)%end, & - & 1:nnode, 1:nb)) + @:ALLOCATE(pb_ts(2)%sf(idwbuff(1)%beg:idwbuff(1)%end, & + idwbuff(2)%beg:idwbuff(2)%end, & + idwbuff(3)%beg:idwbuff(3)%end, 1:nnode, 1:nb)) @:ACC_SETUP_SFs(pb_ts(2)) - @:ALLOCATE(rhs_pb(idwbuff(1)%beg:idwbuff(1)%end, idwbuff(2)%beg:idwbuff(2)%end, idwbuff(3)%beg:idwbuff(3)%end, & - & 1:nnode, 1:nb)) + @:ALLOCATE(rhs_pb(idwbuff(1)%beg:idwbuff(1)%end, & + idwbuff(2)%beg:idwbuff(2)%end, & + idwbuff(3)%beg:idwbuff(3)%end, 1:nnode, 1:nb)) else if (qbmm .and. polytropic) then - @:ALLOCATE(pb_ts(1)%sf(idwbuff(1)%beg:idwbuff(1)%beg + 1, idwbuff(2)%beg:idwbuff(2)%beg + 1, & - & idwbuff(3)%beg:idwbuff(3)%beg + 1, 1:nnode, 1:nb)) + @:ALLOCATE(pb_ts(1)%sf(idwbuff(1)%beg:idwbuff(1)%beg + 1, & + idwbuff(2)%beg:idwbuff(2)%beg + 1, & + idwbuff(3)%beg:idwbuff(3)%beg + 1, 1:nnode, 1:nb)) @:ACC_SETUP_SFs(pb_ts(1)) - @:ALLOCATE(pb_ts(2)%sf(idwbuff(1)%beg:idwbuff(1)%beg + 1, idwbuff(2)%beg:idwbuff(2)%beg + 1, & - & idwbuff(3)%beg:idwbuff(3)%beg + 1, 1:nnode, 1:nb)) + @:ALLOCATE(pb_ts(2)%sf(idwbuff(1)%beg:idwbuff(1)%beg + 1, & + idwbuff(2)%beg:idwbuff(2)%beg + 1, & + idwbuff(3)%beg:idwbuff(3)%beg + 1, 1:nnode, 1:nb)) @:ACC_SETUP_SFs(pb_ts(2)) - @:ALLOCATE(rhs_pb(idwbuff(1)%beg:idwbuff(1)%beg + 1, idwbuff(2)%beg:idwbuff(2)%beg + 1, & - & idwbuff(3)%beg:idwbuff(3)%beg + 1, 1:nnode, 1:nb)) + @:ALLOCATE(rhs_pb(idwbuff(1)%beg:idwbuff(1)%beg + 1, & + idwbuff(2)%beg:idwbuff(2)%beg + 1, & + idwbuff(3)%beg:idwbuff(3)%beg + 1, 1:nnode, 1:nb)) else @:ALLOCATE(pb_ts(1)%sf(0,0,0,0,0)) @:ACC_SETUP_SFs(pb_ts(1)) @@ -341,27 +401,34 @@ contains @:ALLOCATE(mv_ts(1:2)) if (qbmm .and. (.not. polytropic)) then - @:ALLOCATE(mv_ts(1)%sf(idwbuff(1)%beg:idwbuff(1)%end, idwbuff(2)%beg:idwbuff(2)%end, idwbuff(3)%beg:idwbuff(3)%end, & - & 1:nnode, 1:nb)) + @:ALLOCATE(mv_ts(1)%sf(idwbuff(1)%beg:idwbuff(1)%end, & + idwbuff(2)%beg:idwbuff(2)%end, & + idwbuff(3)%beg:idwbuff(3)%end, 1:nnode, 1:nb)) @:ACC_SETUP_SFs(mv_ts(1)) - @:ALLOCATE(mv_ts(2)%sf(idwbuff(1)%beg:idwbuff(1)%end, idwbuff(2)%beg:idwbuff(2)%end, idwbuff(3)%beg:idwbuff(3)%end, & - & 1:nnode, 1:nb)) + @:ALLOCATE(mv_ts(2)%sf(idwbuff(1)%beg:idwbuff(1)%end, & + idwbuff(2)%beg:idwbuff(2)%end, & + idwbuff(3)%beg:idwbuff(3)%end, 1:nnode, 1:nb)) @:ACC_SETUP_SFs(mv_ts(2)) - @:ALLOCATE(rhs_mv(idwbuff(1)%beg:idwbuff(1)%end, idwbuff(2)%beg:idwbuff(2)%end, idwbuff(3)%beg:idwbuff(3)%end, & - & 1:nnode, 1:nb)) + @:ALLOCATE(rhs_mv(idwbuff(1)%beg:idwbuff(1)%end, & + idwbuff(2)%beg:idwbuff(2)%end, & + idwbuff(3)%beg:idwbuff(3)%end, 1:nnode, 1:nb)) + else if (qbmm .and. polytropic) then - @:ALLOCATE(mv_ts(1)%sf(idwbuff(1)%beg:idwbuff(1)%beg + 1, idwbuff(2)%beg:idwbuff(2)%beg + 1, & - & idwbuff(3)%beg:idwbuff(3)%beg + 1, 1:nnode, 1:nb)) + @:ALLOCATE(mv_ts(1)%sf(idwbuff(1)%beg:idwbuff(1)%beg + 1, & + idwbuff(2)%beg:idwbuff(2)%beg + 1, & + idwbuff(3)%beg:idwbuff(3)%beg + 1, 1:nnode, 1:nb)) @:ACC_SETUP_SFs(mv_ts(1)) - @:ALLOCATE(mv_ts(2)%sf(idwbuff(1)%beg:idwbuff(1)%beg + 1, idwbuff(2)%beg:idwbuff(2)%beg + 1, & - & idwbuff(3)%beg:idwbuff(3)%beg + 1, 1:nnode, 1:nb)) + @:ALLOCATE(mv_ts(2)%sf(idwbuff(1)%beg:idwbuff(1)%beg + 1, & + idwbuff(2)%beg:idwbuff(2)%beg + 1, & + idwbuff(3)%beg:idwbuff(3)%beg + 1, 1:nnode, 1:nb)) @:ACC_SETUP_SFs(mv_ts(2)) - @:ALLOCATE(rhs_mv(idwbuff(1)%beg:idwbuff(1)%beg + 1, idwbuff(2)%beg:idwbuff(2)%beg + 1, & - & idwbuff(3)%beg:idwbuff(3)%beg + 1, 1:nnode, 1:nb)) + @:ALLOCATE(rhs_mv(idwbuff(1)%beg:idwbuff(1)%beg + 1, & + idwbuff(2)%beg:idwbuff(2)%beg + 1, & + idwbuff(3)%beg:idwbuff(3)%beg + 1, 1:nnode, 1:nb)) else @:ALLOCATE(mv_ts(1)%sf(0,0,0,0,0)) @:ACC_SETUP_SFs(mv_ts(1)) @@ -399,10 +466,6 @@ contains call s_open_ib_state_file() end if - if (cfl_dt) then - @:ALLOCATE(max_dt(0:m, 0:n, 0:p)) - end if - ! Allocating arrays to store the bc types @:ALLOCATE(bc_type(1:num_dims,1:2)) @@ -436,34 +499,34 @@ contains end if ! TVD RK coefficients - @:ALLOCATE(rk_coef(time_stepper, 4)) + @:ALLOCATE (rk_coef(time_stepper, 4)) if (time_stepper == 1) then - rk_coef(1,:) = (/1._wp, 0._wp, 1._wp, 1._wp/) + rk_coef(1, :) = (/1._wp, 0._wp, 1._wp, 1._wp/) else if (time_stepper == 2) then - rk_coef(1,:) = (/1._wp, 0._wp, 1._wp, 1._wp/) - rk_coef(2,:) = (/1._wp, 1._wp, 1._wp, 2._wp/) + rk_coef(1, :) = (/1._wp, 0._wp, 1._wp, 1._wp/) + rk_coef(2, :) = (/1._wp, 1._wp, 1._wp, 2._wp/) else if (time_stepper == 3) then - rk_coef(1,:) = (/1._wp, 0._wp, 1._wp, 1._wp/) - rk_coef(2,:) = (/1._wp, 3._wp, 1._wp, 4._wp/) - rk_coef(3,:) = (/2._wp, 1._wp, 2._wp, 3._wp/) + rk_coef(1, :) = (/1._wp, 0._wp, 1._wp, 1._wp/) + rk_coef(2, :) = (/1._wp, 3._wp, 1._wp, 4._wp/) + rk_coef(3, :) = (/2._wp, 1._wp, 2._wp, 3._wp/) end if $:GPU_UPDATE(device='[rk_coef, stor]') end if end subroutine s_initialize_time_steppers_module - !> Advance the solution one full step using a TVD Runge-Kutta time integrator + !> @brief Advances the solution one full step using a TVD Runge-Kutta time integrator. impure subroutine s_tvd_rk(t_step, time_avg, nstage) - #ifdef _CRAYFTN - ! DIR$ OPTIMIZE (-haggress) + !DIR$ OPTIMIZE (-haggress) #endif - integer, intent(in) :: t_step + integer, intent(in) :: t_step real(wp), intent(inout) :: time_avg - integer, intent(in) :: nstage - integer :: i, j, k, l, q, s !< Generic loop iterator - real(wp) :: start, finish - integer :: dest + integer, intent(in) :: nstage + + integer :: i, j, k, l, q, s !< Generic loop iterator + real(wp) :: start, finish + integer :: dest call cpu_time(start) call nvtxStartRange("TIMESTEP") @@ -472,8 +535,7 @@ contains if (adap_dt) call s_adaptive_dt_bubble(1) do s = 1, nstage - call s_compute_rhs(q_cons_ts(1)%vf, q_T_sf, q_prim_vf, bc_type, rhs_vf, pb_ts(1)%sf, rhs_pb, mv_ts(1)%sf, rhs_mv, & - & t_step, time_avg, s) + call s_compute_rhs(q_cons_ts(1)%vf, q_T_sf, q_prim_vf, bc_type, rhs_vf, pb_ts(1)%sf, rhs_pb, mv_ts(1)%sf, rhs_mv, t_step, time_avg, s) if (s == 1) then if (run_time_info) then @@ -497,30 +559,33 @@ contains end if end if - if (bubbles_lagrange .and. .not. adap_dt) call s_update_lagrange_tdv_rk(stage=s) + if (bubbles_lagrange .and. .not. adap_dt) call s_update_lagrange_tdv_rk(q_prim_vf, bc_type, stage=s) $:GPU_PARALLEL_LOOP(collapse=4) do i = 1, sys_size do l = 0, p do k = 0, n do j = 0, m if (s == 1 .and. nstage > 1) then - q_cons_ts(stor)%vf(i)%sf(j, k, l) = q_cons_ts(1)%vf(i)%sf(j, k, l) + q_cons_ts(stor)%vf(i)%sf(j, k, l) = & + q_cons_ts(1)%vf(i)%sf(j, k, l) end if if (igr) then - q_cons_ts(1)%vf(i)%sf(j, k, l) = (rk_coef(s, 1)*q_cons_ts(1)%vf(i)%sf(j, k, l) + rk_coef(s, & - & 2)*q_cons_ts(stor)%vf(i)%sf(j, k, l) + rk_coef(s, 3)*rhs_vf(i)%sf(j, k, & - & l))/rk_coef(s, 4) + q_cons_ts(1)%vf(i)%sf(j, k, l) = & + (rk_coef(s, 1)*q_cons_ts(1)%vf(i)%sf(j, k, l) & + + rk_coef(s, 2)*q_cons_ts(stor)%vf(i)%sf(j, k, l) & + + rk_coef(s, 3)*rhs_vf(i)%sf(j, k, l))/rk_coef(s, 4) else - q_cons_ts(1)%vf(i)%sf(j, k, l) = (rk_coef(s, 1)*q_cons_ts(1)%vf(i)%sf(j, k, l) + rk_coef(s, & - & 2)*q_cons_ts(stor)%vf(i)%sf(j, k, l) + rk_coef(s, 3)*dt*rhs_vf(i)%sf(j, k, & - & l))/rk_coef(s, 4) + q_cons_ts(1)%vf(i)%sf(j, k, l) = & + (rk_coef(s, 1)*q_cons_ts(1)%vf(i)%sf(j, k, l) & + + rk_coef(s, 2)*q_cons_ts(stor)%vf(i)%sf(j, k, l) & + + rk_coef(s, 3)*dt*rhs_vf(i)%sf(j, k, l))/rk_coef(s, 4) end if end do end do end do end do $:END_GPU_PARALLEL_LOOP() - ! Evolve pb and mv for non-polytropic qbmm + !Evolve pb and mv for non-polytropic qbmm if (qbmm .and. (.not. polytropic)) then $:GPU_PARALLEL_LOOP(collapse=5) do i = 1, nb @@ -529,13 +594,19 @@ contains do j = 0, m do q = 1, nnode if (s == 1 .and. nstage > 1) then - pb_ts(stor)%sf(j, k, l, q, i) = pb_ts(1)%sf(j, k, l, q, i) - mv_ts(stor)%sf(j, k, l, q, i) = mv_ts(1)%sf(j, k, l, q, i) + pb_ts(stor)%sf(j, k, l, q, i) = & + pb_ts(1)%sf(j, k, l, q, i) + mv_ts(stor)%sf(j, k, l, q, i) = & + mv_ts(1)%sf(j, k, l, q, i) end if - pb_ts(1)%sf(j, k, l, q, i) = (rk_coef(s, 1)*pb_ts(1)%sf(j, k, l, q, i) + rk_coef(s, & - & 2)*pb_ts(stor)%sf(j, k, l, q, i) + rk_coef(s, 3)*dt*rhs_pb(j, k, l, q, i))/rk_coef(s, 4) - mv_ts(1)%sf(j, k, l, q, i) = (rk_coef(s, 1)*mv_ts(1)%sf(j, k, l, q, i) + rk_coef(s, & - & 2)*mv_ts(stor)%sf(j, k, l, q, i) + rk_coef(s, 3)*dt*rhs_mv(j, k, l, q, i))/rk_coef(s, 4) + pb_ts(1)%sf(j, k, l, q, i) = & + (rk_coef(s, 1)*pb_ts(1)%sf(j, k, l, q, i) & + + rk_coef(s, 2)*pb_ts(stor)%sf(j, k, l, q, i) & + + rk_coef(s, 3)*dt*rhs_pb(j, k, l, q, i))/rk_coef(s, 4) + mv_ts(1)%sf(j, k, l, q, i) = & + (rk_coef(s, 1)*mv_ts(1)%sf(j, k, l, q, i) & + + rk_coef(s, 2)*mv_ts(stor)%sf(j, k, l, q, i) & + + rk_coef(s, 3)*dt*rhs_mv(j, k, l, q, i))/rk_coef(s, 4) end do end do end do @@ -575,6 +646,7 @@ contains call s_ibm_correct_state(q_cons_ts(1)%vf, q_prim_vf) end if end if + end do if (moving_immersed_boundary_flag) call s_wrap_periodic_ibs() @@ -596,62 +668,77 @@ contains end subroutine s_tvd_rk !> Bubble source part in Strang operator splitting scheme + !! @param stage Current time-stage impure subroutine s_adaptive_dt_bubble(stage) integer, intent(in) :: stage - type(vector_field) :: gm_alpha_qp - call s_convert_conservative_to_primitive_variables(q_cons_ts(1)%vf, q_T_sf, q_prim_vf, idwint) + type(vector_field) :: gm_alpha_qp + + call s_convert_conservative_to_primitive_variables( & + q_cons_ts(1)%vf, & + q_T_sf, & + q_prim_vf, & + idwbuff) if (bubbles_euler) then + call s_compute_bubble_EE_source(q_cons_ts(1)%vf, q_prim_vf, rhs_vf, divu) call s_comp_alpha_from_n(q_cons_ts(1)%vf) - else if (bubbles_lagrange) then + + elseif (bubbles_lagrange) then + call s_populate_variables_buffers(bc_type, q_prim_vf, pb_ts(1)%sf, mv_ts(1)%sf) - call s_compute_bubble_EL_dynamics(q_prim_vf, stage) - call s_transfer_data_to_tmp() - call s_smear_voidfraction() + call s_compute_bubble_EL_dynamics(q_prim_vf, bc_type, stage) + if (stage == 3) then if (lag_params%write_bubbles_stats) call s_calculate_lag_bubble_stats() if (lag_params%write_bubbles) then - $:GPU_UPDATE(host='[gas_p, gas_mv, intfc_rad, intfc_vel]') - call s_write_lag_particles(mytime) + $:GPU_UPDATE(host='[gas_p,gas_mv,intfc_rad,intfc_vel]') + call s_write_lag_bubble_evol(mytime) end if - call s_write_void_evol(mytime) + if (lag_params%write_void_evol) call s_write_void_evol(mytime) end if + end if end subroutine s_adaptive_dt_bubble - !> Compute the global time step size from CFL stability constraints across all cells + !> @brief Computes the global time step size from CFL stability constraints across all cells. impure subroutine s_compute_dt() - real(wp) :: rho !< Cell-avg. density - + real(wp) :: rho !< Cell-avg. density #:if not MFC_CASE_OPTIMIZATION and USING_AMD - real(wp), dimension(3) :: vel !< Cell-avg. velocity - real(wp), dimension(3) :: alpha !< Cell-avg. volume fraction + real(wp), dimension(3) :: vel !< Cell-avg. velocity + real(wp), dimension(3) :: alpha !< Cell-avg. volume fraction #:else - real(wp), dimension(num_vels) :: vel !< Cell-avg. velocity - real(wp), dimension(num_fluids) :: alpha !< Cell-avg. volume fraction + real(wp), dimension(num_vels) :: vel !< Cell-avg. velocity + real(wp), dimension(num_fluids) :: alpha !< Cell-avg. volume fraction #:endif - real(wp) :: vel_sum !< Cell-avg. velocity sum - real(wp) :: pres !< Cell-avg. pressure - real(wp) :: gamma !< Cell-avg. sp. heat ratio - real(wp) :: pi_inf !< Cell-avg. liquid stiffness function - real(wp) :: qv !< Cell-avg. fluid reference energy - real(wp) :: c !< Cell-avg. sound speed - real(wp) :: H !< Cell-avg. enthalpy - real(wp), dimension(2) :: Re !< Cell-avg. Reynolds numbers - type(vector_field) :: gm_alpha_qp - real(wp) :: dt_local - integer :: j, k, l !< Generic loop iterators + real(wp) :: vel_sum !< Cell-avg. velocity sum + real(wp) :: pres !< Cell-avg. pressure + real(wp) :: gamma !< Cell-avg. sp. heat ratio + real(wp) :: pi_inf !< Cell-avg. liquid stiffness function + real(wp) :: qv !< Cell-avg. fluid reference energy + real(wp) :: c !< Cell-avg. sound speed + real(wp) :: H !< Cell-avg. enthalpy + real(wp), dimension(2) :: Re !< Cell-avg. Reynolds numbers + type(vector_field) :: gm_alpha_qp + real(wp) :: max_dt + real(wp) :: dt_local + integer :: j, k, l !< Generic loop iterators if (.not. igr .or. dummy) then - call s_convert_conservative_to_primitive_variables(q_cons_ts(1)%vf, q_T_sf, q_prim_vf, idwint) + call s_convert_conservative_to_primitive_variables( & + q_cons_ts(1)%vf, & + q_T_sf, & + q_prim_vf, & + idwint) end if - $:GPU_PARALLEL_LOOP(collapse=3, private='[vel, alpha, Re, rho, vel_sum, pres, gamma, pi_inf, c, H, qv]') + dt_local = huge(1.0_wp) + $:GPU_PARALLEL_LOOP(collapse=3, private='[vel, alpha, Re, rho, vel_sum, pres, gamma, pi_inf, c, H, qv]', & + & reduction='[[dt_local]]', reductionOp='[min]') do l = 0, p do k = 0, n do j = 0, m @@ -665,15 +752,13 @@ contains call s_compute_speed_of_sound(pres, rho, gamma, pi_inf, H, alpha, vel_sum, 0._wp, c, qv) call s_compute_dt_from_cfl(vel, c, max_dt, rho, Re, j, k, l) + + dt_local = min(dt_local, max_dt) end do end do end do $:END_GPU_PARALLEL_LOOP() - #:call GPU_PARALLEL(copyout='[dt_local]', copyin='[max_dt]') - dt_local = minval(max_dt) - #:endcall GPU_PARALLEL - if (num_procs == 1) then dt = dt_local else @@ -684,14 +769,20 @@ contains end subroutine s_compute_dt - !> Apply the body forces source term at each Runge-Kutta stage + !> This subroutine applies the body forces source term at each + !! Runge-Kutta stage + !! @param q_cons_vf Conservative variables + !! @param q_prim_vf_in Primitive variables + !! @param rhs_vf_in Right-hand side variables subroutine s_apply_bodyforces(q_cons_vf, q_prim_vf_in, rhs_vf_in, ldt) type(scalar_field), dimension(1:sys_size), intent(inout) :: q_cons_vf - type(scalar_field), dimension(1:sys_size), intent(in) :: q_prim_vf_in + type(scalar_field), dimension(1:sys_size), intent(in) :: q_prim_vf_in type(scalar_field), dimension(1:sys_size), intent(inout) :: rhs_vf_in - real(wp), intent(in) :: ldt !< local dt - integer :: i, j, k, l + + real(wp), intent(in) :: ldt !< local dt + + integer :: i, j, k, l call nvtxStartRange("RHS-BODYFORCES") call s_compute_body_forces_rhs(q_prim_vf_in, q_cons_vf, rhs_vf_in) @@ -701,7 +792,8 @@ contains do l = 0, p do k = 0, n do j = 0, m - q_cons_vf(i)%sf(j, k, l) = q_cons_vf(i)%sf(j, k, l) + ldt*rhs_vf_in(i)%sf(j, k, l) + q_cons_vf(i)%sf(j, k, l) = q_cons_vf(i)%sf(j, k, l) + & + ldt*rhs_vf_in(i)%sf(j, k, l) end do end do end do @@ -712,12 +804,12 @@ contains end subroutine s_apply_bodyforces - !> Update immersed boundary positions and velocities at the current Runge-Kutta stage + !> @brief Updates immersed boundary positions and velocities at the current Runge-Kutta stage. subroutine s_propagate_immersed_boundaries(s) integer, intent(in) :: s - integer :: i - logical :: forces_computed + integer :: i + logical :: forces_computed call nvtxStartRange("PROPAGATE-IMMERSED-BOUNDARIES") @@ -735,13 +827,12 @@ contains if (patch_ib(i)%moving_ibm > 0) then patch_ib(i)%vel = (rk_coef(s, 1)*patch_ib(i)%step_vel + rk_coef(s, 2)*patch_ib(i)%vel)/rk_coef(s, 4) - patch_ib(i)%angular_vel = (rk_coef(s, 1)*patch_ib(i)%step_angular_vel + rk_coef(s, & - & 2)*patch_ib(i)%angular_vel)/rk_coef(s, 4) + patch_ib(i)%angular_vel = (rk_coef(s, 1)*patch_ib(i)%step_angular_vel + rk_coef(s, 2)*patch_ib(i)%angular_vel)/rk_coef(s, 4) if (patch_ib(i)%moving_ibm == 1) then ! plug in analytic velocities for 1-way coupling, if it exists @:mib_analytical() - else if (patch_ib(i)%moving_ibm == 2) then ! if we are using two-way coupling, apply force and torque + else if (patch_ib(i)%moving_ibm == 2) then ! if we are using two-way coupling, apply force and torque ! compute the force and torque on the IB from the fluid if (.not. forces_computed) then call s_compute_ib_forces(q_prim_vf, fluid_pp) @@ -752,25 +843,18 @@ contains patch_ib(i)%vel = patch_ib(i)%vel + rk_coef(s, 3)*dt*(patch_ib(i)%force/patch_ib(i)%mass)/rk_coef(s, 4) ! update the angular velocity with the torque value - patch_ib(i)%angular_vel = (patch_ib(i)%angular_vel*patch_ib(i)%moment) + (rk_coef(s, & - & 3)*dt*patch_ib(i)%torque/rk_coef(s, 4)) ! add the torque to the angular momentum - call s_compute_moment_of_inertia(i, patch_ib(i)%angular_vel) - ! update the moment of inertia to be based on the direction of the angular momentum - patch_ib(i)%angular_vel = patch_ib(i)%angular_vel/patch_ib(i) & - & %moment ! convert back to angular velocity with the new moment of inertia + patch_ib(i)%angular_vel = (patch_ib(i)%angular_vel*patch_ib(i)%moment) + (rk_coef(s, 3)*dt*patch_ib(i)%torque/rk_coef(s, 4)) ! add the torque to the angular momentum + call s_compute_moment_of_inertia(i, patch_ib(i)%angular_vel) ! update the moment of inertia to be based on the direction of the angular momentum + patch_ib(i)%angular_vel = patch_ib(i)%angular_vel/patch_ib(i)%moment ! convert back to angular velocity with the new moment of inertia end if ! Update the angle of the IB - patch_ib(i)%angles = (rk_coef(s, 1)*patch_ib(i)%step_angles + rk_coef(s, 2)*patch_ib(i)%angles + rk_coef(s, & - & 3)*patch_ib(i)%angular_vel*dt)/rk_coef(s, 4) + patch_ib(i)%angles = (rk_coef(s, 1)*patch_ib(i)%step_angles + rk_coef(s, 2)*patch_ib(i)%angles + rk_coef(s, 3)*patch_ib(i)%angular_vel*dt)/rk_coef(s, 4) ! Update the position of the IB - patch_ib(i)%x_centroid = (rk_coef(s, 1)*patch_ib(i)%step_x_centroid + rk_coef(s, & - & 2)*patch_ib(i)%x_centroid + rk_coef(s, 3)*patch_ib(i)%vel(1)*dt)/rk_coef(s, 4) - patch_ib(i)%y_centroid = (rk_coef(s, 1)*patch_ib(i)%step_y_centroid + rk_coef(s, & - & 2)*patch_ib(i)%y_centroid + rk_coef(s, 3)*patch_ib(i)%vel(2)*dt)/rk_coef(s, 4) - patch_ib(i)%z_centroid = (rk_coef(s, 1)*patch_ib(i)%step_z_centroid + rk_coef(s, & - & 2)*patch_ib(i)%z_centroid + rk_coef(s, 3)*patch_ib(i)%vel(3)*dt)/rk_coef(s, 4) + patch_ib(i)%x_centroid = (rk_coef(s, 1)*patch_ib(i)%step_x_centroid + rk_coef(s, 2)*patch_ib(i)%x_centroid + rk_coef(s, 3)*patch_ib(i)%vel(1)*dt)/rk_coef(s, 4) + patch_ib(i)%y_centroid = (rk_coef(s, 1)*patch_ib(i)%step_y_centroid + rk_coef(s, 2)*patch_ib(i)%y_centroid + rk_coef(s, 3)*patch_ib(i)%vel(2)*dt)/rk_coef(s, 4) + patch_ib(i)%z_centroid = (rk_coef(s, 1)*patch_ib(i)%step_z_centroid + rk_coef(s, 2)*patch_ib(i)%z_centroid + rk_coef(s, 3)*patch_ib(i)%vel(3)*dt)/rk_coef(s, 4) end if end do @@ -780,11 +864,14 @@ contains end subroutine s_propagate_immersed_boundaries - !> Save the temporary q_prim_vf vector into q_prim_ts for use in p_main + !> This subroutine saves the temporary q_prim_vf vector + !! into the q_prim_ts vector that is then used in p_main + !! @param t_step current time-step subroutine s_time_step_cycling(t_step) integer, intent(in) :: t_step - integer :: i, j, k, l !< Generic loop iterator + + integer :: i, j, k, l !< Generic loop iterator if (t_step == t_step_start) then $:GPU_PARALLEL_LOOP(collapse=4) @@ -798,7 +885,7 @@ contains end do end do $:END_GPU_PARALLEL_LOOP() - else if (t_step == t_step_start + 1) then + elseif (t_step == t_step_start + 1) then $:GPU_PARALLEL_LOOP(collapse=4) do i = 1, sys_size do l = 0, p @@ -810,7 +897,7 @@ contains end do end do $:END_GPU_PARALLEL_LOOP() - else if (t_step == t_step_start + 2) then + elseif (t_step == t_step_start + 2) then $:GPU_PARALLEL_LOOP(collapse=4) do i = 1, sys_size do l = 0, p @@ -822,7 +909,7 @@ contains end do end do $:END_GPU_PARALLEL_LOOP() - else if (t_step == t_step_start + 3) then + elseif (t_step == t_step_start + 3) then $:GPU_PARALLEL_LOOP(collapse=4) do i = 1, sys_size do l = 0, p @@ -834,7 +921,7 @@ contains end do end do $:END_GPU_PARALLEL_LOOP() - else ! All other timesteps + else ! All other timesteps $:GPU_PARALLEL_LOOP(collapse=4) do i = 1, sys_size do l = 0, p @@ -855,13 +942,13 @@ contains !> Module deallocation and/or disassociation procedures impure subroutine s_finalize_time_steppers_module - #ifdef FRONTIER_UNIFIED use hipfort use hipfort_hipmalloc use hipfort_check #endif - integer :: i, j !< Generic loop iterators + integer :: i, j !< Generic loop iterators + ! Deallocating the cell-average conservative variables #if defined(__NVCOMPILER_GPU_UNIFIED_MEM) do j = 1, sys_size diff --git a/src/simulation/m_viscous.fpp b/src/simulation/m_viscous.fpp index 5f7022714f..9c6e4ad4d8 100644 --- a/src/simulation/m_viscous.fpp +++ b/src/simulation/m_viscous.fpp @@ -7,29 +7,39 @@ !> @brief Computes viscous stress tensors and diffusive flux contributions for the Navier--Stokes equations module m_viscous - use m_derived_types - use m_global_parameters + use m_derived_types !< Definitions of the derived types + + use m_global_parameters !< Definitions of the global parameters + use m_weno - use m_muscl + + use m_muscl !< Monotonic Upstream-centered (MUSCL) + !! schemes for conservation laws + use m_helper + use m_finite_differences - private; public s_get_viscous, s_compute_viscous_stress_cylindrical_boundary, s_initialize_viscous_module, & - & s_reconstruct_cell_boundary_values_visc_deriv, s_finalize_viscous_module, s_compute_viscous_stress_tensor + private; public s_get_viscous, & + s_compute_viscous_stress_cylindrical_boundary, & + s_initialize_viscous_module, & + s_reconstruct_cell_boundary_values_visc_deriv, & + s_finalize_viscous_module, & + s_compute_viscous_stress_tensor type(int_bounds_info) :: iv type(int_bounds_info) :: is1_viscous, is2_viscous, is3_viscous - $:GPU_DECLARE(create='[is1_viscous, is2_viscous, is3_viscous, iv]') + $:GPU_DECLARE(create='[is1_viscous,is2_viscous,is3_viscous,iv]') - real(wp), allocatable, dimension(:,:) :: Res_viscous + real(wp), allocatable, dimension(:, :) :: Res_viscous $:GPU_DECLARE(create='[Res_viscous]') contains - !> Initialize the viscous module + !> @brief Allocates and populates the viscous Reynolds number arrays and transfers data to the GPU. impure subroutine s_initialize_viscous_module - integer :: i, j !< generic loop iterators + integer :: i, j !< generic loop iterators @:ALLOCATE(Res_viscous(1:2, 1:Re_size_max)) @@ -38,34 +48,44 @@ contains Res_viscous(i, j) = fluid_pp(Re_idx(i, j))%Re(i) end do end do - $:GPU_UPDATE(device='[Res_viscous, Re_idx, Re_size]') - $:GPU_ENTER_DATA(copyin='[is1_viscous, is2_viscous, is3_viscous, iv]') + $:GPU_UPDATE(device='[Res_viscous,Re_idx,Re_size]') + $:GPU_ENTER_DATA(copyin='[is1_viscous,is2_viscous,is3_viscous,iv]') end subroutine s_initialize_viscous_module - !> Compute viscous stress tensor near cylindrical axis, avoiding 1/r singularity at y_cb(-1)=0 - subroutine s_compute_viscous_stress_cylindrical_boundary(q_prim_vf, grad_x_vf, grad_y_vf, grad_z_vf, tau_Re_vf, ix, iy, iz) + !> The purpose of this subroutine is to compute the viscous + ! stress tensor for the cells directly next to the axis in + ! cylindrical coordinates. This is necessary to avoid the + ! 1/r singularity that arises at the cell boundary coinciding + ! with the axis, i.e., y_cb(-1) = 0. + ! @param q_prim_vf Cell-average primitive variables + ! @param grad_x_vf Cell-average primitive variable derivatives, x-dir + ! @param grad_y_vf Cell-average primitive variable derivatives, y-dir + ! @param grad_z_vf Cell-average primitive variable derivatives, z-dir + subroutine s_compute_viscous_stress_cylindrical_boundary(q_prim_vf, grad_x_vf, grad_y_vf, grad_z_vf, & + tau_Re_vf, & + ix, iy, iz) type(scalar_field), dimension(sys_size), intent(in) :: q_prim_vf type(scalar_field), dimension(num_dims), intent(in) :: grad_x_vf, grad_y_vf, grad_z_vf type(scalar_field), dimension(1:sys_size), intent(inout) :: tau_Re_vf type(int_bounds_info), intent(in) :: ix, iy, iz + real(wp) :: rho_visc, gamma_visc, pi_inf_visc, alpha_visc_sum !< Mixture variables real(wp), dimension(2) :: Re_visc - #:if not MFC_CASE_OPTIMIZATION and USING_AMD - real(wp), dimension(3) :: alpha_visc, alpha_rho_visc + real(wp), dimension(3) :: alpha_visc, alpha_rho_visc real(wp), dimension(3, 3) :: tau_Re #:else - real(wp), dimension(num_fluids) :: alpha_visc, alpha_rho_visc + real(wp), dimension(num_fluids) :: alpha_visc, alpha_rho_visc real(wp), dimension(num_dims, num_dims) :: tau_Re #:endif - integer :: i, j, k, l, q !< Generic loop iterator + integer :: i, j, k, l, q !< Generic loop iterator is1_viscous = ix; is2_viscous = iy; is3_viscous = iz - $:GPU_UPDATE(device='[is1_viscous, is2_viscous, is3_viscous]') + $:GPU_UPDATE(device='[is1_viscous,is2_viscous,is3_viscous]') $:GPU_PARALLEL_LOOP(collapse=3) do l = is3_viscous%beg, is3_viscous%end @@ -81,12 +101,12 @@ contains $:END_GPU_PARALLEL_LOOP() #:if not MFC_CASE_OPTIMIZATION or num_dims > 1 - if (shear_stress) then ! Shear stresses - $:GPU_PARALLEL_LOOP(collapse=3, private='[i, j, k, l, q, rho_visc, gamma_visc, pi_inf_visc, alpha_visc_sum, & - & alpha_visc, alpha_rho_visc, Re_visc, tau_Re]') + if (shear_stress) then ! Shear stresses + $:GPU_PARALLEL_LOOP(collapse=3, private='[i,j,k,l,q,rho_visc, gamma_visc, pi_inf_visc, alpha_visc_sum, alpha_visc, alpha_rho_visc, Re_visc, tau_Re]') do l = is3_viscous%beg, is3_viscous%end do k = -1, 1 do j = is1_viscous%beg, is1_viscous%end + $:GPU_LOOP(parallelism='[seq]') do i = 1, num_fluids alpha_rho_visc(i) = q_prim_vf(i)%sf(j, k, l) @@ -137,6 +157,7 @@ contains end do alpha_visc = alpha_visc/max(alpha_visc_sum, sgm_eps) + end if $:GPU_LOOP(parallelism='[seq]') @@ -154,26 +175,33 @@ contains if (Re_size(i) > 0) Re_visc(i) = 0._wp $:GPU_LOOP(parallelism='[seq]') do q = 1, Re_size(i) - Re_visc(i) = alpha_visc(Re_idx(i, q))/Res_viscous(i, q) + Re_visc(i) + Re_visc(i) = alpha_visc(Re_idx(i, q))/Res_viscous(i, q) & + + Re_visc(i) end do Re_visc(i) = 1._wp/max(Re_visc(i), sgm_eps) + end do end if end if - ! Shear stress near cylindrical axis: includes v/r hoop term - tau_Re(2, 1) = (grad_y_vf(1)%sf(j, k, l) + grad_x_vf(2)%sf(j, k, l))/Re_visc(1) + tau_Re(2, 1) = (grad_y_vf(1)%sf(j, k, l) + & + grad_x_vf(2)%sf(j, k, l))/ & + Re_visc(1) - tau_Re(2, 2) = (4._wp*grad_y_vf(2)%sf(j, k, l) - 2._wp*grad_x_vf(1)%sf(j, k, & - & l) - 2._wp*q_prim_vf(momxb + 1)%sf(j, k, l)/y_cc(k))/(3._wp*Re_visc(1)) - ! Viscous flux contribution to momentum and energy equations + tau_Re(2, 2) = (4._wp*grad_y_vf(2)%sf(j, k, l) & + - 2._wp*grad_x_vf(1)%sf(j, k, l) & + - 2._wp*q_prim_vf(momxb + 1)%sf(j, k, l)/y_cc(k))/ & + (3._wp*Re_visc(1)) $:GPU_LOOP(parallelism='[seq]') do i = 1, 2 - tau_Re_vf(contxe + i)%sf(j, k, l) = tau_Re_vf(contxe + i)%sf(j, k, l) - tau_Re(2, i) + tau_Re_vf(contxe + i)%sf(j, k, l) = & + tau_Re_vf(contxe + i)%sf(j, k, l) - & + tau_Re(2, i) - tau_Re_vf(E_idx)%sf(j, k, l) = tau_Re_vf(E_idx)%sf(j, k, l) - q_prim_vf(contxe + i)%sf(j, k, & - & l)*tau_Re(2, i) + tau_Re_vf(E_idx)%sf(j, k, l) = & + tau_Re_vf(E_idx)%sf(j, k, l) - & + q_prim_vf(contxe + i)%sf(j, k, l)*tau_Re(2, i) end do end do end do @@ -183,12 +211,12 @@ contains #:endif #:if not MFC_CASE_OPTIMIZATION or num_dims > 1 - if (bulk_stress) then ! Bulk stresses - $:GPU_PARALLEL_LOOP(collapse=3, private='[i, j, k, l, q, rho_visc, gamma_visc, pi_inf_visc, alpha_visc_sum, & - & alpha_visc, alpha_rho_visc, Re_visc, tau_Re]') + if (bulk_stress) then ! Bulk stresses + $:GPU_PARALLEL_LOOP(collapse=3, private='[i,j,k,l,q,rho_visc, gamma_visc, pi_inf_visc, alpha_visc_sum, alpha_visc, alpha_rho_visc, Re_visc, tau_Re]') do l = is3_viscous%beg, is3_viscous%end do k = -1, 1 do j = is1_viscous%beg, is1_viscous%end + $:GPU_LOOP(parallelism='[seq]') do i = 1, num_fluids alpha_rho_visc(i) = q_prim_vf(i)%sf(j, k, l) @@ -239,6 +267,7 @@ contains end do alpha_visc = alpha_visc/max(alpha_visc_sum, sgm_eps) + end if $:GPU_LOOP(parallelism='[seq]') @@ -256,21 +285,29 @@ contains if (Re_size(i) > 0) Re_visc(i) = 0._wp $:GPU_LOOP(parallelism='[seq]') do q = 1, Re_size(i) - Re_visc(i) = alpha_visc(Re_idx(i, q))/Res_viscous(i, q) + Re_visc(i) + Re_visc(i) = alpha_visc(Re_idx(i, q))/Res_viscous(i, q) & + + Re_visc(i) end do Re_visc(i) = 1._wp/max(Re_visc(i), sgm_eps) + end do end if end if - tau_Re(2, 2) = (grad_x_vf(1)%sf(j, k, l) + grad_y_vf(2)%sf(j, k, l) + q_prim_vf(momxb + 1)%sf(j, k, & - & l)/y_cc(k))/Re_visc(2) + tau_Re(2, 2) = (grad_x_vf(1)%sf(j, k, l) + & + grad_y_vf(2)%sf(j, k, l) + & + q_prim_vf(momxb + 1)%sf(j, k, l)/y_cc(k))/ & + Re_visc(2) + + tau_Re_vf(momxb + 1)%sf(j, k, l) = & + tau_Re_vf(momxb + 1)%sf(j, k, l) - & + tau_Re(2, 2) - tau_Re_vf(momxb + 1)%sf(j, k, l) = tau_Re_vf(momxb + 1)%sf(j, k, l) - tau_Re(2, 2) + tau_Re_vf(E_idx)%sf(j, k, l) = & + tau_Re_vf(E_idx)%sf(j, k, l) - & + q_prim_vf(momxb + 1)%sf(j, k, l)*tau_Re(2, 2) - tau_Re_vf(E_idx)%sf(j, k, l) = tau_Re_vf(E_idx)%sf(j, k, l) - q_prim_vf(momxb + 1)%sf(j, k, & - & l)*tau_Re(2, 2) end do end do end do @@ -280,12 +317,13 @@ contains if (p == 0) return #:if not MFC_CASE_OPTIMIZATION or num_dims > 2 - if (shear_stress) then ! Shear stresses - $:GPU_PARALLEL_LOOP(collapse=3, private='[i, j, k, l, q, rho_visc, gamma_visc, pi_inf_visc, alpha_visc_sum, & - & alpha_visc, alpha_rho_visc, Re_visc, tau_Re]') + + if (shear_stress) then ! Shear stresses + $:GPU_PARALLEL_LOOP(collapse=3, private='[i,j,k,l,q,rho_visc, gamma_visc, pi_inf_visc, alpha_visc_sum, alpha_visc, alpha_rho_visc, Re_visc, tau_Re]') do l = is3_viscous%beg, is3_viscous%end do k = -1, 1 do j = is1_viscous%beg, is1_viscous%end + $:GPU_LOOP(parallelism='[seq]') do i = 1, num_fluids alpha_rho_visc(i) = q_prim_vf(i)%sf(j, k, l) @@ -336,6 +374,7 @@ contains end do alpha_visc = alpha_visc/max(alpha_visc_sum, sgm_eps) + end if $:GPU_LOOP(parallelism='[seq]') @@ -353,38 +392,47 @@ contains if (Re_size(i) > 0) Re_visc(i) = 0._wp $:GPU_LOOP(parallelism='[seq]') do q = 1, Re_size(i) - Re_visc(i) = alpha_visc(Re_idx(i, q))/Res_viscous(i, q) + Re_visc(i) + Re_visc(i) = alpha_visc(Re_idx(i, q))/Res_viscous(i, q) & + + Re_visc(i) end do Re_visc(i) = 1._wp/max(Re_visc(i), sgm_eps) + end do end if end if - tau_Re(2, 2) = -(2._wp/3._wp)*grad_z_vf(3)%sf(j, k, l)/y_cc(k)/Re_visc(1) + tau_Re(2, 2) = -(2._wp/3._wp)*grad_z_vf(3)%sf(j, k, l)/y_cc(k)/ & + Re_visc(1) - tau_Re(2, 3) = ((grad_z_vf(2)%sf(j, k, l) - q_prim_vf(momxe)%sf(j, k, & - & l))/y_cc(k) + grad_y_vf(3)%sf(j, k, l))/Re_visc(1) + tau_Re(2, 3) = ((grad_z_vf(2)%sf(j, k, l) - & + q_prim_vf(momxe)%sf(j, k, l))/ & + y_cc(k) + grad_y_vf(3)%sf(j, k, l))/ & + Re_visc(1) $:GPU_LOOP(parallelism='[seq]') do i = 2, 3 - tau_Re_vf(contxe + i)%sf(j, k, l) = tau_Re_vf(contxe + i)%sf(j, k, l) - tau_Re(2, i) + tau_Re_vf(contxe + i)%sf(j, k, l) = & + tau_Re_vf(contxe + i)%sf(j, k, l) - & + tau_Re(2, i) - tau_Re_vf(E_idx)%sf(j, k, l) = tau_Re_vf(E_idx)%sf(j, k, l) - q_prim_vf(contxe + i)%sf(j, k, & - & l)*tau_Re(2, i) + tau_Re_vf(E_idx)%sf(j, k, l) = & + tau_Re_vf(E_idx)%sf(j, k, l) - & + q_prim_vf(contxe + i)%sf(j, k, l)*tau_Re(2, i) end do + end do end do end do $:END_GPU_PARALLEL_LOOP() end if - if (bulk_stress) then ! Bulk stresses - $:GPU_PARALLEL_LOOP(collapse=3, private='[i, j, k, l, q, rho_visc, gamma_visc, pi_inf_visc, alpha_visc_sum, & - & alpha_visc, alpha_rho_visc, Re_visc, tau_Re]') + if (bulk_stress) then ! Bulk stresses + $:GPU_PARALLEL_LOOP(collapse=3, private='[i,j,k,l,q,rho_visc, gamma_visc, pi_inf_visc, alpha_visc_sum, alpha_visc, alpha_rho_visc, Re_visc, tau_Re]') do l = is3_viscous%beg, is3_viscous%end do k = -1, 1 do j = is1_viscous%beg, is1_viscous%end + $:GPU_LOOP(parallelism='[seq]') do i = 1, num_fluids alpha_rho_visc(i) = q_prim_vf(i)%sf(j, k, l) @@ -435,6 +483,7 @@ contains end do alpha_visc = alpha_visc/max(alpha_visc_sum, sgm_eps) + end if $:GPU_LOOP(parallelism='[seq]') @@ -452,81 +501,133 @@ contains if (Re_size(i) > 0) Re_visc(i) = 0._wp $:GPU_LOOP(parallelism='[seq]') do q = 1, Re_size(i) - Re_visc(i) = alpha_visc(Re_idx(i, q))/Res_viscous(i, q) + Re_visc(i) + Re_visc(i) = alpha_visc(Re_idx(i, q))/Res_viscous(i, q) & + + Re_visc(i) end do Re_visc(i) = 1._wp/max(Re_visc(i), sgm_eps) + end do end if end if - tau_Re(2, 2) = grad_z_vf(3)%sf(j, k, l)/y_cc(k)/Re_visc(2) + tau_Re(2, 2) = grad_z_vf(3)%sf(j, k, l)/y_cc(k)/ & + Re_visc(2) + + tau_Re_vf(momxb + 1)%sf(j, k, l) = & + tau_Re_vf(momxb + 1)%sf(j, k, l) - & + tau_Re(2, 2) - tau_Re_vf(momxb + 1)%sf(j, k, l) = tau_Re_vf(momxb + 1)%sf(j, k, l) - tau_Re(2, 2) + tau_Re_vf(E_idx)%sf(j, k, l) = & + tau_Re_vf(E_idx)%sf(j, k, l) - & + q_prim_vf(momxb + 1)%sf(j, k, l)*tau_Re(2, 2) - tau_Re_vf(E_idx)%sf(j, k, l) = tau_Re_vf(E_idx)%sf(j, k, l) - q_prim_vf(momxb + 1)%sf(j, k, & - & l)*tau_Re(2, 2) end do end do end do $:END_GPU_PARALLEL_LOOP() end if #:endif - end subroutine s_compute_viscous_stress_cylindrical_boundary - !> Computes viscous terms - subroutine s_get_viscous(qL_prim_rsx_vf, qL_prim_rsy_vf, qL_prim_rsz_vf, dqL_prim_dx_n, dqL_prim_dy_n, dqL_prim_dz_n, & - - & qL_prim, qR_prim_rsx_vf, qR_prim_rsy_vf, qR_prim_rsz_vf, dqR_prim_dx_n, dqR_prim_dy_n, dqR_prim_dz_n, qR_prim, & - & q_prim_qp, dq_prim_dx_qp, dq_prim_dy_qp, dq_prim_dz_qp, ix, iy, iz) - - real(wp), dimension(idwbuff(1)%beg:,idwbuff(2)%beg:,idwbuff(3)%beg:,1:), intent(inout) :: qL_prim_rsx_vf, qR_prim_rsx_vf, & - & qL_prim_rsy_vf, qR_prim_rsy_vf, qL_prim_rsz_vf, qR_prim_rsz_vf - - type(vector_field), dimension(num_dims), intent(inout) :: qL_prim, qR_prim - type(vector_field), intent(in) :: q_prim_qp - type(vector_field), dimension(1:num_dims), intent(inout) :: dqL_prim_dx_n, dqR_prim_dx_n, dqL_prim_dy_n, dqR_prim_dy_n, & - & dqL_prim_dz_n, dqR_prim_dz_n + !> Computes viscous terms + !! @param qL_prim_rsx_vf Left reconstructed primitive variables in x + !! @param qL_prim_rsy_vf Left reconstructed primitive variables in y + !! @param qL_prim_rsz_vf Left reconstructed primitive variables in z + !! @param dqL_prim_dx_n Left primitive x-derivative + !! @param dqL_prim_dy_n Left primitive y-derivative + !! @param dqL_prim_dz_n Left primitive z-derivative + !! @param qL_prim Left cell-boundary primitive variables + !! @param qR_prim_rsx_vf Right reconstructed primitive variables in x + !! @param qR_prim_rsy_vf Right reconstructed primitive variables in y + !! @param qR_prim_rsz_vf Right reconstructed primitive variables in z + !! @param dqR_prim_dx_n Right primitive x-derivative + !! @param dqR_prim_dy_n Right primitive y-derivative + !! @param dqR_prim_dz_n Right primitive z-derivative + !! @param qR_prim Right cell-boundary primitive variables + !! @param q_prim_qp Cell-averaged primitive variables + !! @param dq_prim_dx_qp Cell-averaged primitive x-derivative + !! @param dq_prim_dy_qp Cell-averaged primitive y-derivative + !! @param dq_prim_dz_qp Cell-averaged primitive z-derivative + !! @param ix Index bounds in the x-direction + !! @param iy Index bounds in the y-direction + !! @param iz Index bounds in the z-direction + subroutine s_get_viscous(qL_prim_rsx_vf, qL_prim_rsy_vf, qL_prim_rsz_vf, & + dqL_prim_dx_n, dqL_prim_dy_n, dqL_prim_dz_n, & + qL_prim, & + qR_prim_rsx_vf, qR_prim_rsy_vf, qR_prim_rsz_vf, & + dqR_prim_dx_n, dqR_prim_dy_n, dqR_prim_dz_n, & + qR_prim, & + q_prim_qp, & + dq_prim_dx_qp, dq_prim_dy_qp, dq_prim_dz_qp, & + ix, iy, iz) + + real(wp), dimension(idwbuff(1)%beg:, idwbuff(2)%beg:, idwbuff(3)%beg:, 1:), & + intent(inout) :: qL_prim_rsx_vf, qR_prim_rsx_vf, & + qL_prim_rsy_vf, qR_prim_rsy_vf, & + qL_prim_rsz_vf, qR_prim_rsz_vf + + type(vector_field), dimension(num_dims), intent(inout) :: qL_prim, qR_prim + + type(vector_field), intent(in) :: q_prim_qp + + type(vector_field), dimension(1:num_dims), & + intent(inout) :: dqL_prim_dx_n, dqR_prim_dx_n, & + dqL_prim_dy_n, dqR_prim_dy_n, & + dqL_prim_dz_n, dqR_prim_dz_n type(vector_field), dimension(1), intent(inout) :: dq_prim_dx_qp, dq_prim_dy_qp, dq_prim_dz_qp - type(int_bounds_info), intent(in) :: ix, iy, iz - integer :: i, j, k, l + type(int_bounds_info), intent(in) :: ix, iy, iz + + integer :: i, j, k, l do i = 1, num_dims + iv%beg = mom_idx%beg; iv%end = mom_idx%end $:GPU_UPDATE(device='[iv]') - call s_reconstruct_cell_boundary_values_visc(q_prim_qp%vf(iv%beg:iv%end), qL_prim_rsx_vf, qL_prim_rsy_vf, & - & qL_prim_rsz_vf, qR_prim_rsx_vf, qR_prim_rsy_vf, qR_prim_rsz_vf, i, qL_prim(i)%vf(iv%beg:iv%end), & - & qR_prim(i)%vf(iv%beg:iv%end), ix, iy, iz) + call s_reconstruct_cell_boundary_values_visc( & + q_prim_qp%vf(iv%beg:iv%end), & + qL_prim_rsx_vf, qL_prim_rsy_vf, qL_prim_rsz_vf, & + qR_prim_rsx_vf, qR_prim_rsy_vf, qR_prim_rsz_vf, & + i, qL_prim(i)%vf(iv%beg:iv%end), qR_prim(i)%vf(iv%beg:iv%end), & + ix, iy, iz) end do if (weno_Re_flux) then - ! Compute velocity gradients via divergence theorem on cell-boundary reconstructed values + ! Compute velocity gradient at cell centers using scalar + ! divergence theorem do i = 1, num_dims if (i == 1) then - call s_apply_scalar_divergence_theorem(qL_prim(i)%vf(iv%beg:iv%end), qR_prim(i)%vf(iv%beg:iv%end), & - & dq_prim_dx_qp(1)%vf(iv%beg:iv%end), i, ix, iy, iz, iv, dx, m, & - & buff_size) - else if (i == 2) then - call s_apply_scalar_divergence_theorem(qL_prim(i)%vf(iv%beg:iv%end), qR_prim(i)%vf(iv%beg:iv%end), & - & dq_prim_dy_qp(1)%vf(iv%beg:iv%end), i, ix, iy, iz, iv, dy, n, & - & buff_size) + call s_apply_scalar_divergence_theorem( & + qL_prim(i)%vf(iv%beg:iv%end), & + qR_prim(i)%vf(iv%beg:iv%end), & + dq_prim_dx_qp(1)%vf(iv%beg:iv%end), i, & + ix, iy, iz, iv, dx, m, buff_size) + elseif (i == 2) then + call s_apply_scalar_divergence_theorem( & + qL_prim(i)%vf(iv%beg:iv%end), & + qR_prim(i)%vf(iv%beg:iv%end), & + dq_prim_dy_qp(1)%vf(iv%beg:iv%end), i, & + ix, iy, iz, iv, dy, n, buff_size) else - call s_apply_scalar_divergence_theorem(qL_prim(i)%vf(iv%beg:iv%end), qR_prim(i)%vf(iv%beg:iv%end), & - & dq_prim_dz_qp(1)%vf(iv%beg:iv%end), i, ix, iy, iz, iv, dz, p, & - & buff_size) + call s_apply_scalar_divergence_theorem( & + qL_prim(i)%vf(iv%beg:iv%end), & + qR_prim(i)%vf(iv%beg:iv%end), & + dq_prim_dz_qp(1)%vf(iv%beg:iv%end), i, & + ix, iy, iz, iv, dz, p, buff_size) end if end do - else ! Compute velocity gradients at cell centers using central finite differences + + else ! Compute velocity gradient at cell centers using finite differences + iv%beg = mom_idx%beg; iv%end = mom_idx%end $:GPU_UPDATE(device='[iv]') is1_viscous = ix; is2_viscous = iy; is3_viscous = iz - $:GPU_UPDATE(device='[is1_viscous, is2_viscous, is3_viscous]') + $:GPU_UPDATE(device='[is1_viscous,is2_viscous,is3_viscous]') $:GPU_PARALLEL_LOOP(collapse=3) do l = is3_viscous%beg, is3_viscous%end @@ -534,8 +635,10 @@ contains do j = is1_viscous%beg + 1, is1_viscous%end $:GPU_LOOP(parallelism='[seq]') do i = iv%beg, iv%end - dqL_prim_dx_n(1)%vf(i)%sf(j, k, l) = (q_prim_qp%vf(i)%sf(j, k, l) - q_prim_qp%vf(i)%sf(j - 1, k, & - & l))/(x_cc(j) - x_cc(j - 1)) + dqL_prim_dx_n(1)%vf(i)%sf(j, k, l) = & + (q_prim_qp%vf(i)%sf(j, k, l) - & + q_prim_qp%vf(i)%sf(j - 1, k, l))/ & + (x_cc(j) - x_cc(j - 1)) end do end do end do @@ -548,8 +651,10 @@ contains do j = is1_viscous%beg, is1_viscous%end - 1 $:GPU_LOOP(parallelism='[seq]') do i = iv%beg, iv%end - dqR_prim_dx_n(1)%vf(i)%sf(j, k, l) = (q_prim_qp%vf(i)%sf(j + 1, k, l) - q_prim_qp%vf(i)%sf(j, k, & - & l))/(x_cc(j + 1) - x_cc(j)) + dqR_prim_dx_n(1)%vf(i)%sf(j, k, l) = & + (q_prim_qp%vf(i)%sf(j + 1, k, l) - & + q_prim_qp%vf(i)%sf(j, k, l))/ & + (x_cc(j + 1) - x_cc(j)) end do end do end do @@ -557,6 +662,7 @@ contains $:END_GPU_PARALLEL_LOOP() if (n > 0) then + #:if not MFC_CASE_OPTIMIZATION or num_dims > 1 $:GPU_PARALLEL_LOOP(collapse=3) do l = is3_viscous%beg, is3_viscous%end @@ -564,8 +670,10 @@ contains do k = is1_viscous%beg, is1_viscous%end $:GPU_LOOP(parallelism='[seq]') do i = iv%beg, iv%end - dqL_prim_dy_n(2)%vf(i)%sf(k, j, l) = (q_prim_qp%vf(i)%sf(k, j, l) - q_prim_qp%vf(i)%sf(k, & - & j - 1, l))/(y_cc(j) - y_cc(j - 1)) + dqL_prim_dy_n(2)%vf(i)%sf(k, j, l) = & + (q_prim_qp%vf(i)%sf(k, j, l) - & + q_prim_qp%vf(i)%sf(k, j - 1, l))/ & + (y_cc(j) - y_cc(j - 1)) end do end do end do @@ -578,8 +686,10 @@ contains do k = is1_viscous%beg, is1_viscous%end $:GPU_LOOP(parallelism='[seq]') do i = iv%beg, iv%end - dqR_prim_dy_n(2)%vf(i)%sf(k, j, l) = (q_prim_qp%vf(i)%sf(k, j + 1, l) - q_prim_qp%vf(i)%sf(k, & - & j, l))/(y_cc(j + 1) - y_cc(j)) + dqR_prim_dy_n(2)%vf(i)%sf(k, j, l) = & + (q_prim_qp%vf(i)%sf(k, j + 1, l) - & + q_prim_qp%vf(i)%sf(k, j, l))/ & + (y_cc(j + 1) - y_cc(j)) end do end do end do @@ -592,11 +702,14 @@ contains do k = is1_viscous%beg + 1, is1_viscous%end - 1 $:GPU_LOOP(parallelism='[seq]') do i = iv%beg, iv%end - dqL_prim_dx_n(2)%vf(i)%sf(k, j, l) = (dqL_prim_dx_n(1)%vf(i)%sf(k, j, & - & l) + dqR_prim_dx_n(1)%vf(i)%sf(k, j, l) + dqL_prim_dx_n(1)%vf(i)%sf(k, j - 1, & - & l) + dqR_prim_dx_n(1)%vf(i)%sf(k, j - 1, l)) - - dqL_prim_dx_n(2)%vf(i)%sf(k, j, l) = 25.e-2_wp*dqL_prim_dx_n(2)%vf(i)%sf(k, j, l) + dqL_prim_dx_n(2)%vf(i)%sf(k, j, l) = & + (dqL_prim_dx_n(1)%vf(i)%sf(k, j, l) + & + dqR_prim_dx_n(1)%vf(i)%sf(k, j, l) + & + dqL_prim_dx_n(1)%vf(i)%sf(k, j - 1, l) + & + dqR_prim_dx_n(1)%vf(i)%sf(k, j - 1, l)) + + dqL_prim_dx_n(2)%vf(i)%sf(k, j, l) = 25.e-2_wp* & + dqL_prim_dx_n(2)%vf(i)%sf(k, j, l) end do end do end do @@ -609,11 +722,15 @@ contains do k = is1_viscous%beg + 1, is1_viscous%end - 1 $:GPU_LOOP(parallelism='[seq]') do i = iv%beg, iv%end - dqR_prim_dx_n(2)%vf(i)%sf(k, j, l) = (dqL_prim_dx_n(1)%vf(i)%sf(k, j + 1, & - & l) + dqR_prim_dx_n(1)%vf(i)%sf(k, j + 1, l) + dqL_prim_dx_n(1)%vf(i)%sf(k, j, & - & l) + dqR_prim_dx_n(1)%vf(i)%sf(k, j, l)) + dqR_prim_dx_n(2)%vf(i)%sf(k, j, l) = & + (dqL_prim_dx_n(1)%vf(i)%sf(k, j + 1, l) + & + dqR_prim_dx_n(1)%vf(i)%sf(k, j + 1, l) + & + dqL_prim_dx_n(1)%vf(i)%sf(k, j, l) + & + dqR_prim_dx_n(1)%vf(i)%sf(k, j, l)) + + dqR_prim_dx_n(2)%vf(i)%sf(k, j, l) = 25.e-2_wp* & + dqR_prim_dx_n(2)%vf(i)%sf(k, j, l) - dqR_prim_dx_n(2)%vf(i)%sf(k, j, l) = 25.e-2_wp*dqR_prim_dx_n(2)%vf(i)%sf(k, j, l) end do end do end do @@ -626,11 +743,15 @@ contains do j = is1_viscous%beg + 1, is1_viscous%end $:GPU_LOOP(parallelism='[seq]') do i = iv%beg, iv%end - dqL_prim_dy_n(1)%vf(i)%sf(j, k, l) = (dqL_prim_dy_n(2)%vf(i)%sf(j, k, & - & l) + dqR_prim_dy_n(2)%vf(i)%sf(j, k, l) + dqL_prim_dy_n(2)%vf(i)%sf(j - 1, k, & - & l) + dqR_prim_dy_n(2)%vf(i)%sf(j - 1, k, l)) + dqL_prim_dy_n(1)%vf(i)%sf(j, k, l) = & + (dqL_prim_dy_n(2)%vf(i)%sf(j, k, l) + & + dqR_prim_dy_n(2)%vf(i)%sf(j, k, l) + & + dqL_prim_dy_n(2)%vf(i)%sf(j - 1, k, l) + & + dqR_prim_dy_n(2)%vf(i)%sf(j - 1, k, l)) + + dqL_prim_dy_n(1)%vf(i)%sf(j, k, l) = 25.e-2_wp* & + dqL_prim_dy_n(1)%vf(i)%sf(j, k, l) - dqL_prim_dy_n(1)%vf(i)%sf(j, k, l) = 25.e-2_wp*dqL_prim_dy_n(1)%vf(i)%sf(j, k, l) end do end do end do @@ -643,16 +764,21 @@ contains do j = is1_viscous%beg, is1_viscous%end - 1 $:GPU_LOOP(parallelism='[seq]') do i = iv%beg, iv%end - dqR_prim_dy_n(1)%vf(i)%sf(j, k, l) = (dqL_prim_dy_n(2)%vf(i)%sf(j + 1, k, & - & l) + dqR_prim_dy_n(2)%vf(i)%sf(j + 1, k, l) + dqL_prim_dy_n(2)%vf(i)%sf(j, k, & - & l) + dqR_prim_dy_n(2)%vf(i)%sf(j, k, l)) + dqR_prim_dy_n(1)%vf(i)%sf(j, k, l) = & + (dqL_prim_dy_n(2)%vf(i)%sf(j + 1, k, l) + & + dqR_prim_dy_n(2)%vf(i)%sf(j + 1, k, l) + & + dqL_prim_dy_n(2)%vf(i)%sf(j, k, l) + & + dqR_prim_dy_n(2)%vf(i)%sf(j, k, l)) + + dqR_prim_dy_n(1)%vf(i)%sf(j, k, l) = 25.e-2_wp* & + dqR_prim_dy_n(1)%vf(i)%sf(j, k, l) - dqR_prim_dy_n(1)%vf(i)%sf(j, k, l) = 25.e-2_wp*dqR_prim_dy_n(1)%vf(i)%sf(j, k, l) end do end do end do end do $:END_GPU_PARALLEL_LOOP() + #:endif if (p > 0) then @@ -663,8 +789,11 @@ contains do k = is1_viscous%beg, is1_viscous%end $:GPU_LOOP(parallelism='[seq]') do i = iv%beg, iv%end - dqL_prim_dz_n(3)%vf(i)%sf(k, l, j) = (q_prim_qp%vf(i)%sf(k, l, j) - q_prim_qp%vf(i)%sf(k, & - & l, j - 1))/(z_cc(j) - z_cc(j - 1)) + + dqL_prim_dz_n(3)%vf(i)%sf(k, l, j) = & + (q_prim_qp%vf(i)%sf(k, l, j) - & + q_prim_qp%vf(i)%sf(k, l, j - 1))/ & + (z_cc(j) - z_cc(j - 1)) end do end do end do @@ -677,8 +806,11 @@ contains do k = is1_viscous%beg, is1_viscous%end $:GPU_LOOP(parallelism='[seq]') do i = iv%beg, iv%end - dqR_prim_dz_n(3)%vf(i)%sf(k, l, j) = (q_prim_qp%vf(i)%sf(k, l, & - & j + 1) - q_prim_qp%vf(i)%sf(k, l, j))/(z_cc(j + 1) - z_cc(j)) + + dqR_prim_dz_n(3)%vf(i)%sf(k, l, j) = & + (q_prim_qp%vf(i)%sf(k, l, j + 1) - & + q_prim_qp%vf(i)%sf(k, l, j))/ & + (z_cc(j + 1) - z_cc(j)) end do end do end do @@ -691,12 +823,16 @@ contains do j = is1_viscous%beg + 1, is1_viscous%end $:GPU_LOOP(parallelism='[seq]') do i = iv%beg, iv%end - dqL_prim_dz_n(1)%vf(i)%sf(j, k, l) = (dqL_prim_dz_n(3)%vf(i)%sf(j, k, & - & l) + dqR_prim_dz_n(3)%vf(i)%sf(j, k, & - & l) + dqL_prim_dz_n(3)%vf(i)%sf(j - 1, k, & - & l) + dqR_prim_dz_n(3)%vf(i)%sf(j - 1, k, l)) - dqL_prim_dz_n(1)%vf(i)%sf(j, k, l) = 25.e-2_wp*dqL_prim_dz_n(1)%vf(i)%sf(j, k, l) + dqL_prim_dz_n(1)%vf(i)%sf(j, k, l) = & + (dqL_prim_dz_n(3)%vf(i)%sf(j, k, l) + & + dqR_prim_dz_n(3)%vf(i)%sf(j, k, l) + & + dqL_prim_dz_n(3)%vf(i)%sf(j - 1, k, l) + & + dqR_prim_dz_n(3)%vf(i)%sf(j - 1, k, l)) + + dqL_prim_dz_n(1)%vf(i)%sf(j, k, l) = 25.e-2_wp* & + dqL_prim_dz_n(1)%vf(i)%sf(j, k, l) + end do end do end do @@ -709,12 +845,16 @@ contains do j = is1_viscous%beg, is1_viscous%end - 1 $:GPU_LOOP(parallelism='[seq]') do i = iv%beg, iv%end - dqR_prim_dz_n(1)%vf(i)%sf(j, k, l) = (dqL_prim_dz_n(3)%vf(i)%sf(j + 1, k, & - & l) + dqR_prim_dz_n(3)%vf(i)%sf(j + 1, k, & - & l) + dqL_prim_dz_n(3)%vf(i)%sf(j, k, l) + dqR_prim_dz_n(3)%vf(i)%sf(j, k, & - & l)) - dqR_prim_dz_n(1)%vf(i)%sf(j, k, l) = 25.e-2_wp*dqR_prim_dz_n(1)%vf(i)%sf(j, k, l) + dqR_prim_dz_n(1)%vf(i)%sf(j, k, l) = & + (dqL_prim_dz_n(3)%vf(i)%sf(j + 1, k, l) + & + dqR_prim_dz_n(3)%vf(i)%sf(j + 1, k, l) + & + dqL_prim_dz_n(3)%vf(i)%sf(j, k, l) + & + dqR_prim_dz_n(3)%vf(i)%sf(j, k, l)) + + dqR_prim_dz_n(1)%vf(i)%sf(j, k, l) = 25.e-2_wp* & + dqR_prim_dz_n(1)%vf(i)%sf(j, k, l) + end do end do end do @@ -727,11 +867,16 @@ contains do k = is1_viscous%beg, is1_viscous%end $:GPU_LOOP(parallelism='[seq]') do i = iv%beg, iv%end - dqL_prim_dz_n(2)%vf(i)%sf(k, j, l) = (dqL_prim_dz_n(3)%vf(i)%sf(k, j, & - & l) + dqR_prim_dz_n(3)%vf(i)%sf(k, j, l) + dqL_prim_dz_n(3)%vf(i)%sf(k, & - & j - 1, l) + dqR_prim_dz_n(3)%vf(i)%sf(k, j - 1, l)) - dqL_prim_dz_n(2)%vf(i)%sf(k, j, l) = 25.e-2_wp*dqL_prim_dz_n(2)%vf(i)%sf(k, j, l) + dqL_prim_dz_n(2)%vf(i)%sf(k, j, l) = & + (dqL_prim_dz_n(3)%vf(i)%sf(k, j, l) + & + dqR_prim_dz_n(3)%vf(i)%sf(k, j, l) + & + dqL_prim_dz_n(3)%vf(i)%sf(k, j - 1, l) + & + dqR_prim_dz_n(3)%vf(i)%sf(k, j - 1, l)) + + dqL_prim_dz_n(2)%vf(i)%sf(k, j, l) = 25.e-2_wp* & + dqL_prim_dz_n(2)%vf(i)%sf(k, j, l) + end do end do end do @@ -744,12 +889,16 @@ contains do k = is1_viscous%beg, is1_viscous%end $:GPU_LOOP(parallelism='[seq]') do i = iv%beg, iv%end - dqR_prim_dz_n(2)%vf(i)%sf(k, j, l) = (dqL_prim_dz_n(3)%vf(i)%sf(k, j + 1, & - & l) + dqR_prim_dz_n(3)%vf(i)%sf(k, j + 1, & - & l) + dqL_prim_dz_n(3)%vf(i)%sf(k, j, l) + dqR_prim_dz_n(3)%vf(i)%sf(k, j, & - & l)) - dqR_prim_dz_n(2)%vf(i)%sf(k, j, l) = 25.e-2_wp*dqR_prim_dz_n(2)%vf(i)%sf(k, j, l) + dqR_prim_dz_n(2)%vf(i)%sf(k, j, l) = & + (dqL_prim_dz_n(3)%vf(i)%sf(k, j + 1, l) + & + dqR_prim_dz_n(3)%vf(i)%sf(k, j + 1, l) + & + dqL_prim_dz_n(3)%vf(i)%sf(k, j, l) + & + dqR_prim_dz_n(3)%vf(i)%sf(k, j, l)) + + dqR_prim_dz_n(2)%vf(i)%sf(k, j, l) = 25.e-2_wp* & + dqR_prim_dz_n(2)%vf(i)%sf(k, j, l) + end do end do end do @@ -762,11 +911,16 @@ contains do k = is1_viscous%beg, is1_viscous%end $:GPU_LOOP(parallelism='[seq]') do i = iv%beg, iv%end - dqL_prim_dy_n(3)%vf(i)%sf(k, l, j) = (dqL_prim_dy_n(2)%vf(i)%sf(k, l, & - & j) + dqR_prim_dy_n(2)%vf(i)%sf(k, l, j) + dqL_prim_dy_n(2)%vf(i)%sf(k, l, & - & j - 1) + dqR_prim_dy_n(2)%vf(i)%sf(k, l, j - 1)) - dqL_prim_dy_n(3)%vf(i)%sf(k, l, j) = 25.e-2_wp*dqL_prim_dy_n(3)%vf(i)%sf(k, l, j) + dqL_prim_dy_n(3)%vf(i)%sf(k, l, j) = & + (dqL_prim_dy_n(2)%vf(i)%sf(k, l, j) + & + dqR_prim_dy_n(2)%vf(i)%sf(k, l, j) + & + dqL_prim_dy_n(2)%vf(i)%sf(k, l, j - 1) + & + dqR_prim_dy_n(2)%vf(i)%sf(k, l, j - 1)) + + dqL_prim_dy_n(3)%vf(i)%sf(k, l, j) = 25.e-2_wp* & + dqL_prim_dy_n(3)%vf(i)%sf(k, l, j) + end do end do end do @@ -779,12 +933,16 @@ contains do k = is1_viscous%beg, is1_viscous%end $:GPU_LOOP(parallelism='[seq]') do i = iv%beg, iv%end - dqR_prim_dy_n(3)%vf(i)%sf(k, l, j) = (dqL_prim_dy_n(2)%vf(i)%sf(k, l, & - & j + 1) + dqR_prim_dy_n(2)%vf(i)%sf(k, l, & - & j + 1) + dqL_prim_dy_n(2)%vf(i)%sf(k, l, & - & j) + dqR_prim_dy_n(2)%vf(i)%sf(k, l, j)) - dqR_prim_dy_n(3)%vf(i)%sf(k, l, j) = 25.e-2_wp*dqR_prim_dy_n(3)%vf(i)%sf(k, l, j) + dqR_prim_dy_n(3)%vf(i)%sf(k, l, j) = & + (dqL_prim_dy_n(2)%vf(i)%sf(k, l, j + 1) + & + dqR_prim_dy_n(2)%vf(i)%sf(k, l, j + 1) + & + dqL_prim_dy_n(2)%vf(i)%sf(k, l, j) + & + dqR_prim_dy_n(2)%vf(i)%sf(k, l, j)) + + dqR_prim_dy_n(3)%vf(i)%sf(k, l, j) = 25.e-2_wp* & + dqR_prim_dy_n(3)%vf(i)%sf(k, l, j) + end do end do end do @@ -796,11 +954,16 @@ contains do k = is1_viscous%beg + 1, is1_viscous%end - 1 $:GPU_LOOP(parallelism='[seq]') do i = iv%beg, iv%end - dqL_prim_dx_n(3)%vf(i)%sf(k, l, j) = (dqL_prim_dx_n(1)%vf(i)%sf(k, l, & - & j) + dqR_prim_dx_n(1)%vf(i)%sf(k, l, j) + dqL_prim_dx_n(1)%vf(i)%sf(k, l, & - & j - 1) + dqR_prim_dx_n(1)%vf(i)%sf(k, l, j - 1)) - dqL_prim_dx_n(3)%vf(i)%sf(k, l, j) = 25.e-2_wp*dqL_prim_dx_n(3)%vf(i)%sf(k, l, j) + dqL_prim_dx_n(3)%vf(i)%sf(k, l, j) = & + (dqL_prim_dx_n(1)%vf(i)%sf(k, l, j) + & + dqR_prim_dx_n(1)%vf(i)%sf(k, l, j) + & + dqL_prim_dx_n(1)%vf(i)%sf(k, l, j - 1) + & + dqR_prim_dx_n(1)%vf(i)%sf(k, l, j - 1)) + + dqL_prim_dx_n(3)%vf(i)%sf(k, l, j) = 25.e-2_wp* & + dqL_prim_dx_n(3)%vf(i)%sf(k, l, j) + end do end do end do @@ -812,12 +975,15 @@ contains do k = is1_viscous%beg + 1, is1_viscous%end - 1 $:GPU_LOOP(parallelism='[seq]') do i = iv%beg, iv%end - dqR_prim_dx_n(3)%vf(i)%sf(k, l, j) = (dqL_prim_dx_n(1)%vf(i)%sf(k, l, & - & j + 1) + dqR_prim_dx_n(1)%vf(i)%sf(k, l, & - & j + 1) + dqL_prim_dx_n(1)%vf(i)%sf(k, l, & - & j) + dqR_prim_dx_n(1)%vf(i)%sf(k, l, j)) + dqR_prim_dx_n(3)%vf(i)%sf(k, l, j) = & + (dqL_prim_dx_n(1)%vf(i)%sf(k, l, j + 1) + & + dqR_prim_dx_n(1)%vf(i)%sf(k, l, j + 1) + & + dqL_prim_dx_n(1)%vf(i)%sf(k, l, j) + & + dqR_prim_dx_n(1)%vf(i)%sf(k, l, j)) + + dqR_prim_dx_n(3)%vf(i)%sf(k, l, j) = 25.e-2_wp* & + dqR_prim_dx_n(3)%vf(i)%sf(k, l, j) - dqR_prim_dx_n(3)%vf(i)%sf(k, l, j) = 25.e-2_wp*dqR_prim_dx_n(3)%vf(i)%sf(k, l, j) end do end do end do @@ -825,37 +991,52 @@ contains $:END_GPU_PARALLEL_LOOP() do i = iv%beg, iv%end - call s_compute_fd_gradient(q_prim_qp%vf(i), dq_prim_dx_qp(1)%vf(i), dq_prim_dy_qp(1)%vf(i), & - & dq_prim_dz_qp(1)%vf(i)) + call s_compute_fd_gradient(q_prim_qp%vf(i), & + dq_prim_dx_qp(1)%vf(i), & + dq_prim_dy_qp(1)%vf(i), & + dq_prim_dz_qp(1)%vf(i)) end do #:endif + else + do i = iv%beg, iv%end - call s_compute_fd_gradient(q_prim_qp%vf(i), dq_prim_dx_qp(1)%vf(i), dq_prim_dy_qp(1)%vf(i), & - & dq_prim_dy_qp(1)%vf(i)) + call s_compute_fd_gradient(q_prim_qp%vf(i), & + dq_prim_dx_qp(1)%vf(i), & + dq_prim_dy_qp(1)%vf(i), & + dq_prim_dy_qp(1)%vf(i)) end do + end if + else + do i = iv%beg, iv%end - call s_compute_fd_gradient(q_prim_qp%vf(i), dq_prim_dx_qp(1)%vf(i), dq_prim_dx_qp(1)%vf(i), & - & dq_prim_dx_qp(1)%vf(i)) + call s_compute_fd_gradient(q_prim_qp%vf(i), & + dq_prim_dx_qp(1)%vf(i), & + dq_prim_dx_qp(1)%vf(i), & + dq_prim_dx_qp(1)%vf(i)) end do + end if + end if end subroutine s_get_viscous - !> Reconstruct left and right cell-boundary values of viscous primitive variables - subroutine s_reconstruct_cell_boundary_values_visc(v_vf, vL_x, vL_y, vL_z, vR_x, vR_y, vR_z, norm_dir, vL_prim_vf, & - - & vR_prim_vf, ix, iy, iz) + !> @brief Reconstructs left and right cell-boundary values of viscous primitive variables using WENO or MUSCL. + subroutine s_reconstruct_cell_boundary_values_visc(v_vf, vL_x, vL_y, vL_z, vR_x, vR_y, vR_z, & + norm_dir, vL_prim_vf, vR_prim_vf, ix, iy, iz) type(scalar_field), dimension(iv%beg:iv%end), intent(in) :: v_vf type(scalar_field), dimension(iv%beg:iv%end), intent(inout) :: vL_prim_vf, vR_prim_vf - real(wp), dimension(idwbuff(1)%beg:,idwbuff(2)%beg:,idwbuff(3)%beg:,1:), intent(inout) :: vL_x, vL_y, vL_z, vR_x, vR_y, vR_z + + real(wp), dimension(idwbuff(1)%beg:, idwbuff(2)%beg:, idwbuff(3)%beg:, 1:), intent(inout) :: vL_x, vL_y, vL_z, vR_x, vR_y, vR_z integer, intent(in) :: norm_dir type(int_bounds_info), intent(in) :: ix, iy, iz - integer :: recon_dir !< Coordinate direction of the WENO reconstruction + + integer :: recon_dir !< Coordinate direction of the WENO reconstruction + integer :: i, j, k, l #:for SCHEME, TYPE in [('weno','WENO_TYPE'), ('muscl','MUSCL_TYPE')] @@ -866,31 +1047,37 @@ contains is1_viscous = ix; is2_viscous = iy; is3_viscous = iz recon_dir = 1; is1_viscous%beg = is1_viscous%beg + ${SCHEME}$_polyn is1_viscous%end = is1_viscous%end - ${SCHEME}$_polyn - else if (norm_dir == 2) then + + elseif (norm_dir == 2) then is1_viscous = iy; is2_viscous = ix; is3_viscous = iz recon_dir = 2; is1_viscous%beg = is1_viscous%beg + ${SCHEME}$_polyn is1_viscous%end = is1_viscous%end - ${SCHEME}$_polyn + else is1_viscous = iz; is2_viscous = iy; is3_viscous = ix recon_dir = 3; is1_viscous%beg = is1_viscous%beg + ${SCHEME}$_polyn is1_viscous%end = is1_viscous%end - ${SCHEME}$_polyn + end if $:GPU_UPDATE(device='[is1_viscous, is2_viscous, is3_viscous, iv]') if (n > 0) then if (p > 0) then - call s_${SCHEME}$ (v_vf(iv%beg:iv%end), vL_x(:,:,:,iv%beg:iv%end), vL_y(:,:,:,iv%beg:iv%end), vL_z(:,:,:, & - & iv%beg:iv%end), vR_x(:,:,:,iv%beg:iv%end), vR_y(:,:,:,iv%beg:iv%end), vR_z(:,:,:, & - & iv%beg:iv%end), recon_dir, is1_viscous, is2_viscous, is3_viscous) + call s_${SCHEME}$ (v_vf(iv%beg:iv%end), & + vL_x(:, :, :, iv%beg:iv%end), vL_y(:, :, :, iv%beg:iv%end), vL_z(:, :, :, iv%beg:iv%end), vR_x(:, :, :, iv%beg:iv%end), vR_y(:, :, :, iv%beg:iv%end), vR_z(:, :, :, iv%beg:iv%end), & + recon_dir, & + is1_viscous, is2_viscous, is3_viscous) else - call s_${SCHEME}$ (v_vf(iv%beg:iv%end), vL_x(:,:,:,iv%beg:iv%end), vL_y(:,:,:,iv%beg:iv%end), vL_z(:,:,:, & - & :), vR_x(:,:,:,iv%beg:iv%end), vR_y(:,:,:,iv%beg:iv%end), vR_z(:,:,:,:), recon_dir, & - & is1_viscous, is2_viscous, is3_viscous) + call s_${SCHEME}$ (v_vf(iv%beg:iv%end), & + vL_x(:, :, :, iv%beg:iv%end), vL_y(:, :, :, iv%beg:iv%end), vL_z(:, :, :, :), vR_x(:, :, :, iv%beg:iv%end), vR_y(:, :, :, iv%beg:iv%end), vR_z(:, :, :, :), & + recon_dir, & + is1_viscous, is2_viscous, is3_viscous) end if else - call s_${SCHEME}$ (v_vf(iv%beg:iv%end), vL_x(:,:,:,iv%beg:iv%end), vL_y(:,:,:,:), vL_z(:,:,:,:), vR_x(:,:,:, & - & iv%beg:iv%end), vR_y(:,:,:,:), vR_z(:,:,:,:), recon_dir, is1_viscous, is2_viscous, & - & is3_viscous) + call s_${SCHEME}$ (v_vf(iv%beg:iv%end), & + vL_x(:, :, :, iv%beg:iv%end), vL_y(:, :, :, :), vL_z(:, :, :, :), vR_x(:, :, :, iv%beg:iv%end), vR_y(:, :, :, :), vR_z(:, :, :, :), & + recon_dir, & + is1_viscous, is2_viscous, is3_viscous) end if end if #:endfor @@ -910,7 +1097,7 @@ contains end do end do $:END_GPU_PARALLEL_LOOP() - else if (norm_dir == 3) then + elseif (norm_dir == 3) then $:GPU_PARALLEL_LOOP(collapse=4) do i = iv%beg, iv%end do j = is1_viscous%beg, is1_viscous%end @@ -923,7 +1110,7 @@ contains end do end do $:END_GPU_PARALLEL_LOOP() - else if (norm_dir == 1) then + elseif (norm_dir == 1) then $:GPU_PARALLEL_LOOP(collapse=4) do i = iv%beg, iv%end do l = is3_viscous%beg, is3_viscous%end @@ -942,19 +1129,19 @@ contains end subroutine s_reconstruct_cell_boundary_values_visc - !> Reconstruct left and right cell-boundary values of viscous primitive variable derivatives - subroutine s_reconstruct_cell_boundary_values_visc_deriv(v_vf, vL_x, vL_y, vL_z, vR_x, vR_y, vR_z, norm_dir, vL_prim_vf, & - - & vR_prim_vf, ix, iy, iz) - type(scalar_field), dimension(iv%beg:iv%end), intent(in) :: v_vf - real(wp), dimension(idwbuff(1)%beg:,idwbuff(2)%beg:,idwbuff(3)%beg:,iv%beg:), intent(inout) :: vL_x, vL_y, vL_z, vR_x, & - & vR_y, vR_z + !> @brief Reconstructs left and right cell-boundary values of viscous primitive variable derivatives using WENO or MUSCL. + subroutine s_reconstruct_cell_boundary_values_visc_deriv(v_vf, vL_x, vL_y, vL_z, vR_x, vR_y, vR_z, & + norm_dir, vL_prim_vf, vR_prim_vf, ix, iy, iz) + type(scalar_field), dimension(iv%beg:iv%end), intent(in) :: v_vf + real(wp), dimension(idwbuff(1)%beg:, idwbuff(2)%beg:, idwbuff(3)%beg:, iv%beg:), intent(inout) :: vL_x, vL_y, vL_z, vR_x, vR_y, vR_z type(scalar_field), dimension(iv%beg:iv%end), intent(inout) :: vL_prim_vf, vR_prim_vf - type(int_bounds_info), intent(in) :: ix, iy, iz - integer, intent(in) :: norm_dir - integer :: recon_dir !< Coordinate direction of the WENO reconstruction - integer :: i, j, k, l + type(int_bounds_info), intent(in) :: ix, iy, iz + + integer, intent(IN) :: norm_dir + + integer :: recon_dir !< Coordinate direction of the WENO reconstruction + integer :: i, j, k, l #:for SCHEME, TYPE in [('weno','WENO_TYPE'), ('muscl','MUSCL_TYPE')] if (recon_type == ${TYPE}$) then ! Reconstruction in s1-direction @@ -963,30 +1150,38 @@ contains is1_viscous = ix; is2_viscous = iy; is3_viscous = iz recon_dir = 1; is1_viscous%beg = is1_viscous%beg + ${SCHEME}$_polyn is1_viscous%end = is1_viscous%end - ${SCHEME}$_polyn - else if (norm_dir == 2) then + + elseif (norm_dir == 2) then is1_viscous = iy; is2_viscous = ix; is3_viscous = iz recon_dir = 2; is1_viscous%beg = is1_viscous%beg + ${SCHEME}$_polyn is1_viscous%end = is1_viscous%end - ${SCHEME}$_polyn + else is1_viscous = iz; is2_viscous = iy; is3_viscous = ix recon_dir = 3; is1_viscous%beg = is1_viscous%beg + ${SCHEME}$_polyn is1_viscous%end = is1_viscous%end - ${SCHEME}$_polyn + end if $:GPU_UPDATE(device='[is1_viscous, is2_viscous, is3_viscous, iv]') if (n > 0) then if (p > 0) then - call s_${SCHEME}$ (v_vf(iv%beg:iv%end), vL_x(:,:,:,iv%beg:iv%end), vL_y(:,:,:,iv%beg:iv%end), vL_z(:,:,:, & - & iv%beg:iv%end), vR_x(:,:,:,iv%beg:iv%end), vR_y(:,:,:,iv%beg:iv%end), vR_z(:,:,:, & - & iv%beg:iv%end), recon_dir, is1_viscous, is2_viscous, is3_viscous) + + call s_${SCHEME}$ (v_vf(iv%beg:iv%end), & + vL_x(:, :, :, iv%beg:iv%end), vL_y(:, :, :, iv%beg:iv%end), vL_z(:, :, :, iv%beg:iv%end), vR_x(:, :, :, iv%beg:iv%end), vR_y(:, :, :, iv%beg:iv%end), vR_z(:, :, :, iv%beg:iv%end), & + recon_dir, & + is1_viscous, is2_viscous, is3_viscous) else - call s_${SCHEME}$ (v_vf(iv%beg:iv%end), vL_x(:,:,:,iv%beg:iv%end), vL_y(:,:,:,iv%beg:iv%end), vL_z(:,:,:, & - & :), vR_x(:,:,:,iv%beg:iv%end), vR_y(:,:,:,iv%beg:iv%end), vR_z(:,:,:,:), recon_dir, & - & is1_viscous, is2_viscous, is3_viscous) + call s_${SCHEME}$ (v_vf(iv%beg:iv%end), & + vL_x(:, :, :, iv%beg:iv%end), vL_y(:, :, :, iv%beg:iv%end), vL_z(:, :, :, :), vR_x(:, :, :, iv%beg:iv%end), vR_y(:, :, :, iv%beg:iv%end), vR_z(:, :, :, :), & + recon_dir, & + is1_viscous, is2_viscous, is3_viscous) end if else - call s_${SCHEME}$ (v_vf(iv%beg:iv%end), vL_x(:,:,:,iv%beg:iv%end), vL_y(:,:,:,:), vL_z(:,:,:,:), vR_x(:,:,:, & - & iv%beg:iv%end), vR_y(:,:,:,:), vR_z(:,:,:,:), recon_dir, is1_viscous, is2_viscous, & - & is3_viscous) + + call s_${SCHEME}$ (v_vf(iv%beg:iv%end), & + vL_x(:, :, :, iv%beg:iv%end), vL_y(:, :, :, :), vL_z(:, :, :, :), vR_x(:, :, :, iv%beg:iv%end), vR_y(:, :, :, :), vR_z(:, :, :, :), & + recon_dir, & + is1_viscous, is2_viscous, is3_viscous) end if end if #:endfor @@ -1006,7 +1201,7 @@ contains end do end do $:END_GPU_PARALLEL_LOOP() - else if (norm_dir == 3) then + elseif (norm_dir == 3) then $:GPU_PARALLEL_LOOP(collapse=4) do i = iv%beg, iv%end do j = is1_viscous%beg, is1_viscous%end @@ -1019,7 +1214,7 @@ contains end do end do $:END_GPU_PARALLEL_LOOP() - else if (norm_dir == 1) then + elseif (norm_dir == 1) then $:GPU_PARALLEL_LOOP(collapse=4) do i = iv%beg, iv%end do l = is3_viscous%beg, is3_viscous%end @@ -1038,17 +1233,43 @@ contains end subroutine s_reconstruct_cell_boundary_values_visc_deriv - !> Compute cell-average spatial derivatives via the scalar divergence theorem - subroutine s_apply_scalar_divergence_theorem(vL_vf, vR_vf, dv_ds_vf, norm_dir, ix, iy, iz, iv_in, dL, dim, buff_size_in) + !> The purpose of this subroutine is to employ the inputted + !! left and right cell-boundary integral-averaged variables + !! to compute the relevant cell-average first-order spatial + !! derivatives in the x-, y- or z-direction by means of the + !! scalar divergence theorem. + !! @param vL_vf Left cell-boundary integral averages + !! @param vR_vf Right cell-boundary integral averages + !! @param dv_ds_vf Cell-average first-order spatial derivatives + !! @param norm_dir Splitting coordinate direction + !! @param ix Index bounds in the x-direction + !! @param iy Index bounds in the y-direction + !! @param iz Index bounds in the z-direction + !! @param iv_in Variable index bounds + !! @param dL Cell width array + !! @param dim Dimension size + !! @param buff_size_in Buffer layer size + subroutine s_apply_scalar_divergence_theorem(vL_vf, vR_vf, & + dv_ds_vf, & + norm_dir, & + ix, iy, iz, iv_in, & + dL, dim, buff_size_in) ! arrays of cell widths - type(scalar_field), dimension(iv%beg:iv%end), intent(in) :: vL_vf, vR_vf - type(scalar_field), dimension(iv%beg:iv%end), intent(inout) :: dv_ds_vf - integer, intent(in) :: norm_dir - type(int_bounds_info), intent(in) :: ix, iy, iz, iv_in - integer, intent(in) :: dim, buff_size_in + type(scalar_field), & + dimension(iv%beg:iv%end), & + intent(in) :: vL_vf, vR_vf + + type(scalar_field), & + dimension(iv%beg:iv%end), & + intent(inout) :: dv_ds_vf + + integer, intent(in) :: norm_dir + type(int_bounds_info), intent(in) :: ix, iy, iz, iv_in + integer, intent(in) :: dim, buff_size_in real(wp), dimension(-buff_size_in:dim + buff_size_in), intent(in) :: dL - integer :: i, j, k, l !< Generic loop iterators + + integer :: i, j, k, l !< Generic loop iterators is1_viscous = ix is2_viscous = iy @@ -1059,9 +1280,12 @@ contains ! First-Order Spatial Derivatives in x-direction if (norm_dir == 1) then - ! A general application of the scalar divergence theorem that utilizes the left and right cell-boundary - ! integral-averages, inside each cell, or an arithmetic mean of these two at the cell-boundaries, to calculate the - ! cell-averaged first-order spatial derivatives inside the cell. + + ! A general application of the scalar divergence theorem that + ! utilizes the left and right cell-boundary integral-averages, + ! inside each cell, or an arithmetic mean of these two at the + ! cell-boundaries, to calculate the cell-averaged first-order + ! spatial derivatives inside the cell. $:GPU_PARALLEL_LOOP(collapse=3) do l = is3_viscous%beg, is3_viscous%end @@ -1069,8 +1293,12 @@ contains do j = is1_viscous%beg + 1, is1_viscous%end - 1 $:GPU_LOOP(parallelism='[seq]') do i = iv%beg, iv%end - dv_ds_vf(i)%sf(j, k, l) = 1._wp/((1._wp + wa_flg)*dL(j))*(wa_flg*vL_vf(i)%sf(j + 1, k, & - & l) + vR_vf(i)%sf(j, k, l) - vL_vf(i)%sf(j, k, l) - wa_flg*vR_vf(i)%sf(j - 1, k, l)) + dv_ds_vf(i)%sf(j, k, l) = & + 1._wp/((1._wp + wa_flg)*dL(j)) & + *(wa_flg*vL_vf(i)%sf(j + 1, k, l) & + + vR_vf(i)%sf(j, k, l) & + - vL_vf(i)%sf(j, k, l) & + - wa_flg*vR_vf(i)%sf(j - 1, k, l)) end do end do end do @@ -1080,10 +1308,13 @@ contains ! END: First-Order Spatial Derivatives in x-direction ! First-Order Spatial Derivatives in y-direction - else if (norm_dir == 2) then - ! A general application of the scalar divergence theorem that utilizes the left and right cell-boundary - ! integral-averages, inside each cell, or an arithmetic mean of these two at the cell-boundaries, to calculate the - ! cell-averaged first-order spatial derivatives inside the cell. + elseif (norm_dir == 2) then + + ! A general application of the scalar divergence theorem that + ! utilizes the left and right cell-boundary integral-averages, + ! inside each cell, or an arithmetic mean of these two at the + ! cell-boundaries, to calculate the cell-averaged first-order + ! spatial derivatives inside the cell. $:GPU_PARALLEL_LOOP(collapse=3) do l = is3_viscous%beg, is3_viscous%end @@ -1091,8 +1322,12 @@ contains do j = is1_viscous%beg, is1_viscous%end $:GPU_LOOP(parallelism='[seq]') do i = iv%beg, iv%end - dv_ds_vf(i)%sf(j, k, l) = 1._wp/((1._wp + wa_flg)*dL(k))*(wa_flg*vL_vf(i)%sf(j, k + 1, & - & l) + vR_vf(i)%sf(j, k, l) - vL_vf(i)%sf(j, k, l) - wa_flg*vR_vf(i)%sf(j, k - 1, l)) + dv_ds_vf(i)%sf(j, k, l) = & + 1._wp/((1._wp + wa_flg)*dL(k)) & + *(wa_flg*vL_vf(i)%sf(j, k + 1, l) & + + vR_vf(i)%sf(j, k, l) & + - vL_vf(i)%sf(j, k, l) & + - wa_flg*vR_vf(i)%sf(j, k - 1, l)) end do end do end do @@ -1103,9 +1338,12 @@ contains ! First-Order Spatial Derivatives in z-direction else - ! A general application of the scalar divergence theorem that utilizes the left and right cell-boundary - ! integral-averages, inside each cell, or an arithmetic mean of these two at the cell-boundaries, to calculate the - ! cell-averaged first-order spatial derivatives inside the cell. + + ! A general application of the scalar divergence theorem that + ! utilizes the left and right cell-boundary integral-averages, + ! inside each cell, or an arithmetic mean of these two at the + ! cell-boundaries, to calculate the cell-averaged first-order + ! spatial derivatives inside the cell. $:GPU_PARALLEL_LOOP(collapse=3) do l = is3_viscous%beg + 1, is3_viscous%end - 1 @@ -1113,27 +1351,37 @@ contains do j = is1_viscous%beg, is1_viscous%end $:GPU_LOOP(parallelism='[seq]') do i = iv%beg, iv%end - dv_ds_vf(i)%sf(j, k, l) = 1._wp/((1._wp + wa_flg)*dL(l))*(wa_flg*vL_vf(i)%sf(j, k, & - & l + 1) + vR_vf(i)%sf(j, k, l) - vL_vf(i)%sf(j, k, l) - wa_flg*vR_vf(i)%sf(j, k, l - 1)) + dv_ds_vf(i)%sf(j, k, l) = & + 1._wp/((1._wp + wa_flg)*dL(l)) & + *(wa_flg*vL_vf(i)%sf(j, k, l + 1) & + + vR_vf(i)%sf(j, k, l) & + - vL_vf(i)%sf(j, k, l) & + - wa_flg*vR_vf(i)%sf(j, k, l - 1)) end do end do end do end do $:END_GPU_PARALLEL_LOOP() + end if ! END: First-Order Spatial Derivatives in z-direction end subroutine s_apply_scalar_divergence_theorem - !> Computes the scalar gradient fields via finite differences + !> Computes the scalar gradient fields via finite differences + !! @param var Variable to compute derivative of + !! @param grad_x First coordinate direction component of the derivative + !! @param grad_y Second coordinate direction component of the derivative + !! @param grad_z Third coordinate direction component of the derivative subroutine s_compute_fd_gradient(var, grad_x, grad_y, grad_z) - type(scalar_field), intent(in) :: var + type(scalar_field), intent(in) :: var type(scalar_field), intent(inout) :: grad_x type(scalar_field), intent(inout) :: grad_y type(scalar_field), intent(inout) :: grad_z - type(int_bounds_info) :: ix, iy, iz - integer :: j, k, l !< Generic loop iterators + type(int_bounds_info) :: ix, iy, iz + + integer :: j, k, l !< Generic loop iterators ix%beg = 1 - buff_size; ix%end = m + buff_size - 1 if (n > 0) then @@ -1150,13 +1398,15 @@ contains is1_viscous = ix; is2_viscous = iy; is3_viscous = iz - $:GPU_UPDATE(device='[is1_viscous, is2_viscous, is3_viscous]') + $:GPU_UPDATE(device='[is1_viscous,is2_viscous,is3_viscous]') $:GPU_PARALLEL_LOOP(collapse=3) do l = is3_viscous%beg, is3_viscous%end do k = is2_viscous%beg, is2_viscous%end do j = is1_viscous%beg, is1_viscous%end - grad_x%sf(j, k, l) = (var%sf(j + 1, k, l) - var%sf(j - 1, k, l))/(x_cc(j + 1) - x_cc(j - 1)) + grad_x%sf(j, k, l) = & + (var%sf(j + 1, k, l) - var%sf(j - 1, k, l))/ & + (x_cc(j + 1) - x_cc(j - 1)) end do end do end do @@ -1167,7 +1417,9 @@ contains do l = is3_viscous%beg, is3_viscous%end do k = is2_viscous%beg, is2_viscous%end do j = is1_viscous%beg, is1_viscous%end - grad_y%sf(j, k, l) = (var%sf(j, k + 1, l) - var%sf(j, k - 1, l))/(y_cc(k + 1) - y_cc(k - 1)) + grad_y%sf(j, k, l) = & + (var%sf(j, k + 1, l) - var%sf(j, k - 1, l))/ & + (y_cc(k + 1) - y_cc(k - 1)) end do end do end do @@ -1179,7 +1431,9 @@ contains do l = is3_viscous%beg, is3_viscous%end do k = is2_viscous%beg, is2_viscous%end do j = is1_viscous%beg, is1_viscous%end - grad_z%sf(j, k, l) = (var%sf(j, k, l + 1) - var%sf(j, k, l - 1))/(z_cc(l + 1) - z_cc(l - 1)) + grad_z%sf(j, k, l) = & + (var%sf(j, k, l + 1) - var%sf(j, k, l - 1))/ & + (z_cc(l + 1) - z_cc(l - 1)) end do end do end do @@ -1189,10 +1443,12 @@ contains $:GPU_PARALLEL_LOOP(collapse=2) do l = idwbuff(3)%beg, idwbuff(3)%end do k = idwbuff(2)%beg, idwbuff(2)%end - grad_x%sf(idwbuff(1)%beg, k, l) = (-3._wp*var%sf(idwbuff(1)%beg, k, l) + 4._wp*var%sf(idwbuff(1)%beg + 1, k, & - & l) - var%sf(idwbuff(1)%beg + 2, k, l))/(x_cc(idwbuff(1)%beg + 2) - x_cc(idwbuff(1)%beg)) - grad_x%sf(idwbuff(1)%end, k, l) = (+3._wp*var%sf(idwbuff(1)%end, k, l) - 4._wp*var%sf(idwbuff(1)%end - 1, k, & - & l) + var%sf(idwbuff(1)%end - 2, k, l))/(x_cc(idwbuff(1)%end) - x_cc(idwbuff(1)%end - 2)) + grad_x%sf(idwbuff(1)%beg, k, l) = & + (-3._wp*var%sf(idwbuff(1)%beg, k, l) + 4._wp*var%sf(idwbuff(1)%beg + 1, k, l) - var%sf(idwbuff(1)%beg + 2, k, l))/ & + (x_cc(idwbuff(1)%beg + 2) - x_cc(idwbuff(1)%beg)) + grad_x%sf(idwbuff(1)%end, k, l) = & + (+3._wp*var%sf(idwbuff(1)%end, k, l) - 4._wp*var%sf(idwbuff(1)%end - 1, k, l) + var%sf(idwbuff(1)%end - 2, k, l))/ & + (x_cc(idwbuff(1)%end) - x_cc(idwbuff(1)%end - 2)) end do end do $:END_GPU_PARALLEL_LOOP() @@ -1200,10 +1456,12 @@ contains $:GPU_PARALLEL_LOOP(collapse=2) do l = idwbuff(3)%beg, idwbuff(3)%end do j = idwbuff(1)%beg, idwbuff(1)%end - grad_y%sf(j, idwbuff(2)%beg, l) = (-3._wp*var%sf(j, idwbuff(2)%beg, l) + 4._wp*var%sf(j, idwbuff(2)%beg + 1, & - & l) - var%sf(j, idwbuff(2)%beg + 2, l))/(y_cc(idwbuff(2)%beg + 2) - y_cc(idwbuff(2)%beg)) - grad_y%sf(j, idwbuff(2)%end, l) = (+3._wp*var%sf(j, idwbuff(2)%end, l) - 4._wp*var%sf(j, idwbuff(2)%end - 1, & - & l) + var%sf(j, idwbuff(2)%end - 2, l))/(y_cc(idwbuff(2)%end) - y_cc(idwbuff(2)%end - 2)) + grad_y%sf(j, idwbuff(2)%beg, l) = & + (-3._wp*var%sf(j, idwbuff(2)%beg, l) + 4._wp*var%sf(j, idwbuff(2)%beg + 1, l) - var%sf(j, idwbuff(2)%beg + 2, l))/ & + (y_cc(idwbuff(2)%beg + 2) - y_cc(idwbuff(2)%beg)) + grad_y%sf(j, idwbuff(2)%end, l) = & + (+3._wp*var%sf(j, idwbuff(2)%end, l) - 4._wp*var%sf(j, idwbuff(2)%end - 1, l) + var%sf(j, idwbuff(2)%end - 2, l))/ & + (y_cc(idwbuff(2)%end) - y_cc(idwbuff(2)%end - 2)) end do end do $:END_GPU_PARALLEL_LOOP() @@ -1211,12 +1469,12 @@ contains $:GPU_PARALLEL_LOOP(collapse=2) do k = idwbuff(2)%beg, idwbuff(2)%end do j = idwbuff(1)%beg, idwbuff(1)%end - grad_z%sf(j, k, idwbuff(3)%beg) = (-3._wp*var%sf(j, k, idwbuff(3)%beg) + 4._wp*var%sf(j, k, & - & idwbuff(3)%beg + 1) - var%sf(j, k, & - & idwbuff(3)%beg + 2))/(z_cc(idwbuff(3)%beg + 2) - z_cc(is3_viscous%beg)) - grad_z%sf(j, k, idwbuff(3)%end) = (+3._wp*var%sf(j, k, idwbuff(3)%end) - 4._wp*var%sf(j, k, & - & idwbuff(3)%end - 1) + var%sf(j, k, & - & idwbuff(3)%end - 2))/(z_cc(idwbuff(3)%end) - z_cc(idwbuff(3)%end - 2)) + grad_z%sf(j, k, idwbuff(3)%beg) = & + (-3._wp*var%sf(j, k, idwbuff(3)%beg) + 4._wp*var%sf(j, k, idwbuff(3)%beg + 1) - var%sf(j, k, idwbuff(3)%beg + 2))/ & + (z_cc(idwbuff(3)%beg + 2) - z_cc(is3_viscous%beg)) + grad_z%sf(j, k, idwbuff(3)%end) = & + (+3._wp*var%sf(j, k, idwbuff(3)%end) - 4._wp*var%sf(j, k, idwbuff(3)%end - 1) + var%sf(j, k, idwbuff(3)%end - 2))/ & + (z_cc(idwbuff(3)%end) - z_cc(idwbuff(3)%end - 2)) end do end do $:END_GPU_PARALLEL_LOOP() @@ -1227,7 +1485,8 @@ contains $:GPU_PARALLEL_LOOP(collapse=2) do l = idwbuff(3)%beg, idwbuff(3)%end do k = idwbuff(2)%beg, idwbuff(2)%end - grad_x%sf(0, k, l) = (-3._wp*var%sf(0, k, l) + 4._wp*var%sf(1, k, l) - var%sf(2, k, l))/(x_cc(2) - x_cc(0)) + grad_x%sf(0, k, l) = (-3._wp*var%sf(0, k, l) + 4._wp*var%sf(1, k, l) - var%sf(2, k, l))/ & + (x_cc(2) - x_cc(0)) end do end do $:END_GPU_PARALLEL_LOOP() @@ -1236,8 +1495,8 @@ contains $:GPU_PARALLEL_LOOP(collapse=2) do l = idwbuff(3)%beg, idwbuff(3)%end do k = idwbuff(2)%beg, idwbuff(2)%end - grad_x%sf(m, k, l) = (3._wp*var%sf(m, k, l) - 4._wp*var%sf(m - 1, k, l) + var%sf(m - 2, k, & - & l))/(x_cc(m) - x_cc(m - 2)) + grad_x%sf(m, k, l) = (3._wp*var%sf(m, k, l) - 4._wp*var%sf(m - 1, k, l) + var%sf(m - 2, k, l))/ & + (x_cc(m) - x_cc(m - 2)) end do end do $:END_GPU_PARALLEL_LOOP() @@ -1247,7 +1506,8 @@ contains $:GPU_PARALLEL_LOOP(collapse=2) do l = idwbuff(3)%beg, idwbuff(3)%end do j = idwbuff(1)%beg, idwbuff(1)%end - grad_y%sf(j, 0, l) = (-3._wp*var%sf(j, 0, l) + 4._wp*var%sf(j, 1, l) - var%sf(j, 2, l))/(y_cc(2) - y_cc(0)) + grad_y%sf(j, 0, l) = (-3._wp*var%sf(j, 0, l) + 4._wp*var%sf(j, 1, l) - var%sf(j, 2, l))/ & + (y_cc(2) - y_cc(0)) end do end do $:END_GPU_PARALLEL_LOOP() @@ -1256,8 +1516,8 @@ contains $:GPU_PARALLEL_LOOP(collapse=2) do l = idwbuff(3)%beg, idwbuff(3)%end do j = idwbuff(1)%beg, idwbuff(1)%end - grad_y%sf(j, n, l) = (3._wp*var%sf(j, n, l) - 4._wp*var%sf(j, n - 1, l) + var%sf(j, n - 2, & - & l))/(y_cc(n) - y_cc(n - 2)) + grad_y%sf(j, n, l) = (3._wp*var%sf(j, n, l) - 4._wp*var%sf(j, n - 1, l) + var%sf(j, n - 2, l))/ & + (y_cc(n) - y_cc(n - 2)) end do end do $:END_GPU_PARALLEL_LOOP() @@ -1267,8 +1527,9 @@ contains $:GPU_PARALLEL_LOOP(collapse=2) do k = idwbuff(2)%beg, idwbuff(2)%end do j = idwbuff(1)%beg, idwbuff(1)%end - grad_z%sf(j, k, 0) = (-3._wp*var%sf(j, k, 0) + 4._wp*var%sf(j, k, 1) - var%sf(j, k, & - & 2))/(z_cc(2) - z_cc(0)) + grad_z%sf(j, k, 0) = & + (-3._wp*var%sf(j, k, 0) + 4._wp*var%sf(j, k, 1) - var%sf(j, k, 2))/ & + (z_cc(2) - z_cc(0)) end do end do $:END_GPU_PARALLEL_LOOP() @@ -1277,8 +1538,9 @@ contains $:GPU_PARALLEL_LOOP(collapse=2) do k = idwbuff(2)%beg, idwbuff(2)%end do j = idwbuff(1)%beg, idwbuff(1)%end - grad_z%sf(j, k, p) = (3._wp*var%sf(j, k, p) - 4._wp*var%sf(j, k, p - 1) + var%sf(j, k, & - & p - 2))/(z_cc(p) - z_cc(p - 2)) + grad_z%sf(j, k, p) = & + (3._wp*var%sf(j, k, p) - 4._wp*var%sf(j, k, p - 1) + var%sf(j, k, p - 2))/ & + (z_cc(p) - z_cc(p - 2)) end do end do $:END_GPU_PARALLEL_LOOP() @@ -1288,19 +1550,19 @@ contains end subroutine s_compute_fd_gradient - !> Compute the viscous stress tensor at a single grid cell using finite-difference velocity gradients + !> @brief Computes the viscous stress tensor at a single grid cell using finite-difference velocity gradients. subroutine s_compute_viscous_stress_tensor(viscous_stress_tensor, q_prim_vf, dynamic_viscosity, i, j, k) - $:GPU_ROUTINE(parallelism='[seq]') - real(wp), dimension(1:3,1:3), intent(inout) :: viscous_stress_tensor + real(wp), dimension(1:3, 1:3), intent(inout) :: viscous_stress_tensor type(scalar_field), dimension(1:sys_size), intent(in) :: q_prim_vf - real(wp), intent(in) :: dynamic_viscosity - integer, intent(in) :: i, j, k - real(wp), dimension(1:3,1:3) :: velocity_gradient_tensor - real(wp), dimension(1:3) :: dx - real(wp) :: divergence - integer :: l, q !< iterators + real(wp), intent(in) :: dynamic_viscosity + integer, intent(in) :: i, j, k + + real(wp), dimension(1:3, 1:3) :: velocity_gradient_tensor + real(wp), dimension(1:3) :: dx + real(wp) :: divergence + integer :: l, q ! iterators ! zero the viscous stress, collection of velocity derivatives, and spatial finite differences viscous_stress_tensor = 0._wp @@ -1316,13 +1578,10 @@ contains ! compute the velocity gradient tensor do l = 1, num_dims - velocity_gradient_tensor(l, 1) = (q_prim_vf(momxb + l - 1)%sf(i + 1, j, k) - q_prim_vf(momxb + l - 1)%sf(i - 1, j, & - & k))/(2._wp*dx(1)) - velocity_gradient_tensor(l, 2) = (q_prim_vf(momxb + l - 1)%sf(i, j + 1, k) - q_prim_vf(momxb + l - 1)%sf(i, j - 1, & - & k))/(2._wp*dx(2)) + velocity_gradient_tensor(l, 1) = (q_prim_vf(momxb + l - 1)%sf(i + 1, j, k) - q_prim_vf(momxb + l - 1)%sf(i - 1, j, k))/(2._wp*dx(1)) + velocity_gradient_tensor(l, 2) = (q_prim_vf(momxb + l - 1)%sf(i, j + 1, k) - q_prim_vf(momxb + l - 1)%sf(i, j - 1, k))/(2._wp*dx(2)) if (num_dims == 3) then - velocity_gradient_tensor(l, 3) = (q_prim_vf(momxb + l - 1)%sf(i, j, k + 1) - q_prim_vf(momxb + l - 1)%sf(i, j, & - & k - 1))/(2._wp*dx(3)) + velocity_gradient_tensor(l, 3) = (q_prim_vf(momxb + l - 1)%sf(i, j, k + 1) - q_prim_vf(momxb + l - 1)%sf(i, j, k - 1))/(2._wp*dx(3)) end if end do @@ -1332,14 +1591,14 @@ contains divergence = divergence + velocity_gradient_tensor(l, l) end do - ! Viscous stress tensor: tau_ij = mu * (du_i/dx_j + du_j/dx_i) - 2/3 * mu * div(u) * delta_ij + ! set up the shear stress tensor do l = 1, num_dims do q = 1, num_dims viscous_stress_tensor(l, q) = dynamic_viscosity*(velocity_gradient_tensor(l, q) + velocity_gradient_tensor(q, l)) end do end do - ! Subtract isotropic bulk viscosity term (Stokes hypothesis) + ! populate the viscous_stress_tensor do l = 1, num_dims viscous_stress_tensor(l, l) = viscous_stress_tensor(l, l) - 2._wp*divergence*dynamic_viscosity/3._wp end do @@ -1353,7 +1612,7 @@ contains end subroutine s_compute_viscous_stress_tensor - !> Finalize the viscous module + !> @brief Deallocates the viscous Reynolds number arrays. impure subroutine s_finalize_viscous_module() @:DEALLOCATE(Res_viscous) diff --git a/src/simulation/m_weno.fpp b/src/simulation/m_weno.fpp index c2b1cc5ac7..357a4e9b3e 100644 --- a/src/simulation/m_weno.fpp +++ b/src/simulation/m_weno.fpp @@ -7,82 +7,95 @@ !> @brief WENO/WENO-Z/TENO reconstruction with optional monotonicity-preserving bounds and mapped weights module m_weno - use m_derived_types - use m_global_parameters - use m_variables_conversion + use m_derived_types !< Definitions of the derived types + + use m_global_parameters !< Definitions of the global parameters + + use m_variables_conversion !< State variables type conversion procedures + ! $:USE_GPU_MODULE() use m_mpi_proxy - use m_muscl + + use m_muscl !< For Interface Compression + private; public :: s_initialize_weno_module, s_initialize_weno, s_finalize_weno_module, s_weno - !> @name The cell-average variables that will be WENO-reconstructed. Formerly, they are stored in v_vf. However, they are - !! transferred to v_rs_wsL and v_rs_wsR as to be reshaped (RS) and/or characteristically decomposed. The reshaping allows the - !! WENO procedure to be independent of the coordinate direction of the reconstruction. Lastly, notice that the left (L) and - !! right (R) results of the characteristic decomposition are stored in custom-constructed WENO- stencils (WS) that are annexed - !! to each position of a given scalar field. + !> @name The cell-average variables that will be WENO-reconstructed. Formerly, they + !! are stored in v_vf. However, they are transferred to v_rs_wsL and v_rs_wsR + !! as to be reshaped (RS) and/or characteristically decomposed. The reshaping + !! allows the WENO procedure to be independent of the coordinate direction of + !! the reconstruction. Lastly, notice that the left (L) and right (R) results + !! of the characteristic decomposition are stored in custom-constructed WENO- + !! stencils (WS) that are annexed to each position of a given scalar field. !> @{ - real(wp), allocatable, dimension(:,:,:,:) :: v_rs_ws_x, v_rs_ws_y, v_rs_ws_z + real(wp), allocatable, dimension(:, :, :, :) :: v_rs_ws_x, v_rs_ws_y, v_rs_ws_z !> @} - $:GPU_DECLARE(create='[v_rs_ws_x, v_rs_ws_y, v_rs_ws_z]') + $:GPU_DECLARE(create='[v_rs_ws_x,v_rs_ws_y,v_rs_ws_z]') ! WENO Coefficients - !> @name Polynomial coefficients at the left and right cell-boundaries (CB) and at the left and right quadrature points (QP), in - !! the x-, y- and z-directions. Note that the first dimension of the array identifies the polynomial, the second dimension - !! identifies the position of its coefficients and the last dimension denotes the cell-location in the relevant coordinate - !! direction. + !> @name Polynomial coefficients at the left and right cell-boundaries (CB) and at + !! the left and right quadrature points (QP), in the x-, y- and z-directions. + !! Note that the first dimension of the array identifies the polynomial, the + !! second dimension identifies the position of its coefficients and the last + !! dimension denotes the cell-location in the relevant coordinate direction. !> @{ - real(wp), target, allocatable, dimension(:,:,:) :: poly_coef_cbL_x - real(wp), target, allocatable, dimension(:,:,:) :: poly_coef_cbL_y - real(wp), target, allocatable, dimension(:,:,:) :: poly_coef_cbL_z - real(wp), target, allocatable, dimension(:,:,:) :: poly_coef_cbR_x - real(wp), target, allocatable, dimension(:,:,:) :: poly_coef_cbR_y - real(wp), target, allocatable, dimension(:,:,:) :: poly_coef_cbR_z + real(wp), target, allocatable, dimension(:, :, :) :: poly_coef_cbL_x + real(wp), target, allocatable, dimension(:, :, :) :: poly_coef_cbL_y + real(wp), target, allocatable, dimension(:, :, :) :: poly_coef_cbL_z + real(wp), target, allocatable, dimension(:, :, :) :: poly_coef_cbR_x + real(wp), target, allocatable, dimension(:, :, :) :: poly_coef_cbR_y + real(wp), target, allocatable, dimension(:, :, :) :: poly_coef_cbR_z !> @} - $:GPU_DECLARE(create='[poly_coef_cbL_x, poly_coef_cbL_y, poly_coef_cbL_z]') - $:GPU_DECLARE(create='[poly_coef_cbR_x, poly_coef_cbR_y, poly_coef_cbR_z]') + $:GPU_DECLARE(create='[poly_coef_cbL_x,poly_coef_cbL_y,poly_coef_cbL_z]') + $:GPU_DECLARE(create='[poly_coef_cbR_x,poly_coef_cbR_y,poly_coef_cbR_z]') - !> @name The ideal weights at the left and the right cell-boundaries and at the left and the right quadrature points, in x-, y- - !! and z-directions. Note that the first dimension of the array identifies the weight, while the last denotes the cell-location - !! in the relevant coordinate direction. + !> @name The ideal weights at the left and the right cell-boundaries and at the + !! left and the right quadrature points, in x-, y- and z-directions. Note + !! that the first dimension of the array identifies the weight, while the + !! last denotes the cell-location in the relevant coordinate direction. !> @{ - real(wp), target, allocatable, dimension(:,:) :: d_cbL_x - real(wp), target, allocatable, dimension(:,:) :: d_cbL_y - real(wp), target, allocatable, dimension(:,:) :: d_cbL_z - real(wp), target, allocatable, dimension(:,:) :: d_cbR_x - real(wp), target, allocatable, dimension(:,:) :: d_cbR_y - real(wp), target, allocatable, dimension(:,:) :: d_cbR_z + real(wp), target, allocatable, dimension(:, :) :: d_cbL_x + real(wp), target, allocatable, dimension(:, :) :: d_cbL_y + real(wp), target, allocatable, dimension(:, :) :: d_cbL_z + + real(wp), target, allocatable, dimension(:, :) :: d_cbR_x + real(wp), target, allocatable, dimension(:, :) :: d_cbR_y + real(wp), target, allocatable, dimension(:, :) :: d_cbR_z !> @} - $:GPU_DECLARE(create='[d_cbL_x, d_cbL_y, d_cbL_z, d_cbR_x, d_cbR_y, d_cbR_z]') + $:GPU_DECLARE(create='[d_cbL_x,d_cbL_y,d_cbL_z,d_cbR_x,d_cbR_y,d_cbR_z]') - !> @name Smoothness indicator coefficients in the x-, y-, and z-directions. Note that the first array dimension identifies the - !! smoothness indicator, the second identifies the position of its coefficients and the last denotes the cell-location in the - !! relevant coordinate direction. + !> @name Smoothness indicator coefficients in the x-, y-, and z-directions. Note + !! that the first array dimension identifies the smoothness indicator, the + !! second identifies the position of its coefficients and the last denotes + !! the cell-location in the relevant coordinate direction. !> @{ - real(wp), target, allocatable, dimension(:,:,:) :: beta_coef_x - real(wp), target, allocatable, dimension(:,:,:) :: beta_coef_y - real(wp), target, allocatable, dimension(:,:,:) :: beta_coef_z + real(wp), target, allocatable, dimension(:, :, :) :: beta_coef_x + real(wp), target, allocatable, dimension(:, :, :) :: beta_coef_y + real(wp), target, allocatable, dimension(:, :, :) :: beta_coef_z !> @} - $:GPU_DECLARE(create='[beta_coef_x, beta_coef_y, beta_coef_z]') + $:GPU_DECLARE(create='[beta_coef_x,beta_coef_y,beta_coef_z]') ! END: WENO Coefficients - integer :: v_size !< Number of WENO-reconstructed cell-average variables + integer :: v_size !< Number of WENO-reconstructed cell-average variables $:GPU_DECLARE(create='[v_size]') !> @name Indical bounds in the s1-, s2- and s3-directions !> @{ type(int_bounds_info) :: is1_weno, is2_weno, is3_weno #ifndef __NVCOMPILER_GPU_UNIFIED_MEM - $:GPU_DECLARE(create='[is1_weno, is2_weno, is3_weno]') + $:GPU_DECLARE(create='[is1_weno,is2_weno,is3_weno]') #endif ! !> @} contains - !> Initialize the WENO module + !> The computation of parameters, the allocation of memory, + !! the association of pointers and/or the execution of any + !! other procedures that are necessary to setup the module. impure subroutine s_initialize_weno_module if (weno_order == 1) return @@ -92,7 +105,7 @@ contains if (n == 0) then is2_weno%beg = 0 else - is2_weno%beg = -buff_size + is2_weno%beg = -buff_size; end if is2_weno%end = n - is2_weno%beg @@ -105,20 +118,23 @@ contains is3_weno%end = p - is3_weno%beg - @:ALLOCATE(poly_coef_cbL_x(is1_weno%beg + weno_polyn:is1_weno%end - weno_polyn, 0:weno_polyn, 0:weno_polyn - 1)) - @:ALLOCATE(poly_coef_cbR_x(is1_weno%beg + weno_polyn:is1_weno%end - weno_polyn, 0:weno_polyn, 0:weno_polyn - 1)) + @:ALLOCATE(poly_coef_cbL_x(is1_weno%beg + weno_polyn:is1_weno%end - weno_polyn, 0:weno_polyn, & + 0:weno_polyn - 1)) + @:ALLOCATE(poly_coef_cbR_x(is1_weno%beg + weno_polyn:is1_weno%end - weno_polyn, 0:weno_polyn, & + 0:weno_polyn - 1)) @:ALLOCATE(d_cbL_x(0:weno_num_stencils, is1_weno%beg + weno_polyn:is1_weno%end - weno_polyn)) @:ALLOCATE(d_cbR_x(0:weno_num_stencils, is1_weno%beg + weno_polyn:is1_weno%end - weno_polyn)) @:ALLOCATE(beta_coef_x(is1_weno%beg + weno_polyn:is1_weno%end - weno_polyn, 0:weno_polyn, & - & 0:weno_polyn*(weno_polyn + 1)/2 - 1)) - ! Number of cross terms for dvd = (k-1)(k-1+1)/2, where weno_polyn = k-1 Note: k-1 not k because we are using value - ! differences (dvd) not the values themselves + 0:weno_polyn*(weno_polyn + 1)/2 - 1)) + ! Number of cross terms for dvd = (k-1)(k-1+1)/2, where weno_polyn = k-1 + ! Note: k-1 not k because we are using value differences (dvd) not the values themselves call s_compute_weno_coefficients(1, is1_weno) - @:ALLOCATE(v_rs_ws_x(is1_weno%beg:is1_weno%end, is2_weno%beg:is2_weno%end, is3_weno%beg:is3_weno%end, 1:sys_size)) + @:ALLOCATE(v_rs_ws_x(is1_weno%beg:is1_weno%end, & + is2_weno%beg:is2_weno%end, is3_weno%beg:is3_weno%end, 1:sys_size)) ! Allocating/Computing WENO Coefficients in y-direction if (n == 0) return @@ -134,18 +150,21 @@ contains is3_weno%end = p - is3_weno%beg - @:ALLOCATE(poly_coef_cbL_y(is2_weno%beg + weno_polyn:is2_weno%end - weno_polyn, 0:weno_polyn, 0:weno_polyn - 1)) - @:ALLOCATE(poly_coef_cbR_y(is2_weno%beg + weno_polyn:is2_weno%end - weno_polyn, 0:weno_polyn, 0:weno_polyn - 1)) + @:ALLOCATE(poly_coef_cbL_y(is2_weno%beg + weno_polyn:is2_weno%end - weno_polyn, 0:weno_polyn, & + 0:weno_polyn - 1)) + @:ALLOCATE(poly_coef_cbR_y(is2_weno%beg + weno_polyn:is2_weno%end - weno_polyn, 0:weno_polyn, & + 0:weno_polyn - 1)) @:ALLOCATE(d_cbL_y(0:weno_num_stencils, is2_weno%beg + weno_polyn:is2_weno%end - weno_polyn)) @:ALLOCATE(d_cbR_y(0:weno_num_stencils, is2_weno%beg + weno_polyn:is2_weno%end - weno_polyn)) @:ALLOCATE(beta_coef_y(is2_weno%beg + weno_polyn:is2_weno%end - weno_polyn, 0:weno_polyn, & - & 0:weno_polyn*(weno_polyn + 1)/2 - 1)) + 0:weno_polyn*(weno_polyn + 1)/2 - 1)) call s_compute_weno_coefficients(2, is2_weno) - @:ALLOCATE(v_rs_ws_y(is2_weno%beg:is2_weno%end, is1_weno%beg:is1_weno%end, is3_weno%beg:is3_weno%end, 1:sys_size)) + @:ALLOCATE(v_rs_ws_y(is2_weno%beg:is2_weno%end, & + is1_weno%beg:is1_weno%end, is3_weno%beg:is3_weno%end, 1:sys_size)) ! Allocating/Computing WENO Coefficients in z-direction if (p == 0) return @@ -154,40 +173,53 @@ contains is1_weno%beg = -buff_size; is1_weno%end = m - is1_weno%beg is3_weno%beg = -buff_size; is3_weno%end = p - is3_weno%beg - @:ALLOCATE(poly_coef_cbL_z(is3_weno%beg + weno_polyn:is3_weno%end - weno_polyn, 0:weno_polyn, 0:weno_polyn - 1)) - @:ALLOCATE(poly_coef_cbR_z(is3_weno%beg + weno_polyn:is3_weno%end - weno_polyn, 0:weno_polyn, 0:weno_polyn - 1)) + @:ALLOCATE(poly_coef_cbL_z(is3_weno%beg + weno_polyn:is3_weno%end - weno_polyn, 0:weno_polyn, & + 0:weno_polyn - 1)) + @:ALLOCATE(poly_coef_cbR_z(is3_weno%beg + weno_polyn:is3_weno%end - weno_polyn, 0:weno_polyn, & + 0:weno_polyn - 1)) @:ALLOCATE(d_cbL_z(0:weno_num_stencils, is3_weno%beg + weno_polyn:is3_weno%end - weno_polyn)) @:ALLOCATE(d_cbR_z(0:weno_num_stencils, is3_weno%beg + weno_polyn:is3_weno%end - weno_polyn)) @:ALLOCATE(beta_coef_z(is3_weno%beg + weno_polyn:is3_weno%end - weno_polyn, 0:weno_polyn, & - & 0:weno_polyn*(weno_polyn + 1)/2 - 1)) + 0:weno_polyn*(weno_polyn + 1)/2 - 1)) call s_compute_weno_coefficients(3, is3_weno) - @:ALLOCATE(v_rs_ws_z(is3_weno%beg:is3_weno%end, is2_weno%beg:is2_weno%end, is1_weno%beg:is1_weno%end, 1:sys_size)) + @:ALLOCATE(v_rs_ws_z(is3_weno%beg:is3_weno%end, & + is2_weno%beg:is2_weno%end, is1_weno%beg:is1_weno%end, 1:sys_size)) end subroutine s_initialize_weno_module - !> Compute WENO polynomial coefficients, ideal weights, and smoothness indicators for a given direction + !> The purpose of this subroutine is to compute the grid + !! dependent coefficients of the WENO polynomials, ideal + !! weights and smoothness indicators, provided the order, + !! the coordinate direction and the location of the WENO + !! reconstruction. + !! @param weno_dir Coordinate direction of the WENO reconstruction + !! @param is Index bounds in the s-direction subroutine s_compute_weno_coefficients(weno_dir, is) - ! Compute WENO coefficients for a given coordinate direction. Shu (1997) - - integer, intent(in) :: weno_dir + integer, intent(in) :: weno_dir type(int_bounds_info), intent(in) :: is - integer :: s - real(wp), pointer, dimension(:) :: s_cb => null() !< Cell-boundary locations in the s-direction - type(int_bounds_info) :: bc_s !< Boundary conditions (BC) in the s-direction - integer :: i !< Generic loop iterator - real(wp) :: w(1:8) !< Intermediate var for ideal weights: s_cb across overall stencil - real(wp) :: y(1:4) !< Intermediate var for poly & beta: diff(s_cb) across sub-stencil + integer :: s + + real(wp), pointer, dimension(:) :: s_cb => null() !< + !! Cell-boundary locations in the s-direction + + type(int_bounds_info) :: bc_s !< Boundary conditions (BC) in the s-direction + + integer :: i !< Generic loop iterator - ! Determine cell count, boundary locations, and BCs for selected WENO direction + real(wp) :: w(1:8) ! Intermediate var for ideal weights: s_cb across overall stencil + real(wp) :: y(1:4) ! Intermediate var for poly & beta: diff(s_cb) across sub-stencil + ! Determining the number of cells, the cell-boundary locations and + ! the boundary conditions in the coordinate direction selected for + ! the WENO reconstruction if (weno_dir == 1) then s = m; s_cb => x_cb; bc_s = bc_x - else if (weno_dir == 2) then + elseif (weno_dir == 2) then s = n; s_cb => y_cb; bc_s = bc_y else s = p; s_cb => z_cb; bc_s = bc_z @@ -198,27 +230,34 @@ contains if (weno_dir == ${WENO_DIR}$) then if (weno_order == 3) then do i = is%beg - 1 + weno_polyn, is%end - 1 - weno_polyn - ! Polynomial reconstruction coefficients - poly_coef_cbR_${XYZ}$ (i + 1, 0, 0) = (s_cb(i) - s_cb(i + 1))/(s_cb(i) - s_cb(i + 2)) - poly_coef_cbR_${XYZ}$ (i + 1, 1, 0) = (s_cb(i) - s_cb(i + 1))/(s_cb(i - 1) - s_cb(i + 1)) + + poly_coef_cbR_${XYZ}$ (i + 1, 0, 0) = (s_cb(i) - s_cb(i + 1))/ & + (s_cb(i) - s_cb(i + 2)) + poly_coef_cbR_${XYZ}$ (i + 1, 1, 0) = (s_cb(i) - s_cb(i + 1))/ & + (s_cb(i - 1) - s_cb(i + 1)) poly_coef_cbL_${XYZ}$ (i + 1, 0, 0) = -poly_coef_cbR_${XYZ}$ (i + 1, 0, 0) poly_coef_cbL_${XYZ}$ (i + 1, 1, 0) = -poly_coef_cbR_${XYZ}$ (i + 1, 1, 0) - ! Ideal (linear) weights - d_cbR_${XYZ}$ (0, i + 1) = (s_cb(i - 1) - s_cb(i + 1))/(s_cb(i - 1) - s_cb(i + 2)) - d_cbL_${XYZ}$ (0, i + 1) = (s_cb(i - 1) - s_cb(i))/(s_cb(i - 1) - s_cb(i + 2)) + d_cbR_${XYZ}$ (0, i + 1) = (s_cb(i - 1) - s_cb(i + 1))/ & + (s_cb(i - 1) - s_cb(i + 2)) + d_cbL_${XYZ}$ (0, i + 1) = (s_cb(i - 1) - s_cb(i))/ & + (s_cb(i - 1) - s_cb(i + 2)) d_cbR_${XYZ}$ (1, i + 1) = 1._wp - d_cbR_${XYZ}$ (0, i + 1) d_cbL_${XYZ}$ (1, i + 1) = 1._wp - d_cbL_${XYZ}$ (0, i + 1) - ! Smoothness indicator coefficients - beta_coef_${XYZ}$ (i + 1, 0, 0) = 4._wp*(s_cb(i) - s_cb(i + 1))**2._wp/(s_cb(i) - s_cb(i + 2))**2._wp - beta_coef_${XYZ}$ (i + 1, 1, 0) = 4._wp*(s_cb(i) - s_cb(i + 1))**2._wp/(s_cb(i - 1) - s_cb(i + 1))**2._wp + beta_coef_${XYZ}$ (i + 1, 0, 0) = 4._wp*(s_cb(i) - s_cb(i + 1))**2._wp/ & + (s_cb(i) - s_cb(i + 2))**2._wp + beta_coef_${XYZ}$ (i + 1, 1, 0) = 4._wp*(s_cb(i) - s_cb(i + 1))**2._wp/ & + (s_cb(i - 1) - s_cb(i + 1))**2._wp + end do - ! Modifying the ideal weights coefficients in the neighborhood of beginning and end Riemann state extrapolation - ! BC to avoid any contributions from outside of the physical domain during the WENO reconstruction + ! Modifying the ideal weights coefficients in the neighborhood + ! of beginning and end Riemann state extrapolation BC to avoid + ! any contributions from outside of the physical domain during + ! the WENO reconstruction if (null_weights) then if (bc_s%beg == BC_RIEMANN_EXTRAP) then d_cbR_${XYZ}$ (1, 0) = 0._wp; d_cbR_${XYZ}$ (0, 0) = 1._wp @@ -233,621 +272,351 @@ contains ! END: Computing WENO3 Coefficients ! Computing WENO5 Coefficients - else if (weno_order == 5) then + elseif (weno_order == 5) then + do i = is%beg - 1 + weno_polyn, is%end - 1 - weno_polyn - ! Polynomial reconstruction coefficients - poly_coef_cbR_${XYZ}$ (i + 1, 0, & - & 0) = ((s_cb(i) - s_cb(i + 1))*(s_cb(i + 1) - s_cb(i + 2)))/((s_cb(i) - s_cb(i & - & + 3))*(s_cb(i + 3) - s_cb(i + 1))) - poly_coef_cbR_${XYZ}$ (i + 1, 1, & - & 0) = ((s_cb(i - 1) - s_cb(i + 1))*(s_cb(i + 1) - s_cb(i)))/((s_cb(i - 1) & - & - s_cb(i + 2))*(s_cb(i + 2) - s_cb(i))) - poly_coef_cbR_${XYZ}$ (i + 1, 1, & - & 1) = ((s_cb(i) - s_cb(i + 1))*(s_cb(i + 1) - s_cb(i + 2)))/((s_cb(i - 1) & - & - s_cb(i + 1))*(s_cb(i - 1) - s_cb(i + 2))) - poly_coef_cbR_${XYZ}$ (i + 1, 2, & - & 1) = ((s_cb(i) - s_cb(i + 1))*(s_cb(i + 1) - s_cb(i - 1)))/((s_cb(i - 2) & - & - s_cb(i))*(s_cb(i - 2) - s_cb(i + 1))) - poly_coef_cbL_${XYZ}$ (i + 1, 0, & - & 0) = ((s_cb(i + 1) - s_cb(i))*(s_cb(i) - s_cb(i + 2)))/((s_cb(i) - s_cb(i + 3)) & - & *(s_cb(i + 3) - s_cb(i + 1))) - poly_coef_cbL_${XYZ}$ (i + 1, 1, & - & 0) = ((s_cb(i) - s_cb(i - 1))*(s_cb(i) - s_cb(i + 1)))/((s_cb(i - 1) - s_cb(i & - & + 2))*(s_cb(i) - s_cb(i + 2))) - poly_coef_cbL_${XYZ}$ (i + 1, 1, & - & 1) = ((s_cb(i + 1) - s_cb(i))*(s_cb(i) - s_cb(i + 2)))/((s_cb(i - 1) - s_cb(i & - & + 1))*(s_cb(i - 1) - s_cb(i + 2))) - poly_coef_cbL_${XYZ}$ (i + 1, 2, & - & 1) = ((s_cb(i - 1) - s_cb(i))*(s_cb(i) - s_cb(i + 1)))/((s_cb(i - 2) - s_cb(i)) & - & *(s_cb(i - 2) - s_cb(i + 1))) - - poly_coef_cbR_${XYZ}$ (i + 1, 0, & - & 1) = ((s_cb(i) - s_cb(i + 2)) + (s_cb(i + 1) - s_cb(i + 3)))/((s_cb(i) - s_cb(i & - & + 2))*(s_cb(i) - s_cb(i + 3)))*((s_cb(i) - s_cb(i + 1))) - poly_coef_cbR_${XYZ}$ (i + 1, 2, & - & 0) = ((s_cb(i - 2) - s_cb(i + 1)) + (s_cb(i - 1) - s_cb(i + 1)))/((s_cb(i - 1) & - & - s_cb(i + 1))*(s_cb(i + 1) - s_cb(i - 2)))*((s_cb(i + 1) - s_cb(i))) - poly_coef_cbL_${XYZ}$ (i + 1, 0, & - & 1) = ((s_cb(i) - s_cb(i + 2)) + (s_cb(i) - s_cb(i + 3)))/((s_cb(i) - s_cb(i + 2)) & - & *(s_cb(i) - s_cb(i + 3)))*((s_cb(i + 1) - s_cb(i))) - poly_coef_cbL_${XYZ}$ (i + 1, 2, & - & 0) = ((s_cb(i - 2) - s_cb(i)) + (s_cb(i - 1) - s_cb(i + 1)))/((s_cb(i - 2) & - & - s_cb(i + 1))*(s_cb(i + 1) - s_cb(i - 1)))*((s_cb(i) - s_cb(i + 1))) - - ! Ideal (linear) weights - d_cbR_${XYZ}$ (0, & - & i + 1) = ((s_cb(i - 2) - s_cb(i + 1))*(s_cb(i + 1) - s_cb(i - 1)))/((s_cb(i - 2) & - & - s_cb(i + 3))*(s_cb(i + 3) - s_cb(i - 1))) - d_cbR_${XYZ}$ (2, & - & i + 1) = ((s_cb(i + 1) - s_cb(i + 2))*(s_cb(i + 1) - s_cb(i + 3)))/((s_cb(i - 2) & - & - s_cb(i + 2))*(s_cb(i - 2) - s_cb(i + 3))) - d_cbL_${XYZ}$ (0, & - & i + 1) = ((s_cb(i - 2) - s_cb(i))*(s_cb(i) - s_cb(i - 1)))/((s_cb(i - 2) - s_cb(i + 3)) & - & *(s_cb(i + 3) - s_cb(i - 1))) - d_cbL_${XYZ}$ (2, & - & i + 1) = ((s_cb(i) - s_cb(i + 2))*(s_cb(i) - s_cb(i + 3)))/((s_cb(i - 2) - s_cb(i + 2)) & - & *(s_cb(i - 2) - s_cb(i + 3))) + + poly_coef_cbR_${XYZ}$ (i + 1, 0, 0) = & + ((s_cb(i) - s_cb(i + 1))*(s_cb(i + 1) - s_cb(i + 2)))/ & + ((s_cb(i) - s_cb(i + 3))*(s_cb(i + 3) - s_cb(i + 1))) + poly_coef_cbR_${XYZ}$ (i + 1, 1, 0) = & + ((s_cb(i - 1) - s_cb(i + 1))*(s_cb(i + 1) - s_cb(i)))/ & + ((s_cb(i - 1) - s_cb(i + 2))*(s_cb(i + 2) - s_cb(i))) + poly_coef_cbR_${XYZ}$ (i + 1, 1, 1) = & + ((s_cb(i) - s_cb(i + 1))*(s_cb(i + 1) - s_cb(i + 2)))/ & + ((s_cb(i - 1) - s_cb(i + 1))*(s_cb(i - 1) - s_cb(i + 2))) + poly_coef_cbR_${XYZ}$ (i + 1, 2, 1) = & + ((s_cb(i) - s_cb(i + 1))*(s_cb(i + 1) - s_cb(i - 1)))/ & + ((s_cb(i - 2) - s_cb(i))*(s_cb(i - 2) - s_cb(i + 1))) + poly_coef_cbL_${XYZ}$ (i + 1, 0, 0) = & + ((s_cb(i + 1) - s_cb(i))*(s_cb(i) - s_cb(i + 2)))/ & + ((s_cb(i) - s_cb(i + 3))*(s_cb(i + 3) - s_cb(i + 1))) + poly_coef_cbL_${XYZ}$ (i + 1, 1, 0) = & + ((s_cb(i) - s_cb(i - 1))*(s_cb(i) - s_cb(i + 1)))/ & + ((s_cb(i - 1) - s_cb(i + 2))*(s_cb(i) - s_cb(i + 2))) + poly_coef_cbL_${XYZ}$ (i + 1, 1, 1) = & + ((s_cb(i + 1) - s_cb(i))*(s_cb(i) - s_cb(i + 2)))/ & + ((s_cb(i - 1) - s_cb(i + 1))*(s_cb(i - 1) - s_cb(i + 2))) + poly_coef_cbL_${XYZ}$ (i + 1, 2, 1) = & + ((s_cb(i - 1) - s_cb(i))*(s_cb(i) - s_cb(i + 1)))/ & + ((s_cb(i - 2) - s_cb(i))*(s_cb(i - 2) - s_cb(i + 1))) + + poly_coef_cbR_${XYZ}$ (i + 1, 0, 1) = & + ((s_cb(i) - s_cb(i + 2)) + (s_cb(i + 1) - s_cb(i + 3)))/ & + ((s_cb(i) - s_cb(i + 2))*(s_cb(i) - s_cb(i + 3)))* & + ((s_cb(i) - s_cb(i + 1))) + poly_coef_cbR_${XYZ}$ (i + 1, 2, 0) = & + ((s_cb(i - 2) - s_cb(i + 1)) + (s_cb(i - 1) - s_cb(i + 1)))/ & + ((s_cb(i - 1) - s_cb(i + 1))*(s_cb(i + 1) - s_cb(i - 2)))* & + ((s_cb(i + 1) - s_cb(i))) + poly_coef_cbL_${XYZ}$ (i + 1, 0, 1) = & + ((s_cb(i) - s_cb(i + 2)) + (s_cb(i) - s_cb(i + 3)))/ & + ((s_cb(i) - s_cb(i + 2))*(s_cb(i) - s_cb(i + 3)))* & + ((s_cb(i + 1) - s_cb(i))) + poly_coef_cbL_${XYZ}$ (i + 1, 2, 0) = & + ((s_cb(i - 2) - s_cb(i)) + (s_cb(i - 1) - s_cb(i + 1)))/ & + ((s_cb(i - 2) - s_cb(i + 1))*(s_cb(i + 1) - s_cb(i - 1)))* & + ((s_cb(i) - s_cb(i + 1))) + + d_cbR_${XYZ}$ (0, i + 1) = & + ((s_cb(i - 2) - s_cb(i + 1))*(s_cb(i + 1) - s_cb(i - 1)))/ & + ((s_cb(i - 2) - s_cb(i + 3))*(s_cb(i + 3) - s_cb(i - 1))) + d_cbR_${XYZ}$ (2, i + 1) = & + ((s_cb(i + 1) - s_cb(i + 2))*(s_cb(i + 1) - s_cb(i + 3)))/ & + ((s_cb(i - 2) - s_cb(i + 2))*(s_cb(i - 2) - s_cb(i + 3))) + d_cbL_${XYZ}$ (0, i + 1) = & + ((s_cb(i - 2) - s_cb(i))*(s_cb(i) - s_cb(i - 1)))/ & + ((s_cb(i - 2) - s_cb(i + 3))*(s_cb(i + 3) - s_cb(i - 1))) + d_cbL_${XYZ}$ (2, i + 1) = & + ((s_cb(i) - s_cb(i + 2))*(s_cb(i) - s_cb(i + 3)))/ & + ((s_cb(i - 2) - s_cb(i + 2))*(s_cb(i - 2) - s_cb(i + 3))) d_cbR_${XYZ}$ (1, i + 1) = 1._wp - d_cbR_${XYZ}$ (0, i + 1) - d_cbR_${XYZ}$ (2, i + 1) d_cbL_${XYZ}$ (1, i + 1) = 1._wp - d_cbL_${XYZ}$ (0, i + 1) - d_cbL_${XYZ}$ (2, i + 1) - ! Smoothness indicator coefficients - beta_coef_${XYZ}$ (i + 1, 0, & - & 0) = 4._wp*(s_cb(i) - s_cb(i + 1))**2._wp*(10._wp*(s_cb(i + 1) - s_cb(i))**2._wp & - & + (s_cb(i + 1) - s_cb(i))*(s_cb(i + 2) - s_cb(i + 1)) + (s_cb(i + 2) - s_cb(i + 1)) & - & **2._wp)/((s_cb(i) - s_cb(i + 3))**2._wp*(s_cb(i + 1) - s_cb(i + 3))**2._wp) - - beta_coef_${XYZ}$ (i + 1, 0, & - & 1) = 4._wp*(s_cb(i) - s_cb(i + 1))**2._wp*(19._wp*(s_cb(i + 1) - s_cb(i))**2._wp & - & - (s_cb(i + 1) - s_cb(i))*(s_cb(i + 3) - s_cb(i + 1)) + 2._wp*(s_cb(i + 2) - s_cb(i)) & - & *((s_cb(i + 2) - s_cb(i)) + (s_cb(i + 3) - s_cb(i + 1))))/((s_cb(i) - s_cb(i + 2)) & - & *(s_cb(i) - s_cb(i + 3))**2._wp*(s_cb(i + 3) - s_cb(i + 1))) - - beta_coef_${XYZ}$ (i + 1, 0, & - & 2) = 4._wp*(s_cb(i) - s_cb(i + 1))**2._wp*(10._wp*(s_cb(i + 1) - s_cb(i))**2._wp & - & + (s_cb(i + 1) - s_cb(i))*((s_cb(i + 2) - s_cb(i)) + (s_cb(i + 3) - s_cb(i + 1))) & - & + ((s_cb(i + 2) - s_cb(i)) + (s_cb(i + 3) - s_cb(i + 1)))**2._wp)/((s_cb(i) - s_cb(i & - & + 2))**2._wp*(s_cb(i) - s_cb(i + 3))**2._wp) - - beta_coef_${XYZ}$ (i + 1, 1, & - & 0) = 4._wp*(s_cb(i) - s_cb(i + 1))**2._wp*(10._wp*(s_cb(i + 1) - s_cb(i))**2._wp & - & + (s_cb(i) - s_cb(i - 1))**2._wp + (s_cb(i) - s_cb(i - 1))*(s_cb(i + 1) - s_cb(i))) & - & /((s_cb(i - 1) - s_cb(i + 2))**2._wp*(s_cb(i) - s_cb(i + 2))**2._wp) - - beta_coef_${XYZ}$ (i + 1, 1, & - & 1) = 4._wp*(s_cb(i) - s_cb(i + 1))**2._wp*((s_cb(i) - s_cb(i + 1))*((s_cb(i) & - & - s_cb(i - 1)) + 20._wp*(s_cb(i + 1) - s_cb(i))) + (2._wp*(s_cb(i) - s_cb(i - 1)) & - & + (s_cb(i + 1) - s_cb(i)))*(s_cb(i + 2) - s_cb(i)))/((s_cb(i + 1) - s_cb(i - 1)) & - & *(s_cb(i - 1) - s_cb(i + 2))**2._wp*(s_cb(i + 2) - s_cb(i))) - - beta_coef_${XYZ}$ (i + 1, 1, & - & 2) = 4._wp*(s_cb(i) - s_cb(i + 1))**2._wp*(10._wp*(s_cb(i + 1) - s_cb(i))**2._wp & - & + (s_cb(i + 1) - s_cb(i))*(s_cb(i + 2) - s_cb(i + 1)) + (s_cb(i + 2) - s_cb(i + 1)) & - & **2._wp)/((s_cb(i - 1) - s_cb(i + 1))**2._wp*(s_cb(i - 1) - s_cb(i + 2))**2._wp) - - beta_coef_${XYZ}$ (i + 1, 2, & - & 0) = 4._wp*(s_cb(i) - s_cb(i + 1))**2._wp*(12._wp*(s_cb(i + 1) - s_cb(i))**2._wp & - & + ((s_cb(i) - s_cb(i - 2)) + (s_cb(i) - s_cb(i - 1)))**2._wp + 3._wp*((s_cb(i) & - & - s_cb(i - 2)) + (s_cb(i) - s_cb(i - 1)))*(s_cb(i + 1) - s_cb(i)))/((s_cb(i - 2) & - & - s_cb(i + 1))**2._wp*(s_cb(i - 1) - s_cb(i + 1))**2._wp) - - beta_coef_${XYZ}$ (i + 1, 2, & - & 1) = 4._wp*(s_cb(i) - s_cb(i + 1))**2._wp*(19._wp*(s_cb(i + 1) - s_cb(i))**2._wp & - & + ((s_cb(i) - s_cb(i - 2))*(s_cb(i) - s_cb(i + 1))) + 2._wp*(s_cb(i + 1) - s_cb(i & - & - 1))*((s_cb(i) - s_cb(i - 2)) + (s_cb(i + 1) - s_cb(i - 1))))/((s_cb(i - 2) & - & - s_cb(i))*(s_cb(i - 2) - s_cb(i + 1))**2._wp*(s_cb(i + 1) - s_cb(i - 1))) - - beta_coef_${XYZ}$ (i + 1, 2, & - & 2) = 4._wp*(s_cb(i) - s_cb(i + 1))**2._wp*(10._wp*(s_cb(i + 1) - s_cb(i))**2._wp & - & + (s_cb(i) - s_cb(i - 1))**2._wp + (s_cb(i) - s_cb(i - 1))*(s_cb(i + 1) - s_cb(i))) & - & /((s_cb(i - 2) - s_cb(i))**2._wp*(s_cb(i - 2) - s_cb(i + 1))**2._wp) + beta_coef_${XYZ}$ (i + 1, 0, 0) = & + 4._wp*(s_cb(i) - s_cb(i + 1))**2._wp*(10._wp*(s_cb(i + 1) - & + s_cb(i))**2._wp + (s_cb(i + 1) - s_cb(i))*(s_cb(i + 2) - & + s_cb(i + 1)) + (s_cb(i + 2) - s_cb(i + 1))**2._wp)/((s_cb(i) - & + s_cb(i + 3))**2._wp*(s_cb(i + 1) - s_cb(i + 3))**2._wp) + + beta_coef_${XYZ}$ (i + 1, 0, 1) = & + 4._wp*(s_cb(i) - s_cb(i + 1))**2._wp*(19._wp*(s_cb(i + 1) - & + s_cb(i))**2._wp - (s_cb(i + 1) - s_cb(i))*(s_cb(i + 3) - & + s_cb(i + 1)) + 2._wp*(s_cb(i + 2) - s_cb(i))*((s_cb(i + 2) - & + s_cb(i)) + (s_cb(i + 3) - s_cb(i + 1))))/((s_cb(i) - & + s_cb(i + 2))*(s_cb(i) - s_cb(i + 3))**2._wp*(s_cb(i + 3) - & + s_cb(i + 1))) + + beta_coef_${XYZ}$ (i + 1, 0, 2) = & + 4._wp*(s_cb(i) - s_cb(i + 1))**2._wp*(10._wp*(s_cb(i + 1) - & + s_cb(i))**2._wp + (s_cb(i + 1) - s_cb(i))*((s_cb(i + 2) - & + s_cb(i)) + (s_cb(i + 3) - s_cb(i + 1))) + ((s_cb(i + 2) - & + s_cb(i)) + (s_cb(i + 3) - s_cb(i + 1)))**2._wp)/((s_cb(i) - & + s_cb(i + 2))**2._wp*(s_cb(i) - s_cb(i + 3))**2._wp) + + beta_coef_${XYZ}$ (i + 1, 1, 0) = & + 4._wp*(s_cb(i) - s_cb(i + 1))**2._wp*(10._wp*(s_cb(i + 1) - & + s_cb(i))**2._wp + (s_cb(i) - s_cb(i - 1))**2._wp + (s_cb(i) - & + s_cb(i - 1))*(s_cb(i + 1) - s_cb(i)))/((s_cb(i - 1) - & + s_cb(i + 2))**2._wp*(s_cb(i) - s_cb(i + 2))**2._wp) + + beta_coef_${XYZ}$ (i + 1, 1, 1) = & + 4._wp*(s_cb(i) - s_cb(i + 1))**2._wp*((s_cb(i) - & + s_cb(i + 1))*((s_cb(i) - s_cb(i - 1)) + 20._wp*(s_cb(i + 1) - & + s_cb(i))) + (2._wp*(s_cb(i) - s_cb(i - 1)) + (s_cb(i + 1) - & + s_cb(i)))*(s_cb(i + 2) - s_cb(i)))/((s_cb(i + 1) - & + s_cb(i - 1))*(s_cb(i - 1) - s_cb(i + 2))**2._wp*(s_cb(i + 2) - & + s_cb(i))) + + beta_coef_${XYZ}$ (i + 1, 1, 2) = & + 4._wp*(s_cb(i) - s_cb(i + 1))**2._wp*(10._wp*(s_cb(i + 1) - & + s_cb(i))**2._wp + (s_cb(i + 1) - s_cb(i))*(s_cb(i + 2) - & + s_cb(i + 1)) + (s_cb(i + 2) - s_cb(i + 1))**2._wp)/ & + ((s_cb(i - 1) - s_cb(i + 1))**2._wp*(s_cb(i - 1) - & + s_cb(i + 2))**2._wp) + + beta_coef_${XYZ}$ (i + 1, 2, 0) = & + 4._wp*(s_cb(i) - s_cb(i + 1))**2._wp*(12._wp*(s_cb(i + 1) - & + s_cb(i))**2._wp + ((s_cb(i) - s_cb(i - 2)) + (s_cb(i) - & + s_cb(i - 1)))**2._wp + 3._wp*((s_cb(i) - s_cb(i - 2)) + & + (s_cb(i) - s_cb(i - 1)))*(s_cb(i + 1) - s_cb(i)))/ & + ((s_cb(i - 2) - s_cb(i + 1))**2._wp*(s_cb(i - 1) - & + s_cb(i + 1))**2._wp) + + beta_coef_${XYZ}$ (i + 1, 2, 1) = & + 4._wp*(s_cb(i) - s_cb(i + 1))**2._wp*(19._wp*(s_cb(i + 1) - & + s_cb(i))**2._wp + ((s_cb(i) - s_cb(i - 2))*(s_cb(i) - & + s_cb(i + 1))) + 2._wp*(s_cb(i + 1) - s_cb(i - 1))*((s_cb(i) - & + s_cb(i - 2)) + (s_cb(i + 1) - s_cb(i - 1))))/((s_cb(i - 2) - & + s_cb(i))*(s_cb(i - 2) - s_cb(i + 1))**2._wp*(s_cb(i + 1) - & + s_cb(i - 1))) + + beta_coef_${XYZ}$ (i + 1, 2, 2) = & + 4._wp*(s_cb(i) - s_cb(i + 1))**2._wp*(10._wp*(s_cb(i + 1) - & + s_cb(i))**2._wp + (s_cb(i) - s_cb(i - 1))**2._wp + (s_cb(i) - & + s_cb(i - 1))*(s_cb(i + 1) - s_cb(i)))/((s_cb(i - 2) - & + s_cb(i))**2._wp*(s_cb(i - 2) - s_cb(i + 1))**2._wp) + end do - ! Modifying the ideal weights coefficients in the neighborhood of beginning and end Riemann state extrapolation - ! BC to avoid any contributions from outside of the physical domain during the WENO reconstruction + ! Modifying the ideal weights coefficients in the neighborhood + ! of beginning and end Riemann state extrapolation BC to avoid + ! any contributions from outside of the physical domain during + ! the WENO reconstruction if (null_weights) then if (bc_s%beg == BC_RIEMANN_EXTRAP) then - d_cbR_${XYZ}$ (1:2,0) = 0._wp; d_cbR_${XYZ}$ (0, 0) = 1._wp - d_cbL_${XYZ}$ (1:2,0) = 0._wp; d_cbL_${XYZ}$ (0, 0) = 1._wp - d_cbR_${XYZ}$ (2, 1) = 0._wp; d_cbR_${XYZ}$ (:,1) = d_cbR_${XYZ}$ (:,1)/sum(d_cbR_${XYZ}$ (:,1)) - d_cbL_${XYZ}$ (2, 1) = 0._wp; d_cbL_${XYZ}$ (:,1) = d_cbL_${XYZ}$ (:,1)/sum(d_cbL_${XYZ}$ (:,1)) + d_cbR_${XYZ}$ (1:2, 0) = 0._wp; d_cbR_${XYZ}$ (0, 0) = 1._wp + d_cbL_${XYZ}$ (1:2, 0) = 0._wp; d_cbL_${XYZ}$ (0, 0) = 1._wp + d_cbR_${XYZ}$ (2, 1) = 0._wp; d_cbR_${XYZ}$ (:, 1) = d_cbR_${XYZ}$ (:, 1)/sum(d_cbR_${XYZ}$ (:, 1)) + d_cbL_${XYZ}$ (2, 1) = 0._wp; d_cbL_${XYZ}$ (:, 1) = d_cbL_${XYZ}$ (:, 1)/sum(d_cbL_${XYZ}$ (:, 1)) end if if (bc_s%end == BC_RIEMANN_EXTRAP) then - d_cbR_${XYZ}$ (0, s - 1) = 0._wp; d_cbR_${XYZ}$ (:,s - 1) = d_cbR_${XYZ}$ (:, & - & s - 1)/sum(d_cbR_${XYZ}$ (:,s - 1)) - d_cbL_${XYZ}$ (0, s - 1) = 0._wp; d_cbL_${XYZ}$ (:,s - 1) = d_cbL_${XYZ}$ (:, & - & s - 1)/sum(d_cbL_${XYZ}$ (:,s - 1)) - d_cbR_${XYZ}$ (0:1,s) = 0._wp; d_cbR_${XYZ}$ (2, s) = 1._wp - d_cbL_${XYZ}$ (0:1,s) = 0._wp; d_cbL_${XYZ}$ (2, s) = 1._wp + d_cbR_${XYZ}$ (0, s - 1) = 0._wp; d_cbR_${XYZ}$ (:, s - 1) = d_cbR_${XYZ}$ (:, s - 1)/sum(d_cbR_${XYZ}$ (:, s - 1)) + d_cbL_${XYZ}$ (0, s - 1) = 0._wp; d_cbL_${XYZ}$ (:, s - 1) = d_cbL_${XYZ}$ (:, s - 1)/sum(d_cbL_${XYZ}$ (:, s - 1)) + d_cbR_${XYZ}$ (0:1, s) = 0._wp; d_cbR_${XYZ}$ (2, s) = 1._wp + d_cbL_${XYZ}$ (0:1, s) = 0._wp; d_cbL_${XYZ}$ (2, s) = 1._wp end if end if - else ! WENO7 + + else ! WENO7 + if (.not. teno) then + do i = is%beg - 1 + weno_polyn, is%end - 1 - weno_polyn - ! Reference: Shu (1997) "Essentially Non-Oscillatory and Weighted Essentially Non-Oscillatory Schemes - ! for Hyperbolic Conservation Laws" Equation 2.20: Polynomial Coefficients (poly_coef_cb) Equation 2.61: - ! Smoothness Indicators (beta_coef) To reduce computational cost, we leverage the fact that all - ! polynomial coefficients in a stencil sum to 1 and compute the polynomial coefficients (poly_coef_cb) - ! for the cell value differences (dvd) instead of the values themselves. The computation of coefficients - ! is further simplified by using grid spacing (y or w) rather than the grid locations (s_cb) directly. - ! Ideal weights (d_cb) are obtained by comparing the grid location coefficients of the polynomial - ! coefficients. The smoothness indicators (beta_coef) are calculated through numerical differentiation - ! and integration of each cross term of the polynomial coefficients, using the cell value differences - ! (dvd) instead of the values themselves. While the polynomial coefficients sum to 1, the derivative of - ! 1 is 0, which means it does not create additional cross terms in the smoothness indicators. - - w = s_cb(i - 3:i + 4) - s_cb(i) ! Offset using s_cb(i) to reduce floating point error - d_cbR_${XYZ}$ (0, & - & i + 1) = ((w(5) - w(6))*(w(5) - w(7))*(w(5) - w(8)))/((w(1) - w(6))*(w(1) - w(7)) & - & *(w(1) - w(8))) - d_cbR_${XYZ}$ (1, & - & i + 1) = ((w(1) - w(5))*(w(5) - w(7))*(w(5) - w(8))*(w(1)*w(2) - w(1)*w(6) - w(1) & - & *w(7) - w(2)*w(6) - w(1)*w(8) - w(2)*w(7) - w(2)*w(8) + w(6)*w(7) + w(6)*w(8) + w(7) & - & *w(8) + w(1)**2 + w(2)**2))/((w(1) - w(6))*(w(1) - w(7))*(w(1) - w(8))*(w(2) - w(7)) & - & *(w(2) - w(8))) - d_cbR_${XYZ}$ (2, & - & i + 1) = ((w(1) - w(5))*(w(2) - w(5))*(w(5) - w(8))*(w(1)*w(2) + w(1)*w(3) + w(2) & - & *w(3) - w(1)*w(7) - w(1)*w(8) - w(2)*w(7) - w(2)*w(8) - w(3)*w(7) - w(3)*w(8) + w(7) & - & *w(8) + w(7)**2 + w(8)**2))/((w(1) - w(7))*(w(1) - w(8))*(w(2) - w(7))*(w(2) - w(8)) & - & *(w(3) - w(8))) - d_cbR_${XYZ}$ (3, & - & i + 1) = ((w(1) - w(5))*(w(2) - w(5))*(w(3) - w(5)))/((w(1) - w(8))*(w(2) - w(8)) & - & *(w(3) - w(8))) + + ! Reference: Shu (1997) "Essentially Non-Oscillatory and Weighted Essentially Non-Oscillatory Schemes for Hyperbolic Conservation Laws" + ! Equation 2.20: Polynomial Coefficients (poly_coef_cb) + ! Equation 2.61: Smoothness Indicators (beta_coef) + ! To reduce computational cost, we leverage the fact that all polynomial coefficients in a stencil sum to 1 + ! and compute the polynomial coefficients (poly_coef_cb) for the cell value differences (dvd) instead of the values themselves. + ! The computation of coefficients is further simplified by using grid spacing (y or w) rather than the grid locations (s_cb) directly. + ! Ideal weights (d_cb) are obtained by comparing the grid location coefficients of the polynomial coefficients. + ! The smoothness indicators (beta_coef) are calculated through numerical differentiation and integration of each cross term of the polynomial coefficients, + ! using the cell value differences (dvd) instead of the values themselves. + ! While the polynomial coefficients sum to 1, the derivative of 1 is 0, which means it does not create additional cross terms in the smoothness indicators. + + w = s_cb(i - 3:i + 4) - s_cb(i) ! Offset using s_cb(i) to reduce floating point error + d_cbR_${XYZ}$ (0, i + 1) = ((w(5) - w(6))*(w(5) - w(7))*(w(5) - w(8)))/((w(1) - w(6))*(w(1) - w(7))*(w(1) - w(8))) !& + d_cbR_${XYZ}$ (1, i + 1) = ((w(1) - w(5))*(w(5) - w(7))*(w(5) - w(8))*(w(1)*w(2) - w(1)*w(6) - w(1)*w(7) - w(2)*w(6) - w(1)*w(8) - w(2)*w(7) - w(2)*w(8) + w(6)*w(7) + w(6)*w(8) + w(7)*w(8) + w(1)**2 + w(2)**2))/((w(1) - w(6))*(w(1) - w(7))*(w(1) - w(8))*(w(2) - w(7))*(w(2) - w(8))) !& + d_cbR_${XYZ}$ (2, i + 1) = ((w(1) - w(5))*(w(2) - w(5))*(w(5) - w(8))*(w(1)*w(2) + w(1)*w(3) + w(2)*w(3) - w(1)*w(7) - w(1)*w(8) - w(2)*w(7) - w(2)*w(8) - w(3)*w(7) - w(3)*w(8) + w(7)*w(8) + w(7)**2 + w(8)**2))/((w(1) - w(7))*(w(1) - w(8))*(w(2) - w(7))*(w(2) - w(8))*(w(3) - w(8))) !& + d_cbR_${XYZ}$ (3, i + 1) = ((w(1) - w(5))*(w(2) - w(5))*(w(3) - w(5)))/((w(1) - w(8))*(w(2) - w(8))*(w(3) - w(8))) !& w = s_cb(i + 4:i - 3:-1) - s_cb(i) - d_cbL_${XYZ}$ (0, & - & i + 1) = ((w(1) - w(5))*(w(2) - w(5))*(w(3) - w(5)))/((w(1) - w(8))*(w(2) - w(8)) & - & *(w(3) - w(8))) - d_cbL_${XYZ}$ (1, & - & i + 1) = ((w(1) - w(5))*(w(2) - w(5))*(w(5) - w(8))*(w(1)*w(2) + w(1)*w(3) + w(2) & - & *w(3) - w(1)*w(7) - w(1)*w(8) - w(2)*w(7) - w(2)*w(8) - w(3)*w(7) - w(3)*w(8) + w(7) & - & *w(8) + w(7)**2 + w(8)**2))/((w(1) - w(7))*(w(1) - w(8))*(w(2) - w(7))*(w(2) - w(8)) & - & *(w(3) - w(8))) - d_cbL_${XYZ}$ (2, & - & i + 1) = ((w(1) - w(5))*(w(5) - w(7))*(w(5) - w(8))*(w(1)*w(2) - w(1)*w(6) - w(1) & - & *w(7) - w(2)*w(6) - w(1)*w(8) - w(2)*w(7) - w(2)*w(8) + w(6)*w(7) + w(6)*w(8) + w(7) & - & *w(8) + w(1)**2 + w(2)**2))/((w(1) - w(6))*(w(1) - w(7))*(w(1) - w(8))*(w(2) - w(7)) & - & *(w(2) - w(8))) - d_cbL_${XYZ}$ (3, & - & i + 1) = ((w(5) - w(6))*(w(5) - w(7))*(w(5) - w(8)))/((w(1) - w(6))*(w(1) - w(7)) & - & *(w(1) - w(8))) + d_cbL_${XYZ}$ (0, i + 1) = ((w(1) - w(5))*(w(2) - w(5))*(w(3) - w(5)))/((w(1) - w(8))*(w(2) - w(8))*(w(3) - w(8))) !& + d_cbL_${XYZ}$ (1, i + 1) = ((w(1) - w(5))*(w(2) - w(5))*(w(5) - w(8))*(w(1)*w(2) + w(1)*w(3) + w(2)*w(3) - w(1)*w(7) - w(1)*w(8) - w(2)*w(7) - w(2)*w(8) - w(3)*w(7) - w(3)*w(8) + w(7)*w(8) + w(7)**2 + w(8)**2))/((w(1) - w(7))*(w(1) - w(8))*(w(2) - w(7))*(w(2) - w(8))*(w(3) - w(8))) !& + d_cbL_${XYZ}$ (2, i + 1) = ((w(1) - w(5))*(w(5) - w(7))*(w(5) - w(8))*(w(1)*w(2) - w(1)*w(6) - w(1)*w(7) - w(2)*w(6) - w(1)*w(8) - w(2)*w(7) - w(2)*w(8) + w(6)*w(7) + w(6)*w(8) + w(7)*w(8) + w(1)**2 + w(2)**2))/((w(1) - w(6))*(w(1) - w(7))*(w(1) - w(8))*(w(2) - w(7))*(w(2) - w(8))) !& + d_cbL_${XYZ}$ (3, i + 1) = ((w(5) - w(6))*(w(5) - w(7))*(w(5) - w(8)))/((w(1) - w(6))*(w(1) - w(7))*(w(1) - w(8))) !& ! Note: Left has the reversed order of both points and coefficients compared to the right y = s_cb(i + 1:i + 4) - s_cb(i:i + 3) - poly_coef_cbR_${XYZ}$ (i + 1, 0, & - & 0) = (y(1)*y(2)*(y(2) + y(3)))/((y(3) + y(4))*(y(2) + y(3) + y(4))*(y(1) & - & + y(2) + y(3) + y(4))) - poly_coef_cbR_${XYZ}$ (i + 1, 0, & - & 1) = -(y(1)*y(2)*(3*y(2)**2 + 6*y(2)*y(3) + 3*y(2)*y(4) + 2*y(1)*y(2) & - & + 3*y(3)**2 + 3*y(3)*y(4) + 2*y(1)*y(3) + y(4)**2 + y(1)*y(4)))/((y(2) + y(3) & - & )*(y(1) + y(2) + y(3))*(y(2) + y(3) + y(4))*(y(1) + y(2) + y(3) + y(4))) - poly_coef_cbR_${XYZ}$ (i + 1, 0, & - & 2) = (y(1)*(y(1)**2 + 3*y(1)*y(2) + 2*y(1)*y(3) + y(4)*y(1) + 3*y(2)**2 & - & + 4*y(2)*y(3) + 2*y(4)*y(2) + y(3)**2 + y(4)*y(3)))/((y(1) + y(2))*(y(1) & - & + y(2) + y(3))*(y(1) + y(2) + y(3) + y(4))) + poly_coef_cbR_${XYZ}$ (i + 1, 0, 0) = (y(1)*y(2)*(y(2) + y(3)))/((y(3) + y(4))*(y(2) + y(3) + y(4))*(y(1) + y(2) + y(3) + y(4))) !& + poly_coef_cbR_${XYZ}$ (i + 1, 0, 1) = -(y(1)*y(2)*(3*y(2)**2 + 6*y(2)*y(3) + 3*y(2)*y(4) + 2*y(1)*y(2) + 3*y(3)**2 + 3*y(3)*y(4) + 2*y(1)*y(3) + y(4)**2 + y(1)*y(4)))/((y(2) + y(3))*(y(1) + y(2) + y(3))*(y(2) + y(3) + y(4))*(y(1) + y(2) + y(3) + y(4))) !& + poly_coef_cbR_${XYZ}$ (i + 1, 0, 2) = (y(1)*(y(1)**2 + 3*y(1)*y(2) + 2*y(1)*y(3) + y(4)*y(1) + 3*y(2)**2 + 4*y(2)*y(3) + 2*y(4)*y(2) + y(3)**2 + y(4)*y(3)))/((y(1) + y(2))*(y(1) + y(2) + y(3))*(y(1) + y(2) + y(3) + y(4))) !& y = s_cb(i:i + 3) - s_cb(i - 1:i + 2) - poly_coef_cbR_${XYZ}$ (i + 1, 1, & - & 0) = -(y(2)*y(3)*(y(1) + y(2)))/((y(3) + y(4))*(y(2) + y(3) + y(4))*(y(1) & - & + y(2) + y(3) + y(4))) - poly_coef_cbR_${XYZ}$ (i + 1, 1, & - & 1) = (y(2)*(y(1) + y(2))*(y(2)**2 + 4*y(2)*y(3) + 2*y(2)*y(4) + y(1)*y(2) & - & + 3*y(3)**2 + 3*y(3)*y(4) + 2*y(1)*y(3) + y(4)**2 + y(1)*y(4)))/((y(2) + y(3) & - & )*(y(1) + y(2) + y(3))*(y(2) + y(3) + y(4))*(y(1) + y(2) + y(3) + y(4))) - poly_coef_cbR_${XYZ}$ (i + 1, 1, & - & 2) = (y(2)*y(3)*(y(3) + y(4)))/((y(1) + y(2))*(y(1) + y(2) + y(3))*(y(1) & - & + y(2) + y(3) + y(4))) + poly_coef_cbR_${XYZ}$ (i + 1, 1, 0) = -(y(2)*y(3)*(y(1) + y(2)))/((y(3) + y(4))*(y(2) + y(3) + y(4))*(y(1) + y(2) + y(3) + y(4))) !& + poly_coef_cbR_${XYZ}$ (i + 1, 1, 1) = (y(2)*(y(1) + y(2))*(y(2)**2 + 4*y(2)*y(3) + 2*y(2)*y(4) + y(1)*y(2) + 3*y(3)**2 + 3*y(3)*y(4) + 2*y(1)*y(3) + y(4)**2 + y(1)*y(4)))/((y(2) + y(3))*(y(1) + y(2) + y(3))*(y(2) + y(3) + y(4))*(y(1) + y(2) + y(3) + y(4))) !& + poly_coef_cbR_${XYZ}$ (i + 1, 1, 2) = (y(2)*y(3)*(y(3) + y(4)))/((y(1) + y(2))*(y(1) + y(2) + y(3))*(y(1) + y(2) + y(3) + y(4))) !& y = s_cb(i - 1:i + 2) - s_cb(i - 2:i + 1) - poly_coef_cbR_${XYZ}$ (i + 1, 2, & - & 0) = (y(3)*(y(2) + y(3))*(y(1) + y(2) + y(3)))/((y(3) + y(4))*(y(2) + y(3) & - & + y(4))*(y(1) + y(2) + y(3) + y(4))) - poly_coef_cbR_${XYZ}$ (i + 1, 2, & - & 1) = (y(3)*y(4)*(y(1)**2 + 3*y(1)*y(2) + 3*y(1)*y(3) + y(4)*y(1) + 3*y(2)**2 & - & + 6*y(2)*y(3) + 2*y(4)*y(2) + 3*y(3)**2 + 2*y(4)*y(3)))/((y(2) + y(3))*(y(1) & - & + y(2) + y(3))*(y(2) + y(3) + y(4))*(y(1) + y(2) + y(3) + y(4))) - poly_coef_cbR_${XYZ}$ (i + 1, 2, & - & 2) = -(y(3)*y(4)*(y(2) + y(3)))/((y(1) + y(2))*(y(1) + y(2) + y(3))*(y(1) & - & + y(2) + y(3) + y(4))) + poly_coef_cbR_${XYZ}$ (i + 1, 2, 0) = (y(3)*(y(2) + y(3))*(y(1) + y(2) + y(3)))/((y(3) + y(4))*(y(2) + y(3) + y(4))*(y(1) + y(2) + y(3) + y(4))) !& + poly_coef_cbR_${XYZ}$ (i + 1, 2, 1) = (y(3)*y(4)*(y(1)**2 + 3*y(1)*y(2) + 3*y(1)*y(3) + y(4)*y(1) + 3*y(2)**2 + 6*y(2)*y(3) + 2*y(4)*y(2) + 3*y(3)**2 + 2*y(4)*y(3)))/((y(2) + y(3))*(y(1) + y(2) + y(3))*(y(2) + y(3) + y(4))*(y(1) + y(2) + y(3) + y(4))) !& + poly_coef_cbR_${XYZ}$ (i + 1, 2, 2) = -(y(3)*y(4)*(y(2) + y(3)))/((y(1) + y(2))*(y(1) + y(2) + y(3))*(y(1) + y(2) + y(3) + y(4))) !& y = s_cb(i - 2:i + 1) - s_cb(i - 3:i) - poly_coef_cbR_${XYZ}$ (i + 1, 3, & - & 0) = (y(4)*(y(2)**2 + 4*y(2)*y(3) + 4*y(2)*y(4) + y(1)*y(2) + 3*y(3)**2 & - & + 6*y(3)*y(4) + 2*y(1)*y(3) + 3*y(4)**2 + 2*y(1)*y(4)))/((y(3) + y(4))*(y(2) & - & + y(3) + y(4))*(y(1) + y(2) + y(3) + y(4))) - poly_coef_cbR_${XYZ}$ (i + 1, 3, & - & 1) = -(y(4)*(y(3) + y(4))*(y(1)**2 + 3*y(1)*y(2) + 3*y(1)*y(3) + 2*y(1)*y(4) & - & + 3*y(2)**2 + 6*y(2)*y(3) + 4*y(2)*y(4) + 3*y(3)**2 + 4*y(3)*y(4) + y(4)**2)) & - & /((y(2) + y(3))*(y(1) + y(2) + y(3))*(y(2) + y(3) + y(4))*(y(1) + y(2) + y(3) & - & + y(4))) - poly_coef_cbR_${XYZ}$ (i + 1, 3, & - & 2) = (y(4)*(y(3) + y(4))*(y(2) + y(3) + y(4)))/((y(1) + y(2))*(y(1) + y(2) & - & + y(3))*(y(1) + y(2) + y(3) + y(4))) + poly_coef_cbR_${XYZ}$ (i + 1, 3, 0) = (y(4)*(y(2)**2 + 4*y(2)*y(3) + 4*y(2)*y(4) + y(1)*y(2) + 3*y(3)**2 + 6*y(3)*y(4) + 2*y(1)*y(3) + 3*y(4)**2 + 2*y(1)*y(4)))/((y(3) + y(4))*(y(2) + y(3) + y(4))*(y(1) + y(2) + y(3) + y(4))) !& + poly_coef_cbR_${XYZ}$ (i + 1, 3, 1) = -(y(4)*(y(3) + y(4))*(y(1)**2 + 3*y(1)*y(2) + 3*y(1)*y(3) + 2*y(1)*y(4) + 3*y(2)**2 + 6*y(2)*y(3) + 4*y(2)*y(4) + 3*y(3)**2 + 4*y(3)*y(4) + y(4)**2))/((y(2) + y(3))*(y(1) + y(2) + y(3))*(y(2) + y(3) + y(4))*(y(1) + y(2) + y(3) + y(4))) !& + poly_coef_cbR_${XYZ}$ (i + 1, 3, 2) = (y(4)*(y(3) + y(4))*(y(2) + y(3) + y(4)))/((y(1) + y(2))*(y(1) + y(2) + y(3))*(y(1) + y(2) + y(3) + y(4))) !& y = s_cb(i + 1:i - 2:-1) - s_cb(i:i - 3:-1) - poly_coef_cbL_${XYZ}$ (i + 1, 3, & - & 2) = (y(1)*y(2)*(y(2) + y(3)))/((y(3) + y(4))*(y(2) + y(3) + y(4))*(y(1) & - & + y(2) + y(3) + y(4))) - poly_coef_cbL_${XYZ}$ (i + 1, 3, & - & 1) = -(y(1)*y(2)*(3*y(2)**2 + 6*y(2)*y(3) + 3*y(2)*y(4) + 2*y(1)*y(2) & - & + 3*y(3)**2 + 3*y(3)*y(4) + 2*y(1)*y(3) + y(4)**2 + y(1)*y(4)))/((y(2) + y(3) & - & )*(y(1) + y(2) + y(3))*(y(2) + y(3) + y(4))*(y(1) + y(2) + y(3) + y(4))) - poly_coef_cbL_${XYZ}$ (i + 1, 3, & - & 0) = (y(1)*(y(1)**2 + 3*y(1)*y(2) + 2*y(1)*y(3) + y(4)*y(1) + 3*y(2)**2 & - & + 4*y(2)*y(3) + 2*y(4)*y(2) + y(3)**2 + y(4)*y(3)))/((y(1) + y(2))*(y(1) & - & + y(2) + y(3))*(y(1) + y(2) + y(3) + y(4))) + poly_coef_cbL_${XYZ}$ (i + 1, 3, 2) = (y(1)*y(2)*(y(2) + y(3)))/((y(3) + y(4))*(y(2) + y(3) + y(4))*(y(1) + y(2) + y(3) + y(4))) !& + poly_coef_cbL_${XYZ}$ (i + 1, 3, 1) = -(y(1)*y(2)*(3*y(2)**2 + 6*y(2)*y(3) + 3*y(2)*y(4) + 2*y(1)*y(2) + 3*y(3)**2 + 3*y(3)*y(4) + 2*y(1)*y(3) + y(4)**2 + y(1)*y(4)))/((y(2) + y(3))*(y(1) + y(2) + y(3))*(y(2) + y(3) + y(4))*(y(1) + y(2) + y(3) + y(4))) !& + poly_coef_cbL_${XYZ}$ (i + 1, 3, 0) = (y(1)*(y(1)**2 + 3*y(1)*y(2) + 2*y(1)*y(3) + y(4)*y(1) + 3*y(2)**2 + 4*y(2)*y(3) + 2*y(4)*y(2) + y(3)**2 + y(4)*y(3)))/((y(1) + y(2))*(y(1) + y(2) + y(3))*(y(1) + y(2) + y(3) + y(4))) !& y = s_cb(i + 2:i - 1:-1) - s_cb(i + 1:i - 2:-1) - poly_coef_cbL_${XYZ}$ (i + 1, 2, & - & 2) = -(y(2)*y(3)*(y(1) + y(2)))/((y(3) + y(4))*(y(2) + y(3) + y(4))*(y(1) & - & + y(2) + y(3) + y(4))) - poly_coef_cbL_${XYZ}$ (i + 1, 2, & - & 1) = (y(2)*(y(1) + y(2))*(y(2)**2 + 4*y(2)*y(3) + 2*y(2)*y(4) + y(1)*y(2) & - & + 3*y(3)**2 + 3*y(3)*y(4) + 2*y(1)*y(3) + y(4)**2 + y(1)*y(4)))/((y(2) + y(3) & - & )*(y(1) + y(2) + y(3))*(y(2) + y(3) + y(4))*(y(1) + y(2) + y(3) + y(4))) - poly_coef_cbL_${XYZ}$ (i + 1, 2, & - & 0) = (y(2)*y(3)*(y(3) + y(4)))/((y(1) + y(2))*(y(1) + y(2) + y(3))*(y(1) & - & + y(2) + y(3) + y(4))) + poly_coef_cbL_${XYZ}$ (i + 1, 2, 2) = -(y(2)*y(3)*(y(1) + y(2)))/((y(3) + y(4))*(y(2) + y(3) + y(4))*(y(1) + y(2) + y(3) + y(4))) !& + poly_coef_cbL_${XYZ}$ (i + 1, 2, 1) = (y(2)*(y(1) + y(2))*(y(2)**2 + 4*y(2)*y(3) + 2*y(2)*y(4) + y(1)*y(2) + 3*y(3)**2 + 3*y(3)*y(4) + 2*y(1)*y(3) + y(4)**2 + y(1)*y(4)))/((y(2) + y(3))*(y(1) + y(2) + y(3))*(y(2) + y(3) + y(4))*(y(1) + y(2) + y(3) + y(4))) !& + poly_coef_cbL_${XYZ}$ (i + 1, 2, 0) = (y(2)*y(3)*(y(3) + y(4)))/((y(1) + y(2))*(y(1) + y(2) + y(3))*(y(1) + y(2) + y(3) + y(4))) !& y = s_cb(i + 3:i:-1) - s_cb(i + 2:i - 1:-1) - poly_coef_cbL_${XYZ}$ (i + 1, 1, & - & 2) = (y(3)*(y(2) + y(3))*(y(1) + y(2) + y(3)))/((y(3) + y(4))*(y(2) + y(3) & - & + y(4))*(y(1) + y(2) + y(3) + y(4))) - poly_coef_cbL_${XYZ}$ (i + 1, 1, & - & 1) = (y(3)*y(4)*(y(1)**2 + 3*y(1)*y(2) + 3*y(1)*y(3) + y(4)*y(1) + 3*y(2)**2 & - & + 6*y(2)*y(3) + 2*y(4)*y(2) + 3*y(3)**2 + 2*y(4)*y(3)))/((y(2) + y(3))*(y(1) & - & + y(2) + y(3))*(y(2) + y(3) + y(4))*(y(1) + y(2) + y(3) + y(4))) - poly_coef_cbL_${XYZ}$ (i + 1, 1, & - & 0) = -(y(3)*y(4)*(y(2) + y(3)))/((y(1) + y(2))*(y(1) + y(2) + y(3))*(y(1) & - & + y(2) + y(3) + y(4))) + poly_coef_cbL_${XYZ}$ (i + 1, 1, 2) = (y(3)*(y(2) + y(3))*(y(1) + y(2) + y(3)))/((y(3) + y(4))*(y(2) + y(3) + y(4))*(y(1) + y(2) + y(3) + y(4))) !& + poly_coef_cbL_${XYZ}$ (i + 1, 1, 1) = (y(3)*y(4)*(y(1)**2 + 3*y(1)*y(2) + 3*y(1)*y(3) + y(4)*y(1) + 3*y(2)**2 + 6*y(2)*y(3) + 2*y(4)*y(2) + 3*y(3)**2 + 2*y(4)*y(3)))/((y(2) + y(3))*(y(1) + y(2) + y(3))*(y(2) + y(3) + y(4))*(y(1) + y(2) + y(3) + y(4))) !& + poly_coef_cbL_${XYZ}$ (i + 1, 1, 0) = -(y(3)*y(4)*(y(2) + y(3)))/((y(1) + y(2))*(y(1) + y(2) + y(3))*(y(1) + y(2) + y(3) + y(4))) !& y = s_cb(i + 4:i + 1:-1) - s_cb(i + 3:i:-1) - poly_coef_cbL_${XYZ}$ (i + 1, 0, & - & 2) = (y(4)*(y(2)**2 + 4*y(2)*y(3) + 4*y(2)*y(4) + y(1)*y(2) + 3*y(3)**2 & - & + 6*y(3)*y(4) + 2*y(1)*y(3) + 3*y(4)**2 + 2*y(1)*y(4)))/((y(3) + y(4))*(y(2) & - & + y(3) + y(4))*(y(1) + y(2) + y(3) + y(4))) - poly_coef_cbL_${XYZ}$ (i + 1, 0, & - & 1) = -(y(4)*(y(3) + y(4))*(y(1)**2 + 3*y(1)*y(2) + 3*y(1)*y(3) + 2*y(1)*y(4) & - & + 3*y(2)**2 + 6*y(2)*y(3) + 4*y(2)*y(4) + 3*y(3)**2 + 4*y(3)*y(4) + y(4)**2)) & - & /((y(2) + y(3))*(y(1) + y(2) + y(3))*(y(2) + y(3) + y(4))*(y(1) + y(2) + y(3) & - & + y(4))) - poly_coef_cbL_${XYZ}$ (i + 1, 0, & - & 0) = (y(4)*(y(3) + y(4))*(y(2) + y(3) + y(4)))/((y(1) + y(2))*(y(1) + y(2) & - & + y(3))*(y(1) + y(2) + y(3) + y(4))) - - poly_coef_cbL_${XYZ}$ (i + 1,:,:) = -poly_coef_cbL_${XYZ}$ (i + 1,:,:) + poly_coef_cbL_${XYZ}$ (i + 1, 0, 2) = (y(4)*(y(2)**2 + 4*y(2)*y(3) + 4*y(2)*y(4) + y(1)*y(2) + 3*y(3)**2 + 6*y(3)*y(4) + 2*y(1)*y(3) + 3*y(4)**2 + 2*y(1)*y(4)))/((y(3) + y(4))*(y(2) + y(3) + y(4))*(y(1) + y(2) + y(3) + y(4))) !& + poly_coef_cbL_${XYZ}$ (i + 1, 0, 1) = -(y(4)*(y(3) + y(4))*(y(1)**2 + 3*y(1)*y(2) + 3*y(1)*y(3) + 2*y(1)*y(4) + 3*y(2)**2 + 6*y(2)*y(3) + 4*y(2)*y(4) + 3*y(3)**2 + 4*y(3)*y(4) + y(4)**2))/((y(2) + y(3))*(y(1) + y(2) + y(3))*(y(2) + y(3) + y(4))*(y(1) + y(2) + y(3) + y(4))) !& + poly_coef_cbL_${XYZ}$ (i + 1, 0, 0) = (y(4)*(y(3) + y(4))*(y(2) + y(3) + y(4)))/((y(1) + y(2))*(y(1) + y(2) + y(3))*(y(1) + y(2) + y(3) + y(4))) !& + + poly_coef_cbL_${XYZ}$ (i + 1, :, :) = -poly_coef_cbL_${XYZ}$ (i + 1, :, :) ! Note: negative sign as the direction of taking the difference (dvd) is reversed y = s_cb(i - 2:i + 1) - s_cb(i - 3:i) - beta_coef_${XYZ}$ (i + 1, 3, & - & 0) = (4*y(4)**2*(5*y(1)**2*y(2)**2 + 20*y(1)**2*y(2)*y(3) + 15*y(1)**2*y(2)*y(4) & - & + 20*y(1)**2*y(3)**2 + 30*y(1)**2*y(3)*y(4) + 60*y(1)**2*y(4)**2 + 10*y(1)*y(2) & - & **3 + 60*y(1)*y(2)**2*y(3) + 45*y(1)*y(2)**2*y(4) + 110*y(1)*y(2)*y(3)**2 & - & + 165*y(1)*y(2)*y(3)*y(4) + 260*y(1)*y(2)*y(4)**2 + 60*y(1)*y(3)**3 + 135*y(1) & - & *y(3)**2*y(4) + 400*y(1)*y(3)*y(4)**2 + 225*y(1)*y(4)**3 + 5*y(2)**4 + 40*y(2) & - & **3*y(3) + 30*y(2)**3*y(4) + 110*y(2)**2*y(3)**2 + 165*y(2)**2*y(3)*y(4) & - & + 260*y(2)**2*y(4)**2 + 120*y(2)*y(3)**3 + 270*y(2)*y(3)**2*y(4) + 800*y(2)*y(3) & - & *y(4)**2 + 450*y(2)*y(4)**3 + 45*y(3)**4 + 135*y(3)**3*y(4) + 600*y(3)**2*y(4) & - & **2 + 675*y(3)*y(4)**3 + 996*y(4)**4))/(5*(y(3) + y(4))**2*(y(2) + y(3) + y(4)) & - & **2*(y(1) + y(2) + y(3) + y(4))**2) - beta_coef_${XYZ}$ (i + 1, 3, & - & 1) = -(4*y(4)**2*(10*y(1)**3*y(2)*y(3) + 5*y(1)**3*y(2)*y(4) + 20*y(1)**3*y(3) & - & **2 + 25*y(1)**3*y(3)*y(4) + 105*y(1)**3*y(4)**2 + 40*y(1)**2*y(2)**2*y(3) & - & + 20*y(1)**2*y(2)**2*y(4) + 130*y(1)**2*y(2)*y(3)**2 + 155*y(1)**2*y(2)*y(3)*y(4) & - & + 535*y(1)**2*y(2)*y(4)**2 + 90*y(1)**2*y(3)**3 + 165*y(1)**2*y(3)**2*y(4) & - & + 790*y(1)**2*y(3)*y(4)**2 + 415*y(1)**2*y(4)**3 + 60*y(1)*y(2)**3*y(3) + 30*y(1) & - & *y(2)**3*y(4) + 270*y(1)*y(2)**2*y(3)**2 + 315*y(1)*y(2)**2*y(3)*y(4) + 975*y(1) & - & *y(2)**2*y(4)**2 + 360*y(1)*y(2)*y(3)**3 + 645*y(1)*y(2)*y(3)**2*y(4) + 2850*y(1) & - & *y(2)*y(3)*y(4)**2 + 1460*y(1)*y(2)*y(4)**3 + 150*y(1)*y(3)**4 + 360*y(1)*y(3) & - & **3*y(4) + 2000*y(1)*y(3)**2*y(4)**2 + 2005*y(1)*y(3)*y(4)**3 + 2077*y(1)*y(4) & - & **4 + 30*y(2)**4*y(3) + 15*y(2)**4*y(4) + 180*y(2)**3*y(3)**2 + 210*y(2)**3*y(3) & - & *y(4) + 650*y(2)**3*y(4)**2 + 360*y(2)**2*y(3)**3 + 645*y(2)**2*y(3)**2*y(4) & - & + 2850*y(2)**2*y(3)*y(4)**2 + 1460*y(2)**2*y(4)**3 + 300*y(2)*y(3)**4 + 720*y(2) & - & *y(3)**3*y(4) + 4000*y(2)*y(3)**2*y(4)**2 + 4010*y(2)*y(3)*y(4)**3 + 4154*y(2) & - & *y(4)**4 + 90*y(3)**5 + 270*y(3)**4*y(4) + 1800*y(3)**3*y(4)**2 + 2655*y(3) & - & **2*y(4)**3 + 4464*y(3)*y(4)**4 + 1767*y(4)**5))/(5*(y(2) + y(3))*(y(3) + y(4)) & - & *(y(1) + y(2) + y(3))*(y(2) + y(3) + y(4))**2*(y(1) + y(2) + y(3) + y(4))**2) - beta_coef_${XYZ}$ (i + 1, 3, & - & 2) = (4*y(4)**2*(10*y(2)**3*y(3) + 5*y(2)**3*y(4) + 50*y(2)**2*y(3)**2 + 60*y(2) & - & **2*y(3)*y(4) + 10*y(1)*y(2)**2*y(3) + 215*y(2)**2*y(4)**2 + 5*y(1)*y(2)**2*y(4) & - & + 70*y(2)*y(3)**3 + 130*y(2)*y(3)**2*y(4) + 30*y(1)*y(2)*y(3)**2 + 775*y(2)*y(3) & - & *y(4)**2 + 35*y(1)*y(2)*y(3)*y(4) + 415*y(2)*y(4)**3 + 110*y(1)*y(2)*y(4)**2 & - & + 30*y(3)**4 + 75*y(3)**3*y(4) + 20*y(1)*y(3)**3 + 665*y(3)**2*y(4)**2 + 35*y(1) & - & *y(3)**2*y(4) + 725*y(3)*y(4)**3 + 220*y(1)*y(3)*y(4)**2 + 1767*y(4)**4 & - & + 105*y(1)*y(4)**3))/(5*(y(1) + y(2))*(y(3) + y(4))*(y(1) + y(2) + y(3))*(y(2) & - & + y(3) + y(4))*(y(1) + y(2) + y(3) + y(4))**2) - beta_coef_${XYZ}$ (i + 1, 3, & - & 3) = (4*y(4)**2*(5*y(1)**4*y(3)**2 + 5*y(1)**4*y(3)*y(4) + 50*y(1)**4*y(4)**2 & - & + 30*y(1)**3*y(2)*y(3)**2 + 30*y(1)**3*y(2)*y(3)*y(4) + 300*y(1)**3*y(2)*y(4)**2 & - & + 30*y(1)**3*y(3)**3 + 45*y(1)**3*y(3)**2*y(4) + 415*y(1)**3*y(3)*y(4)**2 & - & + 200*y(1)**3*y(4)**3 + 75*y(1)**2*y(2)**2*y(3)**2 + 75*y(1)**2*y(2)**2*y(3)*y(4) & - & + 750*y(1)**2*y(2)**2*y(4)**2 + 150*y(1)**2*y(2)*y(3)**3 + 225*y(1)**2*y(2)*y(3) & - & **2*y(4) + 2075*y(1)**2*y(2)*y(3)*y(4)**2 + 1000*y(1)**2*y(2)*y(4)**3 + 75*y(1) & - & **2*y(3)**4 + 150*y(1)**2*y(3)**3*y(4) + 1390*y(1)**2*y(3)**2*y(4)**2 + 1315*y(1) & - & **2*y(3)*y(4)**3 + 1081*y(1)**2*y(4)**4 + 90*y(1)*y(2)**3*y(3)**2 + 90*y(1)*y(2) & - & **3*y(3)*y(4) + 900*y(1)*y(2)**3*y(4)**2 + 270*y(1)*y(2)**2*y(3)**3 + 405*y(1) & - & *y(2)**2*y(3)**2*y(4) + 3735*y(1)*y(2)**2*y(3)*y(4)**2 + 1800*y(1)*y(2)**2*y(4) & - & **3 + 270*y(1)*y(2)*y(3)**4 + 540*y(1)*y(2)*y(3)**3*y(4) + 5025*y(1)*y(2)*y(3) & - & **2*y(4)**2 + 4755*y(1)*y(2)*y(3)*y(4)**3 + 4224*y(1)*y(2)*y(4)**4 + 90*y(1)*y(3) & - & **5 + 225*y(1)*y(3)**4*y(4) + 2190*y(1)*y(3)**3*y(4)**2 + 3060*y(1)*y(3)**2*y(4) & - & **3 + 4529*y(1)*y(3)*y(4)**4 + 1762*y(1)*y(4)**5 + 45*y(2)**4*y(3)**2 + 45*y(2) & - & **4*y(3)*y(4) + 450*y(2)**4*y(4)**2 + 180*y(2)**3*y(3)**3 + 270*y(2)**3*y(3) & - & **2*y(4) + 2490*y(2)**3*y(3)*y(4)**2 + 1200*y(2)**3*y(4)**3 + 270*y(2)**2*y(3) & - & **4 + 540*y(2)**2*y(3)**3*y(4) + 5025*y(2)**2*y(3)**2*y(4)**2 + 4755*y(2)**2*y(3) & - & *y(4)**3 + 4224*y(2)**2*y(4)**4 + 180*y(2)*y(3)**5 + 450*y(2)*y(3)**4*y(4) & - & + 4380*y(2)*y(3)**3*y(4)**2 + 6120*y(2)*y(3)**2*y(4)**3 + 9058*y(2)*y(3)*y(4)**4 & - & + 3524*y(2)*y(4)**5 + 45*y(3)**6 + 135*y(3)**5*y(4) + 1395*y(3)**4*y(4)**2 & - & + 2565*y(3)**3*y(4)**3 + 4884*y(3)**2*y(4)**4 + 3624*y(3)*y(4)**5 + 831*y(4)**6)) & - & /(5*(y(2) + y(3))**2*(y(1) + y(2) + y(3))**2*(y(2) + y(3) + y(4))**2*(y(1) + y(2) & - & + y(3) + y(4))**2) - beta_coef_${XYZ}$ (i + 1, 3, & - & 4) = -(4*y(4)**2*(10*y(1)**2*y(2)*y(3)**2 + 10*y(1)**2*y(2)*y(3)*y(4) + 100*y(1) & - & **2*y(2)*y(4)**2 + 10*y(1)**2*y(3)**3 + 15*y(1)**2*y(3)**2*y(4) + 205*y(1) & - & **2*y(3)*y(4)**2 + 100*y(1)**2*y(4)**3 + 30*y(1)*y(2)**2*y(3)**2 + 30*y(1)*y(2) & - & **2*y(3)*y(4) + 300*y(1)*y(2)**2*y(4)**2 + 60*y(1)*y(2)*y(3)**3 + 90*y(1)*y(2) & - & *y(3)**2*y(4) + 1030*y(1)*y(2)*y(3)*y(4)**2 + 500*y(1)*y(2)*y(4)**3 + 30*y(1) & - & *y(3)**4 + 60*y(1)*y(3)**3*y(4) + 835*y(1)*y(3)**2*y(4)**2 + 805*y(1)*y(3)*y(4) & - & **3 + 1762*y(1)*y(4)**4 + 30*y(2)**3*y(3)**2 + 30*y(2)**3*y(3)*y(4) + 300*y(2) & - & **3*y(4)**2 + 90*y(2)**2*y(3)**3 + 135*y(2)**2*y(3)**2*y(4) + 1445*y(2)**2*y(3) & - & *y(4)**2 + 700*y(2)**2*y(4)**3 + 90*y(2)*y(3)**4 + 180*y(2)*y(3)**3*y(4) & - & + 2205*y(2)*y(3)**2*y(4)**2 + 2115*y(2)*y(3)*y(4)**3 + 3624*y(2)*y(4)**4 & - & + 30*y(3)**5 + 75*y(3)**4*y(4) + 1060*y(3)**3*y(4)**2 + 1515*y(3)**2*y(4)**3 & - & + 3824*y(3)*y(4)**4 + 1662*y(4)**5))/(5*(y(1) + y(2))*(y(2) + y(3))*(y(1) + y(2) & - & + y(3))**2*(y(2) + y(3) + y(4))*(y(1) + y(2) + y(3) + y(4))**2) - beta_coef_${XYZ}$ (i + 1, 3, & - & 5) = (4*y(4)**2*(5*y(2)**2*y(3)**2 + 5*y(2)**2*y(3)*y(4) + 50*y(2)**2*y(4)**2 & - & + 10*y(2)*y(3)**3 + 15*y(2)*y(3)**2*y(4) + 205*y(2)*y(3)*y(4)**2 + 100*y(2)*y(4) & - & **3 + 5*y(3)**4 + 10*y(3)**3*y(4) + 205*y(3)**2*y(4)**2 + 200*y(3)*y(4)**3 & - & + 831*y(4)**4))/(5*(y(1) + y(2))**2*(y(1) + y(2) + y(3))**2*(y(1) + y(2) + y(3) & - & + y(4))**2) + beta_coef_${XYZ}$ (i + 1, 3, 0) = (4*y(4)**2*(5*y(1)**2*y(2)**2 + 20*y(1)**2*y(2)*y(3) + 15*y(1)**2*y(2)*y(4) + 20*y(1)**2*y(3)**2 + 30*y(1)**2*y(3)*y(4) + 60*y(1)**2*y(4)**2 + 10*y(1)*y(2)**3 + 60*y(1)*y(2)**2*y(3) + 45*y(1)*y(2)**2*y(4) + 110*y(1)*y(2)*y(3)**2 + 165*y(1)*y(2)*y(3)*y(4) & !& + + 260*y(1)*y(2)*y(4)**2 + 60*y(1)*y(3)**3 + 135*y(1)*y(3)**2*y(4) + 400*y(1)*y(3)*y(4)**2 + 225*y(1)*y(4)**3 + 5*y(2)**4 + 40*y(2)**3*y(3) + 30*y(2)**3*y(4) + 110*y(2)**2*y(3)**2 + 165*y(2)**2*y(3)*y(4) + 260*y(2)**2*y(4)**2 + 120*y(2)*y(3)**3 & !& + + 270*y(2)*y(3)**2*y(4) + 800*y(2)*y(3)*y(4)**2 + 450*y(2)*y(4)**3 + 45*y(3)**4 + 135*y(3)**3*y(4) + 600*y(3)**2*y(4)**2 + 675*y(3)*y(4)**3 + 996*y(4)**4))/(5*(y(3) + y(4))**2*(y(2) + y(3) + y(4))**2*(y(1) + y(2) + y(3) + y(4))**2) !& + beta_coef_${XYZ}$ (i + 1, 3, 1) = -(4*y(4)**2*(10*y(1)**3*y(2)*y(3) + 5*y(1)**3*y(2)*y(4) + 20*y(1)**3*y(3)**2 + 25*y(1)**3*y(3)*y(4) + 105*y(1)**3*y(4)**2 + 40*y(1)**2*y(2)**2*y(3) + 20*y(1)**2*y(2)**2*y(4) + 130*y(1)**2*y(2)*y(3)**2 + 155*y(1)**2*y(2)*y(3)*y(4) + 535*y(1)**2*y(2)*y(4)**2 & !& + + 90*y(1)**2*y(3)**3 + 165*y(1)**2*y(3)**2*y(4) + 790*y(1)**2*y(3)*y(4)**2 + 415*y(1)**2*y(4)**3 + 60*y(1)*y(2)**3*y(3) + 30*y(1)*y(2)**3*y(4) + 270*y(1)*y(2)**2*y(3)**2 + 315*y(1)*y(2)**2*y(3)*y(4) + 975*y(1)*y(2)**2*y(4)**2 + 360*y(1)*y(2)*y(3)**3 & !& + + 645*y(1)*y(2)*y(3)**2*y(4) + 2850*y(1)*y(2)*y(3)*y(4)**2 + 1460*y(1)*y(2)*y(4)**3 + 150*y(1)*y(3)**4 + 360*y(1)*y(3)**3*y(4) + 2000*y(1)*y(3)**2*y(4)**2 + 2005*y(1)*y(3)*y(4)**3 + 2077*y(1)*y(4)**4 + 30*y(2)**4*y(3) + 15*y(2)**4*y(4) + 180*y(2)**3*y(3)**2 & !& + + 210*y(2)**3*y(3)*y(4) + 650*y(2)**3*y(4)**2 + 360*y(2)**2*y(3)**3 + 645*y(2)**2*y(3)**2*y(4) + 2850*y(2)**2*y(3)*y(4)**2 + 1460*y(2)**2*y(4)**3 + 300*y(2)*y(3)**4 + 720*y(2)*y(3)**3*y(4) + 4000*y(2)*y(3)**2*y(4)**2 + 4010*y(2)*y(3)*y(4)**3 + 4154*y(2)*y(4)**4 & !& + + 90*y(3)**5 + 270*y(3)**4*y(4) + 1800*y(3)**3*y(4)**2 + 2655*y(3)**2*y(4)**3 + 4464*y(3)*y(4)**4 + 1767*y(4)**5))/(5*(y(2) + y(3))*(y(3) + y(4))*(y(1) + y(2) + y(3))*(y(2) + y(3) + y(4))**2*(y(1) + y(2) + y(3) + y(4))**2) !& + beta_coef_${XYZ}$ (i + 1, 3, 2) = (4*y(4)**2*(10*y(2)**3*y(3) + 5*y(2)**3*y(4) + 50*y(2)**2*y(3)**2 + 60*y(2)**2*y(3)*y(4) + 10*y(1)*y(2)**2*y(3) + 215*y(2)**2*y(4)**2 + 5*y(1)*y(2)**2*y(4) + 70*y(2)*y(3)**3 + 130*y(2)*y(3)**2*y(4) + 30*y(1)*y(2)*y(3)**2 + 775*y(2)*y(3)*y(4)**2 & !& + + 35*y(1)*y(2)*y(3)*y(4) + 415*y(2)*y(4)**3 + 110*y(1)*y(2)*y(4)**2 + 30*y(3)**4 + 75*y(3)**3*y(4) + 20*y(1)*y(3)**3 + 665*y(3)**2*y(4)**2 + 35*y(1)*y(3)**2*y(4) + 725*y(3)*y(4)**3 + 220*y(1)*y(3)*y(4)**2 + 1767*y(4)**4 + 105*y(1)*y(4)**3)) & !& + /(5*(y(1) + y(2))*(y(3) + y(4))*(y(1) + y(2) + y(3))*(y(2) + y(3) + y(4))*(y(1) + y(2) + y(3) + y(4))**2) !& + beta_coef_${XYZ}$ (i + 1, 3, 3) = (4*y(4)**2*(5*y(1)**4*y(3)**2 + 5*y(1)**4*y(3)*y(4) + 50*y(1)**4*y(4)**2 + 30*y(1)**3*y(2)*y(3)**2 + 30*y(1)**3*y(2)*y(3)*y(4) + 300*y(1)**3*y(2)*y(4)**2 + 30*y(1)**3*y(3)**3 + 45*y(1)**3*y(3)**2*y(4) + 415*y(1)**3*y(3)*y(4)**2 + 200*y(1)**3*y(4)**3 & !& + + 75*y(1)**2*y(2)**2*y(3)**2 + 75*y(1)**2*y(2)**2*y(3)*y(4) + 750*y(1)**2*y(2)**2*y(4)**2 + 150*y(1)**2*y(2)*y(3)**3 + 225*y(1)**2*y(2)*y(3)**2*y(4) + 2075*y(1)**2*y(2)*y(3)*y(4)**2 + 1000*y(1)**2*y(2)*y(4)**3 + 75*y(1)**2*y(3)**4 + 150*y(1)**2*y(3)**3*y(4) & !& + + 1390*y(1)**2*y(3)**2*y(4)**2 + 1315*y(1)**2*y(3)*y(4)**3 + 1081*y(1)**2*y(4)**4 + 90*y(1)*y(2)**3*y(3)**2 + 90*y(1)*y(2)**3*y(3)*y(4) + 900*y(1)*y(2)**3*y(4)**2 + 270*y(1)*y(2)**2*y(3)**3 + 405*y(1)*y(2)**2*y(3)**2*y(4) + 3735*y(1)*y(2)**2*y(3)*y(4)**2 & !& + + 1800*y(1)*y(2)**2*y(4)**3 + 270*y(1)*y(2)*y(3)**4 + 540*y(1)*y(2)*y(3)**3*y(4) + 5025*y(1)*y(2)*y(3)**2*y(4)**2 + 4755*y(1)*y(2)*y(3)*y(4)**3 + 4224*y(1)*y(2)*y(4)**4 + 90*y(1)*y(3)**5 + 225*y(1)*y(3)**4*y(4) + 2190*y(1)*y(3)**3*y(4)**2 + 3060*y(1)*y(3)**2*y(4)**3 & !& + + 4529*y(1)*y(3)*y(4)**4 + 1762*y(1)*y(4)**5 + 45*y(2)**4*y(3)**2 + 45*y(2)**4*y(3)*y(4) + 450*y(2)**4*y(4)**2 + 180*y(2)**3*y(3)**3 + 270*y(2)**3*y(3)**2*y(4) + 2490*y(2)**3*y(3)*y(4)**2 + 1200*y(2)**3*y(4)**3 + 270*y(2)**2*y(3)**4 + 540*y(2)**2*y(3)**3*y(4) & !& + + 5025*y(2)**2*y(3)**2*y(4)**2 + 4755*y(2)**2*y(3)*y(4)**3 + 4224*y(2)**2*y(4)**4 + 180*y(2)*y(3)**5 + 450*y(2)*y(3)**4*y(4) + 4380*y(2)*y(3)**3*y(4)**2 + 6120*y(2)*y(3)**2*y(4)**3 + 9058*y(2)*y(3)*y(4)**4 + 3524*y(2)*y(4)**5 + 45*y(3)**6 + 135*y(3)**5*y(4) & !& + + 1395*y(3)**4*y(4)**2 + 2565*y(3)**3*y(4)**3 + 4884*y(3)**2*y(4)**4 + 3624*y(3)*y(4)**5 + 831*y(4)**6))/(5*(y(2) + y(3))**2*(y(1) + y(2) + y(3))**2*(y(2) + y(3) + y(4))**2*(y(1) + y(2) + y(3) + y(4))**2) !& + beta_coef_${XYZ}$ (i + 1, 3, 4) = -(4*y(4)**2*(10*y(1)**2*y(2)*y(3)**2 + 10*y(1)**2*y(2)*y(3)*y(4) + 100*y(1)**2*y(2)*y(4)**2 + 10*y(1)**2*y(3)**3 + 15*y(1)**2*y(3)**2*y(4) + 205*y(1)**2*y(3)*y(4)**2 + 100*y(1)**2*y(4)**3 + 30*y(1)*y(2)**2*y(3)**2 + 30*y(1)*y(2)**2*y(3)*y(4) & !& + + 300*y(1)*y(2)**2*y(4)**2 + 60*y(1)*y(2)*y(3)**3 + 90*y(1)*y(2)*y(3)**2*y(4) + 1030*y(1)*y(2)*y(3)*y(4)**2 + 500*y(1)*y(2)*y(4)**3 + 30*y(1)*y(3)**4 + 60*y(1)*y(3)**3*y(4) + 835*y(1)*y(3)**2*y(4)**2 + 805*y(1)*y(3)*y(4)**3 + 1762*y(1)*y(4)**4 + 30*y(2)**3*y(3)**2 & !& + + 30*y(2)**3*y(3)*y(4) + 300*y(2)**3*y(4)**2 + 90*y(2)**2*y(3)**3 + 135*y(2)**2*y(3)**2*y(4) + 1445*y(2)**2*y(3)*y(4)**2 + 700*y(2)**2*y(4)**3 + 90*y(2)*y(3)**4 + 180*y(2)*y(3)**3*y(4) + 2205*y(2)*y(3)**2*y(4)**2 + 2115*y(2)*y(3)*y(4)**3 + 3624*y(2)*y(4)**4 & !& + + 30*y(3)**5 + 75*y(3)**4*y(4) + 1060*y(3)**3*y(4)**2 + 1515*y(3)**2*y(4)**3 + 3824*y(3)*y(4)**4 + 1662*y(4)**5))/(5*(y(1) + y(2))*(y(2) + y(3))*(y(1) + y(2) + y(3))**2*(y(2) + y(3) + y(4))*(y(1) + y(2) + y(3) + y(4))**2) !& + beta_coef_${XYZ}$ (i + 1, 3, 5) = (4*y(4)**2*(5*y(2)**2*y(3)**2 + 5*y(2)**2*y(3)*y(4) + 50*y(2)**2*y(4)**2 + 10*y(2)*y(3)**3 + 15*y(2)*y(3)**2*y(4) + 205*y(2)*y(3)*y(4)**2 + 100*y(2)*y(4)**3 + 5*y(3)**4 + 10*y(3)**3*y(4) + 205*y(3)**2*y(4)**2 + 200*y(3)*y(4)**3 + 831*y(4)**4))/(5*(y(1) & !& + + y(2))**2*(y(1) + y(2) + y(3))**2*(y(1) + y(2) + y(3) + y(4))**2) !& y = s_cb(i - 1:i + 2) - s_cb(i - 2:i + 1) - beta_coef_${XYZ}$ (i + 1, 2, & - & 0) = (4*y(3)**2*(5*y(1)**2*y(2)**2 + 5*y(1)**2*y(2)*y(3) + 50*y(1)**2*y(3)**2 & - & + 10*y(1)*y(2)**3 + 15*y(1)*y(2)**2*y(3) + 205*y(1)*y(2)*y(3)**2 + 100*y(1)*y(3) & - & **3 + 5*y(2)**4 + 10*y(2)**3*y(3) + 205*y(2)**2*y(3)**2 + 200*y(2)*y(3)**3 & - & + 831*y(3)**4))/(5*(y(3) + y(4))**2*(y(2) + y(3) + y(4))**2*(y(1) + y(2) + y(3) & - & + y(4))**2) - beta_coef_${XYZ}$ (i + 1, 2, & - & 1) = (4*y(3)**2*(5*y(1)**3*y(2)*y(3) + 10*y(1)**3*y(2)*y(4) - 95*y(1)**3*y(3)**2 & - & + 5*y(1)**3*y(3)*y(4) + 20*y(1)**2*y(2)**2*y(3) + 40*y(1)**2*y(2)**2*y(4) & - & - 465*y(1)**2*y(2)*y(3)**2 + 55*y(1)**2*y(2)*y(3)*y(4) + 10*y(1)**2*y(2)*y(4)**2 & - & - 285*y(1)**2*y(3)**3 + 20*y(1)**2*y(3)**2*y(4) + 5*y(1)**2*y(3)*y(4)**2 & - & + 30*y(1)*y(2)**3*y(3) + 60*y(1)*y(2)**3*y(4) - 825*y(1)*y(2)**2*y(3)**2 & - & + 135*y(1)*y(2)**2*y(3)*y(4) + 30*y(1)*y(2)**2*y(4)**2 - 1040*y(1)*y(2)*y(3)**3 & - & + 100*y(1)*y(2)*y(3)**2*y(4) + 35*y(1)*y(2)*y(3)*y(4)**2 - 1847*y(1)*y(3)**4 & - & + 125*y(1)*y(3)**3*y(4) + 110*y(1)*y(3)**2*y(4)**2 + 15*y(2)**4*y(3) + 30*y(2) & - & **4*y(4) - 550*y(2)**3*y(3)**2 + 90*y(2)**3*y(3)*y(4) + 20*y(2)**3*y(4)**2 & - & - 1040*y(2)**2*y(3)**3 + 100*y(2)**2*y(3)**2*y(4) + 35*y(2)**2*y(3)*y(4)**2 & - & - 3694*y(2)*y(3)**4 + 250*y(2)*y(3)**3*y(4) + 220*y(2)*y(3)**2*y(4)**2 & - & - 3219*y(3)**5 - 1452*y(3)**4*y(4) + 105*y(3)**3*y(4)**2))/(5*(y(2) + y(3))*(y(3) & - & + y(4))*(y(1) + y(2) + y(3))*(y(2) + y(3) + y(4))**2*(y(1) + y(2) + y(3) + y(4)) & - & **2) - beta_coef_${XYZ}$ (i + 1, 2, & - & 2) = -(4*y(3)**2*(5*y(2)**3*y(3) - 95*y(2)*y(3)**3 - 190*y(2)**2*y(3)**2 & - & + 10*y(2)**3*y(4) + 100*y(3)**3*y(4) - 1562*y(3)**4 - 95*y(1)*y(2)*y(3)**2 & - & + 5*y(1)*y(2)**2*y(3) + 10*y(1)*y(2)**2*y(4) + 100*y(1)*y(3)**2*y(4) + 205*y(2) & - & *y(3)**2*y(4) + 15*y(2)**2*y(3)*y(4) + 10*y(1)*y(2)*y(3)*y(4)))/(5*(y(1) + y(2)) & - & *(y(3) + y(4))*(y(1) + y(2) + y(3))*(y(2) + y(3) + y(4))*(y(1) + y(2) + y(3) & - & + y(4))**2) - beta_coef_${XYZ}$ (i + 1, 2, & - & 3) = (4*y(3)**2*(50*y(1)**4*y(3)**2 + 5*y(1)**4*y(3)*y(4) + 5*y(1)**4*y(4)**2 & - & + 300*y(1)**3*y(2)*y(3)**2 + 30*y(1)**3*y(2)*y(3)*y(4) + 30*y(1)**3*y(2)*y(4)**2 & - & + 200*y(1)**3*y(3)**3 + 25*y(1)**3*y(3)**2*y(4) + 35*y(1)**3*y(3)*y(4)**2 & - & + 10*y(1)**3*y(4)**3 + 750*y(1)**2*y(2)**2*y(3)**2 + 75*y(1)**2*y(2)**2*y(3)*y(4) & - & + 75*y(1)**2*y(2)**2*y(4)**2 + 1000*y(1)**2*y(2)*y(3)**3 + 125*y(1)**2*y(2)*y(3) & - & **2*y(4) + 175*y(1)**2*y(2)*y(3)*y(4)**2 + 50*y(1)**2*y(2)*y(4)**3 + 1081*y(1) & - & **2*y(3)**4 - 50*y(1)**2*y(3)**3*y(4) - 10*y(1)**2*y(3)**2*y(4)**2 + 45*y(1) & - & **2*y(3)*y(4)**3 + 5*y(1)**2*y(4)**4 + 900*y(1)*y(2)**3*y(3)**2 + 90*y(1)*y(2) & - & **3*y(3)*y(4) + 90*y(1)*y(2)**3*y(4)**2 + 1800*y(1)*y(2)**2*y(3)**3 + 225*y(1) & - & *y(2)**2*y(3)**2*y(4) + 315*y(1)*y(2)**2*y(3)*y(4)**2 + 90*y(1)*y(2)**2*y(4)**3 & - & + 4224*y(1)*y(2)*y(3)**4 - 120*y(1)*y(2)*y(3)**3*y(4) + 25*y(1)*y(2)*y(3)**2*y(4) & - & **2 + 165*y(1)*y(2)*y(3)*y(4)**3 + 20*y(1)*y(2)*y(4)**4 + 3324*y(1)*y(3)**5 & - & + 1407*y(1)*y(3)**4*y(4) - 100*y(1)*y(3)**3*y(4)**2 + 70*y(1)*y(3)**2*y(4)**3 & - & + 15*y(1)*y(3)*y(4)**4 + 450*y(2)**4*y(3)**2 + 45*y(2)**4*y(3)*y(4) + 45*y(2) & - & **4*y(4)**2 + 1200*y(2)**3*y(3)**3 + 150*y(2)**3*y(3)**2*y(4) + 210*y(2)**3*y(3) & - & *y(4)**2 + 60*y(2)**3*y(4)**3 + 4224*y(2)**2*y(3)**4 - 120*y(2)**2*y(3)**3*y(4) & - & + 25*y(2)**2*y(3)**2*y(4)**2 + 165*y(2)**2*y(3)*y(4)**3 + 20*y(2)**2*y(4)**4 & - & + 6648*y(2)*y(3)**5 + 2814*y(2)*y(3)**4*y(4) - 200*y(2)*y(3)**3*y(4)**2 & - & + 140*y(2)*y(3)**2*y(4)**3 + 30*y(2)*y(3)*y(4)**4 + 3174*y(3)**6 + 3039*y(3) & - & **5*y(4) + 771*y(3)**4*y(4)**2 + 135*y(3)**3*y(4)**3 + 60*y(3)**2*y(4)**4)) & - & /(5*(y(2) + y(3))**2*(y(1) + y(2) + y(3))**2*(y(2) + y(3) + y(4))**2*(y(1) + y(2) & - & + y(3) + y(4))**2) - beta_coef_${XYZ}$ (i + 1, 2, & - & 4) = -(4*y(3)**2*(100*y(1)**2*y(2)*y(3)**2 + 10*y(1)**2*y(2)*y(3)*y(4) + 10*y(1) & - & **2*y(2)*y(4)**2 - 95*y(1)**2*y(3)**2*y(4) + 5*y(1)**2*y(3)*y(4)**2 + 300*y(1) & - & *y(2)**2*y(3)**2 + 30*y(1)*y(2)**2*y(3)*y(4) + 30*y(1)*y(2)**2*y(4)**2 + 200*y(1) & - & *y(2)*y(3)**3 - 260*y(1)*y(2)*y(3)**2*y(4) + 50*y(1)*y(2)*y(3)*y(4)**2 + 10*y(1) & - & *y(2)*y(4)**3 + 1562*y(1)*y(3)**4 - 190*y(1)*y(3)**3*y(4) + 15*y(1)*y(3)**2*y(4) & - & **2 + 5*y(1)*y(3)*y(4)**3 + 300*y(2)**3*y(3)**2 + 30*y(2)**3*y(3)*y(4) + 30*y(2) & - & **3*y(4)**2 + 400*y(2)**2*y(3)**3 - 235*y(2)**2*y(3)**2*y(4) + 85*y(2)**2*y(3) & - & *y(4)**2 + 20*y(2)**2*y(4)**3 + 3224*y(2)*y(3)**4 - 460*y(2)*y(3)**3*y(4) & - & - 35*y(2)*y(3)**2*y(4)**2 + 25*y(2)*y(3)*y(4)**3 + 3124*y(3)**5 + 1467*y(3) & - & **4*y(4) + 110*y(3)**3*y(4)**2 + 105*y(3)**2*y(4)**3))/(5*(y(1) + y(2))*(y(2) & - & + y(3))*(y(1) + y(2) + y(3))**2*(y(2) + y(3) + y(4))*(y(1) + y(2) + y(3) + y(4)) & - & **2) - beta_coef_${XYZ}$ (i + 1, 2, & - & 5) = (4*y(3)**2*(50*y(2)**2*y(3)**2 + 5*y(2)**2*y(3)*y(4) + 5*y(2)**2*y(4)**2 & - & - 95*y(2)*y(3)**2*y(4) + 5*y(2)*y(3)*y(4)**2 + 781*y(3)**4 + 50*y(3)**2*y(4)**2)) & - & /(5*(y(1) + y(2))**2*(y(1) + y(2) + y(3))**2*(y(1) + y(2) + y(3) + y(4))**2) + beta_coef_${XYZ}$ (i + 1, 2, 0) = (4*y(3)**2*(5*y(1)**2*y(2)**2 + 5*y(1)**2*y(2)*y(3) + 50*y(1)**2*y(3)**2 + 10*y(1)*y(2)**3 + 15*y(1)*y(2)**2*y(3) + 205*y(1)*y(2)*y(3)**2 + 100*y(1)*y(3)**3 + 5*y(2)**4 + 10*y(2)**3*y(3) + 205*y(2)**2*y(3)**2 + 200*y(2)*y(3)**3 + 831*y(3)**4))/(5*(y(3) & !& + + y(4))**2*(y(2) + y(3) + y(4))**2*(y(1) + y(2) + y(3) + y(4))**2) !& + beta_coef_${XYZ}$ (i + 1, 2, 1) = (4*y(3)**2*(5*y(1)**3*y(2)*y(3) + 10*y(1)**3*y(2)*y(4) - 95*y(1)**3*y(3)**2 + 5*y(1)**3*y(3)*y(4) + 20*y(1)**2*y(2)**2*y(3) + 40*y(1)**2*y(2)**2*y(4) - 465*y(1)**2*y(2)*y(3)**2 + 55*y(1)**2*y(2)*y(3)*y(4) + 10*y(1)**2*y(2)*y(4)**2 - 285*y(1)**2*y(3)**3 & !& + + 20*y(1)**2*y(3)**2*y(4) + 5*y(1)**2*y(3)*y(4)**2 + 30*y(1)*y(2)**3*y(3) + 60*y(1)*y(2)**3*y(4) - 825*y(1)*y(2)**2*y(3)**2 + 135*y(1)*y(2)**2*y(3)*y(4) + 30*y(1)*y(2)**2*y(4)**2 - 1040*y(1)*y(2)*y(3)**3 + 100*y(1)*y(2)*y(3)**2*y(4) + 35*y(1)*y(2)*y(3)*y(4)**2 & !& + - 1847*y(1)*y(3)**4 + 125*y(1)*y(3)**3*y(4) + 110*y(1)*y(3)**2*y(4)**2 + 15*y(2)**4*y(3) + 30*y(2)**4*y(4) - 550*y(2)**3*y(3)**2 + 90*y(2)**3*y(3)*y(4) + 20*y(2)**3*y(4)**2 - 1040*y(2)**2*y(3)**3 + 100*y(2)**2*y(3)**2*y(4) + 35*y(2)**2*y(3)*y(4)**2 & !& + - 3694*y(2)*y(3)**4 + 250*y(2)*y(3)**3*y(4) + 220*y(2)*y(3)**2*y(4)**2 - 3219*y(3)**5 - 1452*y(3)**4*y(4) + 105*y(3)**3*y(4)**2))/(5*(y(2) + y(3))*(y(3) + y(4))*(y(1) + y(2) + y(3))*(y(2) + y(3) + y(4))**2*(y(1) + y(2) + y(3) + y(4))**2) !& + beta_coef_${XYZ}$ (i + 1, 2, 2) = -(4*y(3)**2*(5*y(2)**3*y(3) - 95*y(2)*y(3)**3 - 190*y(2)**2*y(3)**2 + 10*y(2)**3*y(4) + 100*y(3)**3*y(4) - 1562*y(3)**4 - 95*y(1)*y(2)*y(3)**2 + 5*y(1)*y(2)**2*y(3) + 10*y(1)*y(2)**2*y(4) + 100*y(1)*y(3)**2*y(4) + 205*y(2)*y(3)**2*y(4) & !& + + 15*y(2)**2*y(3)*y(4) + 10*y(1)*y(2)*y(3)*y(4)))/(5*(y(1) + y(2))*(y(3) + y(4))*(y(1) + y(2) + y(3))*(y(2) + y(3) + y(4))*(y(1) + y(2) + y(3) + y(4))**2) !& + beta_coef_${XYZ}$ (i + 1, 2, 3) = (4*y(3)**2*(50*y(1)**4*y(3)**2 + 5*y(1)**4*y(3)*y(4) + 5*y(1)**4*y(4)**2 + 300*y(1)**3*y(2)*y(3)**2 + 30*y(1)**3*y(2)*y(3)*y(4) + 30*y(1)**3*y(2)*y(4)**2 + 200*y(1)**3*y(3)**3 + 25*y(1)**3*y(3)**2*y(4) + 35*y(1)**3*y(3)*y(4)**2 + 10*y(1)**3*y(4)**3 & !& + + 750*y(1)**2*y(2)**2*y(3)**2 + 75*y(1)**2*y(2)**2*y(3)*y(4) + 75*y(1)**2*y(2)**2*y(4)**2 + 1000*y(1)**2*y(2)*y(3)**3 + 125*y(1)**2*y(2)*y(3)**2*y(4) + 175*y(1)**2*y(2)*y(3)*y(4)**2 + 50*y(1)**2*y(2)*y(4)**3 + 1081*y(1)**2*y(3)**4 - 50*y(1)**2*y(3)**3*y(4) & !& + - 10*y(1)**2*y(3)**2*y(4)**2 + 45*y(1)**2*y(3)*y(4)**3 + 5*y(1)**2*y(4)**4 + 900*y(1)*y(2)**3*y(3)**2 + 90*y(1)*y(2)**3*y(3)*y(4) + 90*y(1)*y(2)**3*y(4)**2 + 1800*y(1)*y(2)**2*y(3)**3 + 225*y(1)*y(2)**2*y(3)**2*y(4) + 315*y(1)*y(2)**2*y(3)*y(4)**2 & !& + + 90*y(1)*y(2)**2*y(4)**3 + 4224*y(1)*y(2)*y(3)**4 - 120*y(1)*y(2)*y(3)**3*y(4) + 25*y(1)*y(2)*y(3)**2*y(4)**2 + 165*y(1)*y(2)*y(3)*y(4)**3 + 20*y(1)*y(2)*y(4)**4 + 3324*y(1)*y(3)**5 + 1407*y(1)*y(3)**4*y(4) - 100*y(1)*y(3)**3*y(4)**2 + 70*y(1)*y(3)**2*y(4)**3 & !& + + 15*y(1)*y(3)*y(4)**4 + 450*y(2)**4*y(3)**2 + 45*y(2)**4*y(3)*y(4) + 45*y(2)**4*y(4)**2 + 1200*y(2)**3*y(3)**3 + 150*y(2)**3*y(3)**2*y(4) + 210*y(2)**3*y(3)*y(4)**2 + 60*y(2)**3*y(4)**3 + 4224*y(2)**2*y(3)**4 - 120*y(2)**2*y(3)**3*y(4) + 25*y(2)**2*y(3)**2*y(4)**2 & !& + + 165*y(2)**2*y(3)*y(4)**3 + 20*y(2)**2*y(4)**4 + 6648*y(2)*y(3)**5 + 2814*y(2)*y(3)**4*y(4) - 200*y(2)*y(3)**3*y(4)**2 + 140*y(2)*y(3)**2*y(4)**3 + 30*y(2)*y(3)*y(4)**4 + 3174*y(3)**6 + 3039*y(3)**5*y(4) + 771*y(3)**4*y(4)**2 + 135*y(3)**3*y(4)**3 + 60*y(3)**2*y(4)**4)) & !& + /(5*(y(2) + y(3))**2*(y(1) + y(2) + y(3))**2*(y(2) + y(3) + y(4))**2*(y(1) + y(2) + y(3) + y(4))**2) !& + beta_coef_${XYZ}$ (i + 1, 2, 4) = -(4*y(3)**2*(100*y(1)**2*y(2)*y(3)**2 + 10*y(1)**2*y(2)*y(3)*y(4) + 10*y(1)**2*y(2)*y(4)**2 - 95*y(1)**2*y(3)**2*y(4) + 5*y(1)**2*y(3)*y(4)**2 + 300*y(1)*y(2)**2*y(3)**2 + 30*y(1)*y(2)**2*y(3)*y(4) + 30*y(1)*y(2)**2*y(4)**2 + 200*y(1)*y(2)*y(3)**3 & !& + - 260*y(1)*y(2)*y(3)**2*y(4) + 50*y(1)*y(2)*y(3)*y(4)**2 + 10*y(1)*y(2)*y(4)**3 + 1562*y(1)*y(3)**4 - 190*y(1)*y(3)**3*y(4) + 15*y(1)*y(3)**2*y(4)**2 + 5*y(1)*y(3)*y(4)**3 + 300*y(2)**3*y(3)**2 + 30*y(2)**3*y(3)*y(4) + 30*y(2)**3*y(4)**2 + 400*y(2)**2*y(3)**3 & !& + - 235*y(2)**2*y(3)**2*y(4) + 85*y(2)**2*y(3)*y(4)**2 + 20*y(2)**2*y(4)**3 + 3224*y(2)*y(3)**4 - 460*y(2)*y(3)**3*y(4) - 35*y(2)*y(3)**2*y(4)**2 + 25*y(2)*y(3)*y(4)**3 + 3124*y(3)**5 + 1467*y(3)**4*y(4) + 110*y(3)**3*y(4)**2 + 105*y(3)**2*y(4)**3)) & !& + /(5*(y(1) + y(2))*(y(2) + y(3))*(y(1) + y(2) + y(3))**2*(y(2) + y(3) + y(4))*(y(1) + y(2) + y(3) + y(4))**2) !& + beta_coef_${XYZ}$ (i + 1, 2, 5) = (4*y(3)**2*(50*y(2)**2*y(3)**2 + 5*y(2)**2*y(3)*y(4) + 5*y(2)**2*y(4)**2 - 95*y(2)*y(3)**2*y(4) + 5*y(2)*y(3)*y(4)**2 + 781*y(3)**4 + 50*y(3)**2*y(4)**2))/(5*(y(1) + y(2))**2*(y(1) + y(2) + y(3))**2*(y(1) + y(2) + y(3) + y(4))**2) !& y = s_cb(i:i + 3) - s_cb(i - 1:i + 2) - beta_coef_${XYZ}$ (i + 1, 1, & - & 0) = (4*y(2)**2*(50*y(1)**2*y(2)**2 + 5*y(1)**2*y(2)*y(3) + 5*y(1)**2*y(3)**2 & - & - 95*y(1)*y(2)**2*y(3) + 5*y(1)*y(2)*y(3)**2 + 781*y(2)**4 + 50*y(2)**2*y(3)**2)) & - & /(5*(y(3) + y(4))**2*(y(2) + y(3) + y(4))**2*(y(1) + y(2) + y(3) + y(4))**2) - beta_coef_${XYZ}$ (i + 1, 1, & - & 1) = -(4*y(2)**2*(105*y(1)**3*y(2)**2 + 25*y(1)**3*y(2)*y(3) + 5*y(1)**3*y(2) & - & *y(4) + 20*y(1)**3*y(3)**2 + 10*y(1)**3*y(3)*y(4) + 110*y(1)**2*y(2)**3 - 35*y(1) & - & **2*y(2)**2*y(3) + 15*y(1)**2*y(2)**2*y(4) + 85*y(1)**2*y(2)*y(3)**2 + 50*y(1) & - & **2*y(2)*y(3)*y(4) + 5*y(1)**2*y(2)*y(4)**2 + 30*y(1)**2*y(3)**3 + 30*y(1) & - & **2*y(3)**2*y(4) + 10*y(1)**2*y(3)*y(4)**2 + 1467*y(1)*y(2)**4 - 460*y(1)*y(2) & - & **3*y(3) - 190*y(1)*y(2)**3*y(4) - 235*y(1)*y(2)**2*y(3)**2 - 260*y(1)*y(2) & - & **2*y(3)*y(4) - 95*y(1)*y(2)**2*y(4)**2 + 30*y(1)*y(2)*y(3)**3 + 30*y(1)*y(2) & - & *y(3)**2*y(4) + 10*y(1)*y(2)*y(3)*y(4)**2 + 3124*y(2)**5 + 3224*y(2)**4*y(3) & - & + 1562*y(2)**4*y(4) + 400*y(2)**3*y(3)**2 + 200*y(2)**3*y(3)*y(4) + 300*y(2) & - & **2*y(3)**3 + 300*y(2)**2*y(3)**2*y(4) + 100*y(2)**2*y(3)*y(4)**2))/(5*(y(2) & - & + y(3))*(y(3) + y(4))*(y(1) + y(2) + y(3))*(y(2) + y(3) + y(4))**2*(y(1) + y(2) & - & + y(3) + y(4))**2) - beta_coef_${XYZ}$ (i + 1, 1, & - & 2) = -(4*y(2)**2*(100*y(1)*y(2)**3 - 190*y(2)**2*y(3)**2 + 10*y(1)*y(3)**3 & - & + 5*y(2)*y(3)**3 - 95*y(2)**3*y(3) - 1562*y(2)**4 + 15*y(1)*y(2)*y(3)**2 & - & + 205*y(1)*y(2)**2*y(3) + 100*y(1)*y(2)**2*y(4) + 10*y(1)*y(3)**2*y(4) + 5*y(2) & - & *y(3)**2*y(4) - 95*y(2)**2*y(3)*y(4) + 10*y(1)*y(2)*y(3)*y(4)))/(5*(y(1) + y(2)) & - & *(y(3) + y(4))*(y(1) + y(2) + y(3))*(y(2) + y(3) + y(4))*(y(1) + y(2) + y(3) & - & + y(4))**2) - beta_coef_${XYZ}$ (i + 1, 1, & - & 3) = (4*y(2)**2*(60*y(1)**4*y(2)**2 + 30*y(1)**4*y(2)*y(3) + 15*y(1)**4*y(2)*y(4) & - & + 20*y(1)**4*y(3)**2 + 20*y(1)**4*y(3)*y(4) + 5*y(1)**4*y(4)**2 + 135*y(1) & - & **3*y(2)**3 + 140*y(1)**3*y(2)**2*y(3) + 70*y(1)**3*y(2)**2*y(4) + 165*y(1) & - & **3*y(2)*y(3)**2 + 165*y(1)**3*y(2)*y(3)*y(4) + 45*y(1)**3*y(2)*y(4)**2 + 60*y(1) & - & **3*y(3)**3 + 90*y(1)**3*y(3)**2*y(4) + 50*y(1)**3*y(3)*y(4)**2 + 10*y(1)**3*y(4) & - & **3 + 771*y(1)**2*y(2)**4 - 200*y(1)**2*y(2)**3*y(3) - 100*y(1)**2*y(2)**3*y(4) & - & + 25*y(1)**2*y(2)**2*y(3)**2 + 25*y(1)**2*y(2)**2*y(3)*y(4) - 10*y(1)**2*y(2) & - & **2*y(4)**2 + 210*y(1)**2*y(2)*y(3)**3 + 315*y(1)**2*y(2)*y(3)**2*y(4) + 175*y(1) & - & **2*y(2)*y(3)*y(4)**2 + 35*y(1)**2*y(2)*y(4)**3 + 45*y(1)**2*y(3)**4 + 90*y(1) & - & **2*y(3)**3*y(4) + 75*y(1)**2*y(3)**2*y(4)**2 + 30*y(1)**2*y(3)*y(4)**3 + 5*y(1) & - & **2*y(4)**4 + 3039*y(1)*y(2)**5 + 2814*y(1)*y(2)**4*y(3) + 1407*y(1)*y(2)**4*y(4) & - & - 120*y(1)*y(2)**3*y(3)**2 - 120*y(1)*y(2)**3*y(3)*y(4) - 50*y(1)*y(2)**3*y(4) & - & **2 + 150*y(1)*y(2)**2*y(3)**3 + 225*y(1)*y(2)**2*y(3)**2*y(4) + 125*y(1)*y(2) & - & **2*y(3)*y(4)**2 + 25*y(1)*y(2)**2*y(4)**3 + 45*y(1)*y(2)*y(3)**4 + 90*y(1)*y(2) & - & *y(3)**3*y(4) + 75*y(1)*y(2)*y(3)**2*y(4)**2 + 30*y(1)*y(2)*y(3)*y(4)**3 + 5*y(1) & - & *y(2)*y(4)**4 + 3174*y(2)**6 + 6648*y(2)**5*y(3) + 3324*y(2)**5*y(4) + 4224*y(2) & - & **4*y(3)**2 + 4224*y(2)**4*y(3)*y(4) + 1081*y(2)**4*y(4)**2 + 1200*y(2)**3*y(3) & - & **3 + 1800*y(2)**3*y(3)**2*y(4) + 1000*y(2)**3*y(3)*y(4)**2 + 200*y(2)**3*y(4) & - & **3 + 450*y(2)**2*y(3)**4 + 900*y(2)**2*y(3)**3*y(4) + 750*y(2)**2*y(3)**2*y(4) & - & **2 + 300*y(2)**2*y(3)*y(4)**3 + 50*y(2)**2*y(4)**4))/(5*(y(2) + y(3))**2*(y(1) & - & + y(2) + y(3))**2*(y(2) + y(3) + y(4))**2*(y(1) + y(2) + y(3) + y(4))**2) - beta_coef_${XYZ}$ (i + 1, 1, & - & 4) = (4*y(2)**2*(105*y(1)**2*y(2)**3 + 220*y(1)**2*y(2)**2*y(3) + 110*y(1) & - & **2*y(2)**2*y(4) + 35*y(1)**2*y(2)*y(3)**2 + 35*y(1)**2*y(2)*y(3)*y(4) + 5*y(1) & - & **2*y(2)*y(4)**2 + 20*y(1)**2*y(3)**3 + 30*y(1)**2*y(3)**2*y(4) + 10*y(1)**2*y(3) & - & *y(4)**2 - 1452*y(1)*y(2)**4 + 250*y(1)*y(2)**3*y(3) + 125*y(1)*y(2)**3*y(4) & - & + 100*y(1)*y(2)**2*y(3)**2 + 100*y(1)*y(2)**2*y(3)*y(4) + 20*y(1)*y(2)**2*y(4) & - & **2 + 90*y(1)*y(2)*y(3)**3 + 135*y(1)*y(2)*y(3)**2*y(4) + 55*y(1)*y(2)*y(3)*y(4) & - & **2 + 5*y(1)*y(2)*y(4)**3 + 30*y(1)*y(3)**4 + 60*y(1)*y(3)**3*y(4) + 40*y(1)*y(3) & - & **2*y(4)**2 + 10*y(1)*y(3)*y(4)**3 - 3219*y(2)**5 - 3694*y(2)**4*y(3) - 1847*y(2) & - & **4*y(4) - 1040*y(2)**3*y(3)**2 - 1040*y(2)**3*y(3)*y(4) - 285*y(2)**3*y(4)**2 & - & - 550*y(2)**2*y(3)**3 - 825*y(2)**2*y(3)**2*y(4) - 465*y(2)**2*y(3)*y(4)**2 & - & - 95*y(2)**2*y(4)**3 + 15*y(2)*y(3)**4 + 30*y(2)*y(3)**3*y(4) + 20*y(2)*y(3) & - & **2*y(4)**2 + 5*y(2)*y(3)*y(4)**3))/(5*(y(1) + y(2))*(y(2) + y(3))*(y(1) + y(2) & - & + y(3))**2*(y(2) + y(3) + y(4))*(y(1) + y(2) + y(3) + y(4))**2) - beta_coef_${XYZ}$ (i + 1, 1, & - & 5) = (4*y(2)**2*(831*y(2)**4 + 200*y(2)**3*y(3) + 100*y(2)**3*y(4) + 205*y(2) & - & **2*y(3)**2 + 205*y(2)**2*y(3)*y(4) + 50*y(2)**2*y(4)**2 + 10*y(2)*y(3)**3 & - & + 15*y(2)*y(3)**2*y(4) + 5*y(2)*y(3)*y(4)**2 + 5*y(3)**4 + 10*y(3)**3*y(4) & - & + 5*y(3)**2*y(4)**2))/(5*(y(1) + y(2))**2*(y(1) + y(2) + y(3))**2*(y(1) + y(2) & - & + y(3) + y(4))**2) + beta_coef_${XYZ}$ (i + 1, 1, 0) = (4*y(2)**2*(50*y(1)**2*y(2)**2 + 5*y(1)**2*y(2)*y(3) + 5*y(1)**2*y(3)**2 - 95*y(1)*y(2)**2*y(3) + 5*y(1)*y(2)*y(3)**2 + 781*y(2)**4 + 50*y(2)**2*y(3)**2))/(5*(y(3) + y(4))**2*(y(2) + y(3) + y(4))**2*(y(1) + y(2) + y(3) + y(4))**2) !& + beta_coef_${XYZ}$ (i + 1, 1, 1) = -(4*y(2)**2*(105*y(1)**3*y(2)**2 + 25*y(1)**3*y(2)*y(3) + 5*y(1)**3*y(2)*y(4) + 20*y(1)**3*y(3)**2 + 10*y(1)**3*y(3)*y(4) + 110*y(1)**2*y(2)**3 - 35*y(1)**2*y(2)**2*y(3) + 15*y(1)**2*y(2)**2*y(4) + 85*y(1)**2*y(2)*y(3)**2 + 50*y(1)**2*y(2)*y(3)*y(4) & !& + + 5*y(1)**2*y(2)*y(4)**2 + 30*y(1)**2*y(3)**3 + 30*y(1)**2*y(3)**2*y(4) + 10*y(1)**2*y(3)*y(4)**2 + 1467*y(1)*y(2)**4 - 460*y(1)*y(2)**3*y(3) - 190*y(1)*y(2)**3*y(4) - 235*y(1)*y(2)**2*y(3)**2 - 260*y(1)*y(2)**2*y(3)*y(4) - 95*y(1)*y(2)**2*y(4)**2 & !& + + 30*y(1)*y(2)*y(3)**3 + 30*y(1)*y(2)*y(3)**2*y(4) + 10*y(1)*y(2)*y(3)*y(4)**2 + 3124*y(2)**5 + 3224*y(2)**4*y(3) + 1562*y(2)**4*y(4) + 400*y(2)**3*y(3)**2 + 200*y(2)**3*y(3)*y(4) + 300*y(2)**2*y(3)**3 + 300*y(2)**2*y(3)**2*y(4) + 100*y(2)**2*y(3)*y(4)**2)) & !& + /(5*(y(2) + y(3))*(y(3) + y(4))*(y(1) + y(2) + y(3))*(y(2) + y(3) + y(4))**2*(y(1) + y(2) + y(3) + y(4))**2) !& + beta_coef_${XYZ}$ (i + 1, 1, 2) = -(4*y(2)**2*(100*y(1)*y(2)**3 - 190*y(2)**2*y(3)**2 + 10*y(1)*y(3)**3 + 5*y(2)*y(3)**3 - 95*y(2)**3*y(3) - 1562*y(2)**4 + 15*y(1)*y(2)*y(3)**2 + 205*y(1)*y(2)**2*y(3) + 100*y(1)*y(2)**2*y(4) + 10*y(1)*y(3)**2*y(4) + 5*y(2)*y(3)**2*y(4) - 95*y(2)**2*y(3)*y(4) & !& + + 10*y(1)*y(2)*y(3)*y(4)))/(5*(y(1) + y(2))*(y(3) + y(4))*(y(1) + y(2) + y(3))*(y(2) + y(3) + y(4))*(y(1) + y(2) + y(3) + y(4))**2) !& + beta_coef_${XYZ}$ (i + 1, 1, 3) = (4*y(2)**2*(60*y(1)**4*y(2)**2 + 30*y(1)**4*y(2)*y(3) + 15*y(1)**4*y(2)*y(4) + 20*y(1)**4*y(3)**2 + 20*y(1)**4*y(3)*y(4) + 5*y(1)**4*y(4)**2 + 135*y(1)**3*y(2)**3 + 140*y(1)**3*y(2)**2*y(3) + 70*y(1)**3*y(2)**2*y(4) + 165*y(1)**3*y(2)*y(3)**2 & !& + + 165*y(1)**3*y(2)*y(3)*y(4) + 45*y(1)**3*y(2)*y(4)**2 + 60*y(1)**3*y(3)**3 + 90*y(1)**3*y(3)**2*y(4) + 50*y(1)**3*y(3)*y(4)**2 + 10*y(1)**3*y(4)**3 + 771*y(1)**2*y(2)**4 - 200*y(1)**2*y(2)**3*y(3) - 100*y(1)**2*y(2)**3*y(4) + 25*y(1)**2*y(2)**2*y(3)**2 & !& + + 25*y(1)**2*y(2)**2*y(3)*y(4) - 10*y(1)**2*y(2)**2*y(4)**2 + 210*y(1)**2*y(2)*y(3)**3 + 315*y(1)**2*y(2)*y(3)**2*y(4) + 175*y(1)**2*y(2)*y(3)*y(4)**2 + 35*y(1)**2*y(2)*y(4)**3 + 45*y(1)**2*y(3)**4 + 90*y(1)**2*y(3)**3*y(4) + 75*y(1)**2*y(3)**2*y(4)**2 & !& + + 30*y(1)**2*y(3)*y(4)**3 + 5*y(1)**2*y(4)**4 + 3039*y(1)*y(2)**5 + 2814*y(1)*y(2)**4*y(3) + 1407*y(1)*y(2)**4*y(4) - 120*y(1)*y(2)**3*y(3)**2 - 120*y(1)*y(2)**3*y(3)*y(4) - 50*y(1)*y(2)**3*y(4)**2 + 150*y(1)*y(2)**2*y(3)**3 + 225*y(1)*y(2)**2*y(3)**2*y(4) & !& + + 125*y(1)*y(2)**2*y(3)*y(4)**2 + 25*y(1)*y(2)**2*y(4)**3 + 45*y(1)*y(2)*y(3)**4 + 90*y(1)*y(2)*y(3)**3*y(4) + 75*y(1)*y(2)*y(3)**2*y(4)**2 + 30*y(1)*y(2)*y(3)*y(4)**3 + 5*y(1)*y(2)*y(4)**4 + 3174*y(2)**6 + 6648*y(2)**5*y(3) + 3324*y(2)**5*y(4) & !& + + 4224*y(2)**4*y(3)**2 + 4224*y(2)**4*y(3)*y(4) + 1081*y(2)**4*y(4)**2 + 1200*y(2)**3*y(3)**3 + 1800*y(2)**3*y(3)**2*y(4) + 1000*y(2)**3*y(3)*y(4)**2 + 200*y(2)**3*y(4)**3 + 450*y(2)**2*y(3)**4 + 900*y(2)**2*y(3)**3*y(4) + 750*y(2)**2*y(3)**2*y(4)**2 & !& + + 300*y(2)**2*y(3)*y(4)**3 + 50*y(2)**2*y(4)**4))/(5*(y(2) + y(3))**2*(y(1) + y(2) + y(3))**2*(y(2) + y(3) + y(4))**2*(y(1) + y(2) + y(3) + y(4))**2) !& + beta_coef_${XYZ}$ (i + 1, 1, 4) = (4*y(2)**2*(105*y(1)**2*y(2)**3 + 220*y(1)**2*y(2)**2*y(3) + 110*y(1)**2*y(2)**2*y(4) + 35*y(1)**2*y(2)*y(3)**2 + 35*y(1)**2*y(2)*y(3)*y(4) + 5*y(1)**2*y(2)*y(4)**2 + 20*y(1)**2*y(3)**3 + 30*y(1)**2*y(3)**2*y(4) + 10*y(1)**2*y(3)*y(4)**2 - 1452*y(1)*y(2)**4 & !& + + 250*y(1)*y(2)**3*y(3) + 125*y(1)*y(2)**3*y(4) + 100*y(1)*y(2)**2*y(3)**2 + 100*y(1)*y(2)**2*y(3)*y(4) + 20*y(1)*y(2)**2*y(4)**2 + 90*y(1)*y(2)*y(3)**3 + 135*y(1)*y(2)*y(3)**2*y(4) + 55*y(1)*y(2)*y(3)*y(4)**2 + 5*y(1)*y(2)*y(4)**3 + 30*y(1)*y(3)**4 & !& + + 60*y(1)*y(3)**3*y(4) + 40*y(1)*y(3)**2*y(4)**2 + 10*y(1)*y(3)*y(4)**3 - 3219*y(2)**5 - 3694*y(2)**4*y(3) - 1847*y(2)**4*y(4) - 1040*y(2)**3*y(3)**2 - 1040*y(2)**3*y(3)*y(4) - 285*y(2)**3*y(4)**2 - 550*y(2)**2*y(3)**3 - 825*y(2)**2*y(3)**2*y(4) & !& + - 465*y(2)**2*y(3)*y(4)**2 - 95*y(2)**2*y(4)**3 + 15*y(2)*y(3)**4 + 30*y(2)*y(3)**3*y(4) + 20*y(2)*y(3)**2*y(4)**2 + 5*y(2)*y(3)*y(4)**3))/(5*(y(1) + y(2))*(y(2) + y(3))*(y(1) + y(2) + y(3))**2*(y(2) + y(3) + y(4))*(y(1) + y(2) + y(3) + y(4))**2) !& + beta_coef_${XYZ}$ (i + 1, 1, 5) = (4*y(2)**2*(831*y(2)**4 + 200*y(2)**3*y(3) + 100*y(2)**3*y(4) + 205*y(2)**2*y(3)**2 + 205*y(2)**2*y(3)*y(4) + 50*y(2)**2*y(4)**2 + 10*y(2)*y(3)**3 + 15*y(2)*y(3)**2*y(4) + 5*y(2)*y(3)*y(4)**2 + 5*y(3)**4 + 10*y(3)**3*y(4) + 5*y(3)**2*y(4)**2))/(5*(y(1) & !& + + y(2))**2*(y(1) + y(2) + y(3))**2*(y(1) + y(2) + y(3) + y(4))**2) !& y = s_cb(i + 1:i + 4) - s_cb(i:i + 3) - beta_coef_${XYZ}$ (i + 1, 0, & - & 0) = (4*y(1)**2*(831*y(1)**4 + 200*y(1)**3*y(2) + 100*y(1)**3*y(3) + 205*y(1) & - & **2*y(2)**2 + 205*y(1)**2*y(2)*y(3) + 50*y(1)**2*y(3)**2 + 10*y(1)*y(2)**3 & - & + 15*y(1)*y(2)**2*y(3) + 5*y(1)*y(2)*y(3)**2 + 5*y(2)**4 + 10*y(2)**3*y(3) & - & + 5*y(2)**2*y(3)**2))/(5*(y(3) + y(4))**2*(y(2) + y(3) + y(4))**2*(y(1) + y(2) & - & + y(3) + y(4))**2) - beta_coef_${XYZ}$ (i + 1, 0, & - & 1) = -(4*y(1)**2*(1662*y(1)**5 + 3824*y(1)**4*y(2) + 3624*y(1)**4*y(3) & - & + 1762*y(1)**4*y(4) + 1515*y(1)**3*y(2)**2 + 2115*y(1)**3*y(2)*y(3) + 805*y(1) & - & **3*y(2)*y(4) + 700*y(1)**3*y(3)**2 + 500*y(1)**3*y(3)*y(4) + 100*y(1)**3*y(4) & - & **2 + 1060*y(1)**2*y(2)**3 + 2205*y(1)**2*y(2)**2*y(3) + 835*y(1)**2*y(2)**2*y(4) & - & + 1445*y(1)**2*y(2)*y(3)**2 + 1030*y(1)**2*y(2)*y(3)*y(4) + 205*y(1)**2*y(2)*y(4) & - & **2 + 300*y(1)**2*y(3)**3 + 300*y(1)**2*y(3)**2*y(4) + 100*y(1)**2*y(3)*y(4)**2 & - & + 75*y(1)*y(2)**4 + 180*y(1)*y(2)**3*y(3) + 60*y(1)*y(2)**3*y(4) + 135*y(1)*y(2) & - & **2*y(3)**2 + 90*y(1)*y(2)**2*y(3)*y(4) + 15*y(1)*y(2)**2*y(4)**2 + 30*y(1)*y(2) & - & *y(3)**3 + 30*y(1)*y(2)*y(3)**2*y(4) + 10*y(1)*y(2)*y(3)*y(4)**2 + 30*y(2)**5 & - & + 90*y(2)**4*y(3) + 30*y(2)**4*y(4) + 90*y(2)**3*y(3)**2 + 60*y(2)**3*y(3)*y(4) & - & + 10*y(2)**3*y(4)**2 + 30*y(2)**2*y(3)**3 + 30*y(2)**2*y(3)**2*y(4) + 10*y(2) & - & **2*y(3)*y(4)**2))/(5*(y(2) + y(3))*(y(3) + y(4))*(y(1) + y(2) + y(3))*(y(2) & - & + y(3) + y(4))**2*(y(1) + y(2) + y(3) + y(4))**2) - beta_coef_${XYZ}$ (i + 1, 0, & - & 2) = (4*y(1)**2*(1767*y(1)**4 + 725*y(1)**3*y(2) + 415*y(1)**3*y(3) + 105*y(4) & - & *y(1)**3 + 665*y(1)**2*y(2)**2 + 775*y(1)**2*y(2)*y(3) + 220*y(4)*y(1)**2*y(2) & - & + 215*y(1)**2*y(3)**2 + 110*y(4)*y(1)**2*y(3) + 75*y(1)*y(2)**3 + 130*y(1)*y(2) & - & **2*y(3) + 35*y(4)*y(1)*y(2)**2 + 60*y(1)*y(2)*y(3)**2 + 35*y(4)*y(1)*y(2)*y(3) & - & + 5*y(1)*y(3)**3 + 5*y(4)*y(1)*y(3)**2 + 30*y(2)**4 + 70*y(2)**3*y(3) + 20*y(4) & - & *y(2)**3 + 50*y(2)**2*y(3)**2 + 30*y(4)*y(2)**2*y(3) + 10*y(2)*y(3)**3 + 10*y(4) & - & *y(2)*y(3)**2))/(5*(y(1) + y(2))*(y(3) + y(4))*(y(1) + y(2) + y(3))*(y(2) + y(3) & - & + y(4))*(y(1) + y(2) + y(3) + y(4))**2) - beta_coef_${XYZ}$ (i + 1, 0, & - & 3) = (4*y(1)**2*(831*y(1)**6 + 3624*y(1)**5*y(2) + 3524*y(1)**5*y(3) + 1762*y(1) & - & **5*y(4) + 4884*y(1)**4*y(2)**2 + 9058*y(1)**4*y(2)*y(3) + 4529*y(1)**4*y(2)*y(4) & - & + 4224*y(1)**4*y(3)**2 + 4224*y(1)**4*y(3)*y(4) + 1081*y(1)**4*y(4)**2 & - & + 2565*y(1)**3*y(2)**3 + 6120*y(1)**3*y(2)**2*y(3) + 3060*y(1)**3*y(2)**2*y(4) & - & + 4755*y(1)**3*y(2)*y(3)**2 + 4755*y(1)**3*y(2)*y(3)*y(4) + 1315*y(1)**3*y(2) & - & *y(4)**2 + 1200*y(1)**3*y(3)**3 + 1800*y(1)**3*y(3)**2*y(4) + 1000*y(1)**3*y(3) & - & *y(4)**2 + 200*y(1)**3*y(4)**3 + 1395*y(1)**2*y(2)**4 + 4380*y(1)**2*y(2)**3*y(3) & - & + 2190*y(1)**2*y(2)**3*y(4) + 5025*y(1)**2*y(2)**2*y(3)**2 + 5025*y(1)**2*y(2) & - & **2*y(3)*y(4) + 1390*y(1)**2*y(2)**2*y(4)**2 + 2490*y(1)**2*y(2)*y(3)**3 & - & + 3735*y(1)**2*y(2)*y(3)**2*y(4) + 2075*y(1)**2*y(2)*y(3)*y(4)**2 + 415*y(1) & - & **2*y(2)*y(4)**3 + 450*y(1)**2*y(3)**4 + 900*y(1)**2*y(3)**3*y(4) + 750*y(1) & - & **2*y(3)**2*y(4)**2 + 300*y(1)**2*y(3)*y(4)**3 + 50*y(1)**2*y(4)**4 + 135*y(1) & - & *y(2)**5 + 450*y(1)*y(2)**4*y(3) + 225*y(1)*y(2)**4*y(4) + 540*y(1)*y(2)**3*y(3) & - & **2 + 540*y(1)*y(2)**3*y(3)*y(4) + 150*y(1)*y(2)**3*y(4)**2 + 270*y(1)*y(2) & - & **2*y(3)**3 + 405*y(1)*y(2)**2*y(3)**2*y(4) + 225*y(1)*y(2)**2*y(3)*y(4)**2 & - & + 45*y(1)*y(2)**2*y(4)**3 + 45*y(1)*y(2)*y(3)**4 + 90*y(1)*y(2)*y(3)**3*y(4) & - & + 75*y(1)*y(2)*y(3)**2*y(4)**2 + 30*y(1)*y(2)*y(3)*y(4)**3 + 5*y(1)*y(2)*y(4)**4 & - & + 45*y(2)**6 + 180*y(2)**5*y(3) + 90*y(2)**5*y(4) + 270*y(2)**4*y(3)**2 & - & + 270*y(2)**4*y(3)*y(4) + 75*y(2)**4*y(4)**2 + 180*y(2)**3*y(3)**3 + 270*y(2) & - & **3*y(3)**2*y(4) + 150*y(2)**3*y(3)*y(4)**2 + 30*y(2)**3*y(4)**3 + 45*y(2) & - & **2*y(3)**4 + 90*y(2)**2*y(3)**3*y(4) + 75*y(2)**2*y(3)**2*y(4)**2 + 30*y(2) & - & **2*y(3)*y(4)**3 + 5*y(2)**2*y(4)**4))/(5*(y(2) + y(3))**2*(y(1) + y(2) + y(3)) & - & **2*(y(2) + y(3) + y(4))**2*(y(1) + y(2) + y(3) + y(4))**2) - beta_coef_${XYZ}$ (i + 1, 0, & - & 4) = -(4*y(1)**2*(1767*y(1)**5 + 4464*y(1)**4*y(2) + 4154*y(1)**4*y(3) & - & + 2077*y(1)**4*y(4) + 2655*y(1)**3*y(2)**2 + 4010*y(1)**3*y(2)*y(3) + 2005*y(1) & - & **3*y(2)*y(4) + 1460*y(1)**3*y(3)**2 + 1460*y(1)**3*y(3)*y(4) + 415*y(1)**3*y(4) & - & **2 + 1800*y(1)**2*y(2)**3 + 4000*y(1)**2*y(2)**2*y(3) + 2000*y(1)**2*y(2) & - & **2*y(4) + 2850*y(1)**2*y(2)*y(3)**2 + 2850*y(1)**2*y(2)*y(3)*y(4) + 790*y(1) & - & **2*y(2)*y(4)**2 + 650*y(1)**2*y(3)**3 + 975*y(1)**2*y(3)**2*y(4) + 535*y(1) & - & **2*y(3)*y(4)**2 + 105*y(1)**2*y(4)**3 + 270*y(1)*y(2)**4 + 720*y(1)*y(2)**3*y(3) & - & + 360*y(1)*y(2)**3*y(4) + 645*y(1)*y(2)**2*y(3)**2 + 645*y(1)*y(2)**2*y(3)*y(4) & - & + 165*y(1)*y(2)**2*y(4)**2 + 210*y(1)*y(2)*y(3)**3 + 315*y(1)*y(2)*y(3)**2*y(4) & - & + 155*y(1)*y(2)*y(3)*y(4)**2 + 25*y(1)*y(2)*y(4)**3 + 15*y(1)*y(3)**4 + 30*y(1) & - & *y(3)**3*y(4) + 20*y(1)*y(3)**2*y(4)**2 + 5*y(1)*y(3)*y(4)**3 + 90*y(2)**5 & - & + 300*y(2)**4*y(3) + 150*y(2)**4*y(4) + 360*y(2)**3*y(3)**2 + 360*y(2)**3*y(3) & - & *y(4) + 90*y(2)**3*y(4)**2 + 180*y(2)**2*y(3)**3 + 270*y(2)**2*y(3)**2*y(4) & - & + 130*y(2)**2*y(3)*y(4)**2 + 20*y(2)**2*y(4)**3 + 30*y(2)*y(3)**4 + 60*y(2)*y(3) & - & **3*y(4) + 40*y(2)*y(3)**2*y(4)**2 + 10*y(2)*y(3)*y(4)**3))/(5*(y(1) + y(2)) & - & *(y(2) + y(3))*(y(1) + y(2) + y(3))**2*(y(2) + y(3) + y(4))*(y(1) + y(2) + y(3) & - & + y(4))**2) - beta_coef_${XYZ}$ (i + 1, 0, & - & 5) = (4*y(1)**2*(996*y(1)**4 + 675*y(1)**3*y(2) + 450*y(1)**3*y(3) + 225*y(1) & - & **3*y(4) + 600*y(1)**2*y(2)**2 + 800*y(1)**2*y(2)*y(3) + 400*y(1)**2*y(2)*y(4) & - & + 260*y(1)**2*y(3)**2 + 260*y(1)**2*y(3)*y(4) + 60*y(1)**2*y(4)**2 + 135*y(1) & - & *y(2)**3 + 270*y(1)*y(2)**2*y(3) + 135*y(1)*y(2)**2*y(4) + 165*y(1)*y(2)*y(3)**2 & - & + 165*y(1)*y(2)*y(3)*y(4) + 30*y(1)*y(2)*y(4)**2 + 30*y(1)*y(3)**3 + 45*y(1)*y(3) & - & **2*y(4) + 15*y(1)*y(3)*y(4)**2 + 45*y(2)**4 + 120*y(2)**3*y(3) + 60*y(2)**3*y(4) & - & + 110*y(2)**2*y(3)**2 + 110*y(2)**2*y(3)*y(4) + 20*y(2)**2*y(4)**2 + 40*y(2)*y(3) & - & **3 + 60*y(2)*y(3)**2*y(4) + 20*y(2)*y(3)*y(4)**2 + 5*y(3)**4 + 10*y(3)**3*y(4) & - & + 5*y(3)**2*y(4)**2))/(5*(y(1) + y(2))**2*(y(1) + y(2) + y(3))**2*(y(1) + y(2) & - & + y(3) + y(4))**2) + beta_coef_${XYZ}$ (i + 1, 0, 0) = (4*y(1)**2*(831*y(1)**4 + 200*y(1)**3*y(2) + 100*y(1)**3*y(3) + 205*y(1)**2*y(2)**2 + 205*y(1)**2*y(2)*y(3) + 50*y(1)**2*y(3)**2 + 10*y(1)*y(2)**3 + 15*y(1)*y(2)**2*y(3) + 5*y(1)*y(2)*y(3)**2 + 5*y(2)**4 + 10*y(2)**3*y(3) + 5*y(2)**2*y(3)**2))/(5*(y(3) & !& + + y(4))**2*(y(2) + y(3) + y(4))**2*(y(1) + y(2) + y(3) + y(4))**2) !& + beta_coef_${XYZ}$ (i + 1, 0, 1) = -(4*y(1)**2*(1662*y(1)**5 + 3824*y(1)**4*y(2) + 3624*y(1)**4*y(3) + 1762*y(1)**4*y(4) + 1515*y(1)**3*y(2)**2 + 2115*y(1)**3*y(2)*y(3) + 805*y(1)**3*y(2)*y(4) + 700*y(1)**3*y(3)**2 + 500*y(1)**3*y(3)*y(4) + 100*y(1)**3*y(4)**2 + 1060*y(1)**2*y(2)**3 & !& + + 2205*y(1)**2*y(2)**2*y(3) + 835*y(1)**2*y(2)**2*y(4) + 1445*y(1)**2*y(2)*y(3)**2 + 1030*y(1)**2*y(2)*y(3)*y(4) + 205*y(1)**2*y(2)*y(4)**2 + 300*y(1)**2*y(3)**3 + 300*y(1)**2*y(3)**2*y(4) + 100*y(1)**2*y(3)*y(4)**2 + 75*y(1)*y(2)**4 + 180*y(1)*y(2)**3*y(3) & !& + + 60*y(1)*y(2)**3*y(4) + 135*y(1)*y(2)**2*y(3)**2 + 90*y(1)*y(2)**2*y(3)*y(4) + 15*y(1)*y(2)**2*y(4)**2 + 30*y(1)*y(2)*y(3)**3 + 30*y(1)*y(2)*y(3)**2*y(4) + 10*y(1)*y(2)*y(3)*y(4)**2 + 30*y(2)**5 + 90*y(2)**4*y(3) + 30*y(2)**4*y(4) + 90*y(2)**3*y(3)**2 & !& + + 60*y(2)**3*y(3)*y(4) + 10*y(2)**3*y(4)**2 + 30*y(2)**2*y(3)**3 + 30*y(2)**2*y(3)**2*y(4) + 10*y(2)**2*y(3)*y(4)**2))/(5*(y(2) + y(3))*(y(3) + y(4))*(y(1) + y(2) + y(3))*(y(2) + y(3) + y(4))**2*(y(1) + y(2) + y(3) + y(4))**2) !& + beta_coef_${XYZ}$ (i + 1, 0, 2) = (4*y(1)**2*(1767*y(1)**4 + 725*y(1)**3*y(2) + 415*y(1)**3*y(3) + 105*y(4)*y(1)**3 + 665*y(1)**2*y(2)**2 + 775*y(1)**2*y(2)*y(3) + 220*y(4)*y(1)**2*y(2) + 215*y(1)**2*y(3)**2 + 110*y(4)*y(1)**2*y(3) + 75*y(1)*y(2)**3 + 130*y(1)*y(2)**2*y(3) + 35*y(4)*y(1)*y(2)**2 & !& + + 60*y(1)*y(2)*y(3)**2 + 35*y(4)*y(1)*y(2)*y(3) + 5*y(1)*y(3)**3 + 5*y(4)*y(1)*y(3)**2 + 30*y(2)**4 + 70*y(2)**3*y(3) + 20*y(4)*y(2)**3 + 50*y(2)**2*y(3)**2 + 30*y(4)*y(2)**2*y(3) + 10*y(2)*y(3)**3 + 10*y(4)*y(2)*y(3)**2)) & !& + /(5*(y(1) + y(2))*(y(3) + y(4))*(y(1) + y(2) + y(3))*(y(2) + y(3) + y(4))*(y(1) + y(2) + y(3) + y(4))**2) !& + beta_coef_${XYZ}$ (i + 1, 0, 3) = (4*y(1)**2*(831*y(1)**6 + 3624*y(1)**5*y(2) + 3524*y(1)**5*y(3) + 1762*y(1)**5*y(4) + 4884*y(1)**4*y(2)**2 + 9058*y(1)**4*y(2)*y(3) + 4529*y(1)**4*y(2)*y(4) + 4224*y(1)**4*y(3)**2 + 4224*y(1)**4*y(3)*y(4) + 1081*y(1)**4*y(4)**2 + 2565*y(1)**3*y(2)**3 & !& + + 6120*y(1)**3*y(2)**2*y(3) + 3060*y(1)**3*y(2)**2*y(4) + 4755*y(1)**3*y(2)*y(3)**2 + 4755*y(1)**3*y(2)*y(3)*y(4) + 1315*y(1)**3*y(2)*y(4)**2 + 1200*y(1)**3*y(3)**3 + 1800*y(1)**3*y(3)**2*y(4) + 1000*y(1)**3*y(3)*y(4)**2 + 200*y(1)**3*y(4)**3 + 1395*y(1)**2*y(2)**4 & !& + + 4380*y(1)**2*y(2)**3*y(3) + 2190*y(1)**2*y(2)**3*y(4) + 5025*y(1)**2*y(2)**2*y(3)**2 + 5025*y(1)**2*y(2)**2*y(3)*y(4) + 1390*y(1)**2*y(2)**2*y(4)**2 + 2490*y(1)**2*y(2)*y(3)**3 + 3735*y(1)**2*y(2)*y(3)**2*y(4) + 2075*y(1)**2*y(2)*y(3)*y(4)**2 & !& + + 415*y(1)**2*y(2)*y(4)**3 + 450*y(1)**2*y(3)**4 + 900*y(1)**2*y(3)**3*y(4) + 750*y(1)**2*y(3)**2*y(4)**2 + 300*y(1)**2*y(3)*y(4)**3 + 50*y(1)**2*y(4)**4 + 135*y(1)*y(2)**5 + 450*y(1)*y(2)**4*y(3) + 225*y(1)*y(2)**4*y(4) + 540*y(1)*y(2)**3*y(3)**2 & !& + + 540*y(1)*y(2)**3*y(3)*y(4) + 150*y(1)*y(2)**3*y(4)**2 + 270*y(1)*y(2)**2*y(3)**3 + 405*y(1)*y(2)**2*y(3)**2*y(4) + 225*y(1)*y(2)**2*y(3)*y(4)**2 + 45*y(1)*y(2)**2*y(4)**3 + 45*y(1)*y(2)*y(3)**4 + 90*y(1)*y(2)*y(3)**3*y(4) + 75*y(1)*y(2)*y(3)**2*y(4)**2 & !& + + 30*y(1)*y(2)*y(3)*y(4)**3 + 5*y(1)*y(2)*y(4)**4 + 45*y(2)**6 + 180*y(2)**5*y(3) + 90*y(2)**5*y(4) + 270*y(2)**4*y(3)**2 + 270*y(2)**4*y(3)*y(4) + 75*y(2)**4*y(4)**2 + 180*y(2)**3*y(3)**3 + 270*y(2)**3*y(3)**2*y(4) + 150*y(2)**3*y(3)*y(4)**2 + 30*y(2)**3*y(4)**3 & !& + + 45*y(2)**2*y(3)**4 + 90*y(2)**2*y(3)**3*y(4) + 75*y(2)**2*y(3)**2*y(4)**2 + 30*y(2)**2*y(3)*y(4)**3 + 5*y(2)**2*y(4)**4))/(5*(y(2) + y(3))**2*(y(1) + y(2) + y(3))**2*(y(2) + y(3) + y(4))**2*(y(1) + y(2) + y(3) + y(4))**2) !& + beta_coef_${XYZ}$ (i + 1, 0, 4) = -(4*y(1)**2*(1767*y(1)**5 + 4464*y(1)**4*y(2) + 4154*y(1)**4*y(3) + 2077*y(1)**4*y(4) + 2655*y(1)**3*y(2)**2 + 4010*y(1)**3*y(2)*y(3) + 2005*y(1)**3*y(2)*y(4) + 1460*y(1)**3*y(3)**2 + 1460*y(1)**3*y(3)*y(4) + 415*y(1)**3*y(4)**2 + 1800*y(1)**2*y(2)**3 & !& + + 4000*y(1)**2*y(2)**2*y(3) + 2000*y(1)**2*y(2)**2*y(4) + 2850*y(1)**2*y(2)*y(3)**2 + 2850*y(1)**2*y(2)*y(3)*y(4) + 790*y(1)**2*y(2)*y(4)**2 + 650*y(1)**2*y(3)**3 + 975*y(1)**2*y(3)**2*y(4) + 535*y(1)**2*y(3)*y(4)**2 + 105*y(1)**2*y(4)**3 + 270*y(1)*y(2)**4 & !& + + 720*y(1)*y(2)**3*y(3) + 360*y(1)*y(2)**3*y(4) + 645*y(1)*y(2)**2*y(3)**2 + 645*y(1)*y(2)**2*y(3)*y(4) + 165*y(1)*y(2)**2*y(4)**2 + 210*y(1)*y(2)*y(3)**3 + 315*y(1)*y(2)*y(3)**2*y(4) + 155*y(1)*y(2)*y(3)*y(4)**2 + 25*y(1)*y(2)*y(4)**3 + 15*y(1)*y(3)**4 & !& + + 30*y(1)*y(3)**3*y(4) + 20*y(1)*y(3)**2*y(4)**2 + 5*y(1)*y(3)*y(4)**3 + 90*y(2)**5 + 300*y(2)**4*y(3) + 150*y(2)**4*y(4) + 360*y(2)**3*y(3)**2 + 360*y(2)**3*y(3)*y(4) + 90*y(2)**3*y(4)**2 + 180*y(2)**2*y(3)**3 + 270*y(2)**2*y(3)**2*y(4) + 130*y(2)**2*y(3)*y(4)**2 & !& + + 20*y(2)**2*y(4)**3 + 30*y(2)*y(3)**4 + 60*y(2)*y(3)**3*y(4) + 40*y(2)*y(3)**2*y(4)**2 + 10*y(2)*y(3)*y(4)**3))/(5*(y(1) + y(2))*(y(2) + y(3))*(y(1) + y(2) + y(3))**2*(y(2) + y(3) + y(4))*(y(1) + y(2) + y(3) + y(4))**2) !& + beta_coef_${XYZ}$ (i + 1, 0, 5) = (4*y(1)**2*(996*y(1)**4 + 675*y(1)**3*y(2) + 450*y(1)**3*y(3) + 225*y(1)**3*y(4) + 600*y(1)**2*y(2)**2 + 800*y(1)**2*y(2)*y(3) + 400*y(1)**2*y(2)*y(4) + 260*y(1)**2*y(3)**2 + 260*y(1)**2*y(3)*y(4) + 60*y(1)**2*y(4)**2 + 135*y(1)*y(2)**3 + 270*y(1)*y(2)**2*y(3) & !& + + 135*y(1)*y(2)**2*y(4) + 165*y(1)*y(2)*y(3)**2 + 165*y(1)*y(2)*y(3)*y(4) + 30*y(1)*y(2)*y(4)**2 + 30*y(1)*y(3)**3 + 45*y(1)*y(3)**2*y(4) + 15*y(1)*y(3)*y(4)**2 + 45*y(2)**4 + 120*y(2)**3*y(3) + 60*y(2)**3*y(4) + 110*y(2)**2*y(3)**2 + 110*y(2)**2*y(3)*y(4) & !& + + 20*y(2)**2*y(4)**2 + 40*y(2)*y(3)**3 + 60*y(2)*y(3)**2*y(4) + 20*y(2)*y(3)*y(4)**2 + 5*y(3)**4 + 10*y(3)**3*y(4) + 5*y(3)**2*y(4)**2))/(5*(y(1) + y(2))**2*(y(1) + y(2) + y(3))**2*(y(1) + y(2) + y(3) + y(4))**2) !& + end do - else ! TENO (only supports uniform grid) + + else ! TENO (only supports uniform grid) ! (Fu, et al., 2016) Table 2 (for right flux) - d_cbL_${XYZ}$ (0,:) = 18._wp/35._wp - d_cbL_${XYZ}$ (1,:) = 3._wp/35._wp - d_cbL_${XYZ}$ (2,:) = 9._wp/35._wp - d_cbL_${XYZ}$ (3,:) = 1._wp/35._wp - d_cbL_${XYZ}$ (4,:) = 4._wp/35._wp - - d_cbR_${XYZ}$ (0,:) = 18._wp/35._wp - d_cbR_${XYZ}$ (1,:) = 9._wp/35._wp - d_cbR_${XYZ}$ (2,:) = 3._wp/35._wp - d_cbR_${XYZ}$ (3,:) = 4._wp/35._wp - d_cbR_${XYZ}$ (4,:) = 1._wp/35._wp + d_cbL_${XYZ}$ (0, :) = 18._wp/35._wp + d_cbL_${XYZ}$ (1, :) = 3._wp/35._wp + d_cbL_${XYZ}$ (2, :) = 9._wp/35._wp + d_cbL_${XYZ}$ (3, :) = 1._wp/35._wp + d_cbL_${XYZ}$ (4, :) = 4._wp/35._wp + + d_cbR_${XYZ}$ (0, :) = 18._wp/35._wp + d_cbR_${XYZ}$ (1, :) = 9._wp/35._wp + d_cbR_${XYZ}$ (2, :) = 3._wp/35._wp + d_cbR_${XYZ}$ (3, :) = 4._wp/35._wp + d_cbR_${XYZ}$ (4, :) = 1._wp/35._wp + end if end if + end if #:endfor if (weno_dir == 1) then - $:GPU_UPDATE(device='[poly_coef_cbL_x, poly_coef_cbR_x, d_cbL_x, d_cbR_x, beta_coef_x]') - else if (weno_dir == 2) then - $:GPU_UPDATE(device='[poly_coef_cbL_y, poly_coef_cbR_y, d_cbL_y, d_cbR_y, beta_coef_y]') + $:GPU_UPDATE(device='[poly_coef_cbL_x,poly_coef_cbR_x,d_cbL_x,d_cbR_x,beta_coef_x]') + elseif (weno_dir == 2) then + $:GPU_UPDATE(device='[poly_coef_cbL_y,poly_coef_cbR_y,d_cbL_y,d_cbR_y,beta_coef_y]') else - $:GPU_UPDATE(device='[poly_coef_cbL_z, poly_coef_cbR_z, d_cbL_z, d_cbR_z, beta_coef_z]') + $:GPU_UPDATE(device='[poly_coef_cbL_z,poly_coef_cbR_z,d_cbL_z,d_cbR_z,beta_coef_z]') end if ! Nullifying WENO coefficients and cell-boundary locations pointers @@ -856,44 +625,46 @@ contains end subroutine s_compute_weno_coefficients - !> Perform WENO reconstruction of left and right cell-boundary values from cell-averaged variables - subroutine s_weno(v_vf, vL_rs_vf_x, vL_rs_vf_y, vL_rs_vf_z, vR_rs_vf_x, vR_rs_vf_y, vR_rs_vf_z, weno_dir, is1_weno_d, & - - & is2_weno_d, is3_weno_d) + !> @brief Performs WENO reconstruction of left and right cell-boundary values from cell-averaged variables. + subroutine s_weno(v_vf, vL_rs_vf_x, vL_rs_vf_y, vL_rs_vf_z, vR_rs_vf_x, vR_rs_vf_y, vR_rs_vf_z, & + weno_dir, & + is1_weno_d, is2_weno_d, is3_weno_d) - type(scalar_field), dimension(1:), intent(in) :: v_vf - real(wp), dimension(idwbuff(1)%beg:,idwbuff(2)%beg:,idwbuff(3)%beg:,1:), intent(inout) :: vL_rs_vf_x, vL_rs_vf_y, vL_rs_vf_z - real(wp), dimension(idwbuff(1)%beg:,idwbuff(2)%beg:,idwbuff(3)%beg:,1:), intent(inout) :: vR_rs_vf_x, vR_rs_vf_y, vR_rs_vf_z - integer, intent(in) :: weno_dir - type(int_bounds_info), intent(in) :: is1_weno_d, is2_weno_d, is3_weno_d + type(scalar_field), dimension(1:), intent(in) :: v_vf + real(wp), dimension(idwbuff(1)%beg:, idwbuff(2)%beg:, idwbuff(3)%beg:, 1:), intent(inout) :: vL_rs_vf_x, vL_rs_vf_y, vL_rs_vf_z + real(wp), dimension(idwbuff(1)%beg:, idwbuff(2)%beg:, idwbuff(3)%beg:, 1:), intent(inout) :: vR_rs_vf_x, vR_rs_vf_y, vR_rs_vf_z + integer, intent(in) :: weno_dir + type(int_bounds_info), intent(in) :: is1_weno_d, is2_weno_d, is3_weno_d #:if not MFC_CASE_OPTIMIZATION and USING_AMD real(wp), dimension(-3:2) :: dvd - real(wp), dimension(0:4) :: poly - real(wp), dimension(0:4) :: alpha - real(wp), dimension(0:4) :: omega - real(wp), dimension(0:4) :: beta - real(wp), dimension(0:4) :: delta + real(wp), dimension(0:4) :: poly + real(wp), dimension(0:4) :: alpha + real(wp), dimension(0:4) :: omega + real(wp), dimension(0:4) :: beta + real(wp), dimension(0:4) :: delta #:else real(wp), dimension(-weno_polyn:weno_polyn - 1) :: dvd - real(wp), dimension(0:weno_num_stencils) :: poly - real(wp), dimension(0:weno_num_stencils) :: alpha - real(wp), dimension(0:weno_num_stencils) :: omega - real(wp), dimension(0:weno_num_stencils) :: beta - real(wp), dimension(0:weno_num_stencils) :: delta + real(wp), dimension(0:weno_num_stencils) :: poly + real(wp), dimension(0:weno_num_stencils) :: alpha + real(wp), dimension(0:weno_num_stencils) :: omega + real(wp), dimension(0:weno_num_stencils) :: beta + real(wp), dimension(0:weno_num_stencils) :: delta #:endif - real(wp), dimension(-3:3) :: v !< temporary field value array for clarity (WENO7 only) - real(wp) :: tau - integer :: i, j, k, l, q + real(wp), dimension(-3:3) :: v ! temporary field value array for clarity (WENO7 only) + real(wp) :: tau + + integer :: i, j, k, l, q is1_weno = is1_weno_d is2_weno = is2_weno_d is3_weno = is3_weno_d - $:GPU_UPDATE(device='[is1_weno, is2_weno, is3_weno]') + $:GPU_UPDATE(device='[is1_weno,is2_weno,is3_weno]') if (weno_order /= 1 .or. dummy) then - call s_initialize_weno(v_vf, weno_dir) + call s_initialize_weno(v_vf, & + weno_dir) end if if (weno_order == 1 .or. dummy) then @@ -941,7 +712,7 @@ contains if (weno_order == 3 .or. dummy) then #:for WENO_DIR, XYZ in [(1, 'x'), (2, 'y'), (3, 'z')] if (weno_dir == ${WENO_DIR}$) then - $:GPU_PARALLEL_LOOP(collapse=4,private='[beta, dvd, poly, omega, alpha, tau]') + $:GPU_PARALLEL_LOOP(collapse=4,private='[beta,dvd,poly,omega,alpha,tau]') do l = is3_weno%beg, is3_weno%end do k = is2_weno%beg, is2_weno%end do j = is1_weno%beg, is1_weno%end @@ -952,34 +723,36 @@ contains omega(:) = 0._wp beta(:) = weno_eps - dvd(0) = v_rs_ws_${XYZ}$ (j + 1, k, l, i) - v_rs_ws_${XYZ}$ (j, k, l, i) - dvd(-1) = v_rs_ws_${XYZ}$ (j, k, l, i) - v_rs_ws_${XYZ}$ (j - 1, k, l, i) + dvd(0) = v_rs_ws_${XYZ}$ (j + 1, k, l, i) & + - v_rs_ws_${XYZ}$ (j, k, l, i) + dvd(-1) = v_rs_ws_${XYZ}$ (j, k, l, i) & + - v_rs_ws_${XYZ}$ (j - 1, k, l, i) - poly(0) = v_rs_ws_${XYZ}$ (j, k, l, i) + poly_coef_cbL_${XYZ}$ (j, 0, 0)*dvd(0) - poly(1) = v_rs_ws_${XYZ}$ (j, k, l, i) + poly_coef_cbL_${XYZ}$ (j, 1, 0)*dvd(-1) + poly(0) = v_rs_ws_${XYZ}$ (j, k, l, i) & + + poly_coef_cbL_${XYZ}$ (j, 0, 0)*dvd(0) + poly(1) = v_rs_ws_${XYZ}$ (j, k, l, i) & + + poly_coef_cbL_${XYZ}$ (j, 1, 0)*dvd(-1) - beta(0) = beta_coef_${XYZ}$ (j, 0, 0)*dvd(0)*dvd(0) + weno_eps - beta(1) = beta_coef_${XYZ}$ (j, 1, 0)*dvd(-1)*dvd(-1) + weno_eps + beta(0) = beta_coef_${XYZ}$ (j, 0, 0)*dvd(0)*dvd(0) & + + weno_eps + beta(1) = beta_coef_${XYZ}$ (j, 1, 0)*dvd(-1)*dvd(-1) & + + weno_eps if (wenojs) then - alpha(0:weno_num_stencils) = d_cbL_${XYZ}$ (0:weno_num_stencils, & - & j)/(beta(0:weno_num_stencils)**2._wp) - else if (mapped_weno) then - alpha(0:weno_num_stencils) = d_cbL_${XYZ}$ (0:weno_num_stencils, & - & j)/(beta(0:weno_num_stencils)**2._wp) + alpha(0:weno_num_stencils) = d_cbL_${XYZ}$ (0:weno_num_stencils, j)/(beta(0:weno_num_stencils)**2._wp) + + elseif (mapped_weno) then + alpha(0:weno_num_stencils) = d_cbL_${XYZ}$ (0:weno_num_stencils, j)/(beta(0:weno_num_stencils)**2._wp) omega = alpha/sum(alpha) - alpha(0:weno_num_stencils) = (d_cbL_${XYZ}$ (0:weno_num_stencils, & - & j)*(1._wp + d_cbL_${XYZ}$ (0:weno_num_stencils, & - & j) - 3._wp*omega(0:weno_num_stencils)) + omega(0:weno_num_stencils)**2._wp) & - & *(omega(0:weno_num_stencils)/(d_cbL_${XYZ}$ (0:weno_num_stencils, & - & j)**2._wp + omega(0:weno_num_stencils)*(1._wp & - & - 2._wp*d_cbL_${XYZ}$ (0:weno_num_stencils,j)))) - else if (wenoz) then + alpha(0:weno_num_stencils) = (d_cbL_${XYZ}$ (0:weno_num_stencils, j)*(1._wp + d_cbL_${XYZ}$ (0:weno_num_stencils, j) - 3._wp*omega(0:weno_num_stencils)) + omega(0:weno_num_stencils)**2._wp) & + *(omega(0:weno_num_stencils)/(d_cbL_${XYZ}$ (0:weno_num_stencils, j)**2._wp + omega(0:weno_num_stencils)*(1._wp - 2._wp*d_cbL_${XYZ}$ (0:weno_num_stencils, j)))) + + elseif (wenoz) then ! Borges, et al. (2008) tau = abs(beta(1) - beta(0)) - alpha(0:weno_num_stencils) = d_cbL_${XYZ}$ (0:weno_num_stencils, & - & j)*(1._wp + tau/beta(0:weno_num_stencils)) + alpha(0:weno_num_stencils) = d_cbL_${XYZ}$ (0:weno_num_stencils, j)*(1._wp + tau/beta(0:weno_num_stencils)) + end if omega = alpha/sum(alpha) @@ -988,30 +761,30 @@ contains ! reconstruct from right side - poly(0) = v_rs_ws_${XYZ}$ (j, k, l, i) + poly_coef_cbR_${XYZ}$ (j, 0, 0)*dvd(0) - poly(1) = v_rs_ws_${XYZ}$ (j, k, l, i) + poly_coef_cbR_${XYZ}$ (j, 1, 0)*dvd(-1) + poly(0) = v_rs_ws_${XYZ}$ (j, k, l, i) & + + poly_coef_cbR_${XYZ}$ (j, 0, 0)*dvd(0) + poly(1) = v_rs_ws_${XYZ}$ (j, k, l, i) & + + poly_coef_cbR_${XYZ}$ (j, 1, 0)*dvd(-1) if (wenojs) then - alpha(0:weno_num_stencils) = d_cbR_${XYZ}$ (0:weno_num_stencils, & - & j)/(beta(0:weno_num_stencils)**2._wp) - else if (mapped_weno) then - alpha(0:weno_num_stencils) = d_cbR_${XYZ}$ (0:weno_num_stencils, & - & j)/(beta(0:weno_num_stencils)**2._wp) + alpha(0:weno_num_stencils) = d_cbR_${XYZ}$ (0:weno_num_stencils, j)/(beta(0:weno_num_stencils)**2._wp) + + elseif (mapped_weno) then + alpha(0:weno_num_stencils) = d_cbR_${XYZ}$ (0:weno_num_stencils, j)/(beta(0:weno_num_stencils)**2._wp) omega = alpha/sum(alpha) - alpha(0:weno_num_stencils) = (d_cbR_${XYZ}$ (0:weno_num_stencils, & - & j)*(1._wp + d_cbR_${XYZ}$ (0:weno_num_stencils, & - & j) - 3._wp*omega(0:weno_num_stencils)) + omega(0:weno_num_stencils)**2._wp) & - & *(omega(0:weno_num_stencils)/(d_cbR_${XYZ}$ (0:weno_num_stencils, & - & j)**2._wp + omega(0:weno_num_stencils)*(1._wp & - & - 2._wp*d_cbR_${XYZ}$ (0:weno_num_stencils,j)))) - else if (wenoz) then - alpha(0:weno_num_stencils) = d_cbR_${XYZ}$ (0:weno_num_stencils, & - & j)*(1._wp + tau/beta(0:weno_num_stencils)) + alpha(0:weno_num_stencils) = (d_cbR_${XYZ}$ (0:weno_num_stencils, j)*(1._wp + d_cbR_${XYZ}$ (0:weno_num_stencils, j) - 3._wp*omega(0:weno_num_stencils)) + omega(0:weno_num_stencils)**2._wp) & + *(omega(0:weno_num_stencils)/(d_cbR_${XYZ}$ (0:weno_num_stencils, j)**2._wp + omega(0:weno_num_stencils)*(1._wp - 2._wp*d_cbR_${XYZ}$ (0:weno_num_stencils, j)))) + + elseif (wenoz) then + + alpha(0:weno_num_stencils) = d_cbR_${XYZ}$ (0:weno_num_stencils, j)*(1._wp + tau/beta(0:weno_num_stencils)) + end if omega = alpha/sum(alpha) vR_rs_vf_${XYZ}$ (j, k, l, i) = omega(0)*poly(0) + omega(1)*poly(1) + end do end do end do @@ -1024,7 +797,7 @@ contains #:if not MFC_CASE_OPTIMIZATION or weno_num_stencils > 1 #:for WENO_DIR, XYZ in [(1, 'x'), (2, 'y'), (3, 'z')] if (weno_dir == ${WENO_DIR}$) then - $:GPU_PARALLEL_LOOP(collapse=3,private='[dvd, poly, beta, alpha, omega, tau, delta, q]') + $:GPU_PARALLEL_LOOP(collapse=3,private='[dvd,poly,beta,alpha,omega,tau,delta,q]') do l = is3_weno%beg, is3_weno%end do k = is2_weno%beg, is2_weno%end do j = is1_weno%beg, is1_weno%end @@ -1037,66 +810,76 @@ contains delta(:) = 0._wp beta(:) = weno_eps - dvd(1) = v_rs_ws_${XYZ}$ (j + 2, k, l, i) - v_rs_ws_${XYZ}$ (j + 1, k, l, i) - dvd(0) = v_rs_ws_${XYZ}$ (j + 1, k, l, i) - v_rs_ws_${XYZ}$ (j, k, l, i) - dvd(-1) = v_rs_ws_${XYZ}$ (j, k, l, i) - v_rs_ws_${XYZ}$ (j - 1, k, l, i) - dvd(-2) = v_rs_ws_${XYZ}$ (j - 1, k, l, i) - v_rs_ws_${XYZ}$ (j - 2, k, l, i) - - poly(0) = v_rs_ws_${XYZ}$ (j, k, l, i) + poly_coef_cbL_${XYZ}$ (j, 0, & - & 0)*dvd(1) + poly_coef_cbL_${XYZ}$ (j, 0, 1)*dvd(0) - poly(1) = v_rs_ws_${XYZ}$ (j, k, l, i) + poly_coef_cbL_${XYZ}$ (j, 1, & - & 0)*dvd(0) + poly_coef_cbL_${XYZ}$ (j, 1, 1)*dvd(-1) - poly(2) = v_rs_ws_${XYZ}$ (j, k, l, i) + poly_coef_cbL_${XYZ}$ (j, 2, & - & 0)*dvd(-1) + poly_coef_cbL_${XYZ}$ (j, 2, 1)*dvd(-2) - - beta(0) = beta_coef_${XYZ}$ (j, 0, 0)*dvd(1)*dvd(1) + beta_coef_${XYZ}$ (j, 0, & - & 1)*dvd(1)*dvd(0) + beta_coef_${XYZ}$ (j, 0, 2)*dvd(0)*dvd(0) + weno_eps - beta(1) = beta_coef_${XYZ}$ (j, 1, 0)*dvd(0)*dvd(0) + beta_coef_${XYZ}$ (j, 1, & - & 1)*dvd(0)*dvd(-1) + beta_coef_${XYZ}$ (j, 1, 2)*dvd(-1)*dvd(-1) + weno_eps - beta(2) = beta_coef_${XYZ}$ (j, 2, 0)*dvd(-1)*dvd(-1) + beta_coef_${XYZ}$ (j, 2, & - & 1)*dvd(-1)*dvd(-2) + beta_coef_${XYZ}$ (j, 2, 2)*dvd(-2)*dvd(-2) + weno_eps + dvd(1) = v_rs_ws_${XYZ}$ (j + 2, k, l, i) & + - v_rs_ws_${XYZ}$ (j + 1, k, l, i) + dvd(0) = v_rs_ws_${XYZ}$ (j + 1, k, l, i) & + - v_rs_ws_${XYZ}$ (j, k, l, i) + dvd(-1) = v_rs_ws_${XYZ}$ (j, k, l, i) & + - v_rs_ws_${XYZ}$ (j - 1, k, l, i) + dvd(-2) = v_rs_ws_${XYZ}$ (j - 1, k, l, i) & + - v_rs_ws_${XYZ}$ (j - 2, k, l, i) + + poly(0) = v_rs_ws_${XYZ}$ (j, k, l, i) & + + poly_coef_cbL_${XYZ}$ (j, 0, 0)*dvd(1) & + + poly_coef_cbL_${XYZ}$ (j, 0, 1)*dvd(0) + poly(1) = v_rs_ws_${XYZ}$ (j, k, l, i) & + + poly_coef_cbL_${XYZ}$ (j, 1, 0)*dvd(0) & + + poly_coef_cbL_${XYZ}$ (j, 1, 1)*dvd(-1) + poly(2) = v_rs_ws_${XYZ}$ (j, k, l, i) & + + poly_coef_cbL_${XYZ}$ (j, 2, 0)*dvd(-1) & + + poly_coef_cbL_${XYZ}$ (j, 2, 1)*dvd(-2) + + beta(0) = beta_coef_${XYZ}$ (j, 0, 0)*dvd(1)*dvd(1) & + + beta_coef_${XYZ}$ (j, 0, 1)*dvd(1)*dvd(0) & + + beta_coef_${XYZ}$ (j, 0, 2)*dvd(0)*dvd(0) & + + weno_eps + beta(1) = beta_coef_${XYZ}$ (j, 1, 0)*dvd(0)*dvd(0) & + + beta_coef_${XYZ}$ (j, 1, 1)*dvd(0)*dvd(-1) & + + beta_coef_${XYZ}$ (j, 1, 2)*dvd(-1)*dvd(-1) & + + weno_eps + beta(2) = beta_coef_${XYZ}$ (j, 2, 0)*dvd(-1)*dvd(-1) & + + beta_coef_${XYZ}$ (j, 2, 1)*dvd(-1)*dvd(-2) & + + beta_coef_${XYZ}$ (j, 2, 2)*dvd(-2)*dvd(-2) & + + weno_eps if (wenojs) then - alpha(0:weno_num_stencils) = d_cbL_${XYZ}$ (0:weno_num_stencils, & - & j)/(beta(0:weno_num_stencils)**2._wp) - else if (mapped_weno) then - alpha(0:weno_num_stencils) = d_cbL_${XYZ}$ (0:weno_num_stencils, & - & j)/(beta(0:weno_num_stencils)**2._wp) + alpha(0:weno_num_stencils) = d_cbL_${XYZ}$ (0:weno_num_stencils, j)/(beta(0:weno_num_stencils)**2._wp) + + elseif (mapped_weno) then + alpha(0:weno_num_stencils) = d_cbL_${XYZ}$ (0:weno_num_stencils, j)/(beta(0:weno_num_stencils)**2._wp) omega = alpha/sum(alpha) - alpha(0:weno_num_stencils) = (d_cbL_${XYZ}$ (0:weno_num_stencils, & - & j)*(1._wp + d_cbL_${XYZ}$ (0:weno_num_stencils, & - & j) - 3._wp*omega(0:weno_num_stencils)) + omega(0:weno_num_stencils)**2._wp) & - & *(omega(0:weno_num_stencils)/(d_cbL_${XYZ}$ (0:weno_num_stencils, & - & j)**2._wp + omega(0:weno_num_stencils)*(1._wp & - & - 2._wp*d_cbL_${XYZ}$ (0:weno_num_stencils,j)))) - else if (wenoz) then + alpha(0:weno_num_stencils) = (d_cbL_${XYZ}$ (0:weno_num_stencils, j)*(1._wp + d_cbL_${XYZ}$ (0:weno_num_stencils, j) - 3._wp*omega(0:weno_num_stencils)) + omega(0:weno_num_stencils)**2._wp) & + *(omega(0:weno_num_stencils)/(d_cbL_${XYZ}$ (0:weno_num_stencils, j)**2._wp + omega(0:weno_num_stencils)*(1._wp - 2._wp*d_cbL_${XYZ}$ (0:weno_num_stencils, j)))) + + elseif (wenoz) then + ! Borges, et al. (2008) - tau = abs(beta(2) - beta(0)) ! Equation 25 + tau = abs(beta(2) - beta(0)) ! Equation 25 $:GPU_LOOP(parallelism='[seq]') do q = 0, weno_num_stencils - alpha(q) = d_cbL_${XYZ}$ (q, j)*(1._wp + (tau/beta(q))) - ! Equation 28 (note: weno_eps was already added to beta) + alpha(q) = d_cbL_${XYZ}$ (q, j)*(1._wp + (tau/beta(q))) ! Equation 28 (note: weno_eps was already added to beta) end do - else if (teno) then - ! Fu, et al. (2016) Fu''s code: https://dx.doi.org/10.13140/RG.2.2.36250.34247 + + elseif (teno) then + ! Fu, et al. (2016) + ! Fu''s code: https://dx.doi.org/10.13140/RG.2.2.36250.34247 tau = abs(beta(2) - beta(0)) $:GPU_LOOP(parallelism='[seq]') do q = 0, weno_num_stencils - alpha(q) = 1._wp + tau/beta(q) ! Equation 22 (reuse alpha as gamma; pick C=1 & q=6) - alpha(q) = (alpha(q)**3._wp) & - & **2._wp ! Equation 22 cont. (some CPU compilers cannot optimize x**6.0) + alpha(q) = 1._wp + tau/beta(q) ! Equation 22 (reuse alpha as gamma; pick C=1 & q=6) + alpha(q) = (alpha(q)**3._wp)**2._wp ! Equation 22 cont. (some CPU compilers cannot optimize x**6.0) end do - omega = alpha/sum(alpha) ! Equation 25 (reuse omega as xi) + omega = alpha/sum(alpha) ! Equation 25 (reuse omega as xi) $:GPU_LOOP(parallelism='[seq]') do q = 0, weno_num_stencils - if (omega(q) < teno_CT) then ! Equation 26 + if (omega(q) < teno_CT) then ! Equation 26 delta(q) = 0._wp else delta(q) = 1._wp end if - alpha(q) = delta(q)*d_cbL_${XYZ}$ (q, j) ! Equation 27 + alpha(q) = delta(q)*d_cbL_${XYZ}$ (q, j) ! Equation 27 end do end if @@ -1106,32 +889,33 @@ contains ! reconstruct from right side - poly(0) = v_rs_ws_${XYZ}$ (j, k, l, i) + poly_coef_cbR_${XYZ}$ (j, 0, & - & 0)*dvd(1) + poly_coef_cbR_${XYZ}$ (j, 0, 1)*dvd(0) - poly(1) = v_rs_ws_${XYZ}$ (j, k, l, i) + poly_coef_cbR_${XYZ}$ (j, 1, & - & 0)*dvd(0) + poly_coef_cbR_${XYZ}$ (j, 1, 1)*dvd(-1) - poly(2) = v_rs_ws_${XYZ}$ (j, k, l, i) + poly_coef_cbR_${XYZ}$ (j, 2, & - & 0)*dvd(-1) + poly_coef_cbR_${XYZ}$ (j, 2, 1)*dvd(-2) + poly(0) = v_rs_ws_${XYZ}$ (j, k, l, i) & + + poly_coef_cbR_${XYZ}$ (j, 0, 0)*dvd(1) & + + poly_coef_cbR_${XYZ}$ (j, 0, 1)*dvd(0) + poly(1) = v_rs_ws_${XYZ}$ (j, k, l, i) & + + poly_coef_cbR_${XYZ}$ (j, 1, 0)*dvd(0) & + + poly_coef_cbR_${XYZ}$ (j, 1, 1)*dvd(-1) + poly(2) = v_rs_ws_${XYZ}$ (j, k, l, i) & + + poly_coef_cbR_${XYZ}$ (j, 2, 0)*dvd(-1) & + + poly_coef_cbR_${XYZ}$ (j, 2, 1)*dvd(-2) if (wenojs) then - alpha(0:weno_num_stencils) = d_cbR_${XYZ}$ (0:weno_num_stencils, & - & j)/(beta(0:weno_num_stencils)**2._wp) - else if (mapped_weno) then - alpha(0:weno_num_stencils) = d_cbR_${XYZ}$ (0:weno_num_stencils, & - & j)/(beta(0:weno_num_stencils)**2._wp) + alpha(0:weno_num_stencils) = d_cbR_${XYZ}$ (0:weno_num_stencils, j)/(beta(0:weno_num_stencils)**2._wp) + + elseif (mapped_weno) then + alpha(0:weno_num_stencils) = d_cbR_${XYZ}$ (0:weno_num_stencils, j)/(beta(0:weno_num_stencils)**2._wp) omega = alpha/sum(alpha) - alpha(0:weno_num_stencils) = (d_cbR_${XYZ}$ (0:weno_num_stencils, & - & j)*(1._wp + d_cbR_${XYZ}$ (0:weno_num_stencils, & - & j) - 3._wp*omega(0:weno_num_stencils)) + omega(0:weno_num_stencils)**2._wp) & - & *(omega(0:weno_num_stencils)/(d_cbR_${XYZ}$ (0:weno_num_stencils, & - & j)**2._wp + omega(0:weno_num_stencils)*(1._wp & - & - 2._wp*d_cbR_${XYZ}$ (0:weno_num_stencils,j)))) - else if (wenoz) then + alpha(0:weno_num_stencils) = (d_cbR_${XYZ}$ (0:weno_num_stencils, j)*(1._wp + d_cbR_${XYZ}$ (0:weno_num_stencils, j) - 3._wp*omega(0:weno_num_stencils)) + omega(0:weno_num_stencils)**2._wp) & + *(omega(0:weno_num_stencils)/(d_cbR_${XYZ}$ (0:weno_num_stencils, j)**2._wp + omega(0:weno_num_stencils)*(1._wp - 2._wp*d_cbR_${XYZ}$ (0:weno_num_stencils, j)))) + + elseif (wenoz) then + $:GPU_LOOP(parallelism='[seq]') do q = 0, weno_num_stencils alpha(q) = d_cbR_${XYZ}$ (q, j)*(1._wp + (tau/beta(q))) end do - else if (teno) then + + elseif (teno) then $:GPU_LOOP(parallelism='[seq]') do q = 0, weno_num_stencils alpha(q) = delta(q)*d_cbR_${XYZ}$ (q, j) @@ -1141,6 +925,7 @@ contains omega = alpha/sum(alpha) vR_rs_vf_${XYZ}$ (j, k, l, i) = omega(0)*poly(0) + omega(1)*poly(1) + omega(2)*poly(2) + end do end do end do @@ -1148,7 +933,8 @@ contains $:END_GPU_PARALLEL_LOOP() if (mp_weno) then - call s_preserve_monotonicity(v_rs_ws_${XYZ}$, vL_rs_vf_${XYZ}$, vR_rs_vf_${XYZ}$) + call s_preserve_monotonicity(v_rs_ws_${XYZ}$, vL_rs_vf_${XYZ}$, & + vR_rs_vf_${XYZ}$) end if end if #:endfor @@ -1158,144 +944,161 @@ contains #:if not MFC_CASE_OPTIMIZATION or weno_num_stencils > 2 #:for WENO_DIR, XYZ in [(1, 'x'), (2, 'y'), (3, 'z')] if (weno_dir == ${WENO_DIR}$) then - $:GPU_PARALLEL_LOOP(collapse=3,private='[poly, beta, alpha, omega, tau, delta, dvd, v, q]') + $:GPU_PARALLEL_LOOP(collapse=3,private='[poly,beta,alpha,omega,tau,delta,dvd,v,q]') do l = is3_weno%beg, is3_weno%end do k = is2_weno%beg, is2_weno%end do j = is1_weno%beg, is1_weno%end $:GPU_LOOP(parallelism='[seq]') do i = 1, v_size + alpha(:) = 0._wp omega(:) = 0._wp delta(:) = 0._wp beta(:) = weno_eps - if (teno) v = v_rs_ws_${XYZ}$ (j - 3:j + 3,k, l, & - & i) ! temporary field value array for clarity + if (teno) v = v_rs_ws_${XYZ}$ (j - 3:j + 3, k, l, i) ! temporary field value array for clarity if (.not. teno) then - dvd(2) = v_rs_ws_${XYZ}$ (j + 3, k, l, i) - v_rs_ws_${XYZ}$ (j + 2, k, l, i) - dvd(1) = v_rs_ws_${XYZ}$ (j + 2, k, l, i) - v_rs_ws_${XYZ}$ (j + 1, k, l, i) - dvd(0) = v_rs_ws_${XYZ}$ (j + 1, k, l, i) - v_rs_ws_${XYZ}$ (j, k, l, i) - dvd(-1) = v_rs_ws_${XYZ}$ (j, k, l, i) - v_rs_ws_${XYZ}$ (j - 1, k, l, i) - dvd(-2) = v_rs_ws_${XYZ}$ (j - 1, k, l, i) - v_rs_ws_${XYZ}$ (j - 2, k, l, i) - dvd(-3) = v_rs_ws_${XYZ}$ (j - 2, k, l, i) - v_rs_ws_${XYZ}$ (j - 3, k, l, i) - - poly(3) = v_rs_ws_${XYZ}$ (j, k, l, i) + poly_coef_cbL_${XYZ}$ (j, 0, & - & 0)*dvd(2) + poly_coef_cbL_${XYZ}$ (j, 0, 1)*dvd(1) + poly_coef_cbL_${XYZ}$ (j, & - & 0, 2)*dvd(0) - poly(2) = v_rs_ws_${XYZ}$ (j, k, l, i) + poly_coef_cbL_${XYZ}$ (j, 1, & - & 0)*dvd(1) + poly_coef_cbL_${XYZ}$ (j, 1, 1)*dvd(0) + poly_coef_cbL_${XYZ}$ (j, & - & 1, 2)*dvd(-1) - poly(1) = v_rs_ws_${XYZ}$ (j, k, l, i) + poly_coef_cbL_${XYZ}$ (j, 2, & - & 0)*dvd(0) + poly_coef_cbL_${XYZ}$ (j, 2, & - & 1)*dvd(-1) + poly_coef_cbL_${XYZ}$ (j, 2, 2)*dvd(-2) - poly(0) = v_rs_ws_${XYZ}$ (j, k, l, i) + poly_coef_cbL_${XYZ}$ (j, 3, & - & 0)*dvd(-1) + poly_coef_cbL_${XYZ}$ (j, 3, & - & 1)*dvd(-2) + poly_coef_cbL_${XYZ}$ (j, 3, 2)*dvd(-3) + dvd(2) = v_rs_ws_${XYZ}$ (j + 3, k, l, i) & + - v_rs_ws_${XYZ}$ (j + 2, k, l, i) + dvd(1) = v_rs_ws_${XYZ}$ (j + 2, k, l, i) & + - v_rs_ws_${XYZ}$ (j + 1, k, l, i) + dvd(0) = v_rs_ws_${XYZ}$ (j + 1, k, l, i) & + - v_rs_ws_${XYZ}$ (j, k, l, i) + dvd(-1) = v_rs_ws_${XYZ}$ (j, k, l, i) & + - v_rs_ws_${XYZ}$ (j - 1, k, l, i) + dvd(-2) = v_rs_ws_${XYZ}$ (j - 1, k, l, i) & + - v_rs_ws_${XYZ}$ (j - 2, k, l, i) + dvd(-3) = v_rs_ws_${XYZ}$ (j - 2, k, l, i) & + - v_rs_ws_${XYZ}$ (j - 3, k, l, i) + + poly(3) = v_rs_ws_${XYZ}$ (j, k, l, i) & + + poly_coef_cbL_${XYZ}$ (j, 0, 0)*dvd(2) & + + poly_coef_cbL_${XYZ}$ (j, 0, 1)*dvd(1) & + + poly_coef_cbL_${XYZ}$ (j, 0, 2)*dvd(0) + poly(2) = v_rs_ws_${XYZ}$ (j, k, l, i) & + + poly_coef_cbL_${XYZ}$ (j, 1, 0)*dvd(1) & + + poly_coef_cbL_${XYZ}$ (j, 1, 1)*dvd(0) & + + poly_coef_cbL_${XYZ}$ (j, 1, 2)*dvd(-1) + poly(1) = v_rs_ws_${XYZ}$ (j, k, l, i) & + + poly_coef_cbL_${XYZ}$ (j, 2, 0)*dvd(0) & + + poly_coef_cbL_${XYZ}$ (j, 2, 1)*dvd(-1) & + + poly_coef_cbL_${XYZ}$ (j, 2, 2)*dvd(-2) + poly(0) = v_rs_ws_${XYZ}$ (j, k, l, i) & + + poly_coef_cbL_${XYZ}$ (j, 3, 0)*dvd(-1) & + + poly_coef_cbL_${XYZ}$ (j, 3, 1)*dvd(-2) & + + poly_coef_cbL_${XYZ}$ (j, 3, 2)*dvd(-3) + else #:if not MFC_CASE_OPTIMIZATION or weno_num_stencils > 3 - ! (Fu, et al., 2016) Table 1 Note: Unlike TENO5, TENO7 stencils differ from WENO7 - ! stencils See Figure 2 (right) for right-sided flux (at i+1/2) Here we need the - ! left-sided flux, so we flip the weights with respect to the x=i point But we need - ! to keep the stencil order to reuse the beta coefficients - poly(0) = (2._wp*v(-1) + 5._wp*v(0) - 1._wp*v(1))/6._wp - poly(1) = (11._wp*v(0) - 7._wp*v(1) + 2._wp*v(2))/6._wp - poly(2) = (-1._wp*v(-2) + 5._wp*v(-1) + 2._wp*v(0))/6._wp - poly(3) = (25._wp*v(0) - 23._wp*v(1) + 13._wp*v(2) - 3._wp*v(3))/12._wp - poly(4) = (1._wp*v(-3) - 5._wp*v(-2) + 13._wp*v(-1) + 3._wp*v(0))/12._wp + ! (Fu, et al., 2016) Table 1 + ! Note: Unlike TENO5, TENO7 stencils differ from WENO7 stencils + ! See Figure 2 (right) for right-sided flux (at i+1/2) + ! Here we need the left-sided flux, so we flip the weights with respect to the x=i point + ! But we need to keep the stencil order to reuse the beta coefficients + poly(0) = ( 2._wp*v(-1) + 5._wp*v( 0) - 1._wp*v( 1)) / 6._wp !& + poly(1) = (11._wp*v( 0) - 7._wp*v( 1) + 2._wp*v( 2)) / 6._wp !& + poly(2) = (-1._wp*v(-2) + 5._wp*v(-1) + 2._wp*v( 0)) / 6._wp !& + poly(3) = (25._wp*v( 0) - 23._wp*v( 1) + 13._wp*v( 2) - 3._wp*v( 3)) / 12._wp !& + poly(4) = ( 1._wp*v(-3) - 5._wp*v(-2) + 13._wp*v(-1) + 3._wp*v( 0)) / 12._wp !& #:endif end if if (.not. teno) then - beta(3) = beta_coef_${XYZ}$ (j, 0, 0)*dvd(2)*dvd(2) + beta_coef_${XYZ}$ (j, 0, & - & 1)*dvd(2)*dvd(1) + beta_coef_${XYZ}$ (j, 0, & - & 2)*dvd(2)*dvd(0) + beta_coef_${XYZ}$ (j, 0, & - & 3)*dvd(1)*dvd(1) + beta_coef_${XYZ}$ (j, 0, & - & 4)*dvd(1)*dvd(0) + beta_coef_${XYZ}$ (j, 0, 5)*dvd(0)*dvd(0) + weno_eps - - beta(2) = beta_coef_${XYZ}$ (j, 1, 0)*dvd(1)*dvd(1) + beta_coef_${XYZ}$ (j, 1, & - & 1)*dvd(1)*dvd(0) + beta_coef_${XYZ}$ (j, 1, & - & 2)*dvd(1)*dvd(-1) + beta_coef_${XYZ}$ (j, 1, & - & 3)*dvd(0)*dvd(0) + beta_coef_${XYZ}$ (j, 1, & - & 4)*dvd(0)*dvd(-1) + beta_coef_${XYZ}$ (j, 1, 5)*dvd(-1)*dvd(-1) + weno_eps - - beta(1) = beta_coef_${XYZ}$ (j, 2, 0)*dvd(0)*dvd(0) + beta_coef_${XYZ}$ (j, 2, & - & 1)*dvd(0)*dvd(-1) + beta_coef_${XYZ}$ (j, 2, & - & 2)*dvd(0)*dvd(-2) + beta_coef_${XYZ}$ (j, 2, & - & 3)*dvd(-1)*dvd(-1) + beta_coef_${XYZ}$ (j, 2, & - & 4)*dvd(-1)*dvd(-2) + beta_coef_${XYZ}$ (j, 2, 5)*dvd(-2)*dvd(-2) + weno_eps - - beta(0) = beta_coef_${XYZ}$ (j, 3, 0)*dvd(-1)*dvd(-1) + beta_coef_${XYZ}$ (j, 3, & - & 1)*dvd(-1)*dvd(-2) + beta_coef_${XYZ}$ (j, 3, & - & 2)*dvd(-1)*dvd(-3) + beta_coef_${XYZ}$ (j, 3, & - & 3)*dvd(-2)*dvd(-2) + beta_coef_${XYZ}$ (j, 3, & - & 4)*dvd(-2)*dvd(-3) + beta_coef_${XYZ}$ (j, 3, 5)*dvd(-3)*dvd(-3) + weno_eps - else ! TENO + + beta(3) = beta_coef_${XYZ}$ (j, 0, 0)*dvd(2)*dvd(2) & + + beta_coef_${XYZ}$ (j, 0, 1)*dvd(2)*dvd(1) & + + beta_coef_${XYZ}$ (j, 0, 2)*dvd(2)*dvd(0) & + + beta_coef_${XYZ}$ (j, 0, 3)*dvd(1)*dvd(1) & + + beta_coef_${XYZ}$ (j, 0, 4)*dvd(1)*dvd(0) & + + beta_coef_${XYZ}$ (j, 0, 5)*dvd(0)*dvd(0) & + + weno_eps + + beta(2) = beta_coef_${XYZ}$ (j, 1, 0)*dvd(1)*dvd(1) & + + beta_coef_${XYZ}$ (j, 1, 1)*dvd(1)*dvd(0) & + + beta_coef_${XYZ}$ (j, 1, 2)*dvd(1)*dvd(-1) & + + beta_coef_${XYZ}$ (j, 1, 3)*dvd(0)*dvd(0) & + + beta_coef_${XYZ}$ (j, 1, 4)*dvd(0)*dvd(-1) & + + beta_coef_${XYZ}$ (j, 1, 5)*dvd(-1)*dvd(-1) & + + weno_eps + + beta(1) = beta_coef_${XYZ}$ (j, 2, 0)*dvd(0)*dvd(0) & + + beta_coef_${XYZ}$ (j, 2, 1)*dvd(0)*dvd(-1) & + + beta_coef_${XYZ}$ (j, 2, 2)*dvd(0)*dvd(-2) & + + beta_coef_${XYZ}$ (j, 2, 3)*dvd(-1)*dvd(-1) & + + beta_coef_${XYZ}$ (j, 2, 4)*dvd(-1)*dvd(-2) & + + beta_coef_${XYZ}$ (j, 2, 5)*dvd(-2)*dvd(-2) & + + weno_eps + + beta(0) = beta_coef_${XYZ}$ (j, 3, 0)*dvd(-1)*dvd(-1) & + + beta_coef_${XYZ}$ (j, 3, 1)*dvd(-1)*dvd(-2) & + + beta_coef_${XYZ}$ (j, 3, 2)*dvd(-1)*dvd(-3) & + + beta_coef_${XYZ}$ (j, 3, 3)*dvd(-2)*dvd(-2) & + + beta_coef_${XYZ}$ (j, 3, 4)*dvd(-2)*dvd(-3) & + + beta_coef_${XYZ}$ (j, 3, 5)*dvd(-3)*dvd(-3) & + + weno_eps + + else ! TENO #:if not MFC_CASE_OPTIMIZATION or weno_num_stencils > 3 - ! High-Order Low-Dissipation Targeted ENO Schemes for Ideal Magnetohydrodynamics (Fu - ! & Tang, 2019) Section 3.2 - beta(0) = 13._wp/12._wp*(v(-1) - 2._wp*v(0) + v(1))**2._wp + ((v(-1) - v(1)) & - & **2._wp)/4._wp + weno_eps - beta(1) = 13._wp/12._wp*(v(0) - 2._wp*v(1) + v(2))**2._wp + ((3._wp*v(0) & - & - 4._wp*v(1) + v(2))**2._wp)/4._wp + weno_eps - beta(2) = 13._wp/12._wp*(v(-2) - 2._wp*v(-1) + v(0))**2._wp + ((v(-2) & - & - 4._wp*v(-1) + 3._wp*v(0))**2._wp)/4._wp + weno_eps - - beta(3) = (v(0)*(2107._wp*v(0) - 9402._wp*v(1) + 7042._wp*v(2) - 1854._wp*v(3)) & - & + v(1)*(11003._wp*v(1) - 17246._wp*v(2) + 4642._wp*v(3)) + v(2) & - & *(7043._wp*v(2) - 3882._wp*v(3)) + v(3)*(547._wp*v(3)))/240._wp + weno_eps - - beta(4) = (v(-3)*(547._wp*v(-3) - 3882._wp*v(-2) + 4642._wp*v(-1) - 1854._wp*v(0)) & - & + v(-2)*(7043._wp*v(-2) - 17246._wp*v(-1) + 7042._wp*v(0)) + v(-1) & - & *(11003._wp*v(-1) - 9402._wp*v(0)) + v(0)*(2107._wp*v(0)))/240._wp + weno_eps + ! High-Order Low-Dissipation Targeted ENO Schemes for Ideal Magnetohydrodynamics (Fu & Tang, 2019) Section 3.2 + beta(0) = 13._wp/12._wp*(v(-1) - 2._wp*v( 0) + v( 1))**2._wp + (( v(-1) - v( 1))**2._wp)/4._wp + weno_eps !& + beta(1) = 13._wp/12._wp*(v( 0) - 2._wp*v( 1) + v( 2))**2._wp + ((3._wp*v( 0) - 4._wp*v( 1) + v( 2))**2._wp)/4._wp + weno_eps !& + beta(2) = 13._wp/12._wp*(v(-2) - 2._wp*v(-1) + v( 0))**2._wp + (( v(-2) - 4._wp*v(-1) + 3._wp*v( 0))**2._wp)/4._wp + weno_eps !& + + beta(3) = ( v( 0)*(2107._wp*v( 0) - 9402._wp*v( 1) + 7042._wp*v( 2) - 1854._wp*v( 3)) & !& + + v( 1)*( 11003._wp*v( 1) - 17246._wp*v( 2) + 4642._wp*v( 3)) & !& + + v( 2)*( 7043._wp*v( 2) - 3882._wp*v( 3)) & !& + + v( 3)*( 547._wp*v( 3)) ) / 240._wp & !& + + weno_eps !& + + beta(4) = ( v(-3)*(547._wp*v(-3) - 3882._wp*v(-2) + 4642._wp*v(-1) - 1854._wp*v( 0)) & !& + + v(-2)*( 7043._wp*v(-2) - 17246._wp*v(-1) + 7042._wp*v( 0)) & !& + + v(-1)*( 11003._wp*v(-1) - 9402._wp*v( 0)) & !& + + v( 0)*( 2107._wp*v( 0)) ) / 240._wp & !& + + weno_eps !& #:endif end if if (wenojs) then - alpha(0:weno_num_stencils) = d_cbL_${XYZ}$ (0:weno_num_stencils, & - & j)/(beta(0:weno_num_stencils)**2._wp) - else if (mapped_weno) then - alpha(0:weno_num_stencils) = d_cbL_${XYZ}$ (0:weno_num_stencils, & - & j)/(beta(0:weno_num_stencils)**2._wp) + alpha(0:weno_num_stencils) = d_cbL_${XYZ}$ (0:weno_num_stencils, j)/(beta(0:weno_num_stencils)**2._wp) + + elseif (mapped_weno) then + alpha(0:weno_num_stencils) = d_cbL_${XYZ}$ (0:weno_num_stencils, j)/(beta(0:weno_num_stencils)**2._wp) omega = alpha/sum(alpha) - alpha(0:weno_num_stencils) = (d_cbL_${XYZ}$ (0:weno_num_stencils, & - & j)*(1._wp + d_cbL_${XYZ}$ (0:weno_num_stencils, & - & j) - 3._wp*omega(0:weno_num_stencils)) + omega(0:weno_num_stencils)**2._wp) & - & *(omega(0:weno_num_stencils)/(d_cbL_${XYZ}$ (0:weno_num_stencils, & - & j)**2._wp + omega(0:weno_num_stencils)*(1._wp & - & - 2._wp*d_cbL_${XYZ}$ (0:weno_num_stencils,j)))) - else if (wenoz) then - ! Castro, et al. (2010) Don & Borges (2013) also helps - tau = abs(beta(3) - beta(0)) ! Equation 50 + alpha(0:weno_num_stencils) = (d_cbL_${XYZ}$ (0:weno_num_stencils, j)*(1._wp + d_cbL_${XYZ}$ (0:weno_num_stencils, j) - 3._wp*omega(0:weno_num_stencils)) + omega(0:weno_num_stencils)**2._wp) & + *(omega(0:weno_num_stencils)/(d_cbL_${XYZ}$ (0:weno_num_stencils, j)**2._wp + omega(0:weno_num_stencils)*(1._wp - 2._wp*d_cbL_${XYZ}$ (0:weno_num_stencils, j)))) + + elseif (wenoz) then + ! Castro, et al. (2010) + ! Don & Borges (2013) also helps + tau = abs(beta(3) - beta(0)) ! Equation 50 $:GPU_LOOP(parallelism='[seq]') do q = 0, weno_num_stencils - alpha(q) = d_cbL_${XYZ}$ (q, & - & j)*(1._wp + (tau/beta(q))**wenoz_q) ! wenoz_q = 2,3,4 for stability + alpha(q) = d_cbL_${XYZ}$ (q, j)*(1._wp + (tau/beta(q))**wenoz_q) ! wenoz_q = 2,3,4 for stability end do - else if (teno) then + + elseif (teno) then #:if not MFC_CASE_OPTIMIZATION or weno_num_stencils > 3 - tau = abs(beta(4) - beta(3)) ! Note the reordering of stencils + tau = abs(beta(4) - beta(3)) ! Note the reordering of stencils alpha = 1._wp + tau/beta - alpha = (alpha**3._wp)**2._wp ! some CPU compilers cannot optimize x**6.0 + alpha = (alpha**3._wp)**2._wp ! some CPU compilers cannot optimize x**6.0 omega = alpha/sum(alpha) $:GPU_LOOP(parallelism='[seq]') do q = 0, weno_num_stencils - if (omega(q) < teno_CT) then ! Equation 26 + if (omega(q) < teno_CT) then ! Equation 26 delta(q) = 0._wp else delta(q) = 1._wp end if - alpha(q) = delta(q)*d_cbL_${XYZ}$ (q, j) ! Equation 27 + alpha(q) = delta(q)*d_cbL_${XYZ}$ (q, j) ! Equation 27 end do #:endif end if omega = alpha/sum(alpha) - vL_rs_vf_${XYZ}$ (j, k, l, & - & i) = omega(0)*poly(0) + omega(1)*poly(1) + omega(2)*poly(2) + omega(3) & - & *poly(3) + vL_rs_vf_${XYZ}$ (j, k, l, i) = omega(0)*poly(0) + omega(1)*poly(1) + omega(2)*poly(2) + omega(3)*poly(3) if (teno) then #:if not MFC_CASE_OPTIMIZATION or weno_num_stencils > 3 @@ -1304,48 +1107,49 @@ contains end if if (.not. teno) then - poly(3) = v_rs_ws_${XYZ}$ (j, k, l, i) + poly_coef_cbR_${XYZ}$ (j, 0, & - & 0)*dvd(2) + poly_coef_cbR_${XYZ}$ (j, 0, 1)*dvd(1) + poly_coef_cbR_${XYZ}$ (j, & - & 0, 2)*dvd(0) - poly(2) = v_rs_ws_${XYZ}$ (j, k, l, i) + poly_coef_cbR_${XYZ}$ (j, 1, & - & 0)*dvd(1) + poly_coef_cbR_${XYZ}$ (j, 1, 1)*dvd(0) + poly_coef_cbR_${XYZ}$ (j, & - & 1, 2)*dvd(-1) - poly(1) = v_rs_ws_${XYZ}$ (j, k, l, i) + poly_coef_cbR_${XYZ}$ (j, 2, & - & 0)*dvd(0) + poly_coef_cbR_${XYZ}$ (j, 2, & - & 1)*dvd(-1) + poly_coef_cbR_${XYZ}$ (j, 2, 2)*dvd(-2) - poly(0) = v_rs_ws_${XYZ}$ (j, k, l, i) + poly_coef_cbR_${XYZ}$ (j, 3, & - & 0)*dvd(-1) + poly_coef_cbR_${XYZ}$ (j, 3, & - & 1)*dvd(-2) + poly_coef_cbR_${XYZ}$ (j, 3, 2)*dvd(-3) + poly(3) = v_rs_ws_${XYZ}$ (j, k, l, i) & + + poly_coef_cbR_${XYZ}$ (j, 0, 0)*dvd(2) & + + poly_coef_cbR_${XYZ}$ (j, 0, 1)*dvd(1) & + + poly_coef_cbR_${XYZ}$ (j, 0, 2)*dvd(0) + poly(2) = v_rs_ws_${XYZ}$ (j, k, l, i) & + + poly_coef_cbR_${XYZ}$ (j, 1, 0)*dvd(1) & + + poly_coef_cbR_${XYZ}$ (j, 1, 1)*dvd(0) & + + poly_coef_cbR_${XYZ}$ (j, 1, 2)*dvd(-1) + poly(1) = v_rs_ws_${XYZ}$ (j, k, l, i) & + + poly_coef_cbR_${XYZ}$ (j, 2, 0)*dvd(0) & + + poly_coef_cbR_${XYZ}$ (j, 2, 1)*dvd(-1) & + + poly_coef_cbR_${XYZ}$ (j, 2, 2)*dvd(-2) + poly(0) = v_rs_ws_${XYZ}$ (j, k, l, i) & + + poly_coef_cbR_${XYZ}$ (j, 3, 0)*dvd(-1) & + + poly_coef_cbR_${XYZ}$ (j, 3, 1)*dvd(-2) & + + poly_coef_cbR_${XYZ}$ (j, 3, 2)*dvd(-3) else #:if not MFC_CASE_OPTIMIZATION or weno_num_stencils > 3 - poly(0) = (-1._wp*v(-1) + 5._wp*v(0) + 2._wp*v(1))/6._wp - poly(1) = (2._wp*v(0) + 5._wp*v(1) - 1._wp*v(2))/6._wp - poly(2) = (2._wp*v(-2) - 7._wp*v(-1) + 11._wp*v(0))/6._wp - poly(3) = (3._wp*v(0) + 13._wp*v(1) - 5._wp*v(2) + 1._wp*v(3))/12._wp - poly(4) = (-3._wp*v(-3) + 13._wp*v(-2) - 23._wp*v(-1) + 25._wp*v(0))/12._wp + poly(0) = (-1._wp*v(-1) + 5._wp*v( 0) + 2._wp*v( 1)) / 6._wp !& + poly(1) = ( 2._wp*v( 0) + 5._wp*v( 1) - 1._wp*v( 2)) / 6._wp !& + poly(2) = ( 2._wp*v(-2) - 7._wp*v(-1) + 11._wp*v( 0)) / 6._wp !& + poly(3) = ( 3._wp*v( 0) + 13._wp*v( 1) - 5._wp*v( 2) + 1._wp*v( 3)) / 12._wp !& + poly(4) = (-3._wp*v(-3) + 13._wp*v(-2) - 23._wp*v(-1) + 25._wp*v( 0)) / 12._wp !& #:endif end if if (wenojs) then - alpha(0:weno_num_stencils) = d_cbR_${XYZ}$ (0:weno_num_stencils, & - & j)/(beta(0:weno_num_stencils)**2._wp) - else if (mapped_weno) then - alpha(0:weno_num_stencils) = d_cbR_${XYZ}$ (0:weno_num_stencils, & - & j)/(beta(0:weno_num_stencils)**2._wp) + alpha(0:weno_num_stencils) = d_cbR_${XYZ}$ (0:weno_num_stencils, j)/(beta(0:weno_num_stencils)**2._wp) + + elseif (mapped_weno) then + alpha(0:weno_num_stencils) = d_cbR_${XYZ}$ (0:weno_num_stencils, j)/(beta(0:weno_num_stencils)**2._wp) omega = alpha/sum(alpha) - alpha(0:weno_num_stencils) = (d_cbR_${XYZ}$ (0:weno_num_stencils, & - & j)*(1._wp + d_cbR_${XYZ}$ (0:weno_num_stencils, & - & j) - 3._wp*omega(0:weno_num_stencils)) + omega(0:weno_num_stencils)**2._wp) & - & *(omega(0:weno_num_stencils)/(d_cbR_${XYZ}$ (0:weno_num_stencils, & - & j)**2._wp + omega(0:weno_num_stencils)*(1._wp & - & - 2._wp*d_cbR_${XYZ}$ (0:weno_num_stencils,j)))) - else if (wenoz) then + alpha(0:weno_num_stencils) = (d_cbR_${XYZ}$ (0:weno_num_stencils, j)*(1._wp + d_cbR_${XYZ}$ (0:weno_num_stencils, j) - 3._wp*omega(0:weno_num_stencils)) + omega(0:weno_num_stencils)**2._wp) & + *(omega(0:weno_num_stencils)/(d_cbR_${XYZ}$ (0:weno_num_stencils, j)**2._wp + omega(0:weno_num_stencils)*(1._wp - 2._wp*d_cbR_${XYZ}$ (0:weno_num_stencils, j)))) + + elseif (wenoz) then + $:GPU_LOOP(parallelism='[seq]') do q = 0, weno_num_stencils - alpha(q) = d_cbR_${XYZ}$ (q, & - & j)*(1._wp + (tau/beta(q))**wenoz_q) ! wenoz_q = 2,3,4 for stability + alpha(q) = d_cbR_${XYZ}$ (q, j)*(1._wp + (tau/beta(q))**wenoz_q) ! wenoz_q = 2,3,4 for stability end do - else if (teno) then + + elseif (teno) then $:GPU_LOOP(parallelism='[seq]') do q = 0, weno_num_stencils alpha(q) = delta(q)*d_cbR_${XYZ}$ (q, j) @@ -1354,15 +1158,14 @@ contains omega = alpha/sum(alpha) - vR_rs_vf_${XYZ}$ (j, k, l, & - & i) = omega(0)*poly(0) + omega(1)*poly(1) + omega(2)*poly(2) + omega(3) & - & *poly(3) + vR_rs_vf_${XYZ}$ (j, k, l, i) = omega(0)*poly(0) + omega(1)*poly(1) + omega(2)*poly(2) + omega(3)*poly(3) if (teno) then #:if not MFC_CASE_OPTIMIZATION or weno_num_stencils > 3 vR_rs_vf_${XYZ}$ (j, k, l, i) = vR_rs_vf_${XYZ}$ (j, k, l, i) + omega(4)*poly(4) #:endif end if + end do end do end do @@ -1373,22 +1176,34 @@ contains #:endif end if - if (int_comp) then - call s_interface_compression(vL_rs_vf_x, vL_rs_vf_y, vL_rs_vf_z, vR_rs_vf_x, vR_rs_vf_y, vR_rs_vf_z, weno_dir, & - & is1_weno_d, is2_weno_d, is3_weno_d) + if (int_comp .and. v_size >= advxe) then + call s_interface_compression(vL_rs_vf_x, vL_rs_vf_y, vL_rs_vf_z, & + vR_rs_vf_x, vR_rs_vf_y, vR_rs_vf_z, & + weno_dir, is1_weno_d, is2_weno_d, is3_weno_d) end if end subroutine s_weno - !> Set up the WENO reconstruction for a given direction - subroutine s_initialize_weno(v_vf, weno_dir) + !> The computation of parameters, the allocation of memory, + !! the association of pointers and/or the execution of any + !! other procedures that are required for the setup of the + !! WENO reconstruction. + !! @param v_vf Cell-averaged variables + !! @param weno_dir Coordinate direction of the WENO reconstruction + subroutine s_initialize_weno(v_vf, & + weno_dir) - type(scalar_field), dimension(:), intent(in) :: v_vf - integer, intent(in) :: weno_dir - integer :: j, k, l, q + type(scalar_field), dimension(:), intent(IN) :: v_vf - ! Determine WENO-reconstructed variables and map coordinate directions + integer, intent(IN) :: weno_dir + integer :: j, k, l, q + + ! Determining the number of cell-average variables which will be + ! WENO-reconstructed and mapping their indical bounds in the x-, + ! y- and z-directions to those in the s1-, s2- and s3-directions + ! as to reshape the inputted data in the coordinate direction of + ! the WENO reconstruction v_size = ubound(v_vf, 1) $:GPU_UPDATE(device='[v_size]') @@ -1442,24 +1257,47 @@ contains end subroutine s_initialize_weno - !> Enforce monotonicity-preserving bounds on the WENO reconstruction + !> The goal of this subroutine is to ensure that the WENO + !! reconstruction is monotonic. The latter is achieved by + !! enforcing monotonicity preserving bounds of Suresh and + !! Huynh (1997). The resulting MPWENO reconstruction, see + !! Balsara and Shu (2000), ensures that the reconstructed + !! values do not reside outside the range spanned by WENO + !! stencil. + !! @param v_rs_ws Reshaped cell-averaged variables + !! @param vL_rs_vf Left WENO reconstructed cell-boundary values + !! @param vR_rs_vf Right WENO reconstructed cell-boundary values subroutine s_preserve_monotonicity(v_rs_ws, vL_rs_vf, vR_rs_vf) - real(wp), dimension(idwbuff(1)%beg:,idwbuff(2)%beg:,idwbuff(3)%beg:,1:), intent(in) :: v_rs_ws - real(wp), dimension(idwbuff(1)%beg:,idwbuff(2)%beg:,idwbuff(3)%beg:,1:), intent(inout) :: vL_rs_vf, vR_rs_vf + real(wp), dimension(idwbuff(1)%beg:, idwbuff(2)%beg:, idwbuff(3)%beg:, 1:), intent(IN) :: v_rs_ws + real(wp), dimension(idwbuff(1)%beg:, idwbuff(2)%beg:, idwbuff(3)%beg:, 1:), intent(INOUT) :: vL_rs_vf, vR_rs_vf + integer :: i, j, k, l - real(wp), dimension(-1:1) :: d !< Curvature measures at the zone centers - real(wp) :: d_MD, d_LC !< Median (md) curvature and large curvature (LC) measures - ! The left and right upper bounds (UL), medians, large curvatures, minima, and maxima of the WENO-reconstructed values of - ! the cell- average variables. + + real(wp), dimension(-1:1) :: d !< Curvature measures at the zone centers + + real(wp) :: d_MD, d_LC !< + !! Median (md) curvature and large curvature (LC) measures + + ! The left and right upper bounds (UL), medians, large curvatures, + ! minima, and maxima of the WENO-reconstructed values of the cell- + ! average variables. real(wp) :: vL_UL, vR_UL real(wp) :: vL_MD, vR_MD real(wp) :: vL_LC, vR_LC real(wp) :: vL_min, vR_min real(wp) :: vL_max, vR_max - ! Monotonicity-preserving bounds, Suresh & Huynh JCP (1997) - real(wp), parameter :: alpha = 2._wp !< Max CFL stability parameter (CFL < 1/(1+alpha)) - real(wp), parameter :: beta = 4._wp/3._wp !< Local curvature freedom parameter + + real(wp), parameter :: alpha = 2._wp !> + !! Determines the maximum Courant–Friedrichs–Lewy (CFL) number that + !! may be utilized with the scheme. In theory, for stability, a CFL + !! number less than 1/(1+alpha) is necessary. The default value for + !! alpha is 2. + + real(wp), parameter :: beta = 4._wp/3._wp !< + !! Determines the amount of freedom available from utilizing a large + !! value for the local curvature. The default value for beta is 4/3. + real(wp), parameter :: alpha_mp = 2._wp real(wp), parameter :: beta_mp = 4._wp/3._wp @@ -1468,65 +1306,121 @@ contains do k = is2_weno%beg, is2_weno%end do j = is1_weno%beg, is1_weno%end do i = 1, v_size - ! Second-order undivided differences for curvature estimation - d(-1) = v_rs_ws(j, k, l, i) + v_rs_ws(j - 2, k, l, i) - v_rs_ws(j - 1, k, l, i)*2._wp - d(0) = v_rs_ws(j + 1, k, l, i) + v_rs_ws(j - 1, k, l, i) - v_rs_ws(j, k, l, i)*2._wp - d(1) = v_rs_ws(j + 2, k, l, i) + v_rs_ws(j, k, l, i) - v_rs_ws(j + 1, k, l, i)*2._wp - - ! Median function for oscillation detection - d_MD = (sign(1._wp, 4._wp*d(-1) - d(0)) + sign(1._wp, 4._wp*d(0) - d(-1)))*abs((sign(1._wp, & - & 4._wp*d(-1) - d(0)) + sign(1._wp, d(-1)))*(sign(1._wp, 4._wp*d(-1) - d(0)) + sign(1._wp, & - & d(0))))*min(abs(4._wp*d(-1) - d(0)), abs(d(-1)), abs(4._wp*d(0) - d(-1)), abs(d(0)))/8._wp - - d_LC = (sign(1._wp, 4._wp*d(0) - d(1)) + sign(1._wp, 4._wp*d(1) - d(0)))*abs((sign(1._wp, & - & 4._wp*d(0) - d(1)) + sign(1._wp, d(0)))*(sign(1._wp, 4._wp*d(0) - d(1)) + sign(1._wp, & - & d(1))))*min(abs(4._wp*d(0) - d(1)), abs(d(0)), abs(4._wp*d(1) - d(0)), abs(d(1)))/8._wp - - vL_UL = v_rs_ws(j, k, l, i) - (v_rs_ws(j + 1, k, l, i) - v_rs_ws(j, k, l, i))*alpha_mp - - vL_MD = (v_rs_ws(j, k, l, i) + v_rs_ws(j - 1, k, l, i) - d_MD)*5.e-1_wp - - vL_LC = v_rs_ws(j, k, l, i) - (v_rs_ws(j + 1, k, l, i) - v_rs_ws(j, k, l, i))*5.e-1_wp + beta_mp*d_LC - - vL_min = max(min(v_rs_ws(j, k, l, i), v_rs_ws(j - 1, k, l, i), vL_MD), min(v_rs_ws(j, k, l, i), vL_UL, & - & vL_LC)) - - vL_max = min(max(v_rs_ws(j, k, l, i), v_rs_ws(j - 1, k, l, i), vL_MD), max(v_rs_ws(j, k, l, i), vL_UL, & - & vL_LC)) - - vL_rs_vf(j, k, l, i) = vL_rs_vf(j, k, l, i) + (sign(5.e-1_wp, vL_min - vL_rs_vf(j, k, l, & - & i)) + sign(5.e-1_wp, vL_max - vL_rs_vf(j, k, l, i)))*min(abs(vL_min - vL_rs_vf(j, k, l, i)), & - & abs(vL_max - vL_rs_vf(j, k, l, i))) + d(-1) = v_rs_ws(j, k, l, i) & + + v_rs_ws(j - 2, k, l, i) & + - v_rs_ws(j - 1, k, l, i) & + *2._wp + d(0) = v_rs_ws(j + 1, k, l, i) & + + v_rs_ws(j - 1, k, l, i) & + - v_rs_ws(j, k, l, i) & + *2._wp + d(1) = v_rs_ws(j + 2, k, l, i) & + + v_rs_ws(j, k, l, i) & + - v_rs_ws(j + 1, k, l, i) & + *2._wp + + d_MD = (sign(1._wp, 4._wp*d(-1) - d(0)) + sign(1._wp, 4._wp*d(0) - d(-1))) & + *abs((sign(1._wp, 4._wp*d(-1) - d(0)) + sign(1._wp, d(-1))) & + *(sign(1._wp, 4._wp*d(-1) - d(0)) + sign(1._wp, d(0)))) & + *min(abs(4._wp*d(-1) - d(0)), abs(d(-1)), & + abs(4._wp*d(0) - d(-1)), abs(d(0)))/8._wp + + d_LC = (sign(1._wp, 4._wp*d(0) - d(1)) + sign(1._wp, 4._wp*d(1) - d(0))) & + *abs((sign(1._wp, 4._wp*d(0) - d(1)) + sign(1._wp, d(0))) & + *(sign(1._wp, 4._wp*d(0) - d(1)) + sign(1._wp, d(1)))) & + *min(abs(4._wp*d(0) - d(1)), abs(d(0)), & + abs(4._wp*d(1) - d(0)), abs(d(1)))/8._wp + + vL_UL = v_rs_ws(j, k, l, i) & + - (v_rs_ws(j + 1, k, l, i) & + - v_rs_ws(j, k, l, i))*alpha_mp + + vL_MD = (v_rs_ws(j, k, l, i) & + + v_rs_ws(j - 1, k, l, i) & + - d_MD)*5.e-1_wp + + vL_LC = v_rs_ws(j, k, l, i) & + - (v_rs_ws(j + 1, k, l, i) & + - v_rs_ws(j, k, l, i))*5.e-1_wp + beta_mp*d_LC + + vL_min = max(min(v_rs_ws(j, k, l, i), & + v_rs_ws(j - 1, k, l, i), & + vL_MD), & + min(v_rs_ws(j, k, l, i), & + vL_UL, & + vL_LC)) + + vL_max = min(max(v_rs_ws(j, k, l, i), & + v_rs_ws(j - 1, k, l, i), & + vL_MD), & + max(v_rs_ws(j, k, l, i), & + vL_UL, & + vL_LC)) + + vL_rs_vf(j, k, l, i) = vL_rs_vf(j, k, l, i) & + + (sign(5.e-1_wp, vL_min - vL_rs_vf(j, k, l, i)) & + + sign(5.e-1_wp, vL_max - vL_rs_vf(j, k, l, i))) & + *min(abs(vL_min - vL_rs_vf(j, k, l, i)), & + abs(vL_max - vL_rs_vf(j, k, l, i))) ! END: Left Monotonicity Preserving Bound ! Right Monotonicity Preserving Bound - d(-1) = v_rs_ws(j, k, l, i) + v_rs_ws(j - 2, k, l, i) - v_rs_ws(j - 1, k, l, i)*2._wp - d(0) = v_rs_ws(j + 1, k, l, i) + v_rs_ws(j - 1, k, l, i) - v_rs_ws(j, k, l, i)*2._wp - d(1) = v_rs_ws(j + 2, k, l, i) + v_rs_ws(j, k, l, i) - v_rs_ws(j + 1, k, l, i)*2._wp - - d_MD = (sign(1._wp, 4._wp*d(0) - d(1)) + sign(1._wp, 4._wp*d(1) - d(0)))*abs((sign(1._wp, & - & 4._wp*d(0) - d(1)) + sign(1._wp, d(0)))*(sign(1._wp, 4._wp*d(0) - d(1)) + sign(1._wp, & - & d(1))))*min(abs(4._wp*d(0) - d(1)), abs(d(0)), abs(4._wp*d(1) - d(0)), abs(d(1)))/8._wp - - d_LC = (sign(1._wp, 4._wp*d(-1) - d(0)) + sign(1._wp, 4._wp*d(0) - d(-1)))*abs((sign(1._wp, & - & 4._wp*d(-1) - d(0)) + sign(1._wp, d(-1)))*(sign(1._wp, 4._wp*d(-1) - d(0)) + sign(1._wp, & - & d(0))))*min(abs(4._wp*d(-1) - d(0)), abs(d(-1)), abs(4._wp*d(0) - d(-1)), abs(d(0)))/8._wp - - vR_UL = v_rs_ws(j, k, l, i) + (v_rs_ws(j, k, l, i) - v_rs_ws(j - 1, k, l, i))*alpha_mp - - vR_MD = (v_rs_ws(j, k, l, i) + v_rs_ws(j + 1, k, l, i) - d_MD)*5.e-1_wp - - vR_LC = v_rs_ws(j, k, l, i) + (v_rs_ws(j, k, l, i) - v_rs_ws(j - 1, k, l, i))*5.e-1_wp + beta_mp*d_LC - - vR_min = max(min(v_rs_ws(j, k, l, i), v_rs_ws(j + 1, k, l, i), vR_MD), min(v_rs_ws(j, k, l, i), vR_UL, & - & vR_LC)) - - vR_max = min(max(v_rs_ws(j, k, l, i), v_rs_ws(j + 1, k, l, i), vR_MD), max(v_rs_ws(j, k, l, i), vR_UL, & - & vR_LC)) - - vR_rs_vf(j, k, l, i) = vR_rs_vf(j, k, l, i) + (sign(5.e-1_wp, vR_min - vR_rs_vf(j, k, l, & - & i)) + sign(5.e-1_wp, vR_max - vR_rs_vf(j, k, l, i)))*min(abs(vR_min - vR_rs_vf(j, k, l, i)), & - & abs(vR_max - vR_rs_vf(j, k, l, i))) + d(-1) = v_rs_ws(j, k, l, i) & + + v_rs_ws(j - 2, k, l, i) & + - v_rs_ws(j - 1, k, l, i) & + *2._wp + d(0) = v_rs_ws(j + 1, k, l, i) & + + v_rs_ws(j - 1, k, l, i) & + - v_rs_ws(j, k, l, i) & + *2._wp + d(1) = v_rs_ws(j + 2, k, l, i) & + + v_rs_ws(j, k, l, i) & + - v_rs_ws(j + 1, k, l, i) & + *2._wp + + d_MD = (sign(1._wp, 4._wp*d(0) - d(1)) + sign(1._wp, 4._wp*d(1) - d(0))) & + *abs((sign(1._wp, 4._wp*d(0) - d(1)) + sign(1._wp, d(0))) & + *(sign(1._wp, 4._wp*d(0) - d(1)) + sign(1._wp, d(1)))) & + *min(abs(4._wp*d(0) - d(1)), abs(d(0)), & + abs(4._wp*d(1) - d(0)), abs(d(1)))/8._wp + + d_LC = (sign(1._wp, 4._wp*d(-1) - d(0)) + sign(1._wp, 4._wp*d(0) - d(-1))) & + *abs((sign(1._wp, 4._wp*d(-1) - d(0)) + sign(1._wp, d(-1))) & + *(sign(1._wp, 4._wp*d(-1) - d(0)) + sign(1._wp, d(0)))) & + *min(abs(4._wp*d(-1) - d(0)), abs(d(-1)), & + abs(4._wp*d(0) - d(-1)), abs(d(0)))/8._wp + + vR_UL = v_rs_ws(j, k, l, i) & + + (v_rs_ws(j, k, l, i) & + - v_rs_ws(j - 1, k, l, i))*alpha_mp + + vR_MD = (v_rs_ws(j, k, l, i) & + + v_rs_ws(j + 1, k, l, i) & + - d_MD)*5.e-1_wp + + vR_LC = v_rs_ws(j, k, l, i) & + + (v_rs_ws(j, k, l, i) & + - v_rs_ws(j - 1, k, l, i))*5.e-1_wp + beta_mp*d_LC + + vR_min = max(min(v_rs_ws(j, k, l, i), & + v_rs_ws(j + 1, k, l, i), & + vR_MD), & + min(v_rs_ws(j, k, l, i), & + vR_UL, & + vR_LC)) + + vR_max = min(max(v_rs_ws(j, k, l, i), & + v_rs_ws(j + 1, k, l, i), & + vR_MD), & + max(v_rs_ws(j, k, l, i), & + vR_UL, & + vR_LC)) + + vR_rs_vf(j, k, l, i) = vR_rs_vf(j, k, l, i) & + + (sign(5.e-1_wp, vR_min - vR_rs_vf(j, k, l, i)) & + + sign(5.e-1_wp, vR_max - vR_rs_vf(j, k, l, i))) & + *min(abs(vR_min - vR_rs_vf(j, k, l, i)), & + abs(vR_max - vR_rs_vf(j, k, l, i))) ! END: Right Monotonicity Preserving Bound end do end do @@ -1536,13 +1430,14 @@ contains end subroutine s_preserve_monotonicity - !> Module deallocation and/or disassociation procedures + !> Module deallocation and/or disassociation procedures impure subroutine s_finalize_weno_module() if (weno_order == 1) return ! Deallocating the WENO-stencil of the WENO-reconstructed variables + !deallocate(vL_rs_vf_x, vR_rs_vf_x) @:DEALLOCATE(v_rs_ws_x) ! Deallocating WENO coefficients in x-direction @@ -1553,6 +1448,7 @@ contains ! Deallocating WENO coefficients in y-direction if (n == 0) return + !deallocate(vL_rs_vf_y, vR_rs_vf_y) @:DEALLOCATE(v_rs_ws_y) @:DEALLOCATE(poly_coef_cbL_y, poly_coef_cbR_y) @@ -1562,6 +1458,7 @@ contains ! Deallocating WENO coefficients in z-direction if (p == 0) return + !deallocate(vL_rs_vf_z, vR_rs_vf_z) @:DEALLOCATE(v_rs_ws_z) @:DEALLOCATE(poly_coef_cbL_z, poly_coef_cbR_z) diff --git a/src/simulation/p_main.fpp b/src/simulation/p_main.fpp index 1d0ad72035..e65722e191 100644 --- a/src/simulation/p_main.fpp +++ b/src/simulation/p_main.fpp @@ -2,40 +2,47 @@ !! @file !! @brief Contains program p_main -!> @brief Quasi-conservative, shock- and interface- capturing finite-volume scheme for the multicomponent Navier-Stokes equations. -!! The system is augmented with the relevant advection equations to capture the material interfaces and closed by the stiffened -!! equation of state as well as any required mixture relations. The effects of surface tension are included and modeled through a -!! volume force that acts across the diffuse material interface regions. The implementation specifics of surface tension may be -!! found in the work by Perigaud and Saurel (2005). Note that both viscous and capillarity effects are only available in the volume -!! fraction model. +!> @brief Quasi-conservative, shock- and interface- capturing finite-volume +!! scheme for the multicomponent Navier-Stokes equations. The system +!! is augmented with the relevant advection equations to capture the +!! material interfaces and closed by the stiffened equation of state +!! as well as any required mixture relations. The effects of surface +!! tension are included and modeled through a volume force that acts +!! across the diffuse material interface regions. The implementation +!! specifics of surface tension may be found in the work by Perigaud +!! and Saurel (2005). Note that both viscous and capillarity effects +!! are only available in the volume fraction model. program p_main - use m_global_parameters + use m_global_parameters !< Definitions of the global parameters + use m_start_up + use m_time_steppers + use m_nvtx implicit none - integer :: t_step !< Iterator for the time-stepping loop - real(wp) :: time_avg, time_final - real(wp) :: io_time_avg, io_time_final + integer :: t_step !< Iterator for the time-stepping loop + real(wp) :: time_avg, time_final + real(wp) :: io_time_avg, io_time_final real(wp), allocatable, dimension(:) :: proc_time real(wp), allocatable, dimension(:) :: io_proc_time - logical :: file_exists - real(wp) :: start, finish - integer :: nt + logical :: file_exists + real(wp) :: start, finish + integer :: nt call system_clock(COUNT=cpu_start, COUNT_RATE=cpu_rate) call nvtxStartRange("INIT") - ! Initialize MPI + !Initialize MPI call nvtxStartRange("INIT-MPI") call s_initialize_mpi_domain() call nvtxEndRange - ! Initialize Modules + !Initialize Modules call nvtxStartRange("INIT-MODULES") call s_initialize_modules() call nvtxEndRange @@ -61,21 +68,22 @@ program p_main finaltime = t_step_stop*dt end if - call nvtxEndRange ! INIT + call nvtxEndRange ! INIT call nvtxStartRange("SIMULATION-TIME-MARCH") ! Time-stepping Loop do + if (cfl_dt) then if (mytime >= t_stop) then - call s_save_performance_metrics(time_avg, time_final, io_time_avg, io_time_final, proc_time, io_proc_time, & - & file_exists) + call s_save_performance_metrics(time_avg, time_final, io_time_avg, & + io_time_final, proc_time, io_proc_time, file_exists) exit end if else if (t_step == t_step_stop) then - call s_save_performance_metrics(time_avg, time_final, io_time_avg, io_time_final, proc_time, io_proc_time, & - & file_exists) + call s_save_performance_metrics(time_avg, time_final, io_time_avg, & + io_time_final, proc_time, io_proc_time, file_exists) exit end if end if @@ -95,11 +103,12 @@ program p_main call system_clock(cpu_end) end do - call nvtxEndRange ! Simulation + call nvtxEndRange ! Simulation deallocate (proc_time, io_proc_time) call nvtxStartRange("FINALIZE-MODULES") call s_finalize_modules() call nvtxEndRange + end program p_main diff --git a/src/syscheck/syscheck.fpp b/src/syscheck/syscheck.fpp index c3ecad2e02..75e18efc33 100644 --- a/src/syscheck/syscheck.fpp +++ b/src/syscheck/syscheck.fpp @@ -102,6 +102,7 @@ program syscheck @:LOG("") @:LOG("Syscheck: PASSED.") + end program syscheck subroutine assert(condition) diff --git a/tests/016C1B8B/golden-metadata.txt b/tests/016C1B8B/golden-metadata.txt index 4f3db90efb..c44c549346 100644 --- a/tests/016C1B8B/golden-metadata.txt +++ b/tests/016C1B8B/golden-metadata.txt @@ -1,16 +1,84 @@ -This file was created on 2026-02-25 22:34:58.244740. +This file was created on 2026-03-15 15:32:55.552143. mfc.sh: - Invocation: test --generate --only 016C1B8B -j 8 --no-build -- -c phoenix + Invocation: test --generate --only CE7B0BC7 016C1B8B -j 4 Lock: mpi=Yes & gpu=No & debug=No & gcov=No & unified=No & single=No & mixed=No & fastmath=No - Git: 0ce91cc551508e01d2fc4127caeb9ac010cfa258 on fix/time-stepping-order (dirty) + Git: 37668dcbdbf4d7402b2fc086a4b9767034ffb45a on moving-bubbles (dirty) + +pre_process: + + CMake Configuration: + + CMake v3.26.5 on atl1-1-02-002-28-2.pace.gatech.edu + + C : GNU v12.3.0 (/usr/local/pace-apps/spack/packages/linux-rhel9-x86_64_v3/gcc-11.3.1/gcc-12.3.0-ukkkutsxfl5kpnnaxflpkq2jtliwthfz/bin/gcc) + Fortran : GNU v12.3.0 (/usr/local/pace-apps/spack/packages/linux-rhel9-x86_64_v3/gcc-11.3.1/gcc-12.3.0-ukkkutsxfl5kpnnaxflpkq2jtliwthfz/bin/gfortran) + + PRE_PROCESS : ON + SIMULATION : OFF + POST_PROCESS : OFF + SYSCHECK : OFF + DOCUMENTATION : OFF + ALL : OFF + + MPI : ON + OpenACC : OFF + OpenMP : OFF + + Fypp : /storage/scratch1/6/sbryngelson3/MFC-ruff/build/venv/bin/fypp + Doxygen : + + Build Type : Release + + Configuration Environment: + + CC : /usr/local/pace-apps/spack/packages/linux-rhel9-x86_64_v3/gcc-11.3.1/gcc-12.3.0-ukkkutsxfl5kpnnaxflpkq2jtliwthfz/bin/gcc + CXX : /usr/local/pace-apps/spack/packages/linux-rhel9-x86_64_v3/gcc-11.3.1/gcc-12.3.0-ukkkutsxfl5kpnnaxflpkq2jtliwthfz/bin/g++ + FC : /usr/local/pace-apps/spack/packages/linux-rhel9-x86_64_v3/gcc-11.3.1/gcc-12.3.0-ukkkutsxfl5kpnnaxflpkq2jtliwthfz/bin/gfortran + OMPI_CC : + OMPI_CXX : + OMPI_FC : + +documentation: + + CMake Configuration: + + CMake v3.26.5 on atl1-1-02-002-23-1.pace.gatech.edu + + C : GNU v12.3.0 (/usr/local/pace-apps/spack/packages/linux-rhel9-x86_64_v3/gcc-11.3.1/gcc-12.3.0-ukkkutsxfl5kpnnaxflpkq2jtliwthfz/bin/gcc) + Fortran : GNU v12.3.0 (/usr/local/pace-apps/spack/packages/linux-rhel9-x86_64_v3/gcc-11.3.1/gcc-12.3.0-ukkkutsxfl5kpnnaxflpkq2jtliwthfz/bin/gfortran) + + PRE_PROCESS : OFF + SIMULATION : OFF + POST_PROCESS : OFF + SYSCHECK : OFF + DOCUMENTATION : ON + ALL : OFF + + MPI : ON + OpenACC : OFF + OpenMP : OFF + + Fypp : /storage/home/hcoda1/6/sbryngelson3/scratch/MFC-ruff/build/venv/bin/fypp + Doxygen : /storage/home/hcoda1/6/sbryngelson3/.local/bin/doxygen + + Build Type : Release + + Configuration Environment: + + CC : /usr/local/pace-apps/spack/packages/linux-rhel9-x86_64_v3/gcc-11.3.1/gcc-12.3.0-ukkkutsxfl5kpnnaxflpkq2jtliwthfz/bin/gcc + CXX : /usr/local/pace-apps/spack/packages/linux-rhel9-x86_64_v3/gcc-11.3.1/gcc-12.3.0-ukkkutsxfl5kpnnaxflpkq2jtliwthfz/bin/g++ + FC : /usr/local/pace-apps/spack/packages/linux-rhel9-x86_64_v3/gcc-11.3.1/gcc-12.3.0-ukkkutsxfl5kpnnaxflpkq2jtliwthfz/bin/gfortran + OMPI_CC : + OMPI_CXX : + OMPI_FC : simulation: CMake Configuration: - CMake v3.26.5 on atl1-1-02-007-5-2.pace.gatech.edu + CMake v3.26.5 on atl1-1-02-002-28-2.pace.gatech.edu C : GNU v12.3.0 (/usr/local/pace-apps/spack/packages/linux-rhel9-x86_64_v3/gcc-11.3.1/gcc-12.3.0-ukkkutsxfl5kpnnaxflpkq2jtliwthfz/bin/gcc) Fortran : GNU v12.3.0 (/usr/local/pace-apps/spack/packages/linux-rhel9-x86_64_v3/gcc-11.3.1/gcc-12.3.0-ukkkutsxfl5kpnnaxflpkq2jtliwthfz/bin/gfortran) @@ -26,7 +94,7 @@ simulation: OpenACC : OFF OpenMP : OFF - Fypp : /storage/home/hcoda1/6/sbryngelson3/scratch/MFC-prs/build/venv/bin/fypp + Fypp : /storage/scratch1/6/sbryngelson3/MFC-ruff/build/venv/bin/fypp Doxygen : Build Type : Release @@ -44,7 +112,7 @@ syscheck: CMake Configuration: - CMake v3.26.5 on atl1-1-02-007-5-2.pace.gatech.edu + CMake v3.26.5 on atl1-1-02-002-23-1.pace.gatech.edu C : GNU v12.3.0 (/usr/local/pace-apps/spack/packages/linux-rhel9-x86_64_v3/gcc-11.3.1/gcc-12.3.0-ukkkutsxfl5kpnnaxflpkq2jtliwthfz/bin/gcc) Fortran : GNU v12.3.0 (/usr/local/pace-apps/spack/packages/linux-rhel9-x86_64_v3/gcc-11.3.1/gcc-12.3.0-ukkkutsxfl5kpnnaxflpkq2jtliwthfz/bin/gfortran) @@ -60,7 +128,7 @@ syscheck: OpenACC : OFF OpenMP : OFF - Fypp : /storage/home/hcoda1/6/sbryngelson3/scratch/MFC-prs/build/venv/bin/fypp + Fypp : /storage/home/hcoda1/6/sbryngelson3/scratch/MFC-ruff/build/venv/bin/fypp Doxygen : Build Type : Release @@ -74,18 +142,18 @@ syscheck: OMPI_CXX : OMPI_FC : -pre_process: +post_process: CMake Configuration: - CMake v3.26.5 on atl1-1-02-007-5-2.pace.gatech.edu + CMake v3.26.5 on atl1-1-02-002-28-2.pace.gatech.edu C : GNU v12.3.0 (/usr/local/pace-apps/spack/packages/linux-rhel9-x86_64_v3/gcc-11.3.1/gcc-12.3.0-ukkkutsxfl5kpnnaxflpkq2jtliwthfz/bin/gcc) Fortran : GNU v12.3.0 (/usr/local/pace-apps/spack/packages/linux-rhel9-x86_64_v3/gcc-11.3.1/gcc-12.3.0-ukkkutsxfl5kpnnaxflpkq2jtliwthfz/bin/gfortran) - PRE_PROCESS : ON + PRE_PROCESS : OFF SIMULATION : OFF - POST_PROCESS : OFF + POST_PROCESS : ON SYSCHECK : OFF DOCUMENTATION : OFF ALL : OFF @@ -94,7 +162,7 @@ pre_process: OpenACC : OFF OpenMP : OFF - Fypp : /storage/home/hcoda1/6/sbryngelson3/scratch/MFC-prs/build/venv/bin/fypp + Fypp : /storage/scratch1/6/sbryngelson3/MFC-ruff/build/venv/bin/fypp Doxygen : Build Type : Release @@ -126,7 +194,7 @@ CPU: Core(s) per socket: 12 Socket(s): 2 Stepping: 7 - CPU(s) scaling MHz: 86% + CPU(s) scaling MHz: 93% CPU max MHz: 2700.0000 CPU min MHz: 1200.0000 BogoMIPS: 5400.00 diff --git a/tests/016C1B8B/golden.txt b/tests/016C1B8B/golden.txt index 29eca83b98..e44a2ae8c7 100644 --- a/tests/016C1B8B/golden.txt +++ b/tests/016C1B8B/golden.txt @@ -1,4 +1,4 @@ -D/beta.9.00.000050.dat 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999999708435 0.9999999644801 0.99999984081087 0.99999973754149 0.99999984081087 0.9999999644801 0.99999999708435 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.9999999644801 0.99999956727907 0.99999806067933 0.99999680260076 0.99999806067933 0.99999956727907 0.9999999644801 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999984081087 0.99999806067933 0.99999130856774 0.99998567025075 0.99999130856774 0.99999806067933 0.99999984081087 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999973754149 0.99999680260076 0.99998567025075 0.99997637423761 0.99998567025075 0.99999680260076 0.99999973754149 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999984081087 0.99999806067933 0.99999130856774 0.99998567025075 0.99999130856774 0.99999806067933 0.99999984081087 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.9999999644801 0.99999956727907 0.99999806067933 0.99999680260076 0.99999806067933 0.99999956727907 0.9999999644801 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999999708435 0.9999999644801 0.99999984081087 0.99999973754149 0.99999984081087 0.9999999644801 0.99999999708435 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.9999999644801 0.99999956727907 0.99999806067933 0.99999680260076 0.99999806067933 0.99999956727907 0.9999999644801 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999956727907 0.99999472837985 0.99997637423761 0.99996104770302 0.99997637423761 0.99999472837985 0.99999956727907 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999806067933 0.99997637423761 0.99989411667893 0.99982542791634 0.99989411667893 0.99997637423761 0.99999806067933 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999680260076 0.99996104770302 0.99982542791634 0.9997121792924 0.99982542791634 0.99996104770302 0.99999680260076 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999806067933 0.99997637423761 0.99989411667893 0.99982542791634 0.99989411667893 0.99997637423761 0.99999806067933 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999956727907 0.99999472837985 0.99997637423761 0.99996104770302 0.99997637423761 0.99999472837985 0.99999956727907 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.9999999644801 0.99999956727907 0.99999806067933 0.99999680260076 0.99999806067933 0.99999956727907 0.9999999644801 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999984081087 0.99999806067933 0.99999130856774 0.99998567025075 0.99999130856774 0.99999806067933 0.99999984081087 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999806067933 0.99997637423761 0.99989411667893 0.99982542791634 0.99989411667893 0.99997637423761 0.99999806067933 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999130856774 0.99989411667893 0.99952546387724 0.99921762220069 0.99952546387724 0.99989411667893 0.99999130856774 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99998567025075 0.99982542791634 0.99921762220069 0.99871007708055 0.99921762220069 0.99982542791634 0.99998567025075 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999130856774 0.99989411667893 0.99952546387724 0.99921762220069 0.99952546387724 0.99989411667893 0.99999130856774 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999806067933 0.99997637423761 0.99989411667893 0.99982542791634 0.99989411667893 0.99997637423761 0.99999806067933 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999984081087 0.99999806067933 0.99999130856774 0.99998567025075 0.99999130856774 0.99999806067933 0.99999984081087 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999973754149 0.99999680260076 0.99998567025075 0.99997637423761 0.99998567025075 0.99999680260076 0.99999973754149 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999680260076 0.99996104770302 0.99982542791634 0.9997121792924 0.99982542791634 0.99996104770302 0.99999680260076 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99998567025075 0.99982542791634 0.99921762220069 0.99871007708055 0.99921762220069 0.99982542791634 0.99998567025075 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99997637423761 0.9997121792924 0.99871007708055 0.99787327664514 0.99871007708055 0.9997121792924 0.99997637423761 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99998567025075 0.99982542791634 0.99921762220069 0.99871007708055 0.99921762220069 0.99982542791634 0.99998567025075 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999680260076 0.99996104770302 0.99982542791634 0.9997121792924 0.99982542791634 0.99996104770302 0.99999680260076 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999973754149 0.99999680260076 0.99998567025075 0.99997637423761 0.99998567025075 0.99999680260076 0.99999973754149 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999984081087 0.99999806067933 0.99999130856774 0.99998567025075 0.99999130856774 0.99999806067933 0.99999984081087 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999806067933 0.99997637423761 0.99989411667893 0.99982542791634 0.99989411667893 0.99997637423761 0.99999806067933 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999130856774 0.99989411667893 0.99952546387724 0.99921762220069 0.99952546387724 0.99989411667893 0.99999130856774 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99998567025075 0.99982542791634 0.99921762220069 0.99871007708055 0.99921762220069 0.99982542791634 0.99998567025075 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999130856774 0.99989411667893 0.99952546387724 0.99921762220069 0.99952546387724 0.99989411667893 0.99999130856774 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999806067933 0.99997637423761 0.99989411667893 0.99982542791634 0.99989411667893 0.99997637423761 0.99999806067933 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999984081087 0.99999806067933 0.99999130856774 0.99998567025075 0.99999130856774 0.99999806067933 0.99999984081087 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.9999999644801 0.99999956727907 0.99999806067933 0.99999680260076 0.99999806067933 0.99999956727907 0.9999999644801 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999956727907 0.99999472837985 0.99997637423761 0.99996104770302 0.99997637423761 0.99999472837985 0.99999956727907 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999806067933 0.99997637423761 0.99989411667893 0.99982542791634 0.99989411667893 0.99997637423761 0.99999806067933 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999680260076 0.99996104770302 0.99982542791634 0.9997121792924 0.99982542791634 0.99996104770302 0.99999680260076 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999806067933 0.99997637423761 0.99989411667893 0.99982542791634 0.99989411667893 0.99997637423761 0.99999806067933 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999956727907 0.99999472837985 0.99997637423761 0.99996104770302 0.99997637423761 0.99999472837985 0.99999956727907 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.9999999644801 0.99999956727907 0.99999806067933 0.99999680260076 0.99999806067933 0.99999956727907 0.9999999644801 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999999708435 0.9999999644801 0.99999984081087 0.99999973754149 0.99999984081087 0.9999999644801 0.99999999708435 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.9999999644801 0.99999956727907 0.99999806067933 0.99999680260076 0.99999806067933 0.99999956727907 0.9999999644801 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999984081087 0.99999806067933 0.99999130856774 0.99998567025075 0.99999130856774 0.99999806067933 0.99999984081087 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999973754149 0.99999680260076 0.99998567025075 0.99997637423761 0.99998567025075 0.99999680260076 0.99999973754149 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999984081087 0.99999806067933 0.99999130856774 0.99998567025075 0.99999130856774 0.99999806067933 0.99999984081087 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.9999999644801 0.99999956727907 0.99999806067933 0.99999680260076 0.99999806067933 0.99999956727907 0.9999999644801 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999999708435 0.9999999644801 0.99999984081087 0.99999973754149 0.99999984081087 0.9999999644801 0.99999999708435 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 +D/beta.9.00.000050.dat 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.9999999970844 0.99999996448075 0.99999984081375 0.99999973754625 0.99999984081375 0.99999996448075 0.9999999970844 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999996448075 0.99999956728691 0.9999980607145 0.99999680265874 0.9999980607145 0.99999956728691 0.99999996448075 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999984081375 0.9999980607145 0.99999130872535 0.99998567051061 0.99999130872535 0.9999980607145 0.99999984081375 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999973754625 0.99999680265874 0.99998567051061 0.99997637466605 0.99998567051061 0.99999680265874 0.99999973754625 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999984081375 0.9999980607145 0.99999130872535 0.99998567051061 0.99999130872535 0.9999980607145 0.99999984081375 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999996448075 0.99999956728691 0.9999980607145 0.99999680265874 0.9999980607145 0.99999956728691 0.99999996448075 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.9999999970844 0.99999996448075 0.99999984081375 0.99999973754625 0.99999984081375 0.99999996448075 0.9999999970844 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999996448075 0.99999956728691 0.9999980607145 0.99999680265874 0.9999980607145 0.99999956728691 0.99999996448075 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999956728691 0.99999472847545 0.99997637466605 0.99996104840939 0.99997637466605 0.99999472847545 0.99999956728691 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.9999980607145 0.99997637466605 0.99989411859905 0.99982543108208 0.99989411859905 0.99997637466605 0.9999980607145 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999680265874 0.99996104840939 0.99982543108208 0.99971218451182 0.99982543108208 0.99996104840939 0.99999680265874 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.9999980607145 0.99997637466605 0.99989411859905 0.99982543108208 0.99989411859905 0.99997637466605 0.9999980607145 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999956728691 0.99999472847545 0.99997637466605 0.99996104840939 0.99997637466605 0.99999472847545 0.99999956728691 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999996448075 0.99999956728691 0.9999980607145 0.99999680265874 0.9999980607145 0.99999956728691 0.99999996448075 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999984081375 0.9999980607145 0.99999130872535 0.99998567051061 0.99999130872535 0.9999980607145 0.99999984081375 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.9999980607145 0.99997637466605 0.99989411859905 0.99982543108208 0.99989411859905 0.99997637466605 0.9999980607145 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999130872535 0.99989411859905 0.9995254724826 0.99921763638853 0.9995254724826 0.99989411859905 0.99999130872535 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99998567051061 0.99982543108208 0.99921763638853 0.99871010047234 0.99921763638853 0.99982543108208 0.99998567051061 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999130872535 0.99989411859905 0.9995254724826 0.99921763638853 0.9995254724826 0.99989411859905 0.99999130872535 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.9999980607145 0.99997637466605 0.99989411859905 0.99982543108208 0.99989411859905 0.99997637466605 0.9999980607145 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999984081375 0.9999980607145 0.99999130872535 0.99998567051061 0.99999130872535 0.9999980607145 0.99999984081375 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999973754625 0.99999680265874 0.99998567051061 0.99997637466605 0.99998567051061 0.99999680265874 0.99999973754625 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999680265874 0.99996104840939 0.99982543108208 0.99971218451182 0.99982543108208 0.99996104840939 0.99999680265874 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99998567051061 0.99982543108208 0.99921763638853 0.99871010047234 0.99921763638853 0.99982543108208 0.99998567051061 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99997637466605 0.99971218451182 0.99871010047234 0.99787331521169 0.99871010047234 0.99971218451182 0.99997637466605 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99998567051061 0.99982543108208 0.99921763638853 0.99871010047234 0.99921763638853 0.99982543108208 0.99998567051061 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999680265874 0.99996104840939 0.99982543108208 0.99971218451182 0.99982543108208 0.99996104840939 0.99999680265874 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999973754625 0.99999680265874 0.99998567051061 0.99997637466605 0.99998567051061 0.99999680265874 0.99999973754625 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999984081375 0.9999980607145 0.99999130872535 0.99998567051061 0.99999130872535 0.9999980607145 0.99999984081375 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.9999980607145 0.99997637466605 0.99989411859905 0.99982543108208 0.99989411859905 0.99997637466605 0.9999980607145 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999130872535 0.99989411859905 0.9995254724826 0.99921763638853 0.9995254724826 0.99989411859905 0.99999130872535 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99998567051061 0.99982543108208 0.99921763638853 0.99871010047234 0.99921763638853 0.99982543108208 0.99998567051061 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999130872535 0.99989411859905 0.9995254724826 0.99921763638853 0.9995254724826 0.99989411859905 0.99999130872535 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.9999980607145 0.99997637466605 0.99989411859905 0.99982543108208 0.99989411859905 0.99997637466605 0.9999980607145 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999984081375 0.9999980607145 0.99999130872535 0.99998567051061 0.99999130872535 0.9999980607145 0.99999984081375 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999996448075 0.99999956728691 0.9999980607145 0.99999680265874 0.9999980607145 0.99999956728691 0.99999996448075 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999956728691 0.99999472847545 0.99997637466605 0.99996104840939 0.99997637466605 0.99999472847545 0.99999956728691 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.9999980607145 0.99997637466605 0.99989411859905 0.99982543108208 0.99989411859905 0.99997637466605 0.9999980607145 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999680265874 0.99996104840939 0.99982543108208 0.99971218451182 0.99982543108208 0.99996104840939 0.99999680265874 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.9999980607145 0.99997637466605 0.99989411859905 0.99982543108208 0.99989411859905 0.99997637466605 0.9999980607145 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999956728691 0.99999472847545 0.99997637466605 0.99996104840939 0.99997637466605 0.99999472847545 0.99999956728691 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999996448075 0.99999956728691 0.9999980607145 0.99999680265874 0.9999980607145 0.99999956728691 0.99999996448075 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.9999999970844 0.99999996448075 0.99999984081375 0.99999973754625 0.99999984081375 0.99999996448075 0.9999999970844 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999996448075 0.99999956728691 0.9999980607145 0.99999680265874 0.9999980607145 0.99999956728691 0.99999996448075 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999984081375 0.9999980607145 0.99999130872535 0.99998567051061 0.99999130872535 0.9999980607145 0.99999984081375 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999973754625 0.99999680265874 0.99998567051061 0.99997637466605 0.99998567051061 0.99999680265874 0.99999973754625 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999984081375 0.9999980607145 0.99999130872535 0.99998567051061 0.99999130872535 0.9999980607145 0.99999984081375 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999996448075 0.99999956728691 0.9999980607145 0.99999680265874 0.9999980607145 0.99999956728691 0.99999996448075 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.9999999970844 0.99999996448075 0.99999984081375 0.99999973754625 0.99999984081375 0.99999996448075 0.9999999970844 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 D/cons.1.00.000000.dat 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 D/cons.1.00.000050.dat 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999987 0.95999999999987 0.95999999999987 0.95999999999987 0.95999999999987 0.95999999999987 0.95999999999987 0.95999999999987 0.95999999999987 0.95999999999987 0.95999999999987 0.95999999999987 0.95999999999987 0.95999999999987 0.95999999999987 0.95999999999987 0.95999999999987 0.95999999999987 0.95999999999987 0.95999999999987 0.95999999999987 0.95999999999987 0.95999999999987 0.95999999999987 0.95999999999987 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000106 0.96000000000106 0.96000000000106 0.96000000000106 0.96000000000106 0.96000000000106 0.96000000000106 0.96000000000106 0.96000000000106 0.96000000000106 0.96000000000106 0.96000000000106 0.96000000000106 0.96000000000106 0.96000000000106 0.96000000000106 0.96000000000106 0.96000000000106 0.96000000000106 0.96000000000106 0.96000000000106 0.96000000000106 0.96000000000106 0.96000000000106 0.96000000000106 0.96000000000071 0.96000000000071 0.96000000000071 0.96000000000071 0.96000000000071 0.96000000000071 0.96000000000071 0.96000000000071 0.96000000000071 0.96000000000071 0.96000000000071 0.96000000000071 0.96000000000071 0.96000000000071 0.96000000000071 0.96000000000071 0.96000000000071 0.96000000000071 0.96000000000071 0.96000000000071 0.96000000000071 0.96000000000071 0.96000000000071 0.96000000000071 0.96000000000071 0.96000000000373 0.96000000000373 0.96000000000373 0.96000000000373 0.96000000000373 0.96000000000373 0.96000000000373 0.96000000000373 0.96000000000373 0.96000000000373 0.96000000000373 0.96000000000373 0.96000000000373 0.96000000000373 0.96000000000373 0.96000000000373 0.96000000000373 0.96000000000373 0.96000000000373 0.96000000000373 0.96000000000373 0.96000000000373 0.96000000000373 0.96000000000373 0.96000000000373 0.96000000000075 0.96000000000075 0.96000000000075 0.96000000000075 0.96000000000075 0.96000000000075 0.96000000000075 0.96000000000075 0.96000000000075 0.96000000000075 0.96000000000075 0.96000000000075 0.96000000000075 0.96000000000075 0.96000000000075 0.96000000000075 0.96000000000075 0.96000000000075 0.96000000000075 0.96000000000075 0.96000000000075 0.96000000000075 0.96000000000075 0.96000000000075 0.96000000000075 0.96000000000107 0.96000000000107 0.96000000000107 0.96000000000107 0.96000000000107 0.96000000000107 0.96000000000107 0.96000000000107 0.96000000000107 0.96000000000107 0.96000000000107 0.96000000000107 0.96000000000107 0.96000000000107 0.96000000000107 0.96000000000107 0.96000000000107 0.96000000000107 0.96000000000107 0.96000000000107 0.96000000000107 0.96000000000107 0.96000000000107 0.96000000000107 0.96000000000107 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.9600000000001 0.9600000000001 0.9600000000001 0.9600000000001 0.9600000000001 0.9600000000001 0.9600000000001 0.9600000000001 0.9600000000001 0.9600000000001 0.9600000000001 0.9600000000001 0.9600000000001 0.9600000000001 0.9600000000001 0.9600000000001 0.9600000000001 0.9600000000001 0.9600000000001 0.9600000000001 0.9600000000001 0.9600000000001 0.9600000000001 0.9600000000001 0.9600000000001 0.96000000000079 0.96000000000079 0.96000000000079 0.96000000000079 0.96000000000079 0.96000000000079 0.96000000000079 0.96000000000079 0.96000000000079 0.96000000000079 0.96000000000079 0.96000000000079 0.96000000000079 0.96000000000079 0.96000000000079 0.96000000000079 0.96000000000079 0.96000000000079 0.96000000000079 0.96000000000079 0.96000000000079 0.96000000000079 0.96000000000079 0.96000000000079 0.96000000000079 0.96000000002206 0.96000000002206 0.96000000002206 0.96000000002206 0.96000000002206 0.96000000002206 0.96000000002206 0.96000000002206 0.96000000002206 0.96000000002206 0.96000000002206 0.96000000002206 0.96000000002206 0.96000000002206 0.96000000002206 0.96000000002206 0.96000000002206 0.96000000002206 0.96000000002206 0.96000000002206 0.96000000002206 0.96000000002206 0.96000000002206 0.96000000002206 0.96000000002206 0.96000000005987 0.96000000005987 0.96000000005987 0.96000000005987 0.96000000005987 0.96000000005987 0.96000000005987 0.96000000005987 0.96000000005987 0.96000000005987 0.96000000005987 0.96000000005987 0.96000000005987 0.96000000005987 0.96000000005987 0.96000000005987 0.96000000005987 0.96000000005987 0.96000000005987 0.96000000005987 0.96000000005987 0.96000000005987 0.96000000005987 0.96000000005987 0.96000000005987 0.96000000004881 0.96000000004881 0.96000000004881 0.96000000004881 0.96000000004881 0.96000000004881 0.96000000004881 0.96000000004881 0.96000000004881 0.96000000004881 0.96000000004881 0.96000000004881 0.96000000004881 0.96000000004881 0.96000000004881 0.96000000004881 0.96000000004881 0.96000000004881 0.96000000004881 0.96000000004881 0.96000000004881 0.96000000004881 0.96000000004881 0.96000000004881 0.96000000004881 0.96000000032881 0.96000000032881 0.96000000032881 0.96000000032881 0.96000000032881 0.96000000032881 0.96000000032881 0.96000000032881 0.96000000032881 0.96000000032881 0.96000000032881 0.96000000032881 0.96000000032882 0.96000000032881 0.96000000032881 0.96000000032881 0.96000000032881 0.96000000032881 0.96000000032881 0.96000000032881 0.96000000032881 0.96000000032881 0.96000000032881 0.96000000032881 0.96000000032881 0.96000000005864 0.96000000005864 0.96000000005864 0.96000000005864 0.96000000005864 0.96000000005864 0.96000000005864 0.96000000005864 0.96000000005864 0.96000000005864 0.96000000005864 0.96000000005864 0.96000000005864 0.96000000005864 0.96000000005864 0.96000000005864 0.96000000005864 0.96000000005864 0.96000000005864 0.96000000005864 0.96000000005864 0.96000000005864 0.96000000005864 0.96000000005864 0.96000000005864 0.96000000008629 0.96000000008629 0.96000000008629 0.96000000008629 0.96000000008629 0.96000000008629 0.96000000008629 0.96000000008629 0.96000000008629 0.96000000008629 0.96000000008629 0.96000000008629 0.96000000008629 0.96000000008629 0.96000000008629 0.96000000008629 0.96000000008629 0.96000000008629 0.96000000008629 0.96000000008629 0.96000000008629 0.96000000008629 0.96000000008629 0.96000000008629 0.96000000008629 0.96000000000597 0.96000000000597 0.96000000000597 0.96000000000597 0.96000000000597 0.96000000000597 0.96000000000597 0.96000000000597 0.96000000000597 0.96000000000597 0.96000000000597 0.96000000000597 0.96000000000597 0.96000000000597 0.96000000000597 0.96000000000597 0.96000000000597 0.96000000000597 0.96000000000597 0.96000000000597 0.96000000000597 0.96000000000597 0.96000000000597 0.96000000000597 0.96000000000597 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.9600000000021 0.9600000000021 0.9600000000021 0.9600000000021 0.9600000000021 0.9600000000021 0.9600000000021 0.9600000000021 0.9600000000021 0.9600000000021 0.9600000000021 0.9600000000021 0.9600000000021 0.9600000000021 0.9600000000021 0.9600000000021 0.9600000000021 0.9600000000021 0.9600000000021 0.9600000000021 0.9600000000021 0.9600000000021 0.9600000000021 0.9600000000021 0.9600000000021 0.96000000013587 0.96000000013587 0.96000000013587 0.96000000013587 0.96000000013587 0.96000000013587 0.96000000013587 0.96000000013587 0.96000000013587 0.96000000013587 0.96000000013587 0.96000000013587 0.96000000013587 0.96000000013587 0.96000000013587 0.96000000013587 0.96000000013587 0.96000000013587 0.96000000013587 0.96000000013587 0.96000000013587 0.96000000013587 0.96000000013587 0.96000000013587 0.96000000013587 0.96000000392457 0.96000000392457 0.96000000392457 0.96000000392457 0.96000000392457 0.96000000392457 0.96000000392457 0.96000000392457 0.96000000392457 0.96000000392457 0.96000000392457 0.96000000392457 0.96000000392457 0.96000000392457 0.96000000392457 0.96000000392457 0.96000000392457 0.96000000392457 0.96000000392457 0.96000000392457 0.96000000392457 0.96000000392457 0.96000000392457 0.96000000392457 0.96000000392457 0.96000000386601 0.96000000386601 0.96000000386601 0.96000000386601 0.96000000386601 0.96000000386601 0.96000000386601 0.96000000386601 0.96000000386601 0.96000000386601 0.96000000386601 0.96000000386601 0.96000000386601 0.96000000386601 0.96000000386601 0.96000000386601 0.96000000386601 0.96000000386601 0.96000000386601 0.96000000386601 0.96000000386601 0.96000000386601 0.96000000386601 0.96000000386601 0.96000000386601 0.96000000372715 0.96000000372715 0.96000000372715 0.96000000372715 0.96000000372715 0.96000000372715 0.96000000372715 0.96000000372715 0.96000000372715 0.96000000372715 0.96000000372716 0.96000000372717 0.96000000372717 0.96000000372717 0.96000000372716 0.96000000372715 0.96000000372715 0.96000000372715 0.96000000372715 0.96000000372715 0.96000000372715 0.96000000372715 0.96000000372715 0.96000000372715 0.96000000372715 0.96000002634421 0.96000002634421 0.96000002634421 0.96000002634421 0.96000002634421 0.96000002634421 0.96000002634421 0.96000002634421 0.96000002634421 0.96000002634422 0.96000002634425 0.96000002634436 0.96000002634445 0.96000002634436 0.96000002634425 0.96000002634422 0.96000002634421 0.96000002634421 0.96000002634421 0.96000002634421 0.96000002634421 0.96000002634421 0.96000002634421 0.96000002634421 0.96000002634421 0.96000000528784 0.96000000528784 0.96000000528784 0.96000000528784 0.96000000528784 0.96000000528784 0.96000000528784 0.96000000528784 0.96000000528784 0.96000000528784 0.96000000528784 0.96000000528782 0.96000000528781 0.96000000528782 0.96000000528784 0.96000000528784 0.96000000528784 0.96000000528784 0.96000000528784 0.96000000528784 0.96000000528784 0.96000000528784 0.96000000528784 0.96000000528784 0.96000000528784 0.96000000790203 0.96000000790203 0.96000000790203 0.96000000790203 0.96000000790203 0.96000000790203 0.96000000790203 0.96000000790203 0.96000000790203 0.96000000790203 0.96000000790201 0.96000000790195 0.96000000790189 0.96000000790195 0.96000000790201 0.96000000790203 0.96000000790203 0.96000000790203 0.96000000790203 0.96000000790203 0.96000000790203 0.96000000790203 0.96000000790203 0.96000000790203 0.96000000790203 0.96000000059137 0.96000000059137 0.96000000059137 0.96000000059137 0.96000000059137 0.96000000059137 0.96000000059137 0.96000000059137 0.96000000059137 0.96000000059137 0.96000000059137 0.96000000059137 0.96000000059136 0.96000000059137 0.96000000059137 0.96000000059137 0.96000000059137 0.96000000059137 0.96000000059137 0.96000000059137 0.96000000059137 0.96000000059137 0.96000000059137 0.96000000059137 0.96000000059137 0.96000000001228 0.96000000001228 0.96000000001228 0.96000000001228 0.96000000001228 0.96000000001228 0.96000000001228 0.96000000001228 0.96000000001228 0.96000000001228 0.96000000001228 0.96000000001228 0.96000000001228 0.96000000001228 0.96000000001228 0.96000000001228 0.96000000001228 0.96000000001228 0.96000000001228 0.96000000001228 0.96000000001228 0.96000000001228 0.96000000001228 0.96000000001228 0.96000000001228 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000002232 0.96000000002232 0.96000000002232 0.96000000002232 0.96000000002232 0.96000000002232 0.96000000002232 0.96000000002232 0.96000000002232 0.96000000002232 0.96000000002232 0.96000000002232 0.96000000002232 0.96000000002232 0.96000000002232 0.96000000002232 0.96000000002232 0.96000000002232 0.96000000002232 0.96000000002232 0.96000000002232 0.96000000002232 0.96000000002232 0.96000000002232 0.96000000002232 0.960000001086 0.960000001086 0.960000001086 0.960000001086 0.960000001086 0.960000001086 0.960000001086 0.960000001086 0.960000001086 0.960000001086 0.960000001086 0.960000001086 0.960000001086 0.960000001086 0.960000001086 0.960000001086 0.960000001086 0.960000001086 0.960000001086 0.960000001086 0.960000001086 0.960000001086 0.960000001086 0.960000001086 0.960000001086 0.96000003357351 0.96000003357351 0.96000003357351 0.96000003357351 0.96000003357351 0.96000003357351 0.96000003357351 0.96000003357351 0.96000003357351 0.96000003357351 0.96000003357351 0.96000003357351 0.96000003357351 0.96000003357351 0.96000003357351 0.96000003357351 0.96000003357351 0.96000003357351 0.96000003357351 0.96000003357351 0.96000003357351 0.96000003357351 0.96000003357351 0.96000003357351 0.96000003357351 0.9600007182478 0.9600007182478 0.9600007182478 0.9600007182478 0.9600007182478 0.9600007182478 0.9600007182478 0.9600007182478 0.9600007182478 0.9600007182478 0.96000071824781 0.96000071824783 0.96000071824785 0.96000071824783 0.96000071824781 0.9600007182478 0.9600007182478 0.9600007182478 0.9600007182478 0.9600007182478 0.9600007182478 0.9600007182478 0.9600007182478 0.9600007182478 0.9600007182478 0.96000023896672 0.96000023896672 0.96000023896672 0.96000023896672 0.96000023896672 0.96000023896672 0.96000023896672 0.96000023896672 0.96000023896672 0.96000023896674 0.96000023896695 0.96000023896772 0.96000023896835 0.96000023896772 0.96000023896695 0.96000023896674 0.96000023896672 0.96000023896672 0.96000023896672 0.96000023896672 0.96000023896672 0.96000023896672 0.96000023896672 0.96000023896672 0.96000023896672 0.96000168485738 0.96000168485738 0.96000168485738 0.96000168485738 0.96000168485738 0.96000168485738 0.96000168485738 0.96000168485738 0.96000168485738 0.96000168485765 0.96000168486045 0.9600016848708 0.9600016848794 0.9600016848708 0.96000168486045 0.96000168485765 0.96000168485738 0.96000168485738 0.96000168485738 0.96000168485738 0.96000168485738 0.96000168485738 0.96000168485738 0.96000168485738 0.96000168485738 0.96000038977218 0.96000038977218 0.96000038977218 0.96000038977218 0.96000038977218 0.96000038977218 0.96000038977218 0.96000038977218 0.96000038977218 0.96000038977213 0.96000038977162 0.96000038976971 0.96000038976812 0.96000038976971 0.96000038977162 0.96000038977213 0.96000038977218 0.96000038977218 0.96000038977218 0.96000038977218 0.96000038977218 0.96000038977218 0.96000038977218 0.96000038977218 0.96000038977218 0.96000058691047 0.96000058691047 0.96000058691047 0.96000058691047 0.96000058691047 0.96000058691047 0.96000058691047 0.96000058691047 0.96000058691047 0.9600005869103 0.96000058690856 0.96000058690212 0.96000058689677 0.96000058690212 0.96000058690856 0.9600005869103 0.96000058691047 0.96000058691047 0.96000058691047 0.96000058691047 0.96000058691047 0.96000058691047 0.96000058691047 0.96000058691047 0.96000058691047 0.96000005194927 0.96000005194927 0.96000005194927 0.96000005194927 0.96000005194927 0.96000005194927 0.96000005194927 0.96000005194927 0.96000005194927 0.96000005194927 0.96000005194925 0.96000005194915 0.96000005194908 0.96000005194915 0.96000005194925 0.96000005194927 0.96000005194927 0.96000005194927 0.96000005194927 0.96000005194927 0.96000005194927 0.96000005194927 0.96000005194927 0.96000005194927 0.96000005194927 0.96000000110092 0.96000000110092 0.96000000110092 0.96000000110092 0.96000000110092 0.96000000110092 0.96000000110092 0.96000000110092 0.96000000110092 0.96000000110092 0.96000000110092 0.96000000110092 0.96000000110091 0.96000000110092 0.96000000110092 0.96000000110092 0.96000000110092 0.96000000110092 0.96000000110092 0.96000000110092 0.96000000110092 0.96000000110092 0.96000000110092 0.96000000110092 0.96000000110092 0.96000000002787 0.96000000002787 0.96000000002787 0.96000000002787 0.96000000002787 0.96000000002787 0.96000000002787 0.96000000002787 0.96000000002787 0.96000000002787 0.96000000002787 0.96000000002787 0.96000000002787 0.96000000002787 0.96000000002787 0.96000000002787 0.96000000002787 0.96000000002787 0.96000000002787 0.96000000002787 0.96000000002787 0.96000000002787 0.96000000002787 0.96000000002787 0.96000000002787 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96000000000024 0.96000000000024 0.96000000000024 0.96000000000024 0.96000000000024 0.96000000000024 0.96000000000024 0.96000000000024 0.96000000000024 0.96000000000024 0.96000000000024 0.96000000000024 0.96000000000024 0.96000000000024 0.96000000000024 0.96000000000024 0.96000000000024 0.96000000000024 0.96000000000024 0.96000000000024 0.96000000000024 0.96000000000024 0.96000000000024 0.96000000000024 0.96000000000024 0.96000000000461 0.96000000000461 0.96000000000461 0.96000000000461 0.96000000000461 0.96000000000461 0.96000000000461 0.96000000000461 0.96000000000461 0.96000000000461 0.96000000000461 0.96000000000461 0.96000000000461 0.96000000000461 0.96000000000461 0.96000000000461 0.96000000000461 0.96000000000461 0.96000000000461 0.96000000000461 0.96000000000461 0.96000000000461 0.96000000000461 0.96000000000461 0.96000000000461 0.96000000028923 0.96000000028923 0.96000000028923 0.96000000028923 0.96000000028923 0.96000000028923 0.96000000028923 0.96000000028923 0.96000000028923 0.96000000028923 0.96000000028923 0.96000000028923 0.96000000028923 0.96000000028923 0.96000000028923 0.96000000028923 0.96000000028923 0.96000000028923 0.96000000028923 0.96000000028923 0.96000000028923 0.96000000028923 0.96000000028923 0.96000000028923 0.96000000028923 0.96000001055314 0.96000001055314 0.96000001055314 0.96000001055314 0.96000001055314 0.96000001055314 0.96000001055314 0.96000001055314 0.96000001055314 0.96000001055314 0.96000001055314 0.96000001055314 0.96000001055314 0.96000001055314 0.96000001055314 0.96000001055314 0.96000001055314 0.96000001055314 0.96000001055314 0.96000001055314 0.96000001055314 0.96000001055314 0.96000001055314 0.96000001055314 0.96000001055314 0.96000025210076 0.96000025210076 0.96000025210076 0.96000025210076 0.96000025210076 0.96000025210076 0.96000025210076 0.96000025210076 0.96000025210076 0.96000025210076 0.96000025210075 0.96000025210075 0.96000025210074 0.96000025210075 0.96000025210075 0.96000025210076 0.96000025210076 0.96000025210076 0.96000025210076 0.96000025210076 0.96000025210076 0.96000025210076 0.96000025210076 0.96000025210076 0.96000025210076 0.96000388888139 0.96000388888139 0.96000388888139 0.96000388888139 0.96000388888139 0.96000388888139 0.96000388888139 0.96000388888139 0.96000388888139 0.96000388888138 0.96000388888123 0.9600038888807 0.96000388888026 0.9600038888807 0.96000388888123 0.96000388888138 0.96000388888139 0.96000388888139 0.96000388888139 0.96000388888139 0.96000388888139 0.96000388888139 0.96000388888139 0.96000388888139 0.96000388888139 0.96003762422319 0.96003762422319 0.96003762422319 0.96003762422319 0.96003762422319 0.96003762422319 0.96003762422319 0.96003762422319 0.96003762422319 0.9600376242231 0.96003762422213 0.96003762421858 0.96003762421563 0.96003762421858 0.96003762422213 0.9600376242231 0.96003762422319 0.96003762422319 0.96003762422319 0.96003762422319 0.96003762422319 0.96003762422319 0.96003762422319 0.96003762422319 0.96003762422319 0.96024757938339 0.96024757938339 0.96024757938339 0.96024757938339 0.96024757938339 0.96024757938339 0.96024757938339 0.96024757938339 0.96024757938339 0.96024757938299 0.96024757937889 0.96024757936384 0.96024757935133 0.96024757936384 0.96024757937889 0.96024757938299 0.96024757938339 0.96024757938339 0.96024757938339 0.96024757938339 0.96024757938339 0.96024757938339 0.96024757938339 0.96024757938339 0.96024757938339 0.96002715152843 0.96002715152843 0.96002715152843 0.96002715152843 0.96002715152843 0.96002715152843 0.96002715152843 0.96002715152843 0.96002715152838 0.96002715152368 0.96002715147466 0.96002715129448 0.96002715114453 0.96002715129448 0.96002715147466 0.96002715152368 0.96002715152838 0.96002715152843 0.96002715152843 0.96002715152843 0.96002715152843 0.96002715152843 0.96002715152843 0.96002715152843 0.96002715152843 0.96003089249465 0.96003089249465 0.96003089249465 0.96003089249465 0.96003089249465 0.96003089249465 0.96003089249465 0.96003089249465 0.96003089249453 0.96003089248229 0.96003089235395 0.96003089188122 0.96003089148813 0.96003089188122 0.96003089235395 0.96003089248229 0.96003089249453 0.96003089249465 0.96003089249465 0.96003089249465 0.96003089249465 0.96003089249465 0.96003089249465 0.96003089249465 0.96003089249465 0.96000375036941 0.96000375036941 0.96000375036941 0.96000375036941 0.96000375036941 0.96000375036941 0.96000375036941 0.96000375036941 0.9600037503694 0.96000375036924 0.96000375036749 0.96000375036112 0.96000375035583 0.96000375036112 0.96000375036749 0.96000375036924 0.9600037503694 0.96000375036941 0.96000375036941 0.96000375036941 0.96000375036941 0.96000375036941 0.96000375036941 0.96000375036941 0.96000375036941 0.96000008693805 0.96000008693805 0.96000008693805 0.96000008693805 0.96000008693805 0.96000008693805 0.96000008693805 0.96000008693805 0.96000008693805 0.96000008693804 0.96000008693792 0.96000008693746 0.96000008693709 0.96000008693746 0.96000008693792 0.96000008693804 0.96000008693805 0.96000008693805 0.96000008693805 0.96000008693805 0.96000008693805 0.96000008693805 0.96000008693805 0.96000008693805 0.96000008693805 0.96000000244292 0.96000000244292 0.96000000244292 0.96000000244292 0.96000000244292 0.96000000244292 0.96000000244292 0.96000000244292 0.96000000244292 0.96000000244292 0.96000000244292 0.96000000244292 0.96000000244291 0.96000000244292 0.96000000244292 0.96000000244292 0.96000000244292 0.96000000244292 0.96000000244292 0.96000000244292 0.96000000244292 0.96000000244292 0.96000000244292 0.96000000244292 0.96000000244292 0.96000000003463 0.96000000003463 0.96000000003463 0.96000000003463 0.96000000003463 0.96000000003463 0.96000000003463 0.96000000003463 0.96000000003463 0.96000000003463 0.96000000003463 0.96000000003463 0.96000000003463 0.96000000003463 0.96000000003463 0.96000000003463 0.96000000003463 0.96000000003463 0.96000000003463 0.96000000003463 0.96000000003463 0.96000000003463 0.96000000003463 0.96000000003463 0.96000000003463 0.9600000000004 0.9600000000004 0.9600000000004 0.9600000000004 0.9600000000004 0.9600000000004 0.9600000000004 0.9600000000004 0.9600000000004 0.9600000000004 0.9600000000004 0.9600000000004 0.9600000000004 0.9600000000004 0.9600000000004 0.9600000000004 0.9600000000004 0.9600000000004 0.9600000000004 0.9600000000004 0.9600000000004 0.9600000000004 0.9600000000004 0.9600000000004 0.9600000000004 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.96000000000021 0.96000000000021 0.96000000000021 0.96000000000021 0.96000000000021 0.96000000000021 0.96000000000021 0.96000000000021 0.96000000000021 0.96000000000021 0.96000000000021 0.96000000000021 0.96000000000021 0.96000000000021 0.96000000000021 0.96000000000021 0.96000000000021 0.96000000000021 0.96000000000021 0.96000000000021 0.96000000000021 0.96000000000021 0.96000000000021 0.96000000000021 0.96000000000021 0.96000000000066 0.96000000000066 0.96000000000066 0.96000000000066 0.96000000000066 0.96000000000066 0.96000000000066 0.96000000000066 0.96000000000066 0.96000000000066 0.96000000000066 0.96000000000066 0.96000000000066 0.96000000000066 0.96000000000066 0.96000000000066 0.96000000000066 0.96000000000066 0.96000000000066 0.96000000000066 0.96000000000066 0.96000000000066 0.96000000000066 0.96000000000066 0.96000000000066 0.9600000000725 0.9600000000725 0.9600000000725 0.9600000000725 0.9600000000725 0.9600000000725 0.9600000000725 0.9600000000725 0.9600000000725 0.9600000000725 0.9600000000725 0.9600000000725 0.9600000000725 0.9600000000725 0.9600000000725 0.9600000000725 0.9600000000725 0.9600000000725 0.9600000000725 0.9600000000725 0.9600000000725 0.9600000000725 0.9600000000725 0.9600000000725 0.9600000000725 0.96000000306584 0.96000000306584 0.96000000306584 0.96000000306584 0.96000000306584 0.96000000306584 0.96000000306584 0.96000000306584 0.96000000306584 0.96000000306584 0.96000000306584 0.96000000306584 0.96000000306584 0.96000000306584 0.96000000306584 0.96000000306584 0.96000000306584 0.96000000306584 0.96000000306584 0.96000000306584 0.96000000306584 0.96000000306584 0.96000000306584 0.96000000306584 0.96000000306584 0.96000008513635 0.96000008513635 0.96000008513635 0.96000008513635 0.96000008513635 0.96000008513635 0.96000008513635 0.96000008513635 0.96000008513635 0.96000008513635 0.96000008513635 0.96000008513635 0.96000008513634 0.96000008513635 0.96000008513635 0.96000008513635 0.96000008513635 0.96000008513635 0.96000008513635 0.96000008513635 0.96000008513635 0.96000008513635 0.96000008513635 0.96000008513635 0.96000008513635 0.96000153658661 0.96000153658661 0.96000153658661 0.96000153658661 0.96000153658661 0.96000153658661 0.96000153658661 0.96000153658661 0.96000153658661 0.9600015365866 0.96000153658648 0.96000153658605 0.96000153658568 0.96000153658605 0.96000153658648 0.9600015365866 0.96000153658661 0.96000153658661 0.96000153658661 0.96000153658661 0.96000153658661 0.96000153658661 0.96000153658661 0.96000153658661 0.96000153658661 0.96001782964953 0.96001782964953 0.96001782964953 0.96001782964953 0.96001782964953 0.96001782964953 0.96001782964953 0.96001782964953 0.96001782964952 0.96001782964798 0.96001782963141 0.96001782956971 0.96001782951832 0.96001782956971 0.96001782963141 0.96001782964798 0.96001782964952 0.96001782964953 0.96001782964953 0.96001782964953 0.96001782964953 0.96001782964953 0.96001782964953 0.96001782964953 0.96001782964953 0.96013299338417 0.96013299338417 0.96013299338417 0.96013299338417 0.96013299338417 0.96013299338417 0.96013299338417 0.96013299338417 0.96013299338407 0.96013299336664 0.96013299317938 0.96013299248152 0.9601329919003 0.96013299248152 0.96013299317938 0.96013299336664 0.96013299338407 0.96013299338417 0.96013299338417 0.96013299338417 0.96013299338417 0.96013299338417 0.96013299338417 0.96013299338417 0.96013299338417 0.96063533731738 0.96063533731738 0.96063533731738 0.96063533731738 0.96063533731738 0.96063533731738 0.96063533731738 0.96063533731738 0.96063533731696 0.96063533724286 0.96063533644612 0.96063533347361 0.96063533099909 0.96063533347361 0.96063533644612 0.96063533724286 0.96063533731696 0.96063533731738 0.96063533731738 0.96063533731738 0.96063533731738 0.96063533731738 0.96063533731738 0.96063533731738 0.96063533731738 0.96190052351632 0.96190052351632 0.96190052351632 0.96190052351632 0.96190052351632 0.96190052351632 0.96190052351631 0.96190052351633 0.96190052351558 0.9619005233962 0.9619005221108 0.96190051731369 0.96190051332184 0.96190051731369 0.9619005221108 0.9619005233962 0.96190052351558 0.96190052351633 0.96190052351631 0.96190052351632 0.96190052351632 0.96190052351632 0.96190052351632 0.96190052351632 0.96190052351632 0.96374631791153 0.96374631791153 0.96374631791153 0.96374631791153 0.96374631791153 0.96374631791153 0.96374631791153 0.96374631791153 0.9637463179113 0.96374631785162 0.9637463172047 0.96374631478143 0.96374631276272 0.96374631478143 0.9637463172047 0.96374631785162 0.9637463179113 0.96374631791153 0.96374631791153 0.96374631791153 0.96374631791153 0.96374631791153 0.96374631791153 0.96374631791153 0.96374631791153 0.96026255957098 0.96026255957098 0.96026255957098 0.96026255957098 0.96026255957098 0.96026255957098 0.96026255957098 0.96026255957098 0.96026255957094 0.96026255955942 0.96026255943523 0.96026255897133 0.96026255858468 0.96026255897133 0.96026255943523 0.96026255955942 0.96026255957094 0.96026255957098 0.96026255957098 0.96026255957098 0.96026255957098 0.96026255957098 0.96026255957098 0.96026255957098 0.96026255957098 0.96000700586267 0.96000700586267 0.96000700586267 0.96000700586267 0.96000700586267 0.96000700586267 0.96000700586267 0.96000700586267 0.96000700586266 0.96000700586123 0.96000700584591 0.96000700578881 0.96000700574126 0.96000700578881 0.96000700584591 0.96000700586123 0.96000700586266 0.96000700586267 0.96000700586267 0.96000700586267 0.96000700586267 0.96000700586267 0.96000700586267 0.96000700586267 0.96000700586267 0.96000019245935 0.96000019245935 0.96000019245935 0.96000019245935 0.96000019245935 0.96000019245935 0.96000019245935 0.96000019245935 0.96000019245935 0.96000019245934 0.96000019245924 0.96000019245887 0.96000019245857 0.96000019245887 0.96000019245924 0.96000019245934 0.96000019245935 0.96000019245935 0.96000019245935 0.96000019245935 0.96000019245935 0.96000019245935 0.96000019245935 0.96000019245935 0.96000019245935 0.9600000027078 0.9600000027078 0.9600000027078 0.9600000027078 0.9600000027078 0.9600000027078 0.9600000027078 0.9600000027078 0.9600000027078 0.9600000027078 0.9600000027078 0.9600000027078 0.96000000270779 0.9600000027078 0.9600000027078 0.9600000027078 0.9600000027078 0.9600000027078 0.9600000027078 0.9600000027078 0.9600000027078 0.9600000027078 0.9600000027078 0.9600000027078 0.9600000027078 0.96000000003541 0.96000000003541 0.96000000003541 0.96000000003541 0.96000000003541 0.96000000003541 0.96000000003541 0.96000000003541 0.96000000003541 0.96000000003541 0.96000000003541 0.96000000003541 0.96000000003541 0.96000000003541 0.96000000003541 0.96000000003541 0.96000000003541 0.96000000003541 0.96000000003541 0.96000000003541 0.96000000003541 0.96000000003541 0.96000000003541 0.96000000003541 0.96000000003541 0.96000000000036 0.96000000000036 0.96000000000036 0.96000000000036 0.96000000000036 0.96000000000036 0.96000000000036 0.96000000000036 0.96000000000036 0.96000000000036 0.96000000000036 0.96000000000036 0.96000000000036 0.96000000000036 0.96000000000036 0.96000000000036 0.96000000000036 0.96000000000036 0.96000000000036 0.96000000000036 0.96000000000036 0.96000000000036 0.96000000000036 0.96000000000036 0.96000000000036 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000004 0.96000000000004 0.96000000000004 0.96000000000004 0.96000000000004 0.96000000000004 0.96000000000004 0.96000000000004 0.96000000000004 0.96000000000004 0.96000000000004 0.96000000000004 0.96000000000004 0.96000000000004 0.96000000000004 0.96000000000004 0.96000000000004 0.96000000000004 0.96000000000004 0.96000000000004 0.96000000000004 0.96000000000004 0.96000000000004 0.96000000000004 0.96000000000004 0.96000000001662 0.96000000001662 0.96000000001662 0.96000000001662 0.96000000001662 0.96000000001662 0.96000000001662 0.96000000001662 0.96000000001662 0.96000000001662 0.96000000001662 0.96000000001662 0.96000000001662 0.96000000001662 0.96000000001662 0.96000000001662 0.96000000001662 0.96000000001662 0.96000000001662 0.96000000001662 0.96000000001662 0.96000000001662 0.96000000001662 0.96000000001662 0.96000000001662 0.96000000087018 0.96000000087018 0.96000000087018 0.96000000087018 0.96000000087018 0.96000000087018 0.96000000087018 0.96000000087018 0.96000000087018 0.96000000087018 0.96000000087018 0.96000000087018 0.96000000087018 0.96000000087018 0.96000000087018 0.96000000087018 0.96000000087018 0.96000000087018 0.96000000087018 0.96000000087018 0.96000000087018 0.96000000087018 0.96000000087018 0.96000000087018 0.96000000087018 0.96000002801722 0.96000002801722 0.96000002801722 0.96000002801722 0.96000002801722 0.96000002801722 0.96000002801722 0.96000002801722 0.96000002801722 0.96000002801722 0.96000002801722 0.96000002801722 0.96000002801722 0.96000002801722 0.96000002801722 0.96000002801722 0.96000002801722 0.96000002801722 0.96000002801722 0.96000002801722 0.96000002801722 0.96000002801722 0.96000002801722 0.96000002801722 0.96000002801722 0.96000057403111 0.96000057403111 0.96000057403111 0.96000057403111 0.96000057403111 0.96000057403111 0.96000057403111 0.96000057403111 0.96000057403111 0.96000057403111 0.96000057403109 0.96000057403102 0.96000057403097 0.96000057403102 0.96000057403109 0.96000057403111 0.96000057403111 0.96000057403111 0.96000057403111 0.96000057403111 0.96000057403111 0.96000057403111 0.96000057403111 0.96000057403111 0.96000057403111 0.9600078024614 0.9600078024614 0.9600078024614 0.9600078024614 0.9600078024614 0.9600078024614 0.9600078024614 0.9600078024614 0.9600078024614 0.96000780246127 0.96000780245992 0.96000780245496 0.96000780245084 0.96000780245496 0.96000780245992 0.96000780246127 0.9600078024614 0.9600078024614 0.9600078024614 0.9600078024614 0.9600078024614 0.9600078024614 0.9600078024614 0.9600078024614 0.9600078024614 0.96006802884276 0.96006802884276 0.96006802884276 0.96006802884276 0.96006802884276 0.96006802884276 0.96006802884276 0.96006802884276 0.96006802884267 0.96006802882497 0.96006802863493 0.96006802792686 0.96006802733718 0.96006802792686 0.96006802863493 0.96006802882497 0.96006802884267 0.96006802884276 0.96006802884276 0.96006802884276 0.96006802884276 0.96006802884276 0.96006802884276 0.96006802884276 0.96006802884276 0.96038137379852 0.96038137379852 0.96038137379852 0.96038137379852 0.96038137379852 0.96038137379852 0.96038137379851 0.96038137379854 0.96038137379712 0.96038137359152 0.96038137137588 0.96038136311132 0.96038135623538 0.96038136311132 0.96038137137588 0.96038137359152 0.96038137379712 0.96038137379854 0.96038137379851 0.96038137379852 0.96038137379852 0.96038137379852 0.96038137379852 0.96038137379852 0.96038137379852 0.96137903643732 0.96137903643732 0.96137903643732 0.96137903643732 0.96137903643732 0.96137903643732 0.96137903643732 0.96137903643733 0.96137903643076 0.96137903552684 0.96137902576482 0.96137898935413 0.96137895906936 0.96137898935413 0.96137902576482 0.96137903552684 0.96137903643076 0.96137903643733 0.96137903643732 0.96137903643732 0.96137903643732 0.96137903643732 0.96137903643732 0.96137903643732 0.96137903643732 0.96321014680893 0.96321014680893 0.96321014680893 0.96321014680893 0.96321014680893 0.96321014680893 0.96321014680895 0.96321014680885 0.96321014679832 0.96321014529002 0.96321012899152 0.96321006817364 0.9632100175864 0.96321006817364 0.96321012899152 0.96321014529002 0.96321014679832 0.96321014680885 0.96321014680895 0.96321014680893 0.96321014680893 0.96321014680893 0.96321014680893 0.96321014680893 0.96321014680893 0.96472448360735 0.96472448360735 0.96472448360735 0.96472448360735 0.96472448360735 0.96472448360735 0.96472448360736 0.96472448360735 0.96472448360078 0.96472448266336 0.96472447252939 0.96472443470448 0.96472440324446 0.96472443470448 0.96472447252939 0.96472448266336 0.96472448360078 0.96472448360735 0.96472448360736 0.96472448360735 0.96472448360735 0.96472448360735 0.96472448360735 0.96472448360735 0.96472448360735 0.96430483319369 0.96430483319369 0.96430483319369 0.96430483319369 0.96430483319369 0.96430483319369 0.96430483319369 0.96430483319372 0.96430483319207 0.96430483296631 0.96430483053594 0.96430482147442 0.96430481393844 0.96430482147442 0.96430483053594 0.96430483296631 0.96430483319207 0.96430483319372 0.96430483319369 0.96430483319369 0.96430483319369 0.96430483319369 0.96430483319369 0.96430483319369 0.96430483319369 0.96019082432575 0.96019082432575 0.96019082432575 0.96019082432575 0.96019082432575 0.96019082432575 0.96019082432575 0.96019082432575 0.96019082432576 0.96019082431475 0.96019082419333 0.96019082373483 0.96019082335182 0.96019082373483 0.96019082419333 0.96019082431475 0.96019082432576 0.96019082432575 0.96019082432575 0.96019082432575 0.96019082432575 0.96019082432575 0.96019082432575 0.96019082432575 0.96019082432575 0.96000932467124 0.96000932467124 0.96000932467124 0.96000932467124 0.96000932467124 0.96000932467124 0.96000932467124 0.96000932467124 0.96000932467124 0.96000932467127 0.96000932467156 0.96000932467266 0.96000932467357 0.96000932467266 0.96000932467156 0.96000932467127 0.96000932467124 0.96000932467124 0.96000932467124 0.96000932467124 0.96000932467124 0.96000932467124 0.96000932467124 0.96000932467124 0.96000932467124 0.96000014529282 0.96000014529282 0.96000014529282 0.96000014529282 0.96000014529282 0.96000014529282 0.96000014529282 0.96000014529282 0.96000014529282 0.96000014529282 0.96000014529282 0.96000014529279 0.96000014529278 0.96000014529279 0.96000014529282 0.96000014529282 0.96000014529282 0.96000014529282 0.96000014529282 0.96000014529282 0.96000014529282 0.96000014529282 0.96000014529282 0.96000014529282 0.96000014529282 0.96000000210283 0.96000000210283 0.96000000210283 0.96000000210283 0.96000000210283 0.96000000210283 0.96000000210283 0.96000000210283 0.96000000210283 0.96000000210283 0.96000000210283 0.96000000210283 0.96000000210283 0.96000000210283 0.96000000210283 0.96000000210283 0.96000000210283 0.96000000210283 0.96000000210283 0.96000000210283 0.96000000210283 0.96000000210283 0.96000000210283 0.96000000210283 0.96000000210283 0.96000000002503 0.96000000002503 0.96000000002503 0.96000000002503 0.96000000002503 0.96000000002503 0.96000000002503 0.96000000002503 0.96000000002503 0.96000000002503 0.96000000002503 0.96000000002503 0.96000000002503 0.96000000002503 0.96000000002503 0.96000000002503 0.96000000002503 0.96000000002503 0.96000000002503 0.96000000002503 0.96000000002503 0.96000000002503 0.96000000002503 0.96000000002503 0.96000000002503 0.96000000000025 0.96000000000025 0.96000000000025 0.96000000000025 0.96000000000025 0.96000000000025 0.96000000000025 0.96000000000025 0.96000000000025 0.96000000000025 0.96000000000025 0.96000000000025 0.96000000000025 0.96000000000025 0.96000000000025 0.96000000000025 0.96000000000025 0.96000000000025 0.96000000000025 0.96000000000025 0.96000000000025 0.96000000000025 0.96000000000025 0.96000000000025 0.96000000000025 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.96000000000049 0.96000000000049 0.96000000000049 0.96000000000049 0.96000000000049 0.96000000000049 0.96000000000049 0.96000000000049 0.96000000000049 0.96000000000049 0.96000000000049 0.96000000000049 0.96000000000049 0.96000000000049 0.96000000000049 0.96000000000049 0.96000000000049 0.96000000000049 0.96000000000049 0.96000000000049 0.96000000000049 0.96000000000049 0.96000000000049 0.96000000000049 0.96000000000049 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000804388 0.96000000804388 0.96000000804388 0.96000000804388 0.96000000804388 0.96000000804388 0.96000000804388 0.96000000804388 0.96000000804388 0.96000000804388 0.96000000804388 0.96000000804388 0.96000000804388 0.96000000804388 0.96000000804388 0.96000000804388 0.96000000804388 0.96000000804388 0.96000000804388 0.96000000804388 0.96000000804388 0.96000000804388 0.96000000804388 0.96000000804388 0.96000000804388 0.96000020225341 0.96000020225341 0.96000020225341 0.96000020225341 0.96000020225341 0.96000020225341 0.96000020225341 0.96000020225341 0.96000020225341 0.96000020225341 0.96000020225341 0.96000020225341 0.9600002022534 0.96000020225341 0.96000020225341 0.96000020225341 0.96000020225341 0.96000020225341 0.96000020225341 0.96000020225341 0.96000020225341 0.96000020225341 0.96000020225341 0.96000020225341 0.96000020225341 0.96000325281143 0.96000325281143 0.96000325281143 0.96000325281143 0.96000325281143 0.96000325281143 0.96000325281143 0.96000325281143 0.96000325281143 0.96000325281142 0.9600032528113 0.96000325281087 0.96000325281052 0.96000325281087 0.9600032528113 0.96000325281142 0.96000325281143 0.96000325281143 0.96000325281143 0.96000325281143 0.96000325281143 0.96000325281143 0.96000325281143 0.96000325281143 0.96000325281143 0.96003298088296 0.96003298088296 0.96003298088296 0.96003298088296 0.96003298088296 0.96003298088296 0.96003298088296 0.96003298088296 0.96003298088296 0.96003298088233 0.9600329808758 0.96003298085173 0.96003298083173 0.96003298085173 0.9600329808758 0.96003298088233 0.96003298088296 0.96003298088296 0.96003298088296 0.96003298088296 0.96003298088296 0.96003298088296 0.96003298088296 0.96003298088296 0.96003298088296 0.96021653301433 0.96021653301433 0.96021653301433 0.96021653301433 0.96021653301433 0.96021653301433 0.96021653301433 0.96021653301433 0.96021653301387 0.96021653293621 0.96021653210171 0.96021652898977 0.96021652639943 0.96021652898977 0.96021653210171 0.96021653293621 0.96021653301387 0.96021653301433 0.96021653301433 0.96021653301433 0.96021653301433 0.96021653301433 0.96021653301433 0.96021653301433 0.96021653301433 0.9609147657699 0.9609147657699 0.9609147657699 0.9609147657699 0.9609147657699 0.9609147657699 0.9609147657699 0.96091476576991 0.96091476576336 0.96091476486061 0.96091475511009 0.96091471874159 0.96091468849072 0.96091471874159 0.96091475511009 0.96091476486061 0.96091476576336 0.96091476576991 0.9609147657699 0.9609147657699 0.9609147657699 0.9609147657699 0.9609147657699 0.9609147657699 0.9609147657699 0.96249799243187 0.96249799243187 0.96249799243187 0.96249799243187 0.96249799243187 0.96249799243186 0.96249799243194 0.96249799243145 0.96249799240347 0.96249798832948 0.96249794431262 0.96249778003937 0.96249764334349 0.96249778003937 0.96249794431262 0.96249798832948 0.96249799240347 0.96249799243145 0.96249799243194 0.96249799243186 0.96249799243187 0.96249799243187 0.96249799243187 0.96249799243187 0.96249799243187 0.964334322046 0.964334322046 0.964334322046 0.964334322046 0.964334322046 0.96433432204598 0.96433432204609 0.96433432204522 0.96433432200005 0.96433431519141 0.96433424156069 0.9643339665361 0.96433373757564 0.9643339665361 0.96433424156069 0.96433431519141 0.96433432200005 0.96433432204522 0.96433432204609 0.96433432204598 0.964334322046 0.964334322046 0.964334322046 0.964334322046 0.964334322046 0.96481258179925 0.96481258179925 0.96481258179925 0.96481258179925 0.96481258179925 0.96481258179924 0.96481258179932 0.96481258179879 0.96481258177069 0.96481257753645 0.96481253174495 0.9648123607406 0.96481221843602 0.9648123607406 0.96481253174495 0.96481257753645 0.96481258177069 0.96481258179879 0.96481258179932 0.96481258179924 0.96481258179925 0.96481258179925 0.96481258179925 0.96481258179925 0.96481258179925 0.96336759080543 0.96336759080543 0.96336759080543 0.96336759080543 0.96336759080543 0.96336759080543 0.96336759080543 0.96336759080543 0.96336759079908 0.96336758987471 0.96336757987429 0.96336754253673 0.96336751147799 0.96336754253673 0.96336757987429 0.96336758987471 0.96336759079908 0.96336759080543 0.96336759080543 0.96336759080543 0.96336759080543 0.96336759080543 0.96336759080543 0.96336759080543 0.96336759080543 0.96143584361298 0.96143584361298 0.96143584361298 0.96143584361298 0.96143584361298 0.96143584361298 0.96143584361298 0.96143584361298 0.96143584361266 0.96143584354588 0.96143584282501 0.96143584013045 0.9614358378864 0.96143584013045 0.96143584282501 0.96143584354588 0.96143584361266 0.96143584361298 0.96143584361298 0.96143584361298 0.96143584361298 0.96143584361298 0.96143584361298 0.96143584361298 0.96143584361298 0.96040089864196 0.96040089864196 0.96040089864196 0.96040089864196 0.96040089864196 0.96040089864196 0.96040089864196 0.96040089864196 0.96040089864197 0.96040089864318 0.96040089865577 0.96040089870198 0.9604008987403 0.96040089870198 0.96040089865577 0.96040089864318 0.96040089864197 0.96040089864196 0.96040089864196 0.96040089864196 0.96040089864196 0.96040089864196 0.96040089864196 0.96040089864196 0.96040089864196 0.96000697925381 0.96000697925381 0.96000697925381 0.96000697925381 0.96000697925381 0.96000697925381 0.96000697925381 0.96000697925381 0.96000697925381 0.96000697925368 0.96000697925236 0.96000697924749 0.96000697924345 0.96000697924749 0.96000697925236 0.96000697925368 0.96000697925381 0.96000697925381 0.96000697925381 0.96000697925381 0.96000697925381 0.96000697925381 0.96000697925381 0.96000697925381 0.96000697925381 0.96000011362105 0.96000011362105 0.96000011362105 0.96000011362105 0.96000011362105 0.96000011362105 0.96000011362105 0.96000011362105 0.96000011362105 0.96000011362105 0.96000011362104 0.96000011362101 0.96000011362098 0.96000011362101 0.96000011362104 0.96000011362105 0.96000011362105 0.96000011362105 0.96000011362105 0.96000011362105 0.96000011362105 0.96000011362105 0.96000011362105 0.96000011362105 0.96000011362105 0.9600000014265 0.9600000014265 0.9600000014265 0.9600000014265 0.9600000014265 0.9600000014265 0.9600000014265 0.9600000014265 0.9600000014265 0.9600000014265 0.9600000014265 0.9600000014265 0.9600000014265 0.9600000014265 0.9600000014265 0.9600000014265 0.9600000014265 0.9600000014265 0.9600000014265 0.9600000014265 0.9600000014265 0.9600000014265 0.9600000014265 0.9600000014265 0.9600000014265 0.96000000001533 0.96000000001533 0.96000000001533 0.96000000001533 0.96000000001533 0.96000000001533 0.96000000001533 0.96000000001533 0.96000000001533 0.96000000001533 0.96000000001533 0.96000000001533 0.96000000001533 0.96000000001533 0.96000000001533 0.96000000001533 0.96000000001533 0.96000000001533 0.96000000001533 0.96000000001533 0.96000000001533 0.96000000001533 0.96000000001533 0.96000000001533 0.96000000001533 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.96000000000005 0.96000000000005 0.96000000000005 0.96000000000005 0.96000000000005 0.96000000000005 0.96000000000005 0.96000000000005 0.96000000000005 0.96000000000005 0.96000000000005 0.96000000000005 0.96000000000005 0.96000000000005 0.96000000000005 0.96000000000005 0.96000000000005 0.96000000000005 0.96000000000005 0.96000000000005 0.96000000000005 0.96000000000005 0.96000000000005 0.96000000000005 0.96000000000005 0.96000000000918 0.96000000000918 0.96000000000918 0.96000000000918 0.96000000000918 0.96000000000918 0.96000000000918 0.96000000000918 0.96000000000918 0.96000000000918 0.96000000000918 0.96000000000918 0.96000000000918 0.96000000000918 0.96000000000918 0.96000000000918 0.96000000000918 0.96000000000918 0.96000000000918 0.96000000000918 0.96000000000918 0.96000000000918 0.96000000000918 0.96000000000918 0.96000000000918 0.96000000079179 0.96000000079179 0.96000000079179 0.96000000079179 0.96000000079179 0.96000000079179 0.96000000079179 0.96000000079179 0.96000000079179 0.96000000079179 0.96000000079179 0.96000000079179 0.96000000079179 0.96000000079179 0.96000000079179 0.96000000079179 0.96000000079179 0.96000000079179 0.96000000079179 0.96000000079179 0.96000000079179 0.96000000079179 0.96000000079179 0.96000000079179 0.96000000079179 0.96000003419278 0.96000003419278 0.96000003419278 0.96000003419278 0.96000003419278 0.96000003419278 0.96000003419278 0.96000003419278 0.96000003419278 0.96000003419278 0.96000003419277 0.96000003419276 0.96000003419274 0.96000003419276 0.96000003419277 0.96000003419278 0.96000003419278 0.96000003419278 0.96000003419278 0.96000003419278 0.96000003419278 0.96000003419278 0.96000003419278 0.96000003419278 0.96000003419278 0.9600149885594 0.9600149885594 0.9600149885594 0.9600149885594 0.9600149885594 0.9600149885594 0.9600149885594 0.9600149885594 0.9600149885594 0.96001498855937 0.96001498855903 0.96001498855777 0.96001498855672 0.96001498855777 0.96001498855903 0.96001498855937 0.9600149885594 0.9600149885594 0.9600149885594 0.9600149885594 0.9600149885594 0.9600149885594 0.9600149885594 0.9600149885594 0.9600149885594 0.96011618398765 0.96011618398765 0.96011618398765 0.96011618398765 0.96011618398765 0.96011618398765 0.96011618398765 0.96011618398765 0.96011618398764 0.96011618398599 0.96011618396883 0.96011618390582 0.96011618385351 0.96011618390582 0.96011618396883 0.96011618398599 0.96011618398764 0.96011618398765 0.96011618398765 0.96011618398765 0.96011618398765 0.96011618398765 0.96011618398765 0.96011618398765 0.96011618398765 0.96057389899636 0.96057389899636 0.96057389899636 0.96057389899636 0.96057389899636 0.96057389899636 0.96057389899635 0.96057389899636 0.96057389899562 0.96057389887514 0.96057389757742 0.96057389273422 0.96057388870364 0.96057389273422 0.96057389757742 0.96057389887514 0.96057389899562 0.96057389899636 0.96057389899635 0.96057389899636 0.96057389899636 0.96057389899636 0.96057389899636 0.96057389899636 0.96057389899636 0.96183629361123 0.96183629361123 0.96183629361123 0.96183629361123 0.96183629361123 0.96183629361122 0.96183629361124 0.96183629361116 0.96183629360059 0.96183629211335 0.96183627604931 0.96183621612527 0.96183616628099 0.96183621612527 0.96183627604931 0.96183629211335 0.96183629360059 0.96183629361116 0.96183629361124 0.96183629361122 0.96183629361123 0.96183629361123 0.96183629361123 0.96183629361123 0.96183629361123 0.96374953553679 0.96374953553679 0.96374953553679 0.96374953553679 0.96374953553679 0.96374953553677 0.96374953553688 0.96374953553603 0.96374953549077 0.9637495287244 0.96374945556744 0.96374918235336 0.96374895490264 0.96374918235336 0.96374945556744 0.9637495287244 0.96374953549077 0.96374953553603 0.96374953553688 0.96374953553677 0.96374953553679 0.96374953553679 0.96374953553679 0.96374953553679 0.96374953553679 0.96487828647848 0.96487828647848 0.96487828647848 0.96487828647848 0.96487828647848 0.96487828647846 0.96487828647859 0.96487828647723 0.9648782864029 0.96487827506076 0.9648781523473 0.96487769368186 0.96487731156637 0.96487769368186 0.9648781523473 0.96487827506076 0.9648782864029 0.96487828647723 0.96487828647859 0.96487828647846 0.96487828647848 0.96487828647848 0.96487828647848 0.96487828647848 0.96487828647848 0.96403753353408 0.96403753353408 0.96403753353408 0.96403753353408 0.96403753353408 0.96403753353407 0.96403753353418 0.96403753353333 0.96403753348892 0.96403752666429 0.96403745281019 0.96403717686123 0.96403694710762 0.96403717686123 0.96403745281019 0.96403752666429 0.96403753348892 0.96403753353333 0.96403753353418 0.96403753353407 0.96403753353408 0.96403753353408 0.96403753353408 0.96403753353408 0.96403753353408 0.96213071462991 0.96213071462991 0.96213071462991 0.96213071462991 0.96213071462991 0.9621307146299 0.96213071462992 0.96213071462984 0.96213071461969 0.96213071311423 0.96213069682395 0.96213063599922 0.96213058539482 0.96213063599922 0.96213069682395 0.96213071311423 0.96213071461969 0.96213071462984 0.96213071462992 0.9621307146299 0.96213071462991 0.96213071462991 0.96213071462991 0.96213071462991 0.96213071462991 0.96071011797522 0.96071011797522 0.96071011797522 0.96071011797522 0.96071011797522 0.96071011797522 0.96071011797522 0.96071011797523 0.96071011797456 0.96071011785818 0.96071011660284 0.96071011191419 0.96071010801161 0.96071011191419 0.96071011660284 0.96071011785818 0.96071011797456 0.96071011797523 0.96071011797522 0.96071011797522 0.96071011797522 0.96071011797522 0.96071011797522 0.96071011797522 0.96071011797522 0.9601508434791 0.9601508434791 0.9601508434791 0.9601508434791 0.9601508434791 0.9601508434791 0.9601508434791 0.9601508434791 0.96015084347909 0.96015084347783 0.96015084346476 0.96015084341687 0.96015084337711 0.96015084341687 0.96015084346476 0.96015084347783 0.96015084347909 0.9601508434791 0.9601508434791 0.9601508434791 0.9601508434791 0.9601508434791 0.9601508434791 0.9601508434791 0.9601508434791 0.9600196248461 0.9600196248461 0.9600196248461 0.9600196248461 0.9600196248461 0.9600196248461 0.9600196248461 0.9600196248461 0.9600196248461 0.96001962484607 0.96001962484575 0.9600196248446 0.96001962484365 0.9600196248446 0.96001962484575 0.96001962484607 0.9600196248461 0.9600196248461 0.9600196248461 0.9600196248461 0.9600196248461 0.9600196248461 0.9600196248461 0.9600196248461 0.9600196248461 0.96000036744425 0.96000036744425 0.96000036744425 0.96000036744425 0.96000036744425 0.96000036744425 0.96000036744425 0.96000036744425 0.96000036744425 0.96000036744425 0.96000036744425 0.96000036744423 0.96000036744422 0.96000036744423 0.96000036744425 0.96000036744425 0.96000036744425 0.96000036744425 0.96000036744425 0.96000036744425 0.96000036744425 0.96000036744425 0.96000036744425 0.96000036744425 0.96000036744425 0.96000000570381 0.96000000570381 0.96000000570381 0.96000000570381 0.96000000570381 0.96000000570381 0.96000000570381 0.96000000570381 0.96000000570381 0.96000000570381 0.96000000570381 0.96000000570381 0.96000000570381 0.96000000570381 0.96000000570381 0.96000000570381 0.96000000570381 0.96000000570381 0.96000000570381 0.96000000570381 0.96000000570381 0.96000000570381 0.96000000570381 0.96000000570381 0.96000000570381 0.96000000007383 0.96000000007383 0.96000000007383 0.96000000007383 0.96000000007383 0.96000000007383 0.96000000007383 0.96000000007383 0.96000000007383 0.96000000007383 0.96000000007383 0.96000000007383 0.96000000007383 0.96000000007383 0.96000000007383 0.96000000007383 0.96000000007383 0.96000000007383 0.96000000007383 0.96000000007383 0.96000000007383 0.96000000007383 0.96000000007383 0.96000000007383 0.96000000007383 0.96000000000109 0.96000000000109 0.96000000000109 0.96000000000109 0.96000000000109 0.96000000000109 0.96000000000109 0.96000000000109 0.96000000000109 0.96000000000109 0.96000000000109 0.96000000000109 0.96000000000109 0.96000000000109 0.96000000000109 0.96000000000109 0.96000000000109 0.96000000000109 0.96000000000109 0.96000000000109 0.96000000000109 0.96000000000109 0.96000000000109 0.96000000000109 0.96000000000109 0.95999999999988 0.95999999999988 0.95999999999988 0.95999999999988 0.95999999999988 0.95999999999988 0.95999999999988 0.95999999999988 0.95999999999988 0.95999999999988 0.95999999999988 0.95999999999988 0.95999999999988 0.95999999999988 0.95999999999988 0.95999999999988 0.95999999999988 0.95999999999988 0.95999999999988 0.95999999999988 0.95999999999988 0.95999999999988 0.95999999999988 0.95999999999988 0.95999999999988 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.96000000000232 0.96000000000232 0.96000000000232 0.96000000000232 0.96000000000232 0.96000000000232 0.96000000000232 0.96000000000232 0.96000000000232 0.96000000000232 0.96000000000232 0.96000000000232 0.96000000000232 0.96000000000232 0.96000000000232 0.96000000000232 0.96000000000232 0.96000000000232 0.96000000000232 0.96000000000232 0.96000000000232 0.96000000000232 0.96000000000232 0.96000000000232 0.96000000000232 0.96000000018275 0.96000000018275 0.96000000018275 0.96000000018275 0.96000000018275 0.96000000018275 0.96000000018275 0.96000000018275 0.96000000018275 0.96000000018275 0.96000000018275 0.96000000018275 0.96000000018275 0.96000000018275 0.96000000018275 0.96000000018275 0.96000000018275 0.96000000018275 0.96000000018275 0.96000000018275 0.96000000018275 0.96000000018275 0.96000000018275 0.96000000018275 0.96000000018275 0.96000001363188 0.96000001363188 0.96000001363188 0.96000001363188 0.96000001363188 0.96000001363188 0.96000001363188 0.96000001363188 0.96000001363188 0.96000001363188 0.96000001363187 0.96000001363183 0.9600000136318 0.96000001363183 0.96000001363187 0.96000001363188 0.96000001363188 0.96000001363188 0.96000001363188 0.96000001363188 0.96000001363188 0.96000001363188 0.96000001363188 0.96000001363188 0.96000001363188 0.96000111210589 0.96000111210589 0.96000111210589 0.96000111210589 0.96000111210589 0.96000111210589 0.96000111210589 0.96000111210589 0.96000111210588 0.96000111210575 0.96000111210433 0.96000111209908 0.96000111209473 0.96000111209908 0.96000111210433 0.96000111210575 0.96000111210588 0.96000111210589 0.96000111210589 0.96000111210589 0.96000111210589 0.96000111210589 0.96000111210589 0.96000111210589 0.96000111210589 0.96033224617124 0.96033224617124 0.96033224617124 0.96033224617124 0.96033224617124 0.96033224617124 0.96033224617124 0.96033224617124 0.96033224617125 0.96033224617226 0.96033224618278 0.96033224622142 0.96033224625347 0.96033224622142 0.96033224618278 0.96033224617226 0.96033224617125 0.96033224617124 0.96033224617124 0.96033224617124 0.96033224617124 0.96033224617124 0.96033224617124 0.96033224617124 0.96033224617124 0.96126932110788 0.96126932110788 0.96126932110788 0.96126932110788 0.96126932110788 0.96126932110788 0.96126932110787 0.96126932110788 0.96126932110752 0.96126932104009 0.96126932031355 0.96126931760025 0.961269315341 0.96126931760025 0.96126932031355 0.96126932104009 0.96126932110752 0.96126932110788 0.96126932110787 0.96126932110788 0.96126932110788 0.96126932110788 0.96126932110788 0.96126932110788 0.96126932110788 0.96305949909787 0.96305949909787 0.96305949909787 0.96305949909787 0.96305949909787 0.96305949909786 0.96305949909787 0.96305949909786 0.96305949909115 0.96305949816147 0.96305948812066 0.96305945066439 0.96305941951215 0.96305945066439 0.96305948812066 0.96305949816147 0.96305949909115 0.96305949909786 0.96305949909787 0.96305949909786 0.96305949909787 0.96305949909787 0.96305949909787 0.96305949909787 0.96305949909787 0.96466883490351 0.96466883490351 0.96466883490351 0.96466883490351 0.9646688349035 0.96466883490349 0.96466883490357 0.96466883490304 0.96466883487489 0.96466883066562 0.9646687851556 0.96466861522582 0.96466847382042 0.96466861522582 0.9646687851556 0.96466883066562 0.96466883487489 0.96466883490304 0.96466883490357 0.96466883490349 0.9646688349035 0.96466883490351 0.96466883490351 0.96466883490351 0.96466883490351 0.96456048864478 0.96456048864478 0.96456048864478 0.96456048864478 0.96456048864478 0.96456048864476 0.96456048864487 0.96456048864401 0.96456048859914 0.96456048174206 0.96456040755388 0.96456013037967 0.96455989961608 0.96456013037967 0.96456040755388 0.96456048174206 0.96456048859914 0.96456048864401 0.96456048864487 0.96456048864476 0.96456048864478 0.96456048864478 0.96456048864478 0.96456048864478 0.96456048864478 0.96281609353146 0.96281609353146 0.96281609353146 0.96281609353146 0.96281609353146 0.96281609353145 0.96281609353152 0.96281609353106 0.96281609350432 0.96281608939444 0.96281604490869 0.96281587872987 0.96281574041835 0.96281587872987 0.96281604490869 0.96281608939444 0.96281609350432 0.96281609353106 0.96281609353152 0.96281609353145 0.96281609353146 0.96281609353146 0.96281609353146 0.96281609353146 0.96281609353146 0.96111125786873 0.96111125786873 0.96111125786873 0.96111125786873 0.96111125786873 0.96111125786873 0.96111125786873 0.96111125786875 0.96111125786243 0.96111125695906 0.96111124718917 0.96111121072379 0.96111118038786 0.96111121072379 0.96111124718917 0.96111125695906 0.96111125786243 0.96111125786875 0.96111125786873 0.96111125786873 0.96111125786873 0.96111125786873 0.96111125786873 0.96111125786873 0.96111125786873 0.96027471074325 0.96027471074325 0.96027471074325 0.96027471074325 0.96027471074325 0.96027471074325 0.96027471074325 0.96027471074325 0.9602747107428 0.96027471066573 0.96027470983716 0.9602747067466 0.96027470417394 0.9602747067466 0.96027470983716 0.96027471066573 0.9602747107428 0.96027471074325 0.96027471074325 0.96027471074325 0.96027471074325 0.96027471074325 0.96027471074325 0.96027471074325 0.96027471074325 0.96004459277341 0.96004459277341 0.96004459277341 0.96004459277341 0.96004459277341 0.96004459277341 0.96004459277341 0.96004459277341 0.9600445927734 0.96004459277274 0.96004459276578 0.96004459274017 0.96004459271889 0.96004459274017 0.96004459276578 0.96004459277274 0.9600445927734 0.96004459277341 0.96004459277341 0.96004459277341 0.96004459277341 0.96004459277341 0.96004459277341 0.96004459277341 0.96004459277341 0.96000499233933 0.96000499233933 0.96000499233933 0.96000499233933 0.96000499233933 0.96000499233933 0.96000499233933 0.96000499233933 0.96000499233933 0.96000499233932 0.96000499233918 0.96000499233868 0.96000499233826 0.96000499233868 0.96000499233918 0.96000499233932 0.96000499233933 0.96000499233933 0.96000499233933 0.96000499233933 0.96000499233933 0.96000499233933 0.96000499233933 0.96000499233933 0.96000499233933 0.96000031117462 0.96000031117462 0.96000031117462 0.96000031117462 0.96000031117462 0.96000031117462 0.96000031117462 0.96000031117462 0.96000031117462 0.96000031117462 0.96000031117462 0.96000031117461 0.96000031117461 0.96000031117461 0.96000031117462 0.96000031117462 0.96000031117462 0.96000031117462 0.96000031117462 0.96000031117462 0.96000031117462 0.96000031117462 0.96000031117462 0.96000031117462 0.96000031117462 0.96000001433426 0.96000001433426 0.96000001433426 0.96000001433426 0.96000001433426 0.96000001433426 0.96000001433426 0.96000001433426 0.96000001433426 0.96000001433426 0.96000001433426 0.96000001433426 0.96000001433426 0.96000001433426 0.96000001433426 0.96000001433426 0.96000001433426 0.96000001433426 0.96000001433426 0.96000001433426 0.96000001433426 0.96000001433426 0.96000001433426 0.96000001433426 0.96000001433426 0.96000000025446 0.96000000025446 0.96000000025446 0.96000000025446 0.96000000025446 0.96000000025446 0.96000000025446 0.96000000025446 0.96000000025446 0.96000000025446 0.96000000025446 0.96000000025446 0.96000000025446 0.96000000025446 0.96000000025446 0.96000000025446 0.96000000025446 0.96000000025446 0.96000000025446 0.96000000025446 0.96000000025446 0.96000000025446 0.96000000025446 0.96000000025446 0.96000000025446 0.96000000000415 0.96000000000415 0.96000000000415 0.96000000000415 0.96000000000415 0.96000000000415 0.96000000000415 0.96000000000415 0.96000000000415 0.96000000000415 0.96000000000415 0.96000000000415 0.96000000000415 0.96000000000415 0.96000000000415 0.96000000000415 0.96000000000415 0.96000000000415 0.96000000000415 0.96000000000415 0.96000000000415 0.96000000000415 0.96000000000415 0.96000000000415 0.96000000000415 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.9600000000212 0.9600000000212 0.9600000000212 0.9600000000212 0.9600000000212 0.9600000000212 0.9600000000212 0.9600000000212 0.9600000000212 0.9600000000212 0.9600000000212 0.9600000000212 0.9600000000212 0.9600000000212 0.9600000000212 0.9600000000212 0.9600000000212 0.9600000000212 0.9600000000212 0.9600000000212 0.9600000000212 0.9600000000212 0.9600000000212 0.9600000000212 0.9600000000212 0.960000001965 0.960000001965 0.960000001965 0.960000001965 0.960000001965 0.960000001965 0.960000001965 0.960000001965 0.960000001965 0.960000001965 0.960000001965 0.96000000196499 0.96000000196499 0.96000000196499 0.960000001965 0.960000001965 0.960000001965 0.960000001965 0.960000001965 0.960000001965 0.960000001965 0.960000001965 0.960000001965 0.960000001965 0.960000001965 0.96000015611273 0.96000015611273 0.96000015611273 0.96000015611273 0.96000015611273 0.96000015611273 0.96000015611273 0.96000015611273 0.96000015611273 0.96000015611273 0.96000015611271 0.96000015611266 0.96000015611262 0.96000015611266 0.96000015611271 0.96000015611273 0.96000015611273 0.96000015611273 0.96000015611273 0.96000015611273 0.96000015611273 0.96000015611273 0.96000015611273 0.96000015611273 0.96000015611273 0.96001764480948 0.96001764480948 0.96001764480948 0.96001764480948 0.96001764480948 0.96001764480948 0.96001764480948 0.96001764480948 0.96001764480948 0.96001764480942 0.96001764480884 0.96001764480673 0.96001764480496 0.96001764480673 0.96001764480884 0.96001764480942 0.96001764480948 0.96001764480948 0.96001764480948 0.96001764480948 0.96001764480948 0.96001764480948 0.96001764480948 0.96001764480948 0.96001764480948 0.96006279164586 0.96006279164586 0.96006279164586 0.96006279164586 0.96006279164586 0.96006279164586 0.96006279164586 0.96006279164586 0.96006279164581 0.96006279163295 0.96006279149437 0.96006279097683 0.96006279054534 0.96006279097683 0.96006279149437 0.96006279163295 0.96006279164581 0.96006279164586 0.96006279164586 0.96006279164586 0.96006279164586 0.96006279164586 0.96006279164586 0.96006279164586 0.96006279164586 0.96400989035802 0.96400989035802 0.96400989035802 0.96400989035802 0.96400989035802 0.96400989035802 0.96400989035801 0.96400989035804 0.96400989035652 0.96400989013945 0.96400988779989 0.96400987907136 0.96400987181106 0.96400987907136 0.96400988779989 0.96400989013945 0.96400989035652 0.96400989035804 0.96400989035801 0.96400989035802 0.96400989035802 0.96400989035802 0.96400989035802 0.96400989035802 0.96400989035802 0.96485606976477 0.96485606976477 0.96485606976477 0.96485606976477 0.96485606976477 0.96485606976477 0.96485606976478 0.96485606976476 0.96485606975791 0.96485606879102 0.96485605834299 0.96485601935399 0.96485598692712 0.96485601935399 0.96485605834299 0.96485606879102 0.96485606975791 0.96485606976476 0.96485606976478 0.96485606976477 0.96485606976477 0.96485606976477 0.96485606976477 0.96485606976477 0.96485606976477 0.96351313793838 0.96351313793838 0.96351313793838 0.96351313793838 0.96351313793838 0.96351313793837 0.96351313793839 0.9635131379383 0.96351313792819 0.96351313641333 0.96351312001869 0.963513058795 0.96351300786241 0.963513058795 0.96351312001869 0.96351313641333 0.96351313792819 0.9635131379383 0.96351313793839 0.96351313793837 0.96351313793838 0.96351313793838 0.96351313793838 0.96351313793838 0.96351313793838 0.96163554558384 0.96163554558384 0.96163554558384 0.96163554558384 0.96163554558384 0.96163554558383 0.96163554558384 0.96163554558385 0.96163554557755 0.96163554466832 0.96163553483201 0.96163549811157 0.96163546756308 0.96163549811157 0.96163553483201 0.96163554466832 0.96163554557755 0.96163554558385 0.96163554558384 0.96163554558383 0.96163554558384 0.96163554558384 0.96163554558384 0.96163554558384 0.96163554558384 0.96047642292959 0.96047642292959 0.96047642292959 0.96047642292959 0.96047642292959 0.96047642292959 0.96047642292959 0.96047642292961 0.96047642292822 0.96047642272307 0.96047642051116 0.96047641225836 0.96047640539179 0.96047641225836 0.96047642051116 0.96047642272307 0.96047642292822 0.96047642292961 0.96047642292959 0.96047642292959 0.96047642292959 0.96047642292959 0.96047642292959 0.96047642292959 0.96047642292959 0.9600895136462 0.9600895136462 0.9600895136462 0.9600895136462 0.9600895136462 0.9600895136462 0.9600895136462 0.9600895136462 0.9600895136461 0.96008951362844 0.9600895134387 0.96008951273172 0.96008951214295 0.96008951273172 0.9600895134387 0.96008951362844 0.9600895136461 0.9600895136462 0.9600895136462 0.9600895136462 0.9600895136462 0.9600895136462 0.9600895136462 0.9600895136462 0.9600895136462 0.96001112432289 0.96001112432289 0.96001112432289 0.96001112432289 0.96001112432289 0.96001112432289 0.96001112432289 0.96001112432289 0.96001112432289 0.96001112432276 0.96001112432141 0.96001112431642 0.96001112431228 0.96001112431642 0.96001112432141 0.96001112432276 0.96001112432289 0.96001112432289 0.96001112432289 0.96001112432289 0.96001112432289 0.96001112432289 0.96001112432289 0.96001112432289 0.96001112432289 0.96000091493657 0.96000091493657 0.96000091493657 0.96000091493657 0.96000091493657 0.96000091493657 0.96000091493657 0.96000091493657 0.96000091493657 0.96000091493657 0.96000091493655 0.96000091493648 0.96000091493643 0.96000091493648 0.96000091493655 0.96000091493657 0.96000091493657 0.96000091493657 0.96000091493657 0.96000091493657 0.96000091493657 0.96000091493657 0.96000091493657 0.96000091493657 0.96000091493657 0.96000005380412 0.96000005380412 0.96000005380412 0.96000005380412 0.96000005380412 0.96000005380412 0.96000005380412 0.96000005380412 0.96000005380412 0.96000005380412 0.96000005380412 0.96000005380412 0.96000005380411 0.96000005380412 0.96000005380412 0.96000005380412 0.96000005380412 0.96000005380412 0.96000005380412 0.96000005380412 0.96000005380412 0.96000005380412 0.96000005380412 0.96000005380412 0.96000005380412 0.96000000216497 0.96000000216497 0.96000000216497 0.96000000216497 0.96000000216497 0.96000000216497 0.96000000216497 0.96000000216497 0.96000000216497 0.96000000216497 0.96000000216497 0.96000000216497 0.96000000216497 0.96000000216497 0.96000000216497 0.96000000216497 0.96000000216497 0.96000000216497 0.96000000216497 0.96000000216497 0.96000000216497 0.96000000216497 0.96000000216497 0.96000000216497 0.96000000216497 0.96000000005184 0.96000000005184 0.96000000005184 0.96000000005184 0.96000000005184 0.96000000005184 0.96000000005184 0.96000000005184 0.96000000005184 0.96000000005184 0.96000000005184 0.96000000005184 0.96000000005184 0.96000000005184 0.96000000005184 0.96000000005184 0.96000000005184 0.96000000005184 0.96000000005184 0.96000000005184 0.96000000005184 0.96000000005184 0.96000000005184 0.96000000005184 0.96000000005184 0.96000000000113 0.96000000000113 0.96000000000113 0.96000000000113 0.96000000000113 0.96000000000113 0.96000000000113 0.96000000000113 0.96000000000113 0.96000000000113 0.96000000000113 0.96000000000113 0.96000000000113 0.96000000000113 0.96000000000113 0.96000000000113 0.96000000000113 0.96000000000113 0.96000000000113 0.96000000000113 0.96000000000113 0.96000000000113 0.96000000000113 0.96000000000113 0.96000000000113 0.95999999999986 0.95999999999986 0.95999999999986 0.95999999999986 0.95999999999986 0.95999999999986 0.95999999999986 0.95999999999986 0.95999999999986 0.95999999999986 0.95999999999986 0.95999999999986 0.95999999999986 0.95999999999986 0.95999999999986 0.95999999999986 0.95999999999986 0.95999999999986 0.95999999999986 0.95999999999986 0.95999999999986 0.95999999999986 0.95999999999986 0.95999999999986 0.95999999999986 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.95999999999994 0.95999999999994 0.95999999999994 0.95999999999994 0.95999999999994 0.95999999999994 0.95999999999994 0.95999999999994 0.95999999999994 0.95999999999994 0.95999999999994 0.95999999999994 0.95999999999994 0.95999999999994 0.95999999999994 0.95999999999994 0.95999999999994 0.95999999999994 0.95999999999994 0.95999999999994 0.95999999999994 0.95999999999994 0.95999999999994 0.95999999999994 0.95999999999994 0.96000000000048 0.96000000000048 0.96000000000048 0.96000000000048 0.96000000000048 0.96000000000048 0.96000000000048 0.96000000000048 0.96000000000048 0.96000000000048 0.96000000000048 0.96000000000048 0.96000000000048 0.96000000000048 0.96000000000048 0.96000000000048 0.96000000000048 0.96000000000048 0.96000000000048 0.96000000000048 0.96000000000048 0.96000000000048 0.96000000000048 0.96000000000048 0.96000000000048 0.96000000004002 0.96000000004002 0.96000000004002 0.96000000004002 0.96000000004002 0.96000000004002 0.96000000004002 0.96000000004002 0.96000000004002 0.96000000004002 0.96000000004002 0.96000000004002 0.96000000004002 0.96000000004002 0.96000000004002 0.96000000004002 0.96000000004002 0.96000000004002 0.96000000004002 0.96000000004002 0.96000000004002 0.96000000004002 0.96000000004002 0.96000000004002 0.96000000004002 0.96000000333307 0.96000000333307 0.96000000333307 0.96000000333307 0.96000000333307 0.96000000333307 0.96000000333307 0.96000000333307 0.96000000333307 0.96000000333307 0.96000000333307 0.96000000333306 0.96000000333306 0.96000000333306 0.96000000333307 0.96000000333307 0.96000000333307 0.96000000333307 0.96000000333307 0.96000000333307 0.96000000333307 0.96000000333307 0.96000000333307 0.96000000333307 0.96000000333307 0.96000032143279 0.96000032143279 0.96000032143279 0.96000032143279 0.96000032143279 0.96000032143279 0.96000032143279 0.96000032143279 0.96000032143279 0.96000032143278 0.96000032143268 0.96000032143232 0.96000032143201 0.96000032143232 0.96000032143268 0.96000032143278 0.96000032143279 0.96000032143279 0.96000032143279 0.96000032143279 0.96000032143279 0.96000032143279 0.96000032143279 0.96000032143279 0.96000032143279 0.96000308149917 0.96000308149917 0.96000308149917 0.96000308149917 0.96000308149917 0.96000308149917 0.96000308149916 0.96000308149917 0.96000308149916 0.96000308149771 0.96000308148218 0.96000308142432 0.96000308137613 0.96000308142432 0.96000308148218 0.96000308149771 0.96000308149916 0.96000308149917 0.96000308149916 0.96000308149917 0.96000308149917 0.96000308149917 0.96000308149917 0.96000308149917 0.96000308149917 0.96017194993358 0.96017194993358 0.96017194993358 0.96017194993358 0.96017194993358 0.96017194993358 0.96017194993358 0.96017194993358 0.96017194993357 0.96017194992391 0.96017194981823 0.96017194942076 0.96017194908906 0.96017194942076 0.96017194981823 0.96017194992391 0.96017194993357 0.96017194993358 0.96017194993358 0.96017194993358 0.96017194993358 0.96017194993358 0.96017194993358 0.96017194993358 0.96017194993358 0.96391155244328 0.96391155244328 0.96391155244328 0.96391155244328 0.96391155244328 0.96391155244328 0.96391155244328 0.96391155244328 0.96391155244324 0.96391155239908 0.9639115519151 0.96391155009172 0.9639115485704 0.96391155009172 0.9639115519151 0.96391155239908 0.96391155244324 0.96391155244328 0.96391155244328 0.96391155244328 0.96391155244328 0.96391155244328 0.96391155244328 0.96391155244328 0.96391155244328 0.96224311853402 0.96224311853402 0.96224311853402 0.96224311853402 0.96224311853402 0.96224311853402 0.96224311853402 0.96224311853403 0.96224311853335 0.96224311841748 0.96224311716783 0.9622431125003 0.96224310861581 0.9622431125003 0.96224311716783 0.96224311841748 0.96224311853335 0.96224311853403 0.96224311853402 0.96224311853402 0.96224311853402 0.96224311853402 0.96224311853402 0.96224311853402 0.96224311853402 0.96078380667 0.96078380667 0.96078380667 0.96078380667 0.96078380667 0.96078380667 0.96078380667 0.96078380667 0.9607838066696 0.96078380659643 0.96078380580856 0.96078380286718 0.9607838004182 0.96078380286718 0.96078380580856 0.96078380659643 0.9607838066696 0.96078380667 0.96078380667 0.96078380667 0.96078380667 0.96078380667 0.96078380667 0.96078380667 0.96078380667 0.9601705079647 0.9601705079647 0.9601705079647 0.9601705079647 0.9601705079647 0.9601705079647 0.9601705079647 0.9601705079647 0.96017050796461 0.96017050794711 0.96017050775915 0.96017050705865 0.96017050647523 0.96017050705865 0.96017050775915 0.96017050794711 0.96017050796461 0.9601705079647 0.9601705079647 0.9601705079647 0.9601705079647 0.9601705079647 0.9601705079647 0.9601705079647 0.9601705079647 0.96002464093767 0.96002464093767 0.96002464093767 0.96002464093767 0.96002464093767 0.96002464093767 0.96002464093767 0.96002464093767 0.96002464093766 0.96002464093612 0.96002464091957 0.96002464085794 0.96002464080663 0.96002464085794 0.96002464091957 0.96002464093612 0.96002464093766 0.96002464093767 0.96002464093767 0.96002464093767 0.96002464093767 0.96002464093767 0.96002464093767 0.96002464093767 0.96002464093767 0.96000234110585 0.96000234110585 0.96000234110585 0.96000234110585 0.96000234110585 0.96000234110585 0.96000234110585 0.96000234110585 0.96000234110585 0.96000234110584 0.96000234110572 0.96000234110529 0.96000234110492 0.96000234110529 0.96000234110572 0.96000234110584 0.96000234110585 0.96000234110585 0.96000234110585 0.96000234110585 0.96000234110585 0.96000234110585 0.96000234110585 0.96000234110585 0.96000234110585 0.96000014892106 0.96000014892106 0.96000014892106 0.96000014892106 0.96000014892106 0.96000014892106 0.96000014892106 0.96000014892106 0.96000014892106 0.96000014892106 0.96000014892106 0.96000014892105 0.96000014892105 0.96000014892105 0.96000014892106 0.96000014892106 0.96000014892106 0.96000014892106 0.96000014892106 0.96000014892106 0.96000014892106 0.96000014892106 0.96000014892106 0.96000014892106 0.96000014892106 0.9600000065405 0.9600000065405 0.9600000065405 0.9600000065405 0.9600000065405 0.9600000065405 0.9600000065405 0.9600000065405 0.9600000065405 0.9600000065405 0.9600000065405 0.9600000065405 0.9600000065405 0.9600000065405 0.9600000065405 0.9600000065405 0.9600000065405 0.9600000065405 0.9600000065405 0.9600000065405 0.9600000065405 0.9600000065405 0.9600000065405 0.9600000065405 0.9600000065405 0.96000000020369 0.96000000020369 0.96000000020369 0.96000000020369 0.96000000020369 0.96000000020369 0.96000000020369 0.96000000020369 0.96000000020369 0.96000000020369 0.96000000020369 0.96000000020369 0.96000000020369 0.96000000020369 0.96000000020369 0.96000000020369 0.96000000020369 0.96000000020369 0.96000000020369 0.96000000020369 0.96000000020369 0.96000000020369 0.96000000020369 0.96000000020369 0.96000000020369 0.96000000000543 0.96000000000543 0.96000000000543 0.96000000000543 0.96000000000543 0.96000000000543 0.96000000000543 0.96000000000543 0.96000000000543 0.96000000000543 0.96000000000543 0.96000000000543 0.96000000000543 0.96000000000543 0.96000000000543 0.96000000000543 0.96000000000543 0.96000000000543 0.96000000000543 0.96000000000543 0.96000000000543 0.96000000000543 0.96000000000543 0.96000000000543 0.96000000000543 0.95999999999992 0.95999999999992 0.95999999999992 0.95999999999992 0.95999999999992 0.95999999999992 0.95999999999992 0.95999999999992 0.95999999999992 0.95999999999992 0.95999999999992 0.95999999999992 0.95999999999992 0.95999999999992 0.95999999999992 0.95999999999992 0.95999999999992 0.95999999999992 0.95999999999992 0.95999999999992 0.95999999999992 0.95999999999992 0.95999999999992 0.95999999999992 0.95999999999992 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.9600000000006 0.9600000000006 0.9600000000006 0.9600000000006 0.9600000000006 0.9600000000006 0.9600000000006 0.9600000000006 0.9600000000006 0.9600000000006 0.9600000000006 0.9600000000006 0.9600000000006 0.9600000000006 0.9600000000006 0.9600000000006 0.9600000000006 0.9600000000006 0.9600000000006 0.9600000000006 0.9600000000006 0.9600000000006 0.9600000000006 0.9600000000006 0.9600000000006 0.96000000005181 0.96000000005181 0.96000000005181 0.96000000005181 0.96000000005181 0.96000000005181 0.96000000005181 0.96000000005181 0.96000000005181 0.96000000005181 0.96000000005181 0.96000000005181 0.96000000005181 0.96000000005181 0.96000000005181 0.96000000005181 0.96000000005181 0.96000000005181 0.96000000005181 0.96000000005181 0.96000000005181 0.96000000005181 0.96000000005181 0.96000000005181 0.96000000005181 0.96000000471331 0.96000000471331 0.96000000471331 0.96000000471331 0.96000000471331 0.96000000471331 0.96000000471331 0.96000000471331 0.96000000471331 0.96000000471331 0.96000000471331 0.9600000047133 0.9600000047133 0.9600000047133 0.96000000471331 0.96000000471331 0.96000000471331 0.96000000471331 0.96000000471331 0.96000000471331 0.96000000471331 0.96000000471331 0.96000000471331 0.96000000471331 0.96000000471331 0.96000009639196 0.96000009639196 0.96000009639196 0.96000009639196 0.96000009639196 0.96000009639196 0.96000009639196 0.96000009639196 0.96000009639196 0.96000009639195 0.96000009639181 0.9600000963913 0.96000009639088 0.9600000963913 0.96000009639181 0.96000009639195 0.96000009639196 0.96000009639196 0.96000009639196 0.96000009639196 0.96000009639196 0.96000009639196 0.96000009639196 0.96000009639196 0.96000009639196 0.96000622376079 0.96000622376079 0.96000622376079 0.96000622376079 0.96000622376079 0.96000622376079 0.96000622376079 0.96000622376079 0.96000622376078 0.96000622376058 0.96000622375841 0.9600062237505 0.96000622374392 0.9600062237505 0.96000622375841 0.96000622376058 0.96000622376078 0.96000622376079 0.96000622376079 0.96000622376079 0.96000622376079 0.96000622376079 0.96000622376079 0.96000622376079 0.96000622376079 0.96013879588321 0.96013879588321 0.96013879588321 0.96013879588321 0.96013879588321 0.96013879588321 0.96013879588321 0.96013879588321 0.96013879588308 0.96013879587095 0.96013879574464 0.96013879528095 0.96013879489543 0.96013879528095 0.96013879574464 0.96013879587095 0.96013879588308 0.96013879588321 0.96013879588321 0.96013879588321 0.96013879588321 0.96013879588321 0.96013879588321 0.96013879588321 0.96013879588321 0.96006476986403 0.96006476986403 0.96006476986403 0.96006476986403 0.96006476986403 0.96006476986403 0.96006476986403 0.96006476986403 0.96006476986392 0.96006476985413 0.96006476975191 0.96006476937608 0.96006476906349 0.96006476937608 0.96006476975191 0.96006476985413 0.96006476986392 0.96006476986403 0.96006476986403 0.96006476986403 0.96006476986403 0.96006476986403 0.96006476986403 0.96006476986403 0.96006476986403 0.96027520928189 0.96027520928189 0.96027520928189 0.96027520928189 0.96027520928189 0.96027520928189 0.96027520928189 0.96027520928189 0.96027520928189 0.96027520928145 0.96027520927704 0.96027520926098 0.96027520924764 0.96027520926098 0.96027520927704 0.96027520928145 0.96027520928189 0.96027520928189 0.96027520928189 0.96027520928189 0.96027520928189 0.96027520928189 0.96027520928189 0.96027520928189 0.96027520928189 0.96005494775729 0.96005494775729 0.96005494775729 0.96005494775729 0.96005494775729 0.96005494775729 0.96005494775729 0.96005494775729 0.96005494775729 0.96005494775717 0.96005494775593 0.96005494775135 0.96005494774755 0.96005494775135 0.96005494775593 0.96005494775717 0.96005494775729 0.96005494775729 0.96005494775729 0.96005494775729 0.96005494775729 0.96005494775729 0.96005494775729 0.96005494775729 0.96005494775729 0.96000571977412 0.96000571977412 0.96000571977412 0.96000571977412 0.96000571977412 0.96000571977412 0.96000571977412 0.96000571977412 0.96000571977412 0.96000571977411 0.96000571977396 0.96000571977341 0.96000571977296 0.96000571977341 0.96000571977396 0.96000571977411 0.96000571977412 0.96000571977412 0.96000571977412 0.96000571977412 0.96000571977412 0.96000571977412 0.96000571977412 0.96000571977412 0.96000571977412 0.96000041848693 0.96000041848693 0.96000041848693 0.96000041848693 0.96000041848693 0.96000041848693 0.96000041848693 0.96000041848693 0.96000041848693 0.96000041848693 0.96000041848692 0.96000041848692 0.96000041848691 0.96000041848692 0.96000041848692 0.96000041848693 0.96000041848693 0.96000041848693 0.96000041848693 0.96000041848693 0.96000041848693 0.96000041848693 0.96000041848693 0.96000041848693 0.96000041848693 0.96000002077145 0.96000002077145 0.96000002077145 0.96000002077145 0.96000002077145 0.96000002077145 0.96000002077145 0.96000002077145 0.96000002077145 0.96000002077145 0.96000002077145 0.96000002077145 0.96000002077145 0.96000002077145 0.96000002077145 0.96000002077145 0.96000002077145 0.96000002077145 0.96000002077145 0.96000002077145 0.96000002077145 0.96000002077145 0.96000002077145 0.96000002077145 0.96000002077145 0.96000000072415 0.96000000072415 0.96000000072415 0.96000000072415 0.96000000072415 0.96000000072415 0.96000000072415 0.96000000072415 0.96000000072415 0.96000000072415 0.96000000072415 0.96000000072415 0.96000000072415 0.96000000072415 0.96000000072415 0.96000000072415 0.96000000072415 0.96000000072415 0.96000000072415 0.96000000072415 0.96000000072415 0.96000000072415 0.96000000072415 0.96000000072415 0.96000000072415 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000000027 0.96000000000027 0.96000000000027 0.96000000000027 0.96000000000027 0.96000000000027 0.96000000000027 0.96000000000027 0.96000000000027 0.96000000000027 0.96000000000027 0.96000000000027 0.96000000000027 0.96000000000027 0.96000000000027 0.96000000000027 0.96000000000027 0.96000000000027 0.96000000000027 0.96000000000027 0.96000000000027 0.96000000000027 0.96000000000027 0.96000000000027 0.96000000000027 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000005445 0.96000000005445 0.96000000005445 0.96000000005445 0.96000000005445 0.96000000005445 0.96000000005445 0.96000000005445 0.96000000005445 0.96000000005445 0.96000000005445 0.96000000005445 0.96000000005445 0.96000000005445 0.96000000005445 0.96000000005445 0.96000000005445 0.96000000005445 0.96000000005445 0.96000000005445 0.96000000005445 0.96000000005445 0.96000000005445 0.96000000005445 0.96000000005445 0.96000000142375 0.96000000142375 0.96000000142375 0.96000000142375 0.96000000142375 0.96000000142375 0.96000000142375 0.96000000142375 0.96000000142375 0.96000000142375 0.96000000142374 0.96000000142374 0.96000000142373 0.96000000142374 0.96000000142374 0.96000000142375 0.96000000142375 0.96000000142375 0.96000000142375 0.96000000142375 0.96000000142375 0.96000000142375 0.96000000142375 0.96000000142375 0.96000000142375 0.96000009370674 0.96000009370674 0.96000009370674 0.96000009370674 0.96000009370674 0.96000009370674 0.96000009370674 0.96000009370674 0.96000009370674 0.96000009370673 0.9600000937067 0.9600000937066 0.96000009370651 0.9600000937066 0.9600000937067 0.96000009370673 0.96000009370674 0.96000009370674 0.96000009370674 0.96000009370674 0.96000009370674 0.96000009370674 0.96000009370674 0.96000009370674 0.96000009370674 0.96000254523862 0.96000254523862 0.96000254523862 0.96000254523862 0.96000254523862 0.96000254523862 0.96000254523862 0.96000254523862 0.96000254523862 0.96000254523842 0.9600025452363 0.96000254522849 0.96000254522198 0.96000254522849 0.9600025452363 0.96000254523842 0.96000254523862 0.96000254523862 0.96000254523862 0.96000254523862 0.96000254523862 0.96000254523862 0.96000254523862 0.96000254523862 0.96000254523862 0.96000117610763 0.96000117610763 0.96000117610763 0.96000117610763 0.96000117610763 0.96000117610763 0.96000117610763 0.96000117610763 0.96000117610763 0.96000117610752 0.96000117610631 0.96000117610187 0.96000117609818 0.96000117610187 0.96000117610631 0.96000117610752 0.96000117610763 0.96000117610763 0.96000117610763 0.96000117610763 0.96000117610763 0.96000117610763 0.96000117610763 0.96000117610763 0.96000117610763 0.96000524478499 0.96000524478499 0.96000524478499 0.96000524478499 0.96000524478499 0.96000524478499 0.96000524478499 0.96000524478499 0.96000524478499 0.96000524478493 0.96000524478429 0.96000524478192 0.96000524477994 0.96000524478192 0.96000524478429 0.96000524478493 0.96000524478499 0.96000524478499 0.96000524478499 0.96000524478499 0.96000524478499 0.96000524478499 0.96000524478499 0.96000524478499 0.96000524478499 0.96000087573747 0.96000087573747 0.96000087573747 0.96000087573747 0.96000087573747 0.96000087573747 0.96000087573747 0.96000087573747 0.96000087573747 0.9600008757375 0.96000087573786 0.9600008757392 0.96000087574031 0.9600008757392 0.96000087573786 0.9600008757375 0.96000087573747 0.96000087573747 0.96000087573747 0.96000087573747 0.96000087573747 0.96000087573747 0.96000087573747 0.96000087573747 0.96000087573747 0.96000085120187 0.96000085120187 0.96000085120187 0.96000085120187 0.96000085120187 0.96000085120187 0.96000085120187 0.96000085120187 0.96000085120187 0.96000085120187 0.96000085120186 0.96000085120185 0.96000085120184 0.96000085120185 0.96000085120186 0.96000085120187 0.96000085120187 0.96000085120187 0.96000085120187 0.96000085120187 0.96000085120187 0.96000085120187 0.96000085120187 0.96000085120187 0.96000085120187 0.96000007393657 0.96000007393657 0.96000007393657 0.96000007393657 0.96000007393657 0.96000007393657 0.96000007393657 0.96000007393657 0.96000007393657 0.96000007393657 0.96000007393657 0.96000007393657 0.96000007393657 0.96000007393657 0.96000007393657 0.96000007393657 0.96000007393657 0.96000007393657 0.96000007393657 0.96000007393657 0.96000007393657 0.96000007393657 0.96000007393657 0.96000007393657 0.96000007393657 0.96000000267574 0.96000000267574 0.96000000267574 0.96000000267574 0.96000000267574 0.96000000267574 0.96000000267574 0.96000000267574 0.96000000267574 0.96000000267574 0.96000000267574 0.96000000267574 0.96000000267574 0.96000000267574 0.96000000267574 0.96000000267574 0.96000000267574 0.96000000267574 0.96000000267574 0.96000000267574 0.96000000267574 0.96000000267574 0.96000000267574 0.96000000267574 0.96000000267574 0.96000000007354 0.96000000007354 0.96000000007354 0.96000000007354 0.96000000007354 0.96000000007354 0.96000000007354 0.96000000007354 0.96000000007354 0.96000000007354 0.96000000007354 0.96000000007354 0.96000000007354 0.96000000007354 0.96000000007354 0.96000000007354 0.96000000007354 0.96000000007354 0.96000000007354 0.96000000007354 0.96000000007354 0.96000000007354 0.96000000007354 0.96000000007354 0.96000000007354 0.96000000000181 0.96000000000181 0.96000000000181 0.96000000000181 0.96000000000181 0.96000000000181 0.96000000000181 0.96000000000181 0.96000000000181 0.96000000000181 0.96000000000181 0.96000000000181 0.96000000000181 0.96000000000181 0.96000000000181 0.96000000000181 0.96000000000181 0.96000000000181 0.96000000000181 0.96000000000181 0.96000000000181 0.96000000000181 0.96000000000181 0.96000000000181 0.96000000000181 0.95999999999985 0.95999999999985 0.95999999999985 0.95999999999985 0.95999999999985 0.95999999999985 0.95999999999985 0.95999999999985 0.95999999999985 0.95999999999985 0.95999999999985 0.95999999999985 0.95999999999985 0.95999999999985 0.95999999999985 0.95999999999985 0.95999999999985 0.95999999999985 0.95999999999985 0.95999999999985 0.95999999999985 0.95999999999985 0.95999999999985 0.95999999999985 0.95999999999985 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.96000000000058 0.96000000000058 0.96000000000058 0.96000000000058 0.96000000000058 0.96000000000058 0.96000000000058 0.96000000000058 0.96000000000058 0.96000000000058 0.96000000000058 0.96000000000058 0.96000000000058 0.96000000000058 0.96000000000058 0.96000000000058 0.96000000000058 0.96000000000058 0.96000000000058 0.96000000000058 0.96000000000058 0.96000000000058 0.96000000000058 0.96000000000058 0.96000000000058 0.96000000001744 0.96000000001744 0.96000000001744 0.96000000001744 0.96000000001744 0.96000000001744 0.96000000001744 0.96000000001744 0.96000000001744 0.96000000001744 0.96000000001744 0.96000000001744 0.96000000001744 0.96000000001744 0.96000000001744 0.96000000001744 0.96000000001744 0.96000000001744 0.96000000001744 0.96000000001744 0.96000000001744 0.96000000001744 0.96000000001744 0.96000000001744 0.96000000001744 0.96000000114058 0.96000000114058 0.96000000114058 0.96000000114058 0.96000000114058 0.96000000114058 0.96000000114058 0.96000000114058 0.96000000114058 0.96000000114058 0.96000000114058 0.96000000114057 0.96000000114057 0.96000000114057 0.96000000114058 0.96000000114058 0.96000000114058 0.96000000114058 0.96000000114058 0.96000000114058 0.96000000114058 0.96000000114058 0.96000000114058 0.96000000114058 0.96000000114058 0.9600000318752 0.9600000318752 0.9600000318752 0.9600000318752 0.9600000318752 0.9600000318752 0.9600000318752 0.9600000318752 0.9600000318752 0.96000003187519 0.96000003187517 0.9600000318751 0.96000003187504 0.9600000318751 0.96000003187517 0.96000003187519 0.9600000318752 0.9600000318752 0.9600000318752 0.9600000318752 0.9600000318752 0.9600000318752 0.9600000318752 0.9600000318752 0.9600000318752 0.96000001538587 0.96000001538587 0.96000001538587 0.96000001538587 0.96000001538587 0.96000001538587 0.96000001538587 0.96000001538587 0.96000001538587 0.96000001538587 0.96000001538586 0.96000001538582 0.96000001538579 0.96000001538582 0.96000001538586 0.96000001538587 0.96000001538587 0.96000001538587 0.96000001538587 0.96000001538587 0.96000001538587 0.96000001538587 0.96000001538587 0.96000001538587 0.96000001538587 0.96000008339363 0.96000008339363 0.96000008339363 0.96000008339363 0.96000008339363 0.96000008339363 0.96000008339363 0.96000008339363 0.96000008339363 0.96000008339363 0.96000008339363 0.96000008339362 0.96000008339361 0.96000008339362 0.96000008339363 0.96000008339363 0.96000008339363 0.96000008339363 0.96000008339363 0.96000008339363 0.96000008339363 0.96000008339363 0.96000008339363 0.96000008339363 0.96000008339363 0.96000001383394 0.96000001383394 0.96000001383394 0.96000001383394 0.96000001383394 0.96000001383394 0.96000001383394 0.96000001383394 0.96000001383394 0.96000001383394 0.96000001383395 0.96000001383396 0.96000001383397 0.96000001383396 0.96000001383395 0.96000001383394 0.96000001383394 0.96000001383394 0.96000001383394 0.96000001383394 0.96000001383394 0.96000001383394 0.96000001383394 0.96000001383394 0.96000001383394 0.96000001361022 0.96000001361022 0.96000001361022 0.96000001361022 0.96000001361022 0.96000001361022 0.96000001361022 0.96000001361022 0.96000001361022 0.96000001361022 0.96000001361022 0.96000001361022 0.96000001361022 0.96000001361022 0.96000001361022 0.96000001361022 0.96000001361022 0.96000001361022 0.96000001361022 0.96000001361022 0.96000001361022 0.96000001361022 0.96000001361022 0.96000001361022 0.96000001361022 0.96000000508758 0.96000000508758 0.96000000508758 0.96000000508758 0.96000000508758 0.96000000508758 0.96000000508758 0.96000000508758 0.96000000508758 0.96000000508758 0.96000000508758 0.96000000508758 0.96000000508758 0.96000000508758 0.96000000508758 0.96000000508758 0.96000000508758 0.96000000508758 0.96000000508758 0.96000000508758 0.96000000508758 0.96000000508758 0.96000000508758 0.96000000508758 0.96000000508758 0.96000000027613 0.96000000027613 0.96000000027613 0.96000000027613 0.96000000027613 0.96000000027613 0.96000000027613 0.96000000027613 0.96000000027613 0.96000000027613 0.96000000027613 0.96000000027613 0.96000000027613 0.96000000027613 0.96000000027613 0.96000000027613 0.96000000027613 0.96000000027613 0.96000000027613 0.96000000027613 0.96000000027613 0.96000000027613 0.96000000027613 0.96000000027613 0.96000000027613 0.96000000000723 0.96000000000723 0.96000000000723 0.96000000000723 0.96000000000723 0.96000000000723 0.96000000000723 0.96000000000723 0.96000000000723 0.96000000000723 0.96000000000723 0.96000000000723 0.96000000000723 0.96000000000723 0.96000000000723 0.96000000000723 0.96000000000723 0.96000000000723 0.96000000000723 0.96000000000723 0.96000000000723 0.96000000000723 0.96000000000723 0.96000000000723 0.96000000000723 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.96000000000014 0.96000000000014 0.96000000000014 0.96000000000014 0.96000000000014 0.96000000000014 0.96000000000014 0.96000000000014 0.96000000000014 0.96000000000014 0.96000000000014 0.96000000000014 0.96000000000014 0.96000000000014 0.96000000000014 0.96000000000014 0.96000000000014 0.96000000000014 0.96000000000014 0.96000000000014 0.96000000000014 0.96000000000014 0.96000000000014 0.96000000000014 0.96000000000014 0.96000000001185 0.96000000001185 0.96000000001185 0.96000000001185 0.96000000001185 0.96000000001185 0.96000000001185 0.96000000001185 0.96000000001185 0.96000000001185 0.96000000001185 0.96000000001185 0.96000000001185 0.96000000001185 0.96000000001185 0.96000000001185 0.96000000001185 0.96000000001185 0.96000000001185 0.96000000001185 0.96000000001185 0.96000000001185 0.96000000001185 0.96000000001185 0.96000000001185 0.96000000033252 0.96000000033252 0.96000000033252 0.96000000033252 0.96000000033252 0.96000000033252 0.96000000033252 0.96000000033252 0.96000000033252 0.96000000033252 0.96000000033252 0.96000000033252 0.96000000033252 0.96000000033252 0.96000000033252 0.96000000033252 0.96000000033252 0.96000000033252 0.96000000033252 0.96000000033252 0.96000000033252 0.96000000033252 0.96000000033252 0.96000000033252 0.96000000033252 0.9600000001676 0.9600000001676 0.9600000001676 0.9600000001676 0.9600000001676 0.9600000001676 0.9600000001676 0.9600000001676 0.9600000001676 0.9600000001676 0.9600000001676 0.9600000001676 0.9600000001676 0.9600000001676 0.9600000001676 0.9600000001676 0.9600000001676 0.9600000001676 0.9600000001676 0.9600000001676 0.9600000001676 0.9600000001676 0.9600000001676 0.9600000001676 0.9600000001676 0.96000000105006 0.96000000105006 0.96000000105006 0.96000000105006 0.96000000105006 0.96000000105006 0.96000000105006 0.96000000105006 0.96000000105006 0.96000000105006 0.96000000105006 0.96000000105006 0.96000000105006 0.96000000105006 0.96000000105006 0.96000000105006 0.96000000105006 0.96000000105006 0.96000000105006 0.96000000105006 0.96000000105006 0.96000000105006 0.96000000105006 0.96000000105006 0.96000000105006 0.96000000017454 0.96000000017454 0.96000000017454 0.96000000017454 0.96000000017454 0.96000000017454 0.96000000017454 0.96000000017454 0.96000000017454 0.96000000017454 0.96000000017454 0.96000000017454 0.96000000017454 0.96000000017454 0.96000000017454 0.96000000017454 0.96000000017454 0.96000000017454 0.96000000017454 0.96000000017454 0.96000000017454 0.96000000017454 0.96000000017454 0.96000000017454 0.96000000017454 0.96000000021066 0.96000000021066 0.96000000021066 0.96000000021066 0.96000000021066 0.96000000021066 0.96000000021066 0.96000000021066 0.96000000021066 0.96000000021066 0.96000000021066 0.96000000021066 0.96000000021066 0.96000000021066 0.96000000021066 0.96000000021066 0.96000000021066 0.96000000021066 0.96000000021066 0.96000000021066 0.96000000021066 0.96000000021066 0.96000000021066 0.96000000021066 0.96000000021066 0.96000000008263 0.96000000008263 0.96000000008263 0.96000000008263 0.96000000008263 0.96000000008263 0.96000000008263 0.96000000008263 0.96000000008263 0.96000000008263 0.96000000008263 0.96000000008263 0.96000000008263 0.96000000008263 0.96000000008263 0.96000000008263 0.96000000008263 0.96000000008263 0.96000000008263 0.96000000008263 0.96000000008263 0.96000000008263 0.96000000008263 0.96000000008263 0.96000000008263 0.96000000000466 0.96000000000466 0.96000000000466 0.96000000000466 0.96000000000466 0.96000000000466 0.96000000000466 0.96000000000466 0.96000000000466 0.96000000000466 0.96000000000466 0.96000000000466 0.96000000000466 0.96000000000466 0.96000000000466 0.96000000000466 0.96000000000466 0.96000000000466 0.96000000000466 0.96000000000466 0.96000000000466 0.96000000000466 0.96000000000466 0.96000000000466 0.96000000000466 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000325 0.96000000000325 0.96000000000325 0.96000000000325 0.96000000000325 0.96000000000325 0.96000000000325 0.96000000000325 0.96000000000325 0.96000000000325 0.96000000000325 0.96000000000325 0.96000000000325 0.96000000000325 0.96000000000325 0.96000000000325 0.96000000000325 0.96000000000325 0.96000000000325 0.96000000000325 0.96000000000325 0.96000000000325 0.96000000000325 0.96000000000325 0.96000000000325 0.96000000000187 0.96000000000187 0.96000000000187 0.96000000000187 0.96000000000187 0.96000000000187 0.96000000000187 0.96000000000187 0.96000000000187 0.96000000000187 0.96000000000187 0.96000000000187 0.96000000000187 0.96000000000187 0.96000000000187 0.96000000000187 0.96000000000187 0.96000000000187 0.96000000000187 0.96000000000187 0.96000000000187 0.96000000000187 0.96000000000187 0.96000000000187 0.96000000000187 0.96000000001122 0.96000000001122 0.96000000001122 0.96000000001122 0.96000000001122 0.96000000001122 0.96000000001122 0.96000000001122 0.96000000001122 0.96000000001122 0.96000000001122 0.96000000001122 0.96000000001122 0.96000000001122 0.96000000001122 0.96000000001122 0.96000000001122 0.96000000001122 0.96000000001122 0.96000000001122 0.96000000001122 0.96000000001122 0.96000000001122 0.96000000001122 0.96000000001122 0.96000000000219 0.96000000000219 0.96000000000219 0.96000000000219 0.96000000000219 0.96000000000219 0.96000000000219 0.96000000000219 0.96000000000219 0.96000000000219 0.96000000000219 0.96000000000219 0.96000000000219 0.96000000000219 0.96000000000219 0.96000000000219 0.96000000000219 0.96000000000219 0.96000000000219 0.96000000000219 0.96000000000219 0.96000000000219 0.96000000000219 0.96000000000219 0.96000000000219 0.96000000000302 0.96000000000302 0.96000000000302 0.96000000000302 0.96000000000302 0.96000000000302 0.96000000000302 0.96000000000302 0.96000000000302 0.96000000000302 0.96000000000302 0.96000000000302 0.96000000000302 0.96000000000302 0.96000000000302 0.96000000000302 0.96000000000302 0.96000000000302 0.96000000000302 0.96000000000302 0.96000000000302 0.96000000000302 0.96000000000302 0.96000000000302 0.96000000000302 0.9600000000017 0.9600000000017 0.9600000000017 0.9600000000017 0.9600000000017 0.9600000000017 0.9600000000017 0.9600000000017 0.9600000000017 0.9600000000017 0.9600000000017 0.9600000000017 0.9600000000017 0.9600000000017 0.9600000000017 0.9600000000017 0.9600000000017 0.9600000000017 0.9600000000017 0.9600000000017 0.9600000000017 0.9600000000017 0.9600000000017 0.9600000000017 0.9600000000017 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999984 0.95999999999984 0.95999999999984 0.95999999999984 0.95999999999984 0.95999999999984 0.95999999999984 0.95999999999984 0.95999999999984 0.95999999999984 0.95999999999984 0.95999999999984 0.95999999999984 0.95999999999984 0.95999999999984 0.95999999999984 0.95999999999984 0.95999999999984 0.95999999999984 0.95999999999984 0.95999999999984 0.95999999999984 0.95999999999984 0.95999999999984 0.95999999999984 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 D/cons.2.00.000000.dat 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 @@ -17,4 +17,4 @@ D/cons.8.00.000000.dat 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0 D/cons.8.00.000050.dat 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 D/lag_bubble_evol_0.dat 0.0 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832988093882 0.008 0.0 1.0001782913460961 0.0 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832988093882 0.008 0.0 1.0001782913460961 1e-06 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832988093882 0.0079999999991335 -2.5998347812e-06 1.000178291800741 2e-06 1.0 0.5 0.5 0.5 3.64821e-11 0.014383298809388 0.0079999999922017 -1.29983238775e-05 1.0001782954379947 3e-06 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832988093872 0.0079999999688074 -3.63926994597e-05 1.000178307713318 4e-06 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832988093845 0.0079999999133575 -7.79781479331e-05 1.0001783368087096 5e-06 1.0 0.5 0.5 0.5 3.64821e-11 0.014383298809378 0.0079999998050647 -0.0001429472756538 1.0001783936314923 6e-06 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832988093644 0.0079999996179508 -0.0002364894691138 1.0001784918127927 7e-06 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832988093391 0.00799999932085 -0.0003637901198454 1.0001786477056553 8e-06 1.0 0.5 0.5 0.5 3.64821e-11 0.014383298809296 0.0079999988774137 -0.0005300296841069 1.0001788803827116 9e-06 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832988092268 0.0079999982461156 -0.000740382547164 1.0001792116333146 1e-05 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832988091214 0.0079999973802587 -0.0010000156616928 1.0001796659600262 1.1e-05 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832988089671 0.0079999962279833 -0.0013140869294889 1.0001802705743383 1.2e-05 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832988087485 0.0079999947322772 -0.0016877432952982 1.0001810553914838 1.3e-05 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832988084475 0.0079999928309878 -0.0021261185211773 1.0001820530241825 1.4e-05 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832988080425 0.007999990456836 -0.002634330609384 1.0001832987751504 1.5e-05 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832988075089 0.0079999875374341 -0.0032174788413769 1.0001848306281818 1.6e-05 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832988068183 0.0079999839953059 -0.0038806404001024 1.0001866892375992 1.7e-05 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832988059382 0.0079999797479105 -0.0046288665423713 1.0001889179158479 1.8e-05 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832988048322 0.0079999747076704 -0.0054671782877993 1.0001915626189932 1.9e-05 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832988034595 0.0079999687820044 -0.0064005615905186 1.0001946719298669 2e-05 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832988017745 0.007999961873365 -0.007433961959695 1.0001982970385817 2.1e-05 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832987997269 0.0079999538792819 -0.0085722784948069 1.000202491720126 2.2e-05 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832987972612 0.0079999446924115 -0.0098203573017131 1.0002073123087254 2.3e-05 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832987943166 0.0079999342005938 -0.0111829842557531 1.000212817668644 2.4e-05 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832987908266 0.007999922286916 -0.0126648770785396 1.0002190691610786 2.5e-05 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832987867191 0.0079999088297855 -0.0142706766957323 1.000226130606784 2.6e-05 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832987819157 0.007999893703011 -0.0160049378439864 1.0002340682440483 2.7e-05 1.0 0.5 0.5 0.5 3.64821e-11 0.014383298776332 0.0079998767758937 -0.0178721188962179 1.000242950681623 2.8e-05 1.0 0.5 0.5 0.5 3.64821e-11 0.014383298769877 0.007999857913329 -0.0198765708761419 1.0002528488461935 2.9e-05 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832987624529 0.0079998369759201 -0.0220225256346343 1.0002638359239637 3e-05 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832987539553 0.007999813820103 -0.0243140831627582 1.000275987295915 3.1e-05 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832987442724 0.0079997882982854 -0.0267551980189568 1.0002893804662816 3.2e-05 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832987332854 0.007999760258999 -0.0293496648510724 1.0003040949837791 3.3e-05 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832987208677 0.0079997295470672 -0.0321011029972354 1.0003202123551105 3.4e-05 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832987068853 0.0079996960037885 -0.0350129401543523 1.0003378159502636 3.5e-05 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832986911963 0.0079996594671366 -0.0380883951075977 1.0003569908991143 3.6e-05 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832986736509 0.0079996197719785 -0.041330459519923 1.0003778239788415 3.7e-05 1.0 0.5 0.5 0.5 3.64821e-11 0.014383298654091 0.0079995767503109 -0.0447418787855614 1.0004004034916618 3.8e-05 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832986323505 0.0079995302315166 -0.0483251319566073 1.000424819132395 3.9e-05 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832986082548 0.0079994800426413 -0.0520824107647706 1.0004511618453742 4e-05 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832985816207 0.0079994260086914 -0.0560155977723029 1.0004795236702335 4.1e-05 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832985522566 0.0079993679529551 -0.0601262436835033 1.0005099975761178 4.2e-05 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832985199623 0.0079993056973452 -0.0644155438558731 1.0005426772838766 4.3e-05 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832984845287 0.0079992390627669 -0.0688843140513614 1.0005776570758202 4.4e-05 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832984457381 0.00799916786951 -0.0735329655284826 1.0006150315926565 4.5e-05 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832984033639 0.0079990919376656 -0.0783614795576986 1.0006548956172674 4.6e-05 1.0 0.5 0.5 0.5 3.64821e-11 0.014383298357171 0.0079990110875694 -0.0833693814493191 1.0006973438450313 4.7e-05 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832983069152 0.0079989251402707 -0.0885557141955299 1.000742470640441 4.8e-05 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832982523439 0.0079988339180279 -0.0939190118482383 1.000790369779823 4.9e-05 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832981931958 0.0079987372448311 -0.0994572727784473 1.0008411341800327 D/stats_lag_bubbles_0.dat 0.0 1.0 0.5 0.5 0.5 1.0 0.9998421556038835 -D/voidfraction.dat 2.1429198e-06 2.1429198e-06 2.1429198e-06 2.1429198e-06 2.1429197e-06 2.1429197e-06 2.1429196e-06 2.1429195e-06 2.1429193e-06 2.142919e-06 2.1429186e-06 2.142918e-06 2.1429172e-06 2.1429161e-06 2.1429148e-06 2.142913e-06 2.1429109e-06 2.1429083e-06 2.1429052e-06 2.1429015e-06 2.1428971e-06 2.1428919e-06 2.1428859e-06 2.142879e-06 2.1428711e-06 2.1428621e-06 2.1428519e-06 2.1428404e-06 2.1428275e-06 2.1428132e-06 2.1427972e-06 2.1427795e-06 2.1427599e-06 2.1427384e-06 2.1427148e-06 2.142689e-06 2.1426608e-06 2.1426302e-06 2.142597e-06 2.142561e-06 2.1425221e-06 2.1424803e-06 2.1424352e-06 2.1423869e-06 2.1423351e-06 2.1422797e-06 2.1422206e-06 2.1421577e-06 2.1420907e-06 2.1420195e-06 2.141944e-06 \ No newline at end of file +D/voidfraction.dat 2.1429198e-06 2.1429198e-06 2.1429198e-06 2.1429198e-06 2.1429197e-06 2.1429197e-06 2.1429196e-06 2.1429195e-06 2.1429192e-06 2.1429189e-06 2.1429183e-06 2.1429177e-06 2.1429167e-06 2.1429155e-06 2.142914e-06 2.1429121e-06 2.1429097e-06 2.1429069e-06 2.1429035e-06 2.1428994e-06 2.1428947e-06 2.1428891e-06 2.1428827e-06 2.1428753e-06 2.1428669e-06 2.1428573e-06 2.1428465e-06 2.1428343e-06 2.1428207e-06 2.1428056e-06 2.1427888e-06 2.1427701e-06 2.1427496e-06 2.1427271e-06 2.1427024e-06 2.1426755e-06 2.1426461e-06 2.1426142e-06 2.1425797e-06 2.1425423e-06 2.142502e-06 2.1424585e-06 2.1424119e-06 2.1423619e-06 2.1423083e-06 2.1422511e-06 2.1421901e-06 2.1421252e-06 2.1420561e-06 2.1419828e-06 2.1419052e-06 \ No newline at end of file diff --git a/tests/2EE0C3AA/golden-metadata.txt b/tests/2EE0C3AA/golden-metadata.txt index 9665f07409..e80b4d4d2e 100644 --- a/tests/2EE0C3AA/golden-metadata.txt +++ b/tests/2EE0C3AA/golden-metadata.txt @@ -1,24 +1,24 @@ -This file was created on 2026-02-28 19:06:40.945427. +This file was created on 2026-03-04 16:01:02.157542. mfc.sh: - Invocation: test --only 2EE0C3AA --generate --no-gpu -j 8 --no-build + Invocation: test --generate -o 2EE0C3AA Lock: mpi=Yes & gpu=No & debug=No & gcov=No & unified=No & single=No & mixed=No & fastmath=No - Git: 53ebfb7c2c1e94dc6b01b6c191eaa4bb11d1adc3 on gpu-optimizations (dirty) + Git: 6ebc84435f0cd9c9ca2161ede72683409650cde2 on MovingBubblesFresh-clean (dirty) -syscheck: +post_process: CMake Configuration: - CMake v3.28.3 on schwarzschild + CMake v3.30.3 on wingtip-gpu3.cc.gatech.edu - C : NVHPC v23.11.0 (/opt/nvidia/hpc_sdk/Linux_x86_64/23.11/compilers/bin/nvc) - Fortran : NVHPC v23.11.0 (/opt/nvidia/hpc_sdk/Linux_x86_64/23.11/compilers/bin/nvfortran) + C : NVHPC v25.11.0 (/fastscratch/bwilfong3/software/hpc_sdk_25_9/Linux_x86_64/25.11/compilers/bin/nvc) + Fortran : NVHPC v25.11.0 (/fastscratch/bwilfong3/software/hpc_sdk_25_9/Linux_x86_64/25.11/compilers/bin/nvfortran) PRE_PROCESS : OFF SIMULATION : OFF - POST_PROCESS : OFF - SYSCHECK : ON + POST_PROCESS : ON + SYSCHECK : OFF DOCUMENTATION : OFF ALL : OFF @@ -26,16 +26,16 @@ syscheck: OpenACC : OFF OpenMP : OFF - Fypp : /home/dan/Documents/repos/MFC/build/venv/bin/fypp + Fypp : /fastscratch/bwilfong3/software/MFC-Wilfong/build/venv/bin/fypp Doxygen : Build Type : Release Configuration Environment: - CC : /opt/nvidia/hpc_sdk/Linux_x86_64/23.11/compilers/bin/nvc - CXX : /opt/nvidia/hpc_sdk/Linux_x86_64/23.11/compilers/bin/nvc++ - FC : /opt/nvidia/hpc_sdk/Linux_x86_64/23.11/compilers/bin/nvfortran + CC : /fastscratch/bwilfong3/software/hpc_sdk_25_9/Linux_x86_64/25.11/compilers/bin/nvc + CXX : /fastscratch/bwilfong3/software/hpc_sdk_25_9/Linux_x86_64/25.11/compilers/bin/nvc++ + FC : /fastscratch/bwilfong3/software/hpc_sdk_25_9/Linux_x86_64/25.11/compilers/bin/nvfortran OMPI_CC : OMPI_CXX : OMPI_FC : @@ -44,10 +44,10 @@ simulation: CMake Configuration: - CMake v3.28.3 on schwarzschild + CMake v3.30.3 on wingtip-gpu3.cc.gatech.edu - C : NVHPC v23.11.0 (/opt/nvidia/hpc_sdk/Linux_x86_64/23.11/compilers/bin/nvc) - Fortran : NVHPC v23.11.0 (/opt/nvidia/hpc_sdk/Linux_x86_64/23.11/compilers/bin/nvfortran) + C : NVHPC v25.11.0 (/fastscratch/bwilfong3/software/hpc_sdk_25_9/Linux_x86_64/25.11/compilers/bin/nvc) + Fortran : NVHPC v25.11.0 (/fastscratch/bwilfong3/software/hpc_sdk_25_9/Linux_x86_64/25.11/compilers/bin/nvfortran) PRE_PROCESS : OFF SIMULATION : ON @@ -60,16 +60,16 @@ simulation: OpenACC : OFF OpenMP : OFF - Fypp : /home/dan/Documents/repos/MFC/build/venv/bin/fypp + Fypp : /fastscratch/bwilfong3/software/MFC-Wilfong/build/venv/bin/fypp Doxygen : Build Type : Release Configuration Environment: - CC : /opt/nvidia/hpc_sdk/Linux_x86_64/23.11/compilers/bin/nvc - CXX : /opt/nvidia/hpc_sdk/Linux_x86_64/23.11/compilers/bin/nvc++ - FC : /opt/nvidia/hpc_sdk/Linux_x86_64/23.11/compilers/bin/nvfortran + CC : /fastscratch/bwilfong3/software/hpc_sdk_25_9/Linux_x86_64/25.11/compilers/bin/nvc + CXX : /fastscratch/bwilfong3/software/hpc_sdk_25_9/Linux_x86_64/25.11/compilers/bin/nvc++ + FC : /fastscratch/bwilfong3/software/hpc_sdk_25_9/Linux_x86_64/25.11/compilers/bin/nvfortran OMPI_CC : OMPI_CXX : OMPI_FC : @@ -78,10 +78,10 @@ pre_process: CMake Configuration: - CMake v3.28.3 on schwarzschild + CMake v3.30.3 on wingtip-gpu3.cc.gatech.edu - C : NVHPC v23.11.0 (/opt/nvidia/hpc_sdk/Linux_x86_64/23.11/compilers/bin/nvc) - Fortran : NVHPC v23.11.0 (/opt/nvidia/hpc_sdk/Linux_x86_64/23.11/compilers/bin/nvfortran) + C : NVHPC v25.11.0 (/fastscratch/bwilfong3/software/hpc_sdk_25_9/Linux_x86_64/25.11/compilers/bin/nvc) + Fortran : NVHPC v25.11.0 (/fastscratch/bwilfong3/software/hpc_sdk_25_9/Linux_x86_64/25.11/compilers/bin/nvfortran) PRE_PROCESS : ON SIMULATION : OFF @@ -94,16 +94,50 @@ pre_process: OpenACC : OFF OpenMP : OFF - Fypp : /home/dan/Documents/repos/MFC/build/venv/bin/fypp + Fypp : /fastscratch/bwilfong3/software/MFC-Wilfong/build/venv/bin/fypp + Doxygen : + + Build Type : Release + + Configuration Environment: + + CC : + CXX : + FC : + OMPI_CC : + OMPI_CXX : + OMPI_FC : + +syscheck: + + CMake Configuration: + + CMake v3.30.3 on wingtip-gpu3.cc.gatech.edu + + C : NVHPC v25.11.0 (/fastscratch/bwilfong3/software/hpc_sdk_25_9/Linux_x86_64/25.11/compilers/bin/nvc) + Fortran : NVHPC v25.11.0 (/fastscratch/bwilfong3/software/hpc_sdk_25_9/Linux_x86_64/25.11/compilers/bin/nvfortran) + + PRE_PROCESS : OFF + SIMULATION : OFF + POST_PROCESS : OFF + SYSCHECK : ON + DOCUMENTATION : OFF + ALL : OFF + + MPI : ON + OpenACC : OFF + OpenMP : OFF + + Fypp : /fastscratch/bwilfong3/software/MFC-Wilfong/build/venv/bin/fypp Doxygen : Build Type : Release Configuration Environment: - CC : /opt/nvidia/hpc_sdk/Linux_x86_64/23.11/compilers/bin/nvc - CXX : /opt/nvidia/hpc_sdk/Linux_x86_64/23.11/compilers/bin/nvc++ - FC : /opt/nvidia/hpc_sdk/Linux_x86_64/23.11/compilers/bin/nvfortran + CC : + CXX : + FC : OMPI_CC : OMPI_CXX : OMPI_FC : @@ -112,49 +146,46 @@ CPU: CPU Info: From lscpu - Architecture: x86_64 - CPU op-mode(s): 32-bit, 64-bit - Address sizes: 46 bits physical, 48 bits virtual - Byte Order: Little Endian - CPU(s): 20 - On-line CPU(s) list: 0-19 - Vendor ID: GenuineIntel - Model name: 12th Gen Intel(R) Core(TM) i7-12700K - CPU family: 6 - Model: 151 - Thread(s) per core: 2 - Core(s) per socket: 12 - Socket(s): 1 - Stepping: 2 - CPU(s) scaling MHz: 24% - CPU max MHz: 5100.0000 - CPU min MHz: 800.0000 - BogoMIPS: 7219.20 - Flags: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc art arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc cpuid aperfmperf tsc_known_freq pni pclmulqdq dtes64 monitor ds_cpl vmx smx est tm2 ssse3 sdbg fma cx16 xtpr pdcm pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm abm 3dnowprefetch cpuid_fault cat_l2 cdp_l2 ssbd ibrs ibpb stibp ibrs_enhanced tpr_shadow flexpriority ept vpid ept_ad fsgsbase tsc_adjust bmi1 avx2 smep bmi2 erms invpcid rdt_a rdseed adx smap clflushopt clwb intel_pt sha_ni xsaveopt xsavec xgetbv1 xsaves split_lock_detect user_shstk avx_vnni dtherm ida arat pln pts hwp hwp_notify hwp_act_window hwp_epp hwp_pkg_req hfi vnmi umip pku ospke waitpkg gfni vaes vpclmulqdq rdpid movdiri movdir64b fsrm md_clear serialize pconfig arch_lbr ibt flush_l1d arch_capabilities - Virtualization: VT-x - L1d cache: 512 KiB (12 instances) - L1i cache: 512 KiB (12 instances) - L2 cache: 12 MiB (9 instances) - L3 cache: 25 MiB (1 instance) - NUMA node(s): 1 - NUMA node0 CPU(s): 0-19 - Vulnerability Gather data sampling: Not affected - Vulnerability Ghostwrite: Not affected - Vulnerability Indirect target selection: Not affected - Vulnerability Itlb multihit: Not affected - Vulnerability L1tf: Not affected - Vulnerability Mds: Not affected - Vulnerability Meltdown: Not affected - Vulnerability Mmio stale data: Not affected - Vulnerability Old microcode: Not affected - Vulnerability Reg file data sampling: Mitigation; Clear Register File - Vulnerability Retbleed: Not affected - Vulnerability Spec rstack overflow: Not affected - Vulnerability Spec store bypass: Mitigation; Speculative Store Bypass disabled via prctl - Vulnerability Spectre v1: Mitigation; usercopy/swapgs barriers and __user pointer sanitization - Vulnerability Spectre v2: Mitigation; Enhanced / Automatic IBRS; IBPB conditional; PBRSB-eIBRS SW sequence; BHI BHI_DIS_S - Vulnerability Srbds: Not affected - Vulnerability Tsa: Not affected - Vulnerability Tsx async abort: Not affected - Vulnerability Vmscape: Mitigation; IBPB before exit to userspace + Architecture: x86_64 + CPU op-mode(s): 32-bit, 64-bit + Address sizes: 52 bits physical, 57 bits virtual + Byte Order: Little Endian + CPU(s): 128 + On-line CPU(s) list: 0-127 + Vendor ID: GenuineIntel + Model name: Intel(R) Xeon(R) Gold 6338 CPU @ 2.00GHz + CPU family: 6 + Model: 106 + Thread(s) per core: 2 + Core(s) per socket: 32 + Socket(s): 2 + Stepping: 6 + CPU(s) scaling MHz: 40% + CPU max MHz: 3200.0000 + CPU min MHz: 800.0000 + BogoMIPS: 4000.00 + Flags: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc art arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc cpuid aperfmperf pni pclmulqdq dtes64 monitor ds_cpl vmx smx est tm2 ssse3 sdbg fma cx16 xtpr pdcm pcid dca sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm abm 3dnowprefetch cpuid_fault epb cat_l3 ssbd mba ibrs ibpb stibp ibrs_enhanced tpr_shadow flexpriority ept vpid ept_ad fsgsbase tsc_adjust bmi1 avx2 smep bmi2 erms invpcid cqm rdt_a avx512f avx512dq rdseed adx smap avx512ifma clflushopt clwb intel_pt avx512cd sha_ni avx512bw avx512vl xsaveopt xsavec xgetbv1 xsaves cqm_llc cqm_occup_llc cqm_mbm_total cqm_mbm_local split_lock_detect wbnoinvd dtherm ida arat pln pts vnmi avx512vbmi umip pku ospke avx512_vbmi2 gfni vaes vpclmulqdq avx512_vnni avx512_bitalg tme avx512_vpopcntdq la57 rdpid fsrm md_clear pconfig flush_l1d arch_capabilities + Virtualization: VT-x + L1d cache: 3 MiB (64 instances) + L1i cache: 2 MiB (64 instances) + L2 cache: 80 MiB (64 instances) + L3 cache: 96 MiB (2 instances) + NUMA node(s): 2 + NUMA node0 CPU(s): 0-31,64-95 + NUMA node1 CPU(s): 32-63,96-127 + Vulnerability Gather data sampling: Mitigation; Microcode + Vulnerability Itlb multihit: Not affected + Vulnerability L1tf: Not affected + Vulnerability Mds: Not affected + Vulnerability Meltdown: Not affected + Vulnerability Mmio stale data: Mitigation; Clear CPU buffers; SMT vulnerable + Vulnerability Reg file data sampling: Not affected + Vulnerability Retbleed: Not affected + Vulnerability Spec rstack overflow: Not affected + Vulnerability Spec store bypass: Mitigation; Speculative Store Bypass disabled via prctl + Vulnerability Spectre v1: Mitigation; usercopy/swapgs barriers and __user pointer sanitization + Vulnerability Spectre v2: Mitigation; Enhanced / Automatic IBRS; IBPB conditional; RSB filling; PBRSB-eIBRS SW sequence; BHI SW loop, KVM SW loop + Vulnerability Srbds: Not affected + Vulnerability Tsx async abort: Not affected + Vulnerability Vmscape: Not affected diff --git a/tests/2EE0C3AA/golden.txt b/tests/2EE0C3AA/golden.txt index d900ad6f6e..5233cf042e 100644 --- a/tests/2EE0C3AA/golden.txt +++ b/tests/2EE0C3AA/golden.txt @@ -1,14 +1,14 @@ D/cons.1.00.000000.dat 0.81 0.81 0.81 0.81 0.81 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.81 0.81 0.81 0.81 0.81 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.81 0.81 0.81 0.81 0.81 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.81 0.81 0.81 0.81 0.81 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.81 0.81 0.81 0.81 0.81 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.81 0.81 0.81 0.81 0.81 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.81 0.81 0.81 0.81 0.81 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.81 0.81 0.81 0.81 0.81 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.81 0.81 0.81 0.81 0.81 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.81 0.81 0.81 0.81 0.81 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.81 0.81 0.81 0.81 0.81 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.81 0.81 0.81 0.81 0.81 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.81 0.81 0.81 0.81 0.81 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.81 0.81 0.81 0.81 0.81 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.81 0.81 0.81 0.81 0.81 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.81 0.81 0.81 0.81 0.81 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.81 0.81 0.81 0.81 0.81 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.81 0.81 0.81 0.81 0.81 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.81 0.81 0.81 0.81 0.81 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.81 0.81 0.81 0.81 0.81 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.81 0.81 0.81 0.81 0.81 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.81 0.81 0.81 0.81 0.81 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.81 0.81 0.81 0.81 0.81 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.81 0.81 0.81 0.81 0.81 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.81 0.81 0.81 0.81 0.81 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.81 0.81 0.81 0.81 0.81 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.81 0.81 0.81 0.81 0.81 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.81 0.81 0.81 0.81 0.81 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.81 0.81 0.81 0.81 0.81 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.81 0.81 0.81 0.81 0.81 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.81 0.81 0.81 0.81 0.81 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.81 0.81 0.81 0.81 0.81 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.81 0.81 0.81 0.81 0.81 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.81 0.81 0.81 0.81 0.81 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.81 0.81 0.81 0.81 0.81 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.81 0.81 0.81 0.81 0.81 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.81 0.81 0.81 0.81 0.81 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.81 0.81 0.81 0.81 0.81 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.81 0.81 0.81 0.81 0.81 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.81 0.81 0.81 0.81 0.81 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.81 0.81 0.81 0.81 0.81 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.81 0.81 0.81 0.81 0.81 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.81 0.81 0.81 0.81 0.81 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.81 0.81 0.81 0.81 0.81 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.81 0.81 0.81 0.81 0.81 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.81 0.81 0.81 0.81 0.81 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.81 0.81 0.81 0.81 0.81 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.81 0.81 0.81 0.81 0.81 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.81 0.81 0.81 0.81 0.81 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.81 0.81 0.81 0.81 0.81 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.08 0.08 -D/cons.1.00.000050.dat 0.81 0.25519735697917 0.25462644269077 0.27489591511187 0.33063650264582 0.26749190593621 0.2571560724576 0.25141083852954 0.25018476156389 0.25001979547556 0.25000174625902 0.25000013072532 0.25000000848295 0.25000000045608 0.24999999997526 0.24999999999258 0.25000000000554 0.2500000000003 0.24999999999971 0.25000000000002 0.25000000000001 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.2499995963654 0.24999455000644 0.24993780798379 0.2494195444654 0.24578641151002 0.2245903425384 0.17194992628504 0.13027872976624 0.12107486420005 0.09492494868361 0.0818609282129 0.0801746494299 0.08016362513661 0.08135416534872 0.09351331828085 0.10696502902716 0.08 0.76974562362404 0.39688317436863 0.32612040346652 0.35557615324074 0.35188185444069 0.27879835840472 0.26317934511791 0.25341389415671 0.25043660038712 0.25004828865489 0.25000433922054 0.25000032929838 0.2500000215542 0.25000000121351 0.25000000002965 0.24999999997911 0.25000000000566 0.25000000000139 0.24999999999965 0.24999999999998 0.25000000000002 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636542 0.24999455000673 0.24993780798783 0.24941954448234 0.24578641003287 0.22459031083626 0.17194962937353 0.13027982694437 0.12107255126353 0.0949024663641 0.08186011126274 0.08019917013852 0.08015116264846 0.08031090558284 0.08116178234819 0.08029476728869 0.22080598813752 0.73171123975255 0.73722125477257 0.65489634453304 0.58516082230443 0.5745515017694 0.36639798110313 0.28334809850702 0.26016263113012 0.25129925413754 0.25014082750805 0.25001240998115 0.25000092451259 0.25000005976847 0.25000000344564 0.25000000016179 0.24999999996681 0.25000000000232 0.25000000000325 0.24999999999976 0.24999999999988 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.2499999740929 0.24999959636548 0.24999455000797 0.24993780800832 0.24941954477003 0.24578641360172 0.22459034823393 0.17194951378055 0.13028007686315 0.12107193798121 0.09490785976292 0.08184802956086 0.08019867289987 0.07999425919406 0.08000874380183 0.0801659632092 0.08273555364025 0.19326027952706 0.74065193584139 0.77641694991117 0.74295176151906 0.67009562101246 0.60709727581757 0.37899372700662 0.29041959148686 0.26225803294199 0.25157449438465 0.2501694892775 0.25001480775463 0.250001093803 0.25000007016325 0.25000000401122 0.25000000018836 0.24999999996635 0.25000000000152 0.25000000000352 0.24999999999978 0.24999999999986 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636539 0.24999455000625 0.24993780798096 0.24941954442228 0.24578641055071 0.22459032752995 0.17194977547463 0.13027924286082 0.12107263284739 0.09491595516458 0.08185791037281 0.08019964569626 0.07999060108936 0.08054290304209 0.08253935059368 0.10987255121882 0.28231058455196 0.75340166922336 0.75776274106975 0.79218741608067 0.73563435942958 0.65791970797367 0.39876481952682 0.29298247771005 0.26184017777901 0.25149920175233 0.25016237367954 0.25001421694001 0.2500010531317 0.25000006776889 0.25000000387605 0.25000000018074 0.24999999996619 0.25000000000185 0.25000000000345 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636536 0.24999455000559 0.24993780796994 0.24941954427898 0.24578640942508 0.22459032190697 0.17195005162539 0.13027848953127 0.12107656282873 0.09493052519051 0.08185348998924 0.08016619297944 0.08017355241667 0.08134356768442 0.08722455869755 0.15016989525838 0.33885872988875 0.56485541589155 0.73918219927816 0.77830190280163 0.75053631678078 0.67074160597033 0.39996018340561 0.29309063465071 0.26162613888335 0.25147394299112 0.25015998984481 0.25001403603411 0.25000104164172 0.25000006709255 0.25000000383375 0.25000000017878 0.24999999996625 0.2500000000019 0.25000000000343 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636535 0.24999455000546 0.24993780796832 0.24941954423518 0.24578640706294 0.22459027789953 0.17194962740284 0.13028041153906 0.12107829116384 0.09491672232951 0.08181681588244 0.08028444959372 0.08025740641923 0.08332524290312 0.10563834697674 0.18529742779138 0.34246155676229 0.53411849380521 0.72992099949941 0.77630110582776 0.7542768095866 0.6727544804008 0.40005536537373 0.29300607435455 0.26156084962515 0.25146741748134 0.25015944373071 0.25001399859256 0.25000103937888 0.2500000669682 0.25000000382922 0.25000000017868 0.24999999996625 0.25000000000191 0.25000000000343 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636535 0.24999455000544 0.24993780796792 0.24941954422572 0.24578640669687 0.22459027121339 0.17194958554143 0.13028057223834 0.12107873746801 0.09491507541321 0.08181313775924 0.08030117776319 0.08028182224191 0.08368103665827 0.10832259068735 0.18664861654808 0.33802358250401 0.52248116046183 0.72746493816782 0.77588813818133 0.75479967358976 0.67301167526526 0.40004555517149 0.29298438135777 0.2615521689354 0.25146664026826 0.25015938355226 0.25001399464984 0.25000103919179 0.25000006696793 0.25000000382985 0.25000000017872 0.24999999996624 0.25000000000191 0.25000000000343 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636535 0.24999455000543 0.24993780796784 0.24941954422441 0.24578640666923 0.22459027062975 0.17194958210626 0.13028058135244 0.12107879498313 0.09491480539446 0.08181277165617 0.08030400488839 0.08028559915253 0.08374417050465 0.10873281985125 0.18652501598584 0.33375389843124 0.52092646635473 0.72714230982176 0.77584391664019 0.75485926617255 0.67303752964759 0.40004324891541 0.29298193830801 0.2615512840754 0.25146656792365 0.25015937830109 0.25001399433955 0.25000103919564 0.25000006696811 0.25000000382981 0.25000000017871 0.24999999996624 0.25000000000191 0.25000000000343 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636535 0.24999455000543 0.24993780796783 0.24941954422424 0.24578640666502 0.22459027060095 0.17194958189855 0.13028058162166 0.12107880127351 0.09491478864071 0.08181274716329 0.08030420974251 0.08028597409563 0.08375032899863 0.10877015717584 0.18645474546472 0.33296522439281 0.52076111885305 0.72710873183106 0.77584000706473 0.75486477192437 0.67303965749045 0.40004294788209 0.29298170762497 0.26155121145839 0.25146656240737 0.25015937792146 0.25001399435005 0.25000103919429 0.25000006696756 0.25000000382976 0.25000000017871 0.24999999996624 0.25000000000191 0.25000000000343 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636535 0.24999455000543 0.24993780796783 0.24941954422425 0.24578640666495 0.22459027060052 0.17194958186454 0.13028058162869 0.12107880180936 0.09491478772977 0.08181274562969 0.08030422284135 0.08028600420485 0.08375082298443 0.10877304768899 0.1864435149408 0.33287475338582 0.52074705267365 0.72710591796015 0.77583971874036 0.75486519767653 0.67303980503068 0.40004291900331 0.29298168991575 0.26155120644226 0.25146656203951 0.25015937793483 0.25001399435006 0.25000103919291 0.25000006696748 0.25000000382976 0.25000000017871 0.24999999996624 0.25000000000191 0.25000000000343 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636535 0.24999455000543 0.24993780796783 0.24941954422425 0.24578640666492 0.22459027059911 0.17194958185966 0.13028058164738 0.12107880182313 0.09491478770139 0.08181274556405 0.08030422352667 0.08028600623947 0.08375085634041 0.10877323742949 0.18644224690383 0.33286629530794 0.52074605128723 0.72710572006643 0.77583970044752 0.75486522584565 0.67303981393746 0.40004291672935 0.29298168871812 0.26155120611943 0.25146656205698 0.25015937793754 0.25001399434786 0.2500010391929 0.2500000669675 0.25000000382976 0.25000000017871 0.24999999996624 0.25000000000191 0.25000000000343 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636535 0.24999455000543 0.24993780796783 0.24941954422424 0.24578640666489 0.2245902705989 0.17194958186225 0.13028058164554 0.12107880181017 0.09491478771713 0.08181274557549 0.08030422352812 0.08028600631898 0.08375085829534 0.10877324820145 0.1864421357263 0.33286564330578 0.52074598989769 0.72710570800951 0.77583969927987 0.75486522760697 0.67303981454495 0.40004291657839 0.29298168865766 0.26155120614477 0.25146656206064 0.25015937793472 0.25001399434786 0.25000103919294 0.2500000669675 0.25000000382976 0.25000000017871 0.24999999996624 0.25000000000191 0.25000000000343 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636535 0.24999455000543 0.24993780796783 0.24941954422424 0.24578640666489 0.22459027059891 0.17194958186225 0.1302805816441 0.12107880181366 0.09491478771512 0.08181274557213 0.08030422351852 0.08028600630116 0.08375085836052 0.10877324867395 0.1864421276071 0.33286560053806 0.52074598651225 0.72710570726444 0.77583969931109 0.75486522765995 0.67303981446245 0.40004291659851 0.29298168868833 0.2615512061503 0.25146656205763 0.25015937793465 0.25001399434792 0.25000103919293 0.2500000669675 0.25000000382976 0.25000000017871 0.24999999996624 0.25000000000191 0.25000000000343 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636535 0.24999455000543 0.24993780796783 0.24941954422424 0.2457864066649 0.22459027059891 0.17194958186212 0.13028058164424 0.12107880181451 0.09491478771409 0.08181274557114 0.08030422352265 0.08028600630484 0.08375085834611 0.10877324867306 0.18644212711242 0.33286559805951 0.52074598632346 0.72710570732104 0.77583969933243 0.75486522761712 0.6730398144528 0.40004291659906 0.29298168868463 0.26155120614671 0.25146656205753 0.25015937793474 0.25001399434791 0.25000103919293 0.2500000669675 0.25000000382976 0.25000000017871 0.24999999996624 0.25000000000191 0.25000000000343 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636535 0.24999455000543 0.24993780796783 0.24941954422424 0.24578640666489 0.22459027059891 0.17194958186214 0.1302805816443 0.1210788018143 0.09491478771421 0.08181274557136 0.08030422352309 0.0802860063065 0.08375085835061 0.10877324866612 0.18644212712424 0.33286559792779 0.52074598638237 0.7271057073337 0.77583969932421 0.7548652276252 0.67303981446149 0.40004291659695 0.29298168868246 0.26155120614649 0.25146656205764 0.25015937793473 0.25001399434791 0.25000103919293 0.2500000669675 0.25000000382976 0.25000000017871 0.24999999996624 0.25000000000191 0.25000000000343 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636535 0.24999455000543 0.24993780796783 0.24941954422424 0.24578640666489 0.22459027059891 0.17194958186214 0.13028058164429 0.12107880181428 0.09491478771424 0.08181274557138 0.08030422352287 0.08028600630624 0.08375085835169 0.10877324867003 0.1864421271362 0.33286559797644 0.52074598637781 0.72710570732619 0.77583969932327 0.75486522762775 0.67303981446171 0.40004291659697 0.29298168868275 0.26155120614665 0.25146656205762 0.25015937793473 0.25001399434791 0.25000103919293 0.2500000669675 0.25000000382976 0.25000000017871 0.24999999996624 0.25000000000191 0.25000000000343 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636535 0.24999455000543 0.24993780796783 0.24941954422424 0.24578640666489 0.22459027059891 0.17194958186214 0.13028058164428 0.1210788018143 0.09491478771423 0.08181274557136 0.08030422352288 0.08028600630619 0.0837508583514 0.10877324867002 0.18644212713163 0.33286559797118 0.52074598637366 0.72710570732575 0.77583969932365 0.7548652276272 0.67303981446128 0.40004291659706 0.29298168868283 0.26155120614664 0.25146656205762 0.25015937793473 0.25001399434791 0.25000103919293 0.2500000669675 0.25000000382976 0.25000000017871 0.24999999996624 0.25000000000191 0.25000000000343 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636535 0.24999455000543 0.24993780796783 0.24941954422424 0.24578640666489 0.22459027059891 0.17194958186214 0.13028058164428 0.1210788018143 0.09491478771423 0.08181274557136 0.08030422352289 0.08028600630621 0.08375085835137 0.10877324866982 0.18644212713092 0.33286559796774 0.52074598637407 0.72710570732608 0.77583969932365 0.75486522762715 0.67303981446132 0.40004291659705 0.2929816886828 0.26155120614664 0.25146656205762 0.25015937793473 0.25001399434791 0.25000103919293 0.2500000669675 0.25000000382976 0.25000000017871 0.24999999996624 0.25000000000191 0.25000000000343 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636535 0.24999455000543 0.24993780796783 0.24941954422424 0.24578640666489 0.22459027059891 0.17194958186214 0.13028058164428 0.12107880181429 0.09491478771423 0.08181274557136 0.08030422352289 0.08028600630621 0.0837508583514 0.10877324866985 0.18644212713116 0.33286559796821 0.52074598637421 0.72710570732606 0.77583969932363 0.75486522762718 0.67303981446134 0.40004291659705 0.2929816886828 0.26155120614664 0.25146656205762 0.25015937793473 0.25001399434791 0.25000103919293 0.2500000669675 0.25000000382976 0.25000000017871 0.24999999996624 0.25000000000191 0.25000000000343 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636535 0.24999455000543 0.24993780796783 0.24941954422424 0.24578640666489 0.22459027059891 0.17194958186214 0.13028058164428 0.12107880181429 0.09491478771423 0.08181274557136 0.08030422352289 0.08028600630621 0.08375085835139 0.10877324866986 0.18644212713118 0.33286559796832 0.52074598637417 0.72710570732605 0.77583969932364 0.75486522762718 0.67303981446134 0.40004291659705 0.2929816886828 0.26155120614664 0.25146656205762 0.25015937793473 0.25001399434791 0.25000103919293 0.2500000669675 0.25000000382976 0.25000000017871 0.24999999996624 0.25000000000191 0.25000000000343 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636535 0.24999455000543 0.24993780796783 0.24941954422424 0.24578640666489 0.22459027059891 0.17194958186214 0.13028058164428 0.12107880181429 0.09491478771423 0.08181274557136 0.08030422352289 0.08028600630621 0.08375085835139 0.10877324866985 0.18644212713116 0.33286559796828 0.52074598637417 0.72710570732605 0.77583969932364 0.75486522762718 0.67303981446134 0.40004291659705 0.2929816886828 0.26155120614664 0.25146656205762 0.25015937793473 0.25001399434791 0.25000103919293 0.2500000669675 0.25000000382976 0.25000000017871 0.24999999996624 0.25000000000191 0.25000000000343 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636535 0.24999455000543 0.24993780796783 0.24941954422424 0.24578640666489 0.22459027059891 0.17194958186214 0.13028058164428 0.12107880181429 0.09491478771423 0.08181274557136 0.08030422352289 0.08028600630621 0.08375085835139 0.10877324866985 0.18644212713116 0.33286559796828 0.52074598637417 0.72710570732605 0.77583969932364 0.75486522762718 0.67303981446134 0.40004291659705 0.2929816886828 0.26155120614664 0.25146656205762 0.25015937793473 0.25001399434791 0.25000103919293 0.2500000669675 0.25000000382976 0.25000000017871 0.24999999996624 0.25000000000191 0.25000000000343 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636535 0.24999455000543 0.24993780796783 0.24941954422424 0.24578640666489 0.22459027059891 0.17194958186214 0.13028058164428 0.12107880181429 0.09491478771423 0.08181274557136 0.08030422352289 0.08028600630621 0.08375085835139 0.10877324866985 0.18644212713116 0.33286559796828 0.52074598637417 0.72710570732605 0.77583969932364 0.75486522762718 0.67303981446134 0.40004291659705 0.2929816886828 0.26155120614664 0.25146656205762 0.25015937793473 0.25001399434791 0.25000103919293 0.2500000669675 0.25000000382976 0.25000000017871 0.24999999996624 0.25000000000191 0.25000000000343 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636535 0.24999455000543 0.24993780796783 0.24941954422424 0.24578640666489 0.22459027059891 0.17194958186214 0.13028058164428 0.12107880181429 0.09491478771423 0.08181274557136 0.08030422352289 0.08028600630621 0.08375085835139 0.10877324866985 0.18644212713116 0.33286559796828 0.52074598637417 0.72710570732605 0.77583969932364 0.75486522762718 0.67303981446134 0.40004291659705 0.2929816886828 0.26155120614664 0.25146656205762 0.25015937793473 0.25001399434791 0.25000103919293 0.2500000669675 0.25000000382976 0.25000000017871 0.24999999996624 0.25000000000191 0.25000000000343 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636535 0.24999455000543 0.24993780796783 0.24941954422424 0.24578640666489 0.22459027059891 0.17194958186214 0.13028058164428 0.12107880181429 0.09491478771423 0.08181274557136 0.08030422352289 0.08028600630621 0.08375085835139 0.10877324866985 0.18644212713116 0.33286559796828 0.52074598637417 0.72710570732605 0.77583969932364 0.75486522762718 0.67303981446134 0.40004291659705 0.2929816886828 0.26155120614664 0.25146656205762 0.25015937793473 0.25001399434791 0.25000103919293 0.2500000669675 0.25000000382976 0.25000000017871 0.24999999996624 0.25000000000191 0.25000000000343 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636535 0.24999455000543 0.24993780796783 0.24941954422424 0.24578640666489 0.22459027059891 0.17194958186214 0.13028058164428 0.12107880181429 0.09491478771423 0.08181274557136 0.08030422352289 0.08028600630621 0.08375085835139 0.10877324866985 0.18644212713116 0.33286559796828 0.52074598637417 0.72710570732605 0.77583969932364 0.75486522762718 0.67303981446134 0.40004291659705 0.2929816886828 0.26155120614664 0.25146656205762 0.25015937793473 0.25001399434791 0.25000103919293 0.2500000669675 0.25000000382976 0.25000000017871 0.24999999996624 0.25000000000191 0.25000000000343 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636535 0.24999455000543 0.24993780796783 0.24941954422424 0.24578640666489 0.22459027059891 0.17194958186214 0.13028058164428 0.12107880181429 0.09491478771423 0.08181274557136 0.08030422352289 0.08028600630621 0.08375085835139 0.10877324866985 0.18644212713116 0.33286559796828 0.52074598637417 0.72710570732605 0.77583969932364 0.75486522762718 0.67303981446134 0.40004291659705 0.2929816886828 0.26155120614664 0.25146656205762 0.25015937793473 0.25001399434791 0.25000103919293 0.2500000669675 0.25000000382976 0.25000000017871 0.24999999996624 0.25000000000191 0.25000000000343 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636535 0.24999455000543 0.24993780796783 0.24941954422424 0.24578640666489 0.22459027059891 0.17194958186214 0.13028058164428 0.12107880181429 0.09491478771423 0.08181274557136 0.08030422352289 0.08028600630621 0.08375085835139 0.10877324866985 0.18644212713116 0.33286559796828 0.52074598637417 0.72710570732605 0.77583969932364 0.75486522762718 0.67303981446134 0.40004291659705 0.2929816886828 0.26155120614664 0.25146656205762 0.25015937793473 0.25001399434791 0.25000103919293 0.2500000669675 0.25000000382976 0.25000000017871 0.24999999996624 0.25000000000191 0.25000000000343 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636535 0.24999455000543 0.24993780796783 0.24941954422424 0.24578640666489 0.22459027059891 0.17194958186214 0.13028058164428 0.12107880181429 0.09491478771423 0.08181274557136 0.08030422352289 0.08028600630621 0.08375085835139 0.10877324866985 0.18644212713116 0.33286559796828 0.52074598637417 0.72710570732605 0.77583969932364 0.75486522762718 0.67303981446134 0.40004291659705 0.2929816886828 0.26155120614664 0.25146656205762 0.25015937793473 0.25001399434791 0.25000103919293 0.2500000669675 0.25000000382976 0.25000000017871 0.24999999996624 0.25000000000191 0.25000000000343 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636535 0.24999455000543 0.24993780796783 0.24941954422424 0.24578640666489 0.22459027059891 0.17194958186214 0.13028058164428 0.12107880181429 0.09491478771423 0.08181274557136 0.08030422352289 0.08028600630621 0.08375085835139 0.10877324866985 0.18644212713116 0.33286559796828 0.52074598637421 0.72710570732607 0.77583969932363 0.75486522762718 0.67303981446134 0.40004291659705 0.2929816886828 0.26155120614664 0.25146656205762 0.25015937793473 0.25001399434791 0.25000103919293 0.2500000669675 0.25000000382976 0.25000000017871 0.24999999996624 0.25000000000191 0.25000000000343 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636535 0.24999455000543 0.24993780796783 0.24941954422424 0.24578640666489 0.22459027059891 0.17194958186214 0.13028058164428 0.12107880181429 0.09491478771423 0.08181274557136 0.08030422352289 0.08028600630621 0.08375085835139 0.10877324866985 0.18644212713118 0.33286559796832 0.52074598637405 0.72710570732609 0.77583969932367 0.75486522762715 0.67303981446133 0.40004291659705 0.2929816886828 0.26155120614664 0.25146656205762 0.25015937793473 0.25001399434791 0.25000103919293 0.2500000669675 0.25000000382976 0.25000000017871 0.24999999996624 0.25000000000191 0.25000000000343 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636535 0.24999455000543 0.24993780796783 0.24941954422424 0.24578640666489 0.22459027059891 0.17194958186214 0.13028058164428 0.12107880181429 0.09491478771423 0.08181274557136 0.08030422352289 0.08028600630621 0.08375085835139 0.10877324866986 0.18644212713117 0.33286559796818 0.52074598637365 0.72710570732563 0.77583969932366 0.7548652276272 0.67303981446133 0.40004291659707 0.29298168868283 0.26155120614664 0.25146656205762 0.25015937793473 0.25001399434791 0.25000103919293 0.2500000669675 0.25000000382976 0.25000000017871 0.24999999996624 0.25000000000191 0.25000000000343 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636535 0.24999455000543 0.24993780796783 0.24941954422424 0.24578640666489 0.22459027059891 0.17194958186214 0.13028058164428 0.12107880181429 0.09491478771423 0.08181274557136 0.08030422352289 0.08028600630621 0.0837508583514 0.1087732486698 0.18644212713085 0.33286559796776 0.52074598637831 0.72710570732641 0.77583969932306 0.75486522762769 0.67303981446145 0.40004291659687 0.29298168868276 0.26155120614666 0.25146656205762 0.25015937793473 0.25001399434791 0.25000103919293 0.2500000669675 0.25000000382976 0.25000000017871 0.24999999996624 0.25000000000191 0.25000000000343 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636535 0.24999455000543 0.24993780796783 0.24941954422424 0.24578640666489 0.22459027059891 0.17194958186214 0.13028058164428 0.12107880181429 0.09491478771423 0.08181274557136 0.08030422352288 0.08028600630622 0.0837508583514 0.1087732486699 0.18644212713185 0.33286559797169 0.52074598638206 0.72710570733537 0.77583969932491 0.75486522762561 0.67303981446137 0.40004291659698 0.29298168868242 0.26155120614653 0.25146656205764 0.25015937793473 0.25001399434791 0.25000103919293 0.2500000669675 0.25000000382976 0.25000000017871 0.24999999996624 0.25000000000191 0.25000000000343 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636535 0.24999455000543 0.24993780796783 0.24941954422424 0.24578640666489 0.22459027059891 0.17194958186214 0.13028058164428 0.1210788018143 0.09491478771424 0.08181274557137 0.08030422352288 0.08028600630621 0.08375085835135 0.10877324867075 0.18644212713732 0.33286559797587 0.52074598631895 0.72710570731528 0.77583969933484 0.75486522761783 0.67303981445861 0.40004291660135 0.29298168868435 0.26155120614651 0.25146656205755 0.25015937793474 0.25001399434791 0.25000103919293 0.2500000669675 0.25000000382976 0.25000000017871 0.24999999996624 0.25000000000191 0.25000000000343 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636535 0.24999455000543 0.24993780796783 0.24941954422424 0.24578640666489 0.22459027059891 0.17194958186214 0.13028058164429 0.12107880181429 0.09491478771424 0.08181274557138 0.08030422352298 0.08028600630614 0.08375085835158 0.10877324866776 0.18644212711944 0.33286559792422 0.52074598654457 0.72710570727496 0.77583969929978 0.75486522765405 0.67303981445991 0.40004291659758 0.29298168868904 0.26155120614953 0.25146656205751 0.25015937793467 0.25001399434792 0.25000103919293 0.2500000669675 0.25000000382976 0.25000000017871 0.24999999996624 0.25000000000191 0.25000000000343 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636535 0.24999455000543 0.24993780796783 0.24941954422424 0.2457864066649 0.22459027059891 0.17194958186213 0.13028058164429 0.12107880181428 0.09491478771408 0.08181274557124 0.08030422352293 0.08028600630638 0.08375085835111 0.10877324866343 0.1864421271254 0.33286559808565 0.52074599041727 0.72710570827109 0.77583969931145 0.75486522763433 0.67303981449936 0.40004291655694 0.2929816886609 0.2615512061487 0.2514665620601 0.25015937793462 0.25001399434786 0.25000103919294 0.2500000669675 0.25000000382976 0.25000000017871 0.24999999996624 0.25000000000191 0.25000000000343 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636535 0.24999455000543 0.24993780796783 0.24941954422424 0.2457864066649 0.22459027059892 0.17194958186217 0.13028058164417 0.1210788018144 0.09491478771465 0.08181274557141 0.08030422352021 0.08028600630578 0.08375085835127 0.10877324871115 0.186442127851 0.33286560094829 0.52074605931517 0.72710572426879 0.77583970103457 0.75486522627641 0.67303981426693 0.40004291686697 0.2929816886963 0.2615512061157 0.25146656205945 0.25015937793715 0.2500139943478 0.2500010391929 0.2500000669675 0.25000000382976 0.25000000017871 0.24999999996624 0.25000000000191 0.25000000000343 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636535 0.24999455000543 0.24993780796783 0.24941954422424 0.24578640666489 0.22459027059886 0.1719495818623 0.13028058164466 0.12107880181365 0.09491478771772 0.08181274557447 0.08030422352415 0.08028600630794 0.08375085834417 0.10877324888475 0.18644213961816 0.33286564951694 0.52074716030417 0.72710597834583 0.77583972802896 0.75486520568535 0.67303980960376 0.40004292053349 0.2929816896994 0.26155120630872 0.25146656203355 0.25015937793651 0.25001399434988 0.25000103919287 0.25000006696748 0.25000000382976 0.25000000017871 0.24999999996624 0.25000000000191 0.25000000000343 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636535 0.24999455000543 0.24993780796783 0.24941954422424 0.2457864066649 0.22459027059894 0.17194958186148 0.13028058164706 0.12107880181334 0.09491478770575 0.08181274556579 0.08030422354152 0.08028600631519 0.08375085774796 0.10877324688405 0.1864422970016 0.33286637649579 0.52076231435172 0.72710947010728 0.77584013399555 0.7548648944335 0.67303971879033 0.40004296918704 0.29298170489467 0.26155120965885 0.25146656226633 0.25015937791514 0.25001399435075 0.25000103919428 0.25000006696755 0.25000000382976 0.25000000017871 0.24999999996624 0.25000000000191 0.25000000000343 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636535 0.24999455000543 0.24993780796783 0.24941954422425 0.24578640666498 0.22459027060004 0.17194958186097 0.13028058163457 0.1210788018288 0.09491478773207 0.08181274557118 0.08030422324419 0.08028600589368 0.08375084187823 0.10877315556377 0.18644406478401 0.33287563289469 0.52093698516298 0.72714975718024 0.77584535912724 0.75486080049189 0.67303823305096 0.40004350088617 0.29298191227264 0.26155126285678 0.25146656614101 0.25015937817788 0.25001399433439 0.25000103919584 0.25000006696815 0.25000000382981 0.25000000017871 0.24999999996624 0.25000000000191 0.25000000000343 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636535 0.24999455000543 0.24993780796783 0.24941954422422 0.24578640666465 0.22459027059869 0.17194958188244 0.13028058163028 0.12107880174224 0.09491478860189 0.0818127464098 0.08030421555836 0.08028599407678 0.08375054220565 0.10877120925561 0.18646065896712 0.3329728991316 0.52255005330691 0.72752334675293 0.77590126585473 0.75481487073517 0.6730183663037 0.40004784185992 0.29298422708628 0.26155197095692 0.25146662191766 0.25015938219147 0.2500139945684 0.25000103918732 0.25000006696792 0.25000000382986 0.25000000017872 0.24999999996624 0.25000000000191 0.25000000000343 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636535 0.24999455000543 0.24993780796781 0.24941954422405 0.24578640666483 0.22459027060063 0.17194958206937 0.13028058152537 0.12107880007514 0.09491480533287 0.08181276615922 0.080304074041 0.0802857873644 0.08374607385788 0.10874008141473 0.18655816521801 0.3338079137592 0.53445953915439 0.73027464888599 0.77639631425737 0.75438813981363 0.67280702198473 0.4000745170771 0.29300492061077 0.26155948448957 0.25146727611752 0.25015943242878 0.25001399786941 0.25000103934002 0.25000006696587 0.25000000382913 0.25000000017868 0.24999999996625 0.25000000000191 0.25000000000343 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636535 0.24999455000543 0.24993780796783 0.2494195442247 0.24578640668564 0.2245902710163 0.1719495858211 0.13028057503551 0.12107877837064 0.09491507868178 0.08181311771677 0.08030188168518 0.08028317028521 0.08369431289296 0.10835909103529 0.18678200967823 0.33822739457309 0.56509804930323 0.73963122651044 0.77871479472273 0.75108215562254 0.67111739872193 0.40010159162153 0.29312164069861 0.26162293144625 0.25147345000595 0.25015994114557 0.25001403257611 0.25000104144976 0.2500000670816 0.25000000383308 0.25000000017875 0.24999999996625 0.25000000000191 0.25000000000343 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636535 0.24999455000545 0.24993780796813 0.24941954423273 0.24578640696582 0.22459027574065 0.17194962307515 0.13028044837214 0.12107854037092 0.09491701461105 0.08181669382118 0.08028745427604 0.08026304287216 0.08336989131035 0.10571710513544 0.1854699485584 0.34272734913075 0.75389271766202 0.75827847936538 0.79304190470975 0.73644568929578 0.6600928693058 0.40003933733924 0.29322961510311 0.26186300584657 0.25150079418991 0.25016249586954 0.25001422520564 0.2500010536775 0.25000006780299 0.2500000038777 0.25000000018079 0.24999999996619 0.25000000000185 0.25000000000346 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636535 0.24999455000538 0.24993780796683 0.24941954423858 0.24578640883183 0.22459031418851 0.17195004320215 0.1302786273737 0.12107744703077 0.09493163254343 0.08184999935865 0.0801738105826 0.08018232633173 0.0814038621147 0.08732687830424 0.15030856778209 0.33912014223095 0.74100108431256 0.7768064521836 0.74371959739328 0.67429099496566 0.61577901569113 0.38359683380794 0.29179307739894 0.26242758026869 0.25158815357034 0.25017075663693 0.25001489744996 0.25000109946775 0.25000007048326 0.25000000402831 0.25000000018912 0.24999999996634 0.2500000000015 0.25000000000352 0.24999999999979 0.24999999999986 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636532 0.24999455000482 0.24993780795726 0.24941954409213 0.24578640650736 0.22459028556407 0.17194981609243 0.13027913838724 0.12107311056476 0.09491230252401 0.08186198755406 0.08020652825778 0.08002110642218 0.08058055659613 0.08260176233764 0.10995195923351 0.28249557758317 0.73178319612072 0.73747203498238 0.65697338897285 0.59378869015643 0.58683029572656 0.37425047865585 0.2843996803848 0.26001591648468 0.25128440659357 0.25014066516588 0.25001246865599 0.25000093310414 0.25000006050462 0.25000000349163 0.25000000016476 0.24999999996679 0.2500000000022 0.25000000000327 0.24999999999976 0.24999999999988 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409288 0.24999959636521 0.24999455000279 0.24993780792565 0.24941954366517 0.24578640113599 0.22459022699618 0.17194979376969 0.13027916111821 0.12107151285104 0.09489414908113 0.08187613049969 0.08019146831599 0.08006285775269 0.08003868340375 0.08017442153682 0.08275530187249 0.19330208125084 0.76975653334217 0.39701549532285 0.32825762653642 0.36243293144105 0.35387153278297 0.27582308414669 0.26244193181823 0.25328784092154 0.2504149947315 0.25004530212744 0.25000403663062 0.25000030489015 0.25000001998456 0.2500000011298 0.25000000002454 0.24999999998031 0.25000000000565 0.25000000000128 0.24999999999966 0.24999999999998 0.25000000000002 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636529 0.2499945500043 0.24993780794877 0.24941954396041 0.2457864042797 0.22459025540917 0.1719497230817 0.13027942070635 0.12107246498811 0.0948980908688 0.08186806065284 0.08019779991802 0.08016216527887 0.08030649391728 0.08116601221463 0.08029757492042 0.22082766327957 0.81 0.25149507417092 0.25360630879849 0.25917897984458 0.26235382321713 0.26235327673602 0.25460126804249 0.25106523743048 0.2501269385684 0.25001305803327 0.25000113008556 0.25000008415464 0.25000000547674 0.25000000028449 0.24999999996271 0.24999999999818 0.250000000005 0.24999999999995 0.24999999999976 0.25000000000003 0.25000000000001 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636537 0.2499945500058 0.24993780797315 0.24941954432047 0.24578640997493 0.22459032933965 0.17194996708147 0.13027855906925 0.12107516233463 0.0949254930024 0.08186177846808 0.08017276725363 0.08016402021904 0.08148487599308 0.09349221242904 0.10742067660486 0.08 +D/cons.1.00.000050.dat 0.81 0.25519735697917 0.25462644269077 0.27489591511187 0.33063650264582 0.26749190593621 0.2571560724576 0.25141083852954 0.25018476156389 0.25001979547556 0.25000174625902 0.25000013072532 0.25000000848295 0.25000000045608 0.24999999997526 0.24999999999258 0.25000000000554 0.2500000000003 0.24999999999971 0.25000000000002 0.25000000000001 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.2499995963654 0.24999455000644 0.24993780798379 0.2494195444654 0.24578641151002 0.2245903425384 0.17194992628504 0.13027872976624 0.12107486420005 0.09492494868361 0.0818609282129 0.0801746494299 0.08016362513661 0.08135416534872 0.09351331828085 0.10696502902716 0.08 0.76974562362404 0.39688317436863 0.32612040346652 0.35557615324074 0.35188185444069 0.27879835840472 0.26317934511791 0.25341389415671 0.25043660038712 0.25004828865489 0.25000433922054 0.25000032929838 0.2500000215542 0.25000000121351 0.25000000002965 0.24999999997911 0.25000000000566 0.25000000000139 0.24999999999965 0.24999999999998 0.25000000000002 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636542 0.24999455000673 0.24993780798783 0.24941954448234 0.24578641003287 0.22459031083626 0.17194962937353 0.13027982694437 0.12107255126353 0.0949024663641 0.08186011126274 0.08019917013852 0.08015116264846 0.08031090558284 0.08116178234819 0.08029476728869 0.22080598813752 0.73171123975255 0.73722125477257 0.65489634453304 0.58516082230443 0.5745515017694 0.36639798110313 0.28334809850702 0.26016263113012 0.25129925413754 0.25014082750805 0.25001240998115 0.25000092451259 0.25000005976847 0.25000000344564 0.25000000016179 0.24999999996681 0.25000000000232 0.25000000000325 0.24999999999976 0.24999999999988 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.2499999740929 0.24999959636548 0.24999455000797 0.24993780800832 0.24941954477003 0.24578641360172 0.22459034823393 0.17194951378055 0.13028007686315 0.12107193798121 0.09490785976292 0.08184802956086 0.08019867289987 0.07999425919406 0.08000874380183 0.0801659632092 0.08273555364025 0.19326027952706 0.74065193584139 0.77641694991117 0.74295176151906 0.67009562101246 0.60709727581757 0.37899372700662 0.29041959148686 0.26225803294199 0.25157449438465 0.2501694892775 0.25001480775463 0.250001093803 0.25000007016325 0.25000000401122 0.25000000018836 0.24999999996635 0.25000000000152 0.25000000000352 0.24999999999978 0.24999999999986 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636539 0.24999455000625 0.24993780798096 0.24941954442228 0.24578641055071 0.22459032752995 0.17194977547463 0.13027924286082 0.12107263284739 0.09491595516458 0.08185791037281 0.08019964569626 0.07999060108936 0.08054290304209 0.08253935059368 0.10987255121882 0.28231058455196 0.75340166922336 0.75776274106975 0.79218741608067 0.73563435942958 0.65791970797367 0.39876481952682 0.29298247771005 0.26184017777901 0.25149920175233 0.25016237367954 0.25001421694001 0.2500010531317 0.25000006776889 0.25000000387605 0.25000000018074 0.24999999996619 0.25000000000185 0.25000000000345 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636536 0.24999455000559 0.24993780796994 0.24941954427898 0.24578640942508 0.22459032190697 0.17195005162539 0.13027848953127 0.12107656282873 0.09493052519051 0.08185348998924 0.08016619297944 0.08017355241667 0.08134356768442 0.08722455869755 0.15016989525838 0.33885872988875 0.56485541589155 0.73918219927816 0.77830190280163 0.75053631678078 0.67074160597033 0.39996018340561 0.29309063465071 0.26162613888335 0.25147394299112 0.25015998984481 0.25001403603411 0.25000104164172 0.25000006709255 0.25000000383375 0.25000000017878 0.24999999996625 0.25000000000191 0.25000000000343 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636535 0.24999455000546 0.24993780796832 0.24941954423518 0.24578640706294 0.22459027789953 0.17194962740284 0.13028041153906 0.12107829116384 0.09491672232951 0.08181681588244 0.08028444959372 0.08025740641923 0.08332524290312 0.10563834697674 0.18529742779138 0.34246155676229 0.53411849380521 0.72992099949941 0.77630110582776 0.7542768095866 0.6727544804008 0.40005536537373 0.29300607435455 0.26156084962515 0.25146741748134 0.25015944373071 0.25001399859256 0.25000103937888 0.2500000669682 0.25000000382922 0.25000000017868 0.24999999996625 0.25000000000191 0.25000000000343 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636535 0.24999455000544 0.24993780796792 0.24941954422572 0.24578640669687 0.22459027121339 0.17194958554143 0.13028057223834 0.12107873746801 0.09491507541321 0.08181313775924 0.08030117776319 0.08028182224191 0.08368103665827 0.10832259068735 0.18664861654808 0.33802358250401 0.52248116046183 0.72746493816782 0.77588813818133 0.75479967358976 0.67301167526526 0.40004555517149 0.29298438135777 0.2615521689354 0.25146664026826 0.25015938355226 0.25001399464984 0.25000103919179 0.25000006696793 0.25000000382985 0.25000000017872 0.24999999996624 0.25000000000191 0.25000000000343 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636535 0.24999455000543 0.24993780796784 0.24941954422441 0.24578640666923 0.22459027062975 0.17194958210626 0.13028058135244 0.12107879498313 0.09491480539446 0.08181277165617 0.08030400488839 0.08028559915253 0.08374417050465 0.10873281985125 0.18652501598584 0.33375389843124 0.52092646635473 0.72714230982176 0.77584391664019 0.75485926617255 0.67303752964759 0.40004324891541 0.29298193830801 0.2615512840754 0.25146656792365 0.25015937830109 0.25001399433955 0.25000103919564 0.25000006696811 0.25000000382981 0.25000000017871 0.24999999996624 0.25000000000191 0.25000000000343 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636535 0.24999455000543 0.24993780796783 0.24941954422424 0.24578640666502 0.22459027060095 0.17194958189855 0.13028058162166 0.12107880127351 0.09491478864071 0.08181274716329 0.08030420974251 0.08028597409563 0.08375032899863 0.10877015717584 0.18645474546472 0.33296522439281 0.52076111885305 0.72710873183106 0.77584000706473 0.75486477192437 0.67303965749045 0.40004294788209 0.29298170762497 0.26155121145839 0.25146656240737 0.25015937792146 0.25001399435005 0.25000103919429 0.25000006696756 0.25000000382976 0.25000000017871 0.24999999996624 0.25000000000191 0.25000000000343 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636535 0.24999455000543 0.24993780796783 0.24941954422425 0.24578640666495 0.22459027060052 0.17194958186454 0.13028058162869 0.12107880180936 0.09491478772977 0.08181274562969 0.08030422284135 0.08028600420485 0.08375082298443 0.10877304768899 0.1864435149408 0.33287475338582 0.52074705267365 0.72710591796015 0.77583971874036 0.75486519767653 0.67303980503068 0.40004291900331 0.29298168991575 0.26155120644226 0.25146656203951 0.25015937793483 0.25001399435006 0.25000103919291 0.25000006696748 0.25000000382976 0.25000000017871 0.24999999996624 0.25000000000191 0.25000000000343 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636535 0.24999455000543 0.24993780796783 0.24941954422425 0.24578640666492 0.22459027059911 0.17194958185966 0.13028058164738 0.12107880182313 0.09491478770139 0.08181274556405 0.08030422352667 0.08028600623947 0.08375085634041 0.10877323742949 0.18644224690383 0.33286629530794 0.52074605128723 0.72710572006643 0.77583970044752 0.75486522584565 0.67303981393746 0.40004291672935 0.29298168871812 0.26155120611943 0.25146656205698 0.25015937793754 0.25001399434786 0.2500010391929 0.2500000669675 0.25000000382976 0.25000000017871 0.24999999996624 0.25000000000191 0.25000000000343 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636535 0.24999455000543 0.24993780796783 0.24941954422424 0.24578640666489 0.2245902705989 0.17194958186225 0.13028058164554 0.12107880181017 0.09491478771713 0.08181274557549 0.08030422352812 0.08028600631898 0.08375085829534 0.10877324820145 0.1864421357263 0.33286564330578 0.52074598989769 0.7271057080095 0.77583969927987 0.75486522760697 0.67303981454495 0.40004291657839 0.29298168865766 0.26155120614477 0.25146656206064 0.25015937793472 0.25001399434786 0.25000103919294 0.2500000669675 0.25000000382976 0.25000000017871 0.24999999996624 0.25000000000191 0.25000000000343 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636535 0.24999455000543 0.24993780796783 0.24941954422424 0.24578640666489 0.22459027059891 0.17194958186225 0.1302805816441 0.12107880181366 0.09491478771512 0.08181274557213 0.08030422351852 0.08028600630116 0.08375085836052 0.10877324867395 0.1864421276071 0.33286560053806 0.52074598651225 0.72710570726444 0.77583969931109 0.75486522765995 0.67303981446245 0.40004291659851 0.29298168868833 0.2615512061503 0.25146656205763 0.25015937793465 0.25001399434792 0.25000103919293 0.2500000669675 0.25000000382976 0.25000000017871 0.24999999996624 0.25000000000191 0.25000000000343 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636535 0.24999455000543 0.24993780796783 0.24941954422424 0.2457864066649 0.22459027059891 0.17194958186212 0.13028058164424 0.12107880181451 0.09491478771409 0.08181274557114 0.08030422352265 0.08028600630484 0.08375085834611 0.10877324867306 0.18644212711242 0.33286559805951 0.52074598632346 0.72710570732104 0.77583969933243 0.75486522761711 0.6730398144528 0.40004291659906 0.29298168868463 0.26155120614671 0.25146656205753 0.25015937793474 0.25001399434791 0.25000103919293 0.2500000669675 0.25000000382976 0.25000000017871 0.24999999996624 0.25000000000191 0.25000000000343 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636535 0.24999455000543 0.24993780796783 0.24941954422424 0.24578640666489 0.22459027059891 0.17194958186214 0.1302805816443 0.1210788018143 0.09491478771421 0.08181274557136 0.08030422352309 0.0802860063065 0.08375085835061 0.10877324866612 0.18644212712424 0.33286559792779 0.52074598638237 0.7271057073337 0.77583969932421 0.7548652276252 0.67303981446149 0.40004291659695 0.29298168868246 0.26155120614649 0.25146656205764 0.25015937793473 0.25001399434791 0.25000103919293 0.2500000669675 0.25000000382976 0.25000000017871 0.24999999996624 0.25000000000191 0.25000000000343 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636535 0.24999455000543 0.24993780796783 0.24941954422424 0.24578640666489 0.22459027059891 0.17194958186214 0.13028058164429 0.12107880181428 0.09491478771424 0.08181274557138 0.08030422352287 0.08028600630624 0.08375085835169 0.10877324867003 0.1864421271362 0.33286559797644 0.52074598637781 0.72710570732619 0.77583969932326 0.75486522762775 0.67303981446171 0.40004291659697 0.29298168868275 0.26155120614665 0.25146656205762 0.25015937793473 0.25001399434791 0.25000103919293 0.2500000669675 0.25000000382976 0.25000000017871 0.24999999996624 0.25000000000191 0.25000000000343 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636535 0.24999455000543 0.24993780796783 0.24941954422424 0.24578640666489 0.22459027059891 0.17194958186214 0.13028058164428 0.1210788018143 0.09491478771423 0.08181274557136 0.08030422352288 0.08028600630619 0.0837508583514 0.10877324867002 0.18644212713163 0.33286559797118 0.52074598637366 0.72710570732575 0.77583969932365 0.7548652276272 0.67303981446128 0.40004291659706 0.29298168868283 0.26155120614664 0.25146656205762 0.25015937793473 0.25001399434791 0.25000103919293 0.2500000669675 0.25000000382976 0.25000000017871 0.24999999996624 0.25000000000191 0.25000000000343 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636535 0.24999455000543 0.24993780796783 0.24941954422424 0.24578640666489 0.22459027059891 0.17194958186214 0.13028058164428 0.1210788018143 0.09491478771423 0.08181274557136 0.08030422352289 0.08028600630621 0.08375085835137 0.10877324866982 0.18644212713092 0.33286559796774 0.52074598637407 0.72710570732608 0.77583969932365 0.75486522762715 0.67303981446132 0.40004291659705 0.2929816886828 0.26155120614664 0.25146656205762 0.25015937793473 0.25001399434791 0.25000103919293 0.2500000669675 0.25000000382976 0.25000000017871 0.24999999996624 0.25000000000191 0.25000000000343 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636535 0.24999455000543 0.24993780796783 0.24941954422424 0.24578640666489 0.22459027059891 0.17194958186214 0.13028058164428 0.12107880181429 0.09491478771423 0.08181274557136 0.08030422352289 0.08028600630621 0.0837508583514 0.10877324866985 0.18644212713116 0.33286559796821 0.52074598637421 0.72710570732606 0.77583969932364 0.75486522762718 0.67303981446134 0.40004291659705 0.2929816886828 0.26155120614664 0.25146656205762 0.25015937793473 0.25001399434791 0.25000103919293 0.2500000669675 0.25000000382976 0.25000000017871 0.24999999996624 0.25000000000191 0.25000000000343 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636535 0.24999455000543 0.24993780796783 0.24941954422424 0.24578640666489 0.22459027059891 0.17194958186214 0.13028058164428 0.12107880181429 0.09491478771423 0.08181274557136 0.08030422352289 0.08028600630621 0.08375085835139 0.10877324866986 0.18644212713118 0.33286559796832 0.52074598637417 0.72710570732605 0.77583969932364 0.75486522762718 0.67303981446134 0.40004291659705 0.2929816886828 0.26155120614664 0.25146656205762 0.25015937793473 0.25001399434791 0.25000103919293 0.2500000669675 0.25000000382976 0.25000000017871 0.24999999996624 0.25000000000191 0.25000000000343 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636535 0.24999455000543 0.24993780796783 0.24941954422424 0.24578640666489 0.22459027059891 0.17194958186214 0.13028058164428 0.12107880181429 0.09491478771423 0.08181274557136 0.08030422352289 0.08028600630621 0.08375085835139 0.10877324866985 0.18644212713116 0.33286559796828 0.52074598637417 0.72710570732605 0.77583969932364 0.75486522762718 0.67303981446134 0.40004291659705 0.2929816886828 0.26155120614664 0.25146656205762 0.25015937793473 0.25001399434791 0.25000103919293 0.2500000669675 0.25000000382976 0.25000000017871 0.24999999996624 0.25000000000191 0.25000000000343 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636535 0.24999455000543 0.24993780796783 0.24941954422424 0.24578640666489 0.22459027059891 0.17194958186214 0.13028058164428 0.12107880181429 0.09491478771423 0.08181274557136 0.08030422352289 0.08028600630621 0.08375085835139 0.10877324866985 0.18644212713116 0.33286559796828 0.52074598637417 0.72710570732605 0.77583969932364 0.75486522762718 0.67303981446134 0.40004291659705 0.2929816886828 0.26155120614664 0.25146656205762 0.25015937793473 0.25001399434791 0.25000103919293 0.2500000669675 0.25000000382976 0.25000000017871 0.24999999996624 0.25000000000191 0.25000000000343 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636535 0.24999455000543 0.24993780796783 0.24941954422424 0.24578640666489 0.22459027059891 0.17194958186214 0.13028058164428 0.12107880181429 0.09491478771423 0.08181274557136 0.08030422352289 0.08028600630621 0.08375085835139 0.10877324866985 0.18644212713116 0.33286559796828 0.52074598637417 0.72710570732605 0.77583969932364 0.75486522762718 0.67303981446134 0.40004291659705 0.2929816886828 0.26155120614664 0.25146656205762 0.25015937793473 0.25001399434791 0.25000103919293 0.2500000669675 0.25000000382976 0.25000000017871 0.24999999996624 0.25000000000191 0.25000000000343 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636535 0.24999455000543 0.24993780796783 0.24941954422424 0.24578640666489 0.22459027059891 0.17194958186214 0.13028058164428 0.12107880181429 0.09491478771423 0.08181274557136 0.08030422352289 0.08028600630621 0.08375085835139 0.10877324866985 0.18644212713116 0.33286559796828 0.52074598637417 0.72710570732605 0.77583969932364 0.75486522762718 0.67303981446134 0.40004291659705 0.2929816886828 0.26155120614664 0.25146656205762 0.25015937793473 0.25001399434791 0.25000103919293 0.2500000669675 0.25000000382976 0.25000000017871 0.24999999996624 0.25000000000191 0.25000000000343 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636535 0.24999455000543 0.24993780796783 0.24941954422424 0.24578640666489 0.22459027059891 0.17194958186214 0.13028058164428 0.12107880181429 0.09491478771423 0.08181274557136 0.08030422352289 0.08028600630621 0.08375085835139 0.10877324866985 0.18644212713116 0.33286559796828 0.52074598637417 0.72710570732605 0.77583969932364 0.75486522762718 0.67303981446134 0.40004291659705 0.2929816886828 0.26155120614664 0.25146656205762 0.25015937793473 0.25001399434791 0.25000103919293 0.2500000669675 0.25000000382976 0.25000000017871 0.24999999996624 0.25000000000191 0.25000000000343 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636535 0.24999455000543 0.24993780796783 0.24941954422424 0.24578640666489 0.22459027059891 0.17194958186214 0.13028058164428 0.12107880181429 0.09491478771423 0.08181274557136 0.08030422352289 0.08028600630621 0.08375085835139 0.10877324866985 0.18644212713116 0.33286559796828 0.52074598637417 0.72710570732605 0.77583969932364 0.75486522762718 0.67303981446134 0.40004291659705 0.2929816886828 0.26155120614664 0.25146656205762 0.25015937793473 0.25001399434791 0.25000103919293 0.2500000669675 0.25000000382976 0.25000000017871 0.24999999996624 0.25000000000191 0.25000000000343 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636535 0.24999455000543 0.24993780796783 0.24941954422424 0.2457864066649 0.22459027059891 0.17194958186214 0.13028058164428 0.12107880181429 0.09491478771423 0.08181274557136 0.08030422352289 0.08028600630621 0.08375085835139 0.10877324866985 0.18644212713116 0.33286559796828 0.52074598637417 0.72710570732605 0.77583969932364 0.75486522762718 0.67303981446134 0.40004291659705 0.2929816886828 0.26155120614664 0.25146656205762 0.25015937793473 0.25001399434791 0.25000103919293 0.2500000669675 0.25000000382976 0.25000000017871 0.24999999996624 0.25000000000191 0.25000000000343 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636535 0.24999455000543 0.24993780796783 0.24941954422424 0.24578640666489 0.22459027059891 0.17194958186214 0.13028058164428 0.12107880181429 0.09491478771423 0.08181274557136 0.08030422352289 0.08028600630621 0.08375085835139 0.10877324866985 0.18644212713116 0.33286559796828 0.52074598637417 0.72710570732605 0.77583969932364 0.75486522762718 0.67303981446134 0.40004291659705 0.2929816886828 0.26155120614664 0.25146656205762 0.25015937793473 0.25001399434791 0.25000103919293 0.2500000669675 0.25000000382976 0.25000000017871 0.24999999996624 0.25000000000191 0.25000000000343 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636535 0.24999455000543 0.24993780796783 0.24941954422424 0.24578640666489 0.22459027059891 0.17194958186214 0.13028058164428 0.12107880181429 0.09491478771423 0.08181274557136 0.08030422352289 0.08028600630621 0.08375085835139 0.10877324866985 0.18644212713116 0.33286559796828 0.52074598637417 0.72710570732605 0.77583969932364 0.75486522762718 0.67303981446134 0.40004291659705 0.2929816886828 0.26155120614664 0.25146656205762 0.25015937793473 0.25001399434791 0.25000103919293 0.2500000669675 0.25000000382976 0.25000000017871 0.24999999996624 0.25000000000191 0.25000000000343 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636535 0.24999455000543 0.24993780796783 0.24941954422424 0.24578640666489 0.22459027059891 0.17194958186214 0.13028058164428 0.12107880181429 0.09491478771423 0.08181274557136 0.08030422352289 0.08028600630621 0.08375085835139 0.10877324866985 0.18644212713116 0.33286559796828 0.52074598637421 0.72710570732607 0.77583969932363 0.75486522762718 0.67303981446134 0.40004291659704 0.2929816886828 0.26155120614664 0.25146656205762 0.25015937793473 0.25001399434791 0.25000103919293 0.2500000669675 0.25000000382976 0.25000000017871 0.24999999996624 0.25000000000191 0.25000000000343 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636535 0.24999455000543 0.24993780796783 0.24941954422424 0.24578640666489 0.22459027059891 0.17194958186214 0.13028058164428 0.12107880181429 0.09491478771423 0.08181274557136 0.08030422352289 0.08028600630621 0.08375085835139 0.10877324866985 0.18644212713118 0.33286559796832 0.52074598637405 0.72710570732609 0.77583969932367 0.75486522762715 0.67303981446133 0.40004291659705 0.2929816886828 0.26155120614664 0.25146656205762 0.25015937793473 0.25001399434791 0.25000103919293 0.2500000669675 0.25000000382976 0.25000000017871 0.24999999996624 0.25000000000191 0.25000000000343 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636535 0.24999455000543 0.24993780796783 0.24941954422424 0.24578640666489 0.22459027059891 0.17194958186214 0.13028058164428 0.12107880181429 0.09491478771423 0.08181274557136 0.08030422352289 0.08028600630621 0.08375085835139 0.10877324866986 0.18644212713117 0.33286559796818 0.52074598637365 0.72710570732563 0.77583969932366 0.7548652276272 0.67303981446133 0.40004291659707 0.29298168868283 0.26155120614664 0.25146656205762 0.25015937793473 0.25001399434791 0.25000103919293 0.2500000669675 0.25000000382976 0.25000000017871 0.24999999996624 0.25000000000191 0.25000000000343 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636535 0.24999455000543 0.24993780796783 0.24941954422424 0.24578640666489 0.22459027059891 0.17194958186214 0.13028058164428 0.12107880181429 0.09491478771423 0.08181274557136 0.08030422352289 0.08028600630621 0.0837508583514 0.1087732486698 0.18644212713085 0.33286559796776 0.52074598637831 0.72710570732641 0.77583969932306 0.75486522762769 0.67303981446145 0.40004291659687 0.29298168868276 0.26155120614666 0.25146656205762 0.25015937793473 0.25001399434791 0.25000103919293 0.2500000669675 0.25000000382976 0.25000000017871 0.24999999996624 0.25000000000191 0.25000000000343 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636535 0.24999455000543 0.24993780796783 0.24941954422424 0.24578640666489 0.22459027059891 0.17194958186214 0.13028058164428 0.12107880181429 0.09491478771423 0.08181274557136 0.08030422352288 0.08028600630622 0.0837508583514 0.1087732486699 0.18644212713185 0.33286559797169 0.52074598638206 0.72710570733537 0.77583969932491 0.75486522762561 0.67303981446137 0.40004291659698 0.29298168868242 0.26155120614653 0.25146656205764 0.25015937793473 0.25001399434791 0.25000103919293 0.2500000669675 0.25000000382976 0.25000000017871 0.24999999996624 0.25000000000191 0.25000000000343 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636535 0.24999455000543 0.24993780796783 0.24941954422424 0.24578640666489 0.22459027059891 0.17194958186214 0.13028058164428 0.1210788018143 0.09491478771424 0.08181274557137 0.08030422352288 0.08028600630621 0.08375085835135 0.10877324867075 0.18644212713732 0.33286559797587 0.52074598631895 0.72710570731528 0.77583969933484 0.75486522761783 0.67303981445861 0.40004291660135 0.29298168868435 0.26155120614651 0.25146656205755 0.25015937793474 0.25001399434791 0.25000103919293 0.2500000669675 0.25000000382976 0.25000000017871 0.24999999996624 0.25000000000191 0.25000000000343 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636535 0.24999455000543 0.24993780796783 0.24941954422424 0.24578640666489 0.22459027059891 0.17194958186214 0.13028058164429 0.12107880181429 0.09491478771424 0.08181274557138 0.08030422352298 0.08028600630614 0.08375085835158 0.10877324866776 0.18644212711944 0.33286559792422 0.52074598654457 0.72710570727496 0.77583969929978 0.75486522765405 0.67303981445991 0.40004291659758 0.29298168868904 0.26155120614953 0.25146656205751 0.25015937793467 0.25001399434792 0.25000103919293 0.2500000669675 0.25000000382976 0.25000000017871 0.24999999996624 0.25000000000191 0.25000000000343 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636535 0.24999455000543 0.24993780796783 0.24941954422424 0.24578640666489 0.22459027059891 0.17194958186213 0.13028058164429 0.12107880181428 0.09491478771408 0.08181274557124 0.08030422352293 0.08028600630638 0.08375085835111 0.10877324866343 0.1864421271254 0.33286559808565 0.52074599041727 0.72710570827109 0.77583969931145 0.75486522763433 0.67303981449936 0.40004291655694 0.2929816886609 0.2615512061487 0.2514665620601 0.25015937793462 0.25001399434786 0.25000103919294 0.2500000669675 0.25000000382976 0.25000000017871 0.24999999996624 0.25000000000191 0.25000000000343 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636535 0.24999455000543 0.24993780796783 0.24941954422424 0.2457864066649 0.22459027059892 0.17194958186217 0.13028058164417 0.1210788018144 0.09491478771465 0.08181274557141 0.08030422352021 0.08028600630578 0.08375085835127 0.10877324871115 0.186442127851 0.33286560094829 0.52074605931517 0.72710572426879 0.77583970103457 0.75486522627641 0.67303981426693 0.40004291686697 0.2929816886963 0.2615512061157 0.25146656205945 0.25015937793715 0.2500139943478 0.2500010391929 0.2500000669675 0.25000000382976 0.25000000017871 0.24999999996624 0.25000000000191 0.25000000000343 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636535 0.24999455000543 0.24993780796783 0.24941954422424 0.24578640666489 0.22459027059886 0.1719495818623 0.13028058164466 0.12107880181365 0.09491478771772 0.08181274557447 0.08030422352415 0.08028600630794 0.08375085834417 0.10877324888475 0.18644213961816 0.33286564951694 0.52074716030417 0.72710597834583 0.77583972802896 0.75486520568535 0.67303980960376 0.40004292053349 0.2929816896994 0.26155120630872 0.25146656203355 0.25015937793651 0.25001399434988 0.25000103919287 0.25000006696748 0.25000000382976 0.25000000017871 0.24999999996624 0.25000000000191 0.25000000000343 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636535 0.24999455000543 0.24993780796783 0.24941954422424 0.2457864066649 0.22459027059894 0.17194958186148 0.13028058164706 0.12107880181334 0.09491478770575 0.08181274556579 0.08030422354152 0.08028600631519 0.08375085774796 0.10877324688405 0.1864422970016 0.33286637649579 0.52076231435172 0.72710947010728 0.77584013399555 0.7548648944335 0.67303971879033 0.40004296918704 0.29298170489467 0.26155120965885 0.25146656226633 0.25015937791514 0.25001399435075 0.25000103919428 0.25000006696755 0.25000000382976 0.25000000017871 0.24999999996624 0.25000000000191 0.25000000000343 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636535 0.24999455000543 0.24993780796783 0.24941954422425 0.24578640666498 0.22459027060004 0.17194958186097 0.13028058163457 0.1210788018288 0.09491478773207 0.08181274557118 0.08030422324419 0.08028600589368 0.08375084187823 0.10877315556377 0.18644406478401 0.33287563289469 0.52093698516298 0.72714975718024 0.77584535912724 0.75486080049189 0.67303823305096 0.40004350088617 0.29298191227264 0.26155126285678 0.25146656614101 0.25015937817788 0.25001399433439 0.25000103919584 0.25000006696815 0.25000000382981 0.25000000017871 0.24999999996624 0.25000000000191 0.25000000000343 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636535 0.24999455000543 0.24993780796783 0.24941954422422 0.24578640666465 0.22459027059869 0.17194958188244 0.13028058163028 0.12107880174224 0.09491478860189 0.0818127464098 0.08030421555836 0.08028599407678 0.08375054220565 0.10877120925561 0.18646065896712 0.3329728991316 0.52255005330691 0.72752334675293 0.77590126585473 0.75481487073517 0.6730183663037 0.40004784185992 0.29298422708628 0.26155197095692 0.25146662191766 0.25015938219147 0.2500139945684 0.25000103918732 0.25000006696792 0.25000000382986 0.25000000017872 0.24999999996624 0.25000000000191 0.25000000000343 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636535 0.24999455000543 0.24993780796781 0.24941954422405 0.24578640666483 0.22459027060063 0.17194958206937 0.13028058152537 0.12107880007514 0.09491480533287 0.08181276615922 0.080304074041 0.0802857873644 0.08374607385788 0.10874008141473 0.18655816521801 0.3338079137592 0.53445953915439 0.73027464888599 0.77639631425737 0.75438813981363 0.67280702198473 0.4000745170771 0.29300492061077 0.26155948448957 0.25146727611752 0.25015943242878 0.25001399786941 0.25000103934002 0.25000006696587 0.25000000382913 0.25000000017868 0.24999999996625 0.25000000000191 0.25000000000343 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636535 0.24999455000543 0.24993780796783 0.2494195442247 0.24578640668564 0.2245902710163 0.1719495858211 0.13028057503551 0.12107877837064 0.09491507868178 0.08181311771677 0.08030188168518 0.08028317028521 0.08369431289296 0.10835909103529 0.18678200967823 0.33822739457309 0.56509804930323 0.73963122651044 0.77871479472273 0.75108215562254 0.67111739872193 0.40010159162153 0.29312164069861 0.26162293144625 0.25147345000595 0.25015994114557 0.25001403257611 0.25000104144976 0.2500000670816 0.25000000383308 0.25000000017875 0.24999999996625 0.25000000000191 0.25000000000343 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636535 0.24999455000545 0.24993780796813 0.24941954423273 0.24578640696582 0.22459027574065 0.17194962307515 0.13028044837214 0.12107854037092 0.09491701461105 0.08181669382118 0.08028745427604 0.08026304287216 0.08336989131035 0.10571710513544 0.1854699485584 0.34272734913075 0.75389271766202 0.75827847936538 0.79304190470975 0.73644568929578 0.6600928693058 0.40003933733924 0.29322961510311 0.26186300584657 0.25150079418991 0.25016249586954 0.25001422520564 0.2500010536775 0.25000006780299 0.2500000038777 0.25000000018079 0.24999999996619 0.25000000000185 0.25000000000345 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636535 0.24999455000538 0.24993780796683 0.24941954423858 0.24578640883183 0.22459031418851 0.17195004320215 0.1302786273737 0.12107744703077 0.09493163254343 0.08184999935865 0.0801738105826 0.08018232633173 0.0814038621147 0.08732687830424 0.15030856778209 0.33912014223095 0.74100108431256 0.7768064521836 0.74371959739328 0.67429099496566 0.61577901569113 0.38359683380794 0.29179307739894 0.26242758026869 0.25158815357034 0.25017075663693 0.25001489744996 0.25000109946775 0.25000007048326 0.25000000402831 0.25000000018912 0.24999999996634 0.2500000000015 0.25000000000352 0.24999999999979 0.24999999999986 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636532 0.24999455000482 0.24993780795726 0.24941954409213 0.24578640650736 0.22459028556407 0.17194981609243 0.13027913838724 0.12107311056476 0.09491230252401 0.08186198755406 0.08020652825778 0.08002110642218 0.08058055659613 0.08260176233764 0.10995195923351 0.28249557758317 0.73178319612072 0.73747203498238 0.65697338897285 0.59378869015643 0.58683029572656 0.37425047865585 0.2843996803848 0.26001591648468 0.25128440659357 0.25014066516588 0.25001246865599 0.25000093310414 0.25000006050462 0.25000000349163 0.25000000016476 0.24999999996679 0.2500000000022 0.25000000000327 0.24999999999976 0.24999999999988 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409288 0.24999959636521 0.24999455000279 0.24993780792565 0.24941954366517 0.24578640113599 0.22459022699618 0.17194979376969 0.13027916111821 0.12107151285104 0.09489414908113 0.08187613049969 0.08019146831599 0.08006285775269 0.08003868340375 0.08017442153682 0.08275530187249 0.19330208125084 0.76975653334217 0.39701549532285 0.32825762653642 0.36243293144105 0.35387153278297 0.27582308414669 0.26244193181823 0.25328784092154 0.2504149947315 0.25004530212744 0.25000403663062 0.25000030489015 0.25000001998456 0.2500000011298 0.25000000002454 0.24999999998031 0.25000000000565 0.25000000000128 0.24999999999966 0.24999999999998 0.25000000000002 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636529 0.2499945500043 0.24993780794877 0.24941954396041 0.2457864042797 0.22459025540917 0.1719497230817 0.13027942070635 0.12107246498811 0.0948980908688 0.08186806065284 0.08019779991802 0.08016216527887 0.08030649391728 0.08116601221463 0.08029757492042 0.22082766327957 0.81 0.25149507417092 0.25360630879849 0.25917897984458 0.26235382321713 0.26235327673602 0.25460126804249 0.25106523743048 0.2501269385684 0.25001305803327 0.25000113008556 0.25000008415464 0.25000000547674 0.25000000028449 0.24999999996271 0.24999999999818 0.250000000005 0.24999999999995 0.24999999999976 0.25000000000003 0.25000000000001 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636537 0.2499945500058 0.24993780797315 0.24941954432047 0.24578640997493 0.22459032933965 0.17194996708147 0.13027855906925 0.12107516233463 0.0949254930024 0.08186177846808 0.08017276725363 0.08016402021904 0.08148487599308 0.09349221242904 0.10742067660486 0.08 D/cons.2.00.000000.dat 0.19 0.19 0.19 0.19 0.19 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.19 0.19 0.19 0.19 0.19 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.19 0.19 0.19 0.19 0.19 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.19 0.19 0.19 0.19 0.19 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.19 0.19 0.19 0.19 0.19 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.19 0.19 0.19 0.19 0.19 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.19 0.19 0.19 0.19 0.19 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.19 0.19 0.19 0.19 0.19 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.19 0.19 0.19 0.19 0.19 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.19 0.19 0.19 0.19 0.19 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.19 0.19 0.19 0.19 0.19 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.19 0.19 0.19 0.19 0.19 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.19 0.19 0.19 0.19 0.19 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.19 0.19 0.19 0.19 0.19 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.19 0.19 0.19 0.19 0.19 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.19 0.19 0.19 0.19 0.19 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.19 0.19 0.19 0.19 0.19 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.19 0.19 0.19 0.19 0.19 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.19 0.19 0.19 0.19 0.19 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.19 0.19 0.19 0.19 0.19 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.19 0.19 0.19 0.19 0.19 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.19 0.19 0.19 0.19 0.19 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.19 0.19 0.19 0.19 0.19 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.19 0.19 0.19 0.19 0.19 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.19 0.19 0.19 0.19 0.19 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.19 0.19 0.19 0.19 0.19 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.19 0.19 0.19 0.19 0.19 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.19 0.19 0.19 0.19 0.19 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.19 0.19 0.19 0.19 0.19 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.19 0.19 0.19 0.19 0.19 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.19 0.19 0.19 0.19 0.19 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.19 0.19 0.19 0.19 0.19 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.19 0.19 0.19 0.19 0.19 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.19 0.19 0.19 0.19 0.19 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.19 0.19 0.19 0.19 0.19 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.19 0.19 0.19 0.19 0.19 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.19 0.19 0.19 0.19 0.19 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.19 0.19 0.19 0.19 0.19 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.19 0.19 0.19 0.19 0.19 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.19 0.19 0.19 0.19 0.19 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.19 0.19 0.19 0.19 0.19 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.19 0.19 0.19 0.19 0.19 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.19 0.19 0.19 0.19 0.19 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.19 0.19 0.19 0.19 0.19 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.19 0.19 0.19 0.19 0.19 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.19 0.19 0.19 0.19 0.19 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.19 0.19 0.19 0.19 0.19 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.19 0.19 0.19 0.19 0.19 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.19 0.19 0.19 0.19 0.19 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.19 0.19 0.19 0.19 0.19 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 0.0225 -D/cons.2.00.000050.dat 0.19 0.2552208436096 0.25452999304654 0.26263009638661 0.24380638426214 0.2631715684653 0.25713253374367 0.25141241936026 0.25018475874456 0.2500197954756 0.25000174625902 0.25000013072532 0.25000000848295 0.25000000045608 0.24999999997526 0.24999999999258 0.25000000000554 0.2500000000003 0.24999999999971 0.25000000000002 0.25000000000001 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.2499995963654 0.24999455000644 0.24993780798379 0.24941954446554 0.24578641836326 0.224518891862 0.1750454792715 0.10254428276082 0.04291411692753 0.02676299736433 0.02302504636431 0.02254912078853 0.02254602010636 0.02288204989281 0.02635681697677 0.03423352975896 0.0225 0.1805572859672 0.24944197324291 0.26773402720492 0.23823522342245 0.23491514696768 0.26504798523279 0.2629962334623 0.25342837514063 0.2504365967241 0.25004828865626 0.25000433922054 0.25000032929838 0.2500000215542 0.25000000121351 0.25000000002965 0.24999999997911 0.25000000000566 0.25000000000139 0.24999999999965 0.24999999999998 0.25000000000002 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636542 0.24999455000673 0.24993780798783 0.24941954448248 0.2457864168858 0.22451886131485 0.17504518499227 0.10254515853762 0.04291340824477 0.02675636752571 0.02302484690138 0.02255601731127 0.0225425149927 0.0225875680626 0.0228277369542 0.02258293079796 0.05602070548185 0.17163367047563 0.17280749890114 0.15594562976503 0.15098234950374 0.1379973218688 0.23354511856216 0.27826989460349 0.26021212375348 0.2512992867511 0.25014082750364 0.25001240998114 0.25000092451259 0.25000005976847 0.25000000344564 0.25000000016179 0.24999999996681 0.25000000000232 0.25000000000325 0.24999999999976 0.24999999999988 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.2499999740929 0.24999959636548 0.24999455000797 0.24993780800832 0.24941954477016 0.24578642045433 0.2245189005626 0.17504509105882 0.10254515559642 0.04291312866481 0.02675810400578 0.02302143970173 0.02255587746577 0.02249838539866 0.02250245924702 0.0225466770159 0.02326792705623 0.05034450078984 0.17373282563648 0.18212264995216 0.17427767458393 0.15709443746136 0.14232604615753 0.23842973683663 0.28428598668229 0.26236866393965 0.25157458132993 0.25016948929534 0.25001480775463 0.250001093803 0.25000007016325 0.25000000401122 0.25000000018836 0.24999999996635 0.25000000000152 0.25000000000352 0.24999999999978 0.24999999999986 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636539 0.24999455000625 0.24993780798096 0.24941954442242 0.24578641740381 0.22451887731014 0.17504533193229 0.10254463916733 0.04291349638867 0.02676037441037 0.02302420862686 0.02255615100613 0.02249735655551 0.02265267041772 0.02320873806533 0.03058177165107 0.06878241217105 0.17672593328875 0.1777486788669 0.18582227162687 0.17256193894377 0.15402415014781 0.24681389055537 0.28691490809582 0.26198225944108 0.25149907887133 0.25016237374022 0.25001421694 0.2500010531317 0.25000006776889 0.25000000387605 0.25000000018074 0.24999999996619 0.25000000000185 0.25000000000345 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636536 0.24999455000559 0.24993780796994 0.24941954427912 0.24578641627858 0.22451886970988 0.17504558994498 0.10254420461609 0.04291455751773 0.02676460535281 0.02302294283358 0.02254674238107 0.02254881145916 0.02287782027125 0.02450858955138 0.04011108594757 0.08054264541941 0.13232534466556 0.17339123025241 0.1825647516134 0.17605924908538 0.15675171113725 0.24849786480597 0.28705651250704 0.26177135908704 0.25147380260584 0.25015998990809 0.25001403603411 0.25000104164172 0.25000006709255 0.25000000383375 0.25000000017878 0.24999999996625 0.2500000000019 0.25000000000343 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636535 0.24999455000546 0.24993780796832 0.24941954423532 0.24578641391607 0.22451882743485 0.17504517866077 0.10254560761555 0.04291451066098 0.02676063667611 0.02301262470689 0.02258000209657 0.02257239445827 0.02343327191813 0.02958845023307 0.04863518558331 0.08127545109449 0.12507472555109 0.17121441463878 0.18209537827551 0.17693678968583 0.15714816124178 0.2487138021526 0.28698597918238 0.26170576882037 0.2514672749311 0.25015944379431 0.25001399859255 0.25000103937888 0.2500000669682 0.25000000382922 0.25000000017868 0.24999999996625 0.25000000000191 0.25000000000343 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636535 0.24999455000544 0.24993780796792 0.24941954422586 0.24578641354998 0.22451882082658 0.17504513732694 0.10254575740388 0.04291462414961 0.02676016191968 0.02301158832787 0.02258470688751 0.02257926125709 0.02353322347426 0.03034582200371 0.04901493160242 0.08031463657436 0.12234650379249 0.17063719639159 0.18199851712886 0.1770595627048 0.15719796849352 0.24873300503761 0.28696581933089 0.2616970008627 0.25146649761311 0.25015938361589 0.25001399464983 0.25000103919179 0.25000006696793 0.25000000382985 0.25000000017872 0.24999999996624 0.25000000000191 0.25000000000343 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636535 0.24999455000543 0.24993780796784 0.24941954422455 0.24578641352233 0.22451882023588 0.1750451340501 0.1025457676675 0.04291464075071 0.0267600838973 0.0230114851081 0.02258550201583 0.02258032349655 0.02355093837281 0.03046620244114 0.0489990958989 0.07930800368037 0.12198247709188 0.17056142480975 0.18198814538627 0.17707355966448 0.15720298906388 0.24873410535828 0.28696351136976 0.26169610586386 0.25146642525927 0.25015937836472 0.25001399433955 0.25000103919564 0.25000006696811 0.25000000382981 0.25000000017871 0.24999999996624 0.25000000000191 0.25000000000343 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636535 0.24999455000543 0.24993780796783 0.24941954422438 0.24578641351812 0.22451882020687 0.17504513385657 0.10254576813931 0.04291464263544 0.02676007904437 0.02301147819921 0.02258555963099 0.02258042894761 0.02355266301382 0.03047744995002 0.04898277581396 0.07912014127225 0.12194377886622 0.17055354085081 0.1819872284631 0.17707485303707 0.15720340335229 0.24873412493506 0.28696329126192 0.26169603231337 0.25146641974277 0.25015937798509 0.25001399435005 0.25000103919429 0.25000006696756 0.25000000382976 0.25000000017871 0.24999999996624 0.25000000000191 0.25000000000343 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636535 0.24999455000543 0.24993780796783 0.24941954422439 0.24578641351806 0.22451882020674 0.1750451338239 0.10254576815553 0.04291464280213 0.02676007878023 0.0230114777665 0.02258556331515 0.02258043741576 0.02355280126401 0.03047833468126 0.04898002910857 0.07909854688397 0.12194048728163 0.1705528802863 0.18198716084339 0.17707495305635 0.15720343212773 0.2487341212037 0.2869632742629 0.2616960272299 0.25146641937494 0.25015937799846 0.25001399435006 0.25000103919291 0.25000006696748 0.25000000382976 0.25000000017871 0.24999999996624 0.25000000000191 0.25000000000343 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636535 0.24999455000543 0.24993780796783 0.24941954422438 0.24578641351803 0.22451882020535 0.17504513381888 0.10254576816752 0.04291464280679 0.02676007877257 0.023011477748 0.02258556350781 0.02258043798798 0.02355281059834 0.03047839353434 0.04897971296489 0.07909652642722 0.12194025295823 0.17055283383656 0.18198715655322 0.17707495967393 0.1572034338691 0.24873412062036 0.28696327311005 0.26169602690233 0.2514664193924 0.25015937800117 0.25001399434786 0.2500010391929 0.2500000669675 0.25000000382976 0.25000000017871 0.24999999996624 0.25000000000191 0.25000000000343 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636535 0.24999455000543 0.24993780796783 0.24941954422438 0.245786413518 0.22451882020511 0.17504513382143 0.10254576816657 0.04291464280208 0.02676007877712 0.0230114777512 0.02258556350821 0.02258043801028 0.02355281114545 0.03047839692068 0.0489796849593 0.07909637064281 0.12194023859271 0.17055283100678 0.18198715627943 0.17707496008764 0.1572034339911 0.24873412059431 0.28696327305227 0.26169602692743 0.25146641939607 0.25015937799835 0.25001399434786 0.25000103919294 0.2500000669675 0.25000000382976 0.25000000017871 0.24999999996624 0.25000000000191 0.25000000000343 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636535 0.24999455000543 0.24993780796783 0.24941954422438 0.245786413518 0.22451882020511 0.17504513382144 0.10254576816576 0.04291464280321 0.0267600787765 0.02301147775025 0.02258556350551 0.02258043800529 0.02355281116362 0.03047839707334 0.04897968289944 0.07909636042514 0.12194023780039 0.17055283083201 0.18198715628678 0.17707496010008 0.1572034339725 0.24873412061063 0.28696327308179 0.26169602693315 0.25146641939306 0.25015937799828 0.25001399434792 0.25000103919293 0.2500000669675 0.25000000382976 0.25000000017871 0.24999999996624 0.25000000000191 0.25000000000343 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636535 0.24999455000543 0.24993780796783 0.24941954422438 0.245786413518 0.22451882020512 0.17504513382131 0.10254576816584 0.04291464280351 0.0267600787762 0.02301147774997 0.02258556350667 0.02258043800632 0.02355281115957 0.03047839707425 0.04897968277325 0.07909635983307 0.12194023775634 0.17055283084528 0.18198715629178 0.17707496009004 0.15720343397058 0.24873412060813 0.28696327307817 0.26169602692954 0.25146641939295 0.25015937799837 0.25001399434791 0.25000103919293 0.2500000669675 0.25000000382976 0.25000000017871 0.24999999996624 0.25000000000191 0.25000000000343 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636535 0.24999455000543 0.24993780796783 0.24941954422438 0.245786413518 0.22451882020512 0.17504513382132 0.10254576816588 0.04291464280344 0.02676007877623 0.02301147775003 0.0225855635068 0.02258043800679 0.02355281116083 0.03047839707247 0.04897968277625 0.07909635980175 0.1219402377701 0.17055283084825 0.18198715628985 0.17707496009194 0.15720343397246 0.24873412060691 0.28696327307607 0.26169602692931 0.25146641939306 0.25015937799836 0.25001399434791 0.25000103919293 0.2500000669675 0.25000000382976 0.25000000017871 0.24999999996624 0.25000000000191 0.25000000000343 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636535 0.24999455000543 0.24993780796783 0.24941954422438 0.245786413518 0.22451882020512 0.17504513382133 0.10254576816587 0.04291464280344 0.02676007877624 0.02301147775004 0.02258556350674 0.02258043800671 0.02355281116113 0.03047839707351 0.04897968277934 0.07909635981337 0.12194023776903 0.17055283084649 0.18198715628963 0.17707496009254 0.1572034339725 0.24873412060706 0.28696327307636 0.26169602692947 0.25146641939305 0.25015937799836 0.25001399434791 0.25000103919293 0.2500000669675 0.25000000382976 0.25000000017871 0.24999999996624 0.25000000000191 0.25000000000343 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636535 0.24999455000543 0.24993780796783 0.24941954422438 0.245786413518 0.22451882020512 0.17504513382132 0.10254576816587 0.04291464280344 0.02676007877624 0.02301147775004 0.02258556350674 0.0225804380067 0.02355281116105 0.03047839707351 0.04897968277817 0.0790963598121 0.12194023776806 0.17055283084639 0.18198715628972 0.17707496009241 0.15720343397241 0.2487341206071 0.28696327307643 0.26169602692946 0.25146641939304 0.25015937799836 0.25001399434791 0.25000103919293 0.2500000669675 0.25000000382976 0.25000000017871 0.24999999996624 0.25000000000191 0.25000000000343 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636535 0.24999455000543 0.24993780796783 0.24941954422438 0.245786413518 0.22451882020512 0.17504513382132 0.10254576816587 0.04291464280344 0.02676007877624 0.02301147775004 0.02258556350674 0.02258043800671 0.02355281116104 0.03047839707345 0.04897968277799 0.07909635981128 0.12194023776816 0.17055283084646 0.18198715628972 0.1770749600924 0.15720343397241 0.24873412060709 0.2869632730764 0.26169602692946 0.25146641939305 0.25015937799836 0.25001399434791 0.25000103919293 0.2500000669675 0.25000000382976 0.25000000017871 0.24999999996624 0.25000000000191 0.25000000000343 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636535 0.24999455000543 0.24993780796783 0.24941954422438 0.245786413518 0.22451882020512 0.17504513382132 0.10254576816587 0.04291464280344 0.02676007877624 0.02301147775004 0.02258556350674 0.02258043800671 0.02355281116105 0.03047839707346 0.04897968277805 0.07909635981139 0.12194023776819 0.17055283084646 0.18198715628972 0.1770749600924 0.15720343397242 0.24873412060709 0.2869632730764 0.26169602692946 0.25146641939305 0.25015937799836 0.25001399434791 0.25000103919293 0.2500000669675 0.25000000382976 0.25000000017871 0.24999999996624 0.25000000000191 0.25000000000343 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636535 0.24999455000543 0.24993780796783 0.24941954422438 0.245786413518 0.22451882020512 0.17504513382132 0.10254576816587 0.04291464280344 0.02676007877624 0.02301147775004 0.02258556350674 0.02258043800671 0.02355281116105 0.03047839707347 0.04897968277805 0.07909635981142 0.12194023776818 0.17055283084646 0.18198715628972 0.1770749600924 0.15720343397242 0.24873412060709 0.2869632730764 0.26169602692946 0.25146641939305 0.25015937799836 0.25001399434791 0.25000103919293 0.2500000669675 0.25000000382976 0.25000000017871 0.24999999996624 0.25000000000191 0.25000000000343 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636535 0.24999455000543 0.24993780796783 0.24941954422438 0.245786413518 0.22451882020512 0.17504513382132 0.10254576816587 0.04291464280344 0.02676007877624 0.02301147775004 0.02258556350674 0.02258043800671 0.02355281116105 0.03047839707346 0.04897968277805 0.07909635981141 0.12194023776818 0.17055283084646 0.18198715628972 0.1770749600924 0.15720343397242 0.24873412060709 0.2869632730764 0.26169602692946 0.25146641939305 0.25015937799836 0.25001399434791 0.25000103919293 0.2500000669675 0.25000000382976 0.25000000017871 0.24999999996624 0.25000000000191 0.25000000000343 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636535 0.24999455000543 0.24993780796783 0.24941954422438 0.245786413518 0.22451882020512 0.17504513382132 0.10254576816587 0.04291464280344 0.02676007877624 0.02301147775004 0.02258556350674 0.02258043800671 0.02355281116105 0.03047839707346 0.04897968277805 0.07909635981141 0.12194023776818 0.17055283084646 0.18198715628972 0.1770749600924 0.15720343397242 0.24873412060709 0.2869632730764 0.26169602692946 0.25146641939305 0.25015937799836 0.25001399434791 0.25000103919293 0.2500000669675 0.25000000382976 0.25000000017871 0.24999999996624 0.25000000000191 0.25000000000343 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636535 0.24999455000543 0.24993780796783 0.24941954422438 0.245786413518 0.22451882020512 0.17504513382132 0.10254576816587 0.04291464280344 0.02676007877624 0.02301147775004 0.02258556350674 0.02258043800671 0.02355281116105 0.03047839707346 0.04897968277805 0.07909635981141 0.12194023776818 0.17055283084646 0.18198715628972 0.1770749600924 0.15720343397242 0.24873412060709 0.2869632730764 0.26169602692946 0.25146641939305 0.25015937799836 0.25001399434791 0.25000103919293 0.2500000669675 0.25000000382976 0.25000000017871 0.24999999996624 0.25000000000191 0.25000000000343 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636535 0.24999455000543 0.24993780796783 0.24941954422438 0.245786413518 0.22451882020512 0.17504513382132 0.10254576816587 0.04291464280344 0.02676007877624 0.02301147775004 0.02258556350674 0.02258043800671 0.02355281116105 0.03047839707346 0.04897968277805 0.07909635981141 0.12194023776818 0.17055283084646 0.18198715628972 0.1770749600924 0.15720343397242 0.24873412060709 0.2869632730764 0.26169602692946 0.25146641939305 0.25015937799836 0.25001399434791 0.25000103919293 0.2500000669675 0.25000000382976 0.25000000017871 0.24999999996624 0.25000000000191 0.25000000000343 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636535 0.24999455000543 0.24993780796783 0.24941954422438 0.245786413518 0.22451882020512 0.17504513382132 0.10254576816587 0.04291464280344 0.02676007877624 0.02301147775004 0.02258556350674 0.02258043800671 0.02355281116105 0.03047839707346 0.04897968277805 0.07909635981141 0.12194023776818 0.17055283084646 0.18198715628972 0.1770749600924 0.15720343397242 0.24873412060709 0.2869632730764 0.26169602692946 0.25146641939305 0.25015937799836 0.25001399434791 0.25000103919293 0.2500000669675 0.25000000382976 0.25000000017871 0.24999999996624 0.25000000000191 0.25000000000343 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636535 0.24999455000543 0.24993780796783 0.24941954422438 0.245786413518 0.22451882020512 0.17504513382132 0.10254576816587 0.04291464280344 0.02676007877624 0.02301147775004 0.02258556350674 0.02258043800671 0.02355281116105 0.03047839707346 0.04897968277805 0.07909635981141 0.12194023776818 0.17055283084646 0.18198715628972 0.1770749600924 0.15720343397242 0.24873412060709 0.2869632730764 0.26169602692946 0.25146641939305 0.25015937799836 0.25001399434791 0.25000103919293 0.2500000669675 0.25000000382976 0.25000000017871 0.24999999996624 0.25000000000191 0.25000000000343 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636535 0.24999455000543 0.24993780796783 0.24941954422438 0.245786413518 0.22451882020512 0.17504513382132 0.10254576816587 0.04291464280344 0.02676007877624 0.02301147775004 0.02258556350674 0.02258043800671 0.02355281116105 0.03047839707346 0.04897968277805 0.07909635981141 0.12194023776818 0.17055283084646 0.18198715628972 0.1770749600924 0.15720343397242 0.24873412060709 0.2869632730764 0.26169602692946 0.25146641939305 0.25015937799836 0.25001399434791 0.25000103919293 0.2500000669675 0.25000000382976 0.25000000017871 0.24999999996624 0.25000000000191 0.25000000000343 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636535 0.24999455000543 0.24993780796783 0.24941954422438 0.245786413518 0.22451882020512 0.17504513382132 0.10254576816587 0.04291464280344 0.02676007877624 0.02301147775004 0.02258556350674 0.02258043800671 0.02355281116105 0.03047839707346 0.04897968277805 0.07909635981141 0.12194023776818 0.17055283084646 0.18198715628972 0.1770749600924 0.15720343397242 0.24873412060709 0.2869632730764 0.26169602692946 0.25146641939305 0.25015937799836 0.25001399434791 0.25000103919293 0.2500000669675 0.25000000382976 0.25000000017871 0.24999999996624 0.25000000000191 0.25000000000343 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636535 0.24999455000543 0.24993780796783 0.24941954422438 0.245786413518 0.22451882020512 0.17504513382132 0.10254576816587 0.04291464280344 0.02676007877624 0.02301147775004 0.02258556350674 0.02258043800671 0.02355281116105 0.03047839707346 0.04897968277805 0.07909635981141 0.12194023776818 0.17055283084646 0.18198715628972 0.1770749600924 0.15720343397242 0.24873412060709 0.2869632730764 0.26169602692946 0.25146641939305 0.25015937799836 0.25001399434791 0.25000103919293 0.2500000669675 0.25000000382976 0.25000000017871 0.24999999996624 0.25000000000191 0.25000000000343 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636535 0.24999455000543 0.24993780796783 0.24941954422438 0.245786413518 0.22451882020512 0.17504513382132 0.10254576816587 0.04291464280344 0.02676007877624 0.02301147775004 0.02258556350674 0.02258043800671 0.02355281116105 0.03047839707346 0.04897968277805 0.07909635981141 0.12194023776819 0.17055283084646 0.18198715628972 0.1770749600924 0.15720343397242 0.24873412060709 0.2869632730764 0.26169602692946 0.25146641939305 0.25015937799836 0.25001399434791 0.25000103919293 0.2500000669675 0.25000000382976 0.25000000017871 0.24999999996624 0.25000000000191 0.25000000000343 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636535 0.24999455000543 0.24993780796783 0.24941954422438 0.245786413518 0.22451882020512 0.17504513382132 0.10254576816587 0.04291464280344 0.02676007877624 0.02301147775004 0.02258556350674 0.02258043800671 0.02355281116105 0.03047839707347 0.04897968277806 0.07909635981142 0.12194023776816 0.17055283084647 0.18198715628972 0.1770749600924 0.15720343397242 0.24873412060709 0.2869632730764 0.26169602692946 0.25146641939305 0.25015937799836 0.25001399434791 0.25000103919293 0.2500000669675 0.25000000382976 0.25000000017871 0.24999999996624 0.25000000000191 0.25000000000343 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636535 0.24999455000543 0.24993780796783 0.24941954422438 0.245786413518 0.22451882020512 0.17504513382132 0.10254576816587 0.04291464280344 0.02676007877624 0.02301147775004 0.02258556350674 0.02258043800671 0.02355281116105 0.03047839707347 0.04897968277805 0.07909635981139 0.12194023776806 0.17055283084636 0.18198715628972 0.17707496009241 0.15720343397242 0.24873412060711 0.28696327307643 0.26169602692946 0.25146641939304 0.25015937799836 0.25001399434791 0.25000103919293 0.2500000669675 0.25000000382976 0.25000000017871 0.24999999996624 0.25000000000191 0.25000000000343 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636535 0.24999455000543 0.24993780796783 0.24941954422438 0.245786413518 0.22451882020512 0.17504513382132 0.10254576816587 0.04291464280344 0.02676007877624 0.02301147775004 0.02258556350674 0.02258043800671 0.02355281116105 0.03047839707345 0.04897968277797 0.07909635981128 0.12194023776915 0.17055283084654 0.18198715628958 0.17707496009252 0.15720343397244 0.24873412060699 0.28696327307637 0.26169602692947 0.25146641939305 0.25015937799836 0.25001399434791 0.25000103919293 0.2500000669675 0.25000000382976 0.25000000017871 0.24999999996624 0.25000000000191 0.25000000000343 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636535 0.24999455000543 0.24993780796783 0.24941954422438 0.245786413518 0.22451882020512 0.17504513382132 0.10254576816587 0.04291464280344 0.02676007877624 0.02301147775004 0.02258556350674 0.02258043800671 0.02355281116105 0.03047839707347 0.04897968277823 0.07909635981222 0.12194023777003 0.17055283084864 0.18198715629002 0.17707496009203 0.15720343397243 0.24873412060698 0.28696327307604 0.26169602692935 0.25146641939306 0.25015937799836 0.25001399434791 0.25000103919293 0.2500000669675 0.25000000382976 0.25000000017871 0.24999999996624 0.25000000000191 0.25000000000343 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636535 0.24999455000543 0.24993780796783 0.24941954422438 0.245786413518 0.22451882020512 0.17504513382132 0.10254576816587 0.04291464280344 0.02676007877624 0.02301147775004 0.02258556350674 0.02258043800671 0.02355281116104 0.03047839707372 0.04897968277964 0.07909635981323 0.12194023775527 0.17055283084393 0.18198715629235 0.17707496009021 0.15720343397198 0.24873412060941 0.2869632730779 0.26169602692934 0.25146641939298 0.25015937799837 0.25001399434791 0.25000103919293 0.2500000669675 0.25000000382976 0.25000000017871 0.24999999996624 0.25000000000191 0.25000000000343 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636535 0.24999455000543 0.24993780796783 0.24941954422438 0.245786413518 0.22451882020512 0.17504513382132 0.10254576816587 0.04291464280344 0.02676007877624 0.02301147775004 0.02258556350677 0.02258043800669 0.0235528111611 0.03047839707292 0.04897968277503 0.07909635980087 0.12194023780808 0.17055283083449 0.18198715628412 0.17707496009872 0.15720343397208 0.24873412060883 0.28696327308234 0.2616960269324 0.25146641939293 0.2501593779983 0.25001399434792 0.25000103919293 0.2500000669675 0.25000000382976 0.25000000017871 0.24999999996624 0.25000000000191 0.25000000000343 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636535 0.24999455000543 0.24993780796783 0.24941954422438 0.245786413518 0.22451882020512 0.17504513382131 0.10254576816587 0.04291464280344 0.0267600787762 0.02301147775 0.02258556350675 0.02258043800675 0.02355281116097 0.03047839707157 0.04897968277663 0.07909635983941 0.12194023871402 0.17055283106822 0.18198715628687 0.17707496009397 0.15720343397976 0.24873412058289 0.28696327305538 0.26169602693137 0.25146641939552 0.25015937799825 0.25001399434786 0.25000103919294 0.2500000669675 0.25000000382976 0.25000000017871 0.24999999996624 0.25000000000191 0.25000000000343 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636535 0.24999455000543 0.24993780796783 0.24941954422438 0.245786413518 0.22451882020512 0.17504513382135 0.10254576816579 0.04291464280348 0.02676007877636 0.02301147775005 0.02258556350599 0.02258043800658 0.02355281116102 0.03047839708394 0.048979682963 0.07909636052253 0.1219402548373 0.17055283482212 0.18198715669088 0.17707495977469 0.15720343394602 0.2487341207098 0.28696327309024 0.2616960268984 0.25146641939487 0.25015937800078 0.25001399434779 0.2500010391929 0.2500000669675 0.25000000382976 0.25000000017871 0.24999999996624 0.25000000000191 0.25000000000343 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636535 0.24999455000543 0.24993780796783 0.24941954422438 0.245786413518 0.22451882020507 0.17504513382149 0.10254576816614 0.04291464280316 0.02676007877725 0.02301147775091 0.0225855635071 0.02258043800719 0.02355281115897 0.03047839711572 0.04897968597485 0.07909637211845 0.1219405124758 0.17055289445287 0.18198716302144 0.17707495493038 0.1572034331935 0.24873412211057 0.28696327405395 0.26169602709638 0.25146641936897 0.25015937800014 0.25001399434987 0.25000103919287 0.25000006696748 0.25000000382976 0.25000000017871 0.24999999996624 0.25000000000191 0.25000000000343 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636535 0.24999455000543 0.24993780796783 0.24941954422438 0.24578641351801 0.22451882020516 0.17504513382066 0.10254576816769 0.04291464280318 0.02676007877386 0.02301147774847 0.02258556351198 0.02258043800923 0.02355281099188 0.0304783962322 0.04897972603928 0.07909654570452 0.1219440587453 0.17055371405147 0.18198725823044 0.1770748817057 0.15720341741614 0.24873413798849 0.28696328862102 0.26169603051382 0.25146641960168 0.25015937797877 0.25001399435075 0.25000103919428 0.25000006696755 0.25000000382976 0.25000000017871 0.24999999996624 0.25000000000191 0.25000000000343 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636535 0.24999455000543 0.24993780796783 0.24941954422439 0.24578641351809 0.22451882020628 0.17504513382015 0.10254576815901 0.04291464280841 0.02676007878118 0.02301147775001 0.02258556342834 0.02258043789067 0.02355280655324 0.03047836538403 0.04898017240972 0.07909875564504 0.12198494038067 0.17056317194642 0.18198848367396 0.17707391877365 0.15720314744586 0.24873426759852 0.28696348650951 0.26169608466668 0.25146642347591 0.25015937824151 0.25001399433439 0.25000103919584 0.25000006696815 0.25000000382981 0.25000000017871 0.24999999996624 0.25000000000191 0.25000000000343 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636535 0.24999455000543 0.24993780796783 0.24941954422436 0.24578641351776 0.22451882020472 0.17504513384132 0.10254576815527 0.042914642775 0.02676007903083 0.02301147798641 0.02258556126703 0.02258043456743 0.02355272263155 0.03047775225452 0.04898431846663 0.07912195730133 0.12236264678738 0.17065089793965 0.18200159582682 0.17706312007272 0.1571994412005 0.24873454696117 0.28696567619018 0.26169680384032 0.25146647925477 0.2501593822551 0.25001399456839 0.25000103918732 0.25000006696792 0.25000000382986 0.25000000017872 0.24999999996624 0.25000000000191 0.25000000000343 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636535 0.24999455000543 0.24993780796781 0.24941954422419 0.24578641351794 0.22451882020603 0.17504513401711 0.10254576797525 0.04291464221414 0.02676008384057 0.02301148355318 0.02258552146488 0.02258037642982 0.02355147190307 0.03046826969619 0.04900767472146 0.07932078862139 0.12515469337358 0.17129735221374 0.1821177071434 0.17696284744377 0.15715953518144 0.24872670854273 0.28698498656592 0.26170441293486 0.25146713354174 0.2501594324924 0.2500139978694 0.25000103934002 0.25000006696587 0.25000000382913 0.25000000017868 0.24999999996625 0.25000000000191 0.25000000000343 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636535 0.24999455000543 0.24993780796783 0.24941954422484 0.24578641353875 0.22451882061406 0.17504513759201 0.10254576115543 0.04291463546013 0.02676016243657 0.02301158262355 0.02258490486527 0.02257964038416 0.02353694996583 0.03035617022177 0.04904936586964 0.08036233453287 0.13238171910142 0.17349649772843 0.18266159245192 0.17618726067254 0.15683362073734 0.24859267765731 0.28708799755228 0.2617684614083 0.25147330899953 0.25015994120902 0.25001403257611 0.25000104144976 0.2500000670816 0.25000000383308 0.25000000017875 0.24999999996625 0.25000000000191 0.25000000000343 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636535 0.24999455000545 0.24993780796813 0.24941954423287 0.24578641381896 0.2245188252106 0.17504517364117 0.10254564133688 0.04291456841505 0.02676071968442 0.02301259004152 0.02258084716131 0.02257397967226 0.02344582154213 0.02961047686602 0.04867872551469 0.081337721805 0.17684109227897 0.17786964325622 0.18602284872288 0.1727518350878 0.1545463536078 0.2474694405446 0.28713697228158 0.2620074851595 0.25150066725486 0.25016249593139 0.25001422520564 0.2500010536775 0.25000006780299 0.2500000038777 0.25000000018079 0.24999999996619 0.25000000000185 0.25000000000346 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636535 0.24999455000538 0.24993780796683 0.24941954423872 0.24578641568536 0.22451886179991 0.17504557932746 0.10254431811255 0.04291471376983 0.02676494336857 0.02302195780073 0.02254888483764 0.02255127908177 0.02289477761374 0.02453729175557 0.04014708081492 0.0806039656806 0.17381470146265 0.1822140040957 0.17445746365574 0.15808777345243 0.14438051421487 0.24015334388181 0.28549433261155 0.26255148976694 0.25158818085677 0.25017075667104 0.25001489744996 0.25000109946775 0.25000007048326 0.25000000402831 0.25000000018912 0.24999999996634 0.2500000000015 0.25000000000352 0.24999999999979 0.24999999999986 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636532 0.24999455000482 0.24993780795726 0.24941954409227 0.24578641336075 0.22451883418119 0.17504536366859 0.10254468919642 0.04291365902379 0.02675924526388 0.02302535904933 0.02255808672752 0.02250593617926 0.02266326030643 0.0232262820961 0.03060375098148 0.06882688384951 0.17165054886759 0.17286560088104 0.15644859094318 0.15299922561646 0.14115554804605 0.23290680512437 0.27889331266522 0.26006958070619 0.25128434571861 0.25014066517787 0.25001246865599 0.25000093310414 0.25000006050462 0.25000000349163 0.25000000016476 0.24999999996679 0.2500000000022 0.25000000000327 0.24999999999976 0.24999999999988 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409288 0.24999959636521 0.24999455000279 0.24993780792565 0.24941954366531 0.24578640798965 0.22451877449029 0.17504533014258 0.10254491847989 0.04291339117372 0.02675376658879 0.02302936486975 0.0225538511482 0.02251767874297 0.02251087975836 0.0225490558838 0.02327347608134 0.05035517600038 0.18055984486024 0.24953167009488 0.26891121696206 0.23756683948766 0.23270325515651 0.26063316342068 0.26223529277413 0.25330321172956 0.25041500448807 0.25004530212903 0.25000403663062 0.25000030489015 0.25000001998456 0.2500000011298 0.25000000002454 0.24999999998031 0.25000000000565 0.25000000000128 0.24999999999966 0.24999999999998 0.25000000000002 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636529 0.2499945500043 0.24993780794877 0.24941954396055 0.24578641113309 0.22451880410574 0.17504526730014 0.10254501044335 0.04291353561054 0.02675499896086 0.02302708807961 0.02255563193197 0.02254560947446 0.02258632831236 0.02282892791406 0.02258372043984 0.05602616191664 0.19 0.25150064756164 0.25360859309762 0.25778526825266 0.26143847044409 0.26168815549714 0.25459756405541 0.2510652567836 0.25012693848997 0.25001305803327 0.25000113008556 0.25000008415464 0.25000000547674 0.25000000028449 0.24999999996271 0.24999999999818 0.250000000005 0.24999999999995 0.24999999999976 0.25000000000003 0.25000000000001 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636537 0.2499945500058 0.24993780797315 0.24941954432061 0.24578641682832 0.22451887814885 0.17504551751981 0.1025441956673 0.04291424349001 0.02676314328288 0.02302528401925 0.02254859142523 0.0225461312361 0.02291892992748 0.02635068309367 0.03451089332715 0.0225 +D/cons.2.00.000050.dat 0.19 0.2552208436096 0.25452999304654 0.26263009638661 0.24380638426214 0.2631715684653 0.25713253374367 0.25141241936026 0.25018475874456 0.2500197954756 0.25000174625902 0.25000013072532 0.25000000848295 0.25000000045608 0.24999999997526 0.24999999999258 0.25000000000554 0.2500000000003 0.24999999999971 0.25000000000002 0.25000000000001 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.2499995963654 0.24999455000644 0.24993780798379 0.24941954446554 0.24578641836326 0.224518891862 0.1750454792715 0.10254428276082 0.04291411692753 0.02676299736433 0.02302504636431 0.02254912078853 0.02254602010636 0.02288204989281 0.02635681697677 0.03423352975896 0.0225 0.1805572859672 0.24944197324291 0.26773402720492 0.23823522342245 0.23491514696768 0.26504798523279 0.2629962334623 0.25342837514063 0.2504365967241 0.25004828865626 0.25000433922054 0.25000032929838 0.2500000215542 0.25000000121351 0.25000000002965 0.24999999997911 0.25000000000566 0.25000000000139 0.24999999999965 0.24999999999998 0.25000000000002 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636542 0.24999455000673 0.24993780798783 0.24941954448248 0.2457864168858 0.22451886131485 0.17504518499227 0.10254515853762 0.04291340824477 0.02675636752571 0.02302484690138 0.02255601731127 0.0225425149927 0.0225875680626 0.0228277369542 0.02258293079796 0.05602070548185 0.17163367047563 0.17280749890114 0.15594562976503 0.15098234950374 0.1379973218688 0.23354511856216 0.27826989460349 0.26021212375348 0.2512992867511 0.25014082750364 0.25001240998114 0.25000092451259 0.25000005976847 0.25000000344564 0.25000000016179 0.24999999996681 0.25000000000232 0.25000000000325 0.24999999999976 0.24999999999988 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.2499999740929 0.24999959636548 0.24999455000797 0.24993780800832 0.24941954477016 0.24578642045433 0.2245189005626 0.17504509105882 0.10254515559642 0.04291312866481 0.02675810400578 0.02302143970173 0.02255587746577 0.02249838539866 0.02250245924702 0.0225466770159 0.02326792705623 0.05034450078984 0.17373282563648 0.18212264995216 0.17427767458393 0.15709443746136 0.14232604615753 0.23842973683663 0.28428598668229 0.26236866393965 0.25157458132993 0.25016948929534 0.25001480775463 0.250001093803 0.25000007016325 0.25000000401122 0.25000000018836 0.24999999996635 0.25000000000152 0.25000000000352 0.24999999999978 0.24999999999986 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636539 0.24999455000625 0.24993780798096 0.24941954442242 0.24578641740381 0.22451887731014 0.17504533193229 0.10254463916733 0.04291349638867 0.02676037441037 0.02302420862686 0.02255615100613 0.02249735655551 0.02265267041772 0.02320873806533 0.03058177165107 0.06878241217105 0.17672593328875 0.1777486788669 0.18582227162687 0.17256193894377 0.15402415014781 0.24681389055537 0.28691490809582 0.26198225944108 0.25149907887133 0.25016237374022 0.25001421694 0.2500010531317 0.25000006776889 0.25000000387605 0.25000000018074 0.24999999996619 0.25000000000185 0.25000000000345 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636536 0.24999455000559 0.24993780796994 0.24941954427912 0.24578641627858 0.22451886970988 0.17504558994498 0.10254420461609 0.04291455751773 0.02676460535281 0.02302294283358 0.02254674238107 0.02254881145916 0.02287782027125 0.02450858955138 0.04011108594757 0.08054264541941 0.13232534466556 0.17339123025241 0.1825647516134 0.17605924908538 0.15675171113725 0.24849786480597 0.28705651250704 0.26177135908704 0.25147380260584 0.25015998990809 0.25001403603411 0.25000104164172 0.25000006709255 0.25000000383375 0.25000000017878 0.24999999996625 0.25000000000191 0.25000000000343 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636535 0.24999455000546 0.24993780796832 0.24941954423531 0.24578641391607 0.22451882743485 0.17504517866077 0.10254560761555 0.04291451066098 0.02676063667611 0.02301262470689 0.02258000209657 0.02257239445827 0.02343327191813 0.02958845023307 0.04863518558331 0.08127545109449 0.12507472555109 0.17121441463878 0.18209537827551 0.17693678968583 0.15714816124178 0.2487138021526 0.28698597918238 0.26170576882037 0.2514672749311 0.25015944379431 0.25001399859255 0.25000103937888 0.2500000669682 0.25000000382922 0.25000000017868 0.24999999996625 0.25000000000191 0.25000000000343 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636535 0.24999455000544 0.24993780796792 0.24941954422586 0.24578641354998 0.22451882082658 0.17504513732694 0.10254575740388 0.04291462414961 0.02676016191968 0.02301158832787 0.02258470688751 0.02257926125709 0.02353322347426 0.03034582200371 0.04901493160242 0.08031463657436 0.12234650379249 0.17063719639159 0.18199851712886 0.1770595627048 0.15719796849352 0.24873300503761 0.28696581933089 0.2616970008627 0.25146649761311 0.25015938361589 0.25001399464983 0.25000103919179 0.25000006696793 0.25000000382985 0.25000000017872 0.24999999996624 0.25000000000191 0.25000000000343 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636535 0.24999455000543 0.24993780796784 0.24941954422455 0.24578641352233 0.22451882023588 0.1750451340501 0.1025457676675 0.04291464075071 0.0267600838973 0.0230114851081 0.02258550201583 0.02258032349655 0.02355093837281 0.03046620244114 0.0489990958989 0.07930800368037 0.12198247709188 0.17056142480975 0.18198814538627 0.17707355966448 0.15720298906388 0.24873410535828 0.28696351136976 0.26169610586386 0.25146642525927 0.25015937836472 0.25001399433955 0.25000103919564 0.25000006696811 0.25000000382981 0.25000000017871 0.24999999996624 0.25000000000191 0.25000000000343 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636535 0.24999455000543 0.24993780796783 0.24941954422438 0.24578641351812 0.22451882020687 0.17504513385657 0.10254576813931 0.04291464263544 0.02676007904437 0.02301147819921 0.02258555963099 0.02258042894761 0.02355266301382 0.03047744995002 0.04898277581396 0.07912014127225 0.12194377886622 0.17055354085081 0.1819872284631 0.17707485303707 0.15720340335229 0.24873412493506 0.28696329126192 0.26169603231337 0.25146641974277 0.25015937798509 0.25001399435005 0.25000103919429 0.25000006696756 0.25000000382976 0.25000000017871 0.24999999996624 0.25000000000191 0.25000000000343 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636535 0.24999455000543 0.24993780796783 0.24941954422439 0.24578641351806 0.22451882020674 0.1750451338239 0.10254576815553 0.04291464280213 0.02676007878023 0.0230114777665 0.02258556331515 0.02258043741576 0.02355280126401 0.03047833468126 0.04898002910857 0.07909854688397 0.12194048728163 0.1705528802863 0.18198716084339 0.17707495305635 0.15720343212773 0.2487341212037 0.2869632742629 0.2616960272299 0.25146641937494 0.25015937799846 0.25001399435006 0.25000103919291 0.25000006696748 0.25000000382976 0.25000000017871 0.24999999996624 0.25000000000191 0.25000000000343 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636535 0.24999455000543 0.24993780796783 0.24941954422438 0.24578641351803 0.22451882020535 0.17504513381888 0.10254576816752 0.04291464280679 0.02676007877257 0.023011477748 0.02258556350781 0.02258043798798 0.02355281059834 0.03047839353434 0.04897971296489 0.07909652642722 0.12194025295823 0.17055283383656 0.18198715655322 0.17707495967393 0.1572034338691 0.24873412062037 0.28696327311005 0.26169602690233 0.2514664193924 0.25015937800117 0.25001399434786 0.2500010391929 0.2500000669675 0.25000000382976 0.25000000017871 0.24999999996624 0.25000000000191 0.25000000000343 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636535 0.24999455000543 0.24993780796783 0.24941954422438 0.245786413518 0.22451882020511 0.17504513382143 0.10254576816657 0.04291464280208 0.02676007877712 0.0230114777512 0.02258556350821 0.02258043801028 0.02355281114545 0.03047839692068 0.0489796849593 0.07909637064281 0.12194023859271 0.17055283100678 0.18198715627943 0.17707496008764 0.1572034339911 0.24873412059431 0.28696327305227 0.26169602692743 0.25146641939607 0.25015937799835 0.25001399434786 0.25000103919294 0.2500000669675 0.25000000382976 0.25000000017871 0.24999999996624 0.25000000000191 0.25000000000343 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636535 0.24999455000543 0.24993780796783 0.24941954422438 0.245786413518 0.22451882020511 0.17504513382144 0.10254576816576 0.04291464280321 0.0267600787765 0.02301147775025 0.02258556350551 0.02258043800529 0.02355281116362 0.03047839707334 0.04897968289944 0.07909636042514 0.12194023780039 0.17055283083201 0.18198715628678 0.17707496010008 0.1572034339725 0.24873412061063 0.28696327308179 0.26169602693315 0.25146641939306 0.25015937799828 0.25001399434792 0.25000103919293 0.2500000669675 0.25000000382976 0.25000000017871 0.24999999996624 0.25000000000191 0.25000000000343 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636535 0.24999455000543 0.24993780796783 0.24941954422438 0.245786413518 0.22451882020512 0.17504513382131 0.10254576816584 0.04291464280351 0.0267600787762 0.02301147774997 0.02258556350667 0.02258043800632 0.02355281115957 0.03047839707425 0.04897968277325 0.07909635983307 0.12194023775634 0.17055283084528 0.18198715629178 0.17707496009004 0.15720343397058 0.24873412060813 0.28696327307817 0.26169602692954 0.25146641939295 0.25015937799837 0.25001399434791 0.25000103919293 0.2500000669675 0.25000000382976 0.25000000017871 0.24999999996624 0.25000000000191 0.25000000000343 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636535 0.24999455000543 0.24993780796783 0.24941954422438 0.245786413518 0.22451882020512 0.17504513382132 0.10254576816588 0.04291464280344 0.02676007877623 0.02301147775003 0.0225855635068 0.02258043800679 0.02355281116083 0.03047839707247 0.04897968277625 0.07909635980175 0.1219402377701 0.17055283084825 0.18198715628985 0.17707496009194 0.15720343397246 0.24873412060691 0.28696327307607 0.26169602692931 0.25146641939306 0.25015937799836 0.25001399434791 0.25000103919293 0.2500000669675 0.25000000382976 0.25000000017871 0.24999999996624 0.25000000000191 0.25000000000343 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636535 0.24999455000543 0.24993780796783 0.24941954422438 0.245786413518 0.22451882020512 0.17504513382133 0.10254576816587 0.04291464280344 0.02676007877624 0.02301147775004 0.02258556350674 0.02258043800671 0.02355281116113 0.03047839707351 0.04897968277934 0.07909635981337 0.12194023776903 0.17055283084649 0.18198715628963 0.17707496009254 0.1572034339725 0.24873412060706 0.28696327307636 0.26169602692947 0.25146641939305 0.25015937799836 0.25001399434791 0.25000103919293 0.2500000669675 0.25000000382976 0.25000000017871 0.24999999996624 0.25000000000191 0.25000000000343 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636535 0.24999455000543 0.24993780796783 0.24941954422438 0.245786413518 0.22451882020512 0.17504513382132 0.10254576816587 0.04291464280344 0.02676007877624 0.02301147775004 0.02258556350674 0.0225804380067 0.02355281116105 0.03047839707351 0.04897968277817 0.0790963598121 0.12194023776806 0.17055283084639 0.18198715628972 0.17707496009241 0.15720343397241 0.2487341206071 0.28696327307643 0.26169602692946 0.25146641939304 0.25015937799836 0.25001399434791 0.25000103919293 0.2500000669675 0.25000000382976 0.25000000017871 0.24999999996624 0.25000000000191 0.25000000000343 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636535 0.24999455000543 0.24993780796783 0.24941954422438 0.245786413518 0.22451882020512 0.17504513382132 0.10254576816587 0.04291464280344 0.02676007877624 0.02301147775004 0.02258556350674 0.02258043800671 0.02355281116104 0.03047839707345 0.04897968277799 0.07909635981128 0.12194023776816 0.17055283084646 0.18198715628972 0.1770749600924 0.15720343397241 0.24873412060709 0.2869632730764 0.26169602692946 0.25146641939305 0.25015937799836 0.25001399434791 0.25000103919293 0.2500000669675 0.25000000382976 0.25000000017871 0.24999999996624 0.25000000000191 0.25000000000343 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636535 0.24999455000543 0.24993780796783 0.24941954422438 0.245786413518 0.22451882020512 0.17504513382132 0.10254576816587 0.04291464280344 0.02676007877624 0.02301147775004 0.02258556350674 0.02258043800671 0.02355281116105 0.03047839707346 0.04897968277805 0.07909635981139 0.12194023776819 0.17055283084646 0.18198715628972 0.1770749600924 0.15720343397242 0.24873412060709 0.2869632730764 0.26169602692946 0.25146641939305 0.25015937799836 0.25001399434791 0.25000103919293 0.2500000669675 0.25000000382976 0.25000000017871 0.24999999996624 0.25000000000191 0.25000000000343 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636535 0.24999455000543 0.24993780796783 0.24941954422438 0.245786413518 0.22451882020512 0.17504513382132 0.10254576816587 0.04291464280344 0.02676007877624 0.02301147775004 0.02258556350674 0.02258043800671 0.02355281116105 0.03047839707347 0.04897968277805 0.07909635981142 0.12194023776818 0.17055283084646 0.18198715628972 0.1770749600924 0.15720343397242 0.24873412060709 0.2869632730764 0.26169602692946 0.25146641939305 0.25015937799836 0.25001399434791 0.25000103919293 0.2500000669675 0.25000000382976 0.25000000017871 0.24999999996624 0.25000000000191 0.25000000000343 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636535 0.24999455000543 0.24993780796783 0.24941954422438 0.245786413518 0.22451882020512 0.17504513382132 0.10254576816587 0.04291464280344 0.02676007877624 0.02301147775004 0.02258556350674 0.02258043800671 0.02355281116105 0.03047839707346 0.04897968277805 0.07909635981141 0.12194023776818 0.17055283084646 0.18198715628972 0.1770749600924 0.15720343397242 0.24873412060709 0.2869632730764 0.26169602692946 0.25146641939305 0.25015937799836 0.25001399434791 0.25000103919293 0.2500000669675 0.25000000382976 0.25000000017871 0.24999999996624 0.25000000000191 0.25000000000343 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636535 0.24999455000543 0.24993780796783 0.24941954422438 0.245786413518 0.22451882020512 0.17504513382132 0.10254576816587 0.04291464280344 0.02676007877624 0.02301147775004 0.02258556350674 0.02258043800671 0.02355281116105 0.03047839707346 0.04897968277805 0.07909635981141 0.12194023776818 0.17055283084646 0.18198715628972 0.1770749600924 0.15720343397242 0.24873412060709 0.2869632730764 0.26169602692946 0.25146641939305 0.25015937799836 0.25001399434791 0.25000103919293 0.2500000669675 0.25000000382976 0.25000000017871 0.24999999996624 0.25000000000191 0.25000000000343 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636535 0.24999455000543 0.24993780796783 0.24941954422438 0.245786413518 0.22451882020512 0.17504513382132 0.10254576816587 0.04291464280344 0.02676007877624 0.02301147775004 0.02258556350674 0.02258043800671 0.02355281116105 0.03047839707346 0.04897968277805 0.07909635981141 0.12194023776818 0.17055283084646 0.18198715628972 0.1770749600924 0.15720343397242 0.24873412060709 0.2869632730764 0.26169602692946 0.25146641939305 0.25015937799836 0.25001399434791 0.25000103919293 0.2500000669675 0.25000000382976 0.25000000017871 0.24999999996624 0.25000000000191 0.25000000000343 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636535 0.24999455000543 0.24993780796783 0.24941954422438 0.245786413518 0.22451882020512 0.17504513382132 0.10254576816587 0.04291464280344 0.02676007877624 0.02301147775004 0.02258556350674 0.02258043800671 0.02355281116105 0.03047839707346 0.04897968277805 0.07909635981141 0.12194023776818 0.17055283084646 0.18198715628972 0.1770749600924 0.15720343397242 0.24873412060709 0.2869632730764 0.26169602692946 0.25146641939305 0.25015937799836 0.25001399434791 0.25000103919293 0.2500000669675 0.25000000382976 0.25000000017871 0.24999999996624 0.25000000000191 0.25000000000343 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636535 0.24999455000543 0.24993780796783 0.24941954422438 0.245786413518 0.22451882020512 0.17504513382132 0.10254576816587 0.04291464280344 0.02676007877624 0.02301147775004 0.02258556350674 0.02258043800671 0.02355281116105 0.03047839707346 0.04897968277805 0.07909635981141 0.12194023776818 0.17055283084646 0.18198715628972 0.1770749600924 0.15720343397242 0.24873412060709 0.2869632730764 0.26169602692946 0.25146641939305 0.25015937799836 0.25001399434791 0.25000103919293 0.2500000669675 0.25000000382976 0.25000000017871 0.24999999996624 0.25000000000191 0.25000000000343 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636535 0.24999455000543 0.24993780796783 0.24941954422438 0.245786413518 0.22451882020512 0.17504513382132 0.10254576816587 0.04291464280344 0.02676007877624 0.02301147775004 0.02258556350674 0.02258043800671 0.02355281116105 0.03047839707346 0.04897968277805 0.07909635981141 0.12194023776818 0.17055283084646 0.18198715628972 0.1770749600924 0.15720343397242 0.24873412060709 0.2869632730764 0.26169602692946 0.25146641939305 0.25015937799836 0.25001399434791 0.25000103919293 0.2500000669675 0.25000000382976 0.25000000017871 0.24999999996624 0.25000000000191 0.25000000000343 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636535 0.24999455000543 0.24993780796783 0.24941954422438 0.245786413518 0.22451882020512 0.17504513382132 0.10254576816587 0.04291464280344 0.02676007877624 0.02301147775004 0.02258556350674 0.02258043800671 0.02355281116105 0.03047839707346 0.04897968277805 0.07909635981141 0.12194023776818 0.17055283084646 0.18198715628972 0.1770749600924 0.15720343397242 0.24873412060709 0.2869632730764 0.26169602692946 0.25146641939305 0.25015937799836 0.25001399434791 0.25000103919293 0.2500000669675 0.25000000382976 0.25000000017871 0.24999999996624 0.25000000000191 0.25000000000343 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636535 0.24999455000543 0.24993780796783 0.24941954422438 0.245786413518 0.22451882020512 0.17504513382132 0.10254576816587 0.04291464280344 0.02676007877624 0.02301147775004 0.02258556350674 0.02258043800671 0.02355281116105 0.03047839707346 0.04897968277805 0.07909635981141 0.12194023776818 0.17055283084646 0.18198715628972 0.1770749600924 0.15720343397242 0.24873412060709 0.2869632730764 0.26169602692946 0.25146641939305 0.25015937799836 0.25001399434791 0.25000103919293 0.2500000669675 0.25000000382976 0.25000000017871 0.24999999996624 0.25000000000191 0.25000000000343 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636535 0.24999455000543 0.24993780796783 0.24941954422438 0.245786413518 0.22451882020512 0.17504513382132 0.10254576816587 0.04291464280344 0.02676007877624 0.02301147775004 0.02258556350674 0.02258043800671 0.02355281116105 0.03047839707346 0.04897968277805 0.07909635981141 0.12194023776818 0.17055283084646 0.18198715628972 0.1770749600924 0.15720343397242 0.24873412060709 0.2869632730764 0.26169602692946 0.25146641939305 0.25015937799836 0.25001399434791 0.25000103919293 0.2500000669675 0.25000000382976 0.25000000017871 0.24999999996624 0.25000000000191 0.25000000000343 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636535 0.24999455000543 0.24993780796783 0.24941954422438 0.245786413518 0.22451882020512 0.17504513382132 0.10254576816587 0.04291464280344 0.02676007877624 0.02301147775004 0.02258556350674 0.02258043800671 0.02355281116105 0.03047839707346 0.04897968277805 0.07909635981141 0.12194023776819 0.17055283084646 0.18198715628972 0.1770749600924 0.15720343397242 0.24873412060709 0.2869632730764 0.26169602692946 0.25146641939305 0.25015937799836 0.25001399434791 0.25000103919293 0.2500000669675 0.25000000382976 0.25000000017871 0.24999999996624 0.25000000000191 0.25000000000343 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636535 0.24999455000543 0.24993780796783 0.24941954422438 0.245786413518 0.22451882020512 0.17504513382132 0.10254576816587 0.04291464280344 0.02676007877624 0.02301147775004 0.02258556350674 0.02258043800671 0.02355281116105 0.03047839707347 0.04897968277806 0.07909635981142 0.12194023776816 0.17055283084647 0.18198715628972 0.1770749600924 0.15720343397242 0.24873412060709 0.2869632730764 0.26169602692946 0.25146641939305 0.25015937799836 0.25001399434791 0.25000103919293 0.2500000669675 0.25000000382976 0.25000000017871 0.24999999996624 0.25000000000191 0.25000000000343 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636535 0.24999455000543 0.24993780796783 0.24941954422438 0.245786413518 0.22451882020512 0.17504513382132 0.10254576816587 0.04291464280344 0.02676007877624 0.02301147775004 0.02258556350674 0.02258043800671 0.02355281116105 0.03047839707347 0.04897968277805 0.07909635981139 0.12194023776806 0.17055283084636 0.18198715628972 0.17707496009241 0.15720343397242 0.24873412060711 0.28696327307643 0.26169602692946 0.25146641939304 0.25015937799836 0.25001399434791 0.25000103919293 0.2500000669675 0.25000000382976 0.25000000017871 0.24999999996624 0.25000000000191 0.25000000000343 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636535 0.24999455000543 0.24993780796783 0.24941954422438 0.245786413518 0.22451882020512 0.17504513382132 0.10254576816587 0.04291464280344 0.02676007877624 0.02301147775004 0.02258556350674 0.02258043800671 0.02355281116105 0.03047839707345 0.04897968277797 0.07909635981128 0.12194023776915 0.17055283084654 0.18198715628958 0.17707496009252 0.15720343397244 0.24873412060699 0.28696327307637 0.26169602692947 0.25146641939305 0.25015937799836 0.25001399434791 0.25000103919293 0.2500000669675 0.25000000382976 0.25000000017871 0.24999999996624 0.25000000000191 0.25000000000343 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636535 0.24999455000543 0.24993780796783 0.24941954422438 0.245786413518 0.22451882020512 0.17504513382132 0.10254576816587 0.04291464280344 0.02676007877624 0.02301147775004 0.02258556350674 0.02258043800671 0.02355281116105 0.03047839707347 0.04897968277823 0.07909635981222 0.12194023777003 0.17055283084864 0.18198715629002 0.17707496009203 0.15720343397243 0.24873412060698 0.28696327307604 0.26169602692935 0.25146641939306 0.25015937799836 0.25001399434791 0.25000103919293 0.2500000669675 0.25000000382976 0.25000000017871 0.24999999996624 0.25000000000191 0.25000000000343 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636535 0.24999455000543 0.24993780796783 0.24941954422438 0.245786413518 0.22451882020512 0.17504513382132 0.10254576816587 0.04291464280344 0.02676007877624 0.02301147775004 0.02258556350674 0.02258043800671 0.02355281116104 0.03047839707372 0.04897968277964 0.07909635981323 0.12194023775527 0.17055283084393 0.18198715629235 0.17707496009021 0.15720343397198 0.24873412060941 0.2869632730779 0.26169602692934 0.25146641939298 0.25015937799837 0.25001399434791 0.25000103919293 0.2500000669675 0.25000000382976 0.25000000017871 0.24999999996624 0.25000000000191 0.25000000000343 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636535 0.24999455000543 0.24993780796783 0.24941954422438 0.245786413518 0.22451882020512 0.17504513382132 0.10254576816587 0.04291464280344 0.02676007877624 0.02301147775004 0.02258556350677 0.02258043800669 0.0235528111611 0.03047839707292 0.04897968277503 0.07909635980087 0.12194023780808 0.17055283083449 0.18198715628412 0.17707496009872 0.15720343397208 0.24873412060883 0.28696327308234 0.2616960269324 0.25146641939293 0.2501593779983 0.25001399434792 0.25000103919293 0.2500000669675 0.25000000382976 0.25000000017871 0.24999999996624 0.25000000000191 0.25000000000343 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636535 0.24999455000543 0.24993780796783 0.24941954422438 0.245786413518 0.22451882020512 0.17504513382131 0.10254576816587 0.04291464280344 0.0267600787762 0.02301147775 0.02258556350675 0.02258043800675 0.02355281116097 0.03047839707157 0.04897968277663 0.07909635983941 0.12194023871402 0.17055283106822 0.18198715628687 0.17707496009397 0.15720343397976 0.24873412058289 0.28696327305538 0.26169602693137 0.25146641939552 0.25015937799825 0.25001399434786 0.25000103919294 0.2500000669675 0.25000000382976 0.25000000017871 0.24999999996624 0.25000000000191 0.25000000000343 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636535 0.24999455000543 0.24993780796783 0.24941954422438 0.245786413518 0.22451882020512 0.17504513382135 0.10254576816579 0.04291464280348 0.02676007877636 0.02301147775005 0.02258556350599 0.02258043800658 0.02355281116102 0.03047839708394 0.048979682963 0.07909636052253 0.1219402548373 0.17055283482212 0.18198715669088 0.17707495977469 0.15720343394602 0.2487341207098 0.28696327309024 0.2616960268984 0.25146641939487 0.25015937800078 0.25001399434779 0.2500010391929 0.2500000669675 0.25000000382976 0.25000000017871 0.24999999996624 0.25000000000191 0.25000000000343 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636535 0.24999455000543 0.24993780796783 0.24941954422438 0.245786413518 0.22451882020507 0.17504513382149 0.10254576816614 0.04291464280316 0.02676007877725 0.02301147775091 0.0225855635071 0.02258043800719 0.02355281115897 0.03047839711572 0.04897968597485 0.07909637211845 0.1219405124758 0.17055289445287 0.18198716302144 0.17707495493038 0.1572034331935 0.24873412211057 0.28696327405395 0.26169602709638 0.25146641936897 0.25015937800014 0.25001399434987 0.25000103919287 0.25000006696748 0.25000000382976 0.25000000017871 0.24999999996624 0.25000000000191 0.25000000000343 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636535 0.24999455000543 0.24993780796783 0.24941954422438 0.24578641351801 0.22451882020515 0.17504513382066 0.10254576816769 0.04291464280318 0.02676007877386 0.02301147774847 0.02258556351198 0.02258043800923 0.02355281099188 0.0304783962322 0.04897972603928 0.07909654570452 0.1219440587453 0.17055371405147 0.18198725823044 0.1770748817057 0.15720341741614 0.24873413798849 0.28696328862102 0.26169603051382 0.25146641960168 0.25015937797877 0.25001399435075 0.25000103919428 0.25000006696755 0.25000000382976 0.25000000017871 0.24999999996624 0.25000000000191 0.25000000000343 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636535 0.24999455000543 0.24993780796783 0.24941954422439 0.24578641351809 0.22451882020628 0.17504513382015 0.10254576815901 0.04291464280841 0.02676007878118 0.02301147775001 0.02258556342834 0.02258043789067 0.02355280655324 0.03047836538403 0.04898017240972 0.07909875564504 0.12198494038067 0.17056317194642 0.18198848367396 0.17707391877365 0.15720314744586 0.24873426759852 0.28696348650951 0.26169608466668 0.25146642347591 0.25015937824151 0.25001399433439 0.25000103919584 0.25000006696815 0.25000000382981 0.25000000017871 0.24999999996624 0.25000000000191 0.25000000000343 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636535 0.24999455000543 0.24993780796783 0.24941954422436 0.24578641351776 0.22451882020472 0.17504513384132 0.10254576815527 0.042914642775 0.02676007903083 0.02301147798641 0.02258556126703 0.02258043456743 0.02355272263155 0.03047775225452 0.04898431846663 0.07912195730133 0.12236264678738 0.17065089793965 0.18200159582682 0.17706312007272 0.1571994412005 0.24873454696117 0.28696567619018 0.26169680384032 0.25146647925477 0.2501593822551 0.25001399456839 0.25000103918732 0.25000006696792 0.25000000382986 0.25000000017872 0.24999999996624 0.25000000000191 0.25000000000343 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636535 0.24999455000543 0.24993780796781 0.24941954422419 0.24578641351794 0.22451882020603 0.17504513401711 0.10254576797525 0.04291464221414 0.02676008384057 0.02301148355318 0.02258552146488 0.02258037642982 0.02355147190307 0.03046826969618 0.04900767472146 0.07932078862139 0.12515469337358 0.17129735221374 0.1821177071434 0.17696284744377 0.15715953518144 0.24872670854273 0.28698498656592 0.26170441293486 0.25146713354174 0.2501594324924 0.2500139978694 0.25000103934002 0.25000006696587 0.25000000382913 0.25000000017868 0.24999999996625 0.25000000000191 0.25000000000343 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636535 0.24999455000543 0.24993780796783 0.24941954422484 0.24578641353875 0.22451882061406 0.17504513759201 0.10254576115543 0.04291463546013 0.02676016243657 0.02301158262355 0.02258490486527 0.02257964038416 0.02353694996583 0.03035617022177 0.04904936586964 0.08036233453287 0.13238171910142 0.17349649772843 0.18266159245192 0.17618726067254 0.15683362073734 0.24859267765731 0.28708799755228 0.2617684614083 0.25147330899953 0.25015994120902 0.25001403257611 0.25000104144976 0.2500000670816 0.25000000383308 0.25000000017875 0.24999999996625 0.25000000000191 0.25000000000343 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636535 0.24999455000545 0.24993780796813 0.24941954423287 0.24578641381896 0.2245188252106 0.17504517364117 0.10254564133688 0.04291456841505 0.02676071968442 0.02301259004152 0.02258084716131 0.02257397967226 0.02344582154213 0.02961047686602 0.04867872551469 0.081337721805 0.17684109227897 0.17786964325622 0.18602284872288 0.1727518350878 0.1545463536078 0.2474694405446 0.28713697228158 0.2620074851595 0.25150066725486 0.25016249593139 0.25001422520564 0.2500010536775 0.25000006780299 0.2500000038777 0.25000000018079 0.24999999996619 0.25000000000185 0.25000000000345 0.24999999999977 0.24999999999987 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636535 0.24999455000538 0.24993780796683 0.24941954423872 0.24578641568536 0.22451886179991 0.17504557932746 0.10254431811255 0.04291471376983 0.02676494336857 0.02302195780073 0.02254888483764 0.02255127908177 0.02289477761374 0.02453729175557 0.04014708081492 0.0806039656806 0.17381470146265 0.1822140040957 0.17445746365574 0.15808777345243 0.14438051421487 0.24015334388181 0.28549433261155 0.26255148976694 0.25158818085677 0.25017075667104 0.25001489744996 0.25000109946775 0.25000007048326 0.25000000402831 0.25000000018912 0.24999999996634 0.2500000000015 0.25000000000352 0.24999999999979 0.24999999999986 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636532 0.24999455000482 0.24993780795726 0.24941954409227 0.24578641336075 0.22451883418119 0.17504536366859 0.10254468919642 0.04291365902379 0.02675924526388 0.02302535904933 0.02255808672752 0.02250593617926 0.02266326030643 0.0232262820961 0.03060375098148 0.06882688384951 0.17165054886759 0.17286560088104 0.15644859094318 0.15299922561646 0.14115554804605 0.23290680512437 0.27889331266522 0.26006958070619 0.25128434571861 0.25014066517787 0.25001246865599 0.25000093310414 0.25000006050462 0.25000000349163 0.25000000016476 0.24999999996679 0.2500000000022 0.25000000000327 0.24999999999976 0.24999999999988 0.25000000000003 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409288 0.24999959636521 0.24999455000279 0.24993780792565 0.24941954366531 0.24578640798965 0.22451877449029 0.17504533014258 0.10254491847989 0.04291339117372 0.02675376658879 0.02302936486975 0.0225538511482 0.02251767874297 0.02251087975836 0.0225490558838 0.02327347608134 0.05035517600038 0.18055984486024 0.24953167009488 0.26891121696206 0.23756683948766 0.23270325515651 0.26063316342068 0.26223529277413 0.25330321172956 0.25041500448807 0.25004530212903 0.25000403663062 0.25000030489015 0.25000001998456 0.2500000011298 0.25000000002454 0.24999999998031 0.25000000000565 0.25000000000128 0.24999999999966 0.24999999999998 0.25000000000002 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636529 0.2499945500043 0.24993780794877 0.24941954396055 0.24578641113309 0.22451880410574 0.17504526730014 0.10254501044335 0.04291353561054 0.02675499896086 0.02302708807961 0.02255563193197 0.02254560947446 0.02258632831236 0.02282892791406 0.02258372043984 0.05602616191664 0.19 0.25150064756164 0.25360859309762 0.25778526825266 0.26143847044409 0.26168815549714 0.25459756405541 0.2510652567836 0.25012693848997 0.25001305803327 0.25000113008556 0.25000008415464 0.25000000547674 0.25000000028449 0.24999999996271 0.24999999999818 0.250000000005 0.24999999999995 0.24999999999976 0.25000000000003 0.25000000000001 0.25 0.25 0.25 0.24999999999997 0.25000000000004 0.25000000000036 0.2499999999983 0.24999999999446 0.25000000002412 0.24999999995383 0.249999998534 0.24999997409289 0.24999959636537 0.2499945500058 0.24993780797315 0.24941954432061 0.24578641682832 0.22451887814885 0.17504551751981 0.1025441956673 0.04291424349001 0.02676314328288 0.02302528401925 0.02254859142523 0.0225461312361 0.02291892992748 0.02635068309367 0.03451089332715 0.0225 D/cons.3.00.000000.dat 0.001 0.001 0.001 0.001 0.001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.001 0.001 0.001 0.001 0.001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.001 0.001 0.001 0.001 0.001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.001 0.001 0.001 0.001 0.001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.001 0.001 0.001 0.001 0.001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.001 0.001 0.001 0.001 0.001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.001 0.001 0.001 0.001 0.001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.001 0.001 0.001 0.001 0.001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.001 0.001 0.001 0.001 0.001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.001 0.001 0.001 0.001 0.001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.001 0.001 0.001 0.001 0.001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.001 0.001 0.001 0.001 0.001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.001 0.001 0.001 0.001 0.001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.001 0.001 0.001 0.001 0.001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.001 0.001 0.001 0.001 0.001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.001 0.001 0.001 0.001 0.001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.001 0.001 0.001 0.001 0.001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.001 0.001 0.001 0.001 0.001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.001 0.001 0.001 0.001 0.001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.001 0.001 0.001 0.001 0.001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.001 0.001 0.001 0.001 0.001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.001 0.001 0.001 0.001 0.001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.001 0.001 0.001 0.001 0.001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.001 0.001 0.001 0.001 0.001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.001 0.001 0.001 0.001 0.001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.001 0.001 0.001 0.001 0.001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.001 0.001 0.001 0.001 0.001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.001 0.001 0.001 0.001 0.001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.001 0.001 0.001 0.001 0.001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.001 0.001 0.001 0.001 0.001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.001 0.001 0.001 0.001 0.001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.001 0.001 0.001 0.001 0.001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.001 0.001 0.001 0.001 0.001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.001 0.001 0.001 0.001 0.001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.001 0.001 0.001 0.001 0.001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.001 0.001 0.001 0.001 0.001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.001 0.001 0.001 0.001 0.001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.001 0.001 0.001 0.001 0.001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.001 0.001 0.001 0.001 0.001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.001 0.001 0.001 0.001 0.001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.001 0.001 0.001 0.001 0.001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.001 0.001 0.001 0.001 0.001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.001 0.001 0.001 0.001 0.001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.001 0.001 0.001 0.001 0.001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.001 0.001 0.001 0.001 0.001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.001 0.001 0.001 0.001 0.001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.001 0.001 0.001 0.001 0.001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.001 0.001 0.001 0.001 0.001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.001 0.001 0.001 0.001 0.001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.001 0.001 0.001 0.001 0.001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 0.0001025 -D/cons.3.00.000050.dat 0.0 0.0 0.0 0.0 0.0 -0.01431394091689 -0.00604850204226 -0.00053429439041 0.00038864891352 0.00048972321003 0.00049920840278 0.00049994758269 0.00049999696765 0.00049999986344 0.00050000000339 0.00050000000365 0.00049999999879 0.00049999999983 0.00050000000006 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999707 0.00049999994819 0.00049999919273 0.00049998909994 0.00049987561455 0.00049883906792 0.0004915725654 0.00044910677896 0.00034698618676 0.00023277874414 0.00016398608612 0.00012823076267 0.00010652798524 9.581402438e-05 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 -0.03702127407672 -0.01962380612003 -0.00329953318892 0.00011545128698 0.00046480840773 0.00049728986492 0.00049981964401 0.00049998936741 0.00049999940831 0.00049999997584 0.00050000000894 0.0004999999988 0.00049999999938 0.00050000000008 0.00050000000002 0.00049999999999 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999707 0.00049999994818 0.00049999919271 0.00049998909963 0.00049987560872 0.00049883897525 0.00049157172841 0.0004490997913 0.00034702197846 0.0002327091835 0.0001643239321 0.00012221989398 0.00010888346603 0.00010022815045 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 -0.09741762527644 -0.04273669858067 -0.02381782419966 -0.00462661568399 2.77434558e-05 0.00045958791889 0.00049707415607 0.00049981634289 0.00049998972994 0.00049999944882 0.00049999997404 0.00050000000628 0.00049999999956 0.0004999999995 0.00050000000004 0.00050000000002 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999707 0.00049999994819 0.00049999919274 0.00049998910011 0.00049987561759 0.00049883911056 0.00049157300137 0.0004491103497 0.00034699747736 0.00023285841732 0.00016440657675 0.00011982374362 0.0001059205854 0.00010333838935 9.416408889e-05 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 -0.05670293684621 -0.02037805240323 -0.0047731238902 0.00027179478193 0.00048990077451 0.00049987911054 0.00050002782282 0.00050000284812 0.00050000001968 0.00050000001235 0.00050000000168 0.00049999999932 0.00050000000005 0.00050000000005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999707 0.00049999994819 0.00049999919276 0.00049998910057 0.0004998756266 0.00049883925846 0.00049157467056 0.00044913008183 0.00034694654208 0.00023294720775 0.00016337571938 0.00011908776833 0.00010121614314 0.00010481854126 4.41473339e-05 0.0 0.0 0.0 0.0 0.0 0.0 0.00327590720269 -0.02510994203047 -0.01918532205596 -0.0052491160084 0.00079981429538 0.00087010189752 0.0005309489375 0.00050251533962 0.00050017285627 0.00050001064212 0.00050000081305 0.00050000006091 0.00050000000278 0.00049999999956 0.0005 0.00050000000004 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999707 0.00049999994819 0.00049999919273 0.0004999891001 0.00049987561761 0.00049883911508 0.00049157327182 0.00044911890159 0.00034696844537 0.00023282250796 0.00016189247689 0.00012174174621 0.00011270647452 9.605303811e-05 5.393276542e-05 -0.00056290890283 -0.00643351071755 0.0 0.0 0.09886256431958 0.0074985696734 0.00337249541471 -0.00589155928902 -0.00179326792428 2.319741475e-05 0.00083482712619 0.00062549944206 0.00051033540024 0.00050085183195 0.00050006075853 0.00050000396085 0.00050000020894 0.00050000000717 0.00050000000025 0.00049999999996 0.00050000000001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999707 0.00049999994819 0.00049999919273 0.00049998910003 0.00049987561606 0.00049883908735 0.0004915728847 0.00044911391638 0.00034698366966 0.00023272178697 0.00016312275122 0.00012441874746 0.00011105961009 7.458323213e-05 8.832047548e-05 -0.00040388043193 -0.00602744703396 -0.00429967335595 0.0167107818138 0.02300377816096 0.00292884349959 0.0014018639718 3.52359149e-06 0.00051678053987 0.00059010127737 0.00063935086208 0.00053899082032 0.00050400611032 0.00050039165983 0.00050003221241 0.000500002269 0.00050000012686 0.00050000000654 0.00050000000033 0.00049999999995 0.0005 0.00050000000001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999707 0.00049999994819 0.00049999919273 0.00049998910001 0.00049987561603 0.0004988390905 0.00049157284476 0.00044910970774 0.00034698967416 0.00023283167409 0.00016388537222 0.00012203792537 0.00010540749191 9.888372513e-05 0.00010028090849 3.508380771e-05 -0.00072695640394 -0.00010700783043 0.00709200701661 0.0033025223242 0.00121905367333 0.00100765095084 0.00082916990805 0.00079985097519 0.00064555843541 0.00058652278171 0.00052494607446 0.0005030426414 0.00050032580765 0.00050002839749 0.00050000204809 0.0005000001336 0.00050000000773 0.00050000000036 0.00049999999993 0.0005 0.00050000000001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999707 0.00049999994819 0.00049999919273 0.00049998910001 0.00049987561594 0.00049883908863 0.00049157282296 0.00044910908391 0.00034699441067 0.00023282739172 0.0001639833831 0.00012169740983 0.00010485958685 0.0001026053962 0.00010254681903 0.00010049387762 6.187087212e-05 0.0002919017237 0.00163384711739 0.00090922889361 0.00093453098591 0.00096237892648 0.00092268560428 0.00082778669183 0.00064874570015 0.00058055296669 0.00052338913652 0.00050294172906 0.00050031933506 0.0005000279406 0.00050000208538 0.00050000013515 0.00050000000774 0.00050000000036 0.00049999999993 0.0005 0.00050000000001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999707 0.00049999994819 0.00049999919273 0.00049998910001 0.00049987561593 0.00049883908842 0.00049157282002 0.00044910908922 0.00034699478143 0.00023282635311 0.00016399239927 0.00012167628616 0.00010482639746 0.00010287198138 0.00010283766262 0.00010676508933 0.00013330124542 0.00024900846538 0.00054981555448 0.00066453311642 0.00090093395729 0.00095817169742 0.00093123964241 0.00083007426173 0.00064879176747 0.00057999092498 0.00052325707609 0.00050293360573 0.00050031869726 0.00050002799482 0.00050000208106 0.00050000013402 0.00050000000766 0.00050000000036 0.00049999999993 0.0005 0.00050000000001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999707 0.00049999994819 0.00049999919273 0.00049998910001 0.00049987561594 0.00049883908846 0.00049157282024 0.00044910909555 0.00034699471791 0.00023282632355 0.00016399348479 0.00012167487328 0.00010482427241 0.00010288866494 0.00010286422652 0.00010726720641 0.00013886314484 0.00023712483627 0.00042470463281 0.00064420271242 0.00089789795315 0.00095784928308 0.00093189453032 0.00083023304462 0.00064877913444 0.00057994804281 0.00052324785778 0.00050293291444 0.00050031875808 0.00050002799337 0.00050000207825 0.0005000001339 0.00050000000766 0.00050000000036 0.00049999999993 0.0005 0.00050000000001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999707 0.00049999994819 0.00049999919273 0.00049998910001 0.00049987561594 0.00049883908845 0.00049157282024 0.00044910909144 0.00034699470909 0.00023282635567 0.00016399345644 0.00012167484945 0.00010482420307 0.00010288982465 0.00010286636911 0.00010730141859 0.00013922996435 0.00023557868334 0.0004129343207 0.00064277770362 0.00089767348638 0.00095782815054 0.00093193752946 0.00083024273435 0.00064877703107 0.00057994502192 0.00052324715927 0.00050293298209 0.00050031876221 0.00050002798843 0.00050000207833 0.00050000013393 0.00050000000766 0.00050000000036 0.00049999999993 0.0005 0.00050000000001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999707 0.00049999994819 0.00049999919273 0.00049998910001 0.00049987561594 0.00049883908845 0.00049157282018 0.00044910909073 0.00034699471558 0.0002328263527 0.00016399343748 0.0001216748707 0.00010482423048 0.00010288979436 0.00010286647172 0.00010730362115 0.00013925046286 0.00023543354798 0.00041202508884 0.0006426912282 0.00089765932887 0.0009578267907 0.00093194017477 0.00083024335967 0.00064877699698 0.00057994490343 0.00052324723143 0.00050293298846 0.00050031875576 0.00050002798859 0.0005000020784 0.00050000013394 0.00050000000766 0.00050000000036 0.00049999999993 0.0005 0.00050000000001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999707 0.00049999994819 0.00049999919273 0.00049998910001 0.00049987561594 0.00049883908845 0.00049157282018 0.00044910909079 0.00034699471597 0.00023282634946 0.00016399344359 0.00012167486762 0.00010482422464 0.00010288978105 0.00010286643708 0.00010730369114 0.00013925168171 0.00023542263863 0.00041196567225 0.00064268641369 0.00089765844343 0.00095782683814 0.00093194023455 0.00083024324287 0.00064877704953 0.0005799449756 0.00052324724076 0.00050293298128 0.00050031875576 0.00050002798873 0.00050000207839 0.00050000013394 0.00050000000766 0.00050000000036 0.00049999999993 0.0005 0.00050000000001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999707 0.00049999994819 0.00049999919273 0.00049998910001 0.00049987561594 0.00049883908845 0.00049157282018 0.00044910909081 0.00034699471565 0.0002328263497 0.00016399344501 0.00012167486631 0.00010482422292 0.00010288978668 0.00010286644246 0.0001073036619 0.00013925164986 0.00023542175342 0.00041196206392 0.00064268615223 0.00089765853424 0.00095782686849 0.00093194017162 0.00083024323763 0.00064877704068 0.00057994496615 0.0005232472331 0.00050293298124 0.00050031875597 0.0005000279887 0.00050000207839 0.00050000013393 0.00050000000766 0.00050000000036 0.00049999999993 0.0005 0.00050000000001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999707 0.00049999994819 0.00049999919273 0.00049998910001 0.00049987561594 0.00049883908845 0.00049157282018 0.00044910909081 0.00034699471567 0.00023282634984 0.00016399344462 0.00012167486645 0.00010482422331 0.00010288978733 0.00010286644474 0.00010730366821 0.00013925163976 0.00023542180193 0.00041196190182 0.00064268623556 0.00089765854856 0.00095782685632 0.00093194018488 0.00083024324898 0.00064877703658 0.00057994496089 0.00052324723279 0.00050293298149 0.00050031875594 0.00050002798869 0.00050000207839 0.00050000013394 0.00050000000766 0.00050000000036 0.00049999999993 0.0005 0.00050000000001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999707 0.00049999994819 0.00049999919273 0.00049998910001 0.00049987561594 0.00049883908845 0.00049157282018 0.0004491090908 0.00034699471569 0.00023282634981 0.00016399344459 0.0001216748665 0.00010482422335 0.00010288978701 0.00010286644435 0.00010730366997 0.00013925164591 0.00023542181703 0.00041196196915 0.00064268622923 0.00089765853821 0.00095782685507 0.0009319401886 0.00083024324889 0.00064877703711 0.00057994496164 0.00052324723311 0.00050293298146 0.00050031875593 0.0005000279887 0.00050000207839 0.00050000013393 0.00050000000766 0.00050000000036 0.00049999999993 0.0005 0.00050000000001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999707 0.00049999994819 0.00049999919273 0.00049998910001 0.00049987561594 0.00049883908845 0.00049157282018 0.0004491090908 0.00034699471568 0.00023282634981 0.00016399344462 0.00012167486649 0.00010482422332 0.00010288978702 0.00010286644428 0.00010730366952 0.00013925164603 0.00023542181061 0.00041196196172 0.00064268622343 0.00089765853776 0.00095782685564 0.00093194018774 0.00083024324835 0.00064877703725 0.00057994496182 0.00052324723309 0.00050293298145 0.00050031875593 0.0005000279887 0.00050000207839 0.00050000013393 0.00050000000766 0.00050000000036 0.00049999999993 0.0005 0.00050000000001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999707 0.00049999994819 0.00049999919273 0.00049998910001 0.00049987561594 0.00049883908845 0.00049157282018 0.0004491090908 0.00034699471568 0.00023282634981 0.00016399344462 0.00012167486649 0.00010482422332 0.00010288978703 0.00010286644431 0.00010730366948 0.00013925164568 0.00023542180956 0.00041196195701 0.000642686224 0.00089765853821 0.00095782685564 0.00093194018767 0.00083024324842 0.00064877703721 0.00057994496176 0.00052324723307 0.00050293298145 0.00050031875593 0.0005000279887 0.00050000207839 0.00050000013393 0.00050000000766 0.00050000000036 0.00049999999993 0.0005 0.00050000000001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999707 0.00049999994819 0.00049999919273 0.00049998910001 0.00049987561594 0.00049883908845 0.00049157282018 0.0004491090908 0.00034699471568 0.00023282634981 0.00016399344462 0.00012167486649 0.00010482422332 0.00010288978703 0.00010286644431 0.00010730366951 0.00013925164573 0.00023542180991 0.00041196195769 0.0006426862242 0.00089765853819 0.00095782685561 0.00093194018772 0.00083024324844 0.0006487770372 0.00057994496176 0.00052324723308 0.00050293298145 0.00050031875593 0.0005000279887 0.00050000207839 0.00050000013394 0.00050000000766 0.00050000000036 0.00049999999993 0.0005 0.00050000000001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999707 0.00049999994819 0.00049999919273 0.00049998910001 0.00049987561594 0.00049883908845 0.00049157282018 0.0004491090908 0.00034699471568 0.00023282634981 0.00016399344462 0.00012167486649 0.00010482422332 0.00010288978703 0.00010286644431 0.00010730366951 0.00013925164575 0.00023542180993 0.00041196195783 0.00064268622414 0.00089765853817 0.00095782685561 0.00093194018772 0.00083024324843 0.0006487770372 0.00057994496176 0.00052324723308 0.00050293298145 0.00050031875593 0.0005000279887 0.00050000207839 0.00050000013393 0.00050000000766 0.00050000000036 0.00049999999993 0.0005 0.00050000000001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999707 0.00049999994819 0.00049999919273 0.00049998910001 0.00049987561594 0.00049883908845 0.00049157282018 0.0004491090908 0.00034699471568 0.00023282634981 0.00016399344462 0.00012167486649 0.00010482422332 0.00010288978703 0.00010286644431 0.00010730366951 0.00013925164574 0.00023542180991 0.00041196195778 0.00064268622414 0.00089765853817 0.00095782685561 0.00093194018772 0.00083024324843 0.0006487770372 0.00057994496176 0.00052324723308 0.00050293298145 0.00050031875593 0.0005000279887 0.00050000207839 0.00050000013393 0.00050000000766 0.00050000000036 0.00049999999993 0.0005 0.00050000000001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999707 0.00049999994819 0.00049999919273 0.00049998910001 0.00049987561594 0.00049883908845 0.00049157282018 0.0004491090908 0.00034699471568 0.00023282634981 0.00016399344462 0.00012167486649 0.00010482422332 0.00010288978703 0.00010286644431 0.00010730366951 0.00013925164574 0.00023542180991 0.00041196195778 0.00064268622414 0.00089765853817 0.00095782685561 0.00093194018772 0.00083024324843 0.0006487770372 0.00057994496176 0.00052324723308 0.00050293298145 0.00050031875593 0.0005000279887 0.00050000207839 0.00050000013393 0.00050000000766 0.00050000000036 0.00049999999993 0.0005 0.00050000000001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999707 0.00049999994819 0.00049999919273 0.00049998910001 0.00049987561594 0.00049883908845 0.00049157282018 0.0004491090908 0.00034699471568 0.00023282634981 0.00016399344462 0.00012167486649 0.00010482422332 0.00010288978703 0.00010286644431 0.00010730366951 0.00013925164574 0.00023542180991 0.00041196195778 0.00064268622414 0.00089765853817 0.00095782685561 0.00093194018772 0.00083024324843 0.0006487770372 0.00057994496176 0.00052324723308 0.00050293298145 0.00050031875593 0.0005000279887 0.00050000207839 0.00050000013394 0.00050000000766 0.00050000000036 0.00049999999993 0.0005 0.00050000000001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999707 0.00049999994819 0.00049999919273 0.00049998910001 0.00049987561594 0.00049883908845 0.00049157282018 0.0004491090908 0.00034699471568 0.00023282634981 0.00016399344462 0.00012167486649 0.00010482422332 0.00010288978703 0.00010286644431 0.00010730366951 0.00013925164574 0.00023542180991 0.00041196195778 0.00064268622414 0.00089765853817 0.00095782685561 0.00093194018772 0.00083024324843 0.0006487770372 0.00057994496176 0.00052324723308 0.00050293298145 0.00050031875593 0.0005000279887 0.00050000207839 0.00050000013394 0.00050000000766 0.00050000000036 0.00049999999993 0.0005 0.00050000000001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999707 0.00049999994819 0.00049999919273 0.00049998910001 0.00049987561594 0.00049883908845 0.00049157282018 0.0004491090908 0.00034699471568 0.00023282634981 0.00016399344462 0.00012167486649 0.00010482422332 0.00010288978703 0.00010286644431 0.00010730366951 0.00013925164574 0.00023542180991 0.00041196195778 0.00064268622414 0.00089765853817 0.00095782685561 0.00093194018772 0.00083024324843 0.0006487770372 0.00057994496176 0.00052324723308 0.00050293298145 0.00050031875593 0.0005000279887 0.00050000207839 0.00050000013393 0.00050000000766 0.00050000000036 0.00049999999993 0.0005 0.00050000000001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999707 0.00049999994819 0.00049999919273 0.00049998910001 0.00049987561594 0.00049883908845 0.00049157282018 0.0004491090908 0.00034699471568 0.00023282634981 0.00016399344462 0.00012167486649 0.00010482422332 0.00010288978703 0.00010286644431 0.00010730366951 0.00013925164574 0.00023542180991 0.00041196195778 0.00064268622414 0.00089765853817 0.00095782685561 0.00093194018772 0.00083024324843 0.0006487770372 0.00057994496176 0.00052324723308 0.00050293298145 0.00050031875593 0.0005000279887 0.00050000207839 0.00050000013393 0.00050000000766 0.00050000000036 0.00049999999993 0.0005 0.00050000000001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999707 0.00049999994819 0.00049999919273 0.00049998910001 0.00049987561594 0.00049883908845 0.00049157282018 0.0004491090908 0.00034699471568 0.00023282634981 0.00016399344462 0.00012167486649 0.00010482422332 0.00010288978703 0.00010286644431 0.00010730366951 0.00013925164574 0.00023542180991 0.00041196195778 0.00064268622414 0.00089765853817 0.00095782685561 0.00093194018772 0.00083024324843 0.0006487770372 0.00057994496176 0.00052324723308 0.00050293298145 0.00050031875593 0.0005000279887 0.00050000207839 0.00050000013394 0.00050000000766 0.00050000000036 0.00049999999993 0.0005 0.00050000000001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999707 0.00049999994819 0.00049999919273 0.00049998910001 0.00049987561594 0.00049883908845 0.00049157282018 0.0004491090908 0.00034699471568 0.00023282634981 0.00016399344462 0.00012167486649 0.00010482422332 0.00010288978703 0.00010286644431 0.00010730366951 0.00013925164574 0.00023542180991 0.00041196195778 0.00064268622415 0.00089765853817 0.00095782685561 0.00093194018772 0.00083024324843 0.0006487770372 0.00057994496176 0.00052324723308 0.00050293298145 0.00050031875593 0.0005000279887 0.00050000207839 0.00050000013394 0.00050000000766 0.00050000000036 0.00049999999993 0.0005 0.00050000000001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999707 0.00049999994819 0.00049999919273 0.00049998910001 0.00049987561594 0.00049883908845 0.00049157282018 0.0004491090908 0.00034699471568 0.00023282634981 0.00016399344462 0.00012167486649 0.00010482422332 0.00010288978703 0.00010286644431 0.00010730366951 0.00013925164574 0.00023542180991 0.00041196195778 0.00064268622414 0.00089765853818 0.00095782685561 0.00093194018772 0.00083024324843 0.0006487770372 0.00057994496176 0.00052324723308 0.00050293298145 0.00050031875593 0.0005000279887 0.00050000207839 0.00050000013393 0.00050000000766 0.00050000000036 0.00049999999993 0.0005 0.00050000000001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999707 0.00049999994819 0.00049999919273 0.00049998910001 0.00049987561594 0.00049883908845 0.00049157282018 0.0004491090908 0.00034699471568 0.00023282634981 0.00016399344462 0.00012167486649 0.00010482422332 0.00010288978703 0.00010286644431 0.00010730366951 0.00013925164574 0.00023542180991 0.00041196195778 0.00064268622408 0.00089765853815 0.00095782685562 0.00093194018772 0.00083024324843 0.00064877703721 0.00057994496176 0.00052324723308 0.00050293298145 0.00050031875593 0.0005000279887 0.00050000207839 0.00050000013394 0.00050000000766 0.00050000000036 0.00049999999993 0.0005 0.00050000000001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999707 0.00049999994819 0.00049999919273 0.00049998910001 0.00049987561594 0.00049883908845 0.00049157282018 0.0004491090908 0.00034699471568 0.00023282634981 0.00016399344462 0.00012167486649 0.00010482422332 0.00010288978703 0.00010286644431 0.00010730366951 0.00013925164574 0.00023542180988 0.00041196195772 0.00064268622431 0.00089765853811 0.00095782685557 0.00093194018776 0.00083024324844 0.00064877703719 0.00057994496176 0.00052324723308 0.00050293298145 0.00050031875593 0.0005000279887 0.00050000207839 0.00050000013393 0.00050000000766 0.00050000000036 0.00049999999993 0.0005 0.00050000000001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999707 0.00049999994819 0.00049999919273 0.00049998910001 0.00049987561594 0.00049883908845 0.00049157282018 0.0004491090908 0.00034699471568 0.00023282634981 0.00016399344462 0.00012167486649 0.00010482422332 0.00010288978703 0.00010286644431 0.00010730366951 0.00013925164574 0.0002354218099 0.00041196195791 0.00064268622486 0.00089765853874 0.00095782685558 0.00093194018771 0.00083024324844 0.00064877703715 0.0005799449617 0.00052324723307 0.00050293298145 0.00050031875593 0.0005000279887 0.00050000207839 0.00050000013393 0.00050000000766 0.00050000000036 0.00049999999993 0.0005 0.00050000000001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999707 0.00049999994819 0.00049999919273 0.00049998910001 0.00049987561594 0.00049883908845 0.00049157282018 0.0004491090908 0.00034699471568 0.00023282634981 0.00016399344462 0.00012167486649 0.00010482422332 0.00010288978703 0.00010286644431 0.0001073036695 0.00013925164583 0.00023542181038 0.00041196195854 0.00064268621838 0.00089765853786 0.00095782685646 0.00093194018694 0.00083024324835 0.00064877703749 0.00057994496184 0.00052324723303 0.00050293298145 0.00050031875593 0.0005000279887 0.00050000207839 0.00050000013393 0.00050000000766 0.00050000000036 0.00049999999993 0.0005 0.00050000000001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999707 0.00049999994819 0.00049999919273 0.00049998910001 0.00049987561594 0.00049883908845 0.00049157282018 0.0004491090908 0.00034699471568 0.00023282634981 0.00016399344462 0.00012167486649 0.00010482422332 0.00010288978703 0.0001028664443 0.0001073036695 0.00013925164567 0.00023542180893 0.00041196195305 0.00064268621324 0.00089765852523 0.00095782685391 0.00093194018985 0.00083024324828 0.00064877703764 0.00057994496268 0.00052324723328 0.00050293298141 0.00050031875593 0.0005000279887 0.00050000207839 0.00050000013394 0.00050000000766 0.00050000000036 0.00049999999993 0.0005 0.00050000000001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999707 0.00049999994819 0.00049999919273 0.00049998910001 0.00049987561594 0.00049883908845 0.00049157282018 0.0004491090908 0.00034699471568 0.00023282634981 0.00016399344461 0.00012167486648 0.00010482422332 0.00010288978705 0.00010286644431 0.00010730366961 0.00013925164439 0.00023542180111 0.00041196194724 0.00064268630287 0.00089765855005 0.0009578268392 0.00093194020302 0.0008302432504 0.00064877702969 0.00057994495814 0.00052324723347 0.0005029329816 0.00050031875589 0.00050002798869 0.00050000207839 0.00050000013394 0.00050000000766 0.00050000000036 0.00049999999993 0.0005 0.00050000000001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999707 0.00049999994819 0.00049999919273 0.00049998910001 0.00049987561594 0.00049883908845 0.00049157282018 0.00044910909081 0.00034699471568 0.00023282634981 0.00016399344462 0.00012167486647 0.0001048242233 0.00010288978689 0.00010286644442 0.00010730366945 0.00013925164914 0.0002354218242 0.00041196202124 0.00064268598501 0.00089765861805 0.00095782689025 0.00093194015218 0.00083024325466 0.00064877702945 0.00057994494715 0.00052324722722 0.00050293298188 0.00050031875606 0.00050002798866 0.00050000207838 0.00050000013394 0.00050000000766 0.00050000000036 0.00049999999993 0.0005 0.00050000000001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999707 0.00049999994819 0.00049999919273 0.00049998910001 0.00049987561594 0.00049883908845 0.00049157282018 0.0004491090908 0.00034699471571 0.00023282634981 0.00016399344463 0.00012167486673 0.00010482422352 0.00010288978697 0.00010286644416 0.00010730366925 0.00013925165982 0.0002354218529 0.00041196180812 0.00064268052162 0.00089765739927 0.00095782687383 0.00093194015527 0.00083024320226 0.00064877711764 0.00057994501089 0.00052324722711 0.00050293297588 0.00050031875631 0.00050002798878 0.00050000207837 0.00050000013393 0.00050000000766 0.00050000000036 0.00049999999993 0.0005 0.00050000000001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999707 0.00049999994819 0.00049999919273 0.00049998910001 0.00049987561594 0.00049883908845 0.00049157282018 0.00044910909079 0.00034699471562 0.00023282635001 0.00016399344441 0.00012167486599 0.00010482422307 0.00010288979086 0.00010286644457 0.00010730366758 0.00013925154425 0.0002354205531 0.00041195770034 0.0006425836991 0.00089763769522 0.00095782479902 0.00093194222535 0.00083024335262 0.00064877674599 0.00057994494948 0.00052324730667 0.00050293297509 0.00050031875061 0.00050002798908 0.00050000207845 0.00050000013393 0.00050000000766 0.00050000000036 0.00049999999993 0.0005 0.00050000000001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999707 0.00049999994819 0.00049999919273 0.00049998910001 0.00049987561594 0.00049883908845 0.00049157282019 0.00044910909094 0.0003469947153 0.00023282634902 0.00016399344633 0.00012167486127 0.0001048242186 0.00010288978733 0.00010286644317 0.00010730366143 0.00013925169395 0.00023540412046 0.00041189047155 0.00064102088096 0.00089733445585 0.00095779220887 0.00093197436778 0.00083024683514 0.00064877218069 0.00057994248622 0.00052324690718 0.00050293305295 0.00050031874975 0.00050002798448 0.00050000207859 0.00050000013397 0.00050000000766 0.00050000000036 0.00049999999993 0.0005 0.00050000000001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999707 0.00049999994819 0.00049999919273 0.00049998910001 0.00049987561594 0.00049883908845 0.00049157282016 0.00044910909075 0.00034699471771 0.00023282634515 0.00016399344704 0.00012167487733 0.00010482423389 0.00010288972884 0.00010286640621 0.00010730413722 0.00013925931856 0.00023518766218 0.00041088138396 0.00061917726083 0.00089334632196 0.00095731799813 0.00093246490887 0.00083032676247 0.00064872118041 0.00057990699828 0.0005232408051 0.00050293258748 0.00050031882068 0.00050002798065 0.00050000207573 0.00050000013386 0.00050000000766 0.00050000000036 0.00049999999993 0.0005 0.00050000000001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999707 0.00049999994819 0.00049999919273 0.00049998910001 0.00049987561593 0.00049883908843 0.00049157281999 0.00044910908691 0.00034699471955 0.00023282636283 0.00016399340337 0.00012167487103 0.00010482424814 0.00010289039064 0.00010286693119 0.00010731739879 0.00013948541143 0.00023286951328 0.0003980518985 0.00036133067716 0.00085026809041 0.00095145986053 0.00093899060562 0.00083175078887 0.00064830043471 0.0005794185778 0.0005231440218 0.00050292659366 0.00050031834125 0.00050002804075 0.00050000207065 0.00050000013264 0.00050000000758 0.00050000000036 0.00049999999993 0.0005 0.00050000000001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999707 0.00049999994819 0.00049999919273 0.00049998910001 0.00049987561594 0.00049883908849 0.00049157282085 0.00044910909436 0.00034699469771 0.00023282639276 0.00016399364292 0.00012167344933 0.00010482278045 0.00010290072507 0.00010287571652 0.00010758472127 0.0001437888019 0.00021275090764 0.00026408818107 -0.00211414609599 0.00049267555083 0.00089213406742 0.00101302235377 0.00085176249815 0.00064708376379 0.00057392707367 0.00052188124698 0.00050284511925 0.00050031307217 0.00050002766995 0.00050000211262 0.00050000013395 0.00050000000756 0.00050000000035 0.00049999999993 0.0005 0.00050000000001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999707 0.00049999994819 0.00049999919273 0.00049998910001 0.00049987561597 0.00049883908889 0.00049157282389 0.00044910912568 0.00034699457851 0.0002328256971 0.00016399678122 0.00012165149819 0.00010479415158 0.00010309172017 0.00010301760133 0.00011173953791 0.00020747459276 0.00013312534548 -0.00088238274908 -0.02222917639537 -0.00167003108873 0.00040770767619 0.00170541550031 0.00107249769555 0.00066741409383 0.00052455648191 0.0005091460447 0.0005019744005 0.00050025378655 0.00050002419339 0.00050000191963 0.00050000014416 0.00050000000888 0.00050000000039 0.00049999999992 0.00050000000001 0.00050000000001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999707 0.00049999994819 0.00049999919273 0.00049998910001 0.00049987561591 0.00049883908756 0.00049157280293 0.00044910869595 0.00034699585226 0.00023282277758 0.00016404329824 0.00012129314816 0.00010425915152 0.0001060357234 0.0001044504496 0.00016269507418 0.00096235092752 0.00037642565462 -0.00651235378604 -0.0983402839119 -0.0067821385256 -0.00194595940128 0.00696168898921 0.0029502228706 0.00099168388362 0.00025886584804 0.00041990533496 0.0004954491488 0.00049978291097 0.00049999508392 0.0005000001914 0.00050000006092 0.00050000000855 0.00050000000048 0.0004999999999 0.0005 0.00050000000001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999707 0.00049999994819 0.00049999919273 0.00049998909999 0.00049987561573 0.00049883908574 0.00049157272551 0.00044910601228 0.00034699885153 0.00023292658444 0.00016451848764 0.00011823197413 9.867472175e-05 0.00012746245272 0.00011415500399 0.00054901825874 0.00619859884769 0.00450618766193 -0.0163880169121 0.0 0.0 -0.00244954296323 0.02567434108666 0.01748088086668 0.00441060932187 -0.00011923941115 0.00012953700114 0.00047161409042 0.00049789555764 0.00049986941751 0.00049999273692 0.00049999940243 0.00049999995282 0.0004999999979 0.0005000000003 0.00050000000001 0.00049999999997 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999707 0.00049999994819 0.00049999919273 0.00049998910004 0.00049987561669 0.00049883910521 0.00049157311042 0.00044911072737 0.00034702761124 0.0002328385069 0.0001655397501 0.0001222319368 9.715227937e-05 0.00010916557989 0.00015097441792 0.0006898393982 0.00654897956809 0.0 0.0 0.0 0.0 0.0 0.0 0.04752601990241 0.01635971299471 0.00366547523487 0.00059060154539 0.00049798232223 0.00049956674149 0.00049996387914 0.00049999812012 0.00050000011226 0.00049999998942 0.00049999999832 0.00050000000071 0.00049999999995 0.00049999999995 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999707 0.00049999994819 0.00049999919276 0.00049998910065 0.00049987562759 0.00049883926883 0.00049157513742 0.00044914425433 0.00034699357285 0.00023284206648 0.00016423032964 0.00012948364445 9.933510893e-05 0.00010414865666 0.00010204425873 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.06532225788682 0.0383571806851 0.02450482107658 0.00577460231474 0.00097588975631 0.00054029314625 0.00050288505285 0.00050017968168 0.0005000101257 0.00050000057797 0.00050000002741 0.00049999999345 0.00050000000045 0.00050000000053 0.00049999999996 0.00049999999998 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999707 0.00049999994819 0.00049999919274 0.00049998910016 0.0004998756187 0.00049883913298 0.00049157321339 0.00044910924838 0.00034698868573 0.00023282606046 0.00016380119814 0.00012554192407 0.00010483719694 0.00010412907315 2.97432584e-05 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.05011334460435 0.02670876593182 0.00483758677413 0.0009592469197 0.00054227682828 0.00050326194399 0.00050021685489 0.00050001271984 0.00050000066448 0.00050000002245 0.00049999998956 0.00050000000174 0.0005000000007 0.00049999999989 0.00049999999998 0.00050000000001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999707 0.00049999994818 0.0004999991927 0.00049998909927 0.00049987560247 0.0004988388805 0.00049157039182 0.00044907578789 0.00034702357588 0.00023277424199 0.00016434153568 0.00011332372547 0.00010688953475 0.00010549746747 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.01171502421791 0.00377862456534 0.0011615151556 0.00056215846284 0.00050559223592 0.00050043492643 0.00050002953944 0.00050000164176 0.00050000007265 0.0004999999983 0.00049999999772 0.00050000000071 0.0005000000001 0.00049999999996 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999707 0.00049999994819 0.00049999919271 0.00049998909964 0.00049987560886 0.00049883897248 0.00049157117609 0.0004490843297 0.00034700786073 0.00023284556313 0.00016433916166 0.0001157670588 0.00010533401527 0.00010885040785 0.0 0.0 0.0 0.0 0.0 +D/cons.3.00.000050.dat 0.0 0.0 0.0 0.0 0.0 -0.01431394091689 -0.00604850204226 -0.00053429439041 0.00038864891352 0.00048972321003 0.00049920840278 0.00049994758269 0.00049999696765 0.00049999986344 0.00050000000339 0.00050000000365 0.00049999999879 0.00049999999983 0.00050000000006 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999707 0.00049999994819 0.00049999919273 0.00049998909994 0.00049987561455 0.00049883906792 0.0004915725654 0.00044910677896 0.00034698618676 0.00023277874414 0.00016398608612 0.00012823076267 0.00010652798524 9.581402438e-05 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 -0.03702127407672 -0.01962380612003 -0.00329953318892 0.00011545128698 0.00046480840773 0.00049728986492 0.00049981964401 0.00049998936741 0.00049999940831 0.00049999997584 0.00050000000894 0.0004999999988 0.00049999999938 0.00050000000008 0.00050000000002 0.00049999999999 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999707 0.00049999994818 0.00049999919271 0.00049998909963 0.00049987560872 0.00049883897525 0.00049157172841 0.0004490997913 0.00034702197846 0.0002327091835 0.0001643239321 0.00012221989398 0.00010888346603 0.00010022815045 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 -0.09741762527644 -0.04273669858067 -0.02381782419966 -0.00462661568399 2.77434558e-05 0.00045958791889 0.00049707415607 0.00049981634289 0.00049998972994 0.00049999944882 0.00049999997404 0.00050000000628 0.00049999999956 0.0004999999995 0.00050000000004 0.00050000000002 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999707 0.00049999994819 0.00049999919274 0.00049998910011 0.00049987561759 0.00049883911056 0.00049157300137 0.0004491103497 0.00034699747736 0.00023285841732 0.00016440657675 0.00011982374362 0.0001059205854 0.00010333838935 9.416408889e-05 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 -0.05670293684621 -0.02037805240323 -0.0047731238902 0.00027179478193 0.00048990077451 0.00049987911054 0.00050002782282 0.00050000284812 0.00050000001968 0.00050000001235 0.00050000000168 0.00049999999932 0.00050000000005 0.00050000000005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999707 0.00049999994819 0.00049999919276 0.00049998910057 0.0004998756266 0.00049883925846 0.00049157467056 0.00044913008183 0.00034694654208 0.00023294720775 0.00016337571938 0.00011908776833 0.00010121614314 0.00010481854126 4.41473339e-05 0.0 0.0 0.0 0.0 0.0 0.0 0.00327590720269 -0.02510994203047 -0.01918532205596 -0.0052491160084 0.00079981429538 0.00087010189752 0.0005309489375 0.00050251533962 0.00050017285627 0.00050001064212 0.00050000081305 0.00050000006091 0.00050000000278 0.00049999999956 0.0005 0.00050000000004 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999707 0.00049999994819 0.00049999919273 0.0004999891001 0.00049987561761 0.00049883911508 0.00049157327182 0.00044911890159 0.00034696844537 0.00023282250796 0.00016189247689 0.00012174174621 0.00011270647452 9.605303811e-05 5.393276542e-05 -0.00056290890283 -0.00643351071755 0.0 0.0 0.09886256431958 0.0074985696734 0.00337249541471 -0.00589155928902 -0.00179326792428 2.319741475e-05 0.00083482712619 0.00062549944206 0.00051033540024 0.00050085183195 0.00050006075853 0.00050000396085 0.00050000020894 0.00050000000717 0.00050000000025 0.00049999999996 0.00050000000001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999707 0.00049999994819 0.00049999919273 0.00049998910003 0.00049987561606 0.00049883908735 0.0004915728847 0.00044911391638 0.00034698366966 0.00023272178697 0.00016312275122 0.00012441874746 0.00011105961009 7.458323213e-05 8.832047548e-05 -0.00040388043193 -0.00602744703396 -0.00429967335595 0.0167107818138 0.02300377816096 0.00292884349959 0.0014018639718 3.52359149e-06 0.00051678053987 0.00059010127737 0.00063935086208 0.00053899082032 0.00050400611032 0.00050039165983 0.00050003221241 0.000500002269 0.00050000012686 0.00050000000654 0.00050000000033 0.00049999999995 0.0005 0.00050000000001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999707 0.00049999994819 0.00049999919273 0.00049998910001 0.00049987561603 0.0004988390905 0.00049157284476 0.00044910970774 0.00034698967416 0.00023283167409 0.00016388537222 0.00012203792537 0.00010540749191 9.888372513e-05 0.00010028090849 3.508380771e-05 -0.00072695640394 -0.00010700783043 0.00709200701661 0.0033025223242 0.00121905367333 0.00100765095084 0.00082916990805 0.00079985097519 0.00064555843541 0.00058652278171 0.00052494607446 0.0005030426414 0.00050032580765 0.00050002839749 0.00050000204809 0.0005000001336 0.00050000000773 0.00050000000036 0.00049999999993 0.0005 0.00050000000001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999707 0.00049999994819 0.00049999919273 0.00049998910001 0.00049987561594 0.00049883908863 0.00049157282296 0.00044910908391 0.00034699441067 0.00023282739172 0.0001639833831 0.00012169740983 0.00010485958685 0.0001026053962 0.00010254681903 0.00010049387762 6.187087212e-05 0.0002919017237 0.00163384711739 0.00090922889361 0.00093453098591 0.00096237892648 0.00092268560428 0.00082778669183 0.00064874570015 0.00058055296669 0.00052338913652 0.00050294172906 0.00050031933506 0.0005000279406 0.00050000208538 0.00050000013515 0.00050000000774 0.00050000000036 0.00049999999993 0.0005 0.00050000000001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999707 0.00049999994819 0.00049999919273 0.00049998910001 0.00049987561593 0.00049883908841 0.00049157282002 0.00044910908922 0.00034699478143 0.00023282635311 0.00016399239927 0.00012167628616 0.00010482639746 0.00010287198138 0.00010283766262 0.00010676508933 0.00013330124542 0.00024900846538 0.00054981555448 0.00066453311643 0.00090093395729 0.00095817169743 0.00093123964241 0.00083007426173 0.00064879176747 0.00057999092498 0.00052325707609 0.00050293360573 0.00050031869726 0.00050002799482 0.00050000208106 0.00050000013402 0.00050000000766 0.00050000000036 0.00049999999993 0.0005 0.00050000000001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999707 0.00049999994819 0.00049999919273 0.00049998910001 0.00049987561594 0.00049883908846 0.00049157282024 0.00044910909555 0.00034699471791 0.00023282632355 0.00016399348479 0.00012167487328 0.00010482427241 0.00010288866494 0.00010286422652 0.00010726720641 0.00013886314484 0.00023712483627 0.00042470463281 0.00064420271242 0.00089789795315 0.00095784928308 0.00093189453032 0.00083023304462 0.00064877913444 0.00057994804281 0.00052324785778 0.00050293291444 0.00050031875808 0.00050002799337 0.00050000207825 0.0005000001339 0.00050000000766 0.00050000000036 0.00049999999993 0.0005 0.00050000000001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999707 0.00049999994819 0.00049999919273 0.00049998910001 0.00049987561594 0.00049883908845 0.00049157282024 0.00044910909144 0.00034699470909 0.00023282635567 0.00016399345644 0.00012167484945 0.00010482420307 0.00010288982465 0.00010286636911 0.00010730141859 0.00013922996435 0.00023557868334 0.0004129343207 0.00064277770361 0.00089767348638 0.00095782815054 0.00093193752946 0.00083024273435 0.00064877703107 0.00057994502192 0.00052324715927 0.00050293298209 0.00050031876221 0.00050002798843 0.00050000207833 0.00050000013393 0.00050000000766 0.00050000000036 0.00049999999993 0.0005 0.00050000000001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999707 0.00049999994819 0.00049999919273 0.00049998910001 0.00049987561594 0.00049883908845 0.00049157282018 0.00044910909073 0.00034699471558 0.0002328263527 0.00016399343748 0.0001216748707 0.00010482423048 0.00010288979436 0.00010286647172 0.00010730362115 0.00013925046286 0.00023543354798 0.00041202508884 0.0006426912282 0.00089765932887 0.0009578267907 0.00093194017477 0.00083024335967 0.00064877699698 0.00057994490343 0.00052324723143 0.00050293298846 0.00050031875576 0.00050002798859 0.0005000020784 0.00050000013394 0.00050000000766 0.00050000000036 0.00049999999993 0.0005 0.00050000000001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999707 0.00049999994819 0.00049999919273 0.00049998910001 0.00049987561594 0.00049883908845 0.00049157282018 0.00044910909079 0.00034699471597 0.00023282634946 0.00016399344359 0.00012167486762 0.00010482422464 0.00010288978105 0.00010286643708 0.00010730369114 0.00013925168171 0.00023542263863 0.00041196567225 0.00064268641369 0.00089765844343 0.00095782683814 0.00093194023455 0.00083024324287 0.00064877704953 0.0005799449756 0.00052324724076 0.00050293298128 0.00050031875576 0.00050002798873 0.00050000207839 0.00050000013394 0.00050000000766 0.00050000000036 0.00049999999993 0.0005 0.00050000000001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999707 0.00049999994819 0.00049999919273 0.00049998910001 0.00049987561594 0.00049883908845 0.00049157282018 0.00044910909081 0.00034699471565 0.0002328263497 0.00016399344501 0.00012167486631 0.00010482422292 0.00010288978668 0.00010286644246 0.0001073036619 0.00013925164986 0.00023542175342 0.00041196206392 0.00064268615223 0.00089765853424 0.00095782686849 0.00093194017162 0.00083024323763 0.00064877704068 0.00057994496615 0.0005232472331 0.00050293298124 0.00050031875597 0.0005000279887 0.00050000207839 0.00050000013393 0.00050000000766 0.00050000000036 0.00049999999993 0.0005 0.00050000000001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999707 0.00049999994819 0.00049999919273 0.00049998910001 0.00049987561594 0.00049883908845 0.00049157282018 0.00044910909081 0.00034699471567 0.00023282634984 0.00016399344462 0.00012167486645 0.00010482422331 0.00010288978733 0.00010286644474 0.00010730366821 0.00013925163976 0.00023542180193 0.00041196190182 0.00064268623555 0.00089765854856 0.00095782685632 0.00093194018488 0.00083024324898 0.00064877703658 0.00057994496089 0.00052324723279 0.00050293298149 0.00050031875594 0.00050002798869 0.00050000207839 0.00050000013394 0.00050000000766 0.00050000000036 0.00049999999993 0.0005 0.00050000000001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999707 0.00049999994819 0.00049999919273 0.00049998910001 0.00049987561594 0.00049883908845 0.00049157282018 0.0004491090908 0.00034699471569 0.00023282634981 0.00016399344459 0.0001216748665 0.00010482422335 0.00010288978701 0.00010286644435 0.00010730366997 0.00013925164591 0.00023542181703 0.00041196196915 0.00064268622923 0.00089765853821 0.00095782685507 0.0009319401886 0.00083024324889 0.00064877703711 0.00057994496164 0.00052324723311 0.00050293298146 0.00050031875593 0.0005000279887 0.00050000207839 0.00050000013393 0.00050000000766 0.00050000000036 0.00049999999993 0.0005 0.00050000000001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999707 0.00049999994819 0.00049999919273 0.00049998910001 0.00049987561594 0.00049883908845 0.00049157282018 0.0004491090908 0.00034699471568 0.00023282634981 0.00016399344462 0.00012167486649 0.00010482422332 0.00010288978702 0.00010286644428 0.00010730366952 0.00013925164603 0.00023542181061 0.00041196196172 0.00064268622343 0.00089765853776 0.00095782685564 0.00093194018774 0.00083024324835 0.00064877703725 0.00057994496182 0.00052324723309 0.00050293298145 0.00050031875593 0.0005000279887 0.00050000207839 0.00050000013393 0.00050000000766 0.00050000000036 0.00049999999993 0.0005 0.00050000000001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999707 0.00049999994819 0.00049999919273 0.00049998910001 0.00049987561594 0.00049883908845 0.00049157282018 0.0004491090908 0.00034699471568 0.00023282634981 0.00016399344462 0.00012167486649 0.00010482422332 0.00010288978703 0.00010286644431 0.00010730366948 0.00013925164568 0.00023542180956 0.00041196195701 0.000642686224 0.00089765853821 0.00095782685564 0.00093194018767 0.00083024324841 0.00064877703721 0.00057994496176 0.00052324723307 0.00050293298145 0.00050031875593 0.0005000279887 0.00050000207839 0.00050000013394 0.00050000000766 0.00050000000036 0.00049999999993 0.0005 0.00050000000001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999707 0.00049999994819 0.00049999919273 0.00049998910001 0.00049987561594 0.00049883908845 0.00049157282018 0.0004491090908 0.00034699471568 0.00023282634981 0.00016399344462 0.00012167486649 0.00010482422332 0.00010288978703 0.00010286644431 0.00010730366951 0.00013925164573 0.00023542180991 0.00041196195769 0.0006426862242 0.00089765853819 0.00095782685561 0.00093194018772 0.00083024324844 0.0006487770372 0.00057994496176 0.00052324723308 0.00050293298145 0.00050031875593 0.0005000279887 0.00050000207839 0.00050000013393 0.00050000000766 0.00050000000036 0.00049999999993 0.0005 0.00050000000001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999707 0.00049999994819 0.00049999919273 0.00049998910001 0.00049987561594 0.00049883908845 0.00049157282018 0.0004491090908 0.00034699471568 0.00023282634981 0.00016399344462 0.00012167486649 0.00010482422332 0.00010288978703 0.00010286644431 0.00010730366951 0.00013925164575 0.00023542180993 0.00041196195783 0.00064268622414 0.00089765853817 0.00095782685561 0.00093194018772 0.00083024324843 0.0006487770372 0.00057994496176 0.00052324723308 0.00050293298145 0.00050031875593 0.0005000279887 0.00050000207839 0.00050000013393 0.00050000000766 0.00050000000036 0.00049999999993 0.0005 0.00050000000001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999707 0.00049999994819 0.00049999919273 0.00049998910001 0.00049987561594 0.00049883908845 0.00049157282018 0.0004491090908 0.00034699471568 0.00023282634981 0.00016399344462 0.00012167486649 0.00010482422332 0.00010288978703 0.00010286644431 0.00010730366951 0.00013925164574 0.00023542180991 0.00041196195778 0.00064268622414 0.00089765853817 0.00095782685561 0.00093194018772 0.00083024324843 0.0006487770372 0.00057994496176 0.00052324723308 0.00050293298145 0.00050031875593 0.0005000279887 0.00050000207839 0.00050000013394 0.00050000000766 0.00050000000036 0.00049999999993 0.0005 0.00050000000001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999707 0.00049999994819 0.00049999919273 0.00049998910001 0.00049987561594 0.00049883908845 0.00049157282018 0.0004491090908 0.00034699471568 0.00023282634981 0.00016399344462 0.00012167486649 0.00010482422332 0.00010288978703 0.00010286644431 0.00010730366951 0.00013925164574 0.00023542180991 0.00041196195778 0.00064268622414 0.00089765853817 0.00095782685561 0.00093194018772 0.00083024324843 0.0006487770372 0.00057994496176 0.00052324723308 0.00050293298145 0.00050031875593 0.0005000279887 0.00050000207839 0.00050000013393 0.00050000000766 0.00050000000036 0.00049999999993 0.0005 0.00050000000001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999707 0.00049999994819 0.00049999919273 0.00049998910001 0.00049987561594 0.00049883908845 0.00049157282018 0.0004491090908 0.00034699471568 0.00023282634981 0.00016399344462 0.00012167486649 0.00010482422332 0.00010288978703 0.00010286644431 0.00010730366951 0.00013925164574 0.00023542180991 0.00041196195778 0.00064268622414 0.00089765853817 0.00095782685561 0.00093194018772 0.00083024324843 0.0006487770372 0.00057994496176 0.00052324723308 0.00050293298145 0.00050031875593 0.0005000279887 0.00050000207839 0.00050000013394 0.00050000000766 0.00050000000036 0.00049999999993 0.0005 0.00050000000001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999707 0.00049999994819 0.00049999919273 0.00049998910001 0.00049987561594 0.00049883908845 0.00049157282018 0.0004491090908 0.00034699471568 0.00023282634981 0.00016399344462 0.00012167486649 0.00010482422332 0.00010288978703 0.00010286644431 0.00010730366951 0.00013925164574 0.00023542180991 0.00041196195778 0.00064268622414 0.00089765853817 0.00095782685561 0.00093194018772 0.00083024324843 0.0006487770372 0.00057994496176 0.00052324723308 0.00050293298145 0.00050031875593 0.0005000279887 0.00050000207839 0.00050000013394 0.00050000000766 0.00050000000036 0.00049999999993 0.0005 0.00050000000001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999707 0.00049999994819 0.00049999919273 0.00049998910001 0.00049987561594 0.00049883908845 0.00049157282018 0.0004491090908 0.00034699471568 0.00023282634981 0.00016399344462 0.00012167486649 0.00010482422332 0.00010288978703 0.00010286644431 0.00010730366951 0.00013925164574 0.00023542180991 0.00041196195778 0.00064268622414 0.00089765853817 0.00095782685561 0.00093194018772 0.00083024324843 0.0006487770372 0.00057994496176 0.00052324723308 0.00050293298145 0.00050031875593 0.0005000279887 0.00050000207839 0.00050000013393 0.00050000000766 0.00050000000036 0.00049999999993 0.0005 0.00050000000001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999707 0.00049999994819 0.00049999919273 0.00049998910001 0.00049987561594 0.00049883908845 0.00049157282018 0.0004491090908 0.00034699471568 0.00023282634981 0.00016399344462 0.00012167486649 0.00010482422332 0.00010288978703 0.00010286644431 0.00010730366951 0.00013925164574 0.00023542180991 0.00041196195778 0.00064268622414 0.00089765853817 0.00095782685561 0.00093194018772 0.00083024324843 0.0006487770372 0.00057994496176 0.00052324723308 0.00050293298145 0.00050031875593 0.0005000279887 0.00050000207839 0.00050000013393 0.00050000000766 0.00050000000036 0.00049999999993 0.0005 0.00050000000001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999707 0.00049999994819 0.00049999919273 0.00049998910001 0.00049987561594 0.00049883908845 0.00049157282018 0.0004491090908 0.00034699471568 0.00023282634981 0.00016399344462 0.00012167486649 0.00010482422332 0.00010288978703 0.00010286644431 0.00010730366951 0.00013925164574 0.00023542180991 0.00041196195778 0.00064268622414 0.00089765853817 0.00095782685561 0.00093194018772 0.00083024324843 0.0006487770372 0.00057994496176 0.00052324723308 0.00050293298145 0.00050031875593 0.0005000279887 0.00050000207839 0.00050000013393 0.00050000000766 0.00050000000036 0.00049999999993 0.0005 0.00050000000001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999707 0.00049999994819 0.00049999919273 0.00049998910001 0.00049987561594 0.00049883908845 0.00049157282018 0.0004491090908 0.00034699471568 0.00023282634981 0.00016399344462 0.00012167486649 0.00010482422332 0.00010288978703 0.00010286644431 0.00010730366951 0.00013925164574 0.00023542180991 0.00041196195778 0.00064268622415 0.00089765853817 0.00095782685561 0.00093194018772 0.00083024324843 0.0006487770372 0.00057994496176 0.00052324723308 0.00050293298145 0.00050031875593 0.0005000279887 0.00050000207839 0.00050000013393 0.00050000000766 0.00050000000036 0.00049999999993 0.0005 0.00050000000001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999707 0.00049999994819 0.00049999919273 0.00049998910001 0.00049987561594 0.00049883908845 0.00049157282018 0.0004491090908 0.00034699471568 0.00023282634981 0.00016399344462 0.00012167486649 0.00010482422332 0.00010288978703 0.00010286644431 0.00010730366951 0.00013925164574 0.00023542180991 0.00041196195778 0.00064268622414 0.00089765853818 0.00095782685561 0.00093194018772 0.00083024324843 0.0006487770372 0.00057994496176 0.00052324723308 0.00050293298145 0.00050031875593 0.0005000279887 0.00050000207839 0.00050000013394 0.00050000000766 0.00050000000036 0.00049999999993 0.0005 0.00050000000001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999707 0.00049999994819 0.00049999919273 0.00049998910001 0.00049987561594 0.00049883908845 0.00049157282018 0.0004491090908 0.00034699471568 0.00023282634981 0.00016399344462 0.00012167486649 0.00010482422332 0.00010288978703 0.00010286644431 0.00010730366951 0.00013925164574 0.00023542180991 0.00041196195778 0.00064268622408 0.00089765853815 0.00095782685562 0.00093194018772 0.00083024324843 0.00064877703721 0.00057994496176 0.00052324723308 0.00050293298145 0.00050031875593 0.0005000279887 0.00050000207839 0.00050000013394 0.00050000000766 0.00050000000036 0.00049999999993 0.0005 0.00050000000001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999707 0.00049999994819 0.00049999919273 0.00049998910001 0.00049987561594 0.00049883908845 0.00049157282018 0.0004491090908 0.00034699471568 0.00023282634981 0.00016399344462 0.00012167486649 0.00010482422332 0.00010288978703 0.00010286644431 0.00010730366951 0.00013925164574 0.00023542180988 0.00041196195772 0.00064268622431 0.00089765853811 0.00095782685557 0.00093194018776 0.00083024324844 0.00064877703719 0.00057994496176 0.00052324723308 0.00050293298145 0.00050031875593 0.0005000279887 0.00050000207839 0.00050000013393 0.00050000000766 0.00050000000036 0.00049999999993 0.0005 0.00050000000001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999707 0.00049999994819 0.00049999919273 0.00049998910001 0.00049987561594 0.00049883908845 0.00049157282018 0.0004491090908 0.00034699471568 0.00023282634981 0.00016399344462 0.00012167486649 0.00010482422332 0.00010288978703 0.00010286644431 0.00010730366951 0.00013925164574 0.0002354218099 0.00041196195791 0.00064268622486 0.00089765853874 0.00095782685558 0.00093194018771 0.00083024324844 0.00064877703715 0.0005799449617 0.00052324723307 0.00050293298145 0.00050031875593 0.0005000279887 0.00050000207839 0.00050000013394 0.00050000000766 0.00050000000036 0.00049999999993 0.0005 0.00050000000001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999707 0.00049999994819 0.00049999919273 0.00049998910001 0.00049987561594 0.00049883908845 0.00049157282018 0.0004491090908 0.00034699471568 0.00023282634981 0.00016399344462 0.00012167486649 0.00010482422332 0.00010288978703 0.00010286644431 0.0001073036695 0.00013925164583 0.00023542181038 0.00041196195854 0.00064268621838 0.00089765853786 0.00095782685646 0.00093194018694 0.00083024324835 0.00064877703749 0.00057994496184 0.00052324723303 0.00050293298145 0.00050031875593 0.0005000279887 0.00050000207839 0.00050000013394 0.00050000000766 0.00050000000036 0.00049999999993 0.0005 0.00050000000001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999707 0.00049999994819 0.00049999919273 0.00049998910001 0.00049987561594 0.00049883908845 0.00049157282018 0.0004491090908 0.00034699471568 0.00023282634981 0.00016399344462 0.00012167486649 0.00010482422332 0.00010288978703 0.0001028664443 0.0001073036695 0.00013925164567 0.00023542180893 0.00041196195305 0.00064268621324 0.00089765852523 0.00095782685391 0.00093194018985 0.00083024324828 0.00064877703764 0.00057994496267 0.00052324723328 0.00050293298141 0.00050031875593 0.0005000279887 0.00050000207839 0.00050000013393 0.00050000000766 0.00050000000036 0.00049999999993 0.0005 0.00050000000001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999707 0.00049999994819 0.00049999919273 0.00049998910001 0.00049987561594 0.00049883908845 0.00049157282018 0.0004491090908 0.00034699471568 0.00023282634981 0.00016399344461 0.00012167486648 0.00010482422332 0.00010288978705 0.00010286644431 0.00010730366961 0.00013925164439 0.00023542180111 0.00041196194724 0.00064268630287 0.00089765855005 0.0009578268392 0.00093194020302 0.0008302432504 0.00064877702969 0.00057994495814 0.00052324723347 0.0005029329816 0.00050031875589 0.00050002798869 0.00050000207839 0.00050000013394 0.00050000000766 0.00050000000036 0.00049999999993 0.0005 0.00050000000001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999707 0.00049999994819 0.00049999919273 0.00049998910001 0.00049987561594 0.00049883908845 0.00049157282018 0.00044910909081 0.00034699471568 0.00023282634981 0.00016399344462 0.00012167486647 0.0001048242233 0.00010288978689 0.00010286644442 0.00010730366945 0.00013925164914 0.0002354218242 0.00041196202124 0.00064268598501 0.00089765861805 0.00095782689025 0.00093194015218 0.00083024325466 0.00064877702945 0.00057994494715 0.00052324722722 0.00050293298188 0.00050031875606 0.00050002798866 0.00050000207838 0.00050000013394 0.00050000000766 0.00050000000036 0.00049999999993 0.0005 0.00050000000001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999707 0.00049999994819 0.00049999919273 0.00049998910001 0.00049987561594 0.00049883908845 0.00049157282018 0.0004491090908 0.00034699471571 0.00023282634981 0.00016399344463 0.00012167486673 0.00010482422352 0.00010288978697 0.00010286644416 0.00010730366925 0.00013925165982 0.0002354218529 0.00041196180812 0.00064268052162 0.00089765739927 0.00095782687383 0.00093194015527 0.00083024320226 0.00064877711764 0.00057994501089 0.00052324722711 0.00050293297588 0.00050031875631 0.00050002798878 0.00050000207837 0.00050000013393 0.00050000000766 0.00050000000036 0.00049999999993 0.0005 0.00050000000001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999707 0.00049999994819 0.00049999919273 0.00049998910001 0.00049987561594 0.00049883908845 0.00049157282018 0.00044910909079 0.00034699471562 0.00023282635001 0.00016399344441 0.00012167486599 0.00010482422307 0.00010288979086 0.00010286644457 0.00010730366758 0.00013925154425 0.0002354205531 0.00041195770034 0.0006425836991 0.00089763769522 0.00095782479902 0.00093194222535 0.00083024335262 0.00064877674599 0.00057994494948 0.00052324730667 0.00050293297509 0.00050031875061 0.00050002798908 0.00050000207845 0.00050000013393 0.00050000000766 0.00050000000036 0.00049999999993 0.0005 0.00050000000001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999707 0.00049999994819 0.00049999919273 0.00049998910001 0.00049987561594 0.00049883908845 0.00049157282019 0.00044910909094 0.0003469947153 0.00023282634902 0.00016399344633 0.00012167486127 0.0001048242186 0.00010288978733 0.00010286644317 0.00010730366143 0.00013925169395 0.00023540412046 0.00041189047155 0.00064102088096 0.00089733445585 0.00095779220887 0.00093197436778 0.00083024683514 0.00064877218069 0.00057994248622 0.00052324690718 0.00050293305295 0.00050031874975 0.00050002798448 0.00050000207859 0.00050000013397 0.00050000000766 0.00050000000036 0.00049999999993 0.0005 0.00050000000001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999707 0.00049999994819 0.00049999919273 0.00049998910001 0.00049987561594 0.00049883908845 0.00049157282016 0.00044910909075 0.00034699471771 0.00023282634515 0.00016399344704 0.00012167487733 0.00010482423389 0.00010288972884 0.00010286640621 0.00010730413722 0.00013925931856 0.00023518766218 0.00041088138396 0.00061917726083 0.00089334632196 0.00095731799813 0.00093246490887 0.00083032676247 0.00064872118041 0.00057990699828 0.0005232408051 0.00050293258748 0.00050031882068 0.00050002798065 0.00050000207573 0.00050000013386 0.00050000000766 0.00050000000036 0.00049999999993 0.0005 0.00050000000001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999707 0.00049999994819 0.00049999919273 0.00049998910001 0.00049987561593 0.00049883908843 0.00049157281999 0.00044910908691 0.00034699471955 0.00023282636283 0.00016399340337 0.00012167487103 0.00010482424814 0.00010289039064 0.00010286693119 0.00010731739879 0.00013948541143 0.00023286951328 0.0003980518985 0.00036133067716 0.00085026809041 0.00095145986053 0.00093899060562 0.00083175078887 0.00064830043471 0.0005794185778 0.0005231440218 0.00050292659366 0.00050031834125 0.00050002804075 0.00050000207065 0.00050000013264 0.00050000000758 0.00050000000036 0.00049999999993 0.0005 0.00050000000001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999707 0.00049999994819 0.00049999919273 0.00049998910001 0.00049987561594 0.00049883908849 0.00049157282085 0.00044910909436 0.00034699469771 0.00023282639276 0.00016399364292 0.00012167344933 0.00010482278045 0.00010290072507 0.00010287571652 0.00010758472127 0.0001437888019 0.00021275090764 0.00026408818107 -0.00211414609599 0.00049267555083 0.00089213406742 0.00101302235377 0.00085176249815 0.00064708376379 0.00057392707367 0.00052188124698 0.00050284511925 0.00050031307217 0.00050002766995 0.00050000211262 0.00050000013395 0.00050000000756 0.00050000000035 0.00049999999993 0.0005 0.00050000000001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999707 0.00049999994819 0.00049999919273 0.00049998910001 0.00049987561597 0.00049883908889 0.00049157282389 0.00044910912568 0.00034699457851 0.0002328256971 0.00016399678122 0.00012165149819 0.00010479415158 0.00010309172017 0.00010301760133 0.00011173953791 0.00020747459276 0.00013312534548 -0.00088238274908 -0.02222917639537 -0.00167003108873 0.00040770767619 0.00170541550031 0.00107249769555 0.00066741409383 0.00052455648191 0.0005091460447 0.0005019744005 0.00050025378655 0.00050002419339 0.00050000191963 0.00050000014416 0.00050000000888 0.00050000000039 0.00049999999992 0.00050000000001 0.00050000000001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999707 0.00049999994819 0.00049999919273 0.00049998910001 0.00049987561591 0.00049883908756 0.00049157280293 0.00044910869595 0.00034699585226 0.00023282277758 0.00016404329824 0.00012129314816 0.00010425915152 0.0001060357234 0.0001044504496 0.00016269507418 0.00096235092752 0.00037642565462 -0.00651235378604 -0.0983402839119 -0.0067821385256 -0.00194595940128 0.00696168898921 0.0029502228706 0.00099168388362 0.00025886584804 0.00041990533496 0.0004954491488 0.00049978291097 0.00049999508392 0.0005000001914 0.00050000006092 0.00050000000855 0.00050000000048 0.0004999999999 0.0005 0.00050000000001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999707 0.00049999994819 0.00049999919273 0.00049998909999 0.00049987561573 0.00049883908574 0.00049157272551 0.00044910601228 0.00034699885153 0.00023292658444 0.00016451848764 0.00011823197413 9.867472175e-05 0.00012746245272 0.00011415500399 0.00054901825874 0.00619859884769 0.00450618766193 -0.0163880169121 0.0 0.0 -0.00244954296323 0.02567434108666 0.01748088086668 0.00441060932187 -0.00011923941115 0.00012953700114 0.00047161409042 0.00049789555764 0.00049986941751 0.00049999273692 0.00049999940243 0.00049999995282 0.0004999999979 0.0005000000003 0.00050000000001 0.00049999999997 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999707 0.00049999994819 0.00049999919273 0.00049998910004 0.00049987561669 0.00049883910521 0.00049157311042 0.00044911072737 0.00034702761124 0.0002328385069 0.0001655397501 0.0001222319368 9.715227937e-05 0.00010916557989 0.00015097441792 0.0006898393982 0.00654897956809 0.0 0.0 0.0 0.0 0.0 0.0 0.04752601990241 0.01635971299471 0.00366547523487 0.00059060154539 0.00049798232223 0.00049956674149 0.00049996387914 0.00049999812012 0.00050000011226 0.00049999998942 0.00049999999832 0.00050000000071 0.00049999999995 0.00049999999995 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999707 0.00049999994819 0.00049999919276 0.00049998910065 0.00049987562759 0.00049883926883 0.00049157513742 0.00044914425433 0.00034699357285 0.00023284206648 0.00016423032964 0.00012948364445 9.933510893e-05 0.00010414865666 0.00010204425873 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.06532225788682 0.0383571806851 0.02450482107658 0.00577460231474 0.00097588975631 0.00054029314625 0.00050288505285 0.00050017968168 0.0005000101257 0.00050000057797 0.00050000002741 0.00049999999345 0.00050000000045 0.00050000000053 0.00049999999996 0.00049999999998 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999707 0.00049999994819 0.00049999919274 0.00049998910016 0.0004998756187 0.00049883913298 0.00049157321339 0.00044910924838 0.00034698868573 0.00023282606046 0.00016380119814 0.00012554192407 0.00010483719694 0.00010412907315 2.97432584e-05 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.05011334460435 0.02670876593182 0.00483758677413 0.0009592469197 0.00054227682828 0.00050326194399 0.00050021685489 0.00050001271984 0.00050000066448 0.00050000002245 0.00049999998956 0.00050000000174 0.0005000000007 0.00049999999989 0.00049999999998 0.00050000000001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999707 0.00049999994818 0.0004999991927 0.00049998909927 0.00049987560247 0.0004988388805 0.00049157039182 0.00044907578789 0.00034702357588 0.00023277424199 0.00016434153568 0.00011332372547 0.00010688953475 0.00010549746747 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.01171502421791 0.00377862456534 0.0011615151556 0.00056215846284 0.00050559223592 0.00050043492643 0.00050002953944 0.00050000164176 0.00050000007265 0.0004999999983 0.00049999999772 0.00050000000071 0.0005000000001 0.00049999999996 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999707 0.00049999994819 0.00049999919271 0.00049998909964 0.00049987560886 0.00049883897248 0.00049157117609 0.0004490843297 0.00034700786073 0.00023284556313 0.00016433916166 0.0001157670588 0.00010533401527 0.00010885040785 0.0 0.0 0.0 0.0 0.0 D/cons.4.00.000000.dat 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 -D/cons.4.00.000050.dat 0.0 0.0 0.0 0.0 0.0 0.03175646939529 0.01345542992285 0.00293204170109 0.00039795733159 4.370728105e-05 3.91972831e-06 2.9688179e-07 1.946627e-08 1.20202e-09 -7.465e-11 -1.652e-11 1.284e-11 7.2e-13 -6.8e-13 5e-14 3e-14 -1e-14 -0.0 -0.0 6e-14 -9e-14 -8.5e-13 4.06e-12 1.276e-11 -5.7e-11 9.601e-11 3.57649e-09 6.132508e-08 9.5514117e-07 1.289677289e-05 0.00014714167637 0.00137112081125 0.00986041263008 0.05608479382184 0.14748820995098 0.16849521383338 0.08757749006526 0.02573968391493 0.00285394202037 0.00039221234722 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.04126932924153 0.0233479966285 0.00678014957125 0.00090077328911 0.00010270764814 9.41563849e-06 7.2450666e-07 4.799628e-08 2.87018e-09 5.133e-11 -4.752e-11 1.294e-11 3.22e-12 -8.1e-13 -5e-14 5e-14 -0.0 -0.0 -0.0 6e-14 -9e-14 -8.5e-13 4.06e-12 1.276e-11 -5.7e-11 9.601e-11 3.57649e-09 6.132508e-08 9.5514114e-07 1.28967723e-05 0.00014714166883 0.00137112080387 0.00986041652959 0.05608488075783 0.147488758441 0.16849455518105 0.08757646564889 0.02577372712047 0.00288206695592 0.000253350454 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.08320769040331 0.14384110567237 0.07792363296143 0.02637361134487 0.00320330687143 0.0003434930572 3.012656142e-05 2.23727986e-06 1.44299e-07 8.31608e-09 4.2347e-10 -8.846e-11 5.79e-12 7.78e-12 -6e-13 -2.9e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.06e-12 1.276e-11 -5.7e-11 9.601e-11 3.57649e-09 6.132507e-08 9.5514097e-07 1.289676908e-05 0.00014714161459 0.00137112002891 0.00986040666302 0.05608476795222 0.14748845891829 0.16849688724405 0.08757612587672 0.02577643221467 0.0028594272149 0.00032588315209 2.582194075e-05 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.11882306522179 0.16132188442171 0.09457193298668 0.03174139739139 0.00383132862788 0.00040727326193 3.541752738e-05 2.60991334e-06 1.6715442e-07 9.54545e-09 5.0067e-10 -9.006e-11 3.76e-12 8.33e-12 -5.2e-13 -3.2e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.06e-12 1.276e-11 -5.7e-11 9.601e-11 3.57649e-09 6.132508e-08 9.551412e-07 1.289677344e-05 0.00014714168501 0.00137112094263 0.00986041517864 0.0560848312957 0.14748844026931 0.16849543397029 0.08757845104619 0.02575987281364 0.00284350435039 0.00036441200091 -5.879441335e-05 0.0 0.0 0.0 0.0 0.0 0.0 0.00293799500315 0.07938738234463 0.19775503284989 0.18480493367976 0.09821522378759 0.02935889048801 0.00356756853098 0.00038430911964 3.362351548e-05 2.49066608e-06 1.602618e-07 9.18699e-09 4.7823e-10 -8.977e-11 4.4e-12 8.18e-12 -5.5e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.06e-12 1.276e-11 -5.7e-11 9.601e-11 3.57649e-09 6.132509e-08 9.5514127e-07 1.289677492e-05 0.00014714170984 0.00137112126607 0.00986041776012 0.05608484310162 0.1474883209046 0.16849397746271 0.08757687857743 0.02573154209658 0.00285108673439 0.00040746551263 -0.0002626961267 -0.00191615667354 -0.01020512783606 0.0 0.0 -0.28976421434607 -0.10635972996776 -0.00444613379317 0.08279840390382 0.20257702695595 0.18757728043386 0.09872070816104 0.02879227821857 0.00350861621685 0.00037880006062 3.320639514e-05 2.46420678e-06 1.5876318e-07 9.10557e-09 4.7282e-10 -8.965e-11 4.54e-12 8.13e-12 -5.6e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.06e-12 1.276e-11 -5.7e-11 9.601e-11 3.57649e-09 6.132509e-08 9.5514129e-07 1.289677521e-05 0.00014714171308 0.00137112135451 0.009860422962 0.05608494471003 0.14748901836641 0.16849348170237 0.08756776750988 0.02577356567414 0.00286812630968 0.00035143669158 -0.00067939285949 -0.00549730841311 -0.05290555969673 -0.21190848109095 -0.41603615041886 -0.30994944904394 -0.11685972638578 -0.00820021260153 0.08245482303754 0.2041501287416 0.18823792128335 0.09864146088779 0.02864537816129 0.00349500385866 0.00037766201716 3.312804444e-05 2.45957973e-06 1.5851979e-07 9.095e-09 4.724e-10 -8.965e-11 4.54e-12 8.13e-12 -5.6e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.06e-12 1.276e-11 -5.7e-11 9.601e-11 3.57649e-09 6.132509e-08 9.551413e-07 1.289677527e-05 0.00014714171417 0.00137112138013 0.00986042380701 0.05608495853484 0.14748910604344 0.16849331781319 0.08756756223286 0.02577689741352 0.00286341851508 0.00034545199173 -0.00070931328131 -0.00587967884441 -0.05488397628023 -0.20978683828578 -0.41055361049454 -0.30736272604818 -0.11888907549261 -0.00885354594064 0.08246443377367 0.20433332969255 0.18828810177625 0.09863322648774 0.02863001700041 0.0034936701914 0.00037755558774 3.312090148e-05 2.45919765e-06 1.5850872e-07 9.09536e-09 4.7248e-10 -8.966e-11 4.54e-12 8.14e-12 -5.6e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.06e-12 1.276e-11 -5.7e-11 9.601e-11 3.57649e-09 6.132509e-08 9.551413e-07 1.289677528e-05 0.00014714171432 0.00137112138276 0.00986042388135 0.05608495973299 0.14748911837158 0.16849329091425 0.08756755838359 0.02577729812798 0.002862683809 0.00034473233761 -0.0007129546583 -0.00594983184858 -0.05525162142588 -0.20825476990535 -0.40287264940442 -0.3068866180226 -0.11909420173658 -0.00892222803744 0.08246930503967 0.20435181184954 0.18829118617885 0.09863236218877 0.0286286668093 0.00349356160732 0.00037754734736 3.312039384e-05 2.45918059e-06 1.5850863e-07 9.09531e-09 4.7247e-10 -8.966e-11 4.54e-12 8.14e-12 -5.6e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.06e-12 1.276e-11 -5.7e-11 9.601e-11 3.57649e-09 6.132509e-08 9.551413e-07 1.289677528e-05 0.00014714171432 0.00137112138291 0.00986042388625 0.05608495981513 0.14748911923517 0.16849328835208 0.08756755841194 0.0257773204052 0.00286264701434 0.00034467333896 -0.00071327784077 -0.00595650641621 -0.05528432230704 -0.20801314283949 -0.40163815438284 -0.30682821970483 -0.11911128755671 -0.00892810161076 0.08246996303913 0.20435333298064 0.18829131002708 0.09863227820206 0.02862856521176 0.00349355410825 0.00037754681961 3.312037888e-05 2.4591799e-06 1.5850818e-07 9.09525e-09 4.7246e-10 -8.966e-11 4.54e-12 8.14e-12 -5.6e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.06e-12 1.276e-11 -5.7e-11 9.601e-11 3.57649e-09 6.132509e-08 9.551413e-07 1.289677528e-05 0.00014714171432 0.00137112138292 0.00986042388661 0.05608495982319 0.14748911926007 0.16849328818613 0.08756755845799 0.02577732146991 0.00286264548906 0.00034466922536 -0.00071330130728 -0.00595702602519 -0.05528654721764 -0.20798572737886 -0.40150409853683 -0.30682285064311 -0.11911246424348 -0.00892851906855 0.08247002290676 0.20435343877191 0.18829131085553 0.09863227145281 0.02862855859392 0.00349355365691 0.00037754681232 3.312037851e-05 2.45917911e-06 1.5850808e-07 9.09525e-09 4.7246e-10 -8.966e-11 4.54e-12 8.14e-12 -5.6e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.06e-12 1.276e-11 -5.7e-11 9.601e-11 3.57649e-09 6.132509e-08 9.551413e-07 1.289677528e-05 0.00014714171433 0.00137112138293 0.0098604238867 0.05608495982303 0.14748911925026 0.16849328822048 0.08756755844091 0.02577732147351 0.00286264548853 0.00034466900473 -0.00071330276035 -0.00595706023 -0.05528665570975 -0.20798318695735 -0.40149208185766 -0.30682244779549 -0.11911253346856 -0.008928544609 0.08247002710855 0.20435344521212 0.18829131049767 0.09863227095201 0.02862855818032 0.00349355365796 0.00037754681317 3.312037748e-05 2.45917902e-06 1.5850809e-07 9.09525e-09 4.7246e-10 -8.966e-11 4.54e-12 8.14e-12 -5.6e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.06e-12 1.276e-11 -5.7e-11 9.601e-11 3.57649e-09 6.132509e-08 9.551413e-07 1.289677528e-05 0.00014714171433 0.00137112138293 0.00986042388672 0.05608495982295 0.14748911925298 0.16849328821859 0.08756755843209 0.02577732146857 0.00286264550403 0.00034466900413 -0.00071330283038 -0.00595706220945 -0.05528665949939 -0.20798299042998 -0.40149118219944 -0.30682242211423 -0.11911253707403 -0.00892854603675 0.08247002741112 0.20435344559805 0.18829131041827 0.09863227093151 0.02862855820036 0.00349355365952 0.00037754681178 3.312037738e-05 2.45917904e-06 1.5850809e-07 9.09525e-09 4.7246e-10 -8.966e-11 4.54e-12 8.14e-12 -5.6e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.06e-12 1.276e-11 -5.7e-11 9.601e-11 3.57649e-09 6.132509e-08 9.551413e-07 1.289677528e-05 0.00014714171433 0.00137112138293 0.00986042388672 0.05608495982301 0.14748911925366 0.16849328821482 0.08756755843521 0.02577732147206 0.00286264550064 0.00034466900404 -0.00071330282557 -0.00595706229016 -0.05528665949975 -0.20798297731933 -0.40149112447708 -0.30682242064291 -0.11911253729432 -0.0089285460565 0.08247002747176 0.20435344554625 0.18829131041241 0.09863227094718 0.02862855820763 0.00349355365813 0.00037754681168 3.312037741e-05 2.45917904e-06 1.5850809e-07 9.09525e-09 4.7246e-10 -8.966e-11 4.54e-12 8.14e-12 -5.6e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.06e-12 1.276e-11 -5.7e-11 9.601e-11 3.57649e-09 6.132509e-08 9.551413e-07 1.289677528e-05 0.00014714171433 0.00137112138293 0.00986042388672 0.05608495982301 0.14748911925352 0.16849328821497 0.08756755843571 0.02577732147255 0.00286264549936 0.000344669003 -0.0007133028258 -0.00595706228852 -0.05528665948821 -0.20798297657609 -0.40149112116764 -0.3068224205565 -0.1191125372754 -0.00892854604262 0.0824700274603 0.20435344554184 0.18829131041725 0.09863227094523 0.02862855820423 0.00349355365799 0.00037754681172 3.31203774e-05 2.45917904e-06 1.5850809e-07 9.09525e-09 4.7246e-10 -8.966e-11 4.54e-12 8.14e-12 -5.6e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.06e-12 1.276e-11 -5.7e-11 9.601e-11 3.57649e-09 6.132509e-08 9.551413e-07 1.289677528e-05 0.00014714171433 0.00137112138293 0.00986042388672 0.05608495982301 0.14748911925351 0.16849328821513 0.08756755843555 0.02577732147236 0.00286264549959 0.00034466900296 -0.00071330282646 -0.00595706229082 -0.05528665949138 -0.2079829765914 -0.40149112099185 -0.30682242058036 -0.1191125372716 -0.00892854604675 0.08247002745814 0.20435344554734 0.18829131041713 0.09863227094423 0.02862855820385 0.00349355365802 0.00037754681171 3.31203774e-05 2.45917904e-06 1.5850809e-07 9.09525e-09 4.7246e-10 -8.966e-11 4.54e-12 8.14e-12 -5.6e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.06e-12 1.276e-11 -5.7e-11 9.601e-11 3.57649e-09 6.132509e-08 9.551413e-07 1.289677528e-05 0.00014714171433 0.00137112138293 0.00986042388672 0.05608495982301 0.14748911925352 0.1684932882151 0.08756755843554 0.02577732147236 0.00286264549962 0.000344669003 -0.00071330282642 -0.00595706229109 -0.05528665949262 -0.20798297660666 -0.40149112105786 -0.30682242057942 -0.11911253727341 -0.00892854604763 0.08247002745888 0.20435344554743 0.1882913104169 0.09863227094437 0.02862855820401 0.00349355365802 0.00037754681171 3.31203774e-05 2.45917904e-06 1.5850809e-07 9.09525e-09 4.7246e-10 -8.966e-11 4.54e-12 8.14e-12 -5.6e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.06e-12 1.276e-11 -5.7e-11 9.601e-11 3.57649e-09 6.132509e-08 9.551413e-07 1.289677528e-05 0.00014714171433 0.00137112138293 0.00986042388672 0.05608495982301 0.14748911925352 0.16849328821509 0.08756755843555 0.02577732147237 0.0028626454996 0.00034466900299 -0.00071330282639 -0.00595706229096 -0.05528665949204 -0.20798297660033 -0.40149112105088 -0.30682242057758 -0.11911253727355 -0.00892854604744 0.08247002745891 0.20435344554719 0.18829131041693 0.0986322709444 0.02862855820401 0.00349355365802 0.00037754681171 3.31203774e-05 2.45917904e-06 1.5850809e-07 9.09525e-09 4.7246e-10 -8.966e-11 4.54e-12 8.14e-12 -5.6e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.06e-12 1.276e-11 -5.7e-11 9.601e-11 3.57649e-09 6.132509e-08 9.551413e-07 1.289677528e-05 0.00014714171433 0.00137112138293 0.00986042388672 0.05608495982301 0.14748911925352 0.1684932882151 0.08756755843555 0.02577732147237 0.0028626454996 0.00034466900299 -0.0007133028264 -0.00595706229096 -0.05528665949194 -0.20798297659944 -0.40149112104638 -0.3068224205777 -0.11911253727347 -0.00892854604743 0.08247002745888 0.20435344554721 0.18829131041694 0.09863227094439 0.028628558204 0.00349355365802 0.00037754681171 3.31203774e-05 2.45917904e-06 1.5850809e-07 9.09525e-09 4.7246e-10 -8.966e-11 4.54e-12 8.14e-12 -5.6e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.06e-12 1.276e-11 -5.7e-11 9.601e-11 3.57649e-09 6.132509e-08 9.551413e-07 1.289677528e-05 0.00014714171433 0.00137112138293 0.00986042388672 0.05608495982301 0.14748911925352 0.1684932882151 0.08756755843555 0.02577732147237 0.0028626454996 0.00034466900299 -0.0007133028264 -0.00595706229097 -0.05528665949198 -0.20798297659976 -0.401491121047 -0.30682242057777 -0.11911253727347 -0.00892854604744 0.08247002745888 0.20435344554722 0.18829131041693 0.09863227094439 0.028628558204 0.00349355365802 0.00037754681171 3.31203774e-05 2.45917904e-06 1.5850809e-07 9.09525e-09 4.7246e-10 -8.966e-11 4.54e-12 8.14e-12 -5.6e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.06e-12 1.276e-11 -5.7e-11 9.601e-11 3.57649e-09 6.132509e-08 9.551413e-07 1.289677528e-05 0.00014714171433 0.00137112138293 0.00986042388672 0.05608495982301 0.14748911925352 0.1684932882151 0.08756755843555 0.02577732147237 0.0028626454996 0.00034466900299 -0.0007133028264 -0.00595706229097 -0.05528665949199 -0.20798297659977 -0.40149112104714 -0.30682242057776 -0.11911253727347 -0.00892854604744 0.08247002745888 0.20435344554722 0.18829131041693 0.09863227094439 0.028628558204 0.00349355365802 0.00037754681171 3.31203774e-05 2.45917904e-06 1.5850809e-07 9.09525e-09 4.7246e-10 -8.966e-11 4.54e-12 8.14e-12 -5.6e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.06e-12 1.276e-11 -5.7e-11 9.601e-11 3.57649e-09 6.132509e-08 9.551413e-07 1.289677528e-05 0.00014714171433 0.00137112138293 0.00986042388672 0.05608495982301 0.14748911925352 0.1684932882151 0.08756755843555 0.02577732147237 0.0028626454996 0.00034466900299 -0.0007133028264 -0.00595706229097 -0.05528665949198 -0.20798297659975 -0.40149112104709 -0.30682242057776 -0.11911253727347 -0.00892854604744 0.08247002745888 0.20435344554722 0.18829131041693 0.09863227094439 0.028628558204 0.00349355365802 0.00037754681171 3.31203774e-05 2.45917904e-06 1.5850809e-07 9.09525e-09 4.7246e-10 -8.966e-11 4.54e-12 8.14e-12 -5.6e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.06e-12 1.276e-11 -5.7e-11 9.601e-11 3.57649e-09 6.132509e-08 9.551413e-07 1.289677528e-05 0.00014714171433 0.00137112138293 0.00986042388672 0.05608495982301 0.14748911925352 0.1684932882151 0.08756755843555 0.02577732147237 0.0028626454996 0.00034466900299 -0.0007133028264 -0.00595706229097 -0.05528665949198 -0.20798297659975 -0.40149112104708 -0.30682242057776 -0.11911253727347 -0.00892854604744 0.08247002745888 0.20435344554722 0.18829131041693 0.09863227094439 0.028628558204 0.00349355365802 0.00037754681171 3.31203774e-05 2.45917904e-06 1.5850809e-07 9.09525e-09 4.7246e-10 -8.966e-11 4.54e-12 8.14e-12 -5.6e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.06e-12 1.276e-11 -5.7e-11 9.601e-11 3.57649e-09 6.132509e-08 9.551413e-07 1.289677528e-05 0.00014714171433 0.00137112138293 0.00986042388672 0.05608495982301 0.14748911925352 0.1684932882151 0.08756755843555 0.02577732147237 0.0028626454996 0.00034466900299 -0.0007133028264 -0.00595706229097 -0.05528665949198 -0.20798297659975 -0.40149112104709 -0.30682242057776 -0.11911253727347 -0.00892854604744 0.08247002745888 0.20435344554722 0.18829131041693 0.09863227094439 0.028628558204 0.00349355365802 0.00037754681171 3.31203774e-05 2.45917904e-06 1.5850809e-07 9.09525e-09 4.7246e-10 -8.966e-11 4.54e-12 8.14e-12 -5.6e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.06e-12 1.276e-11 -5.7e-11 9.601e-11 3.57649e-09 6.132509e-08 9.551413e-07 1.289677528e-05 0.00014714171433 0.00137112138293 0.00986042388672 0.05608495982301 0.14748911925352 0.1684932882151 0.08756755843555 0.02577732147237 0.0028626454996 0.00034466900299 -0.0007133028264 -0.00595706229097 -0.05528665949198 -0.20798297659975 -0.40149112104709 -0.30682242057776 -0.11911253727347 -0.00892854604744 0.08247002745888 0.20435344554722 0.18829131041693 0.09863227094439 0.028628558204 0.00349355365802 0.00037754681171 3.31203774e-05 2.45917904e-06 1.5850809e-07 9.09525e-09 4.7246e-10 -8.966e-11 4.54e-12 8.14e-12 -5.6e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.06e-12 1.276e-11 -5.7e-11 9.601e-11 3.57649e-09 6.132509e-08 9.551413e-07 1.289677528e-05 0.00014714171433 0.00137112138293 0.00986042388672 0.05608495982301 0.14748911925352 0.1684932882151 0.08756755843555 0.02577732147237 0.0028626454996 0.00034466900299 -0.0007133028264 -0.00595706229097 -0.05528665949198 -0.20798297659975 -0.40149112104709 -0.30682242057776 -0.11911253727347 -0.00892854604744 0.08247002745888 0.20435344554722 0.18829131041693 0.09863227094439 0.028628558204 0.00349355365802 0.00037754681171 3.31203774e-05 2.45917904e-06 1.5850809e-07 9.09525e-09 4.7246e-10 -8.966e-11 4.54e-12 8.14e-12 -5.6e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.06e-12 1.276e-11 -5.7e-11 9.601e-11 3.57649e-09 6.132509e-08 9.551413e-07 1.289677528e-05 0.00014714171433 0.00137112138293 0.00986042388672 0.05608495982301 0.14748911925352 0.1684932882151 0.08756755843555 0.02577732147237 0.0028626454996 0.00034466900299 -0.0007133028264 -0.00595706229097 -0.05528665949198 -0.20798297659975 -0.40149112104709 -0.30682242057776 -0.11911253727347 -0.00892854604744 0.08247002745888 0.20435344554722 0.18829131041693 0.09863227094439 0.028628558204 0.00349355365802 0.00037754681171 3.31203774e-05 2.45917904e-06 1.5850809e-07 9.09525e-09 4.7246e-10 -8.966e-11 4.54e-12 8.14e-12 -5.6e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.06e-12 1.276e-11 -5.7e-11 9.601e-11 3.57649e-09 6.132509e-08 9.551413e-07 1.289677528e-05 0.00014714171433 0.00137112138293 0.00986042388672 0.05608495982301 0.14748911925352 0.1684932882151 0.08756755843555 0.02577732147237 0.0028626454996 0.00034466900299 -0.0007133028264 -0.00595706229097 -0.05528665949198 -0.20798297659975 -0.40149112104709 -0.30682242057776 -0.11911253727347 -0.00892854604744 0.08247002745888 0.20435344554722 0.18829131041693 0.09863227094439 0.028628558204 0.00349355365802 0.00037754681171 3.31203774e-05 2.45917904e-06 1.5850809e-07 9.09525e-09 4.7246e-10 -8.966e-11 4.54e-12 8.14e-12 -5.6e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.06e-12 1.276e-11 -5.7e-11 9.601e-11 3.57649e-09 6.132509e-08 9.551413e-07 1.289677528e-05 0.00014714171433 0.00137112138293 0.00986042388672 0.05608495982301 0.14748911925352 0.1684932882151 0.08756755843555 0.02577732147237 0.0028626454996 0.00034466900299 -0.0007133028264 -0.00595706229097 -0.05528665949198 -0.20798297659975 -0.40149112104709 -0.30682242057776 -0.11911253727347 -0.00892854604744 0.08247002745888 0.20435344554722 0.18829131041693 0.09863227094439 0.028628558204 0.00349355365802 0.00037754681171 3.31203774e-05 2.45917904e-06 1.5850809e-07 9.09525e-09 4.7246e-10 -8.966e-11 4.54e-12 8.14e-12 -5.6e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.06e-12 1.276e-11 -5.7e-11 9.601e-11 3.57649e-09 6.132509e-08 9.551413e-07 1.289677528e-05 0.00014714171433 0.00137112138293 0.00986042388672 0.05608495982301 0.14748911925352 0.1684932882151 0.08756755843555 0.02577732147237 0.0028626454996 0.00034466900299 -0.0007133028264 -0.00595706229097 -0.05528665949198 -0.20798297659975 -0.40149112104708 -0.30682242057776 -0.11911253727347 -0.00892854604744 0.08247002745888 0.20435344554722 0.18829131041693 0.09863227094439 0.028628558204 0.00349355365802 0.00037754681171 3.31203774e-05 2.45917904e-06 1.5850809e-07 9.09525e-09 4.7246e-10 -8.966e-11 4.54e-12 8.14e-12 -5.6e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.06e-12 1.276e-11 -5.7e-11 9.601e-11 3.57649e-09 6.132509e-08 9.551413e-07 1.289677528e-05 0.00014714171433 0.00137112138293 0.00986042388672 0.05608495982301 0.14748911925352 0.1684932882151 0.08756755843555 0.02577732147237 0.0028626454996 0.00034466900299 -0.0007133028264 -0.00595706229097 -0.05528665949198 -0.20798297659975 -0.40149112104709 -0.30682242057777 -0.11911253727347 -0.00892854604744 0.08247002745888 0.20435344554722 0.18829131041693 0.09863227094439 0.028628558204 0.00349355365802 0.00037754681171 3.31203774e-05 2.45917904e-06 1.5850809e-07 9.09525e-09 4.7246e-10 -8.966e-11 4.54e-12 8.14e-12 -5.6e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.06e-12 1.276e-11 -5.7e-11 9.601e-11 3.57649e-09 6.132509e-08 9.551413e-07 1.289677528e-05 0.00014714171433 0.00137112138293 0.00986042388672 0.05608495982301 0.14748911925352 0.1684932882151 0.08756755843555 0.02577732147237 0.0028626454996 0.00034466900299 -0.0007133028264 -0.00595706229097 -0.05528665949198 -0.20798297659977 -0.40149112104714 -0.3068224205777 -0.11911253727347 -0.00892854604743 0.08247002745888 0.20435344554721 0.18829131041694 0.09863227094439 0.028628558204 0.00349355365802 0.00037754681171 3.31203774e-05 2.45917904e-06 1.5850809e-07 9.09525e-09 4.7246e-10 -8.966e-11 4.54e-12 8.14e-12 -5.6e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.06e-12 1.276e-11 -5.7e-11 9.601e-11 3.57649e-09 6.132509e-08 9.551413e-07 1.289677528e-05 0.00014714171433 0.00137112138293 0.00986042388672 0.05608495982301 0.14748911925352 0.1684932882151 0.08756755843555 0.02577732147237 0.0028626454996 0.00034466900299 -0.0007133028264 -0.00595706229097 -0.05528665949199 -0.20798297659976 -0.40149112104695 -0.30682242057757 -0.11911253727357 -0.00892854604744 0.08247002745891 0.20435344554719 0.18829131041694 0.09863227094441 0.02862855820401 0.00349355365802 0.00037754681171 3.31203774e-05 2.45917904e-06 1.5850809e-07 9.09525e-09 4.7246e-10 -8.966e-11 4.54e-12 8.14e-12 -5.6e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.06e-12 1.276e-11 -5.7e-11 9.601e-11 3.57649e-09 6.132509e-08 9.551413e-07 1.289677528e-05 0.00014714171433 0.00137112138293 0.00986042388672 0.05608495982301 0.14748911925352 0.1684932882151 0.08756755843555 0.02577732147237 0.0028626454996 0.00034466900299 -0.0007133028264 -0.00595706229097 -0.05528665949193 -0.20798297659934 -0.4014911210464 -0.30682242057955 -0.11911253727343 -0.00892854604766 0.08247002745888 0.20435344554737 0.18829131041682 0.09863227094437 0.02862855820402 0.00349355365802 0.00037754681171 3.31203774e-05 2.45917904e-06 1.5850809e-07 9.09525e-09 4.7246e-10 -8.966e-11 4.54e-12 8.14e-12 -5.6e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.06e-12 1.276e-11 -5.7e-11 9.601e-11 3.57649e-09 6.132509e-08 9.551413e-07 1.289677528e-05 0.00014714171433 0.00137112138293 0.00986042388672 0.05608495982301 0.14748911925352 0.1684932882151 0.08756755843555 0.02577732147237 0.0028626454996 0.00034466900299 -0.0007133028264 -0.00595706229096 -0.05528665949191 -0.20798297660068 -0.40149112105161 -0.30682242058054 -0.11911253727107 -0.00892854604663 0.08247002745819 0.20435344554742 0.18829131041705 0.09863227094414 0.02862855820388 0.00349355365802 0.00037754681171 3.31203774e-05 2.45917904e-06 1.5850809e-07 9.09525e-09 4.7246e-10 -8.966e-11 4.54e-12 8.14e-12 -5.6e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.06e-12 1.276e-11 -5.7e-11 9.601e-11 3.57649e-09 6.132509e-08 9.551413e-07 1.289677528e-05 0.00014714171433 0.00137112138293 0.00986042388672 0.05608495982301 0.14748911925352 0.16849328821509 0.08756755843555 0.02577732147237 0.00286264549961 0.00034466900299 -0.00071330282641 -0.00595706229099 -0.05528665949335 -0.20798297660794 -0.40149112105689 -0.30682242055537 -0.11911253727618 -0.00892854604209 0.08247002746025 0.20435344554291 0.18829131041935 0.09863227094549 0.02862855820401 0.00349355365799 0.00037754681172 3.31203774e-05 2.45917904e-06 1.5850809e-07 9.09525e-09 4.7246e-10 -8.966e-11 4.54e-12 8.14e-12 -5.6e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.06e-12 1.276e-11 -5.7e-11 9.601e-11 3.57649e-09 6.132509e-08 9.551413e-07 1.289677528e-05 0.00014714171433 0.00137112138293 0.00986042388672 0.05608495982301 0.14748911925352 0.1684932882151 0.08756755843554 0.02577732147239 0.00286264549958 0.000344669003 -0.00071330282634 -0.00595706229119 -0.05528665949259 -0.20798297658425 -0.40149112098653 -0.30682242065512 -0.11911253729767 -0.00892854605662 0.08247002746967 0.20435344554334 0.1882913104136 0.09863227094915 0.02862855820717 0.00349355365806 0.00037754681168 3.312037741e-05 2.45917904e-06 1.5850809e-07 9.09525e-09 4.7246e-10 -8.966e-11 4.54e-12 8.14e-12 -5.6e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.06e-12 1.276e-11 -5.7e-11 9.601e-11 3.57649e-09 6.132509e-08 9.551413e-07 1.289677528e-05 0.00014714171433 0.00137112138293 0.00986042388672 0.05608495982301 0.14748911925351 0.1684932882151 0.08756755843556 0.02577732147238 0.00286264549949 0.00034466900301 -0.00071330282627 -0.00595706229049 -0.0552866594804 -0.20798297659359 -0.40149112120169 -0.30682242236855 -0.11911253701738 -0.00892854602118 0.08247002741378 0.20435344559643 0.18829131039446 0.09863227092805 0.02862855820403 0.00349355365936 0.00037754681172 3.312037738e-05 2.45917904e-06 1.5850809e-07 9.09525e-09 4.7246e-10 -8.966e-11 4.54e-12 8.14e-12 -5.6e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.06e-12 1.276e-11 -5.7e-11 9.601e-11 3.57649e-09 6.132509e-08 9.551413e-07 1.289677528e-05 0.00014714171433 0.00137112138293 0.00986042388672 0.05608495982301 0.14748911925355 0.16849328821496 0.08756755843567 0.02577732147211 0.00286264550042 0.00034466900282 -0.00071330282785 -0.00595706228836 -0.05528665954269 -0.2079829776289 -0.40149112498633 -0.30682245165717 -0.11911253261384 -0.00892854423821 0.08247002707413 0.20435344533294 0.18829131061176 0.09863227094785 0.02862855817489 0.00349355365872 0.00037754681301 3.312037743e-05 2.45917902e-06 1.5850809e-07 9.09525e-09 4.7246e-10 -8.966e-11 4.54e-12 8.14e-12 -5.6e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.06e-12 1.276e-11 -5.7e-11 9.601e-11 3.57649e-09 6.132509e-08 9.551413e-07 1.289677528e-05 0.00014714171433 0.00137112138293 0.00986042388672 0.05608495982298 0.14748911925355 0.16849328821575 0.08756755843405 0.02577732147186 0.00286264550257 0.00034466900262 -0.00071330283089 -0.00595706225005 -0.0552866604288 -0.2079829952266 -0.40149118977969 -0.30682290191874 -0.11911244936207 -0.00892851301735 0.08247002229256 0.20435344068792 0.18829131244229 0.09863227160105 0.02862855842353 0.00349355364794 0.00037754681272 3.312037845e-05 2.45917908e-06 1.5850808e-07 9.09525e-09 4.7246e-10 -8.966e-11 4.54e-12 8.14e-12 -5.6e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.06e-12 1.276e-11 -5.7e-11 9.601e-11 3.57649e-09 6.132509e-08 9.551413e-07 1.289677528e-05 0.00014714171433 0.00137112138293 0.00986042388673 0.05608495982314 0.14748911925236 0.16849328821887 0.08756755843368 0.02577732147436 0.00286264549122 0.00034466900124 -0.00071330281742 -0.00595706129504 -0.05528666892902 -0.20798324977681 -0.4014921809149 -0.3068287795783 -0.11911106927729 -0.00892801770168 0.08246995524388 0.20435336179604 0.18829133354073 0.09863228043026 0.0286285628423 0.003493553905 0.00037754680864 3.312037884e-05 2.4591799e-06 1.5850817e-07 9.09525e-09 4.7246e-10 -8.966e-11 4.54e-12 8.14e-12 -5.6e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.06e-12 1.276e-11 -5.7e-11 9.601e-11 3.57649e-09 6.132509e-08 9.551413e-07 1.289677528e-05 0.00014714171433 0.00137112138293 0.00986042388669 0.05608495982371 0.14748911925531 0.16849328819558 0.08756755845112 0.02577732147247 0.00286264551816 0.00034466901846 -0.00071330255081 -0.0059570407437 -0.05528670203532 -0.2079864352225 -0.40150518136624 -0.30689156246244 -0.11909151490416 -0.0089212420599 0.08246921119953 0.20435217848792 0.18829149462775 0.09863239149607 0.02862863587426 0.00349355880854 0.00037754714555 3.312038319e-05 2.45918042e-06 1.5850866e-07 9.09531e-09 4.7247e-10 -8.966e-11 4.54e-12 8.14e-12 -5.6e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.06e-12 1.276e-11 -5.7e-11 9.601e-11 3.57649e-09 6.132509e-08 9.551413e-07 1.289677528e-05 0.00014714171433 0.00137112138294 0.00986042388667 0.05608495982014 0.14748911925792 0.16849328822696 0.08756755837446 0.02577732089169 0.00286264689365 0.0003446700979 -0.00071329422809 -0.00595668187405 -0.05528605670734 -0.20802074463151 -0.40164736929758 -0.30739454757615 -0.11886246912115 -0.00884401658073 0.08246338146612 0.20433722698779 0.18829139515278 0.09863353790165 0.02862967742746 0.00349363746881 0.00037755306839 3.31207446e-05 2.45918961e-06 1.5850845e-07 9.09537e-09 4.7248e-10 -8.966e-11 4.54e-12 8.14e-12 -5.6e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.06e-12 1.276e-11 -5.7e-11 9.601e-11 3.57649e-09 6.132509e-08 9.551413e-07 1.289677528e-05 0.00014714171435 0.00137112138313 0.00986042388607 0.05608495978509 0.14748911886671 0.16849328909917 0.08756755748684 0.0257773064374 0.00286267717304 0.00034469584518 -0.00071312657783 -0.00595147050873 -0.05526407405146 -0.2083013309329 -0.40293855526316 -0.31013083635293 -0.1166306717201 -0.0081172544791 0.08244176426225 0.20418239078556 0.18826920033553 0.09864329913965 0.02864205859756 0.00349468536673 0.00037763688598 3.312643079e-05 2.45949262e-06 1.5851549e-07 9.09482e-09 4.724e-10 -8.965e-11 4.54e-12 8.13e-12 -5.6e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.06e-12 1.276e-11 -5.7e-11 9.601e-11 3.57649e-09 6.132509e-08 9.551413e-07 1.289677529e-05 0.00014714171435 0.00137112138198 0.0098604238387 0.05608495900343 0.1474891115308 0.16849330107721 0.08756754959327 0.02577700361782 0.00286327925622 0.00034512515804 -0.00071072957808 -0.00589168886446 -0.05495076985629 -0.21000015859399 -0.41081849510195 -0.29004283960962 -0.10609703249719 -0.00437330903976 0.08281014419744 0.20281967783098 0.18778878894278 0.09874626784205 0.02877607433841 0.00350683204714 0.00037864500075 3.319599438e-05 2.46364297e-06 1.5873618e-07 9.10427e-09 4.7274e-10 -8.965e-11 4.54e-12 8.13e-12 -5.6e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.06e-12 1.276e-11 -5.7e-11 9.601e-11 3.57649e-09 6.132509e-08 9.551413e-07 1.289677526e-05 0.00014714171379 0.00137112136536 0.00986042322701 0.05608494897904 0.14748904261494 0.16849338332497 0.08756751303546 0.02577424242403 0.00286763829482 0.00034940696399 -0.00068779058531 -0.00553968519705 -0.05299238303428 -0.21221087065655 -0.41669112547517 0.0 0.0 0.00317035604216 0.07920057596829 0.1980968246398 0.18596143017817 0.09872472900923 0.02941220283246 0.00357062856673 0.00038453136597 3.363812308e-05 2.49163186e-06 1.6032195e-07 9.19006e-09 4.7839e-10 -8.977e-11 4.4e-12 8.18e-12 -5.5e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.06e-12 1.276e-11 -5.7e-11 9.601e-11 3.57649e-09 6.132509e-08 9.551413e-07 1.289677538e-05 0.00014714171627 0.00137112133961 0.00986041868998 0.05608485391633 0.14748837620394 0.16849370495639 0.0875754344113 0.02573277419316 0.00284738228609 0.00041193662967 -0.00029779800445 -0.00198291026902 -0.01022592169278 0.0 0.0 0.0 0.0 0.0 0.0 0.11851105780903 0.16744204896662 0.09709745177786 0.03208383189485 0.00385190882053 0.00040954101109 3.559436081e-05 2.62182816e-06 1.6786417e-07 9.58271e-09 5.0295e-10 -9.008e-11 3.7e-12 8.35e-12 -5.2e-13 -3.2e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.06e-12 1.276e-11 -5.7e-11 9.601e-11 3.57649e-09 6.132509e-08 9.5514136e-07 1.289677661e-05 0.00014714173693 0.00137112165792 0.00986042371564 0.05608491364693 0.14748869124828 0.16849395858036 0.08757870956904 0.02576101233218 0.00284730572698 0.0003444493969 -7.456805235e-05 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0816434408622 0.15736904226042 0.08158884461609 0.02588545288926 0.00317113675443 0.00034326828609 3.027117313e-05 2.25818525e-06 1.4612698e-07 8.43472e-09 4.3188e-10 -8.872e-11 5.55e-12 7.84e-12 -5.9e-13 -2.9e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.06e-12 1.276e-11 -5.7e-11 9.601e-11 3.57649e-09 6.13251e-08 9.5514165e-07 1.289678177e-05 0.00014714181873 0.00137112277539 0.00986043784584 0.05608506974342 0.1474891668372 0.16849159926504 0.08758101660882 0.02577127458253 0.0028829220284 0.00024118004541 3.110317933e-05 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.04047589784669 0.02142323503434 0.00661775973331 0.00086245377253 9.677891862e-05 8.78678684e-06 6.7233157e-07 4.448319e-08 2.67577e-09 3.757e-11 -4.459e-11 1.302e-11 2.98e-12 -8e-13 -4e-14 5e-14 -0.0 -0.0 -0.0 6e-14 -9e-14 -8.5e-13 4.06e-12 1.276e-11 -5.7e-11 9.601e-11 3.57649e-09 6.132509e-08 9.5514143e-07 1.289677792e-05 0.00014714175893 0.00137112200108 0.00986042955118 0.05608499337059 0.14748900937526 0.16849274477962 0.08757873603022 0.02577133662423 0.00288834020821 0.00023657924056 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.00552645355567 0.00766952409719 0.00202301301163 0.00025021621351 2.665471663e-05 2.36482013e-06 1.7946809e-07 1.189247e-08 7.2908e-10 -9.607e-11 -3.87e-12 1.128e-11 -1.1e-13 -5.5e-13 8e-14 2e-14 -1e-14 -0.0 -0.0 6e-14 -9e-14 -8.5e-13 4.06e-12 1.276e-11 -5.7e-11 9.601e-11 3.57649e-09 6.132509e-08 9.5514125e-07 1.289677436e-05 0.0001471417005 0.00137112113368 0.00986041588562 0.05608481753275 0.14748823944956 0.16849479740968 0.08757815195705 0.02573665967029 0.0028535856797 0.00040249832518 0.0 0.0 0.0 0.0 0.0 +D/cons.4.00.000050.dat 0.0 0.0 0.0 0.0 0.0 0.03175646939529 0.01345542992285 0.00293204170109 0.00039795733159 4.370728105e-05 3.91972831e-06 2.9688179e-07 1.946627e-08 1.20202e-09 -7.465e-11 -1.652e-11 1.284e-11 7.2e-13 -6.8e-13 5e-14 3e-14 -1e-14 -0.0 -0.0 6e-14 -9e-14 -8.5e-13 4.06e-12 1.276e-11 -5.7e-11 9.601e-11 3.57649e-09 6.132508e-08 9.5514117e-07 1.289677289e-05 0.00014714167637 0.00137112081125 0.00986041263008 0.05608479382185 0.14748820995098 0.16849521383338 0.08757749006526 0.02573968391493 0.00285394202037 0.00039221234722 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.04126932924153 0.0233479966285 0.00678014957125 0.00090077328911 0.00010270764814 9.41563849e-06 7.2450666e-07 4.799628e-08 2.87018e-09 5.133e-11 -4.752e-11 1.294e-11 3.22e-12 -8.1e-13 -5e-14 5e-14 -0.0 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.06e-12 1.276e-11 -5.7e-11 9.601e-11 3.57649e-09 6.132508e-08 9.5514114e-07 1.28967723e-05 0.00014714166883 0.00137112080387 0.00986041652959 0.05608488075783 0.147488758441 0.16849455518105 0.08757646564889 0.02577372712047 0.00288206695592 0.000253350454 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.08320769040331 0.14384110567237 0.07792363296143 0.02637361134487 0.00320330687143 0.0003434930572 3.012656142e-05 2.23727986e-06 1.44299e-07 8.31608e-09 4.2347e-10 -8.846e-11 5.79e-12 7.78e-12 -6e-13 -2.9e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.06e-12 1.276e-11 -5.7e-11 9.601e-11 3.57649e-09 6.132507e-08 9.5514097e-07 1.289676908e-05 0.00014714161459 0.00137112002891 0.00986040666302 0.05608476795222 0.14748845891829 0.16849688724405 0.08757612587672 0.02577643221467 0.0028594272149 0.00032588315209 2.582194075e-05 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.11882306522179 0.16132188442171 0.09457193298668 0.03174139739139 0.00383132862788 0.00040727326193 3.541752738e-05 2.60991334e-06 1.6715442e-07 9.54545e-09 5.0067e-10 -9.006e-11 3.76e-12 8.33e-12 -5.2e-13 -3.2e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.06e-12 1.276e-11 -5.7e-11 9.601e-11 3.57649e-09 6.132508e-08 9.551412e-07 1.289677344e-05 0.00014714168501 0.00137112094263 0.00986041517864 0.0560848312957 0.14748844026931 0.16849543397029 0.08757845104619 0.02575987281364 0.00284350435039 0.00036441200091 -5.879441335e-05 0.0 0.0 0.0 0.0 0.0 0.0 0.00293799500315 0.07938738234463 0.19775503284989 0.18480493367976 0.09821522378759 0.02935889048801 0.00356756853098 0.00038430911964 3.362351548e-05 2.49066608e-06 1.6026181e-07 9.18699e-09 4.7823e-10 -8.977e-11 4.4e-12 8.18e-12 -5.5e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.06e-12 1.276e-11 -5.7e-11 9.601e-11 3.57649e-09 6.132509e-08 9.5514127e-07 1.289677492e-05 0.00014714170984 0.00137112126607 0.00986041776012 0.05608484310162 0.1474883209046 0.16849397746271 0.08757687857743 0.02573154209658 0.00285108673439 0.00040746551263 -0.0002626961267 -0.00191615667354 -0.01020512783606 0.0 0.0 -0.28976421434607 -0.10635972996776 -0.00444613379317 0.08279840390382 0.20257702695595 0.18757728043386 0.09872070816104 0.02879227821857 0.00350861621685 0.00037880006062 3.320639514e-05 2.46420678e-06 1.5876318e-07 9.10557e-09 4.7282e-10 -8.965e-11 4.54e-12 8.13e-12 -5.6e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.06e-12 1.276e-11 -5.7e-11 9.601e-11 3.57649e-09 6.132509e-08 9.5514129e-07 1.289677521e-05 0.00014714171308 0.00137112135451 0.009860422962 0.05608494471003 0.14748901836641 0.16849348170237 0.08756776750988 0.02577356567414 0.00286812630968 0.00035143669158 -0.00067939285949 -0.00549730841311 -0.05290555969673 -0.21190848109095 -0.41603615041886 -0.30994944904394 -0.11685972638578 -0.00820021260153 0.08245482303754 0.2041501287416 0.18823792128335 0.09864146088779 0.02864537816129 0.00349500385866 0.00037766201716 3.312804444e-05 2.45957973e-06 1.5851979e-07 9.095e-09 4.724e-10 -8.965e-11 4.54e-12 8.13e-12 -5.6e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.06e-12 1.276e-11 -5.7e-11 9.601e-11 3.57649e-09 6.132509e-08 9.551413e-07 1.289677527e-05 0.00014714171417 0.00137112138013 0.00986042380701 0.05608495853484 0.14748910604344 0.16849331781319 0.08756756223286 0.02577689741352 0.00286341851508 0.00034545199173 -0.00070931328131 -0.00587967884441 -0.05488397628023 -0.20978683828578 -0.41055361049454 -0.30736272604818 -0.11888907549261 -0.00885354594064 0.08246443377367 0.20433332969255 0.18828810177625 0.09863322648774 0.02863001700041 0.0034936701914 0.00037755558774 3.312090148e-05 2.45919765e-06 1.5850872e-07 9.09536e-09 4.7248e-10 -8.966e-11 4.54e-12 8.14e-12 -5.6e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.06e-12 1.276e-11 -5.7e-11 9.601e-11 3.57649e-09 6.132509e-08 9.551413e-07 1.289677528e-05 0.00014714171432 0.00137112138276 0.00986042388135 0.05608495973299 0.14748911837158 0.16849329091425 0.08756755838359 0.02577729812798 0.002862683809 0.00034473233761 -0.0007129546583 -0.00594983184858 -0.05525162142588 -0.20825476990535 -0.40287264940442 -0.3068866180226 -0.11909420173658 -0.00892222803744 0.08246930503967 0.20435181184954 0.18829118617885 0.09863236218877 0.0286286668093 0.00349356160732 0.00037754734736 3.312039384e-05 2.45918059e-06 1.5850863e-07 9.09531e-09 4.7247e-10 -8.966e-11 4.54e-12 8.14e-12 -5.6e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.06e-12 1.276e-11 -5.7e-11 9.601e-11 3.57649e-09 6.132509e-08 9.551413e-07 1.289677528e-05 0.00014714171432 0.00137112138291 0.00986042388625 0.05608495981513 0.14748911923517 0.16849328835208 0.08756755841194 0.0257773204052 0.00286264701434 0.00034467333896 -0.00071327784077 -0.00595650641621 -0.05528432230704 -0.20801314283949 -0.40163815438284 -0.30682821970483 -0.11911128755671 -0.00892810161076 0.08246996303913 0.20435333298064 0.18829131002708 0.09863227820206 0.02862856521176 0.00349355410825 0.00037754681961 3.312037888e-05 2.4591799e-06 1.5850818e-07 9.09525e-09 4.7246e-10 -8.966e-11 4.54e-12 8.14e-12 -5.6e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.06e-12 1.276e-11 -5.7e-11 9.601e-11 3.57649e-09 6.132509e-08 9.551413e-07 1.289677528e-05 0.00014714171432 0.00137112138292 0.00986042388661 0.05608495982319 0.14748911926007 0.16849328818613 0.08756755845799 0.02577732146991 0.00286264548906 0.00034466922536 -0.00071330130728 -0.00595702602519 -0.05528654721764 -0.20798572737886 -0.40150409853683 -0.30682285064311 -0.11911246424348 -0.00892851906855 0.08247002290676 0.20435343877191 0.18829131085553 0.09863227145281 0.02862855859392 0.00349355365691 0.00037754681232 3.312037851e-05 2.45917911e-06 1.5850808e-07 9.09525e-09 4.7246e-10 -8.966e-11 4.54e-12 8.14e-12 -5.6e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.06e-12 1.276e-11 -5.7e-11 9.601e-11 3.57649e-09 6.132509e-08 9.551413e-07 1.289677528e-05 0.00014714171433 0.00137112138293 0.0098604238867 0.05608495982303 0.14748911925026 0.16849328822048 0.08756755844091 0.02577732147351 0.00286264548853 0.00034466900473 -0.00071330276035 -0.00595706023 -0.05528665570975 -0.20798318695735 -0.40149208185766 -0.30682244779549 -0.11911253346856 -0.008928544609 0.08247002710855 0.20435344521212 0.18829131049767 0.09863227095201 0.02862855818032 0.00349355365796 0.00037754681317 3.312037748e-05 2.45917902e-06 1.5850809e-07 9.09525e-09 4.7246e-10 -8.966e-11 4.54e-12 8.14e-12 -5.6e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.06e-12 1.276e-11 -5.7e-11 9.601e-11 3.57649e-09 6.132509e-08 9.551413e-07 1.289677528e-05 0.00014714171433 0.00137112138293 0.00986042388672 0.05608495982295 0.14748911925298 0.16849328821859 0.08756755843209 0.02577732146857 0.00286264550403 0.00034466900413 -0.00071330283038 -0.00595706220945 -0.05528665949939 -0.20798299042998 -0.40149118219944 -0.30682242211423 -0.11911253707403 -0.00892854603675 0.08247002741112 0.20435344559805 0.18829131041827 0.09863227093151 0.02862855820036 0.00349355365952 0.00037754681178 3.312037738e-05 2.45917904e-06 1.5850809e-07 9.09525e-09 4.7246e-10 -8.966e-11 4.54e-12 8.14e-12 -5.6e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.06e-12 1.276e-11 -5.7e-11 9.601e-11 3.57649e-09 6.132509e-08 9.551413e-07 1.289677528e-05 0.00014714171433 0.00137112138293 0.00986042388672 0.05608495982301 0.14748911925366 0.16849328821482 0.08756755843521 0.02577732147206 0.00286264550064 0.00034466900404 -0.00071330282557 -0.00595706229016 -0.05528665949975 -0.20798297731933 -0.40149112447708 -0.30682242064291 -0.11911253729432 -0.0089285460565 0.08247002747176 0.20435344554625 0.18829131041241 0.09863227094718 0.02862855820763 0.00349355365813 0.00037754681168 3.312037741e-05 2.45917904e-06 1.5850809e-07 9.09525e-09 4.7246e-10 -8.966e-11 4.54e-12 8.14e-12 -5.6e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.06e-12 1.276e-11 -5.7e-11 9.601e-11 3.57649e-09 6.132509e-08 9.551413e-07 1.289677528e-05 0.00014714171433 0.00137112138293 0.00986042388672 0.05608495982301 0.14748911925352 0.16849328821497 0.08756755843571 0.02577732147255 0.00286264549936 0.000344669003 -0.0007133028258 -0.00595706228852 -0.05528665948821 -0.20798297657609 -0.40149112116764 -0.3068224205565 -0.1191125372754 -0.00892854604262 0.0824700274603 0.20435344554184 0.18829131041725 0.09863227094523 0.02862855820423 0.00349355365799 0.00037754681171 3.31203774e-05 2.45917904e-06 1.5850809e-07 9.09525e-09 4.7246e-10 -8.966e-11 4.54e-12 8.14e-12 -5.6e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.06e-12 1.276e-11 -5.7e-11 9.601e-11 3.57649e-09 6.132509e-08 9.551413e-07 1.289677528e-05 0.00014714171433 0.00137112138293 0.00986042388672 0.05608495982301 0.14748911925351 0.16849328821513 0.08756755843555 0.02577732147236 0.00286264549959 0.00034466900296 -0.00071330282646 -0.00595706229082 -0.05528665949138 -0.2079829765914 -0.40149112099185 -0.30682242058036 -0.1191125372716 -0.00892854604675 0.08247002745814 0.20435344554734 0.18829131041713 0.09863227094423 0.02862855820385 0.00349355365802 0.00037754681171 3.31203774e-05 2.45917904e-06 1.5850809e-07 9.09525e-09 4.7246e-10 -8.966e-11 4.54e-12 8.14e-12 -5.6e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.06e-12 1.276e-11 -5.7e-11 9.601e-11 3.57649e-09 6.132509e-08 9.551413e-07 1.289677528e-05 0.00014714171433 0.00137112138293 0.00986042388672 0.05608495982301 0.14748911925352 0.1684932882151 0.08756755843554 0.02577732147236 0.00286264549962 0.000344669003 -0.00071330282642 -0.00595706229109 -0.05528665949262 -0.20798297660666 -0.40149112105786 -0.30682242057942 -0.11911253727341 -0.00892854604763 0.08247002745888 0.20435344554743 0.1882913104169 0.09863227094437 0.02862855820401 0.00349355365802 0.00037754681171 3.31203774e-05 2.45917904e-06 1.5850809e-07 9.09525e-09 4.7246e-10 -8.966e-11 4.54e-12 8.14e-12 -5.6e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.06e-12 1.276e-11 -5.7e-11 9.601e-11 3.57649e-09 6.132509e-08 9.551413e-07 1.289677528e-05 0.00014714171433 0.00137112138293 0.00986042388672 0.05608495982301 0.14748911925352 0.16849328821509 0.08756755843555 0.02577732147237 0.0028626454996 0.00034466900299 -0.00071330282639 -0.00595706229096 -0.05528665949204 -0.20798297660033 -0.40149112105088 -0.30682242057758 -0.11911253727355 -0.00892854604744 0.08247002745891 0.20435344554719 0.18829131041693 0.0986322709444 0.02862855820401 0.00349355365802 0.00037754681171 3.31203774e-05 2.45917904e-06 1.5850809e-07 9.09525e-09 4.7246e-10 -8.966e-11 4.54e-12 8.14e-12 -5.6e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.06e-12 1.276e-11 -5.7e-11 9.601e-11 3.57649e-09 6.132509e-08 9.551413e-07 1.289677528e-05 0.00014714171433 0.00137112138293 0.00986042388672 0.05608495982301 0.14748911925352 0.1684932882151 0.08756755843555 0.02577732147237 0.0028626454996 0.00034466900299 -0.0007133028264 -0.00595706229096 -0.05528665949194 -0.20798297659944 -0.40149112104638 -0.3068224205777 -0.11911253727347 -0.00892854604743 0.08247002745888 0.20435344554721 0.18829131041694 0.09863227094439 0.028628558204 0.00349355365802 0.00037754681171 3.31203774e-05 2.45917904e-06 1.5850809e-07 9.09525e-09 4.7246e-10 -8.966e-11 4.54e-12 8.14e-12 -5.6e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.06e-12 1.276e-11 -5.7e-11 9.601e-11 3.57649e-09 6.132509e-08 9.551413e-07 1.289677528e-05 0.00014714171433 0.00137112138293 0.00986042388672 0.05608495982301 0.14748911925352 0.1684932882151 0.08756755843555 0.02577732147237 0.0028626454996 0.00034466900299 -0.0007133028264 -0.00595706229097 -0.05528665949198 -0.20798297659976 -0.401491121047 -0.30682242057777 -0.11911253727347 -0.00892854604744 0.08247002745888 0.20435344554722 0.18829131041693 0.09863227094439 0.028628558204 0.00349355365802 0.00037754681171 3.31203774e-05 2.45917904e-06 1.5850809e-07 9.09525e-09 4.7246e-10 -8.966e-11 4.54e-12 8.14e-12 -5.6e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.06e-12 1.276e-11 -5.7e-11 9.601e-11 3.57649e-09 6.132509e-08 9.551413e-07 1.289677528e-05 0.00014714171433 0.00137112138293 0.00986042388672 0.05608495982301 0.14748911925352 0.1684932882151 0.08756755843555 0.02577732147237 0.0028626454996 0.00034466900299 -0.0007133028264 -0.00595706229097 -0.05528665949199 -0.20798297659977 -0.40149112104714 -0.30682242057776 -0.11911253727347 -0.00892854604744 0.08247002745888 0.20435344554722 0.18829131041693 0.09863227094439 0.028628558204 0.00349355365802 0.00037754681171 3.31203774e-05 2.45917904e-06 1.5850809e-07 9.09525e-09 4.7246e-10 -8.966e-11 4.54e-12 8.14e-12 -5.6e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.06e-12 1.276e-11 -5.7e-11 9.601e-11 3.57649e-09 6.132509e-08 9.551413e-07 1.289677528e-05 0.00014714171433 0.00137112138293 0.00986042388672 0.05608495982301 0.14748911925352 0.1684932882151 0.08756755843555 0.02577732147237 0.0028626454996 0.00034466900299 -0.0007133028264 -0.00595706229097 -0.05528665949198 -0.20798297659975 -0.40149112104709 -0.30682242057776 -0.11911253727347 -0.00892854604744 0.08247002745888 0.20435344554722 0.18829131041693 0.09863227094439 0.028628558204 0.00349355365802 0.00037754681171 3.31203774e-05 2.45917904e-06 1.5850809e-07 9.09525e-09 4.7246e-10 -8.966e-11 4.54e-12 8.14e-12 -5.6e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.06e-12 1.276e-11 -5.7e-11 9.601e-11 3.57649e-09 6.132509e-08 9.551413e-07 1.289677528e-05 0.00014714171433 0.00137112138293 0.00986042388672 0.05608495982301 0.14748911925352 0.1684932882151 0.08756755843555 0.02577732147237 0.0028626454996 0.00034466900299 -0.0007133028264 -0.00595706229097 -0.05528665949198 -0.20798297659975 -0.40149112104708 -0.30682242057776 -0.11911253727347 -0.00892854604744 0.08247002745888 0.20435344554722 0.18829131041693 0.09863227094439 0.028628558204 0.00349355365802 0.00037754681171 3.31203774e-05 2.45917904e-06 1.5850809e-07 9.09525e-09 4.7246e-10 -8.966e-11 4.54e-12 8.14e-12 -5.6e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.06e-12 1.276e-11 -5.7e-11 9.601e-11 3.57649e-09 6.132509e-08 9.551413e-07 1.289677528e-05 0.00014714171433 0.00137112138293 0.00986042388672 0.05608495982301 0.14748911925352 0.1684932882151 0.08756755843555 0.02577732147237 0.0028626454996 0.00034466900299 -0.0007133028264 -0.00595706229097 -0.05528665949198 -0.20798297659975 -0.40149112104709 -0.30682242057776 -0.11911253727347 -0.00892854604744 0.08247002745888 0.20435344554722 0.18829131041693 0.09863227094439 0.028628558204 0.00349355365802 0.00037754681171 3.31203774e-05 2.45917904e-06 1.5850809e-07 9.09525e-09 4.7246e-10 -8.966e-11 4.54e-12 8.14e-12 -5.6e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.06e-12 1.276e-11 -5.7e-11 9.601e-11 3.57649e-09 6.132509e-08 9.551413e-07 1.289677528e-05 0.00014714171433 0.00137112138293 0.00986042388672 0.05608495982301 0.14748911925352 0.1684932882151 0.08756755843555 0.02577732147237 0.0028626454996 0.00034466900299 -0.0007133028264 -0.00595706229097 -0.05528665949198 -0.20798297659975 -0.40149112104709 -0.30682242057776 -0.11911253727347 -0.00892854604744 0.08247002745888 0.20435344554722 0.18829131041693 0.09863227094439 0.028628558204 0.00349355365802 0.00037754681171 3.31203774e-05 2.45917904e-06 1.5850809e-07 9.09525e-09 4.7246e-10 -8.966e-11 4.54e-12 8.14e-12 -5.6e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.06e-12 1.276e-11 -5.7e-11 9.601e-11 3.57649e-09 6.132509e-08 9.551413e-07 1.289677528e-05 0.00014714171433 0.00137112138293 0.00986042388672 0.05608495982301 0.14748911925352 0.1684932882151 0.08756755843555 0.02577732147237 0.0028626454996 0.00034466900299 -0.0007133028264 -0.00595706229097 -0.05528665949198 -0.20798297659975 -0.40149112104709 -0.30682242057776 -0.11911253727347 -0.00892854604744 0.08247002745888 0.20435344554722 0.18829131041693 0.09863227094439 0.028628558204 0.00349355365802 0.00037754681171 3.31203774e-05 2.45917904e-06 1.5850809e-07 9.09525e-09 4.7246e-10 -8.966e-11 4.54e-12 8.14e-12 -5.6e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.06e-12 1.276e-11 -5.7e-11 9.601e-11 3.57649e-09 6.132509e-08 9.551413e-07 1.289677528e-05 0.00014714171433 0.00137112138293 0.00986042388672 0.05608495982301 0.14748911925352 0.1684932882151 0.08756755843555 0.02577732147237 0.0028626454996 0.00034466900299 -0.0007133028264 -0.00595706229097 -0.05528665949198 -0.20798297659975 -0.40149112104709 -0.30682242057776 -0.11911253727347 -0.00892854604744 0.08247002745888 0.20435344554722 0.18829131041693 0.09863227094439 0.028628558204 0.00349355365802 0.00037754681171 3.31203774e-05 2.45917904e-06 1.5850809e-07 9.09525e-09 4.7246e-10 -8.966e-11 4.54e-12 8.14e-12 -5.6e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.06e-12 1.276e-11 -5.7e-11 9.601e-11 3.57649e-09 6.132509e-08 9.551413e-07 1.289677528e-05 0.00014714171433 0.00137112138293 0.00986042388672 0.05608495982301 0.14748911925352 0.1684932882151 0.08756755843555 0.02577732147237 0.0028626454996 0.00034466900299 -0.0007133028264 -0.00595706229097 -0.05528665949198 -0.20798297659975 -0.40149112104709 -0.30682242057776 -0.11911253727347 -0.00892854604744 0.08247002745888 0.20435344554722 0.18829131041693 0.09863227094439 0.028628558204 0.00349355365802 0.00037754681171 3.31203774e-05 2.45917904e-06 1.5850809e-07 9.09525e-09 4.7246e-10 -8.966e-11 4.54e-12 8.14e-12 -5.6e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.06e-12 1.276e-11 -5.7e-11 9.601e-11 3.57649e-09 6.132509e-08 9.551413e-07 1.289677528e-05 0.00014714171433 0.00137112138293 0.00986042388672 0.05608495982301 0.14748911925352 0.1684932882151 0.08756755843555 0.02577732147237 0.0028626454996 0.00034466900299 -0.0007133028264 -0.00595706229097 -0.05528665949198 -0.20798297659975 -0.40149112104709 -0.30682242057776 -0.11911253727347 -0.00892854604744 0.08247002745888 0.20435344554722 0.18829131041693 0.09863227094439 0.028628558204 0.00349355365802 0.00037754681171 3.31203774e-05 2.45917904e-06 1.5850809e-07 9.09525e-09 4.7246e-10 -8.966e-11 4.54e-12 8.14e-12 -5.6e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.06e-12 1.276e-11 -5.7e-11 9.601e-11 3.57649e-09 6.132509e-08 9.551413e-07 1.289677528e-05 0.00014714171433 0.00137112138293 0.00986042388672 0.05608495982301 0.14748911925352 0.1684932882151 0.08756755843555 0.02577732147237 0.0028626454996 0.00034466900299 -0.0007133028264 -0.00595706229097 -0.05528665949198 -0.20798297659975 -0.40149112104708 -0.30682242057776 -0.11911253727347 -0.00892854604744 0.08247002745888 0.20435344554722 0.18829131041693 0.09863227094439 0.028628558204 0.00349355365802 0.00037754681171 3.31203774e-05 2.45917904e-06 1.5850809e-07 9.09525e-09 4.7246e-10 -8.966e-11 4.54e-12 8.14e-12 -5.6e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.06e-12 1.276e-11 -5.7e-11 9.601e-11 3.57649e-09 6.132509e-08 9.551413e-07 1.289677528e-05 0.00014714171433 0.00137112138293 0.00986042388672 0.05608495982301 0.14748911925352 0.1684932882151 0.08756755843555 0.02577732147237 0.0028626454996 0.00034466900299 -0.0007133028264 -0.00595706229097 -0.05528665949198 -0.20798297659975 -0.40149112104709 -0.30682242057777 -0.11911253727347 -0.00892854604744 0.08247002745888 0.20435344554722 0.18829131041693 0.09863227094439 0.028628558204 0.00349355365802 0.00037754681171 3.31203774e-05 2.45917904e-06 1.5850809e-07 9.09525e-09 4.7246e-10 -8.966e-11 4.54e-12 8.14e-12 -5.6e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.06e-12 1.276e-11 -5.7e-11 9.601e-11 3.57649e-09 6.132509e-08 9.551413e-07 1.289677528e-05 0.00014714171433 0.00137112138293 0.00986042388672 0.05608495982301 0.14748911925352 0.1684932882151 0.08756755843555 0.02577732147237 0.0028626454996 0.00034466900299 -0.0007133028264 -0.00595706229097 -0.05528665949198 -0.20798297659977 -0.40149112104714 -0.3068224205777 -0.11911253727347 -0.00892854604743 0.08247002745888 0.20435344554721 0.18829131041694 0.09863227094439 0.028628558204 0.00349355365802 0.00037754681171 3.31203774e-05 2.45917904e-06 1.5850809e-07 9.09525e-09 4.7246e-10 -8.966e-11 4.54e-12 8.14e-12 -5.6e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.06e-12 1.276e-11 -5.7e-11 9.601e-11 3.57649e-09 6.132509e-08 9.551413e-07 1.289677528e-05 0.00014714171433 0.00137112138293 0.00986042388672 0.05608495982301 0.14748911925352 0.1684932882151 0.08756755843555 0.02577732147237 0.0028626454996 0.00034466900299 -0.0007133028264 -0.00595706229097 -0.05528665949199 -0.20798297659976 -0.40149112104695 -0.30682242057757 -0.11911253727357 -0.00892854604744 0.08247002745891 0.20435344554719 0.18829131041694 0.09863227094441 0.02862855820401 0.00349355365802 0.00037754681171 3.31203774e-05 2.45917904e-06 1.5850809e-07 9.09525e-09 4.7246e-10 -8.966e-11 4.54e-12 8.14e-12 -5.6e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.06e-12 1.276e-11 -5.7e-11 9.601e-11 3.57649e-09 6.132509e-08 9.551413e-07 1.289677528e-05 0.00014714171433 0.00137112138293 0.00986042388672 0.05608495982301 0.14748911925352 0.1684932882151 0.08756755843555 0.02577732147237 0.0028626454996 0.00034466900299 -0.0007133028264 -0.00595706229097 -0.05528665949193 -0.20798297659934 -0.4014911210464 -0.30682242057955 -0.11911253727343 -0.00892854604766 0.08247002745888 0.20435344554737 0.18829131041682 0.09863227094437 0.02862855820402 0.00349355365802 0.00037754681171 3.31203774e-05 2.45917904e-06 1.5850809e-07 9.09525e-09 4.7246e-10 -8.966e-11 4.54e-12 8.14e-12 -5.6e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.06e-12 1.276e-11 -5.7e-11 9.601e-11 3.57649e-09 6.132509e-08 9.551413e-07 1.289677528e-05 0.00014714171433 0.00137112138293 0.00986042388672 0.05608495982301 0.14748911925352 0.1684932882151 0.08756755843555 0.02577732147237 0.0028626454996 0.00034466900299 -0.0007133028264 -0.00595706229096 -0.05528665949191 -0.20798297660068 -0.40149112105161 -0.30682242058054 -0.11911253727107 -0.00892854604663 0.08247002745819 0.20435344554742 0.18829131041705 0.09863227094414 0.02862855820388 0.00349355365802 0.00037754681171 3.31203774e-05 2.45917904e-06 1.5850809e-07 9.09525e-09 4.7246e-10 -8.966e-11 4.54e-12 8.14e-12 -5.6e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.06e-12 1.276e-11 -5.7e-11 9.601e-11 3.57649e-09 6.132509e-08 9.551413e-07 1.289677528e-05 0.00014714171433 0.00137112138293 0.00986042388672 0.05608495982301 0.14748911925352 0.16849328821509 0.08756755843555 0.02577732147237 0.00286264549961 0.00034466900299 -0.00071330282641 -0.00595706229099 -0.05528665949335 -0.20798297660794 -0.40149112105689 -0.30682242055537 -0.11911253727618 -0.00892854604209 0.08247002746025 0.20435344554291 0.18829131041935 0.09863227094549 0.02862855820401 0.00349355365799 0.00037754681172 3.31203774e-05 2.45917904e-06 1.5850809e-07 9.09525e-09 4.7246e-10 -8.966e-11 4.54e-12 8.14e-12 -5.6e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.06e-12 1.276e-11 -5.7e-11 9.601e-11 3.57649e-09 6.132509e-08 9.551413e-07 1.289677528e-05 0.00014714171433 0.00137112138293 0.00986042388672 0.05608495982301 0.14748911925352 0.1684932882151 0.08756755843554 0.02577732147239 0.00286264549958 0.000344669003 -0.00071330282634 -0.00595706229119 -0.05528665949259 -0.20798297658425 -0.40149112098653 -0.30682242065512 -0.11911253729767 -0.00892854605662 0.08247002746967 0.20435344554334 0.1882913104136 0.09863227094915 0.02862855820717 0.00349355365806 0.00037754681168 3.312037741e-05 2.45917904e-06 1.5850809e-07 9.09525e-09 4.7246e-10 -8.966e-11 4.54e-12 8.14e-12 -5.6e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.06e-12 1.276e-11 -5.7e-11 9.601e-11 3.57649e-09 6.132509e-08 9.551413e-07 1.289677528e-05 0.00014714171433 0.00137112138293 0.00986042388672 0.05608495982301 0.14748911925351 0.1684932882151 0.08756755843556 0.02577732147238 0.00286264549949 0.00034466900301 -0.00071330282627 -0.00595706229049 -0.0552866594804 -0.20798297659359 -0.40149112120169 -0.30682242236855 -0.11911253701738 -0.00892854602118 0.08247002741378 0.20435344559643 0.18829131039446 0.09863227092805 0.02862855820403 0.00349355365936 0.00037754681172 3.312037738e-05 2.45917904e-06 1.5850809e-07 9.09525e-09 4.7246e-10 -8.966e-11 4.54e-12 8.14e-12 -5.6e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.06e-12 1.276e-11 -5.7e-11 9.601e-11 3.57649e-09 6.132509e-08 9.551413e-07 1.289677528e-05 0.00014714171433 0.00137112138293 0.00986042388672 0.05608495982301 0.14748911925355 0.16849328821496 0.08756755843567 0.02577732147211 0.00286264550042 0.00034466900282 -0.00071330282785 -0.00595706228836 -0.05528665954269 -0.2079829776289 -0.40149112498633 -0.30682245165717 -0.11911253261384 -0.00892854423821 0.08247002707413 0.20435344533294 0.18829131061176 0.09863227094785 0.02862855817489 0.00349355365872 0.00037754681301 3.312037743e-05 2.45917902e-06 1.5850809e-07 9.09525e-09 4.7246e-10 -8.966e-11 4.54e-12 8.14e-12 -5.6e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.06e-12 1.276e-11 -5.7e-11 9.601e-11 3.57649e-09 6.132509e-08 9.551413e-07 1.289677528e-05 0.00014714171433 0.00137112138293 0.00986042388672 0.05608495982298 0.14748911925355 0.16849328821575 0.08756755843405 0.02577732147186 0.00286264550257 0.00034466900262 -0.00071330283089 -0.00595706225005 -0.0552866604288 -0.2079829952266 -0.40149118977969 -0.30682290191874 -0.11911244936207 -0.00892851301735 0.08247002229256 0.20435344068792 0.18829131244229 0.09863227160105 0.02862855842353 0.00349355364794 0.00037754681272 3.312037845e-05 2.45917908e-06 1.5850808e-07 9.09525e-09 4.7246e-10 -8.966e-11 4.54e-12 8.14e-12 -5.6e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.06e-12 1.276e-11 -5.7e-11 9.601e-11 3.57649e-09 6.132509e-08 9.551413e-07 1.289677528e-05 0.00014714171433 0.00137112138294 0.00986042388673 0.05608495982314 0.14748911925236 0.16849328821887 0.08756755843368 0.02577732147436 0.00286264549122 0.00034466900124 -0.00071330281742 -0.00595706129504 -0.05528666892902 -0.20798324977681 -0.4014921809149 -0.3068287795783 -0.11911106927729 -0.00892801770168 0.08246995524388 0.20435336179604 0.18829133354073 0.09863228043026 0.0286285628423 0.003493553905 0.00037754680864 3.312037884e-05 2.4591799e-06 1.5850817e-07 9.09525e-09 4.7246e-10 -8.966e-11 4.54e-12 8.14e-12 -5.6e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.06e-12 1.276e-11 -5.7e-11 9.601e-11 3.57649e-09 6.132509e-08 9.551413e-07 1.289677528e-05 0.00014714171433 0.00137112138293 0.00986042388669 0.05608495982371 0.14748911925531 0.16849328819558 0.08756755845112 0.02577732147247 0.00286264551816 0.00034466901846 -0.00071330255081 -0.0059570407437 -0.05528670203532 -0.2079864352225 -0.40150518136624 -0.30689156246244 -0.11909151490416 -0.0089212420599 0.08246921119953 0.20435217848792 0.18829149462775 0.09863239149608 0.02862863587426 0.00349355880854 0.00037754714555 3.312038319e-05 2.45918042e-06 1.5850866e-07 9.09531e-09 4.7247e-10 -8.966e-11 4.54e-12 8.14e-12 -5.6e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.06e-12 1.276e-11 -5.7e-11 9.601e-11 3.57649e-09 6.132509e-08 9.551413e-07 1.289677528e-05 0.00014714171433 0.00137112138294 0.00986042388667 0.05608495982014 0.14748911925792 0.16849328822696 0.08756755837446 0.02577732089169 0.00286264689365 0.0003446700979 -0.00071329422809 -0.00595668187405 -0.05528605670734 -0.20802074463151 -0.40164736929758 -0.30739454757615 -0.11886246912115 -0.00884401658073 0.08246338146612 0.20433722698779 0.18829139515278 0.09863353790165 0.02862967742746 0.00349363746881 0.00037755306839 3.31207446e-05 2.45918961e-06 1.5850845e-07 9.09537e-09 4.7248e-10 -8.966e-11 4.54e-12 8.14e-12 -5.6e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.06e-12 1.276e-11 -5.7e-11 9.601e-11 3.57649e-09 6.132509e-08 9.551413e-07 1.289677528e-05 0.00014714171435 0.00137112138313 0.00986042388607 0.05608495978509 0.14748911886671 0.16849328909917 0.08756755748684 0.0257773064374 0.00286267717304 0.00034469584518 -0.00071312657783 -0.00595147050873 -0.05526407405146 -0.2083013309329 -0.40293855526316 -0.31013083635293 -0.1166306717201 -0.0081172544791 0.08244176426225 0.20418239078556 0.18826920033553 0.09864329913965 0.02864205859756 0.00349468536673 0.00037763688598 3.312643079e-05 2.45949262e-06 1.5851549e-07 9.09482e-09 4.724e-10 -8.965e-11 4.54e-12 8.13e-12 -5.6e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.06e-12 1.276e-11 -5.7e-11 9.601e-11 3.57649e-09 6.132509e-08 9.551413e-07 1.289677529e-05 0.00014714171435 0.00137112138198 0.0098604238387 0.05608495900343 0.1474891115308 0.16849330107721 0.08756754959327 0.02577700361782 0.00286327925622 0.00034512515804 -0.00071072957808 -0.00589168886446 -0.05495076985629 -0.21000015859399 -0.41081849510195 -0.29004283960962 -0.10609703249719 -0.00437330903976 0.08281014419744 0.20281967783098 0.18778878894278 0.09874626784205 0.02877607433841 0.00350683204714 0.00037864500075 3.319599438e-05 2.46364297e-06 1.5873618e-07 9.10427e-09 4.7274e-10 -8.965e-11 4.54e-12 8.13e-12 -5.6e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.06e-12 1.276e-11 -5.7e-11 9.601e-11 3.57649e-09 6.132509e-08 9.551413e-07 1.289677526e-05 0.00014714171379 0.00137112136536 0.00986042322701 0.05608494897904 0.14748904261494 0.16849338332497 0.08756751303546 0.02577424242403 0.00286763829482 0.00034940696399 -0.00068779058531 -0.00553968519705 -0.05299238303428 -0.21221087065655 -0.41669112547517 0.0 0.0 0.00317035604216 0.07920057596829 0.1980968246398 0.18596143017817 0.09872472900923 0.02941220283246 0.00357062856673 0.00038453136597 3.363812308e-05 2.49163186e-06 1.6032195e-07 9.19006e-09 4.7839e-10 -8.977e-11 4.4e-12 8.18e-12 -5.5e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.06e-12 1.276e-11 -5.7e-11 9.601e-11 3.57649e-09 6.132509e-08 9.551413e-07 1.289677538e-05 0.00014714171627 0.00137112133961 0.00986041868998 0.05608485391633 0.14748837620394 0.16849370495639 0.0875754344113 0.02573277419316 0.00284738228609 0.00041193662967 -0.00029779800445 -0.00198291026902 -0.01022592169278 0.0 0.0 0.0 0.0 0.0 0.0 0.11851105780903 0.16744204896662 0.09709745177786 0.03208383189485 0.00385190882053 0.00040954101109 3.559436081e-05 2.62182816e-06 1.6786417e-07 9.58271e-09 5.0295e-10 -9.008e-11 3.7e-12 8.35e-12 -5.2e-13 -3.2e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.06e-12 1.276e-11 -5.7e-11 9.601e-11 3.57649e-09 6.132509e-08 9.5514136e-07 1.28967766e-05 0.00014714173693 0.00137112165792 0.00986042371564 0.05608491364693 0.14748869124828 0.16849395858036 0.08757870956904 0.02576101233218 0.00284730572698 0.0003444493969 -7.456805235e-05 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0816434408622 0.15736904226042 0.08158884461609 0.02588545288926 0.00317113675443 0.00034326828609 3.027117313e-05 2.25818525e-06 1.4612698e-07 8.43472e-09 4.3188e-10 -8.872e-11 5.55e-12 7.84e-12 -5.9e-13 -2.9e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.06e-12 1.276e-11 -5.7e-11 9.601e-11 3.57649e-09 6.13251e-08 9.5514165e-07 1.289678177e-05 0.00014714181873 0.00137112277539 0.00986043784584 0.05608506974342 0.1474891668372 0.16849159926504 0.08758101660882 0.02577127458253 0.0028829220284 0.00024118004541 3.110317933e-05 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.04047589784669 0.02142323503434 0.00661775973331 0.00086245377253 9.677891862e-05 8.78678684e-06 6.7233157e-07 4.448319e-08 2.67577e-09 3.757e-11 -4.459e-11 1.302e-11 2.98e-12 -8e-13 -4e-14 5e-14 -0.0 -0.0 -0.0 6e-14 -9e-14 -8.5e-13 4.06e-12 1.276e-11 -5.7e-11 9.601e-11 3.57649e-09 6.132509e-08 9.5514143e-07 1.289677792e-05 0.00014714175892 0.00137112200108 0.00986042955118 0.05608499337059 0.14748900937526 0.16849274477962 0.08757873603022 0.02577133662423 0.00288834020821 0.00023657924056 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.00552645355567 0.00766952409719 0.00202301301163 0.00025021621351 2.665471663e-05 2.36482013e-06 1.7946809e-07 1.189247e-08 7.2908e-10 -9.607e-11 -3.87e-12 1.128e-11 -1.1e-13 -5.5e-13 8e-14 2e-14 -1e-14 -0.0 -0.0 6e-14 -9e-14 -8.5e-13 4.06e-12 1.276e-11 -5.7e-11 9.601e-11 3.57649e-09 6.132509e-08 9.5514125e-07 1.289677436e-05 0.0001471417005 0.00137112113368 0.00986041588562 0.05608481753275 0.14748823944956 0.16849479740968 0.08757815195705 0.02573665967029 0.0028535856797 0.00040249832518 0.0 0.0 0.0 0.0 0.0 D/cons.5.00.000000.dat 2.5000005 2.5000005 2.5000005 2.5000005 2.5000005 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 2.5000005 2.5000005 2.5000005 2.5000005 2.5000005 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 2.5000005 2.5000005 2.5000005 2.5000005 2.5000005 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 2.5000005 2.5000005 2.5000005 2.5000005 2.5000005 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 2.5000005 2.5000005 2.5000005 2.5000005 2.5000005 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 2.5000005 2.5000005 2.5000005 2.5000005 2.5000005 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 2.5000005 2.5000005 2.5000005 2.5000005 2.5000005 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 2.5000005 2.5000005 2.5000005 2.5000005 2.5000005 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 2.5000005 2.5000005 2.5000005 2.5000005 2.5000005 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 2.5000005 2.5000005 2.5000005 2.5000005 2.5000005 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 2.5000005 2.5000005 2.5000005 2.5000005 2.5000005 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 2.5000005 2.5000005 2.5000005 2.5000005 2.5000005 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 2.5000005 2.5000005 2.5000005 2.5000005 2.5000005 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 2.5000005 2.5000005 2.5000005 2.5000005 2.5000005 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 2.5000005 2.5000005 2.5000005 2.5000005 2.5000005 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 2.5000005 2.5000005 2.5000005 2.5000005 2.5000005 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 2.5000005 2.5000005 2.5000005 2.5000005 2.5000005 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 2.5000005 2.5000005 2.5000005 2.5000005 2.5000005 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 2.5000005 2.5000005 2.5000005 2.5000005 2.5000005 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 2.5000005 2.5000005 2.5000005 2.5000005 2.5000005 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 2.5000005 2.5000005 2.5000005 2.5000005 2.5000005 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 2.5000005 2.5000005 2.5000005 2.5000005 2.5000005 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 2.5000005 2.5000005 2.5000005 2.5000005 2.5000005 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 2.5000005 2.5000005 2.5000005 2.5000005 2.5000005 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 2.5000005 2.5000005 2.5000005 2.5000005 2.5000005 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 2.5000005 2.5000005 2.5000005 2.5000005 2.5000005 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 2.5000005 2.5000005 2.5000005 2.5000005 2.5000005 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 2.5000005 2.5000005 2.5000005 2.5000005 2.5000005 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 2.5000005 2.5000005 2.5000005 2.5000005 2.5000005 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 2.5000005 2.5000005 2.5000005 2.5000005 2.5000005 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 2.5000005 2.5000005 2.5000005 2.5000005 2.5000005 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 2.5000005 2.5000005 2.5000005 2.5000005 2.5000005 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 2.5000005 2.5000005 2.5000005 2.5000005 2.5000005 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 2.5000005 2.5000005 2.5000005 2.5000005 2.5000005 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 2.5000005 2.5000005 2.5000005 2.5000005 2.5000005 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 2.5000005 2.5000005 2.5000005 2.5000005 2.5000005 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 2.5000005 2.5000005 2.5000005 2.5000005 2.5000005 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 2.5000005 2.5000005 2.5000005 2.5000005 2.5000005 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 2.5000005 2.5000005 2.5000005 2.5000005 2.5000005 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 2.5000005 2.5000005 2.5000005 2.5000005 2.5000005 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 2.5000005 2.5000005 2.5000005 2.5000005 2.5000005 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 2.5000005 2.5000005 2.5000005 2.5000005 2.5000005 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 2.5000005 2.5000005 2.5000005 2.5000005 2.5000005 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 2.5000005 2.5000005 2.5000005 2.5000005 2.5000005 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 2.5000005 2.5000005 2.5000005 2.5000005 2.5000005 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 2.5000005 2.5000005 2.5000005 2.5000005 2.5000005 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 2.5000005 2.5000005 2.5000005 2.5000005 2.5000005 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 2.5000005 2.5000005 2.5000005 2.5000005 2.5000005 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 2.5000005 2.5000005 2.5000005 2.5000005 2.5000005 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 2.5000005 2.5000005 2.5000005 2.5000005 2.5000005 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 0.25000005125 -D/cons.5.00.000050.dat 2.5000005 1.28771041314719 1.28237101785773 1.37307654778956 1.43475330123318 1.35660675728342 1.30054614844904 1.25991425124101 1.25129413041918 1.25013881729124 1.25001247310416 1.25000116502543 1.25000030937765 1.25000025319241 1.25000024982679 1.25000024994805 1.25000025003876 1.2500002500021 1.25000024999797 1.25000025000015 1.2500002500001 1.25000024999998 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.2500002499881 1.2500002499612 1.25000025016886 1.2500002496768 1.25000023973798 1.25000006865025 1.24999742456292 1.24996210092923 1.24956500663485 1.24594455086714 1.22083645349903 1.08237528674293 0.79003326268914 0.59406963222032 0.48467788019111 0.32343341733435 0.25830676662374 0.25076614044385 0.25071711903441 0.25601082174762 0.31390121852853 0.38551924399443 0.25000005125 2.32938914486433 1.65542639644012 1.53800639041291 1.48147378863281 1.45004363379841 1.39733216165837 1.34368075357703 1.27415382549456 1.25305959795245 1.25033828856222 1.25003062233096 1.25000255491343 1.25000040087012 1.25000025849399 1.25000025020754 1.25000024985379 1.2500002500396 1.2500002500097 1.25000024999758 1.25000024999983 1.25000025000016 1.25000024999999 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.2500002499881 1.2500002499612 1.25000025016886 1.2500002496768 1.25000023973798 1.25000006865026 1.24999742456303 1.24996210093128 1.24956500666307 1.2459445509859 1.22083644355696 1.08237510864833 0.79003214440013 0.594074845035 0.48466582355736 0.32333659530386 0.25830401887428 0.25087332148925 0.25066250441678 0.25137057586653 0.25515536027337 0.25129307057795 0.70241313023696 2.17550169629771 2.19598445470439 1.88281614868001 1.67347269643493 1.60038189964261 1.50814734033859 1.47386695706 1.32489584471257 1.25913429292912 1.25098654631294 1.2500871217263 1.2500067214321 1.25000066836847 1.25000027411893 1.25000025113248 1.25000024976771 1.25000025001625 1.25000025002272 1.25000024999829 1.25000024999916 1.2500002500002 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.2500002499881 1.2500002499612 1.25000025016886 1.2500002496768 1.25000023973798 1.25000006865028 1.24999742456348 1.24996210093994 1.24956500680644 1.24594455299033 1.22083646775563 1.08237532900622 0.79003127418425 0.59407748265339 0.48466235470915 0.32336030241924 0.25825024407567 0.25087131979421 0.24997495531588 0.25003836908334 0.25072680794807 0.26229207737801 0.66512591009523 2.21147018220874 2.35676158049132 2.21712121713238 1.93231058212771 1.70098015430335 1.56821572371889 1.52394914687361 1.34084539182835 1.26107879939841 1.25118744811927 1.2501039110033 1.25000790666384 1.2500007411427 1.25000027807854 1.2500002513185 1.25000024976442 1.25000025001067 1.25000025002462 1.25000024999849 1.25000024999905 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.2500002499881 1.2500002499612 1.25000025016886 1.2500002496768 1.25000023973798 1.25000006865025 1.24999742456285 1.24996210092794 1.24956500661503 1.24594455056711 1.22083644700865 1.08237519975091 0.79003264817951 0.59407249689634 0.48466707893663 0.32339534781762 0.25829342422411 0.2508756054162 0.24995889264239 0.25239537483318 0.2617568748844 0.39201884529681 0.79308593048212 2.26327941718504 2.28123797378839 2.42376234114102 2.1902788451886 1.9053232561305 1.66982049242096 1.54493225969944 1.33686274723773 1.26054216255183 1.25113755871825 1.25009977479429 1.25000762196749 1.25000072438254 1.25000027713242 1.25000025126516 1.25000024976335 1.25000025001298 1.25000025002418 1.25000024999838 1.25000024999908 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.2500002499881 1.2500002499612 1.25000025016886 1.2500002496768 1.25000023973798 1.25000006865024 1.24999742456261 1.24996210092331 1.24956500653793 1.24594454956784 1.22083643931184 1.08237515875682 0.79003403578279 0.59406770287149 0.48468629603197 0.32345784663035 0.25827390769754 0.25072923256219 0.25076037896476 0.25595145803994 0.28352053221681 0.52588195746334 0.88159264805716 1.62275399267511 2.2111177711593 2.36432338946193 2.25364631251102 1.94963262381698 1.68693481416045 1.54614238609352 1.33514618408157 1.26036344962438 1.25112084933293 1.25009850818288 1.25000754153213 1.25000071964828 1.25000027683623 1.25000025125144 1.25000024976377 1.25000025001333 1.25000025002402 1.25000024999837 1.25000024999909 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.2500002499881 1.2500002499612 1.25000025016886 1.2500002496768 1.25000023973798 1.25000006865023 1.24999742456255 1.2499621009224 1.24956500652659 1.24594454926264 1.22083642330458 1.08237490396598 0.79003240485768 0.59407713396473 0.48469075541377 0.32340042481391 0.2581124976028 0.25124677632859 0.25113280294233 0.26509476701976 0.38904878639213 0.74902369781545 1.08958978249324 1.4994418080043 2.17563740619144 2.35585216972188 2.26950105213554 1.95624770775301 1.68959390734255 1.54558567723252 1.33463531486453 1.26031730853377 1.25111702152282 1.25009824603188 1.25000752569009 1.25000071877759 1.25000027680453 1.25000025125078 1.25000024976372 1.25000025001333 1.25000025002402 1.25000024999837 1.25000024999909 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.2500002499881 1.2500002499612 1.25000025016886 1.2500002496768 1.25000023973798 1.25000006865023 1.24999742456254 1.24996210092223 1.24956500652381 1.24594454919681 1.22083642082348 1.08237486417439 0.79003226313922 0.59407784080274 0.48469296431156 0.32339323622067 0.2580961279969 0.25132004507773 0.25124060766019 0.26673995893773 0.40280096628655 0.75227643296502 1.07210935517376 1.45462819238286 2.16616404847065 2.35410972170351 2.27172372746813 1.95708242340229 1.68983230453157 1.54543421763858 1.33456807083054 1.26031181813031 1.25111659975841 1.2500982184265 1.2500075243799 1.25000071877575 1.25000027680896 1.25000025125103 1.25000024976367 1.25000025001334 1.25000025002403 1.25000024999837 1.25000024999909 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.2500002499881 1.2500002499612 1.25000025016886 1.2500002496768 1.25000023973798 1.25000006865023 1.24999742456254 1.24996210092219 1.24956500652323 1.24594454918767 1.22083642063683 1.08237486067396 0.79003225672225 0.59407786502378 0.48469326068791 0.32339203561987 0.25809449085338 0.25133243166538 0.25125728120268 0.26704113956456 0.40528375287396 0.75125468651125 1.05179698532125 1.4487976431273 2.16490367506626 2.35392323487938 2.2719769319136 1.95716699081776 1.68984778567102 1.5454169800776 1.3345612651318 1.26031130740058 1.25111656295786 1.2500982162533 1.25000752440692 1.25000071877701 1.25000027680864 1.25000025125098 1.25000024976367 1.25000025001334 1.25000025002403 1.25000024999837 1.25000024999909 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.2500002499881 1.2500002499612 1.25000025016886 1.2500002496768 1.25000023973798 1.25000006865023 1.24999742456254 1.2499621009222 1.24956500652321 1.2459445491865 1.22083642060792 1.08237486051188 0.79003225644853 0.59407786425177 0.48469329319397 0.32339196092043 0.2580943815574 0.2513333292264 0.25125893495293 0.26707096292002 0.40551622982956 0.75089038815575 1.04814146955543 1.44817948457773 2.1647711578621 2.35390674960464 2.27200030847654 1.95717399022528 1.68984835334902 1.54541533832189 1.33456070808648 1.26031126847479 1.25111656029696 1.25009821632685 1.25000752439753 1.25000071877318 1.25000027680831 1.25000025125097 1.25000024976367 1.25000025001334 1.25000025002403 1.25000024999837 1.25000024999909 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.2500002499881 1.2500002499612 1.25000025016886 1.2500002496768 1.25000023973798 1.25000006865023 1.24999742456254 1.24996210092219 1.24956500652321 1.24594454918657 1.2208364206075 1.08237486051245 0.79003225628444 0.59407786413954 0.48469329598046 0.32339195684444 0.25809437472931 0.25133338661826 0.25125906766679 0.26707338004666 0.4055341809066 0.75083345095187 1.04772760453119 1.44812686993988 2.16475996958265 2.35390553379242 2.27200211501535 1.95717447744566 1.68984834282363 1.54541521157049 1.33456066968646 1.26031126587986 1.25111656039045 1.25009821632698 1.25000752438784 1.25000071877261 1.25000027680829 1.25000025125097 1.25000024976367 1.25000025001334 1.25000025002403 1.25000024999837 1.25000024999909 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.2500002499881 1.2500002499612 1.25000025016886 1.2500002496768 1.25000023973798 1.25000006865023 1.24999742456254 1.24996210092219 1.24956500652321 1.24594454918653 1.22083642060731 1.08237486050276 0.79003225624929 0.59407786426171 0.48469329604288 0.323391956707 0.25809437443776 0.25133338962119 0.25125907663017 0.26707354511211 0.40553531535055 0.75082708804042 1.04768935130325 1.44812311983274 2.16475917832545 2.35390545664642 2.27200223447826 1.95717450702192 1.68984833877603 1.54541520296357 1.33456066721942 1.26031126600182 1.25111656040947 1.25009821631153 1.2500075243878 1.25000071877272 1.2500002768083 1.25000025125097 1.25000024976367 1.25000025001334 1.25000025002403 1.25000024999837 1.25000024999909 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.2500002499881 1.2500002499612 1.25000025016886 1.2500002496768 1.25000023973798 1.25000006865023 1.24999742456254 1.24996210092219 1.2495650065232 1.24594454918651 1.2208364206071 1.08237486050124 0.7900322562663 0.59407786425184 0.4846932959713 0.32339195677926 0.25809437448872 0.25133338962774 0.25125907698135 0.26707355491483 0.40553537641506 0.75082653089893 1.0476864288339 1.44812288961801 2.16475912990633 2.35390545171735 2.2720022419473 1.95717450907255 1.68984833853071 1.54541520253119 1.33456066739429 1.26031126602762 1.25111656038969 1.25009821631154 1.25000752438804 1.25000071877273 1.2500002768083 1.25000025125097 1.25000024976367 1.25000025001334 1.25000025002403 1.25000024999837 1.25000024999909 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.2500002499881 1.2500002499612 1.25000025016886 1.2500002496768 1.25000023973798 1.25000006865023 1.24999742456254 1.24996210092219 1.2495650065232 1.24594454918651 1.2208364206071 1.0823748605013 0.79003225626691 0.59407786424147 0.48469329599093 0.32339195677095 0.25809437447384 0.25133338958562 0.25125907690319 0.26707355526755 0.40553537889429 0.75082649005777 1.04768623863001 1.44812287690543 2.16475912689733 2.35390545185173 2.27200224217089 1.95717450873953 1.68984833866033 1.54541520275373 1.33456066743808 1.26031126600648 1.25111656038922 1.25009821631197 1.25000752438801 1.25000071877272 1.2500002768083 1.25000025125097 1.25000024976367 1.25000025001334 1.25000025002403 1.25000024999837 1.25000024999909 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.2500002499881 1.2500002499612 1.25000025016886 1.2500002496768 1.25000023973798 1.25000006865023 1.24999742456254 1.24996210092219 1.2495650065232 1.24594454918651 1.22083642060711 1.08237486050133 0.79003225626606 0.59407786424223 0.48469329599557 0.32339195676625 0.25809437446945 0.2513333896037 0.25125907691929 0.26707355520618 0.40553537890313 0.75082648755217 1.04768622765671 1.44812287619269 2.16475912713329 2.35390545194232 2.2720022419895 1.95717450871019 1.68984833864378 1.54541520272659 1.33456066741182 1.26031126600577 1.25111656038986 1.25009821631189 1.250007524388 1.25000071877272 1.2500002768083 1.25000025125097 1.25000024976367 1.25000025001334 1.25000025002403 1.25000024999837 1.25000024999909 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.2500002499881 1.2500002499612 1.25000025016886 1.2500002496768 1.25000023973798 1.25000006865023 1.24999742456254 1.24996210092219 1.2495650065232 1.24594454918651 1.2208364206071 1.08237486050133 0.79003225626613 0.59407786424267 0.48469329599439 0.32339195676672 0.2580943744704 0.25133338960565 0.25125907692657 0.26707355522627 0.40553537887785 0.75082648761955 1.0476862270805 1.44812287641258 2.16475912718433 2.35390545190732 2.27200224202376 1.95717450874326 1.68984833863392 1.54541520271084 1.33456066741002 1.26031126600651 1.25111656038978 1.25009821631188 1.250007524388 1.25000071877272 1.2500002768083 1.25000025125097 1.25000024976367 1.25000025001334 1.25000025002403 1.25000024999837 1.25000024999909 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.2500002499881 1.2500002499612 1.25000025016886 1.2500002496768 1.25000023973798 1.25000006865023 1.24999742456254 1.24996210092219 1.2495650065232 1.24594454918651 1.2208364206071 1.08237486050132 0.79003225626616 0.59407786424259 0.48469329599429 0.32339195676689 0.25809437447049 0.25133338960469 0.25125907692546 0.26707355523109 0.40553537889546 0.75082648767997 1.04768622729874 1.44812287639617 2.16475912715352 2.35390545190334 2.27200224203458 1.95717450874368 1.68984833863499 1.54541520271298 1.33456066741119 1.26031126600643 1.25111656038975 1.25009821631188 1.250007524388 1.25000071877272 1.2500002768083 1.25000025125097 1.25000024976367 1.25000025001334 1.25000025002403 1.25000024999837 1.25000024999909 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.2500002499881 1.2500002499612 1.25000025016886 1.2500002496768 1.25000023973798 1.25000006865023 1.24999742456254 1.24996210092219 1.2495650065232 1.24594454918651 1.2208364206071 1.08237486050132 0.79003225626616 0.59407786424257 0.48469329599437 0.32339195676686 0.25809437447043 0.25133338960471 0.25125907692524 0.26707355522978 0.40553537889477 0.75082648765648 1.04768622727443 1.44812287638057 2.16475912715177 2.353905451905 2.27200224203224 1.95717450874204 1.68984833863534 1.54541520271353 1.33456066741114 1.26031126600641 1.25111656038976 1.25009821631188 1.250007524388 1.25000071877272 1.2500002768083 1.25000025125097 1.25000024976367 1.25000025001334 1.25000025002403 1.25000024999837 1.25000024999909 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.2500002499881 1.2500002499612 1.25000025016886 1.2500002496768 1.25000023973798 1.25000006865023 1.24999742456254 1.24996210092219 1.2495650065232 1.24594454918651 1.2208364206071 1.08237486050132 0.79003225626616 0.59407786424258 0.48469329599437 0.32339195676685 0.25809437447043 0.25133338960476 0.25125907692533 0.26707355522969 0.40553537889378 0.7508264876528 1.04768622725943 1.44812287638206 2.16475912715311 2.35390545190499 2.27200224203202 1.95717450874221 1.68984833863525 1.54541520271335 1.33456066741108 1.26031126600641 1.25111656038976 1.25009821631188 1.250007524388 1.25000071877272 1.2500002768083 1.25000025125097 1.25000024976367 1.25000025001334 1.25000025002403 1.25000024999837 1.25000024999909 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.2500002499881 1.2500002499612 1.25000025016886 1.2500002496768 1.25000023973798 1.25000006865023 1.24999742456254 1.24996210092219 1.2495650065232 1.24594454918651 1.2208364206071 1.08237486050132 0.79003225626616 0.59407786424258 0.48469329599436 0.32339195676685 0.25809437447043 0.25133338960476 0.25125907692533 0.26707355522978 0.40553537889396 0.75082648765401 1.04768622726155 1.4481228763826 2.16475912715306 2.35390545190491 2.27200224203217 1.95717450874228 1.68984833863524 1.54541520271334 1.33456066741109 1.26031126600641 1.25111656038976 1.25009821631188 1.250007524388 1.25000071877272 1.2500002768083 1.25000025125097 1.25000024976367 1.25000025001334 1.25000025002403 1.25000024999837 1.25000024999909 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.25000024998809 1.2500002499612 1.25000025016886 1.2500002496768 1.25000023973798 1.25000006865023 1.24999742456254 1.24996210092219 1.2495650065232 1.24594454918651 1.2208364206071 1.08237486050132 0.79003225626616 0.59407786424258 0.48469329599436 0.32339195676685 0.25809437447043 0.25133338960476 0.25125907692533 0.26707355522978 0.405535378894 0.7508264876541 1.04768622726201 1.44812287638246 2.164759127153 2.35390545190492 2.27200224203217 1.95717450874227 1.68984833863524 1.54541520271335 1.33456066741109 1.26031126600641 1.25111656038976 1.25009821631188 1.250007524388 1.25000071877272 1.2500002768083 1.25000025125097 1.25000024976367 1.25000025001334 1.25000025002403 1.25000024999837 1.25000024999909 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.2500002499881 1.2500002499612 1.25000025016886 1.2500002496768 1.25000023973798 1.25000006865023 1.24999742456254 1.24996210092219 1.2495650065232 1.24594454918651 1.2208364206071 1.08237486050132 0.79003225626616 0.59407786424258 0.48469329599436 0.32339195676685 0.25809437447043 0.25133338960476 0.25125907692533 0.26707355522977 0.40553537889399 0.75082648765403 1.04768622726184 1.44812287638244 2.164759127153 2.35390545190492 2.27200224203216 1.95717450874226 1.68984833863524 1.54541520271335 1.33456066741109 1.26031126600641 1.25111656038976 1.25009821631188 1.250007524388 1.25000071877272 1.2500002768083 1.25000025125097 1.25000024976367 1.25000025001334 1.25000025002403 1.25000024999837 1.25000024999909 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.2500002499881 1.2500002499612 1.25000025016886 1.2500002496768 1.25000023973798 1.25000006865023 1.24999742456254 1.24996210092219 1.2495650065232 1.24594454918651 1.2208364206071 1.08237486050132 0.79003225626616 0.59407786424258 0.48469329599436 0.32339195676685 0.25809437447043 0.25133338960476 0.25125907692533 0.26707355522977 0.40553537889399 0.75082648765403 1.04768622726184 1.44812287638245 2.164759127153 2.35390545190492 2.27200224203216 1.95717450874226 1.68984833863524 1.54541520271335 1.33456066741109 1.26031126600641 1.25111656038976 1.25009821631188 1.250007524388 1.25000071877272 1.2500002768083 1.25000025125097 1.25000024976367 1.25000025001334 1.25000025002403 1.25000024999837 1.25000024999909 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.25000024998809 1.2500002499612 1.25000025016886 1.2500002496768 1.25000023973798 1.25000006865023 1.24999742456254 1.24996210092219 1.2495650065232 1.24594454918651 1.2208364206071 1.08237486050132 0.79003225626616 0.59407786424258 0.48469329599436 0.32339195676685 0.25809437447043 0.25133338960476 0.25125907692533 0.26707355522977 0.40553537889399 0.75082648765403 1.04768622726184 1.44812287638245 2.164759127153 2.35390545190492 2.27200224203216 1.95717450874227 1.68984833863524 1.54541520271335 1.33456066741109 1.26031126600641 1.25111656038976 1.25009821631188 1.250007524388 1.25000071877272 1.2500002768083 1.25000025125097 1.25000024976367 1.25000025001334 1.25000025002403 1.25000024999837 1.25000024999909 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.2500002499881 1.2500002499612 1.25000025016886 1.2500002496768 1.25000023973798 1.25000006865023 1.24999742456254 1.24996210092219 1.2495650065232 1.24594454918651 1.2208364206071 1.08237486050132 0.79003225626616 0.59407786424258 0.48469329599436 0.32339195676685 0.25809437447043 0.25133338960476 0.25125907692533 0.26707355522977 0.40553537889399 0.75082648765403 1.04768622726184 1.44812287638245 2.164759127153 2.35390545190492 2.27200224203216 1.95717450874226 1.68984833863524 1.54541520271335 1.33456066741109 1.26031126600641 1.25111656038976 1.25009821631188 1.250007524388 1.25000071877272 1.2500002768083 1.25000025125097 1.25000024976367 1.25000025001334 1.25000025002403 1.25000024999837 1.25000024999909 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.2500002499881 1.2500002499612 1.25000025016886 1.2500002496768 1.25000023973798 1.25000006865023 1.24999742456254 1.24996210092219 1.2495650065232 1.24594454918651 1.2208364206071 1.08237486050132 0.79003225626616 0.59407786424258 0.48469329599436 0.32339195676685 0.25809437447043 0.25133338960476 0.25125907692533 0.26707355522977 0.40553537889399 0.75082648765403 1.04768622726184 1.44812287638245 2.164759127153 2.35390545190492 2.27200224203216 1.95717450874227 1.68984833863524 1.54541520271335 1.33456066741109 1.26031126600641 1.25111656038976 1.25009821631188 1.250007524388 1.25000071877272 1.2500002768083 1.25000025125097 1.25000024976367 1.25000025001334 1.25000025002403 1.25000024999837 1.25000024999909 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.2500002499881 1.2500002499612 1.25000025016886 1.2500002496768 1.25000023973798 1.25000006865023 1.24999742456254 1.24996210092219 1.2495650065232 1.24594454918651 1.2208364206071 1.08237486050132 0.79003225626616 0.59407786424258 0.48469329599436 0.32339195676685 0.25809437447043 0.25133338960476 0.25125907692533 0.26707355522977 0.40553537889399 0.75082648765403 1.04768622726184 1.44812287638245 2.164759127153 2.35390545190492 2.27200224203216 1.95717450874227 1.68984833863524 1.54541520271335 1.33456066741109 1.26031126600641 1.25111656038976 1.25009821631188 1.250007524388 1.25000071877272 1.2500002768083 1.25000025125097 1.25000024976367 1.25000025001334 1.25000025002403 1.25000024999837 1.25000024999909 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.25000024998809 1.2500002499612 1.25000025016886 1.2500002496768 1.25000023973798 1.25000006865023 1.24999742456254 1.24996210092219 1.2495650065232 1.24594454918651 1.2208364206071 1.08237486050132 0.79003225626616 0.59407786424258 0.48469329599436 0.32339195676685 0.25809437447043 0.25133338960476 0.25125907692533 0.26707355522977 0.40553537889399 0.75082648765403 1.04768622726184 1.44812287638245 2.164759127153 2.35390545190492 2.27200224203216 1.95717450874227 1.68984833863524 1.54541520271334 1.33456066741109 1.26031126600641 1.25111656038976 1.25009821631188 1.250007524388 1.25000071877272 1.2500002768083 1.25000025125097 1.25000024976367 1.25000025001334 1.25000025002403 1.25000024999837 1.25000024999909 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.25000024998809 1.2500002499612 1.25000025016886 1.2500002496768 1.25000023973798 1.25000006865023 1.24999742456254 1.24996210092219 1.2495650065232 1.24594454918651 1.2208364206071 1.08237486050132 0.79003225626616 0.59407786424258 0.48469329599436 0.32339195676685 0.25809437447043 0.25133338960476 0.25125907692533 0.26707355522977 0.40553537889399 0.75082648765403 1.04768622726184 1.44812287638244 2.164759127153 2.35390545190492 2.27200224203216 1.95717450874226 1.68984833863524 1.54541520271335 1.33456066741109 1.26031126600641 1.25111656038976 1.25009821631188 1.250007524388 1.25000071877272 1.2500002768083 1.25000025125097 1.25000024976367 1.25000025001334 1.25000025002403 1.25000024999837 1.25000024999909 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.2500002499881 1.2500002499612 1.25000025016886 1.2500002496768 1.25000023973798 1.25000006865023 1.24999742456254 1.24996210092219 1.2495650065232 1.24594454918651 1.2208364206071 1.08237486050132 0.79003225626616 0.59407786424258 0.48469329599436 0.32339195676685 0.25809437447043 0.25133338960476 0.25125907692533 0.26707355522977 0.40553537889399 0.75082648765403 1.04768622726183 1.44812287638246 2.16475912715299 2.35390545190492 2.27200224203217 1.95717450874227 1.68984833863524 1.54541520271335 1.33456066741109 1.26031126600641 1.25111656038976 1.25009821631188 1.250007524388 1.25000071877272 1.2500002768083 1.25000025125097 1.25000024976367 1.25000025001334 1.25000025002403 1.25000024999837 1.25000024999909 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.2500002499881 1.2500002499612 1.25000025016886 1.2500002496768 1.25000023973798 1.25000006865023 1.24999742456254 1.24996210092219 1.2495650065232 1.24594454918651 1.2208364206071 1.08237486050132 0.79003225626616 0.59407786424258 0.48469329599436 0.32339195676685 0.25809437447043 0.25133338960476 0.25125907692533 0.26707355522977 0.40553537889399 0.75082648765402 1.04768622726185 1.44812287638261 2.16475912715308 2.35390545190491 2.27200224203217 1.95717450874227 1.68984833863523 1.54541520271334 1.33456066741109 1.26031126600641 1.25111656038976 1.25009821631188 1.250007524388 1.25000071877272 1.2500002768083 1.25000025125097 1.25000024976367 1.25000025001334 1.25000025002403 1.25000024999837 1.25000024999909 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.2500002499881 1.2500002499612 1.25000025016886 1.2500002496768 1.25000023973798 1.25000006865023 1.24999742456254 1.24996210092219 1.2495650065232 1.24594454918651 1.2208364206071 1.08237486050132 0.79003225626616 0.59407786424258 0.48469329599436 0.32339195676685 0.25809437447043 0.25133338960476 0.25125907692533 0.26707355522977 0.405535378894 0.75082648765412 1.04768622726203 1.448122876382 2.16475912715317 2.35390545190505 2.27200224203204 1.95717450874225 1.68984833863528 1.54541520271334 1.33456066741108 1.26031126600641 1.25111656038976 1.25009821631188 1.250007524388 1.25000071877272 1.2500002768083 1.25000025125097 1.25000024976367 1.25000025001334 1.25000025002403 1.25000024999837 1.25000024999909 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.25000024998809 1.2500002499612 1.25000025016886 1.2500002496768 1.25000023973798 1.25000006865023 1.24999742456254 1.24996210092219 1.2495650065232 1.24594454918651 1.2208364206071 1.08237486050132 0.79003225626616 0.59407786424258 0.48469329599436 0.32339195676685 0.25809437447043 0.25133338960476 0.25125907692533 0.26707355522977 0.40553537889402 0.75082648765406 1.04768622726141 1.44812287638052 2.1647591271513 2.35390545190501 2.27200224203222 1.95717450874224 1.68984833863539 1.54541520271354 1.33456066741112 1.26031126600641 1.25111656038976 1.25009821631188 1.250007524388 1.25000071877272 1.2500002768083 1.25000025125097 1.25000024976367 1.25000025001334 1.25000025002403 1.25000024999837 1.25000024999909 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.2500002499881 1.2500002499612 1.25000025016886 1.2500002496768 1.25000023973798 1.25000006865023 1.24999742456254 1.24996210092219 1.2495650065232 1.24594454918651 1.2208364206071 1.08237486050132 0.79003225626616 0.59407786424258 0.48469329599436 0.32339195676685 0.25809437447043 0.25133338960476 0.25125907692533 0.26707355522979 0.40553537889369 0.75082648765238 1.04768622725949 1.44812287639797 2.16475912715444 2.35390545190246 2.2720022420343 1.95717450874258 1.68984833863437 1.54541520271308 1.33456066741122 1.26031126600642 1.25111656038975 1.25009821631188 1.250007524388 1.25000071877272 1.2500002768083 1.25000025125097 1.25000024976367 1.25000025001334 1.25000025002403 1.25000024999837 1.25000024999909 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.2500002499881 1.2500002499612 1.25000025016886 1.2500002496768 1.25000023973798 1.25000006865023 1.24999742456254 1.24996210092219 1.2495650065232 1.24594454918651 1.2208364206071 1.08237486050132 0.79003225626616 0.59407786424258 0.48469329599436 0.32339195676684 0.25809437447042 0.25133338960474 0.25125907692536 0.26707355522977 0.40553537889411 0.75082648765748 1.04768622727688 1.4481228764116 2.16475912719123 2.35390545191031 2.27200224202556 1.95717450874249 1.68984833863453 1.54541520271058 1.33456066741029 1.26031126600652 1.25111656038977 1.25009821631188 1.250007524388 1.25000071877272 1.2500002768083 1.25000025125097 1.25000024976367 1.25000025001334 1.25000025002403 1.25000024999837 1.25000024999909 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.25000024998809 1.2500002499612 1.25000025016886 1.2500002496768 1.25000023973798 1.25000006865023 1.24999742456254 1.24996210092219 1.2495650065232 1.24594454918651 1.2208364206071 1.08237486050132 0.79003225626616 0.59407786424257 0.48469329599438 0.32339195676688 0.25809437447044 0.25133338960471 0.25125907692533 0.2670735552296 0.40553537889946 0.75082648768628 1.04768622729568 1.44812287617673 2.16475912710967 2.35390545195251 2.27200224199245 1.95717450873473 1.68984833865595 1.54541520272466 1.33456066741029 1.26031126600593 1.25111656038987 1.25009821631189 1.250007524388 1.25000071877272 1.2500002768083 1.25000025125097 1.25000024976367 1.25000025001334 1.25000025002403 1.25000024999837 1.25000024999909 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.2500002499881 1.2500002499612 1.25000025016886 1.2500002496768 1.25000023973798 1.25000006865023 1.24999742456254 1.24996210092219 1.2495650065232 1.24594454918651 1.2208364206071 1.08237486050132 0.79003225626615 0.5940778642426 0.48469329599435 0.3233919567669 0.2580943744705 0.25133338960515 0.25125907692502 0.26707355523071 0.40553537888585 0.75082648759488 1.04768622706272 1.44812287702389 2.16475912694057 2.35390545180383 2.27200224214507 1.95717450873448 1.68984833864545 1.54541520275879 1.33456066743265 1.26031126600561 1.25111656038933 1.25009821631198 1.25000752438801 1.25000071877272 1.2500002768083 1.25000025125097 1.25000024976367 1.25000025001334 1.25000025002403 1.25000024999837 1.25000024999909 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.2500002499881 1.2500002499612 1.25000025016886 1.2500002496768 1.25000023973798 1.25000006865023 1.24999742456254 1.24996210092219 1.2495650065232 1.24594454918651 1.2208364206071 1.08237486050134 0.79003225626609 0.59407786424259 0.4846932959943 0.32339195676612 0.25809437446988 0.25133338960492 0.25125907692606 0.26707355522814 0.40553537885387 0.75082648762001 1.04768622777266 1.44812289157312 2.16475913097847 2.35390545185066 2.27200224206461 1.95717450887206 1.6898483384238 1.54541520255373 1.33456066742371 1.26031126602378 1.25111656038899 1.25009821631158 1.25000752438805 1.25000071877273 1.2500002768083 1.25000025125097 1.25000024976367 1.25000025001334 1.25000025002403 1.25000024999837 1.25000024999909 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.2500002499881 1.2500002499612 1.25000025016886 1.2500002496768 1.25000023973798 1.25000006865023 1.24999742456254 1.24996210092219 1.2495650065232 1.24594454918651 1.22083642060711 1.08237486050136 0.79003225626635 0.59407786424189 0.48469329599495 0.32339195676879 0.25809437447064 0.25133338959302 0.25125907692344 0.26707355522629 0.4055353791217 0.75082649136761 1.04768624036755 1.44812315003301 2.16475919552574 2.35390545912751 2.27200223629866 1.95717450835072 1.68984833962458 1.5454152028101 1.33456066718672 1.26031126601916 1.25111656040674 1.2500982163111 1.25000752438779 1.25000071877272 1.2500002768083 1.25000025125097 1.25000024976367 1.25000025001334 1.25000025002403 1.25000024999837 1.25000024999909 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.25000024998809 1.2500002499612 1.25000025016886 1.2500002496768 1.25000023973798 1.25000006865023 1.24999742456254 1.24996210092219 1.2495650065232 1.24594454918651 1.22083642060707 1.08237486050099 0.79003225626711 0.59407786424508 0.48469329599025 0.32339195678296 0.25809437448419 0.25133338961031 0.25125907693291 0.26707355514138 0.40553538061308 0.75082655198014 1.04768645474356 1.4481272741785 2.16476021645349 2.35390557302904 2.27200214883417 1.95717449608703 1.68984835184311 1.54541521005259 1.33456066866458 1.2603112658376 1.25111656040225 1.25009821632566 1.2500075243876 1.25000071877259 1.25000027680829 1.25000025125097 1.25000024976367 1.25000025001334 1.25000025002403 1.25000024999837 1.25000024999909 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.25000024998809 1.2500002499612 1.25000025016886 1.2500002496768 1.25000023973798 1.25000006865023 1.24999742456254 1.24996210092219 1.2495650065232 1.24594454918651 1.22083642060714 1.08237486050156 0.79003225626147 0.59407786425988 0.48469329598863 0.32339195672686 0.25809437444561 0.25133338968635 0.25125907696433 0.26707355155399 0.40553537375491 0.75082735980946 1.04768968911956 1.44818396412147 2.16477417214173 2.35390728567186 2.27200082665249 1.95717423548877 1.68984848500252 1.54541531925848 1.33456069426557 1.26031126747697 1.25111656025268 1.25009821633175 1.25000752439743 1.25000071877312 1.2500002768083 1.25000025125097 1.25000024976367 1.25000025001334 1.25000025002403 1.25000024999837 1.25000024999909 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.25000024998809 1.2500002499612 1.25000025016886 1.2500002496768 1.25000023973798 1.25000006865023 1.24999742456254 1.24996210092219 1.24956500652321 1.24594454918657 1.2208364206077 1.0823748605093 0.79003225626023 0.5940778641778 0.48469329607741 0.32339195685209 0.25809437447028 0.25133338838428 0.25125907510286 0.26707346649696 0.40553484798658 0.75083643249989 1.04773127045257 1.44883706350351 2.16493404347746 2.35392932492575 2.2719834343726 1.95716973454534 1.68984944035773 1.54541680148914 1.33456110157924 1.26031129478856 1.25111656209305 1.25009821621729 1.25000752440834 1.2500007187773 1.25000027680866 1.25000025125098 1.25000024976367 1.25000025001334 1.25000025002403 1.25000024999837 1.25000024999909 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.2500002499881 1.2500002499612 1.25000025016886 1.2500002496768 1.25000023973798 1.25000006865023 1.24999742456254 1.24996210092219 1.2495650065232 1.24594454918638 1.22083642060539 1.08237486049871 0.79003225638155 0.59407786419023 0.48469329558839 0.32339196082348 0.25809437821232 0.25133335472523 0.25125902296137 0.26707193955178 0.40552302077901 0.75092274888321 1.04817271664303 1.45488602890352 2.1664020173718 2.35416512275071 2.27178829595515 1.95710773122331 1.68984840019177 1.54543321582387 1.33456653538048 1.26031168819205 1.25111659021135 1.25009821785505 1.25000752434872 1.25000071877567 1.25000027680904 1.25000025125104 1.25000024976366 1.25000025001334 1.25000025002403 1.25000024999837 1.25000024999909 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.2500002499881 1.2500002499612 1.25000025016886 1.2500002496768 1.25000023973798 1.25000006865023 1.24999742456254 1.24996210092219 1.24956500652308 1.24594454918515 1.22083642060657 1.08237486049475 0.7900322570325 0.59407786450981 0.48469328650725 0.323392036654 0.25809446624272 0.25133273500911 0.25125811064431 0.26704986427034 0.40533060912819 0.75143400271203 1.05201995902139 1.50075414017454 2.17707775818273 2.35625384916335 2.26997560379394 1.95644120117793 1.68973206927633 1.54557833846431 1.33462442914957 1.26031630530062 1.25111694217059 1.25009824096296 1.25000752541737 1.25000071876133 1.25000027680391 1.25000025125077 1.25000024976371 1.25000025001334 1.25000025002402 1.25000024999837 1.25000024999909 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.2500002499881 1.2500002499612 1.25000025016886 1.2500002496768 1.25000023973798 1.25000006865023 1.24999742456254 1.24996210092218 1.24956500652316 1.24594454918972 1.22083642074764 1.08237486298063 0.79003227029304 0.59407784282996 0.48469316997037 0.32339326644619 0.25809603415422 0.2513231350166 0.25124655317388 0.26680069898177 0.40303624078708 0.75302275708572 1.07293554941358 1.62372070912612 2.21296668836419 2.36607386232852 2.25597083636228 1.9510373362148 1.68792577101082 1.5463779242168 1.33511886198575 1.26035992955444 1.25112050680737 1.25009848390721 1.25000754018481 1.25000071957138 1.2500002768316 1.25000025125126 1.25000024976378 1.25000025001334 1.25000025002402 1.25000024999837 1.25000024999909 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.2500002499881 1.2500002499612 1.25000025016886 1.2500002496768 1.25000023973798 1.25000006865023 1.24999742456254 1.24996210092229 1.24956500652531 1.24594454924566 1.22083642264905 1.0823748907272 0.79003240479215 0.59407725702044 0.48469192431196 0.32340186626944 0.25811193233929 0.25125998208175 0.25115767748227 0.26529655952153 0.38949014842951 0.74994475729068 1.09084203370899 2.2653574465929 2.28342467536133 2.42742368954988 2.19356794925205 1.91444604002328 1.67630880343301 1.54676135594731 1.33703003857736 1.26055329476089 1.25113841040714 1.25009983235796 1.25000762577309 1.25000072462068 1.25000027714387 1.2500002512655 1.25000024976335 1.25000025001298 1.25000025002418 1.25000024999838 1.25000024999908 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.2500002499881 1.2500002499612 1.25000025016886 1.2500002496768 1.25000023973798 1.25000006865023 1.24999742456253 1.24996210092184 1.24956500651618 1.24594454928597 1.22083643524686 1.08237510970953 0.79003404388661 0.59406820571036 0.4846901482205 0.32346283770569 0.25825838746008 0.25076259823637 0.25079904187644 0.2562183799047 0.28399344258391 0.52649112887573 0.88236644734338 2.21293402874531 2.35841621653486 2.22026193505462 1.94923010909349 1.73494560333722 1.5897486773084 1.53402739553053 1.34213681534349 1.26117469748791 1.2511963291234 1.25010453887693 1.25000794630805 1.2500007433816 1.25000027819817 1.25000025132382 1.25000024976441 1.25000025001051 1.25000025002467 1.2500002499985 1.25000024999905 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.25000024998809 1.2500002499612 1.25000025016886 1.2500002496768 1.25000023973798 1.25000006865022 1.24999742456232 1.24996210091788 1.24956500644927 1.24594454826525 1.22083641941801 1.08237493939252 0.79003309498392 0.59407106341725 0.48466973988691 0.32337919880963 0.25831150109953 0.25090569903229 0.25009240902869 0.25256055930519 0.26203410506729 0.39242229576972 0.79376495139749 2.17580149240474 2.197024901603 1.89157782268887 1.70743985455685 1.64153750845796 1.52819460273831 1.48096555448691 1.32358174374939 1.25902953424305 1.25098548713539 1.25008753828785 1.25000678193825 1.25000067354205 1.25000027444197 1.25000025115337 1.25000024976749 1.25000025001538 1.25000025002291 1.25000024999834 1.25000024999914 1.2500002500002 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.2500002499881 1.2500002499612 1.25000025016886 1.2500002496768 1.25000023973798 1.25000006865019 1.24999742456155 1.24996210090373 1.24956500622806 1.24594454529001 1.22083638294872 1.0823745925837 0.79003338861426 0.59406982543149 0.4846628244672 0.32329951465587 0.25837483459403 0.25083960192788 0.25027508408003 0.25016936476487 0.25076389179531 0.2623803623661 0.66531359840214 2.32943500056272 1.65631048324959 1.54937287349388 1.49612866138386 1.4450198024074 1.37075946457507 1.33846425553489 1.27329725375543 1.25290909294601 1.25031745520669 1.25002851011455 1.25000238445251 1.25000038990607 1.25000025790929 1.25000025017178 1.25000024986219 1.25000025003954 1.25000025000899 1.25000024999762 1.25000024999986 1.25000025000015 1.25000024999999 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.2500002499881 1.2500002499612 1.25000025016886 1.2500002496768 1.25000023973798 1.25000006865021 1.24999742456213 1.24996210091429 1.24956500638984 1.24594454734719 1.22083640432065 1.08237476389037 0.79003287284521 0.59407174099397 0.48466655355203 0.32331692137533 0.25833925619905 0.25086729915979 0.25071065980017 0.25135136321776 0.2551739314816 0.25130536745748 0.70250662666548 2.5000005 1.26054481201456 1.27544189662969 1.30891850816541 1.33377214865048 1.33504526889884 1.28246898173154 1.25747594508209 1.25088918446204 1.25009166557878 1.25000816106547 1.2500008391122 1.25000028833896 1.25000025199155 1.25000024973894 1.25000024998726 1.25000025003499 1.25000024999965 1.25000024999832 1.25000025000023 1.25000025000008 1.25000024999998 1.25000025000001 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.2500002499881 1.2500002499612 1.25000025016886 1.2500002496768 1.25000023973798 1.25000006865024 1.24999742456269 1.24996210092474 1.24956500656041 1.24594454985657 1.22083644300847 1.08237520299756 0.79003351072973 0.59406852240693 0.48467972267075 0.32343551221606 0.25831049760352 0.25075792552063 0.2507187074539 0.2565921302427 0.3138016114241 0.38796626532293 0.25000005125 +D/cons.5.00.000050.dat 2.5000005 1.28771041314719 1.28237101785773 1.37307654778956 1.43475330123318 1.35660675728342 1.30054614844904 1.25991425124101 1.25129413041918 1.25013881729124 1.25001247310416 1.25000116502543 1.25000030937765 1.25000025319241 1.25000024982679 1.25000024994805 1.25000025003876 1.2500002500021 1.25000024999797 1.25000025000015 1.2500002500001 1.25000024999998 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.2500002499881 1.2500002499612 1.25000025016886 1.2500002496768 1.25000023973798 1.25000006865025 1.24999742456292 1.24996210092923 1.24956500663485 1.24594455086714 1.22083645349903 1.08237528674293 0.79003326268914 0.59406963222032 0.48467788019111 0.32343341733435 0.25830676662374 0.25076614044385 0.25071711903441 0.25601082174762 0.31390121852853 0.38551924399443 0.25000005125 2.32938914486433 1.65542639644012 1.53800639041291 1.48147378863281 1.45004363379841 1.39733216165837 1.34368075357703 1.27415382549456 1.25305959795245 1.25033828856222 1.25003062233096 1.25000255491343 1.25000040087012 1.25000025849399 1.25000025020754 1.25000024985379 1.2500002500396 1.2500002500097 1.25000024999758 1.25000024999983 1.25000025000016 1.25000024999999 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.25000024998809 1.2500002499612 1.25000025016886 1.2500002496768 1.25000023973798 1.25000006865026 1.24999742456303 1.24996210093128 1.24956500666307 1.2459445509859 1.22083644355696 1.08237510864833 0.79003214440013 0.594074845035 0.48466582355736 0.32333659530386 0.25830401887428 0.25087332148925 0.25066250441678 0.25137057586653 0.25515536027337 0.25129307057795 0.70241313023696 2.17550169629771 2.19598445470439 1.88281614868001 1.67347269643493 1.60038189964261 1.50814734033859 1.47386695706 1.32489584471257 1.25913429292912 1.25098654631294 1.2500871217263 1.2500067214321 1.25000066836848 1.25000027411893 1.25000025113248 1.25000024976771 1.25000025001625 1.25000025002272 1.25000024999829 1.25000024999916 1.2500002500002 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.25000024998809 1.2500002499612 1.25000025016886 1.2500002496768 1.25000023973798 1.25000006865028 1.24999742456348 1.24996210093994 1.24956500680644 1.24594455299033 1.22083646775563 1.08237532900622 0.79003127418425 0.59407748265339 0.48466235470915 0.32336030241924 0.25825024407567 0.25087131979421 0.24997495531588 0.25003836908334 0.25072680794807 0.26229207737801 0.66512591009523 2.21147018220874 2.35676158049132 2.21712121713238 1.93231058212771 1.70098015430335 1.56821572371889 1.52394914687361 1.34084539182834 1.26107879939841 1.25118744811928 1.2501039110033 1.25000790666384 1.2500007411427 1.25000027807854 1.2500002513185 1.25000024976442 1.25000025001067 1.25000025002462 1.25000024999849 1.25000024999905 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.25000024998809 1.2500002499612 1.25000025016886 1.2500002496768 1.25000023973798 1.25000006865025 1.24999742456285 1.24996210092794 1.24956500661503 1.24594455056711 1.22083644700865 1.08237519975091 0.79003264817951 0.59407249689634 0.48466707893663 0.32339534781762 0.25829342422411 0.2508756054162 0.24995889264239 0.25239537483318 0.2617568748844 0.39201884529681 0.79308593048212 2.26327941718504 2.28123797378839 2.42376234114102 2.1902788451886 1.9053232561305 1.66982049242096 1.54493225969944 1.33686274723773 1.26054216255183 1.25113755871825 1.25009977479429 1.25000762196749 1.25000072438254 1.25000027713242 1.25000025126516 1.25000024976335 1.25000025001298 1.25000025002418 1.25000024999838 1.25000024999908 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.2500002499881 1.2500002499612 1.25000025016886 1.2500002496768 1.25000023973798 1.25000006865024 1.24999742456261 1.24996210092331 1.24956500653793 1.24594454956784 1.22083643931184 1.08237515875682 0.79003403578279 0.59406770287149 0.48468629603197 0.32345784663035 0.25827390769754 0.25072923256219 0.25076037896476 0.25595145803994 0.28352053221681 0.52588195746334 0.88159264805716 1.62275399267511 2.2111177711593 2.36432338946193 2.25364631251102 1.94963262381698 1.68693481416045 1.54614238609352 1.33514618408157 1.26036344962438 1.25112084933293 1.25009850818288 1.25000754153213 1.25000071964828 1.25000027683623 1.25000025125144 1.25000024976377 1.25000025001333 1.25000025002402 1.25000024999837 1.25000024999909 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.2500002499881 1.2500002499612 1.25000025016886 1.2500002496768 1.25000023973798 1.25000006865023 1.24999742456255 1.2499621009224 1.24956500652659 1.24594454926264 1.22083642330458 1.08237490396598 0.79003240485768 0.59407713396473 0.48469075541377 0.32340042481391 0.2581124976028 0.25124677632859 0.25113280294233 0.26509476701976 0.38904878639213 0.74902369781545 1.08958978249324 1.4994418080043 2.17563740619144 2.35585216972188 2.26950105213554 1.95624770775301 1.68959390734255 1.54558567723252 1.33463531486453 1.26031730853376 1.25111702152282 1.25009824603188 1.25000752569009 1.25000071877759 1.25000027680453 1.25000025125078 1.25000024976372 1.25000025001333 1.25000025002402 1.25000024999837 1.25000024999909 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.2500002499881 1.2500002499612 1.25000025016886 1.2500002496768 1.25000023973798 1.25000006865023 1.24999742456254 1.24996210092223 1.24956500652381 1.24594454919681 1.22083642082348 1.08237486417439 0.79003226313922 0.59407784080274 0.48469296431156 0.32339323622067 0.2580961279969 0.25132004507773 0.25124060766019 0.26673995893773 0.40280096628655 0.75227643296502 1.07210935517376 1.45462819238286 2.16616404847065 2.35410972170351 2.27172372746813 1.95708242340229 1.68983230453157 1.54543421763858 1.33456807083054 1.26031181813031 1.2511165997584 1.2500982184265 1.2500075243799 1.25000071877575 1.25000027680896 1.25000025125103 1.25000024976367 1.25000025001334 1.25000025002403 1.25000024999837 1.25000024999909 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.2500002499881 1.2500002499612 1.25000025016886 1.2500002496768 1.25000023973798 1.25000006865023 1.24999742456254 1.24996210092219 1.24956500652323 1.24594454918767 1.22083642063683 1.08237486067396 0.79003225672225 0.59407786502378 0.48469326068791 0.32339203561987 0.25809449085338 0.25133243166538 0.25125728120268 0.26704113956456 0.40528375287396 0.75125468651125 1.05179698532125 1.4487976431273 2.16490367506626 2.35392323487938 2.2719769319136 1.95716699081776 1.68984778567101 1.5454169800776 1.3345612651318 1.26031130740058 1.25111656295786 1.2500982162533 1.25000752440692 1.25000071877701 1.25000027680864 1.25000025125098 1.25000024976367 1.25000025001334 1.25000025002403 1.25000024999837 1.25000024999909 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.25000024998809 1.2500002499612 1.25000025016886 1.2500002496768 1.25000023973798 1.25000006865023 1.24999742456254 1.24996210092219 1.24956500652321 1.2459445491865 1.22083642060792 1.08237486051188 0.79003225644853 0.59407786425177 0.48469329319397 0.32339196092043 0.2580943815574 0.2513333292264 0.25125893495293 0.26707096292002 0.40551622982956 0.75089038815575 1.04814146955543 1.44817948457773 2.1647711578621 2.35390674960464 2.27200030847654 1.95717399022528 1.68984835334902 1.54541533832189 1.33456070808648 1.26031126847479 1.25111656029696 1.25009821632685 1.25000752439753 1.25000071877318 1.25000027680831 1.25000025125097 1.25000024976367 1.25000025001334 1.25000025002403 1.25000024999837 1.25000024999909 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.2500002499881 1.2500002499612 1.25000025016886 1.2500002496768 1.25000023973798 1.25000006865023 1.24999742456254 1.24996210092219 1.24956500652321 1.24594454918657 1.2208364206075 1.08237486051245 0.79003225628444 0.59407786413954 0.48469329598046 0.32339195684444 0.25809437472931 0.25133338661826 0.25125906766679 0.26707338004666 0.4055341809066 0.75083345095187 1.04772760453119 1.44812686993988 2.16475996958265 2.35390553379242 2.27200211501535 1.95717447744566 1.68984834282363 1.54541521157049 1.33456066968646 1.26031126587986 1.25111656039045 1.25009821632697 1.25000752438784 1.25000071877261 1.25000027680829 1.25000025125097 1.25000024976367 1.25000025001334 1.25000025002403 1.25000024999837 1.25000024999909 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.2500002499881 1.2500002499612 1.25000025016886 1.2500002496768 1.25000023973798 1.25000006865023 1.24999742456254 1.24996210092219 1.2495650065232 1.24594454918653 1.22083642060731 1.08237486050276 0.79003225624929 0.59407786426171 0.48469329604288 0.323391956707 0.25809437443776 0.25133338962119 0.25125907663017 0.26707354511211 0.40553531535055 0.75082708804042 1.04768935130325 1.44812311983274 2.16475917832545 2.35390545664642 2.27200223447826 1.95717450702192 1.68984833877603 1.54541520296357 1.33456066721942 1.26031126600182 1.25111656040947 1.25009821631153 1.2500075243878 1.25000071877272 1.2500002768083 1.25000025125097 1.25000024976367 1.25000025001334 1.25000025002403 1.25000024999837 1.25000024999909 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.2500002499881 1.2500002499612 1.25000025016886 1.2500002496768 1.25000023973798 1.25000006865023 1.24999742456254 1.24996210092219 1.2495650065232 1.24594454918651 1.2208364206071 1.08237486050124 0.7900322562663 0.59407786425184 0.4846932959713 0.32339195677926 0.25809437448872 0.25133338962774 0.25125907698135 0.26707355491483 0.40553537641506 0.75082653089893 1.0476864288339 1.44812288961801 2.16475912990633 2.35390545171735 2.2720022419473 1.95717450907255 1.68984833853071 1.54541520253119 1.33456066739429 1.26031126602762 1.25111656038969 1.25009821631154 1.25000752438805 1.25000071877273 1.2500002768083 1.25000025125097 1.25000024976367 1.25000025001334 1.25000025002403 1.25000024999837 1.25000024999909 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.2500002499881 1.2500002499612 1.25000025016886 1.2500002496768 1.25000023973798 1.25000006865023 1.24999742456254 1.24996210092219 1.2495650065232 1.24594454918651 1.2208364206071 1.0823748605013 0.79003225626691 0.59407786424147 0.48469329599093 0.32339195677095 0.25809437447384 0.25133338958562 0.25125907690319 0.26707355526755 0.40553537889429 0.75082649005777 1.04768623863001 1.44812287690543 2.16475912689733 2.35390545185173 2.27200224217089 1.95717450873953 1.68984833866033 1.54541520275373 1.33456066743808 1.26031126600648 1.25111656038922 1.25009821631197 1.25000752438801 1.25000071877272 1.2500002768083 1.25000025125097 1.25000024976367 1.25000025001334 1.25000025002403 1.25000024999837 1.25000024999909 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.2500002499881 1.2500002499612 1.25000025016886 1.2500002496768 1.25000023973798 1.25000006865023 1.24999742456254 1.24996210092219 1.2495650065232 1.24594454918651 1.22083642060711 1.08237486050133 0.79003225626606 0.59407786424223 0.48469329599557 0.32339195676625 0.25809437446945 0.2513333896037 0.25125907691929 0.26707355520618 0.40553537890313 0.75082648755217 1.04768622765671 1.44812287619269 2.16475912713329 2.35390545194232 2.2720022419895 1.95717450871019 1.68984833864378 1.54541520272659 1.33456066741182 1.26031126600577 1.25111656038986 1.2500982163119 1.250007524388 1.25000071877272 1.2500002768083 1.25000025125097 1.25000024976367 1.25000025001334 1.25000025002403 1.25000024999837 1.25000024999909 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.25000024998809 1.2500002499612 1.25000025016886 1.2500002496768 1.25000023973798 1.25000006865023 1.24999742456254 1.24996210092219 1.2495650065232 1.24594454918651 1.2208364206071 1.08237486050133 0.79003225626613 0.59407786424267 0.48469329599439 0.32339195676672 0.2580943744704 0.25133338960565 0.25125907692657 0.26707355522627 0.40553537887785 0.75082648761955 1.0476862270805 1.44812287641258 2.16475912718434 2.35390545190732 2.27200224202376 1.95717450874326 1.68984833863392 1.54541520271084 1.33456066741002 1.26031126600651 1.25111656038978 1.25009821631188 1.250007524388 1.25000071877272 1.2500002768083 1.25000025125097 1.25000024976367 1.25000025001334 1.25000025002403 1.25000024999837 1.25000024999909 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.2500002499881 1.2500002499612 1.25000025016886 1.2500002496768 1.25000023973798 1.25000006865023 1.24999742456254 1.24996210092219 1.2495650065232 1.24594454918651 1.2208364206071 1.08237486050132 0.79003225626616 0.59407786424259 0.48469329599429 0.32339195676689 0.25809437447049 0.25133338960469 0.25125907692546 0.26707355523109 0.40553537889546 0.75082648767997 1.04768622729874 1.44812287639617 2.16475912715352 2.35390545190334 2.27200224203458 1.95717450874368 1.68984833863499 1.54541520271298 1.33456066741119 1.26031126600643 1.25111656038975 1.25009821631188 1.250007524388 1.25000071877272 1.2500002768083 1.25000025125097 1.25000024976367 1.25000025001334 1.25000025002403 1.25000024999837 1.25000024999909 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.2500002499881 1.2500002499612 1.25000025016886 1.2500002496768 1.25000023973798 1.25000006865023 1.24999742456254 1.24996210092219 1.2495650065232 1.24594454918651 1.2208364206071 1.08237486050132 0.79003225626616 0.59407786424257 0.48469329599437 0.32339195676686 0.25809437447043 0.25133338960471 0.25125907692524 0.26707355522978 0.40553537889477 0.75082648765648 1.04768622727443 1.44812287638057 2.16475912715177 2.353905451905 2.27200224203224 1.95717450874204 1.68984833863534 1.54541520271353 1.33456066741114 1.26031126600641 1.25111656038976 1.25009821631188 1.250007524388 1.25000071877272 1.2500002768083 1.25000025125097 1.25000024976367 1.25000025001334 1.25000025002403 1.25000024999837 1.25000024999909 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.2500002499881 1.2500002499612 1.25000025016886 1.2500002496768 1.25000023973798 1.25000006865023 1.24999742456254 1.24996210092219 1.2495650065232 1.24594454918651 1.2208364206071 1.08237486050132 0.79003225626616 0.59407786424258 0.48469329599437 0.32339195676685 0.25809437447043 0.25133338960476 0.25125907692533 0.26707355522969 0.40553537889378 0.7508264876528 1.04768622725943 1.44812287638206 2.16475912715311 2.35390545190499 2.27200224203202 1.95717450874221 1.68984833863525 1.54541520271335 1.33456066741108 1.26031126600641 1.25111656038976 1.25009821631188 1.250007524388 1.25000071877272 1.2500002768083 1.25000025125097 1.25000024976367 1.25000025001334 1.25000025002403 1.25000024999837 1.25000024999909 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.2500002499881 1.2500002499612 1.25000025016886 1.2500002496768 1.25000023973798 1.25000006865023 1.24999742456254 1.24996210092219 1.2495650065232 1.24594454918651 1.2208364206071 1.08237486050132 0.79003225626616 0.59407786424258 0.48469329599436 0.32339195676685 0.25809437447043 0.25133338960476 0.25125907692533 0.26707355522978 0.40553537889396 0.75082648765401 1.04768622726155 1.4481228763826 2.16475912715306 2.35390545190492 2.27200224203217 1.95717450874228 1.68984833863524 1.54541520271334 1.33456066741109 1.26031126600641 1.25111656038976 1.25009821631188 1.250007524388 1.25000071877272 1.2500002768083 1.25000025125097 1.25000024976367 1.25000025001334 1.25000025002403 1.25000024999837 1.25000024999909 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.2500002499881 1.2500002499612 1.25000025016886 1.2500002496768 1.25000023973798 1.25000006865023 1.24999742456254 1.24996210092219 1.2495650065232 1.24594454918651 1.2208364206071 1.08237486050132 0.79003225626616 0.59407786424258 0.48469329599436 0.32339195676685 0.25809437447043 0.25133338960476 0.25125907692533 0.26707355522978 0.405535378894 0.7508264876541 1.04768622726201 1.44812287638246 2.16475912715299 2.35390545190492 2.27200224203217 1.95717450874227 1.68984833863524 1.54541520271335 1.33456066741109 1.26031126600641 1.25111656038976 1.25009821631188 1.250007524388 1.25000071877272 1.2500002768083 1.25000025125097 1.25000024976367 1.25000025001334 1.25000025002403 1.25000024999837 1.25000024999909 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.2500002499881 1.2500002499612 1.25000025016886 1.2500002496768 1.25000023973798 1.25000006865023 1.24999742456254 1.2499621009222 1.2495650065232 1.24594454918651 1.2208364206071 1.08237486050132 0.79003225626616 0.59407786424258 0.48469329599436 0.32339195676685 0.25809437447043 0.25133338960476 0.25125907692533 0.26707355522977 0.40553537889399 0.75082648765403 1.04768622726184 1.44812287638244 2.164759127153 2.35390545190492 2.27200224203216 1.95717450874226 1.68984833863524 1.54541520271335 1.33456066741109 1.26031126600641 1.25111656038976 1.25009821631188 1.250007524388 1.25000071877272 1.2500002768083 1.25000025125097 1.25000024976367 1.25000025001334 1.25000025002403 1.25000024999837 1.25000024999909 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.2500002499881 1.2500002499612 1.25000025016886 1.2500002496768 1.25000023973798 1.25000006865023 1.24999742456254 1.2499621009222 1.2495650065232 1.24594454918651 1.2208364206071 1.08237486050132 0.79003225626616 0.59407786424258 0.48469329599436 0.32339195676685 0.25809437447043 0.25133338960476 0.25125907692533 0.26707355522977 0.40553537889399 0.75082648765402 1.04768622726184 1.44812287638245 2.164759127153 2.35390545190492 2.27200224203216 1.95717450874226 1.68984833863524 1.54541520271334 1.33456066741109 1.26031126600641 1.25111656038976 1.25009821631188 1.250007524388 1.25000071877272 1.2500002768083 1.25000025125097 1.25000024976367 1.25000025001334 1.25000025002403 1.25000024999837 1.25000024999909 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.2500002499881 1.2500002499612 1.25000025016886 1.2500002496768 1.25000023973798 1.25000006865023 1.24999742456254 1.2499621009222 1.2495650065232 1.24594454918651 1.2208364206071 1.08237486050132 0.79003225626616 0.59407786424258 0.48469329599436 0.32339195676685 0.25809437447043 0.25133338960476 0.25125907692533 0.26707355522977 0.40553537889399 0.75082648765403 1.04768622726184 1.44812287638245 2.164759127153 2.35390545190492 2.27200224203216 1.95717450874227 1.68984833863524 1.54541520271335 1.33456066741109 1.26031126600641 1.25111656038976 1.25009821631188 1.250007524388 1.25000071877272 1.2500002768083 1.25000025125097 1.25000024976367 1.25000025001334 1.25000025002403 1.25000024999837 1.25000024999909 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.2500002499881 1.2500002499612 1.25000025016886 1.2500002496768 1.25000023973798 1.25000006865023 1.24999742456254 1.24996210092219 1.2495650065232 1.24594454918651 1.2208364206071 1.08237486050132 0.79003225626616 0.59407786424258 0.48469329599436 0.32339195676685 0.25809437447043 0.25133338960476 0.25125907692533 0.26707355522977 0.40553537889399 0.75082648765403 1.04768622726184 1.44812287638245 2.164759127153 2.35390545190492 2.27200224203216 1.95717450874227 1.68984833863524 1.54541520271335 1.33456066741109 1.26031126600641 1.25111656038976 1.25009821631188 1.250007524388 1.25000071877272 1.2500002768083 1.25000025125097 1.25000024976367 1.25000025001334 1.25000025002403 1.25000024999837 1.25000024999909 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.2500002499881 1.2500002499612 1.25000025016886 1.2500002496768 1.25000023973798 1.25000006865023 1.24999742456254 1.24996210092219 1.2495650065232 1.24594454918651 1.2208364206071 1.08237486050132 0.79003225626616 0.59407786424258 0.48469329599436 0.32339195676685 0.25809437447043 0.25133338960476 0.25125907692533 0.26707355522977 0.40553537889399 0.75082648765403 1.04768622726184 1.44812287638245 2.164759127153 2.35390545190492 2.27200224203216 1.95717450874226 1.68984833863524 1.54541520271335 1.33456066741109 1.26031126600641 1.25111656038976 1.25009821631188 1.250007524388 1.25000071877272 1.2500002768083 1.25000025125097 1.25000024976367 1.25000025001334 1.25000025002403 1.25000024999837 1.25000024999909 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.2500002499881 1.2500002499612 1.25000025016886 1.2500002496768 1.25000023973798 1.25000006865023 1.24999742456254 1.24996210092219 1.2495650065232 1.24594454918651 1.2208364206071 1.08237486050132 0.79003225626616 0.59407786424258 0.48469329599436 0.32339195676685 0.25809437447043 0.25133338960476 0.25125907692533 0.26707355522977 0.40553537889399 0.75082648765403 1.04768622726184 1.44812287638245 2.164759127153 2.35390545190492 2.27200224203216 1.95717450874227 1.68984833863524 1.54541520271335 1.33456066741109 1.26031126600641 1.25111656038976 1.25009821631188 1.250007524388 1.25000071877272 1.2500002768083 1.25000025125097 1.25000024976367 1.25000025001334 1.25000025002403 1.25000024999837 1.25000024999909 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.2500002499881 1.2500002499612 1.25000025016886 1.2500002496768 1.25000023973798 1.25000006865023 1.24999742456254 1.24996210092219 1.2495650065232 1.24594454918651 1.2208364206071 1.08237486050132 0.79003225626616 0.59407786424258 0.48469329599436 0.32339195676685 0.25809437447043 0.25133338960476 0.25125907692533 0.26707355522977 0.40553537889399 0.75082648765403 1.04768622726184 1.44812287638245 2.164759127153 2.35390545190492 2.27200224203216 1.95717450874227 1.68984833863524 1.54541520271335 1.33456066741109 1.26031126600641 1.25111656038976 1.25009821631188 1.250007524388 1.25000071877272 1.2500002768083 1.25000025125097 1.25000024976367 1.25000025001334 1.25000025002403 1.25000024999837 1.25000024999909 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.2500002499881 1.2500002499612 1.25000025016886 1.2500002496768 1.25000023973798 1.25000006865023 1.24999742456254 1.24996210092219 1.2495650065232 1.24594454918651 1.2208364206071 1.08237486050132 0.79003225626616 0.59407786424258 0.48469329599436 0.32339195676685 0.25809437447043 0.25133338960476 0.25125907692533 0.26707355522977 0.40553537889399 0.75082648765403 1.04768622726184 1.44812287638244 2.164759127153 2.35390545190492 2.27200224203216 1.95717450874227 1.68984833863524 1.54541520271335 1.33456066741109 1.26031126600641 1.25111656038976 1.25009821631188 1.250007524388 1.25000071877272 1.2500002768083 1.25000025125097 1.25000024976367 1.25000025001334 1.25000025002403 1.25000024999837 1.25000024999909 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.2500002499881 1.2500002499612 1.25000025016886 1.2500002496768 1.25000023973798 1.25000006865023 1.24999742456254 1.24996210092219 1.2495650065232 1.24594454918651 1.2208364206071 1.08237486050132 0.79003225626616 0.59407786424258 0.48469329599436 0.32339195676685 0.25809437447043 0.25133338960476 0.25125907692533 0.26707355522977 0.40553537889399 0.75082648765403 1.04768622726183 1.44812287638246 2.16475912715299 2.35390545190492 2.27200224203217 1.95717450874227 1.68984833863524 1.54541520271335 1.33456066741109 1.26031126600641 1.25111656038976 1.25009821631188 1.250007524388 1.25000071877272 1.2500002768083 1.25000025125097 1.25000024976367 1.25000025001334 1.25000025002403 1.25000024999837 1.25000024999909 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.2500002499881 1.2500002499612 1.25000025016886 1.2500002496768 1.25000023973798 1.25000006865023 1.24999742456254 1.24996210092219 1.2495650065232 1.24594454918651 1.2208364206071 1.08237486050132 0.79003225626616 0.59407786424258 0.48469329599436 0.32339195676685 0.25809437447043 0.25133338960476 0.25125907692533 0.26707355522977 0.40553537889399 0.75082648765402 1.04768622726185 1.44812287638261 2.16475912715308 2.35390545190491 2.27200224203217 1.95717450874227 1.68984833863523 1.54541520271334 1.33456066741109 1.26031126600641 1.25111656038976 1.25009821631188 1.250007524388 1.25000071877272 1.2500002768083 1.25000025125097 1.25000024976367 1.25000025001334 1.25000025002403 1.25000024999837 1.25000024999909 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.2500002499881 1.2500002499612 1.25000025016886 1.2500002496768 1.25000023973798 1.25000006865023 1.24999742456254 1.24996210092219 1.2495650065232 1.24594454918651 1.2208364206071 1.08237486050132 0.79003225626616 0.59407786424258 0.48469329599436 0.32339195676685 0.25809437447043 0.25133338960476 0.25125907692533 0.26707355522977 0.405535378894 0.75082648765412 1.04768622726203 1.448122876382 2.16475912715317 2.35390545190505 2.27200224203204 1.95717450874225 1.68984833863528 1.54541520271334 1.33456066741108 1.26031126600641 1.25111656038976 1.25009821631188 1.250007524388 1.25000071877272 1.2500002768083 1.25000025125097 1.25000024976367 1.25000025001334 1.25000025002403 1.25000024999837 1.25000024999909 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.2500002499881 1.2500002499612 1.25000025016886 1.2500002496768 1.25000023973798 1.25000006865023 1.24999742456254 1.24996210092219 1.2495650065232 1.24594454918651 1.2208364206071 1.08237486050132 0.79003225626616 0.59407786424258 0.48469329599437 0.32339195676685 0.25809437447043 0.25133338960476 0.25125907692533 0.26707355522977 0.40553537889402 0.75082648765406 1.04768622726141 1.44812287638052 2.1647591271513 2.35390545190501 2.27200224203222 1.95717450874224 1.68984833863539 1.54541520271353 1.33456066741112 1.26031126600641 1.25111656038976 1.25009821631188 1.250007524388 1.25000071877272 1.2500002768083 1.25000025125097 1.25000024976367 1.25000025001334 1.25000025002403 1.25000024999837 1.25000024999909 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.25000024998809 1.2500002499612 1.25000025016886 1.2500002496768 1.25000023973798 1.25000006865023 1.24999742456254 1.24996210092219 1.2495650065232 1.24594454918651 1.2208364206071 1.08237486050132 0.79003225626616 0.59407786424258 0.48469329599436 0.32339195676685 0.25809437447043 0.25133338960476 0.25125907692533 0.26707355522979 0.40553537889369 0.75082648765238 1.04768622725949 1.44812287639797 2.16475912715444 2.35390545190245 2.2720022420343 1.95717450874258 1.68984833863437 1.54541520271308 1.33456066741122 1.26031126600642 1.25111656038975 1.25009821631188 1.250007524388 1.25000071877272 1.2500002768083 1.25000025125097 1.25000024976367 1.25000025001334 1.25000025002403 1.25000024999837 1.25000024999909 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.2500002499881 1.2500002499612 1.25000025016886 1.2500002496768 1.25000023973798 1.25000006865023 1.24999742456254 1.24996210092219 1.2495650065232 1.24594454918651 1.2208364206071 1.08237486050132 0.79003225626616 0.59407786424258 0.48469329599436 0.32339195676684 0.25809437447042 0.25133338960474 0.25125907692536 0.26707355522977 0.40553537889411 0.75082648765748 1.04768622727688 1.4481228764116 2.16475912719123 2.35390545191031 2.27200224202556 1.95717450874249 1.68984833863453 1.54541520271058 1.33456066741028 1.26031126600652 1.25111656038977 1.25009821631188 1.250007524388 1.25000071877272 1.2500002768083 1.25000025125097 1.25000024976367 1.25000025001334 1.25000025002403 1.25000024999837 1.25000024999909 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.2500002499881 1.2500002499612 1.25000025016886 1.2500002496768 1.25000023973798 1.25000006865023 1.24999742456254 1.24996210092219 1.2495650065232 1.24594454918651 1.2208364206071 1.08237486050132 0.79003225626616 0.59407786424257 0.48469329599438 0.32339195676688 0.25809437447044 0.25133338960471 0.25125907692533 0.2670735552296 0.40553537889946 0.75082648768628 1.04768622729568 1.44812287617673 2.16475912710967 2.35390545195251 2.27200224199245 1.95717450873474 1.68984833865595 1.54541520272466 1.33456066741029 1.26031126600593 1.25111656038987 1.25009821631189 1.250007524388 1.25000071877272 1.2500002768083 1.25000025125097 1.25000024976367 1.25000025001334 1.25000025002403 1.25000024999837 1.25000024999909 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.2500002499881 1.2500002499612 1.25000025016886 1.2500002496768 1.25000023973798 1.25000006865023 1.24999742456254 1.24996210092219 1.2495650065232 1.24594454918651 1.2208364206071 1.08237486050132 0.79003225626615 0.59407786424259 0.48469329599435 0.3233919567669 0.2580943744705 0.25133338960515 0.25125907692502 0.26707355523071 0.40553537888585 0.75082648759488 1.04768622706272 1.44812287702389 2.16475912694057 2.35390545180383 2.27200224214507 1.95717450873448 1.68984833864545 1.54541520275879 1.33456066743265 1.26031126600561 1.25111656038933 1.25009821631198 1.25000752438801 1.25000071877272 1.2500002768083 1.25000025125097 1.25000024976367 1.25000025001334 1.25000025002403 1.25000024999837 1.25000024999909 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.2500002499881 1.2500002499612 1.25000025016886 1.2500002496768 1.25000023973798 1.25000006865023 1.24999742456254 1.24996210092219 1.2495650065232 1.24594454918651 1.22083642060711 1.08237486050134 0.79003225626609 0.59407786424259 0.4846932959943 0.32339195676612 0.25809437446988 0.25133338960492 0.25125907692606 0.26707355522814 0.40553537885387 0.75082648762001 1.04768622777266 1.44812289157312 2.16475913097847 2.35390545185066 2.27200224206461 1.95717450887206 1.6898483384238 1.54541520255373 1.33456066742371 1.26031126602378 1.25111656038899 1.25009821631158 1.25000752438805 1.25000071877273 1.2500002768083 1.25000025125097 1.25000024976367 1.25000025001334 1.25000025002403 1.25000024999837 1.25000024999909 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.2500002499881 1.2500002499612 1.25000025016886 1.2500002496768 1.25000023973798 1.25000006865023 1.24999742456254 1.24996210092219 1.2495650065232 1.24594454918651 1.22083642060711 1.08237486050136 0.79003225626635 0.59407786424189 0.48469329599495 0.32339195676879 0.25809437447064 0.25133338959302 0.25125907692344 0.26707355522629 0.4055353791217 0.75082649136761 1.04768624036755 1.44812315003301 2.16475919552574 2.35390545912751 2.27200223629866 1.95717450835072 1.68984833962458 1.5454152028101 1.33456066718672 1.26031126601915 1.25111656040674 1.2500982163111 1.25000752438779 1.25000071877272 1.2500002768083 1.25000025125097 1.25000024976367 1.25000025001334 1.25000025002403 1.25000024999837 1.25000024999909 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.25000024998809 1.2500002499612 1.25000025016886 1.2500002496768 1.25000023973798 1.25000006865023 1.24999742456254 1.24996210092219 1.2495650065232 1.24594454918651 1.22083642060707 1.08237486050099 0.79003225626711 0.59407786424508 0.48469329599025 0.32339195678296 0.25809437448419 0.25133338961031 0.25125907693291 0.26707355514138 0.40553538061308 0.75082655198014 1.04768645474357 1.4481272741785 2.16476021645349 2.35390557302904 2.27200214883417 1.95717449608703 1.68984835184311 1.54541521005259 1.33456066866458 1.2603112658376 1.25111656040225 1.25009821632566 1.2500075243876 1.25000071877259 1.25000027680829 1.25000025125097 1.25000024976367 1.25000025001334 1.25000025002403 1.25000024999837 1.25000024999909 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.2500002499881 1.2500002499612 1.25000025016886 1.2500002496768 1.25000023973798 1.25000006865023 1.24999742456254 1.24996210092219 1.2495650065232 1.24594454918651 1.22083642060714 1.08237486050156 0.79003225626147 0.59407786425988 0.48469329598863 0.32339195672686 0.25809437444561 0.25133338968635 0.25125907696433 0.26707355155399 0.40553537375491 0.75082735980946 1.04768968911956 1.44818396412148 2.16477417214173 2.35390728567186 2.27200082665249 1.95717423548877 1.68984848500252 1.54541531925848 1.33456069426557 1.26031126747697 1.25111656025268 1.25009821633175 1.25000752439743 1.25000071877312 1.2500002768083 1.25000025125097 1.25000024976367 1.25000025001334 1.25000025002403 1.25000024999837 1.25000024999909 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.2500002499881 1.2500002499612 1.25000025016886 1.2500002496768 1.25000023973798 1.25000006865023 1.24999742456254 1.24996210092219 1.24956500652321 1.24594454918657 1.2208364206077 1.0823748605093 0.79003225626023 0.5940778641778 0.48469329607741 0.32339195685209 0.25809437447028 0.25133338838428 0.25125907510286 0.26707346649696 0.40553484798658 0.75083643249989 1.04773127045257 1.44883706350351 2.16493404347746 2.35392932492575 2.2719834343726 1.95716973454534 1.68984944035773 1.54541680148914 1.33456110157924 1.26031129478856 1.25111656209305 1.25009821621729 1.25000752440834 1.2500007187773 1.25000027680866 1.25000025125098 1.25000024976367 1.25000025001334 1.25000025002403 1.25000024999837 1.25000024999909 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.2500002499881 1.2500002499612 1.25000025016886 1.2500002496768 1.25000023973798 1.25000006865023 1.24999742456254 1.24996210092219 1.2495650065232 1.24594454918638 1.22083642060539 1.08237486049871 0.79003225638155 0.59407786419023 0.48469329558839 0.32339196082348 0.25809437821232 0.25133335472523 0.25125902296137 0.26707193955178 0.40552302077901 0.75092274888321 1.04817271664303 1.45488602890352 2.1664020173718 2.35416512275071 2.27178829595515 1.95710773122331 1.68984840019177 1.54543321582387 1.33456653538048 1.26031168819205 1.25111659021135 1.25009821785505 1.25000752434872 1.25000071877567 1.25000027680904 1.25000025125104 1.25000024976366 1.25000025001334 1.25000025002403 1.25000024999837 1.25000024999909 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.2500002499881 1.2500002499612 1.25000025016886 1.2500002496768 1.25000023973798 1.25000006865023 1.24999742456254 1.24996210092219 1.24956500652308 1.24594454918515 1.22083642060657 1.08237486049475 0.7900322570325 0.59407786450981 0.48469328650725 0.323392036654 0.25809446624272 0.25133273500911 0.25125811064431 0.26704986427034 0.40533060912818 0.75143400271203 1.05201995902139 1.50075414017454 2.17707775818273 2.35625384916335 2.26997560379395 1.95644120117793 1.68973206927633 1.54557833846431 1.33462442914957 1.26031630530062 1.25111694217059 1.25009824096296 1.25000752541737 1.25000071876133 1.25000027680391 1.25000025125077 1.25000024976371 1.25000025001334 1.25000025002402 1.25000024999837 1.25000024999909 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.2500002499881 1.2500002499612 1.25000025016886 1.2500002496768 1.25000023973798 1.25000006865023 1.24999742456254 1.24996210092218 1.24956500652316 1.24594454918972 1.22083642074764 1.08237486298063 0.79003227029304 0.59407784282996 0.48469316997037 0.32339326644619 0.25809603415422 0.2513231350166 0.25124655317388 0.26680069898177 0.40303624078708 0.75302275708572 1.07293554941358 1.62372070912612 2.21296668836419 2.36607386232852 2.25597083636228 1.9510373362148 1.68792577101082 1.5463779242168 1.33511886198575 1.26035992955444 1.25112050680737 1.25009848390721 1.25000754018481 1.25000071957138 1.2500002768316 1.25000025125126 1.25000024976378 1.25000025001334 1.25000025002402 1.25000024999837 1.25000024999909 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.25000024998809 1.2500002499612 1.25000025016886 1.2500002496768 1.25000023973798 1.25000006865023 1.24999742456254 1.24996210092229 1.24956500652531 1.24594454924566 1.22083642264905 1.0823748907272 0.79003240479215 0.59407725702044 0.48469192431196 0.32340186626944 0.25811193233929 0.25125998208175 0.25115767748227 0.26529655952153 0.38949014842951 0.74994475729068 1.09084203370899 2.2653574465929 2.28342467536133 2.42742368954988 2.19356794925205 1.91444604002328 1.67630880343301 1.5467613559473 1.33703003857736 1.26055329476089 1.25113841040714 1.25009983235796 1.25000762577309 1.25000072462068 1.25000027714387 1.2500002512655 1.25000024976335 1.25000025001298 1.25000025002418 1.25000024999838 1.25000024999908 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.2500002499881 1.2500002499612 1.25000025016886 1.2500002496768 1.25000023973798 1.25000006865023 1.24999742456253 1.24996210092184 1.24956500651618 1.24594454928597 1.22083643524686 1.08237510970953 0.79003404388661 0.59406820571036 0.4846901482205 0.32346283770569 0.25825838746008 0.25076259823637 0.25079904187644 0.2562183799047 0.28399344258391 0.52649112887573 0.88236644734338 2.21293402874531 2.35841621653486 2.22026193505462 1.94923010909349 1.73494560333722 1.5897486773084 1.53402739553053 1.34213681534349 1.26117469748791 1.2511963291234 1.25010453887693 1.25000794630805 1.2500007433816 1.25000027819817 1.25000025132382 1.25000024976441 1.25000025001051 1.25000025002467 1.2500002499985 1.25000024999905 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.2500002499881 1.2500002499612 1.25000025016886 1.2500002496768 1.25000023973798 1.25000006865022 1.24999742456233 1.24996210091789 1.24956500644927 1.24594454826525 1.22083641941801 1.08237493939252 0.79003309498392 0.59407106341725 0.48466973988691 0.32337919880963 0.25831150109953 0.25090569903229 0.25009240902869 0.25256055930519 0.26203410506729 0.39242229576972 0.79376495139749 2.17580149240474 2.19702490160301 1.89157782268887 1.70743985455685 1.64153750845796 1.52819460273831 1.48096555448691 1.32358174374939 1.25902953424305 1.25098548713539 1.25008753828785 1.25000678193825 1.25000067354205 1.25000027444197 1.25000025115337 1.25000024976749 1.25000025001538 1.25000025002291 1.25000024999834 1.25000024999914 1.2500002500002 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.2500002499881 1.2500002499612 1.25000025016886 1.2500002496768 1.25000023973798 1.25000006865019 1.24999742456155 1.24996210090373 1.24956500622806 1.24594454529001 1.22083638294872 1.0823745925837 0.79003338861426 0.59406982543149 0.4846628244672 0.32329951465587 0.25837483459403 0.25083960192788 0.25027508408004 0.25016936476487 0.25076389179531 0.2623803623661 0.66531359840214 2.32943500056272 1.65631048324959 1.54937287349388 1.49612866138386 1.4450198024074 1.37075946457507 1.33846425553489 1.27329725375543 1.25290909294601 1.25031745520669 1.25002851011455 1.25000238445251 1.25000038990606 1.25000025790929 1.25000025017178 1.25000024986219 1.25000025003954 1.25000025000899 1.25000024999762 1.25000024999986 1.25000025000015 1.25000024999999 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.2500002499881 1.2500002499612 1.25000025016886 1.2500002496768 1.25000023973798 1.25000006865021 1.24999742456213 1.24996210091429 1.24956500638985 1.24594454734719 1.22083640432066 1.08237476389037 0.79003287284521 0.59407174099397 0.48466655355203 0.32331692137533 0.25833925619905 0.25086729915979 0.25071065980017 0.25135136321776 0.2551739314816 0.25130536745748 0.70250662666548 2.5000005 1.26054481201456 1.27544189662969 1.30891850816541 1.33377214865048 1.33504526889884 1.28246898173154 1.25747594508209 1.25088918446204 1.25009166557878 1.25000816106547 1.2500008391122 1.25000028833896 1.25000025199155 1.25000024973894 1.25000024998726 1.25000025003499 1.25000024999965 1.25000024999832 1.25000025000023 1.25000025000008 1.25000024999998 1.25000025000001 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.2500002499881 1.2500002499612 1.25000025016886 1.2500002496768 1.25000023973798 1.25000006865024 1.24999742456269 1.24996210092474 1.24956500656041 1.24594454985657 1.22083644300847 1.08237520299756 0.79003351072974 0.59406852240693 0.48467972267075 0.32343551221606 0.25831049760352 0.25075792552063 0.2507187074539 0.2565921302427 0.3138016114241 0.38796626532293 0.25000005125 D/cons.6.00.000000.dat 0.9 0.9 0.9 0.9 0.9 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.9 0.9 0.9 0.9 0.9 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.9 0.9 0.9 0.9 0.9 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.9 0.9 0.9 0.9 0.9 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.9 0.9 0.9 0.9 0.9 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.9 0.9 0.9 0.9 0.9 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.9 0.9 0.9 0.9 0.9 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.9 0.9 0.9 0.9 0.9 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.9 0.9 0.9 0.9 0.9 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.9 0.9 0.9 0.9 0.9 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.9 0.9 0.9 0.9 0.9 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.9 0.9 0.9 0.9 0.9 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.9 0.9 0.9 0.9 0.9 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.9 0.9 0.9 0.9 0.9 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.9 0.9 0.9 0.9 0.9 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.9 0.9 0.9 0.9 0.9 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.9 0.9 0.9 0.9 0.9 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.9 0.9 0.9 0.9 0.9 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.9 0.9 0.9 0.9 0.9 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.9 0.9 0.9 0.9 0.9 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.9 0.9 0.9 0.9 0.9 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.9 0.9 0.9 0.9 0.9 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.9 0.9 0.9 0.9 0.9 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.9 0.9 0.9 0.9 0.9 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.9 0.9 0.9 0.9 0.9 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.9 0.9 0.9 0.9 0.9 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.9 0.9 0.9 0.9 0.9 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.9 0.9 0.9 0.9 0.9 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.9 0.9 0.9 0.9 0.9 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.9 0.9 0.9 0.9 0.9 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.9 0.9 0.9 0.9 0.9 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.9 0.9 0.9 0.9 0.9 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.9 0.9 0.9 0.9 0.9 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.9 0.9 0.9 0.9 0.9 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.9 0.9 0.9 0.9 0.9 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.9 0.9 0.9 0.9 0.9 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.9 0.9 0.9 0.9 0.9 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.9 0.9 0.9 0.9 0.9 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.9 0.9 0.9 0.9 0.9 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.9 0.9 0.9 0.9 0.9 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.9 0.9 0.9 0.9 0.9 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.9 0.9 0.9 0.9 0.9 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.9 0.9 0.9 0.9 0.9 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.9 0.9 0.9 0.9 0.9 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.9 0.9 0.9 0.9 0.9 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.9 0.9 0.9 0.9 0.9 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.9 0.9 0.9 0.9 0.9 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.9 0.9 0.9 0.9 0.9 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.9 0.9 0.9 0.9 0.9 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.9 0.9 0.9 0.9 0.9 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 -D/cons.6.00.000050.dat 0.9 0.50001362971218 0.5000779740013 0.50949544275855 0.57417616490252 0.50312545678926 0.50001688303425 0.50000001549618 0.50000000000155 0.49999999999997 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.36162199804016 0.21923197559877 0.20052745629872 0.20000181212691 0.20000000047725 0.20000000040687 0.20000121932324 0.20046104044312 0.2091718911285 0.2 0.9 0.61048369919077 0.54364735463474 0.59193601188221 0.60098328041381 0.51043831241424 0.50012621180334 0.50000026989788 0.50000000005259 0.49999999999999 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.36162166584493 0.21923156643412 0.20052760941964 0.20000184151564 0.20000000053935 0.2000000003777 0.20000012886018 0.20000101111023 0.20000002831085 0.37568266632189 0.9 0.9 0.8951104187835 0.87268331664979 0.89255956815864 0.60431489916225 0.50353733817738 0.50003201071129 0.50000002799848 0.5000000000021 0.49999999999999 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.36162183490109 0.21923166556958 0.200527606063 0.20000183637526 0.20000000055326 0.20000000000002 0.20000000004162 0.20000000030487 0.2000187036237 0.30808201461077 0.9 0.9 0.9 0.89999999999907 0.89999999999766 0.60653002981158 0.50401795182027 0.50004232138094 0.50000004404899 0.5000000000039 0.49999999999999 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.3616219393896 0.21923196779354 0.20052758390195 0.20000182547979 0.20000000050379 0.20000000000105 0.20000040595672 0.20015900561741 0.20899196898586 0.51790392543118 0.9 0.9 0.9 0.9 0.90000000000002 0.61360021178726 0.50396962451315 0.50003743909214 0.5000000351718 0.50000000000293 0.49999999999999 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.36162191726594 0.21923187449319 0.20052738085141 0.20000180193693 0.20000000047682 0.20000000021939 0.20000112840425 0.20053310207476 0.25514550658405 0.640253498031 0.9 0.9 0.9 0.9 0.9 0.61364278775764 0.50395643393775 0.50003654386538 0.50000003363088 0.50000000000275 0.49999999999999 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.36162112202836 0.21923050895531 0.20052729144188 0.20000181740397 0.2000000005202 0.20000001177552 0.20002552582891 0.20403900638041 0.29039221731466 0.65102896057908 0.9 0.9 0.9 0.9 0.9 0.61373612575537 0.50395148365416 0.50003631984091 0.50000003328316 0.50000000000272 0.49999999999999 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.3616210931288 0.21923042996988 0.20052728909417 0.20000181786152 0.20000000051662 0.20000001326634 0.20002667338385 0.20400172101256 0.29022769738539 0.65344463968353 0.9 0.9 0.9 0.9 0.9 0.61374291239597 0.50395116326873 0.5000363009243 0.50000003325432 0.50000000000271 0.49999999999999 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.36162109138533 0.2192304222183 0.20052728917004 0.20000181793854 0.2000000005162 0.20000001349617 0.20002688952046 0.2039868611058 0.28988833464265 0.6531899327725 0.9 0.9 0.9 0.9 0.9 0.61374348776966 0.50395113997145 0.50003629942944 0.50000003325214 0.50000000000271 0.49999999999999 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.36162109128097 0.2192304216341 0.20052728912867 0.20000181794198 0.20000000051616 0.20000001351681 0.20002691265641 0.20398557456613 0.28985642694078 0.65316998241504 0.9 0.9 0.9 0.9 0.9 0.61374353075556 0.50395113834277 0.50003629932238 0.50000003325199 0.50000000000271 0.49999999999999 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.3616210912718 0.21923042159606 0.20052728912344 0.20000181794207 0.20000000051616 0.20000001351832 0.20002691454817 0.20398547309269 0.28985395383843 0.65316877034987 0.9 0.9 0.9 0.9 0.9 0.61374353360643 0.50395113823717 0.50003629931557 0.50000003325198 0.50000000000271 0.49999999999999 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.36162109126965 0.21923042159357 0.20052728912268 0.20000181794206 0.20000000051616 0.20000001351841 0.20002691467336 0.20398546578469 0.2898537910885 0.6531687153679 0.9 0.9 0.9 0.9 0.9 0.61374353378684 0.50395113822994 0.50003629931515 0.50000003325198 0.50000000000271 0.49999999999999 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.36162109126998 0.21923042159376 0.20052728912269 0.20000181794206 0.20000000051616 0.20000001351842 0.20002691468071 0.20398546532904 0.28985378179402 0.65316871364994 0.9 0.9 0.9 0.9 0.9 0.61374353378196 0.5039511382294 0.50003629931514 0.50000003325198 0.50000000000271 0.49999999999999 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.36162109127012 0.21923042159379 0.20052728912273 0.20000181794206 0.20000000051616 0.20000001351842 0.20002691468107 0.20398546530349 0.28985378132508 0.65316871362903 0.9 0.9 0.9 0.9 0.9 0.61374353377743 0.50395113822963 0.50003629931515 0.50000003325198 0.50000000000271 0.49999999999999 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.36162109127011 0.21923042159377 0.20052728912273 0.20000181794206 0.20000000051616 0.20000001351842 0.2000269146811 0.20398546530303 0.28985378130712 0.65316871363046 0.9 0.9 0.9 0.9 0.9 0.61374353377879 0.50395113822963 0.50003629931515 0.50000003325198 0.50000000000271 0.49999999999999 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.36162109127011 0.21923042159377 0.20052728912272 0.20000181794206 0.20000000051616 0.20000001351842 0.2000269146811 0.20398546530343 0.28985378130924 0.653168713632 0.9 0.9 0.9 0.9 0.9 0.61374353377907 0.50395113822962 0.50003629931515 0.50000003325198 0.50000000000271 0.49999999999999 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.36162109127011 0.21923042159377 0.20052728912273 0.20000181794206 0.20000000051616 0.20000001351842 0.2000269146811 0.20398546530334 0.28985378130903 0.65316871363175 0.9 0.9 0.9 0.9 0.9 0.61374353377901 0.50395113822962 0.50003629931515 0.50000003325198 0.50000000000271 0.49999999999999 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.36162109127011 0.21923042159377 0.20052728912273 0.20000181794206 0.20000000051616 0.20000001351842 0.2000269146811 0.20398546530331 0.28985378130882 0.65316871363173 0.9 0.9 0.9 0.9 0.9 0.613743533779 0.50395113822962 0.50003629931515 0.50000003325198 0.50000000000271 0.49999999999999 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.36162109127011 0.21923042159377 0.20052728912273 0.20000181794206 0.20000000051616 0.20000001351842 0.2000269146811 0.20398546530331 0.28985378130883 0.65316871363174 0.9 0.9 0.9 0.9 0.9 0.613743533779 0.50395113822962 0.50003629931515 0.50000003325198 0.50000000000271 0.49999999999999 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.36162109127011 0.21923042159377 0.20052728912273 0.20000181794206 0.20000000051616 0.20000001351842 0.2000269146811 0.20398546530331 0.28985378130883 0.65316871363174 0.9 0.9 0.9 0.9 0.9 0.613743533779 0.50395113822962 0.50003629931515 0.50000003325198 0.50000000000271 0.49999999999999 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.36162109127011 0.21923042159377 0.20052728912273 0.20000181794206 0.20000000051616 0.20000001351842 0.2000269146811 0.20398546530331 0.28985378130883 0.65316871363174 0.9 0.9 0.9 0.9 0.9 0.613743533779 0.50395113822962 0.50003629931515 0.50000003325198 0.50000000000271 0.49999999999999 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.36162109127011 0.21923042159377 0.20052728912273 0.20000181794206 0.20000000051616 0.20000001351842 0.2000269146811 0.20398546530331 0.28985378130883 0.65316871363174 0.9 0.9 0.9 0.9 0.9 0.613743533779 0.50395113822962 0.50003629931515 0.50000003325198 0.50000000000271 0.49999999999999 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.36162109127011 0.21923042159377 0.20052728912273 0.20000181794206 0.20000000051616 0.20000001351842 0.2000269146811 0.20398546530331 0.28985378130883 0.65316871363174 0.9 0.9 0.9 0.9 0.9 0.613743533779 0.50395113822962 0.50003629931515 0.50000003325198 0.50000000000271 0.49999999999999 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.36162109127011 0.21923042159377 0.20052728912273 0.20000181794206 0.20000000051616 0.20000001351842 0.2000269146811 0.20398546530331 0.28985378130883 0.65316871363174 0.9 0.9 0.9 0.9 0.9 0.613743533779 0.50395113822962 0.50003629931515 0.50000003325198 0.50000000000271 0.49999999999999 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.36162109127011 0.21923042159377 0.20052728912273 0.20000181794206 0.20000000051616 0.20000001351842 0.2000269146811 0.20398546530331 0.28985378130883 0.65316871363174 0.9 0.9 0.9 0.9 0.9 0.613743533779 0.50395113822962 0.50003629931515 0.50000003325198 0.50000000000271 0.49999999999999 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.36162109127011 0.21923042159377 0.20052728912273 0.20000181794206 0.20000000051616 0.20000001351842 0.2000269146811 0.20398546530331 0.28985378130883 0.65316871363174 0.9 0.9 0.9 0.9 0.9 0.613743533779 0.50395113822962 0.50003629931515 0.50000003325198 0.50000000000271 0.49999999999999 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.36162109127011 0.21923042159377 0.20052728912273 0.20000181794206 0.20000000051616 0.20000001351842 0.2000269146811 0.20398546530331 0.28985378130883 0.65316871363174 0.9 0.9 0.9 0.9 0.9 0.613743533779 0.50395113822962 0.50003629931515 0.50000003325198 0.50000000000271 0.49999999999999 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.36162109127011 0.21923042159377 0.20052728912273 0.20000181794206 0.20000000051616 0.20000001351842 0.2000269146811 0.20398546530331 0.28985378130883 0.65316871363174 0.9 0.9 0.9 0.9 0.9 0.613743533779 0.50395113822962 0.50003629931515 0.50000003325198 0.50000000000271 0.49999999999999 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.36162109127011 0.21923042159377 0.20052728912273 0.20000181794206 0.20000000051616 0.20000001351842 0.2000269146811 0.20398546530331 0.28985378130883 0.65316871363174 0.9 0.9 0.9 0.9 0.9 0.613743533779 0.50395113822962 0.50003629931515 0.50000003325198 0.50000000000271 0.49999999999999 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.36162109127011 0.21923042159377 0.20052728912273 0.20000181794206 0.20000000051616 0.20000001351842 0.2000269146811 0.20398546530331 0.28985378130883 0.65316871363174 0.9 0.9 0.9 0.9 0.9 0.613743533779 0.50395113822962 0.50003629931515 0.50000003325198 0.50000000000271 0.49999999999999 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.36162109127011 0.21923042159377 0.20052728912273 0.20000181794206 0.20000000051616 0.20000001351842 0.2000269146811 0.20398546530331 0.28985378130883 0.65316871363174 0.9 0.9 0.9 0.9 0.9 0.613743533779 0.50395113822962 0.50003629931515 0.50000003325198 0.50000000000271 0.49999999999999 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.36162109127011 0.21923042159377 0.20052728912273 0.20000181794206 0.20000000051616 0.20000001351842 0.2000269146811 0.20398546530331 0.28985378130883 0.65316871363174 0.9 0.9 0.9 0.9 0.9 0.613743533779 0.50395113822962 0.50003629931515 0.50000003325198 0.50000000000271 0.49999999999999 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.36162109127011 0.21923042159377 0.20052728912273 0.20000181794206 0.20000000051616 0.20000001351842 0.2000269146811 0.20398546530332 0.28985378130883 0.65316871363174 0.9 0.9 0.9 0.9 0.9 0.613743533779 0.50395113822962 0.50003629931515 0.50000003325198 0.50000000000271 0.49999999999999 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.36162109127011 0.21923042159377 0.20052728912273 0.20000181794206 0.20000000051616 0.20000001351842 0.2000269146811 0.20398546530331 0.28985378130882 0.65316871363174 0.9 0.9 0.9 0.9 0.9 0.61374353377901 0.50395113822962 0.50003629931515 0.50000003325198 0.50000000000271 0.49999999999999 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.36162109127011 0.21923042159377 0.20052728912273 0.20000181794206 0.20000000051616 0.20000001351842 0.2000269146811 0.20398546530331 0.28985378130883 0.65316871363172 0.9 0.9 0.9 0.9 0.9 0.61374353377905 0.50395113822961 0.50003629931515 0.50000003325198 0.50000000000271 0.49999999999999 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.36162109127011 0.21923042159377 0.20052728912273 0.20000181794206 0.20000000051616 0.20000001351842 0.2000269146811 0.20398546530335 0.28985378130907 0.65316871363178 0.9 0.9 0.9 0.9 0.9 0.61374353377875 0.50395113822963 0.50003629931515 0.50000003325198 0.50000000000271 0.49999999999999 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.36162109127011 0.21923042159377 0.20052728912273 0.20000181794206 0.20000000051616 0.20000001351842 0.2000269146811 0.20398546530341 0.28985378130891 0.653168713632 0.9 0.9 0.9 0.9 0.9 0.61374353377782 0.50395113822968 0.50003629931515 0.50000003325198 0.50000000000271 0.49999999999999 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.36162109127011 0.21923042159377 0.20052728912273 0.20000181794206 0.20000000051616 0.20000001351842 0.20002691468109 0.20398546530306 0.28985378130735 0.65316871363037 0.9 0.9 0.9 0.9 0.9 0.61374353378282 0.50395113822939 0.50003629931514 0.50000003325198 0.50000000000271 0.49999999999999 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.36162109127012 0.21923042159378 0.20052728912272 0.20000181794206 0.20000000051616 0.20000001351842 0.20002691468109 0.20398546530446 0.28985378133188 0.65316871363168 0.9 0.9 0.9 0.9 0.9 0.61374353378372 0.50395113822953 0.50003629931513 0.50000003325198 0.50000000000271 0.49999999999999 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.36162109127007 0.2192304215937 0.2005272891227 0.20000181794206 0.20000000051616 0.20000001351842 0.20002691468103 0.20398546534729 0.28985378187382 0.65316871368996 0.9 0.9 0.9 0.9 0.9 0.61374353364707 0.50395113823736 0.5000362993154 0.50000003325198 0.50000000000271 0.49999999999999 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.36162109126974 0.21923042159358 0.20052728912271 0.20000181794206 0.20000000051616 0.20000001351842 0.20002691467882 0.20398546607941 0.28985379241256 0.65316871608172 0.9 0.9 0.9 0.9 0.9 0.6137435316164 0.50395113835505 0.50003629932006 0.50000003325199 0.50000000000271 0.49999999999999 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.36162109127031 0.21923042159419 0.20052728912287 0.20000181794205 0.20000000051616 0.20000001351839 0.20002691461949 0.20398547699248 0.2898539735587 0.65316878156362 0.9 0.9 0.9 0.9 0.9 0.61374350073987 0.50395114012309 0.50003629939784 0.50000003325208 0.50000000000271 0.49999999999999 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.36162109126998 0.21923042159891 0.20052728912159 0.20000181794184 0.20000000051616 0.20000001351765 0.20002691351322 0.20398562388113 0.28985667920991 0.65317015450427 0.9 0.9 0.9 0.9 0.9 0.61374309914772 0.5039511643396 0.50003630054302 0.50000003325362 0.50000000000271 0.49999999999999 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.36162109123099 0.21923042176957 0.2005272891027 0.20000181793784 0.20000000051618 0.20000001350443 0.20002689709877 0.20398729156016 0.28989087942471 0.65319162165962 0.9 0.9 0.9 0.9 0.9 0.61373847547273 0.50395146377441 0.50003631510213 0.50000003327514 0.50000000000272 0.49999999999999 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.36162109102522 0.21923042548939 0.20052728864006 0.20000181786439 0.20000000051642 0.20000001333032 0.20002672406333 0.20400471961339 0.29024937549153 0.65346668958606 0.9 0.9 0.9 0.9 0.9 0.61366045578489 0.50395599760001 0.50003651027558 0.500000033572 0.50000000000275 0.49999999999999 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.36162109292648 0.21923046593454 0.20052728591181 0.20000181743475 0.20000000051891 0.20000001200023 0.20002562636652 0.20404535332019 0.29049396278316 0.65122188561669 0.9 0.9 0.9 0.9 0.9 0.61364243329659 0.50398074343483 0.500037581112 0.50000003530287 0.50000000000294 0.49999999999999 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.3616217852344 0.21923168246927 0.20052734279194 0.20000179999754 0.2000000004754 0.20000000024183 0.20000113674551 0.20053475575764 0.25520808662436 0.6404433522832 0.9 0.9 0.9 0.9 0.9 0.60744548462921 0.50408551748098 0.50004319348634 0.50000004488214 0.50000000000399 0.49999999999999 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.36162185619175 0.21923189464623 0.20052759519887 0.20000182765334 0.20000000050165 0.20000000000293 0.20000040892248 0.20015931486882 0.20900171217092 0.51794872757465 0.9 0.9 0.89511098121487 0.87285399898369 0.89203176789503 0.60909921711363 0.50374051234031 0.50003295401141 0.50000002813418 0.50000000000211 0.49999999999999 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.36162174712172 0.21923190306914 0.20052772870144 0.20000184825151 0.20000000052509 0.20000000000002 0.20000000004207 0.20000000032622 0.20001875263906 0.30808581756617 0.9 0.61050032780692 0.54394501931755 0.59615419454011 0.60234342429209 0.51139950551954 0.50013738019644 0.50000029096408 0.50000000005823 0.49999999999999 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.36162171440577 0.21923171911172 0.2005276564754 0.20000184409423 0.20000000053488 0.20000000037063 0.20000012949606 0.20000101191474 0.20000002831002 0.37568390324767 0.9 0.50000010295341 0.50000738736037 0.50103747694436 0.50066084340778 0.50047256246372 0.50000347787235 0.50000000235363 0.49999999999991 0.49999999999999 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.36162204059349 0.21923203979167 0.20052745461165 0.20000181037967 0.20000000047595 0.20000000041052 0.20000134033948 0.20046034569224 0.20948849026717 0.2 +D/cons.6.00.000050.dat 0.9 0.50001362971218 0.5000779740013 0.50949544275855 0.57417616490252 0.50312545678926 0.50001688303425 0.50000001549618 0.50000000000155 0.49999999999997 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.36162199804016 0.21923197559877 0.20052745629872 0.20000181212691 0.20000000047725 0.20000000040687 0.20000121932324 0.20046104044312 0.2091718911285 0.2 0.9 0.61048369919077 0.54364735463474 0.59193601188221 0.60098328041381 0.51043831241424 0.50012621180334 0.50000026989788 0.50000000005259 0.49999999999999 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.36162166584493 0.21923156643412 0.20052760941964 0.20000184151564 0.20000000053935 0.2000000003777 0.20000012886018 0.20000101111023 0.20000002831085 0.37568266632189 0.9 0.9 0.8951104187835 0.87268331664979 0.89255956815864 0.60431489916225 0.50353733817738 0.50003201071129 0.50000002799848 0.5000000000021 0.49999999999999 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.36162183490109 0.21923166556958 0.200527606063 0.20000183637526 0.20000000055326 0.20000000000002 0.20000000004162 0.20000000030487 0.2000187036237 0.30808201461077 0.9 0.9 0.9 0.89999999999907 0.89999999999766 0.60653002981158 0.50401795182027 0.50004232138094 0.50000004404899 0.5000000000039 0.49999999999999 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.3616219393896 0.21923196779354 0.20052758390195 0.20000182547979 0.20000000050379 0.20000000000105 0.20000040595672 0.20015900561741 0.20899196898586 0.51790392543118 0.9 0.9 0.9 0.9 0.90000000000002 0.61360021178726 0.50396962451315 0.50003743909214 0.5000000351718 0.50000000000293 0.49999999999999 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.36162191726594 0.21923187449319 0.20052738085141 0.20000180193693 0.20000000047682 0.20000000021939 0.20000112840425 0.20053310207476 0.25514550658405 0.640253498031 0.9 0.9 0.9 0.9 0.9 0.61364278775764 0.50395643393775 0.50003654386538 0.50000003363088 0.50000000000275 0.49999999999999 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.36162112202836 0.21923050895531 0.20052729144188 0.20000181740397 0.2000000005202 0.20000001177552 0.20002552582891 0.20403900638041 0.29039221731466 0.65102896057908 0.9 0.9 0.9 0.9 0.9 0.61373612575537 0.50395148365416 0.50003631984091 0.50000003328316 0.50000000000272 0.49999999999999 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.3616210931288 0.21923042996988 0.20052728909417 0.20000181786152 0.20000000051662 0.20000001326634 0.20002667338385 0.20400172101256 0.29022769738539 0.65344463968353 0.9 0.9 0.9 0.9 0.9 0.61374291239597 0.50395116326873 0.5000363009243 0.50000003325432 0.50000000000271 0.49999999999999 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.36162109138533 0.2192304222183 0.20052728917004 0.20000181793854 0.2000000005162 0.20000001349617 0.20002688952046 0.2039868611058 0.28988833464265 0.6531899327725 0.9 0.9 0.9 0.9 0.9 0.61374348776966 0.50395113997145 0.50003629942944 0.50000003325214 0.50000000000271 0.49999999999999 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.36162109128097 0.2192304216341 0.20052728912867 0.20000181794198 0.20000000051616 0.20000001351681 0.20002691265641 0.20398557456613 0.28985642694078 0.65316998241504 0.9 0.9 0.9 0.9 0.9 0.61374353075556 0.50395113834277 0.50003629932238 0.50000003325199 0.50000000000271 0.49999999999999 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.3616210912718 0.21923042159606 0.20052728912344 0.20000181794207 0.20000000051616 0.20000001351832 0.20002691454817 0.20398547309269 0.28985395383843 0.65316877034987 0.9 0.9 0.9 0.9 0.9 0.61374353360643 0.50395113823717 0.50003629931557 0.50000003325198 0.50000000000271 0.49999999999999 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.36162109126965 0.21923042159357 0.20052728912268 0.20000181794206 0.20000000051616 0.20000001351841 0.20002691467336 0.20398546578469 0.2898537910885 0.6531687153679 0.9 0.9 0.9 0.9 0.9 0.61374353378684 0.50395113822994 0.50003629931515 0.50000003325198 0.50000000000271 0.49999999999999 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.36162109126998 0.21923042159376 0.20052728912269 0.20000181794206 0.20000000051616 0.20000001351842 0.20002691468071 0.20398546532904 0.28985378179402 0.65316871364994 0.9 0.9 0.9 0.9 0.9 0.61374353378196 0.5039511382294 0.50003629931514 0.50000003325198 0.50000000000271 0.49999999999999 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.36162109127012 0.21923042159379 0.20052728912273 0.20000181794206 0.20000000051616 0.20000001351842 0.20002691468107 0.20398546530349 0.28985378132508 0.65316871362903 0.9 0.9 0.9 0.9 0.9 0.61374353377743 0.50395113822963 0.50003629931515 0.50000003325198 0.50000000000271 0.49999999999999 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.36162109127011 0.21923042159377 0.20052728912273 0.20000181794206 0.20000000051616 0.20000001351842 0.2000269146811 0.20398546530303 0.28985378130712 0.65316871363046 0.9 0.9 0.9 0.9 0.9 0.61374353377879 0.50395113822963 0.50003629931515 0.50000003325198 0.50000000000271 0.49999999999999 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.36162109127011 0.21923042159377 0.20052728912272 0.20000181794206 0.20000000051616 0.20000001351842 0.2000269146811 0.20398546530343 0.28985378130924 0.653168713632 0.9 0.9 0.9 0.9 0.9 0.61374353377907 0.50395113822962 0.50003629931515 0.50000003325198 0.50000000000271 0.49999999999999 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.36162109127011 0.21923042159377 0.20052728912273 0.20000181794206 0.20000000051616 0.20000001351842 0.2000269146811 0.20398546530334 0.28985378130903 0.65316871363175 0.9 0.9 0.9 0.9 0.9 0.61374353377901 0.50395113822962 0.50003629931515 0.50000003325198 0.50000000000271 0.49999999999999 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.36162109127011 0.21923042159377 0.20052728912273 0.20000181794206 0.20000000051616 0.20000001351842 0.2000269146811 0.20398546530331 0.28985378130882 0.65316871363173 0.9 0.9 0.9 0.9 0.9 0.613743533779 0.50395113822962 0.50003629931515 0.50000003325198 0.50000000000271 0.49999999999999 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.36162109127011 0.21923042159377 0.20052728912273 0.20000181794206 0.20000000051616 0.20000001351842 0.2000269146811 0.20398546530331 0.28985378130883 0.65316871363174 0.9 0.9 0.9 0.9 0.9 0.613743533779 0.50395113822962 0.50003629931515 0.50000003325198 0.50000000000271 0.49999999999999 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.36162109127011 0.21923042159377 0.20052728912273 0.20000181794206 0.20000000051616 0.20000001351842 0.2000269146811 0.20398546530331 0.28985378130883 0.65316871363174 0.9 0.9 0.9 0.9 0.9 0.613743533779 0.50395113822962 0.50003629931515 0.50000003325198 0.50000000000271 0.49999999999999 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.36162109127011 0.21923042159377 0.20052728912273 0.20000181794206 0.20000000051616 0.20000001351842 0.2000269146811 0.20398546530331 0.28985378130883 0.65316871363174 0.9 0.9 0.9 0.9 0.9 0.613743533779 0.50395113822962 0.50003629931515 0.50000003325198 0.50000000000271 0.49999999999999 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.36162109127011 0.21923042159377 0.20052728912273 0.20000181794206 0.20000000051616 0.20000001351842 0.2000269146811 0.20398546530331 0.28985378130883 0.65316871363174 0.9 0.9 0.9 0.9 0.9 0.613743533779 0.50395113822962 0.50003629931515 0.50000003325198 0.50000000000271 0.49999999999999 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.36162109127011 0.21923042159377 0.20052728912273 0.20000181794206 0.20000000051616 0.20000001351842 0.2000269146811 0.20398546530331 0.28985378130883 0.65316871363174 0.9 0.9 0.9 0.9 0.9 0.613743533779 0.50395113822962 0.50003629931515 0.50000003325198 0.50000000000271 0.49999999999999 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.36162109127011 0.21923042159377 0.20052728912273 0.20000181794206 0.20000000051616 0.20000001351842 0.2000269146811 0.20398546530331 0.28985378130883 0.65316871363174 0.9 0.9 0.9 0.9 0.9 0.613743533779 0.50395113822962 0.50003629931515 0.50000003325198 0.50000000000271 0.49999999999999 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.36162109127011 0.21923042159377 0.20052728912273 0.20000181794206 0.20000000051616 0.20000001351842 0.2000269146811 0.20398546530331 0.28985378130883 0.65316871363174 0.9 0.9 0.9 0.9 0.9 0.613743533779 0.50395113822962 0.50003629931515 0.50000003325198 0.50000000000271 0.49999999999999 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.36162109127011 0.21923042159377 0.20052728912273 0.20000181794206 0.20000000051616 0.20000001351842 0.2000269146811 0.20398546530331 0.28985378130883 0.65316871363174 0.9 0.9 0.9 0.9 0.9 0.613743533779 0.50395113822962 0.50003629931515 0.50000003325198 0.50000000000271 0.49999999999999 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.36162109127011 0.21923042159377 0.20052728912273 0.20000181794206 0.20000000051616 0.20000001351842 0.2000269146811 0.20398546530331 0.28985378130883 0.65316871363174 0.9 0.9 0.9 0.9 0.9 0.613743533779 0.50395113822962 0.50003629931515 0.50000003325198 0.50000000000271 0.49999999999999 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.36162109127011 0.21923042159377 0.20052728912273 0.20000181794206 0.20000000051616 0.20000001351842 0.2000269146811 0.20398546530331 0.28985378130883 0.65316871363174 0.9 0.9 0.9 0.9 0.9 0.613743533779 0.50395113822962 0.50003629931515 0.50000003325198 0.50000000000271 0.49999999999999 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.36162109127011 0.21923042159377 0.20052728912273 0.20000181794206 0.20000000051616 0.20000001351842 0.2000269146811 0.20398546530331 0.28985378130883 0.65316871363174 0.9 0.9 0.9 0.9 0.9 0.613743533779 0.50395113822962 0.50003629931515 0.50000003325198 0.50000000000271 0.49999999999999 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.36162109127011 0.21923042159377 0.20052728912273 0.20000181794206 0.20000000051616 0.20000001351842 0.2000269146811 0.20398546530331 0.28985378130883 0.65316871363174 0.9 0.9 0.9 0.9 0.9 0.613743533779 0.50395113822962 0.50003629931515 0.50000003325198 0.50000000000271 0.49999999999999 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.36162109127011 0.21923042159377 0.20052728912273 0.20000181794206 0.20000000051616 0.20000001351842 0.2000269146811 0.20398546530331 0.28985378130883 0.65316871363174 0.9 0.9 0.9 0.9 0.9 0.613743533779 0.50395113822962 0.50003629931515 0.50000003325198 0.50000000000271 0.49999999999999 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.36162109127011 0.21923042159377 0.20052728912273 0.20000181794206 0.20000000051616 0.20000001351842 0.2000269146811 0.20398546530331 0.28985378130883 0.65316871363174 0.9 0.9 0.9 0.9 0.9 0.613743533779 0.50395113822962 0.50003629931515 0.50000003325198 0.50000000000271 0.49999999999999 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.36162109127011 0.21923042159377 0.20052728912273 0.20000181794206 0.20000000051616 0.20000001351842 0.2000269146811 0.20398546530332 0.28985378130883 0.65316871363174 0.9 0.9 0.9 0.9 0.9 0.613743533779 0.50395113822962 0.50003629931515 0.50000003325198 0.50000000000271 0.49999999999999 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.36162109127011 0.21923042159377 0.20052728912273 0.20000181794206 0.20000000051616 0.20000001351842 0.2000269146811 0.20398546530331 0.28985378130882 0.65316871363174 0.9 0.9 0.9 0.9 0.9 0.61374353377901 0.50395113822962 0.50003629931515 0.50000003325198 0.50000000000271 0.49999999999999 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.36162109127011 0.21923042159377 0.20052728912273 0.20000181794206 0.20000000051616 0.20000001351842 0.2000269146811 0.20398546530331 0.28985378130883 0.65316871363172 0.9 0.9 0.9 0.9 0.9 0.61374353377905 0.50395113822961 0.50003629931515 0.50000003325198 0.50000000000271 0.49999999999999 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.36162109127011 0.21923042159377 0.20052728912273 0.20000181794206 0.20000000051616 0.20000001351842 0.2000269146811 0.20398546530335 0.28985378130907 0.65316871363178 0.9 0.9 0.9 0.9 0.9 0.61374353377875 0.50395113822963 0.50003629931515 0.50000003325198 0.50000000000271 0.49999999999999 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.36162109127011 0.21923042159377 0.20052728912273 0.20000181794206 0.20000000051616 0.20000001351842 0.2000269146811 0.20398546530341 0.28985378130891 0.653168713632 0.9 0.9 0.9 0.9 0.9 0.61374353377782 0.50395113822968 0.50003629931515 0.50000003325198 0.50000000000271 0.49999999999999 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.36162109127011 0.21923042159377 0.20052728912273 0.20000181794206 0.20000000051616 0.20000001351842 0.20002691468109 0.20398546530306 0.28985378130735 0.65316871363037 0.9 0.9 0.9 0.9 0.9 0.61374353378282 0.50395113822939 0.50003629931514 0.50000003325198 0.50000000000271 0.49999999999999 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.36162109127012 0.21923042159378 0.20052728912272 0.20000181794206 0.20000000051616 0.20000001351842 0.20002691468109 0.20398546530446 0.28985378133188 0.65316871363168 0.9 0.9 0.9 0.9 0.9 0.61374353378372 0.50395113822953 0.50003629931513 0.50000003325198 0.50000000000271 0.49999999999999 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.36162109127007 0.2192304215937 0.2005272891227 0.20000181794206 0.20000000051616 0.20000001351842 0.20002691468103 0.20398546534729 0.28985378187382 0.65316871368996 0.9 0.9 0.9 0.9 0.9 0.61374353364707 0.50395113823736 0.5000362993154 0.50000003325198 0.50000000000271 0.49999999999999 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.36162109126974 0.21923042159358 0.20052728912271 0.20000181794206 0.20000000051616 0.20000001351842 0.20002691467882 0.20398546607941 0.28985379241256 0.65316871608171 0.9 0.9 0.9 0.9 0.9 0.6137435316164 0.50395113835505 0.50003629932006 0.50000003325199 0.50000000000271 0.49999999999999 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.36162109127031 0.21923042159419 0.20052728912287 0.20000181794205 0.20000000051616 0.20000001351839 0.20002691461949 0.20398547699248 0.2898539735587 0.65316878156362 0.9 0.9 0.9 0.9 0.9 0.61374350073987 0.50395114012309 0.50003629939784 0.50000003325208 0.50000000000271 0.49999999999999 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.36162109126998 0.21923042159891 0.20052728912159 0.20000181794184 0.20000000051616 0.20000001351765 0.20002691351322 0.20398562388113 0.28985667920991 0.65317015450427 0.9 0.9 0.9 0.9 0.9 0.61374309914772 0.5039511643396 0.50003630054302 0.50000003325362 0.50000000000271 0.49999999999999 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.36162109123099 0.21923042176957 0.2005272891027 0.20000181793784 0.20000000051618 0.20000001350443 0.20002689709877 0.20398729156016 0.28989087942471 0.65319162165962 0.9 0.9 0.9 0.9 0.9 0.61373847547273 0.50395146377441 0.50003631510213 0.50000003327514 0.50000000000272 0.49999999999999 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.36162109102522 0.21923042548939 0.20052728864006 0.20000181786439 0.20000000051642 0.20000001333032 0.20002672406333 0.20400471961339 0.29024937549153 0.65346668958606 0.9 0.9 0.9 0.9 0.9 0.61366045578489 0.50395599760001 0.50003651027558 0.500000033572 0.50000000000275 0.49999999999999 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.36162109292648 0.21923046593454 0.20052728591181 0.20000181743475 0.20000000051891 0.20000001200023 0.20002562636652 0.20404535332019 0.29049396278316 0.65122188561669 0.9 0.9 0.9 0.9 0.9 0.61364243329659 0.50398074343483 0.500037581112 0.50000003530287 0.50000000000294 0.49999999999999 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.3616217852344 0.21923168246927 0.20052734279194 0.20000179999754 0.2000000004754 0.20000000024183 0.20000113674551 0.20053475575764 0.25520808662436 0.6404433522832 0.9 0.9 0.9 0.9 0.9 0.60744548462921 0.50408551748098 0.50004319348634 0.50000004488214 0.50000000000399 0.49999999999999 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.36162185619175 0.21923189464623 0.20052759519887 0.20000182765334 0.20000000050165 0.20000000000293 0.20000040892248 0.20015931486882 0.20900171217092 0.51794872757465 0.9 0.9 0.89511098121487 0.87285399898369 0.89203176789503 0.60909921711363 0.50374051234031 0.50003295401141 0.50000002813418 0.50000000000211 0.49999999999999 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.36162174712172 0.21923190306914 0.20052772870144 0.20000184825151 0.20000000052509 0.20000000000002 0.20000000004207 0.20000000032622 0.20001875263906 0.30808581756617 0.9 0.61050032780692 0.54394501931755 0.59615419454011 0.60234342429209 0.51139950551954 0.50013738019644 0.50000029096408 0.50000000005823 0.49999999999999 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.36162171440577 0.21923171911172 0.2005276564754 0.20000184409423 0.20000000053488 0.20000000037063 0.20000012949606 0.20000101191474 0.20000002831002 0.37568390324767 0.9 0.50000010295341 0.50000738736037 0.50103747694436 0.50066084340778 0.50047256246372 0.50000347787235 0.50000000235363 0.49999999999991 0.49999999999999 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.36162204059349 0.21923203979167 0.20052745461165 0.20000181037967 0.20000000047595 0.20000000041052 0.20000134033948 0.20046034569224 0.20948849026717 0.2 D/cons.7.00.000000.dat 0.1 0.1 0.1 0.1 0.1 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.1 0.1 0.1 0.1 0.1 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.1 0.1 0.1 0.1 0.1 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.1 0.1 0.1 0.1 0.1 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.1 0.1 0.1 0.1 0.1 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.1 0.1 0.1 0.1 0.1 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.1 0.1 0.1 0.1 0.1 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.1 0.1 0.1 0.1 0.1 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.1 0.1 0.1 0.1 0.1 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.1 0.1 0.1 0.1 0.1 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.1 0.1 0.1 0.1 0.1 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.1 0.1 0.1 0.1 0.1 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.1 0.1 0.1 0.1 0.1 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.1 0.1 0.1 0.1 0.1 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.1 0.1 0.1 0.1 0.1 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.1 0.1 0.1 0.1 0.1 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.1 0.1 0.1 0.1 0.1 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.1 0.1 0.1 0.1 0.1 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.1 0.1 0.1 0.1 0.1 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.1 0.1 0.1 0.1 0.1 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.1 0.1 0.1 0.1 0.1 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.1 0.1 0.1 0.1 0.1 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.1 0.1 0.1 0.1 0.1 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.1 0.1 0.1 0.1 0.1 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.1 0.1 0.1 0.1 0.1 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.1 0.1 0.1 0.1 0.1 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.1 0.1 0.1 0.1 0.1 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.1 0.1 0.1 0.1 0.1 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.1 0.1 0.1 0.1 0.1 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.1 0.1 0.1 0.1 0.1 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.1 0.1 0.1 0.1 0.1 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.1 0.1 0.1 0.1 0.1 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.1 0.1 0.1 0.1 0.1 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.1 0.1 0.1 0.1 0.1 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.1 0.1 0.1 0.1 0.1 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.1 0.1 0.1 0.1 0.1 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.1 0.1 0.1 0.1 0.1 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.1 0.1 0.1 0.1 0.1 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.1 0.1 0.1 0.1 0.1 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.1 0.1 0.1 0.1 0.1 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.1 0.1 0.1 0.1 0.1 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.1 0.1 0.1 0.1 0.1 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.1 0.1 0.1 0.1 0.1 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.1 0.1 0.1 0.1 0.1 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.1 0.1 0.1 0.1 0.1 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.1 0.1 0.1 0.1 0.1 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.1 0.1 0.1 0.1 0.1 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.1 0.1 0.1 0.1 0.1 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.1 0.1 0.1 0.1 0.1 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.1 0.1 0.1 0.1 0.1 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8 D/cons.7.00.000050.dat 0.1 0.49998637028782 0.4999220259987 0.49050455724145 0.42582383509748 0.49687454321074 0.49998311696575 0.49999998450382 0.49999999999845 0.50000000000003 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.63837800195984 0.78076802440123 0.79947254370128 0.79999818787309 0.79999999952275 0.79999999959314 0.79999878067676 0.79953895955688 0.7908281088715 0.8 0.1 0.38951630080923 0.45635264536526 0.40806398811779 0.39901671958619 0.48956168758576 0.49987378819666 0.49999973010212 0.49999999994741 0.50000000000001 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.63837833415507 0.78076843356588 0.79947239058036 0.79999815848436 0.79999999946066 0.7999999996223 0.79999987113982 0.79999898888977 0.79999997168915 0.62431733367811 0.1 0.1 0.1048895812165 0.12731668335021 0.10744043184136 0.39568510083775 0.49646266182262 0.49996798928871 0.49999997200152 0.4999999999979 0.50000000000001 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.63837816509891 0.78076833443042 0.799472393937 0.79999816362474 0.79999999944674 0.79999999999998 0.79999999995838 0.79999999969513 0.7999812963763 0.69191798538923 0.1 0.1 0.1 0.10000000000093 0.10000000000234 0.39346997018842 0.49598204817973 0.49995767861905 0.49999995595101 0.4999999999961 0.50000000000001 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.6383780606104 0.78076803220646 0.79947241609805 0.79999817452021 0.79999999949621 0.79999999999895 0.79999959404328 0.79984099438259 0.79100803101414 0.48209607456882 0.1 0.1 0.1 0.09999999999999 0.09999999999998 0.38639978821274 0.49603037548685 0.49996256090786 0.4999999648282 0.49999999999707 0.50000000000001 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.63837808273406 0.78076812550681 0.79947261914859 0.79999819806307 0.79999999952318 0.79999999978061 0.79999887159575 0.79946689792524 0.74485449341594 0.359746501969 0.1 0.1 0.1 0.1 0.1 0.38635721224236 0.49604356606225 0.49996345613462 0.49999996636912 0.49999999999725 0.50000000000001 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.63837887797164 0.78076949104469 0.79947270855812 0.79999818259603 0.7999999994798 0.79999998822448 0.79997447417109 0.79596099361959 0.70960778268534 0.34897103942092 0.1 0.1 0.1 0.1 0.1 0.38626387424463 0.49604851634584 0.49996368015909 0.49999996671684 0.49999999999728 0.50000000000001 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.6383789068712 0.78076957003012 0.79947271090583 0.79999818213848 0.79999999948338 0.79999998673366 0.79997332661615 0.79599827898744 0.70977230261461 0.34655536031647 0.1 0.1 0.1 0.1 0.1 0.38625708760403 0.49604883673127 0.49996369907571 0.49999996674568 0.49999999999729 0.50000000000001 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.63837890861467 0.7807695777817 0.79947271082996 0.79999818206146 0.7999999994838 0.79999998650383 0.79997311047954 0.7960131388942 0.71011166535735 0.3468100672275 0.1 0.1 0.1 0.1 0.1 0.38625651223034 0.49604886002855 0.49996370057056 0.49999996674786 0.49999999999729 0.50000000000001 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.63837890871903 0.7807695783659 0.79947271087132 0.79999818205802 0.79999999948384 0.79999998648319 0.79997308734359 0.79601442543387 0.71014357305922 0.34683001758496 0.1 0.1 0.1 0.1 0.1 0.38625646924444 0.49604886165723 0.49996370067762 0.49999996674801 0.49999999999729 0.50000000000001 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.6383789087282 0.78076957840394 0.79947271087656 0.79999818205793 0.79999999948384 0.79999998648168 0.79997308545183 0.7960145269073 0.71014604616157 0.34683122965013 0.1 0.1 0.1 0.1 0.1 0.38625646639357 0.49604886176283 0.49996370068443 0.49999996674802 0.49999999999729 0.50000000000001 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.63837890873035 0.78076957840643 0.79947271087732 0.79999818205794 0.79999999948384 0.79999998648159 0.79997308532664 0.79601453421531 0.7101462089115 0.3468312846321 0.1 0.1 0.1 0.1 0.1 0.38625646621316 0.49604886177006 0.49996370068485 0.49999996674802 0.49999999999729 0.50000000000001 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.63837890873002 0.78076957840624 0.79947271087731 0.79999818205794 0.79999999948384 0.79999998648158 0.79997308531929 0.79601453467096 0.71014621820598 0.34683128635006 0.1 0.1 0.1 0.1 0.1 0.38625646621804 0.4960488617706 0.49996370068486 0.49999996674802 0.49999999999729 0.50000000000001 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.63837890872987 0.78076957840621 0.79947271087727 0.79999818205794 0.79999999948384 0.79999998648158 0.79997308531893 0.79601453469651 0.71014621867492 0.34683128637097 0.1 0.1 0.1 0.1 0.1 0.38625646622257 0.49604886177037 0.49996370068485 0.49999996674802 0.49999999999729 0.50000000000001 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.63837890872989 0.78076957840623 0.79947271087727 0.79999818205794 0.79999999948384 0.79999998648158 0.7999730853189 0.79601453469697 0.71014621869288 0.34683128636954 0.1 0.1 0.1 0.1 0.1 0.38625646622121 0.49604886177037 0.49996370068485 0.49999996674802 0.49999999999729 0.50000000000001 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.63837890872989 0.78076957840623 0.79947271087728 0.79999818205794 0.79999999948384 0.79999998648158 0.7999730853189 0.79601453469657 0.71014621869076 0.346831286368 0.1 0.1 0.1 0.1 0.1 0.38625646622093 0.49604886177038 0.49996370068485 0.49999996674802 0.49999999999729 0.50000000000001 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.63837890872989 0.78076957840623 0.79947271087728 0.79999818205794 0.79999999948384 0.79999998648158 0.7999730853189 0.79601453469666 0.71014621869097 0.34683128636825 0.1 0.1 0.1 0.1 0.1 0.38625646622099 0.49604886177038 0.49996370068485 0.49999996674802 0.49999999999729 0.50000000000001 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.63837890872989 0.78076957840623 0.79947271087728 0.79999818205794 0.79999999948384 0.79999998648158 0.7999730853189 0.79601453469669 0.71014621869118 0.34683128636827 0.1 0.1 0.1 0.1 0.1 0.386256466221 0.49604886177038 0.49996370068485 0.49999996674802 0.49999999999729 0.50000000000001 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.63837890872989 0.78076957840623 0.79947271087728 0.79999818205794 0.79999999948384 0.79999998648158 0.7999730853189 0.79601453469669 0.71014621869117 0.34683128636826 0.1 0.1 0.1 0.1 0.1 0.386256466221 0.49604886177038 0.49996370068485 0.49999996674802 0.49999999999729 0.50000000000001 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.63837890872989 0.78076957840623 0.79947271087728 0.79999818205794 0.79999999948384 0.79999998648158 0.7999730853189 0.79601453469669 0.71014621869117 0.34683128636826 0.1 0.1 0.1 0.1 0.1 0.386256466221 0.49604886177038 0.49996370068485 0.49999996674802 0.49999999999729 0.50000000000001 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.63837890872989 0.78076957840623 0.79947271087728 0.79999818205794 0.79999999948384 0.79999998648158 0.7999730853189 0.79601453469669 0.71014621869117 0.34683128636826 0.1 0.1 0.1 0.1 0.1 0.386256466221 0.49604886177038 0.49996370068485 0.49999996674802 0.49999999999729 0.50000000000001 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.63837890872989 0.78076957840623 0.79947271087728 0.79999818205794 0.79999999948384 0.79999998648158 0.7999730853189 0.79601453469669 0.71014621869117 0.34683128636826 0.1 0.1 0.1 0.1 0.1 0.386256466221 0.49604886177038 0.49996370068485 0.49999996674802 0.49999999999729 0.50000000000001 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.63837890872989 0.78076957840623 0.79947271087728 0.79999818205794 0.79999999948384 0.79999998648158 0.7999730853189 0.79601453469669 0.71014621869117 0.34683128636826 0.1 0.1 0.1 0.1 0.1 0.386256466221 0.49604886177038 0.49996370068485 0.49999996674802 0.49999999999729 0.50000000000001 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.63837890872989 0.78076957840623 0.79947271087728 0.79999818205794 0.79999999948384 0.79999998648158 0.7999730853189 0.79601453469669 0.71014621869117 0.34683128636826 0.1 0.1 0.1 0.1 0.1 0.386256466221 0.49604886177038 0.49996370068485 0.49999996674802 0.49999999999729 0.50000000000001 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.63837890872989 0.78076957840623 0.79947271087728 0.79999818205794 0.79999999948384 0.79999998648158 0.7999730853189 0.79601453469669 0.71014621869117 0.34683128636826 0.1 0.1 0.1 0.1 0.1 0.386256466221 0.49604886177038 0.49996370068485 0.49999996674802 0.49999999999729 0.50000000000001 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.63837890872989 0.78076957840623 0.79947271087728 0.79999818205794 0.79999999948384 0.79999998648158 0.7999730853189 0.79601453469669 0.71014621869117 0.34683128636826 0.1 0.1 0.1 0.1 0.1 0.386256466221 0.49604886177038 0.49996370068485 0.49999996674802 0.49999999999729 0.50000000000001 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.63837890872989 0.78076957840623 0.79947271087728 0.79999818205794 0.79999999948384 0.79999998648158 0.7999730853189 0.79601453469669 0.71014621869117 0.34683128636826 0.1 0.1 0.1 0.1 0.1 0.386256466221 0.49604886177038 0.49996370068485 0.49999996674802 0.49999999999729 0.50000000000001 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.63837890872989 0.78076957840623 0.79947271087728 0.79999818205794 0.79999999948384 0.79999998648158 0.7999730853189 0.79601453469669 0.71014621869117 0.34683128636826 0.1 0.1 0.1 0.1 0.1 0.386256466221 0.49604886177038 0.49996370068485 0.49999996674802 0.49999999999729 0.50000000000001 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.63837890872989 0.78076957840623 0.79947271087728 0.79999818205794 0.79999999948384 0.79999998648158 0.7999730853189 0.79601453469669 0.71014621869117 0.34683128636826 0.1 0.1 0.1 0.1 0.1 0.386256466221 0.49604886177038 0.49996370068485 0.49999996674802 0.49999999999729 0.50000000000001 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.63837890872989 0.78076957840623 0.79947271087728 0.79999818205794 0.79999999948384 0.79999998648158 0.7999730853189 0.79601453469669 0.71014621869117 0.34683128636826 0.1 0.1 0.1 0.1 0.1 0.386256466221 0.49604886177038 0.49996370068485 0.49999996674802 0.49999999999729 0.50000000000001 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.63837890872989 0.78076957840623 0.79947271087728 0.79999818205794 0.79999999948384 0.79999998648158 0.7999730853189 0.79601453469669 0.71014621869117 0.34683128636826 0.1 0.1 0.1 0.1 0.1 0.386256466221 0.49604886177038 0.49996370068485 0.49999996674802 0.49999999999729 0.50000000000001 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.63837890872989 0.78076957840623 0.79947271087728 0.79999818205794 0.79999999948384 0.79999998648158 0.7999730853189 0.79601453469669 0.71014621869117 0.34683128636826 0.1 0.1 0.1 0.1 0.1 0.386256466221 0.49604886177038 0.49996370068485 0.49999996674802 0.49999999999729 0.50000000000001 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.63837890872989 0.78076957840623 0.79947271087728 0.79999818205794 0.79999999948384 0.79999998648158 0.7999730853189 0.79601453469669 0.71014621869117 0.34683128636826 0.1 0.1 0.1 0.1 0.1 0.386256466221 0.49604886177038 0.49996370068485 0.49999996674802 0.49999999999729 0.50000000000001 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.63837890872989 0.78076957840623 0.79947271087728 0.79999818205794 0.79999999948384 0.79999998648158 0.7999730853189 0.79601453469669 0.71014621869118 0.34683128636826 0.1 0.1 0.1 0.1 0.1 0.38625646622099 0.49604886177038 0.49996370068485 0.49999996674802 0.49999999999729 0.50000000000001 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.63837890872989 0.78076957840623 0.79947271087728 0.79999818205794 0.79999999948384 0.79999998648158 0.7999730853189 0.79601453469669 0.71014621869117 0.34683128636828 0.1 0.1 0.1 0.1 0.1 0.38625646622095 0.49604886177039 0.49996370068485 0.49999996674802 0.49999999999729 0.50000000000001 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.63837890872989 0.78076957840623 0.79947271087728 0.79999818205794 0.79999999948384 0.79999998648158 0.7999730853189 0.79601453469665 0.71014621869093 0.34683128636822 0.1 0.1 0.1 0.1 0.1 0.38625646622125 0.49604886177037 0.49996370068485 0.49999996674802 0.49999999999729 0.50000000000001 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.63837890872989 0.78076957840623 0.79947271087728 0.79999818205794 0.79999999948384 0.79999998648158 0.7999730853189 0.79601453469659 0.71014621869109 0.346831286368 0.1 0.1 0.1 0.1 0.1 0.38625646622218 0.49604886177032 0.49996370068485 0.49999996674802 0.49999999999729 0.50000000000001 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.63837890872989 0.78076957840623 0.79947271087727 0.79999818205794 0.79999999948384 0.79999998648158 0.79997308531891 0.79601453469694 0.71014621869265 0.34683128636963 0.1 0.1 0.1 0.1 0.1 0.38625646621718 0.49604886177061 0.49996370068486 0.49999996674802 0.49999999999729 0.50000000000001 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.63837890872988 0.78076957840622 0.79947271087728 0.79999818205794 0.79999999948384 0.79999998648158 0.79997308531892 0.79601453469554 0.71014621866812 0.34683128636832 0.1 0.1 0.1 0.1 0.1 0.38625646621628 0.49604886177047 0.49996370068487 0.49999996674802 0.49999999999729 0.50000000000001 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.63837890872993 0.7807695784063 0.7994727108773 0.79999818205794 0.79999999948384 0.79999998648158 0.79997308531897 0.79601453465271 0.71014621812618 0.34683128631004 0.1 0.1 0.1 0.1 0.1 0.38625646635293 0.49604886176264 0.4999637006846 0.49999996674802 0.49999999999729 0.50000000000001 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.63837890873026 0.78076957840642 0.79947271087729 0.79999818205794 0.79999999948384 0.79999998648158 0.79997308532118 0.79601453392059 0.71014620758744 0.34683128391829 0.1 0.1 0.1 0.1 0.1 0.3862564683836 0.49604886164495 0.49996370067994 0.49999996674801 0.49999999999729 0.50000000000001 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.63837890872969 0.78076957840581 0.79947271087713 0.79999818205795 0.79999999948384 0.79999998648161 0.79997308538051 0.79601452300752 0.7101460264413 0.34683121843638 0.1 0.1 0.1 0.1 0.1 0.38625649926013 0.49604885987691 0.49996370060216 0.49999996674792 0.49999999999729 0.50000000000001 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.63837890873002 0.78076957840109 0.79947271087841 0.79999818205816 0.79999999948384 0.79999998648235 0.79997308648678 0.79601437611887 0.71014332079009 0.34682984549573 0.1 0.1 0.1 0.1 0.1 0.38625690085228 0.49604883566039 0.49996369945698 0.49999996674638 0.49999999999729 0.50000000000001 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.63837890876901 0.78076957823043 0.7994727108973 0.79999818206216 0.79999999948382 0.79999998649557 0.79997310290123 0.79601270843984 0.7101091205753 0.34680837834038 0.1 0.1 0.1 0.1 0.1 0.38626152452727 0.49604853622559 0.49996368489787 0.49999996672486 0.49999999999728 0.50000000000001 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.63837890897478 0.78076957451061 0.79947271135994 0.79999818213561 0.79999999948358 0.79999998666968 0.79997327593667 0.79599528038661 0.70975062450847 0.34653331041394 0.1 0.1 0.1 0.1 0.1 0.38633954421511 0.49604400239999 0.49996348972442 0.499999966428 0.49999999999725 0.50000000000001 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.63837890707352 0.78076953406546 0.79947271408819 0.79999818256525 0.79999999948109 0.79999998799977 0.79997437363348 0.79595464667981 0.70950603721684 0.34877811438331 0.1 0.1 0.1 0.1 0.1 0.38635756670341 0.49601925656516 0.499962418888 0.49999996469712 0.49999999999706 0.50000000000001 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.6383782147656 0.78076831753073 0.79947265720806 0.79999820000246 0.7999999995246 0.79999999975817 0.79999886325449 0.79946524424236 0.74479191337564 0.3595566477168 0.1 0.1 0.1 0.1 0.1 0.39255451537079 0.49591448251902 0.49995680651366 0.49999995511786 0.49999999999601 0.50000000000001 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.63837814380825 0.78076810535377 0.79947240480113 0.79999817234666 0.79999999949835 0.79999999999707 0.79999959107752 0.79984068513118 0.79099828782908 0.48205127242535 0.1 0.1 0.10488901878513 0.12714600101631 0.10796823210497 0.39090078288637 0.49625948765969 0.49996704598859 0.49999997186582 0.49999999999789 0.50000000000001 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.63837825287828 0.78076809693086 0.79947227129856 0.79999815174849 0.79999999947491 0.79999999999998 0.79999999995793 0.79999999967378 0.79998124736094 0.69191418243383 0.1 0.38949967219308 0.45605498068245 0.40384580545989 0.39765657570791 0.48860049448046 0.49986261980356 0.49999970903592 0.49999999994177 0.50000000000001 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.63837828559423 0.78076828088828 0.7994723435246 0.79999815590577 0.79999999946512 0.79999999962937 0.79999987050394 0.79999898808526 0.79999997168998 0.62431609675233 0.1 0.49999989704659 0.49999261263963 0.49896252305564 0.49933915659222 0.49952743753628 0.49999652212765 0.49999999764637 0.50000000000009 0.50000000000001 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.63837795940651 0.78076796020833 0.79947254538835 0.79999818962033 0.79999999952405 0.79999999958948 0.79999865966052 0.79953965430776 0.79051150973283 0.8 \ No newline at end of file diff --git a/tests/3008BA80/golden-metadata.txt b/tests/3008BA80/golden-metadata.txt index 4d2109a9f3..7c36f701ba 100644 --- a/tests/3008BA80/golden-metadata.txt +++ b/tests/3008BA80/golden-metadata.txt @@ -1,19 +1,19 @@ -This file was created on 2026-02-28 19:05:51.303647. +This file was created on 2026-03-04 15:59:56.615266. mfc.sh: - Invocation: test --only 3008BA80 --generate --no-gpu -j 8 + Invocation: test --generate -o 3008BA80 Lock: mpi=Yes & gpu=No & debug=No & gcov=No & unified=No & single=No & mixed=No & fastmath=No - Git: 53ebfb7c2c1e94dc6b01b6c191eaa4bb11d1adc3 on gpu-optimizations (dirty) + Git: 6ebc84435f0cd9c9ca2161ede72683409650cde2 on MovingBubblesFresh-clean (dirty) simulation: CMake Configuration: - CMake v3.28.3 on schwarzschild + CMake v3.30.3 on wingtip-gpu3.cc.gatech.edu - C : NVHPC v23.11.0 (/opt/nvidia/hpc_sdk/Linux_x86_64/23.11/compilers/bin/nvc) - Fortran : NVHPC v23.11.0 (/opt/nvidia/hpc_sdk/Linux_x86_64/23.11/compilers/bin/nvfortran) + C : NVHPC v25.11.0 (/fastscratch/bwilfong3/software/hpc_sdk_25_9/Linux_x86_64/25.11/compilers/bin/nvc) + Fortran : NVHPC v25.11.0 (/fastscratch/bwilfong3/software/hpc_sdk_25_9/Linux_x86_64/25.11/compilers/bin/nvfortran) PRE_PROCESS : OFF SIMULATION : ON @@ -26,16 +26,16 @@ simulation: OpenACC : OFF OpenMP : OFF - Fypp : /home/dan/Documents/repos/MFC/build/venv/bin/fypp + Fypp : /fastscratch/bwilfong3/software/MFC-Wilfong/build/venv/bin/fypp Doxygen : Build Type : Release Configuration Environment: - CC : /opt/nvidia/hpc_sdk/Linux_x86_64/23.11/compilers/bin/nvc - CXX : /opt/nvidia/hpc_sdk/Linux_x86_64/23.11/compilers/bin/nvc++ - FC : /opt/nvidia/hpc_sdk/Linux_x86_64/23.11/compilers/bin/nvfortran + CC : /fastscratch/bwilfong3/software/hpc_sdk_25_9/Linux_x86_64/25.11/compilers/bin/nvc + CXX : /fastscratch/bwilfong3/software/hpc_sdk_25_9/Linux_x86_64/25.11/compilers/bin/nvc++ + FC : /fastscratch/bwilfong3/software/hpc_sdk_25_9/Linux_x86_64/25.11/compilers/bin/nvfortran OMPI_CC : OMPI_CXX : OMPI_FC : @@ -44,10 +44,10 @@ syscheck: CMake Configuration: - CMake v3.28.3 on schwarzschild + CMake v3.30.3 on wingtip-gpu3.cc.gatech.edu - C : NVHPC v23.11.0 (/opt/nvidia/hpc_sdk/Linux_x86_64/23.11/compilers/bin/nvc) - Fortran : NVHPC v23.11.0 (/opt/nvidia/hpc_sdk/Linux_x86_64/23.11/compilers/bin/nvfortran) + C : NVHPC v25.11.0 (/fastscratch/bwilfong3/software/hpc_sdk_25_9/Linux_x86_64/25.11/compilers/bin/nvc) + Fortran : NVHPC v25.11.0 (/fastscratch/bwilfong3/software/hpc_sdk_25_9/Linux_x86_64/25.11/compilers/bin/nvfortran) PRE_PROCESS : OFF SIMULATION : OFF @@ -60,16 +60,16 @@ syscheck: OpenACC : OFF OpenMP : OFF - Fypp : /home/dan/Documents/repos/MFC/build/venv/bin/fypp + Fypp : /fastscratch/bwilfong3/software/MFC-Wilfong/build/venv/bin/fypp Doxygen : Build Type : Release Configuration Environment: - CC : /opt/nvidia/hpc_sdk/Linux_x86_64/23.11/compilers/bin/nvc - CXX : /opt/nvidia/hpc_sdk/Linux_x86_64/23.11/compilers/bin/nvc++ - FC : /opt/nvidia/hpc_sdk/Linux_x86_64/23.11/compilers/bin/nvfortran + CC : + CXX : + FC : OMPI_CC : OMPI_CXX : OMPI_FC : @@ -78,10 +78,10 @@ pre_process: CMake Configuration: - CMake v3.28.3 on schwarzschild + CMake v3.30.3 on wingtip-gpu3.cc.gatech.edu - C : NVHPC v23.11.0 (/opt/nvidia/hpc_sdk/Linux_x86_64/23.11/compilers/bin/nvc) - Fortran : NVHPC v23.11.0 (/opt/nvidia/hpc_sdk/Linux_x86_64/23.11/compilers/bin/nvfortran) + C : NVHPC v25.11.0 (/fastscratch/bwilfong3/software/hpc_sdk_25_9/Linux_x86_64/25.11/compilers/bin/nvc) + Fortran : NVHPC v25.11.0 (/fastscratch/bwilfong3/software/hpc_sdk_25_9/Linux_x86_64/25.11/compilers/bin/nvfortran) PRE_PROCESS : ON SIMULATION : OFF @@ -94,16 +94,50 @@ pre_process: OpenACC : OFF OpenMP : OFF - Fypp : /home/dan/Documents/repos/MFC/build/venv/bin/fypp + Fypp : /fastscratch/bwilfong3/software/MFC-Wilfong/build/venv/bin/fypp Doxygen : Build Type : Release Configuration Environment: - CC : /opt/nvidia/hpc_sdk/Linux_x86_64/23.11/compilers/bin/nvc - CXX : /opt/nvidia/hpc_sdk/Linux_x86_64/23.11/compilers/bin/nvc++ - FC : /opt/nvidia/hpc_sdk/Linux_x86_64/23.11/compilers/bin/nvfortran + CC : + CXX : + FC : + OMPI_CC : + OMPI_CXX : + OMPI_FC : + +post_process: + + CMake Configuration: + + CMake v3.30.3 on wingtip-gpu3.cc.gatech.edu + + C : NVHPC v25.11.0 (/fastscratch/bwilfong3/software/hpc_sdk_25_9/Linux_x86_64/25.11/compilers/bin/nvc) + Fortran : NVHPC v25.11.0 (/fastscratch/bwilfong3/software/hpc_sdk_25_9/Linux_x86_64/25.11/compilers/bin/nvfortran) + + PRE_PROCESS : OFF + SIMULATION : OFF + POST_PROCESS : ON + SYSCHECK : OFF + DOCUMENTATION : OFF + ALL : OFF + + MPI : ON + OpenACC : OFF + OpenMP : OFF + + Fypp : /fastscratch/bwilfong3/software/MFC-Wilfong/build/venv/bin/fypp + Doxygen : + + Build Type : Release + + Configuration Environment: + + CC : /fastscratch/bwilfong3/software/hpc_sdk_25_9/Linux_x86_64/25.11/compilers/bin/nvc + CXX : /fastscratch/bwilfong3/software/hpc_sdk_25_9/Linux_x86_64/25.11/compilers/bin/nvc++ + FC : /fastscratch/bwilfong3/software/hpc_sdk_25_9/Linux_x86_64/25.11/compilers/bin/nvfortran OMPI_CC : OMPI_CXX : OMPI_FC : @@ -112,49 +146,46 @@ CPU: CPU Info: From lscpu - Architecture: x86_64 - CPU op-mode(s): 32-bit, 64-bit - Address sizes: 46 bits physical, 48 bits virtual - Byte Order: Little Endian - CPU(s): 20 - On-line CPU(s) list: 0-19 - Vendor ID: GenuineIntel - Model name: 12th Gen Intel(R) Core(TM) i7-12700K - CPU family: 6 - Model: 151 - Thread(s) per core: 2 - Core(s) per socket: 12 - Socket(s): 1 - Stepping: 2 - CPU(s) scaling MHz: 36% - CPU max MHz: 5100.0000 - CPU min MHz: 800.0000 - BogoMIPS: 7219.20 - Flags: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc art arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc cpuid aperfmperf tsc_known_freq pni pclmulqdq dtes64 monitor ds_cpl vmx smx est tm2 ssse3 sdbg fma cx16 xtpr pdcm pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm abm 3dnowprefetch cpuid_fault cat_l2 cdp_l2 ssbd ibrs ibpb stibp ibrs_enhanced tpr_shadow flexpriority ept vpid ept_ad fsgsbase tsc_adjust bmi1 avx2 smep bmi2 erms invpcid rdt_a rdseed adx smap clflushopt clwb intel_pt sha_ni xsaveopt xsavec xgetbv1 xsaves split_lock_detect user_shstk avx_vnni dtherm ida arat pln pts hwp hwp_notify hwp_act_window hwp_epp hwp_pkg_req hfi vnmi umip pku ospke waitpkg gfni vaes vpclmulqdq rdpid movdiri movdir64b fsrm md_clear serialize pconfig arch_lbr ibt flush_l1d arch_capabilities - Virtualization: VT-x - L1d cache: 512 KiB (12 instances) - L1i cache: 512 KiB (12 instances) - L2 cache: 12 MiB (9 instances) - L3 cache: 25 MiB (1 instance) - NUMA node(s): 1 - NUMA node0 CPU(s): 0-19 - Vulnerability Gather data sampling: Not affected - Vulnerability Ghostwrite: Not affected - Vulnerability Indirect target selection: Not affected - Vulnerability Itlb multihit: Not affected - Vulnerability L1tf: Not affected - Vulnerability Mds: Not affected - Vulnerability Meltdown: Not affected - Vulnerability Mmio stale data: Not affected - Vulnerability Old microcode: Not affected - Vulnerability Reg file data sampling: Mitigation; Clear Register File - Vulnerability Retbleed: Not affected - Vulnerability Spec rstack overflow: Not affected - Vulnerability Spec store bypass: Mitigation; Speculative Store Bypass disabled via prctl - Vulnerability Spectre v1: Mitigation; usercopy/swapgs barriers and __user pointer sanitization - Vulnerability Spectre v2: Mitigation; Enhanced / Automatic IBRS; IBPB conditional; PBRSB-eIBRS SW sequence; BHI BHI_DIS_S - Vulnerability Srbds: Not affected - Vulnerability Tsa: Not affected - Vulnerability Tsx async abort: Not affected - Vulnerability Vmscape: Mitigation; IBPB before exit to userspace + Architecture: x86_64 + CPU op-mode(s): 32-bit, 64-bit + Address sizes: 52 bits physical, 57 bits virtual + Byte Order: Little Endian + CPU(s): 128 + On-line CPU(s) list: 0-127 + Vendor ID: GenuineIntel + Model name: Intel(R) Xeon(R) Gold 6338 CPU @ 2.00GHz + CPU family: 6 + Model: 106 + Thread(s) per core: 2 + Core(s) per socket: 32 + Socket(s): 2 + Stepping: 6 + CPU(s) scaling MHz: 47% + CPU max MHz: 3200.0000 + CPU min MHz: 800.0000 + BogoMIPS: 4000.00 + Flags: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc art arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc cpuid aperfmperf pni pclmulqdq dtes64 monitor ds_cpl vmx smx est tm2 ssse3 sdbg fma cx16 xtpr pdcm pcid dca sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm abm 3dnowprefetch cpuid_fault epb cat_l3 ssbd mba ibrs ibpb stibp ibrs_enhanced tpr_shadow flexpriority ept vpid ept_ad fsgsbase tsc_adjust bmi1 avx2 smep bmi2 erms invpcid cqm rdt_a avx512f avx512dq rdseed adx smap avx512ifma clflushopt clwb intel_pt avx512cd sha_ni avx512bw avx512vl xsaveopt xsavec xgetbv1 xsaves cqm_llc cqm_occup_llc cqm_mbm_total cqm_mbm_local split_lock_detect wbnoinvd dtherm ida arat pln pts vnmi avx512vbmi umip pku ospke avx512_vbmi2 gfni vaes vpclmulqdq avx512_vnni avx512_bitalg tme avx512_vpopcntdq la57 rdpid fsrm md_clear pconfig flush_l1d arch_capabilities + Virtualization: VT-x + L1d cache: 3 MiB (64 instances) + L1i cache: 2 MiB (64 instances) + L2 cache: 80 MiB (64 instances) + L3 cache: 96 MiB (2 instances) + NUMA node(s): 2 + NUMA node0 CPU(s): 0-31,64-95 + NUMA node1 CPU(s): 32-63,96-127 + Vulnerability Gather data sampling: Mitigation; Microcode + Vulnerability Itlb multihit: Not affected + Vulnerability L1tf: Not affected + Vulnerability Mds: Not affected + Vulnerability Meltdown: Not affected + Vulnerability Mmio stale data: Mitigation; Clear CPU buffers; SMT vulnerable + Vulnerability Reg file data sampling: Not affected + Vulnerability Retbleed: Not affected + Vulnerability Spec rstack overflow: Not affected + Vulnerability Spec store bypass: Mitigation; Speculative Store Bypass disabled via prctl + Vulnerability Spectre v1: Mitigation; usercopy/swapgs barriers and __user pointer sanitization + Vulnerability Spectre v2: Mitigation; Enhanced / Automatic IBRS; IBPB conditional; RSB filling; PBRSB-eIBRS SW sequence; BHI SW loop, KVM SW loop + Vulnerability Srbds: Not affected + Vulnerability Tsx async abort: Not affected + Vulnerability Vmscape: Not affected diff --git a/tests/3008BA80/golden.txt b/tests/3008BA80/golden.txt index 600a933dfa..a8d6b94ba0 100644 --- a/tests/3008BA80/golden.txt +++ b/tests/3008BA80/golden.txt @@ -1,10 +1,10 @@ D/cons.1.00.000000.dat 1.0 1.0 1.0 1.0 1.0 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 1.0 1.0 1.0 1.0 1.0 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 1.0 1.0 1.0 1.0 1.0 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 1.0 1.0 1.0 1.0 1.0 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 1.0 1.0 1.0 1.0 1.0 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 1.0 1.0 1.0 1.0 1.0 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 1.0 1.0 1.0 1.0 1.0 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 1.0 1.0 1.0 1.0 1.0 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 1.0 1.0 1.0 1.0 1.0 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 1.0 1.0 1.0 1.0 1.0 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 1.0 1.0 1.0 1.0 1.0 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 1.0 1.0 1.0 1.0 1.0 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 1.0 1.0 1.0 1.0 1.0 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 1.0 1.0 1.0 1.0 1.0 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 1.0 1.0 1.0 1.0 1.0 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 1.0 1.0 1.0 1.0 1.0 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 1.0 1.0 1.0 1.0 1.0 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 1.0 1.0 1.0 1.0 1.0 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 1.0 1.0 1.0 1.0 1.0 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 1.0 1.0 1.0 1.0 1.0 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 1.0 1.0 1.0 1.0 1.0 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 1.0 1.0 1.0 1.0 1.0 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 1.0 1.0 1.0 1.0 1.0 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 1.0 1.0 1.0 1.0 1.0 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 1.0 1.0 1.0 1.0 1.0 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 1.0 1.0 1.0 1.0 1.0 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 1.0 1.0 1.0 1.0 1.0 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 1.0 1.0 1.0 1.0 1.0 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 1.0 1.0 1.0 1.0 1.0 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 1.0 1.0 1.0 1.0 1.0 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 1.0 1.0 1.0 1.0 1.0 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 1.0 1.0 1.0 1.0 1.0 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 1.0 1.0 1.0 1.0 1.0 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 1.0 1.0 1.0 1.0 1.0 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 1.0 1.0 1.0 1.0 1.0 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 1.0 1.0 1.0 1.0 1.0 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 1.0 1.0 1.0 1.0 1.0 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 1.0 1.0 1.0 1.0 1.0 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 1.0 1.0 1.0 1.0 1.0 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 1.0 1.0 1.0 1.0 1.0 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 1.0 1.0 1.0 1.0 1.0 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 1.0 1.0 1.0 1.0 1.0 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 1.0 1.0 1.0 1.0 1.0 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 1.0 1.0 1.0 1.0 1.0 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 1.0 1.0 1.0 1.0 1.0 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 1.0 1.0 1.0 1.0 1.0 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 1.0 1.0 1.0 1.0 1.0 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 1.0 1.0 1.0 1.0 1.0 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 1.0 1.0 1.0 1.0 1.0 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 1.0 1.0 1.0 1.0 1.0 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 0.125 -D/cons.1.00.000050.dat 1.0 0.51043075105762 0.50914843433861 0.53746937852237 0.5744039135955 0.53073582667354 0.51427650265833 0.50282160533058 0.50036941362314 0.50003958288045 0.50000349200902 0.50000026142309 0.50000001696457 0.5000000009121 0.49999999995051 0.49999999998516 0.50000000001107 0.5000000000006 0.49999999999942 0.50000000000004 0.50000000000003 0.49999999999999 0.5 0.5 0.49999999999995 0.50000000000008 0.50000000000071 0.49999999999656 0.49999999998895 0.50000000004864 0.49999999990507 0.49999999702752 0.49999994747562 0.49999918196833 0.49998896747283 0.49987441558983 0.49883319525548 0.49159138747038 0.44974321494722 0.3522719055169 0.24318851988032 0.19253161327859 0.14459194079761 0.12719698366321 0.12518126590012 0.12517077995377 0.12659327448592 0.14270539315164 0.16678116200749 0.125 0.95072868983487 0.64523183514755 0.59353413125036 0.59356348142983 0.58679015645055 0.54376288449459 0.52614369728682 0.50683415528736 0.5008723767016 0.50009650657605 0.50000867334875 0.50000065829167 0.50000004309271 0.50000000242627 0.50000000005926 0.49999999995823 0.50000000001132 0.50000000000277 0.49999999999931 0.49999999999995 0.50000000000005 0.5 0.5 0.5 0.49999999999995 0.50000000000008 0.50000000000071 0.49999999999656 0.49999999998895 0.50000000004864 0.49999999990507 0.49999999702752 0.49999994747562 0.49999918196835 0.49998896747309 0.49987441559026 0.49883319517623 0.4915913843737 0.44974317864824 0.35227189657132 0.24318846783252 0.19253174817458 0.14456682311491 0.12719144580763 0.1252111392919 0.12515623400709 0.1253461026974 0.12636488538847 0.12531596741075 0.30064797256645 0.9044527213652 0.91021685285956 0.81240500885839 0.73664088064436 0.7130822256633 0.5996328228091 0.5616129982527 0.52041482966071 0.50259291929662 0.50028127248097 0.50002479188194 0.50000184736327 0.50000011945464 0.50000000688777 0.50000000032344 0.49999999993363 0.50000000000465 0.50000000000649 0.49999999999951 0.49999999999976 0.50000000000006 0.50000000000001 0.5 0.5 0.49999999999995 0.50000000000008 0.50000000000071 0.49999999999656 0.49999999998895 0.50000000004864 0.49999999990507 0.49999999702752 0.49999994747563 0.49999918196849 0.49998896747589 0.49987441564026 0.49883319593146 0.49159139428891 0.44974326554532 0.35227173157218 0.24318902382593 0.19253028932223 0.1445749690617 0.12717535707629 0.12521075356276 0.1249727562415 0.12500325709618 0.12517487790483 0.12815422051682 0.27006982020504 0.91536466912977 0.95885698669035 0.91724697743707 0.82776067002862 0.75005552208987 0.61674551508496 0.57472798669626 0.52470706264064 0.50314282861692 0.50033856574943 0.50002958462135 0.50000218577744 0.50000014023644 0.50000000801864 0.50000000037658 0.49999999993268 0.50000000000305 0.50000000000703 0.49999999999957 0.49999999999973 0.50000000000006 0.50000000000001 0.5 0.5 0.49999999999995 0.50000000000008 0.50000000000071 0.49999999999656 0.49999999998895 0.50000000004864 0.49999999990507 0.49999999702752 0.49999994747562 0.4999991819683 0.49998896747228 0.49987441557977 0.49883319509652 0.49159138500342 0.44974319213186 0.35227189260898 0.24318858320468 0.19253002675269 0.14458095225109 0.12719220042869 0.1252088485695 0.12498453385354 0.12563284606598 0.12812609715842 0.16375946113618 0.36947600740272 0.93091870655547 0.93621890052843 0.97806892915767 0.90819897394461 0.81358274232151 0.64392377409552 0.58001564091531 0.52380459983127 0.50299650490622 0.50032466523703 0.50002842526043 0.5000021056931 0.50000013550933 0.50000000775096 0.50000000036144 0.49999999993238 0.50000000000371 0.50000000000691 0.49999999999954 0.49999999999974 0.50000000000006 0.50000000000001 0.5 0.5 0.49999999999995 0.50000000000008 0.50000000000071 0.49999999999656 0.49999999998895 0.50000000004864 0.49999999990507 0.49999999702752 0.49999994747562 0.49999918196824 0.49998896747095 0.49987441555582 0.49883319474484 0.4915913809069 0.44974315768844 0.35227203123439 0.24318815022442 0.19253336010566 0.14459540418593 0.12719093639369 0.12517012402885 0.12518305049218 0.12657859586128 0.13415897906839 0.21565242354672 0.43341479311069 0.69913808216375 0.91361700123503 0.96113677438347 0.92658816798526 0.82851953009158 0.64734337737922 0.58028428996242 0.5233732616337 0.50294710697412 0.50031998260471 0.50002806925502 0.50000208304166 0.50000013417287 0.50000000766706 0.50000000035755 0.4999999999325 0.50000000000381 0.50000000000686 0.49999999999953 0.49999999999974 0.50000000000006 0.50000000000001 0.5 0.5 0.49999999999995 0.50000000000008 0.50000000000071 0.49999999999656 0.49999999998895 0.50000000004864 0.49999999990507 0.49999999702752 0.49999994747561 0.49999918196821 0.49998896747019 0.49987441554143 0.49883319449343 0.49159137603035 0.44974310790739 0.35227207914048 0.24318836578862 0.19253826810679 0.14457994507651 0.12714914051218 0.12530119841691 0.12526079966909 0.12885461661009 0.15833911718006 0.26084863231669 0.43762218789982 0.66201542568464 0.90227112800171 0.95869742954856 0.93121772526239 0.83068243279126 0.64788364030861 0.58013401958186 0.52324036329357 0.50293427188016 0.50031890626996 0.50002799543155 0.50000207857389 0.50000013392672 0.5000000076581 0.50000000035736 0.49999999993249 0.50000000000381 0.50000000000686 0.49999999999953 0.49999999999974 0.50000000000006 0.50000000000001 0.5 0.5 0.49999999999995 0.50000000000008 0.50000000000071 0.49999999999656 0.49999999998895 0.50000000004864 0.49999999990507 0.49999999702752 0.49999994747561 0.4999991819682 0.49998896747007 0.4998744155391 0.49883319445095 0.49159137521548 0.44974309932632 0.35227207875513 0.24318830151111 0.19253907653494 0.14457831115001 0.1271452803891 0.12531827312689 0.12528426187233 0.12922865110337 0.16172520965872 0.26285087835962 0.43177093848594 0.64792300677814 0.89925805736421 0.95819268487764 0.93186551978377 0.83095222016131 0.64792791914122 0.58009261509854 0.52322272639417 0.5029327408517 0.50031878754836 0.50002798765007 0.50000207820522 0.50000013392635 0.50000000765937 0.50000000035743 0.49999999993247 0.50000000000381 0.50000000000687 0.49999999999953 0.49999999999974 0.50000000000006 0.50000000000001 0.5 0.5 0.49999999999995 0.50000000000008 0.50000000000071 0.49999999999656 0.49999999998895 0.50000000004864 0.49999999990507 0.49999999702752 0.49999994747561 0.4999991819682 0.49998896747006 0.49987441553889 0.49883319444709 0.49159137514514 0.44974309848471 0.35227207913939 0.24318828694933 0.19253916825366 0.14457809153956 0.12714495078432 0.12532084188047 0.12528750383345 0.12928580849733 0.16221935797328 0.26275511477986 0.42632662021231 0.64603571098897 0.89886185564412 0.95813856776999 0.93193933279498 0.83097921766108 0.64793035419377 0.58008792114178 0.52322093681094 0.50293259832332 0.50031877718442 0.50002798703831 0.50000207821305 0.50000013392672 0.50000000765928 0.50000000035742 0.49999999993248 0.50000000000381 0.50000000000687 0.49999999999953 0.49999999999974 0.50000000000006 0.50000000000001 0.5 0.5 0.49999999999995 0.50000000000008 0.50000000000071 0.49999999999656 0.49999999998895 0.50000000004864 0.49999999990507 0.49999999702752 0.49999994747561 0.4999991819682 0.49998896747007 0.49987441553892 0.4988331944474 0.4915913751479 0.44974309847869 0.35227207909579 0.24318828593133 0.19253917608077 0.14457807946903 0.12714493097836 0.12532100681458 0.12528779751537 0.12929083908667 0.16226267959637 0.26266889826383 0.42533820630149 0.64583416594091 0.89882053956282 0.95813377614523 0.93194615102478 0.83098143283326 0.64793037876647 0.58008747623764 0.52322079041351 0.50293258745546 0.50031877643547 0.5000279870597 0.50000207821034 0.50000013392563 0.50000000765918 0.50000000035742 0.49999999993248 0.50000000000381 0.50000000000687 0.49999999999953 0.49999999999974 0.50000000000006 0.50000000000001 0.5 0.5 0.49999999999995 0.50000000000008 0.50000000000071 0.49999999999656 0.49999999998895 0.50000000004864 0.49999999990507 0.49999999702752 0.49999994747561 0.4999991819682 0.49998896747007 0.49987441553891 0.49883319444731 0.49159137514701 0.44974309848663 0.35227207904895 0.24318828589761 0.19253917662956 0.1445780788912 0.12714492989989 0.12532101619908 0.12528781910179 0.12929120247843 0.16226585772629 0.26265453436891 0.42522533106949 0.64581694981204 0.89881707039178 0.95813342216666 0.93194667819156 0.83098158599631 0.64793036764791 0.58008744200679 0.52322078033073 0.50293258673082 0.50031877646286 0.50002798705959 0.50000207820759 0.50000013392546 0.50000000765918 0.50000000035742 0.49999999993248 0.50000000000381 0.50000000000687 0.49999999999953 0.49999999999974 0.50000000000006 0.50000000000001 0.5 0.5 0.49999999999995 0.50000000000008 0.50000000000071 0.49999999999656 0.49999999998895 0.50000000004864 0.49999999990507 0.49999999702752 0.49999994747561 0.4999991819682 0.49998896747007 0.49987441553891 0.49883319444727 0.49159137514648 0.44974309848241 0.35227207905328 0.24318828592603 0.19253917661131 0.14457807890173 0.12714492988404 0.12532101659656 0.12528782035558 0.12929122441469 0.16226605467472 0.26265295691472 0.42521487205589 0.64581571913867 0.89881682589216 0.95813339966458 0.93194671306744 0.83098159524344 0.64793036608468 0.58008743968831 0.52322077968271 0.50293258676648 0.50031877646807 0.5000279870552 0.50000207820758 0.50000013392549 0.50000000765918 0.50000000035742 0.49999999993248 0.50000000000381 0.50000000000687 0.49999999999953 0.49999999999974 0.50000000000006 0.50000000000001 0.5 0.5 0.49999999999995 0.50000000000008 0.50000000000071 0.49999999999656 0.49999999998895 0.50000000004864 0.49999999990507 0.49999999702752 0.49999994747561 0.4999991819682 0.49998896747006 0.49987441553891 0.49883319444726 0.49159137514642 0.44974309848143 0.35227207905569 0.24318828592061 0.19253917660145 0.1445780789133 0.12714492989587 0.12532101656436 0.12528782036582 0.12929122548165 0.16226606518407 0.2626528207358 0.42521407426831 0.64581564340794 0.89881681096218 0.95813339822554 0.93194671524802 0.83098159588256 0.64793036598898 0.5800874395727 0.52322077973366 0.50293258677357 0.50031877646245 0.50002798705521 0.50000207820765 0.5000001339255 0.50000000765918 0.50000000035742 0.49999999993248 0.50000000000381 0.50000000000687 0.49999999999953 0.49999999999974 0.50000000000006 0.50000000000001 0.5 0.5 0.49999999999995 0.50000000000008 0.50000000000071 0.49999999999656 0.49999999998895 0.50000000004864 0.49999999990507 0.49999999702752 0.49999994747561 0.4999991819682 0.49998896747007 0.49987441553891 0.49883319444726 0.49159137514643 0.44974309848155 0.35227207905521 0.24318828591858 0.19253917660707 0.14457807890984 0.12714492989045 0.12532101656176 0.12528782034923 0.12929122548213 0.16226606559862 0.26265281101334 0.42521402248841 0.64581563922014 0.89881681003781 0.95813339826424 0.93194671531341 0.83098159578098 0.64793036602569 0.58008743963247 0.52322077974482 0.50293258676757 0.50031877646233 0.50002798705534 0.50000207820764 0.5000001339255 0.50000000765918 0.50000000035742 0.49999999993248 0.50000000000381 0.50000000000687 0.49999999999953 0.49999999999974 0.50000000000006 0.50000000000001 0.5 0.5 0.49999999999995 0.50000000000008 0.50000000000071 0.49999999999656 0.49999999998895 0.50000000004864 0.49999999990507 0.49999999702752 0.49999994747561 0.4999991819682 0.49998896747007 0.49987441553891 0.49883319444726 0.49159137514643 0.44974309848158 0.35227207905515 0.2431882859189 0.19253917660748 0.14457807890926 0.12714492988987 0.12532101656653 0.12528782035591 0.12929122547147 0.16226606558118 0.26265281044289 0.42521401951289 0.64581563898527 0.8988168101072 0.95813339829039 0.93194671526046 0.83098159577182 0.64793036602165 0.5800874396251 0.52322077973761 0.50293258676738 0.50031877646251 0.50002798705531 0.50000207820763 0.50000013392549 0.50000000765918 0.50000000035741 0.49999999993248 0.50000000000381 0.50000000000687 0.49999999999953 0.49999999999974 0.50000000000006 0.50000000000001 0.5 0.5 0.49999999999995 0.50000000000008 0.50000000000071 0.49999999999656 0.49999999998895 0.50000000004864 0.49999999990507 0.49999999702752 0.49999994747561 0.4999991819682 0.49998896747006 0.49987441553891 0.49883319444726 0.49159137514643 0.44974309848157 0.35227207905518 0.24318828591897 0.19253917660721 0.14457807890939 0.12714492989015 0.12532101656643 0.12528782035683 0.12929122547815 0.16226606558202 0.26265281047033 0.42521401936096 0.64581563905808 0.89881681012294 0.95813339828026 0.93194671527047 0.8309815957819 0.64793036601878 0.58008743962088 0.52322077973717 0.50293258676759 0.50031877646248 0.50002798705531 0.50000207820763 0.5000001339255 0.50000000765918 0.50000000035742 0.49999999993248 0.50000000000381 0.50000000000687 0.49999999999953 0.49999999999974 0.50000000000006 0.50000000000001 0.5 0.5 0.49999999999995 0.50000000000008 0.50000000000071 0.49999999999656 0.49999999998895 0.50000000004864 0.49999999990507 0.49999999702752 0.49999994747561 0.4999991819682 0.49998896747007 0.49987441553891 0.49883319444726 0.49159137514643 0.44974309848157 0.35227207905518 0.24318828591894 0.19253917660722 0.14457807890941 0.12714492989014 0.12532101656625 0.12528782035647 0.12929122547844 0.16226606558585 0.26265281048224 0.42521401942114 0.64581563905256 0.89881681011369 0.95813339827911 0.93194671527363 0.83098159578204 0.64793036601905 0.58008743962146 0.52322077973749 0.50293258676757 0.50031877646248 0.50002798705531 0.50000207820764 0.50000013392549 0.50000000765918 0.50000000035742 0.49999999993248 0.50000000000381 0.50000000000687 0.49999999999953 0.49999999999974 0.50000000000006 0.50000000000001 0.5 0.5 0.49999999999995 0.50000000000008 0.50000000000071 0.49999999999656 0.49999999998895 0.50000000004864 0.49999999990507 0.49999999702752 0.49999994747561 0.4999991819682 0.49998896747006 0.49987441553891 0.49883319444726 0.49159137514643 0.44974309848157 0.35227207905518 0.24318828591894 0.19253917660723 0.1445780789094 0.12714492989013 0.12532101656628 0.12528782035647 0.12929122547809 0.16226606558521 0.26265281047589 0.42521401941394 0.64581563904741 0.89881681011313 0.95813339827959 0.93194671527295 0.83098159578154 0.64793036601915 0.58008743962161 0.52322077973747 0.50293258676756 0.50031877646248 0.50002798705531 0.50000207820763 0.50000013392549 0.50000000765918 0.50000000035741 0.49999999993248 0.50000000000381 0.50000000000687 0.49999999999953 0.49999999999974 0.50000000000006 0.50000000000001 0.5 0.5 0.49999999999995 0.50000000000008 0.50000000000071 0.49999999999656 0.49999999998895 0.50000000004864 0.49999999990507 0.49999999702752 0.49999994747561 0.4999991819682 0.49998896747006 0.49987441553891 0.49883319444726 0.49159137514643 0.44974309848157 0.35227207905518 0.24318828591894 0.19253917660723 0.1445780789094 0.12714492989013 0.12532101656629 0.12528782035649 0.12929122547812 0.16226606558513 0.26265281047533 0.42521401940981 0.64581563904791 0.89881681011354 0.95813339827958 0.93194671527288 0.83098159578159 0.64793036601913 0.58008743962156 0.52322077973746 0.50293258676757 0.50031877646248 0.50002798705531 0.50000207820763 0.5000001339255 0.50000000765918 0.50000000035742 0.49999999993248 0.50000000000381 0.50000000000687 0.49999999999953 0.49999999999974 0.50000000000006 0.50000000000001 0.5 0.5 0.49999999999995 0.50000000000008 0.50000000000071 0.49999999999656 0.49999999998895 0.50000000004864 0.49999999990507 0.49999999702752 0.49999994747561 0.4999991819682 0.49998896747007 0.49987441553891 0.49883319444726 0.49159137514643 0.44974309848157 0.35227207905518 0.24318828591894 0.19253917660723 0.1445780789094 0.12714492989013 0.12532101656629 0.12528782035649 0.12929122547814 0.16226606558518 0.26265281047565 0.42521401941042 0.64581563904809 0.89881681011352 0.95813339827956 0.93194671527293 0.83098159578161 0.64793036601913 0.58008743962156 0.52322077973746 0.50293258676757 0.50031877646248 0.50002798705531 0.50000207820763 0.50000013392549 0.50000000765918 0.50000000035742 0.49999999993248 0.50000000000381 0.50000000000687 0.49999999999953 0.49999999999974 0.50000000000006 0.50000000000001 0.5 0.5 0.49999999999995 0.50000000000008 0.50000000000071 0.49999999999656 0.49999999998895 0.50000000004864 0.49999999990507 0.49999999702752 0.49999994747561 0.4999991819682 0.49998896747007 0.49987441553891 0.49883319444727 0.49159137514643 0.44974309848157 0.35227207905518 0.24318828591894 0.19253917660723 0.1445780789094 0.12714492989013 0.12532101656629 0.12528782035649 0.12929122547813 0.16226606558518 0.26265281047564 0.42521401941054 0.64581563904804 0.8988168101135 0.95813339827956 0.93194671527293 0.83098159578161 0.64793036601913 0.58008743962156 0.52322077973746 0.50293258676757 0.50031877646248 0.50002798705531 0.50000207820763 0.5000001339255 0.50000000765918 0.50000000035741 0.49999999993248 0.50000000000381 0.50000000000687 0.49999999999953 0.49999999999974 0.50000000000006 0.50000000000001 0.5 0.5 0.49999999999995 0.50000000000008 0.50000000000071 0.49999999999656 0.49999999998895 0.50000000004864 0.49999999990507 0.49999999702752 0.49999994747561 0.4999991819682 0.49998896747006 0.49987441553891 0.49883319444726 0.49159137514643 0.44974309848157 0.35227207905518 0.24318828591894 0.19253917660723 0.1445780789094 0.12714492989013 0.12532101656629 0.12528782035649 0.12929122547813 0.16226606558518 0.26265281047562 0.42521401941049 0.64581563904804 0.8988168101135 0.95813339827957 0.93194671527292 0.83098159578161 0.64793036601913 0.58008743962156 0.52322077973746 0.50293258676757 0.50031877646248 0.50002798705531 0.50000207820763 0.5000001339255 0.50000000765918 0.50000000035742 0.49999999993248 0.50000000000381 0.50000000000687 0.49999999999953 0.49999999999974 0.50000000000006 0.50000000000001 0.5 0.5 0.49999999999995 0.50000000000008 0.50000000000071 0.49999999999656 0.49999999998895 0.50000000004864 0.49999999990507 0.49999999702752 0.49999994747561 0.4999991819682 0.49998896747007 0.49987441553891 0.49883319444726 0.49159137514643 0.44974309848157 0.35227207905518 0.24318828591894 0.19253917660723 0.1445780789094 0.12714492989013 0.12532101656629 0.12528782035649 0.12929122547813 0.16226606558518 0.26265281047563 0.42521401941049 0.64581563904804 0.8988168101135 0.95813339827957 0.93194671527292 0.83098159578161 0.64793036601913 0.58008743962156 0.52322077973746 0.50293258676757 0.50031877646248 0.50002798705531 0.50000207820763 0.50000013392549 0.50000000765918 0.50000000035742 0.49999999993248 0.50000000000381 0.50000000000687 0.49999999999953 0.49999999999974 0.50000000000006 0.50000000000001 0.5 0.5 0.49999999999995 0.50000000000008 0.50000000000071 0.49999999999656 0.49999999998895 0.50000000004864 0.49999999990507 0.49999999702752 0.49999994747561 0.4999991819682 0.49998896747006 0.49987441553891 0.49883319444726 0.49159137514643 0.44974309848157 0.35227207905518 0.24318828591894 0.19253917660723 0.1445780789094 0.12714492989013 0.12532101656629 0.12528782035649 0.12929122547813 0.16226606558518 0.26265281047563 0.42521401941049 0.64581563904804 0.8988168101135 0.95813339827957 0.93194671527292 0.83098159578161 0.64793036601913 0.58008743962156 0.52322077973746 0.50293258676757 0.50031877646248 0.50002798705531 0.50000207820763 0.50000013392549 0.50000000765918 0.50000000035742 0.49999999993248 0.50000000000381 0.50000000000687 0.49999999999953 0.49999999999974 0.50000000000006 0.50000000000001 0.5 0.5 0.49999999999995 0.50000000000008 0.50000000000071 0.49999999999656 0.49999999998895 0.50000000004864 0.49999999990507 0.49999999702752 0.49999994747561 0.4999991819682 0.49998896747006 0.49987441553891 0.49883319444726 0.49159137514643 0.44974309848157 0.35227207905518 0.24318828591894 0.19253917660723 0.1445780789094 0.12714492989013 0.12532101656629 0.12528782035649 0.12929122547813 0.16226606558518 0.26265281047563 0.42521401941049 0.64581563904804 0.89881681011351 0.95813339827957 0.93194671527293 0.83098159578161 0.64793036601913 0.58008743962156 0.52322077973746 0.50293258676757 0.50031877646248 0.50002798705531 0.50000207820763 0.50000013392549 0.50000000765918 0.50000000035742 0.49999999993248 0.50000000000381 0.50000000000687 0.49999999999953 0.49999999999974 0.50000000000006 0.50000000000001 0.5 0.5 0.49999999999995 0.50000000000008 0.50000000000071 0.49999999999656 0.49999999998895 0.50000000004864 0.49999999990507 0.49999999702752 0.49999994747561 0.4999991819682 0.49998896747006 0.49987441553891 0.49883319444727 0.49159137514643 0.44974309848157 0.35227207905518 0.24318828591894 0.19253917660723 0.1445780789094 0.12714492989013 0.12532101656629 0.12528782035649 0.12929122547813 0.16226606558518 0.26265281047563 0.42521401941049 0.64581563904804 0.89881681011351 0.95813339827957 0.93194671527292 0.83098159578161 0.64793036601913 0.58008743962156 0.52322077973746 0.50293258676757 0.50031877646248 0.50002798705531 0.50000207820763 0.50000013392549 0.50000000765918 0.50000000035742 0.49999999993248 0.50000000000381 0.50000000000687 0.49999999999953 0.49999999999974 0.50000000000006 0.50000000000001 0.5 0.5 0.49999999999995 0.50000000000008 0.50000000000071 0.49999999999656 0.49999999998895 0.50000000004864 0.49999999990507 0.49999999702752 0.49999994747561 0.4999991819682 0.49998896747006 0.49987441553891 0.49883319444726 0.49159137514643 0.44974309848157 0.35227207905518 0.24318828591894 0.19253917660723 0.1445780789094 0.12714492989013 0.12532101656629 0.12528782035649 0.12929122547813 0.16226606558518 0.26265281047563 0.42521401941049 0.64581563904804 0.8988168101135 0.95813339827956 0.93194671527293 0.83098159578161 0.64793036601913 0.58008743962156 0.52322077973746 0.50293258676757 0.50031877646248 0.50002798705531 0.50000207820763 0.5000001339255 0.50000000765918 0.50000000035742 0.49999999993248 0.50000000000381 0.50000000000687 0.49999999999953 0.49999999999974 0.50000000000006 0.50000000000001 0.5 0.5 0.49999999999995 0.50000000000008 0.50000000000071 0.49999999999656 0.49999999998895 0.50000000004864 0.49999999990507 0.49999999702752 0.49999994747561 0.4999991819682 0.49998896747007 0.49987441553891 0.49883319444726 0.49159137514643 0.44974309848157 0.35227207905518 0.24318828591894 0.19253917660723 0.1445780789094 0.12714492989013 0.12532101656629 0.12528782035649 0.12929122547813 0.16226606558518 0.26265281047563 0.42521401941049 0.64581563904804 0.8988168101135 0.95813339827956 0.93194671527292 0.83098159578161 0.64793036601913 0.58008743962156 0.52322077973746 0.50293258676757 0.50031877646248 0.50002798705531 0.50000207820763 0.5000001339255 0.50000000765918 0.50000000035742 0.49999999993248 0.50000000000381 0.50000000000687 0.49999999999953 0.49999999999974 0.50000000000006 0.50000000000001 0.5 0.5 0.49999999999995 0.50000000000008 0.50000000000071 0.49999999999656 0.49999999998895 0.50000000004864 0.49999999990507 0.49999999702752 0.49999994747561 0.4999991819682 0.49998896747007 0.49987441553891 0.49883319444726 0.49159137514643 0.44974309848157 0.35227207905518 0.24318828591894 0.19253917660723 0.1445780789094 0.12714492989013 0.12532101656629 0.12528782035649 0.12929122547813 0.16226606558518 0.26265281047563 0.42521401941049 0.64581563904804 0.8988168101135 0.95813339827957 0.93194671527292 0.83098159578161 0.64793036601913 0.58008743962156 0.52322077973746 0.50293258676757 0.50031877646248 0.50002798705531 0.50000207820763 0.50000013392549 0.50000000765918 0.50000000035742 0.49999999993248 0.50000000000381 0.50000000000687 0.49999999999953 0.49999999999974 0.50000000000006 0.50000000000001 0.5 0.5 0.49999999999995 0.50000000000008 0.50000000000071 0.49999999999656 0.49999999998895 0.50000000004864 0.49999999990507 0.49999999702752 0.49999994747561 0.4999991819682 0.49998896747007 0.49987441553891 0.49883319444726 0.49159137514643 0.44974309848157 0.35227207905518 0.24318828591894 0.19253917660723 0.1445780789094 0.12714492989013 0.12532101656629 0.12528782035649 0.12929122547813 0.16226606558518 0.26265281047563 0.42521401941049 0.64581563904804 0.8988168101135 0.95813339827956 0.93194671527293 0.83098159578161 0.64793036601913 0.58008743962156 0.52322077973746 0.50293258676757 0.50031877646248 0.50002798705531 0.50000207820763 0.50000013392549 0.50000000765918 0.50000000035742 0.49999999993248 0.50000000000381 0.50000000000687 0.49999999999953 0.49999999999974 0.50000000000006 0.50000000000001 0.5 0.5 0.49999999999995 0.50000000000008 0.50000000000071 0.49999999999656 0.49999999998895 0.50000000004864 0.49999999990507 0.49999999702752 0.49999994747561 0.4999991819682 0.49998896747007 0.49987441553891 0.49883319444726 0.49159137514643 0.44974309848157 0.35227207905518 0.24318828591894 0.19253917660723 0.1445780789094 0.12714492989013 0.12532101656629 0.12528782035649 0.12929122547813 0.16226606558518 0.26265281047562 0.4252140194105 0.64581563904809 0.89881681011353 0.95813339827956 0.93194671527293 0.83098159578161 0.64793036601912 0.58008743962156 0.52322077973746 0.50293258676757 0.50031877646248 0.50002798705531 0.50000207820763 0.5000001339255 0.50000000765918 0.50000000035742 0.49999999993248 0.50000000000381 0.50000000000687 0.49999999999953 0.49999999999974 0.50000000000006 0.50000000000001 0.5 0.5 0.49999999999995 0.50000000000008 0.50000000000071 0.49999999999656 0.49999999998895 0.50000000004864 0.49999999990507 0.49999999702752 0.49999994747561 0.4999991819682 0.49998896747006 0.49987441553891 0.49883319444726 0.49159137514643 0.44974309848157 0.35227207905518 0.24318828591894 0.19253917660723 0.1445780789094 0.12714492989013 0.12532101656629 0.12528782035649 0.12929122547813 0.16226606558518 0.26265281047564 0.42521401941055 0.64581563904789 0.89881681011355 0.9581333982796 0.93194671527289 0.8309815957816 0.64793036601914 0.58008743962156 0.52322077973746 0.50293258676757 0.50031877646248 0.50002798705531 0.50000207820763 0.50000013392549 0.50000000765918 0.50000000035742 0.49999999993248 0.50000000000381 0.50000000000687 0.49999999999953 0.49999999999974 0.50000000000006 0.50000000000001 0.5 0.5 0.49999999999995 0.50000000000008 0.50000000000071 0.49999999999656 0.49999999998895 0.50000000004864 0.49999999990507 0.49999999702752 0.49999994747561 0.4999991819682 0.49998896747007 0.49987441553891 0.49883319444726 0.49159137514643 0.44974309848157 0.35227207905518 0.24318828591894 0.19253917660723 0.1445780789094 0.12714492989013 0.12532101656629 0.12528782035649 0.12929122547813 0.16226606558519 0.26265281047565 0.42521401941038 0.6458156390474 0.89881681011299 0.95813339827959 0.93194671527294 0.8309815957816 0.64793036601917 0.58008743962161 0.52322077973747 0.50293258676756 0.50031877646248 0.50002798705531 0.50000207820763 0.50000013392549 0.50000000765918 0.50000000035742 0.49999999993248 0.50000000000381 0.50000000000687 0.49999999999953 0.49999999999974 0.50000000000006 0.50000000000001 0.5 0.5 0.49999999999995 0.50000000000008 0.50000000000071 0.49999999999656 0.49999999998895 0.50000000004864 0.49999999990507 0.49999999702752 0.49999994747561 0.4999991819682 0.49998896747007 0.49987441553891 0.49883319444726 0.49159137514643 0.44974309848157 0.35227207905518 0.24318828591894 0.19253917660723 0.1445780789094 0.12714492989013 0.12532101656629 0.12528782035649 0.12929122547814 0.16226606558514 0.26265281047528 0.42521401940981 0.64581563905318 0.89881681011396 0.95813339827885 0.93194671527355 0.8309815957817 0.64793036601888 0.58008743962149 0.5232207797375 0.50293258676757 0.50031877646248 0.50002798705531 0.50000207820764 0.5000001339255 0.50000000765918 0.50000000035742 0.49999999993248 0.50000000000381 0.50000000000687 0.49999999999953 0.49999999999974 0.50000000000006 0.50000000000001 0.5 0.5 0.49999999999995 0.50000000000008 0.50000000000071 0.49999999999656 0.49999999998895 0.50000000004864 0.49999999990507 0.49999999702752 0.49999994747561 0.4999991819682 0.49998896747007 0.49987441553891 0.49883319444726 0.49159137514643 0.44974309848157 0.35227207905518 0.24318828591894 0.19253917660723 0.1445780789094 0.12714492989013 0.12532101656629 0.1252878203565 0.12929122547815 0.16226606558512 0.26265281047612 0.42521401941458 0.6458156390577 0.89881681012501 0.95813339828114 0.93194671527099 0.83098159578166 0.64793036601893 0.58008743962081 0.52322077973724 0.5029325867676 0.50031877646248 0.50002798705531 0.50000207820763 0.50000013392549 0.50000000765918 0.50000000035742 0.49999999993248 0.50000000000381 0.50000000000687 0.49999999999953 0.49999999999974 0.50000000000006 0.50000000000001 0.5 0.5 0.49999999999995 0.50000000000008 0.50000000000071 0.49999999999656 0.49999999998895 0.50000000004864 0.49999999990507 0.49999999702752 0.49999994747561 0.4999991819682 0.49998896747006 0.49987441553891 0.49883319444726 0.49159137514643 0.44974309848157 0.35227207905518 0.24318828591894 0.19253917660724 0.1445780789094 0.12714492989013 0.12532101656628 0.12528782035651 0.12929122547805 0.16226606558611 0.26265281048313 0.42521401942061 0.64581563897975 0.89881681010013 0.95813339829339 0.93194671526133 0.83098159577934 0.64793036602498 0.58008743962456 0.52322077973719 0.50293258676743 0.50031877646251 0.50002798705531 0.50000207820763 0.50000013392549 0.50000000765918 0.50000000035742 0.49999999993248 0.50000000000381 0.50000000000687 0.49999999999953 0.49999999999974 0.50000000000006 0.50000000000001 0.5 0.5 0.49999999999995 0.50000000000008 0.50000000000071 0.49999999999656 0.49999999998895 0.50000000004864 0.49999999990507 0.49999999702752 0.49999994747561 0.4999991819682 0.49998896747007 0.49987441553891 0.49883319444726 0.49159137514643 0.44974309848157 0.35227207905518 0.24318828591894 0.19253917660724 0.14457807890943 0.12714492989014 0.12532101656633 0.12528782035635 0.12929122547817 0.16226606558399 0.26265281046555 0.42521401935595 0.64581563926021 0.8988168100509 0.9581333982502 0.93194671530612 0.8309815957792 0.64793036602214 0.58008743963376 0.52322077974327 0.50293258676733 0.50031877646236 0.50002798705534 0.50000207820764 0.50000013392549 0.50000000765918 0.50000000035742 0.49999999993248 0.50000000000381 0.50000000000687 0.49999999999953 0.49999999999974 0.50000000000006 0.50000000000001 0.5 0.5 0.49999999999995 0.50000000000008 0.50000000000071 0.49999999999656 0.49999999998895 0.50000000004864 0.49999999990507 0.49999999702752 0.49999994747561 0.4999991819682 0.49998896747006 0.49987441553891 0.49883319444726 0.49159137514643 0.44974309848158 0.35227207905518 0.24318828591896 0.19253917660719 0.1445780789093 0.12714492989008 0.12532101656648 0.12528782035654 0.1292912254797 0.16226606557506 0.26265281045356 0.42521401954521 0.64581564405577 0.89881681128742 0.95813339826466 0.93194671528192 0.83098159582031 0.64793036596011 0.58008743957913 0.5232207797417 0.50293258677247 0.50031877646225 0.50002798705522 0.50000207820765 0.5000001339255 0.50000000765918 0.50000000035742 0.49999999993248 0.50000000000381 0.50000000000687 0.49999999999953 0.49999999999974 0.50000000000006 0.50000000000001 0.5 0.5 0.49999999999995 0.50000000000008 0.50000000000071 0.49999999999656 0.49999999998895 0.50000000004864 0.49999999990507 0.49999999702752 0.49999994747561 0.4999991819682 0.49998896747007 0.49987441553891 0.49883319444726 0.49159137514643 0.44974309848159 0.35227207905516 0.24318828591884 0.19253917660728 0.14457807890924 0.12714492988988 0.12532101656446 0.12528782035818 0.12929122547607 0.16226606561439 0.26265281122408 0.42521402299545 0.64581572912781 0.89881683111679 0.95813340039494 0.93194671359772 0.83098159564867 0.64793036631119 0.58008743964621 0.52322077967469 0.5029325867714 0.5003187764673 0.50002798705508 0.50000207820758 0.50000013392549 0.50000000765918 0.50000000035742 0.49999999993248 0.50000000000381 0.50000000000687 0.49999999999953 0.49999999999974 0.50000000000006 0.50000000000001 0.5 0.5 0.49999999999995 0.50000000000008 0.50000000000071 0.49999999999656 0.49999999998895 0.50000000004864 0.49999999990507 0.49999999702752 0.49999994747561 0.4999991819682 0.49998896747007 0.49987441553891 0.49883319444726 0.49159137514642 0.44974309848145 0.35227207905538 0.24318828591905 0.19253917660732 0.14457807891331 0.12714492989295 0.12532101656264 0.12528782035508 0.12929122548272 0.16226606562178 0.26265282429878 0.42521408199435 0.64581708335391 0.89881714539825 0.95813343372903 0.93194668806982 0.8309815916026 0.64793037011579 0.58008744158368 0.52322078005411 0.50293258671921 0.5003187764662 0.50002798705922 0.50000207820752 0.50000013392546 0.50000000765918 0.50000000035742 0.49999999993248 0.50000000000381 0.50000000000687 0.49999999999953 0.49999999999974 0.50000000000006 0.50000000000001 0.5 0.5 0.49999999999995 0.50000000000008 0.50000000000071 0.49999999999656 0.49999999998895 0.50000000004864 0.49999999990507 0.49999999702752 0.49999994747561 0.4999991819682 0.49998896747006 0.49987441553891 0.49883319444726 0.49159137514638 0.44974309848149 0.35227207905544 0.24318828592318 0.192539176605 0.14457807890825 0.1271449298895 0.1253210165923 0.125287820369 0.12929122536562 0.16226606236185 0.26265300736533 0.42521497358829 0.64583564609176 0.89882145542624 0.9581339343715 0.93194630231941 0.8309815066722 0.64793041429112 0.5800874708955 0.52322078668228 0.502932587175 0.50031877642303 0.50002798706108 0.50000207821031 0.50000013392561 0.50000000765918 0.50000000035742 0.49999999993248 0.50000000000381 0.50000000000687 0.49999999999953 0.49999999999974 0.50000000000006 0.50000000000001 0.5 0.5 0.49999999999995 0.50000000000008 0.50000000000071 0.49999999999656 0.49999999998895 0.50000000004864 0.49999999990507 0.49999999702752 0.49999994747561 0.4999991819682 0.49998896747006 0.49987441553891 0.49883319444729 0.49159137514681 0.44974309848455 0.35227207905104 0.24318828591146 0.1925391766248 0.14457807889435 0.12714492985949 0.12532101645785 0.12528782031931 0.12929121848012 0.16226596158909 0.26265516194965 0.42522643403742 0.64604871756586 0.89887108067992 0.95814036798455 0.93194122965886 0.83098004793425 0.64793079672699 0.58008787033119 0.52322089264406 0.50293259478219 0.50031877693935 0.50002798702813 0.50000207821346 0.5000001339268 0.50000000765928 0.50000000035742 0.49999999993248 0.50000000000381 0.50000000000687 0.49999999999953 0.49999999999974 0.50000000000006 0.50000000000001 0.5 0.5 0.49999999999995 0.50000000000008 0.50000000000071 0.49999999999656 0.49999999998895 0.50000000004864 0.49999999990507 0.49999999702752 0.49999994747561 0.4999991819682 0.49998896747007 0.49987441553892 0.49883319444738 0.49159137514761 0.44974309848265 0.35227207906292 0.24318828589025 0.19253917655369 0.14457807939102 0.12714493026704 0.12532101174067 0.12528781518775 0.12929104746187 0.16226386964688 0.26267602795445 0.4253478555662 0.64800804544877 0.89933033928241 0.95820906500162 0.93188432436671 0.83095995021693 0.64793213079836 0.5800923147781 0.52322231244399 0.50293270440187 0.50031878484456 0.50002798748851 0.50000207819635 0.50000013392633 0.50000000765939 0.50000000035743 0.49999999993247 0.50000000000381 0.50000000000687 0.49999999999953 0.49999999999974 0.50000000000006 0.50000000000001 0.5 0.5 0.49999999999995 0.50000000000008 0.50000000000071 0.49999999999656 0.49999999998895 0.50000000004864 0.49999999990507 0.49999999702752 0.49999994747561 0.4999991819682 0.49998896747006 0.49987441553887 0.49883319444655 0.49159137513842 0.4497430984429 0.35227207919758 0.24318828635193 0.19253917445714 0.144578091314 0.12714494464614 0.12532090599103 0.12528768646305 0.12928782670337 0.16222798618242 0.26279596844584 0.42639538550033 0.66243669103741 0.90270779480151 0.95881580985625 0.93135560847753 0.83074245496204 0.64791903377314 0.58013194902955 0.52323746233688 0.50293399092472 0.50031888382452 0.50002799399973 0.50000207849688 0.50000013392212 0.50000000765793 0.50000000035736 0.49999999993249 0.50000000000381 0.50000000000686 0.49999999999953 0.49999999999974 0.50000000000006 0.50000000000001 0.5 0.5 0.49999999999995 0.50000000000008 0.50000000000071 0.49999999999656 0.49999999998895 0.50000000004864 0.49999999990507 0.49999999702752 0.49999994747561 0.4999991819682 0.49998896747006 0.49987441553881 0.49883319444676 0.49159137516825 0.44974309890148 0.35227208087812 0.24318829424258 0.19253913377802 0.14457831322335 0.12714526141236 0.12531900814995 0.12528572857803 0.12924457150699 0.16177315998182 0.26303283669169 0.4320295738415 0.69944351525988 0.91417039137444 0.96164451802645 0.9272628844419 0.82896266025665 0.6475920208275 0.580346584557 0.52336623564712 0.5029461282133 0.50031988612531 0.50002806243348 0.50000208266363 0.50000013415124 0.50000000766575 0.50000000035749 0.49999999993251 0.50000000000381 0.50000000000686 0.49999999999953 0.49999999999974 0.50000000000006 0.50000000000001 0.5 0.5 0.49999999999995 0.50000000000008 0.50000000000071 0.49999999999656 0.49999999998895 0.50000000004864 0.49999999990507 0.49999999702752 0.49999994747561 0.4999991819682 0.49998896747011 0.49987441554007 0.49883319447167 0.49159137563868 0.44974310342903 0.35227209160809 0.243188346471 0.19253865823693 0.14458036723767 0.127148941201 0.12530467405266 0.12526839452641 0.12892015703488 0.15845359121489 0.26108187804229 0.437950602575 0.93152468465458 0.93685575343341 0.97912954148092 0.90919718044367 0.81629982931573 0.64582138862503 0.58048341734228 0.5238479424671 0.50299968343251 0.50032490764246 0.50002844168751 0.50000210678276 0.50000013557772 0.50000000775427 0.50000000036154 0.49999999993238 0.50000000000371 0.50000000000691 0.49999999999954 0.49999999999974 0.50000000000006 0.50000000000001 0.5 0.5 0.49999999999995 0.50000000000008 0.50000000000071 0.49999999999656 0.49999999998895 0.50000000004864 0.49999999990507 0.49999999702752 0.49999994747561 0.49999918196821 0.49998896747036 0.49987441554606 0.49883319460621 0.49159137906524 0.44974314095432 0.35227206821854 0.24318809932709 0.19253474001419 0.14459721655047 0.12718612607045 0.12518037458604 0.12519588403579 0.12667846688517 0.13432348229512 0.21584665419358 0.43373769670589 0.91579551807467 0.95933607855872 0.91819261163374 0.83287910037963 0.76060458296266 0.62317069292154 0.57731166901016 0.52503870644601 0.50316991742505 0.50034108613927 0.5000297633324 0.50000219708743 0.50000014087636 0.50000000805287 0.5000000003781 0.49999999993268 0.50000000000301 0.50000000000705 0.49999999999957 0.49999999999973 0.50000000000006 0.50000000000001 0.5 0.5 0.49999999999995 0.50000000000008 0.50000000000071 0.49999999999656 0.49999999998895 0.50000000004864 0.49999999990507 0.49999999702752 0.49999994747561 0.49999918196816 0.49998896746926 0.49987441552678 0.49883319431432 0.49159137492612 0.44974310284102 0.35227195103575 0.24318821454601 0.19253154256495 0.1445762222508 0.12719635835003 0.1252183525873 0.12502725326151 0.12569181656228 0.12822811959815 0.16387367153045 0.36971459560124 0.90454173001004 0.91052446036202 0.81500336565782 0.74711005087299 0.72810282119661 0.6068506649529 0.56335971445384 0.52009984915678 0.50256393183298 0.50028098391622 0.50002491147445 0.50000186466756 0.50000012093219 0.50000000697996 0.50000000032941 0.49999999993357 0.5000000000044 0.50000000000654 0.49999999999952 0.49999999999976 0.50000000000006 0.50000000000001 0.5 0.5 0.49999999999995 0.50000000000008 0.50000000000071 0.49999999999656 0.49999999998895 0.50000000004864 0.49999999990507 0.49999999702752 0.4999999474756 0.49999918196793 0.49998896746487 0.49987441545451 0.49883319330151 0.49159136225338 0.44974299184008 0.35227201982205 0.24318769404661 0.19253175583663 0.14455460298492 0.12721179734004 0.12520396822272 0.12508496901662 0.12504629487882 0.12518740197722 0.12818136174779 0.2701225797684 0.95074225606158 0.64546541848146 0.59687362292255 0.59975704168606 0.5864929739942 0.53637643546695 0.52463789671977 0.50658315152947 0.5008291618924 0.50009053060382 0.50000806786926 0.50000060945395 0.5000000399526 0.50000000225881 0.50000000004902 0.49999999996064 0.5000000000113 0.50000000000257 0.49999999999932 0.49999999999996 0.50000000000004 0.5 0.5 0.5 0.49999999999995 0.50000000000008 0.50000000000071 0.49999999999656 0.49999999998895 0.50000000004864 0.49999999990507 0.49999999702752 0.49999994747561 0.4999991819681 0.49998896746807 0.4998744155058 0.49883319399109 0.49159137027328 0.4497430570795 0.35227196069538 0.24318801407687 0.1925321912195 0.14456070518323 0.12720154742646 0.12520972990382 0.12517563703539 0.12534267218221 0.12636998770527 0.12531920820479 0.30067497364733 1.0 0.50299232060043 0.50720589621132 0.51693930773198 0.52370802558525 0.52395695923259 0.50920048522293 0.50212946103409 0.50025381073595 0.50002611224629 0.50000226004769 0.50000016830513 0.50000001095282 0.50000000056893 0.49999999992541 0.49999999999636 0.50000000001 0.4999999999999 0.49999999999952 0.50000000000007 0.50000000000002 0.49999999999999 0.5 0.5 0.49999999999995 0.50000000000008 0.50000000000071 0.49999999999656 0.49999999998895 0.50000000004864 0.49999999990507 0.49999999702752 0.49999994747562 0.49999918196827 0.49998896747157 0.4998744155681 0.4988331949447 0.49159138380126 0.44974318397366 0.35227191650083 0.24318839508791 0.19253187920075 0.14459249934973 0.12719883585912 0.12517908985555 0.125170110401 0.1267525680515 0.14267696007156 0.16761189234405 0.125 +D/cons.1.00.000050.dat 1.0 0.51043075105762 0.50914843433861 0.53746937852237 0.5744039135955 0.53073582667354 0.51427650265833 0.50282160533058 0.50036941362314 0.50003958288045 0.50000349200902 0.50000026142309 0.50000001696457 0.5000000009121 0.49999999995051 0.49999999998516 0.50000000001107 0.5000000000006 0.49999999999942 0.50000000000004 0.50000000000003 0.49999999999999 0.5 0.5 0.49999999999995 0.50000000000008 0.50000000000071 0.49999999999656 0.49999999998895 0.50000000004864 0.49999999990507 0.49999999702752 0.49999994747562 0.49999918196833 0.49998896747283 0.49987441558983 0.49883319525548 0.49159138747038 0.44974321494722 0.3522719055169 0.24318851988032 0.19253161327859 0.14459194079761 0.12719698366321 0.12518126590012 0.12517077995377 0.12659327448592 0.14270539315164 0.16678116200749 0.125 0.95072868983487 0.64523183514755 0.59353413125036 0.59356348142983 0.58679015645055 0.54376288449459 0.52614369728682 0.50683415528736 0.5008723767016 0.50009650657605 0.50000867334875 0.50000065829167 0.50000004309271 0.50000000242627 0.50000000005926 0.49999999995823 0.50000000001132 0.50000000000277 0.49999999999931 0.49999999999995 0.50000000000005 0.5 0.5 0.5 0.49999999999995 0.50000000000008 0.50000000000071 0.49999999999656 0.49999999998895 0.50000000004864 0.49999999990507 0.49999999702752 0.49999994747562 0.49999918196835 0.49998896747309 0.49987441559026 0.49883319517623 0.4915913843737 0.44974317864824 0.35227189657132 0.24318846783252 0.19253174817458 0.14456682311491 0.12719144580763 0.1252111392919 0.12515623400709 0.1253461026974 0.12636488538847 0.12531596741075 0.30064797256645 0.9044527213652 0.91021685285956 0.81240500885839 0.73664088064436 0.7130822256633 0.5996328228091 0.5616129982527 0.52041482966071 0.50259291929662 0.50028127248097 0.50002479188194 0.50000184736327 0.50000011945464 0.50000000688777 0.50000000032344 0.49999999993363 0.50000000000465 0.50000000000649 0.49999999999951 0.49999999999976 0.50000000000006 0.50000000000001 0.5 0.5 0.49999999999995 0.50000000000008 0.50000000000071 0.49999999999656 0.49999999998895 0.50000000004864 0.49999999990507 0.49999999702752 0.49999994747563 0.49999918196849 0.49998896747589 0.49987441564026 0.49883319593146 0.49159139428891 0.44974326554532 0.35227173157218 0.24318902382593 0.19253028932223 0.1445749690617 0.12717535707629 0.12521075356276 0.1249727562415 0.12500325709618 0.12517487790483 0.12815422051682 0.27006982020504 0.91536466912977 0.95885698669035 0.91724697743707 0.82776067002862 0.75005552208988 0.61674551508496 0.57472798669626 0.52470706264064 0.50314282861692 0.50033856574943 0.50002958462135 0.50000218577744 0.50000014023644 0.50000000801864 0.50000000037658 0.49999999993268 0.50000000000305 0.50000000000703 0.49999999999957 0.49999999999973 0.50000000000006 0.50000000000001 0.5 0.5 0.49999999999995 0.50000000000008 0.50000000000071 0.49999999999656 0.49999999998895 0.50000000004864 0.49999999990507 0.49999999702752 0.49999994747562 0.49999918196831 0.49998896747228 0.49987441557977 0.49883319509652 0.49159138500342 0.44974319213186 0.35227189260898 0.24318858320468 0.19253002675269 0.14458095225109 0.12719220042869 0.1252088485695 0.12498453385354 0.12563284606598 0.12812609715842 0.16375946113618 0.36947600740272 0.93091870655547 0.93621890052843 0.97806892915767 0.90819897394461 0.81358274232151 0.64392377409552 0.58001564091531 0.52380459983127 0.50299650490622 0.50032466523703 0.50002842526043 0.5000021056931 0.50000013550933 0.50000000775096 0.50000000036144 0.49999999993238 0.50000000000371 0.50000000000691 0.49999999999954 0.49999999999974 0.50000000000006 0.50000000000001 0.5 0.5 0.49999999999995 0.50000000000008 0.50000000000071 0.49999999999656 0.49999999998895 0.50000000004864 0.49999999990507 0.49999999702752 0.49999994747562 0.49999918196824 0.49998896747095 0.49987441555582 0.49883319474484 0.4915913809069 0.44974315768844 0.35227203123439 0.24318815022442 0.19253336010566 0.14459540418593 0.12719093639369 0.12517012402885 0.12518305049218 0.12657859586128 0.13415897906839 0.21565242354672 0.43341479311069 0.69913808216375 0.91361700123503 0.96113677438347 0.92658816798526 0.82851953009158 0.64734337737922 0.58028428996242 0.5233732616337 0.50294710697412 0.50031998260471 0.50002806925502 0.50000208304166 0.50000013417287 0.50000000766706 0.50000000035755 0.4999999999325 0.50000000000381 0.50000000000686 0.49999999999953 0.49999999999974 0.50000000000006 0.50000000000001 0.5 0.5 0.49999999999995 0.50000000000008 0.50000000000071 0.49999999999656 0.49999999998895 0.50000000004864 0.49999999990507 0.49999999702752 0.49999994747561 0.49999918196821 0.49998896747019 0.49987441554143 0.49883319449343 0.49159137603035 0.44974310790739 0.35227207914048 0.24318836578862 0.19253826810679 0.14457994507651 0.12714914051218 0.12530119841691 0.12526079966909 0.12885461661009 0.15833911718006 0.26084863231669 0.43762218789982 0.66201542568464 0.90227112800171 0.95869742954856 0.93121772526239 0.83068243279126 0.64788364030861 0.58013401958186 0.52324036329357 0.50293427188016 0.50031890626997 0.50002799543155 0.50000207857389 0.50000013392672 0.5000000076581 0.50000000035736 0.49999999993249 0.50000000000381 0.50000000000686 0.49999999999953 0.49999999999974 0.50000000000006 0.50000000000001 0.5 0.5 0.49999999999995 0.50000000000008 0.50000000000071 0.49999999999656 0.49999999998895 0.50000000004864 0.49999999990507 0.49999999702752 0.49999994747561 0.4999991819682 0.49998896747007 0.4998744155391 0.49883319445095 0.49159137521548 0.44974309932632 0.35227207875513 0.24318830151111 0.19253907653494 0.14457831115001 0.1271452803891 0.12531827312689 0.12528426187233 0.12922865110337 0.16172520965872 0.26285087835962 0.43177093848594 0.64792300677814 0.89925805736421 0.95819268487764 0.93186551978377 0.83095222016131 0.64792791914122 0.58009261509855 0.52322272639417 0.5029327408517 0.50031878754836 0.50002798765007 0.50000207820522 0.50000013392635 0.50000000765937 0.50000000035743 0.49999999993247 0.50000000000381 0.50000000000687 0.49999999999953 0.49999999999974 0.50000000000006 0.50000000000001 0.5 0.5 0.49999999999995 0.50000000000008 0.50000000000071 0.49999999999656 0.49999999998895 0.50000000004864 0.49999999990507 0.49999999702752 0.49999994747561 0.4999991819682 0.49998896747006 0.49987441553889 0.49883319444709 0.49159137514514 0.44974309848471 0.35227207913939 0.24318828694933 0.19253916825366 0.14457809153956 0.12714495078432 0.12532084188047 0.12528750383345 0.12928580849733 0.16221935797328 0.26275511477986 0.42632662021231 0.64603571098897 0.89886185564412 0.95813856776999 0.93193933279498 0.83097921766108 0.64793035419377 0.58008792114178 0.52322093681094 0.50293259832332 0.50031877718442 0.50002798703831 0.50000207821305 0.50000013392672 0.50000000765928 0.50000000035742 0.49999999993248 0.50000000000381 0.50000000000687 0.49999999999953 0.49999999999974 0.50000000000006 0.50000000000001 0.5 0.5 0.49999999999995 0.50000000000008 0.50000000000071 0.49999999999656 0.49999999998895 0.50000000004864 0.49999999990507 0.49999999702752 0.49999994747561 0.4999991819682 0.49998896747007 0.49987441553892 0.4988331944474 0.4915913751479 0.44974309847869 0.35227207909579 0.24318828593133 0.19253917608077 0.14457807946903 0.12714493097836 0.12532100681458 0.12528779751537 0.12929083908667 0.16226267959637 0.26266889826383 0.42533820630149 0.64583416594091 0.89882053956282 0.95813377614523 0.93194615102478 0.83098143283325 0.64793037876647 0.58008747623764 0.52322079041351 0.50293258745546 0.50031877643547 0.5000279870597 0.50000207821034 0.50000013392563 0.50000000765918 0.50000000035742 0.49999999993248 0.50000000000381 0.50000000000687 0.49999999999953 0.49999999999974 0.50000000000006 0.50000000000001 0.5 0.5 0.49999999999995 0.50000000000008 0.50000000000071 0.49999999999656 0.49999999998895 0.50000000004864 0.49999999990507 0.49999999702752 0.49999994747561 0.4999991819682 0.49998896747007 0.49987441553891 0.49883319444731 0.49159137514701 0.44974309848663 0.35227207904895 0.24318828589761 0.19253917662956 0.1445780788912 0.12714492989989 0.12532101619908 0.12528781910179 0.12929120247843 0.16226585772629 0.26265453436891 0.42522533106949 0.64581694981204 0.89881707039178 0.95813342216666 0.93194667819156 0.83098158599631 0.64793036764791 0.58008744200679 0.52322078033073 0.50293258673082 0.50031877646286 0.50002798705959 0.50000207820759 0.50000013392546 0.50000000765918 0.50000000035742 0.49999999993248 0.50000000000381 0.50000000000687 0.49999999999953 0.49999999999974 0.50000000000006 0.50000000000001 0.5 0.5 0.49999999999995 0.50000000000008 0.50000000000071 0.49999999999656 0.49999999998895 0.50000000004864 0.49999999990507 0.49999999702752 0.49999994747561 0.4999991819682 0.49998896747007 0.49987441553891 0.49883319444727 0.49159137514648 0.44974309848241 0.35227207905328 0.24318828592603 0.19253917661131 0.14457807890173 0.12714492988404 0.12532101659656 0.12528782035558 0.12929122441469 0.16226605467472 0.26265295691472 0.42521487205589 0.64581571913867 0.89881682589216 0.95813339966458 0.93194671306744 0.83098159524344 0.64793036608468 0.58008743968831 0.52322077968271 0.50293258676648 0.50031877646808 0.5000279870552 0.50000207820758 0.50000013392549 0.50000000765918 0.50000000035742 0.49999999993248 0.50000000000381 0.50000000000687 0.49999999999953 0.49999999999974 0.50000000000006 0.50000000000001 0.5 0.5 0.49999999999995 0.50000000000008 0.50000000000071 0.49999999999656 0.49999999998895 0.50000000004864 0.49999999990507 0.49999999702752 0.49999994747561 0.4999991819682 0.49998896747006 0.49987441553891 0.49883319444726 0.49159137514642 0.44974309848143 0.35227207905569 0.24318828592061 0.19253917660145 0.1445780789133 0.12714492989587 0.12532101656436 0.12528782036582 0.12929122548165 0.16226606518407 0.2626528207358 0.42521407426831 0.64581564340794 0.89881681096218 0.95813339822554 0.93194671524802 0.83098159588256 0.64793036598898 0.5800874395727 0.52322077973366 0.50293258677357 0.50031877646245 0.50002798705521 0.50000207820765 0.5000001339255 0.50000000765918 0.50000000035742 0.49999999993248 0.50000000000381 0.50000000000687 0.49999999999953 0.49999999999974 0.50000000000006 0.50000000000001 0.5 0.5 0.49999999999995 0.50000000000008 0.50000000000071 0.49999999999656 0.49999999998895 0.50000000004864 0.49999999990507 0.49999999702752 0.49999994747561 0.4999991819682 0.49998896747006 0.49987441553891 0.49883319444726 0.49159137514643 0.44974309848155 0.35227207905521 0.24318828591858 0.19253917660707 0.14457807890984 0.12714492989045 0.12532101656176 0.12528782034923 0.12929122548213 0.16226606559862 0.26265281101334 0.42521402248841 0.64581563922014 0.89881681003781 0.95813339826424 0.93194671531341 0.83098159578098 0.64793036602569 0.58008743963247 0.52322077974482 0.50293258676757 0.50031877646233 0.50002798705534 0.50000207820764 0.50000013392549 0.50000000765918 0.50000000035742 0.49999999993248 0.50000000000381 0.50000000000687 0.49999999999953 0.49999999999974 0.50000000000006 0.50000000000001 0.5 0.5 0.49999999999995 0.50000000000008 0.50000000000071 0.49999999999656 0.49999999998895 0.50000000004864 0.49999999990507 0.49999999702752 0.49999994747561 0.4999991819682 0.49998896747007 0.49987441553891 0.49883319444727 0.49159137514643 0.44974309848158 0.35227207905515 0.2431882859189 0.19253917660748 0.14457807890926 0.12714492988987 0.12532101656653 0.12528782035591 0.12929122547147 0.16226606558118 0.26265281044289 0.42521401951289 0.64581563898527 0.8988168101072 0.95813339829039 0.93194671526046 0.83098159577182 0.64793036602165 0.5800874396251 0.52322077973761 0.50293258676738 0.50031877646251 0.50002798705531 0.50000207820763 0.50000013392549 0.50000000765918 0.50000000035742 0.49999999993248 0.50000000000381 0.50000000000687 0.49999999999953 0.49999999999974 0.50000000000006 0.50000000000001 0.5 0.5 0.49999999999995 0.50000000000008 0.50000000000071 0.49999999999656 0.49999999998895 0.50000000004864 0.49999999990507 0.49999999702752 0.49999994747561 0.4999991819682 0.49998896747007 0.49987441553891 0.49883319444726 0.49159137514643 0.44974309848157 0.35227207905518 0.24318828591897 0.19253917660721 0.14457807890939 0.12714492989015 0.12532101656643 0.12528782035683 0.12929122547815 0.16226606558202 0.26265281047033 0.42521401936096 0.64581563905808 0.89881681012294 0.95813339828026 0.93194671527047 0.8309815957819 0.64793036601878 0.58008743962088 0.52322077973717 0.50293258676759 0.50031877646248 0.50002798705531 0.50000207820763 0.5000001339255 0.50000000765918 0.50000000035742 0.49999999993248 0.50000000000381 0.50000000000687 0.49999999999953 0.49999999999974 0.50000000000006 0.50000000000001 0.5 0.5 0.49999999999995 0.50000000000008 0.50000000000071 0.49999999999656 0.49999999998895 0.50000000004864 0.49999999990507 0.49999999702752 0.49999994747561 0.4999991819682 0.49998896747006 0.49987441553891 0.49883319444726 0.49159137514643 0.44974309848157 0.35227207905518 0.24318828591894 0.19253917660722 0.14457807890941 0.12714492989014 0.12532101656625 0.12528782035647 0.12929122547844 0.16226606558585 0.26265281048224 0.42521401942114 0.64581563905256 0.89881681011369 0.95813339827911 0.93194671527363 0.83098159578204 0.64793036601905 0.58008743962146 0.52322077973749 0.50293258676757 0.50031877646248 0.50002798705531 0.50000207820763 0.50000013392549 0.50000000765918 0.50000000035742 0.49999999993248 0.50000000000381 0.50000000000687 0.49999999999953 0.49999999999974 0.50000000000006 0.50000000000001 0.5 0.5 0.49999999999995 0.50000000000008 0.50000000000071 0.49999999999656 0.49999999998895 0.50000000004864 0.49999999990507 0.49999999702752 0.49999994747561 0.4999991819682 0.49998896747007 0.49987441553891 0.49883319444726 0.49159137514643 0.44974309848157 0.35227207905518 0.24318828591894 0.19253917660723 0.1445780789094 0.12714492989013 0.12532101656628 0.12528782035647 0.12929122547809 0.16226606558521 0.26265281047589 0.42521401941394 0.64581563904741 0.89881681011313 0.95813339827959 0.93194671527295 0.83098159578154 0.64793036601915 0.58008743962161 0.52322077973747 0.50293258676756 0.50031877646248 0.50002798705531 0.50000207820763 0.5000001339255 0.50000000765918 0.50000000035742 0.49999999993248 0.50000000000381 0.50000000000687 0.49999999999953 0.49999999999974 0.50000000000006 0.50000000000001 0.5 0.5 0.49999999999995 0.50000000000008 0.50000000000071 0.49999999999656 0.49999999998895 0.50000000004864 0.49999999990507 0.49999999702752 0.49999994747561 0.4999991819682 0.49998896747007 0.49987441553891 0.49883319444726 0.49159137514643 0.44974309848157 0.35227207905518 0.24318828591894 0.19253917660723 0.1445780789094 0.12714492989013 0.12532101656629 0.12528782035649 0.12929122547812 0.16226606558513 0.26265281047533 0.42521401940981 0.64581563904791 0.89881681011354 0.95813339827959 0.93194671527288 0.83098159578159 0.64793036601913 0.58008743962156 0.52322077973746 0.50293258676757 0.50031877646248 0.50002798705531 0.50000207820763 0.5000001339255 0.50000000765918 0.50000000035742 0.49999999993248 0.50000000000381 0.50000000000687 0.49999999999953 0.49999999999974 0.50000000000006 0.50000000000001 0.5 0.5 0.49999999999995 0.50000000000008 0.50000000000071 0.49999999999656 0.49999999998895 0.50000000004864 0.49999999990507 0.49999999702752 0.49999994747561 0.4999991819682 0.49998896747006 0.49987441553891 0.49883319444726 0.49159137514643 0.44974309848157 0.35227207905518 0.24318828591894 0.19253917660723 0.1445780789094 0.12714492989013 0.12532101656629 0.12528782035649 0.12929122547814 0.16226606558518 0.26265281047565 0.42521401941042 0.64581563904809 0.89881681011352 0.95813339827956 0.93194671527293 0.83098159578161 0.64793036601913 0.58008743962156 0.52322077973746 0.50293258676757 0.50031877646248 0.50002798705531 0.50000207820763 0.50000013392549 0.50000000765918 0.50000000035742 0.49999999993248 0.50000000000381 0.50000000000687 0.49999999999953 0.49999999999974 0.50000000000006 0.50000000000001 0.5 0.5 0.49999999999995 0.50000000000008 0.50000000000071 0.49999999999656 0.49999999998895 0.50000000004864 0.49999999990507 0.49999999702752 0.49999994747561 0.4999991819682 0.49998896747007 0.49987441553891 0.49883319444726 0.49159137514643 0.44974309848157 0.35227207905518 0.24318828591894 0.19253917660723 0.1445780789094 0.12714492989013 0.12532101656629 0.12528782035649 0.12929122547813 0.16226606558518 0.26265281047564 0.42521401941054 0.64581563904804 0.8988168101135 0.95813339827956 0.93194671527293 0.83098159578161 0.64793036601913 0.58008743962156 0.52322077973746 0.50293258676757 0.50031877646248 0.50002798705531 0.50000207820763 0.5000001339255 0.50000000765918 0.50000000035742 0.49999999993248 0.50000000000381 0.50000000000687 0.49999999999953 0.49999999999974 0.50000000000006 0.50000000000001 0.5 0.5 0.49999999999995 0.50000000000008 0.50000000000071 0.49999999999656 0.49999999998895 0.50000000004864 0.49999999990507 0.49999999702752 0.49999994747561 0.4999991819682 0.49998896747006 0.49987441553891 0.49883319444726 0.49159137514643 0.44974309848157 0.35227207905518 0.24318828591894 0.19253917660723 0.1445780789094 0.12714492989013 0.12532101656629 0.12528782035649 0.12929122547813 0.16226606558518 0.26265281047562 0.42521401941049 0.64581563904804 0.8988168101135 0.95813339827957 0.93194671527292 0.83098159578161 0.64793036601913 0.58008743962156 0.52322077973746 0.50293258676757 0.50031877646248 0.50002798705531 0.50000207820763 0.50000013392549 0.50000000765918 0.50000000035742 0.49999999993248 0.50000000000381 0.50000000000687 0.49999999999953 0.49999999999974 0.50000000000006 0.50000000000001 0.5 0.5 0.49999999999995 0.50000000000008 0.50000000000071 0.49999999999656 0.49999999998895 0.50000000004864 0.49999999990507 0.49999999702752 0.49999994747561 0.4999991819682 0.49998896747007 0.49987441553891 0.49883319444727 0.49159137514643 0.44974309848157 0.35227207905518 0.24318828591894 0.19253917660723 0.1445780789094 0.12714492989013 0.12532101656629 0.12528782035649 0.12929122547813 0.16226606558518 0.26265281047563 0.42521401941049 0.64581563904804 0.8988168101135 0.95813339827956 0.93194671527292 0.83098159578161 0.64793036601913 0.58008743962156 0.52322077973746 0.50293258676757 0.50031877646248 0.50002798705531 0.50000207820763 0.50000013392549 0.50000000765918 0.50000000035742 0.49999999993248 0.50000000000381 0.50000000000687 0.49999999999953 0.49999999999974 0.50000000000006 0.50000000000001 0.5 0.5 0.49999999999995 0.50000000000008 0.50000000000071 0.49999999999656 0.49999999998895 0.50000000004864 0.49999999990507 0.49999999702752 0.49999994747561 0.4999991819682 0.49998896747007 0.49987441553891 0.49883319444726 0.49159137514643 0.44974309848157 0.35227207905518 0.24318828591894 0.19253917660723 0.1445780789094 0.12714492989013 0.12532101656629 0.12528782035649 0.12929122547813 0.16226606558518 0.26265281047563 0.42521401941049 0.64581563904804 0.8988168101135 0.95813339827956 0.93194671527292 0.83098159578161 0.64793036601913 0.58008743962156 0.52322077973746 0.50293258676757 0.50031877646248 0.50002798705531 0.50000207820763 0.5000001339255 0.50000000765918 0.50000000035742 0.49999999993248 0.50000000000381 0.50000000000687 0.49999999999953 0.49999999999974 0.50000000000006 0.50000000000001 0.5 0.5 0.49999999999995 0.50000000000008 0.50000000000071 0.49999999999656 0.49999999998895 0.50000000004864 0.49999999990507 0.49999999702752 0.49999994747561 0.4999991819682 0.49998896747006 0.49987441553891 0.49883319444726 0.49159137514643 0.44974309848157 0.35227207905518 0.24318828591894 0.19253917660723 0.1445780789094 0.12714492989013 0.12532101656629 0.12528782035649 0.12929122547813 0.16226606558518 0.26265281047563 0.42521401941049 0.64581563904804 0.8988168101135 0.95813339827956 0.93194671527293 0.83098159578161 0.64793036601913 0.58008743962156 0.52322077973746 0.50293258676757 0.50031877646248 0.50002798705531 0.50000207820763 0.50000013392549 0.50000000765918 0.50000000035742 0.49999999993248 0.50000000000381 0.50000000000687 0.49999999999953 0.49999999999974 0.50000000000006 0.50000000000001 0.5 0.5 0.49999999999995 0.50000000000008 0.50000000000071 0.49999999999656 0.49999999998895 0.50000000004864 0.49999999990507 0.49999999702752 0.49999994747561 0.4999991819682 0.49998896747006 0.49987441553891 0.49883319444726 0.49159137514643 0.44974309848157 0.35227207905518 0.24318828591894 0.19253917660723 0.1445780789094 0.12714492989013 0.12532101656629 0.12528782035649 0.12929122547813 0.16226606558518 0.26265281047563 0.42521401941049 0.64581563904804 0.8988168101135 0.95813339827957 0.93194671527292 0.83098159578161 0.64793036601913 0.58008743962156 0.52322077973746 0.50293258676757 0.50031877646248 0.50002798705531 0.50000207820763 0.5000001339255 0.50000000765918 0.50000000035742 0.49999999993248 0.50000000000381 0.50000000000687 0.49999999999953 0.49999999999974 0.50000000000006 0.50000000000001 0.5 0.5 0.49999999999995 0.50000000000008 0.50000000000071 0.49999999999656 0.49999999998895 0.50000000004864 0.49999999990507 0.49999999702752 0.49999994747561 0.4999991819682 0.49998896747007 0.49987441553891 0.49883319444726 0.49159137514643 0.44974309848157 0.35227207905518 0.24318828591894 0.19253917660723 0.1445780789094 0.12714492989013 0.12532101656629 0.12528782035649 0.12929122547813 0.16226606558518 0.26265281047563 0.42521401941049 0.64581563904804 0.89881681011351 0.95813339827957 0.93194671527293 0.83098159578161 0.64793036601913 0.58008743962156 0.52322077973746 0.50293258676757 0.50031877646248 0.50002798705531 0.50000207820763 0.5000001339255 0.50000000765918 0.50000000035742 0.49999999993248 0.50000000000381 0.50000000000687 0.49999999999953 0.49999999999974 0.50000000000006 0.50000000000001 0.5 0.5 0.49999999999995 0.50000000000008 0.50000000000071 0.49999999999656 0.49999999998895 0.50000000004864 0.49999999990507 0.49999999702752 0.49999994747561 0.4999991819682 0.49998896747007 0.49987441553891 0.49883319444726 0.49159137514643 0.44974309848157 0.35227207905518 0.24318828591894 0.19253917660723 0.1445780789094 0.12714492989013 0.12532101656629 0.12528782035649 0.12929122547813 0.16226606558518 0.26265281047563 0.42521401941049 0.64581563904804 0.89881681011351 0.95813339827957 0.93194671527292 0.83098159578161 0.64793036601913 0.58008743962156 0.52322077973746 0.50293258676757 0.50031877646248 0.50002798705531 0.50000207820763 0.5000001339255 0.50000000765918 0.50000000035742 0.49999999993248 0.50000000000381 0.50000000000687 0.49999999999953 0.49999999999974 0.50000000000006 0.50000000000001 0.5 0.5 0.49999999999995 0.50000000000008 0.50000000000071 0.49999999999656 0.49999999998895 0.50000000004864 0.49999999990507 0.49999999702752 0.49999994747561 0.4999991819682 0.49998896747007 0.49987441553891 0.49883319444726 0.49159137514643 0.44974309848157 0.35227207905518 0.24318828591894 0.19253917660723 0.1445780789094 0.12714492989013 0.12532101656629 0.12528782035649 0.12929122547813 0.16226606558518 0.26265281047563 0.42521401941049 0.64581563904804 0.8988168101135 0.95813339827957 0.93194671527292 0.83098159578161 0.64793036601913 0.58008743962156 0.52322077973746 0.50293258676757 0.50031877646248 0.50002798705531 0.50000207820763 0.5000001339255 0.50000000765918 0.50000000035742 0.49999999993248 0.50000000000381 0.50000000000687 0.49999999999953 0.49999999999974 0.50000000000006 0.50000000000001 0.5 0.5 0.49999999999995 0.50000000000008 0.50000000000071 0.49999999999656 0.49999999998895 0.50000000004864 0.49999999990507 0.49999999702752 0.49999994747561 0.4999991819682 0.49998896747007 0.49987441553891 0.49883319444726 0.49159137514643 0.44974309848157 0.35227207905518 0.24318828591894 0.19253917660723 0.1445780789094 0.12714492989013 0.12532101656629 0.12528782035649 0.12929122547813 0.16226606558518 0.26265281047563 0.42521401941049 0.64581563904804 0.8988168101135 0.95813339827956 0.93194671527293 0.83098159578161 0.64793036601913 0.58008743962156 0.52322077973746 0.50293258676757 0.50031877646248 0.50002798705531 0.50000207820763 0.5000001339255 0.50000000765918 0.50000000035742 0.49999999993248 0.50000000000381 0.50000000000687 0.49999999999953 0.49999999999974 0.50000000000006 0.50000000000001 0.5 0.5 0.49999999999995 0.50000000000008 0.50000000000071 0.49999999999656 0.49999999998895 0.50000000004864 0.49999999990507 0.49999999702752 0.49999994747561 0.4999991819682 0.49998896747007 0.49987441553891 0.49883319444726 0.49159137514643 0.44974309848157 0.35227207905518 0.24318828591894 0.19253917660723 0.1445780789094 0.12714492989013 0.12532101656629 0.12528782035649 0.12929122547813 0.16226606558518 0.26265281047562 0.42521401941049 0.64581563904809 0.89881681011353 0.95813339827956 0.93194671527293 0.83098159578161 0.64793036601912 0.58008743962156 0.52322077973746 0.50293258676757 0.50031877646248 0.50002798705531 0.50000207820763 0.50000013392549 0.50000000765918 0.50000000035742 0.49999999993248 0.50000000000381 0.50000000000687 0.49999999999953 0.49999999999974 0.50000000000006 0.50000000000001 0.5 0.5 0.49999999999995 0.50000000000008 0.50000000000071 0.49999999999656 0.49999999998895 0.50000000004864 0.49999999990507 0.49999999702752 0.49999994747561 0.4999991819682 0.49998896747007 0.49987441553891 0.49883319444726 0.49159137514643 0.44974309848157 0.35227207905518 0.24318828591894 0.19253917660723 0.1445780789094 0.12714492989013 0.12532101656629 0.12528782035649 0.12929122547813 0.16226606558518 0.26265281047564 0.42521401941055 0.64581563904789 0.89881681011355 0.9581333982796 0.93194671527289 0.8309815957816 0.64793036601914 0.58008743962156 0.52322077973746 0.50293258676757 0.50031877646248 0.50002798705531 0.50000207820763 0.50000013392549 0.50000000765918 0.50000000035742 0.49999999993248 0.50000000000381 0.50000000000687 0.49999999999953 0.49999999999974 0.50000000000006 0.50000000000001 0.5 0.5 0.49999999999995 0.50000000000008 0.50000000000071 0.49999999999656 0.49999999998895 0.50000000004864 0.49999999990507 0.49999999702752 0.49999994747561 0.4999991819682 0.49998896747007 0.49987441553891 0.49883319444726 0.49159137514643 0.44974309848157 0.35227207905518 0.24318828591894 0.19253917660723 0.1445780789094 0.12714492989013 0.12532101656629 0.12528782035649 0.12929122547813 0.16226606558519 0.26265281047565 0.42521401941038 0.6458156390474 0.89881681011299 0.95813339827959 0.93194671527294 0.8309815957816 0.64793036601917 0.58008743962161 0.52322077973747 0.50293258676756 0.50031877646248 0.50002798705531 0.50000207820763 0.5000001339255 0.50000000765918 0.50000000035742 0.49999999993248 0.50000000000381 0.50000000000687 0.49999999999953 0.49999999999974 0.50000000000006 0.50000000000001 0.5 0.5 0.49999999999995 0.50000000000008 0.50000000000071 0.49999999999656 0.49999999998895 0.50000000004864 0.49999999990507 0.49999999702752 0.49999994747561 0.4999991819682 0.49998896747007 0.49987441553891 0.49883319444726 0.49159137514643 0.44974309848157 0.35227207905518 0.24318828591894 0.19253917660723 0.1445780789094 0.12714492989013 0.12532101656629 0.12528782035649 0.12929122547814 0.16226606558514 0.26265281047528 0.42521401940981 0.64581563905318 0.89881681011396 0.95813339827885 0.93194671527355 0.8309815957817 0.64793036601888 0.58008743962149 0.5232207797375 0.50293258676757 0.50031877646248 0.50002798705531 0.50000207820763 0.50000013392549 0.50000000765918 0.50000000035742 0.49999999993248 0.50000000000381 0.50000000000687 0.49999999999953 0.49999999999974 0.50000000000006 0.50000000000001 0.5 0.5 0.49999999999995 0.50000000000008 0.50000000000071 0.49999999999656 0.49999999998895 0.50000000004864 0.49999999990507 0.49999999702752 0.49999994747561 0.4999991819682 0.49998896747006 0.49987441553891 0.49883319444726 0.49159137514643 0.44974309848157 0.35227207905518 0.24318828591894 0.19253917660723 0.1445780789094 0.12714492989013 0.12532101656629 0.1252878203565 0.12929122547815 0.16226606558512 0.26265281047612 0.42521401941458 0.6458156390577 0.89881681012501 0.95813339828114 0.93194671527099 0.83098159578166 0.64793036601892 0.58008743962081 0.52322077973724 0.5029325867676 0.50031877646248 0.50002798705531 0.50000207820763 0.50000013392549 0.50000000765918 0.50000000035742 0.49999999993248 0.50000000000381 0.50000000000687 0.49999999999953 0.49999999999974 0.50000000000006 0.50000000000001 0.5 0.5 0.49999999999995 0.50000000000008 0.50000000000071 0.49999999999656 0.49999999998895 0.50000000004864 0.49999999990507 0.49999999702752 0.49999994747561 0.4999991819682 0.49998896747006 0.49987441553891 0.49883319444726 0.49159137514643 0.44974309848157 0.35227207905518 0.24318828591894 0.19253917660724 0.1445780789094 0.12714492989013 0.12532101656628 0.12528782035651 0.12929122547805 0.16226606558611 0.26265281048313 0.42521401942061 0.64581563897975 0.89881681010013 0.95813339829339 0.93194671526133 0.83098159577934 0.64793036602498 0.58008743962456 0.52322077973719 0.50293258676743 0.50031877646251 0.50002798705531 0.50000207820763 0.5000001339255 0.50000000765918 0.50000000035741 0.49999999993248 0.50000000000381 0.50000000000687 0.49999999999953 0.49999999999974 0.50000000000006 0.50000000000001 0.5 0.5 0.49999999999995 0.50000000000008 0.50000000000071 0.49999999999656 0.49999999998895 0.50000000004864 0.49999999990507 0.49999999702752 0.49999994747561 0.4999991819682 0.49998896747007 0.49987441553891 0.49883319444726 0.49159137514643 0.44974309848157 0.35227207905518 0.24318828591894 0.19253917660724 0.14457807890943 0.12714492989014 0.12532101656633 0.12528782035635 0.12929122547817 0.16226606558399 0.26265281046555 0.42521401935595 0.64581563926021 0.8988168100509 0.9581333982502 0.93194671530612 0.8309815957792 0.64793036602214 0.58008743963376 0.52322077974327 0.50293258676733 0.50031877646236 0.50002798705534 0.50000207820764 0.50000013392549 0.50000000765918 0.50000000035742 0.49999999993248 0.50000000000381 0.50000000000687 0.49999999999953 0.49999999999974 0.50000000000006 0.50000000000001 0.5 0.5 0.49999999999995 0.50000000000008 0.50000000000071 0.49999999999656 0.49999999998895 0.50000000004864 0.49999999990507 0.49999999702752 0.49999994747561 0.4999991819682 0.49998896747006 0.49987441553891 0.49883319444726 0.49159137514643 0.44974309848158 0.35227207905518 0.24318828591896 0.19253917660719 0.1445780789093 0.12714492989008 0.12532101656648 0.12528782035654 0.1292912254797 0.16226606557506 0.26265281045356 0.42521401954521 0.64581564405577 0.89881681128742 0.95813339826466 0.93194671528192 0.83098159582031 0.64793036596011 0.58008743957913 0.5232207797417 0.50293258677247 0.50031877646225 0.50002798705522 0.50000207820765 0.5000001339255 0.50000000765918 0.50000000035742 0.49999999993248 0.50000000000381 0.50000000000687 0.49999999999953 0.49999999999974 0.50000000000006 0.50000000000001 0.5 0.5 0.49999999999995 0.50000000000008 0.50000000000071 0.49999999999656 0.49999999998895 0.50000000004864 0.49999999990507 0.49999999702752 0.49999994747561 0.4999991819682 0.49998896747007 0.49987441553891 0.49883319444727 0.49159137514643 0.44974309848159 0.35227207905516 0.24318828591884 0.19253917660728 0.14457807890924 0.12714492988988 0.12532101656446 0.12528782035818 0.12929122547607 0.16226606561439 0.26265281122408 0.42521402299545 0.64581572912781 0.89881683111679 0.95813340039494 0.93194671359772 0.83098159564867 0.64793036631119 0.58008743964621 0.52322077967469 0.5029325867714 0.5003187764673 0.50002798705508 0.50000207820758 0.5000001339255 0.50000000765918 0.50000000035742 0.49999999993248 0.50000000000381 0.50000000000687 0.49999999999953 0.49999999999974 0.50000000000006 0.50000000000001 0.5 0.5 0.49999999999995 0.50000000000008 0.50000000000071 0.49999999999656 0.49999999998895 0.50000000004864 0.49999999990507 0.49999999702752 0.49999994747561 0.4999991819682 0.49998896747006 0.49987441553891 0.49883319444726 0.49159137514642 0.44974309848145 0.35227207905538 0.24318828591905 0.19253917660732 0.14457807891331 0.12714492989295 0.12532101656264 0.12528782035508 0.12929122548272 0.16226606562178 0.26265282429878 0.42521408199435 0.64581708335391 0.89881714539825 0.95813343372903 0.93194668806982 0.8309815916026 0.64793037011579 0.58008744158368 0.52322078005411 0.50293258671921 0.5003187764662 0.50002798705922 0.50000207820752 0.50000013392546 0.50000000765918 0.50000000035742 0.49999999993248 0.50000000000381 0.50000000000687 0.49999999999953 0.49999999999974 0.50000000000006 0.50000000000001 0.5 0.5 0.49999999999995 0.50000000000008 0.50000000000071 0.49999999999656 0.49999999998895 0.50000000004864 0.49999999990507 0.49999999702752 0.49999994747561 0.4999991819682 0.49998896747007 0.49987441553891 0.49883319444726 0.49159137514638 0.44974309848149 0.35227207905544 0.24318828592318 0.192539176605 0.14457807890825 0.1271449298895 0.1253210165923 0.125287820369 0.12929122536562 0.16226606236185 0.26265300736533 0.42521497358829 0.64583564609176 0.89882145542624 0.9581339343715 0.93194630231941 0.8309815066722 0.64793041429112 0.5800874708955 0.52322078668228 0.502932587175 0.50031877642303 0.50002798706108 0.50000207821031 0.50000013392561 0.50000000765918 0.50000000035742 0.49999999993248 0.50000000000381 0.50000000000687 0.49999999999953 0.49999999999974 0.50000000000006 0.50000000000001 0.5 0.5 0.49999999999995 0.50000000000008 0.50000000000071 0.49999999999656 0.49999999998895 0.50000000004864 0.49999999990507 0.49999999702752 0.49999994747561 0.4999991819682 0.49998896747007 0.49987441553891 0.49883319444729 0.49159137514681 0.44974309848455 0.35227207905104 0.24318828591146 0.1925391766248 0.14457807889435 0.12714492985949 0.12532101645785 0.12528782031931 0.12929121848012 0.16226596158909 0.26265516194965 0.42522643403742 0.64604871756586 0.89887108067993 0.95814036798455 0.93194122965886 0.83098004793425 0.64793079672699 0.58008787033119 0.52322089264406 0.50293259478219 0.50031877693935 0.50002798702813 0.50000207821346 0.5000001339268 0.50000000765928 0.50000000035742 0.49999999993248 0.50000000000381 0.50000000000687 0.49999999999953 0.49999999999974 0.50000000000006 0.50000000000001 0.5 0.5 0.49999999999995 0.50000000000008 0.50000000000071 0.49999999999656 0.49999999998895 0.50000000004864 0.49999999990507 0.49999999702752 0.49999994747561 0.4999991819682 0.49998896747007 0.49987441553892 0.49883319444738 0.49159137514761 0.44974309848265 0.35227207906292 0.24318828589025 0.19253917655369 0.14457807939102 0.12714493026704 0.12532101174067 0.12528781518775 0.12929104746187 0.16226386964688 0.26267602795445 0.4253478555662 0.64800804544877 0.89933033928241 0.95820906500162 0.93188432436671 0.83095995021693 0.64793213079836 0.5800923147781 0.52322231244399 0.50293270440187 0.50031878484456 0.50002798748851 0.50000207819635 0.50000013392633 0.50000000765939 0.50000000035743 0.49999999993247 0.50000000000381 0.50000000000687 0.49999999999953 0.49999999999974 0.50000000000006 0.50000000000001 0.5 0.5 0.49999999999995 0.50000000000008 0.50000000000071 0.49999999999656 0.49999999998895 0.50000000004864 0.49999999990507 0.49999999702752 0.49999994747561 0.4999991819682 0.49998896747006 0.49987441553887 0.49883319444655 0.49159137513842 0.4497430984429 0.35227207919758 0.24318828635193 0.19253917445714 0.144578091314 0.12714494464614 0.12532090599103 0.12528768646305 0.12928782670337 0.16222798618242 0.26279596844584 0.42639538550033 0.66243669103741 0.90270779480152 0.95881580985625 0.93135560847753 0.83074245496204 0.64791903377314 0.58013194902955 0.52323746233688 0.50293399092473 0.50031888382452 0.50002799399972 0.50000207849688 0.50000013392212 0.50000000765793 0.50000000035736 0.49999999993249 0.50000000000381 0.50000000000686 0.49999999999953 0.49999999999974 0.50000000000006 0.50000000000001 0.5 0.5 0.49999999999995 0.50000000000008 0.50000000000071 0.49999999999656 0.49999999998895 0.50000000004864 0.49999999990507 0.49999999702752 0.49999994747561 0.4999991819682 0.49998896747006 0.49987441553881 0.49883319444676 0.49159137516825 0.44974309890148 0.35227208087812 0.24318829424258 0.19253913377802 0.14457831322335 0.12714526141236 0.12531900814995 0.12528572857803 0.12924457150699 0.16177315998182 0.26303283669169 0.4320295738415 0.69944351525988 0.91417039137444 0.96164451802645 0.9272628844419 0.82896266025665 0.6475920208275 0.580346584557 0.52336623564712 0.5029461282133 0.50031988612532 0.50002806243347 0.50000208266363 0.50000013415124 0.50000000766575 0.50000000035749 0.49999999993251 0.50000000000381 0.50000000000686 0.49999999999953 0.49999999999974 0.50000000000006 0.50000000000001 0.5 0.5 0.49999999999995 0.50000000000008 0.50000000000071 0.49999999999656 0.49999999998895 0.50000000004864 0.49999999990507 0.49999999702752 0.49999994747561 0.4999991819682 0.49998896747011 0.49987441554007 0.49883319447167 0.49159137563868 0.44974310342903 0.35227209160809 0.243188346471 0.19253865823693 0.14458036723767 0.127148941201 0.12530467405266 0.12526839452641 0.12892015703488 0.15845359121489 0.26108187804229 0.437950602575 0.93152468465458 0.93685575343341 0.97912954148092 0.90919718044367 0.81629982931572 0.64582138862503 0.58048341734228 0.5238479424671 0.50299968343251 0.50032490764246 0.50002844168751 0.50000210678276 0.50000013557772 0.50000000775427 0.50000000036154 0.49999999993238 0.50000000000371 0.50000000000691 0.49999999999954 0.49999999999974 0.50000000000006 0.50000000000001 0.5 0.5 0.49999999999995 0.50000000000008 0.50000000000071 0.49999999999656 0.49999999998895 0.50000000004864 0.49999999990507 0.49999999702752 0.49999994747561 0.49999918196821 0.49998896747036 0.49987441554606 0.49883319460621 0.49159137906524 0.44974314095432 0.35227206821854 0.24318809932709 0.19253474001419 0.14459721655047 0.12718612607045 0.12518037458604 0.12519588403579 0.12667846688517 0.13432348229512 0.21584665419358 0.43373769670589 0.91579551807467 0.95933607855872 0.91819261163374 0.83287910037963 0.76060458296266 0.62317069292154 0.57731166901015 0.52503870644601 0.50316991742505 0.50034108613927 0.5000297633324 0.50000219708743 0.50000014087636 0.50000000805287 0.5000000003781 0.49999999993268 0.50000000000301 0.50000000000705 0.49999999999957 0.49999999999973 0.50000000000006 0.50000000000001 0.5 0.5 0.49999999999995 0.50000000000008 0.50000000000071 0.49999999999656 0.49999999998895 0.50000000004864 0.49999999990507 0.49999999702752 0.49999994747561 0.49999918196816 0.49998896746926 0.49987441552678 0.49883319431432 0.49159137492612 0.44974310284102 0.35227195103575 0.24318821454601 0.19253154256495 0.1445762222508 0.12719635835003 0.1252183525873 0.12502725326151 0.12569181656228 0.12822811959815 0.16387367153045 0.36971459560124 0.90454173001004 0.91052446036202 0.81500336565782 0.74711005087299 0.72810282119661 0.60685066495291 0.56335971445384 0.52009984915678 0.50256393183298 0.50028098391622 0.50002491147445 0.50000186466756 0.50000012093219 0.50000000697996 0.50000000032941 0.49999999993357 0.5000000000044 0.50000000000655 0.49999999999952 0.49999999999976 0.50000000000006 0.50000000000001 0.5 0.5 0.49999999999995 0.50000000000008 0.50000000000071 0.49999999999656 0.49999999998895 0.50000000004864 0.49999999990507 0.49999999702752 0.4999999474756 0.49999918196793 0.49998896746488 0.49987441545451 0.49883319330151 0.49159136225338 0.44974299184008 0.35227201982205 0.24318769404661 0.19253175583663 0.14455460298492 0.12721179734004 0.12520396822272 0.12508496901662 0.12504629487882 0.12518740197722 0.12818136174779 0.2701225797684 0.95074225606158 0.64546541848146 0.59687362292255 0.59975704168606 0.5864929739942 0.53637643546695 0.52463789671977 0.50658315152947 0.5008291618924 0.50009053060382 0.50000806786926 0.50000060945395 0.5000000399526 0.50000000225881 0.50000000004902 0.49999999996064 0.5000000000113 0.50000000000257 0.49999999999932 0.49999999999996 0.50000000000004 0.5 0.5 0.5 0.49999999999995 0.50000000000008 0.50000000000071 0.49999999999656 0.49999999998895 0.50000000004864 0.49999999990507 0.49999999702752 0.49999994747561 0.4999991819681 0.49998896746807 0.4998744155058 0.49883319399109 0.49159137027328 0.4497430570795 0.35227196069538 0.24318801407687 0.1925321912195 0.14456070518323 0.12720154742646 0.12520972990382 0.12517563703539 0.12534267218221 0.12636998770527 0.12531920820479 0.30067497364733 1.0 0.50299232060043 0.50720589621132 0.51693930773198 0.52370802558525 0.52395695923259 0.50920048522293 0.50212946103409 0.50025381073595 0.50002611224629 0.50000226004769 0.50000016830513 0.50000001095282 0.50000000056893 0.49999999992541 0.49999999999636 0.50000000001 0.4999999999999 0.49999999999952 0.50000000000007 0.50000000000002 0.49999999999999 0.5 0.5 0.49999999999995 0.50000000000008 0.50000000000071 0.49999999999656 0.49999999998895 0.50000000004864 0.49999999990507 0.49999999702752 0.49999994747562 0.49999918196827 0.49998896747157 0.4998744155681 0.4988331949447 0.49159138380126 0.44974318397366 0.35227191650083 0.24318839508791 0.19253187920075 0.14459249934973 0.12719883585912 0.12517908985555 0.125170110401 0.1267525680515 0.14267696007156 0.16761189234405 0.125 D/cons.2.00.000000.dat 0.001 0.001 0.001 0.001 0.001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.001 0.001 0.001 0.001 0.001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.001 0.001 0.001 0.001 0.001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.001 0.001 0.001 0.001 0.001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.001 0.001 0.001 0.001 0.001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.001 0.001 0.001 0.001 0.001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.001 0.001 0.001 0.001 0.001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.001 0.001 0.001 0.001 0.001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.001 0.001 0.001 0.001 0.001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.001 0.001 0.001 0.001 0.001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.001 0.001 0.001 0.001 0.001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.001 0.001 0.001 0.001 0.001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.001 0.001 0.001 0.001 0.001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.001 0.001 0.001 0.001 0.001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.001 0.001 0.001 0.001 0.001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.001 0.001 0.001 0.001 0.001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.001 0.001 0.001 0.001 0.001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.001 0.001 0.001 0.001 0.001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.001 0.001 0.001 0.001 0.001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.001 0.001 0.001 0.001 0.001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.001 0.001 0.001 0.001 0.001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.001 0.001 0.001 0.001 0.001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.001 0.001 0.001 0.001 0.001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.001 0.001 0.001 0.001 0.001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.001 0.001 0.001 0.001 0.001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.001 0.001 0.001 0.001 0.001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.001 0.001 0.001 0.001 0.001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.001 0.001 0.001 0.001 0.001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.001 0.001 0.001 0.001 0.001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.001 0.001 0.001 0.001 0.001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.001 0.001 0.001 0.001 0.001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.001 0.001 0.001 0.001 0.001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.001 0.001 0.001 0.001 0.001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.001 0.001 0.001 0.001 0.001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.001 0.001 0.001 0.001 0.001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.001 0.001 0.001 0.001 0.001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.001 0.001 0.001 0.001 0.001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.001 0.001 0.001 0.001 0.001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.001 0.001 0.001 0.001 0.001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.001 0.001 0.001 0.001 0.001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.001 0.001 0.001 0.001 0.001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.001 0.001 0.001 0.001 0.001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.001 0.001 0.001 0.001 0.001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.001 0.001 0.001 0.001 0.001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.001 0.001 0.001 0.001 0.001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.001 0.001 0.001 0.001 0.001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.001 0.001 0.001 0.001 0.001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.001 0.001 0.001 0.001 0.001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.001 0.001 0.001 0.001 0.001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.001 0.001 0.001 0.001 0.001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 0.000125 -D/cons.2.00.000050.dat 0.0 0.0 0.0 0.0 0.0 -0.01432163110564 -0.0060421031393 -0.00053292310506 0.00038875051231 0.000489731076 0.00049920889572 0.00049994760845 0.00049999696879 0.00049999986347 0.00050000000339 0.00050000000365 0.00049999999879 0.00049999999983 0.00050000000006 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999703 0.00049999994748 0.00049999918197 0.00049998896744 0.00049987441526 0.00049883319798 0.00049159134174 0.00044974054465 0.00035224551313 0.00024326640117 0.0001922703913 0.00014900647414 0.00012888325862 0.00011989630684 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 -0.03705376624279 -0.01959752193492 -0.00329309746997 0.00011588246081 0.00046484017512 0.00049729180828 0.00049981974588 0.00049998937221 0.00049999940856 0.00049999997585 0.00050000000894 0.0004999999988 0.00049999999938 0.00050000000008 0.00050000000002 0.00049999999999 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.0004999999999 0.00049999999703 0.00049999994747 0.00049999918195 0.00049998896709 0.00049987440824 0.00049883307719 0.00049159023912 0.00044973372772 0.00035227347799 0.00024316260212 0.0001927212351 0.00014461878434 0.00013088029345 0.00012358457775 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 -0.09741391402673 -0.04274563454263 -0.02378299139823 -0.00461661170363 2.871775002e-05 0.00045965921663 0.00049707847084 0.00049981655867 0.00049998973884 0.00049999944907 0.00049999997405 0.00050000000628 0.00049999999956 0.0004999999995 0.00050000000004 0.00050000000002 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.0004999999999 0.00049999999703 0.00049999994748 0.00049999918197 0.00049998896755 0.00049987441677 0.00049883320676 0.00049159151132 0.00044974552644 0.0003522752539 0.00024316626684 0.00019294048929 0.00014358593599 0.00012785036207 0.00012588616899 9.630097776e-05 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 -0.05668464476674 -0.02033766676665 -0.00480548545562 0.00026338938519 0.00048908658052 0.000499822988 0.00050002444688 0.00050000266969 0.00050000001221 0.00050000001212 0.00050000000167 0.00049999999932 0.00050000000005 0.00050000000005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999703 0.00049999994748 0.00049999918199 0.00049998896802 0.00049987442654 0.00049883337832 0.00049159348196 0.00044976452966 0.00035226507118 0.00024322859854 0.00019207674056 0.00014353803244 0.0001234204676 0.00012672691267 7.663096583e-05 0.0 0.0 0.0 0.0 0.0 0.0 0.00320359405583 -0.02504708407512 -0.01918063705468 -0.00522120833689 0.00077507041285 0.00086237145056 0.00053035540099 0.00050247568463 0.0005001706165 0.00050001053393 0.00050000080768 0.00050000006064 0.00050000000277 0.00049999999956 0.0005 0.00050000000004 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999703 0.00049999994748 0.00049999918197 0.00049998896759 0.00049987441816 0.00049883324438 0.00049159227549 0.00044975580724 0.00035224946732 0.000243257642 0.0001909464657 0.00014478632718 0.00013256716049 0.0001202589274 9.369134514e-05 -0.00039775000242 -0.00546501594161 0.0 0.0 0.09744920748275 0.00741325612019 0.00332980424034 -0.00587639364127 -0.00178892971534 2.43223836e-05 0.0008289075732 0.00062375397074 0.00051021014494 0.00050084340682 0.00050006028769 0.00050000393958 0.00050000020807 0.00050000000715 0.00050000000024 0.00049999999996 0.00050000000001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999703 0.00049999994748 0.00049999918197 0.00049998896753 0.00049987441683 0.00049883321848 0.00049159180491 0.00044974776051 0.00035224275386 0.00024326741546 0.00019173466549 0.00014629287999 0.00013147811575 0.00010576633438 0.00011617136939 -0.00023848592197 -0.00499115776482 -0.00440869136694 0.01680453038225 0.02269919168666 0.00291322913295 0.00139602063098 4.86213527e-06 0.0005180671794 0.00058955043853 0.00063888781819 0.00053873679966 0.00050399005649 0.00050039065694 0.00050003215587 0.00050000226542 0.00050000012684 0.00050000000654 0.00050000000033 0.00049999999995 0.0005 0.00050000000001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999703 0.00049999994748 0.00049999918197 0.00049998896747 0.00049987441556 0.00049883319513 0.00049159138867 0.00044974373672 0.00035226816165 0.00024320379215 0.00019245012037 0.00014477309137 0.00012749927071 0.000122776701 0.00012372103264 8.179438305e-05 -0.00048816091193 -5.862022714e-05 0.00724088338917 0.00328160307352 0.00121782572953 0.00100737354333 0.00082923685626 0.00080065639923 0.00064475400169 0.00058659275451 0.00052489629032 0.00050304074371 0.00050032573451 0.00050002838975 0.00050000204811 0.00050000013358 0.00050000000773 0.00050000000036 0.00049999999993 0.0005 0.00050000000001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.0004999999999 0.00049999999703 0.00049999994748 0.00049999918197 0.00049998896747 0.00049987441553 0.00049883319434 0.0004915913725 0.00044974305726 0.00035227195145 0.00024318960814 0.00019253201254 0.00014458861153 0.00012716427009 0.0001251603493 0.00012510683719 0.00012523328378 0.00010843637255 0.00032341641351 0.00163535805328 0.00091113961573 0.00093546807466 0.00096264009016 0.00092269284726 0.0008285319885 0.00064790357835 0.00058068847582 0.0005233607478 0.00050294121673 0.00050031934777 0.00050002793895 0.00050000208522 0.00050000013514 0.00050000000774 0.00050000000036 0.00049999999993 0.0005 0.00050000000001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999703 0.00049999994748 0.00049999918197 0.00049998896747 0.00049987441554 0.0004988331945 0.0004915913763 0.00044974309354 0.00035227212758 0.00024318827589 0.00019253854251 0.00014457874941 0.00012714610906 0.0001253120503 0.00012527277609 0.00012900066729 0.00015843512691 0.00027683553634 0.00056116281844 0.00066766670342 0.00090207728644 0.00095847536266 0.0009312459891 0.0008308131992 0.00064794553475 0.00058013287217 0.00052323048843 0.00050293320225 0.00050031871748 0.00050002799331 0.00050000208086 0.00050000013401 0.00050000000766 0.00050000000036 0.00049999999993 0.0005 0.00050000000001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999703 0.00049999994748 0.00049999918197 0.00049998896747 0.00049987441554 0.00049883319449 0.00049159137568 0.0004497431053 0.00035227207201 0.00024318826331 0.00019253923897 0.00014457803117 0.00012714488943 0.00012532049218 0.00012528667829 0.0001292734603 0.00016203531994 0.0002643354818 0.00043767349264 0.00064733885807 0.00089905550483 0.00095815567636 0.00093190103498 0.00083097143469 0.00064793249437 0.00058009048646 0.00052322139496 0.0005029325194 0.00050031877882 0.00050002799169 0.00050000207807 0.00050000013389 0.00050000000766 0.00050000000036 0.00049999999993 0.0005 0.00050000000001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999703 0.00049999994748 0.00049999918197 0.00049998896747 0.00049987441554 0.00049883319445 0.00049159137517 0.00044974309932 0.00035227207583 0.00024318829393 0.00019253917782 0.00014457807488 0.00012714492283 0.00012532107855 0.00012528785787 0.00012929018602 0.00016225434619 0.00026280343747 0.0004261561147 0.00064590777671 0.0008988317407 0.00095813468633 0.00093194405552 0.00083098108486 0.00064793036557 0.00058008749741 0.0005232207057 0.00050293258766 0.0005003187827 0.00050002798679 0.00050000207815 0.00050000013393 0.00050000000766 0.00050000000036 0.00049999999993 0.0005 0.00050000000001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999703 0.00049999994748 0.00049999918197 0.00049998896747 0.00049987441554 0.00049883319445 0.00049159137513 0.00044974309829 0.00035227207948 0.00024318828778 0.00019253917024 0.00014457808264 0.00012714493671 0.00012532101314 0.00012528782985 0.00012929127536 0.0001622654133 0.00026266370687 0.00042527473313 0.00064582068344 0.00089881760151 0.00095813333332 0.00093194670195 0.00083098170685 0.0006479303256 0.00058008738182 0.00052322077834 0.00050293259373 0.00050031877628 0.00050002798695 0.00050000207822 0.00050000013393 0.00050000000766 0.00050000000036 0.00049999999993 0.0005 0.00050000000001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999703 0.00049999994748 0.00049999918197 0.00049998896747 0.00049987441554 0.00049883319445 0.00049159137515 0.00044974309846 0.00035227207912 0.00024318828551 0.0001925391765 0.00014457807925 0.00012714493021 0.00012532101209 0.00012528781329 0.00012929123001 0.00016226612172 0.00026265352955 0.000425217584 0.00064581583121 0.00089881671562 0.00095813338098 0.00093194676209 0.00083098159014 0.00064793037827 0.00058008745349 0.00052322078737 0.00050293258658 0.00050031877629 0.00050002798709 0.00050000207821 0.00050000013393 0.00050000000766 0.00050000000036 0.00049999999993 0.0005 0.00050000000001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999703 0.00049999994748 0.00049999918197 0.00049998896747 0.00049987441554 0.00049883319445 0.00049159137515 0.00044974309849 0.00035227207903 0.00024318828588 0.00019253917689 0.00014457807879 0.00012714492958 0.00012532101683 0.00012528781986 0.00012929121877 0.0001622660599 0.00026265274663 0.00042521411131 0.00064581556672 0.00089881680615 0.00095813341111 0.00093194669919 0.00083098158501 0.00064793036948 0.00058008744396 0.00052322077975 0.00050293258656 0.0005003187765 0.00050002798706 0.00050000207821 0.00050000013393 0.00050000000766 0.00050000000036 0.00049999999993 0.0005 0.00050000000001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999703 0.00049999994748 0.00049999918197 0.00049998896747 0.00049987441554 0.00049883319445 0.00049159137515 0.00044974309848 0.00035227207906 0.00024318828595 0.00019253917657 0.0001445780789 0.00012714492992 0.00012532101672 0.0001252878207 0.00012929122536 0.00016226606149 0.00026265280725 0.00042521396468 0.00064581565047 0.00089881682048 0.00095813339898 0.00093194671244 0.00083098159633 0.0006479303654 0.00058008743875 0.00052322077945 0.00050293258681 0.00050031877647 0.00050002798705 0.00050000207821 0.00050000013393 0.00050000000766 0.00050000000036 0.00049999999993 0.0005 0.00050000000001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.0004999999999 0.00049999999703 0.00049999994748 0.00049999918197 0.00049998896747 0.00049987441554 0.00049883319445 0.00049159137515 0.00044974309848 0.00035227207906 0.00024318828592 0.00019253917659 0.00014457807892 0.0001271449299 0.00012532101653 0.00012528782033 0.0001292912258 0.0001622660663 0.00026265281763 0.0004252140312 0.00064581564418 0.00089881681016 0.00095813339774 0.00093194671615 0.00083098159624 0.00064793036593 0.00058008743951 0.00052322077977 0.00050293258677 0.00050031877646 0.00050002798706 0.00050000207821 0.00050000013393 0.00050000000766 0.00050000000036 0.00049999999993 0.0005 0.00050000000001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.0004999999999 0.00049999999703 0.00049999994748 0.00049999918197 0.00049998896747 0.00049987441554 0.00049883319445 0.00049159137515 0.00044974309848 0.00035227207906 0.00024318828592 0.00019253917661 0.00014457807891 0.00012714492989 0.00012532101656 0.00012528782034 0.00012929122544 0.00016226606565 0.00026265281073 0.00042521402321 0.00064581563833 0.00089881680971 0.00095813339831 0.00093194671529 0.0008309815957 0.00064793036606 0.00058008743968 0.00052322077975 0.00050293258677 0.00050031877646 0.00050002798706 0.00050000207821 0.00050000013393 0.00050000000766 0.00050000000036 0.00049999999993 0.0005 0.00050000000001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999703 0.00049999994748 0.00049999918197 0.00049998896747 0.00049987441554 0.00049883319445 0.00049159137515 0.00044974309848 0.00035227207906 0.00024318828592 0.00019253917661 0.00014457807891 0.00012714492989 0.00012532101657 0.00012528782036 0.00012929122546 0.00016226606552 0.00026265281014 0.00042521401864 0.00064581563891 0.00089881681015 0.0009581333983 0.00093194671522 0.00083098159576 0.00064793036602 0.00058008743962 0.00052322077974 0.00050293258677 0.00050031877646 0.00050002798706 0.00050000207821 0.00050000013393 0.00050000000766 0.00050000000036 0.00049999999993 0.0005 0.00050000000001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999703 0.00049999994748 0.00049999918197 0.00049998896747 0.00049987441554 0.00049883319445 0.00049159137515 0.00044974309848 0.00035227207906 0.00024318828592 0.00019253917661 0.00014457807891 0.00012714492989 0.00012532101657 0.00012528782036 0.00012929122548 0.00016226606559 0.0002626528105 0.00042521401933 0.0006458156391 0.00089881681013 0.00095813339828 0.00093194671528 0.00083098159579 0.00064793036602 0.00058008743962 0.00052322077974 0.00050293258677 0.00050031877646 0.00050002798706 0.00050000207821 0.00050000013393 0.00050000000766 0.00050000000036 0.00049999999993 0.0005 0.00050000000001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999703 0.00049999994748 0.00049999918197 0.00049998896747 0.00049987441554 0.00049883319445 0.00049159137515 0.00044974309848 0.00035227207906 0.00024318828592 0.00019253917661 0.00014457807891 0.00012714492989 0.00012532101657 0.00012528782036 0.00012929122548 0.00016226606559 0.00026265281049 0.00042521401946 0.00064581563905 0.00089881681011 0.00095813339828 0.00093194671527 0.00083098159578 0.00064793036602 0.00058008743962 0.00052322077974 0.00050293258677 0.00050031877646 0.00050002798706 0.00050000207821 0.00050000013393 0.00050000000766 0.00050000000036 0.00049999999993 0.0005 0.00050000000001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999703 0.00049999994748 0.00049999918197 0.00049998896747 0.00049987441554 0.00049883319445 0.00049159137515 0.00044974309848 0.00035227207906 0.00024318828592 0.00019253917661 0.00014457807891 0.00012714492989 0.00012532101657 0.00012528782036 0.00012929122548 0.00016226606558 0.00026265281047 0.00042521401941 0.00064581563905 0.00089881681011 0.00095813339828 0.00093194671527 0.00083098159578 0.00064793036602 0.00058008743962 0.00052322077974 0.00050293258677 0.00050031877646 0.00050002798706 0.00050000207821 0.00050000013393 0.00050000000766 0.00050000000036 0.00049999999993 0.0005 0.00050000000001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999703 0.00049999994748 0.00049999918197 0.00049998896747 0.00049987441554 0.00049883319445 0.00049159137515 0.00044974309848 0.00035227207906 0.00024318828592 0.00019253917661 0.00014457807891 0.00012714492989 0.00012532101657 0.00012528782036 0.00012929122548 0.00016226606559 0.00026265281047 0.00042521401941 0.00064581563905 0.00089881681011 0.00095813339828 0.00093194671527 0.00083098159578 0.00064793036602 0.00058008743962 0.00052322077974 0.00050293258677 0.00050031877646 0.00050002798706 0.00050000207821 0.00050000013393 0.00050000000766 0.00050000000036 0.00049999999993 0.0005 0.00050000000001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.0004999999999 0.00049999999703 0.00049999994748 0.00049999918197 0.00049998896747 0.00049987441554 0.00049883319445 0.00049159137515 0.00044974309848 0.00035227207906 0.00024318828592 0.00019253917661 0.00014457807891 0.00012714492989 0.00012532101657 0.00012528782036 0.00012929122548 0.00016226606559 0.00026265281048 0.00042521401941 0.00064581563905 0.00089881681011 0.00095813339828 0.00093194671527 0.00083098159578 0.00064793036602 0.00058008743962 0.00052322077974 0.00050293258677 0.00050031877646 0.00050002798706 0.00050000207821 0.00050000013393 0.00050000000766 0.00050000000036 0.00049999999993 0.0005 0.00050000000001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999703 0.00049999994748 0.00049999918197 0.00049998896747 0.00049987441554 0.00049883319445 0.00049159137515 0.00044974309848 0.00035227207906 0.00024318828592 0.00019253917661 0.00014457807891 0.00012714492989 0.00012532101657 0.00012528782036 0.00012929122548 0.00016226606559 0.00026265281048 0.00042521401941 0.00064581563905 0.00089881681011 0.00095813339828 0.00093194671527 0.00083098159578 0.00064793036602 0.00058008743962 0.00052322077974 0.00050293258677 0.00050031877646 0.00050002798706 0.00050000207821 0.00050000013393 0.00050000000766 0.00050000000036 0.00049999999993 0.0005 0.00050000000001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999703 0.00049999994748 0.00049999918197 0.00049998896747 0.00049987441554 0.00049883319445 0.00049159137515 0.00044974309848 0.00035227207906 0.00024318828592 0.00019253917661 0.00014457807891 0.00012714492989 0.00012532101657 0.00012528782036 0.00012929122548 0.00016226606559 0.00026265281048 0.00042521401941 0.00064581563905 0.00089881681011 0.00095813339828 0.00093194671527 0.00083098159578 0.00064793036602 0.00058008743962 0.00052322077974 0.00050293258677 0.00050031877646 0.00050002798706 0.00050000207821 0.00050000013393 0.00050000000766 0.00050000000036 0.00049999999993 0.0005 0.00050000000001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999703 0.00049999994748 0.00049999918197 0.00049998896747 0.00049987441554 0.00049883319445 0.00049159137515 0.00044974309848 0.00035227207906 0.00024318828592 0.00019253917661 0.00014457807891 0.00012714492989 0.00012532101657 0.00012528782036 0.00012929122548 0.00016226606559 0.00026265281048 0.00042521401941 0.00064581563905 0.00089881681011 0.00095813339828 0.00093194671527 0.00083098159578 0.00064793036602 0.00058008743962 0.00052322077974 0.00050293258677 0.00050031877646 0.00050002798706 0.00050000207821 0.00050000013393 0.00050000000766 0.00050000000036 0.00049999999993 0.0005 0.00050000000001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999703 0.00049999994748 0.00049999918197 0.00049998896747 0.00049987441554 0.00049883319445 0.00049159137515 0.00044974309848 0.00035227207906 0.00024318828592 0.00019253917661 0.00014457807891 0.00012714492989 0.00012532101657 0.00012528782036 0.00012929122548 0.00016226606559 0.00026265281048 0.00042521401941 0.00064581563905 0.00089881681011 0.00095813339828 0.00093194671527 0.00083098159578 0.00064793036602 0.00058008743962 0.00052322077974 0.00050293258677 0.00050031877646 0.00050002798706 0.00050000207821 0.00050000013393 0.00050000000766 0.00050000000036 0.00049999999993 0.0005 0.00050000000001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999703 0.00049999994748 0.00049999918197 0.00049998896747 0.00049987441554 0.00049883319445 0.00049159137515 0.00044974309848 0.00035227207906 0.00024318828592 0.00019253917661 0.00014457807891 0.00012714492989 0.00012532101657 0.00012528782036 0.00012929122548 0.00016226606559 0.00026265281048 0.00042521401941 0.00064581563905 0.00089881681011 0.00095813339828 0.00093194671527 0.00083098159578 0.00064793036602 0.00058008743962 0.00052322077974 0.00050293258677 0.00050031877646 0.00050002798706 0.00050000207821 0.00050000013393 0.00050000000766 0.00050000000036 0.00049999999993 0.0005 0.00050000000001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.0004999999999 0.00049999999703 0.00049999994748 0.00049999918197 0.00049998896747 0.00049987441554 0.00049883319445 0.00049159137515 0.00044974309848 0.00035227207906 0.00024318828592 0.00019253917661 0.00014457807891 0.00012714492989 0.00012532101657 0.00012528782036 0.00012929122548 0.00016226606559 0.00026265281048 0.00042521401941 0.00064581563904 0.00089881681012 0.00095813339828 0.00093194671527 0.00083098159578 0.00064793036602 0.00058008743962 0.00052322077974 0.00050293258677 0.00050031877646 0.00050002798706 0.00050000207821 0.00050000013393 0.00050000000766 0.00050000000036 0.00049999999993 0.0005 0.00050000000001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.0004999999999 0.00049999999703 0.00049999994748 0.00049999918197 0.00049998896747 0.00049987441554 0.00049883319445 0.00049159137515 0.00044974309848 0.00035227207906 0.00024318828592 0.00019253917661 0.00014457807891 0.00012714492989 0.00012532101657 0.00012528782036 0.00012929122548 0.00016226606559 0.00026265281048 0.00042521401941 0.00064581563899 0.00089881681009 0.00095813339829 0.00093194671527 0.00083098159578 0.00064793036602 0.00058008743962 0.00052322077974 0.00050293258677 0.00050031877646 0.00050002798706 0.00050000207821 0.00050000013393 0.00050000000766 0.00050000000036 0.00049999999993 0.0005 0.00050000000001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999703 0.00049999994748 0.00049999918197 0.00049998896747 0.00049987441554 0.00049883319445 0.00049159137515 0.00044974309848 0.00035227207906 0.00024318828592 0.00019253917661 0.00014457807891 0.00012714492989 0.00012532101657 0.00012528782036 0.00012929122548 0.00016226606558 0.00026265281046 0.00042521401935 0.00064581563922 0.00089881681005 0.00095813339824 0.00093194671532 0.00083098159579 0.00064793036601 0.00058008743962 0.00052322077974 0.00050293258677 0.00050031877646 0.00050002798706 0.00050000207821 0.00050000013393 0.00050000000766 0.00050000000036 0.00049999999993 0.0005 0.00050000000001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999703 0.00049999994748 0.00049999918197 0.00049998896747 0.00049987441554 0.00049883319445 0.00049159137515 0.00044974309848 0.00035227207906 0.00024318828592 0.00019253917661 0.00014457807891 0.00012714492989 0.00012532101657 0.00012528782036 0.00012929122548 0.00016226606558 0.00026265281045 0.00042521401953 0.00064581563977 0.00089881681069 0.00095813339824 0.00093194671527 0.00083098159579 0.00064793036596 0.00058008743956 0.00052322077973 0.00050293258677 0.00050031877646 0.00050002798706 0.00050000207821 0.00050000013393 0.00050000000766 0.00050000000036 0.00049999999993 0.0005 0.00050000000001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.0004999999999 0.00049999999703 0.00049999994748 0.00049999918197 0.00049998896747 0.00049987441554 0.00049883319445 0.00049159137515 0.00044974309848 0.00035227207906 0.00024318828592 0.00019253917661 0.00014457807891 0.00012714492989 0.00012532101657 0.00012528782036 0.00012929122547 0.00016226606563 0.00026265281086 0.00042521402019 0.00064581563323 0.0008988168098 0.00095813339913 0.00093194671449 0.0008309815957 0.00064793036631 0.0005800874397 0.0005232207797 0.00050293258676 0.00050031877646 0.00050002798706 0.00050000207821 0.00050000013393 0.00050000000766 0.00050000000036 0.00049999999993 0.0005 0.00050000000001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999703 0.00049999994748 0.00049999918197 0.00049998896747 0.00049987441554 0.00049883319445 0.00049159137515 0.00044974309848 0.00035227207906 0.00024318828592 0.00019253917661 0.00014457807891 0.00012714492989 0.00012532101657 0.00012528782035 0.00012929122545 0.00016226606563 0.00026265280998 0.00042521401487 0.00064581562817 0.00089881679717 0.00095813339658 0.00093194671741 0.00083098159565 0.00064793036645 0.00058008744054 0.00052322077994 0.00050293258673 0.00050031877646 0.00050002798706 0.00050000207821 0.00050000013393 0.00050000000766 0.00050000000036 0.00049999999993 0.0005 0.00050000000001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999703 0.00049999994748 0.00049999918197 0.00049998896747 0.00049987441554 0.00049883319445 0.00049159137515 0.00044974309848 0.00035227207906 0.00024318828592 0.0001925391766 0.00014457807891 0.00012714492989 0.00012532101658 0.00012528782033 0.00012929122559 0.0001622660646 0.00026265280231 0.00042521400819 0.00064581571836 0.00089881682202 0.00095813338187 0.00093194673055 0.00083098159769 0.00064793035849 0.00058008743605 0.00052322078014 0.00050293258691 0.00050031877642 0.00050002798705 0.00050000207821 0.00050000013393 0.00050000000766 0.00050000000036 0.00049999999993 0.0005 0.00050000000001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.0004999999999 0.00049999999703 0.00049999994748 0.00049999918197 0.00049998896747 0.00049987441554 0.00049883319445 0.00049159137515 0.00044974309848 0.00035227207905 0.00024318828592 0.0001925391766 0.00014457807887 0.00012714492988 0.00012532101652 0.00012528782049 0.00012929122563 0.00016226606753 0.00026265281865 0.00042521408152 0.00064581539649 0.00089881688969 0.00095813343287 0.00093194667969 0.00083098160172 0.0006479303583 0.00058008742502 0.00052322077395 0.0005029325872 0.00050031877659 0.00050002798702 0.00050000207821 0.00050000013393 0.00050000000766 0.00050000000036 0.00049999999993 0.0005 0.00050000000001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999703 0.00049999994748 0.00049999918197 0.00049998896747 0.00049987441554 0.00049883319445 0.00049159137515 0.00044974309848 0.00035227207906 0.0002431882859 0.00019253917665 0.00014457807902 0.00012714492996 0.00012532101635 0.00012528782039 0.00012929122331 0.00016226607768 0.00026265286744 0.00042521388571 0.00064580988785 0.0008988156688 0.00095813341628 0.00093194668359 0.00083098155044 0.00064793044666 0.0005800874882 0.00052322077355 0.00050293258125 0.00050031877685 0.00050002798714 0.00050000207819 0.00050000013392 0.00050000000766 0.00050000000036 0.00049999999993 0.0005 0.00050000000001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999703 0.00049999994748 0.00049999918197 0.00049998896747 0.00049987441554 0.00049883319445 0.00049159137514 0.00044974309846 0.00035227207909 0.00024318828601 0.00019253917652 0.00014457807918 0.00012714493007 0.00012532101851 0.00012528781857 0.00012929122685 0.00016226600197 0.0002626518038 0.00042520991125 0.00064571239169 0.00089879595329 0.00095813134309 0.00093194875714 0.00083098169892 0.00064793006995 0.00058008742945 0.00052322085293 0.00050293258021 0.00050031877118 0.00050002798744 0.00050000207827 0.00050000013393 0.00050000000766 0.00050000000036 0.00049999999993 0.0005 0.00050000000001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.0004999999999 0.00049999999703 0.00049999994748 0.00049999918197 0.00049998896747 0.00049987441554 0.00049883319445 0.00049159137516 0.00044974309863 0.00035227207881 0.00024318828582 0.00019253917691 0.00014457807483 0.0001271449267 0.00012532102128 0.00012528782213 0.00012929121659 0.00016226614716 0.00026263789574 0.00042514486556 0.00064414348865 0.00089849309045 0.00095809879864 0.00093198095497 0.00083098513634 0.00064792547032 0.00058008499566 0.00052322046397 0.00050293265818 0.00050031877011 0.00050002798288 0.00050000207841 0.00050000013396 0.00050000000766 0.00050000000036 0.00049999999993 0.0005 0.00050000000001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.0004999999999 0.00049999999703 0.00049999994748 0.00049999918197 0.00049998896747 0.00049987441554 0.00049883319445 0.0004915913752 0.00044974309869 0.00035227207896 0.00024318828151 0.00019253917971 0.00014457807649 0.00012714492987 0.00012532097483 0.00012528779925 0.00012929124916 0.0001622704407 0.00026244462747 0.00042416134488 0.00062230244867 0.00089451642459 0.00095762574529 0.0009324720305 0.00083106450918 0.00064787416358 0.00058004996582 0.00052321447887 0.00050293220127 0.00050031884121 0.00050002797891 0.00050000207557 0.00050000013386 0.00050000000766 0.00050000000036 0.00049999999993 0.0005 0.00050000000001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999703 0.00049999994748 0.00049999918197 0.00049998896747 0.00049987441554 0.00049883319442 0.00049159137469 0.00044974309402 0.00035227208481 0.00024318829086 0.00019253915074 0.00014457813252 0.00012714499001 0.00012532121362 0.00012528790966 0.00012929520723 0.00016239994426 0.00026024857878 0.0004115602869 0.00036565412148 0.0008516259525 0.00095178962946 0.00093900040602 0.00083248247116 0.00064744644864 0.00057956791077 0.00052311937875 0.0005029263013 0.00050031836892 0.00050002803896 0.00050000207046 0.00050000013263 0.00050000000758 0.00050000000036 0.00049999999993 0.0005 0.00050000000001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999703 0.00049999994748 0.00049999918197 0.00049998896747 0.00049987441553 0.00049883319438 0.00049159137414 0.0004497430982 0.00035227207671 0.00024318835522 0.00019253923828 0.00014457742553 0.00012714426592 0.00012532601798 0.00012529073596 0.0001294082984 0.00016510575403 0.00024020621067 0.00027901846296 -0.0020871732815 0.00049607804787 0.00089281750264 0.00101300091015 0.00085244044695 0.00064618788468 0.00057414877152 0.00052187674419 0.00050284607422 0.00050031317313 0.00050002767376 0.0005000021122 0.00050000013395 0.00050000000756 0.00050000000035 0.00049999999993 0.0005 0.00050000000001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999703 0.00049999994748 0.00049999918197 0.00049998896747 0.00049987441557 0.00049883319505 0.00049159138262 0.0004497431492 0.00035227198364 0.0002431875427 0.00019254138075 0.000144566864 0.0001271296077 0.00012542835478 0.00012535207554 0.00013155740302 0.00020898671768 0.0001585785818 -0.00085962504848 -0.0219201003326 -0.00165264617488 0.00041306577731 0.00170425464304 0.00107286065956 0.00066627354657 0.00052526869502 0.00050934246677 0.00050198863551 0.00050025473407 0.00050002424033 0.00050000192258 0.00050000014412 0.00050000000888 0.00050000000039 0.00049999999992 0.00050000000001 0.00050000000001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999703 0.00049999994748 0.00049999918197 0.00049998896747 0.00049987441563 0.00049883319612 0.00049159138964 0.00044974285089 0.00035227295298 0.00024317900299 0.00019257887202 0.00014436936595 0.00012679505823 0.00012723804396 0.00012607131343 0.00016225965296 0.00077559295422 0.00037627069532 -0.00664169840396 -0.09692822491122 -0.00669685912456 -0.00190046797971 0.00694678008702 0.0029489930742 0.00098920389148 0.00026577005448 0.00042168065922 0.00049557529326 0.000499791151 0.00049999552727 0.000500000211 0.00050000006179 0.00050000000857 0.00050000000048 0.0004999999999 0.0005 0.00050000000001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.0004999999999 0.00049999999703 0.00049999994748 0.00049999918197 0.00049998896743 0.00049987441454 0.00049883317316 0.00049159102032 0.00044974041857 0.00035228977572 0.00024312409074 0.00019302666042 0.00014220621951 0.00012285101811 0.00014200779516 0.00013097169196 0.00042505784605 0.00520767172031 0.00464599140185 -0.0164646573092 0.0 0.0 -0.00238098648062 0.02561214840019 0.0174843010501 0.00438912908043 -8.968462902e-05 0.00013754649077 0.00047221439636 0.00049793612889 0.00049987170801 0.00049999284762 0.00049999940773 0.00049999995308 0.00049999999791 0.0005000000003 0.00050000000001 0.00049999999997 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.0004999999999 0.00049999999703 0.00049999994748 0.00049999918197 0.00049998896746 0.00049987441533 0.00049883319066 0.00049159136519 0.00044974335668 0.00035230925494 0.00024314511565 0.00019364554982 0.00014486894622 0.00012229537071 0.00012935005975 0.00015371812806 0.00055617780546 0.00560743638406 0.0 0.0 0.0 0.0 0.0 0.0 0.04757944191431 0.01633435030523 0.00371316705592 0.00059876780326 0.00049882589853 0.00049962570322 0.00049996727997 0.00049999828982 0.00050000011927 0.00049999998963 0.00049999999833 0.00050000000071 0.00049999999995 0.00049999999995 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999703 0.00049999994748 0.000499999182 0.00049998896812 0.00049987442806 0.00049883339802 0.0004915941594 0.00044977723944 0.00035226620976 0.00024324251255 0.00019210857678 0.00015006599772 0.00012367153027 0.00012596846851 0.00011840228865 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.06561311719966 0.03836397342633 0.02445562042836 0.00576289489932 0.00097479988831 0.00054021228734 0.00050288024114 0.00050017944977 0.00050001011642 0.00050000057772 0.0005000000274 0.00049999999345 0.00050000000045 0.00050000000053 0.00049999999996 0.00049999999998 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999703 0.00049999994748 0.00049999918198 0.00049998896763 0.00049987441886 0.00049883325236 0.00049159182775 0.00044974229453 0.00035225941638 0.0002432273315 0.00019235577819 0.00014722726612 0.00012708426979 0.00012615538238 5.723384888e-05 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.05014940764881 0.02667017616768 0.00483173864463 0.00095884539594 0.00054224602849 0.00050325998986 0.00050021675026 0.0005000127152 0.00050000066424 0.00050000002244 0.00049999998956 0.00050000000174 0.0005000000007 0.00049999999989 0.00049999999998 0.00050000000001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999703 0.00049999994747 0.00049999918193 0.00049998896669 0.0004998744005 0.00049883294636 0.00049158828431 0.00044970866796 0.00035229783323 0.00024307986349 0.00019338085518 0.00013849403155 0.00012804638478 0.00012733806777 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.01174734293411 0.00378120342069 0.0011602381397 0.00056207651516 0.00050558762993 0.00050043474966 0.00050002953158 0.00050000164094 0.0005000000726 0.0004999999983 0.00049999999772 0.00050000000071 0.0005000000001 0.00049999999996 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999703 0.00049999994748 0.00049999918195 0.00049998896708 0.00049987440741 0.00049883304962 0.00049158921534 0.00044971775989 0.0003522907976 0.00024308998213 0.00019318831176 0.00014028958842 0.00012723771752 0.00013032216398 0.0 0.0 0.0 0.0 0.0 +D/cons.2.00.000050.dat 0.0 0.0 0.0 0.0 0.0 -0.01432163110564 -0.0060421031393 -0.00053292310506 0.00038875051231 0.000489731076 0.00049920889572 0.00049994760845 0.00049999696879 0.00049999986347 0.00050000000339 0.00050000000365 0.00049999999879 0.00049999999983 0.00050000000006 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999703 0.00049999994748 0.00049999918197 0.00049998896744 0.00049987441526 0.00049883319798 0.00049159134174 0.00044974054465 0.00035224551313 0.00024326640117 0.0001922703913 0.00014900647414 0.00012888325862 0.00011989630684 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 -0.03705376624279 -0.01959752193492 -0.00329309746997 0.00011588246081 0.00046484017512 0.00049729180828 0.00049981974587 0.00049998937221 0.00049999940856 0.00049999997585 0.00050000000894 0.0004999999988 0.00049999999938 0.00050000000008 0.00050000000002 0.00049999999999 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999703 0.00049999994747 0.00049999918195 0.00049998896709 0.00049987440824 0.00049883307719 0.00049159023912 0.00044973372772 0.00035227347799 0.00024316260212 0.0001927212351 0.00014461878434 0.00013088029345 0.00012358457775 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 -0.09741391402673 -0.04274563454263 -0.02378299139823 -0.00461661170363 2.871775001e-05 0.00045965921663 0.00049707847084 0.00049981655867 0.00049998973884 0.00049999944907 0.00049999997405 0.00050000000628 0.00049999999956 0.0004999999995 0.00050000000004 0.00050000000002 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999703 0.00049999994748 0.00049999918197 0.00049998896755 0.00049987441677 0.00049883320676 0.00049159151132 0.00044974552644 0.0003522752539 0.00024316626684 0.00019294048929 0.00014358593599 0.00012785036207 0.00012588616899 9.630097776e-05 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 -0.05668464476674 -0.02033766676665 -0.00480548545562 0.00026338938519 0.00048908658052 0.000499822988 0.00050002444688 0.00050000266969 0.00050000001221 0.00050000001212 0.00050000000167 0.00049999999932 0.00050000000005 0.00050000000005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999703 0.00049999994748 0.00049999918199 0.00049998896802 0.00049987442654 0.00049883337832 0.00049159348196 0.00044976452966 0.00035226507118 0.00024322859854 0.00019207674056 0.00014353803244 0.0001234204676 0.00012672691267 7.663096583e-05 0.0 0.0 0.0 0.0 0.0 0.0 0.00320359405583 -0.02504708407512 -0.01918063705468 -0.00522120833689 0.00077507041285 0.00086237145056 0.00053035540099 0.00050247568463 0.0005001706165 0.00050001053393 0.00050000080768 0.00050000006064 0.00050000000277 0.00049999999956 0.0005 0.00050000000004 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999703 0.00049999994748 0.00049999918197 0.00049998896759 0.00049987441816 0.00049883324438 0.00049159227549 0.00044975580724 0.00035224946732 0.000243257642 0.0001909464657 0.00014478632718 0.00013256716049 0.0001202589274 9.369134514e-05 -0.00039775000242 -0.00546501594161 0.0 0.0 0.09744920748275 0.00741325612019 0.00332980424034 -0.00587639364127 -0.00178892971534 2.43223836e-05 0.0008289075732 0.00062375397074 0.00051021014494 0.00050084340682 0.00050006028769 0.00050000393958 0.00050000020807 0.00050000000715 0.00050000000024 0.00049999999996 0.00050000000001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999703 0.00049999994748 0.00049999918197 0.00049998896753 0.00049987441683 0.00049883321848 0.00049159180491 0.00044974776051 0.00035224275386 0.00024326741546 0.00019173466549 0.00014629287999 0.00013147811575 0.00010576633438 0.00011617136939 -0.00023848592197 -0.00499115776482 -0.00440869136694 0.01680453038225 0.02269919168666 0.00291322913295 0.00139602063098 4.86213527e-06 0.0005180671794 0.00058955043853 0.00063888781819 0.00053873679966 0.00050399005649 0.00050039065694 0.00050003215587 0.00050000226542 0.00050000012684 0.00050000000654 0.00050000000033 0.00049999999995 0.0005 0.00050000000001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999703 0.00049999994748 0.00049999918197 0.00049998896747 0.00049987441556 0.00049883319513 0.00049159138867 0.00044974373672 0.00035226816165 0.00024320379215 0.00019245012037 0.00014477309137 0.00012749927071 0.000122776701 0.00012372103264 8.179438305e-05 -0.00048816091193 -5.862022714e-05 0.00724088338917 0.00328160307352 0.00121782572953 0.00100737354333 0.00082923685626 0.00080065639923 0.00064475400169 0.00058659275451 0.00052489629032 0.00050304074371 0.0005003257345 0.00050002838975 0.00050000204811 0.00050000013358 0.00050000000773 0.00050000000036 0.00049999999993 0.0005 0.00050000000001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999703 0.00049999994748 0.00049999918197 0.00049998896747 0.00049987441553 0.00049883319434 0.0004915913725 0.00044974305726 0.00035227195145 0.00024318960814 0.00019253201254 0.00014458861153 0.00012716427009 0.0001251603493 0.00012510683719 0.00012523328378 0.00010843637255 0.00032341641351 0.00163535805328 0.00091113961573 0.00093546807466 0.00096264009016 0.00092269284726 0.0008285319885 0.00064790357835 0.00058068847582 0.0005233607478 0.00050294121673 0.00050031934777 0.00050002793895 0.00050000208522 0.00050000013514 0.00050000000774 0.00050000000036 0.00049999999993 0.0005 0.00050000000001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999703 0.00049999994748 0.00049999918197 0.00049998896747 0.00049987441554 0.0004988331945 0.0004915913763 0.00044974309354 0.00035227212758 0.00024318827589 0.00019253854251 0.00014457874941 0.00012714610906 0.0001253120503 0.00012527277609 0.00012900066729 0.00015843512691 0.00027683553634 0.00056116281844 0.00066766670342 0.00090207728644 0.00095847536266 0.0009312459891 0.0008308131992 0.00064794553475 0.00058013287217 0.00052323048843 0.00050293320225 0.00050031871748 0.00050002799331 0.00050000208086 0.00050000013401 0.00050000000766 0.00050000000036 0.00049999999993 0.0005 0.00050000000001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.0004999999999 0.00049999999703 0.00049999994748 0.00049999918197 0.00049998896747 0.00049987441554 0.00049883319449 0.00049159137568 0.0004497431053 0.00035227207201 0.00024318826331 0.00019253923897 0.00014457803117 0.00012714488943 0.00012532049218 0.00012528667829 0.0001292734603 0.00016203531994 0.0002643354818 0.00043767349264 0.00064733885807 0.00089905550483 0.00095815567636 0.00093190103498 0.00083097143469 0.00064793249437 0.00058009048646 0.00052322139496 0.0005029325194 0.00050031877882 0.00050002799169 0.00050000207807 0.00050000013389 0.00050000000766 0.00050000000036 0.00049999999993 0.0005 0.00050000000001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.0004999999999 0.00049999999703 0.00049999994748 0.00049999918197 0.00049998896747 0.00049987441554 0.00049883319445 0.00049159137517 0.00044974309932 0.00035227207583 0.00024318829393 0.00019253917782 0.00014457807488 0.00012714492283 0.00012532107855 0.00012528785787 0.00012929018602 0.00016225434619 0.00026280343747 0.0004261561147 0.00064590777671 0.0008988317407 0.00095813468633 0.00093194405552 0.00083098108486 0.00064793036557 0.00058008749741 0.0005232207057 0.00050293258766 0.0005003187827 0.00050002798679 0.00050000207815 0.00050000013393 0.00050000000766 0.00050000000036 0.00049999999993 0.0005 0.00050000000001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999703 0.00049999994748 0.00049999918197 0.00049998896747 0.00049987441554 0.00049883319445 0.00049159137513 0.00044974309829 0.00035227207948 0.00024318828778 0.00019253917024 0.00014457808264 0.00012714493671 0.00012532101314 0.00012528782985 0.00012929127536 0.0001622654133 0.00026266370687 0.00042527473313 0.00064582068344 0.00089881760151 0.00095813333332 0.00093194670195 0.00083098170685 0.0006479303256 0.00058008738182 0.00052322077834 0.00050293259373 0.00050031877628 0.00050002798695 0.00050000207822 0.00050000013393 0.00050000000766 0.00050000000036 0.00049999999993 0.0005 0.00050000000001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999703 0.00049999994748 0.00049999918197 0.00049998896747 0.00049987441554 0.00049883319445 0.00049159137515 0.00044974309846 0.00035227207912 0.00024318828551 0.0001925391765 0.00014457807925 0.00012714493021 0.00012532101209 0.00012528781329 0.00012929123001 0.00016226612172 0.00026265352955 0.000425217584 0.00064581583121 0.00089881671562 0.00095813338098 0.00093194676209 0.00083098159014 0.00064793037827 0.00058008745349 0.00052322078737 0.00050293258658 0.00050031877629 0.00050002798709 0.00050000207821 0.00050000013393 0.00050000000766 0.00050000000036 0.00049999999993 0.0005 0.00050000000001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999703 0.00049999994748 0.00049999918197 0.00049998896747 0.00049987441554 0.00049883319445 0.00049159137515 0.00044974309849 0.00035227207903 0.00024318828588 0.00019253917689 0.00014457807879 0.00012714492958 0.00012532101683 0.00012528781986 0.00012929121877 0.0001622660599 0.00026265274663 0.00042521411131 0.00064581556672 0.00089881680615 0.00095813341111 0.00093194669919 0.00083098158501 0.00064793036948 0.00058008744396 0.00052322077975 0.00050293258656 0.0005003187765 0.00050002798706 0.00050000207821 0.00050000013393 0.00050000000766 0.00050000000036 0.00049999999993 0.0005 0.00050000000001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999703 0.00049999994748 0.00049999918197 0.00049998896747 0.00049987441554 0.00049883319445 0.00049159137515 0.00044974309848 0.00035227207906 0.00024318828595 0.00019253917657 0.0001445780789 0.00012714492992 0.00012532101672 0.0001252878207 0.00012929122536 0.00016226606149 0.00026265280725 0.00042521396468 0.00064581565047 0.00089881682048 0.00095813339898 0.00093194671244 0.00083098159633 0.0006479303654 0.00058008743875 0.00052322077945 0.00050293258681 0.00050031877647 0.00050002798705 0.00050000207821 0.00050000013393 0.00050000000766 0.00050000000036 0.00049999999993 0.0005 0.00050000000001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999703 0.00049999994748 0.00049999918197 0.00049998896747 0.00049987441554 0.00049883319445 0.00049159137515 0.00044974309848 0.00035227207906 0.00024318828592 0.00019253917659 0.00014457807892 0.0001271449299 0.00012532101653 0.00012528782033 0.0001292912258 0.0001622660663 0.00026265281763 0.0004252140312 0.00064581564418 0.00089881681016 0.00095813339774 0.00093194671615 0.00083098159624 0.00064793036593 0.00058008743951 0.00052322077977 0.00050293258677 0.00050031877646 0.00050002798706 0.00050000207821 0.00050000013393 0.00050000000766 0.00050000000036 0.00049999999993 0.0005 0.00050000000001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999703 0.00049999994748 0.00049999918197 0.00049998896747 0.00049987441554 0.00049883319445 0.00049159137515 0.00044974309848 0.00035227207905 0.00024318828592 0.00019253917661 0.00014457807891 0.00012714492989 0.00012532101656 0.00012528782034 0.00012929122544 0.00016226606565 0.00026265281073 0.00042521402321 0.00064581563833 0.00089881680971 0.00095813339831 0.00093194671529 0.0008309815957 0.00064793036606 0.00058008743968 0.00052322077975 0.00050293258677 0.00050031877646 0.00050002798706 0.00050000207821 0.00050000013393 0.00050000000766 0.00050000000036 0.00049999999993 0.0005 0.00050000000001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999703 0.00049999994748 0.00049999918197 0.00049998896747 0.00049987441554 0.00049883319445 0.00049159137515 0.00044974309848 0.00035227207906 0.00024318828592 0.00019253917661 0.00014457807891 0.00012714492989 0.00012532101657 0.00012528782036 0.00012929122546 0.00016226606552 0.00026265281014 0.00042521401864 0.00064581563891 0.00089881681015 0.0009581333983 0.00093194671522 0.00083098159576 0.00064793036602 0.00058008743962 0.00052322077974 0.00050293258677 0.00050031877646 0.00050002798706 0.00050000207821 0.00050000013393 0.00050000000766 0.00050000000036 0.00049999999993 0.0005 0.00050000000001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999703 0.00049999994748 0.00049999918197 0.00049998896747 0.00049987441554 0.00049883319445 0.00049159137515 0.00044974309848 0.00035227207906 0.00024318828592 0.00019253917661 0.00014457807891 0.00012714492989 0.00012532101657 0.00012528782036 0.00012929122548 0.00016226606559 0.0002626528105 0.00042521401933 0.0006458156391 0.00089881681013 0.00095813339828 0.00093194671528 0.00083098159579 0.00064793036602 0.00058008743962 0.00052322077974 0.00050293258677 0.00050031877646 0.00050002798706 0.00050000207821 0.00050000013393 0.00050000000766 0.00050000000036 0.00049999999993 0.0005 0.00050000000001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.0004999999999 0.00049999999703 0.00049999994748 0.00049999918197 0.00049998896747 0.00049987441554 0.00049883319445 0.00049159137515 0.00044974309848 0.00035227207906 0.00024318828592 0.00019253917661 0.00014457807891 0.00012714492989 0.00012532101657 0.00012528782036 0.00012929122548 0.00016226606559 0.00026265281049 0.00042521401946 0.00064581563905 0.00089881681011 0.00095813339828 0.00093194671527 0.00083098159578 0.00064793036602 0.00058008743962 0.00052322077974 0.00050293258677 0.00050031877646 0.00050002798706 0.00050000207821 0.00050000013393 0.00050000000766 0.00050000000036 0.00049999999993 0.0005 0.00050000000001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999703 0.00049999994748 0.00049999918197 0.00049998896747 0.00049987441554 0.00049883319445 0.00049159137515 0.00044974309848 0.00035227207906 0.00024318828592 0.00019253917661 0.00014457807891 0.00012714492989 0.00012532101657 0.00012528782036 0.00012929122548 0.00016226606558 0.00026265281047 0.00042521401941 0.00064581563905 0.00089881681011 0.00095813339828 0.00093194671527 0.00083098159578 0.00064793036602 0.00058008743962 0.00052322077974 0.00050293258677 0.00050031877646 0.00050002798706 0.00050000207821 0.00050000013393 0.00050000000766 0.00050000000036 0.00049999999993 0.0005 0.00050000000001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999703 0.00049999994748 0.00049999918197 0.00049998896747 0.00049987441554 0.00049883319445 0.00049159137515 0.00044974309848 0.00035227207906 0.00024318828592 0.00019253917661 0.00014457807891 0.00012714492989 0.00012532101657 0.00012528782036 0.00012929122548 0.00016226606559 0.00026265281048 0.00042521401941 0.00064581563905 0.00089881681011 0.00095813339828 0.00093194671527 0.00083098159578 0.00064793036602 0.00058008743962 0.00052322077974 0.00050293258677 0.00050031877646 0.00050002798706 0.00050000207821 0.00050000013393 0.00050000000766 0.00050000000036 0.00049999999993 0.0005 0.00050000000001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.0004999999999 0.00049999999703 0.00049999994748 0.00049999918197 0.00049998896747 0.00049987441554 0.00049883319445 0.00049159137515 0.00044974309848 0.00035227207906 0.00024318828592 0.00019253917661 0.00014457807891 0.00012714492989 0.00012532101657 0.00012528782036 0.00012929122548 0.00016226606559 0.00026265281048 0.00042521401941 0.00064581563905 0.00089881681011 0.00095813339828 0.00093194671527 0.00083098159578 0.00064793036602 0.00058008743962 0.00052322077974 0.00050293258677 0.00050031877646 0.00050002798706 0.00050000207821 0.00050000013393 0.00050000000766 0.00050000000036 0.00049999999993 0.0005 0.00050000000001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999703 0.00049999994748 0.00049999918197 0.00049998896747 0.00049987441554 0.00049883319445 0.00049159137515 0.00044974309848 0.00035227207906 0.00024318828592 0.00019253917661 0.00014457807891 0.00012714492989 0.00012532101657 0.00012528782036 0.00012929122548 0.00016226606559 0.00026265281048 0.00042521401941 0.00064581563905 0.00089881681011 0.00095813339828 0.00093194671527 0.00083098159578 0.00064793036602 0.00058008743962 0.00052322077974 0.00050293258677 0.00050031877646 0.00050002798706 0.00050000207821 0.00050000013393 0.00050000000766 0.00050000000036 0.00049999999993 0.0005 0.00050000000001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999703 0.00049999994748 0.00049999918197 0.00049998896747 0.00049987441554 0.00049883319445 0.00049159137515 0.00044974309848 0.00035227207906 0.00024318828592 0.00019253917661 0.00014457807891 0.00012714492989 0.00012532101657 0.00012528782036 0.00012929122548 0.00016226606559 0.00026265281048 0.00042521401941 0.00064581563905 0.00089881681011 0.00095813339828 0.00093194671527 0.00083098159578 0.00064793036602 0.00058008743962 0.00052322077974 0.00050293258677 0.00050031877646 0.00050002798706 0.00050000207821 0.00050000013393 0.00050000000766 0.00050000000036 0.00049999999993 0.0005 0.00050000000001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999703 0.00049999994748 0.00049999918197 0.00049998896747 0.00049987441554 0.00049883319445 0.00049159137515 0.00044974309848 0.00035227207906 0.00024318828592 0.00019253917661 0.00014457807891 0.00012714492989 0.00012532101657 0.00012528782036 0.00012929122548 0.00016226606559 0.00026265281048 0.00042521401941 0.00064581563905 0.00089881681011 0.00095813339828 0.00093194671527 0.00083098159578 0.00064793036602 0.00058008743962 0.00052322077974 0.00050293258677 0.00050031877646 0.00050002798706 0.00050000207821 0.00050000013393 0.00050000000766 0.00050000000036 0.00049999999993 0.0005 0.00050000000001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999703 0.00049999994748 0.00049999918197 0.00049998896747 0.00049987441554 0.00049883319445 0.00049159137515 0.00044974309848 0.00035227207906 0.00024318828592 0.00019253917661 0.00014457807891 0.00012714492989 0.00012532101657 0.00012528782036 0.00012929122548 0.00016226606559 0.00026265281048 0.00042521401941 0.00064581563905 0.00089881681011 0.00095813339828 0.00093194671527 0.00083098159578 0.00064793036602 0.00058008743962 0.00052322077974 0.00050293258677 0.00050031877646 0.00050002798706 0.00050000207821 0.00050000013393 0.00050000000766 0.00050000000036 0.00049999999993 0.0005 0.00050000000001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999703 0.00049999994748 0.00049999918197 0.00049998896747 0.00049987441554 0.00049883319445 0.00049159137515 0.00044974309848 0.00035227207906 0.00024318828592 0.00019253917661 0.00014457807891 0.00012714492989 0.00012532101657 0.00012528782036 0.00012929122548 0.00016226606559 0.00026265281048 0.00042521401941 0.00064581563905 0.00089881681011 0.00095813339828 0.00093194671527 0.00083098159578 0.00064793036602 0.00058008743962 0.00052322077974 0.00050293258677 0.00050031877646 0.00050002798706 0.00050000207821 0.00050000013393 0.00050000000766 0.00050000000036 0.00049999999993 0.0005 0.00050000000001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.0004999999999 0.00049999999703 0.00049999994748 0.00049999918197 0.00049998896747 0.00049987441554 0.00049883319445 0.00049159137515 0.00044974309848 0.00035227207906 0.00024318828592 0.00019253917661 0.00014457807891 0.00012714492989 0.00012532101657 0.00012528782036 0.00012929122548 0.00016226606559 0.00026265281048 0.00042521401941 0.00064581563904 0.00089881681012 0.00095813339828 0.00093194671527 0.00083098159578 0.00064793036602 0.00058008743962 0.00052322077974 0.00050293258677 0.00050031877646 0.00050002798706 0.00050000207821 0.00050000013393 0.00050000000766 0.00050000000036 0.00049999999993 0.0005 0.00050000000001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999703 0.00049999994748 0.00049999918197 0.00049998896747 0.00049987441554 0.00049883319445 0.00049159137515 0.00044974309848 0.00035227207906 0.00024318828592 0.00019253917661 0.00014457807891 0.00012714492989 0.00012532101657 0.00012528782036 0.00012929122548 0.00016226606559 0.00026265281048 0.00042521401941 0.00064581563899 0.00089881681009 0.00095813339829 0.00093194671527 0.00083098159578 0.00064793036602 0.00058008743962 0.00052322077974 0.00050293258677 0.00050031877646 0.00050002798706 0.00050000207821 0.00050000013393 0.00050000000766 0.00050000000036 0.00049999999993 0.0005 0.00050000000001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999703 0.00049999994748 0.00049999918197 0.00049998896747 0.00049987441554 0.00049883319445 0.00049159137515 0.00044974309848 0.00035227207906 0.00024318828592 0.00019253917661 0.00014457807891 0.00012714492989 0.00012532101657 0.00012528782036 0.00012929122548 0.00016226606558 0.00026265281046 0.00042521401935 0.00064581563922 0.00089881681005 0.00095813339824 0.00093194671532 0.00083098159579 0.00064793036601 0.00058008743962 0.00052322077974 0.00050293258677 0.00050031877646 0.00050002798706 0.00050000207821 0.00050000013393 0.00050000000766 0.00050000000036 0.00049999999993 0.0005 0.00050000000001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999703 0.00049999994748 0.00049999918197 0.00049998896747 0.00049987441554 0.00049883319445 0.00049159137515 0.00044974309848 0.00035227207906 0.00024318828592 0.00019253917661 0.00014457807891 0.00012714492989 0.00012532101657 0.00012528782036 0.00012929122548 0.00016226606558 0.00026265281045 0.00042521401953 0.00064581563977 0.00089881681069 0.00095813339824 0.00093194671527 0.00083098159579 0.00064793036596 0.00058008743956 0.00052322077973 0.00050293258677 0.00050031877646 0.00050002798706 0.00050000207821 0.00050000013393 0.00050000000766 0.00050000000036 0.00049999999993 0.0005 0.00050000000001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999703 0.00049999994748 0.00049999918197 0.00049998896747 0.00049987441554 0.00049883319445 0.00049159137515 0.00044974309848 0.00035227207906 0.00024318828592 0.00019253917661 0.00014457807891 0.00012714492989 0.00012532101657 0.00012528782036 0.00012929122547 0.00016226606563 0.00026265281086 0.00042521402019 0.00064581563323 0.0008988168098 0.00095813339913 0.00093194671449 0.0008309815957 0.00064793036631 0.0005800874397 0.0005232207797 0.00050293258676 0.00050031877646 0.00050002798706 0.00050000207821 0.00050000013393 0.00050000000766 0.00050000000036 0.00049999999993 0.0005 0.00050000000001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999703 0.00049999994748 0.00049999918197 0.00049998896747 0.00049987441554 0.00049883319445 0.00049159137515 0.00044974309848 0.00035227207906 0.00024318828592 0.00019253917661 0.00014457807891 0.00012714492989 0.00012532101657 0.00012528782035 0.00012929122545 0.00016226606563 0.00026265280998 0.00042521401487 0.00064581562817 0.00089881679717 0.00095813339658 0.00093194671741 0.00083098159565 0.00064793036645 0.00058008744054 0.00052322077994 0.00050293258673 0.00050031877646 0.00050002798706 0.00050000207821 0.00050000013393 0.00050000000766 0.00050000000036 0.00049999999993 0.0005 0.00050000000001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999703 0.00049999994748 0.00049999918197 0.00049998896747 0.00049987441554 0.00049883319445 0.00049159137515 0.00044974309848 0.00035227207906 0.00024318828592 0.0001925391766 0.00014457807891 0.00012714492989 0.00012532101658 0.00012528782033 0.00012929122559 0.0001622660646 0.00026265280231 0.00042521400819 0.00064581571836 0.00089881682202 0.00095813338187 0.00093194673055 0.00083098159769 0.00064793035849 0.00058008743605 0.00052322078014 0.00050293258691 0.00050031877642 0.00050002798705 0.00050000207821 0.00050000013393 0.00050000000766 0.00050000000036 0.00049999999993 0.0005 0.00050000000001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.0004999999999 0.00049999999703 0.00049999994748 0.00049999918197 0.00049998896747 0.00049987441554 0.00049883319445 0.00049159137515 0.00044974309848 0.00035227207905 0.00024318828592 0.0001925391766 0.00014457807887 0.00012714492988 0.00012532101652 0.00012528782049 0.00012929122563 0.00016226606753 0.00026265281865 0.00042521408152 0.00064581539649 0.00089881688969 0.00095813343287 0.00093194667969 0.00083098160172 0.0006479303583 0.00058008742502 0.00052322077395 0.0005029325872 0.00050031877659 0.00050002798702 0.00050000207821 0.00050000013393 0.00050000000766 0.00050000000036 0.00049999999993 0.0005 0.00050000000001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999703 0.00049999994748 0.00049999918197 0.00049998896747 0.00049987441554 0.00049883319445 0.00049159137515 0.00044974309848 0.00035227207906 0.0002431882859 0.00019253917665 0.00014457807902 0.00012714492996 0.00012532101635 0.00012528782039 0.00012929122331 0.00016226607768 0.00026265286744 0.00042521388571 0.00064580988785 0.0008988156688 0.00095813341628 0.00093194668359 0.00083098155044 0.00064793044666 0.0005800874882 0.00052322077355 0.00050293258125 0.00050031877685 0.00050002798714 0.00050000207819 0.00050000013392 0.00050000000766 0.00050000000036 0.00049999999993 0.0005 0.00050000000001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999703 0.00049999994748 0.00049999918197 0.00049998896747 0.00049987441554 0.00049883319445 0.00049159137514 0.00044974309846 0.00035227207909 0.00024318828601 0.00019253917652 0.00014457807918 0.00012714493007 0.00012532101851 0.00012528781857 0.00012929122685 0.00016226600197 0.0002626518038 0.00042520991125 0.00064571239169 0.00089879595329 0.00095813134309 0.00093194875714 0.00083098169892 0.00064793006995 0.00058008742945 0.00052322085293 0.00050293258021 0.00050031877118 0.00050002798744 0.00050000207827 0.00050000013393 0.00050000000766 0.00050000000036 0.00049999999993 0.0005 0.00050000000001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.0004999999999 0.00049999999703 0.00049999994748 0.00049999918197 0.00049998896747 0.00049987441554 0.00049883319445 0.00049159137516 0.00044974309863 0.00035227207881 0.00024318828582 0.00019253917691 0.00014457807483 0.0001271449267 0.00012532102128 0.00012528782213 0.00012929121659 0.00016226614716 0.00026263789574 0.00042514486556 0.00064414348865 0.00089849309045 0.00095809879864 0.00093198095497 0.00083098513634 0.00064792547032 0.00058008499566 0.00052322046397 0.00050293265818 0.00050031877011 0.00050002798288 0.00050000207841 0.00050000013396 0.00050000000766 0.00050000000036 0.00049999999993 0.0005 0.00050000000001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.0004999999999 0.00049999999703 0.00049999994748 0.00049999918197 0.00049998896747 0.00049987441554 0.00049883319445 0.0004915913752 0.00044974309869 0.00035227207896 0.00024318828151 0.00019253917971 0.00014457807649 0.00012714492987 0.00012532097483 0.00012528779925 0.00012929124916 0.0001622704407 0.00026244462747 0.00042416134488 0.00062230244867 0.00089451642459 0.00095762574529 0.0009324720305 0.00083106450918 0.00064787416358 0.00058004996583 0.00052321447887 0.00050293220127 0.00050031884121 0.00050002797891 0.00050000207557 0.00050000013386 0.00050000000766 0.00050000000036 0.00049999999993 0.0005 0.00050000000001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999703 0.00049999994748 0.00049999918197 0.00049998896747 0.00049987441554 0.00049883319442 0.00049159137469 0.00044974309402 0.00035227208481 0.00024318829086 0.00019253915074 0.00014457813252 0.00012714499001 0.00012532121362 0.00012528790966 0.00012929520723 0.00016239994426 0.00026024857878 0.0004115602869 0.00036565412148 0.0008516259525 0.00095178962946 0.00093900040602 0.00083248247116 0.00064744644864 0.00057956791077 0.00052311937875 0.0005029263013 0.00050031836892 0.00050002803896 0.00050000207046 0.00050000013263 0.00050000000758 0.00050000000036 0.00049999999993 0.0005 0.00050000000001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999703 0.00049999994748 0.00049999918197 0.00049998896747 0.00049987441553 0.00049883319438 0.00049159137414 0.0004497430982 0.00035227207671 0.00024318835522 0.00019253923828 0.00014457742553 0.00012714426592 0.00012532601798 0.00012529073596 0.0001294082984 0.00016510575403 0.00024020621067 0.00027901846296 -0.0020871732815 0.00049607804787 0.00089281750264 0.00101300091015 0.00085244044695 0.00064618788468 0.00057414877152 0.00052187674419 0.00050284607422 0.00050031317313 0.00050002767376 0.0005000021122 0.00050000013395 0.00050000000756 0.00050000000035 0.00049999999993 0.0005 0.00050000000001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999703 0.00049999994748 0.00049999918197 0.00049998896747 0.00049987441557 0.00049883319505 0.00049159138262 0.0004497431492 0.00035227198364 0.0002431875427 0.00019254138075 0.000144566864 0.0001271296077 0.00012542835478 0.00012535207554 0.00013155740302 0.00020898671768 0.0001585785818 -0.00085962504848 -0.0219201003326 -0.00165264617488 0.00041306577731 0.00170425464304 0.00107286065956 0.00066627354657 0.00052526869502 0.00050934246677 0.00050198863551 0.00050025473407 0.00050002424033 0.00050000192258 0.00050000014412 0.00050000000888 0.00050000000039 0.00049999999992 0.00050000000001 0.00050000000001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999703 0.00049999994748 0.00049999918197 0.00049998896747 0.00049987441563 0.00049883319612 0.00049159138964 0.00044974285089 0.00035227295298 0.00024317900299 0.00019257887202 0.00014436936595 0.00012679505823 0.00012723804396 0.00012607131343 0.00016225965296 0.00077559295422 0.00037627069532 -0.00664169840396 -0.09692822491122 -0.00669685912456 -0.00190046797971 0.00694678008702 0.0029489930742 0.00098920389148 0.00026577005448 0.00042168065922 0.00049557529326 0.000499791151 0.00049999552727 0.000500000211 0.00050000006179 0.00050000000857 0.00050000000048 0.0004999999999 0.0005 0.00050000000001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.0004999999999 0.00049999999703 0.00049999994748 0.00049999918197 0.00049998896743 0.00049987441454 0.00049883317316 0.00049159102032 0.00044974041857 0.00035228977572 0.00024312409074 0.00019302666042 0.00014220621951 0.00012285101811 0.00014200779516 0.00013097169196 0.00042505784605 0.00520767172031 0.00464599140185 -0.0164646573092 0.0 0.0 -0.00238098648062 0.02561214840019 0.0174843010501 0.00438912908043 -8.968462902e-05 0.00013754649077 0.00047221439636 0.00049793612889 0.00049987170801 0.00049999284762 0.00049999940773 0.00049999995308 0.00049999999791 0.0005000000003 0.00050000000001 0.00049999999997 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.0004999999999 0.00049999999703 0.00049999994748 0.00049999918197 0.00049998896746 0.00049987441533 0.00049883319066 0.00049159136519 0.00044974335668 0.00035230925494 0.00024314511565 0.00019364554982 0.00014486894622 0.00012229537071 0.00012935005975 0.00015371812806 0.00055617780546 0.00560743638406 0.0 0.0 0.0 0.0 0.0 0.0 0.04757944191431 0.01633435030523 0.00371316705592 0.00059876780326 0.00049882589853 0.00049962570322 0.00049996727997 0.00049999828982 0.00050000011927 0.00049999998963 0.00049999999833 0.00050000000071 0.00049999999995 0.00049999999995 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999703 0.00049999994748 0.000499999182 0.00049998896812 0.00049987442806 0.00049883339802 0.0004915941594 0.00044977723944 0.00035226620976 0.00024324251255 0.00019210857678 0.00015006599772 0.00012367153027 0.00012596846851 0.00011840228865 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.06561311719966 0.03836397342633 0.02445562042836 0.00576289489932 0.00097479988831 0.00054021228734 0.00050288024114 0.00050017944977 0.00050001011642 0.00050000057772 0.0005000000274 0.00049999999345 0.00050000000045 0.00050000000053 0.00049999999996 0.00049999999998 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999703 0.00049999994748 0.00049999918198 0.00049998896763 0.00049987441886 0.00049883325236 0.00049159182775 0.00044974229453 0.00035225941638 0.0002432273315 0.00019235577819 0.00014722726612 0.00012708426979 0.00012615538238 5.723384888e-05 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.05014940764881 0.02667017616768 0.00483173864463 0.00095884539594 0.00054224602849 0.00050325998986 0.00050021675026 0.0005000127152 0.00050000066424 0.00050000002244 0.00049999998956 0.00050000000174 0.0005000000007 0.00049999999989 0.00049999999998 0.00050000000001 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999703 0.00049999994747 0.00049999918193 0.00049998896669 0.0004998744005 0.00049883294636 0.00049158828431 0.00044970866796 0.00035229783323 0.00024307986349 0.00019338085518 0.00013849403155 0.00012804638478 0.00012733806777 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.01174734293411 0.00378120342069 0.0011602381397 0.00056207651516 0.00050558762993 0.00050043474966 0.00050002953158 0.00050000164094 0.0005000000726 0.0004999999983 0.00049999999772 0.00050000000071 0.0005000000001 0.00049999999996 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.0005 0.00049999999999 0.00050000000005 0.00049999999991 0.00049999999703 0.00049999994748 0.00049999918195 0.00049998896708 0.00049987440741 0.00049883304962 0.00049158921534 0.00044971775989 0.0003522907976 0.00024308998213 0.00019318831176 0.00014028958842 0.00012723771752 0.00013032216398 0.0 0.0 0.0 0.0 0.0 D/cons.3.00.000000.dat 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 -D/cons.3.00.000050.dat 0.0 0.0 0.0 0.0 0.0 0.03174808335338 0.01345420708904 0.00293100450106 0.00039786317896 4.369980519e-05 3.91923991e-06 2.9685443e-07 1.946492e-08 1.20196e-09 -7.466e-11 -1.652e-11 1.284e-11 7.2e-13 -6.8e-13 5e-14 3e-14 -1e-14 -0.0 -0.0 6e-14 -9e-14 -8.5e-13 4.1e-12 1.271e-11 -5.753e-11 9.938e-11 3.62365e-09 6.216589e-08 9.6787535e-07 1.305359006e-05 0.0001485614105 0.00137807763111 0.00984084254932 0.0555012747518 0.14652419179682 0.16793187018781 0.092003603696 0.02400963377805 0.00236863807335 0.00030572819805 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.04126976969797 0.02335115363958 0.00677349131879 0.00090004423485 0.00010263616427 9.41031102e-06 7.241786e-07 4.797885e-08 2.86937e-09 5.128e-11 -4.751e-11 1.294e-11 3.22e-12 -8.1e-13 -5e-14 5e-14 -0.0 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.1e-12 1.271e-11 -5.753e-11 9.938e-11 3.62365e-09 6.216589e-08 9.6787533e-07 1.305358987e-05 0.0001485614126 0.0013780777737 0.00984084710535 0.05550133721662 0.14652451948886 0.16792962736714 0.09200290452217 0.02403596348889 0.0023932162089 0.00019759330931 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.08324824252392 0.14387701951487 0.07795081620287 0.02634223756466 0.0031983533184 0.00034303609199 3.009308082e-05 2.23529841e-06 1.442008e-07 8.31193e-09 4.2326e-10 -8.846e-11 5.8e-12 7.78e-12 -6e-13 -2.9e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.1e-12 1.271e-11 -5.753e-11 9.938e-11 3.62365e-09 6.216588e-08 9.6787516e-07 1.305358624e-05 0.00014856134689 0.00137807676411 0.00984083331591 0.05550120731227 0.14652416883617 0.16793243390753 0.09200293764545 0.02403714937912 0.00237519010897 0.00025974142571 1.22254269e-05 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.11885451700917 0.16128759294263 0.09463228272988 0.0317200095734 0.00382606514072 0.00040676118801 3.537974697e-05 2.6076939e-06 1.6704605e-07 9.54095e-09 5.0046e-10 -9.006e-11 3.77e-12 8.33e-12 -5.2e-13 -3.2e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.1e-12 1.271e-11 -5.753e-11 9.938e-11 3.62365e-09 6.216589e-08 9.6787539e-07 1.305359082e-05 0.00014856142474 0.0013780778576 0.00984084587195 0.05550130692953 0.14652434200803 0.16793127464741 0.09200452313714 0.02402555100329 0.00236465155553 0.00027652881122 -4.731816071e-05 0.0 0.0 0.0 0.0 0.0 0.0 0.002903743555 0.0794673059959 0.19802170918038 0.18443033088273 0.09838060726126 0.02937937537624 0.00356770875313 0.000384219427 3.361372156e-05 2.49001242e-06 1.6022922e-07 9.18571e-09 4.7818e-10 -8.977e-11 4.4e-12 8.18e-12 -5.5e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.1e-12 1.271e-11 -5.753e-11 9.938e-11 3.62365e-09 6.21659e-08 9.6787546e-07 1.30535923e-05 0.00014856145123 0.0013780782458 0.00984085044047 0.05550134023063 0.14652438271383 0.16793048054366 0.09200344884649 0.02400538977902 0.00236827425926 0.00031253233001 -0.00020079610572 -0.0016051211348 -0.00930093999612 0.0 0.0 -0.28833063766983 -0.10519206125941 -0.00410553863076 0.08276788382547 0.20266427424638 0.18732621834974 0.09889823154215 0.02882286364851 0.00350988342369 0.00037880763364 3.320326931e-05 2.46393037e-06 1.5874892e-07 9.10506e-09 4.7281e-10 -8.965e-11 4.54e-12 8.13e-12 -5.6e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.1e-12 1.271e-11 -5.753e-11 9.938e-11 3.62365e-09 6.21659e-08 9.678755e-07 1.30535932e-05 0.00014856146829 0.00137807854043 0.00984085614234 0.05550140501821 0.14652469483881 0.16792782098565 0.09199754015421 0.02403695421726 0.00238379792733 0.00027315433796 -0.00052175129906 -0.00444866873838 -0.04840489380043 -0.21199137303894 -0.4253433415068 -0.30828511375012 -0.11564182857003 -0.00782271834346 0.08242901812155 0.20417825778229 0.18803986351487 0.09881707274253 0.02867726819526 0.00349643744665 0.00037768524358 3.312600063e-05 2.45936337e-06 1.5850833e-07 9.09461e-09 4.7239e-10 -8.965e-11 4.54e-12 8.13e-12 -5.6e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.1e-12 1.271e-11 -5.753e-11 9.938e-11 3.62365e-09 6.21659e-08 9.6787551e-07 1.305359333e-05 0.0001485614709 0.00137807858762 0.00984085701293 0.05550141403017 0.1465247569364 0.16792745516948 0.0919974911107 0.02403934660132 0.00238080446991 0.00026902503685 -0.00054378186112 -0.00471375317682 -0.05030059891547 -0.21038042613128 -0.41905648456675 -0.30573645238323 -0.11767143255576 -0.00847036207444 0.08243966817503 0.20435244848777 0.18809816049589 0.09880851135575 0.02866201278849 0.00349511893867 0.0003775802233 3.311895289e-05 2.45898644e-06 1.5849747e-07 9.09498e-09 4.7247e-10 -8.966e-11 4.54e-12 8.14e-12 -5.6e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.1e-12 1.271e-11 -5.753e-11 9.938e-11 3.62365e-09 6.21659e-08 9.6787551e-07 1.305359334e-05 0.00014856147111 0.00137807859149 0.00984085708499 0.05550141473313 0.14652476379233 0.1679274156868 0.09199749568283 0.02403960815391 0.00238038231637 0.000268584626 -0.00054605256598 -0.00475417153095 -0.05064938960541 -0.20898358746255 -0.41132506084637 -0.30526315761105 -0.1178770225645 -0.00853859452709 0.08244463028711 0.20437000230084 0.18810209218149 0.09880761670726 0.02866067287343 0.00349501166201 0.00037757209111 3.311845232e-05 2.45896969e-06 1.5849739e-07 9.09492e-09 4.7246e-10 -8.966e-11 4.54e-12 8.14e-12 -5.6e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.1e-12 1.271e-11 -5.753e-11 9.938e-11 3.62365e-09 6.21659e-08 9.6787551e-07 1.305359334e-05 0.00014856147109 0.00137807859129 0.00984085708594 0.05550141477533 0.14652476421498 0.16792741300529 0.09199749602284 0.02403962151147 0.00238036389514 0.00026855189641 -0.0005462307008 -0.00475761711073 -0.05068027629319 -0.20876089306519 -0.41010288065378 -0.30520487743757 -0.11789421092505 -0.00854444279056 0.08244529671856 0.20437144475819 0.18810228711632 0.09880753070235 0.02866057209541 0.00349500425755 0.00037757157078 3.311843772e-05 2.45896901e-06 1.5849694e-07 9.09486e-09 4.7245e-10 -8.966e-11 4.54e-12 8.14e-12 -5.6e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.1e-12 1.271e-11 -5.753e-11 9.938e-11 3.62365e-09 6.21659e-08 9.6787551e-07 1.305359334e-05 0.00014856147109 0.00137807859135 0.00984085708609 0.05550141477812 0.14652476420665 0.1679274128946 0.09199749605473 0.02403962206965 0.00238036327402 0.00026854984491 -0.00054624212104 -0.00475785679786 -0.05068239442552 -0.20873540884312 -0.40997059390897 -0.30519949557605 -0.1178953995985 -0.00854485943447 0.08244535727076 0.20437154494628 0.18810229292562 0.09880752384629 0.02866056553233 0.00349500381259 0.00037757156386 3.311843733e-05 2.45896822e-06 1.5849684e-07 9.09486e-09 4.7245e-10 -8.966e-11 4.54e-12 8.14e-12 -5.6e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.1e-12 1.271e-11 -5.753e-11 9.938e-11 3.62365e-09 6.21659e-08 9.6787551e-07 1.305359334e-05 0.00014856147109 0.00137807859138 0.00984085708634 0.05550141477793 0.14652476420282 0.16792741292717 0.09199749602701 0.02403962205895 0.00238036329615 0.00026854975929 -0.00054624272526 -0.00475787061521 -0.05068250493769 -0.20873309260508 -0.40995880699497 -0.30519908988362 -0.11789546987355 -0.00854488498896 0.08244536152006 0.20437155104349 0.1881022928686 0.09880752334103 0.02866056512231 0.00349500381391 0.00037757156467 3.31184363e-05 2.45896813e-06 1.5849685e-07 9.09486e-09 4.7245e-10 -8.966e-11 4.54e-12 8.14e-12 -5.6e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.1e-12 1.271e-11 -5.753e-11 9.938e-11 3.62365e-09 6.21659e-08 9.6787551e-07 1.305359334e-05 0.00014856147109 0.00137807859138 0.00984085708638 0.05550141477809 0.14652476420522 0.16792741292081 0.09199749602439 0.02403962205749 0.00238036330392 0.00026854976278 -0.00054624274204 -0.0047578712994 -0.05068250952129 -0.2087329161641 -0.40995793156197 -0.30519906392207 -0.11789547355491 -0.00854488642075 0.08244536182595 0.20437155140799 0.18810229280764 0.09880752332026 0.02866056514256 0.00349500381543 0.00037757156329 3.311843621e-05 2.45896815e-06 1.5849685e-07 9.09486e-09 4.7245e-10 -8.966e-11 4.54e-12 8.14e-12 -5.6e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.1e-12 1.271e-11 -5.753e-11 9.938e-11 3.62365e-09 6.21659e-08 9.6787551e-07 1.305359334e-05 0.00014856147109 0.00137807859138 0.00984085708638 0.05550141477812 0.14652476420544 0.16792741291801 0.09199749602735 0.0240396220607 0.00238036329992 0.00026854976175 -0.00054624273728 -0.00475787131159 -0.0506825096399 -0.20873290462493 -0.40995787581817 -0.30519906243386 -0.11789547377976 -0.00854488644121 0.08244536188705 0.20437155135562 0.1881022928021 0.09880752333602 0.02866056514975 0.00349500381404 0.00037757156319 3.311843623e-05 2.45896815e-06 1.5849685e-07 9.09486e-09 4.7245e-10 -8.966e-11 4.54e-12 8.14e-12 -5.6e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.1e-12 1.271e-11 -5.753e-11 9.938e-11 3.62365e-09 6.21659e-08 9.6787551e-07 1.305359334e-05 0.00014856147109 0.00137807859138 0.00984085708638 0.05550141477812 0.14652476420535 0.16792741291837 0.09199749602742 0.02403962206078 0.0023803632995 0.00026854976105 -0.00054624273829 -0.0047578713116 -0.05068250963931 -0.20873290398712 -0.40995787263451 -0.30519906234549 -0.117895473761 -0.00854488642738 0.08244536187556 0.20437155135178 0.18810229280643 0.09880752333407 0.02866056514635 0.0034950038139 0.00037757156322 3.311843623e-05 2.45896815e-06 1.5849685e-07 9.09486e-09 4.7245e-10 -8.966e-11 4.54e-12 8.14e-12 -5.6e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.1e-12 1.271e-11 -5.753e-11 9.938e-11 3.62365e-09 6.21659e-08 9.6787551e-07 1.305359334e-05 0.00014856147109 0.00137807859138 0.00984085708638 0.05550141477812 0.14652476420535 0.16792741291845 0.0919974960273 0.02403962206064 0.00238036329969 0.00026854976109 -0.00054624273864 -0.00475787131379 -0.05068250964678 -0.20873290401113 -0.40995787247304 -0.30519906236948 -0.11789547375711 -0.00854488643146 0.08244536187339 0.20437155135718 0.1881022928064 0.09880752333307 0.02866056514598 0.00349500381394 0.00037757156322 3.311843623e-05 2.45896815e-06 1.5849685e-07 9.09486e-09 4.7245e-10 -8.966e-11 4.54e-12 8.14e-12 -5.6e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.1e-12 1.271e-11 -5.753e-11 9.938e-11 3.62365e-09 6.21659e-08 9.6787551e-07 1.305359334e-05 0.00014856147109 0.00137807859138 0.00984085708638 0.05550141477812 0.14652476420535 0.16792741291842 0.09199749602731 0.02403962206066 0.00238036329969 0.00026854976111 -0.00054624273857 -0.0047578713137 -0.05068250964654 -0.20873290402309 -0.40995787253903 -0.30519906236858 -0.11789547375893 -0.00854488643234 0.08244536187412 0.20437155135725 0.18810229280619 0.09880752333321 0.02866056514614 0.00349500381394 0.00037757156322 3.311843623e-05 2.45896815e-06 1.5849685e-07 9.09486e-09 4.7245e-10 -8.966e-11 4.54e-12 8.14e-12 -5.6e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.1e-12 1.271e-11 -5.753e-11 9.938e-11 3.62365e-09 6.21659e-08 9.6787551e-07 1.305359334e-05 0.00014856147109 0.00137807859138 0.00984085708638 0.05550141477812 0.14652476420535 0.16792741291842 0.09199749602731 0.02403962206067 0.00238036329968 0.00026854976111 -0.00054624273856 -0.00475787131359 -0.05068250964584 -0.2087329040168 -0.40995787253139 -0.30519906236672 -0.11789547375908 -0.00854488643216 0.08244536187416 0.20437155135701 0.18810229280622 0.09880752333324 0.02866056514614 0.00349500381393 0.00037757156322 3.311843623e-05 2.45896815e-06 1.5849685e-07 9.09486e-09 4.7245e-10 -8.966e-11 4.54e-12 8.14e-12 -5.6e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.1e-12 1.271e-11 -5.753e-11 9.938e-11 3.62365e-09 6.21659e-08 9.6787551e-07 1.305359334e-05 0.00014856147109 0.00137807859138 0.00984085708638 0.05550141477812 0.14652476420535 0.16792741291842 0.09199749602731 0.02403962206066 0.00238036329968 0.00026854976111 -0.00054624273857 -0.00475787131361 -0.05068250964588 -0.20873290401621 -0.40995787252698 -0.30519906236685 -0.117895473759 -0.00854488643215 0.08244536187412 0.20437155135703 0.18810229280622 0.09880752333323 0.02866056514613 0.00349500381393 0.00037757156322 3.311843623e-05 2.45896815e-06 1.5849685e-07 9.09486e-09 4.7245e-10 -8.966e-11 4.54e-12 8.14e-12 -5.6e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.1e-12 1.271e-11 -5.753e-11 9.938e-11 3.62365e-09 6.21659e-08 9.6787551e-07 1.305359334e-05 0.00014856147109 0.00137807859138 0.00984085708638 0.05550141477812 0.14652476420535 0.16792741291842 0.09199749602731 0.02403962206066 0.00238036329968 0.00026854976111 -0.00054624273857 -0.00475787131361 -0.05068250964592 -0.20873290401652 -0.40995787252762 -0.30519906236692 -0.117895473759 -0.00854488643216 0.08244536187412 0.20437155135704 0.18810229280622 0.09880752333323 0.02866056514613 0.00349500381394 0.00037757156322 3.311843623e-05 2.45896815e-06 1.5849685e-07 9.09486e-09 4.7245e-10 -8.966e-11 4.54e-12 8.14e-12 -5.6e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.1e-12 1.271e-11 -5.753e-11 9.938e-11 3.62365e-09 6.21659e-08 9.6787551e-07 1.305359334e-05 0.00014856147109 0.00137807859138 0.00984085708638 0.05550141477812 0.14652476420535 0.16792741291842 0.09199749602731 0.02403962206066 0.00238036329968 0.00026854976111 -0.00054624273857 -0.00475787131361 -0.05068250964591 -0.20873290401652 -0.40995787252776 -0.3051990623669 -0.117895473759 -0.00854488643216 0.08244536187412 0.20437155135704 0.18810229280622 0.09880752333323 0.02866056514613 0.00349500381393 0.00037757156322 3.311843623e-05 2.45896815e-06 1.5849685e-07 9.09486e-09 4.7245e-10 -8.966e-11 4.54e-12 8.14e-12 -5.6e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.1e-12 1.271e-11 -5.753e-11 9.938e-11 3.62365e-09 6.21659e-08 9.6787551e-07 1.305359334e-05 0.00014856147109 0.00137807859138 0.00984085708638 0.05550141477812 0.14652476420535 0.16792741291842 0.09199749602731 0.02403962206066 0.00238036329968 0.00026854976111 -0.00054624273857 -0.00475787131361 -0.05068250964591 -0.2087329040165 -0.40995787252771 -0.3051990623669 -0.117895473759 -0.00854488643216 0.08244536187412 0.20437155135704 0.18810229280622 0.09880752333323 0.02866056514613 0.00349500381393 0.00037757156322 3.311843623e-05 2.45896815e-06 1.5849685e-07 9.09486e-09 4.7245e-10 -8.966e-11 4.54e-12 8.14e-12 -5.6e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.1e-12 1.271e-11 -5.753e-11 9.938e-11 3.62365e-09 6.21659e-08 9.6787551e-07 1.305359334e-05 0.00014856147109 0.00137807859138 0.00984085708638 0.05550141477812 0.14652476420535 0.16792741291842 0.09199749602731 0.02403962206066 0.00238036329968 0.00026854976111 -0.00054624273857 -0.00475787131361 -0.05068250964591 -0.2087329040165 -0.4099578725277 -0.3051990623669 -0.117895473759 -0.00854488643216 0.08244536187412 0.20437155135704 0.18810229280622 0.09880752333323 0.02866056514613 0.00349500381394 0.00037757156322 3.311843623e-05 2.45896815e-06 1.5849685e-07 9.09486e-09 4.7245e-10 -8.966e-11 4.54e-12 8.14e-12 -5.6e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.1e-12 1.271e-11 -5.753e-11 9.938e-11 3.62365e-09 6.21659e-08 9.6787551e-07 1.305359334e-05 0.00014856147109 0.00137807859138 0.00984085708638 0.05550141477812 0.14652476420535 0.16792741291842 0.09199749602731 0.02403962206066 0.00238036329968 0.00026854976111 -0.00054624273857 -0.00475787131361 -0.05068250964591 -0.2087329040165 -0.40995787252771 -0.3051990623669 -0.117895473759 -0.00854488643216 0.08244536187412 0.20437155135704 0.18810229280622 0.09880752333323 0.02866056514613 0.00349500381393 0.00037757156322 3.311843623e-05 2.45896815e-06 1.5849685e-07 9.09486e-09 4.7245e-10 -8.966e-11 4.54e-12 8.14e-12 -5.6e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.1e-12 1.271e-11 -5.753e-11 9.938e-11 3.62365e-09 6.21659e-08 9.6787551e-07 1.305359334e-05 0.00014856147109 0.00137807859138 0.00984085708638 0.05550141477812 0.14652476420535 0.16792741291842 0.09199749602731 0.02403962206066 0.00238036329968 0.00026854976111 -0.00054624273857 -0.00475787131361 -0.05068250964591 -0.2087329040165 -0.40995787252771 -0.3051990623669 -0.117895473759 -0.00854488643216 0.08244536187412 0.20437155135704 0.18810229280622 0.09880752333323 0.02866056514613 0.00349500381394 0.00037757156322 3.311843623e-05 2.45896815e-06 1.5849685e-07 9.09486e-09 4.7245e-10 -8.966e-11 4.54e-12 8.14e-12 -5.6e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.1e-12 1.271e-11 -5.753e-11 9.938e-11 3.62365e-09 6.21659e-08 9.6787551e-07 1.305359334e-05 0.00014856147109 0.00137807859138 0.00984085708638 0.05550141477812 0.14652476420535 0.16792741291842 0.09199749602731 0.02403962206066 0.00238036329968 0.00026854976111 -0.00054624273857 -0.00475787131361 -0.05068250964591 -0.2087329040165 -0.40995787252771 -0.3051990623669 -0.117895473759 -0.00854488643216 0.08244536187412 0.20437155135704 0.18810229280622 0.09880752333323 0.02866056514613 0.00349500381394 0.00037757156322 3.311843623e-05 2.45896815e-06 1.5849685e-07 9.09486e-09 4.7245e-10 -8.966e-11 4.54e-12 8.14e-12 -5.6e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.1e-12 1.271e-11 -5.753e-11 9.938e-11 3.62365e-09 6.21659e-08 9.6787551e-07 1.305359334e-05 0.00014856147109 0.00137807859138 0.00984085708638 0.05550141477812 0.14652476420535 0.16792741291842 0.09199749602731 0.02403962206066 0.00238036329968 0.00026854976111 -0.00054624273857 -0.00475787131361 -0.05068250964591 -0.2087329040165 -0.40995787252771 -0.3051990623669 -0.117895473759 -0.00854488643216 0.08244536187412 0.20437155135704 0.18810229280622 0.09880752333323 0.02866056514613 0.00349500381394 0.00037757156322 3.311843623e-05 2.45896815e-06 1.5849685e-07 9.09486e-09 4.7245e-10 -8.966e-11 4.54e-12 8.14e-12 -5.6e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.1e-12 1.271e-11 -5.753e-11 9.938e-11 3.62365e-09 6.21659e-08 9.6787551e-07 1.305359334e-05 0.00014856147109 0.00137807859138 0.00984085708638 0.05550141477812 0.14652476420535 0.16792741291842 0.09199749602731 0.02403962206066 0.00238036329968 0.00026854976111 -0.00054624273857 -0.00475787131361 -0.05068250964591 -0.2087329040165 -0.40995787252771 -0.3051990623669 -0.117895473759 -0.00854488643216 0.08244536187412 0.20437155135704 0.18810229280622 0.09880752333323 0.02866056514613 0.00349500381394 0.00037757156322 3.311843623e-05 2.45896815e-06 1.5849685e-07 9.09486e-09 4.7245e-10 -8.966e-11 4.54e-12 8.14e-12 -5.6e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.1e-12 1.271e-11 -5.753e-11 9.938e-11 3.62365e-09 6.21659e-08 9.6787551e-07 1.305359334e-05 0.00014856147109 0.00137807859138 0.00984085708638 0.05550141477812 0.14652476420535 0.16792741291842 0.09199749602731 0.02403962206066 0.00238036329968 0.00026854976111 -0.00054624273857 -0.00475787131361 -0.05068250964591 -0.2087329040165 -0.40995787252771 -0.3051990623669 -0.117895473759 -0.00854488643216 0.08244536187412 0.20437155135704 0.18810229280622 0.09880752333323 0.02866056514613 0.00349500381393 0.00037757156322 3.311843623e-05 2.45896815e-06 1.5849685e-07 9.09486e-09 4.7245e-10 -8.966e-11 4.54e-12 8.14e-12 -5.6e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.1e-12 1.271e-11 -5.753e-11 9.938e-11 3.62365e-09 6.21659e-08 9.6787551e-07 1.305359334e-05 0.00014856147109 0.00137807859138 0.00984085708638 0.05550141477812 0.14652476420535 0.16792741291842 0.09199749602731 0.02403962206066 0.00238036329968 0.00026854976111 -0.00054624273857 -0.00475787131361 -0.05068250964591 -0.2087329040165 -0.4099578725277 -0.3051990623669 -0.117895473759 -0.00854488643216 0.08244536187412 0.20437155135704 0.18810229280622 0.09880752333323 0.02866056514613 0.00349500381394 0.00037757156322 3.311843623e-05 2.45896815e-06 1.5849685e-07 9.09486e-09 4.7245e-10 -8.966e-11 4.54e-12 8.14e-12 -5.6e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.1e-12 1.271e-11 -5.753e-11 9.938e-11 3.62365e-09 6.21659e-08 9.6787551e-07 1.305359334e-05 0.00014856147109 0.00137807859138 0.00984085708638 0.05550141477812 0.14652476420535 0.16792741291842 0.09199749602731 0.02403962206066 0.00238036329968 0.00026854976111 -0.00054624273857 -0.00475787131361 -0.05068250964591 -0.2087329040165 -0.40995787252771 -0.30519906236692 -0.117895473759 -0.00854488643216 0.08244536187412 0.20437155135704 0.18810229280622 0.09880752333323 0.02866056514613 0.00349500381394 0.00037757156322 3.311843623e-05 2.45896815e-06 1.5849685e-07 9.09486e-09 4.7245e-10 -8.966e-11 4.54e-12 8.14e-12 -5.6e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.1e-12 1.271e-11 -5.753e-11 9.938e-11 3.62365e-09 6.21659e-08 9.6787551e-07 1.305359334e-05 0.00014856147109 0.00137807859138 0.00984085708638 0.05550141477812 0.14652476420535 0.16792741291842 0.09199749602731 0.02403962206066 0.00238036329968 0.00026854976111 -0.00054624273857 -0.00475787131361 -0.05068250964591 -0.20873290401652 -0.40995787252776 -0.30519906236685 -0.11789547375899 -0.00854488643214 0.08244536187412 0.20437155135703 0.18810229280623 0.09880752333323 0.02866056514613 0.00349500381394 0.00037757156322 3.311843623e-05 2.45896815e-06 1.5849685e-07 9.09486e-09 4.7245e-10 -8.966e-11 4.54e-12 8.14e-12 -5.6e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.1e-12 1.271e-11 -5.753e-11 9.938e-11 3.62365e-09 6.21659e-08 9.6787551e-07 1.305359334e-05 0.00014856147109 0.00137807859138 0.00984085708638 0.05550141477812 0.14652476420535 0.16792741291842 0.09199749602731 0.02403962206066 0.00238036329968 0.00026854976111 -0.00054624273857 -0.00475787131361 -0.05068250964592 -0.20873290401652 -0.40995787252759 -0.30519906236671 -0.1178954737591 -0.00854488643216 0.08244536187416 0.20437155135701 0.18810229280623 0.09880752333324 0.02866056514614 0.00349500381393 0.00037757156322 3.311843623e-05 2.45896815e-06 1.5849685e-07 9.09486e-09 4.7245e-10 -8.966e-11 4.54e-12 8.14e-12 -5.6e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.1e-12 1.271e-11 -5.753e-11 9.938e-11 3.62365e-09 6.21659e-08 9.6787551e-07 1.305359334e-05 0.00014856147109 0.00137807859138 0.00984085708638 0.05550141477812 0.14652476420535 0.16792741291842 0.09199749602731 0.02403962206066 0.00238036329968 0.00026854976111 -0.00054624273857 -0.00475787131361 -0.05068250964588 -0.20873290401616 -0.40995787252698 -0.30519906236873 -0.11789547375895 -0.00854488643238 0.08244536187412 0.20437155135718 0.18810229280611 0.0988075233332 0.02866056514615 0.00349500381394 0.00037757156322 3.311843623e-05 2.45896815e-06 1.5849685e-07 9.09486e-09 4.7245e-10 -8.966e-11 4.54e-12 8.14e-12 -5.6e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.1e-12 1.271e-11 -5.753e-11 9.938e-11 3.62365e-09 6.21659e-08 9.6787551e-07 1.305359334e-05 0.00014856147109 0.00137807859138 0.00984085708638 0.05550141477812 0.14652476420535 0.16792741291842 0.09199749602731 0.02403962206066 0.00238036329968 0.00026854976111 -0.00054624273857 -0.00475787131361 -0.05068250964577 -0.20873290401704 -0.40995787253206 -0.30519906236962 -0.11789547375658 -0.00854488643134 0.08244536187343 0.20437155135725 0.18810229280633 0.09880752333297 0.02866056514601 0.00349500381394 0.00037757156322 3.311843623e-05 2.45896815e-06 1.5849685e-07 9.09486e-09 4.7245e-10 -8.966e-11 4.54e-12 8.14e-12 -5.6e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.1e-12 1.271e-11 -5.753e-11 9.938e-11 3.62365e-09 6.21659e-08 9.6787551e-07 1.305359334e-05 0.00014856147109 0.00137807859138 0.00984085708638 0.05550141477812 0.14652476420535 0.16792741291842 0.09199749602731 0.02403962206066 0.00238036329968 0.0002685497611 -0.00054624273858 -0.00475787131362 -0.05068250964681 -0.20873290402393 -0.40995787253841 -0.30519906234417 -0.11789547376175 -0.00854488642684 0.08244536187552 0.20437155135292 0.18810229280847 0.09880752333432 0.02866056514614 0.0034950038139 0.00037757156322 3.311843623e-05 2.45896815e-06 1.5849685e-07 9.09486e-09 4.7245e-10 -8.966e-11 4.54e-12 8.14e-12 -5.6e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.1e-12 1.271e-11 -5.753e-11 9.938e-11 3.62365e-09 6.21659e-08 9.6787551e-07 1.305359334e-05 0.00014856147109 0.00137807859138 0.00984085708638 0.05550141477812 0.14652476420535 0.16792741291842 0.09199749602731 0.02403962206068 0.00238036329967 0.00026854976111 -0.00054624273853 -0.00475787131371 -0.05068250964776 -0.20873290400614 -0.40995787246774 -0.30519906244622 -0.11789547378302 -0.00854488644134 0.08244536188496 0.20437155135296 0.1881022928031 0.09880752333805 0.02866056514929 0.00349500381397 0.00037757156319 3.311843623e-05 2.45896815e-06 1.5849685e-07 9.09486e-09 4.7245e-10 -8.966e-11 4.54e-12 8.14e-12 -5.6e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.1e-12 1.271e-11 -5.753e-11 9.938e-11 3.62365e-09 6.21659e-08 9.6787551e-07 1.305359334e-05 0.00014856147109 0.00137807859138 0.00984085708638 0.05550141477812 0.14652476420535 0.16792741291843 0.0919974960273 0.02403962206068 0.0023803632996 0.00026854976115 -0.00054624273843 -0.00475787131367 -0.05068250963454 -0.20873290399724 -0.40995787266905 -0.30519906417864 -0.11789547349742 -0.0085448864049 0.08244536182836 0.20437155140523 0.18810229278485 0.09880752331679 0.02866056514623 0.00349500381527 0.00037757156322 3.311843621e-05 2.45896815e-06 1.5849685e-07 9.09486e-09 4.7245e-10 -8.966e-11 4.54e-12 8.14e-12 -5.6e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.1e-12 1.271e-11 -5.753e-11 9.938e-11 3.62365e-09 6.21659e-08 9.6787551e-07 1.305359334e-05 0.00014856147109 0.00137807859138 0.00984085708638 0.05550141477811 0.14652476420534 0.16792741291839 0.0919974960274 0.02403962206043 0.00238036330004 0.00026854976089 -0.00054624273965 -0.00475787131315 -0.05068250965386 -0.20873290483031 -0.40995787633556 -0.30519909371592 -0.11789546900119 -0.00854488461364 0.08244536148405 0.20437155116445 0.18810229298276 0.09880752333621 0.02866056511694 0.00349500381466 0.00037757156451 3.311843625e-05 2.45896813e-06 1.5849685e-07 9.09486e-09 4.7245e-10 -8.966e-11 4.54e-12 8.14e-12 -5.6e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.1e-12 1.271e-11 -5.753e-11 9.938e-11 3.62365e-09 6.21659e-08 9.6787551e-07 1.305359334e-05 0.00014856147109 0.00137807859138 0.00984085708638 0.0555014147781 0.14652476420541 0.1679274129185 0.09199749602676 0.02403962206034 0.00238036330212 0.00026854976036 -0.00054624274292 -0.0047578713024 -0.05068250996141 -0.20873291955604 -0.4099579394879 -0.30519954623305 -0.11789538444733 -0.00854485331453 0.08244535662643 0.20437154685599 0.18810229453051 0.09880752399306 0.02866056536136 0.00349500380364 0.00037757156425 3.311843727e-05 2.45896819e-06 1.5849684e-07 9.09486e-09 4.7245e-10 -8.966e-11 4.54e-12 8.14e-12 -5.6e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.1e-12 1.271e-11 -5.753e-11 9.938e-11 3.62365e-09 6.21659e-08 9.6787551e-07 1.305359334e-05 0.0001485614711 0.00137807859139 0.0098408570864 0.05550141477817 0.14652476420503 0.16792741292125 0.09199749602446 0.02403962206324 0.00238036329546 0.00026854976083 -0.00054624273896 -0.00475787109148 -0.05068251204579 -0.20873314110636 -0.40995891146308 -0.30520543136122 -0.11789398964564 -0.00854435802231 0.08244528857854 0.20437147327294 0.18810231104917 0.09880753289025 0.02866056971826 0.00349500405432 0.00037757155987 3.311843768e-05 2.458969e-06 1.5849693e-07 9.09486e-09 4.7245e-10 -8.966e-11 4.54e-12 8.14e-12 -5.6e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.1e-12 1.271e-11 -5.753e-11 9.938e-11 3.62365e-09 6.21659e-08 9.6787551e-07 1.305359334e-05 0.00014856147109 0.00137807859137 0.0098408570863 0.0555014147787 0.14652476420508 0.1679274129082 0.09199749604022 0.02403962206451 0.00238036329745 0.00026854975252 -0.00054624275671 -0.00475786479831 -0.05068249314089 -0.20873601553912 -0.40997173020608 -0.30526806948862 -0.11787431513069 -0.00853759990558 0.0824445337652 0.20437036207249 0.18810240949778 0.09880764532991 0.02866064184902 0.0034950088653 0.00037757189015 3.311844174e-05 2.45896953e-06 1.5849742e-07 9.09492e-09 4.7246e-10 -8.966e-11 4.54e-12 8.14e-12 -5.6e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.1e-12 1.271e-11 -5.753e-11 9.938e-11 3.62365e-09 6.21659e-08 9.6787551e-07 1.305359334e-05 0.00014856147109 0.00137807859132 0.00984085708602 0.05550141477799 0.14652476421292 0.16792741289996 0.09199749599423 0.0240396217899 0.00238036394198 0.00026854998504 -0.00054624092283 -0.00475773596543 -0.05068165491846 -0.2087676544148 -0.41011244941903 -0.30576787693259 -0.11764475455183 -0.00846076197637 0.08243860451545 0.20435625166097 0.18810156650254 0.09880881392423 0.02866167191536 0.00349508625637 0.00037757771719 3.31187972e-05 2.45897846e-06 1.584972e-07 9.09498e-09 4.7247e-10 -8.966e-11 4.54e-12 8.14e-12 -5.6e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.1e-12 1.271e-11 -5.753e-11 9.938e-11 3.62365e-09 6.21659e-08 9.6787551e-07 1.305359334e-05 0.00014856147112 0.00137807859174 0.00984085708859 0.05550141476535 0.1465247640782 0.16792741369725 0.09199749535362 0.0240396139173 0.00238037923873 0.00026856060275 -0.00054617005198 -0.00475530413592 -0.05065942265445 -0.20902610659684 -0.41139467090141 -0.30846456097354 -0.11541297661493 -0.00773937395671 0.08241602234054 0.20420969393834 0.18807210218922 0.09881884636427 0.0286739314486 0.00349611914945 0.00037766026254 3.312440147e-05 2.45927715e-06 1.5850407e-07 9.09442e-09 4.7239e-10 -8.965e-11 4.54e-12 8.14e-12 -5.6e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.1e-12 1.271e-11 -5.753e-11 9.938e-11 3.62365e-09 6.21659e-08 9.6787551e-07 1.305359335e-05 0.00014856147118 0.00137807859145 0.00984085706528 0.05550141445955 0.14652476073698 0.16792743195849 0.09199748616738 0.02403942431004 0.00238072266641 0.00026878493504 -0.00054487924577 -0.0047229553548 -0.05036036814543 -0.21058953959141 -0.41933480332063 -0.28861592464942 -0.10492765177475 -0.00403158840983 0.08277818285588 0.20290344982976 0.18754093781795 0.09892342011329 0.02880665611416 0.00350810651759 0.00037865386439 3.319298544e-05 2.46337395e-06 1.5872227e-07 9.10378e-09 4.7273e-10 -8.965e-11 4.54e-12 8.13e-12 -5.6e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.1e-12 1.271e-11 -5.753e-11 9.938e-11 3.62365e-09 6.21659e-08 9.6787551e-07 1.30535933e-05 0.00014856147012 0.0013780785707 0.00984085663056 0.0555014094163 0.14652471522468 0.16792765565038 0.09199737806172 0.02403751045195 0.00238354424518 0.00027142286334 -0.00052950748207 -0.00448837480191 -0.04848936142425 -0.21229977587483 -0.42599674689978 0.0 0.0 0.0031349858265 0.07928039274837 0.19836935994254 0.1855765184693 0.09888941940196 0.0294325081631 0.00357076041696 0.00038444048197 3.362826683e-05 2.49097674e-06 1.6028942e-07 9.18878e-09 4.7833e-10 -8.977e-11 4.4e-12 8.18e-12 -5.5e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.1e-12 1.271e-11 -5.753e-11 9.938e-11 3.62365e-09 6.21659e-08 9.6787549e-07 1.305359297e-05 0.00014856146206 0.00137807838969 0.00984085212037 0.05550135226131 0.14652441732219 0.16792997811154 0.09200236486724 0.02400618280011 0.00236504299502 0.00031782644451 -0.00023734545321 -0.0016755011474 -0.00931854733915 0.0 0.0 0.0 0.0 0.0 0.0 0.11852908155854 0.16740919328852 0.0971362637036 0.03205968645666 0.00384654252988 0.00040901657944 3.555604583e-05 2.61959769e-06 1.6775612e-07 9.57825e-09 5.0275e-10 -9.008e-11 3.71e-12 8.34e-12 -5.2e-13 -3.2e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.1e-12 1.271e-11 -5.753e-11 9.938e-11 3.62365e-09 6.21659e-08 9.6787555e-07 1.305359415e-05 0.00014856148283 0.0013780787058 0.00984085651621 0.05550139395974 0.14652458807124 0.16792947745147 0.09200469442459 0.02402690813353 0.00236860471509 0.00025864735582 -6.380844418e-05 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.08163939405688 0.15734644469257 0.08159978557714 0.02586298614701 0.00316704196968 0.00034285264518 3.024030177e-05 2.25635069e-06 1.4603557e-07 8.43082e-09 4.3168e-10 -8.872e-11 5.55e-12 7.84e-12 -5.9e-13 -2.9e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.1e-12 1.271e-11 -5.753e-11 9.938e-11 3.62365e-09 6.216591e-08 9.6787584e-07 1.305359973e-05 0.00014856157576 0.00137808002406 0.0098408733939 0.05550154757543 0.14652503370365 0.16792638633793 0.09200607473665 0.02403489082555 0.00239839783288 0.00017142235231 2.144081753e-05 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.04046409185891 0.02141295970751 0.00661010378828 0.00086162772385 9.670265494e-05 8.78111161e-06 6.7197908e-07 4.446435e-08 2.67489e-09 3.751e-11 -4.458e-11 1.302e-11 2.98e-12 -8e-13 -4e-14 5e-14 -0.0 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.1e-12 1.271e-11 -5.753e-11 9.938e-11 3.62365e-09 6.21659e-08 9.6787563e-07 1.305359567e-05 0.00014856150992 0.00137807912995 0.00984086296426 0.05550146087045 0.14652482067957 0.16792776157841 0.09200461268218 0.02403465968044 0.00239941432965 0.00017978975883 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.00553050301052 0.00767056873707 0.00202217912408 0.00025015275698 2.664961522e-05 2.36452258e-06 1.7945236e-07 1.189151e-08 7.29e-10 -9.607e-11 -3.87e-12 1.128e-11 -1.1e-13 -5.5e-13 8e-14 2e-14 -1e-14 -0.0 -0.0 6e-14 -9e-14 -8.5e-13 4.1e-12 1.271e-11 -5.753e-11 9.938e-11 3.62365e-09 6.21659e-08 9.6787543e-07 1.30535915e-05 0.00014856143508 0.00137807797521 0.00984084639712 0.05550130241935 0.14652424693627 0.16793155129081 0.09200412767475 0.02400735981967 0.00236819822035 0.00031313450631 0.0 0.0 0.0 0.0 0.0 +D/cons.3.00.000050.dat 0.0 0.0 0.0 0.0 0.0 0.03174808335338 0.01345420708904 0.00293100450106 0.00039786317896 4.369980519e-05 3.91923992e-06 2.9685443e-07 1.946492e-08 1.20196e-09 -7.466e-11 -1.652e-11 1.284e-11 7.2e-13 -6.8e-13 5e-14 3e-14 -1e-14 -0.0 -0.0 6e-14 -9e-14 -8.5e-13 4.1e-12 1.271e-11 -5.753e-11 9.938e-11 3.62365e-09 6.216589e-08 9.6787535e-07 1.305359006e-05 0.0001485614105 0.00137807763111 0.00984084254932 0.0555012747518 0.14652419179682 0.16793187018781 0.092003603696 0.02400963377805 0.00236863807335 0.00030572819805 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.04126976969797 0.02335115363958 0.00677349131879 0.00090004423485 0.00010263616427 9.41031102e-06 7.241786e-07 4.797885e-08 2.86937e-09 5.128e-11 -4.751e-11 1.294e-11 3.22e-12 -8.1e-13 -5e-14 5e-14 -0.0 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.1e-12 1.271e-11 -5.753e-11 9.938e-11 3.62365e-09 6.216589e-08 9.6787533e-07 1.305358987e-05 0.0001485614126 0.0013780777737 0.00984084710535 0.05550133721662 0.14652451948886 0.16792962736714 0.09200290452217 0.02403596348889 0.0023932162089 0.00019759330931 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.08324824252392 0.14387701951487 0.07795081620287 0.02634223756466 0.0031983533184 0.00034303609199 3.009308082e-05 2.23529841e-06 1.442008e-07 8.31193e-09 4.2326e-10 -8.846e-11 5.8e-12 7.78e-12 -6e-13 -2.9e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.1e-12 1.271e-11 -5.753e-11 9.938e-11 3.62365e-09 6.216588e-08 9.6787516e-07 1.305358624e-05 0.00014856134689 0.00137807676411 0.00984083331591 0.05550120731227 0.14652416883617 0.16793243390753 0.09200293764545 0.02403714937912 0.00237519010897 0.00025974142571 1.22254269e-05 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.11885451700917 0.16128759294263 0.09463228272988 0.0317200095734 0.00382606514072 0.00040676118801 3.537974697e-05 2.6076939e-06 1.6704605e-07 9.54095e-09 5.0046e-10 -9.006e-11 3.77e-12 8.33e-12 -5.2e-13 -3.2e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.1e-12 1.271e-11 -5.753e-11 9.938e-11 3.62365e-09 6.216589e-08 9.6787539e-07 1.305359082e-05 0.00014856142474 0.0013780778576 0.00984084587195 0.05550130692953 0.14652434200803 0.16793127464741 0.09200452313714 0.02402555100329 0.00236465155553 0.00027652881122 -4.731816071e-05 0.0 0.0 0.0 0.0 0.0 0.0 0.002903743555 0.0794673059959 0.19802170918038 0.18443033088273 0.09838060726126 0.02937937537624 0.00356770875313 0.000384219427 3.361372156e-05 2.49001242e-06 1.6022922e-07 9.18571e-09 4.7818e-10 -8.977e-11 4.4e-12 8.18e-12 -5.5e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.1e-12 1.271e-11 -5.753e-11 9.938e-11 3.62365e-09 6.21659e-08 9.6787546e-07 1.30535923e-05 0.00014856145123 0.0013780782458 0.00984085044047 0.05550134023063 0.14652438271383 0.16793048054366 0.09200344884649 0.02400538977902 0.00236827425926 0.00031253233001 -0.00020079610572 -0.0016051211348 -0.00930093999612 0.0 0.0 -0.28833063766983 -0.10519206125941 -0.00410553863076 0.08276788382547 0.20266427424638 0.18732621834974 0.09889823154215 0.02882286364851 0.00350988342369 0.00037880763364 3.320326931e-05 2.46393037e-06 1.5874892e-07 9.10506e-09 4.7281e-10 -8.965e-11 4.54e-12 8.13e-12 -5.6e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.1e-12 1.271e-11 -5.753e-11 9.938e-11 3.62365e-09 6.21659e-08 9.678755e-07 1.30535932e-05 0.00014856146829 0.00137807854043 0.00984085614234 0.05550140501821 0.14652469483881 0.16792782098565 0.09199754015421 0.02403695421726 0.00238379792733 0.00027315433796 -0.00052175129906 -0.00444866873838 -0.04840489380043 -0.21199137303894 -0.4253433415068 -0.30828511375012 -0.11564182857003 -0.00782271834346 0.08242901812155 0.20417825778229 0.18803986351487 0.09881707274253 0.02867726819526 0.00349643744665 0.00037768524358 3.312600063e-05 2.45936337e-06 1.5850833e-07 9.09461e-09 4.7239e-10 -8.965e-11 4.54e-12 8.14e-12 -5.6e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.1e-12 1.271e-11 -5.753e-11 9.938e-11 3.62365e-09 6.21659e-08 9.6787551e-07 1.305359333e-05 0.0001485614709 0.00137807858762 0.00984085701293 0.05550141403017 0.1465247569364 0.16792745516948 0.0919974911107 0.02403934660132 0.00238080446991 0.00026902503685 -0.00054378186112 -0.00471375317682 -0.05030059891547 -0.21038042613128 -0.41905648456675 -0.30573645238323 -0.11767143255576 -0.00847036207444 0.08243966817503 0.20435244848777 0.18809816049589 0.09880851135575 0.02866201278849 0.00349511893868 0.0003775802233 3.311895289e-05 2.45898644e-06 1.5849747e-07 9.09498e-09 4.7247e-10 -8.966e-11 4.54e-12 8.14e-12 -5.6e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.1e-12 1.271e-11 -5.753e-11 9.938e-11 3.62365e-09 6.21659e-08 9.6787551e-07 1.305359334e-05 0.00014856147111 0.00137807859149 0.00984085708499 0.05550141473313 0.14652476379233 0.1679274156868 0.09199749568283 0.02403960815391 0.00238038231637 0.000268584626 -0.00054605256598 -0.00475417153095 -0.05064938960541 -0.20898358746255 -0.41132506084637 -0.30526315761105 -0.1178770225645 -0.00853859452709 0.08244463028711 0.20437000230084 0.18810209218149 0.09880761670726 0.02866067287343 0.00349501166201 0.00037757209111 3.311845232e-05 2.45896969e-06 1.5849739e-07 9.09492e-09 4.7246e-10 -8.966e-11 4.54e-12 8.14e-12 -5.6e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.1e-12 1.271e-11 -5.753e-11 9.938e-11 3.62365e-09 6.21659e-08 9.6787551e-07 1.305359334e-05 0.00014856147109 0.00137807859129 0.00984085708594 0.05550141477533 0.14652476421498 0.16792741300529 0.09199749602284 0.02403962151147 0.00238036389514 0.00026855189641 -0.0005462307008 -0.00475761711073 -0.05068027629319 -0.20876089306519 -0.41010288065378 -0.30520487743757 -0.11789421092505 -0.00854444279056 0.08244529671856 0.20437144475819 0.18810228711632 0.09880753070235 0.02866057209541 0.00349500425755 0.00037757157078 3.311843772e-05 2.45896901e-06 1.5849694e-07 9.09486e-09 4.7245e-10 -8.966e-11 4.54e-12 8.14e-12 -5.6e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.1e-12 1.271e-11 -5.753e-11 9.938e-11 3.62365e-09 6.21659e-08 9.6787551e-07 1.305359334e-05 0.00014856147109 0.00137807859135 0.00984085708609 0.05550141477812 0.14652476420665 0.1679274128946 0.09199749605473 0.02403962206965 0.00238036327402 0.00026854984491 -0.00054624212104 -0.00475785679786 -0.05068239442552 -0.20873540884312 -0.40997059390897 -0.30519949557605 -0.1178953995985 -0.00854485943447 0.08244535727076 0.20437154494628 0.18810229292562 0.09880752384629 0.02866056553233 0.00349500381259 0.00037757156386 3.311843733e-05 2.45896822e-06 1.5849684e-07 9.09486e-09 4.7245e-10 -8.966e-11 4.54e-12 8.14e-12 -5.6e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.1e-12 1.271e-11 -5.753e-11 9.938e-11 3.62365e-09 6.21659e-08 9.6787551e-07 1.305359334e-05 0.00014856147109 0.00137807859138 0.00984085708634 0.05550141477793 0.14652476420282 0.16792741292717 0.09199749602701 0.02403962205895 0.00238036329615 0.00026854975929 -0.00054624272526 -0.00475787061521 -0.05068250493769 -0.20873309260508 -0.40995880699497 -0.30519908988362 -0.11789546987355 -0.00854488498896 0.08244536152006 0.20437155104349 0.1881022928686 0.09880752334103 0.02866056512231 0.00349500381391 0.00037757156467 3.31184363e-05 2.45896813e-06 1.5849685e-07 9.09486e-09 4.7245e-10 -8.966e-11 4.54e-12 8.14e-12 -5.6e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.1e-12 1.271e-11 -5.753e-11 9.938e-11 3.62365e-09 6.21659e-08 9.6787551e-07 1.305359334e-05 0.00014856147109 0.00137807859138 0.00984085708638 0.05550141477809 0.14652476420522 0.16792741292081 0.09199749602439 0.02403962205749 0.00238036330392 0.00026854976278 -0.00054624274204 -0.0047578712994 -0.05068250952129 -0.2087329161641 -0.40995793156197 -0.30519906392207 -0.11789547355491 -0.00854488642075 0.08244536182595 0.20437155140799 0.18810229280764 0.09880752332026 0.02866056514256 0.00349500381543 0.00037757156329 3.311843621e-05 2.45896815e-06 1.5849685e-07 9.09486e-09 4.7245e-10 -8.966e-11 4.54e-12 8.14e-12 -5.6e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.1e-12 1.271e-11 -5.753e-11 9.938e-11 3.62365e-09 6.21659e-08 9.6787551e-07 1.305359334e-05 0.00014856147109 0.00137807859138 0.00984085708638 0.05550141477812 0.14652476420544 0.16792741291801 0.09199749602735 0.0240396220607 0.00238036329992 0.00026854976175 -0.00054624273728 -0.00475787131159 -0.0506825096399 -0.20873290462493 -0.40995787581817 -0.30519906243386 -0.11789547377976 -0.00854488644121 0.08244536188705 0.20437155135562 0.1881022928021 0.09880752333602 0.02866056514975 0.00349500381404 0.00037757156319 3.311843623e-05 2.45896815e-06 1.5849685e-07 9.09486e-09 4.7245e-10 -8.966e-11 4.54e-12 8.14e-12 -5.6e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.1e-12 1.271e-11 -5.753e-11 9.938e-11 3.62365e-09 6.21659e-08 9.6787551e-07 1.305359334e-05 0.00014856147109 0.00137807859138 0.00984085708638 0.05550141477812 0.14652476420535 0.16792741291837 0.09199749602742 0.02403962206078 0.0023803632995 0.00026854976105 -0.00054624273829 -0.0047578713116 -0.05068250963931 -0.20873290398712 -0.40995787263451 -0.30519906234549 -0.117895473761 -0.00854488642738 0.08244536187556 0.20437155135178 0.18810229280643 0.09880752333407 0.02866056514635 0.0034950038139 0.00037757156322 3.311843623e-05 2.45896815e-06 1.5849685e-07 9.09486e-09 4.7245e-10 -8.966e-11 4.54e-12 8.14e-12 -5.6e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.1e-12 1.271e-11 -5.753e-11 9.938e-11 3.62365e-09 6.21659e-08 9.6787551e-07 1.305359334e-05 0.00014856147109 0.00137807859138 0.00984085708638 0.05550141477812 0.14652476420535 0.16792741291845 0.0919974960273 0.02403962206064 0.00238036329969 0.00026854976109 -0.00054624273864 -0.00475787131379 -0.05068250964678 -0.20873290401113 -0.40995787247304 -0.30519906236948 -0.11789547375711 -0.00854488643146 0.08244536187339 0.20437155135718 0.1881022928064 0.09880752333307 0.02866056514598 0.00349500381394 0.00037757156322 3.311843623e-05 2.45896815e-06 1.5849685e-07 9.09486e-09 4.7245e-10 -8.966e-11 4.54e-12 8.14e-12 -5.6e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.1e-12 1.271e-11 -5.753e-11 9.938e-11 3.62365e-09 6.21659e-08 9.6787551e-07 1.305359334e-05 0.00014856147109 0.00137807859138 0.00984085708638 0.05550141477812 0.14652476420535 0.16792741291842 0.09199749602731 0.02403962206066 0.00238036329969 0.00026854976111 -0.00054624273857 -0.0047578713137 -0.05068250964654 -0.20873290402309 -0.40995787253903 -0.30519906236858 -0.11789547375893 -0.00854488643234 0.08244536187412 0.20437155135725 0.18810229280619 0.09880752333321 0.02866056514614 0.00349500381394 0.00037757156322 3.311843623e-05 2.45896815e-06 1.5849685e-07 9.09486e-09 4.7245e-10 -8.966e-11 4.54e-12 8.14e-12 -5.6e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.1e-12 1.271e-11 -5.753e-11 9.938e-11 3.62365e-09 6.21659e-08 9.6787551e-07 1.305359334e-05 0.00014856147109 0.00137807859138 0.00984085708638 0.05550141477812 0.14652476420535 0.16792741291842 0.09199749602731 0.02403962206067 0.00238036329968 0.00026854976111 -0.00054624273856 -0.00475787131359 -0.05068250964584 -0.2087329040168 -0.40995787253139 -0.30519906236672 -0.11789547375908 -0.00854488643216 0.08244536187416 0.20437155135701 0.18810229280622 0.09880752333324 0.02866056514614 0.00349500381394 0.00037757156322 3.311843623e-05 2.45896815e-06 1.5849685e-07 9.09486e-09 4.7245e-10 -8.966e-11 4.54e-12 8.14e-12 -5.6e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.1e-12 1.271e-11 -5.753e-11 9.938e-11 3.62365e-09 6.21659e-08 9.6787551e-07 1.305359334e-05 0.00014856147109 0.00137807859138 0.00984085708638 0.05550141477812 0.14652476420535 0.16792741291842 0.09199749602731 0.02403962206066 0.00238036329968 0.00026854976111 -0.00054624273857 -0.00475787131361 -0.05068250964588 -0.20873290401621 -0.40995787252698 -0.30519906236685 -0.117895473759 -0.00854488643215 0.08244536187412 0.20437155135703 0.18810229280622 0.09880752333323 0.02866056514613 0.00349500381394 0.00037757156322 3.311843623e-05 2.45896815e-06 1.5849685e-07 9.09486e-09 4.7245e-10 -8.966e-11 4.54e-12 8.14e-12 -5.6e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.1e-12 1.271e-11 -5.753e-11 9.938e-11 3.62365e-09 6.21659e-08 9.6787551e-07 1.305359334e-05 0.00014856147109 0.00137807859138 0.00984085708638 0.05550141477812 0.14652476420535 0.16792741291842 0.09199749602731 0.02403962206066 0.00238036329968 0.00026854976111 -0.00054624273857 -0.00475787131361 -0.05068250964592 -0.20873290401652 -0.40995787252762 -0.30519906236692 -0.117895473759 -0.00854488643216 0.08244536187412 0.20437155135704 0.18810229280622 0.09880752333323 0.02866056514613 0.00349500381394 0.00037757156322 3.311843623e-05 2.45896815e-06 1.5849685e-07 9.09486e-09 4.7245e-10 -8.966e-11 4.54e-12 8.14e-12 -5.6e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.1e-12 1.271e-11 -5.753e-11 9.938e-11 3.62365e-09 6.21659e-08 9.6787551e-07 1.305359334e-05 0.00014856147109 0.00137807859138 0.00984085708638 0.05550141477812 0.14652476420535 0.16792741291842 0.09199749602731 0.02403962206066 0.00238036329968 0.00026854976111 -0.00054624273857 -0.00475787131361 -0.05068250964591 -0.20873290401652 -0.40995787252776 -0.3051990623669 -0.117895473759 -0.00854488643216 0.08244536187412 0.20437155135704 0.18810229280622 0.09880752333323 0.02866056514613 0.00349500381394 0.00037757156322 3.311843623e-05 2.45896815e-06 1.5849685e-07 9.09486e-09 4.7245e-10 -8.966e-11 4.54e-12 8.14e-12 -5.6e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.1e-12 1.271e-11 -5.753e-11 9.938e-11 3.62365e-09 6.21659e-08 9.6787551e-07 1.305359334e-05 0.00014856147109 0.00137807859138 0.00984085708638 0.05550141477812 0.14652476420535 0.16792741291842 0.09199749602731 0.02403962206066 0.00238036329968 0.00026854976111 -0.00054624273857 -0.00475787131361 -0.05068250964591 -0.2087329040165 -0.40995787252771 -0.3051990623669 -0.117895473759 -0.00854488643216 0.08244536187412 0.20437155135704 0.18810229280622 0.09880752333323 0.02866056514613 0.00349500381394 0.00037757156322 3.311843623e-05 2.45896815e-06 1.5849685e-07 9.09486e-09 4.7245e-10 -8.966e-11 4.54e-12 8.14e-12 -5.6e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.1e-12 1.271e-11 -5.753e-11 9.938e-11 3.62365e-09 6.21659e-08 9.6787551e-07 1.305359334e-05 0.00014856147109 0.00137807859138 0.00984085708638 0.05550141477812 0.14652476420535 0.16792741291842 0.09199749602731 0.02403962206066 0.00238036329968 0.00026854976111 -0.00054624273857 -0.00475787131361 -0.05068250964591 -0.2087329040165 -0.4099578725277 -0.3051990623669 -0.117895473759 -0.00854488643216 0.08244536187412 0.20437155135704 0.18810229280622 0.09880752333323 0.02866056514613 0.00349500381394 0.00037757156322 3.311843623e-05 2.45896815e-06 1.5849685e-07 9.09486e-09 4.7245e-10 -8.966e-11 4.54e-12 8.14e-12 -5.6e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.1e-12 1.271e-11 -5.753e-11 9.938e-11 3.62365e-09 6.21659e-08 9.6787551e-07 1.305359334e-05 0.00014856147109 0.00137807859138 0.00984085708638 0.05550141477812 0.14652476420535 0.16792741291842 0.09199749602731 0.02403962206066 0.00238036329968 0.00026854976111 -0.00054624273857 -0.00475787131361 -0.05068250964591 -0.2087329040165 -0.40995787252771 -0.3051990623669 -0.117895473759 -0.00854488643216 0.08244536187412 0.20437155135704 0.18810229280622 0.09880752333323 0.02866056514613 0.00349500381394 0.00037757156322 3.311843623e-05 2.45896815e-06 1.5849685e-07 9.09486e-09 4.7245e-10 -8.966e-11 4.54e-12 8.14e-12 -5.6e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.1e-12 1.271e-11 -5.753e-11 9.938e-11 3.62365e-09 6.21659e-08 9.6787551e-07 1.305359334e-05 0.00014856147109 0.00137807859138 0.00984085708638 0.05550141477812 0.14652476420535 0.16792741291842 0.09199749602731 0.02403962206066 0.00238036329968 0.00026854976111 -0.00054624273857 -0.00475787131361 -0.05068250964591 -0.2087329040165 -0.40995787252771 -0.3051990623669 -0.117895473759 -0.00854488643216 0.08244536187412 0.20437155135704 0.18810229280622 0.09880752333323 0.02866056514613 0.00349500381394 0.00037757156322 3.311843623e-05 2.45896815e-06 1.5849685e-07 9.09486e-09 4.7245e-10 -8.966e-11 4.54e-12 8.14e-12 -5.6e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.1e-12 1.271e-11 -5.753e-11 9.938e-11 3.62365e-09 6.21659e-08 9.6787551e-07 1.305359334e-05 0.00014856147109 0.00137807859138 0.00984085708638 0.05550141477812 0.14652476420535 0.16792741291842 0.09199749602731 0.02403962206066 0.00238036329968 0.00026854976111 -0.00054624273857 -0.00475787131361 -0.05068250964591 -0.2087329040165 -0.40995787252771 -0.3051990623669 -0.117895473759 -0.00854488643216 0.08244536187412 0.20437155135704 0.18810229280622 0.09880752333323 0.02866056514613 0.00349500381394 0.00037757156322 3.311843623e-05 2.45896815e-06 1.5849685e-07 9.09486e-09 4.7245e-10 -8.966e-11 4.54e-12 8.14e-12 -5.6e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.1e-12 1.271e-11 -5.753e-11 9.938e-11 3.62365e-09 6.21659e-08 9.6787551e-07 1.305359334e-05 0.00014856147109 0.00137807859138 0.00984085708638 0.05550141477812 0.14652476420535 0.16792741291842 0.09199749602731 0.02403962206066 0.00238036329968 0.00026854976111 -0.00054624273857 -0.00475787131361 -0.05068250964591 -0.2087329040165 -0.40995787252771 -0.3051990623669 -0.117895473759 -0.00854488643216 0.08244536187412 0.20437155135704 0.18810229280622 0.09880752333323 0.02866056514613 0.00349500381394 0.00037757156322 3.311843623e-05 2.45896815e-06 1.5849685e-07 9.09486e-09 4.7245e-10 -8.966e-11 4.54e-12 8.14e-12 -5.6e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.1e-12 1.271e-11 -5.753e-11 9.938e-11 3.62365e-09 6.21659e-08 9.6787551e-07 1.305359334e-05 0.00014856147109 0.00137807859138 0.00984085708638 0.05550141477812 0.14652476420535 0.16792741291842 0.09199749602731 0.02403962206066 0.00238036329968 0.00026854976111 -0.00054624273857 -0.00475787131361 -0.05068250964591 -0.2087329040165 -0.40995787252771 -0.3051990623669 -0.117895473759 -0.00854488643216 0.08244536187412 0.20437155135704 0.18810229280622 0.09880752333323 0.02866056514613 0.00349500381394 0.00037757156322 3.311843623e-05 2.45896815e-06 1.5849685e-07 9.09486e-09 4.7245e-10 -8.966e-11 4.54e-12 8.14e-12 -5.6e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.1e-12 1.271e-11 -5.753e-11 9.938e-11 3.62365e-09 6.21659e-08 9.6787551e-07 1.305359334e-05 0.00014856147109 0.00137807859138 0.00984085708638 0.05550141477812 0.14652476420535 0.16792741291842 0.09199749602731 0.02403962206066 0.00238036329968 0.00026854976111 -0.00054624273857 -0.00475787131361 -0.05068250964591 -0.2087329040165 -0.40995787252771 -0.3051990623669 -0.117895473759 -0.00854488643216 0.08244536187412 0.20437155135704 0.18810229280622 0.09880752333323 0.02866056514613 0.00349500381394 0.00037757156322 3.311843623e-05 2.45896815e-06 1.5849685e-07 9.09486e-09 4.7245e-10 -8.966e-11 4.54e-12 8.14e-12 -5.6e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.1e-12 1.271e-11 -5.753e-11 9.938e-11 3.62365e-09 6.21659e-08 9.6787551e-07 1.305359334e-05 0.00014856147109 0.00137807859138 0.00984085708638 0.05550141477812 0.14652476420535 0.16792741291842 0.09199749602731 0.02403962206066 0.00238036329968 0.00026854976111 -0.00054624273857 -0.00475787131361 -0.05068250964591 -0.2087329040165 -0.4099578725277 -0.3051990623669 -0.117895473759 -0.00854488643216 0.08244536187412 0.20437155135704 0.18810229280622 0.09880752333323 0.02866056514613 0.00349500381394 0.00037757156322 3.311843623e-05 2.45896815e-06 1.5849685e-07 9.09486e-09 4.7245e-10 -8.966e-11 4.54e-12 8.14e-12 -5.6e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.1e-12 1.271e-11 -5.753e-11 9.938e-11 3.62365e-09 6.21659e-08 9.6787551e-07 1.305359334e-05 0.00014856147109 0.00137807859138 0.00984085708638 0.05550141477812 0.14652476420535 0.16792741291842 0.09199749602731 0.02403962206066 0.00238036329968 0.00026854976111 -0.00054624273857 -0.00475787131361 -0.05068250964591 -0.2087329040165 -0.40995787252771 -0.30519906236692 -0.117895473759 -0.00854488643216 0.08244536187412 0.20437155135704 0.18810229280622 0.09880752333323 0.02866056514613 0.00349500381394 0.00037757156322 3.311843623e-05 2.45896815e-06 1.5849685e-07 9.09486e-09 4.7245e-10 -8.966e-11 4.54e-12 8.14e-12 -5.6e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.1e-12 1.271e-11 -5.753e-11 9.938e-11 3.62365e-09 6.21659e-08 9.6787551e-07 1.305359334e-05 0.00014856147109 0.00137807859138 0.00984085708638 0.05550141477812 0.14652476420535 0.16792741291842 0.09199749602731 0.02403962206066 0.00238036329968 0.00026854976111 -0.00054624273857 -0.00475787131361 -0.05068250964591 -0.20873290401652 -0.40995787252776 -0.30519906236685 -0.11789547375899 -0.00854488643214 0.08244536187412 0.20437155135703 0.18810229280623 0.09880752333323 0.02866056514613 0.00349500381394 0.00037757156322 3.311843623e-05 2.45896815e-06 1.5849685e-07 9.09486e-09 4.7245e-10 -8.966e-11 4.54e-12 8.14e-12 -5.6e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.1e-12 1.271e-11 -5.753e-11 9.938e-11 3.62365e-09 6.21659e-08 9.6787551e-07 1.305359334e-05 0.00014856147109 0.00137807859138 0.00984085708638 0.05550141477812 0.14652476420535 0.16792741291842 0.09199749602731 0.02403962206066 0.00238036329968 0.00026854976111 -0.00054624273857 -0.00475787131361 -0.05068250964592 -0.20873290401652 -0.40995787252759 -0.30519906236671 -0.1178954737591 -0.00854488643216 0.08244536187416 0.20437155135701 0.18810229280623 0.09880752333324 0.02866056514614 0.00349500381394 0.00037757156322 3.311843623e-05 2.45896815e-06 1.5849685e-07 9.09486e-09 4.7245e-10 -8.966e-11 4.54e-12 8.14e-12 -5.6e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.1e-12 1.271e-11 -5.753e-11 9.938e-11 3.62365e-09 6.21659e-08 9.6787551e-07 1.305359334e-05 0.00014856147109 0.00137807859138 0.00984085708638 0.05550141477812 0.14652476420535 0.16792741291842 0.09199749602731 0.02403962206066 0.00238036329968 0.00026854976111 -0.00054624273857 -0.00475787131361 -0.05068250964588 -0.20873290401616 -0.40995787252698 -0.30519906236873 -0.11789547375895 -0.00854488643238 0.08244536187412 0.20437155135718 0.18810229280611 0.0988075233332 0.02866056514615 0.00349500381394 0.00037757156322 3.311843623e-05 2.45896815e-06 1.5849685e-07 9.09486e-09 4.7245e-10 -8.966e-11 4.54e-12 8.14e-12 -5.6e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.1e-12 1.271e-11 -5.753e-11 9.938e-11 3.62365e-09 6.21659e-08 9.6787551e-07 1.305359334e-05 0.00014856147109 0.00137807859138 0.00984085708638 0.05550141477812 0.14652476420535 0.16792741291842 0.09199749602731 0.02403962206066 0.00238036329968 0.00026854976111 -0.00054624273857 -0.00475787131361 -0.05068250964577 -0.20873290401704 -0.40995787253206 -0.30519906236962 -0.11789547375658 -0.00854488643134 0.08244536187343 0.20437155135725 0.18810229280633 0.09880752333297 0.02866056514601 0.00349500381394 0.00037757156322 3.311843623e-05 2.45896815e-06 1.5849685e-07 9.09486e-09 4.7245e-10 -8.966e-11 4.54e-12 8.14e-12 -5.6e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.1e-12 1.271e-11 -5.753e-11 9.938e-11 3.62365e-09 6.21659e-08 9.6787551e-07 1.305359334e-05 0.00014856147109 0.00137807859138 0.00984085708638 0.05550141477812 0.14652476420535 0.16792741291842 0.09199749602731 0.02403962206066 0.00238036329968 0.0002685497611 -0.00054624273858 -0.00475787131362 -0.05068250964681 -0.20873290402393 -0.40995787253841 -0.30519906234417 -0.11789547376175 -0.00854488642684 0.08244536187552 0.20437155135292 0.18810229280847 0.09880752333432 0.02866056514614 0.0034950038139 0.00037757156322 3.311843623e-05 2.45896815e-06 1.5849685e-07 9.09486e-09 4.7245e-10 -8.966e-11 4.54e-12 8.14e-12 -5.6e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.1e-12 1.271e-11 -5.753e-11 9.938e-11 3.62365e-09 6.21659e-08 9.6787551e-07 1.305359334e-05 0.00014856147109 0.00137807859138 0.00984085708638 0.05550141477812 0.14652476420535 0.16792741291842 0.09199749602731 0.02403962206068 0.00238036329967 0.00026854976111 -0.00054624273853 -0.00475787131371 -0.05068250964776 -0.20873290400614 -0.40995787246774 -0.30519906244622 -0.11789547378302 -0.00854488644134 0.08244536188496 0.20437155135296 0.1881022928031 0.09880752333805 0.02866056514929 0.00349500381397 0.00037757156319 3.311843623e-05 2.45896815e-06 1.5849685e-07 9.09486e-09 4.7245e-10 -8.966e-11 4.54e-12 8.14e-12 -5.6e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.1e-12 1.271e-11 -5.753e-11 9.938e-11 3.62365e-09 6.21659e-08 9.6787551e-07 1.305359334e-05 0.00014856147109 0.00137807859138 0.00984085708638 0.05550141477812 0.14652476420535 0.16792741291843 0.0919974960273 0.02403962206068 0.0023803632996 0.00026854976115 -0.00054624273843 -0.00475787131367 -0.05068250963454 -0.20873290399724 -0.40995787266905 -0.30519906417864 -0.11789547349742 -0.0085448864049 0.08244536182836 0.20437155140523 0.18810229278485 0.09880752331679 0.02866056514623 0.00349500381527 0.00037757156322 3.311843621e-05 2.45896815e-06 1.5849685e-07 9.09486e-09 4.7245e-10 -8.966e-11 4.54e-12 8.14e-12 -5.6e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.1e-12 1.271e-11 -5.753e-11 9.938e-11 3.62365e-09 6.21659e-08 9.6787551e-07 1.305359334e-05 0.00014856147109 0.00137807859138 0.00984085708638 0.05550141477811 0.14652476420534 0.16792741291839 0.0919974960274 0.02403962206043 0.00238036330004 0.00026854976089 -0.00054624273965 -0.00475787131315 -0.05068250965386 -0.20873290483031 -0.40995787633556 -0.30519909371592 -0.11789546900119 -0.00854488461364 0.08244536148405 0.20437155116445 0.18810229298276 0.09880752333621 0.02866056511694 0.00349500381466 0.00037757156451 3.311843625e-05 2.45896813e-06 1.5849685e-07 9.09486e-09 4.7245e-10 -8.966e-11 4.54e-12 8.14e-12 -5.6e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.1e-12 1.271e-11 -5.753e-11 9.938e-11 3.62365e-09 6.21659e-08 9.6787551e-07 1.305359334e-05 0.00014856147109 0.00137807859138 0.00984085708638 0.0555014147781 0.14652476420541 0.1679274129185 0.09199749602676 0.02403962206034 0.00238036330212 0.00026854976036 -0.00054624274292 -0.0047578713024 -0.05068250996141 -0.20873291955604 -0.4099579394879 -0.30519954623305 -0.11789538444733 -0.00854485331453 0.08244535662643 0.20437154685599 0.18810229453051 0.09880752399306 0.02866056536136 0.00349500380364 0.00037757156425 3.311843727e-05 2.45896819e-06 1.5849684e-07 9.09486e-09 4.7245e-10 -8.966e-11 4.54e-12 8.14e-12 -5.6e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.1e-12 1.271e-11 -5.753e-11 9.938e-11 3.62365e-09 6.21659e-08 9.6787551e-07 1.305359334e-05 0.00014856147109 0.00137807859139 0.0098408570864 0.05550141477817 0.14652476420503 0.16792741292125 0.09199749602446 0.02403962206324 0.00238036329546 0.00026854976083 -0.00054624273896 -0.00475787109148 -0.05068251204579 -0.20873314110636 -0.40995891146308 -0.30520543136122 -0.11789398964564 -0.00854435802231 0.08244528857854 0.20437147327294 0.18810231104917 0.09880753289025 0.02866056971826 0.00349500405432 0.00037757155987 3.311843768e-05 2.458969e-06 1.5849693e-07 9.09486e-09 4.7245e-10 -8.966e-11 4.54e-12 8.14e-12 -5.6e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.1e-12 1.271e-11 -5.753e-11 9.938e-11 3.62365e-09 6.21659e-08 9.6787551e-07 1.305359334e-05 0.00014856147109 0.00137807859137 0.0098408570863 0.0555014147787 0.14652476420508 0.1679274129082 0.09199749604022 0.02403962206451 0.00238036329745 0.00026854975252 -0.00054624275671 -0.00475786479831 -0.05068249314089 -0.20873601553912 -0.40997173020608 -0.30526806948862 -0.11787431513069 -0.00853759990558 0.0824445337652 0.20437036207249 0.18810240949778 0.09880764532991 0.02866064184902 0.0034950088653 0.00037757189015 3.311844174e-05 2.45896953e-06 1.5849742e-07 9.09492e-09 4.7246e-10 -8.966e-11 4.54e-12 8.14e-12 -5.6e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.1e-12 1.271e-11 -5.753e-11 9.938e-11 3.62365e-09 6.21659e-08 9.6787551e-07 1.305359334e-05 0.00014856147109 0.00137807859132 0.00984085708602 0.05550141477799 0.14652476421292 0.16792741289996 0.09199749599423 0.0240396217899 0.00238036394198 0.00026854998504 -0.00054624092283 -0.00475773596543 -0.05068165491846 -0.2087676544148 -0.41011244941903 -0.30576787693259 -0.11764475455183 -0.00846076197637 0.08243860451545 0.20435625166097 0.18810156650254 0.09880881392423 0.02866167191536 0.00349508625637 0.00037757771719 3.31187972e-05 2.45897846e-06 1.584972e-07 9.09498e-09 4.7247e-10 -8.966e-11 4.54e-12 8.14e-12 -5.6e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.1e-12 1.271e-11 -5.753e-11 9.938e-11 3.62365e-09 6.21659e-08 9.6787551e-07 1.305359334e-05 0.00014856147112 0.00137807859174 0.00984085708859 0.05550141476535 0.1465247640782 0.16792741369725 0.09199749535362 0.0240396139173 0.00238037923873 0.00026856060275 -0.00054617005198 -0.00475530413592 -0.05065942265445 -0.20902610659684 -0.41139467090141 -0.30846456097354 -0.11541297661493 -0.00773937395671 0.08241602234054 0.20420969393834 0.18807210218922 0.09881884636427 0.0286739314486 0.00349611914945 0.00037766026254 3.312440147e-05 2.45927715e-06 1.5850407e-07 9.09442e-09 4.7239e-10 -8.965e-11 4.54e-12 8.14e-12 -5.6e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.1e-12 1.271e-11 -5.753e-11 9.938e-11 3.62365e-09 6.21659e-08 9.6787551e-07 1.305359335e-05 0.00014856147118 0.00137807859145 0.00984085706528 0.05550141445955 0.14652476073698 0.16792743195849 0.09199748616738 0.02403942431004 0.00238072266641 0.00026878493504 -0.00054487924577 -0.0047229553548 -0.05036036814543 -0.21058953959141 -0.41933480332063 -0.28861592464942 -0.10492765177475 -0.00403158840983 0.08277818285588 0.20290344982976 0.18754093781795 0.09892342011329 0.02880665611416 0.00350810651759 0.00037865386439 3.319298544e-05 2.46337395e-06 1.5872227e-07 9.10378e-09 4.7273e-10 -8.965e-11 4.54e-12 8.13e-12 -5.6e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.1e-12 1.271e-11 -5.753e-11 9.938e-11 3.62365e-09 6.21659e-08 9.6787551e-07 1.30535933e-05 0.00014856147012 0.0013780785707 0.00984085663056 0.0555014094163 0.14652471522468 0.16792765565038 0.09199737806172 0.02403751045195 0.00238354424518 0.00027142286334 -0.00052950748207 -0.00448837480191 -0.04848936142425 -0.21229977587483 -0.42599674689978 0.0 0.0 0.0031349858265 0.07928039274837 0.19836935994254 0.1855765184693 0.09888941940196 0.0294325081631 0.00357076041696 0.00038444048197 3.362826683e-05 2.49097674e-06 1.6028942e-07 9.18878e-09 4.7833e-10 -8.977e-11 4.4e-12 8.18e-12 -5.5e-13 -3.1e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.1e-12 1.271e-11 -5.753e-11 9.938e-11 3.62365e-09 6.21659e-08 9.6787549e-07 1.305359297e-05 0.00014856146206 0.00137807838969 0.00984085212037 0.05550135226131 0.14652441732219 0.16792997811154 0.09200236486724 0.02400618280011 0.00236504299502 0.00031782644451 -0.00023734545321 -0.0016755011474 -0.00931854733915 0.0 0.0 0.0 0.0 0.0 0.0 0.11852908155854 0.16740919328852 0.0971362637036 0.03205968645666 0.00384654252988 0.00040901657944 3.555604584e-05 2.61959769e-06 1.6775612e-07 9.57825e-09 5.0275e-10 -9.008e-11 3.71e-12 8.34e-12 -5.2e-13 -3.2e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.1e-12 1.271e-11 -5.753e-11 9.938e-11 3.62365e-09 6.21659e-08 9.6787555e-07 1.305359415e-05 0.00014856148283 0.0013780787058 0.00984085651621 0.05550139395974 0.14652458807124 0.16792947745147 0.09200469442459 0.02402690813353 0.00236860471509 0.00025864735582 -6.380844418e-05 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.08163939405688 0.15734644469257 0.08159978557714 0.02586298614701 0.00316704196968 0.00034285264518 3.024030177e-05 2.25635069e-06 1.4603557e-07 8.43082e-09 4.3168e-10 -8.872e-11 5.55e-12 7.84e-12 -5.9e-13 -2.9e-13 7e-14 1e-14 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.1e-12 1.271e-11 -5.753e-11 9.938e-11 3.62365e-09 6.216591e-08 9.6787584e-07 1.305359973e-05 0.00014856157576 0.00137808002406 0.0098408733939 0.05550154757543 0.14652503370365 0.16792638633793 0.09200607473665 0.02403489082555 0.00239839783288 0.00017142235231 2.144081753e-05 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.04046409185891 0.02141295970751 0.00661010378828 0.00086162772385 9.670265494e-05 8.78111161e-06 6.7197908e-07 4.446435e-08 2.67489e-09 3.751e-11 -4.458e-11 1.302e-11 2.98e-12 -8e-13 -4e-14 5e-14 -0.0 -1e-14 -0.0 6e-14 -9e-14 -8.5e-13 4.1e-12 1.271e-11 -5.753e-11 9.938e-11 3.62365e-09 6.21659e-08 9.6787563e-07 1.305359567e-05 0.00014856150992 0.00137807912995 0.00984086296426 0.05550146087045 0.14652482067957 0.16792776157841 0.09200461268218 0.02403465968044 0.00239941432965 0.00017978975883 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.00553050301052 0.00767056873707 0.00202217912408 0.00025015275698 2.664961522e-05 2.36452258e-06 1.7945236e-07 1.189151e-08 7.29e-10 -9.607e-11 -3.87e-12 1.128e-11 -1.1e-13 -5.5e-13 8e-14 2e-14 -1e-14 -0.0 -0.0 6e-14 -9e-14 -8.5e-13 4.1e-12 1.271e-11 -5.753e-11 9.938e-11 3.62365e-09 6.21659e-08 9.6787543e-07 1.30535915e-05 0.00014856143508 0.00137807797521 0.00984084639712 0.05550130241935 0.14652424693627 0.16793155129081 0.09200412767475 0.02400735981967 0.00236819822035 0.00031313450631 0.0 0.0 0.0 0.0 0.0 D/cons.4.00.000000.dat 2.5000005 2.5000005 2.5000005 2.5000005 2.5000005 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 2.5000005 2.5000005 2.5000005 2.5000005 2.5000005 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 2.5000005 2.5000005 2.5000005 2.5000005 2.5000005 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 2.5000005 2.5000005 2.5000005 2.5000005 2.5000005 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 2.5000005 2.5000005 2.5000005 2.5000005 2.5000005 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 2.5000005 2.5000005 2.5000005 2.5000005 2.5000005 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 2.5000005 2.5000005 2.5000005 2.5000005 2.5000005 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 2.5000005 2.5000005 2.5000005 2.5000005 2.5000005 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 2.5000005 2.5000005 2.5000005 2.5000005 2.5000005 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 2.5000005 2.5000005 2.5000005 2.5000005 2.5000005 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 2.5000005 2.5000005 2.5000005 2.5000005 2.5000005 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 2.5000005 2.5000005 2.5000005 2.5000005 2.5000005 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 2.5000005 2.5000005 2.5000005 2.5000005 2.5000005 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 2.5000005 2.5000005 2.5000005 2.5000005 2.5000005 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 2.5000005 2.5000005 2.5000005 2.5000005 2.5000005 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 2.5000005 2.5000005 2.5000005 2.5000005 2.5000005 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 2.5000005 2.5000005 2.5000005 2.5000005 2.5000005 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 2.5000005 2.5000005 2.5000005 2.5000005 2.5000005 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 2.5000005 2.5000005 2.5000005 2.5000005 2.5000005 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 2.5000005 2.5000005 2.5000005 2.5000005 2.5000005 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 2.5000005 2.5000005 2.5000005 2.5000005 2.5000005 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 2.5000005 2.5000005 2.5000005 2.5000005 2.5000005 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 2.5000005 2.5000005 2.5000005 2.5000005 2.5000005 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 2.5000005 2.5000005 2.5000005 2.5000005 2.5000005 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 2.5000005 2.5000005 2.5000005 2.5000005 2.5000005 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 2.5000005 2.5000005 2.5000005 2.5000005 2.5000005 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 2.5000005 2.5000005 2.5000005 2.5000005 2.5000005 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 2.5000005 2.5000005 2.5000005 2.5000005 2.5000005 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 2.5000005 2.5000005 2.5000005 2.5000005 2.5000005 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 2.5000005 2.5000005 2.5000005 2.5000005 2.5000005 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 2.5000005 2.5000005 2.5000005 2.5000005 2.5000005 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 2.5000005 2.5000005 2.5000005 2.5000005 2.5000005 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 2.5000005 2.5000005 2.5000005 2.5000005 2.5000005 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 2.5000005 2.5000005 2.5000005 2.5000005 2.5000005 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 2.5000005 2.5000005 2.5000005 2.5000005 2.5000005 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 2.5000005 2.5000005 2.5000005 2.5000005 2.5000005 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 2.5000005 2.5000005 2.5000005 2.5000005 2.5000005 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 2.5000005 2.5000005 2.5000005 2.5000005 2.5000005 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 2.5000005 2.5000005 2.5000005 2.5000005 2.5000005 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 2.5000005 2.5000005 2.5000005 2.5000005 2.5000005 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 2.5000005 2.5000005 2.5000005 2.5000005 2.5000005 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 2.5000005 2.5000005 2.5000005 2.5000005 2.5000005 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 2.5000005 2.5000005 2.5000005 2.5000005 2.5000005 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 2.5000005 2.5000005 2.5000005 2.5000005 2.5000005 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 2.5000005 2.5000005 2.5000005 2.5000005 2.5000005 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 2.5000005 2.5000005 2.5000005 2.5000005 2.5000005 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 2.5000005 2.5000005 2.5000005 2.5000005 2.5000005 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 2.5000005 2.5000005 2.5000005 2.5000005 2.5000005 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 2.5000005 2.5000005 2.5000005 2.5000005 2.5000005 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 2.5000005 2.5000005 2.5000005 2.5000005 2.5000005 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 1.25000025 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 0.2500000625 -D/cons.4.00.000050.dat 2.5000005 1.28765665157671 1.28233774583049 1.3730431173692 1.43481445157317 1.35661926521261 1.30052380036225 1.25990953083113 1.25129375719234 1.25013878904764 1.25001247132286 1.25000116492886 1.25000030937296 1.25000025319221 1.25000024982678 1.25000024994805 1.25000025003876 1.2500002500021 1.25000024999797 1.25000025000015 1.2500002500001 1.25000024999998 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.25000024998796 1.25000024996134 1.25000025017023 1.25000024966774 1.25000023959633 1.25000006616466 1.24999738689441 1.24996163705958 1.24956080701305 1.24592396807319 1.22089826115419 1.08410590450285 0.80688085036114 0.59415378170774 0.47924915719521 0.31247866534241 0.25626209003631 0.25050861264119 0.25047883151923 0.2545214981436 0.30455668455819 0.3784040959543 0.2500000625 2.33081897571178 1.65527415948872 1.53803410542435 1.48153655394781 1.45011105656182 1.39737987380852 1.34362189930212 1.27412527013766 1.25305687749988 1.25033804094179 1.25003060450773 1.25000255384404 1.25000040081421 1.25000025849137 1.25000025020738 1.25000024985381 1.2500002500396 1.2500002500097 1.25000024999758 1.25000024999983 1.25000025000016 1.25000024999999 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.25000024998796 1.25000024996134 1.25000025017023 1.25000024966774 1.25000023959633 1.25000006616467 1.24999738689448 1.2499616370605 1.24956080701457 1.24592396779781 1.2208982507209 1.0841058098054 0.80688107410509 0.59415311126975 0.47924870687498 0.31240925036942 0.25624716941571 0.25059222302881 0.25043805660611 0.2509760912935 0.25387231470168 0.25088683490529 0.70393129585016 2.17910745481097 2.19605345582199 1.88280392522102 1.67349190863522 1.60050626427292 1.50824073129327 1.47376040991629 1.32479188942019 1.25911903948391 1.25098520617626 1.25008702343883 1.25000671561657 1.25000066808089 1.25000027410664 1.25000025113203 1.2500002497677 1.25000025001627 1.25000025002272 1.25000024999829 1.25000024999916 1.2500002500002 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.25000024998796 1.25000024996134 1.25000025017023 1.25000024966774 1.25000023959633 1.25000006616469 1.24999738689496 1.2499616370703 1.24956080718946 1.24592397042853 1.22089828433326 1.08410605645389 0.80688034010881 0.5941557829314 0.47924443262362 0.31243198434529 0.25620153220573 0.25059124012382 0.24992377766829 0.25000918055091 0.25049001964705 0.25904448628118 0.65969589214596 2.21465764257259 2.3578380443945 2.21745177288698 1.93244205289062 1.70097176095038 1.56836554309338 1.52393342610464 1.34076453277863 1.26106317314241 1.25118600149179 1.25010380287696 1.25000790026364 1.25000074082765 1.25000027806525 1.25000025131804 1.25000024976439 1.25000025001068 1.25000025002462 1.25000024999849 1.25000024999905 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.25000024998796 1.25000024996134 1.25000025017023 1.25000024966774 1.25000023959633 1.25000006616466 1.24999738689432 1.24996163705768 1.24956080697786 1.24592396751982 1.220898252791 1.08410584018065 0.80688092826328 0.59415396001275 0.47924404741606 0.31244877262358 0.25624872759161 0.25058589527898 0.24995672136299 0.25178499671554 0.25937105602028 0.37409017634176 0.80988488663987 2.26583803530046 2.28352910774286 2.423959882721 2.19062050163885 1.90533204196797 1.66970502991196 1.54504651214616 1.33688295329616 1.26054122007877 1.25113727122432 1.25009974462094 1.25000761997243 1.2500007242834 1.25000027712842 1.25000025126504 1.25000024976334 1.25000025001299 1.25000025002418 1.25000024999838 1.25000024999908 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.25000024998796 1.25000024996134 1.25000025017023 1.25000024966774 1.25000023959633 1.25000006616465 1.2499973868941 1.24996163705301 1.2495608068941 1.24592396629385 1.22089823881935 1.08410573442657 0.80688135739176 0.5941520613169 0.47925472186346 0.31248840509227 0.2562450338771 0.25047745339528 0.25051310789835 0.25446583398383 0.27728892538585 0.51668532577007 0.91369629277167 1.62875423104341 2.21433416584633 2.36524902440639 2.25376797026712 1.94955202503688 1.68673906018752 1.54630613608229 1.33519856730151 1.26036607567906 1.25112085985883 1.25009849833521 1.25000754068539 1.25000071960541 1.25000027683472 1.25000025125141 1.25000024976376 1.25000025001333 1.25000025002402 1.25000024999837 1.25000024999909 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.25000024998796 1.25000024996134 1.25000025017023 1.25000024966774 1.25000023959633 1.25000006616465 1.24999738689397 1.24996163705036 1.24956080684374 1.24592396541785 1.22089822225606 1.08410559514668 0.80688173902133 0.59415185611001 0.4792682561123 0.31244614438582 0.25612773168047 0.25084453346312 0.25073355205009 0.2611421950968 0.36709607874767 0.73180263309101 1.12602005149118 1.50810773678471 2.17916219721121 2.35688056282079 2.26961221060938 1.95616102830422 1.68938697019561 1.54575582132277 1.33469387024147 1.2603205924002 1.25111708774072 1.25009823989394 1.25000752504637 1.25000071874376 1.25000027680336 1.25000025125077 1.25000024976371 1.25000025001334 1.25000025002403 1.25000024999837 1.25000024999909 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.25000024998796 1.25000024996134 1.25000025017023 1.25000024966774 1.25000023959633 1.25000006616465 1.24999738689395 1.24996163704995 1.24956080683558 1.24592396526981 1.22089821948155 1.08410557010082 0.80688179040657 0.59415152238893 0.4792707981183 0.31244153990989 0.25611680519282 0.25089238524692 0.25079970399871 0.26222745883976 0.37837229707366 0.73567111049254 1.10529352860691 1.46391187236619 2.16975329902974 2.35515490903136 2.27183673558191 1.95699469068369 1.68962336351348 1.54560464300319 1.33462732832857 1.26031517324429 1.25111667170621 1.25009821265214 1.25000752375569 1.25000071874245 1.2500002768078 1.25000025125102 1.25000024976366 1.25000025001334 1.25000025002403 1.25000024999837 1.25000024999909 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.25000024998796 1.25000024996134 1.25000025017023 1.25000024966774 1.25000023959633 1.25000006616465 1.24999738689395 1.24996163704992 1.24956080683487 1.24592396525636 1.22089821924188 1.08410556758697 0.806881797274 0.59415146352566 0.47927108978961 0.31244091450737 0.25611586932915 0.25089958571369 0.25080884016986 0.26239719486976 0.38025305743535 0.73475677106473 1.08452970894232 1.45813915142467 2.16849958645291 2.35496999231165 2.27209023537466 1.95707912457489 1.68963860396564 1.54558747256569 1.33462059691913 1.26031466920266 1.2511166353901 1.25009821051025 1.25000752378315 1.25000071874374 1.25000027680748 1.25000025125097 1.25000024976367 1.25000025001334 1.25000025002403 1.25000024999837 1.25000024999909 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.25000024998796 1.25000024996134 1.25000025017023 1.25000024966774 1.25000023959633 1.25000006616465 1.24999738689395 1.24996163704993 1.24956080683496 1.24592396525745 1.22089821925159 1.08410556758795 0.80688179749901 0.5941514593878 0.47927111483397 0.31244088002367 0.25611581319156 0.25090004804712 0.25080966715201 0.26241235661417 0.38041984691865 0.73441065243879 1.08088322920947 1.45752457011839 2.16836750742587 2.35495362167862 2.27211364453789 1.95708610857827 1.68963914715607 1.54558584031272 1.33462004623658 1.26031463079388 1.2511166327657 1.2500982105851 1.25000752377365 1.25000071873992 1.25000027680715 1.25000025125095 1.25000024976367 1.25000025001334 1.25000025002403 1.25000024999837 1.25000024999909 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.25000024998796 1.25000024996134 1.25000025017023 1.25000024966774 1.25000023959633 1.25000006616465 1.24999738689395 1.24996163704993 1.24956080683494 1.24592396525713 1.22089821924848 1.08410556761514 0.80688179736025 0.59415145924273 0.47927111660625 0.31244087836049 0.25611581013949 0.25090007435307 0.25080972790069 0.26241346332821 0.38043200375621 0.73435630552198 1.08047243087626 1.45747205294573 2.16835633428957 2.35495241228708 2.27211545383615 1.95708659435412 1.68963913442083 1.54558571442991 1.33462000828895 1.26031462823468 1.2511166328615 1.25009821058475 1.25000752376402 1.25000071873935 1.25000027680713 1.25000025125095 1.25000024976367 1.25000025001334 1.25000025002403 1.25000024999837 1.25000024999909 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.25000024998796 1.25000024996134 1.25000025017023 1.25000024966774 1.25000023959633 1.25000006616465 1.24999738689395 1.24996163704993 1.24956080683493 1.24592396525697 1.22089821924666 1.08410556760071 0.80688179737031 0.59415145934367 0.47927111654091 0.31244087838519 0.25611581009498 0.25090007546754 0.25080973142821 0.2624135309034 0.38043272667346 0.73435048353358 1.0804347551429 1.45746829502039 2.16835554245043 2.35495233540072 2.2721155734934 1.95708662382261 1.68963913023032 1.5455857058837 1.33462000585052 1.26031462835906 1.25111663287978 1.25009821056939 1.25000752376399 1.25000071873947 1.25000027680714 1.25000025125095 1.25000024976367 1.25000025001334 1.25000025002403 1.25000024999837 1.25000024999909 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.25000024998796 1.25000024996134 1.25000025017023 1.25000024966774 1.25000023959633 1.25000006616465 1.24999738689395 1.24996163704992 1.24956080683493 1.24592396525696 1.22089821924645 1.08410556759749 0.80688179737904 0.5941514593243 0.47927111650726 0.31244087841994 0.25611581012849 0.25090007537724 0.25080973145741 0.26241353426035 0.38043276297954 0.73434998585076 1.08043190339454 1.4574680635083 2.16835549388864 2.35495233047904 2.27211558097385 1.95708662586375 1.68963912997129 1.54558570545882 1.33462000602773 1.26031462838404 1.25111663286008 1.25009821056942 1.25000752376423 1.25000071873947 1.25000027680714 1.25000025125095 1.25000024976367 1.25000025001334 1.25000025002403 1.25000024999837 1.25000024999909 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.25000024998796 1.25000024996134 1.25000025017023 1.25000024966774 1.25000023959633 1.25000006616465 1.24999738689395 1.24996163704992 1.24956080683493 1.24592396525696 1.2208982192465 1.08410556759792 0.80688179737783 0.59415145931692 0.47927111652623 0.31244087841033 0.25611581011315 0.25090007536995 0.25080973141084 0.2624135342789 0.38043276428807 0.73434995045169 1.08043171942795 1.45746805069441 2.16835549086488 2.35495233061409 2.27211558119852 1.95708662553035 1.68963913009993 1.54558570568034 1.33462000607052 1.26031462836298 1.25111663285965 1.25009821056985 1.2500075237642 1.25000071873947 1.25000027680714 1.25000025125095 1.25000024976367 1.25000025001334 1.25000025002403 1.25000024999837 1.25000024999909 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.25000024998796 1.25000024996134 1.25000025017023 1.25000024966774 1.25000023959633 1.25000006616465 1.24999738689395 1.24996163704992 1.24956080683493 1.24592396525697 1.22089821924651 1.08410556759802 0.80688179737761 0.59415145931806 0.47927111652762 0.31244087840859 0.25611581011151 0.25090007538333 0.25080973142958 0.26241353424956 0.38043276424283 0.73434994838131 1.080431708874 1.45746804997175 2.16835549109964 2.35495233070397 2.27211558101723 1.95708662550136 1.68963913008374 1.54558570565296 1.33462000604436 1.26031462836231 1.25111663286029 1.25009821056977 1.25000752376419 1.25000071873947 1.25000027680714 1.25000025125095 1.25000024976367 1.25000025001334 1.25000025002403 1.25000024999837 1.25000024999909 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.25000024998796 1.25000024996134 1.25000025017023 1.25000024966774 1.25000023959633 1.25000006616464 1.24999738689395 1.24996163704993 1.24956080683493 1.24592396525696 1.22089821924651 1.08410556759799 0.8068817973777 0.59415145931829 0.47927111652669 0.31244087840896 0.25611581011228 0.25090007538306 0.25080973143215 0.26241353426876 0.38043276425231 0.73434994848992 1.080431708342 1.45746805019298 2.16835549115101 2.35495233066908 2.27211558105144 1.95708662553437 1.6896391300739 1.54558570563732 1.3346200060426 1.26031462836304 1.2511166328602 1.25009821056976 1.25000752376419 1.25000071873947 1.25000027680714 1.25000025125095 1.25000024976367 1.25000025001334 1.25000025002403 1.25000024999837 1.25000024999909 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.25000024998796 1.25000024996134 1.25000025017023 1.25000024966774 1.25000023959633 1.25000006616465 1.24999738689395 1.24996163704992 1.24956080683493 1.24592396525697 1.2208982192465 1.08410556759798 0.80688179737769 0.5941514593182 0.47927111652674 0.31244087840901 0.25611581011226 0.25090007538255 0.25080973143116 0.26241353426955 0.38043276426284 0.73434994853124 1.08043170855919 1.45746805017681 2.16835549112024 2.35495233066513 2.27211558106226 1.95708662553478 1.68963913007495 1.54558570563948 1.33462000604376 1.26031462836296 1.25111663286018 1.25009821056976 1.25000752376419 1.25000071873947 1.25000027680714 1.25000025125096 1.25000024976367 1.25000025001334 1.25000025002403 1.25000024999837 1.25000024999909 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.25000024998796 1.25000024996134 1.25000025017023 1.25000024966774 1.25000023959633 1.25000006616465 1.24999738689395 1.24996163704992 1.24956080683493 1.24592396525697 1.22089821924651 1.08410556759799 0.80688179737769 0.5941514593182 0.47927111652678 0.31244087840899 0.25611581011222 0.25090007538263 0.25080973143116 0.26241353426856 0.38043276426027 0.73434994850782 1.08043170853285 1.45746805016106 2.16835549111845 2.35495233066677 2.27211558105992 1.95708662553315 1.6896391300753 1.54558570564001 1.33462000604372 1.26031462836294 1.25111663286018 1.25009821056976 1.25000752376419 1.25000071873947 1.25000027680714 1.25000025125095 1.25000024976367 1.25000025001334 1.25000025002403 1.25000024999837 1.25000024999909 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.25000024998796 1.25000024996134 1.25000025017023 1.25000024966774 1.25000023959633 1.25000006616464 1.24999738689395 1.24996163704993 1.24956080683493 1.24592396525697 1.22089821924651 1.08410556759798 0.80688179737769 0.5941514593182 0.47927111652678 0.31244087840899 0.25611581011223 0.25090007538265 0.25080973143121 0.26241353426864 0.38043276426007 0.73434994850585 1.08043170851824 1.45746805016255 2.1683554911198 2.35495233066677 2.27211558105969 1.95708662553331 1.68963913007521 1.54558570563984 1.33462000604366 1.26031462836294 1.25111663286018 1.25009821056976 1.25000752376419 1.25000071873947 1.25000027680714 1.25000025125095 1.25000024976367 1.25000025001334 1.25000025002403 1.25000024999837 1.25000024999909 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.25000024998796 1.25000024996134 1.25000025017023 1.25000024966775 1.25000023959633 1.25000006616465 1.24999738689395 1.24996163704993 1.24956080683493 1.24592396525697 1.22089821924651 1.08410556759798 0.80688179737769 0.5941514593182 0.47927111652678 0.31244087840899 0.25611581011223 0.25090007538264 0.25080973143121 0.26241353426868 0.38043276426027 0.73434994850701 1.08043170852043 1.45746805016309 2.16835549111974 2.35495233066669 2.27211558105985 1.95708662553338 1.6896391300752 1.54558570563983 1.33462000604367 1.26031462836294 1.25111663286018 1.25009821056976 1.25000752376419 1.25000071873947 1.25000027680714 1.25000025125095 1.25000024976367 1.25000025001334 1.25000025002403 1.25000024999837 1.25000024999909 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.25000024998796 1.25000024996134 1.25000025017023 1.25000024966774 1.25000023959633 1.25000006616465 1.24999738689395 1.24996163704992 1.24956080683493 1.24592396525697 1.22089821924651 1.08410556759798 0.80688179737769 0.5941514593182 0.47927111652678 0.31244087840899 0.25611581011223 0.25090007538264 0.25080973143121 0.26241353426868 0.38043276426025 0.734349948507 1.08043170852086 1.45746805016295 2.16835549111968 2.3549523306667 2.27211558105984 1.95708662553337 1.68963913007521 1.54558570563983 1.33462000604367 1.26031462836294 1.25111663286018 1.25009821056976 1.25000752376419 1.25000071873947 1.25000027680714 1.25000025125095 1.25000024976367 1.25000025001334 1.25000025002403 1.25000024999837 1.25000024999909 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.25000024998796 1.25000024996134 1.25000025017023 1.25000024966774 1.25000023959633 1.25000006616465 1.24999738689395 1.24996163704993 1.24956080683493 1.24592396525697 1.22089821924651 1.08410556759798 0.80688179737769 0.5941514593182 0.47927111652678 0.31244087840899 0.25611581011223 0.25090007538264 0.25080973143121 0.26241353426867 0.38043276426024 0.73434994850693 1.08043170852069 1.45746805016294 2.16835549111968 2.3549523306667 2.27211558105984 1.95708662553337 1.68963913007521 1.54558570563983 1.33462000604367 1.26031462836294 1.25111663286018 1.25009821056976 1.25000752376419 1.25000071873947 1.25000027680714 1.25000025125095 1.25000024976367 1.25000025001334 1.25000025002403 1.25000024999837 1.25000024999909 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.25000024998796 1.25000024996134 1.25000025017023 1.25000024966774 1.25000023959633 1.25000006616465 1.24999738689395 1.24996163704993 1.24956080683493 1.24592396525696 1.22089821924651 1.08410556759799 0.80688179737769 0.5941514593182 0.47927111652678 0.31244087840899 0.25611581011223 0.25090007538264 0.25080973143121 0.26241353426868 0.38043276426025 0.73434994850694 1.08043170852069 1.45746805016295 2.16835549111969 2.3549523306667 2.27211558105984 1.95708662553337 1.68963913007521 1.54558570563983 1.33462000604367 1.26031462836294 1.25111663286018 1.25009821056976 1.25000752376419 1.25000071873947 1.25000027680714 1.25000025125095 1.25000024976367 1.25000025001334 1.25000025002403 1.25000024999837 1.25000024999909 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.25000024998796 1.25000024996134 1.25000025017023 1.25000024966774 1.25000023959633 1.25000006616465 1.24999738689395 1.24996163704993 1.24956080683493 1.24592396525697 1.22089821924651 1.08410556759798 0.80688179737769 0.5941514593182 0.47927111652678 0.31244087840899 0.25611581011223 0.25090007538264 0.25080973143121 0.26241353426868 0.38043276426025 0.73434994850694 1.08043170852069 1.45746805016295 2.16835549111969 2.3549523306667 2.27211558105984 1.95708662553337 1.68963913007521 1.54558570563983 1.33462000604367 1.26031462836294 1.25111663286018 1.25009821056976 1.25000752376419 1.25000071873947 1.25000027680714 1.25000025125095 1.25000024976367 1.25000025001334 1.25000025002403 1.25000024999837 1.25000024999909 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.25000024998796 1.25000024996134 1.25000025017023 1.25000024966774 1.25000023959633 1.25000006616465 1.24999738689395 1.24996163704993 1.24956080683493 1.24592396525697 1.22089821924651 1.08410556759798 0.80688179737769 0.5941514593182 0.47927111652678 0.31244087840899 0.25611581011223 0.25090007538264 0.25080973143121 0.26241353426868 0.38043276426025 0.73434994850694 1.08043170852069 1.45746805016295 2.16835549111969 2.3549523306667 2.27211558105984 1.95708662553337 1.68963913007521 1.54558570563983 1.33462000604367 1.26031462836294 1.25111663286018 1.25009821056976 1.25000752376419 1.25000071873947 1.25000027680714 1.25000025125095 1.25000024976367 1.25000025001334 1.25000025002403 1.25000024999837 1.25000024999909 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.25000024998796 1.25000024996134 1.25000025017023 1.25000024966774 1.25000023959633 1.25000006616465 1.24999738689395 1.24996163704993 1.24956080683493 1.24592396525697 1.22089821924651 1.08410556759798 0.80688179737769 0.5941514593182 0.47927111652678 0.31244087840899 0.25611581011223 0.25090007538264 0.25080973143121 0.26241353426868 0.38043276426025 0.73434994850694 1.08043170852069 1.45746805016295 2.16835549111969 2.3549523306667 2.27211558105984 1.95708662553337 1.68963913007521 1.54558570563983 1.33462000604367 1.26031462836294 1.25111663286018 1.25009821056976 1.25000752376419 1.25000071873947 1.25000027680714 1.25000025125095 1.25000024976367 1.25000025001334 1.25000025002403 1.25000024999837 1.25000024999909 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.25000024998796 1.25000024996134 1.25000025017023 1.25000024966774 1.25000023959633 1.25000006616465 1.24999738689395 1.24996163704992 1.24956080683493 1.24592396525697 1.22089821924651 1.08410556759798 0.80688179737769 0.5941514593182 0.47927111652678 0.31244087840899 0.25611581011223 0.25090007538264 0.25080973143121 0.26241353426868 0.38043276426025 0.73434994850694 1.08043170852069 1.45746805016295 2.16835549111969 2.3549523306667 2.27211558105984 1.95708662553337 1.68963913007521 1.54558570563983 1.33462000604367 1.26031462836294 1.25111663286018 1.25009821056976 1.25000752376419 1.25000071873947 1.25000027680714 1.25000025125095 1.25000024976367 1.25000025001334 1.25000025002403 1.25000024999837 1.25000024999909 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.25000024998796 1.25000024996134 1.25000025017023 1.25000024966774 1.25000023959633 1.25000006616465 1.24999738689395 1.24996163704993 1.24956080683493 1.24592396525697 1.2208982192465 1.08410556759799 0.80688179737769 0.5941514593182 0.47927111652678 0.31244087840899 0.25611581011223 0.25090007538264 0.25080973143121 0.26241353426868 0.38043276426025 0.73434994850694 1.08043170852069 1.45746805016295 2.16835549111969 2.3549523306667 2.27211558105984 1.95708662553337 1.68963913007521 1.54558570563983 1.33462000604367 1.26031462836294 1.25111663286018 1.25009821056976 1.25000752376419 1.25000071873947 1.25000027680714 1.25000025125095 1.25000024976367 1.25000025001334 1.25000025002403 1.25000024999837 1.25000024999909 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.25000024998796 1.25000024996134 1.25000025017023 1.25000024966774 1.25000023959633 1.25000006616464 1.24999738689395 1.24996163704993 1.24956080683493 1.24592396525697 1.22089821924651 1.08410556759799 0.80688179737769 0.5941514593182 0.47927111652678 0.31244087840899 0.25611581011223 0.25090007538264 0.25080973143121 0.26241353426868 0.38043276426025 0.73434994850694 1.0804317085207 1.45746805016294 2.16835549111968 2.3549523306667 2.27211558105984 1.95708662553337 1.68963913007521 1.54558570563983 1.33462000604367 1.26031462836294 1.25111663286018 1.25009821056976 1.25000752376419 1.25000071873947 1.25000027680714 1.25000025125095 1.25000024976367 1.25000025001334 1.25000025002403 1.25000024999837 1.25000024999909 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.25000024998796 1.25000024996134 1.25000025017023 1.25000024966774 1.25000023959633 1.25000006616464 1.24999738689395 1.24996163704993 1.24956080683493 1.24592396525696 1.22089821924651 1.08410556759799 0.80688179737769 0.5941514593182 0.47927111652678 0.31244087840899 0.25611581011223 0.25090007538264 0.25080973143121 0.26241353426868 0.38043276426025 0.73434994850694 1.08043170852069 1.45746805016295 2.16835549111967 2.3549523306667 2.27211558105984 1.95708662553337 1.68963913007521 1.54558570563983 1.33462000604367 1.26031462836294 1.25111663286018 1.25009821056976 1.25000752376419 1.25000071873947 1.25000027680714 1.25000025125095 1.25000024976367 1.25000025001334 1.25000025002403 1.25000024999837 1.25000024999909 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.25000024998796 1.25000024996134 1.25000025017023 1.25000024966774 1.25000023959633 1.25000006616465 1.24999738689395 1.24996163704993 1.24956080683493 1.24592396525696 1.22089821924651 1.08410556759798 0.80688179737769 0.5941514593182 0.47927111652678 0.31244087840899 0.25611581011223 0.25090007538264 0.25080973143121 0.26241353426868 0.38043276426024 0.73434994850693 1.0804317085207 1.4574680501631 2.16835549111976 2.35495233066668 2.27211558105984 1.95708662553337 1.6896391300752 1.54558570563983 1.33462000604367 1.26031462836294 1.25111663286018 1.25009821056976 1.25000752376419 1.25000071873947 1.25000027680714 1.25000025125095 1.25000024976367 1.25000025001334 1.25000025002403 1.25000024999837 1.25000024999909 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.25000024998796 1.25000024996134 1.25000025017023 1.25000024966774 1.25000023959633 1.25000006616465 1.24999738689395 1.24996163704993 1.24956080683493 1.24592396525697 1.2208982192465 1.08410556759798 0.80688179737769 0.5941514593182 0.47927111652678 0.31244087840899 0.25611581011223 0.25090007538264 0.25080973143121 0.26241353426868 0.38043276426025 0.734349948507 1.08043170852088 1.45746805016249 2.16835549111985 2.35495233066683 2.27211558105971 1.95708662553335 1.68963913007524 1.54558570563983 1.33462000604366 1.26031462836294 1.25111663286018 1.25009821056976 1.25000752376419 1.25000071873947 1.25000027680714 1.25000025125095 1.25000024976367 1.25000025001334 1.25000025002403 1.25000024999837 1.25000024999909 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.25000024998796 1.25000024996134 1.25000025017023 1.25000024966774 1.25000023959633 1.25000006616464 1.24999738689395 1.24996163704992 1.24956080683492 1.24592396525697 1.2208982192465 1.08410556759799 0.80688179737769 0.5941514593182 0.47927111652678 0.31244087840899 0.25611581011223 0.25090007538264 0.25080973143121 0.26241353426867 0.38043276426028 0.73434994850702 1.0804317085203 1.45746805016102 2.16835549111798 2.35495233066679 2.2721155810599 1.95708662553335 1.68963913007535 1.54558570564002 1.3346200060437 1.26031462836294 1.25111663286018 1.25009821056976 1.25000752376419 1.25000071873947 1.25000027680714 1.25000025125095 1.25000024976367 1.25000025001334 1.25000025002403 1.25000024999837 1.25000024999909 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.25000024998796 1.25000024996134 1.25000025017023 1.25000024966774 1.25000023959633 1.25000006616465 1.24999738689395 1.24996163704993 1.24956080683493 1.24592396525697 1.22089821924651 1.08410556759799 0.80688179737769 0.5941514593182 0.47927111652678 0.31244087840899 0.25611581011223 0.25090007538264 0.2508097314312 0.26241353426869 0.38043276426009 0.73434994850568 1.08043170851823 1.45746805017864 2.16835549112114 2.35495233066424 2.27211558106197 1.95708662553369 1.68963913007434 1.54558570563958 1.3346200060438 1.26031462836296 1.25111663286018 1.25009821056976 1.25000752376419 1.25000071873947 1.25000027680714 1.25000025125095 1.25000024976367 1.25000025001334 1.25000025002403 1.25000024999837 1.25000024999909 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.25000024998796 1.25000024996134 1.25000025017023 1.25000024966774 1.25000023959633 1.25000006616465 1.24999738689395 1.24996163704993 1.24956080683493 1.24592396525697 1.22089821924651 1.08410556759799 0.80688179737769 0.5941514593182 0.47927111652677 0.31244087840898 0.25611581011223 0.25090007538264 0.25080973143123 0.26241353426873 0.38043276425998 0.73434994850861 1.08043170853517 1.45746805019196 2.16835549115795 2.35495233067208 2.27211558105322 1.95708662553354 1.6896391300745 1.54558570563706 1.33462000604287 1.26031462836305 1.25111663286019 1.25009821056976 1.25000752376419 1.25000071873947 1.25000027680714 1.25000025125095 1.25000024976367 1.25000025001334 1.25000025002403 1.25000024999837 1.25000024999909 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.25000024998796 1.25000024996134 1.25000025017023 1.25000024966774 1.25000023959633 1.25000006616465 1.24999738689395 1.24996163704992 1.24956080683493 1.24592396525697 1.22089821924651 1.08410556759799 0.80688179737769 0.5941514593182 0.47927111652679 0.31244087840899 0.25611581011223 0.25090007538262 0.25080973143127 0.26241353426843 0.38043276426381 0.73434994853471 1.08043170855719 1.45746804995556 2.16835549107605 2.35495233071427 2.2721155810202 1.95708662552599 1.68963913009597 1.54558570565103 1.33462000604283 1.26031462836247 1.2511166328603 1.25009821056977 1.25000752376419 1.25000071873947 1.25000027680714 1.25000025125095 1.25000024976367 1.25000025001334 1.25000025002403 1.25000024999837 1.25000024999909 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.25000024998796 1.25000024996134 1.25000025017023 1.25000024966774 1.25000023959633 1.25000006616465 1.24999738689395 1.24996163704992 1.24956080683493 1.24592396525696 1.2208982192465 1.08410556759798 0.80688179737769 0.59415145931819 0.47927111652681 0.31244087840908 0.25611581011227 0.25090007538276 0.25080973143082 0.26241353426884 0.38043276425843 0.73434994847231 1.08043170832356 1.45746805081435 2.16835549090851 2.35495233056587 2.27211558117293 1.95708662552623 1.68963913008517 1.5455857056854 1.334620006065 1.26031462836211 1.25111663285976 1.25009821056986 1.2500075237642 1.25000071873947 1.25000027680714 1.25000025125095 1.25000024976367 1.25000025001334 1.25000025002403 1.25000024999837 1.25000024999909 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.25000024998796 1.25000024996134 1.25000025017023 1.25000024966774 1.25000023959633 1.25000006616465 1.24999738689395 1.24996163704992 1.24956080683493 1.24592396525696 1.22089821924651 1.084105567598 0.80688179737767 0.59415145931825 0.47927111652662 0.31244087840869 0.25611581011208 0.25090007538318 0.25080973143135 0.26241353427293 0.38043276422173 0.73434994841986 1.08043170899007 1.45746806549051 2.16835549496869 2.35495233061293 2.27211558109007 1.95708662566124 1.68963912986423 1.54558570548147 1.33462000605711 1.26031462838015 1.25111663285939 1.25009821056946 1.25000752376424 1.25000071873948 1.25000027680714 1.25000025125095 1.25000024976367 1.25000025001334 1.25000025002403 1.25000024999837 1.25000024999909 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.25000024998796 1.25000024996134 1.25000025017023 1.25000024966774 1.25000023959633 1.25000006616464 1.24999738689395 1.24996163704992 1.24956080683493 1.24592396525696 1.22089821924652 1.08410556759805 0.80688179737761 0.5941514593179 0.47927111652695 0.31244087840848 0.25611581011154 0.25090007537752 0.25080973143594 0.26241353426175 0.3804327643569 0.73434995123822 1.08043172118334 1.45746832551825 2.16835555977729 2.3549523379012 2.27211557530395 1.95708662514858 1.68963913107792 1.54558570572989 1.33462000581927 1.26031462837631 1.25111663287704 1.25009821056896 1.25000752376398 1.25000071873947 1.25000027680714 1.25000025125095 1.25000024976367 1.25000025001334 1.25000025002403 1.25000024999837 1.25000024999909 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.25000024998796 1.25000024996134 1.25000025017023 1.25000024966774 1.25000023959633 1.25000006616464 1.24999738689395 1.24996163704993 1.24956080683493 1.24592396525696 1.22089821924646 1.08410556759756 0.80688179737831 0.59415145931852 0.4792711165269 0.31244087842055 0.25611581012023 0.25090007537241 0.25080973142728 0.26241353426669 0.38043276468976 0.73434999921205 1.08043193012482 1.45747245995579 2.16835658274987 2.35495245185752 2.27211548752739 1.95708661301177 1.6896391434892 1.54558571291607 1.33462000726625 1.26031462819337 1.2511166328732 1.25009821058343 1.25000752376378 1.25000071873934 1.25000027680713 1.25000025125095 1.25000024976367 1.25000025001334 1.25000025002403 1.25000024999837 1.25000024999909 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.25000024998796 1.25000024996134 1.25000025017023 1.25000024966774 1.25000023959633 1.25000006616465 1.24999738689395 1.24996163704992 1.24956080683492 1.24592396525695 1.22089821924633 1.08410556759771 0.80688179737824 0.59415145933219 0.47927111651882 0.31244087840526 0.2561158101104 0.2509000754555 0.25080973146634 0.26241353367781 0.38043275606449 0.73435067343356 1.08043510606384 1.45752907394649 2.1683705373936 2.35495416308514 2.27211416127343 1.95708635403651 1.68963927865814 1.54558582126409 1.33462003242339 1.26031462979922 1.25111663272217 1.25009821058994 1.25000752377355 1.25000071873986 1.25000027680714 1.25000025125095 1.25000024976367 1.25000025001334 1.25000025002403 1.25000024999837 1.25000024999909 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.25000024998796 1.25000024996134 1.25000025017023 1.25000024966774 1.25000023959633 1.25000006616465 1.24999738689395 1.24996163704993 1.24956080683493 1.24592396525705 1.22089821924782 1.08410556760819 0.80688179736539 0.59415145929143 0.47927111658769 0.31244087836575 0.25611581002586 0.2509000750789 0.25080973132617 0.26241350993599 0.38043240170661 0.73435868101014 1.08047622954944 1.4581787744914 2.1685300714832 2.35497615027326 2.27209672452053 1.95708187049529 1.68964026451837 1.54558729283373 1.33462043351033 1.26031465663464 1.25111663453046 1.25009821047468 1.25000752378457 1.25000071874403 1.25000027680749 1.25000025125097 1.25000024976367 1.25000025001334 1.25000025002403 1.25000024999837 1.25000024999909 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.25000024998796 1.25000024996134 1.25000025017023 1.25000024966774 1.25000023959633 1.25000006616465 1.24999738689395 1.24996163704993 1.24956080683495 1.24592396525735 1.22089821925059 1.08410556760199 0.80688179740343 0.59415145921863 0.4792711163484 0.31244087981158 0.25611581118424 0.2509000618634 0.25080971687545 0.26241296785098 0.38042467185415 0.73443800103679 1.08091555275111 1.46417033782862 2.1699919985533 2.35521091860033 2.27190120319509 1.95702001598881 1.68963948495305 1.54560360570551 1.33462579231949 1.26031504377633 1.25111666222006 1.25009821208581 1.25000752372473 1.25000071874239 1.25000027680788 1.25000025125102 1.25000024976366 1.25000025001334 1.25000025002403 1.25000024999837 1.25000024999909 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.25000024998796 1.25000024996134 1.25000025017023 1.25000024966774 1.25000023959633 1.25000006616465 1.24999738689395 1.24996163704992 1.24956080683477 1.24592396525446 1.22089821921875 1.08410556746144 0.80688179768203 0.59415146082731 0.47927110963694 0.31244091435702 0.25611585194215 0.25089976561372 0.25080935420615 0.26240307396464 0.38028783096425 0.7349124815943 1.08476371717182 1.50942402388759 2.18060409951054 2.35728523419551 2.27008615952001 1.95635451152281 1.6895250758447 1.54574851912279 1.33468294899948 1.26031959174731 1.25111700894544 1.25009823487439 1.25000752477638 1.25000071872766 1.25000027680275 1.25000025125076 1.25000024976371 1.25000025001334 1.25000025002403 1.25000024999837 1.25000024999909 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.25000024998796 1.25000024996134 1.25000025017023 1.25000024966774 1.25000023959633 1.25000006616465 1.24999738689395 1.2499616370499 1.24956080683456 1.24592396525519 1.22089821932065 1.08410556886677 0.80688179963215 0.59415148993559 0.47927098107482 0.31244155272276 0.25611674976915 0.25089444916566 0.25080383469713 0.26227365554431 0.3785662488825 0.73638915677395 1.10616739491852 1.62974875991391 2.21618285112401 2.366992842546 2.25609104194899 1.95095326812402 1.68772815520182 1.54653964631414 1.33517098019701 1.26036256379197 1.25112052056991 1.25009847439115 1.25000753935875 1.2500007195295 1.25000027683013 1.25000025125123 1.25000024976377 1.25000025001334 1.25000025002402 1.25000024999837 1.25000024999909 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.25000024998796 1.25000024996134 1.25000025017023 1.25000024966774 1.25000023959633 1.25000006616464 1.24999738689396 1.24996163705009 1.24956080683899 1.24592396534203 1.22089822092577 1.08410558187201 0.80688179146288 0.5941517170881 0.47926947605692 0.31244743098031 0.25612715973264 0.25085430491742 0.2507549459406 0.26133030279298 0.36750354935289 0.73271890991897 1.12728587981424 2.26791708185569 2.28571793083681 2.42764063846559 2.19389657080241 1.91442568563395 1.67617302945929 1.54686776013768 1.33704928577119 1.26055229798282 1.25113811607497 1.25009980182324 1.25000762376917 1.2500007245216 1.2500002771399 1.25000025126538 1.25000024976334 1.25000025001299 1.25000025002418 1.25000024999838 1.25000024999908 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.25000024998796 1.25000024996134 1.25000025017023 1.25000024966774 1.25000023959633 1.25000006616465 1.24999738689399 1.24996163705095 1.24956080685994 1.24592396581043 1.22089823251606 1.08410568273989 0.80688149091124 0.59415162843628 0.47925893167167 0.31249345709582 0.25623140603882 0.25050617926101 0.25054922314366 0.25474790059491 0.27777253679665 0.51729560042779 0.91448673723827 2.21612188244279 2.35948682340333 2.22058296127633 1.94925140591769 1.73469034636912 1.58987780971214 1.53391874892138 1.34204628649221 1.26115862045317 1.25119483239181 1.25010442838112 1.25000793984356 1.25000074306701 1.25000027818502 1.25000025132337 1.25000024976439 1.25000025001053 1.25000025002467 1.2500002499985 1.25000024999905 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.25000024998796 1.25000024996134 1.25000025017023 1.25000024966774 1.25000023959633 1.25000006616464 1.2499973868938 1.2499616370471 1.2495608067925 1.24592396479323 1.22089821840462 1.08410556834778 0.80688129227664 0.59415215611865 0.47924875641227 0.3124354705258 0.25626052185933 0.25061249688352 0.25007637753012 0.25195047948161 0.25966050542929 0.3744678625474 0.81058221737992 2.17940797009678 2.19709293639394 1.89153756237321 1.70720396609073 1.64110364598582 1.52811423751231 1.48079718848581 1.32349333286744 1.2590168116281 1.25098427340035 1.2500874478413 1.25000677654527 1.25000067327283 1.2500002744304 1.25000025115295 1.25000024976748 1.25000025001539 1.25000025002291 1.25000024999834 1.25000024999914 1.2500002500002 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.25000024998796 1.25000024996134 1.25000025017023 1.25000024966774 1.25000023959633 1.2500000661646 1.249997386893 1.24996163703176 1.24956080653969 1.24592396126457 1.22089817537839 1.08410524703674 0.8068818360251 0.59414973185394 0.47924899579988 0.31237501679347 0.25630465228026 0.25057211353169 0.25023798469088 0.25012969234205 0.25052514113226 0.25912180048615 0.65986714374634 2.33086517759199 1.6561560508728 1.54934759161017 1.49604165985539 1.44485122674365 1.37065471804297 1.33834043992907 1.27326821550054 1.25290625054857 1.2503171973125 1.25002849123902 1.25000238330855 1.25000038984718 1.25000025790649 1.2500002501716 1.25000024986222 1.25000025003954 1.25000025000898 1.25000024999762 1.25000024999986 1.25000025000015 1.25000024999999 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.25000024998796 1.25000024996134 1.25000025017023 1.25000024966774 1.25000023959633 1.25000006616463 1.24999738689359 1.24996163704294 1.24956080671908 1.24592396366688 1.22089820263912 1.08410543886537 0.80688150001411 0.5941511182129 0.47925027975854 0.312392036881 0.25627574352595 0.25058825830015 0.25049239814947 0.25096654385822 0.25388663646986 0.25089591587278 0.7040172157362 2.5000005 1.26053275251026 1.27541084638636 1.30888767624713 1.33383135647922 1.33510916859123 1.28247853039544 1.25747233541763 1.25088895202862 1.25009165220174 1.2500081606332 1.25000083909762 1.25000028833653 1.25000025199133 1.25000024973893 1.25000024998727 1.25000025003499 1.25000024999965 1.25000024999832 1.25000025000023 1.25000025000008 1.25000024999998 1.25000025000001 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.25000024998796 1.25000024996134 1.25000025017023 1.25000024966774 1.25000023959633 1.25000006616466 1.24999738689419 1.24996163705518 1.24956080693702 1.24592396698969 1.2208982486198 1.08410580808548 0.80688092803326 0.59415327331845 0.47925013697964 0.31248014319911 0.25626728215957 0.25050253131758 0.25047687778508 0.25497411867236 0.30446948960777 0.38095126350649 0.2500000625 +D/cons.4.00.000050.dat 2.5000005 1.28765665157671 1.28233774583049 1.3730431173692 1.43481445157317 1.35661926521261 1.30052380036225 1.25990953083113 1.25129375719234 1.25013878904765 1.25001247132286 1.25000116492886 1.25000030937296 1.25000025319221 1.25000024982678 1.25000024994805 1.25000025003876 1.2500002500021 1.25000024999797 1.25000025000015 1.2500002500001 1.25000024999998 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.25000024998796 1.25000024996134 1.25000025017023 1.25000024966774 1.25000023959633 1.25000006616466 1.24999738689441 1.24996163705958 1.24956080701305 1.24592396807319 1.22089826115419 1.08410590450285 0.80688085036114 0.59415378170774 0.47924915719521 0.31247866534241 0.25626209003631 0.25050861264119 0.25047883151923 0.2545214981436 0.30455668455819 0.3784040959543 0.2500000625 2.33081897571178 1.65527415948872 1.53803410542435 1.48153655394781 1.45011105656182 1.39737987380852 1.34362189930212 1.27412527013766 1.25305687749988 1.25033804094179 1.25003060450773 1.25000255384404 1.25000040081421 1.25000025849137 1.25000025020738 1.25000024985381 1.2500002500396 1.2500002500097 1.25000024999758 1.25000024999983 1.25000025000016 1.25000024999999 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.25000024998796 1.25000024996134 1.25000025017023 1.25000024966774 1.25000023959633 1.25000006616467 1.24999738689448 1.2499616370605 1.24956080701457 1.24592396779781 1.2208982507209 1.0841058098054 0.80688107410509 0.59415311126975 0.47924870687498 0.31240925036942 0.25624716941571 0.25059222302881 0.25043805660611 0.2509760912935 0.25387231470168 0.25088683490529 0.70393129585016 2.17910745481097 2.19605345582199 1.88280392522102 1.67349190863522 1.60050626427292 1.50824073129327 1.47376040991629 1.32479188942019 1.25911903948391 1.25098520617626 1.25008702343883 1.25000671561657 1.25000066808089 1.25000027410664 1.25000025113203 1.2500002497677 1.25000025001627 1.25000025002272 1.25000024999829 1.25000024999916 1.2500002500002 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.25000024998796 1.25000024996134 1.25000025017023 1.25000024966774 1.25000023959633 1.25000006616469 1.24999738689496 1.2499616370703 1.24956080718946 1.24592397042853 1.22089828433326 1.08410605645389 0.80688034010881 0.5941557829314 0.47924443262362 0.31243198434529 0.25620153220573 0.25059124012382 0.24992377766829 0.25000918055091 0.25049001964705 0.25904448628118 0.65969589214596 2.21465764257259 2.3578380443945 2.21745177288698 1.93244205289062 1.70097176095038 1.56836554309338 1.52393342610464 1.34076453277863 1.26106317314241 1.25118600149179 1.25010380287696 1.25000790026364 1.25000074082765 1.25000027806525 1.25000025131804 1.25000024976439 1.25000025001068 1.25000025002462 1.25000024999849 1.25000024999905 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.25000024998796 1.25000024996134 1.25000025017023 1.25000024966774 1.25000023959633 1.25000006616466 1.24999738689432 1.24996163705768 1.24956080697786 1.24592396751982 1.220898252791 1.08410584018065 0.80688092826328 0.59415396001275 0.47924404741606 0.31244877262358 0.25624872759161 0.25058589527898 0.24995672136299 0.25178499671554 0.25937105602028 0.37409017634176 0.80988488663987 2.26583803530046 2.28352910774286 2.423959882721 2.19062050163885 1.90533204196798 1.66970502991196 1.54504651214616 1.33688295329616 1.26054122007877 1.25113727122432 1.25009974462094 1.25000761997243 1.2500007242834 1.25000027712842 1.25000025126504 1.25000024976334 1.25000025001299 1.25000025002418 1.25000024999838 1.25000024999908 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.25000024998796 1.25000024996134 1.25000025017023 1.25000024966774 1.25000023959633 1.25000006616465 1.2499973868941 1.24996163705301 1.2495608068941 1.24592396629385 1.22089823881935 1.08410573442657 0.80688135739176 0.5941520613169 0.47925472186346 0.31248840509227 0.2562450338771 0.25047745339528 0.25051310789835 0.25446583398383 0.27728892538585 0.51668532577007 0.91369629277167 1.62875423104341 2.21433416584632 2.36524902440639 2.25376797026712 1.94955202503688 1.68673906018752 1.54630613608229 1.33519856730151 1.26036607567906 1.25112085985883 1.2500984983352 1.25000754068539 1.25000071960541 1.25000027683472 1.25000025125141 1.25000024976376 1.25000025001333 1.25000025002402 1.25000024999837 1.25000024999909 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.25000024998796 1.25000024996134 1.25000025017023 1.25000024966774 1.25000023959633 1.25000006616465 1.24999738689397 1.24996163705036 1.24956080684374 1.24592396541785 1.22089822225606 1.08410559514668 0.80688173902133 0.59415185611001 0.4792682561123 0.31244614438582 0.25612773168047 0.25084453346312 0.25073355205009 0.2611421950968 0.36709607874767 0.73180263309101 1.12602005149118 1.50810773678471 2.17916219721121 2.35688056282079 2.26961221060938 1.95616102830422 1.68938697019561 1.54575582132277 1.33469387024147 1.2603205924002 1.25111708774072 1.25009823989394 1.25000752504637 1.25000071874376 1.25000027680336 1.25000025125077 1.25000024976371 1.25000025001334 1.25000025002402 1.25000024999837 1.25000024999909 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.25000024998796 1.25000024996134 1.25000025017023 1.25000024966774 1.25000023959633 1.25000006616464 1.24999738689395 1.24996163704995 1.24956080683558 1.24592396526981 1.22089821948155 1.08410557010082 0.80688179040657 0.59415152238893 0.4792707981183 0.31244153990989 0.25611680519282 0.25089238524692 0.25079970399871 0.26222745883976 0.37837229707366 0.73567111049253 1.10529352860691 1.46391187236619 2.16975329902974 2.35515490903136 2.27183673558191 1.95699469068369 1.68962336351348 1.54560464300319 1.33462732832857 1.26031517324429 1.25111667170621 1.25009821265214 1.25000752375569 1.25000071874245 1.2500002768078 1.25000025125102 1.25000024976366 1.25000025001334 1.25000025002403 1.25000024999837 1.25000024999909 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.25000024998796 1.25000024996134 1.25000025017023 1.25000024966774 1.25000023959633 1.25000006616464 1.24999738689395 1.24996163704992 1.24956080683487 1.24592396525636 1.22089821924188 1.08410556758697 0.806881797274 0.59415146352566 0.47927108978961 0.31244091450737 0.25611586932915 0.25089958571369 0.25080884016986 0.26239719486976 0.38025305743535 0.73475677106473 1.08452970894232 1.45813915142467 2.16849958645291 2.35496999231165 2.27209023537466 1.95707912457489 1.68963860396564 1.54558747256569 1.33462059691913 1.26031466920266 1.2511166353901 1.25009821051025 1.25000752378315 1.25000071874374 1.25000027680748 1.25000025125097 1.25000024976367 1.25000025001334 1.25000025002403 1.25000024999837 1.25000024999909 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.25000024998796 1.25000024996134 1.25000025017023 1.25000024966774 1.25000023959633 1.25000006616464 1.24999738689395 1.24996163704993 1.24956080683496 1.24592396525745 1.22089821925159 1.08410556758795 0.80688179749901 0.5941514593878 0.47927111483397 0.31244088002367 0.25611581319156 0.25090004804712 0.25080966715201 0.26241235661417 0.38041984691865 0.73441065243879 1.08088322920947 1.45752457011839 2.16836750742587 2.35495362167862 2.2721136445379 1.95708610857827 1.68963914715607 1.54558584031272 1.33462004623658 1.26031463079388 1.2511166327657 1.2500982105851 1.25000752377365 1.25000071873992 1.25000027680715 1.25000025125095 1.25000024976367 1.25000025001334 1.25000025002403 1.25000024999837 1.25000024999909 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.25000024998796 1.25000024996134 1.25000025017023 1.25000024966774 1.25000023959633 1.25000006616465 1.24999738689395 1.24996163704992 1.24956080683494 1.24592396525713 1.22089821924849 1.08410556761514 0.80688179736025 0.59415145924273 0.47927111660625 0.31244087836049 0.25611581013949 0.25090007435307 0.25080972790069 0.26241346332821 0.38043200375621 0.73435630552198 1.08047243087626 1.45747205294573 2.16835633428957 2.35495241228708 2.27211545383615 1.95708659435412 1.68963913442083 1.54558571442991 1.33462000828895 1.26031462823468 1.2511166328615 1.25009821058475 1.25000752376402 1.25000071873935 1.25000027680713 1.25000025125095 1.25000024976367 1.25000025001334 1.25000025002403 1.25000024999837 1.25000024999909 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.25000024998796 1.25000024996134 1.25000025017023 1.25000024966774 1.25000023959633 1.25000006616465 1.24999738689395 1.24996163704992 1.24956080683493 1.24592396525697 1.22089821924666 1.08410556760071 0.80688179737031 0.59415145934367 0.47927111654091 0.31244087838519 0.25611581009498 0.25090007546754 0.25080973142821 0.2624135309034 0.38043272667346 0.73435048353358 1.0804347551429 1.45746829502039 2.16835554245043 2.35495233540072 2.2721155734934 1.95708662382261 1.68963913023032 1.5455857058837 1.33462000585052 1.26031462835906 1.25111663287978 1.25009821056939 1.25000752376399 1.25000071873947 1.25000027680714 1.25000025125095 1.25000024976367 1.25000025001334 1.25000025002403 1.25000024999837 1.25000024999909 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.25000024998796 1.25000024996134 1.25000025017023 1.25000024966774 1.25000023959633 1.25000006616465 1.24999738689395 1.24996163704992 1.24956080683493 1.24592396525696 1.22089821924645 1.08410556759749 0.80688179737904 0.5941514593243 0.47927111650726 0.31244087841994 0.25611581012849 0.25090007537724 0.25080973145741 0.26241353426035 0.38043276297954 0.73434998585076 1.08043190339454 1.4574680635083 2.16835549388864 2.35495233047904 2.27211558097385 1.95708662586375 1.68963912997129 1.54558570545882 1.33462000602773 1.26031462838404 1.25111663286008 1.25009821056942 1.25000752376423 1.25000071873947 1.25000027680714 1.25000025125095 1.25000024976367 1.25000025001334 1.25000025002403 1.25000024999837 1.25000024999909 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.25000024998796 1.25000024996134 1.25000025017023 1.25000024966774 1.25000023959633 1.25000006616465 1.24999738689395 1.24996163704992 1.24956080683493 1.24592396525696 1.2208982192465 1.08410556759792 0.80688179737783 0.59415145931692 0.47927111652623 0.31244087841033 0.25611581011315 0.25090007536995 0.25080973141084 0.2624135342789 0.38043276428807 0.73434995045169 1.08043171942795 1.45746805069441 2.16835549086488 2.35495233061409 2.27211558119852 1.95708662553035 1.68963913009993 1.54558570568034 1.33462000607052 1.26031462836298 1.25111663285965 1.25009821056985 1.2500075237642 1.25000071873947 1.25000027680714 1.25000025125095 1.25000024976367 1.25000025001334 1.25000025002403 1.25000024999837 1.25000024999909 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.25000024998796 1.25000024996134 1.25000025017023 1.25000024966774 1.25000023959633 1.25000006616464 1.24999738689395 1.24996163704993 1.24956080683493 1.24592396525696 1.22089821924651 1.08410556759802 0.80688179737761 0.59415145931806 0.47927111652762 0.31244087840859 0.25611581011151 0.25090007538333 0.25080973142958 0.26241353424956 0.38043276424283 0.73434994838131 1.080431708874 1.45746804997175 2.16835549109964 2.35495233070397 2.27211558101723 1.95708662550136 1.68963913008374 1.54558570565296 1.33462000604436 1.26031462836231 1.25111663286029 1.25009821056977 1.25000752376419 1.25000071873947 1.25000027680714 1.25000025125095 1.25000024976367 1.25000025001334 1.25000025002403 1.25000024999837 1.25000024999909 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.25000024998796 1.25000024996134 1.25000025017023 1.25000024966774 1.25000023959633 1.25000006616464 1.24999738689395 1.24996163704992 1.24956080683493 1.24592396525696 1.22089821924651 1.08410556759799 0.8068817973777 0.59415145931829 0.47927111652669 0.31244087840896 0.25611581011228 0.25090007538306 0.25080973143215 0.26241353426876 0.38043276425231 0.73434994848992 1.080431708342 1.45746805019298 2.16835549115101 2.35495233066908 2.27211558105144 1.95708662553437 1.68963913007391 1.54558570563732 1.3346200060426 1.26031462836304 1.2511166328602 1.25009821056976 1.25000752376419 1.25000071873947 1.25000027680714 1.25000025125095 1.25000024976367 1.25000025001334 1.25000025002403 1.25000024999837 1.25000024999909 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.25000024998796 1.25000024996134 1.25000025017023 1.25000024966774 1.25000023959633 1.25000006616465 1.24999738689395 1.24996163704992 1.24956080683493 1.24592396525697 1.2208982192465 1.08410556759798 0.80688179737769 0.5941514593182 0.47927111652674 0.31244087840901 0.25611581011226 0.25090007538255 0.25080973143116 0.26241353426955 0.38043276426284 0.73434994853124 1.08043170855919 1.45746805017681 2.16835549112024 2.35495233066513 2.27211558106226 1.95708662553478 1.68963913007496 1.54558570563948 1.33462000604376 1.26031462836296 1.25111663286018 1.25009821056976 1.25000752376419 1.25000071873947 1.25000027680714 1.25000025125095 1.25000024976367 1.25000025001334 1.25000025002403 1.25000024999837 1.25000024999909 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.25000024998796 1.25000024996134 1.25000025017023 1.25000024966774 1.25000023959633 1.25000006616464 1.24999738689395 1.24996163704993 1.24956080683493 1.24592396525696 1.22089821924651 1.08410556759798 0.80688179737769 0.5941514593182 0.47927111652678 0.31244087840899 0.25611581011222 0.25090007538263 0.25080973143116 0.26241353426856 0.38043276426027 0.73434994850782 1.08043170853285 1.45746805016106 2.16835549111845 2.35495233066677 2.27211558105992 1.95708662553315 1.6896391300753 1.54558570564001 1.33462000604372 1.26031462836294 1.25111663286018 1.25009821056976 1.25000752376419 1.25000071873947 1.25000027680714 1.25000025125095 1.25000024976367 1.25000025001334 1.25000025002403 1.25000024999837 1.25000024999909 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.25000024998796 1.25000024996134 1.25000025017023 1.25000024966774 1.25000023959633 1.25000006616464 1.24999738689395 1.24996163704993 1.24956080683493 1.24592396525696 1.22089821924651 1.08410556759798 0.80688179737769 0.5941514593182 0.47927111652678 0.31244087840899 0.25611581011223 0.25090007538265 0.25080973143121 0.26241353426864 0.38043276426007 0.73434994850585 1.08043170851824 1.45746805016255 2.1683554911198 2.35495233066677 2.2721155810597 1.95708662553331 1.68963913007521 1.54558570563984 1.33462000604366 1.26031462836294 1.25111663286018 1.25009821056976 1.25000752376419 1.25000071873947 1.25000027680714 1.25000025125095 1.25000024976367 1.25000025001334 1.25000025002403 1.25000024999837 1.25000024999909 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.25000024998796 1.25000024996134 1.25000025017023 1.25000024966774 1.25000023959633 1.25000006616465 1.24999738689395 1.24996163704992 1.24956080683493 1.24592396525696 1.2208982192465 1.08410556759798 0.80688179737769 0.5941514593182 0.47927111652678 0.31244087840899 0.25611581011223 0.25090007538264 0.25080973143121 0.26241353426868 0.38043276426027 0.73434994850701 1.08043170852043 1.45746805016309 2.16835549111974 2.35495233066669 2.27211558105985 1.95708662553338 1.6896391300752 1.54558570563982 1.33462000604367 1.26031462836295 1.25111663286018 1.25009821056976 1.25000752376419 1.25000071873947 1.25000027680714 1.25000025125095 1.25000024976367 1.25000025001334 1.25000025002403 1.25000024999837 1.25000024999909 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.25000024998796 1.25000024996134 1.25000025017023 1.25000024966774 1.25000023959633 1.25000006616464 1.24999738689395 1.24996163704993 1.24956080683493 1.24592396525696 1.22089821924651 1.08410556759799 0.80688179737769 0.5941514593182 0.47927111652678 0.31244087840899 0.25611581011223 0.25090007538264 0.25080973143121 0.26241353426868 0.38043276426025 0.734349948507 1.08043170852086 1.45746805016295 2.16835549111968 2.3549523306667 2.27211558105984 1.95708662553337 1.68963913007521 1.54558570563983 1.33462000604367 1.26031462836294 1.25111663286018 1.25009821056976 1.25000752376419 1.25000071873947 1.25000027680714 1.25000025125095 1.25000024976367 1.25000025001334 1.25000025002403 1.25000024999837 1.25000024999909 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.25000024998796 1.25000024996134 1.25000025017023 1.25000024966774 1.25000023959633 1.25000006616465 1.24999738689395 1.24996163704993 1.24956080683493 1.24592396525697 1.2208982192465 1.08410556759799 0.80688179737769 0.5941514593182 0.47927111652678 0.31244087840899 0.25611581011223 0.25090007538264 0.25080973143121 0.26241353426867 0.38043276426025 0.73434994850693 1.08043170852069 1.45746805016294 2.16835549111969 2.3549523306667 2.27211558105984 1.95708662553337 1.68963913007521 1.54558570563983 1.33462000604367 1.26031462836294 1.25111663286018 1.25009821056976 1.25000752376419 1.25000071873947 1.25000027680714 1.25000025125095 1.25000024976367 1.25000025001334 1.25000025002403 1.25000024999837 1.25000024999909 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.25000024998796 1.25000024996134 1.25000025017023 1.25000024966774 1.25000023959633 1.25000006616465 1.24999738689395 1.24996163704992 1.24956080683493 1.24592396525697 1.22089821924651 1.08410556759799 0.80688179737769 0.5941514593182 0.47927111652678 0.31244087840899 0.25611581011223 0.25090007538264 0.25080973143121 0.26241353426868 0.38043276426025 0.73434994850694 1.08043170852069 1.45746805016295 2.16835549111969 2.3549523306667 2.27211558105984 1.95708662553337 1.68963913007521 1.54558570563983 1.33462000604367 1.26031462836294 1.25111663286018 1.25009821056976 1.25000752376419 1.25000071873947 1.25000027680714 1.25000025125095 1.25000024976367 1.25000025001334 1.25000025002403 1.25000024999837 1.25000024999909 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.25000024998796 1.25000024996134 1.25000025017023 1.25000024966774 1.25000023959633 1.25000006616464 1.24999738689395 1.24996163704993 1.24956080683493 1.24592396525696 1.22089821924651 1.08410556759798 0.80688179737769 0.5941514593182 0.47927111652678 0.31244087840899 0.25611581011223 0.25090007538264 0.25080973143121 0.26241353426868 0.38043276426025 0.73434994850694 1.08043170852069 1.45746805016295 2.16835549111969 2.3549523306667 2.27211558105984 1.95708662553337 1.68963913007521 1.54558570563983 1.33462000604367 1.26031462836294 1.25111663286018 1.25009821056976 1.25000752376419 1.25000071873947 1.25000027680714 1.25000025125095 1.25000024976367 1.25000025001334 1.25000025002403 1.25000024999837 1.25000024999909 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.25000024998796 1.25000024996134 1.25000025017023 1.25000024966774 1.25000023959633 1.25000006616465 1.24999738689395 1.24996163704992 1.24956080683493 1.24592396525697 1.22089821924651 1.08410556759799 0.80688179737769 0.5941514593182 0.47927111652678 0.31244087840899 0.25611581011223 0.25090007538264 0.25080973143121 0.26241353426868 0.38043276426025 0.73434994850694 1.08043170852069 1.45746805016295 2.16835549111969 2.3549523306667 2.27211558105984 1.95708662553337 1.68963913007521 1.54558570563983 1.33462000604367 1.26031462836294 1.25111663286018 1.25009821056976 1.25000752376419 1.25000071873947 1.25000027680714 1.25000025125095 1.25000024976367 1.25000025001334 1.25000025002403 1.25000024999837 1.25000024999909 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.25000024998796 1.25000024996134 1.25000025017023 1.25000024966774 1.25000023959633 1.25000006616464 1.24999738689395 1.24996163704993 1.24956080683493 1.24592396525697 1.22089821924651 1.08410556759798 0.80688179737769 0.5941514593182 0.47927111652678 0.31244087840899 0.25611581011223 0.25090007538264 0.25080973143121 0.26241353426868 0.38043276426025 0.73434994850694 1.08043170852069 1.45746805016295 2.16835549111969 2.3549523306667 2.27211558105984 1.95708662553337 1.68963913007521 1.54558570563983 1.33462000604367 1.26031462836294 1.25111663286018 1.25009821056976 1.25000752376419 1.25000071873947 1.25000027680714 1.25000025125095 1.25000024976367 1.25000025001334 1.25000025002403 1.25000024999837 1.25000024999909 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.25000024998796 1.25000024996134 1.25000025017023 1.25000024966774 1.25000023959633 1.25000006616464 1.24999738689395 1.24996163704992 1.24956080683493 1.24592396525696 1.22089821924651 1.08410556759798 0.80688179737769 0.5941514593182 0.47927111652678 0.31244087840899 0.25611581011223 0.25090007538264 0.25080973143121 0.26241353426868 0.38043276426025 0.73434994850694 1.08043170852069 1.45746805016295 2.16835549111969 2.3549523306667 2.27211558105984 1.95708662553337 1.68963913007521 1.54558570563983 1.33462000604367 1.26031462836294 1.25111663286018 1.25009821056976 1.25000752376419 1.25000071873947 1.25000027680714 1.25000025125095 1.25000024976367 1.25000025001334 1.25000025002403 1.25000024999837 1.25000024999909 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.25000024998796 1.25000024996134 1.25000025017023 1.25000024966774 1.25000023959633 1.25000006616465 1.24999738689395 1.24996163704992 1.24956080683493 1.24592396525696 1.22089821924651 1.08410556759799 0.80688179737769 0.5941514593182 0.47927111652678 0.31244087840899 0.25611581011223 0.25090007538264 0.25080973143121 0.26241353426868 0.38043276426025 0.73434994850694 1.08043170852069 1.45746805016295 2.16835549111969 2.3549523306667 2.27211558105984 1.95708662553337 1.68963913007521 1.54558570563983 1.33462000604367 1.26031462836294 1.25111663286018 1.25009821056976 1.25000752376419 1.25000071873947 1.25000027680714 1.25000025125095 1.25000024976367 1.25000025001334 1.25000025002403 1.25000024999837 1.25000024999909 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.25000024998796 1.25000024996134 1.25000025017023 1.25000024966774 1.25000023959633 1.25000006616464 1.24999738689395 1.24996163704993 1.24956080683493 1.24592396525697 1.22089821924651 1.08410556759798 0.80688179737769 0.5941514593182 0.47927111652678 0.31244087840899 0.25611581011223 0.25090007538264 0.25080973143121 0.26241353426868 0.38043276426025 0.73434994850694 1.08043170852069 1.45746805016294 2.16835549111968 2.3549523306667 2.27211558105984 1.95708662553337 1.68963913007521 1.54558570563983 1.33462000604367 1.26031462836294 1.25111663286018 1.25009821056976 1.25000752376419 1.25000071873947 1.25000027680714 1.25000025125095 1.25000024976367 1.25000025001334 1.25000025002403 1.25000024999837 1.25000024999909 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.25000024998796 1.25000024996134 1.25000025017023 1.25000024966774 1.25000023959633 1.25000006616465 1.24999738689395 1.24996163704992 1.24956080683493 1.24592396525697 1.22089821924651 1.08410556759799 0.80688179737769 0.5941514593182 0.47927111652678 0.31244087840899 0.25611581011223 0.25090007538264 0.25080973143121 0.26241353426868 0.38043276426025 0.73434994850694 1.08043170852068 1.45746805016295 2.16835549111967 2.3549523306667 2.27211558105984 1.95708662553337 1.68963913007521 1.54558570563983 1.33462000604367 1.26031462836294 1.25111663286018 1.25009821056976 1.25000752376419 1.25000071873947 1.25000027680714 1.25000025125095 1.25000024976367 1.25000025001334 1.25000025002403 1.25000024999837 1.25000024999909 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.25000024998796 1.25000024996134 1.25000025017023 1.25000024966774 1.25000023959633 1.25000006616465 1.24999738689395 1.24996163704992 1.24956080683493 1.24592396525696 1.2208982192465 1.08410556759798 0.80688179737769 0.5941514593182 0.47927111652678 0.31244087840899 0.25611581011223 0.25090007538264 0.25080973143121 0.26241353426868 0.38043276426024 0.73434994850693 1.0804317085207 1.45746805016311 2.16835549111976 2.35495233066668 2.27211558105984 1.95708662553337 1.6896391300752 1.54558570563983 1.33462000604367 1.26031462836295 1.25111663286018 1.25009821056976 1.25000752376419 1.25000071873947 1.25000027680714 1.25000025125095 1.25000024976367 1.25000025001334 1.25000025002403 1.25000024999837 1.25000024999909 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.25000024998796 1.25000024996134 1.25000025017023 1.25000024966774 1.25000023959633 1.25000006616464 1.24999738689395 1.24996163704993 1.24956080683493 1.24592396525696 1.22089821924651 1.08410556759798 0.80688179737769 0.5941514593182 0.47927111652678 0.31244087840899 0.25611581011223 0.25090007538264 0.25080973143121 0.26241353426868 0.38043276426025 0.734349948507 1.08043170852088 1.45746805016249 2.16835549111985 2.35495233066683 2.27211558105971 1.95708662553335 1.68963913007524 1.54558570563983 1.33462000604366 1.26031462836294 1.25111663286018 1.25009821056976 1.25000752376419 1.25000071873947 1.25000027680714 1.25000025125095 1.25000024976367 1.25000025001334 1.25000025002403 1.25000024999837 1.25000024999909 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.25000024998796 1.25000024996134 1.25000025017023 1.25000024966774 1.25000023959633 1.25000006616464 1.24999738689395 1.24996163704993 1.24956080683493 1.24592396525696 1.22089821924651 1.08410556759798 0.80688179737769 0.5941514593182 0.47927111652678 0.31244087840899 0.25611581011223 0.25090007538264 0.25080973143121 0.26241353426867 0.38043276426028 0.73434994850702 1.0804317085203 1.45746805016102 2.16835549111798 2.35495233066679 2.2721155810599 1.95708662553335 1.68963913007535 1.54558570564002 1.3346200060437 1.26031462836294 1.25111663286018 1.25009821056976 1.25000752376419 1.25000071873947 1.25000027680714 1.25000025125095 1.25000024976367 1.25000025001334 1.25000025002403 1.25000024999837 1.25000024999909 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.25000024998796 1.25000024996134 1.25000025017023 1.25000024966774 1.25000023959633 1.25000006616464 1.24999738689395 1.24996163704992 1.24956080683493 1.24592396525696 1.22089821924651 1.08410556759798 0.80688179737769 0.5941514593182 0.47927111652678 0.31244087840899 0.25611581011223 0.25090007538264 0.2508097314312 0.26241353426869 0.38043276426009 0.73434994850568 1.08043170851823 1.45746805017864 2.16835549112114 2.35495233066424 2.27211558106197 1.95708662553369 1.68963913007434 1.54558570563958 1.3346200060438 1.26031462836296 1.25111663286018 1.25009821056976 1.25000752376419 1.25000071873947 1.25000027680714 1.25000025125095 1.25000024976367 1.25000025001334 1.25000025002403 1.25000024999837 1.25000024999909 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.25000024998796 1.25000024996134 1.25000025017023 1.25000024966774 1.25000023959633 1.25000006616464 1.24999738689395 1.24996163704992 1.24956080683493 1.24592396525696 1.22089821924651 1.08410556759799 0.80688179737769 0.5941514593182 0.47927111652677 0.31244087840898 0.25611581011223 0.25090007538264 0.25080973143123 0.26241353426873 0.38043276425998 0.73434994850861 1.08043170853517 1.45746805019196 2.16835549115795 2.35495233067208 2.27211558105322 1.95708662553354 1.6896391300745 1.54558570563706 1.33462000604287 1.26031462836305 1.25111663286019 1.25009821056976 1.25000752376419 1.25000071873947 1.25000027680714 1.25000025125095 1.25000024976367 1.25000025001334 1.25000025002403 1.25000024999837 1.25000024999909 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.25000024998796 1.25000024996134 1.25000025017023 1.25000024966774 1.25000023959633 1.25000006616464 1.24999738689395 1.24996163704993 1.24956080683493 1.24592396525697 1.22089821924651 1.08410556759799 0.80688179737769 0.5941514593182 0.47927111652679 0.31244087840899 0.25611581011223 0.25090007538262 0.25080973143127 0.26241353426843 0.38043276426381 0.73434994853471 1.08043170855719 1.45746804995556 2.16835549107605 2.35495233071427 2.2721155810202 1.95708662552599 1.68963913009597 1.54558570565103 1.33462000604283 1.26031462836247 1.25111663286029 1.25009821056977 1.25000752376419 1.25000071873947 1.25000027680714 1.25000025125095 1.25000024976367 1.25000025001334 1.25000025002403 1.25000024999837 1.25000024999909 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.25000024998796 1.25000024996134 1.25000025017023 1.25000024966774 1.25000023959633 1.25000006616465 1.24999738689395 1.24996163704992 1.24956080683493 1.24592396525697 1.2208982192465 1.08410556759798 0.80688179737769 0.59415145931819 0.47927111652681 0.31244087840908 0.25611581011227 0.25090007538276 0.25080973143082 0.26241353426884 0.38043276425843 0.73434994847231 1.08043170832356 1.45746805081435 2.16835549090851 2.35495233056587 2.27211558117293 1.95708662552623 1.68963913008517 1.5455857056854 1.334620006065 1.26031462836212 1.25111663285976 1.25009821056986 1.2500075237642 1.25000071873947 1.25000027680714 1.25000025125095 1.25000024976367 1.25000025001334 1.25000025002403 1.25000024999837 1.25000024999909 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.25000024998796 1.25000024996134 1.25000025017023 1.25000024966774 1.25000023959633 1.25000006616465 1.24999738689395 1.24996163704992 1.24956080683493 1.24592396525697 1.22089821924651 1.084105567598 0.80688179737767 0.59415145931825 0.47927111652662 0.31244087840869 0.25611581011208 0.25090007538318 0.25080973143135 0.26241353427293 0.38043276422173 0.73434994841986 1.08043170899007 1.45746806549051 2.16835549496869 2.35495233061293 2.27211558109008 1.95708662566124 1.68963912986423 1.54558570548147 1.33462000605711 1.26031462838015 1.25111663285939 1.25009821056946 1.25000752376424 1.25000071873947 1.25000027680714 1.25000025125095 1.25000024976367 1.25000025001334 1.25000025002403 1.25000024999837 1.25000024999909 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.25000024998796 1.25000024996134 1.25000025017023 1.25000024966774 1.25000023959633 1.25000006616465 1.24999738689395 1.24996163704993 1.24956080683493 1.24592396525696 1.22089821924652 1.08410556759805 0.80688179737761 0.5941514593179 0.47927111652695 0.31244087840848 0.25611581011154 0.25090007537752 0.25080973143594 0.26241353426175 0.3804327643569 0.73434995123822 1.08043172118335 1.45746832551825 2.16835555977729 2.3549523379012 2.27211557530395 1.95708662514858 1.68963913107792 1.54558570572989 1.33462000581927 1.26031462837631 1.25111663287704 1.25009821056896 1.25000752376398 1.25000071873947 1.25000027680714 1.25000025125095 1.25000024976367 1.25000025001334 1.25000025002403 1.25000024999837 1.25000024999909 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.25000024998796 1.25000024996134 1.25000025017023 1.25000024966774 1.25000023959633 1.25000006616464 1.24999738689395 1.24996163704993 1.24956080683493 1.24592396525696 1.22089821924646 1.08410556759756 0.80688179737831 0.59415145931852 0.4792711165269 0.31244087842055 0.25611581012023 0.25090007537241 0.25080973142728 0.26241353426669 0.38043276468976 0.73434999921205 1.08043193012482 1.45747245995579 2.16835658274987 2.35495245185752 2.27211548752739 1.95708661301177 1.6896391434892 1.54558571291607 1.33462000726625 1.26031462819337 1.2511166328732 1.25009821058343 1.25000752376378 1.25000071873934 1.25000027680713 1.25000025125095 1.25000024976367 1.25000025001334 1.25000025002403 1.25000024999837 1.25000024999909 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.25000024998796 1.25000024996134 1.25000025017023 1.25000024966774 1.25000023959633 1.25000006616465 1.24999738689395 1.24996163704992 1.24956080683492 1.24592396525695 1.22089821924633 1.08410556759771 0.80688179737824 0.59415145933219 0.47927111651883 0.31244087840526 0.2561158101104 0.2509000754555 0.25080973146634 0.26241353367781 0.38043275606449 0.73435067343357 1.08043510606384 1.45752907394649 2.1683705373936 2.35495416308514 2.27211416127343 1.95708635403651 1.68963927865814 1.54558582126409 1.33462003242339 1.26031462979922 1.25111663272217 1.25009821058994 1.25000752377355 1.25000071873986 1.25000027680714 1.25000025125095 1.25000024976367 1.25000025001334 1.25000025002403 1.25000024999837 1.25000024999909 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.25000024998796 1.25000024996134 1.25000025017023 1.25000024966774 1.25000023959633 1.25000006616464 1.24999738689395 1.24996163704993 1.24956080683493 1.24592396525705 1.22089821924782 1.08410556760819 0.80688179736539 0.59415145929143 0.47927111658769 0.31244087836575 0.25611581002586 0.2509000750789 0.25080973132617 0.26241350993599 0.38043240170661 0.73435868101014 1.08047622954944 1.4581787744914 2.1685300714832 2.35497615027326 2.27209672452053 1.95708187049529 1.68964026451837 1.54558729283373 1.33462043351033 1.26031465663464 1.25111663453046 1.25009821047468 1.25000752378457 1.25000071874403 1.25000027680749 1.25000025125097 1.25000024976367 1.25000025001334 1.25000025002403 1.25000024999837 1.25000024999909 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.25000024998796 1.25000024996134 1.25000025017023 1.25000024966774 1.25000023959633 1.25000006616464 1.24999738689395 1.24996163704993 1.24956080683495 1.24592396525735 1.22089821925059 1.08410556760199 0.80688179740343 0.59415145921863 0.4792711163484 0.31244087981158 0.25611581118424 0.2509000618634 0.25080971687545 0.26241296785098 0.38042467185415 0.73443800103679 1.08091555275111 1.46417033782862 2.1699919985533 2.35521091860033 2.27190120319509 1.95702001598881 1.68963948495305 1.54560360570551 1.33462579231949 1.26031504377633 1.25111666222006 1.25009821208581 1.25000752372473 1.25000071874239 1.25000027680788 1.25000025125102 1.25000024976366 1.25000025001334 1.25000025002403 1.25000024999837 1.25000024999909 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.25000024998796 1.25000024996134 1.25000025017023 1.25000024966774 1.25000023959633 1.25000006616465 1.24999738689395 1.24996163704992 1.24956080683477 1.24592396525446 1.22089821921875 1.08410556746144 0.80688179768203 0.59415146082731 0.47927110963694 0.31244091435702 0.25611585194215 0.25089976561372 0.25080935420615 0.26240307396464 0.38028783096425 0.7349124815943 1.08476371717182 1.50942402388759 2.18060409951054 2.35728523419551 2.27008615952001 1.95635451152281 1.6895250758447 1.54574851912279 1.33468294899948 1.26031959174731 1.25111700894544 1.25009823487439 1.25000752477638 1.25000071872766 1.25000027680275 1.25000025125076 1.25000024976371 1.25000025001334 1.25000025002402 1.25000024999837 1.25000024999909 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.25000024998796 1.25000024996134 1.25000025017023 1.25000024966774 1.25000023959633 1.25000006616464 1.24999738689395 1.2499616370499 1.24956080683456 1.24592396525519 1.22089821932065 1.08410556886677 0.80688179963215 0.59415148993559 0.47927098107482 0.31244155272276 0.25611674976915 0.25089444916566 0.25080383469713 0.26227365554431 0.3785662488825 0.73638915677395 1.10616739491852 1.62974875991391 2.21618285112401 2.366992842546 2.25609104194899 1.95095326812402 1.68772815520182 1.54653964631414 1.33517098019701 1.26036256379198 1.25112052056991 1.25009847439115 1.25000753935875 1.2500007195295 1.25000027683013 1.25000025125123 1.25000024976377 1.25000025001334 1.25000025002402 1.25000024999837 1.25000024999909 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.25000024998796 1.25000024996134 1.25000025017023 1.25000024966774 1.25000023959633 1.25000006616465 1.24999738689396 1.24996163705009 1.24956080683899 1.24592396534203 1.22089822092577 1.08410558187201 0.80688179146288 0.5941517170881 0.47926947605692 0.31244743098031 0.25612715973264 0.25085430491742 0.2507549459406 0.26133030279298 0.36750354935289 0.73271890991897 1.12728587981424 2.26791708185569 2.28571793083681 2.42764063846559 2.19389657080241 1.91442568563395 1.67617302945929 1.54686776013768 1.33704928577119 1.26055229798282 1.25113811607497 1.25009980182324 1.25000762376917 1.2500007245216 1.2500002771399 1.25000025126538 1.25000024976334 1.25000025001299 1.25000025002418 1.25000024999838 1.25000024999908 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.25000024998796 1.25000024996134 1.25000025017023 1.25000024966774 1.25000023959633 1.25000006616465 1.24999738689399 1.24996163705095 1.24956080685994 1.24592396581043 1.22089823251606 1.08410568273989 0.80688149091124 0.59415162843628 0.47925893167167 0.31249345709582 0.25623140603882 0.25050617926101 0.25054922314366 0.25474790059491 0.27777253679665 0.51729560042779 0.91448673723827 2.21612188244279 2.35948682340333 2.22058296127633 1.94925140591768 1.73469034636912 1.58987780971214 1.53391874892138 1.34204628649221 1.26115862045317 1.25119483239181 1.25010442838112 1.25000793984356 1.25000074306701 1.25000027818502 1.25000025132337 1.25000024976439 1.25000025001053 1.25000025002467 1.2500002499985 1.25000024999905 1.25000025000021 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.25000024998796 1.25000024996134 1.25000025017023 1.25000024966774 1.25000023959633 1.25000006616464 1.2499973868938 1.2499616370471 1.2495608067925 1.24592396479323 1.22089821840462 1.08410556834778 0.80688129227664 0.59415215611865 0.47924875641227 0.3124354705258 0.25626052185933 0.25061249688352 0.25007637753011 0.25195047948161 0.25966050542929 0.3744678625474 0.81058221737992 2.17940797009678 2.19709293639394 1.89153756237321 1.70720396609073 1.64110364598582 1.52811423751231 1.48079718848581 1.32349333286743 1.2590168116281 1.25098427340035 1.2500874478413 1.25000677654527 1.25000067327283 1.2500002744304 1.25000025115295 1.25000024976748 1.25000025001539 1.25000025002291 1.25000024999834 1.25000024999914 1.2500002500002 1.25000025000003 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.25000024998796 1.25000024996134 1.25000025017023 1.25000024966774 1.25000023959633 1.2500000661646 1.249997386893 1.24996163703176 1.24956080653969 1.24592396126457 1.22089817537839 1.08410524703674 0.8068818360251 0.59414973185394 0.47924899579988 0.31237501679347 0.25630465228026 0.25057211353169 0.25023798469088 0.25012969234205 0.25052514113226 0.25912180048615 0.65986714374634 2.33086517759199 1.6561560508728 1.54934759161017 1.49604165985539 1.44485122674365 1.37065471804297 1.33834043992907 1.27326821550054 1.25290625054857 1.2503171973125 1.25002849123902 1.25000238330855 1.25000038984718 1.25000025790649 1.2500002501716 1.25000024986222 1.25000025003954 1.25000025000898 1.25000024999762 1.25000024999986 1.25000025000015 1.25000024999999 1.25000025 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.25000024998796 1.25000024996134 1.25000025017023 1.25000024966774 1.25000023959633 1.25000006616463 1.24999738689359 1.24996163704294 1.24956080671908 1.24592396366688 1.22089820263912 1.08410543886537 0.80688150001411 0.5941511182129 0.47925027975854 0.312392036881 0.25627574352595 0.25058825830015 0.25049239814947 0.25096654385822 0.25388663646986 0.25089591587278 0.7040172157362 2.5000005 1.26053275251026 1.27541084638636 1.30888767624713 1.33383135647922 1.33510916859123 1.28247853039544 1.25747233541763 1.25088895202862 1.25009165220174 1.2500081606332 1.25000083909762 1.25000028833653 1.25000025199133 1.25000024973893 1.25000024998727 1.25000025003499 1.25000024999965 1.25000024999832 1.25000025000023 1.25000025000008 1.25000024999998 1.25000025000001 1.25000025 1.25000024999982 1.25000025000027 1.25000025000249 1.25000024998796 1.25000024996134 1.25000025017023 1.25000024966774 1.25000023959633 1.25000006616466 1.24999738689419 1.24996163705518 1.24956080693702 1.24592396698969 1.2208982486198 1.08410580808548 0.80688092803326 0.59415327331845 0.47925013697964 0.31248014319911 0.25626728215957 0.25050253131758 0.25047687778508 0.25497411867236 0.30446948960777 0.38095126350649 0.2500000625 D/cons.5.00.000000.dat 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 D/cons.5.00.000050.dat 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 \ No newline at end of file diff --git a/tests/CE7B0BC7/golden-metadata.txt b/tests/CE7B0BC7/golden-metadata.txt index 09d00c7d93..884fe638c1 100644 --- a/tests/CE7B0BC7/golden-metadata.txt +++ b/tests/CE7B0BC7/golden-metadata.txt @@ -1,24 +1,24 @@ -This file was created on 2026-02-25 22:45:42.319357. +This file was created on 2026-03-15 15:33:24.218067. mfc.sh: - Invocation: test --generate --only CE7B0BC7 -j 8 --no-build -- -c phoenix + Invocation: test --generate --only CE7B0BC7 016C1B8B -j 4 Lock: mpi=Yes & gpu=No & debug=No & gcov=No & unified=No & single=No & mixed=No & fastmath=No - Git: 0ce91cc551508e01d2fc4127caeb9ac010cfa258 on fix/time-stepping-order (dirty) + Git: 37668dcbdbf4d7402b2fc086a4b9767034ffb45a on moving-bubbles (dirty) -syscheck: +pre_process: CMake Configuration: - CMake v3.26.5 on atl1-1-02-007-5-2.pace.gatech.edu + CMake v3.26.5 on atl1-1-02-002-28-2.pace.gatech.edu C : GNU v12.3.0 (/usr/local/pace-apps/spack/packages/linux-rhel9-x86_64_v3/gcc-11.3.1/gcc-12.3.0-ukkkutsxfl5kpnnaxflpkq2jtliwthfz/bin/gcc) Fortran : GNU v12.3.0 (/usr/local/pace-apps/spack/packages/linux-rhel9-x86_64_v3/gcc-11.3.1/gcc-12.3.0-ukkkutsxfl5kpnnaxflpkq2jtliwthfz/bin/gfortran) - PRE_PROCESS : OFF + PRE_PROCESS : ON SIMULATION : OFF POST_PROCESS : OFF - SYSCHECK : ON + SYSCHECK : OFF DOCUMENTATION : OFF ALL : OFF @@ -26,7 +26,7 @@ syscheck: OpenACC : OFF OpenMP : OFF - Fypp : /storage/home/hcoda1/6/sbryngelson3/scratch/MFC-prs/build/venv/bin/fypp + Fypp : /storage/scratch1/6/sbryngelson3/MFC-ruff/build/venv/bin/fypp Doxygen : Build Type : Release @@ -40,11 +40,45 @@ syscheck: OMPI_CXX : OMPI_FC : +documentation: + + CMake Configuration: + + CMake v3.26.5 on atl1-1-02-002-23-1.pace.gatech.edu + + C : GNU v12.3.0 (/usr/local/pace-apps/spack/packages/linux-rhel9-x86_64_v3/gcc-11.3.1/gcc-12.3.0-ukkkutsxfl5kpnnaxflpkq2jtliwthfz/bin/gcc) + Fortran : GNU v12.3.0 (/usr/local/pace-apps/spack/packages/linux-rhel9-x86_64_v3/gcc-11.3.1/gcc-12.3.0-ukkkutsxfl5kpnnaxflpkq2jtliwthfz/bin/gfortran) + + PRE_PROCESS : OFF + SIMULATION : OFF + POST_PROCESS : OFF + SYSCHECK : OFF + DOCUMENTATION : ON + ALL : OFF + + MPI : ON + OpenACC : OFF + OpenMP : OFF + + Fypp : /storage/home/hcoda1/6/sbryngelson3/scratch/MFC-ruff/build/venv/bin/fypp + Doxygen : /storage/home/hcoda1/6/sbryngelson3/.local/bin/doxygen + + Build Type : Release + + Configuration Environment: + + CC : /usr/local/pace-apps/spack/packages/linux-rhel9-x86_64_v3/gcc-11.3.1/gcc-12.3.0-ukkkutsxfl5kpnnaxflpkq2jtliwthfz/bin/gcc + CXX : /usr/local/pace-apps/spack/packages/linux-rhel9-x86_64_v3/gcc-11.3.1/gcc-12.3.0-ukkkutsxfl5kpnnaxflpkq2jtliwthfz/bin/g++ + FC : /usr/local/pace-apps/spack/packages/linux-rhel9-x86_64_v3/gcc-11.3.1/gcc-12.3.0-ukkkutsxfl5kpnnaxflpkq2jtliwthfz/bin/gfortran + OMPI_CC : + OMPI_CXX : + OMPI_FC : + simulation: CMake Configuration: - CMake v3.26.5 on atl1-1-02-007-5-2.pace.gatech.edu + CMake v3.26.5 on atl1-1-02-002-28-2.pace.gatech.edu C : GNU v12.3.0 (/usr/local/pace-apps/spack/packages/linux-rhel9-x86_64_v3/gcc-11.3.1/gcc-12.3.0-ukkkutsxfl5kpnnaxflpkq2jtliwthfz/bin/gcc) Fortran : GNU v12.3.0 (/usr/local/pace-apps/spack/packages/linux-rhel9-x86_64_v3/gcc-11.3.1/gcc-12.3.0-ukkkutsxfl5kpnnaxflpkq2jtliwthfz/bin/gfortran) @@ -60,7 +94,7 @@ simulation: OpenACC : OFF OpenMP : OFF - Fypp : /storage/home/hcoda1/6/sbryngelson3/scratch/MFC-prs/build/venv/bin/fypp + Fypp : /storage/scratch1/6/sbryngelson3/MFC-ruff/build/venv/bin/fypp Doxygen : Build Type : Release @@ -74,18 +108,52 @@ simulation: OMPI_CXX : OMPI_FC : -pre_process: +syscheck: CMake Configuration: - CMake v3.26.5 on atl1-1-02-007-5-2.pace.gatech.edu + CMake v3.26.5 on atl1-1-02-002-23-1.pace.gatech.edu C : GNU v12.3.0 (/usr/local/pace-apps/spack/packages/linux-rhel9-x86_64_v3/gcc-11.3.1/gcc-12.3.0-ukkkutsxfl5kpnnaxflpkq2jtliwthfz/bin/gcc) Fortran : GNU v12.3.0 (/usr/local/pace-apps/spack/packages/linux-rhel9-x86_64_v3/gcc-11.3.1/gcc-12.3.0-ukkkutsxfl5kpnnaxflpkq2jtliwthfz/bin/gfortran) - PRE_PROCESS : ON + PRE_PROCESS : OFF SIMULATION : OFF POST_PROCESS : OFF + SYSCHECK : ON + DOCUMENTATION : OFF + ALL : OFF + + MPI : ON + OpenACC : OFF + OpenMP : OFF + + Fypp : /storage/home/hcoda1/6/sbryngelson3/scratch/MFC-ruff/build/venv/bin/fypp + Doxygen : + + Build Type : Release + + Configuration Environment: + + CC : /usr/local/pace-apps/spack/packages/linux-rhel9-x86_64_v3/gcc-11.3.1/gcc-12.3.0-ukkkutsxfl5kpnnaxflpkq2jtliwthfz/bin/gcc + CXX : /usr/local/pace-apps/spack/packages/linux-rhel9-x86_64_v3/gcc-11.3.1/gcc-12.3.0-ukkkutsxfl5kpnnaxflpkq2jtliwthfz/bin/g++ + FC : /usr/local/pace-apps/spack/packages/linux-rhel9-x86_64_v3/gcc-11.3.1/gcc-12.3.0-ukkkutsxfl5kpnnaxflpkq2jtliwthfz/bin/gfortran + OMPI_CC : + OMPI_CXX : + OMPI_FC : + +post_process: + + CMake Configuration: + + CMake v3.26.5 on atl1-1-02-002-28-2.pace.gatech.edu + + C : GNU v12.3.0 (/usr/local/pace-apps/spack/packages/linux-rhel9-x86_64_v3/gcc-11.3.1/gcc-12.3.0-ukkkutsxfl5kpnnaxflpkq2jtliwthfz/bin/gcc) + Fortran : GNU v12.3.0 (/usr/local/pace-apps/spack/packages/linux-rhel9-x86_64_v3/gcc-11.3.1/gcc-12.3.0-ukkkutsxfl5kpnnaxflpkq2jtliwthfz/bin/gfortran) + + PRE_PROCESS : OFF + SIMULATION : OFF + POST_PROCESS : ON SYSCHECK : OFF DOCUMENTATION : OFF ALL : OFF @@ -94,7 +162,7 @@ pre_process: OpenACC : OFF OpenMP : OFF - Fypp : /storage/home/hcoda1/6/sbryngelson3/scratch/MFC-prs/build/venv/bin/fypp + Fypp : /storage/scratch1/6/sbryngelson3/MFC-ruff/build/venv/bin/fypp Doxygen : Build Type : Release @@ -126,7 +194,7 @@ CPU: Core(s) per socket: 12 Socket(s): 2 Stepping: 7 - CPU(s) scaling MHz: 97% + CPU(s) scaling MHz: 95% CPU max MHz: 2700.0000 CPU min MHz: 1200.0000 BogoMIPS: 5400.00 diff --git a/tests/CE7B0BC7/golden.txt b/tests/CE7B0BC7/golden.txt index b1011e6325..d02ecc3b2d 100644 --- a/tests/CE7B0BC7/golden.txt +++ b/tests/CE7B0BC7/golden.txt @@ -1,4 +1,4 @@ -D/beta.9.00.000050.dat 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999999708435 0.9999999644801 0.99999984081087 0.99999973754149 0.99999984081087 0.9999999644801 0.99999999708435 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.9999999644801 0.99999956727907 0.99999806067934 0.99999680260077 0.99999806067934 0.99999956727907 0.9999999644801 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999984081087 0.99999806067934 0.99999130856777 0.99998567025082 0.99999130856777 0.99999806067934 0.99999984081087 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999973754149 0.99999680260077 0.99998567025082 0.99997637423772 0.99998567025082 0.99999680260077 0.99999973754149 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999984081087 0.99999806067934 0.99999130856777 0.99998567025082 0.99999130856777 0.99999806067934 0.99999984081087 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.9999999644801 0.99999956727907 0.99999806067934 0.99999680260077 0.99999806067934 0.99999956727907 0.9999999644801 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999999708435 0.9999999644801 0.99999984081087 0.99999973754149 0.99999984081087 0.9999999644801 0.99999999708435 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.9999999644801 0.99999956727907 0.99999806067934 0.99999680260077 0.99999806067934 0.99999956727907 0.9999999644801 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999956727907 0.99999472837988 0.99997637423772 0.99996104770319 0.99997637423772 0.99999472837988 0.99999956727907 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999806067934 0.99997637423772 0.9998941166794 0.99982542791712 0.9998941166794 0.99997637423772 0.99999806067934 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999680260077 0.99996104770319 0.99982542791712 0.99971217929369 0.99982542791712 0.99996104770319 0.99999680260077 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999806067934 0.99997637423772 0.9998941166794 0.99982542791712 0.9998941166794 0.99997637423772 0.99999806067934 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999956727907 0.99999472837988 0.99997637423772 0.99996104770319 0.99997637423772 0.99999472837988 0.99999956727907 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.9999999644801 0.99999956727907 0.99999806067934 0.99999680260077 0.99999806067934 0.99999956727907 0.9999999644801 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999984081087 0.99999806067934 0.99999130856777 0.99998567025082 0.99999130856777 0.99999806067934 0.99999984081087 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999806067934 0.99997637423772 0.9998941166794 0.99982542791712 0.9998941166794 0.99997637423772 0.99999806067934 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999130856777 0.9998941166794 0.99952546387935 0.99921762220417 0.99952546387935 0.9998941166794 0.99999130856777 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99998567025082 0.99982542791712 0.99921762220417 0.99871007708629 0.99921762220417 0.99982542791712 0.99998567025082 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999130856777 0.9998941166794 0.99952546387935 0.99921762220417 0.99952546387935 0.9998941166794 0.99999130856777 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999806067934 0.99997637423772 0.9998941166794 0.99982542791712 0.9998941166794 0.99997637423772 0.99999806067934 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999984081087 0.99999806067934 0.99999130856777 0.99998567025082 0.99999130856777 0.99999806067934 0.99999984081087 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999973754149 0.99999680260077 0.99998567025082 0.99997637423772 0.99998567025082 0.99999680260077 0.99999973754149 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999680260077 0.99996104770319 0.99982542791712 0.99971217929369 0.99982542791712 0.99996104770319 0.99999680260077 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99998567025082 0.99982542791712 0.99921762220417 0.99871007708629 0.99921762220417 0.99982542791712 0.99998567025082 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99997637423772 0.99971217929369 0.99871007708629 0.99787327665461 0.99871007708629 0.99971217929369 0.99997637423772 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99998567025082 0.99982542791712 0.99921762220417 0.99871007708629 0.99921762220417 0.99982542791712 0.99998567025082 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999680260077 0.99996104770319 0.99982542791712 0.99971217929369 0.99982542791712 0.99996104770319 0.99999680260077 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999973754149 0.99999680260077 0.99998567025082 0.99997637423772 0.99998567025082 0.99999680260077 0.99999973754149 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999984081087 0.99999806067934 0.99999130856777 0.99998567025082 0.99999130856777 0.99999806067934 0.99999984081087 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999806067934 0.99997637423772 0.9998941166794 0.99982542791712 0.9998941166794 0.99997637423772 0.99999806067934 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999130856777 0.9998941166794 0.99952546387935 0.99921762220417 0.99952546387935 0.9998941166794 0.99999130856777 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99998567025082 0.99982542791712 0.99921762220417 0.99871007708629 0.99921762220417 0.99982542791712 0.99998567025082 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999130856777 0.9998941166794 0.99952546387935 0.99921762220417 0.99952546387935 0.9998941166794 0.99999130856777 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999806067934 0.99997637423772 0.9998941166794 0.99982542791712 0.9998941166794 0.99997637423772 0.99999806067934 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999984081087 0.99999806067934 0.99999130856777 0.99998567025082 0.99999130856777 0.99999806067934 0.99999984081087 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.9999999644801 0.99999956727907 0.99999806067934 0.99999680260077 0.99999806067934 0.99999956727907 0.9999999644801 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999956727907 0.99999472837988 0.99997637423772 0.99996104770319 0.99997637423772 0.99999472837988 0.99999956727907 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999806067934 0.99997637423772 0.9998941166794 0.99982542791712 0.9998941166794 0.99997637423772 0.99999806067934 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999680260077 0.99996104770319 0.99982542791712 0.99971217929369 0.99982542791712 0.99996104770319 0.99999680260077 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999806067934 0.99997637423772 0.9998941166794 0.99982542791712 0.9998941166794 0.99997637423772 0.99999806067934 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999956727907 0.99999472837988 0.99997637423772 0.99996104770319 0.99997637423772 0.99999472837988 0.99999956727907 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.9999999644801 0.99999956727907 0.99999806067934 0.99999680260077 0.99999806067934 0.99999956727907 0.9999999644801 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999999708435 0.9999999644801 0.99999984081087 0.99999973754149 0.99999984081087 0.9999999644801 0.99999999708435 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.9999999644801 0.99999956727907 0.99999806067934 0.99999680260077 0.99999806067934 0.99999956727907 0.9999999644801 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999984081087 0.99999806067934 0.99999130856777 0.99998567025082 0.99999130856777 0.99999806067934 0.99999984081087 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999973754149 0.99999680260077 0.99998567025082 0.99997637423772 0.99998567025082 0.99999680260077 0.99999973754149 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999984081087 0.99999806067934 0.99999130856777 0.99998567025082 0.99999130856777 0.99999806067934 0.99999984081087 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.9999999644801 0.99999956727907 0.99999806067934 0.99999680260077 0.99999806067934 0.99999956727907 0.9999999644801 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999999708435 0.9999999644801 0.99999984081087 0.99999973754149 0.99999984081087 0.9999999644801 0.99999999708435 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 +D/beta.9.00.000050.dat 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.9999999970844 0.99999996448075 0.99999984081375 0.99999973754625 0.99999984081375 0.99999996448075 0.9999999970844 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999996448075 0.99999956728692 0.9999980607145 0.99999680265875 0.9999980607145 0.99999956728692 0.99999996448075 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999984081375 0.9999980607145 0.99999130872539 0.99998567051068 0.99999130872539 0.9999980607145 0.99999984081375 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999973754625 0.99999680265875 0.99998567051068 0.99997637466616 0.99998567051068 0.99999680265875 0.99999973754625 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999984081375 0.9999980607145 0.99999130872539 0.99998567051068 0.99999130872539 0.9999980607145 0.99999984081375 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999996448075 0.99999956728692 0.9999980607145 0.99999680265875 0.9999980607145 0.99999956728692 0.99999996448075 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.9999999970844 0.99999996448075 0.99999984081375 0.99999973754625 0.99999984081375 0.99999996448075 0.9999999970844 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999996448075 0.99999956728692 0.9999980607145 0.99999680265875 0.9999980607145 0.99999956728692 0.99999996448075 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999956728692 0.99999472847548 0.99997637466616 0.99996104840957 0.99997637466616 0.99999472847548 0.99999956728692 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.9999980607145 0.99997637466616 0.99989411859955 0.9998254310829 0.99989411859955 0.99997637466616 0.9999980607145 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999680265875 0.99996104840957 0.9998254310829 0.99971218451318 0.9998254310829 0.99996104840957 0.99999680265875 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.9999980607145 0.99997637466616 0.99989411859955 0.9998254310829 0.99989411859955 0.99997637466616 0.9999980607145 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999956728692 0.99999472847548 0.99997637466616 0.99996104840957 0.99997637466616 0.99999472847548 0.99999956728692 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999996448075 0.99999956728692 0.9999980607145 0.99999680265875 0.9999980607145 0.99999956728692 0.99999996448075 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999984081375 0.9999980607145 0.99999130872539 0.99998567051068 0.99999130872539 0.9999980607145 0.99999984081375 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.9999980607145 0.99997637466616 0.99989411859955 0.9998254310829 0.99989411859955 0.99997637466616 0.9999980607145 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999130872539 0.99989411859955 0.99952547248484 0.99921763639223 0.99952547248484 0.99989411859955 0.99999130872539 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99998567051068 0.9998254310829 0.99921763639223 0.99871010047844 0.99921763639223 0.9998254310829 0.99998567051068 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999130872539 0.99989411859955 0.99952547248484 0.99921763639223 0.99952547248484 0.99989411859955 0.99999130872539 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.9999980607145 0.99997637466616 0.99989411859955 0.9998254310829 0.99989411859955 0.99997637466616 0.9999980607145 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999984081375 0.9999980607145 0.99999130872539 0.99998567051068 0.99999130872539 0.9999980607145 0.99999984081375 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999973754625 0.99999680265875 0.99998567051068 0.99997637466616 0.99998567051068 0.99999680265875 0.99999973754625 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999680265875 0.99996104840957 0.9998254310829 0.99971218451318 0.9998254310829 0.99996104840957 0.99999680265875 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99998567051068 0.9998254310829 0.99921763639223 0.99871010047844 0.99921763639223 0.9998254310829 0.99998567051068 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99997637466616 0.99971218451318 0.99871010047844 0.99787331522175 0.99871010047844 0.99971218451318 0.99997637466616 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99998567051068 0.9998254310829 0.99921763639223 0.99871010047844 0.99921763639223 0.9998254310829 0.99998567051068 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999680265875 0.99996104840957 0.9998254310829 0.99971218451318 0.9998254310829 0.99996104840957 0.99999680265875 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999973754625 0.99999680265875 0.99998567051068 0.99997637466616 0.99998567051068 0.99999680265875 0.99999973754625 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999984081375 0.9999980607145 0.99999130872539 0.99998567051068 0.99999130872539 0.9999980607145 0.99999984081375 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.9999980607145 0.99997637466616 0.99989411859955 0.9998254310829 0.99989411859955 0.99997637466616 0.9999980607145 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999130872539 0.99989411859955 0.99952547248484 0.99921763639223 0.99952547248484 0.99989411859955 0.99999130872539 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99998567051068 0.9998254310829 0.99921763639223 0.99871010047844 0.99921763639223 0.9998254310829 0.99998567051068 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999130872539 0.99989411859955 0.99952547248484 0.99921763639223 0.99952547248484 0.99989411859955 0.99999130872539 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.9999980607145 0.99997637466616 0.99989411859955 0.9998254310829 0.99989411859955 0.99997637466616 0.9999980607145 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999984081375 0.9999980607145 0.99999130872539 0.99998567051068 0.99999130872539 0.9999980607145 0.99999984081375 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999996448075 0.99999956728692 0.9999980607145 0.99999680265875 0.9999980607145 0.99999956728692 0.99999996448075 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999956728692 0.99999472847548 0.99997637466616 0.99996104840957 0.99997637466616 0.99999472847548 0.99999956728692 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.9999980607145 0.99997637466616 0.99989411859955 0.9998254310829 0.99989411859955 0.99997637466616 0.9999980607145 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999680265875 0.99996104840957 0.9998254310829 0.99971218451318 0.9998254310829 0.99996104840957 0.99999680265875 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.9999980607145 0.99997637466616 0.99989411859955 0.9998254310829 0.99989411859955 0.99997637466616 0.9999980607145 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999956728692 0.99999472847548 0.99997637466616 0.99996104840957 0.99997637466616 0.99999472847548 0.99999956728692 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999996448075 0.99999956728692 0.9999980607145 0.99999680265875 0.9999980607145 0.99999956728692 0.99999996448075 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.9999999970844 0.99999996448075 0.99999984081375 0.99999973754625 0.99999984081375 0.99999996448075 0.9999999970844 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999996448075 0.99999956728692 0.9999980607145 0.99999680265875 0.9999980607145 0.99999956728692 0.99999996448075 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999984081375 0.9999980607145 0.99999130872539 0.99998567051068 0.99999130872539 0.9999980607145 0.99999984081375 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999973754625 0.99999680265875 0.99998567051068 0.99997637466616 0.99998567051068 0.99999680265875 0.99999973754625 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999984081375 0.9999980607145 0.99999130872539 0.99998567051068 0.99999130872539 0.9999980607145 0.99999984081375 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999996448075 0.99999956728692 0.9999980607145 0.99999680265875 0.9999980607145 0.99999956728692 0.99999996448075 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.9999999970844 0.99999996448075 0.99999984081375 0.99999973754625 0.99999984081375 0.99999996448075 0.9999999970844 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 D/cons.1.00.000000.dat 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 D/cons.1.00.000050.dat 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999987 0.95999999999987 0.95999999999987 0.95999999999987 0.95999999999987 0.95999999999987 0.95999999999987 0.95999999999987 0.95999999999987 0.95999999999987 0.95999999999987 0.95999999999987 0.95999999999987 0.95999999999987 0.95999999999987 0.95999999999987 0.95999999999987 0.95999999999987 0.95999999999987 0.95999999999987 0.95999999999987 0.95999999999987 0.95999999999987 0.95999999999987 0.95999999999987 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000106 0.96000000000106 0.96000000000106 0.96000000000106 0.96000000000106 0.96000000000106 0.96000000000106 0.96000000000106 0.96000000000106 0.96000000000106 0.96000000000106 0.96000000000106 0.96000000000106 0.96000000000106 0.96000000000106 0.96000000000106 0.96000000000106 0.96000000000106 0.96000000000106 0.96000000000106 0.96000000000106 0.96000000000106 0.96000000000106 0.96000000000106 0.96000000000106 0.96000000000071 0.96000000000071 0.96000000000071 0.96000000000071 0.96000000000071 0.96000000000071 0.96000000000071 0.96000000000071 0.96000000000071 0.96000000000071 0.96000000000071 0.96000000000071 0.96000000000071 0.96000000000071 0.96000000000071 0.96000000000071 0.96000000000071 0.96000000000071 0.96000000000071 0.96000000000071 0.96000000000071 0.96000000000071 0.96000000000071 0.96000000000071 0.96000000000071 0.96000000000373 0.96000000000373 0.96000000000373 0.96000000000373 0.96000000000373 0.96000000000373 0.96000000000373 0.96000000000373 0.96000000000373 0.96000000000373 0.96000000000373 0.96000000000373 0.96000000000373 0.96000000000373 0.96000000000373 0.96000000000373 0.96000000000373 0.96000000000373 0.96000000000373 0.96000000000373 0.96000000000373 0.96000000000373 0.96000000000373 0.96000000000373 0.96000000000373 0.96000000000075 0.96000000000075 0.96000000000075 0.96000000000075 0.96000000000075 0.96000000000075 0.96000000000075 0.96000000000075 0.96000000000075 0.96000000000075 0.96000000000075 0.96000000000075 0.96000000000075 0.96000000000075 0.96000000000075 0.96000000000075 0.96000000000075 0.96000000000075 0.96000000000075 0.96000000000075 0.96000000000075 0.96000000000075 0.96000000000075 0.96000000000075 0.96000000000075 0.96000000000107 0.96000000000107 0.96000000000107 0.96000000000107 0.96000000000107 0.96000000000107 0.96000000000107 0.96000000000107 0.96000000000107 0.96000000000107 0.96000000000107 0.96000000000107 0.96000000000107 0.96000000000107 0.96000000000107 0.96000000000107 0.96000000000107 0.96000000000107 0.96000000000107 0.96000000000107 0.96000000000107 0.96000000000107 0.96000000000107 0.96000000000107 0.96000000000107 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.9600000000001 0.9600000000001 0.9600000000001 0.9600000000001 0.9600000000001 0.9600000000001 0.9600000000001 0.9600000000001 0.9600000000001 0.9600000000001 0.9600000000001 0.9600000000001 0.9600000000001 0.9600000000001 0.9600000000001 0.9600000000001 0.9600000000001 0.9600000000001 0.9600000000001 0.9600000000001 0.9600000000001 0.9600000000001 0.9600000000001 0.9600000000001 0.9600000000001 0.96000000000079 0.96000000000079 0.96000000000079 0.96000000000079 0.96000000000079 0.96000000000079 0.96000000000079 0.96000000000079 0.96000000000079 0.96000000000079 0.96000000000079 0.96000000000079 0.96000000000079 0.96000000000079 0.96000000000079 0.96000000000079 0.96000000000079 0.96000000000079 0.96000000000079 0.96000000000079 0.96000000000079 0.96000000000079 0.96000000000079 0.96000000000079 0.96000000000079 0.96000000002206 0.96000000002206 0.96000000002206 0.96000000002206 0.96000000002206 0.96000000002206 0.96000000002206 0.96000000002206 0.96000000002206 0.96000000002206 0.96000000002206 0.96000000002206 0.96000000002206 0.96000000002206 0.96000000002206 0.96000000002206 0.96000000002206 0.96000000002206 0.96000000002206 0.96000000002206 0.96000000002206 0.96000000002206 0.96000000002206 0.96000000002206 0.96000000002206 0.96000000005987 0.96000000005987 0.96000000005987 0.96000000005987 0.96000000005987 0.96000000005987 0.96000000005987 0.96000000005987 0.96000000005987 0.96000000005987 0.96000000005987 0.96000000005987 0.96000000005987 0.96000000005987 0.96000000005987 0.96000000005987 0.96000000005987 0.96000000005987 0.96000000005987 0.96000000005987 0.96000000005987 0.96000000005987 0.96000000005987 0.96000000005987 0.96000000005987 0.96000000004881 0.96000000004881 0.96000000004881 0.96000000004881 0.96000000004881 0.96000000004881 0.96000000004881 0.96000000004881 0.96000000004881 0.96000000004881 0.96000000004881 0.96000000004881 0.96000000004881 0.96000000004881 0.96000000004881 0.96000000004881 0.96000000004881 0.96000000004881 0.96000000004881 0.96000000004881 0.96000000004881 0.96000000004881 0.96000000004881 0.96000000004881 0.96000000004881 0.96000000032881 0.96000000032881 0.96000000032881 0.96000000032881 0.96000000032881 0.96000000032881 0.96000000032881 0.96000000032881 0.96000000032881 0.96000000032881 0.96000000032881 0.96000000032881 0.96000000032881 0.96000000032881 0.96000000032881 0.96000000032881 0.96000000032881 0.96000000032881 0.96000000032881 0.96000000032881 0.96000000032881 0.96000000032881 0.96000000032881 0.96000000032881 0.96000000032881 0.96000000005864 0.96000000005864 0.96000000005864 0.96000000005864 0.96000000005864 0.96000000005864 0.96000000005864 0.96000000005864 0.96000000005864 0.96000000005864 0.96000000005864 0.96000000005864 0.96000000005864 0.96000000005864 0.96000000005864 0.96000000005864 0.96000000005864 0.96000000005864 0.96000000005864 0.96000000005864 0.96000000005864 0.96000000005864 0.96000000005864 0.96000000005864 0.96000000005864 0.96000000008629 0.96000000008629 0.96000000008629 0.96000000008629 0.96000000008629 0.96000000008629 0.96000000008629 0.96000000008629 0.96000000008629 0.96000000008629 0.96000000008629 0.96000000008629 0.96000000008629 0.96000000008629 0.96000000008629 0.96000000008629 0.96000000008629 0.96000000008629 0.96000000008629 0.96000000008629 0.96000000008629 0.96000000008629 0.96000000008629 0.96000000008629 0.96000000008629 0.96000000000597 0.96000000000597 0.96000000000597 0.96000000000597 0.96000000000597 0.96000000000597 0.96000000000597 0.96000000000597 0.96000000000597 0.96000000000597 0.96000000000597 0.96000000000597 0.96000000000597 0.96000000000597 0.96000000000597 0.96000000000597 0.96000000000597 0.96000000000597 0.96000000000597 0.96000000000597 0.96000000000597 0.96000000000597 0.96000000000597 0.96000000000597 0.96000000000597 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.9600000000021 0.9600000000021 0.9600000000021 0.9600000000021 0.9600000000021 0.9600000000021 0.9600000000021 0.9600000000021 0.9600000000021 0.9600000000021 0.9600000000021 0.9600000000021 0.9600000000021 0.9600000000021 0.9600000000021 0.9600000000021 0.9600000000021 0.9600000000021 0.9600000000021 0.9600000000021 0.9600000000021 0.9600000000021 0.9600000000021 0.9600000000021 0.9600000000021 0.96000000013587 0.96000000013587 0.96000000013587 0.96000000013587 0.96000000013587 0.96000000013587 0.96000000013587 0.96000000013587 0.96000000013587 0.96000000013587 0.96000000013587 0.96000000013587 0.96000000013587 0.96000000013587 0.96000000013587 0.96000000013587 0.96000000013587 0.96000000013587 0.96000000013587 0.96000000013587 0.96000000013587 0.96000000013587 0.96000000013587 0.96000000013587 0.96000000013587 0.96000000392457 0.96000000392457 0.96000000392457 0.96000000392457 0.96000000392457 0.96000000392457 0.96000000392457 0.96000000392457 0.96000000392457 0.96000000392457 0.96000000392457 0.96000000392457 0.96000000392457 0.96000000392457 0.96000000392457 0.96000000392457 0.96000000392457 0.96000000392457 0.96000000392457 0.96000000392457 0.96000000392457 0.96000000392457 0.96000000392457 0.96000000392457 0.96000000392457 0.96000000386601 0.96000000386601 0.96000000386601 0.96000000386601 0.96000000386601 0.96000000386601 0.96000000386601 0.96000000386601 0.96000000386601 0.96000000386601 0.96000000386601 0.96000000386601 0.96000000386601 0.96000000386601 0.96000000386601 0.96000000386601 0.96000000386601 0.96000000386601 0.96000000386601 0.96000000386601 0.96000000386601 0.96000000386601 0.96000000386601 0.96000000386601 0.96000000386601 0.96000000372715 0.96000000372715 0.96000000372715 0.96000000372715 0.96000000372715 0.96000000372715 0.96000000372715 0.96000000372715 0.96000000372715 0.96000000372715 0.96000000372715 0.96000000372715 0.96000000372715 0.96000000372715 0.96000000372715 0.96000000372715 0.96000000372715 0.96000000372715 0.96000000372715 0.96000000372715 0.96000000372715 0.96000000372715 0.96000000372715 0.96000000372715 0.96000000372715 0.96000002634421 0.96000002634421 0.96000002634421 0.96000002634421 0.96000002634421 0.96000002634421 0.96000002634421 0.96000002634421 0.96000002634421 0.96000002634421 0.96000002634421 0.96000002634421 0.96000002634421 0.96000002634421 0.96000002634421 0.96000002634421 0.96000002634421 0.96000002634421 0.96000002634421 0.96000002634421 0.96000002634421 0.96000002634421 0.96000002634421 0.96000002634421 0.96000002634421 0.96000000528784 0.96000000528784 0.96000000528784 0.96000000528784 0.96000000528784 0.96000000528784 0.96000000528784 0.96000000528784 0.96000000528784 0.96000000528784 0.96000000528784 0.96000000528784 0.96000000528784 0.96000000528784 0.96000000528784 0.96000000528784 0.96000000528784 0.96000000528784 0.96000000528784 0.96000000528784 0.96000000528784 0.96000000528784 0.96000000528784 0.96000000528784 0.96000000528784 0.96000000790203 0.96000000790203 0.96000000790203 0.96000000790203 0.96000000790203 0.96000000790203 0.96000000790203 0.96000000790203 0.96000000790203 0.96000000790203 0.96000000790203 0.96000000790203 0.96000000790203 0.96000000790203 0.96000000790203 0.96000000790203 0.96000000790203 0.96000000790203 0.96000000790203 0.96000000790203 0.96000000790203 0.96000000790203 0.96000000790203 0.96000000790203 0.96000000790203 0.96000000059137 0.96000000059137 0.96000000059137 0.96000000059137 0.96000000059137 0.96000000059137 0.96000000059137 0.96000000059137 0.96000000059137 0.96000000059137 0.96000000059137 0.96000000059137 0.96000000059137 0.96000000059137 0.96000000059137 0.96000000059137 0.96000000059137 0.96000000059137 0.96000000059137 0.96000000059137 0.96000000059137 0.96000000059137 0.96000000059137 0.96000000059137 0.96000000059137 0.96000000001228 0.96000000001228 0.96000000001228 0.96000000001228 0.96000000001228 0.96000000001228 0.96000000001228 0.96000000001228 0.96000000001228 0.96000000001228 0.96000000001228 0.96000000001228 0.96000000001228 0.96000000001228 0.96000000001228 0.96000000001228 0.96000000001228 0.96000000001228 0.96000000001228 0.96000000001228 0.96000000001228 0.96000000001228 0.96000000001228 0.96000000001228 0.96000000001228 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000002232 0.96000000002232 0.96000000002232 0.96000000002232 0.96000000002232 0.96000000002232 0.96000000002232 0.96000000002232 0.96000000002232 0.96000000002232 0.96000000002232 0.96000000002232 0.96000000002232 0.96000000002232 0.96000000002232 0.96000000002232 0.96000000002232 0.96000000002232 0.96000000002232 0.96000000002232 0.96000000002232 0.96000000002232 0.96000000002232 0.96000000002232 0.96000000002232 0.960000001086 0.960000001086 0.960000001086 0.960000001086 0.960000001086 0.960000001086 0.960000001086 0.960000001086 0.960000001086 0.960000001086 0.960000001086 0.960000001086 0.960000001086 0.960000001086 0.960000001086 0.960000001086 0.960000001086 0.960000001086 0.960000001086 0.960000001086 0.960000001086 0.960000001086 0.960000001086 0.960000001086 0.960000001086 0.96000003357351 0.96000003357351 0.96000003357351 0.96000003357351 0.96000003357351 0.96000003357351 0.96000003357351 0.96000003357351 0.96000003357351 0.96000003357351 0.96000003357351 0.96000003357351 0.96000003357351 0.96000003357351 0.96000003357351 0.96000003357351 0.96000003357351 0.96000003357351 0.96000003357351 0.96000003357351 0.96000003357351 0.96000003357351 0.96000003357351 0.96000003357351 0.96000003357351 0.9600007182478 0.9600007182478 0.9600007182478 0.9600007182478 0.9600007182478 0.9600007182478 0.9600007182478 0.9600007182478 0.9600007182478 0.9600007182478 0.9600007182478 0.9600007182478 0.9600007182478 0.9600007182478 0.9600007182478 0.9600007182478 0.9600007182478 0.9600007182478 0.9600007182478 0.9600007182478 0.9600007182478 0.9600007182478 0.9600007182478 0.9600007182478 0.9600007182478 0.96000023896672 0.96000023896672 0.96000023896672 0.96000023896672 0.96000023896672 0.96000023896672 0.96000023896672 0.96000023896672 0.96000023896672 0.96000023896672 0.96000023896672 0.96000023896672 0.96000023896672 0.96000023896672 0.96000023896672 0.96000023896672 0.96000023896672 0.96000023896672 0.96000023896672 0.96000023896672 0.96000023896672 0.96000023896672 0.96000023896672 0.96000023896672 0.96000023896672 0.96000168485738 0.96000168485738 0.96000168485738 0.96000168485738 0.96000168485738 0.96000168485738 0.96000168485738 0.96000168485738 0.96000168485738 0.96000168485738 0.96000168485738 0.96000168485738 0.96000168485738 0.96000168485738 0.96000168485738 0.96000168485738 0.96000168485738 0.96000168485738 0.96000168485738 0.96000168485738 0.96000168485738 0.96000168485738 0.96000168485738 0.96000168485738 0.96000168485738 0.96000038977218 0.96000038977218 0.96000038977218 0.96000038977218 0.96000038977218 0.96000038977218 0.96000038977218 0.96000038977218 0.96000038977218 0.96000038977218 0.96000038977218 0.96000038977218 0.96000038977218 0.96000038977218 0.96000038977218 0.96000038977218 0.96000038977218 0.96000038977218 0.96000038977218 0.96000038977218 0.96000038977218 0.96000038977218 0.96000038977218 0.96000038977218 0.96000038977218 0.96000058691047 0.96000058691047 0.96000058691047 0.96000058691047 0.96000058691047 0.96000058691047 0.96000058691047 0.96000058691047 0.96000058691047 0.96000058691047 0.96000058691047 0.96000058691047 0.96000058691047 0.96000058691047 0.96000058691047 0.96000058691047 0.96000058691047 0.96000058691047 0.96000058691047 0.96000058691047 0.96000058691047 0.96000058691047 0.96000058691047 0.96000058691047 0.96000058691047 0.96000005194927 0.96000005194927 0.96000005194927 0.96000005194927 0.96000005194927 0.96000005194927 0.96000005194927 0.96000005194927 0.96000005194927 0.96000005194927 0.96000005194927 0.96000005194927 0.96000005194927 0.96000005194927 0.96000005194927 0.96000005194927 0.96000005194927 0.96000005194927 0.96000005194927 0.96000005194927 0.96000005194927 0.96000005194927 0.96000005194927 0.96000005194927 0.96000005194927 0.96000000110092 0.96000000110092 0.96000000110092 0.96000000110092 0.96000000110092 0.96000000110092 0.96000000110092 0.96000000110092 0.96000000110092 0.96000000110092 0.96000000110092 0.96000000110092 0.96000000110092 0.96000000110092 0.96000000110092 0.96000000110092 0.96000000110092 0.96000000110092 0.96000000110092 0.96000000110092 0.96000000110092 0.96000000110092 0.96000000110092 0.96000000110092 0.96000000110092 0.96000000002787 0.96000000002787 0.96000000002787 0.96000000002787 0.96000000002787 0.96000000002787 0.96000000002787 0.96000000002787 0.96000000002787 0.96000000002787 0.96000000002787 0.96000000002787 0.96000000002787 0.96000000002787 0.96000000002787 0.96000000002787 0.96000000002787 0.96000000002787 0.96000000002787 0.96000000002787 0.96000000002787 0.96000000002787 0.96000000002787 0.96000000002787 0.96000000002787 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96000000000024 0.96000000000024 0.96000000000024 0.96000000000024 0.96000000000024 0.96000000000024 0.96000000000024 0.96000000000024 0.96000000000024 0.96000000000024 0.96000000000024 0.96000000000024 0.96000000000024 0.96000000000024 0.96000000000024 0.96000000000024 0.96000000000024 0.96000000000024 0.96000000000024 0.96000000000024 0.96000000000024 0.96000000000024 0.96000000000024 0.96000000000024 0.96000000000024 0.96000000000461 0.96000000000461 0.96000000000461 0.96000000000461 0.96000000000461 0.96000000000461 0.96000000000461 0.96000000000461 0.96000000000461 0.96000000000461 0.96000000000461 0.96000000000461 0.96000000000461 0.96000000000461 0.96000000000461 0.96000000000461 0.96000000000461 0.96000000000461 0.96000000000461 0.96000000000461 0.96000000000461 0.96000000000461 0.96000000000461 0.96000000000461 0.96000000000461 0.96000000028923 0.96000000028923 0.96000000028923 0.96000000028923 0.96000000028923 0.96000000028923 0.96000000028923 0.96000000028923 0.96000000028923 0.96000000028923 0.96000000028923 0.96000000028923 0.96000000028923 0.96000000028923 0.96000000028923 0.96000000028923 0.96000000028923 0.96000000028923 0.96000000028923 0.96000000028923 0.96000000028923 0.96000000028923 0.96000000028923 0.96000000028923 0.96000000028923 0.96000001055314 0.96000001055314 0.96000001055314 0.96000001055314 0.96000001055314 0.96000001055314 0.96000001055314 0.96000001055314 0.96000001055314 0.96000001055314 0.96000001055314 0.96000001055314 0.96000001055314 0.96000001055314 0.96000001055314 0.96000001055314 0.96000001055314 0.96000001055314 0.96000001055314 0.96000001055314 0.96000001055314 0.96000001055314 0.96000001055314 0.96000001055314 0.96000001055314 0.96000025210076 0.96000025210076 0.96000025210076 0.96000025210076 0.96000025210076 0.96000025210076 0.96000025210076 0.96000025210076 0.96000025210076 0.96000025210076 0.96000025210076 0.96000025210076 0.96000025210076 0.96000025210076 0.96000025210076 0.96000025210076 0.96000025210076 0.96000025210076 0.96000025210076 0.96000025210076 0.96000025210076 0.96000025210076 0.96000025210076 0.96000025210076 0.96000025210076 0.96000388888139 0.96000388888139 0.96000388888139 0.96000388888139 0.96000388888139 0.96000388888139 0.96000388888139 0.96000388888139 0.96000388888139 0.96000388888139 0.96000388888139 0.96000388888139 0.96000388888139 0.96000388888139 0.96000388888139 0.96000388888139 0.96000388888139 0.96000388888139 0.96000388888139 0.96000388888139 0.96000388888139 0.96000388888139 0.96000388888139 0.96000388888139 0.96000388888139 0.96003762422319 0.96003762422319 0.96003762422319 0.96003762422319 0.96003762422319 0.96003762422319 0.96003762422319 0.96003762422319 0.96003762422319 0.96003762422319 0.96003762422319 0.96003762422319 0.96003762422319 0.96003762422319 0.96003762422319 0.96003762422319 0.96003762422319 0.96003762422319 0.96003762422319 0.96003762422319 0.96003762422319 0.96003762422319 0.96003762422319 0.96003762422319 0.96003762422319 0.96024757938339 0.96024757938339 0.96024757938339 0.96024757938339 0.96024757938339 0.96024757938339 0.96024757938339 0.96024757938339 0.96024757938339 0.96024757938339 0.96024757938339 0.96024757938339 0.96024757938339 0.96024757938339 0.96024757938339 0.96024757938339 0.96024757938339 0.96024757938339 0.96024757938339 0.96024757938339 0.96024757938339 0.96024757938339 0.96024757938339 0.96024757938339 0.96024757938339 0.96002715152843 0.96002715152843 0.96002715152843 0.96002715152843 0.96002715152843 0.96002715152843 0.96002715152843 0.96002715152843 0.96002715152843 0.96002715152843 0.96002715152843 0.96002715152843 0.96002715152843 0.96002715152843 0.96002715152843 0.96002715152843 0.96002715152843 0.96002715152843 0.96002715152843 0.96002715152843 0.96002715152843 0.96002715152843 0.96002715152843 0.96002715152843 0.96002715152843 0.96003089249465 0.96003089249465 0.96003089249465 0.96003089249465 0.96003089249465 0.96003089249465 0.96003089249465 0.96003089249465 0.96003089249465 0.96003089249465 0.96003089249465 0.96003089249465 0.96003089249465 0.96003089249465 0.96003089249465 0.96003089249465 0.96003089249465 0.96003089249465 0.96003089249465 0.96003089249465 0.96003089249465 0.96003089249465 0.96003089249465 0.96003089249465 0.96003089249465 0.96000375036941 0.96000375036941 0.96000375036941 0.96000375036941 0.96000375036941 0.96000375036941 0.96000375036941 0.96000375036941 0.96000375036941 0.96000375036941 0.96000375036941 0.96000375036941 0.96000375036941 0.96000375036941 0.96000375036941 0.96000375036941 0.96000375036941 0.96000375036941 0.96000375036941 0.96000375036941 0.96000375036941 0.96000375036941 0.96000375036941 0.96000375036941 0.96000375036941 0.96000008693805 0.96000008693805 0.96000008693805 0.96000008693805 0.96000008693805 0.96000008693805 0.96000008693805 0.96000008693805 0.96000008693805 0.96000008693805 0.96000008693805 0.96000008693805 0.96000008693805 0.96000008693805 0.96000008693805 0.96000008693805 0.96000008693805 0.96000008693805 0.96000008693805 0.96000008693805 0.96000008693805 0.96000008693805 0.96000008693805 0.96000008693805 0.96000008693805 0.96000000244292 0.96000000244292 0.96000000244292 0.96000000244292 0.96000000244292 0.96000000244292 0.96000000244292 0.96000000244292 0.96000000244292 0.96000000244292 0.96000000244292 0.96000000244292 0.96000000244292 0.96000000244292 0.96000000244292 0.96000000244292 0.96000000244292 0.96000000244292 0.96000000244292 0.96000000244292 0.96000000244292 0.96000000244292 0.96000000244292 0.96000000244292 0.96000000244292 0.96000000003463 0.96000000003463 0.96000000003463 0.96000000003463 0.96000000003463 0.96000000003463 0.96000000003463 0.96000000003463 0.96000000003463 0.96000000003463 0.96000000003463 0.96000000003463 0.96000000003463 0.96000000003463 0.96000000003463 0.96000000003463 0.96000000003463 0.96000000003463 0.96000000003463 0.96000000003463 0.96000000003463 0.96000000003463 0.96000000003463 0.96000000003463 0.96000000003463 0.9600000000004 0.9600000000004 0.9600000000004 0.9600000000004 0.9600000000004 0.9600000000004 0.9600000000004 0.9600000000004 0.9600000000004 0.9600000000004 0.9600000000004 0.9600000000004 0.9600000000004 0.9600000000004 0.9600000000004 0.9600000000004 0.9600000000004 0.9600000000004 0.9600000000004 0.9600000000004 0.9600000000004 0.9600000000004 0.9600000000004 0.9600000000004 0.9600000000004 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.96000000000021 0.96000000000021 0.96000000000021 0.96000000000021 0.96000000000021 0.96000000000021 0.96000000000021 0.96000000000021 0.96000000000021 0.96000000000021 0.96000000000021 0.96000000000021 0.96000000000021 0.96000000000021 0.96000000000021 0.96000000000021 0.96000000000021 0.96000000000021 0.96000000000021 0.96000000000021 0.96000000000021 0.96000000000021 0.96000000000021 0.96000000000021 0.96000000000021 0.96000000000066 0.96000000000066 0.96000000000066 0.96000000000066 0.96000000000066 0.96000000000066 0.96000000000066 0.96000000000066 0.96000000000066 0.96000000000066 0.96000000000066 0.96000000000066 0.96000000000066 0.96000000000066 0.96000000000066 0.96000000000066 0.96000000000066 0.96000000000066 0.96000000000066 0.96000000000066 0.96000000000066 0.96000000000066 0.96000000000066 0.96000000000066 0.96000000000066 0.9600000000725 0.9600000000725 0.9600000000725 0.9600000000725 0.9600000000725 0.9600000000725 0.9600000000725 0.9600000000725 0.9600000000725 0.9600000000725 0.9600000000725 0.9600000000725 0.9600000000725 0.9600000000725 0.9600000000725 0.9600000000725 0.9600000000725 0.9600000000725 0.9600000000725 0.9600000000725 0.9600000000725 0.9600000000725 0.9600000000725 0.9600000000725 0.9600000000725 0.96000000306584 0.96000000306584 0.96000000306584 0.96000000306584 0.96000000306584 0.96000000306584 0.96000000306584 0.96000000306584 0.96000000306584 0.96000000306584 0.96000000306584 0.96000000306584 0.96000000306584 0.96000000306584 0.96000000306584 0.96000000306584 0.96000000306584 0.96000000306584 0.96000000306584 0.96000000306584 0.96000000306584 0.96000000306584 0.96000000306584 0.96000000306584 0.96000000306584 0.96000008513635 0.96000008513635 0.96000008513635 0.96000008513635 0.96000008513635 0.96000008513635 0.96000008513635 0.96000008513635 0.96000008513635 0.96000008513635 0.96000008513635 0.96000008513635 0.96000008513635 0.96000008513635 0.96000008513635 0.96000008513635 0.96000008513635 0.96000008513635 0.96000008513635 0.96000008513635 0.96000008513635 0.96000008513635 0.96000008513635 0.96000008513635 0.96000008513635 0.96000153658661 0.96000153658661 0.96000153658661 0.96000153658661 0.96000153658661 0.96000153658661 0.96000153658661 0.96000153658661 0.96000153658661 0.96000153658661 0.96000153658661 0.96000153658661 0.96000153658661 0.96000153658661 0.96000153658661 0.96000153658661 0.96000153658661 0.96000153658661 0.96000153658661 0.96000153658661 0.96000153658661 0.96000153658661 0.96000153658661 0.96000153658661 0.96000153658661 0.96001782964953 0.96001782964953 0.96001782964953 0.96001782964953 0.96001782964953 0.96001782964953 0.96001782964953 0.96001782964953 0.96001782964953 0.96001782964953 0.96001782964953 0.96001782964953 0.96001782964953 0.96001782964953 0.96001782964953 0.96001782964953 0.96001782964953 0.96001782964953 0.96001782964953 0.96001782964953 0.96001782964953 0.96001782964953 0.96001782964953 0.96001782964953 0.96001782964953 0.96013299338417 0.96013299338417 0.96013299338417 0.96013299338417 0.96013299338417 0.96013299338417 0.96013299338417 0.96013299338417 0.96013299338417 0.96013299338417 0.96013299338417 0.96013299338417 0.96013299338417 0.96013299338417 0.96013299338417 0.96013299338417 0.96013299338417 0.96013299338417 0.96013299338417 0.96013299338417 0.96013299338417 0.96013299338417 0.96013299338417 0.96013299338417 0.96013299338417 0.96063533731738 0.96063533731738 0.96063533731738 0.96063533731738 0.96063533731738 0.96063533731738 0.96063533731738 0.96063533731738 0.96063533731738 0.96063533731738 0.96063533731738 0.96063533731738 0.96063533731738 0.96063533731738 0.96063533731738 0.96063533731738 0.96063533731738 0.96063533731738 0.96063533731738 0.96063533731738 0.96063533731738 0.96063533731738 0.96063533731738 0.96063533731738 0.96063533731738 0.96190052351632 0.96190052351632 0.96190052351632 0.96190052351632 0.96190052351632 0.96190052351632 0.96190052351632 0.96190052351632 0.96190052351632 0.96190052351632 0.96190052351632 0.96190052351632 0.96190052351632 0.96190052351632 0.96190052351632 0.96190052351632 0.96190052351632 0.96190052351632 0.96190052351632 0.96190052351632 0.96190052351632 0.96190052351632 0.96190052351632 0.96190052351632 0.96190052351632 0.96374631791153 0.96374631791153 0.96374631791153 0.96374631791153 0.96374631791153 0.96374631791153 0.96374631791153 0.96374631791153 0.96374631791153 0.96374631791153 0.96374631791153 0.96374631791153 0.96374631791153 0.96374631791153 0.96374631791153 0.96374631791153 0.96374631791153 0.96374631791153 0.96374631791153 0.96374631791153 0.96374631791153 0.96374631791153 0.96374631791153 0.96374631791153 0.96374631791153 0.96026255957098 0.96026255957098 0.96026255957098 0.96026255957098 0.96026255957098 0.96026255957098 0.96026255957098 0.96026255957098 0.96026255957098 0.96026255957098 0.96026255957098 0.96026255957098 0.96026255957098 0.96026255957098 0.96026255957098 0.96026255957098 0.96026255957098 0.96026255957098 0.96026255957098 0.96026255957098 0.96026255957098 0.96026255957098 0.96026255957098 0.96026255957098 0.96026255957098 0.96000700586267 0.96000700586267 0.96000700586267 0.96000700586267 0.96000700586267 0.96000700586267 0.96000700586267 0.96000700586267 0.96000700586267 0.96000700586267 0.96000700586267 0.96000700586267 0.96000700586267 0.96000700586267 0.96000700586267 0.96000700586267 0.96000700586267 0.96000700586267 0.96000700586267 0.96000700586267 0.96000700586267 0.96000700586267 0.96000700586267 0.96000700586267 0.96000700586267 0.96000019245935 0.96000019245935 0.96000019245935 0.96000019245935 0.96000019245935 0.96000019245935 0.96000019245935 0.96000019245935 0.96000019245935 0.96000019245935 0.96000019245935 0.96000019245935 0.96000019245935 0.96000019245935 0.96000019245935 0.96000019245935 0.96000019245935 0.96000019245935 0.96000019245935 0.96000019245935 0.96000019245935 0.96000019245935 0.96000019245935 0.96000019245935 0.96000019245935 0.9600000027078 0.9600000027078 0.9600000027078 0.9600000027078 0.9600000027078 0.9600000027078 0.9600000027078 0.9600000027078 0.9600000027078 0.9600000027078 0.9600000027078 0.9600000027078 0.9600000027078 0.9600000027078 0.9600000027078 0.9600000027078 0.9600000027078 0.9600000027078 0.9600000027078 0.9600000027078 0.9600000027078 0.9600000027078 0.9600000027078 0.9600000027078 0.9600000027078 0.96000000003541 0.96000000003541 0.96000000003541 0.96000000003541 0.96000000003541 0.96000000003541 0.96000000003541 0.96000000003541 0.96000000003541 0.96000000003541 0.96000000003541 0.96000000003541 0.96000000003541 0.96000000003541 0.96000000003541 0.96000000003541 0.96000000003541 0.96000000003541 0.96000000003541 0.96000000003541 0.96000000003541 0.96000000003541 0.96000000003541 0.96000000003541 0.96000000003541 0.96000000000036 0.96000000000036 0.96000000000036 0.96000000000036 0.96000000000036 0.96000000000036 0.96000000000036 0.96000000000036 0.96000000000036 0.96000000000036 0.96000000000036 0.96000000000036 0.96000000000036 0.96000000000036 0.96000000000036 0.96000000000036 0.96000000000036 0.96000000000036 0.96000000000036 0.96000000000036 0.96000000000036 0.96000000000036 0.96000000000036 0.96000000000036 0.96000000000036 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000004 0.96000000000004 0.96000000000004 0.96000000000004 0.96000000000004 0.96000000000004 0.96000000000004 0.96000000000004 0.96000000000004 0.96000000000004 0.96000000000004 0.96000000000004 0.96000000000004 0.96000000000004 0.96000000000004 0.96000000000004 0.96000000000004 0.96000000000004 0.96000000000004 0.96000000000004 0.96000000000004 0.96000000000004 0.96000000000004 0.96000000000004 0.96000000000004 0.96000000001662 0.96000000001662 0.96000000001662 0.96000000001662 0.96000000001662 0.96000000001662 0.96000000001662 0.96000000001662 0.96000000001662 0.96000000001662 0.96000000001662 0.96000000001662 0.96000000001662 0.96000000001662 0.96000000001662 0.96000000001662 0.96000000001662 0.96000000001662 0.96000000001662 0.96000000001662 0.96000000001662 0.96000000001662 0.96000000001662 0.96000000001662 0.96000000001662 0.96000000087018 0.96000000087018 0.96000000087018 0.96000000087018 0.96000000087018 0.96000000087018 0.96000000087018 0.96000000087018 0.96000000087018 0.96000000087018 0.96000000087018 0.96000000087018 0.96000000087018 0.96000000087018 0.96000000087018 0.96000000087018 0.96000000087018 0.96000000087018 0.96000000087018 0.96000000087018 0.96000000087018 0.96000000087018 0.96000000087018 0.96000000087018 0.96000000087018 0.96000002801722 0.96000002801722 0.96000002801722 0.96000002801722 0.96000002801722 0.96000002801722 0.96000002801722 0.96000002801722 0.96000002801722 0.96000002801722 0.96000002801722 0.96000002801722 0.96000002801722 0.96000002801722 0.96000002801722 0.96000002801722 0.96000002801722 0.96000002801722 0.96000002801722 0.96000002801722 0.96000002801722 0.96000002801722 0.96000002801722 0.96000002801722 0.96000002801722 0.96000057403111 0.96000057403111 0.96000057403111 0.96000057403111 0.96000057403111 0.96000057403111 0.96000057403111 0.96000057403111 0.96000057403111 0.96000057403111 0.96000057403111 0.96000057403111 0.96000057403111 0.96000057403111 0.96000057403111 0.96000057403111 0.96000057403111 0.96000057403111 0.96000057403111 0.96000057403111 0.96000057403111 0.96000057403111 0.96000057403111 0.96000057403111 0.96000057403111 0.9600078024614 0.9600078024614 0.9600078024614 0.9600078024614 0.9600078024614 0.9600078024614 0.9600078024614 0.9600078024614 0.9600078024614 0.9600078024614 0.9600078024614 0.9600078024614 0.9600078024614 0.9600078024614 0.9600078024614 0.9600078024614 0.9600078024614 0.9600078024614 0.9600078024614 0.9600078024614 0.9600078024614 0.9600078024614 0.9600078024614 0.9600078024614 0.9600078024614 0.96006802884276 0.96006802884276 0.96006802884276 0.96006802884276 0.96006802884276 0.96006802884276 0.96006802884276 0.96006802884276 0.96006802884276 0.96006802884276 0.96006802884276 0.96006802884276 0.96006802884276 0.96006802884276 0.96006802884276 0.96006802884276 0.96006802884276 0.96006802884276 0.96006802884276 0.96006802884276 0.96006802884276 0.96006802884276 0.96006802884276 0.96006802884276 0.96006802884276 0.96038137379852 0.96038137379852 0.96038137379852 0.96038137379852 0.96038137379852 0.96038137379852 0.96038137379852 0.96038137379852 0.96038137379852 0.96038137379852 0.96038137379852 0.96038137379852 0.96038137379852 0.96038137379852 0.96038137379852 0.96038137379852 0.96038137379852 0.96038137379852 0.96038137379852 0.96038137379852 0.96038137379852 0.96038137379852 0.96038137379852 0.96038137379852 0.96038137379852 0.96137903643732 0.96137903643732 0.96137903643732 0.96137903643732 0.96137903643732 0.96137903643732 0.96137903643732 0.96137903643732 0.96137903643732 0.96137903643732 0.96137903643732 0.96137903643732 0.96137903643732 0.96137903643732 0.96137903643732 0.96137903643732 0.96137903643732 0.96137903643732 0.96137903643732 0.96137903643732 0.96137903643732 0.96137903643732 0.96137903643732 0.96137903643732 0.96137903643732 0.96321014680893 0.96321014680893 0.96321014680893 0.96321014680893 0.96321014680893 0.96321014680893 0.96321014680893 0.96321014680893 0.96321014680893 0.96321014680893 0.96321014680893 0.96321014680893 0.96321014680893 0.96321014680893 0.96321014680893 0.96321014680893 0.96321014680893 0.96321014680893 0.96321014680893 0.96321014680893 0.96321014680893 0.96321014680893 0.96321014680893 0.96321014680893 0.96321014680893 0.96472448360735 0.96472448360735 0.96472448360735 0.96472448360735 0.96472448360735 0.96472448360735 0.96472448360735 0.96472448360735 0.96472448360735 0.96472448360735 0.96472448360735 0.96472448360735 0.96472448360735 0.96472448360735 0.96472448360735 0.96472448360735 0.96472448360735 0.96472448360735 0.96472448360735 0.96472448360735 0.96472448360735 0.96472448360735 0.96472448360735 0.96472448360735 0.96472448360735 0.96430483319369 0.96430483319369 0.96430483319369 0.96430483319369 0.96430483319369 0.96430483319369 0.96430483319369 0.96430483319369 0.96430483319369 0.96430483319369 0.96430483319369 0.96430483319369 0.96430483319369 0.96430483319369 0.96430483319369 0.96430483319369 0.96430483319369 0.96430483319369 0.96430483319369 0.96430483319369 0.96430483319369 0.96430483319369 0.96430483319369 0.96430483319369 0.96430483319369 0.96019082432575 0.96019082432575 0.96019082432575 0.96019082432575 0.96019082432575 0.96019082432575 0.96019082432575 0.96019082432575 0.96019082432575 0.96019082432575 0.96019082432575 0.96019082432575 0.96019082432575 0.96019082432575 0.96019082432575 0.96019082432575 0.96019082432575 0.96019082432575 0.96019082432575 0.96019082432575 0.96019082432575 0.96019082432575 0.96019082432575 0.96019082432575 0.96019082432575 0.96000932467124 0.96000932467124 0.96000932467124 0.96000932467124 0.96000932467124 0.96000932467124 0.96000932467124 0.96000932467124 0.96000932467124 0.96000932467124 0.96000932467124 0.96000932467124 0.96000932467124 0.96000932467124 0.96000932467124 0.96000932467124 0.96000932467124 0.96000932467124 0.96000932467124 0.96000932467124 0.96000932467124 0.96000932467124 0.96000932467124 0.96000932467124 0.96000932467124 0.96000014529282 0.96000014529282 0.96000014529282 0.96000014529282 0.96000014529282 0.96000014529282 0.96000014529282 0.96000014529282 0.96000014529282 0.96000014529282 0.96000014529282 0.96000014529282 0.96000014529282 0.96000014529282 0.96000014529282 0.96000014529282 0.96000014529282 0.96000014529282 0.96000014529282 0.96000014529282 0.96000014529282 0.96000014529282 0.96000014529282 0.96000014529282 0.96000014529282 0.96000000210283 0.96000000210283 0.96000000210283 0.96000000210283 0.96000000210283 0.96000000210283 0.96000000210283 0.96000000210283 0.96000000210283 0.96000000210283 0.96000000210283 0.96000000210283 0.96000000210283 0.96000000210283 0.96000000210283 0.96000000210283 0.96000000210283 0.96000000210283 0.96000000210283 0.96000000210283 0.96000000210283 0.96000000210283 0.96000000210283 0.96000000210283 0.96000000210283 0.96000000002503 0.96000000002503 0.96000000002503 0.96000000002503 0.96000000002503 0.96000000002503 0.96000000002503 0.96000000002503 0.96000000002503 0.96000000002503 0.96000000002503 0.96000000002503 0.96000000002503 0.96000000002503 0.96000000002503 0.96000000002503 0.96000000002503 0.96000000002503 0.96000000002503 0.96000000002503 0.96000000002503 0.96000000002503 0.96000000002503 0.96000000002503 0.96000000002503 0.96000000000025 0.96000000000025 0.96000000000025 0.96000000000025 0.96000000000025 0.96000000000025 0.96000000000025 0.96000000000025 0.96000000000025 0.96000000000025 0.96000000000025 0.96000000000025 0.96000000000025 0.96000000000025 0.96000000000025 0.96000000000025 0.96000000000025 0.96000000000025 0.96000000000025 0.96000000000025 0.96000000000025 0.96000000000025 0.96000000000025 0.96000000000025 0.96000000000025 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.96000000000049 0.96000000000049 0.96000000000049 0.96000000000049 0.96000000000049 0.96000000000049 0.96000000000049 0.96000000000049 0.96000000000049 0.96000000000049 0.96000000000049 0.96000000000049 0.96000000000049 0.96000000000049 0.96000000000049 0.96000000000049 0.96000000000049 0.96000000000049 0.96000000000049 0.96000000000049 0.96000000000049 0.96000000000049 0.96000000000049 0.96000000000049 0.96000000000049 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000804388 0.96000000804388 0.96000000804388 0.96000000804388 0.96000000804388 0.96000000804388 0.96000000804388 0.96000000804388 0.96000000804388 0.96000000804388 0.96000000804388 0.96000000804388 0.96000000804388 0.96000000804388 0.96000000804388 0.96000000804388 0.96000000804388 0.96000000804388 0.96000000804388 0.96000000804388 0.96000000804388 0.96000000804388 0.96000000804388 0.96000000804388 0.96000000804388 0.96000020225341 0.96000020225341 0.96000020225341 0.96000020225341 0.96000020225341 0.96000020225341 0.96000020225341 0.96000020225341 0.96000020225341 0.96000020225341 0.96000020225341 0.96000020225341 0.96000020225341 0.96000020225341 0.96000020225341 0.96000020225341 0.96000020225341 0.96000020225341 0.96000020225341 0.96000020225341 0.96000020225341 0.96000020225341 0.96000020225341 0.96000020225341 0.96000020225341 0.96000325281143 0.96000325281143 0.96000325281143 0.96000325281143 0.96000325281143 0.96000325281143 0.96000325281143 0.96000325281143 0.96000325281143 0.96000325281143 0.96000325281143 0.96000325281143 0.96000325281143 0.96000325281143 0.96000325281143 0.96000325281143 0.96000325281143 0.96000325281143 0.96000325281143 0.96000325281143 0.96000325281143 0.96000325281143 0.96000325281143 0.96000325281143 0.96000325281143 0.96003298088296 0.96003298088296 0.96003298088296 0.96003298088296 0.96003298088296 0.96003298088296 0.96003298088296 0.96003298088296 0.96003298088296 0.96003298088296 0.96003298088296 0.96003298088296 0.96003298088296 0.96003298088296 0.96003298088296 0.96003298088296 0.96003298088296 0.96003298088296 0.96003298088296 0.96003298088296 0.96003298088296 0.96003298088296 0.96003298088296 0.96003298088296 0.96003298088296 0.96021653301433 0.96021653301433 0.96021653301433 0.96021653301433 0.96021653301433 0.96021653301433 0.96021653301433 0.96021653301433 0.96021653301433 0.96021653301433 0.96021653301433 0.96021653301433 0.96021653301433 0.96021653301433 0.96021653301433 0.96021653301433 0.96021653301433 0.96021653301433 0.96021653301433 0.96021653301433 0.96021653301433 0.96021653301433 0.96021653301433 0.96021653301433 0.96021653301433 0.9609147657699 0.9609147657699 0.9609147657699 0.9609147657699 0.9609147657699 0.9609147657699 0.9609147657699 0.9609147657699 0.9609147657699 0.9609147657699 0.9609147657699 0.9609147657699 0.9609147657699 0.9609147657699 0.9609147657699 0.9609147657699 0.9609147657699 0.9609147657699 0.9609147657699 0.9609147657699 0.9609147657699 0.9609147657699 0.9609147657699 0.9609147657699 0.9609147657699 0.96249799243187 0.96249799243187 0.96249799243187 0.96249799243187 0.96249799243187 0.96249799243187 0.96249799243187 0.96249799243187 0.96249799243187 0.96249799243187 0.96249799243187 0.96249799243187 0.96249799243187 0.96249799243187 0.96249799243187 0.96249799243187 0.96249799243187 0.96249799243187 0.96249799243187 0.96249799243187 0.96249799243187 0.96249799243187 0.96249799243187 0.96249799243187 0.96249799243187 0.964334322046 0.964334322046 0.964334322046 0.964334322046 0.964334322046 0.964334322046 0.964334322046 0.964334322046 0.964334322046 0.964334322046 0.964334322046 0.964334322046 0.964334322046 0.964334322046 0.964334322046 0.964334322046 0.964334322046 0.964334322046 0.964334322046 0.964334322046 0.964334322046 0.964334322046 0.964334322046 0.964334322046 0.964334322046 0.96481258179925 0.96481258179925 0.96481258179925 0.96481258179925 0.96481258179925 0.96481258179925 0.96481258179925 0.96481258179925 0.96481258179925 0.96481258179925 0.96481258179925 0.96481258179925 0.96481258179925 0.96481258179925 0.96481258179925 0.96481258179925 0.96481258179925 0.96481258179925 0.96481258179925 0.96481258179925 0.96481258179925 0.96481258179925 0.96481258179925 0.96481258179925 0.96481258179925 0.96336759080543 0.96336759080543 0.96336759080543 0.96336759080543 0.96336759080543 0.96336759080543 0.96336759080543 0.96336759080543 0.96336759080543 0.96336759080543 0.96336759080543 0.96336759080543 0.96336759080543 0.96336759080543 0.96336759080543 0.96336759080543 0.96336759080543 0.96336759080543 0.96336759080543 0.96336759080543 0.96336759080543 0.96336759080543 0.96336759080543 0.96336759080543 0.96336759080543 0.96143584361298 0.96143584361298 0.96143584361298 0.96143584361298 0.96143584361298 0.96143584361298 0.96143584361298 0.96143584361298 0.96143584361298 0.96143584361298 0.96143584361298 0.96143584361298 0.96143584361298 0.96143584361298 0.96143584361298 0.96143584361298 0.96143584361298 0.96143584361298 0.96143584361298 0.96143584361298 0.96143584361298 0.96143584361298 0.96143584361298 0.96143584361298 0.96143584361298 0.96040089864196 0.96040089864196 0.96040089864196 0.96040089864196 0.96040089864196 0.96040089864196 0.96040089864196 0.96040089864196 0.96040089864196 0.96040089864196 0.96040089864196 0.96040089864196 0.96040089864196 0.96040089864196 0.96040089864196 0.96040089864196 0.96040089864196 0.96040089864196 0.96040089864196 0.96040089864196 0.96040089864196 0.96040089864196 0.96040089864196 0.96040089864196 0.96040089864196 0.96000697925381 0.96000697925381 0.96000697925381 0.96000697925381 0.96000697925381 0.96000697925381 0.96000697925381 0.96000697925381 0.96000697925381 0.96000697925381 0.96000697925381 0.96000697925381 0.96000697925381 0.96000697925381 0.96000697925381 0.96000697925381 0.96000697925381 0.96000697925381 0.96000697925381 0.96000697925381 0.96000697925381 0.96000697925381 0.96000697925381 0.96000697925381 0.96000697925381 0.96000011362105 0.96000011362105 0.96000011362105 0.96000011362105 0.96000011362105 0.96000011362105 0.96000011362105 0.96000011362105 0.96000011362105 0.96000011362105 0.96000011362105 0.96000011362105 0.96000011362105 0.96000011362105 0.96000011362105 0.96000011362105 0.96000011362105 0.96000011362105 0.96000011362105 0.96000011362105 0.96000011362105 0.96000011362105 0.96000011362105 0.96000011362105 0.96000011362105 0.9600000014265 0.9600000014265 0.9600000014265 0.9600000014265 0.9600000014265 0.9600000014265 0.9600000014265 0.9600000014265 0.9600000014265 0.9600000014265 0.9600000014265 0.9600000014265 0.9600000014265 0.9600000014265 0.9600000014265 0.9600000014265 0.9600000014265 0.9600000014265 0.9600000014265 0.9600000014265 0.9600000014265 0.9600000014265 0.9600000014265 0.9600000014265 0.9600000014265 0.96000000001533 0.96000000001533 0.96000000001533 0.96000000001533 0.96000000001533 0.96000000001533 0.96000000001533 0.96000000001533 0.96000000001533 0.96000000001533 0.96000000001533 0.96000000001533 0.96000000001533 0.96000000001533 0.96000000001533 0.96000000001533 0.96000000001533 0.96000000001533 0.96000000001533 0.96000000001533 0.96000000001533 0.96000000001533 0.96000000001533 0.96000000001533 0.96000000001533 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.96000000000005 0.96000000000005 0.96000000000005 0.96000000000005 0.96000000000005 0.96000000000005 0.96000000000005 0.96000000000005 0.96000000000005 0.96000000000005 0.96000000000005 0.96000000000005 0.96000000000005 0.96000000000005 0.96000000000005 0.96000000000005 0.96000000000005 0.96000000000005 0.96000000000005 0.96000000000005 0.96000000000005 0.96000000000005 0.96000000000005 0.96000000000005 0.96000000000005 0.96000000000918 0.96000000000918 0.96000000000918 0.96000000000918 0.96000000000918 0.96000000000918 0.96000000000918 0.96000000000918 0.96000000000918 0.96000000000918 0.96000000000918 0.96000000000918 0.96000000000918 0.96000000000918 0.96000000000918 0.96000000000918 0.96000000000918 0.96000000000918 0.96000000000918 0.96000000000918 0.96000000000918 0.96000000000918 0.96000000000918 0.96000000000918 0.96000000000918 0.96000000079179 0.96000000079179 0.96000000079179 0.96000000079179 0.96000000079179 0.96000000079179 0.96000000079179 0.96000000079179 0.96000000079179 0.96000000079179 0.96000000079179 0.96000000079179 0.96000000079179 0.96000000079179 0.96000000079179 0.96000000079179 0.96000000079179 0.96000000079179 0.96000000079179 0.96000000079179 0.96000000079179 0.96000000079179 0.96000000079179 0.96000000079179 0.96000000079179 0.96000003419278 0.96000003419278 0.96000003419278 0.96000003419278 0.96000003419278 0.96000003419278 0.96000003419278 0.96000003419278 0.96000003419278 0.96000003419278 0.96000003419278 0.96000003419278 0.96000003419278 0.96000003419278 0.96000003419278 0.96000003419278 0.96000003419278 0.96000003419278 0.96000003419278 0.96000003419278 0.96000003419278 0.96000003419278 0.96000003419278 0.96000003419278 0.96000003419278 0.9600149885594 0.9600149885594 0.9600149885594 0.9600149885594 0.9600149885594 0.9600149885594 0.9600149885594 0.9600149885594 0.9600149885594 0.9600149885594 0.9600149885594 0.9600149885594 0.9600149885594 0.9600149885594 0.9600149885594 0.9600149885594 0.9600149885594 0.9600149885594 0.9600149885594 0.9600149885594 0.9600149885594 0.9600149885594 0.9600149885594 0.9600149885594 0.9600149885594 0.96011618398765 0.96011618398765 0.96011618398765 0.96011618398765 0.96011618398765 0.96011618398765 0.96011618398765 0.96011618398765 0.96011618398765 0.96011618398765 0.96011618398765 0.96011618398765 0.96011618398765 0.96011618398765 0.96011618398765 0.96011618398765 0.96011618398765 0.96011618398765 0.96011618398765 0.96011618398765 0.96011618398765 0.96011618398765 0.96011618398765 0.96011618398765 0.96011618398765 0.96057389899636 0.96057389899636 0.96057389899636 0.96057389899636 0.96057389899636 0.96057389899636 0.96057389899636 0.96057389899636 0.96057389899636 0.96057389899636 0.96057389899636 0.96057389899636 0.96057389899636 0.96057389899636 0.96057389899636 0.96057389899636 0.96057389899636 0.96057389899636 0.96057389899636 0.96057389899636 0.96057389899636 0.96057389899636 0.96057389899636 0.96057389899636 0.96057389899636 0.96183629361123 0.96183629361123 0.96183629361123 0.96183629361123 0.96183629361123 0.96183629361123 0.96183629361123 0.96183629361123 0.96183629361123 0.96183629361123 0.96183629361123 0.96183629361123 0.96183629361123 0.96183629361123 0.96183629361123 0.96183629361123 0.96183629361123 0.96183629361123 0.96183629361123 0.96183629361123 0.96183629361123 0.96183629361123 0.96183629361123 0.96183629361123 0.96183629361123 0.96374953553679 0.96374953553679 0.96374953553679 0.96374953553679 0.96374953553679 0.96374953553679 0.96374953553679 0.96374953553679 0.96374953553679 0.96374953553679 0.96374953553679 0.96374953553679 0.96374953553679 0.96374953553679 0.96374953553679 0.96374953553679 0.96374953553679 0.96374953553679 0.96374953553679 0.96374953553679 0.96374953553679 0.96374953553679 0.96374953553679 0.96374953553679 0.96374953553679 0.96487828647848 0.96487828647848 0.96487828647848 0.96487828647848 0.96487828647848 0.96487828647848 0.96487828647848 0.96487828647848 0.96487828647848 0.96487828647848 0.96487828647848 0.96487828647848 0.96487828647848 0.96487828647848 0.96487828647848 0.96487828647848 0.96487828647848 0.96487828647848 0.96487828647848 0.96487828647848 0.96487828647848 0.96487828647848 0.96487828647848 0.96487828647848 0.96487828647848 0.96403753353408 0.96403753353408 0.96403753353408 0.96403753353408 0.96403753353408 0.96403753353408 0.96403753353408 0.96403753353408 0.96403753353408 0.96403753353408 0.96403753353408 0.96403753353408 0.96403753353408 0.96403753353408 0.96403753353408 0.96403753353408 0.96403753353408 0.96403753353408 0.96403753353408 0.96403753353408 0.96403753353408 0.96403753353408 0.96403753353408 0.96403753353408 0.96403753353408 0.96213071462991 0.96213071462991 0.96213071462991 0.96213071462991 0.96213071462991 0.96213071462991 0.96213071462991 0.96213071462991 0.96213071462991 0.96213071462991 0.96213071462991 0.96213071462991 0.96213071462991 0.96213071462991 0.96213071462991 0.96213071462991 0.96213071462991 0.96213071462991 0.96213071462991 0.96213071462991 0.96213071462991 0.96213071462991 0.96213071462991 0.96213071462991 0.96213071462991 0.96071011797522 0.96071011797522 0.96071011797522 0.96071011797522 0.96071011797522 0.96071011797522 0.96071011797522 0.96071011797522 0.96071011797522 0.96071011797522 0.96071011797522 0.96071011797522 0.96071011797522 0.96071011797522 0.96071011797522 0.96071011797522 0.96071011797522 0.96071011797522 0.96071011797522 0.96071011797522 0.96071011797522 0.96071011797522 0.96071011797522 0.96071011797522 0.96071011797522 0.9601508434791 0.9601508434791 0.9601508434791 0.9601508434791 0.9601508434791 0.9601508434791 0.9601508434791 0.9601508434791 0.9601508434791 0.9601508434791 0.9601508434791 0.9601508434791 0.9601508434791 0.9601508434791 0.9601508434791 0.9601508434791 0.9601508434791 0.9601508434791 0.9601508434791 0.9601508434791 0.9601508434791 0.9601508434791 0.9601508434791 0.9601508434791 0.9601508434791 0.9600196248461 0.9600196248461 0.9600196248461 0.9600196248461 0.9600196248461 0.9600196248461 0.9600196248461 0.9600196248461 0.9600196248461 0.9600196248461 0.9600196248461 0.9600196248461 0.9600196248461 0.9600196248461 0.9600196248461 0.9600196248461 0.9600196248461 0.9600196248461 0.9600196248461 0.9600196248461 0.9600196248461 0.9600196248461 0.9600196248461 0.9600196248461 0.9600196248461 0.96000036744425 0.96000036744425 0.96000036744425 0.96000036744425 0.96000036744425 0.96000036744425 0.96000036744425 0.96000036744425 0.96000036744425 0.96000036744425 0.96000036744425 0.96000036744425 0.96000036744425 0.96000036744425 0.96000036744425 0.96000036744425 0.96000036744425 0.96000036744425 0.96000036744425 0.96000036744425 0.96000036744425 0.96000036744425 0.96000036744425 0.96000036744425 0.96000036744425 0.96000000570381 0.96000000570381 0.96000000570381 0.96000000570381 0.96000000570381 0.96000000570381 0.96000000570381 0.96000000570381 0.96000000570381 0.96000000570381 0.96000000570381 0.96000000570381 0.96000000570381 0.96000000570381 0.96000000570381 0.96000000570381 0.96000000570381 0.96000000570381 0.96000000570381 0.96000000570381 0.96000000570381 0.96000000570381 0.96000000570381 0.96000000570381 0.96000000570381 0.96000000007383 0.96000000007383 0.96000000007383 0.96000000007383 0.96000000007383 0.96000000007383 0.96000000007383 0.96000000007383 0.96000000007383 0.96000000007383 0.96000000007383 0.96000000007383 0.96000000007383 0.96000000007383 0.96000000007383 0.96000000007383 0.96000000007383 0.96000000007383 0.96000000007383 0.96000000007383 0.96000000007383 0.96000000007383 0.96000000007383 0.96000000007383 0.96000000007383 0.96000000000109 0.96000000000109 0.96000000000109 0.96000000000109 0.96000000000109 0.96000000000109 0.96000000000109 0.96000000000109 0.96000000000109 0.96000000000109 0.96000000000109 0.96000000000109 0.96000000000109 0.96000000000109 0.96000000000109 0.96000000000109 0.96000000000109 0.96000000000109 0.96000000000109 0.96000000000109 0.96000000000109 0.96000000000109 0.96000000000109 0.96000000000109 0.96000000000109 0.95999999999988 0.95999999999988 0.95999999999988 0.95999999999988 0.95999999999988 0.95999999999988 0.95999999999988 0.95999999999988 0.95999999999988 0.95999999999988 0.95999999999988 0.95999999999988 0.95999999999988 0.95999999999988 0.95999999999988 0.95999999999988 0.95999999999988 0.95999999999988 0.95999999999988 0.95999999999988 0.95999999999988 0.95999999999988 0.95999999999988 0.95999999999988 0.95999999999988 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.96000000000232 0.96000000000232 0.96000000000232 0.96000000000232 0.96000000000232 0.96000000000232 0.96000000000232 0.96000000000232 0.96000000000232 0.96000000000232 0.96000000000232 0.96000000000232 0.96000000000232 0.96000000000232 0.96000000000232 0.96000000000232 0.96000000000232 0.96000000000232 0.96000000000232 0.96000000000232 0.96000000000232 0.96000000000232 0.96000000000232 0.96000000000232 0.96000000000232 0.96000000018275 0.96000000018275 0.96000000018275 0.96000000018275 0.96000000018275 0.96000000018275 0.96000000018275 0.96000000018275 0.96000000018275 0.96000000018275 0.96000000018275 0.96000000018275 0.96000000018275 0.96000000018275 0.96000000018275 0.96000000018275 0.96000000018275 0.96000000018275 0.96000000018275 0.96000000018275 0.96000000018275 0.96000000018275 0.96000000018275 0.96000000018275 0.96000000018275 0.96000001363188 0.96000001363188 0.96000001363188 0.96000001363188 0.96000001363188 0.96000001363188 0.96000001363188 0.96000001363188 0.96000001363188 0.96000001363188 0.96000001363188 0.96000001363188 0.96000001363188 0.96000001363188 0.96000001363188 0.96000001363188 0.96000001363188 0.96000001363188 0.96000001363188 0.96000001363188 0.96000001363188 0.96000001363188 0.96000001363188 0.96000001363188 0.96000001363188 0.96000111210589 0.96000111210589 0.96000111210589 0.96000111210589 0.96000111210589 0.96000111210589 0.96000111210589 0.96000111210589 0.96000111210589 0.96000111210589 0.96000111210589 0.96000111210589 0.96000111210589 0.96000111210589 0.96000111210589 0.96000111210589 0.96000111210589 0.96000111210589 0.96000111210589 0.96000111210589 0.96000111210589 0.96000111210589 0.96000111210589 0.96000111210589 0.96000111210589 0.96033224617124 0.96033224617124 0.96033224617124 0.96033224617124 0.96033224617124 0.96033224617124 0.96033224617124 0.96033224617124 0.96033224617124 0.96033224617124 0.96033224617124 0.96033224617124 0.96033224617124 0.96033224617124 0.96033224617124 0.96033224617124 0.96033224617124 0.96033224617124 0.96033224617124 0.96033224617124 0.96033224617124 0.96033224617124 0.96033224617124 0.96033224617124 0.96033224617124 0.96126932110788 0.96126932110788 0.96126932110788 0.96126932110788 0.96126932110788 0.96126932110788 0.96126932110788 0.96126932110788 0.96126932110788 0.96126932110788 0.96126932110788 0.96126932110788 0.96126932110788 0.96126932110788 0.96126932110788 0.96126932110788 0.96126932110788 0.96126932110788 0.96126932110788 0.96126932110788 0.96126932110788 0.96126932110788 0.96126932110788 0.96126932110788 0.96126932110788 0.96305949909787 0.96305949909787 0.96305949909787 0.96305949909787 0.96305949909787 0.96305949909787 0.96305949909787 0.96305949909787 0.96305949909787 0.96305949909787 0.96305949909787 0.96305949909787 0.96305949909787 0.96305949909787 0.96305949909787 0.96305949909787 0.96305949909787 0.96305949909787 0.96305949909787 0.96305949909787 0.96305949909787 0.96305949909787 0.96305949909787 0.96305949909787 0.96305949909787 0.96466883490351 0.96466883490351 0.96466883490351 0.96466883490351 0.96466883490351 0.96466883490351 0.96466883490351 0.96466883490351 0.96466883490351 0.96466883490351 0.96466883490351 0.96466883490351 0.96466883490351 0.96466883490351 0.96466883490351 0.96466883490351 0.96466883490351 0.96466883490351 0.96466883490351 0.96466883490351 0.96466883490351 0.96466883490351 0.96466883490351 0.96466883490351 0.96466883490351 0.96456048864478 0.96456048864478 0.96456048864478 0.96456048864478 0.96456048864478 0.96456048864478 0.96456048864478 0.96456048864478 0.96456048864478 0.96456048864478 0.96456048864478 0.96456048864478 0.96456048864478 0.96456048864478 0.96456048864478 0.96456048864478 0.96456048864478 0.96456048864478 0.96456048864478 0.96456048864478 0.96456048864478 0.96456048864478 0.96456048864478 0.96456048864478 0.96456048864478 0.96281609353146 0.96281609353146 0.96281609353146 0.96281609353146 0.96281609353146 0.96281609353146 0.96281609353146 0.96281609353146 0.96281609353146 0.96281609353146 0.96281609353146 0.96281609353146 0.96281609353146 0.96281609353146 0.96281609353146 0.96281609353146 0.96281609353146 0.96281609353146 0.96281609353146 0.96281609353146 0.96281609353146 0.96281609353146 0.96281609353146 0.96281609353146 0.96281609353146 0.96111125786873 0.96111125786873 0.96111125786873 0.96111125786873 0.96111125786873 0.96111125786873 0.96111125786873 0.96111125786873 0.96111125786873 0.96111125786873 0.96111125786873 0.96111125786873 0.96111125786873 0.96111125786873 0.96111125786873 0.96111125786873 0.96111125786873 0.96111125786873 0.96111125786873 0.96111125786873 0.96111125786873 0.96111125786873 0.96111125786873 0.96111125786873 0.96111125786873 0.96027471074325 0.96027471074325 0.96027471074325 0.96027471074325 0.96027471074325 0.96027471074325 0.96027471074325 0.96027471074325 0.96027471074325 0.96027471074325 0.96027471074325 0.96027471074325 0.96027471074325 0.96027471074325 0.96027471074325 0.96027471074325 0.96027471074325 0.96027471074325 0.96027471074325 0.96027471074325 0.96027471074325 0.96027471074325 0.96027471074325 0.96027471074325 0.96027471074325 0.96004459277341 0.96004459277341 0.96004459277341 0.96004459277341 0.96004459277341 0.96004459277341 0.96004459277341 0.96004459277341 0.96004459277341 0.96004459277341 0.96004459277341 0.96004459277341 0.96004459277341 0.96004459277341 0.96004459277341 0.96004459277341 0.96004459277341 0.96004459277341 0.96004459277341 0.96004459277341 0.96004459277341 0.96004459277341 0.96004459277341 0.96004459277341 0.96004459277341 0.96000499233933 0.96000499233933 0.96000499233933 0.96000499233933 0.96000499233933 0.96000499233933 0.96000499233933 0.96000499233933 0.96000499233933 0.96000499233933 0.96000499233933 0.96000499233933 0.96000499233933 0.96000499233933 0.96000499233933 0.96000499233933 0.96000499233933 0.96000499233933 0.96000499233933 0.96000499233933 0.96000499233933 0.96000499233933 0.96000499233933 0.96000499233933 0.96000499233933 0.96000031117462 0.96000031117462 0.96000031117462 0.96000031117462 0.96000031117462 0.96000031117462 0.96000031117462 0.96000031117462 0.96000031117462 0.96000031117462 0.96000031117462 0.96000031117462 0.96000031117462 0.96000031117462 0.96000031117462 0.96000031117462 0.96000031117462 0.96000031117462 0.96000031117462 0.96000031117462 0.96000031117462 0.96000031117462 0.96000031117462 0.96000031117462 0.96000031117462 0.96000001433426 0.96000001433426 0.96000001433426 0.96000001433426 0.96000001433426 0.96000001433426 0.96000001433426 0.96000001433426 0.96000001433426 0.96000001433426 0.96000001433426 0.96000001433426 0.96000001433426 0.96000001433426 0.96000001433426 0.96000001433426 0.96000001433426 0.96000001433426 0.96000001433426 0.96000001433426 0.96000001433426 0.96000001433426 0.96000001433426 0.96000001433426 0.96000001433426 0.96000000025446 0.96000000025446 0.96000000025446 0.96000000025446 0.96000000025446 0.96000000025446 0.96000000025446 0.96000000025446 0.96000000025446 0.96000000025446 0.96000000025446 0.96000000025446 0.96000000025446 0.96000000025446 0.96000000025446 0.96000000025446 0.96000000025446 0.96000000025446 0.96000000025446 0.96000000025446 0.96000000025446 0.96000000025446 0.96000000025446 0.96000000025446 0.96000000025446 0.96000000000415 0.96000000000415 0.96000000000415 0.96000000000415 0.96000000000415 0.96000000000415 0.96000000000415 0.96000000000415 0.96000000000415 0.96000000000415 0.96000000000415 0.96000000000415 0.96000000000415 0.96000000000415 0.96000000000415 0.96000000000415 0.96000000000415 0.96000000000415 0.96000000000415 0.96000000000415 0.96000000000415 0.96000000000415 0.96000000000415 0.96000000000415 0.96000000000415 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.9600000000212 0.9600000000212 0.9600000000212 0.9600000000212 0.9600000000212 0.9600000000212 0.9600000000212 0.9600000000212 0.9600000000212 0.9600000000212 0.9600000000212 0.9600000000212 0.9600000000212 0.9600000000212 0.9600000000212 0.9600000000212 0.9600000000212 0.9600000000212 0.9600000000212 0.9600000000212 0.9600000000212 0.9600000000212 0.9600000000212 0.9600000000212 0.9600000000212 0.960000001965 0.960000001965 0.960000001965 0.960000001965 0.960000001965 0.960000001965 0.960000001965 0.960000001965 0.960000001965 0.960000001965 0.960000001965 0.960000001965 0.960000001965 0.960000001965 0.960000001965 0.960000001965 0.960000001965 0.960000001965 0.960000001965 0.960000001965 0.960000001965 0.960000001965 0.960000001965 0.960000001965 0.960000001965 0.96000015611273 0.96000015611273 0.96000015611273 0.96000015611273 0.96000015611273 0.96000015611273 0.96000015611273 0.96000015611273 0.96000015611273 0.96000015611273 0.96000015611273 0.96000015611273 0.96000015611273 0.96000015611273 0.96000015611273 0.96000015611273 0.96000015611273 0.96000015611273 0.96000015611273 0.96000015611273 0.96000015611273 0.96000015611273 0.96000015611273 0.96000015611273 0.96000015611273 0.96001764480948 0.96001764480948 0.96001764480948 0.96001764480948 0.96001764480948 0.96001764480948 0.96001764480948 0.96001764480948 0.96001764480948 0.96001764480948 0.96001764480948 0.96001764480948 0.96001764480948 0.96001764480948 0.96001764480948 0.96001764480948 0.96001764480948 0.96001764480948 0.96001764480948 0.96001764480948 0.96001764480948 0.96001764480948 0.96001764480948 0.96001764480948 0.96001764480948 0.96006279164586 0.96006279164586 0.96006279164586 0.96006279164586 0.96006279164586 0.96006279164586 0.96006279164586 0.96006279164586 0.96006279164586 0.96006279164586 0.96006279164586 0.96006279164586 0.96006279164586 0.96006279164586 0.96006279164586 0.96006279164586 0.96006279164586 0.96006279164586 0.96006279164586 0.96006279164586 0.96006279164586 0.96006279164586 0.96006279164586 0.96006279164586 0.96006279164586 0.96400989035802 0.96400989035802 0.96400989035802 0.96400989035802 0.96400989035802 0.96400989035802 0.96400989035802 0.96400989035802 0.96400989035802 0.96400989035802 0.96400989035802 0.96400989035802 0.96400989035802 0.96400989035802 0.96400989035802 0.96400989035802 0.96400989035802 0.96400989035802 0.96400989035802 0.96400989035802 0.96400989035802 0.96400989035802 0.96400989035802 0.96400989035802 0.96400989035802 0.96485606976477 0.96485606976477 0.96485606976477 0.96485606976477 0.96485606976477 0.96485606976477 0.96485606976477 0.96485606976477 0.96485606976477 0.96485606976477 0.96485606976477 0.96485606976477 0.96485606976477 0.96485606976477 0.96485606976477 0.96485606976477 0.96485606976477 0.96485606976477 0.96485606976477 0.96485606976477 0.96485606976477 0.96485606976477 0.96485606976477 0.96485606976477 0.96485606976477 0.96351313793838 0.96351313793838 0.96351313793838 0.96351313793838 0.96351313793838 0.96351313793838 0.96351313793838 0.96351313793838 0.96351313793838 0.96351313793838 0.96351313793838 0.96351313793838 0.96351313793838 0.96351313793838 0.96351313793838 0.96351313793838 0.96351313793838 0.96351313793838 0.96351313793838 0.96351313793838 0.96351313793838 0.96351313793838 0.96351313793838 0.96351313793838 0.96351313793838 0.96163554558384 0.96163554558384 0.96163554558384 0.96163554558384 0.96163554558384 0.96163554558384 0.96163554558384 0.96163554558384 0.96163554558384 0.96163554558384 0.96163554558384 0.96163554558384 0.96163554558384 0.96163554558384 0.96163554558384 0.96163554558384 0.96163554558384 0.96163554558384 0.96163554558384 0.96163554558384 0.96163554558384 0.96163554558384 0.96163554558384 0.96163554558384 0.96163554558384 0.96047642292959 0.96047642292959 0.96047642292959 0.96047642292959 0.96047642292959 0.96047642292959 0.96047642292959 0.96047642292959 0.96047642292959 0.96047642292959 0.96047642292959 0.96047642292959 0.96047642292959 0.96047642292959 0.96047642292959 0.96047642292959 0.96047642292959 0.96047642292959 0.96047642292959 0.96047642292959 0.96047642292959 0.96047642292959 0.96047642292959 0.96047642292959 0.96047642292959 0.9600895136462 0.9600895136462 0.9600895136462 0.9600895136462 0.9600895136462 0.9600895136462 0.9600895136462 0.9600895136462 0.9600895136462 0.9600895136462 0.9600895136462 0.9600895136462 0.9600895136462 0.9600895136462 0.9600895136462 0.9600895136462 0.9600895136462 0.9600895136462 0.9600895136462 0.9600895136462 0.9600895136462 0.9600895136462 0.9600895136462 0.9600895136462 0.9600895136462 0.96001112432289 0.96001112432289 0.96001112432289 0.96001112432289 0.96001112432289 0.96001112432289 0.96001112432289 0.96001112432289 0.96001112432289 0.96001112432289 0.96001112432289 0.96001112432289 0.96001112432289 0.96001112432289 0.96001112432289 0.96001112432289 0.96001112432289 0.96001112432289 0.96001112432289 0.96001112432289 0.96001112432289 0.96001112432289 0.96001112432289 0.96001112432289 0.96001112432289 0.96000091493657 0.96000091493657 0.96000091493657 0.96000091493657 0.96000091493657 0.96000091493657 0.96000091493657 0.96000091493657 0.96000091493657 0.96000091493657 0.96000091493657 0.96000091493657 0.96000091493657 0.96000091493657 0.96000091493657 0.96000091493657 0.96000091493657 0.96000091493657 0.96000091493657 0.96000091493657 0.96000091493657 0.96000091493657 0.96000091493657 0.96000091493657 0.96000091493657 0.96000005380412 0.96000005380412 0.96000005380412 0.96000005380412 0.96000005380412 0.96000005380412 0.96000005380412 0.96000005380412 0.96000005380412 0.96000005380412 0.96000005380412 0.96000005380412 0.96000005380412 0.96000005380412 0.96000005380412 0.96000005380412 0.96000005380412 0.96000005380412 0.96000005380412 0.96000005380412 0.96000005380412 0.96000005380412 0.96000005380412 0.96000005380412 0.96000005380412 0.96000000216497 0.96000000216497 0.96000000216497 0.96000000216497 0.96000000216497 0.96000000216497 0.96000000216497 0.96000000216497 0.96000000216497 0.96000000216497 0.96000000216497 0.96000000216497 0.96000000216497 0.96000000216497 0.96000000216497 0.96000000216497 0.96000000216497 0.96000000216497 0.96000000216497 0.96000000216497 0.96000000216497 0.96000000216497 0.96000000216497 0.96000000216497 0.96000000216497 0.96000000005184 0.96000000005184 0.96000000005184 0.96000000005184 0.96000000005184 0.96000000005184 0.96000000005184 0.96000000005184 0.96000000005184 0.96000000005184 0.96000000005184 0.96000000005184 0.96000000005184 0.96000000005184 0.96000000005184 0.96000000005184 0.96000000005184 0.96000000005184 0.96000000005184 0.96000000005184 0.96000000005184 0.96000000005184 0.96000000005184 0.96000000005184 0.96000000005184 0.96000000000113 0.96000000000113 0.96000000000113 0.96000000000113 0.96000000000113 0.96000000000113 0.96000000000113 0.96000000000113 0.96000000000113 0.96000000000113 0.96000000000113 0.96000000000113 0.96000000000113 0.96000000000113 0.96000000000113 0.96000000000113 0.96000000000113 0.96000000000113 0.96000000000113 0.96000000000113 0.96000000000113 0.96000000000113 0.96000000000113 0.96000000000113 0.96000000000113 0.95999999999986 0.95999999999986 0.95999999999986 0.95999999999986 0.95999999999986 0.95999999999986 0.95999999999986 0.95999999999986 0.95999999999986 0.95999999999986 0.95999999999986 0.95999999999986 0.95999999999986 0.95999999999986 0.95999999999986 0.95999999999986 0.95999999999986 0.95999999999986 0.95999999999986 0.95999999999986 0.95999999999986 0.95999999999986 0.95999999999986 0.95999999999986 0.95999999999986 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.95999999999994 0.95999999999994 0.95999999999994 0.95999999999994 0.95999999999994 0.95999999999994 0.95999999999994 0.95999999999994 0.95999999999994 0.95999999999994 0.95999999999994 0.95999999999994 0.95999999999994 0.95999999999994 0.95999999999994 0.95999999999994 0.95999999999994 0.95999999999994 0.95999999999994 0.95999999999994 0.95999999999994 0.95999999999994 0.95999999999994 0.95999999999994 0.95999999999994 0.96000000000048 0.96000000000048 0.96000000000048 0.96000000000048 0.96000000000048 0.96000000000048 0.96000000000048 0.96000000000048 0.96000000000048 0.96000000000048 0.96000000000048 0.96000000000048 0.96000000000048 0.96000000000048 0.96000000000048 0.96000000000048 0.96000000000048 0.96000000000048 0.96000000000048 0.96000000000048 0.96000000000048 0.96000000000048 0.96000000000048 0.96000000000048 0.96000000000048 0.96000000004002 0.96000000004002 0.96000000004002 0.96000000004002 0.96000000004002 0.96000000004002 0.96000000004002 0.96000000004002 0.96000000004002 0.96000000004002 0.96000000004002 0.96000000004002 0.96000000004002 0.96000000004002 0.96000000004002 0.96000000004002 0.96000000004002 0.96000000004002 0.96000000004002 0.96000000004002 0.96000000004002 0.96000000004002 0.96000000004002 0.96000000004002 0.96000000004002 0.96000000333307 0.96000000333307 0.96000000333307 0.96000000333307 0.96000000333307 0.96000000333307 0.96000000333307 0.96000000333307 0.96000000333307 0.96000000333307 0.96000000333307 0.96000000333307 0.96000000333307 0.96000000333307 0.96000000333307 0.96000000333307 0.96000000333307 0.96000000333307 0.96000000333307 0.96000000333307 0.96000000333307 0.96000000333307 0.96000000333307 0.96000000333307 0.96000000333307 0.96000032143279 0.96000032143279 0.96000032143279 0.96000032143279 0.96000032143279 0.96000032143279 0.96000032143279 0.96000032143279 0.96000032143279 0.96000032143279 0.96000032143279 0.96000032143279 0.96000032143279 0.96000032143279 0.96000032143279 0.96000032143279 0.96000032143279 0.96000032143279 0.96000032143279 0.96000032143279 0.96000032143279 0.96000032143279 0.96000032143279 0.96000032143279 0.96000032143279 0.96000308149917 0.96000308149917 0.96000308149917 0.96000308149917 0.96000308149917 0.96000308149917 0.96000308149917 0.96000308149917 0.96000308149917 0.96000308149917 0.96000308149917 0.96000308149917 0.96000308149917 0.96000308149917 0.96000308149917 0.96000308149917 0.96000308149917 0.96000308149917 0.96000308149917 0.96000308149917 0.96000308149917 0.96000308149917 0.96000308149917 0.96000308149917 0.96000308149917 0.96017194993358 0.96017194993358 0.96017194993358 0.96017194993358 0.96017194993358 0.96017194993358 0.96017194993358 0.96017194993358 0.96017194993358 0.96017194993358 0.96017194993358 0.96017194993358 0.96017194993358 0.96017194993358 0.96017194993358 0.96017194993358 0.96017194993358 0.96017194993358 0.96017194993358 0.96017194993358 0.96017194993358 0.96017194993358 0.96017194993358 0.96017194993358 0.96017194993358 0.96391155244328 0.96391155244328 0.96391155244328 0.96391155244328 0.96391155244328 0.96391155244328 0.96391155244328 0.96391155244328 0.96391155244328 0.96391155244328 0.96391155244328 0.96391155244328 0.96391155244328 0.96391155244328 0.96391155244328 0.96391155244328 0.96391155244328 0.96391155244328 0.96391155244328 0.96391155244328 0.96391155244328 0.96391155244328 0.96391155244328 0.96391155244328 0.96391155244328 0.96224311853402 0.96224311853402 0.96224311853402 0.96224311853402 0.96224311853402 0.96224311853402 0.96224311853402 0.96224311853402 0.96224311853402 0.96224311853402 0.96224311853402 0.96224311853402 0.96224311853402 0.96224311853402 0.96224311853402 0.96224311853402 0.96224311853402 0.96224311853402 0.96224311853402 0.96224311853402 0.96224311853402 0.96224311853402 0.96224311853402 0.96224311853402 0.96224311853402 0.96078380667 0.96078380667 0.96078380667 0.96078380667 0.96078380667 0.96078380667 0.96078380667 0.96078380667 0.96078380667 0.96078380667 0.96078380667 0.96078380667 0.96078380667 0.96078380667 0.96078380667 0.96078380667 0.96078380667 0.96078380667 0.96078380667 0.96078380667 0.96078380667 0.96078380667 0.96078380667 0.96078380667 0.96078380667 0.9601705079647 0.9601705079647 0.9601705079647 0.9601705079647 0.9601705079647 0.9601705079647 0.9601705079647 0.9601705079647 0.9601705079647 0.9601705079647 0.9601705079647 0.9601705079647 0.9601705079647 0.9601705079647 0.9601705079647 0.9601705079647 0.9601705079647 0.9601705079647 0.9601705079647 0.9601705079647 0.9601705079647 0.9601705079647 0.9601705079647 0.9601705079647 0.9601705079647 0.96002464093767 0.96002464093767 0.96002464093767 0.96002464093767 0.96002464093767 0.96002464093767 0.96002464093767 0.96002464093767 0.96002464093767 0.96002464093767 0.96002464093767 0.96002464093767 0.96002464093767 0.96002464093767 0.96002464093767 0.96002464093767 0.96002464093767 0.96002464093767 0.96002464093767 0.96002464093767 0.96002464093767 0.96002464093767 0.96002464093767 0.96002464093767 0.96002464093767 0.96000234110585 0.96000234110585 0.96000234110585 0.96000234110585 0.96000234110585 0.96000234110585 0.96000234110585 0.96000234110585 0.96000234110585 0.96000234110585 0.96000234110585 0.96000234110585 0.96000234110585 0.96000234110585 0.96000234110585 0.96000234110585 0.96000234110585 0.96000234110585 0.96000234110585 0.96000234110585 0.96000234110585 0.96000234110585 0.96000234110585 0.96000234110585 0.96000234110585 0.96000014892106 0.96000014892106 0.96000014892106 0.96000014892106 0.96000014892106 0.96000014892106 0.96000014892106 0.96000014892106 0.96000014892106 0.96000014892106 0.96000014892106 0.96000014892106 0.96000014892106 0.96000014892106 0.96000014892106 0.96000014892106 0.96000014892106 0.96000014892106 0.96000014892106 0.96000014892106 0.96000014892106 0.96000014892106 0.96000014892106 0.96000014892106 0.96000014892106 0.9600000065405 0.9600000065405 0.9600000065405 0.9600000065405 0.9600000065405 0.9600000065405 0.9600000065405 0.9600000065405 0.9600000065405 0.9600000065405 0.9600000065405 0.9600000065405 0.9600000065405 0.9600000065405 0.9600000065405 0.9600000065405 0.9600000065405 0.9600000065405 0.9600000065405 0.9600000065405 0.9600000065405 0.9600000065405 0.9600000065405 0.9600000065405 0.9600000065405 0.96000000020369 0.96000000020369 0.96000000020369 0.96000000020369 0.96000000020369 0.96000000020369 0.96000000020369 0.96000000020369 0.96000000020369 0.96000000020369 0.96000000020369 0.96000000020369 0.96000000020369 0.96000000020369 0.96000000020369 0.96000000020369 0.96000000020369 0.96000000020369 0.96000000020369 0.96000000020369 0.96000000020369 0.96000000020369 0.96000000020369 0.96000000020369 0.96000000020369 0.96000000000543 0.96000000000543 0.96000000000543 0.96000000000543 0.96000000000543 0.96000000000543 0.96000000000543 0.96000000000543 0.96000000000543 0.96000000000543 0.96000000000543 0.96000000000543 0.96000000000543 0.96000000000543 0.96000000000543 0.96000000000543 0.96000000000543 0.96000000000543 0.96000000000543 0.96000000000543 0.96000000000543 0.96000000000543 0.96000000000543 0.96000000000543 0.96000000000543 0.95999999999992 0.95999999999992 0.95999999999992 0.95999999999992 0.95999999999992 0.95999999999992 0.95999999999992 0.95999999999992 0.95999999999992 0.95999999999992 0.95999999999992 0.95999999999992 0.95999999999992 0.95999999999992 0.95999999999992 0.95999999999992 0.95999999999992 0.95999999999992 0.95999999999992 0.95999999999992 0.95999999999992 0.95999999999992 0.95999999999992 0.95999999999992 0.95999999999992 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.9600000000006 0.9600000000006 0.9600000000006 0.9600000000006 0.9600000000006 0.9600000000006 0.9600000000006 0.9600000000006 0.9600000000006 0.9600000000006 0.9600000000006 0.9600000000006 0.9600000000006 0.9600000000006 0.9600000000006 0.9600000000006 0.9600000000006 0.9600000000006 0.9600000000006 0.9600000000006 0.9600000000006 0.9600000000006 0.9600000000006 0.9600000000006 0.9600000000006 0.96000000005181 0.96000000005181 0.96000000005181 0.96000000005181 0.96000000005181 0.96000000005181 0.96000000005181 0.96000000005181 0.96000000005181 0.96000000005181 0.96000000005181 0.96000000005181 0.96000000005181 0.96000000005181 0.96000000005181 0.96000000005181 0.96000000005181 0.96000000005181 0.96000000005181 0.96000000005181 0.96000000005181 0.96000000005181 0.96000000005181 0.96000000005181 0.96000000005181 0.96000000471331 0.96000000471331 0.96000000471331 0.96000000471331 0.96000000471331 0.96000000471331 0.96000000471331 0.96000000471331 0.96000000471331 0.96000000471331 0.96000000471331 0.96000000471331 0.96000000471331 0.96000000471331 0.96000000471331 0.96000000471331 0.96000000471331 0.96000000471331 0.96000000471331 0.96000000471331 0.96000000471331 0.96000000471331 0.96000000471331 0.96000000471331 0.96000000471331 0.96000009639196 0.96000009639196 0.96000009639196 0.96000009639196 0.96000009639196 0.96000009639196 0.96000009639196 0.96000009639196 0.96000009639196 0.96000009639196 0.96000009639196 0.96000009639196 0.96000009639196 0.96000009639196 0.96000009639196 0.96000009639196 0.96000009639196 0.96000009639196 0.96000009639196 0.96000009639196 0.96000009639196 0.96000009639196 0.96000009639196 0.96000009639196 0.96000009639196 0.96000622376079 0.96000622376079 0.96000622376079 0.96000622376079 0.96000622376079 0.96000622376079 0.96000622376079 0.96000622376079 0.96000622376079 0.96000622376079 0.96000622376079 0.96000622376079 0.96000622376079 0.96000622376079 0.96000622376079 0.96000622376079 0.96000622376079 0.96000622376079 0.96000622376079 0.96000622376079 0.96000622376079 0.96000622376079 0.96000622376079 0.96000622376079 0.96000622376079 0.96013879588321 0.96013879588321 0.96013879588321 0.96013879588321 0.96013879588321 0.96013879588321 0.96013879588321 0.96013879588321 0.96013879588321 0.96013879588321 0.96013879588321 0.96013879588321 0.96013879588321 0.96013879588321 0.96013879588321 0.96013879588321 0.96013879588321 0.96013879588321 0.96013879588321 0.96013879588321 0.96013879588321 0.96013879588321 0.96013879588321 0.96013879588321 0.96013879588321 0.96006476986403 0.96006476986403 0.96006476986403 0.96006476986403 0.96006476986403 0.96006476986403 0.96006476986403 0.96006476986403 0.96006476986403 0.96006476986403 0.96006476986403 0.96006476986403 0.96006476986403 0.96006476986403 0.96006476986403 0.96006476986403 0.96006476986403 0.96006476986403 0.96006476986403 0.96006476986403 0.96006476986403 0.96006476986403 0.96006476986403 0.96006476986403 0.96006476986403 0.96027520928189 0.96027520928189 0.96027520928189 0.96027520928189 0.96027520928189 0.96027520928189 0.96027520928189 0.96027520928189 0.96027520928189 0.96027520928189 0.96027520928189 0.96027520928189 0.96027520928189 0.96027520928189 0.96027520928189 0.96027520928189 0.96027520928189 0.96027520928189 0.96027520928189 0.96027520928189 0.96027520928189 0.96027520928189 0.96027520928189 0.96027520928189 0.96027520928189 0.96005494775729 0.96005494775729 0.96005494775729 0.96005494775729 0.96005494775729 0.96005494775729 0.96005494775729 0.96005494775729 0.96005494775729 0.96005494775729 0.96005494775729 0.96005494775729 0.96005494775729 0.96005494775729 0.96005494775729 0.96005494775729 0.96005494775729 0.96005494775729 0.96005494775729 0.96005494775729 0.96005494775729 0.96005494775729 0.96005494775729 0.96005494775729 0.96005494775729 0.96000571977412 0.96000571977412 0.96000571977412 0.96000571977412 0.96000571977412 0.96000571977412 0.96000571977412 0.96000571977412 0.96000571977412 0.96000571977412 0.96000571977412 0.96000571977412 0.96000571977412 0.96000571977412 0.96000571977412 0.96000571977412 0.96000571977412 0.96000571977412 0.96000571977412 0.96000571977412 0.96000571977412 0.96000571977412 0.96000571977412 0.96000571977412 0.96000571977412 0.96000041848693 0.96000041848693 0.96000041848693 0.96000041848693 0.96000041848693 0.96000041848693 0.96000041848693 0.96000041848693 0.96000041848693 0.96000041848693 0.96000041848693 0.96000041848693 0.96000041848693 0.96000041848693 0.96000041848693 0.96000041848693 0.96000041848693 0.96000041848693 0.96000041848693 0.96000041848693 0.96000041848693 0.96000041848693 0.96000041848693 0.96000041848693 0.96000041848693 0.96000002077145 0.96000002077145 0.96000002077145 0.96000002077145 0.96000002077145 0.96000002077145 0.96000002077145 0.96000002077145 0.96000002077145 0.96000002077145 0.96000002077145 0.96000002077145 0.96000002077145 0.96000002077145 0.96000002077145 0.96000002077145 0.96000002077145 0.96000002077145 0.96000002077145 0.96000002077145 0.96000002077145 0.96000002077145 0.96000002077145 0.96000002077145 0.96000002077145 0.96000000072415 0.96000000072415 0.96000000072415 0.96000000072415 0.96000000072415 0.96000000072415 0.96000000072415 0.96000000072415 0.96000000072415 0.96000000072415 0.96000000072415 0.96000000072415 0.96000000072415 0.96000000072415 0.96000000072415 0.96000000072415 0.96000000072415 0.96000000072415 0.96000000072415 0.96000000072415 0.96000000072415 0.96000000072415 0.96000000072415 0.96000000072415 0.96000000072415 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000000027 0.96000000000027 0.96000000000027 0.96000000000027 0.96000000000027 0.96000000000027 0.96000000000027 0.96000000000027 0.96000000000027 0.96000000000027 0.96000000000027 0.96000000000027 0.96000000000027 0.96000000000027 0.96000000000027 0.96000000000027 0.96000000000027 0.96000000000027 0.96000000000027 0.96000000000027 0.96000000000027 0.96000000000027 0.96000000000027 0.96000000000027 0.96000000000027 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000005445 0.96000000005445 0.96000000005445 0.96000000005445 0.96000000005445 0.96000000005445 0.96000000005445 0.96000000005445 0.96000000005445 0.96000000005445 0.96000000005445 0.96000000005445 0.96000000005445 0.96000000005445 0.96000000005445 0.96000000005445 0.96000000005445 0.96000000005445 0.96000000005445 0.96000000005445 0.96000000005445 0.96000000005445 0.96000000005445 0.96000000005445 0.96000000005445 0.96000000142375 0.96000000142375 0.96000000142375 0.96000000142375 0.96000000142375 0.96000000142375 0.96000000142375 0.96000000142375 0.96000000142375 0.96000000142375 0.96000000142375 0.96000000142375 0.96000000142375 0.96000000142375 0.96000000142375 0.96000000142375 0.96000000142375 0.96000000142375 0.96000000142375 0.96000000142375 0.96000000142375 0.96000000142375 0.96000000142375 0.96000000142375 0.96000000142375 0.96000009370674 0.96000009370674 0.96000009370674 0.96000009370674 0.96000009370674 0.96000009370674 0.96000009370674 0.96000009370674 0.96000009370674 0.96000009370674 0.96000009370674 0.96000009370674 0.96000009370674 0.96000009370674 0.96000009370674 0.96000009370674 0.96000009370674 0.96000009370674 0.96000009370674 0.96000009370674 0.96000009370674 0.96000009370674 0.96000009370674 0.96000009370674 0.96000009370674 0.96000254523862 0.96000254523862 0.96000254523862 0.96000254523862 0.96000254523862 0.96000254523862 0.96000254523862 0.96000254523862 0.96000254523862 0.96000254523862 0.96000254523862 0.96000254523862 0.96000254523862 0.96000254523862 0.96000254523862 0.96000254523862 0.96000254523862 0.96000254523862 0.96000254523862 0.96000254523862 0.96000254523862 0.96000254523862 0.96000254523862 0.96000254523862 0.96000254523862 0.96000117610763 0.96000117610763 0.96000117610763 0.96000117610763 0.96000117610763 0.96000117610763 0.96000117610763 0.96000117610763 0.96000117610763 0.96000117610763 0.96000117610763 0.96000117610763 0.96000117610763 0.96000117610763 0.96000117610763 0.96000117610763 0.96000117610763 0.96000117610763 0.96000117610763 0.96000117610763 0.96000117610763 0.96000117610763 0.96000117610763 0.96000117610763 0.96000117610763 0.96000524478499 0.96000524478499 0.96000524478499 0.96000524478499 0.96000524478499 0.96000524478499 0.96000524478499 0.96000524478499 0.96000524478499 0.96000524478499 0.96000524478499 0.96000524478499 0.96000524478499 0.96000524478499 0.96000524478499 0.96000524478499 0.96000524478499 0.96000524478499 0.96000524478499 0.96000524478499 0.96000524478499 0.96000524478499 0.96000524478499 0.96000524478499 0.96000524478499 0.96000087573747 0.96000087573747 0.96000087573747 0.96000087573747 0.96000087573747 0.96000087573747 0.96000087573747 0.96000087573747 0.96000087573747 0.96000087573747 0.96000087573747 0.96000087573747 0.96000087573747 0.96000087573747 0.96000087573747 0.96000087573747 0.96000087573747 0.96000087573747 0.96000087573747 0.96000087573747 0.96000087573747 0.96000087573747 0.96000087573747 0.96000087573747 0.96000087573747 0.96000085120187 0.96000085120187 0.96000085120187 0.96000085120187 0.96000085120187 0.96000085120187 0.96000085120187 0.96000085120187 0.96000085120187 0.96000085120187 0.96000085120187 0.96000085120187 0.96000085120187 0.96000085120187 0.96000085120187 0.96000085120187 0.96000085120187 0.96000085120187 0.96000085120187 0.96000085120187 0.96000085120187 0.96000085120187 0.96000085120187 0.96000085120187 0.96000085120187 0.96000007393657 0.96000007393657 0.96000007393657 0.96000007393657 0.96000007393657 0.96000007393657 0.96000007393657 0.96000007393657 0.96000007393657 0.96000007393657 0.96000007393657 0.96000007393657 0.96000007393657 0.96000007393657 0.96000007393657 0.96000007393657 0.96000007393657 0.96000007393657 0.96000007393657 0.96000007393657 0.96000007393657 0.96000007393657 0.96000007393657 0.96000007393657 0.96000007393657 0.96000000267574 0.96000000267574 0.96000000267574 0.96000000267574 0.96000000267574 0.96000000267574 0.96000000267574 0.96000000267574 0.96000000267574 0.96000000267574 0.96000000267574 0.96000000267574 0.96000000267574 0.96000000267574 0.96000000267574 0.96000000267574 0.96000000267574 0.96000000267574 0.96000000267574 0.96000000267574 0.96000000267574 0.96000000267574 0.96000000267574 0.96000000267574 0.96000000267574 0.96000000007354 0.96000000007354 0.96000000007354 0.96000000007354 0.96000000007354 0.96000000007354 0.96000000007354 0.96000000007354 0.96000000007354 0.96000000007354 0.96000000007354 0.96000000007354 0.96000000007354 0.96000000007354 0.96000000007354 0.96000000007354 0.96000000007354 0.96000000007354 0.96000000007354 0.96000000007354 0.96000000007354 0.96000000007354 0.96000000007354 0.96000000007354 0.96000000007354 0.96000000000181 0.96000000000181 0.96000000000181 0.96000000000181 0.96000000000181 0.96000000000181 0.96000000000181 0.96000000000181 0.96000000000181 0.96000000000181 0.96000000000181 0.96000000000181 0.96000000000181 0.96000000000181 0.96000000000181 0.96000000000181 0.96000000000181 0.96000000000181 0.96000000000181 0.96000000000181 0.96000000000181 0.96000000000181 0.96000000000181 0.96000000000181 0.96000000000181 0.95999999999985 0.95999999999985 0.95999999999985 0.95999999999985 0.95999999999985 0.95999999999985 0.95999999999985 0.95999999999985 0.95999999999985 0.95999999999985 0.95999999999985 0.95999999999985 0.95999999999985 0.95999999999985 0.95999999999985 0.95999999999985 0.95999999999985 0.95999999999985 0.95999999999985 0.95999999999985 0.95999999999985 0.95999999999985 0.95999999999985 0.95999999999985 0.95999999999985 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.96000000000058 0.96000000000058 0.96000000000058 0.96000000000058 0.96000000000058 0.96000000000058 0.96000000000058 0.96000000000058 0.96000000000058 0.96000000000058 0.96000000000058 0.96000000000058 0.96000000000058 0.96000000000058 0.96000000000058 0.96000000000058 0.96000000000058 0.96000000000058 0.96000000000058 0.96000000000058 0.96000000000058 0.96000000000058 0.96000000000058 0.96000000000058 0.96000000000058 0.96000000001744 0.96000000001744 0.96000000001744 0.96000000001744 0.96000000001744 0.96000000001744 0.96000000001744 0.96000000001744 0.96000000001744 0.96000000001744 0.96000000001744 0.96000000001744 0.96000000001744 0.96000000001744 0.96000000001744 0.96000000001744 0.96000000001744 0.96000000001744 0.96000000001744 0.96000000001744 0.96000000001744 0.96000000001744 0.96000000001744 0.96000000001744 0.96000000001744 0.96000000114058 0.96000000114058 0.96000000114058 0.96000000114058 0.96000000114058 0.96000000114058 0.96000000114058 0.96000000114058 0.96000000114058 0.96000000114058 0.96000000114058 0.96000000114058 0.96000000114058 0.96000000114058 0.96000000114058 0.96000000114058 0.96000000114058 0.96000000114058 0.96000000114058 0.96000000114058 0.96000000114058 0.96000000114058 0.96000000114058 0.96000000114058 0.96000000114058 0.9600000318752 0.9600000318752 0.9600000318752 0.9600000318752 0.9600000318752 0.9600000318752 0.9600000318752 0.9600000318752 0.9600000318752 0.9600000318752 0.9600000318752 0.9600000318752 0.9600000318752 0.9600000318752 0.9600000318752 0.9600000318752 0.9600000318752 0.9600000318752 0.9600000318752 0.9600000318752 0.9600000318752 0.9600000318752 0.9600000318752 0.9600000318752 0.9600000318752 0.96000001538587 0.96000001538587 0.96000001538587 0.96000001538587 0.96000001538587 0.96000001538587 0.96000001538587 0.96000001538587 0.96000001538587 0.96000001538587 0.96000001538587 0.96000001538587 0.96000001538587 0.96000001538587 0.96000001538587 0.96000001538587 0.96000001538587 0.96000001538587 0.96000001538587 0.96000001538587 0.96000001538587 0.96000001538587 0.96000001538587 0.96000001538587 0.96000001538587 0.96000008339363 0.96000008339363 0.96000008339363 0.96000008339363 0.96000008339363 0.96000008339363 0.96000008339363 0.96000008339363 0.96000008339363 0.96000008339363 0.96000008339363 0.96000008339363 0.96000008339363 0.96000008339363 0.96000008339363 0.96000008339363 0.96000008339363 0.96000008339363 0.96000008339363 0.96000008339363 0.96000008339363 0.96000008339363 0.96000008339363 0.96000008339363 0.96000008339363 0.96000001383394 0.96000001383394 0.96000001383394 0.96000001383394 0.96000001383394 0.96000001383394 0.96000001383394 0.96000001383394 0.96000001383394 0.96000001383394 0.96000001383394 0.96000001383394 0.96000001383394 0.96000001383394 0.96000001383394 0.96000001383394 0.96000001383394 0.96000001383394 0.96000001383394 0.96000001383394 0.96000001383394 0.96000001383394 0.96000001383394 0.96000001383394 0.96000001383394 0.96000001361022 0.96000001361022 0.96000001361022 0.96000001361022 0.96000001361022 0.96000001361022 0.96000001361022 0.96000001361022 0.96000001361022 0.96000001361022 0.96000001361022 0.96000001361022 0.96000001361022 0.96000001361022 0.96000001361022 0.96000001361022 0.96000001361022 0.96000001361022 0.96000001361022 0.96000001361022 0.96000001361022 0.96000001361022 0.96000001361022 0.96000001361022 0.96000001361022 0.96000000508758 0.96000000508758 0.96000000508758 0.96000000508758 0.96000000508758 0.96000000508758 0.96000000508758 0.96000000508758 0.96000000508758 0.96000000508758 0.96000000508758 0.96000000508758 0.96000000508758 0.96000000508758 0.96000000508758 0.96000000508758 0.96000000508758 0.96000000508758 0.96000000508758 0.96000000508758 0.96000000508758 0.96000000508758 0.96000000508758 0.96000000508758 0.96000000508758 0.96000000027613 0.96000000027613 0.96000000027613 0.96000000027613 0.96000000027613 0.96000000027613 0.96000000027613 0.96000000027613 0.96000000027613 0.96000000027613 0.96000000027613 0.96000000027613 0.96000000027613 0.96000000027613 0.96000000027613 0.96000000027613 0.96000000027613 0.96000000027613 0.96000000027613 0.96000000027613 0.96000000027613 0.96000000027613 0.96000000027613 0.96000000027613 0.96000000027613 0.96000000000723 0.96000000000723 0.96000000000723 0.96000000000723 0.96000000000723 0.96000000000723 0.96000000000723 0.96000000000723 0.96000000000723 0.96000000000723 0.96000000000723 0.96000000000723 0.96000000000723 0.96000000000723 0.96000000000723 0.96000000000723 0.96000000000723 0.96000000000723 0.96000000000723 0.96000000000723 0.96000000000723 0.96000000000723 0.96000000000723 0.96000000000723 0.96000000000723 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.96000000000014 0.96000000000014 0.96000000000014 0.96000000000014 0.96000000000014 0.96000000000014 0.96000000000014 0.96000000000014 0.96000000000014 0.96000000000014 0.96000000000014 0.96000000000014 0.96000000000014 0.96000000000014 0.96000000000014 0.96000000000014 0.96000000000014 0.96000000000014 0.96000000000014 0.96000000000014 0.96000000000014 0.96000000000014 0.96000000000014 0.96000000000014 0.96000000000014 0.96000000001185 0.96000000001185 0.96000000001185 0.96000000001185 0.96000000001185 0.96000000001185 0.96000000001185 0.96000000001185 0.96000000001185 0.96000000001185 0.96000000001185 0.96000000001185 0.96000000001185 0.96000000001185 0.96000000001185 0.96000000001185 0.96000000001185 0.96000000001185 0.96000000001185 0.96000000001185 0.96000000001185 0.96000000001185 0.96000000001185 0.96000000001185 0.96000000001185 0.96000000033252 0.96000000033252 0.96000000033252 0.96000000033252 0.96000000033252 0.96000000033252 0.96000000033252 0.96000000033252 0.96000000033252 0.96000000033252 0.96000000033252 0.96000000033252 0.96000000033252 0.96000000033252 0.96000000033252 0.96000000033252 0.96000000033252 0.96000000033252 0.96000000033252 0.96000000033252 0.96000000033252 0.96000000033252 0.96000000033252 0.96000000033252 0.96000000033252 0.9600000001676 0.9600000001676 0.9600000001676 0.9600000001676 0.9600000001676 0.9600000001676 0.9600000001676 0.9600000001676 0.9600000001676 0.9600000001676 0.9600000001676 0.9600000001676 0.9600000001676 0.9600000001676 0.9600000001676 0.9600000001676 0.9600000001676 0.9600000001676 0.9600000001676 0.9600000001676 0.9600000001676 0.9600000001676 0.9600000001676 0.9600000001676 0.9600000001676 0.96000000105006 0.96000000105006 0.96000000105006 0.96000000105006 0.96000000105006 0.96000000105006 0.96000000105006 0.96000000105006 0.96000000105006 0.96000000105006 0.96000000105006 0.96000000105006 0.96000000105006 0.96000000105006 0.96000000105006 0.96000000105006 0.96000000105006 0.96000000105006 0.96000000105006 0.96000000105006 0.96000000105006 0.96000000105006 0.96000000105006 0.96000000105006 0.96000000105006 0.96000000017454 0.96000000017454 0.96000000017454 0.96000000017454 0.96000000017454 0.96000000017454 0.96000000017454 0.96000000017454 0.96000000017454 0.96000000017454 0.96000000017454 0.96000000017454 0.96000000017454 0.96000000017454 0.96000000017454 0.96000000017454 0.96000000017454 0.96000000017454 0.96000000017454 0.96000000017454 0.96000000017454 0.96000000017454 0.96000000017454 0.96000000017454 0.96000000017454 0.96000000021066 0.96000000021066 0.96000000021066 0.96000000021066 0.96000000021066 0.96000000021066 0.96000000021066 0.96000000021066 0.96000000021066 0.96000000021066 0.96000000021066 0.96000000021066 0.96000000021066 0.96000000021066 0.96000000021066 0.96000000021066 0.96000000021066 0.96000000021066 0.96000000021066 0.96000000021066 0.96000000021066 0.96000000021066 0.96000000021066 0.96000000021066 0.96000000021066 0.96000000008263 0.96000000008263 0.96000000008263 0.96000000008263 0.96000000008263 0.96000000008263 0.96000000008263 0.96000000008263 0.96000000008263 0.96000000008263 0.96000000008263 0.96000000008263 0.96000000008263 0.96000000008263 0.96000000008263 0.96000000008263 0.96000000008263 0.96000000008263 0.96000000008263 0.96000000008263 0.96000000008263 0.96000000008263 0.96000000008263 0.96000000008263 0.96000000008263 0.96000000000466 0.96000000000466 0.96000000000466 0.96000000000466 0.96000000000466 0.96000000000466 0.96000000000466 0.96000000000466 0.96000000000466 0.96000000000466 0.96000000000466 0.96000000000466 0.96000000000466 0.96000000000466 0.96000000000466 0.96000000000466 0.96000000000466 0.96000000000466 0.96000000000466 0.96000000000466 0.96000000000466 0.96000000000466 0.96000000000466 0.96000000000466 0.96000000000466 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000325 0.96000000000325 0.96000000000325 0.96000000000325 0.96000000000325 0.96000000000325 0.96000000000325 0.96000000000325 0.96000000000325 0.96000000000325 0.96000000000325 0.96000000000325 0.96000000000325 0.96000000000325 0.96000000000325 0.96000000000325 0.96000000000325 0.96000000000325 0.96000000000325 0.96000000000325 0.96000000000325 0.96000000000325 0.96000000000325 0.96000000000325 0.96000000000325 0.96000000000187 0.96000000000187 0.96000000000187 0.96000000000187 0.96000000000187 0.96000000000187 0.96000000000187 0.96000000000187 0.96000000000187 0.96000000000187 0.96000000000187 0.96000000000187 0.96000000000187 0.96000000000187 0.96000000000187 0.96000000000187 0.96000000000187 0.96000000000187 0.96000000000187 0.96000000000187 0.96000000000187 0.96000000000187 0.96000000000187 0.96000000000187 0.96000000000187 0.96000000001122 0.96000000001122 0.96000000001122 0.96000000001122 0.96000000001122 0.96000000001122 0.96000000001122 0.96000000001122 0.96000000001122 0.96000000001122 0.96000000001122 0.96000000001122 0.96000000001122 0.96000000001122 0.96000000001122 0.96000000001122 0.96000000001122 0.96000000001122 0.96000000001122 0.96000000001122 0.96000000001122 0.96000000001122 0.96000000001122 0.96000000001122 0.96000000001122 0.96000000000219 0.96000000000219 0.96000000000219 0.96000000000219 0.96000000000219 0.96000000000219 0.96000000000219 0.96000000000219 0.96000000000219 0.96000000000219 0.96000000000219 0.96000000000219 0.96000000000219 0.96000000000219 0.96000000000219 0.96000000000219 0.96000000000219 0.96000000000219 0.96000000000219 0.96000000000219 0.96000000000219 0.96000000000219 0.96000000000219 0.96000000000219 0.96000000000219 0.96000000000302 0.96000000000302 0.96000000000302 0.96000000000302 0.96000000000302 0.96000000000302 0.96000000000302 0.96000000000302 0.96000000000302 0.96000000000302 0.96000000000302 0.96000000000302 0.96000000000302 0.96000000000302 0.96000000000302 0.96000000000302 0.96000000000302 0.96000000000302 0.96000000000302 0.96000000000302 0.96000000000302 0.96000000000302 0.96000000000302 0.96000000000302 0.96000000000302 0.9600000000017 0.9600000000017 0.9600000000017 0.9600000000017 0.9600000000017 0.9600000000017 0.9600000000017 0.9600000000017 0.9600000000017 0.9600000000017 0.9600000000017 0.9600000000017 0.9600000000017 0.9600000000017 0.9600000000017 0.9600000000017 0.9600000000017 0.9600000000017 0.9600000000017 0.9600000000017 0.9600000000017 0.9600000000017 0.9600000000017 0.9600000000017 0.9600000000017 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999984 0.95999999999984 0.95999999999984 0.95999999999984 0.95999999999984 0.95999999999984 0.95999999999984 0.95999999999984 0.95999999999984 0.95999999999984 0.95999999999984 0.95999999999984 0.95999999999984 0.95999999999984 0.95999999999984 0.95999999999984 0.95999999999984 0.95999999999984 0.95999999999984 0.95999999999984 0.95999999999984 0.95999999999984 0.95999999999984 0.95999999999984 0.95999999999984 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 D/cons.2.00.000000.dat 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 @@ -17,4 +17,4 @@ D/cons.8.00.000000.dat 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0 D/cons.8.00.000050.dat 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 D/lag_bubble_evol_0.dat 0.0 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832988093882 0.008 0.0 1.0001782913460961 0.0 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832988093882 0.008 0.0 1.0001782913460961 1e-06 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832988093882 0.0079999999991335 -2.5998347812e-06 1.000178291800741 2e-06 1.0 0.5 0.5 0.5 3.64821e-11 0.014383298809388 0.0079999999922017 -1.29983242186e-05 1.000178295437995 3e-06 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832988093872 0.0079999999688074 -3.63927017024e-05 1.0001783077133188 4e-06 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832988093845 0.0079999999133575 -7.79781563216e-05 1.000178336808713 5e-06 1.0 0.5 0.5 0.5 3.64821e-11 0.014383298809378 0.0079999998050647 -0.0001429472991708 1.0001783936315034 6e-06 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832988093644 0.0079999996179507 -0.0002364895241275 1.0001784918128234 7e-06 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832988093391 0.0079999993208499 -0.0003637902333544 1.0001786477057284 8e-06 1.0 0.5 0.5 0.5 3.64821e-11 0.014383298809296 0.0079999988774134 -0.0005300298975884 1.000178880382868 9e-06 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832988092268 0.0079999982461151 -0.0007403829210309 1.0001792116336214 1e-05 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832988091214 0.0079999973802576 -0.0010000162803676 1.0001796659605886 1.1e-05 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832988089671 0.0079999962279814 -0.0013140879071025 1.0001802705753133 1.2e-05 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832988087485 0.0079999947322742 -0.001687744782021 1.0001810553930972 1.3e-05 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832988084475 0.0079999928309829 -0.002126120710193 1.0001820530267498 1.4e-05 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832988080425 0.0079999904568284 -0.0026343337445149 1.0001832987791015 1.5e-05 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832988075089 0.0079999875374229 -0.0032174832253708 1.0001848306340897 1.6e-05 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832988068183 0.0079999839952895 -0.0038806464035904 1.000186689246213 1.7e-05 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832988059382 0.0079999797478871 -0.0046288746135072 1.000188917928131 1.8e-05 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832988048322 0.0079999747076377 -0.0054671889625894 1.000191562636167 1.9e-05 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832988034595 0.0079999687819595 -0.0064005755038528 1.0001946719534596 2e-05 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832988017745 0.0079999618733042 -0.007433979857085 1.0001982970704828 2.1e-05 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832987997269 0.0079999538792009 -0.0085723012448426 1.000202491762648 2.2e-05 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832987972612 0.0079999446923049 -0.0098203859092421 1.0002073123646718 2.3e-05 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832987943166 0.0079999342004551 -0.011183019875789 1.0002128177413845 2.4e-05 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832987908266 0.0079999222867377 -0.0126649210309033 1.0002190692546316 2.5e-05 1.0 0.5 0.5 0.5 3.64821e-11 0.014383298786719 0.0079999088295585 -0.0142707304804285 1.000226130725907 2.6e-05 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832987819156 0.0079998937027246 -0.0160050031573143 1.0002340683943376 2.7e-05 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832987763319 0.0079998767755354 -0.0178721976476137 1.0002429508696198 2.8e-05 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832987698769 0.0079998579128844 -0.0198766652057478 1.000252849079501 2.9e-05 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832987624528 0.0079998369753724 -0.0220226379315838 1.0002638362113736 3e-05 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832987539552 0.007999813819433 -0.0243142160841659 1.0002759876475424 3.1e-05 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832987442723 0.0079997882974709 -0.0267553545095958 1.0002893808937117 3.2e-05 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832987332852 0.0079997602580149 -0.029349848163718 1.0003040955002234 3.3e-05 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832987208674 0.0079997295458849 -0.0321013167136486 1.0003202129755737 3.4e-05 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832987068849 0.0079996960023757 -0.0350131882068714 1.000337816691723 3.5e-05 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832986911959 0.0079996594654568 -0.0380886818013008 1.0003569917807094 3.6e-05 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832986736504 0.0079996197699907 -0.0413307895553177 1.0003778250220763 3.7e-05 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832986540904 0.0079995767479693 -0.0447422572817508 1.0004004047206192 3.8e-05 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832986323498 0.0079995302287701 -0.048325564474873 1.000424820573963 3.9e-05 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832986082539 0.0079994800394327 -0.0520829033325081 1.000451163529485 4e-05 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832985816196 0.0079994260049577 -0.0560161569072351 1.0004795256301158 4.1e-05 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832985522554 0.007999367948626 -0.0601268764180896 1.0005099998485611 4.2e-05 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832985199608 0.0079993056923434 -0.0644162577618181 1.0005426799095096 4.3e-05 1.0 0.5 0.5 0.5 3.64821e-11 0.014383298484527 0.0079992390570073 -0.0688851172641215 1.0005776600994014 4.4e-05 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832984457361 0.007999167862899 -0.0735338667716603 1.0006150350633782 4.5e-05 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832984033616 0.0079990919301005 -0.0783624881671981 1.000654899589073 4.6e-05 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832983571682 0.0079990110789379 -0.0833705073971212 1.000697348376945 4.7e-05 1.0 0.5 0.5 0.5 3.64821e-11 0.014383298306912 0.0079989251304502 -0.0885569681129268 1.0007424757969103 4.8e-05 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832982523402 0.0079988339068849 -0.0939204050483519 1.0007903756310734 4.9e-05 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832981931914 0.0079987372322203 -0.0994588172778342 1.000841140802435 D/stats_lag_bubbles_0.dat 0.0 1.0 0.5 0.5 0.5 1.0 0.9998421540275337 -D/voidfraction.dat 2.1429198e-06 2.1429198e-06 2.1429198e-06 2.1429198e-06 2.1429197e-06 2.1429197e-06 2.1429196e-06 2.1429195e-06 2.1429193e-06 2.142919e-06 2.1429186e-06 2.142918e-06 2.1429172e-06 2.1429161e-06 2.1429148e-06 2.142913e-06 2.1429109e-06 2.1429083e-06 2.1429052e-06 2.1429015e-06 2.1428971e-06 2.1428919e-06 2.1428859e-06 2.142879e-06 2.1428711e-06 2.1428621e-06 2.1428519e-06 2.1428404e-06 2.1428275e-06 2.1428132e-06 2.1427972e-06 2.1427795e-06 2.1427599e-06 2.1427384e-06 2.1427148e-06 2.142689e-06 2.1426608e-06 2.1426302e-06 2.1425969e-06 2.142561e-06 2.1425221e-06 2.1424803e-06 2.1424352e-06 2.1423869e-06 2.1423351e-06 2.1422797e-06 2.1422206e-06 2.1421577e-06 2.1420907e-06 2.1420195e-06 2.141944e-06 \ No newline at end of file +D/voidfraction.dat 2.1429198e-06 2.1429198e-06 2.1429198e-06 2.1429198e-06 2.1429197e-06 2.1429197e-06 2.1429196e-06 2.1429195e-06 2.1429192e-06 2.1429189e-06 2.1429183e-06 2.1429177e-06 2.1429167e-06 2.1429155e-06 2.142914e-06 2.1429121e-06 2.1429097e-06 2.1429069e-06 2.1429035e-06 2.1428994e-06 2.1428947e-06 2.1428891e-06 2.1428827e-06 2.1428753e-06 2.1428669e-06 2.1428573e-06 2.1428465e-06 2.1428343e-06 2.1428207e-06 2.1428056e-06 2.1427888e-06 2.1427701e-06 2.1427496e-06 2.1427271e-06 2.1427024e-06 2.1426755e-06 2.1426461e-06 2.1426142e-06 2.1425797e-06 2.1425423e-06 2.1425019e-06 2.1424585e-06 2.1424119e-06 2.1423619e-06 2.1423083e-06 2.1422511e-06 2.1421901e-06 2.1421252e-06 2.1420561e-06 2.1419828e-06 2.1419052e-06 \ No newline at end of file diff --git a/toolchain/bootstrap/format.sh b/toolchain/bootstrap/format.sh index 962fe5d7a9..ce500ab301 100644 --- a/toolchain/bootstrap/format.sh +++ b/toolchain/bootstrap/format.sh @@ -51,10 +51,59 @@ else PYTHON_DIRS="toolchain/ examples/ benchmarks/" fi -# Format Fortran files with ffmt (single-pass, idempotent) -if ! ffmt -j ${JOBS:-1} $FORTRAN_DIRS 2>/dev/null; then - error "Formatting Fortran files failed: ffmt." - exit 1 +# Format Fortran files (.f90, .fpp) +FORTRAN_FILES=$(find $FORTRAN_DIRS -type f 2>/dev/null | grep -Ev 'autogen' | grep -E '\.(f90|fpp)$' || true) +if [[ -n "$FORTRAN_FILES" ]]; then + FPRETTIFY_OPTS="--silent --indent 4 --c-relations --enable-replacements --enable-decl --whitespace-comma 1 --whitespace-multdiv 0 --whitespace-plusminus 1 --case 1 1 1 1 --strict-indent --line-length 1000" + + # Skip files unchanged since last format (hash cache in build/.cache/format/) + CACHE_DIR="build/.cache/format" + mkdir -p "$CACHE_DIR" + DIRTY_FILES="" + for f in $FORTRAN_FILES; do + cache_key=$(echo "$f" | tr '/' '_') + current_hash=$(md5sum "$f" | cut -d' ' -f1) + cached_hash=$(cat "$CACHE_DIR/$cache_key" 2>/dev/null || true) + if [[ "$current_hash" != "$cached_hash" ]]; then + DIRTY_FILES+="$f"$'\n' + fi + done + DIRTY_FILES=$(echo "$DIRTY_FILES" | sed '/^$/d') + + if [[ -n "$DIRTY_FILES" ]]; then + for niter in 1 2 3 4; do + old_hash=$(echo "$DIRTY_FILES" | xargs cat | md5sum) + + # Run indenter on dirty files in one process + if ! echo "$DIRTY_FILES" | xargs python3 toolchain/indenter.py; then + error "Formatting Fortran files failed: indenter.py." + exit 1 + fi + + # Run fprettify in parallel (one process per file) + if ! echo "$DIRTY_FILES" | xargs -P ${JOBS:-1} -L 1 fprettify $FPRETTIFY_OPTS; then + error "Formatting Fortran files failed: fprettify." + exit 1 + fi + + new_hash=$(echo "$DIRTY_FILES" | xargs cat | md5sum) + if [[ "$old_hash" == "$new_hash" ]]; then + break + fi + if [[ "$niter" -eq 4 ]]; then + error "Formatting Fortran files failed: no steady-state after $niter iterations." + exit 1 + fi + done + + # Update hash cache for formatted files + for f in $DIRTY_FILES; do + cache_key=$(echo "$f" | tr '/' '_') + md5sum "$f" | cut -d' ' -f1 > "$CACHE_DIR/$cache_key" + done + + echo "$DIRTY_FILES" | while read -r f; do echo "> $f"; done + fi fi # Apply safe auto-fixes (import sorting, etc.) before formatting. diff --git a/toolchain/indenter.py b/toolchain/indenter.py new file mode 100644 index 0000000000..ab0203ae4e --- /dev/null +++ b/toolchain/indenter.py @@ -0,0 +1,83 @@ +#!/usr/bin/env python3 + +import argparse +import os + + +def main(): + parser = argparse.ArgumentParser(prog="indenter.py", description="Adjust indentation of OpenACC directives in Fortran files") + parser.add_argument("filepaths", metavar="input_file", type=str, nargs="+", help="Files to format") + args = parser.parse_args() + + for filepath in args.filepaths: + temp_filepath = f"{filepath}.new" + adjust_indentation(filepath, temp_filepath) + os.replace(temp_filepath, filepath) + + +BLOCK_STARTERS = ("if", "do", "#:if", "#:else", "#ifdef", "#else") +BLOCK_ENDERS = ("end", "contains", "else", "#:end", "#:else", "#else", "#endif") +LOOP_DIRECTIVES = ("!$acc loop", "!$acc parallel loop") +INDENTERS = ("!DIR", "!$acc") + + +def adjust_indentation(input_file, output_file): + max_empty_lines = 4 + indent_len = 4 + + with open(input_file, "r") as file_in, open(output_file, "w") as file_out: + lines = file_in.readlines() + + # this makes sure !$acc lines that have line continuations get indented at proper level + for _ in range(10): + # loop through file + for i in range(len(lines)): + if lines[i].lstrip().startswith(INDENTERS) and i + 1 < len(lines): + j = i + 1 + empty_lines = 0 + # look down to see how to indent a line + while j < len(lines) and empty_lines < max_empty_lines: + # if the following line starts with [end, else, contains], skip to looking up + if lines[j].lstrip().startswith(BLOCK_ENDERS): + empty_lines = max_empty_lines + # skip empty lines + elif lines[j].strip() == "": + empty_lines += 1 + # indent acc lines + elif not lines[j].lstrip().startswith(INDENTERS): + indent = len(lines[j]) - len(lines[j].lstrip()) + lines[i] = " " * indent + lines[i].lstrip() + break + j += 1 + # if looking down just finds empty lines, start looking up for indentation level + if empty_lines == max_empty_lines: + k = i - 1 + while k >= 0: + # if line above is not empty + if lines[k].strip() != "": + # if line 2 above ends with line continuation, indent at that level + if lines[k - 1].strip().endswith("&"): + indent = len(lines[k - 1]) - len(lines[k - 1].lstrip()) + # if line above starts a loop or branch, indent + elif lines[k].lstrip().startswith(BLOCK_STARTERS): + indent = indent_len + (len(lines[k]) - len(lines[k].lstrip())) + # else indent at level of line above + else: + indent = len(lines[k]) - len(lines[k].lstrip()) + lines[i] = " " * indent + lines[i].lstrip() + break + k -= 1 + + # remove empty lines following an acc loop directive + i = 0 + while i < len(lines): + if lines[i].lstrip().startswith(LOOP_DIRECTIVES) and i + 1 < len(lines) and lines[i + 1].strip() == "": + file_out.write(lines[i]) + i += 2 + else: + file_out.write(lines[i]) + i += 1 + + +if __name__ == "__main__": + main() diff --git a/toolchain/mfc/params/definitions.py b/toolchain/mfc/params/definitions.py index 2f3631c228..e3ea3f45ad 100644 --- a/toolchain/mfc/params/definitions.py +++ b/toolchain/mfc/params/definitions.py @@ -627,8 +627,8 @@ def get_value_label(param_name: str, value: int) -> str: }, # Bubbles "bubble_model": { - "choices": [1, 2, 3], - "value_labels": {1: "Gilmore", 2: "Keller-Miksis", 3: "Rayleigh-Plesset"}, + "choices": [0, 1, 2, 3], + "value_labels": {0: "Particle", 1: "Gilmore", 2: "Keller-Miksis", 3: "Rayleigh-Plesset"}, }, # Output "format": { @@ -1053,6 +1053,13 @@ def _load(): _r(f"p_{d}", REAL, math=r"\f$\phi_" + d + r"\f$") _r(f"bf_{d}", LOG) + # Interfacial flow inputs + _r("normMag", REAL) + _r("p0_ic", REAL) + _r("g0_ic", REAL) + _r("normFac", REAL) + _r("interface_file", STR) + # INDEXED PARAMETERS # patch_icpp (10 patches) @@ -1260,12 +1267,13 @@ def _load(): _r(f"simplex_params%perturb_vel_offset({d},{j})", REAL) # lag_params (Lagrangian bubbles) - for a in ["heatTransfer_model", "massTransfer_model", "pressure_corrector", "write_bubbles", "write_bubbles_stats"]: + for a in ["heatTransfer_model", "massTransfer_model", "pressure_corrector", "write_bubbles", "write_bubbles_stats", "pressure_force", "gravity_force", "write_void_evol"]: _r(f"lag_params%{a}", LOG, {"bubbles"}) - for a in ["solver_approach", "cluster_type", "smooth_type", "nBubs_glb"]: + for a in ["solver_approach", "cluster_type", "smooth_type", "nBubs_glb", "drag_model", "vel_model", "charNz"]: _r(f"lag_params%{a}", INT, {"bubbles"}) for a in ["epsilonb", "valmaxvoid", "charwidth", "c0", "rho0", "T0", "x0", "Thost"]: _r(f"lag_params%{a}", REAL, {"bubbles"}) + _r("lag_params%input_path", STR, {"bubbles"}) # chem_params for a in ["diffusion", "reactions"]: diff --git a/toolchain/mfc/params/descriptions.py b/toolchain/mfc/params/descriptions.py index 7906b6d38d..e903d82e54 100644 --- a/toolchain/mfc/params/descriptions.py +++ b/toolchain/mfc/params/descriptions.py @@ -250,6 +250,12 @@ "lag_mg_wrt": "Write bubble gas mass", "lag_betaT_wrt": "Write bubble heat transfer coefficient", "lag_betaC_wrt": "Write bubble mass transfer coefficient", + # Interfacial flow parameters + "interface_file": "Path to interface geometry data file", + "normFac": "Interface normalization factor", + "normMag": "Interface normal magnitude", + "g0_ic": "Initial gas volume fraction for interfacial IC", + "p0_ic": "Initial pressure for interfacial IC", } # Patterns for auto-generating descriptions of indexed parameters @@ -483,15 +489,17 @@ (r"lag_params%massTransfer_model", "Enable mass transfer at bubble-liquid interface"), (r"lag_params%write_bubbles", "Write bubble evolution data each time step"), (r"lag_params%write_bubbles_stats", "Write max/min radius statistics for bubbles"), + (r"lag_params%write_void_evol", "Write void fraction evolution data"), (r"lag_params%nBubs_glb", "Global number of Lagrangian bubbles"), (r"lag_params%epsilonb", "Standard deviation scaling for Gaussian smoothing"), (r"lag_params%charwidth", "Domain virtual depth for 2D simulations"), + (r"lag_params%charNz", "Number of cells in virtual depth"), (r"lag_params%valmaxvoid", "Maximum permitted void fraction"), - (r"lag_params%T0", "Initial bubble temperature"), - (r"lag_params%Thost", "Host fluid temperature"), - (r"lag_params%c0", "Initial sound speed"), - (r"lag_params%rho0", "Initial density"), - (r"lag_params%x0", "Initial bubble position"), + (r"lag_params%vel_model", "Model for translational motion"), + (r"lag_params%drag_model", "Drag model for translational motion"), + (r"lag_params%pressure_force", "Enable pressure force for Newton's 2nd law force model"), + (r"lag_params%gravity_force", "Enable gravity force for Newton's 2nd law force model"), + (r"lag_params%input_path", "Path to input file for Lagrangian bubbles"), (r"lag_params%(\w+)", "Lagrangian tracking parameter: {0}"), # chem_params patterns - specific fields first (r"chem_params%diffusion", "Enable species diffusion for chemistry"), diff --git a/toolchain/mfc/test/cases.py b/toolchain/mfc/test/cases.py index 3666b930c3..8d431d056f 100644 --- a/toolchain/mfc/test/cases.py +++ b/toolchain/mfc/test/cases.py @@ -1325,6 +1325,7 @@ def alter_lag_bubbles(dimInfo): "lag_betaC_wrt": "T", "lag_params%write_bubbles": "T", "lag_params%write_bubbles_stats": "T", + "lag_params%write_void_evol": "T", "polytropic": "F", "bub_pp%R0ref": 1.0, "bub_pp%p0ref": 1.0, @@ -1542,6 +1543,8 @@ def foreach_example(): "1D_multispecies_diffusion", "2D_ibm_stl_MFCCharacter", "1D_qbmm", # formatted I/O field overflow on gfortran 12 + "2D_moving_lag_bubs", # adap_dt hangs on reduced grid + "3D_moving_lag_particles", # adap_dt hangs on reduced grid ] if path in casesToSkip: continue diff --git a/toolchain/mfc/test/coverage.py b/toolchain/mfc/test/coverage.py index 429129afc3..eca6f3fae5 100644 --- a/toolchain/mfc/test/coverage.py +++ b/toolchain/mfc/test/coverage.py @@ -44,8 +44,6 @@ # are conservatively included (not in cache -> always runs). # - definitions.py: adding a parameter doesn't affect tests that don't use it; # the PR's .fpp changes trigger the relevant tests via coverage overlap. -# - case_validator.py: validation only affects user-facing error messages for -# invalid configs, not test outputs (tests use valid configs). ALWAYS_RUN_ALL = frozenset( [ "CMakeLists.txt", @@ -58,6 +56,7 @@ "toolchain/mfc/test/case.py", "toolchain/mfc/test/coverage.py", "toolchain/mfc/run/input.py", + "toolchain/mfc/case_validator.py", ] ) diff --git a/toolchain/mfc/test/test_coverage_unit.py b/toolchain/mfc/test/test_coverage_unit.py index 6327a31e17..9b9302f84b 100644 --- a/toolchain/mfc/test/test_coverage_unit.py +++ b/toolchain/mfc/test/test_coverage_unit.py @@ -237,9 +237,8 @@ def test_definitions_py_does_not_trigger_all(self): def test_input_py_triggers_all(self): assert should_run_all_tests({"toolchain/mfc/run/input.py"}) is True - def test_case_validator_does_not_trigger_all(self): - """case_validator.py removed: validation only affects error messages, not test outputs.""" - assert should_run_all_tests({"toolchain/mfc/case_validator.py"}) is False + def test_case_validator_triggers_all(self): + assert should_run_all_tests({"toolchain/mfc/case_validator.py"}) is True def test_cmakelists_triggers_all(self): assert should_run_all_tests({"CMakeLists.txt"}) is True diff --git a/toolchain/modules b/toolchain/modules index d2169ad865..70c048ff70 100644 --- a/toolchain/modules +++ b/toolchain/modules @@ -45,7 +45,7 @@ f-all cpe/25.03 rocm/6.3.1 f-all cray-fftw cray-hdf5 python cmake f-gpu python craype-accel-amd-gfx90a rocprofiler-compute/3.0.0 -famd OLCF Frontier AMD +famd OLCF Frontier AMD famd-all python cmake famd-all cpe/25.09 famd-all PrgEnv-amd @@ -98,7 +98,7 @@ h-all python/3.12 h-cpu gcc/14.2 openmpi/5.0.7 h-gpu UCX_NET_DEVICES="mlx5_4:1,mlx5_7:1,mlx5_8:1,mlx5_9:1,mlx5_10:1,mlx5_13:1,mlx5_14:1,mlx5_15:1" h-gpu cuda/12.9.1 nvhpc/25.9 openmpi/5.0.7 -h-gpu CC=/apps/compilers/nvhpc/25.9/Linux_x86_64/25.9/comm_libs/mpi/bin/mpicc +h-gpu CC=/apps/compilers/nvhpc/25.9/Linux_x86_64/25.9/comm_libs/mpi/bin/mpicc h-gpu CXX=/apps/compilers/nvhpc/25.9/Linux_x86_64/25.9/comm_libs/mpi/bin/mpicxx h-gpu FC=/apps/compilers/nvhpc/25.9/Linux_x86_64/25.9/comm_libs/mpi/bin/mpifort h-gpu NVCOMPILER_COMM_LIBS_HOME=/apps/compilers/nvhpc/25.9/Linux_x86_64/25.9/comm_libs/12.9 diff --git a/toolchain/pyproject.toml b/toolchain/pyproject.toml index fe9b7b7fee..74611d3442 100644 --- a/toolchain/pyproject.toml +++ b/toolchain/pyproject.toml @@ -24,7 +24,7 @@ dependencies = [ # Code Health "typos", "ruff", - "ffmt", + "fprettify", "ansi2txt", # Profiling From ac13779ecd966fdc556acd6842b84c2fbe1d238d Mon Sep 17 00:00:00 2001 From: Spencer Bryngelson Date: Fri, 27 Mar 2026 09:31:35 -0400 Subject: [PATCH 04/14] remove stale toolchain files, apply format fixes --- .ffmt_cache/hashes | 152 +- .gitignore | 1 + misc/runners/common/rebalance-runners.sh | 10 + misc/runners/common/runner-lib.sh | 2 +- misc/runners/phoenix/config.sh | 1 - src/common/include/1dHardcodedIC.fpp | 26 +- src/common/include/2dHardcodedIC.fpp | 171 +- src/common/include/3dHardcodedIC.fpp | 91 +- src/common/include/ExtrusionHardcodedIC.fpp | 111 +- src/common/include/SharedHardcoded.fpp | 9 +- src/common/include/acc_macros.fpp | 13 +- src/common/include/macros.fpp | 38 +- src/common/include/omp_macros.fpp | 33 +- src/common/include/parallel_macros.fpp | 62 +- src/common/m_boundary_common.fpp | 1233 +++---- src/common/m_checker_common.fpp | 26 +- src/common/m_chemistry.fpp | 138 +- src/common/m_compile_specific.f90 | 48 +- src/common/m_constants.fpp | 125 +- src/common/m_delay_file_access.f90 | 16 +- src/common/m_derived_types.fpp | 574 ++- src/common/m_finite_differences.fpp | 94 +- src/common/m_helper.fpp | 340 +- src/common/m_helper_basic.fpp | 76 +- src/common/m_model.fpp | 546 ++- src/common/m_mpi_common.fpp | 1209 +++---- src/common/m_nvtx.f90 | 50 +- src/common/m_phase_change.fpp | 539 ++- src/common/m_precision_select.f90 | 6 +- src/common/m_variables_conversion.fpp | 876 ++--- src/post_process/m_checker.fpp | 15 +- src/post_process/m_data_input.f90 | 352 +- src/post_process/m_data_output.fpp | 1075 +++--- src/post_process/m_derived_variables.fpp | 669 ++-- src/post_process/m_global_parameters.fpp | 485 ++- src/post_process/m_mpi_proxy.fpp | 274 +- src/post_process/m_start_up.fpp | 424 +-- src/post_process/p_main.fpp | 51 +- src/pre_process/m_assign_variables.fpp | 398 +-- src/pre_process/m_boundary_conditions.fpp | 74 +- src/pre_process/m_check_ib_patches.fpp | 246 +- src/pre_process/m_check_patches.fpp | 322 +- src/pre_process/m_checker.fpp | 13 +- src/pre_process/m_data_output.fpp | 357 +- src/pre_process/m_global_parameters.fpp | 493 ++- src/pre_process/m_grid.f90 | 130 +- src/pre_process/m_icpp_patches.fpp | 1126 +++--- src/pre_process/m_initial_condition.fpp | 136 +- src/pre_process/m_mpi_proxy.fpp | 22 +- src/pre_process/m_perturbation.fpp | 150 +- src/pre_process/m_simplex_noise.fpp | 140 +- src/pre_process/m_start_up.fpp | 453 +-- src/pre_process/p_main.f90 | 11 +- src/simulation/include/inline_capillary.fpp | 3 - src/simulation/include/inline_riemann.fpp | 40 +- src/simulation/m_acoustic_src.fpp | 321 +- src/simulation/m_body_forces.fpp | 87 +- src/simulation/m_bubbles.fpp | 755 ++-- src/simulation/m_bubbles_EE.fpp | 147 +- src/simulation/m_bubbles_EL.fpp | 1285 +++---- src/simulation/m_bubbles_EL_kernels.fpp | 402 +-- src/simulation/m_cbc.fpp | 962 ++---- src/simulation/m_checker.fpp | 42 +- src/simulation/m_compute_cbc.fpp | 120 +- src/simulation/m_compute_levelset.fpp | 299 +- src/simulation/m_data_output.fpp | 1126 +++--- src/simulation/m_derived_variables.fpp | 351 +- src/simulation/m_fftw.fpp | 120 +- src/simulation/m_global_parameters.fpp | 815 ++--- src/simulation/m_hyperelastic.fpp | 199 +- src/simulation/m_hypoelastic.fpp | 331 +- src/simulation/m_ib_patches.fpp | 611 ++-- src/simulation/m_ibm.fpp | 545 ++- src/simulation/m_igr.fpp | 1907 +++++----- src/simulation/m_mpi_proxy.fpp | 466 ++- src/simulation/m_muscl.fpp | 177 +- src/simulation/m_pressure_relaxation.fpp | 86 +- src/simulation/m_qbmm.fpp | 1118 +++--- src/simulation/m_rhs.fpp | 1295 +++---- src/simulation/m_riemann_solvers.fpp | 3460 ++++++++----------- src/simulation/m_sim_helpers.fpp | 215 +- src/simulation/m_start_up.fpp | 576 ++- src/simulation/m_surface_tension.fpp | 160 +- src/simulation/m_time_steppers.fpp | 479 ++- src/simulation/m_viscous.fpp | 832 ++--- src/simulation/m_weno.fpp | 1854 +++++----- src/simulation/p_main.fpp | 51 +- src/syscheck/syscheck.fpp | 1 - toolchain/bootstrap/format.sh | 57 +- toolchain/indenter.py | 83 - toolchain/mfc/test/coverage.py | 3 +- toolchain/mfc/test/test_coverage_unit.py | 5 +- toolchain/pyproject.toml | 2 +- 93 files changed, 15061 insertions(+), 20359 deletions(-) delete mode 100644 toolchain/indenter.py diff --git a/.ffmt_cache/hashes b/.ffmt_cache/hashes index 4042be2e0a..bca4027465 100644 --- a/.ffmt_cache/hashes +++ b/.ffmt_cache/hashes @@ -1,45 +1,49 @@ 10103916424136661533 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.YNbWNpe5YF/b/src/common/m_delay_file_access.f90 +10103916424136661533 src/common/m_delay_file_access.f90 10105209818380589033 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.UKcnsjaI4a/b/src/simulation/m_rhs.fpp 10105209818380589033 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.dhTNdaQgUC/b/src/simulation/m_rhs.fpp 10105209818380589033 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.erX3snVzaV/pr.fpp -10164694090871819377 src/common/m_constants.fpp +10105209818380589033 src/simulation/m_rhs.fpp 10547681541613149381 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.QwIzwEBHeU/b/src/simulation/m_compute_cbc.fpp 10547681541613149381 src/simulation/m_compute_cbc.fpp -1095557846383781790 src/pre_process/m_check_ib_patches.fpp 10971775388782938368 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.wXyGiacHHu/b/src/pre_process/m_initial_condition.fpp -11086768803786626714 src/post_process/m_start_up.fpp +10971775388782938368 src/pre_process/m_initial_condition.fpp 1123613300469720145 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.NhWX9QvMiS/b/src/simulation/m_pressure_relaxation.fpp +1123613300469720145 src/simulation/m_pressure_relaxation.fpp 11247271584116519044 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.5zMHO1bIjC/b/src/common/m_helper.fpp 11247271584116519044 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.UKcnsjaI4a/b/src/common/m_helper.fpp +11247271584116519044 src/common/m_helper.fpp 11328367635707741672 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.fRp2cEQ9ib/b/src/pre_process/m_grid.f90 -11432400921178226204 src/simulation/m_ibm.fpp -11506244912723874882 src/simulation/m_muscl.fpp +11328367635707741672 src/pre_process/m_grid.f90 1152355942436141718 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.yvB87OqER1/b/src/post_process/m_derived_variables.fpp +1152355942436141718 src/post_process/m_derived_variables.fpp 1162163686405901254 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.IXCiOAmlT9/b/src/simulation/m_bubbles.fpp 1162163686405901254 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.OMiiuUbkm3/pr.fpp 1162163686405901254 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.UKcnsjaI4a/b/src/simulation/m_bubbles.fpp 1162163686405901254 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.iJz2nMUb3Q/b/src/simulation/m_bubbles.fpp -11671852064421512331 src/simulation/m_bubbles.fpp -11754772473885935152 src/simulation/m_checker.fpp +1162163686405901254 src/simulation/m_bubbles.fpp 1177935745597610133 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.KsaCosfP7l/b/src/simulation/m_surface_tension.fpp +1177935745597610133 src/simulation/m_surface_tension.fpp 11799777124238319529 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.p6vSsTKmTQ/b/src/common/include/ExtrusionHardcodedIC.fpp +11799777124238319529 src/common/include/ExtrusionHardcodedIC.fpp 11844429005742744406 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.p40EgjuOZ4/b/src/common/include/macros.fpp +11844429005742744406 src/common/include/macros.fpp 11886921327637192006 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.rNk4nDDuiA/b/src/pre_process/m_assign_variables.fpp +11886921327637192006 src/pre_process/m_assign_variables.fpp 11928143073477354808 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.ApVsay2rl0/b/src/common/m_chemistry.fpp -12064023182745758546 src/simulation/m_ib_patches.fpp -12065466121610630094 src/simulation/m_qbmm.fpp -1207923543607638260 src/simulation/m_bubbles_EE.fpp +11928143073477354808 src/common/m_chemistry.fpp 12545196112158418286 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.4QCea7ntGd/b/src/common/m_constants.fpp 12545196112158418286 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.UKcnsjaI4a/b/src/common/m_constants.fpp 12545196112158418286 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.pHQFxfnpka/pr.fpp -12810014594504355113 src/common/m_chemistry.fpp -13010474331324068029 src/pre_process/m_check_patches.fpp +12545196112158418286 src/common/m_constants.fpp 1302629992983287045 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.jlX0OxaJWC/b/src/common/include/2dHardcodedIC.fpp +1302629992983287045 src/common/include/2dHardcodedIC.fpp 13379422254557003055 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.tQPN4tJmBS/b/src/common/include/parallel_macros.fpp -13404712065072015994 src/common/include/1dHardcodedIC.fpp -13444615600554412704 src/pre_process/m_initial_condition.fpp +13379422254557003055 src/common/include/parallel_macros.fpp 13737474862947549962 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.wBcCWjwdfh/b/src/common/include/1dHardcodedIC.fpp +13737474862947549962 src/common/include/1dHardcodedIC.fpp 13778436859709422582 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.ZQxwzOCdYP/b/src/pre_process/p_main.f90 +13778436859709422582 src/pre_process/p_main.f90 13798070750203827352 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.9oWQDBRzDO/b/src/simulation/m_data_output.fpp 13798070750203827352 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.BPphaiI0iT/b/src/simulation/m_data_output.fpp 13798070750203827352 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.FyLr7CvpOg/b/src/simulation/m_data_output.fpp @@ -48,14 +52,14 @@ 13798070750203827352 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.l4geGiBejN/b/src/simulation/m_data_output.fpp 13798070750203827352 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.mAWaP5Yqf6/pr.fpp 13798070750203827352 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.nW8Pq43Vvf/b/src/simulation/m_data_output.fpp -14038700267823699434 src/simulation/m_hypoelastic.fpp 14047356244834746872 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.xVza69symx/b/src/simulation/m_hyperelastic.fpp +14047356244834746872 src/simulation/m_hyperelastic.fpp 14218853748338101619 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.F8v3PuEaEB/b/src/common/m_checker_common.fpp +14218853748338101619 src/common/m_checker_common.fpp 14257682203105278348 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.CZPMCJMBJW/b/src/common/m_phase_change.fpp -14264799885104244614 src/common/m_mpi_common.fpp +14257682203105278348 src/common/m_phase_change.fpp 14450336682570067792 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.1BExP6R8f9/b/src/simulation/m_acoustic_src.fpp -1453706485316947653 src/common/include/2dHardcodedIC.fpp -14633053619551717675 src/common/m_helper_basic.fpp +14450336682570067792 src/simulation/m_acoustic_src.fpp 14636237826800124746 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.1geSh90r6o/b/src/pre_process/m_global_parameters.fpp 14636237826800124746 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.1nYoCE2Z93/b/src/pre_process/m_global_parameters.fpp 14636237826800124746 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.CF4oy4IF0z/b/src/pre_process/m_global_parameters.fpp @@ -65,127 +69,127 @@ 14636237826800124746 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.UKcnsjaI4a/b/src/pre_process/m_global_parameters.fpp 14636237826800124746 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.ketcpZUBhe/b/src/pre_process/m_global_parameters.fpp 14636237826800124746 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.kfAB4MRB1T/b/src/pre_process/m_global_parameters.fpp +14636237826800124746 src/pre_process/m_global_parameters.fpp 14739644014569295158 src/common/include/SharedHardcoded.fpp 14954376616734417912 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.5wobk7aEG0/b/src/simulation/p_main.fpp +14954376616734417912 src/simulation/p_main.fpp 14999475271112169381 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.zed9MGw8lu/b/src/common/include/acc_macros.fpp 14999475271112169381 src/common/include/acc_macros.fpp 15049314966727887552 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.foNVQzeyQX/b/src/pre_process/m_simplex_noise.fpp +15049314966727887552 src/pre_process/m_simplex_noise.fpp 15110474130912937443 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.EOjTtcOp00/b/src/post_process/m_checker.fpp -15255403987111061930 src/simulation/m_igr.fpp -15338984378825505953 src/simulation/m_global_parameters.fpp +15110474130912937443 src/post_process/m_checker.fpp 15343341342992294043 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.ZE1xLrrD4M/b/src/simulation/m_body_forces.fpp +15343341342992294043 src/simulation/m_body_forces.fpp 15508824445404703824 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.DJdV0uDXkk/pr.fpp 15508824445404703824 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.UKcnsjaI4a/b/src/common/m_helper_basic.fpp 15508824445404703824 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.dpV8UkalaA/b/src/common/m_helper_basic.fpp +15508824445404703824 src/common/m_helper_basic.fpp 15573111593524903869 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.7rXfBv7i7f/b/src/simulation/m_qbmm.fpp -15615432817640526542 src/post_process/m_checker.fpp +15573111593524903869 src/simulation/m_qbmm.fpp 15811265556360623843 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.6h5PDEc3xX/b/src/simulation/include/inline_capillary.fpp 15811265556360623843 src/simulation/include/inline_capillary.fpp -15842852871903378886 src/simulation/m_bubbles_EL.fpp 15941699165887750367 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.S0h68IhVLd/b/src/common/m_precision_select.f90 -16125650575599718923 src/common/include/macros.fpp -16165252533980060148 src/common/m_phase_change.fpp -16572865122016119827 src/post_process/p_main.fpp +15941699165887750367 src/common/m_precision_select.f90 +16362615099332163096 src/simulation/m_data_output.fpp 16590815127468205830 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.wqmnQUCDbi/b/src/common/include/omp_macros.fpp 16590815127468205830 src/common/include/omp_macros.fpp -1663788838675579049 src/pre_process/m_perturbation.fpp 16666864254209086704 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.4QVjyhlBbR/b/src/simulation/m_ib_patches.fpp 16666864254209086704 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.EKTuvrJmZf/pr.fpp 16666864254209086704 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.UKcnsjaI4a/b/src/simulation/m_ib_patches.fpp -16667441275814153857 src/common/m_derived_types.fpp -1668812924145503864 src/pre_process/m_icpp_patches.fpp +16666864254209086704 src/simulation/m_ib_patches.fpp 16819660696315222173 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.wZ5g7DS74M/b/src/simulation/include/inline_riemann.fpp 16819660696315222173 src/simulation/include/inline_riemann.fpp 16863576169260976215 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.BtoC8sntqC/b/src/common/m_boundary_common.fpp 16863576169260976215 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.UKcnsjaI4a/b/src/common/m_boundary_common.fpp 16863576169260976215 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.WV8J0UVWWc/pr.fpp 16863576169260976215 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.tPbHdHuGzL/b/src/common/m_boundary_common.fpp -16921026541737365190 src/pre_process/m_data_output.fpp -17002367283301422912 src/post_process/m_data_output.fpp -17058020954763061075 src/simulation/m_derived_variables.fpp +16863576169260976215 src/common/m_boundary_common.fpp 17150360143499547248 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.GwPH1PymWU/b/src/pre_process/m_mpi_proxy.fpp 17150360143499547248 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.UKcnsjaI4a/b/src/pre_process/m_mpi_proxy.fpp +17150360143499547248 src/pre_process/m_mpi_proxy.fpp 17374991166589206306 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.CKefDZblI8/b/src/simulation/m_muscl.fpp 17374991166589206306 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.UKcnsjaI4a/b/src/simulation/m_muscl.fpp 17374991166589206306 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.bThVXwVjHQ/pr.fpp -17474896583037663449 src/common/m_boundary_common.fpp +17374991166589206306 src/simulation/m_muscl.fpp 17475717397114845816 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.7vhQq2kOXS/b/src/pre_process/m_check_ib_patches.fpp +17475717397114845816 src/pre_process/m_check_ib_patches.fpp 17489851833420935241 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.UKcnsjaI4a/b/src/pre_process/m_start_up.fpp 17489851833420935241 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.jKReiOTmE3/pr.fpp 17489851833420935241 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.pN7wf0OOXk/b/src/pre_process/m_start_up.fpp +17489851833420935241 src/pre_process/m_start_up.fpp 17729534019838315074 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.5q1Y270gxY/b/src/post_process/m_global_parameters.fpp 17729534019838315074 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.UKcnsjaI4a/b/src/post_process/m_global_parameters.fpp 17729534019838315074 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.VmGqKfWL4e/b/src/post_process/m_global_parameters.fpp 17729534019838315074 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.fEo4jGidK0/pr.fpp -17747955368322546147 src/simulation/m_time_steppers.fpp -17924857709100145307 src/simulation/m_mpi_proxy.fpp -17932981799378708392 src/common/m_variables_conversion.fpp +17729534019838315074 src/post_process/m_global_parameters.fpp 17939937579085231691 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.1FlGgFgoLk/b/src/simulation/m_riemann_solvers.fpp +17939937579085231691 src/simulation/m_riemann_solvers.fpp 17952081853197839750 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.FM3hyTJcC1/b/src/post_process/p_main.fpp +17952081853197839750 src/post_process/p_main.fpp 18080888037678917285 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.UOicaksnAM/b/src/common/m_variables_conversion.fpp +18080888037678917285 src/common/m_variables_conversion.fpp 18166547160227944552 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.04SRuU4uDG/b/src/simulation/m_sim_helpers.fpp 18166547160227944552 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.UH5isBDNLP/pr.fpp 18166547160227944552 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.UKcnsjaI4a/b/src/simulation/m_sim_helpers.fpp -18206858153626918909 src/post_process/m_mpi_proxy.fpp -18303915459629736231 src/simulation/m_bubbles_EL_kernels.fpp +18166547160227944552 src/simulation/m_sim_helpers.fpp 18308153827535525888 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.LcZmBtbXI5/b/src/simulation/m_time_steppers.fpp 18308153827535525888 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.TMdfrAiUad/b/src/simulation/m_time_steppers.fpp 18308153827535525888 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.UKcnsjaI4a/b/src/simulation/m_time_steppers.fpp 18308153827535525888 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.zBXQoIJ9Ns/pr.fpp +18308153827535525888 src/simulation/m_time_steppers.fpp 18424647052757242046 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.90F2SuKdN3/b/src/simulation/m_igr.fpp -1878831292940939747 src/pre_process/m_boundary_conditions.fpp -1956361042530399503 src/pre_process/m_start_up.fpp +18424647052757242046 src/simulation/m_igr.fpp 2089934286629799065 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.UKcnsjaI4a/b/src/simulation/m_bubbles_EE.fpp 2089934286629799065 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.ehVOiqSEna/b/src/simulation/m_bubbles_EE.fpp 2089934286629799065 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.mGbGtZnmMH/pr.fpp -2092302292714238550 src/pre_process/m_checker.fpp +2089934286629799065 src/simulation/m_bubbles_EE.fpp 2179692337769865707 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.UKcnsjaI4a/b/src/common/m_derived_types.fpp 2179692337769865707 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.ahYsbo4OkN/b/src/common/m_derived_types.fpp 2179692337769865707 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.u43jNT6Y9N/pr.fpp 2179692337769865707 /tmp/pr_derived.fpp +2179692337769865707 src/common/m_derived_types.fpp 2180900767736986011 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.2wyV79dZFt/pr.fpp 2180900767736986011 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.9ywat4IE5E/b/src/simulation/m_ibm.fpp 2180900767736986011 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.UKcnsjaI4a/b/src/simulation/m_ibm.fpp +2180900767736986011 src/simulation/m_ibm.fpp 2238355401608193277 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.Xeee1w2Np4/b/src/post_process/m_start_up.fpp +2238355401608193277 src/post_process/m_start_up.fpp 2246088494097541240 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.6XVxKq1Gls/b/src/simulation/m_mpi_proxy.fpp 2246088494097541240 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.UKcnsjaI4a/b/src/simulation/m_mpi_proxy.fpp 2246088494097541240 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.bFnMb9Yj6X/pr.fpp +2246088494097541240 src/simulation/m_mpi_proxy.fpp 2275015924369440500 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.GyRQmToKip/b/src/simulation/m_bubbles_EL.fpp 2275015924369440500 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.QWfhmzAUhW/b/src/simulation/m_bubbles_EL.fpp 2275015924369440500 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.UKcnsjaI4a/b/src/simulation/m_bubbles_EL.fpp 2275015924369440500 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.sq9eLcwlqR/pr.fpp +2275015924369440500 src/simulation/m_bubbles_EL.fpp 2431245550782554100 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.IwOd4FjXKf/b/src/simulation/m_viscous.fpp -246952844057435839 src/pre_process/p_main.f90 +2431245550782554100 src/simulation/m_viscous.fpp 2525268250784412532 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.2moDi289m2/b/src/simulation/m_compute_levelset.fpp 2525268250784412532 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.UKcnsjaI4a/b/src/simulation/m_compute_levelset.fpp 2525268250784412532 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.fNlW6mq81s/pr.fpp +2525268250784412532 src/simulation/m_compute_levelset.fpp 2551148861500766043 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.61vHeCBp3z/b/src/common/m_nvtx.f90 -2558082555087995757 src/pre_process/m_simplex_noise.fpp -2580392981306692199 src/common/m_checker_common.fpp -260403609643327097 src/common/m_delay_file_access.f90 -3177637622633093141 src/simulation/m_pressure_relaxation.fpp +2551148861500766043 src/common/m_nvtx.f90 330369965658929155 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.l3vlWwFtc6/b/src/pre_process/m_checker.fpp +330369965658929155 src/pre_process/m_checker.fpp 3322818355154981622 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.zxtBRdLiDM/b/src/simulation/m_derived_variables.fpp -3420663690071121996 src/simulation/m_rhs.fpp -370939259527769189 src/pre_process/m_grid.f90 +3322818355154981622 src/simulation/m_derived_variables.fpp 3852216218768625740 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.ON0VZhypev/b/src/common/m_compile_specific.f90 +3852216218768625740 src/common/m_compile_specific.f90 4271870002582174631 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.h1I7f50x8l/b/src/post_process/m_mpi_proxy.fpp +4271870002582174631 src/post_process/m_mpi_proxy.fpp 4316649851528138914 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.vJ4faZHES0/b/src/post_process/m_data_input.f90 -4318428400001911186 src/common/m_nvtx.f90 +4316649851528138914 src/post_process/m_data_input.f90 47037120222980462 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.oFDAmDeZN7/b/src/simulation/m_fftw.fpp -4731308583521756677 src/pre_process/m_assign_variables.fpp -4769787692054280401 src/common/m_precision_select.f90 -4898418582330870284 src/simulation/m_data_output.fpp +47037120222980462 src/simulation/m_fftw.fpp 4993379909229078812 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.RprlXGCudJ/b/src/simulation/m_checker.fpp -5143161135957632347 src/simulation/m_weno.fpp -541372253676220467 src/common/include/ExtrusionHardcodedIC.fpp -5442684352742972305 src/simulation/m_compute_levelset.fpp -5568409634376181500 src/common/m_compile_specific.f90 -5650096065662263890 src/simulation/m_cbc.fpp -5725362251714205830 src/post_process/m_global_parameters.fpp +4993379909229078812 src/simulation/m_checker.fpp 5871828278470799827 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.hpU6ltVEIS/b/src/syscheck/syscheck.fpp 5871828278470799827 src/syscheck/syscheck.fpp 5928207121067860413 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.mpy7h1Q0k4/b/src/common/m_model.fpp +5928207121067860413 src/common/m_model.fpp 6137784461014282246 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.21jzdeIFZA/b/src/common/include/3dHardcodedIC.fpp 6137784461014282246 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.Ngtiv1vOCD/b/src/common/include/3dHardcodedIC.fpp 6137784461014282246 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.UKcnsjaI4a/b/src/common/include/3dHardcodedIC.fpp @@ -194,56 +198,52 @@ 6137784461014282246 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.ox5RwzwCDq/b/src/common/include/3dHardcodedIC.fpp 6137784461014282246 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.uHW6w2dKmd/b/src/common/include/3dHardcodedIC.fpp 6137784461014282246 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.unuGVybPf5/b/src/common/include/3dHardcodedIC.fpp -6211238564233770195 src/simulation/m_surface_tension.fpp +6137784461014282246 src/common/include/3dHardcodedIC.fpp 6240714802147004944 src/common/include/shared_parallel_macros.fpp -6266670715849348639 src/common/m_finite_differences.fpp -6276978915188096958 src/common/include/3dHardcodedIC.fpp -6310967954464841129 src/simulation/m_sim_helpers.fpp -6471948232201815663 src/common/include/parallel_macros.fpp -6927376021528420031 src/simulation/m_fftw.fpp 6938669613291679776 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.4o4LVAkqMP/b/src/common/m_finite_differences.fpp -6949123019557822621 src/common/m_helper.fpp +6938669613291679776 src/common/m_finite_differences.fpp 732149268206108348 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.2J0Z5N2qcF/b/src/simulation/m_weno.fpp 732149268206108348 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.2QXPygy8q1/pr_1646504.fpp 732149268206108348 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.D9KOPlN1LD/pr.fpp 732149268206108348 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.UKcnsjaI4a/b/src/simulation/m_weno.fpp 732149268206108348 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.xwrbhmKSBn/b/src/simulation/m_weno.fpp -7447400852528884671 src/post_process/m_derived_variables.fpp -7471514455985910739 src/simulation/m_start_up.fpp -7477197243973776229 src/simulation/m_riemann_solvers.fpp +732149268206108348 src/simulation/m_weno.fpp 7530723425281110009 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.A857NqLisR/b/src/simulation/m_cbc.fpp +7530723425281110009 src/simulation/m_cbc.fpp 7580365803335695134 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.WMlJs7jEPw/b/src/simulation/m_hypoelastic.fpp -7591413184552042268 src/simulation/m_hyperelastic.fpp +7580365803335695134 src/simulation/m_hypoelastic.fpp 7723221865542041495 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.svITM8tMXS/b/src/pre_process/m_icpp_patches.fpp +7723221865542041495 src/pre_process/m_icpp_patches.fpp 7737322002952828776 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.UKcnsjaI4a/b/src/simulation/m_start_up.fpp 7737322002952828776 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.aYeUsTe6vQ/b/src/simulation/m_start_up.fpp 7737322002952828776 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.mGRII3r92Q/pr.fpp -8066276099644435316 src/post_process/m_data_input.f90 +7737322002952828776 src/simulation/m_start_up.fpp 8093344263636711422 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.CtULDFfiWw/pr.fpp 8093344263636711422 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.UKcnsjaI4a/b/src/simulation/m_bubbles_EL_kernels.fpp 8093344263636711422 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.u1zFhDbdg8/b/src/simulation/m_bubbles_EL_kernels.fpp +8093344263636711422 src/simulation/m_bubbles_EL_kernels.fpp 8258277022714838383 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.7MRd899dQW/b/src/simulation/m_global_parameters.fpp 8258277022714838383 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.Du4hJUphgy/b/src/simulation/m_global_parameters.fpp 8258277022714838383 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.M29f3SMb5C/pr.fpp 8258277022714838383 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.UKcnsjaI4a/b/src/simulation/m_global_parameters.fpp 8258277022714838383 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.cJ15SrprHl/b/src/simulation/m_global_parameters.fpp 8258277022714838383 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.yxQ0X6fv0o/b/src/simulation/m_global_parameters.fpp +8258277022714838383 src/simulation/m_global_parameters.fpp 8373688306336592140 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.tVW0Ag4HFB/b/src/pre_process/m_data_output.fpp -8384884432422989494 src/simulation/m_body_forces.fpp +8373688306336592140 src/pre_process/m_data_output.fpp 8639686218598077333 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.fo85j8vdro/b/src/post_process/m_data_output.fpp -8655330804873794929 src/pre_process/m_mpi_proxy.fpp -8755329155192764099 src/pre_process/m_global_parameters.fpp +8639686218598077333 src/post_process/m_data_output.fpp 8835068673407070922 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.qfglItrwDK/b/src/pre_process/m_boundary_conditions.fpp +8835068673407070922 src/pre_process/m_boundary_conditions.fpp 8870602128241043159 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.V53atDEagj/b/src/pre_process/m_check_patches.fpp -891279443899891679 src/simulation/m_acoustic_src.fpp +8870602128241043159 src/pre_process/m_check_patches.fpp 9370663205287462789 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.zoRoHcwA35/b/src/pre_process/m_perturbation.fpp -9374565448212229788 src/simulation/m_viscous.fpp -9419299607787709748 src/simulation/p_main.fpp +9370663205287462789 src/pre_process/m_perturbation.fpp 9606486790139625748 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.QCod6CiPeT/b/src/common/m_mpi_common.fpp 9606486790139625748 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.UKcnsjaI4a/b/src/common/m_mpi_common.fpp 9606486790139625748 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.Z9FK1bV094/b/src/common/m_mpi_common.fpp 9606486790139625748 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.dF9qaNUJjz/b/src/common/m_mpi_common.fpp 9606486790139625748 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.j1H2hZqcGd/pr.fpp 9606486790139625748 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.sBmtXp00OQ/b/src/common/m_mpi_common.fpp -9680365827169577304 src/common/m_model.fpp +9606486790139625748 src/common/m_mpi_common.fpp 9812035701611855679 /tmp/test_ffmt.fpp diff --git a/.gitignore b/.gitignore index 664b6c3083..aba54411e1 100644 --- a/.gitignore +++ b/.gitignore @@ -113,3 +113,4 @@ benchmarks/*.png cce_*/ cce_*.log run_cce_*.sh +.ffmt_cache/ diff --git a/misc/runners/common/rebalance-runners.sh b/misc/runners/common/rebalance-runners.sh index 20a20b0f7c..e94047ff85 100644 --- a/misc/runners/common/rebalance-runners.sh +++ b/misc/runners/common/rebalance-runners.sh @@ -106,6 +106,16 @@ done # Add offline runners to be placed for i in "${offline[@]}"; do to_place+=("offline $i"); done +# Shuffle to_place so sequential runner numbers spread across nodes +# (avoids overloading one node when jobs arrive in number order) +shuffled=() +while [ ${#to_place[@]} -gt 0 ]; do + rand=$(( RANDOM % ${#to_place[@]} )) + shuffled+=("${to_place[$rand]}") + to_place=("${to_place[@]:0:$rand}" "${to_place[@]:$((rand+1))}") +done +to_place=("${shuffled[@]}") + # Assign to underloaded nodes moves=() for entry in "${to_place[@]}"; do diff --git a/misc/runners/common/runner-lib.sh b/misc/runners/common/runner-lib.sh index 810e1b8301..21b7ce7083 100755 --- a/misc/runners/common/runner-lib.sh +++ b/misc/runners/common/runner-lib.sh @@ -21,7 +21,7 @@ gh_list_runners() { # Get a registration token for new runners. gh_registration_token() { - gh api "orgs/$ORG/actions/runners/registration-token" --jq .token + gh api "orgs/$ORG/actions/runners/registration-token" -X POST --jq .token } # Get the latest runner binary version. diff --git a/misc/runners/phoenix/config.sh b/misc/runners/phoenix/config.sh index 11826019c2..8931219fbe 100755 --- a/misc/runners/phoenix/config.sh +++ b/misc/runners/phoenix/config.sh @@ -15,7 +15,6 @@ SSH_OPTS="-o ConnectTimeout=5" # Parent directories containing actions-runner-*/ installations on shared storage. RUNNER_PARENT_DIRS=( - /storage/scratch1/6/sbryngelson3/mfc-runners /storage/project/r-sbryngelson3-0/sbryngelson3/mfc-runners-2 ) diff --git a/src/common/include/1dHardcodedIC.fpp b/src/common/include/1dHardcodedIC.fpp index 4359528a3f..80b7e9edcb 100644 --- a/src/common/include/1dHardcodedIC.fpp +++ b/src/common/include/1dHardcodedIC.fpp @@ -5,7 +5,7 @@ #:def Hardcoded1D() select case (patch_icpp(patch_id)%hcid) - case (150) ! 1D Smooth Alfven Case for MHD + case (150) ! 1D Smooth Alfven Case for MHD ! velocity q_prim_vf(momxb + 1)%sf(i, 0, 0) = 0.1_wp*sin(2._wp*pi*x_cc(i)) q_prim_vf(momxb + 2)%sf(i, 0, 0) = 0.1_wp*cos(2._wp*pi*x_cc(i)) @@ -13,23 +13,20 @@ ! magnetic field q_prim_vf(B_idx%end - 1)%sf(i, 0, 0) = 0.1_wp*sin(2._wp*pi*x_cc(i)) q_prim_vf(B_idx%end)%sf(i, 0, 0) = 0.1_wp*cos(2._wp*pi*x_cc(i)) - case (170) - ! This hardcoded case can be used to start a simulation with initial conditions given from a known 1D profile (e.g. Cantera, SDtoolbox) + ! This hardcoded case can be used to start a simulation with initial conditions given from a known 1D profile (e.g. Cantera, + ! SDtoolbox) @: HardcodedReadValues() - case (180) - ! This is patch is hard-coded for test suite optimization used in the - ! 1D_shuoser cases: "patch_icpp(2)%alpha_rho(1)": "1 + 0.2*sin(5*x)" + ! This is patch is hard-coded for test suite optimization used in the 1D_shuoser cases: "patch_icpp(2)%alpha_rho(1)": "1 + + ! 0.2*sin(5*x)" if (patch_id == 2) then q_prim_vf(contxb + 0)%sf(i, 0, 0) = 1 + 0.2*sin(5*x_cc(i)) end if - case (181) - ! This is patch is hard-coded for test suite optimization used in the - ! 1D_titarevtorro cases: "patch_icpp(2)%alpha_rho(1)": "1 + 0.1*sin(20*x*pi)" + ! This is patch is hard-coded for test suite optimization used in the 1D_titarevtorro cases: "patch_icpp(2)%alpha_rho(1)": + ! "1 + 0.1*sin(20*x*pi)" q_prim_vf(contxb + 0)%sf(i, 0, 0) = 1 + 0.1*sin(20*x_cc(i)*pi) - case (182) ! This patch is a hard-coded for test suite optimization (multiple component diffusion) x_mid_diffu = 0.05_wp/2.0_wp @@ -51,16 +48,11 @@ temp = (320.0_wp - 1350.0_wp)*profile_shape + 1350.0_wp - molar_mass_inv = y1/31.998_wp + & - y2/18.01508_wp + & - y3/16.04256_wp + & - y4/28.0134_wp + molar_mass_inv = y1/31.998_wp + y2/18.01508_wp + y3/16.04256_wp + y4/28.0134_wp q_prim_vf(contxb)%sf(i, 0, 0) = 1.01325_wp*(10.0_wp)**5/(temp*8.3144626_wp*1000.0_wp*molar_mass_inv) - case default call s_int_to_str(patch_id, iStr) - call s_mpi_abort("Invalid hcid specified for patch "//trim(iStr)) + call s_mpi_abort("Invalid hcid specified for patch " // trim(iStr)) end select - #:enddef diff --git a/src/common/include/2dHardcodedIC.fpp b/src/common/include/2dHardcodedIC.fpp index a35633bca1..a39e68b662 100644 --- a/src/common/include/2dHardcodedIC.fpp +++ b/src/common/include/2dHardcodedIC.fpp @@ -6,7 +6,6 @@ real(wp) :: factor real(wp) :: r0, alpha, r2 real(wp) :: sinA, cosA - real(wp) :: r_sq ! # 207 @@ -18,9 +17,7 @@ #:enddef #:def Hardcoded2D() - - select case (patch_icpp(patch_id)%hcid) ! 2D_hardcoded_ic example case - + select case (patch_icpp(patch_id)%hcid) ! 2D_hardcoded_ic example case case (200) if (y_cc(j) <= (-x_cc(i)**3 + 1)**(1._wp/3._wp)) then ! Volume Fractions @@ -32,7 +29,7 @@ ! Pressure q_prim_vf(E_idx)%sf(i, j, 0) = 1000._wp end if - case (202) ! Gresho vortex (Gouasmi et al 2022 JCP) + case (202) ! Gresho vortex (Gouasmi et al 2022 JCP) r = ((x_cc(i) - 0.5_wp)**2 + (y_cc(j) - 0.5_wp)**2)**0.5_wp rmax = 0.2_wp @@ -53,7 +50,7 @@ q_prim_vf(momxe)%sf(i, j, 0) = 0._wp q_prim_vf(E_idx)%sf(i, j, 0) = p0 + umax**2*(-2 + 4*log(2._wp)) end if - case (203) ! Gresho vortex (Gouasmi et al 2022 JCP) with density correction + case (203) ! Gresho vortex (Gouasmi et al 2022 JCP) with density correction r = ((x_cc(i) - 0.5_wp)**2._wp + (y_cc(j) - 0.5_wp)**2)**0.5_wp rmax = 0.2_wp @@ -76,7 +73,7 @@ end if q_prim_vf(contxb)%sf(i, j, 0) = q_prim_vf(E_idx)%sf(i, j, 0)**(1._wp/gam) - case (204) ! Rayleigh-Taylor instability + case (204) ! Rayleigh-Taylor instability rhoH = 3._wp rhoL = 1._wp pRef = 1.e5_wp @@ -107,11 +104,10 @@ pInt = pref + rhoH*9.81_wp*(1.2_wp - intH) q_prim_vf(E_idx)%sf(i, j, 0) = pInt + rhoL*9.81_wp*(intH - y_cc(j)) end if - - case (205) ! 2D lung wave interaction problem - h = 0.0_wp !non dim origin y - lam = 1.0_wp !non dim lambda - amp = patch_icpp(patch_id)%a(2) !to be changed later! !non dim amplitude + case (205) ! 2D lung wave interaction problem + h = 0.0_wp ! non dim origin y + lam = 1.0_wp ! non dim lambda + amp = patch_icpp(patch_id)%a(2) ! to be changed later! !non dim amplitude intH = amp*sin(2*pi*x_cc(i)/lam - pi/2) + h @@ -122,30 +118,26 @@ q_prim_vf(advxb)%sf(i, j, 0) = patch_icpp(1)%alpha(1) q_prim_vf(advxe)%sf(i, j, 0) = patch_icpp(1)%alpha(2) end if - - case (206) ! 2D lung wave interaction problem - horizontal domain - h = 0.0_wp !non dim origin y - lam = 1.0_wp !non dim lambda + case (206) ! 2D lung wave interaction problem - horizontal domain + h = 0.0_wp ! non dim origin y + lam = 1.0_wp ! non dim lambda amp = patch_icpp(patch_id)%a(2) intL = amp*sin(2*pi*y_cc(j)/lam - pi/2) + h - if (x_cc(i) > intL) then !this is the liquid + if (x_cc(i) > intL) then ! this is the liquid q_prim_vf(contxb)%sf(i, j, 0) = patch_icpp(1)%alpha_rho(1) q_prim_vf(contxe)%sf(i, j, 0) = patch_icpp(1)%alpha_rho(2) q_prim_vf(E_idx)%sf(i, j, 0) = patch_icpp(1)%pres q_prim_vf(advxb)%sf(i, j, 0) = patch_icpp(1)%alpha(1) q_prim_vf(advxe)%sf(i, j, 0) = patch_icpp(1)%alpha(2) end if - - case (207) ! Kelvin Helmholtz Instability + case (207) ! Kelvin Helmholtz Instability sigma = 0.05_wp/sqrt(2.0_wp) gauss1 = exp(-(y_cc(j) - 0.75_wp)**2/(2.0_wp*sigma**2)) gauss2 = exp(-(y_cc(j) - 0.25_wp)**2/(2.0_wp*sigma**2)) - q_prim_vf(momxb + 1)%sf(i, j, 0) = & - 0.1_wp*sin(4.0_wp*pi*x_cc(i))*(gauss1 + gauss2) - - case (208) ! Richtmeyer Meshkov Instability + q_prim_vf(momxb + 1)%sf(i, j, 0) = 0.1_wp*sin(4.0_wp*pi*x_cc(i))*(gauss1 + gauss2) + case (208) ! Richtmeyer Meshkov Instability lam = 1.0_wp eps = 1.0e-6_wp ei = 5.0_wp @@ -160,25 +152,20 @@ q_prim_vf(advxb)%sf(i, j, 0) = alpha_sf6 q_prim_vf(advxe)%sf(i, j, 0) = alpha_air end if - - case (250) ! MHD Orszag-Tang vortex - ! gamma = 5/3 - ! rho = 25/(36*pi) - ! p = 5/(12*pi) - ! v = (-sin(2*pi*y), sin(2*pi*x), 0) - ! B = (-sin(2*pi*y)/sqrt(4*pi), sin(4*pi*x)/sqrt(4*pi), 0) + case (250) ! MHD Orszag-Tang vortex + ! gamma = 5/3 rho = 25/(36*pi) p = 5/(12*pi) v = (-sin(2*pi*y), sin(2*pi*x), 0) B = (-sin(2*pi*y)/sqrt(4*pi), + ! sin(4*pi*x)/sqrt(4*pi), 0) q_prim_vf(momxb)%sf(i, j, 0) = -sin(2._wp*pi*y_cc(j)) q_prim_vf(momxb + 1)%sf(i, j, 0) = sin(2._wp*pi*x_cc(i)) q_prim_vf(B_idx%beg)%sf(i, j, 0) = -sin(2._wp*pi*y_cc(j))/sqrt(4._wp*pi) q_prim_vf(B_idx%beg + 1)%sf(i, j, 0) = sin(4._wp*pi*x_cc(i))/sqrt(4._wp*pi) - - case (251) ! RMHD Cylindrical Blast Wave [Mignone, 2006: Section 4.3.1] + case (251) ! RMHD Cylindrical Blast Wave [Mignone, 2006: Section 4.3.1] if (x_cc(i)**2 + y_cc(j)**2 < 0.08_wp**2) then q_prim_vf(contxb)%sf(i, j, 0) = 0.01 q_prim_vf(E_idx)%sf(i, j, 0) = 1.0 - elseif (x_cc(i)**2 + y_cc(j)**2 <= 1._wp**2) then + else if (x_cc(i)**2 + y_cc(j)**2 <= 1._wp**2) then ! Linear interpolation between r=0.08 and r=1.0 factor = (1.0_wp - sqrt(x_cc(i)**2 + y_cc(j)**2))/(1.0_wp - 0.08_wp) q_prim_vf(contxb)%sf(i, j, 0) = 0.01_wp*factor + 1.e-4_wp*(1.0_wp - factor) @@ -189,29 +176,21 @@ end if ! case 252 is for the 2D MHD Rotor problem - case (252) ! 2D MHD Rotor Problem - ! Ambient conditions are set in the JSON file. - ! This case imposes the dense, rotating cylinder. + case (252) ! 2D MHD Rotor Problem + ! Ambient conditions are set in the JSON file. This case imposes the dense, rotating cylinder. ! - ! gamma = 1.4 - ! Ambient medium (r > 0.1): - ! rho = 1, p = 1, v = 0, B = (1,0,0) - ! Rotor (r <= 0.1): - ! rho = 10, p = 1 - ! v has angular velocity w=20, giving v_tan=2 at r=0.1 + ! gamma = 1.4 Ambient medium (r > 0.1): rho = 1, p = 1, v = 0, B = (1,0,0) Rotor (r <= 0.1): rho = 10, p = 1 v has angular + ! velocity w=20, giving v_tan=2 at r=0.1 ! Calculate distance squared from the center r_sq = (x_cc(i) - 0.5_wp)**2 + (y_cc(j) - 0.5_wp)**2 ! inner radius of 0.1 if (r_sq <= 0.1**2) then - ! -- Inside the rotor -- - ! Set density uniformly to 10 + ! -- Inside the rotor -- Set density uniformly to 10 q_prim_vf(contxb)%sf(i, j, 0) = 10._wp - ! Set vup constant rotation of rate v=2 - ! v_x = -omega * (y - y_c) - ! v_y = omega * (x - x_c) + ! Set vup constant rotation of rate v=2 v_x = -omega * (y - y_c) v_y = omega * (x - x_c) q_prim_vf(momxb)%sf(i, j, 0) = -20._wp*(y_cc(j) - 0.5_wp) q_prim_vf(momxb + 1)%sf(i, j, 0) = 20._wp*(x_cc(i) - 0.5_wp) @@ -223,11 +202,9 @@ q_prim_vf(momxb)%sf(i, j, 0) = -(2._wp/sqrt(r_sq))*(y_cc(j) - 0.5_wp)*(0.115_wp - sqrt(r_sq))/(0.015_wp) q_prim_vf(momxb + 1)%sf(i, j, 0) = (2._wp/sqrt(r_sq))*(x_cc(i) - 0.5_wp)*(0.115_wp - sqrt(r_sq))/(0.015_wp) end if - - case (253) ! MHD Smooth Magnetic Vortex - ! Section 5.2 of - ! Implicit hybridized discontinuous Galerkin methods for compressible magnetohydrodynamics - ! C. Ciuca, P. Fernandez, A. Christophe, N.C. Nguyen, J. Peraire + case (253) ! MHD Smooth Magnetic Vortex + ! Section 5.2 of Implicit hybridized discontinuous Galerkin methods for compressible magnetohydrodynamics C. Ciuca, P. + ! Fernandez, A. Christophe, N.C. Nguyen, J. Peraire ! velocity q_prim_vf(momxb)%sf(i, j, 0) = 1._wp - (y_cc(j)*exp(1 - (x_cc(i)**2 + y_cc(j)**2))/(2.*pi)) @@ -238,13 +215,12 @@ q_prim_vf(B_idx%beg + 1)%sf(i, j, 0) = x_cc(i)*exp(1 - (x_cc(i)**2 + y_cc(j)**2))/(2.*pi) ! pressure - q_prim_vf(E_idx)%sf(i, j, 0) = 1._wp + (1 - 2._wp*(x_cc(i)**2 + y_cc(j)**2))*exp(1 - (x_cc(i)**2 + y_cc(j)**2))/((2._wp*pi)**3) - + q_prim_vf(E_idx)%sf(i, j, & + & 0) = 1._wp + (1 - 2._wp*(x_cc(i)**2 + y_cc(j)**2))*exp(1 - (x_cc(i)**2 + y_cc(j)**2))/((2._wp*pi)**3) case (260) ! Gaussian Divergence Pulse - ! Bx(x) = 1 + C * erf((x-0.5)/σ) - ! ⇒ ∂Bx/∂x = C * (2/√π) * exp[-((x-0.5)/σ)**2] * (1/σ) - ! Choose C = ε * σ * √π / 2 ⇒ ∂Bx/∂x = ε * exp[-((x-0.5)/σ)**2] - ! ψ is initialized to zero everywhere. + ! Bx(x) = 1 + C * erf((x-0.5)/\sigma) => \partialBx/\partialx = C * (2/\sqrt\pi) * exp[-((x-0.5)/\sigma)**2] * (1/\sigma) + ! Choose C = \epsilon * \sigma * \sqrt\pi / 2 => \partialBx/\partialx = \epsilon * exp[-((x-0.5)/\sigma)**2] \psi is + ! initialized to zero everywhere. eps_mhd = patch_icpp(patch_id)%a(2) sigma = patch_icpp(patch_id)%a(3) @@ -252,7 +228,6 @@ ! B-field q_prim_vf(B_idx%beg)%sf(i, j, 0) = 1._wp + C_mhd*erf((x_cc(i) - 0.5_wp)/sigma) - case (261) ! Blob r0 = 1._wp/sqrt(8._wp) r2 = x_cc(i)**2 + y_cc(j)**2 @@ -261,12 +236,11 @@ if (alpha < 1) then q_prim_vf(B_idx%beg)%sf(i, j, 0) = 1._wp/sqrt(4._wp*pi)*(alpha**8 - 2._wp*alpha**4 + 1._wp) ! q_prim_vf(B_idx%beg)%sf(i,j,0) = 1._wp/sqrt(4000._wp*pi) * (4096._wp*r2**4 - 128._wp*r2**2 + 1._wp) - ! q_prim_vf(B_idx%beg)%sf(i,j,0) = 1._wp/(4._wp*pi) * (alpha**8 - 2._wp*alpha**4 + 1._wp) - ! q_prim_vf(E_idx)%sf(i,j,0) = 6._wp - q_prim_vf(B_idx%beg)%sf(i,j,0)**2/2._wp + ! q_prim_vf(B_idx%beg)%sf(i,j,0) = 1._wp/(4._wp*pi) * (alpha**8 - 2._wp*alpha**4 + 1._wp) q_prim_vf(E_idx)%sf(i,j,0) = + ! 6._wp - q_prim_vf(B_idx%beg)%sf(i,j,0)**2/2._wp end if - case (262) ! Tilted 2D MHD shock‐tube at α = arctan2 (≈63.4°) - ! rotate by α = atan(2) + ! rotate by \alpha = atan(2) alpha = atan(2._wp) cosA = cos(alpha) sinA = sin(alpha) @@ -274,69 +248,68 @@ r = x_cc(i)*cosA + y_cc(j)*sinA if (r <= 0.5_wp) then - ! LEFT state: ρ=1, v∥=+10, v⊥=0, p=20, B∥=B⊥=5/√(4π) + ! LEFT state: \rho=1, v\parallel=+10, v\perp=0, p=20, B\parallel=B\perp=5/\sqrt(4\pi) q_prim_vf(contxb)%sf(i, j, 0) = 1._wp q_prim_vf(momxb)%sf(i, j, 0) = 10._wp*cosA q_prim_vf(momxb + 1)%sf(i, j, 0) = 10._wp*sinA q_prim_vf(E_idx)%sf(i, j, 0) = 20._wp - q_prim_vf(B_idx%beg)%sf(i, j, 0) = (5._wp/sqrt(4._wp*pi))*cosA & - - (5._wp/sqrt(4._wp*pi))*sinA - q_prim_vf(B_idx%beg + 1)%sf(i, j, 0) = (5._wp/sqrt(4._wp*pi))*sinA & - + (5._wp/sqrt(4._wp*pi))*cosA + q_prim_vf(B_idx%beg)%sf(i, j, 0) = (5._wp/sqrt(4._wp*pi))*cosA - (5._wp/sqrt(4._wp*pi))*sinA + q_prim_vf(B_idx%beg + 1)%sf(i, j, 0) = (5._wp/sqrt(4._wp*pi))*sinA + (5._wp/sqrt(4._wp*pi))*cosA else - ! RIGHT state: ρ=1, v∥=−10, v⊥=0, p=1, B∥=B⊥=5/√(4π) + ! RIGHT state: \rho=1, v\parallel=-10, v\perp=0, p=1, B\parallel=B\perp=5/\sqrt(4\pi) q_prim_vf(contxb)%sf(i, j, 0) = 1._wp q_prim_vf(momxb)%sf(i, j, 0) = -10._wp*cosA q_prim_vf(momxb + 1)%sf(i, j, 0) = -10._wp*sinA q_prim_vf(E_idx)%sf(i, j, 0) = 1._wp - q_prim_vf(B_idx%beg)%sf(i, j, 0) = (5._wp/sqrt(4._wp*pi))*cosA & - - (5._wp/sqrt(4._wp*pi))*sinA - q_prim_vf(B_idx%beg + 1)%sf(i, j, 0) = (5._wp/sqrt(4._wp*pi))*sinA & - + (5._wp/sqrt(4._wp*pi))*cosA + q_prim_vf(B_idx%beg)%sf(i, j, 0) = (5._wp/sqrt(4._wp*pi))*cosA - (5._wp/sqrt(4._wp*pi))*sinA + q_prim_vf(B_idx%beg + 1)%sf(i, j, 0) = (5._wp/sqrt(4._wp*pi))*sinA + (5._wp/sqrt(4._wp*pi))*cosA end if ! v^z and B^z remain zero by default - case (270) ! This hardcoded case extrudes a 1D profile to initialize a 2D simulation domain @: HardcodedReadValues() - case (280) - ! This is patch is hard-coded for test suite optimization used in the - ! 2D_isentropicvortex case: - ! This analytic patch uses geometry 2 + ! This is patch is hard-coded for test suite optimization used in the 2D_isentropicvortex case: This analytic patch uses + ! geometry 2 if (patch_id == 1) then - q_prim_vf(E_idx)%sf(i, j, 0) = 1.0*(1.0 - (1.0/1.0)*(5.0/(2.0*pi))*(5.0/(8.0*1.0*(1.4 + 1.0)*pi))*exp(2.0*1.0*(1.0 - (x_cc(i) - patch_icpp(1)%x_centroid)**2.0 - (y_cc(j) - patch_icpp(1)%y_centroid)**2.0)))**(1.4 + 1.0) - q_prim_vf(contxb + 0)%sf(i, j, 0) = 1.0*(1.0 - (1.0/1.0)*(5.0/(2.0*pi))*(5.0/(8.0*1.0*(1.4 + 1.0)*pi))*exp(2.0*1.0*(1.0 - (x_cc(i) - patch_icpp(1)%x_centroid)**2.0 - (y_cc(j) - patch_icpp(1)%y_centroid)**2.0)))**1.4 - q_prim_vf(momxb + 0)%sf(i, j, 0) = 0.0 + (y_cc(j) - patch_icpp(1)%y_centroid)*(5.0/(2.0*pi))*exp(1.0*(1.0 - (x_cc(i) - patch_icpp(1)%x_centroid)**2.0 - (y_cc(j) - patch_icpp(1)%y_centroid)**2.0)) - q_prim_vf(momxb + 1)%sf(i, j, 0) = 0.0 - (x_cc(i) - patch_icpp(1)%x_centroid)*(5.0/(2.0*pi))*exp(1.0*(1.0 - (x_cc(i) - patch_icpp(1)%x_centroid)**2.0 - (y_cc(j) - patch_icpp(1)%y_centroid)**2.0)) + q_prim_vf(E_idx)%sf(i, j, & + & 0) = 1.0*(1.0 - (1.0/1.0)*(5.0/(2.0*pi))*(5.0/(8.0*1.0*(1.4 + 1.0)*pi))*exp(2.0*1.0*(1.0 - (x_cc(i) & + & - patch_icpp(1)%x_centroid)**2.0 - (y_cc(j) - patch_icpp(1)%y_centroid)**2.0)))**(1.4 + 1.0) + q_prim_vf(contxb + 0)%sf(i, j, & + & 0) = 1.0*(1.0 - (1.0/1.0)*(5.0/(2.0*pi))*(5.0/(8.0*1.0*(1.4 + 1.0)*pi))*exp(2.0*1.0*(1.0 - (x_cc(i) & + & - patch_icpp(1)%x_centroid)**2.0 - (y_cc(j) - patch_icpp(1)%y_centroid)**2.0)))**1.4 + q_prim_vf(momxb + 0)%sf(i, j, & + & 0) = 0.0 + (y_cc(j) - patch_icpp(1)%y_centroid)*(5.0/(2.0*pi))*exp(1.0*(1.0 - (x_cc(i) - patch_icpp(1) & + & %x_centroid)**2.0 - (y_cc(j) - patch_icpp(1)%y_centroid)**2.0)) + q_prim_vf(momxb + 1)%sf(i, j, & + & 0) = 0.0 - (x_cc(i) - patch_icpp(1)%x_centroid)*(5.0/(2.0*pi))*exp(1.0*(1.0 - (x_cc(i) - patch_icpp(1) & + & %x_centroid)**2.0 - (y_cc(j) - patch_icpp(1)%y_centroid)**2.0)) end if - case (281) - ! This is patch is hard-coded for test suite optimization used in the - ! 2D_acoustic_pulse case: - ! This analytic patch uses geometry 2 + ! This is patch is hard-coded for test suite optimization used in the 2D_acoustic_pulse case: This analytic patch uses + ! geometry 2 if (patch_id == 2) then - q_prim_vf(E_idx)%sf(i, j, 0) = 101325*(1 - 0.5*(1.4 - 1)*(0.4)**2*exp(0.5*(1 - sqrt(x_cc(i)**2 + y_cc(j)**2))))**(1.4/(1.4 - 1)) - q_prim_vf(contxb + 0)%sf(i, j, 0) = 1*(1 - 0.5*(1.4 - 1)*(0.4)**2*exp(0.5*(1 - sqrt(x_cc(i)**2 + y_cc(j)**2))))**(1/(1.4 - 1)) + q_prim_vf(E_idx)%sf(i, j, & + & 0) = 101325*(1 - 0.5*(1.4 - 1)*(0.4)**2*exp(0.5*(1 - sqrt(x_cc(i)**2 + y_cc(j)**2))))**(1.4/(1.4 - 1)) + q_prim_vf(contxb + 0)%sf(i, j, & + & 0) = 1*(1 - 0.5*(1.4 - 1)*(0.4)**2*exp(0.5*(1 - sqrt(x_cc(i)**2 + y_cc(j)**2))))**(1/(1.4 - 1)) end if - case (282) - ! This is patch is hard-coded for test suite optimization used in the - ! 2D_zero_circ_vortex case: - ! This analytic patch uses geometry 2 + ! This is patch is hard-coded for test suite optimization used in the 2D_zero_circ_vortex case: This analytic patch uses + ! geometry 2 if (patch_id == 2) then - q_prim_vf(E_idx)%sf(i, j, 0) = 101325*(1 - 0.5*(1.4 - 1)*(0.1/0.3)**2*exp(0.5*(1 - sqrt(x_cc(i)**2 + y_cc(j)**2))))**(1.4/(1.4 - 1)) - q_prim_vf(contxb + 0)%sf(i, j, 0) = 1*(1 - 0.5*(1.4 - 1)*(0.1/0.3)**2*exp(0.5*(1 - sqrt(x_cc(i)**2 + y_cc(j)**2))))**(1/(1.4 - 1)) - q_prim_vf(momxb + 0)%sf(i, j, 0) = 112.99092883944267*(1 - (0.1/0.3))*y_cc(j)*exp(0.5*(1 - sqrt(x_cc(i)**2 + y_cc(j)**2))) + q_prim_vf(E_idx)%sf(i, j, & + & 0) = 101325*(1 - 0.5*(1.4 - 1)*(0.1/0.3)**2*exp(0.5*(1 - sqrt(x_cc(i)**2 + y_cc(j)**2))))**(1.4/(1.4 - 1)) + q_prim_vf(contxb + 0)%sf(i, j, & + & 0) = 1*(1 - 0.5*(1.4 - 1)*(0.1/0.3)**2*exp(0.5*(1 - sqrt(x_cc(i)**2 + y_cc(j)**2))))**(1/(1.4 - 1)) + q_prim_vf(momxb + 0)%sf(i, j, & + & 0) = 112.99092883944267*(1 - (0.1/0.3))*y_cc(j)*exp(0.5*(1 - sqrt(x_cc(i)**2 + y_cc(j)**2))) q_prim_vf(momxb + 1)%sf(i, j, 0) = 112.99092883944267*((0.1/0.3))*x_cc(i)*exp(0.5*(1 - sqrt(x_cc(i)**2 + y_cc(j)**2))) end if - case default if (proc_rank == 0) then call s_int_to_str(patch_id, iStr) - call s_mpi_abort("Invalid hcid specified for patch "//trim(iStr)) + call s_mpi_abort("Invalid hcid specified for patch " // trim(iStr)) end if - end select - #:enddef diff --git a/src/common/include/3dHardcodedIC.fpp b/src/common/include/3dHardcodedIC.fpp index 359df5f80f..cb3132ca17 100644 --- a/src/common/include/3dHardcodedIC.fpp +++ b/src/common/include/3dHardcodedIC.fpp @@ -3,23 +3,19 @@ real(wp) :: rhoH, rhoL, pRef, pInt, h, lam, wl, amp, intH, alph, Mach real(wp) :: eps - ! IGR Jets - ! Arrays to stor position and radii of jets from input file + ! IGR Jets Arrays to stor position and radii of jets from input file real(wp), dimension(:), allocatable :: y_th_arr, z_th_arr, r_th_arr ! Variables to describe initial condition of jet - real(wp) :: r, ux_th, ux_am, p_th, p_am, rho_th, rho_am, y_th, z_th, r_th, eps_smooth - real(wp) :: rcut, xcut ! Intermediate variables for creating smooth initial condition - - real(wp), dimension(0:n, 0:p) :: rcut_arr - integer :: l, q, s ! Iterators for reading input files - integer :: start, end ! Ints to keep track of position in file - - character(len=100000) :: line ! String to store line in file - character(len=25) :: value ! String to store value in line - integer :: NJet ! Number of jets - - real(wp), allocatable, dimension(:, :) :: ih ! Array to store interface height in - logical :: file_exist ! Flag to check if file exists + real(wp) :: r, ux_th, ux_am, p_th, p_am, rho_th, rho_am, y_th, z_th, r_th, eps_smooth + real(wp) :: rcut, xcut ! Intermediate variables for creating smooth initial condition + real(wp), dimension(0:n,0:p) :: rcut_arr + integer :: l, q, s ! Iterators for reading input files + integer :: start, end ! Ints to keep track of position in file + character(len=100000) :: line ! String to store line in file + character(len=25) :: value ! String to store value in line + integer :: NJet ! Number of jets + real(wp), allocatable, dimension(:,:) :: ih ! Array to store interface height in + logical :: file_exist ! Flag to check if file exists eps = 1e-9_wp @@ -34,9 +30,9 @@ call s_mpi_abort("Error: njet.txt file specified for hcid=303 does not exist") end if - @:ALLOCATE (y_th_arr(0:NJet - 1)) - @:ALLOCATE (z_th_arr(0:NJet - 1)) - @:ALLOCATE (r_th_arr(0:NJet - 1)) + @:ALLOCATE(y_th_arr(0:NJet - 1)) + @:ALLOCATE(z_th_arr(0:NJet - 1)) + @:ALLOCATE(r_th_arr(0:NJet - 1)) inquire (file="jets.csv", exist=file_exist) if (file_exist) then @@ -55,7 +51,7 @@ end if if (l == 0) then read (value, *) y_th_arr(q) ! Convert string to numeric value - elseif (l == 1) then + else if (l == 1) then read (value, *) z_th_arr(q) else read (value, *) r_th_arr(q) @@ -133,13 +129,11 @@ end if end if end if - #:enddef #:def Hardcoded3D() - select case (patch_icpp(patch_id)%hcid) - case (300) ! Rayleigh-Taylor instability + case (300) ! Rayleigh-Taylor instability rhoH = 3._wp rhoL = 1._wp pRef = 1.e5_wp @@ -170,8 +164,7 @@ pInt = pref + rhoH*9.81_wp*(1.2_wp - intH) q_prim_vf(E_idx)%sf(i, j, k) = pInt + rhoL*9.81_wp*(intH - y_cc(j)) end if - - case (301) ! (3D lung geometry in X direction, |sin(*)+sin(*)|) + case (301) ! (3D lung geometry in X direction, |sin(*)+sin(*)|) h = 0.0_wp lam = 1.0_wp amp = patch_icpp(patch_id)%a(2) @@ -183,8 +176,7 @@ q_prim_vf(advxb)%sf(i, j, k) = patch_icpp(1)%alpha(1) q_prim_vf(advxe)%sf(i, j, k) = patch_icpp(1)%alpha(2) end if - - case (302) ! 3D Jet with IGR + case (302) ! 3D Jet with IGR ux_th = 10*sqrt(1.4*0.4) ux_am = 0.0*sqrt(1.4) p_th = 2.0_wp @@ -214,9 +206,7 @@ end if q_prim_vf(E_idx)%sf(i, j, k) = p_th*rcut*xcut + p_am - - case (303) ! 3D Multijet - + case (303) ! 3D Multijet eps_smooth = 3.0_wp ux_th = 10*sqrt(1.4*0.4) ux_am = 2.5*sqrt(1.4*0.4) @@ -242,11 +232,8 @@ end if q_prim_vf(E_idx)%sf(i, j, k) = p_th*rcut*xcut + p_am - - case (304) ! 3D Interface from file cartesian - - alph = 0.5_wp*(1 + (1._wp - 2._wp*eps)* & - tanh((ih(start_idx(2) + j, start_idx(3) + k) - x_cc(i))*(0.5_wp/dx))) + case (304) ! 3D Interface from file cartesian + alph = 0.5_wp*(1 + (1._wp - 2._wp*eps)*tanh((ih(start_idx(2) + j, start_idx(3) + k) - x_cc(i))*(0.5_wp/dx))) q_prim_vf(advxb)%sf(i, j, k) = alph q_prim_vf(advxe)%sf(i, j, k) = 1._wp - alph @@ -254,19 +241,15 @@ q_prim_vf(contxb)%sf(i, j, k) = q_prim_vf(advxb)%sf(i, j, k)*(950._wp/1000._wp) q_prim_vf(contxe)%sf(i, j, k) = q_prim_vf(advxe)%sf(i, j, k)*(1._wp/1000._wp) - !h = x_cc(i) - ih(start_idx(2) + j, start_idx(3) + k) - !q_prim_vf(momxb)%sf(i,j,k) = -1._wp * (ih(start_idx(2) + j, start_idx(3) + k) - normFac) * exp(-h * h / 1000) / 100._wp + ! h = x_cc(i) - ih(start_idx(2) + j, start_idx(3) + k) q_prim_vf(momxb)%sf(i,j,k) = -1._wp * (ih(start_idx(2) + j, + ! start_idx(3) + k) - normFac) * exp(-h * h / 1000) / 100._wp - q_prim_vf(E_idx)%sf(i, j, k) = p0_ic + & - (q_prim_vf(contxb)%sf(i, j, k) + q_prim_vf(contxe)%sf(i, j, k))*g0_ic* & - (ih(start_idx(2) + j, start_idx(3) + k) - x_cc(i)) + q_prim_vf(E_idx)%sf(i, j, k) = p0_ic + (q_prim_vf(contxb)%sf(i, j, k) + q_prim_vf(contxe)%sf(i, j, & + & k))*g0_ic*(ih(start_idx(2) + j, start_idx(3) + k) - x_cc(i)) if (surface_tension) q_prim_vf(c_idx)%sf(i, j, k) = alph - - case (305) ! 3D Interface from file axisymmetric - - alph = 0.5_wp*(1 + (1._wp - 2._wp*eps)* & - tanh((ih(start_idx(2) + j, 0) - x_cc(i))*(0.01_wp/dx))) + case (305) ! 3D Interface from file axisymmetric + alph = 0.5_wp*(1 + (1._wp - 2._wp*eps)*tanh((ih(start_idx(2) + j, 0) - x_cc(i))*(0.01_wp/dx))) q_prim_vf(advxb)%sf(i, j, k) = alph q_prim_vf(advxe)%sf(i, j, k) = 1._wp - alph @@ -274,31 +257,25 @@ q_prim_vf(contxb)%sf(i, j, k) = q_prim_vf(advxb)%sf(i, j, k)*1._wp q_prim_vf(contxe)%sf(i, j, k) = q_prim_vf(advxe)%sf(i, j, k)*(1._wp/950._wp) - q_prim_vf(E_idx)%sf(i, j, k) = p0_ic + & - (q_prim_vf(contxb)%sf(i, j, k) + q_prim_vf(contxe)%sf(i, j, k))*g0_ic* & - (ih(start_idx(1) + i, start_idx(3) + k) - y_cc(j)) + q_prim_vf(E_idx)%sf(i, j, k) = p0_ic + (q_prim_vf(contxb)%sf(i, j, k) + q_prim_vf(contxe)%sf(i, j, & + & k))*g0_ic*(ih(start_idx(1) + i, start_idx(3) + k) - y_cc(j)) if (surface_tension) q_prim_vf(c_idx)%sf(i, j, k) = alph - case (370) ! This hardcoded case extrudes a 2D profile to initialize a 3D simulation domain @: HardcodedReadValues() - case (380) - ! This is patch is hard-coded for test suite optimization used in the - ! 3D_TaylorGreenVortex case: - ! This analytic patch used geometry 9 + ! This is patch is hard-coded for test suite optimization used in the 3D_TaylorGreenVortex case: This analytic patch used + ! geometry 9 Mach = 0.1 if (patch_id == 1) then - q_prim_vf(E_idx)%sf(i, j, k) = 101325 + (Mach**2*376.636429464809**2/16)*(cos(2*x_cc(i)/1) + cos(2*y_cc(j)/1))*(cos(2*z_cc(k)/1) + 2) + q_prim_vf(E_idx)%sf(i, j, & + & k) = 101325 + (Mach**2*376.636429464809**2/16)*(cos(2*x_cc(i)/1) + cos(2*y_cc(j)/1))*(cos(2*z_cc(k)/1) + 2) q_prim_vf(momxb + 0)%sf(i, j, k) = Mach*376.636429464809*sin(x_cc(i)/1)*cos(y_cc(j)/1)*sin(z_cc(k)/1) q_prim_vf(momxb + 1)%sf(i, j, k) = -Mach*376.636429464809*cos(x_cc(i)/1)*sin(y_cc(j)/1)*sin(z_cc(k)/1) end if - case default call s_int_to_str(patch_id, iStr) - call s_mpi_abort("Invalid hcid specified for patch "//trim(iStr)) + call s_mpi_abort("Invalid hcid specified for patch " // trim(iStr)) end select - #:enddef - diff --git a/src/common/include/ExtrusionHardcodedIC.fpp b/src/common/include/ExtrusionHardcodedIC.fpp index 264b227f21..0adb8beaa1 100644 --- a/src/common/include/ExtrusionHardcodedIC.fpp +++ b/src/common/include/ExtrusionHardcodedIC.fpp @@ -1,71 +1,70 @@ !> @brief Allocate memory and read initial condition data for IC extrusion. !> !> @details -!> This macro handles the complete initialization process for IC extrusion by: +!> This macro handles the complete initialization process for IC extrusion by: !> -!> **Memory Allocation:** -!> - stored_values(xRows, yRows, sys_size) - stores primitive variable data from files -!> - x_coords(nrows) - stores x-coordinates from input files -!> - y_coords(nrows) - stores y-coordinates from input files (3D case only) +!> **Memory Allocation:** +!> - stored_values(xRows, yRows, sys_size) - stores primitive variable data from files +!> - x_coords(nrows) - stores x-coordinates from input files +!> - y_coords(nrows) - stores y-coordinates from input files (3D case only) !> -!> **File Reading Operations:** -!> - Reads primitive variable data from multiple files with pattern: -!> `prim..00..dat` where timestep uses `zeros_default` padding -!> - Files are read from directory specified by `init_dir` parameter -!> - Supports 1D, 2D, and 3D computational domains +!> **File Reading Operations:** +!> - Reads primitive variable data from multiple files with pattern: +!> `prim..00..dat` where timestep uses `zeros_default` padding +!> - Files are read from directory specified by `init_dir` parameter +!> - Supports 1D, 2D, and 3D computational domains !> -!> **Grid Structure Detection:** -!> - 1D/2D: Counts lines in first file to determine xRows -!> - 3D: Analyzes coordinate patterns to determine xRows and yRows structure +!> **Grid Structure Detection:** +!> - 1D/2D: Counts lines in first file to determine xRows +!> - 3D: Analyzes coordinate patterns to determine xRows and yRows structure !> -!> **MPI Domain Mapping:** -!> - Calculates global_offset_x and global_offset_y for MPI subdomain positioning -!> - Maps file coordinates to local computational grid coordinates +!> **MPI Domain Mapping:** +!> - Calculates global_offset_x and global_offset_y for MPI subdomain positioning +!> - Maps file coordinates to local computational grid coordinates !> -!> **Data Assignment:** -!> - Populates q_prim_vf primitive variable arrays with file data -!> - Handles momentum component indexing with special treatment for momxe -!> - Sets momxe component to zero for 2D/3D cases +!> **Data Assignment:** +!> - Populates q_prim_vf primitive variable arrays with file data +!> - Handles momentum component indexing with special treatment for momxe +!> - Sets momxe component to zero for 2D/3D cases !> -!> **State Management:** -!> - Uses files_loaded flag to prevent redundant file operations -!> - Preserves data across multiple macro calls within same simulation +!> **State Management:** +!> - Uses files_loaded flag to prevent redundant file operations +!> - Preserves data across multiple macro calls within same simulation !> -!> @note File pattern uses `zeros_default` parameter (default: "000000") for timestep padding -!> @note Directory path is hardcoded in `init_dir` parameter - modify as needed -!> @warning Aborts execution if file reading errors occur. +!> @note File pattern uses `zeros_default` parameter (default: "000000") for timestep padding +!> @note Directory path is hardcoded in `init_dir` parameter - modify as needed +!> @warning Aborts execution if file reading errors occur. #:def HardcodedDimensionsExtrusion() - integer :: xRows, yRows, nRows, iix, iiy, max_files - integer :: f, iter, ios, ios2, unit, unit2, idx, idy, index_x, index_y, jump, line_count, ycount - real(wp) :: x_len, x_step, y_len, y_step - real(wp) :: dummy_x, dummy_y, dummy_z, x0, y0 - integer :: global_offset_x, global_offset_y ! MPI subdomain offset - real(wp) :: delta_x, delta_y - character(len=100), dimension(sys_size) :: fileNames ! Arrays to store all data from files - character(len=200) :: errmsg - real(wp), allocatable :: stored_values(:, :, :) - real(wp), allocatable :: x_coords(:), y_coords(:) - logical :: files_loaded = .false. - real(wp) :: domain_xstart, domain_xend, domain_ystart, domain_yend - character(len=*), parameter :: init_dir = "/home/MFC/FilesDirectory" ! For example /home/MFC/examples/1D_Shock/D/ - character(len=20) :: file_num_str ! For storing the file number as a string - character(len=20) :: zeros_part ! For the trailing zeros part - character(len=6), parameter :: zeros_default = "000000" ! Default zeros (can be changed) + integer :: xRows, yRows, nRows, iix, iiy, max_files + integer :: f, iter, ios, ios2, unit, unit2, idx, idy, index_x, index_y, jump, line_count, ycount + real(wp) :: x_len, x_step, y_len, y_step + real(wp) :: dummy_x, dummy_y, dummy_z, x0, y0 + integer :: global_offset_x, global_offset_y ! MPI subdomain offset + real(wp) :: delta_x, delta_y + character(len=100), dimension(sys_size) :: fileNames ! Arrays to store all data from files + character(len=200) :: errmsg + real(wp), allocatable :: stored_values(:,:,:) + real(wp), allocatable :: x_coords(:), y_coords(:) + logical :: files_loaded = .false. + real(wp) :: domain_xstart, domain_xend, domain_ystart, domain_yend + character(len=*), parameter :: init_dir = "/home/MFC/FilesDirectory" ! For example /home/MFC/examples/1D_Shock/D/ + character(len=20) :: file_num_str ! For storing the file number as a string + character(len=20) :: zeros_part ! For the trailing zeros part + character(len=6), parameter :: zeros_default = "000000" ! Default zeros (can be changed) #:enddef #:def HardcodedReadValues() - if (.not. files_loaded) then max_files = merge(sys_size, sys_size - 1, num_dims == 1) do f = 1, max_files write (file_num_str, '(I0)') f - fileNames(f) = trim(init_dir)//"prim."//trim(file_num_str)//".00."//zeros_default//".dat" + fileNames(f) = trim(init_dir) // "prim." // trim(file_num_str) // ".00." // zeros_default // ".dat" end do ! Common file reading setup open (newunit=unit2, file=trim(fileNames(1)), status='old', action='read', iostat=ios2) - if (ios2 /= 0) call s_mpi_abort("Error opening file: "//trim(fileNames(1))) + if (ios2 /= 0) call s_mpi_abort("Error opening file: " // trim(fileNames(1))) select case (num_dims) case (1, 2) ! 1D and 2D cases are similar @@ -82,16 +81,16 @@ yRows = 1 index_x = 0 if (num_dims == 2) index_x = i - @:ALLOCATE (x_coords(xRows), stored_values(xRows, 1, sys_size)) + @:ALLOCATE(x_coords(xRows), stored_values(xRows, 1, sys_size)) ! Read data from all files do f = 1, max_files open (newunit=unit, file=trim(fileNames(f)), status='old', action='read', iostat=ios) - if (ios /= 0) call s_mpi_abort("Error opening file: "//trim(fileNames(f))) + if (ios /= 0) call s_mpi_abort("Error opening file: " // trim(fileNames(f))) do iter = 1, xRows read (unit, *, iostat=ios) x_coords(iter), stored_values(iter, 1, f) - if (ios /= 0) call s_mpi_abort("Error reading file: "//trim(fileNames(f))) + if (ios /= 0) call s_mpi_abort("Error reading file: " // trim(fileNames(f))) end do close (unit) end do @@ -99,10 +98,8 @@ ! Calculate offsets domain_xstart = x_coords(1) x_step = x_cc(1) - x_cc(0) - delta_x = merge(x_cc(0) - domain_xstart + x_step/2.0, & - x_cc(index_x) - domain_xstart + x_step/2.0, num_dims == 1) + delta_x = merge(x_cc(0) - domain_xstart + x_step/2.0, x_cc(index_x) - domain_xstart + x_step/2.0, num_dims == 1) global_offset_x = nint(abs(delta_x)/x_step) - case (3) ! 3D case - determine grid structure ! Find yRows by counting rows with same x read (unit2, *, iostat=ios2) x0, y0, dummy_z @@ -131,7 +128,7 @@ close (unit2) xRows = nrows/yRows - @:ALLOCATE (x_coords(nrows), y_coords(nrows), stored_values(xRows, yRows, sys_size)) + @:ALLOCATE(x_coords(nrows), y_coords(nrows), stored_values(xRows, yRows, sys_size)) index_x = i index_y = j @@ -139,7 +136,7 @@ do f = 1, max_files open (newunit=unit, file=trim(fileNames(f)), status='old', action='read', iostat=ios) if (ios /= 0) then - if (f == 1) call s_mpi_abort("Error opening file: "//trim(fileNames(f))) + if (f == 1) call s_mpi_abort("Error opening file: " // trim(fileNames(f))) cycle end if @@ -177,7 +174,6 @@ do f = 1, sys_size q_prim_vf(f)%sf(i, 0, 0) = stored_values(idx, 1, f) end do - case (2) idx = i + 1 + global_offset_x - index_x do f = 1, sys_size - 1 @@ -185,7 +181,6 @@ q_prim_vf(f + jump)%sf(i, j, 0) = stored_values(idx, 1, f) end do q_prim_vf(momxe)%sf(i, j, 0) = 0.0_wp - case (3) idx = i + 1 + global_offset_x - index_x idy = j + 1 + global_offset_y - index_y @@ -199,11 +194,11 @@ #:def HardcodedDellacation() if (allocated(stored_values)) then - @:DEALLOCATE (stored_values) - @:DEALLOCATE (x_coords) + @:DEALLOCATE(stored_values) + @:DEALLOCATE(x_coords) end if if (allocated(y_coords)) then - @:DEALLOCATE (y_coords) + @:DEALLOCATE(y_coords) end if #:enddef diff --git a/src/common/include/SharedHardcoded.fpp b/src/common/include/SharedHardcoded.fpp index 9ebd288c83..8c7dd8c98b 100644 --- a/src/common/include/SharedHardcoded.fpp +++ b/src/common/include/SharedHardcoded.fpp @@ -1,17 +1,14 @@ #:def HardcodedDeallocation() - if (allocated(stored_values)) then - @:DEALLOCATE (stored_values) - @:DEALLOCATE (x_coords) + @:DEALLOCATE(stored_values) + @:DEALLOCATE(x_coords) end if if (allocated(y_coords)) then - @:DEALLOCATE (y_coords) + @:DEALLOCATE(y_coords) end if if (allocated(ih)) then @:DEALLOCATE(ih) end if - #:enddef - diff --git a/src/common/include/acc_macros.fpp b/src/common/include/acc_macros.fpp index 771ee976db..bd4284c01b 100644 --- a/src/common/include/acc_macros.fpp +++ b/src/common/include/acc_macros.fpp @@ -173,7 +173,8 @@ $:acc_directive #:enddef -#:def ACC_DECLARE(copy=None, copyin=None, copyinReadOnly=None, copyout=None, create=None, present=None, deviceptr=None, link=None, extraAccArgs=None) +#:def ACC_DECLARE(copy=None, copyin=None, copyinReadOnly=None, copyout=None, create=None, present=None, deviceptr=None, & + & link=None, extraAccArgs=None) #:set copy_val = GEN_COPY_STR(copy) #:set copyin_val = GEN_COPYIN_STR(copyin, False).strip('\n') + GEN_COPYIN_STR(copyinReadOnly, True).strip('\n') #:set copyout_val = GEN_COPYOUT_STR(copyout) @@ -190,13 +191,14 @@ $:acc_directive #:enddef -#:def ACC_LOOP(collapse=None, parallelism=None, data_dependency=None, reduction=None, reductionOp=None, private=None, extraAccArgs=None) +#:def ACC_LOOP(collapse=None, parallelism=None, data_dependency=None, reduction=None, reductionOp=None, private=None, & + & extraAccArgs=None) #:set collapse_val = GEN_COLLAPSE_STR(collapse) #:set parallelism_val = GEN_PARALLELISM_STR(parallelism) #:if data_dependency is not None #:assert isinstance(data_dependency, str) #:assert (data_dependency == 'auto' or data_dependency == 'independent') - #:set data_dependency_val = data_dependency + #:set data_dependency_val = data_dependency #:else #:set data_dependency_val = '' #:endif @@ -211,7 +213,8 @@ $:acc_directive #:enddef -#:def ACC_DATA(code, copy=None, copyin=None, copyinReadOnly=None, copyout=None, create=None, no_create=None, present=None, deviceptr=None, attach=None, default=None, extraAccArgs=None) +#:def ACC_DATA(code, copy=None, copyin=None, copyinReadOnly=None, copyout=None, create=None, no_create=None, present=None, & + & deviceptr=None, attach=None, default=None, extraAccArgs=None) #:assert code is not None #:assert isinstance(code, str) #:if code == '' or code.isspace() @@ -229,7 +232,7 @@ #:set extraAccArgs_val = GEN_EXTRA_ARGS_STR(extraAccArgs) #:set clause_val = copy_val.strip('\n') + copyin_val.strip('\n') + & & copyout_val.strip('\n') + create_val.strip('\n') + & - & no_create_val.strip('\n') + present_val.strip('\n') + & + & no_create_val.strip('\n') + present_val.strip('\n') + & & deviceptr_val.strip('\n') + attach_val.strip('\n') + & & default_val.strip('\n') #:set acc_directive = '!$acc data ' + clause_val + extraAccArgs_val.strip('\n') diff --git a/src/common/include/macros.fpp b/src/common/include/macros.fpp index 03d812f53d..3fc7e99cd0 100644 --- a/src/common/include/macros.fpp +++ b/src/common/include/macros.fpp @@ -12,20 +12,18 @@ #endif #:enddef -! Caution: -! This macro requires the use of a binding script to set CUDA_VISIBLE_DEVICES, such that we have one GPU device per MPI rank. -! That's because for both cudaMemAdvise (preferred location) and cudaMemPrefetchAsync we use location = device_id = 0. -! For an example see misc/nvidia_uvm/bind.sh. +! Caution: This macro requires the use of a binding script to set CUDA_VISIBLE_DEVICES, such that we have one GPU device per MPI +! rank. That's because for both cudaMemAdvise (preferred location) and cudaMemPrefetchAsync we use location = device_id = 0. For an +! example see misc/nvidia_uvm/bind.sh. #:def PREFER_GPU(*args) #ifdef MFC_SIMULATION #ifdef __NVCOMPILER_GPU_UNIFIED_MEM block -! Beginning in the 25.3 release, the structure of the cudafor module has been changed slightly. -! The module now includes, or “uses” 3 submodules: cuda_runtime_api, gpu_reductions, and sort. -! The cudafor functionality has not changed. But for new users, or users who have needed to -! work-around name conflicts in the module, it may be better to use cuda_runtime_api to expose -! interfaces to the CUDA runtime calls described in Chapter 4 of this guide. -! https://docs.nvidia.com/hpc-sdk/compilers/cuda-fortran-prog-guide/index.html#fortran-host-modules + ! Beginning in the 25.3 release, the structure of the cudafor module has been changed slightly. The module now includes, or + ! "uses" 3 submodules: cuda_runtime_api, gpu_reductions, and sort. The cudafor functionality has not changed. But for new + ! users, or users who have needed to work-around name conflicts in the module, it may be better to use cuda_runtime_api to + ! expose interfaces to the CUDA runtime calls described in Chapter 4 of this guide. + ! https://docs.nvidia.com/hpc-sdk/compilers/cuda-fortran-prog-guide/index.html#fortran-host-modules #if __NVCOMPILER_MAJOR__ < 25 || (__NVCOMPILER_MAJOR__ == 25 && __NVCOMPILER_MINOR__ < 3) use cudafor, gpu_sum => sum, gpu_maxval => maxval, gpu_minval => minval #else @@ -35,24 +33,23 @@ if (nv_uvm_pref_gpu) then #:for arg in args - !print*, "Moving ${arg}$ to GPU => ", SHAPE(${arg}$) - ! set preferred location GPU + ! print*, "Moving ${arg}$ to GPU => ", SHAPE(${arg}$) set preferred location GPU istat = cudaMemAdvise(c_devloc(${arg}$), SIZEOF(${arg}$), cudaMemAdviseSetPreferredLocation, 0) if (istat /= cudaSuccess) then write (*, "('Error code: ',I0, ': ')") istat - !write(*,*) cudaGetErrorString(istat) + ! write(*,*) cudaGetErrorString(istat) end if ! set accessed by CPU istat = cudaMemAdvise(c_devloc(${arg}$), SIZEOF(${arg}$), cudaMemAdviseSetAccessedBy, cudaCpuDeviceId) if (istat /= cudaSuccess) then write (*, "('Error code: ',I0, ': ')") istat - !write(*,*) cudaGetErrorString(istat) + ! write(*,*) cudaGetErrorString(istat) end if ! prefetch to GPU - physically populate memory pages istat = cudaMemPrefetchAsync(c_devloc(${arg}$), SIZEOF(${arg}$), 0, 0) if (istat /= cudaSuccess) then write (*, "('Error code: ',I0, ': ')") istat - !write(*,*) cudaGetErrorString(istat) + ! write(*,*) cudaGetErrorString(istat) end if #:endfor end if @@ -70,7 +67,8 @@ #:set s = a.rstrip() #:if s.endswith(')') #:set rev = s[::-1] - #:set pos = next(i for i, ch, d in ( (j, c, sum(1 if t==')' else -1 if t=='(' else 0 for t in rev[:j+1])) for j, c in enumerate(rev) ) if ch == '(' and d == 0 ) + #:set pos = next(i for i, ch, d in ( (j, c, sum(1 if t==')' else -1 if t=='(' else 0 for t in rev[:j+1])) for j, & + & c in enumerate(rev) ) if ch == '(' and d == 0 ) #:set s = s[:len(s)-1-pos] #:endif $:cleaned.append(s) @@ -112,7 +110,6 @@ #:def ACC_SETUP_SFs(*args) #ifdef _CRAYFTN block - @:LOG({'@:ACC_SETUP_SFs(${', '.join(args)}$)'}) #:for arg in args @@ -128,7 +125,6 @@ #:def ACC_SETUP_source_spatials(*args) #ifdef _CRAYFTN block - @:LOG({'@:ACC_SETUP_source_spatials(${', '.join(args)}$)'}) #:for arg in args @@ -146,7 +142,6 @@ $:GPU_ENTER_DATA(copyin=('[' + arg + '%xyz_to_r_ratios]')) end if #:endfor - end block #endif #:enddef @@ -159,9 +154,8 @@ #:def ASSERT(predicate, message = None) if (.not. (${predicate}$)) then - call s_mpi_abort("${_FILE_.split('/')[-1]}$:${_LINE_}$: "// & - "Assertion failed: ${predicate}$. " & - //${message or '"No error description."'}$) + call s_mpi_abort("${_FILE_.split('/')[-1]}$:${_LINE_}$: " // "Assertion failed: ${predicate}$. " & + & // ${message or '"No error description."'}$) end if #:enddef ! New line at end of file is required for FYPP diff --git a/src/common/include/omp_macros.fpp b/src/common/include/omp_macros.fpp index 2e1df1dd8a..7620e7607f 100644 --- a/src/common/include/omp_macros.fpp +++ b/src/common/include/omp_macros.fpp @@ -8,7 +8,7 @@ #:def OMP_MAP_STR(map_type, var_list) #:assert map_type is not None - #:assert isinstance(map_type, str) + #:assert isinstance(map_type, str) #:if var_list is not None #:set map_clause = 'map(' + map_type + ':' #:set map_val = GEN_CLAUSE(map_clause, var_list) @@ -85,13 +85,13 @@ #:enddef #! #:def OMP_ATTACH_STR(attach) - #! #:set attach_val = OMP_MAP_STR('always,to', attach) - #! $:attach_val +#! #:set attach_val = OMP_MAP_STR('always,to', attach) +#! $:attach_val #! #:enddef #! #:def OMP_DETACH_STR(detach) - #! #:set detach_val = OMP_MAP_STR('always,from', detach) - #! $:detach_val +#! #:set detach_val = OMP_MAP_STR('always,from', detach) +#! $:detach_val #! #:enddef #:def OMP_TO_STR(to) @@ -110,13 +110,13 @@ #:enddef #:def OMP_USE_DEVICE_ADDR_STR(use_device_addr) - #:set use_device_addr_val = GEN_PARENTHESES_CLAUSE('use_device_addr', use_device_addr) - $:use_device_addr_val + #:set use_device_addr_val = GEN_PARENTHESES_CLAUSE('use_device_addr', use_device_addr) + $:use_device_addr_val #:enddef #:def OMP_USE_DEVICE_PTR_STR(use_device_ptr) - #:set use_device_ptr_val = GEN_PARENTHESES_CLAUSE('use_device_ptr', use_device_ptr) - $:use_device_ptr_val + #:set use_device_ptr_val = GEN_PARENTHESES_CLAUSE('use_device_ptr', use_device_ptr) + $:use_device_ptr_val #:enddef #:def OMP_PARALLEL(code, private=None, default='present', firstprivate=None, reduction=None, reductionOp=None, & @@ -139,7 +139,7 @@ & copyout_val.strip('\n') + create_val.strip('\n') + & & no_create_val.strip('\n') + present_val.strip('\n') + & & deviceptr_val.strip('\n') + attach_val.strip('\n') - + #:set omp_clause_val = omp_clause_val.strip('\n') #:set omp_directive = '!$omp target teams ' + omp_clause_val + extraOmpArgs_val.strip('\n') @@ -153,7 +153,7 @@ & default='present', firstprivate=None, reduction=None, reductionOp=None, & & copy=None, copyin=None, copyinReadOnly=None, copyout=None, create=None, & & no_create=None, present=None, deviceptr=None, attach=None, extraOmpArgs=None) - + #:set collapse_val = GEN_COLLAPSE_STR(collapse) #:set parallelism_val = OMP_PARALLELISM_STR(parallelism) #:set default_val = OMP_DEFAULT_STR(default) @@ -191,7 +191,6 @@ #:enddef #:def END_OMP_PARALLEL_LOOP() - #:if MFC_COMPILER == NVIDIA_COMPILER_ID or MFC_COMPILER == PGI_COMPILER_ID #:set omp_end_directive = '!$omp end target teams loop' #:elif MFC_COMPILER == CCE_COMPILER_ID @@ -218,7 +217,7 @@ #:else #:set function_name_val = '' #:endif - + #:if MFC_COMPILER == AMD_COMPILER_ID #:set clause_val = '' #:else @@ -242,7 +241,8 @@ #:enddef #! Not fully implemented yet (ignores most args right now) -#:def OMP_LOOP(collapse=None, parallelism=None, data_dependency=None, reduction=None, reductionOp=None, private=None, extraOmpArgs=None) +#:def OMP_LOOP(collapse=None, parallelism=None, data_dependency=None, reduction=None, reductionOp=None, private=None, & + & extraOmpArgs=None) #:if MFC_COMPILER == NVIDIA_COMPILER_ID or MFC_COMPILER == PGI_COMPILER_ID #:set omp_directive = '!$omp loop bind(thread)' #:elif MFC_COMPILER == CCE_COMPILER_ID or MFC_COMPILER == AMD_COMPILER_ID @@ -253,7 +253,8 @@ $:omp_directive #:enddef -#:def OMP_DATA(code, copy=None, copyin=None, copyinReadOnly=None, copyout=None, create=None, no_create=None, present=None, deviceptr=None, attach=None, default=None, extraOmpArgs=None) +#:def OMP_DATA(code, copy=None, copyin=None, copyinReadOnly=None, copyout=None, create=None, no_create=None, present=None, & + & deviceptr=None, attach=None, default=None, extraOmpArgs=None) #:assert code is not None #:assert isinstance(code, str) #:if code == '' or code.isspace() @@ -271,7 +272,7 @@ #:set extraOmpArgs_val = GEN_EXTRA_ARGS_STR(extraOmpArgs) #:set clause_val = copy_val.strip('\n') + copyin_val.strip('\n') + & & copyout_val.strip('\n') + create_val.strip('\n') + & - & no_create_val.strip('\n') + present_val.strip('\n') + & + & no_create_val.strip('\n') + present_val.strip('\n') + & & deviceptr_val.strip('\n') + attach_val.strip('\n') + & & default_val.strip('\n') #:set omp_directive = '!$omp target data ' + clause_val + extraOmpArgs_val.strip('\n') diff --git a/src/common/include/parallel_macros.fpp b/src/common/include/parallel_macros.fpp index a13bcbdfcb..b3b65eb9c6 100644 --- a/src/common/include/parallel_macros.fpp +++ b/src/common/include/parallel_macros.fpp @@ -6,8 +6,10 @@ & copy=None, copyin=None, copyinReadOnly=None, copyout=None, create=None, & & no_create=None, present=None, deviceptr=None, attach=None, extraAccArgs=None, extraOmpArgs=None) - #:set acc_code = ACC_PARALLEL(code, private, default, firstprivate, reduction, reductionOp, copy, copyin, copyinReadOnly, copyout, create, no_create, present, deviceptr, attach, extraAccArgs) - #:set omp_code = OMP_PARALLEL(code, private, default, firstprivate, reduction, reductionOp, copy, copyin, copyinReadOnly, copyout, create, no_create, present, deviceptr, attach, extraOmpArgs) + #:set acc_code = ACC_PARALLEL(code, private, default, firstprivate, reduction, reductionOp, copy, copyin, copyinReadOnly, & + & copyout, create, no_create, present, deviceptr, attach, extraAccArgs) + #:set omp_code = OMP_PARALLEL(code, private, default, firstprivate, reduction, reductionOp, copy, copyin, copyinReadOnly, & + & copyout, create, no_create, present, deviceptr, attach, extraOmpArgs) #if defined(MFC_OpenACC) $:acc_code @@ -16,7 +18,6 @@ #else $:code #endif - #:enddef #:def GPU_PARALLEL_LOOP(collapse=None, private=None, parallelism='[gang, vector]', & @@ -24,19 +25,21 @@ & copy=None, copyin=None, copyinReadOnly=None, copyout=None, create=None, & & no_create=None, present=None, deviceptr=None, attach=None, extraAccArgs=None, extraOmpArgs=None) - #:set acc_directive = ACC_PARALLEL_LOOP(collapse, private, parallelism, default, firstprivate, reduction, reductionOp, copy, copyin, copyinReadOnly, copyout, create, no_create, present, deviceptr, attach, extraAccArgs) - #:set omp_directive = OMP_PARALLEL_LOOP(collapse, private, parallelism, default, firstprivate, reduction, reductionOp, copy, copyin, copyinReadOnly, copyout, create, no_create, present, deviceptr, attach, extraOmpArgs) + #:set acc_directive = ACC_PARALLEL_LOOP(collapse, private, parallelism, default, firstprivate, reduction, reductionOp, copy, & + & copyin, copyinReadOnly, copyout, create, no_create, present, deviceptr, attach, & + & extraAccArgs) + #:set omp_directive = OMP_PARALLEL_LOOP(collapse, private, parallelism, default, firstprivate, reduction, reductionOp, copy, & + & copyin, copyinReadOnly, copyout, create, no_create, present, deviceptr, attach, & + & extraOmpArgs) #if defined(MFC_OpenACC) $:acc_directive #elif defined(MFC_OpenMP) $:omp_directive #endif - #:enddef #:def END_GPU_PARALLEL_LOOP() - #:set acc_end_directive = '!$acc end parallel loop' #:set omp_end_directive = END_OMP_PARALLEL_LOOP() @@ -45,14 +48,15 @@ #elif defined(MFC_OpenMP) $:omp_end_directive #endif - #:enddef -#:def GPU_ROUTINE(function_name=None, parallelism=None, nohost=False, cray_inline=False, cray_noinline=False, extraAccArgs=None, extraOmpArgs=None) +#:def GPU_ROUTINE(function_name=None, parallelism=None, nohost=False, cray_inline=False, cray_noinline=False, extraAccArgs=None, & + & extraOmpArgs=None) #:assert isinstance(cray_inline, bool) #:assert isinstance(cray_noinline, bool) #:assert not (cray_inline and cray_noinline), "cray_inline and cray_noinline are mutually exclusive" - #:set acc_directive = ACC_ROUTINE(function_name=function_name, parallelism=parallelism, nohost=nohost, extraAccArgs=extraAccArgs) + #:set acc_directive = ACC_ROUTINE(function_name=function_name, parallelism=parallelism, nohost=nohost, & + & extraAccArgs=extraAccArgs) #:set omp_directive = OMP_ROUTINE(function_name=function_name, nohost=nohost, extraOmpArgs=extraOmpArgs) #:if cray_noinline == True @@ -102,8 +106,10 @@ #:endif #:enddef -#:def GPU_DECLARE(copy=None, copyin=None, copyinReadOnly=None, copyout=None, create=None, present=None, deviceptr=None, link=None, extraAccArgs=None, extraOmpArgs=None) - #:set acc_code = ACC_DECLARE(copy=copy, copyin=copyin, copyinReadOnly=copyinReadOnly, copyout=copyout, create=create, present=present, deviceptr=deviceptr, link=link, extraAccArgs=None) +#:def GPU_DECLARE(copy=None, copyin=None, copyinReadOnly=None, copyout=None, create=None, present=None, deviceptr=None, & + & link=None, extraAccArgs=None, extraOmpArgs=None) + #:set acc_code = ACC_DECLARE(copy=copy, copyin=copyin, copyinReadOnly=copyinReadOnly, copyout=copyout, create=create, & + & present=present, deviceptr=deviceptr, link=link, extraAccArgs=None) #:assert copyout is None #:assert present is None #:assert deviceptr is None @@ -117,9 +123,12 @@ #endif #:enddef -#:def GPU_LOOP(collapse=None, parallelism=None, data_dependency=None, reduction=None, reductionOp=None, private=None, extraAccArgs=None, extraOmpArgs=None) - #:set acc_code = ACC_LOOP(collapse=collapse, parallelism=parallelism, data_dependency=data_dependency, reduction=reduction, reductionOp=reductionOp, private=private, extraAccArgs=extraAccArgs) - #:set omp_code = OMP_LOOP(collapse=collapse, parallelism=parallelism, data_dependency=data_dependency, reduction=reduction, reductionOp=reductionOp, private=private, extraOmpArgs=extraOmpArgs) +#:def GPU_LOOP(collapse=None, parallelism=None, data_dependency=None, reduction=None, reductionOp=None, private=None, & + & extraAccArgs=None, extraOmpArgs=None) + #:set acc_code = ACC_LOOP(collapse=collapse, parallelism=parallelism, data_dependency=data_dependency, reduction=reduction, & + & reductionOp=reductionOp, private=private, extraAccArgs=extraAccArgs) + #:set omp_code = OMP_LOOP(collapse=collapse, parallelism=parallelism, data_dependency=data_dependency, reduction=reduction, & + & reductionOp=reductionOp, private=private, extraOmpArgs=extraOmpArgs) #if defined(MFC_OpenACC) $:acc_code @@ -128,9 +137,14 @@ #endif #:enddef -#:def GPU_DATA(code, copy=None, copyin=None, copyinReadOnly=None, copyout=None, create=None, no_create=None, present=None, deviceptr=None, attach=None, default=None, extraAccArgs=None, extraOmpArgs=None) - #:set acc_code = ACC_DATA(code=code, copy=copy, copyin=copyin, copyinReadOnly=copyinReadOnly, copyout=copyout, create=create, no_create=no_create, present=present, deviceptr=deviceptr, attach=attach, default=default, extraAccArgs=extraAccArgs) - #:set omp_code = OMP_DATA(code=code, copy=copy, copyin=copyin, copyinReadOnly=copyinReadOnly, copyout=copyout, create=create, no_create=no_create, present=present, deviceptr=deviceptr, attach=attach, default=default, extraOmpArgs=extraOmpArgs) +#:def GPU_DATA(code, copy=None, copyin=None, copyinReadOnly=None, copyout=None, create=None, no_create=None, present=None, & + & deviceptr=None, attach=None, default=None, extraAccArgs=None, extraOmpArgs=None) + #:set acc_code = ACC_DATA(code=code, copy=copy, copyin=copyin, copyinReadOnly=copyinReadOnly, copyout=copyout, create=create, & + & no_create=no_create, present=present, deviceptr=deviceptr, attach=attach, default=default, & + & extraAccArgs=extraAccArgs) + #:set omp_code = OMP_DATA(code=code, copy=copy, copyin=copyin, copyinReadOnly=copyinReadOnly, copyout=copyout, create=create, & + & no_create=no_create, present=present, deviceptr=deviceptr, attach=attach, default=default, & + & extraOmpArgs=extraOmpArgs) #if defined(MFC_OpenACC) $:acc_code @@ -142,7 +156,6 @@ #:enddef #:def GPU_HOST_DATA(code, use_device_addr=None, use_device_ptr=None, extraAccArgs=None, extraOmpArgs=None) - #:if use_device_addr is not None and use_device_ptr is not None #:set use_device_addr_end_index = len(use_device_addr) - 1 #:set use_device = use_device_addr + use_device_ptr @@ -158,7 +171,8 @@ #:set use_device = None #:endif #:set acc_code = ACC_HOST_DATA(code=code, use_device=use_device, extraAccArgs=extraAccArgs) - #:set omp_code = OMP_HOST_DATA(code=code, use_device_addr=use_device_addr, use_device_ptr=use_device_ptr, extraOmpArgs=extraOmpArgs) + #:set omp_code = OMP_HOST_DATA(code=code, use_device_addr=use_device_addr, use_device_ptr=use_device_ptr, & + & extraOmpArgs=extraOmpArgs) #if defined(MFC_OpenACC) $:acc_code @@ -170,8 +184,10 @@ #:enddef #:def GPU_ENTER_DATA(copyin=None, copyinReadOnly=None, create=None, attach=None, extraAccArgs=None, extraOmpArgs=None) - #:set acc_code = ACC_ENTER_DATA(copyin=copyin, copyinReadOnly=copyinReadOnly, create=create, attach=attach, extraAccArgs=extraAccArgs) - #:set omp_code = OMP_ENTER_DATA(copyin=copyin, copyinReadOnly=copyinReadOnly, create=create, attach=attach, extraOmpArgs=extraOmpArgs) + #:set acc_code = ACC_ENTER_DATA(copyin=copyin, copyinReadOnly=copyinReadOnly, create=create, attach=attach, & + & extraAccArgs=extraAccArgs) + #:set omp_code = OMP_ENTER_DATA(copyin=copyin, copyinReadOnly=copyinReadOnly, create=create, attach=attach, & + & extraOmpArgs=extraOmpArgs) #if defined(MFC_OpenACC) $:acc_code @@ -235,13 +251,11 @@ #:enddef #:def USE_GPU_MODULE() - #if defined(MFC_OpenACC) use openacc #elif defined(MFC_OpenMP) use omp_lib #endif - #:enddef #:def DEF_AMD(code) diff --git a/src/common/m_boundary_common.fpp b/src/common/m_boundary_common.fpp index 42b816d865..5d8675d84f 100644 --- a/src/common/m_boundary_common.fpp +++ b/src/common/m_boundary_common.fpp @@ -8,44 +8,31 @@ module m_boundary_common - use m_derived_types !< Definitions of the derived types - - use m_global_parameters !< Definitions of the global parameters - + use m_derived_types !< Definitions of the derived types + use m_global_parameters !< Definitions of the global parameters use m_mpi_proxy - use m_constants - use m_delay_file_access - use m_compile_specific implicit none - type(scalar_field), dimension(:, :), allocatable :: bc_buffers + type(scalar_field), dimension(:,:), allocatable :: bc_buffers $:GPU_DECLARE(create='[bc_buffers]') type(int_bounds_info), dimension(3) :: beta_bc_bounds $:GPU_DECLARE(create='[beta_bc_bounds]') #ifdef MFC_MPI - integer, dimension(1:3, 1:2) :: MPI_BC_TYPE_TYPE - integer, dimension(1:3, 1:2) :: MPI_BC_BUFFER_TYPE + integer, dimension(1:3,1:2) :: MPI_BC_TYPE_TYPE + integer, dimension(1:3,1:2) :: MPI_BC_BUFFER_TYPE #endif - private; public :: s_initialize_boundary_common_module, & - s_populate_variables_buffers, & - s_populate_beta_buffers, & - s_create_mpi_types, & - s_populate_capillary_buffers, & - s_populate_F_igr_buffers, & - s_write_serial_boundary_condition_files, & - s_write_parallel_boundary_condition_files, & - s_read_serial_boundary_condition_files, & - s_read_parallel_boundary_condition_files, & - s_assign_default_bc_type, & - s_populate_grid_variables_buffers, & - s_finalize_boundary_common_module + private; public :: s_initialize_boundary_common_module, s_populate_variables_buffers, s_populate_beta_buffers, & + & s_create_mpi_types, s_populate_capillary_buffers, s_populate_F_igr_buffers, s_write_serial_boundary_condition_files, & + & s_write_parallel_boundary_condition_files, s_read_serial_boundary_condition_files, & + & s_read_parallel_boundary_condition_files, s_assign_default_bc_type, s_populate_grid_variables_buffers, & + & s_finalize_boundary_common_module public :: bc_buffers @@ -102,22 +89,21 @@ contains end subroutine s_initialize_boundary_common_module - !> The purpose of this procedure is to populate the buffers - !! of the primitive variables, depending on the selected - !! boundary conditions. + !> The purpose of this procedure is to populate the buffers of the primitive variables, depending on the selected boundary + !! conditions. impure subroutine s_populate_variables_buffers(bc_type, q_prim_vf, pb_in, mv_in) - type(scalar_field), dimension(sys_size), intent(inout) :: q_prim_vf - real(stp), optional, dimension(idwbuff(1)%beg:, idwbuff(2)%beg:, idwbuff(3)%beg:, 1:, 1:), intent(inout) :: pb_in, mv_in - type(integer_field), dimension(1:num_dims, 1:2), intent(in) :: bc_type - - integer :: k, l + type(scalar_field), dimension(sys_size), intent(inout) :: q_prim_vf + real(stp), optional, dimension(idwbuff(1)%beg:,idwbuff(2)%beg:,idwbuff(3)%beg:,1:,1:), intent(inout) :: pb_in, mv_in + type(integer_field), dimension(1:num_dims,1:2), intent(in) :: bc_type + integer :: k, l ! Population of Buffers in x-direction + if (bc_x%beg >= 0) then call s_mpi_sendrecv_variables_buffers(q_prim_vf, 1, -1, sys_size, pb_in, mv_in) else - $:GPU_PARALLEL_LOOP(private='[l,k]', collapse=2) + $:GPU_PARALLEL_LOOP(private='[l, k]', collapse=2) do l = 0, p do k = 0, n select case (int(bc_type(1, 1)%sf(0, k, l))) @@ -135,8 +121,7 @@ contains call s_dirichlet(q_prim_vf, 1, -1, k, l) end select - if (qbmm .and. (.not. polytropic) .and. & - (bc_type(1, 1)%sf(0, k, l) <= BC_GHOST_EXTRAP)) then + if (qbmm .and. (.not. polytropic) .and. (bc_type(1, 1)%sf(0, k, l) <= BC_GHOST_EXTRAP)) then call s_qbmm_extrapolation(1, -1, k, l, pb_in, mv_in) end if end do @@ -147,11 +132,11 @@ contains if (bc_x%end >= 0) then call s_mpi_sendrecv_variables_buffers(q_prim_vf, 1, 1, sys_size, pb_in, mv_in) else - $:GPU_PARALLEL_LOOP(private='[l,k]', collapse=2) + $:GPU_PARALLEL_LOOP(private='[l, k]', collapse=2) do l = 0, p do k = 0, n select case (int(bc_type(1, 2)%sf(0, k, l))) - case (BC_CHAR_SUP_OUTFLOW:BC_GHOST_EXTRAP) ! Ghost-cell extrap. BC at end + case (BC_CHAR_SUP_OUTFLOW:BC_GHOST_EXTRAP) ! Ghost-cell extrap. BC at end call s_ghost_cell_extrapolation(q_prim_vf, 1, 1, k, l) case (BC_REFLECTIVE) call s_symmetry(q_prim_vf, 1, 1, k, l, pb_in, mv_in) @@ -165,8 +150,7 @@ contains call s_dirichlet(q_prim_vf, 1, 1, k, l) end select - if (qbmm .and. (.not. polytropic) .and. & - (bc_type(1, 2)%sf(0, k, l) <= BC_GHOST_EXTRAP)) then + if (qbmm .and. (.not. polytropic) .and. (bc_type(1, 2)%sf(0, k, l) <= BC_GHOST_EXTRAP)) then call s_qbmm_extrapolation(1, 1, k, l, pb_in, mv_in) end if end do @@ -179,11 +163,10 @@ contains if (n == 0) return #:if not MFC_CASE_OPTIMIZATION or num_dims > 1 - if (bc_y%beg >= 0) then call s_mpi_sendrecv_variables_buffers(q_prim_vf, 2, -1, sys_size, pb_in, mv_in) else - $:GPU_PARALLEL_LOOP(private='[l,k]', collapse=2) + $:GPU_PARALLEL_LOOP(private='[l, k]', collapse=2) do l = 0, p do k = -buff_size, m + buff_size select case (int(bc_type(2, 1)%sf(k, 0, l))) @@ -203,9 +186,8 @@ contains call s_dirichlet(q_prim_vf, 2, -1, k, l) end select - if (qbmm .and. (.not. polytropic) .and. & - (bc_type(2, 1)%sf(k, 0, l) <= BC_GHOST_EXTRAP) .and. & - (bc_type(2, 1)%sf(k, 0, l) /= BC_AXIS)) then + if (qbmm .and. (.not. polytropic) .and. (bc_type(2, 1)%sf(k, 0, l) <= BC_GHOST_EXTRAP) .and. (bc_type(2, & + & 1)%sf(k, 0, l) /= BC_AXIS)) then call s_qbmm_extrapolation(2, -1, k, l, pb_in, mv_in) end if end do @@ -216,7 +198,7 @@ contains if (bc_y%end >= 0) then call s_mpi_sendrecv_variables_buffers(q_prim_vf, 2, 1, sys_size, pb_in, mv_in) else - $:GPU_PARALLEL_LOOP(private='[l,k]', collapse=2) + $:GPU_PARALLEL_LOOP(private='[l, k]', collapse=2) do l = 0, p do k = -buff_size, m + buff_size select case (int(bc_type(2, 2)%sf(k, 0, l))) @@ -234,15 +216,13 @@ contains call s_dirichlet(q_prim_vf, 2, 1, k, l) end select - if (qbmm .and. (.not. polytropic) .and. & - (bc_type(2, 2)%sf(k, 0, l) <= BC_GHOST_EXTRAP)) then + if (qbmm .and. (.not. polytropic) .and. (bc_type(2, 2)%sf(k, 0, l) <= BC_GHOST_EXTRAP)) then call s_qbmm_extrapolation(2, 1, k, l, pb_in, mv_in) end if end do end do $:END_GPU_PARALLEL_LOOP() end if - #:endif ! Population of Buffers in z-direction @@ -250,11 +230,10 @@ contains if (p == 0) return #:if not MFC_CASE_OPTIMIZATION or num_dims > 2 - if (bc_z%beg >= 0) then call s_mpi_sendrecv_variables_buffers(q_prim_vf, 3, -1, sys_size, pb_in, mv_in) else - $:GPU_PARALLEL_LOOP(private='[l,k]', collapse=2) + $:GPU_PARALLEL_LOOP(private='[l, k]', collapse=2) do l = -buff_size, n + buff_size do k = -buff_size, m + buff_size select case (int(bc_type(3, 1)%sf(k, l, 0))) @@ -272,8 +251,7 @@ contains call s_dirichlet(q_prim_vf, 3, -1, k, l) end select - if (qbmm .and. (.not. polytropic) .and. & - (bc_type(3, 1)%sf(k, l, 0) <= BC_GHOST_EXTRAP)) then + if (qbmm .and. (.not. polytropic) .and. (bc_type(3, 1)%sf(k, l, 0) <= BC_GHOST_EXTRAP)) then call s_qbmm_extrapolation(3, -1, k, l, pb_in, mv_in) end if end do @@ -284,7 +262,7 @@ contains if (bc_z%end >= 0) then call s_mpi_sendrecv_variables_buffers(q_prim_vf, 3, 1, sys_size, pb_in, mv_in) else - $:GPU_PARALLEL_LOOP(private='[l,k]', collapse=2) + $:GPU_PARALLEL_LOOP(private='[l, k]', collapse=2) do l = -buff_size, n + buff_size do k = -buff_size, m + buff_size select case (int(bc_type(3, 2)%sf(k, l, 0))) @@ -302,8 +280,7 @@ contains call s_dirichlet(q_prim_vf, 3, 1, k, l) end select - if (qbmm .and. (.not. polytropic) .and. & - (bc_type(3, 2)%sf(k, l, 0) <= BC_GHOST_EXTRAP)) then + if (qbmm .and. (.not. polytropic) .and. (bc_type(3, 2)%sf(k, l, 0) <= BC_GHOST_EXTRAP)) then call s_qbmm_extrapolation(3, 1, k, l, pb_in, mv_in) end if end do @@ -317,59 +294,52 @@ contains !> @brief Fills ghost cells by copying the nearest boundary cell value along the specified direction. subroutine s_ghost_cell_extrapolation(q_prim_vf, bc_dir, bc_loc, k, l) - $:GPU_ROUTINE(function_name='s_ghost_cell_extrapolation', & - & parallelism='[seq]', cray_inline=True) - type(scalar_field), dimension(sys_size), intent(inout) :: q_prim_vf - integer, intent(in) :: bc_dir, bc_loc - integer, intent(in) :: k, l - integer :: j, i + $:GPU_ROUTINE(function_name='s_ghost_cell_extrapolation', parallelism='[seq]', cray_inline=True) + type(scalar_field), dimension(sys_size), intent(inout) :: q_prim_vf + integer, intent(in) :: bc_dir, bc_loc + integer, intent(in) :: k, l + integer :: j, i - if (bc_dir == 1) then !< x-direction - if (bc_loc == -1) then !bc_x%beg + if (bc_dir == 1) then !< x-direction + if (bc_loc == -1) then ! bc_x%beg do i = 1, sys_size do j = 1, buff_size - q_prim_vf(i)%sf(-j, k, l) = & - q_prim_vf(i)%sf(0, k, l) + q_prim_vf(i)%sf(-j, k, l) = q_prim_vf(i)%sf(0, k, l) end do end do - else !< bc_x%end + else !< bc_x%end do i = 1, sys_size do j = 1, buff_size - q_prim_vf(i)%sf(m + j, k, l) = & - q_prim_vf(i)%sf(m, k, l) + q_prim_vf(i)%sf(m + j, k, l) = q_prim_vf(i)%sf(m, k, l) end do end do end if - elseif (bc_dir == 2) then !< y-direction - if (bc_loc == -1) then !< bc_y%beg + else if (bc_dir == 2) then !< y-direction + if (bc_loc == -1) then !< bc_y%beg do i = 1, sys_size do j = 1, buff_size - q_prim_vf(i)%sf(k, -j, l) = & - q_prim_vf(i)%sf(k, 0, l) + q_prim_vf(i)%sf(k, -j, l) = q_prim_vf(i)%sf(k, 0, l) end do end do - else !< bc_y%end + else !< bc_y%end do i = 1, sys_size do j = 1, buff_size - q_prim_vf(i)%sf(k, n + j, l) = & - q_prim_vf(i)%sf(k, n, l) + q_prim_vf(i)%sf(k, n + j, l) = q_prim_vf(i)%sf(k, n, l) end do end do end if - elseif (bc_dir == 3) then !< z-direction - if (bc_loc == -1) then !< bc_z%beg + else if (bc_dir == 3) then !< z-direction + if (bc_loc == -1) then !< bc_z%beg do i = 1, sys_size do j = 1, buff_size - q_prim_vf(i)%sf(k, l, -j) = & - q_prim_vf(i)%sf(k, l, 0) + q_prim_vf(i)%sf(k, l, -j) = q_prim_vf(i)%sf(k, l, 0) end do end do - else !< bc_z%end + else !< bc_z%end do i = 1, sys_size do j = 1, buff_size - q_prim_vf(i)%sf(k, l, p + j) = & - q_prim_vf(i)%sf(k, l, p) + q_prim_vf(i)%sf(k, l, p + j) = q_prim_vf(i)%sf(k, l, p) end do end do end if @@ -377,125 +347,108 @@ contains end subroutine s_ghost_cell_extrapolation - !> @brief Applies reflective (symmetry) boundary conditions by mirroring primitive variables and flipping the normal velocity component. + !> @brief Applies reflective (symmetry) boundary conditions by mirroring primitive variables and flipping the normal velocity + !! component. subroutine s_symmetry(q_prim_vf, bc_dir, bc_loc, k, l, pb_in, mv_in) - $:GPU_ROUTINE(parallelism='[seq]') - type(scalar_field), dimension(sys_size), intent(inout) :: q_prim_vf - real(stp), optional, dimension(idwbuff(1)%beg:, idwbuff(2)%beg:, idwbuff(3)%beg:, 1:, 1:), intent(inout) :: pb_in, mv_in - integer, intent(in) :: bc_dir, bc_loc - integer, intent(in) :: k, l - integer :: j, q, i - - if (bc_dir == 1) then !< x-direction - if (bc_loc == -1) then !< bc_x%beg + $:GPU_ROUTINE(parallelism='[seq]') + type(scalar_field), dimension(sys_size), intent(inout) :: q_prim_vf + real(stp), optional, dimension(idwbuff(1)%beg:,idwbuff(2)%beg:,idwbuff(3)%beg:,1:,1:), intent(inout) :: pb_in, mv_in + integer, intent(in) :: bc_dir, bc_loc + integer, intent(in) :: k, l + integer :: j, q, i + + if (bc_dir == 1) then !< x-direction + if (bc_loc == -1) then !< bc_x%beg do j = 1, buff_size do i = 1, contxe - q_prim_vf(i)%sf(-j, k, l) = & - q_prim_vf(i)%sf(j - 1, k, l) + q_prim_vf(i)%sf(-j, k, l) = q_prim_vf(i)%sf(j - 1, k, l) end do - q_prim_vf(momxb)%sf(-j, k, l) = & - -q_prim_vf(momxb)%sf(j - 1, k, l) + q_prim_vf(momxb)%sf(-j, k, l) = -q_prim_vf(momxb)%sf(j - 1, k, l) do i = momxb + 1, sys_size - q_prim_vf(i)%sf(-j, k, l) = & - q_prim_vf(i)%sf(j - 1, k, l) + q_prim_vf(i)%sf(-j, k, l) = q_prim_vf(i)%sf(j - 1, k, l) end do if (elasticity) then do i = 1, shear_BC_flip_num - q_prim_vf(shear_BC_flip_indices(1, i))%sf(-j, k, l) = & - -q_prim_vf(shear_BC_flip_indices(1, i))%sf(j - 1, k, l) + q_prim_vf(shear_BC_flip_indices(1, i))%sf(-j, k, l) = -q_prim_vf(shear_BC_flip_indices(1, & + & i))%sf(j - 1, k, l) end do end if if (hyperelasticity) then - q_prim_vf(xibeg)%sf(-j, k, l) = & - -q_prim_vf(xibeg)%sf(j - 1, k, l) + q_prim_vf(xibeg)%sf(-j, k, l) = -q_prim_vf(xibeg)%sf(j - 1, k, l) end if - end do if (qbmm .and. .not. polytropic) then do i = 1, nb do q = 1, nnode do j = 1, buff_size - pb_in(-j, k, l, q, i) = & - pb_in(j - 1, k, l, q, i) - mv_in(-j, k, l, q, i) = & - mv_in(j - 1, k, l, q, i) + pb_in(-j, k, l, q, i) = pb_in(j - 1, k, l, q, i) + mv_in(-j, k, l, q, i) = mv_in(j - 1, k, l, q, i) end do end do end do end if - else !< bc_x%end + else !< bc_x%end do j = 1, buff_size do i = 1, contxe - q_prim_vf(i)%sf(m + j, k, l) = & - q_prim_vf(i)%sf(m - (j - 1), k, l) + q_prim_vf(i)%sf(m + j, k, l) = q_prim_vf(i)%sf(m - (j - 1), k, l) end do - q_prim_vf(momxb)%sf(m + j, k, l) = & - -q_prim_vf(momxb)%sf(m - (j - 1), k, l) + q_prim_vf(momxb)%sf(m + j, k, l) = -q_prim_vf(momxb)%sf(m - (j - 1), k, l) do i = momxb + 1, sys_size - q_prim_vf(i)%sf(m + j, k, l) = & - q_prim_vf(i)%sf(m - (j - 1), k, l) + q_prim_vf(i)%sf(m + j, k, l) = q_prim_vf(i)%sf(m - (j - 1), k, l) end do if (elasticity) then do i = 1, shear_BC_flip_num - q_prim_vf(shear_BC_flip_indices(1, i))%sf(m + j, k, l) = & - -q_prim_vf(shear_BC_flip_indices(1, i))%sf(m - (j - 1), k, l) + q_prim_vf(shear_BC_flip_indices(1, i))%sf(m + j, k, l) = -q_prim_vf(shear_BC_flip_indices(1, & + & i))%sf(m - (j - 1), k, l) end do end if if (hyperelasticity) then - q_prim_vf(xibeg)%sf(m + j, k, l) = & - -q_prim_vf(xibeg)%sf(m - (j - 1), k, l) + q_prim_vf(xibeg)%sf(m + j, k, l) = -q_prim_vf(xibeg)%sf(m - (j - 1), k, l) end if end do if (qbmm .and. .not. polytropic) then - do i = 1, nb do q = 1, nnode do j = 1, buff_size - pb_in(m + j, k, l, q, i) = & - pb_in(m - (j - 1), k, l, q, i) - mv_in(m + j, k, l, q, i) = & - mv_in(m - (j - 1), k, l, q, i) + pb_in(m + j, k, l, q, i) = pb_in(m - (j - 1), k, l, q, i) + mv_in(m + j, k, l, q, i) = mv_in(m - (j - 1), k, l, q, i) end do end do end do end if end if - elseif (bc_dir == 2) then !< y-direction - if (bc_loc == -1) then !< bc_y%beg + else if (bc_dir == 2) then !< y-direction + if (bc_loc == -1) then !< bc_y%beg do j = 1, buff_size do i = 1, momxb - q_prim_vf(i)%sf(k, -j, l) = & - q_prim_vf(i)%sf(k, j - 1, l) + q_prim_vf(i)%sf(k, -j, l) = q_prim_vf(i)%sf(k, j - 1, l) end do - q_prim_vf(momxb + 1)%sf(k, -j, l) = & - -q_prim_vf(momxb + 1)%sf(k, j - 1, l) + q_prim_vf(momxb + 1)%sf(k, -j, l) = -q_prim_vf(momxb + 1)%sf(k, j - 1, l) do i = momxb + 2, sys_size - q_prim_vf(i)%sf(k, -j, l) = & - q_prim_vf(i)%sf(k, j - 1, l) + q_prim_vf(i)%sf(k, -j, l) = q_prim_vf(i)%sf(k, j - 1, l) end do if (elasticity) then do i = 1, shear_BC_flip_num - q_prim_vf(shear_BC_flip_indices(2, i))%sf(k, -j, l) = & - -q_prim_vf(shear_BC_flip_indices(2, i))%sf(k, j - 1, l) + q_prim_vf(shear_BC_flip_indices(2, i))%sf(k, -j, l) = -q_prim_vf(shear_BC_flip_indices(2, i))%sf(k, & + & j - 1, l) end do end if if (hyperelasticity) then - q_prim_vf(xibeg + 1)%sf(k, -j, l) = & - -q_prim_vf(xibeg + 1)%sf(k, j - 1, l) + q_prim_vf(xibeg + 1)%sf(k, -j, l) = -q_prim_vf(xibeg + 1)%sf(k, j - 1, l) end if end do @@ -503,39 +456,33 @@ contains do i = 1, nb do q = 1, nnode do j = 1, buff_size - pb_in(k, -j, l, q, i) = & - pb_in(k, j - 1, l, q, i) - mv_in(k, -j, l, q, i) = & - mv_in(k, j - 1, l, q, i) + pb_in(k, -j, l, q, i) = pb_in(k, j - 1, l, q, i) + mv_in(k, -j, l, q, i) = mv_in(k, j - 1, l, q, i) end do end do end do end if - else !< bc_y%end + else !< bc_y%end do j = 1, buff_size do i = 1, momxb - q_prim_vf(i)%sf(k, n + j, l) = & - q_prim_vf(i)%sf(k, n - (j - 1), l) + q_prim_vf(i)%sf(k, n + j, l) = q_prim_vf(i)%sf(k, n - (j - 1), l) end do - q_prim_vf(momxb + 1)%sf(k, n + j, l) = & - -q_prim_vf(momxb + 1)%sf(k, n - (j - 1), l) + q_prim_vf(momxb + 1)%sf(k, n + j, l) = -q_prim_vf(momxb + 1)%sf(k, n - (j - 1), l) do i = momxb + 2, sys_size - q_prim_vf(i)%sf(k, n + j, l) = & - q_prim_vf(i)%sf(k, n - (j - 1), l) + q_prim_vf(i)%sf(k, n + j, l) = q_prim_vf(i)%sf(k, n - (j - 1), l) end do if (elasticity) then do i = 1, shear_BC_flip_num - q_prim_vf(shear_BC_flip_indices(2, i))%sf(k, n + j, l) = & - -q_prim_vf(shear_BC_flip_indices(2, i))%sf(k, n - (j - 1), l) + q_prim_vf(shear_BC_flip_indices(2, i))%sf(k, n + j, l) = -q_prim_vf(shear_BC_flip_indices(2, & + & i))%sf(k, n - (j - 1), l) end do end if if (hyperelasticity) then - q_prim_vf(xibeg + 1)%sf(k, n + j, l) = & - -q_prim_vf(xibeg + 1)%sf(k, n - (j - 1), l) + q_prim_vf(xibeg + 1)%sf(k, n + j, l) = -q_prim_vf(xibeg + 1)%sf(k, n - (j - 1), l) end if end do @@ -543,41 +490,35 @@ contains do i = 1, nb do q = 1, nnode do j = 1, buff_size - pb_in(k, n + j, l, q, i) = & - pb_in(k, n - (j - 1), l, q, i) - mv_in(k, n + j, l, q, i) = & - mv_in(k, n - (j - 1), l, q, i) + pb_in(k, n + j, l, q, i) = pb_in(k, n - (j - 1), l, q, i) + mv_in(k, n + j, l, q, i) = mv_in(k, n - (j - 1), l, q, i) end do end do end do end if end if - elseif (bc_dir == 3) then !< z-direction - if (bc_loc == -1) then !< bc_z%beg + else if (bc_dir == 3) then !< z-direction + if (bc_loc == -1) then !< bc_z%beg do j = 1, buff_size do i = 1, momxb + 1 - q_prim_vf(i)%sf(k, l, -j) = & - q_prim_vf(i)%sf(k, l, j - 1) + q_prim_vf(i)%sf(k, l, -j) = q_prim_vf(i)%sf(k, l, j - 1) end do - q_prim_vf(momxe)%sf(k, l, -j) = & - -q_prim_vf(momxe)%sf(k, l, j - 1) + q_prim_vf(momxe)%sf(k, l, -j) = -q_prim_vf(momxe)%sf(k, l, j - 1) do i = E_idx, sys_size - q_prim_vf(i)%sf(k, l, -j) = & - q_prim_vf(i)%sf(k, l, j - 1) + q_prim_vf(i)%sf(k, l, -j) = q_prim_vf(i)%sf(k, l, j - 1) end do if (elasticity) then do i = 1, shear_BC_flip_num - q_prim_vf(shear_BC_flip_indices(3, i))%sf(k, l, -j) = & - -q_prim_vf(shear_BC_flip_indices(3, i))%sf(k, l, j - 1) + q_prim_vf(shear_BC_flip_indices(3, i))%sf(k, l, -j) = -q_prim_vf(shear_BC_flip_indices(3, i))%sf(k, & + & l, j - 1) end do end if if (hyperelasticity) then - q_prim_vf(xiend)%sf(k, l, -j) = & - -q_prim_vf(xiend)%sf(k, l, j - 1) + q_prim_vf(xiend)%sf(k, l, -j) = -q_prim_vf(xiend)%sf(k, l, j - 1) end if end do @@ -585,39 +526,33 @@ contains do i = 1, nb do q = 1, nnode do j = 1, buff_size - pb_in(k, l, -j, q, i) = & - pb_in(k, l, j - 1, q, i) - mv_in(k, l, -j, q, i) = & - mv_in(k, l, j - 1, q, i) + pb_in(k, l, -j, q, i) = pb_in(k, l, j - 1, q, i) + mv_in(k, l, -j, q, i) = mv_in(k, l, j - 1, q, i) end do end do end do end if - else !< bc_z%end + else !< bc_z%end do j = 1, buff_size do i = 1, momxb + 1 - q_prim_vf(i)%sf(k, l, p + j) = & - q_prim_vf(i)%sf(k, l, p - (j - 1)) + q_prim_vf(i)%sf(k, l, p + j) = q_prim_vf(i)%sf(k, l, p - (j - 1)) end do - q_prim_vf(momxe)%sf(k, l, p + j) = & - -q_prim_vf(momxe)%sf(k, l, p - (j - 1)) + q_prim_vf(momxe)%sf(k, l, p + j) = -q_prim_vf(momxe)%sf(k, l, p - (j - 1)) do i = E_idx, sys_size - q_prim_vf(i)%sf(k, l, p + j) = & - q_prim_vf(i)%sf(k, l, p - (j - 1)) + q_prim_vf(i)%sf(k, l, p + j) = q_prim_vf(i)%sf(k, l, p - (j - 1)) end do if (elasticity) then do i = 1, shear_BC_flip_num - q_prim_vf(shear_BC_flip_indices(3, i))%sf(k, l, p + j) = & - -q_prim_vf(shear_BC_flip_indices(3, i))%sf(k, l, p - (j - 1)) + q_prim_vf(shear_BC_flip_indices(3, i))%sf(k, l, p + j) = -q_prim_vf(shear_BC_flip_indices(3, & + & i))%sf(k, l, p - (j - 1)) end do end if if (hyperelasticity) then - q_prim_vf(xiend)%sf(k, l, p + j) = & - -q_prim_vf(xiend)%sf(k, l, p - (j - 1)) + q_prim_vf(xiend)%sf(k, l, p + j) = -q_prim_vf(xiend)%sf(k, l, p - (j - 1)) end if end do @@ -625,10 +560,8 @@ contains do i = 1, nb do q = 1, nnode do j = 1, buff_size - pb_in(k, l, p + j, q, i) = & - pb_in(k, l, p - (j - 1), q, i) - mv_in(k, l, p + j, q, i) = & - mv_in(k, l, p - (j - 1), q, i) + pb_in(k, l, p + j, q, i) = pb_in(k, l, p - (j - 1), q, i) + mv_in(k, l, p + j, q, i) = mv_in(k, l, p - (j - 1), q, i) end do end do end do @@ -640,20 +573,19 @@ contains !> @brief Applies periodic boundary conditions by copying values from the opposite domain boundary. subroutine s_periodic(q_prim_vf, bc_dir, bc_loc, k, l, pb_in, mv_in) - $:GPU_ROUTINE(parallelism='[seq]') - type(scalar_field), dimension(sys_size), intent(inout) :: q_prim_vf - real(stp), optional, dimension(idwbuff(1)%beg:, idwbuff(2)%beg:, idwbuff(3)%beg:, 1:, 1:), intent(inout) :: pb_in, mv_in - integer, intent(in) :: bc_dir, bc_loc - integer, intent(in) :: k, l - - integer :: j, q, i - if (bc_dir == 1) then !< x-direction - if (bc_loc == -1) then !< bc_x%beg + $:GPU_ROUTINE(parallelism='[seq]') + type(scalar_field), dimension(sys_size), intent(inout) :: q_prim_vf + real(stp), optional, dimension(idwbuff(1)%beg:,idwbuff(2)%beg:,idwbuff(3)%beg:,1:,1:), intent(inout) :: pb_in, mv_in + integer, intent(in) :: bc_dir, bc_loc + integer, intent(in) :: k, l + integer :: j, q, i + + if (bc_dir == 1) then !< x-direction + if (bc_loc == -1) then !< bc_x%beg do i = 1, sys_size do j = 1, buff_size - q_prim_vf(i)%sf(-j, k, l) = & - q_prim_vf(i)%sf(m - (j - 1), k, l) + q_prim_vf(i)%sf(-j, k, l) = q_prim_vf(i)%sf(m - (j - 1), k, l) end do end do @@ -661,19 +593,16 @@ contains do i = 1, nb do q = 1, nnode do j = 1, buff_size - pb_in(-j, k, l, q, i) = & - pb_in(m - (j - 1), k, l, q, i) - mv_in(-j, k, l, q, i) = & - mv_in(m - (j - 1), k, l, q, i) + pb_in(-j, k, l, q, i) = pb_in(m - (j - 1), k, l, q, i) + mv_in(-j, k, l, q, i) = mv_in(m - (j - 1), k, l, q, i) end do end do end do end if - else !< bc_x%end + else !< bc_x%end do i = 1, sys_size do j = 1, buff_size - q_prim_vf(i)%sf(m + j, k, l) = & - q_prim_vf(i)%sf(j - 1, k, l) + q_prim_vf(i)%sf(m + j, k, l) = q_prim_vf(i)%sf(j - 1, k, l) end do end do @@ -681,21 +610,18 @@ contains do i = 1, nb do q = 1, nnode do j = 1, buff_size - pb_in(m + j, k, l, q, i) = & - pb_in(j - 1, k, l, q, i) - mv_in(m + j, k, l, q, i) = & - mv_in(j - 1, k, l, q, i) + pb_in(m + j, k, l, q, i) = pb_in(j - 1, k, l, q, i) + mv_in(m + j, k, l, q, i) = mv_in(j - 1, k, l, q, i) end do end do end do end if end if - elseif (bc_dir == 2) then !< y-direction - if (bc_loc == -1) then !< bc_y%beg + else if (bc_dir == 2) then !< y-direction + if (bc_loc == -1) then !< bc_y%beg do i = 1, sys_size do j = 1, buff_size - q_prim_vf(i)%sf(k, -j, l) = & - q_prim_vf(i)%sf(k, n - (j - 1), l) + q_prim_vf(i)%sf(k, -j, l) = q_prim_vf(i)%sf(k, n - (j - 1), l) end do end do @@ -703,19 +629,16 @@ contains do i = 1, nb do q = 1, nnode do j = 1, buff_size - pb_in(k, -j, l, q, i) = & - pb_in(k, n - (j - 1), l, q, i) - mv_in(k, -j, l, q, i) = & - mv_in(k, n - (j - 1), l, q, i) + pb_in(k, -j, l, q, i) = pb_in(k, n - (j - 1), l, q, i) + mv_in(k, -j, l, q, i) = mv_in(k, n - (j - 1), l, q, i) end do end do end do end if - else !< bc_y%end + else !< bc_y%end do i = 1, sys_size do j = 1, buff_size - q_prim_vf(i)%sf(k, n + j, l) = & - q_prim_vf(i)%sf(k, j - 1, l) + q_prim_vf(i)%sf(k, n + j, l) = q_prim_vf(i)%sf(k, j - 1, l) end do end do @@ -723,21 +646,18 @@ contains do i = 1, nb do q = 1, nnode do j = 1, buff_size - pb_in(k, n + j, l, q, i) = & - pb_in(k, (j - 1), l, q, i) - mv_in(k, n + j, l, q, i) = & - mv_in(k, (j - 1), l, q, i) + pb_in(k, n + j, l, q, i) = pb_in(k, (j - 1), l, q, i) + mv_in(k, n + j, l, q, i) = mv_in(k, (j - 1), l, q, i) end do end do end do end if end if - elseif (bc_dir == 3) then !< z-direction - if (bc_loc == -1) then !< bc_z%beg + else if (bc_dir == 3) then !< z-direction + if (bc_loc == -1) then !< bc_z%beg do i = 1, sys_size do j = 1, buff_size - q_prim_vf(i)%sf(k, l, -j) = & - q_prim_vf(i)%sf(k, l, p - (j - 1)) + q_prim_vf(i)%sf(k, l, -j) = q_prim_vf(i)%sf(k, l, p - (j - 1)) end do end do @@ -745,19 +665,16 @@ contains do i = 1, nb do q = 1, nnode do j = 1, buff_size - pb_in(k, l, -j, q, i) = & - pb_in(k, l, p - (j - 1), q, i) - mv_in(k, l, -j, q, i) = & - mv_in(k, l, p - (j - 1), q, i) + pb_in(k, l, -j, q, i) = pb_in(k, l, p - (j - 1), q, i) + mv_in(k, l, -j, q, i) = mv_in(k, l, p - (j - 1), q, i) end do end do end do end if - else !< bc_z%end + else !< bc_z%end do i = 1, sys_size do j = 1, buff_size - q_prim_vf(i)%sf(k, l, p + j) = & - q_prim_vf(i)%sf(k, l, j - 1) + q_prim_vf(i)%sf(k, l, p + j) = q_prim_vf(i)%sf(k, l, j - 1) end do end do @@ -765,10 +682,8 @@ contains do i = 1, nb do q = 1, nnode do j = 1, buff_size - pb_in(k, l, p + j, q, i) = & - pb_in(k, l, j - 1, q, i) - mv_in(k, l, p + j, q, i) = & - mv_in(k, l, j - 1, q, i) + pb_in(k, l, p + j, q, i) = pb_in(k, l, j - 1, q, i) + mv_in(k, l, p + j, q, i) = mv_in(k, l, j - 1, q, i) end do end do end do @@ -778,47 +693,40 @@ contains end subroutine s_periodic - !> @brief Applies axis boundary conditions for cylindrical coordinates by reflecting values across the axis with azimuthal phase shift. + !> @brief Applies axis boundary conditions for cylindrical coordinates by reflecting values across the axis with azimuthal phase + !! shift. subroutine s_axis(q_prim_vf, pb_in, mv_in, k, l) - $:GPU_ROUTINE(parallelism='[seq]') - type(scalar_field), dimension(sys_size), intent(inout) :: q_prim_vf - real(stp), dimension(idwbuff(1)%beg:, idwbuff(2)%beg:, idwbuff(3)%beg:, 1:, 1:), intent(inout) :: pb_in, mv_in - integer, intent(in) :: k, l - integer :: j, q, i + $:GPU_ROUTINE(parallelism='[seq]') + type(scalar_field), dimension(sys_size), intent(inout) :: q_prim_vf + real(stp), dimension(idwbuff(1)%beg:,idwbuff(2)%beg:,idwbuff(3)%beg:,1:,1:), intent(inout) :: pb_in, mv_in + integer, intent(in) :: k, l + integer :: j, q, i do j = 1, buff_size if (z_cc(l) < pi) then do i = 1, momxb - q_prim_vf(i)%sf(k, -j, l) = & - q_prim_vf(i)%sf(k, j - 1, l + ((p + 1)/2)) + q_prim_vf(i)%sf(k, -j, l) = q_prim_vf(i)%sf(k, j - 1, l + ((p + 1)/2)) end do - q_prim_vf(momxb + 1)%sf(k, -j, l) = & - -q_prim_vf(momxb + 1)%sf(k, j - 1, l + ((p + 1)/2)) + q_prim_vf(momxb + 1)%sf(k, -j, l) = -q_prim_vf(momxb + 1)%sf(k, j - 1, l + ((p + 1)/2)) - q_prim_vf(momxe)%sf(k, -j, l) = & - -q_prim_vf(momxe)%sf(k, j - 1, l + ((p + 1)/2)) + q_prim_vf(momxe)%sf(k, -j, l) = -q_prim_vf(momxe)%sf(k, j - 1, l + ((p + 1)/2)) do i = E_idx, sys_size - q_prim_vf(i)%sf(k, -j, l) = & - q_prim_vf(i)%sf(k, j - 1, l + ((p + 1)/2)) + q_prim_vf(i)%sf(k, -j, l) = q_prim_vf(i)%sf(k, j - 1, l + ((p + 1)/2)) end do else do i = 1, momxb - q_prim_vf(i)%sf(k, -j, l) = & - q_prim_vf(i)%sf(k, j - 1, l - ((p + 1)/2)) + q_prim_vf(i)%sf(k, -j, l) = q_prim_vf(i)%sf(k, j - 1, l - ((p + 1)/2)) end do - q_prim_vf(momxb + 1)%sf(k, -j, l) = & - -q_prim_vf(momxb + 1)%sf(k, j - 1, l - ((p + 1)/2)) + q_prim_vf(momxb + 1)%sf(k, -j, l) = -q_prim_vf(momxb + 1)%sf(k, j - 1, l - ((p + 1)/2)) - q_prim_vf(momxe)%sf(k, -j, l) = & - -q_prim_vf(momxe)%sf(k, j - 1, l - ((p + 1)/2)) + q_prim_vf(momxe)%sf(k, -j, l) = -q_prim_vf(momxe)%sf(k, j - 1, l - ((p + 1)/2)) do i = E_idx, sys_size - q_prim_vf(i)%sf(k, -j, l) = & - q_prim_vf(i)%sf(k, j - 1, l - ((p + 1)/2)) + q_prim_vf(i)%sf(k, -j, l) = q_prim_vf(i)%sf(k, j - 1, l - ((p + 1)/2)) end do end if end do @@ -827,10 +735,8 @@ contains do i = 1, nb do q = 1, nnode do j = 1, buff_size - pb_in(k, -j, l, q, i) = & - pb_in(k, j - 1, l - ((p + 1)/2), q, i) - mv_in(k, -j, l, q, i) = & - mv_in(k, j - 1, l - ((p + 1)/2), q, i) + pb_in(k, -j, l, q, i) = pb_in(k, j - 1, l - ((p + 1)/2), q, i) + mv_in(k, -j, l, q, i) = mv_in(k, j - 1, l - ((p + 1)/2), q, i) end do end do end do @@ -840,88 +746,75 @@ contains !> @brief Applies slip wall boundary conditions by extrapolating scalars and reflecting the wall-normal velocity component. subroutine s_slip_wall(q_prim_vf, bc_dir, bc_loc, k, l) - $:GPU_ROUTINE(function_name='s_slip_wall',parallelism='[seq]', & - & cray_inline=True) - type(scalar_field), dimension(sys_size), intent(inout) :: q_prim_vf - integer, intent(in) :: bc_dir, bc_loc - integer, intent(in) :: k, l - integer :: j, i + $:GPU_ROUTINE(function_name='s_slip_wall',parallelism='[seq]', cray_inline=True) + type(scalar_field), dimension(sys_size), intent(inout) :: q_prim_vf + integer, intent(in) :: bc_dir, bc_loc + integer, intent(in) :: k, l + integer :: j, i - if (bc_dir == 1) then !< x-direction - if (bc_loc == -1) then !< bc_x%beg + if (bc_dir == 1) then !< x-direction + if (bc_loc == -1) then !< bc_x%beg do i = 1, sys_size do j = 1, buff_size if (i == momxb) then - q_prim_vf(i)%sf(-j, k, l) = & - -q_prim_vf(i)%sf(j - 1, k, l) + 2._wp*bc_x%vb1 + q_prim_vf(i)%sf(-j, k, l) = -q_prim_vf(i)%sf(j - 1, k, l) + 2._wp*bc_x%vb1 else - q_prim_vf(i)%sf(-j, k, l) = & - q_prim_vf(i)%sf(0, k, l) + q_prim_vf(i)%sf(-j, k, l) = q_prim_vf(i)%sf(0, k, l) end if end do end do - else !< bc_x%end + else !< bc_x%end do i = 1, sys_size do j = 1, buff_size if (i == momxb) then - q_prim_vf(i)%sf(m + j, k, l) = & - -q_prim_vf(i)%sf(m - (j - 1), k, l) + 2._wp*bc_x%ve1 + q_prim_vf(i)%sf(m + j, k, l) = -q_prim_vf(i)%sf(m - (j - 1), k, l) + 2._wp*bc_x%ve1 else - q_prim_vf(i)%sf(m + j, k, l) = & - q_prim_vf(i)%sf(m, k, l) + q_prim_vf(i)%sf(m + j, k, l) = q_prim_vf(i)%sf(m, k, l) end if end do end do end if - elseif (bc_dir == 2) then !< y-direction - if (bc_loc == -1) then !< bc_y%beg + else if (bc_dir == 2) then !< y-direction + if (bc_loc == -1) then !< bc_y%beg do i = 1, sys_size do j = 1, buff_size if (i == momxb + 1) then - q_prim_vf(i)%sf(k, -j, l) = & - -q_prim_vf(i)%sf(k, j - 1, l) + 2._wp*bc_y%vb2 + q_prim_vf(i)%sf(k, -j, l) = -q_prim_vf(i)%sf(k, j - 1, l) + 2._wp*bc_y%vb2 else - q_prim_vf(i)%sf(k, -j, l) = & - q_prim_vf(i)%sf(k, 0, l) + q_prim_vf(i)%sf(k, -j, l) = q_prim_vf(i)%sf(k, 0, l) end if end do end do - else !< bc_y%end + else !< bc_y%end do i = 1, sys_size do j = 1, buff_size if (i == momxb + 1) then - q_prim_vf(i)%sf(k, n + j, l) = & - -q_prim_vf(i)%sf(k, n - (j - 1), l) + 2._wp*bc_y%ve2 + q_prim_vf(i)%sf(k, n + j, l) = -q_prim_vf(i)%sf(k, n - (j - 1), l) + 2._wp*bc_y%ve2 else - q_prim_vf(i)%sf(k, n + j, l) = & - q_prim_vf(i)%sf(k, n, l) + q_prim_vf(i)%sf(k, n + j, l) = q_prim_vf(i)%sf(k, n, l) end if end do end do end if - elseif (bc_dir == 3) then !< z-direction - if (bc_loc == -1) then !< bc_z%beg + else if (bc_dir == 3) then !< z-direction + if (bc_loc == -1) then !< bc_z%beg do i = 1, sys_size do j = 1, buff_size if (i == momxe) then - q_prim_vf(i)%sf(k, l, -j) = & - -q_prim_vf(i)%sf(k, l, j - 1) + 2._wp*bc_z%vb3 + q_prim_vf(i)%sf(k, l, -j) = -q_prim_vf(i)%sf(k, l, j - 1) + 2._wp*bc_z%vb3 else - q_prim_vf(i)%sf(k, l, -j) = & - q_prim_vf(i)%sf(k, l, 0) + q_prim_vf(i)%sf(k, l, -j) = q_prim_vf(i)%sf(k, l, 0) end if end do end do - else !< bc_z%end + else !< bc_z%end do i = 1, sys_size do j = 1, buff_size if (i == momxe) then - q_prim_vf(i)%sf(k, l, p + j) = & - -q_prim_vf(i)%sf(k, l, p - (j - 1)) + 2._wp*bc_z%ve3 + q_prim_vf(i)%sf(k, l, p + j) = -q_prim_vf(i)%sf(k, l, p - (j - 1)) + 2._wp*bc_z%ve3 else - q_prim_vf(i)%sf(k, l, p + j) = & - q_prim_vf(i)%sf(k, l, p) + q_prim_vf(i)%sf(k, l, p + j) = q_prim_vf(i)%sf(k, l, p) end if end do end do @@ -932,125 +825,100 @@ contains !> @brief Applies no-slip wall boundary conditions by reflecting and negating all velocity components at the wall. subroutine s_no_slip_wall(q_prim_vf, bc_dir, bc_loc, k, l) - $:GPU_ROUTINE(function_name='s_no_slip_wall',parallelism='[seq]', & - & cray_inline=True) - type(scalar_field), dimension(sys_size), intent(inout) :: q_prim_vf - integer, intent(in) :: bc_dir, bc_loc - integer, intent(in) :: k, l + $:GPU_ROUTINE(function_name='s_no_slip_wall',parallelism='[seq]', cray_inline=True) - integer :: j, i + type(scalar_field), dimension(sys_size), intent(inout) :: q_prim_vf + integer, intent(in) :: bc_dir, bc_loc + integer, intent(in) :: k, l + integer :: j, i - if (bc_dir == 1) then !< x-direction - if (bc_loc == -1) then !< bc_x%beg + if (bc_dir == 1) then !< x-direction + if (bc_loc == -1) then !< bc_x%beg do i = 1, sys_size do j = 1, buff_size if (i == momxb) then - q_prim_vf(i)%sf(-j, k, l) = & - -q_prim_vf(i)%sf(j - 1, k, l) + 2._wp*bc_x%vb1 - elseif (i == momxb + 1 .and. num_dims > 1) then - q_prim_vf(i)%sf(-j, k, l) = & - -q_prim_vf(i)%sf(j - 1, k, l) + 2._wp*bc_x%vb2 - elseif (i == momxb + 2 .and. num_dims > 2) then - q_prim_vf(i)%sf(-j, k, l) = & - -q_prim_vf(i)%sf(j - 1, k, l) + 2._wp*bc_x%vb3 + q_prim_vf(i)%sf(-j, k, l) = -q_prim_vf(i)%sf(j - 1, k, l) + 2._wp*bc_x%vb1 + else if (i == momxb + 1 .and. num_dims > 1) then + q_prim_vf(i)%sf(-j, k, l) = -q_prim_vf(i)%sf(j - 1, k, l) + 2._wp*bc_x%vb2 + else if (i == momxb + 2 .and. num_dims > 2) then + q_prim_vf(i)%sf(-j, k, l) = -q_prim_vf(i)%sf(j - 1, k, l) + 2._wp*bc_x%vb3 else - q_prim_vf(i)%sf(-j, k, l) = & - q_prim_vf(i)%sf(0, k, l) + q_prim_vf(i)%sf(-j, k, l) = q_prim_vf(i)%sf(0, k, l) end if end do end do - else !< bc_x%end + else !< bc_x%end do i = 1, sys_size do j = 1, buff_size if (i == momxb) then - q_prim_vf(i)%sf(m + j, k, l) = & - -q_prim_vf(i)%sf(m - (j - 1), k, l) + 2._wp*bc_x%ve1 - elseif (i == momxb + 1 .and. num_dims > 1) then - q_prim_vf(i)%sf(m + j, k, l) = & - -q_prim_vf(i)%sf(m - (j - 1), k, l) + 2._wp*bc_x%ve2 - elseif (i == momxb + 2 .and. num_dims > 2) then - q_prim_vf(i)%sf(m + j, k, l) = & - -q_prim_vf(i)%sf(m - (j - 1), k, l) + 2._wp*bc_x%ve3 + q_prim_vf(i)%sf(m + j, k, l) = -q_prim_vf(i)%sf(m - (j - 1), k, l) + 2._wp*bc_x%ve1 + else if (i == momxb + 1 .and. num_dims > 1) then + q_prim_vf(i)%sf(m + j, k, l) = -q_prim_vf(i)%sf(m - (j - 1), k, l) + 2._wp*bc_x%ve2 + else if (i == momxb + 2 .and. num_dims > 2) then + q_prim_vf(i)%sf(m + j, k, l) = -q_prim_vf(i)%sf(m - (j - 1), k, l) + 2._wp*bc_x%ve3 else - q_prim_vf(i)%sf(m + j, k, l) = & - q_prim_vf(i)%sf(m, k, l) + q_prim_vf(i)%sf(m + j, k, l) = q_prim_vf(i)%sf(m, k, l) end if end do end do end if - elseif (bc_dir == 2) then !< y-direction - if (bc_loc == -1) then !< bc_y%beg + else if (bc_dir == 2) then !< y-direction + if (bc_loc == -1) then !< bc_y%beg do i = 1, sys_size do j = 1, buff_size if (i == momxb) then - q_prim_vf(i)%sf(k, -j, l) = & - -q_prim_vf(i)%sf(k, j - 1, l) + 2._wp*bc_y%vb1 - elseif (i == momxb + 1 .and. num_dims > 1) then - q_prim_vf(i)%sf(k, -j, l) = & - -q_prim_vf(i)%sf(k, j - 1, l) + 2._wp*bc_y%vb2 - elseif (i == momxb + 2 .and. num_dims > 2) then - q_prim_vf(i)%sf(k, -j, l) = & - -q_prim_vf(i)%sf(k, j - 1, l) + 2._wp*bc_y%vb3 + q_prim_vf(i)%sf(k, -j, l) = -q_prim_vf(i)%sf(k, j - 1, l) + 2._wp*bc_y%vb1 + else if (i == momxb + 1 .and. num_dims > 1) then + q_prim_vf(i)%sf(k, -j, l) = -q_prim_vf(i)%sf(k, j - 1, l) + 2._wp*bc_y%vb2 + else if (i == momxb + 2 .and. num_dims > 2) then + q_prim_vf(i)%sf(k, -j, l) = -q_prim_vf(i)%sf(k, j - 1, l) + 2._wp*bc_y%vb3 else - q_prim_vf(i)%sf(k, -j, l) = & - q_prim_vf(i)%sf(k, 0, l) + q_prim_vf(i)%sf(k, -j, l) = q_prim_vf(i)%sf(k, 0, l) end if end do end do - else !< bc_y%end + else !< bc_y%end do i = 1, sys_size do j = 1, buff_size if (i == momxb) then - q_prim_vf(i)%sf(k, n + j, l) = & - -q_prim_vf(i)%sf(k, n - (j - 1), l) + 2._wp*bc_y%ve1 - elseif (i == momxb + 1 .and. num_dims > 1) then - q_prim_vf(i)%sf(k, n + j, l) = & - -q_prim_vf(i)%sf(k, n - (j - 1), l) + 2._wp*bc_y%ve2 - elseif (i == momxb + 2 .and. num_dims > 2) then - q_prim_vf(i)%sf(k, n + j, l) = & - -q_prim_vf(i)%sf(k, n - (j - 1), l) + 2._wp*bc_y%ve3 + q_prim_vf(i)%sf(k, n + j, l) = -q_prim_vf(i)%sf(k, n - (j - 1), l) + 2._wp*bc_y%ve1 + else if (i == momxb + 1 .and. num_dims > 1) then + q_prim_vf(i)%sf(k, n + j, l) = -q_prim_vf(i)%sf(k, n - (j - 1), l) + 2._wp*bc_y%ve2 + else if (i == momxb + 2 .and. num_dims > 2) then + q_prim_vf(i)%sf(k, n + j, l) = -q_prim_vf(i)%sf(k, n - (j - 1), l) + 2._wp*bc_y%ve3 else - q_prim_vf(i)%sf(k, n + j, l) = & - q_prim_vf(i)%sf(k, n, l) + q_prim_vf(i)%sf(k, n + j, l) = q_prim_vf(i)%sf(k, n, l) end if end do end do end if - elseif (bc_dir == 3) then !< z-direction - if (bc_loc == -1) then !< bc_z%beg + else if (bc_dir == 3) then !< z-direction + if (bc_loc == -1) then !< bc_z%beg do i = 1, sys_size do j = 1, buff_size if (i == momxb) then - q_prim_vf(i)%sf(k, l, -j) = & - -q_prim_vf(i)%sf(k, l, j - 1) + 2._wp*bc_z%vb1 - elseif (i == momxb + 1 .and. num_dims > 1) then - q_prim_vf(i)%sf(k, l, -j) = & - -q_prim_vf(i)%sf(k, l, j - 1) + 2._wp*bc_z%vb2 - elseif (i == momxb + 2 .and. num_dims > 2) then - q_prim_vf(i)%sf(k, l, -j) = & - -q_prim_vf(i)%sf(k, l, j - 1) + 2._wp*bc_z%vb3 + q_prim_vf(i)%sf(k, l, -j) = -q_prim_vf(i)%sf(k, l, j - 1) + 2._wp*bc_z%vb1 + else if (i == momxb + 1 .and. num_dims > 1) then + q_prim_vf(i)%sf(k, l, -j) = -q_prim_vf(i)%sf(k, l, j - 1) + 2._wp*bc_z%vb2 + else if (i == momxb + 2 .and. num_dims > 2) then + q_prim_vf(i)%sf(k, l, -j) = -q_prim_vf(i)%sf(k, l, j - 1) + 2._wp*bc_z%vb3 else - q_prim_vf(i)%sf(k, l, -j) = & - q_prim_vf(i)%sf(k, l, 0) + q_prim_vf(i)%sf(k, l, -j) = q_prim_vf(i)%sf(k, l, 0) end if end do end do - else !< bc_z%end + else !< bc_z%end do i = 1, sys_size do j = 1, buff_size if (i == momxb) then - q_prim_vf(i)%sf(k, l, p + j) = & - -q_prim_vf(i)%sf(k, l, p - (j - 1)) + 2._wp*bc_z%ve1 - elseif (i == momxb + 1 .and. num_dims > 1) then - q_prim_vf(i)%sf(k, l, p + j) = & - -q_prim_vf(i)%sf(k, l, p - (j - 1)) + 2._wp*bc_z%ve2 - elseif (i == momxb + 2 .and. num_dims > 2) then - q_prim_vf(i)%sf(k, l, p + j) = & - -q_prim_vf(i)%sf(k, l, p - (j - 1)) + 2._wp*bc_z%ve3 + q_prim_vf(i)%sf(k, l, p + j) = -q_prim_vf(i)%sf(k, l, p - (j - 1)) + 2._wp*bc_z%ve1 + else if (i == momxb + 1 .and. num_dims > 1) then + q_prim_vf(i)%sf(k, l, p + j) = -q_prim_vf(i)%sf(k, l, p - (j - 1)) + 2._wp*bc_z%ve2 + else if (i == momxb + 2 .and. num_dims > 2) then + q_prim_vf(i)%sf(k, l, p + j) = -q_prim_vf(i)%sf(k, l, p - (j - 1)) + 2._wp*bc_z%ve3 else - q_prim_vf(i)%sf(k, l, p + j) = & - q_prim_vf(i)%sf(k, l, p) + q_prim_vf(i)%sf(k, l, p + j) = q_prim_vf(i)%sf(k, l, p) end if end do end do @@ -1061,63 +929,56 @@ contains !> @brief Applies Dirichlet boundary conditions by prescribing ghost cell values from stored boundary buffers. subroutine s_dirichlet(q_prim_vf, bc_dir, bc_loc, k, l) - $:GPU_ROUTINE(function_name='s_dirichlet',parallelism='[seq]', & - & cray_inline=True) - type(scalar_field), dimension(sys_size), intent(inout) :: q_prim_vf - integer, intent(in) :: bc_dir, bc_loc - integer, intent(in) :: k, l - integer :: j, i + $:GPU_ROUTINE(function_name='s_dirichlet',parallelism='[seq]', cray_inline=True) + type(scalar_field), dimension(sys_size), intent(inout) :: q_prim_vf + integer, intent(in) :: bc_dir, bc_loc + integer, intent(in) :: k, l + integer :: j, i #ifdef MFC_SIMULATION - if (bc_dir == 1) then !< x-direction - if (bc_loc == -1) then !bc_x%beg + if (bc_dir == 1) then !< x-direction + if (bc_loc == -1) then ! bc_x%beg do i = 1, sys_size do j = 1, buff_size - q_prim_vf(i)%sf(-j, k, l) = & - bc_buffers(1, 1)%sf(i, k, l) + q_prim_vf(i)%sf(-j, k, l) = bc_buffers(1, 1)%sf(i, k, l) end do end do - else !< bc_x%end + else !< bc_x%end do i = 1, sys_size do j = 1, buff_size - q_prim_vf(i)%sf(m + j, k, l) = & - bc_buffers(1, 2)%sf(i, k, l) + q_prim_vf(i)%sf(m + j, k, l) = bc_buffers(1, 2)%sf(i, k, l) end do end do end if - elseif (bc_dir == 2) then !< y-direction + else if (bc_dir == 2) then !< y-direction #:if not MFC_CASE_OPTIMIZATION or num_dims > 1 - if (bc_loc == -1) then !< bc_y%beg + if (bc_loc == -1) then !< bc_y%beg do i = 1, sys_size do j = 1, buff_size - q_prim_vf(i)%sf(k, -j, l) = & - bc_buffers(2, 1)%sf(k, i, l) + q_prim_vf(i)%sf(k, -j, l) = bc_buffers(2, 1)%sf(k, i, l) end do end do - else !< bc_y%end + else !< bc_y%end do i = 1, sys_size do j = 1, buff_size - q_prim_vf(i)%sf(k, n + j, l) = & - bc_buffers(2, 2)%sf(k, i, l) + q_prim_vf(i)%sf(k, n + j, l) = bc_buffers(2, 2)%sf(k, i, l) end do end do end if #:endif - elseif (bc_dir == 3) then !< z-direction + else if (bc_dir == 3) then !< z-direction #:if not MFC_CASE_OPTIMIZATION or num_dims > 2 - if (bc_loc == -1) then !< bc_z%beg + if (bc_loc == -1) then !< bc_z%beg do i = 1, sys_size do j = 1, buff_size - q_prim_vf(i)%sf(k, l, -j) = & - bc_buffers(3, 1)%sf(k, l, i) + q_prim_vf(i)%sf(k, l, -j) = bc_buffers(3, 1)%sf(k, l, i) end do end do - else !< bc_z%end + else !< bc_z%end do i = 1, sys_size do j = 1, buff_size - q_prim_vf(i)%sf(k, l, p + j) = & - bc_buffers(3, 2)%sf(k, l, i) + q_prim_vf(i)%sf(k, l, p + j) = bc_buffers(3, 2)%sf(k, l, i) end do end do end if @@ -1131,15 +992,15 @@ contains !> @brief Extrapolates QBMM bubble pressure and mass-vapor variables into ghost cells by copying boundary values. subroutine s_qbmm_extrapolation(bc_dir, bc_loc, k, l, pb_in, mv_in) - $:GPU_ROUTINE(parallelism='[seq]') - real(stp), optional, dimension(idwbuff(1)%beg:, idwbuff(2)%beg:, idwbuff(3)%beg:, 1:, 1:), intent(inout) :: pb_in, mv_in - integer, intent(in) :: bc_dir, bc_loc - integer, intent(in) :: k, l - integer :: j, q, i + $:GPU_ROUTINE(parallelism='[seq]') + real(stp), optional, dimension(idwbuff(1)%beg:,idwbuff(2)%beg:,idwbuff(3)%beg:,1:,1:), intent(inout) :: pb_in, mv_in + integer, intent(in) :: bc_dir, bc_loc + integer, intent(in) :: k, l + integer :: j, q, i - if (bc_dir == 1) then !< x-direction - if (bc_loc == -1) then !bc_x%beg + if (bc_dir == 1) then !< x-direction + if (bc_loc == -1) then ! bc_x%beg do i = 1, nb do q = 1, nnode do j = 1, buff_size @@ -1148,7 +1009,7 @@ contains end do end do end do - else !< bc_x%end + else !< bc_x%end do i = 1, nb do q = 1, nnode do j = 1, buff_size @@ -1158,8 +1019,8 @@ contains end do end do end if - elseif (bc_dir == 2) then !< y-direction - if (bc_loc == -1) then !< bc_y%beg + else if (bc_dir == 2) then !< y-direction + if (bc_loc == -1) then !< bc_y%beg do i = 1, nb do q = 1, nnode do j = 1, buff_size @@ -1168,7 +1029,7 @@ contains end do end do end do - else !< bc_y%end + else !< bc_y%end do i = 1, nb do q = 1, nnode do j = 1, buff_size @@ -1178,8 +1039,8 @@ contains end do end do end if - elseif (bc_dir == 3) then !< z-direction - if (bc_loc == -1) then !< bc_z%beg + else if (bc_dir == 3) then !< z-direction + if (bc_loc == -1) then !< bc_z%beg do i = 1, nb do q = 1, nnode do j = 1, buff_size @@ -1188,7 +1049,7 @@ contains end do end do end do - else !< bc_z%end + else !< bc_z%end do i = 1, nb do q = 1, nnode do j = 1, buff_size @@ -1204,16 +1065,16 @@ contains impure subroutine s_populate_beta_buffers(q_beta, kahan_comp, bc_type, nvar) - type(scalar_field), dimension(:), intent(inout) :: q_beta - type(scalar_field), dimension(:), intent(inout) :: kahan_comp - type(integer_field), dimension(1:num_dims, 1:2), intent(in) :: bc_type - integer, intent(in) :: nvar + type(scalar_field), dimension(:), intent(inout) :: q_beta + type(scalar_field), dimension(:), intent(inout) :: kahan_comp + type(integer_field), dimension(1:num_dims,1:2), intent(in) :: bc_type + integer, intent(in) :: nvar + integer :: k, l - integer :: k, l + !> x-direction - !< x-direction if (bc_x%beg < 0) then - $:GPU_PARALLEL_LOOP(private='[l,k]', collapse=2) + $:GPU_PARALLEL_LOOP(private='[l, k]', collapse=2) do l = beta_bc_bounds(3)%beg, beta_bc_bounds(3)%end do k = beta_bc_bounds(2)%beg, beta_bc_bounds(2)%end select case (bc_x%beg) @@ -1232,7 +1093,7 @@ contains end if if (bc_x%end < 0) then - $:GPU_PARALLEL_LOOP(private='[l,k]', collapse=2) + $:GPU_PARALLEL_LOOP(private='[l, k]', collapse=2) do l = beta_bc_bounds(3)%beg, beta_bc_bounds(3)%end do k = beta_bc_bounds(2)%beg, beta_bc_bounds(2)%end select case (bc_x%end) @@ -1250,9 +1111,9 @@ contains call s_mpi_reduce_beta_variables_buffers(q_beta, kahan_comp, 1, 1, nvar) end if - !< y-direction + !> y-direction if (bc_y%beg < 0) then - $:GPU_PARALLEL_LOOP(private='[l,k]', collapse=2) + $:GPU_PARALLEL_LOOP(private='[l, k]', collapse=2) do l = beta_bc_bounds(3)%beg, beta_bc_bounds(3)%end do k = beta_bc_bounds(1)%beg, beta_bc_bounds(1)%end select case (bc_y%beg) @@ -1271,7 +1132,7 @@ contains end if if (bc_y%end < 0) then - $:GPU_PARALLEL_LOOP(private='[l,k]', collapse=2) + $:GPU_PARALLEL_LOOP(private='[l, k]', collapse=2) do l = beta_bc_bounds(3)%beg, beta_bc_bounds(3)%end do k = beta_bc_bounds(1)%beg, beta_bc_bounds(1)%end select case (bc_y%end) @@ -1292,9 +1153,9 @@ contains if (num_dims == 2) return #:if not MFC_CASE_OPTIMIZATION or num_dims > 2 - !< z-direction + !> z-direction if (bc_z%beg < 0) then - $:GPU_PARALLEL_LOOP(private='[l,k]', collapse=2) + $:GPU_PARALLEL_LOOP(private='[l, k]', collapse=2) do l = beta_bc_bounds(2)%beg, beta_bc_bounds(2)%end do k = beta_bc_bounds(1)%beg, beta_bc_bounds(1)%end select case (bc_type(3, 1)%sf(k, l, 0)) @@ -1313,7 +1174,7 @@ contains end if if (bc_z%end < 0) then - $:GPU_PARALLEL_LOOP(private='[l,k]', collapse=2) + $:GPU_PARALLEL_LOOP(private='[l, k]', collapse=2) do l = beta_bc_bounds(2)%beg, beta_bc_bounds(2)%end do k = beta_bc_bounds(1)%beg, beta_bc_bounds(1)%end select case (bc_type(3, 2)%sf(k, l, 0)) @@ -1335,32 +1196,30 @@ contains end subroutine s_populate_beta_buffers subroutine s_beta_periodic(q_beta, kahan_comp, bc_dir, bc_loc, k, l, nvar) - $:GPU_ROUTINE(function_name='s_beta_periodic', & - & parallelism='[seq]', cray_inline=True) + + $:GPU_ROUTINE(function_name='s_beta_periodic', parallelism='[seq]', cray_inline=True) type(scalar_field), dimension(num_dims + 1), intent(inout) :: q_beta type(scalar_field), dimension(num_dims + 1), intent(inout) :: kahan_comp - integer, intent(in) :: bc_dir, bc_loc - integer, intent(in) :: k, l - integer, intent(in) :: nvar - - integer :: j, i - real(wp) :: y_kahan, t_kahan - - if (bc_dir == 1) then !< x-direction - if (bc_loc == -1) then !bc_x%beg + integer, intent(in) :: bc_dir, bc_loc + integer, intent(in) :: k, l + integer, intent(in) :: nvar + integer :: j, i + real(wp) :: y_kahan, t_kahan + + if (bc_dir == 1) then !< x-direction + if (bc_loc == -1) then ! bc_x%beg do i = 1, nvar do j = -mapCells - 1, mapCells ! Kahan-compensated addition of ghost to interior - y_kahan = real(q_beta(beta_vars(i))%sf(m + j + 1, k, l), kind=wp) & - + kahan_comp(beta_vars(i))%sf(m + j + 1, k, l) & - - kahan_comp(beta_vars(i))%sf(j, k, l) + y_kahan = real(q_beta(beta_vars(i))%sf(m + j + 1, k, l), & + & kind=wp) + kahan_comp(beta_vars(i))%sf(m + j + 1, k, l) - kahan_comp(beta_vars(i))%sf(j, & + & k, l) t_kahan = real(q_beta(beta_vars(i))%sf(j, k, l), kind=wp) + y_kahan - kahan_comp(beta_vars(i))%sf(j, k, l) = & - (t_kahan - q_beta(beta_vars(i))%sf(j, k, l)) - y_kahan + kahan_comp(beta_vars(i))%sf(j, k, l) = (t_kahan - q_beta(beta_vars(i))%sf(j, k, l)) - y_kahan q_beta(beta_vars(i))%sf(j, k, l) = t_kahan end do end do - else !< bc_x%end + else !< bc_x%end do i = 1, nvar do j = -mapcells, mapcells + 1 q_beta(beta_vars(i))%sf(m + j, k, l) = q_beta(beta_vars(i))%sf(j - 1, k, l) @@ -1368,20 +1227,18 @@ contains end do end do end if - elseif (bc_dir == 2) then !< y-direction - if (bc_loc == -1) then !< bc_y%beg + else if (bc_dir == 2) then !< y-direction + if (bc_loc == -1) then !< bc_y%beg do i = 1, nvar do j = -mapcells - 1, mapcells - y_kahan = real(q_beta(beta_vars(i))%sf(k, n + j + 1, l), kind=wp) & - + kahan_comp(beta_vars(i))%sf(k, n + j + 1, l) & - - kahan_comp(beta_vars(i))%sf(k, j, l) + y_kahan = real(q_beta(beta_vars(i))%sf(k, n + j + 1, l), kind=wp) + kahan_comp(beta_vars(i))%sf(k, & + & n + j + 1, l) - kahan_comp(beta_vars(i))%sf(k, j, l) t_kahan = real(q_beta(beta_vars(i))%sf(k, j, l), kind=wp) + y_kahan - kahan_comp(beta_vars(i))%sf(k, j, l) = & - (t_kahan - q_beta(beta_vars(i))%sf(k, j, l)) - y_kahan + kahan_comp(beta_vars(i))%sf(k, j, l) = (t_kahan - q_beta(beta_vars(i))%sf(k, j, l)) - y_kahan q_beta(beta_vars(i))%sf(k, j, l) = t_kahan end do end do - else !< bc_y%end + else !< bc_y%end do i = 1, nvar do j = -mapcells, mapcells + 1 q_beta(beta_vars(i))%sf(k, n + j, l) = q_beta(beta_vars(i))%sf(k, j - 1, l) @@ -1389,20 +1246,18 @@ contains end do end do end if - elseif (bc_dir == 3) then !< z-direction - if (bc_loc == -1) then !< bc_z%beg + else if (bc_dir == 3) then !< z-direction + if (bc_loc == -1) then !< bc_z%beg do i = 1, nvar do j = -mapcells - 1, mapcells - y_kahan = real(q_beta(beta_vars(i))%sf(k, l, p + j + 1), kind=wp) & - + kahan_comp(beta_vars(i))%sf(k, l, p + j + 1) & - - kahan_comp(beta_vars(i))%sf(k, l, j) + y_kahan = real(q_beta(beta_vars(i))%sf(k, l, p + j + 1), kind=wp) + kahan_comp(beta_vars(i))%sf(k, l, & + & p + j + 1) - kahan_comp(beta_vars(i))%sf(k, l, j) t_kahan = real(q_beta(beta_vars(i))%sf(k, l, j), kind=wp) + y_kahan - kahan_comp(beta_vars(i))%sf(k, l, j) = & - (t_kahan - q_beta(beta_vars(i))%sf(k, l, j)) - y_kahan + kahan_comp(beta_vars(i))%sf(k, l, j) = (t_kahan - q_beta(beta_vars(i))%sf(k, l, j)) - y_kahan q_beta(beta_vars(i))%sf(k, l, j) = t_kahan end do end do - else !< bc_z%end + else !< bc_z%end do i = 1, nvar do j = -mapcells, mapcells + 1 q_beta(beta_vars(i))%sf(k, l, p + j) = q_beta(beta_vars(i))%sf(k, l, j - 1) @@ -1415,53 +1270,52 @@ contains end subroutine s_beta_periodic subroutine s_beta_extrapolation(q_beta, bc_dir, bc_loc, k, l, nvar) - $:GPU_ROUTINE(function_name='s_beta_extrapolation', & - & parallelism='[seq]', cray_inline=True) - type(scalar_field), dimension(num_dims + 1), intent(inout) :: q_beta - integer, intent(in) :: bc_dir, bc_loc - integer, intent(in) :: k, l - integer, intent(in) :: nvar - integer :: j, i + $:GPU_ROUTINE(function_name='s_beta_extrapolation', parallelism='[seq]', cray_inline=True) + type(scalar_field), dimension(num_dims + 1), intent(inout) :: q_beta + integer, intent(in) :: bc_dir, bc_loc + integer, intent(in) :: k, l + integer, intent(in) :: nvar + integer :: j, i ! Set beta in buffer regions equal to zero - if (bc_dir == 1) then !< x-direction - if (bc_loc == -1) then !bc_x%beg + if (bc_dir == 1) then !< x-direction + if (bc_loc == -1) then ! bc_x%beg do i = 1, nvar do j = 1, buff_size q_beta(beta_vars(i))%sf(-j, k, l) = 0._wp end do end do - else !< bc_x%end + else !< bc_x%end do i = 1, nvar do j = 1, buff_size q_beta(beta_vars(i))%sf(m + j, k, l) = 0._wp end do end do end if - elseif (bc_dir == 2) then !< y-direction - if (bc_loc == -1) then !< bc_y%beg + else if (bc_dir == 2) then !< y-direction + if (bc_loc == -1) then !< bc_y%beg do i = 1, nvar do j = 1, buff_size q_beta(beta_vars(i))%sf(k, -j, l) = 0._wp end do end do - else !< bc_y%end + else !< bc_y%end do i = 1, nvar do j = 1, buff_size q_beta(beta_vars(i))%sf(k, n + j, l) = 0._wp end do end do end if - elseif (bc_dir == 3) then !< z-direction - if (bc_loc == -1) then !< bc_z%beg + else if (bc_dir == 3) then !< z-direction + if (bc_loc == -1) then !< bc_z%beg do i = 1, nvar do j = 1, buff_size q_beta(beta_vars(i))%sf(k, l, -j) = 0._wp end do end do - else !< bc_z%end + else !< bc_z%end do i = 1, nvar do j = 1, buff_size q_beta(beta_vars(i))%sf(k, l, p + j) = 0._wp @@ -1473,31 +1327,27 @@ contains end subroutine s_beta_extrapolation subroutine s_beta_reflective(q_beta, kahan_comp, bc_dir, bc_loc, k, l, nvar) - $:GPU_ROUTINE(function_name='s_beta_reflective', & - & parallelism='[seq]', cray_inline=True) + + $:GPU_ROUTINE(function_name='s_beta_reflective', parallelism='[seq]', cray_inline=True) type(scalar_field), dimension(num_dims + 1), intent(inout) :: q_beta type(scalar_field), dimension(num_dims + 1), intent(inout) :: kahan_comp - integer, intent(in) :: bc_dir, bc_loc - integer, intent(in) :: k, l - integer, intent(in) :: nvar - - integer :: j, i - real(wp) :: y_kahan, t_kahan + integer, intent(in) :: bc_dir, bc_loc + integer, intent(in) :: k, l + integer, intent(in) :: nvar + integer :: j, i + real(wp) :: y_kahan, t_kahan - ! Reflective BC for void fraction: - ! 1) Fold ghost-cell contributions back onto their mirror interior cells (Kahan) - ! 2) Set ghost cells = mirror of (now-folded) interior values + ! Reflective BC for void fraction: 1) Fold ghost-cell contributions back onto their mirror interior cells (Kahan) 2) Set + ! ghost cells = mirror of (now-folded) interior values - if (bc_dir == 1) then !< x-direction - if (bc_loc == -1) then !< bc_x%beg + if (bc_dir == 1) then !< x-direction + if (bc_loc == -1) then !< bc_x%beg do i = 1, nvar do j = 1, mapCells + 1 - y_kahan = real(q_beta(beta_vars(i))%sf(-j, k, l), kind=wp) & - + kahan_comp(beta_vars(i))%sf(-j, k, l) & - - kahan_comp(beta_vars(i))%sf(j - 1, k, l) + y_kahan = real(q_beta(beta_vars(i))%sf(-j, k, l), kind=wp) + kahan_comp(beta_vars(i))%sf(-j, k, & + & l) - kahan_comp(beta_vars(i))%sf(j - 1, k, l) t_kahan = real(q_beta(beta_vars(i))%sf(j - 1, k, l), kind=wp) + y_kahan - kahan_comp(beta_vars(i))%sf(j - 1, k, l) = & - (t_kahan - q_beta(beta_vars(i))%sf(j - 1, k, l)) - y_kahan + kahan_comp(beta_vars(i))%sf(j - 1, k, l) = (t_kahan - q_beta(beta_vars(i))%sf(j - 1, k, l)) - y_kahan q_beta(beta_vars(i))%sf(j - 1, k, l) = t_kahan end do do j = 1, mapCells + 1 @@ -1505,15 +1355,14 @@ contains kahan_comp(beta_vars(i))%sf(-j, k, l) = kahan_comp(beta_vars(i))%sf(j - 1, k, l) end do end do - else !< bc_x%end + else !< bc_x%end do i = 1, nvar do j = 1, mapCells + 1 - y_kahan = real(q_beta(beta_vars(i))%sf(m + j, k, l), kind=wp) & - + kahan_comp(beta_vars(i))%sf(m + j, k, l) & - - kahan_comp(beta_vars(i))%sf(m - (j - 1), k, l) + y_kahan = real(q_beta(beta_vars(i))%sf(m + j, k, l), kind=wp) + kahan_comp(beta_vars(i))%sf(m + j, k, & + & l) - kahan_comp(beta_vars(i))%sf(m - (j - 1), k, l) t_kahan = real(q_beta(beta_vars(i))%sf(m - (j - 1), k, l), kind=wp) + y_kahan - kahan_comp(beta_vars(i))%sf(m - (j - 1), k, l) = & - (t_kahan - q_beta(beta_vars(i))%sf(m - (j - 1), k, l)) - y_kahan + kahan_comp(beta_vars(i))%sf(m - (j - 1), k, l) = (t_kahan - q_beta(beta_vars(i))%sf(m - (j - 1), k, & + & l)) - y_kahan q_beta(beta_vars(i))%sf(m - (j - 1), k, l) = t_kahan end do do j = 1, mapCells + 1 @@ -1522,16 +1371,14 @@ contains end do end do end if - elseif (bc_dir == 2) then !< y-direction - if (bc_loc == -1) then !< bc_y%beg + else if (bc_dir == 2) then !< y-direction + if (bc_loc == -1) then !< bc_y%beg do i = 1, nvar do j = 1, mapCells + 1 - y_kahan = real(q_beta(beta_vars(i))%sf(k, -j, l), kind=wp) & - + kahan_comp(beta_vars(i))%sf(k, -j, l) & - - kahan_comp(beta_vars(i))%sf(k, j - 1, l) + y_kahan = real(q_beta(beta_vars(i))%sf(k, -j, l), kind=wp) + kahan_comp(beta_vars(i))%sf(k, -j, & + & l) - kahan_comp(beta_vars(i))%sf(k, j - 1, l) t_kahan = real(q_beta(beta_vars(i))%sf(k, j - 1, l), kind=wp) + y_kahan - kahan_comp(beta_vars(i))%sf(k, j - 1, l) = & - (t_kahan - q_beta(beta_vars(i))%sf(k, j - 1, l)) - y_kahan + kahan_comp(beta_vars(i))%sf(k, j - 1, l) = (t_kahan - q_beta(beta_vars(i))%sf(k, j - 1, l)) - y_kahan q_beta(beta_vars(i))%sf(k, j - 1, l) = t_kahan end do do j = 1, mapCells + 1 @@ -1539,15 +1386,14 @@ contains kahan_comp(beta_vars(i))%sf(k, -j, l) = kahan_comp(beta_vars(i))%sf(k, j - 1, l) end do end do - else !< bc_y%end + else !< bc_y%end do i = 1, nvar do j = 1, mapCells + 1 - y_kahan = real(q_beta(beta_vars(i))%sf(k, n + j, l), kind=wp) & - + kahan_comp(beta_vars(i))%sf(k, n + j, l) & - - kahan_comp(beta_vars(i))%sf(k, n - (j - 1), l) + y_kahan = real(q_beta(beta_vars(i))%sf(k, n + j, l), kind=wp) + kahan_comp(beta_vars(i))%sf(k, n + j, & + & l) - kahan_comp(beta_vars(i))%sf(k, n - (j - 1), l) t_kahan = real(q_beta(beta_vars(i))%sf(k, n - (j - 1), l), kind=wp) + y_kahan - kahan_comp(beta_vars(i))%sf(k, n - (j - 1), l) = & - (t_kahan - q_beta(beta_vars(i))%sf(k, n - (j - 1), l)) - y_kahan + kahan_comp(beta_vars(i))%sf(k, n - (j - 1), l) = (t_kahan - q_beta(beta_vars(i))%sf(k, n - (j - 1), & + & l)) - y_kahan q_beta(beta_vars(i))%sf(k, n - (j - 1), l) = t_kahan end do do j = 1, mapCells + 1 @@ -1556,16 +1402,14 @@ contains end do end do end if - elseif (bc_dir == 3) then !< z-direction - if (bc_loc == -1) then !< bc_z%beg + else if (bc_dir == 3) then !< z-direction + if (bc_loc == -1) then !< bc_z%beg do i = 1, nvar do j = 1, mapCells + 1 - y_kahan = real(q_beta(beta_vars(i))%sf(k, l, -j), kind=wp) & - + kahan_comp(beta_vars(i))%sf(k, l, -j) & - - kahan_comp(beta_vars(i))%sf(k, l, j - 1) + y_kahan = real(q_beta(beta_vars(i))%sf(k, l, -j), kind=wp) + kahan_comp(beta_vars(i))%sf(k, l, & + & -j) - kahan_comp(beta_vars(i))%sf(k, l, j - 1) t_kahan = real(q_beta(beta_vars(i))%sf(k, l, j - 1), kind=wp) + y_kahan - kahan_comp(beta_vars(i))%sf(k, l, j - 1) = & - (t_kahan - q_beta(beta_vars(i))%sf(k, l, j - 1)) - y_kahan + kahan_comp(beta_vars(i))%sf(k, l, j - 1) = (t_kahan - q_beta(beta_vars(i))%sf(k, l, j - 1)) - y_kahan q_beta(beta_vars(i))%sf(k, l, j - 1) = t_kahan end do do j = 1, mapCells + 1 @@ -1573,15 +1417,14 @@ contains kahan_comp(beta_vars(i))%sf(k, l, -j) = kahan_comp(beta_vars(i))%sf(k, l, j - 1) end do end do - else !< bc_z%end + else !< bc_z%end do i = 1, nvar do j = 1, mapCells + 1 - y_kahan = real(q_beta(beta_vars(i))%sf(k, l, p + j), kind=wp) & - + kahan_comp(beta_vars(i))%sf(k, l, p + j) & - - kahan_comp(beta_vars(i))%sf(k, l, p - (j - 1)) + y_kahan = real(q_beta(beta_vars(i))%sf(k, l, p + j), kind=wp) + kahan_comp(beta_vars(i))%sf(k, l, & + & p + j) - kahan_comp(beta_vars(i))%sf(k, l, p - (j - 1)) t_kahan = real(q_beta(beta_vars(i))%sf(k, l, p - (j - 1)), kind=wp) + y_kahan - kahan_comp(beta_vars(i))%sf(k, l, p - (j - 1)) = & - (t_kahan - q_beta(beta_vars(i))%sf(k, l, p - (j - 1))) - y_kahan + kahan_comp(beta_vars(i))%sf(k, l, p - (j - 1)) = (t_kahan - q_beta(beta_vars(i))%sf(k, l, & + & p - (j - 1))) - y_kahan q_beta(beta_vars(i))%sf(k, l, p - (j - 1)) = t_kahan end do do j = 1, mapCells + 1 @@ -1598,15 +1441,15 @@ contains impure subroutine s_populate_capillary_buffers(c_divs, bc_type) type(scalar_field), dimension(num_dims + 1), intent(inout) :: c_divs - type(integer_field), dimension(1:num_dims, 1:2), intent(in) :: bc_type + type(integer_field), dimension(1:num_dims,1:2), intent(in) :: bc_type + integer :: k, l - integer :: k, l + !> x-direction - !< x-direction if (bc_x%beg >= 0) then call s_mpi_sendrecv_variables_buffers(c_divs, 1, -1, num_dims + 1) else - $:GPU_PARALLEL_LOOP(private='[l,k]', collapse=2) + $:GPU_PARALLEL_LOOP(private='[l, k]', collapse=2) do l = 0, p do k = 0, n select case (bc_type(1, 1)%sf(0, k, l)) @@ -1625,7 +1468,7 @@ contains if (bc_x%end >= 0) then call s_mpi_sendrecv_variables_buffers(c_divs, 1, 1, num_dims + 1) else - $:GPU_PARALLEL_LOOP(private='[l,k]', collapse=2) + $:GPU_PARALLEL_LOOP(private='[l, k]', collapse=2) do l = 0, p do k = 0, n select case (bc_type(1, 2)%sf(0, k, l)) @@ -1644,12 +1487,11 @@ contains if (n == 0) return #:if not MFC_CASE_OPTIMIZATION or num_dims > 1 - - !< y-direction + !> y-direction if (bc_y%beg >= 0) then call s_mpi_sendrecv_variables_buffers(c_divs, 2, -1, num_dims + 1) else - $:GPU_PARALLEL_LOOP(private='[l,k]', collapse=2) + $:GPU_PARALLEL_LOOP(private='[l, k]', collapse=2) do l = 0, p do k = -buff_size, m + buff_size select case (bc_type(2, 1)%sf(k, 0, l)) @@ -1668,7 +1510,7 @@ contains if (bc_y%end >= 0) then call s_mpi_sendrecv_variables_buffers(c_divs, 2, 1, num_dims + 1) else - $:GPU_PARALLEL_LOOP(private='[l,k]', collapse=2) + $:GPU_PARALLEL_LOOP(private='[l, k]', collapse=2) do l = 0, p do k = -buff_size, m + buff_size select case (bc_type(2, 2)%sf(k, 0, l)) @@ -1683,17 +1525,16 @@ contains end do $:END_GPU_PARALLEL_LOOP() end if - #:endif if (p == 0) return #:if not MFC_CASE_OPTIMIZATION or num_dims > 2 - !< z-direction + !> z-direction if (bc_z%beg >= 0) then call s_mpi_sendrecv_variables_buffers(c_divs, 3, -1, num_dims + 1) else - $:GPU_PARALLEL_LOOP(private='[l,k]', collapse=2) + $:GPU_PARALLEL_LOOP(private='[l, k]', collapse=2) do l = -buff_size, n + buff_size do k = -buff_size, m + buff_size select case (bc_type(3, 1)%sf(k, l, 0)) @@ -1712,7 +1553,7 @@ contains if (bc_z%end >= 0) then call s_mpi_sendrecv_variables_buffers(c_divs, 3, 1, num_dims + 1) else - $:GPU_PARALLEL_LOOP(private='[l,k]', collapse=2) + $:GPU_PARALLEL_LOOP(private='[l, k]', collapse=2) do l = -buff_size, n + buff_size do k = -buff_size, m + buff_size select case (bc_type(3, 2)%sf(k, l, 0)) @@ -1733,50 +1574,49 @@ contains !> @brief Applies periodic boundary conditions to the color function and its divergence fields. subroutine s_color_function_periodic(c_divs, bc_dir, bc_loc, k, l) - $:GPU_ROUTINE(function_name='s_color_function_periodic', & - & parallelism='[seq]', cray_inline=True) - type(scalar_field), dimension(num_dims + 1), intent(inout) :: c_divs - integer, intent(in) :: bc_dir, bc_loc - integer, intent(in) :: k, l - integer :: j, i + $:GPU_ROUTINE(function_name='s_color_function_periodic', parallelism='[seq]', cray_inline=True) + type(scalar_field), dimension(num_dims + 1), intent(inout) :: c_divs + integer, intent(in) :: bc_dir, bc_loc + integer, intent(in) :: k, l + integer :: j, i - if (bc_dir == 1) then !< x-direction - if (bc_loc == -1) then !bc_x%beg + if (bc_dir == 1) then !< x-direction + if (bc_loc == -1) then ! bc_x%beg do i = 1, num_dims + 1 do j = 1, buff_size c_divs(i)%sf(-j, k, l) = c_divs(i)%sf(m - (j - 1), k, l) end do end do - else !< bc_x%end + else !< bc_x%end do i = 1, num_dims + 1 do j = 1, buff_size c_divs(i)%sf(m + j, k, l) = c_divs(i)%sf(j - 1, k, l) end do end do end if - elseif (bc_dir == 2) then !< y-direction - if (bc_loc == -1) then !< bc_y%beg + else if (bc_dir == 2) then !< y-direction + if (bc_loc == -1) then !< bc_y%beg do i = 1, num_dims + 1 do j = 1, buff_size c_divs(i)%sf(k, -j, l) = c_divs(i)%sf(k, n - (j - 1), l) end do end do - else !< bc_y%end + else !< bc_y%end do i = 1, num_dims + 1 do j = 1, buff_size c_divs(i)%sf(k, n + j, l) = c_divs(i)%sf(k, j - 1, l) end do end do end if - elseif (bc_dir == 3) then !< z-direction - if (bc_loc == -1) then !< bc_z%beg + else if (bc_dir == 3) then !< z-direction + if (bc_loc == -1) then !< bc_z%beg do i = 1, num_dims + 1 do j = 1, buff_size c_divs(i)%sf(k, l, -j) = c_divs(i)%sf(k, l, p - (j - 1)) end do end do - else !< bc_z%end + else !< bc_z%end do i = 1, num_dims + 1 do j = 1, buff_size c_divs(i)%sf(k, l, p + j) = c_divs(i)%sf(k, l, j - 1) @@ -1789,16 +1629,15 @@ contains !> @brief Applies reflective boundary conditions to the color function and its divergence fields. subroutine s_color_function_reflective(c_divs, bc_dir, bc_loc, k, l) - $:GPU_ROUTINE(function_name='s_color_function_reflective', & - & parallelism='[seq]', cray_inline=True) - type(scalar_field), dimension(num_dims + 1), intent(inout) :: c_divs - integer, intent(in) :: bc_dir, bc_loc - integer, intent(in) :: k, l - integer :: j, i + $:GPU_ROUTINE(function_name='s_color_function_reflective', parallelism='[seq]', cray_inline=True) + type(scalar_field), dimension(num_dims + 1), intent(inout) :: c_divs + integer, intent(in) :: bc_dir, bc_loc + integer, intent(in) :: k, l + integer :: j, i - if (bc_dir == 1) then !< x-direction - if (bc_loc == -1) then !bc_x%beg + if (bc_dir == 1) then !< x-direction + if (bc_loc == -1) then ! bc_x%beg do i = 1, num_dims + 1 do j = 1, buff_size if (i == bc_dir) then @@ -1808,7 +1647,7 @@ contains end if end do end do - else !< bc_x%end + else !< bc_x%end do i = 1, num_dims + 1 do j = 1, buff_size if (i == bc_dir) then @@ -1819,8 +1658,8 @@ contains end do end do end if - elseif (bc_dir == 2) then !< y-direction - if (bc_loc == -1) then !< bc_y%beg + else if (bc_dir == 2) then !< y-direction + if (bc_loc == -1) then !< bc_y%beg do i = 1, num_dims + 1 do j = 1, buff_size if (i == bc_dir) then @@ -1830,7 +1669,7 @@ contains end if end do end do - else !< bc_y%end + else !< bc_y%end do i = 1, num_dims + 1 do j = 1, buff_size if (i == bc_dir) then @@ -1841,8 +1680,8 @@ contains end do end do end if - elseif (bc_dir == 3) then !< z-direction - if (bc_loc == -1) then !< bc_z%beg + else if (bc_dir == 3) then !< z-direction + if (bc_loc == -1) then !< bc_z%beg do i = 1, num_dims + 1 do j = 1, buff_size if (i == bc_dir) then @@ -1852,7 +1691,7 @@ contains end if end do end do - else !< bc_z%end + else !< bc_z%end do i = 1, num_dims + 1 do j = 1, buff_size if (i == bc_dir) then @@ -1869,50 +1708,49 @@ contains !> @brief Extrapolates the color function and its divergence into ghost cells by copying boundary values. subroutine s_color_function_ghost_cell_extrapolation(c_divs, bc_dir, bc_loc, k, l) - $:GPU_ROUTINE(function_name='s_color_function_ghost_cell_extrapolation', & - & parallelism='[seq]', cray_inline=True) - type(scalar_field), dimension(num_dims + 1), intent(inout) :: c_divs - integer, intent(in) :: bc_dir, bc_loc - integer, intent(in) :: k, l - integer :: j, i + $:GPU_ROUTINE(function_name='s_color_function_ghost_cell_extrapolation', parallelism='[seq]', cray_inline=True) + type(scalar_field), dimension(num_dims + 1), intent(inout) :: c_divs + integer, intent(in) :: bc_dir, bc_loc + integer, intent(in) :: k, l + integer :: j, i - if (bc_dir == 1) then !< x-direction - if (bc_loc == -1) then !bc_x%beg + if (bc_dir == 1) then !< x-direction + if (bc_loc == -1) then ! bc_x%beg do i = 1, num_dims + 1 do j = 1, buff_size c_divs(i)%sf(-j, k, l) = c_divs(i)%sf(0, k, l) end do end do - else !< bc_x%end + else !< bc_x%end do i = 1, num_dims + 1 do j = 1, buff_size c_divs(i)%sf(m + j, k, l) = c_divs(i)%sf(m, k, l) end do end do end if - elseif (bc_dir == 2) then !< y-direction - if (bc_loc == -1) then !< bc_y%beg + else if (bc_dir == 2) then !< y-direction + if (bc_loc == -1) then !< bc_y%beg do i = 1, num_dims + 1 do j = 1, buff_size c_divs(i)%sf(k, -j, l) = c_divs(i)%sf(k, 0, l) end do end do - else !< bc_y%end + else !< bc_y%end do i = 1, num_dims + 1 do j = 1, buff_size c_divs(i)%sf(k, n + j, l) = c_divs(i)%sf(k, n, l) end do end do end if - elseif (bc_dir == 3) then !< z-direction - if (bc_loc == -1) then !< bc_z%beg + else if (bc_dir == 3) then !< z-direction + if (bc_loc == -1) then !< bc_z%beg do i = 1, num_dims + 1 do j = 1, buff_size c_divs(i)%sf(k, l, -j) = c_divs(i)%sf(k, l, 0) end do end do - else !< bc_z%end + else !< bc_z%end do i = 1, num_dims + 1 do j = 1, buff_size c_divs(i)%sf(k, l, p + j) = c_divs(i)%sf(k, l, p) @@ -1926,15 +1764,14 @@ contains !> @brief Populates ghost cell buffers for the Jacobian scalar field used in the IGR elliptic solver. impure subroutine s_populate_F_igr_buffers(bc_type, jac_sf) - type(integer_field), dimension(1:num_dims, 1:2), intent(in) :: bc_type - type(scalar_field), dimension(1:), intent(inout) :: jac_sf - - integer :: j, k, l + type(integer_field), dimension(1:num_dims,1:2), intent(in) :: bc_type + type(scalar_field), dimension(1:), intent(inout) :: jac_sf + integer :: j, k, l if (bc_x%beg >= 0) then call s_mpi_sendrecv_variables_buffers(jac_sf, 1, -1, 1) else - $:GPU_PARALLEL_LOOP(private='[l,k]', collapse=2) + $:GPU_PARALLEL_LOOP(private='[l, k]', collapse=2) do l = 0, p do k = 0, n select case (bc_type(1, 1)%sf(0, k, l)) @@ -1954,13 +1791,12 @@ contains end do end do $:END_GPU_PARALLEL_LOOP() - end if if (bc_x%end >= 0) then call s_mpi_sendrecv_variables_buffers(jac_sf, 1, 1, 1) else - $:GPU_PARALLEL_LOOP(private='[l,k]', collapse=2) + $:GPU_PARALLEL_LOOP(private='[l, k]', collapse=2) do l = 0, p do k = 0, n select case (bc_type(1, 2)%sf(0, k, l)) @@ -1980,17 +1816,15 @@ contains end do end do $:END_GPU_PARALLEL_LOOP() - end if #:if not MFC_CASE_OPTIMIZATION or num_dims > 1 - if (n == 0) then return else if (bc_y%beg >= 0) then call s_mpi_sendrecv_variables_buffers(jac_sf, 2, -1, 1) else - $:GPU_PARALLEL_LOOP(private='[l,k]', collapse=2) + $:GPU_PARALLEL_LOOP(private='[l, k]', collapse=2) do l = 0, p do k = idwbuff(1)%beg, idwbuff(1)%end select case (bc_type(2, 1)%sf(k, 0, l)) @@ -2010,13 +1844,12 @@ contains end do end do $:END_GPU_PARALLEL_LOOP() - end if if (bc_y%end >= 0) then call s_mpi_sendrecv_variables_buffers(jac_sf, 2, 1, 1) else - $:GPU_PARALLEL_LOOP(private='[l,k]', collapse=2) + $:GPU_PARALLEL_LOOP(private='[l, k]', collapse=2) do l = 0, p do k = idwbuff(1)%beg, idwbuff(1)%end select case (bc_type(2, 2)%sf(k, 0, l)) @@ -2037,7 +1870,6 @@ contains end do $:END_GPU_PARALLEL_LOOP() end if - #:endif #:if not MFC_CASE_OPTIMIZATION or num_dims > 2 @@ -2046,7 +1878,7 @@ contains else if (bc_z%beg >= 0) then call s_mpi_sendrecv_variables_buffers(jac_sf, 3, -1, 1) else - $:GPU_PARALLEL_LOOP(private='[l,k]', collapse=2) + $:GPU_PARALLEL_LOOP(private='[l, k]', collapse=2) do l = idwbuff(2)%beg, idwbuff(2)%end do k = idwbuff(1)%beg, idwbuff(1)%end select case (bc_type(3, 1)%sf(k, l, 0)) @@ -2071,7 +1903,7 @@ contains if (bc_z%end >= 0) then call s_mpi_sendrecv_variables_buffers(jac_sf, 3, 1, 1) else - $:GPU_PARALLEL_LOOP(private='[l,k]', collapse=2) + $:GPU_PARALLEL_LOOP(private='[l, k]', collapse=2) do l = idwbuff(2)%beg, idwbuff(2)%end do k = idwbuff(1)%beg, idwbuff(1)%end select case (bc_type(3, 2)%sf(k, l, 0)) @@ -2093,25 +1925,26 @@ contains $:END_GPU_PARALLEL_LOOP() end if #:endif + end subroutine s_populate_F_igr_buffers !> @brief Creates MPI derived datatypes for boundary condition type arrays and buffer arrays used in parallel I/O. impure subroutine s_create_mpi_types(bc_type) - type(integer_field), dimension(1:num_dims, 1:2), intent(in) :: bc_type + type(integer_field), dimension(1:num_dims,1:2), intent(in) :: bc_type #ifdef MFC_MPI - integer :: dir, loc + integer :: dir, loc integer, dimension(3) :: sf_start_idx, sf_extents_loc - integer :: ierr + integer :: ierr do dir = 1, num_dims do loc = 1, 2 sf_start_idx = (/0, 0, 0/) sf_extents_loc = shape(bc_type(dir, loc)%sf) - call MPI_TYPE_CREATE_SUBARRAY(num_dims, sf_extents_loc, sf_extents_loc, sf_start_idx, & - MPI_ORDER_FORTRAN, MPI_INTEGER, MPI_BC_TYPE_TYPE(dir, loc), ierr) + call MPI_TYPE_CREATE_SUBARRAY(num_dims, sf_extents_loc, sf_extents_loc, sf_start_idx, MPI_ORDER_FORTRAN, & + & MPI_INTEGER, MPI_BC_TYPE_TYPE(dir, loc), ierr) call MPI_TYPE_COMMIT(MPI_BC_TYPE_TYPE(dir, loc), ierr) end do end do @@ -2122,26 +1955,24 @@ contains sf_extents_loc = shape(bc_buffers(dir, loc)%sf) call MPI_TYPE_CREATE_SUBARRAY(num_dims, sf_extents_loc*mpi_io_type, sf_extents_loc*mpi_io_type, sf_start_idx, & - MPI_ORDER_FORTRAN, mpi_io_p, MPI_BC_BUFFER_TYPE(dir, loc), ierr) + & MPI_ORDER_FORTRAN, mpi_io_p, MPI_BC_BUFFER_TYPE(dir, loc), ierr) call MPI_TYPE_COMMIT(MPI_BC_BUFFER_TYPE(dir, loc), ierr) end do end do #endif + end subroutine s_create_mpi_types !> @brief Writes boundary condition type and buffer data to serial (unformatted) restart files. subroutine s_write_serial_boundary_condition_files(q_prim_vf, bc_type, step_dirpath, old_grid_in) - type(scalar_field), dimension(sys_size), intent(in) :: q_prim_vf - type(integer_field), dimension(1:num_dims, 1:2), intent(in) :: bc_type - logical, intent(in) :: old_grid_in - - character(LEN=*), intent(in) :: step_dirpath - - integer :: dir, loc, i - character(len=path_len) :: file_path - - character(len=10) :: status + type(scalar_field), dimension(sys_size), intent(in) :: q_prim_vf + type(integer_field), dimension(1:num_dims,1:2), intent(in) :: bc_type + logical, intent(in) :: old_grid_in + character(LEN=*), intent(in) :: step_dirpath + integer :: dir, loc, i + character(len=path_len) :: file_path + character(len=10) :: status if (old_grid_in) then status = 'old' @@ -2151,8 +1982,8 @@ contains call s_pack_boundary_condition_buffers(q_prim_vf) - file_path = trim(step_dirpath)//'/bc_type.dat' - open (1, FILE=trim(file_path), FORM='unformatted', STATUS=status) + file_path = trim(step_dirpath) // '/bc_type.dat' + open (1, FILE=trim(file_path), form='unformatted', STATUS=status) do dir = 1, num_dims do loc = 1, 2 write (1) bc_type(dir, loc)%sf @@ -2160,8 +1991,8 @@ contains end do close (1) - file_path = trim(step_dirpath)//'/bc_buffers.dat' - open (1, FILE=trim(file_path), FORM='unformatted', STATUS=status) + file_path = trim(step_dirpath) // '/bc_buffers.dat' + open (1, FILE=trim(file_path), form='unformatted', STATUS=status) do dir = 1, num_dims do loc = 1, 2 write (1) bc_buffers(dir, loc)%sf @@ -2174,25 +2005,23 @@ contains !> @brief Writes boundary condition type and buffer data to per-rank parallel files using MPI I/O. subroutine s_write_parallel_boundary_condition_files(q_prim_vf, bc_type) - type(scalar_field), dimension(sys_size), intent(in) :: q_prim_vf - type(integer_field), dimension(1:num_dims, 1:2), intent(in) :: bc_type - - integer :: dir, loc - character(len=path_len) :: file_loc, file_path - - character(len=10) :: status + type(scalar_field), dimension(sys_size), intent(in) :: q_prim_vf + type(integer_field), dimension(1:num_dims,1:2), intent(in) :: bc_type + integer :: dir, loc + character(len=path_len) :: file_loc, file_path + character(len=10) :: status #ifdef MFC_MPI - integer :: ierr - integer :: file_id - integer :: offset + integer :: ierr + integer :: file_id + integer :: offset character(len=7) :: proc_rank_str - logical :: dir_check - integer :: nelements + logical :: dir_check + integer :: nelements call s_pack_boundary_condition_buffers(q_prim_vf) - file_loc = trim(case_dir)//'/restart_data/boundary_conditions' + file_loc = trim(case_dir) // '/restart_data/boundary_conditions' if (proc_rank == 0) then call my_inquire(file_loc, dir_check) if (dir_check .neqv. .true.) then @@ -2207,7 +2036,7 @@ contains call DelayFileAccess(proc_rank) write (proc_rank_str, '(I7.7)') proc_rank - file_path = trim(file_loc)//'/bc_'//trim(proc_rank_str)//'.dat' + file_path = trim(file_loc) // '/bc_' // trim(proc_rank_str) // '.dat' call MPI_File_open(MPI_COMM_SELF, trim(file_path), MPI_MODE_CREATE + MPI_MODE_WRONLY, MPI_INFO_NULL, file_id, ierr) offset = 0 @@ -2241,24 +2070,22 @@ contains !> @brief Reads boundary condition type and buffer data from serial (unformatted) restart files. subroutine s_read_serial_boundary_condition_files(step_dirpath, bc_type) - character(LEN=*), intent(in) :: step_dirpath - - type(integer_field), dimension(1:num_dims, 1:2), intent(inout) :: bc_type - - integer :: dir, loc - logical :: file_exist - character(len=path_len) :: file_path - - character(len=10) :: status + character(LEN=*), intent(in) :: step_dirpath + type(integer_field), dimension(1:num_dims,1:2), intent(inout) :: bc_type + integer :: dir, loc + logical :: file_exist + character(len=path_len) :: file_path + character(len=10) :: status ! Read bc_types - file_path = trim(step_dirpath)//'/bc_type.dat' + + file_path = trim(step_dirpath) // '/bc_type.dat' inquire (FILE=trim(file_path), EXIST=file_exist) if (.not. file_exist) then - call s_mpi_abort(trim(file_path)//' is missing. Exiting.') + call s_mpi_abort(trim(file_path) // ' is missing. Exiting.') end if - open (1, FILE=trim(file_path), FORM='unformatted', STATUS='unknown') + open (1, FILE=trim(file_path), form='unformatted', STATUS='unknown') do dir = 1, num_dims do loc = 1, 2 read (1) bc_type(dir, loc)%sf @@ -2268,13 +2095,13 @@ contains close (1) ! Read bc_buffers - file_path = trim(step_dirpath)//'/bc_buffers.dat' + file_path = trim(step_dirpath) // '/bc_buffers.dat' inquire (FILE=trim(file_path), EXIST=file_exist) if (.not. file_exist) then - call s_mpi_abort(trim(file_path)//' is missing. Exiting.') + call s_mpi_abort(trim(file_path) // ' is missing. Exiting.') end if - open (1, FILE=trim(file_path), FORM='unformatted', STATUS='unknown') + open (1, FILE=trim(file_path), form='unformatted', STATUS='unknown') do dir = 1, num_dims do loc = 1, 2 read (1) bc_buffers(dir, loc)%sf @@ -2288,27 +2115,25 @@ contains !> @brief Reads boundary condition type and buffer data from per-rank parallel files using MPI I/O. subroutine s_read_parallel_boundary_condition_files(bc_type) - type(integer_field), dimension(1:num_dims, 1:2), intent(inout) :: bc_type - - integer :: dir, loc - character(len=path_len) :: file_loc, file_path - - character(len=10) :: status + type(integer_field), dimension(1:num_dims,1:2), intent(inout) :: bc_type + integer :: dir, loc + character(len=path_len) :: file_loc, file_path + character(len=10) :: status #ifdef MFC_MPI - integer :: ierr - integer :: file_id - integer :: offset + integer :: ierr + integer :: file_id + integer :: offset character(len=7) :: proc_rank_str - logical :: dir_check - integer :: nelements + logical :: dir_check + integer :: nelements - file_loc = trim(case_dir)//'/restart_data/boundary_conditions' + file_loc = trim(case_dir) // '/restart_data/boundary_conditions' if (proc_rank == 0) then call my_inquire(file_loc, dir_check) if (dir_check .neqv. .true.) then - call s_mpi_abort(trim(file_loc)//' is missing. Exiting.') + call s_mpi_abort(trim(file_loc) // ' is missing. Exiting.') end if end if @@ -2319,7 +2144,7 @@ contains call DelayFileAccess(proc_rank) write (proc_rank_str, '(I7.7)') proc_rank - file_path = trim(file_loc)//'/bc_'//trim(proc_rank_str)//'.dat' + file_path = trim(file_loc) // '/bc_' // trim(proc_rank_str) // '.dat' call MPI_File_open(MPI_COMM_SELF, trim(file_path), MPI_MODE_RDONLY, MPI_INFO_NULL, file_id, ierr) offset = 0 @@ -2356,7 +2181,7 @@ contains subroutine s_pack_boundary_condition_buffers(q_prim_vf) type(scalar_field), dimension(sys_size), intent(in) :: q_prim_vf - integer :: i, j, k + integer :: i, j, k do k = 0, p do j = 0, n @@ -2368,7 +2193,6 @@ contains end do #:if not MFC_CASE_OPTIMIZATION or num_dims > 1 - if (n > 0) then do k = 0, p do j = 1, sys_size @@ -2380,7 +2204,6 @@ contains end do #:if not MFC_CASE_OPTIMIZATION or num_dims > 2 - if (p > 0) then do k = 1, sys_size do j = 0, n @@ -2391,10 +2214,8 @@ contains end do end do end if - #:endif end if - #:endif end subroutine s_pack_boundary_condition_buffers @@ -2402,22 +2223,22 @@ contains !> @brief Initializes the per-cell boundary condition type arrays with the global default BC values. subroutine s_assign_default_bc_type(bc_type) - type(integer_field), dimension(1:num_dims, 1:2), intent(in) :: bc_type + type(integer_field), dimension(1:num_dims,1:2), intent(in) :: bc_type - bc_type(1, 1)%sf(:, :, :) = int(min(bc_x%beg, 0), kind=1) - bc_type(1, 2)%sf(:, :, :) = int(min(bc_x%end, 0), kind=1) - $:GPU_UPDATE(device='[bc_type(1,1)%sf,bc_type(1,2)%sf]') + bc_type(1, 1)%sf(:,:,:) = int(min(bc_x%beg, 0), kind=1) + bc_type(1, 2)%sf(:,:,:) = int(min(bc_x%end, 0), kind=1) + $:GPU_UPDATE(device='[bc_type(1, 1)%sf, bc_type(1, 2)%sf]') #:if not MFC_CASE_OPTIMIZATION or num_dims > 1 if (n > 0) then - bc_type(2, 1)%sf(:, :, :) = int(min(bc_y%beg, 0), kind=1) - bc_type(2, 2)%sf(:, :, :) = int(min(bc_y%end, 0), kind=1) - $:GPU_UPDATE(device='[bc_type(2,1)%sf,bc_type(2,2)%sf]') + bc_type(2, 1)%sf(:,:,:) = int(min(bc_y%beg, 0), kind=1) + bc_type(2, 2)%sf(:,:,:) = int(min(bc_y%end, 0), kind=1) + $:GPU_UPDATE(device='[bc_type(2, 1)%sf, bc_type(2, 2)%sf]') #:if not MFC_CASE_OPTIMIZATION or num_dims > 2 if (p > 0) then - bc_type(3, 1)%sf(:, :, :) = int(min(bc_z%beg, 0), kind=1) - bc_type(3, 2)%sf(:, :, :) = int(min(bc_z%end, 0), kind=1) - $:GPU_UPDATE(device='[bc_type(3,1)%sf,bc_type(3,2)%sf]') + bc_type(3, 1)%sf(:,:,:) = int(min(bc_z%beg, 0), kind=1) + bc_type(3, 2)%sf(:,:,:) = int(min(bc_z%end, 0), kind=1) + $:GPU_UPDATE(device='[bc_type(3, 1)%sf, bc_type(3, 2)%sf]') end if #:endif end if @@ -2425,13 +2246,11 @@ contains end subroutine s_assign_default_bc_type - !> The purpose of this subroutine is to populate the buffers - !! of the grid variables, which are constituted of the cell- - !! boundary locations and cell-width distributions, based on - !! the boundary conditions. + !> The purpose of this subroutine is to populate the buffers of the grid variables, which are constituted of the cell- boundary + !! locations and cell-width distributions, based on the boundary conditions. subroutine s_populate_grid_variables_buffers - integer :: i !< Generic loop iterator + integer :: i !< Generic loop iterator #ifdef MFC_SIMULATION ! Required for compatibility between codes @@ -2463,7 +2282,6 @@ contains end if #endif $:GPU_UPDATE(device='[glb_bounds]') - #endif #ifndef MFC_PRE_PROCESS @@ -2472,15 +2290,15 @@ contains ! Populating cell-width distribution buffer at bc_x%beg if (bc_x%beg >= 0) then call s_mpi_sendrecv_grid_variables_buffers(1, -1) - elseif (bc_x%beg <= BC_GHOST_EXTRAP) then + else if (bc_x%beg <= BC_GHOST_EXTRAP) then do i = 1, buff_size dx(-i) = dx(0) end do - elseif (bc_x%beg == BC_REFLECTIVE) then + else if (bc_x%beg == BC_REFLECTIVE) then do i = 1, buff_size dx(-i) = dx(i - 1) end do - elseif (bc_x%beg == BC_PERIODIC) then + else if (bc_x%beg == BC_PERIODIC) then do i = 1, buff_size dx(-i) = dx(m - (i - 1)) end do @@ -2498,15 +2316,15 @@ contains ! Populating the cell-width distribution buffer at bc_x%end if (bc_x%end >= 0) then call s_mpi_sendrecv_grid_variables_buffers(1, 1) - elseif (bc_x%end <= BC_GHOST_EXTRAP) then + else if (bc_x%end <= BC_GHOST_EXTRAP) then do i = 1, buff_size dx(m + i) = dx(m) end do - elseif (bc_x%end == BC_REFLECTIVE) then + else if (bc_x%end == BC_REFLECTIVE) then do i = 1, buff_size dx(m + i) = dx(m - (i - 1)) end do - elseif (bc_x%end == BC_PERIODIC) then + else if (bc_x%end == BC_PERIODIC) then do i = 1, buff_size dx(m + i) = dx(i - 1) end do @@ -2527,17 +2345,17 @@ contains ! Populating cell-width distribution buffer at bc_y%beg if (n == 0) then return - elseif (bc_y%beg >= 0) then + else if (bc_y%beg >= 0) then call s_mpi_sendrecv_grid_variables_buffers(2, -1) - elseif (bc_y%beg <= BC_GHOST_EXTRAP .and. bc_y%beg /= BC_AXIS) then + else if (bc_y%beg <= BC_GHOST_EXTRAP .and. bc_y%beg /= BC_AXIS) then do i = 1, buff_size dy(-i) = dy(0) end do - elseif (bc_y%beg == BC_REFLECTIVE .or. bc_y%beg == BC_AXIS) then + else if (bc_y%beg == BC_REFLECTIVE .or. bc_y%beg == BC_AXIS) then do i = 1, buff_size dy(-i) = dy(i - 1) end do - elseif (bc_y%beg == BC_PERIODIC) then + else if (bc_y%beg == BC_PERIODIC) then do i = 1, buff_size dy(-i) = dy(n - (i - 1)) end do @@ -2555,15 +2373,15 @@ contains ! Populating the cell-width distribution buffer at bc_y%end if (bc_y%end >= 0) then call s_mpi_sendrecv_grid_variables_buffers(2, 1) - elseif (bc_y%end <= BC_GHOST_EXTRAP) then + else if (bc_y%end <= BC_GHOST_EXTRAP) then do i = 1, buff_size dy(n + i) = dy(n) end do - elseif (bc_y%end == BC_REFLECTIVE) then + else if (bc_y%end == BC_REFLECTIVE) then do i = 1, buff_size dy(n + i) = dy(n - (i - 1)) end do - elseif (bc_y%end == BC_PERIODIC) then + else if (bc_y%end == BC_PERIODIC) then do i = 1, buff_size dy(n + i) = dy(i - 1) end do @@ -2584,17 +2402,17 @@ contains ! Populating cell-width distribution buffer at bc_z%beg if (p == 0) then return - elseif (Bc_z%beg >= 0) then + else if (Bc_z%beg >= 0) then call s_mpi_sendrecv_grid_variables_buffers(3, -1) - elseif (bc_z%beg <= BC_GHOST_EXTRAP) then + else if (bc_z%beg <= BC_GHOST_EXTRAP) then do i = 1, buff_size dz(-i) = dz(0) end do - elseif (bc_z%beg == BC_REFLECTIVE) then + else if (bc_z%beg == BC_REFLECTIVE) then do i = 1, buff_size dz(-i) = dz(i - 1) end do - elseif (bc_z%beg == BC_PERIODIC) then + else if (bc_z%beg == BC_PERIODIC) then do i = 1, buff_size dz(-i) = dz(p - (i - 1)) end do @@ -2612,15 +2430,15 @@ contains ! Populating the cell-width distribution buffer at bc_z%end if (bc_z%end >= 0) then call s_mpi_sendrecv_grid_variables_buffers(3, 1) - elseif (bc_z%end <= BC_GHOST_EXTRAP) then + else if (bc_z%end <= BC_GHOST_EXTRAP) then do i = 1, buff_size dz(p + i) = dz(p) end do - elseif (bc_z%end == BC_REFLECTIVE) then + else if (bc_z%end == BC_REFLECTIVE) then do i = 1, buff_size dz(p + i) = dz(p - (i - 1)) end do - elseif (bc_z%end == BC_PERIODIC) then + else if (bc_z%end == BC_PERIODIC) then do i = 1, buff_size dz(p + i) = dz(i - 1) end do @@ -2635,7 +2453,6 @@ contains z_cc(p + i) = z_cc(p + (i - 1)) + (dz(p + (i - 1)) + dz(p + i))/2._wp end do ! END: Population of Buffers in z-direction - #endif end subroutine s_populate_grid_variables_buffers diff --git a/src/common/m_checker_common.fpp b/src/common/m_checker_common.fpp index 2280828a3a..e6c6b54632 100644 --- a/src/common/m_checker_common.fpp +++ b/src/common/m_checker_common.fpp @@ -8,12 +8,9 @@ !> @brief Shared input validation checks for grid dimensions and AMD GPU compiler limits module m_checker_common - use m_global_parameters !< Definitions of the global parameters - - use m_mpi_proxy !< Message passing interface (MPI) module proxy - - use m_helper_basic !< Functions to compare floating point numbers - + use m_global_parameters !< Definitions of the global parameters + use m_mpi_proxy !< Message passing interface (MPI) module proxy + use m_helper_basic !< Functions to compare floating point numbers use m_helper implicit none @@ -22,8 +19,7 @@ module m_checker_common contains - !> Checks compatibility of parameters in the input file. - !! Used by all three stages + !> Checks compatibility of parameters in the input file. Used by all three stages impure subroutine s_check_inputs_common #ifndef MFC_SIMULATION @@ -36,20 +32,20 @@ contains end subroutine s_check_inputs_common #ifndef MFC_SIMULATION - !> @brief Verifies that the total number of grid cells meets the minimum required by the number of dimensions and MPI ranks. impure subroutine s_check_total_cells - character(len=18) :: numStr !< for int to string conversion - integer(kind=8) :: min_cells + + character(len=18) :: numStr !< for int to string conversion + integer(kind=8) :: min_cells min_cells = int(2, kind=8)**int(min(1, m) + min(1, n) + min(1, p), kind=8)*int(num_procs, kind=8) call s_int_to_str(2**(min(1, m) + min(1, n) + min(1, p))*num_procs, numStr) @:PROHIBIT(nGlobal < min_cells, & - "Total number of cells must be at least (2^[number of dimensions])*num_procs, " // & - "which is currently "//trim(numStr)) - end subroutine s_check_total_cells + & "Total number of cells must be at least (2^[number of dimensions])*num_procs, " & + & // "which is currently "//trim(numStr)) + end subroutine s_check_total_cells #endif !> @brief Checks that simulation parameters stay within AMD GPU compiler limits when case optimization is disabled. @@ -64,7 +60,5 @@ contains end subroutine s_check_amd #ifndef MFC_POST_PROCESS - #endif - end module m_checker_common diff --git a/src/common/m_chemistry.fpp b/src/common/m_chemistry.fpp index d7ffbc3cfe..7ffb622e13 100644 --- a/src/common/m_chemistry.fpp +++ b/src/common/m_chemistry.fpp @@ -9,21 +9,18 @@ !> @brief Multi-species chemistry interface for thermodynamic properties, reaction rates, and transport coefficients module m_chemistry - use m_thermochem, only: & - num_species, molecular_weights, get_temperature, get_net_production_rates, & - get_mole_fractions, get_species_binary_mass_diffusivities, & - get_species_mass_diffusivities_mixavg, gas_constant, get_mixture_molecular_weight, & - get_mixture_energy_mass, get_mixture_thermal_conductivity_mixavg, get_species_enthalpies_rt, & - get_mixture_viscosity_mixavg, get_mixture_specific_heat_cp_mass, get_mixture_enthalpy_mass + use m_thermochem, only: num_species, molecular_weights, get_temperature, get_net_production_rates, get_mole_fractions, & + & get_species_binary_mass_diffusivities, get_species_mass_diffusivities_mixavg, gas_constant, & + & get_mixture_molecular_weight, get_mixture_energy_mass, get_mixture_thermal_conductivity_mixavg, & + & get_species_enthalpies_rt, get_mixture_viscosity_mixavg, get_mixture_specific_heat_cp_mass, get_mixture_enthalpy_mass use m_global_parameters implicit none #:if USING_AMD - real(wp) :: molecular_weights_nonparameter(10) = & - (/2.016, 1.008, 15.999, 31.998, 17.007, 18.015, 33.006, & - 34.014, 39.95, 28.014/) + real(wp) :: molecular_weights_nonparameter(10) = (/2.016, 1.008, 15.999, 31.998, 17.007, 18.015, 33.006, 34.014, 39.95, & + & 28.014/) $:GPU_DECLARE(create='[molecular_weights_nonparameter]') #:endif @@ -37,10 +34,9 @@ contains !> @brief Computes mixture viscosities for left and right states and inverts them for use as reciprocal Reynolds numbers. subroutine compute_viscosity_and_inversion(T_L, Ys_L, T_R, Ys_R, Re_L, Re_R) - $:GPU_ROUTINE(function_name='compute_viscosity_and_inversion',parallelism='[seq]', & - & cray_inline=True) + $:GPU_ROUTINE(function_name='compute_viscosity_and_inversion',parallelism='[seq]', cray_inline=True) - real(wp), intent(inout) :: T_L, T_R, Re_L, Re_R + real(wp), intent(inout) :: T_L, T_R, Re_L, Re_R real(wp), dimension(num_species), intent(inout) :: Ys_R, Ys_L call get_mixture_viscosity_mixavg(T_L, Ys_L, Re_L) @@ -53,40 +49,32 @@ contains !> @brief Initializes the temperature field from conservative variables by inverting the energy equation. subroutine s_compute_q_T_sf(q_T_sf, q_cons_vf, bounds) - ! Initialize the temperature field at the start of the simulation to - ! reasonable values. Temperature is computed the regular way using the - ! conservative variables. + ! Initialize the temperature field at the start of the simulation to reasonable values. Temperature is computed the regular + ! way using the conservative variables. - type(scalar_field), intent(inout) :: q_T_sf + type(scalar_field), intent(inout) :: q_T_sf type(scalar_field), dimension(sys_size), intent(in) :: q_cons_vf - type(int_bounds_info), dimension(1:3), intent(in) :: bounds - - integer :: x, y, z, eqn - real(wp) :: energy, T_in - real(wp), dimension(num_species) :: Ys + type(int_bounds_info), dimension(1:3), intent(in) :: bounds + integer :: x, y, z, eqn + real(wp) :: energy, T_in + real(wp), dimension(num_species) :: Ys do z = bounds(3)%beg, bounds(3)%end do y = bounds(2)%beg, bounds(2)%end do x = bounds(1)%beg, bounds(1)%end do eqn = chemxb, chemxe - Ys(eqn - chemxb + 1) = & - q_cons_vf(eqn)%sf(x, y, z)/q_cons_vf(contxb)%sf(x, y, z) + Ys(eqn - chemxb + 1) = q_cons_vf(eqn)%sf(x, y, z)/q_cons_vf(contxb)%sf(x, y, z) end do - ! e = E - 1/2*|u|^2 - ! cons. E_idx = \rho E - ! cons. contxb = \rho (1-fluid model) - ! cons. momxb + i = \rho u_i + ! e = E - 1/2*|u|^2 cons. E_idx = \rho E cons. contxb = \rho (1-fluid model) cons. momxb + i = \rho u_i energy = q_cons_vf(E_idx)%sf(x, y, z)/q_cons_vf(contxb)%sf(x, y, z) do eqn = momxb, momxe - energy = energy - & - 0.5_wp*(q_cons_vf(eqn)%sf(x, y, z)/q_cons_vf(contxb)%sf(x, y, z))**2._wp + energy = energy - 0.5_wp*(q_cons_vf(eqn)%sf(x, y, z)/q_cons_vf(contxb)%sf(x, y, z))**2._wp end do T_in = real(q_T_sf%sf(x, y, z), kind=wp) call get_temperature(energy, dflt_T_guess, Ys, .true., T_in) q_T_sf%sf(x, y, z) = T_in - end do end do end do @@ -96,13 +84,12 @@ contains !> @brief Computes the temperature field from primitive variables using the ideal gas law and mixture molecular weight. subroutine s_compute_T_from_primitives(q_T_sf, q_prim_vf, bounds) - type(scalar_field), intent(inout) :: q_T_sf + type(scalar_field), intent(inout) :: q_T_sf type(scalar_field), dimension(sys_size), intent(in) :: q_prim_vf - type(int_bounds_info), dimension(1:3), intent(in) :: bounds - - integer :: x, y, z, i - real(wp), dimension(num_species) :: Ys - real(wp) :: mix_mol_weight + type(int_bounds_info), dimension(1:3), intent(in) :: bounds + integer :: x, y, z, i + real(wp), dimension(num_species) :: Ys + real(wp) :: mix_mol_weight do z = bounds(3)%beg, bounds(3)%end do y = bounds(2)%beg, bounds(2)%end @@ -123,14 +110,14 @@ contains subroutine s_compute_chemistry_reaction_flux(rhs_vf, q_cons_qp, q_T_sf, q_prim_qp, bounds) type(scalar_field), dimension(sys_size), intent(inout) :: rhs_vf - type(scalar_field), intent(inout) :: q_T_sf + type(scalar_field), intent(inout) :: q_T_sf type(scalar_field), dimension(sys_size), intent(inout) :: q_cons_qp, q_prim_qp - type(int_bounds_info), dimension(1:3), intent(in) :: bounds + type(int_bounds_info), dimension(1:3), intent(in) :: bounds + integer :: x, y, z + integer :: eqn + real(wp) :: T + real(wp) :: rho, omega_m - integer :: x, y, z - integer :: eqn - real(wp) :: T - real(wp) :: rho, omega_m #:if not MFC_CASE_OPTIMIZATION and USING_AMD real(wp), dimension(10) :: Ys real(wp), dimension(10) :: omega @@ -143,7 +130,6 @@ contains do z = bounds(3)%beg, bounds(3)%end do y = bounds(2)%beg, bounds(2)%end do x = bounds(1)%beg, bounds(1)%end - $:GPU_LOOP(parallelism='[seq]') do eqn = chemxb, chemxe Ys(eqn - chemxb + 1) = q_prim_qp(eqn)%sf(x, y, z) @@ -162,9 +148,7 @@ contains omega_m = molecular_weights(eqn - chemxb + 1)*omega(eqn - chemxb + 1) #:endif rhs_vf(eqn)%sf(x, y, z) = rhs_vf(eqn)%sf(x, y, z) + omega_m - end do - end do end do end do @@ -175,11 +159,11 @@ contains !> @brief Computes species mass diffusion fluxes at cell interfaces using mixture-averaged diffusivities. subroutine s_compute_chemistry_diffusion_flux(idir, q_prim_qp, flux_src_vf, irx, iry, irz) - type(scalar_field), dimension(sys_size), intent(in) :: q_prim_qp + type(scalar_field), dimension(sys_size), intent(in) :: q_prim_qp type(scalar_field), dimension(sys_size), intent(inout) :: flux_src_vf - type(int_bounds_info), intent(in) :: irx, iry, irz + type(int_bounds_info), intent(in) :: irx, iry, irz + integer, intent(in) :: idir - integer, intent(in) :: idir #:if not MFC_CASE_OPTIMIZATION and USING_AMD real(wp), dimension(10) :: Xs_L, Xs_R, Xs_cell, Ys_L, Ys_R, Ys_cell real(wp), dimension(10) :: mass_diffusivities_mixavg1, mass_diffusivities_mixavg2 @@ -192,29 +176,31 @@ contains real(wp), dimension(num_species) :: Mass_Diffu_Flux, dYk_dxi #:endif - real(wp) :: Mass_Diffu_Energy - real(wp) :: MW_L, MW_R, MW_cell, Rgas_L, Rgas_R, T_L, T_R, P_L, P_R, rho_L, rho_R, rho_cell, rho_Vic - real(wp) :: lambda_L, lambda_R, lambda_Cell, dT_dxi, grid_spacing - real(wp) :: Cp_L, Cp_R - real(wp) :: diffusivity_L, diffusivity_R, diffusivity_cell - real(wp) :: hmix_L, hmix_R, dh_dxi - - integer :: x, y, z, i, n, eqn + real(wp) :: Mass_Diffu_Energy + real(wp) :: MW_L, MW_R, MW_cell, Rgas_L, Rgas_R, T_L, T_R, P_L, P_R, rho_L, rho_R, rho_cell, rho_Vic + real(wp) :: lambda_L, lambda_R, lambda_Cell, dT_dxi, grid_spacing + real(wp) :: Cp_L, Cp_R + real(wp) :: diffusivity_L, diffusivity_R, diffusivity_cell + real(wp) :: hmix_L, hmix_R, dh_dxi + integer :: x, y, z, i, n, eqn integer, dimension(3) :: offsets isc1 = irx; isc2 = iry; isc3 = irz - $:GPU_UPDATE(device='[isc1,isc2,isc3]') + $:GPU_UPDATE(device='[isc1, isc2, isc3]') if (chemistry .or. dummy) then - ! Set offsets based on direction using array indexing offsets = 0 offsets(idir) = 1 ! Model 1: Mixture-Average Transport if (chem_params%transport_model == 1) then ! Note: Added 'i' and 'eqn' to private list. - $:GPU_PARALLEL_LOOP(collapse=3, private='[x,y,z,i,eqn,Ys_L, Ys_R, Ys_cell, Xs_L, Xs_R, mass_diffusivities_mixavg1, mass_diffusivities_mixavg2, mass_diffusivities_mixavg_Cell, h_l, h_r, Xs_cell, h_k, dXk_dxi,Mass_Diffu_Flux, Mass_Diffu_Energy, MW_L, MW_R, MW_cell, Rgas_L, Rgas_R, T_L, T_R, P_L, P_R, rho_L, rho_R, rho_cell, rho_Vic, lambda_L, lambda_R, lambda_Cell, dT_dxi, grid_spacing]', copyin='[offsets]') + $:GPU_PARALLEL_LOOP(collapse=3, private='[x, y, z, i, eqn, Ys_L, Ys_R, Ys_cell, Xs_L, Xs_R, & + & mass_diffusivities_mixavg1, mass_diffusivities_mixavg2, mass_diffusivities_mixavg_Cell, & + & h_l, h_r, Xs_cell, h_k, dXk_dxi, Mass_Diffu_Flux, Mass_Diffu_Energy, MW_L, MW_R, MW_cell, & + & Rgas_L, Rgas_R, T_L, T_R, P_L, P_R, rho_L, rho_R, rho_cell, rho_Vic, lambda_L, lambda_R, & + & lambda_Cell, dT_dxi, grid_spacing]', copyin='[offsets]') do z = isc3%beg, isc3%end do y = isc2%beg, isc2%end do x = isc1%beg, isc1%end @@ -274,8 +260,10 @@ contains $:GPU_LOOP(parallelism='[seq]') do i = chemxb, chemxe #:if USING_AMD - h_l(i - chemxb + 1) = h_l(i - chemxb + 1)*gas_constant*T_L/molecular_weights_nonparameter(i - chemxb + 1) - h_r(i - chemxb + 1) = h_r(i - chemxb + 1)*gas_constant*T_R/molecular_weights_nonparameter(i - chemxb + 1) + h_l(i - chemxb + 1) = h_l(i - chemxb + 1)*gas_constant*T_L/molecular_weights_nonparameter(i & + & - chemxb + 1) + h_r(i - chemxb + 1) = h_r(i - chemxb + 1)*gas_constant*T_R/molecular_weights_nonparameter(i & + & - chemxb + 1) #:else h_l(i - chemxb + 1) = h_l(i - chemxb + 1)*gas_constant*T_L/molecular_weights(i - chemxb + 1) h_r(i - chemxb + 1) = h_r(i - chemxb + 1)*gas_constant*T_R/molecular_weights(i - chemxb + 1) @@ -288,8 +276,8 @@ contains ! Calculate mixture-averaged diffusivities $:GPU_LOOP(parallelism='[seq]') do i = chemxb, chemxe - mass_diffusivities_mixavg_Cell(i - chemxb + 1) = & - (mass_diffusivities_mixavg2(i - chemxb + 1) + mass_diffusivities_mixavg1(i - chemxb + 1))/2.0_wp + mass_diffusivities_mixavg_Cell(i - chemxb + 1) = (mass_diffusivities_mixavg2(i - chemxb + 1) & + & + mass_diffusivities_mixavg1(i - chemxb + 1))/2.0_wp end do lambda_Cell = 0.5_wp*(lambda_R + lambda_L) @@ -301,11 +289,12 @@ contains $:GPU_LOOP(parallelism='[seq]') do eqn = chemxb, chemxe #:if USING_AMD - Mass_Diffu_Flux(eqn - chemxb + 1) = rho_cell*mass_diffusivities_mixavg_Cell(eqn - chemxb + 1)* & - molecular_weights_nonparameter(eqn - chemxb + 1)/MW_cell*dXk_dxi(eqn - chemxb + 1) + Mass_Diffu_Flux(eqn - chemxb + 1) = rho_cell*mass_diffusivities_mixavg_Cell(eqn - chemxb + 1) & + & *molecular_weights_nonparameter(eqn - chemxb + 1)/MW_cell*dXk_dxi(eqn & + & - chemxb + 1) #:else - Mass_Diffu_Flux(eqn - chemxb + 1) = rho_cell*mass_diffusivities_mixavg_Cell(eqn - chemxb + 1)* & - molecular_weights(eqn - chemxb + 1)/MW_cell*dXk_dxi(eqn - chemxb + 1) + Mass_Diffu_Flux(eqn - chemxb + 1) = rho_cell*mass_diffusivities_mixavg_Cell(eqn - chemxb + 1) & + & *molecular_weights(eqn - chemxb + 1)/MW_cell*dXk_dxi(eqn - chemxb + 1) #:endif rho_Vic = rho_Vic + Mass_Diffu_Flux(eqn - chemxb + 1) Mass_Diffu_Energy = Mass_Diffu_Energy + h_k(eqn - chemxb + 1)*Mass_Diffu_Flux(eqn - chemxb + 1) @@ -315,7 +304,8 @@ contains $:GPU_LOOP(parallelism='[seq]') do eqn = chemxb, chemxe Mass_Diffu_Energy = Mass_Diffu_Energy - h_k(eqn - chemxb + 1)*Ys_cell(eqn - chemxb + 1)*rho_Vic - Mass_Diffu_Flux(eqn - chemxb + 1) = Mass_Diffu_Flux(eqn - chemxb + 1) - rho_Vic*Ys_cell(eqn - chemxb + 1) + Mass_Diffu_Flux(eqn - chemxb + 1) = Mass_Diffu_Flux(eqn - chemxb + 1) - rho_Vic*Ys_cell(eqn & + & - chemxb + 1) end do ! Add thermal conduction contribution @@ -336,7 +326,10 @@ contains ! Model 2: Unity Lewis Number else if (chem_params%transport_model == 2) then ! Note: Added ALL scalars and 'i'/'eqn' to private list to prevent race conditions. - $:GPU_PARALLEL_LOOP(collapse=3, private='[x,y,z,i,eqn,Ys_L, Ys_R, Ys_cell, dYk_dxi, Mass_Diffu_Flux, grid_spacing, MW_L, MW_R, MW_cell, Rgas_L, Rgas_R, P_L, P_R, rho_L, rho_R, rho_cell, T_L, T_R, Cp_L, Cp_R, hmix_L, hmix_R, dh_dxi, lambda_L, lambda_R, lambda_Cell, diffusivity_L, diffusivity_R, diffusivity_cell, Mass_Diffu_Energy]', copyin='[offsets]') + $:GPU_PARALLEL_LOOP(collapse=3, private='[x, y, z, i, eqn, Ys_L, Ys_R, Ys_cell, dYk_dxi, Mass_Diffu_Flux, & + & grid_spacing, MW_L, MW_R, MW_cell, Rgas_L, Rgas_R, P_L, P_R, rho_L, rho_R, rho_cell, T_L, & + & T_R, Cp_L, Cp_R, hmix_L, hmix_R, dh_dxi, lambda_L, lambda_R, lambda_Cell, diffusivity_L, & + & diffusivity_R, diffusivity_cell, Mass_Diffu_Energy]', copyin='[offsets]') do z = isc3%beg, isc3%end do y = isc2%beg, isc2%end do x = isc1%beg, isc1%end @@ -391,8 +384,7 @@ contains ! Calculate species properties and gradients $:GPU_LOOP(parallelism='[seq]') do i = chemxb, chemxe - dYk_dxi(i - chemxb + 1) = (Ys_R(i - chemxb + 1) - & - Ys_L(i - chemxb + 1))/grid_spacing + dYk_dxi(i - chemxb + 1) = (Ys_R(i - chemxb + 1) - Ys_L(i - chemxb + 1))/grid_spacing end do ! Calculate mixture-averaged diffusivities @@ -407,9 +399,7 @@ contains $:GPU_LOOP(parallelism='[seq]') do eqn = chemxb, chemxe - Mass_Diffu_Flux(eqn - chemxb + 1) = rho_cell* & - diffusivity_cell* & - dYk_dxi(eqn - chemxb + 1) + Mass_Diffu_Flux(eqn - chemxb + 1) = rho_cell*diffusivity_cell*dYk_dxi(eqn - chemxb + 1) end do Mass_Diffu_Energy = rho_cell*diffusivity_cell*dh_dxi diff --git a/src/common/m_compile_specific.f90 b/src/common/m_compile_specific.f90 index 6820ef3a9a..bba8d62f74 100644 --- a/src/common/m_compile_specific.f90 +++ b/src/common/m_compile_specific.f90 @@ -12,82 +12,88 @@ module m_compile_specific contains - !> Creates a directory and all its parents if it does not exist - !! @param dir_name Directory path + !> Creates a directory and all its parents if it does not exist + !! @param dir_name Directory path impure subroutine s_create_directory(dir_name) + character(LEN=*), intent(in) :: dir_name #ifdef _WIN32 - call system('mkdir "'//dir_name//'" 2> NUL') + call system('mkdir "' // dir_name // '" 2> NUL') #else - call system('mkdir -p "'//dir_name//'"') + call system('mkdir -p "' // dir_name // '"') #endif end subroutine s_create_directory !> @brief Deletes a file at the given path using a platform-specific system command. impure subroutine s_delete_file(filepath) + character(LEN=*), intent(in) :: filepath #ifdef _WIN32 - call system('del "'//filepath//'"') + call system('del "' // filepath // '"') #else - call system('rm "'//filepath//'"') + call system('rm "' // filepath // '"') #endif end subroutine s_delete_file !> @brief Recursively deletes a directory using a platform-specific system command. impure subroutine s_delete_directory(dir_name) + character(LEN=*), intent(in) :: dir_name #ifdef _WIN32 - call system('rmdir "'//dir_name//'" /s /q') + call system('rmdir "' // dir_name // '" /s /q') #else - call system('rm -r "'//dir_name//'"') + call system('rm -r "' // dir_name // '"') #endif end subroutine s_delete_directory - !> Inquires on the existence of a directory - !! @param fileloc File directory location - !! @param dircheck Switch that indicates if directory exists + !> Inquires on the existence of a directory + !! @param fileloc File directory location + !! @param dircheck Switch that indicates if directory exists impure subroutine my_inquire(fileloc, dircheck) + character(LEN=*), intent(in) :: fileloc - logical, intent(inout) :: dircheck + logical, intent(inout) :: dircheck #ifdef __INTEL_COMPILER - inquire (DIRECTORY=trim(fileloc), EXIST=dircheck) !Intel + inquire (DIRECTORY=trim(fileloc), EXIST=dircheck) ! Intel #else - inquire (FILE=trim(fileloc), EXIST=dircheck) !GCC + inquire (FILE=trim(fileloc), EXIST=dircheck) ! GCC #endif end subroutine my_inquire !> @brief Retrieves the current working directory path via the GETCWD intrinsic. impure subroutine s_get_cwd(cwd) + character(LEN=*), intent(out) :: cwd call GETCWD(cwd) + end subroutine s_get_cwd !> @brief Extracts the base filename from a directory path using the system basename command. impure subroutine s_get_basename(dirpath, basename) - character(LEN=*), intent(in) :: dirpath - character(LEN=*), intent(out) :: basename - integer :: iUnit - character(len=30) :: tmpfilepath + character(LEN=*), intent(in) :: dirpath + character(LEN=*), intent(out) :: basename + integer :: iUnit + character(len=30) :: tmpfilepath write (tmpfilepath, '(A,I0)') 'basename_', proc_rank #ifdef _WIN32 - call system('for /F %i in ("'//trim(dirpath)//'") do @echo %~ni > '//trim(tmpfilepath)) + call system('for /F %i in ("' // trim(dirpath) // '") do @echo %~ni > ' // trim(tmpfilepath)) #else - call system('basename "'//trim(dirpath)//'" > '//trim(tmpfilepath)) + call system('basename "' // trim(dirpath) // '" > ' // trim(tmpfilepath)) #endif - open (newunit=iUnit, FILE=trim(tmpfilepath), FORM='formatted', STATUS='old') + open (newunit=iUnit, FILE=trim(tmpfilepath), form='formatted', STATUS='old') read (iUnit, '(A)') basename close (iUnit) diff --git a/src/common/m_constants.fpp b/src/common/m_constants.fpp index 75d5f1d6dd..f7f9623f37 100644 --- a/src/common/m_constants.fpp +++ b/src/common/m_constants.fpp @@ -7,70 +7,74 @@ module m_constants use m_precision_select - character, parameter :: dflt_char = ' ' !< Default string value - - real(wp), parameter :: dflt_real = -1.e6_wp !< Default real value - real(wp), parameter :: sgm_eps = 1.e-16_wp !< Segmentation tolerance - real(wp), parameter :: Chem_Tolerance = 1.e-16_wp !< Speed of Sound Tolerance in Chemistry - real(wp), parameter :: small_alf = 1.e-11_wp !< Small alf tolerance - real(wp), parameter :: pi = 3.141592653589793_wp !< Pi - real(wp), parameter :: verysmall = 1.e-12_wp !< Very small number - real(wp), parameter :: small_radius = 1.e-32_wp !< Radius cutoff to avoid division by zero for 3D spherical harmonic patch (geometry 14) - - integer, parameter :: num_stcls_min = 5 !< Minimum # of stencils - integer, parameter :: path_len = 400 !< Maximum path length - integer, parameter :: name_len = 50 !< Maximum name length - integer, parameter :: dflt_int = -100 !< Default integer value - integer, parameter :: fourier_rings = 5 !< Fourier filter ring limit - integer, parameter :: num_fluids_max = 10 !< Maximum number of fluids in the simulation - integer, parameter :: num_probes_max = 10 !< Maximum number of flow probes in the simulation - integer, parameter :: num_patches_max = 1000 - integer, parameter :: num_bc_patches_max = 10 - integer, parameter :: max_2d_fourier_modes = 10 !< Max Fourier mode index for 2D modal patch (geometry 13) - integer, parameter :: max_sph_harm_degree = 5 !< Max degree L for 3D spherical harmonic patch (geometry 14) - integer, parameter :: pathlen_max = 400 - integer, parameter :: nnode = 4 !< Number of QBMM nodes - integer, parameter :: dflt_num_igr_iters = 2 !< number of iterations for IGR elliptic solve - integer, parameter :: dflt_num_igr_warm_start_iters = 50 !< default number of iterations for IGR elliptic solve - real(wp), parameter :: dflt_alf_factor = 10._wp !< scaling factor for IGR alpha - integer, parameter :: gp_layers = 3 !< Number of ghost point layers for IBM - real(wp), parameter :: capillary_cutoff = 1.e-6 !< color function gradient magnitude at which to apply the surface tension fluxes - real(wp), parameter :: acoustic_spatial_support_width = 2.5_wp !< Spatial support width of acoustic source, used in s_source_spatial - real(wp), parameter :: dflt_vcfl_dt = 100._wp !< value of vcfl_dt when viscosity is off for computing adaptive timestep size - real(wp), parameter :: broadband_spectral_level_constant = 20._wp !< The constant to scale the spectral level at the lower frequency bound - real(wp), parameter :: broadband_spectral_level_growth_rate = 10._wp !< The spectral level constant to correct the magnitude at each frequency to ensure the source is overall broadband + character, parameter :: dflt_char = ' ' !< Default string value + real(wp), parameter :: dflt_real = -1.e6_wp !< Default real value + real(wp), parameter :: sgm_eps = 1.e-16_wp !< Segmentation tolerance + real(wp), parameter :: Chem_Tolerance = 1.e-16_wp !< Speed of Sound Tolerance in Chemistry + real(wp), parameter :: small_alf = 1.e-11_wp !< Small alf tolerance + real(wp), parameter :: pi = 3.141592653589793_wp !< Pi + real(wp), parameter :: verysmall = 1.e-12_wp !< Very small number + !> Radius cutoff to avoid division by zero for 3D spherical harmonic patch (geometry 14) + real(wp), parameter :: small_radius = 1.e-32_wp + integer, parameter :: num_stcls_min = 5 !< Minimum # of stencils + integer, parameter :: path_len = 400 !< Maximum path length + integer, parameter :: name_len = 50 !< Maximum name length + integer, parameter :: dflt_int = -100 !< Default integer value + integer, parameter :: fourier_rings = 5 !< Fourier filter ring limit + integer, parameter :: num_fluids_max = 10 !< Maximum number of fluids in the simulation + integer, parameter :: num_probes_max = 10 !< Maximum number of flow probes in the simulation + integer, parameter :: num_patches_max = 1000 + integer, parameter :: num_bc_patches_max = 10 + integer, parameter :: max_2d_fourier_modes = 10 !< Max Fourier mode index for 2D modal patch (geometry 13) + integer, parameter :: max_sph_harm_degree = 5 !< Max degree L for 3D spherical harmonic patch (geometry 14) + integer, parameter :: pathlen_max = 400 + integer, parameter :: nnode = 4 !< Number of QBMM nodes + integer, parameter :: dflt_num_igr_iters = 2 !< number of iterations for IGR elliptic solve + integer, parameter :: dflt_num_igr_warm_start_iters = 50 !< default number of iterations for IGR elliptic solve + real(wp), parameter :: dflt_alf_factor = 10._wp !< scaling factor for IGR alpha + integer, parameter :: gp_layers = 3 !< Number of ghost point layers for IBM + !> color function gradient magnitude at which to apply the surface tension fluxes + real(wp), parameter :: capillary_cutoff = 1.e-6 + !> Spatial support width of acoustic source, used in s_source_spatial + real(wp), parameter :: acoustic_spatial_support_width = 2.5_wp + real(wp), parameter :: dflt_vcfl_dt = 100._wp !< value of vcfl_dt when viscosity is off for computing adaptive timestep size + !> The constant to scale the spectral level at the lower frequency bound + real(wp), parameter :: broadband_spectral_level_constant = 20._wp + !> The spectral level constant to correct the magnitude at each frequency to ensure the source is overall broadband + real(wp), parameter :: broadband_spectral_level_growth_rate = 10._wp ! Reconstruction Types - integer, parameter :: WENO_TYPE = 1 !< Using WENO for reconstruction type - integer, parameter :: MUSCL_TYPE = 2 !< Using MUSCL for reconstruction type + integer, parameter :: WENO_TYPE = 1 !< Using WENO for reconstruction type + integer, parameter :: MUSCL_TYPE = 2 !< Using MUSCL for reconstruction type ! Interface Compression - real(wp), parameter :: dflt_ic_eps = 1e-4_wp !< Ensure compression is only applied to surface cells in THINC - real(wp), parameter :: dflt_ic_beta = 1.6_wp !< Sharpness parameter's default value used in THINC - real(wp), parameter :: moncon_cutoff = 1e-8_wp !< Monotonicity constraint's limiter to prevent extremas in THINC + real(wp), parameter :: dflt_ic_eps = 1e-4_wp !< Ensure compression is only applied to surface cells in THINC + real(wp), parameter :: dflt_ic_beta = 1.6_wp !< Sharpness parameter's default value used in THINC + real(wp), parameter :: moncon_cutoff = 1e-8_wp !< Monotonicity constraint's limiter to prevent extremas in THINC ! Chemistry - real(wp), parameter :: dflt_T_guess = 1200._wp ! Default guess for temperature (when a previous value is not available) + real(wp), parameter :: dflt_T_guess = 1200._wp ! Default guess for temperature (when a previous value is not available) ! IBM+STL interpolation constants - integer, parameter :: num_ray = 20 !< Default number of rays traced per cell - real(wp), parameter :: ray_tracing_threshold = 0.9_wp !< Threshold above which the cell is marked as the model patch - real(wp), parameter :: threshold_vector_zero = 1.e-10_wp !< Threshold to treat the component of a vector to be zero - real(wp), parameter :: threshold_edge_zero = 1.e-10_wp !< Threshold to treat two edges to be overlapped - real(wp), parameter :: initial_distance_buffer = 1.e12_wp !< Initialized levelset distance for the shortest path pair algorithm + integer, parameter :: num_ray = 20 !< Default number of rays traced per cell + real(wp), parameter :: ray_tracing_threshold = 0.9_wp !< Threshold above which the cell is marked as the model patch + real(wp), parameter :: threshold_vector_zero = 1.e-10_wp !< Threshold to treat the component of a vector to be zero + real(wp), parameter :: threshold_edge_zero = 1.e-10_wp !< Threshold to treat two edges to be overlapped + real(wp), parameter :: initial_distance_buffer = 1.e12_wp !< Initialized levelset distance for the shortest path pair algorithm ! Lagrange bubbles constants - integer, parameter :: mapCells = 3 !< Number of cells around the bubble where the smoothening function will have effect - integer, parameter :: beta_vars(1:3) = [1, 2, 5] !< q_beta indices to communicate: 1=void fraction, 2=d(beta)/dt, 5=energy source - real(wp), parameter :: R_uni = 8314._wp !< Universal gas constant - J/kmol/K - integer, parameter :: lag_io_vars = 21 !< Number of variables per particle for MPI_IO + integer, parameter :: mapCells = 3 !< Number of cells around the bubble where the smoothening function will have effect + !> q_beta indices to communicate: 1=void fraction, 2=d(beta)/dt, 5=energy source + integer, parameter :: beta_vars(1:3) = [1, 2, 5] + real(wp), parameter :: R_uni = 8314._wp !< Universal gas constant - J/kmol/K + integer, parameter :: lag_io_vars = 21 !< Number of variables per particle for MPI_IO ! Strang Splitting constants - real(wp), parameter :: dflt_adap_dt_tol = 1.e-4_wp !< Default tolerance for adaptive step size - integer, parameter :: dflt_adap_dt_max_iters = 100 !< Default max iteration for adaptive step size + real(wp), parameter :: dflt_adap_dt_tol = 1.e-4_wp !< Default tolerance for adaptive step size + integer, parameter :: dflt_adap_dt_max_iters = 100 !< Default max iteration for adaptive step size - ! Constants of the algorithm described by Heirer, E. Hairer, S. P.Nørsett, G. Wanner, Solving Ordinary Differential Equations I, Chapter II.4 - ! to choose the initial time step size for the adaptive time stepping routine + ! Constants of the algorithm described by Heirer, E. Hairer, S. P.Norsett, G. Wanner, Solving Ordinary Differential Equations I, + ! Chapter II.4 to choose the initial time step size for the adaptive time stepping routine real(wp), parameter :: threshold_first_guess = 1.e-5_wp real(wp), parameter :: threshold_second_guess = 1.e-15_wp real(wp), parameter :: scale_first_guess = 1.e-3_wp @@ -81,23 +85,17 @@ module m_constants integer, parameter :: relativity_cons_to_prim_max_iter = 100 ! Pseudo-random number generator - integer, parameter :: modulus = 2**30 - 1 - integer, parameter :: multiplier = 1664525 - integer, parameter :: increment = 1013904223 - integer, parameter :: amplifier = 3**13 + integer, parameter :: modulus = 2**30 - 1 + integer, parameter :: multiplier = 1664525 + integer, parameter :: increment = 1013904223 + integer, parameter :: amplifier = 3**13 real(wp), parameter :: decimal_trim = 1.e5_wp ! System constants integer, parameter :: CASE_FILE_ERROR_CODE = 22 - ! Boundary condition enumeration - ! Abbreviations - ! CHAR - Characteristic - ! NR - Non-reflecting - ! SUB - subsonic - ! SUP - supersonic - ! FF - Force-free - ! CP - Constant pressure + ! Boundary condition enumeration Abbreviations CHAR - Characteristic NR - Non-reflecting SUB - subsonic SUP - supersonic FF - + ! Force-free CP - Constant pressure integer, parameter :: BC_PERIODIC = -1 integer, parameter :: BC_REFLECTIVE = -2 integer, parameter :: BC_GHOST_EXTRAP = -3 @@ -115,5 +113,4 @@ module m_constants integer, parameter :: BC_SLIP_WALL = -15 integer, parameter :: BC_NO_SLIP_WALL = -16 integer, parameter :: BC_DIRICHLET = -17 - end module m_constants diff --git a/src/common/m_delay_file_access.f90 b/src/common/m_delay_file_access.f90 index 096bbbb6af..95e310a01f 100644 --- a/src/common/m_delay_file_access.f90 +++ b/src/common/m_delay_file_access.f90 @@ -4,27 +4,27 @@ !> @brief Rank-staggered file access delays to prevent I/O contention on parallel file systems module m_delay_file_access + use m_precision_select + implicit none + private public :: DelayFileAccess - integer, private, parameter :: & - N_PROCESSES_FILE_ACCESS = 128, & - FILE_ACCESS_DELAY_UNIT = 10000 + integer, private, parameter :: N_PROCESSES_FILE_ACCESS = 128, FILE_ACCESS_DELAY_UNIT = 10000 contains !> @brief Introduces a rank-dependent busy-wait delay to stagger parallel file access and reduce I/O contention. impure subroutine DelayFileAccess(ProcessRank) - integer, intent(in) :: ProcessRank - integer :: iDelay, nFileAccessDelayIterations - real(wp) :: Number, Dummy + integer, intent(in) :: ProcessRank + integer :: iDelay, nFileAccessDelayIterations + real(wp) :: Number, Dummy - nFileAccessDelayIterations & - = (ProcessRank/N_PROCESSES_FILE_ACCESS)*FILE_ACCESS_DELAY_UNIT + nFileAccessDelayIterations = (ProcessRank/N_PROCESSES_FILE_ACCESS)*FILE_ACCESS_DELAY_UNIT do iDelay = 1, nFileAccessDelayIterations ! Wait my turn diff --git a/src/common/m_derived_types.fpp b/src/common/m_derived_types.fpp index f4049a75af..3c7cc2fcf9 100644 --- a/src/common/m_derived_types.fpp +++ b/src/common/m_derived_types.fpp @@ -8,7 +8,6 @@ module m_derived_types use m_constants !< Constants - use m_precision_select use m_thermochem, only: num_species @@ -16,66 +15,66 @@ module m_derived_types !> Derived type adding the field position (fp) as an attribute type field_position - real(stp), allocatable, dimension(:, :, :) :: fp !< Field position + real(stp), allocatable, dimension(:,:,:) :: fp !< Field position end type field_position !> Derived type annexing a scalar field (SF) type scalar_field - real(stp), pointer, dimension(:, :, :) :: sf => null() + real(stp), pointer, dimension(:,:,:) :: sf => null() end type scalar_field !> Derived type for bubble variables pb and mv at quadrature nodes (qbmm) type pres_field - real(stp), pointer, dimension(:, :, :, :, :) :: sf => null() + real(stp), pointer, dimension(:,:,:,:,:) :: sf => null() end type pres_field !> Derived type annexing an integer scalar field (SF) type integer_field #ifdef MFC_MIXED_PRECISION - integer(kind=1), pointer, dimension(:, :, :) :: sf => null() + integer(kind=1), pointer, dimension(:,:,:) :: sf => null() #else - integer, pointer, dimension(:, :, :) :: sf => null() + integer, pointer, dimension(:,:,:) :: sf => null() #endif end type integer_field !> Derived type for levelset type levelset_field - real(stp), pointer, dimension(:, :, :, :) :: sf => null() + real(stp), pointer, dimension(:,:,:,:) :: sf => null() end type levelset_field !> Derived type for levelset norm type levelset_norm_field - real(stp), pointer, dimension(:, :, :, :, :) :: sf => null() + real(stp), pointer, dimension(:,:,:,:,:) :: sf => null() end type levelset_norm_field type mpi_io_var - integer, allocatable, dimension(:) :: view + integer, allocatable, dimension(:) :: view type(scalar_field), allocatable, dimension(:) :: var end type mpi_io_var type mpi_io_ib_var - integer :: view + integer :: view type(integer_field) :: var end type mpi_io_ib_var type mpi_io_levelset_var - integer :: view + integer :: view type(levelset_field) :: var end type mpi_io_levelset_var type mpi_io_levelset_norm_var - integer :: view + integer :: view type(levelset_norm_field) :: var end type mpi_io_levelset_norm_var !> Derived type annexing a vector field (VF) type vector_field - type(scalar_field), allocatable, dimension(:) :: vf !< Vector field + type(scalar_field), allocatable, dimension(:) :: vf !< Vector field end type vector_field - !> Generic 3-component vector (e.g., spatial coordinates or field components) - !! Named _dt (derived types: x,y,z) to differentiate from t_vec3 (3-component vector) - type vec3_dt ! dt for derived types + !> Generic 3-component vector (e.g., spatial coordinates or field components) Named _dt (derived types: x,y,z) to differentiate + !! from t_vec3 (3-component vector) + type vec3_dt ! dt for derived types real(wp) :: x real(wp) :: y real(wp) :: z @@ -95,30 +94,28 @@ module m_derived_types !> Integer bounds for variables type int_bounds_info - integer :: beg - integer :: end - - real(wp) :: vb1 - real(wp) :: vb2 - real(wp) :: vb3 - real(wp) :: ve1 - real(wp) :: ve2 - real(wp) :: ve3 - real(wp) :: pres_in, pres_out - real(wp), dimension(3) :: vel_in, vel_out + integer :: beg + integer :: end + real(wp) :: vb1 + real(wp) :: vb2 + real(wp) :: vb3 + real(wp) :: ve1 + real(wp) :: ve2 + real(wp) :: ve3 + real(wp) :: pres_in, pres_out + real(wp), dimension(3) :: vel_in, vel_out real(wp), dimension(num_fluids_max) :: alpha_rho_in, alpha_in - logical :: grcbc_in, grcbc_out, grcbc_vel_out - + logical :: grcbc_in, grcbc_out, grcbc_vel_out end type int_bounds_info type bc_patch_parameters - integer :: geometry - integer :: type - integer :: dir - integer :: loc + integer :: geometry + integer :: type + integer :: dir + integer :: loc real(wp), dimension(3) :: centroid real(wp), dimension(3) :: length - real(wp) :: radius + real(wp) :: radius end type bc_patch_parameters !> Derived type adding beginning (beg) and end bounds info as attributes @@ -129,356 +126,287 @@ module m_derived_types !> bounds for the bubble dynamic variables type bub_bounds_info - integer :: beg - integer :: end - integer, dimension(:), allocatable :: rs - integer, dimension(:), allocatable :: vs - integer, dimension(:), allocatable :: ps - integer, dimension(:), allocatable :: ms - integer, dimension(:, :), allocatable :: moms !< Moment indices for qbmm - integer, dimension(:, :, :), allocatable :: fullmom !< Moment indices for qbmm + integer :: beg + integer :: end + integer, dimension(:), allocatable :: rs + integer, dimension(:), allocatable :: vs + integer, dimension(:), allocatable :: ps + integer, dimension(:), allocatable :: ms + integer, dimension(:,:), allocatable :: moms !< Moment indices for qbmm + integer, dimension(:,:,:), allocatable :: fullmom !< Moment indices for qbmm end type bub_bounds_info !> Defines parameters for a Model Patch type ic_model_parameters - character(LEN=pathlen_max) :: filepath !< - !! Path the STL file relative to case_dir. - - real(wp), dimension(1:3) :: translate !< - !! Translation of the STL object. - - real(wp), dimension(1:3) :: scale !< - !! Scale factor for the STL object. - - real(wp), dimension(1:3) :: rotate !< - !! Angle to rotate the STL object along each cartesian coordinate axis, - !! in radians. - - integer :: spc !< - !! Number of samples per cell to use when discretizing the STL object. - - real(wp) :: threshold !< - !! Threshold to turn on smoothen STL patch. + character(LEN=pathlen_max) :: filepath !< Path the STL file relative to case_dir. + real(wp), dimension(1:3) :: translate !< Translation of the STL object. + real(wp), dimension(1:3) :: scale !< Scale factor for the STL object. + real(wp), dimension(1:3) :: rotate !< Angle to rotate the STL object along each cartesian coordinate axis, in radians. + integer :: spc !< Number of samples per cell to use when discretizing the STL object. + real(wp) :: threshold !< Threshold to turn on smoothen STL patch. end type ic_model_parameters type :: t_triangle - real(wp), dimension(1:3, 1:3) :: v ! Vertices of the triangle - real(wp), dimension(1:3) :: n ! Normal vector + real(wp), dimension(1:3,1:3) :: v ! Vertices of the triangle + real(wp), dimension(1:3) :: n ! Normal vector end type t_triangle type :: t_ray - real(wp), dimension(1:3) :: o ! Origin - real(wp), dimension(1:3) :: d ! Direction + real(wp), dimension(1:3) :: o ! Origin + real(wp), dimension(1:3) :: d ! Direction end type t_ray type :: t_bbox - real(wp), dimension(1:3) :: min ! Minimum coordinates - real(wp), dimension(1:3) :: max ! Maximum coordinates + real(wp), dimension(1:3) :: min ! Minimum coordinates + real(wp), dimension(1:3) :: max ! Maximum coordinates end type t_bbox type :: t_model - integer :: ntrs ! Number of triangles - type(t_triangle), allocatable :: trs(:) ! Triangles - + integer :: ntrs ! Number of triangles + type(t_triangle), allocatable :: trs(:) ! Triangles end type t_model type :: t_model_array ! Original CPU-side fields (unchanged) - type(t_model), allocatable :: model - real(wp), allocatable, dimension(:, :, :) :: boundary_v - real(wp), allocatable, dimension(:, :) :: interpolated_boundary_v - integer :: boundary_edge_count - integer :: total_vertices - integer :: interpolate + type(t_model), allocatable :: model + real(wp), allocatable, dimension(:,:,:) :: boundary_v + real(wp), allocatable, dimension(:,:) :: interpolated_boundary_v + integer :: boundary_edge_count + integer :: total_vertices + integer :: interpolate ! GPU-friendly flattened arrays - integer :: ntrs ! copy of model%ntrs - real(wp), allocatable, dimension(:, :, :) :: trs_v ! (3, 3, ntrs) - triangle vertices - real(wp), allocatable, dimension(:, :) :: trs_n ! (3, ntrs) - triangle normals + integer :: ntrs ! copy of model%ntrs + real(wp), allocatable, dimension(:,:,:) :: trs_v ! (3, 3, ntrs) - triangle vertices + real(wp), allocatable, dimension(:,:) :: trs_n ! (3, ntrs) - triangle normals end type t_model_array - !> Derived type adding initial condition (ic) patch parameters as attributes - !! NOTE: The requirements for the specification of the above parameters - !! are strongly dependent on both the choice of the multicomponent flow - !! model as well as the choice of the patch geometry. + !> Derived type adding initial condition (ic) patch parameters as attributes NOTE: The requirements for the specification of the + !! above parameters are strongly dependent on both the choice of the multicomponent flow model as well as the choice of the + !! patch geometry. type ic_patch_parameters - integer :: geometry !< Type of geometry for the patch - - real(wp) :: x_centroid, y_centroid, z_centroid !< - !! Location of the geometric center, i.e. the centroid, of the patch. It - !! is specified through its x-, y- and z-coordinates, respectively. + integer :: geometry !< Type of geometry for the patch - real(wp) :: length_x, length_y, length_z !< Dimensions of the patch. x,y,z Lengths. - real(wp) :: radius !< Dimensions of the patch. radius. - - real(wp), dimension(3) :: radii !< - !! Vector indicating the various radii for the elliptical and ellipsoidal - !! patch geometries. It is specified through its x-, y-, and z-components + !> Location of the geometric center, i.e. the centroid, of the patch. It is specified through its x-, y- and z-coordinates, !! respectively. - - real(wp) :: epsilon, beta !< - !! The isentropic vortex parameters for the amplitude of the disturbance and - !! domain of influence. - - real(wp), dimension(2:9) :: a !< - !! Used by hardcoded IC and as temporary variables. - + real(wp) :: x_centroid, y_centroid, z_centroid + real(wp) :: length_x, length_y, length_z !< Dimensions of the patch. x,y,z Lengths. + real(wp) :: radius !< Dimensions of the patch. radius. + + !> Vector indicating the various radii for the elliptical and ellipsoidal patch geometries. It is specified through its x-, + !! y-, and z-components respectively. + real(wp), dimension(3) :: radii + real(wp) :: epsilon, beta !< The isentropic vortex parameters for the amplitude of the disturbance and domain of influence. + real(wp), dimension(2:9) :: a !< Used by hardcoded IC and as temporary variables. logical :: non_axis_sym ! Geometry 13 (2D modal Fourier): fourier_cos(n), fourier_sin(n) for mode n real(wp), dimension(1:max_2d_fourier_modes) :: fourier_cos, fourier_sin - logical :: modal_clip_r_to_min !< When true, clip boundary radius: R(theta) = max(R(theta), modal_r_min) (Non-exp form only) - real(wp) :: modal_r_min !< Minimum boundary radius when modal_clip_r_to_min is true (Non-exp form only) + logical :: modal_clip_r_to_min !< When true, clip boundary radius: R(theta) = max(R(theta), modal_r_min) (Non-exp form only) + real(wp) :: modal_r_min !< Minimum boundary radius when modal_clip_r_to_min is true (Non-exp form only) logical :: modal_use_exp_form !< When true, boundary = radius*exp(Fourier series) ! Geometry 14 (3D spherical harmonic): sph_har_coeff(l,m) for real Y_lm - real(wp), dimension(0:max_sph_harm_degree, -max_sph_harm_degree:max_sph_harm_degree) :: sph_har_coeff - - real(wp), dimension(3) :: normal !< - !! Normal vector indicating the orientation of the patch. It is specified - !! through its x-, y- and z-components, respectively. - - logical, dimension(0:num_patches_max - 1) :: alter_patch !< + real(wp), dimension(0:max_sph_harm_degree,-max_sph_harm_degree:max_sph_harm_degree) :: sph_har_coeff - !! List of permissions that indicate to the current patch which preceding - !! patches it is allowed to overwrite when it is in process of being laid - !! out in the domain + !> Normal vector indicating the orientation of the patch. It is specified through its x-, y- and z-components, respectively. + real(wp), dimension(3) :: normal - logical :: smoothen !< - !! Permission indicating to the current patch whether its boundaries will - !! be smoothed out across a few cells or whether they are to remain sharp + !> List of permissions that indicate to the current patch which preceding patches it is allowed to overwrite when it is in + !! process of being laid out in the domain + logical, dimension(0:num_patches_max - 1) :: alter_patch - integer :: smooth_patch_id !< - !! Identity (id) of the patch with which current patch is to get smoothed - - real(wp) :: smooth_coeff !< - !! Smoothing coefficient (coeff) for the size of the stencil of - !! cells across which boundaries of the current patch will be smeared out + !> Permission indicating to the current patch whether its boundaries will be smoothed out across a few cells or whether they + !! are to remain sharp + logical :: smoothen + integer :: smooth_patch_id !< Identity (id) of the patch with which current patch is to get smoothed + !> Smoothing coefficient (coeff) for the size of the stencil of cells across which boundaries of the current patch will be + !! smeared out + real(wp) :: smooth_coeff real(wp), dimension(num_fluids_max) :: alpha_rho - real(wp) :: rho - real(wp), dimension(3) :: vel - real(wp) :: pres + real(wp) :: rho + real(wp), dimension(3) :: vel + real(wp) :: pres real(wp), dimension(num_fluids_max) :: alpha - real(wp) :: gamma - real(wp) :: pi_inf !< - real(wp) :: cv !< - real(wp) :: qv !< - real(wp) :: qvp !< - - !! Primitive variables associated with the patch. In order, these include - !! the partial densities, density, velocity, pressure, volume fractions, - !! specific heat ratio function and the liquid stiffness function. - - real(wp) :: Bx, By, Bz !< - !! Magnetic field components; B%x is not used for 1D - - real(wp), dimension(6) :: tau_e !< - !! Elastic stresses added to primitive variables if hypoelasticity = True - - real(wp) :: R0 !< Bubble size - real(wp) :: V0 !< Bubble velocity - - real(wp) :: p0 !< Bubble size - real(wp) :: m0 !< Bubble velocity - - integer :: hcid + real(wp) :: gamma + real(wp) :: pi_inf + real(wp) :: cv + real(wp) :: qv + !> Primitive variables associated with the patch. In order, these include the partial densities, density, velocity, + !! pressure, volume fractions, specific heat ratio function and the liquid stiffness function. + real(wp) :: qvp + real(wp) :: Bx, By, Bz !< Magnetic field components; B%x is not used for 1D + real(wp), dimension(6) :: tau_e !< Elastic stresses added to primitive variables if hypoelasticity = True + real(wp) :: R0 !< Bubble size + real(wp) :: V0 !< Bubble velocity + real(wp) :: p0 !< Bubble size + real(wp) :: m0 !< Bubble velocity + integer :: hcid !! id for hard coded initial condition real(wp) :: cf_val !! color function value real(wp) :: Y(1:num_species) !! STL or OBJ model input parameter - character(LEN=pathlen_max) :: model_filepath !< - !! Path the STL file relative to case_dir. - - real(wp), dimension(1:3) :: model_translate !< - !! Translation of the STL object. - - real(wp), dimension(1:3) :: model_scale !< - !! Scale factor for the STL object. - - real(wp), dimension(1:3) :: model_rotate !< - !! Angle to rotate the STL object along each cartesian coordinate axis, - !! in radians. - - integer :: model_spc !< - !! Number of samples per cell to use when discretizing the STL object. - - real(wp) :: model_threshold !< - !! Threshold to turn on smoothen STL patch. - + character(LEN=pathlen_max) :: model_filepath !< Path the STL file relative to case_dir. + real(wp), dimension(1:3) :: model_translate !< Translation of the STL object. + real(wp), dimension(1:3) :: model_scale !< Scale factor for the STL object. + real(wp), dimension(1:3) :: model_rotate !< Angle to rotate the STL object along each cartesian coordinate axis, in radians. + integer :: model_spc !< Number of samples per cell to use when discretizing the STL object. + real(wp) :: model_threshold !< Threshold to turn on smoothen STL patch. end type ic_patch_parameters type ib_patch_parameters - integer :: geometry !< Type of geometry for the patch - - real(wp) :: x_centroid, y_centroid, z_centroid !< - !! Location of the geometric center, i.e. the centroid, of the patch. It - !! is specified through its x-, y- and z-coordinates, respectively. - real(wp) :: step_x_centroid, step_y_centroid, step_z_centroid !< - !! Centroid locations of intermediate steps in the time_stepper module - real(wp), dimension(1:3) :: centroid_offset ! offset of center of mass from computed cell center for odd-shaped IBs + integer :: geometry !< Type of geometry for the patch - real(wp), dimension(1:3) :: angles - real(wp), dimension(1:3) :: step_angles - real(wp), dimension(1:3, 1:3) :: rotation_matrix !< matrix that converts from IB reference frame to fluid reference frame - real(wp), dimension(1:3, 1:3) :: rotation_matrix_inverse !< matrix that converts from fluid reference frame to IB reference frame - - real(wp) :: c, p, t, m - - real(wp) :: length_x, length_y, length_z !< Dimensions of the patch. x,y,z Lengths. - real(wp) :: radius !< Dimensions of the patch. radius. - real(wp) :: theta - - logical :: slip + !> Location of the geometric center, i.e. the centroid, of the patch. It is specified through its x-, y- and z-coordinates, + !! respectively. + real(wp) :: x_centroid, y_centroid, z_centroid + !> Centroid locations of intermediate steps in the time_stepper module + real(wp) :: step_x_centroid, step_y_centroid, step_z_centroid + real(wp), dimension(1:3) :: centroid_offset ! offset of center of mass from computed cell center for odd-shaped IBs + real(wp), dimension(1:3) :: angles + real(wp), dimension(1:3) :: step_angles + real(wp), dimension(1:3,1:3) :: rotation_matrix !< matrix that converts from IB reference frame to fluid reference frame + !> matrix that converts from fluid reference frame to IB reference frame + real(wp), dimension(1:3,1:3) :: rotation_matrix_inverse + real(wp) :: c, p, t, m + real(wp) :: length_x, length_y, length_z !< Dimensions of the patch. x,y,z Lengths. + real(wp) :: radius !< Dimensions of the patch. radius. + real(wp) :: theta + logical :: slip !! STL or OBJ model input parameter - character(LEN=pathlen_max) :: model_filepath !< - !! Path the STL file relative to case_dir. - - real(wp), dimension(1:3) :: model_translate !< - !! Translation of the STL object. - - real(wp), dimension(1:3) :: model_scale !< - !! Scale factor for the STL object. - - real(wp), dimension(1:3) :: model_rotate !< - !! Angle to rotate the STL object along each cartesian coordinate axis, - !! in radians. - - integer :: model_spc !< - !! Number of samples per cell to use when discretizing the STL object. - - real(wp) :: model_threshold !< - !! Threshold to turn on smoothen STL patch. - - !! Patch conditions for moving imersed boundaries - integer :: moving_ibm ! 0 for no moving, 1 for moving, 2 for moving on forced path - real(wp) :: mass, moment ! mass and moment of inertia of object used to compute forces in 2-way coupling - real(wp), dimension(1:3) :: force, torque ! vectors for the computed force and torque values applied to an IB + character(LEN=pathlen_max) :: model_filepath !< Path the STL file relative to case_dir. + real(wp), dimension(1:3) :: model_translate !< Translation of the STL object. + real(wp), dimension(1:3) :: model_scale !< Scale factor for the STL object. + real(wp), dimension(1:3) :: model_rotate !< Angle to rotate the STL object along each cartesian coordinate axis, in radians. + integer :: model_spc !< Number of samples per cell to use when discretizing the STL object. + real(wp) :: model_threshold !< Threshold to turn on smoothen STL patch. Patch conditions for moving imersed boundaries + integer :: moving_ibm ! 0 for no moving, 1 for moving, 2 for moving on forced path + real(wp) :: mass, moment ! mass and moment of inertia of object used to compute forces in 2-way coupling + real(wp), dimension(1:3) :: force, torque ! vectors for the computed force and torque values applied to an IB real(wp), dimension(1:3) :: vel - real(wp), dimension(1:3) :: step_vel ! velocity array used to store intermediate steps in the time_stepper module + real(wp), dimension(1:3) :: step_vel ! velocity array used to store intermediate steps in the time_stepper module real(wp), dimension(1:3) :: angular_vel - real(wp), dimension(1:3) :: step_angular_vel ! velocity array used to store intermediate steps in the time_stepper module - + real(wp), dimension(1:3) :: step_angular_vel ! velocity array used to store intermediate steps in the time_stepper module end type ib_patch_parameters - !> Derived type annexing the physical parameters (PP) of the fluids. These - !! include the specific heat ratio function and liquid stiffness function. + !> Derived type annexing the physical parameters (PP) of the fluids. These include the specific heat ratio function and liquid + !! stiffness function. type physical_parameters - real(wp) :: gamma !< Sp. heat ratio - real(wp) :: pi_inf !< Liquid stiffness - real(wp), dimension(2) :: Re !< Reynolds number - real(wp) :: cv !< heat capacity - real(wp) :: qv !< reference energy per unit mass for SGEOS, q (see Le Metayer (2004)) - real(wp) :: qvp !< reference entropy per unit mass for SGEOS, q' (see Le Metayer (2004)) - real(wp) :: G + real(wp) :: gamma !< Sp. heat ratio + real(wp) :: pi_inf !< Liquid stiffness + real(wp), dimension(2) :: Re !< Reynolds number + real(wp) :: cv !< heat capacity + real(wp) :: qv !< reference energy per unit mass for SGEOS, q (see Le Metayer (2004)) + real(wp) :: qvp !< reference entropy per unit mass for SGEOS, q' (see Le Metayer (2004)) + real(wp) :: G end type physical_parameters !> Derived type annexing the physical parameters required for sub-grid bubble models type subgrid_bubble_physical_parameters - real(wp) :: R0ref !< reference bubble radius - real(wp) :: p0ref !< reference pressure - real(wp) :: rho0ref !< reference density - real(wp) :: T0ref !< reference temperature - real(wp) :: ss !< surface tension between host and gas (bubble) - real(wp) :: pv !< vapor pressure of host - real(wp) :: vd !< vapor diffusivity in gas (bubble) - real(wp) :: mu_l !< viscosity of host in liquid state - real(wp) :: mu_v !< viscosity of host in vapor state - real(wp) :: mu_g !< viscosity of gas (bubble) - real(wp) :: gam_v !< specific heat ratio of host in vapor state - real(wp) :: gam_g !< specific heat ratio of gas (bubble) - real(wp) :: M_v !< Molecular weight of host - real(wp) :: M_g !< Molecular weight of gas (bubble) - real(wp) :: k_v !< thermal conductivity of host in vapor state - real(wp) :: k_g !< thermal conductivity of gas (bubble) - real(wp) :: cp_v !< specific heat capacity in constant pressure of host in vapor state - real(wp) :: cp_g !< specific heat capacity in constant pressure of gas (bubble) - real(wp) :: R_v !< gas constant of host in vapor state - real(wp) :: R_g !< gas constant of gas (bubble) + real(wp) :: R0ref !< reference bubble radius + real(wp) :: p0ref !< reference pressure + real(wp) :: rho0ref !< reference density + real(wp) :: T0ref !< reference temperature + real(wp) :: ss !< surface tension between host and gas (bubble) + real(wp) :: pv !< vapor pressure of host + real(wp) :: vd !< vapor diffusivity in gas (bubble) + real(wp) :: mu_l !< viscosity of host in liquid state + real(wp) :: mu_v !< viscosity of host in vapor state + real(wp) :: mu_g !< viscosity of gas (bubble) + real(wp) :: gam_v !< specific heat ratio of host in vapor state + real(wp) :: gam_g !< specific heat ratio of gas (bubble) + real(wp) :: M_v !< Molecular weight of host + real(wp) :: M_g !< Molecular weight of gas (bubble) + real(wp) :: k_v !< thermal conductivity of host in vapor state + real(wp) :: k_g !< thermal conductivity of gas (bubble) + real(wp) :: cp_v !< specific heat capacity in constant pressure of host in vapor state + real(wp) :: cp_g !< specific heat capacity in constant pressure of gas (bubble) + real(wp) :: R_v !< gas constant of host in vapor state + real(wp) :: R_g !< gas constant of gas (bubble) end type subgrid_bubble_physical_parameters type mpi_io_airfoil_ib_var - integer, dimension(2) :: view + integer, dimension(2) :: view type(vec3_dt), allocatable, dimension(:) :: var end type mpi_io_airfoil_ib_var !> Derived type annexing integral regions type integral_parameters - real(wp) :: xmin !< Min. boundary first coordinate direction - real(wp) :: xmax !< Max. boundary first coordinate direction - real(wp) :: ymin !< Min. boundary second coordinate direction - real(wp) :: ymax !< Max. boundary second coordinate direction - real(wp) :: zmin !< Min. boundary third coordinate direction - real(wp) :: zmax !< Max. boundary third coordinate direction + real(wp) :: xmin !< Min. boundary first coordinate direction + real(wp) :: xmax !< Max. boundary first coordinate direction + real(wp) :: ymin !< Min. boundary second coordinate direction + real(wp) :: ymax !< Max. boundary second coordinate direction + real(wp) :: zmin !< Min. boundary third coordinate direction + real(wp) :: zmax !< Max. boundary third coordinate direction end type integral_parameters !> Acoustic source parameters type acoustic_parameters - integer :: pulse !< Type of pulse - integer :: support !< Type of support - logical :: dipole !< Whether the source is a dipole or monopole - real(wp), dimension(3) :: loc !< Physical location of acoustic source - real(wp) :: mag !< Acoustic pulse magnitude - real(wp) :: length !< Length of planar source (2D/3D) - real(wp) :: height !< Height of planar source (3D) - real(wp) :: wavelength !< Wave length of pulse - real(wp) :: frequency !< Frequency of pulse - real(wp) :: gauss_sigma_dist !< sigma of Gaussian pulse multiplied by speed of sound - real(wp) :: gauss_sigma_time !< sigma of Gaussian pulse - real(wp) :: npulse !< Number of cycles of pulse - real(wp) :: dir !< Direction of pulse - real(wp) :: delay !< Time-delay of pulse start - real(wp) :: foc_length ! < Focal length of transducer - real(wp) :: aperture ! < Aperture diameter of transducer - real(wp) :: element_spacing_angle !< Spacing between aperture elements in 2D acoustic array - real(wp) :: element_polygon_ratio !< Ratio of aperture element diameter to side length of polygon connecting their centers, in 3D acoustic array - real(wp) :: rotate_angle !< Angle of rotation of the entire circular 3D acoustic array - real(wp) :: bb_bandwidth !< Bandwidth of each frequency in broadband wave - real(wp) :: bb_lowest_freq !< The lower frequency bound of broadband wave - integer :: num_elements !< Number of elements in the acoustic array - integer :: element_on !< Element in the acoustic array to turn on - integer :: bb_num_freq !< Number of frequencies in the broadband wave + integer :: pulse !< Type of pulse + integer :: support !< Type of support + logical :: dipole !< Whether the source is a dipole or monopole + real(wp), dimension(3) :: loc !< Physical location of acoustic source + real(wp) :: mag !< Acoustic pulse magnitude + real(wp) :: length !< Length of planar source (2D/3D) + real(wp) :: height !< Height of planar source (3D) + real(wp) :: wavelength !< Wave length of pulse + real(wp) :: frequency !< Frequency of pulse + real(wp) :: gauss_sigma_dist !< sigma of Gaussian pulse multiplied by speed of sound + real(wp) :: gauss_sigma_time !< sigma of Gaussian pulse + real(wp) :: npulse !< Number of cycles of pulse + real(wp) :: dir !< Direction of pulse + real(wp) :: delay !< Time-delay of pulse start + real(wp) :: foc_length ! < Focal length of transducer + real(wp) :: aperture ! < Aperture diameter of transducer + real(wp) :: element_spacing_angle !< Spacing between aperture elements in 2D acoustic array + !> Ratio of aperture element diameter to side length of polygon connecting their centers, in 3D acoustic array + real(wp) :: element_polygon_ratio + real(wp) :: rotate_angle !< Angle of rotation of the entire circular 3D acoustic array + real(wp) :: bb_bandwidth !< Bandwidth of each frequency in broadband wave + real(wp) :: bb_lowest_freq !< The lower frequency bound of broadband wave + integer :: num_elements !< Number of elements in the acoustic array + integer :: element_on !< Element in the acoustic array to turn on + integer :: bb_num_freq !< Number of frequencies in the broadband wave end type acoustic_parameters !> Acoustic source source_spatial pre-calculated values type source_spatial_type - integer, pointer, dimension(:, :) :: coord => null() !< List of grid points indices with non-zero source_spatial values - real(wp), pointer, dimension(:) :: val => null() !< List of non-zero source_spatial values - real(wp), pointer, dimension(:) :: angle => null() !< List of angles with x-axis for mom source term vector - real(wp), pointer, dimension(:, :) :: xyz_to_r_ratios => null() !< List of [xyz]/r for mom source term vector - + integer, pointer, dimension(:,:) :: coord => null() !< List of grid points indices with non-zero source_spatial values + real(wp), pointer, dimension(:) :: val => null() !< List of non-zero source_spatial values + real(wp), pointer, dimension(:) :: angle => null() !< List of angles with x-axis for mom source term vector + real(wp), pointer, dimension(:,:) :: xyz_to_r_ratios => null() !< List of [xyz]/r for mom source term vector end type source_spatial_type !> Ghost Point for Immersed Boundaries type ghost_point - integer, dimension(3) :: loc !< Physical location of the ghost point - real(wp), dimension(3) :: ip_loc !< Physical location of the image point - integer, dimension(3) :: ip_grid !< Top left grid point of IP - real(wp), dimension(2, 2, 2) :: interp_coeffs !< Interpolation Coefficients of image point - integer :: ib_patch_id !< ID of the IB Patch the ghost point is part of - real(wp) :: levelset - real(wp), dimension(1:3) :: levelset_norm - logical :: slip - integer, dimension(3) :: DB - integer :: x_periodicity, y_periodicity, z_periodicity + integer, dimension(3) :: loc !< Physical location of the ghost point + real(wp), dimension(3) :: ip_loc !< Physical location of the image point + integer, dimension(3) :: ip_grid !< Top left grid point of IP + real(wp), dimension(2, 2, 2) :: interp_coeffs !< Interpolation Coefficients of image point + integer :: ib_patch_id !< ID of the IB Patch the ghost point is part of + real(wp) :: levelset + real(wp), dimension(1:3) :: levelset_norm + logical :: slip + integer, dimension(3) :: DB + integer :: x_periodicity, y_periodicity, z_periodicity end type ghost_point !> Species parameters type species_parameters - character(LEN=name_len) :: name !< Name of species + character(LEN=name_len) :: name !< Name of species end type species_parameters !> Chemistry parameters type chemistry_parameters - character(LEN=name_len) :: cantera_file !< Path to Cantera file - - logical :: diffusion - logical :: reactions + character(LEN=name_len) :: cantera_file !< Path to Cantera file + logical :: diffusion + logical :: reactions !> Method of determining gamma. !> gamma_method = 1: Ref. Section 2.3.1 Formulation of doi:10.7907/ZKW8-ES97. @@ -490,26 +418,25 @@ module m_derived_types !> Lagrangian bubble parameters type bubbles_lagrange_parameters - integer :: solver_approach !< 1: One-way coupling, 2: two-way coupling - integer :: cluster_type !< Cluster model to find p_inf - logical :: pressure_corrector !< Cell pressure correction term - integer :: smooth_type !< Smoothing function. 1: Gaussian, 2:Delta 3x3 - logical :: heatTransfer_model !< Activate HEAT transfer model at the bubble-liquid interface - logical :: massTransfer_model !< Activate MASS transfer model at the bubble-liquid interface - logical :: write_void_evol !< Write files to track evolution of void fraction at each time step - logical :: write_bubbles !< Write files to track the bubble evolution each time step - logical :: write_bubbles_stats !< Write the maximum and minimum radius of each bubble - integer :: nBubs_glb !< Global number of bubbles - integer :: vel_model !< Particle velocity model - integer :: drag_model !< Particle drag model - logical :: pressure_force !< Include pressure force translational motion - logical :: gravity_force !< Include gravity force in translational motion - character(LEN=pathlen_max) :: input_path !< Path to lag_bubbles.dat - real(wp) :: epsilonb !< Standard deviation scaling for the gaussian function - real(wp) :: charwidth !< Domain virtual depth (z direction, for 2D simulations) - integer :: charNz !< Number of grid cells in characteristic depth - real(wp) :: valmaxvoid !< Maximum void fraction permitted - + integer :: solver_approach !< 1: One-way coupling, 2: two-way coupling + integer :: cluster_type !< Cluster model to find p_inf + logical :: pressure_corrector !< Cell pressure correction term + integer :: smooth_type !< Smoothing function. 1: Gaussian, 2:Delta 3x3 + logical :: heatTransfer_model !< Activate HEAT transfer model at the bubble-liquid interface + logical :: massTransfer_model !< Activate MASS transfer model at the bubble-liquid interface + logical :: write_void_evol !< Write files to track evolution of void fraction at each time step + logical :: write_bubbles !< Write files to track the bubble evolution each time step + logical :: write_bubbles_stats !< Write the maximum and minimum radius of each bubble + integer :: nBubs_glb !< Global number of bubbles + integer :: vel_model !< Particle velocity model + integer :: drag_model !< Particle drag model + logical :: pressure_force !< Include pressure force translational motion + logical :: gravity_force !< Include gravity force in translational motion + character(LEN=pathlen_max) :: input_path !< Path to lag_bubbles.dat + real(wp) :: epsilonb !< Standard deviation scaling for the gaussian function + real(wp) :: charwidth !< Domain virtual depth (z direction, for 2D simulations) + integer :: charNz !< Number of grid cells in characteristic depth + real(wp) :: valmaxvoid !< Maximum void fraction permitted end type bubbles_lagrange_parameters !> Max and min number of cells in a direction of each combination of x-,y-, and z- @@ -519,16 +446,13 @@ module m_derived_types end type cell_num_bounds type simplex_noise_params - logical, dimension(3) :: perturb_vel - real(wp), dimension(3) :: perturb_vel_freq - real(wp), dimension(3) :: perturb_vel_scale - real(wp), dimension(3, 3) :: perturb_vel_offset - - logical, dimension(1:num_fluids_max) :: perturb_dens - real(wp), dimension(1:num_fluids_max) :: perturb_dens_freq - real(wp), dimension(1:num_fluids_max) :: perturb_dens_scale - real(wp), dimension(1:num_fluids_max, 3) :: perturb_dens_offset - end type - + logical, dimension(3) :: perturb_vel + real(wp), dimension(3) :: perturb_vel_freq + real(wp), dimension(3) :: perturb_vel_scale + real(wp), dimension(3, 3) :: perturb_vel_offset + logical, dimension(1:num_fluids_max) :: perturb_dens + real(wp), dimension(1:num_fluids_max) :: perturb_dens_freq + real(wp), dimension(1:num_fluids_max) :: perturb_dens_scale + real(wp), dimension(1:num_fluids_max,3) :: perturb_dens_offset + end type simplex_noise_params end module m_derived_types - diff --git a/src/common/m_finite_differences.fpp b/src/common/m_finite_differences.fpp index e44b6905c0..9db868add1 100644 --- a/src/common/m_finite_differences.fpp +++ b/src/common/m_finite_differences.fpp @@ -15,49 +15,53 @@ contains subroutine s_compute_fd_divergence(div, fields, ix_s, iy_s, iz_s) - type(scalar_field), intent(INOUT) :: div - type(scalar_field), intent(IN) :: fields(1:3) - type(int_bounds_info), intent(IN) :: ix_s, iy_s, iz_s + type(scalar_field), intent(inout) :: div + type(scalar_field), intent(in) :: fields(1:3) + type(int_bounds_info), intent(in) :: ix_s, iy_s, iz_s + integer :: x, y, z !< Generic loop iterators + real(wp) :: divergence - integer :: x, y, z !< Generic loop iterators - - real(wp) :: divergence - - $:GPU_PARALLEL_LOOP(collapse=3, private='[x,y,z,divergence]') + $:GPU_PARALLEL_LOOP(collapse=3, private='[x, y, z, divergence]') do x = ix_s%beg, ix_s%end do y = iy_s%beg, iy_s%end do z = iz_s%beg, iz_s%end - if (x == ix_s%beg) then - divergence = (-3._wp*fields(1)%sf(x, y, z) + 4._wp*fields(1)%sf(x + 1, y, z) - fields(1)%sf(x + 2, y, z))/(x_cc(x + 2) - x_cc(x)) + divergence = (-3._wp*fields(1)%sf(x, y, z) + 4._wp*fields(1)%sf(x + 1, y, z) - fields(1)%sf(x + 2, y, & + & z))/(x_cc(x + 2) - x_cc(x)) else if (x == ix_s%end) then - divergence = (+3._wp*fields(1)%sf(x, y, z) - 4._wp*fields(1)%sf(x - 1, y, z) + fields(1)%sf(x - 2, y, z))/(x_cc(x) - x_cc(x - 2)) + divergence = (+3._wp*fields(1)%sf(x, y, z) - 4._wp*fields(1)%sf(x - 1, y, z) + fields(1)%sf(x - 2, y, & + & z))/(x_cc(x) - x_cc(x - 2)) else divergence = (fields(1)%sf(x + 1, y, z) - fields(1)%sf(x - 1, y, z))/(x_cc(x + 1) - x_cc(x - 1)) end if if (n > 0) then if (y == iy_s%beg) then - divergence = divergence + (-3._wp*fields(2)%sf(x, y, z) + 4._wp*fields(2)%sf(x, y + 1, z) - fields(2)%sf(x, y + 2, z))/(y_cc(y + 2) - y_cc(y)) + divergence = divergence + (-3._wp*fields(2)%sf(x, y, z) + 4._wp*fields(2)%sf(x, y + 1, & + & z) - fields(2)%sf(x, y + 2, z))/(y_cc(y + 2) - y_cc(y)) else if (y == iy_s%end) then - divergence = divergence + (+3._wp*fields(2)%sf(x, y, z) - 4._wp*fields(2)%sf(x, y - 1, z) + fields(2)%sf(x, y - 2, z))/(y_cc(y) - y_cc(y - 2)) + divergence = divergence + (+3._wp*fields(2)%sf(x, y, z) - 4._wp*fields(2)%sf(x, y - 1, & + & z) + fields(2)%sf(x, y - 2, z))/(y_cc(y) - y_cc(y - 2)) else - divergence = divergence + (fields(2)%sf(x, y + 1, z) - fields(2)%sf(x, y - 1, z))/(y_cc(y + 1) - y_cc(y - 1)) + divergence = divergence + (fields(2)%sf(x, y + 1, z) - fields(2)%sf(x, y - 1, & + & z))/(y_cc(y + 1) - y_cc(y - 1)) end if end if if (p > 0) then if (z == iz_s%beg) then - divergence = divergence + (-3._wp*fields(3)%sf(x, y, z) + 4._wp*fields(3)%sf(x, y, z + 1) - fields(3)%sf(x, y, z + 2))/(z_cc(z + 2) - z_cc(z)) + divergence = divergence + (-3._wp*fields(3)%sf(x, y, z) + 4._wp*fields(3)%sf(x, y, & + & z + 1) - fields(3)%sf(x, y, z + 2))/(z_cc(z + 2) - z_cc(z)) else if (z == iz_s%end) then - divergence = divergence + (+3._wp*fields(3)%sf(x, y, z) - 4._wp*fields(3)%sf(x, y, z - 1) + fields(3)%sf(x, y, z - 2))/(z_cc(z) - z_cc(z - 2)) + divergence = divergence + (+3._wp*fields(3)%sf(x, y, z) - 4._wp*fields(3)%sf(x, y, & + & z - 1) + fields(3)%sf(x, y, z - 2))/(z_cc(z) - z_cc(z - 2)) else - divergence = divergence + (fields(3)%sf(x, y, z + 1) - fields(3)%sf(x, y, z - 1))/(z_cc(z + 1) - z_cc(z - 1)) + divergence = divergence + (fields(3)%sf(x, y, z + 1) - fields(3)%sf(x, y, & + & z - 1))/(z_cc(z + 1) - z_cc(z - 1)) end if end if div%sf(x, y, z) = div%sf(x, y, z) + divergence - end do end do end do @@ -65,34 +69,26 @@ contains end subroutine s_compute_fd_divergence - !> The purpose of this subroutine is to compute the finite- - !! difference coefficients for the centered schemes utilized - !! in computations of first order spatial derivatives in the - !! s-coordinate direction. The s-coordinate direction refers - !! to the x-, y- or z-coordinate direction, depending on the - !! subroutine's inputs. Note that coefficients of up to 4th - !! order accuracy are available. - !! @param q Number of cells in the s-coordinate direction - !! @param s_cc Locations of the cell-centers in the s-coordinate direction - !! @param fd_coeff_s Finite-diff. coefficients in the s-coordinate direction - !! @param local_buff_size Size of the local buffer - !! @param fd_number_in Finite-difference number - !! @param fd_order_in Finite-difference order of accuracy - !! @param offset_s Optional offset bounds in the s-coordinate direction - subroutine s_compute_finite_difference_coefficients(q, s_cc, fd_coeff_s, local_buff_size, & - fd_number_in, fd_order_in, offset_s) - - integer :: lB, lE !< loop bounds - integer, intent(IN) :: q - integer, intent(IN) :: local_buff_size, fd_number_in, fd_order_in - type(int_bounds_info), optional, intent(IN) :: offset_s - real(wp), allocatable, dimension(:, :), intent(INOUT) :: fd_coeff_s - - real(wp), & - dimension(-local_buff_size:q + local_buff_size), & - intent(IN) :: s_cc - - integer :: i !< Generic loop iterator + !> The purpose of this subroutine is to compute the finite- difference coefficients for the centered schemes utilized in + !! computations of first order spatial derivatives in the s-coordinate direction. The s-coordinate direction refers to the x-, + !! y- or z-coordinate direction, depending on the subroutine's inputs. Note that coefficients of up to 4th order accuracy are + !! available. + !! @param q Number of cells in the s-coordinate direction + !! @param s_cc Locations of the cell-centers in the s-coordinate direction + !! @param fd_coeff_s Finite-diff. coefficients in the s-coordinate direction + !! @param local_buff_size Size of the local buffer + !! @param fd_number_in Finite-difference number + !! @param fd_order_in Finite-difference order of accuracy + !! @param offset_s Optional offset bounds in the s-coordinate direction + subroutine s_compute_finite_difference_coefficients(q, s_cc, fd_coeff_s, local_buff_size, fd_number_in, fd_order_in, offset_s) + + integer :: lB, lE !< loop bounds + integer, intent(in) :: q + integer, intent(in) :: local_buff_size, fd_number_in, fd_order_in + type(int_bounds_info), optional, intent(in) :: offset_s + real(wp), allocatable, dimension(:,:), intent(inout) :: fd_coeff_s + real(wp), dimension(-local_buff_size:q + local_buff_size), intent(in) :: s_cc + integer :: i !< Generic loop iterator if (present(offset_s)) then lB = -offset_s%beg @@ -104,7 +100,7 @@ contains #ifdef MFC_POST_PROCESS if (allocated(fd_coeff_s)) deallocate (fd_coeff_s) - allocate (fd_coeff_s(-fd_number_in:fd_number_in, lb:lE)) + allocate (fd_coeff_s(-fd_number_in:fd_number_in,lb:lE)) #endif ! Computing the 1st order finite-difference coefficients @@ -116,7 +112,7 @@ contains end do ! Computing the 2nd order finite-difference coefficients - elseif (fd_order_in == 2) then + else if (fd_order_in == 2) then do i = lB, lE fd_coeff_s(-1, i) = -1._wp/(s_cc(i + 1) - s_cc(i - 1)) fd_coeff_s(0, i) = 0._wp @@ -132,10 +128,8 @@ contains fd_coeff_s(1, i) = -fd_coeff_s(-1, i) fd_coeff_s(2, i) = -fd_coeff_s(-2, i) end do - end if end subroutine s_compute_finite_difference_coefficients end module m_finite_differences - diff --git a/src/common/m_helper.fpp b/src/common/m_helper.fpp index 1941d119ec..72a92442d5 100644 --- a/src/common/m_helper.fpp +++ b/src/common/m_helper.fpp @@ -8,56 +8,33 @@ !> @brief Utility routines for bubble model setup, coordinate transforms, array sampling, and special functions module m_helper - use m_derived_types !< Definitions of the derived types - - use m_global_parameters !< Definitions of the global parameters - - use ieee_arithmetic !< For checking NaN + use m_derived_types !< Definitions of the derived types + use m_global_parameters !< Definitions of the global parameters + use ieee_arithmetic !< For checking NaN implicit none - private; - public :: s_comp_n_from_prim, & - s_comp_n_from_cons, & - s_initialize_bubbles_model, & - s_initialize_nonpoly, & - s_simpson, & - s_transcoeff, & - s_int_to_str, & - s_transform_vec, & - s_transform_triangle, & - s_transform_model, & - s_swap, & - f_cross, & - f_create_transform_matrix, & - f_create_bbox, & - s_print_2D_array, & - f_xor, & - f_logical_to_int, & - associated_legendre, & - real_ylm, & - double_factorial, & - factorial, & - f_cut_on, & - f_cut_off, & - s_downsample_data, & - s_upsample_data + private + public :: s_comp_n_from_prim, s_comp_n_from_cons, s_initialize_bubbles_model, s_initialize_nonpoly, s_simpson, s_transcoeff, & + & s_int_to_str, s_transform_vec, s_transform_triangle, s_transform_model, s_swap, f_cross, f_create_transform_matrix, & + & f_create_bbox, s_print_2D_array, f_xor, f_logical_to_int, associated_legendre, real_ylm, double_factorial, factorial, & + & f_cut_on, f_cut_off, s_downsample_data, s_upsample_data contains !> Computes the bubble number density n from the primitive variables - !! @param vftmp is the void fraction - !! @param Rtmp is the bubble radii - !! @param ntmp is the output number bubble density - !! @param weights is the quadrature weights + !! @param vftmp is the void fraction + !! @param Rtmp is the bubble radii + !! @param ntmp is the output number bubble density + !! @param weights is the quadrature weights subroutine s_comp_n_from_prim(vftmp, Rtmp, ntmp, weights) + $:GPU_ROUTINE(parallelism='[seq]') - real(wp), intent(in) :: vftmp + real(wp), intent(in) :: vftmp real(wp), dimension(nb), intent(in) :: Rtmp - real(wp), intent(out) :: ntmp + real(wp), intent(out) :: ntmp real(wp), dimension(nb), intent(in) :: weights - - real(wp) :: R3 + real(wp) :: R3 R3 = dot_product(weights, Rtmp**3._wp) ntmp = (3._wp/(4._wp*pi))*vftmp/R3 @@ -66,13 +43,13 @@ contains !> @brief Computes the bubble number density from the conservative void fraction and weighted bubble radii. subroutine s_comp_n_from_cons(vftmp, nRtmp, ntmp, weights) + $:GPU_ROUTINE(parallelism='[seq]') - real(wp), intent(in) :: vftmp + real(wp), intent(in) :: vftmp real(wp), dimension(nb), intent(in) :: nRtmp - real(wp), intent(out) :: ntmp + real(wp), intent(out) :: ntmp real(wp), dimension(nb), intent(in) :: weights - - real(wp) :: nR3 + real(wp) :: nR3 nR3 = dot_product(weights, nRtmp**3._wp) ntmp = sqrt((4._wp*pi/3._wp)*nR3/vftmp) @@ -82,12 +59,11 @@ contains !> @brief Prints a 2D real array to standard output, optionally dividing each element by a given scalar. impure subroutine s_print_2D_array(A, div) - real(wp), dimension(:, :), intent(in) :: A - real(wp), optional, intent(in) :: div - - integer :: i, j - integer :: local_m, local_n - real(wp) :: c + real(wp), dimension(:,:), intent(in) :: A + real(wp), optional, intent(in) :: div + integer :: i, j + integer :: local_m, local_n + real(wp) :: c local_m = size(A, 1) local_n = size(A, 2) @@ -110,10 +86,7 @@ contains end subroutine s_print_2D_array - !> - !! bubbles_euler + polytropic - !! bubbles_euler + non-polytropic - !! bubbles_lagrange + non-polytropic + !> bubbles_euler + polytropic bubbles_euler + non-polytropic bubbles_lagrange + non-polytropic impure subroutine s_initialize_bubbles_model() ! Allocate memory @@ -147,7 +120,7 @@ contains impure subroutine s_initialize_bubble_vars() R0ref = bub_pp%R0ref; p0ref = bub_pp%p0ref - rho0ref = bub_pp%rho0ref; + rho0ref = bub_pp%rho0ref ss = bub_pp%ss; pv = bub_pp%pv; vd = bub_pp%vd mu_l = bub_pp%mu_l; mu_v = bub_pp%mu_v; mu_g = bub_pp%mu_g gam_v = bub_pp%gam_v; gam_g = bub_pp%gam_g @@ -199,17 +172,15 @@ contains !> Initializes non-polydisperse bubble modeling impure subroutine s_initialize_nonpoly() - integer :: ir - real(wp), dimension(nb) :: chi_vw0, cp_m0, k_m0, rho_m0, x_vw, omegaN, rhol0 - real(wp), parameter :: k_poly = 1._wp !< - !! polytropic index used to compute isothermal natural frequency + integer :: ir + real(wp), dimension(nb) :: chi_vw0, cp_m0, k_m0, rho_m0, x_vw, omegaN, rhol0 + real(wp), parameter :: k_poly = 1._wp !< polytropic index used to compute isothermal natural frequency ! phi_vg & phi_gv (phi_gg = phi_vv = 1) (Eq. 2.22 in Ando 2010) - phi_vg = (1._wp + sqrt(mu_v/mu_g)*(M_g/M_v)**(0.25_wp))**2 & - /(sqrt(8._wp)*sqrt(1._wp + M_v/M_g)) - phi_gv = (1._wp + sqrt(mu_g/mu_v)*(M_v/M_g)**(0.25_wp))**2 & - /(sqrt(8._wp)*sqrt(1._wp + M_g/M_v)) + + phi_vg = (1._wp + sqrt(mu_v/mu_g)*(M_g/M_v)**(0.25_wp))**2/(sqrt(8._wp)*sqrt(1._wp + M_v/M_g)) + phi_gv = (1._wp + sqrt(mu_g/mu_v)*(M_v/M_g)**(0.25_wp))**2/(sqrt(8._wp)*sqrt(1._wp + M_g/M_v)) ! internal bubble pressure pb0 = Eu + 2._wp/Web/R0 @@ -218,15 +189,13 @@ contains chi_vw0 = 1._wp/(1._wp + R_v/R_g*(pb0/pv - 1._wp)) ! specific heat for gas/vapor mixture - cp_m0 = chi_vw0*R_v*gam_v/(gam_v - 1._wp) & - + (1._wp - chi_vw0)*R_g*gam_g/(gam_g - 1._wp) + cp_m0 = chi_vw0*R_v*gam_v/(gam_v - 1._wp) + (1._wp - chi_vw0)*R_g*gam_g/(gam_g - 1._wp) ! mole fraction of vapor (Eq. 2.23 in Ando 2010) x_vw = M_g*chi_vw0/(M_v + (M_g - M_v)*chi_vw0) ! thermal conductivity for gas/vapor mixture (Eq. 2.21 in Ando 2010) - k_m0 = x_vw*k_v/(x_vw + (1._wp - x_vw)*phi_vg) & - + (1._wp - x_vw)*k_g/(x_vw*phi_gv + 1._wp - x_vw) + k_m0 = x_vw*k_v/(x_vw + (1._wp - x_vw)*phi_vg) + (1._wp - x_vw)*k_g/(x_vw*phi_gv + 1._wp - x_vw) k_g(:) = k_g(:)/k_m0(:) k_v(:) = k_v(:)/k_m0(:) @@ -243,33 +212,30 @@ contains ! natural frequencies (Eq. B.1) omegaN(:) = sqrt(3._wp*k_poly*Ca + 2._wp*(3._wp*k_poly - 1._wp)/(Web*R0))/R0/sqrt(rho0ref) do ir = 1, nb - call s_transcoeff(omegaN(ir)*R0(ir), Pe_T(ir)*R0(ir), & - Re_trans_T(ir), Im_trans_T(ir)) - call s_transcoeff(omegaN(ir)*R0(ir), Pe_c*R0(ir), & - Re_trans_c(ir), Im_trans_c(ir)) + call s_transcoeff(omegaN(ir)*R0(ir), Pe_T(ir)*R0(ir), Re_trans_T(ir), Im_trans_T(ir)) + call s_transcoeff(omegaN(ir)*R0(ir), Pe_c*R0(ir), Re_trans_c(ir), Im_trans_c(ir)) end do Im_trans_T = 0._wp end subroutine s_initialize_nonpoly !> Computes the transfer coefficient for the non-polytropic bubble compression process - !! @param omega natural frequencies - !! @param peclet Peclet number - !! @param Re_trans Real part of the transport coefficients - !! @param Im_trans Imaginary part of the transport coefficients + !! @param omega natural frequencies + !! @param peclet Peclet number + !! @param Re_trans Real part of the transport coefficients + !! @param Im_trans Imaginary part of the transport coefficients elemental subroutine s_transcoeff(omega, peclet, Re_trans, Im_trans) - real(wp), intent(in) :: omega, peclet + real(wp), intent(in) :: omega, peclet real(wp), intent(out) :: Re_trans, Im_trans - - complex(wp) :: imag, trans, c1, c2, c3 + complex(wp) :: imag, trans, c1, c2, c3 imag = (0._wp, 1._wp) c1 = imag*omega*peclet c2 = sqrt(c1) - c3 = (exp(c2) - exp(-c2))/(exp(c2) + exp(-c2)) ! TANH(c2) - trans = ((c2/c3 - 1._wp)**(-1) - 3._wp/c1)**(-1) ! transfer function + c3 = (exp(c2) - exp(-c2))/(exp(c2) + exp(-c2)) ! TANH(c2) + trans = ((c2/c3 - 1._wp)**(-1) - 3._wp/c1)**(-1) ! transfer function Re_trans = trans Im_trans = aimag(trans) @@ -279,11 +245,12 @@ contains !> @brief Converts an integer to its trimmed string representation. elemental subroutine s_int_to_str(i, res) - integer, intent(in) :: i + integer, intent(in) :: i character(len=*), intent(inout) :: res write (res, '(I0)') i res = trim(res) + end subroutine s_int_to_str !> Computes the Simpson weights for quadrature @@ -291,9 +258,9 @@ contains real(wp), dimension(:), intent(inout) :: local_weight real(wp), dimension(:), intent(inout) :: local_R0 - integer :: ir - real(wp) :: R0mn, R0mx, dphi, tmp, sd - real(wp), dimension(nb) :: phi + integer :: ir + real(wp) :: R0mn, R0mx, dphi, tmp, sd + real(wp), dimension(nb) :: phi sd = poly_sigma R0mn = 0.8_wp*exp(-2.8_wp*sd) @@ -301,8 +268,7 @@ contains ! phi = ln( R0 ) & return R0 do ir = 1, nb - phi(ir) = log(R0mn) & - + (ir - 1._wp)*log(R0mx/R0mn)/(nb - 1._wp) + phi(ir) = log(R0mn) + (ir - 1._wp)*log(R0mx/R0mn)/(nb - 1._wp) local_R0(ir) = exp(phi(ir)) end do @@ -336,11 +302,12 @@ contains $:GPU_ROUTINE(parallelism='[seq]') real(wp), dimension(3), intent(in) :: a, b - real(wp), dimension(3) :: c + real(wp), dimension(3) :: c c(1) = a(2)*b(3) - a(3)*b(2) c(2) = a(3)*b(1) - a(1)*b(3) c(3) = a(1)*b(2) - a(2)*b(1) + end function f_cross !> This procedure swaps two real numbers. @@ -349,11 +316,12 @@ contains elemental subroutine s_swap(lhs, rhs) real(wp), intent(inout) :: lhs, rhs - real(wp) :: ltemp + real(wp) :: ltemp ltemp = lhs lhs = rhs rhs = ltemp + end subroutine s_swap !> This procedure creates a transformation matrix. @@ -362,54 +330,33 @@ contains !! @return Transformation matrix. function f_create_transform_matrix(param, center) result(out_matrix) - type(ic_model_parameters), intent(in) :: param + type(ic_model_parameters), intent(in) :: param real(wp), dimension(1:3), optional, intent(in) :: center - real(wp), dimension(1:4, 1:4) :: sc, rz, rx, ry, tr, t_back, t_to_origin, out_matrix - - sc = transpose(reshape([ & - param%scale(1), 0._wp, 0._wp, 0._wp, & - 0._wp, param%scale(2), 0._wp, 0._wp, & - 0._wp, 0._wp, param%scale(3), 0._wp, & - 0._wp, 0._wp, 0._wp, 1._wp], shape(sc))) - - rz = transpose(reshape([ & - cos(param%rotate(3)), -sin(param%rotate(3)), 0._wp, 0._wp, & - sin(param%rotate(3)), cos(param%rotate(3)), 0._wp, 0._wp, & - 0._wp, 0._wp, 1._wp, 0._wp, & - 0._wp, 0._wp, 0._wp, 1._wp], shape(rz))) - - rx = transpose(reshape([ & - 1._wp, 0._wp, 0._wp, 0._wp, & - 0._wp, cos(param%rotate(1)), -sin(param%rotate(1)), 0._wp, & - 0._wp, sin(param%rotate(1)), cos(param%rotate(1)), 0._wp, & - 0._wp, 0._wp, 0._wp, 1._wp], shape(rx))) - - ry = transpose(reshape([ & - cos(param%rotate(2)), 0._wp, sin(param%rotate(2)), 0._wp, & - 0._wp, 1._wp, 0._wp, 0._wp, & - -sin(param%rotate(2)), 0._wp, cos(param%rotate(2)), 0._wp, & - 0._wp, 0._wp, 0._wp, 1._wp], shape(ry))) - - tr = transpose(reshape([ & - 1._wp, 0._wp, 0._wp, param%translate(1), & - 0._wp, 1._wp, 0._wp, param%translate(2), & - 0._wp, 0._wp, 1._wp, param%translate(3), & - 0._wp, 0._wp, 0._wp, 1._wp], shape(tr))) + real(wp), dimension(1:4,1:4) :: sc, rz, rx, ry, tr, t_back, t_to_origin, out_matrix + + sc = transpose(reshape([param%scale(1), 0._wp, 0._wp, 0._wp, 0._wp, param%scale(2), 0._wp, 0._wp, 0._wp, 0._wp, & + & param%scale(3), 0._wp, 0._wp, 0._wp, 0._wp, 1._wp], shape(sc))) + + rz = transpose(reshape([cos(param%rotate(3)), -sin(param%rotate(3)), 0._wp, 0._wp, sin(param%rotate(3)), & + & cos(param%rotate(3)), 0._wp, 0._wp, 0._wp, 0._wp, 1._wp, 0._wp, 0._wp, 0._wp, 0._wp, 1._wp], shape(rz))) + + rx = transpose(reshape([1._wp, 0._wp, 0._wp, 0._wp, 0._wp, cos(param%rotate(1)), -sin(param%rotate(1)), 0._wp, 0._wp, & + & sin(param%rotate(1)), cos(param%rotate(1)), 0._wp, 0._wp, 0._wp, 0._wp, 1._wp], shape(rx))) + + ry = transpose(reshape([cos(param%rotate(2)), 0._wp, sin(param%rotate(2)), 0._wp, 0._wp, 1._wp, 0._wp, 0._wp, & + & -sin(param%rotate(2)), 0._wp, cos(param%rotate(2)), 0._wp, 0._wp, 0._wp, 0._wp, 1._wp], shape(ry))) + + tr = transpose(reshape([1._wp, 0._wp, 0._wp, param%translate(1), 0._wp, 1._wp, 0._wp, param%translate(2), 0._wp, 0._wp, & + & 1._wp, param%translate(3), 0._wp, 0._wp, 0._wp, 1._wp], shape(tr))) if (present(center)) then ! Translation matrix to move center to the origin - t_to_origin = transpose(reshape([ & - 1._wp, 0._wp, 0._wp, -center(1), & - 0._wp, 1._wp, 0._wp, -center(2), & - 0._wp, 0._wp, 1._wp, -center(3), & - 0._wp, 0._wp, 0._wp, 1._wp], shape(tr))) + t_to_origin = transpose(reshape([1._wp, 0._wp, 0._wp, -center(1), 0._wp, 1._wp, 0._wp, -center(2), 0._wp, 0._wp, & + & 1._wp, -center(3), 0._wp, 0._wp, 0._wp, 1._wp], shape(tr))) ! Translation matrix to move center back to original position - t_back = transpose(reshape([ & - 1._wp, 0._wp, 0._wp, center(1), & - 0._wp, 1._wp, 0._wp, center(2), & - 0._wp, 0._wp, 1._wp, center(3), & - 0._wp, 0._wp, 0._wp, 1._wp], shape(tr))) + t_back = transpose(reshape([1._wp, 0._wp, 0._wp, center(1), 0._wp, 1._wp, 0._wp, center(2), 0._wp, 0._wp, 1._wp, & + & center(3), 0._wp, 0._wp, 0._wp, 1._wp], shape(tr))) out_matrix = matmul(tr, matmul(t_back, matmul(ry, matmul(rx, matmul(rz, matmul(sc, t_to_origin)))))) else @@ -423,10 +370,9 @@ contains !! @param matrix Transformation matrix. subroutine s_transform_vec(vec, matrix) - real(wp), dimension(1:3), intent(inout) :: vec - real(wp), dimension(1:4, 1:4), intent(in) :: matrix - - real(wp), dimension(1:4) :: tmp + real(wp), dimension(1:3), intent(inout) :: vec + real(wp), dimension(1:4,1:4), intent(in) :: matrix + real(wp), dimension(1:4) :: tmp tmp = matmul(matrix, [vec(1), vec(2), vec(3), 1._wp]) vec = tmp(1:3) @@ -439,13 +385,12 @@ contains !! @param matrix_n Normal transformation matrix. subroutine s_transform_triangle(triangle, matrix, matrix_n) - type(t_triangle), intent(inout) :: triangle - real(wp), dimension(1:4, 1:4), intent(in) :: matrix, matrix_n - - integer :: i + type(t_triangle), intent(inout) :: triangle + real(wp), dimension(1:4,1:4), intent(in) :: matrix, matrix_n + integer :: i do i = 1, 3 - call s_transform_vec(triangle%v(i, :), matrix) + call s_transform_vec(triangle%v(i,:), matrix) end do call s_transform_vec(triangle%n(1:3), matrix_n) @@ -458,10 +403,9 @@ contains !! @param matrix_n Normal transformation matrix. subroutine s_transform_model(model, matrix, matrix_n) - type(t_model), intent(inout) :: model - real(wp), dimension(1:4, 1:4), intent(in) :: matrix, matrix_n - - integer :: i + type(t_model), intent(inout) :: model + real(wp), dimension(1:4,1:4), intent(in) :: matrix, matrix_n + integer :: i do i = 1, size(model%trs) call s_transform_triangle(model%trs(i), matrix, matrix_n) @@ -475,9 +419,8 @@ contains function f_create_bbox(model) result(bbox) type(t_model), intent(in) :: model - type(t_bbox) :: bbox - - integer :: i, j + type(t_bbox) :: bbox + integer :: i, j if (size(model%trs) == 0) then bbox%min = 0._wp @@ -485,13 +428,13 @@ contains return end if - bbox%min = model%trs(1)%v(1, :) - bbox%max = model%trs(1)%v(1, :) + bbox%min = model%trs(1)%v(1,:) + bbox%max = model%trs(1)%v(1,:) do i = 1, size(model%trs) do j = 1, 3 - bbox%min = min(bbox%min, model%trs(i)%v(j, :)) - bbox%max = max(bbox%max, model%trs(i)%v(j, :)) + bbox%min = min(bbox%min, model%trs(i)%v(j,:)) + bbox%max = max(bbox%max, model%trs(i)%v(j,:)) end do end do @@ -504,9 +447,10 @@ contains elemental function f_xor(lhs, rhs) result(res) logical, intent(in) :: lhs, rhs - logical :: res + logical :: res res = (lhs .and. .not. rhs) .or. (.not. lhs .and. rhs) + end function f_xor !> This procedure converts logical to 1 or 0. @@ -515,22 +459,24 @@ contains elemental function f_logical_to_int(predicate) result(int) logical, intent(in) :: predicate - integer :: int + integer :: int if (predicate) then int = 1 else int = 0 end if + end function f_logical_to_int - !> Real spherical harmonic Y_lm(theta, phi). theta = polar angle from +z (acos(z/r)), - !! phi = atan2(y,x). Uses associated Legendre P_l^|m|(cos theta). Standard normalisation. + !> Real spherical harmonic Y_lm(theta, phi). theta = polar angle from +z (acos(z/r)), phi = atan2(y,x). Uses associated Legendre + !! P_l^|m|(cos theta). Standard normalisation. function real_ylm(theta, phi, l, m) result(Y) - integer, intent(in) :: l, m + + integer, intent(in) :: l, m real(wp), intent(in) :: theta, phi - real(wp) :: Y, x, prefac - integer :: m_abs + real(wp) :: Y, x, prefac + integer :: m_abs m_abs = abs(m) if (m_abs > l) then @@ -546,24 +492,25 @@ contains else Y = prefac*sqrt(2._wp)*associated_legendre(x, l, m_abs)*sin(m_abs*phi) end if + end function real_ylm - !> Associated Legendre polynomial P_l^m(x) (Ferrers function, Condon-Shortley phase). - !! Valid for integer l >= 0, 0 <= m <= l, and x in [-1,1]. Returns 0 for |m| > l or l < 0. - !! Formulas: DLMF 14.10.3 (recurrence in degree), Wikipedia "Associated Legendre polynomials" - !! (P_l^l and P_l^{l-1} identities). Recurrence: (l-m)P_l^m = (2l-1)x P_{l-1}^m - (l+m-1)P_{l-2}^m. + !> Associated Legendre polynomial P_l^m(x) (Ferrers function, Condon-Shortley phase). Valid for integer l >= 0, 0 <= m <= l, and + !! x in [-1,1]. Returns 0 for |m| > l or l < 0. Formulas: DLMF 14.10.3 (recurrence in degree), Wikipedia "Associated Legendre + !! polynomials" (P_l^l and P_l^{l-1} identities). Recurrence: (l-m)P_l^m = (2l-1)x P_{l-1}^m - (l+m-1)P_{l-2}^m. !! @param x argument (typically cos(theta)), should be in [-1,1] !! @param l degree (>= 0) !! @param m_order order (0 <= m_order <= l) !! @return result_P P_l^m(x) recursive function associated_legendre(x, l, m_order) result(result_P) - integer, intent(in) :: l, m_order + integer, intent(in) :: l, m_order real(wp), intent(in) :: x - real(wp) :: result_P - real(wp) :: one_minus_x2 + real(wp) :: result_P + real(wp) :: one_minus_x2 ! Out-of-domain: P_l^m = 0 for |m| > l or l < 0 (standard convention) + if (l < 0 .or. m_order < 0 .or. m_order > l) then result_P = 0._wp return @@ -571,19 +518,20 @@ contains if (m_order <= 0 .and. l <= 0) then result_P = 1._wp - elseif (l == 1 .and. m_order <= 0) then + else if (l == 1 .and. m_order <= 0) then result_P = x - elseif (l == 1 .and. m_order == 1) then + else if (l == 1 .and. m_order == 1) then one_minus_x2 = max(0._wp, 1._wp - x**2) result_P = -sqrt(one_minus_x2) - elseif (m_order == l) then + else if (m_order == l) then ! P_l^l(x) = (-1)^l (2l-1)!! (1-x^2)^(l/2). Use real exponent for odd l one_minus_x2 = max(0._wp, 1._wp - x**2) result_P = (-1)**l*real(double_factorial(2*l - 1), wp)*one_minus_x2**(0.5_wp*real(l, wp)) - elseif (m_order == l - 1) then + else if (m_order == l - 1) then result_P = x*(2*l - 1)*associated_legendre(x, l - 1, l - 1) else - result_P = ((2*l - 1)*x*associated_legendre(x, l - 1, m_order) - (l + m_order - 1)*associated_legendre(x, l - 2, m_order))/(l - m_order) + result_P = ((2*l - 1)*x*associated_legendre(x, l - 1, m_order) - (l + m_order - 1)*associated_legendre(x, l - 2, & + & m_order))/(l - m_order) end if end function associated_legendre @@ -593,10 +541,10 @@ contains !! @return R is the double factorial value of n elemental function double_factorial(n_in) result(R_result) - integer, intent(in) :: n_in - integer, parameter :: int64_kind = selected_int_kind(18) ! 18 bytes for 64-bit integer + integer, intent(in) :: n_in + integer, parameter :: int64_kind = selected_int_kind(18) ! 18 bytes for 64-bit integer integer(kind=int64_kind) :: R_result - integer :: i + integer :: i R_result = product((/(i, i=n_in, 1, -2)/)) @@ -607,41 +555,38 @@ contains !! @return R is the factorial value of n elemental function factorial(n_in) result(R_result) - integer, intent(in) :: n_in - integer, parameter :: int64_kind = selected_int_kind(18) ! 18 bytes for 64-bit integer + integer, intent(in) :: n_in + integer, parameter :: int64_kind = selected_int_kind(18) ! 18 bytes for 64-bit integer integer(kind=int64_kind) :: R_result - - integer :: i + integer :: i R_result = product((/(i, i=n_in, 1, -1)/)) end function factorial - !> This function calculates a smooth cut-on function that is zero for x values - !! smaller than zero and goes to one. It can be used for generating smooth - !! initial conditions + !> This function calculates a smooth cut-on function that is zero for x values smaller than zero and goes to one. It can be used + !! for generating smooth initial conditions !! @param x is the input value !! @param eps is the smoothing parameter !! @return fx is the cut-on function evaluated at x function f_cut_on(x, eps) result(fx) real(wp), intent(in) :: x, eps - real(wp) :: fx + real(wp) :: fx fx = 1 - f_gx(x/eps)/(f_gx(x/eps) + f_gx(1 - x/eps)) end function f_cut_on - !> This function calculates a smooth cut-off function that is one for x values - !! smaller than zero and goes to zero. It can be used for generating smooth - !! initial conditions + !> This function calculates a smooth cut-off function that is one for x values smaller than zero and goes to zero. It can be + !! used for generating smooth initial conditions !! @param x is the input value !! @param eps is the smoothing parameter !! @return fx is the cut-ff function evaluated at x function f_cut_off(x, eps) result(fx) real(wp), intent(in) :: x, eps - real(wp) :: fx + real(wp) :: fx fx = f_gx(x/eps)/(f_gx(x/eps) + f_gx(1 - x/eps)) @@ -653,7 +598,7 @@ contains function f_gx(x) result(gx) real(wp), intent(in) :: x - real(wp) :: gx + real(wp) :: gx if (x > 0) then gx = exp(-1._wp/x) @@ -669,8 +614,8 @@ contains type(scalar_field), dimension(sys_size), intent(inout) :: q_cons_vf, q_cons_temp ! Down sampling variables - integer :: i, j, k, l - integer :: ix, iy, iz, x_id, y_id, z_id + integer :: i, j, k, l + integer :: ix, iy, iz, x_id, y_id, z_id integer, intent(inout) :: m_ds, n_ds, p_ds, m_glb_ds, n_glb_ds, p_glb_ds m_ds = int((m + 1)/3) - 1 @@ -693,8 +638,8 @@ contains do iz = -1, 1 do iy = -1, 1 do ix = -1, 1 - q_cons_temp(i)%sf(j, k, l) = q_cons_temp(i)%sf(j, k, l) & - + (1._wp/27._wp)*q_cons_vf(i)%sf(x_id + ix, y_id + iy, z_id + iz) + q_cons_temp(i)%sf(j, k, l) = q_cons_temp(i)%sf(j, k, & + & l) + (1._wp/27._wp)*q_cons_vf(i)%sf(x_id + ix, y_id + iy, z_id + iz) end do end do end do @@ -709,16 +654,15 @@ contains subroutine s_upsample_data(q_cons_vf, q_cons_temp) type(scalar_field), intent(inout), dimension(sys_size) :: q_cons_vf, q_cons_temp - integer :: i, j, k, l - integer :: ix, iy, iz - integer :: x_id, y_id, z_id - real(wp), dimension(4) :: temp + integer :: i, j, k, l + integer :: ix, iy, iz + integer :: x_id, y_id, z_id + real(wp), dimension(4) :: temp do l = 0, p do k = 0, n do j = 0, m do i = 1, sys_size - ix = int(j/3._wp) iy = int(k/3._wp) iz = int(l/3._wp) @@ -728,15 +672,17 @@ contains z_id = l - int(3*iz) - 1 temp(1) = (2._wp/3._wp)*q_cons_temp(i)%sf(ix, iy, iz) + (1._wp/3._wp)*q_cons_temp(i)%sf(ix + x_id, iy, iz) - temp(2) = (2._wp/3._wp)*q_cons_temp(i)%sf(ix, iy + y_id, iz) + (1._wp/3._wp)*q_cons_temp(i)%sf(ix + x_id, iy + y_id, iz) + temp(2) = (2._wp/3._wp)*q_cons_temp(i)%sf(ix, iy + y_id, iz) + (1._wp/3._wp)*q_cons_temp(i)%sf(ix + x_id, & + & iy + y_id, iz) temp(3) = (2._wp/3._wp)*temp(1) + (1._wp/3._wp)*temp(2) - temp(1) = (2._wp/3._wp)*q_cons_temp(i)%sf(ix, iy, iz + z_id) + (1._wp/3._wp)*q_cons_temp(i)%sf(ix + x_id, iy, iz + z_id) - temp(2) = (2._wp/3._wp)*q_cons_temp(i)%sf(ix, iy + y_id, iz + z_id) + (1._wp/3._wp)*q_cons_temp(i)%sf(ix + x_id, iy + y_id, iz + z_id) + temp(1) = (2._wp/3._wp)*q_cons_temp(i)%sf(ix, iy, iz + z_id) + (1._wp/3._wp)*q_cons_temp(i)%sf(ix + x_id, & + & iy, iz + z_id) + temp(2) = (2._wp/3._wp)*q_cons_temp(i)%sf(ix, iy + y_id, & + & iz + z_id) + (1._wp/3._wp)*q_cons_temp(i)%sf(ix + x_id, iy + y_id, iz + z_id) temp(4) = (2._wp/3._wp)*temp(1) + (1._wp/3._wp)*temp(2) q_cons_vf(i)%sf(j, k, l) = (2._wp/3._wp)*temp(3) + (1._wp/3._wp)*temp(4) - end do end do end do diff --git a/src/common/m_helper_basic.fpp b/src/common/m_helper_basic.fpp index dcc0a86e69..c4f2599d62 100644 --- a/src/common/m_helper_basic.fpp +++ b/src/common/m_helper_basic.fpp @@ -7,18 +7,13 @@ !> @brief Basic floating-point utilities: approximate equality, default detection, and coordinate bounds module m_helper_basic - use m_derived_types !< Definitions of the derived types + use m_derived_types !< Definitions of the derived types implicit none - private; - public :: f_approx_equal, & - f_approx_in_array, & - f_is_default, & - f_all_default, & - f_is_integer, & - s_configure_coordinate_bounds, & - s_update_cell_bounds + private + public :: f_approx_equal, f_approx_in_array, f_is_default, f_all_default, f_is_integer, s_configure_coordinate_bounds, & + & s_update_cell_bounds contains @@ -28,10 +23,11 @@ contains !! @param tol_input Relative error (default = 1.e-10_wp). !! @return Result of the comparison. logical elemental function f_approx_equal(a, b, tol_input) result(res) + $:GPU_ROUTINE(parallelism='[seq]') - real(wp), intent(in) :: a, b + real(wp), intent(in) :: a, b real(wp), optional, intent(in) :: tol_input - real(wp) :: tol + real(wp) :: tol if (present(tol_input)) then tol = tol_input @@ -46,6 +42,7 @@ contains else res = (abs(a - b)/min(abs(a) + abs(b), huge(a)) < tol) end if + end function f_approx_equal !> This procedure checks if the point numbers of wp belongs to another array are within tolerance. @@ -54,12 +51,13 @@ contains !! @param tol_input Relative error (default = 1e-10_wp). !! @return Result of the comparison. logical function f_approx_in_array(a, b, tol_input) result(res) + $:GPU_ROUTINE(parallelism='[seq]') - real(wp), intent(in) :: a - real(wp), intent(in) :: b(:) + real(wp), intent(in) :: a + real(wp), intent(in) :: b(:) real(wp), optional, intent(in) :: tol_input - real(wp) :: tol - integer :: i + real(wp) :: tol + integer :: i res = .false. @@ -75,69 +73,70 @@ contains exit end if end do + end function f_approx_in_array !> Checks if a real(wp) variable is of default value. !! @param var Variable to check. logical elemental function f_is_default(var) result(res) + $:GPU_ROUTINE(parallelism='[seq]') real(wp), intent(in) :: var res = f_approx_equal(var, dflt_real) + end function f_is_default !> Checks if ALL elements of a real(wp) array are of default value. !! @param var_array Array to check. logical function f_all_default(var_array) result(res) + real(wp), intent(in) :: var_array(:) res = all(f_is_default(var_array)) - !logical :: res_array(size(var_array)) - !integer :: i + ! logical :: res_array(size(var_array)) integer :: i - ! do i = 1, size(var_array) - ! res_array(i) = f_is_default(var_array(i)) - ! end do + ! do i = 1, size(var_array) res_array(i) = f_is_default(var_array(i)) end do ! res = all(res_array) + end function f_all_default !> Checks if a real(wp) variable is an integer. !! @param var Variable to check. logical elemental function f_is_integer(var) result(res) + $:GPU_ROUTINE(parallelism='[seq]') real(wp), intent(in) :: var res = f_approx_equal(var, real(nint(var), wp)) + end function f_is_integer - subroutine s_configure_coordinate_bounds(recon_type, weno_polyn, muscl_polyn, & - igr_order, buff_size, idwint, idwbuff, & - viscous, bubbles_lagrange, m, n, p, num_dims, & - igr, ib, fd_number) + subroutine s_configure_coordinate_bounds(recon_type, weno_polyn, muscl_polyn, igr_order, buff_size, idwint, idwbuff, viscous, & + & bubbles_lagrange, m, n, p, num_dims, igr, ib, fd_number) - integer, intent(in) :: recon_type, weno_polyn, muscl_polyn - integer, intent(in) :: m, n, p, num_dims, igr_order, fd_number - integer, intent(inout) :: buff_size + integer, intent(in) :: recon_type, weno_polyn, muscl_polyn + integer, intent(in) :: m, n, p, num_dims, igr_order, fd_number + integer, intent(inout) :: buff_size type(int_bounds_info), dimension(3), intent(inout) :: idwint, idwbuff - logical, intent(in) :: viscous, bubbles_lagrange - logical, intent(in) :: igr - logical, intent(in) :: ib - - ! Determining the number of cells that are needed in order to store - ! sufficient boundary conditions data as to iterate the solution in - ! the physical computational domain from one time-step iteration to - ! the next one + logical, intent(in) :: viscous, bubbles_lagrange + logical, intent(in) :: igr + logical, intent(in) :: ib + + ! Determining the number of cells that are needed in order to store sufficient boundary conditions data as to iterate the + ! solution in the physical computational domain from one time-step iteration to the next one + if (igr) then buff_size = (igr_order - 1)/2 + 2 - elseif (recon_type == WENO_TYPE) then + else if (recon_type == WENO_TYPE) then if (viscous) then buff_size = 2*weno_polyn + 2 else buff_size = weno_polyn + 2 end if - elseif (recon_type == MUSCL_TYPE) then + else if (recon_type == MUSCL_TYPE) then buff_size = muscl_polyn + 2 end if @@ -170,8 +169,9 @@ contains !! @param n Number of cells in y-axis !! @param p Number of cells in z-axis elemental subroutine s_update_cell_bounds(bounds, m, n, p) + type(cell_num_bounds), intent(out) :: bounds - integer, intent(in) :: m, n, p + integer, intent(in) :: m, n, p bounds%mn_max = max(m, n) bounds%np_max = max(n, p) diff --git a/src/common/m_model.fpp b/src/common/m_model.fpp index 9683f4caac..2c297ebe8e 100644 --- a/src/common/m_model.fpp +++ b/src/common/m_model.fpp @@ -11,20 +11,18 @@ module m_model use m_helper use m_mpi_proxy use m_derived_types - use iso_c_binding, only: c_char, c_int32_t, c_int16_t, c_float implicit none private - public :: f_model_read, s_model_write, s_model_free, f_model_is_inside, models, gpu_ntrs, & - gpu_trs_v, gpu_trs_n, gpu_boundary_v, gpu_boundary_edge_count, & - gpu_total_vertices, stl_bounding_boxes + public :: f_model_read, s_model_write, s_model_free, f_model_is_inside, models, gpu_ntrs, gpu_trs_v, gpu_trs_n, & + & gpu_boundary_v, gpu_boundary_edge_count, gpu_total_vertices, stl_bounding_boxes ! Subroutines for STL immersed boundaries - public :: s_check_boundary, s_register_edge, f_model_is_inside_flat, & - s_distance_normals_3D, s_distance_normals_2D, s_pack_model_for_gpu + public :: s_check_boundary, s_register_edge, f_model_is_inside_flat, s_distance_normals_3D, s_distance_normals_2D, & + & s_pack_model_for_gpu #ifdef MFC_SIMULATION public :: s_instantiate_STL_models @@ -33,14 +31,14 @@ module m_model !! array of STL models that can be allocated and then used in IB marker and levelset compute type(t_model_array), allocatable, target :: models(:) !! GPU-friendly flat arrays for STL model data - integer, allocatable :: gpu_ntrs(:) - real(wp), allocatable, dimension(:, :, :, :) :: gpu_trs_v - real(wp), allocatable, dimension(:, :, :) :: gpu_trs_n - real(wp), allocatable, dimension(:, :, :, :) :: gpu_boundary_v - integer, allocatable :: gpu_boundary_edge_count(:) - integer, allocatable :: gpu_total_vertices(:) - real(wp), allocatable :: stl_bounding_boxes(:, :, :) - $:GPU_DECLARE(create='[gpu_ntrs,gpu_trs_v,gpu_trs_n,gpu_boundary_v,gpu_boundary_edge_count,gpu_total_vertices]') + integer, allocatable :: gpu_ntrs(:) + real(wp), allocatable, dimension(:,:,:,:) :: gpu_trs_v + real(wp), allocatable, dimension(:,:,:) :: gpu_trs_n + real(wp), allocatable, dimension(:,:,:,:) :: gpu_boundary_v + integer, allocatable :: gpu_boundary_edge_count(:) + integer, allocatable :: gpu_total_vertices(:) + real(wp), allocatable :: stl_bounding_boxes(:,:,:) + $:GPU_DECLARE(create='[gpu_ntrs, gpu_trs_v, gpu_trs_n, gpu_boundary_v, gpu_boundary_edge_count, gpu_total_vertices]') contains @@ -49,20 +47,15 @@ contains !! @param model The binary of the STL file. impure subroutine s_read_stl_binary(filepath, model) - character(LEN=*), intent(in) :: filepath - type(t_model), intent(out) :: model - - integer :: i, iunit, iostat - + character(LEN=*), intent(in) :: filepath + type(t_model), intent(out) :: model + integer :: i, iunit, iostat character(kind=c_char, len=80) :: header - integer(kind=c_int32_t) :: nTriangles + integer(kind=c_int32_t) :: nTriangles + real(kind=c_float) :: normal(3), v(3, 3), v_norm + integer(kind=c_int16_t) :: attribute - real(kind=c_float) :: normal(3), v(3, 3), v_norm - integer(kind=c_int16_t) :: attribute - - open (newunit=iunit, file=filepath, action='READ', & - form='UNFORMATTED', status='OLD', iostat=iostat, & - access='STREAM') + open (newunit=iunit, file=filepath, action='READ', form='UNFORMATTED', status='OLD', iostat=iostat, access='STREAM') if (iostat /= 0) then print *, "Error: could not open Binary STL file ", filepath @@ -83,7 +76,7 @@ contains allocate (model%trs(model%ntrs)) do i = 1, model%ntrs - read (iunit) normal(:), v(1, :), v(2, :), v(3, :), attribute + read (iunit) normal(:), v(1,:), v(2,:), v(3,:), attribute model%trs(i)%v = v model%trs(i)%n = normal @@ -99,19 +92,17 @@ contains !! @param filepath Path to the STL file. !! @param model the STL file. impure subroutine s_read_stl_ascii(filepath, model) - character(LEN=*), intent(in) :: filepath - type(t_model), intent(out) :: model - integer :: i, j, iunit, iostat - character(80) :: line, buffered_line - logical :: is_buffered - real(wp) :: normal(3), v_norm + character(LEN=*), intent(in) :: filepath + type(t_model), intent(out) :: model + integer :: i, j, iunit, iostat + character(80) :: line, buffered_line + logical :: is_buffered + real(wp) :: normal(3), v_norm is_buffered = .false. - open (newunit=iunit, file=filepath, action='READ', & - form='FORMATTED', status='OLD', iostat=iostat, & - access='STREAM') + open (newunit=iunit, file=filepath, action='READ', form='FORMATTED', status='OLD', iostat=iostat, access='STREAM') if (iostat /= 0) then print *, "Error: could not open ASCII STL file ", filepath @@ -180,7 +171,7 @@ contains end if call s_skip_ignored_lines(iunit, buffered_line, is_buffered) - read (line(7:), *) model%trs(i)%v(j, :) + read (line(7:), *) model%trs(i)%v(j,:) end do if (is_buffered) then @@ -204,6 +195,7 @@ contains i = i + 1 end do + end subroutine s_read_stl_ascii !> This procedure reads an STL file. @@ -212,15 +204,11 @@ contains impure subroutine s_read_stl(filepath, model) character(LEN=*), intent(in) :: filepath - type(t_model), intent(out) :: model - - integer :: iunit, iostat + type(t_model), intent(out) :: model + integer :: iunit, iostat + character(80) :: line - character(80) :: line - - open (newunit=iunit, file=filepath, action='READ', & - form='FORMATTED', status='OLD', iostat=iostat, & - access='STREAM') + open (newunit=iunit, file=filepath, action='READ', form='FORMATTED', status='OLD', iostat=iostat, access='STREAM') if (iostat /= 0) then print *, "Error: could not open STL file ", filepath @@ -245,18 +233,13 @@ contains !! @param model The obj file. impure subroutine s_read_obj(filepath, model) - character(LEN=*), intent(in) :: filepath - type(t_model), intent(out) :: model - - integer :: i, j, k, l, iv3, iunit, iostat, nVertices - - real(wp), dimension(1:3), allocatable :: vertices(:, :) - - character(80) :: line + character(LEN=*), intent(in) :: filepath + type(t_model), intent(out) :: model + integer :: i, j, k, l, iv3, iunit, iostat, nVertices + real(wp), dimension(1:3), allocatable :: vertices(:,:) + character(80) :: line - open (newunit=iunit, file=filepath, action='READ', & - form='FORMATTED', status='OLD', iostat=iostat, & - access='STREAM') + open (newunit=iunit, file=filepath, action='READ', form='FORMATTED', status='OLD', iostat=iostat, access='STREAM') if (iostat /= 0) then print *, "Error: could not open model file ", filepath @@ -279,7 +262,7 @@ contains rewind (iunit) - allocate (vertices(nVertices, 1:3)) + allocate (vertices(nVertices,1:3)) allocate (model%trs(model%ntrs)) i = 1 @@ -294,13 +277,13 @@ contains case ("vt") case ("l ") case ("v ") - read (line(3:), *) vertices(i, :) + read (line(3:), *) vertices(i,:) i = i + 1 case ("f ") read (line(3:), *) k, l, iv3 - model%trs(j)%v(1, :) = vertices(k, :) - model%trs(j)%v(2, :) = vertices(l, :) - model%trs(j)%v(3, :) = vertices(iv3, :) + model%trs(j)%v(1,:) = vertices(k,:) + model%trs(j)%v(2,:) = vertices(l,:) + model%trs(j)%v(3,:) = vertices(iv3,:) j = j + 1 case default print *, "Error: unknown line type in OBJ file ", filepath @@ -322,8 +305,7 @@ contains impure function f_model_read(filepath) result(model) character(LEN=*), intent(in) :: filepath - - type(t_model) :: model + type(t_model) :: model select case (filepath(len(trim(filepath)) - 3:len(trim(filepath)))) case (".stl") @@ -343,18 +325,15 @@ contains !! @param model STL to write impure subroutine s_write_stl(filepath, model) - character(LEN=*), intent(in) :: filepath - type(t_model), intent(in) :: model - - integer :: i, j, iunit, iostat - + character(LEN=*), intent(in) :: filepath + type(t_model), intent(in) :: model + integer :: i, j, iunit, iostat character(kind=c_char, len=80), parameter :: header = "Model file written by MFC." - integer(kind=c_int32_t) :: nTriangles - real(wp) :: normal(3), v(3) - integer(kind=c_int16_t) :: attribute + integer(kind=c_int32_t) :: nTriangles + real(wp) :: normal(3), v(3) + integer(kind=c_int16_t) :: attribute - open (newunit=iunit, file=filepath, action='WRITE', & - form='UNFORMATTED', iostat=iostat, access='STREAM') + open (newunit=iunit, file=filepath, action='WRITE', form='UNFORMATTED', iostat=iostat, access='STREAM') if (iostat /= 0) then print *, "Error: could not open STL file ", filepath @@ -376,7 +355,7 @@ contains write (iunit) normal do j = 1, 3 - v = model%trs(i)%v(j, :) + v = model%trs(i)%v(j,:) write (iunit) v(:) end do @@ -394,14 +373,11 @@ contains impure subroutine s_write_obj(filepath, model) character(LEN=*), intent(in) :: filepath - type(t_model), intent(in) :: model - - integer :: iunit, iostat + type(t_model), intent(in) :: model + integer :: iunit, iostat + integer :: i, j - integer :: i, j - - open (newunit=iunit, file=filepath, action='WRITE', & - form='FORMATTED', iostat=iostat, access='STREAM') + open (newunit=iunit, file=filepath, action='WRITE', form='FORMATTED', iostat=iostat, access='STREAM') if (iostat /= 0) then print *, "Error: could not open OBJ file ", filepath @@ -413,12 +389,11 @@ contains do i = 1, model%ntrs do j = 1, 3 - write (iunit, '(A, " ", (f30.20), " ", (f30.20), " ", (f30.20))') & - "v", model%trs(i)%v(j, 1), model%trs(i)%v(j, 2), model%trs(i)%v(j, 3) + write (iunit, '(A, " ", (f30.20), " ", (f30.20), " ", (f30.20))') "v", model%trs(i)%v(j, 1), model%trs(i)%v(j, & + & 2), model%trs(i)%v(j, 3) end do - write (iunit, '(A, " ", I0, " ", I0, " ", I0)') & - "f", i*3 - 2, i*3 - 1, i*3 + write (iunit, '(A, " ", I0, " ", I0, " ", I0)') "f", i*3 - 2, i*3 - 1, i*3 end do close (iunit) @@ -431,7 +406,7 @@ contains impure subroutine s_model_write(filepath, model) character(LEN=*), intent(in) :: filepath - type(t_model), intent(in) :: model + type(t_model), intent(in) :: model select case (filepath(len(trim(filepath)) - 3:len(trim(filepath)))) case (".stl") @@ -457,11 +432,10 @@ contains impure function f_read_line(iunit, line) result(bIsLine) - integer, intent(in) :: iunit + integer, intent(in) :: iunit character(80), intent(out) :: line - - logical :: bIsLine - integer :: iostat + logical :: bIsLine + integer :: iostat bIsLine = .true. @@ -486,11 +460,11 @@ contains !> @brief Reads the next non-comment line from a model file, using a buffered look-ahead mechanism. impure subroutine s_skip_ignored_lines(iunit, buffered_line, is_buffered) - integer, intent(in) :: iunit - character(80), intent(inout) :: buffered_line - logical, intent(inout) :: is_buffered - character(80) :: line + integer, intent(in) :: iunit + character(80), intent(inout) :: buffered_line + logical, intent(inout) :: is_buffered + character(80) :: line if (is_buffered) then line = buffered_line @@ -501,23 +475,24 @@ contains buffered_line = line is_buffered = .true. + end subroutine s_skip_ignored_lines - !> This function is used to replace the fortran random number - !! generator because the native generator is not compatible being called - !! from GPU routines/functions + !> This function is used to replace the fortran random number generator because the native generator is not compatible being + !! called from GPU routines/functions function f_model_random_number(seed) result(rval) ! $:GPU_ROUTINE(parallelism='[seq]') integer, intent(inout) :: seed - real(wp) :: rval + real(wp) :: rval seed = ieor(seed, ishft(seed, 13)) seed = ieor(seed, ishft(seed, -17)) seed = ieor(seed, ishft(seed, 5)) rval = abs(real(seed, wp))/real(huge(seed), wp) + end function f_model_random_number !> This procedure, recursively, finds whether a point is inside an octree. @@ -530,23 +505,18 @@ contains ! $:GPU_ROUTINE(parallelism='[seq]') - type(t_model), intent(in) :: model + type(t_model), intent(in) :: model real(wp), dimension(1:3), intent(in) :: point real(wp), dimension(1:3), intent(in) :: spacing - integer, intent(in) :: spc - real(wp) :: phi, theta - integer :: rand_seed - - real(wp) :: fraction - - type(t_ray) :: ray - integer :: i, j, k, nInOrOut, nHits - - real(wp), dimension(1:spc, 1:3) :: ray_origins, ray_dirs - - rand_seed = int(point(1)*73856093._wp) + & - int(point(2)*19349663._wp) + & - int(point(3)*83492791._wp) + integer, intent(in) :: spc + real(wp) :: phi, theta + integer :: rand_seed + real(wp) :: fraction + type(t_ray) :: ray + integer :: i, j, k, nInOrOut, nHits + real(wp), dimension(1:spc,1:3) :: ray_origins, ray_dirs + + rand_seed = int(point(1)*73856093._wp) + int(point(2)*19349663._wp) + int(point(3)*83492791._wp) if (rand_seed == 0) rand_seed = 1 ! generate our random collection or rays @@ -557,14 +527,14 @@ contains ! cast sample rays in all directions ray_dirs(i, k) = f_model_random_number(rand_seed) - 0.5_wp end do - ray_dirs(i, :) = ray_dirs(i, :)/sqrt(sum(ray_dirs(i, :)*ray_dirs(i, :))) + ray_dirs(i,:) = ray_dirs(i,:)/sqrt(sum(ray_dirs(i,:)*ray_dirs(i,:))) end do ! ray trace nInOrOut = 0 do i = 1, spc - ray%o = ray_origins(i, :) - ray%d = ray_dirs(i, :) + ray%o = ray_origins(i,:) + ray%d = ray_dirs(i,:) nHits = 0 do j = 1, model%ntrs @@ -574,8 +544,7 @@ contains end if end do - ! if the ray hits an odd number of triangles on its way out, then - ! it must be on the inside of the model + ! if the ray hits an odd number of triangles on its way out, then it must be on the inside of the model nInOrOut = nInOrOut + mod(nHits, 2) end do @@ -583,12 +552,9 @@ contains end function f_model_is_inside - !> This procedure determines if a point is inside a surface using - !! the generalized winding number (Jacobson et al., SIGGRAPH 2013). - !! In 3D, sums the solid angle subtended by each triangle (Van - !! Oosterom-Strackee formula). In 2D (p==0), sums the signed - !! angle subtended by each boundary edge. Returns ~1.0 inside, - !! ~0.0 outside. Unlike ray casting, this is robust to small + !> This procedure determines if a point is inside a surface using the generalized winding number (Jacobson et al., SIGGRAPH + !! 2013). In 3D, sums the solid angle subtended by each triangle (Van Oosterom-Strackee formula). In 2D (p==0), sums the signed + !! angle subtended by each boundary edge. Returns ~1.0 inside, ~0.0 outside. Unlike ray casting, this is robust to small !! triangles/edges and vertex winding order. !! @param ntrs Number of triangles in the model. !! @param pid Patch ID of this model. @@ -598,23 +564,20 @@ contains $:GPU_ROUTINE(parallelism='[seq]') - integer, intent(in) :: ntrs - integer, intent(in) :: pid + integer, intent(in) :: ntrs + integer, intent(in) :: pid real(wp), dimension(1:3), intent(in) :: point - - real(wp) :: fraction - - real(wp) :: r1(3), r2(3), r3(3) - real(wp) :: r1_mag, r2_mag, r3_mag - real(wp) :: numerator, denominator - real(wp) :: d1(2), d2(2) - integer :: q + real(wp) :: fraction + real(wp) :: r1(3), r2(3), r3(3) + real(wp) :: r1_mag, r2_mag, r3_mag + real(wp) :: numerator, denominator + real(wp) :: d1(2), d2(2) + integer :: q fraction = 0.0_wp if (p == 0) then - ! 2D winding number: sum signed angles subtended by - ! each boundary edge at the query point. + ! 2D winding number: sum signed angles subtended by each boundary edge at the query point. do q = 1, gpu_boundary_edge_count(pid) d1(1) = gpu_boundary_v(q, 1, 1, pid) - point(1) d1(2) = gpu_boundary_v(q, 1, 2, pid) - point(2) @@ -622,54 +585,43 @@ contains d2(2) = gpu_boundary_v(q, 2, 2, pid) - point(2) ! Signed angle = atan2(d1 x d2, d1 . d2) - fraction = fraction + atan2( & - d1(1)*d2(2) - d1(2)*d2(1), & - d1(1)*d2(1) + d1(2)*d2(2)) + fraction = fraction + atan2(d1(1)*d2(2) - d1(2)*d2(1), d1(1)*d2(1) + d1(2)*d2(2)) end do ! 2D winding number = total angle / (2*pi) fraction = fraction/(2.0_wp*acos(-1.0_wp)) else - ! 3D winding number: sum solid angles via Van - ! Oosterom-Strackee formula. + ! 3D winding number: sum solid angles via Van Oosterom-Strackee formula. do q = 1, ntrs - r1 = gpu_trs_v(1, :, q, pid) - point - r2 = gpu_trs_v(2, :, q, pid) - point - r3 = gpu_trs_v(3, :, q, pid) - point + r1 = gpu_trs_v(1,:,q, pid) - point + r2 = gpu_trs_v(2,:,q, pid) - point + r3 = gpu_trs_v(3,:,q, pid) - point r1_mag = sqrt(dot_product(r1, r1)) r2_mag = sqrt(dot_product(r2, r2)) r3_mag = sqrt(dot_product(r3, r3)) - ! Skip if query point is coincident with a vertex - ! (magnitudes are zero/subnormal). + ! Skip if query point is coincident with a vertex (magnitudes are zero/subnormal). if (r1_mag*r2_mag*r3_mag < tiny(1.0_wp)) cycle - ! tan(Omega/2) = numerator / denominator - ! numerator = scalar triple product r1 . (r2 x r3) - numerator = r1(1)*(r2(2)*r3(3) - r2(3)*r3(2)) & - + r1(2)*(r2(3)*r3(1) - r2(1)*r3(3)) & - + r1(3)*(r2(1)*r3(2) - r2(2)*r3(1)) + ! tan(Omega/2) = numerator / denominator numerator = scalar triple product r1 . (r2 x r3) + numerator = r1(1)*(r2(2)*r3(3) - r2(3)*r3(2)) + r1(2)*(r2(3)*r3(1) - r2(1)*r3(3)) + r1(3)*(r2(1)*r3(2) - r2(2) & + & *r3(1)) - denominator = r1_mag*r2_mag*r3_mag & - + dot_product(r1, r2)*r3_mag & - + dot_product(r2, r3)*r1_mag & - + dot_product(r3, r1)*r2_mag + denominator = r1_mag*r2_mag*r3_mag + dot_product(r1, r2)*r3_mag + dot_product(r2, r3)*r1_mag + dot_product(r3, & + & r1)*r2_mag fraction = fraction + atan2(numerator, denominator) end do - ! Each atan2 returns Omega/2 per triangle; divide - ! by 2*pi to get winding number = sum(Omega)/(4*pi). + ! Each atan2 returns Omega/2 per triangle; divide by 2*pi to get winding number = sum(Omega)/(4*pi). fraction = fraction/(2.0_wp*acos(-1.0_wp)) end if end function f_model_is_inside_flat - !> This procedure checks if a ray intersects a triangle using the - !! Moller-Trumbore algorithm (barycentric coordinates). Unlike the - !! previous cross-product sign test, this is vertex winding-order - !! independent. + !> This procedure checks if a ray intersects a triangle using the Moller-Trumbore algorithm (barycentric coordinates). Unlike + !! the previous cross-product sign test, this is vertex winding-order independent. !! @param ray Ray. !! @param triangle Triangle. !! @return 1 if the ray intersects the triangle, 0 otherwise. @@ -677,27 +629,24 @@ contains $:GPU_ROUTINE(parallelism='[seq]') - type(t_ray), intent(in) :: ray + type(t_ray), intent(in) :: ray type(t_triangle), intent(in) :: triangle - - integer :: intersects - - real(wp) :: edge1(3), edge2(3), h(3), s(3), q(3) - real(wp) :: a, f, u, v, t + integer :: intersects + real(wp) :: edge1(3), edge2(3), h(3), s(3), q(3) + real(wp) :: a, f, u, v, t intersects = 0 - edge1 = triangle%v(2, :) - triangle%v(1, :) - edge2 = triangle%v(3, :) - triangle%v(1, :) + edge1 = triangle%v(2,:) - triangle%v(1,:) + edge2 = triangle%v(3,:) - triangle%v(1,:) h = f_cross(ray%d, edge2) a = dot_product(edge1, h) - ! Ray nearly parallel to triangle plane. In single precision - ! builds epsilon(1.0) ~ 1.2e-7, so use 10*epsilon as a floor. + ! Ray nearly parallel to triangle plane. In single precision builds epsilon(1.0) ~ 1.2e-7, so use 10*epsilon as a floor. if (abs(a) < max(1e-7_wp, 10.0_wp*epsilon(1.0_wp))) return f = 1.0_wp/a - s = ray%o - triangle%v(1, :) + s = ray%o - triangle%v(1,:) u = f*dot_product(s, h) if (u < 0.0_wp .or. u > 1.0_wp) return @@ -719,18 +668,18 @@ contains subroutine s_check_boundary(model, boundary_v, boundary_vertex_count, boundary_edge_count) type(t_model), intent(in) :: model - real(wp), allocatable, intent(out), dimension(:, :, :) :: boundary_v !< Output boundary vertices/normals - integer, intent(out) :: boundary_vertex_count, boundary_edge_count !< Output boundary vertex/edge count - - integer :: i, j !< Model index iterator - integer :: edge_count, edge_index, store_index !< Boundary edge index iterator - real(wp), dimension(1:2, 1:2) :: edge !< Edge end points buffer - real(wp), dimension(1:2) :: boundary_edge !< Boundary edge end points buffer - real(wp), dimension(1:(3*model%ntrs), 1:2, 1:2) :: temp_boundary_v !< Temporary boundary vertex buffer - integer, dimension(1:(3*model%ntrs)) :: edge_occurrence !< The manifoldness of the edges - real(wp) :: edgetan, initial, v_norm, xnormal, ynormal !< The manifoldness of the edges + real(wp), allocatable, intent(out), dimension(:,:,:) :: boundary_v !< Output boundary vertices/normals + integer, intent(out) :: boundary_vertex_count, boundary_edge_count !< Output boundary vertex/edge count + integer :: i, j !< Model index iterator + integer :: edge_count, edge_index, store_index !< Boundary edge index iterator + real(wp), dimension(1:2,1:2) :: edge !< Edge end points buffer + real(wp), dimension(1:2) :: boundary_edge !< Boundary edge end points buffer + real(wp), dimension(1:(3*model%ntrs),1:2,1:2) :: temp_boundary_v !< Temporary boundary vertex buffer + integer, dimension(1:(3*model%ntrs)) :: edge_occurrence !< The manifoldness of the edges + real(wp) :: edgetan, initial, v_norm, xnormal, ynormal !< The manifoldness of the edges ! Total number of edges in 2D STL + edge_count = 3*model%ntrs ! Initialize edge_occurrence array to zero @@ -740,35 +689,35 @@ contains ! Collect all edges of all triangles and store them do i = 1, model%ntrs ! First edge (v1, v2) - edge(1, 1:2) = model%trs(i)%v(1, 1:2) - edge(2, 1:2) = model%trs(i)%v(2, 1:2) + edge(1,1:2) = model%trs(i)%v(1,1:2) + edge(2,1:2) = model%trs(i)%v(2,1:2) call s_register_edge(temp_boundary_v, edge, edge_index, edge_count) ! Second edge (v2, v3) - edge(1, 1:2) = model%trs(i)%v(2, 1:2) - edge(2, 1:2) = model%trs(i)%v(3, 1:2) + edge(1,1:2) = model%trs(i)%v(2,1:2) + edge(2,1:2) = model%trs(i)%v(3,1:2) call s_register_edge(temp_boundary_v, edge, edge_index, edge_count) ! Third edge (v3, v1) - edge(1, 1:2) = model%trs(i)%v(3, 1:2) - edge(2, 1:2) = model%trs(i)%v(1, 1:2) + edge(1,1:2) = model%trs(i)%v(3,1:2) + edge(2,1:2) = model%trs(i)%v(1,1:2) call s_register_edge(temp_boundary_v, edge, edge_index, edge_count) end do ! Check all edges and count repeated edges - $:GPU_PARALLEL_LOOP(private='[i,j]', copy='[temp_boundary_v,edge_occurrence]', collapse=2) + $:GPU_PARALLEL_LOOP(private='[i, j]', copy='[temp_boundary_v, edge_occurrence]', collapse=2) do i = 1, edge_count do j = 1, edge_count if (i /= j) then - if (((abs(temp_boundary_v(i, 1, 1) - temp_boundary_v(j, 1, 1)) < threshold_edge_zero) .and. & - (abs(temp_boundary_v(i, 1, 2) - temp_boundary_v(j, 1, 2)) < threshold_edge_zero) .and. & - (abs(temp_boundary_v(i, 2, 1) - temp_boundary_v(j, 2, 1)) < threshold_edge_zero) .and. & - (abs(temp_boundary_v(i, 2, 2) - temp_boundary_v(j, 2, 2)) < threshold_edge_zero)) .or. & - ((abs(temp_boundary_v(i, 1, 1) - temp_boundary_v(j, 2, 1)) < threshold_edge_zero) .and. & - (abs(temp_boundary_v(i, 1, 2) - temp_boundary_v(j, 2, 2)) < threshold_edge_zero) .and. & - (abs(temp_boundary_v(i, 2, 1) - temp_boundary_v(j, 1, 1)) < threshold_edge_zero) .and. & - (abs(temp_boundary_v(i, 2, 2) - temp_boundary_v(j, 1, 2)) < threshold_edge_zero))) then - + if (((abs(temp_boundary_v(i, 1, 1) - temp_boundary_v(j, 1, & + & 1)) < threshold_edge_zero) .and. (abs(temp_boundary_v(i, 1, 2) - temp_boundary_v(j, 1, & + & 2)) < threshold_edge_zero) .and. (abs(temp_boundary_v(i, 2, 1) - temp_boundary_v(j, 2, & + & 1)) < threshold_edge_zero) .and. (abs(temp_boundary_v(i, 2, 2) - temp_boundary_v(j, 2, & + & 2)) < threshold_edge_zero)) .or. ((abs(temp_boundary_v(i, 1, 1) - temp_boundary_v(j, 2, & + & 1)) < threshold_edge_zero) .and. (abs(temp_boundary_v(i, 1, 2) - temp_boundary_v(j, 2, & + & 2)) < threshold_edge_zero) .and. (abs(temp_boundary_v(i, 2, 1) - temp_boundary_v(j, 1, & + & 1)) < threshold_edge_zero) .and. (abs(temp_boundary_v(i, 2, 2) - temp_boundary_v(j, 1, & + & 2)) < threshold_edge_zero))) then $:GPU_ATOMIC(atomic='update') edge_occurrence(i) = edge_occurrence(i) + 1 end if @@ -789,15 +738,15 @@ contains end do ! Allocate the boundary_v array based on the number of boundary edges - allocate (boundary_v(boundary_edge_count, 1:3, 1:2)) + allocate (boundary_v(boundary_edge_count,1:3,1:2)) ! Store boundary vertices store_index = 0 do i = 1, edge_count if (edge_occurrence(i) == 0) then store_index = store_index + 1 - boundary_v(store_index, 1, 1:2) = temp_boundary_v(i, 1, 1:2) - boundary_v(store_index, 2, 1:2) = temp_boundary_v(i, 2, 1:2) + boundary_v(store_index, 1,1:2) = temp_boundary_v(i, 1,1:2) + boundary_v(store_index, 2,1:2) = temp_boundary_v(i, 2,1:2) end if end do @@ -831,20 +780,21 @@ contains !> This procedure appends the edge end vertices to a temporary buffer. subroutine s_register_edge(temp_boundary_v, edge, edge_index, edge_count) - integer, intent(inout) :: edge_index !< Edge index iterator - integer, intent(inout) :: edge_count !< Total number of edges - real(wp), intent(in), dimension(1:2, 1:2) :: edge !< Edges end points to be registered - real(wp), dimension(1:edge_count, 1:2, 1:2), intent(inout) :: temp_boundary_v !< Temporary edge end vertex buffer + integer, intent(inout) :: edge_index !< Edge index iterator + integer, intent(inout) :: edge_count !< Total number of edges + real(wp), intent(in), dimension(1:2,1:2) :: edge !< Edges end points to be registered + real(wp), dimension(1:edge_count,1:2,1:2), intent(inout) :: temp_boundary_v !< Temporary edge end vertex buffer ! Increment edge index and store the edge + edge_index = edge_index + 1 - temp_boundary_v(edge_index, 1, 1:2) = edge(1, 1:2) - temp_boundary_v(edge_index, 2, 1:2) = edge(2, 1:2) + temp_boundary_v(edge_index, 1,1:2) = edge(1,1:2) + temp_boundary_v(edge_index, 2,1:2) = edge(2,1:2) end subroutine s_register_edge - !> This procedure determines the levelset distance and normals of 3D models - !! by computing the exact closest point via projection onto triangle surfaces. + !> This procedure determines the levelset distance and normals of 3D models by computing the exact closest point via projection + !! onto triangle surfaces. !! @param ntrs Number of triangles for this patch !! @param trs_v Flat GPU array of triangle vertices for all patches !! @param trs_n Flat GPU array of triangle normals for all patches @@ -853,41 +803,41 @@ contains !! @param normals Output levelset normals !! @param distance Output levelset distance subroutine s_distance_normals_3D(ntrs, pid, point, normals, distance) + $:GPU_ROUTINE(parallelism='[seq]') - integer, intent(in) :: ntrs - integer, intent(in) :: pid - real(wp), dimension(1:3), intent(in) :: point + integer, intent(in) :: ntrs + integer, intent(in) :: pid + real(wp), dimension(1:3), intent(in) :: point real(wp), dimension(1:3), intent(out) :: normals - real(wp), intent(out) :: distance - - integer :: i, j, l - real(wp) :: dist_min, dist_proj, dist_v, dist_e, t - real(wp) :: v1(1:3), v2(1:3), v3(1:3) - real(wp) :: e0(1:3), e1(1:3), pv(1:3) - real(wp) :: n(1:3), proj(1:3), norm_vec(1:3) - real(wp) :: d, ndot, denom, norm_mag - real(wp) :: u, v_bary, w - real(wp) :: l00, l01, l11, l20, l21 - real(wp) :: edge(1:3), pe(1:3) - real(wp) :: verts(1:3, 1:3) + real(wp), intent(out) :: distance + integer :: i, j, l + real(wp) :: dist_min, dist_proj, dist_v, dist_e, t + real(wp) :: v1(1:3), v2(1:3), v3(1:3) + real(wp) :: e0(1:3), e1(1:3), pv(1:3) + real(wp) :: n(1:3), proj(1:3), norm_vec(1:3) + real(wp) :: d, ndot, denom, norm_mag + real(wp) :: u, v_bary, w + real(wp) :: l00, l01, l11, l20, l21 + real(wp) :: edge(1:3), pe(1:3) + real(wp) :: verts(1:3,1:3) dist_min = initial_distance_buffer normals = 0._wp do i = 1, ntrs ! Triangle vertices - v1(:) = gpu_trs_v(1, :, i, pid) - v2(:) = gpu_trs_v(2, :, i, pid) - v3(:) = gpu_trs_v(3, :, i, pid) + v1(:) = gpu_trs_v(1,:,i, pid) + v2(:) = gpu_trs_v(2,:,i, pid) + v3(:) = gpu_trs_v(3,:,i, pid) ! Triangle normal - n(:) = gpu_trs_n(:, i, pid) + n(:) = gpu_trs_n(:,i, pid) ! Project point onto triangle plane pv(:) = point(:) - v1(:) d = dot_product(pv, n) - if (abs(d) >= dist_min) cycle ! minimum distance is not small enough, no need to check validity + if (abs(d) >= dist_min) cycle ! minimum distance is not small enough, no need to check validity proj(:) = point(:) - d*n(:) ! Check if projection is inside triangle using barycentric coordinates @@ -916,9 +866,7 @@ contains ! If projection is inside triangle if (u >= 0._wp .and. v_bary >= 0._wp .and. w >= 0._wp) then - dist_proj = sqrt((point(1) - proj(1))**2 + & - (point(2) - proj(2))**2 + & - (point(3) - proj(3))**2) + dist_proj = sqrt((point(1) - proj(1))**2 + (point(2) - proj(2))**2 + (point(3) - proj(3))**2) if (dist_proj < dist_min) then dist_min = dist_proj @@ -926,22 +874,20 @@ contains end if else ! Projection outside triangle: check edges and vertices - verts(:, 1) = v1(:) - verts(:, 2) = v2(:) - verts(:, 3) = v3(:) + verts(:,1) = v1(:) + verts(:,2) = v2(:) + verts(:,3) = v3(:) ! Check three edges do j = 1, 3 - edge(:) = verts(:, mod(j, 3) + 1) - verts(:, j) - pe(:) = point(:) - verts(:, j) + edge(:) = verts(:,mod(j, 3) + 1) - verts(:,j) + pe(:) = point(:) - verts(:,j) t = dot_product(pe, edge)/max(dot_product(edge, edge), 1.e-30_wp) if (t >= 0._wp .and. t <= 1._wp) then - proj(:) = verts(:, j) + t*edge(:) - dist_e = sqrt((point(1) - proj(1))**2 + & - (point(2) - proj(2))**2 + & - (point(3) - proj(3))**2) + proj(:) = verts(:,j) + t*edge(:) + dist_e = sqrt((point(1) - proj(1))**2 + (point(2) - proj(2))**2 + (point(3) - proj(3))**2) if (dist_e < dist_min) then dist_min = dist_e @@ -955,25 +901,22 @@ contains end if end if else if (t < 0._wp) then - dist_v = sqrt((point(1) - verts(1, j))**2 + & - (point(2) - verts(2, j))**2 + & - (point(3) - verts(3, j))**2) + dist_v = sqrt((point(1) - verts(1, j))**2 + (point(2) - verts(2, j))**2 + (point(3) - verts(3, j))**2) if (dist_v < dist_min) then dist_min = dist_v - norm_vec(:) = verts(:, j) - point(:) + norm_vec(:) = verts(:,j) - point(:) norm_mag = sqrt(dot_product(norm_vec, norm_vec)) if (norm_mag > 0._wp) norm_vec = norm_vec/norm_mag normals(:) = norm_vec(:) end if else - dist_v = sqrt((point(1) - verts(1, mod(j, 3) + 1))**2 + & - (point(2) - verts(2, mod(j, 3) + 1))**2 + & - (point(3) - verts(3, mod(j, 3) + 1))**2) + dist_v = sqrt((point(1) - verts(1, mod(j, 3) + 1))**2 + (point(2) - verts(2, mod(j, & + & 3) + 1))**2 + (point(3) - verts(3, mod(j, 3) + 1))**2) if (dist_v < dist_min) then dist_min = dist_v - norm_vec(:) = verts(:, mod(j, 3) + 1) - point(:) + norm_vec(:) = verts(:,mod(j, 3) + 1) - point(:) norm_mag = sqrt(dot_product(norm_vec, norm_vec)) if (norm_mag > 0._wp) norm_vec = norm_vec/norm_mag normals(:) = norm_vec(:) @@ -987,8 +930,8 @@ contains end subroutine s_distance_normals_3D - !> This procedure determines the levelset distance and normals of 2D models - !! by computing the exact closest point via projection onto boundary edges. + !> This procedure determines the levelset distance and normals of 2D models by computing the exact closest point via projection + !! onto boundary edges. !! @param boundary_v Flat GPU array of boundary vertices/normals for all patches !! @param pid Patch index into the boundary_v array !! @param boundary_edge_count Total number of boundary edges for this patch @@ -996,18 +939,18 @@ contains !! @param normals Output levelset normals !! @param distance Output levelset distance subroutine s_distance_normals_2D(pid, boundary_edge_count, point, normals, distance) + $:GPU_ROUTINE(parallelism='[seq]') - integer, intent(in) :: pid - integer, intent(in) :: boundary_edge_count - real(wp), dimension(1:3), intent(in) :: point + integer, intent(in) :: pid + integer, intent(in) :: boundary_edge_count + real(wp), dimension(1:3), intent(in) :: point real(wp), dimension(1:3), intent(out) :: normals - real(wp), intent(out) :: distance - - integer :: i - real(wp) :: dist_min, dist, t, norm_mag - real(wp) :: v1(1:2), v2(1:2), edge(1:2), pv(1:2) - real(wp) :: edge_len_sq, proj(1:2), norm(1:2), c + real(wp), intent(out) :: distance + integer :: i + real(wp) :: dist_min, dist, t, norm_mag + real(wp) :: v1(1:2), v2(1:2), edge(1:2), pv(1:2) + real(wp) :: edge_len_sq, proj(1:2), norm(1:2), c dist_min = initial_distance_buffer normals = 0._wp @@ -1039,12 +982,12 @@ contains dist = sqrt((point(1) - proj(1))**2 + (point(2) - proj(2))**2) norm(1) = gpu_boundary_v(i, 3, 1, pid) norm(2) = gpu_boundary_v(i, 3, 2, pid) - else if (t < 0._wp) then ! negative t means that v1 is the closest point on the edge + else if (t < 0._wp) then ! negative t means that v1 is the closest point on the edge dist = sqrt((point(1) - v1(1))**2 + (point(2) - v1(2))**2) norm(1) = v1(1) - point(1) norm(2) = v1(2) - point(2) norm = norm/dist - else ! t > 1 means that v2 is the closest point on the line edge + else ! t > 1 means that v2 is the closest point on the line edge dist = sqrt((point(1) - v2(1))**2 + (point(2) - v2(2))**2) norm(1) = v2(1) - point(1) norm(2) = v2(2) - point(2) @@ -1063,37 +1006,32 @@ contains end subroutine s_distance_normals_2D #ifdef MFC_SIMULATION - subroutine s_instantiate_STL_models() ! Variables for IBM+STL - real(wp) :: normals(1:3) !< Boundary normal buffer - integer :: boundary_vertex_count, boundary_edge_count, total_vertices !< Boundary vertex - real(wp), allocatable, dimension(:, :, :) :: boundary_v !< Boundary vertex buffer - real(wp) :: dx_local, dy_local, dz_local !< Levelset distance buffer - - integer :: i, j, k !< Generic loop iterators - integer :: patch_id - - type(t_bbox) :: bbox, bbox_old - type(t_model) :: model - type(ic_model_parameters) :: params - - real(wp) :: eta - real(wp), dimension(1:3) :: point, model_center - real(wp) :: grid_mm(1:3, 1:2) - - real(wp), dimension(1:4, 1:4) :: transform, transform_n + real(wp) :: normals(1:3) !< Boundary normal buffer + integer :: boundary_vertex_count, boundary_edge_count, total_vertices !< Boundary vertex + real(wp), allocatable, dimension(:,:,:) :: boundary_v !< Boundary vertex buffer + real(wp) :: dx_local, dy_local, dz_local !< Levelset distance buffer + integer :: i, j, k !< Generic loop iterators + integer :: patch_id + type(t_bbox) :: bbox, bbox_old + type(t_model) :: model + type(ic_model_parameters) :: params + real(wp) :: eta + real(wp), dimension(1:3) :: point, model_center + real(wp) :: grid_mm(1:3,1:2) + real(wp), dimension(1:4,1:4) :: transform, transform_n dx_local = minval(dx); dy_local = minval(dy) if (p /= 0) dz_local = minval(dz) - allocate (stl_bounding_boxes(num_ibs, 1:3, 1:3)) + allocate (stl_bounding_boxes(num_ibs,1:3,1:3)) do patch_id = 1, num_ibs if (patch_ib(patch_id)%geometry == 5 .or. patch_ib(patch_id)%geometry == 12) then allocate (models(patch_id)%model) - print *, " * Reading model: "//trim(patch_ib(patch_id)%model_filepath) + print *, " * Reading model: " // trim(patch_ib(patch_id)%model_filepath) model = f_model_read(patch_ib(patch_id)%model_filepath) params%scale(:) = patch_ib(patch_id)%model_scale(:) @@ -1141,23 +1079,23 @@ contains write (*, "(A, 3(2X, F20.10))") " > Cen:", (bbox%min(1:3) + bbox%max(1:3))/2._wp write (*, "(A, 3(2X, F20.10))") " > Max:", bbox%max(1:3) - grid_mm(1, :) = (/minval(x_cc(0:m)) - 0.5_wp*dx_local, maxval(x_cc(0:m)) + 0.5_wp*dx_local/) - grid_mm(2, :) = (/minval(y_cc(0:n)) - 0.5_wp*dy_local, maxval(y_cc(0:n)) + 0.5_wp*dy_local/) + grid_mm(1,:) = (/minval(x_cc(0:m)) - 0.5_wp*dx_local, maxval(x_cc(0:m)) + 0.5_wp*dx_local/) + grid_mm(2,:) = (/minval(y_cc(0:n)) - 0.5_wp*dy_local, maxval(y_cc(0:n)) + 0.5_wp*dy_local/) if (p > 0) then - grid_mm(3, :) = (/minval(z_cc(0:p)) - 0.5_wp*dz_local, maxval(z_cc(0:p)) + 0.5_wp*dz_local/) + grid_mm(3,:) = (/minval(z_cc(0:p)) - 0.5_wp*dz_local, maxval(z_cc(0:p)) + 0.5_wp*dz_local/) else - grid_mm(3, :) = (/0._wp, 0._wp/) + grid_mm(3,:) = (/0._wp, 0._wp/) end if - write (*, "(A, 3(2X, F20.10))") " > Domain: Min:", grid_mm(:, 1) - write (*, "(A, 3(2X, F20.10))") " > Cen:", (grid_mm(:, 1) + grid_mm(:, 2))/2._wp - write (*, "(A, 3(2X, F20.10))") " > Max:", grid_mm(:, 2) + write (*, "(A, 3(2X, F20.10))") " > Domain: Min:", grid_mm(:,1) + write (*, "(A, 3(2X, F20.10))") " > Cen:", (grid_mm(:,1) + grid_mm(:,2))/2._wp + write (*, "(A, 3(2X, F20.10))") " > Max:", grid_mm(:,2) end if - stl_bounding_boxes(patch_id, 1, 1:3) = [bbox%min(1), (bbox%min(1) + bbox%max(1))/2._wp, bbox%max(1)] - stl_bounding_boxes(patch_id, 2, 1:3) = [bbox%min(2), (bbox%min(2) + bbox%max(2))/2._wp, bbox%max(2)] - stl_bounding_boxes(patch_id, 3, 1:3) = [bbox%min(3), (bbox%min(3) + bbox%max(3))/2._wp, bbox%max(3)] + stl_bounding_boxes(patch_id, 1,1:3) = [bbox%min(1), (bbox%min(1) + bbox%max(1))/2._wp, bbox%max(1)] + stl_bounding_boxes(patch_id, 2,1:3) = [bbox%min(2), (bbox%min(2) + bbox%max(2))/2._wp, bbox%max(2)] + stl_bounding_boxes(patch_id, 3,1:3) = [bbox%min(3), (bbox%min(3) + bbox%max(3))/2._wp, bbox%max(3)] models(patch_id)%model = model if (p == 0) then @@ -1209,15 +1147,14 @@ contains do pid = 1, num_ibs if (allocated(models(pid)%model)) then gpu_ntrs(pid) = models(pid)%ntrs - gpu_trs_v(:, :, 1:models(pid)%ntrs, pid) = models(pid)%trs_v - gpu_trs_n(:, 1:models(pid)%ntrs, pid) = models(pid)%trs_n + gpu_trs_v(:,:,1:models(pid)%ntrs,pid) = models(pid)%trs_v + gpu_trs_n(:,1:models(pid)%ntrs,pid) = models(pid)%trs_n gpu_boundary_edge_count(pid) = models(pid)%boundary_edge_count gpu_total_vertices(pid) = models(pid)%total_vertices end if if (allocated(models(pid)%boundary_v) .and. p == 0) then - gpu_boundary_v(1:size(models(pid)%boundary_v, 1), & - 1:size(models(pid)%boundary_v, 2), & - 1:size(models(pid)%boundary_v, 3), pid) = models(pid)%boundary_v + gpu_boundary_v(1:size(models(pid)%boundary_v, 1),1:size(models(pid)%boundary_v, 2), & + & 1:size(models(pid)%boundary_v, 3),pid) = models(pid)%boundary_v end if end do @@ -1229,21 +1166,22 @@ contains end block end subroutine s_instantiate_STL_models - #endif subroutine s_pack_model_for_gpu(ma) + type(t_model_array), intent(inout) :: ma - integer :: i + integer :: i ma%ntrs = ma%model%ntrs - allocate (ma%trs_v(1:3, 1:3, 1:ma%ntrs)) - allocate (ma%trs_n(1:3, 1:ma%ntrs)) + allocate (ma%trs_v(1:3,1:3,1:ma%ntrs)) + allocate (ma%trs_n(1:3,1:ma%ntrs)) do i = 1, ma%ntrs - ma%trs_v(:, :, i) = ma%model%trs(i)%v(:, :) - ma%trs_n(:, i) = ma%model%trs(i)%n(:) + ma%trs_v(:,:,i) = ma%model%trs(i)%v(:,:) + ma%trs_n(:,i) = ma%model%trs(i)%n(:) end do - end subroutine + + end subroutine s_pack_model_for_gpu end module m_model diff --git a/src/common/m_mpi_common.fpp b/src/common/m_mpi_common.fpp index 882f032d8e..627c6a30bf 100644 --- a/src/common/m_mpi_common.fpp +++ b/src/common/m_mpi_common.fpp @@ -9,17 +9,13 @@ module m_mpi_common #ifdef MFC_MPI - use mpi !< Message passing interface (MPI) module + use mpi !< Message passing interface (MPI) module #endif - use m_derived_types !< Definitions of the derived types - - use m_global_parameters !< Definitions of the global parameters - + use m_derived_types !< Definitions of the derived types + use m_global_parameters !< Definitions of the global parameters use m_helper - use ieee_arithmetic - use m_nvtx implicit none @@ -28,18 +24,15 @@ module m_mpi_common $:GPU_DECLARE(create='[v_size]') !! Generic flags used to identify and report MPI errors - real(wp), private, allocatable, dimension(:) :: buff_send !< - !! This variable is utilized to pack and send the buffer of the cell-average - !! primitive variables, for a single computational domain boundary at the - !! time, to the relevant neighboring processor. + !> This variable is utilized to pack and send the buffer of the cell-average primitive variables, for a single computational + !! domain boundary at the time, to the relevant neighboring processor. + real(wp), private, allocatable, dimension(:) :: buff_send - real(wp), private, allocatable, dimension(:) :: buff_recv !< - !! buff_recv is utilized to receive and unpack the buffer of the cell- - !! average primitive variables, for a single computational domain boundary - !! at the time, from the relevant neighboring processor. - - type(int_bounds_info) :: comm_coords(3) - integer :: comm_size(3) + !> buff_recv is utilized to receive and unpack the buffer of the cell- average primitive variables, for a single computational + !! domain boundary at the time, from the relevant neighboring processor. + real(wp), private, allocatable, dimension(:) :: buff_recv + type(int_bounds_info) :: comm_coords(3) + integer :: comm_size(3) $:GPU_DECLARE(create='[comm_coords, comm_size]') !! Variables for EL bubbles communication @@ -52,15 +45,13 @@ module m_mpi_common contains - !> The computation of parameters, the allocation of memory, - !! the association of pointers and/or the execution of any - !! other procedures that are necessary to setup the module. + !> The computation of parameters, the allocation of memory, the association of pointers and/or the execution of any other + !! procedures that are necessary to setup the module. impure subroutine s_initialize_mpi_common_module #ifdef MFC_MPI - ! Allocating buff_send/recv and. Please note that for the sake of - ! simplicity, both variables are provided sufficient storage to hold - ! the largest buffer in the computational domain. + ! Allocating buff_send/recv and. Please note that for the sake of simplicity, both variables are provided sufficient storage + ! to hold the largest buffer in the computational domain. if (qbmm .and. .not. polytropic) then v_size = sys_size + 2*nb*nnode @@ -70,14 +61,10 @@ contains if (n > 0) then if (p > 0) then - halo_size = nint(-1._wp + 1._wp*buff_size*(v_size)* & - & (m + 2*buff_size + 1)* & - & (n + 2*buff_size + 1)* & - & (p + 2*buff_size + 1)/ & - & (cells_bounds%mnp_min + 2*buff_size + 1)) + halo_size = nint(-1._wp + 1._wp*buff_size*(v_size)*(m + 2*buff_size + 1)*(n + 2*buff_size + 1)*(p + 2*buff_size & + & + 1)/(cells_bounds%mnp_min + 2*buff_size + 1)) else - halo_size = -1 + buff_size*(v_size)* & - & (cells_bounds%mn_max + 2*buff_size + 1) + halo_size = -1 + buff_size*(v_size)*(cells_bounds%mn_max + 2*buff_size + 1) end if else halo_size = -1 + buff_size*(v_size) @@ -96,13 +83,12 @@ contains end subroutine s_initialize_mpi_common_module - !> The subroutine initializes the MPI execution environment - !! and queries both the number of processors which will be - !! available for the job and the local processor rank. + !> The subroutine initializes the MPI execution environment and queries both the number of processors which will be available + !! for the job and the local processor rank. impure subroutine s_mpi_initialize #ifdef MFC_MPI - integer :: ierr !< Generic flag used to identify and report MPI errors + integer :: ierr !< Generic flag used to identify and report MPI errors ! Initializing the MPI environment call MPI_INIT(ierr) @@ -133,19 +119,17 @@ contains impure subroutine s_initialize_mpi_data(q_cons_vf, ib_markers, beta) type(scalar_field), dimension(sys_size), intent(in) :: q_cons_vf - type(integer_field), optional, intent(in) :: ib_markers - type(scalar_field), intent(in), optional :: beta - - integer, dimension(num_dims) :: sizes_glb, sizes_loc - integer, dimension(1) :: airfoil_glb, airfoil_loc, airfoil_start + type(integer_field), optional, intent(in) :: ib_markers + type(scalar_field), intent(in), optional :: beta + integer, dimension(num_dims) :: sizes_glb, sizes_loc + integer, dimension(1) :: airfoil_glb, airfoil_loc, airfoil_start #ifdef MFC_MPI - ! Generic loop iterator integer :: i, j - integer :: ierr !< Generic flag used to identify and report MPI errors + integer :: ierr !< Generic flag used to identify and report MPI errors - !Altered system size for the lagrangian subgrid bubble model + ! Altered system size for the lagrangian subgrid bubble model integer :: alt_sys if (present(beta)) then @@ -155,23 +139,23 @@ contains end if do i = 1, sys_size - MPI_IO_DATA%var(i)%sf => q_cons_vf(i)%sf(0:m, 0:n, 0:p) + MPI_IO_DATA%var(i)%sf => q_cons_vf(i)%sf(0:m,0:n,0:p) end do if (present(beta)) then - MPI_IO_DATA%var(alt_sys)%sf => beta%sf(0:m, 0:n, 0:p) + MPI_IO_DATA%var(alt_sys)%sf => beta%sf(0:m,0:n,0:p) end if - !Additional variables pb and mv for non-polytropic qbmm + ! Additional variables pb and mv for non-polytropic qbmm if (qbmm .and. .not. polytropic) then do i = 1, nb do j = 1, nnode #ifdef MFC_PRE_PROCESS - MPI_IO_DATA%var(sys_size + (i - 1)*nnode + j)%sf => pb%sf(0:m, 0:n, 0:p, j, i) - MPI_IO_DATA%var(sys_size + (i - 1)*nnode + j + nb*nnode)%sf => mv%sf(0:m, 0:n, 0:p, j, i) + MPI_IO_DATA%var(sys_size + (i - 1)*nnode + j)%sf => pb%sf(0:m,0:n,0:p,j, i) + MPI_IO_DATA%var(sys_size + (i - 1)*nnode + j + nb*nnode)%sf => mv%sf(0:m,0:n,0:p,j, i) #elif defined (MFC_SIMULATION) - MPI_IO_DATA%var(sys_size + (i - 1)*nnode + j)%sf => pb_ts(1)%sf(0:m, 0:n, 0:p, j, i) - MPI_IO_DATA%var(sys_size + (i - 1)*nnode + j + nb*nnode)%sf => mv_ts(1)%sf(0:m, 0:n, 0:p, j, i) + MPI_IO_DATA%var(sys_size + (i - 1)*nnode + j)%sf => pb_ts(1)%sf(0:m,0:n,0:p,j, i) + MPI_IO_DATA%var(sys_size + (i - 1)*nnode + j + nb*nnode)%sf => mv_ts(1)%sf(0:m,0:n,0:p,j, i) #endif end do end do @@ -188,32 +172,30 @@ contains ! Define the view for each variable do i = 1, alt_sys - call MPI_TYPE_CREATE_SUBARRAY(num_dims, sizes_glb, sizes_loc, start_idx, & - MPI_ORDER_FORTRAN, mpi_p, MPI_IO_DATA%view(i), ierr) + call MPI_TYPE_CREATE_SUBARRAY(num_dims, sizes_glb, sizes_loc, start_idx, MPI_ORDER_FORTRAN, mpi_p, & + & MPI_IO_DATA%view(i), ierr) call MPI_TYPE_COMMIT(MPI_IO_DATA%view(i), ierr) end do #ifndef MFC_POST_PROCESS if (qbmm .and. .not. polytropic) then do i = sys_size + 1, sys_size + 2*nb*nnode - call MPI_TYPE_CREATE_SUBARRAY(num_dims, sizes_glb, sizes_loc, start_idx, & - MPI_ORDER_FORTRAN, mpi_p, MPI_IO_DATA%view(i), ierr) + call MPI_TYPE_CREATE_SUBARRAY(num_dims, sizes_glb, sizes_loc, start_idx, MPI_ORDER_FORTRAN, mpi_p, & + & MPI_IO_DATA%view(i), ierr) call MPI_TYPE_COMMIT(MPI_IO_DATA%view(i), ierr) - end do end if #endif #ifndef MFC_PRE_PROCESS if (present(ib_markers)) then - MPI_IO_IB_DATA%var%sf => ib_markers%sf(0:m, 0:n, 0:p) + MPI_IO_IB_DATA%var%sf => ib_markers%sf(0:m,0:n,0:p) - call MPI_TYPE_CREATE_SUBARRAY(num_dims, sizes_glb, sizes_loc, start_idx, & - MPI_ORDER_FORTRAN, MPI_INTEGER, MPI_IO_IB_DATA%view, ierr) + call MPI_TYPE_CREATE_SUBARRAY(num_dims, sizes_glb, sizes_loc, start_idx, MPI_ORDER_FORTRAN, MPI_INTEGER, & + & MPI_IO_IB_DATA%view, ierr) call MPI_TYPE_COMMIT(MPI_IO_IB_DATA%view, ierr) end if #endif - #endif end subroutine s_initialize_mpi_data @@ -221,15 +203,11 @@ contains !! @param q_cons_vf Conservative variables subroutine s_initialize_mpi_data_ds(q_cons_vf) - type(scalar_field), & - dimension(sys_size), & - intent(in) :: q_cons_vf - - integer, dimension(num_dims) :: sizes_glb, sizes_loc - integer, dimension(3) :: sf_start_idx + type(scalar_field), dimension(sys_size), intent(in) :: q_cons_vf + integer, dimension(num_dims) :: sizes_glb, sizes_loc + integer, dimension(3) :: sf_start_idx #ifdef MFC_MPI - ! Generic loop iterator integer :: i, j, q, k, l, m_ds, n_ds, p_ds, ierr @@ -247,7 +225,7 @@ contains #ifdef MFC_POST_PROCESS do i = 1, sys_size - MPI_IO_DATA%var(i)%sf => q_cons_vf(i)%sf(-1:m_ds + 1, -1:n_ds + 1, -1:p_ds + 1) + MPI_IO_DATA%var(i)%sf => q_cons_vf(i)%sf(-1:m_ds + 1,-1:n_ds + 1,-1:p_ds + 1) end do #endif ! Define global(g) and local(l) sizes for flow variables @@ -261,8 +239,8 @@ contains ! Define the view for each variable do i = 1, sys_size - call MPI_TYPE_CREATE_SUBARRAY(num_dims, sizes_loc, sizes_loc, sf_start_idx, & - MPI_ORDER_FORTRAN, mpi_p, MPI_IO_DATA%view(i), ierr) + call MPI_TYPE_CREATE_SUBARRAY(num_dims, sizes_loc, sizes_loc, sf_start_idx, MPI_ORDER_FORTRAN, mpi_p, & + & MPI_IO_DATA%view(i), ierr) call MPI_TYPE_COMMIT(MPI_IO_DATA%view(i), ierr) end do #endif @@ -272,21 +250,18 @@ contains !> @brief Gathers variable-length real vectors from all MPI ranks onto the root process. impure subroutine s_mpi_gather_data(my_vector, counts, gathered_vector, root) - integer, intent(in) :: counts ! Array of vector lengths for each process - real(wp), intent(in), dimension(counts) :: my_vector ! Input vector on each process - integer, intent(in) :: root ! Rank of the root process - real(wp), allocatable, intent(out) :: gathered_vector(:) ! Gathered vector on the root process - - integer :: i - integer :: ierr !< Generic flag used to identify and report MPI errors - integer, allocatable :: recounts(:), displs(:) + integer, intent(in) :: counts ! Array of vector lengths for each process + real(wp), intent(in), dimension(counts) :: my_vector ! Input vector on each process + integer, intent(in) :: root ! Rank of the root process + real(wp), allocatable, intent(out) :: gathered_vector(:) ! Gathered vector on the root process + integer :: i + integer :: ierr !< Generic flag used to identify and report MPI errors + integer, allocatable :: recounts(:), displs(:) #ifdef MFC_MPI - allocate (recounts(num_procs)) - call MPI_GATHER(counts, 1, MPI_INTEGER, recounts, 1, MPI_INTEGER, root, & - MPI_COMM_WORLD, ierr) + call MPI_GATHER(counts, 1, MPI_INTEGER, recounts, 1, MPI_INTEGER, root, MPI_COMM_WORLD, ierr) allocate (displs(size(recounts))) @@ -297,28 +272,28 @@ contains end do allocate (gathered_vector(sum(recounts))) - call MPI_GATHERV(my_vector, counts, mpi_p, gathered_vector, recounts, displs, mpi_p, & - root, MPI_COMM_WORLD, ierr) + call MPI_GATHERV(my_vector, counts, mpi_p, gathered_vector, recounts, displs, mpi_p, root, MPI_COMM_WORLD, ierr) #endif + end subroutine s_mpi_gather_data !> @brief Gathers per-rank time step wall-clock times onto rank 0 for performance reporting. impure subroutine mpi_bcast_time_step_values(proc_time, time_avg) real(wp), dimension(0:num_procs - 1), intent(inout) :: proc_time - real(wp), intent(inout) :: time_avg + real(wp), intent(inout) :: time_avg #ifdef MFC_MPI - integer :: ierr !< Generic flag used to identify and report MPI errors + integer :: ierr !< Generic flag used to identify and report MPI errors call MPI_GATHER(time_avg, 1, mpi_p, proc_time(0), 1, mpi_p, 0, MPI_COMM_WORLD, ierr) - #endif end subroutine mpi_bcast_time_step_values !> @brief Prints a case file error with the prohibited condition and message, then aborts execution. impure subroutine s_prohibit_abort(condition, message) + character(len=*), intent(in) :: condition, message print *, "" @@ -329,69 +304,50 @@ contains end if print *, "" call s_mpi_abort(code=CASE_FILE_ERROR_CODE) - end subroutine s_prohibit_abort - !> The goal of this subroutine is to determine the global - !! extrema of the stability criteria in the computational - !! domain. This is performed by sifting through the local - !! extrema of each stability criterion. Note that each of - !! the local extrema is from a single process, within its - !! assigned section of the computational domain. Finally, - !! note that the global extrema values are only bookkeept - !! on the rank 0 processor. - !! @param icfl_max_loc Local maximum ICFL stability criterion - !! @param vcfl_max_loc Local maximum VCFL stability criterion - !! @param Rc_min_loc Local minimum Rc stability criterion - !! @param icfl_max_glb Global maximum ICFL stability criterion - !! @param vcfl_max_glb Global maximum VCFL stability criterion - !! @param Rc_min_glb Global minimum Rc stability criterion - impure subroutine s_mpi_reduce_stability_criteria_extrema(icfl_max_loc, & - vcfl_max_loc, & - Rc_min_loc, & - bubs_loc, & - icfl_max_glb, & - vcfl_max_glb, & - Rc_min_glb, & - bubs_glb) - - real(wp), intent(in) :: icfl_max_loc - real(wp), intent(in) :: vcfl_max_loc - real(wp), intent(in) :: Rc_min_loc - integer, intent(in) :: bubs_loc + end subroutine s_prohibit_abort + !> The goal of this subroutine is to determine the global extrema of the stability criteria in the computational domain. This is + !! performed by sifting through the local extrema of each stability criterion. Note that each of the local extrema is from a + !! single process, within its assigned section of the computational domain. Finally, note that the global extrema values are + !! only bookkeept on the rank 0 processor. + !! @param icfl_max_loc Local maximum ICFL stability criterion + !! @param vcfl_max_loc Local maximum VCFL stability criterion + !! @param Rc_min_loc Local minimum Rc stability criterion + !! @param icfl_max_glb Global maximum ICFL stability criterion + !! @param vcfl_max_glb Global maximum VCFL stability criterion + !! @param Rc_min_glb Global minimum Rc stability criterion + impure subroutine s_mpi_reduce_stability_criteria_extrema(icfl_max_loc, vcfl_max_loc, Rc_min_loc, bubs_loc, icfl_max_glb, & + & vcfl_max_glb, Rc_min_glb, bubs_glb) + + real(wp), intent(in) :: icfl_max_loc + real(wp), intent(in) :: vcfl_max_loc + real(wp), intent(in) :: Rc_min_loc + integer, intent(in) :: bubs_loc real(wp), intent(out) :: icfl_max_glb real(wp), intent(out) :: vcfl_max_glb real(wp), intent(out) :: Rc_min_glb - integer, intent(out) :: bubs_glb + integer, intent(out) :: bubs_glb #ifdef MFC_SIMULATION #ifdef MFC_MPI - integer :: ierr !< Generic flag used to identify and report MPI errors + integer :: ierr !< Generic flag used to identify and report MPI errors bubs_glb = 0 - ! Reducing local extrema of ICFL, VCFL, CCFL and Rc numbers to their - ! global extrema and bookkeeping the results on the rank 0 processor - call MPI_REDUCE(icfl_max_loc, icfl_max_glb, 1, & - mpi_p, MPI_MAX, 0, & - MPI_COMM_WORLD, ierr) + ! Reducing local extrema of ICFL, VCFL, CCFL and Rc numbers to their global extrema and bookkeeping the results on the rank + ! 0 processor + call MPI_REDUCE(icfl_max_loc, icfl_max_glb, 1, mpi_p, MPI_MAX, 0, MPI_COMM_WORLD, ierr) if (viscous) then - call MPI_REDUCE(vcfl_max_loc, vcfl_max_glb, 1, & - mpi_p, MPI_MAX, 0, & - MPI_COMM_WORLD, ierr) - call MPI_REDUCE(Rc_min_loc, Rc_min_glb, 1, & - mpi_p, MPI_MIN, 0, & - MPI_COMM_WORLD, ierr) + call MPI_REDUCE(vcfl_max_loc, vcfl_max_glb, 1, mpi_p, MPI_MAX, 0, MPI_COMM_WORLD, ierr) + call MPI_REDUCE(Rc_min_loc, Rc_min_glb, 1, mpi_p, MPI_MIN, 0, MPI_COMM_WORLD, ierr) end if if (bubbles_lagrange) then - call MPI_REDUCE(bubs_loc, bubs_glb, 1, & - MPI_INTEGER, MPI_SUM, 0, & - MPI_COMM_WORLD, ierr) + call MPI_REDUCE(bubs_loc, bubs_glb, 1, MPI_INTEGER, MPI_SUM, 0, MPI_COMM_WORLD, ierr) end if #else - icfl_max_glb = icfl_max_loc bubs_glb = 0 @@ -406,232 +362,195 @@ contains end subroutine s_mpi_reduce_stability_criteria_extrema - !> The following subroutine takes the inputted variable and - !! determines its sum on the entire computational domain. - !! @param var_loc holds the local value to be reduced among - !! all the processors in communicator. On output, the variable holds - !! the sum, reduced amongst all of the local values. + !> The following subroutine takes the inputted variable and determines its sum on the entire computational domain. + ! ! @param var_loc holds the local value to be reduced among all the processors in communicator. On output, the variable holds + ! the sum, reduced amongst all of the local values. subroutine s_mpi_reduce_int_sum(var_loc, sum) - integer, intent(in) :: var_loc + integer, intent(in) :: var_loc integer, intent(out) :: sum #ifdef MFC_MPI - integer :: ierr !< Generic flag used to identify and report MPI errors - - ! Performing reduction procedure and eventually storing its result - ! into the variable that was initially inputted into the subroutine - call MPI_REDUCE(var_loc, sum, 1, MPI_INTEGER, & - MPI_SUM, 0, MPI_COMM_WORLD, ierr) + integer :: ierr !< Generic flag used to identify and report MPI errors + ! Performing reduction procedure and eventually storing its result into the variable that was initially inputted into the + ! subroutine + call MPI_REDUCE(var_loc, sum, 1, MPI_INTEGER, MPI_SUM, 0, MPI_COMM_WORLD, ierr) #else sum = var_loc #endif end subroutine s_mpi_reduce_int_sum - !> The following subroutine takes the input local variable - !! from all processors and reduces to the sum of all - !! values. The reduced variable is recorded back onto the - !! original local variable on each processor. - !! @param var_loc Some variable containing the local value which should be - !! reduced amongst all the processors in the communicator. - !! @param var_glb The globally reduced value + !> The following subroutine takes the input local variable from all processors and reduces to the sum of all values. The reduced + !! variable is recorded back onto the original local variable on each processor. + ! ! @param var_loc Some variable containing the local value which should be reduced amongst all the processors in the + ! communicator. + !! @param var_glb The globally reduced value impure subroutine s_mpi_allreduce_sum(var_loc, var_glb) - real(wp), intent(in) :: var_loc + real(wp), intent(in) :: var_loc real(wp), intent(out) :: var_glb #ifdef MFC_MPI - integer :: ierr !< Generic flag used to identify and report MPI errors + integer :: ierr !< Generic flag used to identify and report MPI errors ! Performing the reduction procedure - call MPI_ALLREDUCE(var_loc, var_glb, 1, mpi_p, & - MPI_SUM, MPI_COMM_WORLD, ierr) - + call MPI_ALLREDUCE(var_loc, var_glb, 1, mpi_p, MPI_SUM, MPI_COMM_WORLD, ierr) #endif end subroutine s_mpi_allreduce_sum - !> This subroutine follows the behavior of the s_mpi_allreduce_sum subroutine - !> with the additional feature that it reduces an array of vectors. + !> This subroutine follows the behavior of the s_mpi_allreduce_sum subroutine + !> with the additional feature that it reduces an array of vectors. impure subroutine s_mpi_allreduce_vectors_sum(var_loc, var_glb, num_vectors, vector_length) - integer, intent(in) :: num_vectors, vector_length - real(wp), dimension(:, :), intent(in) :: var_loc - real(wp), dimension(:, :), intent(out) :: var_glb + integer, intent(in) :: num_vectors, vector_length + real(wp), dimension(:,:), intent(in) :: var_loc + real(wp), dimension(:,:), intent(out) :: var_glb #ifdef MFC_MPI - integer :: ierr !< Generic flag used to identify and report MPI errors + integer :: ierr !< Generic flag used to identify and report MPI errors ! Performing the reduction procedure if (loc(var_loc) == loc(var_glb)) then - call MPI_Allreduce(MPI_IN_PLACE, var_glb, num_vectors*vector_length, & - mpi_p, MPI_SUM, MPI_COMM_WORLD, ierr) + call MPI_Allreduce(MPI_IN_PLACE, var_glb, num_vectors*vector_length, mpi_p, MPI_SUM, MPI_COMM_WORLD, ierr) else - call MPI_Allreduce(var_loc, var_glb, num_vectors*vector_length, & - mpi_p, MPI_SUM, MPI_COMM_WORLD, ierr) + call MPI_Allreduce(var_loc, var_glb, num_vectors*vector_length, mpi_p, MPI_SUM, MPI_COMM_WORLD, ierr) end if - #else - var_glb(1:num_vectors, 1:vector_length) = var_loc(1:num_vectors, 1:vector_length) + var_glb(1:num_vectors,1:vector_length) = var_loc(1:num_vectors,1:vector_length) #endif end subroutine s_mpi_allreduce_vectors_sum - !> The following subroutine takes the input local variable - !! from all processors and reduces to the sum of all - !! values. The reduced variable is recorded back onto the - !! original local variable on each processor. - !! @param var_loc Some variable containing the local value which should be - !! reduced amongst all the processors in the communicator. - !! @param var_glb The globally reduced value + !> The following subroutine takes the input local variable from all processors and reduces to the sum of all values. The reduced + !! variable is recorded back onto the original local variable on each processor. + ! ! @param var_loc Some variable containing the local value which should be reduced amongst all the processors in the + ! communicator. + !! @param var_glb The globally reduced value impure subroutine s_mpi_allreduce_integer_sum(var_loc, var_glb) - integer, intent(in) :: var_loc + integer, intent(in) :: var_loc integer, intent(out) :: var_glb #ifdef MFC_MPI - integer :: ierr !< Generic flag used to identify and report MPI errors + integer :: ierr !< Generic flag used to identify and report MPI errors ! Performing the reduction procedure - call MPI_ALLREDUCE(var_loc, var_glb, 1, MPI_INTEGER, & - MPI_SUM, MPI_COMM_WORLD, ierr) + call MPI_ALLREDUCE(var_loc, var_glb, 1, MPI_INTEGER, MPI_SUM, MPI_COMM_WORLD, ierr) #else var_glb = var_loc #endif end subroutine s_mpi_allreduce_integer_sum - !> The following subroutine takes the input local variable - !! from all processors and reduces to the minimum of all - !! values. The reduced variable is recorded back onto the - !! original local variable on each processor. - !! @param var_loc Some variable containing the local value which should be - !! reduced amongst all the processors in the communicator. - !! @param var_glb The globally reduced value + !> The following subroutine takes the input local variable from all processors and reduces to the minimum of all values. The + !! reduced variable is recorded back onto the original local variable on each processor. + ! ! @param var_loc Some variable containing the local value which should be reduced amongst all the processors in the + ! communicator. + !! @param var_glb The globally reduced value impure subroutine s_mpi_allreduce_min(var_loc, var_glb) - real(wp), intent(in) :: var_loc + real(wp), intent(in) :: var_loc real(wp), intent(out) :: var_glb #ifdef MFC_MPI - integer :: ierr !< Generic flag used to identify and report MPI errors + integer :: ierr !< Generic flag used to identify and report MPI errors ! Performing the reduction procedure - call MPI_ALLREDUCE(var_loc, var_glb, 1, mpi_p, & - MPI_MIN, MPI_COMM_WORLD, ierr) - + call MPI_ALLREDUCE(var_loc, var_glb, 1, mpi_p, MPI_MIN, MPI_COMM_WORLD, ierr) #endif end subroutine s_mpi_allreduce_min - !> The following subroutine takes the input local variable - !! from all processors and reduces to the maximum of all - !! values. The reduced variable is recorded back onto the - !! original local variable on each processor. - !! @param var_loc Some variable containing the local value which should be - !! reduced amongst all the processors in the communicator. - !! @param var_glb The globally reduced value + !> The following subroutine takes the input local variable from all processors and reduces to the maximum of all values. The + !! reduced variable is recorded back onto the original local variable on each processor. + ! ! @param var_loc Some variable containing the local value which should be reduced amongst all the processors in the + ! communicator. + !! @param var_glb The globally reduced value impure subroutine s_mpi_allreduce_max(var_loc, var_glb) - real(wp), intent(in) :: var_loc + real(wp), intent(in) :: var_loc real(wp), intent(out) :: var_glb #ifdef MFC_MPI - integer :: ierr !< Generic flag used to identify and report MPI errors + integer :: ierr !< Generic flag used to identify and report MPI errors ! Performing the reduction procedure - call MPI_ALLREDUCE(var_loc, var_glb, 1, mpi_p, & - MPI_MAX, MPI_COMM_WORLD, ierr) - + call MPI_ALLREDUCE(var_loc, var_glb, 1, mpi_p, MPI_MAX, MPI_COMM_WORLD, ierr) #endif end subroutine s_mpi_allreduce_max - !> The following subroutine takes the inputted variable and - !! determines its minimum value on the entire computational - !! domain. The result is stored back into inputted variable. - !! @param var_loc holds the local value to be reduced among - !! all the processors in communicator. On output, the variable holds - !! the minimum value, reduced amongst all of the local values. + !> The following subroutine takes the inputted variable and determines its minimum value on the entire computational domain. The + !! result is stored back into inputted variable. + ! ! @param var_loc holds the local value to be reduced among all the processors in communicator. On output, the variable holds + ! the minimum value, reduced amongst all of the local values. impure subroutine s_mpi_reduce_min(var_loc) real(wp), intent(inout) :: var_loc #ifdef MFC_MPI - integer :: ierr !< Generic flag used to identify and report MPI errors + integer :: ierr !< Generic flag used to identify and report MPI errors ! Temporary storage variable that holds the reduced minimum value real(wp) :: var_glb - ! Performing reduction procedure and eventually storing its result - ! into the variable that was initially inputted into the subroutine - call MPI_REDUCE(var_loc, var_glb, 1, mpi_p, & - MPI_MIN, 0, MPI_COMM_WORLD, ierr) + ! Performing reduction procedure and eventually storing its result into the variable that was initially inputted into the + ! subroutine + call MPI_REDUCE(var_loc, var_glb, 1, mpi_p, MPI_MIN, 0, MPI_COMM_WORLD, ierr) - call MPI_BCAST(var_glb, 1, mpi_p, & - 0, MPI_COMM_WORLD, ierr) + call MPI_BCAST(var_glb, 1, mpi_p, 0, MPI_COMM_WORLD, ierr) var_loc = var_glb - #endif end subroutine s_mpi_reduce_min - !> The following subroutine takes the first element of the - !! 2-element inputted variable and determines its maximum - !! value on the entire computational domain. The result is - !! stored back into the first element of the variable while - !! the rank of the processor that is in charge of the sub- - !! domain containing the maximum is stored into the second - !! element of the variable. - !! @param var_loc On input, this variable holds the local value and processor rank, - !! which are to be reduced among all the processors in communicator. - !! On output, this variable holds the maximum value, reduced amongst - !! all of the local values, and the process rank to which the value - !! belongs. + !> The following subroutine takes the first element of the 2-element inputted variable and determines its maximum value on the + !! entire computational domain. The result is stored back into the first element of the variable while the rank of the processor + !! that is in charge of the sub- domain containing the maximum is stored into the second element of the variable. + ! ! @param var_loc On input, this variable holds the local value and processor rank, which are to be reduced among all the + ! processors in communicator. On output, this variable holds the maximum value, reduced amongst all of the local values, and the + ! process rank to which the value belongs. impure subroutine s_mpi_reduce_maxloc(var_loc) real(wp), dimension(2), intent(inout) :: var_loc #ifdef MFC_MPI - integer :: ierr !< Generic flag used to identify and report MPI errors + integer :: ierr !< Generic flag used to identify and report MPI errors - real(wp), dimension(2) :: var_glb !< - !! Temporary storage variable that holds the reduced maximum value - !! and the rank of the processor with which the value is associated + !> Temporary storage variable that holds the reduced maximum value and the rank of the processor with which the value is + !! associated + real(wp), dimension(2) :: var_glb - ! Performing reduction procedure and eventually storing its result - ! into the variable that was initially inputted into the subroutine - call MPI_REDUCE(var_loc, var_glb, 1, mpi_2p, & - MPI_MAXLOC, 0, MPI_COMM_WORLD, ierr) + ! Performing reduction procedure and eventually storing its result into the variable that was initially inputted into the + ! subroutine + call MPI_REDUCE(var_loc, var_glb, 1, mpi_2p, MPI_MAXLOC, 0, MPI_COMM_WORLD, ierr) - call MPI_BCAST(var_glb, 1, mpi_2p, & - 0, MPI_COMM_WORLD, ierr) + call MPI_BCAST(var_glb, 1, mpi_2p, 0, MPI_COMM_WORLD, ierr) var_loc = var_glb - #endif end subroutine s_mpi_reduce_maxloc !> The subroutine terminates the MPI execution environment. - !! @param prnt error message to be printed - !! @param code optional exit code + !! @param prnt error message to be printed + !! @param code optional exit code impure subroutine s_mpi_abort(prnt, code) character(len=*), intent(in), optional :: prnt - integer, intent(in), optional :: code + integer, intent(in), optional :: code #ifdef MFC_MPI - integer :: ierr !< Generic flag used to identify and report MPI errors + integer :: ierr !< Generic flag used to identify and report MPI errors #endif if (present(prnt)) then print *, prnt call flush (6) - end if #ifndef MFC_MPI @@ -651,15 +570,14 @@ contains end subroutine s_mpi_abort - !>Halts all processes until all have reached barrier. + !> Halts all processes until all have reached barrier. impure subroutine s_mpi_barrier #ifdef MFC_MPI - integer :: ierr !< Generic flag used to identify and report MPI errors + integer :: ierr !< Generic flag used to identify and report MPI errors ! Calling MPI_BARRIER call MPI_BARRIER(MPI_COMM_WORLD, ierr) - #endif end subroutine s_mpi_barrier @@ -668,48 +586,37 @@ contains impure subroutine s_mpi_finalize #ifdef MFC_MPI - integer :: ierr !< Generic flag used to identify and report MPI errors + integer :: ierr !< Generic flag used to identify and report MPI errors ! Finalizing the MPI environment call MPI_FINALIZE(ierr) - #endif end subroutine s_mpi_finalize - !> The goal of this procedure is to populate the buffers of - !! the cell-average conservative variables by communicating - !! with the neighboring processors. - !! @param q_comm Cell-average conservative variables - !! @param mpi_dir MPI communication coordinate direction - !! @param pbc_loc Processor boundary condition (PBC) location - !! @param nVar Number of variables to communicate - !! @param pb_in Optional internal bubble pressure - !! @param mv_in Optional bubble mass velocity - subroutine s_mpi_sendrecv_variables_buffers(q_comm, & - mpi_dir, & - pbc_loc, & - nVar, & - pb_in, mv_in) + !> The goal of this procedure is to populate the buffers of the cell-average conservative variables by communicating with the + !! neighboring processors. + !! @param q_comm Cell-average conservative variables + !! @param mpi_dir MPI communication coordinate direction + !! @param pbc_loc Processor boundary condition (PBC) location + !! @param nVar Number of variables to communicate + !! @param pb_in Optional internal bubble pressure + !! @param mv_in Optional bubble mass velocity + subroutine s_mpi_sendrecv_variables_buffers(q_comm, mpi_dir, pbc_loc, nVar, pb_in, mv_in) type(scalar_field), dimension(1:), intent(inout) :: q_comm - real(stp), optional, dimension(idwbuff(1)%beg:, idwbuff(2)%beg:, idwbuff(3)%beg:, 1:, 1:), intent(inout) :: pb_in, mv_in + real(stp), optional, dimension(idwbuff(1)%beg:,idwbuff(2)%beg:,idwbuff(3)%beg:,1:,1:), intent(inout) :: pb_in, mv_in integer, intent(in) :: mpi_dir, pbc_loc, nVar - - integer :: i, j, k, l, r, q !< Generic loop iterators - + integer :: i, j, k, l, r, q !< Generic loop iterators integer :: buffer_counts(1:3), buffer_count - type(int_bounds_info) :: boundary_conditions(1:3) integer :: beg_end(1:2), grid_dims(1:3) integer :: dst_proc, src_proc, recv_tag, send_tag - logical :: beg_end_geq_0, qbmm_comm - integer :: pack_offset, unpack_offset #ifdef MFC_MPI - integer :: ierr !< Generic flag used to identify and report MPI errors + integer :: ierr !< Generic flag used to identify and report MPI errors call nvtxStartRange("RHS-COMM-PACKBUF") @@ -718,18 +625,12 @@ contains if (present(pb_in) .and. present(mv_in) .and. qbmm .and. .not. polytropic) then qbmm_comm = .true. v_size = nVar + 2*nb*nnode - buffer_counts = (/ & - buff_size*v_size*(n + 1)*(p + 1), & - buff_size*v_size*(m + 2*buff_size + 1)*(p + 1), & - buff_size*v_size*(m + 2*buff_size + 1)*(n + 2*buff_size + 1) & - /) + buffer_counts = (/buff_size*v_size*(n + 1)*(p + 1), buff_size*v_size*(m + 2*buff_size + 1)*(p + 1), & + & buff_size*v_size*(m + 2*buff_size + 1)*(n + 2*buff_size + 1)/) else v_size = nVar - buffer_counts = (/ & - buff_size*v_size*(n + 1)*(p + 1), & - buff_size*v_size*(m + 2*buff_size + 1)*(p + 1), & - buff_size*v_size*(m + 2*buff_size + 1)*(n + 2*buff_size + 1) & - /) + buffer_counts = (/buff_size*v_size*(n + 1)*(p + 1), buff_size*v_size*(m + 2*buff_size + 1)*(p + 1), & + & buff_size*v_size*(m + 2*buff_size + 1)*(n + 2*buff_size + 1)/) end if $:GPU_UPDATE(device='[v_size]') @@ -739,12 +640,9 @@ contains beg_end = (/boundary_conditions(mpi_dir)%beg, boundary_conditions(mpi_dir)%end/) beg_end_geq_0 = beg_end(max(pbc_loc, 0) - pbc_loc + 1) >= 0 - ! Implements: - ! pbc_loc bc_x >= 0 -> [send/recv]_tag [dst/src]_proc - ! -1 (=0) 0 -> [1,0] [0,0] | 0 0 [1,0] [beg,beg] - ! -1 (=0) 1 -> [0,0] [1,0] | 0 1 [0,0] [end,beg] - ! +1 (=1) 0 -> [0,1] [1,1] | 1 0 [0,1] [end,end] - ! +1 (=1) 1 -> [1,1] [0,1] | 1 1 [1,1] [beg,end] + ! Implements: pbc_loc bc_x >= 0 -> [send/recv]_tag [dst/src]_proc -1 (=0) 0 -> [1,0] [0,0] | 0 0 [1,0] [beg,beg] -1 (=0) 1 + ! -> [0,0] [1,0] | 0 1 [0,0] [end,beg] +1 (=1) 0 -> [0,1] [1,1] | 1 0 [0,1] [end,end] +1 (=1) 1 -> [1,1] [0,1] | 1 1 [1,1] + ! [beg,end] send_tag = f_logical_to_int(.not. f_xor(beg_end_geq_0, pbc_loc == 1)) recv_tag = f_logical_to_int(pbc_loc == 1) @@ -788,8 +686,7 @@ contains do j = 0, buff_size - 1 do i = nVar + 1, nVar + nnode do q = 1, nb - r = (i - 1) + (q - 1)*nnode + v_size* & - (j + buff_size*(k + (n + 1)*l)) + r = (i - 1) + (q - 1)*nnode + v_size*(j + buff_size*(k + (n + 1)*l)) buff_send(r) = real(pb_in(j + pack_offset, k, l, i - nVar, q), kind=wp) end do end do @@ -804,8 +701,7 @@ contains do j = 0, buff_size - 1 do i = nVar + 1, nVar + nnode do q = 1, nb - r = (i - 1) + (q - 1)*nnode + nb*nnode + v_size* & - (j + buff_size*(k + (n + 1)*l)) + r = (i - 1) + (q - 1)*nnode + nb*nnode + v_size*(j + buff_size*(k + (n + 1)*l)) buff_send(r) = real(mv_in(j + pack_offset, k, l, i - nVar, q), kind=wp) end do end do @@ -820,9 +716,7 @@ contains do l = 0, p do k = 0, buff_size - 1 do j = -buff_size, m + buff_size - r = (i - 1) + v_size* & - ((j + buff_size) + (m + 2*buff_size + 1)* & - (k + buff_size*l)) + r = (i - 1) + v_size*((j + buff_size) + (m + 2*buff_size + 1)*(k + buff_size*l)) buff_send(r) = real(q_comm(i)%sf(j, k + pack_offset, l), kind=wp) end do end do @@ -837,9 +731,8 @@ contains do k = 0, buff_size - 1 do j = -buff_size, m + buff_size do q = 1, nb - r = (i - 1) + (q - 1)*nnode + v_size* & - ((j + buff_size) + (m + 2*buff_size + 1)* & - (k + buff_size*l)) + r = (i - 1) + (q - 1)*nnode + v_size*((j + buff_size) + (m + 2*buff_size + 1)*(k & + & + buff_size*l)) buff_send(r) = real(pb_in(j, k + pack_offset, l, i - nVar, q), kind=wp) end do end do @@ -854,9 +747,8 @@ contains do k = 0, buff_size - 1 do j = -buff_size, m + buff_size do q = 1, nb - r = (i - 1) + (q - 1)*nnode + nb*nnode + v_size* & - ((j + buff_size) + (m + 2*buff_size + 1)* & - (k + buff_size*l)) + r = (i - 1) + (q - 1)*nnode + nb*nnode + v_size*((j + buff_size) + (m + 2*buff_size & + & + 1)*(k + buff_size*l)) buff_send(r) = real(mv_in(j, k + pack_offset, l, i - nVar, q), kind=wp) end do end do @@ -871,9 +763,8 @@ contains do l = 0, buff_size - 1 do k = -buff_size, n + buff_size do j = -buff_size, m + buff_size - r = (i - 1) + v_size* & - ((j + buff_size) + (m + 2*buff_size + 1)* & - ((k + buff_size) + (n + 2*buff_size + 1)*l)) + r = (i - 1) + v_size*((j + buff_size) + (m + 2*buff_size + 1)*((k + buff_size) + (n & + & + 2*buff_size + 1)*l)) buff_send(r) = real(q_comm(i)%sf(j, k, l + pack_offset), kind=wp) end do end do @@ -888,9 +779,8 @@ contains do k = -buff_size, n + buff_size do j = -buff_size, m + buff_size do q = 1, nb - r = (i - 1) + (q - 1)*nnode + v_size* & - ((j + buff_size) + (m + 2*buff_size + 1)* & - ((k + buff_size) + (n + 2*buff_size + 1)*l)) + r = (i - 1) + (q - 1)*nnode + v_size*((j + buff_size) + (m + 2*buff_size + 1)*((k & + & + buff_size) + (n + 2*buff_size + 1)*l)) buff_send(r) = real(pb_in(j, k, l + pack_offset, i - nVar, q), kind=wp) end do end do @@ -905,9 +795,8 @@ contains do k = -buff_size, n + buff_size do j = -buff_size, m + buff_size do q = 1, nb - r = (i - 1) + (q - 1)*nnode + nb*nnode + v_size* & - ((j + buff_size) + (m + 2*buff_size + 1)* & - ((k + buff_size) + (n + 2*buff_size + 1)*l)) + r = (i - 1) + (q - 1)*nnode + nb*nnode + v_size*((j + buff_size) + (m + 2*buff_size & + & + 1)*((k + buff_size) + (n + 2*buff_size + 1)*l)) buff_send(r) = real(mv_in(j, k, l + pack_offset, i - nVar, q), kind=wp) end do end do @@ -919,7 +808,7 @@ contains #:endif end if #:endfor - call nvtxEndRange ! Packbuf + call nvtxEndRange ! Packbuf ! Send/Recv #ifdef MFC_SIMULATION @@ -929,13 +818,10 @@ contains #:call GPU_HOST_DATA(use_device_addr='[buff_send, buff_recv]') call nvtxStartRange("RHS-COMM-SENDRECV-RDMA") - call MPI_SENDRECV( & - buff_send, buffer_count, mpi_p, dst_proc, send_tag, & - buff_recv, buffer_count, mpi_p, src_proc, recv_tag, & - MPI_COMM_WORLD, MPI_STATUS_IGNORE, ierr) - - call nvtxEndRange ! RHS-MPI-SENDRECV-(NO)-RDMA + call MPI_SENDRECV(buff_send, buffer_count, mpi_p, dst_proc, send_tag, buff_recv, buffer_count, mpi_p, & + & src_proc, recv_tag, MPI_COMM_WORLD, MPI_STATUS_IGNORE, ierr) + call nvtxEndRange ! RHS-MPI-SENDRECV-(NO)-RDMA #:endcall GPU_HOST_DATA $:GPU_WAIT() #:else @@ -944,12 +830,10 @@ contains call nvtxEndRange call nvtxStartRange("RHS-COMM-SENDRECV-NO-RMDA") - call MPI_SENDRECV( & - buff_send, buffer_count, mpi_p, dst_proc, send_tag, & - buff_recv, buffer_count, mpi_p, src_proc, recv_tag, & - MPI_COMM_WORLD, MPI_STATUS_IGNORE, ierr) + call MPI_SENDRECV(buff_send, buffer_count, mpi_p, dst_proc, send_tag, buff_recv, buffer_count, mpi_p, & + & src_proc, recv_tag, MPI_COMM_WORLD, MPI_STATUS_IGNORE, ierr) - call nvtxEndRange ! RHS-MPI-SENDRECV-(NO)-RDMA + call nvtxEndRange ! RHS-MPI-SENDRECV-(NO)-RDMA call nvtxStartRange("RHS-COMM-HOST2DEV") $:GPU_UPDATE(device='[buff_recv]') @@ -958,10 +842,8 @@ contains end if #:endfor #else - call MPI_SENDRECV( & - buff_send, buffer_count, mpi_p, dst_proc, send_tag, & - buff_recv, buffer_count, mpi_p, src_proc, recv_tag, & - MPI_COMM_WORLD, MPI_STATUS_IGNORE, ierr) + call MPI_SENDRECV(buff_send, buffer_count, mpi_p, dst_proc, send_tag, buff_recv, buffer_count, mpi_p, src_proc, recv_tag, & + & MPI_COMM_WORLD, MPI_STATUS_IGNORE, ierr) #endif ! Unpack Received Buffer @@ -974,8 +856,7 @@ contains do k = 0, n do j = -buff_size, -1 do i = 1, nVar - r = (i - 1) + v_size* & - (j + buff_size*((k + 1) + (n + 1)*l)) + r = (i - 1) + v_size*(j + buff_size*((k + 1) + (n + 1)*l)) q_comm(i)%sf(j + unpack_offset, k, l) = real(buff_recv(r), kind=stp) #if defined(__INTEL_COMPILER) if (ieee_is_nan(q_comm(i)%sf(j + unpack_offset, k, l))) then @@ -996,8 +877,7 @@ contains do j = -buff_size, -1 do i = nVar + 1, nVar + nnode do q = 1, nb - r = (i - 1) + (q - 1)*nnode + v_size* & - (j + buff_size*((k + 1) + (n + 1)*l)) + r = (i - 1) + (q - 1)*nnode + v_size*(j + buff_size*((k + 1) + (n + 1)*l)) pb_in(j + unpack_offset, k, l, i - nVar, q) = real(buff_recv(r), kind=stp) end do end do @@ -1012,8 +892,7 @@ contains do j = -buff_size, -1 do i = nVar + 1, nVar + nnode do q = 1, nb - r = (i - 1) + (q - 1)*nnode + nb*nnode + v_size* & - (j + buff_size*((k + 1) + (n + 1)*l)) + r = (i - 1) + (q - 1)*nnode + nb*nnode + v_size*(j + buff_size*((k + 1) + (n + 1)*l)) mv_in(j + unpack_offset, k, l, i - nVar, q) = real(buff_recv(r), kind=stp) end do end do @@ -1028,9 +907,7 @@ contains do l = 0, p do k = -buff_size, -1 do j = -buff_size, m + buff_size - r = (i - 1) + v_size* & - ((j + buff_size) + (m + 2*buff_size + 1)* & - ((k + buff_size) + buff_size*l)) + r = (i - 1) + v_size*((j + buff_size) + (m + 2*buff_size + 1)*((k + buff_size) + buff_size*l)) q_comm(i)%sf(j, k + unpack_offset, l) = real(buff_recv(r), kind=stp) #if defined(__INTEL_COMPILER) if (ieee_is_nan(q_comm(i)%sf(j, k + unpack_offset, l))) then @@ -1051,9 +928,8 @@ contains do k = -buff_size, -1 do j = -buff_size, m + buff_size do q = 1, nb - r = (i - 1) + (q - 1)*nnode + v_size* & - ((j + buff_size) + (m + 2*buff_size + 1)* & - ((k + buff_size) + buff_size*l)) + r = (i - 1) + (q - 1)*nnode + v_size*((j + buff_size) + (m + 2*buff_size + 1)*((k & + & + buff_size) + buff_size*l)) pb_in(j, k + unpack_offset, l, i - nVar, q) = real(buff_recv(r), kind=stp) end do end do @@ -1068,9 +944,8 @@ contains do k = -buff_size, -1 do j = -buff_size, m + buff_size do q = 1, nb - r = (i - 1) + (q - 1)*nnode + nb*nnode + v_size* & - ((j + buff_size) + (m + 2*buff_size + 1)* & - ((k + buff_size) + buff_size*l)) + r = (i - 1) + (q - 1)*nnode + nb*nnode + v_size*((j + buff_size) + (m + 2*buff_size & + & + 1)*((k + buff_size) + buff_size*l)) mv_in(j, k + unpack_offset, l, i - nVar, q) = real(buff_recv(r), kind=stp) end do end do @@ -1086,10 +961,8 @@ contains do l = -buff_size, -1 do k = -buff_size, n + buff_size do j = -buff_size, m + buff_size - r = (i - 1) + v_size* & - ((j + buff_size) + (m + 2*buff_size + 1)* & - ((k + buff_size) + (n + 2*buff_size + 1)* & - (l + buff_size))) + r = (i - 1) + v_size*((j + buff_size) + (m + 2*buff_size + 1)*((k + buff_size) + (n & + & + 2*buff_size + 1)*(l + buff_size))) q_comm(i)%sf(j, k, l + unpack_offset) = real(buff_recv(r), kind=stp) #if defined(__INTEL_COMPILER) if (ieee_is_nan(q_comm(i)%sf(j, k, l + unpack_offset))) then @@ -1110,10 +983,8 @@ contains do k = -buff_size, n + buff_size do j = -buff_size, m + buff_size do q = 1, nb - r = (i - 1) + (q - 1)*nnode + v_size* & - ((j + buff_size) + (m + 2*buff_size + 1)* & - ((k + buff_size) + (n + 2*buff_size + 1)* & - (l + buff_size))) + r = (i - 1) + (q - 1)*nnode + v_size*((j + buff_size) + (m + 2*buff_size + 1)*((k & + & + buff_size) + (n + 2*buff_size + 1)*(l + buff_size))) pb_in(j, k, l + unpack_offset, i - nVar, q) = real(buff_recv(r), kind=stp) end do end do @@ -1128,10 +999,8 @@ contains do k = -buff_size, n + buff_size do j = -buff_size, m + buff_size do q = 1, nb - r = (i - 1) + (q - 1)*nnode + nb*nnode + v_size* & - ((j + buff_size) + (m + 2*buff_size + 1)* & - ((k + buff_size) + (n + 2*buff_size + 1)* & - (l + buff_size))) + r = (i - 1) + (q - 1)*nnode + nb*nnode + v_size*((j + buff_size) + (m + 2*buff_size & + & + 1)*((k + buff_size) + (n + 2*buff_size + 1)*(l + buff_size))) mv_in(j, k, l + unpack_offset, i - nVar, q) = real(buff_recv(r), kind=stp) end do end do @@ -1148,45 +1017,34 @@ contains end subroutine s_mpi_sendrecv_variables_buffers - !> The goal of this procedure is to populate the buffers of - !! the cell-average conservative variables by communicating - !! with the neighboring processors. - !! @param q_cons_vf Cell-average conservative variables - !! @param mpi_dir MPI communication coordinate direction - !! @param pbc_loc Processor boundary condition (PBC) location - subroutine s_mpi_reduce_beta_variables_buffers(q_comm, kahan_comp, & - mpi_dir, & - pbc_loc, & - nVar) + !> The goal of this procedure is to populate the buffers of the cell-average conservative variables by communicating with the + !! neighboring processors. + !! @param q_cons_vf Cell-average conservative variables + !! @param mpi_dir MPI communication coordinate direction + !! @param pbc_loc Processor boundary condition (PBC) location + subroutine s_mpi_reduce_beta_variables_buffers(q_comm, kahan_comp, mpi_dir, pbc_loc, nVar) type(scalar_field), dimension(1:), intent(inout) :: q_comm type(scalar_field), dimension(1:), intent(inout) :: kahan_comp - integer, intent(in) :: mpi_dir, pbc_loc, nVar - - integer :: i, j, k, l, r, q !< Generic loop iterators - integer :: lb_size - - integer :: buffer_counts(1:3), buffer_count - - type(int_bounds_info) :: boundary_conditions(1:3) - integer :: beg_end(1:2), grid_dims(1:3) - integer :: dst_proc, src_proc, recv_tag, send_tag - - logical :: replace_buff - - integer :: pack_offset, unpack_offset - real(wp) :: y_kahan, t_kahan + integer, intent(in) :: mpi_dir, pbc_loc, nVar + integer :: i, j, k, l, r, q !< Generic loop iterators + integer :: lb_size + integer :: buffer_counts(1:3), buffer_count + type(int_bounds_info) :: boundary_conditions(1:3) + integer :: beg_end(1:2), grid_dims(1:3) + integer :: dst_proc, src_proc, recv_tag, send_tag + logical :: replace_buff + integer :: pack_offset, unpack_offset + real(wp) :: y_kahan, t_kahan #ifdef MFC_MPI - integer :: ierr !< Generic flag used to identify and report MPI errors + integer :: ierr !< Generic flag used to identify and report MPI errors call nvtxStartRange("BETA-COMM-PACKBUF") - ! Set bounds for each dimension - ! Always include the full buffer range for each existing dimension. - ! The Gaussian smearing kernel writes to buffer cells even at physical - ! boundaries, and these contributions must be communicated to neighbors - ! in other directions via ADD operations. + ! Set bounds for each dimension Always include the full buffer range for each existing dimension. The Gaussian smearing + ! kernel writes to buffer cells even at physical boundaries, and these contributions must be communicated to neighbors in + ! other directions via ADD operations. comm_coords(1)%beg = -mapcells - 1 comm_coords(1)%end = m + mapcells + 1 comm_coords(2)%beg = merge(-mapcells - 1, 0, n > 0) @@ -1201,12 +1059,9 @@ contains ! Buffer counts using the conditional sizes v_size = nVar - lb_size = 2*(mapcells + 1) ! Size of the buffer region for beta variables (-mapcells - 1, mapcells) - buffer_counts = (/ & - lb_size*v_size*comm_size(2)*comm_size(3), & ! mpi_dir=1 - lb_size*v_size*comm_size(1)*comm_size(3), & ! mpi_dir=2 - lb_size*v_size*comm_size(1)*comm_size(2) & ! mpi_dir=3 - /) + lb_size = 2*(mapcells + 1) ! Size of the buffer region for beta variables (-mapcells - 1, mapcells) + buffer_counts = (/lb_size*v_size*comm_size(2)*comm_size(3), lb_size*v_size*comm_size(1)*comm_size(3), & + & lb_size*v_size*comm_size(1)*comm_size(2)/) $:GPU_UPDATE(device='[v_size, comm_coords, comm_size]') @@ -1216,8 +1071,7 @@ contains grid_dims = (/m, n, p/) if (pbc_loc == -1) then - ! Phase 1: Rightward accumulation - ! Send END buffer to right neighbor, recv from left into BEG, ADD + ! Phase 1: Rightward accumulation Send END buffer to right neighbor, recv from left into BEG, ADD pack_offset = grid_dims(mpi_dir) + 1 unpack_offset = 0 dst_proc = merge(beg_end(2), MPI_PROC_NULL, beg_end(2) >= 0) @@ -1226,8 +1080,7 @@ contains recv_tag = 0 replace_buff = .false. else - ! Phase 2: Leftward distribution - ! Send BEG buffer to left neighbor, recv from right into END, REPLACE + ! Phase 2: Leftward distribution Send BEG buffer to left neighbor, recv from right into END, REPLACE pack_offset = 0 unpack_offset = grid_dims(mpi_dir) + 1 dst_proc = merge(beg_end(1), MPI_PROC_NULL, beg_end(1) >= 0) @@ -1246,12 +1099,10 @@ contains do k = comm_coords(2)%beg, comm_coords(2)%end do j = -mapcells - 1, mapcells do i = 1, v_size - r = (i - 1) + v_size*( & - (j + mapcells + 1) + lb_size*( & - (k - comm_coords(2)%beg) + comm_size(2)* & - (l - comm_coords(3)%beg))) - buff_send(r) = real(q_comm(beta_vars(i))%sf(j + pack_offset, k, l), kind=wp) & - - real(kahan_comp(beta_vars(i))%sf(j + pack_offset, k, l), kind=wp) + r = (i - 1) + v_size*((j + mapcells + 1) + lb_size*((k - comm_coords(2)%beg) + comm_size(2) & + & *(l - comm_coords(3)%beg))) + buff_send(r) = real(q_comm(beta_vars(i))%sf(j + pack_offset, k, l), & + & kind=wp) - real(kahan_comp(beta_vars(i))%sf(j + pack_offset, k, l), kind=wp) end do end do end do @@ -1263,12 +1114,10 @@ contains do l = comm_coords(3)%beg, comm_coords(3)%end do k = -mapcells - 1, mapcells do j = comm_coords(1)%beg, comm_coords(1)%end - r = (i - 1) + v_size*( & - (j - comm_coords(1)%beg) + comm_size(1)*( & - (k + mapcells + 1) + lb_size* & - (l - comm_coords(3)%beg))) - buff_send(r) = real(q_comm(beta_vars(i))%sf(j, k + pack_offset, l), kind=wp) & - - real(kahan_comp(beta_vars(i))%sf(j, k + pack_offset, l), kind=wp) + r = (i - 1) + v_size*((j - comm_coords(1)%beg) + comm_size(1)*((k + mapcells + 1) & + & + lb_size*(l - comm_coords(3)%beg))) + buff_send(r) = real(q_comm(beta_vars(i))%sf(j, k + pack_offset, l), & + & kind=wp) - real(kahan_comp(beta_vars(i))%sf(j, k + pack_offset, l), kind=wp) end do end do end do @@ -1280,12 +1129,10 @@ contains do l = -mapcells - 1, mapcells do k = comm_coords(2)%beg, comm_coords(2)%end do j = comm_coords(1)%beg, comm_coords(1)%end - r = (i - 1) + v_size*( & - (j - comm_coords(1)%beg) + comm_size(1)*( & - (k - comm_coords(2)%beg) + comm_size(2)* & - (l + mapcells + 1))) - buff_send(r) = real(q_comm(beta_vars(i))%sf(j, k, l + pack_offset), kind=wp) & - - real(kahan_comp(beta_vars(i))%sf(j, k, l + pack_offset), kind=wp) + r = (i - 1) + v_size*((j - comm_coords(1)%beg) + comm_size(1)*((k - comm_coords(2)%beg) & + & + comm_size(2)*(l + mapcells + 1))) + buff_send(r) = real(q_comm(beta_vars(i))%sf(j, k, l + pack_offset), & + & kind=wp) - real(kahan_comp(beta_vars(i))%sf(j, k, l + pack_offset), kind=wp) end do end do end do @@ -1294,7 +1141,7 @@ contains #:endif end if #:endfor - call nvtxEndRange ! Packbuf + call nvtxEndRange ! Packbuf ! Send/Recv #ifdef MFC_SIMULATION @@ -1304,13 +1151,10 @@ contains #:call GPU_HOST_DATA(use_device_addr='[buff_send, buff_recv]') call nvtxStartRange("BETA-COMM-SENDRECV-RDMA") - call MPI_SENDRECV( & - buff_send, buffer_count, mpi_p, dst_proc, send_tag, & - buff_recv, buffer_count, mpi_p, src_proc, recv_tag, & - MPI_COMM_WORLD, MPI_STATUS_IGNORE, ierr) - - call nvtxEndRange ! BETA-MPI-SENDRECV-(NO)-RDMA + call MPI_SENDRECV(buff_send, buffer_count, mpi_p, dst_proc, send_tag, buff_recv, buffer_count, mpi_p, & + & src_proc, recv_tag, MPI_COMM_WORLD, MPI_STATUS_IGNORE, ierr) + call nvtxEndRange ! BETA-MPI-SENDRECV-(NO)-RDMA #:endcall GPU_HOST_DATA $:GPU_WAIT() #:else @@ -1319,12 +1163,10 @@ contains call nvtxEndRange call nvtxStartRange("BETA-COMM-SENDRECV-NO-RMDA") - call MPI_SENDRECV( & - buff_send, buffer_count, mpi_p, dst_proc, send_tag, & - buff_recv, buffer_count, mpi_p, src_proc, recv_tag, & - MPI_COMM_WORLD, MPI_STATUS_IGNORE, ierr) + call MPI_SENDRECV(buff_send, buffer_count, mpi_p, dst_proc, send_tag, buff_recv, buffer_count, mpi_p, & + & src_proc, recv_tag, MPI_COMM_WORLD, MPI_STATUS_IGNORE, ierr) - call nvtxEndRange ! BETA-MPI-SENDRECV-(NO)-RDMA + call nvtxEndRange ! BETA-MPI-SENDRECV-(NO)-RDMA call nvtxStartRange("BETA-COMM-HOST2DEV") $:GPU_UPDATE(device='[buff_recv]') @@ -1333,10 +1175,8 @@ contains end if #:endfor #else - call MPI_SENDRECV( & - buff_send, buffer_count, mpi_p, dst_proc, send_tag, & - buff_recv, buffer_count, mpi_p, src_proc, recv_tag, & - MPI_COMM_WORLD, MPI_STATUS_IGNORE, ierr) + call MPI_SENDRECV(buff_send, buffer_count, mpi_p, dst_proc, send_tag, buff_recv, buffer_count, mpi_p, src_proc, recv_tag, & + & MPI_COMM_WORLD, MPI_STATUS_IGNORE, ierr) #endif ! Unpack Received Buffer (skip if no source rank) @@ -1345,25 +1185,24 @@ contains #:for mpi_dir in [1, 2, 3] if (mpi_dir == ${mpi_dir}$) then #:if mpi_dir == 1 - $:GPU_PARALLEL_LOOP(collapse=4,private='[r,y_kahan,t_kahan]',copyin='[replace_buff]') + $:GPU_PARALLEL_LOOP(collapse=4,private='[r, y_kahan, t_kahan]',copyin='[replace_buff]') do l = comm_coords(3)%beg, comm_coords(3)%end do k = comm_coords(2)%beg, comm_coords(2)%end do j = -mapcells - 1, mapcells do i = 1, v_size - r = (i - 1) + v_size*( & - (j + mapcells + 1) + lb_size*( & - (k - comm_coords(2)%beg) + comm_size(2)* & - (l - comm_coords(3)%beg))) + r = (i - 1) + v_size*((j + mapcells + 1) + lb_size*((k - comm_coords(2)%beg) & + & + comm_size(2)*(l - comm_coords(3)%beg))) if (replace_buff) then q_comm(beta_vars(i))%sf(j + unpack_offset, k, l) = real(buff_recv(r), kind=stp) - kahan_comp(beta_vars(i))%sf(j + unpack_offset, k, l) = & - real(q_comm(beta_vars(i))%sf(j + unpack_offset, k, l), kind=wp) - buff_recv(r) + kahan_comp(beta_vars(i))%sf(j + unpack_offset, k, & + & l) = real(q_comm(beta_vars(i))%sf(j + unpack_offset, k, l), & + & kind=wp) - buff_recv(r) else - y_kahan = buff_recv(r) & - - real(kahan_comp(beta_vars(i))%sf(j + unpack_offset, k, l), kind=wp) + y_kahan = buff_recv(r) - real(kahan_comp(beta_vars(i))%sf(j + unpack_offset, k, l), & + & kind=wp) t_kahan = real(q_comm(beta_vars(i))%sf(j + unpack_offset, k, l), kind=wp) + y_kahan - kahan_comp(beta_vars(i))%sf(j + unpack_offset, k, l) = & - (t_kahan - q_comm(beta_vars(i))%sf(j + unpack_offset, k, l)) - y_kahan + kahan_comp(beta_vars(i))%sf(j + unpack_offset, k, & + & l) = (t_kahan - q_comm(beta_vars(i))%sf(j + unpack_offset, k, l)) - y_kahan q_comm(beta_vars(i))%sf(j + unpack_offset, k, l) = t_kahan end if end do @@ -1372,25 +1211,24 @@ contains end do $:END_GPU_PARALLEL_LOOP() #:elif mpi_dir == 2 - $:GPU_PARALLEL_LOOP(collapse=4,private='[r,y_kahan,t_kahan]',copyin='[replace_buff]') + $:GPU_PARALLEL_LOOP(collapse=4,private='[r, y_kahan, t_kahan]',copyin='[replace_buff]') do i = 1, v_size do l = comm_coords(3)%beg, comm_coords(3)%end do k = -mapcells - 1, mapcells do j = comm_coords(1)%beg, comm_coords(1)%end - r = (i - 1) + v_size*( & - (j - comm_coords(1)%beg) + comm_size(1)*( & - (k + mapcells + 1) + lb_size* & - (l - comm_coords(3)%beg))) + r = (i - 1) + v_size*((j - comm_coords(1)%beg) + comm_size(1)*((k + mapcells + 1) & + & + lb_size*(l - comm_coords(3)%beg))) if (replace_buff) then q_comm(beta_vars(i))%sf(j, k + unpack_offset, l) = real(buff_recv(r), kind=stp) - kahan_comp(beta_vars(i))%sf(j, k + unpack_offset, l) = & - real(q_comm(beta_vars(i))%sf(j, k + unpack_offset, l), kind=wp) - buff_recv(r) + kahan_comp(beta_vars(i))%sf(j, k + unpack_offset, & + & l) = real(q_comm(beta_vars(i))%sf(j, k + unpack_offset, l), & + & kind=wp) - buff_recv(r) else - y_kahan = buff_recv(r) & - - real(kahan_comp(beta_vars(i))%sf(j, k + unpack_offset, l), kind=wp) + y_kahan = buff_recv(r) - real(kahan_comp(beta_vars(i))%sf(j, k + unpack_offset, l), & + & kind=wp) t_kahan = real(q_comm(beta_vars(i))%sf(j, k + unpack_offset, l), kind=wp) + y_kahan - kahan_comp(beta_vars(i))%sf(j, k + unpack_offset, l) = & - (t_kahan - q_comm(beta_vars(i))%sf(j, k + unpack_offset, l)) - y_kahan + kahan_comp(beta_vars(i))%sf(j, k + unpack_offset, & + & l) = (t_kahan - q_comm(beta_vars(i))%sf(j, k + unpack_offset, l)) - y_kahan q_comm(beta_vars(i))%sf(j, k + unpack_offset, l) = t_kahan end if end do @@ -1399,25 +1237,25 @@ contains end do $:END_GPU_PARALLEL_LOOP() #:else - $:GPU_PARALLEL_LOOP(collapse=4,private='[r,y_kahan,t_kahan]',copyin='[replace_buff]') + $:GPU_PARALLEL_LOOP(collapse=4,private='[r, y_kahan, t_kahan]',copyin='[replace_buff]') do i = 1, v_size do l = -mapcells - 1, mapcells do k = comm_coords(2)%beg, comm_coords(2)%end do j = comm_coords(1)%beg, comm_coords(1)%end - r = (i - 1) + v_size*( & - (j - comm_coords(1)%beg) + comm_size(1)*( & - (k - comm_coords(2)%beg) + comm_size(2)* & - (l + mapcells + 1))) + r = (i - 1) + v_size*((j - comm_coords(1)%beg) + comm_size(1)*((k - comm_coords(2)%beg) & + & + comm_size(2)*(l + mapcells + 1))) if (replace_buff) then q_comm(beta_vars(i))%sf(j, k, l + unpack_offset) = real(buff_recv(r), kind=stp) - kahan_comp(beta_vars(i))%sf(j, k, l + unpack_offset) = & - real(q_comm(beta_vars(i))%sf(j, k, l + unpack_offset), kind=wp) - buff_recv(r) + kahan_comp(beta_vars(i))%sf(j, k, & + & l + unpack_offset) = real(q_comm(beta_vars(i))%sf(j, k, & + & l + unpack_offset), kind=wp) - buff_recv(r) else - y_kahan = buff_recv(r) & - - real(kahan_comp(beta_vars(i))%sf(j, k, l + unpack_offset), kind=wp) + y_kahan = buff_recv(r) - real(kahan_comp(beta_vars(i))%sf(j, k, l + unpack_offset), & + & kind=wp) t_kahan = real(q_comm(beta_vars(i))%sf(j, k, l + unpack_offset), kind=wp) + y_kahan - kahan_comp(beta_vars(i))%sf(j, k, l + unpack_offset) = & - (t_kahan - q_comm(beta_vars(i))%sf(j, k, l + unpack_offset)) - y_kahan + kahan_comp(beta_vars(i))%sf(j, k, & + & l + unpack_offset) = (t_kahan - q_comm(beta_vars(i))%sf(j, k, & + & l + unpack_offset)) - y_kahan q_comm(beta_vars(i))%sf(j, k, l + unpack_offset) = t_kahan end if end do @@ -1434,37 +1272,25 @@ contains end subroutine s_mpi_reduce_beta_variables_buffers - !> The purpose of this procedure is to optimally decompose - !! the computational domain among the available processors. - !! This is performed by attempting to award each processor, - !! in each of the coordinate directions, approximately the - !! same number of cells, and then recomputing the affected - !! global parameters. + !> The purpose of this procedure is to optimally decompose the computational domain among the available processors. This is + !! performed by attempting to award each processor, in each of the coordinate directions, approximately the same number of + !! cells, and then recomputing the affected global parameters. subroutine s_mpi_decompose_computational_domain #ifdef MFC_MPI + integer :: num_procs_x, num_procs_y, num_procs_z !< Optimal number of processors in the x-, y- and z-directions - integer :: num_procs_x, num_procs_y, num_procs_z !< - !! Optimal number of processors in the x-, y- and z-directions - - real(wp) :: tmp_num_procs_x, tmp_num_procs_y, tmp_num_procs_z !< - !! Non-optimal number of processors in the x-, y- and z-directions - - real(wp) :: fct_min !< - !! Processor factorization (fct) minimization parameter + !> Non-optimal number of processors in the x-, y- and z-directions + real(wp) :: tmp_num_procs_x, tmp_num_procs_y, tmp_num_procs_z + real(wp) :: fct_min !< Processor factorization (fct) minimization parameter + integer :: MPI_COMM_CART !< Cartesian processor topology communicator - integer :: MPI_COMM_CART !< - !! Cartesian processor topology communicator - - integer :: rem_cells !< - !! Remaining number of cells, in a particular coordinate direction, - !! after the majority is divided up among the available processors - - integer :: recon_order !< - !! WENO or MUSCL reconstruction order - - integer :: i, j, k !< Generic loop iterators - integer :: ierr !< Generic flag used to identify and report MPI errors + !> Remaining number of cells, in a particular coordinate direction, after the majority is divided up among the available + !! processors + integer :: rem_cells + integer :: recon_order !< WENO or MUSCL reconstruction order + integer :: i, j, k !< Generic loop iterators + integer :: ierr !< Generic flag used to identify and report MPI errors ! temp array to store neighbor rank coordinates integer, dimension(1:num_dims) :: neighbor_coords @@ -1493,10 +1319,8 @@ contains ! 3D Cartesian Processor Topology if (n > 0) then - if (p > 0) then if (fft_wrt) then - ! Initial estimate of optimal processor topology num_procs_x = 1 num_procs_y = 1 @@ -1506,43 +1330,28 @@ contains ! Benchmarking the quality of this initial guess tmp_num_procs_y = num_procs_y tmp_num_procs_z = num_procs_z - fct_min = 10._wp*abs((n + 1)/tmp_num_procs_y & - - (p + 1)/tmp_num_procs_z) + fct_min = 10._wp*abs((n + 1)/tmp_num_procs_y - (p + 1)/tmp_num_procs_z) ! Optimization of the initial processor topology do i = 1, num_procs - - if (mod(num_procs, i) == 0 & - .and. & - (n + 1)/i >= num_stcls_min*recon_order) then - + if (mod(num_procs, i) == 0 .and. (n + 1)/i >= num_stcls_min*recon_order) then tmp_num_procs_y = i tmp_num_procs_z = num_procs/i - if (fct_min >= abs((n + 1)/tmp_num_procs_y & - - (p + 1)/tmp_num_procs_z) & - .and. & - (p + 1)/tmp_num_procs_z & - >= & - num_stcls_min*recon_order) then - + if (fct_min >= abs((n + 1)/tmp_num_procs_y - (p + 1)/tmp_num_procs_z) .and. (p + 1) & + & /tmp_num_procs_z >= num_stcls_min*recon_order) then num_procs_y = i num_procs_z = num_procs/i - fct_min = abs((n + 1)/tmp_num_procs_y & - - (p + 1)/tmp_num_procs_z) + fct_min = abs((n + 1)/tmp_num_procs_y - (p + 1)/tmp_num_procs_z) ierr = 0 - end if - end if - end do else - if (cyl_coord .and. p > 0) then - ! Implement pencil processor blocking if using cylindrical coordinates so - ! that all cells in azimuthal direction are stored on a single processor. - ! This is necessary for efficient application of Fourier filter near axis. + ! Implement pencil processor blocking if using cylindrical coordinates so that all cells in azimuthal + ! direction are stored on a single processor. This is necessary for efficient application of Fourier filter + ! near axis. ! Initial values of the processor factorization optimization num_procs_x = 1 @@ -1554,40 +1363,24 @@ contains tmp_num_procs_x = num_procs_x tmp_num_procs_y = num_procs_y tmp_num_procs_z = num_procs_z - fct_min = 10._wp*abs((m + 1)/tmp_num_procs_x & - - (n + 1)/tmp_num_procs_y) + fct_min = 10._wp*abs((m + 1)/tmp_num_procs_x - (n + 1)/tmp_num_procs_y) ! Searching for optimal computational domain distribution do i = 1, num_procs - - if (mod(num_procs, i) == 0 & - .and. & - (m + 1)/i >= num_stcls_min*recon_order) then - + if (mod(num_procs, i) == 0 .and. (m + 1)/i >= num_stcls_min*recon_order) then tmp_num_procs_x = i tmp_num_procs_y = num_procs/i - if (fct_min >= abs((m + 1)/tmp_num_procs_x & - - (n + 1)/tmp_num_procs_y) & - .and. & - (n + 1)/tmp_num_procs_y & - >= & - num_stcls_min*recon_order) then - + if (fct_min >= abs((m + 1)/tmp_num_procs_x - (n + 1)/tmp_num_procs_y) .and. (n + 1) & + & /tmp_num_procs_y >= num_stcls_min*recon_order) then num_procs_x = i num_procs_y = num_procs/i - fct_min = abs((m + 1)/tmp_num_procs_x & - - (n + 1)/tmp_num_procs_y) + fct_min = abs((m + 1)/tmp_num_procs_x - (n + 1)/tmp_num_procs_y) ierr = 0 - end if - end if - end do - else - ! Initial estimate of optimal processor topology num_procs_x = 1 num_procs_y = 1 @@ -1598,77 +1391,48 @@ contains tmp_num_procs_x = num_procs_x tmp_num_procs_y = num_procs_y tmp_num_procs_z = num_procs_z - fct_min = 10._wp*abs((m + 1)/tmp_num_procs_x & - - (n + 1)/tmp_num_procs_y) & - + 10._wp*abs((n + 1)/tmp_num_procs_y & - - (p + 1)/tmp_num_procs_z) + fct_min = 10._wp*abs((m + 1)/tmp_num_procs_x - (n + 1)/tmp_num_procs_y) + 10._wp*abs((n + 1) & + & /tmp_num_procs_y - (p + 1)/tmp_num_procs_z) ! Optimization of the initial processor topology do i = 1, num_procs - - if (mod(num_procs, i) == 0 & - .and. & - (m + 1)/i >= num_stcls_min*recon_order) then - + if (mod(num_procs, i) == 0 .and. (m + 1)/i >= num_stcls_min*recon_order) then do j = 1, num_procs/i - - if (mod(num_procs/i, j) == 0 & - .and. & - (n + 1)/j >= num_stcls_min*recon_order) then - + if (mod(num_procs/i, j) == 0 .and. (n + 1)/j >= num_stcls_min*recon_order) then tmp_num_procs_x = i tmp_num_procs_y = j tmp_num_procs_z = num_procs/(i*j) - if (fct_min >= abs((m + 1)/tmp_num_procs_x & - - (n + 1)/tmp_num_procs_y) & - + abs((n + 1)/tmp_num_procs_y & - - (p + 1)/tmp_num_procs_z) & - .and. & - (p + 1)/tmp_num_procs_z & - >= & - num_stcls_min*recon_order) & - then - + if (fct_min >= abs((m + 1)/tmp_num_procs_x - (n + 1)/tmp_num_procs_y) + abs((n + 1) & + & /tmp_num_procs_y - (p + 1)/tmp_num_procs_z) .and. (p + 1) & + & /tmp_num_procs_z >= num_stcls_min*recon_order) then num_procs_x = i num_procs_y = j num_procs_z = num_procs/(i*j) - fct_min = abs((m + 1)/tmp_num_procs_x & - - (n + 1)/tmp_num_procs_y) & - + abs((n + 1)/tmp_num_procs_y & - - (p + 1)/tmp_num_procs_z) + fct_min = abs((m + 1)/tmp_num_procs_x - (n + 1)/tmp_num_procs_y) + abs((n + 1) & + & /tmp_num_procs_y - (p + 1)/tmp_num_procs_z) ierr = 0 - end if - end if - end do - end if - end do - end if end if - ! Verifying that a valid decomposition of the computational - ! domain has been established. If not, the simulation exits. + ! Verifying that a valid decomposition of the computational domain has been established. If not, the simulation + ! exits. if (proc_rank == 0 .and. ierr == -1) then - call s_mpi_abort('Unsupported combination of values '// & - 'of num_procs, m, n, p and '// & - 'weno/muscl/igr_order. Exiting.') + call s_mpi_abort('Unsupported combination of values ' // 'of num_procs, m, n, p and ' & + & // 'weno/muscl/igr_order. Exiting.') end if ! Creating new communicator using the Cartesian topology - call MPI_CART_CREATE(MPI_COMM_WORLD, 3, (/num_procs_x, & - num_procs_y, num_procs_z/), & - (/.true., .true., .true./), & - .false., MPI_COMM_CART, ierr) + call MPI_CART_CREATE(MPI_COMM_WORLD, 3, (/num_procs_x, num_procs_y, num_procs_z/), (/.true., .true., .true./), & + & .false., MPI_COMM_CART, ierr) ! Finding the Cartesian coordinates of the local process - call MPI_CART_COORDS(MPI_COMM_CART, proc_rank, 3, & - proc_coords, ierr) + call MPI_CART_COORDS(MPI_COMM_CART, proc_rank, 3, proc_coords, ierr) ! END: 3D Cartesian Processor Topology ! Global Parameters for z-direction @@ -1689,8 +1453,7 @@ contains ! Boundary condition at the beginning if (proc_coords(3) > 0 .or. (bc_z%beg == BC_PERIODIC .and. num_procs_z > 1)) then proc_coords(3) = proc_coords(3) - 1 - call MPI_CART_RANK(MPI_COMM_CART, proc_coords, & - bc_z%beg, ierr) + call MPI_CART_RANK(MPI_COMM_CART, proc_coords, bc_z%beg, ierr) proc_coords(3) = proc_coords(3) + 1 nidx(3)%beg = -1 end if @@ -1698,8 +1461,7 @@ contains ! Boundary condition at the end if (proc_coords(3) < num_procs_z - 1 .or. (bc_z%end == BC_PERIODIC .and. num_procs_z > 1)) then proc_coords(3) = proc_coords(3) + 1 - call MPI_CART_RANK(MPI_COMM_CART, proc_coords, & - bc_z%end, ierr) + call MPI_CART_RANK(MPI_COMM_CART, proc_coords, bc_z%end, ierr) proc_coords(3) = proc_coords(3) - 1 nidx(3)%end = 1 end if @@ -1733,16 +1495,12 @@ contains dz = (z_domain%end - z_domain%beg)/real(p_glb + 1, wp) if (proc_coords(3) < rem_cells) then - z_domain%beg = z_domain%beg + dz*real((p + 1)* & - proc_coords(3)) - z_domain%end = z_domain%end - dz*real((p + 1)* & - (num_procs_z - proc_coords(3) - 1) & - - (num_procs_z - rem_cells)) + z_domain%beg = z_domain%beg + dz*real((p + 1)*proc_coords(3)) + z_domain%end = z_domain%end - dz*real((p + 1)*(num_procs_z - proc_coords(3) - 1) - (num_procs_z & + & - rem_cells)) else - z_domain%beg = z_domain%beg + dz*real((p + 1)* & - proc_coords(3) + rem_cells) - z_domain%end = z_domain%end - dz*real((p + 1)* & - (num_procs_z - proc_coords(3) - 1)) + z_domain%beg = z_domain%beg + dz*real((p + 1)*proc_coords(3) + rem_cells) + z_domain%end = z_domain%end - dz*real((p + 1)*(num_procs_z - proc_coords(3) - 1)) end if end if #endif @@ -1750,7 +1508,6 @@ contains ! 2D Cartesian Processor Topology else - ! Initial estimate of optimal processor topology num_procs_x = 1 num_procs_y = num_procs @@ -1759,56 +1516,37 @@ contains ! Benchmarking the quality of this initial guess tmp_num_procs_x = num_procs_x tmp_num_procs_y = num_procs_y - fct_min = 10._wp*abs((m + 1)/tmp_num_procs_x & - - (n + 1)/tmp_num_procs_y) + fct_min = 10._wp*abs((m + 1)/tmp_num_procs_x - (n + 1)/tmp_num_procs_y) ! Optimization of the initial processor topology do i = 1, num_procs - - if (mod(num_procs, i) == 0 & - .and. & - (m + 1)/i >= num_stcls_min*recon_order) then - + if (mod(num_procs, i) == 0 .and. (m + 1)/i >= num_stcls_min*recon_order) then tmp_num_procs_x = i tmp_num_procs_y = num_procs/i - if (fct_min >= abs((m + 1)/tmp_num_procs_x & - - (n + 1)/tmp_num_procs_y) & - .and. & - (n + 1)/tmp_num_procs_y & - >= & - num_stcls_min*recon_order) then - + if (fct_min >= abs((m + 1)/tmp_num_procs_x - (n + 1)/tmp_num_procs_y) .and. (n + 1) & + & /tmp_num_procs_y >= num_stcls_min*recon_order) then num_procs_x = i num_procs_y = num_procs/i - fct_min = abs((m + 1)/tmp_num_procs_x & - - (n + 1)/tmp_num_procs_y) + fct_min = abs((m + 1)/tmp_num_procs_x - (n + 1)/tmp_num_procs_y) ierr = 0 - end if - end if - end do - ! Verifying that a valid decomposition of the computational - ! domain has been established. If not, the simulation exits. + ! Verifying that a valid decomposition of the computational domain has been established. If not, the simulation + ! exits. if (proc_rank == 0 .and. ierr == -1) then - call s_mpi_abort('Unsupported combination of values '// & - 'of num_procs, m, n and '// & - 'weno/muscl/igr_order. Exiting.') + call s_mpi_abort('Unsupported combination of values ' // 'of num_procs, m, n and ' & + & // 'weno/muscl/igr_order. Exiting.') end if ! Creating new communicator using the Cartesian topology - call MPI_CART_CREATE(MPI_COMM_WORLD, 2, (/num_procs_x, & - num_procs_y/), (/.true., & - .true./), .false., MPI_COMM_CART, & - ierr) + call MPI_CART_CREATE(MPI_COMM_WORLD, 2, (/num_procs_x, num_procs_y/), (/.true., .true./), .false., MPI_COMM_CART, & + & ierr) ! Finding the Cartesian coordinates of the local process - call MPI_CART_COORDS(MPI_COMM_CART, proc_rank, 2, & - proc_coords, ierr) - + call MPI_CART_COORDS(MPI_COMM_CART, proc_rank, 2, proc_coords, ierr) end if ! END: 2D Cartesian Processor Topology @@ -1830,8 +1568,7 @@ contains ! Boundary condition at the beginning if (proc_coords(2) > 0 .or. (bc_y%beg == BC_PERIODIC .and. num_procs_y > 1)) then proc_coords(2) = proc_coords(2) - 1 - call MPI_CART_RANK(MPI_COMM_CART, proc_coords, & - bc_y%beg, ierr) + call MPI_CART_RANK(MPI_COMM_CART, proc_coords, bc_y%beg, ierr) proc_coords(2) = proc_coords(2) + 1 nidx(2)%beg = -1 end if @@ -1839,8 +1576,7 @@ contains ! Boundary condition at the end if (proc_coords(2) < num_procs_y - 1 .or. (bc_y%end == BC_PERIODIC .and. num_procs_y > 1)) then proc_coords(2) = proc_coords(2) + 1 - call MPI_CART_RANK(MPI_COMM_CART, proc_coords, & - bc_y%end, ierr) + call MPI_CART_RANK(MPI_COMM_CART, proc_coords, bc_y%end, ierr) proc_coords(2) = proc_coords(2) - 1 nidx(2)%end = 1 end if @@ -1874,16 +1610,12 @@ contains dy = (y_domain%end - y_domain%beg)/real(n_glb + 1, wp) if (proc_coords(2) < rem_cells) then - y_domain%beg = y_domain%beg + dy*real((n + 1)* & - proc_coords(2)) - y_domain%end = y_domain%end - dy*real((n + 1)* & - (num_procs_y - proc_coords(2) - 1) & - - (num_procs_y - rem_cells)) + y_domain%beg = y_domain%beg + dy*real((n + 1)*proc_coords(2)) + y_domain%end = y_domain%end - dy*real((n + 1)*(num_procs_y - proc_coords(2) - 1) - (num_procs_y & + & - rem_cells)) else - y_domain%beg = y_domain%beg + dy*real((n + 1)* & - proc_coords(2) + rem_cells) - y_domain%end = y_domain%end - dy*real((n + 1)* & - (num_procs_y - proc_coords(2) - 1)) + y_domain%beg = y_domain%beg + dy*real((n + 1)*proc_coords(2) + rem_cells) + y_domain%end = y_domain%end - dy*real((n + 1)*(num_procs_y - proc_coords(2) - 1)) end if end if #endif @@ -1891,19 +1623,14 @@ contains ! 1D Cartesian Processor Topology else - ! Optimal processor topology num_procs_x = num_procs ! Creating new communicator using the Cartesian topology - call MPI_CART_CREATE(MPI_COMM_WORLD, 1, (/num_procs_x/), & - (/.true./), .false., MPI_COMM_CART, & - ierr) + call MPI_CART_CREATE(MPI_COMM_WORLD, 1, (/num_procs_x/), (/.true./), .false., MPI_COMM_CART, ierr) ! Finding the Cartesian coordinates of the local process - call MPI_CART_COORDS(MPI_COMM_CART, proc_rank, 1, & - proc_coords, ierr) - + call MPI_CART_COORDS(MPI_COMM_CART, proc_rank, 1, proc_coords, ierr) end if ! Global Parameters for x-direction @@ -1968,24 +1695,17 @@ contains dx = (x_domain%end - x_domain%beg)/real(m_glb + 1, wp) if (proc_coords(1) < rem_cells) then - x_domain%beg = x_domain%beg + dx*real((m + 1)* & - proc_coords(1)) - x_domain%end = x_domain%end - dx*real((m + 1)* & - (num_procs_x - proc_coords(1) - 1) & - - (num_procs_x - rem_cells)) + x_domain%beg = x_domain%beg + dx*real((m + 1)*proc_coords(1)) + x_domain%end = x_domain%end - dx*real((m + 1)*(num_procs_x - proc_coords(1) - 1) - (num_procs_x - rem_cells)) else - x_domain%beg = x_domain%beg + dx*real((m + 1)* & - proc_coords(1) + rem_cells) - x_domain%end = x_domain%end - dx*real((m + 1)* & - (num_procs_x - proc_coords(1) - 1)) + x_domain%beg = x_domain%beg + dx*real((m + 1)*proc_coords(1) + rem_cells) + x_domain%end = x_domain%end - dx*real((m + 1)*(num_procs_x - proc_coords(1) - 1)) end if end if #endif end if - @:ALLOCATE(neighbor_ranks(nidx(1)%beg:nidx(1)%end, & - nidx(2)%beg:nidx(2)%end, & - nidx(3)%beg:nidx(3)%end)) + @:ALLOCATE(neighbor_ranks(nidx(1)%beg:nidx(1)%end, nidx(2)%beg:nidx(2)%end, nidx(3)%beg:nidx(3)%end)) do k = nidx(3)%beg, nidx(3)%end do j = nidx(2)%beg, nidx(2)%end do i = nidx(1)%beg, nidx(1)%end @@ -1993,8 +1713,7 @@ contains neighbor_coords(1) = proc_coords(1) + i if (num_dims > 1) neighbor_coords(2) = proc_coords(2) + j if (num_dims > 2) neighbor_coords(3) = proc_coords(3) + k - call MPI_CART_RANK(MPI_COMM_CART, neighbor_coords, & - neighbor_ranks(i, j, k), ierr) + call MPI_CART_RANK(MPI_COMM_CART, neighbor_coords, neighbor_ranks(i, j, k), ierr) end if end do end do @@ -2003,14 +1722,11 @@ contains end subroutine s_mpi_decompose_computational_domain - !> The goal of this procedure is to populate the buffers of - !! the grid variables by communicating with the neighboring - !! processors. Note that only the buffers of the cell-width - !! distributions are handled in such a way. This is because - !! the buffers of cell-boundary locations may be calculated - !! directly from those of the cell-width distributions. - !! @param mpi_dir MPI communication coordinate direction - !! @param pbc_loc Processor boundary condition (PBC) location + !> The goal of this procedure is to populate the buffers of the grid variables by communicating with the neighboring processors. + !! Note that only the buffers of the cell-width distributions are handled in such a way. This is because the buffers of + !! cell-boundary locations may be calculated directly from those of the cell-width distributions. + !! @param mpi_dir MPI communication coordinate direction + !! @param pbc_loc Processor boundary condition (PBC) location #ifndef MFC_PRE_PROCESS subroutine s_mpi_sendrecv_grid_variables_buffers(mpi_dir, pbc_loc) @@ -2018,169 +1734,90 @@ contains integer, intent(in) :: pbc_loc #ifdef MFC_MPI - integer :: ierr !< Generic flag used to identify and report MPI errors + integer :: ierr !< Generic flag used to identify and report MPI errors ! MPI Communication in x-direction if (mpi_dir == 1) then + if (pbc_loc == -1) then ! PBC at the beginning - if (pbc_loc == -1) then ! PBC at the beginning - - if (bc_x%end >= 0) then ! PBC at the beginning and end + if (bc_x%end >= 0) then ! PBC at the beginning and end ! Send/receive buffer to/from bc_x%end/bc_x%beg - call MPI_SENDRECV( & - dx(m - buff_size + 1), buff_size, & - mpi_p, bc_x%end, 0, & - dx(-buff_size), buff_size, & - mpi_p, bc_x%beg, 0, & - MPI_COMM_WORLD, MPI_STATUS_IGNORE, ierr) - - else ! PBC at the beginning only - + call MPI_SENDRECV(dx(m - buff_size + 1), buff_size, mpi_p, bc_x%end, 0, dx(-buff_size), buff_size, mpi_p, & + & bc_x%beg, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE, ierr) + else ! PBC at the beginning only ! Send/receive buffer to/from bc_x%beg/bc_x%beg - call MPI_SENDRECV( & - dx(0), buff_size, & - mpi_p, bc_x%beg, 1, & - dx(-buff_size), buff_size, & - mpi_p, bc_x%beg, 0, & - MPI_COMM_WORLD, MPI_STATUS_IGNORE, ierr) - + call MPI_SENDRECV(dx(0), buff_size, mpi_p, bc_x%beg, 1, dx(-buff_size), buff_size, mpi_p, bc_x%beg, 0, & + & MPI_COMM_WORLD, MPI_STATUS_IGNORE, ierr) end if - - else ! PBC at the end - - if (bc_x%beg >= 0) then ! PBC at the end and beginning + else ! PBC at the end + if (bc_x%beg >= 0) then ! PBC at the end and beginning ! Send/receive buffer to/from bc_x%beg/bc_x%end - call MPI_SENDRECV( & - dx(0), buff_size, & - mpi_p, bc_x%beg, 1, & - dx(m + 1), buff_size, & - mpi_p, bc_x%end, 1, & - MPI_COMM_WORLD, MPI_STATUS_IGNORE, ierr) - - else ! PBC at the end only - + call MPI_SENDRECV(dx(0), buff_size, mpi_p, bc_x%beg, 1, dx(m + 1), buff_size, mpi_p, bc_x%end, 1, & + & MPI_COMM_WORLD, MPI_STATUS_IGNORE, ierr) + else ! PBC at the end only ! Send/receive buffer to/from bc_x%end/bc_x%end - call MPI_SENDRECV( & - dx(m - buff_size + 1), buff_size, & - mpi_p, bc_x%end, 0, & - dx(m + 1), buff_size, & - mpi_p, bc_x%end, 1, & - MPI_COMM_WORLD, MPI_STATUS_IGNORE, ierr) - + call MPI_SENDRECV(dx(m - buff_size + 1), buff_size, mpi_p, bc_x%end, 0, dx(m + 1), buff_size, mpi_p, & + & bc_x%end, 1, MPI_COMM_WORLD, MPI_STATUS_IGNORE, ierr) end if - end if ! END: MPI Communication in x-direction ! MPI Communication in y-direction - elseif (mpi_dir == 2) then - - if (pbc_loc == -1) then ! PBC at the beginning + else if (mpi_dir == 2) then + if (pbc_loc == -1) then ! PBC at the beginning - if (bc_y%end >= 0) then ! PBC at the beginning and end + if (bc_y%end >= 0) then ! PBC at the beginning and end ! Send/receive buffer to/from bc_y%end/bc_y%beg - call MPI_SENDRECV( & - dy(n - buff_size + 1), buff_size, & - mpi_p, bc_y%end, 0, & - dy(-buff_size), buff_size, & - mpi_p, bc_y%beg, 0, & - MPI_COMM_WORLD, MPI_STATUS_IGNORE, ierr) - - else ! PBC at the beginning only - + call MPI_SENDRECV(dy(n - buff_size + 1), buff_size, mpi_p, bc_y%end, 0, dy(-buff_size), buff_size, mpi_p, & + & bc_y%beg, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE, ierr) + else ! PBC at the beginning only ! Send/receive buffer to/from bc_y%beg/bc_y%beg - call MPI_SENDRECV( & - dy(0), buff_size, & - mpi_p, bc_y%beg, 1, & - dy(-buff_size), buff_size, & - mpi_p, bc_y%beg, 0, & - MPI_COMM_WORLD, MPI_STATUS_IGNORE, ierr) - + call MPI_SENDRECV(dy(0), buff_size, mpi_p, bc_y%beg, 1, dy(-buff_size), buff_size, mpi_p, bc_y%beg, 0, & + & MPI_COMM_WORLD, MPI_STATUS_IGNORE, ierr) end if - - else ! PBC at the end - - if (bc_y%beg >= 0) then ! PBC at the end and beginning + else ! PBC at the end + if (bc_y%beg >= 0) then ! PBC at the end and beginning ! Send/receive buffer to/from bc_y%beg/bc_y%end - call MPI_SENDRECV( & - dy(0), buff_size, & - mpi_p, bc_y%beg, 1, & - dy(n + 1), buff_size, & - mpi_p, bc_y%end, 1, & - MPI_COMM_WORLD, MPI_STATUS_IGNORE, ierr) - - else ! PBC at the end only - + call MPI_SENDRECV(dy(0), buff_size, mpi_p, bc_y%beg, 1, dy(n + 1), buff_size, mpi_p, bc_y%end, 1, & + & MPI_COMM_WORLD, MPI_STATUS_IGNORE, ierr) + else ! PBC at the end only ! Send/receive buffer to/from bc_y%end/bc_y%end - call MPI_SENDRECV( & - dy(n - buff_size + 1), buff_size, & - mpi_p, bc_y%end, 0, & - dy(n + 1), buff_size, & - mpi_p, bc_y%end, 1, & - MPI_COMM_WORLD, MPI_STATUS_IGNORE, ierr) - + call MPI_SENDRECV(dy(n - buff_size + 1), buff_size, mpi_p, bc_y%end, 0, dy(n + 1), buff_size, mpi_p, & + & bc_y%end, 1, MPI_COMM_WORLD, MPI_STATUS_IGNORE, ierr) end if - end if ! END: MPI Communication in y-direction ! MPI Communication in z-direction else + if (pbc_loc == -1) then ! PBC at the beginning - if (pbc_loc == -1) then ! PBC at the beginning - - if (bc_z%end >= 0) then ! PBC at the beginning and end + if (bc_z%end >= 0) then ! PBC at the beginning and end ! Send/receive buffer to/from bc_z%end/bc_z%beg - call MPI_SENDRECV( & - dz(p - buff_size + 1), buff_size, & - mpi_p, bc_z%end, 0, & - dz(-buff_size), buff_size, & - mpi_p, bc_z%beg, 0, & - MPI_COMM_WORLD, MPI_STATUS_IGNORE, ierr) - - else ! PBC at the beginning only - + call MPI_SENDRECV(dz(p - buff_size + 1), buff_size, mpi_p, bc_z%end, 0, dz(-buff_size), buff_size, mpi_p, & + & bc_z%beg, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE, ierr) + else ! PBC at the beginning only ! Send/receive buffer to/from bc_z%beg/bc_z%beg - call MPI_SENDRECV( & - dz(0), buff_size, & - mpi_p, bc_z%beg, 1, & - dz(-buff_size), buff_size, & - mpi_p, bc_z%beg, 0, & - MPI_COMM_WORLD, MPI_STATUS_IGNORE, ierr) - + call MPI_SENDRECV(dz(0), buff_size, mpi_p, bc_z%beg, 1, dz(-buff_size), buff_size, mpi_p, bc_z%beg, 0, & + & MPI_COMM_WORLD, MPI_STATUS_IGNORE, ierr) end if - - else ! PBC at the end - - if (bc_z%beg >= 0) then ! PBC at the end and beginning + else ! PBC at the end + if (bc_z%beg >= 0) then ! PBC at the end and beginning ! Send/receive buffer to/from bc_z%beg/bc_z%end - call MPI_SENDRECV( & - dz(0), buff_size, & - mpi_p, bc_z%beg, 1, & - dz(p + 1), buff_size, & - mpi_p, bc_z%end, 1, & - MPI_COMM_WORLD, MPI_STATUS_IGNORE, ierr) - - else ! PBC at the end only - + call MPI_SENDRECV(dz(0), buff_size, mpi_p, bc_z%beg, 1, dz(p + 1), buff_size, mpi_p, bc_z%end, 1, & + & MPI_COMM_WORLD, MPI_STATUS_IGNORE, ierr) + else ! PBC at the end only ! Send/receive buffer to/from bc_z%end/bc_z%end - call MPI_SENDRECV( & - dz(p - buff_size + 1), buff_size, & - mpi_p, bc_z%end, 0, & - dz(p + 1), buff_size, & - mpi_p, bc_z%end, 1, & - MPI_COMM_WORLD, MPI_STATUS_IGNORE, ierr) - + call MPI_SENDRECV(dz(p - buff_size + 1), buff_size, mpi_p, bc_z%end, 0, dz(p + 1), buff_size, mpi_p, & + & bc_z%end, 1, MPI_COMM_WORLD, MPI_STATUS_IGNORE, ierr) end if - end if - end if ! END: MPI Communication in z-direction #endif diff --git a/src/common/m_nvtx.f90 b/src/common/m_nvtx.f90 index 449401128b..82d6e1a208 100644 --- a/src/common/m_nvtx.f90 +++ b/src/common/m_nvtx.f90 @@ -9,64 +9,64 @@ module m_nvtx implicit none - integer, private :: col(7) = [ & - int(Z'0000ff00'), int(Z'000000ff'), int(Z'00ffff00'), & - int(Z'00ff00ff'), int(Z'0000ffff'), int(Z'00ff0000'), & - int(Z'00ffffff') & - ] + integer, private :: col(7) = [int(Z'0000ff00'), int(Z'000000ff'), int(Z'00ffff00'), int(Z'00ff00ff'), int(Z'0000ffff'), & + & int(Z'00ff0000'), int(Z'00ffffff')] character(len=256), private :: tempName type, bind(C) :: nvtxEventAttributes integer(c_int16_t) :: version = 1 - integer(c_int16_t) :: size = 48 ! - integer(c_int) :: category = 0 - integer(c_int) :: colorType = 1 ! NVTX_COLOR_ARGB = 1 - integer(c_int) :: color - integer(c_int) :: payloadType = 0 ! NVTX_PAYLOAD_UNKNOWN = 0 - integer(c_int) :: reserved0 - integer(c_int64_t) :: payload ! union uint,int,double - integer(c_int) :: messageType = 1 ! NVTX_MESSAGE_TYPE_ASCII = 1 - type(c_ptr) :: message ! ascii char + integer(c_int16_t) :: size = 48 ! + integer(c_int) :: category = 0 + integer(c_int) :: colorType = 1 ! NVTX_COLOR_ARGB = 1 + integer(c_int) :: color + integer(c_int) :: payloadType = 0 ! NVTX_PAYLOAD_UNKNOWN = 0 + integer(c_int) :: reserved0 + integer(c_int64_t) :: payload ! union uint,int,double + integer(c_int) :: messageType = 1 ! NVTX_MESSAGE_TYPE_ASCII = 1 + type(c_ptr) :: message ! ascii char end type nvtxEventAttributes #if defined(MFC_GPU) && defined(__PGI) - interface nvtxRangePush ! push range with custom label and standard color subroutine nvtxRangePushA(name) bind(C, name='nvtxRangePushA') + use iso_c_binding - character(kind=c_char, len=*), intent(IN) :: name + character(kind=c_char, len=*), intent(in) :: name + end subroutine nvtxRangePushA ! push range with custom label and custom color subroutine nvtxRangePushEx(event) bind(C, name='nvtxRangePushEx') + use iso_c_binding import :: nvtxEventAttributes - type(nvtxEventAttributes), intent(IN) :: event + type(nvtxEventAttributes), intent(in) :: event + end subroutine nvtxRangePushEx end interface nvtxRangePush interface nvtxRangePop subroutine nvtxRangePop() bind(C, name='nvtxRangePop') + end subroutine nvtxRangePop end interface nvtxRangePop - #endif contains !> @brief Pushes a named NVTX range for GPU profiling, optionally with a color based on the given identifier. subroutine nvtxStartRange(name, id) - character(kind=c_char, len=*), intent(IN) :: name - integer, intent(IN), optional :: id - type(nvtxEventAttributes) :: event -#if defined(MFC_GPU) && defined(__PGI) + character(kind=c_char, len=*), intent(in) :: name + integer, intent(in), optional :: id + type(nvtxEventAttributes) :: event - tempName = trim(name)//c_null_char +#if defined(MFC_GPU) && defined(__PGI) + tempName = trim(name) // c_null_char if (.not. present(id)) then call nvtxRangePush(tempName) @@ -75,15 +75,17 @@ subroutine nvtxStartRange(name, id) event%message = c_loc(tempName) call nvtxRangePushEx(event) end if - #endif + end subroutine nvtxStartRange !> @brief Pops the current NVTX range to end the GPU profiling region. subroutine nvtxEndRange + #if defined(MFC_GPU) && defined(__PGI) call nvtxRangePop #endif + end subroutine nvtxEndRange end module m_nvtx diff --git a/src/common/m_phase_change.fpp b/src/common/m_phase_change.fpp index ecd519e41c..f8e5aaa6f0 100644 --- a/src/common/m_phase_change.fpp +++ b/src/common/m_phase_change.fpp @@ -9,35 +9,26 @@ module m_phase_change #ifndef MFC_POST_PROCESS - - use m_derived_types !< Definitions of the derived types - - use m_global_parameters !< Definitions of the global parameters - - use m_mpi_proxy !< Message passing interface (MPI) module proxy - - use m_variables_conversion !< State variables type conversion procedures - + use m_derived_types !< Definitions of the derived types + use m_global_parameters !< Definitions of the global parameters + use m_mpi_proxy !< Message passing interface (MPI) module proxy + use m_variables_conversion !< State variables type conversion procedures use ieee_arithmetic - - use m_helper_basic !< Functions to compare floating point numbers + use m_helper_basic !< Functions to compare floating point numbers implicit none - private; - public :: s_initialize_phasechange_module, & - s_relaxation_solver, & - s_infinite_relaxation_k, & - s_finalize_relaxation_solver_module + private + public :: s_initialize_phasechange_module, s_relaxation_solver, s_infinite_relaxation_k, s_finalize_relaxation_solver_module !> @name Parameters for the first order transition phase change !> @{ - integer, parameter :: max_iter = 1e8_wp !< max # of iterations - real(wp), parameter :: pCr = 4.94e7_wp !< Critical water pressure + integer, parameter :: max_iter = 1e8_wp !< max # of iterations + real(wp), parameter :: pCr = 4.94e7_wp !< Critical water pressure real(wp), parameter :: TCr = 385.05_wp + 273.15_wp !< Critical water temperature - real(wp), parameter :: mixM = 1.0e-8_wp !< threshold for 'mixture cell'. If Y < mixM, phase change does not happen - integer, parameter :: lp = 1 !< index for the liquid phase of the reacting fluid - integer, parameter :: vp = 2 !< index for the vapor phase of the reacting fluid + real(wp), parameter :: mixM = 1.0e-8_wp !< threshold for 'mixture cell'. If Y < mixM, phase change does not happen + integer, parameter :: lp = 1 !< index for the liquid phase of the reacting fluid + integer, parameter :: vp = 2 !< index for the vapor phase of the reacting fluid !> @} !> @name Gibbs free energy phase change parameters @@ -45,55 +36,53 @@ module m_phase_change real(wp) :: A, B, C, D !> @} - $:GPU_DECLARE(create='[A,B,C,D]') + $:GPU_DECLARE(create='[A, B, C, D]') contains - !> This subroutine should dispatch to the correct relaxation solver based - !! some parameter. It replaces the procedure pointer, which CCE - !! is breaking on. + !> This subroutine should dispatch to the correct relaxation solver based some parameter. It replaces the procedure pointer, + !! which CCE is breaking on. impure subroutine s_relaxation_solver(q_cons_vf) + type(scalar_field), dimension(sys_size), intent(inout) :: q_cons_vf - ! This is empty because in current master the procedure pointer - ! was never assigned + ! This is empty because in current master the procedure pointer was never assigned + @:ASSERT(.false., "s_relaxation_solver called but it currently does nothing") + end subroutine s_relaxation_solver - !> The purpose of this subroutine is to initialize the phase change module - !! by setting the parameters needed for phase change and - !! selecting the phase change module that will be used - !! (pT- or pTg-equilibrium) + !> The purpose of this subroutine is to initialize the phase change module by setting the parameters needed for phase change and + !! selecting the phase change module that will be used (pT- or pTg-equilibrium) impure subroutine s_initialize_phasechange_module + ! variables used in the calculation of the saturation curves for fluids 1 and 2 - A = (gs_min(lp)*cvs(lp) - gs_min(vp)*cvs(vp) & - + qvps(vp) - qvps(lp))/((gs_min(vp) - 1.0_wp)*cvs(vp)) + A = (gs_min(lp)*cvs(lp) - gs_min(vp)*cvs(vp) + qvps(vp) - qvps(lp))/((gs_min(vp) - 1.0_wp)*cvs(vp)) B = (qvs(lp) - qvs(vp))/((gs_min(vp) - 1.0_wp)*cvs(vp)) - C = (gs_min(vp)*cvs(vp) - gs_min(lp)*cvs(lp)) & - /((gs_min(vp) - 1.0_wp)*cvs(vp)) + C = (gs_min(vp)*cvs(vp) - gs_min(lp)*cvs(lp))/((gs_min(vp) - 1.0_wp)*cvs(vp)) - D = ((gs_min(lp) - 1.0_wp)*cvs(lp)) & - /((gs_min(vp) - 1.0_wp)*cvs(vp)) + D = ((gs_min(lp) - 1.0_wp)*cvs(lp))/((gs_min(vp) - 1.0_wp)*cvs(vp)) end subroutine s_initialize_phasechange_module - !> This subroutine is created to activate either the pT- (N fluids) or the - !! pTg-equilibrium (2 fluids for g-equilibrium) - !! model, also considering mass depletion, depending on the incoming - !! state conditions. - !! @param q_cons_vf Cell-average conservative variables + !> This subroutine is created to activate either the pT- (N fluids) or the pTg-equilibrium (2 fluids for g-equilibrium) model, + !! also considering mass depletion, depending on the incoming state conditions. + !! @param q_cons_vf Cell-average conservative variables subroutine s_infinite_relaxation_k(q_cons_vf) type(scalar_field), dimension(sys_size), intent(inout) :: q_cons_vf - real(wp) :: pS, pSOV, pSSL !< equilibrium pressure for mixture, overheated vapor, and subcooled liquid - real(wp) :: TS, TSOV, TSSL, TSatOV, TSatSL !< equilibrium temperature for mixture, overheated vapor, and subcooled liquid. Saturation Temperatures at overheated vapor and subcooled liquid - real(wp) :: rhoe, dynE, rhos !< total internal energy, kinetic energy, and total entropy - real(wp) :: rho, rM, m1, m2, MCT !< total density, total reacting mass, individual reacting masses - real(wp) :: TvF !< total volume fraction + real(wp) :: pS, pSOV, pSSL !< equilibrium pressure for mixture, overheated vapor, and subcooled liquid + !> equilibrium temperature for mixture, overheated vapor, and subcooled liquid. Saturation Temperatures at overheated vapor + !! and subcooled liquid + real(wp) :: TS, TSOV, TSSL, TSatOV, TSatSL + real(wp) :: rhoe, dynE, rhos !< total internal energy, kinetic energy, and total entropy + real(wp) :: rho, rM, m1, m2, MCT !< total density, total reacting mass, individual reacting masses + real(wp) :: TvF !< total volume fraction ! $:GPU_DECLARE(create='[pS,pSOV,pSSL,TS,TSOV,TSSL,TSatOV,TSatSL]') ! $:GPU_DECLARE(create='[rhoe,dynE,rhos,rho,rM,m1,m2,MCT,TvF]') + #:if not MFC_CASE_OPTIMIZATION and USING_AMD real(wp), dimension(3) :: p_infOV, p_infpT, p_infSL, sk, hk, gk, ek, rhok #:else @@ -101,35 +90,30 @@ contains #:endif ! $:GPU_DECLARE(create='[p_infOV,p_infpT,p_infSL,sk,hk,gk,ek,rhok]') - !< Generic loop iterators + !> Generic loop iterators integer :: i, j, k, l #ifdef _CRAYFTN #ifdef MFC_OpenACC - ! CCE 19 IPA workaround: prevent bring_routine_resident SIGSEGV - !DIR$ NOINLINE s_infinite_pt_relaxation_k - !DIR$ NOINLINE s_infinite_ptg_relaxation_k - !DIR$ NOINLINE s_correct_partial_densities - !DIR$ NOINLINE s_TSat + ! CCE 19 IPA workaround: prevent bring_routine_resident SIGSEGV DIR$ NOINLINE s_infinite_pt_relaxation_k DIR$ NOINLINE + ! s_infinite_ptg_relaxation_k DIR$ NOINLINE s_correct_partial_densities DIR$ NOINLINE s_TSat #endif #endif ! starting equilibrium solver - $:GPU_PARALLEL_LOOP(collapse=3, private='[i,j,k,l,p_infOV, p_infpT, p_infSL, sk, hk, gk, ek, rhok,pS, pSOV, pSSL, TS, TSOV, TSatOV, TSatSL, TSSL, rhoe, dynE, rhos, rho, rM, m1, m2, MCT, TvF]') + $:GPU_PARALLEL_LOOP(collapse=3, private='[i, j, k, l, p_infOV, p_infpT, p_infSL, sk, hk, gk, ek, rhok, pS, pSOV, pSSL, & + & TS, TSOV, TSatOV, TSatSL, TSSL, rhoe, dynE, rhos, rho, rM, m1, m2, MCT, TvF]') do j = 0, m do k = 0, n do l = 0, p - rho = 0.0_wp; TvF = 0.0_wp $:GPU_LOOP(parallelism='[seq]') do i = 1, num_fluids - ! Mixture density rho = rho + q_cons_vf(i + contxb - 1)%sf(j, k, l) ! Total Volume Fraction TvF = TvF + q_cons_vf(i + advxb - 1)%sf(j, k, l) - end do ! calculating the total reacting mass for the phase change process. By hypothesis, this should not change @@ -149,33 +133,28 @@ contains dynE = 0.0_wp $:GPU_LOOP(parallelism='[seq]') do i = momxb, momxe - dynE = dynE + 5.0e-1_wp*q_cons_vf(i)%sf(j, k, l)**2/rho - end do - ! calculating the total energy that MUST be preserved throughout the pT- and pTg-relaxation procedures - ! at each of the cells. The internal energy is calculated as the total energy minus the kinetic - ! energy to preserved its value at sharp interfaces + ! calculating the total energy that MUST be preserved throughout the pT- and pTg-relaxation procedures at each + ! of the cells. The internal energy is calculated as the total energy minus the kinetic energy to preserved its + ! value at sharp interfaces rhoe = q_cons_vf(E_idx)%sf(j, k, l) - dynE - ! Calling pT-equilibrium for either finishing phase-change module, or as an IC for the pTg-equilibrium - ! for this case, MFL cannot be either 0 or 1, so I chose it to be 2 + ! Calling pT-equilibrium for either finishing phase-change module, or as an IC for the pTg-equilibrium for this + ! case, MFL cannot be either 0 or 1, so I chose it to be 2 call s_infinite_pt_relaxation_k(j, k, l, 2, pS, p_infpT, q_cons_vf, rhoe, TS) - ! check if pTg-equilibrium is required - ! NOTE that NOTHING else needs to be updated OTHER than the individual partial densities - ! given the outputs from the pT- and pTg-equilibrium solvers are just p and one of the partial masses - ! (pTg- case) - if ((relax_model == 6) .and. ((q_cons_vf(lp + contxb - 1)%sf(j, k, l) > mixM*rM) & - .and. (q_cons_vf(vp + contxb - 1)%sf(j, k, l) > mixM*rM)) & - .and. (pS < pCr) .and. (TS < TCr)) then + ! check if pTg-equilibrium is required NOTE that NOTHING else needs to be updated OTHER than the individual + ! partial densities given the outputs from the pT- and pTg-equilibrium solvers are just p and one of the partial + ! masses (pTg- case) + if ((relax_model == 6) .and. ((q_cons_vf(lp + contxb - 1)%sf(j, k, & + & l) > mixM*rM) .and. (q_cons_vf(vp + contxb - 1)%sf(j, k, & + & l) > mixM*rM)) .and. (pS < pCr) .and. (TS < TCr)) then + ! Checking if phase change is needed, by checking whether the final solution is either subcoooled liquid or + ! overheated vapor. - ! Checking if phase change is needed, by checking whether the final solution is either subcoooled - ! liquid or overheated vapor. - - ! overheated vapor case - ! depleting the mass of liquid + ! overheated vapor case depleting the mass of liquid q_cons_vf(lp + contxb - 1)%sf(j, k, l) = mixM*rM ! transferring the total mass to vapor @@ -187,8 +166,7 @@ contains ! calculating Saturation temperature call s_TSat(pSOV, TSatOV, TSOV) - ! subcooled liquid case - ! transferring the total mass to liquid + ! subcooled liquid case transferring the total mass to liquid q_cons_vf(lp + contxb - 1)%sf(j, k, l) = (1.0_wp - mixM)*rM ! depleting the mass of vapor @@ -202,7 +180,6 @@ contains ! checking the conditions for overheated vapor and subcooled liquide if (TSOV > TSatOV) then - ! Assigning pressure pS = pSOV @@ -214,9 +191,7 @@ contains ! correcting the vapor partial density q_cons_vf(vp + contxb - 1)%sf(j, k, l) = (1.0_wp - mixM)*rM - - elseif (TSSL < TSatSL) then - + else if (TSSL < TSatSL) then ! Assigning pressure pS = pSSL @@ -228,11 +203,8 @@ contains ! correcting the vapor partial density q_cons_vf(vp + contxb - 1)%sf(j, k, l) = mixM*rM - else - - ! returning partial pressures to what they were from the homogeneous solver - ! liquid + ! returning partial pressures to what they were from the homogeneous solver liquid q_cons_vf(lp + contxb - 1)%sf(j, k, l) = m1 ! vapor @@ -240,9 +212,7 @@ contains ! calling the pTg-equilibrium solver call s_infinite_ptg_relaxation_k(j, k, l, pS, p_infpT, rhoe, q_cons_vf, TS) - end if - end if ! Calculations AFTER equilibrium @@ -250,31 +220,25 @@ contains $:GPU_LOOP(parallelism='[seq]') do i = 1, num_fluids ! entropy - sk(i) = cvs(i)*log((TS**gs_min(i)) & - /((pS + ps_inf(i))**(gs_min(i) - 1.0_wp))) + qvps(i) + sk(i) = cvs(i)*log((TS**gs_min(i))/((pS + ps_inf(i))**(gs_min(i) - 1.0_wp))) + qvps(i) ! enthalpy - hk(i) = gs_min(i)*cvs(i)*TS & - + qvs(i) + hk(i) = gs_min(i)*cvs(i)*TS + qvs(i) ! Gibbs-free energy gk(i) = hk(i) - TS*sk(i) ! densities - rhok(i) = (pS + ps_inf(i)) & - /((gs_min(i) - 1)*cvs(i)*TS) + rhok(i) = (pS + ps_inf(i))/((gs_min(i) - 1)*cvs(i)*TS) ! internal energy - ek(i) = (pS + gs_min(i) & - *ps_inf(i))/(pS + ps_inf(i)) & - *cvs(i)*TS + qvs(i) + ek(i) = (pS + gs_min(i)*ps_inf(i))/(pS + ps_inf(i))*cvs(i)*TS + qvs(i) end do ! calculating volume fractions, internal energies, and total entropy rhos = 0.0_wp $:GPU_LOOP(parallelism='[seq]') do i = 1, num_fluids - ! volume fractions q_cons_vf(i + advxb - 1)%sf(j, k, l) = q_cons_vf(i + contxb - 1)%sf(j, k, l)/rhok(i) @@ -285,7 +249,6 @@ contains ! Total entropy rhos = rhos + q_cons_vf(i + contxb - 1)%sf(j, k, l)*sk(i) - end do end do end do @@ -294,31 +257,30 @@ contains end subroutine s_infinite_relaxation_k - !> This auxiliary subroutine is created to activate the pT-equilibrium for N fluids - !! @param j generic loop iterator for x direction - !! @param k generic loop iterator for y direction - !! @param l generic loop iterator for z direction - !! @param MFL flag that tells whether the fluid is gas (0), liquid (1), or a mixture (2) - !! @param pS equilibrium pressure at the interface - !! @param p_infpT stiffness for the participating fluids under pT-equilibrium - !! @param q_cons_vf Cell-average conservative variables - !! @param rhoe mixture energy - !! @param TS equilibrium temperature at the interface + !> This auxiliary subroutine is created to activate the pT-equilibrium for N fluids + !! @param j generic loop iterator for x direction + !! @param k generic loop iterator for y direction + !! @param l generic loop iterator for z direction + !! @param MFL flag that tells whether the fluid is gas (0), liquid (1), or a mixture (2) + !! @param pS equilibrium pressure at the interface + !! @param p_infpT stiffness for the participating fluids under pT-equilibrium + !! @param q_cons_vf Cell-average conservative variables + !! @param rhoe mixture energy + !! @param TS equilibrium temperature at the interface subroutine s_infinite_pt_relaxation_k(j, k, l, MFL, pS, p_infpT, q_cons_vf, rhoe, TS) - $:GPU_ROUTINE(function_name='s_infinite_pt_relaxation_k', & - & parallelism='[seq]', cray_noinline=True) + + $:GPU_ROUTINE(function_name='s_infinite_pt_relaxation_k', parallelism='[seq]', cray_noinline=True) ! initializing variables - integer, intent(in) :: j, k, l, MFL - real(wp), intent(out) :: pS - real(wp), dimension(1:), intent(out) :: p_infpT + integer, intent(in) :: j, k, l, MFL + real(wp), intent(out) :: pS + real(wp), dimension(1:), intent(out) :: p_infpT type(scalar_field), dimension(sys_size), intent(in) :: q_cons_vf - real(wp), intent(in) :: rhoe - real(wp), intent(out) :: TS - real(wp) :: gp, gpp, hp, pO, mCP, mQ !< variables for the Newton Solver - real(wp) :: p_infpT_sum - - integer :: i, ns !< generic loop iterators + real(wp), intent(in) :: rhoe + real(wp), intent(out) :: TS + real(wp) :: gp, gpp, hp, pO, mCP, mQ !< variables for the Newton Solver + real(wp) :: p_infpT_sum + integer :: i, ns !< generic loop iterators ! auxiliary variables for the pT-equilibrium solver mCP = 0.0_wp; mQ = 0.0_wp; p_infpT_sum = 0._wp @@ -330,13 +292,11 @@ contains ! Performing tests before initializing the pT-equilibrium $:GPU_LOOP(parallelism='[seq]') do i = 1, num_fluids - ! sum of the total alpha*rho*cp of the system mCP = mCP + q_cons_vf(i + contxb - 1)%sf(j, k, l)*cvs(i)*gs_min(i) ! sum of the total alpha*rho*q of the system mQ = mQ + q_cons_vf(i + contxb - 1)%sf(j, k, l)*qvs(i) - end do #:if not MFC_CASE_OPTIMIZATION and USING_AMD @@ -350,11 +310,8 @@ contains ! Checking energy constraint if ((rhoe - mQ - minval(p_infpT)) < 0.0_wp) then - if ((MFL == 0) .or. (MFL == 1)) then - - ! Assigning zero values for mass depletion cases - ! pressure + ! Assigning zero values for mass depletion cases pressure pS = 0.0_wp ! temperature @@ -362,22 +319,20 @@ contains return end if - end if - ! calculating initial estimate for pressure in the pT-relaxation procedure. I will also use this variable to - ! iterate over the Newton's solver + ! calculating initial estimate for pressure in the pT-relaxation procedure. I will also use this variable to iterate over + ! the Newton's solver pO = 0.0_wp - ! Maybe improve this condition afterwards. As long as the initial guess is in between -min(ps_inf) - ! and infinity, a solution should be able to be found. + ! Maybe improve this condition afterwards. As long as the initial guess is in between -min(ps_inf) and infinity, a solution + ! should be able to be found. pS = 1.0e4_wp ! Newton Solver for the pT-equilibrium ns = 0 ! change this relative error metric. 1.e4_wp is just arbitrary do while ((abs(pS - pO) > palpha_eps) .and. (abs((pS - pO)/pO) > palpha_eps/1.e4_wp) .or. (ns == 0)) - ! increasing counter ns = ns + 1 @@ -388,20 +343,16 @@ contains gpp = 0.0_wp; gp = 0.0_wp; hp = 0.0_wp $:GPU_LOOP(parallelism='[seq]') do i = 1, num_fluids + gp = gp + (gs_min(i) - 1.0_wp)*q_cons_vf(i + contxb - 1)%sf(j, k, l)*cvs(i)*(rhoe + pS - mQ)/(mCP*(pS + p_infpT(i))) - gp = gp + (gs_min(i) - 1.0_wp)*q_cons_vf(i + contxb - 1)%sf(j, k, l)*cvs(i) & - *(rhoe + pS - mQ)/(mCP*(pS + p_infpT(i))) - - gpp = gpp + (gs_min(i) - 1.0_wp)*q_cons_vf(i + contxb - 1)%sf(j, k, l)*cvs(i) & - *(p_infpT(i) - rhoe + mQ)/(mCP*(pS + p_infpT(i))**2) - + gpp = gpp + (gs_min(i) - 1.0_wp)*q_cons_vf(i + contxb - 1)%sf(j, k, & + & l)*cvs(i)*(p_infpT(i) - rhoe + mQ)/(mCP*(pS + p_infpT(i))**2) end do hp = 1.0_wp/(rhoe + pS - mQ) + 1.0_wp/(pS + minval(p_infpT)) ! updating common pressure for the newton solver - pS = pO + ((1.0_wp - gp)/gpp)/(1.0_wp - (1.0_wp - gp + abs(1.0_wp - gp)) & - /(2.0_wp*gpp)*hp) + pS = pO + ((1.0_wp - gp)/gpp)/(1.0_wp - (1.0_wp - gp + abs(1.0_wp - gp))/(2.0_wp*gpp)*hp) end do ! common temperature @@ -409,42 +360,40 @@ contains end subroutine s_infinite_pt_relaxation_k - !> This auxiliary subroutine is created to activate the pTg-equilibrium for N fluids under pT - !! and 2 fluids under pTg-equilibrium. There is a final common p and T during relaxation - !! @param j generic loop iterator for x direction - !! @param k generic loop iterator for y direction - !! @param l generic loop iterator for z direction - !! @param pS equilibrium pressure at the interface - !! @param p_infpT stiffness for the participating fluids under pT-equilibrium - !! @param rhoe mixture energy - !! @param q_cons_vf Cell-average conservative variables - !! @param TS equilibrium temperature at the interface + !> This auxiliary subroutine is created to activate the pTg-equilibrium for N fluids under pT and 2 fluids under + !! pTg-equilibrium. There is a final common p and T during relaxation + !! @param j generic loop iterator for x direction + !! @param k generic loop iterator for y direction + !! @param l generic loop iterator for z direction + !! @param pS equilibrium pressure at the interface + !! @param p_infpT stiffness for the participating fluids under pT-equilibrium + !! @param rhoe mixture energy + !! @param q_cons_vf Cell-average conservative variables + !! @param TS equilibrium temperature at the interface subroutine s_infinite_ptg_relaxation_k(j, k, l, pS, p_infpT, rhoe, q_cons_vf, TS) - $:GPU_ROUTINE(function_name='s_infinite_ptg_relaxation_k', & - & parallelism='[seq]', cray_noinline=True) - integer, intent(in) :: j, k, l - real(wp), intent(inout) :: pS - real(wp), dimension(1:), intent(in) :: p_infpT - real(wp), intent(in) :: rhoe + $:GPU_ROUTINE(function_name='s_infinite_ptg_relaxation_k', parallelism='[seq]', cray_noinline=True) + + integer, intent(in) :: j, k, l + real(wp), intent(inout) :: pS + real(wp), dimension(1:), intent(in) :: p_infpT + real(wp), intent(in) :: rhoe type(scalar_field), dimension(sys_size), intent(inout) :: q_cons_vf - real(wp), intent(inout) :: TS + real(wp), intent(inout) :: TS #:if not MFC_CASE_OPTIMIZATION and USING_AMD - real(wp), dimension(3) :: p_infpTg !< stiffness for the participating fluids for pTg-equilibrium + real(wp), dimension(3) :: p_infpTg !< stiffness for the participating fluids for pTg-equilibrium #:else - real(wp), dimension(num_fluids) :: p_infpTg !< stiffness for the participating fluids for pTg-equilibrium + real(wp), dimension(num_fluids) :: p_infpTg !< stiffness for the participating fluids for pTg-equilibrium #:endif - real(wp), dimension(2, 2) :: Jac, InvJac, TJac !< matrices for the Newton Solver - real(wp), dimension(2) :: R2D, DeltamP !< residual and correction array - real(wp) :: Om ! underrelaxation factor - real(wp) :: mCP, mCPD, mCVGP, mCVGP2, mQ, mQD ! auxiliary variables for the pTg-solver - real(wp) :: ml, mT, dFdT, dTdm, dTdp + real(wp), dimension(2, 2) :: Jac, InvJac, TJac !< matrices for the Newton Solver + real(wp), dimension(2) :: R2D, DeltamP !< residual and correction array + real(wp) :: Om ! underrelaxation factor + real(wp) :: mCP, mCPD, mCVGP, mCVGP2, mQ, mQD ! auxiliary variables for the pTg-solver + real(wp) :: ml, mT, dFdT, dTdm, dTdp - !< Generic loop iterators + !> Generic loop iterators integer :: i, ns - ! pTg-equilibrium solution procedure - ! Newton Solver parameters - ! counter + ! pTg-equilibrium solution procedure Newton Solver parameters counter ns = 0 ! Relaxation factor @@ -452,62 +401,45 @@ contains p_infpTg = p_infpT - if (((pS < 0.0_wp) .and. ((q_cons_vf(lp + contxb - 1)%sf(j, k, l) & - + q_cons_vf(vp + contxb - 1)%sf(j, k, l)) > ((rhoe & - - gs_min(lp)*ps_inf(lp)/(gs_min(lp) - 1))/qvs(lp)))) .or. & - ((pS >= 0.0_wp) .and. (pS < 1.0e-1_wp))) then - + if (((pS < 0.0_wp) .and. ((q_cons_vf(lp + contxb - 1)%sf(j, k, l) + q_cons_vf(vp + contxb - 1)%sf(j, k, & + & l)) > ((rhoe - gs_min(lp)*ps_inf(lp)/(gs_min(lp) - 1))/qvs(lp)))) .or. ((pS >= 0.0_wp) .and. (pS < 1.0e-1_wp))) then ! improve this initial condition pS = 1.0e4_wp - end if - ! Loop until the solution for F(X) is satisfied - ! Check whether I need to use both absolute and relative values - ! for the residual, and how to do it adequately. - ! Dummy guess to start the pTg-equilibrium problem. - ! improve this initial condition + ! Loop until the solution for F(X) is satisfied Check whether I need to use both absolute and relative values for the + ! residual, and how to do it adequately. Dummy guess to start the pTg-equilibrium problem. improve this initial condition R2D(1) = 0.0_wp; R2D(2) = 0.0_wp DeltamP(1) = 0.0_wp; DeltamP(2) = 0.0_wp - do while (((sqrt(R2D(1)**2 + R2D(2)**2) > ptgalpha_eps) & - .and. ((sqrt(R2D(1)**2 + R2D(2)**2)/rhoe) > (ptgalpha_eps/1.e6_wp))) & - .or. (ns == 0)) + do while (((sqrt(R2D(1)**2 + R2D(2)**2) > ptgalpha_eps) .and. ((sqrt(R2D(1)**2 + R2D(2)**2)/rhoe) > (ptgalpha_eps/1.e6_wp) & + & )) .or. (ns == 0)) ! Updating counter for the iterative procedure ns = ns + 1 ! Auxiliary variables to help in the calculation of the residue mCP = 0.0_wp; mCPD = 0.0_wp; mCVGP = 0.0_wp; mCVGP2 = 0.0_wp; mQ = 0.0_wp; mQD = 0.0_wp - ! Those must be updated through the iterations, as they either depend on - ! the partial masses for all fluids, or on the equilibrium pressure + ! Those must be updated through the iterations, as they either depend on the partial masses for all fluids, or on the + ! equilibrium pressure $:GPU_LOOP(parallelism='[seq]') do i = 1, num_fluids - ! sum of the total alpha*rho*cp of the system - mCP = mCP + q_cons_vf(i + contxb - 1)%sf(j, k, l) & - *cvs(i)*gs_min(i) + mCP = mCP + q_cons_vf(i + contxb - 1)%sf(j, k, l)*cvs(i)*gs_min(i) ! sum of the total alpha*rho*q of the system mQ = mQ + q_cons_vf(i + contxb - 1)%sf(j, k, l)*qvs(i) - ! These auxiliary variables now need to be updated, as the partial densities now - ! vary at every iteration + ! These auxiliary variables now need to be updated, as the partial densities now vary at every iteration if ((i /= lp) .and. (i /= vp)) then + mCVGP = mCVGP + q_cons_vf(i + contxb - 1)%sf(j, k, l)*cvs(i)*(gs_min(i) - 1)/(pS + ps_inf(i)) - mCVGP = mCVGP + q_cons_vf(i + contxb - 1)%sf(j, k, l) & - *cvs(i)*(gs_min(i) - 1)/(pS + ps_inf(i)) - - mCVGP2 = mCVGP2 + q_cons_vf(i + contxb - 1)%sf(j, k, l) & - *cvs(i)*(gs_min(i) - 1)/((pS + ps_inf(i))**2) + mCVGP2 = mCVGP2 + q_cons_vf(i + contxb - 1)%sf(j, k, l)*cvs(i)*(gs_min(i) - 1)/((pS + ps_inf(i))**2) mQD = mQD + q_cons_vf(i + contxb - 1)%sf(j, k, l)*qvs(i) ! sum of the total alpha*rho*cp of the system - mCPD = mCPD + q_cons_vf(i + contxb - 1)%sf(j, k, l)*cvs(i) & - *gs_min(i) - + mCPD = mCPD + q_cons_vf(i + contxb - 1)%sf(j, k, l)*cvs(i)*gs_min(i) end if - end do ! calculating the (2D) Jacobian Matrix used in the solution of the pTg-quilibrium model @@ -516,62 +448,41 @@ contains ml = q_cons_vf(lp + contxb - 1)%sf(j, k, l) ! mass of the two participating fluids - mT = q_cons_vf(lp + contxb - 1)%sf(j, k, l) & - + q_cons_vf(vp + contxb - 1)%sf(j, k, l) - - TS = 1/(mT*cvs(vp)*(gs_min(vp) - 1)/(pS + ps_inf(vp)) & - + ml*(cvs(lp)*(gs_min(lp) - 1)/(pS + ps_inf(lp)) & - - cvs(vp)*(gs_min(vp) - 1)/(pS + ps_inf(vp))) & - + mCVGP) - - dFdT = & - -(cvs(lp)*gs_min(lp) - cvs(vp)*gs_min(vp))*log(TS) & - - (qvps(lp) - qvps(vp)) & - + cvs(lp)*(gs_min(lp) - 1)*log(pS + ps_inf(lp)) & - - cvs(vp)*(gs_min(vp) - 1)*log(pS + ps_inf(vp)) - - dTdm = -(cvs(lp)*(gs_min(lp) - 1)/(pS + ps_inf(lp)) & - - cvs(vp)*(gs_min(vp) - 1)/(pS + ps_inf(vp)))*TS**2 - - dTdp = (mT*cvs(vp)*(gs_min(vp) - 1)/(pS + ps_inf(vp))**2 & - + ml*(cvs(lp)*(gs_min(lp) - 1)/(pS + ps_inf(lp))**2 & - - cvs(vp)*(gs_min(vp) - 1)/(pS + ps_inf(vp))**2) & - + mCVGP2)*TS**2 - - ! F = (F1,F2) is the function whose roots we are looking for - ! x = (m1, p) are the independent variables. m1 = mass of the first participant fluid, p = pressure - ! F1 = 0 is the Gibbs free energy quality - ! F2 = 0 is the enforcement of the thermodynamic (total - kinectic) energy - ! dF1dm + mT = q_cons_vf(lp + contxb - 1)%sf(j, k, l) + q_cons_vf(vp + contxb - 1)%sf(j, k, l) + + TS = 1/(mT*cvs(vp)*(gs_min(vp) - 1)/(pS + ps_inf(vp)) + ml*(cvs(lp)*(gs_min(lp) - 1)/(pS + ps_inf(lp)) - cvs(vp) & + & *(gs_min(vp) - 1)/(pS + ps_inf(vp))) + mCVGP) + + dFdT = -(cvs(lp)*gs_min(lp) - cvs(vp)*gs_min(vp))*log(TS) - (qvps(lp) - qvps(vp)) + cvs(lp)*(gs_min(lp) - 1)*log(pS & + & + ps_inf(lp)) - cvs(vp)*(gs_min(vp) - 1)*log(pS + ps_inf(vp)) + + dTdm = -(cvs(lp)*(gs_min(lp) - 1)/(pS + ps_inf(lp)) - cvs(vp)*(gs_min(vp) - 1)/(pS + ps_inf(vp)))*TS**2 + + dTdp = (mT*cvs(vp)*(gs_min(vp) - 1)/(pS + ps_inf(vp))**2 + ml*(cvs(lp)*(gs_min(lp) - 1)/(pS + ps_inf(lp))**2 - cvs(vp) & + & *(gs_min(vp) - 1)/(pS + ps_inf(vp))**2) + mCVGP2)*TS**2 + + ! F = (F1,F2) is the function whose roots we are looking for x = (m1, p) are the independent variables. m1 = mass of the + ! first participant fluid, p = pressure F1 = 0 is the Gibbs free energy quality F2 = 0 is the enforcement of the + ! thermodynamic (total - kinectic) energy dF1dm Jac(1, 1) = dFdT*dTdm ! dF1dp - Jac(1, 2) = dFdT*dTdp + TS & - *(cvs(lp)*(gs_min(lp) - 1)/(pS + ps_inf(lp)) & - - cvs(vp)*(gs_min(vp) - 1)/(pS + ps_inf(vp))) + Jac(1, 2) = dFdT*dTdp + TS*(cvs(lp)*(gs_min(lp) - 1)/(pS + ps_inf(lp)) - cvs(vp)*(gs_min(vp) - 1)/(pS + ps_inf(vp))) ! dF2dm - Jac(2, 1) = (qvs(vp) - qvs(lp) & - + (cvs(vp)*gs_min(vp) - cvs(lp)*gs_min(lp)) & - /(ml*(cvs(lp)*(gs_min(lp) - 1)/(pS + ps_inf(lp)) & - - cvs(vp)*(gs_min(vp) - 1)/(pS + ps_inf(vp))) & - + mT*cvs(vp)*(gs_min(vp) - 1)/(pS + ps_inf(vp)) + mCVGP) & - - (ml*(cvs(vp)*gs_min(vp) - cvs(lp)*gs_min(lp)) & - - mT*cvs(vp)*gs_min(vp) - mCPD) & - *(cvs(lp)*(gs_min(lp) - 1)/(pS + ps_inf(lp)) & - - cvs(vp)*(gs_min(vp) - 1)/(pS + ps_inf(vp))) & - /((ml*(cvs(lp)*(gs_min(lp) - 1)/(pS + ps_inf(lp)) & - - cvs(vp)*(gs_min(vp) - 1)/(pS + ps_inf(vp))) & - + mT*cvs(vp)*(gs_min(vp) - 1)/(pS + ps_inf(vp)) + mCVGP)**2))/1 + Jac(2, & + & 1) = (qvs(vp) - qvs(lp) + (cvs(vp)*gs_min(vp) - cvs(lp)*gs_min(lp))/(ml*(cvs(lp)*(gs_min(lp) - 1)/(pS & + & + ps_inf(lp)) - cvs(vp)*(gs_min(vp) - 1)/(pS + ps_inf(vp))) + mT*cvs(vp)*(gs_min(vp) - 1)/(pS + ps_inf(vp)) & + & + mCVGP) - (ml*(cvs(vp)*gs_min(vp) - cvs(lp)*gs_min(lp)) - mT*cvs(vp)*gs_min(vp) - mCPD)*(cvs(lp)*(gs_min(lp) & + & - 1)/(pS + ps_inf(lp)) - cvs(vp)*(gs_min(vp) - 1)/(pS + ps_inf(vp)))/((ml*(cvs(lp)*(gs_min(lp) - 1)/(pS & + & + ps_inf(lp)) - cvs(vp)*(gs_min(vp) - 1)/(pS + ps_inf(vp))) + mT*cvs(vp)*(gs_min(vp) - 1)/(pS + ps_inf(vp)) & + & + mCVGP)**2))/1 ! dF2dp - Jac(2, 2) = (1 + (ml*(cvs(vp)*gs_min(vp) - cvs(lp)*gs_min(lp)) & - - mT*cvs(vp)*gs_min(vp) - mCPD) & - *(ml*(cvs(lp)*(gs_min(lp) - 1)/(pS + ps_inf(lp))**2 & - - cvs(vp)*(gs_min(vp) - 1)/(pS + ps_inf(vp))**2) & - + mT*cvs(vp)*(gs_min(vp) - 1)/(pS + ps_inf(vp))**2 + mCVGP2) & - /(ml*(cvs(lp)*(gs_min(lp) - 1)/(pS + ps_inf(lp)) & - - cvs(vp)*(gs_min(vp) - 1)/(pS + ps_inf(vp))) & - + mT*cvs(vp)*(gs_min(vp) - 1)/(pS + ps_inf(vp)) + mCVGP)**2)/1 + Jac(2, & + & 2) = (1 + (ml*(cvs(vp)*gs_min(vp) - cvs(lp)*gs_min(lp)) - mT*cvs(vp)*gs_min(vp) - mCPD)*(ml*(cvs(lp)*(gs_min(lp) & + & - 1)/(pS + ps_inf(lp))**2 - cvs(vp)*(gs_min(vp) - 1)/(pS + ps_inf(vp))**2) + mT*cvs(vp)*(gs_min(vp) - 1)/(pS & + & + ps_inf(vp))**2 + mCVGP2)/(ml*(cvs(lp)*(gs_min(lp) - 1)/(pS + ps_inf(lp)) - cvs(vp)*(gs_min(vp) - 1)/(pS & + & + ps_inf(vp))) + mT*cvs(vp)*(gs_min(vp) - 1)/(pS + ps_inf(vp)) + mCVGP)**2)/1 ! intermediate elements of J^{-1} InvJac(1, 1) = Jac(2, 2) @@ -592,8 +503,7 @@ contains DeltamP(1) = -1.0_wp*(InvJac(1, 1)*R2D(1) + InvJac(1, 2)*R2D(2)) DeltamP(2) = -1.0_wp*(InvJac(2, 1)*R2D(1) + InvJac(2, 2)*R2D(2)) - ! updating two reacting 'masses'. Recall that inert 'masses' do not change during the phase change - ! liquid + ! updating two reacting 'masses'. Recall that inert 'masses' do not change during the phase change liquid q_cons_vf(lp + contxb - 1)%sf(j, k, l) = q_cons_vf(lp + contxb - 1)%sf(j, k, l) + Om*DeltamP(1) ! gas @@ -602,124 +512,102 @@ contains ! updating pressure pS = pS + Om*DeltamP(2) - ! calculating residuals, which are (i) the difference between the Gibbs Free energy of the gas and the liquid - ! and (ii) the energy before and after the phase-change process. + ! calculating residuals, which are (i) the difference between the Gibbs Free energy of the gas and the liquid and (ii) + ! the energy before and after the phase-change process. ! mass of the reacting liquid ml = q_cons_vf(lp + contxb - 1)%sf(j, k, l) ! mass of the two participating fluids - mT = q_cons_vf(lp + contxb - 1)%sf(j, k, l) & - + q_cons_vf(vp + contxb - 1)%sf(j, k, l) + mT = q_cons_vf(lp + contxb - 1)%sf(j, k, l) + q_cons_vf(vp + contxb - 1)%sf(j, k, l) - TS = 1/(mT*cvs(vp)*(gs_min(vp) - 1)/(pS + ps_inf(vp)) & - + ml*(cvs(lp)*(gs_min(lp) - 1)/(pS + ps_inf(lp)) & - - cvs(vp)*(gs_min(vp) - 1)/(pS + ps_inf(vp))) & - + mCVGP) + TS = 1/(mT*cvs(vp)*(gs_min(vp) - 1)/(pS + ps_inf(vp)) + ml*(cvs(lp)*(gs_min(lp) - 1)/(pS + ps_inf(lp)) - cvs(vp) & + & *(gs_min(vp) - 1)/(pS + ps_inf(vp))) + mCVGP) ! Gibbs Free Energy Equality condition (DG) - R2D(1) = TS*((cvs(lp)*gs_min(lp) - cvs(vp)*gs_min(vp)) & - *(1 - log(TS)) - (qvps(lp) - qvps(vp)) & - + cvs(lp)*(gs_min(lp) - 1)*log(pS + ps_inf(lp)) & - - cvs(vp)*(gs_min(vp) - 1)*log(pS + ps_inf(vp))) & - + qvs(lp) - qvs(vp) + R2D(1) = TS*((cvs(lp)*gs_min(lp) - cvs(vp)*gs_min(vp))*(1 - log(TS)) - (qvps(lp) - qvps(vp)) + cvs(lp)*(gs_min(lp) & + & - 1)*log(pS + ps_inf(lp)) - cvs(vp)*(gs_min(vp) - 1)*log(pS + ps_inf(vp))) + qvs(lp) - qvs(vp) ! Constant Energy Process condition (DE) - R2D(2) = (rhoe + pS & - + ml*(qvs(vp) - qvs(lp)) - mT*qvs(vp) - mQD & - + (ml*(gs_min(vp)*cvs(vp) - gs_min(lp)*cvs(lp)) & - - mT*gs_min(vp)*cvs(vp) - mCPD) & - /(ml*(cvs(lp)*(gs_min(lp) - 1)/(pS + ps_inf(lp)) & - - cvs(vp)*(gs_min(vp) - 1)/(pS + ps_inf(vp))) & - + mT*cvs(vp)*(gs_min(vp) - 1)/(pS + ps_inf(vp)) + mCVGP))/1 - + R2D(2) = (rhoe + pS + ml*(qvs(vp) - qvs(lp)) - mT*qvs(vp) - mQD + (ml*(gs_min(vp)*cvs(vp) - gs_min(lp)*cvs(lp)) & + & - mT*gs_min(vp)*cvs(vp) - mCPD)/(ml*(cvs(lp)*(gs_min(lp) - 1)/(pS + ps_inf(lp)) - cvs(vp)*(gs_min(vp) - 1)/(pS & + & + ps_inf(vp))) + mT*cvs(vp)*(gs_min(vp) - 1)/(pS + ps_inf(vp)) + mCVGP))/1 end do ! common temperature TS = (rhoe + pS - mQ)/mCP + end subroutine s_infinite_ptg_relaxation_k - !> This auxiliary subroutine corrects the partial densities of the REACTING fluids in case one of them is negative - !! but their sum is positive. Inert phases are not corrected at this moment - !! @param MCT partial density correction parameter - !! @param q_cons_vf Cell-average conservative variables - !! @param rM sum of the reacting masses - !! @param j generic loop iterator for x direction - !! @param k generic loop iterator for y direction - !! @param l generic loop iterator for z direction + !> This auxiliary subroutine corrects the partial densities of the REACTING fluids in case one of them is negative but their sum + !! is positive. Inert phases are not corrected at this moment + !! @param MCT partial density correction parameter + !! @param q_cons_vf Cell-average conservative variables + !! @param rM sum of the reacting masses + !! @param j generic loop iterator for x direction + !! @param k generic loop iterator for y direction + !! @param l generic loop iterator for z direction subroutine s_correct_partial_densities(MCT, q_cons_vf, rM, j, k, l) - $:GPU_ROUTINE(function_name='s_correct_partial_densities', & - & parallelism='[seq]', cray_noinline=True) + + $:GPU_ROUTINE(function_name='s_correct_partial_densities', parallelism='[seq]', cray_noinline=True) !> @name variables for the correction of the reacting partial densities !> @{ - real(wp), intent(out) :: MCT + real(wp), intent(out) :: MCT type(scalar_field), dimension(sys_size), intent(inout) :: q_cons_vf - real(wp), intent(inout) :: rM - integer, intent(in) :: j, k, l + real(wp), intent(inout) :: rM + integer, intent(in) :: j, k, l !> @} if (rM < 0.0_wp) then - - if ((q_cons_vf(lp + contxb - 1)%sf(j, k, l) >= -1.0_wp*mixM) .and. & - (q_cons_vf(vp + contxb - 1)%sf(j, k, l) >= -1.0_wp*mixM)) then - + if ((q_cons_vf(lp + contxb - 1)%sf(j, k, l) >= -1.0_wp*mixM) .and. (q_cons_vf(vp + contxb - 1)%sf(j, k, & + & l) >= -1.0_wp*mixM)) then q_cons_vf(lp + contxb - 1)%sf(j, k, l) = 0.0_wp q_cons_vf(vp + contxb - 1)%sf(j, k, l) = 0.0_wp rM = q_cons_vf(lp + contxb - 1)%sf(j, k, l) + q_cons_vf(vp + contxb - 1)%sf(j, k, l) - end if - end if - ! Defining the correction in terms of an absolute value might not be the best practice. - ! Maybe a good way to do this is to partition the partial densities, giving a small percentage of the total reacting density + ! Defining the correction in terms of an absolute value might not be the best practice. Maybe a good way to do this is to + ! partition the partial densities, giving a small percentage of the total reacting density MCT = 2*mixM ! correcting the partial densities of the reacting fluids. What to do for the nonreacting ones? if (q_cons_vf(lp + contxb - 1)%sf(j, k, l) < 0.0_wp) then - q_cons_vf(lp + contxb - 1)%sf(j, k, l) = MCT*rM q_cons_vf(vp + contxb - 1)%sf(j, k, l) = (1.0_wp - MCT)*rM - - elseif (q_cons_vf(vp + contxb - 1)%sf(j, k, l) < 0.0_wp) then - + else if (q_cons_vf(vp + contxb - 1)%sf(j, k, l) < 0.0_wp) then q_cons_vf(lp + contxb - 1)%sf(j, k, l) = (1.0_wp - MCT)*rM q_cons_vf(vp + contxb - 1)%sf(j, k, l) = MCT*rM - end if + end subroutine s_correct_partial_densities - !> This auxiliary subroutine finds the Saturation temperature for a given - !! saturation pressure through a newton solver - !! @param pSat Saturation Pressure - !! @param TSat Saturation Temperature - !! @param TSIn equilibrium Temperature + !> This auxiliary subroutine finds the Saturation temperature for a given saturation pressure through a newton solver + !! @param pSat Saturation Pressure + !! @param TSat Saturation Temperature + !! @param TSIn equilibrium Temperature elemental subroutine s_TSat(pSat, TSat, TSIn) - $:GPU_ROUTINE(function_name='s_TSat',parallelism='[seq]', & - & cray_noinline=True) - real(wp), intent(in) :: pSat - real(wp), intent(out) :: TSat - real(wp), intent(in) :: TSIn + $:GPU_ROUTINE(function_name='s_TSat',parallelism='[seq]', cray_noinline=True) - real(wp) :: dFdT, FT, Om !< auxiliary variables + real(wp), intent(in) :: pSat + real(wp), intent(out) :: TSat + real(wp), intent(in) :: TSIn + real(wp) :: dFdT, FT, Om !< auxiliary variables ! Generic loop iterators integer :: ns if ((f_approx_equal(pSat, 0.0_wp)) .and. (f_approx_equal(TSIn, 0.0_wp))) then - ! assigning Saturation temperature TSat = 0.0_wp - else - - ! calculating initial estimate for temperature in the TSat procedure. I will also use this variable to - ! iterate over the Newton's solver + ! calculating initial estimate for temperature in the TSat procedure. I will also use this variable to iterate over the + ! Newton's solver TSat = TSIn ! iteration counter @@ -728,9 +616,8 @@ contains ! underrelaxation factor Om = 1.0e-3_wp - ! FT must be initialized before the do while condition is evaluated. - ! Fortran .or. is not short-circuit: abs(FT) is always evaluated even - ! when ns == 0, so FT must have a defined value here. + ! FT must be initialized before the do while condition is evaluated. Fortran .or. is not short-circuit: abs(FT) is + ! always evaluated even when ns == 0, so FT must have a defined value here. FT = huge(1.0_wp) do while ((abs(FT) > ptgalpha_eps) .or. (ns == 0)) @@ -738,33 +625,25 @@ contains ns = ns + 1 ! calculating residual - FT = TSat*((cvs(lp)*gs_min(lp) - cvs(vp)*gs_min(vp)) & - *(1 - log(TSat)) - (qvps(lp) - qvps(vp)) & - + cvs(lp)*(gs_min(lp) - 1)*log(pSat + ps_inf(lp)) & - - cvs(vp)*(gs_min(vp) - 1)*log(pSat + ps_inf(vp))) & - + qvs(lp) - qvs(vp) + FT = TSat*((cvs(lp)*gs_min(lp) - cvs(vp)*gs_min(vp))*(1 - log(TSat)) - (qvps(lp) - qvps(vp)) + cvs(lp)*(gs_min(lp) & + & - 1)*log(pSat + ps_inf(lp)) - cvs(vp)*(gs_min(vp) - 1)*log(pSat + ps_inf(vp))) + qvs(lp) - qvs(vp) ! calculating the jacobian - dFdT = & - -(cvs(lp)*gs_min(lp) - cvs(vp)*gs_min(vp))*log(TSat) & - - (qvps(lp) - qvps(vp)) & - + cvs(lp)*(gs_min(lp) - 1)*log(pSat + ps_inf(lp)) & - - cvs(vp)*(gs_min(vp) - 1)*log(pSat + ps_inf(vp)) + dFdT = -(cvs(lp)*gs_min(lp) - cvs(vp)*gs_min(vp))*log(TSat) - (qvps(lp) - qvps(vp)) + cvs(lp)*(gs_min(lp) - 1) & + & *log(pSat + ps_inf(lp)) - cvs(vp)*(gs_min(vp) - 1)*log(pSat + ps_inf(vp)) ! updating saturation temperature TSat = TSat - Om*FT/dFdT if (abs(FT) <= ptgalpha_eps) exit end do - end if end subroutine s_TSat - !> This subroutine finalizes the phase change module + !> This subroutine finalizes the phase change module impure subroutine s_finalize_relaxation_solver_module - end subroutine s_finalize_relaxation_solver_module + end subroutine s_finalize_relaxation_solver_module #endif - end module m_phase_change diff --git a/src/common/m_precision_select.f90 b/src/common/m_precision_select.f90 index 9874ccd87f..5fc1c5c667 100644 --- a/src/common/m_precision_select.f90 +++ b/src/common/m_precision_select.f90 @@ -7,16 +7,15 @@ module m_precision_select ! use, intrinsic :: iso_c_binding #ifdef MFC_MPI - use mpi !< Message passing interface (MPI) module + use mpi !< Message passing interface (MPI) module #endif implicit none ! Define the available precision types - integer, parameter :: half_precision = 2 ! selected_real_kind(3, 4) + integer, parameter :: half_precision = 2 ! selected_real_kind(3, 4) integer, parameter :: single_precision = selected_real_kind(6, 37) integer, parameter :: double_precision = selected_real_kind(15, 307) - integer, parameter :: hp = half_precision integer, parameter :: sp = single_precision integer, parameter :: dp = double_precision @@ -48,5 +47,4 @@ module m_precision_select integer, parameter :: mpi_io_p = -100 integer, parameter :: mpi_io_type = -100 #endif - end module m_precision_select diff --git a/src/common/m_variables_conversion.fpp b/src/common/m_variables_conversion.fpp index 632c8df1b0..e19919c27e 100644 --- a/src/common/m_variables_conversion.fpp +++ b/src/common/m_variables_conversion.fpp @@ -8,23 +8,17 @@ !> @brief Conservative-to-primitive variable conversion, mixture property evaluation, and pressure computation module m_variables_conversion - use m_derived_types !< Definitions of the derived types - - use m_global_parameters !< Definitions of the global parameters - - use m_mpi_proxy !< Message passing interface (MPI) module proxy - - use m_helper_basic !< Functions to compare floating point numbers - + use m_derived_types !< Definitions of the derived types + use m_global_parameters !< Definitions of the global parameters + use m_mpi_proxy !< Message passing interface (MPI) module proxy + use m_helper_basic !< Functions to compare floating point numbers use m_helper - - use m_thermochem, only: & - num_species, get_temperature, get_pressure, gas_constant, & - get_mixture_molecular_weight, get_mixture_energy_mass + use m_thermochem, only: num_species, get_temperature, get_pressure, gas_constant, get_mixture_molecular_weight, & + & get_mixture_energy_mass implicit none - private; + private public :: s_initialize_variables_conversion_module, & s_initialize_pb, & s_initialize_mv, & @@ -38,118 +32,109 @@ module m_variables_conversion s_compute_pressure, & s_compute_species_fraction, & #ifndef MFC_PRE_PROCESS - s_compute_speed_of_sound, & + s_compute_speed_of_sound, & s_compute_fast_magnetosonic_speed, & #endif - s_finalize_variables_conversion_module + s_finalize_variables_conversion_module !! In simulation, gammas, pi_infs, and qvs are already declared in m_global_variables #ifndef MFC_SIMULATION real(wp), allocatable, public, dimension(:) :: gammas, gs_min, pi_infs, ps_inf, cvs, qvs, qvps - $:GPU_DECLARE(create='[gammas,gs_min,pi_infs,ps_inf,cvs,qvs,qvps]') + $:GPU_DECLARE(create='[gammas, gs_min, pi_infs, ps_inf, cvs, qvs, qvps]') #endif - real(wp), allocatable, dimension(:) :: Gs_vc - integer, allocatable, dimension(:) :: bubrs_vc - real(wp), allocatable, dimension(:, :) :: Res_vc - $:GPU_DECLARE(create='[bubrs_vc,Gs_vc,Res_vc]') + real(wp), allocatable, dimension(:) :: Gs_vc + integer, allocatable, dimension(:) :: bubrs_vc + real(wp), allocatable, dimension(:,:) :: Res_vc + $:GPU_DECLARE(create='[bubrs_vc, Gs_vc, Res_vc]') integer :: is1b, is2b, is3b, is1e, is2e, is3e - $:GPU_DECLARE(create='[is1b,is2b,is3b,is1e,is2e,is3e]') + $:GPU_DECLARE(create='[is1b, is2b, is3b, is1e, is2e, is3e]') - real(wp), allocatable, dimension(:, :, :), public :: rho_sf !< Scalar density function - real(wp), allocatable, dimension(:, :, :), public :: gamma_sf !< Scalar sp. heat ratio function - real(wp), allocatable, dimension(:, :, :), public :: pi_inf_sf !< Scalar liquid stiffness function - real(wp), allocatable, dimension(:, :, :), public :: qv_sf !< Scalar liquid energy reference function + real(wp), allocatable, dimension(:,:,:), public :: rho_sf !< Scalar density function + real(wp), allocatable, dimension(:,:,:), public :: gamma_sf !< Scalar sp. heat ratio function + real(wp), allocatable, dimension(:,:,:), public :: pi_inf_sf !< Scalar liquid stiffness function + real(wp), allocatable, dimension(:,:,:), public :: qv_sf !< Scalar liquid energy reference function contains - !> Dispatch to the s_convert_mixture_to_mixture_variables - !! and s_convert_species_to_mixture_variables subroutines. - !! Replaces a procedure pointer. - !! @param q_vf Conservative or primitive variables - !! @param i First-coordinate cell index - !! @param j Second-coordinate cell index - !! @param k Third-coordinate cell index - !! @param rho Density - !! @param gamma Specific heat ratio function - !! @param pi_inf Liquid stiffness function - !! @param qv Fluid reference energy - !! @param Re_K Reynolds number (optional) - !! @param G_K Shear modulus (optional) - !! @param G Shear moduli of the fluids (optional) - subroutine s_convert_to_mixture_variables(q_vf, i, j, k, & - rho, gamma, pi_inf, qv, Re_K, G_K, G) - - type(scalar_field), dimension(sys_size), intent(in) :: q_vf - integer, intent(in) :: i, j, k - real(wp), intent(out), target :: rho, gamma, pi_inf, qv - real(wp), optional, dimension(2), intent(out) :: Re_K - real(wp), optional, intent(out) :: G_K + !> Dispatch to the s_convert_mixture_to_mixture_variables and s_convert_species_to_mixture_variables subroutines. Replaces a + !! procedure pointer. + !! @param q_vf Conservative or primitive variables + !! @param i First-coordinate cell index + !! @param j Second-coordinate cell index + !! @param k Third-coordinate cell index + !! @param rho Density + !! @param gamma Specific heat ratio function + !! @param pi_inf Liquid stiffness function + !! @param qv Fluid reference energy + !! @param Re_K Reynolds number (optional) + !! @param G_K Shear modulus (optional) + !! @param G Shear moduli of the fluids (optional) + subroutine s_convert_to_mixture_variables(q_vf, i, j, k, rho, gamma, pi_inf, qv, Re_K, G_K, G) + + type(scalar_field), dimension(sys_size), intent(in) :: q_vf + integer, intent(in) :: i, j, k + real(wp), intent(out), target :: rho, gamma, pi_inf, qv + real(wp), optional, dimension(2), intent(out) :: Re_K + real(wp), optional, intent(out) :: G_K real(wp), optional, dimension(num_fluids), intent(in) :: G - if (model_eqns == 1) then ! Gamma/pi_inf model - call s_convert_mixture_to_mixture_variables(q_vf, i, j, k, & - rho, gamma, pi_inf, qv) - + if (model_eqns == 1) then ! Gamma/pi_inf model + call s_convert_mixture_to_mixture_variables(q_vf, i, j, k, rho, gamma, pi_inf, qv) else ! Volume fraction model - call s_convert_species_to_mixture_variables(q_vf, i, j, k, & - rho, gamma, pi_inf, qv, Re_K, G_K, G) + call s_convert_species_to_mixture_variables(q_vf, i, j, k, rho, gamma, pi_inf, qv, Re_K, G_K, G) end if end subroutine s_convert_to_mixture_variables - !> This procedure conditionally calculates the appropriate pressure - !! @param energy Energy - !! @param alf Void Fraction - !! @param dyn_p Dynamic Pressure - !! @param pi_inf Liquid Stiffness - !! @param gamma Specific Heat Ratio - !! @param rho Density - !! @param qv fluid reference energy - !! @param rhoYks Species partial densities - !! @param pres Pressure to calculate - !! @param T Temperature - !! @param stress Shear Stress - !! @param mom Momentum - !! @param G Shear modulus (optional) - !! @param pres_mag Magnetic pressure (optional) + !> This procedure conditionally calculates the appropriate pressure + !! @param energy Energy + !! @param alf Void Fraction + !! @param dyn_p Dynamic Pressure + !! @param pi_inf Liquid Stiffness + !! @param gamma Specific Heat Ratio + !! @param rho Density + !! @param qv fluid reference energy + !! @param rhoYks Species partial densities + !! @param pres Pressure to calculate + !! @param T Temperature + !! @param stress Shear Stress + !! @param mom Momentum + !! @param G Shear modulus (optional) + !! @param pres_mag Magnetic pressure (optional) subroutine s_compute_pressure(energy, alf, dyn_p, pi_inf, gamma, rho, qv, rhoYks, pres, T, stress, mom, G, pres_mag) - $:GPU_ROUTINE(function_name='s_compute_pressure',parallelism='[seq]', & - & cray_noinline=True) - - real(stp), intent(in) :: energy, alf - real(wp), intent(in) :: dyn_p - real(wp), intent(in) :: pi_inf, gamma, rho, qv - real(wp), intent(out) :: pres - real(wp), intent(inout) :: T + + $:GPU_ROUTINE(function_name='s_compute_pressure',parallelism='[seq]', cray_noinline=True) + + real(stp), intent(in) :: energy, alf + real(wp), intent(in) :: dyn_p + real(wp), intent(in) :: pi_inf, gamma, rho, qv + real(wp), intent(out) :: pres + real(wp), intent(inout) :: T real(stp), intent(in), optional :: stress, mom - real(wp), intent(in), optional :: G, pres_mag + real(wp), intent(in), optional :: G, pres_mag ! Chemistry real(wp), dimension(1:num_species), intent(in) :: rhoYks - real(wp), dimension(1:num_species) :: Y_rs - real(wp) :: E_e - real(wp) :: e_Per_Kg, Pdyn_Per_Kg - real(wp) :: T_guess - - integer :: s !< Generic loop iterator + real(wp), dimension(1:num_species) :: Y_rs + real(wp) :: E_e + real(wp) :: e_Per_Kg, Pdyn_Per_Kg + real(wp) :: T_guess + integer :: s !< Generic loop iterator #:if not chemistry - ! Depending on model_eqns and bubbles_euler, the appropriate procedure - ! for computing pressure is targeted by the procedure pointer + ! Depending on model_eqns and bubbles_euler, the appropriate procedure for computing pressure is targeted by the + ! procedure pointer if (mhd) then pres = (energy - dyn_p - pi_inf - qv - pres_mag)/gamma - elseif ((model_eqns /= 4) .and. (bubbles_euler .neqv. .true.)) then + else if ((model_eqns /= 4) .and. (bubbles_euler .neqv. .true.)) then pres = (energy - dyn_p - pi_inf - qv)/gamma else if ((model_eqns /= 4) .and. bubbles_euler) then pres = ((energy - dyn_p)/(1._wp - alf) - pi_inf - qv)/gamma else - pres = (pref + pi_inf)* & - (energy/ & - (rhoref*(1 - alf)) & - )**(1/gamma + 1) - pi_inf + pres = (pref + pi_inf)*(energy/(rhoref*(1 - alf)))**(1/gamma + 1) - pi_inf end if if (hypoelasticity .and. present(G)) then @@ -165,16 +150,9 @@ contains end if end do - pres = ( & - energy - & - 0.5_wp*(mom**2._wp)/rho - & - pi_inf - qv - E_e & - )/gamma - + pres = (energy - 0.5_wp*(mom**2._wp)/rho - pi_inf - qv - E_e)/gamma end if - #:else - Y_rs(:) = rhoYks(:)/rho e_Per_Kg = energy/rho Pdyn_Per_Kg = dyn_p/rho @@ -183,41 +161,35 @@ contains call get_temperature(e_Per_Kg - Pdyn_Per_Kg, T_guess, Y_rs, .true., T) call get_pressure(rho, T, Y_rs, pres) - #:endif end subroutine s_compute_pressure - !> This subroutine is designed for the gamma/pi_inf model - !! and provided a set of either conservative or primitive - !! variables, transfers the density, specific heat ratio - !! function and the liquid stiffness function from q_vf to - !! rho, gamma and pi_inf. - !! @param q_vf conservative or primitive variables - !! @param i cell index to transfer mixture variables - !! @param j cell index to transfer mixture variables - !! @param k cell index to transfer mixture variables - !! @param rho density - !! @param gamma specific heat ratio function - !! @param pi_inf liquid stiffness - !! @param qv fluid reference energy - subroutine s_convert_mixture_to_mixture_variables(q_vf, i, j, k, & - rho, gamma, pi_inf, qv) + !> This subroutine is designed for the gamma/pi_inf model and provided a set of either conservative or primitive variables, + !! transfers the density, specific heat ratio function and the liquid stiffness function from q_vf to rho, gamma and pi_inf. + !! @param q_vf conservative or primitive variables + !! @param i cell index to transfer mixture variables + !! @param j cell index to transfer mixture variables + !! @param k cell index to transfer mixture variables + !! @param rho density + !! @param gamma specific heat ratio function + !! @param pi_inf liquid stiffness + !! @param qv fluid reference energy + subroutine s_convert_mixture_to_mixture_variables(q_vf, i, j, k, rho, gamma, pi_inf, qv) type(scalar_field), dimension(sys_size), intent(in) :: q_vf - integer, intent(in) :: i, j, k + integer, intent(in) :: i, j, k + real(wp), intent(out), target :: rho + real(wp), intent(out), target :: gamma + real(wp), intent(out), target :: pi_inf + real(wp), intent(out), target :: qv - real(wp), intent(out), target :: rho - real(wp), intent(out), target :: gamma - real(wp), intent(out), target :: pi_inf - real(wp), intent(out), target :: qv + ! Transferring the density, the specific heat ratio function and the liquid stiffness function, respectively - ! Transferring the density, the specific heat ratio function and the - ! liquid stiffness function, respectively rho = q_vf(1)%sf(i, j, k) gamma = q_vf(gamma_idx)%sf(i, j, k) pi_inf = q_vf(pi_inf_idx)%sf(i, j, k) - qv = 0._wp ! keep this value nill for now. For future adjustment + qv = 0._wp ! keep this value nill for now. For future adjustment ! Post process requires rho_sf/gamma_sf/pi_inf_sf/qv_sf to also be updated #ifdef MFC_POST_PROCESS @@ -229,48 +201,40 @@ contains end subroutine s_convert_mixture_to_mixture_variables - !> This subroutine is designed for the volume fraction model - !! and provided a set of either conservative or primitive - !! variables, computes the density, the specific heat ratio - !! function and the liquid stiffness function from q_vf and - !! stores the results into rho, gamma and pi_inf. - !! @param q_vf primitive variables - !! @param k Cell index - !! @param l Cell index - !! @param r Cell index - !! @param rho density - !! @param gamma specific heat ratio - !! @param pi_inf liquid stiffness - !! @param qv fluid reference energy - !! @param Re_K Reynolds number (optional) - !! @param G_K Shear modulus (optional) - !! @param G Shear moduli of the fluids (optional) - subroutine s_convert_species_to_mixture_variables(q_vf, k, l, r, rho, & - gamma, pi_inf, qv, Re_K, G_K, G) - - type(scalar_field), dimension(sys_size), intent(in) :: q_vf - - integer, intent(in) :: k, l, r - - real(wp), intent(out), target :: rho - real(wp), intent(out), target :: gamma - real(wp), intent(out), target :: pi_inf - real(wp), intent(out), target :: qv - - real(wp), optional, dimension(2), intent(out) :: Re_K - real(wp), optional, intent(out) :: G_K - real(wp), dimension(num_fluids) :: alpha_rho_K, alpha_K !< + !> This subroutine is designed for the volume fraction model and provided a set of either conservative or primitive variables, + !! computes the density, the specific heat ratio function and the liquid stiffness function from q_vf and stores the results + !! into rho, gamma and pi_inf. + !! @param q_vf primitive variables + !! @param k Cell index + !! @param l Cell index + !! @param r Cell index + !! @param rho density + !! @param gamma specific heat ratio + !! @param pi_inf liquid stiffness + !! @param qv fluid reference energy + !! @param Re_K Reynolds number (optional) + !! @param G_K Shear modulus (optional) + !! @param G Shear moduli of the fluids (optional) + subroutine s_convert_species_to_mixture_variables(q_vf, k, l, r, rho, gamma, pi_inf, qv, Re_K, G_K, G) + + type(scalar_field), dimension(sys_size), intent(in) :: q_vf + integer, intent(in) :: k, l, r + real(wp), intent(out), target :: rho + real(wp), intent(out), target :: gamma + real(wp), intent(out), target :: pi_inf + real(wp), intent(out), target :: qv + real(wp), optional, dimension(2), intent(out) :: Re_K + real(wp), optional, intent(out) :: G_K + real(wp), dimension(num_fluids) :: alpha_rho_K, alpha_K real(wp), optional, dimension(num_fluids), intent(in) :: G + integer :: i, j !< Generic loop iterator - integer :: i, j !< Generic loop iterator + ! Computing the density, the specific heat ratio function and the liquid stiffness function, respectively - ! Computing the density, the specific heat ratio function and the - ! liquid stiffness function, respectively call s_compute_species_fraction(q_vf, k, l, r, alpha_rho_K, alpha_K) - ! Calculating the density, the specific heat ratio function, the - ! liquid stiffness function, and the energy reference function, - ! respectively, from the species analogs + ! Calculating the density, the specific heat ratio function, the liquid stiffness function, and the energy reference + ! function, respectively, from the species analogs if (num_fluids == 1 .and. bubbles_euler) then rho = alpha_rho_K(1) gamma = gammas(1) @@ -293,8 +257,7 @@ contains Re_K(i) = dflt_real; if (Re_size(i) > 0) Re_K(i) = 0._wp do j = 1, Re_size(i) - Re_K(i) = alpha_K(Re_idx(i, j))/fluid_pp(Re_idx(i, j))%Re(i) & - + Re_K(i) + Re_K(i) = alpha_K(Re_idx(i, j))/fluid_pp(Re_idx(i, j))%Re(i) + Re_K(i) end do Re_K(i) = 1._wp/max(Re_K(i), sgm_eps) @@ -320,33 +283,29 @@ contains end subroutine s_convert_species_to_mixture_variables - !> @brief GPU-accelerated conversion of species volume fractions and partial densities to mixture density, gamma, pi_inf, and qv. - subroutine s_convert_species_to_mixture_variables_acc(rho_K, & - gamma_K, pi_inf_K, qv_K, & - alpha_K, alpha_rho_K, Re_K, & - G_K, G) - $:GPU_ROUTINE(function_name='s_convert_species_to_mixture_variables_acc', & - & parallelism='[seq]', cray_noinline=True) + !> @brief GPU-accelerated conversion of species volume fractions and partial densities to mixture density, gamma, pi_inf, and + !! qv. + subroutine s_convert_species_to_mixture_variables_acc(rho_K, gamma_K, pi_inf_K, qv_K, alpha_K, alpha_rho_K, Re_K, G_K, G) + + $:GPU_ROUTINE(function_name='s_convert_species_to_mixture_variables_acc', parallelism='[seq]', cray_noinline=True) real(wp), intent(out) :: rho_K, gamma_K, pi_inf_K, qv_K #:if not MFC_CASE_OPTIMIZATION and USING_AMD - real(wp), dimension(3), intent(inout) :: alpha_rho_K, alpha_K !< + real(wp), dimension(3), intent(inout) :: alpha_rho_K, alpha_K real(wp), optional, dimension(3), intent(in) :: G #:else - real(wp), dimension(num_fluids), intent(inout) :: alpha_rho_K, alpha_K !< + real(wp), dimension(num_fluids), intent(inout) :: alpha_rho_K, alpha_K real(wp), optional, dimension(num_fluids), intent(in) :: G #:endif real(wp), dimension(2), intent(out) :: Re_K - real(wp), optional, intent(out) :: G_K - real(wp) :: alpha_K_sum - - integer :: i, j !< Generic loop iterators + real(wp), optional, intent(out) :: G_K + real(wp) :: alpha_K_sum + integer :: i, j !< Generic loop iterators #ifdef MFC_SIMULATION - ! Constraining the partial densities and the volume fractions within - ! their physical bounds to make sure that any mixture variables that - ! are derived from them result within the limits that are set by the - ! fluids physical parameters that make up the mixture + ! Constraining the partial densities and the volume fractions within their physical bounds to make sure that any mixture + ! variables that are derived from them result within the limits that are set by the fluids physical parameters that make up + ! the mixture if (num_fluids == 1 .and. bubbles_euler) then rho_K = alpha_rho_K(1) gamma_K = gammas(1) @@ -374,8 +333,7 @@ contains if (present(G_K)) then G_K = 0._wp do i = 1, num_fluids - !TODO: change to use Gs_vc directly here? - !TODO: Make this changes as well for GPUs + ! TODO: change to use Gs_vc directly here? TODO: Make this changes as well for GPUs G_K = G_K + alpha_K(i)*G(i) end do G_K = max(0._wp, G_K) @@ -388,8 +346,7 @@ contains if (Re_size(i) > 0) Re_K(i) = 0._wp do j = 1, Re_size(i) - Re_K(i) = alpha_K(Re_idx(i, j))/Res_vc(i, j) & - + Re_K(i) + Re_K(i) = alpha_K(Re_idx(i, j))/Res_vc(i, j) + Re_K(i) end do Re_K(i) = 1._wp/max(Re_K(i), sgm_eps) @@ -399,14 +356,13 @@ contains end subroutine s_convert_species_to_mixture_variables_acc - !> The computation of parameters, the allocation of memory, - !! the association of pointers and/or the execution of any - !! other procedures that are necessary to setup the module. + !> The computation of parameters, the allocation of memory, the association of pointers and/or the execution of any other + !! procedures that are necessary to setup the module. impure subroutine s_initialize_variables_conversion_module integer :: i, j - $:GPU_ENTER_DATA(copyin='[is1b,is1e,is2b,is2e,is3b,is3e]') + $:GPU_ENTER_DATA(copyin='[is1b, is1e, is2b, is2e, is3b, is3e]') @:ALLOCATE(gammas (1:num_fluids)) @:ALLOCATE(gs_min (1:num_fluids)) @@ -427,10 +383,9 @@ contains qvs(i) = fluid_pp(i)%qv qvps(i) = fluid_pp(i)%qvp end do - $:GPU_UPDATE(device='[gammas,gs_min,pi_infs,ps_inf,cvs,qvs,qvps,Gs_vc]') + $:GPU_UPDATE(device='[gammas, gs_min, pi_infs, ps_inf, cvs, qvs, qvps, Gs_vc]') #ifdef MFC_SIMULATION - if (viscous) then @:ALLOCATE(Res_vc(1:2, 1:Re_size_max)) do i = 1, 2 @@ -439,7 +394,7 @@ contains end do end do - $:GPU_UPDATE(device='[Res_vc,Re_idx,Re_size]') + $:GPU_UPDATE(device='[Res_vc, Re_idx, Re_size]') end if #endif @@ -452,61 +407,31 @@ contains end if #ifdef MFC_POST_PROCESS - ! Allocating the density, the specific heat ratio function and the - ! liquid stiffness function, respectively + ! Allocating the density, the specific heat ratio function and the liquid stiffness function, respectively ! Simulation is at least 2D if (n > 0) then - ! Simulation is 3D if (p > 0) then - - allocate (rho_sf(-buff_size:m + buff_size, & - -buff_size:n + buff_size, & - -buff_size:p + buff_size)) - allocate (gamma_sf(-buff_size:m + buff_size, & - -buff_size:n + buff_size, & - -buff_size:p + buff_size)) - allocate (pi_inf_sf(-buff_size:m + buff_size, & - -buff_size:n + buff_size, & - -buff_size:p + buff_size)) - allocate (qv_sf(-buff_size:m + buff_size, & - -buff_size:n + buff_size, & - -buff_size:p + buff_size)) + allocate (rho_sf(-buff_size:m + buff_size,-buff_size:n + buff_size,-buff_size:p + buff_size)) + allocate (gamma_sf(-buff_size:m + buff_size,-buff_size:n + buff_size,-buff_size:p + buff_size)) + allocate (pi_inf_sf(-buff_size:m + buff_size,-buff_size:n + buff_size,-buff_size:p + buff_size)) + allocate (qv_sf(-buff_size:m + buff_size,-buff_size:n + buff_size,-buff_size:p + buff_size)) ! Simulation is 2D else - - allocate (rho_sf(-buff_size:m + buff_size, & - -buff_size:n + buff_size, & - 0:0)) - allocate (gamma_sf(-buff_size:m + buff_size, & - -buff_size:n + buff_size, & - 0:0)) - allocate (pi_inf_sf(-buff_size:m + buff_size, & - -buff_size:n + buff_size, & - 0:0)) - allocate (qv_sf(-buff_size:m + buff_size, & - -buff_size:n + buff_size, & - 0:0)) + allocate (rho_sf(-buff_size:m + buff_size,-buff_size:n + buff_size,0:0)) + allocate (gamma_sf(-buff_size:m + buff_size,-buff_size:n + buff_size,0:0)) + allocate (pi_inf_sf(-buff_size:m + buff_size,-buff_size:n + buff_size,0:0)) + allocate (qv_sf(-buff_size:m + buff_size,-buff_size:n + buff_size,0:0)) end if ! Simulation is 1D else - - allocate (rho_sf(-buff_size:m + buff_size, & - 0:0, & - 0:0)) - allocate (gamma_sf(-buff_size:m + buff_size, & - 0:0, & - 0:0)) - allocate (pi_inf_sf(-buff_size:m + buff_size, & - 0:0, & - 0:0)) - allocate (qv_sf(-buff_size:m + buff_size, & - 0:0, & - 0:0)) - + allocate (rho_sf(-buff_size:m + buff_size,0:0,0:0)) + allocate (gamma_sf(-buff_size:m + buff_size,0:0,0:0)) + allocate (pi_inf_sf(-buff_size:m + buff_size,0:0,0:0)) + allocate (qv_sf(-buff_size:m + buff_size,0:0,0:0)) end if #endif @@ -515,17 +440,14 @@ contains !> @brief Initializes bubble mass-vapor values at quadrature nodes from the conserved moment statistics. subroutine s_initialize_mv(qK_cons_vf, mv) - type(scalar_field), dimension(sys_size), intent(in) :: qK_cons_vf - - real(stp), dimension(idwint(1)%beg:, idwint(2)%beg:, idwint(3)%beg:, 1:, 1:), intent(inout) :: mv - - integer :: i, j, k, l - real(wp) :: mu, sig, nbub_sc + type(scalar_field), dimension(sys_size), intent(in) :: qK_cons_vf + real(stp), dimension(idwint(1)%beg:,idwint(2)%beg:,idwint(3)%beg:,1:,1:), intent(inout) :: mv + integer :: i, j, k, l + real(wp) :: mu, sig, nbub_sc do l = idwint(3)%beg, idwint(3)%end do k = idwint(2)%beg, idwint(2)%end do j = idwint(1)%beg, idwint(1)%end - nbub_sc = qK_cons_vf(bubxb)%sf(j, k, l) $:GPU_LOOP(parallelism='[seq]') @@ -538,7 +460,6 @@ contains mv(j, k, l, 3, i) = (mass_v0(i))*(mu + sig)**(3._wp)/(R0(i)**(3._wp)) mv(j, k, l, 4, i) = (mass_v0(i))*(mu + sig)**(3._wp)/(R0(i)**(3._wp)) end do - end do end do end do @@ -547,18 +468,16 @@ contains !> @brief Initializes bubble internal pressures at quadrature nodes using isothermal relations from the Preston model. subroutine s_initialize_pb(qK_cons_vf, mv, pb) - type(scalar_field), dimension(sys_size), intent(in) :: qK_cons_vf - - real(stp), dimension(idwint(1)%beg:, idwint(2)%beg:, idwint(3)%beg:, 1:, 1:), intent(in) :: mv - real(stp), dimension(idwint(1)%beg:, idwint(2)%beg:, idwint(3)%beg:, 1:, 1:), intent(inout) :: pb - integer :: i, j, k, l - real(wp) :: mu, sig, nbub_sc + type(scalar_field), dimension(sys_size), intent(in) :: qK_cons_vf + real(stp), dimension(idwint(1)%beg:,idwint(2)%beg:,idwint(3)%beg:,1:,1:), intent(in) :: mv + real(stp), dimension(idwint(1)%beg:,idwint(2)%beg:,idwint(3)%beg:,1:,1:), intent(inout) :: pb + integer :: i, j, k, l + real(wp) :: mu, sig, nbub_sc do l = idwint(3)%beg, idwint(3)%end do k = idwint(2)%beg, idwint(2)%end do j = idwint(1)%beg, idwint(1)%end - nbub_sc = qK_cons_vf(bubxb)%sf(j, k, l) $:GPU_LOOP(parallelism='[seq]') @@ -566,11 +485,15 @@ contains mu = qK_cons_vf(bubxb + 1 + (i - 1)*nmom)%sf(j, k, l)/nbub_sc sig = (qK_cons_vf(bubxb + 3 + (i - 1)*nmom)%sf(j, k, l)/nbub_sc - mu**2)**0.5_wp - !PRESTON (ISOTHERMAL) - pb(j, k, l, 1, i) = (pb0(i))*(R0(i)**(3._wp))*(mass_g0(i) + mv(j, k, l, 1, i))/(mu - sig)**(3._wp)/(mass_g0(i) + mass_v0(i)) - pb(j, k, l, 2, i) = (pb0(i))*(R0(i)**(3._wp))*(mass_g0(i) + mv(j, k, l, 2, i))/(mu - sig)**(3._wp)/(mass_g0(i) + mass_v0(i)) - pb(j, k, l, 3, i) = (pb0(i))*(R0(i)**(3._wp))*(mass_g0(i) + mv(j, k, l, 3, i))/(mu + sig)**(3._wp)/(mass_g0(i) + mass_v0(i)) - pb(j, k, l, 4, i) = (pb0(i))*(R0(i)**(3._wp))*(mass_g0(i) + mv(j, k, l, 4, i))/(mu + sig)**(3._wp)/(mass_g0(i) + mass_v0(i)) + ! PRESTON (ISOTHERMAL) + pb(j, k, l, 1, i) = (pb0(i))*(R0(i)**(3._wp))*(mass_g0(i) + mv(j, k, l, 1, & + & i))/(mu - sig)**(3._wp)/(mass_g0(i) + mass_v0(i)) + pb(j, k, l, 2, i) = (pb0(i))*(R0(i)**(3._wp))*(mass_g0(i) + mv(j, k, l, 2, & + & i))/(mu - sig)**(3._wp)/(mass_g0(i) + mass_v0(i)) + pb(j, k, l, 3, i) = (pb0(i))*(R0(i)**(3._wp))*(mass_g0(i) + mv(j, k, l, 3, & + & i))/(mu + sig)**(3._wp)/(mass_g0(i) + mass_v0(i)) + pb(j, k, l, 4, i) = (pb0(i))*(R0(i)**(3._wp))*(mass_g0(i) + mv(j, k, l, 4, & + & i))/(mu + sig)**(3._wp)/(mass_g0(i) + mass_v0(i)) end do end do end do @@ -578,55 +501,48 @@ contains end subroutine s_initialize_pb - !> The following procedure handles the conversion between - !! the conservative variables and the primitive variables. - !! @param qK_cons_vf Conservative variables - !! @param q_T_sf Temperature scalar field - !! @param qK_prim_vf Primitive variables - !! @param ibounds Index bounds in each coordinate direction - subroutine s_convert_conservative_to_primitive_variables(qK_cons_vf, & - q_T_sf, & - qK_prim_vf, & - ibounds) - - type(scalar_field), dimension(sys_size), intent(in) :: qK_cons_vf - type(scalar_field), intent(inout) :: q_T_sf + !> The following procedure handles the conversion between the conservative variables and the primitive variables. + !! @param qK_cons_vf Conservative variables + !! @param q_T_sf Temperature scalar field + !! @param qK_prim_vf Primitive variables + !! @param ibounds Index bounds in each coordinate direction + subroutine s_convert_conservative_to_primitive_variables(qK_cons_vf, q_T_sf, qK_prim_vf, ibounds) + + type(scalar_field), dimension(sys_size), intent(in) :: qK_cons_vf + type(scalar_field), intent(inout) :: q_T_sf type(scalar_field), dimension(sys_size), intent(inout) :: qK_prim_vf - type(int_bounds_info), dimension(1:3), intent(in) :: ibounds + type(int_bounds_info), dimension(1:3), intent(in) :: ibounds + #:if USING_AMD and not MFC_CASE_OPTIMIZATION real(wp), dimension(3) :: alpha_K, alpha_rho_K real(wp), dimension(3) :: nRtmp - real(wp) :: rhoYks(1:10) + real(wp) :: rhoYks(1:10) #:else real(wp), dimension(num_fluids) :: alpha_K, alpha_rho_K - real(wp), dimension(nb) :: nRtmp - real(wp) :: rhoYks(1:num_species) + real(wp), dimension(nb) :: nRtmp + real(wp) :: rhoYks(1:num_species) #:endif real(wp), dimension(2) :: Re_K - real(wp) :: rho_K, gamma_K, pi_inf_K, qv_K, dyn_pres_K - - real(wp) :: vftmp, nbub_sc - - real(wp) :: G_K - - real(wp) :: pres - - integer :: i, j, k, l !< Generic loop iterators - - real(wp) :: T - real(wp) :: pres_mag - - real(wp) :: Ga ! Lorentz factor (gamma in relativity) - real(wp) :: B2 ! Magnetic field magnitude squared - real(wp) :: B(3) ! Magnetic field components - real(wp) :: m2 ! Relativistic momentum magnitude squared - real(wp) :: S ! Dot product of the magnetic field and the relativistic momentum - real(wp) :: W, dW ! W := rho*v*Ga**2; f = f(W) in Newton-Raphson - real(wp) :: E, D ! Prim/Cons variables within Newton-Raphson iteration - real(wp) :: f, dGa_dW, dp_dW, df_dW ! Functions within Newton-Raphson iteration - integer :: iter ! Newton-Raphson iteration counter - - $:GPU_PARALLEL_LOOP(collapse=3, private='[alpha_K, alpha_rho_K, Re_K, nRtmp, rho_K, gamma_K, pi_inf_K,qv_K, dyn_pres_K, rhoYks, B, pres, vftmp, nbub_sc, G_K, T, pres_mag, Ga, B2, m2, S, W, dW, E, D, f, dGa_dW, dp_dW, df_dW, iter ]') + real(wp) :: rho_K, gamma_K, pi_inf_K, qv_K, dyn_pres_K + real(wp) :: vftmp, nbub_sc + real(wp) :: G_K + real(wp) :: pres + integer :: i, j, k, l !< Generic loop iterators + real(wp) :: T + real(wp) :: pres_mag + real(wp) :: Ga ! Lorentz factor (gamma in relativity) + real(wp) :: B2 ! Magnetic field magnitude squared + real(wp) :: B(3) ! Magnetic field components + real(wp) :: m2 ! Relativistic momentum magnitude squared + real(wp) :: S ! Dot product of the magnetic field and the relativistic momentum + real(wp) :: W, dW ! W := rho*v*Ga**2; f = f(W) in Newton-Raphson + real(wp) :: E, D ! Prim/Cons variables within Newton-Raphson iteration + real(wp) :: f, dGa_dW, dp_dW, df_dW ! Functions within Newton-Raphson iteration + integer :: iter ! Newton-Raphson iteration counter + + $:GPU_PARALLEL_LOOP(collapse=3, private='[alpha_K, alpha_rho_K, Re_K, nRtmp, rho_K, gamma_K, pi_inf_K, qv_K, dyn_pres_K, & + & rhoYks, B, pres, vftmp, nbub_sc, G_K, T, pres_mag, Ga, B2, m2, S, W, dW, E, D, f, dGa_dW, dp_dW, & + & df_dW, iter ]') do l = ibounds(3)%beg, ibounds(3)%end do k = ibounds(2)%beg, ibounds(2)%end do j = ibounds(1)%beg, ibounds(1)%end @@ -638,20 +554,19 @@ contains #ifdef MFC_SIMULATION ! If in simulation, use acc mixture subroutines if (elasticity) then - call s_convert_species_to_mixture_variables_acc(rho_K, gamma_K, pi_inf_K, qv_K, alpha_K, & - alpha_rho_K, Re_K, G_K, Gs_vc) + call s_convert_species_to_mixture_variables_acc(rho_K, gamma_K, pi_inf_K, qv_K, alpha_K, alpha_rho_K, & + & Re_K, G_K, Gs_vc) else - call s_convert_species_to_mixture_variables_acc(rho_K, gamma_K, pi_inf_K, qv_K, & - alpha_K, alpha_rho_K, Re_K) + call s_convert_species_to_mixture_variables_acc(rho_K, gamma_K, pi_inf_K, qv_K, alpha_K, alpha_rho_K, & + & Re_K) end if #else ! If pre-processing, use non acc mixture subroutines if (elasticity) then - call s_convert_to_mixture_variables(qK_cons_vf, j, k, l, & - rho_K, gamma_K, pi_inf_K, qv_K, Re_K, G_K, fluid_pp(:)%G) + call s_convert_to_mixture_variables(qK_cons_vf, j, k, l, rho_K, gamma_K, pi_inf_K, qv_K, Re_K, G_K, & + & fluid_pp(:)%G) else - call s_convert_to_mixture_variables(qK_cons_vf, j, k, l, & - rho_K, gamma_K, pi_inf_K, qv_K) + call s_convert_to_mixture_variables(qK_cons_vf, j, k, l, rho_K, gamma_K, pi_inf_K, qv_K) end if #endif end if @@ -693,15 +608,14 @@ contains $:GPU_LOOP(parallelism='[seq]') do iter = 1, relativity_cons_to_prim_max_iter Ga = (W + B2)*W/sqrt((W + B2)**2*W**2 - (m2*W**2 + S**2*(2*W + B2))) - pres = (W - D*Ga)/((gamma_K + 1)*Ga**2) ! Thermal pressure from EOS + pres = (W - D*Ga)/((gamma_K + 1)*Ga**2) ! Thermal pressure from EOS f = W - pres + (1 - 1/(2*Ga**2))*B2 - S**2/(2*W**2) - E - D - ! The first equation below corrects a typo in (Mignone & Bodo, 2006) - ! m2*W**2 → 2*m2*W**2, which would cancel with the 2* in other terms - ! This corrected version is not used as the second equation empirically converges faster. - ! First equation is kept for further investigation. - ! dGa_dW = -Ga**3 * ( S**2*(3*W**2+3*W*B2+B2**2) + m2*W**2 ) / (W**3 * (W+B2)**3) ! first (corrected) - dGa_dW = -Ga**3*(2*S**2*(3*W**2 + 3*W*B2 + B2**2) + m2*W**2)/(2*W**3*(W + B2)**3) ! second (in paper) + ! The first equation below corrects a typo in (Mignone & Bodo, 2006) m2*W**2 -> 2*m2*W**2, which would + ! cancel with the 2* in other terms This corrected version is not used as the second equation + ! empirically converges faster. First equation is kept for further investigation. dGa_dW = -Ga**3 * ( + ! S**2*(3*W**2+3*W*B2+B2**2) + m2*W**2 ) / (W**3 * (W+B2)**3) ! first (corrected) + dGa_dW = -Ga**3*(2*S**2*(3*W**2 + 3*W*B2 + B2**2) + m2*W**2)/(2*W**3*(W + B2)**3) ! second (in paper) dp_dW = (Ga*(1 + D*dGa_dW) - 2*W*dGa_dW)/((gamma_K + 1)*Ga**3) df_dW = 1 - dp_dW + (B2/Ga**3)*dGa_dW + S**2/W**3 @@ -720,14 +634,14 @@ contains do i = 1, 3 qK_prim_vf(momxb + i - 1)%sf(j, k, l) = (qK_cons_vf(momxb + i - 1)%sf(j, k, l) + (S/W)*B(i))/(W + B2) end do - qK_prim_vf(1)%sf(j, k, l) = D/Ga ! Hard-coded for single-component for now + qK_prim_vf(1)%sf(j, k, l) = D/Ga ! Hard-coded for single-component for now $:GPU_LOOP(parallelism='[seq]') do i = B_idx%beg, B_idx%end qK_prim_vf(i)%sf(j, k, l) = qK_cons_vf(i)%sf(j, k, l) end do - cycle ! skip all the non-relativistic conversions below + cycle ! skip all the non-relativistic conversions below end if if (chemistry) then @@ -760,13 +674,10 @@ contains $:GPU_LOOP(parallelism='[seq]') do i = momxb, momxe if (model_eqns /= 4) then - qK_prim_vf(i)%sf(j, k, l) = qK_cons_vf(i)%sf(j, k, l) & - /rho_K - dyn_pres_K = dyn_pres_K + 5.e-1_wp*qK_cons_vf(i)%sf(j, k, l) & - *qK_prim_vf(i)%sf(j, k, l) + qK_prim_vf(i)%sf(j, k, l) = qK_cons_vf(i)%sf(j, k, l)/rho_K + dyn_pres_K = dyn_pres_K + 5.e-1_wp*qK_cons_vf(i)%sf(j, k, l)*qK_prim_vf(i)%sf(j, k, l) else - qK_prim_vf(i)%sf(j, k, l) = qK_cons_vf(i)%sf(j, k, l) & - /qK_cons_vf(1)%sf(j, k, l) + qK_prim_vf(i)%sf(j, k, l) = qK_cons_vf(i)%sf(j, k, l)/qK_cons_vf(1)%sf(j, k, l) end if end do @@ -781,18 +692,18 @@ contains if (mhd) then if (n == 0) then - pres_mag = 0.5_wp*(Bx0**2 + qK_cons_vf(B_idx%beg)%sf(j, k, l)**2 + qK_cons_vf(B_idx%beg + 1)%sf(j, k, l)**2) + pres_mag = 0.5_wp*(Bx0**2 + qK_cons_vf(B_idx%beg)%sf(j, k, l)**2 + qK_cons_vf(B_idx%beg + 1)%sf(j, k, & + & l)**2) else - pres_mag = 0.5_wp*(qK_cons_vf(B_idx%beg)%sf(j, k, l)**2 + qK_cons_vf(B_idx%beg + 1)%sf(j, k, l)**2 + qK_cons_vf(B_idx%beg + 2)%sf(j, k, l)**2) + pres_mag = 0.5_wp*(qK_cons_vf(B_idx%beg)%sf(j, k, l)**2 + qK_cons_vf(B_idx%beg + 1)%sf(j, k, & + & l)**2 + qK_cons_vf(B_idx%beg + 2)%sf(j, k, l)**2) end if else pres_mag = 0._wp end if - call s_compute_pressure(qK_cons_vf(E_idx)%sf(j, k, l), & - qK_cons_vf(alf_idx)%sf(j, k, l), & - dyn_pres_K, pi_inf_K, gamma_K, rho_K, & - qv_K, rhoYks, pres, T, pres_mag=pres_mag) + call s_compute_pressure(qK_cons_vf(E_idx)%sf(j, k, l), qK_cons_vf(alf_idx)%sf(j, k, l), dyn_pres_K, pi_inf_K, & + & gamma_K, rho_K, qv_K, rhoYks, pres, T, pres_mag=pres_mag) qK_prim_vf(E_idx)%sf(j, k, l) = pres @@ -809,19 +720,18 @@ contains vftmp = qK_cons_vf(alf_idx)%sf(j, k, l) if (qbmm) then - !Get nb (constant across all R0 bins) + ! Get nb (constant across all R0 bins) nbub_sc = qK_cons_vf(bubxb)%sf(j, k, l) - !Convert cons to prim + ! Convert cons to prim $:GPU_LOOP(parallelism='[seq]') do i = bubxb, bubxe qK_prim_vf(i)%sf(j, k, l) = qK_cons_vf(i)%sf(j, k, l)/nbub_sc end do - !Need to keep track of nb in the primitive variable list (converted back to true value before output) + ! Need to keep track of nb in the primitive variable list (converted back to true value before output) #ifdef MFC_SIMULATION qK_prim_vf(bubxb)%sf(j, k, l) = qK_cons_vf(bubxb)%sf(j, k, l) #endif - else if (adv_n) then qK_prim_vf(n_idx)%sf(j, k, l) = qK_cons_vf(n_idx)%sf(j, k, l) @@ -857,12 +767,12 @@ contains do i = strxb, strxe ! subtracting elastic contribution for pressure calculation if (G_K > verysmall) then - qK_prim_vf(E_idx)%sf(j, k, l) = qK_prim_vf(E_idx)%sf(j, k, l) - & - ((qK_prim_vf(i)%sf(j, k, l)**2._wp)/(4._wp*G_K))/gamma_K + qK_prim_vf(E_idx)%sf(j, k, l) = qK_prim_vf(E_idx)%sf(j, k, l) - ((qK_prim_vf(i)%sf(j, k, & + & l)**2._wp)/(4._wp*G_K))/gamma_K ! Double for shear stresses if (any(i == shear_indices)) then - qK_prim_vf(E_idx)%sf(j, k, l) = qK_prim_vf(E_idx)%sf(j, k, l) - & - ((qK_prim_vf(i)%sf(j, k, l)**2._wp)/(4._wp*G_K))/gamma_K + qK_prim_vf(E_idx)%sf(j, k, l) = qK_prim_vf(E_idx)%sf(j, k, l) - ((qK_prim_vf(i)%sf(j, k, & + & l)**2._wp)/(4._wp*G_K))/gamma_K end if end if end do @@ -892,7 +802,6 @@ contains #ifdef MFC_POST_PROCESS if (bubbles_lagrange) qK_prim_vf(beta_idx)%sf(j, k, l) = qK_cons_vf(beta_idx)%sf(j, k, l) #endif - end do end do end do @@ -900,41 +809,35 @@ contains end subroutine s_convert_conservative_to_primitive_variables - !> The following procedure handles the conversion between - !! the primitive variables and the conservative variables. - !! @param q_prim_vf Primitive variables - !! @param q_cons_vf Conservative variables - impure subroutine s_convert_primitive_to_conservative_variables(q_prim_vf, & - q_cons_vf) + !> The following procedure handles the conversion between the primitive variables and the conservative variables. + !! @param q_prim_vf Primitive variables + !! @param q_cons_vf Conservative variables + impure subroutine s_convert_primitive_to_conservative_variables(q_prim_vf, q_cons_vf) - type(scalar_field), dimension(sys_size), intent(in) :: q_prim_vf + type(scalar_field), dimension(sys_size), intent(in) :: q_prim_vf type(scalar_field), dimension(sys_size), intent(inout) :: q_cons_vf - ! Density, specific heat ratio function, liquid stiffness function - ! and dynamic pressure, as defined in the incompressible flow sense, - ! respectively - real(wp) :: rho - real(wp) :: gamma - real(wp) :: pi_inf - real(wp) :: qv - real(wp) :: dyn_pres - real(wp) :: nbub, R3tmp - real(wp), dimension(nb) :: Rtmp - real(wp) :: G - real(wp), dimension(2) :: Re_K - - integer :: i, j, k, l !< Generic loop iterators - + ! Density, specific heat ratio function, liquid stiffness function and dynamic pressure, as defined in the incompressible + ! flow sense, respectively + real(wp) :: rho + real(wp) :: gamma + real(wp) :: pi_inf + real(wp) :: qv + real(wp) :: dyn_pres + real(wp) :: nbub, R3tmp + real(wp), dimension(nb) :: Rtmp + real(wp) :: G + real(wp), dimension(2) :: Re_K + integer :: i, j, k, l !< Generic loop iterators real(wp), dimension(num_species) :: Ys - real(wp) :: e_mix, mix_mol_weight, T - real(wp) :: pres_mag - - real(wp) :: Ga ! Lorentz factor (gamma in relativity) - real(wp) :: h ! relativistic enthalpy - real(wp) :: v2 ! Square of the velocity magnitude - real(wp) :: B2 ! Square of the magnetic field magnitude - real(wp) :: vdotB ! Dot product of the velocity and magnetic field vectors - real(wp) :: B(3) ! Magnetic field components + real(wp) :: e_mix, mix_mol_weight, T + real(wp) :: pres_mag + real(wp) :: Ga ! Lorentz factor (gamma in relativity) + real(wp) :: h ! relativistic enthalpy + real(wp) :: v2 ! Square of the velocity magnitude + real(wp) :: B2 ! Square of the magnetic field magnitude + real(wp) :: vdotB ! Dot product of the velocity and magnetic field vectors + real(wp) :: B(3) ! Magnetic field components pres_mag = 0._wp @@ -945,11 +848,8 @@ contains do l = 0, p do k = 0, n do j = 0, m - - ! Obtaining the density, specific heat ratio function - ! and the liquid stiffness function, respectively - call s_convert_to_mixture_variables(q_prim_vf, j, k, l, & - rho, gamma, pi_inf, qv, Re_K, G, fluid_pp(:)%G) + ! Obtaining the density, specific heat ratio function and the liquid stiffness function, respectively + call s_convert_to_mixture_variables(q_prim_vf, j, k, l, rho, gamma, pi_inf, qv, Re_K, G, fluid_pp(:)%G) if (.not. igr .or. num_fluids > 1) then ! Transferring the advection equation(s) variable(s) @@ -959,7 +859,6 @@ contains end if if (relativity) then - if (n == 0) then B(1) = Bx0 B(2) = q_prim_vf(B_idx%beg)%sf(j, k, l) @@ -978,7 +877,7 @@ contains Ga = 1._wp/sqrt(1._wp - v2) - h = 1._wp + (gamma + 1)*q_prim_vf(E_idx)%sf(j, k, l)/rho ! Assume perfect gas for now + h = 1._wp + (gamma + 1)*q_prim_vf(E_idx)%sf(j, k, l)/rho ! Assume perfect gas for now B2 = 0._wp do i = B_idx%beg, B_idx%end @@ -996,12 +895,10 @@ contains end do do i = momxb, momxe - q_cons_vf(i)%sf(j, k, l) = (rho*h*Ga**2 + B2)*q_prim_vf(i)%sf(j, k, l) & - - vdotB*B(i - momxb + 1) + q_cons_vf(i)%sf(j, k, l) = (rho*h*Ga**2 + B2)*q_prim_vf(i)%sf(j, k, l) - vdotB*B(i - momxb + 1) end do - q_cons_vf(E_idx)%sf(j, k, l) = rho*h*Ga**2 - q_prim_vf(E_idx)%sf(j, k, l) & - + 0.5_wp*(B2 + v2*B2 - vdotB**2) + q_cons_vf(E_idx)%sf(j, k, l) = rho*h*Ga**2 - q_prim_vf(E_idx)%sf(j, k, l) + 0.5_wp*(B2 + v2*B2 - vdotB**2) ! Remove rest energy do i = 1, contxe q_cons_vf(E_idx)%sf(j, k, l) = q_cons_vf(E_idx)%sf(j, k, l) - q_cons_vf(i)%sf(j, k, l) @@ -1011,8 +908,7 @@ contains q_cons_vf(i)%sf(j, k, l) = q_prim_vf(i)%sf(j, k, l) end do - cycle ! skip all the non-relativistic conversions below - + cycle ! skip all the non-relativistic conversions below end if ! Transferring the continuity equation(s) variable(s) @@ -1020,15 +916,13 @@ contains q_cons_vf(i)%sf(j, k, l) = q_prim_vf(i)%sf(j, k, l) end do - ! Zeroing out the dynamic pressure since it is computed - ! iteratively by cycling through the velocity equations + ! Zeroing out the dynamic pressure since it is computed iteratively by cycling through the velocity equations dyn_pres = 0._wp ! Computing momenta and dynamic pressure from velocity do i = momxb, momxe q_cons_vf(i)%sf(j, k, l) = rho*q_prim_vf(i)%sf(j, k, l) - dyn_pres = dyn_pres + q_cons_vf(i)%sf(j, k, l)* & - q_prim_vf(i)%sf(j, k, l)/2._wp + dyn_pres = dyn_pres + q_cons_vf(i)%sf(j, k, l)*q_prim_vf(i)%sf(j, k, l)/2._wp end do if (chemistry) then @@ -1041,30 +935,27 @@ contains T = q_prim_vf(E_idx)%sf(j, k, l)*mix_mol_weight/(gas_constant*rho) call get_mixture_energy_mass(T, Ys, e_mix) - q_cons_vf(E_idx)%sf(j, k, l) = & - dyn_pres + rho*e_mix + q_cons_vf(E_idx)%sf(j, k, l) = dyn_pres + rho*e_mix else ! Computing the energy from the pressure if (mhd) then if (n == 0) then - pres_mag = 0.5_wp*(Bx0**2 + q_prim_vf(B_idx%beg)%sf(j, k, l)**2 + q_prim_vf(B_idx%beg + 1)%sf(j, k, l)**2) + pres_mag = 0.5_wp*(Bx0**2 + q_prim_vf(B_idx%beg)%sf(j, k, l)**2 + q_prim_vf(B_idx%beg + 1)%sf(j, & + & k, l)**2) else - pres_mag = 0.5_wp*(q_prim_vf(B_idx%beg)%sf(j, k, l)**2 + q_prim_vf(B_idx%beg + 1)%sf(j, k, l)**2 + q_prim_vf(B_idx%beg + 2)%sf(j, k, l)**2) + pres_mag = 0.5_wp*(q_prim_vf(B_idx%beg)%sf(j, k, l)**2 + q_prim_vf(B_idx%beg + 1)%sf(j, k, & + & l)**2 + q_prim_vf(B_idx%beg + 2)%sf(j, k, l)**2) end if - q_cons_vf(E_idx)%sf(j, k, l) = & - gamma*q_prim_vf(E_idx)%sf(j, k, l) + dyn_pres + pres_mag & - + pi_inf + qv - elseif ((model_eqns /= 4) .and. (bubbles_euler .neqv. .true.)) then + q_cons_vf(E_idx)%sf(j, k, l) = gamma*q_prim_vf(E_idx)%sf(j, k, l) + dyn_pres + pres_mag + pi_inf + qv + else if ((model_eqns /= 4) .and. (bubbles_euler .neqv. .true.)) then ! E = Gamma*P + \rho u u /2 + \pi_inf + (\alpha\rho qv) - q_cons_vf(E_idx)%sf(j, k, l) = & - gamma*q_prim_vf(E_idx)%sf(j, k, l) + dyn_pres + pi_inf + qv + q_cons_vf(E_idx)%sf(j, k, l) = gamma*q_prim_vf(E_idx)%sf(j, k, l) + dyn_pres + pi_inf + qv else if ((model_eqns /= 4) .and. (bubbles_euler)) then ! \tilde{E} = dyn_pres + (1-\alf)(\Gamma p_l + \Pi_inf) - q_cons_vf(E_idx)%sf(j, k, l) = dyn_pres + & - (1._wp - q_prim_vf(alf_idx)%sf(j, k, l))* & - (gamma*q_prim_vf(E_idx)%sf(j, k, l) + pi_inf) + q_cons_vf(E_idx)%sf(j, k, l) = dyn_pres + (1._wp - q_prim_vf(alf_idx)%sf(j, k, & + & l))*(gamma*q_prim_vf(E_idx)%sf(j, k, l) + pi_inf) else - !Tait EOS, no conserved energy variable + ! Tait EOS, no conserved energy variable q_cons_vf(E_idx)%sf(j, k, l) = 0._wp end if end if @@ -1073,9 +964,9 @@ contains if (model_eqns == 3) then do i = 1, num_fluids ! internal energy calculation for each of the fluids - q_cons_vf(i + intxb - 1)%sf(j, k, l) = q_cons_vf(i + advxb - 1)%sf(j, k, l)* & - (gammas(i)*q_prim_vf(E_idx)%sf(j, k, l) + pi_infs(i)) + & - q_cons_vf(i + contxb - 1)%sf(j, k, l)*qvs(i) + q_cons_vf(i + intxb - 1)%sf(j, k, l) = q_cons_vf(i + advxb - 1)%sf(j, k, & + & l)*(gammas(i)*q_prim_vf(E_idx)%sf(j, k, & + & l) + pi_infs(i)) + q_cons_vf(i + contxb - 1)%sf(j, k, l)*qvs(i) end do end if @@ -1093,13 +984,13 @@ contains call s_comp_n_from_prim(real(q_prim_vf(alf_idx)%sf(j, k, l), kind=wp), Rtmp, nbub, weight) end if else - !Initialize R3 averaging over R0 and R directions + ! Initialize R3 averaging over R0 and R directions R3tmp = 0._wp do i = 1, nb R3tmp = R3tmp + weight(i)*0.5_wp*(Rtmp(i) + sigR)**3._wp R3tmp = R3tmp + weight(i)*0.5_wp*(Rtmp(i) - sigR)**3._wp end do - !Initialize nb + ! Initialize nb nbub = 3._wp*q_prim_vf(alf_idx)%sf(j, k, l)/(4._wp*pi*R3tmp) end if @@ -1115,8 +1006,7 @@ contains end if if (elasticity) then - ! adding the elastic contribution - ! Multiply \tau to \rho \tau + ! adding the elastic contribution Multiply \tau to \rho \tau do i = strxb, strxe q_cons_vf(i)%sf(j, k, l) = rho*q_prim_vf(i)%sf(j, k, l) end do @@ -1127,12 +1017,12 @@ contains do i = strxb, strxe ! adding elastic contribution if (G > verysmall) then - q_cons_vf(E_idx)%sf(j, k, l) = q_cons_vf(E_idx)%sf(j, k, l) + & - (q_prim_vf(i)%sf(j, k, l)**2._wp)/(4._wp*G) + q_cons_vf(E_idx)%sf(j, k, l) = q_cons_vf(E_idx)%sf(j, k, l) + (q_prim_vf(i)%sf(j, k, & + & l)**2._wp)/(4._wp*G) ! Double for shear stresses if (any(i == shear_indices)) then - q_cons_vf(E_idx)%sf(j, k, l) = q_cons_vf(E_idx)%sf(j, k, l) + & - (q_prim_vf(i)%sf(j, k, l)**2._wp)/(4._wp*G) + q_cons_vf(E_idx)%sf(j, k, l) = q_cons_vf(E_idx)%sf(j, k, l) + (q_prim_vf(i)%sf(j, k, & + & l)**2._wp)/(4._wp*G) end if end if end do @@ -1153,82 +1043,74 @@ contains if (cont_damage) q_cons_vf(damage_idx)%sf(j, k, l) = q_prim_vf(damage_idx)%sf(j, k, l) if (hyper_cleaning) q_cons_vf(psi_idx)%sf(j, k, l) = q_prim_vf(psi_idx)%sf(j, k, l) - end do end do end do #else if (proc_rank == 0) then - call s_mpi_abort('Conversion from primitive to '// & - 'conservative variables not '// & - 'implemented. Exiting.') + call s_mpi_abort('Conversion from primitive to ' // 'conservative variables not ' // 'implemented. Exiting.') end if #endif + end subroutine s_convert_primitive_to_conservative_variables - !> The following subroutine handles the conversion between - !! the primitive variables and the Eulerian flux variables. - !! @param qK_prim_vf Primitive variables - !! @param FK_vf Flux variables - !! @param FK_src_vf Flux source variables - !! @param is1 Index bounds in the first coordinate direction - !! @param is2 Index bounds in the second coordinate direction - !! @param is3 Index bounds in the third coordinate direction - !! @param s2b Starting boundary index in the second coordinate direction - !! @param s3b Starting boundary index in the third coordinate direction - subroutine s_convert_primitive_to_flux_variables(qK_prim_vf, & - FK_vf, & - FK_src_vf, & - is1, is2, is3, s2b, s3b) - - integer, intent(in) :: s2b, s3b - real(wp), dimension(0:, idwbuff(2)%beg:, idwbuff(3)%beg:, 1:), intent(in) :: qK_prim_vf - real(wp), dimension(0:, idwbuff(2)%beg:, idwbuff(3)%beg:, 1:), intent(inout) :: FK_vf - real(wp), dimension(0:, idwbuff(2)%beg:, idwbuff(3)%beg:, advxb:), intent(inout) :: FK_src_vf - - type(int_bounds_info), intent(in) :: is1, is2, is3 - - ! Partial densities, density, velocity, pressure, energy, advection - ! variables, the specific heat ratio and liquid stiffness functions, - ! the shear and volume Reynolds numbers and the Weber numbers + !> The following subroutine handles the conversion between the primitive variables and the Eulerian flux variables. + !! @param qK_prim_vf Primitive variables + !! @param FK_vf Flux variables + !! @param FK_src_vf Flux source variables + !! @param is1 Index bounds in the first coordinate direction + !! @param is2 Index bounds in the second coordinate direction + !! @param is3 Index bounds in the third coordinate direction + !! @param s2b Starting boundary index in the second coordinate direction + !! @param s3b Starting boundary index in the third coordinate direction + subroutine s_convert_primitive_to_flux_variables(qK_prim_vf, FK_vf, FK_src_vf, is1, is2, is3, s2b, s3b) + + integer, intent(in) :: s2b, s3b + real(wp), dimension(0:,idwbuff(2)%beg:,idwbuff(3)%beg:,1:), intent(in) :: qK_prim_vf + real(wp), dimension(0:,idwbuff(2)%beg:,idwbuff(3)%beg:,1:), intent(inout) :: FK_vf + real(wp), dimension(0:,idwbuff(2)%beg:,idwbuff(3)%beg:,advxb:), intent(inout) :: FK_src_vf + type(int_bounds_info), intent(in) :: is1, is2, is3 + + ! Partial densities, density, velocity, pressure, energy, advection variables, the specific heat ratio and liquid stiffness + ! functions, the shear and volume Reynolds numbers and the Weber numbers + #:if not MFC_CASE_OPTIMIZATION and USING_AMD - real(wp), dimension(3) :: alpha_rho_K - real(wp), dimension(3) :: alpha_K - real(wp), dimension(3) :: vel_K + real(wp), dimension(3) :: alpha_rho_K + real(wp), dimension(3) :: alpha_K + real(wp), dimension(3) :: vel_K real(wp), dimension(10) :: Y_K #:else - real(wp), dimension(num_fluids) :: alpha_rho_K - real(wp), dimension(num_fluids) :: alpha_K - real(wp), dimension(num_vels) :: vel_K + real(wp), dimension(num_fluids) :: alpha_rho_K + real(wp), dimension(num_fluids) :: alpha_K + real(wp), dimension(num_vels) :: vel_K real(wp), dimension(num_species) :: Y_K #:endif - real(wp) :: rho_K - real(wp) :: vel_K_sum - real(wp) :: pres_K - real(wp) :: E_K - real(wp) :: gamma_K - real(wp) :: pi_inf_K - real(wp) :: qv_K + real(wp) :: rho_K + real(wp) :: vel_K_sum + real(wp) :: pres_K + real(wp) :: E_K + real(wp) :: gamma_K + real(wp) :: pi_inf_K + real(wp) :: qv_K real(wp), dimension(2) :: Re_K - real(wp) :: G_K - real(wp) :: T_K, mix_mol_weight, R_gas - - integer :: i, j, k, l !< Generic loop iterators + real(wp) :: G_K + real(wp) :: T_K, mix_mol_weight, R_gas + integer :: i, j, k, l !< Generic loop iterators is1b = is1%beg; is1e = is1%end is2b = is2%beg; is2e = is2%end is3b = is3%beg; is3e = is3%end - $:GPU_UPDATE(device='[is1b,is2b,is3b,is1e,is2e,is3e]') + $:GPU_UPDATE(device='[is1b, is2b, is3b, is1e, is2e, is3e]') - ! Computing the flux variables from the primitive variables, without - ! accounting for the contribution of either viscosity or capillarity + ! Computing the flux variables from the primitive variables, without accounting for the contribution of either viscosity or + ! capillarity #ifdef MFC_SIMULATION - $:GPU_PARALLEL_LOOP(collapse=3, private='[alpha_rho_K, vel_K, alpha_K, Re_K, Y_K, rho_K, vel_K_sum, pres_K, E_K, gamma_K, pi_inf_K, qv_K, G_K, T_K, mix_mol_weight, R_gas]') + $:GPU_PARALLEL_LOOP(collapse=3, private='[alpha_rho_K, vel_K, alpha_K, Re_K, Y_K, rho_K, vel_K_sum, pres_K, E_K, gamma_K, & + & pi_inf_K, qv_K, G_K, T_K, mix_mol_weight, R_gas]') do l = is3b, is3e do k = is2b, is2e do j = is1b, is1e - $:GPU_LOOP(parallelism='[seq]') do i = 1, contxe alpha_rho_K(i) = qK_prim_vf(j, k, l, i) @@ -1252,12 +1134,10 @@ contains pres_K = qK_prim_vf(j, k, l, E_idx) if (elasticity) then - call s_convert_species_to_mixture_variables_acc(rho_K, gamma_K, pi_inf_K, qv_K, & - alpha_K, alpha_rho_K, Re_K, & - G_K, Gs_vc) + call s_convert_species_to_mixture_variables_acc(rho_K, gamma_K, pi_inf_K, qv_K, alpha_K, alpha_rho_K, & + & Re_K, G_K, Gs_vc) else - call s_convert_species_to_mixture_variables_acc(rho_K, gamma_K, pi_inf_K, qv_K, & - alpha_K, alpha_rho_K, Re_K) + call s_convert_species_to_mixture_variables_acc(rho_K, gamma_K, pi_inf_K, qv_K, alpha_K, alpha_rho_K, Re_K) end if ! Computing the energy from the pressure @@ -1267,7 +1147,7 @@ contains do i = chemxb, chemxe Y_K(i - chemxb + 1) = qK_prim_vf(j, k, l, i) end do - !Computing the energy from the internal energy of the mixture + ! Computing the energy from the internal energy of the mixture call get_mixture_molecular_weight(Y_k, mix_mol_weight) R_gas = gas_constant/mix_mol_weight T_K = pres_K/rho_K/R_gas @@ -1275,8 +1155,7 @@ contains E_K = rho_K*E_K + 5.e-1_wp*rho_K*vel_K_sum else ! Computing the energy from the pressure - E_K = gamma_K*pres_K + pi_inf_K & - + 5.e-1_wp*rho_K*vel_K_sum + qv_K + E_K = gamma_K*pres_K + pi_inf_K + 5.e-1_wp*rho_K*vel_K_sum + qv_K end if ! mass flux, this should be \alpha_i \rho_i u_i @@ -1287,10 +1166,7 @@ contains $:GPU_LOOP(parallelism='[seq]') do i = 1, num_vels - FK_vf(j, k, l, contxe + dir_idx(i)) = & - rho_K*vel_K(dir_idx(1)) & - *vel_K(dir_idx(i)) & - + pres_K*dir_flg(dir_idx(i)) + FK_vf(j, k, l, contxe + dir_idx(i)) = rho_K*vel_K(dir_idx(1))*vel_K(dir_idx(i)) + pres_K*dir_flg(dir_idx(i)) end do ! energy flux, u(E+p) @@ -1310,7 +1186,6 @@ contains FK_vf(j, k, l, i) = 0._wp FK_src_vf(j, k, l, i) = alpha_K(i - E_idx) end do - else ! Could be bubbles_euler! $:GPU_LOOP(parallelism='[seq]') @@ -1322,28 +1197,27 @@ contains do i = advxb, advxe FK_src_vf(j, k, l, i) = vel_K(dir_idx(1)) end do - end if - end do end do end do $:END_GPU_PARALLEL_LOOP() #endif + end subroutine s_convert_primitive_to_flux_variables - !> This subroutine computes partial densities and volume fractions + !> This subroutine computes partial densities and volume fractions subroutine s_compute_species_fraction(q_vf, k, l, r, alpha_rho_K, alpha_K) - $:GPU_ROUTINE(function_name='s_compute_species_fraction', & - & parallelism='[seq]', cray_noinline=True) + + $:GPU_ROUTINE(function_name='s_compute_species_fraction', parallelism='[seq]', cray_noinline=True) type(scalar_field), dimension(sys_size), intent(in) :: q_vf - integer, intent(in) :: k, l, r + integer, intent(in) :: k, l, r #:if not MFC_CASE_OPTIMIZATION and USING_AMD real(wp), dimension(3), intent(out) :: alpha_rho_K, alpha_K #:else real(wp), dimension(num_fluids), intent(out) :: alpha_rho_K, alpha_K #:endif - integer :: i + integer :: i real(wp) :: alpha_K_sum if (num_fluids == 1) then @@ -1386,8 +1260,7 @@ contains !> @brief Deallocates fluid property arrays and post-processing fields allocated during module initialization. impure subroutine s_finalize_variables_conversion_module() - ! Deallocating the density, the specific heat ratio function and the - ! liquid stiffness function + ! Deallocating the density, the specific heat ratio function and the liquid stiffness function #ifdef MFC_POST_PROCESS deallocate (rho_sf, gamma_sf, pi_inf_sf, qv_sf) #endif @@ -1409,6 +1282,7 @@ contains #ifndef MFC_PRE_PROCESS !> @brief Computes the speed of sound from thermodynamic state variables, supporting multiple equation-of-state models. subroutine s_compute_speed_of_sound(pres, rho, gamma, pi_inf, H, adv, vel_sum, c_c, c, qv) + $:GPU_ROUTINE(parallelism='[seq]') real(wp), intent(in) :: pres @@ -1419,13 +1293,11 @@ contains #:else real(wp), dimension(num_fluids), intent(in) :: adv #:endif - real(wp), intent(in) :: vel_sum - real(wp), intent(in) :: c_c + real(wp), intent(in) :: vel_sum + real(wp), intent(in) :: c_c real(wp), intent(out) :: c - - real(wp) :: blkmod1, blkmod2 - - integer :: q + real(wp) :: blkmod1, blkmod2 + integer :: q if (chemistry) then if (avg_state == 1 .and. abs(c_c) > verysmall) then @@ -1433,35 +1305,28 @@ contains else c = sqrt((1.0_wp + 1.0_wp/gamma)*pres/rho) end if - elseif (relativity) then + else if (relativity) then ! Only supports perfect gas for now c = sqrt((1._wp + 1._wp/gamma)*pres/rho/H) else if (alt_soundspeed) then - blkmod1 = ((gammas(1) + 1._wp)*pres + & - pi_infs(1))/gammas(1) - blkmod2 = ((gammas(2) + 1._wp)*pres + & - pi_infs(2))/gammas(2) + blkmod1 = ((gammas(1) + 1._wp)*pres + pi_infs(1))/gammas(1) + blkmod2 = ((gammas(2) + 1._wp)*pres + pi_infs(2))/gammas(2) c = (1._wp/(rho*(adv(1)/blkmod1 + adv(2)/blkmod2))) - elseif (model_eqns == 3) then + else if (model_eqns == 3) then c = 0._wp $:GPU_LOOP(parallelism='[seq]') do q = 1, num_fluids - c = c + adv(q)*gs_min(q)* & - (pres + pi_infs(q)/(gammas(q) + 1._wp)) + c = c + adv(q)*gs_min(q)*(pres + pi_infs(q)/(gammas(q) + 1._wp)) end do c = c/rho - elseif (((model_eqns == 4) .or. (model_eqns == 2 .and. bubbles_euler))) then + else if (((model_eqns == 4) .or. (model_eqns == 2 .and. bubbles_euler))) then ! Sound speed for bubble mixture to order O(\alpha) if (mpp_lim .and. (num_fluids > 1)) then - c = (1._wp/gamma + 1._wp)* & - (pres + pi_inf/(gamma + 1._wp))/rho + c = (1._wp/gamma + 1._wp)*(pres + pi_inf/(gamma + 1._wp))/rho else - c = & - (1._wp/gamma + 1._wp)* & - (pres + pi_inf/(gamma + 1._wp))/ & - (rho*(1._wp - adv(num_fluids))) + c = (1._wp/gamma + 1._wp)*(pres + pi_inf/(gamma + 1._wp))/(rho*(1._wp - adv(num_fluids))) end if else c = (H - 5.e-1*vel_sum - qv/rho)/gamma @@ -1473,21 +1338,21 @@ contains c = sqrt(c) end if end if + end subroutine s_compute_speed_of_sound #endif #ifndef MFC_PRE_PROCESS !> @brief Computes the fast magnetosonic wave speed from the sound speed, density, and magnetic field components. subroutine s_compute_fast_magnetosonic_speed(rho, c, B, norm, c_fast, h) - $:GPU_ROUTINE(function_name='s_compute_fast_magnetosonic_speed', & - & parallelism='[seq]', cray_noinline=True) - real(wp), intent(in) :: B(3), rho, c - real(wp), intent(in) :: h ! only used for relativity - real(wp), intent(out) :: c_fast - integer, intent(in) :: norm + $:GPU_ROUTINE(function_name='s_compute_fast_magnetosonic_speed', parallelism='[seq]', cray_noinline=True) - real(wp) :: B2, term, disc + real(wp), intent(in) :: B(3), rho, c + real(wp), intent(in) :: h ! only used for relativity + real(wp), intent(out) :: c_fast + integer, intent(in) :: norm + real(wp) :: B2, term, disc B2 = sum(B**2) @@ -1511,5 +1376,4 @@ contains end subroutine s_compute_fast_magnetosonic_speed #endif - end module m_variables_conversion diff --git a/src/post_process/m_checker.fpp b/src/post_process/m_checker.fpp index 13587887a8..6d01538edb 100644 --- a/src/post_process/m_checker.fpp +++ b/src/post_process/m_checker.fpp @@ -7,12 +7,9 @@ !> @brief Validates post-process input parameters and output format consistency module m_checker - use m_global_parameters !< Definitions of the global parameters - - use m_mpi_proxy !< Message passing interface (MPI) module proxy - - use m_helper_basic !< Functions to compare floating point numbers - + use m_global_parameters !< Definitions of the global parameters + use m_mpi_proxy !< Message passing interface (MPI) module proxy + use m_helper_basic !< Functions to compare floating point numbers use m_helper implicit none @@ -21,13 +18,14 @@ module m_checker contains - !> Checks compatibility of parameters in the input file. - !! Used by the post_process stage + !> Checks compatibility of parameters in the input file. Used by the post_process stage impure subroutine s_check_inputs + end subroutine s_check_inputs !> Checks constraints on fft_wrt impure subroutine s_check_inputs_fft + integer :: num_procs_y, num_procs_z @:PROHIBIT(fft_wrt .and. MOD(n_glb+1,n+1) /= 0, "FFT WRT requires n_glb to be divisible by num_procs_y") @@ -36,6 +34,7 @@ contains num_procs_z = (p_glb + 1)/(p + 1) @:PROHIBIT(fft_wrt .and. MOD(m_glb+1,num_procs_y) /= 0, "FFT WRT requires m_glb to be divisible by num_procs_y") @:PROHIBIT(fft_wrt .and. MOD(n_glb+1,num_procs_z) /= 0, "FFT WRT requires n_glb to be divisible by num_procs_z") + end subroutine s_check_inputs_fft end module m_checker diff --git a/src/post_process/m_data_input.f90 b/src/post_process/m_data_input.f90 index be1bdcb2d2..ef006ddeda 100644 --- a/src/post_process/m_data_input.f90 +++ b/src/post_process/m_data_input.f90 @@ -6,35 +6,26 @@ module m_data_input #ifdef MFC_MPI - use mpi !< Message passing interface (MPI) module + use mpi !< Message passing interface (MPI) module #endif - use m_derived_types !< Definitions of the derived types - - use m_global_parameters !< Global parameters for the code - - use m_mpi_proxy !< Message passing interface (MPI) module proxy - + use m_derived_types !< Definitions of the derived types + use m_global_parameters !< Global parameters for the code + use m_mpi_proxy !< Message passing interface (MPI) module proxy use m_mpi_common - use m_compile_specific - use m_boundary_common - use m_helper implicit none - private; public :: s_initialize_data_input_module, & - s_read_data_files, & - s_read_serial_data_files, & - s_read_parallel_data_files, & - s_finalize_data_input_module + private; public :: s_initialize_data_input_module, s_read_data_files, s_read_serial_data_files, s_read_parallel_data_files, & + & s_finalize_data_input_module abstract interface !> Subroutine for reading data files - !! @param t_step Current time-step to input + !! @param t_step Current time-step to input impure subroutine s_read_abstract_data_files(t_step) implicit none @@ -42,22 +33,13 @@ impure subroutine s_read_abstract_data_files(t_step) integer, intent(in) :: t_step end subroutine s_read_abstract_data_files - end interface - type(scalar_field), allocatable, dimension(:), public :: q_cons_vf !< - !! Conservative variables - - type(scalar_field), allocatable, dimension(:), public :: q_cons_temp - - type(scalar_field), allocatable, dimension(:), public :: q_prim_vf !< - !! Primitive variables - - type(integer_field), allocatable, dimension(:, :), public :: bc_type !< - !! Boundary condition identifiers - - type(scalar_field), public :: q_T_sf !< - !! Temperature field + type(scalar_field), allocatable, dimension(:), public :: q_cons_vf !< Conservative variables + type(scalar_field), allocatable, dimension(:), public :: q_cons_temp + type(scalar_field), allocatable, dimension(:), public :: q_prim_vf !< Primitive variables + type(integer_field), allocatable, dimension(:,:), public :: bc_type !< Boundary condition identifiers + type(scalar_field), public :: q_T_sf !< Temperature field ! type(scalar_field), public :: ib_markers !< type(integer_field), public :: ib_markers @@ -67,37 +49,35 @@ end subroutine s_read_abstract_data_files contains !> Helper subroutine to read grid data files for a given direction - !! @param t_step_dir Directory containing the time-step data - !! @param direction Direction name ('x', 'y', 'z') - !! @param cb_array Cell boundary array to populate - !! @param d_array Cell width array to populate - !! @param cc_array Cell center array to populate - !! @param size_dim Size of the dimension + !! @param t_step_dir Directory containing the time-step data + !! @param direction Direction name ('x', 'y', 'z') + !! @param cb_array Cell boundary array to populate + !! @param d_array Cell width array to populate + !! @param cc_array Cell center array to populate + !! @param size_dim Size of the dimension impure subroutine s_read_grid_data_direction(t_step_dir, direction, cb_array, d_array, cc_array, size_dim) - character(len=*), intent(in) :: t_step_dir - character(len=1), intent(in) :: direction - real(wp), dimension(-1:), intent(out) :: cb_array - real(wp), dimension(0:), intent(out) :: d_array - real(wp), dimension(0:), intent(out) :: cc_array - integer, intent(in) :: size_dim - + character(len=*), intent(in) :: t_step_dir + character(len=1), intent(in) :: direction + real(wp), dimension(-1:), intent(out) :: cb_array + real(wp), dimension(0:), intent(out) :: d_array + real(wp), dimension(0:), intent(out) :: cc_array + integer, intent(in) :: size_dim character(LEN=len_trim(t_step_dir) + 10) :: file_loc - logical :: file_check + logical :: file_check ! Checking whether direction_cb.dat exists - file_loc = trim(t_step_dir)//'/'//direction//'_cb.dat' + + file_loc = trim(t_step_dir) // '/' // direction // '_cb.dat' inquire (FILE=trim(file_loc), EXIST=file_check) ! Reading direction_cb.dat if it exists, exiting otherwise if (file_check) then - open (1, FILE=trim(file_loc), FORM='unformatted', & - STATUS='old', ACTION='read') + open (1, FILE=trim(file_loc), form='unformatted', STATUS='old', ACTION='read') read (1) cb_array(-1:size_dim) close (1) else - call s_mpi_abort('File '//direction//'_cb.dat is missing in '// & - trim(t_step_dir)//'. Exiting.') + call s_mpi_abort('File ' // direction // '_cb.dat is missing in ' // trim(t_step_dir) // '. Exiting.') end if ! Computing the cell-width distribution @@ -110,16 +90,17 @@ end subroutine s_read_grid_data_direction #ifdef MFC_MPI !> Helper subroutine to setup MPI data I/O parameters - !! @param data_size Local array size (output) - !! @param m_MOK, n_MOK, p_MOK MPI offset kinds for dimensions (output) - !! @param WP_MOK, MOK, str_MOK, NVARS_MOK Other MPI offset kinds (output) + !! @param data_size Local array size (output) + !! @param m_MOK, n_MOK, p_MOK MPI offset kinds for dimensions (output) + !! @param WP_MOK, MOK, str_MOK, NVARS_MOK Other MPI offset kinds (output) impure subroutine s_setup_mpi_io_params(data_size, m_MOK, n_MOK, p_MOK, WP_MOK, MOK, str_MOK, NVARS_MOK) - integer, intent(out) :: data_size + integer, intent(out) :: data_size integer(KIND=MPI_OFFSET_KIND), intent(out) :: m_MOK, n_MOK, p_MOK integer(KIND=MPI_OFFSET_KIND), intent(out) :: WP_MOK, MOK, str_MOK, NVARS_MOK ! Initialize MPI data I/O + if (ib) then call s_initialize_mpi_data(q_cons_vf, ib_markers) else @@ -142,29 +123,27 @@ end subroutine s_setup_mpi_io_params #endif !> Helper subroutine to read IB data files - !! @param file_loc_base Base file location for IB data - !! @param t_step Time step index + !! @param file_loc_base Base file location for IB data + !! @param t_step Time step index impure subroutine s_read_ib_data_files(file_loc_base, t_step) - character(len=*), intent(in) :: file_loc_base - integer, intent(in), optional :: t_step - + character(len=*), intent(in) :: file_loc_base + integer, intent(in), optional :: t_step character(LEN=len_trim(file_loc_base) + 20) :: file_loc - logical :: file_exist - integer :: ifile, ierr, data_size, var_MOK + logical :: file_exist + integer :: ifile, ierr, data_size, var_MOK #ifdef MFC_MPI integer, dimension(MPI_STATUS_SIZE) :: status - integer(KIND=MPI_OFFSET_KIND) :: disp - integer :: m_MOK, n_MOK, p_MOK, MOK, WP_MOK, save_index - + integer(KIND=MPI_OFFSET_KIND) :: disp + integer :: m_MOK, n_MOK, p_MOK, MOK, WP_MOK, save_index #endif if (.not. ib) return if (parallel_io) then - write (file_loc, '(A)') trim(file_loc_base)//'ib.dat' + write (file_loc, '(A)') trim(file_loc_base) // 'ib.dat' else - write (file_loc, '(A)') trim(file_loc_base)//'/ib_data.dat' + write (file_loc, '(A)') trim(file_loc_base) // '/ib_data.dat' end if inquire (FILE=trim(file_loc), EXIST=file_exist) @@ -178,7 +157,7 @@ impure subroutine s_read_ib_data_files(file_loc_base, t_step) p_MOK = int(p_glb + 1, MPI_OFFSET_KIND) MOK = int(1._wp, MPI_OFFSET_KIND) WP_MOK = int(storage_size(0._stp)/8, MPI_OFFSET_KIND) - save_index = t_step/t_step_save ! get the number of saves done to this point + save_index = t_step/t_step_save ! get the number of saves done to this point data_size = (m + 1)*(n + 1)*(p + 1) var_MOK = int(sys_size + 1, MPI_OFFSET_KIND) @@ -188,95 +167,77 @@ impure subroutine s_read_ib_data_files(file_loc_base, t_step) disp = m_MOK*max(MOK, n_MOK)*max(MOK, p_MOK)*WP_MOK*(var_MOK - 1 + int(save_index, MPI_OFFSET_KIND)) end if - call MPI_FILE_SET_VIEW(ifile, disp, MPI_INTEGER, MPI_IO_IB_DATA%view, & - 'native', mpi_info_int, ierr) - call MPI_FILE_READ(ifile, MPI_IO_IB_DATA%var%sf, data_size, & - MPI_INTEGER, status, ierr) + call MPI_FILE_SET_VIEW(ifile, disp, MPI_INTEGER, MPI_IO_IB_DATA%view, 'native', mpi_info_int, ierr) + call MPI_FILE_READ(ifile, MPI_IO_IB_DATA%var%sf, data_size, MPI_INTEGER, status, ierr) call MPI_FILE_CLOSE(ifile, ierr) #endif else - open (2, FILE=trim(file_loc), & - FORM='unformatted', & - ACTION='read', & - STATUS='old') - read (2) ib_markers%sf(0:m, 0:n, 0:p) + open (2, FILE=trim(file_loc), form='unformatted', ACTION='read', STATUS='old') + read (2) ib_markers%sf(0:m,0:n,0:p) close (2) end if else - call s_mpi_abort('File '//trim(file_loc)//' is missing. Exiting.') + call s_mpi_abort('File ' // trim(file_loc) // ' is missing. Exiting.') end if end subroutine s_read_ib_data_files !> Helper subroutine to allocate field arrays for given dimensionality - !! @param local_start_idx Starting index for allocation - !! @param end_x End index for x dimension - !! @param end_y End index for y dimension - !! @param end_z End index for z dimension + !! @param local_start_idx Starting index for allocation + !! @param end_x End index for x dimension + !! @param end_y End index for y dimension + !! @param end_z End index for z dimension impure subroutine s_allocate_field_arrays(local_start_idx, end_x, end_y, end_z) integer, intent(in) :: local_start_idx, end_x, end_y, end_z - integer :: i + integer :: i do i = 1, sys_size - allocate (q_cons_vf(i)%sf(local_start_idx:end_x, local_start_idx:end_y, local_start_idx:end_z)) - allocate (q_prim_vf(i)%sf(local_start_idx:end_x, local_start_idx:end_y, local_start_idx:end_z)) + allocate (q_cons_vf(i)%sf(local_start_idx:end_x,local_start_idx:end_y,local_start_idx:end_z)) + allocate (q_prim_vf(i)%sf(local_start_idx:end_x,local_start_idx:end_y,local_start_idx:end_z)) end do if (ib) then - allocate (ib_markers%sf(local_start_idx:end_x, local_start_idx:end_y, local_start_idx:end_z)) + allocate (ib_markers%sf(local_start_idx:end_x,local_start_idx:end_y,local_start_idx:end_z)) end if if (chemistry) then - allocate (q_T_sf%sf(local_start_idx:end_x, local_start_idx:end_y, local_start_idx:end_z)) + allocate (q_T_sf%sf(local_start_idx:end_x,local_start_idx:end_y,local_start_idx:end_z)) end if end subroutine s_allocate_field_arrays - !> This subroutine is called at each time-step that has to - !! be post-processed in order to read the raw data files - !! present in the corresponding time-step directory and to - !! populate the associated grid and conservative variables. - !! @param t_step Current time-step + !> This subroutine is called at each time-step that has to be post-processed in order to read the raw data files present in the + !! corresponding time-step directory and to populate the associated grid and conservative variables. + !! @param t_step Current time-step impure subroutine s_read_serial_data_files(t_step) - integer, intent(in) :: t_step - - character(LEN=len_trim(case_dir) + 2*name_len) :: t_step_dir !< - !! Location of the time-step directory associated with t_step - - character(LEN=len_trim(case_dir) + 3*name_len) :: file_loc !< - !! Generic string used to store the location of a particular file - - character(LEN= & - int(floor(log10(real(sys_size, wp)))) + 1) :: file_num !< - !! Used to store the variable position, in character form, of the - !! currently manipulated conservative variable file + integer, intent(in) :: t_step + character(LEN=len_trim(case_dir) + 2*name_len) :: t_step_dir !< Location of the time-step directory associated with t_step + character(LEN=len_trim(case_dir) + 3*name_len) :: file_loc !< Generic string used to store the location of a particular file - character(LEN=len_trim(case_dir) + 2*name_len) :: t_step_ib_dir !< - !! Location of the time-step directory associated with t_step + !> Used to store the variable position, in character form, of the currently manipulated conservative variable file + character(LEN=int(floor(log10(real(sys_size, wp)))) + 1) :: file_num - logical :: dir_check !< - !! Generic logical used to test the existence of a particular folder - - logical :: file_check !< - !! Generic logical used to test the existence of a particular file - - integer :: i !< Generic loop iterator + !> Location of the time-step directory associated with t_step + character(LEN=len_trim(case_dir) + 2*name_len) :: t_step_ib_dir + logical :: dir_check !< Generic logical used to test the existence of a particular folder + logical :: file_check !< Generic logical used to test the existence of a particular file + integer :: i !< Generic loop iterator ! Setting location of time-step folder based on current time-step + write (t_step_dir, '(A,I0,A,I0)') '/p_all/p', proc_rank, '/', t_step - t_step_dir = trim(case_dir)//trim(t_step_dir) + t_step_dir = trim(case_dir) // trim(t_step_dir) ! Inquiring as to the existence of the time-step directory - file_loc = trim(t_step_dir)//'/.' + file_loc = trim(t_step_dir) // '/.' call my_inquire(file_loc, dir_check) ! If the time-step directory is missing, the post-process exits. if (dir_check .neqv. .true.) then - call s_mpi_abort('Time-step folder '//trim(t_step_dir)// & - ' is missing. Exiting.') + call s_mpi_abort('Time-step folder ' // trim(t_step_dir) // ' is missing. Exiting.') end if if (bc_io) then @@ -298,30 +259,23 @@ impure subroutine s_read_serial_data_files(t_step) ! Reading the Conservative Variables Data Files do i = 1, sys_size - - ! Checking whether the data file associated with the variable - ! position of currently manipulated conservative variable exists + ! Checking whether the data file associated with the variable position of currently manipulated conservative variable + ! exists write (file_num, '(I0)') i - file_loc = trim(t_step_dir)//'/q_cons_vf'// & - trim(file_num)//'.dat' + file_loc = trim(t_step_dir) // '/q_cons_vf' // trim(file_num) // '.dat' inquire (FILE=trim(file_loc), EXIST=file_check) ! Reading the data file if it exists, exiting otherwise if (file_check) then - open (1, FILE=trim(file_loc), FORM='unformatted', & - STATUS='old', ACTION='read') - read (1) q_cons_vf(i)%sf(0:m, 0:n, 0:p) + open (1, FILE=trim(file_loc), form='unformatted', STATUS='old', ACTION='read') + read (1) q_cons_vf(i)%sf(0:m,0:n,0:p) close (1) else if (bubbles_lagrange .and. i == beta_idx) then - ! beta (Lagrangian void fraction) is not written by pre_process - ! for t_step_start; initialize to zero. - q_cons_vf(i)%sf(0:m, 0:n, 0:p) = 0._wp + ! beta (Lagrangian void fraction) is not written by pre_process for t_step_start; initialize to zero. + q_cons_vf(i)%sf(0:m,0:n,0:p) = 0._wp else - call s_mpi_abort('File q_cons_vf'//trim(file_num)// & - '.dat is missing in '//trim(t_step_dir)// & - '. Exiting.') + call s_mpi_abort('File q_cons_vf' // trim(file_num) // '.dat is missing in ' // trim(t_step_dir) // '. Exiting.') end if - end do ! Reading IB data using helper subroutine @@ -329,36 +283,28 @@ impure subroutine s_read_serial_data_files(t_step) end subroutine s_read_serial_data_files - !> This subroutine is called at each time-step that has to - !! be post-processed in order to parallel-read the raw data files - !! present in the corresponding time-step directory and to - !! populate the associated grid and conservative variables. - !! @param t_step Current time-step + !> This subroutine is called at each time-step that has to be post-processed in order to parallel-read the raw data files + !! present in the corresponding time-step directory and to populate the associated grid and conservative variables. + !! @param t_step Current time-step impure subroutine s_read_parallel_data_files(t_step) integer, intent(in) :: t_step #ifdef MFC_MPI - - real(wp), allocatable, dimension(:) :: x_cb_glb, y_cb_glb, z_cb_glb - - integer :: ifile, ierr, data_size, filetype, stride - integer, dimension(MPI_STATUS_SIZE) :: status - - integer(KIND=MPI_OFFSET_KIND) :: disp - integer(KIND=MPI_OFFSET_KIND) :: m_MOK, n_MOK, p_MOK - integer(KIND=MPI_OFFSET_KIND) :: WP_MOK, var_MOK, str_MOK - integer(KIND=MPI_OFFSET_KIND) :: NVARS_MOK - integer(KIND=MPI_OFFSET_KIND) :: MOK - integer(kind=MPI_OFFSET_KIND) :: offset - real(wp) :: delx, dely, delz - + real(wp), allocatable, dimension(:) :: x_cb_glb, y_cb_glb, z_cb_glb + integer :: ifile, ierr, data_size, filetype, stride + integer, dimension(MPI_STATUS_SIZE) :: status + integer(KIND=MPI_OFFSET_KIND) :: disp + integer(KIND=MPI_OFFSET_KIND) :: m_MOK, n_MOK, p_MOK + integer(KIND=MPI_OFFSET_KIND) :: WP_MOK, var_MOK, str_MOK + integer(KIND=MPI_OFFSET_KIND) :: NVARS_MOK + integer(KIND=MPI_OFFSET_KIND) :: MOK + integer(kind=MPI_OFFSET_KIND) :: offset + real(wp) :: delx, dely, delz character(LEN=path_len + 2*name_len) :: file_loc - logical :: file_exist - - character(len=10) :: t_step_string - - integer :: i + logical :: file_exist + character(len=10) :: t_step_string + integer :: i allocate (x_cb_glb(-1:m_glb)) allocate (y_cb_glb(-1:n_glb)) @@ -371,7 +317,7 @@ impure subroutine s_read_parallel_data_files(t_step) end if ! Read in cell boundary locations in x-direction - file_loc = trim(case_dir)//'/restart_data'//trim(mpiiofs)//'x_cb.dat' + file_loc = trim(case_dir) // '/restart_data' // trim(mpiiofs) // 'x_cb.dat' inquire (FILE=trim(file_loc), EXIST=file_exist) if (file_exist) then @@ -387,7 +333,7 @@ impure subroutine s_read_parallel_data_files(t_step) call MPI_FILE_READ(ifile, x_cb_glb, data_size, mpi_p, status, ierr) call MPI_FILE_CLOSE(ifile, ierr) else - call s_mpi_abort('File '//trim(file_loc)//' is missing. Exiting.') + call s_mpi_abort('File ' // trim(file_loc) // ' is missing. Exiting.') end if ! Assigning local cell boundary locations @@ -399,7 +345,7 @@ impure subroutine s_read_parallel_data_files(t_step) if (n > 0) then ! Read in cell boundary locations in y-direction - file_loc = trim(case_dir)//'/restart_data'//trim(mpiiofs)//'y_cb.dat' + file_loc = trim(case_dir) // '/restart_data' // trim(mpiiofs) // 'y_cb.dat' inquire (FILE=trim(file_loc), EXIST=file_exist) if (file_exist) then @@ -415,7 +361,7 @@ impure subroutine s_read_parallel_data_files(t_step) call MPI_FILE_READ(ifile, y_cb_glb, data_size, mpi_p, status, ierr) call MPI_FILE_CLOSE(ifile, ierr) else - call s_mpi_abort('File '//trim(file_loc)//' is missing. Exiting.') + call s_mpi_abort('File ' // trim(file_loc) // ' is missing. Exiting.') end if ! Assigning local cell boundary locations @@ -427,7 +373,7 @@ impure subroutine s_read_parallel_data_files(t_step) if (p > 0) then ! Read in cell boundary locations in z-direction - file_loc = trim(case_dir)//'/restart_data'//trim(mpiiofs)//'z_cb.dat' + file_loc = trim(case_dir) // '/restart_data' // trim(mpiiofs) // 'z_cb.dat' inquire (FILE=trim(file_loc), EXIST=file_exist) if (file_exist) then @@ -443,7 +389,7 @@ impure subroutine s_read_parallel_data_files(t_step) call MPI_FILE_READ(ifile, z_cb_glb, data_size, mpi_p, status, ierr) call MPI_FILE_CLOSE(ifile, ierr) else - call s_mpi_abort('File '//trim(file_loc)//' is missing. Exiting.') + call s_mpi_abort('File ' // trim(file_loc) // ' is missing. Exiting.') end if ! Assigning local cell boundary locations @@ -464,35 +410,33 @@ impure subroutine s_read_parallel_data_files(t_step) else call s_assign_default_bc_type(bc_type) end if - #endif end subroutine s_read_parallel_data_files #ifdef MFC_MPI !> Helper subroutine to read parallel conservative variable data - !! @param t_step Current time-step - !! @param m_MOK, n_MOK, p_MOK MPI offset kinds for dimensions - !! @param WP_MOK, MOK, str_MOK, NVARS_MOK Other MPI offset kinds + !! @param t_step Current time-step + !! @param m_MOK, n_MOK, p_MOK MPI offset kinds for dimensions + !! @param WP_MOK, MOK, str_MOK, NVARS_MOK Other MPI offset kinds impure subroutine s_read_parallel_conservative_data(t_step, m_MOK, n_MOK, p_MOK, WP_MOK, MOK, str_MOK, NVARS_MOK) - integer, intent(in) :: t_step + integer, intent(in) :: t_step integer(KIND=MPI_OFFSET_KIND), intent(inout) :: m_MOK, n_MOK, p_MOK integer(KIND=MPI_OFFSET_KIND), intent(inout) :: WP_MOK, MOK, str_MOK, NVARS_MOK - - integer :: ifile, ierr, data_size - integer, dimension(MPI_STATUS_SIZE) :: status - integer(KIND=MPI_OFFSET_KIND) :: disp, var_MOK - character(LEN=path_len + 2*name_len) :: file_loc - logical :: file_exist - character(len=10) :: t_step_string - integer :: i + integer :: ifile, ierr, data_size + integer, dimension(MPI_STATUS_SIZE) :: status + integer(KIND=MPI_OFFSET_KIND) :: disp, var_MOK + character(LEN=path_len + 2*name_len) :: file_loc + logical :: file_exist + character(len=10) :: t_step_string + integer :: i if (file_per_process) then call s_int_to_str(t_step, t_step_string) ! Open the file to read conservative variables write (file_loc, '(I0,A1,I7.7,A)') t_step, '_', proc_rank, '.dat' - file_loc = trim(case_dir)//'/restart_data/lustre_'//trim(t_step_string)//trim(mpiiofs)//trim(file_loc) + file_loc = trim(case_dir) // '/restart_data/lustre_' // trim(t_step_string) // trim(mpiiofs) // trim(file_loc) inquire (FILE=trim(file_loc), EXIST=file_exist) if (file_exist) then @@ -530,14 +474,12 @@ impure subroutine s_read_parallel_conservative_data(t_step, m_MOK, n_MOK, p_MOK, if (bubbles_euler .or. elasticity .or. mhd) then do i = 1, sys_size var_MOK = int(i, MPI_OFFSET_KIND) - call MPI_FILE_READ_ALL(ifile, MPI_IO_DATA%var(i)%sf, data_size*mpi_io_type, & - mpi_io_p, status, ierr) + call MPI_FILE_READ_ALL(ifile, MPI_IO_DATA%var(i)%sf, data_size*mpi_io_type, mpi_io_p, status, ierr) end do else do i = 1, sys_size var_MOK = int(i, MPI_OFFSET_KIND) - call MPI_FILE_READ_ALL(ifile, MPI_IO_DATA%var(i)%sf, data_size*mpi_io_type, & - mpi_io_p, status, ierr) + call MPI_FILE_READ_ALL(ifile, MPI_IO_DATA%var(i)%sf, data_size*mpi_io_type, mpi_io_p, status, ierr) end do end if @@ -546,18 +488,18 @@ impure subroutine s_read_parallel_conservative_data(t_step, m_MOK, n_MOK, p_MOK, if (down_sample) then do i = 1, sys_size - q_cons_vf(i)%sf(0:m, 0:n, 0:p) = q_cons_temp(i)%sf(0:m, 0:n, 0:p) + q_cons_vf(i)%sf(0:m,0:n,0:p) = q_cons_temp(i)%sf(0:m,0:n,0:p) end do end if - call s_read_ib_data_files(trim(case_dir)//'/restart_data'//trim(mpiiofs), t_step) + call s_read_ib_data_files(trim(case_dir) // '/restart_data' // trim(mpiiofs), t_step) else - call s_mpi_abort('File '//trim(file_loc)//' is missing. Exiting.') + call s_mpi_abort('File ' // trim(file_loc) // ' is missing. Exiting.') end if else ! Open the file to read conservative variables write (file_loc, '(I0,A)') t_step, '.dat' - file_loc = trim(case_dir)//'/restart_data'//trim(mpiiofs)//trim(file_loc) + file_loc = trim(case_dir) // '/restart_data' // trim(mpiiofs) // trim(file_loc) inquire (FILE=trim(file_loc), EXIST=file_exist) if (file_exist) then @@ -572,39 +514,36 @@ impure subroutine s_read_parallel_conservative_data(t_step, m_MOK, n_MOK, p_MOK, ! Initial displacement to skip at beginning of file disp = m_MOK*max(MOK, n_MOK)*max(MOK, p_MOK)*WP_MOK*(var_MOK - 1) - call MPI_FILE_SET_VIEW(ifile, disp, mpi_p, MPI_IO_DATA%view(i), & - 'native', mpi_info_int, ierr) - call MPI_FILE_READ_ALL(ifile, MPI_IO_DATA%var(i)%sf, data_size*mpi_io_type, & - mpi_io_p, status, ierr) + call MPI_FILE_SET_VIEW(ifile, disp, mpi_p, MPI_IO_DATA%view(i), 'native', mpi_info_int, ierr) + call MPI_FILE_READ_ALL(ifile, MPI_IO_DATA%var(i)%sf, data_size*mpi_io_type, mpi_io_p, status, ierr) end do call s_mpi_barrier() call MPI_FILE_CLOSE(ifile, ierr) - call s_read_ib_data_files(trim(case_dir)//'/restart_data'//trim(mpiiofs), t_step) + call s_read_ib_data_files(trim(case_dir) // '/restart_data' // trim(mpiiofs), t_step) else - call s_mpi_abort('File '//trim(file_loc)//' is missing. Exiting.') + call s_mpi_abort('File ' // trim(file_loc) // ' is missing. Exiting.') end if end if + end subroutine s_read_parallel_conservative_data #endif - !> Computation of parameters, allocation procedures, and/or - !! any other tasks needed to properly setup the module + !> Computation of parameters, allocation procedures, and/or any other tasks needed to properly setup the module impure subroutine s_initialize_data_input_module - integer :: i !< Generic loop iterator + integer :: i !< Generic loop iterator + + ! Allocating the parts of the conservative and primitive variables that do not require the direct knowledge of the + ! dimensionality of the simulation - ! Allocating the parts of the conservative and primitive variables - ! that do not require the direct knowledge of the dimensionality of - ! the simulation allocate (q_cons_vf(1:sys_size)) allocate (q_prim_vf(1:sys_size)) allocate (q_cons_temp(1:sys_size)) - ! Allocating the parts of the conservative and primitive variables - ! that do require the direct knowledge of the dimensionality of - ! the simulation using helper subroutine + ! Allocating the parts of the conservative and primitive variables that do require the direct knowledge of the + ! dimensionality of the simulation using helper subroutine ! Simulation is at least 2D if (n > 0) then @@ -613,7 +552,7 @@ impure subroutine s_initialize_data_input_module call s_allocate_field_arrays(-buff_size, m + buff_size, n + buff_size, p + buff_size) if (down_sample) then do i = 1, sys_size - allocate (q_cons_temp(i)%sf(-1:m + 1, -1:n + 1, -1:p + 1)) + allocate (q_cons_temp(i)%sf(-1:m + 1,-1:n + 1,-1:p + 1)) end do end if else @@ -626,16 +565,16 @@ impure subroutine s_initialize_data_input_module end if ! Allocating arrays to store the bc types - allocate (bc_type(1:num_dims, 1:2)) + allocate (bc_type(1:num_dims,1:2)) - allocate (bc_type(1, 1)%sf(0:0, 0:n, 0:p)) - allocate (bc_type(1, 2)%sf(0:0, 0:n, 0:p)) + allocate (bc_type(1, 1)%sf(0:0,0:n,0:p)) + allocate (bc_type(1, 2)%sf(0:0,0:n,0:p)) if (n > 0) then - allocate (bc_type(2, 1)%sf(-buff_size:m + buff_size, 0:0, 0:p)) - allocate (bc_type(2, 2)%sf(-buff_size:m + buff_size, 0:0, 0:p)) + allocate (bc_type(2, 1)%sf(-buff_size:m + buff_size,0:0,0:p)) + allocate (bc_type(2, 2)%sf(-buff_size:m + buff_size,0:0,0:p)) if (p > 0) then - allocate (bc_type(3, 1)%sf(-buff_size:m + buff_size, -buff_size:n + buff_size, 0:0)) - allocate (bc_type(3, 2)%sf(-buff_size:m + buff_size, -buff_size:n + buff_size, 0:0)) + allocate (bc_type(3, 1)%sf(-buff_size:m + buff_size,-buff_size:n + buff_size,0:0)) + allocate (bc_type(3, 2)%sf(-buff_size:m + buff_size,-buff_size:n + buff_size,0:0)) end if end if @@ -650,9 +589,10 @@ end subroutine s_initialize_data_input_module !> Deallocation procedures for the module impure subroutine s_finalize_data_input_module - integer :: i !< Generic loop iterator + integer :: i !< Generic loop iterator ! Deallocating the conservative and primitive variables + do i = 1, sys_size deallocate (q_cons_vf(i)%sf) deallocate (q_prim_vf(i)%sf) diff --git a/src/post_process/m_data_output.fpp b/src/post_process/m_data_output.fpp index 3251b3ac3b..166fd67f5a 100644 --- a/src/post_process/m_data_output.fpp +++ b/src/post_process/m_data_output.fpp @@ -5,187 +5,145 @@ !> @brief Writes post-processed grid and flow-variable data to Silo-HDF5 or binary database files module m_data_output - use m_derived_types ! Definitions of the derived types - - use m_global_parameters ! Global parameters - - use m_derived_variables !< Procedures used to compute quantities derived - - use m_mpi_proxy ! Message passing interface (MPI) module proxy - + use m_derived_types ! Definitions of the derived types + use m_global_parameters ! Global parameters + use m_derived_variables !< Procedures used to compute quantities derived + use m_mpi_proxy ! Message passing interface (MPI) module proxy use m_compile_specific - use m_helper - use m_variables_conversion implicit none - private; public :: s_initialize_data_output_module, & - s_define_output_region, & - s_open_formatted_database_file, & - s_open_intf_data_file, & - s_open_energy_data_file, & - s_write_grid_to_formatted_database_file, & - s_write_variable_to_formatted_database_file, & - s_write_lag_bubbles_results_to_text, & - s_write_lag_bubbles_to_formatted_database_file, & - s_write_ib_state_files, & - s_write_intf_data_file, & - s_write_energy_data_file, & - s_close_formatted_database_file, & - s_close_intf_data_file, & - s_close_energy_data_file, & - s_finalize_data_output_module - - ! Including the Silo Fortran interface library that features the subroutines - ! and parameters that are required to write in the Silo-HDF5 database format - ! INCLUDE 'silo.inc' + private; public :: s_initialize_data_output_module, s_define_output_region, s_open_formatted_database_file, & + & s_open_intf_data_file, s_open_energy_data_file, s_write_grid_to_formatted_database_file, & + & s_write_variable_to_formatted_database_file, s_write_lag_bubbles_results_to_text, & + & s_write_lag_bubbles_to_formatted_database_file, s_write_ib_state_files, s_write_intf_data_file, & + & s_write_energy_data_file, s_close_formatted_database_file, s_close_intf_data_file, s_close_energy_data_file, & + & s_finalize_data_output_module + + ! Including the Silo Fortran interface library that features the subroutines and parameters that are required to write in the + ! Silo-HDF5 database format INCLUDE 'silo.inc' include 'silo_f9x.inc' - ! Generic storage for flow variable(s) that are to be written to formatted - ! database file(s). Note that for 1D simulations, q_root_sf is employed to - ! gather the flow variable(s) from all sub-domains on to the root process. - ! If the run is not parallel, but serial, then q_root_sf is equal to q_sf. - real(wp), allocatable, dimension(:, :, :), public :: q_sf - real(wp), allocatable, dimension(:, :, :) :: q_root_sf - real(wp), allocatable, dimension(:, :, :) :: cyl_q_sf + ! Generic storage for flow variable(s) that are to be written to formatted database file(s). Note that for 1D simulations, + ! q_root_sf is employed to gather the flow variable(s) from all sub-domains on to the root process. If the run is not parallel, + ! but serial, then q_root_sf is equal to q_sf. + real(wp), allocatable, dimension(:,:,:), public :: q_sf + real(wp), allocatable, dimension(:,:,:) :: q_root_sf + real(wp), allocatable, dimension(:,:,:) :: cyl_q_sf ! Single precision storage for flow variables - real(sp), allocatable, dimension(:, :, :), public :: q_sf_s - real(sp), allocatable, dimension(:, :, :) :: q_root_sf_s - real(sp), allocatable, dimension(:, :, :) :: cyl_q_sf_s - - ! The spatial and data extents array variables contain information about the - ! minimum and maximum values of the grid and flow variable(s), respectively. - ! The purpose of bookkeeping this information is to boost the visualization - ! of the Silo-HDF5 database file(s) in VisIt. - real(wp), allocatable, dimension(:, :) :: spatial_extents - real(wp), allocatable, dimension(:, :) :: data_extents - - ! The size of the ghost zone layer at beginning of each coordinate direction - ! (lo) and at end of each coordinate direction (hi). Adding this information - ! to Silo-HDF5 database file(s) is recommended since it supplies VisIt with - ! connectivity information between the sub-domains of a parallel data set. + real(sp), allocatable, dimension(:,:,:), public :: q_sf_s + real(sp), allocatable, dimension(:,:,:) :: q_root_sf_s + real(sp), allocatable, dimension(:,:,:) :: cyl_q_sf_s + + ! The spatial and data extents array variables contain information about the minimum and maximum values of the grid and flow + ! variable(s), respectively. The purpose of bookkeeping this information is to boost the visualization of the Silo-HDF5 database + ! file(s) in VisIt. + real(wp), allocatable, dimension(:,:) :: spatial_extents + real(wp), allocatable, dimension(:,:) :: data_extents + + ! The size of the ghost zone layer at beginning of each coordinate direction (lo) and at end of each coordinate direction (hi). + ! Adding this information to Silo-HDF5 database file(s) is recommended since it supplies VisIt with connectivity information + ! between the sub-domains of a parallel data set. integer, allocatable, dimension(:) :: lo_offset integer, allocatable, dimension(:) :: hi_offset - ! For Silo-HDF5 database format, this variable is used to keep track of the - ! number of cell-boundaries, for the grid associated with the local process, - ! in each of the active coordinate directions. + ! For Silo-HDF5 database format, this variable is used to keep track of the number of cell-boundaries, for the grid associated + ! with the local process, in each of the active coordinate directions. integer, allocatable, dimension(:) :: dims - ! Locations of various folders in the case's directory tree, associated with - ! the choice of the formatted database format. These include, in order, the - ! location of the folder named after the selected formatted database format, - ! and the locations of two sub-directories of the latter, the first of which - ! is named after the local processor rank, while the second is named 'root'. - ! The folder associated with the local processor rank contains only the data - ! pertaining to the part of the domain taken care of by the local processor. - ! The root directory, on the other hand, will contain either the information - ! about the connectivity required to put the entire domain back together, or - ! the actual data associated with the entire computational domain. This all + ! Locations of various folders in the case's directory tree, associated with the choice of the formatted database format. These + ! include, in order, the location of the folder named after the selected formatted database format, and the locations of two + ! sub-directories of the latter, the first of which is named after the local processor rank, while the second is named 'root'. + ! The folder associated with the local processor rank contains only the data pertaining to the part of the domain taken care of + ! by the local processor. The root directory, on the other hand, will contain either the information about the connectivity + ! required to put the entire domain back together, or the actual data associated with the entire computational domain. This all ! depends on dimensionality and the choice of the formatted database format. - character(LEN=path_len + name_len) :: dbdir + character(LEN=path_len + name_len) :: dbdir character(LEN=path_len + 2*name_len) :: proc_rank_dir character(LEN=path_len + 2*name_len) :: rootdir - ! Handles of the formatted database master/root file, slave/local processor - ! file and options list. The list of options is explicitly used in the Silo- - ! HDF5 database format to provide additional details about the contents of a - ! formatted database file, such as the previously described spatial and data - ! extents. + ! Handles of the formatted database master/root file, slave/local processor file and options list. The list of options is + ! explicitly used in the Silo- HDF5 database format to provide additional details about the contents of a formatted database + ! file, such as the previously described spatial and data extents. integer :: dbroot integer :: dbfile integer :: optlist - ! The total number of flow variable(s) to be stored in a formatted database - ! file. Note that this is only needed when using the Binary format. + ! The total number of flow variable(s) to be stored in a formatted database file. Note that this is only needed when using the + ! Binary format. integer :: dbvars - ! Generic error flags utilized in the handling, checking and the reporting - ! of the input and output operations errors with a formatted database file + ! Generic error flags utilized in the handling, checking and the reporting of the input and output operations errors with a + ! formatted database file integer, private :: err contains !> @brief Allocate storage arrays, configure output directories, and count flow variables for formatted database output. impure subroutine s_initialize_data_output_module() - ! Description: Computation of parameters, allocation procedures, and/or - ! any other tasks needed to properly setup the module + + ! Description: Computation of parameters, allocation procedures, and/or any other tasks needed to properly setup the module ! Generic string used to store the location of a particular file character(LEN=len_trim(case_dir) + 2*name_len) :: file_loc ! Generic logical used to test the existence of a particular folder logical :: dir_check - integer :: i - ! Allocating the generic storage for the flow variable(s) that are - ! going to be written to the formatted database file(s). Note once - ! more that the root variable is only required for 1D computations. - allocate (q_sf(-offset_x%beg:m + offset_x%end, & - -offset_y%beg:n + offset_y%end, & - -offset_z%beg:p + offset_z%end)) + ! Allocating the generic storage for the flow variable(s) that are going to be written to the formatted database file(s). + ! Note once more that the root variable is only required for 1D computations. + + allocate (q_sf(-offset_x%beg:m + offset_x%end,-offset_y%beg:n + offset_y%end,-offset_z%beg:p + offset_z%end)) if (grid_geometry == 3) then - allocate (cyl_q_sf(-offset_y%beg:n + offset_y%end, & - -offset_z%beg:p + offset_z%end, & - -offset_x%beg:m + offset_x%end)) + allocate (cyl_q_sf(-offset_y%beg:n + offset_y%end,-offset_z%beg:p + offset_z%end,-offset_x%beg:m + offset_x%end)) end if if (precision == 1) then - allocate (q_sf_s(-offset_x%beg:m + offset_x%end, & - -offset_y%beg:n + offset_y%end, & - -offset_z%beg:p + offset_z%end)) + allocate (q_sf_s(-offset_x%beg:m + offset_x%end,-offset_y%beg:n + offset_y%end,-offset_z%beg:p + offset_z%end)) if (grid_geometry == 3) then - allocate (cyl_q_sf_s(-offset_y%beg:n + offset_y%end, & - -offset_z%beg:p + offset_z%end, & - -offset_x%beg:m + offset_x%end)) + allocate (cyl_q_sf_s(-offset_y%beg:n + offset_y%end,-offset_z%beg:p + offset_z%end,-offset_x%beg:m + offset_x%end)) end if end if if (n == 0) then - allocate (q_root_sf(0:m_root, 0:0, 0:0)) + allocate (q_root_sf(0:m_root,0:0,0:0)) if (precision == 1) then - allocate (q_root_sf_s(0:m_root, 0:0, 0:0)) + allocate (q_root_sf_s(0:m_root,0:0,0:0)) end if end if - ! Allocating the spatial and data extents and also the variables for - ! the offsets and the one bookkeeping the number of cell-boundaries - ! in each active coordinate direction. Note that all these variables - ! are only needed by the Silo-HDF5 format for multidimensional data. + ! Allocating the spatial and data extents and also the variables for the offsets and the one bookkeeping the number of + ! cell-boundaries in each active coordinate direction. Note that all these variables are only needed by the Silo-HDF5 format + ! for multidimensional data. if (format == 1) then - - allocate (data_extents(1:2, 0:num_procs - 1)) + allocate (data_extents(1:2,0:num_procs - 1)) if (p > 0) then - allocate (spatial_extents(1:6, 0:num_procs - 1)) + allocate (spatial_extents(1:6,0:num_procs - 1)) allocate (lo_offset(1:3)) allocate (hi_offset(1:3)) allocate (dims(1:3)) - elseif (n > 0) then - allocate (spatial_extents(1:4, 0:num_procs - 1)) + else if (n > 0) then + allocate (spatial_extents(1:4,0:num_procs - 1)) allocate (lo_offset(1:2)) allocate (hi_offset(1:2)) allocate (dims(1:2)) else - allocate (spatial_extents(1:2, 0:num_procs - 1)) + allocate (spatial_extents(1:2,0:num_procs - 1)) allocate (lo_offset(1:1)) allocate (hi_offset(1:1)) allocate (dims(1:1)) end if - end if - ! The size of the ghost zone layer in each of the active coordinate - ! directions was set in the module m_mpi_proxy.f90. The results are - ! now transferred to the local variables of this module when they are - ! required by the Silo-HDF5 format, for multidimensional data sets. - ! With the same, latter, requirements, the variables bookkeeping the - ! number of cell-boundaries in each active coordinate direction are - ! also set here. + ! The size of the ghost zone layer in each of the active coordinate directions was set in the module m_mpi_proxy.f90. The + ! results are now transferred to the local variables of this module when they are required by the Silo-HDF5 format, for + ! multidimensional data sets. With the same, latter, requirements, the variables bookkeeping the number of cell-boundaries + ! in each active coordinate direction are also set here. if (format == 1) then if (p > 0) then if (grid_geometry == 3) then @@ -197,20 +155,17 @@ contains end if if (grid_geometry == 3) then - dims(:) = (/n + offset_y%beg + offset_y%end + 2, & - p + offset_z%beg + offset_z%end + 2, & - m + offset_x%beg + offset_x%end + 2/) + dims(:) = (/n + offset_y%beg + offset_y%end + 2, p + offset_z%beg + offset_z%end + 2, & + & m + offset_x%beg + offset_x%end + 2/) else - dims(:) = (/m + offset_x%beg + offset_x%end + 2, & - n + offset_y%beg + offset_y%end + 2, & - p + offset_z%beg + offset_z%end + 2/) + dims(:) = (/m + offset_x%beg + offset_x%end + 2, n + offset_y%beg + offset_y%end + 2, & + & p + offset_z%beg + offset_z%end + 2/) end if - elseif (n > 0) then + else if (n > 0) then lo_offset(:) = (/offset_x%beg, offset_y%beg/) hi_offset(:) = (/offset_x%end, offset_y%end/) - dims(:) = (/m + offset_x%beg + offset_x%end + 2, & - n + offset_y%beg + offset_y%end + 2/) + dims(:) = (/m + offset_x%beg + offset_x%end + 2, n + offset_y%beg + offset_y%end + 2/) else lo_offset(:) = (/offset_x%beg/) hi_offset(:) = (/offset_x%end/) @@ -220,15 +175,14 @@ contains ! Generating Silo-HDF5 Directory Tree if (format == 1) then - ! Creating the directory associated with the local process - dbdir = trim(case_dir)//'/silo_hdf5' + dbdir = trim(case_dir) // '/silo_hdf5' write (proc_rank_dir, '(A,I0)') '/p', proc_rank - proc_rank_dir = trim(dbdir)//trim(proc_rank_dir) + proc_rank_dir = trim(dbdir) // trim(proc_rank_dir) - file_loc = trim(proc_rank_dir)//'/.' + file_loc = trim(proc_rank_dir) // '/.' call my_inquire(file_loc, dir_check) if (dir_check .neqv. .true.) then @@ -237,30 +191,26 @@ contains ! Creating the directory associated with the root process if (proc_rank == 0) then + rootdir = trim(dbdir) // '/root' - rootdir = trim(dbdir)//'/root' - - file_loc = trim(rootdir)//'/.' + file_loc = trim(rootdir) // '/.' call my_inquire(file_loc, dir_check) if (dir_check .neqv. .true.) then call s_create_directory(trim(rootdir)) end if - end if ! Generating Binary Directory Tree - else - ! Creating the directory associated with the local process - dbdir = trim(case_dir)//'/binary' + dbdir = trim(case_dir) // '/binary' write (proc_rank_dir, '(A,I0)') '/p', proc_rank - proc_rank_dir = trim(dbdir)//trim(proc_rank_dir) + proc_rank_dir = trim(dbdir) // trim(proc_rank_dir) - file_loc = trim(proc_rank_dir)//'/.' + file_loc = trim(proc_rank_dir) // '/.' call my_inquire(file_loc, dir_check) @@ -270,25 +220,22 @@ contains ! Creating the directory associated with the root process if (n == 0 .and. proc_rank == 0) then + rootdir = trim(dbdir) // '/root' - rootdir = trim(dbdir)//'/root' - - file_loc = trim(rootdir)//'/.' + file_loc = trim(rootdir) // '/.' call my_inquire(file_loc, dir_check) if (dir_check .neqv. .true.) then call s_create_directory(trim(rootdir)) end if - end if - end if - if (bubbles_lagrange) then !Lagrangian solver + if (bubbles_lagrange) then ! Lagrangian solver if (lag_txt_wrt) then - dbdir = trim(case_dir)//'/lag_bubbles_post_process' - file_loc = trim(dbdir)//'/.' + dbdir = trim(case_dir) // '/lag_bubbles_post_process' + file_loc = trim(dbdir) // '/.' call my_inquire(file_loc, dir_check) if (dir_check .neqv. .true.) then @@ -297,10 +244,9 @@ contains end if end if - ! Contrary to the Silo-HDF5 database format, handles of the Binary - ! database master/root and slave/local process files are perfectly - ! static throughout post-process. Hence, they are set here so that - ! they do not have to be repetitively computed in later procedures. + ! Contrary to the Silo-HDF5 database format, handles of the Binary database master/root and slave/local process files are + ! perfectly static throughout post-process. Hence, they are set here so that they do not have to be repetitively computed in + ! later procedures. if (format == 2) then if (n == 0 .and. proc_rank == 0) dbroot = 2 dbfile = 1 @@ -309,25 +255,20 @@ contains ! Querying Number of Flow Variable(s) in Binary Output if (format == 2) then - - ! Initializing the counter of the number of flow variable(s) to - ! be written to the formatted database file(s) + ! Initializing the counter of the number of flow variable(s) to be written to the formatted database file(s) dbvars = 0 ! Partial densities if ((model_eqns == 2) .or. (model_eqns == 3)) then do i = 1, num_fluids - if (alpha_rho_wrt(i) & - .or. & - (cons_vars_wrt .or. prim_vars_wrt)) then + if (alpha_rho_wrt(i) .or. (cons_vars_wrt .or. prim_vars_wrt)) then dbvars = dbvars + 1 end if end do end if ! Density - if ((rho_wrt .or. (model_eqns == 1 .and. (cons_vars_wrt .or. prim_vars_wrt))) & - .and. (.not. relativity)) then + if ((rho_wrt .or. (model_eqns == 1 .and. (cons_vars_wrt .or. prim_vars_wrt))) .and. (.not. relativity)) then dbvars = dbvars + 1 end if @@ -375,29 +316,19 @@ contains ! Volume fraction(s) if ((model_eqns == 2) .or. (model_eqns == 3)) then - do i = 1, num_fluids - 1 - if (alpha_wrt(i) & - .or. & - (cons_vars_wrt .or. prim_vars_wrt)) then + if (alpha_wrt(i) .or. (cons_vars_wrt .or. prim_vars_wrt)) then dbvars = dbvars + 1 end if end do - if (alpha_wrt(num_fluids) & - .or. & - (cons_vars_wrt .or. prim_vars_wrt)) & - then + if (alpha_wrt(num_fluids) .or. (cons_vars_wrt .or. prim_vars_wrt)) then dbvars = dbvars + 1 end if - end if ! Specific heat ratio function - if (gamma_wrt & - .or. & - (model_eqns == 1 .and. (cons_vars_wrt .or. prim_vars_wrt))) & - then + if (gamma_wrt .or. (model_eqns == 1 .and. (cons_vars_wrt .or. prim_vars_wrt))) then dbvars = dbvars + 1 end if @@ -405,10 +336,7 @@ contains if (heat_ratio_wrt) dbvars = dbvars + 1 ! Liquid stiffness function - if (pi_inf_wrt & - .or. & - (model_eqns == 1 .and. (cons_vars_wrt .or. prim_vars_wrt))) & - then + if (pi_inf_wrt .or. (model_eqns == 1 .and. (cons_vars_wrt .or. prim_vars_wrt))) then dbvars = dbvars + 1 end if @@ -423,7 +351,7 @@ contains do i = 1, num_vels if (omega_wrt(i)) dbvars = dbvars + 1 end do - elseif (n > 0) then + else if (n > 0) then do i = 1, num_vels if (omega_wrt(i)) dbvars = dbvars + 1 end do @@ -431,7 +359,6 @@ contains ! Numerical Schlieren function if (schlieren_wrt) dbvars = dbvars + 1 - end if ! END: Querying Number of Flow Variable(s) in Binary Output @@ -445,11 +372,10 @@ contains integer :: lower_bound, upper_bound #:for X, M in [('x', 'm'), ('y', 'n'), ('z', 'p')] - - if (${M}$ == 0) return ! Early return for y or z if simulation is 1D or 2D + if (${M}$ == 0) return ! Early return for y or z if simulation is 1D or 2D lower_bound = -offset_${X}$%beg - upper_bound = ${M}$+offset_${X}$%end + upper_bound = ${M}$ + offset_${X}$%end do i = lower_bound, upper_bound if (${X}$_cc(i) > ${X}$_output%beg) then @@ -470,126 +396,94 @@ contains ${X}$_output_idx%beg = 0 ${X}$_output_idx%end = 0 end if - #:endfor end subroutine s_define_output_region !> @brief Open (or create) the Silo-HDF5 or Binary formatted database slave and master files for a given time step. impure subroutine s_open_formatted_database_file(t_step) - ! Description: This subroutine opens a new formatted database file, or - ! replaces an old one, and readies it for the data storage - ! of the grid and the flow variable(s) associated with the - ! current time-step, t_step. This is performed by all the - ! local process(es). The root processor, in addition, must - ! also generate a master formatted database file whose job - ! will be to link, and thus combine, the data from all of - ! the local process(es). Note that for the Binary format, - ! this extra task that is assigned to the root process is - ! not performed in multidimensions. + + ! Description: This subroutine opens a new formatted database file, or replaces an old one, and readies it for the data + ! storage of the grid and the flow variable(s) associated with the current time-step, t_step. This is performed by all the + ! local process(es). The root processor, in addition, must also generate a master formatted database file whose job will be + ! to link, and thus combine, the data from all of the local process(es). Note that for the Binary format, this extra task + ! that is assigned to the root process is not performed in multidimensions. ! Time-step that is currently being post-processed - integer, intent(IN) :: t_step + integer, intent(in) :: t_step ! Generic string used to store the location of a particular file character(LEN=len_trim(case_dir) + 3*name_len) :: file_loc - - integer :: ierr !< Generic flag used to identify and report database errors + integer :: ierr !< Generic flag used to identify and report database errors ! Silo-HDF5 Database Format if (format == 1) then - - ! Generating the relative path to the formatted database slave - ! file, that is to be opened for the current time-step, t_step + ! Generating the relative path to the formatted database slave file, that is to be opened for the current time-step, + ! t_step write (file_loc, '(A,I0,A)') '/', t_step, '.silo' - file_loc = trim(proc_rank_dir)//trim(file_loc) + file_loc = trim(proc_rank_dir) // trim(file_loc) - ! Creating formatted database slave file at the above location - ! and setting up the structure of the file and its header info - ierr = DBCREATE(trim(file_loc), len_trim(file_loc), & - DB_CLOBBER, DB_LOCAL, 'MFC v3.0', 8, & - DB_HDF5, dbfile) + ! Creating formatted database slave file at the above location and setting up the structure of the file and its header + ! info + ierr = DBCREATE(trim(file_loc), len_trim(file_loc), DB_CLOBBER, DB_LOCAL, 'MFC v3.0', 8, DB_HDF5, dbfile) - ! Verifying that the creation and setup process of the formatted - ! database slave file has been performed without errors. If this - ! is not the case, the post-process exits. + ! Verifying that the creation and setup process of the formatted database slave file has been performed without errors. + ! If this is not the case, the post-process exits. if (dbfile == -1) then - call s_mpi_abort('Unable to create Silo-HDF5 database '// & - 'slave file '//trim(file_loc)//'. '// & - 'Exiting.') + call s_mpi_abort('Unable to create Silo-HDF5 database ' // 'slave file ' // trim(file_loc) // '. ' // 'Exiting.') end if - ! Next, analogous steps to the ones above are carried out by the - ! root process to create and setup the formatted database master - ! file. + ! Next, analogous steps to the ones above are carried out by the root process to create and setup the formatted database + ! master file. if (proc_rank == 0) then - write (file_loc, '(A,I0,A)') '/collection_', t_step, '.silo' - file_loc = trim(rootdir)//trim(file_loc) + file_loc = trim(rootdir) // trim(file_loc) - ierr = DBCREATE(trim(file_loc), len_trim(file_loc), & - DB_CLOBBER, DB_LOCAL, 'MFC v3.0', 8, & - DB_HDF5, dbroot) + ierr = DBCREATE(trim(file_loc), len_trim(file_loc), DB_CLOBBER, DB_LOCAL, 'MFC v3.0', 8, DB_HDF5, dbroot) if (dbroot == -1) then - call s_mpi_abort('Unable to create Silo-HDF5 database '// & - 'master file '//trim(file_loc)//'. '// & - 'Exiting.') + call s_mpi_abort('Unable to create Silo-HDF5 database ' // 'master file ' // trim(file_loc) // '. ' & + & // 'Exiting.') end if - end if ! Binary Database Format - else - - ! Generating the relative path to the formatted database slave - ! file, that is to be opened for the current time-step, t_step + ! Generating the relative path to the formatted database slave file, that is to be opened for the current time-step, + ! t_step write (file_loc, '(A,I0,A)') '/', t_step, '.dat' - file_loc = trim(proc_rank_dir)//trim(file_loc) + file_loc = trim(proc_rank_dir) // trim(file_loc) - ! Creating the formatted database slave file, at the previously - ! precised relative path location, and setting up its structure - open (dbfile, IOSTAT=err, FILE=trim(file_loc), & - FORM='unformatted', STATUS='replace') + ! Creating the formatted database slave file, at the previously precised relative path location, and setting up its + ! structure + open (dbfile, IOSTAT=err, FILE=trim(file_loc), form='unformatted', STATUS='replace') - ! Verifying that the creation and setup process of the formatted - ! database slave file has been performed without errors. If this - ! is not the case, the post-process exits. + ! Verifying that the creation and setup process of the formatted database slave file has been performed without errors. + ! If this is not the case, the post-process exits. if (err /= 0) then - call s_mpi_abort('Unable to create Binary database slave '// & - 'file '//trim(file_loc)//'. Exiting.') + call s_mpi_abort('Unable to create Binary database slave ' // 'file ' // trim(file_loc) // '. Exiting.') end if - ! Further defining the structure of the formatted database slave - ! file by describing in it the dimensionality of post-processed - ! data as well as the total number of flow variable(s) that will - ! eventually be stored in it + ! Further defining the structure of the formatted database slave file by describing in it the dimensionality of + ! post-processed data as well as the total number of flow variable(s) that will eventually be stored in it if (output_partial_domain) then - write (dbfile) x_output_idx%end - x_output_idx%beg, & - y_output_idx%end - y_output_idx%beg, & - z_output_idx%end - z_output_idx%beg, & - dbvars + write (dbfile) x_output_idx%end - x_output_idx%beg, y_output_idx%end - y_output_idx%beg, & + & z_output_idx%end - z_output_idx%beg, dbvars else write (dbfile) m, n, p, dbvars end if - ! Next, analogous steps to the ones above are carried out by the - ! root process to create and setup the formatted database master - ! file. Note that this is only done in multidimensional cases. + ! Next, analogous steps to the ones above are carried out by the root process to create and setup the formatted database + ! master file. Note that this is only done in multidimensional cases. if (n == 0 .and. proc_rank == 0) then - write (file_loc, '(A,I0,A)') '/', t_step, '.dat' - file_loc = trim(rootdir)//trim(file_loc) + file_loc = trim(rootdir) // trim(file_loc) - open (dbroot, IOSTAT=err, FILE=trim(file_loc), & - FORM='unformatted', STATUS='replace') + open (dbroot, IOSTAT=err, FILE=trim(file_loc), form='unformatted', STATUS='replace') if (err /= 0) then - call s_mpi_abort('Unable to create Binary database '// & - 'master file '//trim(file_loc)// & - '. Exiting.') + call s_mpi_abort('Unable to create Binary database ' // 'master file ' // trim(file_loc) // '. Exiting.') end if if (output_partial_domain) then @@ -597,9 +491,7 @@ contains else write (dbroot) m_root, 0, 0, dbvars end if - end if - end if end subroutine s_open_formatted_database_file @@ -607,211 +499,153 @@ contains !> @brief Open the interface data file for appending extracted interface coordinates. impure subroutine s_open_intf_data_file() - character(LEN=path_len + 3*name_len) :: file_path !< - !! Relative path to a file in the case directory + character(LEN=path_len + 3*name_len) :: file_path !< Relative path to a file in the case directory write (file_path, '(A)') '/intf_data.dat' - file_path = trim(case_dir)//trim(file_path) + file_path = trim(case_dir) // trim(file_path) ! Opening the simulation data file - open (211, FILE=trim(file_path), & - FORM='formatted', & - POSITION='append', & - STATUS='unknown') + open (211, FILE=trim(file_path), form='formatted', POSITION='append', STATUS='unknown') end subroutine s_open_intf_data_file !> @brief Open the energy data file for appending volume-integrated energy budget quantities. impure subroutine s_open_energy_data_file() - character(LEN=path_len + 3*name_len) :: file_path !< - !! Relative path to a file in the case directory + character(LEN=path_len + 3*name_len) :: file_path !< Relative path to a file in the case directory write (file_path, '(A)') '/eng_data.dat' - file_path = trim(case_dir)//trim(file_path) + file_path = trim(case_dir) // trim(file_path) ! Opening the simulation data file - open (251, FILE=trim(file_path), & - FORM='formatted', & - POSITION='append', & - STATUS='unknown') + open (251, FILE=trim(file_path), form='formatted', POSITION='append', STATUS='unknown') end subroutine s_open_energy_data_file !> @brief Write the computational grid (cell-boundary coordinates) to the formatted database slave and master files. impure subroutine s_write_grid_to_formatted_database_file(t_step) - ! Description: The general objective of this subroutine is to write the - ! necessary grid data to the formatted database file, for - ! the current time-step, t_step. The local processor will - ! write the grid data of the domain segment that it is in - ! charge of to the formatted database slave file. The root - ! process will additionally take care of linking that grid - ! data in the formatted database master file. In the Silo- - ! HDF5 database format, the spatial extents of each local - ! process grid are also written to the master file. In the - ! Binary format, note that no master file is maintained in - ! multidimensions. Finally, in 1D, no grid data is written - ! within this subroutine for the Silo-HDF5 format because - ! curve objects rather than quadrilateral meshes are used. - ! For curve objects, in contrast to the quadrilateral mesh - ! objects, the grid data is included side by side with the - ! flow variable data. Then, in this case, we take care of - ! writing both the grid and the flow variable data in the - ! subroutine s_write_variable_to_formatted_database_file. + + ! Description: The general objective of this subroutine is to write the necessary grid data to the formatted database file, + ! for the current time-step, t_step. The local processor will write the grid data of the domain segment that it is in charge + ! of to the formatted database slave file. The root process will additionally take care of linking that grid data in the + ! formatted database master file. In the Silo- HDF5 database format, the spatial extents of each local process grid are also + ! written to the master file. In the Binary format, note that no master file is maintained in multidimensions. Finally, in + ! 1D, no grid data is written within this subroutine for the Silo-HDF5 format because curve objects rather than + ! quadrilateral meshes are used. For curve objects, in contrast to the quadrilateral mesh objects, the grid data is included + ! side by side with the flow variable data. Then, in this case, we take care of writing both the grid and the flow variable + ! data in the subroutine s_write_variable_to_formatted_database_file. ! Time-step that is currently being post-processed - integer, intent(IN) :: t_step + integer, intent(in) :: t_step - ! Bookkeeping variables storing the name and type of mesh that is - ! handled by the local processor(s). Note that due to an internal - ! NAG Fortran compiler problem, these two variables could not be - ! allocated dynamically. + ! Bookkeeping variables storing the name and type of mesh that is handled by the local processor(s). Note that due to an + ! internal NAG Fortran compiler problem, these two variables could not be allocated dynamically. character(LEN=4*name_len), dimension(num_procs) :: meshnames - integer, dimension(num_procs) :: meshtypes + integer, dimension(num_procs) :: meshtypes ! Generic loop iterator integer :: i - - integer :: ierr !< Generic flag used to identify and report database errors + integer :: ierr !< Generic flag used to identify and report database errors ! Silo-HDF5 Database Format if (format == 1) then - - ! For multidimensional data sets, the spatial extents of all of - ! the grid(s) handled by the local processor(s) are recorded so - ! that they may be written, by root processor, to the formatted - ! database master file. + ! For multidimensional data sets, the spatial extents of all of the grid(s) handled by the local processor(s) are + ! recorded so that they may be written, by root processor, to the formatted database master file. if (num_procs > 1) then call s_mpi_gather_spatial_extents(spatial_extents) - elseif (p > 0) then + else if (p > 0) then if (grid_geometry == 3) then - spatial_extents(:, 0) = (/minval(y_cb), minval(z_cb), & - minval(x_cb), maxval(y_cb), & - maxval(z_cb), maxval(x_cb)/) + spatial_extents(:,0) = (/minval(y_cb), minval(z_cb), minval(x_cb), maxval(y_cb), maxval(z_cb), maxval(x_cb)/) else - spatial_extents(:, 0) = (/minval(x_cb), minval(y_cb), & - minval(z_cb), maxval(x_cb), & - maxval(y_cb), maxval(z_cb)/) + spatial_extents(:,0) = (/minval(x_cb), minval(y_cb), minval(z_cb), maxval(x_cb), maxval(y_cb), maxval(z_cb)/) end if - elseif (n > 0) then - spatial_extents(:, 0) = (/minval(x_cb), minval(y_cb), & - maxval(x_cb), maxval(y_cb)/) + else if (n > 0) then + spatial_extents(:,0) = (/minval(x_cb), minval(y_cb), maxval(x_cb), maxval(y_cb)/) else - spatial_extents(:, 0) = (/minval(x_cb), maxval(x_cb)/) + spatial_extents(:,0) = (/minval(x_cb), maxval(x_cb)/) end if - ! Next, the root processor proceeds to record all of the spatial - ! extents in the formatted database master file. In addition, it - ! also records a sub-domain connectivity map so that the entire - ! grid may be reassembled by looking at the master file. + ! Next, the root processor proceeds to record all of the spatial extents in the formatted database master file. In + ! addition, it also records a sub-domain connectivity map so that the entire grid may be reassembled by looking at the + ! master file. if (proc_rank == 0) then - do i = 1, num_procs - write (meshnames(i), '(A,I0,A,I0,A)') '../p', i - 1, & - '/', t_step, '.silo:rectilinear_grid' + write (meshnames(i), '(A,I0,A,I0,A)') '../p', i - 1, '/', t_step, '.silo:rectilinear_grid' end do meshtypes = DB_QUAD_RECT err = DBSET2DSTRLEN(len(meshnames(1))) err = DBMKOPTLIST(2, optlist) - err = DBADDIOPT(optlist, DBOPT_EXTENTS_SIZE, & - size(spatial_extents, 1)) + err = DBADDIOPT(optlist, DBOPT_EXTENTS_SIZE, size(spatial_extents, 1)) err = DBADDDOPT(optlist, DBOPT_EXTENTS, spatial_extents) - err = DBPUTMMESH(dbroot, 'rectilinear_grid', 16, & - num_procs, meshnames, & - len_trim(meshnames), & - meshtypes, optlist, ierr) + err = DBPUTMMESH(dbroot, 'rectilinear_grid', 16, num_procs, meshnames, len_trim(meshnames), meshtypes, optlist, & + & ierr) err = DBFREEOPTLIST(optlist) - end if - ! Finally, the local quadrilateral mesh, either 2D or 3D, along - ! with its offsets that indicate the presence and size of ghost - ! zone layer(s), are put in the formatted database slave file. + ! Finally, the local quadrilateral mesh, either 2D or 3D, along with its offsets that indicate the presence and size of + ! ghost zone layer(s), are put in the formatted database slave file. if (p > 0) then err = DBMKOPTLIST(2, optlist) err = DBADDIOPT(optlist, DBOPT_LO_OFFSET, lo_offset) err = DBADDIOPT(optlist, DBOPT_HI_OFFSET, hi_offset) if (grid_geometry == 3) then - err = DBPUTQM(dbfile, 'rectilinear_grid', 16, & - 'x', 1, 'y', 1, 'z', 1, & - y_cb, z_cb, x_cb, dims, 3, & - DB_DOUBLE, DB_COLLINEAR, & - optlist, ierr) + err = DBPUTQM(dbfile, 'rectilinear_grid', 16, 'x', 1, 'y', 1, 'z', 1, y_cb, z_cb, x_cb, dims, 3, DB_DOUBLE, & + & DB_COLLINEAR, optlist, ierr) else - err = DBPUTQM(dbfile, 'rectilinear_grid', 16, & - 'x', 1, 'y', 1, 'z', 1, & - x_cb, y_cb, z_cb, dims, 3, & - DB_DOUBLE, DB_COLLINEAR, & - optlist, ierr) + err = DBPUTQM(dbfile, 'rectilinear_grid', 16, 'x', 1, 'y', 1, 'z', 1, x_cb, y_cb, z_cb, dims, 3, DB_DOUBLE, & + & DB_COLLINEAR, optlist, ierr) end if err = DBFREEOPTLIST(optlist) - elseif (n > 0) then + else if (n > 0) then err = DBMKOPTLIST(2, optlist) err = DBADDIOPT(optlist, DBOPT_LO_OFFSET, lo_offset) err = DBADDIOPT(optlist, DBOPT_HI_OFFSET, hi_offset) - err = DBPUTQM(dbfile, 'rectilinear_grid', 16, & - 'x', 1, 'y', 1, 'z', 1, & - x_cb, y_cb, DB_F77NULL, dims, 2, & - DB_DOUBLE, DB_COLLINEAR, & - optlist, ierr) + err = DBPUTQM(dbfile, 'rectilinear_grid', 16, 'x', 1, 'y', 1, 'z', 1, x_cb, y_cb, DB_F77NULL, dims, 2, DB_DOUBLE, & + & DB_COLLINEAR, optlist, ierr) err = DBFREEOPTLIST(optlist) else err = DBMKOPTLIST(2, optlist) err = DBADDIOPT(optlist, DBOPT_LO_OFFSET, lo_offset) err = DBADDIOPT(optlist, DBOPT_HI_OFFSET, hi_offset) - err = DBPUTQM(dbfile, 'rectilinear_grid', 16, & - 'x', 1, 'y', 1, 'z', 1, & - x_cb, DB_F77NULL, DB_F77NULL, dims, 1, & - DB_DOUBLE, DB_COLLINEAR, & - optlist, ierr) + err = DBPUTQM(dbfile, 'rectilinear_grid', 16, 'x', 1, 'y', 1, 'z', 1, x_cb, DB_F77NULL, DB_F77NULL, dims, 1, & + & DB_DOUBLE, DB_COLLINEAR, optlist, ierr) err = DBFREEOPTLIST(optlist) end if ! END: Silo-HDF5 Database Format ! Binary Database Format - - elseif (format == 2) then - - ! Multidimensional local grid data is written to the formatted - ! database slave file. Recall that no master file to maintained - ! in multidimensions. + else if (format == 2) then + ! Multidimensional local grid data is written to the formatted database slave file. Recall that no master file to + ! maintained in multidimensions. if (p > 0) then if (precision == 1) then - write (dbfile) real(x_cb, sp), & - real(y_cb, sp), & - real(z_cb, sp) + write (dbfile) real(x_cb, sp), real(y_cb, sp), real(z_cb, sp) else if (output_partial_domain) then - write (dbfile) x_cb(x_output_idx%beg - 1:x_output_idx%end), & - y_cb(y_output_idx%beg - 1:y_output_idx%end), & - z_cb(z_output_idx%beg - 1:z_output_idx%end) + write (dbfile) x_cb(x_output_idx%beg - 1:x_output_idx%end), y_cb(y_output_idx%beg - 1:y_output_idx%end), & + & z_cb(z_output_idx%beg - 1:z_output_idx%end) else write (dbfile) x_cb, y_cb, z_cb end if end if - - elseif (n > 0) then + else if (n > 0) then if (precision == 1) then - write (dbfile) real(x_cb, sp), & - real(y_cb, sp) + write (dbfile) real(x_cb, sp), real(y_cb, sp) else if (output_partial_domain) then - write (dbfile) x_cb(x_output_idx%beg - 1:x_output_idx%end), & - y_cb(y_output_idx%beg - 1:y_output_idx%end) + write (dbfile) x_cb(x_output_idx%beg - 1:x_output_idx%end), y_cb(y_output_idx%beg - 1:y_output_idx%end) else write (dbfile) x_cb, y_cb end if end if - ! One-dimensional local grid data is written to the formatted - ! database slave file. In addition, the local grid data is put - ! together by the root process and written to the master file. + ! One-dimensional local grid data is written to the formatted database slave file. In addition, the local grid data + ! is put together by the root process and written to the master file. else - if (precision == 1) then write (dbfile) real(x_cb, sp) else @@ -839,69 +673,52 @@ contains end if end if end if - end if - end if end subroutine s_write_grid_to_formatted_database_file !> @brief Write a single flow variable field to the formatted database slave and master files for a given time step. impure subroutine s_write_variable_to_formatted_database_file(varname, t_step) - ! Description: The goal of this subroutine is to write to the formatted - ! database file the flow variable at the current time-step, - ! t_step. The local process(es) write the part of the flow - ! variable that they handle to the formatted database slave - ! file. The root process, on the other hand, will also take - ! care of connecting all of the flow variable data in the - ! formatted database master file. In the Silo-HDF5 database - ! format, the extents of each local process flow variable - ! are also written to the master file. Note that in Binary - ! format, no master file is maintained in multidimensions. - ! Finally note that in 1D, grid data is also written within - ! this subroutine for Silo-HDF5 database format since curve - ! and not the quadrilateral variable objects are used, see - ! description of s_write_grid_to_formatted_database_file - ! for more details on this topic. - - ! Name of the flow variable, which will be written to the formatted - ! database file at the current time-step, t_step - character(LEN=*), intent(IN) :: varname + + ! Description: The goal of this subroutine is to write to the formatted database file the flow variable at the current + ! time-step, t_step. The local process(es) write the part of the flow variable that they handle to the formatted database + ! slave file. The root process, on the other hand, will also take care of connecting all of the flow variable data in the + ! formatted database master file. In the Silo-HDF5 database format, the extents of each local process flow variable are also + ! written to the master file. Note that in Binary format, no master file is maintained in multidimensions. Finally note that + ! in 1D, grid data is also written within this subroutine for Silo-HDF5 database format since curve and not the + ! quadrilateral variable objects are used, see description of s_write_grid_to_formatted_database_file for more details on + ! this topic. + + ! Name of the flow variable, which will be written to the formatted database file at the current time-step, t_step + character(LEN=*), intent(in) :: varname ! Time-step that is currently being post-processed - integer, intent(IN) :: t_step + integer, intent(in) :: t_step - ! Bookkeeping variables storing the name and type of flow variable - ! that is about to be handled by the local processor(s). Note that - ! due to an internal NAG Fortran compiler problem, these variables - ! could not be allocated dynamically. + ! Bookkeeping variables storing the name and type of flow variable that is about to be handled by the local processor(s). + ! Note that due to an internal NAG Fortran compiler problem, these variables could not be allocated dynamically. character(LEN=4*name_len), dimension(num_procs) :: varnames - integer, dimension(num_procs) :: vartypes + integer, dimension(num_procs) :: vartypes ! Generic loop iterator integer :: i, j, k - - integer :: ierr !< Generic flag used to identify and report database errors + integer :: ierr !< Generic flag used to identify and report database errors ! Silo-HDF5 Database Format if (format == 1) then - - ! Determining the extents of the flow variable on each local - ! process and gathering all this information on root process + ! Determining the extents of the flow variable on each local process and gathering all this information on root process if (num_procs > 1) then call s_mpi_gather_data_extents(q_sf, data_extents) else - data_extents(:, 0) = (/minval(q_sf), maxval(q_sf)/) + data_extents(:,0) = (/minval(q_sf), maxval(q_sf)/) end if - ! Next, the root process proceeds to write the gathered flow - ! variable data extents to formatted database master file. + ! Next, the root process proceeds to write the gathered flow variable data extents to formatted database master file. if (proc_rank == 0) then - do i = 1, num_procs - write (varnames(i), '(A,I0,A,I0,A)') '../p', i - 1, & - '/', t_step, '.silo:'//trim(varname) + write (varnames(i), '(A,I0,A,I0,A)') '../p', i - 1, '/', t_step, '.silo:' // trim(varname) end do vartypes = DB_QUADVAR @@ -910,16 +727,12 @@ contains err = DBMKOPTLIST(2, optlist) err = DBADDIOPT(optlist, DBOPT_EXTENTS_SIZE, 2) err = DBADDDOPT(optlist, DBOPT_EXTENTS, data_extents) - err = DBPUTMVAR(dbroot, trim(varname), & - len_trim(varname), num_procs, & - varnames, len_trim(varnames), & - vartypes, optlist, ierr) + err = DBPUTMVAR(dbroot, trim(varname), len_trim(varname), num_procs, varnames, len_trim(varnames), vartypes, & + & optlist, ierr) err = DBFREEOPTLIST(optlist) - end if - ! Finally, each of the local processor(s) proceeds to write - ! the flow variable data that it is responsible for to the + ! Finally, each of the local processor(s) proceeds to write the flow variable data that it is responsible for to the ! formatted database slave file. if (wp == dp) then if (precision == 1) then @@ -950,7 +763,7 @@ contains end do end if end if - elseif (wp == sp) then + else if (wp == sp) then do i = -offset_x%beg, m + offset_x%end do j = -offset_y%beg, n + offset_y%end do k = -offset_z%beg, p + offset_z%end @@ -973,35 +786,18 @@ contains if (precision == ${PRECISION}$) then if (p > 0) then if (grid_geometry == 3) then - err = DBPUTQV1(dbfile, trim(varname), & - len_trim(varname), & - 'rectilinear_grid', 16, & - cyl_q_sf${SFX}$, dims - 1, 3, DB_F77NULL, & - 0, ${DBT}$, DB_ZONECENT, & - DB_F77NULL, ierr) + err = DBPUTQV1(dbfile, trim(varname), len_trim(varname), 'rectilinear_grid', 16, cyl_q_sf${SFX}$, & + & dims - 1, 3, DB_F77NULL, 0, ${DBT}$, DB_ZONECENT, DB_F77NULL, ierr) else - err = DBPUTQV1(dbfile, trim(varname), & - len_trim(varname), & - 'rectilinear_grid', 16, & - q_sf${SFX}$, dims - 1, 3, DB_F77NULL, & - 0, ${DBT}$, DB_ZONECENT, & - DB_F77NULL, ierr) + err = DBPUTQV1(dbfile, trim(varname), len_trim(varname), 'rectilinear_grid', 16, q_sf${SFX}$, & + & dims - 1, 3, DB_F77NULL, 0, ${DBT}$, DB_ZONECENT, DB_F77NULL, ierr) end if - elseif (n > 0) then - err = DBPUTQV1(dbfile, trim(varname), & - len_trim(varname), & - 'rectilinear_grid', 16, & - q_sf${SFX}$, dims - 1, 2, DB_F77NULL, & - 0, ${DBT}$, DB_ZONECENT, & - DB_F77NULL, ierr) + else if (n > 0) then + err = DBPUTQV1(dbfile, trim(varname), len_trim(varname), 'rectilinear_grid', 16, q_sf${SFX}$, dims - 1, & + & 2, DB_F77NULL, 0, ${DBT}$, DB_ZONECENT, DB_F77NULL, ierr) else - err = DBPUTQV1(dbfile, trim(varname), & - len_trim(varname), & - 'rectilinear_grid', 16, & - q_sf${SFX}$, dims - 1, 1, DB_F77NULL, & - 0, ${DBT}$, DB_ZONECENT, & - DB_F77NULL, ierr) - + err = DBPUTQV1(dbfile, trim(varname), len_trim(varname), 'rectilinear_grid', 16, q_sf${SFX}$, dims - 1, & + & 1, DB_F77NULL, 0, ${DBT}$, DB_ZONECENT, DB_F77NULL, ierr) end if end if #:endfor @@ -1009,26 +805,22 @@ contains ! END: Silo-HDF5 Database Format ! Binary Database Format - else - - ! Writing the name of the flow variable and its data, associated - ! with the local processor, to the formatted database slave file + ! Writing the name of the flow variable and its data, associated with the local processor, to the formatted database + ! slave file if (precision == 1) then write (dbfile) varname, real(q_sf, wp) else write (dbfile) varname, q_sf end if - ! In 1D, the root process also takes care of gathering the flow - ! variable data from all of the local processor(s) and writes it - ! to the formatted database master file. + ! In 1D, the root process also takes care of gathering the flow variable data from all of the local processor(s) and + ! writes it to the formatted database master file. if (n == 0) then - if (num_procs > 1) then call s_mpi_defragment_1d_flow_variable(q_sf, q_root_sf) else - q_root_sf(:, :, :) = q_sf(:, :, :) + q_root_sf(:,:,:) = q_sf(:,:,:) end if if (proc_rank == 0) then @@ -1038,58 +830,50 @@ contains write (dbroot) varname, q_root_sf end if end if - end if - end if end subroutine s_write_variable_to_formatted_database_file - !> Subroutine that writes the post processed results in the folder 'lag_bubbles_data' - !! @param t_step Current time step + !> Subroutine that writes the post processed results in the folder 'lag_bubbles_data' + !! @param t_step Current time step impure subroutine s_write_lag_bubbles_results_to_text(t_step) - integer, intent(in) :: t_step - + integer, intent(in) :: t_step character(len=len_trim(case_dir) + 3*name_len) :: file_loc - - integer :: id + integer :: id #ifdef MFC_MPI - real(wp), dimension(20) :: inputvals - real(wp) :: time_real - integer, dimension(MPI_STATUS_SIZE) :: status - integer(KIND=MPI_OFFSET_KIND) :: disp - integer :: view - - logical :: lg_bub_file, file_exist - - integer, dimension(2) :: gsizes, lsizes, start_idx_part - integer :: ifile - integer :: ierr !< Generic flag used to identify and report MPI errors - real(wp) :: file_time, file_dt - integer :: file_num_procs, file_tot_part, tot_part - integer :: i - - integer, dimension(:), allocatable :: proc_bubble_counts - real(wp), dimension(1:1, 1:lag_io_vars) :: lag_io_null + real(wp), dimension(20) :: inputvals + real(wp) :: time_real + integer, dimension(MPI_STATUS_SIZE) :: status + integer(KIND=MPI_OFFSET_KIND) :: disp + integer :: view + logical :: lg_bub_file, file_exist + integer, dimension(2) :: gsizes, lsizes, start_idx_part + integer :: ifile + integer :: ierr !< Generic flag used to identify and report MPI errors + real(wp) :: file_time, file_dt + integer :: file_num_procs, file_tot_part, tot_part + integer :: i + integer, dimension(:), allocatable :: proc_bubble_counts + real(wp), dimension(1:1,1:lag_io_vars) :: lag_io_null lag_io_null = 0._wp ! Construct file path write (file_loc, '(A,I0,A)') 'lag_bubbles_', t_step, '.dat' - file_loc = trim(case_dir)//'/restart_data'//trim(mpiiofs)//trim(file_loc) + file_loc = trim(case_dir) // '/restart_data' // trim(mpiiofs) // trim(file_loc) ! Check if file exists inquire (FILE=trim(file_loc), EXIST=file_exist) if (.not. file_exist) then - call s_mpi_abort('Restart file '//trim(file_loc)//' does not exist!') + call s_mpi_abort('Restart file ' // trim(file_loc) // ' does not exist!') end if if (.not. parallel_io) return if (proc_rank == 0) then - call MPI_FILE_OPEN(MPI_COMM_SELF, file_loc, MPI_MODE_RDONLY, & - mpi_info_int, ifile, ierr) + call MPI_FILE_OPEN(MPI_COMM_SELF, file_loc, MPI_MODE_RDONLY, mpi_info_int, ifile, ierr) call MPI_FILE_READ(ifile, file_tot_part, 1, MPI_INTEGER, status, ierr) call MPI_FILE_READ(ifile, file_time, 1, mpi_p, status, ierr) @@ -1108,12 +892,10 @@ contains allocate (proc_bubble_counts(file_num_procs)) if (proc_rank == 0) then - call MPI_FILE_OPEN(MPI_COMM_SELF, file_loc, MPI_MODE_RDONLY, & - mpi_info_int, ifile, ierr) + call MPI_FILE_OPEN(MPI_COMM_SELF, file_loc, MPI_MODE_RDONLY, mpi_info_int, ifile, ierr) ! Skip to processor counts position - disp = int(sizeof(file_tot_part) + 2*sizeof(file_time) + sizeof(file_num_procs), & - MPI_OFFSET_KIND) + disp = int(sizeof(file_tot_part) + 2*sizeof(file_time) + sizeof(file_num_procs), MPI_OFFSET_KIND) call MPI_FILE_SEEK(ifile, disp, MPI_SEEK_SET, ierr) call MPI_FILE_READ(ifile, proc_bubble_counts, file_num_procs, MPI_INTEGER, status, ierr) @@ -1129,25 +911,21 @@ contains start_idx_part(1) = 0 start_idx_part(2) = 0 - call MPI_TYPE_CREATE_SUBARRAY(2, gsizes, lsizes, start_idx_part, & - MPI_ORDER_FORTRAN, mpi_p, view, ierr) + call MPI_TYPE_CREATE_SUBARRAY(2, gsizes, lsizes, start_idx_part, MPI_ORDER_FORTRAN, mpi_p, view, ierr) call MPI_TYPE_COMMIT(view, ierr) - call MPI_FILE_OPEN(MPI_COMM_WORLD, file_loc, MPI_MODE_RDONLY, & - mpi_info_int, ifile, ierr) + call MPI_FILE_OPEN(MPI_COMM_WORLD, file_loc, MPI_MODE_RDONLY, mpi_info_int, ifile, ierr) - disp = int(sizeof(file_tot_part) + 2*sizeof(file_time) + sizeof(file_num_procs) + & - file_num_procs*sizeof(proc_bubble_counts(1)), MPI_OFFSET_KIND) - call MPI_FILE_SET_VIEW(ifile, disp, mpi_p, view, & - 'native', mpi_info_null, ierr) + disp = int(sizeof(file_tot_part) + 2*sizeof(file_time) + sizeof(file_num_procs) & + & + file_num_procs*sizeof(proc_bubble_counts(1)), MPI_OFFSET_KIND) + call MPI_FILE_SET_VIEW(ifile, disp, mpi_p, view, 'native', mpi_info_null, ierr) - allocate (MPI_IO_DATA_lg_bubbles(file_tot_part, 1:lag_io_vars)) + allocate (MPI_IO_DATA_lg_bubbles(file_tot_part,1:lag_io_vars)) - call MPI_FILE_READ_ALL(ifile, MPI_IO_DATA_lg_bubbles, lag_io_vars*file_tot_part, & - mpi_p, status, ierr) + call MPI_FILE_READ_ALL(ifile, MPI_IO_DATA_lg_bubbles, lag_io_vars*file_tot_part, mpi_p, status, ierr) write (file_loc, '(A,I0,A)') 'lag_bubbles_post_process_', t_step, '.dat' - file_loc = trim(case_dir)//'/lag_bubbles_post_process/'//trim(file_loc) + file_loc = trim(case_dir) // '/lag_bubbles_post_process/' // trim(file_loc) if (proc_rank == 0) then open (unit=29, file=file_loc, form='formatted', position='rewind') @@ -1174,13 +952,16 @@ contains do i = 1, file_tot_part id = int(MPI_IO_DATA_lg_bubbles(i, 1)) - inputvals(1:20) = MPI_IO_DATA_lg_bubbles(i, 2:21) + inputvals(1:20) = MPI_IO_DATA_lg_bubbles(i,2:21) if (id > 0) then write (29, '(100(A))', advance='no') '' if (lag_id_wrt) write (29, '(I6, A)', advance='no') id, ', ' - if (lag_pos_wrt) write (29, '(3(E15.7, A))', advance='no') inputvals(1), ', ', inputvals(2), ', ', inputvals(3), ', ' - if (lag_pos_prev_wrt) write (29, '(3(E15.7, A))', advance='no') inputvals(4), ', ', inputvals(5), ', ', inputvals(6), ', ' - if (lag_vel_wrt) write (29, '(3(E15.7, A))', advance='no') inputvals(7), ', ', inputvals(8), ', ', inputvals(9), ', ' + if (lag_pos_wrt) write (29, '(3(E15.7, A))', advance='no') inputvals(1), ', ', inputvals(2), ', ', & + & inputvals(3), ', ' + if (lag_pos_prev_wrt) write (29, '(3(E15.7, A))', advance='no') inputvals(4), ', ', inputvals(5), ', ', & + & inputvals(6), ', ' + if (lag_vel_wrt) write (29, '(3(E15.7, A))', advance='no') inputvals(7), ', ', inputvals(8), ', ', & + & inputvals(9), ', ' if (lag_rad_wrt) write (29, '(E15.7, A)', advance='no') inputvals(10), ', ' if (lag_rvel_wrt) write (29, '(E15.7, A)', advance='no') inputvals(11), ', ' if (lag_r0_wrt) write (29, '(E15.7, A)', advance='no') inputvals(12), ', ' @@ -1210,56 +991,49 @@ contains !> @brief Read Lagrangian bubble restart data and write bubble positions and scalar fields to the Silo database. impure subroutine s_write_lag_bubbles_to_formatted_database_file(t_step) - integer, intent(in) :: t_step - + integer, intent(in) :: t_step character(len=len_trim(case_dir) + 3*name_len) :: file_loc - - integer :: id + integer :: id #ifdef MFC_MPI - real(wp), dimension(20) :: inputvals - real(wp) :: time_real - integer, dimension(MPI_STATUS_SIZE) :: status - integer(KIND=MPI_OFFSET_KIND) :: disp - integer :: view - - logical :: lg_bub_file, file_exist - - integer, dimension(2) :: gsizes, lsizes, start_idx_part - integer :: ifile, ierr, tot_data, valid_data, nBub - real(wp) :: file_time, file_dt - integer :: file_num_procs, file_tot_part - integer, dimension(:), allocatable :: proc_bubble_counts - real(wp), dimension(1:1, 1:lag_io_vars) :: dummy + real(wp), dimension(20) :: inputvals + real(wp) :: time_real + integer, dimension(MPI_STATUS_SIZE) :: status + integer(KIND=MPI_OFFSET_KIND) :: disp + integer :: view + logical :: lg_bub_file, file_exist + integer, dimension(2) :: gsizes, lsizes, start_idx_part + integer :: ifile, ierr, tot_data, valid_data, nBub + real(wp) :: file_time, file_dt + integer :: file_num_procs, file_tot_part + integer, dimension(:), allocatable :: proc_bubble_counts + real(wp), dimension(1:1,1:lag_io_vars) :: dummy character(LEN=4*name_len), dimension(num_procs) :: meshnames - integer, dimension(num_procs) :: meshtypes - real(wp) :: dummy_data - - integer :: i, j - - real(wp), dimension(:), allocatable :: bub_id - real(wp), dimension(:), allocatable :: px, py, pz, ppx, ppy, ppz, vx, vy, vz - real(wp), dimension(:), allocatable :: radius, rvel, rnot, rmax, rmin, dphidt - real(wp), dimension(:), allocatable :: pressure, mv, mg, betaT, betaC + integer, dimension(num_procs) :: meshtypes + real(wp) :: dummy_data + integer :: i, j + real(wp), dimension(:), allocatable :: bub_id + real(wp), dimension(:), allocatable :: px, py, pz, ppx, ppy, ppz, vx, vy, vz + real(wp), dimension(:), allocatable :: radius, rvel, rnot, rmax, rmin, dphidt + real(wp), dimension(:), allocatable :: pressure, mv, mg, betaT, betaC dummy = 0._wp dummy_data = 0._wp ! Construct file path write (file_loc, '(A,I0,A)') 'lag_bubbles_', t_step, '.dat' - file_loc = trim(case_dir)//'/restart_data'//trim(mpiiofs)//trim(file_loc) + file_loc = trim(case_dir) // '/restart_data' // trim(mpiiofs) // trim(file_loc) ! Check if file exists inquire (FILE=trim(file_loc), EXIST=file_exist) if (.not. file_exist) then - call s_mpi_abort('Restart file '//trim(file_loc)//' does not exist!') + call s_mpi_abort('Restart file ' // trim(file_loc) // ' does not exist!') end if if (.not. parallel_io) return if (proc_rank == 0) then - call MPI_FILE_OPEN(MPI_COMM_SELF, file_loc, MPI_MODE_RDONLY, & - mpi_info_int, ifile, ierr) + call MPI_FILE_OPEN(MPI_COMM_SELF, file_loc, MPI_MODE_RDONLY, mpi_info_int, ifile, ierr) call MPI_FILE_READ(ifile, file_tot_part, 1, MPI_INTEGER, status, ierr) call MPI_FILE_READ(ifile, file_time, 1, mpi_p, status, ierr) @@ -1278,12 +1052,10 @@ contains allocate (proc_bubble_counts(file_num_procs)) if (proc_rank == 0) then - call MPI_FILE_OPEN(MPI_COMM_SELF, file_loc, MPI_MODE_RDONLY, & - mpi_info_int, ifile, ierr) + call MPI_FILE_OPEN(MPI_COMM_SELF, file_loc, MPI_MODE_RDONLY, mpi_info_int, ifile, ierr) ! Skip to processor counts position - disp = int(sizeof(file_tot_part) + 2*sizeof(file_time) + sizeof(file_num_procs), & - MPI_OFFSET_KIND) + disp = int(sizeof(file_tot_part) + 2*sizeof(file_time) + sizeof(file_num_procs), MPI_OFFSET_KIND) call MPI_FILE_SEEK(ifile, disp, MPI_SEEK_SET, ierr) call MPI_FILE_READ(ifile, proc_bubble_counts, file_num_procs, MPI_INTEGER, status, ierr) @@ -1309,62 +1081,49 @@ contains gsizes(2) = lag_io_vars if (nBub > 0) then - #:for VAR in ['bub_id', 'px', 'py', 'pz', 'ppx', 'ppy', 'ppz', 'vx', 'vy', 'vz', & 'radius', 'rvel', 'rnot', 'rmax', 'rmin', 'dphidt', & 'pressure', 'mv', 'mg', 'betaT', 'betaC'] allocate (${VAR}$ (nBub)) #:endfor - allocate (MPI_IO_DATA_lg_bubbles(nBub, 1:lag_io_vars)) + allocate (MPI_IO_DATA_lg_bubbles(nBub,1:lag_io_vars)) - call MPI_TYPE_CREATE_SUBARRAY(2, gsizes, lsizes, start_idx_part, & - MPI_ORDER_FORTRAN, mpi_p, view, ierr) + call MPI_TYPE_CREATE_SUBARRAY(2, gsizes, lsizes, start_idx_part, MPI_ORDER_FORTRAN, mpi_p, view, ierr) call MPI_TYPE_COMMIT(view, ierr) - call MPI_FILE_OPEN(MPI_COMM_WORLD, file_loc, MPI_MODE_RDONLY, & - mpi_info_int, ifile, ierr) + call MPI_FILE_OPEN(MPI_COMM_WORLD, file_loc, MPI_MODE_RDONLY, mpi_info_int, ifile, ierr) ! Skip extended header - disp = int(sizeof(file_tot_part) + 2*sizeof(file_time) + sizeof(file_num_procs) + & - file_num_procs*sizeof(proc_bubble_counts(1)), MPI_OFFSET_KIND) + disp = int(sizeof(file_tot_part) + 2*sizeof(file_time) + sizeof(file_num_procs) & + & + file_num_procs*sizeof(proc_bubble_counts(1)), MPI_OFFSET_KIND) call MPI_FILE_SET_VIEW(ifile, disp, mpi_p, view, 'native', mpi_info_int, ierr) - call MPI_FILE_READ_ALL(ifile, MPI_IO_DATA_lg_bubbles, & - lag_io_vars*nBub, mpi_p, status, ierr) + call MPI_FILE_READ_ALL(ifile, MPI_IO_DATA_lg_bubbles, lag_io_vars*nBub, mpi_p, status, ierr) call MPI_FILE_CLOSE(ifile, ierr) call MPI_TYPE_FREE(view, ierr) - ! Extract data from MPI_IO_DATA_lg_bubbles array - ! Adjust these indices based on your actual data layout + ! Extract data from MPI_IO_DATA_lg_bubbles array Adjust these indices based on your actual data layout #:for VAR, IDX in [('bub_id', 1), ('px', 2), ('py',3), ('pz',4), ('ppx',5), ('ppy',6), ('ppz',7), & ('vx',8), ('vy',9), ('vz',10), ('radius',11), ('rvel',12), & ('rnot',13), ('rmax',14), ('rmin',15), ('dphidt',16), & ('pressure',17), ('mv',18), ('mg',19), ('betaT',20), ('betaC',21)] - ${VAR}$ (:) = MPI_IO_DATA_lg_bubbles(:, ${IDX}$) + ${VAR}$ (:) = MPI_IO_DATA_lg_bubbles(:,${IDX}$) #:endfor - ! Next, the root processor proceeds to record all of the spatial - ! extents in the formatted database master file. In addition, it - ! also records a sub-domain connectivity map so that the entire - ! grid may be reassembled by looking at the master file. + ! Next, the root processor proceeds to record all of the spatial extents in the formatted database master file. In + ! addition, it also records a sub-domain connectivity map so that the entire grid may be reassembled by looking at the + ! master file. if (proc_rank == 0) then - do i = 1, num_procs - write (meshnames(i), '(A,I0,A,I0,A)') '../p', i - 1, & - '/', t_step, '.silo:lag_bubbles' + write (meshnames(i), '(A,I0,A,I0,A)') '../p', i - 1, '/', t_step, '.silo:lag_bubbles' meshtypes(i) = DB_POINTMESH end do err = DBSET2DSTRLEN(len(meshnames(1))) - err = DBPUTMMESH(dbroot, 'lag_bubbles', 16, & - num_procs, meshnames, & - len_trim(meshnames), & - meshtypes, DB_F77NULL, ierr) + err = DBPUTMMESH(dbroot, 'lag_bubbles', 16, num_procs, meshnames, len_trim(meshnames), meshtypes, DB_F77NULL, ierr) end if - err = DBPUTPM(dbfile, 'lag_bubbles', 11, 3, & - px, py, pz, nBub, & - DB_DOUBLE, DB_F77NULL, ierr) + err = DBPUTPM(dbfile, 'lag_bubbles', 11, 3, px, py, pz, nBub, DB_DOUBLE, DB_F77NULL, ierr) if (lag_id_wrt) call s_write_lag_variable_to_formatted_database_file('part_id', t_step, bub_id, nBub) if (lag_vel_wrt) then @@ -1384,20 +1143,18 @@ contains if (lag_betaT_wrt) call s_write_lag_variable_to_formatted_database_file('part_betaT', t_step, betaT, nBub) if (lag_betaC_wrt) call s_write_lag_variable_to_formatted_database_file('part_betaC', t_step, betaC, nBub) - deallocate (bub_id, px, py, pz, ppx, ppy, ppz, vx, vy, vz, radius, & - rvel, rnot, rmax, rmin, dphidt, pressure, mv, mg, & - betaT, betaC) + deallocate (bub_id, px, py, pz, ppx, ppy, ppz, vx, vy, vz, radius, rvel, rnot, rmax, rmin, dphidt, pressure, mv, mg, & + & betaT, betaC) deallocate (MPI_IO_DATA_lg_bubbles) else call MPI_TYPE_CONTIGUOUS(0, mpi_p, view, ierr) call MPI_TYPE_COMMIT(view, ierr) - call MPI_FILE_OPEN(MPI_COMM_WORLD, file_loc, MPI_MODE_RDONLY, & - mpi_info_int, ifile, ierr) + call MPI_FILE_OPEN(MPI_COMM_WORLD, file_loc, MPI_MODE_RDONLY, mpi_info_int, ifile, ierr) ! Skip extended header - disp = int(sizeof(file_tot_part) + 2*sizeof(file_time) + sizeof(file_num_procs) + & - file_num_procs*sizeof(proc_bubble_counts(1)), MPI_OFFSET_KIND) + disp = int(sizeof(file_tot_part) + 2*sizeof(file_time) + sizeof(file_num_procs) & + & + file_num_procs*sizeof(proc_bubble_counts(1)), MPI_OFFSET_KIND) call MPI_FILE_SET_VIEW(ifile, disp, mpi_p, view, 'native', mpi_info_int, ierr) call MPI_FILE_READ_ALL(ifile, dummy, 0, mpi_p, status, ierr) @@ -1406,23 +1163,16 @@ contains call MPI_TYPE_FREE(view, ierr) if (proc_rank == 0) then - do i = 1, num_procs - write (meshnames(i), '(A,I0,A,I0,A)') '../p', i - 1, & - '/', t_step, '.silo:lag_bubbles' + write (meshnames(i), '(A,I0,A,I0,A)') '../p', i - 1, '/', t_step, '.silo:lag_bubbles' meshtypes(i) = DB_POINTMESH end do err = DBSET2DSTRLEN(len(meshnames(1))) - err = DBPUTMMESH(dbroot, 'lag_bubbles', 16, & - num_procs, meshnames, & - len_trim(meshnames), & - meshtypes, DB_F77NULL, ierr) + err = DBPUTMMESH(dbroot, 'lag_bubbles', 16, num_procs, meshnames, len_trim(meshnames), meshtypes, DB_F77NULL, ierr) end if err = DBSETEMPTYOK(1) - err = DBPUTPM(dbfile, 'lag_bubbles', 11, 3, & - dummy_data, dummy_data, dummy_data, 0, & - DB_DOUBLE, DB_F77NULL, ierr) + err = DBPUTPM(dbfile, 'lag_bubbles', 11, 3, dummy_data, dummy_data, dummy_data, 0, DB_DOUBLE, DB_F77NULL, ierr) if (lag_id_wrt) call s_write_lag_variable_to_formatted_database_file('part_id', t_step) if (lag_vel_wrt) then @@ -1442,7 +1192,6 @@ contains if (lag_betaT_wrt) call s_write_lag_variable_to_formatted_database_file('part_betaT', t_step) if (lag_betaC_wrt) call s_write_lag_variable_to_formatted_database_file('part_betaC', t_step) end if - #endif end subroutine s_write_lag_bubbles_to_formatted_database_file @@ -1450,54 +1199,44 @@ contains !> @brief Write a single Lagrangian bubble point-variable to the Silo database slave and master files. subroutine s_write_lag_variable_to_formatted_database_file(varname, t_step, data, nBubs) - character(len=*), intent(in) :: varname - integer, intent(in) :: t_step + character(len=*), intent(in) :: varname + integer, intent(in) :: t_step real(wp), dimension(1:), intent(in), optional :: data - integer, intent(in), optional :: nBubs - - character(len=64), dimension(num_procs) :: var_names - integer, dimension(num_procs) :: var_types - real(wp) :: dummy_data - - integer :: ierr !< Generic flag used to identify and report database errors - integer :: i + integer, intent(in), optional :: nBubs + character(len=64), dimension(num_procs) :: var_names + integer, dimension(num_procs) :: var_types + real(wp) :: dummy_data + integer :: ierr !< Generic flag used to identify and report database errors + integer :: i dummy_data = 0._wp if (present(nBubs) .and. present(data)) then if (proc_rank == 0) then do i = 1, num_procs - write (var_names(i), '(A,I0,A,I0,A)') '../p', i - 1, & - '/', t_step, '.silo:'//trim(varname) + write (var_names(i), '(A,I0,A,I0,A)') '../p', i - 1, '/', t_step, '.silo:' // trim(varname) var_types(i) = DB_POINTVAR end do err = DBSET2DSTRLEN(len(var_names(1))) - err = DBPUTMVAR(dbroot, trim(varname), len_trim(varname), & - num_procs, var_names, & - len_trim(var_names), & - var_types, DB_F77NULL, ierr) + err = DBPUTMVAR(dbroot, trim(varname), len_trim(varname), num_procs, var_names, len_trim(var_names), var_types, & + & DB_F77NULL, ierr) end if - err = DBPUTPV1(dbfile, trim(varname), len_trim(varname), & - 'lag_bubbles', 11, data, nBubs, DB_DOUBLE, DB_F77NULL, ierr) + err = DBPUTPV1(dbfile, trim(varname), len_trim(varname), 'lag_bubbles', 11, data, nBubs, DB_DOUBLE, DB_F77NULL, ierr) else if (proc_rank == 0) then do i = 1, num_procs - write (var_names(i), '(A,I0,A,I0,A)') '../p', i - 1, & - '/', t_step, '.silo:'//trim(varname) + write (var_names(i), '(A,I0,A,I0,A)') '../p', i - 1, '/', t_step, '.silo:' // trim(varname) var_types(i) = DB_POINTVAR end do err = DBSET2DSTRLEN(len(var_names(1))) err = DBSETEMPTYOK(1) - err = DBPUTMVAR(dbroot, trim(varname), len_trim(varname), & - num_procs, var_names, & - len_trim(var_names), & - var_types, DB_F77NULL, ierr) + err = DBPUTMVAR(dbroot, trim(varname), len_trim(varname), num_procs, var_names, len_trim(var_names), var_types, & + & DB_F77NULL, ierr) end if err = DBSETEMPTYOK(1) - err = DBPUTPV1(dbfile, trim(varname), len_trim(varname), & - 'lag_bubbles', 11, dummy_data, 0, DB_DOUBLE, DB_F77NULL, ierr) + err = DBPUTPV1(dbfile, trim(varname), len_trim(varname), 'lag_bubbles', 11, dummy_data, 0, DB_DOUBLE, DB_F77NULL, ierr) end if end subroutine s_write_lag_variable_to_formatted_database_file @@ -1505,47 +1244,42 @@ contains impure subroutine s_write_ib_state_files() character(len=len_trim(case_dir) + 4*name_len) :: in_file, out_file, file_loc - integer :: iu_in, ios, i, rec_id - integer, allocatable, dimension(:) :: iu_out - real(wp) :: rec_time - real(wp), dimension(3) :: rec_force, rec_torque - real(wp), dimension(3) :: rec_vel, rec_angular_vel - real(wp), dimension(3) :: rec_angles, rec_centroid - - file_loc = trim(case_dir)//'/D' - - in_file = trim(file_loc)//'/ib_state.dat' - open (newunit=iu_in, file=trim(in_file), form='unformatted', access='stream', & - status='old', action='read', iostat=ios) + integer :: iu_in, ios, i, rec_id + integer, allocatable, dimension(:) :: iu_out + real(wp) :: rec_time + real(wp), dimension(3) :: rec_force, rec_torque + real(wp), dimension(3) :: rec_vel, rec_angular_vel + real(wp), dimension(3) :: rec_angles, rec_centroid + + file_loc = trim(case_dir) // '/D' + + in_file = trim(file_loc) // '/ib_state.dat' + open (newunit=iu_in, file=trim(in_file), form='unformatted', access='stream', status='old', action='read', iostat=ios) if (ios /= 0) then - call s_mpi_abort('Cannot open IB state input file: '//trim(in_file)) + call s_mpi_abort('Cannot open IB state input file: ' // trim(in_file)) end if allocate (iu_out(num_ibs)) do i = 1, num_ibs - write (out_file, '(A,I0,A)') trim(file_loc)//'/ib_', i, '.txt' + write (out_file, '(A,I0,A)') trim(file_loc) // '/ib_', i, '.txt' open (newunit=iu_out(i), file=trim(out_file), form='formatted', status='replace', action='write', iostat=ios) if (ios /= 0) then - call s_mpi_abort('Cannot open IB state output file: '//trim(out_file)) + call s_mpi_abort('Cannot open IB state output file: ' // trim(out_file)) end if - write (iu_out(i), '(A)') & - 'mytime fx fy fz Tau_x Tau_y Tau_z vx vy vz omega_x omega_y omega_z angle_x angle_y angle_z x_c y_c z_c' + write (iu_out(i), & + & '(A)') 'mytime fx fy fz Tau_x Tau_y Tau_z vx vy vz omega_x omega_y omega_z angle_x angle_y angle_z x_c y_c z_c' end do do - read (iu_in, iostat=ios) rec_time, rec_id, & - rec_force, rec_torque, rec_vel, rec_angular_vel, rec_angles, & - rec_centroid(1), rec_centroid(2), rec_centroid(3) + read (iu_in, iostat=ios) rec_time, rec_id, rec_force, rec_torque, rec_vel, rec_angular_vel, rec_angles, & + & rec_centroid(1), rec_centroid(2), rec_centroid(3) if (ios /= 0) exit if (rec_id >= 1 .and. rec_id <= num_ibs) then - write (iu_out(rec_id), '(19(ES24.16E3,1X))') rec_time, & - rec_force(1), rec_force(2), rec_force(3), & - rec_torque(1), rec_torque(2), rec_torque(3), & - rec_vel(1), rec_vel(2), rec_vel(3), & - rec_angular_vel(1), rec_angular_vel(2), rec_angular_vel(3), & - rec_angles(1), rec_angles(2), rec_angles(3), & - rec_centroid(1), rec_centroid(2), rec_centroid(3) + write (iu_out(rec_id), '(19(ES24.16E3,1X))') rec_time, rec_force(1), rec_force(2), rec_force(3), rec_torque(1), & + & rec_torque(2), rec_torque(3), rec_vel(1), rec_vel(2), rec_vel(3), rec_angular_vel(1), & + & rec_angular_vel(2), rec_angular_vel(3), rec_angles(1), rec_angles(2), rec_angles(3), rec_centroid(1), & + & rec_centroid(2), rec_centroid(3) end if end do @@ -1557,12 +1291,13 @@ contains end subroutine s_write_ib_state_files - !> @brief Extract the volume-fraction interface contour from primitive fields and write the coordinates to the interface data file. + !> @brief Extract the volume-fraction interface contour from primitive fields and write the coordinates to the interface data + !! file. impure subroutine s_write_intf_data_file(q_prim_vf) - type(scalar_field), dimension(sys_size), intent(IN) :: q_prim_vf - integer :: i, j, k, l, cent !< Generic loop iterators - integer :: counter, root !< number of data points extracted to fit shape to SH perturbations + type(scalar_field), dimension(sys_size), intent(in) :: q_prim_vf + integer :: i, j, k, l, cent !< Generic loop iterators + integer :: counter, root !< number of data points extracted to fit shape to SH perturbations real(wp), allocatable :: x_td(:), y_td(:), x_d1(:), y_d1(:), y_d(:), x_d(:) real(wp) :: axp, axm, ayp, aym, tgp, euc_d, thres, maxalph_loc, maxalph_glb @@ -1598,8 +1333,8 @@ contains axm = q_prim_vf(E_idx + 2)%sf(j, k, cent) ayp = q_prim_vf(E_idx + 2)%sf(j, k + 1, cent) aym = q_prim_vf(E_idx + 2)%sf(j, k, cent) - if ((axp > thres .and. axm < thres) .or. (axp < thres .and. axm > thres) & - .or. (ayp > thres .and. aym < thres) .or. (ayp < thres .and. aym > thres)) then + if ((axp > thres .and. axm < thres) .or. (axp < thres .and. axm > thres) .or. (ayp > thres .and. aym < thres) & + & .or. (ayp < thres .and. aym > thres)) then if (counter == 0) then counter = counter + 1 x_d1(counter) = x_cc(j) @@ -1610,7 +1345,7 @@ contains euc_d = sqrt((x_cc(j) - x_d1(i))**2 + (y_cc(k) - y_d1(i))**2) if (euc_d < tgp) then exit - elseif (i == counter) then + else if (i == counter) then counter = counter + 1 x_d1(counter) = x_cc(j) y_d1(counter) = y_cc(k) @@ -1634,25 +1369,25 @@ contains if (proc_rank == 0) then do i = 1, size(x_td) if (i == size(x_td)) then - write (211, '(F12.9,1X,F12.9,1X,I4)') & - x_td(i), y_td(i), size(x_td) + write (211, '(F12.9,1X,F12.9,1X,I4)') x_td(i), y_td(i), size(x_td) else - write (211, '(F12.9,1X,F12.9,1X,F3.1)') & - x_td(i), y_td(i), 0._wp + write (211, '(F12.9,1X,F12.9,1X,F3.1)') x_td(i), y_td(i), 0._wp end if end do end if end subroutine s_write_intf_data_file - !> @brief Compute volume-integrated kinetic, potential, and internal energies and write the energy budget to the energy data file. + !> @brief Compute volume-integrated kinetic, potential, and internal energies and write the energy budget to the energy data + !! file. impure subroutine s_write_energy_data_file(q_prim_vf, q_cons_vf) - type(scalar_field), dimension(sys_size), intent(IN) :: q_prim_vf, q_cons_vf + + type(scalar_field), dimension(sys_size), intent(in) :: q_prim_vf, q_cons_vf real(wp) :: Elk, Egk, Elp, Egint, Vb, Vl, pres_av, Et real(wp) :: rho, pres, dV, tmp, gamma, pi_inf, MaxMa, MaxMa_glb, maxvel, c, Ma, H, qv real(wp), dimension(num_vels) :: vel real(wp), dimension(num_fluids) :: adv - integer :: i, j, k, l, s !looping indices + integer :: i, j, k, l, s ! looping indices Egk = 0._wp Elp = 0._wp @@ -1698,9 +1433,7 @@ contains H = ((gamma + 1._wp)*pres + pi_inf + qv)/rho - call s_compute_speed_of_sound(pres, rho, & - gamma, pi_inf, & - H, adv, 0._wp, 0._wp, c, qv) + call s_compute_speed_of_sound(pres, rho, gamma, pi_inf, H, adv, 0._wp, 0._wp, c, qv) Ma = maxvel/c if (Ma > MaxMa .and. (adv(1) > (1.0_wp - 1.0e-10_wp))) then @@ -1733,36 +1466,24 @@ contains Elp = pres_av/Vl*Vb if (proc_rank == 0) then - write (251, '(10X, 8F24.8)') & - Elp, & - Egint, & - Elk, & - Egk, & - Et, & - Vb, & - Vl, & - MaxMa_glb + write (251, '(10X, 8F24.8)') Elp, Egint, Elk, Egk, Et, Vb, Vl, MaxMa_glb end if end subroutine s_write_energy_data_file !> @brief Close the formatted database slave file and, for the root process, the master file. impure subroutine s_close_formatted_database_file() - ! Description: The purpose of this subroutine is to close any formatted - ! database file(s) that may be opened at the time-step that - ! is currently being post-processed. The root process must - ! typically close two files, one associated with the local - ! sub-domain and the other with the entire domain. The non- - ! root process(es) must close one file, which is associated - ! with the local sub-domain. Note that for the Binary data- - ! base format and multidimensional data, the root process - ! only has to close the file associated with the local sub- - ! domain, because one associated with the entire domain is - ! not generated. - - integer :: ierr !< Generic flag used to identify and report database errors + + ! Description: The purpose of this subroutine is to close any formatted database file(s) that may be opened at the time-step + ! that is currently being post-processed. The root process must typically close two files, one associated with the local + ! sub-domain and the other with the entire domain. The non- root process(es) must close one file, which is associated with + ! the local sub-domain. Note that for the Binary data- base format and multidimensional data, the root process only has to + ! close the file associated with the local sub- domain, because one associated with the entire domain is not generated. + + integer :: ierr !< Generic flag used to identify and report database errors ! Silo-HDF5 database format + if (format == 1) then ierr = DBCLOSE(dbfile) if (proc_rank == 0) ierr = DBCLOSE(dbroot) @@ -1771,7 +1492,6 @@ contains else close (dbfile) if (n == 0 .and. proc_rank == 0) close (dbroot) - end if end subroutine s_close_formatted_database_file @@ -1792,21 +1512,20 @@ contains !> @brief Deallocate module arrays and release all data-output resources. impure subroutine s_finalize_data_output_module() + ! Description: Deallocation procedures for the module - ! Deallocating the generic storage employed for the flow variable(s) - ! that were written to the formatted database file(s). Note that the - ! root variable is only deallocated in the case of a 1D computation. + ! Deallocating the generic storage employed for the flow variable(s) that were written to the formatted database file(s). + ! Note that the root variable is only deallocated in the case of a 1D computation. deallocate (q_sf) if (n == 0) deallocate (q_root_sf) if (grid_geometry == 3) then deallocate (cyl_q_sf) end if - ! Deallocating spatial and data extents and also the variables for - ! the offsets and the one bookkeeping the number of cell-boundaries - ! in each active coordinate direction. Note that all these variables - ! were only needed by Silo-HDF5 format for multidimensional data. + ! Deallocating spatial and data extents and also the variables for the offsets and the one bookkeeping the number of + ! cell-boundaries in each active coordinate direction. Note that all these variables were only needed by Silo-HDF5 format + ! for multidimensional data. if (format == 1) then deallocate (spatial_extents) deallocate (data_extents) diff --git a/src/post_process/m_derived_variables.fpp b/src/post_process/m_derived_variables.fpp index 0407d06485..f3c2bef50e 100644 --- a/src/post_process/m_derived_variables.fpp +++ b/src/post_process/m_derived_variables.fpp @@ -6,101 +6,71 @@ module m_derived_variables - use m_derived_types !< Definitions of the derived types - - use m_global_parameters !< Global parameters for the code - - use m_mpi_proxy !< Message passing interface (MPI) module proxy - - use m_helper_basic !< Functions to compare floating point numbers - + use m_derived_types !< Definitions of the derived types + use m_global_parameters !< Global parameters for the code + use m_mpi_proxy !< Message passing interface (MPI) module proxy + use m_helper_basic !< Functions to compare floating point numbers use m_variables_conversion implicit none - private; public :: s_initialize_derived_variables_module, & - s_derive_specific_heat_ratio, & - s_derive_liquid_stiffness, & - s_derive_sound_speed, & - s_derive_flux_limiter, & - s_derive_vorticity_component, & - s_derive_qm, & - s_derive_liutex, & - s_derive_numerical_schlieren_function, & - s_compute_speed_of_sound, & - s_finalize_derived_variables_module - - real(wp), allocatable, dimension(:, :, :) :: gm_rho_sf !< - !! Gradient magnitude (gm) of the density for each cell of the computational - !! sub-domain. This variable is employed in the calculation of the numerical - !! Schlieren function. - - !> @name Finite-difference (fd) coefficients in x-, y- and z-coordinate directions. - !! Note that because sufficient boundary information is available for all the - !! active coordinate directions, the centered family of the finite-difference - !! schemes is used. + private; public :: s_initialize_derived_variables_module, s_derive_specific_heat_ratio, s_derive_liquid_stiffness, & + & s_derive_sound_speed, s_derive_flux_limiter, s_derive_vorticity_component, s_derive_qm, s_derive_liutex, & + & s_derive_numerical_schlieren_function, s_compute_speed_of_sound, s_finalize_derived_variables_module + + !> Gradient magnitude (gm) of the density for each cell of the computational sub-domain. This variable is employed in the + !! calculation of the numerical Schlieren function. + real(wp), allocatable, dimension(:,:,:) :: gm_rho_sf + + !> @name Finite-difference (fd) coefficients in x-, y- and z-coordinate directions. Note that because sufficient boundary + !! information is available for all the active coordinate directions, the centered family of the finite-difference schemes is + !! used. !> @{ - real(wp), allocatable, dimension(:, :), public :: fd_coeff_x - real(wp), allocatable, dimension(:, :), public :: fd_coeff_y - real(wp), allocatable, dimension(:, :), public :: fd_coeff_z + real(wp), allocatable, dimension(:,:), public :: fd_coeff_x + real(wp), allocatable, dimension(:,:), public :: fd_coeff_y + real(wp), allocatable, dimension(:,:), public :: fd_coeff_z !> @} - integer, private :: flg !< - !! Flagging (flg) variable used to annotate the dimensionality of the dataset - !! that is undergoing the post-process. A flag value of 1 indicates that the - !! dataset is 3D, while a flag value of 0 indicates that it is not. This flg - !! variable is necessary to avoid cycling through the third dimension of the - !! flow variable(s) when the simulation is not 3D and the size of the buffer - !! is non-zero. Note that a similar procedure does not have to be applied to - !! the second dimension since in 1D, the buffer size is always zero. + !> Flagging (flg) variable used to annotate the dimensionality of the dataset that is undergoing the post-process. A flag value + !! of 1 indicates that the dataset is 3D, while a flag value of 0 indicates that it is not. This flg variable is necessary to + !! avoid cycling through the third dimension of the flow variable(s) when the simulation is not 3D and the size of the buffer is + !! non-zero. Note that a similar procedure does not have to be applied to the second dimension since in 1D, the buffer size is + !! always zero. + integer, private :: flg contains - !> Computation of parameters, allocation procedures, and/or - !! any other tasks needed to properly setup the module + !> Computation of parameters, allocation procedures, and/or any other tasks needed to properly setup the module impure subroutine s_initialize_derived_variables_module - ! Allocating the gradient magnitude of the density variable provided - ! that numerical Schlieren function is outputted during post-process + ! Allocating the gradient magnitude of the density variable provided that numerical Schlieren function is outputted during + ! post-process if (schlieren_wrt) then - allocate (gm_rho_sf(-offset_x%beg:m + offset_x%end, & - -offset_y%beg:n + offset_y%end, & - -offset_z%beg:p + offset_z%end)) + allocate (gm_rho_sf(-offset_x%beg:m + offset_x%end,-offset_y%beg:n + offset_y%end,-offset_z%beg:p + offset_z%end)) end if - ! Allocating the variables which will store the coefficients of the - ! centered family of finite-difference schemes. Note that sufficient - ! space is allocated so that the coefficients up to any chosen order - ! of accuracy may be bookkept. However, if higher than fourth-order - ! accuracy coefficients are wanted, the formulae required to compute - ! these coefficients will have to be implemented in the subroutine - ! s_compute_finite_difference_coefficients. + ! Allocating the variables which will store the coefficients of the centered family of finite-difference schemes. Note that + ! sufficient space is allocated so that the coefficients up to any chosen order of accuracy may be bookkept. However, if + ! higher than fourth-order accuracy coefficients are wanted, the formulae required to compute these coefficients will have + ! to be implemented in the subroutine s_compute_finite_difference_coefficients. ! Allocating centered finite-difference coefficients in x-direction if (omega_wrt(2) .or. omega_wrt(3) .or. schlieren_wrt .or. liutex_wrt) then - allocate (fd_coeff_x(-fd_number:fd_number, & - -offset_x%beg:m + offset_x%end)) + allocate (fd_coeff_x(-fd_number:fd_number,-offset_x%beg:m + offset_x%end)) end if ! Allocating centered finite-difference coefficients in y-direction - if (omega_wrt(1) .or. omega_wrt(3) .or. liutex_wrt & - .or. & - (n > 0 .and. schlieren_wrt)) then - allocate (fd_coeff_y(-fd_number:fd_number, & - -offset_y%beg:n + offset_y%end)) + if (omega_wrt(1) .or. omega_wrt(3) .or. liutex_wrt .or. (n > 0 .and. schlieren_wrt)) then + allocate (fd_coeff_y(-fd_number:fd_number,-offset_y%beg:n + offset_y%end)) end if ! Allocating centered finite-difference coefficients in z-direction - if (omega_wrt(1) .or. omega_wrt(2) .or. liutex_wrt & - .or. & - (p > 0 .and. schlieren_wrt)) then - allocate (fd_coeff_z(-fd_number:fd_number, & - -offset_z%beg:p + offset_z%end)) + if (omega_wrt(1) .or. omega_wrt(2) .or. liutex_wrt .or. (p > 0 .and. schlieren_wrt)) then + allocate (fd_coeff_z(-fd_number:fd_number,-offset_z%beg:p + offset_z%end)) end if - ! Annotating the dimensionality of the dataset undergoing the post- - ! process. A flag value of 1 indicates that the dataset is 3D, while - ! a flag value of 0 indicates that it is not. + ! Annotating the dimensionality of the dataset undergoing the post- process. A flag value of 1 indicates that the dataset is + ! 3D, while a flag value of 0 indicates that it is not. if (p > 0) then flg = 1 else @@ -109,20 +79,15 @@ contains end subroutine s_initialize_derived_variables_module - !> This subroutine receives as input the specific heat ratio - !! function, gamma_sf, and derives from it the specific heat - !! ratio. The latter is stored in the derived flow quantity - !! storage variable, q_sf. - !! @param q_sf Specific heat ratio + !> This subroutine receives as input the specific heat ratio function, gamma_sf, and derives from it the specific heat ratio. + !! The latter is stored in the derived flow quantity storage variable, q_sf. + !! @param q_sf Specific heat ratio subroutine s_derive_specific_heat_ratio(q_sf) - real(wp), & - dimension(-offset_x%beg:m + offset_x%end, & - -offset_y%beg:n + offset_y%end, & - -offset_z%beg:p + offset_z%end), & - intent(inout) :: q_sf + real(wp), dimension(-offset_x%beg:m + offset_x%end,-offset_y%beg:n + offset_y%end,-offset_z%beg:p + offset_z%end), & + & intent(inout) :: q_sf - integer :: i, j, k !< Generic loop iterators + integer :: i, j, k !< Generic loop iterators ! Computing specific heat ratio from specific heat ratio function do k = -offset_z%beg, p + offset_z%end @@ -135,24 +100,19 @@ contains end subroutine s_derive_specific_heat_ratio - !> This subroutine admits as inputs the specific heat ratio - !! function and the liquid stiffness function, gamma_sf and - !! pi_inf_sf, respectively. These are used to calculate the - !! values of the liquid stiffness, which are stored in the - !! derived flow quantity storage variable, q_sf. - !! @param q_sf Liquid stiffness + !> This subroutine admits as inputs the specific heat ratio function and the liquid stiffness function, gamma_sf and pi_inf_sf, + !! respectively. These are used to calculate the values of the liquid stiffness, which are stored in the derived flow quantity + !! storage variable, q_sf. + !! @param q_sf Liquid stiffness subroutine s_derive_liquid_stiffness(q_sf) - real(wp), & - dimension(-offset_x%beg:m + offset_x%end, & - -offset_y%beg:n + offset_y%end, & - -offset_z%beg:p + offset_z%end), & - intent(inout) :: q_sf + real(wp), dimension(-offset_x%beg:m + offset_x%end,-offset_y%beg:n + offset_y%end,-offset_z%beg:p + offset_z%end), & + & intent(inout) :: q_sf - integer :: i, j, k !< Generic loop iterators + integer :: i, j, k !< Generic loop iterators - ! Calculating the values of the liquid stiffness from those of the - ! specific heat ratio function and the liquid stiffness function + ! Calculating the values of the liquid stiffness from those of the specific heat ratio function and the liquid stiffness + ! function do k = -offset_z%beg, p + offset_z%end do j = -offset_y%beg, n + offset_y%end do i = -offset_x%beg, m + offset_x%end @@ -163,49 +123,37 @@ contains end subroutine s_derive_liquid_stiffness - !> This subroutine admits as inputs the primitive variables, - !! the density, the specific heat ratio function and liquid - !! stiffness function. It then computes from those variables - !! the values of the speed of sound, which are stored in the - !! derived flow quantity storage variable, q_sf. - !! @param q_prim_vf Primitive variables - !! @param q_sf Speed of sound + !> This subroutine admits as inputs the primitive variables, the density, the specific heat ratio function and liquid stiffness + !! function. It then computes from those variables the values of the speed of sound, which are stored in the derived flow + !! quantity storage variable, q_sf. + !! @param q_prim_vf Primitive variables + !! @param q_sf Speed of sound subroutine s_derive_sound_speed(q_prim_vf, q_sf) - type(scalar_field), & - dimension(sys_size), & - intent(in) :: q_prim_vf + type(scalar_field), dimension(sys_size), intent(in) :: q_prim_vf - real(wp), & - dimension(-offset_x%beg:m + offset_x%end, & - -offset_y%beg:n + offset_y%end, & - -offset_z%beg:p + offset_z%end), & - intent(inout) :: q_sf + real(wp), dimension(-offset_x%beg:m + offset_x%end,-offset_y%beg:n + offset_y%end,-offset_z%beg:p + offset_z%end), & + & intent(inout) :: q_sf - integer :: i, j, k !< Generic loop iterators + integer :: i, j, k !< Generic loop iterators ! Fluid bulk modulus for alternate sound speed real(wp) :: blkmod1, blkmod2 - ! Computing speed of sound values from those of pressure, density, - ! specific heat ratio function and the liquid stiffness function + ! Computing speed of sound values from those of pressure, density, specific heat ratio function and the liquid stiffness + ! function do k = -offset_z%beg, p + offset_z%end do j = -offset_y%beg, n + offset_y%end do i = -offset_x%beg, m + offset_x%end - ! Compute mixture sound speed if (alt_soundspeed .neqv. .true.) then - q_sf(i, j, k) = (((gamma_sf(i, j, k) + 1._wp)* & - q_prim_vf(E_idx)%sf(i, j, k) + & - pi_inf_sf(i, j, k))/(gamma_sf(i, j, k)* & - rho_sf(i, j, k))) + q_sf(i, j, k) = (((gamma_sf(i, j, k) + 1._wp)*q_prim_vf(E_idx)%sf(i, j, k) + pi_inf_sf(i, j, & + & k))/(gamma_sf(i, j, k)*rho_sf(i, j, k))) else - blkmod1 = ((gammas(1) + 1._wp)*q_prim_vf(E_idx)%sf(i, j, k) + & - pi_infs(1))/gammas(1) - blkmod2 = ((gammas(2) + 1._wp)*q_prim_vf(E_idx)%sf(i, j, k) + & - pi_infs(2))/gammas(2) - q_sf(i, j, k) = (1._wp/(rho_sf(i, j, k)*(q_prim_vf(adv_idx%beg)%sf(i, j, k)/blkmod1 + & - (1._wp - q_prim_vf(adv_idx%beg)%sf(i, j, k))/blkmod2))) + blkmod1 = ((gammas(1) + 1._wp)*q_prim_vf(E_idx)%sf(i, j, k) + pi_infs(1))/gammas(1) + blkmod2 = ((gammas(2) + 1._wp)*q_prim_vf(E_idx)%sf(i, j, k) + pi_infs(2))/gammas(2) + q_sf(i, j, k) = (1._wp/(rho_sf(i, j, k)*(q_prim_vf(adv_idx%beg)%sf(i, j, & + & k)/blkmod1 + (1._wp - q_prim_vf(adv_idx%beg)%sf(i, j, k))/blkmod2))) end if if (mixture_err .and. q_sf(i, j, k) < 0._wp) then @@ -219,66 +167,49 @@ contains end subroutine s_derive_sound_speed - !> This subroutine derives the flux_limiter at cell boundary - !! i+1/2. This is an approximation because the velocity used - !! to determine the upwind direction is the velocity at the - !! cell center i instead of the contact velocity at the cell - !! boundary from the Riemann solver. - !! @param i Component indicator - !! @param q_prim_vf Primitive variables - !! @param q_sf Flux limiter + !> This subroutine derives the flux_limiter at cell boundary i+1/2. This is an approximation because the velocity used to + !! determine the upwind direction is the velocity at the cell center i instead of the contact velocity at the cell boundary from + !! the Riemann solver. + !! @param i Component indicator + !! @param q_prim_vf Primitive variables + !! @param q_sf Flux limiter subroutine s_derive_flux_limiter(i, q_prim_vf, q_sf) - integer, intent(in) :: i - + integer, intent(in) :: i type(scalar_field), dimension(sys_size), intent(in) :: q_prim_vf - real(wp), dimension(-offset_x%beg:m + offset_x%end, & - -offset_y%beg:n + offset_y%end, & - -offset_z%beg:p + offset_z%end), & - intent(inout) :: q_sf + real(wp), dimension(-offset_x%beg:m + offset_x%end,-offset_y%beg:n + offset_y%end,-offset_z%beg:p + offset_z%end), & + & intent(inout) :: q_sf - real(wp) :: top, bottom, slope !< Flux limiter calcs - integer :: j, k, l !< Generic loop iterators + real(wp) :: top, bottom, slope !< Flux limiter calcs + integer :: j, k, l !< Generic loop iterators do l = -offset_z%beg, p + offset_z%end do k = -offset_y%beg, n + offset_y%end do j = -offset_x%beg, m + offset_x%end if (i == 1) then if (q_prim_vf(cont_idx%end + i)%sf(j, k, l) >= 0._wp) then - top = q_prim_vf(adv_idx%beg)%sf(j, k, l) - & - q_prim_vf(adv_idx%beg)%sf(j - 1, k, l) - bottom = q_prim_vf(adv_idx%beg)%sf(j + 1, k, l) - & - q_prim_vf(adv_idx%beg)%sf(j, k, l) + top = q_prim_vf(adv_idx%beg)%sf(j, k, l) - q_prim_vf(adv_idx%beg)%sf(j - 1, k, l) + bottom = q_prim_vf(adv_idx%beg)%sf(j + 1, k, l) - q_prim_vf(adv_idx%beg)%sf(j, k, l) else - top = q_prim_vf(adv_idx%beg)%sf(j + 2, k, l) - & - q_prim_vf(adv_idx%beg)%sf(j + 1, k, l) - bottom = q_prim_vf(adv_idx%beg)%sf(j + 1, k, l) - & - q_prim_vf(adv_idx%beg)%sf(j, k, l) + top = q_prim_vf(adv_idx%beg)%sf(j + 2, k, l) - q_prim_vf(adv_idx%beg)%sf(j + 1, k, l) + bottom = q_prim_vf(adv_idx%beg)%sf(j + 1, k, l) - q_prim_vf(adv_idx%beg)%sf(j, k, l) end if - elseif (i == 2) then + else if (i == 2) then if (q_prim_vf(cont_idx%end + i)%sf(j, k, l) >= 0._wp) then - top = q_prim_vf(adv_idx%beg)%sf(j, k, l) - & - q_prim_vf(adv_idx%beg)%sf(j, k - 1, l) - bottom = q_prim_vf(adv_idx%beg)%sf(j, k + 1, l) - & - q_prim_vf(adv_idx%beg)%sf(j, k, l) + top = q_prim_vf(adv_idx%beg)%sf(j, k, l) - q_prim_vf(adv_idx%beg)%sf(j, k - 1, l) + bottom = q_prim_vf(adv_idx%beg)%sf(j, k + 1, l) - q_prim_vf(adv_idx%beg)%sf(j, k, l) else - top = q_prim_vf(adv_idx%beg)%sf(j, k + 2, l) - & - q_prim_vf(adv_idx%beg)%sf(j, k + 1, l) - bottom = q_prim_vf(adv_idx%beg)%sf(j, k + 1, l) - & - q_prim_vf(adv_idx%beg)%sf(j, k, l) + top = q_prim_vf(adv_idx%beg)%sf(j, k + 2, l) - q_prim_vf(adv_idx%beg)%sf(j, k + 1, l) + bottom = q_prim_vf(adv_idx%beg)%sf(j, k + 1, l) - q_prim_vf(adv_idx%beg)%sf(j, k, l) end if else if (q_prim_vf(cont_idx%end + i)%sf(j, k, l) >= 0._wp) then - top = q_prim_vf(adv_idx%beg)%sf(j, k, l) - & - q_prim_vf(adv_idx%beg)%sf(j, k, l - 1) - bottom = q_prim_vf(adv_idx%beg)%sf(j, k, l + 1) - & - q_prim_vf(adv_idx%beg)%sf(j, k, l) + top = q_prim_vf(adv_idx%beg)%sf(j, k, l) - q_prim_vf(adv_idx%beg)%sf(j, k, l - 1) + bottom = q_prim_vf(adv_idx%beg)%sf(j, k, l + 1) - q_prim_vf(adv_idx%beg)%sf(j, k, l) else - top = q_prim_vf(adv_idx%beg)%sf(j, k, l + 2) - & - q_prim_vf(adv_idx%beg)%sf(j, k, l + 1) - bottom = q_prim_vf(adv_idx%beg)%sf(j, k, l + 1) - & - q_prim_vf(adv_idx%beg)%sf(j, k, l) + top = q_prim_vf(adv_idx%beg)%sf(j, k, l + 2) - q_prim_vf(adv_idx%beg)%sf(j, k, l + 1) + bottom = q_prim_vf(adv_idx%beg)%sf(j, k, l + 1) - q_prim_vf(adv_idx%beg)%sf(j, k, l) end if end if @@ -287,68 +218,67 @@ contains if (f_approx_equal(top, bottom)) then slope = 1._wp - ! ELSEIF((top == 0._wp .AND. bottom /= 0._wp) & - ! .OR. & - ! (bottom == 0._wp .AND. top /= 0._wp)) THEN - ! slope = 0._wp + ! ELSEIF((top == 0._wp .AND. bottom /= 0._wp) & .OR. & (bottom == 0._wp .AND. top /= 0._wp)) THEN slope = + ! 0._wp else slope = (top*bottom)/(bottom**2._wp + 1.e-16_wp) end if ! Flux limiter function - if (flux_lim == 1) then ! MINMOD (MM) + if (flux_lim == 1) then ! MINMOD (MM) q_sf(j, k, l) = max(0._wp, min(1._wp, slope)) - elseif (flux_lim == 2) then ! MUSCL (MC) + else if (flux_lim == 2) then ! MUSCL (MC) q_sf(j, k, l) = max(0._wp, min(2._wp*slope, 5.e-1_wp*(1._wp + slope), 2._wp)) - elseif (flux_lim == 3) then ! OSPRE (OP) + else if (flux_lim == 3) then ! OSPRE (OP) q_sf(j, k, l) = (15.e-1_wp*(slope**2._wp + slope))/(slope**2._wp + slope + 1._wp) - elseif (flux_lim == 4) then ! SUPERBEE (SB) + else if (flux_lim == 4) then ! SUPERBEE (SB) q_sf(j, k, l) = max(0._wp, min(1._wp, 2._wp*slope), min(slope, 2._wp)) - elseif (flux_lim == 5) then ! SWEBY (SW) (beta = 1.5) + else if (flux_lim == 5) then ! SWEBY (SW) (beta = 1.5) q_sf(j, k, l) = max(0._wp, min(15.e-1_wp*slope, 1._wp), min(slope, 15.e-1_wp)) - elseif (flux_lim == 6) then ! VAN ALBADA (VA) + else if (flux_lim == 6) then ! VAN ALBADA (VA) q_sf(j, k, l) = (slope**2._wp + slope)/(slope**2._wp + 1._wp) - elseif (flux_lim == 7) then ! VAN LEER (VL) + else if (flux_lim == 7) then ! VAN LEER (VL) q_sf(j, k, l) = (abs(slope) + slope)/(1._wp + abs(slope)) end if end do end do end do + end subroutine s_derive_flux_limiter - !> Computes the solution to the linear system Ax=b w/ sol = x - !! @param A Input matrix - !! @param b right-hane-side - !! @param sol Solution - !! @param ndim Problem size + !> Computes the solution to the linear system Ax=b w/ sol = x + !! @param A Input matrix + !! @param b right-hane-side + !! @param sol Solution + !! @param ndim Problem size subroutine s_solve_linear_system(A, b, sol, ndim) - integer, intent(in) :: ndim + integer, intent(in) :: ndim real(wp), dimension(ndim, ndim), intent(inout) :: A - real(wp), dimension(ndim), intent(inout) :: b - real(wp), dimension(ndim), intent(out) :: sol + real(wp), dimension(ndim), intent(inout) :: b + real(wp), dimension(ndim), intent(out) :: sol - !EXTERNAL DGESV + ! EXTERNAL DGESV integer :: i, j, k - ! Solve linear system using own linear solver (Thomson/Darter/Comet/Stampede) - ! Forward elimination + ! Solve linear system using own linear solver (Thomson/Darter/Comet/Stampede) Forward elimination + do i = 1, ndim ! Pivoting - j = i - 1 + maxloc(abs(A(i:ndim, i)), 1) - sol = A(i, :) - A(i, :) = A(j, :) - A(j, :) = sol + j = i - 1 + maxloc(abs(A(i:ndim,i)), 1) + sol = A(i,:) + A(i,:) = A(j,:) + A(j,:) = sol sol(1) = b(i) b(i) = b(j) b(j) = sol(1) ! Elimination b(i) = b(i)/A(i, i) - A(i, :) = A(i, :)/A(i, i) + A(i,:) = A(i,:)/A(i, i) do k = i + 1, ndim b(k) = b(k) - A(k, i)*b(i) - A(k, :) = A(k, :) - A(k, i)*A(i, :) + A(k,:) = A(k,:) - A(k, i)*A(i,:) end do end do @@ -362,84 +292,59 @@ contains end subroutine s_solve_linear_system - !> This subroutine receives as inputs the indicator of the - !! component of the vorticity that should be outputted and - !! the primitive variables. From those inputs, it proceeds - !! to calculate values of the desired vorticity component, - !! which are subsequently stored in derived flow quantity - !! storage variable, q_sf. - !! @param i Vorticity component indicator - !! @param q_prim_vf Primitive variables - !! @param q_sf Vorticity component + !> This subroutine receives as inputs the indicator of the component of the vorticity that should be outputted and the primitive + !! variables. From those inputs, it proceeds to calculate values of the desired vorticity component, which are subsequently + !! stored in derived flow quantity storage variable, q_sf. + !! @param i Vorticity component indicator + !! @param q_prim_vf Primitive variables + !! @param q_sf Vorticity component subroutine s_derive_vorticity_component(i, q_prim_vf, q_sf) - integer, intent(in) :: i - - type(scalar_field), & - dimension(sys_size), & - intent(in) :: q_prim_vf + integer, intent(in) :: i + type(scalar_field), dimension(sys_size), intent(in) :: q_prim_vf - real(wp), & - dimension(-offset_x%beg:m + offset_x%end, & - -offset_y%beg:n + offset_y%end, & - -offset_z%beg:p + offset_z%end), & - intent(inout) :: q_sf + real(wp), dimension(-offset_x%beg:m + offset_x%end,-offset_y%beg:n + offset_y%end,-offset_z%beg:p + offset_z%end), & + & intent(inout) :: q_sf - integer :: j, k, l, r !< Generic loop iterators + integer :: j, k, l, r !< Generic loop iterators ! Computing the vorticity component in the x-coordinate direction if (i == 1) then do l = -offset_z%beg, p + offset_z%end do k = -offset_y%beg, n + offset_y%end do j = -offset_x%beg, m + offset_x%end - q_sf(j, k, l) = 0._wp do r = -fd_number, fd_number if (grid_geometry == 3) then - q_sf(j, k, l) = & - q_sf(j, k, l) + 1._wp/y_cc(k)* & - (fd_coeff_y(r, k)*y_cc(r + k)* & - q_prim_vf(mom_idx%end)%sf(j, r + k, l) & - - fd_coeff_z(r, l)* & - q_prim_vf(mom_idx%beg + 1)%sf(j, k, r + l)) + q_sf(j, k, l) = q_sf(j, k, l) + 1._wp/y_cc(k)*(fd_coeff_y(r, & + & k)*y_cc(r + k)*q_prim_vf(mom_idx%end)%sf(j, r + k, l) - fd_coeff_z(r, & + & l)*q_prim_vf(mom_idx%beg + 1)%sf(j, k, r + l)) else - q_sf(j, k, l) = & - q_sf(j, k, l) + fd_coeff_y(r, k)* & - q_prim_vf(mom_idx%end)%sf(j, r + k, l) & - - fd_coeff_z(r, l)* & - q_prim_vf(mom_idx%beg + 1)%sf(j, k, r + l) + q_sf(j, k, l) = q_sf(j, k, l) + fd_coeff_y(r, k)*q_prim_vf(mom_idx%end)%sf(j, r + k, & + & l) - fd_coeff_z(r, l)*q_prim_vf(mom_idx%beg + 1)%sf(j, k, r + l) end if end do - end do end do end do ! Computing the vorticity component in the y-coordinate direction - elseif (i == 2) then + else if (i == 2) then do l = -offset_z%beg, p + offset_z%end do k = -offset_y%beg, n + offset_y%end do j = -offset_x%beg, m + offset_x%end - q_sf(j, k, l) = 0._wp do r = -fd_number, fd_number if (grid_geometry == 3) then - q_sf(j, k, l) = & - q_sf(j, k, l) + fd_coeff_z(r, l)/y_cc(k)* & - q_prim_vf(mom_idx%beg)%sf(j, k, r + l) & - - fd_coeff_x(r, j)* & - q_prim_vf(mom_idx%end)%sf(r + j, k, l) + q_sf(j, k, l) = q_sf(j, k, l) + fd_coeff_z(r, l)/y_cc(k)*q_prim_vf(mom_idx%beg)%sf(j, k, & + & r + l) - fd_coeff_x(r, j)*q_prim_vf(mom_idx%end)%sf(r + j, k, l) else - q_sf(j, k, l) = & - q_sf(j, k, l) + fd_coeff_z(r, l)* & - q_prim_vf(mom_idx%beg)%sf(j, k, r + l) & - - fd_coeff_x(r, j)* & - q_prim_vf(mom_idx%end)%sf(r + j, k, l) + q_sf(j, k, l) = q_sf(j, k, l) + fd_coeff_z(r, l)*q_prim_vf(mom_idx%beg)%sf(j, k, & + & r + l) - fd_coeff_x(r, j)*q_prim_vf(mom_idx%end)%sf(r + j, k, l) end if end do - end do end do end do @@ -449,17 +354,12 @@ contains do l = -offset_z%beg, p + offset_z%end do k = -offset_y%beg, n + offset_y%end do j = -offset_x%beg, m + offset_x%end - q_sf(j, k, l) = 0._wp do r = -fd_number, fd_number - q_sf(j, k, l) = & - q_sf(j, k, l) + fd_coeff_x(r, j)* & - q_prim_vf(mom_idx%beg + 1)%sf(r + j, k, l) & - - fd_coeff_y(r, k)* & - q_prim_vf(mom_idx%beg)%sf(j, r + k, l) + q_sf(j, k, l) = q_sf(j, k, l) + fd_coeff_x(r, j)*q_prim_vf(mom_idx%beg + 1)%sf(r + j, k, & + & l) - fd_coeff_y(r, k)*q_prim_vf(mom_idx%beg)%sf(j, r + k, l) end do - end do end do end do @@ -467,156 +367,114 @@ contains end subroutine s_derive_vorticity_component - !> This subroutine gets as inputs the primitive variables. From those - !! inputs, it proceeds to calculate the value of the Q_M - !! function, which are subsequently stored in the derived flow - !! quantity storage variable, q_sf. - !! @param q_prim_vf Primitive variables - !! @param q_sf Q_M + !> This subroutine gets as inputs the primitive variables. From those inputs, it proceeds to calculate the value of the Q_M + !! function, which are subsequently stored in the derived flow quantity storage variable, q_sf. + !! @param q_prim_vf Primitive variables + !! @param q_sf Q_M subroutine s_derive_qm(q_prim_vf, q_sf) - type(scalar_field), & - dimension(sys_size), & - intent(in) :: q_prim_vf - real(wp), & - dimension(-offset_x%beg:m + offset_x%end, & - -offset_y%beg:n + offset_y%end, & - -offset_z%beg:p + offset_z%end), & - intent(inout) :: q_sf + type(scalar_field), dimension(sys_size), intent(in) :: q_prim_vf - real(wp), & - dimension(1:3, 1:3) :: q_jacobian_sf, S, S2, O, O2 + real(wp), dimension(-offset_x%beg:m + offset_x%end,-offset_y%beg:n + offset_y%end,-offset_z%beg:p + offset_z%end), & + & intent(inout) :: q_sf - real(wp) :: trS, Q, IIS - integer :: j, k, l, r, jj, kk !< Generic loop iterators + real(wp), dimension(1:3,1:3) :: q_jacobian_sf, S, S2, O, O2 + real(wp) :: trS, Q, IIS + integer :: j, k, l, r, jj, kk !< Generic loop iterators do l = -offset_z%beg, p + offset_z%end do k = -offset_y%beg, n + offset_y%end do j = -offset_x%beg, m + offset_x%end - ! Get velocity gradient tensor - q_jacobian_sf(:, :) = 0._wp + q_jacobian_sf(:,:) = 0._wp do r = -fd_number, fd_number do jj = 1, 3 ! d()/dx - q_jacobian_sf(jj, 1) = & - q_jacobian_sf(jj, 1) + & - fd_coeff_x(r, j)* & - q_prim_vf(mom_idx%beg + jj - 1)%sf(r + j, k, l) + q_jacobian_sf(jj, 1) = q_jacobian_sf(jj, 1) + fd_coeff_x(r, & + & j)*q_prim_vf(mom_idx%beg + jj - 1)%sf(r + j, k, l) ! d()/dy - q_jacobian_sf(jj, 2) = & - q_jacobian_sf(jj, 2) + & - fd_coeff_y(r, k)* & - q_prim_vf(mom_idx%beg + jj - 1)%sf(j, r + k, l) + q_jacobian_sf(jj, 2) = q_jacobian_sf(jj, 2) + fd_coeff_y(r, k)*q_prim_vf(mom_idx%beg + jj - 1)%sf(j, & + & r + k, l) ! d()/dz - q_jacobian_sf(jj, 3) = & - q_jacobian_sf(jj, 3) + & - fd_coeff_z(r, l)* & - q_prim_vf(mom_idx%beg + jj - 1)%sf(j, k, r + l) + q_jacobian_sf(jj, 3) = q_jacobian_sf(jj, 3) + fd_coeff_z(r, l)*q_prim_vf(mom_idx%beg + jj - 1)%sf(j, & + & k, r + l) end do end do ! Decompose J into asymmetric matrix, S, and a skew-symmetric matrix, O do jj = 1, 3 do kk = 1, 3 - S(jj, kk) = 0.5_wp* & - (q_jacobian_sf(jj, kk) + q_jacobian_sf(kk, jj)) - O(jj, kk) = 0.5_wp* & - (q_jacobian_sf(jj, kk) - q_jacobian_sf(kk, jj)) + S(jj, kk) = 0.5_wp*(q_jacobian_sf(jj, kk) + q_jacobian_sf(kk, jj)) + O(jj, kk) = 0.5_wp*(q_jacobian_sf(jj, kk) - q_jacobian_sf(kk, jj)) end do end do ! Compute S2 = S*S' do jj = 1, 3 do kk = 1, 3 - O2(jj, kk) = O(jj, 1)*O(kk, 1) + & - O(jj, 2)*O(kk, 2) + & - O(jj, 3)*O(kk, 3) - S2(jj, kk) = S(jj, 1)*S(kk, 1) + & - S(jj, 2)*S(kk, 2) + & - S(jj, 3)*S(kk, 3) + O2(jj, kk) = O(jj, 1)*O(kk, 1) + O(jj, 2)*O(kk, 2) + O(jj, 3)*O(kk, 3) + S2(jj, kk) = S(jj, 1)*S(kk, 1) + S(jj, 2)*S(kk, 2) + S(jj, 3)*S(kk, 3) end do end do ! Compute Q - Q = 0.5_wp*((O2(1, 1) + O2(2, 2) + O2(3, 3)) - & - (S2(1, 1) + S2(2, 2) + S2(3, 3))) + Q = 0.5_wp*((O2(1, 1) + O2(2, 2) + O2(3, 3)) - (S2(1, 1) + S2(2, 2) + S2(3, 3))) trS = S(1, 1) + S(2, 2) + S(3, 3) - IIS = 0.5_wp*((S(1, 1) + S(2, 2) + S(3, 3))**2 - & - (S2(1, 1) + S2(2, 2) + S2(3, 3))) + IIS = 0.5_wp*((S(1, 1) + S(2, 2) + S(3, 3))**2 - (S2(1, 1) + S2(2, 2) + S2(3, 3))) q_sf(j, k, l) = Q + IIS - end do end do end do end subroutine s_derive_qm - !> This subroutine gets as inputs the primitive variables. From those - !! inputs, it proceeds to calculate the Liutex vector and its - !! magnitude based on Xu et al. (2019). - !! @param q_prim_vf Primitive variables + !> This subroutine gets as inputs the primitive variables. From those inputs, it proceeds to calculate the Liutex vector and its + !! magnitude based on Xu et al. (2019). + !! @param q_prim_vf Primitive variables impure subroutine s_derive_liutex(q_prim_vf, liutex_mag, liutex_axis) - integer, parameter :: nm = 3 - type(scalar_field), & - dimension(sys_size), & - intent(in) :: q_prim_vf - - real(wp), & - dimension(-offset_x%beg:m + offset_x%end, & - -offset_y%beg:n + offset_y%end, & - -offset_z%beg:p + offset_z%end), & - intent(out) :: liutex_mag !< Liutex magnitude - - real(wp), & - dimension(-offset_x%beg:m + offset_x%end, & - -offset_y%beg:n + offset_y%end, & - -offset_z%beg:p + offset_z%end, nm), & - intent(out) :: liutex_axis !< Liutex rigid rotation axis - - character, parameter :: ivl = 'N' !< compute left eigenvectors - character, parameter :: ivr = 'V' !< compute right eigenvectors - real(wp), dimension(nm, nm) :: vgt !< velocity gradient tensor - real(wp), dimension(nm) :: lr, li !< real and imaginary parts of eigenvalues - real(wp), dimension(nm, nm) :: vl, vr !< left and right eigenvectors - integer, parameter :: lwork = 4*nm !< size of work array (4*nm recommended) - real(wp), dimension(lwork) :: work !< work array - integer :: info - - real(wp), dimension(nm) :: eigvec !< real eigenvector - real(wp) :: eigvec_mag !< magnitude of real eigenvector - real(wp) :: omega_proj !< projection of vorticity on real eigenvector - real(wp) :: lci !< imaginary part of complex eigenvalue - real(wp) :: alpha - - integer :: j, k, l, r, i !< Generic loop iterators - integer :: idx + + integer, parameter :: nm = 3 + type(scalar_field), dimension(sys_size), intent(in) :: q_prim_vf + + !> Liutex magnitude + real(wp), dimension(-offset_x%beg:m + offset_x%end,-offset_y%beg:n + offset_y%end,-offset_z%beg:p + offset_z%end), & + & intent(out) :: liutex_mag + + !> Liutex rigid rotation axis + real(wp), dimension(-offset_x%beg:m + offset_x%end,-offset_y%beg:n + offset_y%end,-offset_z%beg:p + offset_z%end,nm), & + & intent(out) :: liutex_axis + + character, parameter :: ivl = 'N' !< compute left eigenvectors + character, parameter :: ivr = 'V' !< compute right eigenvectors + real(wp), dimension(nm, nm) :: vgt !< velocity gradient tensor + real(wp), dimension(nm) :: lr, li !< real and imaginary parts of eigenvalues + real(wp), dimension(nm, nm) :: vl, vr !< left and right eigenvectors + integer, parameter :: lwork = 4*nm !< size of work array (4*nm recommended) + real(wp), dimension(lwork) :: work !< work array + integer :: info + real(wp), dimension(nm) :: eigvec !< real eigenvector + real(wp) :: eigvec_mag !< magnitude of real eigenvector + real(wp) :: omega_proj !< projection of vorticity on real eigenvector + real(wp) :: lci !< imaginary part of complex eigenvalue + real(wp) :: alpha + integer :: j, k, l, r, i !< Generic loop iterators + integer :: idx do l = -offset_z%beg, p + offset_z%end do k = -offset_y%beg, n + offset_y%end do j = -offset_x%beg, m + offset_x%end - ! Get velocity gradient tensor (VGT) - vgt(:, :) = 0._wp + vgt(:,:) = 0._wp do r = -fd_number, fd_number do i = 1, 3 ! d()/dx - vgt(i, 1) = & - vgt(i, 1) + & - fd_coeff_x(r, j)* & - q_prim_vf(mom_idx%beg + i - 1)%sf(r + j, k, l) + vgt(i, 1) = vgt(i, 1) + fd_coeff_x(r, j)*q_prim_vf(mom_idx%beg + i - 1)%sf(r + j, k, l) ! d()/dy - vgt(i, 2) = & - vgt(i, 2) + & - fd_coeff_y(r, k)* & - q_prim_vf(mom_idx%beg + i - 1)%sf(j, r + k, l) + vgt(i, 2) = vgt(i, 2) + fd_coeff_y(r, k)*q_prim_vf(mom_idx%beg + i - 1)%sf(j, r + k, l) ! d()/dz - vgt(i, 3) = & - vgt(i, 3) + & - fd_coeff_z(r, l)* & - q_prim_vf(mom_idx%beg + i - 1)%sf(j, k, r + l) + vgt(i, 3) = vgt(i, 3) + fd_coeff_z(r, l)*q_prim_vf(mom_idx%beg + i - 1)%sf(j, k, r + l) end do end do @@ -634,12 +492,10 @@ contains idx = r end if end do - eigvec = vr(:, idx) + eigvec = vr(:,idx) ! Normalize real eigenvector if it is effectively non-zero - eigvec_mag = sqrt(eigvec(1)**2._wp & - + eigvec(2)**2._wp & - + eigvec(3)**2._wp) + eigvec_mag = sqrt(eigvec(1)**2._wp + eigvec(2)**2._wp + eigvec(3)**2._wp) if (eigvec_mag > sgm_eps) then eigvec = eigvec/eigvec_mag else @@ -647,12 +503,10 @@ contains end if ! Compute vorticity projected on the eigenvector - omega_proj = (vgt(3, 2) - vgt(2, 3))*eigvec(1) & - + (vgt(1, 3) - vgt(3, 1))*eigvec(2) & - + (vgt(2, 1) - vgt(1, 2))*eigvec(3) + omega_proj = (vgt(3, 2) - vgt(2, 3))*eigvec(1) + (vgt(1, 3) - vgt(3, 1))*eigvec(2) + (vgt(2, 1) - vgt(1, & + & 2))*eigvec(3) - ! As eigenvector can have +/- signs, we can choose the sign - ! so that omega_proj is positive + ! As eigenvector can have +/- signs, we can choose the sign so that omega_proj is positive if (omega_proj < 0._wp) then eigvec = -eigvec omega_proj = -omega_proj @@ -662,7 +516,7 @@ contains lci = li(mod(idx, 3) + 1) ! Compute Liutex magnitude - alpha = omega_proj**2._wp - 4._wp*lci**2._wp ! (2*alpha)^2 + alpha = omega_proj**2._wp - 4._wp*lci**2._wp ! (2*alpha)^2 if (alpha > 0._wp) then liutex_mag(j, k, l) = omega_proj - sqrt(alpha) else @@ -673,42 +527,30 @@ contains liutex_axis(j, k, l, 1) = eigvec(1) liutex_axis(j, k, l, 2) = eigvec(2) liutex_axis(j, k, l, 3) = eigvec(3) - end do end do end do end subroutine s_derive_liutex - !> This subroutine gets as inputs the conservative variables - !! and density. From those inputs, it proceeds to calculate - !! the values of the numerical Schlieren function, which are - !! subsequently stored in the derived flow quantity storage - !! variable, q_sf. - !! @param q_cons_vf Conservative variables - !! @param q_sf Numerical Schlieren function + !> This subroutine gets as inputs the conservative variables and density. From those inputs, it proceeds to calculate the values + !! of the numerical Schlieren function, which are subsequently stored in the derived flow quantity storage variable, q_sf. + !! @param q_cons_vf Conservative variables + !! @param q_sf Numerical Schlieren function impure subroutine s_derive_numerical_schlieren_function(q_cons_vf, q_sf) - type(scalar_field), & - dimension(sys_size), & - intent(in) :: q_cons_vf - - real(wp), & - dimension(-offset_x%beg:m + offset_x%end, & - -offset_y%beg:n + offset_y%end, & - -offset_z%beg:p + offset_z%end), & - intent(inout) :: q_sf + type(scalar_field), dimension(sys_size), intent(in) :: q_cons_vf - real(wp) :: drho_dx, drho_dy, drho_dz !< - !! Spatial derivatives of the density in the x-, y- and z-directions + real(wp), dimension(-offset_x%beg:m + offset_x%end,-offset_y%beg:n + offset_y%end,-offset_z%beg:p + offset_z%end), & + & intent(inout) :: q_sf - real(wp), dimension(2) :: gm_rho_max !< - !! Maximum value of the gradient magnitude (gm) of the density field - !! in entire computational domain and not just the local sub-domain. - !! The first position in the variable contains the maximum value and - !! the second contains the rank of the processor on which it occurred. + real(wp) :: drho_dx, drho_dy, drho_dz !< Spatial derivatives of the density in the x-, y- and z-directions - integer :: i, j, k, l !< Generic loop iterators + !> Maximum value of the gradient magnitude (gm) of the density field in entire computational domain and not just the local + !! sub-domain. The first position in the variable contains the maximum value and the second contains the rank of the + !! processor on which it occurred. + real(wp), dimension(2) :: gm_rho_max + integer :: i, j, k, l !< Generic loop iterators ! Computing Gradient Magnitude of Density @@ -716,7 +558,6 @@ contains do l = -offset_z%beg, p + offset_z%end do k = -offset_y%beg, n + offset_y%end do j = -offset_x%beg, m + offset_x%end - drho_dx = 0._wp drho_dy = 0._wp @@ -726,7 +567,6 @@ contains end do gm_rho_sf(j, k, l) = drho_dx*drho_dx + drho_dy*drho_dy - end do end do end do @@ -736,91 +576,74 @@ contains do l = -offset_z%beg, p + offset_z%end do k = -offset_y%beg, n + offset_y%end do j = -offset_x%beg, m + offset_x%end - drho_dz = 0._wp do i = -fd_number, fd_number if (grid_geometry == 3) then - drho_dz = drho_dz + fd_coeff_z(i, l)/y_cc(k)* & - rho_sf(j, k, i + l) + drho_dz = drho_dz + fd_coeff_z(i, l)/y_cc(k)*rho_sf(j, k, i + l) else - drho_dz = drho_dz + fd_coeff_z(i, l)* & - rho_sf(j, k, i + l) + drho_dz = drho_dz + fd_coeff_z(i, l)*rho_sf(j, k, i + l) end if end do - gm_rho_sf(j, k, l) = gm_rho_sf(j, k, l) & - + drho_dz*drho_dz - + gm_rho_sf(j, k, l) = gm_rho_sf(j, k, l) + drho_dz*drho_dz end do end do end do end if - ! Up until now, only the dot product of the gradient of the density - ! field has been calculated and stored in the gradient magnitude of - ! density variable. So now we proceed to take the square-root as to - ! complete the desired calculation. + ! Up until now, only the dot product of the gradient of the density field has been calculated and stored in the gradient + ! magnitude of density variable. So now we proceed to take the square-root as to complete the desired calculation. gm_rho_sf = sqrt(gm_rho_sf) - ! Determining the local maximum of the gradient magnitude of density - ! and bookkeeping the result, along with rank of the local processor + ! Determining the local maximum of the gradient magnitude of density and bookkeeping the result, along with rank of the + ! local processor gm_rho_max = (/maxval(gm_rho_sf), real(proc_rank, wp)/) - ! Comparing the local maximum gradient magnitude of the density on - ! this processor to the those computed on the remaining processors. - ! This allows for the global maximum to be computed and the rank of - ! the processor on which it has occurred to be recorded. + ! Comparing the local maximum gradient magnitude of the density on this processor to the those computed on the remaining + ! processors. This allows for the global maximum to be computed and the rank of the processor on which it has occurred to be + ! recorded. if (num_procs > 1) call s_mpi_reduce_maxloc(gm_rho_max) ! Computing Numerical Schlieren Function - ! The form of the numerical Schlieren function depends on the choice - ! of the multicomponent flow model. For the gamma/pi_inf model, the - ! exponential of the negative, normalized, gradient magnitude of the - ! density is computed. For the volume fraction model, the amplitude - ! of the exponential's inside is also modulated with respect to the - ! identity of the fluid in which the function is evaluated. For more - ! information, refer to Marquina and Mulet (2003). + ! The form of the numerical Schlieren function depends on the choice of the multicomponent flow model. For the gamma/pi_inf + ! model, the exponential of the negative, normalized, gradient magnitude of the density is computed. For the volume fraction + ! model, the amplitude of the exponential's inside is also modulated with respect to the identity of the fluid in which the + ! function is evaluated. For more information, refer to Marquina and Mulet (2003). - if (model_eqns == 1) then ! Gamma/pi_inf model + if (model_eqns == 1) then ! Gamma/pi_inf model q_sf = -gm_rho_sf/gm_rho_max(1) - - else ! Volume fraction model + else ! Volume fraction model do l = -offset_z%beg, p + offset_z%end do k = -offset_y%beg, n + offset_y%end do j = -offset_x%beg, m + offset_x%end - q_sf(j, k, l) = 0._wp do i = 1, adv_idx%end - E_idx - q_sf(j, k, l) = & - q_sf(j, k, l) - schlieren_alpha(i)* & - q_cons_vf(i + E_idx)%sf(j, k, l)* & - gm_rho_sf(j, k, l)/gm_rho_max(1) + q_sf(j, k, l) = q_sf(j, k, l) - schlieren_alpha(i)*q_cons_vf(i + E_idx)%sf(j, k, l)*gm_rho_sf(j, k, & + & l)/gm_rho_max(1) end do end do end do end do end if - ! Up until now, only the inside of the exponential of the numerical - ! Schlieren function has been evaluated and stored. Then, to finish - ! the computation, the exponential of the inside quantity is taken. + ! Up until now, only the inside of the exponential of the numerical Schlieren function has been evaluated and stored. Then, + ! to finish the computation, the exponential of the inside quantity is taken. q_sf = exp(q_sf) end subroutine s_derive_numerical_schlieren_function - !> Deallocation procedures for the module + !> Deallocation procedures for the module impure subroutine s_finalize_derived_variables_module - ! Deallocating the variable containing the gradient magnitude of the - ! density field provided that the numerical Schlieren function was - ! was outputted during the post-process + ! Deallocating the variable containing the gradient magnitude of the density field provided that the numerical Schlieren + ! function was was outputted during the post-process if (schlieren_wrt) deallocate (gm_rho_sf) - ! Deallocating the variables that might have been used to bookkeep - ! the finite-difference coefficients in the x-, y- and z-directions + ! Deallocating the variables that might have been used to bookkeep the finite-difference coefficients in the x-, y- and + ! z-directions if (allocated(fd_coeff_x)) deallocate (fd_coeff_x) if (allocated(fd_coeff_y)) deallocate (fd_coeff_y) if (allocated(fd_coeff_z)) deallocate (fd_coeff_z) diff --git a/src/post_process/m_global_parameters.fpp b/src/post_process/m_global_parameters.fpp index 83aa0da561..feb5ec5107 100644 --- a/src/post_process/m_global_parameters.fpp +++ b/src/post_process/m_global_parameters.fpp @@ -8,26 +8,24 @@ module m_global_parameters #ifdef MFC_MPI - use mpi !< Message passing interface (MPI) module + use mpi !< Message passing interface (MPI) module #endif - use m_derived_types !< Definitions of the derived types - - use m_helper_basic !< Functions to compare floating point numbers - + use m_derived_types !< Definitions of the derived types + use m_helper_basic !< Functions to compare floating point numbers use m_thermochem, only: num_species, species_names implicit none !> @name Logistics !> @{ - integer :: num_procs !< Number of processors - character(LEN=path_len) :: case_dir !< Case folder location + integer :: num_procs !< Number of processors + character(LEN=path_len) :: case_dir !< Case folder location !> @} ! Computational Domain Parameters - integer :: proc_rank !< Rank of the local processor + integer :: proc_rank !< Rank of the local processor !> @name Number of cells in the x-, y- and z-coordinate directions !> @{ @@ -38,8 +36,7 @@ module m_global_parameters !> @name Max and min number of cells in a direction of each combination of x-,y-, and z- type(cell_num_bounds) :: cells_bounds - - integer(kind=8) :: nGlobal ! Total number of cells in global domain + integer(kind=8) :: nGlobal ! Total number of cells in global domain !> @name Cylindrical coordinates (either axisymmetric or full 3D) !> @{ @@ -52,8 +49,8 @@ module m_global_parameters integer :: m_glb, n_glb, p_glb !> @} - integer :: num_dims !< Number of spatial dimensions - integer :: num_vels !< Number of velocity components (different from num_dims for mhd) + integer :: num_dims !< Number of spatial dimensions + integer :: num_vels !< Number of velocity components (different from num_dims for mhd) !> @name Cell-boundary locations in the x-, y- and z-coordinate directions !> @{ @@ -71,239 +68,212 @@ module m_global_parameters real(wp), allocatable, dimension(:) :: dx, dy, dz !> @} - integer :: buff_size !< - !! Number of cells in buffer region. For the variables which feature a buffer - !! region, this region is used to store information outside the computational - !! domain based on the boundary conditions. - + !> Number of cells in buffer region. For the variables which feature a buffer region, this region is used to store information + !! outside the computational domain based on the boundary conditions. + integer :: buff_size integer :: t_step_start !< First time-step directory integer :: t_step_stop !< Last time-step directory integer :: t_step_save !< Interval between consecutive time-step directory !> @name IO options for adaptive time-stepping !> @{ - logical :: cfl_adap_dt, cfl_const_dt, cfl_dt + logical :: cfl_adap_dt, cfl_const_dt, cfl_dt real(wp) :: t_save real(wp) :: t_stop real(wp) :: cfl_target - integer :: n_save - integer :: n_start + integer :: n_save + integer :: n_start !> @} - ! NOTE: The variables m_root, x_root_cb and x_root_cc contain the grid data - ! of the defragmented computational domain. They are only used in 1D. For - ! serial simulations, they are equal to m, x_cb and x_cc, respectively. + ! NOTE: The variables m_root, x_root_cb and x_root_cc contain the grid data of the defragmented computational domain. They are + ! only used in 1D. For serial simulations, they are equal to m, x_cb and x_cc, respectively. !> @name Simulation Algorithm Parameters !> @{ - integer :: model_eqns !< Multicomponent flow model - integer :: num_fluids !< Number of different fluids present in the flow - logical :: relax !< phase change - integer :: relax_model !< Phase change relaxation model - logical :: mpp_lim !< Maximum volume fraction limiter - integer :: sys_size !< Number of unknowns in the system of equations - integer :: recon_type !< Which type of reconstruction to use - integer :: weno_order !< Order of accuracy for the WENO reconstruction - integer :: muscl_order !< Order of accuracy for the MUSCL reconstruction - logical :: mixture_err !< Mixture error limiter - logical :: alt_soundspeed !< Alternate sound speed - logical :: mhd !< Magnetohydrodynamics - logical :: relativity !< Relativity for RMHD - logical :: hypoelasticity !< Turn hypoelasticity on - logical :: hyperelasticity !< Turn hyperelasticity on - logical :: elasticity !< elasticity modeling, true for hyper or hypo - integer :: b_size !< Number of components in the b tensor - integer :: tensor_size !< Number of components in the nonsymmetric tensor - logical :: cont_damage !< Continuum damage modeling - logical :: hyper_cleaning !< Hyperbolic cleaning for MHD - logical :: igr !< enable IGR - integer :: igr_order !< IGR reconstruction order - logical, parameter :: chemistry = .${chemistry}$. !< Chemistry modeling + integer :: model_eqns !< Multicomponent flow model + integer :: num_fluids !< Number of different fluids present in the flow + logical :: relax !< phase change + integer :: relax_model !< Phase change relaxation model + logical :: mpp_lim !< Maximum volume fraction limiter + integer :: sys_size !< Number of unknowns in the system of equations + integer :: recon_type !< Which type of reconstruction to use + integer :: weno_order !< Order of accuracy for the WENO reconstruction + integer :: muscl_order !< Order of accuracy for the MUSCL reconstruction + logical :: mixture_err !< Mixture error limiter + logical :: alt_soundspeed !< Alternate sound speed + logical :: mhd !< Magnetohydrodynamics + logical :: relativity !< Relativity for RMHD + logical :: hypoelasticity !< Turn hypoelasticity on + logical :: hyperelasticity !< Turn hyperelasticity on + logical :: elasticity !< elasticity modeling, true for hyper or hypo + integer :: b_size !< Number of components in the b tensor + integer :: tensor_size !< Number of components in the nonsymmetric tensor + logical :: cont_damage !< Continuum damage modeling + logical :: hyper_cleaning !< Hyperbolic cleaning for MHD + logical :: igr !< enable IGR + integer :: igr_order !< IGR reconstruction order + logical, parameter :: chemistry = .${chemistry}$. !< Chemistry modeling !> @} - integer :: avg_state !< Average state evaluation method + integer :: avg_state !< Average state evaluation method !> @name Annotations of the structure, i.e. the organization, of the state vectors !> @{ type(int_bounds_info) :: cont_idx !< Indexes of first & last continuity eqns. type(int_bounds_info) :: mom_idx !< Indexes of first & last momentum eqns. - integer :: E_idx !< Index of energy equation - integer :: n_idx !< Index of number density - integer :: beta_idx !< Index of lagrange bubbles beta + integer :: E_idx !< Index of energy equation + integer :: n_idx !< Index of number density + integer :: beta_idx !< Index of lagrange bubbles beta type(int_bounds_info) :: adv_idx !< Indexes of first & last advection eqns. type(int_bounds_info) :: internalEnergies_idx !< Indexes of first & last internal energy eqns. type(bub_bounds_info) :: bub_idx !< Indexes of first & last bubble variable eqns. - integer :: gamma_idx !< Index of specific heat ratio func. eqn. - integer :: alf_idx !< Index of specific heat ratio func. eqn. - integer :: pi_inf_idx !< Index of liquid stiffness func. eqn. + integer :: gamma_idx !< Index of specific heat ratio func. eqn. + integer :: alf_idx !< Index of specific heat ratio func. eqn. + integer :: pi_inf_idx !< Index of liquid stiffness func. eqn. type(int_bounds_info) :: B_idx !< Indexes of first and last magnetic field eqns. type(int_bounds_info) :: stress_idx !< Indices of elastic stresses type(int_bounds_info) :: xi_idx !< Indexes of first and last reference map eqns. - integer :: c_idx !< Index of color function + integer :: c_idx !< Index of color function type(int_bounds_info) :: species_idx !< Indexes of first & last concentration eqns. - integer :: damage_idx !< Index of damage state variable (D) for continuum damage model - integer :: psi_idx !< Index of hyperbolic cleaning state variable for MHD + integer :: damage_idx !< Index of damage state variable (D) for continuum damage model + integer :: psi_idx !< Index of hyperbolic cleaning state variable for MHD !> @} - ! Cell Indices for the (local) interior points (O-m, O-n, 0-p). - ! Stands for "InDices With BUFFer". + ! Cell Indices for the (local) interior points (O-m, O-n, 0-p). Stands for "InDices With BUFFer". type(int_bounds_info) :: idwint(1:3) - ! Cell Indices for the entire (local) domain. In simulation, this includes - ! the buffer region. idwbuff and idwint are the same otherwise. - ! Stands for "InDices With BUFFer". + ! Cell Indices for the entire (local) domain. In simulation, this includes the buffer region. idwbuff and idwint are the same + ! otherwise. Stands for "InDices With BUFFer". type(int_bounds_info) :: idwbuff(1:3) - - integer :: num_bc_patches - logical :: bc_io + integer :: num_bc_patches + logical :: bc_io !> @name Boundary conditions in the x-, y- and z-coordinate directions !> @{ type(int_bounds_info) :: bc_x, bc_y, bc_z !> @} - integer :: shear_num !! Number of shear stress components - integer, dimension(3) :: shear_indices !< - !! Indices of the stress components that represent shear stress - integer :: shear_BC_flip_num !< - !! Number of shear stress components to reflect for boundary conditions - integer, dimension(3, 2) :: shear_BC_flip_indices !< - !! Indices of shear stress components to reflect for boundary conditions. - !! Size: (1:3, 1:shear_BC_flip_num) for (x/y/z, [indices]) - - logical :: parallel_io !< Format of the data files - logical :: sim_data - logical :: file_per_process !< output format - - integer, allocatable, dimension(:) :: proc_coords !< - !! Processor coordinates in MPI_CART_COMM - - type(int_bounds_info), dimension(3) :: nidx - - integer, allocatable, dimension(:, :, :) :: neighbor_ranks + integer :: shear_num !! Number of shear stress components + integer, dimension(3) :: shear_indices !< Indices of the stress components that represent shear stress + integer :: shear_BC_flip_num !< Number of shear stress components to reflect for boundary conditions + !> Indices of shear stress components to reflect for boundary conditions. Size: (1:3, 1:shear_BC_flip_num) for (x/y/z, + !! [indices]) + integer, dimension(3, 2) :: shear_BC_flip_indices + logical :: parallel_io !< Format of the data files + logical :: sim_data + logical :: file_per_process !< output format + integer, allocatable, dimension(:) :: proc_coords !< Processor coordinates in MPI_CART_COMM + type(int_bounds_info), dimension(3) :: nidx + integer, allocatable, dimension(:,:,:) :: neighbor_ranks !! Neighbor processor ranks - integer, allocatable, dimension(:) :: start_idx !< - !! Starting cell-center index of local processor in global grid - - integer :: num_ibs !< Number of immersed boundaries + integer, allocatable, dimension(:) :: start_idx !< Starting cell-center index of local processor in global grid + integer :: num_ibs !< Number of immersed boundaries #ifdef MFC_MPI - - type(mpi_io_var), public :: MPI_IO_DATA - type(mpi_io_ib_var), public :: MPI_IO_IB_DATA - type(mpi_io_levelset_var), public :: MPI_IO_levelset_DATA - type(mpi_io_levelset_norm_var), public :: MPI_IO_levelsetnorm_DATA - real(wp), allocatable, dimension(:, :), public :: MPI_IO_DATA_lg_bubbles - + type(mpi_io_var), public :: MPI_IO_DATA + type(mpi_io_ib_var), public :: MPI_IO_IB_DATA + type(mpi_io_levelset_var), public :: MPI_IO_levelset_DATA + type(mpi_io_levelset_norm_var), public :: MPI_IO_levelsetnorm_DATA + real(wp), allocatable, dimension(:,:), public :: MPI_IO_DATA_lg_bubbles #endif !> @name MPI info for parallel IO with Lustre file systems !> @{ character(LEN=name_len) :: mpiiofs - integer :: mpi_info_int + integer :: mpi_info_int !> @} - type(physical_parameters), dimension(num_fluids_max) :: fluid_pp !< - !! Database of the physical parameters of each of the fluids that is present - !! in the flow. These include the stiffened gas equation of state parameters, - !! and the Reynolds numbers. + !> Database of the physical parameters of each of the fluids that is present in the flow. These include the stiffened gas + !! equation of state parameters, and the Reynolds numbers. + type(physical_parameters), dimension(num_fluids_max) :: fluid_pp ! Subgrid Bubble Parameters type(subgrid_bubble_physical_parameters) :: bub_pp - - real(wp), allocatable, dimension(:) :: adv !< Advection variables + real(wp), allocatable, dimension(:) :: adv !< Advection variables ! Formatted Database File(s) Structure Parameters - integer :: format !< Format of the database file(s) - - integer :: precision !< Floating point precision of the database file(s) - logical :: down_sample !< down sampling of the database file(s) - - logical :: output_partial_domain !< Specify portion of domain to output for post-processing + integer :: format !< Format of the database file(s) + integer :: precision !< Floating point precision of the database file(s) + logical :: down_sample !< down sampling of the database file(s) + logical :: output_partial_domain !< Specify portion of domain to output for post-processing + type(bounds_info) :: x_output, y_output, z_output !< Portion of domain to output for post-processing + type(int_bounds_info) :: x_output_idx, y_output_idx, z_output_idx !< Indices of domain to output for post-processing - type(bounds_info) :: x_output, y_output, z_output !< Portion of domain to output for post-processing - type(int_bounds_info) :: x_output_idx, y_output_idx, z_output_idx !< Indices of domain to output for post-processing - - !> @name Size of the ghost zone layer in the x-, y- and z-coordinate directions. - !! The definition of the ghost zone layers is only necessary when using the - !! Silo database file format in multidimensions. These zones provide VisIt - !! with the subdomain connectivity information that it requires in order to - !! produce smooth plots. + !> @name Size of the ghost zone layer in the x-, y- and z-coordinate directions. The definition of the ghost zone layers is only + !! necessary when using the Silo database file format in multidimensions. These zones provide VisIt with the subdomain + !! connectivity information that it requires in order to produce smooth plots. !> @{ type(int_bounds_info) :: offset_x, offset_y, offset_z !> @} - !> @name The list of all possible flow variables that may be written to a database - !! file. It includes partial densities, density, momentum, velocity, energy, - !! pressure, volume fraction(s), specific heat ratio function, specific heat - !! ratio, liquid stiffness function, liquid stiffness, primitive variables, - !! conservative variables, speed of sound, the vorticity, - !! and the numerical Schlieren function. + !> @name The list of all possible flow variables that may be written to a database file. It includes partial densities, density, + !! momentum, velocity, energy, pressure, volume fraction(s), specific heat ratio function, specific heat ratio, liquid stiffness + !! function, liquid stiffness, primitive variables, conservative variables, speed of sound, the vorticity, and the numerical + !! Schlieren function. !> @{ logical, dimension(num_fluids_max) :: alpha_rho_wrt - logical :: rho_wrt - logical, dimension(3) :: mom_wrt - logical, dimension(3) :: vel_wrt - integer :: flux_lim - logical, dimension(3) :: flux_wrt - logical :: E_wrt + logical :: rho_wrt + logical, dimension(3) :: mom_wrt + logical, dimension(3) :: vel_wrt + integer :: flux_lim + logical, dimension(3) :: flux_wrt + logical :: E_wrt logical, dimension(num_fluids_max) :: alpha_rho_e_wrt - logical :: fft_wrt - logical :: dummy !< AMDFlang workaround: keep a dummy logical to avoid a compiler case-optimization bug when a parameter+GPU-kernel conditional is false - logical :: pres_wrt + logical :: fft_wrt + !> AMDFlang workaround: keep a dummy logical to avoid a compiler case-optimization bug when a parameter+GPU-kernel conditional + !! is false + logical :: dummy + logical :: pres_wrt logical, dimension(num_fluids_max) :: alpha_wrt - logical :: gamma_wrt - logical :: heat_ratio_wrt - logical :: pi_inf_wrt - logical :: pres_inf_wrt - logical :: prim_vars_wrt - logical :: cons_vars_wrt - logical :: c_wrt - logical, dimension(3) :: omega_wrt - logical :: qm_wrt - logical :: liutex_wrt - logical :: schlieren_wrt - logical :: cf_wrt - logical :: ib - logical :: ib_state_wrt - logical :: chem_wrt_Y(1:num_species) - logical :: chem_wrt_T - logical :: lag_header - logical :: lag_txt_wrt - logical :: lag_db_wrt - logical :: lag_id_wrt - logical :: lag_pos_wrt - logical :: lag_pos_prev_wrt - logical :: lag_vel_wrt - logical :: lag_rad_wrt - logical :: lag_rvel_wrt - logical :: lag_r0_wrt - logical :: lag_rmax_wrt - logical :: lag_rmin_wrt - logical :: lag_dphidt_wrt - logical :: lag_pres_wrt - logical :: lag_mv_wrt - logical :: lag_mg_wrt - logical :: lag_betaT_wrt - logical :: lag_betaC_wrt + logical :: gamma_wrt + logical :: heat_ratio_wrt + logical :: pi_inf_wrt + logical :: pres_inf_wrt + logical :: prim_vars_wrt + logical :: cons_vars_wrt + logical :: c_wrt + logical, dimension(3) :: omega_wrt + logical :: qm_wrt + logical :: liutex_wrt + logical :: schlieren_wrt + logical :: cf_wrt + logical :: ib + logical :: ib_state_wrt + logical :: chem_wrt_Y(1:num_species) + logical :: chem_wrt_T + logical :: lag_header + logical :: lag_txt_wrt + logical :: lag_db_wrt + logical :: lag_id_wrt + logical :: lag_pos_wrt + logical :: lag_pos_prev_wrt + logical :: lag_vel_wrt + logical :: lag_rad_wrt + logical :: lag_rvel_wrt + logical :: lag_r0_wrt + logical :: lag_rmax_wrt + logical :: lag_rmin_wrt + logical :: lag_dphidt_wrt + logical :: lag_pres_wrt + logical :: lag_mv_wrt + logical :: lag_mg_wrt + logical :: lag_betaT_wrt + logical :: lag_betaC_wrt !> @} - real(wp), dimension(num_fluids_max) :: schlieren_alpha !< - !! Amplitude coefficients of the numerical Schlieren function that are used - !! to adjust the intensity of numerical Schlieren renderings for individual - !! fluids. This enables waves and interfaces of varying strengths and in all - !! of the fluids to be made simultaneously visible on a single plot. + !> Amplitude coefficients of the numerical Schlieren function that are used to adjust the intensity of numerical Schlieren + !! renderings for individual fluids. This enables waves and interfaces of varying strengths and in all of the fluids to be made + !! simultaneously visible on a single plot. + real(wp), dimension(num_fluids_max) :: schlieren_alpha - integer :: fd_order !< - !! The order of the finite-difference (fd) approximations of the first-order - !! derivatives that need to be evaluated when vorticity and/or the numerical - !! Schlieren function are to be outputted to the formatted database file(s). + !> The order of the finite-difference (fd) approximations of the first-order derivatives that need to be evaluated when + !! vorticity and/or the numerical Schlieren function are to be outputted to the formatted database file(s). + integer :: fd_order - integer :: fd_number !< - !! The finite-difference number is given by MAX(1, fd_order/2). Essentially, - !! it is a measure of the half-size of the finite-difference stencil for the - !! selected order of accuracy. + !> The finite-difference number is given by MAX(1, fd_order/2). Essentially, it is a measure of the half-size of the + !! finite-difference stencil for the selected order of accuracy. + integer :: fd_number !> @name Reference parameters for Tait EOS !> @{ @@ -326,8 +296,7 @@ module m_global_parameters real(wp) :: gam_m real(wp), dimension(:), allocatable :: pb0, mass_g0, mass_v0, Pe_T, k_v, k_g real(wp), dimension(:), allocatable :: Re_trans_T, Re_trans_c, Im_trans_T, Im_trans_c, omegaN - real(wp) :: R0ref, p0ref, rho0ref, T0ref, ss, pv, vd, mu_l, mu_v, mu_g, & - gam_v, gam_g, M_v, M_g, cp_v, cp_g, R_v, R_g + real(wp) :: R0ref, p0ref, rho0ref, T0ref, ss, pv, vd, mu_l, mu_v, mu_g, gam_v, gam_g, M_v, M_g, cp_v, cp_g, R_v, R_g real(wp) :: G real(wp) :: poly_sigma real(wp) :: sigR @@ -336,9 +305,8 @@ module m_global_parameters !> @name surface tension coefficient !> @{ - real(wp) :: sigma - logical :: surface_tension + logical :: surface_tension !> @} !> @name Index variables used for m_variables_conversion @@ -358,20 +326,19 @@ module m_global_parameters logical :: bubbles_lagrange !> @} - real(wp) :: Bx0 !< Constant magnetic field in the x-direction (1D) - - real(wp) :: wall_time, wall_time_avg !< Wall time measurements + real(wp) :: Bx0 !< Constant magnetic field in the x-direction (1D) + real(wp) :: wall_time, wall_time_avg !< Wall time measurements contains - !> Assigns default values to user inputs prior to reading - !! them in. This allows for an easier consistency check of - !! these parameters once they are read from the input file. + !> Assigns default values to user inputs prior to reading them in. This allows for an easier consistency check of these + !! parameters once they are read from the input file. impure subroutine s_assign_default_values_to_user_inputs - integer :: i !< Generic loop iterator + integer :: i !< Generic loop iterator ! Logistics + case_dir = '.' ! Computational domain parameters @@ -457,8 +424,8 @@ contains bub_pp%gam_g = dflt_real; gam_g = dflt_real bub_pp%M_v = dflt_real; M_v = dflt_real bub_pp%M_g = dflt_real; M_g = dflt_real - bub_pp%k_v = dflt_real; - bub_pp%k_g = dflt_real; + bub_pp%k_v = dflt_real + bub_pp%k_g = dflt_real bub_pp%cp_v = dflt_real; cp_v = dflt_real bub_pp%cp_g = dflt_real; cp_g = dflt_real bub_pp%R_v = dflt_real; R_v = dflt_real @@ -561,24 +528,22 @@ contains end subroutine s_assign_default_values_to_user_inputs - !> Computation of parameters, allocation procedures, and/or - !! any other tasks needed to properly setup the module + !> Computation of parameters, allocation procedures, and/or any other tasks needed to properly setup the module impure subroutine s_initialize_global_parameters_module integer :: i, j, fac ! Setting m_root equal to m in the case of a 1D serial simulation + if (n == 0) m_root = m_glb ! Gamma/Pi_inf Model if (model_eqns == 1) then - ! Setting number of fluids num_fluids = 1 - ! Annotating structure of the state and flux vectors belonging - ! to the system of equations defined by the selected number of - ! spatial dimensions and the gamma/pi_inf model + ! Annotating structure of the state and flux vectors belonging to the system of equations defined by the selected number + ! of spatial dimensions and the gamma/pi_inf model cont_idx%beg = 1 cont_idx%end = cont_idx%beg mom_idx%beg = cont_idx%end + 1 @@ -592,10 +557,8 @@ contains ! Volume Fraction Model (5-equation model) else if (model_eqns == 2) then - - ! Annotating structure of the state and flux vectors belonging - ! to the system of equations defined by the selected number of - ! spatial dimensions and the volume fraction model + ! Annotating structure of the state and flux vectors belonging to the system of equations defined by the selected number + ! of spatial dimensions and the volume fraction model cont_idx%beg = 1 cont_idx%end = num_fluids mom_idx%beg = cont_idx%end + 1 @@ -603,17 +566,14 @@ contains E_idx = mom_idx%end + 1 if (igr) then - ! Volume fractions are stored in the indices immediately following - ! the energy equation. IGR tracks a total of (N-1) volume fractions - ! for N fluids, hence the "-1" in adv_idx%end. If num_fluids = 1 - ! then adv_idx%end < adv_idx%beg, which skips all loops over the - ! volume fractions since there is no volume fraction to track - adv_idx%beg = E_idx + 1 ! Alpha for fluid 1 + ! Volume fractions are stored in the indices immediately following the energy equation. IGR tracks a total of (N-1) + ! volume fractions for N fluids, hence the "-1" in adv_idx%end. If num_fluids = 1 then adv_idx%end < adv_idx%beg, + ! which skips all loops over the volume fractions since there is no volume fraction to track + adv_idx%beg = E_idx + 1 ! Alpha for fluid 1 adv_idx%end = E_idx + num_fluids - 1 else - ! Volume fractions are stored in the indices immediately following - ! the energy equation. WENO/MUSCL + Riemann tracks a total of (N) - ! volume fractions for N fluids, hence the lack of "-1" in adv_idx%end + ! Volume fractions are stored in the indices immediately following the energy equation. WENO/MUSCL + Riemann tracks + ! a total of (N) volume fractions for N fluids, hence the lack of "-1" in adv_idx%end adv_idx%beg = E_idx + 1 adv_idx%end = E_idx + num_fluids end if @@ -631,7 +591,6 @@ contains end if if (bubbles_euler) then - bub_idx%beg = sys_size + 1 if (qbmm) then bub_idx%end = adv_idx%end + nb*nmom @@ -683,19 +642,17 @@ contains if (mhd) then B_idx%beg = sys_size + 1 if (n == 0) then - B_idx%end = sys_size + 2 ! 1D: By, Bz + B_idx%end = sys_size + 2 ! 1D: By, Bz else - B_idx%end = sys_size + 3 ! 2D/3D: Bx, By, Bz + B_idx%end = sys_size + 3 ! 2D/3D: Bx, By, Bz end if sys_size = B_idx%end end if ! Volume Fraction Model (6-equation model) else if (model_eqns == 3) then - - ! Annotating structure of the state and flux vectors belonging - ! to the system of equations defined by the selected number of - ! spatial dimensions and the volume fraction model + ! Annotating structure of the state and flux vectors belonging to the system of equations defined by the selected number + ! of spatial dimensions and the volume fraction model cont_idx%beg = 1 cont_idx%end = num_fluids mom_idx%beg = cont_idx%end + 1 @@ -706,18 +663,17 @@ contains internalEnergies_idx%beg = adv_idx%end + 1 internalEnergies_idx%end = adv_idx%end + num_fluids sys_size = internalEnergies_idx%end - alf_idx = 1 ! dummy, cannot actually have a void fraction - + alf_idx = 1 ! dummy, cannot actually have a void fraction else if (model_eqns == 4) then - cont_idx%beg = 1 ! one continuity equation - cont_idx%end = 1 !num_fluids - mom_idx%beg = cont_idx%end + 1 ! one momentum equation in each + cont_idx%beg = 1 ! one continuity equation + cont_idx%end = 1 ! num_fluids + mom_idx%beg = cont_idx%end + 1 ! one momentum equation in each mom_idx%end = cont_idx%end + num_vels - E_idx = mom_idx%end + 1 ! one energy equation + E_idx = mom_idx%end + 1 ! one energy equation adv_idx%beg = E_idx + 1 - adv_idx%end = adv_idx%beg !one volume advection equation + adv_idx%end = adv_idx%beg ! one volume advection equation alf_idx = adv_idx%end - sys_size = alf_idx !adv_idx%end + sys_size = alf_idx ! adv_idx%end if (bubbles_euler) then bub_idx%beg = sys_size + 1 @@ -762,7 +718,6 @@ contains end if if (model_eqns == 2 .or. model_eqns == 3) then - if (hypoelasticity .or. hyperelasticity) then elasticity = .true. stress_idx%beg = sys_size + 1 @@ -778,18 +733,16 @@ contains shear_num = 1 shear_indices(1) = stress_idx%beg - 1 + 2 shear_BC_flip_num = 1 - shear_BC_flip_indices(1:2, 1) = shear_indices(1) + shear_BC_flip_indices(1:2,1) = shear_indices(1) ! Both x-dir and y-dir: flip tau_xy only else if (num_dims == 3) then shear_num = 3 shear_indices(1:3) = stress_idx%beg - 1 + (/2, 4, 5/) shear_BC_flip_num = 2 - shear_BC_flip_indices(1, 1:2) = shear_indices((/1, 2/)) - shear_BC_flip_indices(2, 1:2) = shear_indices((/1, 3/)) - shear_BC_flip_indices(3, 1:2) = shear_indices((/2, 3/)) - ! x-dir: flip tau_xy and tau_xz - ! y-dir: flip tau_xy and tau_yz - ! z-dir: flip tau_xz and tau_yz + shear_BC_flip_indices(1,1:2) = shear_indices((/1, 2/)) + shear_BC_flip_indices(2,1:2) = shear_indices((/1, 3/)) + shear_BC_flip_indices(3,1:2) = shear_indices((/2, 3/)) + ! x-dir: flip tau_xy and tau_xz y-dir: flip tau_xy and tau_yz z-dir: flip tau_xz and tau_yz end if end if @@ -826,7 +779,6 @@ contains else psi_idx = dflt_int end if - end if if (chemistry) then @@ -875,58 +827,46 @@ contains do i = 1, sys_size if (down_sample) then - allocate (MPI_IO_DATA%var(i)%sf(-1:m + 1, -1:n + 1, -1:p + 1)) + allocate (MPI_IO_DATA%var(i)%sf(-1:m + 1,-1:n + 1,-1:p + 1)) else - allocate (MPI_IO_DATA%var(i)%sf(0:m, 0:n, 0:p)) + allocate (MPI_IO_DATA%var(i)%sf(0:m,0:n,0:p)) end if MPI_IO_DATA%var(i)%sf => null() end do if (qbmm .and. .not. polytropic) then do i = sys_size + 1, sys_size + 2*nb*nnode - allocate (MPI_IO_DATA%var(i)%sf(0:m, 0:n, 0:p)) + allocate (MPI_IO_DATA%var(i)%sf(0:m,0:n,0:p)) MPI_IO_DATA%var(i)%sf => null() end do end if - if (ib) allocate (MPI_IO_IB_DATA%var%sf(0:m, 0:n, 0:p)) + if (ib) allocate (MPI_IO_IB_DATA%var%sf(0:m,0:n,0:p)) #endif - ! Size of the ghost zone layer is non-zero only when post-processing - ! the raw simulation data of a parallel multidimensional computation - ! in the Silo-HDF5 format. If this is the case, one must also verify - ! whether the raw simulation data is 2D or 3D. In the 2D case, size - ! of the z-coordinate direction ghost zone layer must be zeroed out. + ! Size of the ghost zone layer is non-zero only when post-processing the raw simulation data of a parallel multidimensional + ! computation in the Silo-HDF5 format. If this is the case, one must also verify whether the raw simulation data is 2D or + ! 3D. In the 2D case, size of the z-coordinate direction ghost zone layer must be zeroed out. if (num_procs == 1 .or. format /= 1) then - offset_x%beg = 0 offset_x%end = 0 offset_y%beg = 0 offset_y%end = 0 offset_z%beg = 0 offset_z%end = 0 - - elseif (n == 0) then - + else if (n == 0) then offset_y%beg = 0 offset_y%end = 0 offset_z%beg = 0 offset_z%end = 0 - - elseif (p == 0) then - + else if (p == 0) then offset_z%beg = 0 offset_z%end = 0 - end if - ! Determining the finite-difference number and the buffer size. Note - ! that the size of the buffer is unrelated to the order of the WENO - ! scheme. Rather, it is directly dependent on maximum size of ghost - ! zone layers and possibly the order of the finite difference scheme - ! used for the computation of vorticity and/or numerical Schlieren - ! function. - buff_size = max(offset_x%beg, offset_x%end, offset_y%beg, & - offset_y%end, offset_z%beg, offset_z%end) + ! Determining the finite-difference number and the buffer size. Note that the size of the buffer is unrelated to the order + ! of the WENO scheme. Rather, it is directly dependent on maximum size of ghost zone layers and possibly the order of the + ! finite difference scheme used for the computation of vorticity and/or numerical Schlieren function. + buff_size = max(offset_x%beg, offset_x%end, offset_y%beg, offset_y%end, offset_z%beg, offset_z%end) if (any(omega_wrt) .or. schlieren_wrt .or. qm_wrt .or. liutex_wrt) then fd_number = max(1, fd_order/2) @@ -955,7 +895,6 @@ contains ! Allocating grid variables in the y- and z-coordinate directions if (n > 0) then - allocate (y_cb(-1 - offset_y%beg:n + offset_y%end)) allocate (y_cc(-buff_size:n + buff_size)) allocate (dy(-buff_size:n + buff_size)) @@ -966,26 +905,24 @@ contains allocate (dz(-buff_size:p + buff_size)) end if - ! Allocating the grid variables, only used for the 1D simulations, - ! and containing the defragmented computational domain grid data + ! Allocating the grid variables, only used for the 1D simulations, and containing the defragmented computational domain + ! grid data else - allocate (x_root_cb(-1:m_root)) allocate (x_root_cc(0:m_root)) if (precision == 1) then allocate (x_root_cc_s(0:m_root)) end if - end if allocate (adv(num_fluids)) - if (cyl_coord .neqv. .true.) then ! Cartesian grid + if (cyl_coord .neqv. .true.) then ! Cartesian grid grid_geometry = 1 - elseif (cyl_coord .and. p == 0) then ! Axisymmetric cylindrical grid + else if (cyl_coord .and. p == 0) then ! Axisymmetric cylindrical grid grid_geometry = 2 - else ! Fully 3D cylindrical grid + else ! Fully 3D cylindrical grid grid_geometry = 3 end if @@ -995,7 +932,7 @@ contains impure subroutine s_initialize_parallel_io #ifdef MFC_MPI - integer :: ierr !< Generic flag used to identify and report MPI errors + integer :: ierr !< Generic flag used to identify and report MPI errors #endif num_dims = 1 + min(1, n) + min(1, p) @@ -1011,20 +948,16 @@ contains if (parallel_io .neqv. .true.) return #ifdef MFC_MPI - ! Option for Lustre file system (Darter/Comet/Stampede) write (mpiiofs, '(A)') '/lustre_' mpiiofs = trim(mpiiofs) call MPI_INFO_CREATE(mpi_info_int, ierr) call MPI_INFO_SET(mpi_info_int, 'romio_ds_write', 'disable', ierr) - ! Option for UNIX file system (Hooke/Thomson) - ! WRITE(mpiiofs, '(A)') '/ufs_' - ! mpiiofs = TRIM(mpiiofs) - ! mpi_info_int = MPI_INFO_NULL + ! Option for UNIX file system (Hooke/Thomson) WRITE(mpiiofs, '(A)') '/ufs_' mpiiofs = TRIM(mpiiofs) mpi_info_int = + ! MPI_INFO_NULL allocate (start_idx(1:num_dims)) - #endif end subroutine s_initialize_parallel_io @@ -1035,6 +968,7 @@ contains integer :: i ! Deallocating the grid variables for the x-coordinate direction + deallocate (x_cc, x_cb, dx) ! Deallocating grid variables for the y- and z-coordinate directions @@ -1044,8 +978,8 @@ contains deallocate (z_cc, z_cb, dz) end if else - ! Deallocating the grid variables, only used for the 1D simulations, - ! and containing the defragmented computational domain grid data + ! Deallocating the grid variables, only used for the 1D simulations, and containing the defragmented computational + ! domain grid data deallocate (x_root_cb, x_root_cc) end if @@ -1054,7 +988,6 @@ contains deallocate (adv) #ifdef MFC_MPI - if (parallel_io) then deallocate (start_idx) do i = 1, sys_size diff --git a/src/post_process/m_mpi_proxy.fpp b/src/post_process/m_mpi_proxy.fpp index d0a1311f4e..84d1861f7d 100644 --- a/src/post_process/m_mpi_proxy.fpp +++ b/src/post_process/m_mpi_proxy.fpp @@ -6,22 +6,18 @@ module m_mpi_proxy #ifdef MFC_MPI - use mpi !< Message passing interface (MPI) module + use mpi !< Message passing interface (MPI) module #endif - use m_derived_types !< Definitions of the derived types - - use m_global_parameters !< Global parameters for the code - + use m_derived_types !< Definitions of the derived types + use m_global_parameters !< Global parameters for the code use m_mpi_common - use ieee_arithmetic implicit none - !> @name Receive counts and displacement vector variables, respectively, used in - !! enabling MPI to gather varying amounts of data from all processes to the - !! root process + !> @name Receive counts and displacement vector variables, respectively, used in enabling MPI to gather varying amounts of data + !! from all processes to the root process !> @{ integer, allocatable, dimension(:) :: recvcounts integer, allocatable, dimension(:) :: displs @@ -29,28 +25,23 @@ module m_mpi_proxy contains - !> Computation of parameters, allocation procedures, and/or - !! any other tasks needed to properly setup the module + !> Computation of parameters, allocation procedures, and/or any other tasks needed to properly setup the module impure subroutine s_initialize_mpi_proxy_module #ifdef MFC_MPI + integer :: i !< Generic loop iterator + integer :: ierr !< Generic flag used to identify and report MPI errors - integer :: i !< Generic loop iterator - integer :: ierr !< Generic flag used to identify and report MPI errors - - ! Allocating and configuring the receive counts and the displacement - ! vector variables used in variable-gather communication procedures. - ! Note that these are only needed for either multidimensional runs - ! that utilize the Silo database file format or for 1D simulations. + ! Allocating and configuring the receive counts and the displacement vector variables used in variable-gather communication + ! procedures. Note that these are only needed for either multidimensional runs that utilize the Silo database file format or + ! for 1D simulations. if ((format == 1 .and. n > 0) .or. n == 0) then - allocate (recvcounts(0:num_procs - 1)) allocate (displs(0:num_procs - 1)) if (n == 0) then - call MPI_GATHER(m + 1, 1, MPI_INTEGER, recvcounts(0), 1, & - MPI_INTEGER, 0, MPI_COMM_WORLD, ierr) - elseif (proc_rank == 0) then + call MPI_GATHER(m + 1, 1, MPI_INTEGER, recvcounts(0), 1, MPI_INTEGER, 0, MPI_COMM_WORLD, ierr) + else if (proc_rank == 0) then recvcounts = 1 end if @@ -61,23 +52,18 @@ contains displs(i) = displs(i - 1) + recvcounts(i - 1) end do end if - end if - #endif end subroutine s_initialize_mpi_proxy_module - !> Since only processor with rank 0 is in charge of reading - !! and checking the consistency of the user provided inputs, - !! these are not available to the remaining processors. This - !! subroutine is then in charge of broadcasting the required - !! information. + !> Since only processor with rank 0 is in charge of reading and checking the consistency of the user provided inputs, these are + !! not available to the remaining processors. This subroutine is then in charge of broadcasting the required information. impure subroutine s_mpi_bcast_user_inputs #ifdef MFC_MPI - integer :: i !< Generic loop iterator - integer :: ierr !< Generic flag used to identify and report MPI errors + integer :: i !< Generic loop iterator + integer :: ierr !< Generic flag used to identify and report MPI errors ! Logistics call MPI_BCAST(case_dir, len(case_dir), MPI_CHARACTER, 0, MPI_COMM_WORLD, ierr) @@ -152,248 +138,171 @@ contains end subroutine s_mpi_bcast_user_inputs - !> This subroutine gathers the Silo database metadata for - !! the spatial extents in order to boost the performance of - !! the multidimensional visualization. - !! @param spatial_extents Spatial extents for each processor's sub-domain. First dimension - !! corresponds to the minimum and maximum values, respectively, while - !! the second dimension corresponds to the processor rank. + !> This subroutine gathers the Silo database metadata for the spatial extents in order to boost the performance of the + !! multidimensional visualization. + ! ! @param spatial_extents Spatial extents for each processor's sub-domain. First dimension corresponds to the minimum and + ! maximum values, respectively, while the second dimension corresponds to the processor rank. impure subroutine s_mpi_gather_spatial_extents(spatial_extents) - real(wp), dimension(1:, 0:), intent(INOUT) :: spatial_extents + real(wp), dimension(1:,0:), intent(inout) :: spatial_extents #ifdef MFC_MPI - integer :: ierr !< Generic flag used to identify and report MPI errors + integer :: ierr !< Generic flag used to identify and report MPI errors real(wp) :: ext_temp(0:num_procs - 1) ! Simulation is 3D if (p > 0) then if (grid_geometry == 3) then ! Minimum spatial extent in the r-direction - call MPI_GATHERV(minval(y_cb), 1, mpi_p, & - spatial_extents(1, 0), recvcounts, 6*displs, & - mpi_p, 0, MPI_COMM_WORLD, & - ierr) + call MPI_GATHERV(minval(y_cb), 1, mpi_p, spatial_extents(1, 0), recvcounts, 6*displs, mpi_p, 0, MPI_COMM_WORLD, & + & ierr) ! Minimum spatial extent in the theta-direction - call MPI_GATHERV(minval(z_cb), 1, mpi_p, & - spatial_extents(2, 0), recvcounts, 6*displs, & - mpi_p, 0, MPI_COMM_WORLD, & - ierr) + call MPI_GATHERV(minval(z_cb), 1, mpi_p, spatial_extents(2, 0), recvcounts, 6*displs, mpi_p, 0, MPI_COMM_WORLD, & + & ierr) ! Minimum spatial extent in the z-direction - call MPI_GATHERV(minval(x_cb), 1, mpi_p, & - spatial_extents(3, 0), recvcounts, 6*displs, & - mpi_p, 0, MPI_COMM_WORLD, & - ierr) + call MPI_GATHERV(minval(x_cb), 1, mpi_p, spatial_extents(3, 0), recvcounts, 6*displs, mpi_p, 0, MPI_COMM_WORLD, & + & ierr) ! Maximum spatial extent in the r-direction - call MPI_GATHERV(maxval(y_cb), 1, mpi_p, & - spatial_extents(4, 0), recvcounts, 6*displs, & - mpi_p, 0, MPI_COMM_WORLD, & - ierr) + call MPI_GATHERV(maxval(y_cb), 1, mpi_p, spatial_extents(4, 0), recvcounts, 6*displs, mpi_p, 0, MPI_COMM_WORLD, & + & ierr) ! Maximum spatial extent in the theta-direction - call MPI_GATHERV(maxval(z_cb), 1, mpi_p, & - spatial_extents(5, 0), recvcounts, 6*displs, & - mpi_p, 0, MPI_COMM_WORLD, & - ierr) + call MPI_GATHERV(maxval(z_cb), 1, mpi_p, spatial_extents(5, 0), recvcounts, 6*displs, mpi_p, 0, MPI_COMM_WORLD, & + & ierr) ! Maximum spatial extent in the z-direction - call MPI_GATHERV(maxval(x_cb), 1, mpi_p, & - spatial_extents(6, 0), recvcounts, 6*displs, & - mpi_p, 0, MPI_COMM_WORLD, & - ierr) + call MPI_GATHERV(maxval(x_cb), 1, mpi_p, spatial_extents(6, 0), recvcounts, 6*displs, mpi_p, 0, MPI_COMM_WORLD, & + & ierr) else ! Minimum spatial extent in the x-direction - call MPI_GATHERV(minval(x_cb), 1, mpi_p, & - spatial_extents(1, 0), recvcounts, 6*displs, & - mpi_p, 0, MPI_COMM_WORLD, & - ierr) + call MPI_GATHERV(minval(x_cb), 1, mpi_p, spatial_extents(1, 0), recvcounts, 6*displs, mpi_p, 0, MPI_COMM_WORLD, & + & ierr) ! Minimum spatial extent in the y-direction - call MPI_GATHERV(minval(y_cb), 1, mpi_p, & - spatial_extents(2, 0), recvcounts, 6*displs, & - mpi_p, 0, MPI_COMM_WORLD, & - ierr) + call MPI_GATHERV(minval(y_cb), 1, mpi_p, spatial_extents(2, 0), recvcounts, 6*displs, mpi_p, 0, MPI_COMM_WORLD, & + & ierr) ! Minimum spatial extent in the z-direction - call MPI_GATHERV(minval(z_cb), 1, mpi_p, & - spatial_extents(3, 0), recvcounts, 6*displs, & - mpi_p, 0, MPI_COMM_WORLD, & - ierr) + call MPI_GATHERV(minval(z_cb), 1, mpi_p, spatial_extents(3, 0), recvcounts, 6*displs, mpi_p, 0, MPI_COMM_WORLD, & + & ierr) ! Maximum spatial extent in the x-direction - call MPI_GATHERV(maxval(x_cb), 1, mpi_p, & - spatial_extents(4, 0), recvcounts, 6*displs, & - mpi_p, 0, MPI_COMM_WORLD, & - ierr) + call MPI_GATHERV(maxval(x_cb), 1, mpi_p, spatial_extents(4, 0), recvcounts, 6*displs, mpi_p, 0, MPI_COMM_WORLD, & + & ierr) ! Maximum spatial extent in the y-direction - call MPI_GATHERV(maxval(y_cb), 1, mpi_p, & - spatial_extents(5, 0), recvcounts, 6*displs, & - mpi_p, 0, MPI_COMM_WORLD, & - ierr) + call MPI_GATHERV(maxval(y_cb), 1, mpi_p, spatial_extents(5, 0), recvcounts, 6*displs, mpi_p, 0, MPI_COMM_WORLD, & + & ierr) ! Maximum spatial extent in the z-direction - call MPI_GATHERV(maxval(z_cb), 1, mpi_p, & - spatial_extents(6, 0), recvcounts, 6*displs, & - mpi_p, 0, MPI_COMM_WORLD, & - ierr) + call MPI_GATHERV(maxval(z_cb), 1, mpi_p, spatial_extents(6, 0), recvcounts, 6*displs, mpi_p, 0, MPI_COMM_WORLD, & + & ierr) end if ! Simulation is 2D - elseif (n > 0) then - + else if (n > 0) then ! Minimum spatial extent in the x-direction - call MPI_GATHERV(minval(x_cb), 1, mpi_p, & - spatial_extents(1, 0), recvcounts, 4*displs, & - mpi_p, 0, MPI_COMM_WORLD, & - ierr) + call MPI_GATHERV(minval(x_cb), 1, mpi_p, spatial_extents(1, 0), recvcounts, 4*displs, mpi_p, 0, MPI_COMM_WORLD, ierr) ! Minimum spatial extent in the y-direction - call MPI_GATHERV(minval(y_cb), 1, mpi_p, & - spatial_extents(2, 0), recvcounts, 4*displs, & - mpi_p, 0, MPI_COMM_WORLD, & - ierr) + call MPI_GATHERV(minval(y_cb), 1, mpi_p, spatial_extents(2, 0), recvcounts, 4*displs, mpi_p, 0, MPI_COMM_WORLD, ierr) ! Maximum spatial extent in the x-direction - call MPI_GATHERV(maxval(x_cb), 1, mpi_p, & - spatial_extents(3, 0), recvcounts, 4*displs, & - mpi_p, 0, MPI_COMM_WORLD, & - ierr) + call MPI_GATHERV(maxval(x_cb), 1, mpi_p, spatial_extents(3, 0), recvcounts, 4*displs, mpi_p, 0, MPI_COMM_WORLD, ierr) ! Maximum spatial extent in the y-direction - call MPI_GATHERV(maxval(y_cb), 1, mpi_p, & - spatial_extents(4, 0), recvcounts, 4*displs, & - mpi_p, 0, MPI_COMM_WORLD, & - ierr) + call MPI_GATHERV(maxval(y_cb), 1, mpi_p, spatial_extents(4, 0), recvcounts, 4*displs, mpi_p, 0, MPI_COMM_WORLD, ierr) ! Simulation is 1D else - - ! For 1D, recvcounts/displs are sized for grid defragmentation - ! (m+1 per rank), not for scalar gathers. Use MPI_GATHER instead. + ! For 1D, recvcounts/displs are sized for grid defragmentation (m+1 per rank), not for scalar gathers. Use MPI_GATHER + ! instead. ! Minimum spatial extent in the x-direction - call MPI_GATHER(minval(x_cb), 1, mpi_p, & - ext_temp, 1, mpi_p, 0, & - MPI_COMM_WORLD, ierr) - if (proc_rank == 0) spatial_extents(1, :) = ext_temp + call MPI_GATHER(minval(x_cb), 1, mpi_p, ext_temp, 1, mpi_p, 0, MPI_COMM_WORLD, ierr) + if (proc_rank == 0) spatial_extents(1,:) = ext_temp ! Maximum spatial extent in the x-direction - call MPI_GATHER(maxval(x_cb), 1, mpi_p, & - ext_temp, 1, mpi_p, 0, & - MPI_COMM_WORLD, ierr) - if (proc_rank == 0) spatial_extents(2, :) = ext_temp + call MPI_GATHER(maxval(x_cb), 1, mpi_p, ext_temp, 1, mpi_p, 0, MPI_COMM_WORLD, ierr) + if (proc_rank == 0) spatial_extents(2,:) = ext_temp end if - #endif end subroutine s_mpi_gather_spatial_extents - !> This subroutine collects the sub-domain cell-boundary or - !! cell-center locations data from all of the processors and - !! puts back together the grid of the entire computational - !! domain on the rank 0 processor. This is only done for 1D - !! simulations. + !> This subroutine collects the sub-domain cell-boundary or cell-center locations data from all of the processors and puts back + !! together the grid of the entire computational domain on the rank 0 processor. This is only done for 1D simulations. impure subroutine s_mpi_defragment_1d_grid_variable #ifdef MFC_MPI - integer :: ierr !< Generic flag used to identify and report MPI errors + integer :: ierr !< Generic flag used to identify and report MPI errors ! Silo-HDF5 database format if (format == 1) then - - call MPI_GATHERV(x_cc(0), m + 1, mpi_p, & - x_root_cc(0), recvcounts, displs, & - mpi_p, 0, MPI_COMM_WORLD, & - ierr) + call MPI_GATHERV(x_cc(0), m + 1, mpi_p, x_root_cc(0), recvcounts, displs, mpi_p, 0, MPI_COMM_WORLD, ierr) ! Binary database format else - - call MPI_GATHERV(x_cb(0), m + 1, mpi_p, & - x_root_cb(0), recvcounts, displs, & - mpi_p, 0, MPI_COMM_WORLD, & - ierr) + call MPI_GATHERV(x_cb(0), m + 1, mpi_p, x_root_cb(0), recvcounts, displs, mpi_p, 0, MPI_COMM_WORLD, ierr) if (proc_rank == 0) x_root_cb(-1) = x_cb(-1) - end if - #endif end subroutine s_mpi_defragment_1d_grid_variable - !> This subroutine gathers the Silo database metadata for - !! the flow variable's extents as to boost performance of - !! the multidimensional visualization. - !! @param q_sf Flow variable defined on a single computational sub-domain - !! @param data_extents The flow variable extents on each of the processor's sub-domain. - !! First dimension of array corresponds to the former's minimum and - !! maximum values, respectively, while second dimension corresponds - !! to each processor's rank. + !> This subroutine gathers the Silo database metadata for the flow variable's extents as to boost performance of the + !! multidimensional visualization. + !! @param q_sf Flow variable defined on a single computational sub-domain + ! ! @param data_extents The flow variable extents on each of the processor's sub-domain. First dimension of array corresponds to + ! the former's minimum and maximum values, respectively, while second dimension corresponds to each processor's rank. impure subroutine s_mpi_gather_data_extents(q_sf, data_extents) - real(wp), dimension(:, :, :), intent(in) :: q_sf - real(wp), dimension(1:2, 0:num_procs - 1), intent(inout) :: data_extents + real(wp), dimension(:,:,:), intent(in) :: q_sf + real(wp), dimension(1:2,0:num_procs - 1), intent(inout) :: data_extents #ifdef MFC_MPI - integer :: ierr !< Generic flag used to identify and report MPI errors + integer :: ierr !< Generic flag used to identify and report MPI errors real(wp) :: ext_temp(0:num_procs - 1) if (n > 0) then - ! Multi-D: recvcounts = 1, so strided MPI_GATHERV works correctly - ! Minimum flow variable extent - call MPI_GATHERV(minval(q_sf), 1, mpi_p, & - data_extents(1, 0), recvcounts, 2*displs, & - mpi_p, 0, MPI_COMM_WORLD, ierr) + ! Multi-D: recvcounts = 1, so strided MPI_GATHERV works correctly Minimum flow variable extent + call MPI_GATHERV(minval(q_sf), 1, mpi_p, data_extents(1, 0), recvcounts, 2*displs, mpi_p, 0, MPI_COMM_WORLD, ierr) ! Maximum flow variable extent - call MPI_GATHERV(maxval(q_sf), 1, mpi_p, & - data_extents(2, 0), recvcounts, 2*displs, & - mpi_p, 0, MPI_COMM_WORLD, ierr) + call MPI_GATHERV(maxval(q_sf), 1, mpi_p, data_extents(2, 0), recvcounts, 2*displs, mpi_p, 0, MPI_COMM_WORLD, ierr) else - ! 1D: recvcounts/displs are sized for grid defragmentation - ! (m+1 per rank), not for scalar gathers. Use MPI_GATHER instead. + ! 1D: recvcounts/displs are sized for grid defragmentation (m+1 per rank), not for scalar gathers. Use MPI_GATHER + ! instead. ! Minimum flow variable extent - call MPI_GATHER(minval(q_sf), 1, mpi_p, & - ext_temp, 1, mpi_p, 0, & - MPI_COMM_WORLD, ierr) - if (proc_rank == 0) data_extents(1, :) = ext_temp + call MPI_GATHER(minval(q_sf), 1, mpi_p, ext_temp, 1, mpi_p, 0, MPI_COMM_WORLD, ierr) + if (proc_rank == 0) data_extents(1,:) = ext_temp ! Maximum flow variable extent - call MPI_GATHER(maxval(q_sf), 1, mpi_p, & - ext_temp, 1, mpi_p, 0, & - MPI_COMM_WORLD, ierr) - if (proc_rank == 0) data_extents(2, :) = ext_temp + call MPI_GATHER(maxval(q_sf), 1, mpi_p, ext_temp, 1, mpi_p, 0, MPI_COMM_WORLD, ierr) + if (proc_rank == 0) data_extents(2,:) = ext_temp end if - #endif end subroutine s_mpi_gather_data_extents - !> This subroutine gathers the sub-domain flow variable data - !! from all of the processors and puts it back together for - !! the entire computational domain on the rank 0 processor. - !! This is only done for 1D simulations. - !! @param q_sf Flow variable defined on a single computational sub-domain - !! @param q_root_sf Flow variable defined on the entire computational domain + !> This subroutine gathers the sub-domain flow variable data from all of the processors and puts it back together for the entire + !! computational domain on the rank 0 processor. This is only done for 1D simulations. + !! @param q_sf Flow variable defined on a single computational sub-domain + !! @param q_root_sf Flow variable defined on the entire computational domain impure subroutine s_mpi_defragment_1d_flow_variable(q_sf, q_root_sf) - real(wp), dimension(0:m), intent(in) :: q_sf + real(wp), dimension(0:m), intent(in) :: q_sf real(wp), dimension(0:m), intent(inout) :: q_root_sf #ifdef MFC_MPI - integer :: ierr !< Generic flag used to identify and report MPI errors - - ! Gathering the sub-domain flow variable data from all the processes - ! and putting it back together for the entire computational domain - ! on the process with rank 0 - call MPI_GATHERV(q_sf(0), m + 1, mpi_p, & - q_root_sf(0), recvcounts, displs, & - mpi_p, 0, MPI_COMM_WORLD, ierr) + integer :: ierr !< Generic flag used to identify and report MPI errors + ! Gathering the sub-domain flow variable data from all the processes and putting it back together for the entire + ! computational domain on the process with rank 0 + call MPI_GATHERV(q_sf(0), m + 1, mpi_p, q_root_sf(0), recvcounts, displs, mpi_p, 0, MPI_COMM_WORLD, ierr) #endif end subroutine s_mpi_defragment_1d_flow_variable @@ -402,14 +311,11 @@ contains impure subroutine s_finalize_mpi_proxy_module #ifdef MFC_MPI - - ! Deallocating the receive counts and the displacement vector - ! variables used in variable-gather communication procedures + ! Deallocating the receive counts and the displacement vector variables used in variable-gather communication procedures if ((format == 1 .and. n > 0) .or. n == 0) then deallocate (recvcounts) deallocate (displs) end if - #endif end subroutine s_finalize_mpi_proxy_module diff --git a/src/post_process/m_start_up.fpp b/src/post_process/m_start_up.fpp index 7ae3dbfebe..7563310c4a 100644 --- a/src/post_process/m_start_up.fpp +++ b/src/post_process/m_start_up.fpp @@ -13,128 +13,87 @@ module m_start_up use, intrinsic :: iso_c_binding use m_derived_types !< Definitions of the derived types - use m_global_parameters !< Global parameters for the code - use m_mpi_proxy !< Message passing interface (MPI) module proxy - use m_mpi_common !< Common MPI subroutines - use m_boundary_common !< Common boundary conditions subroutines - - use m_variables_conversion !< Subroutines to change the state variables from - !! one form to another - - use m_data_input !< Procedures reading raw simulation data to fill - !! the conservative, primitive and grid variables - - use m_data_output !< Procedures that write the grid and chosen flow - !! variable(s) to the formatted database file(s) - - use m_derived_variables !< Procedures used to compute quantities derived - !! from the conservative and primitive variables + use m_variables_conversion !< Subroutines to change the state variables from one form to another + use m_data_input !< Procedures reading raw simulation data to fill the conservative, primitive and grid variables + use m_data_output !< Procedures that write the grid and chosen flow variable(s) to the formatted database file(s) + use m_derived_variables !< Procedures used to compute quantities derived from the conservative and primitive variables use m_helper - use m_compile_specific - use m_checker_common - use m_checker - use m_thermochem, only: num_species, species_names - use m_finite_differences - use m_chemistry #ifdef MFC_MPI - use mpi !< Message passing interface (MPI) module + use mpi !< Message passing interface (MPI) module #endif implicit none include 'fftw3.f03' - type(c_ptr) :: fwd_plan_x, fwd_plan_y, fwd_plan_z - complex(c_double_complex), allocatable :: data_in(:), data_out(:) - complex(c_double_complex), allocatable :: data_cmplx(:, :, :), data_cmplx_y(:, :, :), data_cmplx_z(:, :, :) - real(wp), allocatable, dimension(:, :, :) :: En_real - real(wp), allocatable, dimension(:) :: En - integer :: num_procs_x, num_procs_y, num_procs_z - integer :: Nx, Ny, Nz, Nxloc, Nyloc, Nyloc2, Nzloc, Nf - integer :: ierr - integer :: MPI_COMM_CART, MPI_COMM_CART12, MPI_COMM_CART13 - integer, dimension(3) :: cart3d_coords - integer, dimension(2) :: cart2d12_coords, cart2d13_coords - integer :: proc_rank12, proc_rank13 + type(c_ptr) :: fwd_plan_x, fwd_plan_y, fwd_plan_z + complex(c_double_complex), allocatable :: data_in(:), data_out(:) + complex(c_double_complex), allocatable :: data_cmplx(:,:,:), data_cmplx_y(:,:,:), data_cmplx_z(:,:,:) + real(wp), allocatable, dimension(:,:,:) :: En_real + real(wp), allocatable, dimension(:) :: En + integer :: num_procs_x, num_procs_y, num_procs_z + integer :: Nx, Ny, Nz, Nxloc, Nyloc, Nyloc2, Nzloc, Nf + integer :: ierr + integer :: MPI_COMM_CART, MPI_COMM_CART12, MPI_COMM_CART13 + integer, dimension(3) :: cart3d_coords + integer, dimension(2) :: cart2d12_coords, cart2d13_coords + integer :: proc_rank12, proc_rank13 contains - !> Reads the configuration file post_process.inp, in order - !! to populate parameters in module m_global_parameters.f90 - !! with the user provided inputs + !> Reads the configuration file post_process.inp, in order to populate parameters in module m_global_parameters.f90 with the + !! user provided inputs impure subroutine s_read_input_file - character(LEN=name_len) :: file_loc !< - !! Generic string used to store the address of a particular file - - logical :: file_check !< - !! Generic logical used for the purpose of asserting whether a file - !! is or is not present in the designated location + character(LEN=name_len) :: file_loc !< Generic string used to store the address of a particular file + !> Generic logical used for the purpose of asserting whether a file is or is not present in the designated location + logical :: file_check integer :: iostatus - !! Integer to check iostat of file read + !! Integer to check iostat of file read character(len=1000) :: line ! Namelist for all of the parameters to be inputted by the user - namelist /user_inputs/ case_dir, m, n, p, t_step_start, & - t_step_stop, t_step_save, model_eqns, & - num_fluids, mpp_lim, & - weno_order, bc_x, & - bc_y, bc_z, fluid_pp, bub_pp, format, precision, & - output_partial_domain, x_output, y_output, z_output, & - hypoelasticity, G, mhd, & - chem_wrt_Y, chem_wrt_T, avg_state, & - alpha_rho_wrt, rho_wrt, mom_wrt, vel_wrt, & - E_wrt, fft_wrt, pres_wrt, alpha_wrt, gamma_wrt, & - heat_ratio_wrt, pi_inf_wrt, pres_inf_wrt, & - cons_vars_wrt, prim_vars_wrt, c_wrt, & - omega_wrt, qm_wrt, liutex_wrt, schlieren_wrt, schlieren_alpha, & - fd_order, mixture_err, alt_soundspeed, & - flux_lim, flux_wrt, cyl_coord, & - parallel_io, rhoref, pref, bubbles_euler, qbmm, sigR, & - R0ref, nb, polytropic, thermal, Ca, Web, Re_inv, & - polydisperse, poly_sigma, file_per_process, relax, & - relax_model, cf_wrt, sigma, adv_n, ib, num_ibs, & - cfl_adap_dt, cfl_const_dt, t_save, t_stop, n_start, & - cfl_target, surface_tension, bubbles_lagrange, & - sim_data, hyperelasticity, Bx0, relativity, cont_damage, hyper_cleaning, & - num_bc_patches, igr, igr_order, down_sample, recon_type, & - muscl_order, lag_header, lag_txt_wrt, lag_db_wrt, & - lag_id_wrt, lag_pos_wrt, lag_pos_prev_wrt, lag_vel_wrt, & - lag_rad_wrt, lag_rvel_wrt, lag_r0_wrt, lag_rmax_wrt, & - lag_rmin_wrt, lag_dphidt_wrt, lag_pres_wrt, lag_mv_wrt, & - lag_mg_wrt, lag_betaT_wrt, lag_betaC_wrt, & - alpha_rho_e_wrt, ib_state_wrt + + namelist /user_inputs/ case_dir, m, n, p, t_step_start, t_step_stop, t_step_save, model_eqns, num_fluids, mpp_lim, & + & weno_order, bc_x, bc_y, bc_z, fluid_pp, bub_pp, format, precision, output_partial_domain, x_output, y_output, & + & z_output, hypoelasticity, G, mhd, chem_wrt_Y, chem_wrt_T, avg_state, alpha_rho_wrt, rho_wrt, mom_wrt, vel_wrt, & + & E_wrt, fft_wrt, pres_wrt, alpha_wrt, gamma_wrt, heat_ratio_wrt, pi_inf_wrt, pres_inf_wrt, cons_vars_wrt, & + & prim_vars_wrt, c_wrt, omega_wrt, qm_wrt, liutex_wrt, schlieren_wrt, schlieren_alpha, fd_order, mixture_err, & + & alt_soundspeed, flux_lim, flux_wrt, cyl_coord, parallel_io, rhoref, pref, bubbles_euler, qbmm, sigR, R0ref, nb, & + & polytropic, thermal, Ca, Web, Re_inv, polydisperse, poly_sigma, file_per_process, relax, relax_model, cf_wrt, & + & sigma, adv_n, ib, num_ibs, cfl_adap_dt, cfl_const_dt, t_save, t_stop, n_start, cfl_target, surface_tension, & + & bubbles_lagrange, sim_data, hyperelasticity, Bx0, relativity, cont_damage, hyper_cleaning, num_bc_patches, igr, & + & igr_order, down_sample, recon_type, muscl_order, lag_header, lag_txt_wrt, lag_db_wrt, lag_id_wrt, lag_pos_wrt, & + & lag_pos_prev_wrt, lag_vel_wrt, lag_rad_wrt, lag_rvel_wrt, lag_r0_wrt, lag_rmax_wrt, lag_rmin_wrt, lag_dphidt_wrt, & + & lag_pres_wrt, lag_mv_wrt, lag_mg_wrt, lag_betaT_wrt, lag_betaC_wrt, alpha_rho_e_wrt, ib_state_wrt ! Inquiring the status of the post_process.inp file file_loc = 'post_process.inp' inquire (FILE=trim(file_loc), EXIST=file_check) - ! Checking whether the input file is there. If it is, the input file - ! is read. If not, the program is terminated. + ! Checking whether the input file is there. If it is, the input file is read. If not, the program is terminated. if (file_check) then - open (1, FILE=trim(file_loc), FORM='formatted', & - STATUS='old', ACTION='read') + open (1, FILE=trim(file_loc), form='formatted', STATUS='old', ACTION='read') read (1, NML=user_inputs, iostat=iostatus) if (iostatus /= 0) then backspace (1) read (1, fmt='(A)') line - print *, 'Invalid line in namelist: '//trim(line) - call s_mpi_abort('Invalid line in post_process.inp. It is '// & - 'likely due to a datatype mismatch. Exiting.') + print *, 'Invalid line in namelist: ' // trim(line) + call s_mpi_abort('Invalid line in post_process.inp. It is ' // 'likely due to a datatype mismatch. Exiting.') end if close (1) @@ -156,40 +115,33 @@ contains if (cfl_adap_dt .or. cfl_const_dt) cfl_dt = .true. - if (any((/bc_x%beg, bc_x%end, bc_y%beg, bc_y%end, bc_z%beg, bc_z%end/) == -17) .or. & - num_bc_patches > 0) then + if (any((/bc_x%beg, bc_x%end, bc_y%beg, bc_y%end, bc_z%beg, bc_z%end/) == -17) .or. num_bc_patches > 0) then bc_io = .true. end if - else call s_mpi_abort('File post_process.inp is missing. Exiting.') end if end subroutine s_read_input_file - !> Checking that the user inputs make sense, i.e. that the - !! individual choices are compatible with the code's options - !! and that the combination of these choices results into a - !! valid configuration for the post-process + !> Checking that the user inputs make sense, i.e. that the individual choices are compatible with the code's options and that + !! the combination of these choices results into a valid configuration for the post-process impure subroutine s_check_input_file - character(LEN=len_trim(case_dir)) :: file_loc !< - !! Generic string used to store the address of a particular file - - logical :: dir_check !< - !! Logical variable used to test the existence of folders + character(LEN=len_trim(case_dir)) :: file_loc !< Generic string used to store the address of a particular file + logical :: dir_check !< Logical variable used to test the existence of folders ! Checking the existence of the case folder + case_dir = adjustl(case_dir) - file_loc = trim(case_dir)//'/.' + file_loc = trim(case_dir) // '/.' call my_inquire(file_loc, dir_check) ! Constraint on the location of the case directory if (dir_check .neqv. .true.) then - call s_mpi_abort('Unsupported choice for the value of '// & - 'case_dir. Exiting.') + call s_mpi_abort('Unsupported choice for the value of ' // 'case_dir. Exiting.') end if call s_check_inputs_common() @@ -201,17 +153,16 @@ contains impure subroutine s_perform_time_step(t_step) integer, intent(inout) :: t_step + if (proc_rank == 0) then if (cfl_dt) then print '(" [", I3, "%] Saving ", I8, " of ", I0, " Time Avg = ", ES16.6, " Time/step = ", ES12.6, "")', & - int(ceiling(100._wp*(real(t_step - n_start)/(n_save)))), & - t_step, n_save, wall_time_avg, wall_time + & int(ceiling(100._wp*(real(t_step - n_start)/(n_save)))), t_step, n_save, wall_time_avg, wall_time else print '(" [", I3, "%] Saving ", I8, " of ", I0, " @ t_step = ", I8, " Time Avg = ", ES16.6, " Time/step = ", ES12.6, "")', & - int(ceiling(100._wp*(real(t_step - t_step_start)/(t_step_stop - t_step_start + 1)))), & - (t_step - t_step_start)/t_step_save + 1, & - (t_step_stop - t_step_start)/t_step_save + 1, & - t_step, wall_time_avg, wall_time + & int(ceiling(100._wp*(real(t_step - t_step_start)/(t_step_stop - t_step_start + 1)))), & + & (t_step - t_step_start)/t_step_save + 1, (t_step_stop - t_step_start)/t_step_save + 1, t_step, & + & wall_time_avg, wall_time end if end if @@ -235,21 +186,20 @@ contains !> @brief Derive requested flow quantities from primitive variables and write them to the formatted database files. impure subroutine s_save_data(t_step, varname, pres, c, H) - integer, intent(inout) :: t_step + integer, intent(inout) :: t_step character(LEN=name_len), intent(inout) :: varname - real(wp), intent(inout) :: pres, c, H - real(wp) :: theta1, theta2 - real(wp), dimension(-offset_x%beg:m + offset_x%end, & - -offset_y%beg:n + offset_y%end, & - -offset_z%beg:p + offset_z%end) :: liutex_mag - real(wp), dimension(-offset_x%beg:m + offset_x%end, & - -offset_y%beg:n + offset_y%end, & - -offset_z%beg:p + offset_z%end, 3) :: liutex_axis - integer :: i, j, k, l, kx, ky, kz, kf, j_glb, k_glb, l_glb - real(wp) :: En_tot + real(wp), intent(inout) :: pres, c, H + real(wp) :: theta1, theta2 + + real(wp), dimension(-offset_x%beg:m + offset_x%end,-offset_y%beg:n + offset_y%end, & + & -offset_z%beg:p + offset_z%end) :: liutex_mag + real(wp), dimension(-offset_x%beg:m + offset_x%end,-offset_y%beg:n + offset_y%end,-offset_z%beg:p + offset_z%end, & + & 3) :: liutex_axis + integer :: i, j, k, l, kx, ky, kz, kf, j_glb, k_glb, l_glb + real(wp) :: En_tot character(50) :: filename, dirname - logical :: file_exists, dir_exists - integer :: x_beg, x_end, y_beg, y_end, z_beg, z_end + logical :: file_exists, dir_exists + integer :: x_beg, x_end, y_beg, y_end, z_beg, z_end if (output_partial_domain) then call s_define_output_region @@ -286,30 +236,24 @@ contains ! Computing centered finite-difference coefficients in x-direction if (omega_wrt(2) .or. omega_wrt(3) .or. qm_wrt .or. liutex_wrt .or. schlieren_wrt) then - call s_compute_finite_difference_coefficients(m, x_cc, & - fd_coeff_x, buff_size, & - fd_number, fd_order, offset_x) + call s_compute_finite_difference_coefficients(m, x_cc, fd_coeff_x, buff_size, fd_number, fd_order, offset_x) end if ! Computing centered finite-difference coefficients in y-direction if (omega_wrt(1) .or. omega_wrt(3) .or. qm_wrt .or. liutex_wrt .or. (n > 0 .and. schlieren_wrt)) then - call s_compute_finite_difference_coefficients(n, y_cc, & - fd_coeff_y, buff_size, & - fd_number, fd_order, offset_y) + call s_compute_finite_difference_coefficients(n, y_cc, fd_coeff_y, buff_size, fd_number, fd_order, offset_y) end if ! Computing centered finite-difference coefficients in z-direction if (omega_wrt(1) .or. omega_wrt(2) .or. qm_wrt .or. liutex_wrt .or. (p > 0 .and. schlieren_wrt)) then - call s_compute_finite_difference_coefficients(p, z_cc, & - fd_coeff_z, buff_size, & - fd_number, fd_order, offset_z) + call s_compute_finite_difference_coefficients(p, z_cc, fd_coeff_z, buff_size, fd_number, fd_order, offset_z) end if ! Adding the partial densities to the formatted database file if ((model_eqns == 2) .or. (model_eqns == 3) .or. (model_eqns == 4)) then do i = 1, num_fluids if (alpha_rho_wrt(i) .or. (cons_vars_wrt .or. prim_vars_wrt)) then - q_sf(:, :, :) = q_cons_vf(i)%sf(x_beg:x_end, y_beg:y_end, z_beg:z_end) + q_sf(:,:,:) = q_cons_vf(i)%sf(x_beg:x_end,y_beg:y_end,z_beg:z_end) if (model_eqns /= 4) then write (varname, '(A,I0)') 'alpha_rho', i else @@ -318,14 +262,13 @@ contains call s_write_variable_to_formatted_database_file(varname, t_step) varname(:) = ' ' - end if end do end if ! Adding the density to the formatted database file if ((rho_wrt .or. (model_eqns == 1 .and. (cons_vars_wrt .or. prim_vars_wrt))) .and. (.not. relativity)) then - q_sf(:, :, :) = rho_sf(x_beg:x_end, y_beg:y_end, z_beg:z_end) + q_sf(:,:,:) = rho_sf(x_beg:x_end,y_beg:y_end,z_beg:z_end) write (varname, '(A)') 'rho' call s_write_variable_to_formatted_database_file(varname, t_step) @@ -333,7 +276,7 @@ contains end if if (relativity .and. (rho_wrt .or. prim_vars_wrt)) then - q_sf(:, :, :) = q_prim_vf(1)%sf(x_beg:x_end, y_beg:y_end, z_beg:z_end) + q_sf(:,:,:) = q_prim_vf(1)%sf(x_beg:x_end,y_beg:y_end,z_beg:z_end) write (varname, '(A)') 'rho' call s_write_variable_to_formatted_database_file(varname, t_step) @@ -341,9 +284,8 @@ contains end if if (relativity .and. (rho_wrt .or. cons_vars_wrt)) then - ! For relativistic flow, conservative and primitive densities are different - ! Hard-coded single-component for now - q_sf(:, :, :) = q_cons_vf(1)%sf(x_beg:x_end, y_beg:y_end, z_beg:z_end) + ! For relativistic flow, conservative and primitive densities are different Hard-coded single-component for now + q_sf(:,:,:) = q_cons_vf(1)%sf(x_beg:x_end,y_beg:y_end,z_beg:z_end) write (varname, '(A)') 'D' call s_write_variable_to_formatted_database_file(varname, t_step) @@ -353,24 +295,22 @@ contains ! Adding the momentum to the formatted database file do i = 1, E_idx - mom_idx%beg if (mom_wrt(i) .or. cons_vars_wrt) then - q_sf(:, :, :) = q_cons_vf(i + cont_idx%end)%sf(x_beg:x_end, y_beg:y_end, z_beg:z_end) + q_sf(:,:,:) = q_cons_vf(i + cont_idx%end)%sf(x_beg:x_end,y_beg:y_end,z_beg:z_end) write (varname, '(A,I0)') 'mom', i call s_write_variable_to_formatted_database_file(varname, t_step) varname(:) = ' ' - end if end do ! Adding the velocity to the formatted database file do i = 1, E_idx - mom_idx%beg if (vel_wrt(i) .or. prim_vars_wrt) then - q_sf(:, :, :) = q_prim_vf(i + cont_idx%end)%sf(x_beg:x_end, y_beg:y_end, z_beg:z_end) + q_sf(:,:,:) = q_prim_vf(i + cont_idx%end)%sf(x_beg:x_end,y_beg:y_end,z_beg:z_end) write (varname, '(A,I0)') 'vel', i call s_write_variable_to_formatted_database_file(varname, t_step) varname(:) = ' ' - end if end do @@ -378,17 +318,16 @@ contains if (chemistry) then do i = 1, num_species if (chem_wrt_Y(i) .or. prim_vars_wrt) then - q_sf(:, :, :) = q_prim_vf(chemxb + i - 1)%sf(x_beg:x_end, y_beg:y_end, z_beg:z_end) + q_sf(:,:,:) = q_prim_vf(chemxb + i - 1)%sf(x_beg:x_end,y_beg:y_end,z_beg:z_end) write (varname, '(A,A)') 'Y_', trim(species_names(i)) call s_write_variable_to_formatted_database_file(varname, t_step) varname(:) = ' ' - end if end do if (chem_wrt_T) then - q_sf(:, :, :) = q_T_sf%sf(x_beg:x_end, y_beg:y_end, z_beg:z_end) + q_sf(:,:,:) = q_T_sf%sf(x_beg:x_end,y_beg:y_end,z_beg:z_end) write (varname, '(A)') 'T' call s_write_variable_to_formatted_database_file(varname, t_step) @@ -399,7 +338,6 @@ contains ! Adding the flux limiter function to the formatted database file do i = 1, E_idx - mom_idx%beg if (flux_wrt(i)) then - call s_derive_flux_limiter(i, q_prim_vf, q_sf) write (varname, '(A,I0)') 'flux', i @@ -411,19 +349,18 @@ contains ! Adding the energy to the formatted database file if (E_wrt .or. cons_vars_wrt) then - q_sf(:, :, :) = q_cons_vf(E_idx)%sf(x_beg:x_end, y_beg:y_end, z_beg:z_end) + q_sf(:,:,:) = q_cons_vf(E_idx)%sf(x_beg:x_end,y_beg:y_end,z_beg:z_end) write (varname, '(A)') 'E' call s_write_variable_to_formatted_database_file(varname, t_step) varname(:) = ' ' - end if ! Adding the individual energies to the formatted database file if (model_eqns == 3) then do i = 1, num_fluids if (alpha_rho_e_wrt(i) .or. cons_vars_wrt) then - q_sf = q_cons_vf(i + intxb - 1)%sf(x_beg:x_end, y_beg:y_end, z_beg:z_end) + q_sf = q_cons_vf(i + intxb - 1)%sf(x_beg:x_end,y_beg:y_end,z_beg:z_end) write (varname, '(A,I0)') 'alpha_rho_e', i call s_write_variable_to_formatted_database_file(varname, t_step) @@ -432,9 +369,8 @@ contains end do end if - !Adding Energy cascade FFT + ! Adding Energy cascade FFT if (fft_wrt) then - do l = 0, p do k = 0, n do j = 0, m @@ -450,7 +386,8 @@ contains do l = 0, p do k = 0, n do j = 0, m - data_cmplx(j + 1, k + 1, l + 1) = cmplx(q_cons_vf(mom_idx%beg + 1)%sf(j, k, l)/q_cons_vf(1)%sf(j, k, l), 0._wp) + data_cmplx(j + 1, k + 1, l + 1) = cmplx(q_cons_vf(mom_idx%beg + 1)%sf(j, k, l)/q_cons_vf(1)%sf(j, k, l), & + & 0._wp) end do end do end do @@ -462,7 +399,8 @@ contains do l = 0, p do k = 0, n do j = 0, m - data_cmplx(j + 1, k + 1, l + 1) = cmplx(q_cons_vf(mom_idx%beg + 2)%sf(j, k, l)/q_cons_vf(1)%sf(j, k, l), 0._wp) + data_cmplx(j + 1, k + 1, l + 1) = cmplx(q_cons_vf(mom_idx%beg + 2)%sf(j, k, l)/q_cons_vf(1)%sf(j, k, l), & + & 0._wp) end do end do end do @@ -478,7 +416,6 @@ contains do l = 1, Nz do k = 1, Nyloc2 do j = 1, Nxloc - j_glb = j + cart3d_coords(2)*Nxloc k_glb = k + cart3d_coords(3)*Nyloc2 l_glb = l @@ -504,7 +441,6 @@ contains kf = nint(sqrt(kx**2._wp + ky**2._wp + kz**2._wp)) + 1 En(kf) = En(kf) + En_real(j, k, l) - end do end do end do @@ -537,13 +473,12 @@ contains end if end if end do - end if ! Adding the magnetic field to the formatted database file if (mhd .and. prim_vars_wrt) then do i = B_idx%beg, B_idx%end - q_sf(:, :, :) = q_prim_vf(i)%sf(x_beg:x_end, y_beg:y_end, z_beg:z_end) + q_sf(:,:,:) = q_prim_vf(i)%sf(x_beg:x_end,y_beg:y_end,z_beg:z_end) ! 1D: output By, Bz if (n == 0) then @@ -556,7 +491,7 @@ contains else if (i == B_idx%beg) then write (varname, '(A)') 'Bx' - elseif (i == B_idx%beg + 1) then + else if (i == B_idx%beg + 1) then write (varname, '(A)') 'By' else write (varname, '(A)') 'Bz' @@ -572,7 +507,7 @@ contains if (elasticity) then do i = 1, stress_idx%end - stress_idx%beg + 1 if (prim_vars_wrt) then - q_sf(:, :, :) = q_prim_vf(i - 1 + stress_idx%beg)%sf(x_beg:x_end, y_beg:y_end, z_beg:z_end) + q_sf(:,:,:) = q_prim_vf(i - 1 + stress_idx%beg)%sf(x_beg:x_end,y_beg:y_end,z_beg:z_end) write (varname, '(A,I0)') 'tau', i call s_write_variable_to_formatted_database_file(varname, t_step) end if @@ -583,7 +518,7 @@ contains if (hyperelasticity) then do i = 1, xiend - xibeg + 1 if (prim_vars_wrt) then - q_sf(:, :, :) = q_prim_vf(i - 1 + xibeg)%sf(x_beg:x_end, y_beg:y_end, z_beg:z_end) + q_sf(:,:,:) = q_prim_vf(i - 1 + xibeg)%sf(x_beg:x_end,y_beg:y_end,z_beg:z_end) write (varname, '(A,I0)') 'xi', i call s_write_variable_to_formatted_database_file(varname, t_step) end if @@ -592,7 +527,7 @@ contains end if if (cont_damage) then - q_sf(:, :, :) = q_cons_vf(damage_idx)%sf(x_beg:x_end, y_beg:y_end, z_beg:z_end) + q_sf(:,:,:) = q_cons_vf(damage_idx)%sf(x_beg:x_end,y_beg:y_end,z_beg:z_end) write (varname, '(A)') 'damage_state' call s_write_variable_to_formatted_database_file(varname, t_step) @@ -600,7 +535,7 @@ contains end if if (hyper_cleaning) then - q_sf = q_cons_vf(psi_idx)%sf(x_beg:x_end, y_beg:y_end, z_beg:z_end) + q_sf = q_cons_vf(psi_idx)%sf(x_beg:x_end,y_beg:y_end,z_beg:z_end) write (varname, '(A)') 'psi' call s_write_variable_to_formatted_database_file(varname, t_step) @@ -609,33 +544,26 @@ contains ! Adding the pressure to the formatted database file if (pres_wrt .or. prim_vars_wrt) then - q_sf(:, :, :) = q_prim_vf(E_idx)%sf(x_beg:x_end, y_beg:y_end, z_beg:z_end) + q_sf(:,:,:) = q_prim_vf(E_idx)%sf(x_beg:x_end,y_beg:y_end,z_beg:z_end) write (varname, '(A)') 'pres' call s_write_variable_to_formatted_database_file(varname, t_step) varname(:) = ' ' - end if ! Adding the volume fraction(s) to the formatted database file - if (((model_eqns == 2) .and. (bubbles_euler .neqv. .true.)) & - .or. (model_eqns == 3) & - ) then - + if (((model_eqns == 2) .and. (bubbles_euler .neqv. .true.)) .or. (model_eqns == 3)) then do i = 1, num_fluids - 1 if (alpha_wrt(i) .or. (cons_vars_wrt .or. prim_vars_wrt)) then - q_sf(:, :, :) = q_cons_vf(i + E_idx)%sf(x_beg:x_end, y_beg:y_end, z_beg:z_end) + q_sf(:,:,:) = q_cons_vf(i + E_idx)%sf(x_beg:x_end,y_beg:y_end,z_beg:z_end) write (varname, '(A,I0)') 'alpha', i call s_write_variable_to_formatted_database_file(varname, t_step) varname(:) = ' ' - end if end do - if (alpha_wrt(num_fluids) & - .or. & - (cons_vars_wrt .or. prim_vars_wrt)) then + if (alpha_wrt(num_fluids) .or. (cons_vars_wrt .or. prim_vars_wrt)) then if (igr) then do k = z_beg, z_end do j = y_beg, y_end @@ -648,63 +576,51 @@ contains end do end do else - q_sf(:, :, :) = q_cons_vf(adv_idx%end)%sf(x_beg:x_end, y_beg:y_end, z_beg:z_end) + q_sf(:,:,:) = q_cons_vf(adv_idx%end)%sf(x_beg:x_end,y_beg:y_end,z_beg:z_end) end if write (varname, '(A,I0)') 'alpha', num_fluids call s_write_variable_to_formatted_database_file(varname, t_step) varname(:) = ' ' - end if - end if ! Adding specific heat ratio function to formatted database file - if (gamma_wrt & - .or. & - (model_eqns == 1 .and. (cons_vars_wrt .or. prim_vars_wrt))) then - q_sf(:, :, :) = gamma_sf(x_beg:x_end, y_beg:y_end, z_beg:z_end) + if (gamma_wrt .or. (model_eqns == 1 .and. (cons_vars_wrt .or. prim_vars_wrt))) then + q_sf(:,:,:) = gamma_sf(x_beg:x_end,y_beg:y_end,z_beg:z_end) write (varname, '(A)') 'gamma' call s_write_variable_to_formatted_database_file(varname, t_step) varname(:) = ' ' - end if ! Adding the specific heat ratio to the formatted database file if (heat_ratio_wrt) then - call s_derive_specific_heat_ratio(q_sf) write (varname, '(A)') 'heat_ratio' call s_write_variable_to_formatted_database_file(varname, t_step) varname(:) = ' ' - end if ! Adding liquid stiffness function to formatted database file - if (pi_inf_wrt & - .or. & - (model_eqns == 1 .and. (cons_vars_wrt .or. prim_vars_wrt))) then - q_sf(:, :, :) = pi_inf_sf(x_beg:x_end, y_beg:y_end, z_beg:z_end) + if (pi_inf_wrt .or. (model_eqns == 1 .and. (cons_vars_wrt .or. prim_vars_wrt))) then + q_sf(:,:,:) = pi_inf_sf(x_beg:x_end,y_beg:y_end,z_beg:z_end) write (varname, '(A)') 'pi_inf' call s_write_variable_to_formatted_database_file(varname, t_step) varname(:) = ' ' - end if ! Adding the liquid stiffness to the formatted database file if (pres_inf_wrt) then - call s_derive_liquid_stiffness(q_sf) write (varname, '(A)') 'pres_inf' call s_write_variable_to_formatted_database_file(varname, t_step) varname(:) = ' ' - end if ! Adding the sound speed to the formatted database file @@ -718,12 +634,10 @@ contains pres = q_prim_vf(E_idx)%sf(i, j, k) - H = ((gamma_sf(i, j, k) + 1._wp)*pres + & - pi_inf_sf(i, j, k) + qv_sf(i, j, k))/rho_sf(i, j, k) + H = ((gamma_sf(i, j, k) + 1._wp)*pres + pi_inf_sf(i, j, k) + qv_sf(i, j, k))/rho_sf(i, j, k) - call s_compute_speed_of_sound(pres, rho_sf(i, j, k), & - gamma_sf(i, j, k), pi_inf_sf(i, j, k), & - H, adv, 0._wp, 0._wp, c, qv_sf(i, j, k)) + call s_compute_speed_of_sound(pres, rho_sf(i, j, k), gamma_sf(i, j, k), pi_inf_sf(i, j, k), H, adv, & + & 0._wp, 0._wp, c, qv_sf(i, j, k)) q_sf(i, j, k) = c end do @@ -734,13 +648,11 @@ contains call s_write_variable_to_formatted_database_file(varname, t_step) varname(:) = ' ' - end if ! Adding the vorticity to the formatted database file do i = 1, 3 if (omega_wrt(i)) then - call s_derive_vorticity_component(i, q_prim_vf, q_sf) write (varname, '(A,I0)') 'omega', i @@ -751,7 +663,8 @@ contains end do if (ib) then - q_sf(:, :, :) = real(ib_markers%sf(-offset_x%beg:m + offset_x%end, -offset_y%beg:n + offset_y%end, -offset_z%beg:p + offset_z%end)) + q_sf(:,:,:) = real(ib_markers%sf(-offset_x%beg:m + offset_x%end,-offset_y%beg:n + offset_y%end, & + & -offset_z%beg:p + offset_z%end)) varname = 'ib_markers' call s_write_variable_to_formatted_database_file(varname, t_step) end if @@ -768,7 +681,6 @@ contains ! Adding Liutex magnitude to the formatted database file if (liutex_wrt) then - ! Compute Liutex vector and its magnitude call s_derive_liutex(q_prim_vf, liutex_mag, liutex_axis) @@ -782,41 +694,37 @@ contains ! Liutex axis do i = 1, 3 - q_sf = liutex_axis(:, :, :, i) + q_sf = liutex_axis(:,:,:,i) write (varname, '(A,I0)') 'liutex_axis', i call s_write_variable_to_formatted_database_file(varname, t_step) varname(:) = ' ' end do - end if ! Adding numerical Schlieren function to formatted database file if (schlieren_wrt) then - call s_derive_numerical_schlieren_function(q_cons_vf, q_sf) write (varname, '(A)') 'schlieren' call s_write_variable_to_formatted_database_file(varname, t_step) varname(:) = ' ' - end if ! Adding the color function to formatted database file if (cf_wrt) then - q_sf(:, :, :) = q_cons_vf(c_idx)%sf(x_beg:x_end, y_beg:y_end, z_beg:z_end) + q_sf(:,:,:) = q_cons_vf(c_idx)%sf(x_beg:x_end,y_beg:y_end,z_beg:z_end) write (varname, '(A,I0)') 'color_function' call s_write_variable_to_formatted_database_file(varname, t_step) varname(:) = ' ' - end if ! Adding the volume fraction(s) to the formatted database file if (bubbles_euler) then do i = adv_idx%beg, adv_idx%end - q_sf(:, :, :) = q_cons_vf(i)%sf(x_beg:x_end, y_beg:y_end, z_beg:z_end) + q_sf(:,:,:) = q_cons_vf(i)%sf(x_beg:x_end,y_beg:y_end,z_beg:z_end) write (varname, '(A,I0)') 'alpha', i - E_idx call s_write_variable_to_formatted_database_file(varname, t_step) varname(:) = ' ' @@ -825,33 +733,33 @@ contains ! Adding the bubble variables to the formatted database file if (bubbles_euler) then - !nR + ! nR do i = 1, nb - q_sf(:, :, :) = q_cons_vf(bub_idx%rs(i))%sf(x_beg:x_end, y_beg:y_end, z_beg:z_end) + q_sf(:,:,:) = q_cons_vf(bub_idx%rs(i))%sf(x_beg:x_end,y_beg:y_end,z_beg:z_end) write (varname, '(A,I3.3)') 'nR', i call s_write_variable_to_formatted_database_file(varname, t_step) varname(:) = ' ' end do - !nRdot + ! nRdot do i = 1, nb - q_sf(:, :, :) = q_cons_vf(bub_idx%vs(i))%sf(x_beg:x_end, y_beg:y_end, z_beg:z_end) + q_sf(:,:,:) = q_cons_vf(bub_idx%vs(i))%sf(x_beg:x_end,y_beg:y_end,z_beg:z_end) write (varname, '(A,I3.3)') 'nV', i call s_write_variable_to_formatted_database_file(varname, t_step) varname(:) = ' ' end do if ((polytropic .neqv. .true.) .and. (.not. qbmm)) then - !nP + ! nP do i = 1, nb - q_sf(:, :, :) = q_cons_vf(bub_idx%ps(i))%sf(x_beg:x_end, y_beg:y_end, z_beg:z_end) + q_sf(:,:,:) = q_cons_vf(bub_idx%ps(i))%sf(x_beg:x_end,y_beg:y_end,z_beg:z_end) write (varname, '(A,I3.3)') 'nP', i call s_write_variable_to_formatted_database_file(varname, t_step) varname(:) = ' ' end do - !nM + ! nM do i = 1, nb - q_sf(:, :, :) = q_cons_vf(bub_idx%ms(i))%sf(x_beg:x_end, y_beg:y_end, z_beg:z_end) + q_sf(:,:,:) = q_cons_vf(bub_idx%ms(i))%sf(x_beg:x_end,y_beg:y_end,z_beg:z_end) write (varname, '(A,I3.3)') 'nM', i call s_write_variable_to_formatted_database_file(varname, t_step) varname(:) = ' ' @@ -860,7 +768,7 @@ contains ! number density if (adv_n) then - q_sf(:, :, :) = q_cons_vf(n_idx)%sf(x_beg:x_end, y_beg:y_end, z_beg:z_end) + q_sf(:,:,:) = q_cons_vf(n_idx)%sf(x_beg:x_end,y_beg:y_end,z_beg:z_end) write (varname, '(A)') 'n' call s_write_variable_to_formatted_database_file(varname, t_step) varname(:) = ' ' @@ -870,16 +778,14 @@ contains ! Adding the lagrangian subgrid variables to the formatted database file if (bubbles_lagrange) then !! Void fraction field - q_sf(:, :, :) = 1._wp - q_cons_vf(beta_idx)%sf( & - -offset_x%beg:m + offset_x%end, & - -offset_y%beg:n + offset_y%end, & - -offset_z%beg:p + offset_z%end) + q_sf(:,:,:) = 1._wp - q_cons_vf(beta_idx)%sf(-offset_x%beg:m + offset_x%end,-offset_y%beg:n + offset_y%end, & + & -offset_z%beg:p + offset_z%end) write (varname, '(A)') 'voidFraction' call s_write_variable_to_formatted_database_file(varname, t_step) varname(:) = ' ' - if (lag_txt_wrt) call s_write_lag_bubbles_results_to_text(t_step) ! text output - if (lag_db_wrt) call s_write_lag_bubbles_to_formatted_database_file(t_step) ! silo file output + if (lag_txt_wrt) call s_write_lag_bubbles_results_to_text(t_step) ! text output + if (lag_db_wrt) call s_write_lag_bubbles_to_formatted_database_file(t_step) ! silo file output end if if (sim_data .and. proc_rank == 0) then @@ -894,12 +800,12 @@ contains !> @brief Transpose 3-D complex data from x-pencil to y-pencil layout via MPI_Alltoall. subroutine s_mpi_transpose_x2y + complex(c_double_complex), allocatable :: sendbuf(:), recvbuf(:) - integer :: dest_rank, src_rank - integer :: i, j, k, l + integer :: dest_rank, src_rank + integer :: i, j, k, l #ifdef MFC_MPI - allocate (sendbuf(Nx*Nyloc*Nzloc)) allocate (recvbuf(Nx*Nyloc*Nzloc)) @@ -907,20 +813,22 @@ contains do l = 1, Nzloc do k = 1, Nyloc do j = 1, Nxloc - sendbuf(j + (k - 1)*Nxloc + (l - 1)*Nxloc*Nyloc + dest_rank*Nxloc*Nyloc*Nzloc) = data_cmplx(j + dest_rank*Nxloc, k, l) + sendbuf(j + (k - 1)*Nxloc + (l - 1)*Nxloc*Nyloc + dest_rank*Nxloc*Nyloc*Nzloc) = data_cmplx(j & + & + dest_rank*Nxloc, k, l) end do end do end do end do - call MPI_Alltoall(sendbuf, Nxloc*Nyloc*Nzloc, MPI_C_DOUBLE_COMPLEX, & - recvbuf, Nxloc*Nyloc*Nzloc, MPI_C_DOUBLE_COMPLEX, MPI_COMM_CART12, ierr) + call MPI_Alltoall(sendbuf, Nxloc*Nyloc*Nzloc, MPI_C_DOUBLE_COMPLEX, recvbuf, Nxloc*Nyloc*Nzloc, MPI_C_DOUBLE_COMPLEX, & + & MPI_COMM_CART12, ierr) do src_rank = 0, num_procs_y - 1 do l = 1, Nzloc do k = 1, Nyloc do j = 1, Nxloc - data_cmplx_y(j, k + src_rank*Nyloc, l) = recvbuf(j + (k - 1)*Nxloc + (l - 1)*Nxloc*Nyloc + src_rank*Nxloc*Nyloc*Nzloc) + data_cmplx_y(j, k + src_rank*Nyloc, & + & l) = recvbuf(j + (k - 1)*Nxloc + (l - 1)*Nxloc*Nyloc + src_rank*Nxloc*Nyloc*Nzloc) end do end do end do @@ -928,19 +836,18 @@ contains deallocate (sendbuf) deallocate (recvbuf) - #endif end subroutine s_mpi_transpose_x2y !> @brief Transpose 3-D complex data from y-pencil to z-pencil layout via MPI_Alltoall. subroutine s_mpi_transpose_y2z + complex(c_double_complex), allocatable :: sendbuf(:), recvbuf(:) - integer :: dest_rank, src_rank - integer :: j, k, l + integer :: dest_rank, src_rank + integer :: j, k, l #ifdef MFC_MPI - allocate (sendbuf(Ny*Nxloc*Nzloc)) allocate (recvbuf(Ny*Nxloc*Nzloc)) @@ -948,20 +855,23 @@ contains do l = 1, Nzloc do j = 1, Nxloc do k = 1, Nyloc2 - sendbuf(k + (j - 1)*Nyloc2 + (l - 1)*(Nyloc2*Nxloc) + dest_rank*Nyloc2*Nxloc*Nzloc) = data_cmplx_y(j, k + dest_rank*Nyloc2, l) + sendbuf(k + (j - 1)*Nyloc2 + (l - 1)*(Nyloc2*Nxloc) + dest_rank*Nyloc2*Nxloc*Nzloc) = data_cmplx_y(j, & + & k + dest_rank*Nyloc2, l) end do end do end do end do - call MPI_Alltoall(sendbuf, Nyloc2*Nxloc*Nzloc, MPI_C_DOUBLE_COMPLEX, & - recvbuf, Nyloc2*Nxloc*Nzloc, MPI_C_DOUBLE_COMPLEX, MPI_COMM_CART13, ierr) + call MPI_Alltoall(sendbuf, Nyloc2*Nxloc*Nzloc, MPI_C_DOUBLE_COMPLEX, recvbuf, Nyloc2*Nxloc*Nzloc, MPI_C_DOUBLE_COMPLEX, & + & MPI_COMM_CART13, ierr) do src_rank = 0, num_procs_z - 1 do l = 1, Nzloc do j = 1, Nxloc do k = 1, Nyloc2 - data_cmplx_z(j, k, l + src_rank*Nzloc) = recvbuf(k + (j - 1)*Nyloc2 + (l - 1)*(Nyloc2*Nxloc) + src_rank*Nyloc2*Nxloc*Nzloc) + data_cmplx_z(j, k, & + & l + src_rank*Nzloc) = recvbuf(k + (j - 1)*Nyloc2 + (l - 1)*(Nyloc2*Nxloc) & + & + src_rank*Nyloc2*Nxloc*Nzloc) end do end do end do @@ -969,15 +879,14 @@ contains deallocate (sendbuf) deallocate (recvbuf) - #endif end subroutine s_mpi_transpose_y2z !> @brief Initialize all post-process sub-modules, set up I/O pointers, and prepare FFTW plans and MPI communicators. impure subroutine s_initialize_modules - ! Computation of parameters, allocation procedures, and/or any other tasks - ! needed to properly setup the modules + + ! Computation of parameters, allocation procedures, and/or any other tasks needed to properly setup the modules integer :: size_n(1), inembed(1), onembed(1) call s_initialize_global_parameters_module() @@ -1003,7 +912,6 @@ contains #ifdef MFC_MPI if (fft_wrt) then - num_procs_x = (m_glb + 1)/(m + 1) num_procs_y = (n_glb + 1)/(n + 1) num_procs_z = (p_glb + 1)/(p + 1) @@ -1033,35 +941,26 @@ contains inembed(1) = Nx onembed(1) = Nx - fwd_plan_x = fftw_plan_many_dft(1, size_n, Nyloc*Nzloc, & - data_in, inembed, 1, Nx, & - data_out, onembed, 1, Nx, & - FFTW_FORWARD, FFTW_MEASURE) + fwd_plan_x = fftw_plan_many_dft(1, size_n, Nyloc*Nzloc, data_in, inembed, 1, Nx, data_out, onembed, 1, Nx, & + & FFTW_FORWARD, FFTW_MEASURE) size_n(1) = Ny inembed(1) = Ny onembed(1) = Ny - fwd_plan_y = fftw_plan_many_dft(1, size_n, Nxloc*Nzloc, & - data_out, inembed, 1, Ny, & - data_in, onembed, 1, Ny, & - FFTW_FORWARD, FFTW_MEASURE) + fwd_plan_y = fftw_plan_many_dft(1, size_n, Nxloc*Nzloc, data_out, inembed, 1, Ny, data_in, onembed, 1, Ny, & + & FFTW_FORWARD, FFTW_MEASURE) size_n(1) = Nz inembed(1) = Nz onembed(1) = Nz - fwd_plan_z = fftw_plan_many_dft(1, size_n, Nxloc*Nyloc2, & - data_in, inembed, 1, Nz, & - data_out, onembed, 1, Nz, & - FFTW_FORWARD, FFTW_MEASURE) + fwd_plan_z = fftw_plan_many_dft(1, size_n, Nxloc*Nyloc2, data_in, inembed, 1, Nz, data_out, onembed, 1, Nz, & + & FFTW_FORWARD, FFTW_MEASURE) - call MPI_CART_CREATE(MPI_COMM_WORLD, 3, (/num_procs_x, & - num_procs_y, num_procs_z/), & - (/.true., .true., .true./), & - .false., MPI_COMM_CART, ierr) - call MPI_CART_COORDS(MPI_COMM_CART, proc_rank, 3, & - cart3d_coords, ierr) + call MPI_CART_CREATE(MPI_COMM_WORLD, 3, (/num_procs_x, num_procs_y, num_procs_z/), (/.true., .true., .true./), & + & .false., MPI_COMM_CART, ierr) + call MPI_CART_COORDS(MPI_COMM_CART, proc_rank, 3, cart3d_coords, ierr) call MPI_Cart_SUB(MPI_COMM_CART, (/.true., .true., .false./), MPI_COMM_CART12, ierr) call MPI_COMM_RANK(MPI_COMM_CART12, proc_rank12, ierr) @@ -1070,9 +969,9 @@ contains call MPI_Cart_SUB(MPI_COMM_CART, (/.true., .false., .true./), MPI_COMM_CART13, ierr) call MPI_COMM_RANK(MPI_COMM_CART13, proc_rank13, ierr) call MPI_CART_COORDS(MPI_COMM_CART13, proc_rank13, 2, cart2d13_coords, ierr) - end if #endif + end subroutine s_initialize_modules !> @brief Perform a distributed forward 3-D FFT using pencil decomposition with FFTW and MPI transposes. @@ -1081,7 +980,6 @@ contains integer :: j, k, l #ifdef MFC_MPI - do l = 1, Nzloc do k = 1, Nyloc do j = 1, Nx @@ -1139,7 +1037,6 @@ contains end do end do end do - #endif end subroutine s_mpi_FFT_fwd @@ -1152,10 +1049,9 @@ contains ! Initialization of the MPI environment call s_mpi_initialize() - ! Processor with rank 0 assigns default user input values prior to reading - ! those in from the input file. Next, the user inputs are read in and their - ! consistency is checked. The detection of any inconsistencies automatically - ! leads to the termination of the post-process. + ! Processor with rank 0 assigns default user input values prior to reading those in from the input file. Next, the user + ! inputs are read in and their consistency is checked. The detection of any inconsistencies automatically leads to the + ! termination of the post-process. if (proc_rank == 0) then call s_assign_default_values_to_user_inputs() call s_read_input_file() @@ -1164,9 +1060,8 @@ contains print '(" Post-processing a ", I0, "x", I0, "x", I0, " case on ", I0, " rank(s)")', m, n, p, num_procs end if - ! Broadcasting the user inputs to all of the processors and performing the - ! parallel computational domain decomposition. Neither procedure has to be - ! carried out if the post-process is in fact not truly executed in parallel. + ! Broadcasting the user inputs to all of the processors and performing the parallel computational domain decomposition. + ! Neither procedure has to be carried out if the post-process is in fact not truly executed in parallel. call s_mpi_bcast_user_inputs() call s_initialize_parallel_io() call s_mpi_decompose_computational_domain() @@ -1176,13 +1071,11 @@ contains !> @brief Destroy FFTW plans, free MPI communicators, and finalize all post-process sub-modules. impure subroutine s_finalize_modules + ! Disassociate pointers for serial and parallel I/O s_read_data_files => null() -! if (sim_data .and. proc_rank == 0) then -! call s_close_intf_data_file() -! call s_close_energy_data_file() -! end if + ! if (sim_data .and. proc_rank == 0) then call s_close_intf_data_file() call s_close_energy_data_file() end if if (fft_wrt) then if (c_associated(fwd_plan_x)) call fftw_destroy_plan(fwd_plan_x) @@ -1219,6 +1112,7 @@ contains ! Finalizing the MPI environment call s_mpi_finalize() + end subroutine s_finalize_modules end module m_start_up diff --git a/src/post_process/p_main.fpp b/src/post_process/p_main.fpp index c325b649da..76a5017883 100644 --- a/src/post_process/p_main.fpp +++ b/src/post_process/p_main.fpp @@ -2,31 +2,25 @@ !! @file !! @brief Contains program p_main -!> @brief The post-process restructures raw unformatted data, outputted by -!! the simulation, into a formatted database, Silo-HDF5 or Binary, -!! chosen by the user. The user may also specify which variables to -!! include in the database. The choices range from any one of the -!! primitive and conservative variables, as well as quantities that -!! can be derived from those such as the unadvected volume fraction, -!! specific heat ratio, liquid stiffness, speed of sound, vorticity -!! and the numerical Schlieren function. +!> @brief The post-process restructures raw unformatted data, outputted by the simulation, into a formatted database, Silo-HDF5 or +!! Binary, chosen by the user. The user may also specify which variables to include in the database. The choices range from any one +!! of the primitive and conservative variables, as well as quantities that can be derived from those such as the unadvected volume +!! fraction, specific heat ratio, liquid stiffness, speed of sound, vorticity and the numerical Schlieren function. program p_main - use m_global_parameters !< Global parameters for the code + use m_global_parameters !< Global parameters for the code use m_start_up implicit none - integer :: t_step !< Iterator for the main time-stepping loop + integer :: t_step !< Iterator for the main time-stepping loop - character(LEN=name_len) :: varname !< - !! Generic storage for the name(s) of the flow variable(s) that will be added - !! to the formatted database file(s) - - real(wp) :: pres - real(wp) :: c - real(wp) :: H - real(wp) :: start, finish + !> Generic storage for the name(s) of the flow variable(s) that will be added to the formatted database file(s) + character(LEN=name_len) :: varname + real(wp) :: pres + real(wp) :: c + real(wp) :: H + real(wp) :: start, finish call s_initialize_mpi_domain() @@ -42,12 +36,9 @@ program p_main ! Time-Marching Loop do - - ! If all time-steps are not ready to be post-processed and one rank is - ! faster than another, the slower rank processing the last available - ! step might be killed when the faster rank attempts to process the - ! first missing step, before the slower rank finishes writing the last - ! available step. To avoid this, we force synchronization here. + ! If all time-steps are not ready to be post-processed and one rank is faster than another, the slower rank processing the + ! last available step might be killed when the faster rank attempts to process the first missing step, before the slower + ! rank finishes writing the last available step. To avoid this, we force synchronization here. call s_mpi_barrier() call cpu_time(start) @@ -71,14 +62,12 @@ program p_main exit end if else - ! Modifies the time-step iterator so that it may reach the final time- - ! step to be post-processed, in the case that this one is not originally - ! attainable through constant incrementation from the first time-step. - ! This modification is performed upon reaching the final time-step. In - ! case that it is not needed, the post-processor is done and may exit. + ! Modifies the time-step iterator so that it may reach the final time- step to be post-processed, in the case that this + ! one is not originally attainable through constant incrementation from the first time-step. This modification is + ! performed upon reaching the final time-step. In case that it is not needed, the post-processor is done and may exit. if ((t_step_stop - t_step) < t_step_save .and. t_step_stop /= t_step) then t_step = t_step_stop - t_step_save - elseif (t_step == t_step_stop) then + else if (t_step == t_step_stop) then exit end if end if @@ -89,7 +78,6 @@ program p_main ! Incrementing time-step iterator to next time-step to be post-processed t_step = t_step + t_step_save end if - end do ! END: Time-Marching Loop @@ -100,5 +88,4 @@ program p_main close (11) call s_finalize_modules() - end program p_main diff --git a/src/pre_process/m_assign_variables.fpp b/src/pre_process/m_assign_variables.fpp index bfb6f9d159..5c6786139f 100644 --- a/src/pre_process/m_assign_variables.fpp +++ b/src/pre_process/m_assign_variables.fpp @@ -8,14 +8,10 @@ !> @brief Assigns initial primitive variables to computational cells based on patch geometry module m_assign_variables - use m_derived_types ! Definitions of the derived types - - use m_global_parameters ! Global parameters for the code - + use m_derived_types ! Definitions of the derived types + use m_global_parameters ! Global parameters for the code use m_variables_conversion ! Subroutines to change the state variables from - - use m_helper_basic !< Functions to compare floating point numbers - + use m_helper_basic !< Functions to compare floating point numbers use m_thermochem, only: num_species, gas_constant, get_mixture_molecular_weight implicit none @@ -24,19 +20,15 @@ module m_assign_variables type(scalar_field) :: alf_sum - procedure(s_assign_patch_xxxxx_primitive_variables), & - pointer :: s_assign_patch_primitive_variables => null() !< - !! Depending on the multicomponent flow model, this variable is a pointer to - !! either the subroutine s_assign_patch_mixture_primitive_variables, or the - !! subroutine s_assign_patch_species_primitive_variables + !> Depending on the multicomponent flow model, this variable is a pointer to either the subroutine + !! s_assign_patch_mixture_primitive_variables, or the subroutine s_assign_patch_species_primitive_variables + procedure(s_assign_patch_xxxxx_primitive_variables), pointer :: s_assign_patch_primitive_variables => null() - !> Abstract interface to the two subroutines that assign the patch primitive - !! variables, either mixture or species, depending on the subroutine, to a - !! particular cell in the computational domain + !> Abstract interface to the two subroutines that assign the patch primitive variables, either mixture or species, depending on + !! the subroutine, to a particular cell in the computational domain abstract interface - !> Skeleton of s_assign_patch_mixture_primitive_variables - !! and s_assign_patch_species_primitive_variables + !> Skeleton of s_assign_patch_mixture_primitive_variables and s_assign_patch_species_primitive_variables !! @param patch_id is the patch identifier !! @param j (x) cell index in which the mixture or species primitive variables from the indicated patch are assigned !! @param k (y,th) cell index in which the mixture or species primitive variables from the indicated patch are assigned @@ -44,31 +36,27 @@ module m_assign_variables !! @param eta pseudo volume fraction !! @param q_prim_vf Primitive variables !! @param patch_id_fp Array to track patch ids - subroutine s_assign_patch_xxxxx_primitive_variables(patch_id, j, k, l, & - eta, q_prim_vf, patch_id_fp) + subroutine s_assign_patch_xxxxx_primitive_variables(patch_id, j, k, l, eta, q_prim_vf, patch_id_fp) import :: scalar_field, sys_size, n, m, p, wp - integer, intent(in) :: patch_id - integer, intent(in) :: j, k, l - real(wp), intent(in) :: eta + integer, intent(in) :: patch_id + integer, intent(in) :: j, k, l + real(wp), intent(in) :: eta type(scalar_field), dimension(1:sys_size), intent(inout) :: q_prim_vf + #ifdef MFC_MIXED_PRECISION - integer(kind=1), dimension(0:m, 0:n, 0:p), intent(inout) :: patch_id_fp + integer(kind=1), dimension(0:m,0:n,0:p), intent(inout) :: patch_id_fp #else - integer, dimension(0:m, 0:n, 0:p), intent(inout) :: patch_id_fp + integer, dimension(0:m,0:n,0:p), intent(inout) :: patch_id_fp #endif end subroutine s_assign_patch_xxxxx_primitive_variables - end interface - private; - public :: s_initialize_assign_variables_module, & - s_assign_patch_primitive_variables, & - s_assign_patch_mixture_primitive_variables, & - s_assign_patch_species_primitive_variables, & - s_finalize_assign_variables_module + private + public :: s_initialize_assign_variables_module, s_assign_patch_primitive_variables, & + & s_assign_patch_mixture_primitive_variables, s_assign_patch_species_primitive_variables, s_finalize_assign_variables_module contains @@ -76,58 +64,49 @@ contains impure subroutine s_initialize_assign_variables_module if (.not. igr) then - allocate (alf_sum%sf(0:m, 0:n, 0:p)) + allocate (alf_sum%sf(0:m,0:n,0:p)) end if - ! Depending on multicomponent flow model, the appropriate procedure - ! for assignment of the patch mixture or species primitive variables - ! to a cell in the domain is targeted by the procedure pointer + ! Depending on multicomponent flow model, the appropriate procedure for assignment of the patch mixture or species primitive + ! variables to a cell in the domain is targeted by the procedure pointer - if (model_eqns == 1) then ! Gamma/pi_inf model - s_assign_patch_primitive_variables => & - s_assign_patch_mixture_primitive_variables - else ! Volume fraction model - s_assign_patch_primitive_variables => & - s_assign_patch_species_primitive_variables + if (model_eqns == 1) then ! Gamma/pi_inf model + s_assign_patch_primitive_variables => s_assign_patch_mixture_primitive_variables + else ! Volume fraction model + s_assign_patch_primitive_variables => s_assign_patch_species_primitive_variables end if end subroutine s_initialize_assign_variables_module - !> This subroutine assigns the mixture primitive variables - !! of the patch designated by the patch_id, to the cell that - !! is designated by the indexes (j,k,l). In addition, the - !! variable bookkeeping the patch identities in the entire - !! domain is updated with the new assignment. Note that if - !! the smoothing of the patch's boundaries is employed, the - !! ensuing primitive variables in the cell will be a type of - !! combination of the current patch's primitive variables - !! with those of the smoothing patch. The specific details - !! of the combination may be found in Shyue's work (1998). - !! @param patch_id the patch identifier - !! @param j the x-dir node index - !! @param k the y-dir node index - !! @param l the z-dir node index - !! @param eta pseudo volume fraction - !! @param q_prim_vf Primitive variables - !! @param patch_id_fp Array to track patch ids - subroutine s_assign_patch_mixture_primitive_variables(patch_id, j, k, l, & - eta, q_prim_vf, patch_id_fp) + !> This subroutine assigns the mixture primitive variables of the patch designated by the patch_id, to the cell that is + !! designated by the indexes (j,k,l). In addition, the variable bookkeeping the patch identities in the entire domain is updated + !! with the new assignment. Note that if the smoothing of the patch's boundaries is employed, the ensuing primitive variables in + !! the cell will be a type of combination of the current patch's primitive variables with those of the smoothing patch. The + !! specific details of the combination may be found in Shyue's work (1998). + !! @param patch_id the patch identifier + !! @param j the x-dir node index + !! @param k the y-dir node index + !! @param l the z-dir node index + !! @param eta pseudo volume fraction + !! @param q_prim_vf Primitive variables + !! @param patch_id_fp Array to track patch ids + subroutine s_assign_patch_mixture_primitive_variables(patch_id, j, k, l, eta, q_prim_vf, patch_id_fp) + $:GPU_ROUTINE(parallelism='[seq]') - integer, intent(in) :: patch_id - integer, intent(in) :: j, k, l - real(wp), intent(in) :: eta + integer, intent(in) :: patch_id + integer, intent(in) :: j, k, l + real(wp), intent(in) :: eta type(scalar_field), dimension(1:sys_size), intent(inout) :: q_prim_vf #ifdef MFC_MIXED_PRECISION - integer(kind=1), dimension(0:m, 0:n, 0:p), intent(inout) :: patch_id_fp + integer(kind=1), dimension(0:m,0:n,0:p), intent(inout) :: patch_id_fp #else - integer, dimension(0:m, 0:n, 0:p), intent(inout) :: patch_id_fp + integer, dimension(0:m,0:n,0:p), intent(inout) :: patch_id_fp #endif real(wp) :: Ys(1:num_species) - - integer :: smooth_patch_id - integer :: i !< generic loop operator + integer :: smooth_patch_id + integer :: i !< generic loop operator ! Assigning the mixture primitive variables of a uniform state patch @@ -135,37 +114,25 @@ contains smooth_patch_id = patch_icpp(patch_id)%smooth_patch_id ! Density - q_prim_vf(1)%sf(j, k, l) = & - eta*patch_icpp(patch_id)%rho & - + (1._wp - eta)*patch_icpp(smooth_patch_id)%rho + q_prim_vf(1)%sf(j, k, l) = eta*patch_icpp(patch_id)%rho + (1._wp - eta)*patch_icpp(smooth_patch_id)%rho ! Velocity do i = 1, E_idx - mom_idx%beg - q_prim_vf(i + 1)%sf(j, k, l) = & - 1._wp/q_prim_vf(1)%sf(j, k, l)* & - (eta*patch_icpp(patch_id)%rho & - *patch_icpp(patch_id)%vel(i) & - + (1._wp - eta)*patch_icpp(smooth_patch_id)%rho & - *patch_icpp(smooth_patch_id)%vel(i)) + q_prim_vf(i + 1)%sf(j, k, l) = 1._wp/q_prim_vf(1)%sf(j, k, & + & l)*(eta*patch_icpp(patch_id)%rho*patch_icpp(patch_id)%vel(i) + (1._wp - eta)*patch_icpp(smooth_patch_id) & + & %rho*patch_icpp(smooth_patch_id)%vel(i)) end do ! Specific heat ratio function - q_prim_vf(gamma_idx)%sf(j, k, l) = & - eta*patch_icpp(patch_id)%gamma & - + (1._wp - eta)*patch_icpp(smooth_patch_id)%gamma + q_prim_vf(gamma_idx)%sf(j, k, l) = eta*patch_icpp(patch_id)%gamma + (1._wp - eta)*patch_icpp(smooth_patch_id)%gamma ! Pressure - q_prim_vf(E_idx)%sf(j, k, l) = & - 1._wp/q_prim_vf(gamma_idx)%sf(j, k, l)* & - (eta*patch_icpp(patch_id)%gamma & - *patch_icpp(patch_id)%pres & - + (1._wp - eta)*patch_icpp(smooth_patch_id)%gamma & - *patch_icpp(smooth_patch_id)%pres) + q_prim_vf(E_idx)%sf(j, k, l) = 1._wp/q_prim_vf(gamma_idx)%sf(j, k, & + & l)*(eta*patch_icpp(patch_id)%gamma*patch_icpp(patch_id)%pres + (1._wp - eta)*patch_icpp(smooth_patch_id) & + & %gamma*patch_icpp(smooth_patch_id)%pres) ! Liquid stiffness function - q_prim_vf(pi_inf_idx)%sf(j, k, l) = & - eta*patch_icpp(patch_id)%pi_inf & - + (1._wp - eta)*patch_icpp(smooth_patch_id)%pi_inf + q_prim_vf(pi_inf_idx)%sf(j, k, l) = eta*patch_icpp(patch_id)%pi_inf + (1._wp - eta)*patch_icpp(smooth_patch_id)%pi_inf ! Species Concentrations if (chemistry) then @@ -175,9 +142,7 @@ contains ! Accumulating the species concentrations sum = 0._wp do i = 1, num_species - term = & - eta*patch_icpp(patch_id)%Y(i) & - + (1._wp - eta)*patch_icpp(smooth_patch_id)%Y(i) + term = eta*patch_icpp(patch_id)%Y(i) + (1._wp - eta)*patch_icpp(smooth_patch_id)%Y(i) q_prim_vf(chemxb + i - 1)%sf(j, k, l) = term sum = sum + term end do @@ -186,8 +151,7 @@ contains ! Normalizing the species concentrations do i = 1, num_species - q_prim_vf(chemxb + i - 1)%sf(j, k, l) = & - q_prim_vf(chemxb + i - 1)%sf(j, k, l)/sum + q_prim_vf(chemxb + i - 1)%sf(j, k, l) = q_prim_vf(chemxb + i - 1)%sf(j, k, l)/sum Ys(i) = q_prim_vf(chemxb + i - 1)%sf(j, k, l) end do end block @@ -205,12 +169,11 @@ contains !! @param q_prim_vf Primitive variables subroutine s_perturb_primitive(j, k, l, q_prim_vf) - integer, intent(in) :: j, k, l + integer, intent(in) :: j, k, l type(scalar_field), dimension(1:sys_size), intent(inout) :: q_prim_vf - - integer :: i - real(wp) :: pres_mag, loc, n_tait, B_tait, p0 - real(wp) :: R3bar, n0, ratio, nH, vfH, velH, rhoH, deno + integer :: i + real(wp) :: pres_mag, loc, n_tait, B_tait, p0 + real(wp) :: R3bar, n0, ratio, nH, vfH, velH, rhoH, deno p0 = 101325._wp pres_mag = 1.e-1_wp @@ -224,7 +187,8 @@ contains if (qbmm) then do i = 1, nb - q_prim_vf(bubxb + 1 + (i - 1)*nmom)%sf(j, k, l) = q_prim_vf(bubxb + 1 + (i - 1)*nmom)%sf(j, k, l)*((p0 - bub_pp%pv)/(q_prim_vf(E_idx)%sf(j, k, l)*p0 - bub_pp%pv))**(1._wp/3._wp) + q_prim_vf(bubxb + 1 + (i - 1)*nmom)%sf(j, k, l) = q_prim_vf(bubxb + 1 + (i - 1)*nmom)%sf(j, k, & + & l)*((p0 - bub_pp%pv)/(q_prim_vf(E_idx)%sf(j, k, l)*p0 - bub_pp%pv))**(1._wp/3._wp) end do end if @@ -273,54 +237,48 @@ contains end subroutine s_perturb_primitive - !> This subroutine assigns the species primitive variables. This follows - !! s_assign_patch_species_primitive_variables with adaptation for - !! ensemble-averaged bubble modeling - !! @param patch_id the patch identifier - !! @param j the x-dir node index - !! @param k the y-dir node index - !! @param l the z-dir node index - !! @param eta pseudo volume fraction - !! @param q_prim_vf Primitive variables - !! @param patch_id_fp Array to track patch ids - impure subroutine s_assign_patch_species_primitive_variables(patch_id, j, k, l, & - eta, q_prim_vf, patch_id_fp) + !> This subroutine assigns the species primitive variables. This follows s_assign_patch_species_primitive_variables with + !! adaptation for ensemble-averaged bubble modeling + !! @param patch_id the patch identifier + !! @param j the x-dir node index + !! @param k the y-dir node index + !! @param l the z-dir node index + !! @param eta pseudo volume fraction + !! @param q_prim_vf Primitive variables + !! @param patch_id_fp Array to track patch ids + impure subroutine s_assign_patch_species_primitive_variables(patch_id, j, k, l, eta, q_prim_vf, patch_id_fp) + $:GPU_ROUTINE(parallelism='[seq]') - integer, intent(in) :: patch_id - integer, intent(in) :: j, k, l + integer, intent(in) :: patch_id + integer, intent(in) :: j, k, l real(wp), intent(in) :: eta #ifdef MFC_MIXED_PRECISION - integer(kind=1), dimension(0:m, 0:n, 0:p), intent(inout) :: patch_id_fp + integer(kind=1), dimension(0:m,0:n,0:p), intent(inout) :: patch_id_fp #else - integer, dimension(0:m, 0:n, 0:p), intent(inout) :: patch_id_fp + integer, dimension(0:m,0:n,0:p), intent(inout) :: patch_id_fp #endif type(scalar_field), dimension(1:sys_size), intent(inout) :: q_prim_vf - ! Density, the specific heat ratio function and the liquid stiffness - ! function, respectively, obtained from the combination of primitive - ! variables of the current and smoothing patches - real(wp) :: rho !< density - real(wp) :: gamma - real(wp) :: lit_gamma !< specific heat ratio - real(wp) :: pi_inf !< stiffness from SEOS - real(wp) :: qv !< reference energy from SEOS - real(wp) :: orig_rho - real(wp) :: orig_gamma - real(wp) :: orig_pi_inf - real(wp) :: orig_qv - real(wp) :: muR, muV - real(wp) :: R3bar - real(wp) :: rcoord, theta, phi, xi_sph - real(wp), dimension(3) :: xi_cart - - real(wp) :: Ys(1:num_species) - - real(stp), dimension(sys_size) :: orig_prim_vf !< - !! Vector to hold original values of cell for smoothing purposes - - integer :: i !< Generic loop iterator - integer :: smooth_patch_id + ! Density, the specific heat ratio function and the liquid stiffness function, respectively, obtained from the combination + ! of primitive variables of the current and smoothing patches + real(wp) :: rho !< density + real(wp) :: gamma + real(wp) :: lit_gamma !< specific heat ratio + real(wp) :: pi_inf !< stiffness from SEOS + real(wp) :: qv !< reference energy from SEOS + real(wp) :: orig_rho + real(wp) :: orig_gamma + real(wp) :: orig_pi_inf + real(wp) :: orig_qv + real(wp) :: muR, muV + real(wp) :: R3bar + real(wp) :: rcoord, theta, phi, xi_sph + real(wp), dimension(3) :: xi_cart + real(wp) :: Ys(1:num_species) + real(stp), dimension(sys_size) :: orig_prim_vf !< Vector to hold original values of cell for smoothing purposes + integer :: i !< Generic loop iterator + integer :: smooth_patch_id ! Transferring the identity of the smoothing patch smooth_patch_id = patch_icpp(patch_id)%smooth_patch_id @@ -331,25 +289,19 @@ contains end do if (mpp_lim .and. bubbles_euler) then - !adjust volume fractions, according to modeled gas void fraction + ! adjust volume fractions, according to modeled gas void fraction alf_sum%sf = 0._wp do i = adv_idx%beg, adv_idx%end - 1 alf_sum%sf = alf_sum%sf + q_prim_vf(i)%sf end do do i = adv_idx%beg, adv_idx%end - 1 - q_prim_vf(i)%sf = q_prim_vf(i)%sf*(1._wp - q_prim_vf(alf_idx)%sf) & - /alf_sum%sf + q_prim_vf(i)%sf = q_prim_vf(i)%sf*(1._wp - q_prim_vf(alf_idx)%sf)/alf_sum%sf end do end if - ! Computing Mixture Variables from Original Primitive Variables - ! call s_convert_species_to_mixture_variables( & - call s_convert_to_mixture_variables( & - q_prim_vf, j, k, l, & - orig_rho, & - orig_gamma, & - orig_pi_inf, orig_qv) + ! Computing Mixture Variables from Original Primitive Variables call s_convert_species_to_mixture_variables( & + call s_convert_to_mixture_variables(q_prim_vf, j, k, l, orig_rho, orig_gamma, orig_pi_inf, orig_qv) ! Computing Mixture Variables of Current Patch @@ -361,15 +313,14 @@ contains end if if (mpp_lim .and. bubbles_euler) then - !adjust volume fractions, according to modeled gas void fraction + ! adjust volume fractions, according to modeled gas void fraction alf_sum%sf = 0._wp do i = adv_idx%beg, adv_idx%end - 1 alf_sum%sf = alf_sum%sf + q_prim_vf(i)%sf end do do i = adv_idx%beg, adv_idx%end - 1 - q_prim_vf(i)%sf = q_prim_vf(i)%sf*(1._wp - q_prim_vf(alf_idx)%sf) & - /alf_sum%sf + q_prim_vf(i)%sf = q_prim_vf(i)%sf*(1._wp - q_prim_vf(alf_idx)%sf)/alf_sum%sf end do end if @@ -380,14 +331,9 @@ contains end do end if - ! Density and the specific heat ratio and liquid stiffness functions - ! call s_convert_species_to_mixture_variables( & - call s_convert_to_mixture_variables( & - q_prim_vf, j, k, l, & - patch_icpp(patch_id)%rho, & - patch_icpp(patch_id)%gamma, & - patch_icpp(patch_id)%pi_inf, & - patch_icpp(patch_id)%qv) + ! Density and the specific heat ratio and liquid stiffness functions call s_convert_species_to_mixture_variables( & + call s_convert_to_mixture_variables(q_prim_vf, j, k, l, patch_icpp(patch_id)%rho, patch_icpp(patch_id)%gamma, & + & patch_icpp(patch_id)%pi_inf, patch_icpp(patch_id)%qv) ! Computing Mixture Variables of Smoothing Patch @@ -406,15 +352,14 @@ contains end if if (mpp_lim .and. bubbles_euler) then - !adjust volume fractions, according to modeled gas void fraction + ! adjust volume fractions, according to modeled gas void fraction alf_sum%sf = 0._wp do i = adv_idx%beg, adv_idx%end - 1 alf_sum%sf = alf_sum%sf + q_prim_vf(i)%sf end do do i = adv_idx%beg, adv_idx%end - 1 - q_prim_vf(i)%sf = q_prim_vf(i)%sf*(1._wp - q_prim_vf(alf_idx)%sf) & - /alf_sum%sf + q_prim_vf(i)%sf = q_prim_vf(i)%sf*(1._wp - q_prim_vf(alf_idx)%sf)/alf_sum%sf end do end if @@ -460,67 +405,47 @@ contains end if end if - ! Density and the specific heat ratio and liquid stiffness functions - ! call s_convert_species_to_mixture_variables( & - call s_convert_to_mixture_variables( & - q_prim_vf, j, k, l, & - patch_icpp(smooth_patch_id)%rho, & - patch_icpp(smooth_patch_id)%gamma, & - patch_icpp(smooth_patch_id)%pi_inf, & - patch_icpp(smooth_patch_id)%qv) + ! Density and the specific heat ratio and liquid stiffness functions call s_convert_species_to_mixture_variables( & + call s_convert_to_mixture_variables(q_prim_vf, j, k, l, patch_icpp(smooth_patch_id)%rho, & + & patch_icpp(smooth_patch_id)%gamma, patch_icpp(smooth_patch_id)%pi_inf, & + & patch_icpp(smooth_patch_id)%qv) ! Pressure - q_prim_vf(E_idx)%sf(j, k, l) = & - (eta*patch_icpp(patch_id)%pres & - + (1._wp - eta)*orig_prim_vf(E_idx)) + q_prim_vf(E_idx)%sf(j, k, l) = (eta*patch_icpp(patch_id)%pres + (1._wp - eta)*orig_prim_vf(E_idx)) if (.not. igr .or. num_fluids > 1) then ! Volume fractions \alpha do i = adv_idx%beg, adv_idx%end - q_prim_vf(i)%sf(j, k, l) = & - eta*patch_icpp(patch_id)%alpha(i - E_idx) & - + (1._wp - eta)*orig_prim_vf(i) + q_prim_vf(i)%sf(j, k, l) = eta*patch_icpp(patch_id)%alpha(i - E_idx) + (1._wp - eta)*orig_prim_vf(i) end do end if if (mhd) then - if (n == 0) then ! 1D: By, Bz - q_prim_vf(B_idx%beg)%sf(j, k, l) = & - eta*patch_icpp(patch_id)%By & - + (1._wp - eta)*orig_prim_vf(B_idx%beg) - q_prim_vf(B_idx%beg + 1)%sf(j, k, l) = & - eta*patch_icpp(patch_id)%Bz & - + (1._wp - eta)*orig_prim_vf(B_idx%beg + 1) - else ! 2D/3D: Bx, By, Bz - q_prim_vf(B_idx%beg)%sf(j, k, l) = & - eta*patch_icpp(patch_id)%Bx & - + (1._wp - eta)*orig_prim_vf(B_idx%beg) - q_prim_vf(B_idx%beg + 1)%sf(j, k, l) = & - eta*patch_icpp(patch_id)%By & - + (1._wp - eta)*orig_prim_vf(B_idx%beg + 1) - q_prim_vf(B_idx%beg + 2)%sf(j, k, l) = & - eta*patch_icpp(patch_id)%Bz & - + (1._wp - eta)*orig_prim_vf(B_idx%beg + 2) + if (n == 0) then ! 1D: By, Bz + q_prim_vf(B_idx%beg)%sf(j, k, l) = eta*patch_icpp(patch_id)%By + (1._wp - eta)*orig_prim_vf(B_idx%beg) + q_prim_vf(B_idx%beg + 1)%sf(j, k, l) = eta*patch_icpp(patch_id)%Bz + (1._wp - eta)*orig_prim_vf(B_idx%beg + 1) + else ! 2D/3D: Bx, By, Bz + q_prim_vf(B_idx%beg)%sf(j, k, l) = eta*patch_icpp(patch_id)%Bx + (1._wp - eta)*orig_prim_vf(B_idx%beg) + q_prim_vf(B_idx%beg + 1)%sf(j, k, l) = eta*patch_icpp(patch_id)%By + (1._wp - eta)*orig_prim_vf(B_idx%beg + 1) + q_prim_vf(B_idx%beg + 2)%sf(j, k, l) = eta*patch_icpp(patch_id)%Bz + (1._wp - eta)*orig_prim_vf(B_idx%beg + 2) end if end if ! Elastic Shear Stress if (elasticity) then do i = 1, (stress_idx%end - stress_idx%beg) + 1 - q_prim_vf(i + stress_idx%beg - 1)%sf(j, k, l) = & - (eta*patch_icpp(patch_id)%tau_e(i) & - + (1._wp - eta)*orig_prim_vf(i + stress_idx%beg - 1)) + q_prim_vf(i + stress_idx%beg - 1)%sf(j, k, & + & l) = (eta*patch_icpp(patch_id)%tau_e(i) + (1._wp - eta)*orig_prim_vf(i + stress_idx%beg - 1)) end do end if ! Elastic Shear Stress if (hyperelasticity) then - - if (pre_stress) then ! pre stressed initial condition in spatial domain + if (pre_stress) then ! pre stressed initial condition in spatial domain rcoord = sqrt((x_cc(j)**2 + y_cc(k)**2 + z_cc(l)**2)) theta = atan2(y_cc(k), x_cc(j)) phi = atan2(sqrt(x_cc(j)**2 + y_cc(k)**2), z_cc(l)) - !spherical coord, assuming Rmax=1 + ! spherical coord, assuming Rmax=1 xi_sph = (rcoord**3 - R0ref**3 + 1._wp)**(1._wp/3._wp) xi_cart(1) = xi_sph*sin(phi)*cos(theta) xi_cart(2) = xi_sph*sin(phi)*sin(theta) @@ -533,54 +458,47 @@ contains ! assigning the reference map to the q_prim vector field do i = 1, num_dims - q_prim_vf(i + xibeg - 1)%sf(j, k, l) = eta*xi_cart(i) + & - (1._wp - eta)*orig_prim_vf(i + xibeg - 1) + q_prim_vf(i + xibeg - 1)%sf(j, k, l) = eta*xi_cart(i) + (1._wp - eta)*orig_prim_vf(i + xibeg - 1) end do end if if (mpp_lim .and. bubbles_euler) then - !adjust volume fractions, according to modeled gas void fraction + ! adjust volume fractions, according to modeled gas void fraction alf_sum%sf = 0._wp do i = adv_idx%beg, adv_idx%end - 1 alf_sum%sf = alf_sum%sf + q_prim_vf(i)%sf end do do i = adv_idx%beg, adv_idx%end - 1 - q_prim_vf(i)%sf = q_prim_vf(i)%sf*(1._wp - q_prim_vf(alf_idx)%sf) & - /alf_sum%sf + q_prim_vf(i)%sf = q_prim_vf(i)%sf*(1._wp - q_prim_vf(alf_idx)%sf)/alf_sum%sf end do end if ! Partial densities \alpha \rho if (model_eqns /= 4) then - !mixture density is an input + ! mixture density is an input do i = 1, cont_idx%end - q_prim_vf(i)%sf(j, k, l) = & - eta*patch_icpp(patch_id)%alpha_rho(i) & - + (1._wp - eta)*orig_prim_vf(i) + q_prim_vf(i)%sf(j, k, l) = eta*patch_icpp(patch_id)%alpha_rho(i) + (1._wp - eta)*orig_prim_vf(i) end do else - !get mixture density from pressure via Tait EOS + ! get mixture density from pressure via Tait EOS pi_inf = pi_infs(1) gamma = gammas(1) lit_gamma = gs_min(1) ! \rho = (( p_l + pi_inf)/( p_ref + pi_inf))**(1/little_gam) * rhoref(1-alf) - q_prim_vf(1)%sf(j, k, l) = & - (((q_prim_vf(E_idx)%sf(j, k, l) + pi_inf)/(pref + pi_inf))**(1/lit_gamma))* & - rhoref*(1 - q_prim_vf(alf_idx)%sf(j, k, l)) + q_prim_vf(1)%sf(j, k, l) = (((q_prim_vf(E_idx)%sf(j, k, & + & l) + pi_inf)/(pref + pi_inf))**(1/lit_gamma))*rhoref*(1 - q_prim_vf(alf_idx)%sf(j, k, l)) end if - ! Density and the specific heat ratio and liquid stiffness functions - ! call s_convert_species_to_mixture_variables(q_prim_vf, j, k, l, & - call s_convert_to_mixture_variables(q_prim_vf, j, k, l, & - rho, gamma, pi_inf, qv) + ! Density and the specific heat ratio and liquid stiffness functions call s_convert_species_to_mixture_variables(q_prim_vf, + ! j, k, l, & + call s_convert_to_mixture_variables(q_prim_vf, j, k, l, rho, gamma, pi_inf, qv) ! Velocity do i = 1, E_idx - mom_idx%beg - q_prim_vf(i + cont_idx%end)%sf(j, k, l) = & - (eta*patch_icpp(patch_id)%vel(i) & - + (1._wp - eta)*orig_prim_vf(i + cont_idx%end)) + q_prim_vf(i + cont_idx%end)%sf(j, k, & + & l) = (eta*patch_icpp(patch_id)%vel(i) + (1._wp - eta)*orig_prim_vf(i + cont_idx%end)) end do ! Species Concentrations @@ -591,9 +509,7 @@ contains ! Accumulating the species concentrations sum = 0._wp do i = 1, num_species - term = & - eta*patch_icpp(patch_id)%Y(i) & - + (1._wp - eta)*patch_icpp(smooth_patch_id)%Y(i) + term = eta*patch_icpp(patch_id)%Y(i) + (1._wp - eta)*patch_icpp(smooth_patch_id)%Y(i) q_prim_vf(chemxb + i - 1)%sf(j, k, l) = term sum = sum + term end do @@ -604,8 +520,7 @@ contains ! Normalizing the species concentrations do i = 1, num_species - q_prim_vf(chemxb + i - 1)%sf(j, k, l) = & - q_prim_vf(chemxb + i - 1)%sf(j, k, l)/sum + q_prim_vf(chemxb + i - 1)%sf(j, k, l) = q_prim_vf(chemxb + i - 1)%sf(j, k, l)/sum Ys(i) = q_prim_vf(chemxb + i - 1)%sf(j, k, l) end do end block @@ -613,9 +528,9 @@ contains ! Set streamwise velocity to hyperbolic tangent function of y if (mixlayer_vel_profile) then - q_prim_vf(1 + cont_idx%end)%sf(j, k, l) = & - (eta*patch_icpp(patch_id)%vel(1)*tanh(y_cc(k)*mixlayer_vel_coef) & - + (1._wp - eta)*orig_prim_vf(1 + cont_idx%end)) + q_prim_vf(1 + cont_idx%end)%sf(j, k, & + & l) = (eta*patch_icpp(patch_id)%vel(1)*tanh(y_cc(k)*mixlayer_vel_coef) + (1._wp - eta)*orig_prim_vf(1 & + & + cont_idx%end)) end if ! Set partial pressures to mixture pressure for the 6-eqn model @@ -655,7 +570,6 @@ contains q_prim_vf(bub_idx%ps(i))%sf(j, k, l) = patch_icpp(patch_id)%p0 q_prim_vf(bub_idx%ms(i))%sf(j, k, l) = patch_icpp(patch_id)%m0 end if - end if end do @@ -670,15 +584,14 @@ contains end if if (mpp_lim .and. bubbles_euler) then - !adjust volume fractions, according to modeled gas void fraction + ! adjust volume fractions, according to modeled gas void fraction alf_sum%sf = 0._wp do i = adv_idx%beg, adv_idx%end - 1 alf_sum%sf = alf_sum%sf + q_prim_vf(i)%sf end do do i = adv_idx%beg, adv_idx%end - 1 - q_prim_vf(i)%sf = q_prim_vf(i)%sf*(1._wp - q_prim_vf(alf_idx)%sf) & - /alf_sum%sf + q_prim_vf(i)%sf = q_prim_vf(i)%sf*(1._wp - q_prim_vf(alf_idx)%sf)/alf_sum%sf end do end if @@ -695,30 +608,23 @@ contains end if if (surface_tension) then - q_prim_vf(c_idx)%sf(j, k, l) = eta*patch_icpp(patch_id)%cf_val + & - (1._wp - eta)*orig_prim_vf(c_idx) + q_prim_vf(c_idx)%sf(j, k, l) = eta*patch_icpp(patch_id)%cf_val + (1._wp - eta)*orig_prim_vf(c_idx) end if ! Updating the patch identities bookkeeping variable if (1._wp - eta < 1.e-16_wp) patch_id_fp(j, k, l) = patch_id - ! if (j == 1) then - ! print *, (q_prim_vf(bub_idx%rs(i))%sf(j, k, l), i = 1, nb) - ! print *, (q_prim_vf(bub_idx%fullmom(i, 1, 0))%sf(j, k, l), i = 1, nb) - ! print *, (R0(i), i = 1, nb) - ! print *, patch_icpp(patch_id)%r0 - ! print *, (bub_idx%rs(i), i = 1, nb) - ! print *, (bub_idx%fullmom(i, 1, 0), i = 1, nb) - ! end if + ! if (j == 1) then print *, (q_prim_vf(bub_idx%rs(i))%sf(j, k, l), i = 1, nb) print *, (q_prim_vf(bub_idx%fullmom(i, 1, + ! 0))%sf(j, k, l), i = 1, nb) print *, (R0(i), i = 1, nb) print *, patch_icpp(patch_id)%r0 print *, (bub_idx%rs(i), i = 1, + ! nb) print *, (bub_idx%fullmom(i, 1, 0), i = 1, nb) end if end subroutine s_assign_patch_species_primitive_variables !> @brief Nullifies the patch primitive variable assignment procedure pointer. impure subroutine s_finalize_assign_variables_module - ! Nullifying procedure pointer to the subroutine assigning either - ! the patch mixture or species primitive variables to a cell in the - ! computational domain + ! Nullifying procedure pointer to the subroutine assigning either the patch mixture or species primitive variables to a cell + ! in the computational domain s_assign_patch_primitive_variables => null() end subroutine s_finalize_assign_variables_module diff --git a/src/pre_process/m_boundary_conditions.fpp b/src/pre_process/m_boundary_conditions.fpp index 46cbbda47c..1c5eef99f3 100644 --- a/src/pre_process/m_boundary_conditions.fpp +++ b/src/pre_process/m_boundary_conditions.fpp @@ -6,23 +6,20 @@ module m_boundary_conditions use m_derived_types - use m_global_parameters #ifdef MFC_MPI use mpi #endif use m_delay_file_access - use m_compile_specific - use m_boundary_common implicit none - real(wp) :: x_centroid, y_centroid, z_centroid - real(wp) :: length_x, length_y, length_z - real(wp) :: radius - type(bounds_info) :: x_boundary, y_boundary, z_boundary !< + real(wp) :: x_centroid, y_centroid, z_centroid + real(wp) :: length_x, length_y, length_z + real(wp) :: radius + type(bounds_info) :: x_boundary, y_boundary, z_boundary private; public :: s_apply_boundary_patches @@ -30,12 +27,12 @@ contains !> @brief Applies a line-segment boundary condition patch along a domain edge in 2D. impure subroutine s_line_segment_bc(patch_id, bc_type) - type(integer_field), dimension(1:num_dims, 1:2), intent(inout) :: bc_type - integer, intent(in) :: patch_id - - integer :: j + type(integer_field), dimension(1:num_dims,1:2), intent(inout) :: bc_type + integer, intent(in) :: patch_id + integer :: j ! Patch is a vertical line at x_beg or x_end + if (patch_bc(patch_id)%dir == 1) then y_centroid = patch_bc(patch_id)%centroid(2) length_y = patch_bc(patch_id)%length(2) @@ -80,11 +77,10 @@ contains !> @brief Applies a circular boundary condition patch on a domain face in 3D. impure subroutine s_circle_bc(patch_id, bc_type) - type(integer_field), dimension(1:num_dims, 1:2), intent(inout) :: bc_type - - integer, intent(in) :: patch_id + type(integer_field), dimension(1:num_dims,1:2), intent(inout) :: bc_type + integer, intent(in) :: patch_id + integer :: j, k - integer :: j, k if (patch_bc(patch_id)%dir == 1) then y_centroid = patch_bc(patch_id)%centroid(2) z_centroid = patch_bc(patch_id)%centroid(3) @@ -94,8 +90,7 @@ contains if (patch_bc(patch_id)%loc == ${LOC}$ .and. bc_x%${BOUND}$ < 0) then do k = 0, p do j = 0, n - if ((z_cc(k) - z_centroid)**2._wp + & - (y_cc(j) - y_centroid)**2._wp <= radius**2._wp) then + if ((z_cc(k) - z_centroid)**2._wp + (y_cc(j) - y_centroid)**2._wp <= radius**2._wp) then bc_type(1, ${IDX}$)%sf(0, j, k) = patch_bc(patch_id)%type end if end do @@ -112,8 +107,7 @@ contains if (patch_bc(patch_id)%loc == ${LOC}$ .and. bc_y%${BOUND}$ < 0) then do k = 0, p do j = 0, m - if ((z_cc(k) - z_centroid)**2._wp + & - (x_cc(j) - x_centroid)**2._wp <= radius**2._wp) then + if ((z_cc(k) - z_centroid)**2._wp + (x_cc(j) - x_centroid)**2._wp <= radius**2._wp) then bc_type(2, ${IDX}$)%sf(j, 0, k) = patch_bc(patch_id)%type end if end do @@ -129,8 +123,7 @@ contains if (patch_bc(patch_id)%loc == ${LOC}$ .and. bc_z%${BOUND}$ < 0) then do k = 0, n do j = 0, m - if ((y_cc(k) - y_centroid)**2._wp + & - (x_cc(j) - x_centroid)**2._wp <= radius**2._wp) then + if ((y_cc(k) - y_centroid)**2._wp + (x_cc(j) - x_centroid)**2._wp <= radius**2._wp) then bc_type(3, ${IDX}$)%sf(j, k, 0) = patch_bc(patch_id)%type end if end do @@ -144,10 +137,10 @@ contains !> @brief Applies a rectangular boundary condition patch on a domain face in 3D. impure subroutine s_rectangle_bc(patch_id, bc_type) - type(integer_field), dimension(1:num_dims, 1:2), intent(inout) :: bc_type + type(integer_field), dimension(1:num_dims,1:2), intent(inout) :: bc_type + integer, intent(in) :: patch_id + integer :: j, k - integer, intent(in) :: patch_id - integer :: j, k if (patch_bc(patch_id)%dir == 1) then y_centroid = patch_bc(patch_id)%centroid(2) z_centroid = patch_bc(patch_id)%centroid(3) @@ -164,10 +157,8 @@ contains if (patch_bc(patch_id)%loc == ${LOC}$ .and. bc_x%${BOUND}$ < 0) then do k = 0, p do j = 0, n - if (y_boundary%beg <= y_cc(j) .and. & - y_boundary%end >= y_cc(j) .and. & - z_boundary%beg <= z_cc(k) .and. & - z_boundary%end >= z_cc(k)) then + if (y_boundary%beg <= y_cc(j) .and. y_boundary%end >= y_cc(j) .and. z_boundary%beg <= z_cc(k) & + & .and. z_boundary%end >= z_cc(k)) then bc_type(1, ${IDX}$)%sf(0, j, k) = patch_bc(patch_id)%type end if end do @@ -191,10 +182,8 @@ contains if (patch_bc(patch_id)%loc == ${LOC}$ .and. bc_y%${BOUND}$ < 0) then do k = 0, p do j = 0, m - if (x_boundary%beg <= x_cc(j) .and. & - x_boundary%end >= x_cc(j) .and. & - z_boundary%beg <= z_cc(k) .and. & - z_boundary%end >= z_cc(k)) then + if (x_boundary%beg <= x_cc(j) .and. x_boundary%end >= x_cc(j) .and. z_boundary%beg <= z_cc(k) & + & .and. z_boundary%end >= z_cc(k)) then bc_type(2, ${IDX}$)%sf(j, 0, k) = patch_bc(patch_id)%type end if end do @@ -217,10 +206,8 @@ contains if (patch_bc(patch_id)%loc == ${LOC}$ .and. bc_z%${BOUND}$ < 0) then do k = 0, n do j = 0, m - if (x_boundary%beg <= x_cc(j) .and. & - x_boundary%end >= x_cc(j) .and. & - y_boundary%beg <= y_cc(k) .and. & - y_boundary%end >= y_cc(k)) then + if (x_boundary%beg <= x_cc(j) .and. x_boundary%end >= x_cc(j) .and. y_boundary%beg <= y_cc(k) & + & .and. y_boundary%end >= y_cc(k)) then bc_type(3, ${IDX}$)%sf(j, k, 0) = patch_bc(patch_id)%type end if end do @@ -234,11 +221,12 @@ contains !> @brief Iterates over all boundary condition patches and dispatches them by geometry type. impure subroutine s_apply_boundary_patches(q_prim_vf, bc_type) - type(scalar_field), dimension(sys_size) :: q_prim_vf - type(integer_field), dimension(1:num_dims, 1:2) :: bc_type - integer :: i + type(scalar_field), dimension(sys_size) :: q_prim_vf + type(integer_field), dimension(1:num_dims,1:2) :: bc_type + integer :: i + + !> Apply 2D patches to 3D domain - !< Apply 2D patches to 3D domain if (p > 0) then do i = 1, num_bc_patches if (proc_rank == 0) then @@ -247,12 +235,12 @@ contains if (patch_bc(i)%geometry == 2) then call s_circle_bc(i, bc_type) - elseif (patch_bc(i)%geometry == 3) then + else if (patch_bc(i)%geometry == 3) then call s_rectangle_bc(i, bc_type) end if end do - !< Apply 1D patches to 2D domain - elseif (n > 0) then + !> Apply 1D patches to 2D domain + else if (n > 0) then do i = 1, num_bc_patches if (proc_rank == 0) then print *, 'Processing boundary condition patch', i diff --git a/src/pre_process/m_check_ib_patches.fpp b/src/pre_process/m_check_ib_patches.fpp index ea481d2e91..5c96c56722 100644 --- a/src/pre_process/m_check_ib_patches.fpp +++ b/src/pre_process/m_check_ib_patches.fpp @@ -8,28 +8,22 @@ module m_check_ib_patches - use m_derived_types !< Definitions of the derived types - - use m_global_parameters !< Global parameters - - use m_mpi_proxy !< Message passing interface (MPI) module proxy - - use m_data_output !< Procedures to write the grid data and the - !! conservative variables to files + use m_derived_types !< Definitions of the derived types + use m_global_parameters !< Global parameters + use m_mpi_proxy !< Message passing interface (MPI) module proxy + use m_data_output !< Procedures to write the grid data and the conservative variables to files #ifdef MFC_MPI - use mpi !< Message passing interface (MPI) module + use mpi !< Message passing interface (MPI) module #endif use m_compile_specific - - use m_helper_basic !< Functions to compare floating point numbers - + use m_helper_basic !< Functions to compare floating point numbers use m_helper implicit none - private; + private public :: s_check_ib_patches character(len=10) :: iStr @@ -45,8 +39,7 @@ contains if (i <= num_ibs) then ! call s_check_patch_geometry(i) call s_int_to_str(i, iStr) - @:PROHIBIT(patch_ib(i)%geometry == dflt_int, "IB patch undefined. & - patch_ib("//trim(iStr)//")%geometry must be set.") + @:PROHIBIT(patch_ib(i)%geometry == dflt_int, "IB patch undefined. patch_ib("//trim(iStr)//")%geometry must be set.") ! Constraints on the geometric initial condition patch parameters if (patch_ib(i)%geometry == 2) then @@ -63,265 +56,174 @@ contains call s_check_3d_airfoil_ib_patch_geometry(i) else if (patch_ib(i)%geometry == 10) then call s_check_cylinder_ib_patch_geometry(i) - else if (patch_ib(i)%geometry == 5 .or. & - patch_ib(i)%geometry == 12) then + else if (patch_ib(i)%geometry == 5 .or. patch_ib(i)%geometry == 12) then call s_check_model_ib_patch_geometry(i) else if (patch_ib(i)%geometry == 6) then call s_check_ellipse_ib_patch_geometry(i) else call s_prohibit_abort("Invalid IB patch", & - "patch_ib("//trim(iStr)//")%geometry must be "// & - "2-4, 8-10, 11 or 12.") + & "patch_ib(" // trim(iStr) // ")%geometry must be " // "2-4, 8-10, 11 or 12.") end if else - @:PROHIBIT(patch_ib(i)%geometry /= dflt_int, "Inactive IB patch defined. "// & - "patch_ib("//trim(iStr)//")%geometry must not be set for inactive patches.") + @:PROHIBIT(patch_ib(i)%geometry /= dflt_int, & + & "Inactive IB patch defined. "// "patch_ib("//trim(iStr) & + & //")%geometry must not be set for inactive patches.") call s_check_inactive_ib_patch_geometry(i) end if end do end subroutine s_check_ib_patches - !> This subroutine verifies that the geometric parameters of - !! the circle patch have consistently been inputted by the - !! user. - !! @param patch_id Patch identifier + !> This subroutine verifies that the geometric parameters of the circle patch have consistently been inputted by the user. + !! @param patch_id Patch identifier impure subroutine s_check_circle_ib_patch_geometry(patch_id) integer, intent(in) :: patch_id call s_int_to_str(patch_id, iStr) - @:PROHIBIT(n == 0 .or. p > 0 & - .or. patch_ib(patch_id)%radius <= 0._wp & - .or. f_is_default(patch_ib(patch_id)%x_centroid) & - .or. f_is_default(patch_ib(patch_id)%y_centroid), & - 'in circle IB patch '//trim(iStr)) + @:PROHIBIT(n == 0 .or. p > 0 .or. patch_ib(patch_id)%radius <= 0._wp .or. f_is_default(patch_ib(patch_id)%x_centroid) & + & .or. f_is_default(patch_ib(patch_id)%y_centroid), 'in circle IB patch '//trim(iStr)) end subroutine s_check_circle_ib_patch_geometry - !> This subroutine verifies that the geometric parameters of - !! the ellipse patch have consistently been inputted by the - !! user. - !! @param patch_id Patch identifier + !> This subroutine verifies that the geometric parameters of the ellipse patch have consistently been inputted by the user. + !! @param patch_id Patch identifier impure subroutine s_check_ellipse_ib_patch_geometry(patch_id) integer, intent(in) :: patch_id call s_int_to_str(patch_id, iStr) - @:PROHIBIT(n == 0 .or. p > 0 & - .or. patch_ib(patch_id)%length_x <= 0._wp & - .or. patch_ib(patch_id)%length_y <= 0._wp & - .or. f_is_default(patch_ib(patch_id)%x_centroid) & - .or. f_is_default(patch_ib(patch_id)%y_centroid), & - 'in ellipse IB patch '//trim(iStr)) + @:PROHIBIT(n == 0 .or. p > 0 .or. patch_ib(patch_id)%length_x <= 0._wp .or. patch_ib(patch_id) & + & %length_y <= 0._wp .or. f_is_default(patch_ib(patch_id)%x_centroid) .or. f_is_default(patch_ib(patch_id) & + & %y_centroid), 'in ellipse IB patch '//trim(iStr)) end subroutine s_check_ellipse_ib_patch_geometry - !> This subroutine verifies that the geometric parameters of - !! the airfoil patch have consistently been inputted by the - !! user. - !! @param patch_id Patch identifier + !> This subroutine verifies that the geometric parameters of the airfoil patch have consistently been inputted by the user. + !! @param patch_id Patch identifier impure subroutine s_check_airfoil_ib_patch_geometry(patch_id) integer, intent(in) :: patch_id call s_int_to_str(patch_id, iStr) - @:PROHIBIT(n == 0 .or. p > 0 & - .or. patch_ib(patch_id)%c <= 0._wp & - .or. patch_ib(patch_id)%p <= 0._wp & - .or. patch_ib(patch_id)%t <= 0._wp & - .or. patch_ib(patch_id)%m <= 0._wp & - .or. f_is_default(patch_ib(patch_id)%x_centroid) & - .or. f_is_default(patch_ib(patch_id)%y_centroid), & - 'in airfoil IB patch '//trim(iStr)) + @:PROHIBIT(n == 0 .or. p > 0 .or. patch_ib(patch_id)%c <= 0._wp .or. patch_ib(patch_id)%p <= 0._wp .or. patch_ib(patch_id) & + & %t <= 0._wp .or. patch_ib(patch_id)%m <= 0._wp .or. f_is_default(patch_ib(patch_id)%x_centroid) & + & .or. f_is_default(patch_ib(patch_id)%y_centroid), 'in airfoil IB patch '//trim(iStr)) end subroutine s_check_airfoil_ib_patch_geometry - !> This subroutine verifies that the geometric parameters of - !! the 3d airfoil patch have consistently been inputted by the - !! user. - !! @param patch_id Patch identifier + !> This subroutine verifies that the geometric parameters of the 3d airfoil patch have consistently been inputted by the user. + !! @param patch_id Patch identifier impure subroutine s_check_3d_airfoil_ib_patch_geometry(patch_id) integer, intent(in) :: patch_id call s_int_to_str(patch_id, iStr) - @:PROHIBIT(n == 0 .or. p == 0 & - .or. patch_ib(patch_id)%c <= 0._wp & - .or. patch_ib(patch_id)%p <= 0._wp & - .or. patch_ib(patch_id)%t <= 0._wp & - .or. patch_ib(patch_id)%m <= 0._wp & - .or. f_is_default(patch_ib(patch_id)%x_centroid) & - .or. f_is_default(patch_ib(patch_id)%y_centroid) & - .or. f_is_default(patch_ib(patch_id)%z_centroid) & - .or. f_is_default(patch_ib(patch_id)%length_z), & - 'in 3d airfoil IB patch '//trim(iStr)) + @:PROHIBIT(n == 0 .or. p == 0 .or. patch_ib(patch_id)%c <= 0._wp .or. patch_ib(patch_id) & + & %p <= 0._wp .or. patch_ib(patch_id)%t <= 0._wp .or. patch_ib(patch_id) & + & %m <= 0._wp .or. f_is_default(patch_ib(patch_id)%x_centroid) .or. f_is_default(patch_ib(patch_id)%y_centroid) & + & .or. f_is_default(patch_ib(patch_id)%z_centroid) .or. f_is_default(patch_ib(patch_id)%length_z), & + & 'in 3d airfoil IB patch '//trim(iStr)) end subroutine s_check_3d_airfoil_ib_patch_geometry - !> This subroutine verifies that the geometric parameters of - !! the rectangle patch have consistently been inputted by - !! the user. - !! @param patch_id Patch identifier + !> This subroutine verifies that the geometric parameters of the rectangle patch have consistently been inputted by the user. + !! @param patch_id Patch identifier impure subroutine s_check_rectangle_ib_patch_geometry(patch_id) integer, intent(in) :: patch_id call s_int_to_str(patch_id, iStr) - @:PROHIBIT(n == 0 .or. p > 0 & - .or. & - f_is_default(patch_ib(patch_id)%x_centroid) & - .or. & - f_is_default(patch_ib(patch_id)%y_centroid) & - .or. & - patch_ib(patch_id)%length_x <= 0._wp & - .or. & - patch_ib(patch_id)%length_y <= 0._wp, & - 'in rectangle IB patch '//trim(iStr)) + @:PROHIBIT(n == 0 .or. p > 0 .or. f_is_default(patch_ib(patch_id)%x_centroid) .or. f_is_default(patch_ib(patch_id) & + & %y_centroid) .or. patch_ib(patch_id)%length_x <= 0._wp .or. patch_ib(patch_id)%length_y <= 0._wp, & + & 'in rectangle IB patch '//trim(iStr)) end subroutine s_check_rectangle_ib_patch_geometry - !> This subroutine verifies that the geometric parameters of - !! the sphere patch have consistently been inputted by - !! the user. - !! @param patch_id Patch identifier + !> This subroutine verifies that the geometric parameters of the sphere patch have consistently been inputted by the user. + !! @param patch_id Patch identifier impure subroutine s_check_sphere_ib_patch_geometry(patch_id) integer, intent(in) :: patch_id call s_int_to_str(patch_id, iStr) - @:PROHIBIT(n == 0 .or. p == 0 & - .or. & - f_is_default(patch_ib(patch_id)%x_centroid) & - .or. & - f_is_default(patch_ib(patch_id)%y_centroid) & - .or. & - f_is_default(patch_ib(patch_id)%z_centroid) & - .or. & - patch_ib(patch_id)%radius <= 0._wp, & - 'in sphere IB patch '//trim(iStr)) + @:PROHIBIT(n == 0 .or. p == 0 .or. f_is_default(patch_ib(patch_id)%x_centroid) .or. f_is_default(patch_ib(patch_id) & + & %y_centroid) .or. f_is_default(patch_ib(patch_id)%z_centroid) .or. patch_ib(patch_id)%radius <= 0._wp, & + & 'in sphere IB patch '//trim(iStr)) end subroutine s_check_sphere_ib_patch_geometry - !> This subroutine verifies that the geometric parameters of - !! the cuboid patch have consistently been inputted by - !! the user. - !! @param patch_id Patch identifier + !> This subroutine verifies that the geometric parameters of the cuboid patch have consistently been inputted by the user. + !! @param patch_id Patch identifier impure subroutine s_check_cuboid_ib_patch_geometry(patch_id) integer, intent(in) :: patch_id call s_int_to_str(patch_id, iStr) - @:PROHIBIT(n == 0 .or. p == 0 & - .or. & - f_is_default(patch_ib(patch_id)%x_centroid) & - .or. & - f_is_default(patch_ib(patch_id)%y_centroid) & - .or. & - f_is_default(patch_ib(patch_id)%z_centroid) & - .or. & - patch_ib(patch_id)%length_x <= 0._wp & - .or. & - patch_ib(patch_id)%length_y <= 0._wp & - .or. & - patch_ib(patch_id)%length_z <= 0._wp, & - 'in cuboid IB patch '//trim(iStr)) + @:PROHIBIT(n == 0 .or. p == 0 .or. f_is_default(patch_ib(patch_id)%x_centroid) .or. f_is_default(patch_ib(patch_id) & + & %y_centroid) .or. f_is_default(patch_ib(patch_id)%z_centroid) .or. patch_ib(patch_id) & + & %length_x <= 0._wp .or. patch_ib(patch_id)%length_y <= 0._wp .or. patch_ib(patch_id)%length_z <= 0._wp, & + & 'in cuboid IB patch '//trim(iStr)) end subroutine s_check_cuboid_ib_patch_geometry - !> This subroutine verifies that the geometric parameters of - !! the cylinder patch have consistently been inputted by - !! the user. - !! @param patch_id Patch identifier + !> This subroutine verifies that the geometric parameters of the cylinder patch have consistently been inputted by the user. + !! @param patch_id Patch identifier impure subroutine s_check_cylinder_ib_patch_geometry(patch_id) integer, intent(in) :: patch_id call s_int_to_str(patch_id, iStr) - @:PROHIBIT(p == 0 & - .or. & - f_is_default(patch_ib(patch_id)%x_centroid) & - .or. & - f_is_default(patch_ib(patch_id)%y_centroid) & - .or. & - f_is_default(patch_ib(patch_id)%z_centroid) & - .or. & - (patch_ib(patch_id)%length_x <= 0._wp .and. & - patch_ib(patch_id)%length_y <= 0._wp .and. & - patch_ib(patch_id)%length_z <= 0._wp) & - .or. & - patch_ib(patch_id)%radius <= 0._wp, & - 'in cylinder IB patch '//trim(iStr)) - - @:PROHIBIT( & - (patch_ib(patch_id)%length_x > 0._wp .and. & - ((.not. f_is_default(patch_ib(patch_id)%length_y)) .or. & - (.not. f_is_default(patch_ib(patch_id)%length_z)))) & - .or. & - (patch_ib(patch_id)%length_y > 0._wp .and. & - ((.not. f_is_default(patch_ib(patch_id)%length_x)) .or. & - (.not. f_is_default(patch_ib(patch_id)%length_z)))) & - .or. & - (patch_ib(patch_id)%length_z > 0._wp .and. & - ((.not. f_is_default(patch_ib(patch_id)%length_x)) .or. & - (.not. f_is_default(patch_ib(patch_id)%length_y)))), & - 'in cylinder IB patch '//trim(iStr)) + @:PROHIBIT(p == 0 .or. f_is_default(patch_ib(patch_id)%x_centroid) .or. f_is_default(patch_ib(patch_id)%y_centroid) & + & .or. f_is_default(patch_ib(patch_id)%z_centroid) .or. (patch_ib(patch_id) & + & %length_x <= 0._wp .and. patch_ib(patch_id)%length_y <= 0._wp .and. patch_ib(patch_id)%length_z <= 0._wp) & + & .or. patch_ib(patch_id)%radius <= 0._wp, 'in cylinder IB patch '//trim(iStr)) + + @:PROHIBIT( (patch_ib(patch_id)%length_x > 0._wp .and. ((.not. f_is_default(patch_ib(patch_id)%length_y)) & + & .or. (.not. f_is_default(patch_ib(patch_id)%length_z)))) .or. (patch_ib(patch_id) & + & %length_y > 0._wp .and. ((.not. f_is_default(patch_ib(patch_id)%length_x)) & + & .or. (.not. f_is_default(patch_ib(patch_id)%length_z)))) .or. (patch_ib(patch_id) & + & %length_z > 0._wp .and. ((.not. f_is_default(patch_ib(patch_id)%length_x)) & + & .or. (.not. f_is_default(patch_ib(patch_id)%length_y)))), 'in cylinder IB patch '//trim(iStr)) end subroutine s_check_cylinder_ib_patch_geometry - !> This subroutine verifies that the geometric parameters of - !! the model patch have consistently been inputted by - !! the user. - !! @param patch_id Patch identifier + !> This subroutine verifies that the geometric parameters of the model patch have consistently been inputted by the user. + !! @param patch_id Patch identifier impure subroutine s_check_model_ib_patch_geometry(patch_id) integer, intent(in) :: patch_id call s_int_to_str(patch_id, iStr) - @:PROHIBIT(patch_ib(patch_id)%model_filepath == dflt_char, & - 'Empty model file path for patch '//trim(iStr)) + @:PROHIBIT(patch_ib(patch_id)%model_filepath == dflt_char, 'Empty model file path for patch '//trim(iStr)) - @:PROHIBIT(patch_ib(patch_id)%model_scale(1) <= 0._wp & - .or. & - patch_ib(patch_id)%model_scale(2) <= 0._wp & - .or. & - patch_ib(patch_id)%model_scale(3) <= 0._wp, & - 'Negative scale in model IB patch '//trim(iStr)) + @:PROHIBIT(patch_ib(patch_id)%model_scale(1) <= 0._wp .or. patch_ib(patch_id)%model_scale(2) & + & <= 0._wp .or. patch_ib(patch_id)%model_scale(3) <= 0._wp, 'Negative scale in model IB patch '//trim(iStr)) end subroutine s_check_model_ib_patch_geometry !!> This subroutine verifies that the geometric parameters of - !! the inactive patch remain unaltered by the user inputs. - !! @param patch_id Patch identifier + !! the inactive patch remain unaltered by the user inputs. @param patch_id Patch identifier impure subroutine s_check_inactive_ib_patch_geometry(patch_id) integer, intent(in) :: patch_id call s_int_to_str(patch_id, iStr) - @:PROHIBIT((.not. f_is_default(patch_ib(patch_id)%x_centroid)) & - .or. & - (.not. f_is_default(patch_ib(patch_id)%y_centroid)) & - .or. & - (.not. f_is_default(patch_ib(patch_id)%z_centroid)) & - .or. & - (.not. f_is_default(patch_ib(patch_id)%length_x)) & - .or. & - (.not. f_is_default(patch_ib(patch_id)%length_y)) & - .or. & - (.not. f_is_default(patch_ib(patch_id)%length_z)) & - .or. & - (.not. f_is_default(patch_ib(patch_id)%radius)), & - 'in inactive IB patch '//trim(iStr)) + @:PROHIBIT((.not. f_is_default(patch_ib(patch_id)%x_centroid)) .or. (.not. f_is_default(patch_ib(patch_id)%y_centroid)) & + & .or. (.not. f_is_default(patch_ib(patch_id)%z_centroid)) .or. (.not. f_is_default(patch_ib(patch_id) & + & %length_x)) .or. (.not. f_is_default(patch_ib(patch_id)%length_y)) & + & .or. (.not. f_is_default(patch_ib(patch_id)%length_z)) .or. (.not. f_is_default(patch_ib(patch_id)%radius)), & + & 'in inactive IB patch '//trim(iStr)) end subroutine s_check_inactive_ib_patch_geometry diff --git a/src/pre_process/m_check_patches.fpp b/src/pre_process/m_check_patches.fpp index 6725faba75..170c52ea90 100644 --- a/src/pre_process/m_check_patches.fpp +++ b/src/pre_process/m_check_patches.fpp @@ -11,23 +11,17 @@ module m_check_patches ! Dependencies - use m_derived_types !< Definitions of the derived types - - use m_global_parameters !< Global parameters for the code - - use m_mpi_proxy !< Message passing interface (MPI) module proxy - - use m_data_output !< Procedures to write the grid data and the - !! conservative variables to files + use m_derived_types !< Definitions of the derived types + use m_global_parameters !< Global parameters for the code + use m_mpi_proxy !< Message passing interface (MPI) module proxy + use m_data_output !< Procedures to write the grid data and the conservative variables to files #ifdef MFC_MPI - use mpi !< Message passing interface (MPI) module + use mpi !< Message passing interface (MPI) module #endif use m_compile_specific - - use m_helper_basic !< Functions to compare floating point numbers - + use m_helper_basic !< Functions to compare floating point numbers use m_helper implicit none @@ -41,7 +35,7 @@ contains !> @brief Validates the geometry parameters of all active and inactive initial condition patches. impure subroutine s_check_patches - integer :: i + integer :: i character(len=10) :: num_patches_str call s_int_to_str(num_patches, num_patches_str) @@ -50,52 +44,53 @@ contains if (i <= num_patches) then ! call s_check_patch_geometry(i) call s_int_to_str(i, iStr) - @:PROHIBIT(patch_icpp(i)%geometry == 6, "Invalid patch geometry number. "// & - "patch_icpp("//trim(iStr)//")%geometry is deprecated.") - @:PROHIBIT(patch_icpp(i)%geometry == 7, "Invalid patch geometry number. "// & - "patch_icpp("//trim(iStr)//")%geometry is deprecated.") - @:PROHIBIT(patch_icpp(i)%geometry == 15, "Invalid patch geometry number. "// & - "patch_icpp("//trim(iStr)//")%geometry is deprecated.") - @:PROHIBIT(patch_icpp(i)%geometry == dflt_int, "Invalid patch geometry number. "// & - "patch_icpp("//trim(iStr)//")%geometry must be set.") + @:PROHIBIT(patch_icpp(i)%geometry == 6, & + & "Invalid patch geometry number. "// "patch_icpp("//trim(iStr)//")%geometry is deprecated.") + @:PROHIBIT(patch_icpp(i)%geometry == 7, & + & "Invalid patch geometry number. "// "patch_icpp("//trim(iStr)//")%geometry is deprecated.") + @:PROHIBIT(patch_icpp(i)%geometry == 15, & + & "Invalid patch geometry number. "// "patch_icpp("//trim(iStr)//")%geometry is deprecated.") + @:PROHIBIT(patch_icpp(i)%geometry == dflt_int, & + & "Invalid patch geometry number. "// "patch_icpp("//trim(iStr)//")%geometry must be set.") ! Constraints on the geometric initial condition patch parameters if (patch_icpp(i)%geometry == 1) then call s_check_line_segment_patch_geometry(i) - elseif (patch_icpp(i)%geometry == 2) then + else if (patch_icpp(i)%geometry == 2) then call s_check_circle_patch_geometry(i) - elseif (patch_icpp(i)%geometry == 3) then + else if (patch_icpp(i)%geometry == 3) then call s_check_rectangle_patch_geometry(i) - elseif (patch_icpp(i)%geometry == 4) then + else if (patch_icpp(i)%geometry == 4) then call s_check_line_sweep_patch_geometry(i) - elseif (patch_icpp(i)%geometry == 5) then + else if (patch_icpp(i)%geometry == 5) then call s_check_ellipse_patch_geometry(i) - elseif (patch_icpp(i)%geometry == 8) then + else if (patch_icpp(i)%geometry == 8) then call s_check_sphere_patch_geometry(i) - elseif (patch_icpp(i)%geometry == 9) then + else if (patch_icpp(i)%geometry == 9) then call s_check_cuboid_patch_geometry(i) - elseif (patch_icpp(i)%geometry == 10) then + else if (patch_icpp(i)%geometry == 10) then call s_check_cylinder_patch_geometry(i) - elseif (patch_icpp(i)%geometry == 11) then + else if (patch_icpp(i)%geometry == 11) then call s_check_plane_sweep_patch_geometry(i) - elseif (patch_icpp(i)%geometry == 12) then + else if (patch_icpp(i)%geometry == 12) then call s_check_ellipsoid_patch_geometry(i) - elseif (patch_icpp(i)%geometry == 13) then + else if (patch_icpp(i)%geometry == 13) then call s_check_2d_modal_patch_geometry(i) - elseif (patch_icpp(i)%geometry == 14) then + else if (patch_icpp(i)%geometry == 14) then call s_check_3d_spherical_harmonic_patch_geometry(i) - elseif (patch_icpp(i)%geometry == 20) then + else if (patch_icpp(i)%geometry == 20) then call s_check_2D_TaylorGreen_vortex_patch_geometry(i) - elseif (patch_icpp(i)%geometry == 21) then + else if (patch_icpp(i)%geometry == 21) then call s_check_model_geometry(i) else - call s_prohibit_abort("Invalid patch geometry number", "patch_icpp("//trim(iStr)//")%geometry "// & - "must be between 1 and 21") + call s_prohibit_abort("Invalid patch geometry number", & + & "patch_icpp(" // trim(iStr) // ")%geometry " // "must be between 1 and 21") end if else - @:PROHIBIT(patch_icpp(i)%geometry /= dflt_int, "Inactive patch defined. "// & - "patch_icpp("//trim(iStr)//")%geometry not be set for inactive patches. "// & - "Patch "//trim(iStr)//" is inactive as the number of patches is "//trim(num_patches_str)) + @:PROHIBIT(patch_icpp(i)%geometry /= dflt_int, & + & "Inactive patch defined. "// "patch_icpp("//trim(iStr) & + & //")%geometry not be set for inactive patches. "// "Patch "//trim(iStr) & + & //" is inactive as the number of patches is "//trim(num_patches_str)) call s_check_inactive_patch_geometry(i) end if end do @@ -111,17 +106,10 @@ contains ! Constraints on smoothing initial condition patch parameters do i = 1, num_patches - if (i > 1 .and. (patch_icpp(i)%geometry == 2 .or. & - patch_icpp(i)%geometry == 3 .or. & - patch_icpp(i)%geometry == 4 .or. & - patch_icpp(i)%geometry == 5 .or. & - patch_icpp(i)%geometry == 8 .or. & - patch_icpp(i)%geometry == 9 .or. & - patch_icpp(i)%geometry == 10 .or. & - patch_icpp(i)%geometry == 11 .or. & - patch_icpp(i)%geometry == 12 .or. & - patch_icpp(i)%geometry == 13 .or. & - patch_icpp(i)%geometry == 14)) then + if (i > 1 .and. (patch_icpp(i)%geometry == 2 .or. patch_icpp(i)%geometry == 3 .or. patch_icpp(i) & + & %geometry == 4 .or. patch_icpp(i)%geometry == 5 .or. patch_icpp(i)%geometry == 8 .or. patch_icpp(i) & + & %geometry == 9 .or. patch_icpp(i)%geometry == 10 .or. patch_icpp(i)%geometry == 11 .or. patch_icpp(i) & + & %geometry == 12 .or. patch_icpp(i)%geometry == 13 .or. patch_icpp(i)%geometry == 14)) then call s_check_supported_patch_smoothing(i) else call s_check_unsupported_patch_smoothing(i) @@ -140,24 +128,27 @@ contains end subroutine s_check_patches !> This subroutine checks the line segment patch input - !! @param patch_id Patch identifier + !! @param patch_id Patch identifier impure subroutine s_check_line_segment_patch_geometry(patch_id) integer, intent(in) :: patch_id + call s_int_to_str(patch_id, iStr) @:PROHIBIT(n > 0, "Line segment patch "//trim(iStr)//": n must be zero") - @:PROHIBIT(patch_icpp(patch_id)%length_x <= 0._wp, "Line segment patch "//trim(iStr)//": length_x must be greater than zero") + @:PROHIBIT(patch_icpp(patch_id)%length_x <= 0._wp, & + & "Line segment patch "//trim(iStr)//": length_x must be greater than zero") @:PROHIBIT(f_is_default(patch_icpp(patch_id)%x_centroid), "Line segment patch "//trim(iStr)//": x_centroid must be set") @:PROHIBIT(cyl_coord, "Line segment patch "//trim(iStr)//": cyl_coord is not supported") end subroutine s_check_line_segment_patch_geometry - !> This subroutine checks the circle patch input - !! @param patch_id Patch identifier + !> This subroutine checks the circle patch input + !! @param patch_id Patch identifier impure subroutine s_check_circle_patch_geometry(patch_id) integer, intent(in) :: patch_id + call s_int_to_str(patch_id, iStr) @:PROHIBIT(n == 0, "Circle patch "//trim(iStr)//": n must be zero") @@ -168,11 +159,12 @@ contains end subroutine s_check_circle_patch_geometry - !> This subroutine checks the rectangle patch input - !! @param patch_id Patch identifier + !> This subroutine checks the rectangle patch input + !! @param patch_id Patch identifier impure subroutine s_check_rectangle_patch_geometry(patch_id) integer, intent(in) :: patch_id + call s_int_to_str(patch_id, iStr) @:PROHIBIT(n == 0, "Rectangle patch "//trim(iStr)//": n must be greater than zero") @@ -185,10 +177,11 @@ contains end subroutine s_check_rectangle_patch_geometry !> This subroutine checks the line sweep patch input - !! @param patch_id Patch identifier + !! @param patch_id Patch identifier impure subroutine s_check_line_sweep_patch_geometry(patch_id) integer, intent(in) :: patch_id + call s_int_to_str(patch_id, iStr) @:PROHIBIT(n == 0, "Line sweep patch "//trim(iStr)//": n must be greater than zero") @@ -197,15 +190,17 @@ contains @:PROHIBIT(f_is_default(patch_icpp(patch_id)%y_centroid), "Line sweep patch "//trim(iStr)//": y_centroid must be set") @:PROHIBIT(f_is_default(patch_icpp(patch_id)%normal(1)), "Line sweep patch "//trim(iStr)//": normal(1) must be set") @:PROHIBIT(f_is_default(patch_icpp(patch_id)%normal(2)), "Line sweep patch "//trim(iStr)//": normal(2) must be set") - @:PROHIBIT(.not. f_is_default(patch_icpp(patch_id)%normal(3)), "Line sweep patch "//trim(iStr)//": normal(3) must not be set") + @:PROHIBIT(.not. f_is_default(patch_icpp(patch_id)%normal(3)), & + & "Line sweep patch "//trim(iStr)//": normal(3) must not be set") end subroutine s_check_line_sweep_patch_geometry - !> This subroutine checks the ellipse patch input - !! @param patch_id Patch identifier + !> This subroutine checks the ellipse patch input + !! @param patch_id Patch identifier impure subroutine s_check_ellipse_patch_geometry(patch_id) integer, intent(in) :: patch_id + call s_int_to_str(patch_id, iStr) @:PROHIBIT(n == 0, "Ellipse patch "//trim(iStr)//": n must be greater than zero") @@ -218,28 +213,35 @@ contains end subroutine s_check_ellipse_patch_geometry - !> This subroutine checks the model patch input - !! @param patch_id Patch identifier + !> This subroutine checks the model patch input + !! @param patch_id Patch identifier impure subroutine s_check_2D_TaylorGreen_vortex_patch_geometry(patch_id) integer, intent(in) :: patch_id + call s_int_to_str(patch_id, iStr) @:PROHIBIT(n == 0, "Taylor Green vortex patch "//trim(iStr)//": n must be greater than zero") @:PROHIBIT(p > 0, "Taylor Green vortex patch "//trim(iStr)//": p must be zero") - @:PROHIBIT(f_is_default(patch_icpp(patch_id)%x_centroid), "Taylor Green vortex patch "//trim(iStr)//": x_centroid must be set") - @:PROHIBIT(f_is_default(patch_icpp(patch_id)%y_centroid), "Taylor Green vortex patch "//trim(iStr)//": y_centroid must be set") - @:PROHIBIT(patch_icpp(patch_id)%length_x <= 0._wp, "Taylor Green vortex patch "//trim(iStr)//": length_x must be greater than zero") - @:PROHIBIT(patch_icpp(patch_id)%length_y <= 0._wp, "Taylor Green vortex patch "//trim(iStr)//": length_y must be greater than zero") - @:PROHIBIT(patch_icpp(patch_id)%vel(2) <= 0._wp, "Taylor Green vortex patch "//trim(iStr)//": vel(2) must be greater than zero") + @:PROHIBIT(f_is_default(patch_icpp(patch_id)%x_centroid), & + & "Taylor Green vortex patch "//trim(iStr)//": x_centroid must be set") + @:PROHIBIT(f_is_default(patch_icpp(patch_id)%y_centroid), & + & "Taylor Green vortex patch "//trim(iStr)//": y_centroid must be set") + @:PROHIBIT(patch_icpp(patch_id)%length_x <= 0._wp, & + & "Taylor Green vortex patch "//trim(iStr)//": length_x must be greater than zero") + @:PROHIBIT(patch_icpp(patch_id)%length_y <= 0._wp, & + & "Taylor Green vortex patch "//trim(iStr)//": length_y must be greater than zero") + @:PROHIBIT(patch_icpp(patch_id)%vel(2) <= 0._wp, & + & "Taylor Green vortex patch "//trim(iStr)//": vel(2) must be greater than zero") end subroutine s_check_2D_TaylorGreen_vortex_patch_geometry !> This subroutine checks the model patch input - !! @param patch_id Patch identifier + !! @param patch_id Patch identifier impure subroutine s_check_sphere_patch_geometry(patch_id) integer, intent(in) :: patch_id + call s_int_to_str(patch_id, iStr) @:PROHIBIT(p == 0, "Sphere patch "//trim(iStr)//": p must be greater than zero") @@ -251,6 +253,7 @@ contains end subroutine s_check_sphere_patch_geometry impure subroutine s_check_2d_modal_patch_geometry(patch_id) + integer, intent(in) :: patch_id call s_int_to_str(patch_id, iStr) @@ -264,24 +267,30 @@ contains end subroutine s_check_2d_modal_patch_geometry impure subroutine s_check_3d_spherical_harmonic_patch_geometry(patch_id) + integer, intent(in) :: patch_id call s_int_to_str(patch_id, iStr) @:PROHIBIT(p == 0, "Spherical harmonic patch "//trim(iStr)//": p must be greater than zero") - @:PROHIBIT(patch_icpp(patch_id)%radius <= 0._wp, "Spherical harmonic patch "//trim(iStr)//": radius must be greater than zero") - @:PROHIBIT(f_is_default(patch_icpp(patch_id)%x_centroid), "Spherical harmonic patch "//trim(iStr)//": x_centroid must be set") - @:PROHIBIT(f_is_default(patch_icpp(patch_id)%y_centroid), "Spherical harmonic patch "//trim(iStr)//": y_centroid must be set") - @:PROHIBIT(f_is_default(patch_icpp(patch_id)%z_centroid), "Spherical harmonic patch "//trim(iStr)//": z_centroid must be set") + @:PROHIBIT(patch_icpp(patch_id)%radius <= 0._wp, & + & "Spherical harmonic patch "//trim(iStr)//": radius must be greater than zero") + @:PROHIBIT(f_is_default(patch_icpp(patch_id)%x_centroid), & + & "Spherical harmonic patch "//trim(iStr)//": x_centroid must be set") + @:PROHIBIT(f_is_default(patch_icpp(patch_id)%y_centroid), & + & "Spherical harmonic patch "//trim(iStr)//": y_centroid must be set") + @:PROHIBIT(f_is_default(patch_icpp(patch_id)%z_centroid), & + & "Spherical harmonic patch "//trim(iStr)//": z_centroid must be set") end subroutine s_check_3d_spherical_harmonic_patch_geometry - !> This subroutine checks the model patch input - !! @param patch_id Patch identifier + !> This subroutine checks the model patch input + !! @param patch_id Patch identifier impure subroutine s_check_cuboid_patch_geometry(patch_id) ! Patch identifier integer, intent(in) :: patch_id + call s_int_to_str(patch_id, iStr) @:PROHIBIT(p == 0, "Cuboid patch "//trim(iStr)//": p must be greater than zero") @@ -294,12 +303,13 @@ contains end subroutine s_check_cuboid_patch_geometry - !> This subroutine checks the model patch input - !! @param patch_id Patch identifier + !> This subroutine checks the model patch input + !! @param patch_id Patch identifier impure subroutine s_check_cylinder_patch_geometry(patch_id) ! Patch identifier integer, intent(in) :: patch_id + call s_int_to_str(patch_id, iStr) @:PROHIBIT(p == 0, "Cylinder patch "//trim(iStr)//": p must be greater than zero") @@ -309,27 +319,25 @@ contains @:PROHIBIT(patch_icpp(patch_id)%radius <= 0._wp, "Cylinder patch "//trim(iStr)//": radius must be greater than zero") ! Check if exactly one length is defined - @:PROHIBIT(count([ & - patch_icpp(patch_id)%length_x > 0._wp, & - patch_icpp(patch_id)%length_y > 0._wp, & - patch_icpp(patch_id)%length_z > 0._wp & - ]) /= 1, "Cylinder patch "//trim(iStr)//": Exactly one of length_x, length_y, or length_z must be defined and positive") + @:PROHIBIT(count([ patch_icpp(patch_id)%length_x > 0._wp, patch_icpp(patch_id)%length_y > 0._wp, & + & patch_icpp(patch_id)%length_z > 0._wp ]) /= 1, & + & "Cylinder patch "//trim(iStr)//": Exactly one of length_x, length_y, or length_z must be defined and positive") ! Ensure the defined length is positive - @:PROHIBIT( & - (.not. f_is_default(patch_icpp(patch_id)%length_x) .and. patch_icpp(patch_id)%length_x <= 0._wp) .or. & - (.not. f_is_default(patch_icpp(patch_id)%length_y) .and. patch_icpp(patch_id)%length_y <= 0._wp) .or. & - (.not. f_is_default(patch_icpp(patch_id)%length_z) .and. patch_icpp(patch_id)%length_z <= 0._wp), & - "Cylinder patch "//trim(iStr)//": The defined length_{} must be greater than zero") + @:PROHIBIT( (.not. f_is_default(patch_icpp(patch_id)%length_x) .and. patch_icpp(patch_id)%length_x <= 0._wp) & + & .or. (.not. f_is_default(patch_icpp(patch_id)%length_y) .and. patch_icpp(patch_id)%length_y <= 0._wp) & + & .or. (.not. f_is_default(patch_icpp(patch_id)%length_z) .and. patch_icpp(patch_id)%length_z <= 0._wp), & + & "Cylinder patch "//trim(iStr)//": The defined length_{} must be greater than zero") end subroutine s_check_cylinder_patch_geometry - !> This subroutine checks the model patch input - !! @param patch_id Patch identifier + !> This subroutine checks the model patch input + !! @param patch_id Patch identifier impure subroutine s_check_plane_sweep_patch_geometry(patch_id) ! Patch identifier integer, intent(in) :: patch_id + call s_int_to_str(patch_id, iStr) @:PROHIBIT(p == 0, "Plane sweep patch "//trim(iStr)//": p must be greater than zero") @@ -343,10 +351,11 @@ contains end subroutine s_check_plane_sweep_patch_geometry !> This subroutine checks the model patch input - !! @param patch_id Patch identifier + !! @param patch_id Patch identifier impure subroutine s_check_ellipsoid_patch_geometry(patch_id) integer, intent(in) :: patch_id + call s_int_to_str(patch_id, iStr) @:PROHIBIT(p == 0, "Ellipsoid patch "//trim(iStr)//": p must be greater than zero") @@ -360,16 +369,19 @@ contains end subroutine s_check_ellipsoid_patch_geometry !!> This subroutine verifies that the geometric parameters of - !! the inactive patch remain unaltered by the user inputs. - !! @param patch_id Patch identifier + !! the inactive patch remain unaltered by the user inputs. @param patch_id Patch identifier impure subroutine s_check_inactive_patch_geometry(patch_id) integer, intent(in) :: patch_id + call s_int_to_str(patch_id, iStr) - @:PROHIBIT(.not. f_is_default(patch_icpp(patch_id)%x_centroid), "Inactive patch "//trim(iStr)//": x_centroid must not be set") - @:PROHIBIT(.not. f_is_default(patch_icpp(patch_id)%y_centroid), "Inactive patch "//trim(iStr)//": y_centroid must not be set") - @:PROHIBIT(.not. f_is_default(patch_icpp(patch_id)%z_centroid), "Inactive patch "//trim(iStr)//": z_centroid must not be set") + @:PROHIBIT(.not. f_is_default(patch_icpp(patch_id)%x_centroid), & + & "Inactive patch "//trim(iStr)//": x_centroid must not be set") + @:PROHIBIT(.not. f_is_default(patch_icpp(patch_id)%y_centroid), & + & "Inactive patch "//trim(iStr)//": y_centroid must not be set") + @:PROHIBIT(.not. f_is_default(patch_icpp(patch_id)%z_centroid), & + & "Inactive patch "//trim(iStr)//": z_centroid must not be set") @:PROHIBIT(.not. f_is_default(patch_icpp(patch_id)%length_x), "Inactive patch "//trim(iStr)//": length_x must not be set") @:PROHIBIT(.not. f_is_default(patch_icpp(patch_id)%length_y), "Inactive patch "//trim(iStr)//": length_y must not be set") @:PROHIBIT(.not. f_is_default(patch_icpp(patch_id)%length_z), "Inactive patch "//trim(iStr)//": length_z must not be set") @@ -385,122 +397,122 @@ contains end subroutine s_check_inactive_patch_geometry - !> This subroutine verifies the active patch's right to overwrite the preceding patches - !! @param patch_id Patch identifier + !> This subroutine verifies the active patch's right to overwrite the preceding patches + !! @param patch_id Patch identifier impure subroutine s_check_active_patch_alteration_rights(patch_id) integer, intent(in) :: patch_id + call s_int_to_str(patch_id, iStr) @:PROHIBIT(.not. patch_icpp(patch_id)%alter_patch(0), "Patch "//trim(iStr)//": alter_patch(0) must be true") - @:PROHIBIT(any(patch_icpp(patch_id)%alter_patch(patch_id:)), "Patch "//trim(iStr)// & - ":alter_patch(i) must be false for i >= "//trim(iStr)//". Only preceding patches can be altered") + @:PROHIBIT(any(patch_icpp(patch_id)%alter_patch(patch_id:)), & + & "Patch "//trim(iStr)// ":alter_patch(i) must be false for i >= "//trim(iStr) & + & //". Only preceding patches can be altered") end subroutine s_check_active_patch_alteration_rights - !> This subroutine verifies that inactive patches cannot overwrite other patches - !! @param patch_id Patch identifier + !> This subroutine verifies that inactive patches cannot overwrite other patches + !! @param patch_id Patch identifier impure subroutine s_check_inactive_patch_alteration_rights(patch_id) ! Patch identifier integer, intent(in) :: patch_id + call s_int_to_str(patch_id, iStr) @:PROHIBIT(.not. patch_icpp(patch_id)%alter_patch(0), "Inactive patch "//trim(iStr)//": cannot have alter_patch(0) altered") - @:PROHIBIT(any(patch_icpp(patch_id)%alter_patch(1:)), "Inactive patch "//trim(iStr)//": cannot have any alter_patch(i) enabled") + @:PROHIBIT(any(patch_icpp(patch_id)%alter_patch(1:)), & + & "Inactive patch "//trim(iStr)//": cannot have any alter_patch(i) enabled") end subroutine s_check_inactive_patch_alteration_rights !> This subroutine checks the smoothing parameters - !! @param patch_id Patch identifier + !! @param patch_id Patch identifier impure subroutine s_check_supported_patch_smoothing(patch_id) integer, intent(in) :: patch_id + call s_int_to_str(patch_id, iStr) if (patch_icpp(patch_id)%smoothen) then @:PROHIBIT(patch_icpp(patch_id)%smooth_patch_id >= patch_id, & - "Smoothen enabled. Patch "//trim(iStr)//": smooth_patch_id must be less than patch_id") + & "Smoothen enabled. Patch "//trim(iStr)//": smooth_patch_id must be less than patch_id") @:PROHIBIT(patch_icpp(patch_id)%smooth_patch_id == 0, & - "Smoothen enabled. Patch "//trim(iStr)//": smooth_patch_id must be greater than zero") + & "Smoothen enabled. Patch "//trim(iStr)//": smooth_patch_id must be greater than zero") @:PROHIBIT(patch_icpp(patch_id)%smooth_coeff <= 0._wp, & - "Smoothen enabled. Patch "//trim(iStr)//": smooth_coeff must be greater than zero") + & "Smoothen enabled. Patch "//trim(iStr)//": smooth_coeff must be greater than zero") else @:PROHIBIT(patch_icpp(patch_id)%smooth_patch_id /= patch_id, & - "Smoothen disabled. Patch "//trim(iStr)//": smooth_patch_id must be equal to patch_id") + & "Smoothen disabled. Patch "//trim(iStr)//": smooth_patch_id must be equal to patch_id") @:PROHIBIT(.not. f_is_default(patch_icpp(patch_id)%smooth_coeff), & - "Smoothen disabled. Patch "//trim(iStr)//": smooth_coeff must not be set") + & "Smoothen disabled. Patch "//trim(iStr)//": smooth_coeff must not be set") end if end subroutine s_check_supported_patch_smoothing !> This subroutine verifies that inactive patches cannot be smoothed - !! @param patch_id Patch identifier + !! @param patch_id Patch identifier impure subroutine s_check_unsupported_patch_smoothing(patch_id) ! Patch identifier integer, intent(in) :: patch_id + call s_int_to_str(patch_id, iStr) - @:PROHIBIT(patch_icpp(patch_id)%smoothen, & - "Inactive patch "//trim(iStr)//": cannot have smoothen enabled") + @:PROHIBIT(patch_icpp(patch_id)%smoothen, "Inactive patch "//trim(iStr)//": cannot have smoothen enabled") @:PROHIBIT(patch_icpp(patch_id)%smooth_patch_id /= patch_id, & - "Inactive patch "//trim(iStr)//": smooth_patch_id must be equal to patch_id") + & "Inactive patch "//trim(iStr)//": smooth_patch_id must be equal to patch_id") @:PROHIBIT(.not. f_is_default(patch_icpp(patch_id)%smooth_coeff), & - "Inactive patch "//trim(iStr)//": smooth_coeff must not be set") + & "Inactive patch "//trim(iStr)//": smooth_coeff must not be set") end subroutine s_check_unsupported_patch_smoothing - !> This subroutine checks the primitive variables - !! @param patch_id Patch identifier + !> This subroutine checks the primitive variables + !! @param patch_id Patch identifier impure subroutine s_check_active_patch_primitive_variables(patch_id) - integer, intent(in) :: patch_id - + integer, intent(in) :: patch_id logical, dimension(3) :: is_set_B call s_int_to_str(patch_id, iStr) - @:PROHIBIT(f_is_default(patch_icpp(patch_id)%vel(1)), & - "Patch "//trim(iStr)//": vel(1) must be set") - @:PROHIBIT(n == 0 .and. (.not. f_is_default(patch_icpp(patch_id)%vel(2))) .and. (.not. f_approx_equal(patch_icpp(patch_id)%vel(2) , 0._wp)) .and. (.not. mhd), & - "Patch "//trim(iStr)//": vel(2) must not be set when n = 0") - @:PROHIBIT(n > 0 .and. f_is_default(patch_icpp(patch_id)%vel(2)), & - "Patch "//trim(iStr)//": vel(2) must be set when n > 0") - @:PROHIBIT(p == 0 .and. (.not. f_is_default(patch_icpp(patch_id)%vel(3))) .and. (.not. f_approx_equal(patch_icpp(patch_id)%vel(3) , 0._wp)) .and. (.not. mhd), & - "Patch "//trim(iStr)//": vel(3) must not be set when p = 0") - @:PROHIBIT(p > 0 .and. f_is_default(patch_icpp(patch_id)%vel(3)), & - "Patch "//trim(iStr)//": vel(3) must be set when p > 0") + @:PROHIBIT(f_is_default(patch_icpp(patch_id)%vel(1)), "Patch "//trim(iStr)//": vel(1) must be set") + @:PROHIBIT(n == 0 .and. (.not. f_is_default(patch_icpp(patch_id)%vel(2))) .and. (.not. f_approx_equal(patch_icpp(patch_id) & + & %vel(2) , 0._wp)) .and. (.not. mhd), "Patch "//trim(iStr)//": vel(2) must not be set when n = 0") + @:PROHIBIT(n > 0 .and. f_is_default(patch_icpp(patch_id)%vel(2)), "Patch "//trim(iStr)//": vel(2) must be set when n > 0") + @:PROHIBIT(p == 0 .and. (.not. f_is_default(patch_icpp(patch_id)%vel(3))) .and. (.not. f_approx_equal(patch_icpp(patch_id) & + & %vel(3) , 0._wp)) .and. (.not. mhd), "Patch "//trim(iStr)//": vel(3) must not be set when p = 0") + @:PROHIBIT(p > 0 .and. f_is_default(patch_icpp(patch_id)%vel(3)), "Patch "//trim(iStr)//": vel(3) must be set when p > 0") @:PROHIBIT(mhd .and. (f_is_default(patch_icpp(patch_id)%vel(2)) .or. f_is_default(patch_icpp(patch_id)%vel(3))), & - "Patch "//trim(iStr)//": All velocities (vel(1:3)) must be set when mhd = true") + & "Patch "//trim(iStr)//": All velocities (vel(1:3)) must be set when mhd = true") @:PROHIBIT(model_eqns == 1 .and. patch_icpp(patch_id)%rho <= 0._wp, & - "Patch "//trim(iStr)//": rho must be greater than zero when model_eqns = 1") + & "Patch "//trim(iStr)//": rho must be greater than zero when model_eqns = 1") @:PROHIBIT(model_eqns == 1 .and. patch_icpp(patch_id)%gamma <= 0._wp, & - "Patch "//trim(iStr)//": gamma must be greater than zero when model_eqns = 1") + & "Patch "//trim(iStr)//": gamma must be greater than zero when model_eqns = 1") @:PROHIBIT(model_eqns == 1 .and. patch_icpp(patch_id)%pi_inf < 0._wp, & - "Patch "//trim(iStr)//": pi_inf must be greater than or equal to zero when model_eqns = 1") + & "Patch "//trim(iStr)//": pi_inf must be greater than or equal to zero when model_eqns = 1") @:PROHIBIT(patch_icpp(patch_id)%geometry == 5 .and. patch_icpp(patch_id)%pi_inf > 0, & - "Patch "//trim(iStr)//": pi_inf must be less than or equal to zero when geometry = 5") + & "Patch "//trim(iStr)//": pi_inf must be less than or equal to zero when geometry = 5") @:PROHIBIT(model_eqns == 2 .and. any(patch_icpp(patch_id)%alpha_rho(1:num_fluids) < 0._wp), & - "Patch "//trim(iStr)//": alpha_rho(1:num_fluids) must be greater than or equal to zero when model_eqns = 2") + & "Patch "//trim(iStr)//": alpha_rho(1:num_fluids) must be greater than or equal to zero when model_eqns = 2") is_set_B(1) = .not. f_is_default(patch_icpp(patch_id)%Bx) is_set_B(2) = .not. f_is_default(patch_icpp(patch_id)%By) is_set_B(3) = .not. f_is_default(patch_icpp(patch_id)%Bz) - @:PROHIBIT(.not. mhd .and. any(is_set_B), & - "Bx, By, and Bz must not be set if MHD is not enabled") + @:PROHIBIT(.not. mhd .and. any(is_set_B), "Bx, By, and Bz must not be set if MHD is not enabled") @:PROHIBIT(mhd .and. n == 0 .and. is_set_B(1), "Bx must not be set in 1D MHD simulations") @:PROHIBIT(mhd .and. n > 0 .and. .not. is_set_B(1), "Bx must be set in 2D/3D MHD simulations") @:PROHIBIT(mhd .and. .not. (is_set_B(2) .and. is_set_B(3)), "By and Bz must be set in all MHD simulations") if (model_eqns == 2 .and. num_fluids < num_fluids_max) then @:PROHIBIT(.not. f_all_default(patch_icpp(patch_id)%alpha_rho(num_fluids + 1:)), & - "Patch "//trim(iStr)//": alpha_rho(i) must not be set for i > num_fluids") + & "Patch "//trim(iStr)//": alpha_rho(i) must not be set for i > num_fluids") @:PROHIBIT(.not. f_all_default(patch_icpp(patch_id)%alpha(num_fluids + 1:)), & - "Patch "//trim(iStr)//": alpha(i) must not be set for i > num_fluids") + & "Patch "//trim(iStr)//": alpha(i) must not be set for i > num_fluids") @:PROHIBIT(f_is_default(patch_icpp(patch_id)%alpha(num_fluids)), & - "Patch "//trim(iStr)//": alpha(num_fluids) must be set") + & "Patch "//trim(iStr)//": alpha(num_fluids) must be set") end if if (chemistry) then @@ -510,29 +522,23 @@ contains end subroutine s_check_active_patch_primitive_variables - !> This subroutine verifies that the primitive variables - !! associated with the given inactive patch remain unaltered - !! by the user inputs. - !! @param patch_id Patch identifier + !> This subroutine verifies that the primitive variables associated with the given inactive patch remain unaltered by the user + !! inputs. + !! @param patch_id Patch identifier impure subroutine s_check_inactive_patch_primitive_variables(patch_id) integer, intent(in) :: patch_id + call s_int_to_str(patch_id, iStr) @:PROHIBIT(.not. f_all_default(patch_icpp(patch_id)%alpha_rho), & - "Inactive patch "//trim(iStr)//": alpha_rho must not be set") - @:PROHIBIT(.not. f_is_default(patch_icpp(patch_id)%rho), & - "Inactive patch "//trim(iStr)//": rho must not be set") - @:PROHIBIT(.not. f_all_default(patch_icpp(patch_id)%vel), & - "Inactive patch "//trim(iStr)//": vel must not be set") - @:PROHIBIT(.not. f_is_default(patch_icpp(patch_id)%pres), & - "Inactive patch "//trim(iStr)//": pres must not be set") - @:PROHIBIT(.not. f_all_default(patch_icpp(patch_id)%alpha), & - "Inactive patch "//trim(iStr)//": alpha must not be set") - @:PROHIBIT(.not. f_is_default(patch_icpp(patch_id)%gamma), & - "Inactive patch "//trim(iStr)//": gamma must not be set") - @:PROHIBIT(.not. f_is_default(patch_icpp(patch_id)%pi_inf), & - "Inactive patch "//trim(iStr)//": pi_inf must not be set") + & "Inactive patch "//trim(iStr)//": alpha_rho must not be set") + @:PROHIBIT(.not. f_is_default(patch_icpp(patch_id)%rho), "Inactive patch "//trim(iStr)//": rho must not be set") + @:PROHIBIT(.not. f_all_default(patch_icpp(patch_id)%vel), "Inactive patch "//trim(iStr)//": vel must not be set") + @:PROHIBIT(.not. f_is_default(patch_icpp(patch_id)%pres), "Inactive patch "//trim(iStr)//": pres must not be set") + @:PROHIBIT(.not. f_all_default(patch_icpp(patch_id)%alpha), "Inactive patch "//trim(iStr)//": alpha must not be set") + @:PROHIBIT(.not. f_is_default(patch_icpp(patch_id)%gamma), "Inactive patch "//trim(iStr)//": gamma must not be set") + @:PROHIBIT(.not. f_is_default(patch_icpp(patch_id)%pi_inf), "Inactive patch "//trim(iStr)//": pi_inf must not be set") end subroutine s_check_inactive_patch_primitive_variables @@ -540,13 +546,13 @@ contains impure subroutine s_check_model_geometry(patch_id) integer, intent(in) :: patch_id - - logical :: file_exists + logical :: file_exists inquire (file=patch_icpp(patch_id)%model_filepath, exist=file_exists) - @:PROHIBIT(.not. file_exists, "Model file "//trim(patch_icpp(patch_id)%model_filepath)// & - " requested by patch "//trim(iStr)//" does not exist") + @:PROHIBIT(.not. file_exists, & + & "Model file "//trim(patch_icpp(patch_id)%model_filepath)// " requested by patch "//trim(iStr) & + & //" does not exist") end subroutine s_check_model_geometry diff --git a/src/pre_process/m_checker.fpp b/src/pre_process/m_checker.fpp index 63ed19199b..5585ca0a7a 100644 --- a/src/pre_process/m_checker.fpp +++ b/src/pre_process/m_checker.fpp @@ -7,12 +7,9 @@ !> @brief Checks pre-process input file parameters for compatibility and correctness module m_checker - use m_global_parameters !< Definitions of the global parameters - - use m_mpi_proxy !< Message passing interface (MPI) module proxy - - use m_helper_basic !< Functions to compare floating point numbers - + use m_global_parameters !< Definitions of the global parameters + use m_mpi_proxy !< Message passing interface (MPI) module proxy + use m_helper_basic !< Functions to compare floating point numbers use m_helper implicit none @@ -21,9 +18,9 @@ module m_checker contains - !> Checks compatibility of parameters in the input file. - !! Used by the pre_process stage + !> Checks compatibility of parameters in the input file. Used by the pre_process stage impure subroutine s_check_inputs + end subroutine s_check_inputs end module m_checker diff --git a/src/pre_process/m_data_output.fpp b/src/pre_process/m_data_output.fpp index 5dbc84ade8..0d1b9d76b5 100644 --- a/src/pre_process/m_data_output.fpp +++ b/src/pre_process/m_data_output.fpp @@ -5,115 +5,80 @@ !> @brief Writes grid and initial condition data to serial or parallel output files module m_data_output - use m_derived_types !< Definitions of the derived types - - use m_global_parameters !< Global parameters for the code - + use m_derived_types !< Definitions of the derived types + use m_global_parameters !< Global parameters for the code use m_helper - - use m_mpi_proxy !< Message passing interface (MPI) module proxy + use m_mpi_proxy !< Message passing interface (MPI) module proxy #ifdef MFC_MPI - use mpi !< Message passing interface (MPI) module + use mpi !< Message passing interface (MPI) module #endif use m_compile_specific - use m_variables_conversion - use m_helper - use m_delay_file_access - use m_boundary_common - use m_boundary_conditions - use m_thermochem, only: species_names - use m_helper implicit none - private; - public :: s_write_serial_data_files, & - s_write_parallel_data_files, & - s_write_data_files, & - s_initialize_data_output_module, & - s_finalize_data_output_module + private + public :: s_write_serial_data_files, s_write_parallel_data_files, s_write_data_files, s_initialize_data_output_module, & + & s_finalize_data_output_module type(scalar_field), allocatable, dimension(:) :: q_cons_temp abstract interface - !> Interface for the conservative data + !> Interface for the conservative data !! @param q_cons_vf Conservative variables impure subroutine s_write_abstract_data_files(q_cons_vf, q_prim_vf, bc_type) - import :: scalar_field, integer_field, sys_size, m, n, p, & - pres_field, num_dims + import :: scalar_field, integer_field, sys_size, m, n, p, pres_field, num_dims ! Conservative variables - type(scalar_field), & - dimension(sys_size), & - intent(inout) :: q_cons_vf, q_prim_vf - - type(integer_field), & - dimension(1:num_dims, -1:1), & - intent(in) :: bc_type + type(scalar_field), dimension(sys_size), intent(inout) :: q_cons_vf, q_prim_vf + type(integer_field), dimension(1:num_dims,-1:1), intent(in) :: bc_type end subroutine s_write_abstract_data_files end interface - character(LEN=path_len + 2*name_len), private :: t_step_dir !< - !! Time-step folder into which grid and initial condition data will be placed - - character(LEN=path_len + 2*name_len), public :: restart_dir !< - !! Restart data folder + !> Time-step folder into which grid and initial condition data will be placed + character(LEN=path_len + 2*name_len), private :: t_step_dir + character(LEN=path_len + 2*name_len), public :: restart_dir !< Restart data folder procedure(s_write_abstract_data_files), pointer :: s_write_data_files => null() contains - !> Writes grid and initial condition data files to the "0" - !! time-step directory in the local processor rank folder - !! @param q_cons_vf Conservative variables - !! @param q_prim_vf Primitive variables - !! @param bc_type Boundary condition types + !> Writes grid and initial condition data files to the "0" time-step directory in the local processor rank folder + !! @param q_cons_vf Conservative variables + !! @param q_prim_vf Primitive variables + !! @param bc_type Boundary condition types impure subroutine s_write_serial_data_files(q_cons_vf, q_prim_vf, bc_type) - type(scalar_field), & - dimension(sys_size), & - intent(inout) :: q_cons_vf, q_prim_vf - - ! BC types - type(integer_field), & - dimension(1:num_dims, -1:1), & - intent(in) :: bc_type - - logical :: file_exist !< checks if file exists - - character(LEN=15) :: FMT - character(LEN=3) :: status - - character(LEN= & - int(floor(log10(real(sys_size, wp)))) + 1) :: file_num !< Used to store - !! the number, in character form, of the currently - !! manipulated conservative variable data file - character(LEN=len_trim(t_step_dir) + name_len) :: file_loc !< - !! Generic string used to store the address of a particular file + type(scalar_field), dimension(sys_size), intent(inout) :: q_cons_vf, q_prim_vf - integer :: i, j, k, l, r, c !< Generic loop iterator + ! BC types + type(integer_field), dimension(1:num_dims,-1:1), intent(in) :: bc_type + logical :: file_exist !< checks if file exists + character(LEN=15) :: FMT + character(LEN=3) :: status + + !> Used to store the number, in character form, of the currently manipulated conservative variable data file + character(LEN=int(floor(log10(real(sys_size, wp)))) + 1) :: file_num + character(LEN=len_trim(t_step_dir) + name_len) :: file_loc !< Generic string used to store the address of a particular file + integer :: i, j, k, l, r, c !< Generic loop iterator integer :: t_step - - real(wp), dimension(nb) :: nRtmp !< Temporary bubble concentration - real(wp) :: nbub !< Temporary bubble number density - real(wp) :: gamma, lit_gamma, pi_inf, qv !< Temporary EOS params - real(wp) :: rho !< Temporary density - real(wp) :: pres, T !< Temporary pressure - - real(wp) :: rhoYks(1:num_species) !< Temporary species mass fractions - + real(wp), dimension(nb) :: nRtmp !< Temporary bubble concentration + real(wp) :: nbub !< Temporary bubble number density + real(wp) :: gamma, lit_gamma, pi_inf, qv !< Temporary EOS params + real(wp) :: rho !< Temporary density + real(wp) :: pres, T !< Temporary pressure + real(wp) :: rhoYks(1:num_species) !< Temporary species mass fractions real(wp) :: pres_mag pres_mag = 0._wp @@ -139,25 +104,23 @@ contains end if ! x-coordinate direction - file_loc = trim(t_step_dir)//'/x_cb.dat' - open (1, FILE=trim(file_loc), FORM='unformatted', STATUS=status) + file_loc = trim(t_step_dir) // '/x_cb.dat' + open (1, FILE=trim(file_loc), form='unformatted', STATUS=status) write (1) x_cb(-1:m) close (1) ! y- and z-coordinate directions if (n > 0) then ! y-coordinate direction - file_loc = trim(t_step_dir)//'/y_cb.dat' - open (1, FILE=trim(file_loc), FORM='unformatted', & - STATUS=status) + file_loc = trim(t_step_dir) // '/y_cb.dat' + open (1, FILE=trim(file_loc), form='unformatted', STATUS=status) write (1) y_cb(-1:n) close (1) ! z-coordinate direction if (p > 0) then - file_loc = trim(t_step_dir)//'/z_cb.dat' - open (1, FILE=trim(file_loc), FORM='unformatted', & - STATUS=status) + file_loc = trim(t_step_dir) // '/z_cb.dat' + open (1, FILE=trim(file_loc), form='unformatted', STATUS=status) write (1) z_cb(-1:p) close (1) end if @@ -166,24 +129,20 @@ contains ! Outputting Conservative Variables do i = 1, sys_size write (file_num, '(I0)') i - file_loc = trim(t_step_dir)//'/q_cons_vf'//trim(file_num) & - //'.dat' - open (1, FILE=trim(file_loc), FORM='unformatted', & - STATUS=status) - write (1) q_cons_vf(i)%sf(0:m, 0:n, 0:p) + file_loc = trim(t_step_dir) // '/q_cons_vf' // trim(file_num) // '.dat' + open (1, FILE=trim(file_loc), form='unformatted', STATUS=status) + write (1) q_cons_vf(i)%sf(0:m,0:n,0:p) close (1) end do - !Outputting pb and mv for non-polytropic qbmm + ! Outputting pb and mv for non-polytropic qbmm if (qbmm .and. .not. polytropic) then do i = 1, nb do r = 1, nnode write (file_num, '(I0)') r + (i - 1)*nnode + sys_size - file_loc = trim(t_step_dir)//'/pb'//trim(file_num) & - //'.dat' - open (1, FILE=trim(file_loc), FORM='unformatted', & - STATUS=status) - write (1) pb%sf(:, :, :, r, i) + file_loc = trim(t_step_dir) // '/pb' // trim(file_num) // '.dat' + open (1, FILE=trim(file_loc), form='unformatted', STATUS=status) + write (1) pb%sf(:,:,:,r, i) close (1) end do end do @@ -191,11 +150,9 @@ contains do i = 1, nb do r = 1, nnode write (file_num, '(I0)') r + (i - 1)*nnode + sys_size - file_loc = trim(t_step_dir)//'/mv'//trim(file_num) & - //'.dat' - open (1, FILE=trim(file_loc), FORM='unformatted', & - STATUS=status) - write (1) mv%sf(:, :, :, r, i) + file_loc = trim(t_step_dir) // '/mv' // trim(file_num) // '.dat' + open (1, FILE=trim(file_loc), form='unformatted', STATUS=status) + write (1) mv%sf(:,:,:,r, i) close (1) end do end do @@ -212,8 +169,8 @@ contains FMT = "(2F40.14)" end if - write (t_step_dir, '(A,I0,A,I0)') trim(case_dir)//'/D' - file_loc = trim(t_step_dir)//'/.' + write (t_step_dir, '(A,I0,A,I0)') trim(case_dir) // '/D' + file_loc = trim(t_step_dir) // '/.' inquire (FILE=trim(file_loc), EXIST=file_exist) @@ -221,15 +178,14 @@ contains if (cfl_dt) t_step = n_start - !1D + ! 1D if (n == 0 .and. p == 0) then if (model_eqns == 2) then do i = 1, sys_size - write (file_loc, '(A,I0,A,I2.2,A,I6.6,A)') trim(t_step_dir)//'/prim.', i, '.', proc_rank, '.', t_step, '.dat' + write (file_loc, '(A,I0,A,I2.2,A,I6.6,A)') trim(t_step_dir) // '/prim.', i, '.', proc_rank, '.', t_step, '.dat' open (2, FILE=trim(file_loc)) do j = 0, m - if (chemistry) then do c = 1, num_species rhoYks(c) = q_cons_vf(chemxb + c - 1)%sf(j, 0, 0) @@ -242,40 +198,34 @@ contains if ((i >= chemxb) .and. (i <= chemxe)) then write (2, FMT) x_cb(j), q_cons_vf(i)%sf(j, 0, 0)/rho - else if (((i >= cont_idx%beg) .and. (i <= cont_idx%end)) & - .or. & - ((i >= adv_idx%beg) .and. (i <= adv_idx%end)) & - .or. & - ((i >= chemxb) .and. (i <= chemxe)) & - ) then + else if (((i >= cont_idx%beg) .and. (i <= cont_idx%end)) .or. ((i >= adv_idx%beg) .and. (i <= adv_idx%end) & + & ) .or. ((i >= chemxb) .and. (i <= chemxe))) then write (2, FMT) x_cb(j), q_cons_vf(i)%sf(j, 0, 0) - else if (i == mom_idx%beg) then !u + else if (i == mom_idx%beg) then ! u write (2, FMT) x_cb(j), q_cons_vf(mom_idx%beg)%sf(j, 0, 0)/rho - else if (i == stress_idx%beg) then !tau_e + else if (i == stress_idx%beg) then ! tau_e write (2, FMT) x_cb(j), q_cons_vf(stress_idx%beg)%sf(j, 0, 0)/rho - else if (i == E_idx) then !p + else if (i == E_idx) then ! p if (mhd) then - pres_mag = 0.5_wp*(Bx0**2 + q_cons_vf(B_idx%beg)%sf(j, 0, 0)**2 + q_cons_vf(B_idx%beg + 1)%sf(j, 0, 0)**2) + pres_mag = 0.5_wp*(Bx0**2 + q_cons_vf(B_idx%beg)%sf(j, 0, 0)**2 + q_cons_vf(B_idx%beg + 1)%sf(j, & + & 0, 0)**2) end if - call s_compute_pressure( & - q_cons_vf(E_idx)%sf(j, 0, 0), & - q_cons_vf(alf_idx)%sf(j, 0, 0), & - 0.5_wp*(q_cons_vf(mom_idx%beg)%sf(j, 0, 0)**2._wp)/rho, & - pi_inf, gamma, rho, qv, rhoYks, pres, T, pres_mag=pres_mag) + call s_compute_pressure(q_cons_vf(E_idx)%sf(j, 0, 0), q_cons_vf(alf_idx)%sf(j, 0, 0), & + & 0.5_wp*(q_cons_vf(mom_idx%beg)%sf(j, 0, 0)**2._wp)/rho, pi_inf, gamma, rho, & + & qv, rhoYks, pres, T, pres_mag=pres_mag) write (2, FMT) x_cb(j), pres else if (mhd) then - if (i == mom_idx%beg + 1) then ! v + if (i == mom_idx%beg + 1) then ! v write (2, FMT) x_cb(j), q_cons_vf(mom_idx%beg + 1)%sf(j, 0, 0)/rho - else if (i == mom_idx%beg + 2) then ! w + else if (i == mom_idx%beg + 2) then ! w write (2, FMT) x_cb(j), q_cons_vf(mom_idx%beg + 2)%sf(j, 0, 0)/rho - else if (i == B_idx%beg) then ! By + else if (i == B_idx%beg) then ! By write (2, FMT) x_cb(j), q_cons_vf(B_idx%beg)%sf(j, 0, 0)/rho - else if (i == B_idx%beg + 1) then ! Bz + else if (i == B_idx%beg + 1) then ! Bz write (2, FMT) x_cb(j), q_cons_vf(B_idx%beg + 1)%sf(j, 0, 0)/rho end if else if ((i >= bub_idx%beg) .and. (i <= bub_idx%end) .and. bubbles_euler) then - if (qbmm) then nbub = q_cons_vf(bubxb)%sf(j, 0, 0) else @@ -301,7 +251,7 @@ contains end if do i = 1, sys_size - write (file_loc, '(A,I0,A,I2.2,A,I6.6,A)') trim(t_step_dir)//'/cons.', i, '.', proc_rank, '.', t_step, '.dat' + write (file_loc, '(A,I0,A,I2.2,A,I6.6,A)') trim(t_step_dir) // '/cons.', i, '.', proc_rank, '.', t_step, '.dat' open (2, FILE=trim(file_loc)) do j = 0, m @@ -313,7 +263,8 @@ contains if (qbmm .and. .not. polytropic) then do i = 1, nb do r = 1, nnode - write (file_loc, '(A,I0,A,I0,A,I2.2,A,I6.6,A)') trim(t_step_dir)//'/pres.', i, '.', r, '.', proc_rank, '.', t_step, '.dat' + write (file_loc, '(A,I0,A,I0,A,I2.2,A,I6.6,A)') trim(t_step_dir) // '/pres.', i, '.', r, '.', proc_rank, & + & '.', t_step, '.dat' open (2, FILE=trim(file_loc)) do j = 0, m @@ -324,7 +275,8 @@ contains end do do i = 1, nb do r = 1, nnode - write (file_loc, '(A,I0,A,I0,A,I2.2,A,I6.6,A)') trim(t_step_dir)//'/mv.', i, '.', r, '.', proc_rank, '.', t_step, '.dat' + write (file_loc, '(A,I0,A,I0,A,I2.2,A,I6.6,A)') trim(t_step_dir) // '/mv.', i, '.', r, '.', proc_rank, & + & '.', t_step, '.dat' open (2, FILE=trim(file_loc)) do j = 0, m @@ -345,7 +297,7 @@ contains ! 2D if ((n > 0) .and. (p == 0)) then do i = 1, sys_size - write (file_loc, '(A,I0,A,I2.2,A,I6.6,A)') trim(t_step_dir)//'/cons.', i, '.', proc_rank, '.', t_step, '.dat' + write (file_loc, '(A,I0,A,I2.2,A,I6.6,A)') trim(t_step_dir) // '/cons.', i, '.', proc_rank, '.', t_step, '.dat' open (2, FILE=trim(file_loc)) do j = 0, m do k = 0, n @@ -359,7 +311,8 @@ contains if (qbmm .and. .not. polytropic) then do i = 1, nb do r = 1, nnode - write (file_loc, '(A,I0,A,I0,A,I2.2,A,I6.6,A)') trim(t_step_dir)//'/pres.', i, '.', r, '.', proc_rank, '.', t_step, '.dat' + write (file_loc, '(A,I0,A,I0,A,I2.2,A,I6.6,A)') trim(t_step_dir) // '/pres.', i, '.', r, '.', proc_rank, & + & '.', t_step, '.dat' open (2, FILE=trim(file_loc)) do j = 0, m @@ -372,7 +325,8 @@ contains end do do i = 1, nb do r = 1, nnode - write (file_loc, '(A,I0,A,I0,A,I2.2,A,I6.6,A)') trim(t_step_dir)//'/mv.', i, '.', r, '.', proc_rank, '.', t_step, '.dat' + write (file_loc, '(A,I0,A,I0,A,I2.2,A,I6.6,A)') trim(t_step_dir) // '/mv.', i, '.', r, '.', proc_rank, & + & '.', t_step, '.dat' open (2, FILE=trim(file_loc)) do j = 0, m @@ -395,7 +349,7 @@ contains ! 3D if (p > 0) then do i = 1, sys_size - write (file_loc, '(A,I0,A,I2.2,A,I6.6,A)') trim(t_step_dir)//'/cons.', i, '.', proc_rank, '.', t_step, '.dat' + write (file_loc, '(A,I0,A,I2.2,A,I6.6,A)') trim(t_step_dir) // '/cons.', i, '.', proc_rank, '.', t_step, '.dat' open (2, FILE=trim(file_loc)) do j = 0, m do k = 0, n @@ -412,7 +366,8 @@ contains if (qbmm .and. .not. polytropic) then do i = 1, nb do r = 1, nnode - write (file_loc, '(A,I0,A,I0,A,I2.2,A,I6.6,A)') trim(t_step_dir)//'/pres.', i, '.', r, '.', proc_rank, '.', t_step, '.dat' + write (file_loc, '(A,I0,A,I0,A,I2.2,A,I6.6,A)') trim(t_step_dir) // '/pres.', i, '.', r, '.', proc_rank, & + & '.', t_step, '.dat' open (2, FILE=trim(file_loc)) do j = 0, m @@ -427,7 +382,8 @@ contains end do do i = 1, nb do r = 1, nnode - write (file_loc, '(A,I0,A,I0,A,I2.2,A,I6.6,A)') trim(t_step_dir)//'/mv.', i, '.', r, '.', proc_rank, '.', t_step, '.dat' + write (file_loc, '(A,I0,A,I0,A,I2.2,A,I6.6,A)') trim(t_step_dir) // '/mv.', i, '.', r, '.', proc_rank, & + & '.', t_step, '.dat' open (2, FILE=trim(file_loc)) do j = 0, m @@ -445,43 +401,35 @@ contains end subroutine s_write_serial_data_files - !> Writes grid and initial condition data files in parallel to the "0" - !! time-step directory in the local processor rank folder - !! @param q_cons_vf Conservative variables - !! @param q_prim_vf Primitive variables - !! @param bc_type Boundary condition types + !> Writes grid and initial condition data files in parallel to the "0" time-step directory in the local processor rank folder + !! @param q_cons_vf Conservative variables + !! @param q_prim_vf Primitive variables + !! @param bc_type Boundary condition types impure subroutine s_write_parallel_data_files(q_cons_vf, q_prim_vf, bc_type) ! Conservative variables - type(scalar_field), & - dimension(sys_size), & - intent(inout) :: q_cons_vf, q_prim_vf - - type(integer_field), & - dimension(1:num_dims, -1:1), & - intent(in) :: bc_type + type(scalar_field), dimension(sys_size), intent(inout) :: q_cons_vf, q_prim_vf + type(integer_field), dimension(1:num_dims,-1:1), intent(in) :: bc_type #ifdef MFC_MPI - - integer :: ifile, ierr, data_size - integer, dimension(MPI_STATUS_SIZE) :: status - integer(KIND=MPI_OFFSET_KIND) :: disp - integer(KIND=MPI_OFFSET_KIND) :: m_MOK, n_MOK, p_MOK - integer(KIND=MPI_OFFSET_KIND) :: WP_MOK, var_MOK, str_MOK - integer(KIND=MPI_OFFSET_KIND) :: NVARS_MOK - integer(KIND=MPI_OFFSET_KIND) :: MOK - + integer :: ifile, ierr, data_size + integer, dimension(MPI_STATUS_SIZE) :: status + integer(KIND=MPI_OFFSET_KIND) :: disp + integer(KIND=MPI_OFFSET_KIND) :: m_MOK, n_MOK, p_MOK + integer(KIND=MPI_OFFSET_KIND) :: WP_MOK, var_MOK, str_MOK + integer(KIND=MPI_OFFSET_KIND) :: NVARS_MOK + integer(KIND=MPI_OFFSET_KIND) :: MOK character(LEN=path_len + 2*name_len) :: file_loc - logical :: file_exist, dir_check + logical :: file_exist, dir_check ! Generic loop iterators - integer :: i, j, k, l + integer :: i, j, k, l real(wp) :: loc_violations, glb_violations ! Downsample variables integer :: m_ds, n_ds, p_ds integer :: m_glb_ds, n_glb_ds, p_glb_ds - integer :: m_glb_save, n_glb_save, p_glb_save ! Size of array being saved + integer :: m_glb_save, n_glb_save, p_glb_save ! Size of array being saved loc_violations = 0._wp @@ -491,17 +439,17 @@ contains end if call s_mpi_allreduce_sum(loc_violations, glb_violations) if (proc_rank == 0 .and. nint(glb_violations) > 0) then - print *, "WARNING: Attempting to downsample data but there are"// & - "processors with local problem sizes that are not divisible by 3." + print *, & + & "WARNING: Attempting to downsample data but there are" & + & // "processors with local problem sizes that are not divisible by 3." end if call s_populate_variables_buffers(bc_type, q_cons_vf) - call s_downsample_data(q_cons_vf, q_cons_temp, & - m_ds, n_ds, p_ds, m_glb_ds, n_glb_ds, p_glb_ds) + call s_downsample_data(q_cons_vf, q_cons_temp, m_ds, n_ds, p_ds, m_glb_ds, n_glb_ds, p_glb_ds) end if if (file_per_process) then if (proc_rank == 0) then - file_loc = trim(case_dir)//'/restart_data/lustre_0' + file_loc = trim(case_dir) // '/restart_data/lustre_0' call my_inquire(file_loc, dir_check) if (dir_check .neqv. .true.) then call s_create_directory(trim(file_loc)) @@ -524,14 +472,13 @@ contains else write (file_loc, '(I0,A,i7.7,A)') t_step_start, '_', proc_rank, '.dat' end if - file_loc = trim(restart_dir)//'/lustre_0'//trim(mpiiofs)//trim(file_loc) + file_loc = trim(restart_dir) // '/lustre_0' // trim(mpiiofs) // trim(file_loc) inquire (FILE=trim(file_loc), EXIST=file_exist) if (file_exist .and. proc_rank == 0) then call MPI_FILE_DELETE(file_loc, mpi_info_int, ierr) end if if (file_exist) call MPI_FILE_DELETE(file_loc, mpi_info_int, ierr) - call MPI_FILE_OPEN(MPI_COMM_SELF, file_loc, ior(MPI_MODE_WRONLY, MPI_MODE_CREATE), & - mpi_info_int, ifile, ierr) + call MPI_FILE_OPEN(MPI_COMM_SELF, file_loc, ior(MPI_MODE_WRONLY, MPI_MODE_CREATE), mpi_info_int, ifile, ierr) if (down_sample) then ! Size of local arrays @@ -558,19 +505,17 @@ contains ! Write the data for each variable if (bubbles_euler) then - do i = 1, sys_size! adv_idx%end + do i = 1, sys_size ! adv_idx%end var_MOK = int(i, MPI_OFFSET_KIND) - call MPI_FILE_WRITE_ALL(ifile, MPI_IO_DATA%var(i)%sf, data_size*mpi_io_type, & - mpi_io_p, status, ierr) + call MPI_FILE_WRITE_ALL(ifile, MPI_IO_DATA%var(i)%sf, data_size*mpi_io_type, mpi_io_p, status, ierr) end do - !Additional variables pb and mv for non-polytropic qbmm + ! Additional variables pb and mv for non-polytropic qbmm if (qbmm .and. .not. polytropic) then do i = sys_size + 1, sys_size + 2*nb*nnode var_MOK = int(i, MPI_OFFSET_KIND) - call MPI_FILE_WRITE_ALL(ifile, MPI_IO_DATA%var(i)%sf, data_size*mpi_io_type, & - mpi_io_p, status, ierr) + call MPI_FILE_WRITE_ALL(ifile, MPI_IO_DATA%var(i)%sf, data_size*mpi_io_type, mpi_io_p, status, ierr) end do end if else @@ -578,21 +523,18 @@ contains do i = 1, sys_size var_MOK = int(i, MPI_OFFSET_KIND) - call MPI_FILE_WRITE_ALL(ifile, q_cons_temp(i)%sf, data_size*mpi_io_type, & - mpi_io_p, status, ierr) + call MPI_FILE_WRITE_ALL(ifile, q_cons_temp(i)%sf, data_size*mpi_io_type, mpi_io_p, status, ierr) end do else do i = 1, sys_size var_MOK = int(i, MPI_OFFSET_KIND) - call MPI_FILE_WRITE_ALL(ifile, MPI_IO_DATA%var(i)%sf, data_size*mpi_io_type, & - mpi_io_p, status, ierr) + call MPI_FILE_WRITE_ALL(ifile, MPI_IO_DATA%var(i)%sf, data_size*mpi_io_type, mpi_io_p, status, ierr) end do end if end if call MPI_FILE_CLOSE(ifile, ierr) - else call s_initialize_mpi_data(q_cons_vf) @@ -602,13 +544,12 @@ contains else write (file_loc, '(I0,A)') t_step_start, '.dat' end if - file_loc = trim(restart_dir)//trim(mpiiofs)//trim(file_loc) + file_loc = trim(restart_dir) // trim(mpiiofs) // trim(file_loc) inquire (FILE=trim(file_loc), EXIST=file_exist) if (file_exist .and. proc_rank == 0) then call MPI_FILE_DELETE(file_loc, mpi_info_int, ierr) end if - call MPI_FILE_OPEN(MPI_COMM_WORLD, file_loc, ior(MPI_MODE_WRONLY, MPI_MODE_CREATE), & - mpi_info_int, ifile, ierr) + call MPI_FILE_OPEN(MPI_COMM_WORLD, file_loc, ior(MPI_MODE_WRONLY, MPI_MODE_CREATE), mpi_info_int, ifile, ierr) ! Size of local arrays data_size = (m + 1)*(n + 1)*(p + 1) @@ -624,18 +565,16 @@ contains ! Write the data for each variable if (bubbles_euler) then - do i = 1, sys_size! adv_idx%end + do i = 1, sys_size ! adv_idx%end var_MOK = int(i, MPI_OFFSET_KIND) ! Initial displacement to skip at beginning of file disp = m_MOK*max(MOK, n_MOK)*max(MOK, p_MOK)*WP_MOK*(var_MOK - 1) - call MPI_FILE_SET_VIEW(ifile, disp, mpi_io_p, MPI_IO_DATA%view(i), & - 'native', mpi_info_int, ierr) - call MPI_FILE_WRITE_ALL(ifile, MPI_IO_DATA%var(i)%sf, data_size*mpi_io_type, & - mpi_io_p, status, ierr) + call MPI_FILE_SET_VIEW(ifile, disp, mpi_io_p, MPI_IO_DATA%view(i), 'native', mpi_info_int, ierr) + call MPI_FILE_WRITE_ALL(ifile, MPI_IO_DATA%var(i)%sf, data_size*mpi_io_type, mpi_io_p, status, ierr) end do - !Additional variables pb and mv for non-polytropic qbmm + ! Additional variables pb and mv for non-polytropic qbmm if (qbmm .and. .not. polytropic) then do i = sys_size + 1, sys_size + 2*nb*nnode var_MOK = int(i, MPI_OFFSET_KIND) @@ -643,26 +582,21 @@ contains ! Initial displacement to skip at beginning of file disp = m_MOK*max(MOK, n_MOK)*max(MOK, p_MOK)*WP_MOK*(var_MOK - 1) - call MPI_FILE_SET_VIEW(ifile, disp, mpi_io_p, MPI_IO_DATA%view(i), & - 'native', mpi_info_int, ierr) - call MPI_FILE_WRITE_ALL(ifile, MPI_IO_DATA%var(i)%sf, data_size*mpi_io_type, & - mpi_io_p, status, ierr) + call MPI_FILE_SET_VIEW(ifile, disp, mpi_io_p, MPI_IO_DATA%view(i), 'native', mpi_info_int, ierr) + call MPI_FILE_WRITE_ALL(ifile, MPI_IO_DATA%var(i)%sf, data_size*mpi_io_type, mpi_io_p, status, ierr) end do end if else - do i = 1, sys_size !TODO: check if this is right + do i = 1, sys_size ! TODO: check if this is right ! do i = 1, adv_idx%end var_MOK = int(i, MPI_OFFSET_KIND) ! Initial displacement to skip at beginning of file disp = m_MOK*max(MOK, n_MOK)*max(MOK, p_MOK)*WP_MOK*(var_MOK - 1) - call MPI_FILE_SET_VIEW(ifile, disp, mpi_io_p, MPI_IO_DATA%view(i), & - 'native', mpi_info_int, ierr) - call MPI_FILE_WRITE_ALL(ifile, MPI_IO_DATA%var(i)%sf, data_size*mpi_io_type, & - mpi_io_p, status, ierr) + call MPI_FILE_SET_VIEW(ifile, disp, mpi_io_p, MPI_IO_DATA%view(i), 'native', mpi_info_int, ierr) + call MPI_FILE_WRITE_ALL(ifile, MPI_IO_DATA%var(i)%sf, data_size*mpi_io_type, mpi_io_p, status, ierr) end do - end if call MPI_FILE_CLOSE(ifile, ierr) @@ -679,50 +613,44 @@ contains end subroutine s_write_parallel_data_files - !> Computation of parameters, allocation procedures, and/or - !! any other tasks needed to properly setup the module + !> Computation of parameters, allocation procedures, and/or any other tasks needed to properly setup the module impure subroutine s_initialize_data_output_module + ! Generic string used to store the address of a particular file character(LEN=len_trim(case_dir) + 2*name_len) :: file_loc - character(len=15) :: temp - character(LEN=1), dimension(3), parameter :: coord = (/'x', 'y', 'z'/) + character(len=15) :: temp + character(LEN=1), dimension(3), parameter :: coord = (/'x', 'y', 'z'/) ! Generic logical used to check the existence of directories logical :: dir_check integer :: i - - integer :: m_ds, n_ds, p_ds !< down sample dimensions + integer :: m_ds, n_ds, p_ds !< down sample dimensions if (parallel_io .neqv. .true.) then ! Setting the address of the time-step directory write (t_step_dir, '(A,I0,A)') '/p_all/p', proc_rank, '/0' - t_step_dir = trim(case_dir)//trim(t_step_dir) + t_step_dir = trim(case_dir) // trim(t_step_dir) - ! Checking the existence of the time-step directory, removing it, if - ! it exists, and creating a new copy. Note that if preexisting grid - ! and/or initial condition data are to be read in from the very same - ! location, then the above described steps are not executed here but - ! rather in the module m_start_up.f90. + ! Checking the existence of the time-step directory, removing it, if it exists, and creating a new copy. Note that if + ! preexisting grid and/or initial condition data are to be read in from the very same location, then the above described + ! steps are not executed here but rather in the module m_start_up.f90. if (old_grid .neqv. .true.) then - - file_loc = trim(t_step_dir)//'/' + file_loc = trim(t_step_dir) // '/' call my_inquire(file_loc, dir_check) if (dir_check) call s_delete_directory(trim(t_step_dir)) call s_create_directory(trim(t_step_dir)) - end if s_write_data_files => s_write_serial_data_files else write (restart_dir, '(A)') '/restart_data' - restart_dir = trim(case_dir)//trim(restart_dir) + restart_dir = trim(case_dir) // trim(restart_dir) if ((old_grid .neqv. .true.) .and. (proc_rank == 0)) then - - file_loc = trim(restart_dir)//'/' + file_loc = trim(restart_dir) // '/' call my_inquire(file_loc, dir_check) if (dir_check) call s_delete_directory(trim(restart_dir)) @@ -732,7 +660,6 @@ contains call s_mpi_barrier() s_write_data_files => s_write_parallel_data_files - end if open (1, FILE='indices.dat', STATUS='unknown') @@ -744,21 +671,23 @@ contains write (1, '(A)') " " do i = contxb, contxe write (temp, '(I0)') i - contxb + 1 - write (1, '(I3,A20,A20)') i, "\alpha_{"//trim(temp)//"} \rho_{"//trim(temp)//"}", "\alpha_{"//trim(temp)//"} \rho" + write (1, '(I3,A20,A20)') i, "\alpha_{" // trim(temp) // "} \rho_{" // trim(temp) // "}", & + & "\alpha_{" // trim(temp) // "} \rho" end do do i = momxb, momxe - write (1, '(I3,A20,A20)') i, "\rho u_"//coord(i - momxb + 1), "u_"//coord(i - momxb + 1) + write (1, '(I3,A20,A20)') i, "\rho u_" // coord(i - momxb + 1), "u_" // coord(i - momxb + 1) end do do i = E_idx, E_idx write (1, '(I3,A20,A20)') i, "\rho U", "p" end do do i = advxb, advxe write (temp, '(I0)') i - contxb + 1 - write (1, '(I3,A20,A20)') i, "\alpha_{"//trim(temp)//"}", "\alpha_{"//trim(temp)//"}" + write (1, '(I3,A20,A20)') i, "\alpha_{" // trim(temp) // "}", "\alpha_{" // trim(temp) // "}" end do if (chemistry) then do i = 1, num_species - write (1, '(I3,A20,A20)') chemxb + i - 1, "Y_{"//trim(species_names(i))//"} \rho", "Y_{"//trim(species_names(i))//"}" + write (1, '(I3,A20,A20)') chemxb + i - 1, "Y_{" // trim(species_names(i)) // "} \rho", & + & "Y_{" // trim(species_names(i)) // "}" end do end if @@ -781,7 +710,7 @@ contains allocate (q_cons_temp(1:sys_size)) do i = 1, sys_size - allocate (q_cons_temp(i)%sf(-1:m_ds + 1, -1:n_ds + 1, -1:p_ds + 1)) + allocate (q_cons_temp(i)%sf(-1:m_ds + 1,-1:n_ds + 1,-1:p_ds + 1)) end do end if diff --git a/src/pre_process/m_global_parameters.fpp b/src/pre_process/m_global_parameters.fpp index 93a49e8d63..e934edded8 100644 --- a/src/pre_process/m_global_parameters.fpp +++ b/src/pre_process/m_global_parameters.fpp @@ -8,261 +8,214 @@ module m_global_parameters #ifdef MFC_MPI - use mpi ! Message passing interface (MPI) module + use mpi ! Message passing interface (MPI) module #endif - use m_derived_types ! Definitions of the derived types - - use m_helper_basic ! Functions to compare floating point numbers - + use m_derived_types ! Definitions of the derived types + use m_helper_basic ! Functions to compare floating point numbers use m_thermochem, only: num_species implicit none ! Logistics - integer :: num_procs !< Number of processors - character(LEN=path_len) :: case_dir !< Case folder location - logical :: old_grid !< Use existing grid data - logical :: old_ic, non_axis_sym !< Use existing IC data - integer :: t_step_old, t_step_start !< Existing IC/grid folder - - logical :: cfl_adap_dt, cfl_const_dt, cfl_dt - integer :: n_start, n_start_old + integer :: num_procs !< Number of processors + character(LEN=path_len) :: case_dir !< Case folder location + logical :: old_grid !< Use existing grid data + logical :: old_ic, non_axis_sym !< Use existing IC data + integer :: t_step_old, t_step_start !< Existing IC/grid folder + logical :: cfl_adap_dt, cfl_const_dt, cfl_dt + integer :: n_start, n_start_old ! Computational Domain Parameters - integer :: proc_rank !< Rank of the local processor - - !! Number of cells in the x-, y- and z-coordinate directions + integer :: proc_rank !< Rank of the local processor Number of cells in the x-, y- and z-coordinate directions integer :: m integer :: n integer :: p !> @name Max and min number of cells in a direction of each combination of x-,y-, and z- type(cell_num_bounds) :: cells_bounds - - integer(kind=8) :: nGlobal !< Global number of cells in the domain - - integer :: m_glb, n_glb, p_glb !< Global number of cells in each direction - - integer :: num_dims !< Number of spatial dimensions - integer :: num_vels !< Number of velocity components (different from num_dims for mhd) - - logical :: cyl_coord - integer :: grid_geometry !< Cylindrical coordinates (either axisymmetric or full 3D) - - real(wp), allocatable, dimension(:) :: x_cc, y_cc, z_cc !< - !! Locations of cell-centers (cc) in x-, y- and z-directions, respectively - - real(wp), allocatable, dimension(:) :: x_cb, y_cb, z_cb !< - !! Locations of cell-boundaries (cb) in x-, y- and z-directions, respectively - - real(wp) :: dx, dy, dz !< - !! Minimum cell-widths in the x-, y- and z-coordinate directions - - type(bounds_info) :: x_domain, y_domain, z_domain !< - !! Locations of the domain bounds in the x-, y- and z-coordinate directions - - logical :: stretch_x, stretch_y, stretch_z !< - !! Grid stretching flags for the x-, y- and z-coordinate directions - - ! Parameters of the grid stretching function for the x-, y- and z-coordinate - ! directions. The "a" parameters are a measure of the rate at which the grid - ! is stretched while the remaining parameters are indicative of the location - ! on the grid at which the stretching begins. + integer(kind=8) :: nGlobal !< Global number of cells in the domain + integer :: m_glb, n_glb, p_glb !< Global number of cells in each direction + integer :: num_dims !< Number of spatial dimensions + integer :: num_vels !< Number of velocity components (different from num_dims for mhd) + logical :: cyl_coord + integer :: grid_geometry !< Cylindrical coordinates (either axisymmetric or full 3D) + + !> Locations of cell-centers (cc) in x-, y- and z-directions, respectively + real(wp), allocatable, dimension(:) :: x_cc, y_cc, z_cc + + !> Locations of cell-boundaries (cb) in x-, y- and z-directions, respectively + real(wp), allocatable, dimension(:) :: x_cb, y_cb, z_cb + real(wp) :: dx, dy, dz !< Minimum cell-widths in the x-, y- and z-coordinate directions + type(bounds_info) :: x_domain, y_domain, z_domain !< Locations of the domain bounds in the x-, y- and z-coordinate directions + logical :: stretch_x, stretch_y, stretch_z !< Grid stretching flags for the x-, y- and z-coordinate directions + + ! Parameters of the grid stretching function for the x-, y- and z-coordinate directions. The "a" parameters are a measure of the + ! rate at which the grid is stretched while the remaining parameters are indicative of the location on the grid at which the + ! stretching begins. real(wp) :: a_x, a_y, a_z - integer :: loops_x, loops_y, loops_z + integer :: loops_x, loops_y, loops_z real(wp) :: x_a, y_a, z_a real(wp) :: x_b, y_b, z_b ! Simulation Algorithm Parameters - integer :: model_eqns !< Multicomponent flow model - logical :: relax !< activate phase change - integer :: relax_model !< Relax Model - real(wp) :: palpha_eps !< trigger parameter for the p relaxation procedure, phase change model - real(wp) :: ptgalpha_eps !< trigger parameter for the pTg relaxation procedure, phase change model - integer :: num_fluids !< Number of different fluids present in the flow - logical :: mpp_lim !< Alpha limiter - integer :: sys_size !< Number of unknowns in the system of equations - integer :: recon_type !< Reconstruction Type - integer :: weno_polyn !< Degree of the WENO polynomials (polyn) - integer :: muscl_polyn !< Degree of the MUSCL polynomials (polyn) - integer :: weno_order !< Order of accuracy for the WENO reconstruction - integer :: muscl_order !< Order of accuracy for the MUSCL reconstruction - logical :: hypoelasticity !< activate hypoelasticity - logical :: hyperelasticity !< activate hyperelasticity - logical :: elasticity !< elasticity modeling, true for hyper or hypo - logical :: mhd !< Magnetohydrodynamics - logical :: relativity !< Relativity for RMHD - integer :: b_size !< Number of components in the b tensor - integer :: tensor_size !< Number of components in the nonsymmetric tensor - logical :: pre_stress !< activate pre_stressed domain - logical :: cont_damage !< continuum damage modeling - logical :: hyper_cleaning !< Hyperbolic cleaning for MHD - logical :: igr !< Use information geometric regularization - integer :: igr_order !< IGR reconstruction order - logical, parameter :: chemistry = .${chemistry}$. !< Chemistry modeling + integer :: model_eqns !< Multicomponent flow model + logical :: relax !< activate phase change + integer :: relax_model !< Relax Model + real(wp) :: palpha_eps !< trigger parameter for the p relaxation procedure, phase change model + real(wp) :: ptgalpha_eps !< trigger parameter for the pTg relaxation procedure, phase change model + integer :: num_fluids !< Number of different fluids present in the flow + logical :: mpp_lim !< Alpha limiter + integer :: sys_size !< Number of unknowns in the system of equations + integer :: recon_type !< Reconstruction Type + integer :: weno_polyn !< Degree of the WENO polynomials (polyn) + integer :: muscl_polyn !< Degree of the MUSCL polynomials (polyn) + integer :: weno_order !< Order of accuracy for the WENO reconstruction + integer :: muscl_order !< Order of accuracy for the MUSCL reconstruction + logical :: hypoelasticity !< activate hypoelasticity + logical :: hyperelasticity !< activate hyperelasticity + logical :: elasticity !< elasticity modeling, true for hyper or hypo + logical :: mhd !< Magnetohydrodynamics + logical :: relativity !< Relativity for RMHD + integer :: b_size !< Number of components in the b tensor + integer :: tensor_size !< Number of components in the nonsymmetric tensor + logical :: pre_stress !< activate pre_stressed domain + logical :: cont_damage !< continuum damage modeling + logical :: hyper_cleaning !< Hyperbolic cleaning for MHD + logical :: igr !< Use information geometric regularization + integer :: igr_order !< IGR reconstruction order + logical, parameter :: chemistry = .${chemistry}$. !< Chemistry modeling ! Annotations of the structure, i.e. the organization, of the state vectors type(int_bounds_info) :: cont_idx !< Indexes of first & last continuity eqns. type(int_bounds_info) :: mom_idx !< Indexes of first & last momentum eqns. - integer :: E_idx !< Index of total energy equation - integer :: alf_idx !< Index of void fraction - integer :: n_idx !< Index of number density + integer :: E_idx !< Index of total energy equation + integer :: alf_idx !< Index of void fraction + integer :: n_idx !< Index of number density type(int_bounds_info) :: adv_idx !< Indexes of first & last advection eqns. type(int_bounds_info) :: internalEnergies_idx !< Indexes of first & last internal energy eqns. type(bub_bounds_info) :: bub_idx !< Indexes of first & last bubble variable eqns. - integer :: gamma_idx !< Index of specific heat ratio func. eqn. - integer :: pi_inf_idx !< Index of liquid stiffness func. eqn. + integer :: gamma_idx !< Index of specific heat ratio func. eqn. + integer :: pi_inf_idx !< Index of liquid stiffness func. eqn. type(int_bounds_info) :: B_idx !< Indexes of first and last magnetic field eqns. type(int_bounds_info) :: stress_idx !< Indexes of elastic shear stress eqns. type(int_bounds_info) :: xi_idx !< Indexes of first and last reference map eqns. - integer :: c_idx !< Index of the color function + integer :: c_idx !< Index of the color function type(int_bounds_info) :: species_idx !< Indexes of first & last concentration eqns. - integer :: damage_idx !< Index of damage state variable (D) for continuum damage model - integer :: psi_idx !< Index of hyperbolic cleaning state variable for MHD + integer :: damage_idx !< Index of damage state variable (D) for continuum damage model + integer :: psi_idx !< Index of hyperbolic cleaning state variable for MHD - ! Cell Indices for the (local) interior points (O-m, O-n, 0-p). - ! Stands for "InDices With BUFFer". + ! Cell Indices for the (local) interior points (O-m, O-n, 0-p). Stands for "InDices With BUFFer". type(int_bounds_info) :: idwint(1:3) - ! Cell Indices for the entire (local) domain. In simulation and post_process, - ! this includes the buffer region. idwbuff and idwint are the same otherwise. - ! Stands for "InDices With BUFFer". + ! Cell Indices for the entire (local) domain. In simulation and post_process, this includes the buffer region. idwbuff and + ! idwint are the same otherwise. Stands for "InDices With BUFFer". type(int_bounds_info) :: idwbuff(1:3) - integer :: fd_order !< - !! The order of the finite-difference (fd) approximations of the first-order - !! derivatives that need to be evaluated when the CoM or flow probe data - !! files are to be written at each time step + !> The order of the finite-difference (fd) approximations of the first-order derivatives that need to be evaluated when the CoM + !! or flow probe data files are to be written at each time step + integer :: fd_order - integer :: fd_number !< - !! The finite-difference number is given by MAX(1, fd_order/2). Essentially, - !! it is a measure of the half-size of the finite-difference stencil for the - !! selected order of accuracy. + !> The finite-difference number is given by MAX(1, fd_order/2). Essentially, it is a measure of the half-size of the + !! finite-difference stencil for the selected order of accuracy. + integer :: fd_number !> @name lagrangian subgrid bubble parameters !> @{! - type(bubbles_lagrange_parameters) :: lag_params !< Lagrange bubbles' parameters + type(bubbles_lagrange_parameters) :: lag_params !< Lagrange bubbles' parameters !> @} - type(int_bounds_info) :: bc_x, bc_y, bc_z !< - !! Boundary conditions in the x-, y- and z-coordinate directions - - integer :: shear_num !! Number of shear stress components - integer, dimension(3) :: shear_indices !< - !! Indices of the stress components that represent shear stress - integer :: shear_BC_flip_num !< - !! Number of shear stress components to reflect for boundary conditions - integer, dimension(3, 2) :: shear_BC_flip_indices !< - !! Indices of shear stress components to reflect for boundary conditions. - !! Size: (1:3, 1:shear_BC_flip_num) for (x/y/z, [indices]) - - logical :: parallel_io !< Format of the data files - logical :: file_per_process !< type of data output - integer :: precision !< Precision of output files - logical :: down_sample !< Down-sample the output data - - logical :: mixlayer_vel_profile !< Set hyperbolic tangent streamwise velocity profile - real(wp) :: mixlayer_vel_coef !< Coefficient for the hyperbolic tangent streamwise velocity profile - logical :: mixlayer_perturb !< Superimpose instability waves to surrounding fluid flow - integer :: mixlayer_perturb_nk !< Number of Fourier modes for perturbation with mixlayer_perturb flag - real(wp) :: mixlayer_perturb_k0 !< Peak wavenumber of prescribed energy spectra with mixlayer_perturb flag - !! Default value (k0 = 0.4446) is most unstable mode obtained from linear stability analysis - !! See Michalke (1964, JFM) for details - logical :: simplex_perturb + type(int_bounds_info) :: bc_x, bc_y, bc_z !< Boundary conditions in the x-, y- and z-coordinate directions + integer :: shear_num !! Number of shear stress components + integer, dimension(3) :: shear_indices !< Indices of the stress components that represent shear stress + integer :: shear_BC_flip_num !< Number of shear stress components to reflect for boundary conditions + !> Indices of shear stress components to reflect for boundary conditions. Size: (1:3, 1:shear_BC_flip_num) for (x/y/z, + !! [indices]) + integer, dimension(3, 2) :: shear_BC_flip_indices + logical :: parallel_io !< Format of the data files + logical :: file_per_process !< type of data output + integer :: precision !< Precision of output files + logical :: down_sample !< Down-sample the output data + logical :: mixlayer_vel_profile !< Set hyperbolic tangent streamwise velocity profile + real(wp) :: mixlayer_vel_coef !< Coefficient for the hyperbolic tangent streamwise velocity profile + logical :: mixlayer_perturb !< Superimpose instability waves to surrounding fluid flow + integer :: mixlayer_perturb_nk !< Number of Fourier modes for perturbation with mixlayer_perturb flag + !> Peak wavenumber of prescribed energy spectra with mixlayer_perturb flag Default value (k0 = 0.4446) is most unstable mode + !! obtained from linear stability analysis See Michalke (1964, JFM) for details + real(wp) :: mixlayer_perturb_k0 + logical :: simplex_perturb type(simplex_noise_params) :: simplex_params - - real(wp) :: pi_fac !< Factor for artificial pi_inf - - logical :: viscous - logical :: bubbles_lagrange + real(wp) :: pi_fac !< Factor for artificial pi_inf + logical :: viscous + logical :: bubbles_lagrange ! Perturb density of surrounding air so as to break symmetry of grid - logical :: perturb_flow - integer :: perturb_flow_fluid !< Fluid to be perturbed with perturb_flow flag - real(wp) :: perturb_flow_mag !< Magnitude of perturbation with perturb_flow flag - logical :: perturb_sph - integer :: perturb_sph_fluid !< Fluid to be perturbed with perturb_sph flag - real(wp), dimension(num_fluids_max) :: fluid_rho - - logical :: elliptic_smoothing - integer :: elliptic_smoothing_iters - - integer, allocatable, dimension(:) :: proc_coords !< - !! Processor coordinates in MPI_CART_COMM - - type(int_bounds_info), dimension(3) :: nidx - - integer, allocatable, dimension(:, :, :) :: neighbor_ranks + logical :: perturb_flow + integer :: perturb_flow_fluid !< Fluid to be perturbed with perturb_flow flag + real(wp) :: perturb_flow_mag !< Magnitude of perturbation with perturb_flow flag + logical :: perturb_sph + integer :: perturb_sph_fluid !< Fluid to be perturbed with perturb_sph flag + real(wp), dimension(num_fluids_max) :: fluid_rho + logical :: elliptic_smoothing + integer :: elliptic_smoothing_iters + integer, allocatable, dimension(:) :: proc_coords !< Processor coordinates in MPI_CART_COMM + type(int_bounds_info), dimension(3) :: nidx + integer, allocatable, dimension(:,:,:) :: neighbor_ranks !! Neighbor ranks - integer, allocatable, dimension(:) :: start_idx !< - !! Starting cell-center index of local processor in global grid + integer, allocatable, dimension(:) :: start_idx !< Starting cell-center index of local processor in global grid #ifdef MFC_MPI - type(mpi_io_var), public :: MPI_IO_DATA - - character(LEN=name_len) :: mpiiofs - integer :: mpi_info_int !< - !! MPI info for parallel IO with Lustre file systems - + character(LEN=name_len) :: mpiiofs + integer :: mpi_info_int !< MPI info for parallel IO with Lustre file systems #endif ! Initial Condition Parameters - integer :: num_patches !< Number of patches composing initial condition - - type(ic_patch_parameters), dimension(num_patches_max) :: patch_icpp !< - !! Database of the initial condition patch parameters (icpp) for each of the - !! patches employed in the configuration of the initial condition. Note that - !! the maximum allowable number of patches, num_patches_max, may be changed - !! in the module m_derived_types.f90. - - integer :: num_bc_patches !< Number of boundary condition patches - logical :: bc_io !< whether or not to save BC data + integer :: num_patches !< Number of patches composing initial condition + + !> Database of the initial condition patch parameters (icpp) for each of the patches employed in the configuration of the + !! initial condition. Note that the maximum allowable number of patches, num_patches_max, may be changed in the module + !! m_derived_types.f90. + type(ic_patch_parameters), dimension(num_patches_max) :: patch_icpp + integer :: num_bc_patches !< Number of boundary condition patches + logical :: bc_io !< whether or not to save BC data type(bc_patch_parameters), dimension(num_bc_patches_max) :: patch_bc - !! Database of the boundary condition patch parameters for each of the patches - !! employed in the configuration of the boundary conditions + !! Database of the boundary condition patch parameters for each of the patches employed in the configuration of the boundary + !! conditions ! Fluids Physical Parameters - type(physical_parameters), dimension(num_fluids_max) :: fluid_pp !< - !! Database of the physical parameters of each of the fluids that is present - !! in the flow. These include the stiffened gas equation of state parameters, - !! and the Reynolds numbers. + !> Database of the physical parameters of each of the fluids that is present in the flow. These include the stiffened gas + !! equation of state parameters, and the Reynolds numbers. + type(physical_parameters), dimension(num_fluids_max) :: fluid_pp ! Subgrid Bubble Parameters type(subgrid_bubble_physical_parameters) :: bub_pp - - real(wp) :: rhoref, pref !< Reference parameters for Tait EOS - - type(chemistry_parameters) :: chem_params + real(wp) :: rhoref, pref !< Reference parameters for Tait EOS + type(chemistry_parameters) :: chem_params !> @name Bubble modeling !> @{ - integer :: nb - real(wp) :: Ca, Web, Re_inv, Eu + integer :: nb + real(wp) :: Ca, Web, Re_inv, Eu real(wp), dimension(:), allocatable :: weight, R0 - logical :: bubbles_euler - logical :: qbmm !< Quadrature moment method - integer :: nmom !< Number of carried moments - real(wp) :: sigR, sigV, rhoRV !< standard deviations in R/V - logical :: adv_n !< Solve the number density equation and compute alpha from number density + logical :: bubbles_euler + logical :: qbmm !< Quadrature moment method + integer :: nmom !< Number of carried moments + real(wp) :: sigR, sigV, rhoRV !< standard deviations in R/V + logical :: adv_n !< Solve the number density equation and compute alpha from number density !> @} !> @name Immersed Boundaries !> @{ - logical :: ib !< Turn immersed boundaries on - integer :: num_ibs !< Number of immersed boundaries - integer :: Np - + logical :: ib !< Turn immersed boundaries on + integer :: num_ibs !< Number of immersed boundaries + integer :: Np type(ib_patch_parameters), dimension(num_patches_max) :: patch_ib - - type(vec3_dt), allocatable, dimension(:) :: airfoil_grid_u, airfoil_grid_l - !! Database of the immersed boundary patch parameters for each of the - !! patches employed in the configuration of the initial condition. Note that - !! the maximum allowable number of patches, num_patches_max, may be changed - !! in the module m_derived_types.f90. - + type(vec3_dt), allocatable, dimension(:) :: airfoil_grid_u, airfoil_grid_l + !! Database of the immersed boundary patch parameters for each of the patches employed in the configuration of the initial + !! condition. Note that the maximum allowable number of patches, num_patches_max, may be changed in the module + !! m_derived_types.f90. !> @} !> @name Non-polytropic bubble gas compression @@ -270,25 +223,19 @@ module m_global_parameters logical :: polytropic logical :: polydisperse real(wp) :: poly_sigma - integer :: dist_type !1 = binormal, 2 = lognormal-normal - - integer :: thermal !1 = adiabatic, 2 = isotherm, 3 = transfer - + integer :: dist_type ! 1 = binormal, 2 = lognormal-normal + integer :: thermal ! 1 = adiabatic, 2 = isotherm, 3 = transfer real(wp) :: phi_vg, phi_gv, Pe_c, Tw, k_vl, k_gl real(wp) :: gam_m - real(wp), dimension(:), allocatable :: pb0, mass_g0, mass_v0, Pe_T, k_v, k_g real(wp), dimension(:), allocatable :: Re_trans_T, Re_trans_c, Im_trans_T, Im_trans_c, omegaN - - real(wp) :: R0ref, p0ref, rho0ref, T0ref, ss, pv, vd, mu_l, mu_v, mu_g, & - gam_v, gam_g, M_v, M_g, cp_v, cp_g, R_v, R_g - + real(wp) :: R0ref, p0ref, rho0ref, T0ref, ss, pv, vd, mu_l, mu_v, mu_g, gam_v, gam_g, M_v, M_g, cp_v, cp_g, R_v, R_g !> @} !> @name Surface Tension Modeling !> @{ real(wp) :: sigma - logical :: surface_tension + logical :: surface_tension !> @} !> @name Index variables used for m_variables_conversion @@ -303,35 +250,33 @@ module m_global_parameters integer :: chemxb, chemxe !> @} - integer, allocatable, dimension(:, :, :) :: logic_grid - - type(pres_field) :: pb - type(pres_field) :: mv - - real(wp) :: Bx0 !< Constant magnetic field in the x-direction (1D) - - integer :: buff_size !< - !! The number of cells that are necessary to be able to store enough boundary - !! conditions data to march the solution in the physical computational domain - !! to the next time-step. + integer, allocatable, dimension(:,:,:) :: logic_grid + type(pres_field) :: pb + type(pres_field) :: mv + real(wp) :: Bx0 !< Constant magnetic field in the x-direction (1D) + !> The number of cells that are necessary to be able to store enough boundary conditions data to march the solution in the + !! physical computational domain to the next time-step. + integer :: buff_size logical :: fft_wrt - logical :: dummy !< AMDFlang workaround: keep a dummy logical to avoid a compiler case-optimization bug when a parameter+GPU-kernel conditional is false + !> AMDFlang workaround: keep a dummy logical to avoid a compiler case-optimization bug when a parameter+GPU-kernel conditional + !! is false + logical :: dummy ! Variables for hardcoded initial conditions that are read from input files character(LEN=2*path_len) :: interface_file - real(wp) :: normFac, normMag, g0_ic, p0_ic + real(wp) :: normFac, normMag, g0_ic, p0_ic contains - !> Assigns default values to user inputs prior to reading - !! them in. This allows for an easier consistency check of - !! these parameters once they are read from the input file. + !> Assigns default values to user inputs prior to reading them in. This allows for an easier consistency check of these + !! parameters once they are read from the input file. impure subroutine s_assign_default_values_to_user_inputs - integer :: i !< Generic loop operator + integer :: i !< Generic loop operator ! Logistics + case_dir = '.' old_grid = .false. old_ic = .false. @@ -437,11 +382,11 @@ contains simplex_params%perturb_vel(:) = .false. simplex_params%perturb_vel_freq(:) = dflt_real simplex_params%perturb_vel_scale(:) = dflt_real - simplex_params%perturb_vel_offset(:, :) = dflt_real + simplex_params%perturb_vel_offset(:,:) = dflt_real simplex_params%perturb_dens(:) = .false. simplex_params%perturb_dens_freq(:) = dflt_real simplex_params%perturb_dens_scale(:) = dflt_real - simplex_params%perturb_dens_offset(:, :) = dflt_real + simplex_params%perturb_dens_offset(:,:) = dflt_real ! Initial condition parameters num_patches = dflt_int @@ -516,9 +461,9 @@ contains patch_icpp(i)%modal_clip_r_to_min = .false. patch_icpp(i)%modal_r_min = 1.e-12_wp patch_icpp(i)%modal_use_exp_form = .false. - patch_icpp(i)%sph_har_coeff(:, :) = 0._wp + patch_icpp(i)%sph_har_coeff(:,:) = 0._wp - !should get all of r0's and v0's + ! should get all of r0's and v0's patch_icpp(i)%r0 = dflt_real patch_icpp(i)%v0 = dflt_real @@ -660,8 +605,8 @@ contains bub_pp%gam_g = dflt_real; gam_g = dflt_real bub_pp%M_v = dflt_real; M_v = dflt_real bub_pp%M_g = dflt_real; M_g = dflt_real - bub_pp%k_v = dflt_real; - bub_pp%k_g = dflt_real; + bub_pp%k_v = dflt_real + bub_pp%k_g = dflt_real bub_pp%cp_v = dflt_real; cp_v = dflt_real bub_pp%cp_g = dflt_real; cp_g = dflt_real bub_pp%R_v = dflt_real; R_v = dflt_real @@ -669,31 +614,27 @@ contains end subroutine s_assign_default_values_to_user_inputs - !> Computation of parameters, allocation procedures, and/or - !! any other tasks needed to properly setup the module + !> Computation of parameters, allocation procedures, and/or any other tasks needed to properly setup the module impure subroutine s_initialize_global_parameters_module integer :: i, j, fac if (recon_type == WENO_TYPE) then weno_polyn = (weno_order - 1)/2 - elseif (recon_type == MUSCL_TYPE) then + else if (recon_type == MUSCL_TYPE) then muscl_polyn = muscl_order end if - ! Determining the layout of the state vectors and overall size of - ! the system of equations, given the dimensionality and choice of - ! the equations of motion + ! Determining the layout of the state vectors and overall size of the system of equations, given the dimensionality and + ! choice of the equations of motion ! Gamma/Pi_inf Model if (model_eqns == 1) then - ! Setting number of fluids num_fluids = 1 - ! Annotating structure of the state and flux vectors belonging - ! to the system of equations defined by the selected number of - ! spatial dimensions and the gamma/pi_inf model + ! Annotating structure of the state and flux vectors belonging to the system of equations defined by the selected number + ! of spatial dimensions and the gamma/pi_inf model cont_idx%beg = 1 cont_idx%end = cont_idx%beg mom_idx%beg = cont_idx%end + 1 @@ -707,10 +648,8 @@ contains ! Volume Fraction Model (5-equation model) else if (model_eqns == 2) then - - ! Annotating structure of the state and flux vectors belonging - ! to the system of equations defined by the selected number of - ! spatial dimensions and the volume fraction model + ! Annotating structure of the state and flux vectors belonging to the system of equations defined by the selected number + ! of spatial dimensions and the volume fraction model cont_idx%beg = 1 cont_idx%end = num_fluids mom_idx%beg = cont_idx%end + 1 @@ -718,17 +657,14 @@ contains E_idx = mom_idx%end + 1 if (igr) then - ! Volume fractions are stored in the indices immediately following - ! the energy equation. IGR tracks a total of (N-1) volume fractions - ! for N fluids, hence the "-1" in adv_idx%end. If num_fluids = 1 - ! then adv_idx%end < adv_idx%beg, which skips all loops over the - ! volume fractions since there is no volume fraction to track + ! Volume fractions are stored in the indices immediately following the energy equation. IGR tracks a total of (N-1) + ! volume fractions for N fluids, hence the "-1" in adv_idx%end. If num_fluids = 1 then adv_idx%end < adv_idx%beg, + ! which skips all loops over the volume fractions since there is no volume fraction to track adv_idx%beg = E_idx + 1 adv_idx%end = E_idx + num_fluids - 1 else - ! Volume fractions are stored in the indices immediately following - ! the energy equation. WENO/MUSCL + Riemann tracks a total of (N) - ! volume fractions for N fluids, hence the lack of "-1" in adv_idx%end + ! Volume fractions are stored in the indices immediately following the energy equation. WENO/MUSCL + Riemann tracks + ! a total of (N) volume fractions for N fluids, hence the lack of "-1" in adv_idx%end adv_idx%beg = E_idx + 1 adv_idx%end = E_idx + num_fluids end if @@ -767,7 +703,7 @@ contains if (qbmm) then allocate (bub_idx%moms(nb, nmom)) - allocate (bub_idx%fullmom(nb, 0:nmom, 0:nmom)) + allocate (bub_idx%fullmom(nb,0:nmom,0:nmom)) do i = 1, nb do j = 1, nmom @@ -803,19 +739,17 @@ contains if (mhd) then B_idx%beg = sys_size + 1 if (n == 0) then - B_idx%end = sys_size + 2 ! 1D: By, Bz + B_idx%end = sys_size + 2 ! 1D: By, Bz else - B_idx%end = sys_size + 3 ! 2D/3D: Bx, By, Bz + B_idx%end = sys_size + 3 ! 2D/3D: Bx, By, Bz end if sys_size = B_idx%end end if ! Volume Fraction Model (6-equation model) else if (model_eqns == 3) then - - ! Annotating structure of the state and flux vectors belonging - ! to the system of equations defined by the selected number of - ! spatial dimensions and the volume fraction model + ! Annotating structure of the state and flux vectors belonging to the system of equations defined by the selected number + ! of spatial dimensions and the volume fraction model cont_idx%beg = 1 cont_idx%end = num_fluids mom_idx%beg = cont_idx%end + 1 @@ -826,18 +760,17 @@ contains internalEnergies_idx%beg = adv_idx%end + 1 internalEnergies_idx%end = adv_idx%end + num_fluids sys_size = internalEnergies_idx%end - else if (model_eqns == 4) then ! 4 equation model with subgrid bubbles_euler - cont_idx%beg = 1 ! one continuity equation - cont_idx%end = 1 ! num_fluids - mom_idx%beg = cont_idx%end + 1 ! one momentum equation in each direction + cont_idx%beg = 1 ! one continuity equation + cont_idx%end = 1 ! num_fluids + mom_idx%beg = cont_idx%end + 1 ! one momentum equation in each direction mom_idx%end = cont_idx%end + num_vels - E_idx = mom_idx%end + 1 ! one energy equation + E_idx = mom_idx%end + 1 ! one energy equation adv_idx%beg = E_idx + 1 - adv_idx%end = adv_idx%beg !one volume advection equation + adv_idx%end = adv_idx%beg ! one volume advection equation alf_idx = adv_idx%end - sys_size = alf_idx !adv_idx%end + sys_size = alf_idx ! adv_idx%end if (bubbles_euler) then bub_idx%beg = sys_size + 1 @@ -878,12 +811,10 @@ contains rhoref = 1._wp pref = 1._wp end if - end if end if if (model_eqns == 2 .or. model_eqns == 3) then - if (hypoelasticity .or. hyperelasticity) then elasticity = .true. stress_idx%beg = sys_size + 1 @@ -899,18 +830,16 @@ contains shear_num = 1 shear_indices(1) = stress_idx%beg - 1 + 2 shear_BC_flip_num = 1 - shear_BC_flip_indices(1:2, 1) = shear_indices(1) + shear_BC_flip_indices(1:2,1) = shear_indices(1) ! Both x-dir and y-dir: flip tau_xy only else if (num_dims == 3) then shear_num = 3 shear_indices(1:3) = stress_idx%beg - 1 + (/2, 4, 5/) shear_BC_flip_num = 2 - shear_BC_flip_indices(1, 1:2) = shear_indices((/1, 2/)) - shear_BC_flip_indices(2, 1:2) = shear_indices((/1, 3/)) - shear_BC_flip_indices(3, 1:2) = shear_indices((/2, 3/)) - ! x-dir: flip tau_xy and tau_xz - ! y-dir: flip tau_xy and tau_yz - ! z-dir: flip tau_xz and tau_yz + shear_BC_flip_indices(1,1:2) = shear_indices((/1, 2/)) + shear_BC_flip_indices(2,1:2) = shear_indices((/1, 3/)) + shear_BC_flip_indices(3,1:2) = shear_indices((/2, 3/)) + ! x-dir: flip tau_xy and tau_xz y-dir: flip tau_xy and tau_yz z-dir: flip tau_xz and tau_yz end if end if @@ -938,7 +867,6 @@ contains psi_idx = sys_size + 1 sys_size = psi_idx end if - end if if (chemistry) then @@ -966,14 +894,10 @@ contains if (bubbles_lagrange) fd_number = max(1, fd_order/2) - call s_configure_coordinate_bounds(recon_type, weno_polyn, muscl_polyn, & - igr_order, buff_size, & - idwint, idwbuff, viscous, & - bubbles_lagrange, m, n, p, & - num_dims, igr, ib, fd_number) + call s_configure_coordinate_bounds(recon_type, weno_polyn, muscl_polyn, igr_order, buff_size, idwint, idwbuff, viscous, & + & bubbles_lagrange, m, n, p, num_dims, igr, ib, fd_number) #ifdef MFC_MPI - if (qbmm .and. .not. polytropic) then allocate (MPI_IO_DATA%view(1:sys_size + 2*nb*nnode)) allocate (MPI_IO_DATA%var(1:sys_size + 2*nb*nnode)) @@ -984,13 +908,13 @@ contains if (.not. down_sample) then do i = 1, sys_size - allocate (MPI_IO_DATA%var(i)%sf(0:m, 0:n, 0:p)) + allocate (MPI_IO_DATA%var(i)%sf(0:m,0:n,0:p)) MPI_IO_DATA%var(i)%sf => null() end do end if if (qbmm .and. .not. polytropic) then do i = sys_size + 1, sys_size + 2*nb*nnode - allocate (MPI_IO_DATA%var(i)%sf(0:m, 0:n, 0:p)) + allocate (MPI_IO_DATA%var(i)%sf(0:m,0:n,0:p)) MPI_IO_DATA%var(i)%sf => null() end do end if @@ -1006,16 +930,16 @@ contains end if end if - if (cyl_coord .neqv. .true.) then ! Cartesian grid + if (cyl_coord .neqv. .true.) then ! Cartesian grid grid_geometry = 1 - elseif (cyl_coord .and. p == 0) then ! Axisymmetric cylindrical grid + else if (cyl_coord .and. p == 0) then ! Axisymmetric cylindrical grid grid_geometry = 2 - else ! Fully 3D cylindrical grid + else ! Fully 3D cylindrical grid grid_geometry = 3 end if if (.not. igr) then - allocate (logic_grid(0:m, 0:n, 0:p)) + allocate (logic_grid(0:m,0:n,0:p)) end if end subroutine s_initialize_global_parameters_module @@ -1024,7 +948,7 @@ contains impure subroutine s_initialize_parallel_io #ifdef MFC_MPI - integer :: ierr !< Generic flag used to identify and report MPI errors + integer :: ierr !< Generic flag used to identify and report MPI errors #endif num_dims = 1 + min(1, n) + min(1, p) @@ -1040,20 +964,16 @@ contains if (parallel_io .neqv. .true.) return #ifdef MFC_MPI - ! Option for Lustre file system (Darter/Comet/Stampede) write (mpiiofs, '(A)') '/lustre_' mpiiofs = trim(mpiiofs) call MPI_INFO_CREATE(mpi_info_int, ierr) call MPI_INFO_SET(mpi_info_int, 'romio_ds_write', 'disable', ierr) - ! Option for UNIX file system (Hooke/Thomson) - ! WRITE(mpiiofs, '(A)') '/ufs_' - ! mpiiofs = TRIM(mpiiofs) - ! mpi_info_int = MPI_INFO_NULL + ! Option for UNIX file system (Hooke/Thomson) WRITE(mpiiofs, '(A)') '/ufs_' mpiiofs = TRIM(mpiiofs) mpi_info_int = + ! MPI_INFO_NULL allocate (start_idx(1:num_dims)) - #endif end subroutine s_initialize_parallel_io @@ -1064,6 +984,7 @@ contains integer :: i ! Deallocating grid variables for the x-direction + deallocate (x_cc, x_cb) ! Deallocating grid variables for the y- and z-directions if (n > 0) then @@ -1076,7 +997,6 @@ contains deallocate (proc_coords) #ifdef MFC_MPI - if (parallel_io) then deallocate (start_idx) do i = 1, sys_size @@ -1086,7 +1006,6 @@ contains deallocate (MPI_IO_DATA%var) deallocate (MPI_IO_DATA%view) end if - #endif if (allocated(neighbor_ranks)) deallocate (neighbor_ranks) diff --git a/src/pre_process/m_grid.f90 b/src/pre_process/m_grid.f90 index 6ea71bd592..47968251bf 100644 --- a/src/pre_process/m_grid.f90 +++ b/src/pre_process/m_grid.f90 @@ -5,26 +5,19 @@ !> @brief Generates uniform or stretched rectilinear grids with hyperbolic-tangent spacing module m_grid - use m_derived_types ! Definitions of the derived types - - use m_global_parameters ! Global parameters for the code - - use m_mpi_proxy ! Message passing interface (MPI) module proxy - - use m_helper_basic !< Functions to compare floating point numbers + use m_derived_types ! Definitions of the derived types + use m_global_parameters ! Global parameters for the code + use m_mpi_proxy ! Message passing interface (MPI) module proxy + use m_helper_basic !< Functions to compare floating point numbers #ifdef MFC_MPI - use mpi ! Message passing interface (MPI) module + use mpi ! Message passing interface (MPI) module #endif implicit none - private; - public :: s_initialize_grid_module, & - s_generate_grid, & - s_generate_serial_grid, & - s_generate_parallel_grid, & - s_finalize_grid_module + private + public :: s_initialize_grid_module, s_generate_grid, s_generate_serial_grid, s_generate_parallel_grid, s_finalize_grid_module abstract interface @@ -32,25 +25,23 @@ module m_grid impure subroutine s_generate_abstract_grid end subroutine s_generate_abstract_grid - end interface procedure(s_generate_abstract_grid), pointer :: s_generate_grid => null() contains - !> The following subroutine generates either a uniform or - !! non-uniform rectilinear grid in serial, defined by the parameters - !! inputted by the user. The grid information is stored in - !! the grid variables containing coordinates of the cell- - !! centers and cell-boundaries. + !> The following subroutine generates either a uniform or non-uniform rectilinear grid in serial, defined by the parameters + !! inputted by the user. The grid information is stored in the grid variables containing coordinates of the cell- centers and + !! cell-boundaries. impure subroutine s_generate_serial_grid ! Generic loop iterator - integer :: i, j !< generic loop operators - real(wp) :: length !< domain lengths + integer :: i, j !< generic loop operators + real(wp) :: length !< domain lengths ! Grid Generation in the x-direction + dx = (x_domain%end - x_domain%beg)/real(m + 1, wp) do i = 0, m @@ -61,7 +52,6 @@ impure subroutine s_generate_serial_grid x_cb(m) = x_domain%end if (stretch_x) then - length = abs(x_cb(m) - x_cb(-1)) x_cb = x_cb/length x_a = x_a/length @@ -69,10 +59,8 @@ impure subroutine s_generate_serial_grid do j = 1, loops_x do i = -1, m - x_cb(i) = x_cb(i)/a_x* & - (a_x + log(cosh(a_x*(x_cb(i) - x_a))) & - + log(cosh(a_x*(x_cb(i) - x_b))) & - - 2._wp*log(cosh(a_x*(x_b - x_a)/2._wp))) + x_cb(i) = x_cb(i)/a_x*(a_x + log(cosh(a_x*(x_cb(i) - x_a))) + log(cosh(a_x*(x_cb(i) - x_b))) & + & - 2._wp*log(cosh(a_x*(x_b - x_a)/2._wp))) end do end do x_cb = x_cb*length @@ -82,15 +70,13 @@ impure subroutine s_generate_serial_grid dx = minval(x_cb(0:m) - x_cb(-1:m - 1)) print *, 'Stretched grid: min/max x grid: ', minval(x_cc(:)), maxval(x_cc(:)) if (num_procs > 1) call s_mpi_reduce_min(dx) - end if ! Grid Generation in the y-direction if (n == 0) return if (grid_geometry == 2 .and. f_approx_equal(y_domain%beg, 0.0_wp)) then - !IF (grid_geometry == 2) THEN - + ! IF (grid_geometry == 2) THEN dy = (y_domain%end - y_domain%beg)/real(2*n + 1, wp) y_cc(0) = y_domain%beg + 5.e-1_wp*dy @@ -100,22 +86,18 @@ impure subroutine s_generate_serial_grid y_cc(i) = y_domain%beg + 2._wp*dy*real(i, wp) y_cb(i - 1) = y_domain%beg + dy*real(2*i - 1, wp) end do - else - dy = (y_domain%end - y_domain%beg)/real(n + 1, wp) do i = 0, n y_cc(i) = y_domain%beg + 5.e-1_wp*dy*real(2*i + 1, wp) y_cb(i - 1) = y_domain%beg + dy*real(i, wp) end do - end if y_cb(n) = y_domain%end if (stretch_y) then - length = abs(y_cb(n) - y_cb(-1)) y_cb = y_cb/length y_a = y_a/length @@ -123,10 +105,8 @@ impure subroutine s_generate_serial_grid do j = 1, loops_y do i = -1, n - y_cb(i) = y_cb(i)/a_y* & - (a_y + log(cosh(a_y*(y_cb(i) - y_a))) & - + log(cosh(a_y*(y_cb(i) - y_b))) & - - 2._wp*log(cosh(a_y*(y_b - y_a)/2._wp))) + y_cb(i) = y_cb(i)/a_y*(a_y + log(cosh(a_y*(y_cb(i) - y_a))) + log(cosh(a_y*(y_cb(i) - y_b))) & + & - 2._wp*log(cosh(a_y*(y_b - y_a)/2._wp))) end do end do @@ -136,7 +116,6 @@ impure subroutine s_generate_serial_grid dy = minval(y_cb(0:n) - y_cb(-1:n - 1)) if (num_procs > 1) call s_mpi_reduce_min(dy) - end if ! Grid Generation in the z-direction @@ -152,7 +131,6 @@ impure subroutine s_generate_serial_grid z_cb(p) = z_domain%end if (stretch_z) then - length = abs(z_cb(p) - z_cb(-1)) z_cb = z_cb/length z_a = z_a/length @@ -160,10 +138,8 @@ impure subroutine s_generate_serial_grid do j = 1, loops_z do i = -1, p - z_cb(i) = z_cb(i)/a_z* & - (a_z + log(cosh(a_z*(z_cb(i) - z_a))) & - + log(cosh(a_z*(z_cb(i) - z_b))) & - - 2._wp*log(cosh(a_z*(z_b - z_a)/2._wp))) + z_cb(i) = z_cb(i)/a_z*(a_z + log(cosh(a_z*(z_cb(i) - z_a))) + log(cosh(a_z*(z_cb(i) - z_b))) & + & - 2._wp*log(cosh(a_z*(z_b - z_a)/2._wp))) end do end do @@ -173,33 +149,24 @@ impure subroutine s_generate_serial_grid dz = minval(z_cb(0:p) - z_cb(-1:p - 1)) if (num_procs > 1) call s_mpi_reduce_min(dz) - end if end subroutine s_generate_serial_grid - !> The following subroutine generates either a uniform or - !! non-uniform rectilinear grid in parallel, defined by the parameters - !! inputted by the user. The grid information is stored in - !! the grid variables containing coordinates of the cell- - !! centers and cell-boundaries. + !> The following subroutine generates either a uniform or non-uniform rectilinear grid in parallel, defined by the parameters + !! inputted by the user. The grid information is stored in the grid variables containing coordinates of the cell- centers and + !! cell-boundaries. impure subroutine s_generate_parallel_grid #ifdef MFC_MPI - - real(wp) :: length !< domain lengths + real(wp) :: length !< domain lengths ! Locations of cell boundaries - real(wp), allocatable, dimension(:) :: x_cb_glb, y_cb_glb, z_cb_glb !< - !! Locations of cell boundaries - - character(LEN=path_len + name_len) :: file_loc !< - !! Generic string used to store the address of a file - - integer :: ifile, ierr, data_size + real(wp), allocatable, dimension(:) :: x_cb_glb, y_cb_glb, z_cb_glb !< Locations of cell boundaries + character(LEN=path_len + name_len) :: file_loc !< Generic string used to store the address of a file + integer :: ifile, ierr, data_size integer, dimension(MPI_STATUS_SIZE) :: status - - integer :: i, j !< Generic loop integers + integer :: i, j !< Generic loop integers allocate (x_cb_glb(-1:m_glb)) allocate (y_cb_glb(-1:n_glb)) @@ -221,20 +188,16 @@ impure subroutine s_generate_parallel_grid do j = 1, loops_x do i = -1, m_glb - x_cb_glb(i) = x_cb_glb(i)/a_x* & - (a_x + log(cosh(a_x*(x_cb_glb(i) - x_a))) & - + log(cosh(a_x*(x_cb_glb(i) - x_b))) & - - 2._wp*log(cosh(a_x*(x_b - x_a)/2._wp))) + x_cb_glb(i) = x_cb_glb(i)/a_x*(a_x + log(cosh(a_x*(x_cb_glb(i) - x_a))) + log(cosh(a_x*(x_cb_glb(i) - x_b))) & + & - 2._wp*log(cosh(a_x*(x_b - x_a)/2._wp))) end do end do x_cb_glb = x_cb_glb*length - end if ! Grid generation in the y-direction if (n_glb > 0) then - if (grid_geometry == 2 .and. f_approx_equal(y_domain%beg, 0.0_wp)) then dy = (y_domain%end - y_domain%beg)/real(2*n_glb + 1, wp) y_cb_glb(-1) = y_domain%beg @@ -258,15 +221,12 @@ impure subroutine s_generate_parallel_grid do j = 1, loops_y do i = -1, n_glb - y_cb_glb(i) = y_cb_glb(i)/a_y* & - (a_y + log(cosh(a_y*(y_cb_glb(i) - y_a))) & - + log(cosh(a_y*(y_cb_glb(i) - y_b))) & - - 2._wp*log(cosh(a_y*(y_b - y_a)/2._wp))) + y_cb_glb(i) = y_cb_glb(i)/a_y*(a_y + log(cosh(a_y*(y_cb_glb(i) - y_a))) + log(cosh(a_y*(y_cb_glb(i) - y_b) & + & )) - 2._wp*log(cosh(a_y*(y_b - y_a)/2._wp))) end do end do y_cb_glb = y_cb_glb*length - end if ! Grid generation in the z-direction @@ -285,53 +245,45 @@ impure subroutine s_generate_parallel_grid do j = 1, loops_z do i = -1, p_glb - z_cb_glb(i) = z_cb_glb(i)/a_z* & - (a_z + log(cosh(a_z*(z_cb_glb(i) - z_a))) & - + log(cosh(a_z*(z_cb_glb(i) - z_b))) & - - 2._wp*log(cosh(a_z*(z_b - z_a)/2._wp))) + z_cb_glb(i) = z_cb_glb(i)/a_z*(a_z + log(cosh(a_z*(z_cb_glb(i) - z_a))) + log(cosh(a_z*(z_cb_glb(i) & + & - z_b))) - 2._wp*log(cosh(a_z*(z_b - z_a)/2._wp))) end do end do z_cb_glb = z_cb_glb*length - end if end if end if ! Write cell boundary locations to grid data files - file_loc = trim(case_dir)//'/restart_data'//trim(mpiiofs)//'x_cb.dat' + file_loc = trim(case_dir) // '/restart_data' // trim(mpiiofs) // 'x_cb.dat' data_size = m_glb + 2 - call MPI_FILE_OPEN(MPI_COMM_SELF, file_loc, ior(MPI_MODE_WRONLY, MPI_MODE_CREATE), & - mpi_info_int, ifile, ierr) + call MPI_FILE_OPEN(MPI_COMM_SELF, file_loc, ior(MPI_MODE_WRONLY, MPI_MODE_CREATE), mpi_info_int, ifile, ierr) call MPI_FILE_WRITE(ifile, x_cb_glb, data_size, mpi_p, status, ierr) call MPI_FILE_CLOSE(ifile, ierr) if (n > 0) then - file_loc = trim(case_dir)//'/restart_data'//trim(mpiiofs)//'y_cb.dat' + file_loc = trim(case_dir) // '/restart_data' // trim(mpiiofs) // 'y_cb.dat' data_size = n_glb + 2 - call MPI_FILE_OPEN(MPI_COMM_SELF, file_loc, ior(MPI_MODE_WRONLY, MPI_MODE_CREATE), & - mpi_info_int, ifile, ierr) + call MPI_FILE_OPEN(MPI_COMM_SELF, file_loc, ior(MPI_MODE_WRONLY, MPI_MODE_CREATE), mpi_info_int, ifile, ierr) call MPI_FILE_WRITE(ifile, y_cb_glb, data_size, mpi_p, status, ierr) call MPI_FILE_CLOSE(ifile, ierr) if (p > 0) then - file_loc = trim(case_dir)//'/restart_data'//trim(mpiiofs)//'z_cb.dat' + file_loc = trim(case_dir) // '/restart_data' // trim(mpiiofs) // 'z_cb.dat' data_size = p_glb + 2 - call MPI_FILE_OPEN(MPI_COMM_SELF, file_loc, ior(MPI_MODE_WRONLY, MPI_MODE_CREATE), & - mpi_info_int, ifile, ierr) + call MPI_FILE_OPEN(MPI_COMM_SELF, file_loc, ior(MPI_MODE_WRONLY, MPI_MODE_CREATE), mpi_info_int, ifile, ierr) call MPI_FILE_WRITE(ifile, z_cb_glb, data_size, mpi_p, status, ierr) call MPI_FILE_CLOSE(ifile, ierr) end if end if deallocate (x_cb_glb, y_cb_glb, z_cb_glb) - #endif end subroutine s_generate_parallel_grid - !> Computation of parameters, allocation procedures, and/or - !! any other tasks needed to properly setup the module + !> Computation of parameters, allocation procedures, and/or any other tasks needed to properly setup the module impure subroutine s_initialize_grid_module if (parallel_io .neqv. .true.) then diff --git a/src/pre_process/m_icpp_patches.fpp b/src/pre_process/m_icpp_patches.fpp index 25a88f36f9..2c40594f11 100644 --- a/src/pre_process/m_icpp_patches.fpp +++ b/src/pre_process/m_icpp_patches.fpp @@ -12,24 +12,15 @@ !> @brief Constructs initial condition patch geometries (lines, circles, rectangles, spheres, etc.) on the grid module m_icpp_patches - use m_model ! Subroutine(s) related to STL files - - use m_derived_types ! Definitions of the derived types - - use m_global_parameters !< Definitions of the global parameters - + use m_model ! Subroutine(s) related to STL files + use m_derived_types ! Definitions of the derived types + use m_global_parameters !< Definitions of the global parameters use m_constants, only: max_2d_fourier_modes, max_sph_harm_degree, small_radius - - use m_helper_basic !< Functions to compare floating point numbers - + use m_helper_basic !< Functions to compare floating point numbers use m_helper - use m_mpi_common - use m_assign_variables - use m_mpi_common - use m_variables_conversion implicit none @@ -38,32 +29,25 @@ module m_icpp_patches real(wp) :: x_centroid, y_centroid, z_centroid real(wp) :: length_x, length_y, length_z - - integer :: smooth_patch_id - real(wp) :: smooth_coeff !< - !! These variables are analogous in both meaning and use to the similarly - !! named components in the ic_patch_parameters type (see m_derived_types.f90 - !! for additional details). They are employed as a means to more concisely - !! perform the actions necessary to lay out a particular patch on the grid. - - real(wp) :: eta !< - !! In the case that smoothing of patch boundaries is enabled and the boundary - !! between two adjacent patches is to be smeared out, this variable's purpose - !! is to act as a pseudo volume fraction to indicate the contribution of each - !! patch toward the composition of a cell's fluid state. - + integer :: smooth_patch_id + !> These variables are analogous in both meaning and use to the similarly named components in the ic_patch_parameters type (see + !! m_derived_types.f90 for additional details). They are employed as a means to more concisely perform the actions necessary to + !! lay out a particular patch on the grid. + real(wp) :: smooth_coeff + + !> In the case that smoothing of patch boundaries is enabled and the boundary between two adjacent patches is to be smeared out, + !! this variable's purpose is to act as a pseudo volume fraction to indicate the contribution of each patch toward the + !! composition of a cell's fluid state. + real(wp) :: eta real(wp) :: cart_x, cart_y, cart_z - real(wp) :: sph_phi !< - !! Variables to be used to hold cell locations in Cartesian coordinates if - !! 3D simulation is using cylindrical coordinates - - type(bounds_info) :: x_boundary, y_boundary, z_boundary !< - !! These variables combine the centroid and length parameters associated with - !! a particular patch to yield the locations of the patch boundaries in the - !! x-, y- and z-coordinate directions. They are used as a means to concisely - !! perform the actions necessary to lay out a particular patch on the grid. + !> Variables to be used to hold cell locations in Cartesian coordinates if 3D simulation is using cylindrical coordinates + real(wp) :: sph_phi - character(len=5) :: istr ! string to store int to string result for error checking + !> These variables combine the centroid and length parameters associated with a particular patch to yield the locations of the + !! patch boundaries in the x-, y- and z-coordinate directions. They are used as a means to concisely perform the actions + !! necessary to lay out a particular patch on the grid. + type(bounds_info) :: x_boundary, y_boundary, z_boundary + character(len=5) :: istr ! string to store int to string result for error checking contains @@ -71,18 +55,17 @@ contains impure subroutine s_apply_icpp_patches(patch_id_fp, q_prim_vf) type(scalar_field), dimension(1:sys_size), intent(inout) :: q_prim_vf + #ifdef MFC_MIXED_PRECISION - integer(kind=1), dimension(0:m, 0:n, 0:p), intent(inout) :: patch_id_fp + integer(kind=1), dimension(0:m,0:n,0:p), intent(inout) :: patch_id_fp #else - integer, dimension(0:m, 0:n, 0:p), intent(inout) :: patch_id_fp + integer, dimension(0:m,0:n,0:p), intent(inout) :: patch_id_fp #endif integer :: i ! 3D Patch Geometries if (p > 0) then - do i = 1, num_patches - if (proc_rank == 0) then print *, 'Processing patch', i end if @@ -93,35 +76,33 @@ contains if (patch_icpp(i)%geometry == 8) then call s_icpp_sphere(i, patch_id_fp, q_prim_vf) ! Cuboidal patch - elseif (patch_icpp(i)%geometry == 9) then + else if (patch_icpp(i)%geometry == 9) then call s_icpp_cuboid(i, patch_id_fp, q_prim_vf) ! Cylindrical patch - elseif (patch_icpp(i)%geometry == 10) then + else if (patch_icpp(i)%geometry == 10) then call s_icpp_cylinder(i, patch_id_fp, q_prim_vf) ! Swept plane patch - elseif (patch_icpp(i)%geometry == 11) then + else if (patch_icpp(i)%geometry == 11) then call s_icpp_sweep_plane(i, patch_id_fp, q_prim_vf) ! Ellipsoidal patch - elseif (patch_icpp(i)%geometry == 12) then + else if (patch_icpp(i)%geometry == 12) then call s_icpp_ellipsoid(i, patch_id_fp, q_prim_vf) ! 3D spherical harmonic patch - elseif (patch_icpp(i)%geometry == 14) then + else if (patch_icpp(i)%geometry == 14) then call s_icpp_3d_spherical_harmonic(i, patch_id_fp, q_prim_vf) ! 3D Modified circular patch - elseif (patch_icpp(i)%geometry == 19) then + else if (patch_icpp(i)%geometry == 19) then call s_icpp_3dvarcircle(i, patch_id_fp, q_prim_vf) ! 3D STL patch - elseif (patch_icpp(i)%geometry == 21) then + else if (patch_icpp(i)%geometry == 21) then call s_icpp_model(i, patch_id_fp, q_prim_vf) end if end do !> @} ! 2D Patch Geometries - elseif (n > 0) then - + else if (n > 0) then do i = 1, num_patches - if (proc_rank == 0) then print *, 'Processing patch', i end if @@ -132,32 +113,32 @@ contains if (patch_icpp(i)%geometry == 2) then call s_icpp_circle(i, patch_id_fp, q_prim_vf) ! Rectangular patch - elseif (patch_icpp(i)%geometry == 3) then + else if (patch_icpp(i)%geometry == 3) then call s_icpp_rectangle(i, patch_id_fp, q_prim_vf) ! Swept line patch - elseif (patch_icpp(i)%geometry == 4) then + else if (patch_icpp(i)%geometry == 4) then call s_icpp_sweep_line(i, patch_id_fp, q_prim_vf) ! Elliptical patch - elseif (patch_icpp(i)%geometry == 5) then + else if (patch_icpp(i)%geometry == 5) then call s_icpp_ellipse(i, patch_id_fp, q_prim_vf) ! Unimplemented patch (formerly isentropic vortex) - elseif (patch_icpp(i)%geometry == 6) then - call s_mpi_abort('This used to be the isentropic vortex patch, '// & - 'which no longer exists. See Examples. Exiting.') + else if (patch_icpp(i)%geometry == 6) then + call s_mpi_abort('This used to be the isentropic vortex patch, ' & + & // 'which no longer exists. See Examples. Exiting.') ! 2D modal (Fourier) patch - elseif (patch_icpp(i)%geometry == 13) then + else if (patch_icpp(i)%geometry == 13) then call s_icpp_2d_modal(i, patch_id_fp, q_prim_vf) ! Spiral patch - elseif (patch_icpp(i)%geometry == 17) then + else if (patch_icpp(i)%geometry == 17) then call s_icpp_spiral(i, patch_id_fp, q_prim_vf) ! Modified circular patch - elseif (patch_icpp(i)%geometry == 18) then + else if (patch_icpp(i)%geometry == 18) then call s_icpp_varcircle(i, patch_id_fp, q_prim_vf) ! TaylorGreen vortex patch - elseif (patch_icpp(i)%geometry == 20) then + else if (patch_icpp(i)%geometry == 20) then call s_icpp_2D_TaylorGreen_vortex(i, patch_id_fp, q_prim_vf) ! STL patch - elseif (patch_icpp(i)%geometry == 21) then + else if (patch_icpp(i)%geometry == 21) then call s_icpp_model(i, patch_id_fp, q_prim_vf) end if !> @} @@ -165,9 +146,7 @@ contains ! 1D Patch Geometries else - do i = 1, num_patches - if (proc_rank == 0) then print *, 'Processing patch', i end if @@ -176,31 +155,28 @@ contains if (patch_icpp(i)%geometry == 1) then call s_icpp_line_segment(i, patch_id_fp, q_prim_vf) ! 1d analytical - elseif (patch_icpp(i)%geometry == 16) then + else if (patch_icpp(i)%geometry == 16) then call s_icpp_1d_bubble_pulse(i, patch_id_fp, q_prim_vf) end if end do - end if end subroutine s_apply_icpp_patches - !> The line segment patch is a 1D geometry that may be used, - !! for example, in creating a Riemann problem. The geometry - !! of the patch is well-defined when its centroid and length - !! in the x-coordinate direction are provided. Note that the - !! line segment patch DOES NOT allow for the smearing of its - !! boundaries. + !> The line segment patch is a 1D geometry that may be used, for example, in creating a Riemann problem. The geometry of the + !! patch is well-defined when its centroid and length in the x-coordinate direction are provided. Note that the line segment + !! patch DOES NOT allow for the smearing of its boundaries. !! @param patch_id patch identifier !! @param patch_id_fp Array to track patch ids !! @param q_prim_vf Array of primitive variables subroutine s_icpp_line_segment(patch_id, patch_id_fp, q_prim_vf) integer, intent(in) :: patch_id + #ifdef MFC_MIXED_PRECISION - integer(kind=1), dimension(0:m, 0:n, 0:p), intent(inout) :: patch_id_fp + integer(kind=1), dimension(0:m,0:n,0:p), intent(inout) :: patch_id_fp #else - integer, dimension(0:m, 0:n, 0:p), intent(inout) :: patch_id_fp + integer, dimension(0:m,0:n,0:p), intent(inout) :: patch_id_fp #endif type(scalar_field), dimension(1:sys_size), intent(inout) :: q_prim_vf @@ -222,28 +198,21 @@ contains x_centroid = patch_icpp(patch_id)%x_centroid length_x = patch_icpp(patch_id)%length_x - ! Computing the beginning and end x-coordinates of the line segment - ! based on its centroid and length + ! Computing the beginning and end x-coordinates of the line segment based on its centroid and length x_boundary%beg = x_centroid - 0.5_wp*length_x x_boundary%end = x_centroid + 0.5_wp*length_x - ! Since the line segment patch does not allow for its boundaries to - ! be smoothed out, the pseudo volume fraction is set to 1 to ensure - ! that only the current patch contributes to the fluid state in the - ! cells that this patch covers. + ! Since the line segment patch does not allow for its boundaries to be smoothed out, the pseudo volume fraction is set to 1 + ! to ensure that only the current patch contributes to the fluid state in the cells that this patch covers. eta = 1._wp - ! Checking whether the line segment covers a particular cell in the - ! domain and verifying whether the current patch has the permission - ! to write to that cell. If both queries check out, the primitive - ! variables of the current patch are assigned to this cell. + ! Checking whether the line segment covers a particular cell in the domain and verifying whether the current patch has the + ! permission to write to that cell. If both queries check out, the primitive variables of the current patch are assigned to + ! this cell. do i = 0, m - if (x_boundary%beg <= x_cc(i) .and. & - x_boundary%end >= x_cc(i) .and. & - patch_icpp(patch_id)%alter_patch(patch_id_fp(i, 0, 0))) then - - call s_assign_patch_primitive_variables(patch_id, i, 0, 0, & - eta, q_prim_vf, patch_id_fp) + if (x_boundary%beg <= x_cc(i) .and. x_boundary%end >= x_cc(i) .and. patch_icpp(patch_id)%alter_patch(patch_id_fp(i, & + & 0, 0))) then + call s_assign_patch_primitive_variables(patch_id, i, 0, 0, eta, q_prim_vf, patch_id_fp) @:analytical() @@ -254,38 +223,34 @@ contains ! Updating the patch identities bookkeeping variable if (1._wp - eta < sgm_eps) patch_id_fp(i, 0, 0) = patch_id - end if end do @:HardcodedDellacation() end subroutine s_icpp_line_segment - !> The spiral patch is a 2D geometry that may be used, The geometry - !! of the patch is well-defined when its centroid and radius - !! are provided. Note that the circular patch DOES allow for - !! the smoothing of its boundary. - !! @param patch_id patch identifier - !! @param patch_id_fp Array to track patch ids - !! @param q_prim_vf Array of primitive variables + !> The spiral patch is a 2D geometry that may be used, The geometry of the patch is well-defined when its centroid and radius + !! are provided. Note that the circular patch DOES allow for the smoothing of its boundary. + !! @param patch_id patch identifier + !! @param patch_id_fp Array to track patch ids + !! @param q_prim_vf Array of primitive variables impure subroutine s_icpp_spiral(patch_id, patch_id_fp, q_prim_vf) integer, intent(in) :: patch_id + #ifdef MFC_MIXED_PRECISION - integer(kind=1), dimension(0:m, 0:n, 0:p), intent(inout) :: patch_id_fp + integer(kind=1), dimension(0:m,0:n,0:p), intent(inout) :: patch_id_fp #else - integer, dimension(0:m, 0:n, 0:p), intent(inout) :: patch_id_fp + integer, dimension(0:m,0:n,0:p), intent(inout) :: patch_id_fp #endif type(scalar_field), dimension(1:sys_size), intent(inout) :: q_prim_vf - - integer :: i, j, k !< Generic loop iterators - real(wp) :: th, thickness, nturns, mya - real(wp) :: spiral_x_min, spiral_x_max, spiral_y_min, spiral_y_max + integer :: i, j, k !< Generic loop iterators + real(wp) :: th, thickness, nturns, mya + real(wp) :: spiral_x_min, spiral_x_max, spiral_y_min, spiral_y_max @:HardcodedDimensionsExtrusion() @:Hardcoded2DVariables() - ! Transferring the circular patch's radius, centroid, smearing patch - ! identity and smearing coefficient information + ! Transferring the circular patch's radius, centroid, smearing patch identity and smearing coefficient information x_centroid = patch_icpp(patch_id)%x_centroid y_centroid = patch_icpp(patch_id)%y_centroid mya = patch_icpp(patch_id)%radius @@ -297,29 +262,24 @@ contains do k = 0, int(m*91*nturns) th = k/real(int(m*91._wp*nturns))*nturns*2._wp*pi - spiral_x_min = minval((/f_r(th, 0.0_wp, mya)*cos(th), & - f_r(th, thickness, mya)*cos(th)/)) - spiral_y_min = minval((/f_r(th, 0.0_wp, mya)*sin(th), & - f_r(th, thickness, mya)*sin(th)/)) + spiral_x_min = minval((/f_r(th, 0.0_wp, mya)*cos(th), f_r(th, thickness, mya)*cos(th)/)) + spiral_y_min = minval((/f_r(th, 0.0_wp, mya)*sin(th), f_r(th, thickness, mya)*sin(th)/)) - spiral_x_max = maxval((/f_r(th, 0.0_wp, mya)*cos(th), & - f_r(th, thickness, mya)*cos(th)/)) - spiral_y_max = maxval((/f_r(th, 0.0_wp, mya)*sin(th), & - f_r(th, thickness, mya)*sin(th)/)) + spiral_x_max = maxval((/f_r(th, 0.0_wp, mya)*cos(th), f_r(th, thickness, mya)*cos(th)/)) + spiral_y_max = maxval((/f_r(th, 0.0_wp, mya)*sin(th), f_r(th, thickness, mya)*sin(th)/)) - do j = 0, n; do i = 0, m; - if ((x_cc(i) > spiral_x_min) .and. (x_cc(i) < spiral_x_max) .and. & - (y_cc(j) > spiral_y_min) .and. (y_cc(j) < spiral_y_max)) then - logic_grid(i, j, 0) = 1 - end if - end do; end do + do j = 0, n; do i = 0, m + if ((x_cc(i) > spiral_x_min) .and. (x_cc(i) < spiral_x_max) .and. (y_cc(j) > spiral_y_min) .and. (y_cc(j) & + & < spiral_y_max)) then + logic_grid(i, j, 0) = 1 + end if + end do; end do end do do j = 0, n do i = 0, m if ((logic_grid(i, j, 0) == 1)) then - call s_assign_patch_primitive_variables(patch_id, i, j, 0, & - eta, q_prim_vf, patch_id_fp) + call s_assign_patch_primitive_variables(patch_id, i, j, 0, eta, q_prim_vf, patch_id_fp) @:analytical() if (patch_icpp(patch_id)%hcid /= dflt_int) then @@ -335,32 +295,28 @@ contains end subroutine s_icpp_spiral - !> The circular patch is a 2D geometry that may be used, for - !! example, in creating a bubble or a droplet. The geometry - !! of the patch is well-defined when its centroid and radius - !! are provided. Note that the circular patch DOES allow for - !! the smoothing of its boundary. - !! @param patch_id is the patch identifier - !! @param patch_id_fp Array to track patch ids - !! @param q_prim_vf Array of primitive variables + !> The circular patch is a 2D geometry that may be used, for example, in creating a bubble or a droplet. The geometry of the + !! patch is well-defined when its centroid and radius are provided. Note that the circular patch DOES allow for the smoothing of + !! its boundary. + !! @param patch_id is the patch identifier + !! @param patch_id_fp Array to track patch ids + !! @param q_prim_vf Array of primitive variables subroutine s_icpp_circle(patch_id, patch_id_fp, q_prim_vf) integer, intent(in) :: patch_id + #ifdef MFC_MIXED_PRECISION - integer(kind=1), dimension(0:m, 0:n, 0:p), intent(inout) :: patch_id_fp + integer(kind=1), dimension(0:m,0:n,0:p), intent(inout) :: patch_id_fp #else - integer, dimension(0:m, 0:n, 0:p), intent(inout) :: patch_id_fp + integer, dimension(0:m,0:n,0:p), intent(inout) :: patch_id_fp #endif type(scalar_field), dimension(1:sys_size), intent(inout) :: q_prim_vf - - real(wp) :: radius - - integer :: i, j, k !< Generic loop iterators + real(wp) :: radius + integer :: i, j, k !< Generic loop iterators @:HardcodedDimensionsExtrusion() @:Hardcoded2DVariables() - ! Transferring the circular patch's radius, centroid, smearing patch - ! identity and smearing coefficient information + ! Transferring the circular patch's radius, centroid, smearing patch identity and smearing coefficient information x_centroid = patch_icpp(patch_id)%x_centroid y_centroid = patch_icpp(patch_id)%y_centroid @@ -368,44 +324,28 @@ contains smooth_patch_id = patch_icpp(patch_id)%smooth_patch_id smooth_coeff = patch_icpp(patch_id)%smooth_coeff - ! Initializing the pseudo volume fraction value to 1. The value will - ! be modified as the patch is laid out on the grid, but only in the - ! case that smoothing of the circular patch's boundary is enabled. + ! Initializing the pseudo volume fraction value to 1. The value will be modified as the patch is laid out on the grid, but + ! only in the case that smoothing of the circular patch's boundary is enabled. eta = 1._wp - ! Checking whether the circle covers a particular cell in the domain - ! and verifying whether the current patch has permission to write to - ! that cell. If both queries check out, the primitive variables of - ! the current patch are assigned to this cell. + ! Checking whether the circle covers a particular cell in the domain and verifying whether the current patch has permission + ! to write to that cell. If both queries check out, the primitive variables of the current patch are assigned to this cell. do j = 0, n do i = 0, m - if (patch_icpp(patch_id)%smoothen) then - - eta = tanh(smooth_coeff/min(dx, dy)* & - (sqrt((x_cc(i) - x_centroid)**2 & - + (y_cc(j) - y_centroid)**2) & - - radius))*(-0.5_wp) + 0.5_wp - + eta = tanh(smooth_coeff/min(dx, & + & dy)*(sqrt((x_cc(i) - x_centroid)**2 + (y_cc(j) - y_centroid)**2) - radius))*(-0.5_wp) + 0.5_wp end if - if (((x_cc(i) - x_centroid)**2 & - + (y_cc(j) - y_centroid)**2 <= radius**2 & - .and. & - patch_icpp(patch_id)%alter_patch(patch_id_fp(i, j, 0))) & - .or. & - patch_id_fp(i, j, 0) == smooth_patch_id) & - then - - call s_assign_patch_primitive_variables(patch_id, i, j, 0, & - eta, q_prim_vf, patch_id_fp) + if (((x_cc(i) - x_centroid)**2 + (y_cc(j) - y_centroid)**2 <= radius**2 .and. patch_icpp(patch_id) & + & %alter_patch(patch_id_fp(i, j, 0))) .or. patch_id_fp(i, j, 0) == smooth_patch_id) then + call s_assign_patch_primitive_variables(patch_id, i, j, 0, eta, q_prim_vf, patch_id_fp) @:analytical() if (patch_icpp(patch_id)%hcid /= dflt_int) then @:Hardcoded2D() end if - end if end do end do @@ -413,30 +353,29 @@ contains end subroutine s_icpp_circle - !> The varcircle patch is a 2D geometry that may be used - !! . It generatres an annulus - !! @param patch_id is the patch identifier - !! @param patch_id_fp Array to track patch ids - !! @param q_prim_vf Array of primitive variables + !> The varcircle patch is a 2D geometry that may be used . It generatres an annulus + !! @param patch_id is the patch identifier + !! @param patch_id_fp Array to track patch ids + !! @param q_prim_vf Array of primitive variables subroutine s_icpp_varcircle(patch_id, patch_id_fp, q_prim_vf) ! Patch identifier integer, intent(in) :: patch_id + #ifdef MFC_MIXED_PRECISION - integer(kind=1), dimension(0:m, 0:n, 0:p), intent(inout) :: patch_id_fp + integer(kind=1), dimension(0:m,0:n,0:p), intent(inout) :: patch_id_fp #else - integer, dimension(0:m, 0:n, 0:p), intent(inout) :: patch_id_fp + integer, dimension(0:m,0:n,0:p), intent(inout) :: patch_id_fp #endif type(scalar_field), dimension(1:sys_size), intent(inout) :: q_prim_vf ! Generic loop iterators - integer :: i, j, k + integer :: i, j, k real(wp) :: radius, myr, thickness @:HardcodedDimensionsExtrusion() @:Hardcoded2DVariables() - ! Transferring the circular patch's radius, centroid, smearing patch - ! identity and smearing coefficient information + ! Transferring the circular patch's radius, centroid, smearing patch identity and smearing coefficient information x_centroid = patch_icpp(patch_id)%x_centroid y_centroid = patch_icpp(patch_id)%y_centroid radius = patch_icpp(patch_id)%radius @@ -444,26 +383,19 @@ contains smooth_coeff = patch_icpp(patch_id)%smooth_coeff thickness = patch_icpp(patch_id)%epsilon - ! Initializing the pseudo volume fraction value to 1. The value will - ! be modified as the patch is laid out on the grid, but only in the - ! case that smoothing of the circular patch's boundary is enabled. + ! Initializing the pseudo volume fraction value to 1. The value will be modified as the patch is laid out on the grid, but + ! only in the case that smoothing of the circular patch's boundary is enabled. eta = 1._wp - ! Checking whether the circle covers a particular cell in the domain - ! and verifying whether the current patch has permission to write to - ! that cell. If both queries check out, the primitive variables of - ! the current patch are assigned to this cell. + ! Checking whether the circle covers a particular cell in the domain and verifying whether the current patch has permission + ! to write to that cell. If both queries check out, the primitive variables of the current patch are assigned to this cell. do j = 0, n do i = 0, m - myr = sqrt((x_cc(i) - x_centroid)**2 & - + (y_cc(j) - y_centroid)**2) + myr = sqrt((x_cc(i) - x_centroid)**2 + (y_cc(j) - y_centroid)**2) - if (myr <= radius + thickness/2._wp .and. & - myr >= radius - thickness/2._wp .and. & - patch_icpp(patch_id)%alter_patch(patch_id_fp(i, j, 0))) then - - call s_assign_patch_primitive_variables(patch_id, i, j, 0, & - eta, q_prim_vf, patch_id_fp) + if (myr <= radius + thickness/2._wp .and. myr >= radius - thickness/2._wp .and. patch_icpp(patch_id) & + & %alter_patch(patch_id_fp(i, j, 0))) then + call s_assign_patch_primitive_variables(patch_id, i, j, 0, eta, q_prim_vf, patch_id_fp) @:analytical() if (patch_icpp(patch_id)%hcid /= dflt_int) then @@ -473,10 +405,9 @@ contains ! Updating the patch identities bookkeeping variable if (1._wp - eta < sgm_eps) patch_id_fp(i, j, 0) = patch_id - q_prim_vf(alf_idx)%sf(i, j, 0) = patch_icpp(patch_id)%alpha(1)* & - exp(-0.5_wp*((myr - radius)**2._wp)/(thickness/3._wp)**2._wp) + q_prim_vf(alf_idx)%sf(i, j, & + & 0) = patch_icpp(patch_id)%alpha(1)*exp(-0.5_wp*((myr - radius)**2._wp)/(thickness/3._wp)**2._wp) end if - end do end do @:HardcodedDellacation() @@ -491,21 +422,21 @@ contains ! Patch identifier integer, intent(in) :: patch_id + #ifdef MFC_MIXED_PRECISION - integer(kind=1), dimension(0:m, 0:n, 0:p), intent(inout) :: patch_id_fp + integer(kind=1), dimension(0:m,0:n,0:p), intent(inout) :: patch_id_fp #else - integer, dimension(0:m, 0:n, 0:p), intent(inout) :: patch_id_fp + integer, dimension(0:m,0:n,0:p), intent(inout) :: patch_id_fp #endif type(scalar_field), dimension(1:sys_size), intent(inout) :: q_prim_vf ! Generic loop iterators - integer :: i, j, k + integer :: i, j, k real(wp) :: radius, myr, thickness @:HardcodedDimensionsExtrusion() @:Hardcoded3DVariables() - ! Transferring the circular patch's radius, centroid, smearing patch - ! identity and smearing coefficient information + ! Transferring the circular patch's radius, centroid, smearing patch identity and smearing coefficient information x_centroid = patch_icpp(patch_id)%x_centroid y_centroid = patch_icpp(patch_id)%y_centroid z_centroid = patch_icpp(patch_id)%z_centroid @@ -515,29 +446,22 @@ contains smooth_coeff = patch_icpp(patch_id)%smooth_coeff thickness = patch_icpp(patch_id)%epsilon - ! Initializing the pseudo volume fraction value to 1. The value will - ! be modified as the patch is laid out on the grid, but only in the - ! case that smoothing of the circular patch's boundary is enabled. + ! Initializing the pseudo volume fraction value to 1. The value will be modified as the patch is laid out on the grid, but + ! only in the case that smoothing of the circular patch's boundary is enabled. eta = 1._wp ! write for all z - ! Checking whether the circle covers a particular cell in the domain - ! and verifying whether the current patch has permission to write to - ! that cell. If both queries check out, the primitive variables of - ! the current patch are assigned to this cell. + ! Checking whether the circle covers a particular cell in the domain and verifying whether the current patch has permission + ! to write to that cell. If both queries check out, the primitive variables of the current patch are assigned to this cell. do k = 0, p do j = 0, n do i = 0, m - myr = sqrt((x_cc(i) - x_centroid)**2 & - + (y_cc(j) - y_centroid)**2) + myr = sqrt((x_cc(i) - x_centroid)**2 + (y_cc(j) - y_centroid)**2) - if (myr <= radius + thickness/2._wp .and. & - myr >= radius - thickness/2._wp .and. & - patch_icpp(patch_id)%alter_patch(patch_id_fp(i, j, k))) then - - call s_assign_patch_primitive_variables(patch_id, i, j, k, & - eta, q_prim_vf, patch_id_fp) + if (myr <= radius + thickness/2._wp .and. myr >= radius - thickness/2._wp .and. patch_icpp(patch_id) & + & %alter_patch(patch_id_fp(i, j, k))) then + call s_assign_patch_primitive_variables(patch_id, i, j, k, eta, q_prim_vf, patch_id_fp) @:analytical() if (patch_icpp(patch_id)%hcid /= dflt_int) then @@ -547,10 +471,9 @@ contains ! Updating the patch identities bookkeeping variable if (1._wp - eta < sgm_eps) patch_id_fp(i, j, k) = patch_id - q_prim_vf(alf_idx)%sf(i, j, k) = patch_icpp(patch_id)%alpha(1)* & - exp(-0.5_wp*((myr - radius)**2._wp)/(thickness/3._wp)**2._wp) + q_prim_vf(alf_idx)%sf(i, j, & + & k) = patch_icpp(patch_id)%alpha(1)*exp(-0.5_wp*((myr - radius)**2._wp)/(thickness/3._wp)**2._wp) end if - end do end do end do @@ -558,30 +481,27 @@ contains end subroutine s_icpp_3dvarcircle - !> The elliptical patch is a 2D geometry. The geometry of - !! the patch is well-defined when its centroid and radii - !! are provided. Note that the elliptical patch DOES allow - !! for the smoothing of its boundary - !! @param patch_id is the patch identifier - !! @param patch_id_fp Array to track patch ids - !! @param q_prim_vf Array of primitive variables + !> The elliptical patch is a 2D geometry. The geometry of the patch is well-defined when its centroid and radii are provided. + !! Note that the elliptical patch DOES allow for the smoothing of its boundary + !! @param patch_id is the patch identifier + !! @param patch_id_fp Array to track patch ids + !! @param q_prim_vf Array of primitive variables subroutine s_icpp_ellipse(patch_id, patch_id_fp, q_prim_vf) integer, intent(in) :: patch_id + #ifdef MFC_MIXED_PRECISION - integer(kind=1), dimension(0:m, 0:n, 0:p), intent(inout) :: patch_id_fp + integer(kind=1), dimension(0:m,0:n,0:p), intent(inout) :: patch_id_fp #else - integer, dimension(0:m, 0:n, 0:p), intent(inout) :: patch_id_fp + integer, dimension(0:m,0:n,0:p), intent(inout) :: patch_id_fp #endif type(scalar_field), dimension(1:sys_size), intent(inout) :: q_prim_vf - - integer :: i, j, k !< Generic loop operators - real(wp) :: a, b + integer :: i, j, k !< Generic loop operators + real(wp) :: a, b @:HardcodedDimensionsExtrusion() @:Hardcoded2DVariables() - ! Transferring the elliptical patch's radii, centroid, smearing - ! patch identity, and smearing coefficient information + ! Transferring the elliptical patch's radii, centroid, smearing patch identity, and smearing coefficient information x_centroid = patch_icpp(patch_id)%x_centroid y_centroid = patch_icpp(patch_id)%y_centroid a = patch_icpp(patch_id)%radii(1) @@ -589,36 +509,23 @@ contains smooth_patch_id = patch_icpp(patch_id)%smooth_patch_id smooth_coeff = patch_icpp(patch_id)%smooth_coeff - ! Initializing the pseudo volume fraction value to 1. The value - ! be modified as the patch is laid out on the grid, but only in - ! the case that smoothing of the elliptical patch's boundary is - ! enabled. + ! Initializing the pseudo volume fraction value to 1. The value be modified as the patch is laid out on the grid, but only + ! in the case that smoothing of the elliptical patch's boundary is enabled. eta = 1._wp - ! Checking whether the ellipse covers a particular cell in the - ! domain and verifying whether the current patch has permission - ! to write to that cell. If both queries check out, the primitive - ! variables of the current patch are assigned to this cell. + ! Checking whether the ellipse covers a particular cell in the domain and verifying whether the current patch has permission + ! to write to that cell. If both queries check out, the primitive variables of the current patch are assigned to this cell. do j = 0, n do i = 0, m - if (patch_icpp(patch_id)%smoothen) then - eta = tanh(smooth_coeff/min(dx, dy)* & - (sqrt(((x_cc(i) - x_centroid)/a)**2 + & - ((y_cc(j) - y_centroid)/b)**2) & - - 1._wp))*(-0.5_wp) + 0.5_wp + eta = tanh(smooth_coeff/min(dx, & + & dy)*(sqrt(((x_cc(i) - x_centroid)/a)**2 + ((y_cc(j) - y_centroid)/b)**2) - 1._wp))*(-0.5_wp) & + & + 0.5_wp end if - if ((((x_cc(i) - x_centroid)/a)**2 + & - ((y_cc(j) - y_centroid)/b)**2 <= 1._wp & - .and. & - patch_icpp(patch_id)%alter_patch(patch_id_fp(i, j, 0))) & - .or. & - patch_id_fp(i, j, 0) == smooth_patch_id) & - then - - call s_assign_patch_primitive_variables(patch_id, i, j, 0, & - eta, q_prim_vf, patch_id_fp) + if ((((x_cc(i) - x_centroid)/a)**2 + ((y_cc(j) - y_centroid)/b)**2 <= 1._wp .and. patch_icpp(patch_id) & + & %alter_patch(patch_id_fp(i, j, 0))) .or. patch_id_fp(i, j, 0) == smooth_patch_id) then + call s_assign_patch_primitive_variables(patch_id, i, j, 0, eta, q_prim_vf, patch_id_fp) @:analytical() if (patch_icpp(patch_id)%hcid /= dflt_int) then @@ -634,32 +541,30 @@ contains end subroutine s_icpp_ellipse - !> The ellipsoidal patch is a 3D geometry. The geometry of - !! the patch is well-defined when its centroid and radii - !! are provided. Note that the ellipsoidal patch DOES allow - !! for the smoothing of its boundary - !! @param patch_id is the patch identifier - !! @param patch_id_fp Array to track patch ids - !! @param q_prim_vf Array of primitive variables + !> The ellipsoidal patch is a 3D geometry. The geometry of the patch is well-defined when its centroid and radii are provided. + !! Note that the ellipsoidal patch DOES allow for the smoothing of its boundary + !! @param patch_id is the patch identifier + !! @param patch_id_fp Array to track patch ids + !! @param q_prim_vf Array of primitive variables subroutine s_icpp_ellipsoid(patch_id, patch_id_fp, q_prim_vf) ! Patch identifier integer, intent(in) :: patch_id + #ifdef MFC_MIXED_PRECISION - integer(kind=1), dimension(0:m, 0:n, 0:p), intent(inout) :: patch_id_fp + integer(kind=1), dimension(0:m,0:n,0:p), intent(inout) :: patch_id_fp #else - integer, dimension(0:m, 0:n, 0:p), intent(inout) :: patch_id_fp + integer, dimension(0:m,0:n,0:p), intent(inout) :: patch_id_fp #endif type(scalar_field), dimension(1:sys_size), intent(inout) :: q_prim_vf ! Generic loop iterators - integer :: i, j, k + integer :: i, j, k real(wp) :: a, b, c @:HardcodedDimensionsExtrusion() @:Hardcoded3DVariables() - ! Transferring the ellipsoidal patch's radii, centroid, smearing - ! patch identity, and smearing coefficient information + ! Transferring the ellipsoidal patch's radii, centroid, smearing patch identity, and smearing coefficient information x_centroid = patch_icpp(patch_id)%x_centroid y_centroid = patch_icpp(patch_id)%y_centroid z_centroid = patch_icpp(patch_id)%z_centroid @@ -669,20 +574,16 @@ contains smooth_patch_id = patch_icpp(patch_id)%smooth_patch_id smooth_coeff = patch_icpp(patch_id)%smooth_coeff - ! Initializing the pseudo volume fraction value to 1. The value - ! be modified as the patch is laid out on the grid, but only in - ! the case that smoothing of the ellipsoidal patch's boundary is - ! enabled. + ! Initializing the pseudo volume fraction value to 1. The value be modified as the patch is laid out on the grid, but only + ! in the case that smoothing of the ellipsoidal patch's boundary is enabled. eta = 1._wp - ! Checking whether the ellipsoid covers a particular cell in the - ! domain and verifying whether the current patch has permission - ! to write to that cell. If both queries check out, the primitive - ! variables of the current patch are assigned to this cell. + ! Checking whether the ellipsoid covers a particular cell in the domain and verifying whether the current patch has + ! permission to write to that cell. If both queries check out, the primitive variables of the current patch are assigned to + ! this cell. do k = 0, p do j = 0, n do i = 0, m - if (grid_geometry == 3) then call s_convert_cylindrical_to_cartesian_coord(y_cc(j), z_cc(k)) else @@ -691,24 +592,15 @@ contains end if if (patch_icpp(patch_id)%smoothen) then - eta = tanh(smooth_coeff/min(dx, dy, dz)* & - (sqrt(((x_cc(i) - x_centroid)/a)**2 + & - ((cart_y - y_centroid)/b)**2 + & - ((cart_z - z_centroid)/c)**2) & - - 1._wp))*(-0.5_wp) + 0.5_wp + eta = tanh(smooth_coeff/min(dx, dy, & + & dz)*(sqrt(((x_cc(i) - x_centroid)/a)**2 + ((cart_y - y_centroid)/b)**2 + ((cart_z & + & - z_centroid)/c)**2) - 1._wp))*(-0.5_wp) + 0.5_wp end if - if ((((x_cc(i) - x_centroid)/a)**2 + & - ((cart_y - y_centroid)/b)**2 + & - ((cart_z - z_centroid)/c)**2 <= 1._wp & - .and. & - patch_icpp(patch_id)%alter_patch(patch_id_fp(i, j, k))) & - .or. & - patch_id_fp(i, j, k) == smooth_patch_id) & - then - - call s_assign_patch_primitive_variables(patch_id, i, j, k, & - eta, q_prim_vf, patch_id_fp) + if ((((x_cc(i) - x_centroid)/a)**2 + ((cart_y - y_centroid)/b)**2 + ((cart_z - z_centroid)/c) & + & **2 <= 1._wp .and. patch_icpp(patch_id)%alter_patch(patch_id_fp(i, j, k))) .or. patch_id_fp(i, j, & + & k) == smooth_patch_id) then + call s_assign_patch_primitive_variables(patch_id, i, j, k, eta, q_prim_vf, patch_id_fp) @:analytical() if (patch_icpp(patch_id)%hcid /= dflt_int) then @@ -725,29 +617,25 @@ contains end subroutine s_icpp_ellipsoid - !> The rectangular patch is a 2D geometry that may be used, - !! for example, in creating a solid boundary, or pre-/post- - !! shock region, in alignment with the axes of the Cartesian - !! coordinate system. The geometry of such a patch is well- - !! defined when its centroid and lengths in the x- and y- - !! coordinate directions are provided. Please note that the - !! rectangular patch DOES NOT allow for the smoothing of its - !! boundaries. - !! @param patch_id is the patch identifier - !! @param patch_id_fp Array to track patch ids - !! @param q_prim_vf Array of primitive variables + !> The rectangular patch is a 2D geometry that may be used, for example, in creating a solid boundary, or pre-/post- shock + !! region, in alignment with the axes of the Cartesian coordinate system. The geometry of such a patch is well- defined when its + !! centroid and lengths in the x- and y- coordinate directions are provided. Please note that the rectangular patch DOES NOT + !! allow for the smoothing of its boundaries. + !! @param patch_id is the patch identifier + !! @param patch_id_fp Array to track patch ids + !! @param q_prim_vf Array of primitive variables subroutine s_icpp_rectangle(patch_id, patch_id_fp, q_prim_vf) integer, intent(in) :: patch_id + #ifdef MFC_MIXED_PRECISION - integer(kind=1), dimension(0:m, 0:n, 0:p), intent(inout) :: patch_id_fp + integer(kind=1), dimension(0:m,0:n,0:p), intent(inout) :: patch_id_fp #else - integer, dimension(0:m, 0:n, 0:p), intent(inout) :: patch_id_fp + integer, dimension(0:m,0:n,0:p), intent(inout) :: patch_id_fp #endif type(scalar_field), dimension(1:sys_size), intent(inout) :: q_prim_vf - - integer :: i, j, k !< generic loop iterators - real(wp) :: pi_inf, gamma, lit_gamma !< Equation of state parameters + integer :: i, j, k !< generic loop iterators + real(wp) :: pi_inf, gamma, lit_gamma !< Equation of state parameters @:HardcodedDimensionsExtrusion() @:Hardcoded2DVariables() @@ -761,34 +649,25 @@ contains length_x = patch_icpp(patch_id)%length_x length_y = patch_icpp(patch_id)%length_y - ! Computing the beginning and the end x- and y-coordinates of the - ! rectangle based on its centroid and lengths + ! Computing the beginning and the end x- and y-coordinates of the rectangle based on its centroid and lengths x_boundary%beg = x_centroid - 0.5_wp*length_x x_boundary%end = x_centroid + 0.5_wp*length_x y_boundary%beg = y_centroid - 0.5_wp*length_y y_boundary%end = y_centroid + 0.5_wp*length_y - ! Since the rectangular patch does not allow for its boundaries to - ! be smoothed out, the pseudo volume fraction is set to 1 to ensure - ! that only the current patch contributes to the fluid state in the - ! cells that this patch covers. + ! Since the rectangular patch does not allow for its boundaries to be smoothed out, the pseudo volume fraction is set to 1 + ! to ensure that only the current patch contributes to the fluid state in the cells that this patch covers. eta = 1._wp - ! Checking whether the rectangle covers a particular cell in the - ! domain and verifying whether the current patch has the permission - ! to write to that cell. If both queries check out, the primitive - ! variables of the current patch are assigned to this cell. + ! Checking whether the rectangle covers a particular cell in the domain and verifying whether the current patch has the + ! permission to write to that cell. If both queries check out, the primitive variables of the current patch are assigned to + ! this cell. do j = 0, n do i = 0, m - if (x_boundary%beg <= x_cc(i) .and. & - x_boundary%end >= x_cc(i) .and. & - y_boundary%beg <= y_cc(j) .and. & - y_boundary%end >= y_cc(j)) then - if (patch_icpp(patch_id)%alter_patch(patch_id_fp(i, j, 0))) & - then - - call s_assign_patch_primitive_variables(patch_id, i, j, 0, & - eta, q_prim_vf, patch_id_fp) + if (x_boundary%beg <= x_cc(i) .and. x_boundary%end >= x_cc(i) .and. y_boundary%beg <= y_cc(j) & + & .and. y_boundary%end >= y_cc(j)) then + if (patch_icpp(patch_id)%alter_patch(patch_id_fp(i, j, 0))) then + call s_assign_patch_primitive_variables(patch_id, i, j, 0, eta, q_prim_vf, patch_id_fp) @:analytical() @@ -797,10 +676,10 @@ contains end if if ((q_prim_vf(1)%sf(i, j, 0) < 1.e-10) .and. (model_eqns == 4)) then - !zero density, reassign according to Tait EOS - q_prim_vf(1)%sf(i, j, 0) = & - (((q_prim_vf(E_idx)%sf(i, j, 0) + pi_inf)/(pref + pi_inf))**(1._wp/lit_gamma))* & - rhoref*(1._wp - q_prim_vf(alf_idx)%sf(i, j, 0)) + ! zero density, reassign according to Tait EOS + q_prim_vf(1)%sf(i, j, 0) = (((q_prim_vf(E_idx)%sf(i, j, & + & 0) + pi_inf)/(pref + pi_inf))**(1._wp/lit_gamma))*rhoref*(1._wp - q_prim_vf(alf_idx) & + & %sf(i, j, 0)) end if ! Updating the patch identities bookkeeping variable @@ -813,28 +692,25 @@ contains end subroutine s_icpp_rectangle - !> The swept line patch is a 2D geometry that may be used, - !! for example, in creating a solid boundary, or pre-/post- - !! shock region, at an angle with respect to the axes of the - !! Cartesian coordinate system. The geometry of the patch is - !! well-defined when its centroid and normal vector, aimed - !! in the sweep direction, are provided. Note that the sweep - !! line patch DOES allow the smoothing of its boundary. - !! @param patch_id is the patch identifier - !! @param patch_id_fp Array to track patch ids - !! @param q_prim_vf Array of primitive variables + !> The swept line patch is a 2D geometry that may be used, for example, in creating a solid boundary, or pre-/post- shock + !! region, at an angle with respect to the axes of the Cartesian coordinate system. The geometry of the patch is well-defined + !! when its centroid and normal vector, aimed in the sweep direction, are provided. Note that the sweep line patch DOES allow + !! the smoothing of its boundary. + !! @param patch_id is the patch identifier + !! @param patch_id_fp Array to track patch ids + !! @param q_prim_vf Array of primitive variables subroutine s_icpp_sweep_line(patch_id, patch_id_fp, q_prim_vf) integer, intent(in) :: patch_id + #ifdef MFC_MIXED_PRECISION - integer(kind=1), dimension(0:m, 0:n, 0:p), intent(inout) :: patch_id_fp + integer(kind=1), dimension(0:m,0:n,0:p), intent(inout) :: patch_id_fp #else - integer, dimension(0:m, 0:n, 0:p), intent(inout) :: patch_id_fp + integer, dimension(0:m,0:n,0:p), intent(inout) :: patch_id_fp #endif type(scalar_field), dimension(1:sys_size), intent(inout) :: q_prim_vf - - integer :: i, j, k !< Generic loop operators - real(wp) :: a, b, c + integer :: i, j, k !< Generic loop operators + real(wp) :: a, b, c @:HardcodedDimensionsExtrusion() @:Hardcoded3DVariables() @@ -849,32 +725,22 @@ contains b = patch_icpp(patch_id)%normal(2) c = -a*x_centroid - b*y_centroid - ! Initializing the pseudo volume fraction value to 1. The value will - ! be modified as the patch is laid out on the grid, but only in the - ! case that smoothing of the sweep line patch's boundary is enabled. + ! Initializing the pseudo volume fraction value to 1. The value will be modified as the patch is laid out on the grid, but + ! only in the case that smoothing of the sweep line patch's boundary is enabled. eta = 1._wp - ! Checking whether the region swept by the line covers a particular - ! cell in the domain and verifying whether the current patch has the - ! permission to write to that cell. If both queries check out, the - ! primitive variables of the current patch are written to this cell. + ! Checking whether the region swept by the line covers a particular cell in the domain and verifying whether the current + ! patch has the permission to write to that cell. If both queries check out, the primitive variables of the current patch + ! are written to this cell. do j = 0, n do i = 0, m - if (patch_icpp(patch_id)%smoothen) then - eta = 5.e-1_wp + 5.e-1_wp*tanh(smooth_coeff/min(dx, dy) & - *(a*x_cc(i) + b*y_cc(j) + c) & - /sqrt(a**2 + b**2)) + eta = 5.e-1_wp + 5.e-1_wp*tanh(smooth_coeff/min(dx, dy)*(a*x_cc(i) + b*y_cc(j) + c)/sqrt(a**2 + b**2)) end if - if ((a*x_cc(i) + b*y_cc(j) + c >= 0._wp & - .and. & - patch_icpp(patch_id)%alter_patch(patch_id_fp(i, j, 0))) & - .or. & - patch_id_fp(i, j, 0) == smooth_patch_id) & - then - call s_assign_patch_primitive_variables(patch_id, i, j, 0, & - eta, q_prim_vf, patch_id_fp) + if ((a*x_cc(i) + b*y_cc(j) + c >= 0._wp .and. patch_icpp(patch_id)%alter_patch(patch_id_fp(i, j, & + & 0))) .or. patch_id_fp(i, j, 0) == smooth_patch_id) then + call s_assign_patch_primitive_variables(patch_id, i, j, 0, eta, q_prim_vf, patch_id_fp) @:analytical() if (patch_icpp(patch_id)%hcid /= dflt_int) then @@ -884,33 +750,30 @@ contains ! Updating the patch identities bookkeeping variable if (1._wp - eta < sgm_eps) patch_id_fp(i, j, 0) = patch_id end if - end do end do @:HardcodedDellacation() end subroutine s_icpp_sweep_line - !> The Taylor Green vortex is 2D decaying vortex that may be used, - !! for example, to verify the effects of viscous attenuation. - !! Geometry of the patch is well-defined when its centroid - !! are provided. - !! @param patch_id is the patch identifier - !! @param patch_id_fp Array to track patch ids - !! @param q_prim_vf Array of primitive variables + !> The Taylor Green vortex is 2D decaying vortex that may be used, for example, to verify the effects of viscous attenuation. + !! Geometry of the patch is well-defined when its centroid are provided. + !! @param patch_id is the patch identifier + !! @param patch_id_fp Array to track patch ids + !! @param q_prim_vf Array of primitive variables subroutine s_icpp_2D_TaylorGreen_Vortex(patch_id, patch_id_fp, q_prim_vf) integer, intent(in) :: patch_id + #ifdef MFC_MIXED_PRECISION - integer(kind=1), dimension(0:m, 0:n, 0:p), intent(inout) :: patch_id_fp + integer(kind=1), dimension(0:m,0:n,0:p), intent(inout) :: patch_id_fp #else - integer, dimension(0:m, 0:n, 0:p), intent(inout) :: patch_id_fp + integer, dimension(0:m,0:n,0:p), intent(inout) :: patch_id_fp #endif type(scalar_field), dimension(1:sys_size), intent(inout) :: q_prim_vf - - integer :: i, j, k !< generic loop iterators - real(wp) :: pi_inf, gamma, lit_gamma !< equation of state parameters - real(wp) :: L0, U0 !< Taylor Green Vortex parameters + integer :: i, j, k !< generic loop iterators + real(wp) :: pi_inf, gamma, lit_gamma !< equation of state parameters + real(wp) :: L0, U0 !< Taylor Green Vortex parameters @:HardcodedDimensionsExtrusion() @:Hardcoded2DVariables() @@ -924,37 +787,27 @@ contains length_x = patch_icpp(patch_id)%length_x length_y = patch_icpp(patch_id)%length_y - ! Computing the beginning and the end x- and y-coordinates - ! of the patch based on its centroid and lengths + ! Computing the beginning and the end x- and y-coordinates of the patch based on its centroid and lengths x_boundary%beg = x_centroid - 0.5_wp*length_x x_boundary%end = x_centroid + 0.5_wp*length_x y_boundary%beg = y_centroid - 0.5_wp*length_y y_boundary%end = y_centroid + 0.5_wp*length_y - ! Since the patch doesn't allow for its boundaries to be - ! smoothed out, the pseudo volume fraction is set to 1 to - ! ensure that only the current patch contributes to the fluid - ! state in the cells that this patch covers. + ! Since the patch doesn't allow for its boundaries to be smoothed out, the pseudo volume fraction is set to 1 to ensure that + ! only the current patch contributes to the fluid state in the cells that this patch covers. eta = 1._wp ! U0 is the characteristic velocity of the vortex U0 = patch_icpp(patch_id)%vel(1) ! L0 is the characteristic length of the vortex L0 = patch_icpp(patch_id)%vel(2) - ! Checking whether the patch covers a particular cell in the - ! domain and verifying whether the current patch has the - ! permission to write to that cell. If both queries check out, - ! the primitive variables of the current patch are assigned - ! to this cell. + ! Checking whether the patch covers a particular cell in the domain and verifying whether the current patch has the + ! permission to write to that cell. If both queries check out, the primitive variables of the current patch are assigned to + ! this cell. do j = 0, n do i = 0, m - if (x_boundary%beg <= x_cc(i) .and. & - x_boundary%end >= x_cc(i) .and. & - y_boundary%beg <= y_cc(j) .and. & - y_boundary%end >= y_cc(j) .and. & - patch_icpp(patch_id)%alter_patch(patch_id_fp(i, j, 0))) then - - call s_assign_patch_primitive_variables(patch_id, i, j, 0, & - eta, q_prim_vf, patch_id_fp) + if (x_boundary%beg <= x_cc(i) .and. x_boundary%end >= x_cc(i) .and. y_boundary%beg <= y_cc(j) & + & .and. y_boundary%end >= y_cc(j) .and. patch_icpp(patch_id)%alter_patch(patch_id_fp(i, j, 0))) then + call s_assign_patch_primitive_variables(patch_id, i, j, 0, eta, q_prim_vf, patch_id_fp) @:analytical() if (patch_icpp(patch_id)%hcid /= dflt_int) then @@ -967,9 +820,9 @@ contains ! Assign Parameters q_prim_vf(mom_idx%beg)%sf(i, j, 0) = U0*sin(x_cc(i)/L0)*cos(y_cc(j)/L0) q_prim_vf(mom_idx%end)%sf(i, j, 0) = -U0*cos(x_cc(i)/L0)*sin(y_cc(j)/L0) - q_prim_vf(E_idx)%sf(i, j, 0) = patch_icpp(patch_id)%pres + (cos(2*x_cc(i))/L0 + & - cos(2*y_cc(j))/L0)* & - (q_prim_vf(1)%sf(i, j, 0)*U0*U0)/16 + q_prim_vf(E_idx)%sf(i, j, & + & 0) = patch_icpp(patch_id)%pres + (cos(2*x_cc(i))/L0 + cos(2*y_cc(j))/L0)*(q_prim_vf(1)%sf(i, j, & + & 0)*U0*U0)/16 end if end do end do @@ -978,19 +831,20 @@ contains end subroutine s_icpp_2D_TaylorGreen_Vortex !> @brief Initializes a 1D bubble-pulse patch with analytical primitive variable profiles. - !! @param patch_id is the patch identifier - !! @param patch_id_fp Array to track patch ids - !! @param q_prim_vf Array of primitive variables + !! @param patch_id is the patch identifier + !! @param patch_id_fp Array to track patch ids + !! @param q_prim_vf Array of primitive variables subroutine s_icpp_1d_bubble_pulse(patch_id, patch_id_fp, q_prim_vf) - ! Description: This patch assigns the primitive variables as analytical - ! functions such that the code can be verified. + + ! Description: This patch assigns the primitive variables as analytical functions such that the code can be verified. ! Patch identifier integer, intent(in) :: patch_id + #ifdef MFC_MIXED_PRECISION - integer(kind=1), dimension(0:m, 0:n, 0:p), intent(inout) :: patch_id_fp + integer(kind=1), dimension(0:m,0:n,0:p), intent(inout) :: patch_id_fp #else - integer, dimension(0:m, 0:n, 0:p), intent(inout) :: patch_id_fp + integer, dimension(0:m,0:n,0:p), intent(inout) :: patch_id_fp #endif type(scalar_field), dimension(1:sys_size), intent(inout) :: q_prim_vf @@ -1009,55 +863,48 @@ contains x_centroid = patch_icpp(patch_id)%x_centroid length_x = patch_icpp(patch_id)%length_x - ! Computing the beginning and the end x- and y-coordinates - ! of the patch based on its centroid and lengths + ! Computing the beginning and the end x- and y-coordinates of the patch based on its centroid and lengths x_boundary%beg = x_centroid - 0.5_wp*length_x x_boundary%end = x_centroid + 0.5_wp*length_x - ! Since the patch doesn't allow for its boundaries to be - ! smoothed out, the pseudo volume fraction is set to 1 to - ! ensure that only the current patch contributes to the fluid - ! state in the cells that this patch covers. + ! Since the patch doesn't allow for its boundaries to be smoothed out, the pseudo volume fraction is set to 1 to ensure that + ! only the current patch contributes to the fluid state in the cells that this patch covers. eta = 1._wp - ! Checking whether the line segment covers a particular cell in the - ! domain and verifying whether the current patch has the permission - ! to write to that cell. If both queries check out, the primitive - ! variables of the current patch are assigned to this cell. + ! Checking whether the line segment covers a particular cell in the domain and verifying whether the current patch has the + ! permission to write to that cell. If both queries check out, the primitive variables of the current patch are assigned to + ! this cell. do i = 0, m - if (x_boundary%beg <= x_cc(i) .and. & - x_boundary%end >= x_cc(i) .and. & - patch_icpp(patch_id)%alter_patch(patch_id_fp(i, 0, 0))) then - - call s_assign_patch_primitive_variables(patch_id, i, 0, 0, & - eta, q_prim_vf, patch_id_fp) + if (x_boundary%beg <= x_cc(i) .and. x_boundary%end >= x_cc(i) .and. patch_icpp(patch_id)%alter_patch(patch_id_fp(i, & + & 0, 0))) then + call s_assign_patch_primitive_variables(patch_id, i, 0, 0, eta, q_prim_vf, patch_id_fp) @:analytical() if (patch_icpp(patch_id)%hcid /= dflt_int) then @:Hardcoded1D() end if - end if end do @:HardcodedDellacation() end subroutine s_icpp_1D_bubble_pulse - !> 2D modal (Fourier) patch. theta = atan2(y - y_centroid, x - x_centroid). - !! Additive (modal_use_exp_form false): R = radius + sum_n [fourier_cos*cos(n*theta)+fourier_sin*sin(n*theta)]; - !! coefficients are absolute (same units as radius). R is clipped to max(R,0). If modal_clip_r_to_min, R = max(R, modal_r_min). - !! Exponential (modal_use_exp_form true): R = radius*exp(sum); coefficients are relative (dimensionless). + !> 2D modal (Fourier) patch. theta = atan2(y - y_centroid, x - x_centroid). Additive (modal_use_exp_form false): R = radius + + !! sum_n [fourier_cos*cos(n*theta)+fourier_sin*sin(n*theta)]; coefficients are absolute (same units as radius). R is clipped to + !! max(R,0). If modal_clip_r_to_min, R = max(R, modal_r_min). Exponential (modal_use_exp_form true): R = radius*exp(sum); + !! coefficients are relative (dimensionless). subroutine s_icpp_2d_modal(patch_id, patch_id_fp, q_prim_vf) + integer, intent(in) :: patch_id + #ifdef MFC_MIXED_PRECISION - integer(kind=1), dimension(0:m, 0:n, 0:p), intent(inout) :: patch_id_fp + integer(kind=1), dimension(0:m,0:n,0:p), intent(inout) :: patch_id_fp #else - integer, dimension(0:m, 0:n, 0:p), intent(inout) :: patch_id_fp + integer, dimension(0:m,0:n,0:p), intent(inout) :: patch_id_fp #endif type(scalar_field), dimension(1:sys_size), intent(inout) :: q_prim_vf - - real(wp) :: r, theta, R_boundary, sum_series - integer :: i, j, nn + real(wp) :: r, theta, R_boundary, sum_series + integer :: i, j, nn x_centroid = patch_icpp(patch_id)%x_centroid y_centroid = patch_icpp(patch_id)%y_centroid @@ -1075,8 +922,8 @@ contains end if sum_series = 0._wp do nn = 1, max_2d_fourier_modes - sum_series = sum_series + patch_icpp(patch_id)%fourier_cos(nn)*cos(real(nn, wp)*theta) & - + patch_icpp(patch_id)%fourier_sin(nn)*sin(real(nn, wp)*theta) + sum_series = sum_series + patch_icpp(patch_id)%fourier_cos(nn)*cos(real(nn, & + & wp)*theta) + patch_icpp(patch_id)%fourier_sin(nn)*sin(real(nn, wp)*theta) end do if (patch_icpp(patch_id)%modal_use_exp_form) then R_boundary = patch_icpp(patch_id)%radius*exp(sum_series) @@ -1090,27 +937,29 @@ contains if (patch_icpp(patch_id)%smoothen) then eta = 0.5_wp + 0.5_wp*tanh(smooth_coeff/min(dx, dy)*(R_boundary - r)) end if - if ((r <= R_boundary .and. patch_icpp(patch_id)%alter_patch(patch_id_fp(i, j, 0))) & - .or. patch_id_fp(i, j, 0) == smooth_patch_id) then + if ((r <= R_boundary .and. patch_icpp(patch_id)%alter_patch(patch_id_fp(i, j, 0))) .or. patch_id_fp(i, j, & + & 0) == smooth_patch_id) then call s_assign_patch_primitive_variables(patch_id, i, j, 0, eta, q_prim_vf, patch_id_fp) end if end do end do + end subroutine s_icpp_2d_modal - !> 3D spherical harmonic patch. Surface r = radius + sum_lm sph_har_coeff(l,m)*Y_lm(theta,phi). - !! theta = acos(z/r), phi = atan2(y,x) relative to centroid. + !> 3D spherical harmonic patch. Surface r = radius + sum_lm sph_har_coeff(l,m)*Y_lm(theta,phi). theta = acos(z/r), phi = + !! atan2(y,x) relative to centroid. subroutine s_icpp_3d_spherical_harmonic(patch_id, patch_id_fp, q_prim_vf) + integer, intent(in) :: patch_id + #ifdef MFC_MIXED_PRECISION - integer(kind=1), dimension(0:m, 0:n, 0:p), intent(inout) :: patch_id_fp + integer(kind=1), dimension(0:m,0:n,0:p), intent(inout) :: patch_id_fp #else - integer, dimension(0:m, 0:n, 0:p), intent(inout) :: patch_id_fp + integer, dimension(0:m,0:n,0:p), intent(inout) :: patch_id_fp #endif type(scalar_field), dimension(1:sys_size), intent(inout) :: q_prim_vf - - real(wp) :: dx_loc, dy_loc, dz_loc, r, theta, phi, R_surface, eta_local - integer :: i, j, k, ll, mm + real(wp) :: dx_loc, dy_loc, dz_loc, r, theta, phi, R_surface, eta_local + integer :: i, j, k, ll, mm x_centroid = patch_icpp(patch_id)%x_centroid y_centroid = patch_icpp(patch_id)%y_centroid @@ -1150,44 +999,43 @@ contains if (patch_icpp(patch_id)%smoothen) then eta_local = 0.5_wp + 0.5_wp*tanh(smooth_coeff/min(dx, dy, dz)*(R_surface - r)) end if - if ((r <= R_surface .and. patch_icpp(patch_id)%alter_patch(patch_id_fp(i, j, k))) & - .or. patch_id_fp(i, j, k) == smooth_patch_id) then + if ((r <= R_surface .and. patch_icpp(patch_id)%alter_patch(patch_id_fp(i, j, k))) .or. patch_id_fp(i, j, & + & k) == smooth_patch_id) then call s_assign_patch_primitive_variables(patch_id, i, j, k, eta_local, q_prim_vf, patch_id_fp) end if end do end do end do + end subroutine s_icpp_3d_spherical_harmonic - !> The spherical patch is a 3D geometry that may be used, - !! for example, in creating a bubble or a droplet. The patch - !! geometry is well-defined when its centroid and radius are - !! provided. Please note that the spherical patch DOES allow - !! for the smoothing of its boundary. - !! @param patch_id is the patch identifier - !! @param patch_id_fp Array to track patch ids - !! @param q_prim_vf Array of primitive variables + !> The spherical patch is a 3D geometry that may be used, for example, in creating a bubble or a droplet. The patch geometry is + !! well-defined when its centroid and radius are provided. Please note that the spherical patch DOES allow for the smoothing of + !! its boundary. + !! @param patch_id is the patch identifier + !! @param patch_id_fp Array to track patch ids + !! @param q_prim_vf Array of primitive variables subroutine s_icpp_sphere(patch_id, patch_id_fp, q_prim_vf) integer, intent(in) :: patch_id + #ifdef MFC_MIXED_PRECISION - integer(kind=1), dimension(0:m, 0:n, 0:p), intent(inout) :: patch_id_fp + integer(kind=1), dimension(0:m,0:n,0:p), intent(inout) :: patch_id_fp #else - integer, dimension(0:m, 0:n, 0:p), intent(inout) :: patch_id_fp + integer, dimension(0:m,0:n,0:p), intent(inout) :: patch_id_fp #endif type(scalar_field), dimension(1:sys_size), intent(inout) :: q_prim_vf ! Generic loop iterators - integer :: i, j, k + integer :: i, j, k real(wp) :: radius @:HardcodedDimensionsExtrusion() @:Hardcoded3DVariables() - !! Variables to initialize the pressure field that corresponds to the - !! bubble-collapse test case found in Tiwari et al. (2013) + !! Variables to initialize the pressure field that corresponds to the bubble-collapse test case found in Tiwari et al. + !! (2013) - ! Transferring spherical patch's radius, centroid, smoothing patch - ! identity and smoothing coefficient information + ! Transferring spherical patch's radius, centroid, smoothing patch identity and smoothing coefficient information x_centroid = patch_icpp(patch_id)%x_centroid y_centroid = patch_icpp(patch_id)%y_centroid z_centroid = patch_icpp(patch_id)%z_centroid @@ -1195,19 +1043,15 @@ contains smooth_patch_id = patch_icpp(patch_id)%smooth_patch_id smooth_coeff = patch_icpp(patch_id)%smooth_coeff - ! Initializing the pseudo volume fraction value to 1. The value will - ! be modified as the patch is laid out on the grid, but only in the - ! case that smoothing of the spherical patch's boundary is enabled. + ! Initializing the pseudo volume fraction value to 1. The value will be modified as the patch is laid out on the grid, but + ! only in the case that smoothing of the spherical patch's boundary is enabled. eta = 1._wp - ! Checking whether the sphere covers a particular cell in the domain - ! and verifying whether the current patch has permission to write to - ! that cell. If both queries check out, the primitive variables of - ! the current patch are assigned to this cell. + ! Checking whether the sphere covers a particular cell in the domain and verifying whether the current patch has permission + ! to write to that cell. If both queries check out, the primitive variables of the current patch are assigned to this cell. do k = 0, p do j = 0, n do i = 0, m - if (grid_geometry == 3) then call s_convert_cylindrical_to_cartesian_coord(y_cc(j), z_cc(k)) else @@ -1216,27 +1060,20 @@ contains end if if (patch_icpp(patch_id)%smoothen) then - eta = tanh(smooth_coeff/min(dx, dy, dz)* & - (sqrt((x_cc(i) - x_centroid)**2 & - + (cart_y - y_centroid)**2 & - + (cart_z - z_centroid)**2) & - - radius))*(-0.5_wp) + 0.5_wp + eta = tanh(smooth_coeff/min(dx, dy, & + & dz)*(sqrt((x_cc(i) - x_centroid)**2 + (cart_y - y_centroid)**2 + (cart_z - z_centroid)**2) & + & - radius))*(-0.5_wp) + 0.5_wp end if - if ((((x_cc(i) - x_centroid)**2 & - + (cart_y - y_centroid)**2 & - + (cart_z - z_centroid)**2 <= radius**2) .and. & - patch_icpp(patch_id)%alter_patch(patch_id_fp(i, j, k))) .or. & - patch_id_fp(i, j, k) == smooth_patch_id) then - - call s_assign_patch_primitive_variables(patch_id, i, j, k, & - eta, q_prim_vf, patch_id_fp) + if ((((x_cc(i) - x_centroid)**2 + (cart_y - y_centroid)**2 + (cart_z - z_centroid)**2 <= radius**2) & + & .and. patch_icpp(patch_id)%alter_patch(patch_id_fp(i, j, k))) .or. patch_id_fp(i, j, & + & k) == smooth_patch_id) then + call s_assign_patch_primitive_variables(patch_id, i, j, k, eta, q_prim_vf, patch_id_fp) @:analytical() if (patch_icpp(patch_id)%hcid /= dflt_int) then @:Hardcoded3D() end if - end if end do end do @@ -1245,28 +1082,24 @@ contains end subroutine s_icpp_sphere - !> The cuboidal patch is a 3D geometry that may be used, for - !! example, in creating a solid boundary, or pre-/post-shock - !! region, which is aligned with the axes of the Cartesian - !! coordinate system. The geometry of such a patch is well- - !! defined when its centroid and lengths in the x-, y- and - !! z-coordinate directions are provided. Please notice that - !! the cuboidal patch DOES NOT allow for the smearing of its - !! boundaries. - !! @param patch_id is the patch identifier - !! @param patch_id_fp Array to track patch ids - !! @param q_prim_vf Array of primitive variables + !> The cuboidal patch is a 3D geometry that may be used, for example, in creating a solid boundary, or pre-/post-shock region, + !! which is aligned with the axes of the Cartesian coordinate system. The geometry of such a patch is well- defined when its + !! centroid and lengths in the x-, y- and z-coordinate directions are provided. Please notice that the cuboidal patch DOES NOT + !! allow for the smearing of its boundaries. + !! @param patch_id is the patch identifier + !! @param patch_id_fp Array to track patch ids + !! @param q_prim_vf Array of primitive variables subroutine s_icpp_cuboid(patch_id, patch_id_fp, q_prim_vf) integer, intent(in) :: patch_id + #ifdef MFC_MIXED_PRECISION - integer(kind=1), dimension(0:m, 0:n, 0:p), intent(inout) :: patch_id_fp + integer(kind=1), dimension(0:m,0:n,0:p), intent(inout) :: patch_id_fp #else - integer, dimension(0:m, 0:n, 0:p), intent(inout) :: patch_id_fp + integer, dimension(0:m,0:n,0:p), intent(inout) :: patch_id_fp #endif type(scalar_field), dimension(1:sys_size), intent(inout) :: q_prim_vf - - integer :: i, j, k !< Generic loop iterators + integer :: i, j, k !< Generic loop iterators @:HardcodedDimensionsExtrusion() @:Hardcoded3DVariables() @@ -1278,8 +1111,7 @@ contains length_y = patch_icpp(patch_id)%length_y length_z = patch_icpp(patch_id)%length_z - ! Computing the beginning and the end x-, y- and z-coordinates of - ! the cuboid based on its centroid and lengths + ! Computing the beginning and the end x-, y- and z-coordinates of the cuboid based on its centroid and lengths x_boundary%beg = x_centroid - 0.5_wp*length_x x_boundary%end = x_centroid + 0.5_wp*length_x y_boundary%beg = y_centroid - 0.5_wp*length_y @@ -1287,20 +1119,16 @@ contains z_boundary%beg = z_centroid - 0.5_wp*length_z z_boundary%end = z_centroid + 0.5_wp*length_z - ! Since the cuboidal patch does not allow for its boundaries to get - ! smoothed out, the pseudo volume fraction is set to 1 to make sure - ! that only the current patch contributes to the fluid state in the - ! cells that this patch covers. + ! Since the cuboidal patch does not allow for its boundaries to get smoothed out, the pseudo volume fraction is set to 1 to + ! make sure that only the current patch contributes to the fluid state in the cells that this patch covers. eta = 1._wp - ! Checking whether the cuboid covers a particular cell in the domain - ! and verifying whether the current patch has permission to write to - ! to that cell. If both queries check out, the primitive variables - ! of the current patch are assigned to this cell. + ! Checking whether the cuboid covers a particular cell in the domain and verifying whether the current patch has permission + ! to write to to that cell. If both queries check out, the primitive variables of the current patch are assigned to this + ! cell. do k = 0, p do j = 0, n do i = 0, m - if (grid_geometry == 3) then call s_convert_cylindrical_to_cartesian_coord(y_cc(j), z_cc(k)) else @@ -1308,17 +1136,10 @@ contains cart_z = z_cc(k) end if - if (x_boundary%beg <= x_cc(i) .and. & - x_boundary%end >= x_cc(i) .and. & - y_boundary%beg <= cart_y .and. & - y_boundary%end >= cart_y .and. & - z_boundary%beg <= cart_z .and. & - z_boundary%end >= cart_z) then - + if (x_boundary%beg <= x_cc(i) .and. x_boundary%end >= x_cc(i) & + & .and. y_boundary%beg <= cart_y .and. y_boundary%end >= cart_y .and. z_boundary%beg <= cart_z .and. z_boundary%end >= cart_z) then if (patch_icpp(patch_id)%alter_patch(patch_id_fp(i, j, k))) then - - call s_assign_patch_primitive_variables(patch_id, i, j, k, & - eta, q_prim_vf, patch_id_fp) + call s_assign_patch_primitive_variables(patch_id, i, j, k, eta, q_prim_vf, patch_id_fp) @:analytical() if (patch_icpp(patch_id)%hcid /= dflt_int) then @@ -1327,7 +1148,6 @@ contains ! Updating the patch identities bookkeeping variable if (1._wp - eta < sgm_eps) patch_id_fp(i, j, k) = patch_id - end if end if end do @@ -1337,34 +1157,30 @@ contains end subroutine s_icpp_cuboid - !> The cylindrical patch is a 3D geometry that may be used, - !! for example, in setting up a cylindrical solid boundary - !! confinement, like a blood vessel. The geometry of this - !! patch is well-defined when the centroid, the radius and - !! the length along the cylinder's axis, parallel to the x-, - !! y- or z-coordinate direction, are provided. Please note - !! that the cylindrical patch DOES allow for the smoothing - !! of its lateral boundary. - !! @param patch_id is the patch identifier - !! @param patch_id_fp Array to track patch ids - !! @param q_prim_vf Array of primitive variables + !> The cylindrical patch is a 3D geometry that may be used, for example, in setting up a cylindrical solid boundary confinement, + !! like a blood vessel. The geometry of this patch is well-defined when the centroid, the radius and the length along the + !! cylinder's axis, parallel to the x-, y- or z-coordinate direction, are provided. Please note that the cylindrical patch DOES + !! allow for the smoothing of its lateral boundary. + !! @param patch_id is the patch identifier + !! @param patch_id_fp Array to track patch ids + !! @param q_prim_vf Array of primitive variables subroutine s_icpp_cylinder(patch_id, patch_id_fp, q_prim_vf) integer, intent(in) :: patch_id + #ifdef MFC_MIXED_PRECISION - integer(kind=1), dimension(0:m, 0:n, 0:p), intent(inout) :: patch_id_fp + integer(kind=1), dimension(0:m,0:n,0:p), intent(inout) :: patch_id_fp #else - integer, dimension(0:m, 0:n, 0:p), intent(inout) :: patch_id_fp + integer, dimension(0:m,0:n,0:p), intent(inout) :: patch_id_fp #endif type(scalar_field), dimension(1:sys_size), intent(inout) :: q_prim_vf - - integer :: i, j, k !< Generic loop iterators - real(wp) :: radius + integer :: i, j, k !< Generic loop iterators + real(wp) :: radius @:HardcodedDimensionsExtrusion() @:Hardcoded3DVariables() - ! Transferring the cylindrical patch's centroid, length, radius, - ! smoothing patch identity and smoothing coefficient information + ! Transferring the cylindrical patch's centroid, length, radius, smoothing patch identity and smoothing coefficient + ! information x_centroid = patch_icpp(patch_id)%x_centroid y_centroid = patch_icpp(patch_id)%y_centroid z_centroid = patch_icpp(patch_id)%z_centroid @@ -1375,8 +1191,7 @@ contains smooth_patch_id = patch_icpp(patch_id)%smooth_patch_id smooth_coeff = patch_icpp(patch_id)%smooth_coeff - ! Computing the beginning and the end x-, y- and z-coordinates of - ! the cylinder based on its centroid and lengths + ! Computing the beginning and the end x-, y- and z-coordinates of the cylinder based on its centroid and lengths x_boundary%beg = x_centroid - 0.5_wp*length_x x_boundary%end = x_centroid + 0.5_wp*length_x y_boundary%beg = y_centroid - 0.5_wp*length_y @@ -1384,19 +1199,16 @@ contains z_boundary%beg = z_centroid - 0.5_wp*length_z z_boundary%end = z_centroid + 0.5_wp*length_z - ! Initializing the pseudo volume fraction value to 1. The value will - ! be modified as the patch is laid out on the grid, but only in the - ! case that smearing of the cylindrical patch's boundary is enabled. + ! Initializing the pseudo volume fraction value to 1. The value will be modified as the patch is laid out on the grid, but + ! only in the case that smearing of the cylindrical patch's boundary is enabled. eta = 1._wp - ! Checking whether the cylinder covers a particular cell in the - ! domain and verifying whether the current patch has the permission - ! to write to that cell. If both queries check out, the primitive - ! variables of the current patch are assigned to this cell. + ! Checking whether the cylinder covers a particular cell in the domain and verifying whether the current patch has the + ! permission to write to that cell. If both queries check out, the primitive variables of the current patch are assigned to + ! this cell. do k = 0, p do j = 0, n do i = 0, m - if (grid_geometry == 3) then call s_convert_cylindrical_to_cartesian_coord(y_cc(j), z_cc(k)) else @@ -1406,45 +1218,29 @@ contains if (patch_icpp(patch_id)%smoothen) then if (.not. f_is_default(length_x)) then - eta = tanh(smooth_coeff/min(dy, dz)* & - (sqrt((cart_y - y_centroid)**2 & - + (cart_z - z_centroid)**2) & - - radius))*(-0.5_wp) + 0.5_wp - elseif (.not. f_is_default(length_y)) then - eta = tanh(smooth_coeff/min(dx, dz)* & - (sqrt((x_cc(i) - x_centroid)**2 & - + (cart_z - z_centroid)**2) & - - radius))*(-0.5_wp) + 0.5_wp + eta = tanh(smooth_coeff/min(dy, & + & dz)*(sqrt((cart_y - y_centroid)**2 + (cart_z - z_centroid)**2) - radius))*(-0.5_wp) & + & + 0.5_wp + else if (.not. f_is_default(length_y)) then + eta = tanh(smooth_coeff/min(dx, & + & dz)*(sqrt((x_cc(i) - x_centroid)**2 + (cart_z - z_centroid)**2) - radius))*(-0.5_wp) & + & + 0.5_wp else - eta = tanh(smooth_coeff/min(dx, dy)* & - (sqrt((x_cc(i) - x_centroid)**2 & - + (cart_y - y_centroid)**2) & - - radius))*(-0.5_wp) + 0.5_wp + eta = tanh(smooth_coeff/min(dx, & + & dy)*(sqrt((x_cc(i) - x_centroid)**2 + (cart_y - y_centroid)**2) - radius))*(-0.5_wp) & + & + 0.5_wp end if end if - if (((.not. f_is_default(length_x) .and. & - (cart_y - y_centroid)**2 & - + (cart_z - z_centroid)**2 <= radius**2 .and. & - x_boundary%beg <= x_cc(i) .and. & - x_boundary%end >= x_cc(i)) & - .or. & - (.not. f_is_default(length_y) .and. & - (x_cc(i) - x_centroid)**2 & - + (cart_z - z_centroid)**2 <= radius**2 .and. & - y_boundary%beg <= cart_y .and. & - y_boundary%end >= cart_y) & - .or. & - (.not. f_is_default(length_z) .and. & - (x_cc(i) - x_centroid)**2 & - + (cart_y - y_centroid)**2 <= radius**2 .and. & - z_boundary%beg <= cart_z .and. & - z_boundary%end >= cart_z) .and. & - patch_icpp(patch_id)%alter_patch(patch_id_fp(i, j, k))) .or. & - patch_id_fp(i, j, k) == smooth_patch_id) then - - call s_assign_patch_primitive_variables(patch_id, i, j, k, & - eta, q_prim_vf, patch_id_fp) + if (((.not. f_is_default(length_x) .and. (cart_y - y_centroid)**2 + (cart_z - z_centroid) & + & **2 <= radius**2 .and. x_boundary%beg <= x_cc(i) .and. x_boundary%end >= x_cc(i)) & + & .or. (.not. f_is_default(length_y) .and. (x_cc(i) - x_centroid)**2 + (cart_z - z_centroid) & + & **2 <= radius**2 .and. y_boundary%beg <= cart_y .and. y_boundary%end >= cart_y) & + & .or. (.not. f_is_default(length_z) .and. (x_cc(i) - x_centroid)**2 + (cart_y - y_centroid) & + & **2 <= radius**2 .and. z_boundary%beg <= cart_z .and. z_boundary%end >= cart_z) & + & .and. patch_icpp(patch_id)%alter_patch(patch_id_fp(i, j, k))) .or. patch_id_fp(i, j, & + & k) == smooth_patch_id) then + call s_assign_patch_primitive_variables(patch_id, i, j, k, eta, q_prim_vf, patch_id_fp) @:analytical() if (patch_icpp(patch_id)%hcid /= dflt_int) then @@ -1461,28 +1257,25 @@ contains end subroutine s_icpp_cylinder - !> The swept plane patch is a 3D geometry that may be used, - !! for example, in creating a solid boundary, or pre-/post- - !! shock region, at an angle with respect to the axes of the - !! Cartesian coordinate system. The geometry of the patch is - !! well-defined when its centroid and normal vector, aimed - !! in the sweep direction, are provided. Note that the sweep - !! plane patch DOES allow the smoothing of its boundary. - !! @param patch_id is the patch identifier - !! @param patch_id_fp Array to track patch ids - !! @param q_prim_vf Primitive variables + !> The swept plane patch is a 3D geometry that may be used, for example, in creating a solid boundary, or pre-/post- shock + !! region, at an angle with respect to the axes of the Cartesian coordinate system. The geometry of the patch is well-defined + !! when its centroid and normal vector, aimed in the sweep direction, are provided. Note that the sweep plane patch DOES allow + !! the smoothing of its boundary. + !! @param patch_id is the patch identifier + !! @param patch_id_fp Array to track patch ids + !! @param q_prim_vf Primitive variables subroutine s_icpp_sweep_plane(patch_id, patch_id_fp, q_prim_vf) integer, intent(in) :: patch_id + #ifdef MFC_MIXED_PRECISION - integer(kind=1), dimension(0:m, 0:n, 0:p), intent(inout) :: patch_id_fp + integer(kind=1), dimension(0:m,0:n,0:p), intent(inout) :: patch_id_fp #else - integer, dimension(0:m, 0:n, 0:p), intent(inout) :: patch_id_fp + integer, dimension(0:m,0:n,0:p), intent(inout) :: patch_id_fp #endif type(scalar_field), dimension(1:sys_size), intent(inout) :: q_prim_vf - - integer :: i, j, k !< Generic loop iterators - real(wp) :: a, b, c, d + integer :: i, j, k !< Generic loop iterators + real(wp) :: a, b, c, d @:HardcodedDimensionsExtrusion() @:Hardcoded3DVariables() @@ -1499,19 +1292,16 @@ contains c = patch_icpp(patch_id)%normal(3) d = -a*x_centroid - b*y_centroid - c*z_centroid - ! Initializing the pseudo volume fraction value to 1. The value will - ! be modified as the patch is laid out on the grid, but only in the - ! case that smearing of the sweep plane patch's boundary is enabled. + ! Initializing the pseudo volume fraction value to 1. The value will be modified as the patch is laid out on the grid, but + ! only in the case that smearing of the sweep plane patch's boundary is enabled. eta = 1._wp - ! Checking whether the region swept by the plane covers a particular - ! cell in the domain and verifying whether the current patch has the - ! permission to write to that cell. If both queries check out, the - ! primitive variables of the current patch are written to this cell. + ! Checking whether the region swept by the plane covers a particular cell in the domain and verifying whether the current + ! patch has the permission to write to that cell. If both queries check out, the primitive variables of the current patch + ! are written to this cell. do k = 0, p do j = 0, n do i = 0, m - if (grid_geometry == 3) then call s_convert_cylindrical_to_cartesian_coord(y_cc(j), z_cc(k)) else @@ -1520,22 +1310,13 @@ contains end if if (patch_icpp(patch_id)%smoothen) then - eta = 5.e-1_wp + 5.e-1_wp*tanh(smooth_coeff/min(dx, dy, dz) & - *(a*x_cc(i) + & - b*cart_y + & - c*cart_z + d) & - /sqrt(a**2 + b**2 + c**2)) + eta = 5.e-1_wp + 5.e-1_wp*tanh(smooth_coeff/min(dx, dy, & + & dz)*(a*x_cc(i) + b*cart_y + c*cart_z + d)/sqrt(a**2 + b**2 + c**2)) end if - if ((a*x_cc(i) + b*cart_y + c*cart_z + d >= 0._wp & - .and. & - patch_icpp(patch_id)%alter_patch(patch_id_fp(i, j, k))) & - .or. & - patch_id_fp(i, j, k) == smooth_patch_id) & - then - - call s_assign_patch_primitive_variables(patch_id, i, j, k, & - eta, q_prim_vf, patch_id_fp) + if ((a*x_cc(i) + b*cart_y + c*cart_z + d >= 0._wp .and. patch_icpp(patch_id)%alter_patch(patch_id_fp(i, j, & + & k))) .or. patch_id_fp(i, j, k) == smooth_patch_id) then + call s_assign_patch_primitive_variables(patch_id, i, j, k, eta, q_prim_vf, patch_id_fp) @:analytical() if (patch_icpp(patch_id)%hcid /= dflt_int) then @@ -1545,7 +1326,6 @@ contains ! Updating the patch identities bookkeeping variable if (1._wp - eta < sgm_eps) patch_id_fp(i, j, k) = patch_id end if - end do end do end do @@ -1560,37 +1340,32 @@ contains subroutine s_icpp_model(patch_id, patch_id_fp, q_prim_vf) integer, intent(in) :: patch_id + #ifdef MFC_MIXED_PRECISION - integer(kind=1), dimension(0:m, 0:n, 0:p), intent(inout) :: patch_id_fp + integer(kind=1), dimension(0:m,0:n,0:p), intent(inout) :: patch_id_fp #else - integer, dimension(0:m, 0:n, 0:p), intent(inout) :: patch_id_fp + integer, dimension(0:m,0:n,0:p), intent(inout) :: patch_id_fp #endif type(scalar_field), dimension(1:sys_size), intent(inout) :: q_prim_vf ! Variables for IBM+STL - real(wp) :: normals(1:3) !< Boundary normal buffer - integer :: boundary_vertex_count, boundary_edge_count, total_vertices !< Boundary vertex - real(wp), allocatable, dimension(:, :, :) :: boundary_v !< Boundary vertex buffer - real(wp) :: distance !< Levelset distance buffer - logical :: interpolate !< Logical variable to determine whether or not the model should be interpolated - - integer :: i, j, k !< Generic loop iterators - + real(wp) :: normals(1:3) !< Boundary normal buffer + integer :: boundary_vertex_count, boundary_edge_count, total_vertices !< Boundary vertex + real(wp), allocatable, dimension(:,:,:) :: boundary_v !< Boundary vertex buffer + real(wp) :: distance !< Levelset distance buffer + logical :: interpolate !< Logical variable to determine whether or not the model should be interpolated + integer :: i, j, k !< Generic loop iterators type(t_bbox) :: bbox, bbox_old type(t_model) :: model type(ic_model_parameters) :: params - real(wp), dimension(1:3) :: point, model_center - - real(wp) :: grid_mm(1:3, 1:2) - + real(wp) :: grid_mm(1:3,1:2) integer :: cell_num integer :: ncells - - real(wp), dimension(1:4, 1:4) :: transform, transform_n + real(wp), dimension(1:4,1:4) :: transform, transform_n if (proc_rank == 0) then - print *, " * Reading model: "//trim(patch_icpp(patch_id)%model_filepath) + print *, " * Reading model: " // trim(patch_icpp(patch_id)%model_filepath) end if model = f_model_read(patch_icpp(patch_id)%model_filepath) @@ -1634,57 +1409,51 @@ contains write (*, "(A, 3(2X, F20.10))") " > Cen:", (bbox%min(1:3) + bbox%max(1:3))/2._wp write (*, "(A, 3(2X, F20.10))") " > Max:", bbox%max(1:3) - !call s_model_write("__out__.stl", model) - !call s_model_write("__out__.obj", model) + ! call s_model_write("__out__.stl", model) call s_model_write("__out__.obj", model) - grid_mm(1, :) = (/minval(x_cc) - 0.e5_wp*dx, maxval(x_cc) + 0.e5_wp*dx/) - grid_mm(2, :) = (/minval(y_cc) - 0.e5_wp*dy, maxval(y_cc) + 0.e5_wp*dy/) + grid_mm(1,:) = (/minval(x_cc) - 0.e5_wp*dx, maxval(x_cc) + 0.e5_wp*dx/) + grid_mm(2,:) = (/minval(y_cc) - 0.e5_wp*dy, maxval(y_cc) + 0.e5_wp*dy/) if (p > 0) then - grid_mm(3, :) = (/minval(z_cc) - 0.e5_wp*dz, maxval(z_cc) + 0.e5_wp*dz/) + grid_mm(3,:) = (/minval(z_cc) - 0.e5_wp*dz, maxval(z_cc) + 0.e5_wp*dz/) else - grid_mm(3, :) = (/0._wp, 0._wp/) + grid_mm(3,:) = (/0._wp, 0._wp/) end if - write (*, "(A, 3(2X, F20.10))") " > Domain: Min:", grid_mm(:, 1) - write (*, "(A, 3(2X, F20.10))") " > Cen:", (grid_mm(:, 1) + grid_mm(:, 2))/2._wp - write (*, "(A, 3(2X, F20.10))") " > Max:", grid_mm(:, 2) + write (*, "(A, 3(2X, F20.10))") " > Domain: Min:", grid_mm(:,1) + write (*, "(A, 3(2X, F20.10))") " > Cen:", (grid_mm(:,1) + grid_mm(:,2))/2._wp + write (*, "(A, 3(2X, F20.10))") " > Max:", grid_mm(:,2) end if ncells = (m + 1)*(n + 1)*(p + 1) do i = 0, m; do j = 0, n; do k = 0, p + cell_num = i*(n + 1)*(p + 1) + j*(p + 1) + (k + 1) + if (proc_rank == 0 .and. mod(cell_num, ncells/100) == 0) then + write (*, "(A, I3, A)", advance="no") char(13) // " * Generating grid: ", nint(100*real(cell_num)/ncells), "%" + end if - cell_num = i*(n + 1)*(p + 1) + j*(p + 1) + (k + 1) - if (proc_rank == 0 .and. mod(cell_num, ncells/100) == 0) then - write (*, "(A, I3, A)", advance="no") & - char(13)//" * Generating grid: ", & - nint(100*real(cell_num)/ncells), "%" - end if - - point = (/x_cc(i), y_cc(j), 0._wp/) - if (p > 0) then - point(3) = z_cc(k) - end if + point = (/x_cc(i), y_cc(j), 0._wp/) + if (p > 0) then + point(3) = z_cc(k) + end if - if (grid_geometry == 3) then - point = f_convert_cyl_to_cart(point) - end if + if (grid_geometry == 3) then + point = f_convert_cyl_to_cart(point) + end if - eta = f_model_is_inside(model, point, (/dx, dy, dz/), patch_icpp(patch_id)%model_spc) + eta = f_model_is_inside(model, point, (/dx, dy, dz/), patch_icpp(patch_id)%model_spc) - if (eta > patch_icpp(patch_id)%model_threshold) then - eta = 1._wp - else if (.not. patch_icpp(patch_id)%smoothen) then - eta = 0._wp - end if + if (eta > patch_icpp(patch_id)%model_threshold) then + eta = 1._wp + else if (.not. patch_icpp(patch_id)%smoothen) then + eta = 0._wp + end if - call s_assign_patch_primitive_variables(patch_id, i, j, k, & - eta, q_prim_vf, patch_id_fp) + call s_assign_patch_primitive_variables(patch_id, i, j, k, eta, q_prim_vf, patch_id_fp) - ! Note: Should probably use *eta* to compute primitive variables - ! if defining them analytically. - @:analytical() - end do; end do; end do + ! Note: Should probably use *eta* to compute primitive variables if defining them analytically. + @:analytical() + end do; end do; end do if (proc_rank == 0) then print *, "" @@ -1697,6 +1466,7 @@ contains !> @brief Converts cylindrical (r, theta) coordinates to Cartesian (y, z) module variables. subroutine s_convert_cylindrical_to_cartesian_coord(cyl_y, cyl_z) + $:GPU_ROUTINE(parallelism='[seq]') real(wp), intent(in) :: cyl_y, cyl_z @@ -1712,19 +1482,18 @@ contains $:GPU_ROUTINE(parallelism='[seq]') real(wp), dimension(1:3), intent(in) :: cyl - real(wp), dimension(1:3) :: cart + real(wp), dimension(1:3) :: cart - cart = (/cyl(1), & - cyl(2)*sin(cyl(3)), & - cyl(2)*cos(cyl(3))/) + cart = (/cyl(1), cyl(2)*sin(cyl(3)), cyl(2)*cos(cyl(3))/) end function f_convert_cyl_to_cart !> @brief Computes the spherical azimuthal angle from cylindrical (x, r) coordinates. subroutine s_convert_cylindrical_to_spherical_coord(cyl_x, cyl_y) + $:GPU_ROUTINE(parallelism='[seq]') - real(wp), intent(IN) :: cyl_x, cyl_y + real(wp), intent(in) :: cyl_x, cyl_y sph_phi = atan(cyl_y/cyl_x) @@ -1738,13 +1507,14 @@ contains $:GPU_ROUTINE(parallelism='[seq]') real(wp), intent(in) :: myth, offset, a - real(wp) :: b - real(wp) :: f_r + real(wp) :: b + real(wp) :: f_r - !r(th) = a + b*th + ! r(th) = a + b*th b = 2._wp*a/(2._wp*pi) f_r = a + b*myth + offset + end function f_r end module m_icpp_patches diff --git a/src/pre_process/m_initial_condition.fpp b/src/pre_process/m_initial_condition.fpp index 45ad160af0..f591798fe2 100644 --- a/src/pre_process/m_initial_condition.fpp +++ b/src/pre_process/m_initial_condition.fpp @@ -5,104 +5,82 @@ !> @brief Assembles initial conditions by layering prioritized patches via constructive solid geometry module m_initial_condition - use m_derived_types ! Definitions of the derived types - - use m_global_parameters ! Global parameters for the code - - use m_mpi_proxy !< Message passing interface (MPI) module proxy - + use m_derived_types ! Definitions of the derived types + use m_global_parameters ! Global parameters for the code + use m_mpi_proxy !< Message passing interface (MPI) module proxy use m_helper - use m_variables_conversion ! Subroutines to change the state variables from ! one form to another use m_icpp_patches - use m_assign_variables - - use m_perturbation ! Subroutines to perturb initial flow fields - + use m_perturbation ! Subroutines to perturb initial flow fields use m_chemistry - use m_boundary_conditions implicit none - ! NOTE: The abstract interface allows for the declaration of a pointer to - ! a procedure such that the choice of the model equations does not have to - ! be queried every time the patch primitive variables are to be assigned in - ! a cell in the computational domain. - type(scalar_field), allocatable, dimension(:) :: q_prim_vf !< primitive variables - - type(scalar_field), allocatable, dimension(:) :: q_cons_vf !< conservative variables - - type(scalar_field) :: q_T_sf !< Temperature field - - type(integer_field), dimension(:, :), allocatable :: bc_type !< bc_type fields + ! NOTE: The abstract interface allows for the declaration of a pointer to a procedure such that the choice of the model + ! equations does not have to be queried every time the patch primitive variables are to be assigned in a cell in the + ! computational domain. + type(scalar_field), allocatable, dimension(:) :: q_prim_vf !< primitive variables + type(scalar_field), allocatable, dimension(:) :: q_cons_vf !< conservative variables + type(scalar_field) :: q_T_sf !< Temperature field + type(integer_field), dimension(:,:), allocatable :: bc_type !< bc_type fields -!> @cond + !> @cond #ifdef MFC_MIXED_PRECISION - integer(kind=1), allocatable, dimension(:, :, :) :: patch_id_fp + integer(kind=1), allocatable, dimension(:,:,:) :: patch_id_fp #else -!> @endcond - integer, allocatable, dimension(:, :, :) :: patch_id_fp -!> @cond + !> @endcond + integer, allocatable, dimension(:,:,:) :: patch_id_fp + !> @cond #endif -!> @endcond + !> @endcond contains - !> Computation of parameters, allocation procedures, and/or - !! any other tasks needed to properly setup the module + !> Computation of parameters, allocation procedures, and/or any other tasks needed to properly setup the module impure subroutine s_initialize_initial_condition_module - integer :: i, j, k, l !< generic loop iterators + integer :: i, j, k, l !< generic loop iterators ! Allocating the primitive and conservative variables + allocate (q_prim_vf(1:sys_size)) allocate (q_cons_vf(1:sys_size)) do i = 1, sys_size - allocate (q_prim_vf(i)%sf(idwbuff(1)%beg:idwbuff(1)%end, & - idwbuff(2)%beg:idwbuff(2)%end, & - idwbuff(3)%beg:idwbuff(3)%end)) - allocate (q_cons_vf(i)%sf(idwbuff(1)%beg:idwbuff(1)%end, & - idwbuff(2)%beg:idwbuff(2)%end, & - idwbuff(3)%beg:idwbuff(3)%end)) + allocate (q_prim_vf(i)%sf(idwbuff(1)%beg:idwbuff(1)%end,idwbuff(2)%beg:idwbuff(2)%end,idwbuff(3)%beg:idwbuff(3)%end)) + allocate (q_cons_vf(i)%sf(idwbuff(1)%beg:idwbuff(1)%end,idwbuff(2)%beg:idwbuff(2)%end,idwbuff(3)%beg:idwbuff(3)%end)) end do if (chemistry) then - allocate (q_T_sf%sf(0:m, 0:n, 0:p)) + allocate (q_T_sf%sf(0:m,0:n,0:p)) end if ! Allocating the patch identities bookkeeping variable - allocate (patch_id_fp(0:m, 0:n, 0:p)) + allocate (patch_id_fp(0:m,0:n,0:p)) if (qbmm .and. .not. polytropic) then - !Allocate bubble pressure pb and vapor mass mv for non-polytropic qbmm at all quad nodes and R0 bins - allocate (pb%sf(0:m, & - 0:n, & - 0:p, 1:nnode, 1:nb)) - allocate (mv%sf(0:m, & - 0:n, & - 0:p, 1:nnode, 1:nb)) + ! Allocate bubble pressure pb and vapor mass mv for non-polytropic qbmm at all quad nodes and R0 bins + allocate (pb%sf(0:m,0:n,0:p,1:nnode,1:nb)) + allocate (mv%sf(0:m,0:n,0:p,1:nnode,1:nb)) end if - ! Setting default values for conservative and primitive variables so - ! that in the case that the initial condition is wrongly laid out on - ! the grid the simulation component will catch the problem on start- - ! up. The conservative variables do not need to be similarly treated - ! since they are computed directly from the primitive variables. + ! Setting default values for conservative and primitive variables so that in the case that the initial condition is wrongly + ! laid out on the grid the simulation component will catch the problem on start- up. The conservative variables do not need + ! to be similarly treated since they are computed directly from the primitive variables. do i = 1, sys_size - q_cons_vf(i)%sf = -1.e-6_stp ! real(dflt_real, kind=stp) ! TODO :: remove this magic number - q_prim_vf(i)%sf = -1.e-6_stp ! real(dflt_real, kind=stp) + q_cons_vf(i)%sf = -1.e-6_stp ! real(dflt_real, kind=stp) ! TODO :: remove this magic number + q_prim_vf(i)%sf = -1.e-6_stp ! real(dflt_real, kind=stp) end do ! Allocating arrays to store the bc types - allocate (bc_type(1:num_dims, 1:2)) + allocate (bc_type(1:num_dims,1:2)) - allocate (bc_type(1, 1)%sf(0:0, 0:n, 0:p)) - allocate (bc_type(1, 2)%sf(0:0, 0:n, 0:p)) + allocate (bc_type(1, 1)%sf(0:0,0:n,0:p)) + allocate (bc_type(1, 2)%sf(0:0,0:n,0:p)) do l = 0, p do k = 0, n @@ -112,8 +90,8 @@ contains end do if (n > 0) then - allocate (bc_type(2, 1)%sf(-buff_size:m + buff_size, 0:0, 0:p)) - allocate (bc_type(2, 2)%sf(-buff_size:m + buff_size, 0:0, 0:p)) + allocate (bc_type(2, 1)%sf(-buff_size:m + buff_size,0:0,0:p)) + allocate (bc_type(2, 2)%sf(-buff_size:m + buff_size,0:0,0:p)) do l = 0, p do j = -buff_size, m + buff_size @@ -123,8 +101,8 @@ contains end do if (p > 0) then - allocate (bc_type(3, 1)%sf(-buff_size:m + buff_size, -buff_size:n + buff_size, 0:0)) - allocate (bc_type(3, 2)%sf(-buff_size:m + buff_size, -buff_size:n + buff_size, 0:0)) + allocate (bc_type(3, 1)%sf(-buff_size:m + buff_size,-buff_size:n + buff_size,0:0)) + allocate (bc_type(3, 2)%sf(-buff_size:m + buff_size,-buff_size:n + buff_size,0:0)) do k = -buff_size, n + buff_size do j = -buff_size, m + buff_size @@ -141,38 +119,31 @@ contains q_prim_vf(damage_idx)%sf = 0._wp end if - ! Initial hyper_cleaning state is always zero - ! TODO more general + ! Initial hyper_cleaning state is always zero TODO more general if (hyper_cleaning) then q_cons_vf(psi_idx)%sf = 0._wp q_prim_vf(psi_idx)%sf = 0._wp end if - ! Setting default values for patch identities bookkeeping variable. - ! This is necessary to avoid any confusion in the assessment of the - ! extent of application that the overwrite permissions give a patch - ! when it is being applied in the domain. + ! Setting default values for patch identities bookkeeping variable. This is necessary to avoid any confusion in the + ! assessment of the extent of application that the overwrite permissions give a patch when it is being applied in the + ! domain. patch_id_fp = 0 end subroutine s_initialize_initial_condition_module - !> This subroutine peruses the patches and depending on the - !! type of geometry associated with a particular patch, it - !! calls the related subroutine to setup the said geometry - !! on the grid using the primitive variables included with - !! the patch parameters. The subroutine is complete once the - !! primitive variables are converted to conservative ones. + !> This subroutine peruses the patches and depending on the type of geometry associated with a particular patch, it calls the + !! related subroutine to setup the said geometry on the grid using the primitive variables included with the patch parameters. + !! The subroutine is complete once the primitive variables are converted to conservative ones. impure subroutine s_generate_initial_condition integer :: i - ! Converting the conservative variables to the primitive ones given - ! preexisting initial condition data files were read in on start-up + ! Converting the conservative variables to the primitive ones given preexisting initial condition data files were read in on + ! start-up + if (old_ic) then - call s_convert_conservative_to_primitive_variables(q_cons_vf, & - q_T_sf, & - q_prim_vf, & - idwbuff) + call s_convert_conservative_to_primitive_variables(q_cons_vf, q_T_sf, q_prim_vf, idwbuff) end if call s_apply_icpp_patches(patch_id_fp, q_prim_vf) @@ -191,19 +162,20 @@ contains if (chemistry) call s_compute_T_from_primitives(q_T_sf, q_prim_vf, idwint) if (qbmm .and. .not. polytropic) then - !Initialize pb and mv + ! Initialize pb and mv call s_initialize_mv(q_cons_vf, mv%sf) call s_initialize_pb(q_cons_vf, mv%sf, pb%sf) end if end subroutine s_generate_initial_condition - !> Deallocation procedures for the module + !> Deallocation procedures for the module impure subroutine s_finalize_initial_condition_module - integer :: i !< Generic loop iterator + integer :: i !< Generic loop iterator ! Dellocating the primitive and conservative variables + do i = 1, sys_size deallocate (q_prim_vf(i)%sf) deallocate (q_cons_vf(i)%sf) diff --git a/src/pre_process/m_mpi_proxy.fpp b/src/pre_process/m_mpi_proxy.fpp index d1db67180a..1fe5d54b6d 100644 --- a/src/pre_process/m_mpi_proxy.fpp +++ b/src/pre_process/m_mpi_proxy.fpp @@ -6,29 +6,22 @@ module m_mpi_proxy #ifdef MFC_MPI - use mpi !< Message passing interface (MPI) module + use mpi !< Message passing interface (MPI) module #endif use m_helper - - use m_derived_types !< Definitions of the derived types - - use m_global_parameters !< Global parameters for the code - + use m_derived_types !< Definitions of the derived types + use m_global_parameters !< Global parameters for the code use m_mpi_common implicit none contains - !> Since only processor with rank 0 is in charge of reading - !! and checking the consistency of the user provided inputs, - !! these are not available to the remaining processors. This - !! subroutine is then in charge of broadcasting the required - !! information. + !> Since only processor with rank 0 is in charge of reading and checking the consistency of the user provided inputs, these are + !! not available to the remaining processors. This subroutine is then in charge of broadcasting the required information. impure subroutine s_mpi_bcast_user_inputs #ifdef MFC_MPI - ! Generic loop iterator integer :: i, j ! Generic flag used to identify and report MPI errors @@ -122,8 +115,8 @@ contains if (chemistry) then call MPI_BCAST(patch_icpp(i)%Y, size(patch_icpp(i)%Y), mpi_p, 0, MPI_COMM_WORLD, ierr) end if - ! Broadcast IB variables: patch_ib is indexed 1:num_patches_max, - ! not 1:num_bc_patches_max, so these must live in the num_patches_max loop. + ! Broadcast IB variables: patch_ib is indexed 1:num_patches_max, not 1:num_bc_patches_max, so these must live in the + ! num_patches_max loop. #:for VAR in ['vel', 'angular_vel', 'angles'] call MPI_BCAST(patch_ib(i)%${VAR}$, size(patch_ib(i)%${VAR}$), mpi_p, 0, MPI_COMM_WORLD, ierr) #:endfor @@ -183,7 +176,6 @@ contains call MPI_BCAST(simplex_params%perturb_vel_offset(i, j), 1, mpi_p, 0, MPI_COMM_WORLD, ierr) end do end do - #endif end subroutine s_mpi_bcast_user_inputs diff --git a/src/pre_process/m_perturbation.fpp b/src/pre_process/m_perturbation.fpp index 2093ea30dd..ffc5633b82 100644 --- a/src/pre_process/m_perturbation.fpp +++ b/src/pre_process/m_perturbation.fpp @@ -5,23 +5,17 @@ !> @brief Perturbs initial mean flow fields with random noise, mixing-layer instabilities, or simplex noise module m_perturbation - use m_derived_types ! Definitions of the derived types - - use m_global_parameters ! Global parameters for the code - - use m_mpi_proxy !< Message passing interface (MPI) module proxy - - use m_boundary_common ! Boundary conditions module - + use m_derived_types ! Definitions of the derived types + use m_global_parameters ! Global parameters for the code + use m_mpi_proxy !< Message passing interface (MPI) module proxy + use m_boundary_common ! Boundary conditions module use m_helper - use m_simplex_noise - use ieee_arithmetic implicit none - real(wp), allocatable, dimension(:, :, :, :) :: q_prim_temp + real(wp), allocatable, dimension(:,:,:,:) :: q_prim_temp contains @@ -29,19 +23,19 @@ contains impure subroutine s_initialize_perturbation_module() if (elliptic_smoothing) then - allocate (q_prim_temp(0:m, 0:n, 0:p, 1:sys_size)) + allocate (q_prim_temp(0:m,0:n,0:p,1:sys_size)) end if end subroutine s_initialize_perturbation_module !> @brief Randomly perturbs partial density fields at the interface of a spherical volume fraction region. impure subroutine s_perturb_sphere(q_prim_vf) - type(scalar_field), dimension(sys_size), intent(inout) :: q_prim_vf - integer :: i, j, k, l !< generic loop operators - real(wp) :: perturb_alpha + type(scalar_field), dimension(sys_size), intent(inout) :: q_prim_vf + integer :: i, j, k, l !< generic loop operators + real(wp) :: perturb_alpha + real(wp) :: rand_real - real(wp) :: rand_real call random_seed() do k = 0, p @@ -51,15 +45,13 @@ contains perturb_alpha = q_prim_vf(E_idx + perturb_sph_fluid)%sf(i, j, k) - ! Perturb partial density fields to match perturbed volume fraction fields - ! IF ((perturb_alpha >= 25e-2_wp) .AND. (perturb_alpha <= 75e-2_wp)) THEN + ! Perturb partial density fields to match perturbed volume fraction fields IF ((perturb_alpha >= 25e-2_wp) .AND. + ! (perturb_alpha <= 75e-2_wp)) THEN if ((.not. f_approx_equal(perturb_alpha, 0._wp)) .and. (.not. f_approx_equal(perturb_alpha, 1._wp))) then - ! Derive new partial densities do l = 1, num_fluids q_prim_vf(l)%sf(i, j, k) = q_prim_vf(E_idx + l)%sf(i, j, k)*fluid_rho(l) end do - end if end do end do @@ -69,11 +61,12 @@ contains !> @brief Adds random noise to the velocity and void fraction of the surrounding flow field. impure subroutine s_perturb_surrounding_flow(q_prim_vf) + type(scalar_field), dimension(sys_size), intent(inout) :: q_prim_vf - integer :: i, j, k !< generic loop iterators + integer :: i, j, k !< generic loop iterators + real(wp) :: perturb_alpha + real(wp) :: rand_real - real(wp) :: perturb_alpha - real(wp) :: rand_real call random_seed() ! Perturb partial density or velocity of surrounding flow by some random small amount of noise @@ -91,17 +84,17 @@ contains end do end do end do + end subroutine s_perturb_surrounding_flow !> @brief Iteratively smooths all primitive variable fields using a discrete elliptic (Laplacian) filter. impure subroutine s_elliptic_smoothing(q_prim_vf, bc_type) - type(scalar_field), dimension(sys_size), intent(inout) :: q_prim_vf - type(integer_field), dimension(1:num_dims, 1:2), intent(in) :: bc_type - integer :: i, j, k, l, q + type(scalar_field), dimension(sys_size), intent(inout) :: q_prim_vf + type(integer_field), dimension(1:num_dims,1:2), intent(in) :: bc_type + integer :: i, j, k, l, q do q = 1, elliptic_smoothing_iters - ! Communication of buffer regions and apply boundary conditions call s_populate_variables_buffers(bc_type, q_prim_vf, pb%sf, mv%sf) @@ -109,19 +102,17 @@ contains if (n == 0) then do j = 0, m do i = 1, sys_size - q_prim_temp(j, 0, 0, i) = (1._wp/4._wp)* & - (q_prim_vf(i)%sf(j + 1, 0, 0) + q_prim_vf(i)%sf(j - 1, 0, 0) + & - 2._wp*q_prim_vf(i)%sf(j, 0, 0)) + q_prim_temp(j, 0, 0, i) = (1._wp/4._wp)*(q_prim_vf(i)%sf(j + 1, 0, 0) + q_prim_vf(i)%sf(j - 1, 0, & + & 0) + 2._wp*q_prim_vf(i)%sf(j, 0, 0)) end do end do else if (p == 0) then do k = 0, n do j = 0, m do i = 1, sys_size - q_prim_temp(j, k, 0, i) = (1._wp/8._wp)* & - (q_prim_vf(i)%sf(j + 1, k, 0) + q_prim_vf(i)%sf(j - 1, k, 0) + & - q_prim_vf(i)%sf(j, k + 1, 0) + q_prim_vf(i)%sf(j, k - 1, 0) + & - 4._wp*q_prim_vf(i)%sf(j, k, 0)) + q_prim_temp(j, k, 0, i) = (1._wp/8._wp)*(q_prim_vf(i)%sf(j + 1, k, 0) + q_prim_vf(i)%sf(j - 1, k, & + & 0) + q_prim_vf(i)%sf(j, k + 1, 0) + q_prim_vf(i)%sf(j, k - 1, & + & 0) + 4._wp*q_prim_vf(i)%sf(j, k, 0)) end do end do end do @@ -130,11 +121,10 @@ contains do k = 0, n do j = 0, m do i = 1, sys_size - q_prim_temp(j, k, l, i) = (1._wp/12._wp)* & - (q_prim_vf(i)%sf(j + 1, k, l) + q_prim_vf(i)%sf(j - 1, k, l) + & - q_prim_vf(i)%sf(j, k + 1, l) + q_prim_vf(i)%sf(j, k - 1, l) + & - q_prim_vf(i)%sf(j, k, l + 1) + q_prim_vf(i)%sf(j, k, l - 1) + & - 6._wp*q_prim_vf(i)%sf(j, k, l)) + q_prim_temp(j, k, l, i) = (1._wp/12._wp)*(q_prim_vf(i)%sf(j + 1, k, l) + q_prim_vf(i)%sf(j - 1, & + & k, l) + q_prim_vf(i)%sf(j, k + 1, l) + q_prim_vf(i)%sf(j, k - 1, & + & l) + q_prim_vf(i)%sf(j, k, l + 1) + q_prim_vf(i)%sf(j, k, & + & l - 1) + 6._wp*q_prim_vf(i)%sf(j, k, l)) end do end do end do @@ -159,12 +149,11 @@ contains subroutine s_perturb_simplex(q_prim_vf) type(scalar_field), dimension(sys_size), intent(inout) :: q_prim_vf - real(wp) :: mag, freq, scale, vel_rsm - real(wp), dimension(:, :), allocatable :: ofs - integer :: nOffsets - real(wp) :: xl, yl, zl - - integer :: i, j, k, l, q + real(wp) :: mag, freq, scale, vel_rsm + real(wp), dimension(:,:), allocatable :: ofs + integer :: nOffsets + real(wp) :: xl, yl, zl + integer :: i, j, k, l, q nOffsets = max(num_dims, num_fluids) @@ -189,7 +178,7 @@ contains yl = freq*(y_cc(k) + ofs(i, 2)) if (num_dims == 2) then mag = f_simplex2d(xl, yl) - elseif (num_dims == 3) then + else if (num_dims == 3) then zl = freq*(z_cc(l) + ofs(i, 3)) mag = f_simplex3d(xl, yl, zl) end if @@ -200,8 +189,7 @@ contains end do vel_rsm = sqrt(vel_rsm) - q_prim_vf(momxb + i - 1)%sf(j, k, l) = q_prim_vf(momxb + i - 1)%sf(j, k, l) + & - vel_rsm*scale*mag + q_prim_vf(momxb + i - 1)%sf(j, k, l) = q_prim_vf(momxb + i - 1)%sf(j, k, l) + vel_rsm*scale*mag end do end do end do @@ -227,12 +215,12 @@ contains yl = freq*(y_cc(k) + ofs(i, 2)) if (num_dims == 2) then mag = f_simplex2d(xl, yl) - elseif (num_dims == 3) then + else if (num_dims == 3) then zl = freq*(z_cc(l) + ofs(i, 3)) mag = f_simplex3d(xl, yl, zl) end if - q_prim_vf(contxb + i - 1)%sf(j, k, l) = q_prim_vf(contxb + i - 1)%sf(j, k, l) + & - q_prim_vf(contxb + i - 1)%sf(j, k, l)*scale*mag + q_prim_vf(contxb + i - 1)%sf(j, k, l) = q_prim_vf(contxb + i - 1)%sf(j, k, & + & l) + q_prim_vf(contxb + i - 1)%sf(j, k, l)*scale*mag end do end do end do @@ -243,20 +231,20 @@ contains end subroutine s_perturb_simplex - !> This subroutine computes velocity perturbations for a temporal mixing - !! layer with a hyperbolic tangent mean streamwise velocity - !! profile, using an inverted version of the spectrum-based - !! synthetic turbulence generation method proposed by - !! Guo et al. (2023, JFM). + !> This subroutine computes velocity perturbations for a temporal mixing layer with a hyperbolic tangent mean streamwise + !! velocity profile, using an inverted version of the spectrum-based synthetic turbulence generation method proposed by Guo et + !! al. (2023, JFM). subroutine s_perturb_mixlayer(q_prim_vf) + type(scalar_field), dimension(sys_size), intent(inout) :: q_prim_vf - real(wp), dimension(mixlayer_perturb_nk) :: k, Ek - real(wp), dimension(3, 3) :: Rij, Lmat - real(wp), dimension(3) :: velfluc, sig_tmp, sig, khat, xi - real(wp) :: dk, alpha, Eksum, q, uu0, phi - integer :: i, j, l, r, ierr + real(wp), dimension(mixlayer_perturb_nk) :: k, Ek + real(wp), dimension(3, 3) :: Rij, Lmat + real(wp), dimension(3) :: velfluc, sig_tmp, sig, khat, xi + real(wp) :: dk, alpha, Eksum, q, uu0, phi + integer :: i, j, l, r, ierr ! Initialize parameters + dk = 1._wp/mixlayer_perturb_nk ! Compute prescribed energy spectra @@ -269,11 +257,9 @@ contains ! Main loop do r = 0, n - ! Compute prescribed Reynolds stress tensor with about half - ! magnitude of its self-similar value - Rij(:, :) = 0._wp - uu0 = patch_icpp(1)%vel(1)**2._wp & - *(1._wp - tanh(y_cc(r)*mixlayer_vel_coef)**2._wp) + ! Compute prescribed Reynolds stress tensor with about half magnitude of its self-similar value + Rij(:,:) = 0._wp + uu0 = patch_icpp(1)%vel(1)**2._wp*(1._wp - tanh(y_cc(r)*mixlayer_vel_coef)**2._wp) Rij(1, 1) = 0.05_wp*uu0 Rij(2, 2) = 0.03_wp*uu0 Rij(3, 3) = 0.03_wp*uu0 @@ -293,8 +279,7 @@ contains ! Compute perturbation for each Fourier component do i = 1, mixlayer_perturb_nk - ! Generate random numbers for unit wavevector khat, - ! random unit vector xi, and random mode phase phi + ! Generate random numbers for unit wavevector khat, random unit vector xi, and random mode phase phi if (proc_rank == 0) then call s_generate_random_perturbation(khat, xi, phi, i, y_cc(r)) end if @@ -329,12 +314,13 @@ contains !> @brief Generates deterministic pseudo-random wave vector, polarization, and phase for a perturbation mode. subroutine s_generate_random_perturbation(khat, xi, phi, ik, yloc) - integer, intent(in) :: ik - real(wp), intent(in) :: yloc + + integer, intent(in) :: ik + real(wp), intent(in) :: yloc real(wp), dimension(3), intent(out) :: khat, xi - real(wp), intent(out) :: phi - real(wp) :: theta, eta - integer :: seed, kfac, yfac + real(wp), intent(out) :: phi + real(wp) :: theta, eta + integer :: seed, kfac, yfac kfac = ik*amplifier yfac = nint((sin(yloc) + 1._wp)*amplifier) @@ -354,8 +340,9 @@ contains !> @brief Generates a unit vector uniformly distributed on the sphere from two random parameters. function f_unit_vector(theta, eta) result(vec) - real(wp), intent(in) :: theta, eta - real(wp) :: zeta, xi + + real(wp), intent(in) :: theta, eta + real(wp) :: zeta, xi real(wp), dimension(3) :: vec xi = 2._wp*pi*theta @@ -366,12 +353,12 @@ contains end function f_unit_vector - !> This function generates a pseudo-random number between 0 and 1 based on - !! linear congruential generator. + !> This function generates a pseudo-random number between 0 and 1 based on linear congruential generator. subroutine s_prng(var, seed) + integer, intent(inout) :: seed - real(wp), intent(out) :: var - integer :: i + real(wp), intent(out) :: var + integer :: i seed = mod(modmul(seed), modulus) var = seed/real(modulus, wp) @@ -380,9 +367,10 @@ contains !> @brief Computes a modular multiplication step for the linear congruential pseudo-random number generator. function modmul(a) result(val) + integer, intent(in) :: a - integer :: val - real(wp) :: x, y + integer :: val + real(wp) :: x, y x = (multiplier/real(modulus, wp))*a + (increment/real(modulus, wp)) y = nint((x - floor(x))*decimal_trim)/decimal_trim diff --git a/src/pre_process/m_simplex_noise.fpp b/src/pre_process/m_simplex_noise.fpp index 5dacdda7b6..487b4f5022 100644 --- a/src/pre_process/m_simplex_noise.fpp +++ b/src/pre_process/m_simplex_noise.fpp @@ -6,69 +6,44 @@ module m_simplex_noise use m_constants - use m_precision_select implicit none - private; public :: f_simplex3d, & - f_simplex2d - - integer, parameter :: p_vec(0:511) = [ & - 151, 160, 137, 91, 90, 15, 131, 13, 201, 95, 96, 53, 194, 233, 7, 225, 140, 36, 103, 30, & - 69, 142, 8, 99, 37, 240, 21, 10, 23, 190, 6, 148, 247, 120, 234, 75, 0, 26, 197, 62, 94, & - 252, 219, 203, 117, 35, 11, 32, 57, 177, 33, 88, 237, 149, 56, 87, 174, 20, 125, 136, & - 171, 168, 68, 175, 74, 165, 71, 134, 139, 48, 27, 166, 77, 146, 158, 231, 83, 111, 229, & - 122, 60, 211, 133, 230, 220, 105, 92, 41, 55, 46, 245, 40, 244, 102, 143, 54, 65, 25, 63, & - 161, 1, 216, 80, 73, 209, 76, 132, 187, 208, 89, 18, 169, 200, 196, 135, 130, 116, 188, & - 159, 86, 164, 100, 109, 198, 173, 186, 3, 64, 52, 217, 226, 250, 124, 123, 5, 202, 38, & - 147, 118, 126, 255, 82, 85, 212, 207, 206, 59, 227, 47, 16, 58, 17, 182, 189, 28, 42, 223, & - 183, 170, 213, 119, 248, 152, 2, 44, 154, 163, 70, 221, 153, 101, 155, 167, 43, 172, 9, & - 129, 22, 39, 253, 19, 98, 108, 110, 79, 113, 224, 232, 178, 185, 112, 104, 218, 246, 97, & - 228, 251, 34, 242, 193, 238, 210, 144, 12, 191, 179, 162, 241, 81, 51, 145, 235, 249, 14, & - 239, 107, 49, 192, 214, 31, 181, 199, 106, 157, 184, 84, 204, 176, 115, 121, 50, 45, 127, & - 4, 150, 254, 138, 236, 205, 93, 222, 114, 67, 29, 24, 72, 243, 141, 128, 195, 78, 66, 215, & - 61, 156, 180, & - 151, 160, 137, 91, 90, 15, 131, 13, 201, 95, 96, 53, 194, 233, 7, 225, 140, 36, 103, 30, & - 69, 142, 8, 99, 37, 240, 21, 10, 23, 190, 6, 148, 247, 120, 234, 75, 0, 26, 197, 62, 94, & - 252, 219, 203, 117, 35, 11, 32, 57, 177, 33, 88, 237, 149, 56, 87, 174, 20, 125, 136, & - 171, 168, 68, 175, 74, 165, 71, 134, 139, 48, 27, 166, 77, 146, 158, 231, 83, 111, 229, & - 122, 60, 211, 133, 230, 220, 105, 92, 41, 55, 46, 245, 40, 244, 102, 143, 54, 65, 25, 63, & - 161, 1, 216, 80, 73, 209, 76, 132, 187, 208, 89, 18, 169, 200, 196, 135, 130, 116, 188, & - 159, 86, 164, 100, 109, 198, 173, 186, 3, 64, 52, 217, 226, 250, 124, 123, 5, 202, 38, & - 147, 118, 126, 255, 82, 85, 212, 207, 206, 59, 227, 47, 16, 58, 17, 182, 189, 28, 42, 223, & - 183, 170, 213, 119, 248, 152, 2, 44, 154, 163, 70, 221, 153, 101, 155, 167, 43, 172, 9, & - 129, 22, 39, 253, 19, 98, 108, 110, 79, 113, 224, 232, 178, 185, 112, 104, 218, 246, 97, & - 228, 251, 34, 242, 193, 238, 210, 144, 12, 191, 179, 162, 241, 81, 51, 145, 235, 249, 14, & - 239, 107, 49, 192, 214, 31, 181, 199, 106, 157, 184, 84, 204, 176, 115, 121, 50, 45, 127, & - 4, 150, 254, 138, 236, 205, 93, 222, 114, 67, 29, 24, 72, 243, 141, 128, 195, 78, 66, 215, & - 61, 156, 180] - - real(wp), parameter :: grad3(12, 3) = reshape([ & - 1._wp, 1._wp, 0._wp, & - -1._wp, 1._wp, 0._wp, & - 1._wp, -1._wp, 0._wp, & - -1._wp, -1._wp, 0._wp, & - 1._wp, 0._wp, 1._wp, & - -1._wp, 0._wp, 1._wp, & - 1._wp, 0._wp, -1._wp, & - -1._wp, 0._wp, -1._wp, & - 0._wp, 1._wp, 1._wp, & - 0._wp, -1._wp, 1._wp, & - 0._wp, 1._wp, -1._wp, & - 0._wp, -1._wp, -1._wp], shape=[12, 3]) - - real(wp), parameter :: grad2(10, 2) = reshape([ & - 1._wp, 1._wp, & - -1._wp, 1._wp, & - 1._wp, -1._wp, & - -1._wp, -1._wp, & - 1._wp, 0._wp, & - -1._wp, 0._wp, & - 0._wp, 1._wp, & - 0._wp, -1._wp, & - 1._wp, 1._wp, & - -1._wp, 1._wp], shape=[10, 2]) + private; public :: f_simplex3d, f_simplex2d + + integer, parameter :: p_vec(0:511) = [151, 160, 137, 91, 90, 15, 131, 13, 201, 95, 96, 53, 194, 233, 7, 225, 140, 36, 103, & + & 30, 69, 142, 8, 99, 37, 240, 21, 10, 23, 190, 6, 148, 247, 120, 234, 75, 0, 26, 197, 62, 94, & + & 252, 219, 203, 117, 35, 11, 32, 57, 177, 33, 88, 237, 149, 56, 87, 174, 20, 125, 136, 171, 168, & + & 68, 175, 74, 165, 71, 134, 139, 48, 27, 166, 77, 146, 158, 231, 83, 111, 229, 122, 60, 211, & + & 133, 230, 220, 105, 92, 41, 55, 46, 245, 40, 244, 102, 143, 54, 65, 25, 63, 161, 1, 216, 80, & + & 73, 209, 76, 132, 187, 208, 89, 18, 169, 200, 196, 135, 130, 116, 188, 159, 86, 164, 100, 109, & + & 198, 173, 186, 3, 64, 52, 217, 226, 250, 124, 123, 5, 202, 38, 147, 118, 126, 255, 82, 85, 212, & + & 207, 206, 59, 227, 47, 16, 58, 17, 182, 189, 28, 42, 223, 183, 170, 213, 119, 248, 152, 2, 44, & + & 154, 163, 70, 221, 153, 101, 155, 167, 43, 172, 9, 129, 22, 39, 253, 19, 98, 108, 110, 79, 113, & + & 224, 232, 178, 185, 112, 104, 218, 246, 97, 228, 251, 34, 242, 193, 238, 210, 144, 12, 191, & + & 179, 162, 241, 81, 51, 145, 235, 249, 14, 239, 107, 49, 192, 214, 31, 181, 199, 106, 157, 184, & + & 84, 204, 176, 115, 121, 50, 45, 127, 4, 150, 254, 138, 236, 205, 93, 222, 114, 67, 29, 24, 72, & + & 243, 141, 128, 195, 78, 66, 215, 61, 156, 180, 151, 160, 137, 91, 90, 15, 131, 13, 201, 95, 96, & + & 53, 194, 233, 7, 225, 140, 36, 103, 30, 69, 142, 8, 99, 37, 240, 21, 10, 23, 190, 6, 148, 247, & + & 120, 234, 75, 0, 26, 197, 62, 94, 252, 219, 203, 117, 35, 11, 32, 57, 177, 33, 88, 237, 149, & + & 56, 87, 174, 20, 125, 136, 171, 168, 68, 175, 74, 165, 71, 134, 139, 48, 27, 166, 77, 146, 158, & + & 231, 83, 111, 229, 122, 60, 211, 133, 230, 220, 105, 92, 41, 55, 46, 245, 40, 244, 102, 143, & + & 54, 65, 25, 63, 161, 1, 216, 80, 73, 209, 76, 132, 187, 208, 89, 18, 169, 200, 196, 135, 130, & + & 116, 188, 159, 86, 164, 100, 109, 198, 173, 186, 3, 64, 52, 217, 226, 250, 124, 123, 5, 202, & + & 38, 147, 118, 126, 255, 82, 85, 212, 207, 206, 59, 227, 47, 16, 58, 17, 182, 189, 28, 42, 223, & + & 183, 170, 213, 119, 248, 152, 2, 44, 154, 163, 70, 221, 153, 101, 155, 167, 43, 172, 9, 129, & + & 22, 39, 253, 19, 98, 108, 110, 79, 113, 224, 232, 178, 185, 112, 104, 218, 246, 97, 228, 251, & + & 34, 242, 193, 238, 210, 144, 12, 191, 179, 162, 241, 81, 51, 145, 235, 249, 14, 239, 107, 49, & + & 192, 214, 31, 181, 199, 106, 157, 184, 84, 204, 176, 115, 121, 50, 45, 127, 4, 150, 254, 138, & + & 236, 205, 93, 222, 114, 67, 29, 24, 72, 243, 141, 128, 195, 78, 66, 215, 61, 156, 180] + + real(wp), parameter :: grad3(12, 3) = reshape([1._wp, 1._wp, 0._wp, -1._wp, 1._wp, 0._wp, 1._wp, -1._wp, 0._wp, -1._wp, & + & -1._wp, 0._wp, 1._wp, 0._wp, 1._wp, -1._wp, 0._wp, 1._wp, 1._wp, 0._wp, -1._wp, -1._wp, 0._wp, -1._wp, 0._wp, 1._wp, & + & 1._wp, 0._wp, -1._wp, 1._wp, 0._wp, 1._wp, -1._wp, 0._wp, -1._wp, -1._wp], shape=[12, 3]) + + real(wp), parameter :: grad2(10, 2) = reshape([1._wp, 1._wp, -1._wp, 1._wp, 1._wp, -1._wp, -1._wp, -1._wp, 1._wp, 0._wp, & + & -1._wp, 0._wp, 0._wp, 1._wp, 0._wp, -1._wp, 1._wp, 1._wp, -1._wp, 1._wp], shape=[10, 2]) contains @@ -76,15 +51,15 @@ contains function f_simplex3d(xin, yin, zin) result(n) real(wp), intent(in) :: xin, yin, zin - real(wp) :: n - real(wp) :: n0, n1, n2, n3 - real(wp) :: f3, g3 - real(wp) :: x0, y0, z0, x1, y1, z1, x2, y2, z2, x3, y3, z3 - integer :: i, j, k, i1, j1, k1, i2, j2, k2 - integer :: ii, jj, kk, gi0, gi1, gi2, gi3 - real(wp) :: s, t, r, t0, t1, t2, t3 - real(wp) :: g(3) - real(wp) :: x, y, z + real(wp) :: n + real(wp) :: n0, n1, n2, n3 + real(wp) :: f3, g3 + real(wp) :: x0, y0, z0, x1, y1, z1, x2, y2, z2, x3, y3, z3 + integer :: i, j, k, i1, j1, k1, i2, j2, k2 + integer :: ii, jj, kk, gi0, gi1, gi2, gi3 + real(wp) :: s, t, r, t0, t1, t2, t3 + real(wp) :: g(3) + real(wp) :: x, y, z f3 = 1._wp/3._wp g3 = 1._wp/6._wp @@ -142,7 +117,7 @@ contains n0 = 0._wp else t0 = t0*t0 - n0 = t0*t0*dot_product(grad3(gi0, :), [x0, y0, z0]) + n0 = t0*t0*dot_product(grad3(gi0,:), [x0, y0, z0]) end if t1 = 0.5_wp - x1*x1 - y1*y1 - z1*z1 @@ -150,7 +125,7 @@ contains n1 = 0._wp else t1 = t1*t1 - n1 = t1*t1*dot_product(grad3(gi1, :), [x1, y1, z1]) + n1 = t1*t1*dot_product(grad3(gi1,:), [x1, y1, z1]) end if t2 = 0.5_wp - x2*x2 - y2*y2 - z2*z2 @@ -158,7 +133,7 @@ contains n2 = 0._wp else t2 = t2*t2 - n2 = t2*t2*dot_product(grad3(gi2, :), [x2, y2, z2]) + n2 = t2*t2*dot_product(grad3(gi2,:), [x2, y2, z2]) end if t3 = 0.5_wp - x3*x3 - y3*y3 - z3*z3 @@ -166,7 +141,7 @@ contains n3 = 0._wp else t3 = t3*t3 - n3 = t3*t3*dot_product(grad3(gi3, :), [x3, y3, z3]) + n3 = t3*t3*dot_product(grad3(gi3,:), [x3, y3, z3]) end if n = 32._wp*(n0 + n1 + n2 + n3) @@ -177,13 +152,13 @@ contains function f_simplex2d(xin, yin) result(n) real(wp), intent(in) :: xin, yin - real(wp) :: n - real(wp), parameter :: F2 = 0.5_wp*(sqrt(3._wp) - 1._wp) - real(wp), parameter :: G2 = (3._wp - sqrt(3._wp))/6._wp - integer :: i, j, ii, jj, gi0, gi1, gi2 - real(wp) :: s, t, x0, y0, x1, y1, x2, y2 - real(wp) :: t0, t1, t2, n0, n1, n2 - integer :: i1, j1 + real(wp) :: n + real(wp), parameter :: F2 = 0.5_wp*(sqrt(3._wp) - 1._wp) + real(wp), parameter :: G2 = (3._wp - sqrt(3._wp))/6._wp + integer :: i, j, ii, jj, gi0, gi1, gi2 + real(wp) :: s, t, x0, y0, x1, y1, x2, y2 + real(wp) :: t0, t1, t2, n0, n1, n2 + integer :: i1, j1 s = (xin + yin)*F2 i = floor(xin + s) @@ -243,11 +218,12 @@ contains !> @brief Computes the dot product of a 2D gradient vector with the given offset coordinates. function dot2(g, x, y) result(dot) - integer, intent(in) :: g + integer, intent(in) :: g real(wp), intent(in) :: x, y - real(wp) :: dot + real(wp) :: dot + dot = grad2(g + 1, 1)*x + grad2(g + 1, 2)*y - end function + end function dot2 end module m_simplex_noise diff --git a/src/pre_process/m_start_up.fpp b/src/pre_process/m_start_up.fpp index 97387e9b4a..11187bd780 100644 --- a/src/pre_process/m_start_up.fpp +++ b/src/pre_process/m_start_up.fpp @@ -8,70 +8,38 @@ module m_start_up use m_derived_types !< Definitions of the derived types - use m_global_parameters !< Global parameters for the code - use m_mpi_proxy !< Message passing interface (MPI) module proxy - use m_mpi_common - - use m_variables_conversion !< Subroutines to change the state variables from - !! one form to another - + use m_variables_conversion !< Subroutines to change the state variables from one form to another use m_grid !< Procedures to generate (non-)uniform grids - use m_initial_condition !< Procedures to generate initial condition - - use m_data_output !< Procedures to write the grid data and the - !! conservative variables to files - + use m_data_output !< Procedures to write the grid data and the conservative variables to files use m_compile_specific !< Compile-specific procedures - use m_icpp_patches - use m_assign_variables - use m_phase_change !< Phase-change module - use m_helper_basic !< Functions to compare floating point numbers - use m_helper #ifdef MFC_MPI - use mpi !< Message passing interface (MPI) module + use mpi !< Message passing interface (MPI) module #endif use m_check_patches - use m_check_ib_patches - use m_helper - use m_checker_common - use m_checker - use m_boundary_common - use m_boundary_conditions implicit none - private; - public :: s_read_input_file, & - s_check_input_file, & - s_read_grid_data_files, & - s_read_ic_data_files, & - s_read_serial_grid_data_files, & - s_read_serial_ic_data_files, & - s_read_parallel_grid_data_files, & - s_read_parallel_ic_data_files, & - s_check_grid_data_files, & - s_initialize_modules, & - s_initialize_mpi_domain, & - s_finalize_modules, & - s_apply_initial_condition, & - s_save_data, s_read_grid + private + public :: s_read_input_file, s_check_input_file, s_read_grid_data_files, s_read_ic_data_files, s_read_serial_grid_data_files, & + & s_read_serial_ic_data_files, s_read_parallel_grid_data_files, s_read_parallel_ic_data_files, s_check_grid_data_files, & + & s_initialize_modules, s_initialize_mpi_domain, s_finalize_modules, s_apply_initial_condition, s_save_data, s_read_grid abstract interface @@ -86,88 +54,63 @@ module m_start_up import :: scalar_field, integer_field, sys_size, pres_field - type(scalar_field), & - dimension(sys_size), & - intent(inout) :: q_cons_vf_in + type(scalar_field), dimension(sys_size), intent(inout) :: q_cons_vf_in end subroutine s_read_abstract_ic_data_files - end interface - character(LEN=path_len + name_len) :: proc_rank_dir !< - !! Location of the folder associated with the rank of the local processor + character(LEN=path_len + name_len) :: proc_rank_dir !< Location of the folder associated with the rank of the local processor - character(LEN=path_len + 2*name_len), private :: t_step_dir !< - !! Possible location of time-step folder containing preexisting grid and/or - !! conservative variables data to be used as starting point for pre-process + !> Possible location of time-step folder containing preexisting grid and/or conservative variables data to be used as starting + !! point for pre-process + character(LEN=path_len + 2*name_len), private :: t_step_dir procedure(s_read_abstract_grid_data_files), pointer :: s_read_grid_data_files => null() procedure(s_read_abstract_ic_data_files), pointer :: s_read_ic_data_files => null() contains - !> Reads the configuration file pre_process.inp, in order to - !! populate the parameters in module m_global_parameters.f90 - !! with the user provided inputs + !> Reads the configuration file pre_process.inp, in order to populate the parameters in module m_global_parameters.f90 with the + !! user provided inputs impure subroutine s_read_input_file - character(LEN=name_len) :: file_loc !< - !! Generic string used to store the address of a particular file - - logical :: file_check !< - !! Generic logical used for the purpose of asserting whether a file - !! is or is not present in the designated location + character(LEN=name_len) :: file_loc !< Generic string used to store the address of a particular file + !> Generic logical used for the purpose of asserting whether a file is or is not present in the designated location + logical :: file_check integer :: iostatus - !! Integer to check iostat of file read + !! Integer to check iostat of file read character(len=1000) :: line ! Namelist for all of the parameters to be inputted by the user - namelist /user_inputs/ case_dir, old_grid, old_ic, & - t_step_old, t_step_start, m, n, p, x_domain, y_domain, z_domain, & - stretch_x, stretch_y, stretch_z, a_x, a_y, & - a_z, x_a, y_a, z_a, x_b, y_b, z_b, & - model_eqns, num_fluids, mpp_lim, & - weno_order, bc_x, bc_y, bc_z, num_patches, & - hypoelasticity, mhd, patch_icpp, fluid_pp, bub_pp, & - precision, parallel_io, mixlayer_vel_profile, mixlayer_vel_coef, & - mixlayer_perturb, mixlayer_perturb_nk, mixlayer_perturb_k0, & - pi_fac, perturb_flow, perturb_flow_fluid, perturb_flow_mag, & - perturb_sph, perturb_sph_fluid, fluid_rho, & - cyl_coord, loops_x, loops_y, loops_z, & - rhoref, pref, bubbles_euler, R0ref, nb, & - polytropic, thermal, Ca, Web, Re_inv, & - polydisperse, poly_sigma, qbmm, & - sigR, sigV, dist_type, rhoRV, & - file_per_process, relax, relax_model, & - palpha_eps, ptgalpha_eps, ib, num_ibs, patch_ib, & - sigma, adv_n, cfl_adap_dt, cfl_const_dt, n_start, & - n_start_old, surface_tension, hyperelasticity, pre_stress, & - elliptic_smoothing, elliptic_smoothing_iters, & - viscous, bubbles_lagrange, num_bc_patches, & - patch_bc, Bx0, relativity, cont_damage, igr, igr_order, & - down_sample, recon_type, muscl_order, fft_wrt, & - fd_order, lag_params, simplex_perturb, simplex_params, & - interface_file, normFac, normMag, & - g0_ic, p0_ic, hyper_cleaning + + namelist /user_inputs/ case_dir, old_grid, old_ic, t_step_old, t_step_start, m, n, p, x_domain, y_domain, z_domain, & + & stretch_x, stretch_y, stretch_z, a_x, a_y, a_z, x_a, y_a, z_a, x_b, y_b, z_b, model_eqns, num_fluids, mpp_lim, & + & weno_order, bc_x, bc_y, bc_z, num_patches, hypoelasticity, mhd, patch_icpp, fluid_pp, bub_pp, precision, & + & parallel_io, mixlayer_vel_profile, mixlayer_vel_coef, mixlayer_perturb, mixlayer_perturb_nk, mixlayer_perturb_k0, & + & pi_fac, perturb_flow, perturb_flow_fluid, perturb_flow_mag, perturb_sph, perturb_sph_fluid, fluid_rho, cyl_coord, & + & loops_x, loops_y, loops_z, rhoref, pref, bubbles_euler, R0ref, nb, polytropic, thermal, Ca, Web, Re_inv, & + & polydisperse, poly_sigma, qbmm, sigR, sigV, dist_type, rhoRV, file_per_process, relax, relax_model, palpha_eps, & + & ptgalpha_eps, ib, num_ibs, patch_ib, sigma, adv_n, cfl_adap_dt, cfl_const_dt, n_start, n_start_old, & + & surface_tension, hyperelasticity, pre_stress, elliptic_smoothing, elliptic_smoothing_iters, viscous, & + & bubbles_lagrange, num_bc_patches, patch_bc, Bx0, relativity, cont_damage, igr, igr_order, down_sample, recon_type, & + & muscl_order, fft_wrt, fd_order, lag_params, simplex_perturb, simplex_params, interface_file, normFac, normMag, & + & g0_ic, p0_ic, hyper_cleaning ! Inquiring the status of the pre_process.inp file file_loc = 'pre_process.inp' inquire (FILE=trim(file_loc), EXIST=file_check) - ! Checking whether the input file is there. If it is, the input file - ! is read. If not, the program is terminated. + ! Checking whether the input file is there. If it is, the input file is read. If not, the program is terminated. if (file_check) then - open (1, FILE=trim(file_loc), FORM='formatted', & - STATUS='old', ACTION='read') + open (1, FILE=trim(file_loc), form='formatted', STATUS='old', ACTION='read') read (1, NML=user_inputs, iostat=iostatus) if (iostatus /= 0) then backspace (1) read (1, fmt='(A)') line - print *, 'Invalid line in namelist: '//trim(line) - call s_mpi_abort('Invalid line in pre_process.inp. It is '// & - 'likely due to a datatype mismatch. Exiting.') + print *, 'Invalid line in namelist: ' // trim(line) + call s_mpi_abort('Invalid line in pre_process.inp. It is ' // 'likely due to a datatype mismatch. Exiting.') end if close (1) @@ -182,41 +125,34 @@ contains if (cfl_adap_dt .or. cfl_const_dt) cfl_dt = .true. - if (any((/bc_x%beg, bc_x%end, bc_y%beg, bc_y%end, bc_z%beg, bc_z%end/) == BC_DIRICHLET) .or. & - num_bc_patches > 0) then + if (any((/bc_x%beg, bc_x%end, bc_y%beg, bc_y%end, bc_z%beg, bc_z%end/) == BC_DIRICHLET) .or. num_bc_patches > 0) then bc_io = .true. end if - else call s_mpi_abort('File pre_process.inp is missing. Exiting.') end if end subroutine s_read_input_file - !> Checking that the user inputs make sense, i.e. that the - !! individual choices are compatible with the code's options - !! and that the combination of these choices results into a - !! valid configuration for the pre-process + !> Checking that the user inputs make sense, i.e. that the individual choices are compatible with the code's options and that + !! the combination of these choices results into a valid configuration for the pre-process impure subroutine s_check_input_file - character(LEN=len_trim(case_dir)) :: file_loc !< - !! Generic string used to store the address of a particular file - - logical :: dir_check !< - !! Logical variable used to test the existence of folders + character(LEN=len_trim(case_dir)) :: file_loc !< Generic string used to store the address of a particular file + logical :: dir_check !< Logical variable used to test the existence of folders ! Checking the existence of the case folder + case_dir = adjustl(case_dir) - file_loc = trim(case_dir)//'/.' + file_loc = trim(case_dir) // '/.' call my_inquire(file_loc, dir_check) if (dir_check .neqv. .true.) then print '(A)', 'WARNING: Ensure that compiler flags/choices in Makefiles match your compiler! ' print '(A)', 'WARNING: Ensure that preprocessor flags are enabled! ' - call s_mpi_abort('Unsupported choice for the value of case_dir.'// & - 'Exiting.') + call s_mpi_abort('Unsupported choice for the value of case_dir.' // 'Exiting.') end if call s_check_inputs_common() @@ -229,9 +165,8 @@ contains end subroutine s_check_input_file - !> The goal of this subroutine is to read in any preexisting - !! grid data as well as based on the imported grid, complete - !! the necessary global computational domain parameters. + !> The goal of this subroutine is to read in any preexisting grid data as well as based on the imported grid, complete the + !! necessary global computational domain parameters. impure subroutine s_read_serial_grid_data_files ! Generic string used to store the address of a particular file @@ -240,42 +175,39 @@ contains ! Logical variable used to test the existence of folders logical :: dir_check - ! Generic logical used for the purpose of asserting whether a file - ! is or is not present in the designated location + ! Generic logical used for the purpose of asserting whether a file is or is not present in the designated location logical :: file_check ! Setting address of the local processor rank and time-step directory + write (proc_rank_dir, '(A,I0)') '/p_all/p', proc_rank - proc_rank_dir = trim(case_dir)//trim(proc_rank_dir) + proc_rank_dir = trim(case_dir) // trim(proc_rank_dir) write (t_step_dir, '(A,I0)') '/', t_step_start - t_step_dir = trim(proc_rank_dir)//trim(t_step_dir) + t_step_dir = trim(proc_rank_dir) // trim(t_step_dir) ! Inquiring as to the existence of the time-step directory - file_loc = trim(t_step_dir)//'/.' + file_loc = trim(t_step_dir) // '/.' call my_inquire(file_loc, dir_check) ! If the time-step directory is missing, the pre-process exits if (dir_check .neqv. .true.) then - call s_mpi_abort('Time-step folder '//trim(t_step_dir)// & - ' is missing. Exiting.') + call s_mpi_abort('Time-step folder ' // trim(t_step_dir) // ' is missing. Exiting.') end if ! Reading the Grid Data File for the x-direction ! Checking whether x_cb.dat exists - file_loc = trim(t_step_dir)//'/x_cb.dat' + file_loc = trim(t_step_dir) // '/x_cb.dat' inquire (FILE=trim(file_loc), EXIST=file_check) ! If it exists, x_cb.dat is read if (file_check) then - open (1, FILE=trim(file_loc), FORM='unformatted', & - STATUS='old', ACTION='read') + open (1, FILE=trim(file_loc), form='unformatted', STATUS='old', ACTION='read') read (1) x_cb(-1:m) close (1) else - call s_mpi_abort('File x_cb.dat is missing in '// & - trim(t_step_dir)//'. Exiting.') + call s_mpi_abort('File x_cb.dat is missing in ' // trim(t_step_dir) // '. Exiting.') end if ! Computing cell-center locations @@ -292,20 +224,17 @@ contains ! Reading the Grid Data File for the y-direction if (n > 0) then - ! Checking whether y_cb.dat exists - file_loc = trim(t_step_dir)//'/y_cb.dat' + file_loc = trim(t_step_dir) // '/y_cb.dat' inquire (FILE=trim(file_loc), EXIST=file_check) ! If it exists, y_cb.dat is read if (file_check) then - open (1, FILE=trim(file_loc), FORM='unformatted', & - STATUS='old', ACTION='read') + open (1, FILE=trim(file_loc), form='unformatted', STATUS='old', ACTION='read') read (1) y_cb(-1:n) close (1) else - call s_mpi_abort('File y_cb.dat is missing in '// & - trim(t_step_dir)//'. Exiting.') + call s_mpi_abort('File y_cb.dat is missing in ' // trim(t_step_dir) // '. Exiting.') end if ! Computing cell-center locations @@ -321,20 +250,17 @@ contains ! Reading the Grid Data File for the z-direction if (p > 0) then - ! Checking whether z_cb.dat exists - file_loc = trim(t_step_dir)//'/z_cb.dat' + file_loc = trim(t_step_dir) // '/z_cb.dat' inquire (FILE=trim(file_loc), EXIST=file_check) ! If it exists, z_cb.dat is read if (file_check) then - open (1, FILE=trim(file_loc), FORM='unformatted', & - STATUS='old', ACTION='read') + open (1, FILE=trim(file_loc), form='unformatted', STATUS='old', ACTION='read') read (1) z_cb(-1:p) close (1) else - call s_mpi_abort('File z_cb.dat is missing in '// & - trim(t_step_dir)//'. Exiting.') + call s_mpi_abort('File z_cb.dat is missing in ' // trim(t_step_dir) // '. Exiting.') end if ! Computing cell-center locations @@ -347,195 +273,148 @@ contains ! Setting locations of domain bounds z_domain%beg = z_cb(-1) z_domain%end = z_cb(p) - end if - end if - ! If only the preexisting grid data files are read in and there will - ! not be any preexisting initial condition data files imported, then - ! the directory associated with the rank of the local processor may - ! be cleaned to make room for the new pre-process data. In addition, - ! the time-step directory that will contain the new grid and initial - ! condition data are also generated. + ! If only the preexisting grid data files are read in and there will not be any preexisting initial condition data files + ! imported, then the directory associated with the rank of the local processor may be cleaned to make room for the new + ! pre-process data. In addition, the time-step directory that will contain the new grid and initial condition data are also + ! generated. if (old_ic .neqv. .true.) then call s_delete_directory(trim(proc_rank_dir)) - call s_create_directory(trim(proc_rank_dir)//'/0') + call s_create_directory(trim(proc_rank_dir) // '/0') end if end subroutine s_read_serial_grid_data_files - !> Cell-boundary data are checked for consistency by looking - !! at the (non-)uniform cell-width distributions for all the - !! active coordinate directions and making sure that all of - !! the cell-widths are positively valued + !> Cell-boundary data are checked for consistency by looking at the (non-)uniform cell-width distributions for all the active + !! coordinate directions and making sure that all of the cell-widths are positively valued impure subroutine s_check_grid_data_files ! Cell-boundary Data Consistency Check in x-direction if (any(x_cb(0:m) - x_cb(-1:m - 1) <= 0._wp)) then - call s_mpi_abort('x_cb.dat in '//trim(t_step_dir)// & - ' contains non-positive cell-spacings. Exiting.') + call s_mpi_abort('x_cb.dat in ' // trim(t_step_dir) // ' contains non-positive cell-spacings. Exiting.') end if ! Cell-boundary Data Consistency Check in y-direction if (n > 0) then - if (any(y_cb(0:n) - y_cb(-1:n - 1) <= 0._wp)) then - call s_mpi_abort('y_cb.dat in '//trim(t_step_dir)// & - ' contains non-positive cell-spacings. '// & - 'Exiting.') + call s_mpi_abort('y_cb.dat in ' // trim(t_step_dir) // ' contains non-positive cell-spacings. ' // 'Exiting.') end if ! Cell-boundary Data Consistency Check in z-direction if (p > 0) then - if (any(z_cb(0:p) - z_cb(-1:p - 1) <= 0._wp)) then - call s_mpi_abort('z_cb.dat in '//trim(t_step_dir)// & - ' contains non-positive cell-spacings'// & - ' .Exiting.') + call s_mpi_abort('z_cb.dat in ' // trim(t_step_dir) // ' contains non-positive cell-spacings' // ' .Exiting.') end if - end if - end if end subroutine s_check_grid_data_files - !> The goal of this subroutine is to read in any preexisting - !! initial condition data files so that they may be used by - !! the pre-process as a starting point in the creation of an - !! all new initial condition. - !! @param q_cons_vf_in Conservative variables + !> The goal of this subroutine is to read in any preexisting initial condition data files so that they may be used by the + !! pre-process as a starting point in the creation of an all new initial condition. + !! @param q_cons_vf_in Conservative variables impure subroutine s_read_serial_ic_data_files(q_cons_vf_in) - type(scalar_field), & - dimension(sys_size), & - intent(inout) :: q_cons_vf_in - - character(LEN=len_trim(case_dir) + 3*name_len) :: file_loc !< + type(scalar_field), dimension(sys_size), intent(inout) :: q_cons_vf_in + character(LEN=len_trim(case_dir) + 3*name_len) :: file_loc ! Generic string used to store the address of a particular file - character(LEN= & - int(floor(log10(real(sys_size, wp)))) + 1) :: file_num !< - !! Used to store the variable position, in character form, of the - !! currently manipulated conservative variable file - - logical :: file_check !< - !! Generic logical used for the purpose of asserting whether a file - !! is or is not present in the designated location + !> Used to store the variable position, in character form, of the currently manipulated conservative variable file + character(LEN=int(floor(log10(real(sys_size, wp)))) + 1) :: file_num - integer :: i, r !< Generic loop iterator + !> Generic logical used for the purpose of asserting whether a file is or is not present in the designated location + logical :: file_check + integer :: i, r !< Generic loop iterator ! Reading the Conservative Variables Data Files - do i = 1, sys_size - ! Checking whether data file associated with variable position - ! of the currently manipulated conservative variable exists + do i = 1, sys_size + ! Checking whether data file associated with variable position of the currently manipulated conservative variable exists write (file_num, '(I0)') i - file_loc = trim(t_step_dir)//'/q_cons_vf'// & - trim(file_num)//'.dat' + file_loc = trim(t_step_dir) // '/q_cons_vf' // trim(file_num) // '.dat' inquire (FILE=trim(file_loc), EXIST=file_check) ! If it exists, the data file is read if (file_check) then - open (1, FILE=trim(file_loc), FORM='unformatted', & - STATUS='old', ACTION='read') + open (1, FILE=trim(file_loc), form='unformatted', STATUS='old', ACTION='read') read (1) q_cons_vf_in(i)%sf close (1) else - call s_mpi_abort('File q_cons_vf'//trim(file_num)// & - '.dat is missing in '//trim(t_step_dir)// & - '. Exiting.') + call s_mpi_abort('File q_cons_vf' // trim(file_num) // '.dat is missing in ' // trim(t_step_dir) // '. Exiting.') end if - end do - !Read bubble variables pb and mv for non-polytropic qbmm + ! Read bubble variables pb and mv for non-polytropic qbmm if (qbmm .and. .not. polytropic) then do i = 1, nb do r = 1, nnode - ! Checking whether data file associated with variable position - ! of the currently manipulated bubble variable exists + ! Checking whether data file associated with variable position of the currently manipulated bubble variable + ! exists write (file_num, '(I0)') sys_size + r + (i - 1)*nnode - file_loc = trim(t_step_dir)//'/pb'// & - trim(file_num)//'.dat' + file_loc = trim(t_step_dir) // '/pb' // trim(file_num) // '.dat' inquire (FILE=trim(file_loc), EXIST=file_check) ! If it exists, the data file is read if (file_check) then - open (1, FILE=trim(file_loc), FORM='unformatted', & - STATUS='old', ACTION='read') - read (1) pb%sf(:, :, :, r, i) + open (1, FILE=trim(file_loc), form='unformatted', STATUS='old', ACTION='read') + read (1) pb%sf(:,:,:,r, i) close (1) else - call s_mpi_abort('File pb'//trim(file_num)// & - '.dat is missing in '//trim(t_step_dir)// & - '. Exiting.') + call s_mpi_abort('File pb' // trim(file_num) // '.dat is missing in ' // trim(t_step_dir) // '. Exiting.') end if end do - end do do i = 1, nb do r = 1, nnode - ! Checking whether data file associated with variable position - ! of the currently manipulated bubble variable exists + ! Checking whether data file associated with variable position of the currently manipulated bubble variable + ! exists write (file_num, '(I0)') sys_size + r + (i - 1)*nnode - file_loc = trim(t_step_dir)//'/mv'// & - trim(file_num)//'.dat' + file_loc = trim(t_step_dir) // '/mv' // trim(file_num) // '.dat' inquire (FILE=trim(file_loc), EXIST=file_check) ! If it exists, the data file is read if (file_check) then - open (1, FILE=trim(file_loc), FORM='unformatted', & - STATUS='old', ACTION='read') - read (1) mv%sf(:, :, :, r, i) + open (1, FILE=trim(file_loc), form='unformatted', STATUS='old', ACTION='read') + read (1) mv%sf(:,:,:,r, i) close (1) else - call s_mpi_abort('File mv'//trim(file_num)// & - '.dat is missing in '//trim(t_step_dir)// & - '. Exiting.') + call s_mpi_abort('File mv' // trim(file_num) // '.dat is missing in ' // trim(t_step_dir) // '. Exiting.') end if end do - end do end if - ! Since the preexisting grid and initial condition data files have - ! been read in, the directory associated with the rank of the local - ! process may be cleaned out to make room for new pre-process data. - ! In addition, the time-step folder that will contain the new grid - ! and initial condition data are also generated. + ! Since the preexisting grid and initial condition data files have been read in, the directory associated with the rank of + ! the local process may be cleaned out to make room for new pre-process data. In addition, the time-step folder that will + ! contain the new grid and initial condition data are also generated. call s_delete_directory(trim(proc_rank_dir)) - call s_create_directory(trim(proc_rank_dir)//'/0') + call s_create_directory(trim(proc_rank_dir) // '/0') end subroutine s_read_serial_ic_data_files - !> Cell-boundary data are checked for consistency by looking - !! at the (non-)uniform cell-width distributions for all the - !! active coordinate directions and making sure that all of - !! the cell-widths are positively valued + !> Cell-boundary data are checked for consistency by looking at the (non-)uniform cell-width distributions for all the active + !! coordinate directions and making sure that all of the cell-widths are positively valued impure subroutine s_read_parallel_grid_data_files #ifdef MFC_MPI - - real(wp), allocatable, dimension(:) :: x_cb_glb, y_cb_glb, z_cb_glb - - integer :: ifile, ierr, data_size - integer, dimension(MPI_STATUS_SIZE) :: status - + real(wp), allocatable, dimension(:) :: x_cb_glb, y_cb_glb, z_cb_glb + integer :: ifile, ierr, data_size + integer, dimension(MPI_STATUS_SIZE) :: status character(LEN=path_len + 2*name_len) :: file_loc - logical :: file_exist + logical :: file_exist allocate (x_cb_glb(-1:m_glb)) allocate (y_cb_glb(-1:n_glb)) allocate (z_cb_glb(-1:p_glb)) ! Read in cell boundary locations in x-direction - file_loc = trim(case_dir)//'/restart_data'//trim(mpiiofs)//'x_cb.dat' + file_loc = trim(case_dir) // '/restart_data' // trim(mpiiofs) // 'x_cb.dat' inquire (FILE=trim(file_loc), EXIST=file_exist) if (file_exist) then @@ -544,7 +423,7 @@ contains call MPI_FILE_READ_ALL(ifile, x_cb_glb, data_size, mpi_p, status, ierr) call MPI_FILE_CLOSE(ifile, ierr) else - call s_mpi_abort('File '//trim(file_loc)//' is missing. Exiting. ') + call s_mpi_abort('File ' // trim(file_loc) // ' is missing. Exiting. ') end if ! Assigning local cell boundary locations @@ -560,7 +439,7 @@ contains if (n > 0) then ! Read in cell boundary locations in y-direction - file_loc = trim(case_dir)//'/restart_data'//trim(mpiiofs)//'y_cb.dat' + file_loc = trim(case_dir) // '/restart_data' // trim(mpiiofs) // 'y_cb.dat' inquire (FILE=trim(file_loc), EXIST=file_exist) if (file_exist) then @@ -569,7 +448,7 @@ contains call MPI_FILE_READ_ALL(ifile, y_cb_glb, data_size, mpi_p, status, ierr) call MPI_FILE_CLOSE(ifile, ierr) else - call s_mpi_abort('File '//trim(file_loc)//' is missing. Exiting. ') + call s_mpi_abort('File ' // trim(file_loc) // ' is missing. Exiting. ') end if ! Assigning local cell boundary locations @@ -585,7 +464,7 @@ contains if (p > 0) then ! Read in cell boundary locations in z-direction - file_loc = trim(case_dir)//'/restart_data'//trim(mpiiofs)//'z_cb.dat' + file_loc = trim(case_dir) // '/restart_data' // trim(mpiiofs) // 'z_cb.dat' inquire (FILE=trim(file_loc), EXIST=file_exist) if (file_exist) then @@ -594,7 +473,7 @@ contains call MPI_FILE_READ_ALL(ifile, z_cb_glb, data_size, mpi_p, status, ierr) call MPI_FILE_CLOSE(ifile, ierr) else - call s_mpi_abort('File '//trim(file_loc)//' is missing. Exiting. ') + call s_mpi_abort('File ' // trim(file_loc) // ' is missing. Exiting. ') end if ! Assigning local cell boundary locations @@ -607,41 +486,32 @@ contains ! Setting locations of domain bounds z_domain%beg = z_cb(-1) z_domain%end = z_cb(p) - end if end if deallocate (x_cb_glb, y_cb_glb, z_cb_glb) - #endif end subroutine s_read_parallel_grid_data_files - !> The goal of this subroutine is to read in any preexisting - !! initial condition data files so that they may be used by - !! the pre-process as a starting point in the creation of an - !! all new initial condition. - !! @param q_cons_vf_in Conservative variables + !> The goal of this subroutine is to read in any preexisting initial condition data files so that they may be used by the + !! pre-process as a starting point in the creation of an all new initial condition. + !! @param q_cons_vf_in Conservative variables impure subroutine s_read_parallel_ic_data_files(q_cons_vf_in) - type(scalar_field), & - dimension(sys_size), & - intent(inout) :: q_cons_vf_in + type(scalar_field), dimension(sys_size), intent(inout) :: q_cons_vf_in #ifdef MFC_MPI - - integer :: ifile, ierr, data_size - integer, dimension(MPI_STATUS_SIZE) :: status - integer(KIND=MPI_OFFSET_KIND) :: disp - integer(KIND=MPI_OFFSET_KIND) :: m_MOK, n_MOK, p_MOK - integer(KIND=MPI_OFFSET_KIND) :: WP_MOK, var_MOK, str_MOK - integer(KIND=MPI_OFFSET_KIND) :: NVARS_MOK - integer(KIND=MPI_OFFSET_KIND) :: MOK - + integer :: ifile, ierr, data_size + integer, dimension(MPI_STATUS_SIZE) :: status + integer(KIND=MPI_OFFSET_KIND) :: disp + integer(KIND=MPI_OFFSET_KIND) :: m_MOK, n_MOK, p_MOK + integer(KIND=MPI_OFFSET_KIND) :: WP_MOK, var_MOK, str_MOK + integer(KIND=MPI_OFFSET_KIND) :: NVARS_MOK + integer(KIND=MPI_OFFSET_KIND) :: MOK character(LEN=path_len + 2*name_len) :: file_loc - logical :: file_exist - - integer :: i + logical :: file_exist + integer :: i ! Open the file to read if (cfl_adap_dt) then @@ -649,7 +519,7 @@ contains else write (file_loc, '(I0,A)') t_step_start, '.dat' end if - file_loc = trim(restart_dir)//trim(mpiiofs)//trim(file_loc) + file_loc = trim(restart_dir) // trim(mpiiofs) // trim(file_loc) inquire (FILE=trim(file_loc), EXIST=file_exist) if (file_exist) then @@ -676,10 +546,8 @@ contains ! Initial displacement to skip at beginning of file disp = m_MOK*max(MOK, n_MOK)*max(MOK, p_MOK)*WP_MOK*(var_MOK - 1) - call MPI_FILE_SET_VIEW(ifile, disp, mpi_p, MPI_IO_DATA%view(i), & - 'native', mpi_info_int, ierr) - call MPI_FILE_READ(ifile, MPI_IO_DATA%var(i)%sf, data_size, & - mpi_p, status, ierr) + call MPI_FILE_SET_VIEW(ifile, disp, mpi_p, MPI_IO_DATA%view(i), 'native', mpi_info_int, ierr) + call MPI_FILE_READ(ifile, MPI_IO_DATA%var(i)%sf, data_size, mpi_p, status, ierr) end do if (qbmm .and. .not. polytropic) then @@ -689,31 +557,27 @@ contains ! Initial displacement to skip at beginning of file disp = m_MOK*max(MOK, n_MOK)*max(MOK, p_MOK)*WP_MOK*(var_MOK - 1) - call MPI_FILE_SET_VIEW(ifile, disp, mpi_p, MPI_IO_DATA%view(i), & - 'native', mpi_info_int, ierr) - call MPI_FILE_READ(ifile, MPI_IO_DATA%var(i)%sf, data_size, & - mpi_p, status, ierr) + call MPI_FILE_SET_VIEW(ifile, disp, mpi_p, MPI_IO_DATA%view(i), 'native', mpi_info_int, ierr) + call MPI_FILE_READ(ifile, MPI_IO_DATA%var(i)%sf, data_size, mpi_p, status, ierr) end do end if call s_mpi_barrier() call MPI_FILE_CLOSE(ifile, ierr) - else - call s_mpi_abort('File '//trim(file_loc)//' is missing. Exiting. ') + call s_mpi_abort('File ' // trim(file_loc) // ' is missing. Exiting. ') end if call s_mpi_barrier() - #endif end subroutine s_read_parallel_ic_data_files !> @brief Initializes all pre-process modules, allocates data structures, and sets I/O procedure pointers. impure subroutine s_initialize_modules - ! Computation of parameters, allocation procedures, and/or any other tasks - ! needed to properly setup the modules + + ! Computation of parameters, allocation procedures, and/or any other tasks needed to properly setup the modules call s_initialize_global_parameters_module() if (bubbles_euler .or. bubbles_lagrange) then call s_initialize_bubbles_model() @@ -728,8 +592,7 @@ contains call s_initialize_boundary_common_module() if (relax) call s_initialize_phasechange_module() - ! Create the D directory if it doesn't exit, to store - ! the serial data files + ! Create the D directory if it doesn't exit, to store the serial data files call s_create_directory('D') ! Associate pointers for serial or parallel I/O @@ -770,20 +633,17 @@ contains impure subroutine s_apply_initial_condition(start, finish) real(wp), intent(inout) :: start, finish + integer :: j, k, l + real(wp) :: r2 - integer :: j, k, l - real(wp) :: r2 - - ! Setting up the grid and the initial condition. If the grid is read in from - ! preexisting grid data files, it is checked for consistency. If the grid is - ! not read in, it is generated from scratch according to the inputs provided - ! by the user. The initial condition may also be read in. It in turn is not - ! checked for consistency since it WILL further be edited by the pre-process - ! and also because it may be incomplete at the time it is read in. Finally, - ! when the grid and initial condition are completely setup, they are written - ! to their respective data files. + ! Setting up the grid and the initial condition. If the grid is read in from preexisting grid data files, it is checked for + ! consistency. If the grid is not read in, it is generated from scratch according to the inputs provided by the user. The + ! initial condition may also be read in. It in turn is not checked for consistency since it WILL further be edited by the + ! pre-process and also because it may be incomplete at the time it is read in. Finally, when the grid and initial condition + ! are completely setup, they are written to their respective data files. ! Setting up grid and initial condition + call cpu_time(start) if (old_ic) call s_read_ic_data_files(q_cons_vf) @@ -808,8 +668,7 @@ contains if (relax) then if (proc_rank == 0) then - print *, 'initial condition might have been altered due to enforcement of & -& pTg-equilibrium (relax = "T" activated)' + print *, 'initial condition might have been altered due to enforcement of pTg-equilibrium (relax = "T" activated)' end if call s_infinite_relaxation_k(q_cons_vf) @@ -818,14 +677,15 @@ contains call s_write_data_files(q_cons_vf, q_prim_vf, bc_type) call cpu_time(finish) + end subroutine s_apply_initial_condition !> @brief Gathers processor timing data and writes elapsed wall-clock time to a summary file. impure subroutine s_save_data(proc_time, time_avg, time_final, file_exists) real(wp), dimension(:), intent(inout) :: proc_time - real(wp), intent(inout) :: time_avg, time_final - logical, intent(inout) :: file_exists + real(wp), intent(inout) :: time_avg, time_final + logical, intent(inout) :: file_exists call s_mpi_barrier() @@ -853,18 +713,19 @@ contains close (1) end if end if + end subroutine s_save_data !> @brief Initializes MPI, reads and validates user inputs on rank 0, and decomposes the computational domain. impure subroutine s_initialize_mpi_domain + ! Initialization of the MPI environment call s_mpi_initialize() - ! Rank 0 processor assigns default values to user inputs prior to reading - ! those in from the input file. Next, the user inputs are read in and their - ! consistency is checked. The detection of any inconsistencies automatically - ! leads to the termination of the pre-process. + ! Rank 0 processor assigns default values to user inputs prior to reading those in from the input file. Next, the user + ! inputs are read in and their consistency is checked. The detection of any inconsistencies automatically leads to the + ! termination of the pre-process. if (proc_rank == 0) then call s_assign_default_values_to_user_inputs() @@ -874,16 +735,17 @@ contains print '(" Pre-processing a ", I0, "x", I0, "x", I0, " case on ", I0, " rank(s)")', m, n, p, num_procs end if - ! Broadcasting the user inputs to all of the processors and performing the - ! parallel computational domain decomposition. Neither procedure has to be - ! carried out if pre-process is in fact not truly executed in parallel. + ! Broadcasting the user inputs to all of the processors and performing the parallel computational domain decomposition. + ! Neither procedure has to be carried out if pre-process is in fact not truly executed in parallel. call s_mpi_bcast_user_inputs() call s_initialize_parallel_io() call s_mpi_decompose_computational_domain() + end subroutine s_initialize_mpi_domain !> @brief Finalizes all pre-process modules, deallocates resources, and shuts down MPI. impure subroutine s_finalize_modules + ! Disassociate pointers for serial and parallel I/O s_generate_grid => null() s_read_grid_data_files => null() @@ -903,6 +765,7 @@ contains call s_finalize_initial_condition_module() ! Finalization of the MPI environment call s_mpi_finalize() + end subroutine s_finalize_modules end module m_start_up diff --git a/src/pre_process/p_main.f90 b/src/pre_process/p_main.f90 index 9197eecf8f..fb663412f0 100644 --- a/src/pre_process/p_main.f90 +++ b/src/pre_process/p_main.f90 @@ -2,18 +2,16 @@ !! @file !! @brief Contains program p_main -!> @brief This program takes care of setting up the initial condition and -!! grid data for the multicomponent flow code. +!> @brief This program takes care of setting up the initial condition and grid data for the multicomponent flow code. program p_main - use m_global_parameters !< Global parameters for the code - + use m_global_parameters !< Global parameters for the code use m_start_up implicit none - logical :: file_exists - real(wp) :: start, finish, time_avg, time_final + logical :: file_exists + real(wp) :: start, finish, time_avg, time_final real(wp), allocatable, dimension(:) :: proc_time call random_seed() @@ -37,5 +35,4 @@ program p_main deallocate (proc_time) call s_finalize_modules() - end program p_main diff --git a/src/simulation/include/inline_capillary.fpp b/src/simulation/include/inline_capillary.fpp index 89e1aabaec..ba62d99740 100644 --- a/src/simulation/include/inline_capillary.fpp +++ b/src/simulation/include/inline_capillary.fpp @@ -1,5 +1,4 @@ #:def compute_capillary_stress_tensor() - Omega(1, 1) = -sigma*(w2*w2 + w3*w3)/normW #:if not MFC_CASE_OPTIMIZATION or num_dims > 1 Omega(2, 1) = sigma*w1*w2/normW @@ -18,7 +17,5 @@ Omega(3, 3) = -sigma*(w1*w1 + w2*w2)/normW #:endif - end if - #:enddef compute_capillary_stress_tensor diff --git a/src/simulation/include/inline_riemann.fpp b/src/simulation/include/inline_riemann.fpp index d8d0cc87c7..aae4015292 100644 --- a/src/simulation/include/inline_riemann.fpp +++ b/src/simulation/include/inline_riemann.fpp @@ -9,32 +9,25 @@ H_avg = 5.e-1_wp*(H_L + H_R) gamma_avg = 5.e-1_wp*(gamma_L + gamma_R) qv_avg = 5.e-1_wp*(qv_L + qv_R) - #:enddef arithmetic_avg #:def roe_avg() - rho_avg = sqrt(rho_L*rho_R) vel_avg_rms = 0._wp $:GPU_LOOP(parallelism='[seq]') do i = 1, num_vels - vel_avg_rms = vel_avg_rms + (sqrt(rho_L)*vel_L(i) + sqrt(rho_R)*vel_R(i))**2._wp/ & - (sqrt(rho_L) + sqrt(rho_R))**2._wp + vel_avg_rms = vel_avg_rms + (sqrt(rho_L)*vel_L(i) + sqrt(rho_R)*vel_R(i))**2._wp/(sqrt(rho_L) + sqrt(rho_R))**2._wp end do - H_avg = (sqrt(rho_L)*H_L + sqrt(rho_R)*H_R)/ & - (sqrt(rho_L) + sqrt(rho_R)) + H_avg = (sqrt(rho_L)*H_L + sqrt(rho_R)*H_R)/(sqrt(rho_L) + sqrt(rho_R)) - gamma_avg = (sqrt(rho_L)*gamma_L + sqrt(rho_R)*gamma_R)/ & - (sqrt(rho_L) + sqrt(rho_R)) + gamma_avg = (sqrt(rho_L)*gamma_L + sqrt(rho_R)*gamma_R)/(sqrt(rho_L) + sqrt(rho_R)) - vel_avg_rms = (sqrt(rho_L)*vel_L(1) + sqrt(rho_R)*vel_R(1))**2._wp/ & - (sqrt(rho_L) + sqrt(rho_R))**2._wp + vel_avg_rms = (sqrt(rho_L)*vel_L(1) + sqrt(rho_R)*vel_R(1))**2._wp/(sqrt(rho_L) + sqrt(rho_R))**2._wp - qv_avg = (sqrt(rho_L)*qv_L + sqrt(rho_R)*qv_R)/ & - (sqrt(rho_L) + sqrt(rho_R)) + qv_avg = (sqrt(rho_L)*qv_L + sqrt(rho_R)*qv_R)/(sqrt(rho_L) + sqrt(rho_R)) if (chemistry) then eps = 0.001_wp @@ -57,7 +50,8 @@ if (abs(T_L - T_R) < eps) then ! Case when T_L and T_R are very close Cp_avg = sum(Yi_avg(:)*(0.5_wp*Cp_iL(:) + 0.5_wp*Cp_iR(:))*gas_constant/molecular_weights_nonparameter(:)) - Cv_avg = sum(Yi_avg(:)*((0.5_wp*Cp_iL(:) + 0.5_wp*Cp_iR(:))*gas_constant/molecular_weights_nonparameter(:) - gas_constant/molecular_weights_nonparameter(:))) + Cv_avg = sum(Yi_avg(:)*((0.5_wp*Cp_iL(:) + 0.5_wp*Cp_iR(:))*gas_constant/molecular_weights_nonparameter(:) & + & - gas_constant/molecular_weights_nonparameter(:))) else ! Normal calculation when T_L and T_R are sufficiently different Cp_avg = sum(Yi_avg(:)*(h_iR(:) - h_iL(:))/(T_R - T_L)) @@ -65,13 +59,15 @@ end if gamma_avg = Cp_avg/Cv_avg - Phi_avg(:) = (gamma_avg - 1._wp)*(vel_avg_rms/2.0_wp - h_avg_2(:)) + gamma_avg*gas_constant/molecular_weights_nonparameter(:)*T_avg + Phi_avg(:) = (gamma_avg - 1._wp)*(vel_avg_rms/2.0_wp - h_avg_2(:)) & + & + gamma_avg*gas_constant/molecular_weights_nonparameter(:)*T_avg c_sum_Yi_Phi = sum(Yi_avg(:)*Phi_avg(:)) #:else if (abs(T_L - T_R) < eps) then ! Case when T_L and T_R are very close Cp_avg = sum(Yi_avg(:)*(0.5_wp*Cp_iL(:) + 0.5_wp*Cp_iR(:))*gas_constant/molecular_weights(:)) - Cv_avg = sum(Yi_avg(:)*((0.5_wp*Cp_iL(:) + 0.5_wp*Cp_iR(:))*gas_constant/molecular_weights(:) - gas_constant/molecular_weights(:))) + Cv_avg = sum(Yi_avg(:)*((0.5_wp*Cp_iL(:) + 0.5_wp*Cp_iR(:))*gas_constant/molecular_weights(:) & + & - gas_constant/molecular_weights(:))) else ! Normal calculation when T_L and T_R are sufficiently different Cp_avg = sum(Yi_avg(:)*(h_iR(:) - h_iL(:))/(T_R - T_L)) @@ -82,13 +78,10 @@ Phi_avg(:) = (gamma_avg - 1._wp)*(vel_avg_rms/2.0_wp - h_avg_2(:)) + gamma_avg*gas_constant/molecular_weights(:)*T_avg c_sum_Yi_Phi = sum(Yi_avg(:)*Phi_avg(:)) #:endif - end if - #:enddef roe_avg #:def compute_average_state() - if (avg_state == 1) then @:roe_avg() end if @@ -96,29 +89,23 @@ if (avg_state == 2) then @:arithmetic_avg() end if - #:enddef compute_average_state #:def compute_low_Mach_correction() - if (riemann_solver == 1 .or. riemann_solver == 5) then - zcoef = min(1._wp, max(vel_L_rms**5.e-1_wp/c_L, vel_R_rms**5.e-1_wp/c_R)) pcorr = 0._wp if (low_Mach == 1) then pcorr = -(s_P - s_M)*(rho_L + rho_R)/8._wp*(zcoef - 1._wp) end if - else if (riemann_solver == 2) then zcoef = min(1._wp, max(vel_L_rms**5.e-1_wp/c_L, vel_R_rms**5.e-1_wp/c_R)) pcorr = 0._wp if (low_Mach == 1) then - pcorr = rho_L*rho_R* & - (s_L - vel_L(dir_idx(1)))*(s_R - vel_R(dir_idx(1)))*(vel_R(dir_idx(1)) - vel_L(dir_idx(1)))/ & - (rho_R*(s_R - vel_R(dir_idx(1))) - rho_L*(s_L - vel_L(dir_idx(1))))* & - (zcoef - 1._wp) + pcorr = rho_L*rho_R*(s_L - vel_L(dir_idx(1)))*(s_R - vel_R(dir_idx(1)))*(vel_R(dir_idx(1)) - vel_L(dir_idx(1))) & + & /(rho_R*(s_R - vel_R(dir_idx(1))) - rho_L*(s_L - vel_L(dir_idx(1))))*(zcoef - 1._wp) else if (low_Mach == 2) then vel_L_tmp = 5.e-1_wp*((vel_L(dir_idx(1)) + vel_R(dir_idx(1))) + zcoef*(vel_L(dir_idx(1)) - vel_R(dir_idx(1)))) vel_R_tmp = 5.e-1_wp*((vel_L(dir_idx(1)) + vel_R(dir_idx(1))) + zcoef*(vel_R(dir_idx(1)) - vel_L(dir_idx(1)))) @@ -126,5 +113,4 @@ vel_R(dir_idx(1)) = vel_R_tmp end if end if - #:enddef compute_low_Mach_correction diff --git a/src/simulation/m_acoustic_src.fpp b/src/simulation/m_acoustic_src.fpp index 5b021fecbf..1f30873f20 100644 --- a/src/simulation/m_acoustic_src.fpp +++ b/src/simulation/m_acoustic_src.fpp @@ -7,67 +7,70 @@ !> @brief Applies acoustic pressure source terms including focused, planar, and broadband transducers module m_acoustic_src - use m_derived_types !< Definitions of the derived types - - use m_global_parameters !< Definitions of the global parameters - - use m_bubbles !< Bubble dynamic routines - - use m_variables_conversion !< State variables type conversion procedures - - use m_helper_basic !< Functions to compare floating point numbers - - use m_constants !< Definitions of the constants + use m_derived_types !< Definitions of the derived types + use m_global_parameters !< Definitions of the global parameters + use m_bubbles !< Bubble dynamic routines + use m_variables_conversion !< State variables type conversion procedures + use m_helper_basic !< Functions to compare floating point numbers + use m_constants !< Definitions of the constants implicit none + private; public :: s_initialize_acoustic_src, s_precalculate_acoustic_spatial_sources, s_acoustic_src_calculations integer, allocatable, dimension(:) :: pulse, support - $:GPU_DECLARE(create='[pulse,support]') + $:GPU_DECLARE(create='[pulse, support]') logical, allocatable, dimension(:) :: dipole $:GPU_DECLARE(create='[dipole]') - real(wp), allocatable, target, dimension(:, :) :: loc_acoustic + real(wp), allocatable, target, dimension(:,:) :: loc_acoustic $:GPU_DECLARE(create='[loc_acoustic]') real(wp), allocatable, dimension(:) :: mag, length, height, wavelength, frequency real(wp), allocatable, dimension(:) :: gauss_sigma_dist, gauss_sigma_time, npulse, dir, delay - $:GPU_DECLARE(create='[mag,length,height,wavelength,frequency]') - $:GPU_DECLARE(create='[gauss_sigma_dist,gauss_sigma_time,npulse,dir,delay]') + $:GPU_DECLARE(create='[mag, length, height, wavelength, frequency]') + $:GPU_DECLARE(create='[gauss_sigma_dist, gauss_sigma_time, npulse, dir, delay]') real(wp), allocatable, dimension(:) :: foc_length, aperture - $:GPU_DECLARE(create='[foc_length,aperture]') + $:GPU_DECLARE(create='[foc_length, aperture]') real(wp), allocatable, dimension(:) :: element_spacing_angle, element_polygon_ratio, rotate_angle - $:GPU_DECLARE(create='[element_spacing_angle,element_polygon_ratio,rotate_angle]') + $:GPU_DECLARE(create='[element_spacing_angle, element_polygon_ratio, rotate_angle]') real(wp), allocatable, dimension(:) :: bb_bandwidth, bb_lowest_freq - $:GPU_DECLARE(create='[bb_bandwidth,bb_lowest_freq]') + $:GPU_DECLARE(create='[bb_bandwidth, bb_lowest_freq]') integer, allocatable, dimension(:) :: num_elements, element_on, bb_num_freq - $:GPU_DECLARE(create='[num_elements,element_on,bb_num_freq]') + $:GPU_DECLARE(create='[num_elements, element_on, bb_num_freq]') !> @name Acoustic source terms !> @{ - real(wp), allocatable, dimension(:, :, :) :: mass_src, e_src - real(wp), allocatable, dimension(:, :, :, :) :: mom_src + real(wp), allocatable, dimension(:,:,:) :: mass_src, e_src + real(wp), allocatable, dimension(:,:,:,:) :: mom_src !> @} - $:GPU_DECLARE(create='[mass_src,e_src,mom_src]') + $:GPU_DECLARE(create='[mass_src, e_src, mom_src]') - integer, dimension(:), allocatable :: source_spatials_num_points !< Number of non-zero source grid points for each source + integer, dimension(:), allocatable :: source_spatials_num_points !< Number of non-zero source grid points for each source $:GPU_DECLARE(create='[source_spatials_num_points]') - type(source_spatial_type), dimension(:), allocatable :: source_spatials !< Data of non-zero source grid points for each source + type(source_spatial_type), dimension(:), allocatable :: source_spatials !< Data of non-zero source grid points for each source $:GPU_DECLARE(create='[source_spatials]') contains !> This subroutine initializes the acoustic source module impure subroutine s_initialize_acoustic_src - integer :: i, j !< generic loop variables - @:ALLOCATE(loc_acoustic(1:3, 1:num_source), mag(1:num_source), dipole(1:num_source), support(1:num_source), length(1:num_source), height(1:num_source), wavelength(1:num_source), frequency(1:num_source), gauss_sigma_dist(1:num_source), gauss_sigma_time(1:num_source), foc_length(1:num_source), aperture(1:num_source), npulse(1:num_source), pulse(1:num_source), dir(1:num_source), delay(1:num_source), element_polygon_ratio(1:num_source), rotate_angle(1:num_source), element_spacing_angle(1:num_source), num_elements(1:num_source), element_on(1:num_source), bb_num_freq(1:num_source), bb_bandwidth(1:num_source), bb_lowest_freq(1:num_source)) + integer :: i, j !< generic loop variables + + @:ALLOCATE(loc_acoustic(1:3, 1:num_source), mag(1:num_source), dipole(1:num_source), support(1:num_source), & + & length(1:num_source), height(1:num_source), wavelength(1:num_source), frequency(1:num_source), & + & gauss_sigma_dist(1:num_source), gauss_sigma_time(1:num_source), foc_length(1:num_source), & + & aperture(1:num_source), npulse(1:num_source), pulse(1:num_source), dir(1:num_source), delay(1:num_source), & + & element_polygon_ratio(1:num_source), rotate_angle(1:num_source), element_spacing_angle(1:num_source), & + & num_elements(1:num_source), element_on(1:num_source), bb_num_freq(1:num_source), bb_bandwidth(1:num_source), & + & bb_lowest_freq(1:num_source)) do i = 1, num_source do j = 1, 3 @@ -104,18 +107,15 @@ contains else rotate_angle(i) = acoustic(i)%rotate_angle end if - if (f_is_default(acoustic(i)%delay)) then ! m_checker guarantees acoustic(i)%delay is set for pulse = 2 (Gaussian) - delay(i) = 0._wp ! Defaults to zero for sine and square waves + if (f_is_default(acoustic(i)%delay)) then ! m_checker guarantees acoustic(i)%delay is set for pulse = 2 (Gaussian) + delay(i) = 0._wp ! Defaults to zero for sine and square waves else delay(i) = acoustic(i)%delay end if end do - $:GPU_UPDATE(device='[loc_acoustic,mag,dipole,support,length, & - & height,wavelength,frequency,gauss_sigma_dist, & - & gauss_sigma_time,foc_length,aperture,npulse,pulse, & - & dir,delay,element_polygon_ratio,rotate_angle, & - & element_spacing_angle,num_elements,element_on, & - & bb_num_freq,bb_bandwidth,bb_lowest_freq]') + $:GPU_UPDATE(device='[loc_acoustic, mag, dipole, support, length, height, wavelength, frequency, gauss_sigma_dist, & + & gauss_sigma_time, foc_length, aperture, npulse, pulse, dir, delay, element_polygon_ratio, rotate_angle, & + & element_spacing_angle, num_elements, element_on, bb_num_freq, bb_bandwidth, bb_lowest_freq]') @:ALLOCATE(mass_src(0:m, 0:n, 0:p)) @:ALLOCATE(mom_src(1:num_vels, 0:m, 0:n, 0:p)) @@ -129,9 +129,8 @@ contains !! @param rhs_vf rhs variables impure subroutine s_acoustic_src_calculations(q_cons_vf, q_prim_vf, rhs_vf) - type(scalar_field), dimension(sys_size), intent(inout) :: q_cons_vf !< Conservative variables - type(scalar_field), dimension(sys_size), intent(inout) :: q_prim_vf !< Primitive variables - + type(scalar_field), dimension(sys_size), intent(inout) :: q_cons_vf !< Conservative variables + type(scalar_field), dimension(sys_size), intent(inout) :: q_prim_vf !< Primitive variables type(scalar_field), dimension(sys_size), intent(inout) :: rhs_vf #:if not MFC_CASE_OPTIMIZATION and USING_AMD @@ -139,28 +138,25 @@ contains #:else real(wp), dimension(num_fluids) :: myalpha, myalpha_rho #:endif - real(wp) :: myRho, B_tait - real(wp) :: sim_time, c, small_gamma - real(wp) :: frequency_local, gauss_sigma_time_local - real(wp) :: mass_src_diff, mom_src_diff - real(wp) :: source_temporal - real(wp) :: period_BB !< period of each sine wave in broadband source - real(wp) :: sl_BB !< spectral level at each frequency - real(wp) :: ffre_BB !< source term corresponding to each frequency - real(wp) :: sum_BB !< total source term for the broadband wave - real(wp), allocatable, dimension(:) :: phi_rn !< random phase shift for each frequency - - integer :: i, j, k, l, q !< generic loop variables - integer :: ai !< acoustic source index - integer :: num_points - - logical :: freq_conv_flag, gauss_conv_flag - - integer, parameter :: mass_label = 1, mom_label = 2 - - sim_time = mytime ! Accumulated time, correct under adaptive dt - - $:GPU_PARALLEL_LOOP(private='[j,k,l]', collapse=3) + real(wp) :: myRho, B_tait + real(wp) :: sim_time, c, small_gamma + real(wp) :: frequency_local, gauss_sigma_time_local + real(wp) :: mass_src_diff, mom_src_diff + real(wp) :: source_temporal + real(wp) :: period_BB !< period of each sine wave in broadband source + real(wp) :: sl_BB !< spectral level at each frequency + real(wp) :: ffre_BB !< source term corresponding to each frequency + real(wp) :: sum_BB !< total source term for the broadband wave + real(wp), allocatable, dimension(:) :: phi_rn !< random phase shift for each frequency + integer :: i, j, k, l, q !< generic loop variables + integer :: ai !< acoustic source index + integer :: num_points + logical :: freq_conv_flag, gauss_conv_flag + integer, parameter :: mass_label = 1, mom_label = 2 + + sim_time = mytime ! Accumulated time, correct under adaptive dt + + $:GPU_PARALLEL_LOOP(private='[j, k, l]', collapse=3) do l = 0, p do k = 0, n do j = 0, m @@ -178,12 +174,11 @@ contains do ai = 1, num_source ! Skip if the pulse has not started yet for sine and square waves if (.not. (sim_time < delay(ai) .and. (pulse(ai) == 1 .or. pulse(ai) == 3))) then - ! Decide if frequency need to be converted from wavelength freq_conv_flag = f_is_default(frequency(ai)) gauss_conv_flag = f_is_default(gauss_sigma_time(ai)) - num_points = source_spatials_num_points(ai) ! Use scalar to force firstprivate to prevent GPU bug + num_points = source_spatials_num_points(ai) ! Use scalar to force firstprivate to prevent GPU bug ! Calculate the broadband source period_BB = 0._wp @@ -214,7 +209,9 @@ contains deallocate (phi_rn) - $:GPU_PARALLEL_LOOP(private='[myalpha,myalpha_rho, myRho, B_tait,c, small_gamma, frequency_local, gauss_sigma_time_local, mass_src_diff, mom_src_diff, source_temporal, j, k, l, q ]', copyin = '[sum_BB, freq_conv_flag, gauss_conv_flag, sim_time]') + $:GPU_PARALLEL_LOOP(private='[myalpha, myalpha_rho, myRho, B_tait, c, small_gamma, frequency_local, & + & gauss_sigma_time_local, mass_src_diff, mom_src_diff, source_temporal, j, k, l, q ]', & + & copyin = '[sum_BB, freq_conv_flag, gauss_conv_flag, sim_time]') do i = 1, num_points j = source_spatials(ai)%coord(1, i) k = source_spatials(ai)%coord(2, i) @@ -263,29 +260,28 @@ contains if (pulse(ai) == 2) gauss_sigma_time_local = f_gauss_sigma_time_local(gauss_conv_flag, ai, c) ! Update momentum source term - call s_source_temporal(sim_time, c, ai, mom_label, frequency_local, gauss_sigma_time_local, source_temporal, sum_BB) + call s_source_temporal(sim_time, c, ai, mom_label, frequency_local, gauss_sigma_time_local, source_temporal, & + & sum_BB) mom_src_diff = source_temporal*source_spatials(ai)%val(i) - if (dipole(ai)) then ! Double amplitude & No momentum source term (only works for Planar) + if (dipole(ai)) then ! Double amplitude & No momentum source term (only works for Planar) mass_src(j, k, l) = mass_src(j, k, l) + 2._wp*mom_src_diff/c if (model_eqns /= 4) E_src(j, k, l) = E_src(j, k, l) + 2._wp*mom_src_diff*c/(small_gamma - 1._wp) cycle end if - if (n == 0) then ! 1D - mom_src(1, j, k, l) = mom_src(1, j, k, l) + mom_src_diff*sign(1._wp, dir(ai)) ! Left or right-going wave - - elseif (p == 0) then ! 2D - if (support(ai) < 5) then ! Planar + if (n == 0) then ! 1D + mom_src(1, j, k, l) = mom_src(1, j, k, l) + mom_src_diff*sign(1._wp, dir(ai)) ! Left or right-going wave + else if (p == 0) then ! 2D + if (support(ai) < 5) then ! Planar mom_src(1, j, k, l) = mom_src(1, j, k, l) + mom_src_diff*cos(dir(ai)) mom_src(2, j, k, l) = mom_src(2, j, k, l) + mom_src_diff*sin(dir(ai)) else mom_src(1, j, k, l) = mom_src(1, j, k, l) + mom_src_diff*cos(source_spatials(ai)%angle(i)) mom_src(2, j, k, l) = mom_src(2, j, k, l) + mom_src_diff*sin(source_spatials(ai)%angle(i)) end if - - else ! 3D - if (support(ai) < 5) then ! Planar + else ! 3D + if (support(ai) < 5) then ! Planar mom_src(1, j, k, l) = mom_src(1, j, k, l) + mom_src_diff*cos(dir(ai)) mom_src(2, j, k, l) = mom_src(2, j, k, l) + mom_src_diff*sin(dir(ai)) else @@ -296,11 +292,13 @@ contains end if ! Update mass source term - if (support(ai) < 5) then ! Planar + if (support(ai) < 5) then ! Planar mass_src_diff = mom_src_diff/c - else ! Spherical or cylindrical support - ! Mass source term must be calculated differently using a correction term for spherical and cylindrical support - call s_source_temporal(sim_time, c, ai, mass_label, frequency_local, gauss_sigma_time_local, source_temporal, sum_BB) + else ! Spherical or cylindrical support + ! Mass source term must be calculated differently using a correction term for spherical and cylindrical + ! support + call s_source_temporal(sim_time, c, ai, mass_label, frequency_local, gauss_sigma_time_local, & + & source_temporal, sum_BB) mass_src_diff = source_temporal*source_spatials(ai)%val(i) end if mass_src(j, k, l) = mass_src(j, k, l) + mass_src_diff @@ -309,14 +307,13 @@ contains if (model_eqns /= 4) then E_src(j, k, l) = E_src(j, k, l) + mass_src_diff*c**2._wp/(small_gamma - 1._wp) end if - end do $:END_GPU_PARALLEL_LOOP() end if end do ! Update the rhs variables - $:GPU_PARALLEL_LOOP(private='[j,k,l]',collapse=3) + $:GPU_PARALLEL_LOOP(private='[j, k, l]',collapse=3) do l = 0, p do k = 0, n do j = 0, m @@ -333,6 +330,7 @@ contains end do end do $:END_GPU_PARALLEL_LOOP() + end subroutine s_acoustic_src_calculations !> This subroutine gives the temporally varying amplitude of the pulse @@ -345,29 +343,29 @@ contains !! @param source Source term amplitude !! @param sum_bb Sum of basis functions elemental subroutine s_source_temporal(sim_time, c, ai, term_index, frequency_local, gauss_sigma_time_local, source, sum_BB) + $:GPU_ROUTINE(parallelism='[seq]') - integer, intent(in) :: ai, term_index - real(wp), intent(in) :: sim_time, c, sum_BB - real(wp), intent(in) :: frequency_local, gauss_sigma_time_local + integer, intent(in) :: ai, term_index + real(wp), intent(in) :: sim_time, c, sum_BB + real(wp), intent(in) :: frequency_local, gauss_sigma_time_local real(wp), intent(out) :: source - - real(wp) :: omega ! angular frequency - real(wp) :: sine_wave ! sine function for square wave - real(wp) :: foc_length_factor ! Scale amplitude with radius for spherical support + real(wp) :: omega ! angular frequency + real(wp) :: sine_wave ! sine function for square wave + real(wp) :: foc_length_factor ! Scale amplitude with radius for spherical support ! i.e. Spherical support -> 1/r scaling; Cylindrical support -> 1/sqrt(r) [empirical correction: ^-0.5 -> ^-0.85] integer, parameter :: mass_label = 1 if (n == 0) then foc_length_factor = 1._wp - elseif (p == 0 .and. (.not. cyl_coord)) then ! 2D axisymmetric case is physically 3D - foc_length_factor = foc_length(ai)**(-0.85_wp); ! Empirical correction + else if (p == 0 .and. (.not. cyl_coord)) then ! 2D axisymmetric case is physically 3D + foc_length_factor = foc_length(ai)**(-0.85_wp) ! Empirical correction else - foc_length_factor = 1/foc_length(ai); + foc_length_factor = 1/foc_length(ai) end if source = 0._wp - if (pulse(ai) == 1) then ! Sine wave + if (pulse(ai) == 1) then ! Sine wave if ((sim_time - delay(ai))*frequency_local > npulse(ai)) return omega = 2._wp*pi*frequency_local @@ -376,17 +374,14 @@ contains if (term_index == mass_label) then source = source/c + foc_length_factor*mag(ai)*(cos((sim_time - delay(ai))*omega) - 1._wp)/omega end if - - elseif (pulse(ai) == 2) then ! Gaussian pulse + else if (pulse(ai) == 2) then ! Gaussian pulse source = mag(ai)*exp(-0.5_wp*((sim_time - delay(ai))**2._wp)/(gauss_sigma_time_local**2._wp)) if (term_index == mass_label) then - source = source/c - & - foc_length_factor*mag(ai)*sqrt(pi/2)*gauss_sigma_time_local* & - (erf((sim_time - delay(ai))/(sqrt(2._wp)*gauss_sigma_time_local)) + 1) + source = source/c - foc_length_factor*mag(ai)*sqrt(pi/2)*gauss_sigma_time_local*(erf((sim_time - delay(ai)) & + & /(sqrt(2._wp)*gauss_sigma_time_local)) + 1) end if - - elseif (pulse(ai) == 3) then ! Square wave + else if (pulse(ai) == 3) then ! Square wave if ((sim_time - delay(ai))*frequency_local > npulse(ai)) return omega = 2._wp*pi*frequency_local @@ -397,23 +392,24 @@ contains if (abs(sine_wave) < 1.e-2_wp) then source = mag(ai)*sine_wave*1.e2_wp end if - - elseif (pulse(ai) == 4) then ! Broadband wave + else if (pulse(ai) == 4) then ! Broadband wave source = sum_BB end if + end subroutine s_source_temporal !> This subroutine identifies and precalculates the non-zero acoustic spatial sources before time-stepping impure subroutine s_precalculate_acoustic_spatial_sources - integer :: j, k, l, ai - integer :: count - integer :: dim - real(wp) :: source_spatial, angle, xyz_to_r_ratios(3) + + integer :: j, k, l, ai + integer :: count + integer :: dim + real(wp) :: source_spatial, angle, xyz_to_r_ratios(3) real(wp), parameter :: threshold = 1.e-10_wp if (n == 0) then dim = 1 - elseif (p == 0) then + else if (p == 0) then dim = 2 else dim = 3 @@ -428,7 +424,7 @@ contains do l = 0, p do k = 0, n do j = 0, m - call s_source_spatial(j, k, l, loc_acoustic(:, ai), ai, source_spatial, angle, xyz_to_r_ratios) + call s_source_spatial(j, k, l, loc_acoustic(:,ai), ai, source_spatial, angle, xyz_to_r_ratios) if (abs(source_spatial) < threshold) cycle count = count + 1 end do @@ -446,11 +442,11 @@ contains @:ACC_SETUP_source_spatials(source_spatials(ai)) ! Second pass: Store the values - count = 0 ! Reset counter + count = 0 ! Reset counter do l = 0, p do k = 0, n do j = 0, m - call s_source_spatial(j, k, l, loc_acoustic(:, ai), ai, source_spatial, angle, xyz_to_r_ratios) + call s_source_spatial(j, k, l, loc_acoustic(:,ai), ai, source_spatial, angle, xyz_to_r_ratios) if (abs(source_spatial) < threshold) cycle count = count + 1 source_spatials(ai)%coord(1, count) = j @@ -459,7 +455,7 @@ contains source_spatials(ai)%val(count) = source_spatial if (support(ai) >= 5) then if (dim == 2) source_spatials(ai)%angle(count) = angle - if (dim == 3) source_spatials(ai)%xyz_to_r_ratios(1:3, count) = xyz_to_r_ratios + if (dim == 3) source_spatials(ai)%xyz_to_r_ratios(1:3,count) = xyz_to_r_ratios end if end do end do @@ -479,13 +475,12 @@ contains $:GPU_UPDATE(device='[source_spatials(ai)%xyz_to_r_ratios]') end if end if - end do #ifdef MFC_DEBUG do ai = 1, num_source write (*, '(A,I2,A,I8,A)') 'Acoustic source ', ai, ' has ', source_spatials_num_points(ai), & - ' grid points with non-zero source term' + & ' grid points with non-zero source term' end do #endif @@ -501,16 +496,17 @@ contains !! @param angle Angle of the source term with respect to the x-axis (for 2D or 2D axisymmetric) !! @param xyz_to_r_ratios Ratios of the [xyz]-component of the source term to the magnitude (for 3D) subroutine s_source_spatial(j, k, l, loc, ai, source, angle, xyz_to_r_ratios) - integer, intent(in) :: j, k, l, ai - real(wp), dimension(3), intent(in) :: loc - real(wp), intent(out) :: source, angle, xyz_to_r_ratios(3) - real(wp) :: sig, r(3) + integer, intent(in) :: j, k, l, ai + real(wp), dimension(3), intent(in) :: loc + real(wp), intent(out) :: source, angle, xyz_to_r_ratios(3) + real(wp) :: sig, r(3) ! Calculate sig spatial support width + if (n == 0) then sig = dx(j) - elseif (p == 0) then + else if (p == 0) then sig = maxval((/dx(j), dy(k)/)) else sig = maxval((/dx(j), dy(k), dz(l)/)) @@ -524,11 +520,12 @@ contains if (any(support(ai) == (/1, 2, 3, 4/))) then call s_source_spatial_planar(ai, sig, r, source) - elseif (any(support(ai) == (/5, 6, 7/))) then + else if (any(support(ai) == (/5, 6, 7/))) then call s_source_spatial_transducer(ai, sig, r, source, angle, xyz_to_r_ratios) - elseif (any(support(ai) == (/9, 10, 11/))) then + else if (any(support(ai) == (/9, 10, 11/))) then call s_source_spatial_transducer_array(ai, sig, r, source, angle, xyz_to_r_ratios) end if + end subroutine s_source_spatial !> This subroutine calculates the spatial support for planar acoustic sources in 1D, 2D, and 3D @@ -537,26 +534,27 @@ contains !! @param r Displacement from source to current point !! @param source Source term amplitude subroutine s_source_spatial_planar(ai, sig, r, source) - integer, intent(in) :: ai - real(wp), intent(in) :: sig, r(3) - real(wp), intent(out) :: source - real(wp) :: dist + integer, intent(in) :: ai + real(wp), intent(in) :: sig, r(3) + real(wp), intent(out) :: source + real(wp) :: dist source = 0._wp - if (support(ai) == 1) then ! 1D + if (support(ai) == 1) then ! 1D source = 1._wp/(sqrt(2._wp*pi)*sig/2._wp)*exp(-0.5_wp*(r(1)/(sig/2._wp))**2._wp) - - elseif (support(ai) == 2 .or. support(ai) == 3) then ! 2D or 3D + else if (support(ai) == 2 .or. support(ai) == 3) then ! 2D or 3D ! If we let unit vector e = (cos(dir), sin(dir)), - dist = r(1)*cos(dir(ai)) + r(2)*sin(dir(ai)) ! dot(r,e) - if ((r(1) - dist*cos(dir(ai)))**2._wp + (r(2) - dist*sin(dir(ai)))**2._wp < 0.25_wp*length(ai)**2._wp) then ! |r - dist*e| < length/2 - if (support(ai) /= 3 .or. abs(r(3)) < 0.25_wp*height(ai)) then ! additional height constraint for 3D + dist = r(1)*cos(dir(ai)) + r(2)*sin(dir(ai)) ! dot(r,e) + if ((r(1) - dist*cos(dir(ai)))**2._wp + (r(2) - dist*sin(dir(ai)))**2._wp < 0.25_wp*length(ai)**2._wp) & + & then ! |r - dist*e| < length/2 + if (support(ai) /= 3 .or. abs(r(3)) < 0.25_wp*height(ai)) then ! additional height constraint for 3D source = 1._wp/(sqrt(2._wp*pi)*sig/2._wp)*exp(-0.5_wp*(dist/(sig/2._wp))**2._wp) end if end if end if + end subroutine s_source_spatial_planar !> This subroutine calculates the spatial support for a single transducer in 2D, 2D axisymmetric, and 3D @@ -567,17 +565,17 @@ contains !! @param angle Angle of the source term with respect to the x-axis (for 2D or 2D axisymmetric) !! @param xyz_to_r_ratios Ratios of the [xyz]-component of the source term to the magnitude (for 3D) subroutine s_source_spatial_transducer(ai, sig, r, source, angle, xyz_to_r_ratios) - integer, intent(in) :: ai - real(wp), intent(in) :: sig, r(3) - real(wp), intent(out) :: source, angle, xyz_to_r_ratios(3) - real(wp) :: current_angle, angle_half_aperture, dist, norm + integer, intent(in) :: ai + real(wp), intent(in) :: sig, r(3) + real(wp), intent(out) :: source, angle, xyz_to_r_ratios(3) + real(wp) :: current_angle, angle_half_aperture, dist, norm - source = 0._wp ! If not affected by transducer + source = 0._wp ! If not affected by transducer angle = 0._wp xyz_to_r_ratios = 0._wp - if (support(ai) == 5 .or. support(ai) == 6) then ! 2D or 2D axisymmetric + if (support(ai) == 5 .or. support(ai) == 6) then ! 2D or 2D axisymmetric current_angle = -atan(r(2)/(foc_length(ai) - r(1))) angle_half_aperture = asin((aperture(ai)/2._wp)/(foc_length(ai))) @@ -586,8 +584,7 @@ contains source = 1._wp/(sqrt(2._wp*pi)*sig/2._wp)*exp(-0.5_wp*(dist/(sig/2._wp))**2._wp) angle = -atan(r(2)/(foc_length(ai) - r(1))) end if - - elseif (support(ai) == 7) then ! 3D + else if (support(ai) == 7) then ! 3D current_angle = -atan(sqrt(r(2)**2 + r(3)**2)/(foc_length(ai) - r(1))) angle_half_aperture = asin((aperture(ai)/2._wp)/(foc_length(ai))) @@ -600,8 +597,8 @@ contains xyz_to_r_ratios(2) = -r(2)/norm xyz_to_r_ratios(3) = -r(3)/norm end if - end if + end subroutine s_source_spatial_transducer !> This subroutine calculates the spatial support for multiple transducers in 2D, 2D axisymmetric, and 3D @@ -612,29 +609,29 @@ contains !! @param angle Angle of the source term with respect to the x-axis (for 2D or 2D axisymmetric) !! @param xyz_to_r_ratios Ratios of the [xyz]-component of the source term to the magnitude (for 3D) subroutine s_source_spatial_transducer_array(ai, sig, r, source, angle, xyz_to_r_ratios) - integer, intent(in) :: ai - real(wp), intent(in) :: sig, r(3) - real(wp), intent(out) :: source, angle, xyz_to_r_ratios(3) - integer :: elem, elem_min, elem_max - real(wp) :: current_angle, angle_half_aperture, angle_per_elem, dist - real(wp) :: angle_min, angle_max, norm - real(wp) :: poly_side_length, aperture_element_3D, angle_elem - real(wp) :: x2, y2, z2, x3, y3, z3, C, f, half_apert, dist_interp_to_elem_center + integer, intent(in) :: ai + real(wp), intent(in) :: sig, r(3) + real(wp), intent(out) :: source, angle, xyz_to_r_ratios(3) + integer :: elem, elem_min, elem_max + real(wp) :: current_angle, angle_half_aperture, angle_per_elem, dist + real(wp) :: angle_min, angle_max, norm + real(wp) :: poly_side_length, aperture_element_3D, angle_elem + real(wp) :: x2, y2, z2, x3, y3, z3, C, f, half_apert, dist_interp_to_elem_center - if (element_on(ai) == 0) then ! Full transducer + if (element_on(ai) == 0) then ! Full transducer elem_min = 1 elem_max = num_elements(ai) - else ! Transducer element specified + else ! Transducer element specified elem_min = element_on(ai) elem_max = element_on(ai) end if - source = 0._wp ! If not affected by any transducer element + source = 0._wp ! If not affected by any transducer element angle = 0._wp xyz_to_r_ratios = 0._wp - if (support(ai) == 9 .or. support(ai) == 10) then ! 2D or 2D axisymmetric + if (support(ai) == 9 .or. support(ai) == 10) then ! 2D or 2D axisymmetric current_angle = -atan(r(2)/(foc_length(ai) - r(1))) angle_half_aperture = asin((aperture(ai)/2._wp)/(foc_length(ai))) angle_per_elem = (2._wp*angle_half_aperture - (num_elements(ai) - 1._wp)*element_spacing_angle(ai))/num_elements(ai) @@ -647,11 +644,10 @@ contains if (current_angle > angle_min .and. current_angle < angle_max .and. r(1) < foc_length(ai)) then source = exp(-0.5_wp*(dist/(sig/2._wp))**2._wp)/(sqrt(2._wp*pi)*sig/2._wp) angle = current_angle - exit ! Assume elements don't overlap + exit ! Assume elements don't overlap end if end do - - elseif (support(ai) == 11) then ! 3D + else if (support(ai) == 11) then ! 3D poly_side_length = aperture(ai)*sin(pi/num_elements(ai)) aperture_element_3D = poly_side_length*element_polygon_ratio(ai) f = foc_length(ai) @@ -665,9 +661,9 @@ contains y2 = half_apert*cos(angle_elem) z2 = half_apert*sin(angle_elem) - ! Construct a plane normal to the line from the focal point to the elem center, - ! Point 3 is the intercept of the plane and the line from the focal point to the current location - C = f**2._wp/((r(1) - f)*(x2 - f) + r(2)*y2 + r(3)*z2) ! Constant for intermediate step + ! Construct a plane normal to the line from the focal point to the elem center, Point 3 is the intercept of the + ! plane and the line from the focal point to the current location + C = f**2._wp/((r(1) - f)*(x2 - f) + r(2)*y2 + r(3)*z2) ! Constant for intermediate step x3 = C*(r(1) - f) + f y3 = C*r(2) z3 = C*r(3) @@ -682,10 +678,9 @@ contains xyz_to_r_ratios(2) = -r(2)/norm xyz_to_r_ratios(3) = -r(3)/norm end if - end do - end if + end subroutine s_source_spatial_transducer_array !> This function performs wavelength to frequency conversion @@ -694,17 +689,19 @@ contains !! @param c Speed of sound !! @return frequency_local Converted frequency elemental function f_frequency_local(freq_conv_flag, ai, c) + $:GPU_ROUTINE(parallelism='[seq]') - logical, intent(in) :: freq_conv_flag - integer, intent(in) :: ai + logical, intent(in) :: freq_conv_flag + integer, intent(in) :: ai real(wp), intent(in) :: c - real(wp) :: f_frequency_local + real(wp) :: f_frequency_local if (freq_conv_flag) then f_frequency_local = c/wavelength(ai) else f_frequency_local = frequency(ai) end if + end function f_frequency_local !> This function performs Gaussian sigma dist to time conversion @@ -713,17 +710,19 @@ contains !! @param ai Acoustic source index !! @return gauss_sigma_time_local Converted Gaussian sigma time function f_gauss_sigma_time_local(gauss_conv_flag, ai, c) + $:GPU_ROUTINE(parallelism='[seq]') - logical, intent(in) :: gauss_conv_flag - integer, intent(in) :: ai + logical, intent(in) :: gauss_conv_flag + integer, intent(in) :: ai real(wp), intent(in) :: c - real(wp) :: f_gauss_sigma_time_local + real(wp) :: f_gauss_sigma_time_local if (gauss_conv_flag) then f_gauss_sigma_time_local = gauss_sigma_dist(ai)/c else f_gauss_sigma_time_local = gauss_sigma_time(ai) end if + end function f_gauss_sigma_time_local end module m_acoustic_src diff --git a/src/simulation/m_body_forces.fpp b/src/simulation/m_body_forces.fpp index 1b9b1a209b..5d13919865 100644 --- a/src/simulation/m_body_forces.fpp +++ b/src/simulation/m_body_forces.fpp @@ -7,50 +7,38 @@ !> @brief Computes gravitational and user-defined body force source terms for the momentum equations module m_body_forces - use m_derived_types !< Definitions of the derived types - - use m_global_parameters !< Definitions of the global parameters - + use m_derived_types !< Definitions of the derived types + use m_global_parameters !< Definitions of the global parameters use m_variables_conversion - use m_nvtx -! $:USE_GPU_MODULE() + ! $:USE_GPU_MODULE() implicit none - private; - public :: s_compute_body_forces_rhs, & - s_initialize_body_forces_module, & - s_finalize_body_forces_module + private + public :: s_compute_body_forces_rhs, s_initialize_body_forces_module, s_finalize_body_forces_module - real(wp), allocatable, dimension(:, :, :) :: rhoM + real(wp), allocatable, dimension(:,:,:) :: rhoM $:GPU_DECLARE(create='[rhoM]') contains - !> This subroutine initializes the module global array of mixture - !! densities in each grid cell + !> This subroutine initializes the module global array of mixture densities in each grid cell impure subroutine s_initialize_body_forces_module ! Simulation is at least 2D if (n > 0) then ! Simulation is 3D if (p > 0) then - @:ALLOCATE (rhoM(-buff_size:buff_size + m, & - -buff_size:buff_size + n, & - -buff_size:buff_size + p)) + @:ALLOCATE(rhoM(-buff_size:buff_size + m, -buff_size:buff_size + n, -buff_size:buff_size + p)) ! Simulation is 2D else - @:ALLOCATE (rhoM(-buff_size:buff_size + m, & - -buff_size:buff_size + n, & - 0:0)) + @:ALLOCATE(rhoM(-buff_size:buff_size + m, -buff_size:buff_size + n, 0:0)) end if ! Simulation is 1D else - @:ALLOCATE (rhoM(-buff_size:buff_size + m, & - 0:0, & - 0:0)) + @:ALLOCATE(rhoM(-buff_size:buff_size + m, 0:0, 0:0)) end if end subroutine s_initialize_body_forces_module @@ -62,7 +50,7 @@ contains #:for DIR, XYZ in [(1, 'x'), (2, 'y'), (3, 'z')] if (bf_${XYZ}$) then - accel_bf(${DIR}$) = g_${XYZ}$+k_${XYZ}$*sin(w_${XYZ}$*t - p_${XYZ}$) + accel_bf(${DIR}$) = g_${XYZ}$ + k_${XYZ}$*sin(w_${XYZ}$*t - p_${XYZ}$) end if #:endfor @@ -70,22 +58,20 @@ contains end subroutine s_compute_acceleration - !> This subroutine calculates the mixture density at each cell - !! center + !> This subroutine calculates the mixture density at each cell center !! @param q_cons_vf Conservative variables subroutine s_compute_mixture_density(q_cons_vf) type(scalar_field), dimension(sys_size), intent(in) :: q_cons_vf - integer :: i, j, k, l !< standard iterators + integer :: i, j, k, l !< standard iterators - $:GPU_PARALLEL_LOOP(private='[j,k,l]', collapse=3) + $:GPU_PARALLEL_LOOP(private='[j, k, l]', collapse=3) do l = 0, p do k = 0, n do j = 0, m rhoM(j, k, l) = 0._wp do i = 1, num_fluids - rhoM(j, k, l) = rhoM(j, k, l) + & - q_cons_vf(contxb + i - 1)%sf(j, k, l) + rhoM(j, k, l) = rhoM(j, k, l) + q_cons_vf(contxb + i - 1)%sf(j, k, l) end do end do end do @@ -94,23 +80,21 @@ contains end subroutine s_compute_mixture_density - !> This subroutine calculates the source term due to body forces - !! so the system can be advanced in time + !> This subroutine calculates the source term due to body forces so the system can be advanced in time !! @param q_cons_vf Conservative variables !! @param q_prim_vf Primitive variables !! @param rhs_vf Right-hand side accumulator subroutine s_compute_body_forces_rhs(q_prim_vf, q_cons_vf, rhs_vf) - type(scalar_field), dimension(sys_size), intent(in) :: q_prim_vf - type(scalar_field), dimension(sys_size), intent(in) :: q_cons_vf + type(scalar_field), dimension(sys_size), intent(in) :: q_prim_vf + type(scalar_field), dimension(sys_size), intent(in) :: q_cons_vf type(scalar_field), dimension(sys_size), intent(inout) :: rhs_vf - - integer :: i, j, k, l !< Loop variables + integer :: i, j, k, l !< Loop variables call s_compute_acceleration(mytime) call s_compute_mixture_density(q_cons_vf) - $:GPU_PARALLEL_LOOP(private='[i,j,k,l]', collapse=4) + $:GPU_PARALLEL_LOOP(private='[i, j, k, l]', collapse=4) do i = momxb, E_idx do l = 0, p do k = 0, n @@ -122,53 +106,46 @@ contains end do $:END_GPU_PARALLEL_LOOP() - if (bf_x) then ! x-direction body forces + if (bf_x) then ! x-direction body forces - $:GPU_PARALLEL_LOOP(private='[j,k,l]', collapse=3) + $:GPU_PARALLEL_LOOP(private='[j, k, l]', collapse=3) do l = 0, p do k = 0, n do j = 0, m - rhs_vf(momxb)%sf(j, k, l) = rhs_vf(momxb)%sf(j, k, l) + & - rhoM(j, k, l)*accel_bf(1) - rhs_vf(E_idx)%sf(j, k, l) = rhs_vf(E_idx)%sf(j, k, l) + & - q_cons_vf(momxb)%sf(j, k, l)*accel_bf(1) + rhs_vf(momxb)%sf(j, k, l) = rhs_vf(momxb)%sf(j, k, l) + rhoM(j, k, l)*accel_bf(1) + rhs_vf(E_idx)%sf(j, k, l) = rhs_vf(E_idx)%sf(j, k, l) + q_cons_vf(momxb)%sf(j, k, l)*accel_bf(1) end do end do end do $:END_GPU_PARALLEL_LOOP() end if - if (bf_y) then ! y-direction body forces + if (bf_y) then ! y-direction body forces - $:GPU_PARALLEL_LOOP(private='[j,k,l]', collapse=3) + $:GPU_PARALLEL_LOOP(private='[j, k, l]', collapse=3) do l = 0, p do k = 0, n do j = 0, m - rhs_vf(momxb + 1)%sf(j, k, l) = rhs_vf(momxb + 1)%sf(j, k, l) + & - rhoM(j, k, l)*accel_bf(2) - rhs_vf(E_idx)%sf(j, k, l) = rhs_vf(E_idx)%sf(j, k, l) + & - q_cons_vf(momxb + 1)%sf(j, k, l)*accel_bf(2) + rhs_vf(momxb + 1)%sf(j, k, l) = rhs_vf(momxb + 1)%sf(j, k, l) + rhoM(j, k, l)*accel_bf(2) + rhs_vf(E_idx)%sf(j, k, l) = rhs_vf(E_idx)%sf(j, k, l) + q_cons_vf(momxb + 1)%sf(j, k, l)*accel_bf(2) end do end do end do $:END_GPU_PARALLEL_LOOP() end if - if (bf_z) then ! z-direction body forces + if (bf_z) then ! z-direction body forces - $:GPU_PARALLEL_LOOP(private='[j,k,l]', collapse=3) + $:GPU_PARALLEL_LOOP(private='[j, k, l]', collapse=3) do l = 0, p do k = 0, n do j = 0, m - rhs_vf(momxe)%sf(j, k, l) = rhs_vf(momxe)%sf(j, k, l) + & - rhoM(j, k, l)*accel_bf(3) - rhs_vf(E_idx)%sf(j, k, l) = rhs_vf(E_idx)%sf(j, k, l) + & - q_cons_vf(momxe)%sf(j, k, l)*accel_bf(3) + rhs_vf(momxe)%sf(j, k, l) = rhs_vf(momxe)%sf(j, k, l) + rhoM(j, k, l)*accel_bf(3) + rhs_vf(E_idx)%sf(j, k, l) = rhs_vf(E_idx)%sf(j, k, l) + q_cons_vf(momxe)%sf(j, k, l)*accel_bf(3) end do end do end do $:END_GPU_PARALLEL_LOOP() - end if end subroutine s_compute_body_forces_rhs diff --git a/src/simulation/m_bubbles.fpp b/src/simulation/m_bubbles.fpp index cb2fb6a353..52ae804140 100644 --- a/src/simulation/m_bubbles.fpp +++ b/src/simulation/m_bubbles.fpp @@ -4,19 +4,15 @@ #:include 'macros.fpp' -!> @brief Shared bubble-dynamics procedures (radial acceleration, wall pressure, sound speed) for ensemble- and volume-averaged models +!> @brief Shared bubble-dynamics procedures (radial acceleration, wall pressure, sound speed) for ensemble- and volume-averaged +!! models module m_bubbles - use m_derived_types !< Definitions of the derived types - - use m_global_parameters !< Definitions of the global parameters - - use m_mpi_proxy !< Message passing interface (MPI) module proxy - - use m_variables_conversion !< State variables type conversion procedures - - use m_helper_basic !< Functions to compare floating point numbers - + use m_derived_types !< Definitions of the derived types + use m_global_parameters !< Definitions of the global parameters + use m_mpi_proxy !< Message passing interface (MPI) module proxy + use m_variables_conversion !< State variables type conversion procedures + use m_helper_basic !< Functions to compare floating point numbers use m_bubbles_EL_kernels implicit none @@ -24,32 +20,32 @@ module m_bubbles real(wp) :: chi_vw !< Bubble wall properties (Ando 2010) real(wp) :: k_mw !< Bubble wall properties (Ando 2010) real(wp) :: rho_mw !< Bubble wall properties (Ando 2010) - $:GPU_DECLARE(create='[chi_vw,k_mw,rho_mw]') + $:GPU_DECLARE(create='[chi_vw, k_mw, rho_mw]') contains !> Function that computes the bubble radial acceleration based on bubble models - !! @param fRho Current density - !! @param fP Current driving pressure - !! @param fR Current bubble radius - !! @param fV Current bubble velocity - !! @param fR0 Equilibrium bubble radius - !! @param fpb Internal bubble pressure - !! @param fpbdot Time-derivative of internal bubble pressure - !! @param alf bubble volume fraction - !! @param fntait Tait EOS parameter - !! @param fBtait Tait EOS parameter - !! @param f_bub_adv_src Source for bubble volume fraction - !! @param f_divu Divergence of velocity - !! @param fCson Speed of sound from fP (EL) + !! @param fRho Current density + !! @param fP Current driving pressure + !! @param fR Current bubble radius + !! @param fV Current bubble velocity + !! @param fR0 Equilibrium bubble radius + !! @param fpb Internal bubble pressure + !! @param fpbdot Time-derivative of internal bubble pressure + !! @param alf bubble volume fraction + !! @param fntait Tait EOS parameter + !! @param fBtait Tait EOS parameter + !! @param f_bub_adv_src Source for bubble volume fraction + !! @param f_divu Divergence of velocity + !! @param fCson Speed of sound from fP (EL) function f_rddot(fRho, fP, fR, fV, fR0, fpb, fpbdot, alf, fntait, fBtait, f_bub_adv_src, f_divu, fCson) + $:GPU_ROUTINE(parallelism='[seq]') real(wp), intent(in) :: fRho, fP, fR, fV, fR0, fpb, fpbdot, alf real(wp), intent(in) :: fntait, fBtait, f_bub_adv_src, f_divu real(wp), intent(in) :: fCson - - real(wp) :: fCpbw, fCpinf, fCpinf_dot, fH, fHdot, c_gas, c_liquid - real(wp) :: f_rddot + real(wp) :: fCpbw, fCpinf, fCpinf_dot, fH, fHdot, c_gas, c_liquid + real(wp) :: f_rddot if (bubble_model == 1) then ! Gilmore bubbles @@ -81,16 +77,16 @@ contains end function f_rddot - !> Function that computes that bubble wall pressure for Gilmore bubbles - !! @param fR0 Equilibrium bubble radius - !! @param fR Current bubble radius - !! @param fV Current bubble velocity - !! @param fpb Internal bubble pressure + !> Function that computes that bubble wall pressure for Gilmore bubbles + !! @param fR0 Equilibrium bubble radius + !! @param fR Current bubble radius + !! @param fV Current bubble velocity + !! @param fpb Internal bubble pressure function f_cpbw(fR0, fR, fV, fpb) + $:GPU_ROUTINE(parallelism='[seq]') real(wp), intent(in) :: fR0, fR, fV, fpb - - real(wp) :: f_cpbw + real(wp) :: f_cpbw if (polytropic) then f_cpbw = (Ca + 2._wp/Web/fR0)*((fR0/fR)**(3._wp*gam)) - Ca - 4._wp*Re_inv*fV/fR - 2._wp/(fR*Web) @@ -100,17 +96,17 @@ contains end function f_cpbw - !> Function that computes the bubble enthalpy - !! @param fCpbw Bubble wall pressure - !! @param fCpinf Driving bubble pressure - !! @param fntait Tait EOS parameter - !! @param fBtait Tait EOS parameter + !> Function that computes the bubble enthalpy + !! @param fCpbw Bubble wall pressure + !! @param fCpinf Driving bubble pressure + !! @param fntait Tait EOS parameter + !! @param fBtait Tait EOS parameter function f_H(fCpbw, fCpinf, fntait, fBtait) + $:GPU_ROUTINE(parallelism='[seq]') real(wp), intent(in) :: fCpbw, fCpinf, fntait, fBtait - - real(wp) :: tmp1, tmp2, tmp3 - real(wp) :: f_H + real(wp) :: tmp1, tmp2, tmp3 + real(wp) :: f_H tmp1 = (fntait - 1._wp)/fntait tmp2 = (fCpbw/(1._wp + fBtait) + 1._wp)**tmp1 @@ -121,16 +117,16 @@ contains end function f_H !> Function that computes the sound speed for the bubble - !! @param fCpinf Driving bubble pressure - !! @param fntait Tait EOS parameter - !! @param fBtait Tait EOS parameter - !! @param fH Bubble enthalpy + !! @param fCpinf Driving bubble pressure + !! @param fntait Tait EOS parameter + !! @param fBtait Tait EOS parameter + !! @param fH Bubble enthalpy function f_cgas(fCpinf, fntait, fBtait, fH) + $:GPU_ROUTINE(parallelism='[seq]') real(wp), intent(in) :: fCpinf, fntait, fBtait, fH - - real(wp) :: tmp - real(wp) :: f_cgas + real(wp) :: tmp + real(wp) :: f_cgas ! get sound speed for Gilmore equations "C" -> c_gas tmp = (fCpinf/(1._wp + fBtait) + 1._wp)**((fntait - 1._wp)/fntait) @@ -140,23 +136,22 @@ contains end function f_cgas - !> Function that computes the time derivative of the driving pressure - !! @param fRho Local liquid density - !! @param fP Local pressure - !! @param falf Local void fraction - !! @param fntait Tait EOS parameter - !! @param fBtait Tait EOS parameter - !! @param advsrc Advection equation source term - !! @param divu Divergence of velocity + !> Function that computes the time derivative of the driving pressure + !! @param fRho Local liquid density + !! @param fP Local pressure + !! @param falf Local void fraction + !! @param fntait Tait EOS parameter + !! @param fBtait Tait EOS parameter + !! @param advsrc Advection equation source term + !! @param divu Divergence of velocity function f_cpinfdot(fRho, fP, falf, fntait, fBtait, advsrc, divu) + $:GPU_ROUTINE(parallelism='[seq]') real(wp), intent(in) :: fRho, fP, falf, fntait, fBtait, advsrc, divu + real(wp) :: c2_liquid + real(wp) :: f_cpinfdot - real(wp) :: c2_liquid - real(wp) :: f_cpinfdot - - ! get sound speed squared for liquid (only needed for pbdot) - ! c_l^2 = gam (p+B) / (rho*(1-alf)) + ! get sound speed squared for liquid (only needed for pbdot) c_l^2 = gam (p+B) / (rho*(1-alf)) if (mpp_lim) then c2_liquid = fntait*(fP + fBtait)/fRho else @@ -168,23 +163,23 @@ contains end function f_cpinfdot - !> Function that computes the time derivative of the enthalpy - !! @param fCpbw Bubble wall pressure - !! @param fCpinf Driving bubble pressure - !! @param fCpinf_dot Time derivative of the driving pressure - !! @param fntait Tait EOS parameter - !! @param fBtait Tait EOS parameter - !! @param fR Current bubble radius - !! @param fV Current bubble velocity - !! @param fR0 Equilibrium bubble radius - !! @param fpbdot Time derivative of the internal bubble pressure + !> Function that computes the time derivative of the enthalpy + !! @param fCpbw Bubble wall pressure + !! @param fCpinf Driving bubble pressure + !! @param fCpinf_dot Time derivative of the driving pressure + !! @param fntait Tait EOS parameter + !! @param fBtait Tait EOS parameter + !! @param fR Current bubble radius + !! @param fV Current bubble velocity + !! @param fR0 Equilibrium bubble radius + !! @param fpbdot Time derivative of the internal bubble pressure function f_Hdot(fCpbw, fCpinf, fCpinf_dot, fntait, fBtait, fR, fV, fR0, fpbdot) + $:GPU_ROUTINE(parallelism='[seq]') real(wp), intent(in) :: fCpbw, fCpinf, fCpinf_dot, fntait, fBtait real(wp), intent(in) :: fR, fV, fR0, fpbdot - - real(wp) :: tmp1, tmp2 - real(wp) :: f_Hdot + real(wp) :: tmp1, tmp2 + real(wp) :: f_Hdot if (polytropic) then tmp1 = (fR0/fR)**(3._wp*gam) @@ -194,80 +189,75 @@ contains end if tmp2 = (2._wp/Web + 4._wp*Re_inv*fV)*fV/(fR**2._wp) - f_Hdot = & - (fCpbw/(1._wp + fBtait) + 1._wp)**(-1._wp/fntait)*(tmp1 + tmp2) & - - (fCpinf/(1._wp + fBtait) + 1._wp)**(-1._wp/fntait)*fCpinf_dot + f_Hdot = (fCpbw/(1._wp + fBtait) + 1._wp)**(-1._wp/fntait)*(tmp1 + tmp2) - (fCpinf/(1._wp + fBtait) + 1._wp) & + & **(-1._wp/fntait)*fCpinf_dot - ! Hdot = (Cpbw/(1+B) + 1)^(-1/n_tait)*(-3 gam)*(R0/R)^(3gam) V/R - !f_Hdot = ((fCpbw/(1._wp+fBtait)+1._wp)**(-1._wp/fntait))*(-3._wp)*gam * & - ! ( (fR0/fR)**(3._wp*gam ))*(fV/fR) + ! Hdot = (Cpbw/(1+B) + 1)^(-1/n_tait)*(-3 gam)*(R0/R)^(3gam) V/R f_Hdot = + ! ((fCpbw/(1._wp+fBtait)+1._wp)**(-1._wp/fntait))*(-3._wp)*gam * & ( (fR0/fR)**(3._wp*gam ))*(fV/fR) - ! Hdot = Hdot - (Cpinf/(1+B) + 1)^(-1/n_tait) Cpinfdot - !f_Hdot = f_Hdot - ((fCpinf/(1._wp+fBtait)+1._wp)**(-1._wp/fntait))*fCpinf_dot + ! Hdot = Hdot - (Cpinf/(1+B) + 1)^(-1/n_tait) Cpinfdot f_Hdot = f_Hdot - + ! ((fCpinf/(1._wp+fBtait)+1._wp)**(-1._wp/fntait))*fCpinf_dot end function f_Hdot - !> Function that computes the bubble radial acceleration for Rayleigh-Plesset bubbles - !! @param fCp Driving pressure - !! @param fRho Current density - !! @param fR Current bubble radius - !! @param fV Current bubble velocity - !! @param fCpbw Boundary wall pressure + !> Function that computes the bubble radial acceleration for Rayleigh-Plesset bubbles + !! @param fCp Driving pressure + !! @param fRho Current density + !! @param fR Current bubble radius + !! @param fV Current bubble velocity + !! @param fCpbw Boundary wall pressure function f_rddot_RP(fCp, fRho, fR, fV, fCpbw) + $:GPU_ROUTINE(parallelism='[seq]') real(wp), intent(in) :: fCp, fRho, fR, fV, fCpbw + real(wp) :: f_rddot_RP - real(wp) :: f_rddot_RP - - !! rddot = (1/r) ( -3/2 rdot^2 + ((r0/r)^3\gamma - Cp)/rho ) - !! rddot = (1/r) ( -3/2 rdot^2 + (tmp1 - Cp)/rho ) - !! rddot = (1/r) ( tmp2 ) + !! rddot = (1/r) ( -3/2 rdot^2 + ((r0/r)^3\gamma - Cp)/rho ) rddot = (1/r) ( -3/2 rdot^2 + (tmp1 - Cp)/rho ) rddot = (1/r) ( + !! tmp2 ) f_rddot_RP = (-1.5_wp*(fV**2._wp) + (fCpbw - fCp)/fRho)/fR end function f_rddot_RP - !> Function that computes the bubble radial acceleration - !! @param fCpbw Bubble wall pressure - !! @param fR Current bubble radius - !! @param fV Current bubble velocity - !! @param fH Current enthalpy - !! @param fHdot Current time derivative of the enthalpy - !! @param fcgas Current gas sound speed - !! @param fntait Tait EOS parameter - !! @param fBtait Tait EOS parameter + !> Function that computes the bubble radial acceleration + !! @param fCpbw Bubble wall pressure + !! @param fR Current bubble radius + !! @param fV Current bubble velocity + !! @param fH Current enthalpy + !! @param fHdot Current time derivative of the enthalpy + !! @param fcgas Current gas sound speed + !! @param fntait Tait EOS parameter + !! @param fBtait Tait EOS parameter function f_rddot_G(fCpbw, fR, fV, fH, fHdot, fcgas, fntait, fBtait) + $:GPU_ROUTINE(parallelism='[seq]') real(wp), intent(in) :: fCpbw, fR, fV, fH, fHdot real(wp), intent(in) :: fcgas, fntait, fBtait - - real(wp) :: tmp1, tmp2, tmp3 - real(wp) :: f_rddot_G + real(wp) :: tmp1, tmp2, tmp3 + real(wp) :: f_rddot_G tmp1 = fV/fcgas - tmp2 = 1._wp + 4._wp*Re_inv/fcgas/fR*(fCpbw/(1._wp + fBtait) + 1._wp) & - **(-1._wp/fntait) - tmp3 = 1.5_wp*fV**2._wp*(tmp1/3._wp - 1._wp) + fH*(1._wp + tmp1) & - + fR*fHdot*(1._wp - tmp1)/fcgas + tmp2 = 1._wp + 4._wp*Re_inv/fcgas/fR*(fCpbw/(1._wp + fBtait) + 1._wp)**(-1._wp/fntait) + tmp3 = 1.5_wp*fV**2._wp*(tmp1/3._wp - 1._wp) + fH*(1._wp + tmp1) + fR*fHdot*(1._wp - tmp1)/fcgas f_rddot_G = tmp3/(fR*(1._wp - tmp1)*tmp2) end function f_rddot_G - !> Function that computes the bubble wall pressure for Keller--Miksis bubbles - !! @param fR0 Equilibrium bubble radius - !! @param fR Current bubble radius - !! @param fV Current bubble velocity - !! @param fpb Internal bubble pressure + !> Function that computes the bubble wall pressure for Keller--Miksis bubbles + !! @param fR0 Equilibrium bubble radius + !! @param fR Current bubble radius + !! @param fV Current bubble velocity + !! @param fpb Internal bubble pressure function f_cpbw_KM(fR0, fR, fV, fpb) + $:GPU_ROUTINE(parallelism='[seq]') real(wp), intent(in) :: fR0, fR, fV, fpb - real(wp) :: f_cpbw_KM + real(wp) :: f_cpbw_KM if (polytropic) then f_cpbw_KM = Ca*((fR0/fR)**(3._wp*gam)) - Ca + Eu - if (.not. f_is_default(Web)) f_cpbw_KM = f_cpbw_KM + & - (2._wp/(Web*fR0))*((fR0/fR)**(3._wp*gam)) + if (.not. f_is_default(Web)) f_cpbw_KM = f_cpbw_KM + (2._wp/(Web*fR0))*((fR0/fR)**(3._wp*gam)) else f_cpbw_KM = fpb end if @@ -277,26 +267,25 @@ contains end function f_cpbw_KM - !> Function that computes the bubble radial acceleration for Keller--Miksis bubbles - !! @param fpbdot Time-derivative of internal bubble pressure - !! @param fCp Driving pressure - !! @param fCpbw Bubble wall pressure - !! @param fRho Current density - !! @param fR Current bubble radius - !! @param fV Current bubble velocity - !! @param fR0 Equilibrium bubble radius - !! @param fC Current sound speed + !> Function that computes the bubble radial acceleration for Keller--Miksis bubbles + !! @param fpbdot Time-derivative of internal bubble pressure + !! @param fCp Driving pressure + !! @param fCpbw Bubble wall pressure + !! @param fRho Current density + !! @param fR Current bubble radius + !! @param fV Current bubble velocity + !! @param fR0 Equilibrium bubble radius + !! @param fC Current sound speed function f_rddot_KM(fpbdot, fCp, fCpbw, fRho, fR, fV, fR0, fC) + $:GPU_ROUTINE(parallelism='[seq]') real(wp), intent(in) :: fpbdot, fCp, fCpbw real(wp), intent(in) :: fRho, fR, fV, fR0, fC - - real(wp) :: tmp1, tmp2, cdot_star - real(wp) :: f_rddot_KM + real(wp) :: tmp1, tmp2, cdot_star + real(wp) :: f_rddot_KM if (polytropic) then cdot_star = -3._wp*gam*Ca*((fR0/fR)**(3._wp*gam))*fV/fR - if (.not. f_is_default(Web)) cdot_star = cdot_star - & - 3._wp*gam*(2._wp/(Web*fR0))*((fR0/fR)**(3._wp*gam))*fV/fR + if (.not. f_is_default(Web)) cdot_star = cdot_star - 3._wp*gam*(2._wp/(Web*fR0))*((fR0/fR)**(3._wp*gam))*fV/fR else cdot_star = fpbdot end if @@ -305,9 +294,7 @@ contains if (.not. f_is_default(Re_inv)) cdot_star = cdot_star + 4._wp*Re_inv*((fV/fR)**2._wp) tmp1 = fV/fC - tmp2 = 1.5_wp*(fV**2._wp)*(tmp1/3._wp - 1._wp) + & - (1._wp + tmp1)*(fCpbw - fCp)/fRho + & - cdot_star*fR/(fRho*fC) + tmp2 = 1.5_wp*(fV**2._wp)*(tmp1/3._wp - 1._wp) + (1._wp + tmp1)*(fCpbw - fCp)/fRho + cdot_star*fR/(fRho*fC) if (f_is_default(Re_inv)) then f_rddot_KM = tmp2/(fR*(1._wp - tmp1)) @@ -317,57 +304,57 @@ contains end function f_rddot_KM - !> Subroutine that computes bubble wall properties for vapor bubbles - !! @param pb_in Internal bubble pressure - !! @param iR0 Current bubble size index + !> Subroutine that computes bubble wall properties for vapor bubbles + !! @param pb_in Internal bubble pressure + !! @param iR0 Current bubble size index subroutine s_bwproperty(pb_in, iR0, chi_vw_out, k_mw_out, rho_mw_out) + $:GPU_ROUTINE(parallelism='[seq]') - real(wp), intent(in) :: pb_in - integer, intent(in) :: iR0 + real(wp), intent(in) :: pb_in + integer, intent(in) :: iR0 real(wp), intent(out) :: chi_vw_out !< Bubble wall properties (Ando 2010) real(wp), intent(out) :: k_mw_out !< Bubble wall properties (Ando 2010) real(wp), intent(out) :: rho_mw_out !< Bubble wall properties (Ando 2010) - real(wp) :: x_vw + real(wp) :: x_vw ! mass fraction of vapor chi_vw_out = 1._wp/(1._wp + R_v/R_g*(pb_in/pv - 1._wp)) ! mole fraction of vapor & thermal conductivity of gas mixture x_vw = M_g*chi_vw_out/(M_v + (M_g - M_v)*chi_vw_out) - k_mw_out = x_vw*k_v(iR0)/(x_vw + (1._wp - x_vw)*phi_vg) & - + (1._wp - x_vw)*k_g(iR0)/(x_vw*phi_gv + 1._wp - x_vw) + k_mw_out = x_vw*k_v(iR0)/(x_vw + (1._wp - x_vw)*phi_vg) + (1._wp - x_vw)*k_g(iR0)/(x_vw*phi_gv + 1._wp - x_vw) ! gas mixture density rho_mw_out = pv/(chi_vw_out*R_v*Tw) end subroutine s_bwproperty - !> Function that computes the vapour flux - !! @param fR Current bubble radius - !! @param fV Current bubble velocity - !! @param fpb - !! @param fmass_v Current mass of vapour - !! @param iR0 Bubble size index (EE) or bubble identifier (EL) - !! @param vflux Computed vapour flux - !! @param fmass_g Current gas mass (EL) - !! @param fbeta_c Mass transfer coefficient (EL) - !! @param fR_m Mixture gas constant (EL) - !! @param fgamma_m Mixture gamma (EL) + !> Function that computes the vapour flux + !! @param fR Current bubble radius + !! @param fV Current bubble velocity + !! @param fpb + !! @param fmass_v Current mass of vapour + !! @param iR0 Bubble size index (EE) or bubble identifier (EL) + !! @param vflux Computed vapour flux + !! @param fmass_g Current gas mass (EL) + !! @param fbeta_c Mass transfer coefficient (EL) + !! @param fR_m Mixture gas constant (EL) + !! @param fgamma_m Mixture gamma (EL) subroutine s_vflux(fR, fV, fpb, fmass_v, iR0, vflux, fmass_g, fbeta_c, fR_m, fgamma_m) + $:GPU_ROUTINE(parallelism='[seq]') - real(wp), intent(in) :: fR - real(wp), intent(in) :: fV - real(wp), intent(in) :: fpb - real(wp), intent(in) :: fmass_v - integer, intent(in) :: iR0 - real(wp), intent(out) :: vflux - real(wp), intent(in), optional :: fmass_g, fbeta_c + real(wp), intent(in) :: fR + real(wp), intent(in) :: fV + real(wp), intent(in) :: fpb + real(wp), intent(in) :: fmass_v + integer, intent(in) :: iR0 + real(wp), intent(out) :: vflux + real(wp), intent(in), optional :: fmass_g, fbeta_c real(wp), intent(out), optional :: fR_m, fgamma_m + real(wp) :: chi_bar + real(wp) :: rho_mw_lag + real(wp) :: grad_chi + real(wp) :: conc_v - real(wp) :: chi_bar - real(wp) :: rho_mw_lag - real(wp) :: grad_chi - real(wp) :: conc_v - - if (thermal == 3) then !transfer + if (thermal == 3) then ! transfer ! constant transfer model if (bubbles_lagrange) then ! Mixture properties (gas+vapor) in the bubble @@ -398,103 +385,95 @@ contains end subroutine s_vflux - !> Function that computes the time derivative of - !! the internal bubble pressure - !! @param fvflux Vapour flux - !! @param fR Current bubble radius - !! @param fV Current bubble velocity - !! @param fpb Current internal bubble pressure - !! @param fmass_v Current mass of vapour - !! @param iR0 Bubble size index (EE) or bubble identifier (EL) - !! @param fbeta_t Mass transfer coefficient (EL) - !! @param fR_m Mixture gas constant (EL) - !! @param fgamma_m Mixture gamma (EL) + !> Function that computes the time derivative of the internal bubble pressure + !! @param fvflux Vapour flux + !! @param fR Current bubble radius + !! @param fV Current bubble velocity + !! @param fpb Current internal bubble pressure + !! @param fmass_v Current mass of vapour + !! @param iR0 Bubble size index (EE) or bubble identifier (EL) + !! @param fbeta_t Mass transfer coefficient (EL) + !! @param fR_m Mixture gas constant (EL) + !! @param fgamma_m Mixture gamma (EL) function f_bpres_dot(fvflux, fR, fV, fpb, fmass_v, iR0, fbeta_t, fR_m, fgamma_m) + !$DIR INLINENEVER f_bpres_dot $:GPU_ROUTINE(parallelism='[seq]') - real(wp), intent(in) :: fvflux - real(wp), intent(in) :: fR - real(wp), intent(in) :: fV - real(wp), intent(in) :: fpb - real(wp), intent(in) :: fmass_v - integer, intent(in) :: iR0 + real(wp), intent(in) :: fvflux + real(wp), intent(in) :: fR + real(wp), intent(in) :: fV + real(wp), intent(in) :: fpb + real(wp), intent(in) :: fmass_v + integer, intent(in) :: iR0 real(wp), intent(in), optional :: fbeta_t, fR_m, fgamma_m - - real(wp) :: T_bar - real(wp) :: grad_T - real(wp) :: f_bpres_dot - real(wp) :: heatflux + real(wp) :: T_bar + real(wp) :: grad_T + real(wp) :: f_bpres_dot + real(wp) :: heatflux if (thermal == 3) then if (bubbles_lagrange) then T_bar = fpb*(4._wp/3._wp*pi*fR**3._wp)/fR_m grad_T = -fbeta_t*(T_bar - Tw) heatflux = (fgamma_m - 1._wp)/fgamma_m*grad_T/fR - f_bpres_dot = 3._wp*fgamma_m*(-fV*fpb + fvflux*R_v*Tw & - + heatflux)/fR + f_bpres_dot = 3._wp*fgamma_m*(-fV*fpb + fvflux*R_v*Tw + heatflux)/fR return end if - grad_T = -Re_trans_T(iR0)*((fpb/pb0(iR0))*(fR/R0(iR0))**3 & - *(mass_g0(iR0) + mass_v0(iR0))/(mass_g0(iR0) + fmass_v) - 1._wp) - f_bpres_dot = 3._wp*gam_m*(-fV*fpb + fvflux*R_v*Tw & - + pb0(iR0)*k_mw*grad_T/Pe_T(iR0)/fR)/fR + grad_T = -Re_trans_T(iR0)*((fpb/pb0(iR0))*(fR/R0(iR0))**3*(mass_g0(iR0) + mass_v0(iR0))/(mass_g0(iR0) + fmass_v) & + & - 1._wp) + f_bpres_dot = 3._wp*gam_m*(-fV*fpb + fvflux*R_v*Tw + pb0(iR0)*k_mw*grad_T/Pe_T(iR0)/fR)/fR else f_bpres_dot = -3._wp*gam_m*fV/fR*(fpb - pv) end if end function f_bpres_dot - !> Adaptive time stepping routine for subgrid bubbles - !! (See Heirer, E. Hairer S.P.Nørsett G. Wanner, Solving Ordinary - !! Differential Equations I, Chapter II.4) - !! @param fRho Current density - !! @param fP Current driving pressure - !! @param fR Current bubble radius - !! @param fV Current bubble radial velocity - !! @param fR0 Equilibrium bubble radius - !! @param fpb Internal bubble pressure - !! @param fpbdot Time-derivative of internal bubble pressure - !! @param alf bubble volume fraction - !! @param fntait Tait EOS parameter - !! @param fBtait Tait EOS parameter - !! @param f_bub_adv_src Source for bubble volume fraction - !! @param f_divu Divergence of velocity - !! @param bub_id Bubble identifier (EL) - !! @param fmass_v Current mass of vapour (EL) - !! @param fmass_g Current mass of gas (EL) - !! @param fbeta_c Mass transfer coefficient (EL) - !! @param fbeta_t Heat transfer coefficient (EL) - !! @param fCson Speed of sound (EL) - !! @param adap_dt_stop Fail-safe exit if max iteration count reached - function f_advance_step(fRho, fP, fR, fV, fR0, fpb, fpbdot, alf, & - fntait, fBtait, f_bub_adv_src, f_divu, & - bub_id, fmass_v, fmass_g, fbeta_c, & - fbeta_t, fCson, fRe, fPos, & - fVel, cell, q_prim_vf) result(adap_dt_stop) + !> Adaptive time stepping routine for subgrid bubbles (See Heirer, E. Hairer S.P.Norsett G. Wanner, Solving Ordinary + !! Differential Equations I, Chapter II.4) + !! @param fRho Current density + !! @param fP Current driving pressure + !! @param fR Current bubble radius + !! @param fV Current bubble radial velocity + !! @param fR0 Equilibrium bubble radius + !! @param fpb Internal bubble pressure + !! @param fpbdot Time-derivative of internal bubble pressure + !! @param alf bubble volume fraction + !! @param fntait Tait EOS parameter + !! @param fBtait Tait EOS parameter + !! @param f_bub_adv_src Source for bubble volume fraction + !! @param f_divu Divergence of velocity + !! @param bub_id Bubble identifier (EL) + !! @param fmass_v Current mass of vapour (EL) + !! @param fmass_g Current mass of gas (EL) + !! @param fbeta_c Mass transfer coefficient (EL) + !! @param fbeta_t Heat transfer coefficient (EL) + !! @param fCson Speed of sound (EL) + !! @param adap_dt_stop Fail-safe exit if max iteration count reached + function f_advance_step(fRho, fP, fR, fV, fR0, fpb, fpbdot, alf, fntait, fBtait, f_bub_adv_src, f_divu, bub_id, fmass_v, & + & fmass_g, fbeta_c, fbeta_t, fCson, fRe, fPos, fVel, cell, q_prim_vf) result(adap_dt_stop) $:GPU_ROUTINE(parallelism='[seq]') - real(wp), intent(inout) :: fR, fV, fpb, fmass_v - real(wp), intent(in) :: fRho, fP, fR0, fpbdot, alf - real(wp), intent(in) :: fntait, fBtait, f_bub_adv_src, f_divu - integer, intent(in) :: bub_id - real(wp), intent(in) :: fmass_g, fbeta_c, fbeta_t, fCson - real(wp), intent(inout), dimension(3), optional :: fPos, fVel - real(wp), intent(in), optional :: fRe - integer, intent(in), dimension(3), optional :: cell + real(wp), intent(inout) :: fR, fV, fpb, fmass_v + real(wp), intent(in) :: fRho, fP, fR0, fpbdot, alf + real(wp), intent(in) :: fntait, fBtait, f_bub_adv_src, f_divu + integer, intent(in) :: bub_id + real(wp), intent(in) :: fmass_g, fbeta_c, fbeta_t, fCson + real(wp), intent(inout), dimension(3), optional :: fPos, fVel + real(wp), intent(in), optional :: fRe + integer, intent(in), dimension(3), optional :: cell type(scalar_field), intent(in), dimension(sys_size), optional :: q_prim_vf - - real(wp), dimension(5) :: err !< Error estimates for adaptive time stepping - real(wp) :: t_new !< Updated time step size - real(wp) :: h0, h !< Time step size - real(wp), dimension(4) :: myR_tmp1, myV_tmp1, myR_tmp2, myV_tmp2 !< Bubble radius, radial velocity, and radial acceleration for the inner loop - real(wp), dimension(4) :: myPb_tmp1, myMv_tmp1, myPb_tmp2, myMv_tmp2 !< Gas pressure and vapor mass for the inner loop (EL) - real(wp) :: fR2, fV2, fpb2, fmass_v2, f_bTemp + real(wp), dimension(5) :: err !< Error estimates for adaptive time stepping + real(wp) :: t_new !< Updated time step size + real(wp) :: h0, h !< Time step size + !> Bubble radius, radial velocity, and radial acceleration for the inner loop + real(wp), dimension(4) :: myR_tmp1, myV_tmp1, myR_tmp2, myV_tmp2 + real(wp), dimension(4) :: myPb_tmp1, myMv_tmp1, myPb_tmp2, myMv_tmp2 !< Gas pressure and vapor mass for the inner loop (EL) + real(wp) :: fR2, fV2, fpb2, fmass_v2, f_bTemp real(wp), dimension(3) :: vTemp, aTemp - integer :: adap_dt_stop - integer :: l, iter_count + integer :: adap_dt_stop + integer :: l, iter_count - call s_initial_substep_h(fRho, fP, fR, fV, fR0, fpb, fpbdot, alf, & - fntait, fBtait, f_bub_adv_src, f_divu, fCson, h0) + call s_initial_substep_h(fRho, fP, fR, fV, fR0, fpb, fpbdot, alf, fntait, fBtait, f_bub_adv_src, f_divu, fCson, h0) h = h0 ! Advancing one step t_new = 0._wp @@ -508,28 +487,21 @@ contains ! Advancing one sub-step do while (iter_count < adap_dt_max_iters) - iter_count = iter_count + 1 ! Advance one sub-step - call s_advance_substep(err(1), & - fRho, fP, fR, fV, fR0, fpb, fpbdot, alf, & - fntait, fBtait, f_bub_adv_src, f_divu, & - bub_id, fmass_v, fmass_g, fbeta_c, & - fbeta_t, fCson, h, & - myR_tmp1, myV_tmp1, myPb_tmp1, myMv_tmp1) + call s_advance_substep(err(1), fRho, fP, fR, fV, fR0, fpb, fpbdot, alf, fntait, fBtait, f_bub_adv_src, f_divu, & + & bub_id, fmass_v, fmass_g, fbeta_c, fbeta_t, fCson, h, myR_tmp1, myV_tmp1, myPb_tmp1, & + & myMv_tmp1) if (err(1) > adap_dt_tol) then h = 0.25_wp*h cycle end if ! Advance one sub-step by advancing two half steps - call s_advance_substep(err(2), & - fRho, fP, fR, fV, fR0, fpb, fpbdot, alf, & - fntait, fBtait, f_bub_adv_src, f_divu, & - bub_id, fmass_v, fmass_g, fbeta_c, & - fbeta_t, fCson, 0.5_wp*h, & - myR_tmp2, myV_tmp2, myPb_tmp2, myMv_tmp2) + call s_advance_substep(err(2), fRho, fP, fR, fV, fR0, fpb, fpbdot, alf, fntait, fBtait, f_bub_adv_src, f_divu, & + & bub_id, fmass_v, fmass_g, fbeta_c, fbeta_t, fCson, 0.5_wp*h, myR_tmp2, myV_tmp2, & + & myPb_tmp2, myMv_tmp2) if (err(2) > adap_dt_tol) then h = 0.25_wp*h cycle @@ -538,12 +510,9 @@ contains fR2 = myR_tmp2(4); fV2 = myV_tmp2(4) fpb2 = myPb_tmp2(4); fmass_v2 = myMv_tmp2(4) - call s_advance_substep(err(3), & - fRho, fP, fR2, fV2, fR0, fpb2, fpbdot, alf, & - fntait, fBtait, f_bub_adv_src, f_divu, & - bub_id, fmass_v2, fmass_g, fbeta_c, & - fbeta_t, fCson, 0.5_wp*h, & - myR_tmp2, myV_tmp2, myPb_tmp2, myMv_tmp2) + call s_advance_substep(err(3), fRho, fP, fR2, fV2, fR0, fpb2, fpbdot, alf, fntait, fBtait, f_bub_adv_src, f_divu, & + & bub_id, fmass_v2, fmass_g, fbeta_c, fbeta_t, fCson, 0.5_wp*h, myR_tmp2, myV_tmp2, & + & myPb_tmp2, myMv_tmp2) if (err(3) > adap_dt_tol) then h = 0.5_wp*h cycle @@ -553,15 +522,10 @@ contains err(5) = abs((myV_tmp1(4) - myV_tmp2(4))/myV_tmp1(4)) if (abs(myV_tmp1(4)) < verysmall) err(5) = 0._wp - ! Determine acceptance/rejection and update step size - ! Rule 1: err1, err2, err3 < tol - ! Rule 2: myR_tmp1(4) > 0._wp - ! Rule 3: abs((myR_tmp1(4) - myR_tmp2(4))/fR) < tol - ! Rule 4: abs((myV_tmp1(4) - myV_tmp2(4))/fV) < tol - if ((err(1) <= adap_dt_tol) .and. (err(2) <= adap_dt_tol) .and. & - (err(3) <= adap_dt_tol) .and. (err(4) <= adap_dt_tol) .and. & - (err(5) <= adap_dt_tol) .and. myR_tmp1(4) > 0._wp) then - + ! Determine acceptance/rejection and update step size Rule 1: err1, err2, err3 < tol Rule 2: myR_tmp1(4) > 0._wp + ! Rule 3: abs((myR_tmp1(4) - myR_tmp2(4))/fR) < tol Rule 4: abs((myV_tmp1(4) - myV_tmp2(4))/fV) < tol + if ((err(1) <= adap_dt_tol) .and. (err(2) <= adap_dt_tol) .and. (err(3) <= adap_dt_tol) .and. (err(4) & + & <= adap_dt_tol) .and. (err(5) <= adap_dt_tol) .and. myR_tmp1(4) > 0._wp) then ! Accepted. Finalize the sub-step t_new = t_new + h @@ -585,8 +549,8 @@ contains end do case (2) do l = 1, num_dims - f_bTemp = f_get_bubble_force(fPos(l), fR, fV, fVel(l), fmass_g, fmass_v, & - fRe, fRho, cell, l, q_prim_vf) + f_bTemp = f_get_bubble_force(fPos(l), fR, fV, fVel(l), fmass_g, fmass_v, fRe, fRho, cell, l, & + & q_prim_vf) aTemp(l) = f_bTemp/(fmass_g + fmass_v) end do do l = 1, num_dims @@ -595,8 +559,8 @@ contains end do case (3) do l = 1, num_dims - f_bTemp = f_get_bubble_force(fPos(l), fR, fV, fVel(l), fmass_g, fmass_v, & - fRe, fRho, cell, l, q_prim_vf) + f_bTemp = f_get_bubble_force(fPos(l), fR, fV, fVel(l), fmass_g, fmass_v, fRe, fRho, cell, l, & + & q_prim_vf) aTemp(l) = 2._wp*f_bTemp/(fmass_g + fmass_v) - 3._wp*fV*fVel(l)/fR end do do l = 1, num_dims @@ -622,53 +586,44 @@ contains ! Exit the loop if the final time reached dt if (f_approx_equal(t_new, 0.5_wp*dt) .or. iter_count >= adap_dt_max_iters) exit - end do if (iter_count >= adap_dt_max_iters) adap_dt_stop = 1 end function f_advance_step - !> Choose the initial time step size for the adaptive time stepping routine - !! (See Heirer, E. Hairer S.P.Nørsett G. Wanner, Solving Ordinary - !! Differential Equations I, Chapter II.4) - !! @param fRho Current density - !! @param fP Current driving pressure - !! @param fR Current bubble radius - !! @param fV Current bubble velocity - !! @param fR0 Equilibrium bubble radius - !! @param fpb Internal bubble pressure - !! @param fpbdot Time-derivative of internal bubble pressure - !! @param alf bubble volume fraction - !! @param fntait Tait EOS parameter - !! @param fBtait Tait EOS parameter - !! @param f_bub_adv_src Source for bubble volume fraction - !! @param f_divu Divergence of velocity - !! @param fCson Speed of sound (EL) - !! @param h Time step size - subroutine s_initial_substep_h(fRho, fP, fR, fV, fR0, fpb, fpbdot, alf, & - fntait, fBtait, f_bub_adv_src, f_divu, & - fCson, h) - $:GPU_ROUTINE(function_name='s_initial_substep_h',parallelism='[seq]', & - & cray_inline=True) - - real(wp), intent(in) :: fRho, fP, fR, fV, fR0, fpb, fpbdot, alf - real(wp), intent(in) :: fntait, fBtait, f_bub_adv_src, f_divu - real(wp), intent(in) :: fCson - real(wp), intent(out) :: h - - real(wp), dimension(2) :: h_size !< Time step size (h0, h1) - real(wp), dimension(3) :: d_norms !< norms (d_0, d_1, d_2) - real(wp), dimension(2) :: myR_tmp, myV_tmp, myA_tmp !< Bubble radius, radial velocity, and radial acceleration - - ! Determine the starting time step - ! Evaluate f(x0,y0) + !> Choose the initial time step size for the adaptive time stepping routine (See Heirer, E. Hairer S.P.Norsett G. Wanner, + !! Solving Ordinary Differential Equations I, Chapter II.4) + !! @param fRho Current density + !! @param fP Current driving pressure + !! @param fR Current bubble radius + !! @param fV Current bubble velocity + !! @param fR0 Equilibrium bubble radius + !! @param fpb Internal bubble pressure + !! @param fpbdot Time-derivative of internal bubble pressure + !! @param alf bubble volume fraction + !! @param fntait Tait EOS parameter + !! @param fBtait Tait EOS parameter + !! @param f_bub_adv_src Source for bubble volume fraction + !! @param f_divu Divergence of velocity + !! @param fCson Speed of sound (EL) + !! @param h Time step size + subroutine s_initial_substep_h(fRho, fP, fR, fV, fR0, fpb, fpbdot, alf, fntait, fBtait, f_bub_adv_src, f_divu, fCson, h) + + $:GPU_ROUTINE(function_name='s_initial_substep_h',parallelism='[seq]', cray_inline=True) + + real(wp), intent(in) :: fRho, fP, fR, fV, fR0, fpb, fpbdot, alf + real(wp), intent(in) :: fntait, fBtait, f_bub_adv_src, f_divu + real(wp), intent(in) :: fCson + real(wp), intent(out) :: h + real(wp), dimension(2) :: h_size !< Time step size (h0, h1) + real(wp), dimension(3) :: d_norms !< norms (d_0, d_1, d_2) + real(wp), dimension(2) :: myR_tmp, myV_tmp, myA_tmp !< Bubble radius, radial velocity, and radial acceleration + + ! Determine the starting time step Evaluate f(x0,y0) myR_tmp(1) = fR myV_tmp(1) = fV - myA_tmp(1) = f_rddot(fRho, fP, myR_tmp(1), myV_tmp(1), fR0, & - fpb, fpbdot, alf, fntait, fBtait, & - f_bub_adv_src, f_divu, & - fCson) + myA_tmp(1) = f_rddot(fRho, fP, myR_tmp(1), myV_tmp(1), fR0, fpb, fpbdot, alf, fntait, fBtait, f_bub_adv_src, f_divu, fCson) ! Compute d_0 = ||y0|| and d_1 = ||f(x0,y0)|| d_norms(1) = sqrt((myR_tmp(1)**2._wp + myV_tmp(1)**2._wp)/2._wp) @@ -682,16 +637,12 @@ contains ! Evaluate f(x0+h0,y0+h0*f(x0,y0)) myR_tmp(2) = myR_tmp(1) + h_size(1)*myV_tmp(1) myV_tmp(2) = myV_tmp(1) + h_size(1)*myA_tmp(1) - myA_tmp(2) = f_rddot(fRho, fP, myR_tmp(2), myV_tmp(2), fR0, & - fpb, fpbdot, alf, fntait, fBtait, & - f_bub_adv_src, f_divu, & - fCson) + myA_tmp(2) = f_rddot(fRho, fP, myR_tmp(2), myV_tmp(2), fR0, fpb, fpbdot, alf, fntait, fBtait, f_bub_adv_src, f_divu, fCson) ! Compute d_2 = ||f(x0+h0,y0+h0*f(x0,y0))-f(x0,y0)||/h0 d_norms(3) = sqrt(((myV_tmp(2) - myV_tmp(1))**2._wp + (myA_tmp(2) - myA_tmp(1))**2._wp)/2._wp)/h_size(1) - ! Set h1 = (0.01/max(d_1,d_2))^{1/(p+1)} - ! if max(d_1,d_2) < 1.e-15_wp, h_size(2) = max(1.e-6_wp, h0*1.e-3_wp) + ! Set h1 = (0.01/max(d_1,d_2))^{1/(p+1)} if max(d_1,d_2) < 1.e-15_wp, h_size(2) = max(1.e-6_wp, h0*1.e-3_wp) if (max(d_norms(2), d_norms(3)) < threshold_second_guess) then h_size(2) = max(small_guess, h_size(1)*scale_first_guess) else @@ -702,49 +653,43 @@ contains end subroutine s_initial_substep_h - !> Integrate bubble variables over the given time step size, h, using a - !! third-order accurate embedded Runge–Kutta scheme. - !! @param err Estimated error - !! @param fRho Current density - !! @param fP Current driving pressure - !! @param fR Current bubble radius - !! @param fV Current bubble velocity - !! @param fR0 Equilibrium bubble radius - !! @param fpb Internal bubble pressure - !! @param fpbdot Time-derivative of internal bubble pressure - !! @param alf bubble volume fraction - !! @param fntait Tait EOS parameter - !! @param fBtait Tait EOS parameter - !! @param f_bub_adv_src Source for bubble volume fraction - !! @param f_divu Divergence of velocity - !! @param bub_id Bubble identifier (EL) - !! @param fmass_v Current mass of vapour (EL) - !! @param fmass_g Current mass of gas (EL) - !! @param fbeta_c Mass transfer coefficient (EL) - !! @param fbeta_t Heat transfer coefficient (EL) - !! @param fCson Speed of sound (EL) - !! @param h Time step size - !! @param myR_tmp Bubble radius at each stage - !! @param myV_tmp Bubble radial velocity at each stage - !! @param myPb_tmp Internal bubble pressure at each stage (EL) - !! @param myMv_tmp Mass of vapor in the bubble at each stage (EL) - subroutine s_advance_substep(err, fRho, fP, fR, fV, fR0, fpb, fpbdot, alf, & - fntait, fBtait, f_bub_adv_src, f_divu, & - bub_id, fmass_v, fmass_g, fbeta_c, & - fbeta_t, fCson, h, & - myR_tmp, myV_tmp, myPb_tmp, myMv_tmp) - $:GPU_ROUTINE(function_name='s_advance_substep',parallelism='[seq]', & - & cray_inline=True) - - real(wp), intent(out) :: err - real(wp), intent(in) :: fRho, fP, fR, fV, fR0, fpb, fpbdot, alf - real(wp), intent(in) :: fntait, fBtait, f_bub_adv_src, f_divu, h - integer, intent(in) :: bub_id - real(wp), intent(in) :: fmass_v, fmass_g, fbeta_c, fbeta_t, fCson + !> Integrate bubble variables over the given time step size, h, using a third-order accurate embedded Runge-Kutta scheme. + !! @param err Estimated error + !! @param fRho Current density + !! @param fP Current driving pressure + !! @param fR Current bubble radius + !! @param fV Current bubble velocity + !! @param fR0 Equilibrium bubble radius + !! @param fpb Internal bubble pressure + !! @param fpbdot Time-derivative of internal bubble pressure + !! @param alf bubble volume fraction + !! @param fntait Tait EOS parameter + !! @param fBtait Tait EOS parameter + !! @param f_bub_adv_src Source for bubble volume fraction + !! @param f_divu Divergence of velocity + !! @param bub_id Bubble identifier (EL) + !! @param fmass_v Current mass of vapour (EL) + !! @param fmass_g Current mass of gas (EL) + !! @param fbeta_c Mass transfer coefficient (EL) + !! @param fbeta_t Heat transfer coefficient (EL) + !! @param fCson Speed of sound (EL) + !! @param h Time step size + !! @param myR_tmp Bubble radius at each stage + !! @param myV_tmp Bubble radial velocity at each stage + !! @param myPb_tmp Internal bubble pressure at each stage (EL) + !! @param myMv_tmp Mass of vapor in the bubble at each stage (EL) + subroutine s_advance_substep(err, fRho, fP, fR, fV, fR0, fpb, fpbdot, alf, fntait, fBtait, f_bub_adv_src, f_divu, bub_id, & + & fmass_v, fmass_g, fbeta_c, fbeta_t, fCson, h, myR_tmp, myV_tmp, myPb_tmp, myMv_tmp) + $:GPU_ROUTINE(function_name='s_advance_substep',parallelism='[seq]', cray_inline=True) + + real(wp), intent(out) :: err + real(wp), intent(in) :: fRho, fP, fR, fV, fR0, fpb, fpbdot, alf + real(wp), intent(in) :: fntait, fBtait, f_bub_adv_src, f_divu, h + integer, intent(in) :: bub_id + real(wp), intent(in) :: fmass_v, fmass_g, fbeta_c, fbeta_t, fCson real(wp), dimension(4), intent(out) :: myR_tmp, myV_tmp, myPb_tmp, myMv_tmp - - real(wp), dimension(4) :: myA_tmp, mydPbdt_tmp, mydMvdt_tmp - real(wp) :: err_R, err_V + real(wp), dimension(4) :: myA_tmp, mydPbdt_tmp, mydMvdt_tmp + real(wp) :: err_R, err_V myPb_tmp(1:4) = fpb mydPbdt_tmp(1:4) = fpbdot @@ -755,13 +700,11 @@ contains if (bubbles_lagrange) then myPb_tmp(1) = fpb myMv_tmp(1) = fmass_v - call s_advance_EL(myR_tmp(1), myV_tmp(1), myPb_tmp(1), myMv_tmp(1), bub_id, & - fmass_g, fbeta_c, fbeta_t, mydPbdt_tmp(1), mydMvdt_tmp(1)) + call s_advance_EL(myR_tmp(1), myV_tmp(1), myPb_tmp(1), myMv_tmp(1), bub_id, fmass_g, fbeta_c, fbeta_t, & + & mydPbdt_tmp(1), mydMvdt_tmp(1)) end if - myA_tmp(1) = f_rddot(fRho, fP, myR_tmp(1), myV_tmp(1), fR0, & - myPb_tmp(1), mydPbdt_tmp(1), alf, fntait, fBtait, & - f_bub_adv_src, f_divu, & - fCson) + myA_tmp(1) = f_rddot(fRho, fP, myR_tmp(1), myV_tmp(1), fR0, myPb_tmp(1), mydPbdt_tmp(1), alf, fntait, fBtait, & + & f_bub_adv_src, f_divu, fCson) ! Stage 1 myR_tmp(2) = myR_tmp(1) + h*myV_tmp(1) @@ -772,13 +715,11 @@ contains if (bubbles_lagrange) then myPb_tmp(2) = myPb_tmp(1) + h*mydPbdt_tmp(1) myMv_tmp(2) = myMv_tmp(1) + h*mydMvdt_tmp(1) - call s_advance_EL(myR_tmp(2), myV_tmp(2), myPb_tmp(2), myMv_tmp(2), & - bub_id, fmass_g, fbeta_c, fbeta_t, mydPbdt_tmp(2), mydMvdt_tmp(2)) + call s_advance_EL(myR_tmp(2), myV_tmp(2), myPb_tmp(2), myMv_tmp(2), bub_id, fmass_g, fbeta_c, fbeta_t, & + & mydPbdt_tmp(2), mydMvdt_tmp(2)) end if - myA_tmp(2) = f_rddot(fRho, fP, myR_tmp(2), myV_tmp(2), fR0, & - myPb_tmp(2), mydPbdt_tmp(2), alf, fntait, fBtait, & - f_bub_adv_src, f_divu, & - fCson) + myA_tmp(2) = f_rddot(fRho, fP, myR_tmp(2), myV_tmp(2), fR0, myPb_tmp(2), mydPbdt_tmp(2), alf, fntait, fBtait, & + & f_bub_adv_src, f_divu, fCson) ! Stage 2 myR_tmp(3) = myR_tmp(1) + (h/4._wp)*(myV_tmp(1) + myV_tmp(2)) @@ -789,13 +730,11 @@ contains if (bubbles_lagrange) then myPb_tmp(3) = myPb_tmp(1) + (h/4._wp)*(mydPbdt_tmp(1) + mydPbdt_tmp(2)) myMv_tmp(3) = myMv_tmp(1) + (h/4._wp)*(mydMvdt_tmp(1) + mydMvdt_tmp(2)) - call s_advance_EL(myR_tmp(3), myV_tmp(3), myPb_tmp(3), myMv_tmp(3), & - bub_id, fmass_g, fbeta_c, fbeta_t, mydPbdt_tmp(3), mydMvdt_tmp(3)) + call s_advance_EL(myR_tmp(3), myV_tmp(3), myPb_tmp(3), myMv_tmp(3), bub_id, fmass_g, fbeta_c, fbeta_t, & + & mydPbdt_tmp(3), mydMvdt_tmp(3)) end if - myA_tmp(3) = f_rddot(fRho, fP, myR_tmp(3), myV_tmp(3), fR0, & - myPb_tmp(3), mydPbdt_tmp(3), alf, fntait, fBtait, & - f_bub_adv_src, f_divu, & - fCson) + myA_tmp(3) = f_rddot(fRho, fP, myR_tmp(3), myV_tmp(3), fR0, myPb_tmp(3), mydPbdt_tmp(3), alf, fntait, fBtait, & + & f_bub_adv_src, f_divu, fCson) ! Stage 3 myR_tmp(4) = myR_tmp(1) + (h/6._wp)*(myV_tmp(1) + myV_tmp(2) + 4._wp*myV_tmp(3)) @@ -806,52 +745,48 @@ contains if (bubbles_lagrange) then myPb_tmp(4) = myPb_tmp(1) + (h/6._wp)*(mydPbdt_tmp(1) + mydPbdt_tmp(2) + 4._wp*mydPbdt_tmp(3)) myMv_tmp(4) = myMv_tmp(1) + (h/6._wp)*(mydMvdt_tmp(1) + mydMvdt_tmp(2) + 4._wp*mydMvdt_tmp(3)) - call s_advance_EL(myR_tmp(4), myV_tmp(4), myPb_tmp(4), myMv_tmp(4), & - bub_id, fmass_g, fbeta_c, fbeta_t, mydPbdt_tmp(4), mydMvdt_tmp(4)) + call s_advance_EL(myR_tmp(4), myV_tmp(4), myPb_tmp(4), myMv_tmp(4), bub_id, fmass_g, fbeta_c, fbeta_t, & + & mydPbdt_tmp(4), mydMvdt_tmp(4)) end if - myA_tmp(4) = f_rddot(fRho, fP, myR_tmp(4), myV_tmp(4), fR0, & - myPb_tmp(4), mydPbdt_tmp(4), alf, fntait, fBtait, & - f_bub_adv_src, f_divu, & - fCson) + myA_tmp(4) = f_rddot(fRho, fP, myR_tmp(4), myV_tmp(4), fR0, myPb_tmp(4), mydPbdt_tmp(4), alf, fntait, fBtait, & + & f_bub_adv_src, f_divu, fCson) ! Estimate error - err_R = (-5._wp*h/24._wp)*(myV_tmp(2) + myV_tmp(3) - 2._wp*myV_tmp(4)) & - /max(abs(myR_tmp(1)), abs(myR_tmp(4))) - err_V = (-5._wp*h/24._wp)*(myA_tmp(2) + myA_tmp(3) - 2._wp*myA_tmp(4)) & - /max(abs(myV_tmp(1)), abs(myV_tmp(4))) + err_R = (-5._wp*h/24._wp)*(myV_tmp(2) + myV_tmp(3) - 2._wp*myV_tmp(4))/max(abs(myR_tmp(1)), abs(myR_tmp(4))) + err_V = (-5._wp*h/24._wp)*(myA_tmp(2) + myA_tmp(3) - 2._wp*myA_tmp(4))/max(abs(myV_tmp(1)), abs(myV_tmp(4))) ! Error correction for non-oscillating bubbles if (max(abs(myV_tmp(1)), abs(myV_tmp(4))) < 1.e-12_wp) then err_V = 0._wp end if - if (bubbles_lagrange .and. f_approx_equal(myA_tmp(1), 0._wp) .and. f_approx_equal(myA_tmp(2), 0._wp) .and. & - f_approx_equal(myA_tmp(3), 0._wp) .and. f_approx_equal(myA_tmp(4), 0._wp)) then + if (bubbles_lagrange .and. f_approx_equal(myA_tmp(1), 0._wp) .and. f_approx_equal(myA_tmp(2), & + & 0._wp) .and. f_approx_equal(myA_tmp(3), 0._wp) .and. f_approx_equal(myA_tmp(4), 0._wp)) then err_V = 0._wp end if err = sqrt((err_R**2._wp + err_V**2._wp)/2._wp) end subroutine s_advance_substep - !> Changes of pressure and vapor mass in the lagrange bubbles. - !! @param fR_tmp Bubble radius - !! @param fV_tmp Bubble radial velocity - !! @param fPb_tmp Internal bubble pressure - !! @param fMv_tmp Mass of vapor in the bubble - !! @param bub_id Bubble identifier - !! @param fmass_g Current mass of gas - !! @param fbeta_c Mass transfer coefficient - !! @param fbeta_t Heat transfer coefficient - !! @param fdPbdt_tmp Rate of change of the internal bubble pressure - !! @param fdMvdt_tmp Rate of change of the mass of vapor in the bubble - !! @param advance_EL Rate of change of the mass of vapor in the bubble - subroutine s_advance_EL(fR_tmp, fV_tmp, fPb_tmp, fMv_tmp, bub_id, & - fmass_g, fbeta_c, fbeta_t, fdPbdt_tmp, advance_EL) + !> Changes of pressure and vapor mass in the lagrange bubbles. + !! @param fR_tmp Bubble radius + !! @param fV_tmp Bubble radial velocity + !! @param fPb_tmp Internal bubble pressure + !! @param fMv_tmp Mass of vapor in the bubble + !! @param bub_id Bubble identifier + !! @param fmass_g Current mass of gas + !! @param fbeta_c Mass transfer coefficient + !! @param fbeta_t Heat transfer coefficient + !! @param fdPbdt_tmp Rate of change of the internal bubble pressure + !! @param fdMvdt_tmp Rate of change of the mass of vapor in the bubble + !! @param advance_EL Rate of change of the mass of vapor in the bubble + subroutine s_advance_EL(fR_tmp, fV_tmp, fPb_tmp, fMv_tmp, bub_id, fmass_g, fbeta_c, fbeta_t, fdPbdt_tmp, advance_EL) + $:GPU_ROUTINE(parallelism='[seq]') - real(wp), intent(in) :: fR_tmp, fV_tmp, fPb_tmp, fMv_tmp - real(wp), intent(in) :: fmass_g, fbeta_c, fbeta_t - integer, intent(in) :: bub_id + real(wp), intent(in) :: fR_tmp, fV_tmp, fPb_tmp, fMv_tmp + real(wp), intent(in) :: fmass_g, fbeta_c, fbeta_t + integer, intent(in) :: bub_id real(wp), intent(inout) :: fdPbdt_tmp - real(wp), intent(out) :: advance_EL - real(wp) :: fVapFlux, myR_m, mygamma_m + real(wp), intent(out) :: advance_EL + real(wp) :: fVapFlux, myR_m, mygamma_m call s_vflux(fR_tmp, fV_tmp, fPb_tmp, fMv_tmp, bub_id, fVapFlux, fmass_g, fbeta_c, myR_m, mygamma_m) fdPbdt_tmp = f_bpres_dot(fVapFlux, fR_tmp, fV_tmp, fPb_tmp, fMv_tmp, bub_id, fbeta_t, myR_m, mygamma_m) diff --git a/src/simulation/m_bubbles_EE.fpp b/src/simulation/m_bubbles_EE.fpp index a88d6bb20f..24929202db 100644 --- a/src/simulation/m_bubbles_EE.fpp +++ b/src/simulation/m_bubbles_EE.fpp @@ -7,27 +7,23 @@ !> @brief Computes ensemble-averaged (Euler--Euler) bubble source terms for radius, velocity, pressure, and mass transfer module m_bubbles_EE - use m_derived_types !< Definitions of the derived types - - use m_global_parameters !< Definitions of the global parameters - - use m_mpi_proxy !< Message passing interface (MPI) module proxy - - use m_variables_conversion !< State variables type conversion procedures - - use m_bubbles !< General bubble dynamics procedures + use m_derived_types !< Definitions of the derived types + use m_global_parameters !< Definitions of the global parameters + use m_mpi_proxy !< Message passing interface (MPI) module proxy + use m_variables_conversion !< State variables type conversion procedures + use m_bubbles !< General bubble dynamics procedures implicit none - real(wp), allocatable, dimension(:, :, :) :: bub_adv_src - real(wp), allocatable, dimension(:, :, :, :) :: bub_r_src, bub_v_src, bub_p_src, bub_m_src - $:GPU_DECLARE(create='[bub_adv_src,bub_r_src,bub_v_src,bub_p_src,bub_m_src]') + real(wp), allocatable, dimension(:,:,:) :: bub_adv_src + real(wp), allocatable, dimension(:,:,:,:) :: bub_r_src, bub_v_src, bub_p_src, bub_m_src + $:GPU_DECLARE(create='[bub_adv_src, bub_r_src, bub_v_src, bub_p_src, bub_m_src]') - type(scalar_field) :: divu !< matrix for div(u) + type(scalar_field) :: divu !< matrix for div(u) $:GPU_DECLARE(create='[divu]') integer, allocatable, dimension(:) :: rs, vs, ms, ps - $:GPU_DECLARE(create='[rs,vs,ms,ps]') + $:GPU_DECLARE(create='[rs, vs, ms, ps]') contains @@ -70,13 +66,14 @@ contains end subroutine s_initialize_bubbles_EE_module !> @brief Computes the bubble volume fraction alpha from the bubble number density. - !! @param q_cons_vf is the conservative variable + !! @param q_cons_vf is the conservative variable subroutine s_comp_alpha_from_n(q_cons_vf) + type(scalar_field), dimension(sys_size), intent(inout) :: q_cons_vf - real(wp) :: nR3bar - integer(wp) :: i, j, k, l + real(wp) :: nR3bar + integer(wp) :: i, j, k, l - $:GPU_PARALLEL_LOOP(private='[i,j,k,l,nR3bar]', collapse=3) + $:GPU_PARALLEL_LOOP(private='[i, j, k, l, nR3bar]', collapse=3) do l = 0, p do k = 0, n do j = 0, m @@ -93,101 +90,86 @@ contains end subroutine s_comp_alpha_from_n - !> Compute the right-hand side for Euler-Euler bubble transport - !! @param idir Direction index - !! @param q_prim_vf Primitive variables + !> Compute the right-hand side for Euler-Euler bubble transport + !! @param idir Direction index + !! @param q_prim_vf Primitive variables subroutine s_compute_bubbles_EE_rhs(idir, q_prim_vf, divu_in) - integer, intent(in) :: idir + integer, intent(in) :: idir type(scalar_field), dimension(sys_size), intent(in) :: q_prim_vf - type(scalar_field), intent(inout) :: divu_in !< matrix for div(u) - - integer :: j, k, l + type(scalar_field), intent(inout) :: divu_in !< matrix for div(u) + integer :: j, k, l if (idir == 1) then - if (.not. qbmm) then - $:GPU_PARALLEL_LOOP(private='[j,k,l]', collapse=3) + $:GPU_PARALLEL_LOOP(private='[j, k, l]', collapse=3) do l = 0, p do k = 0, n do j = 0, m divu_in%sf(j, k, l) = 0._wp - divu_in%sf(j, k, l) = & - 5.e-1_wp/dx(j)*(q_prim_vf(contxe + idir)%sf(j + 1, k, l) - & - q_prim_vf(contxe + idir)%sf(j - 1, k, l)) - + divu_in%sf(j, k, l) = 5.e-1_wp/dx(j)*(q_prim_vf(contxe + idir)%sf(j + 1, k, & + & l) - q_prim_vf(contxe + idir)%sf(j - 1, k, l)) end do end do end do $:END_GPU_PARALLEL_LOOP() end if - - elseif (idir == 2) then - - $:GPU_PARALLEL_LOOP(private='[j,k,l]', collapse=3) + else if (idir == 2) then + $:GPU_PARALLEL_LOOP(private='[j, k, l]', collapse=3) do l = 0, p do k = 0, n do j = 0, m - divu_in%sf(j, k, l) = divu_in%sf(j, k, l) + & - 5.e-1_wp/dy(k)*(q_prim_vf(contxe + idir)%sf(j, k + 1, l) - & - q_prim_vf(contxe + idir)%sf(j, k - 1, l)) - + divu_in%sf(j, k, l) = divu_in%sf(j, k, l) + 5.e-1_wp/dy(k)*(q_prim_vf(contxe + idir)%sf(j, k + 1, & + & l) - q_prim_vf(contxe + idir)%sf(j, k - 1, l)) end do end do end do $:END_GPU_PARALLEL_LOOP() - - elseif (idir == 3) then - - $:GPU_PARALLEL_LOOP(private='[j,k,l]', collapse=3) + else if (idir == 3) then + $:GPU_PARALLEL_LOOP(private='[j, k, l]', collapse=3) do l = 0, p do k = 0, n do j = 0, m - divu_in%sf(j, k, l) = divu_in%sf(j, k, l) + & - 5.e-1_wp/dz(l)*(q_prim_vf(contxe + idir)%sf(j, k, l + 1) - & - q_prim_vf(contxe + idir)%sf(j, k, l - 1)) - + divu_in%sf(j, k, l) = divu_in%sf(j, k, l) + 5.e-1_wp/dz(l)*(q_prim_vf(contxe + idir)%sf(j, k, & + & l + 1) - q_prim_vf(contxe + idir)%sf(j, k, l - 1)) end do end do end do $:END_GPU_PARALLEL_LOOP() - end if end subroutine s_compute_bubbles_EE_rhs - !> The purpose of this procedure is to compute the source terms - !! that are needed for the bubble modeling - !! @param q_prim_vf Primitive variables - !! @param q_cons_vf Conservative variables - !! @param rhs_vf Right-hand side variables + !> The purpose of this procedure is to compute the source terms that are needed for the bubble modeling + !! @param q_prim_vf Primitive variables + !! @param q_cons_vf Conservative variables + !! @param rhs_vf Right-hand side variables impure subroutine s_compute_bubble_EE_source(q_cons_vf, q_prim_vf, rhs_vf, divu_in) + type(scalar_field), dimension(sys_size), intent(inout) :: q_cons_vf - type(scalar_field), dimension(sys_size), intent(in) :: q_prim_vf + type(scalar_field), dimension(sys_size), intent(in) :: q_prim_vf type(scalar_field), dimension(sys_size), intent(inout) :: rhs_vf - type(scalar_field), intent(in) :: divu_in !< matrix for div(u) + type(scalar_field), intent(in) :: divu_in !< matrix for div(u) + real(wp) :: rddot + real(wp) :: pb_local, mv_local, vflux, pbdot + real(wp) :: n_tait, B_tait - real(wp) :: rddot - real(wp) :: pb_local, mv_local, vflux, pbdot - real(wp) :: n_tait, B_tait #:if not MFC_CASE_OPTIMIZATION and USING_AMD real(wp), dimension(3) :: Rtmp, Vtmp real(wp), dimension(3) :: myalpha, myalpha_rho #:else - real(wp), dimension(nb) :: Rtmp, Vtmp + real(wp), dimension(nb) :: Rtmp, Vtmp real(wp), dimension(num_fluids) :: myalpha, myalpha_rho #:endif real(wp) :: myR, myV, alf, myP, myRho, R2Vav, R3 - real(wp) :: nbub !< Bubble number density + real(wp) :: nbub !< Bubble number density real(wp) :: my_divu - - integer :: i, j, k, l, q, ii !< Loop variables - - integer :: adap_dt_stop_sum, adap_dt_stop !< Fail-safe exit if max iteration count reached - integer :: dmBub_id !< Dummy variables for unified subgrid bubble subroutines + integer :: i, j, k, l, q, ii !< Loop variables + integer :: adap_dt_stop_sum, adap_dt_stop !< Fail-safe exit if max iteration count reached + integer :: dmBub_id !< Dummy variables for unified subgrid bubble subroutines real(wp) :: dmMass_v, dmMass_n, dmBeta_c, dmBeta_t, dmCson - $:GPU_PARALLEL_LOOP(private='[j,k,l,q]', collapse=3) + $:GPU_PARALLEL_LOOP(private='[j, k, l, q]', collapse=3) do l = 0, p do k = 0, n do j = 0, m @@ -206,12 +188,12 @@ contains $:END_GPU_PARALLEL_LOOP() adap_dt_stop_sum = 0 - $:GPU_PARALLEL_LOOP(private='[j,k,l,Rtmp, Vtmp, myalpha_rho, myalpha, myR, myV, alf, myP, myRho, R2Vav, R3, nbub, pb_local, mv_local, vflux, pbdot, rddot, n_tait, B_tait, my_divu, adap_dt_stop]', collapse=3, & - & copy='[adap_dt_stop_sum]') + $:GPU_PARALLEL_LOOP(private='[j, k, l, Rtmp, Vtmp, myalpha_rho, myalpha, myR, myV, alf, myP, myRho, R2Vav, R3, nbub, & + & pb_local, mv_local, vflux, pbdot, rddot, n_tait, B_tait, my_divu, & + & adap_dt_stop]', collapse=3, copy='[adap_dt_stop_sum]') do l = 0, p do k = 0, n do j = 0, m - if (adv_n) then nbub = q_prim_vf(n_idx)%sf(j, k, l) else @@ -244,7 +226,6 @@ contains $:GPU_LOOP(parallelism='[seq]') do q = 1, nb - $:GPU_LOOP(parallelism='[seq]') do ii = 1, num_fluids myalpha_rho(ii) = q_cons_vf(ii)%sf(j, k, l) @@ -268,8 +249,8 @@ contains end do end if - n_tait = 1._wp/n_tait + 1._wp !make this the usual little 'gamma' - B_tait = B_tait*(n_tait - 1)/n_tait ! make this the usual pi_inf + n_tait = 1._wp/n_tait + 1._wp ! make this the usual little 'gamma' + B_tait = B_tait*(n_tait - 1)/n_tait ! make this the usual pi_inf myP = q_prim_vf(E_idx)%sf(j, k, l) alf = q_prim_vf(alf_idx)%sf(j, k, l) @@ -301,21 +282,15 @@ contains ! Adaptive time stepping if (adap_dt) then - - adap_dt_stop = f_advance_step(myRho, myP, myR, myV, R0(q), & - pb_local, pbdot, alf, n_tait, B_tait, & - bub_adv_src(j, k, l), divu_in%sf(j, k, l), & - dmBub_id, dmMass_v, dmMass_n, dmBeta_c, & - dmBeta_t, dmCson) + adap_dt_stop = f_advance_step(myRho, myP, myR, myV, R0(q), pb_local, pbdot, alf, n_tait, B_tait, & + & bub_adv_src(j, k, l), divu_in%sf(j, k, l), dmBub_id, dmMass_v, & + & dmMass_n, dmBeta_c, dmBeta_t, dmCson) q_cons_vf(rs(q))%sf(j, k, l) = nbub*myR q_cons_vf(vs(q))%sf(j, k, l) = nbub*myV - else - rddot = f_rddot(myRho, myP, myR, myV, R0(q), & - pb_local, pbdot, alf, n_tait, B_tait, & - bub_adv_src(j, k, l), divu_in%sf(j, k, l), & - dmCson) + rddot = f_rddot(myRho, myP, myR, myV, R0(q), pb_local, pbdot, alf, n_tait, B_tait, bub_adv_src(j, & + & k, l), divu_in%sf(j, k, l), dmCson) bub_v_src(j, k, l, q) = nbub*rddot bub_r_src(j, k, l, q) = q_cons_vf(vs(q))%sf(j, k, l) end if @@ -332,13 +307,12 @@ contains if (adap_dt .and. adap_dt_stop_sum > 0) call s_mpi_abort("Adaptive time stepping failed to converge.") if (.not. adap_dt) then - $:GPU_PARALLEL_LOOP(private='[i,k,l,q]', collapse=3) + $:GPU_PARALLEL_LOOP(private='[i, k, l, q]', collapse=3) do l = 0, p do q = 0, n do i = 0, m rhs_vf(alf_idx)%sf(i, q, l) = rhs_vf(alf_idx)%sf(i, q, l) + bub_adv_src(i, q, l) - if (num_fluids > 1) rhs_vf(advxb)%sf(i, q, l) = & - rhs_vf(advxb)%sf(i, q, l) - bub_adv_src(i, q, l) + if (num_fluids > 1) rhs_vf(advxb)%sf(i, q, l) = rhs_vf(advxb)%sf(i, q, l) - bub_adv_src(i, q, l) $:GPU_LOOP(parallelism='[seq]') do k = 1, nb rhs_vf(rs(k))%sf(i, q, l) = rhs_vf(rs(k))%sf(i, q, l) + bub_r_src(i, q, l, k) @@ -353,6 +327,7 @@ contains end do $:END_GPU_PARALLEL_LOOP() end if + end subroutine s_compute_bubble_EE_source end module m_bubbles_EE diff --git a/src/simulation/m_bubbles_EL.fpp b/src/simulation/m_bubbles_EL.fpp index 9e6b413db5..1e89a7b7af 100644 --- a/src/simulation/m_bubbles_EL.fpp +++ b/src/simulation/m_bubbles_EL.fpp @@ -7,112 +7,99 @@ !> @brief Tracks Lagrangian bubbles and couples their dynamics to the Eulerian flow via volume averaging module m_bubbles_EL - use m_global_parameters !< Definitions of the global parameters - - use m_mpi_proxy !< Message passing interface (MPI) module proxy - - use m_bubbles_EL_kernels !< Definitions of the kernel functions - - use m_bubbles !< General bubble dynamics procedures - - use m_variables_conversion !< State variables type conversion procedures - + use m_global_parameters !< Definitions of the global parameters + use m_mpi_proxy !< Message passing interface (MPI) module proxy + use m_bubbles_EL_kernels !< Definitions of the kernel functions + use m_bubbles !< General bubble dynamics procedures + use m_variables_conversion !< State variables type conversion procedures use m_compile_specific - use m_boundary_common - - use m_helper_basic !< Functions to compare floating point numbers - + use m_helper_basic !< Functions to compare floating point numbers use m_sim_helpers - use m_helper - use m_mpi_common - use m_ibm - use m_finite_differences implicit none - !(nBub) - integer, allocatable, dimension(:, :) :: lag_id !< Global and local IDs - real(wp), allocatable, dimension(:) :: bub_R0 !< Initial bubble radius - real(wp), allocatable, dimension(:) :: Rmax_stats !< Maximum radius - real(wp), allocatable, dimension(:) :: Rmin_stats !< Minimum radius + ! (nBub) + integer, allocatable, dimension(:,:) :: lag_id !< Global and local IDs + real(wp), allocatable, dimension(:) :: bub_R0 !< Initial bubble radius + real(wp), allocatable, dimension(:) :: Rmax_stats !< Maximum radius + real(wp), allocatable, dimension(:) :: Rmin_stats !< Minimum radius $:GPU_DECLARE(create='[lag_id, bub_R0, Rmax_stats, Rmin_stats]') - real(wp), allocatable, dimension(:) :: gas_mg !< Bubble's gas mass - real(wp), allocatable, dimension(:) :: gas_betaT !< heatflux model (Preston et al., 2007) - real(wp), allocatable, dimension(:) :: gas_betaC !< massflux model (Preston et al., 2007) - real(wp), allocatable, dimension(:) :: bub_dphidt !< subgrid velocity potential (Maeda & Colonius, 2018) + real(wp), allocatable, dimension(:) :: gas_mg !< Bubble's gas mass + real(wp), allocatable, dimension(:) :: gas_betaT !< heatflux model (Preston et al., 2007) + real(wp), allocatable, dimension(:) :: gas_betaC !< massflux model (Preston et al., 2007) + real(wp), allocatable, dimension(:) :: bub_dphidt !< subgrid velocity potential (Maeda & Colonius, 2018) $:GPU_DECLARE(create='[gas_mg, gas_betaT, gas_betaC, bub_dphidt]') - !(nBub, 1 -> actual val or 2 -> temp val) - real(wp), allocatable, dimension(:, :) :: gas_p !< Pressure in the bubble - real(wp), allocatable, dimension(:, :) :: gas_mv !< Vapor mass in the bubble - real(wp), allocatable, dimension(:, :) :: intfc_rad !< Bubble radius - real(wp), allocatable, dimension(:, :) :: intfc_vel !< Velocity of the bubble interface + ! (nBub, 1 -> actual val or 2 -> temp val) + real(wp), allocatable, dimension(:,:) :: gas_p !< Pressure in the bubble + real(wp), allocatable, dimension(:,:) :: gas_mv !< Vapor mass in the bubble + real(wp), allocatable, dimension(:,:) :: intfc_rad !< Bubble radius + real(wp), allocatable, dimension(:,:) :: intfc_vel !< Velocity of the bubble interface $:GPU_DECLARE(create='[gas_p, gas_mv, intfc_rad, intfc_vel]') - !(nBub, 1-> x or 2->y or 3 ->z, 1 -> actual or 2 -> temporal val) - real(wp), allocatable, dimension(:, :, :) :: mtn_pos !< Bubble's position - real(wp), allocatable, dimension(:, :, :) :: mtn_posPrev !< Bubble's previous position - real(wp), allocatable, dimension(:, :, :) :: mtn_vel !< Bubble's velocity - real(wp), allocatable, dimension(:, :, :) :: mtn_s !< Bubble's computational cell position in real format + ! (nBub, 1-> x or 2->y or 3 ->z, 1 -> actual or 2 -> temporal val) + real(wp), allocatable, dimension(:,:,:) :: mtn_pos !< Bubble's position + real(wp), allocatable, dimension(:,:,:) :: mtn_posPrev !< Bubble's previous position + real(wp), allocatable, dimension(:,:,:) :: mtn_vel !< Bubble's velocity + real(wp), allocatable, dimension(:,:,:) :: mtn_s !< Bubble's computational cell position in real format $:GPU_DECLARE(create='[mtn_pos, mtn_posPrev, mtn_vel, mtn_s]') - !(nBub, 1-> x or 2->y or 3 ->z, time-stage) - real(wp), allocatable, dimension(:, :) :: intfc_draddt !< Time derivative of bubble's radius - real(wp), allocatable, dimension(:, :) :: intfc_dveldt !< Time derivative of bubble's interface velocity - real(wp), allocatable, dimension(:, :) :: gas_dpdt !< Time derivative of gas pressure - real(wp), allocatable, dimension(:, :) :: gas_dmvdt !< Time derivative of the vapor mass in the bubble - real(wp), allocatable, dimension(:, :, :) :: mtn_dposdt !< Time derivative of the bubble's position - real(wp), allocatable, dimension(:, :, :) :: mtn_dveldt !< Time derivative of the bubble's velocity + ! (nBub, 1-> x or 2->y or 3 ->z, time-stage) + real(wp), allocatable, dimension(:,:) :: intfc_draddt !< Time derivative of bubble's radius + real(wp), allocatable, dimension(:,:) :: intfc_dveldt !< Time derivative of bubble's interface velocity + real(wp), allocatable, dimension(:,:) :: gas_dpdt !< Time derivative of gas pressure + real(wp), allocatable, dimension(:,:) :: gas_dmvdt !< Time derivative of the vapor mass in the bubble + real(wp), allocatable, dimension(:,:,:) :: mtn_dposdt !< Time derivative of the bubble's position + real(wp), allocatable, dimension(:,:,:) :: mtn_dveldt !< Time derivative of the bubble's velocity $:GPU_DECLARE(create='[intfc_draddt, intfc_dveldt, gas_dpdt, gas_dmvdt, mtn_dposdt, mtn_dveldt]') - integer, private :: lag_num_ts !< Number of time stages in the time-stepping scheme + integer, private :: lag_num_ts !< Number of time stages in the time-stepping scheme $:GPU_DECLARE(create='[lag_num_ts]') - real(wp) :: Rmax_glb, Rmin_glb !< Maximum and minimum bubble size in the local domain - !< Projection of the lagrangian particles in the Eulerian framework + real(wp) :: Rmax_glb, Rmin_glb !< Maximum and minimum bubble size in the local domain + !> Projection of the lagrangian particles in the Eulerian framework type(scalar_field), dimension(:), allocatable :: q_beta - type(scalar_field), dimension(:), allocatable :: kahan_comp !< Kahan compensation for q_beta accumulation - integer :: q_beta_idx !< Size of the q_beta vector field - - $:GPU_DECLARE(create='[Rmax_glb,Rmin_glb,q_beta,kahan_comp,q_beta_idx]') + type(scalar_field), dimension(:), allocatable :: kahan_comp !< Kahan compensation for q_beta accumulation + integer :: q_beta_idx !< Size of the q_beta vector field - integer, parameter :: LAG_EVOL_ID = 11 ! File id for lag_bubbles_evol_*.dat - integer, parameter :: LAG_STATS_ID = 12 ! File id for stats_lag_bubbles_*.dat - integer, parameter :: LAG_VOID_ID = 13 ! File id for voidfraction.dat + $:GPU_DECLARE(create='[Rmax_glb, Rmin_glb, q_beta, kahan_comp, q_beta_idx]') - integer, allocatable, dimension(:) :: keep_bubble - integer, allocatable, dimension(:, :) :: wrap_bubble_loc, wrap_bubble_dir + integer, parameter :: LAG_EVOL_ID = 11 ! File id for lag_bubbles_evol_*.dat + integer, parameter :: LAG_STATS_ID = 12 ! File id for stats_lag_bubbles_*.dat + integer, parameter :: LAG_VOID_ID = 13 ! File id for voidfraction.dat + integer, allocatable, dimension(:) :: keep_bubble + integer, allocatable, dimension(:,:) :: wrap_bubble_loc, wrap_bubble_dir $:GPU_DECLARE(create='[keep_bubble]') $:GPU_DECLARE(create='[wrap_bubble_loc, wrap_bubble_dir]') contains !> Initializes the lagrangian subgrid bubble solver - !! @param q_cons_vf Initial conservative variables + !! @param q_cons_vf Initial conservative variables impure subroutine s_initialize_bubbles_EL_module(q_cons_vf, bc_type) - type(scalar_field), dimension(sys_size), intent(inout) :: q_cons_vf - type(integer_field), dimension(1:num_dims, 1:2), intent(in) :: bc_type - - integer :: nBubs_glb, i + type(scalar_field), dimension(sys_size), intent(inout) :: q_cons_vf + type(integer_field), dimension(1:num_dims,1:2), intent(in) :: bc_type + integer :: nBubs_glb, i ! Setting number of time-stages for selected time-stepping scheme + lag_num_ts = time_stepper ! Allocate space for the Eulerian fields needed to map the effect of the bubbles if (lag_params%solver_approach == 1) then ! One-way coupling q_beta_idx = 3 - elseif (lag_params%solver_approach == 2) then + else if (lag_params%solver_approach == 2) then ! Two-way coupling q_beta_idx = 4 if (p == 0) then - !Subgrid noise model for 2D approximation + ! Subgrid noise model for 2D approximation q_beta_idx = 6 end if else @@ -139,13 +126,10 @@ contains @:ALLOCATE(kahan_comp(1:q_beta_idx)) do i = 1, q_beta_idx - @:ALLOCATE(q_beta(i)%sf(idwbuff(1)%beg:idwbuff(1)%end, & - idwbuff(2)%beg:idwbuff(2)%end, & - idwbuff(3)%beg:idwbuff(3)%end)) + @:ALLOCATE(q_beta(i)%sf(idwbuff(1)%beg:idwbuff(1)%end, idwbuff(2)%beg:idwbuff(2)%end, idwbuff(3)%beg:idwbuff(3)%end)) @:ACC_SETUP_SFs(q_beta(i)) - @:ALLOCATE(kahan_comp(i)%sf(idwbuff(1)%beg:idwbuff(1)%end, & - idwbuff(2)%beg:idwbuff(2)%end, & - idwbuff(3)%beg:idwbuff(3)%end)) + @:ALLOCATE(kahan_comp(i)%sf(idwbuff(1)%beg:idwbuff(1)%end, idwbuff(2)%beg:idwbuff(2)%end, & + & idwbuff(3)%beg:idwbuff(3)%end)) @:ACC_SETUP_SFs(kahan_comp(i)) end do @@ -194,28 +178,24 @@ contains lag_vel_model = lag_params%vel_model lag_drag_model = lag_params%drag_model end if - $:GPU_UPDATE(device='[moving_lag_bubbles, lag_pressure_force, & - & lag_gravity_force, lag_vel_model, lag_drag_model]') + $:GPU_UPDATE(device='[moving_lag_bubbles, lag_pressure_force, lag_gravity_force, lag_vel_model, lag_drag_model]') ! Allocate cell-centered pressure gradient arrays and FD coefficients if (lag_params%vel_model > 0 .and. lag_params%pressure_force) then @:ALLOCATE(grad_p_x(0:m, 0:n, 0:p)) @:ALLOCATE(fd_coeff_x_pgrad(-fd_number:fd_number, 0:m)) - call s_compute_finite_difference_coefficients(m, x_cc, fd_coeff_x_pgrad, & - buff_size, fd_number, fd_order) + call s_compute_finite_difference_coefficients(m, x_cc, fd_coeff_x_pgrad, buff_size, fd_number, fd_order) $:GPU_UPDATE(device='[fd_coeff_x_pgrad]') if (n > 0) then @:ALLOCATE(grad_p_y(0:m, 0:n, 0:p)) @:ALLOCATE(fd_coeff_y_pgrad(-fd_number:fd_number, 0:n)) - call s_compute_finite_difference_coefficients(n, y_cc, fd_coeff_y_pgrad, & - buff_size, fd_number, fd_order) + call s_compute_finite_difference_coefficients(n, y_cc, fd_coeff_y_pgrad, buff_size, fd_number, fd_order) $:GPU_UPDATE(device='[fd_coeff_y_pgrad]') end if if (p > 0) then @:ALLOCATE(grad_p_z(0:m, 0:n, 0:p)) @:ALLOCATE(fd_coeff_z_pgrad(-fd_number:fd_number, 0:p)) - call s_compute_finite_difference_coefficients(p, z_cc, fd_coeff_z_pgrad, & - buff_size, fd_number, fd_order) + call s_compute_finite_difference_coefficients(p, z_cc, fd_coeff_z_pgrad, buff_size, fd_number, fd_order) $:GPU_UPDATE(device='[fd_coeff_z_pgrad]') end if end if @@ -230,22 +210,21 @@ contains end subroutine s_initialize_bubbles_EL_module !> The purpose of this procedure is to obtain the initial bubbles' information - !! @param q_cons_vf Conservative variables + !! @param q_cons_vf Conservative variables impure subroutine s_read_input_bubbles(q_cons_vf, bc_type) - type(scalar_field), dimension(sys_size), intent(inout) :: q_cons_vf - type(integer_field), dimension(1:num_dims, 1:2), intent(in) :: bc_type - - real(wp), dimension(8) :: inputBubble - real(wp) :: qtime - integer :: id, bub_id, save_count - integer :: i, ios - logical :: file_exist, indomain - integer, dimension(3) :: cell - - character(LEN=path_len + 2*name_len) :: path_D_dir !< + type(scalar_field), dimension(sys_size), intent(inout) :: q_cons_vf + type(integer_field), dimension(1:num_dims,1:2), intent(in) :: bc_type + real(wp), dimension(8) :: inputBubble + real(wp) :: qtime + integer :: id, bub_id, save_count + integer :: i, ios + logical :: file_exist, indomain + integer, dimension(3) :: cell + character(LEN=path_len + 2*name_len) :: path_D_dir ! Initialize number of particles + bub_id = 0 id = 0 @@ -274,14 +253,14 @@ contains if (indomain) then bub_id = bub_id + 1 call s_add_bubbles(inputBubble, q_cons_vf, bub_id) - lag_id(bub_id, 1) = id !global ID - lag_id(bub_id, 2) = bub_id !local ID - n_el_bubs_loc = bub_id ! local number of bubbles + lag_id(bub_id, 1) = id ! global ID + lag_id(bub_id, 2) = bub_id ! local ID + n_el_bubs_loc = bub_id ! local number of bubbles end if end do close (94) else - call s_mpi_abort("Initialize the lagrange bubbles in "//trim(lag_params%input_path)) + call s_mpi_abort("Initialize the lagrange bubbles in " // trim(lag_params%input_path)) end if else if (proc_rank == 0) print *, 'Restarting lagrange bubbles at save_count: ', save_count @@ -297,36 +276,34 @@ contains end if if (proc_rank == 0) then - if (n_el_bubs_glb == 0) call s_mpi_abort('No bubbles in the domain. Check '//trim(lag_params%input_path)) + if (n_el_bubs_glb == 0) call s_mpi_abort('No bubbles in the domain. Check ' // trim(lag_params%input_path)) end if $:GPU_UPDATE(device='[bubbles_lagrange, lag_params]') - $:GPU_UPDATE(device='[lag_id,bub_R0,Rmax_stats,Rmin_stats,gas_mg, & - & gas_betaT,gas_betaC,bub_dphidt,gas_p,gas_mv, & - & intfc_rad,intfc_vel,mtn_pos,mtn_posPrev,mtn_vel, & - & mtn_s,intfc_draddt,intfc_dveldt,gas_dpdt,gas_dmvdt, & - & mtn_dposdt,mtn_dveldt,n_el_bubs_loc]') + $:GPU_UPDATE(device='[lag_id, bub_R0, Rmax_stats, Rmin_stats, gas_mg, gas_betaT, gas_betaC, bub_dphidt, gas_p, gas_mv, & + & intfc_rad, intfc_vel, mtn_pos, mtn_posPrev, mtn_vel, mtn_s, intfc_draddt, intfc_dveldt, gas_dpdt, & + & gas_dmvdt, mtn_dposdt, mtn_dveldt, n_el_bubs_loc]') Rmax_glb = min(dflt_real, -dflt_real) Rmin_glb = max(dflt_real, -dflt_real) $:GPU_UPDATE(device='[Rmax_glb, Rmin_glb]') - $:GPU_UPDATE(device='[dx,dy,dz,x_cb,x_cc,y_cb,y_cc,z_cb,z_cc]') + $:GPU_UPDATE(device='[dx, dy, dz, x_cb, x_cc, y_cb, y_cc, z_cb, z_cc]') - !Populate temporal variables + ! Populate temporal variables call s_transfer_data_to_tmp() call s_smear_voidfraction(bc_type) if (save_count == 0) then ! Create ./D directory if (proc_rank == 0) then - write (path_D_dir, '(A,I0,A,I0)') trim(case_dir)//'/D' + write (path_D_dir, '(A,I0,A,I0)') trim(case_dir) // '/D' call my_inquire(trim(path_D_dir), file_exist) if (.not. file_exist) call s_create_directory(trim(path_D_dir)) end if call s_mpi_barrier() - call s_write_restart_lag_bubbles(save_count) ! Needed for post_processing + call s_write_restart_lag_bubbles(save_count) ! Needed for post_processing if (lag_params%write_void_evol) call s_write_void_evol(qtime) end if @@ -335,21 +312,20 @@ contains end subroutine s_read_input_bubbles !> The purpose of this procedure is to obtain the information of the bubbles when starting fresh - !! @param inputBubble Bubble information - !! @param q_cons_vf Conservative variables - !! @param bub_id Local id of the bubble + !! @param inputBubble Bubble information + !! @param q_cons_vf Conservative variables + !! @param bub_id Local id of the bubble impure subroutine s_add_bubbles(inputBubble, q_cons_vf, bub_id) type(scalar_field), dimension(sys_size), intent(in) :: q_cons_vf - real(wp), dimension(8), intent(in) :: inputBubble - integer, intent(in) :: bub_id - integer :: i - - real(wp) :: pliq, volparticle, concvap, totalmass, kparticle, cpparticle - real(wp) :: omegaN_local, PeG, PeT, rhol, pcrit, qv, gamma, pi_inf, dynP - integer, dimension(3) :: cell - real(wp), dimension(2) :: Re - real(wp) :: massflag, heatflag, Re_trans, Im_trans + real(wp), dimension(8), intent(in) :: inputBubble + integer, intent(in) :: bub_id + integer :: i + real(wp) :: pliq, volparticle, concvap, totalmass, kparticle, cpparticle + real(wp) :: omegaN_local, PeG, PeT, rhol, pcrit, qv, gamma, pi_inf, dynP + integer, dimension(3) :: cell + real(wp), dimension(2) :: Re + real(wp) :: massflag, heatflag, Re_trans, Im_trans massflag = 0._wp heatflag = 0._wp @@ -362,45 +338,45 @@ contains bub_dphidt(bub_id) = 0._wp intfc_rad(bub_id, 1) = inputBubble(7) intfc_vel(bub_id, 1) = inputBubble(8) - mtn_pos(bub_id, 1:3, 1) = inputBubble(1:3) - mtn_posPrev(bub_id, 1:3, 1) = mtn_pos(bub_id, 1:3, 1) - mtn_vel(bub_id, 1:3, 1) = inputBubble(4:6) + mtn_pos(bub_id,1:3,1) = inputBubble(1:3) + mtn_posPrev(bub_id,1:3,1) = mtn_pos(bub_id,1:3,1) + mtn_vel(bub_id,1:3,1) = inputBubble(4:6) if (cyl_coord .and. p == 0) then - mtn_pos(bub_id, 2, 1) = sqrt(mtn_pos(bub_id, 2, 1)**2._wp + & - mtn_pos(bub_id, 3, 1)**2._wp) - !Storing azimuthal angle (-Pi to Pi)) into the third coordinate variable + mtn_pos(bub_id, 2, 1) = sqrt(mtn_pos(bub_id, 2, 1)**2._wp + mtn_pos(bub_id, 3, 1)**2._wp) + ! Storing azimuthal angle (-Pi to Pi)) into the third coordinate variable mtn_pos(bub_id, 3, 1) = atan2(inputBubble(3), inputBubble(2)) - mtn_posPrev(bub_id, 1:3, 1) = mtn_pos(bub_id, 1:3, 1) + mtn_posPrev(bub_id,1:3,1) = mtn_pos(bub_id,1:3,1) end if cell = fd_number - buff_size - call s_locate_cell(mtn_pos(bub_id, 1:3, 1), cell, mtn_s(bub_id, 1:3, 1)) + call s_locate_cell(mtn_pos(bub_id,1:3,1), cell, mtn_s(bub_id,1:3,1)) ! Check if the bubble is located in the ghost cell of a symmetric, or wall boundary - if ((any(bc_x%beg == (/BC_REFLECTIVE, BC_CHAR_SLIP_WALL, BC_SLIP_WALL, BC_NO_SLIP_WALL/)) .and. cell(1) < 0) .or. & - (any(bc_x%end == (/BC_REFLECTIVE, BC_CHAR_SLIP_WALL, BC_SLIP_WALL, BC_NO_SLIP_WALL/)) .and. cell(1) > m) .or. & - (any(bc_y%beg == (/BC_REFLECTIVE, BC_CHAR_SLIP_WALL, BC_SLIP_WALL, BC_NO_SLIP_WALL/)) .and. cell(2) < 0) .or. & - (any(bc_y%end == (/BC_REFLECTIVE, BC_CHAR_SLIP_WALL, BC_SLIP_WALL, BC_NO_SLIP_WALL/)) .and. cell(2) > n)) then + if ((any(bc_x%beg == (/BC_REFLECTIVE, BC_CHAR_SLIP_WALL, BC_SLIP_WALL, & + & BC_NO_SLIP_WALL/)) .and. cell(1) < 0) .or. (any(bc_x%end == (/BC_REFLECTIVE, BC_CHAR_SLIP_WALL, BC_SLIP_WALL, & + & BC_NO_SLIP_WALL/)) .and. cell(1) > m) .or. (any(bc_y%beg == (/BC_REFLECTIVE, BC_CHAR_SLIP_WALL, BC_SLIP_WALL, & + & BC_NO_SLIP_WALL/)) .and. cell(2) < 0) .or. (any(bc_y%end == (/BC_REFLECTIVE, BC_CHAR_SLIP_WALL, BC_SLIP_WALL, & + & BC_NO_SLIP_WALL/)) .and. cell(2) > n)) then call s_mpi_abort("Lagrange bubble is in the ghost cells of a symmetric or wall boundary.") end if if (p > 0) then - if ((any(bc_z%beg == (/BC_REFLECTIVE, BC_CHAR_SLIP_WALL, BC_SLIP_WALL, BC_NO_SLIP_WALL/)) .and. cell(3) < 0) .or. & - (any(bc_z%end == (/BC_REFLECTIVE, BC_CHAR_SLIP_WALL, BC_SLIP_WALL, BC_NO_SLIP_WALL/)) .and. cell(3) > p)) then + if ((any(bc_z%beg == (/BC_REFLECTIVE, BC_CHAR_SLIP_WALL, BC_SLIP_WALL, & + & BC_NO_SLIP_WALL/)) .and. cell(3) < 0) .or. (any(bc_z%end == (/BC_REFLECTIVE, BC_CHAR_SLIP_WALL, BC_SLIP_WALL, & + & BC_NO_SLIP_WALL/)) .and. cell(3) > p)) then call s_mpi_abort("Lagrange bubble is in the ghost cells of a symmetric or wall boundary.") end if end if - call s_convert_to_mixture_variables(q_cons_vf, cell(1), cell(2), cell(3), & - rhol, gamma, pi_inf, qv, Re) + call s_convert_to_mixture_variables(q_cons_vf, cell(1), cell(2), cell(3), rhol, gamma, pi_inf, qv, Re) dynP = 0._wp do i = 1, num_dims dynP = dynP + 0.5_wp*q_cons_vf(contxe + i)%sf(cell(1), cell(2), cell(3))**2/rhol end do pliq = (q_cons_vf(E_idx)%sf(cell(1), cell(2), cell(3)) - dynP - pi_inf)/gamma - if (pliq < 0) print *, "Negative pressure", proc_rank, & - q_cons_vf(E_idx)%sf(cell(1), cell(2), cell(3)), pi_inf, gamma, pliq, cell, dynP + if (pliq < 0) print *, "Negative pressure", proc_rank, q_cons_vf(E_idx)%sf(cell(1), cell(2), cell(3)), pi_inf, gamma, & + & pliq, cell, dynP ! Initial particle pressure gas_p(bub_id, 1) = pliq + 2._wp*(1._wp/Web)/bub_R0(bub_id) @@ -412,13 +388,13 @@ contains end if ! Initial particle mass - volparticle = 4._wp/3._wp*pi*bub_R0(bub_id)**3._wp ! volume - gas_mv(bub_id, 1) = pv*volparticle*(1._wp/(R_v*Tw))*(massflag) ! vapermass - gas_mg(bub_id) = (gas_p(bub_id, 1) - pv*(massflag))*volparticle*(1._wp/(R_g*Tw)) ! gasmass + volparticle = 4._wp/3._wp*pi*bub_R0(bub_id)**3._wp ! volume + gas_mv(bub_id, 1) = pv*volparticle*(1._wp/(R_v*Tw))*(massflag) ! vapermass + gas_mg(bub_id) = (gas_p(bub_id, 1) - pv*(massflag))*volparticle*(1._wp/(R_g*Tw)) ! gasmass if (gas_mg(bub_id) <= 0._wp) then call s_mpi_abort("The initial mass of gas inside the bubble is negative. Check the initial conditions.") end if - totalmass = gas_mg(bub_id) + gas_mv(bub_id, 1) ! totalmass + totalmass = gas_mg(bub_id) + gas_mv(bub_id, 1) ! totalmass ! Bubble natural frequency concvap = gas_mv(bub_id, 1)/(gas_mv(bub_id, 1) + gas_mg(bub_id)) @@ -447,48 +423,43 @@ contains end subroutine s_add_bubbles !> The purpose of this procedure is to obtain the information of the bubbles from a restart point. - !! @param bub_id Local ID of the particle - !! @param save_count File identifier + !! @param bub_id Local ID of the particle + !! @param save_count File identifier impure subroutine s_restart_bubbles(bub_id, save_count) - integer, intent(inout) :: bub_id, save_count - + integer, intent(inout) :: bub_id, save_count character(LEN=path_len + 2*name_len) :: file_loc - real(wp) :: file_time, file_dt - integer :: file_num_procs, file_tot_part, tot_part + real(wp) :: file_time, file_dt + integer :: file_num_procs, file_tot_part, tot_part #ifdef MFC_MPI - real(wp), dimension(20) :: inputvals - integer, dimension(MPI_STATUS_SIZE) :: status - integer(kind=MPI_OFFSET_KIND) :: disp - integer :: view - - integer, dimension(3) :: cell - logical :: indomain, particle_file, file_exist - - integer, dimension(2) :: gsizes, lsizes, start_idx_part - integer :: ifile, ierr, tot_data, id - integer :: i - - integer, dimension(:), allocatable :: proc_bubble_counts - real(wp), dimension(1:1, 1:lag_io_vars) :: dummy + real(wp), dimension(20) :: inputvals + integer, dimension(MPI_STATUS_SIZE) :: status + integer(kind=MPI_OFFSET_KIND) :: disp + integer :: view + integer, dimension(3) :: cell + logical :: indomain, particle_file, file_exist + integer, dimension(2) :: gsizes, lsizes, start_idx_part + integer :: ifile, ierr, tot_data, id + integer :: i + integer, dimension(:), allocatable :: proc_bubble_counts + real(wp), dimension(1:1,1:lag_io_vars) :: dummy dummy = 0._wp ! Construct file path write (file_loc, '(A,I0,A)') 'lag_bubbles_', save_count, '.dat' - file_loc = trim(case_dir)//'/restart_data'//trim(mpiiofs)//trim(file_loc) + file_loc = trim(case_dir) // '/restart_data' // trim(mpiiofs) // trim(file_loc) ! Check if file exists inquire (FILE=trim(file_loc), EXIST=file_exist) if (.not. file_exist) then - call s_mpi_abort('Restart file '//trim(file_loc)//' does not exist!') + call s_mpi_abort('Restart file ' // trim(file_loc) // ' does not exist!') end if if (.not. parallel_io) return if (proc_rank == 0) then - call MPI_FILE_OPEN(MPI_COMM_SELF, file_loc, MPI_MODE_RDONLY, & - mpi_info_int, ifile, ierr) + call MPI_FILE_OPEN(MPI_COMM_SELF, file_loc, MPI_MODE_RDONLY, mpi_info_int, ifile, ierr) call MPI_FILE_READ(ifile, file_tot_part, 1, MPI_INTEGER, status, ierr) call MPI_FILE_READ(ifile, file_time, 1, mpi_p, status, ierr) @@ -506,12 +477,10 @@ contains allocate (proc_bubble_counts(file_num_procs)) if (proc_rank == 0) then - call MPI_FILE_OPEN(MPI_COMM_SELF, file_loc, MPI_MODE_RDONLY, & - mpi_info_int, ifile, ierr) + call MPI_FILE_OPEN(MPI_COMM_SELF, file_loc, MPI_MODE_RDONLY, mpi_info_int, ifile, ierr) ! Skip to processor counts position - disp = int(sizeof(file_tot_part) + 2*sizeof(file_time) + sizeof(file_num_procs), & - MPI_OFFSET_KIND) + disp = int(sizeof(file_tot_part) + 2*sizeof(file_time) + sizeof(file_num_procs), MPI_OFFSET_KIND) call MPI_FILE_SEEK(ifile, disp, MPI_SEEK_SET, ierr) call MPI_FILE_READ(ifile, proc_bubble_counts, file_num_procs, MPI_INTEGER, status, ierr) @@ -539,23 +508,19 @@ contains gsizes(2) = lag_io_vars if (bub_id > 0) then + allocate (MPI_IO_DATA_lag_bubbles(bub_id,1:lag_io_vars)) - allocate (MPI_IO_DATA_lag_bubbles(bub_id, 1:lag_io_vars)) - - call MPI_TYPE_CREATE_SUBARRAY(2, gsizes, lsizes, start_idx_part, & - MPI_ORDER_FORTRAN, mpi_p, view, ierr) + call MPI_TYPE_CREATE_SUBARRAY(2, gsizes, lsizes, start_idx_part, MPI_ORDER_FORTRAN, mpi_p, view, ierr) call MPI_TYPE_COMMIT(view, ierr) - call MPI_FILE_OPEN(MPI_COMM_WORLD, file_loc, MPI_MODE_RDONLY, & - mpi_info_int, ifile, ierr) + call MPI_FILE_OPEN(MPI_COMM_WORLD, file_loc, MPI_MODE_RDONLY, mpi_info_int, ifile, ierr) ! Skip extended header - disp = int(sizeof(file_tot_part) + 2*sizeof(file_time) + sizeof(file_num_procs) + & - file_num_procs*sizeof(proc_bubble_counts(1)), MPI_OFFSET_KIND) + disp = int(sizeof(file_tot_part) + 2*sizeof(file_time) + sizeof(file_num_procs) & + & + file_num_procs*sizeof(proc_bubble_counts(1)), MPI_OFFSET_KIND) call MPI_FILE_SET_VIEW(ifile, disp, mpi_p, view, 'native', mpi_info_int, ierr) - call MPI_FILE_READ_ALL(ifile, MPI_IO_DATA_lag_bubbles, & - lag_io_vars*bub_id, mpi_p, status, ierr) + call MPI_FILE_READ_ALL(ifile, MPI_IO_DATA_lag_bubbles, lag_io_vars*bub_id, mpi_p, status, ierr) call MPI_FILE_CLOSE(ifile, ierr) call MPI_TYPE_FREE(view, ierr) @@ -564,9 +529,9 @@ contains do i = 1, bub_id lag_id(i, 1) = int(MPI_IO_DATA_lag_bubbles(i, 1)) - mtn_pos(i, 1:3, 1) = MPI_IO_DATA_lag_bubbles(i, 2:4) - mtn_posPrev(i, 1:3, 1) = MPI_IO_DATA_lag_bubbles(i, 5:7) - mtn_vel(i, 1:3, 1) = MPI_IO_DATA_lag_bubbles(i, 8:10) + mtn_pos(i,1:3,1) = MPI_IO_DATA_lag_bubbles(i,2:4) + mtn_posPrev(i,1:3,1) = MPI_IO_DATA_lag_bubbles(i,5:7) + mtn_vel(i,1:3,1) = MPI_IO_DATA_lag_bubbles(i,8:10) intfc_rad(i, 1) = MPI_IO_DATA_lag_bubbles(i, 11) intfc_vel(i, 1) = MPI_IO_DATA_lag_bubbles(i, 12) bub_R0(i) = MPI_IO_DATA_lag_bubbles(i, 13) @@ -579,23 +544,21 @@ contains gas_betaT(i) = MPI_IO_DATA_lag_bubbles(i, 20) gas_betaC(i) = MPI_IO_DATA_lag_bubbles(i, 21) cell = -buff_size - call s_locate_cell(mtn_pos(i, 1:3, 1), cell, mtn_s(i, 1:3, 1)) + call s_locate_cell(mtn_pos(i,1:3,1), cell, mtn_s(i,1:3,1)) end do deallocate (MPI_IO_DATA_lag_bubbles) - else n_el_bubs_loc = 0 call MPI_TYPE_CONTIGUOUS(0, mpi_p, view, ierr) call MPI_TYPE_COMMIT(view, ierr) - call MPI_FILE_OPEN(MPI_COMM_WORLD, file_loc, MPI_MODE_RDONLY, & - mpi_info_int, ifile, ierr) + call MPI_FILE_OPEN(MPI_COMM_WORLD, file_loc, MPI_MODE_RDONLY, mpi_info_int, ifile, ierr) ! Skip extended header - disp = int(sizeof(file_tot_part) + 2*sizeof(file_time) + sizeof(file_num_procs) + & - file_num_procs*sizeof(proc_bubble_counts(1)), MPI_OFFSET_KIND) + disp = int(sizeof(file_tot_part) + 2*sizeof(file_time) + sizeof(file_num_procs) & + & + file_num_procs*sizeof(proc_bubble_counts(1)), MPI_OFFSET_KIND) call MPI_FILE_SET_VIEW(ifile, disp, mpi_p, view, 'native', mpi_info_int, ierr) call MPI_FILE_READ_ALL(ifile, dummy, 0, mpi_p, status, ierr) @@ -614,22 +577,22 @@ contains end subroutine s_restart_bubbles - !> Contains the bubble dynamics subroutines. - !! @param q_prim_vf Primitive variables - !! @param stage Current stage in the time-stepper algorithm + !> Contains the bubble dynamics subroutines. + !! @param q_prim_vf Primitive variables + !! @param stage Current stage in the time-stepper algorithm subroutine s_compute_bubble_EL_dynamics(q_prim_vf, bc_type, stage) - type(scalar_field), dimension(sys_size), intent(inout) :: q_prim_vf - type(integer_field), dimension(1:num_dims, 1:2), intent(in) :: bc_type - integer, intent(in) :: stage - - real(wp) :: myVapFlux - real(wp) :: preterm1, term2, paux, pint, Romega, term1_fac - real(wp) :: myR_m, mygamma_m, myPb, myMass_n, myMass_v - real(wp) :: myR, myV, myBeta_c, myBeta_t, myR0, myPbdot, myMvdot - real(wp) :: myPinf, aux1, aux2, myCson, myRho - real(wp), dimension(3) :: myPos, myVel - real(wp) :: gamma, pi_inf, qv, f_b, myRe + type(scalar_field), dimension(sys_size), intent(inout) :: q_prim_vf + type(integer_field), dimension(1:num_dims,1:2), intent(in) :: bc_type + integer, intent(in) :: stage + real(wp) :: myVapFlux + real(wp) :: preterm1, term2, paux, pint, Romega, term1_fac + real(wp) :: myR_m, mygamma_m, myPb, myMass_n, myMass_v + real(wp) :: myR, myV, myBeta_c, myBeta_t, myR0, myPbdot, myMvdot + real(wp) :: myPinf, aux1, aux2, myCson, myRho + real(wp), dimension(3) :: myPos, myVel + real(wp) :: gamma, pi_inf, qv, f_b, myRe + #:if not MFC_CASE_OPTIMIZATION and USING_AMD real(wp), dimension(3) :: myalpha_rho, myalpha #:else @@ -637,17 +600,15 @@ contains #:endif real(wp), dimension(2) :: Re integer, dimension(3) :: cell - - integer :: adap_dt_stop_sum, adap_dt_stop !< Fail-safe exit if max iteration count reached - real(wp) :: dmalf, dmntait, dmBtait, dm_bub_adv_src, dm_divu !< Dummy variables for unified subgrid bubble subroutines - + integer :: adap_dt_stop_sum, adap_dt_stop !< Fail-safe exit if max iteration count reached + real(wp) :: dmalf, dmntait, dmBtait, dm_bub_adv_src, dm_divu !< Dummy variables for unified subgrid bubble subroutines integer :: k, l ! Subgrid p_inf model based on Maeda and Colonius (2018). if (lag_params%pressure_corrector) then call nvtxStartRange("LAGRANGE-BUBBLE-PINF-CORRECTION") ! Calculate velocity potentials (valid for one bubble per cell) - $:GPU_PARALLEL_LOOP(private='[k,cell,paux,preterm1,term2,Romega,myR0,myR,myV,myPb,pint,term1_fac]') + $:GPU_PARALLEL_LOOP(private='[k, cell, paux, preterm1, term2, Romega, myR0, myR, myV, myPb, pint, term1_fac]') do k = 1, n_el_bubs_loc call s_get_pinf(k, q_prim_vf, 2, paux, cell, preterm1, term2, Romega) myR0 = bub_R0(k) @@ -658,8 +619,8 @@ contains pint = pint + 0.5_wp*myV**2._wp if (lag_params%cluster_type == 2) then bub_dphidt(k) = (paux - pint) + term2 - ! Accounting for the potential induced by the bubble averaged over the control volume - ! Note that this is based on the incompressible flow assumption near the bubble. + ! Accounting for the potential induced by the bubble averaged over the control volume Note that this is based on + ! the incompressible flow assumption near the bubble. term1_fac = 3._wp/2._wp*(myR*(Romega**2._wp - myR**2._wp))/(Romega**3._wp - myR**3._wp) bub_dphidt(k) = bub_dphidt(k)/(1._wp - term1_fac) end if @@ -678,8 +639,10 @@ contains call nvtxStartRange("LAGRANGE-BUBBLE-DYNAMICS") ! Radial motion model adap_dt_stop_sum = 0 - $:GPU_PARALLEL_LOOP(private='[k,myalpha_rho,myalpha,Re,cell,myVapFlux,preterm1, term2, paux, pint, Romega,term1_fac,myR_m, mygamma_m, myPb, myMass_n, myMass_v,myR, myV, myBeta_c, myBeta_t, myR0, myPbdot, myMvdot,myPinf, aux1,aux2, myCson, myRho,gamma,pi_inf,qv,dmalf, dmntait, dmBtait, dm_bub_adv_src, dm_divu,adap_dt_stop,myPos,myVel]', & - & copy='[adap_dt_stop_sum]',copyin='[stage]') + $:GPU_PARALLEL_LOOP(private='[k, myalpha_rho, myalpha, Re, cell, myVapFlux, preterm1, term2, paux, pint, Romega, & + & term1_fac, myR_m, mygamma_m, myPb, myMass_n, myMass_v, myR, myV, myBeta_c, myBeta_t, myR0, myPbdot, & + & myMvdot, myPinf, aux1, aux2, myCson, myRho, gamma, pi_inf, qv, dmalf, dmntait, dmBtait, & + & dm_bub_adv_src, dm_divu, adap_dt_stop, myPos, myVel]', copy='[adap_dt_stop_sum]',copyin='[stage]') do k = 1, n_el_bubs_loc ! Keller-Miksis model @@ -692,8 +655,8 @@ contains myBeta_c = gas_betaC(k) myBeta_t = gas_betaT(k) myR0 = bub_R0(k) - myPos = mtn_pos(k, :, 2) - myVel = mtn_vel(k, :, 2) + myPos = mtn_pos(k,:,2) + myVel = mtn_vel(k,:,2) ! Vapor and heat fluxes call s_vflux(myR, myV, myPb, myMass_v, k, myVapFlux, myMass_n, myBeta_c, myR_m, mygamma_m) @@ -705,38 +668,31 @@ contains ! Obtain liquid density and computing speed of sound from pinf call s_compute_species_fraction(q_prim_vf, cell(1), cell(2), cell(3), myalpha_rho, myalpha) - call s_convert_species_to_mixture_variables_acc(myRho, gamma, pi_inf, qv, myalpha, & - myalpha_rho, Re) + call s_convert_species_to_mixture_variables_acc(myRho, gamma, pi_inf, qv, myalpha, myalpha_rho, Re) call s_compute_cson_from_pinf(q_prim_vf, myPinf, cell, myRho, gamma, pi_inf, myCson) ! Adaptive time stepping adap_dt_stop = 0 if (adap_dt) then - - mtn_posPrev(k, :, 1) = myPos + mtn_posPrev(k,:,1) = myPos myRe = Re(1) - adap_dt_stop = f_advance_step(myRho, myPinf, myR, myV, myR0, myPb, myPbdot, dmalf, & - dmntait, dmBtait, dm_bub_adv_src, dm_divu, & - k, myMass_v, myMass_n, myBeta_c, & - myBeta_t, myCson, myRe, & - myPos, myVel, cell, q_prim_vf) + adap_dt_stop = f_advance_step(myRho, myPinf, myR, myV, myR0, myPb, myPbdot, dmalf, dmntait, dmBtait, & + & dm_bub_adv_src, dm_divu, k, myMass_v, myMass_n, myBeta_c, myBeta_t, myCson, myRe, & + & myPos, myVel, cell, q_prim_vf) ! Update bubble state intfc_rad(k, 1) = myR intfc_vel(k, 1) = myV gas_p(k, 1) = myPb gas_mv(k, 1) = myMass_v - mtn_pos(k, :, 1) = myPos - mtn_vel(k, :, 1) = myVel - + mtn_pos(k,:,1) = myPos + mtn_vel(k,:,1) = myVel else ! Radial acceleration from bubble models - intfc_dveldt(k, stage) = f_rddot(myRho, myPinf, myR, myV, myR0, & - myPb, myPbdot, dmalf, dmntait, dmBtait, & - dm_bub_adv_src, dm_divu, & - myCson) + intfc_dveldt(k, stage) = f_rddot(myRho, myPinf, myR, myV, myR0, myPb, myPbdot, dmalf, dmntait, dmBtait, & + & dm_bub_adv_src, dm_divu, myCson) intfc_draddt(k, stage) = myV gas_dmvdt(k, stage) = myMvdot @@ -746,22 +702,17 @@ contains do l = 1, num_dims select case (lag_vel_model) case (1) - mtn_dposdt(k, l, stage) = f_interpolate_velocity(myPos(l), & - cell, l, q_prim_vf) + mtn_dposdt(k, l, stage) = f_interpolate_velocity(myPos(l), cell, l, q_prim_vf) mtn_dveldt(k, l, stage) = 0._wp case (2) mtn_dposdt(k, l, stage) = myVel(l) - f_b = f_get_bubble_force(myPos(l), & - myR, myV, myVel(l), & - myMass_n, myMass_v, & - Re(1), myRho, cell, l, q_prim_vf) + f_b = f_get_bubble_force(myPos(l), myR, myV, myVel(l), myMass_n, myMass_v, Re(1), myRho, cell, l, & + & q_prim_vf) mtn_dveldt(k, l, stage) = f_b/(myMass_n + myMass_v) case (3) mtn_dposdt(k, l, stage) = myVel(l) - f_b = f_get_bubble_force(myPos(l), & - myR, myV, myVel(l), & - myMass_n, myMass_v, & - Re(1), myRho, cell, l, q_prim_vf) + f_b = f_get_bubble_force(myPos(l), myR, myV, myVel(l), myMass_n, myMass_v, Re(1), myRho, cell, l, & + & q_prim_vf) mtn_dveldt(k, l, stage) = 2._wp*f_b/(myMass_n + myMass_v) - 3._wp*myV*myVel(l)/myR case default mtn_dposdt(k, l, stage) = 0._wp @@ -773,7 +724,6 @@ contains $:GPU_ATOMIC(atomic='update') adap_dt_stop_sum = adap_dt_stop_sum + adap_dt_stop - end do $:END_GPU_PARALLEL_LOOP() call nvtxEndRange @@ -788,31 +738,29 @@ contains end subroutine s_compute_bubble_EL_dynamics - !> The purpose of this subroutine is to obtain the bubble source terms based on Maeda and Colonius (2018) - !! and add them to the RHS scalar field. - !! @param q_cons_vf Conservative variables - !! @param q_prim_vf Conservative variables - !! @param rhs_vf Time derivative of the conservative variables + !> The purpose of this subroutine is to obtain the bubble source terms based on Maeda and Colonius (2018) and add them to the + !! RHS scalar field. + !! @param q_cons_vf Conservative variables + !! @param q_prim_vf Conservative variables + !! @param rhs_vf Time derivative of the conservative variables subroutine s_compute_bubbles_EL_source(q_cons_vf, q_prim_vf, rhs_vf) type(scalar_field), dimension(sys_size), intent(inout) :: q_cons_vf type(scalar_field), dimension(sys_size), intent(inout) :: q_prim_vf type(scalar_field), dimension(sys_size), intent(inout) :: rhs_vf - - integer :: i, j, k, l + integer :: i, j, k, l call nvtxStartRange("LAGRANGE-BUBBLE-EL-SOURCE") ! (q / (1 - beta)) * d(beta)/dt source if (lag_params%cluster_type >= 4) then - $:GPU_PARALLEL_LOOP(private='[i,j,k,l]', collapse=4) + $:GPU_PARALLEL_LOOP(private='[i, j, k, l]', collapse=4) do k = idwint(3)%beg, idwint(3)%end do j = idwint(2)%beg, idwint(2)%end do i = idwint(1)%beg, idwint(1)%end do l = 1, E_idx if (q_beta(1)%sf(i, j, k) > (1._wp - lag_params%valmaxvoid)) then - rhs_vf(l)%sf(i, j, k) = rhs_vf(l)%sf(i, j, k) + & - q_cons_vf(l)%sf(i, j, k)*(q_beta(2)%sf(i, j, k) + & - q_beta(5)%sf(i, j, k)) + rhs_vf(l)%sf(i, j, k) = rhs_vf(l)%sf(i, j, k) + q_cons_vf(l)%sf(i, j, k)*(q_beta(2)%sf(i, j, & + & k) + q_beta(5)%sf(i, j, k)) end if end do end do @@ -820,15 +768,14 @@ contains end do $:END_GPU_PARALLEL_LOOP() else - $:GPU_PARALLEL_LOOP(private='[i,j,k,l]', collapse=4) + $:GPU_PARALLEL_LOOP(private='[i, j, k, l]', collapse=4) do k = idwint(3)%beg, idwint(3)%end do j = idwint(2)%beg, idwint(2)%end do i = idwint(1)%beg, idwint(1)%end do l = 1, E_idx if (q_beta(1)%sf(i, j, k) > (1._wp - lag_params%valmaxvoid)) then - rhs_vf(l)%sf(i, j, k) = rhs_vf(l)%sf(i, j, k) + & - (q_cons_vf(l)%sf(i, j, k)/q_beta(1)%sf(i, j, k))* & - q_beta(2)%sf(i, j, k) + rhs_vf(l)%sf(i, j, k) = rhs_vf(l)%sf(i, j, k) + (q_cons_vf(l)%sf(i, j, k)/q_beta(1)%sf(i, j, & + & k))*q_beta(2)%sf(i, j, k) end if end do end do @@ -838,27 +785,24 @@ contains end if do l = 1, num_dims - call s_gradient_dir(q_prim_vf(E_idx)%sf, q_beta(3)%sf, l) ! (q / (1 - beta)) * d(beta)/dt source - $:GPU_PARALLEL_LOOP(private='[i,j,k]', collapse=3) + $:GPU_PARALLEL_LOOP(private='[i, j, k]', collapse=3) do k = idwint(3)%beg, idwint(3)%end do j = idwint(2)%beg, idwint(2)%end do i = idwint(1)%beg, idwint(1)%end if (q_beta(1)%sf(i, j, k) > (1._wp - lag_params%valmaxvoid)) then - rhs_vf(contxe + l)%sf(i, j, k) = rhs_vf(contxe + l)%sf(i, j, k) - & - (1._wp - q_beta(1)%sf(i, j, k))/ & - q_beta(1)%sf(i, j, k)* & - q_beta(3)%sf(i, j, k) + rhs_vf(contxe + l)%sf(i, j, k) = rhs_vf(contxe + l)%sf(i, j, k) - (1._wp - q_beta(1)%sf(i, j, & + & k))/q_beta(1)%sf(i, j, k)*q_beta(3)%sf(i, j, k) end if end do end do end do $:END_GPU_PARALLEL_LOOP() - !source in energy - $:GPU_PARALLEL_LOOP(private='[i,j,k]', collapse=3) + ! source in energy + $:GPU_PARALLEL_LOOP(private='[i, j, k]', collapse=3) do k = idwbuff(3)%beg, idwbuff(3)%end do j = idwbuff(2)%beg, idwbuff(2)%end do i = idwbuff(1)%beg, idwbuff(1)%end @@ -871,42 +815,40 @@ contains call s_gradient_dir(q_beta(3)%sf, q_beta(4)%sf, l) ! (beta / (1 - beta)) * d(Pu)/dl source - $:GPU_PARALLEL_LOOP(private='[i,j,k]', collapse=3) + $:GPU_PARALLEL_LOOP(private='[i, j, k]', collapse=3) do k = idwint(3)%beg, idwint(3)%end do j = idwint(2)%beg, idwint(2)%end do i = idwint(1)%beg, idwint(1)%end if (q_beta(1)%sf(i, j, k) > (1._wp - lag_params%valmaxvoid)) then - rhs_vf(E_idx)%sf(i, j, k) = rhs_vf(E_idx)%sf(i, j, k) - & - q_beta(4)%sf(i, j, k)*(1._wp - q_beta(1)%sf(i, j, k))/ & - q_beta(1)%sf(i, j, k) + rhs_vf(E_idx)%sf(i, j, k) = rhs_vf(E_idx)%sf(i, j, k) - q_beta(4)%sf(i, j, & + & k)*(1._wp - q_beta(1)%sf(i, j, k))/q_beta(1)%sf(i, j, k) end if end do end do end do $:END_GPU_PARALLEL_LOOP() end do - call nvtxEndRange ! LAGRANGE-BUBBLE-EL-SOURCE + call nvtxEndRange ! LAGRANGE-BUBBLE-EL-SOURCE end subroutine s_compute_bubbles_EL_source - !> This procedure computes the speed of sound from a given driving pressure - !! @param q_prim_vf Primitive variables - !! @param pinf Driving pressure - !! @param cell Bubble cell - !! @param rhol Liquid density - !! @param gamma Liquid specific heat ratio - !! @param pi_inf Liquid stiffness - !! @param cson Calculated speed of sound + !> This procedure computes the speed of sound from a given driving pressure + !! @param q_prim_vf Primitive variables + !! @param pinf Driving pressure + !! @param cell Bubble cell + !! @param rhol Liquid density + !! @param gamma Liquid specific heat ratio + !! @param pi_inf Liquid stiffness + !! @param cson Calculated speed of sound subroutine s_compute_cson_from_pinf(q_prim_vf, pinf, cell, rhol, gamma, pi_inf, cson) - $:GPU_ROUTINE(function_name='s_compute_cson_from_pinf', & - & parallelism='[seq]', cray_inline=True) - type(scalar_field), dimension(sys_size), intent(in) :: q_prim_vf - real(wp), intent(in) :: pinf, rhol, gamma, pi_inf - integer, dimension(3), intent(in) :: cell - real(wp), intent(out) :: cson + $:GPU_ROUTINE(function_name='s_compute_cson_from_pinf', parallelism='[seq]', cray_inline=True) - real(wp) :: E, H + type(scalar_field), dimension(sys_size), intent(in) :: q_prim_vf + real(wp), intent(in) :: pinf, rhol, gamma, pi_inf + integer, dimension(3), intent(in) :: cell + real(wp), intent(out) :: cson + real(wp) :: E, H #:if not MFC_CASE_OPTIMIZATION and USING_AMD real(wp), dimension(3) :: vel #:else @@ -925,14 +867,14 @@ contains end subroutine s_compute_cson_from_pinf - !> The purpose of this subroutine is to smear the effect of the bubbles in the Eulerian framework + !> The purpose of this subroutine is to smear the effect of the bubbles in the Eulerian framework subroutine s_smear_voidfraction(bc_type) - type(integer_field), dimension(1:num_dims, 1:2), intent(in) :: bc_type - integer :: i, j, k, l + type(integer_field), dimension(1:num_dims,1:2), intent(in) :: bc_type + integer :: i, j, k, l call nvtxStartRange("BUBBLES-LAGRANGE-SMEARING") - $:GPU_PARALLEL_LOOP(private='[i,j,k,l]', collapse=4) + $:GPU_PARALLEL_LOOP(private='[i, j, k, l]', collapse=4) do i = 1, q_beta_idx do l = idwbuff(3)%beg, idwbuff(3)%end do k = idwbuff(2)%beg, idwbuff(2)%end @@ -948,8 +890,7 @@ contains ! Build cell list before smearing (CPU-side counting sort) call s_build_cell_list(n_el_bubs_loc, mtn_s) - call s_smoothfunction(n_el_bubs_loc, intfc_rad, intfc_vel, & - mtn_s, mtn_pos, q_beta, kahan_comp) + call s_smoothfunction(n_el_bubs_loc, intfc_rad, intfc_vel, mtn_s, mtn_pos, q_beta, kahan_comp) call nvtxStartRange("BUBBLES-LAGRANGE-BETA-COMM") if (lag_params%cluster_type >= 4) then @@ -959,59 +900,57 @@ contains end if call nvtxEndRange - !Store 1-beta - $:GPU_PARALLEL_LOOP(private='[j,k,l]', collapse=3) + ! Store 1-beta + $:GPU_PARALLEL_LOOP(private='[j, k, l]', collapse=3) do l = idwbuff(3)%beg, idwbuff(3)%end do k = idwbuff(2)%beg, idwbuff(2)%end do j = idwbuff(1)%beg, idwbuff(1)%end q_beta(1)%sf(j, k, l) = 1._wp - q_beta(1)%sf(j, k, l) ! Limiting void fraction given max value - q_beta(1)%sf(j, k, l) = max(q_beta(1)%sf(j, k, l), & - 1._wp - lag_params%valmaxvoid) + q_beta(1)%sf(j, k, l) = max(q_beta(1)%sf(j, k, l), 1._wp - lag_params%valmaxvoid) end do end do end do $:END_GPU_PARALLEL_LOOP() - call nvtxEndRange ! BUBBLES-LAGRANGE-SMEARING + call nvtxEndRange ! BUBBLES-LAGRANGE-SMEARING end subroutine s_smear_voidfraction !> The purpose of this procedure is obtain the bubble driving pressure p_inf - !! @param bub_id Particle identifier - !! @param q_prim_vf Primitive variables - !! @param ptype 1: p at infinity, 2: averaged P at the bubble location - !! @param f_pinfl Driving pressure - !! @param cell Bubble cell - !! @param preterm1 Pre-computed term 1 - !! @param term2 Computed term 2 - !! @param Romega Control volume radius + !! @param bub_id Particle identifier + !! @param q_prim_vf Primitive variables + !! @param ptype 1: p at infinity, 2: averaged P at the bubble location + !! @param f_pinfl Driving pressure + !! @param cell Bubble cell + !! @param preterm1 Pre-computed term 1 + !! @param term2 Computed term 2 + !! @param Romega Control volume radius subroutine s_get_pinf(bub_id, q_prim_vf, ptype, f_pinfl, cell, preterm1, term2, Romega) - $:GPU_ROUTINE(function_name='s_get_pinf',parallelism='[seq]', & - & cray_inline=True) - integer, intent(in) :: bub_id, ptype + $:GPU_ROUTINE(function_name='s_get_pinf',parallelism='[seq]', cray_inline=True) + + integer, intent(in) :: bub_id, ptype type(scalar_field), dimension(sys_size), intent(in) :: q_prim_vf - real(wp), intent(out) :: f_pinfl - integer, dimension(3), intent(out) :: cell - real(wp), intent(out), optional :: preterm1, term2, Romega - - real(wp), dimension(3) :: scoord, psi_pos, psi_x, psi_y, psi_z - real(wp) :: xi, eta, zeta - real(wp) :: dc, vol, aux - real(wp) :: volgas, term1, Rbeq, denom - real(wp) :: charvol, charpres, charvol2, charpres2 - integer, dimension(3) :: cellaux - integer :: i, j, k - integer :: smearGrid, smearGridz + real(wp), intent(out) :: f_pinfl + integer, dimension(3), intent(out) :: cell + real(wp), intent(out), optional :: preterm1, term2, Romega + real(wp), dimension(3) :: scoord, psi_pos, psi_x, psi_y, psi_z + real(wp) :: xi, eta, zeta + real(wp) :: dc, vol, aux + real(wp) :: volgas, term1, Rbeq, denom + real(wp) :: charvol, charpres, charvol2, charpres2 + integer, dimension(3) :: cellaux + integer :: i, j, k + integer :: smearGrid, smearGridz f_pinfl = 0._wp if (moving_lag_bubbles) then cell = fd_number - buff_size - call s_locate_cell(mtn_pos(bub_id, 1:3, 2), cell, mtn_s(bub_id, 1:3, 2)) - scoord = mtn_s(bub_id, 1:3, 2) + call s_locate_cell(mtn_pos(bub_id,1:3,2), cell, mtn_s(bub_id,1:3,2)) + scoord = mtn_s(bub_id,1:3,2) else - scoord = mtn_s(bub_id, 1:3, 2) + scoord = mtn_s(bub_id,1:3,2) cell(:) = int(scoord(:)) $:GPU_LOOP(parallelism='[seq]') do i = 1, num_dims @@ -1020,9 +959,9 @@ contains end if if ((lag_params%cluster_type == 1)) then - !< Getting p_cell in terms of only the current cell by interpolation + !> Getting p_cell in terms of only the current cell by interpolation - if (fd_order == 2) then ! Bilinear interpolation + if (fd_order == 2) then ! Bilinear interpolation if (p > 0) then vol = dx(cell(1))*dy(cell(2))*dz(cell(3)) @@ -1034,7 +973,7 @@ contains end if end if - !< Obtain bilinear interpolation coefficients, based on the current location of the bubble. + !> Obtain bilinear interpolation coefficients, based on the current location of the bubble. psi_pos(1) = (scoord(1) - real(cell(1)))*dx(cell(1)) + x_cb(cell(1) - 1) psi_pos(1) = abs((psi_pos(1) - x_cc(cell(1)))/(x_cc(cell(1) + 1) - x_cc(cell(1)))) @@ -1048,50 +987,46 @@ contains psi_pos(3) = 0._wp end if - ! Calculate bilinear basis functions for each direction - ! For normalized coordinate xi in [0, 1], the two basis functions are: - ! phi_0(xi) = 1 - xi, phi_1(xi) = xi + ! Calculate bilinear basis functions for each direction For normalized coordinate xi in [0, 1], the two basis + ! functions are: phi_0(xi) = 1 - xi, phi_1(xi) = xi ! X-direction basis functions psi_x(1) = 1._wp - psi_pos(1) ! Left basis function - psi_x(2) = psi_pos(1) ! Right basis function + psi_x(2) = psi_pos(1) ! Right basis function ! Y-direction basis functions psi_y(1) = 1._wp - psi_pos(2) ! Left basis function - psi_y(2) = psi_pos(2) ! Right basis function + psi_y(2) = psi_pos(2) ! Right basis function if (p > 0) then ! Z-direction basis functions psi_z(1) = 1._wp - psi_pos(3) ! Left basis function - psi_z(2) = psi_pos(3) ! Right basis function + psi_z(2) = psi_pos(3) ! Right basis function else psi_z(1) = 1._wp psi_z(2) = 0._wp end if - !< Perform bilinear interpolation + !> Perform bilinear interpolation f_pinfl = 0._wp - if (p == 0) then !2D - 4 point interpolation (2x2) + if (p == 0) then ! 2D - 4 point interpolation (2x2) do j = 1, 2 do i = 1, 2 - f_pinfl = f_pinfl + q_prim_vf(E_idx)%sf(cell(1) + i - 1, cell(2) + j - 1, cell(3))* & - psi_x(i)*psi_y(j) + f_pinfl = f_pinfl + q_prim_vf(E_idx)%sf(cell(1) + i - 1, cell(2) + j - 1, cell(3))*psi_x(i)*psi_y(j) end do end do - else !3D - 8 point interpolation (2x2x2) + else ! 3D - 8 point interpolation (2x2x2) do k = 1, 2 do j = 1, 2 do i = 1, 2 - f_pinfl = f_pinfl + q_prim_vf(E_idx)%sf(cell(1) + i - 1, cell(2) + j - 1, cell(3) + k - 1)* & - psi_x(i)*psi_y(j)*psi_z(k) + f_pinfl = f_pinfl + q_prim_vf(E_idx)%sf(cell(1) + i - 1, cell(2) + j - 1, & + & cell(3) + k - 1)*psi_x(i)*psi_y(j)*psi_z(k) end do end do end do end if - - elseif (fd_order == 4) then ! Biquadratic interpolation - + else if (fd_order == 4) then ! Biquadratic interpolation if (p > 0) then vol = dx(cell(1))*dy(cell(2))*dz(cell(3)) else @@ -1102,7 +1037,7 @@ contains end if end if - !< Obtain biquadratic interpolation coefficients, based on the current location of the bubble. + !> Obtain biquadratic interpolation coefficients, based on the current location of the bubble. ! For biquadratic interpolation, we need coefficients for 3 points in each direction psi_pos(1) = (scoord(1) - real(cell(1)))*dx(cell(1)) + x_cb(cell(1) - 1) psi_pos(1) = (psi_pos(1) - x_cc(cell(1)))/(x_cc(cell(1) + 1) - x_cc(cell(1))) @@ -1117,59 +1052,56 @@ contains psi_pos(3) = 0._wp end if - ! Calculate biquadratic basis functions for each direction - ! For normalized coordinate xi in [-1, 1], the three basis functions are: - ! phi_0(xi) = xi*(xi-1)/2, phi_1(xi) = (1-xi)*(1+xi), phi_2(xi) = xi*(xi+1)/2 + ! Calculate biquadratic basis functions for each direction For normalized coordinate xi in [-1, 1], the three basis + ! functions are: phi_0(xi) = xi*(xi-1)/2, phi_1(xi) = (1-xi)*(1+xi), phi_2(xi) = xi*(xi+1)/2 ! X-direction basis functions xi = 2._wp*psi_pos(1) - 1._wp ! Convert to [-1, 1] range - psi_x(1) = xi*(xi - 1._wp)/2._wp ! Left basis function - psi_x(2) = (1._wp - xi)*(1._wp + xi) ! Center basis function - psi_x(3) = xi*(xi + 1._wp)/2._wp ! Right basis function + psi_x(1) = xi*(xi - 1._wp)/2._wp ! Left basis function + psi_x(2) = (1._wp - xi)*(1._wp + xi) ! Center basis function + psi_x(3) = xi*(xi + 1._wp)/2._wp ! Right basis function ! Y-direction basis functions eta = 2._wp*psi_pos(2) - 1._wp ! Convert to [-1, 1] range - psi_y(1) = eta*(eta - 1._wp)/2._wp ! Left basis function + psi_y(1) = eta*(eta - 1._wp)/2._wp ! Left basis function psi_y(2) = (1._wp - eta)*(1._wp + eta) ! Center basis function - psi_y(3) = eta*(eta + 1._wp)/2._wp ! Right basis function + psi_y(3) = eta*(eta + 1._wp)/2._wp ! Right basis function if (p > 0) then ! Z-direction basis functions zeta = 2._wp*psi_pos(3) - 1._wp ! Convert to [-1, 1] range - psi_z(1) = zeta*(zeta - 1._wp)/2._wp ! Left basis function + psi_z(1) = zeta*(zeta - 1._wp)/2._wp ! Left basis function psi_z(2) = (1._wp - zeta)*(1._wp + zeta) ! Center basis function - psi_z(3) = zeta*(zeta + 1._wp)/2._wp ! Right basis function + psi_z(3) = zeta*(zeta + 1._wp)/2._wp ! Right basis function else psi_z(1) = 0._wp psi_z(2) = 1._wp psi_z(3) = 0._wp end if - !< Perform biquadratic interpolation + !> Perform biquadratic interpolation f_pinfl = 0._wp - if (p == 0) then !2D - 9 point interpolation (3x3) + if (p == 0) then ! 2D - 9 point interpolation (3x3) do j = 1, 3 do i = 1, 3 - f_pinfl = f_pinfl + q_prim_vf(E_idx)%sf(cell(1) + i - 2, cell(2) + j - 2, cell(3))* & - psi_x(i)*psi_y(j) + f_pinfl = f_pinfl + q_prim_vf(E_idx)%sf(cell(1) + i - 2, cell(2) + j - 2, cell(3))*psi_x(i)*psi_y(j) end do end do - else !3D - 27 point interpolation (3x3x3) + else ! 3D - 27 point interpolation (3x3x3) do k = 1, 3 do j = 1, 3 do i = 1, 3 - f_pinfl = f_pinfl + q_prim_vf(E_idx)%sf(cell(1) + i - 2, cell(2) + j - 2, cell(3) + k - 2)* & - psi_x(i)*psi_y(j)*psi_z(k) + f_pinfl = f_pinfl + q_prim_vf(E_idx)%sf(cell(1) + i - 2, cell(2) + j - 2, & + & cell(3) + k - 2)*psi_x(i)*psi_y(j)*psi_z(k) end do end do end do end if end if - !R_Omega + ! R_Omega dc = (3._wp*vol/(4._wp*pi))**(1._wp/3._wp) - else if (lag_params%cluster_type >= 2) then ! Bubble dynamic closure from Maeda and Colonius (2018) @@ -1195,7 +1127,7 @@ contains cellaux(3) = cell(3) + k - (mapCells + 1) if (p == 0) cellaux(3) = 0 - !< Obtaining the cell volume + !> Obtaining the cell volume if (p > 0) then vol = dx(cellaux(1))*dy(cellaux(2))*dz(cellaux(3)) else @@ -1205,71 +1137,67 @@ contains vol = dx(cellaux(1))*dy(cellaux(2))*lag_params%charwidth end if end if - !< Update values + !> Update values charvol = charvol + vol charpres = charpres + q_prim_vf(E_idx)%sf(cellaux(1), cellaux(2), cellaux(3))*vol charvol2 = charvol2 + vol*q_beta(1)%sf(cellaux(1), cellaux(2), cellaux(3)) - charpres2 = charpres2 + q_prim_vf(E_idx)%sf(cellaux(1), cellaux(2), cellaux(3)) & - *vol*q_beta(1)%sf(cellaux(1), cellaux(2), cellaux(3)) + charpres2 = charpres2 + q_prim_vf(E_idx)%sf(cellaux(1), cellaux(2), & + & cellaux(3))*vol*q_beta(1)%sf(cellaux(1), cellaux(2), cellaux(3)) end do end do end do f_pinfl = charpres2/charvol2 vol = charvol dc = (3._wp*abs(vol)/(4._wp*pi))**(1._wp/3._wp) - end if if (lag_params%pressure_corrector) then - - !Valid if only one bubble exists per cell + ! Valid if only one bubble exists per cell volgas = intfc_rad(bub_id, 2)**3._wp denom = intfc_rad(bub_id, 2)**2._wp term1 = bub_dphidt(bub_id)*intfc_rad(bub_id, 2)**2._wp term2 = intfc_vel(bub_id, 2)*intfc_rad(bub_id, 2)**2._wp - Rbeq = volgas**(1._wp/3._wp) !surrogate bubble radius + Rbeq = volgas**(1._wp/3._wp) ! surrogate bubble radius aux = dc**3._wp - Rbeq**3._wp term2 = term2/denom term2 = 3._wp/2._wp*term2**2._wp*Rbeq**3._wp*(1._wp - Rbeq/dc)/aux preterm1 = 3._wp/2._wp*Rbeq*(dc**2._wp - Rbeq**2._wp)/(aux*denom) - !Control volume radius + ! Control volume radius if (ptype == 2) Romega = dc ! Getting p_inf if (ptype == 1) then f_pinfl = f_pinfl + preterm1*term1 + term2 end if - end if end subroutine s_get_pinf - !> This subroutine updates the Lagrange variables using the tvd RK time steppers. - !! The time derivative of the bubble variables must be stored at every stage to avoid precision errors. - !! @param stage Current tvd RK stage + !> This subroutine updates the Lagrange variables using the tvd RK time steppers. The time derivative of the bubble variables + !! must be stored at every stage to avoid precision errors. + !! @param stage Current tvd RK stage impure subroutine s_update_lagrange_tdv_rk(q_prim_vf, bc_type, stage) - type(scalar_field), dimension(sys_size), intent(in) :: q_prim_vf - type(integer_field), dimension(1:num_dims, 1:2), intent(in) :: bc_type - integer, intent(in) :: stage + type(scalar_field), dimension(sys_size), intent(in) :: q_prim_vf + type(integer_field), dimension(1:num_dims,1:2), intent(in) :: bc_type + integer, intent(in) :: stage + integer :: k - integer :: k - - if (time_stepper == 1) then ! 1st order TVD RK + if (time_stepper == 1) then ! 1st order TVD RK $:GPU_PARALLEL_LOOP(private='[k]') do k = 1, n_el_bubs_loc - !u{1} = u{n} + dt * RHS{n} + ! u{1} = u{n} + dt * RHS{n} intfc_rad(k, 1) = intfc_rad(k, 1) + dt*intfc_draddt(k, 1) intfc_vel(k, 1) = intfc_vel(k, 1) + dt*intfc_dveldt(k, 1) gas_p(k, 1) = gas_p(k, 1) + dt*gas_dpdt(k, 1) gas_mv(k, 1) = gas_mv(k, 1) + dt*gas_dmvdt(k, 1) if (moving_lag_bubbles) then - mtn_posPrev(k, 1:3, 1) = mtn_pos(k, 1:3, 1) - mtn_pos(k, 1:3, 1) = mtn_pos(k, 1:3, 1) + dt*mtn_dposdt(k, 1:3, 1) - mtn_vel(k, 1:3, 1) = mtn_vel(k, 1:3, 1) + dt*mtn_dveldt(k, 1:3, 1) + mtn_posPrev(k,1:3,1) = mtn_pos(k,1:3,1) + mtn_pos(k,1:3,1) = mtn_pos(k,1:3,1) + dt*mtn_dposdt(k,1:3,1) + mtn_vel(k,1:3,1) = mtn_vel(k,1:3,1) + dt*mtn_dveldt(k,1:3,1) end if end do $:END_GPU_PARALLEL_LOOP() @@ -1280,44 +1208,40 @@ contains if (lag_params%write_void_evol) call s_write_void_evol(mytime) if (lag_params%write_bubbles_stats) call s_calculate_lag_bubble_stats() if (lag_params%write_bubbles) then - $:GPU_UPDATE(host='[gas_p,gas_mv,intfc_rad,intfc_vel]') + $:GPU_UPDATE(host='[gas_p, gas_mv, intfc_rad, intfc_vel]') call s_write_lag_bubble_evol(mytime) end if - - elseif (time_stepper == 2) then ! 2nd order TVD RK + else if (time_stepper == 2) then ! 2nd order TVD RK if (stage == 1) then - $:GPU_PARALLEL_LOOP(private='[k]') do k = 1, n_el_bubs_loc - !u{1} = u{n} + dt * RHS{n} + ! u{1} = u{n} + dt * RHS{n} intfc_rad(k, 2) = intfc_rad(k, 1) + dt*intfc_draddt(k, 1) intfc_vel(k, 2) = intfc_vel(k, 1) + dt*intfc_dveldt(k, 1) gas_p(k, 2) = gas_p(k, 1) + dt*gas_dpdt(k, 1) gas_mv(k, 2) = gas_mv(k, 1) + dt*gas_dmvdt(k, 1) if (moving_lag_bubbles) then - mtn_posPrev(k, 1:3, 2) = mtn_pos(k, 1:3, 1) - mtn_pos(k, 1:3, 2) = mtn_pos(k, 1:3, 1) + dt*mtn_dposdt(k, 1:3, 1) - mtn_vel(k, 1:3, 2) = mtn_vel(k, 1:3, 1) + dt*mtn_dveldt(k, 1:3, 1) + mtn_posPrev(k,1:3,2) = mtn_pos(k,1:3,1) + mtn_pos(k,1:3,2) = mtn_pos(k,1:3,1) + dt*mtn_dposdt(k,1:3,1) + mtn_vel(k,1:3,2) = mtn_vel(k,1:3,1) + dt*mtn_dveldt(k,1:3,1) end if end do $:END_GPU_PARALLEL_LOOP() if (moving_lag_bubbles) call s_enforce_EL_bubbles_boundary_conditions(q_prim_vf) call s_smear_voidfraction(bc_type) - - elseif (stage == 2) then - + else if (stage == 2) then $:GPU_PARALLEL_LOOP(private='[k]') do k = 1, n_el_bubs_loc - !u{1} = u{n} + (1/2) * dt * (RHS{n} + RHS{1}) + ! u{1} = u{n} + (1/2) * dt * (RHS{n} + RHS{1}) intfc_rad(k, 1) = intfc_rad(k, 1) + dt*(intfc_draddt(k, 1) + intfc_draddt(k, 2))/2._wp intfc_vel(k, 1) = intfc_vel(k, 1) + dt*(intfc_dveldt(k, 1) + intfc_dveldt(k, 2))/2._wp gas_p(k, 1) = gas_p(k, 1) + dt*(gas_dpdt(k, 1) + gas_dpdt(k, 2))/2._wp gas_mv(k, 1) = gas_mv(k, 1) + dt*(gas_dmvdt(k, 1) + gas_dmvdt(k, 2))/2._wp if (moving_lag_bubbles) then - mtn_posPrev(k, 1:3, 1) = mtn_pos(k, 1:3, 2) - mtn_pos(k, 1:3, 1) = mtn_pos(k, 1:3, 1) + dt*(mtn_dposdt(k, 1:3, 1) + mtn_dposdt(k, 1:3, 2))/2._wp - mtn_vel(k, 1:3, 1) = mtn_vel(k, 1:3, 1) + dt*(mtn_dveldt(k, 1:3, 1) + mtn_dveldt(k, 1:3, 2))/2._wp + mtn_posPrev(k,1:3,1) = mtn_pos(k,1:3,2) + mtn_pos(k,1:3,1) = mtn_pos(k,1:3,1) + dt*(mtn_dposdt(k,1:3,1) + mtn_dposdt(k,1:3,2))/2._wp + mtn_vel(k,1:3,1) = mtn_vel(k,1:3,1) + dt*(mtn_dveldt(k,1:3,1) + mtn_dveldt(k,1:3,2))/2._wp end if end do $:END_GPU_PARALLEL_LOOP() @@ -1328,66 +1252,63 @@ contains if (lag_params%write_void_evol) call s_write_void_evol(mytime) if (lag_params%write_bubbles_stats) call s_calculate_lag_bubble_stats() if (lag_params%write_bubbles) then - $:GPU_UPDATE(host='[gas_p,gas_mv,intfc_rad,intfc_vel]') + $:GPU_UPDATE(host='[gas_p, gas_mv, intfc_rad, intfc_vel]') call s_write_lag_bubble_evol(mytime) end if - end if - - elseif (time_stepper == 3) then ! 3rd order TVD RK + else if (time_stepper == 3) then ! 3rd order TVD RK if (stage == 1) then - $:GPU_PARALLEL_LOOP(private='[k]') do k = 1, n_el_bubs_loc - !u{1} = u{n} + dt * RHS{n} + ! u{1} = u{n} + dt * RHS{n} intfc_rad(k, 2) = intfc_rad(k, 1) + dt*intfc_draddt(k, 1) intfc_vel(k, 2) = intfc_vel(k, 1) + dt*intfc_dveldt(k, 1) gas_p(k, 2) = gas_p(k, 1) + dt*gas_dpdt(k, 1) gas_mv(k, 2) = gas_mv(k, 1) + dt*gas_dmvdt(k, 1) if (moving_lag_bubbles) then - mtn_posPrev(k, 1:3, 2) = mtn_pos(k, 1:3, 1) - mtn_pos(k, 1:3, 2) = mtn_pos(k, 1:3, 1) + dt*mtn_dposdt(k, 1:3, 1) - mtn_vel(k, 1:3, 2) = mtn_vel(k, 1:3, 1) + dt*mtn_dveldt(k, 1:3, 1) + mtn_posPrev(k,1:3,2) = mtn_pos(k,1:3,1) + mtn_pos(k,1:3,2) = mtn_pos(k,1:3,1) + dt*mtn_dposdt(k,1:3,1) + mtn_vel(k,1:3,2) = mtn_vel(k,1:3,1) + dt*mtn_dveldt(k,1:3,1) end if end do $:END_GPU_PARALLEL_LOOP() if (moving_lag_bubbles) call s_enforce_EL_bubbles_boundary_conditions(q_prim_vf) call s_smear_voidfraction(bc_type) - - elseif (stage == 2) then - + else if (stage == 2) then $:GPU_PARALLEL_LOOP(private='[k]') do k = 1, n_el_bubs_loc - !u{2} = u{n} + (1/4) * dt * [RHS{n} + RHS{1}] + ! u{2} = u{n} + (1/4) * dt * [RHS{n} + RHS{1}] intfc_rad(k, 2) = intfc_rad(k, 1) + dt*(intfc_draddt(k, 1) + intfc_draddt(k, 2))/4._wp intfc_vel(k, 2) = intfc_vel(k, 1) + dt*(intfc_dveldt(k, 1) + intfc_dveldt(k, 2))/4._wp gas_p(k, 2) = gas_p(k, 1) + dt*(gas_dpdt(k, 1) + gas_dpdt(k, 2))/4._wp gas_mv(k, 2) = gas_mv(k, 1) + dt*(gas_dmvdt(k, 1) + gas_dmvdt(k, 2))/4._wp if (moving_lag_bubbles) then - mtn_posPrev(k, 1:3, 2) = mtn_pos(k, 1:3, 2) - mtn_pos(k, 1:3, 2) = mtn_pos(k, 1:3, 1) + dt*(mtn_dposdt(k, 1:3, 1) + mtn_dposdt(k, 1:3, 2))/4._wp - mtn_vel(k, 1:3, 2) = mtn_vel(k, 1:3, 1) + dt*(mtn_dveldt(k, 1:3, 1) + mtn_dveldt(k, 1:3, 2))/4._wp + mtn_posPrev(k,1:3,2) = mtn_pos(k,1:3,2) + mtn_pos(k,1:3,2) = mtn_pos(k,1:3,1) + dt*(mtn_dposdt(k,1:3,1) + mtn_dposdt(k,1:3,2))/4._wp + mtn_vel(k,1:3,2) = mtn_vel(k,1:3,1) + dt*(mtn_dveldt(k,1:3,1) + mtn_dveldt(k,1:3,2))/4._wp end if end do $:END_GPU_PARALLEL_LOOP() if (moving_lag_bubbles) call s_enforce_EL_bubbles_boundary_conditions(q_prim_vf) call s_smear_voidfraction(bc_type) - - elseif (stage == 3) then - + else if (stage == 3) then $:GPU_PARALLEL_LOOP(private='[k]') do k = 1, n_el_bubs_loc - !u{n+1} = u{n} + (2/3) * dt * [(1/4)* RHS{n} + (1/4)* RHS{1} + RHS{2}] - intfc_rad(k, 1) = intfc_rad(k, 1) + (2._wp/3._wp)*dt*(intfc_draddt(k, 1)/4._wp + intfc_draddt(k, 2)/4._wp + intfc_draddt(k, 3)) - intfc_vel(k, 1) = intfc_vel(k, 1) + (2._wp/3._wp)*dt*(intfc_dveldt(k, 1)/4._wp + intfc_dveldt(k, 2)/4._wp + intfc_dveldt(k, 3)) + ! u{n+1} = u{n} + (2/3) * dt * [(1/4)* RHS{n} + (1/4)* RHS{1} + RHS{2}] + intfc_rad(k, 1) = intfc_rad(k, 1) + (2._wp/3._wp)*dt*(intfc_draddt(k, 1)/4._wp + intfc_draddt(k, & + & 2)/4._wp + intfc_draddt(k, 3)) + intfc_vel(k, 1) = intfc_vel(k, 1) + (2._wp/3._wp)*dt*(intfc_dveldt(k, 1)/4._wp + intfc_dveldt(k, & + & 2)/4._wp + intfc_dveldt(k, 3)) gas_p(k, 1) = gas_p(k, 1) + (2._wp/3._wp)*dt*(gas_dpdt(k, 1)/4._wp + gas_dpdt(k, 2)/4._wp + gas_dpdt(k, 3)) gas_mv(k, 1) = gas_mv(k, 1) + (2._wp/3._wp)*dt*(gas_dmvdt(k, 1)/4._wp + gas_dmvdt(k, 2)/4._wp + gas_dmvdt(k, 3)) if (moving_lag_bubbles) then - mtn_posPrev(k, 1:3, 1) = mtn_pos(k, 1:3, 2) - mtn_pos(k, 1:3, 1) = mtn_pos(k, 1:3, 1) + (2._wp/3._wp)*dt*(mtn_dposdt(k, 1:3, 1)/4._wp + mtn_dposdt(k, 1:3, 2)/4._wp + mtn_dposdt(k, 1:3, 3)) - mtn_vel(k, 1:3, 1) = mtn_vel(k, 1:3, 1) + (2._wp/3._wp)*dt*(mtn_dveldt(k, 1:3, 1)/4._wp + mtn_dveldt(k, 1:3, 2)/4._wp + mtn_dveldt(k, 1:3, 3)) + mtn_posPrev(k,1:3,1) = mtn_pos(k,1:3,2) + mtn_pos(k,1:3,1) = mtn_pos(k,1:3,1) + (2._wp/3._wp)*dt*(mtn_dposdt(k,1:3,1)/4._wp + mtn_dposdt(k,1:3, & + & 2)/4._wp + mtn_dposdt(k,1:3,3)) + mtn_vel(k,1:3,1) = mtn_vel(k,1:3,1) + (2._wp/3._wp)*dt*(mtn_dveldt(k,1:3,1)/4._wp + mtn_dveldt(k,1:3, & + & 2)/4._wp + mtn_dveldt(k,1:3,3)) end if end do $:END_GPU_PARALLEL_LOOP() @@ -1398,124 +1319,116 @@ contains if (lag_params%write_void_evol) call s_write_void_evol(mytime) if (lag_params%write_bubbles_stats) call s_calculate_lag_bubble_stats() if (lag_params%write_bubbles) then - $:GPU_UPDATE(host='[gas_p,gas_mv,gas_mg,intfc_rad,intfc_vel]') + $:GPU_UPDATE(host='[gas_p, gas_mv, gas_mg, intfc_rad, intfc_vel]') call s_write_lag_bubble_evol(mytime) end if - end if - end if end subroutine s_update_lagrange_tdv_rk !> This subroutine enforces reflective and wall boundary conditions for EL bubbles - !! @param dest Destination for the bubble position update + !! @param dest Destination for the bubble position update impure subroutine s_enforce_EL_bubbles_boundary_conditions(q_prim_vf) type(scalar_field), dimension(sys_size), intent(in) :: q_prim_vf - integer :: k, i, q - integer :: patch_id, newBubs, new_idx - real(wp) :: offset - integer, dimension(3) :: cell + integer :: k, i, q + integer :: patch_id, newBubs, new_idx + real(wp) :: offset + integer, dimension(3) :: cell call nvtxStartRange("LAG-BC") call nvtxStartRange("LAG-BC-DEV2HOST") - $:GPU_UPDATE(host='[bub_R0, Rmax_stats, Rmin_stats, gas_mg, gas_betaT, & - & gas_betaC, bub_dphidt, lag_id, gas_p, gas_mv, intfc_rad, intfc_vel, & - & mtn_pos, mtn_posPrev, mtn_vel, mtn_s, intfc_draddt, intfc_dveldt, & - & gas_dpdt, gas_dmvdt, mtn_dposdt, mtn_dveldt, keep_bubble, n_el_bubs_loc, & - & wrap_bubble_dir, wrap_bubble_loc]') + $:GPU_UPDATE(host='[bub_R0, Rmax_stats, Rmin_stats, gas_mg, gas_betaT, gas_betaC, bub_dphidt, lag_id, gas_p, gas_mv, & + & intfc_rad, intfc_vel, mtn_pos, mtn_posPrev, mtn_vel, mtn_s, intfc_draddt, intfc_dveldt, gas_dpdt, & + & gas_dmvdt, mtn_dposdt, mtn_dveldt, keep_bubble, n_el_bubs_loc, wrap_bubble_dir, wrap_bubble_loc]') call nvtxEndRange ! Handle MPI transfer of bubbles going to another processor's local domain if (num_procs > 1) then call nvtxStartRange("LAG-BC-TRANSFER-LIST") - call s_add_particles_to_transfer_list(n_el_bubs_loc, mtn_pos(:, :, 2), mtn_posPrev(:, :, 2)) + call s_add_particles_to_transfer_list(n_el_bubs_loc, mtn_pos(:,:,2), mtn_posPrev(:,:,2)) call nvtxEndRange call nvtxStartRange("LAG-BC-SENDRECV") - call s_mpi_sendrecv_particles(bub_R0, Rmax_stats, Rmin_stats, gas_mg, gas_betaT, & - gas_betaC, bub_dphidt, lag_id, gas_p, gas_mv, & - intfc_rad, intfc_vel, mtn_pos, mtn_posPrev, mtn_vel, & - mtn_s, intfc_draddt, intfc_dveldt, gas_dpdt, & - gas_dmvdt, mtn_dposdt, mtn_dveldt, lag_num_ts, n_el_bubs_loc, & - 2) + call s_mpi_sendrecv_particles(bub_R0, Rmax_stats, Rmin_stats, gas_mg, gas_betaT, gas_betaC, bub_dphidt, lag_id, & + & gas_p, gas_mv, intfc_rad, intfc_vel, mtn_pos, mtn_posPrev, mtn_vel, mtn_s, & + & intfc_draddt, intfc_dveldt, gas_dpdt, gas_dmvdt, mtn_dposdt, mtn_dveldt, lag_num_ts, & + & n_el_bubs_loc, 2) call nvtxEndRange end if call nvtxStartRange("LAG-BC-HOST2DEV") - $:GPU_UPDATE(device='[bub_R0, Rmax_stats, Rmin_stats, gas_mg, gas_betaT, & - & gas_betaC, bub_dphidt, lag_id, gas_p, gas_mv, intfc_rad, intfc_vel, & - & mtn_pos, mtn_posPrev, mtn_vel, mtn_s, intfc_draddt, intfc_dveldt, & - & gas_dpdt, gas_dmvdt, mtn_dposdt, mtn_dveldt, n_el_bubs_loc]') + $:GPU_UPDATE(device='[bub_R0, Rmax_stats, Rmin_stats, gas_mg, gas_betaT, gas_betaC, bub_dphidt, lag_id, gas_p, gas_mv, & + & intfc_rad, intfc_vel, mtn_pos, mtn_posPrev, mtn_vel, mtn_s, intfc_draddt, intfc_dveldt, gas_dpdt, & + & gas_dmvdt, mtn_dposdt, mtn_dveldt, n_el_bubs_loc]') call nvtxEndRange $:GPU_PARALLEL_LOOP(private='[k, cell]') do k = 1, n_el_bubs_loc keep_bubble(k) = 1 - wrap_bubble_loc(k, :) = 0 - wrap_bubble_dir(k, :) = 0 + wrap_bubble_loc(k,:) = 0 + wrap_bubble_dir(k,:) = 0 - ! Relocate bubbles at solid boundaries and delete bubbles that leave - ! buffer regions - if (any(bc_x%beg == (/BC_REFLECTIVE, BC_CHAR_SLIP_WALL, BC_SLIP_WALL, BC_NO_SLIP_WALL/)) & - .and. mtn_pos(k, 1, 2) < x_cb(-1) + intfc_rad(k, 2)) then + ! Relocate bubbles at solid boundaries and delete bubbles that leave buffer regions + if (any(bc_x%beg == (/BC_REFLECTIVE, BC_CHAR_SLIP_WALL, BC_SLIP_WALL, BC_NO_SLIP_WALL/)) .and. mtn_pos(k, 1, & + & 2) < x_cb(-1) + intfc_rad(k, 2)) then mtn_pos(k, 1, 2) = x_cb(-1) + intfc_rad(k, 2) - elseif (any(bc_x%end == (/BC_REFLECTIVE, BC_CHAR_SLIP_WALL, BC_SLIP_WALL, BC_NO_SLIP_WALL/)) & - .and. mtn_pos(k, 1, 2) > x_cb(m) - intfc_rad(k, 2)) then + else if (any(bc_x%end == (/BC_REFLECTIVE, BC_CHAR_SLIP_WALL, BC_SLIP_WALL, BC_NO_SLIP_WALL/)) .and. mtn_pos(k, 1, & + & 2) > x_cb(m) - intfc_rad(k, 2)) then mtn_pos(k, 1, 2) = x_cb(m) - intfc_rad(k, 2) - elseif (bc_x%beg == BC_PERIODIC .and. mtn_pos(k, 1, 2) < pcomm_coords(1)%beg .and. & - mtn_posPrev(k, 1, 2) >= pcomm_coords(1)%beg) then + else if (bc_x%beg == BC_PERIODIC .and. mtn_pos(k, 1, 2) < pcomm_coords(1)%beg .and. mtn_posPrev(k, 1, & + & 2) >= pcomm_coords(1)%beg) then wrap_bubble_dir(k, 1) = 1 wrap_bubble_loc(k, 1) = -1 - elseif (bc_x%end == BC_PERIODIC .and. mtn_pos(k, 1, 2) > pcomm_coords(1)%end .and. & - mtn_posPrev(k, 1, 2) <= pcomm_coords(1)%end) then + else if (bc_x%end == BC_PERIODIC .and. mtn_pos(k, 1, 2) > pcomm_coords(1)%end .and. mtn_posPrev(k, 1, & + & 2) <= pcomm_coords(1)%end) then wrap_bubble_dir(k, 1) = 1 wrap_bubble_loc(k, 1) = 1 - elseif (mtn_pos(k, 1, 2) >= x_cb(m)) then + else if (mtn_pos(k, 1, 2) >= x_cb(m)) then keep_bubble(k) = 0 - elseif (mtn_pos(k, 1, 2) < x_cb(-1)) then + else if (mtn_pos(k, 1, 2) < x_cb(-1)) then keep_bubble(k) = 0 end if - if (any(bc_y%beg == (/BC_REFLECTIVE, BC_CHAR_SLIP_WALL, BC_SLIP_WALL, BC_NO_SLIP_WALL/)) & - .and. mtn_pos(k, 2, 2) < y_cb(-1) + intfc_rad(k, 2)) then + if (any(bc_y%beg == (/BC_REFLECTIVE, BC_CHAR_SLIP_WALL, BC_SLIP_WALL, BC_NO_SLIP_WALL/)) .and. mtn_pos(k, 2, & + & 2) < y_cb(-1) + intfc_rad(k, 2)) then mtn_pos(k, 2, 2) = y_cb(-1) + intfc_rad(k, 2) - else if (any(bc_y%end == (/BC_REFLECTIVE, BC_CHAR_SLIP_WALL, BC_SLIP_WALL, BC_NO_SLIP_WALL/)) & - .and. mtn_pos(k, 2, 2) > y_cb(n) - intfc_rad(k, 2)) then + else if (any(bc_y%end == (/BC_REFLECTIVE, BC_CHAR_SLIP_WALL, BC_SLIP_WALL, BC_NO_SLIP_WALL/)) .and. mtn_pos(k, 2, & + & 2) > y_cb(n) - intfc_rad(k, 2)) then mtn_pos(k, 2, 2) = y_cb(n) - intfc_rad(k, 2) - elseif (bc_y%beg == BC_PERIODIC .and. mtn_pos(k, 2, 2) < pcomm_coords(2)%beg .and. & - mtn_posPrev(k, 2, 2) >= pcomm_coords(2)%beg) then + else if (bc_y%beg == BC_PERIODIC .and. mtn_pos(k, 2, 2) < pcomm_coords(2)%beg .and. mtn_posPrev(k, 2, & + & 2) >= pcomm_coords(2)%beg) then wrap_bubble_dir(k, 2) = 1 wrap_bubble_loc(k, 2) = -1 - elseif (bc_y%end == BC_PERIODIC .and. mtn_pos(k, 2, 2) > pcomm_coords(2)%end .and. & - mtn_posPrev(k, 2, 2) <= pcomm_coords(2)%end) then + else if (bc_y%end == BC_PERIODIC .and. mtn_pos(k, 2, 2) > pcomm_coords(2)%end .and. mtn_posPrev(k, 2, & + & 2) <= pcomm_coords(2)%end) then wrap_bubble_dir(k, 2) = 1 wrap_bubble_loc(k, 2) = 1 - elseif (mtn_pos(k, 2, 2) >= y_cb(n)) then + else if (mtn_pos(k, 2, 2) >= y_cb(n)) then keep_bubble(k) = 0 - elseif (mtn_pos(k, 2, 2) < y_cb(-1)) then + else if (mtn_pos(k, 2, 2) < y_cb(-1)) then keep_bubble(k) = 0 end if if (p > 0) then - if (any(bc_z%beg == (/BC_REFLECTIVE, BC_CHAR_SLIP_WALL, BC_SLIP_WALL, BC_NO_SLIP_WALL/)) & - .and. mtn_pos(k, 3, 2) < z_cb(-1) + intfc_rad(k, 2)) then + if (any(bc_z%beg == (/BC_REFLECTIVE, BC_CHAR_SLIP_WALL, BC_SLIP_WALL, BC_NO_SLIP_WALL/)) .and. mtn_pos(k, 3, & + & 2) < z_cb(-1) + intfc_rad(k, 2)) then mtn_pos(k, 3, 2) = z_cb(-1) + intfc_rad(k, 2) - else if (any(bc_z%end == (/BC_REFLECTIVE, BC_CHAR_SLIP_WALL, BC_SLIP_WALL, BC_NO_SLIP_WALL/)) & - .and. mtn_pos(k, 3, 2) > z_cb(p) - intfc_rad(k, 2)) then + else if (any(bc_z%end == (/BC_REFLECTIVE, BC_CHAR_SLIP_WALL, BC_SLIP_WALL, BC_NO_SLIP_WALL/)) .and. mtn_pos(k, 3, & + & 2) > z_cb(p) - intfc_rad(k, 2)) then mtn_pos(k, 3, 2) = z_cb(p) - intfc_rad(k, 2) - elseif (bc_z%beg == BC_PERIODIC .and. mtn_pos(k, 3, 2) < pcomm_coords(3)%beg .and. & - mtn_posPrev(k, 3, 2) >= pcomm_coords(3)%beg) then + else if (bc_z%beg == BC_PERIODIC .and. mtn_pos(k, 3, 2) < pcomm_coords(3)%beg .and. mtn_posPrev(k, 3, & + & 2) >= pcomm_coords(3)%beg) then wrap_bubble_dir(k, 3) = 1 wrap_bubble_loc(k, 3) = -1 - elseif (bc_z%end == BC_PERIODIC .and. mtn_pos(k, 3, 2) > pcomm_coords(3)%end .and. & - mtn_posPrev(k, 3, 2) <= pcomm_coords(3)%end) then + else if (bc_z%end == BC_PERIODIC .and. mtn_pos(k, 3, 2) > pcomm_coords(3)%end .and. mtn_posPrev(k, 3, & + & 2) <= pcomm_coords(3)%end) then wrap_bubble_dir(k, 3) = 1 wrap_bubble_loc(k, 3) = 1 - elseif (mtn_pos(k, 3, 2) >= z_cb(p)) then + else if (mtn_pos(k, 3, 2) >= z_cb(p)) then keep_bubble(k) = 0 - elseif (mtn_pos(k, 3, 2) < z_cb(-1)) then + else if (mtn_pos(k, 3, 2) < z_cb(-1)) then keep_bubble(k) = 0 end if end if @@ -1523,7 +1436,7 @@ contains if (keep_bubble(k) == 1) then ! Remove bubbles that are no longer in a liquid cell = fd_number - buff_size - call s_locate_cell(mtn_pos(k, 1:3, 2), cell, mtn_s(k, 1:3, 2)) + call s_locate_cell(mtn_pos(k,1:3,2), cell, mtn_s(k,1:3,2)) if (q_prim_vf(advxb)%sf(cell(1), cell(2), cell(3)) < (1._wp - lag_params%valmaxvoid)) then keep_bubble(k) = 0 @@ -1534,11 +1447,9 @@ contains if (n_el_bubs_loc > 0) then call nvtxStartRange("LAG-BC-DEV2HOST") - $:GPU_UPDATE(host='[bub_R0, Rmax_stats, Rmin_stats, gas_mg, gas_betaT, & - & gas_betaC, bub_dphidt, lag_id, gas_p, gas_mv, intfc_rad, intfc_vel, & - & mtn_pos, mtn_posPrev, mtn_vel, mtn_s, intfc_draddt, intfc_dveldt, & - & gas_dpdt, gas_dmvdt, mtn_dposdt, mtn_dveldt, keep_bubble, n_el_bubs_loc, & - & wrap_bubble_dir, wrap_bubble_loc]') + $:GPU_UPDATE(host='[bub_R0, Rmax_stats, Rmin_stats, gas_mg, gas_betaT, gas_betaC, bub_dphidt, lag_id, gas_p, gas_mv, & + & intfc_rad, intfc_vel, mtn_pos, mtn_posPrev, mtn_vel, mtn_s, intfc_draddt, intfc_dveldt, gas_dpdt, & + & gas_dmvdt, mtn_dposdt, mtn_dveldt, keep_bubble, n_el_bubs_loc, wrap_bubble_dir, wrap_bubble_loc]') call nvtxEndRange newBubs = 0 @@ -1547,8 +1458,8 @@ contains newBubs = newBubs + 1 if (newBubs /= k) then call s_copy_lag_bubble(newBubs, k) - wrap_bubble_dir(newBubs, :) = wrap_bubble_dir(k, :) - wrap_bubble_loc(newBubs, :) = wrap_bubble_loc(k, :) + wrap_bubble_dir(newBubs,:) = wrap_bubble_dir(k,:) + wrap_bubble_loc(newBubs,:) = wrap_bubble_loc(k,:) end if end if end do @@ -1556,7 +1467,7 @@ contains ! Handle periodic wrapping of bubbles on same processor do k = 1, n_el_bubs_loc - if (any(wrap_bubble_dir(k, :) == 1)) then + if (any(wrap_bubble_dir(k,:) == 1)) then do i = 1, num_dims if (wrap_bubble_dir(k, i) == 1) then offset = glb_bounds(i)%end - glb_bounds(i)%beg @@ -1576,38 +1487,35 @@ contains end if end do call nvtxStartRange("LAG-BC-HOST2DEV") - $:GPU_UPDATE(device='[bub_R0, Rmax_stats, Rmin_stats, gas_mg, gas_betaT, & - & gas_betaC, bub_dphidt, lag_id, gas_p, gas_mv, intfc_rad, intfc_vel, & - & mtn_pos, mtn_posPrev, mtn_vel, mtn_s, intfc_draddt, intfc_dveldt, & - & gas_dpdt, gas_dmvdt, mtn_dposdt, mtn_dveldt, n_el_bubs_loc]') + $:GPU_UPDATE(device='[bub_R0, Rmax_stats, Rmin_stats, gas_mg, gas_betaT, gas_betaC, bub_dphidt, lag_id, gas_p, & + & gas_mv, intfc_rad, intfc_vel, mtn_pos, mtn_posPrev, mtn_vel, mtn_s, intfc_draddt, intfc_dveldt, & + & gas_dpdt, gas_dmvdt, mtn_dposdt, mtn_dveldt, n_el_bubs_loc]') call nvtxEndRange - end if $:GPU_PARALLEL_LOOP(private='[cell]') do k = 1, n_el_bubs_loc cell = fd_number - buff_size - call s_locate_cell(mtn_pos(k, 1:3, 2), cell, mtn_s(k, 1:3, 2)) + call s_locate_cell(mtn_pos(k,1:3,2), cell, mtn_s(k,1:3,2)) end do $:END_GPU_PARALLEL_LOOP() - call nvtxEndRange ! LAG-BC + call nvtxEndRange ! LAG-BC end subroutine s_enforce_EL_bubbles_boundary_conditions !> This subroutine returns the computational coordinate of the cell for the given position. - !! @param pos Input coordinates - !! @param cell Computational coordinate of the cell - !! @param scoord Calculated particle coordinates + !! @param pos Input coordinates + !! @param cell Computational coordinate of the cell + !! @param scoord Calculated particle coordinates subroutine s_locate_cell(pos, cell, scoord) - $:GPU_ROUTINE(function_name='s_locate_cell',parallelism='[seq]', & - & cray_inline=True) - real(wp), dimension(3), intent(in) :: pos - real(wp), dimension(3), intent(out) :: scoord - integer, dimension(3), intent(inout) :: cell + $:GPU_ROUTINE(function_name='s_locate_cell',parallelism='[seq]', cray_inline=True) - integer :: i + real(wp), dimension(3), intent(in) :: pos + real(wp), dimension(3), intent(out) :: scoord + integer, dimension(3), intent(inout) :: cell + integer :: i do while (pos(1) < x_cb(cell(1) - 1)) cell(1) = cell(1) - 1 @@ -1634,13 +1542,11 @@ contains end do end if - ! The numbering of the cell of which left boundary is the domain boundary is 0. - ! if comp.coord of the pos is s, the real coordinate of s is - ! (the coordinate of the left boundary of the Floor(s)-th cell) - ! + (s-(int(s))*(cell-width). - ! In other words, the coordinate of the center of the cell is x_cc(cell). + ! The numbering of the cell of which left boundary is the domain boundary is 0. if comp.coord of the pos is s, the real + ! coordinate of s is (the coordinate of the left boundary of the Floor(s)-th cell) + (s-(int(s))*(cell-width). In other + ! words, the coordinate of the center of the cell is x_cc(cell). - !coordinates in computational space + ! coordinates in computational space scoord(1) = cell(1) + (pos(1) - x_cb(cell(1) - 1))/dx(cell(1)) scoord(2) = cell(2) + (pos(2) - y_cb(cell(2) - 1))/dy(cell(2)) scoord(3) = 0._wp @@ -1663,48 +1569,44 @@ contains gas_mv(k, 2) = gas_mv(k, 1) intfc_rad(k, 2) = intfc_rad(k, 1) intfc_vel(k, 2) = intfc_vel(k, 1) - mtn_pos(k, 1:3, 2) = mtn_pos(k, 1:3, 1) - mtn_posPrev(k, 1:3, 2) = mtn_posPrev(k, 1:3, 1) - mtn_vel(k, 1:3, 2) = mtn_vel(k, 1:3, 1) - mtn_s(k, 1:3, 2) = mtn_s(k, 1:3, 1) + mtn_pos(k,1:3,2) = mtn_pos(k,1:3,1) + mtn_posPrev(k,1:3,2) = mtn_posPrev(k,1:3,1) + mtn_vel(k,1:3,2) = mtn_vel(k,1:3,1) + mtn_s(k,1:3,2) = mtn_s(k,1:3,1) end do $:END_GPU_PARALLEL_LOOP() end subroutine s_transfer_data_to_tmp - !> The purpose of this procedure is to determine if the global coordinates of the bubbles - !! are present in the current MPI processor (including ghost cells). - !! @param pos_part Spatial coordinates of the bubble + !> The purpose of this procedure is to determine if the global coordinates of the bubbles are present in the current MPI + !! processor (including ghost cells). + !! @param pos_part Spatial coordinates of the bubble function particle_in_domain(pos_part) - logical :: particle_in_domain + logical :: particle_in_domain real(wp), dimension(3), intent(in) :: pos_part ! 2D + if (p == 0 .and. cyl_coord .neqv. .true.) then - ! Defining a virtual z-axis that has the same dimensions as y-axis - ! defined in the input file - particle_in_domain = ((pos_part(1) < x_cb(m + buff_size - fd_number)) .and. & - (pos_part(1) >= x_cb(fd_number - buff_size - 1)) .and. & - (pos_part(2) < y_cb(n + buff_size - fd_number)) .and. & - (pos_part(2) >= y_cb(fd_number - buff_size - 1)) .and. & - (pos_part(3) < lag_params%charwidth/2._wp) .and. (pos_part(3) > -lag_params%charwidth/2._wp)) + ! Defining a virtual z-axis that has the same dimensions as y-axis defined in the input file + particle_in_domain = ((pos_part(1) < x_cb(m + buff_size - fd_number)) .and. (pos_part(1) >= x_cb(fd_number & + & - buff_size - 1)) .and. (pos_part(2) < y_cb(n + buff_size - fd_number)) .and. (pos_part(2) & + & >= y_cb(fd_number - buff_size - 1)) .and. (pos_part(3) < lag_params%charwidth/2._wp) & + & .and. (pos_part(3) > -lag_params%charwidth/2._wp)) else ! cyl_coord - particle_in_domain = ((pos_part(1) < x_cb(m + buff_size - fd_number)) .and. & - (pos_part(1) >= x_cb(fd_number - buff_size - 1)) .and. & - (abs(pos_part(2)) < y_cb(n + buff_size - fd_number)) .and. & - (abs(pos_part(2)) >= max(y_cb(fd_number - buff_size - 1), 0._wp))) + particle_in_domain = ((pos_part(1) < x_cb(m + buff_size - fd_number)) .and. (pos_part(1) >= x_cb(fd_number & + & - buff_size - 1)) .and. (abs(pos_part(2)) < y_cb(n + buff_size - fd_number)) & + & .and. (abs(pos_part(2)) >= max(y_cb(fd_number - buff_size - 1), 0._wp))) end if ! 3D if (p > 0) then - particle_in_domain = ((pos_part(1) < x_cb(m + buff_size - fd_number)) .and. & - (pos_part(1) >= x_cb(fd_number - buff_size - 1)) .and. & - (pos_part(2) < y_cb(n + buff_size - fd_number)) .and. & - (pos_part(2) >= y_cb(fd_number - buff_size - 1)) .and. & - (pos_part(3) < z_cb(p + buff_size - fd_number)) .and. & - (pos_part(3) >= z_cb(fd_number - buff_size - 1))) + particle_in_domain = ((pos_part(1) < x_cb(m + buff_size - fd_number)) .and. (pos_part(1) >= x_cb(fd_number & + & - buff_size - 1)) .and. (pos_part(2) < y_cb(n + buff_size - fd_number)) .and. (pos_part(2) & + & >= y_cb(fd_number - buff_size - 1)) .and. (pos_part(3) < z_cb(p + buff_size - fd_number)) & + & .and. (pos_part(3) >= z_cb(fd_number - buff_size - 1))) end if ! For symmetric and wall boundary condition @@ -1731,76 +1633,70 @@ contains end function particle_in_domain - !> The purpose of this procedure is to determine if the lagrangian bubble is located in the - !! physical domain. The ghost cells are not part of the physical domain. - !! @param pos_part Spatial coordinates of the bubble + !> The purpose of this procedure is to determine if the lagrangian bubble is located in the physical domain. The ghost cells are + !! not part of the physical domain. + !! @param pos_part Spatial coordinates of the bubble function particle_in_domain_physical(pos_part) - logical :: particle_in_domain_physical + logical :: particle_in_domain_physical real(wp), dimension(3), intent(in) :: pos_part - particle_in_domain_physical = ((pos_part(1) < x_cb(m)) .and. (pos_part(1) >= x_cb(-1)) .and. & - (pos_part(2) < y_cb(n)) .and. (pos_part(2) >= y_cb(-1))) + particle_in_domain_physical = ((pos_part(1) < x_cb(m)) .and. (pos_part(1) >= x_cb(-1)) .and. (pos_part(2) < y_cb(n)) & + & .and. (pos_part(2) >= y_cb(-1))) if (p > 0) then - particle_in_domain_physical = (particle_in_domain_physical .and. (pos_part(3) < z_cb(p)) .and. (pos_part(3) >= z_cb(-1))) + particle_in_domain_physical = (particle_in_domain_physical .and. (pos_part(3) < z_cb(p)) .and. (pos_part(3) & + & >= z_cb(-1))) end if end function particle_in_domain_physical - !> The purpose of this procedure is to calculate the gradient of a scalar field along the x, y and z directions - !! following a second-order central difference considering uneven widths - !! @param q Input scalar field - !! @param dq Output gradient of q - !! @param dir Gradient spatial direction + !> The purpose of this procedure is to calculate the gradient of a scalar field along the x, y and z directions following a + !! second-order central difference considering uneven widths + !! @param q Input scalar field + !! @param dq Output gradient of q + !! @param dir Gradient spatial direction subroutine s_gradient_dir(q, dq, dir) - real(stp), dimension(idwbuff(1)%beg:, idwbuff(2)%beg:, idwbuff(3)%beg:), intent(inout) :: q, dq - integer, intent(in) :: dir - - integer :: i, j, k + real(stp), dimension(idwbuff(1)%beg:,idwbuff(2)%beg:,idwbuff(3)%beg:), intent(inout) :: q, dq + integer, intent(in) :: dir + integer :: i, j, k if (dir == 1) then ! Gradient in x dir. - $:GPU_PARALLEL_LOOP(private='[i,j,k]', collapse=3) + $:GPU_PARALLEL_LOOP(private='[i, j, k]', collapse=3) do k = 0, p do j = 0, n do i = 0, m - dq(i, j, k) = q(i, j, k)*(dx(i + 1) - dx(i - 1)) & - + q(i + 1, j, k)*(dx(i) + dx(i - 1)) & - - q(i - 1, j, k)*(dx(i) + dx(i + 1)) - dq(i, j, k) = dq(i, j, k)/ & - ((dx(i) + dx(i - 1))*(dx(i) + dx(i + 1))) + dq(i, j, k) = q(i, j, k)*(dx(i + 1) - dx(i - 1)) + q(i + 1, j, k)*(dx(i) + dx(i - 1)) - q(i - 1, j, & + & k)*(dx(i) + dx(i + 1)) + dq(i, j, k) = dq(i, j, k)/((dx(i) + dx(i - 1))*(dx(i) + dx(i + 1))) end do end do end do $:END_GPU_PARALLEL_LOOP() - elseif (dir == 2) then + else if (dir == 2) then ! Gradient in y dir. - $:GPU_PARALLEL_LOOP(private='[i,j,k]', collapse=3) + $:GPU_PARALLEL_LOOP(private='[i, j, k]', collapse=3) do k = 0, p do j = 0, n do i = 0, m - dq(i, j, k) = q(i, j, k)*(dy(j + 1) - dy(j - 1)) & - + q(i, j + 1, k)*(dy(j) + dy(j - 1)) & - - q(i, j - 1, k)*(dy(j) + dy(j + 1)) - dq(i, j, k) = dq(i, j, k)/ & - ((dy(j) + dy(j - 1))*(dy(j) + dy(j + 1))) + dq(i, j, k) = q(i, j, k)*(dy(j + 1) - dy(j - 1)) + q(i, j + 1, k)*(dy(j) + dy(j - 1)) - q(i, j - 1, & + & k)*(dy(j) + dy(j + 1)) + dq(i, j, k) = dq(i, j, k)/((dy(j) + dy(j - 1))*(dy(j) + dy(j + 1))) end do end do end do $:END_GPU_PARALLEL_LOOP() - elseif (dir == 3) then + else if (dir == 3) then ! Gradient in z dir. - $:GPU_PARALLEL_LOOP(private='[i,j,k]', collapse=3) + $:GPU_PARALLEL_LOOP(private='[i, j, k]', collapse=3) do k = 0, p do j = 0, n do i = 0, m - dq(i, j, k) = q(i, j, k)*(dz(k + 1) - dz(k - 1)) & - + q(i, j, k + 1)*(dz(k) + dz(k - 1)) & - - q(i, j, k - 1)*(dz(k) + dz(k + 1)) - dq(i, j, k) = dq(i, j, k)/ & - ((dz(k) + dz(k - 1))*(dz(k) + dz(k + 1))) + dq(i, j, k) = q(i, j, k)*(dz(k + 1) - dz(k - 1)) + q(i, j, k + 1)*(dz(k) + dz(k - 1)) - q(i, j, & + & k - 1)*(dz(k) + dz(k + 1)) + dq(i, j, k) = dq(i, j, k)/((dz(k) + dz(k - 1))*(dz(k) + dz(k + 1))) end do end do end do @@ -1810,18 +1706,17 @@ contains end subroutine s_gradient_dir !> Subroutine that writes on each time step the changes of the lagrangian bubbles. - !! @param qtime Current time + !! @param qtime Current time impure subroutine s_write_lag_particles(qtime) - real(wp), intent(in) :: qtime - integer :: k - + real(wp), intent(in) :: qtime + integer :: k character(LEN=path_len + 2*name_len) :: file_loc - logical :: file_exist - character(LEN=25) :: FMT + logical :: file_exist + character(LEN=25) :: FMT write (file_loc, '(A,I0,A)') 'lag_bubble_evol_', proc_rank, '.dat' - file_loc = trim(case_dir)//'/D/'//trim(file_loc) + file_loc = trim(case_dir) // '/D/' // trim(file_loc) call my_inquire(trim(file_loc), file_exist) if (precision == 1) then @@ -1831,12 +1726,11 @@ contains end if if (.not. file_exist) then - open (LAG_EVOL_ID, FILE=trim(file_loc), FORM='formatted', position='rewind') - write (LAG_EVOL_ID, FMT) 'currentTime', 'particleID', 'x', 'y', 'z', & - 'coreVaporMass', 'coreVaporConcentration', 'radius', 'interfaceVelocity', & - 'corePressure' + open (LAG_EVOL_ID, FILE=trim(file_loc), form='formatted', position='rewind') + write (LAG_EVOL_ID, FMT) 'currentTime', 'particleID', 'x', 'y', 'z', 'coreVaporMass', 'coreVaporConcentration', & + & 'radius', 'interfaceVelocity', 'corePressure' else - open (LAG_EVOL_ID, FILE=trim(file_loc), FORM='formatted', position='append') + open (LAG_EVOL_ID, FILE=trim(file_loc), form='formatted', position='append') end if end subroutine s_write_lag_particles @@ -1845,11 +1739,11 @@ contains impure subroutine s_open_lag_bubble_evol() character(LEN=path_len + 2*name_len) :: file_loc - logical :: file_exist - character(LEN=25) :: FMT + logical :: file_exist + character(LEN=25) :: FMT write (file_loc, '(A,I0,A)') 'lag_bubble_evol_', proc_rank, '.dat' - file_loc = trim(case_dir)//'/D/'//trim(file_loc) + file_loc = trim(case_dir) // '/D/' // trim(file_loc) call my_inquire(trim(file_loc), file_exist) if (precision == 1) then @@ -1859,26 +1753,24 @@ contains end if if (.not. file_exist) then - open (LAG_EVOL_ID, FILE=trim(file_loc), FORM='formatted', position='rewind') - write (LAG_EVOL_ID, FMT) 'currentTime', 'particleID', 'x', 'y', 'z', & - 'coreVaporMass', 'coreVaporConcentration', 'radius', 'interfaceVelocity', & - 'corePressure' + open (LAG_EVOL_ID, FILE=trim(file_loc), form='formatted', position='rewind') + write (LAG_EVOL_ID, FMT) 'currentTime', 'particleID', 'x', 'y', 'z', 'coreVaporMass', 'coreVaporConcentration', & + & 'radius', 'interfaceVelocity', 'corePressure' else - open (LAG_EVOL_ID, FILE=trim(file_loc), FORM='formatted', position='append') + open (LAG_EVOL_ID, FILE=trim(file_loc), form='formatted', position='append') end if end subroutine s_open_lag_bubble_evol !> Subroutine that writes on each time step the changes of the lagrangian bubbles. - !! @param q_time Current time + !! @param q_time Current time impure subroutine s_write_lag_bubble_evol(qtime) - real(wp), intent(in) :: qtime - integer :: k, ios - character(LEN=25) :: FMT - + real(wp), intent(in) :: qtime + integer :: k, ios + character(LEN=25) :: FMT character(LEN=path_len + 2*name_len) :: file_loc, path - logical :: file_exist + logical :: file_exist if (precision == 1) then FMT = "(F16.8,I14,8F16.8)" @@ -1888,17 +1780,8 @@ contains ! Cycle through list do k = 1, n_el_bubs_loc - write (LAG_EVOL_ID, FMT) & - qtime, & - lag_id(k, 1), & - mtn_pos(k, 1, 1), & - mtn_pos(k, 2, 1), & - mtn_pos(k, 3, 1), & - gas_mv(k, 1), & - gas_mv(k, 1)/(gas_mv(k, 1) + gas_mg(k)), & - intfc_rad(k, 1), & - intfc_vel(k, 1), & - gas_p(k, 1) + write (LAG_EVOL_ID, FMT) qtime, lag_id(k, 1), mtn_pos(k, 1, 1), mtn_pos(k, 2, 1), mtn_pos(k, 3, 1), gas_mv(k, 1), & + & gas_mv(k, 1)/(gas_mv(k, 1) + gas_mg(k)), intfc_rad(k, 1), intfc_vel(k, 1), gas_p(k, 1) end do end subroutine s_write_lag_bubble_evol @@ -1912,46 +1795,42 @@ contains subroutine s_open_void_evol character(LEN=path_len + 2*name_len) :: file_loc - logical :: file_exist + logical :: file_exist if (proc_rank == 0) then write (file_loc, '(A)') 'voidfraction.dat' - file_loc = trim(case_dir)//'/D/'//trim(file_loc) + file_loc = trim(case_dir) // '/D/' // trim(file_loc) call my_inquire(trim(file_loc), file_exist) if (.not. file_exist) then - open (LAG_VOID_ID, FILE=trim(file_loc), FORM='formatted', position='rewind') - !write (12, *) 'currentTime, averageVoidFraction, ', & - ! 'maximumVoidFraction, totalParticlesVolume' - !write (12, *) 'The averageVoidFraction value does ', & - ! 'not reflect the real void fraction in the cloud since the ', & - ! 'cells which do not have bubbles are not accounted' + open (LAG_VOID_ID, FILE=trim(file_loc), form='formatted', position='rewind') + ! write (12, *) 'currentTime, averageVoidFraction, ', & 'maximumVoidFraction, totalParticlesVolume' write (12, *) + ! 'The averageVoidFraction value does ', & 'not reflect the real void fraction in the cloud since the ', & 'cells + ! which do not have bubbles are not accounted' else - open (LAG_VOID_ID, FILE=trim(file_loc), FORM='formatted', position='append') + open (LAG_VOID_ID, FILE=trim(file_loc), form='formatted', position='append') end if end if end subroutine s_open_void_evol - !> Subroutine that writes some useful statistics related to the volume fraction - !! of the particles (void fraction) in the computational domain - !! on each time step. - !! @param qtime Current time + !> Subroutine that writes some useful statistics related to the volume fraction of the particles (void fraction) in the + !! computational domain on each time step. + !! @param qtime Current time impure subroutine s_write_void_evol(qtime) - real(wp), intent(in) :: qtime - real(wp) :: volcell, voltot - real(wp) :: lag_void_max, lag_void_avg, lag_vol - real(wp) :: void_max_glb, void_avg_glb, vol_glb - - integer :: i, j, k - + real(wp), intent(in) :: qtime + real(wp) :: volcell, voltot + real(wp) :: lag_void_max, lag_void_avg, lag_vol + real(wp) :: void_max_glb, void_avg_glb, vol_glb + integer :: i, j, k character(LEN=path_len + 2*name_len) :: file_loc - logical :: file_exist + logical :: file_exist lag_void_max = 0._wp lag_void_avg = 0._wp lag_vol = 0._wp - $:GPU_PARALLEL_LOOP(private='[volcell]', collapse=3, reduction='[[lag_vol, lag_void_avg], [lag_void_max]]', reductionOp='[+, MAX]', copy='[lag_vol, lag_void_avg, lag_void_max]') + $:GPU_PARALLEL_LOOP(private='[volcell]', collapse=3, reduction='[[lag_vol, lag_void_avg], [lag_void_max]]', & + & reductionOp='[+, MAX]', copy='[lag_vol, lag_void_avg, lag_void_max]') do k = 0, p do j = 0, n do i = 0, m @@ -1977,16 +1856,12 @@ contains end if #endif voltot = lag_void_avg - ! This voidavg value does not reflect the real void fraction in the cloud - ! since the cell which does not have bubbles are not accounted + ! This voidavg value does not reflect the real void fraction in the cloud since the cell which does not have bubbles are not + ! accounted if (lag_vol > 0._wp) lag_void_avg = lag_void_avg/lag_vol if (proc_rank == 0) then - write (LAG_VOID_ID, '(6X,4e24.8)') & - qtime, & - lag_void_avg, & - lag_void_max, & - voltot + write (LAG_VOID_ID, '(6X,4e24.8)') qtime, lag_void_avg, lag_void_max, voltot end if end subroutine s_write_void_evol @@ -1997,33 +1872,32 @@ contains end subroutine s_close_void_evol - !> Subroutine that writes the restarting files for the particles in the lagrangian solver. - !! @param t_step Current time step + !> Subroutine that writes the restarting files for the particles in the lagrangian solver. + !! @param t_step Current time step impure subroutine s_write_restart_lag_bubbles(t_step) ! Generic string used to store the address of a particular file - integer, intent(in) :: t_step - + integer, intent(in) :: t_step character(LEN=path_len + 2*name_len) :: file_loc - logical :: file_exist - integer :: bub_id, tot_part - integer :: i, k + logical :: file_exist + integer :: bub_id, tot_part + integer :: i, k #ifdef MFC_MPI ! For Parallel I/O - integer :: ifile, ierr - integer, dimension(MPI_STATUS_SIZE) :: status - integer(KIND=MPI_OFFSET_KIND) :: disp - integer :: view - integer, dimension(2) :: gsizes, lsizes, start_idx_part - integer, allocatable :: proc_bubble_counts(:) - real(wp), dimension(1:1, 1:lag_io_vars) :: dummy + integer :: ifile, ierr + integer, dimension(MPI_STATUS_SIZE) :: status + integer(KIND=MPI_OFFSET_KIND) :: disp + integer :: view + integer, dimension(2) :: gsizes, lsizes, start_idx_part + integer, allocatable :: proc_bubble_counts(:) + real(wp), dimension(1:1,1:lag_io_vars) :: dummy dummy = 0._wp bub_id = 0._wp if (n_el_bubs_loc /= 0) then do k = 1, n_el_bubs_loc - if (particle_in_domain_physical(mtn_pos(k, 1:3, 1))) then + if (particle_in_domain_physical(mtn_pos(k,1:3,1))) then bub_id = bub_id + 1 end if end do @@ -2037,11 +1911,9 @@ contains lsizes(2) = lag_io_vars ! Total number of particles - call MPI_ALLREDUCE(bub_id, tot_part, 1, MPI_integer, & - MPI_SUM, MPI_COMM_WORLD, ierr) + call MPI_ALLREDUCE(bub_id, tot_part, 1, MPI_integer, MPI_SUM, MPI_COMM_WORLD, ierr) - call MPI_ALLGATHER(bub_id, 1, MPI_INTEGER, proc_bubble_counts, 1, MPI_INTEGER, & - MPI_COMM_WORLD, ierr) + call MPI_ALLGATHER(bub_id, 1, MPI_INTEGER, proc_bubble_counts, 1, MPI_INTEGER, MPI_COMM_WORLD, ierr) ! Calculate starting index for this processor's particles call MPI_EXSCAN(lsizes(1), start_idx_part(1), 1, MPI_INTEGER, MPI_SUM, MPI_COMM_WORLD, ierr) @@ -2052,7 +1924,7 @@ contains gsizes(2) = lag_io_vars write (file_loc, '(A,I0,A)') 'lag_bubbles_', t_step, '.dat' - file_loc = trim(case_dir)//'/restart_data'//trim(mpiiofs)//trim(file_loc) + file_loc = trim(case_dir) // '/restart_data' // trim(mpiiofs) // trim(file_loc) ! Clean up existing file if (proc_rank == 0) then @@ -2065,9 +1937,7 @@ contains call MPI_BARRIER(MPI_COMM_WORLD, ierr) if (proc_rank == 0) then - call MPI_FILE_OPEN(MPI_COMM_SELF, file_loc, & - ior(MPI_MODE_WRONLY, MPI_MODE_CREATE), & - mpi_info_int, ifile, ierr) + call MPI_FILE_OPEN(MPI_COMM_SELF, file_loc, ior(MPI_MODE_WRONLY, MPI_MODE_CREATE), mpi_info_int, ifile, ierr) ! Write header using MPI I/O for consistency call MPI_FILE_WRITE(ifile, tot_part, 1, MPI_INTEGER, status, ierr) @@ -2082,16 +1952,16 @@ contains call MPI_BARRIER(MPI_COMM_WORLD, ierr) if (bub_id > 0) then - allocate (MPI_IO_DATA_lag_bubbles(max(1, bub_id), 1:lag_io_vars)) + allocate (MPI_IO_DATA_lag_bubbles(max(1, bub_id),1:lag_io_vars)) i = 0 do k = 1, n_el_bubs_loc - if (.not. particle_in_domain_physical(mtn_pos(k, 1:3, 1))) cycle + if (.not. particle_in_domain_physical(mtn_pos(k,1:3,1))) cycle i = i + 1 MPI_IO_DATA_lag_bubbles(i, 1) = real(lag_id(k, 1)) - MPI_IO_DATA_lag_bubbles(i, 2:4) = mtn_pos(k, 1:3, 1) - MPI_IO_DATA_lag_bubbles(i, 5:7) = mtn_posPrev(k, 1:3, 1) - MPI_IO_DATA_lag_bubbles(i, 8:10) = mtn_vel(k, 1:3, 1) + MPI_IO_DATA_lag_bubbles(i,2:4) = mtn_pos(k,1:3,1) + MPI_IO_DATA_lag_bubbles(i,5:7) = mtn_posPrev(k,1:3,1) + MPI_IO_DATA_lag_bubbles(i,8:10) = mtn_vel(k,1:3,1) MPI_IO_DATA_lag_bubbles(i, 11) = intfc_rad(k, 1) MPI_IO_DATA_lag_bubbles(i, 12) = intfc_vel(k, 1) MPI_IO_DATA_lag_bubbles(i, 13) = bub_R0(k) @@ -2105,37 +1975,30 @@ contains MPI_IO_DATA_lag_bubbles(i, 21) = gas_betaC(k) end do - call MPI_TYPE_CREATE_SUBARRAY(2, gsizes, lsizes, start_idx_part, & - MPI_ORDER_FORTRAN, mpi_p, view, ierr) + call MPI_TYPE_CREATE_SUBARRAY(2, gsizes, lsizes, start_idx_part, MPI_ORDER_FORTRAN, mpi_p, view, ierr) call MPI_TYPE_COMMIT(view, ierr) - call MPI_FILE_OPEN(MPI_COMM_WORLD, file_loc, & - ior(MPI_MODE_WRONLY, MPI_MODE_CREATE), & - mpi_info_int, ifile, ierr) + call MPI_FILE_OPEN(MPI_COMM_WORLD, file_loc, ior(MPI_MODE_WRONLY, MPI_MODE_CREATE), mpi_info_int, ifile, ierr) ! Skip header (written by rank 0) - disp = int(sizeof(tot_part) + 2*sizeof(mytime) + sizeof(num_procs) + & - num_procs*sizeof(proc_bubble_counts(1)), MPI_OFFSET_KIND) + disp = int(sizeof(tot_part) + 2*sizeof(mytime) + sizeof(num_procs) + num_procs*sizeof(proc_bubble_counts(1)), & + & MPI_OFFSET_KIND) call MPI_FILE_SET_VIEW(ifile, disp, mpi_p, view, 'native', mpi_info_int, ierr) - call MPI_FILE_WRITE_ALL(ifile, MPI_IO_DATA_lag_bubbles, & - lag_io_vars*bub_id, mpi_p, status, ierr) + call MPI_FILE_WRITE_ALL(ifile, MPI_IO_DATA_lag_bubbles, lag_io_vars*bub_id, mpi_p, status, ierr) call MPI_FILE_CLOSE(ifile, ierr) deallocate (MPI_IO_DATA_lag_bubbles) - else call MPI_TYPE_CONTIGUOUS(0, mpi_p, view, ierr) call MPI_TYPE_COMMIT(view, ierr) - call MPI_FILE_OPEN(MPI_COMM_WORLD, file_loc, & - ior(MPI_MODE_WRONLY, MPI_MODE_CREATE), & - mpi_info_int, ifile, ierr) + call MPI_FILE_OPEN(MPI_COMM_WORLD, file_loc, ior(MPI_MODE_WRONLY, MPI_MODE_CREATE), mpi_info_int, ifile, ierr) ! Skip header (written by rank 0) - disp = int(sizeof(tot_part) + 2*sizeof(mytime) + sizeof(num_procs) + & - num_procs*sizeof(proc_bubble_counts(1)), MPI_OFFSET_KIND) + disp = int(sizeof(tot_part) + 2*sizeof(mytime) + sizeof(num_procs) + num_procs*sizeof(proc_bubble_counts(1)), & + & MPI_OFFSET_KIND) call MPI_FILE_SET_VIEW(ifile, disp, mpi_p, view, 'native', mpi_info_int, ierr) call MPI_FILE_WRITE_ALL(ifile, dummy, 0, mpi_p, status, ierr) @@ -2144,18 +2007,17 @@ contains end if deallocate (proc_bubble_counts) - #endif end subroutine s_write_restart_lag_bubbles - !> This procedure calculates the maximum and minimum radius of each bubble. + !> This procedure calculates the maximum and minimum radius of each bubble. subroutine s_calculate_lag_bubble_stats() integer :: k - $:GPU_PARALLEL_LOOP(private='[k]', reduction='[[Rmax_glb], [Rmin_glb]]', & - & reductionOp='[MAX, MIN]', copy='[Rmax_glb,Rmin_glb]') + $:GPU_PARALLEL_LOOP(private='[k]', reduction='[[Rmax_glb], [Rmin_glb]]', reductionOp='[MAX, MIN]', & + & copy='[Rmax_glb, Rmin_glb]') do k = 1, n_el_bubs_loc Rmax_glb = max(Rmax_glb, intfc_rad(k, 1)/bub_R0(k)) Rmin_glb = min(Rmin_glb, intfc_rad(k, 1)/bub_R0(k)) @@ -2169,11 +2031,11 @@ contains impure subroutine s_open_lag_bubble_stats() character(LEN=path_len + 2*name_len) :: file_loc - character(LEN=20) :: FMT - logical :: file_exist + character(LEN=20) :: FMT + logical :: file_exist write (file_loc, '(A,I0,A)') 'stats_lag_bubbles_', proc_rank, '.dat' - file_loc = trim(case_dir)//'/D/'//trim(file_loc) + file_loc = trim(case_dir) // '/D/' // trim(file_loc) call my_inquire(trim(file_loc), file_exist) if (precision == 1) then @@ -2183,22 +2045,22 @@ contains end if if (.not. file_exist) then - open (LAG_STATS_ID, FILE=trim(file_loc), FORM='formatted', position='rewind') + open (LAG_STATS_ID, FILE=trim(file_loc), form='formatted', position='rewind') write (LAG_STATS_ID, *) 'proc_rank, particleID, x, y, z, Rmax_glb, Rmin_glb' else - open (LAG_STATS_ID, FILE=trim(file_loc), FORM='formatted', position='append') + open (LAG_STATS_ID, FILE=trim(file_loc), form='formatted', position='append') end if end subroutine s_open_lag_bubble_stats - !> Subroutine that writes the maximum and minimum radius of each bubble. + !> Subroutine that writes the maximum and minimum radius of each bubble. impure subroutine s_write_lag_bubble_stats() - integer :: k + integer :: k character(LEN=path_len + 2*name_len) :: file_loc - character(LEN=20) :: FMT + character(LEN=20) :: FMT - $:GPU_UPDATE(host='[Rmax_glb,Rmin_glb]') + $:GPU_UPDATE(host='[Rmax_glb, Rmin_glb]') if (precision == 1) then FMT = "(I10,I14,5F16.8)" @@ -2207,14 +2069,8 @@ contains end if do k = 1, n_el_bubs_loc - write (LAG_STATS_ID, FMT) & - proc_rank, & - lag_id(k, 1), & - mtn_pos(k, 1, 1), & - mtn_pos(k, 2, 1), & - mtn_pos(k, 3, 1), & - Rmax_stats(k), & - Rmin_stats(k) + write (LAG_STATS_ID, FMT) proc_rank, lag_id(k, 1), mtn_pos(k, 1, 1), mtn_pos(k, 2, 1), mtn_pos(k, 3, 1), & + & Rmax_stats(k), Rmin_stats(k) end do end subroutine s_write_lag_bubble_stats @@ -2226,7 +2082,7 @@ contains end subroutine s_close_lag_bubble_stats !> The purpose of this subroutine is to remove one specific particle if dt is too small. - !! @param bub_id Particle id + !! @param bub_id Particle id impure subroutine s_copy_lag_bubble(dest, src) integer, intent(in) :: src, dest @@ -2239,20 +2095,20 @@ contains gas_betaC(dest) = gas_betaC(src) bub_dphidt(dest) = bub_dphidt(src) lag_id(dest, 1) = lag_id(src, 1) - gas_p(dest, 1:2) = gas_p(src, 1:2) - gas_mv(dest, 1:2) = gas_mv(src, 1:2) - intfc_rad(dest, 1:2) = intfc_rad(src, 1:2) - intfc_vel(dest, 1:2) = intfc_vel(src, 1:2) - mtn_vel(dest, 1:3, 1:2) = mtn_vel(src, 1:3, 1:2) - mtn_s(dest, 1:3, 1:2) = mtn_s(src, 1:3, 1:2) - mtn_pos(dest, 1:3, 1:2) = mtn_pos(src, 1:3, 1:2) - mtn_posPrev(dest, 1:3, 1:2) = mtn_posPrev(src, 1:3, 1:2) - intfc_draddt(dest, 1:lag_num_ts) = intfc_draddt(src, 1:lag_num_ts) - intfc_dveldt(dest, 1:lag_num_ts) = intfc_dveldt(src, 1:lag_num_ts) - gas_dpdt(dest, 1:lag_num_ts) = gas_dpdt(src, 1:lag_num_ts) - gas_dmvdt(dest, 1:lag_num_ts) = gas_dmvdt(src, 1:lag_num_ts) - mtn_dposdt(dest, 1:3, 1:lag_num_ts) = mtn_dposdt(src, 1:3, 1:lag_num_ts) - mtn_dveldt(dest, 1:3, 1:lag_num_ts) = mtn_dveldt(src, 1:3, 1:lag_num_ts) + gas_p(dest,1:2) = gas_p(src,1:2) + gas_mv(dest,1:2) = gas_mv(src,1:2) + intfc_rad(dest,1:2) = intfc_rad(src,1:2) + intfc_vel(dest,1:2) = intfc_vel(src,1:2) + mtn_vel(dest,1:3,1:2) = mtn_vel(src,1:3,1:2) + mtn_s(dest,1:3,1:2) = mtn_s(src,1:3,1:2) + mtn_pos(dest,1:3,1:2) = mtn_pos(src,1:3,1:2) + mtn_posPrev(dest,1:3,1:2) = mtn_posPrev(src,1:3,1:2) + intfc_draddt(dest,1:lag_num_ts) = intfc_draddt(src,1:lag_num_ts) + intfc_dveldt(dest,1:lag_num_ts) = intfc_dveldt(src,1:lag_num_ts) + gas_dpdt(dest,1:lag_num_ts) = gas_dpdt(src,1:lag_num_ts) + gas_dmvdt(dest,1:lag_num_ts) = gas_dmvdt(src,1:lag_num_ts) + mtn_dposdt(dest,1:3,1:lag_num_ts) = mtn_dposdt(src,1:3,1:lag_num_ts) + mtn_dveldt(dest,1:3,1:lag_num_ts) = mtn_dveldt(src,1:3,1:lag_num_ts) end subroutine s_copy_lag_bubble @@ -2272,7 +2128,7 @@ contains @:DEALLOCATE(q_beta) @:DEALLOCATE(kahan_comp) - !Deallocating space + ! Deallocating space @:DEALLOCATE(lag_id) @:DEALLOCATE(bub_R0) @:DEALLOCATE(Rmax_stats) @@ -2321,4 +2177,3 @@ contains end subroutine s_finalize_lagrangian_solver end module m_bubbles_EL - diff --git a/src/simulation/m_bubbles_EL_kernels.fpp b/src/simulation/m_bubbles_EL_kernels.fpp index 6c4d92861f..f0ff7b012f 100644 --- a/src/simulation/m_bubbles_EL_kernels.fpp +++ b/src/simulation/m_bubbles_EL_kernels.fpp @@ -7,73 +7,72 @@ !> @brief Kernel functions (Gaussian, delta) that smear Lagrangian bubble effects onto the Eulerian grid module m_bubbles_EL_kernels - use m_mpi_proxy !< Message passing interface (MPI) module proxy + use m_mpi_proxy !< Message passing interface (MPI) module proxy implicit none ! Cell-centered pressure gradients (precomputed for translational motion) - real(wp), allocatable, dimension(:, :, :) :: grad_p_x, grad_p_y, grad_p_z + real(wp), allocatable, dimension(:,:,:) :: grad_p_x, grad_p_y, grad_p_z $:GPU_DECLARE(create='[grad_p_x, grad_p_y, grad_p_z]') ! Finite-difference coefficients for pressure gradient computation - real(wp), allocatable, dimension(:, :) :: fd_coeff_x_pgrad - real(wp), allocatable, dimension(:, :) :: fd_coeff_y_pgrad - real(wp), allocatable, dimension(:, :) :: fd_coeff_z_pgrad + real(wp), allocatable, dimension(:,:) :: fd_coeff_x_pgrad + real(wp), allocatable, dimension(:,:) :: fd_coeff_y_pgrad + real(wp), allocatable, dimension(:,:) :: fd_coeff_z_pgrad $:GPU_DECLARE(create='[fd_coeff_x_pgrad, fd_coeff_y_pgrad, fd_coeff_z_pgrad]') ! Cell list for bubble-to-cell mapping (rebuilt each RK stage before smearing) - integer, allocatable, dimension(:, :, :) :: cell_list_start ! (0:m, 0:n, 0:p) - integer, allocatable, dimension(:, :, :) :: cell_list_count ! (0:m, 0:n, 0:p) - integer, allocatable, dimension(:) :: cell_list_idx ! (1:nBubs_glb) sorted bubble indices + integer, allocatable, dimension(:,:,:) :: cell_list_start ! (0:m, 0:n, 0:p) + integer, allocatable, dimension(:,:,:) :: cell_list_count ! (0:m, 0:n, 0:p) + integer, allocatable, dimension(:) :: cell_list_idx ! (1:nBubs_glb) sorted bubble indices $:GPU_DECLARE(create='[cell_list_start, cell_list_count, cell_list_idx]') contains - !> The purpose of this subroutine is to smear the strength of the lagrangian - !! bubbles into the Eulerian framework using different approaches. - !! @param nBubs Number of lagrangian bubbles in the current domain - !! @param lbk_rad Radius of the bubbles - !! @param lbk_vel Interface velocity of the bubbles - !! @param lbk_s Computational coordinates of the bubbles - !! @param lbk_pos Spatial coordinates of the bubbles - !! @param updatedvar Eulerian variable to be updated + !> The purpose of this subroutine is to smear the strength of the lagrangian bubbles into the Eulerian framework using different + !! approaches. + !! @param nBubs Number of lagrangian bubbles in the current domain + !! @param lbk_rad Radius of the bubbles + !! @param lbk_vel Interface velocity of the bubbles + !! @param lbk_s Computational coordinates of the bubbles + !! @param lbk_pos Spatial coordinates of the bubbles + !! @param updatedvar Eulerian variable to be updated subroutine s_smoothfunction(nBubs, lbk_rad, lbk_vel, lbk_s, lbk_pos, updatedvar, kcomp) - integer, intent(in) :: nBubs - real(wp), dimension(1:lag_params%nBubs_glb, 1:3, 1:2), intent(in) :: lbk_s, lbk_pos - real(wp), dimension(1:lag_params%nBubs_glb, 1:2), intent(in) :: lbk_rad, lbk_vel - type(scalar_field), dimension(:), intent(inout) :: updatedvar - type(scalar_field), dimension(:), intent(inout) :: kcomp + integer, intent(in) :: nBubs + real(wp), dimension(1:lag_params%nBubs_glb,1:3,1:2), intent(in) :: lbk_s, lbk_pos + real(wp), dimension(1:lag_params%nBubs_glb,1:2), intent(in) :: lbk_rad, lbk_vel + type(scalar_field), dimension(:), intent(inout) :: updatedvar + type(scalar_field), dimension(:), intent(inout) :: kcomp smoothfunc:select case(lag_params%smooth_type) case (1) - call s_gaussian(nBubs, lbk_rad, lbk_vel, lbk_s, lbk_pos, updatedvar, kcomp) + call s_gaussian(nBubs, lbk_rad, lbk_vel, lbk_s, lbk_pos, updatedvar, kcomp) case (2) - call s_deltafunc(nBubs, lbk_rad, lbk_vel, lbk_s, updatedvar, kcomp) + call s_deltafunc(nBubs, lbk_rad, lbk_vel, lbk_s, updatedvar, kcomp) end select smoothfunc end subroutine s_smoothfunction - !> Builds a sorted cell list mapping each interior cell (0:m,0:n,0:p) to its - !! resident bubbles. Uses a counting-sort on the host (O(nBubs + N_cells)). - !! Must be called before s_gaussian each RK stage. + !> Builds a sorted cell list mapping each interior cell (0:m,0:n,0:p) to its resident bubbles. Uses a counting-sort on the host + !! (O(nBubs + N_cells)). Must be called before s_gaussian each RK stage. !! @param nBubs Number of lagrangian bubbles in the current domain !! @param lbk_s Computational coordinates of the bubbles subroutine s_build_cell_list(nBubs, lbk_s) - integer, intent(in) :: nBubs - real(wp), dimension(1:lag_params%nBubs_glb, 1:3, 1:2), intent(in) :: lbk_s - - integer :: l, ci, cj, ck, idx - real(wp), dimension(3) :: s_coord + integer, intent(in) :: nBubs + real(wp), dimension(1:lag_params%nBubs_glb,1:3,1:2), intent(in) :: lbk_s + integer :: l, ci, cj, ck, idx + real(wp), dimension(3) :: s_coord ! Bring current bubble positions to host + $:GPU_UPDATE(host='[lbk_s]') ! Pass 1: zero counts and count bubbles per cell cell_list_count = 0 do l = 1, nBubs - s_coord(1:3) = lbk_s(l, 1:3, 2) + s_coord(1:3) = lbk_s(l,1:3,2) ci = int(s_coord(1)) cj = int(s_coord(2)) ck = int(s_coord(3)) @@ -95,11 +94,10 @@ contains end do end do - ! Pass 2: place bubble indices into cell_list_idx - ! Temporarily reuse cell_list_count as a running offset + ! Pass 2: place bubble indices into cell_list_idx Temporarily reuse cell_list_count as a running offset cell_list_count = 0 do l = 1, nBubs - s_coord(1:3) = lbk_s(l, 1:3, 2) + s_coord(1:3) = lbk_s(l,1:3,2) ci = int(s_coord(1)) cj = int(s_coord(2)) ck = int(s_coord(3)) @@ -115,27 +113,25 @@ contains end subroutine s_build_cell_list - !> Cell-centric delta-function smearing using the cell list (no GPU atomics). - !! Each bubble only affects the cell it resides in. The outer GPU loop - !! iterates over interior cells and sums contributions from resident bubbles. + !> Cell-centric delta-function smearing using the cell list (no GPU atomics). Each bubble only affects the cell it resides in. + !! The outer GPU loop iterates over interior cells and sums contributions from resident bubbles. subroutine s_deltafunc(nBubs, lbk_rad, lbk_vel, lbk_s, updatedvar, kcomp) - integer, intent(in) :: nBubs - real(wp), dimension(1:lag_params%nBubs_glb, 1:3, 1:2), intent(in) :: lbk_s - real(wp), dimension(1:lag_params%nBubs_glb, 1:2), intent(in) :: lbk_rad, lbk_vel - type(scalar_field), dimension(:), intent(inout) :: updatedvar - type(scalar_field), dimension(:), intent(inout) :: kcomp + integer, intent(in) :: nBubs + real(wp), dimension(1:lag_params%nBubs_glb,1:3,1:2), intent(in) :: lbk_s + real(wp), dimension(1:lag_params%nBubs_glb,1:2), intent(in) :: lbk_rad, lbk_vel + type(scalar_field), dimension(:), intent(inout) :: updatedvar + type(scalar_field), dimension(:), intent(inout) :: kcomp + real(wp) :: strength_vel, strength_vol + real(wp) :: volpart, Vol + real(wp) :: y_kahan, t_kahan + integer :: i, j, k, lb, bub_idx - real(wp) :: strength_vel, strength_vol - real(wp) :: volpart, Vol - real(wp) :: y_kahan, t_kahan - integer :: i, j, k, lb, bub_idx - - $:GPU_PARALLEL_LOOP(collapse=3, private='[i,j,k,lb,bub_idx,volpart,Vol,strength_vel,strength_vol,y_kahan,t_kahan]') + $:GPU_PARALLEL_LOOP(collapse=3, & + & private='[i, j, k, lb, bub_idx, volpart, Vol, strength_vel, strength_vol, y_kahan, t_kahan]') do k = 0, p do j = 0, n do i = 0, m - ! Cell volume if (num_dims == 2) then Vol = dx(i)*dy(j)*lag_params%charwidth @@ -146,9 +142,7 @@ contains ! Loop over bubbles in this cell $:GPU_LOOP(parallelism='[seq]') - do lb = cell_list_start(i, j, k), & - cell_list_start(i, j, k) + cell_list_count(i, j, k) - 1 - + do lb = cell_list_start(i, j, k), cell_list_start(i, j, k) + cell_list_count(i, j, k) - 1 bub_idx = cell_list_idx(lb) volpart = 4._wp/3._wp*pi*lbk_rad(bub_idx, 2)**3._wp @@ -175,7 +169,6 @@ contains updatedvar(5)%sf(i, j, k) = t_kahan end if end do - end do end do end do @@ -183,30 +176,29 @@ contains end subroutine s_deltafunc - !> Cell-centric gaussian smearing using the cell list (no GPU atomics). - !! Each grid cell accumulates contributions from nearby bubbles looked up - !! via cell_list_start/count/idx. + !> Cell-centric gaussian smearing using the cell list (no GPU atomics). Each grid cell accumulates contributions from nearby + !! bubbles looked up via cell_list_start/count/idx. subroutine s_gaussian(nBubs, lbk_rad, lbk_vel, lbk_s, lbk_pos, updatedvar, kcomp) - integer, intent(in) :: nBubs - real(wp), dimension(1:lag_params%nBubs_glb, 1:3, 1:2), intent(in) :: lbk_s, lbk_pos - real(wp), dimension(1:lag_params%nBubs_glb, 1:2), intent(in) :: lbk_rad, lbk_vel - type(scalar_field), dimension(:), intent(inout) :: updatedvar - type(scalar_field), dimension(:), intent(inout) :: kcomp - - real(wp), dimension(3) :: center, nodecoord, s_coord - integer, dimension(3) :: cell, cellijk - real(wp) :: stddsv, volpart - real(wp) :: strength_vel, strength_vol - real(wp) :: func, func2 - real(wp) :: y_kahan, t_kahan - integer :: i, j, k, di, dj, dk, lb, bub_idx - integer :: di_beg, di_end, dj_beg, dj_end, dk_beg, dk_end - integer :: smear_x_beg, smear_x_end - integer :: smear_y_beg, smear_y_end - integer :: smear_z_beg, smear_z_end + integer, intent(in) :: nBubs + real(wp), dimension(1:lag_params%nBubs_glb,1:3,1:2), intent(in) :: lbk_s, lbk_pos + real(wp), dimension(1:lag_params%nBubs_glb,1:2), intent(in) :: lbk_rad, lbk_vel + type(scalar_field), dimension(:), intent(inout) :: updatedvar + type(scalar_field), dimension(:), intent(inout) :: kcomp + real(wp), dimension(3) :: center, nodecoord, s_coord + integer, dimension(3) :: cell, cellijk + real(wp) :: stddsv, volpart + real(wp) :: strength_vel, strength_vol + real(wp) :: func, func2 + real(wp) :: y_kahan, t_kahan + integer :: i, j, k, di, dj, dk, lb, bub_idx + integer :: di_beg, di_end, dj_beg, dj_end, dk_beg, dk_end + integer :: smear_x_beg, smear_x_end + integer :: smear_y_beg, smear_y_end + integer :: smear_z_beg, smear_z_end ! Extended grid range for smearing (includes buffer cells for MPI communication) + smear_x_beg = -mapCells - 1 smear_x_end = m + mapCells + 1 smear_y_beg = merge(-mapCells - 1, 0, n > 0) @@ -214,13 +206,13 @@ contains smear_z_beg = merge(-mapCells - 1, 0, p > 0) smear_z_end = merge(p + mapCells + 1, p, p > 0) - $:GPU_PARALLEL_LOOP(collapse=3, & - & private='[i,j,k,di,dj,dk,lb,bub_idx,center,nodecoord,s_coord,cell,cellijk,stddsv,volpart,strength_vel,strength_vol,func,func2,y_kahan,t_kahan,di_beg,di_end,dj_beg,dj_end,dk_beg,dk_end]', & - & copyin='[smear_x_beg,smear_x_end,smear_y_beg,smear_y_end,smear_z_beg,smear_z_end]') + $:GPU_PARALLEL_LOOP(collapse=3, private='[i, j, k, di, dj, dk, lb, bub_idx, center, nodecoord, s_coord, cell, cellijk, & + & stddsv, volpart, strength_vel, strength_vol, func, func2, y_kahan, t_kahan, di_beg, di_end, dj_beg, & + & dj_end, dk_beg, dk_end]', copyin='[smear_x_beg, smear_x_end, smear_y_beg, smear_y_end, smear_z_beg, & + & smear_z_end]') do k = smear_z_beg, smear_z_end do j = smear_y_beg, smear_y_end do i = smear_x_beg, smear_x_end - cellijk(1) = i cellijk(2) = j cellijk(3) = k @@ -245,21 +237,19 @@ contains $:GPU_LOOP(parallelism='[seq]') do di = di_beg, di_end $:GPU_LOOP(parallelism='[seq]') - do lb = cell_list_start(di, dj, dk), & - cell_list_start(di, dj, dk) + cell_list_count(di, dj, dk) - 1 - + do lb = cell_list_start(di, dj, dk), cell_list_start(di, dj, dk) + cell_list_count(di, dj, dk) - 1 bub_idx = cell_list_idx(lb) ! Bubble properties volpart = 4._wp/3._wp*pi*lbk_rad(bub_idx, 2)**3._wp - s_coord(1:3) = lbk_s(bub_idx, 1:3, 2) + s_coord(1:3) = lbk_s(bub_idx,1:3,2) call s_get_cell(s_coord, cell) call s_compute_stddsv(cell, volpart, stddsv) strength_vol = volpart strength_vel = 4._wp*pi*lbk_rad(bub_idx, 2)**2._wp*lbk_vel(bub_idx, 2) - center(1:2) = lbk_pos(bub_idx, 1:2, 2) + center(1:2) = lbk_pos(bub_idx,1:2,2) center(3) = 0._wp if (p > 0) center(3) = lbk_pos(bub_idx, 3, 2) @@ -284,12 +274,10 @@ contains kcomp(5)%sf(i, j, k) = (t_kahan - updatedvar(5)%sf(i, j, k)) - y_kahan updatedvar(5)%sf(i, j, k) = t_kahan end if - end do end do end do end do - end do end do end do @@ -299,29 +287,28 @@ contains !> The purpose of this subroutine is to apply the gaussian kernel function for each bubble (Maeda and Colonius, 2018)). subroutine s_applygaussian(center, cellaux, nodecoord, stddsv, strength_idx, func) - $:GPU_ROUTINE(function_name='s_applygaussian',parallelism='[seq]', & - & cray_inline=True) + + $:GPU_ROUTINE(function_name='s_applygaussian',parallelism='[seq]', cray_inline=True) real(wp), dimension(3), intent(in) :: center - integer, dimension(3), intent(in) :: cellaux + integer, dimension(3), intent(in) :: cellaux real(wp), dimension(3), intent(in) :: nodecoord - real(wp), intent(in) :: stddsv - real(wp), intent(in) :: strength_idx - real(wp), intent(out) :: func - integer :: i - - real(wp) :: distance - real(wp) :: theta, dtheta, L2, dzp, Lz2, zc - real(wp) :: Nr, Nr_count + real(wp), intent(in) :: stddsv + real(wp), intent(in) :: strength_idx + real(wp), intent(out) :: func + integer :: i + real(wp) :: distance + real(wp) :: theta, dtheta, L2, dzp, Lz2, zc + real(wp) :: Nr, Nr_count distance = sqrt((center(1) - nodecoord(1))**2._wp + (center(2) - nodecoord(2))**2._wp + (center(3) - nodecoord(3))**2._wp) if (num_dims == 3) then - !< 3D gaussian function + !> 3D gaussian function func = exp(-0.5_wp*(distance/stddsv)**2._wp)/(sqrt(2._wp*pi)*stddsv)**3._wp else if (cyl_coord) then - !< 2D cylindrical function: + !> 2D cylindrical function: ! We smear particles in the azimuthal direction for given r theta = 0._wp Nr = ceiling(2._wp*pi*nodecoord(2)/(y_cb(cellaux(2)) - y_cb(cellaux(2) - 1))) @@ -338,17 +325,17 @@ contains L2 = center(2)**2._wp + nodecoord(2)**2._wp - 2._wp*center(2)*nodecoord(2)*cos(theta) distance = sqrt((center(1) - nodecoord(1))**2._wp + L2) ! nodecoord(2)*dtheta is the azimuthal width of the cell - func = func + & - dtheta/2._wp/pi*exp(-0.5_wp*(distance/stddsv)**2._wp)/(sqrt(2._wp*pi)*stddsv)**(3._wp*(strength_idx + 1._wp)) + func = func + dtheta/2._wp/pi*exp(-0.5_wp*(distance/stddsv)**2._wp)/(sqrt(2._wp*pi)*stddsv) & + & **(3._wp*(strength_idx + 1._wp)) end do else - !< 2D cartesian function: Equation (48) from Madea and Colonius 2018 + !> 2D cartesian function: Equation (48) from Madea and Colonius 2018 ! We smear particles considering a virtual depth (lag_params%charwidth) with lag_params%charNz cells dzp = (lag_params%charwidth/(lag_params%charNz + 1._wp)) func = 0._wp do i = 0, lag_params%charNz - zc = (-lag_params%charwidth/2._wp + dzp*(0.5_wp + i)) ! Center of virtual cell i in z-direction + zc = (-lag_params%charwidth/2._wp + dzp*(0.5_wp + i)) ! Center of virtual cell i in z-direction Lz2 = (center(3) - zc)**2._wp distance = sqrt((center(1) - nodecoord(1))**2._wp + (center(2) - nodecoord(2))**2._wp + Lz2) func = func + dzp/lag_params%charwidth*exp(-0.5_wp*(distance/stddsv)**2._wp)/(sqrt(2._wp*pi)*stddsv)**3._wp @@ -358,15 +345,16 @@ contains end subroutine s_applygaussian - !> The purpose of this subroutine is to check if the current cell is outside the computational domain or not (including ghost cells). - !! @param cellaux Tested cell to smear the bubble effect in. - !! @param celloutside If true, then cellaux is outside the computational domain. + !> The purpose of this subroutine is to check if the current cell is outside the computational domain or not (including ghost + !! cells). + !! @param cellaux Tested cell to smear the bubble effect in. + !! @param celloutside If true, then cellaux is outside the computational domain. subroutine s_check_celloutside(cellaux, celloutside) - $:GPU_ROUTINE(function_name='s_check_celloutside',parallelism='[seq]', & - & cray_inline=True) + + $:GPU_ROUTINE(function_name='s_check_celloutside',parallelism='[seq]', cray_inline=True) integer, dimension(3), intent(inout) :: cellaux - logical, intent(out) :: celloutside + logical, intent(out) :: celloutside celloutside = .false. @@ -393,14 +381,14 @@ contains end subroutine s_check_celloutside !> This subroutine relocates the current cell, if it intersects a symmetric boundary. - !! @param cell Cell of the current bubble - !! @param cellaux Cell to map the bubble effect in. + !! @param cell Cell of the current bubble + !! @param cellaux Cell to map the bubble effect in. subroutine s_shift_cell_symmetric_bc(cellaux, cell) - $:GPU_ROUTINE(function_name='s_shift_cell_symmetric_bc', & - & parallelism='[seq]', cray_inline=True) + + $:GPU_ROUTINE(function_name='s_shift_cell_symmetric_bc', parallelism='[seq]', cray_inline=True) integer, dimension(3), intent(inout) :: cellaux - integer, dimension(3), intent(in) :: cell + integer, dimension(3), intent(in) :: cell ! x-dir if (bc_x%beg == BC_REFLECTIVE .and. (cell(1) <= mapCells - 1)) then @@ -410,7 +398,7 @@ contains cellaux(1) = cellaux(1) - (2*(cellaux(1) - m) - 1) end if - !y-dir + ! y-dir if (bc_y%beg == BC_REFLECTIVE .and. (cell(2) <= mapCells - 1)) then cellaux(2) = abs(cellaux(2)) - 1 end if @@ -419,7 +407,7 @@ contains end if if (p > 0) then - !z-dir + ! z-dir if (bc_z%beg == BC_REFLECTIVE .and. (cell(3) <= mapCells - 1)) then cellaux(3) = abs(cellaux(3)) - 1 end if @@ -431,25 +419,24 @@ contains end subroutine s_shift_cell_symmetric_bc !> Calculates the standard deviation of the bubble being smeared in the Eulerian framework. - !! @param cell Cell where the bubble is located - !! @param volpart Volume of the bubble - !! @param stddsv Standard deviaton + !! @param cell Cell where the bubble is located + !! @param volpart Volume of the bubble + !! @param stddsv Standard deviaton subroutine s_compute_stddsv(cell, volpart, stddsv) - $:GPU_ROUTINE(function_name='s_compute_stddsv',parallelism='[seq]', & - & cray_inline=True) - integer, dimension(3), intent(in) :: cell - real(wp), intent(in) :: volpart - real(wp), intent(out) :: stddsv + $:GPU_ROUTINE(function_name='s_compute_stddsv',parallelism='[seq]', cray_inline=True) - real(wp) :: chardist, charvol - real(wp) :: rad + integer, dimension(3), intent(in) :: cell + real(wp), intent(in) :: volpart + real(wp), intent(out) :: stddsv + real(wp) :: chardist, charvol + real(wp) :: rad - !< Compute characteristic distance + !> Compute characteristic distance chardist = sqrt(dx(cell(1))*dy(cell(2))) if (p > 0) chardist = (dx(cell(1))*dy(cell(2))*dz(cell(3)))**(1._wp/3._wp) - !< Compute characteristic volume + !> Compute characteristic volume if (p > 0) then charvol = dx(cell(1))*dy(cell(2))*dz(cell(3)) else @@ -460,7 +447,7 @@ contains end if end if - !< Compute Standard deviaton + !> Compute Standard deviaton if ((volpart/charvol) > 0.5_wp*lag_params%valmaxvoid .or. (lag_params%smooth_type == 1)) then rad = (3._wp*volpart/(4._wp*pi))**(1._wp/3._wp) stddsv = 1._wp*lag_params%epsilonb*max(chardist, rad) @@ -471,15 +458,15 @@ contains end subroutine s_compute_stddsv !> The purpose of this procedure is to calculate the characteristic cell volume - !! @param cellx x-direction cell index - !! @param celly y-direction cell index - !! @param cellz z-direction cell index - !! @param Charvol Characteristic volume + !! @param cellx x-direction cell index + !! @param celly y-direction cell index + !! @param cellz z-direction cell index + !! @param Charvol Characteristic volume subroutine s_get_char_vol(cellx, celly, cellz, Charvol) - $:GPU_ROUTINE(function_name='s_get_char_vol',parallelism='[seq]', & - & cray_inline=True) - integer, intent(in) :: cellx, celly, cellz + $:GPU_ROUTINE(function_name='s_get_char_vol',parallelism='[seq]', cray_inline=True) + + integer, intent(in) :: cellx, celly, cellz real(wp), intent(out) :: Charvol if (p > 0) then @@ -494,17 +481,16 @@ contains end subroutine s_get_char_vol - !> This subroutine transforms the computational coordinates of the bubble from - !! real type into integer. - !! @param s_cell Computational coordinates of the bubble, real type - !! @param get_cell Computational coordinates of the bubble, integer type + !> This subroutine transforms the computational coordinates of the bubble from real type into integer. + !! @param s_cell Computational coordinates of the bubble, real type + !! @param get_cell Computational coordinates of the bubble, integer type subroutine s_get_cell(s_cell, get_cell) - $:GPU_ROUTINE(function_name='s_get_cell',parallelism='[seq]', & - & cray_inline=True) + + $:GPU_ROUTINE(function_name='s_get_cell',parallelism='[seq]', cray_inline=True) real(wp), dimension(3), intent(in) :: s_cell integer, dimension(3), intent(out) :: get_cell - integer :: i + integer :: i get_cell(:) = int(s_cell(:)) do i = 1, num_dims @@ -513,27 +499,25 @@ contains end subroutine s_get_cell - !> Precomputes cell-centered pressure gradients (dp/dx, dp/dy, dp/dz) at all cell centers - !! using finite-difference coefficients of the specified order. This avoids - !! scattered memory accesses to the pressure field when computing translational - !! bubble forces. - !! @param q_prim_vf Primitive variables (pressure is at index E_idx) + !> Precomputes cell-centered pressure gradients (dp/dx, dp/dy, dp/dz) at all cell centers using finite-difference coefficients + !! of the specified order. This avoids scattered memory accesses to the pressure field when computing translational bubble + !! forces. + !! @param q_prim_vf Primitive variables (pressure is at index E_idx) subroutine s_compute_pressure_gradients(q_prim_vf) type(scalar_field), dimension(sys_size), intent(in) :: q_prim_vf - - integer :: i, j, k, r + integer :: i, j, k, r ! dp/dx at all cell centers - $:GPU_PARALLEL_LOOP(private='[i,j,k,r]', collapse=3) + + $:GPU_PARALLEL_LOOP(private='[i, j, k, r]', collapse=3) do k = 0, p do j = 0, n do i = 0, m grad_p_x(i, j, k) = 0._wp $:GPU_LOOP(parallelism='[seq]') do r = -fd_number, fd_number - grad_p_x(i, j, k) = grad_p_x(i, j, k) + & - q_prim_vf(E_idx)%sf(i + r, j, k)*fd_coeff_x_pgrad(r, i) + grad_p_x(i, j, k) = grad_p_x(i, j, k) + q_prim_vf(E_idx)%sf(i + r, j, k)*fd_coeff_x_pgrad(r, i) end do end do end do @@ -542,15 +526,14 @@ contains ! dp/dy at all cell centers if (n > 0) then - $:GPU_PARALLEL_LOOP(private='[i,j,k,r]', collapse=3) + $:GPU_PARALLEL_LOOP(private='[i, j, k, r]', collapse=3) do k = 0, p do j = 0, n do i = 0, m grad_p_y(i, j, k) = 0._wp $:GPU_LOOP(parallelism='[seq]') do r = -fd_number, fd_number - grad_p_y(i, j, k) = grad_p_y(i, j, k) + & - q_prim_vf(E_idx)%sf(i, j + r, k)*fd_coeff_y_pgrad(r, j) + grad_p_y(i, j, k) = grad_p_y(i, j, k) + q_prim_vf(E_idx)%sf(i, j + r, k)*fd_coeff_y_pgrad(r, j) end do end do end do @@ -560,15 +543,14 @@ contains ! dp/dz at all cell centers if (p > 0) then - $:GPU_PARALLEL_LOOP(private='[i,j,k,r]', collapse=3) + $:GPU_PARALLEL_LOOP(private='[i, j, k, r]', collapse=3) do k = 0, p do j = 0, n do i = 0, m grad_p_z(i, j, k) = 0._wp $:GPU_LOOP(parallelism='[seq]') do r = -fd_number, fd_number - grad_p_z(i, j, k) = grad_p_z(i, j, k) + & - q_prim_vf(E_idx)%sf(i, j, k + r)*fd_coeff_z_pgrad(r, k) + grad_p_z(i, j, k) = grad_p_z(i, j, k) + q_prim_vf(E_idx)%sf(i, j, k + r)*fd_coeff_z_pgrad(r, k) end do end do end do @@ -578,22 +560,21 @@ contains end subroutine s_compute_pressure_gradients - !! This function interpolates the velocity of Eulerian field at the position - !! of the bubble. - !! @param pos Position of the bubble in directiion i - !! @param cell Computational coordinates of the bubble - !! @param i Direction of the velocity (1: x, 2: y, 3: z) - !! @param q_prim_vf Eulerian field with primitive variables - !! @return v Interpolated velocity at the position of the bubble + !! This function interpolates the velocity of Eulerian field at the position of the bubble. + !! @param pos Position of the bubble in directiion i + !! @param cell Computational coordinates of the bubble + !! @param i Direction of the velocity (1: x, 2: y, 3: z) + !! @param q_prim_vf Eulerian field with primitive variables + !! @return v Interpolated velocity at the position of the bubble function f_interpolate_velocity(pos, cell, i, q_prim_vf) result(v) + $:GPU_ROUTINE(parallelism='[seq]') - real(wp), intent(in) :: pos - integer, dimension(3), intent(in) :: cell - integer, intent(in) :: i + real(wp), intent(in) :: pos + integer, dimension(3), intent(in) :: cell + integer, intent(in) :: i type(scalar_field), dimension(sys_size), intent(in) :: q_prim_vf - - real(wp) :: v - real(wp), dimension(fd_order + 1) :: xi, eta, L + real(wp) :: v + real(wp), dimension(fd_order + 1) :: xi, eta, L if (fd_order == 2) then if (i == 1) then @@ -603,14 +584,14 @@ contains eta(2) = q_prim_vf(momxb)%sf(cell(1), cell(2), cell(3)) xi(3) = x_cc(cell(1) + 1) eta(3) = q_prim_vf(momxb)%sf(cell(1) + 1, cell(2), cell(3)) - elseif (i == 2) then + else if (i == 2) then xi(1) = y_cc(cell(2) - 1) eta(1) = q_prim_vf(momxb + 1)%sf(cell(1), cell(2) - 1, cell(3)) xi(2) = y_cc(cell(2)) eta(2) = q_prim_vf(momxb + 1)%sf(cell(1), cell(2), cell(3)) xi(3) = y_cc(cell(2) + 1) eta(3) = q_prim_vf(momxb + 1)%sf(cell(1), cell(2) + 1, cell(3)) - elseif (i == 3) then + else if (i == 3) then xi(1) = z_cc(cell(3) - 1) eta(1) = q_prim_vf(momxe)%sf(cell(1), cell(2), cell(3) - 1) xi(2) = z_cc(cell(3)) @@ -624,7 +605,7 @@ contains L(3) = ((pos - xi(1))*(pos - xi(2)))/((xi(3) - xi(1))*(xi(3) - xi(2))) v = L(1)*eta(1) + L(2)*eta(2) + L(3)*eta(3) - elseif (fd_order == 4) then + else if (fd_order == 4) then if (i == 1) then xi(1) = x_cc(cell(1) - 2) eta(1) = q_prim_vf(momxb)%sf(cell(1) - 2, cell(2), cell(3)) @@ -636,7 +617,7 @@ contains eta(4) = q_prim_vf(momxb)%sf(cell(1) + 1, cell(2), cell(3)) xi(5) = x_cc(cell(1) + 2) eta(5) = q_prim_vf(momxb)%sf(cell(1) + 2, cell(2), cell(3)) - elseif (i == 2) then + else if (i == 2) then xi(1) = y_cc(cell(2) - 2) eta(1) = q_prim_vf(momxb + 1)%sf(cell(1), cell(2) - 2, cell(3)) xi(2) = y_cc(cell(2) - 1) @@ -647,7 +628,7 @@ contains eta(4) = q_prim_vf(momxb + 1)%sf(cell(1), cell(2) + 1, cell(3)) xi(5) = y_cc(cell(2) + 2) eta(5) = q_prim_vf(momxb + 1)%sf(cell(1), cell(2) + 2, cell(3)) - elseif (i == 3) then + else if (i == 3) then xi(1) = z_cc(cell(3) - 2) eta(1) = q_prim_vf(momxe)%sf(cell(1), cell(2), cell(3) - 2) xi(2) = z_cc(cell(3) - 1) @@ -660,45 +641,44 @@ contains eta(5) = q_prim_vf(momxe)%sf(cell(1), cell(2), cell(3) + 2) end if - L(1) = ((pos - xi(2))*(pos - xi(3))*(pos - xi(4))*(pos - xi(5)))/ & - ((xi(1) - xi(2))*(xi(1) - xi(3))*(xi(1) - xi(4))*(xi(1) - xi(5))) - L(2) = ((pos - xi(1))*(pos - xi(3))*(pos - xi(4))*(pos - xi(5)))/ & - ((xi(2) - xi(1))*(xi(2) - xi(3))*(xi(2) - xi(4))*(xi(2) - xi(5))) - L(3) = ((pos - xi(1))*(pos - xi(2))*(pos - xi(4))*(pos - xi(5)))/ & - ((xi(3) - xi(1))*(xi(3) - xi(2))*(xi(3) - xi(4))*(xi(3) - xi(5))) - L(4) = ((pos - xi(1))*(pos - xi(2))*(pos - xi(3))*(pos - xi(5)))/ & - ((xi(4) - xi(1))*(xi(4) - xi(2))*(xi(4) - xi(3))*(xi(4) - xi(5))) - L(5) = ((pos - xi(1))*(pos - xi(2))*(pos - xi(3))*(pos - xi(4)))/ & - ((xi(5) - xi(1))*(xi(5) - xi(2))*(xi(5) - xi(3))*(xi(5) - xi(4))) + L(1) = ((pos - xi(2))*(pos - xi(3))*(pos - xi(4))*(pos - xi(5)))/((xi(1) - xi(2))*(xi(1) - xi(3))*(xi(1) - xi(4)) & + & *(xi(1) - xi(5))) + L(2) = ((pos - xi(1))*(pos - xi(3))*(pos - xi(4))*(pos - xi(5)))/((xi(2) - xi(1))*(xi(2) - xi(3))*(xi(2) - xi(4)) & + & *(xi(2) - xi(5))) + L(3) = ((pos - xi(1))*(pos - xi(2))*(pos - xi(4))*(pos - xi(5)))/((xi(3) - xi(1))*(xi(3) - xi(2))*(xi(3) - xi(4)) & + & *(xi(3) - xi(5))) + L(4) = ((pos - xi(1))*(pos - xi(2))*(pos - xi(3))*(pos - xi(5)))/((xi(4) - xi(1))*(xi(4) - xi(2))*(xi(4) - xi(3)) & + & *(xi(4) - xi(5))) + L(5) = ((pos - xi(1))*(pos - xi(2))*(pos - xi(3))*(pos - xi(4)))/((xi(5) - xi(1))*(xi(5) - xi(2))*(xi(5) - xi(3)) & + & *(xi(5) - xi(4))) v = L(1)*eta(1) + L(2)*eta(2) + L(3)*eta(3) + L(4)*eta(4) + L(5)*eta(5) end if end function f_interpolate_velocity - !! This function calculates the force on a bubble - !! based on the pressure gradient, velocity, and drag model. - !! @param pos Position of the bubble in direction i - !! @param rad Radius of the bubble - !! @param rdot Radial velocity of the bubble - !! @param vel Velocity of the bubble - !! @param mg Mass of the gas in the bubble - !! @param mv Mass of the liquid in the bubble - !! @param Re Reynolds number - !! @param rho Density of the fluid - !! @param cell Computational coordinates of the bubble - !! @param i Direction of the velocity (1: x, 2: y, 3: z) - !! @param q_prim_vf Eulerian field with primitive variables - !! @return a Acceleration of the bubble in direction i + !! This function calculates the force on a bubble based on the pressure gradient, velocity, and drag model. + !! @param pos Position of the bubble in direction i + !! @param rad Radius of the bubble + !! @param rdot Radial velocity of the bubble + !! @param vel Velocity of the bubble + !! @param mg Mass of the gas in the bubble + !! @param mv Mass of the liquid in the bubble + !! @param Re Reynolds number + !! @param rho Density of the fluid + !! @param cell Computational coordinates of the bubble + !! @param i Direction of the velocity (1: x, 2: y, 3: z) + !! @param q_prim_vf Eulerian field with primitive variables + !! @return a Acceleration of the bubble in direction i function f_get_bubble_force(pos, rad, rdot, vel, mg, mv, Re, rho, cell, i, q_prim_vf) result(force) + $:GPU_ROUTINE(parallelism='[seq]') - real(wp), intent(in) :: pos, rad, rdot, mg, mv, Re, rho, vel - integer, dimension(3), intent(in) :: cell - integer, intent(in) :: i + real(wp), intent(in) :: pos, rad, rdot, mg, mv, Re, rho, vel + integer, dimension(3), intent(in) :: cell + integer, intent(in) :: i type(scalar_field), dimension(sys_size), intent(in) :: q_prim_vf - - real(wp) :: dp, vol, force - real(wp) :: v_rel + real(wp) :: dp, vol, force + real(wp) :: v_rel if (fd_order > 1) then v_rel = vel - f_interpolate_velocity(pos, cell, i, q_prim_vf) @@ -708,11 +688,11 @@ contains force = 0._wp - if (lag_params%drag_model == 1) then ! Free slip Stokes drag + if (lag_params%drag_model == 1) then ! Free slip Stokes drag force = force - (4._wp*pi*rad*v_rel)/Re - else if (lag_params%drag_model == 2) then ! No slip Stokes drag + else if (lag_params%drag_model == 2) then ! No slip Stokes drag force = force - (6._wp*pi*rad*v_rel)/Re - else if (lag_params%drag_model == 3) then ! Levich drag + else if (lag_params%drag_model == 3) then ! Levich drag force = force - (12._wp*pi*rad*v_rel)/Re end if @@ -720,9 +700,9 @@ contains ! Use precomputed cell-centered pressure gradients if (i == 1) then dp = grad_p_x(cell(1), cell(2), cell(3)) - elseif (i == 2) then + else if (i == 2) then dp = grad_p_y(cell(1), cell(2), cell(3)) - elseif (i == 3) then + else if (i == 3) then dp = grad_p_z(cell(1), cell(2), cell(3)) end if diff --git a/src/simulation/m_cbc.fpp b/src/simulation/m_cbc.fpp index f5f9cb4c30..f1b825a907 100644 --- a/src/simulation/m_cbc.fpp +++ b/src/simulation/m_cbc.fpp @@ -8,110 +8,96 @@ module m_cbc - use m_derived_types !< Definitions of the derived types - - use m_global_parameters !< Definitions of the global parameters - - use m_variables_conversion !< State variables type conversion procedures - + use m_derived_types !< Definitions of the derived types + use m_global_parameters !< Definitions of the global parameters + use m_variables_conversion !< State variables type conversion procedures use m_compute_cbc - - use m_thermochem, only: & - get_mixture_energy_mass, get_mixture_specific_heat_cv_mass, & - get_mixture_specific_heat_cp_mass, gas_constant, & - get_mixture_molecular_weight, get_species_enthalpies_rt, & - molecular_weights, get_species_specific_heats_r, & - get_mole_fractions, get_species_specific_heats_r + use m_thermochem, only: get_mixture_energy_mass, get_mixture_specific_heat_cv_mass, get_mixture_specific_heat_cp_mass, & + & gas_constant, get_mixture_molecular_weight, get_species_enthalpies_rt, molecular_weights, get_species_specific_heats_r, & + & get_mole_fractions, get_species_specific_heats_r #:if USING_AMD use m_chemistry, only: molecular_weights_nonparameter #:endif + implicit none private; public :: s_initialize_cbc_module, s_cbc, s_finalize_cbc_module - !! The cell-average primitive variables. They are obtained by reshaping (RS) - !! q_prim_vf in the coordinate direction normal to the domain boundary along - !! which the CBC is applied. + !! The cell-average primitive variables. They are obtained by reshaping (RS) q_prim_vf in the coordinate direction normal to the + !! domain boundary along which the CBC is applied. - real(wp), allocatable, dimension(:, :, :, :) :: q_prim_rsx_vf - real(wp), allocatable, dimension(:, :, :, :) :: q_prim_rsy_vf - real(wp), allocatable, dimension(:, :, :, :) :: q_prim_rsz_vf - $:GPU_DECLARE(create='[q_prim_rsx_vf,q_prim_rsy_vf,q_prim_rsz_vf]') + real(wp), allocatable, dimension(:,:,:,:) :: q_prim_rsx_vf + real(wp), allocatable, dimension(:,:,:,:) :: q_prim_rsy_vf + real(wp), allocatable, dimension(:,:,:,:) :: q_prim_rsz_vf + $:GPU_DECLARE(create='[q_prim_rsx_vf, q_prim_rsy_vf, q_prim_rsz_vf]') - !! Cell-average fluxes (src - source). These are directly determined from the - !! cell-average primitive variables, q_prims_rs_vf, and not a Riemann solver. + !! Cell-average fluxes (src - source). These are directly determined from the cell-average primitive variables, q_prims_rs_vf, + !! and not a Riemann solver. - real(wp), allocatable, dimension(:, :, :, :) :: F_rsx_vf, F_src_rsx_vf !< - real(wp), allocatable, dimension(:, :, :, :) :: F_rsy_vf, F_src_rsy_vf !< - real(wp), allocatable, dimension(:, :, :, :) :: F_rsz_vf, F_src_rsz_vf !< - $:GPU_DECLARE(create='[F_rsx_vf,F_src_rsx_vf,F_rsy_vf,F_src_rsy_vf,F_rsz_vf,F_src_rsz_vf]') + real(wp), allocatable, dimension(:,:,:,:) :: F_rsx_vf, F_src_rsx_vf + real(wp), allocatable, dimension(:,:,:,:) :: F_rsy_vf, F_src_rsy_vf + real(wp), allocatable, dimension(:,:,:,:) :: F_rsz_vf, F_src_rsz_vf + $:GPU_DECLARE(create='[F_rsx_vf, F_src_rsx_vf, F_rsy_vf, F_src_rsy_vf, F_rsz_vf, F_src_rsz_vf]') - !! There is a CCE bug that is causing some subset of these variables to interfere - !! with variables of the same name in m_riemann_solvers.fpp, and giving this versions - !! unique "_l" names works around the bug. Other private module allocatable arrays - !! in `acc declare create` clauses don't have this problem, so we still need to - !! isolate this bug. + !! There is a CCE bug that is causing some subset of these variables to interfere with variables of the same name in + !! m_riemann_solvers.fpp, and giving this versions unique "_l" names works around the bug. Other private module allocatable + !! arrays in `acc declare create` clauses don't have this problem, so we still need to isolate this bug. - real(wp), allocatable, dimension(:, :, :, :) :: flux_rsx_vf_l, flux_src_rsx_vf_l !< - real(wp), allocatable, dimension(:, :, :, :) :: flux_rsy_vf_l, flux_src_rsy_vf_l - real(wp), allocatable, dimension(:, :, :, :) :: flux_rsz_vf_l, flux_src_rsz_vf_l - $:GPU_DECLARE(create='[flux_rsx_vf_l,flux_src_rsx_vf_l,flux_rsy_vf_l,flux_src_rsy_vf_l,flux_rsz_vf_l,flux_src_rsz_vf_l]') + real(wp), allocatable, dimension(:,:,:,:) :: flux_rsx_vf_l, flux_src_rsx_vf_l + real(wp), allocatable, dimension(:,:,:,:) :: flux_rsy_vf_l, flux_src_rsy_vf_l + real(wp), allocatable, dimension(:,:,:,:) :: flux_rsz_vf_l, flux_src_rsz_vf_l + $:GPU_DECLARE(create='[flux_rsx_vf_l, flux_src_rsx_vf_l, flux_rsy_vf_l, flux_src_rsy_vf_l, flux_rsz_vf_l, flux_src_rsz_vf_l]') - real(wp), allocatable, dimension(:) :: ds !< Cell-width distribution in the s-direction + real(wp), allocatable, dimension(:) :: ds !< Cell-width distribution in the s-direction ! CBC Coefficients - real(wp), allocatable, dimension(:, :) :: fd_coef_x !< Finite diff. coefficients x-dir - real(wp), allocatable, dimension(:, :) :: fd_coef_y !< Finite diff. coefficients y-dir - real(wp), allocatable, dimension(:, :) :: fd_coef_z !< Finite diff. coefficients z-dir - - !! The first dimension identifies the location of a coefficient in the FD - !! formula, while the last dimension denotes the location of the CBC. + real(wp), allocatable, dimension(:,:) :: fd_coef_x !< Finite diff. coefficients x-dir + real(wp), allocatable, dimension(:,:) :: fd_coef_y !< Finite diff. coefficients y-dir + !> Finite diff. coefficients z-dir The first dimension identifies the location of a coefficient in the FD formula, while the + !! last dimension denotes the location of the CBC. + real(wp), allocatable, dimension(:,:) :: fd_coef_z - ! Bug with NVHPC when using nullified pointers in a declare create - ! real(wp), pointer, dimension(:, :) :: fd_coef => null() + ! Bug with NVHPC when using nullified pointers in a declare create real(wp), pointer, dimension(:, :) :: fd_coef => null() - real(wp), allocatable, dimension(:, :, :) :: pi_coef_x !< Polynomial interpolant coefficients in x-dir - real(wp), allocatable, dimension(:, :, :) :: pi_coef_y !< Polynomial interpolant coefficients in y-dir - real(wp), allocatable, dimension(:, :, :) :: pi_coef_z !< Polynomial interpolant coefficients in z-dir + real(wp), allocatable, dimension(:,:,:) :: pi_coef_x !< Polynomial interpolant coefficients in x-dir + real(wp), allocatable, dimension(:,:,:) :: pi_coef_y !< Polynomial interpolant coefficients in y-dir + real(wp), allocatable, dimension(:,:,:) :: pi_coef_z !< Polynomial interpolant coefficients in z-dir - $:GPU_DECLARE(create='[ds,fd_coef_x,fd_coef_y,fd_coef_z,pi_coef_x,pi_coef_y,pi_coef_z]') + $:GPU_DECLARE(create='[ds, fd_coef_x, fd_coef_y, fd_coef_z, pi_coef_x, pi_coef_y, pi_coef_z]') - !! The first dimension of the array identifies the polynomial, the - !! second dimension identifies the position of its coefficients and the last - !! dimension denotes the location of the CBC. + !! The first dimension of the array identifies the polynomial, the second dimension identifies the position of its coefficients + !! and the last dimension denotes the location of the CBC. - type(int_bounds_info) :: is1, is2, is3 !< Indical bounds in the s1-, s2- and s3-directions - $:GPU_DECLARE(create='[is1,is2,is3]') + type(int_bounds_info) :: is1, is2, is3 !< Indical bounds in the s1-, s2- and s3-directions + $:GPU_DECLARE(create='[is1, is2, is3]') integer :: dj integer :: bcxb, bcxe, bcyb, bcye, bczb, bcze integer :: cbc_dir, cbc_loc integer :: flux_cbc_index - $:GPU_DECLARE(create='[dj,bcxb,bcxe,bcyb,bcye,bczb,bcze]') - $:GPU_DECLARE(create='[cbc_dir, cbc_loc,flux_cbc_index]') + $:GPU_DECLARE(create='[dj, bcxb, bcxe, bcyb, bcye, bczb, bcze]') + $:GPU_DECLARE(create='[cbc_dir, cbc_loc, flux_cbc_index]') - !! GRCBC inputs for subsonic inflow and outflow conditions consisting of - !! inflow velocities, pressure, density and void fraction as well as - !! outflow velocities and pressure + !! GRCBC inputs for subsonic inflow and outflow conditions consisting of inflow velocities, pressure, density and void fraction + !! as well as outflow velocities and pressure - real(wp), allocatable, dimension(:) :: pres_in, pres_out, Del_in, Del_out - real(wp), allocatable, dimension(:, :) :: vel_in, vel_out - real(wp), allocatable, dimension(:, :) :: alpha_rho_in, alpha_in - $:GPU_DECLARE(create='[pres_in,pres_out,Del_in,Del_out]') - $:GPU_DECLARE(create='[vel_in,vel_out]') - $:GPU_DECLARE(create='[alpha_rho_in,alpha_in]') + real(wp), allocatable, dimension(:) :: pres_in, pres_out, Del_in, Del_out + real(wp), allocatable, dimension(:,:) :: vel_in, vel_out + real(wp), allocatable, dimension(:,:) :: alpha_rho_in, alpha_in + $:GPU_DECLARE(create='[pres_in, pres_out, Del_in, Del_out]') + $:GPU_DECLARE(create='[vel_in, vel_out]') + $:GPU_DECLARE(create='[alpha_rho_in, alpha_in]') contains - !> The computation of parameters, the allocation of memory, - !! the association of pointers and/or the execution of any - !! other procedures that are necessary to setup the module. + !> The computation of parameters, the allocation of memory, the association of pointers and/or the execution of any other + !! procedures that are necessary to setup the module. impure subroutine s_initialize_cbc_module - integer :: i - logical :: is_cbc + integer :: i + logical :: is_cbc type(int_bounds_info) :: idx1, idx2 if (chemistry) then @@ -127,7 +113,6 @@ contains if (n == 0) then is2%beg = 0 - else is2%beg = -buff_size end if @@ -136,41 +121,26 @@ contains if (p == 0) then is3%beg = 0 - else is3%beg = -buff_size end if is3%end = p - is3%beg - @:ALLOCATE(q_prim_rsx_vf(0:buff_size, & - is2%beg:is2%end, & - is3%beg:is3%end, 1:sys_size)) + @:ALLOCATE(q_prim_rsx_vf(0:buff_size, is2%beg:is2%end, is3%beg:is3%end, 1:sys_size)) if (weno_order > 1 .or. muscl_order > 1) then + @:ALLOCATE(F_rsx_vf(0:buff_size, is2%beg:is2%end, is3%beg:is3%end, 1:flux_cbc_index)) - @:ALLOCATE(F_rsx_vf(0:buff_size, & - is2%beg:is2%end, & - is3%beg:is3%end, 1:flux_cbc_index)) - - @:ALLOCATE(F_src_rsx_vf(0:buff_size, & - is2%beg:is2%end, & - is3%beg:is3%end, adv_idx%beg:adv_idx%end)) - + @:ALLOCATE(F_src_rsx_vf(0:buff_size, is2%beg:is2%end, is3%beg:is3%end, adv_idx%beg:adv_idx%end)) end if - @:ALLOCATE(flux_rsx_vf_l(-1:buff_size, & - is2%beg:is2%end, & - is3%beg:is3%end, 1:flux_cbc_index)) + @:ALLOCATE(flux_rsx_vf_l(-1:buff_size, is2%beg:is2%end, is3%beg:is3%end, 1:flux_cbc_index)) - @:ALLOCATE(flux_src_rsx_vf_l(-1:buff_size, & - is2%beg:is2%end, & - is3%beg:is3%end, adv_idx%beg:adv_idx%end)) + @:ALLOCATE(flux_src_rsx_vf_l(-1:buff_size, is2%beg:is2%end, is3%beg:is3%end, adv_idx%beg:adv_idx%end)) if (n > 0) then - if (m == 0) then is2%beg = 0 - else is2%beg = -buff_size end if @@ -179,43 +149,27 @@ contains if (p == 0) then is3%beg = 0 - else is3%beg = -buff_size end if is3%end = p - is3%beg - @:ALLOCATE(q_prim_rsy_vf(0:buff_size, & - is2%beg:is2%end, & - is3%beg:is3%end, 1:sys_size)) + @:ALLOCATE(q_prim_rsy_vf(0:buff_size, is2%beg:is2%end, is3%beg:is3%end, 1:sys_size)) if (weno_order > 1 .or. muscl_order > 1) then + @:ALLOCATE(F_rsy_vf(0:buff_size, is2%beg:is2%end, is3%beg:is3%end, 1:flux_cbc_index)) - @:ALLOCATE(F_rsy_vf(0:buff_size, & - is2%beg:is2%end, & - is3%beg:is3%end, 1:flux_cbc_index)) - - @:ALLOCATE(F_src_rsy_vf(0:buff_size, & - is2%beg:is2%end, & - is3%beg:is3%end, adv_idx%beg:adv_idx%end)) - + @:ALLOCATE(F_src_rsy_vf(0:buff_size, is2%beg:is2%end, is3%beg:is3%end, adv_idx%beg:adv_idx%end)) end if - @:ALLOCATE(flux_rsy_vf_l(-1:buff_size, & - is2%beg:is2%end, & - is3%beg:is3%end, 1:flux_cbc_index)) - - @:ALLOCATE(flux_src_rsy_vf_l(-1:buff_size, & - is2%beg:is2%end, & - is3%beg:is3%end, adv_idx%beg:adv_idx%end)) + @:ALLOCATE(flux_rsy_vf_l(-1:buff_size, is2%beg:is2%end, is3%beg:is3%end, 1:flux_cbc_index)) + @:ALLOCATE(flux_src_rsy_vf_l(-1:buff_size, is2%beg:is2%end, is3%beg:is3%end, adv_idx%beg:adv_idx%end)) end if if (p > 0) then - if (n == 0) then is2%beg = 0 - else is2%beg = -buff_size end if @@ -224,36 +178,22 @@ contains if (m == 0) then is3%beg = 0 - else is3%beg = -buff_size end if is3%end = m - is3%beg - @:ALLOCATE(q_prim_rsz_vf(0:buff_size, & - is2%beg:is2%end, & - is3%beg:is3%end, 1:sys_size)) + @:ALLOCATE(q_prim_rsz_vf(0:buff_size, is2%beg:is2%end, is3%beg:is3%end, 1:sys_size)) if (weno_order > 1 .or. muscl_order > 1) then + @:ALLOCATE(F_rsz_vf(0:buff_size, is2%beg:is2%end, is3%beg:is3%end, 1:flux_cbc_index)) - @:ALLOCATE(F_rsz_vf(0:buff_size, & - is2%beg:is2%end, & - is3%beg:is3%end, 1:flux_cbc_index)) - - @:ALLOCATE(F_src_rsz_vf(0:buff_size, & - is2%beg:is2%end, & - is3%beg:is3%end, adv_idx%beg:adv_idx%end)) - + @:ALLOCATE(F_src_rsz_vf(0:buff_size, is2%beg:is2%end, is3%beg:is3%end, adv_idx%beg:adv_idx%end)) end if - @:ALLOCATE(flux_rsz_vf_l(-1:buff_size, & - is2%beg:is2%end, & - is3%beg:is3%end, 1:flux_cbc_index)) - - @:ALLOCATE(flux_src_rsz_vf_l(-1:buff_size, & - is2%beg:is2%end, & - is3%beg:is3%end, adv_idx%beg:adv_idx%end)) + @:ALLOCATE(flux_rsz_vf_l(-1:buff_size, is2%beg:is2%end, is3%beg:is3%end, 1:flux_cbc_index)) + @:ALLOCATE(flux_src_rsz_vf_l(-1:buff_size, is2%beg:is2%end, is3%beg:is3%end, adv_idx%beg:adv_idx%end)) end if ! Allocating the cell-width distribution in the s-direction @@ -272,7 +212,6 @@ contains end if ! Allocating/Computing CBC Coefficients in x-direction if (all((/bc_x%beg, bc_x%end/) <= -5) .and. all((/bc_x%beg, bc_x%end/) >= -13)) then - @:ALLOCATE(fd_coef_x(0:buff_size, -1:1)) if (weno_order > 1 .or. muscl_order > 1) then @@ -281,9 +220,7 @@ contains call s_compute_cbc_coefficients(1, -1) call s_compute_cbc_coefficients(1, 1) - - elseif (bc_x%beg <= -5 .and. bc_x%beg >= -13) then - + else if (bc_x%beg <= -5 .and. bc_x%beg >= -13) then @:ALLOCATE(fd_coef_x(0:buff_size, -1:-1)) if (weno_order > 1 .or. muscl_order > 1) then @@ -291,9 +228,7 @@ contains end if call s_compute_cbc_coefficients(1, -1) - - elseif (bc_x%end <= -5 .and. bc_x%end >= -13) then - + else if (bc_x%end <= -5 .and. bc_x%end >= -13) then @:ALLOCATE(fd_coef_x(0:buff_size, 1:1)) if (weno_order > 1 .or. muscl_order > 1) then @@ -301,14 +236,11 @@ contains end if call s_compute_cbc_coefficients(1, 1) - end if ! Allocating/Computing CBC Coefficients in y-direction if (n > 0) then - if (all((/bc_y%beg, bc_y%end/) <= -5) .and. all((/bc_y%beg, bc_y%end/) >= -13)) then - @:ALLOCATE(fd_coef_y(0:buff_size, -1:1)) if (weno_order > 1 .or. muscl_order > 1) then @@ -317,9 +249,7 @@ contains call s_compute_cbc_coefficients(2, -1) call s_compute_cbc_coefficients(2, 1) - - elseif (bc_y%beg <= -5 .and. bc_y%beg >= -13) then - + else if (bc_y%beg <= -5 .and. bc_y%beg >= -13) then @:ALLOCATE(fd_coef_y(0:buff_size, -1:-1)) if (weno_order > 1 .or. muscl_order > 1) then @@ -327,9 +257,7 @@ contains end if call s_compute_cbc_coefficients(2, -1) - - elseif (bc_y%end <= -5 .and. bc_y%end >= -13) then - + else if (bc_y%end <= -5 .and. bc_y%end >= -13) then @:ALLOCATE(fd_coef_y(0:buff_size, 1:1)) if (weno_order > 1 .or. muscl_order > 1) then @@ -337,16 +265,12 @@ contains end if call s_compute_cbc_coefficients(2, 1) - end if - end if ! Allocating/Computing CBC Coefficients in z-direction if (p > 0) then - if (all((/bc_z%beg, bc_z%end/) <= -5) .and. all((/bc_z%beg, bc_z%end/) >= -13)) then - @:ALLOCATE(fd_coef_z(0:buff_size, -1:1)) if (weno_order > 1 .or. muscl_order > 1) then @@ -355,9 +279,7 @@ contains call s_compute_cbc_coefficients(3, -1) call s_compute_cbc_coefficients(3, 1) - - elseif (bc_z%beg <= -5 .and. bc_z%beg >= -13) then - + else if (bc_z%beg <= -5 .and. bc_z%beg >= -13) then @:ALLOCATE(fd_coef_z(0:buff_size, -1:-1)) if (weno_order > 1 .or. muscl_order > 1) then @@ -365,9 +287,7 @@ contains end if call s_compute_cbc_coefficients(3, -1) - - elseif (bc_z%end <= -5 .and. bc_z%end >= -13) then - + else if (bc_z%end <= -5 .and. bc_z%end >= -13) then @:ALLOCATE(fd_coef_z(0:buff_size, 1:1)) if (weno_order > 1 .or. muscl_order > 1) then @@ -375,16 +295,13 @@ contains end if call s_compute_cbc_coefficients(3, 1) - end if - end if - $:GPU_UPDATE(device='[fd_coef_x,fd_coef_y,fd_coef_z, & - & pi_coef_x,pi_coef_y,pi_coef_z]') + $:GPU_UPDATE(device='[fd_coef_x, fd_coef_y, fd_coef_z, pi_coef_x, pi_coef_y, pi_coef_z]') - ! Associating the procedural pointer to the appropriate subroutine - ! that will be utilized in the conversion to the mixture variables + ! Associating the procedural pointer to the appropriate subroutine that will be utilized in the conversion to the mixture + ! variables bcxb = bc_x%beg bcxe = bc_x%end @@ -434,17 +351,17 @@ contains end do end if #:endfor - $:GPU_UPDATE(device='[vel_in,vel_out,pres_in,pres_out,Del_in,Del_out,alpha_rho_in,alpha_in]') + $:GPU_UPDATE(device='[vel_in, vel_out, pres_in, pres_out, Del_in, Del_out, alpha_rho_in, alpha_in]') end subroutine s_initialize_cbc_module - !> Compute CBC coefficients - !! @param cbc_dir_in CBC coordinate direction - !! @param cbc_loc_in CBC coordinate location + !> Compute CBC coefficients + !! @param cbc_dir_in CBC coordinate direction + !! @param cbc_loc_in CBC coordinate location subroutine s_compute_cbc_coefficients(cbc_dir_in, cbc_loc_in) - ! Description: The purpose of this subroutine is to compute the grid - ! dependent FD and PI coefficients, or CBC coefficients, - ! provided the CBC coordinate direction and location. + + ! Description: The purpose of this subroutine is to compute the grid dependent FD and PI coefficients, or CBC coefficients, + ! provided the CBC coordinate direction and location. ! CBC coordinate direction and location integer, intent(in) :: cbc_dir_in, cbc_loc_in @@ -456,6 +373,7 @@ contains integer :: i ! Associating CBC coefficients pointers + call s_associate_cbc_coefficients_pointers(cbc_dir_in, cbc_loc_in) ! Determining the cell-boundary locations in the s-direction @@ -469,15 +387,13 @@ contains #:for CBC_DIR, XYZ in [(1, 'x'), (2, 'y'), (3, 'z')] if (cbc_dir_in == ${CBC_DIR}$ .and. recon_type == WENO_TYPE) then if (weno_order == 1) then - - fd_coef_${XYZ}$ (:, cbc_loc_in) = 0._wp + fd_coef_${XYZ}$ (:,cbc_loc_in) = 0._wp fd_coef_${XYZ}$ (0, cbc_loc_in) = -2._wp/(ds(0) + ds(1)) fd_coef_${XYZ}$ (1, cbc_loc_in) = -fd_coef_${XYZ}$ (0, cbc_loc_in) ! Computing CBC2 Coefficients - elseif (weno_order == 3) then - - fd_coef_${XYZ}$ (:, cbc_loc_in) = 0._wp + else if (weno_order == 3) then + fd_coef_${XYZ}$ (:,cbc_loc_in) = 0._wp fd_coef_${XYZ}$ (0, cbc_loc_in) = -6._wp/(3._wp*ds(0) + 2._wp*ds(1) - ds(2)) fd_coef_${XYZ}$ (1, cbc_loc_in) = -4._wp*fd_coef_${XYZ}$ (0, cbc_loc_in)/3._wp fd_coef_${XYZ}$ (2, cbc_loc_in) = fd_coef_${XYZ}$ (0, cbc_loc_in)/3._wp @@ -486,49 +402,36 @@ contains ! Computing CBC4 Coefficients else - - fd_coef_${XYZ}$ (:, cbc_loc_in) = 0._wp - fd_coef_${XYZ}$ (0, cbc_loc_in) = -50._wp/(25._wp*ds(0) + 2._wp*ds(1) & - - 1.e1_wp*ds(2) + 1.e1_wp*ds(3) & - - 3._wp*ds(4)) + fd_coef_${XYZ}$ (:,cbc_loc_in) = 0._wp + fd_coef_${XYZ}$ (0, & + & cbc_loc_in) = -50._wp/(25._wp*ds(0) + 2._wp*ds(1) - 1.e1_wp*ds(2) + 1.e1_wp*ds(3) & + & - 3._wp*ds(4)) fd_coef_${XYZ}$ (1, cbc_loc_in) = -48._wp*fd_coef_${XYZ}$ (0, cbc_loc_in)/25._wp fd_coef_${XYZ}$ (2, cbc_loc_in) = 36._wp*fd_coef_${XYZ}$ (0, cbc_loc_in)/25._wp fd_coef_${XYZ}$ (3, cbc_loc_in) = -16._wp*fd_coef_${XYZ}$ (0, cbc_loc_in)/25._wp fd_coef_${XYZ}$ (4, cbc_loc_in) = 3._wp*fd_coef_${XYZ}$ (0, cbc_loc_in)/25._wp - pi_coef_${XYZ}$ (0, 0, cbc_loc_in) = & - ((s_cb(0) - s_cb(1))*(s_cb(1) - s_cb(2))* & - (s_cb(1) - s_cb(3)))/((s_cb(1) - s_cb(4))* & - (s_cb(4) - s_cb(0))*(s_cb(4) - s_cb(2))) - pi_coef_${XYZ}$ (0, 1, cbc_loc_in) = & - ((s_cb(1) - s_cb(0))*(s_cb(1) - s_cb(2))* & - ((s_cb(1) - s_cb(3))*(s_cb(1) - s_cb(3)) - & - (s_cb(0) - s_cb(4))*((s_cb(3) - s_cb(1)) + & - (s_cb(4) - s_cb(1)))))/ & - ((s_cb(0) - s_cb(3))*(s_cb(1) - s_cb(3))* & - (s_cb(0) - s_cb(4))*(s_cb(1) - s_cb(4))) - pi_coef_${XYZ}$ (0, 2, cbc_loc_in) = & - (s_cb(1) - s_cb(0))*((s_cb(1) - s_cb(2))* & - (s_cb(1) - s_cb(3)) + ((s_cb(0) - s_cb(2)) + & - (s_cb(1) - s_cb(3)))*(s_cb(0) - s_cb(4)))/ & - ((s_cb(2) - s_cb(0))*(s_cb(0) - s_cb(3))* & - (s_cb(0) - s_cb(4))) - pi_coef_${XYZ}$ (1, 0, cbc_loc_in) = & - ((s_cb(0) - s_cb(2))*(s_cb(2) - s_cb(1))* & - (s_cb(2) - s_cb(3)))/((s_cb(2) - s_cb(4))* & - (s_cb(4) - s_cb(0))*(s_cb(4) - s_cb(1))) - pi_coef_${XYZ}$ (1, 1, cbc_loc_in) = & - ((s_cb(0) - s_cb(2))*(s_cb(1) - s_cb(2))* & - ((s_cb(1) - s_cb(3))*(s_cb(2) - s_cb(3)) + & - (s_cb(0) - s_cb(4))*((s_cb(1) - s_cb(3)) + & - (s_cb(2) - s_cb(4)))))/ & - ((s_cb(0) - s_cb(3))*(s_cb(1) - s_cb(3))* & - (s_cb(0) - s_cb(4))*(s_cb(1) - s_cb(4))) - pi_coef_${XYZ}$ (1, 2, cbc_loc_in) = & - ((s_cb(1) - s_cb(2))*(s_cb(2) - s_cb(3))* & - (s_cb(2) - s_cb(4)))/((s_cb(0) - s_cb(2))* & - (s_cb(0) - s_cb(3))*(s_cb(0) - s_cb(4))) - + pi_coef_${XYZ}$ (0, 0, & + & cbc_loc_in) = ((s_cb(0) - s_cb(1))*(s_cb(1) - s_cb(2))*(s_cb(1) - s_cb(3)))/((s_cb(1) & + & - s_cb(4))*(s_cb(4) - s_cb(0))*(s_cb(4) - s_cb(2))) + pi_coef_${XYZ}$ (0, 1, & + & cbc_loc_in) = ((s_cb(1) - s_cb(0))*(s_cb(1) - s_cb(2))*((s_cb(1) - s_cb(3))*(s_cb(1) & + & - s_cb(3)) - (s_cb(0) - s_cb(4))*((s_cb(3) - s_cb(1)) + (s_cb(4) - s_cb(1)))))/((s_cb(0) & + & - s_cb(3))*(s_cb(1) - s_cb(3))*(s_cb(0) - s_cb(4))*(s_cb(1) - s_cb(4))) + pi_coef_${XYZ}$ (0, 2, & + & cbc_loc_in) = (s_cb(1) - s_cb(0))*((s_cb(1) - s_cb(2))*(s_cb(1) - s_cb(3)) + ((s_cb(0) & + & - s_cb(2)) + (s_cb(1) - s_cb(3)))*(s_cb(0) - s_cb(4)))/((s_cb(2) - s_cb(0))*(s_cb(0) & + & - s_cb(3))*(s_cb(0) - s_cb(4))) + pi_coef_${XYZ}$ (1, 0, & + & cbc_loc_in) = ((s_cb(0) - s_cb(2))*(s_cb(2) - s_cb(1))*(s_cb(2) - s_cb(3)))/((s_cb(2) & + & - s_cb(4))*(s_cb(4) - s_cb(0))*(s_cb(4) - s_cb(1))) + pi_coef_${XYZ}$ (1, 1, & + & cbc_loc_in) = ((s_cb(0) - s_cb(2))*(s_cb(1) - s_cb(2))*((s_cb(1) - s_cb(3))*(s_cb(2) & + & - s_cb(3)) + (s_cb(0) - s_cb(4))*((s_cb(1) - s_cb(3)) + (s_cb(2) - s_cb(4)))))/((s_cb(0) & + & - s_cb(3))*(s_cb(1) - s_cb(3))*(s_cb(0) - s_cb(4))*(s_cb(1) - s_cb(4))) + pi_coef_${XYZ}$ (1, 2, & + & cbc_loc_in) = ((s_cb(1) - s_cb(2))*(s_cb(2) - s_cb(3))*(s_cb(2) - s_cb(4)))/((s_cb(0) & + & - s_cb(2))*(s_cb(0) - s_cb(3))*(s_cb(0) - s_cb(4))) end if end if #:endfor @@ -539,23 +442,20 @@ contains end subroutine s_compute_cbc_coefficients - !> @brief Associates finite-difference and polynomial-interpolation CBC coefficients with targets based on coordinate direction and boundary location. - !! The goal of the procedure is to associate the FD and PI - !! coefficients, or CBC coefficients, with the appropriate - !! targets, based on the coordinate direction and location - !! of the CBC. - !! @param cbc_dir_in CBC coordinate direction - !! @param cbc_loc_in CBC coordinate location + !> @brief Associates finite-difference and polynomial-interpolation CBC coefficients with targets based on coordinate direction + !! and boundary location. The goal of the procedure is to associate the FD and PI coefficients, or CBC coefficients, with the + !! appropriate targets, based on the coordinate direction and location of the CBC. + !! @param cbc_dir_in CBC coordinate direction + !! @param cbc_loc_in CBC coordinate location subroutine s_associate_cbc_coefficients_pointers(cbc_dir_in, cbc_loc_in) integer, intent(in) :: cbc_dir_in, cbc_loc_in - - integer :: i !< Generic loop iterator + integer :: i !< Generic loop iterator ! Associating CBC Coefficients in x-direction - if (cbc_dir_in == 1) then - !fd_coef => fd_coef_x; if (weno_order > 1) pi_coef => pi_coef_x + if (cbc_dir_in == 1) then + ! fd_coef => fd_coef_x; if (weno_order > 1) pi_coef => pi_coef_x if (cbc_loc_in == -1) then do i = 0, buff_size @@ -568,9 +468,8 @@ contains end if ! Associating CBC Coefficients in y-direction - elseif (cbc_dir_in == 2) then - - !fd_coef => fd_coef_y; if (weno_order > 1) pi_coef => pi_coef_y + else if (cbc_dir_in == 2) then + ! fd_coef => fd_coef_y; if (weno_order > 1) pi_coef => pi_coef_y if (cbc_loc_in == -1) then do i = 0, buff_size @@ -584,8 +483,7 @@ contains ! Associating CBC Coefficients in z-direction else - - !fd_coef => fd_coef_z; if (weno_order > 1) pi_coef => pi_coef_z + ! fd_coef => fd_coef_z; if (weno_order > 1) pi_coef => pi_coef_z if (cbc_loc_in == -1) then do i = 0, buff_size @@ -596,90 +494,75 @@ contains ds(i) = dz(p - i) end do end if - end if $:GPU_UPDATE(device='[ds]') end subroutine s_associate_cbc_coefficients_pointers - !> The following is the implementation of the CBC based on - !! the work of Thompson (1987, 1990) on hyperbolic systems. - !! The CBC is indirectly applied in the computation of the - !! right-hand-side (RHS) near the relevant domain boundary - !! through the modification of the fluxes. - !! @param q_prim_vf Cell-average primitive variables - !! @param flux_vf Cell-boundary-average fluxes - !! @param flux_src_vf Cell-boundary-average flux sources - !! @param cbc_dir_norm CBC coordinate direction - !! @param cbc_loc_norm CBC coordinate location - !! @param ix Index bound in the first coordinate direction - !! @param iy Index bound in the second coordinate direction - !! @param iz Index bound in the third coordinate direction - subroutine s_cbc(q_prim_vf, flux_vf, flux_src_vf, & - cbc_dir_norm, cbc_loc_norm, & - ix, iy, iz) - - type(scalar_field), & - dimension(sys_size), & - intent(in) :: q_prim_vf - - type(scalar_field), & - dimension(sys_size), & - intent(inout) :: flux_vf, flux_src_vf - - integer, intent(in) :: cbc_dir_norm, cbc_loc_norm - - type(int_bounds_info), intent(in) :: ix, iy, iz - real(wp) :: drho_dt - real(wp) :: dpres_dt - real(wp) :: dgamma_dt - real(wp) :: dpi_inf_dt - real(wp) :: dqv_dt - real(wp) :: dpres_ds + !> The following is the implementation of the CBC based on the work of Thompson (1987, 1990) on hyperbolic systems. The CBC is + !! indirectly applied in the computation of the right-hand-side (RHS) near the relevant domain boundary through the modification + !! of the fluxes. + !! @param q_prim_vf Cell-average primitive variables + !! @param flux_vf Cell-boundary-average fluxes + !! @param flux_src_vf Cell-boundary-average flux sources + !! @param cbc_dir_norm CBC coordinate direction + !! @param cbc_loc_norm CBC coordinate location + !! @param ix Index bound in the first coordinate direction + !! @param iy Index bound in the second coordinate direction + !! @param iz Index bound in the third coordinate direction + subroutine s_cbc(q_prim_vf, flux_vf, flux_src_vf, cbc_dir_norm, cbc_loc_norm, ix, iy, iz) + + type(scalar_field), dimension(sys_size), intent(in) :: q_prim_vf + type(scalar_field), dimension(sys_size), intent(inout) :: flux_vf, flux_src_vf + integer, intent(in) :: cbc_dir_norm, cbc_loc_norm + type(int_bounds_info), intent(in) :: ix, iy, iz + real(wp) :: drho_dt + real(wp) :: dpres_dt + real(wp) :: dgamma_dt + real(wp) :: dpi_inf_dt + real(wp) :: dqv_dt + real(wp) :: dpres_ds + #:if USING_AMD real(wp), dimension(20) :: L #:else real(wp), dimension(sys_size) :: L #:endif #:if not MFC_CASE_OPTIMIZATION and USING_AMD - real(wp), dimension(3) :: alpha_rho, dalpha_rho_ds, mf - real(wp), dimension(3) :: vel, dvel_ds - real(wp), dimension(3) :: adv_local, dadv_ds - real(wp), dimension(3) :: dadv_dt - real(wp), dimension(3) :: dvel_dt - real(wp), dimension(3) :: dalpha_rho_dt + real(wp), dimension(3) :: alpha_rho, dalpha_rho_ds, mf + real(wp), dimension(3) :: vel, dvel_ds + real(wp), dimension(3) :: adv_local, dadv_ds + real(wp), dimension(3) :: dadv_dt + real(wp), dimension(3) :: dvel_dt + real(wp), dimension(3) :: dalpha_rho_dt real(wp), dimension(10) :: Ys, h_k, dYs_dt, dYs_ds, Xs, Gamma_i, Cp_i #:else - real(wp), dimension(num_fluids) :: alpha_rho, dalpha_rho_ds, mf - real(wp), dimension(num_vels) :: vel, dvel_ds - real(wp), dimension(num_fluids) :: adv_local, dadv_ds - real(wp), dimension(num_fluids) :: dadv_dt - real(wp), dimension(num_dims) :: dvel_dt - real(wp), dimension(num_fluids) :: dalpha_rho_dt + real(wp), dimension(num_fluids) :: alpha_rho, dalpha_rho_ds, mf + real(wp), dimension(num_vels) :: vel, dvel_ds + real(wp), dimension(num_fluids) :: adv_local, dadv_ds + real(wp), dimension(num_fluids) :: dadv_dt + real(wp), dimension(num_dims) :: dvel_dt + real(wp), dimension(num_fluids) :: dalpha_rho_dt real(wp), dimension(num_species) :: Ys, h_k, dYs_dt, dYs_ds, Xs, Gamma_i, Cp_i #:endif real(wp), dimension(2) :: Re_cbc real(wp), dimension(3) :: lambda - - real(wp) :: rho !< Cell averaged density - real(wp) :: pres !< Cell averaged pressure - real(wp) :: E !< Cell averaged energy - real(wp) :: H !< Cell averaged enthalpy - real(wp) :: gamma !< Cell averaged specific heat ratio - real(wp) :: pi_inf !< Cell averaged liquid stiffness - real(wp) :: qv !< Cell averaged fluid reference energy - real(wp) :: c - real(wp) :: Ma - real(wp) :: T, sum_Enthalpies - real(wp) :: Cv, Cp, e_mix, Mw, R_gas - - real(wp) :: vel_K_sum, vel_dv_dt_sum - - integer :: i, j, k, r !< Generic loop iterators - - ! Reshaping of inputted data and association of the FD and PI - ! coefficients, or CBC coefficients, respectively, hinging on + real(wp) :: rho !< Cell averaged density + real(wp) :: pres !< Cell averaged pressure + real(wp) :: E !< Cell averaged energy + real(wp) :: H !< Cell averaged enthalpy + real(wp) :: gamma !< Cell averaged specific heat ratio + real(wp) :: pi_inf !< Cell averaged liquid stiffness + real(wp) :: qv !< Cell averaged fluid reference energy + real(wp) :: c + real(wp) :: Ma + real(wp) :: T, sum_Enthalpies + real(wp) :: Cv, Cp, e_mix, Mw, R_gas + real(wp) :: vel_K_sum, vel_dv_dt_sum + integer :: i, j, k, r !< Generic loop iterators + + ! Reshaping of inputted data and association of the FD and PI coefficients, or CBC coefficients, respectively, hinging on ! selected CBC coordinate direction cbc_dir = cbc_dir_norm @@ -687,43 +570,34 @@ contains $:GPU_UPDATE(device='[cbc_dir, cbc_loc]') - call s_initialize_cbc(q_prim_vf, flux_vf, flux_src_vf, & - ix, iy, iz) + call s_initialize_cbc(q_prim_vf, flux_vf, flux_src_vf, ix, iy, iz) call s_associate_cbc_coefficients_pointers(cbc_dir, cbc_loc) #:for CBC_DIR, XYZ in [(1, 'x'), (2, 'y'), (3, 'z')] if (cbc_dir == ${CBC_DIR}$ .and. recon_type == WENO_TYPE) then - ! PI2 of flux_rs_vf and flux_src_rs_vf at j = 1/2 if (weno_order == 3 .or. dummy) then + call s_convert_primitive_to_flux_variables(q_prim_rs${XYZ}$_vf, F_rs${XYZ}$_vf, F_src_rs${XYZ}$_vf, is1, is2, & + & is3, idwbuff(2)%beg, idwbuff(3)%beg) - call s_convert_primitive_to_flux_variables(q_prim_rs${XYZ}$_vf, & - F_rs${XYZ}$_vf, & - F_src_rs${XYZ}$_vf, & - is1, is2, is3, idwbuff(2)%beg, idwbuff(3)%beg) - - $:GPU_PARALLEL_LOOP(private='[i,r,k]', collapse=3) + $:GPU_PARALLEL_LOOP(private='[i, r, k]', collapse=3) do i = 1, flux_cbc_index do r = is3%beg, is3%end do k = is2%beg, is2%end - flux_rs${XYZ}$_vf_l(0, k, r, i) = F_rs${XYZ}$_vf(0, k, r, i) & - + pi_coef_${XYZ}$ (0, 0, cbc_loc)* & - (F_rs${XYZ}$_vf(1, k, r, i) - & - F_rs${XYZ}$_vf(0, k, r, i)) + flux_rs${XYZ}$_vf_l(0, k, r, i) = F_rs${XYZ}$_vf(0, k, r, i) + pi_coef_${XYZ}$ (0, 0, & + & cbc_loc)*(F_rs${XYZ}$_vf(1, k, r, i) - F_rs${XYZ}$_vf(0, k, r, i)) end do end do end do $:END_GPU_PARALLEL_LOOP() - $:GPU_PARALLEL_LOOP(private='[i,r,k]', collapse=3) + $:GPU_PARALLEL_LOOP(private='[i, r, k]', collapse=3) do i = advxb, advxe do r = is3%beg, is3%end do k = is2%beg, is2%end - flux_src_rs${XYZ}$_vf_l(0, k, r, i) = F_src_rs${XYZ}$_vf(0, k, r, i) + & - (F_src_rs${XYZ}$_vf(1, k, r, i) - & - F_src_rs${XYZ}$_vf(0, k, r, i)) & - *pi_coef_${XYZ}$ (0, 0, cbc_loc) + flux_src_rs${XYZ}$_vf_l(0, k, r, i) = F_src_rs${XYZ}$_vf(0, k, r, i) + (F_src_rs${XYZ}$_vf(1, k, & + & r, i) - F_src_rs${XYZ}$_vf(0, k, r, i))*pi_coef_${XYZ}$ (0, 0, cbc_loc) end do end do end do @@ -732,60 +606,51 @@ contains ! PI4 of flux_rs_vf and flux_src_rs_vf at j = 1/2, 3/2 if (weno_order == 5 .or. dummy) then - call s_convert_primitive_to_flux_variables(q_prim_rs${XYZ}$_vf, & - F_rs${XYZ}$_vf, & - F_src_rs${XYZ}$_vf, & - is1, is2, is3, idwbuff(2)%beg, idwbuff(3)%beg) + call s_convert_primitive_to_flux_variables(q_prim_rs${XYZ}$_vf, F_rs${XYZ}$_vf, F_src_rs${XYZ}$_vf, is1, is2, & + & is3, idwbuff(2)%beg, idwbuff(3)%beg) - $:GPU_PARALLEL_LOOP(private='[i,j,r,k]', collapse=4) + $:GPU_PARALLEL_LOOP(private='[i, j, r, k]', collapse=4) do i = 1, flux_cbc_index do j = 0, 1 do r = is3%beg, is3%end do k = is2%beg, is2%end - flux_rs${XYZ}$_vf_l(j, k, r, i) = F_rs${XYZ}$_vf(j, k, r, i) & - + pi_coef_${XYZ}$ (j, 0, cbc_loc)* & - (F_rs${XYZ}$_vf(3, k, r, i) - & - F_rs${XYZ}$_vf(2, k, r, i)) & - + pi_coef_${XYZ}$ (j, 1, cbc_loc)* & - (F_rs${XYZ}$_vf(2, k, r, i) - & - F_rs${XYZ}$_vf(1, k, r, i)) & - + pi_coef_${XYZ}$ (j, 2, cbc_loc)* & - (F_rs${XYZ}$_vf(1, k, r, i) - & - F_rs${XYZ}$_vf(0, k, r, i)) + flux_rs${XYZ}$_vf_l(j, k, r, i) = F_rs${XYZ}$_vf(j, k, r, i) + pi_coef_${XYZ}$ (j, 0, & + & cbc_loc)*(F_rs${XYZ}$_vf(3, k, r, i) - F_rs${XYZ}$_vf(2, k, r, & + & i)) + pi_coef_${XYZ}$ (j, 1, cbc_loc)*(F_rs${XYZ}$_vf(2, k, r, & + & i) - F_rs${XYZ}$_vf(1, k, r, i)) + pi_coef_${XYZ}$ (j, 2, & + & cbc_loc)*(F_rs${XYZ}$_vf(1, k, r, i) - F_rs${XYZ}$_vf(0, k, r, i)) end do end do end do end do $:END_GPU_PARALLEL_LOOP() - $:GPU_PARALLEL_LOOP(private='[i,j,r,k]', collapse=4) + $:GPU_PARALLEL_LOOP(private='[i, j, r, k]', collapse=4) do i = advxb, advxe do j = 0, 1 do r = is3%beg, is3%end do k = is2%beg, is2%end - flux_src_rs${XYZ}$_vf_l(j, k, r, i) = F_src_rs${XYZ}$_vf(j, k, r, i) + & - (F_src_rs${XYZ}$_vf(3, k, r, i) - & - F_src_rs${XYZ}$_vf(2, k, r, i)) & - *pi_coef_${XYZ}$ (j, 0, cbc_loc) + & - (F_src_rs${XYZ}$_vf(2, k, r, i) - & - F_src_rs${XYZ}$_vf(1, k, r, i)) & - *pi_coef_${XYZ}$ (j, 1, cbc_loc) + & - (F_src_rs${XYZ}$_vf(1, k, r, i) - & - F_src_rs${XYZ}$_vf(0, k, r, i)) & - *pi_coef_${XYZ}$ (j, 2, cbc_loc) + flux_src_rs${XYZ}$_vf_l(j, k, r, i) = F_src_rs${XYZ}$_vf(j, k, r, i) + (F_src_rs${XYZ}$_vf(3, & + & k, r, i) - F_src_rs${XYZ}$_vf(2, k, r, i))*pi_coef_${XYZ}$ (j, 0, & + & cbc_loc) + (F_src_rs${XYZ}$_vf(2, k, r, i) - F_src_rs${XYZ}$_vf(1, & + & k, r, i))*pi_coef_${XYZ}$ (j, 1, cbc_loc) + (F_src_rs${XYZ}$_vf(1, & + & k, r, i) - F_src_rs${XYZ}$_vf(0, k, r, i))*pi_coef_${XYZ}$ (j, 2, & + & cbc_loc) end do end do end do end do $:END_GPU_PARALLEL_LOOP() - end if ! FD2 or FD4 of RHS at j = 0 - $:GPU_PARALLEL_LOOP(collapse=2, private='[r,k,alpha_rho, vel, adv_local, mf, dvel_ds, dadv_ds, Re_cbc, dalpha_rho_ds, dpres_ds, dvel_dt, dadv_dt, dalpha_rho_dt, L, lambda, Ys, dYs_dt, dYs_ds, h_k, Cp_i, Gamma_i, Xs, drho_dt, dpres_dt, dpi_inf_dt, dqv_dt, dgamma_dt, rho, pres, E, H, gamma, pi_inf, qv, c, Ma, T, sum_Enthalpies, Cv, Cp, e_mix, Mw, R_gas, vel_K_sum, vel_dv_dt_sum, i, j]', copyin='[dir_idx]') + $:GPU_PARALLEL_LOOP(collapse=2, private='[r, k, alpha_rho, vel, adv_local, mf, dvel_ds, dadv_ds, Re_cbc, & + & dalpha_rho_ds, dpres_ds, dvel_dt, dadv_dt, dalpha_rho_dt, L, lambda, Ys, dYs_dt, dYs_ds, & + & h_k, Cp_i, Gamma_i, Xs, drho_dt, dpres_dt, dpi_inf_dt, dqv_dt, dgamma_dt, rho, pres, E, H, & + & gamma, pi_inf, qv, c, Ma, T, sum_Enthalpies, Cv, Cp, e_mix, Mw, R_gas, vel_K_sum, & + & vel_dv_dt_sum, i, j]', copyin='[dir_idx]') do r = is3%beg, is3%end do k = is2%beg, is2%end - ! Transferring the Primitive Variables $:GPU_LOOP(parallelism='[seq]') do i = 1, contxe @@ -876,36 +741,26 @@ contains $:GPU_LOOP(parallelism='[seq]') do j = 0, buff_size - $:GPU_LOOP(parallelism='[seq]') do i = 1, contxe - dalpha_rho_ds(i) = q_prim_rs${XYZ}$_vf(j, k, r, i)* & - fd_coef_${XYZ}$ (j, cbc_loc) + & - dalpha_rho_ds(i) + dalpha_rho_ds(i) = q_prim_rs${XYZ}$_vf(j, k, r, i)*fd_coef_${XYZ}$ (j, cbc_loc) + dalpha_rho_ds(i) end do $:GPU_LOOP(parallelism='[seq]') do i = 1, num_dims - dvel_ds(i) = q_prim_rs${XYZ}$_vf(j, k, r, contxe + i)* & - fd_coef_${XYZ}$ (j, cbc_loc) + & - dvel_ds(i) + dvel_ds(i) = q_prim_rs${XYZ}$_vf(j, k, r, contxe + i)*fd_coef_${XYZ}$ (j, cbc_loc) + dvel_ds(i) end do - dpres_ds = q_prim_rs${XYZ}$_vf(j, k, r, E_idx)* & - fd_coef_${XYZ}$ (j, cbc_loc) + & - dpres_ds + dpres_ds = q_prim_rs${XYZ}$_vf(j, k, r, E_idx)*fd_coef_${XYZ}$ (j, cbc_loc) + dpres_ds $:GPU_LOOP(parallelism='[seq]') do i = 1, advxe - E_idx - dadv_ds(i) = q_prim_rs${XYZ}$_vf(j, k, r, E_idx + i)* & - fd_coef_${XYZ}$ (j, cbc_loc) + & - dadv_ds(i) + dadv_ds(i) = q_prim_rs${XYZ}$_vf(j, k, r, E_idx + i)*fd_coef_${XYZ}$ (j, cbc_loc) + dadv_ds(i) end do if (chemistry) then $:GPU_LOOP(parallelism='[seq]') do i = 1, num_species - dYs_ds(i) = q_prim_rs${XYZ}$_vf(j, k, r, chemxb - 1 + i)* & - fd_coef_${XYZ}$ (j, cbc_loc) + & - dYs_ds(i) + dYs_ds(i) = q_prim_rs${XYZ}$_vf(j, k, r, chemxb - 1 + i)*fd_coef_${XYZ}$ (j, & + & cbc_loc) + dYs_ds(i) end do end if end do @@ -917,20 +772,22 @@ contains Ma = vel(dir_idx(1))/c - if ((cbc_loc == -1 .and. bc${XYZ}$b == BC_CHAR_SLIP_WALL) .or. & - (cbc_loc == 1 .and. bc${XYZ}$e == BC_CHAR_SLIP_WALL)) then + if ((cbc_loc == -1 .and. bc${XYZ}$b == BC_CHAR_SLIP_WALL) & + & .or. (cbc_loc == 1 .and. bc${XYZ}$e == BC_CHAR_SLIP_WALL)) then call s_compute_slip_wall_L(lambda, L, rho, c, dpres_ds, dvel_ds) - else if ((cbc_loc == -1 .and. bc${XYZ}$b == BC_CHAR_NR_SUB_BUFFER) .or. & - (cbc_loc == 1 .and. bc${XYZ}$e == BC_CHAR_NR_SUB_BUFFER)) then - call s_compute_nonreflecting_subsonic_buffer_L(lambda, L, rho, c, mf, dalpha_rho_ds, dpres_ds, dvel_ds, dadv_ds, dYs_ds) - else if ((cbc_loc == -1 .and. bc${XYZ}$b == BC_CHAR_NR_SUB_INFLOW) .or. & - (cbc_loc == 1 .and. bc${XYZ}$e == BC_CHAR_NR_SUB_INFLOW)) then + else if ((cbc_loc == -1 .and. bc${XYZ}$b == BC_CHAR_NR_SUB_BUFFER) & + & .or. (cbc_loc == 1 .and. bc${XYZ}$e == BC_CHAR_NR_SUB_BUFFER)) then + call s_compute_nonreflecting_subsonic_buffer_L(lambda, L, rho, c, mf, dalpha_rho_ds, dpres_ds, & + & dvel_ds, dadv_ds, dYs_ds) + else if ((cbc_loc == -1 .and. bc${XYZ}$b == BC_CHAR_NR_SUB_INFLOW) & + & .or. (cbc_loc == 1 .and. bc${XYZ}$e == BC_CHAR_NR_SUB_INFLOW)) then call s_compute_nonreflecting_subsonic_inflow_L(lambda, L, rho, c, dpres_ds, dvel_ds) ! Add GRCBC for Subsonic Inflow if (bc_${XYZ}$%grcbc_in) then $:GPU_LOOP(parallelism='[seq]') do i = 2, momxb - L(i) = c**3._wp*Ma*(alpha_rho(i - 1) - alpha_rho_in(i - 1, ${CBC_DIR}$))/Del_in(${CBC_DIR}$) - c*Ma*(pres - pres_in(${CBC_DIR}$))/Del_in(${CBC_DIR}$) + L(i) = c**3._wp*Ma*(alpha_rho(i - 1) - alpha_rho_in(i - 1, & + & ${CBC_DIR}$))/Del_in(${CBC_DIR}$) - c*Ma*(pres - pres_in(${CBC_DIR}$))/Del_in(${CBC_DIR}$) end do if (n > 0) then L(momxb + 1) = c*Ma*(vel(dir_idx(2)) - vel_in(${CBC_DIR}$, dir_idx(2)))/Del_in(${CBC_DIR}$) @@ -940,56 +797,59 @@ contains end if $:GPU_LOOP(parallelism='[seq]') do i = E_idx, advxe - 1 - L(i) = c*Ma*(adv_local(i + 1 - E_idx) - alpha_in(i + 1 - E_idx, ${CBC_DIR}$))/Del_in(${CBC_DIR}$) + L(i) = c*Ma*(adv_local(i + 1 - E_idx) - alpha_in(i + 1 - E_idx, & + & ${CBC_DIR}$))/Del_in(${CBC_DIR}$) end do - L(advxe) = rho*c**2._wp*(1._wp + Ma)*(vel(dir_idx(1)) + vel_in(${CBC_DIR}$, dir_idx(1))*sign(1, cbc_loc))/Del_in(${CBC_DIR}$) + c*(1._wp + Ma)*(pres - pres_in(${CBC_DIR}$))/Del_in(${CBC_DIR}$) + L(advxe) = rho*c**2._wp*(1._wp + Ma)*(vel(dir_idx(1)) + vel_in(${CBC_DIR}$, dir_idx(1))*sign(1, & + & cbc_loc))/Del_in(${CBC_DIR}$) + c*(1._wp + Ma)*(pres - pres_in(${CBC_DIR}$))/Del_in(${CBC_DIR}$) end if - else if ((cbc_loc == -1 .and. bc${XYZ}$b == BC_CHAR_NR_SUB_OUTFLOW) .or. & - (cbc_loc == 1 .and. bc${XYZ}$e == BC_CHAR_NR_SUB_OUTFLOW)) then - call s_compute_nonreflecting_subsonic_outflow_L(lambda, L, rho, c, mf, dalpha_rho_ds, dpres_ds, dvel_ds, dadv_ds, dYs_ds) + else if ((cbc_loc == -1 .and. bc${XYZ}$b == BC_CHAR_NR_SUB_OUTFLOW) & + & .or. (cbc_loc == 1 .and. bc${XYZ}$e == BC_CHAR_NR_SUB_OUTFLOW)) then + call s_compute_nonreflecting_subsonic_outflow_L(lambda, L, rho, c, mf, dalpha_rho_ds, dpres_ds, & + & dvel_ds, dadv_ds, dYs_ds) ! Add GRCBC for Subsonic Outflow (Pressure) if (bc_${XYZ}$%grcbc_out) then L(advxe) = c*(1._wp - Ma)*(pres - pres_out(${CBC_DIR}$))/Del_out(${CBC_DIR}$) ! Add GRCBC for Subsonic Outflow (Normal Velocity) if (bc_${XYZ}$%grcbc_vel_out) then - L(advxe) = L(advxe) + rho*c**2._wp*(1._wp - Ma)*(vel(dir_idx(1)) + vel_out(${CBC_DIR}$, dir_idx(1))*sign(1, cbc_loc))/Del_out(${CBC_DIR}$) + L(advxe) = L(advxe) + rho*c**2._wp*(1._wp - Ma)*(vel(dir_idx(1)) + vel_out(${CBC_DIR}$, & + & dir_idx(1))*sign(1, cbc_loc))/Del_out(${CBC_DIR}$) end if end if - else if ((cbc_loc == -1 .and. bc${XYZ}$b == BC_CHAR_FF_SUB_OUTFLOW) .or. & - (cbc_loc == 1 .and. bc${XYZ}$e == BC_CHAR_FF_SUB_OUTFLOW)) then - call s_compute_force_free_subsonic_outflow_L(lambda, L, rho, c, mf, dalpha_rho_ds, dpres_ds, dvel_ds, dadv_ds) - else if ((cbc_loc == -1 .and. bc${XYZ}$b == BC_CHAR_CP_SUB_OUTFLOW) .or. & - (cbc_loc == 1 .and. bc${XYZ}$e == BC_CHAR_CP_SUB_OUTFLOW)) then - call s_compute_constant_pressure_subsonic_outflow_L(lambda, L, rho, c, mf, dalpha_rho_ds, dpres_ds, dvel_ds, dadv_ds) - else if ((cbc_loc == -1 .and. bc${XYZ}$b == BC_CHAR_SUP_INFLOW) .or. & - (cbc_loc == 1 .and. bc${XYZ}$e == BC_CHAR_SUP_INFLOW)) then + else if ((cbc_loc == -1 .and. bc${XYZ}$b == BC_CHAR_FF_SUB_OUTFLOW) & + & .or. (cbc_loc == 1 .and. bc${XYZ}$e == BC_CHAR_FF_SUB_OUTFLOW)) then + call s_compute_force_free_subsonic_outflow_L(lambda, L, rho, c, mf, dalpha_rho_ds, dpres_ds, dvel_ds, & + & dadv_ds) + else if ((cbc_loc == -1 .and. bc${XYZ}$b == BC_CHAR_CP_SUB_OUTFLOW) & + & .or. (cbc_loc == 1 .and. bc${XYZ}$e == BC_CHAR_CP_SUB_OUTFLOW)) then + call s_compute_constant_pressure_subsonic_outflow_L(lambda, L, rho, c, mf, dalpha_rho_ds, dpres_ds, & + & dvel_ds, dadv_ds) + else if ((cbc_loc == -1 .and. bc${XYZ}$b == BC_CHAR_SUP_INFLOW) & + & .or. (cbc_loc == 1 .and. bc${XYZ}$e == BC_CHAR_SUP_INFLOW)) then call s_compute_supersonic_inflow_L(L) - else if ((cbc_loc == -1 .and. bc${XYZ}$b == BC_CHAR_SUP_OUTFLOW) .or. & - (cbc_loc == 1 .and. bc${XYZ}$e == BC_CHAR_SUP_OUTFLOW)) then - call s_compute_supersonic_outflow_L(lambda, L, rho, c, mf, dalpha_rho_ds, dpres_ds, dvel_ds, dadv_ds, dYs_ds) + else if ((cbc_loc == -1 .and. bc${XYZ}$b == BC_CHAR_SUP_OUTFLOW) & + & .or. (cbc_loc == 1 .and. bc${XYZ}$e == BC_CHAR_SUP_OUTFLOW)) then + call s_compute_supersonic_outflow_L(lambda, L, rho, c, mf, dalpha_rho_ds, dpres_ds, dvel_ds, dadv_ds, & + & dYs_ds) end if ! Be careful about the cylindrical coordinate! if (cyl_coord .and. cbc_dir == 2 .and. cbc_loc == 1) then - dpres_dt = -5.e-1_wp*(L(advxe) + L(1)) + rho*c*c*vel(dir_idx(1)) & - /y_cc(n) + dpres_dt = -5.e-1_wp*(L(advxe) + L(1)) + rho*c*c*vel(dir_idx(1))/y_cc(n) else dpres_dt = -5.e-1_wp*(L(advxe) + L(1)) end if $:GPU_LOOP(parallelism='[seq]') do i = 1, contxe - dalpha_rho_dt(i) = & - -(L(i + 1) - mf(i)*dpres_dt)/(c*c) + dalpha_rho_dt(i) = -(L(i + 1) - mf(i)*dpres_dt)/(c*c) end do $:GPU_LOOP(parallelism='[seq]') do i = 1, num_dims - dvel_dt(dir_idx(i)) = dir_flg(dir_idx(i))* & - (L(1) - L(advxe))/(2._wp*rho*c) + & - (dir_flg(dir_idx(i)) - 1._wp)* & - L(momxb + i - 1) + dvel_dt(dir_idx(i)) = dir_flg(dir_idx(i))*(L(1) - L(advxe))/(2._wp*rho*c) + (dir_flg(dir_idx(i)) & + & - 1._wp)*L(momxb + i - 1) end do vel_dv_dt_sum = 0._wp @@ -1009,7 +869,7 @@ contains if (cyl_coord .and. cbc_dir == 2 .and. cbc_loc == 1) then $:GPU_LOOP(parallelism='[seq]') do i = 1, advxe - E_idx - dadv_dt(i) = -L(momxe + i) !+ adv_local(i) * vel(dir_idx(1))/y_cc(n) + dadv_dt(i) = -L(momxe + i) ! + adv_local(i) * vel(dir_idx(1))/y_cc(n) end do else $:GPU_LOOP(parallelism='[seq]') @@ -1039,47 +899,43 @@ contains ! flux_rs_vf_l and flux_src_rs_vf_l at j = -1/2 $:GPU_LOOP(parallelism='[seq]') do i = 1, contxe - flux_rs${XYZ}$_vf_l(-1, k, r, i) = flux_rs${XYZ}$_vf_l(0, k, r, i) & - + ds(0)*dalpha_rho_dt(i) + flux_rs${XYZ}$_vf_l(-1, k, r, i) = flux_rs${XYZ}$_vf_l(0, k, r, i) + ds(0)*dalpha_rho_dt(i) end do $:GPU_LOOP(parallelism='[seq]') do i = momxb, momxe - flux_rs${XYZ}$_vf_l(-1, k, r, i) = flux_rs${XYZ}$_vf_l(0, k, r, i) & - + ds(0)*(vel(i - contxe)*drho_dt & - + rho*dvel_dt(i - contxe)) + flux_rs${XYZ}$_vf_l(-1, k, r, i) = flux_rs${XYZ}$_vf_l(0, k, r, & + & i) + ds(0)*(vel(i - contxe)*drho_dt + rho*dvel_dt(i - contxe)) end do if (chemistry) then - ! Evolution of LODI equation of energy for real gases adjusted to perfect gas, doi:10.1006/jcph.2002.6990 + ! Evolution of LODI equation of energy for real gases adjusted to perfect gas, + ! doi:10.1006/jcph.2002.6990 call get_species_enthalpies_rt(T, h_k) sum_Enthalpies = 0._wp $:GPU_LOOP(parallelism='[seq]') do i = 1, num_species - #:if USING_AMD h_k(i) = h_k(i)*gas_constant/molecular_weights_nonparameter(i)*T - sum_Enthalpies = sum_Enthalpies + (rho*h_k(i) - pres*Mw/molecular_weights_nonparameter(i)*Cp/R_gas)*dYs_dt(i) + sum_Enthalpies = sum_Enthalpies + (rho*h_k(i) - pres*Mw/molecular_weights_nonparameter(i) & + & *Cp/R_gas)*dYs_dt(i) #:else h_k(i) = h_k(i)*gas_constant/molecular_weights(i)*T sum_Enthalpies = sum_Enthalpies + (rho*h_k(i) - pres*Mw/molecular_weights(i)*Cp/R_gas)*dYs_dt(i) #:endif end do - flux_rs${XYZ}$_vf_l(-1, k, r, E_idx) = flux_rs${XYZ}$_vf_l(0, k, r, E_idx) & - + ds(0)*((E/rho + pres/rho)*drho_dt + rho*vel_dv_dt_sum + Cp*T*L(2)/(c*c) + sum_Enthalpies) + flux_rs${XYZ}$_vf_l(-1, k, r, E_idx) = flux_rs${XYZ}$_vf_l(0, k, r, & + & E_idx) + ds(0)*((E/rho + pres/rho)*drho_dt + rho*vel_dv_dt_sum + Cp*T*L(2)/(c*c) & + & + sum_Enthalpies) $:GPU_LOOP(parallelism='[seq]') do i = 1, num_species - flux_rs${XYZ}$_vf_l(-1, k, r, i - 1 + chemxb) = flux_rs${XYZ}$_vf_l(0, k, r, chemxb + i - 1) & - + ds(0)*(drho_dt*Ys(i) + rho*dYs_dt(i)) + flux_rs${XYZ}$_vf_l(-1, k, r, i - 1 + chemxb) = flux_rs${XYZ}$_vf_l(0, k, r, & + & chemxb + i - 1) + ds(0)*(drho_dt*Ys(i) + rho*dYs_dt(i)) end do else - flux_rs${XYZ}$_vf_l(-1, k, r, E_idx) = flux_rs${XYZ}$_vf_l(0, k, r, E_idx) & - + ds(0)*(pres*dgamma_dt & - + gamma*dpres_dt & - + dpi_inf_dt & - + dqv_dt & - + rho*vel_dv_dt_sum & - + 5.e-1_wp*drho_dt*vel_K_sum) + flux_rs${XYZ}$_vf_l(-1, k, r, E_idx) = flux_rs${XYZ}$_vf_l(0, k, r, & + & E_idx) + ds(0)*(pres*dgamma_dt + gamma*dpres_dt + dpi_inf_dt + dqv_dt & + & + rho*vel_dv_dt_sum + 5.e-1_wp*drho_dt*vel_K_sum) end if if (riemann_solver == 1) then @@ -1090,31 +946,23 @@ contains $:GPU_LOOP(parallelism='[seq]') do i = advxb, advxe - flux_src_rs${XYZ}$_vf_l(-1, k, r, i) = & - 1._wp/max(abs(vel(dir_idx(1))), sgm_eps) & - *sign(1._wp, vel(dir_idx(1))) & - *(flux_rs${XYZ}$_vf_l(0, k, r, i) & - + vel(dir_idx(1)) & - *flux_src_rs${XYZ}$_vf_l(0, k, r, i) & - + ds(0)*dadv_dt(i - E_idx)) + flux_src_rs${XYZ}$_vf_l(-1, k, r, i) = 1._wp/max(abs(vel(dir_idx(1))), sgm_eps)*sign(1._wp, & + & vel(dir_idx(1)))*(flux_rs${XYZ}$_vf_l(0, k, r, & + & i) + vel(dir_idx(1))*flux_src_rs${XYZ}$_vf_l(0, k, r, & + & i) + ds(0)*dadv_dt(i - E_idx)) end do - else - $:GPU_LOOP(parallelism='[seq]') do i = advxb, advxe - flux_rs${XYZ}$_vf_l(-1, k, r, i) = flux_rs${XYZ}$_vf_l(0, k, r, i) + & - ds(0)*dadv_dt(i - E_idx) + flux_rs${XYZ}$_vf_l(-1, k, r, i) = flux_rs${XYZ}$_vf_l(0, k, r, i) + ds(0)*dadv_dt(i - E_idx) end do $:GPU_LOOP(parallelism='[seq]') do i = advxb, advxe flux_src_rs${XYZ}$_vf_l(-1, k, r, i) = flux_src_rs${XYZ}$_vf_l(0, k, r, i) end do - end if ! END: flux_rs_vf_l and flux_src_rs_vf_l at j = -1/2 - end do end do $:END_GPU_PARALLEL_LOOP() @@ -1123,36 +971,26 @@ contains ! END: FD2 or FD4 of RHS at j = 0 - ! The reshaping of outputted data and disssociation of the FD and PI - ! coefficients, or CBC coefficients, respectively, based on selected - ! CBC coordinate direction. + ! The reshaping of outputted data and disssociation of the FD and PI coefficients, or CBC coefficients, respectively, based + ! on selected CBC coordinate direction. call s_finalize_cbc(flux_vf, flux_src_vf) - end subroutine s_cbc - - !> The computation of parameters, the allocation of memory, - !! the association of pointers and/or the execution of any - !! other procedures that are required for the setup of the - !! selected CBC. - !! @param q_prim_vf Cell-average primitive variables - !! @param flux_vf Cell-boundary-average fluxes - !! @param flux_src_vf Cell-boundary-average flux sources - !! @param ix Index bound in the first coordinate direction - !! @param iy Index bound in the second coordinate direction - !! @param iz Index bound in the third coordinate direction - subroutine s_initialize_cbc(q_prim_vf, flux_vf, flux_src_vf, & - ix, iy, iz) - - type(scalar_field), & - dimension(sys_size), & - intent(in) :: q_prim_vf - - type(scalar_field), & - dimension(sys_size), & - intent(in) :: flux_vf, flux_src_vf - type(int_bounds_info), intent(in) :: ix, iy, iz + end subroutine s_cbc - integer :: i, j, k, r !< Generic loop iterators + !> The computation of parameters, the allocation of memory, the association of pointers and/or the execution of any other + !! procedures that are required for the setup of the selected CBC. + !! @param q_prim_vf Cell-average primitive variables + !! @param flux_vf Cell-boundary-average fluxes + !! @param flux_src_vf Cell-boundary-average flux sources + !! @param ix Index bound in the first coordinate direction + !! @param iy Index bound in the second coordinate direction + !! @param iz Index bound in the third coordinate direction + subroutine s_initialize_cbc(q_prim_vf, flux_vf, flux_src_vf, ix, iy, iz) + + type(scalar_field), dimension(sys_size), intent(in) :: q_prim_vf + type(scalar_field), dimension(sys_size), intent(in) :: flux_vf, flux_src_vf + type(int_bounds_info), intent(in) :: ix, iy, iz + integer :: i, j, k, r !< Generic loop iterators ! Configuring the coordinate direction indexes and flags @@ -1163,7 +1001,7 @@ contains if (cbc_dir == 1) then is1%beg = 0; is1%end = buff_size; is2 = iy; is3 = iz dir_idx = (/1, 2, 3/); dir_flg = (/1._wp, 0._wp, 0._wp/) - elseif (cbc_dir == 2) then + else if (cbc_dir == 2) then is1%beg = 0; is1%end = buff_size; is2 = ix; is3 = iz dir_idx = (/2, 1, 3/); dir_flg = (/0._wp, 1._wp, 0._wp/) else @@ -1172,83 +1010,74 @@ contains end if dj = max(0, cbc_loc) - $:GPU_UPDATE(device='[is1,is2,is3,dj]') - $:GPU_UPDATE(device='[dir_idx,dir_flg]') + $:GPU_UPDATE(device='[is1, is2, is3, dj]') + $:GPU_UPDATE(device='[dir_idx, dir_flg]') ! Reshaping Inputted Data in x-direction if (cbc_dir == 1) then - - $:GPU_PARALLEL_LOOP(private='[i,j,k,r]', collapse=4) + $:GPU_PARALLEL_LOOP(private='[i, j, k, r]', collapse=4) do i = 1, sys_size do r = is3%beg, is3%end do k = is2%beg, is2%end do j = 0, buff_size - q_prim_rsx_vf(j, k, r, i) = & - q_prim_vf(i)%sf(dj*(m - 2*j) + j, k, r) + q_prim_rsx_vf(j, k, r, i) = q_prim_vf(i)%sf(dj*(m - 2*j) + j, k, r) end do end do end do end do $:END_GPU_PARALLEL_LOOP() - $:GPU_PARALLEL_LOOP(private='[j,k,r]', collapse=3) + $:GPU_PARALLEL_LOOP(private='[j, k, r]', collapse=3) do r = is3%beg, is3%end do k = is2%beg, is2%end do j = 0, buff_size - q_prim_rsx_vf(j, k, r, momxb) = & - q_prim_vf(momxb)%sf(dj*(m - 2*j) + j, k, r)* & - sign(1._wp, -1._wp*cbc_loc) + q_prim_rsx_vf(j, k, r, momxb) = q_prim_vf(momxb)%sf(dj*(m - 2*j) + j, k, r)*sign(1._wp, -1._wp*cbc_loc) end do end do end do $:END_GPU_PARALLEL_LOOP() - $:GPU_PARALLEL_LOOP(private='[i,j,k,r]', collapse=4) + $:GPU_PARALLEL_LOOP(private='[i, j, k, r]', collapse=4) do i = 1, flux_cbc_index do r = is3%beg, is3%end do k = is2%beg, is2%end do j = -1, buff_size - flux_rsx_vf_l(j, k, r, i) = & - flux_vf(i)%sf(dj*((m - 1) - 2*j) + j, k, r)* & - sign(1._wp, -1._wp*cbc_loc) + flux_rsx_vf_l(j, k, r, i) = flux_vf(i)%sf(dj*((m - 1) - 2*j) + j, k, r)*sign(1._wp, -1._wp*cbc_loc) end do end do end do end do $:END_GPU_PARALLEL_LOOP() - $:GPU_PARALLEL_LOOP(private='[j,k,r]', collapse=3) + $:GPU_PARALLEL_LOOP(private='[j, k, r]', collapse=3) do r = is3%beg, is3%end do k = is2%beg, is2%end do j = -1, buff_size - flux_rsx_vf_l(j, k, r, momxb) = & - flux_vf(momxb)%sf(dj*((m - 1) - 2*j) + j, k, r) + flux_rsx_vf_l(j, k, r, momxb) = flux_vf(momxb)%sf(dj*((m - 1) - 2*j) + j, k, r) end do end do end do $:END_GPU_PARALLEL_LOOP() if (riemann_solver == 1) then - $:GPU_PARALLEL_LOOP(private='[i,j,k,r]', collapse=4) + $:GPU_PARALLEL_LOOP(private='[i, j, k, r]', collapse=4) do i = advxb, advxe do r = is3%beg, is3%end do k = is2%beg, is2%end do j = -1, buff_size - flux_src_rsx_vf_l(j, k, r, i) = & - flux_src_vf(i)%sf(dj*((m - 1) - 2*j) + j, k, r) + flux_src_rsx_vf_l(j, k, r, i) = flux_src_vf(i)%sf(dj*((m - 1) - 2*j) + j, k, r) end do end do end do end do $:END_GPU_PARALLEL_LOOP() else - $:GPU_PARALLEL_LOOP(private='[j,k,r]', collapse=3) + $:GPU_PARALLEL_LOOP(private='[j, k, r]', collapse=3) do r = is3%beg, is3%end do k = is2%beg, is2%end do j = -1, buff_size - flux_src_rsx_vf_l(j, k, r, advxb) = & - flux_src_vf(advxb)%sf(dj*((m - 1) - 2*j) + j, k, r)* & - sign(1._wp, -1._wp*cbc_loc) + flux_src_rsx_vf_l(j, k, r, advxb) = flux_src_vf(advxb)%sf(dj*((m - 1) - 2*j) + j, k, r)*sign(1._wp, & + & -1._wp*cbc_loc) end do end do end do @@ -1258,79 +1087,71 @@ contains ! END: Reshaping Inputted Data in x-direction ! Reshaping Inputted Data in y-direction - elseif (cbc_dir == 2) then - - $:GPU_PARALLEL_LOOP(private='[i,j,k,r]', collapse=4) + else if (cbc_dir == 2) then + $:GPU_PARALLEL_LOOP(private='[i, j, k, r]', collapse=4) do i = 1, sys_size do r = is3%beg, is3%end do k = is2%beg, is2%end do j = 0, buff_size - q_prim_rsy_vf(j, k, r, i) = & - q_prim_vf(i)%sf(k, dj*(n - 2*j) + j, r) + q_prim_rsy_vf(j, k, r, i) = q_prim_vf(i)%sf(k, dj*(n - 2*j) + j, r) end do end do end do end do $:END_GPU_PARALLEL_LOOP() - $:GPU_PARALLEL_LOOP(private='[j,k,r]', collapse=3) + $:GPU_PARALLEL_LOOP(private='[j, k, r]', collapse=3) do r = is3%beg, is3%end do k = is2%beg, is2%end do j = 0, buff_size - q_prim_rsy_vf(j, k, r, momxb + 1) = & - q_prim_vf(momxb + 1)%sf(k, dj*(n - 2*j) + j, r)* & - sign(1._wp, -1._wp*cbc_loc) + q_prim_rsy_vf(j, k, r, momxb + 1) = q_prim_vf(momxb + 1)%sf(k, dj*(n - 2*j) + j, r)*sign(1._wp, & + & -1._wp*cbc_loc) end do end do end do $:END_GPU_PARALLEL_LOOP() - $:GPU_PARALLEL_LOOP(private='[i,j,k,r]', collapse=4) + $:GPU_PARALLEL_LOOP(private='[i, j, k, r]', collapse=4) do i = 1, flux_cbc_index do r = is3%beg, is3%end do k = is2%beg, is2%end do j = -1, buff_size - flux_rsy_vf_l(j, k, r, i) = & - flux_vf(i)%sf(k, dj*((n - 1) - 2*j) + j, r)* & - sign(1._wp, -1._wp*cbc_loc) + flux_rsy_vf_l(j, k, r, i) = flux_vf(i)%sf(k, dj*((n - 1) - 2*j) + j, r)*sign(1._wp, -1._wp*cbc_loc) end do end do end do end do $:END_GPU_PARALLEL_LOOP() - $:GPU_PARALLEL_LOOP(private='[j,k,r]', collapse=3) + $:GPU_PARALLEL_LOOP(private='[j, k, r]', collapse=3) do r = is3%beg, is3%end do k = is2%beg, is2%end do j = -1, buff_size - flux_rsy_vf_l(j, k, r, momxb + 1) = & - flux_vf(momxb + 1)%sf(k, dj*((n - 1) - 2*j) + j, r) + flux_rsy_vf_l(j, k, r, momxb + 1) = flux_vf(momxb + 1)%sf(k, dj*((n - 1) - 2*j) + j, r) end do end do end do $:END_GPU_PARALLEL_LOOP() if (riemann_solver == 1) then - $:GPU_PARALLEL_LOOP(private='[i,j,k,r]', collapse=4) + $:GPU_PARALLEL_LOOP(private='[i, j, k, r]', collapse=4) do i = advxb, advxe do r = is3%beg, is3%end do k = is2%beg, is2%end do j = -1, buff_size - flux_src_rsy_vf_l(j, k, r, i) = & - flux_src_vf(i)%sf(k, dj*((n - 1) - 2*j) + j, r) + flux_src_rsy_vf_l(j, k, r, i) = flux_src_vf(i)%sf(k, dj*((n - 1) - 2*j) + j, r) end do end do end do end do $:END_GPU_PARALLEL_LOOP() else - $:GPU_PARALLEL_LOOP(private='[j,k,r]', collapse=3) + $:GPU_PARALLEL_LOOP(private='[j, k, r]', collapse=3) do r = is3%beg, is3%end do k = is2%beg, is2%end do j = -1, buff_size - flux_src_rsy_vf_l(j, k, r, advxb) = & - flux_src_vf(advxb)%sf(k, dj*((n - 1) - 2*j) + j, r)* & - sign(1._wp, -1._wp*cbc_loc) + flux_src_rsy_vf_l(j, k, r, advxb) = flux_src_vf(advxb)%sf(k, dj*((n - 1) - 2*j) + j, r)*sign(1._wp, & + & -1._wp*cbc_loc) end do end do end do @@ -1341,156 +1162,137 @@ contains ! Reshaping Inputted Data in z-direction else - - $:GPU_PARALLEL_LOOP(private='[i,j,k,r]', collapse=4) + $:GPU_PARALLEL_LOOP(private='[i, j, k, r]', collapse=4) do i = 1, sys_size do r = is3%beg, is3%end do k = is2%beg, is2%end do j = 0, buff_size - q_prim_rsz_vf(j, k, r, i) = & - q_prim_vf(i)%sf(r, k, dj*(p - 2*j) + j) + q_prim_rsz_vf(j, k, r, i) = q_prim_vf(i)%sf(r, k, dj*(p - 2*j) + j) end do end do end do end do $:END_GPU_PARALLEL_LOOP() - $:GPU_PARALLEL_LOOP(private='[j,k,r]', collapse=3) + $:GPU_PARALLEL_LOOP(private='[j, k, r]', collapse=3) do r = is3%beg, is3%end do k = is2%beg, is2%end do j = 0, buff_size - q_prim_rsz_vf(j, k, r, momxe) = & - q_prim_vf(momxe)%sf(r, k, dj*(p - 2*j) + j)* & - sign(1._wp, -1._wp*cbc_loc) + q_prim_rsz_vf(j, k, r, momxe) = q_prim_vf(momxe)%sf(r, k, dj*(p - 2*j) + j)*sign(1._wp, -1._wp*cbc_loc) end do end do end do $:END_GPU_PARALLEL_LOOP() - $:GPU_PARALLEL_LOOP(private='[i,j,k,r]', collapse=4) + $:GPU_PARALLEL_LOOP(private='[i, j, k, r]', collapse=4) do i = 1, flux_cbc_index do r = is3%beg, is3%end do k = is2%beg, is2%end do j = -1, buff_size - flux_rsz_vf_l(j, k, r, i) = & - flux_vf(i)%sf(r, k, dj*((p - 1) - 2*j) + j)* & - sign(1._wp, -1._wp*cbc_loc) + flux_rsz_vf_l(j, k, r, i) = flux_vf(i)%sf(r, k, dj*((p - 1) - 2*j) + j)*sign(1._wp, -1._wp*cbc_loc) end do end do end do end do $:END_GPU_PARALLEL_LOOP() - $:GPU_PARALLEL_LOOP(private='[j,k,r]', collapse=3) + $:GPU_PARALLEL_LOOP(private='[j, k, r]', collapse=3) do r = is3%beg, is3%end do k = is2%beg, is2%end do j = -1, buff_size - flux_rsz_vf_l(j, k, r, momxe) = & - flux_vf(momxe)%sf(r, k, dj*((p - 1) - 2*j) + j) + flux_rsz_vf_l(j, k, r, momxe) = flux_vf(momxe)%sf(r, k, dj*((p - 1) - 2*j) + j) end do end do end do $:END_GPU_PARALLEL_LOOP() if (riemann_solver == 1) then - $:GPU_PARALLEL_LOOP(private='[i,j,k,r]', collapse=4) + $:GPU_PARALLEL_LOOP(private='[i, j, k, r]', collapse=4) do i = advxb, advxe do r = is3%beg, is3%end do k = is2%beg, is2%end do j = -1, buff_size - flux_src_rsz_vf_l(j, k, r, i) = & - flux_src_vf(i)%sf(r, k, dj*((p - 1) - 2*j) + j) + flux_src_rsz_vf_l(j, k, r, i) = flux_src_vf(i)%sf(r, k, dj*((p - 1) - 2*j) + j) end do end do end do end do $:END_GPU_PARALLEL_LOOP() else - $:GPU_PARALLEL_LOOP(private='[j,k,r]', collapse=3) + $:GPU_PARALLEL_LOOP(private='[j, k, r]', collapse=3) do r = is3%beg, is3%end do k = is2%beg, is2%end do j = -1, buff_size - flux_src_rsz_vf_l(j, k, r, advxb) = & - flux_src_vf(advxb)%sf(r, k, dj*((p - 1) - 2*j) + j)* & - sign(1._wp, -1._wp*cbc_loc) + flux_src_rsz_vf_l(j, k, r, advxb) = flux_src_vf(advxb)%sf(r, k, dj*((p - 1) - 2*j) + j)*sign(1._wp, & + & -1._wp*cbc_loc) end do end do end do $:END_GPU_PARALLEL_LOOP() end if - end if ! END: Reshaping Inputted Data in z-direction - ! Association of the procedural pointer to the appropriate procedure - ! that will be utilized in the evaluation of L variables for the CBC + ! Association of the procedural pointer to the appropriate procedure that will be utilized in the evaluation of L variables + ! for the CBC end subroutine s_initialize_cbc - !> Deallocation and/or the disassociation procedures that - !! are necessary in order to finalize the CBC application - !! @param flux_vf Cell-boundary-average fluxes - !! @param flux_src_vf Cell-boundary-average flux sources + !> Deallocation and/or the disassociation procedures that are necessary in order to finalize the CBC application + !! @param flux_vf Cell-boundary-average fluxes + !! @param flux_src_vf Cell-boundary-average flux sources subroutine s_finalize_cbc(flux_vf, flux_src_vf) - type(scalar_field), & - dimension(sys_size), & - intent(inout) :: flux_vf, flux_src_vf - - integer :: i, j, k, r !< Generic loop iterators + type(scalar_field), dimension(sys_size), intent(inout) :: flux_vf, flux_src_vf + integer :: i, j, k, r !< Generic loop iterators ! Determining the indicial shift based on CBC location + dj = max(0, cbc_loc) $:GPU_UPDATE(device='[dj]') ! Reshaping Outputted Data in x-direction if (cbc_dir == 1) then - - $:GPU_PARALLEL_LOOP(private='[i,j,k,r]', collapse=4) + $:GPU_PARALLEL_LOOP(private='[i, j, k, r]', collapse=4) do i = 1, flux_cbc_index do r = is3%beg, is3%end do k = is2%beg, is2%end do j = -1, buff_size - flux_vf(i)%sf(dj*((m - 1) - 2*j) + j, k, r) = & - flux_rsx_vf_l(j, k, r, i)* & - sign(1._wp, -1._wp*cbc_loc) + flux_vf(i)%sf(dj*((m - 1) - 2*j) + j, k, r) = flux_rsx_vf_l(j, k, r, i)*sign(1._wp, -1._wp*cbc_loc) end do end do end do end do $:END_GPU_PARALLEL_LOOP() - $:GPU_PARALLEL_LOOP(private='[j,k,r]', collapse=3) + $:GPU_PARALLEL_LOOP(private='[j, k, r]', collapse=3) do r = is3%beg, is3%end do k = is2%beg, is2%end do j = -1, buff_size - flux_vf(momxb)%sf(dj*((m - 1) - 2*j) + j, k, r) = & - flux_rsx_vf_l(j, k, r, momxb) + flux_vf(momxb)%sf(dj*((m - 1) - 2*j) + j, k, r) = flux_rsx_vf_l(j, k, r, momxb) end do end do end do $:END_GPU_PARALLEL_LOOP() if (riemann_solver == 1) then - $:GPU_PARALLEL_LOOP(private='[i,j,k,r]', collapse=4) + $:GPU_PARALLEL_LOOP(private='[i, j, k, r]', collapse=4) do i = advxb, advxe do r = is3%beg, is3%end do k = is2%beg, is2%end do j = -1, buff_size - flux_src_vf(i)%sf(dj*((m - 1) - 2*j) + j, k, r) = & - flux_src_rsx_vf_l(j, k, r, i) + flux_src_vf(i)%sf(dj*((m - 1) - 2*j) + j, k, r) = flux_src_rsx_vf_l(j, k, r, i) end do end do end do end do $:END_GPU_PARALLEL_LOOP() else - $:GPU_PARALLEL_LOOP(private='[j,k,r]', collapse=3) + $:GPU_PARALLEL_LOOP(private='[j, k, r]', collapse=3) do r = is3%beg, is3%end do k = is2%beg, is2%end do j = -1, buff_size - flux_src_vf(advxb)%sf(dj*((m - 1) - 2*j) + j, k, r) = & - flux_src_rsx_vf_l(j, k, r, advxb)* & - sign(1._wp, -1._wp*cbc_loc) + flux_src_vf(advxb)%sf(dj*((m - 1) - 2*j) + j, k, r) = flux_src_rsx_vf_l(j, k, r, advxb)*sign(1._wp, & + & -1._wp*cbc_loc) end do end do end do @@ -1499,54 +1301,48 @@ contains ! END: Reshaping Outputted Data in x-direction ! Reshaping Outputted Data in y-direction - elseif (cbc_dir == 2) then - - $:GPU_PARALLEL_LOOP(private='[i,j,k,r]', collapse=4) + else if (cbc_dir == 2) then + $:GPU_PARALLEL_LOOP(private='[i, j, k, r]', collapse=4) do i = 1, flux_cbc_index do r = is3%beg, is3%end do k = is2%beg, is2%end do j = -1, buff_size - flux_vf(i)%sf(k, dj*((n - 1) - 2*j) + j, r) = & - flux_rsy_vf_l(j, k, r, i)* & - sign(1._wp, -1._wp*cbc_loc) + flux_vf(i)%sf(k, dj*((n - 1) - 2*j) + j, r) = flux_rsy_vf_l(j, k, r, i)*sign(1._wp, -1._wp*cbc_loc) end do end do end do end do $:END_GPU_PARALLEL_LOOP() - $:GPU_PARALLEL_LOOP(private='[j,k,r]', collapse=3) + $:GPU_PARALLEL_LOOP(private='[j, k, r]', collapse=3) do r = is3%beg, is3%end do k = is2%beg, is2%end do j = -1, buff_size - flux_vf(momxb + 1)%sf(k, dj*((n - 1) - 2*j) + j, r) = & - flux_rsy_vf_l(j, k, r, momxb + 1) + flux_vf(momxb + 1)%sf(k, dj*((n - 1) - 2*j) + j, r) = flux_rsy_vf_l(j, k, r, momxb + 1) end do end do end do $:END_GPU_PARALLEL_LOOP() if (riemann_solver == 1) then - $:GPU_PARALLEL_LOOP(private='[i,j,k,r]', collapse=4) + $:GPU_PARALLEL_LOOP(private='[i, j, k, r]', collapse=4) do i = advxb, advxe do r = is3%beg, is3%end do k = is2%beg, is2%end do j = -1, buff_size - flux_src_vf(i)%sf(k, dj*((n - 1) - 2*j) + j, r) = & - flux_src_rsy_vf_l(j, k, r, i) + flux_src_vf(i)%sf(k, dj*((n - 1) - 2*j) + j, r) = flux_src_rsy_vf_l(j, k, r, i) end do end do end do end do $:END_GPU_PARALLEL_LOOP() else - $:GPU_PARALLEL_LOOP(private='[j,k,r]', collapse=3) + $:GPU_PARALLEL_LOOP(private='[j, k, r]', collapse=3) do r = is3%beg, is3%end do k = is2%beg, is2%end do j = -1, buff_size - flux_src_vf(advxb)%sf(k, dj*((n - 1) - 2*j) + j, r) = & - flux_src_rsy_vf_l(j, k, r, advxb)* & - sign(1._wp, -1._wp*cbc_loc) + flux_src_vf(advxb)%sf(k, dj*((n - 1) - 2*j) + j, r) = flux_src_rsy_vf_l(j, k, r, advxb)*sign(1._wp, & + & -1._wp*cbc_loc) end do end do end do @@ -1557,59 +1353,52 @@ contains ! Reshaping Outputted Data in z-direction else - - $:GPU_PARALLEL_LOOP(private='[i,j,k,r]', collapse=4) + $:GPU_PARALLEL_LOOP(private='[i, j, k, r]', collapse=4) do i = 1, flux_cbc_index do r = is3%beg, is3%end do k = is2%beg, is2%end do j = -1, buff_size - flux_vf(i)%sf(r, k, dj*((p - 1) - 2*j) + j) = & - flux_rsz_vf_l(j, k, r, i)* & - sign(1._wp, -1._wp*cbc_loc) + flux_vf(i)%sf(r, k, dj*((p - 1) - 2*j) + j) = flux_rsz_vf_l(j, k, r, i)*sign(1._wp, -1._wp*cbc_loc) end do end do end do end do $:END_GPU_PARALLEL_LOOP() - $:GPU_PARALLEL_LOOP(private='[j,k,r]', collapse=3) + $:GPU_PARALLEL_LOOP(private='[j, k, r]', collapse=3) do r = is3%beg, is3%end do k = is2%beg, is2%end do j = -1, buff_size - flux_vf(momxe)%sf(r, k, dj*((p - 1) - 2*j) + j) = & - flux_rsz_vf_l(j, k, r, momxe) + flux_vf(momxe)%sf(r, k, dj*((p - 1) - 2*j) + j) = flux_rsz_vf_l(j, k, r, momxe) end do end do end do $:END_GPU_PARALLEL_LOOP() if (riemann_solver == 1) then - $:GPU_PARALLEL_LOOP(private='[i,j,k,r]', collapse=4) + $:GPU_PARALLEL_LOOP(private='[i, j, k, r]', collapse=4) do i = advxb, advxe do r = is3%beg, is3%end do k = is2%beg, is2%end do j = -1, buff_size - flux_src_vf(i)%sf(r, k, dj*((p - 1) - 2*j) + j) = & - flux_src_rsz_vf_l(j, k, r, i) + flux_src_vf(i)%sf(r, k, dj*((p - 1) - 2*j) + j) = flux_src_rsz_vf_l(j, k, r, i) end do end do end do end do $:END_GPU_PARALLEL_LOOP() else - $:GPU_PARALLEL_LOOP(private='[j,k,r]', collapse=3) + $:GPU_PARALLEL_LOOP(private='[j, k, r]', collapse=3) do r = is3%beg, is3%end do k = is2%beg, is2%end do j = -1, buff_size - flux_src_vf(advxb)%sf(r, k, dj*((p - 1) - 2*j) + j) = & - flux_src_rsz_vf_l(j, k, r, advxb)* & - sign(1._wp, -1._wp*cbc_loc) + flux_src_vf(advxb)%sf(r, k, dj*((p - 1) - 2*j) + j) = flux_src_rsz_vf_l(j, k, r, advxb)*sign(1._wp, & + & -1._wp*cbc_loc) end do end do end do $:END_GPU_PARALLEL_LOOP() end if - end if ! END: Reshaping Outputted Data in z-direction @@ -1668,9 +1457,8 @@ contains @:DEALLOCATE(vel_in, vel_out, pres_in, pres_out, Del_in, Del_out, alpha_rho_in, alpha_in) ! Deallocating CBC Coefficients in x-direction - if (all((/bc_x%beg, bc_x%end/) <= -5) .and. all((/bc_x%beg, bc_x%end/) >= -13) .or. & - bc_x%beg <= -5 .and. bc_x%beg >= -13 .or. & - bc_x%end <= -5 .and. bc_x%end >= -13) then + if (all((/bc_x%beg, bc_x%end/) <= -5) .and. all((/bc_x%beg, & + & bc_x%end/) >= -13) .or. bc_x%beg <= -5 .and. bc_x%beg >= -13 .or. bc_x%end <= -5 .and. bc_x%end >= -13) then @:DEALLOCATE(fd_coef_x) if (weno_order > 1 .or. muscl_order > 1) then @:DEALLOCATE(pi_coef_x) @@ -1679,9 +1467,8 @@ contains ! Deallocating CBC Coefficients in y-direction if (n > 0) then - if (all((/bc_y%beg, bc_y%end/) <= -5) .and. all((/bc_y%beg, bc_y%end/) >= -13) .or. & - bc_y%beg <= -5 .and. bc_y%beg >= -13 .or. & - bc_y%end <= -5 .and. bc_y%end >= -13) then + if (all((/bc_y%beg, bc_y%end/) <= -5) .and. all((/bc_y%beg, & + & bc_y%end/) >= -13) .or. bc_y%beg <= -5 .and. bc_y%beg >= -13 .or. bc_y%end <= -5 .and. bc_y%end >= -13) then @:DEALLOCATE(fd_coef_y) if (weno_order > 1) then @:DEALLOCATE(pi_coef_y) @@ -1691,9 +1478,8 @@ contains ! Deallocating CBC Coefficients in z-direction if (p > 0) then - if (all((/bc_z%beg, bc_z%end/) <= -5) .and. all((/bc_z%beg, bc_z%end/) >= -13) .or. & - bc_z%beg <= -5 .and. bc_z%beg >= -13 .or. & - bc_z%end <= -5 .and. bc_z%end >= -13) then + if (all((/bc_z%beg, bc_z%end/) <= -5) .and. all((/bc_z%beg, & + & bc_z%end/) >= -13) .or. bc_z%beg <= -5 .and. bc_z%beg >= -13 .or. bc_z%end <= -5 .and. bc_z%end >= -13) then @:DEALLOCATE(fd_coef_z) if (weno_order > 1) then @:DEALLOCATE(pi_coef_z) diff --git a/src/simulation/m_checker.fpp b/src/simulation/m_checker.fpp index 5543cba645..81e25563bb 100644 --- a/src/simulation/m_checker.fpp +++ b/src/simulation/m_checker.fpp @@ -8,13 +8,10 @@ !> @brief Validates simulation input parameters for consistency and supported configurations module m_checker - use m_global_parameters !< Definitions of the global parameters - - use m_mpi_proxy !< Message passing interface (MPI) module proxy - + use m_global_parameters !< Definitions of the global parameters + use m_mpi_proxy !< Message passing interface (MPI) module proxy use m_helper - - use m_helper_basic !< Functions to compare floating point numbers + use m_helper_basic !< Functions to compare floating point numbers implicit none @@ -22,8 +19,7 @@ module m_checker contains - !> Checks compatibility of parameters in the input file. - !! Used by the simulation stage + !> Checks compatibility of parameters in the input file. Used by the simulation stage impure subroutine s_check_inputs call s_check_inputs_compilers @@ -46,51 +42,61 @@ contains !> Checks constraints on compiler options impure subroutine s_check_inputs_compilers + #if !defined(MFC_OpenACC) && !(defined(__PGI) || defined(_CRAYFTN)) @:PROHIBIT(rdma_mpi, "Unsupported value of rdma_mpi for the current compiler") #endif + end subroutine s_check_inputs_compilers !> Checks constraints on WENO scheme parameters impure subroutine s_check_inputs_weno - character(len=5) :: numStr !< for int to string conversion + + character(len=5) :: numStr !< for int to string conversion call s_int_to_str(num_stcls_min*weno_order, numStr) @:PROHIBIT(m + 1 < num_stcls_min*weno_order, & - "m must be greater than or equal to (num_stcls_min*weno_order - 1), whose value is "//trim(numStr)) + & "m must be greater than or equal to (num_stcls_min*weno_order - 1), whose value is "//trim(numStr)) @:PROHIBIT(n + 1 < min(1, n)*num_stcls_min*weno_order, & - "For 2D simulation, n must be greater than or equal to (num_stcls_min*weno_order - 1), whose value is "//trim(numStr)) + & "For 2D simulation, n must be greater than or equal to (num_stcls_min*weno_order - 1), whose value is "//trim(numStr)) @:PROHIBIT(p + 1 < min(1, p)*num_stcls_min*weno_order, & - "For 3D simulation, p must be greater than or equal to (num_stcls_min*weno_order - 1), whose value is "//trim(numStr)) + & "For 3D simulation, p must be greater than or equal to (num_stcls_min*weno_order - 1), whose value is "//trim(numStr)) + end subroutine s_check_inputs_weno !> @brief Validates that the grid resolution is sufficient for the MUSCL reconstruction order. impure subroutine s_check_inputs_muscl - character(len=5) :: numStr !< for int to string conversion + + character(len=5) :: numStr !< for int to string conversion call s_int_to_str(num_stcls_min*muscl_order, numStr) @:PROHIBIT(m + 1 < num_stcls_min*muscl_order, & - "m must be greater than or equal to (num_stcls_min*muscl_order - 1), whose value is "//trim(numStr)) + & "m must be greater than or equal to (num_stcls_min*muscl_order - 1), whose value is "//trim(numStr)) @:PROHIBIT(n + 1 < min(1, n)*num_stcls_min*muscl_order, & - "For 2D simulation, n must be greater than or equal to (num_stcls_min*muscl_order - 1), whose value is "//trim(numStr)) + & "For 2D simulation, n must be greater than or equal to (num_stcls_min*muscl_order - 1), whose value is "//trim(numStr)) @:PROHIBIT(p + 1 < min(1, p)*num_stcls_min*muscl_order, & - "For 3D simulation, p must be greater than or equal to (num_stcls_min*muscl_order - 1), whose value is "//trim(numStr)) + & "For 3D simulation, p must be greater than or equal to (num_stcls_min*muscl_order - 1), whose value is "//trim(numStr)) + end subroutine s_check_inputs_muscl !> Checks constraints on time stepping parameters impure subroutine s_check_inputs_time_stepping + if (.not. cfl_dt) then @:PROHIBIT(dt <= 0) end if + end subroutine s_check_inputs_time_stepping impure subroutine s_check_inputs_nvidia_uvm + #ifdef __NVCOMPILER_GPU_UNIFIED_MEM @:PROHIBIT(nv_uvm_igr_temps_on_gpu > 3 .or. nv_uvm_igr_temps_on_gpu < 0, & - "nv_uvm_igr_temps_on_gpu must be in the range [0, 3]") + & "nv_uvm_igr_temps_on_gpu must be in the range [0, 3]") @:PROHIBIT(nv_uvm_igr_temps_on_gpu == 3 .and. igr_iter_solver == 2, & - "nv_uvm_igr_temps_on_gpu must be in the range [0, 2] for igr_iter_solver == 2") + & "nv_uvm_igr_temps_on_gpu must be in the range [0, 2] for igr_iter_solver == 2") #endif + end subroutine s_check_inputs_nvidia_uvm end module m_checker diff --git a/src/simulation/m_compute_cbc.fpp b/src/simulation/m_compute_cbc.fpp index bb7c59ac5f..cbeac697af 100644 --- a/src/simulation/m_compute_cbc.fpp +++ b/src/simulation/m_compute_cbc.fpp @@ -6,24 +6,23 @@ !> @brief Characteristic boundary condition (CBC) computations for subsonic inflow, outflow, and slip walls module m_compute_cbc + use m_global_parameters + implicit none - private; public :: s_compute_slip_wall_L, & - s_compute_nonreflecting_subsonic_buffer_L, & - s_compute_nonreflecting_subsonic_inflow_L, & - s_compute_nonreflecting_subsonic_outflow_L, & - s_compute_force_free_subsonic_outflow_L, & - s_compute_constant_pressure_subsonic_outflow_L, & - s_compute_supersonic_inflow_L, & - s_compute_supersonic_outflow_L + private; public :: s_compute_slip_wall_L, s_compute_nonreflecting_subsonic_buffer_L, & + & s_compute_nonreflecting_subsonic_inflow_L, s_compute_nonreflecting_subsonic_outflow_L, & + & s_compute_force_free_subsonic_outflow_L, s_compute_constant_pressure_subsonic_outflow_L, s_compute_supersonic_inflow_L, & + & s_compute_supersonic_outflow_L contains !> Base L1 calculation function f_base_L1(lambda, rho, c, dpres_ds, dvel_ds) result(L1) + $:GPU_ROUTINE(parallelism='[seq]') real(wp), dimension(3), intent(in) :: lambda - real(wp), intent(in) :: rho, c, dpres_ds + real(wp), intent(in) :: rho, c, dpres_ds #:if not MFC_CASE_OPTIMIZATION and USING_AMD real(wp), dimension(3), intent(in) :: dvel_ds #:else @@ -31,10 +30,12 @@ contains #:endif real(wp) :: L1 L1 = lambda(1)*(dpres_ds - rho*c*dvel_ds(dir_idx(1))) + end function f_base_L1 !> Fill density L variables subroutine s_fill_density_L(L, lambda_factor, lambda2, c, mf, dalpha_rho_ds, dpres_ds) + $:GPU_ROUTINE(parallelism='[seq]') #:if USING_AMD real(wp), dimension(20), intent(inout) :: L @@ -48,16 +49,18 @@ contains #:endif real(wp), intent(in) :: lambda_factor, lambda2, c real(wp), intent(in) :: dpres_ds - integer :: i + integer :: i ! $:GPU_LOOP(parallelism='[seq]') do i = 2, momxb L(i) = lambda_factor*lambda2*(c*c*dalpha_rho_ds(i - 1) - mf(i - 1)*dpres_ds) end do + end subroutine s_fill_density_L !> Fill velocity L variables subroutine s_fill_velocity_L(L, lambda_factor, lambda2, dvel_ds) + $:GPU_ROUTINE(parallelism='[seq]') #:if USING_AMD real(wp), dimension(20), intent(inout) :: L @@ -70,16 +73,18 @@ contains real(wp), dimension(num_dims), intent(in) :: dvel_ds #:endif real(wp), intent(in) :: lambda_factor, lambda2 - integer :: i + integer :: i ! $:GPU_LOOP(parallelism='[seq]') do i = momxb + 1, momxe L(i) = lambda_factor*lambda2*dvel_ds(dir_idx(i - contxe)) end do + end subroutine s_fill_velocity_L !> Fill advection L variables subroutine s_fill_advection_L(L, lambda_factor, lambda2, dadv_ds) + $:GPU_ROUTINE(parallelism='[seq]') #:if USING_AMD real(wp), dimension(20), intent(inout) :: L @@ -92,16 +97,18 @@ contains real(wp), dimension(num_fluids), intent(in) :: dadv_ds #:endif real(wp), intent(in) :: lambda_factor, lambda2 - integer :: i + integer :: i ! $:GPU_LOOP(parallelism='[seq]') do i = E_idx, advxe - 1 L(i) = lambda_factor*lambda2*dadv_ds(i - momxe) end do + end subroutine s_fill_advection_L !> Fill chemistry L variables subroutine s_fill_chemistry_L(L, lambda_factor, lambda2, dYs_ds) + $:GPU_ROUTINE(parallelism='[seq]') #:if USING_AMD real(wp), dimension(20), intent(inout) :: L @@ -114,7 +121,7 @@ contains real(wp), dimension(num_species), intent(in) :: dYs_ds #:endif real(wp), intent(in) :: lambda_factor, lambda2 - integer :: i + integer :: i if (.not. chemistry) return @@ -122,12 +129,13 @@ contains do i = chemxb, chemxe L(i) = lambda_factor*lambda2*dYs_ds(i - chemxb + 1) end do + end subroutine s_fill_chemistry_L !> Slip wall CBC (Thompson 1990, pg. 451) subroutine s_compute_slip_wall_L(lambda, L, rho, c, dpres_ds, dvel_ds) - $:GPU_ROUTINE(function_name='s_compute_slip_wall_L',parallelism='[seq]', & - & cray_inline=True) + + $:GPU_ROUTINE(function_name='s_compute_slip_wall_L',parallelism='[seq]', cray_inline=True) real(wp), dimension(3), intent(in) :: lambda #:if USING_AMD @@ -141,17 +149,18 @@ contains real(wp), dimension(num_dims), intent(in) :: dvel_ds #:endif real(wp), intent(in) :: rho, c, dpres_ds - integer :: i + integer :: i L(1) = f_base_L1(lambda, rho, c, dpres_ds, dvel_ds) L(2:advxe - 1) = 0._wp L(advxe) = L(1) + end subroutine s_compute_slip_wall_L !> Nonreflecting subsonic buffer CBC (Thompson 1987, pg. 13) subroutine s_compute_nonreflecting_subsonic_buffer_L(lambda, L, rho, c, mf, dalpha_rho_ds, dpres_ds, dvel_ds, dadv_ds, dYs_ds) - $:GPU_ROUTINE(function_name='s_compute_nonreflecting_subsonic_buffer_L', & - & parallelism='[seq]', cray_inline=True) + + $:GPU_ROUTINE(function_name='s_compute_nonreflecting_subsonic_buffer_L', parallelism='[seq]', cray_inline=True) real(wp), dimension(3), intent(in) :: lambda #:if USING_AMD @@ -160,20 +169,19 @@ contains real(wp), dimension(sys_size), intent(inout) :: L #:endif #:if not MFC_CASE_OPTIMIZATION and USING_AMD - real(wp), dimension(3), intent(in) :: mf, dalpha_rho_ds - real(wp), dimension(3), intent(in) :: dvel_ds - real(wp), dimension(3), intent(in) :: dadv_ds + real(wp), dimension(3), intent(in) :: mf, dalpha_rho_ds + real(wp), dimension(3), intent(in) :: dvel_ds + real(wp), dimension(3), intent(in) :: dadv_ds real(wp), dimension(10), intent(in) :: dYs_ds #:else - real(wp), dimension(num_fluids), intent(in) :: mf, dalpha_rho_ds - real(wp), dimension(num_dims), intent(in) :: dvel_ds - real(wp), dimension(num_fluids), intent(in) :: dadv_ds + real(wp), dimension(num_fluids), intent(in) :: mf, dalpha_rho_ds + real(wp), dimension(num_dims), intent(in) :: dvel_ds + real(wp), dimension(num_fluids), intent(in) :: dadv_ds real(wp), dimension(num_species), intent(in) :: dYs_ds #:endif real(wp), intent(in) :: rho, c real(wp), intent(in) :: dpres_ds - - real(wp) :: lambda_factor + real(wp) :: lambda_factor lambda_factor = (5.e-1_wp - 5.e-1_wp*sign(1._wp, lambda(1))) L(1) = lambda_factor*lambda(1)*(dpres_ds - rho*c*dvel_ds(dir_idx(1))) @@ -186,12 +194,13 @@ contains lambda_factor = (5.e-1_wp - 5.e-1_wp*sign(1._wp, lambda(3))) L(advxe) = lambda_factor*lambda(3)*(dpres_ds + rho*c*dvel_ds(dir_idx(1))) + end subroutine s_compute_nonreflecting_subsonic_buffer_L !> Nonreflecting subsonic inflow CBC (Thompson 1990, pg. 455) subroutine s_compute_nonreflecting_subsonic_inflow_L(lambda, L, rho, c, dpres_ds, dvel_ds) - $:GPU_ROUTINE(function_name='s_compute_nonreflecting_subsonic_inflow_L', & - & parallelism='[seq]', cray_inline=True) + + $:GPU_ROUTINE(function_name='s_compute_nonreflecting_subsonic_inflow_L', parallelism='[seq]', cray_inline=True) real(wp), dimension(3), intent(in) :: lambda #:if USING_AMD @@ -209,12 +218,13 @@ contains L(1) = f_base_L1(lambda, rho, c, dpres_ds, dvel_ds) L(2:advxe) = 0._wp if (chemistry) L(chemxb:chemxe) = 0._wp + end subroutine s_compute_nonreflecting_subsonic_inflow_L !> Nonreflecting subsonic outflow CBC (Thompson 1990, pg. 454) subroutine s_compute_nonreflecting_subsonic_outflow_L(lambda, L, rho, c, mf, dalpha_rho_ds, dpres_ds, dvel_ds, dadv_ds, dYs_ds) - $:GPU_ROUTINE(function_name='s_compute_nonreflecting_subsonic_outflow_L', & - & parallelism='[seq]', cray_inline=True) + + $:GPU_ROUTINE(function_name='s_compute_nonreflecting_subsonic_outflow_L', parallelism='[seq]', cray_inline=True) real(wp), dimension(3), intent(in) :: lambda #:if USING_AMD @@ -223,14 +233,14 @@ contains real(wp), dimension(sys_size), intent(inout) :: L #:endif #:if not MFC_CASE_OPTIMIZATION and USING_AMD - real(wp), dimension(3), intent(in) :: mf, dalpha_rho_ds - real(wp), dimension(3), intent(in) :: dvel_ds - real(wp), dimension(3), intent(in) :: dadv_ds + real(wp), dimension(3), intent(in) :: mf, dalpha_rho_ds + real(wp), dimension(3), intent(in) :: dvel_ds + real(wp), dimension(3), intent(in) :: dadv_ds real(wp), dimension(10), intent(in) :: dYs_ds #:else - real(wp), dimension(num_fluids), intent(in) :: mf, dalpha_rho_ds - real(wp), dimension(num_dims), intent(in) :: dvel_ds - real(wp), dimension(num_fluids), intent(in) :: dadv_ds + real(wp), dimension(num_fluids), intent(in) :: mf, dalpha_rho_ds + real(wp), dimension(num_dims), intent(in) :: dvel_ds + real(wp), dimension(num_fluids), intent(in) :: dadv_ds real(wp), dimension(num_species), intent(in) :: dYs_ds #:endif real(wp), intent(in) :: rho, c @@ -242,12 +252,13 @@ contains call s_fill_advection_L(L, 1._wp, lambda(2), dadv_ds) call s_fill_chemistry_L(L, 1._wp, lambda(2), dYs_ds) L(advxe) = 0._wp + end subroutine s_compute_nonreflecting_subsonic_outflow_L !> Force-free subsonic outflow CBC (Thompson 1990, pg. 454) subroutine s_compute_force_free_subsonic_outflow_L(lambda, L, rho, c, mf, dalpha_rho_ds, dpres_ds, dvel_ds, dadv_ds) - $:GPU_ROUTINE(function_name='s_compute_force_free_subsonic_outflow_L', & - & parallelism='[seq]', cray_inline=True) + + $:GPU_ROUTINE(function_name='s_compute_force_free_subsonic_outflow_L', parallelism='[seq]', cray_inline=True) real(wp), dimension(3), intent(in) :: lambda #:if USING_AMD @@ -261,7 +272,7 @@ contains real(wp), dimension(3), intent(in) :: dadv_ds #:else real(wp), dimension(num_fluids), intent(in) :: mf, dalpha_rho_ds - real(wp), dimension(num_dims), intent(in) :: dvel_ds + real(wp), dimension(num_dims), intent(in) :: dvel_ds real(wp), dimension(num_fluids), intent(in) :: dadv_ds #:endif real(wp), intent(in) :: rho, c @@ -272,12 +283,13 @@ contains call s_fill_velocity_L(L, 1._wp, lambda(2), dvel_ds) call s_fill_advection_L(L, 1._wp, lambda(2), dadv_ds) L(advxe) = L(1) + 2._wp*rho*c*lambda(2)*dvel_ds(dir_idx(1)) + end subroutine s_compute_force_free_subsonic_outflow_L !> Constant pressure subsonic outflow CBC (Thompson 1990, pg. 455) subroutine s_compute_constant_pressure_subsonic_outflow_L(lambda, L, rho, c, mf, dalpha_rho_ds, dpres_ds, dvel_ds, dadv_ds) - $:GPU_ROUTINE(function_name='s_compute_constant_pressure_subsonic_outflow_L', & - & parallelism='[seq]', cray_inline=True) + + $:GPU_ROUTINE(function_name='s_compute_constant_pressure_subsonic_outflow_L', parallelism='[seq]', cray_inline=True) real(wp), dimension(3), intent(in) :: lambda #:if USING_AMD @@ -291,7 +303,7 @@ contains real(wp), dimension(3), intent(in) :: dadv_ds #:else real(wp), dimension(num_fluids), intent(in) :: mf, dalpha_rho_ds - real(wp), dimension(num_dims), intent(in) :: dvel_ds + real(wp), dimension(num_dims), intent(in) :: dvel_ds real(wp), dimension(num_fluids), intent(in) :: dadv_ds #:endif real(wp), intent(in) :: rho, c @@ -302,12 +314,13 @@ contains call s_fill_velocity_L(L, 1._wp, lambda(2), dvel_ds) call s_fill_advection_L(L, 1._wp, lambda(2), dadv_ds) L(advxe) = -L(1) + end subroutine s_compute_constant_pressure_subsonic_outflow_L !> Supersonic inflow CBC (Thompson 1990, pg. 453) subroutine s_compute_supersonic_inflow_L(L) - $:GPU_ROUTINE(function_name='s_compute_supersonic_inflow_L', & - & parallelism='[seq]', cray_inline=True) + + $:GPU_ROUTINE(function_name='s_compute_supersonic_inflow_L', parallelism='[seq]', cray_inline=True) #:if USING_AMD real(wp), dimension(20), intent(inout) :: L #:else @@ -315,12 +328,13 @@ contains #:endif L(1:advxe) = 0._wp if (chemistry) L(chemxb:chemxe) = 0._wp + end subroutine s_compute_supersonic_inflow_L !> Supersonic outflow CBC (Thompson 1990, pg. 453) subroutine s_compute_supersonic_outflow_L(lambda, L, rho, c, mf, dalpha_rho_ds, dpres_ds, dvel_ds, dadv_ds, dYs_ds) - $:GPU_ROUTINE(function_name='s_compute_supersonic_outflow_L', & - & parallelism='[seq]', cray_inline=True) + + $:GPU_ROUTINE(function_name='s_compute_supersonic_outflow_L', parallelism='[seq]', cray_inline=True) real(wp), dimension(3), intent(in) :: lambda #:if USING_AMD @@ -329,14 +343,14 @@ contains real(wp), dimension(sys_size), intent(inout) :: L #:endif #:if not MFC_CASE_OPTIMIZATION and USING_AMD - real(wp), dimension(3), intent(in) :: mf, dalpha_rho_ds - real(wp), dimension(3), intent(in) :: dvel_ds - real(wp), dimension(3), intent(in) :: dadv_ds + real(wp), dimension(3), intent(in) :: mf, dalpha_rho_ds + real(wp), dimension(3), intent(in) :: dvel_ds + real(wp), dimension(3), intent(in) :: dadv_ds real(wp), dimension(10), intent(in) :: dYs_ds #:else - real(wp), dimension(num_fluids), intent(in) :: mf, dalpha_rho_ds - real(wp), dimension(num_dims), intent(in) :: dvel_ds - real(wp), dimension(num_fluids), intent(in) :: dadv_ds + real(wp), dimension(num_fluids), intent(in) :: mf, dalpha_rho_ds + real(wp), dimension(num_dims), intent(in) :: dvel_ds + real(wp), dimension(num_fluids), intent(in) :: dadv_ds real(wp), dimension(num_species), intent(in) :: dYs_ds #:endif real(wp), intent(in) :: rho, c @@ -348,5 +362,7 @@ contains call s_fill_advection_L(L, 1._wp, lambda(2), dadv_ds) call s_fill_chemistry_L(L, 1._wp, lambda(2), dYs_ds) L(advxe) = lambda(3)*(dpres_ds + rho*c*dvel_ds(dir_idx(1))) + end subroutine s_compute_supersonic_outflow_L + end module m_compute_cbc diff --git a/src/simulation/m_compute_levelset.fpp b/src/simulation/m_compute_levelset.fpp index f5d07f9e58..e7f23db4dc 100644 --- a/src/simulation/m_compute_levelset.fpp +++ b/src/simulation/m_compute_levelset.fpp @@ -7,17 +7,12 @@ !> @brief Computes signed-distance level-set fields and surface normals for immersed-boundary patch geometries module m_compute_levelset - use m_ib_patches !< The IB patch parameters - - use m_model !< Subroutine(s) related to STL files - - use m_derived_types !< Definitions of the derived types - - use m_global_parameters !< Definitions of the global parameters - - use m_mpi_proxy !< Message passing interface (MPI) module proxy - - use m_helper_basic !< Functions to compare floating point numbers + use m_ib_patches !< The IB patch parameters + use m_model !< Subroutine(s) related to STL files + use m_derived_types !< Definitions of the derived types + use m_global_parameters !< Definitions of the global parameters + use m_mpi_proxy !< Message passing interface (MPI) module proxy + use m_helper_basic !< Functions to compare floating point numbers implicit none @@ -29,56 +24,51 @@ contains impure subroutine s_apply_levelset(gps, num_gps) type(ghost_point), dimension(:), intent(inout) :: gps - integer, intent(in) :: num_gps - - integer :: i, patch_id, patch_geometry + integer, intent(in) :: num_gps + integer :: i, patch_id, patch_geometry ! 3D Patch Geometries - if (p > 0) then - $:GPU_PARALLEL_LOOP(private='[i,patch_id,patch_geometry]', copy='[gps]', copyin='[patch_ib(1:num_ibs),Np]') + if (p > 0) then + $:GPU_PARALLEL_LOOP(private='[i, patch_id, patch_geometry]', copy='[gps]', copyin='[patch_ib(1:num_ibs), Np]') do i = 1, num_gps - patch_id = gps(i)%ib_patch_id patch_geometry = patch_ib(patch_id)%geometry if (patch_geometry == 8) then call s_sphere_levelset(gps(i)) - elseif (patch_geometry == 9) then + else if (patch_geometry == 9) then call s_cuboid_levelset(gps(i)) - elseif (patch_geometry == 10) then + else if (patch_geometry == 10) then call s_cylinder_levelset(gps(i)) - elseif (patch_geometry == 11) then + else if (patch_geometry == 11) then call s_3d_airfoil_levelset(gps(i)) - elseif (patch_geometry == 12) then + else if (patch_geometry == 12) then call s_model_levelset(gps(i)) end if end do $:END_GPU_PARALLEL_LOOP() ! 2D Patch Geometries - elseif (n > 0) then - - $:GPU_PARALLEL_LOOP(private='[i,patch_id,patch_geometry]', copy='[gps]', copyin='[Np,patch_ib(1:num_ibs)]') + else if (n > 0) then + $:GPU_PARALLEL_LOOP(private='[i, patch_id, patch_geometry]', copy='[gps]', copyin='[Np, patch_ib(1:num_ibs)]') do i = 1, num_gps - patch_id = gps(i)%ib_patch_id patch_geometry = patch_ib(patch_id)%geometry if (patch_geometry == 2) then call s_circle_levelset(gps(i)) - elseif (patch_geometry == 3) then + else if (patch_geometry == 3) then call s_rectangle_levelset(gps(i)) - elseif (patch_geometry == 4) then + else if (patch_geometry == 4) then call s_airfoil_levelset(gps(i)) - elseif (patch_geometry == 5) then + else if (patch_geometry == 5) then call s_model_levelset(gps(i)) - elseif (patch_geometry == 6) then + else if (patch_geometry == 6) then call s_ellipse_levelset(gps(i)) end if end do $:END_GPU_PARALLEL_LOOP() - end if end subroutine s_apply_levelset @@ -89,12 +79,10 @@ contains $:GPU_ROUTINE(parallelism='[seq]') type(ghost_point), intent(inout) :: gp - - real(wp) :: radius, dist - real(wp), dimension(2) :: center - real(wp), dimension(3) :: dist_vec - - integer :: i, j, ib_patch_id !< Loop index variables + real(wp) :: radius, dist + real(wp), dimension(2) :: center + real(wp), dimension(3) :: dist_vec + integer :: i, j, ib_patch_id !< Loop index variables ib_patch_id = gp%ib_patch_id i = gp%loc(1) @@ -102,8 +90,10 @@ contains radius = patch_ib(ib_patch_id)%radius - dist_vec(1) = x_cc(i) - patch_ib(ib_patch_id)%x_centroid - real(gp%x_periodicity, wp)*(glb_bounds(1)%end - glb_bounds(1)%beg) - dist_vec(2) = y_cc(j) - patch_ib(ib_patch_id)%y_centroid - real(gp%y_periodicity, wp)*(glb_bounds(2)%end - glb_bounds(2)%beg) + dist_vec(1) = x_cc(i) - patch_ib(ib_patch_id)%x_centroid - real(gp%x_periodicity, & + & wp)*(glb_bounds(1)%end - glb_bounds(1)%beg) + dist_vec(2) = y_cc(j) - patch_ib(ib_patch_id)%y_centroid - real(gp%y_periodicity, & + & wp)*(glb_bounds(2)%end - glb_bounds(2)%beg) dist_vec(3) = 0._wp dist = sqrt(sum(dist_vec**2)) @@ -122,16 +112,13 @@ contains $:GPU_ROUTINE(parallelism='[seq]') type(ghost_point), intent(inout) :: gp - - real(wp) :: dist, global_dist - integer :: global_id - real(wp), dimension(3) :: dist_vec - - real(wp), dimension(1:3) :: xy_local, offset !< x and y coordinates in local IB frame - real(wp), dimension(1:2) :: center - real(wp), dimension(1:3, 1:3) :: rotation, inverse_rotation - - integer :: i, j, k, ib_patch_id !< Loop index variables + real(wp) :: dist, global_dist + integer :: global_id + real(wp), dimension(3) :: dist_vec + real(wp), dimension(1:3) :: xy_local, offset !< x and y coordinates in local IB frame + real(wp), dimension(1:2) :: center + real(wp), dimension(1:3,1:3) :: rotation, inverse_rotation + integer :: i, j, k, ib_patch_id !< Loop index variables ib_patch_id = gp%ib_patch_id i = gp%loc(1) @@ -139,13 +126,13 @@ contains center(1) = patch_ib(ib_patch_id)%x_centroid + real(gp%x_periodicity, wp)*(glb_bounds(1)%end - glb_bounds(1)%beg) center(2) = patch_ib(ib_patch_id)%y_centroid + real(gp%y_periodicity, wp)*(glb_bounds(2)%end - glb_bounds(2)%beg) - inverse_rotation(:, :) = patch_ib(ib_patch_id)%rotation_matrix_inverse(:, :) - rotation(:, :) = patch_ib(ib_patch_id)%rotation_matrix(:, :) + inverse_rotation(:,:) = patch_ib(ib_patch_id)%rotation_matrix_inverse(:,:) + rotation(:,:) = patch_ib(ib_patch_id)%rotation_matrix(:,:) offset(:) = patch_ib(ib_patch_id)%centroid_offset(:) - xy_local = [x_cc(i) - center(1), y_cc(j) - center(2), 0._wp] ! get coordinate frame centered on IB - xy_local = matmul(inverse_rotation, xy_local) ! rotate the frame into the IB's coordinate - xy_local = xy_local - offset ! airfoils are a patch that require a centroid offset + xy_local = [x_cc(i) - center(1), y_cc(j) - center(2), 0._wp] ! get coordinate frame centered on IB + xy_local = matmul(inverse_rotation, xy_local) ! rotate the frame into the IB's coordinate + xy_local = xy_local - offset ! airfoils are a patch that require a centroid offset if (xy_local(2) >= 0._wp) then ! finds the location on the airfoil grid with the minimum distance (closest) @@ -194,29 +181,26 @@ contains if (f_approx_equal(dist, 0._wp)) then gp%levelset_norm = 0._wp else - gp%levelset_norm = matmul(rotation, dist_vec(:))/dist ! convert the normal vector back to global grid coordinates + gp%levelset_norm = matmul(rotation, dist_vec(:))/dist ! convert the normal vector back to global grid coordinates end if end subroutine s_airfoil_levelset - !> @brief Computes the signed distance and outward normal from a ghost point to a 3D extruded airfoil surface including spanwise end caps. + !> @brief Computes the signed distance and outward normal from a ghost point to a 3D extruded airfoil surface including spanwise + !! end caps. subroutine s_3d_airfoil_levelset(gp) $:GPU_ROUTINE(parallelism='[seq]') type(ghost_point), intent(inout) :: gp - - real(wp) :: dist, dist_surf, dist_side, global_dist - integer :: global_id - real(wp) :: lz, z_max, z_min - real(wp), dimension(3) :: dist_vec - - real(wp), dimension(1:3) :: xyz_local, center, offset, normal !< x, y, z coordinates in local IB frame - real(wp), dimension(1:3, 1:3) :: rotation, inverse_rotation - - real(wp) :: length_z - - integer :: i, j, k, l, ib_patch_id !< Loop index variables + real(wp) :: dist, dist_surf, dist_side, global_dist + integer :: global_id + real(wp) :: lz, z_max, z_min + real(wp), dimension(3) :: dist_vec + real(wp), dimension(1:3) :: xyz_local, center, offset, normal !< x, y, z coordinates in local IB frame + real(wp), dimension(1:3,1:3) :: rotation, inverse_rotation + real(wp) :: length_z + integer :: i, j, k, l, ib_patch_id !< Loop index variables ib_patch_id = gp%ib_patch_id i = gp%loc(1) @@ -227,16 +211,16 @@ contains center(2) = patch_ib(ib_patch_id)%y_centroid + real(gp%y_periodicity, wp)*(glb_bounds(2)%end - glb_bounds(2)%beg) center(3) = patch_ib(ib_patch_id)%z_centroid + real(gp%z_periodicity, wp)*(glb_bounds(3)%end - glb_bounds(3)%beg) lz = patch_ib(ib_patch_id)%length_z - inverse_rotation(:, :) = patch_ib(ib_patch_id)%rotation_matrix_inverse(:, :) - rotation(:, :) = patch_ib(ib_patch_id)%rotation_matrix(:, :) + inverse_rotation(:,:) = patch_ib(ib_patch_id)%rotation_matrix_inverse(:,:) + rotation(:,:) = patch_ib(ib_patch_id)%rotation_matrix(:,:) offset(:) = patch_ib(ib_patch_id)%centroid_offset(:) z_max = lz/2 z_min = -lz/2 xyz_local = [x_cc(i), y_cc(j), z_cc(l)] - center - xyz_local = matmul(inverse_rotation, xyz_local) ! rotate the frame into the IB's coordinates - xyz_local = xyz_local - offset ! airfoils are a patch that require a centroid offset + xyz_local = matmul(inverse_rotation, xyz_local) ! rotate the frame into the IB's coordinates + xyz_local = xyz_local - offset ! airfoils are a patch that require a centroid offset if (xyz_local(2) >= 0._wp) then do k = 1, Np @@ -302,25 +286,22 @@ contains end subroutine s_3d_airfoil_levelset - !> Subroutine for computing the levelset values at a ghost point belonging to the rectangle IB + !> Subroutine for computing the levelset values at a ghost point belonging to the rectangle IB subroutine s_rectangle_levelset(gp) $:GPU_ROUTINE(parallelism='[seq]') type(ghost_point), intent(inout) :: gp - - real(wp) :: top_right(2), bottom_left(2) - real(wp) :: min_dist - real(wp) :: side_dists(4) - - real(wp) :: length_x, length_y - real(wp), dimension(1:3) :: xy_local, dist_vec !< x and y coordinates in local IB frame - real(wp), dimension(2) :: center !< x and y coordinates in local IB frame - real(wp), dimension(1:3, 1:3) :: rotation, inverse_rotation - - integer :: i, j, k !< Loop index variables - integer :: idx !< Shortest path direction indicator - integer :: ib_patch_id !< patch ID + real(wp) :: top_right(2), bottom_left(2) + real(wp) :: min_dist + real(wp) :: side_dists(4) + real(wp) :: length_x, length_y + real(wp), dimension(1:3) :: xy_local, dist_vec !< x and y coordinates in local IB frame + real(wp), dimension(2) :: center !< x and y coordinates in local IB frame + real(wp), dimension(1:3,1:3) :: rotation, inverse_rotation + integer :: i, j, k !< Loop index variables + integer :: idx !< Shortest path direction indicator + integer :: ib_patch_id !< patch ID ib_patch_id = gp%ib_patch_id i = gp%loc(1) @@ -330,8 +311,8 @@ contains length_y = patch_ib(ib_patch_id)%length_y center(1) = patch_ib(ib_patch_id)%x_centroid + real(gp%x_periodicity, wp)*(glb_bounds(1)%end - glb_bounds(1)%beg) center(2) = patch_ib(ib_patch_id)%y_centroid + real(gp%y_periodicity, wp)*(glb_bounds(2)%end - glb_bounds(2)%beg) - inverse_rotation(:, :) = patch_ib(ib_patch_id)%rotation_matrix_inverse(:, :) - rotation(:, :) = patch_ib(ib_patch_id)%rotation_matrix(:, :) + inverse_rotation(:,:) = patch_ib(ib_patch_id)%rotation_matrix_inverse(:,:) + rotation(:,:) = patch_ib(ib_patch_id)%rotation_matrix(:,:) top_right(1) = length_x/2 top_right(2) = length_y/2 @@ -374,24 +355,22 @@ contains end subroutine s_rectangle_levelset - !> @brief Computes the signed distance and outward normal from a ghost point to an elliptical immersed boundary via a quadratic projection. + !> @brief Computes the signed distance and outward normal from a ghost point to an elliptical immersed boundary via a quadratic + !! projection. subroutine s_ellipse_levelset(gp) $:GPU_ROUTINE(parallelism='[seq]') type(ghost_point), intent(inout) :: gp - - real(wp) :: ellipse_coeffs(2) ! a and b in the ellipse equation - real(wp) :: quadratic_coeffs(3) ! A, B, C in the quadratic equation to compute levelset - - real(wp) :: length_x, length_y - real(wp), dimension(1:3) :: xy_local, normal_vector !< x and y coordinates in local IB frame - real(wp), dimension(2) :: center !< x and y coordinates in local IB frame - real(wp), dimension(1:3, 1:3) :: rotation, inverse_rotation - - integer :: i, j, k !< Loop index variables - integer :: idx !< Shortest path direction indicator - integer :: ib_patch_id !< patch ID + real(wp) :: ellipse_coeffs(2) ! a and b in the ellipse equation + real(wp) :: quadratic_coeffs(3) ! A, B, C in the quadratic equation to compute levelset + real(wp) :: length_x, length_y + real(wp), dimension(1:3) :: xy_local, normal_vector !< x and y coordinates in local IB frame + real(wp), dimension(2) :: center !< x and y coordinates in local IB frame + real(wp), dimension(1:3,1:3) :: rotation, inverse_rotation + integer :: i, j, k !< Loop index variables + integer :: idx !< Shortest path direction indicator + integer :: ib_patch_id !< patch ID ib_patch_id = gp%ib_patch_id i = gp%loc(1) @@ -401,8 +380,8 @@ contains length_y = patch_ib(ib_patch_id)%length_y center(1) = patch_ib(ib_patch_id)%x_centroid + real(gp%x_periodicity, wp)*(glb_bounds(1)%end - glb_bounds(1)%beg) center(2) = patch_ib(ib_patch_id)%y_centroid + real(gp%y_periodicity, wp)*(glb_bounds(2)%end - glb_bounds(2)%beg) - inverse_rotation(:, :) = patch_ib(ib_patch_id)%rotation_matrix_inverse(:, :) - rotation(:, :) = patch_ib(ib_patch_id)%rotation_matrix(:, :) + inverse_rotation(:,:) = patch_ib(ib_patch_id)%rotation_matrix_inverse(:,:) + rotation(:,:) = patch_ib(ib_patch_id)%rotation_matrix(:,:) ellipse_coeffs(1) = 0.5_wp*length_x ellipse_coeffs(2) = 0.5_wp*length_y @@ -411,17 +390,20 @@ contains xy_local = matmul(inverse_rotation, xy_local) normal_vector = xy_local - normal_vector(2) = normal_vector(2)*(ellipse_coeffs(1)/ellipse_coeffs(2))**2._wp ! get the normal direction via the coordinate transformation method - normal_vector = normal_vector/sqrt(dot_product(normal_vector, normal_vector)) ! normalize the vector - gp%levelset_norm = matmul(rotation, normal_vector) ! save after rotating the vector to the global frame + normal_vector(2) = normal_vector(2)*(ellipse_coeffs(1)/ellipse_coeffs(2)) & + & **2._wp ! get the normal direction via the coordinate transformation method + normal_vector = normal_vector/sqrt(dot_product(normal_vector, normal_vector)) ! normalize the vector + gp%levelset_norm = matmul(rotation, normal_vector) ! save after rotating the vector to the global frame ! use the normal vector to set up the quadratic equation for the levelset, using A, B, and C in indices 1, 2, and 3 quadratic_coeffs(1) = (normal_vector(1)/ellipse_coeffs(1))**2 + (normal_vector(2)/ellipse_coeffs(2))**2 - quadratic_coeffs(2) = 2._wp*((xy_local(1)*normal_vector(1)/(ellipse_coeffs(1)**2)) + (xy_local(2)*normal_vector(2)/(ellipse_coeffs(2)**2))) + quadratic_coeffs(2) = 2._wp*((xy_local(1)*normal_vector(1)/(ellipse_coeffs(1)**2)) + (xy_local(2)*normal_vector(2) & + & /(ellipse_coeffs(2)**2))) quadratic_coeffs(3) = (xy_local(1)/ellipse_coeffs(1))**2._wp + (xy_local(2)/ellipse_coeffs(2))**2._wp - 1._wp ! compute the levelset with the quadratic equation [ -B + sqrt(B^2 - 4AC) ] / 2A - gp%levelset = -0.5_wp*(-quadratic_coeffs(2) + sqrt(quadratic_coeffs(2)**2._wp - 4._wp*quadratic_coeffs(1)*quadratic_coeffs(3)))/quadratic_coeffs(1) + gp%levelset = -0.5_wp*(-quadratic_coeffs(2) + sqrt(quadratic_coeffs(2)**2._wp - 4._wp*quadratic_coeffs(1) & + & *quadratic_coeffs(3)))/quadratic_coeffs(1) end subroutine s_ellipse_levelset @@ -431,18 +413,15 @@ contains $:GPU_ROUTINE(parallelism='[seq]') type(ghost_point), intent(inout) :: gp - - real(wp) :: Right, Left, Bottom, Top, Front, Back - real(wp) :: min_dist - real(wp) :: dist_left, dist_right, dist_bottom, dist_top, dist_back, dist_front - - real(wp), dimension(3) :: center - real(wp) :: length_x, length_y, length_z - real(wp), dimension(1:3) :: xyz_local, dist_vec !< x and y coordinates in local IB frame - real(wp), dimension(1:3, 1:3) :: rotation, inverse_rotation - - integer :: i, j, k !< Loop index variables - integer :: ib_patch_id !< patch ID + real(wp) :: Right, Left, Bottom, Top, Front, Back + real(wp) :: min_dist + real(wp) :: dist_left, dist_right, dist_bottom, dist_top, dist_back, dist_front + real(wp), dimension(3) :: center + real(wp) :: length_x, length_y, length_z + real(wp), dimension(1:3) :: xyz_local, dist_vec !< x and y coordinates in local IB frame + real(wp), dimension(1:3,1:3) :: rotation, inverse_rotation + integer :: i, j, k !< Loop index variables + integer :: ib_patch_id !< patch ID ib_patch_id = gp%ib_patch_id i = gp%loc(1) @@ -457,8 +436,8 @@ contains center(2) = patch_ib(ib_patch_id)%y_centroid + real(gp%y_periodicity, wp)*(glb_bounds(2)%end - glb_bounds(2)%beg) center(3) = patch_ib(ib_patch_id)%z_centroid + real(gp%z_periodicity, wp)*(glb_bounds(3)%end - glb_bounds(3)%beg) - inverse_rotation(:, :) = patch_ib(ib_patch_id)%rotation_matrix_inverse(:, :) - rotation(:, :) = patch_ib(ib_patch_id)%rotation_matrix(:, :) + inverse_rotation(:,:) = patch_ib(ib_patch_id)%rotation_matrix_inverse(:,:) + rotation(:,:) = patch_ib(ib_patch_id)%rotation_matrix(:,:) Right = length_x/2 Left = -length_x/2 @@ -467,8 +446,8 @@ contains Front = length_z/2 Back = -length_z/2 - xyz_local = [x_cc(i), y_cc(j), z_cc(k)] - center ! get coordinate frame centered on IB - xyz_local = matmul(inverse_rotation, xyz_local) ! rotate the frame into the IB's coordinate + xyz_local = [x_cc(i), y_cc(j), z_cc(k)] - center ! get coordinate frame centered on IB + xyz_local = matmul(inverse_rotation, xyz_local) ! rotate the frame into the IB's coordinate dist_left = Left - xyz_local(1) dist_right = xyz_local(1) - Right @@ -477,8 +456,7 @@ contains dist_back = Back - xyz_local(3) dist_front = xyz_local(3) - Front - min_dist = min(abs(dist_left), abs(dist_right), abs(dist_bottom), & - abs(dist_top), abs(dist_back), abs(dist_front)) + min_dist = min(abs(dist_left), abs(dist_right), abs(dist_bottom), abs(dist_top), abs(dist_back), abs(dist_front)) dist_vec = 0._wp if (f_approx_equal(min_dist, abs(dist_left))) then @@ -523,11 +501,9 @@ contains $:GPU_ROUTINE(parallelism='[seq]') type(ghost_point), intent(inout) :: gp - - real(wp) :: radius, dist - real(wp), dimension(3) :: dist_vec, center, periodicity - - integer :: i, j, k, ib_patch_id !< Loop index variables + real(wp) :: radius, dist + real(wp), dimension(3) :: dist_vec, center, periodicity + integer :: i, j, k, ib_patch_id !< Loop index variables ib_patch_id = gp%ib_patch_id i = gp%loc(1) @@ -556,22 +532,21 @@ contains end subroutine s_sphere_levelset - !> @brief Computes the signed distance and outward normal from a ghost point to a cylindrical immersed boundary surface and end caps. + !> @brief Computes the signed distance and outward normal from a ghost point to a cylindrical immersed boundary surface and end + !! caps. subroutine s_cylinder_levelset(gp) $:GPU_ROUTINE(parallelism='[seq]') type(ghost_point), intent(inout) :: gp - - real(wp) :: radius - real(wp), dimension(3) :: dist_sides_vec, dist_surface_vec, length - real(wp), dimension(2) :: boundary - real(wp) :: dist_side, dist_surface, side_pos - integer :: i, j, k !< Loop index variables - integer :: ib_patch_id !< patch ID - - real(wp), dimension(1:3) :: xyz_local, center !< x and y coordinates in local IB frame - real(wp), dimension(1:3, 1:3) :: rotation, inverse_rotation + real(wp) :: radius + real(wp), dimension(3) :: dist_sides_vec, dist_surface_vec, length + real(wp), dimension(2) :: boundary + real(wp) :: dist_side, dist_surface, side_pos + integer :: i, j, k !< Loop index variables + integer :: ib_patch_id !< patch ID + real(wp), dimension(1:3) :: xyz_local, center !< x and y coordinates in local IB frame + real(wp), dimension(1:3,1:3) :: rotation, inverse_rotation ib_patch_id = gp%ib_patch_id i = gp%loc(1) @@ -586,8 +561,8 @@ contains length(2) = patch_ib(ib_patch_id)%length_y length(3) = patch_ib(ib_patch_id)%length_z - inverse_rotation(:, :) = patch_ib(ib_patch_id)%rotation_matrix_inverse(:, :) - rotation(:, :) = patch_ib(ib_patch_id)%rotation_matrix(:, :) + inverse_rotation(:,:) = patch_ib(ib_patch_id)%rotation_matrix_inverse(:,:) + rotation(:,:) = patch_ib(ib_patch_id)%rotation_matrix(:,:) if (.not. f_approx_equal(length(1), 0._wp)) then boundary(1) = -0.5_wp*length(1) @@ -606,16 +581,14 @@ contains dist_surface_vec = (/1, 1, 0/) end if - xyz_local = [x_cc(i), y_cc(j), z_cc(k)] - center ! get coordinate frame centered on IB - xyz_local = matmul(inverse_rotation, xyz_local) ! rotate the frame into the IB's coordinates + xyz_local = [x_cc(i), y_cc(j), z_cc(k)] - center ! get coordinate frame centered on IB + xyz_local = matmul(inverse_rotation, xyz_local) ! rotate the frame into the IB's coordinates ! get distance to flat edge of cylinder side_pos = dot_product(xyz_local, dist_sides_vec) - dist_side = min(abs(side_pos - boundary(1)), & - abs(boundary(2) - side_pos)) + dist_side = min(abs(side_pos - boundary(1)), abs(boundary(2) - side_pos)) ! get distance to curved side of cylinder - dist_surface = norm2(xyz_local*dist_surface_vec) & - - radius + dist_surface = norm2(xyz_local*dist_surface_vec) - radius if (dist_side < abs(dist_surface)) then ! if the closest edge is flat @@ -641,12 +614,11 @@ contains $:GPU_ROUTINE(parallelism='[seq]') type(ghost_point), intent(inout) :: gp - - integer :: i, j, k, patch_id, boundary_edge_count, total_vertices - real(wp), dimension(1:3) :: center, xyz_local - real(wp) :: normals(1:3) !< Boundary normal buffer - real(wp) :: distance - real(wp), dimension(1:3, 1:3) :: inverse_rotation, rotation + integer :: i, j, k, patch_id, boundary_edge_count, total_vertices + real(wp), dimension(1:3) :: center, xyz_local + real(wp) :: normals(1:3) !< Boundary normal buffer + real(wp) :: distance + real(wp), dimension(1:3,1:3) :: inverse_rotation, rotation patch_id = gp%ib_patch_id i = gp%loc(1) @@ -658,14 +630,17 @@ contains total_vertices = gpu_total_vertices(patch_id) center = 0._wp - if (.not. f_is_default(patch_ib(patch_id)%x_centroid)) center(1) = patch_ib(patch_id)%x_centroid + real(gp%x_periodicity, wp)*(glb_bounds(1)%end - glb_bounds(1)%beg) - if (.not. f_is_default(patch_ib(patch_id)%y_centroid)) center(2) = patch_ib(patch_id)%y_centroid + real(gp%y_periodicity, wp)*(glb_bounds(2)%end - glb_bounds(2)%beg) + if (.not. f_is_default(patch_ib(patch_id)%x_centroid)) center(1) = patch_ib(patch_id)%x_centroid + real(gp%x_periodicity, & + & wp)*(glb_bounds(1)%end - glb_bounds(1)%beg) + if (.not. f_is_default(patch_ib(patch_id)%y_centroid)) center(2) = patch_ib(patch_id)%y_centroid + real(gp%y_periodicity, & + & wp)*(glb_bounds(2)%end - glb_bounds(2)%beg) if (p > 0) then - if (.not. f_is_default(patch_ib(patch_id)%z_centroid)) center(3) = patch_ib(patch_id)%z_centroid + real(gp%z_periodicity, wp)*(glb_bounds(3)%end - glb_bounds(3)%beg) + if (.not. f_is_default(patch_ib(patch_id)%z_centroid)) center(3) = patch_ib(patch_id)%z_centroid & + & + real(gp%z_periodicity, wp)*(glb_bounds(3)%end - glb_bounds(3)%beg) end if - inverse_rotation(:, :) = patch_ib(patch_id)%rotation_matrix_inverse(:, :) - rotation(:, :) = patch_ib(patch_id)%rotation_matrix(:, :) + inverse_rotation(:,:) = patch_ib(patch_id)%rotation_matrix_inverse(:,:) + rotation(:,:) = patch_ib(patch_id)%rotation_matrix(:,:) ! determine where we are located in space xyz_local = (/x_cc(i) - center(1), y_cc(j) - center(2), 0._wp/) @@ -687,9 +662,7 @@ contains gp%levelset_norm = matmul(rotation, normals(1:3)) else ! 2D models - call s_distance_normals_2D(patch_id, & - boundary_edge_count, & - xyz_local, normals, distance) + call s_distance_normals_2D(patch_id, boundary_edge_count, xyz_local, normals, distance) gp%levelset = -abs(distance) gp%levelset_norm = matmul(rotation, normals(1:3)) end if diff --git a/src/simulation/m_data_output.fpp b/src/simulation/m_data_output.fpp index 58b5c4cd1a..0b03033c25 100644 --- a/src/simulation/m_data_output.fpp +++ b/src/simulation/m_data_output.fpp @@ -8,61 +8,37 @@ !> @brief Writes solution data, run-time stability diagnostics (ICFL, VCFL, CCFL, Rc), and probe/center-of-mass files module m_data_output - use m_derived_types !< Definitions of the derived types - - use m_global_parameters !< Definitions of the global parameters - - use m_mpi_proxy !< Message passing interface (MPI) module proxy - - use m_variables_conversion !< State variables type conversion procedures - + use m_derived_types !< Definitions of the derived types + use m_global_parameters !< Definitions of the global parameters + use m_mpi_proxy !< Message passing interface (MPI) module proxy + use m_variables_conversion !< State variables type conversion procedures use m_compile_specific - use m_helper - - use m_helper_basic !< Functions to compare floating point numbers - + use m_helper_basic !< Functions to compare floating point numbers use m_sim_helpers - use m_delay_file_access - use m_ibm - use m_boundary_common implicit none - private; - public :: s_initialize_data_output_module, & - s_open_run_time_information_file, & - s_open_com_files, & - s_open_probe_files, & - s_open_ib_state_file, & - s_write_run_time_information, & - s_write_data_files, & - s_write_serial_data_files, & - s_write_parallel_data_files, & - s_write_ib_data_file, & - s_write_com_files, & - s_write_probe_files, & - s_write_ib_state_file, & - s_close_run_time_information_file, & - s_close_com_files, & - s_close_probe_files, & - s_close_ib_state_file, & - s_finalize_data_output_module - - integer :: ib_state_unit = -1 !< I/O unit for IB state binary file - - real(wp), public, allocatable, dimension(:, :) :: c_mass + private + public :: s_initialize_data_output_module, s_open_run_time_information_file, s_open_com_files, s_open_probe_files, & + & s_open_ib_state_file, s_write_run_time_information, s_write_data_files, s_write_serial_data_files, & + & s_write_parallel_data_files, s_write_ib_data_file, s_write_com_files, s_write_probe_files, s_write_ib_state_file, & + & s_close_run_time_information_file, s_close_com_files, s_close_probe_files, s_close_ib_state_file, & + & s_finalize_data_output_module + + integer :: ib_state_unit = -1 !< I/O unit for IB state binary file + real(wp), public, allocatable, dimension(:,:) :: c_mass $:GPU_DECLARE(create='[c_mass]') !> @name ICFL, VCFL, CCFL and Rc stability criteria extrema over all the time-steps !> @{ - real(wp) :: icfl_max !< ICFL criterion maximum - real(wp) :: vcfl_max !< VCFL criterion maximum - real(wp) :: ccfl_max !< CCFL criterion maximum - real(wp) :: Rc_min !< Rc criterion maximum + real(wp) :: icfl_max !< ICFL criterion maximum + real(wp) :: vcfl_max !< VCFL criterion maximum + real(wp) :: ccfl_max !< CCFL criterion maximum + real(wp) :: Rc_min !< Rc criterion maximum !> @} type(scalar_field), allocatable, dimension(:) :: q_cons_temp_ds @@ -70,33 +46,20 @@ module m_data_output contains !> Write data files. Dispatch subroutine that replaces procedure pointer. - !! @param q_cons_vf Conservative variables - !! @param q_T_sf Temperature scalar field - !! @param q_prim_vf Primitive variables - !! @param t_step Current time step - !! @param bc_type Boundary condition type - !! @param beta Eulerian void fraction from lagrangian bubbles + !! @param q_cons_vf Conservative variables + !! @param q_T_sf Temperature scalar field + !! @param q_prim_vf Primitive variables + !! @param t_step Current time step + !! @param bc_type Boundary condition type + !! @param beta Eulerian void fraction from lagrangian bubbles impure subroutine s_write_data_files(q_cons_vf, q_T_sf, q_prim_vf, t_step, bc_type, beta) - type(scalar_field), & - dimension(sys_size), & - intent(inout) :: q_cons_vf - - type(scalar_field), & - intent(inout) :: q_T_sf - - type(scalar_field), & - dimension(sys_size), & - intent(inout) :: q_prim_vf - - integer, intent(in) :: t_step - - type(scalar_field), & - intent(inout), optional :: beta - - type(integer_field), & - dimension(1:num_dims, -1:1), & - intent(in) :: bc_type + type(scalar_field), dimension(sys_size), intent(inout) :: q_cons_vf + type(scalar_field), intent(inout) :: q_T_sf + type(scalar_field), dimension(sys_size), intent(inout) :: q_prim_vf + integer, intent(in) :: t_step + type(scalar_field), intent(inout), optional :: beta + type(integer_field), dimension(1:num_dims,-1:1), intent(in) :: bc_type if (.not. parallel_io) then call s_write_serial_data_files(q_cons_vf, q_T_sf, q_prim_vf, t_step, bc_type, beta) @@ -106,207 +69,160 @@ contains end subroutine s_write_data_files - !> The purpose of this subroutine is to open a new or pre- - !! existing run-time information file and append to it the - !! basic header information relevant to current simulation. - !! In general, this requires generating a table header for - !! those stability criteria which will be written at every - !! time-step. + !> The purpose of this subroutine is to open a new or pre- existing run-time information file and append to it the basic header + !! information relevant to current simulation. In general, this requires generating a table header for those stability criteria + !! which will be written at every time-step. impure subroutine s_open_run_time_information_file - character(LEN=name_len), parameter :: file_name = 'run_time.inf' !< - !! Name of the run-time information file + character(LEN=name_len), parameter :: file_name = 'run_time.inf' !< Name of the run-time information file + character(LEN=path_len + name_len) :: file_path !< Relative path to a file in the case directory + character(LEN=8) :: file_date !< Creation date of the run-time information file - character(LEN=path_len + name_len) :: file_path !< - !! Relative path to a file in the case directory + ! Opening the run-time information file - character(LEN=8) :: file_date !< - !! Creation date of the run-time information file + file_path = trim(case_dir) // '/' // trim(file_name) - ! Opening the run-time information file - file_path = trim(case_dir)//'/'//trim(file_name) - - open (3, FILE=trim(file_path), & - FORM='formatted', & - STATUS='replace') - - write (3, '(A)') 'Description: Stability information at '// & - 'each time-step of the simulation. This' - write (3, '(13X,A)') 'data is composed of the inviscid '// & - 'Courant-Friedrichs-Lewy (ICFL)' - write (3, '(13X,A)') 'number, the viscous CFL (VCFL) number, '// & - 'the capillary CFL (CCFL)' - write (3, '(13X,A)') 'number and the cell Reynolds (Rc) '// & - 'number. Please note that only' - write (3, '(13X,A)') 'those stability conditions pertinent '// & - 'to the physics included in' + open (3, FILE=trim(file_path), form='formatted', STATUS='replace') + + write (3, '(A)') 'Description: Stability information at ' // 'each time-step of the simulation. This' + write (3, '(13X,A)') 'data is composed of the inviscid ' // 'Courant-Friedrichs-Lewy (ICFL)' + write (3, '(13X,A)') 'number, the viscous CFL (VCFL) number, ' // 'the capillary CFL (CCFL)' + write (3, '(13X,A)') 'number and the cell Reynolds (Rc) ' // 'number. Please note that only' + write (3, '(13X,A)') 'those stability conditions pertinent ' // 'to the physics included in' write (3, '(13X,A)') 'the current computation are displayed.' call date_and_time(DATE=file_date) - write (3, '(A)') 'Date: '//file_date(5:6)//'/'// & - file_date(7:8)//'/'// & - file_date(3:4) + write (3, '(A)') 'Date: ' // file_date(5:6) // '/' // file_date(7:8) // '/' // file_date(3:4) write (3, '(A)') ''; write (3, '(A)') '' ! Generating table header for the stability criteria to be outputted - write (3, '(13X,A9,13X,A10,13X,A10,13X,A10)', advance="no") & - trim('Time-step'), trim('dt'), trim('Time'), trim('ICFL Max') + write (3, '(13X,A9,13X,A10,13X,A10,13X,A10)', advance="no") trim('Time-step'), trim('dt'), trim('Time'), trim('ICFL Max') if (viscous) then - write (3, '(13X,A10,13X,A16)', advance="no") & - trim('VCFL Max'), trim('Rc Min') + write (3, '(13X,A10,13X,A16)', advance="no") trim('VCFL Max'), trim('Rc Min') end if if (bubbles_lagrange) then write (3, '(13X,A10)', advance="no") trim('N Bubbles') end if - write (3, *) ! new line + write (3, *) ! new line end subroutine s_open_run_time_information_file - !> This opens a formatted data file where the root processor - !! can write out the CoM information + !> This opens a formatted data file where the root processor can write out the CoM information impure subroutine s_open_com_files() - character(len=path_len + 3*name_len) :: file_path !< - !! Relative path to the CoM file in the case directory - integer :: i !< Generic loop iterator + character(len=path_len + 3*name_len) :: file_path !< Relative path to the CoM file in the case directory + integer :: i !< Generic loop iterator do i = 1, num_fluids ! Generating the relative path to the CoM data file write (file_path, '(A,I0,A)') '/fluid', i, '_com.dat' - file_path = trim(case_dir)//trim(file_path) - ! Creating the formatted data file and setting up its - ! structure - open (i + 120, file=trim(file_path), & - form='formatted', & - position='append', & - status='unknown') + file_path = trim(case_dir) // trim(file_path) + ! Creating the formatted data file and setting up its structure + open (i + 120, file=trim(file_path), form='formatted', position='append', status='unknown') if (n == 0) then - write (i + 120, '(A)') ' Non-Dimensional Time '// & - ' Total Mass '// & - ' x-loc '// & - ' Total Volume ' - elseif (p == 0) then - write (i + 120, '(A)') ' Non-Dimensional Time '// & - ' Total Mass '// & - ' x-loc '// & - ' y-loc '// & - ' Total Volume ' + write (i + 120, '(A)') ' Non-Dimensional Time ' // ' Total Mass ' // ' x-loc ' // ' Total Volume ' + else if (p == 0) then + write (i + 120, & + & '(A)') ' Non-Dimensional Time ' // ' Total Mass ' // ' x-loc ' // ' y-loc ' & + & // ' Total Volume ' else - write (i + 120, '(A)') ' Non-Dimensional Time '// & - ' Total Mass '// & - ' x-loc '// & - ' y-loc '// & - ' z-loc '// & - ' Total Volume ' + write (i + 120, & + & '(A)') ' Non-Dimensional Time ' // ' Total Mass ' // ' x-loc ' // ' y-loc ' // ' z-loc ' & + & // ' Total Volume ' end if end do + end subroutine s_open_com_files - !> This opens a formatted data file where the root processor - !! can write out flow probe information + !> This opens a formatted data file where the root processor can write out flow probe information impure subroutine s_open_probe_files - character(LEN=path_len + 3*name_len) :: file_path !< - !! Relative path to the probe data file in the case directory - - integer :: i !< Generic loop iterator - logical :: file_exist + character(LEN=path_len + 3*name_len) :: file_path !< Relative path to the probe data file in the case directory + integer :: i !< Generic loop iterator + logical :: file_exist do i = 1, num_probes ! Generating the relative path to the data file write (file_path, '(A,I0,A)') '/D/probe', i, '_prim.dat' - file_path = trim(case_dir)//trim(file_path) + file_path = trim(case_dir) // trim(file_path) - ! Creating the formatted data file and setting up its - ! structure + ! Creating the formatted data file and setting up its structure inquire (file=trim(file_path), exist=file_exist) if (file_exist) then - open (i + 30, FILE=trim(file_path), & - FORM='formatted', & - STATUS='old', & - POSITION='append') + open (i + 30, FILE=trim(file_path), form='formatted', STATUS='old', POSITION='append') else - open (i + 30, FILE=trim(file_path), & - FORM='formatted', & - STATUS='unknown') + open (i + 30, FILE=trim(file_path), form='formatted', STATUS='unknown') end if end do if (integral_wrt) then do i = 1, num_integrals write (file_path, '(A,I0,A)') '/D/integral', i, '_prim.dat' - file_path = trim(case_dir)//trim(file_path) + file_path = trim(case_dir) // trim(file_path) - open (i + 70, FILE=trim(file_path), & - FORM='formatted', & - POSITION='append', & - STATUS='unknown') + open (i + 70, FILE=trim(file_path), form='formatted', POSITION='append', STATUS='unknown') end do end if end subroutine s_open_probe_files impure subroutine s_open_ib_state_file + character(len=path_len + 2*name_len) :: file_loc - integer :: ios + integer :: ios write (file_loc, '(A)') 'ib_state.dat' - file_loc = trim(case_dir)//'/D/'//trim(file_loc) - open (newunit=ib_state_unit, file=trim(file_loc), & - form='unformatted', & - access='stream', & - status='replace', & - iostat=ios) - if (ios /= 0) call s_mpi_abort('Cannot open IB state output file: '//trim(file_loc)) + file_loc = trim(case_dir) // '/D/' // trim(file_loc) + open (newunit=ib_state_unit, file=trim(file_loc), form='unformatted', access='stream', status='replace', iostat=ios) + if (ios /= 0) call s_mpi_abort('Cannot open IB state output file: ' // trim(file_loc)) + end subroutine s_open_ib_state_file - !> The goal of the procedure is to output to the run-time - !! information file the stability criteria extrema in the - !! entire computational domain and at the given time-step. - !! Moreover, the subroutine is also in charge of tracking - !! these stability criteria extrema over all time-steps. - !! @param q_prim_vf Cell-average primitive variables - !! @param t_step Current time step + !> The goal of the procedure is to output to the run-time information file the stability criteria extrema in the entire + !! computational domain and at the given time-step. Moreover, the subroutine is also in charge of tracking these stability + !! criteria extrema over all time-steps. + !! @param q_prim_vf Cell-average primitive variables + !! @param t_step Current time step impure subroutine s_write_run_time_information(q_prim_vf, t_step) type(scalar_field), dimension(sys_size), intent(in) :: q_prim_vf - integer, intent(in) :: t_step + integer, intent(in) :: t_step + real(wp) :: rho !< Cell-avg. density - real(wp) :: rho !< Cell-avg. density #:if not MFC_CASE_OPTIMIZATION and USING_AMD - real(wp), dimension(3) :: alpha !< Cell-avg. volume fraction - real(wp), dimension(3) :: vel !< Cell-avg. velocity + real(wp), dimension(3) :: alpha !< Cell-avg. volume fraction + real(wp), dimension(3) :: vel !< Cell-avg. velocity #:else - real(wp), dimension(num_fluids) :: alpha !< Cell-avg. volume fraction - real(wp), dimension(num_vels) :: vel !< Cell-avg. velocity + real(wp), dimension(num_fluids) :: alpha !< Cell-avg. volume fraction + real(wp), dimension(num_vels) :: vel !< Cell-avg. velocity #:endif - real(wp) :: vel_sum !< Cell-avg. velocity sum - real(wp) :: pres !< Cell-avg. pressure - real(wp) :: gamma !< Cell-avg. sp. heat ratio - real(wp) :: pi_inf !< Cell-avg. liquid stiffness function - real(wp) :: qv !< Cell-avg. internal energy reference value - real(wp) :: c !< Cell-avg. sound speed - real(wp) :: H !< Cell-avg. enthalpy - real(wp), dimension(2) :: Re !< Cell-avg. Reynolds numbers - integer :: j, k, l - real(wp) :: icfl_max_loc, icfl_max_glb !< ICFL stability extrema on local and global grids - real(wp) :: vcfl_max_loc, vcfl_max_glb !< VCFL stability extrema on local and global grids - real(wp) :: ccfl_max_loc, ccfl_max_glb !< CCFL stability extrema on local and global grids - real(wp) :: Rc_min_loc, Rc_min_glb !< Rc stability extrema on local and global grids - real(wp) :: icfl, vcfl, Rc + real(wp) :: vel_sum !< Cell-avg. velocity sum + real(wp) :: pres !< Cell-avg. pressure + real(wp) :: gamma !< Cell-avg. sp. heat ratio + real(wp) :: pi_inf !< Cell-avg. liquid stiffness function + real(wp) :: qv !< Cell-avg. internal energy reference value + real(wp) :: c !< Cell-avg. sound speed + real(wp) :: H !< Cell-avg. enthalpy + real(wp), dimension(2) :: Re !< Cell-avg. Reynolds numbers + integer :: j, k, l + real(wp) :: icfl_max_loc, icfl_max_glb !< ICFL stability extrema on local and global grids + real(wp) :: vcfl_max_loc, vcfl_max_glb !< VCFL stability extrema on local and global grids + real(wp) :: ccfl_max_loc, ccfl_max_glb !< CCFL stability extrema on local and global grids + real(wp) :: Rc_min_loc, Rc_min_glb !< Rc stability extrema on local and global grids + real(wp) :: icfl, vcfl, Rc icfl_max_loc = 0._wp vcfl_max_loc = 0._wp Rc_min_loc = huge(1.0_wp) ! Computing Stability Criteria at Current Time-step - $:GPU_PARALLEL_LOOP(collapse=3, private='[j,k,l,vel, alpha, Re, rho, vel_sum, pres, gamma, pi_inf, c, H, qv, icfl, vcfl, Rc]', & - & reduction='[[icfl_max_loc,vcfl_max_loc],[Rc_min_loc]]', reductionOp='[max,min]') + $:GPU_PARALLEL_LOOP(collapse=3, private='[j, k, l, vel, alpha, Re, rho, vel_sum, pres, gamma, pi_inf, c, H, qv, icfl, & + & vcfl, Rc]', reduction='[[icfl_max_loc, vcfl_max_loc], [Rc_min_loc]]', reductionOp='[max, min]') do l = 0, p do k = 0, n do j = 0, m @@ -331,14 +247,8 @@ contains ! Determining global stability criteria extrema at current time-step if (num_procs > 1) then - call s_mpi_reduce_stability_criteria_extrema(icfl_max_loc, & - vcfl_max_loc, & - Rc_min_loc, & - n_el_bubs_loc, & - icfl_max_glb, & - vcfl_max_glb, & - Rc_min_glb, & - n_el_bubs_glb) + call s_mpi_reduce_stability_criteria_extrema(icfl_max_loc, vcfl_max_loc, Rc_min_loc, n_el_bubs_loc, icfl_max_glb, & + & vcfl_max_glb, Rc_min_glb, n_el_bubs_glb) else icfl_max_glb = icfl_max_loc if (viscous) vcfl_max_glb = vcfl_max_loc @@ -356,24 +266,21 @@ contains ! Outputting global stability criteria extrema at current time-step if (proc_rank == 0) then - write (3, '(13X,I9,13X,F10.6,13X,F10.6,13X,F10.6)', advance="no") & - t_step, dt, mytime, icfl_max_glb + write (3, '(13X,I9,13X,F10.6,13X,F10.6,13X,F10.6)', advance="no") t_step, dt, mytime, icfl_max_glb if (viscous) then - write (3, '(13X,F10.6,13X,ES16.6)', advance="no") & - vcfl_max_glb, & - Rc_min_glb + write (3, '(13X,F10.6,13X,ES16.6)', advance="no") vcfl_max_glb, Rc_min_glb end if if (bubbles_lagrange) then write (3, '(13X,I10)', advance="no") n_el_bubs_glb end if - write (3, *) ! new line + write (3, *) ! new line if (.not. f_approx_equal(icfl_max_glb, icfl_max_glb)) then call s_mpi_abort('ICFL is NaN. Exiting.') - elseif (icfl_max_glb > 1._wp) then + else if (icfl_max_glb > 1._wp) then print *, 'icfl', icfl_max_glb call s_mpi_abort('ICFL is greater than 1.0. Exiting.') end if @@ -381,7 +288,7 @@ contains if (viscous) then if (.not. f_approx_equal(vcfl_max_glb, vcfl_max_glb)) then call s_mpi_abort('VCFL is NaN. Exiting.') - elseif (vcfl_max_glb > 1._wp) then + else if (vcfl_max_glb > 1._wp) then print *, 'vcfl', vcfl_max_glb call s_mpi_abort('VCFL is greater than 1.0. Exiting.') end if @@ -398,14 +305,13 @@ contains end subroutine s_write_run_time_information - !> The goal of this subroutine is to output the grid and - !! conservative variables data files for given time-step. - !! @param q_cons_vf Cell-average conservative variables - !! @param q_T_sf Temperature scalar field - !! @param q_prim_vf Cell-average primitive variables - !! @param t_step Current time-step - !! @param bc_type Boundary condition type - !! @param beta Eulerian void fraction from lagrangian bubbles + !> The goal of this subroutine is to output the grid and conservative variables data files for given time-step. + !! @param q_cons_vf Cell-average conservative variables + !! @param q_T_sf Temperature scalar field + !! @param q_prim_vf Cell-average primitive variables + !! @param t_step Current time-step + !! @param bc_type Boundary condition type + !! @param beta Eulerian void fraction from lagrangian bubbles impure subroutine s_write_serial_data_files(q_cons_vf, q_T_sf, q_prim_vf, t_step, bc_type, beta) type(scalar_field), dimension(sys_size), intent(inout) :: q_cons_vf @@ -413,115 +319,84 @@ contains type(scalar_field), dimension(sys_size), intent(inout) :: q_prim_vf integer, intent(in) :: t_step type(scalar_field), intent(inout), optional :: beta - type(integer_field), dimension(1:num_dims, -1:1), intent(in) :: bc_type - - character(LEN=path_len + 2*name_len) :: t_step_dir !< - !! Relative path to the current time-step directory - - character(LEN=path_len + 3*name_len) :: file_path !< - !! Relative path to the grid and conservative variables data files - - logical :: file_exist !< - !! Logical used to check existence of current time-step directory - + type(integer_field), dimension(1:num_dims,-1:1), intent(in) :: bc_type + character(LEN=path_len + 2*name_len) :: t_step_dir !< Relative path to the current time-step directory + character(LEN=path_len + 3*name_len) :: file_path !< Relative path to the grid and conservative variables data files + logical :: file_exist !< Logical used to check existence of current time-step directory character(LEN=15) :: FMT - integer :: i, j, k, l, r - - real(wp) :: gamma, lit_gamma, pi_inf, qv !< Temporary EOS params + real(wp) :: gamma, lit_gamma, pi_inf, qv !< Temporary EOS params ! Creating or overwriting the time-step root directory - write (t_step_dir, '(A,I0,A,I0)') trim(case_dir)//'/p_all' + + write (t_step_dir, '(A,I0,A,I0)') trim(case_dir) // '/p_all' ! Creating or overwriting the current time-step directory - write (t_step_dir, '(a,i0,a,i0)') trim(case_dir)//'/p_all/p', & - proc_rank, '/', t_step + write (t_step_dir, '(a,i0,a,i0)') trim(case_dir) // '/p_all/p', proc_rank, '/', t_step - file_path = trim(t_step_dir)//'/.' + file_path = trim(t_step_dir) // '/.' call my_inquire(file_path, file_exist) if (file_exist) call s_delete_directory(trim(t_step_dir)) call s_create_directory(trim(t_step_dir)) ! Writing the grid data file in the x-direction - file_path = trim(t_step_dir)//'/x_cb.dat' + file_path = trim(t_step_dir) // '/x_cb.dat' - open (2, FILE=trim(file_path), & - FORM='unformatted', & - STATUS='new') + open (2, FILE=trim(file_path), form='unformatted', STATUS='new') write (2) x_cb(-1:m); close (2) ! Writing the grid data files in the y- and z-directions if (n > 0) then + file_path = trim(t_step_dir) // '/y_cb.dat' - file_path = trim(t_step_dir)//'/y_cb.dat' - - open (2, FILE=trim(file_path), & - FORM='unformatted', & - STATUS='new') + open (2, FILE=trim(file_path), form='unformatted', STATUS='new') write (2) y_cb(-1:n); close (2) if (p > 0) then + file_path = trim(t_step_dir) // '/z_cb.dat' - file_path = trim(t_step_dir)//'/z_cb.dat' - - open (2, FILE=trim(file_path), & - FORM='unformatted', & - STATUS='new') + open (2, FILE=trim(file_path), form='unformatted', STATUS='new') write (2) z_cb(-1:p); close (2) - end if - end if ! Writing the conservative variables data files do i = 1, sys_size - write (file_path, '(A,I0,A)') trim(t_step_dir)//'/q_cons_vf', & - i, '.dat' + write (file_path, '(A,I0,A)') trim(t_step_dir) // '/q_cons_vf', i, '.dat' - open (2, FILE=trim(file_path), & - FORM='unformatted', & - STATUS='new') + open (2, FILE=trim(file_path), form='unformatted', STATUS='new') - write (2) q_cons_vf(i)%sf(0:m, 0:n, 0:p); close (2) + write (2) q_cons_vf(i)%sf(0:m,0:n,0:p); close (2) end do - ! Lagrangian beta (void fraction) written as q_cons_vf(sys_size+1) to - ! match the parallel I/O path and allow post_process to read it. + ! Lagrangian beta (void fraction) written as q_cons_vf(sys_size+1) to match the parallel I/O path and allow post_process to + ! read it. if (bubbles_lagrange) then - write (file_path, '(A,I0,A)') trim(t_step_dir)//'/q_cons_vf', & - sys_size + 1, '.dat' + write (file_path, '(A,I0,A)') trim(t_step_dir) // '/q_cons_vf', sys_size + 1, '.dat' - open (2, FILE=trim(file_path), & - FORM='unformatted', & - STATUS='new') + open (2, FILE=trim(file_path), form='unformatted', STATUS='new') - write (2) beta%sf(0:m, 0:n, 0:p); close (2) + write (2) beta%sf(0:m,0:n,0:p); close (2) end if if (qbmm .and. .not. polytropic) then do i = 1, nb do r = 1, nnode - write (file_path, '(A,I0,A)') trim(t_step_dir)//'/pb', & - sys_size + (i - 1)*nnode + r, '.dat' + write (file_path, '(A,I0,A)') trim(t_step_dir) // '/pb', sys_size + (i - 1)*nnode + r, '.dat' - open (2, FILE=trim(file_path), & - FORM='unformatted', & - STATUS='new') + open (2, FILE=trim(file_path), form='unformatted', STATUS='new') - write (2) pb_ts(1)%sf(0:m, 0:n, 0:p, r, i); close (2) + write (2) pb_ts(1)%sf(0:m,0:n,0:p,r, i); close (2) end do end do do i = 1, nb do r = 1, nnode - write (file_path, '(A,I0,A)') trim(t_step_dir)//'/mv', & - sys_size + (i - 1)*nnode + r, '.dat' + write (file_path, '(A,I0,A)') trim(t_step_dir) // '/mv', sys_size + (i - 1)*nnode + r, '.dat' - open (2, FILE=trim(file_path), & - FORM='unformatted', & - STATUS='new') + open (2, FILE=trim(file_path), form='unformatted', STATUS='new') - write (2) mv_ts(1)%sf(0:m, 0:n, 0:p, r, i); close (2) + write (2) mv_ts(1)%sf(0:m,0:n,0:p,r, i); close (2) end do end do end if @@ -531,9 +406,7 @@ contains call s_write_serial_ib_data(t_step) ! write (file_path, '(A,I0,A)') trim(t_step_dir)//'/ib.dat' - ! open (2, FILE=trim(file_path), & - ! FORM='unformatted', & - ! STATUS='new') + ! open (2, FILE=trim(file_path), & FORM='unformatted', & STATUS='new') ! write (2) ib_markers%sf(0:m, 0:n, 0:p); close (2) end if @@ -550,8 +423,8 @@ contains end if ! writing an output directory - write (t_step_dir, '(A,I0,A,I0)') trim(case_dir)//'/D' - file_path = trim(t_step_dir)//'/.' + write (t_step_dir, '(A,I0,A,I0)') trim(case_dir) // '/D' + file_path = trim(t_step_dir) // '/.' inquire (FILE=trim(file_path), EXIST=file_exist) @@ -560,7 +433,7 @@ contains if ((prim_vars_wrt .or. (n == 0 .and. p == 0)) .and. (.not. igr)) then call s_convert_conservative_to_primitive_variables(q_cons_vf, q_T_sf, q_prim_vf, idwint) do i = 1, sys_size - $:GPU_UPDATE(host='[q_prim_vf(i)%sf(:,:,:)]') + $:GPU_UPDATE(host='[q_prim_vf(i)%sf(:, :, :)]') end do ! q_prim_vf(bubxb) stores the value of nb needed in riemann solvers, so replace with true primitive value (=1._wp) if (qbmm) then @@ -568,12 +441,11 @@ contains end if end if - !1D + ! 1D if (n == 0 .and. p == 0) then - if (model_eqns == 2 .and. (.not. igr)) then do i = 1, sys_size - write (file_path, '(A,I0,A,I2.2,A,I6.6,A)') trim(t_step_dir)//'/prim.', i, '.', proc_rank, '.', t_step, '.dat' + write (file_path, '(A,I0,A,I2.2,A,I6.6,A)') trim(t_step_dir) // '/prim.', i, '.', proc_rank, '.', t_step, '.dat' open (2, FILE=trim(file_path)) do j = 0, m @@ -589,7 +461,7 @@ contains end if do i = 1, sys_size - write (file_path, '(A,I0,A,I2.2,A,I6.6,A)') trim(t_step_dir)//'/cons.', i, '.', proc_rank, '.', t_step, '.dat' + write (file_path, '(A,I0,A,I2.2,A,I6.6,A)') trim(t_step_dir) // '/cons.', i, '.', proc_rank, '.', t_step, '.dat' open (2, FILE=trim(file_path)) do j = 0, m @@ -601,7 +473,8 @@ contains if (qbmm .and. .not. polytropic) then do i = 1, nb do r = 1, nnode - write (file_path, '(A,I0,A,I0,A,I2.2,A,I6.6,A)') trim(t_step_dir)//'/pres.', i, '.', r, '.', proc_rank, '.', t_step, '.dat' + write (file_path, '(A,I0,A,I0,A,I2.2,A,I6.6,A)') trim(t_step_dir) // '/pres.', i, '.', r, '.', proc_rank, & + & '.', t_step, '.dat' open (2, FILE=trim(file_path)) do j = 0, m @@ -612,7 +485,8 @@ contains end do do i = 1, nb do r = 1, nnode - write (file_path, '(A,I0,A,I0,A,I2.2,A,I6.6,A)') trim(t_step_dir)//'/mv.', i, '.', r, '.', proc_rank, '.', t_step, '.dat' + write (file_path, '(A,I0,A,I0,A,I2.2,A,I6.6,A)') trim(t_step_dir) // '/mv.', i, '.', r, '.', proc_rank, & + & '.', t_step, '.dat' open (2, FILE=trim(file_path)) do j = 0, m @@ -633,7 +507,7 @@ contains ! 2D if ((n > 0) .and. (p == 0)) then do i = 1, sys_size - write (file_path, '(A,I0,A,I2.2,A,I6.6,A)') trim(t_step_dir)//'/cons.', i, '.', proc_rank, '.', t_step, '.dat' + write (file_path, '(A,I0,A,I2.2,A,I6.6,A)') trim(t_step_dir) // '/cons.', i, '.', proc_rank, '.', t_step, '.dat' open (2, FILE=trim(file_path)) do j = 0, m do k = 0, n @@ -645,7 +519,7 @@ contains end do if (present(beta)) then - write (file_path, '(A,I0,A,I2.2,A,I6.6,A)') trim(t_step_dir)//'/beta.', i, '.', proc_rank, '.', t_step, '.dat' + write (file_path, '(A,I0,A,I2.2,A,I6.6,A)') trim(t_step_dir) // '/beta.', i, '.', proc_rank, '.', t_step, '.dat' open (2, FILE=trim(file_path)) do j = 0, m do k = 0, n @@ -659,7 +533,8 @@ contains if (qbmm .and. .not. polytropic) then do i = 1, nb do r = 1, nnode - write (file_path, '(A,I0,A,I0,A,I2.2,A,I6.6,A)') trim(t_step_dir)//'/pres.', i, '.', r, '.', proc_rank, '.', t_step, '.dat' + write (file_path, '(A,I0,A,I0,A,I2.2,A,I6.6,A)') trim(t_step_dir) // '/pres.', i, '.', r, '.', proc_rank, & + & '.', t_step, '.dat' open (2, FILE=trim(file_path)) do j = 0, m @@ -672,7 +547,8 @@ contains end do do i = 1, nb do r = 1, nnode - write (file_path, '(A,I0,A,I0,A,I2.2,A,I6.6,A)') trim(t_step_dir)//'/mv.', i, '.', r, '.', proc_rank, '.', t_step, '.dat' + write (file_path, '(A,I0,A,I0,A,I2.2,A,I6.6,A)') trim(t_step_dir) // '/mv.', i, '.', r, '.', proc_rank, & + & '.', t_step, '.dat' open (2, FILE=trim(file_path)) do j = 0, m @@ -687,16 +563,14 @@ contains if (prim_vars_wrt .and. (.not. igr)) then do i = 1, sys_size - write (file_path, '(A,I0,A,I2.2,A,I6.6,A)') trim(t_step_dir)//'/prim.', i, '.', proc_rank, '.', t_step, '.dat' + write (file_path, '(A,I0,A,I2.2,A,I6.6,A)') trim(t_step_dir) // '/prim.', i, '.', proc_rank, '.', t_step, '.dat' open (2, FILE=trim(file_path)) do j = 0, m do k = 0, n - if (((i >= cont_idx%beg) .and. (i <= cont_idx%end)) & - .or. & - ((i >= adv_idx%beg) .and. (i <= adv_idx%end)) & - ) then + if (((i >= cont_idx%beg) .and. (i <= cont_idx%end)) .or. ((i >= adv_idx%beg) .and. (i <= adv_idx%end)) & + & ) then write (2, FMT) x_cb(j), y_cb(k), q_cons_vf(i)%sf(j, k, 0) else write (2, FMT) x_cb(j), y_cb(k), q_prim_vf(i)%sf(j, k, 0) @@ -718,7 +592,7 @@ contains ! 3D if (p > 0) then do i = 1, sys_size - write (file_path, '(A,I0,A,I2.2,A,I6.6,A)') trim(t_step_dir)//'/cons.', i, '.', proc_rank, '.', t_step, '.dat' + write (file_path, '(A,I0,A,I2.2,A,I6.6,A)') trim(t_step_dir) // '/cons.', i, '.', proc_rank, '.', t_step, '.dat' open (2, FILE=trim(file_path)) do j = 0, m do k = 0, n @@ -733,7 +607,7 @@ contains end do if (present(beta)) then - write (file_path, '(A,I0,A,I2.2,A,I6.6,A)') trim(t_step_dir)//'/beta.', i, '.', proc_rank, '.', t_step, '.dat' + write (file_path, '(A,I0,A,I2.2,A,I6.6,A)') trim(t_step_dir) // '/beta.', i, '.', proc_rank, '.', t_step, '.dat' open (2, FILE=trim(file_path)) do j = 0, m do k = 0, n @@ -750,7 +624,8 @@ contains if (qbmm .and. .not. polytropic) then do i = 1, nb do r = 1, nnode - write (file_path, '(A,I0,A,I0,A,I2.2,A,I6.6,A)') trim(t_step_dir)//'/pres.', i, '.', r, '.', proc_rank, '.', t_step, '.dat' + write (file_path, '(A,I0,A,I0,A,I2.2,A,I6.6,A)') trim(t_step_dir) // '/pres.', i, '.', r, '.', proc_rank, & + & '.', t_step, '.dat' open (2, FILE=trim(file_path)) do j = 0, m @@ -765,7 +640,8 @@ contains end do do i = 1, nb do r = 1, nnode - write (file_path, '(A,I0,A,I0,A,I2.2,A,I6.6,A)') trim(t_step_dir)//'/mv.', i, '.', r, '.', proc_rank, '.', t_step, '.dat' + write (file_path, '(A,I0,A,I0,A,I2.2,A,I6.6,A)') trim(t_step_dir) // '/mv.', i, '.', r, '.', proc_rank, & + & '.', t_step, '.dat' open (2, FILE=trim(file_path)) do j = 0, m @@ -782,19 +658,15 @@ contains if (prim_vars_wrt .and. (.not. igr)) then do i = 1, sys_size - write (file_path, '(A,I0,A,I2.2,A,I6.6,A)') trim(t_step_dir)//'/prim.', i, '.', proc_rank, '.', t_step, '.dat' + write (file_path, '(A,I0,A,I2.2,A,I6.6,A)') trim(t_step_dir) // '/prim.', i, '.', proc_rank, '.', t_step, '.dat' open (2, FILE=trim(file_path)) do j = 0, m do k = 0, n do l = 0, p - if (((i >= cont_idx%beg) .and. (i <= cont_idx%end)) & - .or. & - ((i >= adv_idx%beg) .and. (i <= adv_idx%end)) & - .or. & - ((i >= chemxb) .and. (i <= chemxe)) & - ) then + if (((i >= cont_idx%beg) .and. (i <= cont_idx%end)) .or. ((i >= adv_idx%beg) & + & .and. (i <= adv_idx%end)) .or. ((i >= chemxb) .and. (i <= chemxe))) then write (2, FMT) x_cb(j), y_cb(k), z_cb(l), q_cons_vf(i)%sf(j, k, l) else write (2, FMT) x_cb(j), y_cb(k), z_cb(l), q_prim_vf(i)%sf(j, k, l) @@ -811,47 +683,39 @@ contains end subroutine s_write_serial_data_files - !> The goal of this subroutine is to output the grid and - !! conservative variables data files for given time-step. - !! @param q_cons_vf Cell-average conservative variables - !! @param t_step Current time-step - !! @param bc_type Boundary condition type - !! @param beta Eulerian void fraction from lagrangian bubbles + !> The goal of this subroutine is to output the grid and conservative variables data files for given time-step. + !! @param q_cons_vf Cell-average conservative variables + !! @param t_step Current time-step + !! @param bc_type Boundary condition type + !! @param beta Eulerian void fraction from lagrangian bubbles impure subroutine s_write_parallel_data_files(q_cons_vf, t_step, bc_type, beta) - type(scalar_field), dimension(sys_size), intent(inout) :: q_cons_vf - integer, intent(in) :: t_step - type(scalar_field), intent(inout), optional :: beta - type(integer_field), & - dimension(1:num_dims, -1:1), & - intent(in) :: bc_type + type(scalar_field), dimension(sys_size), intent(inout) :: q_cons_vf + integer, intent(in) :: t_step + type(scalar_field), intent(inout), optional :: beta + type(integer_field), dimension(1:num_dims,-1:1), intent(in) :: bc_type #ifdef MFC_MPI - - integer :: ifile, ierr, data_size - integer, dimension(MPI_STATUS_SIZE) :: status - integer(kind=MPI_OFFSET_kind) :: disp - integer(kind=MPI_OFFSET_kind) :: m_MOK, n_MOK, p_MOK - integer(kind=MPI_OFFSET_kind) :: WP_MOK, var_MOK, str_MOK - integer(kind=MPI_OFFSET_kind) :: NVARS_MOK - integer(kind=MPI_OFFSET_kind) :: MOK - + integer :: ifile, ierr, data_size + integer, dimension(MPI_STATUS_SIZE) :: status + integer(kind=MPI_OFFSET_kind) :: disp + integer(kind=MPI_OFFSET_kind) :: m_MOK, n_MOK, p_MOK + integer(kind=MPI_OFFSET_kind) :: WP_MOK, var_MOK, str_MOK + integer(kind=MPI_OFFSET_kind) :: NVARS_MOK + integer(kind=MPI_OFFSET_kind) :: MOK character(LEN=path_len + 2*name_len) :: file_loc - logical :: file_exist, dir_check - character(len=10) :: t_step_string - - integer :: i !< Generic loop iterator - - integer :: alt_sys !< Altered system size for the lagrangian subgrid bubble model + logical :: file_exist, dir_check + character(len=10) :: t_step_string + integer :: i !< Generic loop iterator + integer :: alt_sys !< Altered system size for the lagrangian subgrid bubble model ! Down sampling variables integer :: m_ds, n_ds, p_ds integer :: m_glb_ds, n_glb_ds, p_glb_ds - integer :: m_glb_save, n_glb_save, p_glb_save ! Global save size + integer :: m_glb_save, n_glb_save, p_glb_save ! Global save size if (down_sample) then - call s_downsample_data(q_cons_vf, q_cons_temp_ds, & - m_ds, n_ds, p_ds, m_glb_ds, n_glb_ds, p_glb_ds) + call s_downsample_data(q_cons_vf, q_cons_temp_ds, m_ds, n_ds, p_ds, m_glb_ds, n_glb_ds, p_glb_ds) end if if (present(beta)) then @@ -861,7 +725,6 @@ contains end if if (file_per_process) then - call s_int_to_str(t_step, t_step_string) ! Initialize MPI data I/O @@ -876,7 +739,7 @@ contains end if if (proc_rank == 0) then - file_loc = trim(case_dir)//'/restart_data/lustre_'//trim(t_step_string) + file_loc = trim(case_dir) // '/restart_data/lustre_' // trim(t_step_string) call my_inquire(file_loc, dir_check) if (dir_check .neqv. .true.) then call s_create_directory(trim(file_loc)) @@ -891,13 +754,12 @@ contains ! Open the file to write all flow variables write (file_loc, '(I0,A,i7.7,A)') t_step, '_', proc_rank, '.dat' - file_loc = trim(case_dir)//'/restart_data/lustre_'//trim(t_step_string)//trim(mpiiofs)//trim(file_loc) + file_loc = trim(case_dir) // '/restart_data/lustre_' // trim(t_step_string) // trim(mpiiofs) // trim(file_loc) inquire (FILE=trim(file_loc), EXIST=file_exist) if (file_exist .and. proc_rank == 0) then call MPI_FILE_DELETE(file_loc, mpi_info_int, ierr) end if - call MPI_FILE_OPEN(MPI_COMM_SELF, file_loc, ior(MPI_MODE_WRONLY, MPI_MODE_CREATE), & - mpi_info_int, ifile, ierr) + call MPI_FILE_OPEN(MPI_COMM_SELF, file_loc, ior(MPI_MODE_WRONLY, MPI_MODE_CREATE), mpi_info_int, ifile, ierr) if (down_sample) then ! Size of local arrays @@ -927,32 +789,28 @@ contains do i = 1, sys_size var_MOK = int(i, MPI_OFFSET_KIND) - call MPI_FILE_WRITE_ALL(ifile, MPI_IO_DATA%var(i)%sf, data_size*mpi_io_type, & - mpi_io_p, status, ierr) + call MPI_FILE_WRITE_ALL(ifile, MPI_IO_DATA%var(i)%sf, data_size*mpi_io_type, mpi_io_p, status, ierr) end do - !Write pb and mv for non-polytropic qbmm + ! Write pb and mv for non-polytropic qbmm if (qbmm .and. .not. polytropic) then do i = sys_size + 1, sys_size + 2*nb*nnode var_MOK = int(i, MPI_OFFSET_KIND) - call MPI_FILE_WRITE_ALL(ifile, MPI_IO_DATA%var(i)%sf, data_size*mpi_io_type, & - mpi_io_p, status, ierr) + call MPI_FILE_WRITE_ALL(ifile, MPI_IO_DATA%var(i)%sf, data_size*mpi_io_type, mpi_io_p, status, ierr) end do end if else if (down_sample) then - do i = 1, sys_size !TODO: check if correct (sys_size + do i = 1, sys_size ! TODO: check if correct (sys_size var_MOK = int(i, MPI_OFFSET_KIND) - call MPI_FILE_WRITE_ALL(ifile, q_cons_temp_ds(i)%sf, data_size*mpi_io_type, & - mpi_io_p, status, ierr) + call MPI_FILE_WRITE_ALL(ifile, q_cons_temp_ds(i)%sf, data_size*mpi_io_type, mpi_io_p, status, ierr) end do else - do i = 1, sys_size !TODO: check if correct (sys_size + do i = 1, sys_size ! TODO: check if correct (sys_size var_MOK = int(i, MPI_OFFSET_KIND) - call MPI_FILE_WRITE_ALL(ifile, MPI_IO_DATA%var(i)%sf, data_size*mpi_io_type, & - mpi_io_p, status, ierr) + call MPI_FILE_WRITE_ALL(ifile, MPI_IO_DATA%var(i)%sf, data_size*mpi_io_type, mpi_io_p, status, ierr) end do end if end if @@ -963,20 +821,19 @@ contains if (ib) then call s_initialize_mpi_data(q_cons_vf, ib_markers) - elseif (present(beta)) then + else if (present(beta)) then call s_initialize_mpi_data(q_cons_vf, beta=beta) else call s_initialize_mpi_data(q_cons_vf) end if write (file_loc, '(I0,A)') t_step, '.dat' - file_loc = trim(case_dir)//'/restart_data'//trim(mpiiofs)//trim(file_loc) + file_loc = trim(case_dir) // '/restart_data' // trim(mpiiofs) // trim(file_loc) inquire (FILE=trim(file_loc), EXIST=file_exist) if (file_exist .and. proc_rank == 0) then call MPI_FILE_DELETE(file_loc, mpi_info_int, ierr) end if - call MPI_FILE_OPEN(MPI_COMM_WORLD, file_loc, ior(MPI_MODE_WRONLY, MPI_MODE_CREATE), & - mpi_info_int, ifile, ierr) + call MPI_FILE_OPEN(MPI_COMM_WORLD, file_loc, ior(MPI_MODE_WRONLY, MPI_MODE_CREATE), mpi_info_int, ifile, ierr) ! Size of local arrays data_size = (m + 1)*(n + 1)*(p + 1) @@ -998,12 +855,10 @@ contains ! Initial displacement to skip at beginning of file disp = m_MOK*max(MOK, n_MOK)*max(MOK, p_MOK)*WP_MOK*(var_MOK - 1) - call MPI_FILE_SET_VIEW(ifile, disp, mpi_p, MPI_IO_DATA%view(i), & - 'native', mpi_info_int, ierr) - call MPI_FILE_WRITE_ALL(ifile, MPI_IO_DATA%var(i)%sf, data_size*mpi_io_type, & - mpi_io_p, status, ierr) + call MPI_FILE_SET_VIEW(ifile, disp, mpi_p, MPI_IO_DATA%view(i), 'native', mpi_info_int, ierr) + call MPI_FILE_WRITE_ALL(ifile, MPI_IO_DATA%var(i)%sf, data_size*mpi_io_type, mpi_io_p, status, ierr) end do - !Write pb and mv for non-polytropic qbmm + ! Write pb and mv for non-polytropic qbmm if (qbmm .and. .not. polytropic) then do i = sys_size + 1, sys_size + 2*nb*nnode var_MOK = int(i, MPI_OFFSET_KIND) @@ -1011,23 +866,19 @@ contains ! Initial displacement to skip at beginning of file disp = m_MOK*max(MOK, n_MOK)*max(MOK, p_MOK)*WP_MOK*(var_MOK - 1) - call MPI_FILE_SET_VIEW(ifile, disp, mpi_p, MPI_IO_DATA%view(i), & - 'native', mpi_info_int, ierr) - call MPI_FILE_WRITE_ALL(ifile, MPI_IO_DATA%var(i)%sf, data_size*mpi_io_type, & - mpi_io_p, status, ierr) + call MPI_FILE_SET_VIEW(ifile, disp, mpi_p, MPI_IO_DATA%view(i), 'native', mpi_info_int, ierr) + call MPI_FILE_WRITE_ALL(ifile, MPI_IO_DATA%var(i)%sf, data_size*mpi_io_type, mpi_io_p, status, ierr) end do end if else - do i = 1, sys_size !TODO: check if correct (sys_size + do i = 1, sys_size ! TODO: check if correct (sys_size var_MOK = int(i, MPI_OFFSET_KIND) ! Initial displacement to skip at beginning of file disp = m_MOK*max(MOK, n_MOK)*max(MOK, p_MOK)*WP_MOK*(var_MOK - 1) - call MPI_FILE_SET_VIEW(ifile, disp, mpi_p, MPI_IO_DATA%view(i), & - 'native', mpi_info_int, ierr) - call MPI_FILE_WRITE_ALL(ifile, MPI_IO_DATA%var(i)%sf, data_size*mpi_io_type, & - mpi_io_p, status, ierr) + call MPI_FILE_SET_VIEW(ifile, disp, mpi_p, MPI_IO_DATA%view(i), 'native', mpi_info_int, ierr) + call MPI_FILE_WRITE_ALL(ifile, MPI_IO_DATA%var(i)%sf, data_size*mpi_io_type, mpi_io_p, status, ierr) end do end if @@ -1038,32 +889,25 @@ contains ! Initial displacement to skip at beginning of file disp = m_MOK*max(MOK, n_MOK)*max(MOK, p_MOK)*WP_MOK*(var_MOK - 1) - call MPI_FILE_SET_VIEW(ifile, disp, mpi_p, MPI_IO_DATA%view(sys_size + 1), & - 'native', mpi_info_int, ierr) - call MPI_FILE_WRITE_ALL(ifile, MPI_IO_DATA%var(sys_size + 1)%sf, data_size*mpi_io_type, & - mpi_io_p, status, ierr) + call MPI_FILE_SET_VIEW(ifile, disp, mpi_p, MPI_IO_DATA%view(sys_size + 1), 'native', mpi_info_int, ierr) + call MPI_FILE_WRITE_ALL(ifile, MPI_IO_DATA%var(sys_size + 1)%sf, data_size*mpi_io_type, mpi_io_p, status, ierr) end if call MPI_FILE_CLOSE(ifile, ierr) - !Write ib data + ! Write ib data if (ib) then call s_write_parallel_ib_data(t_step) - ! write (file_loc, '(A)') 'ib.dat' - ! file_loc = trim(case_dir)//'/restart_data'//trim(mpiiofs)//trim(file_loc) - ! call MPI_FILE_OPEN(MPI_COMM_WORLD, file_loc, ior(MPI_MODE_WRONLY, MPI_MODE_CREATE), & - ! mpi_info_int, ifile, ierr) - - ! var_MOK = int(sys_size + 1, MPI_OFFSET_KIND) - ! disp = m_MOK*max(MOK, n_MOK)*max(MOK, p_MOK)*WP_MOK*(var_MOK - 1 + int(t_step/t_step_save)) - - ! call MPI_FILE_SET_VIEW(ifile, disp, MPI_INTEGER, MPI_IO_IB_DATA%view, & - ! 'native', mpi_info_int, ierr) - ! call MPI_FILE_WRITE_ALL(ifile, MPI_IO_IB_DATA%var%sf, data_size, & - ! MPI_INTEGER, status, ierr) - ! call MPI_FILE_CLOSE(ifile, ierr) - end if + ! write (file_loc, '(A)') 'ib.dat' file_loc = trim(case_dir)//'/restart_data'//trim(mpiiofs)//trim(file_loc) call + ! MPI_FILE_OPEN(MPI_COMM_WORLD, file_loc, ior(MPI_MODE_WRONLY, MPI_MODE_CREATE), & mpi_info_int, ifile, ierr) + + ! var_MOK = int(sys_size + 1, MPI_OFFSET_KIND) disp = m_MOK*max(MOK, n_MOK)*max(MOK, p_MOK)*WP_MOK*(var_MOK - 1 + + ! int(t_step/t_step_save)) + ! call MPI_FILE_SET_VIEW(ifile, disp, MPI_INTEGER, MPI_IO_IB_DATA%view, & 'native', mpi_info_int, ierr) call + ! MPI_FILE_WRITE_ALL(ifile, MPI_IO_IB_DATA%var%sf, data_size, & MPI_INTEGER, status, ierr) call + ! MPI_FILE_CLOSE(ifile, ierr) + end if end if #endif @@ -1072,24 +916,22 @@ contains !> @brief Writes immersed boundary marker data to a serial (per-processor) unformatted file. subroutine s_write_serial_ib_data(time_step) - integer, intent(in) :: time_step + integer, intent(in) :: time_step character(LEN=path_len + 2*name_len) :: file_path character(LEN=path_len + 2*name_len) :: t_step_dir ! Creating or overwriting the time-step root directory - write (t_step_dir, '(A,I0,A,I0)') trim(case_dir)//'/p_all' - write (t_step_dir, '(a,i0,a,i0)') trim(case_dir)//'/p_all/p', & - proc_rank, '/', time_step - write (file_path, '(A,I0,A)') trim(t_step_dir)//'/ib_data.dat' - open (2, FILE=trim(file_path), & - FORM='unformatted', & - STATUS='new') + write (t_step_dir, '(A,I0,A,I0)') trim(case_dir) // '/p_all' + write (t_step_dir, '(a,i0,a,i0)') trim(case_dir) // '/p_all/p', proc_rank, '/', time_step + write (file_path, '(A,I0,A)') trim(t_step_dir) // '/ib_data.dat' + + open (2, FILE=trim(file_path), form='unformatted', STATUS='new') $:GPU_UPDATE(host='[ib_markers%sf]') - write (2) ib_markers%sf(0:m, 0:n, 0:p); close (2) + write (2) ib_markers%sf(0:m,0:n,0:p); close (2) - end subroutine + end subroutine s_write_serial_ib_data !> @brief Writes immersed boundary marker data in parallel using MPI I/O. subroutine s_write_parallel_ib_data(time_step) @@ -1097,13 +939,12 @@ contains integer, intent(in) :: time_step #ifdef MFC_MPI - character(LEN=path_len + 2*name_len) :: file_loc - integer(kind=MPI_OFFSET_kind) :: disp - integer(kind=MPI_OFFSET_kind) :: m_MOK, n_MOK, p_MOK - integer(kind=MPI_OFFSET_kind) :: WP_MOK, var_MOK, MOK - integer :: ifile, ierr, data_size - integer, dimension(MPI_STATUS_SIZE) :: status + integer(kind=MPI_OFFSET_kind) :: disp + integer(kind=MPI_OFFSET_kind) :: m_MOK, n_MOK, p_MOK + integer(kind=MPI_OFFSET_kind) :: WP_MOK, var_MOK, MOK + integer :: ifile, ierr, data_size + integer, dimension(MPI_STATUS_SIZE) :: status $:GPU_UPDATE(host='[ib_markers%sf]') @@ -1116,20 +957,16 @@ contains MOK = int(1._wp, MPI_OFFSET_KIND) write (file_loc, '(A)') 'ib.dat' - file_loc = trim(case_dir)//'/restart_data'//trim(mpiiofs)//trim(file_loc) - call MPI_FILE_OPEN(MPI_COMM_WORLD, file_loc, ior(MPI_MODE_WRONLY, MPI_MODE_CREATE), & - mpi_info_int, ifile, ierr) + file_loc = trim(case_dir) // '/restart_data' // trim(mpiiofs) // trim(file_loc) + call MPI_FILE_OPEN(MPI_COMM_WORLD, file_loc, ior(MPI_MODE_WRONLY, MPI_MODE_CREATE), mpi_info_int, ifile, ierr) var_MOK = int(sys_size + 1, MPI_OFFSET_KIND) disp = m_MOK*max(MOK, n_MOK)*max(MOK, p_MOK)*WP_MOK*(var_MOK - 1 + int(time_step/t_step_save)) if (time_step == 0) disp = 0 - call MPI_FILE_SET_VIEW(ifile, disp, MPI_INTEGER, MPI_IO_IB_DATA%view, & - 'native', mpi_info_int, ierr) - call MPI_FILE_WRITE_ALL(ifile, MPI_IO_IB_DATA%var%sf, data_size, & - MPI_INTEGER, status, ierr) + call MPI_FILE_SET_VIEW(ifile, disp, MPI_INTEGER, MPI_IO_IB_DATA%view, 'native', mpi_info_int, ierr) + call MPI_FILE_WRITE_ALL(ifile, MPI_IO_IB_DATA%var%sf, data_size, MPI_INTEGER, status, ierr) call MPI_FILE_CLOSE(ifile, ierr) - #endif end subroutine s_write_parallel_ib_data @@ -1153,31 +990,24 @@ contains integer :: i do i = 1, num_ibs - write (ib_state_unit) mytime, i, & - patch_ib(i)%force, & - patch_ib(i)%torque, & - patch_ib(i)%vel, & - patch_ib(i)%angular_vel, & - patch_ib(i)%angles, & - patch_ib(i)%x_centroid, & - patch_ib(i)%y_centroid, & - patch_ib(i)%z_centroid + write (ib_state_unit) mytime, i, patch_ib(i)%force, patch_ib(i)%torque, patch_ib(i)%vel, patch_ib(i)%angular_vel, & + & patch_ib(i)%angles, patch_ib(i)%x_centroid, patch_ib(i)%y_centroid, patch_ib(i)%z_centroid end do end subroutine s_write_ib_state_file - !> This writes a formatted data file where the root processor - !! can write out the CoM information - !! @param t_step Current time-step - !! @param c_mass_in Center of mass information + !> This writes a formatted data file where the root processor can write out the CoM information + !! @param t_step Current time-step + !! @param c_mass_in Center of mass information impure subroutine s_write_com_files(t_step, c_mass_in) - integer, intent(in) :: t_step + integer, intent(in) :: t_step real(wp), dimension(num_fluids, 5), intent(in) :: c_mass_in - integer :: i !< Generic loop iterator - real(wp) :: nondim_time !< Non-dimensional time + integer :: i !< Generic loop iterator + real(wp) :: nondim_time !< Non-dimensional time ! Non-dimensional time calculation + if (t_step_old /= dflt_int) then nondim_time = real(t_step + t_step_old, wp)*dt else @@ -1185,93 +1015,71 @@ contains end if if (proc_rank == 0) then - if (n == 0) then ! 1D simulation - do i = 1, num_fluids ! Loop through fluids - write (i + 120, '(6X,4F24.12)') & - nondim_time, & - c_mass_in(i, 1), & - c_mass_in(i, 2), & - c_mass_in(i, 5) + if (n == 0) then ! 1D simulation + do i = 1, num_fluids ! Loop through fluids + write (i + 120, '(6X,4F24.12)') nondim_time, c_mass_in(i, 1), c_mass_in(i, 2), c_mass_in(i, 5) end do - elseif (p == 0) then ! 2D simulation - do i = 1, num_fluids ! Loop through fluids - write (i + 120, '(6X,5F24.12)') & - nondim_time, & - c_mass_in(i, 1), & - c_mass_in(i, 2), & - c_mass_in(i, 3), & - c_mass_in(i, 5) + else if (p == 0) then ! 2D simulation + do i = 1, num_fluids ! Loop through fluids + write (i + 120, '(6X,5F24.12)') nondim_time, c_mass_in(i, 1), c_mass_in(i, 2), c_mass_in(i, 3), c_mass_in(i, 5) end do - else ! 3D simulation - do i = 1, num_fluids ! Loop through fluids - write (i + 120, '(6X,6F24.12)') & - nondim_time, & - c_mass_in(i, 1), & - c_mass_in(i, 2), & - c_mass_in(i, 3), & - c_mass_in(i, 4), & - c_mass_in(i, 5) + else ! 3D simulation + do i = 1, num_fluids ! Loop through fluids + write (i + 120, '(6X,6F24.12)') nondim_time, c_mass_in(i, 1), c_mass_in(i, 2), c_mass_in(i, 3), c_mass_in(i, & + & 4), c_mass_in(i, 5) end do end if end if end subroutine s_write_com_files - !> This writes a formatted data file for the flow probe information - !! @param t_step Current time-step - !! @param q_cons_vf Conservative variables - !! @param accel_mag Acceleration magnitude information + !> This writes a formatted data file for the flow probe information + !! @param t_step Current time-step + !! @param q_cons_vf Conservative variables + !! @param accel_mag Acceleration magnitude information impure subroutine s_write_probe_files(t_step, q_cons_vf, accel_mag) - integer, intent(in) :: t_step + integer, intent(in) :: t_step type(scalar_field), dimension(sys_size), intent(in) :: q_cons_vf - real(wp), dimension(0:m, 0:n, 0:p), intent(in) :: accel_mag - - real(wp), dimension(-1:m) :: distx - real(wp), dimension(-1:n) :: disty - real(wp), dimension(-1:p) :: distz - - ! The cell-averaged partial densities, density, velocity, pressure, - ! volume fractions, specific heat ratio function, liquid stiffness - ! function, and sound speed. - real(wp) :: lit_gamma, nbub - real(wp) :: rho - real(wp), dimension(num_vels) :: vel - real(wp) :: pres - real(wp) :: ptilde - real(wp) :: ptot - real(wp) :: alf - real(wp) :: alfgr + real(wp), dimension(0:m,0:n,0:p), intent(in) :: accel_mag + real(wp), dimension(-1:m) :: distx + real(wp), dimension(-1:n) :: disty + real(wp), dimension(-1:p) :: distz + + ! The cell-averaged partial densities, density, velocity, pressure, volume fractions, specific heat ratio function, liquid + ! stiffness function, and sound speed. + real(wp) :: lit_gamma, nbub + real(wp) :: rho + real(wp), dimension(num_vels) :: vel + real(wp) :: pres + real(wp) :: ptilde + real(wp) :: ptot + real(wp) :: alf + real(wp) :: alfgr real(wp), dimension(num_fluids) :: alpha - real(wp) :: gamma - real(wp) :: pi_inf - real(wp) :: qv - real(wp) :: c - real(wp) :: M00, M10, M01, M20, M11, M02 - real(wp) :: varR, varV - real(wp), dimension(Nb) :: nR, R, nRdot, Rdot - real(wp) :: nR3 - real(wp) :: accel - real(wp) :: int_pres - real(wp) :: max_pres - real(wp), dimension(2) :: Re - real(wp), dimension(6) :: tau_e - real(wp) :: G_local - real(wp) :: dyn_p, T - real(wp) :: damage_state - - integer :: i, j, k, l, s, d !< Generic loop iterator - - real(wp) :: nondim_time !< Non-dimensional time - - real(wp) :: tmp !< - !! Temporary variable to store quantity for mpi_allreduce - - integer :: npts !< Number of included integral points - real(wp) :: rad, thickness !< For integral quantities - logical :: trigger !< For integral quantities - - real(wp) :: rhoYks(1:num_species) + real(wp) :: gamma + real(wp) :: pi_inf + real(wp) :: qv + real(wp) :: c + real(wp) :: M00, M10, M01, M20, M11, M02 + real(wp) :: varR, varV + real(wp), dimension(Nb) :: nR, R, nRdot, Rdot + real(wp) :: nR3 + real(wp) :: accel + real(wp) :: int_pres + real(wp) :: max_pres + real(wp), dimension(2) :: Re + real(wp), dimension(6) :: tau_e + real(wp) :: G_local + real(wp) :: dyn_p, T + real(wp) :: damage_state + integer :: i, j, k, l, s, d !< Generic loop iterator + real(wp) :: nondim_time !< Non-dimensional time + real(wp) :: tmp !< Temporary variable to store quantity for mpi_allreduce + integer :: npts !< Number of included integral points + real(wp) :: rad, thickness !< For integral quantities + logical :: trigger !< For integral quantities + real(wp) :: rhoYks(1:num_species) T = dflt_T_guess @@ -1314,16 +1122,15 @@ contains end do damage_state = 0._wp - ! Find probe location in terms of indices on a - ! specific processor - if (n == 0) then ! 1D simulation + ! Find probe location in terms of indices on a specific processor + if (n == 0) then ! 1D simulation if ((probe(i)%x >= x_cb(-1)) .and. (probe(i)%x <= x_cb(m))) then do s = -1, m distx(s) = x_cb(s) - probe(i)%x if (distx(s) < 0._wp) distx(s) = 1000._wp end do j = minloc(distx, 1) - if (j == 1) j = 2 ! Pick first point if probe is at edge + if (j == 1) j = 2 ! Pick first point if probe is at edge k = 0 l = 0 @@ -1335,12 +1142,10 @@ contains ! Computing/Sharing necessary state variables if (elasticity) then - call s_convert_to_mixture_variables(q_cons_vf, j - 2, k, l, & - rho, gamma, pi_inf, qv, & - Re, G_local, fluid_pp(:)%G) + call s_convert_to_mixture_variables(q_cons_vf, j - 2, k, l, rho, gamma, pi_inf, qv, Re, G_local, & + & fluid_pp(:)%G) else - call s_convert_to_mixture_variables(q_cons_vf, j - 2, k, l, & - rho, gamma, pi_inf, qv) + call s_convert_to_mixture_variables(q_cons_vf, j - 2, k, l, rho, gamma, pi_inf, qv) end if do s = 1, num_vels vel(s) = q_cons_vf(cont_idx%end + s)%sf(j - 2, k, l)/rho @@ -1354,17 +1159,12 @@ contains G_local = G_local*max((1._wp - damage_state), 0._wp) end if - call s_compute_pressure( & - q_cons_vf(1)%sf(j - 2, k, l), & - q_cons_vf(alf_idx)%sf(j - 2, k, l), & - dyn_p, pi_inf, gamma, rho, qv, rhoYks(:), pres, T, & - q_cons_vf(stress_idx%beg)%sf(j - 2, k, l), & - q_cons_vf(mom_idx%beg)%sf(j - 2, k, l), G_local) + call s_compute_pressure(q_cons_vf(1)%sf(j - 2, k, l), q_cons_vf(alf_idx)%sf(j - 2, k, l), dyn_p, pi_inf, & + & gamma, rho, qv, rhoYks(:), pres, T, q_cons_vf(stress_idx%beg)%sf(j - 2, k, l), & + & q_cons_vf(mom_idx%beg)%sf(j - 2, k, l), G_local) else - call s_compute_pressure( & - q_cons_vf(E_idx)%sf(j - 2, k, l), & - q_cons_vf(alf_idx)%sf(j - 2, k, l), & - dyn_p, pi_inf, gamma, rho, qv, rhoYks, pres, T) + call s_compute_pressure(q_cons_vf(E_idx)%sf(j - 2, k, l), q_cons_vf(alf_idx)%sf(j - 2, k, l), dyn_p, & + & pi_inf, gamma, rho, qv, rhoYks, pres, T) end if if (model_eqns == 4) then @@ -1421,12 +1221,12 @@ contains end if ! Compute mixture sound Speed - call s_compute_speed_of_sound(pres, rho, gamma, pi_inf, & - ((gamma + 1._wp)*pres + pi_inf)/rho, alpha, 0._wp, 0._wp, c, qv) + call s_compute_speed_of_sound(pres, rho, gamma, pi_inf, ((gamma + 1._wp)*pres + pi_inf)/rho, alpha, 0._wp, & + & 0._wp, c, qv) accel = accel_mag(j - 2, k, l) end if - elseif (p == 0) then ! 2D simulation + else if (p == 0) then ! 2D simulation if (chemistry) then do d = 1, num_species rhoYks(d) = q_cons_vf(chemxb + d - 1)%sf(j - 2, k - 2, l) @@ -1445,14 +1245,13 @@ contains end do j = minloc(distx, 1) k = minloc(disty, 1) - if (j == 1) j = 2 ! Pick first point if probe is at edge - if (k == 1) k = 2 ! Pick first point if probe is at edge + if (j == 1) j = 2 ! Pick first point if probe is at edge + if (k == 1) k = 2 ! Pick first point if probe is at edge l = 0 ! Computing/Sharing necessary state variables - call s_convert_to_mixture_variables(q_cons_vf, j - 2, k - 2, l, & - rho, gamma, pi_inf, qv, & - Re, G_local, fluid_pp(:)%G) + call s_convert_to_mixture_variables(q_cons_vf, j - 2, k - 2, l, rho, gamma, pi_inf, qv, Re, G_local, & + & fluid_pp(:)%G) do s = 1, num_vels vel(s) = q_cons_vf(cont_idx%end + s)%sf(j - 2, k - 2, l)/rho end do @@ -1465,20 +1264,13 @@ contains G_local = G_local*max((1._wp - damage_state), 0._wp) end if - call s_compute_pressure( & - q_cons_vf(1)%sf(j - 2, k - 2, l), & - q_cons_vf(alf_idx)%sf(j - 2, k - 2, l), & - dyn_p, pi_inf, gamma, rho, qv, & - rhoYks, & - pres, & - T, & - q_cons_vf(stress_idx%beg)%sf(j - 2, k - 2, l), & - q_cons_vf(mom_idx%beg)%sf(j - 2, k - 2, l), G_local) + call s_compute_pressure(q_cons_vf(1)%sf(j - 2, k - 2, l), q_cons_vf(alf_idx)%sf(j - 2, k - 2, l), & + & dyn_p, pi_inf, gamma, rho, qv, rhoYks, pres, T, & + & q_cons_vf(stress_idx%beg)%sf(j - 2, k - 2, l), & + & q_cons_vf(mom_idx%beg)%sf(j - 2, k - 2, l), G_local) else - call s_compute_pressure(q_cons_vf(E_idx)%sf(j - 2, k - 2, l), & - q_cons_vf(alf_idx)%sf(j - 2, k - 2, l), & - dyn_p, pi_inf, gamma, rho, qv, & - rhoYks, pres, T) + call s_compute_pressure(q_cons_vf(E_idx)%sf(j - 2, k - 2, l), q_cons_vf(alf_idx)%sf(j - 2, k - 2, l), & + & dyn_p, pi_inf, gamma, rho, qv, rhoYks, pres, T) end if if (model_eqns == 4) then @@ -1511,12 +1303,11 @@ contains Rdot(:) = nRdot(:)/nbub end if ! Compute mixture sound speed - call s_compute_speed_of_sound(pres, rho, gamma, pi_inf, & - ((gamma + 1._wp)*pres + pi_inf)/rho, alpha, 0._wp, 0._wp, c, qv) - + call s_compute_speed_of_sound(pres, rho, gamma, pi_inf, ((gamma + 1._wp)*pres + pi_inf)/rho, alpha, & + & 0._wp, 0._wp, c, qv) end if end if - else ! 3D + else ! 3D if ((probe(i)%x >= x_cb(-1)) .and. (probe(i)%x <= x_cb(m))) then if ((probe(i)%y >= y_cb(-1)) .and. (probe(i)%y <= y_cb(n))) then if ((probe(i)%z >= z_cb(-1)) .and. (probe(i)%z <= z_cb(p))) then @@ -1535,14 +1326,13 @@ contains j = minloc(distx, 1) k = minloc(disty, 1) l = minloc(distz, 1) - if (j == 1) j = 2 ! Pick first point if probe is at edge - if (k == 1) k = 2 ! Pick first point if probe is at edge - if (l == 1) l = 2 ! Pick first point if probe is at edge + if (j == 1) j = 2 ! Pick first point if probe is at edge + if (k == 1) k = 2 ! Pick first point if probe is at edge + if (l == 1) l = 2 ! Pick first point if probe is at edge ! Computing/Sharing necessary state variables - call s_convert_to_mixture_variables(q_cons_vf, j - 2, k - 2, l - 2, & - rho, gamma, pi_inf, qv, & - Re, G_local, fluid_pp(:)%G) + call s_convert_to_mixture_variables(q_cons_vf, j - 2, k - 2, l - 2, rho, gamma, pi_inf, qv, Re, & + & G_local, fluid_pp(:)%G) do s = 1, num_vels vel(s) = q_cons_vf(cont_idx%end + s)%sf(j - 2, k - 2, l - 2)/rho end do @@ -1561,23 +1351,18 @@ contains G_local = G_local*max((1._wp - damage_state), 0._wp) end if - call s_compute_pressure( & - q_cons_vf(1)%sf(j - 2, k - 2, l - 2), & - q_cons_vf(alf_idx)%sf(j - 2, k - 2, l - 2), & - dyn_p, pi_inf, gamma, rho, qv, & - rhoYks, pres, T, & - q_cons_vf(stress_idx%beg)%sf(j - 2, k - 2, l - 2), & - q_cons_vf(mom_idx%beg)%sf(j - 2, k - 2, l - 2), G_local) + call s_compute_pressure(q_cons_vf(1)%sf(j - 2, k - 2, l - 2), q_cons_vf(alf_idx)%sf(j - 2, k - 2, & + & l - 2), dyn_p, pi_inf, gamma, rho, qv, rhoYks, pres, T, & + & q_cons_vf(stress_idx%beg)%sf(j - 2, k - 2, l - 2), & + & q_cons_vf(mom_idx%beg)%sf(j - 2, k - 2, l - 2), G_local) else - call s_compute_pressure(q_cons_vf(E_idx)%sf(j - 2, k - 2, l - 2), & - q_cons_vf(alf_idx)%sf(j - 2, k - 2, l - 2), & - dyn_p, pi_inf, gamma, rho, qv, & - rhoYks, pres, T) + call s_compute_pressure(q_cons_vf(E_idx)%sf(j - 2, k - 2, l - 2), q_cons_vf(alf_idx)%sf(j - 2, & + & k - 2, l - 2), dyn_p, pi_inf, gamma, rho, qv, rhoYks, pres, T) end if ! Compute mixture sound speed - call s_compute_speed_of_sound(pres, rho, gamma, pi_inf, & - ((gamma + 1._wp)*pres + pi_inf)/rho, alpha, 0._wp, 0._wp, c, qv) + call s_compute_speed_of_sound(pres, rho, gamma, pi_inf, ((gamma + 1._wp)*pres + pi_inf)/rho, alpha, & + & 0._wp, 0._wp, c, qv) accel = accel_mag(j - 2, k - 2, l - 2) end if @@ -1625,134 +1410,53 @@ contains if (n == 0) then if (bubbles_euler .and. (num_fluids <= 2)) then if (qbmm) then - write (i + 30, '(6x,f12.6,14f28.16)') & - nondim_time, & - rho, & - vel(1), & - pres, & - alf, & - R(1), & - Rdot(1), & - nR(1), & - nRdot(1), & - varR, & - varV, & - M10, & - M01, & - M20, & - M02 + write (i + 30, '(6x,f12.6,14f28.16)') nondim_time, rho, vel(1), pres, alf, R(1), Rdot(1), nR(1), & + & nRdot(1), varR, varV, M10, M01, M20, M02 else - write (i + 30, '(6x,f12.6,8f24.8)') & - nondim_time, & - rho, & - vel(1), & - pres, & - alf, & - R(1), & - Rdot(1), & - nR(1), & - nRdot(1) - ! ptilde, & - ! ptot + write (i + 30, '(6x,f12.6,8f24.8)') nondim_time, rho, vel(1), pres, alf, R(1), Rdot(1), nR(1), nRdot(1) + ! ptilde, & ptot end if else if (bubbles_euler .and. (num_fluids == 3)) then - write (i + 30, '(6x,f12.6,f24.8,f24.8,f24.8,f24.8,f24.8,'// & - 'f24.8,f24.8,f24.8,f24.8,f24.8, f24.8)') & - nondim_time, & - rho, & - vel(1), & - pres, & - alf, & - alfgr, & - nR(1), & - nRdot(1), & - R(1), & - Rdot(1), & - ptilde, & - ptot + write (i + 30, & + & '(6x,f12.6,f24.8,f24.8,f24.8,f24.8,f24.8,' // 'f24.8,f24.8,f24.8,f24.8,f24.8, f24.8)') & + & nondim_time, rho, vel(1), pres, alf, alfgr, nR(1), nRdot(1), R(1), Rdot(1), ptilde, ptot else if (bubbles_euler .and. num_fluids == 4) then - write (i + 30, '(6x,f12.6,f24.8,f24.8,f24.8,f24.8,'// & - 'f24.8,f24.8,f24.8,f24.8,f24.8,f24.8,f24.8,f24.8,f24.8)') & - nondim_time, & - q_cons_vf(1)%sf(j - 2, 0, 0), & - q_cons_vf(2)%sf(j - 2, 0, 0), & - q_cons_vf(3)%sf(j - 2, 0, 0), & - q_cons_vf(4)%sf(j - 2, 0, 0), & - q_cons_vf(5)%sf(j - 2, 0, 0), & - q_cons_vf(6)%sf(j - 2, 0, 0), & - q_cons_vf(7)%sf(j - 2, 0, 0), & - q_cons_vf(8)%sf(j - 2, 0, 0), & - q_cons_vf(9)%sf(j - 2, 0, 0), & - q_cons_vf(10)%sf(j - 2, 0, 0), & - nbub, & - R(1), & - Rdot(1) + write (i + 30, & + & '(6x,f12.6,f24.8,f24.8,f24.8,f24.8,' // 'f24.8,f24.8,f24.8,f24.8,f24.8,f24.8,f24.8,f24.8,f24.8)') & + & nondim_time, q_cons_vf(1)%sf(j - 2, 0, 0), q_cons_vf(2)%sf(j - 2, 0, 0), q_cons_vf(3)%sf(j - 2, & + & 0, 0), q_cons_vf(4)%sf(j - 2, 0, 0), q_cons_vf(5)%sf(j - 2, 0, 0), q_cons_vf(6)%sf(j - 2, 0, 0), & + & q_cons_vf(7)%sf(j - 2, 0, 0), q_cons_vf(8)%sf(j - 2, 0, 0), q_cons_vf(9)%sf(j - 2, 0, 0), & + & q_cons_vf(10)%sf(j - 2, 0, 0), nbub, R(1), Rdot(1) else - write (i + 30, '(6X,F12.6,F24.8,F24.8,F24.8)') & - nondim_time, & - rho, & - vel(1), & - pres + write (i + 30, '(6X,F12.6,F24.8,F24.8,F24.8)') nondim_time, rho, vel(1), pres end if - elseif (p == 0) then + else if (p == 0) then if (bubbles_euler) then #:if not MFC_CASE_OPTIMIZATION or num_dims > 1 - write (i + 30, '(6X,10F24.8)') & - nondim_time, & - rho, & - vel(1), & - vel(2), & - pres, & - alf, & - nR(1), & - nRdot(1), & - R(1), & - Rdot(1) + write (i + 30, '(6X,10F24.8)') nondim_time, rho, vel(1), vel(2), pres, alf, nR(1), nRdot(1), R(1), & + & Rdot(1) #:endif else if (elasticity) then #:if not MFC_CASE_OPTIMIZATION or num_dims > 1 - write (i + 30, '(6X,F12.6,F24.8,F24.8,F24.8,F24.8,'// & - 'F24.8,F24.8,F24.8)') & - nondim_time, & - rho, & - vel(1), & - vel(2), & - pres, & - tau_e(1), & - tau_e(2), & - tau_e(3) + write (i + 30, '(6X,F12.6,F24.8,F24.8,F24.8,F24.8,' // 'F24.8,F24.8,F24.8)') nondim_time, rho, & + & vel(1), vel(2), pres, tau_e(1), tau_e(2), tau_e(3) #:endif else - write (i + 30, '(6X,F12.6,F24.8,F24.8,F24.8)') & - nondim_time, & - rho, & - vel(1), & - pres + write (i + 30, '(6X,F12.6,F24.8,F24.8,F24.8)') nondim_time, rho, vel(1), pres print *, 'time =', nondim_time, 'rho =', rho, 'pres =', pres end if else #:if not MFC_CASE_OPTIMIZATION or num_dims > 2 - write (i + 30, '(6X,F12.6,F24.8,F24.8,F24.8,F24.8,'// & - 'F24.8,F24.8,F24.8,F24.8,F24.8,'// & - 'F24.8)') & - nondim_time, & - rho, & - vel(1), & - vel(2), & - vel(3), & - pres, & - gamma, & - pi_inf, & - qv, & - c, & - accel + write (i + 30, & + & '(6X,F12.6,F24.8,F24.8,F24.8,F24.8,' // 'F24.8,F24.8,F24.8,F24.8,F24.8,' // 'F24.8)') & + & nondim_time, rho, vel(1), vel(2), vel(3), pres, gamma, pi_inf, qv, c, accel #:endif end if end if end do if (integral_wrt .and. bubbles_euler) then - if (n == 0) then ! 1D simulation + if (n == 0) then ! 1D simulation do i = 1, num_integrals int_pres = 0._wp max_pres = 0._wp @@ -1771,18 +1475,13 @@ contains if ((integral(i)%xmin <= x_cb(j)) .and. (integral(i)%xmax >= x_cb(j))) then npts = npts + 1 - call s_convert_to_mixture_variables(q_cons_vf, j, k, l, & - rho, gamma, pi_inf, qv, Re) + call s_convert_to_mixture_variables(q_cons_vf, j, k, l, rho, gamma, pi_inf, qv, Re) do s = 1, num_vels vel(s) = q_cons_vf(cont_idx%end + s)%sf(j, k, l)/rho end do - pres = ( & - (q_cons_vf(E_idx)%sf(j, k, l) - & - 0.5_wp*(q_cons_vf(mom_idx%beg)%sf(j, k, l)**2._wp)/rho)/ & - (1._wp - q_cons_vf(alf_idx)%sf(j, k, l)) - & - pi_inf - qv & - )/gamma + pres = ((q_cons_vf(E_idx)%sf(j, k, l) - 0.5_wp*(q_cons_vf(mom_idx%beg)%sf(j, k, & + & l)**2._wp)/rho)/(1._wp - q_cons_vf(alf_idx)%sf(j, k, l)) - pi_inf - qv)/gamma int_pres = int_pres + (pres - 1._wp)**2._wp end if end do @@ -1795,12 +1494,11 @@ contains if (proc_rank == 0) then if (bubbles_euler .and. (num_fluids <= 2)) then - write (i + 70, '(6x,f12.6,f24.8)') & - nondim_time, int_pres + write (i + 70, '(6x,f12.6,f24.8)') nondim_time, int_pres end if end if end do - elseif (p == 0) then + else if (p == 0) then if (num_integrals /= 3) then call s_mpi_abort('Incorrect number of integrals') end if @@ -1817,18 +1515,15 @@ contains do k = 1, n trigger = .false. if (i == 1) then - !inner portion - if (sqrt(x_cb(j)**2._wp + y_cb(k)**2._wp) < (rad - 0.5_wp*thickness)) & - trigger = .true. - elseif (i == 2) then - !net region - if (sqrt(x_cb(j)**2._wp + y_cb(k)**2._wp) > (rad - 0.5_wp*thickness) .and. & - sqrt(x_cb(j)**2._wp + y_cb(k)**2._wp) < (rad + 0.5_wp*thickness)) & - trigger = .true. - elseif (i == 3) then - !everything else - if (sqrt(x_cb(j)**2._wp + y_cb(k)**2._wp) > (rad + 0.5_wp*thickness)) & - trigger = .true. + ! inner portion + if (sqrt(x_cb(j)**2._wp + y_cb(k)**2._wp) < (rad - 0.5_wp*thickness)) trigger = .true. + else if (i == 2) then + ! net region + if (sqrt(x_cb(j)**2._wp + y_cb(k)**2._wp) > (rad - 0.5_wp*thickness) .and. sqrt(x_cb(j)**2._wp & + & + y_cb(k)**2._wp) < (rad + 0.5_wp*thickness)) trigger = .true. + else if (i == 3) then + ! everything else + if (sqrt(x_cb(j)**2._wp + y_cb(k)**2._wp) > (rad + 0.5_wp*thickness)) trigger = .true. end if pres = 0._wp @@ -1843,22 +1538,16 @@ contains if (trigger) then npts = npts + 1 - call s_convert_to_mixture_variables(q_cons_vf, j, k, l, & - rho, gamma, pi_inf, qv, Re) + call s_convert_to_mixture_variables(q_cons_vf, j, k, l, rho, gamma, pi_inf, qv, Re) do s = 1, num_vels vel(s) = q_cons_vf(cont_idx%end + s)%sf(j, k, l)/rho end do - pres = ( & - (q_cons_vf(E_idx)%sf(j, k, l) - & - 0.5_wp*(q_cons_vf(mom_idx%beg)%sf(j, k, l)**2._wp)/rho)/ & - (1._wp - q_cons_vf(alf_idx)%sf(j, k, l)) - & - pi_inf - qv & - )/gamma + pres = ((q_cons_vf(E_idx)%sf(j, k, l) - 0.5_wp*(q_cons_vf(mom_idx%beg)%sf(j, k, & + & l)**2._wp)/rho)/(1._wp - q_cons_vf(alf_idx)%sf(j, k, l)) - pi_inf - qv)/gamma int_pres = int_pres + abs(pres - 1._wp) max_pres = max(max_pres, abs(pres - 1._wp)) end if - end do end do @@ -1878,8 +1567,7 @@ contains if (proc_rank == 0) then if (bubbles_euler .and. (num_fluids <= 2)) then - write (i + 70, '(6x,f12.6,f24.8,f24.8)') & - nondim_time, int_pres, max_pres + write (i + 70, '(6x,f12.6,f24.8,f24.8)') nondim_time, int_pres, max_pres end if end if end do @@ -1888,16 +1576,15 @@ contains end subroutine s_write_probe_files - !> The goal of this subroutine is to write to the run-time - !! information file basic footer information applicable to - !! the current computation and to close the file when done. - !! The footer contains the stability criteria extrema over - !! all of the time-steps and the simulation run-time. + !> The goal of this subroutine is to write to the run-time information file basic footer information applicable to the current + !! computation and to close the file when done. The footer contains the stability criteria extrema over all of the time-steps + !! and the simulation run-time. impure subroutine s_close_run_time_information_file - real(wp) :: run_time !< Run-time of the simulation + real(wp) :: run_time !< Run-time of the simulation ! Writing the footer of and closing the run-time information file + write (3, '(A)') ' ' write (3, '(A)') '' @@ -1917,7 +1604,8 @@ contains !> Closes communication files impure subroutine s_close_com_files() - integer :: i !< Generic loop iterator + integer :: i !< Generic loop iterator + do i = 1, num_fluids close (i + 120) end do @@ -1927,7 +1615,7 @@ contains !> Closes probe files impure subroutine s_close_probe_files - integer :: i !< Generic loop iterator + integer :: i !< Generic loop iterator do i = 1, num_probes close (i + 30) @@ -1941,14 +1629,14 @@ contains end subroutine s_close_ib_state_file - !> The computation of parameters, the allocation of memory, - !! the association of pointers and/or the execution of any - !! other procedures that are necessary to setup the module. + !> The computation of parameters, the allocation of memory, the association of pointers and/or the execution of any other + !! procedures that are necessary to setup the module. impure subroutine s_initialize_data_output_module integer :: i, m_ds, n_ds, p_ds ! Allocating/initializing ICFL, VCFL, CCFL and Rc stability criteria + if (run_time_info) then icfl_max = 0._wp if (viscous) then @@ -1968,7 +1656,7 @@ contains allocate (q_cons_temp_ds(1:sys_size)) do i = 1, sys_size - allocate (q_cons_temp_ds(i)%sf(-1:m_ds + 1, -1:n_ds + 1, -1:p_ds + 1)) + allocate (q_cons_temp_ds(i)%sf(-1:m_ds + 1,-1:n_ds + 1,-1:p_ds + 1)) end do end if diff --git a/src/simulation/m_derived_variables.fpp b/src/simulation/m_derived_variables.fpp index 53a8396cbf..a87c36465e 100644 --- a/src/simulation/m_derived_variables.fpp +++ b/src/simulation/m_derived_variables.fpp @@ -2,65 +2,52 @@ !! @file !! @brief Contains module m_derived_variables -!> @brief Derives diagnostic flow quantities (vorticity, speed of sound, numerical Schlieren, etc.) from conservative and primitive variables +!> @brief Derives diagnostic flow quantities (vorticity, speed of sound, numerical Schlieren, etc.) from conservative and primitive +!! variables #:include 'macros.fpp' module m_derived_variables - use m_derived_types !< Definitions of the derived types - - use m_global_parameters !< Global parameters for the code - - use m_mpi_proxy !< Message passing interface (MPI) module proxy - - use m_data_output !< Data output module - + use m_derived_types !< Definitions of the derived types + use m_global_parameters !< Global parameters for the code + use m_mpi_proxy !< Message passing interface (MPI) module proxy + use m_data_output !< Data output module use m_compile_specific - use m_helper - use m_finite_differences implicit none - private; public :: s_initialize_derived_variables_module, & - s_initialize_derived_variables, & - s_compute_derived_variables, & - s_finalize_derived_variables_module + private; public :: s_initialize_derived_variables_module, s_initialize_derived_variables, s_compute_derived_variables, & + & s_finalize_derived_variables_module - !> @name Finite-difference coefficients - !! Finite-difference (fd) coefficients in x-, y- and z-coordinate directions. - !! Note that because sufficient boundary information is available for all the - !! active coordinate directions, the centered family of the finite-difference - !! schemes is used. + !> @name Finite-difference coefficients Finite-difference (fd) coefficients in x-, y- and z-coordinate directions. Note that + !! because sufficient boundary information is available for all the active coordinate directions, the centered family of the + !! finite-difference schemes is used. !> @{ - real(wp), public, allocatable, dimension(:, :) :: fd_coeff_x - real(wp), public, allocatable, dimension(:, :) :: fd_coeff_y - real(wp), public, allocatable, dimension(:, :) :: fd_coeff_z + real(wp), public, allocatable, dimension(:,:) :: fd_coeff_x + real(wp), public, allocatable, dimension(:,:) :: fd_coeff_y + real(wp), public, allocatable, dimension(:,:) :: fd_coeff_z !> @} - $:GPU_DECLARE(create='[fd_coeff_x,fd_coeff_y,fd_coeff_z]') + $:GPU_DECLARE(create='[fd_coeff_x, fd_coeff_y, fd_coeff_z]') ! @name Variables for computing acceleration !> @{ - real(wp), public, allocatable, dimension(:, :, :) :: accel_mag - real(wp), public, allocatable, dimension(:, :, :) :: x_accel, y_accel, z_accel + real(wp), public, allocatable, dimension(:,:,:) :: accel_mag + real(wp), public, allocatable, dimension(:,:,:) :: x_accel, y_accel, z_accel !> @} - $:GPU_DECLARE(create='[accel_mag,x_accel,y_accel,z_accel]') + $:GPU_DECLARE(create='[accel_mag, x_accel, y_accel, z_accel]') contains - !> Computation of parameters, allocation procedures, and/or - !! any other tasks needed to properly setup the module + !> Computation of parameters, allocation procedures, and/or any other tasks needed to properly setup the module impure subroutine s_initialize_derived_variables_module - ! Allocating the variables which will store the coefficients of the - ! centered family of finite-difference schemes. Note that sufficient - ! space is allocated so that the coefficients up to any chosen order - ! of accuracy may be bookkept. However, if higher than fourth-order - ! accuracy coefficients are wanted, the formulae required to compute - ! these coefficients will have to be implemented in the subroutine - ! s_compute_finite_difference_coefficients. + ! Allocating the variables which will store the coefficients of the centered family of finite-difference schemes. Note that + ! sufficient space is allocated so that the coefficients up to any chosen order of accuracy may be bookkept. However, if + ! higher than fourth-order accuracy coefficients are wanted, the formulae required to compute these coefficients will have + ! to be implemented in the subroutine s_compute_finite_difference_coefficients. ! Allocating centered finite-difference coefficients if (probe_wrt) then @@ -94,18 +81,15 @@ contains call s_open_com_files() end if ! Computing centered finite difference coefficients - call s_compute_finite_difference_coefficients(m, x_cc, fd_coeff_x, buff_size, & - fd_number, fd_order) + call s_compute_finite_difference_coefficients(m, x_cc, fd_coeff_x, buff_size, fd_number, fd_order) $:GPU_UPDATE(device='[fd_coeff_x]') if (n > 0) then - call s_compute_finite_difference_coefficients(n, y_cc, fd_coeff_y, buff_size, & - fd_number, fd_order) + call s_compute_finite_difference_coefficients(n, y_cc, fd_coeff_y, buff_size, fd_number, fd_order) $:GPU_UPDATE(device='[fd_coeff_y]') end if if (p > 0) then - call s_compute_finite_difference_coefficients(p, z_cc, fd_coeff_z, buff_size, & - fd_number, fd_order) + call s_compute_finite_difference_coefficients(p, z_cc, fd_coeff_z, buff_size, fd_number, fd_order) $:GPU_UPDATE(device='[fd_coeff_z]') end if end if @@ -113,49 +97,36 @@ contains end subroutine s_initialize_derived_variables !> Writes coherent body information, communication files, and probes. - !! @param t_step Current time-step - !! @param q_cons_vf Conservative variables - !! @param q_prim_ts1 Primitive variables at time-stage 1 - !! @param q_prim_ts2 Primitive variables at time-stage 2 + !! @param t_step Current time-step + !! @param q_cons_vf Conservative variables + !! @param q_prim_ts1 Primitive variables at time-stage 1 + !! @param q_prim_ts2 Primitive variables at time-stage 2 subroutine s_compute_derived_variables(t_step, q_cons_vf, q_prim_ts1, q_prim_ts2) - integer, intent(in) :: t_step + integer, intent(in) :: t_step type(scalar_field), dimension(:), intent(inout) :: q_cons_vf type(vector_field), dimension(:), intent(inout) :: q_prim_ts1, q_prim_ts2 - integer :: i, j, k !< Generic loop iterators + integer :: i, j, k !< Generic loop iterators if (probe_wrt) then - call s_derive_acceleration_component(1, q_prim_ts1(1)%vf, & - q_prim_ts1(2)%vf, & - q_prim_ts2(1)%vf, & - q_prim_ts2(2)%vf, & - x_accel) + call s_derive_acceleration_component(1, q_prim_ts1(1)%vf, q_prim_ts1(2)%vf, q_prim_ts2(1)%vf, q_prim_ts2(2)%vf, x_accel) if (n > 0) then - call s_derive_acceleration_component(2, q_prim_ts1(1)%vf, & - q_prim_ts1(2)%vf, & - q_prim_ts2(1)%vf, & - q_prim_ts2(2)%vf, & - y_accel) + call s_derive_acceleration_component(2, q_prim_ts1(1)%vf, q_prim_ts1(2)%vf, q_prim_ts2(1)%vf, q_prim_ts2(2)%vf, & + & y_accel) end if if (p > 0) then - call s_derive_acceleration_component(3, q_prim_ts1(1)%vf, & - q_prim_ts1(2)%vf, & - q_prim_ts2(1)%vf, & - q_prim_ts2(2)%vf, & - z_accel) + call s_derive_acceleration_component(3, q_prim_ts1(1)%vf, q_prim_ts1(2)%vf, q_prim_ts2(1)%vf, q_prim_ts2(2)%vf, & + & z_accel) end if - $:GPU_PARALLEL_LOOP(private='[i,j,k]', collapse=3) + $:GPU_PARALLEL_LOOP(private='[i, j, k]', collapse=3) do k = 0, p do j = 0, n do i = 0, m if (p > 0) then - accel_mag(i, j, k) = sqrt(x_accel(i, j, k)**2._wp + & - y_accel(i, j, k)**2._wp + & - z_accel(i, j, k)**2._wp) - elseif (n > 0) then - accel_mag(i, j, k) = sqrt(x_accel(i, j, k)**2._wp + & - y_accel(i, j, k)**2._wp) + accel_mag(i, j, k) = sqrt(x_accel(i, j, k)**2._wp + y_accel(i, j, k)**2._wp + z_accel(i, j, k)**2._wp) + else if (n > 0) then + accel_mag(i, j, k) = sqrt(x_accel(i, j, k)**2._wp + y_accel(i, j, k)**2._wp) else accel_mag(i, j, k) = x_accel(i, j, k) end if @@ -175,72 +146,61 @@ contains end subroutine s_compute_derived_variables - !> This subroutine receives as inputs the indicator of the - !! component of the acceleration that should be outputted and - !! the primitive variables. From those inputs, it proceeds - !! to calculate values of the desired acceleration component, - !! which are subsequently stored in derived flow quantity - !! storage variable, q_sf. - !! @param i Acceleration component indicator - !! @param q_prim_vf0 Primitive variables - !! @param q_prim_vf1 Primitive variables - !! @param q_prim_vf2 Primitive variables - !! @param q_prim_vf3 Primitive variables - !! @param q_sf Acceleration component - subroutine s_derive_acceleration_component(i, q_prim_vf0, q_prim_vf1, & - q_prim_vf2, q_prim_vf3, q_sf) - - integer, intent(in) :: i - + !> This subroutine receives as inputs the indicator of the component of the acceleration that should be outputted and the + !! primitive variables. From those inputs, it proceeds to calculate values of the desired acceleration component, which are + !! subsequently stored in derived flow quantity storage variable, q_sf. + !! @param i Acceleration component indicator + !! @param q_prim_vf0 Primitive variables + !! @param q_prim_vf1 Primitive variables + !! @param q_prim_vf2 Primitive variables + !! @param q_prim_vf3 Primitive variables + !! @param q_sf Acceleration component + subroutine s_derive_acceleration_component(i, q_prim_vf0, q_prim_vf1, q_prim_vf2, q_prim_vf3, q_sf) + + integer, intent(in) :: i type(scalar_field), dimension(sys_size), intent(in) :: q_prim_vf0 type(scalar_field), dimension(sys_size), intent(in) :: q_prim_vf1 type(scalar_field), dimension(sys_size), intent(in) :: q_prim_vf2 type(scalar_field), dimension(sys_size), intent(in) :: q_prim_vf3 - - real(wp), dimension(0:m, 0:n, 0:p), intent(out) :: q_sf - - integer :: j, k, l, r !< Generic loop iterators + real(wp), dimension(0:m,0:n,0:p), intent(out) :: q_sf + integer :: j, k, l, r !< Generic loop iterators ! Computing the acceleration component in the x-coordinate direction + if (i == 1) then - $:GPU_PARALLEL_LOOP(private='[j,k,l]', collapse=3) + $:GPU_PARALLEL_LOOP(private='[j, k, l]', collapse=3) do l = 0, p do k = 0, n do j = 0, m - q_sf(j, k, l) = (11._wp*q_prim_vf0(momxb)%sf(j, k, l) & - - 18._wp*q_prim_vf1(momxb)%sf(j, k, l) & - + 9._wp*q_prim_vf2(momxb)%sf(j, k, l) & - - 2._wp*q_prim_vf3(momxb)%sf(j, k, l))/(6._wp*dt) + q_sf(j, k, l) = (11._wp*q_prim_vf0(momxb)%sf(j, k, l) - 18._wp*q_prim_vf1(momxb)%sf(j, k, & + & l) + 9._wp*q_prim_vf2(momxb)%sf(j, k, l) - 2._wp*q_prim_vf3(momxb)%sf(j, k, l))/(6._wp*dt) end do end do end do $:END_GPU_PARALLEL_LOOP() if (n == 0) then - $:GPU_PARALLEL_LOOP(private='[j,k,l,r]', collapse=4) + $:GPU_PARALLEL_LOOP(private='[j, k, l, r]', collapse=4) do l = 0, p do k = 0, n do j = 0, m do r = -fd_number, fd_number - q_sf(j, k, l) = q_sf(j, k, l) & - + q_prim_vf0(momxb)%sf(j, k, l)*fd_coeff_x(r, j)* & - q_prim_vf0(momxb)%sf(r + j, k, l) + q_sf(j, k, l) = q_sf(j, k, l) + q_prim_vf0(momxb)%sf(j, k, l)*fd_coeff_x(r, & + & j)*q_prim_vf0(momxb)%sf(r + j, k, l) end do end do end do end do $:END_GPU_PARALLEL_LOOP() - elseif (p == 0) then - $:GPU_PARALLEL_LOOP(private='[j,k,l,r]', collapse=4) + else if (p == 0) then + $:GPU_PARALLEL_LOOP(private='[j, k, l, r]', collapse=4) do l = 0, p do k = 0, n do j = 0, m do r = -fd_number, fd_number - q_sf(j, k, l) = q_sf(j, k, l) & - + q_prim_vf0(momxb)%sf(j, k, l)*fd_coeff_x(r, j)* & - q_prim_vf0(momxb)%sf(r + j, k, l) & - + q_prim_vf0(momxb + 1)%sf(j, k, l)*fd_coeff_y(r, k)* & - q_prim_vf0(momxb)%sf(j, r + k, l) + q_sf(j, k, l) = q_sf(j, k, l) + q_prim_vf0(momxb)%sf(j, k, l)*fd_coeff_x(r, & + & j)*q_prim_vf0(momxb)%sf(r + j, k, l) + q_prim_vf0(momxb + 1)%sf(j, k, l)*fd_coeff_y(r, & + & k)*q_prim_vf0(momxb)%sf(j, r + k, l) end do end do end do @@ -248,36 +208,30 @@ contains $:END_GPU_PARALLEL_LOOP() else if (grid_geometry == 3) then - $:GPU_PARALLEL_LOOP(private='[j,k,l,r]', collapse=4) + $:GPU_PARALLEL_LOOP(private='[j, k, l, r]', collapse=4) do l = 0, p do k = 0, n do j = 0, m do r = -fd_number, fd_number - q_sf(j, k, l) = q_sf(j, k, l) & - + q_prim_vf0(momxb)%sf(j, k, l)*fd_coeff_x(r, j)* & - q_prim_vf0(momxb)%sf(r + j, k, l) & - + q_prim_vf0(momxb + 1)%sf(j, k, l)*fd_coeff_y(r, k)* & - q_prim_vf0(momxb)%sf(j, r + k, l) & - + q_prim_vf0(momxe)%sf(j, k, l)*fd_coeff_z(r, l)* & - q_prim_vf0(momxb)%sf(j, k, r + l)/y_cc(k) + q_sf(j, k, l) = q_sf(j, k, l) + q_prim_vf0(momxb)%sf(j, k, l)*fd_coeff_x(r, & + & j)*q_prim_vf0(momxb)%sf(r + j, k, l) + q_prim_vf0(momxb + 1)%sf(j, k, l)*fd_coeff_y(r, & + & k)*q_prim_vf0(momxb)%sf(j, r + k, l) + q_prim_vf0(momxe)%sf(j, k, l)*fd_coeff_z(r, & + & l)*q_prim_vf0(momxb)%sf(j, k, r + l)/y_cc(k) end do end do end do end do $:END_GPU_PARALLEL_LOOP() else - $:GPU_PARALLEL_LOOP(private='[j,k,l,r]', collapse=4) + $:GPU_PARALLEL_LOOP(private='[j, k, l, r]', collapse=4) do l = 0, p do k = 0, n do j = 0, m do r = -fd_number, fd_number - q_sf(j, k, l) = q_sf(j, k, l) & - + q_prim_vf0(momxb)%sf(j, k, l)*fd_coeff_x(r, j)* & - q_prim_vf0(momxb)%sf(r + j, k, l) & - + q_prim_vf0(momxb + 1)%sf(j, k, l)*fd_coeff_y(r, k)* & - q_prim_vf0(momxb)%sf(j, r + k, l) & - + q_prim_vf0(momxe)%sf(j, k, l)*fd_coeff_z(r, l)* & - q_prim_vf0(momxb)%sf(j, k, r + l) + q_sf(j, k, l) = q_sf(j, k, l) + q_prim_vf0(momxb)%sf(j, k, l)*fd_coeff_x(r, & + & j)*q_prim_vf0(momxb)%sf(r + j, k, l) + q_prim_vf0(momxb + 1)%sf(j, k, l)*fd_coeff_y(r, & + & k)*q_prim_vf0(momxb)%sf(j, r + k, l) + q_prim_vf0(momxe)%sf(j, k, l)*fd_coeff_z(r, & + & l)*q_prim_vf0(momxb)%sf(j, k, r + l) end do end do end do @@ -286,31 +240,27 @@ contains end if end if ! Computing the acceleration component in the y-coordinate direction - elseif (i == 2) then - $:GPU_PARALLEL_LOOP(private='[j,k,l]', collapse=3) + else if (i == 2) then + $:GPU_PARALLEL_LOOP(private='[j, k, l]', collapse=3) do l = 0, p do k = 0, n do j = 0, m - q_sf(j, k, l) = (11._wp*q_prim_vf0(momxb + 1)%sf(j, k, l) & - - 18._wp*q_prim_vf1(momxb + 1)%sf(j, k, l) & - + 9._wp*q_prim_vf2(momxb + 1)%sf(j, k, l) & - - 2._wp*q_prim_vf3(momxb + 1)%sf(j, k, l))/(6._wp*dt) + q_sf(j, k, l) = (11._wp*q_prim_vf0(momxb + 1)%sf(j, k, l) - 18._wp*q_prim_vf1(momxb + 1)%sf(j, k, & + & l) + 9._wp*q_prim_vf2(momxb + 1)%sf(j, k, l) - 2._wp*q_prim_vf3(momxb + 1)%sf(j, k, l))/(6._wp*dt) end do end do end do $:END_GPU_PARALLEL_LOOP() if (p == 0) then - $:GPU_PARALLEL_LOOP(private='[j,k,l,r]', collapse=4) + $:GPU_PARALLEL_LOOP(private='[j, k, l, r]', collapse=4) do l = 0, p do k = 0, n do j = 0, m do r = -fd_number, fd_number - q_sf(j, k, l) = q_sf(j, k, l) & - + q_prim_vf0(momxb)%sf(j, k, l)*fd_coeff_x(r, j)* & - q_prim_vf0(momxb + 1)%sf(r + j, k, l) & - + q_prim_vf0(momxb + 1)%sf(j, k, l)*fd_coeff_y(r, k)* & - q_prim_vf0(momxb + 1)%sf(j, r + k, l) + q_sf(j, k, l) = q_sf(j, k, l) + q_prim_vf0(momxb)%sf(j, k, l)*fd_coeff_x(r, & + & j)*q_prim_vf0(momxb + 1)%sf(r + j, k, l) + q_prim_vf0(momxb + 1)%sf(j, k, l)*fd_coeff_y(r, & + & k)*q_prim_vf0(momxb + 1)%sf(j, r + k, l) end do end do end do @@ -318,37 +268,31 @@ contains $:END_GPU_PARALLEL_LOOP() else if (grid_geometry == 3) then - $:GPU_PARALLEL_LOOP(private='[j,k,l,r]', collapse=4) + $:GPU_PARALLEL_LOOP(private='[j, k, l, r]', collapse=4) do l = 0, p do k = 0, n do j = 0, m do r = -fd_number, fd_number - q_sf(j, k, l) = q_sf(j, k, l) & - + q_prim_vf0(momxb)%sf(j, k, l)*fd_coeff_x(r, j)* & - q_prim_vf0(momxb + 1)%sf(r + j, k, l) & - + q_prim_vf0(momxb + 1)%sf(j, k, l)*fd_coeff_y(r, k)* & - q_prim_vf0(momxb + 1)%sf(j, r + k, l) & - + q_prim_vf0(momxe)%sf(j, k, l)*fd_coeff_z(r, l)* & - q_prim_vf0(momxb + 1)%sf(j, k, r + l)/y_cc(k) & - - (q_prim_vf0(momxe)%sf(j, k, l)**2._wp)/y_cc(k) + q_sf(j, k, l) = q_sf(j, k, l) + q_prim_vf0(momxb)%sf(j, k, l)*fd_coeff_x(r, & + & j)*q_prim_vf0(momxb + 1)%sf(r + j, k, l) + q_prim_vf0(momxb + 1)%sf(j, k, & + & l)*fd_coeff_y(r, k)*q_prim_vf0(momxb + 1)%sf(j, r + k, l) + q_prim_vf0(momxe)%sf(j, k, & + & l)*fd_coeff_z(r, l)*q_prim_vf0(momxb + 1)%sf(j, k, & + & r + l)/y_cc(k) - (q_prim_vf0(momxe)%sf(j, k, l)**2._wp)/y_cc(k) end do end do end do end do $:END_GPU_PARALLEL_LOOP() else - $:GPU_PARALLEL_LOOP(private='[j,k,l,r]', collapse=4) + $:GPU_PARALLEL_LOOP(private='[j, k, l, r]', collapse=4) do l = 0, p do k = 0, n do j = 0, m do r = -fd_number, fd_number - q_sf(j, k, l) = q_sf(j, k, l) & - + q_prim_vf0(momxb)%sf(j, k, l)*fd_coeff_x(r, j)* & - q_prim_vf0(momxb + 1)%sf(r + j, k, l) & - + q_prim_vf0(momxb + 1)%sf(j, k, l)*fd_coeff_y(r, k)* & - q_prim_vf0(momxb + 1)%sf(j, r + k, l) & - + q_prim_vf0(momxe)%sf(j, k, l)*fd_coeff_z(r, l)* & - q_prim_vf0(momxb + 1)%sf(j, k, r + l) + q_sf(j, k, l) = q_sf(j, k, l) + q_prim_vf0(momxb)%sf(j, k, l)*fd_coeff_x(r, & + & j)*q_prim_vf0(momxb + 1)%sf(r + j, k, l) + q_prim_vf0(momxb + 1)%sf(j, k, & + & l)*fd_coeff_y(r, k)*q_prim_vf0(momxb + 1)%sf(j, r + k, l) + q_prim_vf0(momxe)%sf(j, k, & + & l)*fd_coeff_z(r, l)*q_prim_vf0(momxb + 1)%sf(j, k, r + l) end do end do end do @@ -358,52 +302,43 @@ contains end if ! Computing the acceleration component in the z-coordinate direction else - $:GPU_PARALLEL_LOOP(private='[j,k,l]', collapse=3) + $:GPU_PARALLEL_LOOP(private='[j, k, l]', collapse=3) do l = 0, p do k = 0, n do j = 0, m - q_sf(j, k, l) = (11._wp*q_prim_vf0(momxe)%sf(j, k, l) & - - 18._wp*q_prim_vf1(momxe)%sf(j, k, l) & - + 9._wp*q_prim_vf2(momxe)%sf(j, k, l) & - - 2._wp*q_prim_vf3(momxe)%sf(j, k, l))/(6._wp*dt) + q_sf(j, k, l) = (11._wp*q_prim_vf0(momxe)%sf(j, k, l) - 18._wp*q_prim_vf1(momxe)%sf(j, k, & + & l) + 9._wp*q_prim_vf2(momxe)%sf(j, k, l) - 2._wp*q_prim_vf3(momxe)%sf(j, k, l))/(6._wp*dt) end do end do end do $:END_GPU_PARALLEL_LOOP() if (grid_geometry == 3) then - $:GPU_PARALLEL_LOOP(private='[j,k,l,r]', collapse=4) + $:GPU_PARALLEL_LOOP(private='[j, k, l, r]', collapse=4) do l = 0, p do k = 0, n do j = 0, m do r = -fd_number, fd_number - q_sf(j, k, l) = q_sf(j, k, l) & - + q_prim_vf0(momxb)%sf(j, k, l)*fd_coeff_x(r, j)* & - q_prim_vf0(momxe)%sf(r + j, k, l) & - + q_prim_vf0(momxb + 1)%sf(j, k, l)*fd_coeff_y(r, k)* & - q_prim_vf0(momxe)%sf(j, r + k, l) & - + q_prim_vf0(momxe)%sf(j, k, l)*fd_coeff_z(r, l)* & - q_prim_vf0(momxe)%sf(j, k, r + l)/y_cc(k) & - + (q_prim_vf0(momxe)%sf(j, k, l)* & - q_prim_vf0(momxb + 1)%sf(j, k, l))/y_cc(k) + q_sf(j, k, l) = q_sf(j, k, l) + q_prim_vf0(momxb)%sf(j, k, l)*fd_coeff_x(r, & + & j)*q_prim_vf0(momxe)%sf(r + j, k, l) + q_prim_vf0(momxb + 1)%sf(j, k, l)*fd_coeff_y(r, & + & k)*q_prim_vf0(momxe)%sf(j, r + k, l) + q_prim_vf0(momxe)%sf(j, k, l)*fd_coeff_z(r, & + & l)*q_prim_vf0(momxe)%sf(j, k, r + l)/y_cc(k) + (q_prim_vf0(momxe)%sf(j, k, & + & l)*q_prim_vf0(momxb + 1)%sf(j, k, l))/y_cc(k) end do end do end do end do $:END_GPU_PARALLEL_LOOP() else - $:GPU_PARALLEL_LOOP(private='[j,k,l,r]', collapse=4) + $:GPU_PARALLEL_LOOP(private='[j, k, l, r]', collapse=4) do l = 0, p do k = 0, n do j = 0, m do r = -fd_number, fd_number - q_sf(j, k, l) = q_sf(j, k, l) & - + q_prim_vf0(momxb)%sf(j, k, l)*fd_coeff_x(r, j)* & - q_prim_vf0(momxe)%sf(r + j, k, l) & - + q_prim_vf0(momxb + 1)%sf(j, k, l)*fd_coeff_y(r, k)* & - q_prim_vf0(momxe)%sf(j, r + k, l) & - + q_prim_vf0(momxe)%sf(j, k, l)*fd_coeff_z(r, l)* & - q_prim_vf0(momxe)%sf(j, k, r + l) + q_sf(j, k, l) = q_sf(j, k, l) + q_prim_vf0(momxb)%sf(j, k, l)*fd_coeff_x(r, & + & j)*q_prim_vf0(momxe)%sf(r + j, k, l) + q_prim_vf0(momxb + 1)%sf(j, k, l)*fd_coeff_y(r, & + & k)*q_prim_vf0(momxe)%sf(j, r + k, l) + q_prim_vf0(momxe)%sf(j, k, l)*fd_coeff_z(r, & + & l)*q_prim_vf0(momxe)%sf(j, k, r + l) end do end do end do @@ -414,31 +349,30 @@ contains end subroutine s_derive_acceleration_component - !> This subroutine is used together with the volume fraction - !! model and when called upon, it computes the location of - !! of the center of mass for each fluid from the inputted - !! primitive variables, q_prim_vf. The computed location - !! is then written to a formatted data file by the root process. - !! @param q_vf Primitive variables - !! @param c_m Mass,x-location,y-location,z-location + !> This subroutine is used together with the volume fraction model and when called upon, it computes the location of of the + !! center of mass for each fluid from the inputted primitive variables, q_prim_vf. The computed location is then written to a + !! formatted data file by the root process. + !! @param q_vf Primitive variables + !! @param c_m Mass,x-location,y-location,z-location impure subroutine s_derive_center_of_mass(q_vf, c_m) - type(scalar_field), dimension(sys_size), intent(IN) :: q_vf - real(wp), dimension(1:num_fluids, 1:5), intent(INOUT) :: c_m - integer :: i, j, k, l !< Generic loop iterators - real(wp) :: tmp, tmp_out !< Temporary variable to store quantity for mpi_allreduce - real(wp) :: dV !< Discrete cell volume - c_m(:, :) = 0.0_wp + type(scalar_field), dimension(sys_size), intent(in) :: q_vf + real(wp), dimension(1:num_fluids,1:5), intent(inout) :: c_m + integer :: i, j, k, l !< Generic loop iterators + real(wp) :: tmp, tmp_out !< Temporary variable to store quantity for mpi_allreduce + real(wp) :: dV !< Discrete cell volume + + c_m(:,:) = 0.0_wp $:GPU_UPDATE(device='[c_m]') - if (n == 0) then !1D simulation - $:GPU_PARALLEL_LOOP(collapse=3,private='[j,k,l,dV]') - do l = 0, p !Loop over grid + if (n == 0) then ! 1D simulation + $:GPU_PARALLEL_LOOP(collapse=3,private='[j, k, l, dV]') + do l = 0, p ! Loop over grid do k = 0, n do j = 0, m $:GPU_LOOP(parallelism='[seq]') - do i = 1, num_fluids !Loop over individual fluids + do i = 1, num_fluids ! Loop over individual fluids dV = dx(j) ! Mass $:GPU_ATOMIC(atomic='update') @@ -454,13 +388,13 @@ contains end do end do $:END_GPU_PARALLEL_LOOP() - elseif (p == 0) then !2D simulation - $:GPU_PARALLEL_LOOP(collapse=3,private='[j,k,l,dV]') - do l = 0, p !Loop over grid + else if (p == 0) then ! 2D simulation + $:GPU_PARALLEL_LOOP(collapse=3,private='[j, k, l, dV]') + do l = 0, p ! Loop over grid do k = 0, n do j = 0, m $:GPU_LOOP(parallelism='[seq]') - do i = 1, num_fluids !Loop over individual fluids + do i = 1, num_fluids ! Loop over individual fluids dV = dx(j)*dy(k) ! Mass $:GPU_ATOMIC(atomic='update') @@ -479,14 +413,13 @@ contains end do end do $:END_GPU_PARALLEL_LOOP() - else !3D simulation - $:GPU_PARALLEL_LOOP(collapse=3,private='[j,k,l,dV]') - do l = 0, p !Loop over grid + else ! 3D simulation + $:GPU_PARALLEL_LOOP(collapse=3,private='[j, k, l, dV]') + do l = 0, p ! Loop over grid do k = 0, n do j = 0, m $:GPU_LOOP(parallelism='[seq]') - do i = 1, num_fluids !Loop over individual fluids - + do i = 1, num_fluids ! Loop over individual fluids dV = dx(j)*dy(k)*dz(l) ! Mass $:GPU_ATOMIC(atomic='update') @@ -512,8 +445,8 @@ contains $:GPU_UPDATE(host='[c_m]') - if (n == 0) then !1D simulation - do i = 1, num_fluids !Loop over individual fluids + if (n == 0) then ! 1D simulation + do i = 1, num_fluids ! Loop over individual fluids ! Sum all components across all processors using MPI_ALLREDUCE if (num_procs > 1) then tmp = c_m(i, 1) @@ -529,8 +462,8 @@ contains ! Compute quotients c_m(i, 2) = c_m(i, 2)/c_m(i, 1) end do - elseif (p == 0) then !2D simulation - do i = 1, num_fluids !Loop over individual fluids + else if (p == 0) then ! 2D simulation + do i = 1, num_fluids ! Loop over individual fluids ! Sum all components across all processors using MPI_ALLREDUCE if (num_procs > 1) then tmp = c_m(i, 1) @@ -550,8 +483,8 @@ contains c_m(i, 2) = c_m(i, 2)/c_m(i, 1) c_m(i, 3) = c_m(i, 3)/c_m(i, 1) end do - else !3D simulation - do i = 1, num_fluids !Loop over individual fluids + else ! 3D simulation + do i = 1, num_fluids ! Loop over individual fluids ! Sum all components across all processors using MPI_ALLREDUCE if (num_procs > 1) then tmp = c_m(i, 1) @@ -600,8 +533,8 @@ contains end if end if - ! Deallocating the variables that might have been used to bookkeep - ! the finite-difference coefficients in the x-, y- and z-directions + ! Deallocating the variables that might have been used to bookkeep the finite-difference coefficients in the x-, y- and + ! z-directions if (allocated(fd_coeff_x)) deallocate (fd_coeff_x) if (allocated(fd_coeff_y)) deallocate (fd_coeff_y) if (allocated(fd_coeff_z)) deallocate (fd_coeff_z) diff --git a/src/simulation/m_fftw.fpp b/src/simulation/m_fftw.fpp index 661767e13c..b27b708621 100644 --- a/src/simulation/m_fftw.fpp +++ b/src/simulation/m_fftw.fpp @@ -6,13 +6,12 @@ !> @brief Forward and inverse FFT wrappers (FFTW/cuFFT/hipFFT) for azimuthal Fourier filtering in cylindrical geometries module m_fftw - use, intrinsic :: iso_c_binding - - use m_derived_types !< Definitions of the derived types - use m_global_parameters !< Definitions of the global parameters + use, intrinsic :: iso_c_binding - use m_mpi_proxy !< Message passing interface (MPI) module proxy + use m_derived_types !< Definitions of the derived types + use m_global_parameters !< Definitions of the global parameters + use m_mpi_proxy !< Message passing interface (MPI) module proxy #if defined(MFC_GPU) && defined(__PGI) use cufft @@ -24,59 +23,51 @@ module m_fftw implicit none - private; public :: s_initialize_fftw_module, & - s_apply_fourier_filter, & - s_finalize_fftw_module + private; public :: s_initialize_fftw_module, s_apply_fourier_filter, s_finalize_fftw_module #if !defined(MFC_GPU) include 'fftw3.f03' #endif - type(c_ptr) :: fwd_plan, bwd_plan - type(c_ptr) :: fftw_real_data, fftw_cmplx_data, fftw_fltr_cmplx_data - integer :: real_size, cmplx_size, x_size, batch_size, Nfq - - real(c_double), pointer :: data_real(:) !< Real data - - complex(c_double_complex), pointer :: data_cmplx(:) !< - !! Complex data in Fourier space - - complex(c_double_complex), pointer :: data_fltr_cmplx(:) !< - !! Filtered complex data in Fourier space + type(c_ptr) :: fwd_plan, bwd_plan + type(c_ptr) :: fftw_real_data, fftw_cmplx_data, fftw_fltr_cmplx_data + integer :: real_size, cmplx_size, x_size, batch_size, Nfq + real(c_double), pointer :: data_real(:) !< Real data + complex(c_double_complex), pointer :: data_cmplx(:) !< Complex data in Fourier space + complex(c_double_complex), pointer :: data_fltr_cmplx(:) !< Filtered complex data in Fourier space #if defined(MFC_GPU) - $:GPU_DECLARE(create='[real_size,cmplx_size,x_size,batch_size,Nfq]') + $:GPU_DECLARE(create='[real_size, cmplx_size, x_size, batch_size, Nfq]') - real(dp), allocatable, target :: data_real_gpu(:) + real(dp), allocatable, target :: data_real_gpu(:) complex(dp), allocatable, target :: data_cmplx_gpu(:) complex(dp), allocatable, target :: data_fltr_cmplx_gpu(:) - $:GPU_DECLARE(create='[data_real_gpu,data_cmplx_gpu,data_fltr_cmplx_gpu]') + $:GPU_DECLARE(create='[data_real_gpu, data_cmplx_gpu, data_fltr_cmplx_gpu]') -!> @cond + !> @cond #if defined(__PGI) integer :: fwd_plan_gpu, bwd_plan_gpu #else -!> @endcond + !> @endcond type(c_ptr) :: fwd_plan_gpu, bwd_plan_gpu -!> @cond + !> @cond #endif -!> @endcond + !> @endcond integer, allocatable :: gpu_fft_size(:), iembed(:), oembed(:) - - integer :: istride, ostride, idist, odist, rank + integer :: istride, ostride, idist, odist, rank #endif contains - !> The purpose of this subroutine is to create the fftw plan - !! that will be used in the forward and backward DFTs when - !! applying the Fourier filter in the azimuthal direction. + !> The purpose of this subroutine is to create the fftw plan that will be used in the forward and backward DFTs when applying + !! the Fourier filter in the azimuthal direction. impure subroutine s_initialize_fftw_module - integer :: ierr !< Generic flag used to identify and report GPU errors + integer :: ierr !< Generic flag used to identify and report GPU errors ! Size of input array going into DFT + real_size = p + 1 ! Size of output array coming out of DFT cmplx_size = (p + 1)/2 + 1 @@ -86,14 +77,13 @@ contains #if defined(MFC_GPU) rank = 1; istride = 1; ostride = 1 - allocate (gpu_fft_size(1:rank), iembed(1:rank), oembed(1:rank)) - gpu_fft_size(1) = real_size; + gpu_fft_size(1) = real_size iembed(1) = 0 oembed(1) = 0 - $:GPU_ENTER_DATA(copyin='[real_size,cmplx_size,x_size,sys_size,batch_size,Nfq]') - $:GPU_UPDATE(device='[real_size,cmplx_size,x_size,sys_size,batch_size]') + $:GPU_ENTER_DATA(copyin='[real_size, cmplx_size, x_size, sys_size, batch_size, Nfq]') + $:GPU_UPDATE(device='[real_size, cmplx_size, x_size, sys_size, batch_size]') #else ! Allocate input and output DFT data sizes fftw_real_data = fftw_alloc_real(int(real_size, c_size_t)) @@ -115,32 +105,33 @@ contains @:ALLOCATE(data_fltr_cmplx_gpu(1:cmplx_size*x_size*sys_size)) #if defined(__PGI) - ierr = cufftPlanMany(fwd_plan_gpu, rank, gpu_fft_size, iembed, istride, real_size, oembed, ostride, cmplx_size, CUFFT_D2Z, batch_size) - ierr = cufftPlanMany(bwd_plan_gpu, rank, gpu_fft_size, iembed, istride, cmplx_size, oembed, ostride, real_size, CUFFT_Z2D, batch_size) + ierr = cufftPlanMany(fwd_plan_gpu, rank, gpu_fft_size, iembed, istride, real_size, oembed, ostride, cmplx_size, & + & CUFFT_D2Z, batch_size) + ierr = cufftPlanMany(bwd_plan_gpu, rank, gpu_fft_size, iembed, istride, cmplx_size, oembed, ostride, real_size, & + & CUFFT_Z2D, batch_size) #else - ierr = hipfftPlanMany(fwd_plan_gpu, rank, gpu_fft_size, iembed, istride, real_size, oembed, ostride, cmplx_size, HIPFFT_D2Z, batch_size) - ierr = hipfftPlanMany(bwd_plan_gpu, rank, gpu_fft_size, iembed, istride, cmplx_size, oembed, ostride, real_size, HIPFFT_Z2D, batch_size) + ierr = hipfftPlanMany(fwd_plan_gpu, rank, gpu_fft_size, iembed, istride, real_size, oembed, ostride, cmplx_size, & + & HIPFFT_D2Z, batch_size) + ierr = hipfftPlanMany(bwd_plan_gpu, rank, gpu_fft_size, iembed, istride, cmplx_size, oembed, ostride, real_size, & + & HIPFFT_Z2D, batch_size) #endif - #endif end subroutine s_initialize_fftw_module - !> The purpose of this subroutine is to apply a Fourier low- - !! pass filter to the flow variables in the azimuthal direction - !! to remove the high-frequency content. This alleviates the - !! restrictive CFL condition arising from cells near the axis. - !! @param q_cons_vf Conservative variables + !> The purpose of this subroutine is to apply a Fourier low- pass filter to the flow variables in the azimuthal direction to + !! remove the high-frequency content. This alleviates the restrictive CFL condition arising from cells near the axis. + !! @param q_cons_vf Conservative variables impure subroutine s_apply_fourier_filter(q_cons_vf) type(scalar_field), dimension(sys_size), intent(inout) :: q_cons_vf - integer :: i, j, k, l !< Generic loop iterators - integer :: ierr !< Generic flag used to identify and report GPU errors + integer :: i, j, k, l !< Generic loop iterators + integer :: ierr !< Generic flag used to identify and report GPU errors ! Restrict filter to processors that have cells adjacent to axis + if (bc_y%beg >= 0) return #if defined(MFC_GPU) - $:GPU_PARALLEL_LOOP(collapse=3) do k = 1, sys_size do j = 0, m @@ -176,7 +167,8 @@ contains do k = 1, sys_size do j = 0, m do l = 1, Nfq - data_fltr_cmplx_gpu(l + j*cmplx_size + (k - 1)*cmplx_size*x_size) = data_cmplx_gpu(l + j*cmplx_size + (k - 1)*cmplx_size*x_size) + data_fltr_cmplx_gpu(l + j*cmplx_size + (k - 1)*cmplx_size*x_size) = data_cmplx_gpu(l + j*cmplx_size + (k - 1) & + & *cmplx_size*x_size) end do end do end do @@ -195,7 +187,8 @@ contains do k = 1, sys_size do j = 0, m do l = 0, p - data_real_gpu(l + j*real_size + 1 + (k - 1)*real_size*x_size) = data_real_gpu(l + j*real_size + 1 + (k - 1)*real_size*x_size)/real(real_size, dp) + data_real_gpu(l + j*real_size + 1 + (k - 1)*real_size*x_size) = data_real_gpu(l + j*real_size + 1 + (k - 1) & + & *real_size*x_size)/real(real_size, dp) q_cons_vf(k)%sf(j, 0, l) = data_real_gpu(l + j*real_size + 1 + (k - 1)*real_size*x_size) end do end do @@ -203,7 +196,6 @@ contains $:END_GPU_PARALLEL_LOOP() do i = 1, fourier_rings - $:GPU_PARALLEL_LOOP(collapse=3) do k = 1, sys_size do j = 0, m @@ -240,7 +232,8 @@ contains do k = 1, sys_size do j = 0, m do l = 1, Nfq - data_fltr_cmplx_gpu(l + j*cmplx_size + (k - 1)*cmplx_size*x_size) = data_cmplx_gpu(l + j*cmplx_size + (k - 1)*cmplx_size*x_size) + data_fltr_cmplx_gpu(l + j*cmplx_size + (k - 1)*cmplx_size*x_size) = data_cmplx_gpu(l + j*cmplx_size + (k & + & - 1)*cmplx_size*x_size) end do end do end do @@ -259,25 +252,25 @@ contains do k = 1, sys_size do j = 0, m do l = 0, p - data_real_gpu(l + j*real_size + 1 + (k - 1)*real_size*x_size) = data_real_gpu(l + j*real_size + 1 + (k - 1)*real_size*x_size)/real(real_size, dp) + data_real_gpu(l + j*real_size + 1 + (k - 1)*real_size*x_size) = data_real_gpu(l + j*real_size + 1 + (k & + & - 1)*real_size*x_size)/real(real_size, dp) q_cons_vf(k)%sf(j, i, l) = data_real_gpu(l + j*real_size + 1 + (k - 1)*real_size*x_size) end do end do end do $:END_GPU_PARALLEL_LOOP() end do - #else Nfq = 3 do j = 0, m do k = 1, sys_size data_fltr_cmplx(:) = (0_dp, 0_dp) - data_real(1:p + 1) = q_cons_vf(k)%sf(j, 0, 0:p) + data_real(1:p + 1) = q_cons_vf(k)%sf(j, 0,0:p) call fftw_execute_dft_r2c(fwd_plan, data_real, data_cmplx) data_fltr_cmplx(1:Nfq) = data_cmplx(1:Nfq) call fftw_execute_dft_c2r(bwd_plan, data_fltr_cmplx, data_real) data_real(:) = data_real(:)/real(real_size, dp) - q_cons_vf(k)%sf(j, 0, 0:p) = data_real(1:p + 1) + q_cons_vf(k)%sf(j, 0,0:p) = data_real(1:p + 1) end do end do @@ -287,12 +280,12 @@ contains do j = 0, m do k = 1, sys_size data_fltr_cmplx(:) = (0_dp, 0_dp) - data_real(1:p + 1) = q_cons_vf(k)%sf(j, i, 0:p) + data_real(1:p + 1) = q_cons_vf(k)%sf(j, i,0:p) call fftw_execute_dft_r2c(fwd_plan, data_real, data_cmplx) data_fltr_cmplx(1:Nfq) = data_cmplx(1:Nfq) call fftw_execute_dft_c2r(bwd_plan, data_fltr_cmplx, data_real) data_real(:) = data_real(:)/real(real_size, dp) - q_cons_vf(k)%sf(j, i, 0:p) = data_real(1:p + 1) + q_cons_vf(k)%sf(j, i,0:p) = data_real(1:p + 1) end do end do end do @@ -300,16 +293,14 @@ contains end subroutine s_apply_fourier_filter - !> The purpose of this subroutine is to destroy the fftw plan - !! that will be used in the forward and backward DFTs when - !! applying the Fourier filter in the azimuthal direction. + !> The purpose of this subroutine is to destroy the fftw plan that will be used in the forward and backward DFTs when applying + !! the Fourier filter in the azimuthal direction. impure subroutine s_finalize_fftw_module #if defined(MFC_GPU) - integer :: ierr !< Generic flag used to identify and report GPU errors + integer :: ierr !< Generic flag used to identify and report GPU errors @:DEALLOCATE(data_real_gpu, data_fltr_cmplx_gpu, data_cmplx_gpu) #if defined(__PGI) - ierr = cufftDestroy(fwd_plan_gpu) ierr = cufftDestroy(bwd_plan_gpu) #else @@ -326,4 +317,5 @@ contains #endif end subroutine s_finalize_fftw_module + end module m_fftw diff --git a/src/simulation/m_global_parameters.fpp b/src/simulation/m_global_parameters.fpp index 9d3d018b3b..222d4aa97a 100644 --- a/src/simulation/m_global_parameters.fpp +++ b/src/simulation/m_global_parameters.fpp @@ -9,12 +9,11 @@ module m_global_parameters #ifdef MFC_MPI - use mpi !< Message passing interface (MPI) module + use mpi !< Message passing interface (MPI) module #endif - use m_derived_types !< Definitions of the derived types - - use m_helper_basic !< Functions to compare floating point numbers + use m_derived_types !< Definitions of the derived types + use m_helper_basic !< Functions to compare floating point numbers ! $:USE_GPU_MODULE() @@ -24,13 +23,13 @@ module m_global_parameters real(wp) :: wall_time_avg = 0 ! Logistics - integer :: num_procs !< Number of processors - character(LEN=path_len) :: case_dir !< Case folder location - logical :: run_time_info !< Run-time output flag - integer :: t_step_old !< Existing IC/grid folder + integer :: num_procs !< Number of processors + character(LEN=path_len) :: case_dir !< Case folder location + logical :: run_time_info !< Run-time output flag + integer :: t_step_old !< Existing IC/grid folder ! Computational Domain Parameters - integer :: proc_rank !< Rank of the local processor + integer :: proc_rank !< Rank of the local processor !> @name Number of cells in the x-, y- and z-directions, respectively !> @{ @@ -50,12 +49,12 @@ module m_global_parameters logical :: cyl_coord integer :: grid_geometry !> @} - $:GPU_DECLARE(create='[cyl_coord,grid_geometry]') + $:GPU_DECLARE(create='[cyl_coord, grid_geometry]') !> @name Cell-boundary (CB) locations in the x-, y- and z-directions, respectively !> @{ real(wp), target, allocatable, dimension(:) :: x_cb, y_cb, z_cb - type(bounds_info), dimension(3) :: glb_bounds !< + type(bounds_info), dimension(3) :: glb_bounds !> @} !> @name Cell-center (CC) locations in the x-, y- and z-directions, respectively @@ -68,126 +67,123 @@ module m_global_parameters real(wp), target, allocatable, dimension(:) :: dx, dy, dz !> @} - real(wp) :: dt !< Size of the time-step + real(wp) :: dt !< Size of the time-step - $:GPU_DECLARE(create='[x_cb,y_cb,z_cb,x_cc,y_cc,z_cc,dx,dy,dz,dt,m,n,p,glb_bounds]') + $:GPU_DECLARE(create='[x_cb, y_cb, z_cb, x_cc, y_cc, z_cc, dx, dy, dz, dt, m, n, p, glb_bounds]') - !> @name Starting time-step iteration, stopping time-step iteration and the number - !! of time-step iterations between successive solution backups, respectively + !> @name Starting time-step iteration, stopping time-step iteration and the number of time-step iterations between successive + !! solution backups, respectively !> @{ integer :: t_step_start, t_step_stop, t_step_save !> @} - !> @name Starting time, stopping time, and time between backups, simulation time, - !! and prescribed cfl respectively + !> @name Starting time, stopping time, and time between backups, simulation time, and prescribed cfl respectively !> @{ real(wp) :: t_stop, t_save, cfl_target - integer :: n_start + integer :: n_start !> @} $:GPU_DECLARE(create='[cfl_target]') logical :: cfl_adap_dt, cfl_const_dt, cfl_dt - - integer :: t_step_print !< Number of time-steps between printouts + integer :: t_step_print !< Number of time-steps between printouts ! Simulation Algorithm Parameters - integer :: model_eqns !< Multicomponent flow model + integer :: model_eqns !< Multicomponent flow model #:if MFC_CASE_OPTIMIZATION - integer, parameter :: num_dims = ${num_dims}$ !< Number of spatial dimensions - integer, parameter :: num_vels = ${num_vels}$ !< Number of velocity components (different from num_dims for mhd) + integer, parameter :: num_dims = ${num_dims}$ !< Number of spatial dimensions + integer, parameter :: num_vels = ${num_vels}$ !< Number of velocity components (different from num_dims for mhd) #:else - integer :: num_dims !< Number of spatial dimensions - integer :: num_vels !< Number of velocity components (different from num_dims for mhd) + integer :: num_dims !< Number of spatial dimensions + integer :: num_vels !< Number of velocity components (different from num_dims for mhd) #:endif - logical :: mpp_lim !< Mixture physical parameters (MPP) limits - integer :: time_stepper !< Time-stepper algorithm + logical :: mpp_lim !< Mixture physical parameters (MPP) limits + integer :: time_stepper !< Time-stepper algorithm logical :: prim_vars_wrt #:if MFC_CASE_OPTIMIZATION - integer, parameter :: recon_type = ${recon_type}$ !< Reconstruction type - integer, parameter :: weno_polyn = ${weno_polyn}$ !< Degree of the WENO polynomials (polyn) - integer, parameter :: muscl_polyn = ${muscl_polyn}$ !< Degree of the MUSCL polynomials (polyn) - integer, parameter :: weno_order = ${weno_order}$ !< Order of the WENO reconstruction - integer, parameter :: muscl_order = ${muscl_order}$ !< Order of the MUSCL order - integer, parameter :: weno_num_stencils = ${weno_num_stencils}$ !< Number of stencils for WENO reconstruction (only different from weno_polyn for TENO(>5)) - integer, parameter :: muscl_lim = ${muscl_lim}$ !< MUSCL Limiter - integer, parameter :: num_fluids = ${num_fluids}$ !< number of fluids in the simulation - logical, parameter :: wenojs = (${wenojs}$ /= 0) !< WENO-JS (default) - logical, parameter :: mapped_weno = (${mapped_weno}$ /= 0) !< WENO-M (WENO with mapping of nonlinear weights) - logical, parameter :: wenoz = (${wenoz}$ /= 0) !< WENO-Z - logical, parameter :: teno = (${teno}$ /= 0) !< TENO (Targeted ENO) - real(wp), parameter :: wenoz_q = ${wenoz_q}$ !< Power constant for WENO-Z - logical, parameter :: mhd = (${mhd}$ /= 0) !< Magnetohydrodynamics - logical, parameter :: relativity = (${relativity}$ /= 0) !< Relativity (only for MHD) - integer, parameter :: igr_iter_solver = ${igr_iter_solver}$ !< IGR elliptic solver - integer, parameter :: igr_order = ${igr_order}$ !< Reconstruction order for IGR - logical, parameter :: igr = (${igr}$ /= 0) !< use information geometric regularization - logical, parameter :: igr_pres_lim = (${igr_pres_lim}$ /= 0)!< Limit to positive pressures for IGR - logical, parameter :: viscous = (${viscous}$ /= 0) !< Viscous effects + integer, parameter :: recon_type = ${recon_type}$ !< Reconstruction type + integer, parameter :: weno_polyn = ${weno_polyn}$ !< Degree of the WENO polynomials (polyn) + integer, parameter :: muscl_polyn = ${muscl_polyn}$ !< Degree of the MUSCL polynomials (polyn) + integer, parameter :: weno_order = ${weno_order}$ !< Order of the WENO reconstruction + integer, parameter :: muscl_order = ${muscl_order}$ !< Order of the MUSCL order + !> Number of stencils for WENO reconstruction (only different from weno_polyn for TENO(>5)) + integer, parameter :: weno_num_stencils = ${weno_num_stencils}$ + integer, parameter :: muscl_lim = ${muscl_lim}$ !< MUSCL Limiter + integer, parameter :: num_fluids = ${num_fluids}$ !< number of fluids in the simulation + logical, parameter :: wenojs = (${wenojs}$ /= 0) !< WENO-JS (default) + logical, parameter :: mapped_weno = (${mapped_weno}$ /= 0) !< WENO-M (WENO with mapping of nonlinear weights) + logical, parameter :: wenoz = (${wenoz}$ /= 0) !< WENO-Z + logical, parameter :: teno = (${teno}$ /= 0) !< TENO (Targeted ENO) + real(wp), parameter :: wenoz_q = ${wenoz_q}$ !< Power constant for WENO-Z + logical, parameter :: mhd = (${mhd}$ /= 0) !< Magnetohydrodynamics + logical, parameter :: relativity = (${relativity}$ /= 0) !< Relativity (only for MHD) + integer, parameter :: igr_iter_solver = ${igr_iter_solver}$ !< IGR elliptic solver + integer, parameter :: igr_order = ${igr_order}$ !< Reconstruction order for IGR + logical, parameter :: igr = (${igr}$ /= 0) !< use information geometric regularization + logical, parameter :: igr_pres_lim = (${igr_pres_lim}$ /= 0) !< Limit to positive pressures for IGR + logical, parameter :: viscous = (${viscous}$ /= 0) !< Viscous effects #:else - integer :: recon_type !< Reconstruction Type - integer :: weno_polyn !< Degree of the WENO polynomials (polyn) - integer :: muscl_polyn !< Degree of the MUSCL polynomials (polyn)i - integer :: weno_order !< Order of the WENO reconstruction - integer :: muscl_order !< Order of the MUSCL reconstruction - integer :: weno_num_stencils !< Number of stencils for WENO reconstruction (only different from weno_polyn for TENO(>5)) - integer :: muscl_lim !< MUSCL Limiter - integer :: num_fluids !< number of fluids in the simulation - logical :: wenojs !< WENO-JS (default) - logical :: mapped_weno !< WENO-M (WENO with mapping of nonlinear weights) - logical :: wenoz !< WENO-Z - logical :: teno !< TENO (Targeted ENO) - real(wp) :: wenoz_q !< Power constant for WENO-Z - logical :: mhd !< Magnetohydrodynamics - logical :: relativity !< Relativity (only for MHD) - integer :: igr_iter_solver!< IGR elliptic solver - integer :: igr_order !< Reconstruction order for IGR - logical :: igr !< Use information geometric regularization - logical :: igr_pres_lim !< Limit to positive pressures for IGR - logical :: viscous !< Viscous effects + integer :: recon_type !< Reconstruction Type + integer :: weno_polyn !< Degree of the WENO polynomials (polyn) + integer :: muscl_polyn !< Degree of the MUSCL polynomials (polyn)i + integer :: weno_order !< Order of the WENO reconstruction + integer :: muscl_order !< Order of the MUSCL reconstruction + integer :: weno_num_stencils !< Number of stencils for WENO reconstruction (only different from weno_polyn for TENO(>5)) + integer :: muscl_lim !< MUSCL Limiter + integer :: num_fluids !< number of fluids in the simulation + logical :: wenojs !< WENO-JS (default) + logical :: mapped_weno !< WENO-M (WENO with mapping of nonlinear weights) + logical :: wenoz !< WENO-Z + logical :: teno !< TENO (Targeted ENO) + real(wp) :: wenoz_q !< Power constant for WENO-Z + logical :: mhd !< Magnetohydrodynamics + logical :: relativity !< Relativity (only for MHD) + integer :: igr_iter_solver !< IGR elliptic solver + integer :: igr_order !< Reconstruction order for IGR + logical :: igr !< Use information geometric regularization + logical :: igr_pres_lim !< Limit to positive pressures for IGR + logical :: viscous !< Viscous effects #:endif !> @name Variables for our of core IGR computation on NVIDIA !> @{ - logical :: nv_uvm_out_of_core ! Enable out-of-core storage of q_cons_ts(2) in timestepping (default FALSE) - integer :: nv_uvm_igr_temps_on_gpu ! 0 => jac, jac_rhs, and jac_old on CPU - ! 1 => jac on GPU, jac_rhs and jac_old on CPU - ! 2 => jac and jac_rhs on GPU, jac_old on CPU - ! 3 => jac, jac_rhs, and jac_old on GPU (default) - logical :: nv_uvm_pref_gpu ! Enable explicit gpu memory hints (default FALSE) + logical :: nv_uvm_out_of_core ! Enable out-of-core storage of q_cons_ts(2) in timestepping (default FALSE) + integer :: nv_uvm_igr_temps_on_gpu ! 0 => jac, jac_rhs, and jac_old on CPU + ! 1 => jac on GPU, jac_rhs and jac_old on CPU 2 => jac and jac_rhs on GPU, jac_old on CPU 3 => jac, jac_rhs, and jac_old on GPU + ! (default) + logical :: nv_uvm_pref_gpu ! Enable explicit gpu memory hints (default FALSE) !> @} - real(wp) :: weno_eps !< Binding for the WENO nonlinear weights - real(wp) :: teno_CT !< Smoothness threshold for TENO - logical :: mp_weno !< Monotonicity preserving (MP) WENO - logical :: weno_avg ! Average left/right cell-boundary states - logical :: weno_Re_flux !< WENO reconstruct velocity gradients for viscous stress tensor - integer :: riemann_solver !< Riemann solver algorithm - integer :: low_Mach !< Low Mach number fix to HLLC Riemann solver - integer :: wave_speeds !< Wave speeds estimation method - integer :: avg_state !< Average state evaluation method - logical :: alt_soundspeed !< Alternate mixture sound speed - logical :: null_weights !< Null undesired WENO weights - logical :: mixture_err !< Mixture properties correction - logical :: hypoelasticity !< hypoelasticity modeling - logical :: hyperelasticity !< hyperelasticity modeling - logical :: int_comp !< THINC interface compression - real(wp) :: ic_eps !< THINC Epsilon to compress on surface cells - real(wp) :: ic_beta !< THINC Sharpness Parameter - integer :: hyper_model !< hyperelasticity solver algorithm - logical :: elasticity !< elasticity modeling, true for hyper or hypo - logical, parameter :: chemistry = .${chemistry}$. !< Chemistry modeling - logical :: shear_stress !< Shear stresses - logical :: bulk_stress !< Bulk stresses - logical :: cont_damage !< Continuum damage modeling - logical :: hyper_cleaning !< Hyperbolic cleaning for MHD for divB=0 - integer :: num_igr_iters !< number of iterations for elliptic solve - integer :: num_igr_warm_start_iters !< number of warm start iterations for elliptic solve - real(wp) :: alf_factor !< alpha factor for IGR - - logical :: bodyForces - logical :: bf_x, bf_y, bf_z !< body force toggle in three directions - !< amplitude, frequency, and phase shift sinusoid in each direction + real(wp) :: weno_eps !< Binding for the WENO nonlinear weights + real(wp) :: teno_CT !< Smoothness threshold for TENO + logical :: mp_weno !< Monotonicity preserving (MP) WENO + logical :: weno_avg ! Average left/right cell-boundary states + logical :: weno_Re_flux !< WENO reconstruct velocity gradients for viscous stress tensor + integer :: riemann_solver !< Riemann solver algorithm + integer :: low_Mach !< Low Mach number fix to HLLC Riemann solver + integer :: wave_speeds !< Wave speeds estimation method + integer :: avg_state !< Average state evaluation method + logical :: alt_soundspeed !< Alternate mixture sound speed + logical :: null_weights !< Null undesired WENO weights + logical :: mixture_err !< Mixture properties correction + logical :: hypoelasticity !< hypoelasticity modeling + logical :: hyperelasticity !< hyperelasticity modeling + logical :: int_comp !< THINC interface compression + real(wp) :: ic_eps !< THINC Epsilon to compress on surface cells + real(wp) :: ic_beta !< THINC Sharpness Parameter + integer :: hyper_model !< hyperelasticity solver algorithm + logical :: elasticity !< elasticity modeling, true for hyper or hypo + logical, parameter :: chemistry = .${chemistry}$. !< Chemistry modeling + logical :: shear_stress !< Shear stresses + logical :: bulk_stress !< Bulk stresses + logical :: cont_damage !< Continuum damage modeling + logical :: hyper_cleaning !< Hyperbolic cleaning for MHD for divB=0 + integer :: num_igr_iters !< number of iterations for elliptic solve + integer :: num_igr_warm_start_iters !< number of warm start iterations for elliptic solve + real(wp) :: alf_factor !< alpha factor for IGR + logical :: bodyForces + logical :: bf_x, bf_y, bf_z !< body force toggle in three directions + !> amplitude, frequency, and phase shift sinusoid in each direction #:for dir in {'x', 'y', 'z'} #:for param in {'k','w','p','g'} real(wp) :: ${param}$_${dir}$ @@ -200,27 +196,27 @@ module m_global_parameters integer :: cpu_start, cpu_end, cpu_rate #:if not MFC_CASE_OPTIMIZATION - $:GPU_DECLARE(create='[num_dims,num_vels,weno_polyn,weno_order]') - $:GPU_DECLARE(create='[weno_num_stencils,num_fluids,wenojs]') - $:GPU_DECLARE(create='[mapped_weno, wenoz,teno,wenoz_q,mhd,relativity]') - $:GPU_DECLARE(create='[igr_iter_solver,igr_order,viscous,igr_pres_lim,igr]') + $:GPU_DECLARE(create='[num_dims, num_vels, weno_polyn, weno_order]') + $:GPU_DECLARE(create='[weno_num_stencils, num_fluids, wenojs]') + $:GPU_DECLARE(create='[mapped_weno, wenoz, teno, wenoz_q, mhd, relativity]') + $:GPU_DECLARE(create='[igr_iter_solver, igr_order, viscous, igr_pres_lim, igr]') $:GPU_DECLARE(create='[recon_type, muscl_order, muscl_polyn, muscl_lim]') #:endif - $:GPU_DECLARE(create='[mpp_lim,model_eqns,mixture_err,alt_soundspeed]') - $:GPU_DECLARE(create='[avg_state,mp_weno,weno_eps,teno_CT,hypoelasticity]') - $:GPU_DECLARE(create='[hyperelasticity,hyper_model,elasticity,low_Mach]') - $:GPU_DECLARE(create='[shear_stress,bulk_stress,cont_damage,hyper_cleaning]') + $:GPU_DECLARE(create='[mpp_lim, model_eqns, mixture_err, alt_soundspeed]') + $:GPU_DECLARE(create='[avg_state, mp_weno, weno_eps, teno_CT, hypoelasticity]') + $:GPU_DECLARE(create='[hyperelasticity, hyper_model, elasticity, low_Mach]') + $:GPU_DECLARE(create='[shear_stress, bulk_stress, cont_damage, hyper_cleaning]') - logical :: relax !< activate phase change - integer :: relax_model !< Relaxation model - real(wp) :: palpha_eps !< trigger parameter for the p relaxation procedure, phase change model - real(wp) :: ptgalpha_eps !< trigger parameter for the pTg relaxation procedure, phase change model + logical :: relax !< activate phase change + integer :: relax_model !< Relaxation model + real(wp) :: palpha_eps !< trigger parameter for the p relaxation procedure, phase change model + real(wp) :: ptgalpha_eps !< trigger parameter for the pTg relaxation procedure, phase change model - $:GPU_DECLARE(create='[relax, relax_model, palpha_eps,ptgalpha_eps]') + $:GPU_DECLARE(create='[relax, relax_model, palpha_eps, ptgalpha_eps]') - integer :: num_bc_patches - logical :: bc_io + integer :: num_bc_patches + logical :: bc_io logical, dimension(3) :: periodic_bc !> @name Boundary conditions (BC) in the x-, y- and z-directions, respectively @@ -235,238 +231,216 @@ module m_global_parameters $:GPU_DECLARE(create='[bc_x, bc_y, bc_z]') #endif - logical :: parallel_io !< Format of the data files - logical :: file_per_process !< shared file or not when using parallel io - integer :: precision !< Precision of output files - logical :: down_sample !< down sample the output files + logical :: parallel_io !< Format of the data files + logical :: file_per_process !< shared file or not when using parallel io + integer :: precision !< Precision of output files + logical :: down_sample !< down sample the output files $:GPU_DECLARE(create='[down_sample]') - integer, allocatable, dimension(:) :: proc_coords !< - !! Processor coordinates in MPI_CART_COMM - + integer, allocatable, dimension(:) :: proc_coords !< Processor coordinates in MPI_CART_COMM type(bounds_info), allocatable, dimension(:) :: pcomm_coords $:GPU_DECLARE(create='[pcomm_coords]') !! Coordinates for EL particle transfer - type(int_bounds_info), dimension(3) :: nidx !< Indices for neighboring processors - - integer, allocatable, dimension(:, :, :) :: neighbor_ranks + type(int_bounds_info), dimension(3) :: nidx !< Indices for neighboring processors + integer, allocatable, dimension(:,:,:) :: neighbor_ranks !! Neighbor ranks - integer, allocatable, dimension(:) :: start_idx !< - !! Starting cell-center index of local processor in global grid - - type(mpi_io_var), public :: MPI_IO_DATA - type(mpi_io_ib_var), public :: MPI_IO_IB_DATA - type(mpi_io_airfoil_ib_var), public :: MPI_IO_airfoil_IB_DATA - type(mpi_io_levelset_var), public :: MPI_IO_levelset_DATA - type(mpi_io_levelset_norm_var), public :: MPI_IO_levelsetnorm_DATA - real(wp), allocatable, dimension(:, :), public :: MPI_IO_DATA_lag_bubbles + integer, allocatable, dimension(:) :: start_idx !< Starting cell-center index of local processor in global grid + type(mpi_io_var), public :: MPI_IO_DATA + type(mpi_io_ib_var), public :: MPI_IO_IB_DATA + type(mpi_io_airfoil_ib_var), public :: MPI_IO_airfoil_IB_DATA + type(mpi_io_levelset_var), public :: MPI_IO_levelset_DATA + type(mpi_io_levelset_norm_var), public :: MPI_IO_levelsetnorm_DATA + real(wp), allocatable, dimension(:,:), public :: MPI_IO_DATA_lag_bubbles !> @name MPI info for parallel IO with Lustre file systems !> @{ character(LEN=name_len) :: mpiiofs - integer :: mpi_info_int + integer :: mpi_info_int !> @} - !> @name Annotations of the structure of the state and flux vectors in terms of the - !! size and the configuration of the system of equations to which they belong + !> @name Annotations of the structure of the state and flux vectors in terms of the size and the configuration of the system of + !! equations to which they belong !> @{ - integer :: sys_size !< Number of unknowns in system of eqns. - type(int_bounds_info) :: cont_idx !< Indexes of first & last continuity eqns. - type(int_bounds_info) :: mom_idx !< Indexes of first & last momentum eqns. - integer :: E_idx !< Index of energy equation - integer :: n_idx !< Index of number density - type(int_bounds_info) :: adv_idx !< Indexes of first & last advection eqns. - type(int_bounds_info) :: internalEnergies_idx !< Indexes of first & last internal energy eqns. - type(bub_bounds_info) :: bub_idx !< Indexes of first & last bubble variable eqns. - integer :: alf_idx !< Index of void fraction - integer :: gamma_idx !< Index of specific heat ratio func. eqn. - integer :: pi_inf_idx !< Index of liquid stiffness func. eqn. - type(int_bounds_info) :: B_idx !< Indexes of first and last magnetic field eqns. - type(int_bounds_info) :: stress_idx !< Indexes of first and last shear stress eqns. - type(int_bounds_info) :: xi_idx !< Indexes of first and last reference map eqns. - integer :: b_size !< Number of elements in the symmetric b tensor, plus one - integer :: tensor_size !< Number of elements in the full tensor plus one - type(int_bounds_info) :: species_idx !< Indexes of first & last concentration eqns. - integer :: c_idx !< Index of color function - integer :: damage_idx !< Index of damage state variable (D) for continuum damage model - integer :: psi_idx !< Index of hyperbolic cleaning state variable for MHD + integer :: sys_size !< Number of unknowns in system of eqns. + type(int_bounds_info) :: cont_idx !< Indexes of first & last continuity eqns. + type(int_bounds_info) :: mom_idx !< Indexes of first & last momentum eqns. + integer :: E_idx !< Index of energy equation + integer :: n_idx !< Index of number density + type(int_bounds_info) :: adv_idx !< Indexes of first & last advection eqns. + type(int_bounds_info) :: internalEnergies_idx !< Indexes of first & last internal energy eqns. + type(bub_bounds_info) :: bub_idx !< Indexes of first & last bubble variable eqns. + integer :: alf_idx !< Index of void fraction + integer :: gamma_idx !< Index of specific heat ratio func. eqn. + integer :: pi_inf_idx !< Index of liquid stiffness func. eqn. + type(int_bounds_info) :: B_idx !< Indexes of first and last magnetic field eqns. + type(int_bounds_info) :: stress_idx !< Indexes of first and last shear stress eqns. + type(int_bounds_info) :: xi_idx !< Indexes of first and last reference map eqns. + integer :: b_size !< Number of elements in the symmetric b tensor, plus one + integer :: tensor_size !< Number of elements in the full tensor plus one + type(int_bounds_info) :: species_idx !< Indexes of first & last concentration eqns. + integer :: c_idx !< Index of color function + integer :: damage_idx !< Index of damage state variable (D) for continuum damage model + integer :: psi_idx !< Index of hyperbolic cleaning state variable for MHD !> @} - $:GPU_DECLARE(create='[sys_size,E_idx,n_idx,bub_idx,alf_idx,gamma_idx]') - $:GPU_DECLARE(create='[pi_inf_idx,B_idx,stress_idx,xi_idx,b_size]') - $:GPU_DECLARE(create='[tensor_size,species_idx,c_idx]') + $:GPU_DECLARE(create='[sys_size, E_idx, n_idx, bub_idx, alf_idx, gamma_idx]') + $:GPU_DECLARE(create='[pi_inf_idx, B_idx, stress_idx, xi_idx, b_size]') + $:GPU_DECLARE(create='[tensor_size, species_idx, c_idx]') - ! Cell Indices for the (local) interior points (O-m, O-n, 0-p). - ! Stands for "InDices With INTerior". + ! Cell Indices for the (local) interior points (O-m, O-n, 0-p). Stands for "InDices With INTerior". type(int_bounds_info) :: idwint(1:3) $:GPU_DECLARE(create='[idwint]') - ! Cell Indices for the entire (local) domain. In simulation and post_process, - ! this includes the buffer region. idwbuff and idwint are the same otherwise. - ! Stands for "InDices With BUFFer". + ! Cell Indices for the entire (local) domain. In simulation and post_process, this includes the buffer region. idwbuff and + ! idwint are the same otherwise. Stands for "InDices With BUFFer". type(int_bounds_info) :: idwbuff(1:3) $:GPU_DECLARE(create='[idwbuff]') - !> @name The number of fluids, along with their identifying indexes, respectively, - !! for which viscous effects, e.g. the shear and/or the volume Reynolds (Re) - !! numbers, will be non-negligible. + !> @name The number of fluids, along with their identifying indexes, respectively, for which viscous effects, e.g. the shear + !! and/or the volume Reynolds (Re) numbers, will be non-negligible. !> @{ - integer, dimension(2) :: Re_size - integer :: Re_size_max - integer, allocatable, dimension(:, :) :: Re_idx + integer, dimension(2) :: Re_size + integer :: Re_size_max + integer, allocatable, dimension(:,:) :: Re_idx !> @} - $:GPU_DECLARE(create='[Re_size,Re_size_max,Re_idx]') + $:GPU_DECLARE(create='[Re_size, Re_size_max, Re_idx]') - ! The WENO average (WA) flag regulates whether the calculation of any cell- - ! average spatial derivatives is carried out in each cell by utilizing the - ! arithmetic mean of the left and right, WENO-reconstructed, cell-boundary - ! values or simply, the unaltered left and right, WENO-reconstructed, cell- - ! boundary values. + ! The WENO average (WA) flag regulates whether the calculation of any cell- average spatial derivatives is carried out in each + ! cell by utilizing the arithmetic mean of the left and right, WENO-reconstructed, cell-boundary values or simply, the unaltered + ! left and right, WENO-reconstructed, cell- boundary values. !> @{ real(wp) :: wa_flg !> @} $:GPU_DECLARE(create='[wa_flg]') - !> @name The coordinate direction indexes and flags (flg), respectively, for which - !! the configurations will be determined with respect to a working direction - !! and that will be used to isolate the contributions, in that direction, in - !! the dimensionally split system of equations. + !> @name The coordinate direction indexes and flags (flg), respectively, for which the configurations will be determined with + !! respect to a working direction and that will be used to isolate the contributions, in that direction, in the dimensionally + !! split system of equations. !> @{ - integer, dimension(3) :: dir_idx + integer, dimension(3) :: dir_idx real(wp), dimension(3) :: dir_flg - integer, dimension(3) :: dir_idx_tau !!used for hypoelasticity=true + integer, dimension(3) :: dir_idx_tau !!used for hypoelasticity=true !> @} - $:GPU_DECLARE(create='[dir_idx,dir_flg,dir_idx_tau]') + $:GPU_DECLARE(create='[dir_idx, dir_flg, dir_idx_tau]') - integer :: buff_size !< - !! The number of cells that are necessary to be able to store enough boundary - !! conditions data to march the solution in the physical computational domain - !! to the next time-step. + !> The number of cells that are necessary to be able to store enough boundary conditions data to march the solution in the + !! physical computational domain to the next time-step. + integer :: buff_size $:GPU_DECLARE(create='[buff_size]') - integer :: shear_num !! Number of shear stress components - integer, dimension(3) :: shear_indices !< - !! Indices of the stress components that represent shear stress - integer :: shear_BC_flip_num !< - !! Number of shear stress components to reflect for boundary conditions - integer, dimension(3, 2) :: shear_BC_flip_indices !< - !! Indices of shear stress components to reflect for boundary conditions. - !! Size: (1:3, 1:shear_BC_flip_num) for (x/y/z, [indices]) + integer :: shear_num !! Number of shear stress components + integer, dimension(3) :: shear_indices !< Indices of the stress components that represent shear stress + integer :: shear_BC_flip_num !< Number of shear stress components to reflect for boundary conditions + !> Indices of shear stress components to reflect for boundary conditions. Size: (1:3, 1:shear_BC_flip_num) for (x/y/z, + !! [indices]) + integer, dimension(3, 2) :: shear_BC_flip_indices - $:GPU_DECLARE(create='[shear_num,shear_indices,shear_BC_flip_num,shear_BC_flip_indices]') + $:GPU_DECLARE(create='[shear_num, shear_indices, shear_BC_flip_num, shear_BC_flip_indices]') ! END: Simulation Algorithm Parameters ! Fluids Physical Parameters - type(physical_parameters), dimension(num_fluids_max) :: fluid_pp !< - !! Database of the physical parameters of each of the fluids that is present - !! in the flow. These include the stiffened gas equation of state parameters, - !! and the Reynolds numbers. + !> Database of the physical parameters of each of the fluids that is present in the flow. These include the stiffened gas + !! equation of state parameters, and the Reynolds numbers. + type(physical_parameters), dimension(num_fluids_max) :: fluid_pp ! Subgrid Bubble Parameters type(subgrid_bubble_physical_parameters) :: bub_pp - integer :: fd_order !< - !! The order of the finite-difference (fd) approximations of the first-order - !! derivatives that need to be evaluated when the CoM or flow probe data - !! files are to be written at each time step - - integer :: fd_number !< - !! The finite-difference number is given by MAX(1, fd_order/2). Essentially, - !! it is a measure of the half-size of the finite-difference stencil for the - !! selected order of accuracy. - $:GPU_DECLARE(create='[fd_order,fd_number]') - - logical :: probe_wrt - logical :: integral_wrt - integer :: num_probes - integer :: num_integrals - type(vec3_dt), dimension(num_probes_max) :: probe + !> The order of the finite-difference (fd) approximations of the first-order derivatives that need to be evaluated when the CoM + !! or flow probe data files are to be written at each time step + integer :: fd_order + + !> The finite-difference number is given by MAX(1, fd_order/2). Essentially, it is a measure of the half-size of the + !! finite-difference stencil for the selected order of accuracy. + integer :: fd_number + $:GPU_DECLARE(create='[fd_order, fd_number]') + + logical :: probe_wrt + logical :: integral_wrt + integer :: num_probes + integer :: num_integrals + type(vec3_dt), dimension(num_probes_max) :: probe type(integral_parameters), dimension(num_probes_max) :: integral !> @name Reference density and pressure for Tait EOS !> @{ real(wp) :: rhoref, pref !> @} - $:GPU_DECLARE(create='[rhoref,pref]') + $:GPU_DECLARE(create='[rhoref, pref]') !> @name Immersed Boundaries !> @{ - logical :: ib - integer :: num_ibs - logical :: ib_state_wrt - + logical :: ib + integer :: num_ibs + logical :: ib_state_wrt type(ib_patch_parameters), dimension(num_patches_max) :: patch_ib - type(vec3_dt), allocatable, dimension(:) :: airfoil_grid_u, airfoil_grid_l - integer :: Np - !! Database of the immersed boundary patch parameters for each of the - !! patches employed in the configuration of the initial condition. Note that - !! the maximum allowable number of patches, num_patches_max, may be changed - !! in the module m_derived_types.f90. - - $:GPU_DECLARE(create='[ib,num_ibs,patch_ib,Np,airfoil_grid_u,airfoil_grid_l]') + type(vec3_dt), allocatable, dimension(:) :: airfoil_grid_u, airfoil_grid_l + integer :: Np + !! Database of the immersed boundary patch parameters for each of the patches employed in the configuration of the initial + !! condition. Note that the maximum allowable number of patches, num_patches_max, may be changed in the module + !! m_derived_types.f90. + + $:GPU_DECLARE(create='[ib, num_ibs, patch_ib, Np, airfoil_grid_u, airfoil_grid_l]') !> @} !> @name Bubble modeling !> @{ #:if MFC_CASE_OPTIMIZATION - integer, parameter :: nb = ${nb}$ !< Number of eq. bubble sizes + integer, parameter :: nb = ${nb}$ !< Number of eq. bubble sizes #:else - integer :: nb !< Number of eq. bubble sizes + integer :: nb !< Number of eq. bubble sizes #:endif - real(wp) :: Eu !< Euler number - real(wp) :: Ca !< Cavitation number - real(wp) :: Web !< Weber number - real(wp) :: Re_inv !< Inverse Reynolds number - $:GPU_DECLARE(create='[Eu,Ca,Web,Re_inv]') - - real(wp), dimension(:), allocatable :: weight !< Simpson quadrature weights - real(wp), dimension(:), allocatable :: R0 !< Bubble sizes - $:GPU_DECLARE(create='[weight,R0]') - - logical :: bubbles_euler !< Bubbles euler on/off - logical :: polytropic !< Polytropic switch - logical :: polydisperse !< Polydisperse bubbles - $:GPU_DECLARE(create='[bubbles_euler,polytropic,polydisperse]') - - logical :: adv_n !< Solve the number density equation and compute alpha from number density - logical :: adap_dt !< Adaptive step size control - real(wp) :: adap_dt_tol !< Tolerance to control adaptive step size - integer :: adap_dt_max_iters !< Maximum number of iterations - $:GPU_DECLARE(create='[adv_n,adap_dt,adap_dt_tol,adap_dt_max_iters]') - - integer :: bubble_model !< Gilmore or Keller--Miksis bubble model - integer :: thermal !< Thermal behavior. 1 = adiabatic, 2 = isotherm, 3 = transfer - $:GPU_DECLARE(create='[bubble_model,thermal]') - - real(wp), allocatable, dimension(:, :, :) :: ptil !< Pressure modification - - real(wp) :: poly_sigma !< log normal sigma for polydisperse PDF + real(wp) :: Eu !< Euler number + real(wp) :: Ca !< Cavitation number + real(wp) :: Web !< Weber number + real(wp) :: Re_inv !< Inverse Reynolds number + $:GPU_DECLARE(create='[Eu, Ca, Web, Re_inv]') + + real(wp), dimension(:), allocatable :: weight !< Simpson quadrature weights + real(wp), dimension(:), allocatable :: R0 !< Bubble sizes + $:GPU_DECLARE(create='[weight, R0]') + + logical :: bubbles_euler !< Bubbles euler on/off + logical :: polytropic !< Polytropic switch + logical :: polydisperse !< Polydisperse bubbles + $:GPU_DECLARE(create='[bubbles_euler, polytropic, polydisperse]') + + logical :: adv_n !< Solve the number density equation and compute alpha from number density + logical :: adap_dt !< Adaptive step size control + real(wp) :: adap_dt_tol !< Tolerance to control adaptive step size + integer :: adap_dt_max_iters !< Maximum number of iterations + $:GPU_DECLARE(create='[adv_n, adap_dt, adap_dt_tol, adap_dt_max_iters]') + + integer :: bubble_model !< Gilmore or Keller--Miksis bubble model + integer :: thermal !< Thermal behavior. 1 = adiabatic, 2 = isotherm, 3 = transfer + $:GPU_DECLARE(create='[bubble_model, thermal]') + + real(wp), allocatable, dimension(:,:,:) :: ptil !< Pressure modification + real(wp) :: poly_sigma !< log normal sigma for polydisperse PDF $:GPU_DECLARE(create='[ptil, poly_sigma]') - logical :: qbmm !< Quadrature moment method - integer, parameter :: nmom = 6 !< Number of carried moments per R0 location - integer :: nmomsp !< Number of moments required by ensemble-averaging - integer :: nmomtot !< Total number of carried moments moments/transport equations - - real(wp) :: pi_fac !< Factor for artificial pi_inf - $:GPU_DECLARE(create='[qbmm, nmomsp,nmomtot,pi_fac]') + logical :: qbmm !< Quadrature moment method + integer, parameter :: nmom = 6 !< Number of carried moments per R0 location + integer :: nmomsp !< Number of moments required by ensemble-averaging + integer :: nmomtot !< Total number of carried moments moments/transport equations + real(wp) :: pi_fac !< Factor for artificial pi_inf + $:GPU_DECLARE(create='[qbmm, nmomsp, nmomtot, pi_fac]') #:if not MFC_CASE_OPTIMIZATION $:GPU_DECLARE(create='[nb]') #:endif - type(scalar_field), allocatable, dimension(:) :: mom_sp - type(scalar_field), allocatable, dimension(:, :, :) :: mom_3d - $:GPU_DECLARE(create='[mom_sp,mom_3d]') - + type(scalar_field), allocatable, dimension(:) :: mom_sp + type(scalar_field), allocatable, dimension(:,:,:) :: mom_3d + $:GPU_DECLARE(create='[mom_sp, mom_3d]') !> @} type(chemistry_parameters) :: chem_params @@ -475,36 +449,33 @@ module m_global_parameters !> @name Physical bubble parameters (see Ando 2010, Preston 2007) !> @{ real(wp) :: phi_vg, phi_gv, Pe_c, Tw, k_vl, k_gl - $:GPU_DECLARE(create='[phi_vg,phi_gv,Pe_c,Tw,k_vl,k_gl]') + $:GPU_DECLARE(create='[phi_vg, phi_gv, Pe_c, Tw, k_vl, k_gl]') real(wp), dimension(:), allocatable :: pb0, mass_g0, mass_v0, Pe_T, k_v, k_g real(wp), dimension(:), allocatable :: Re_trans_T, Re_trans_c, Im_trans_T, Im_trans_c, omegaN - $:GPU_DECLARE(create='[pb0,mass_g0,mass_v0,Pe_T,k_v,k_g]') - $:GPU_DECLARE(create='[Re_trans_T,Re_trans_c,Im_trans_T,Im_trans_c,omegaN]') + $:GPU_DECLARE(create='[pb0, mass_g0, mass_v0, Pe_T, k_v, k_g]') + $:GPU_DECLARE(create='[Re_trans_T, Re_trans_c, Im_trans_T, Im_trans_c, omegaN]') real(wp) :: gam, gam_m - $:GPU_DECLARE(create='[gam,gam_m]') + $:GPU_DECLARE(create='[gam, gam_m]') - real(wp) :: R0ref, p0ref, rho0ref, T0ref, ss, pv, vd, mu_l, mu_v, mu_g, & - gam_v, gam_g, M_v, M_g, cp_v, cp_g, R_v, R_g - $:GPU_DECLARE(create='[R0ref, p0ref, rho0ref, T0ref, ss, pv, vd, mu_l, mu_v, mu_g, & - gam_v, gam_g, M_v, M_g, cp_v, cp_g, R_v, R_g]') + real(wp) :: R0ref, p0ref, rho0ref, T0ref, ss, pv, vd, mu_l, mu_v, mu_g, gam_v, gam_g, M_v, M_g, cp_v, cp_g, R_v, R_g + $:GPU_DECLARE(create='[R0ref, p0ref, rho0ref, T0ref, ss, pv, vd, mu_l, mu_v, mu_g, gam_v, gam_g, M_v, M_g, cp_v, cp_g, R_v, R_g]') !> @} !> @name Acoustic acoustic_source parameters !> @{ - logical :: acoustic_source !< Acoustic source switch - type(acoustic_parameters), dimension(num_probes_max) :: acoustic !< Acoustic source parameters - integer :: num_source !< Number of acoustic sources + logical :: acoustic_source !< Acoustic source switch + type(acoustic_parameters), dimension(num_probes_max) :: acoustic !< Acoustic source parameters + integer :: num_source !< Number of acoustic sources !> @} - $:GPU_DECLARE(create='[acoustic_source,acoustic,num_source]') + $:GPU_DECLARE(create='[acoustic_source, acoustic, num_source]') !> @name Surface tension parameters !> @{ - real(wp) :: sigma - logical :: surface_tension - $:GPU_DECLARE(create='[sigma,surface_tension]') + logical :: surface_tension + $:GPU_DECLARE(create='[sigma, surface_tension]') !> @} integer :: momxb, momxe @@ -515,70 +486,69 @@ module m_global_parameters integer :: strxb, strxe integer :: chemxb, chemxe integer :: xibeg, xiend - $:GPU_DECLARE(create='[momxb,momxe,advxb,advxe,contxb,contxe]') - $:GPU_DECLARE(create='[intxb,intxe, bubxb,bubxe]') - $:GPU_DECLARE(create='[strxb,strxe,chemxb,chemxe]') - $:GPU_DECLARE(create='[xibeg,xiend]') + $:GPU_DECLARE(create='[momxb, momxe, advxb, advxe, contxb, contxe]') + $:GPU_DECLARE(create='[intxb, intxe, bubxb, bubxe]') + $:GPU_DECLARE(create='[strxb, strxe, chemxb, chemxe]') + $:GPU_DECLARE(create='[xibeg, xiend]') real(wp), allocatable, dimension(:) :: gammas, gs_min, pi_infs, ps_inf, cvs, qvs, qvps - $:GPU_DECLARE(create='[gammas,gs_min,pi_infs,ps_inf,cvs,qvs,qvps]') - - real(wp) :: mytime !< Current simulation time - real(wp) :: finaltime !< Final simulation time - - logical :: rdma_mpi + $:GPU_DECLARE(create='[gammas, gs_min, pi_infs, ps_inf, cvs, qvs, qvps]') + real(wp) :: mytime !< Current simulation time + real(wp) :: finaltime !< Final simulation time + logical :: rdma_mpi type(pres_field), allocatable, dimension(:) :: pb_ts - type(pres_field), allocatable, dimension(:) :: mv_ts - $:GPU_DECLARE(create='[pb_ts,mv_ts]') + $:GPU_DECLARE(create='[pb_ts, mv_ts]') !> @name lagrangian subgrid bubble parameters !> @{! - logical :: bubbles_lagrange !< Lagrangian subgrid bubble model switch - type(bubbles_lagrange_parameters) :: lag_params !< Lagrange bubbles' parameters - integer :: n_el_bubs_loc, n_el_bubs_glb !< Number of Lagrangian bubbles (local and global) - logical :: moving_lag_bubbles - logical :: lag_pressure_force - logical :: lag_gravity_force - integer :: lag_vel_model, lag_drag_model - $:GPU_DECLARE(create='[bubbles_lagrange,lag_params,n_el_bubs_loc,n_el_bubs_glb]') + logical :: bubbles_lagrange !< Lagrangian subgrid bubble model switch + type(bubbles_lagrange_parameters) :: lag_params !< Lagrange bubbles' parameters + integer :: n_el_bubs_loc, n_el_bubs_glb !< Number of Lagrangian bubbles (local and global) + logical :: moving_lag_bubbles + logical :: lag_pressure_force + logical :: lag_gravity_force + integer :: lag_vel_model, lag_drag_model + $:GPU_DECLARE(create='[bubbles_lagrange, lag_params, n_el_bubs_loc, n_el_bubs_glb]') $:GPU_DECLARE(create='[moving_lag_bubbles, lag_vel_model, lag_drag_model]') - $:GPU_DECLARE(create='[lag_pressure_force,lag_gravity_force]') + $:GPU_DECLARE(create='[lag_pressure_force, lag_gravity_force]') !> @} - real(wp) :: Bx0 !< Constant magnetic field in the x-direction (1D) + real(wp) :: Bx0 !< Constant magnetic field in the x-direction (1D) $:GPU_DECLARE(create='[Bx0]') logical :: fft_wrt - logical :: dummy !< AMDFlang workaround: keep a dummy logical to avoid a compiler case-optimization bug when a parameter+GPU-kernel conditional is false + !> AMDFlang workaround: keep a dummy logical to avoid a compiler case-optimization bug when a parameter+GPU-kernel conditional + !! is false + logical :: dummy !> @name Continuum damage model parameters !> @{! - real(wp) :: tau_star !< Stress threshold for continuum damage modeling - real(wp) :: cont_damage_s !< Exponent s for continuum damage modeling - real(wp) :: alpha_bar !< Damage rate factor for continuum damage modeling - $:GPU_DECLARE(create='[tau_star,cont_damage_s,alpha_bar]') + real(wp) :: tau_star !< Stress threshold for continuum damage modeling + real(wp) :: cont_damage_s !< Exponent s for continuum damage modeling + real(wp) :: alpha_bar !< Damage rate factor for continuum damage modeling + $:GPU_DECLARE(create='[tau_star, cont_damage_s, alpha_bar]') !> @} !> @name MHD Hyperbolic cleaning parameters !> @{! - real(wp) :: hyper_cleaning_speed !< Hyperbolic cleaning wave speed (c_h) - real(wp) :: hyper_cleaning_tau !< Hyperbolic cleaning tau + real(wp) :: hyper_cleaning_speed !< Hyperbolic cleaning wave speed (c_h) + real(wp) :: hyper_cleaning_tau !< Hyperbolic cleaning tau $:GPU_DECLARE(create='[hyper_cleaning_speed, hyper_cleaning_tau]') !> @} contains - !> Assigns default values to the user inputs before reading - !! them in. This enables for an easier consistency check of - !! these parameters once they are read from the input file. + !> Assigns default values to the user inputs before reading them in. This enables for an easier consistency check of these + !! parameters once they are read from the input file. impure subroutine s_assign_default_values_to_user_inputs - integer :: i, j !< Generic loop iterator + integer :: i, j !< Generic loop iterator ! Logistics + case_dir = '.' run_time_info = .false. t_step_old = dflt_int @@ -607,7 +577,7 @@ contains ! NVIDIA UVM options nv_uvm_out_of_core = .false. - nv_uvm_igr_temps_on_gpu = 3 ! => jac, jac_rhs, and jac_old on GPU (default) + nv_uvm_igr_temps_on_gpu = 3 ! => jac, jac_rhs, and jac_old on GPU (default) nv_uvm_pref_gpu = .false. ! Simulation algorithm parameters @@ -714,8 +684,8 @@ contains bub_pp%gam_g = dflt_real; gam_g = dflt_real bub_pp%M_v = dflt_real; M_v = dflt_real bub_pp%M_g = dflt_real; M_g = dflt_real - bub_pp%k_v = dflt_real; - bub_pp%k_g = dflt_real; + bub_pp%k_v = dflt_real + bub_pp%k_g = dflt_real bub_pp%cp_v = dflt_real; cp_v = dflt_real bub_pp%cp_g = dflt_real; cp_g = dflt_real bub_pp%R_v = dflt_real; R_v = dflt_real @@ -773,7 +743,7 @@ contains bodyForces = .false. bf_x = .false.; bf_y = .false.; bf_z = .false. - !< amplitude, frequency, and phase shift sinusoid in each direction + !> amplitude, frequency, and phase shift sinusoid in each direction #:for dir in {'x', 'y', 'z'} #:for param in {'k','w','p','g'} ${param}$_${dir}$ = dflt_real @@ -922,9 +892,8 @@ contains end subroutine s_assign_default_values_to_user_inputs - !> The computation of parameters, the allocation of memory, - !! the association of pointers and/or the execution of any - !! other procedures that are necessary to setup the module. + !> The computation of parameters, the allocation of memory, the association of pointers and/or the execution of any other + !! procedures that are necessary to setup the module. impure subroutine s_initialize_global_parameters_module integer :: i, j, k @@ -939,30 +908,26 @@ contains else weno_num_stencils = weno_polyn end if - elseif (recon_type == MUSCL_TYPE) then + else if (recon_type == MUSCL_TYPE) then muscl_polyn = muscl_order end if $:GPU_UPDATE(device='[weno_polyn, muscl_polyn]') $:GPU_UPDATE(device='[weno_num_stencils]') $:GPU_UPDATE(device='[nb]') - $:GPU_UPDATE(device='[num_dims,num_vels,num_fluids]') - $:GPU_UPDATE(device='[igr,igr_order,igr_iter_solver]') + $:GPU_UPDATE(device='[num_dims, num_vels, num_fluids]') + $:GPU_UPDATE(device='[igr, igr_order, igr_iter_solver]') #:endif - ! Initializing the number of fluids for which viscous effects will - ! be non-negligible, the number of distinctive material interfaces - ! for which surface tension will be important and also, the number - ! of fluids for which the physical and geometric curvatures of the - ! interfaces will be computed + ! Initializing the number of fluids for which viscous effects will be non-negligible, the number of distinctive material + ! interfaces for which surface tension will be important and also, the number of fluids for which the physical and geometric + ! curvatures of the interfaces will be computed Re_size = 0 Re_size_max = 0 ! Gamma/Pi_inf Model if (model_eqns == 1) then - - ! Annotating structure of the state and flux vectors belonging - ! to the system of equations defined by the selected number of - ! spatial dimensions and the gamma/pi_inf model + ! Annotating structure of the state and flux vectors belonging to the system of equations defined by the selected number + ! of spatial dimensions and the gamma/pi_inf model cont_idx%beg = 1 cont_idx%end = cont_idx%beg mom_idx%beg = cont_idx%end + 1 @@ -976,10 +941,8 @@ contains ! Volume Fraction Model else - - ! Annotating structure of the state and flux vectors belonging - ! to the system of equations defined by the selected number of - ! spatial dimensions and the volume fraction model + ! Annotating structure of the state and flux vectors belonging to the system of equations defined by the selected number + ! of spatial dimensions and the volume fraction model if (model_eqns == 2) then cont_idx%beg = 1 cont_idx%end = num_fluids @@ -988,17 +951,14 @@ contains E_idx = mom_idx%end + 1 if (igr) then - ! Volume fractions are stored in the indices immediately following - ! the energy equation. IGR tracks a total of (N-1) volume fractions - ! for N fluids, hence the "-1" in adv_idx%end. If num_fluids = 1 - ! then adv_idx%end < adv_idx%beg, which skips all loops over the - ! volume fractions since there is no volume fraction to track - adv_idx%beg = E_idx + 1 ! Alpha for fluid 1 + ! Volume fractions are stored in the indices immediately following the energy equation. IGR tracks a total of + ! (N-1) volume fractions for N fluids, hence the "-1" in adv_idx%end. If num_fluids = 1 then adv_idx%end < + ! adv_idx%beg, which skips all loops over the volume fractions since there is no volume fraction to track + adv_idx%beg = E_idx + 1 ! Alpha for fluid 1 adv_idx%end = E_idx + num_fluids - 1 else - ! Volume fractions are stored in the indices immediately following - ! the energy equation. WENO/MUSCL + Riemann tracks a total of (N) - ! volume fractions for N fluids, hence the lack of "-1" in adv_idx%end + ! Volume fractions are stored in the indices immediately following the energy equation. WENO/MUSCL + Riemann + ! tracks a total of (N) volume fractions for N fluids, hence the lack of "-1" in adv_idx%end adv_idx%beg = E_idx + 1 adv_idx%end = E_idx + num_fluids end if @@ -1014,7 +974,7 @@ contains if (bubbles_euler) then bub_idx%beg = sys_size + 1 if (qbmm) then - nmomsp = 4 !number of special moments + nmomsp = 4 ! number of special moments if (nnode == 4) then ! nmom = 6 : It is already a parameter nmomtot = nmom*nb @@ -1048,7 +1008,6 @@ contains bub_idx%rs(i) = bub_idx%moms(i, 2) bub_idx%vs(i) = bub_idx%moms(i, 3) end do - else do i = 1, nb if (.not. polytropic) then @@ -1071,13 +1030,12 @@ contains if (mhd) then B_idx%beg = sys_size + 1 if (n == 0) then - B_idx%end = sys_size + 2 ! 1D: By, Bz + B_idx%end = sys_size + 2 ! 1D: By, Bz else - B_idx%end = sys_size + 3 ! 2D/3D: Bx, By, Bz + B_idx%end = sys_size + 3 ! 2D/3D: Bx, By, Bz end if sys_size = B_idx%end end if - else if (model_eqns == 3) then cont_idx%beg = 1 cont_idx%end = num_fluids @@ -1090,15 +1048,14 @@ contains internalEnergies_idx%beg = adv_idx%end + 1 internalEnergies_idx%end = adv_idx%end + num_fluids sys_size = internalEnergies_idx%end - else if (model_eqns == 4) then - cont_idx%beg = 1 ! one continuity equation - cont_idx%end = 1 !num_fluids - mom_idx%beg = cont_idx%end + 1 ! one momentum equation in each direction + cont_idx%beg = 1 ! one continuity equation + cont_idx%end = 1 ! num_fluids + mom_idx%beg = cont_idx%end + 1 ! one momentum equation in each direction mom_idx%end = cont_idx%end + num_vels - E_idx = mom_idx%end + 1 ! one energy equation + E_idx = mom_idx%end + 1 ! one energy equation adv_idx%beg = E_idx + 1 - adv_idx%end = adv_idx%beg !one volume advection equation + adv_idx%end = adv_idx%beg ! one volume advection equation alf_idx = adv_idx%end sys_size = adv_idx%end @@ -1131,8 +1088,8 @@ contains end if end if - ! Determining the number of fluids for which the shear and the - ! volume Reynolds numbers, e.g. viscous effects, are important + ! Determining the number of fluids for which the shear and the volume Reynolds numbers, e.g. viscous effects, are + ! important do i = 1, num_fluids if (fluid_pp(i)%Re(1) > 0) Re_size(1) = Re_size(1) + 1 if (fluid_pp(i)%Re(2) > 0) Re_size(2) = Re_size(2) + 1 @@ -1143,12 +1100,11 @@ contains Re_size_max = maxval(Re_size) - $:GPU_UPDATE(device='[Re_size,Re_size_max,shear_stress,bulk_stress]') + $:GPU_UPDATE(device='[Re_size, Re_size_max, shear_stress, bulk_stress]') - ! Bookkeeping the indexes of any viscous fluids and any pairs of - ! fluids whose interface will support effects of surface tension + ! Bookkeeping the indexes of any viscous fluids and any pairs of fluids whose interface will support effects of surface + ! tension if (viscous) then - @:ALLOCATE(Re_idx(1:2, 1:Re_size_max)) k = 0 @@ -1164,13 +1120,10 @@ contains k = k + 1; Re_idx(2, k) = i end if end do - end if - end if if (model_eqns == 2 .or. model_eqns == 3) then - if (hypoelasticity .or. hyperelasticity) then elasticity = .true. stress_idx%beg = sys_size + 1 @@ -1186,20 +1139,18 @@ contains shear_num = 1 shear_indices(1) = stress_idx%beg - 1 + 2 shear_BC_flip_num = 1 - shear_BC_flip_indices(1:2, 1) = shear_indices(1) + shear_BC_flip_indices(1:2,1) = shear_indices(1) ! Both x-dir and y-dir: flip tau_xy only else if (num_dims == 3) then shear_num = 3 shear_indices(1:3) = stress_idx%beg - 1 + (/2, 4, 5/) shear_BC_flip_num = 2 - shear_BC_flip_indices(1, 1:2) = shear_indices((/1, 2/)) - shear_BC_flip_indices(2, 1:2) = shear_indices((/1, 3/)) - shear_BC_flip_indices(3, 1:2) = shear_indices((/2, 3/)) - ! x-dir: flip tau_xy and tau_xz - ! y-dir: flip tau_xy and tau_yz - ! z-dir: flip tau_xz and tau_yz + shear_BC_flip_indices(1,1:2) = shear_indices((/1, 2/)) + shear_BC_flip_indices(2,1:2) = shear_indices((/1, 3/)) + shear_BC_flip_indices(3,1:2) = shear_indices((/2, 3/)) + ! x-dir: flip tau_xy and tau_xz y-dir: flip tau_xy and tau_yz z-dir: flip tau_xz and tau_yz end if - $:GPU_UPDATE(device='[shear_num,shear_indices,shear_BC_flip_num,shear_BC_flip_indices]') + $:GPU_UPDATE(device='[shear_num, shear_indices, shear_BC_flip_num, shear_BC_flip_indices]') end if if (hyperelasticity) then @@ -1227,7 +1178,6 @@ contains psi_idx = sys_size + 1 sys_size = psi_idx end if - end if ! END: Volume Fraction Model @@ -1241,7 +1191,7 @@ contains if (bubbles_euler .and. qbmm .and. .not. polytropic) then allocate (MPI_IO_DATA%view(1:sys_size + 2*nb*nnode)) allocate (MPI_IO_DATA%var(1:sys_size + 2*nb*nnode)) - elseif (bubbles_lagrange) then + else if (bubbles_lagrange) then allocate (MPI_IO_DATA%view(1:sys_size + 1)) allocate (MPI_IO_DATA%var(1:sys_size + 1)) else @@ -1251,27 +1201,25 @@ contains if (.not. down_sample) then do i = 1, sys_size - allocate (MPI_IO_DATA%var(i)%sf(0:m, 0:n, 0:p)) + allocate (MPI_IO_DATA%var(i)%sf(0:m,0:n,0:p)) MPI_IO_DATA%var(i)%sf => null() end do end if if (bubbles_euler .and. qbmm .and. .not. polytropic) then do i = sys_size + 1, sys_size + 2*nb*nnode - allocate (MPI_IO_DATA%var(i)%sf(0:m, 0:n, 0:p)) + allocate (MPI_IO_DATA%var(i)%sf(0:m,0:n,0:p)) MPI_IO_DATA%var(i)%sf => null() end do - elseif (bubbles_lagrange) then + else if (bubbles_lagrange) then do i = 1, sys_size + 1 - allocate (MPI_IO_DATA%var(i)%sf(0:m, 0:n, 0:p)) + allocate (MPI_IO_DATA%var(i)%sf(0:m,0:n,0:p)) MPI_IO_DATA%var(i)%sf => null() end do end if - ! Configuring the WENO average flag that will be used to regulate - ! whether any spatial derivatives are to computed in each cell by - ! using the arithmetic mean of left and right, WENO-reconstructed, - ! cell-boundary values or otherwise, the unaltered left and right, - ! WENO-reconstructed, cell-boundary values + ! Configuring the WENO average flag that will be used to regulate whether any spatial derivatives are to computed in each + ! cell by using the arithmetic mean of left and right, WENO-reconstructed, cell-boundary values or otherwise, the unaltered + ! left and right, WENO-reconstructed, cell-boundary values wa_flg = 0._wp; if (weno_avg) wa_flg = 1._wp $:GPU_UPDATE(device='[wa_flg]') @@ -1280,38 +1228,32 @@ contains wenojs = .not. (mapped_weno .or. wenoz .or. teno) #:endif - if (ib) allocate (MPI_IO_IB_DATA%var%sf(0:m, 0:n, 0:p)) + if (ib) allocate (MPI_IO_IB_DATA%var%sf(0:m,0:n,0:p)) Np = 0 if (elasticity) fd_number = max(1, fd_order/2) - if (mhd) then ! TODO merge with above; waiting for hyperelasticity PR + if (mhd) then ! TODO merge with above; waiting for hyperelasticity PR fd_number = max(1, fd_order/2) end if if (probe_wrt) fd_number = max(1, fd_order/2) if (bubbles_lagrange) fd_number = max(1, fd_order/2) - call s_configure_coordinate_bounds(recon_type, weno_polyn, muscl_polyn, & - igr_order, buff_size, & - idwint, idwbuff, viscous, & - bubbles_lagrange, m, n, p, & - num_dims, igr, ib, fd_number) + call s_configure_coordinate_bounds(recon_type, weno_polyn, muscl_polyn, igr_order, buff_size, idwint, idwbuff, viscous, & + & bubbles_lagrange, m, n, p, num_dims, igr, ib, fd_number) $:GPU_UPDATE(device='[idwint, idwbuff]') ! Configuring Coordinate Direction Indexes if (bubbles_euler) then - @:ALLOCATE(ptil(& - & idwbuff(1)%beg:idwbuff(1)%end, & - & idwbuff(2)%beg:idwbuff(2)%end, & - & idwbuff(3)%beg:idwbuff(3)%end)) + @:ALLOCATE(ptil( idwbuff(1)%beg:idwbuff(1)%end, idwbuff(2)%beg:idwbuff(2)%end, idwbuff(3)%beg:idwbuff(3)%end)) end if $:GPU_UPDATE(device='[fd_order, fd_number]') - if (cyl_coord .neqv. .true.) then ! Cartesian grid + if (cyl_coord .neqv. .true.) then ! Cartesian grid grid_geometry = 1 - elseif (cyl_coord .and. p == 0) then ! Axisymmetric cylindrical grid + else if (cyl_coord .and. p == 0) then ! Axisymmetric cylindrical grid grid_geometry = 2 - else ! Fully 3D cylindrical grid + else ! Fully 3D cylindrical grid grid_geometry = 3 end if @@ -1332,44 +1274,39 @@ contains chemxb = species_idx%beg chemxe = species_idx%end - $:GPU_UPDATE(device='[momxb,momxe,advxb,advxe,contxb,contxe, & - & bubxb,bubxe,intxb,intxe,sys_size,buff_size,E_idx, & - & alf_idx,n_idx,adv_n,adap_dt,pi_fac,strxb,strxe, & - & chemxb,chemxe,c_idx,adap_dt_tol,adap_dt_max_iters]') - $:GPU_UPDATE(device='[b_size,xibeg,xiend,tensor_size]') + $:GPU_UPDATE(device='[momxb, momxe, advxb, advxe, contxb, contxe, bubxb, bubxe, intxb, intxe, sys_size, buff_size, E_idx, & + & alf_idx, n_idx, adv_n, adap_dt, pi_fac, strxb, strxe, chemxb, chemxe, c_idx, adap_dt_tol, & + & adap_dt_max_iters]') + $:GPU_UPDATE(device='[b_size, xibeg, xiend, tensor_size]') $:GPU_UPDATE(device='[species_idx]') - $:GPU_UPDATE(device='[cfl_target,m,n,p]') + $:GPU_UPDATE(device='[cfl_target, m, n, p]') - $:GPU_UPDATE(device='[alt_soundspeed,acoustic_source,num_source]') - $:GPU_UPDATE(device='[dt,sys_size,buff_size,pref,rhoref, & - & gamma_idx,pi_inf_idx,E_idx,alf_idx,stress_idx, & - & mpp_lim,bubbles_euler,hypoelasticity,alt_soundspeed, & - & avg_state,model_eqns, & - & mixture_err,grid_geometry,cyl_coord,mp_weno,weno_eps, & - & teno_CT,hyperelasticity,hyper_model,elasticity,xi_idx, & - & B_idx,low_Mach]') + $:GPU_UPDATE(device='[alt_soundspeed, acoustic_source, num_source]') + $:GPU_UPDATE(device='[dt, sys_size, buff_size, pref, rhoref, gamma_idx, pi_inf_idx, E_idx, alf_idx, stress_idx, mpp_lim, & + & bubbles_euler, hypoelasticity, alt_soundspeed, avg_state, model_eqns, mixture_err, grid_geometry, & + & cyl_coord, mp_weno, weno_eps, teno_CT, hyperelasticity, hyper_model, elasticity, xi_idx, B_idx, low_Mach]') $:GPU_UPDATE(device='[Bx0]') $:GPU_UPDATE(device='[chem_params]') - $:GPU_UPDATE(device='[cont_damage,tau_star,cont_damage_s,alpha_bar]') + $:GPU_UPDATE(device='[cont_damage, tau_star, cont_damage_s, alpha_bar]') $:GPU_UPDATE(device='[hyper_cleaning, hyper_cleaning_speed, hyper_cleaning_tau]') #:if not MFC_CASE_OPTIMIZATION - $:GPU_UPDATE(device='[wenojs,mapped_weno,wenoz,teno]') + $:GPU_UPDATE(device='[wenojs, mapped_weno, wenoz, teno]') $:GPU_UPDATE(device='[wenoz_q]') $:GPU_UPDATE(device='[mhd, relativity]') $:GPU_UPDATE(device='[muscl_order, muscl_lim]') $:GPU_UPDATE(device='[igr, igr_order]') - $:GPU_UPDATE(device='[num_fluids,num_dims,viscous,num_vels,nb,muscl_lim]') + $:GPU_UPDATE(device='[num_fluids, num_dims, viscous, num_vels, nb, muscl_lim]') #:endif - $:GPU_UPDATE(device='[dir_idx,dir_flg,dir_idx_tau]') + $:GPU_UPDATE(device='[dir_idx, dir_flg, dir_idx_tau]') - $:GPU_UPDATE(device='[relax,relax_model,palpha_eps,ptgalpha_eps]') + $:GPU_UPDATE(device='[relax, relax_model, palpha_eps, ptgalpha_eps]') ! Allocating grid variables for the x-, y- and z-directions @:ALLOCATE(x_cb(-1 - buff_size:m + buff_size)) @@ -1379,7 +1316,7 @@ contains @:PREFER_GPU(x_cc) @:PREFER_GPU(dx) - if (n == 0) return; + if (n == 0) return @:ALLOCATE(y_cb(-1 - buff_size:n + buff_size)) @:ALLOCATE(y_cc(-buff_size:n + buff_size)) @:ALLOCATE(dy(-buff_size:n + buff_size)) @@ -1387,7 +1324,7 @@ contains @:PREFER_GPU(y_cc) @:PREFER_GPU(dy) - if (p == 0) return; + if (p == 0) return @:ALLOCATE(z_cb(-1 - buff_size:p + buff_size)) @:ALLOCATE(z_cc(-buff_size:p + buff_size)) @:ALLOCATE(dz(-buff_size:p + buff_size)) @@ -1401,7 +1338,7 @@ contains impure subroutine s_initialize_parallel_io #ifdef MFC_MPI - integer :: ierr !< Generic flag used to identify and report MPI errors + integer :: ierr !< Generic flag used to identify and report MPI errors #endif #:if not MFC_CASE_OPTIMIZATION @@ -1421,7 +1358,6 @@ contains if (parallel_io .neqv. .true.) return #ifdef MFC_MPI - ! Option for Lustre file system (Darter/Comet/Stampede) write (mpiiofs, '(A)') '/lustre_' mpiiofs = trim(mpiiofs) @@ -1429,13 +1365,10 @@ contains call MPI_INFO_CREATE(mpi_info_int, ierr) call MPI_INFO_SET(mpi_info_int, 'romio_ds_write', 'disable', ierr) - ! Option for UNIX file system (Hooke/Thomson) - ! WRITE(mpiiofs, '(A)') '/ufs_' - ! mpiiofs = TRIM(mpiiofs) - ! mpi_info_int = MPI_INFO_NULL + ! Option for UNIX file system (Hooke/Thomson) WRITE(mpiiofs, '(A)') '/ufs_' mpiiofs = TRIM(mpiiofs) mpi_info_int = + ! MPI_INFO_NULL allocate (start_idx(1:num_dims)) - #endif end subroutine s_initialize_parallel_io @@ -1445,9 +1378,9 @@ contains integer :: i - ! Deallocating the variables bookkeeping the indexes of any viscous - ! fluids and any pairs of fluids whose interfaces supported effects - ! of surface tension + ! Deallocating the variables bookkeeping the indexes of any viscous fluids and any pairs of fluids whose interfaces + ! supported effects of surface tension + if (viscous) then @:DEALLOCATE(Re_idx) end if @@ -1478,10 +1411,10 @@ contains ! Deallocating grid variables for the x-, y- and z-directions @:DEALLOCATE(x_cb, x_cc, dx) - if (n == 0) return; + if (n == 0) return @:DEALLOCATE(y_cb, y_cc, dy) - if (p == 0) return; + if (p == 0) return @:DEALLOCATE(z_cb, z_cc, dz) if (allocated(neighbor_ranks)) then diff --git a/src/simulation/m_hyperelastic.fpp b/src/simulation/m_hyperelastic.fpp index e687244280..4fb504b2bc 100644 --- a/src/simulation/m_hyperelastic.fpp +++ b/src/simulation/m_hyperelastic.fpp @@ -8,42 +8,35 @@ module m_hyperelastic - use m_derived_types !< Definitions of the derived types - - use m_global_parameters !< Definitions of the global parameters - - use m_variables_conversion !< State variables type conversion procedures - + use m_derived_types !< Definitions of the derived types + use m_global_parameters !< Definitions of the global parameters + use m_variables_conversion !< State variables type conversion procedures use m_finite_differences implicit none - private; public :: s_hyperelastic_rmt_stress_update, & - s_initialize_hyperelastic_module, & - s_finalize_hyperelastic_module + private; public :: s_hyperelastic_rmt_stress_update, s_initialize_hyperelastic_module, s_finalize_hyperelastic_module - !! The btensor at the cell-interior Gaussian quadrature points. - !! These tensor is needed to be calculated once and make the code DRY. - type(vector_field) :: btensor !< + !! The btensor at the cell-interior Gaussian quadrature points. These tensor is needed to be calculated once and make the code + !! DRY. + type(vector_field) :: btensor $:GPU_DECLARE(create='[btensor]') - real(wp), allocatable, dimension(:, :) :: fd_coeff_x_hyper - real(wp), allocatable, dimension(:, :) :: fd_coeff_y_hyper - real(wp), allocatable, dimension(:, :) :: fd_coeff_z_hyper - $:GPU_DECLARE(create='[fd_coeff_x_hyper,fd_coeff_y_hyper, fd_coeff_z_hyper]') + real(wp), allocatable, dimension(:,:) :: fd_coeff_x_hyper + real(wp), allocatable, dimension(:,:) :: fd_coeff_y_hyper + real(wp), allocatable, dimension(:,:) :: fd_coeff_z_hyper + $:GPU_DECLARE(create='[fd_coeff_x_hyper, fd_coeff_y_hyper, fd_coeff_z_hyper]') real(wp), allocatable, dimension(:) :: Gs_hyper $:GPU_DECLARE(create='[Gs_hyper]') contains - !> The following subroutine handles the calculation of the btensor. - !! The calculation of the btensor takes qprimvf. - !! calculate the grad_xi, grad_xi is a nxn tensor - !! calculate the inverse of grad_xi to obtain F, F is a nxn tensor - !! calculate the FFtranspose to obtain the btensor, btensor is nxn tensor - !! btensor is symmetric, save the data space + !> The following subroutine handles the calculation of the btensor. The calculation of the btensor takes qprimvf. calculate the + !! grad_xi, grad_xi is a nxn tensor calculate the inverse of grad_xi to obtain F, F is a nxn tensor calculate the FFtranspose to + !! obtain the btensor, btensor is nxn tensor btensor is symmetric, save the data space impure subroutine s_initialize_hyperelastic_module - integer :: i !< generic iterator + + integer :: i !< generic iterator @:ALLOCATE(btensor%vf(1:b_size)) do i = 1, b_size @@ -67,34 +60,29 @@ contains end if ! Computing centered finite difference coefficients - call s_compute_finite_difference_coefficients(m, x_cc, fd_coeff_x_hyper, buff_size, & - fd_number, fd_order) + call s_compute_finite_difference_coefficients(m, x_cc, fd_coeff_x_hyper, buff_size, fd_number, fd_order) $:GPU_UPDATE(device='[fd_coeff_x_hyper]') if (n > 0) then - call s_compute_finite_difference_coefficients(n, y_cc, fd_coeff_y_hyper, buff_size, & - fd_number, fd_order) + call s_compute_finite_difference_coefficients(n, y_cc, fd_coeff_y_hyper, buff_size, fd_number, fd_order) $:GPU_UPDATE(device='[fd_coeff_y_hyper]') end if if (p > 0) then - call s_compute_finite_difference_coefficients(p, z_cc, fd_coeff_z_hyper, buff_size, & - fd_number, fd_order) + call s_compute_finite_difference_coefficients(p, z_cc, fd_coeff_z_hyper, buff_size, fd_number, fd_order) $:GPU_UPDATE(device='[fd_coeff_z_hyper]') end if end subroutine s_initialize_hyperelastic_module - !> The following subroutine handles the calculation of the btensor. - !! The calculation of the btensor takes qprimvf. - !! @param q_cons_vf Conservative variables - !! @param q_prim_vf Primitive variables - !! calculate the grad_xi, grad_xi is a nxn tensor - !! calculate the inverse of grad_xi to obtain F, F is a nxn tensor - !! calculate the FFtranspose to obtain the btensor, btensor is nxn tensor - !! btensor is symmetric, save the data space + !> The following subroutine handles the calculation of the btensor. The calculation of the btensor takes qprimvf. + !! @param q_cons_vf Conservative variables + !! @param q_prim_vf Primitive variables + !! calculate the grad_xi, grad_xi is a nxn tensor calculate the inverse of grad_xi to obtain F, F is a nxn tensor calculate the + !! FFtranspose to obtain the btensor, btensor is nxn tensor btensor is symmetric, save the data space subroutine s_hyperelastic_rmt_stress_update(q_cons_vf, q_prim_vf) type(scalar_field), dimension(sys_size), intent(inout) :: q_cons_vf type(scalar_field), dimension(sys_size), intent(inout) :: q_prim_vf + #:if USING_AMD real(wp), dimension(10) :: tensora, tensorb #:else @@ -107,34 +95,31 @@ contains real(wp), dimension(num_fluids) :: alpha_k, alpha_rho_k #:endif real(wp), dimension(2) :: Re - real(wp) :: rho, gamma, pi_inf, qv - real(wp) :: G_local - integer :: j, k, l, i, r + real(wp) :: rho, gamma, pi_inf, qv + real(wp) :: G_local + integer :: j, k, l, i, r - $:GPU_PARALLEL_LOOP(collapse=3, private='[i,j,k,l,alpha_K, alpha_rho_K, rho, gamma, pi_inf, qv, G_local, Re, tensora, tensorb]') + $:GPU_PARALLEL_LOOP(collapse=3, & + & private='[i, j, k, l, alpha_K, alpha_rho_K, rho, gamma, pi_inf, qv, G_local, Re, tensora, tensorb]') do l = 0, p do k = 0, n do j = 0, m - call s_compute_species_fraction(q_cons_vf, j, k, l, alpha_rho_k, alpha_k) ! If in simulation, use acc mixture subroutines - call s_convert_species_to_mixture_variables_acc(rho, gamma, pi_inf, qv, alpha_k, & - alpha_rho_k, Re, G_local, Gs_hyper) + call s_convert_species_to_mixture_variables_acc(rho, gamma, pi_inf, qv, alpha_k, alpha_rho_k, Re, G_local, & + & Gs_hyper) rho = max(rho, sgm_eps) G_local = max(G_local, sgm_eps) - !if ( G_local <= verysmall ) G_K = 0._wp + ! if ( G_local <= verysmall ) G_K = 0._wp if (G_local > verysmall) then $:GPU_LOOP(parallelism='[seq]') do i = 1, tensor_size tensora(i) = 0._wp end do - ! STEP 1: computing the grad_xi tensor using finite differences - ! grad_xi definition / organization - ! number for the tensor 1-3: dxix_dx, dxiy_dx, dxiz_dx - ! 4-6 : dxix_dy, dxiy_dy, dxiz_dy - ! 7-9 : dxix_dz, dxiy_dz, dxiz_dz + ! STEP 1: computing the grad_xi tensor using finite differences grad_xi definition / organization number for + ! the tensor 1-3: dxix_dx, dxiy_dx, dxiz_dx 4-6 : dxix_dy, dxiy_dy, dxiz_dy 7-9 : dxix_dz, dxiy_dz, dxiz_dz $:GPU_LOOP(parallelism='[seq]') do r = -fd_number, fd_number ! derivatives in the x-direction @@ -162,13 +147,11 @@ contains tensorb(9) = tensora(1)*tensora(5) - tensora(2)*tensora(4) ! STEP 2b: computing the determinant of the grad_xi tensor - tensorb(tensor_size) = tensora(1)*(tensora(5)*tensora(9) - tensora(6)*tensora(8)) & - - tensora(2)*(tensora(4)*tensora(9) - tensora(6)*tensora(7)) & - + tensora(3)*(tensora(4)*tensora(8) - tensora(5)*tensora(7)) + tensorb(tensor_size) = tensora(1)*(tensora(5)*tensora(9) - tensora(6)*tensora(8)) - tensora(2)*(tensora(4) & + & *tensora(9) - tensora(6)*tensora(7)) + tensora(3)*(tensora(4)*tensora(8) - tensora(5)*tensora(7)) if (tensorb(tensor_size) > verysmall) then - ! STEP 2c: computing the inverse of grad_xi tensor = F - ! tensorb is the adjoint, tensora becomes F + ! STEP 2c: computing the inverse of grad_xi tensor = F tensorb is the adjoint, tensora becomes F $:GPU_LOOP(parallelism='[seq]') do i = 1, tensor_size - 1 tensora(i) = tensorb(i)/tensorb(tensor_size) @@ -193,17 +176,16 @@ contains ! STEP 5a: updating the Cauchy stress primitive scalar field if (hyper_model == 1) then call s_neoHookean_cauchy_solver(btensor%vf, q_prim_vf, G_local, j, k, l) - elseif (hyper_model == 2) then + else if (hyper_model == 2) then call s_Mooney_Rivlin_cauchy_solver(btensor%vf, q_prim_vf, G_local, j, k, l) end if ! STEP 5b: updating the pressure field - q_prim_vf(E_idx)%sf(j, k, l) = q_prim_vf(E_idx)%sf(j, k, l) - & - G_local*q_prim_vf(xiend + 1)%sf(j, k, l)/gamma + q_prim_vf(E_idx)%sf(j, k, l) = q_prim_vf(E_idx)%sf(j, k, l) - G_local*q_prim_vf(xiend + 1)%sf(j, k, & + & l)/gamma ! STEP 5c: updating the Cauchy stress conservative scalar field $:GPU_LOOP(parallelism='[seq]') do i = 1, b_size - 1 - q_cons_vf(strxb + i - 1)%sf(j, k, l) = & - rho*q_prim_vf(strxb + i - 1)%sf(j, k, l) + q_cons_vf(strxb + i - 1)%sf(j, k, l) = rho*q_prim_vf(strxb + i - 1)%sf(j, k, l) end do end if end if @@ -211,30 +193,28 @@ contains end do end do $:END_GPU_PARALLEL_LOOP() + end subroutine s_hyperelastic_rmt_stress_update - !> The following subroutine handles the calculation of the btensor. - !! The calculation of the btensor takes qprimvf. - !! @param btensor_in Left Cauchy-Green deformation tensor - !! @param q_prim_vf Primitive variables - !! @param G_param Elastic shear modulus - !! @param j x-direction cell index - !! @param k y-direction cell index - !! @param l z-direction cell index - !! calculate the grad_xi, grad_xi is a nxn tensor - !! calculate the inverse of grad_xi to obtain F, F is a nxn tensor - !! calculate the FFtranspose to obtain the btensor, btensor is nxn tensor - !! btensor is symmetric, save the data space + !> The following subroutine handles the calculation of the btensor. The calculation of the btensor takes qprimvf. + !! @param btensor_in Left Cauchy-Green deformation tensor + !! @param q_prim_vf Primitive variables + !! @param G_param Elastic shear modulus + !! @param j x-direction cell index + !! @param k y-direction cell index + !! @param l z-direction cell index + !! calculate the grad_xi, grad_xi is a nxn tensor calculate the inverse of grad_xi to obtain F, F is a nxn tensor calculate the + !! FFtranspose to obtain the btensor, btensor is nxn tensor btensor is symmetric, save the data space subroutine s_neoHookean_cauchy_solver(btensor_in, q_prim_vf, G_param, j, k, l) + $:GPU_ROUTINE(parallelism='[seq]') type(scalar_field), dimension(sys_size), intent(inout) :: q_prim_vf - type(scalar_field), dimension(b_size), intent(inout) :: btensor_in - real(wp), intent(in) :: G_param - integer, intent(in) :: j, k, l - - real(wp) :: trace - real(wp), parameter :: f13 = 1._wp/3._wp - integer :: i !< Generic loop iterators + type(scalar_field), dimension(b_size), intent(inout) :: btensor_in + real(wp), intent(in) :: G_param + integer, intent(in) :: j, k, l + real(wp) :: trace + real(wp), parameter :: f13 = 1._wp/3._wp + integer :: i !< Generic loop iterators ! tensor is the symmetric tensor & calculate the trace of the tensor trace = btensor_in(1)%sf(j, k, l) + btensor_in(3)%sf(j, k, l) + btensor_in(6)%sf(j, k, l) @@ -243,44 +223,37 @@ contains #:for IJ in [1,3,6] btensor_in(${IJ}$)%sf(j, k, l) = btensor_in(${IJ}$)%sf(j, k, l) - f13*trace #:endfor - ! dividing by the jacobian for neo-Hookean model - ! setting the tensor to the stresses for riemann solver + ! dividing by the jacobian for neo-Hookean model setting the tensor to the stresses for riemann solver $:GPU_LOOP(parallelism='[seq]') do i = 1, b_size - 1 - q_prim_vf(strxb + i - 1)%sf(j, k, l) = & - G_param*btensor_in(i)%sf(j, k, l)/btensor_in(b_size)%sf(j, k, l) + q_prim_vf(strxb + i - 1)%sf(j, k, l) = G_param*btensor_in(i)%sf(j, k, l)/btensor_in(b_size)%sf(j, k, l) end do ! compute the invariant without the elastic modulus - q_prim_vf(xiend + 1)%sf(j, k, l) = & - 0.5_wp*(trace - 3.0_wp)/btensor_in(b_size)%sf(j, k, l) + q_prim_vf(xiend + 1)%sf(j, k, l) = 0.5_wp*(trace - 3.0_wp)/btensor_in(b_size)%sf(j, k, l) end subroutine s_neoHookean_cauchy_solver - !> The following subroutine handles the calculation of the btensor. - !! The calculation of the btensor takes qprimvf. - !! @param btensor_in Left Cauchy-Green deformation tensor - !! @param q_prim_vf Primitive variables - !! @param G_param Elastic shear modulus - !! @param j x-direction cell index - !! @param k y-direction cell index - !! @param l z-direction cell index - !! calculate the grad_xi, grad_xi is a nxn tensor - !! calculate the inverse of grad_xi to obtain F, F is a nxn tensor - !! calculate the FFtranspose to obtain the btensor, btensor is nxn tensor - !! btensor is symmetric, save the data space + !> The following subroutine handles the calculation of the btensor. The calculation of the btensor takes qprimvf. + !! @param btensor_in Left Cauchy-Green deformation tensor + !! @param q_prim_vf Primitive variables + !! @param G_param Elastic shear modulus + !! @param j x-direction cell index + !! @param k y-direction cell index + !! @param l z-direction cell index + !! calculate the grad_xi, grad_xi is a nxn tensor calculate the inverse of grad_xi to obtain F, F is a nxn tensor calculate the + !! FFtranspose to obtain the btensor, btensor is nxn tensor btensor is symmetric, save the data space subroutine s_Mooney_Rivlin_cauchy_solver(btensor_in, q_prim_vf, G_param, j, k, l) + $:GPU_ROUTINE(parallelism='[seq]') type(scalar_field), dimension(sys_size), intent(inout) :: q_prim_vf - type(scalar_field), dimension(b_size), intent(inout) :: btensor_in - real(wp), intent(in) :: G_param - integer, intent(in) :: j, k, l - - real(wp) :: trace - real(wp), parameter :: f13 = 1._wp/3._wp - integer :: i !< Generic loop iterators - - !TODO Make this 1D and 2D capable - ! tensor is the symmetric tensor & calculate the trace of the tensor + type(scalar_field), dimension(b_size), intent(inout) :: btensor_in + real(wp), intent(in) :: G_param + integer, intent(in) :: j, k, l + real(wp) :: trace + real(wp), parameter :: f13 = 1._wp/3._wp + integer :: i !< Generic loop iterators + + ! TODO Make this 1D and 2D capable tensor is the symmetric tensor & calculate the trace of the tensor trace = btensor_in(1)%sf(j, k, l) + btensor_in(3)%sf(j, k, l) + btensor_in(6)%sf(j, k, l) ! calculate the deviatoric of the tensor @@ -288,25 +261,23 @@ contains btensor_in(3)%sf(j, k, l) = btensor_in(3)%sf(j, k, l) - f13*trace btensor_in(6)%sf(j, k, l) = btensor_in(6)%sf(j, k, l) - f13*trace - ! dividing by the jacobian for neo-Hookean model - ! setting the tensor to the stresses for riemann solver + ! dividing by the jacobian for neo-Hookean model setting the tensor to the stresses for riemann solver $:GPU_LOOP(parallelism='[seq]') do i = 1, b_size - 1 - q_prim_vf(strxb + i - 1)%sf(j, k, l) = & - G_param*btensor_in(i)%sf(j, k, l)/btensor_in(b_size)%sf(j, k, l) + q_prim_vf(strxb + i - 1)%sf(j, k, l) = G_param*btensor_in(i)%sf(j, k, l)/btensor_in(b_size)%sf(j, k, l) end do ! compute the invariant without the elastic modulus - q_prim_vf(xiend + 1)%sf(j, k, l) = & - 0.5_wp*(trace - 3.0_wp)/btensor_in(b_size)%sf(j, k, l) + q_prim_vf(xiend + 1)%sf(j, k, l) = 0.5_wp*(trace - 3.0_wp)/btensor_in(b_size)%sf(j, k, l) end subroutine s_Mooney_Rivlin_cauchy_solver !> @brief Deallocates memory for hyperelastic deformation tensor and finite-difference coefficients. impure subroutine s_finalize_hyperelastic_module() - integer :: i !< iterator + integer :: i !< iterator ! Deallocating memory + do i = 1, b_size @:DEALLOCATE(btensor%vf(i)%sf) end do diff --git a/src/simulation/m_hypoelastic.fpp b/src/simulation/m_hypoelastic.fpp index 8ee46b1ba8..a04fcb6b3b 100644 --- a/src/simulation/m_hypoelastic.fpp +++ b/src/simulation/m_hypoelastic.fpp @@ -7,33 +7,31 @@ !> @brief Computes hypoelastic stress-rate source terms and damage-state evolution module m_hypoelastic - use m_derived_types !< Definitions of the derived types - use m_global_parameters !< Definitions of the global parameters + use m_derived_types !< Definitions of the derived types + use m_global_parameters !< Definitions of the global parameters use m_finite_differences use m_helper implicit none - private; public :: s_initialize_hypoelastic_module, & - s_finalize_hypoelastic_module, & - s_compute_hypoelastic_rhs, & - s_compute_damage_state + private; public :: s_initialize_hypoelastic_module, s_finalize_hypoelastic_module, s_compute_hypoelastic_rhs, & + & s_compute_damage_state real(wp), allocatable, dimension(:) :: Gs_hypo $:GPU_DECLARE(create='[Gs_hypo]') - real(wp), allocatable, dimension(:, :, :) :: du_dx_hypo, du_dy_hypo, du_dz_hypo - real(wp), allocatable, dimension(:, :, :) :: dv_dx_hypo, dv_dy_hypo, dv_dz_hypo - real(wp), allocatable, dimension(:, :, :) :: dw_dx_hypo, dw_dy_hypo, dw_dz_hypo - $:GPU_DECLARE(create='[du_dx_hypo,du_dy_hypo,du_dz_hypo,dv_dx_hypo,dv_dy_hypo,dv_dz_hypo,dw_dx_hypo,dw_dy_hypo,dw_dz_hypo]') + real(wp), allocatable, dimension(:,:,:) :: du_dx_hypo, du_dy_hypo, du_dz_hypo + real(wp), allocatable, dimension(:,:,:) :: dv_dx_hypo, dv_dy_hypo, dv_dz_hypo + real(wp), allocatable, dimension(:,:,:) :: dw_dx_hypo, dw_dy_hypo, dw_dz_hypo + $:GPU_DECLARE(create='[du_dx_hypo, du_dy_hypo, du_dz_hypo, dv_dx_hypo, dv_dy_hypo, dv_dz_hypo, dw_dx_hypo, dw_dy_hypo, dw_dz_hypo]') - real(wp), allocatable, dimension(:, :, :) :: rho_K_field, G_K_field - $:GPU_DECLARE(create='[rho_K_field,G_K_field]') + real(wp), allocatable, dimension(:,:,:) :: rho_K_field, G_K_field + $:GPU_DECLARE(create='[rho_K_field, G_K_field]') - real(wp), allocatable, dimension(:, :) :: fd_coeff_x_hypo - real(wp), allocatable, dimension(:, :) :: fd_coeff_y_hypo - real(wp), allocatable, dimension(:, :) :: fd_coeff_z_hypo - $:GPU_DECLARE(create='[fd_coeff_x_hypo,fd_coeff_y_hypo,fd_coeff_z_hypo]') + real(wp), allocatable, dimension(:,:) :: fd_coeff_x_hypo + real(wp), allocatable, dimension(:,:) :: fd_coeff_y_hypo + real(wp), allocatable, dimension(:,:) :: fd_coeff_z_hypo + $:GPU_DECLARE(create='[fd_coeff_x_hypo, fd_coeff_y_hypo, fd_coeff_z_hypo]') contains @@ -67,43 +65,36 @@ contains end if ! Computing centered finite difference coefficients - call s_compute_finite_difference_coefficients(m, x_cc, fd_coeff_x_hypo, buff_size, & - fd_number, fd_order) + call s_compute_finite_difference_coefficients(m, x_cc, fd_coeff_x_hypo, buff_size, fd_number, fd_order) $:GPU_UPDATE(device='[fd_coeff_x_hypo]') if (n > 0) then - call s_compute_finite_difference_coefficients(n, y_cc, fd_coeff_y_hypo, buff_size, & - fd_number, fd_order) + call s_compute_finite_difference_coefficients(n, y_cc, fd_coeff_y_hypo, buff_size, fd_number, fd_order) $:GPU_UPDATE(device='[fd_coeff_y_hypo]') end if if (p > 0) then - call s_compute_finite_difference_coefficients(p, z_cc, fd_coeff_z_hypo, buff_size, & - fd_number, fd_order) + call s_compute_finite_difference_coefficients(p, z_cc, fd_coeff_z_hypo, buff_size, fd_number, fd_order) $:GPU_UPDATE(device='[fd_coeff_z_hypo]') end if end subroutine s_initialize_hypoelastic_module - !> The purpose of this procedure is to compute the source terms - !! that are needed for the elastic stress equations - !! @param idir Dimension splitting index - !! @param q_prim_vf Primitive variables - !! @param rhs_vf rhs variables + !> The purpose of this procedure is to compute the source terms that are needed for the elastic stress equations + !! @param idir Dimension splitting index + !! @param q_prim_vf Primitive variables + !! @param rhs_vf rhs variables subroutine s_compute_hypoelastic_rhs(idir, q_prim_vf, rhs_vf) - integer, intent(in) :: idir - type(scalar_field), dimension(sys_size), intent(in) :: q_prim_vf + integer, intent(in) :: idir + type(scalar_field), dimension(sys_size), intent(in) :: q_prim_vf type(scalar_field), dimension(sys_size), intent(inout) :: rhs_vf - - real(wp) :: rho_K, G_K - - integer :: i, k, l, q, r !< Loop variables - integer :: ndirs !< Number of coordinate directions + real(wp) :: rho_K, G_K + integer :: i, k, l, q, r !< Loop variables + integer :: ndirs !< Number of coordinate directions ndirs = 1; if (n > 0) ndirs = 2; if (p > 0) ndirs = 3 if (idir == 1) then - ! calculate velocity gradients + rho_K and G_K - ! TODO: re-organize these loops one by one for GPU efficiency if possible? + ! calculate velocity gradients + rho_K and G_K TODO: re-organize these loops one by one for GPU efficiency if possible? $:GPU_PARALLEL_LOOP(collapse=3) do q = 0, p @@ -121,10 +112,8 @@ contains do k = 0, m $:GPU_LOOP(parallelism='[seq]') do r = -fd_number, fd_number - du_dx_hypo(k, l, q) = du_dx_hypo(k, l, q) & - + q_prim_vf(momxb)%sf(k + r, l, q)*fd_coeff_x_hypo(r, k) + du_dx_hypo(k, l, q) = du_dx_hypo(k, l, q) + q_prim_vf(momxb)%sf(k + r, l, q)*fd_coeff_x_hypo(r, k) end do - end do end do end do @@ -147,12 +136,11 @@ contains do k = 0, m $:GPU_LOOP(parallelism='[seq]') do r = -fd_number, fd_number - du_dy_hypo(k, l, q) = du_dy_hypo(k, l, q) & - + q_prim_vf(momxb)%sf(k, l + r, q)*fd_coeff_y_hypo(r, l) - dv_dx_hypo(k, l, q) = dv_dx_hypo(k, l, q) & - + q_prim_vf(momxb + 1)%sf(k + r, l, q)*fd_coeff_x_hypo(r, k) - dv_dy_hypo(k, l, q) = dv_dy_hypo(k, l, q) & - + q_prim_vf(momxb + 1)%sf(k, l + r, q)*fd_coeff_y_hypo(r, l) + du_dy_hypo(k, l, q) = du_dy_hypo(k, l, q) + q_prim_vf(momxb)%sf(k, l + r, q)*fd_coeff_y_hypo(r, l) + dv_dx_hypo(k, l, q) = dv_dx_hypo(k, l, q) + q_prim_vf(momxb + 1)%sf(k + r, l, & + & q)*fd_coeff_x_hypo(r, k) + dv_dy_hypo(k, l, q) = dv_dy_hypo(k, l, q) + q_prim_vf(momxb + 1)%sf(k, l + r, & + & q)*fd_coeff_y_hypo(r, l) end do end do end do @@ -161,13 +149,12 @@ contains ! 3D if (ndirs == 3) then - $:GPU_PARALLEL_LOOP(collapse=3) do q = 0, p do l = 0, n do k = 0, m - du_dz_hypo(k, l, q) = 0._wp; dv_dz_hypo(k, l, q) = 0._wp; dw_dx_hypo(k, l, q) = 0._wp; - dw_dy_hypo(k, l, q) = 0._wp; dw_dz_hypo(k, l, q) = 0._wp; + du_dz_hypo(k, l, q) = 0._wp; dv_dz_hypo(k, l, q) = 0._wp; dw_dx_hypo(k, l, q) = 0._wp + dw_dy_hypo(k, l, q) = 0._wp; dw_dz_hypo(k, l, q) = 0._wp end do end do end do @@ -179,16 +166,16 @@ contains do k = 0, m $:GPU_LOOP(parallelism='[seq]') do r = -fd_number, fd_number - du_dz_hypo(k, l, q) = du_dz_hypo(k, l, q) & - + q_prim_vf(momxb)%sf(k, l, q + r)*fd_coeff_z_hypo(r, q) - dv_dz_hypo(k, l, q) = dv_dz_hypo(k, l, q) & - + q_prim_vf(momxb + 1)%sf(k, l, q + r)*fd_coeff_z_hypo(r, q) - dw_dx_hypo(k, l, q) = dw_dx_hypo(k, l, q) & - + q_prim_vf(momxe)%sf(k + r, l, q)*fd_coeff_x_hypo(r, k) - dw_dy_hypo(k, l, q) = dw_dy_hypo(k, l, q) & - + q_prim_vf(momxe)%sf(k, l + r, q)*fd_coeff_y_hypo(r, l) - dw_dz_hypo(k, l, q) = dw_dz_hypo(k, l, q) & - + q_prim_vf(momxe)%sf(k, l, q + r)*fd_coeff_z_hypo(r, q) + du_dz_hypo(k, l, q) = du_dz_hypo(k, l, q) + q_prim_vf(momxb)%sf(k, l, & + & q + r)*fd_coeff_z_hypo(r, q) + dv_dz_hypo(k, l, q) = dv_dz_hypo(k, l, q) + q_prim_vf(momxb + 1)%sf(k, l, & + & q + r)*fd_coeff_z_hypo(r, q) + dw_dx_hypo(k, l, q) = dw_dx_hypo(k, l, q) + q_prim_vf(momxe)%sf(k + r, l, & + & q)*fd_coeff_x_hypo(r, k) + dw_dy_hypo(k, l, q) = dw_dy_hypo(k, l, q) + q_prim_vf(momxe)%sf(k, l + r, & + & q)*fd_coeff_y_hypo(r, l) + dw_dz_hypo(k, l, q) = dw_dz_hypo(k, l, q) + q_prim_vf(momxe)%sf(k, l, & + & q + r)*fd_coeff_z_hypo(r, q) end do end do end do @@ -203,8 +190,8 @@ contains do k = 0, m rho_K = 0._wp; G_K = 0._wp do i = 1, num_fluids - rho_K = rho_K + q_prim_vf(i)%sf(k, l, q) !alpha_rho_K(1) - G_K = G_K + q_prim_vf(advxb - 1 + i)%sf(k, l, q)*Gs_hypo(i) !alpha_K(1) * Gs_hypo(1) + rho_K = rho_K + q_prim_vf(i)%sf(k, l, q) ! alpha_rho_K(1) + G_K = G_K + q_prim_vf(advxb - 1 + i)%sf(k, l, q)*Gs_hypo(i) ! alpha_K(1) * Gs_hypo(1) end do if (cont_damage) G_K = G_K*max((1._wp - q_prim_vf(damage_idx)%sf(k, l, q)), 0._wp) @@ -212,7 +199,7 @@ contains rho_K_field(k, l, q) = rho_K G_K_field(k, l, q) = G_K - !TODO: take this out if not needed + ! TODO: take this out if not needed if (G_K < verysmall) then G_K_field(k, l, q) = 0 end if @@ -226,114 +213,85 @@ contains do q = 0, p do l = 0, n do k = 0, m - rhs_vf(strxb)%sf(k, l, q) = & - rhs_vf(strxb)%sf(k, l, q) + rho_K_field(k, l, q)* & - ((4._wp*G_K_field(k, l, q)/3._wp) + & - q_prim_vf(strxb)%sf(k, l, q))* & - du_dx_hypo(k, l, q) + rhs_vf(strxb)%sf(k, l, q) = rhs_vf(strxb)%sf(k, l, q) + rho_K_field(k, l, q)*((4._wp*G_K_field(k, l, & + & q)/3._wp) + q_prim_vf(strxb)%sf(k, l, q))*du_dx_hypo(k, l, q) end do end do end do $:END_GPU_PARALLEL_LOOP() - - elseif (idir == 2) then + else if (idir == 2) then $:GPU_PARALLEL_LOOP(collapse=3) do q = 0, p do l = 0, n do k = 0, m - rhs_vf(strxb)%sf(k, l, q) = rhs_vf(strxb)%sf(k, l, q) + rho_K_field(k, l, q)* & - (q_prim_vf(strxb + 1)%sf(k, l, q)*du_dy_hypo(k, l, q) + & - q_prim_vf(strxb + 1)%sf(k, l, q)*du_dy_hypo(k, l, q) - & - q_prim_vf(strxb)%sf(k, l, q)*dv_dy_hypo(k, l, q) - & - 2._wp*G_K_field(k, l, q)*(1._wp/3._wp)*dv_dy_hypo(k, l, q)) - - rhs_vf(strxb + 1)%sf(k, l, q) = rhs_vf(strxb + 1)%sf(k, l, q) + rho_K_field(k, l, q)* & - (q_prim_vf(strxb + 1)%sf(k, l, q)*du_dx_hypo(k, l, q) + & - q_prim_vf(strxb)%sf(k, l, q)*dv_dx_hypo(k, l, q) - & - q_prim_vf(strxb + 1)%sf(k, l, q)*du_dx_hypo(k, l, q) + & - q_prim_vf(strxb + 2)%sf(k, l, q)*du_dy_hypo(k, l, q) + & - q_prim_vf(strxb + 1)%sf(k, l, q)*dv_dy_hypo(k, l, q) - & - q_prim_vf(strxb + 1)%sf(k, l, q)*dv_dy_hypo(k, l, q) + & - 2._wp*G_K_field(k, l, q)*(1._wp/2._wp)*(du_dy_hypo(k, l, q) + & - dv_dx_hypo(k, l, q))) - - rhs_vf(strxb + 2)%sf(k, l, q) = rhs_vf(strxb + 2)%sf(k, l, q) + rho_K_field(k, l, q)* & - (q_prim_vf(strxb + 1)%sf(k, l, q)*dv_dx_hypo(k, l, q) + & - q_prim_vf(strxb + 1)%sf(k, l, q)*dv_dx_hypo(k, l, q) - & - q_prim_vf(strxb + 2)%sf(k, l, q)*du_dx_hypo(k, l, q) + & - q_prim_vf(strxb + 2)%sf(k, l, q)*dv_dy_hypo(k, l, q) + & - q_prim_vf(strxb + 2)%sf(k, l, q)*dv_dy_hypo(k, l, q) - & - q_prim_vf(strxb + 2)%sf(k, l, q)*dv_dy_hypo(k, l, q) + & - 2._wp*G_K_field(k, l, q)*(dv_dy_hypo(k, l, q) - (1._wp/3._wp)* & - (du_dx_hypo(k, l, q) + & - dv_dy_hypo(k, l, q)))) + rhs_vf(strxb)%sf(k, l, q) = rhs_vf(strxb)%sf(k, l, q) + rho_K_field(k, l, q)*(q_prim_vf(strxb + 1)%sf(k, & + & l, q)*du_dy_hypo(k, l, q) + q_prim_vf(strxb + 1)%sf(k, l, q)*du_dy_hypo(k, l, & + & q) - q_prim_vf(strxb)%sf(k, l, q)*dv_dy_hypo(k, l, q) - 2._wp*G_K_field(k, l, & + & q)*(1._wp/3._wp)*dv_dy_hypo(k, l, q)) + + rhs_vf(strxb + 1)%sf(k, l, q) = rhs_vf(strxb + 1)%sf(k, l, q) + rho_K_field(k, l, & + & q)*(q_prim_vf(strxb + 1)%sf(k, l, q)*du_dx_hypo(k, l, q) + q_prim_vf(strxb)%sf(k, l, & + & q)*dv_dx_hypo(k, l, q) - q_prim_vf(strxb + 1)%sf(k, l, q)*du_dx_hypo(k, l, & + & q) + q_prim_vf(strxb + 2)%sf(k, l, q)*du_dy_hypo(k, l, q) + q_prim_vf(strxb + 1)%sf(k, l, & + & q)*dv_dy_hypo(k, l, q) - q_prim_vf(strxb + 1)%sf(k, l, q)*dv_dy_hypo(k, l, & + & q) + 2._wp*G_K_field(k, l, q)*(1._wp/2._wp)*(du_dy_hypo(k, l, q) + dv_dx_hypo(k, l, q))) + + rhs_vf(strxb + 2)%sf(k, l, q) = rhs_vf(strxb + 2)%sf(k, l, q) + rho_K_field(k, l, & + & q)*(q_prim_vf(strxb + 1)%sf(k, l, q)*dv_dx_hypo(k, l, q) + q_prim_vf(strxb + 1)%sf(k, l, & + & q)*dv_dx_hypo(k, l, q) - q_prim_vf(strxb + 2)%sf(k, l, q)*du_dx_hypo(k, l, & + & q) + q_prim_vf(strxb + 2)%sf(k, l, q)*dv_dy_hypo(k, l, q) + q_prim_vf(strxb + 2)%sf(k, l, & + & q)*dv_dy_hypo(k, l, q) - q_prim_vf(strxb + 2)%sf(k, l, q)*dv_dy_hypo(k, l, & + & q) + 2._wp*G_K_field(k, l, q)*(dv_dy_hypo(k, l, q) - (1._wp/3._wp)*(du_dx_hypo(k, l, & + & q) + dv_dy_hypo(k, l, q)))) end do end do end do $:END_GPU_PARALLEL_LOOP() - - elseif (idir == 3) then + else if (idir == 3) then $:GPU_PARALLEL_LOOP(collapse=3) do q = 0, p do l = 0, n do k = 0, m - rhs_vf(strxb)%sf(k, l, q) = rhs_vf(strxb)%sf(k, l, q) + rho_K_field(k, l, q)* & - (q_prim_vf(strxb + 3)%sf(k, l, q)*du_dz_hypo(k, l, q) + & - q_prim_vf(strxb + 3)%sf(k, l, q)*du_dz_hypo(k, l, q) - & - q_prim_vf(strxb)%sf(k, l, q)*dw_dz_hypo(k, l, q) - & - 2._wp*G_K_field(k, l, q)*(1._wp/3._wp)*dw_dz_hypo(k, l, q)) - - rhs_vf(strxb + 1)%sf(k, l, q) = rhs_vf(strxb + 1)%sf(k, l, q) + rho_K_field(k, l, q)* & - (q_prim_vf(strxb + 4)%sf(k, l, q)*du_dz_hypo(k, l, q) + & - q_prim_vf(strxb + 3)%sf(k, l, q)*dv_dz_hypo(k, l, q) - & - q_prim_vf(strxb + 1)%sf(k, l, q)*dw_dz_hypo(k, l, q)) - - rhs_vf(strxb + 2)%sf(k, l, q) = rhs_vf(strxb + 2)%sf(k, l, q) + rho_K_field(k, l, q)* & - (q_prim_vf(strxb + 4)%sf(k, l, q)*dv_dz_hypo(k, l, q) + & - q_prim_vf(strxb + 4)%sf(k, l, q)*dv_dz_hypo(k, l, q) - & - q_prim_vf(strxb + 2)%sf(k, l, q)*dw_dz_hypo(k, l, q) - & - 2._wp*G_K_field(k, l, q)*(1._wp/3._wp)*dw_dz_hypo(k, l, q)) - - rhs_vf(strxb + 3)%sf(k, l, q) = rhs_vf(strxb + 3)%sf(k, l, q) + rho_K_field(k, l, q)* & - (q_prim_vf(strxb + 3)%sf(k, l, q)*du_dx_hypo(k, l, q) + & - q_prim_vf(strxb)%sf(k, l, q)*dw_dx_hypo(k, l, q) - & - q_prim_vf(strxb + 3)%sf(k, l, q)*du_dx_hypo(k, l, q) + & - q_prim_vf(strxb + 4)%sf(k, l, q)*du_dy_hypo(k, l, q) + & - q_prim_vf(strxb + 1)%sf(k, l, q)*dw_dy_hypo(k, l, q) - & - q_prim_vf(strxb + 3)%sf(k, l, q)*dv_dy_hypo(k, l, q) + & - q_prim_vf(strxb + 5)%sf(k, l, q)*du_dz_hypo(k, l, q) + & - q_prim_vf(strxb + 3)%sf(k, l, q)*dw_dz_hypo(k, l, q) - & - q_prim_vf(strxb + 3)%sf(k, l, q)*dw_dz_hypo(k, l, q) + & - 2._wp*G_K_field(k, l, q)*(1._wp/2._wp)*(du_dz_hypo(k, l, q) + & - dw_dx_hypo(k, l, q))) - - rhs_vf(strxb + 4)%sf(k, l, q) = rhs_vf(strxb + 4)%sf(k, l, q) + rho_K_field(k, l, q)* & - (q_prim_vf(strxb + 3)%sf(k, l, q)*dv_dx_hypo(k, l, q) + & - q_prim_vf(strxb + 1)%sf(k, l, q)*dw_dx_hypo(k, l, q) - & - q_prim_vf(strxb + 4)%sf(k, l, q)*du_dx_hypo(k, l, q) + & - q_prim_vf(strxb + 4)%sf(k, l, q)*dv_dy_hypo(k, l, q) + & - q_prim_vf(strxb + 2)%sf(k, l, q)*dw_dy_hypo(k, l, q) - & - q_prim_vf(strxb + 4)%sf(k, l, q)*dv_dy_hypo(k, l, q) + & - q_prim_vf(strxb + 5)%sf(k, l, q)*dv_dz_hypo(k, l, q) + & - q_prim_vf(strxb + 4)%sf(k, l, q)*dw_dz_hypo(k, l, q) - & - q_prim_vf(strxb + 4)%sf(k, l, q)*dw_dz_hypo(k, l, q) + & - 2._wp*G_K_field(k, l, q)*(1._wp/2._wp)*(dv_dz_hypo(k, l, q) + & - dw_dy_hypo(k, l, q))) - - rhs_vf(strxe)%sf(k, l, q) = rhs_vf(strxe)%sf(k, l, q) + rho_K_field(k, l, q)* & - (q_prim_vf(strxe - 2)%sf(k, l, q)*dw_dx_hypo(k, l, q) + & - q_prim_vf(strxe - 2)%sf(k, l, q)*dw_dx_hypo(k, l, q) - & - q_prim_vf(strxe)%sf(k, l, q)*du_dx_hypo(k, l, q) + & - q_prim_vf(strxe - 1)%sf(k, l, q)*dw_dy_hypo(k, l, q) + & - q_prim_vf(strxe - 1)%sf(k, l, q)*dw_dy_hypo(k, l, q) - & - q_prim_vf(strxe)%sf(k, l, q)*dv_dy_hypo(k, l, q) + & - q_prim_vf(strxe)%sf(k, l, q)*dw_dz_hypo(k, l, q) + & - q_prim_vf(strxe)%sf(k, l, q)*dw_dz_hypo(k, l, q) - & - q_prim_vf(strxe)%sf(k, l, q)*dw_dz_hypo(k, l, q) + & - 2._wp*G_K_field(k, l, q)*(dw_dz_hypo(k, l, q) - (1._wp/3._wp)* & - (du_dx_hypo(k, l, q) + & - dv_dy_hypo(k, l, q) + & - dw_dz_hypo(k, l, q)))) + rhs_vf(strxb)%sf(k, l, q) = rhs_vf(strxb)%sf(k, l, q) + rho_K_field(k, l, q)*(q_prim_vf(strxb + 3)%sf(k, & + & l, q)*du_dz_hypo(k, l, q) + q_prim_vf(strxb + 3)%sf(k, l, q)*du_dz_hypo(k, l, & + & q) - q_prim_vf(strxb)%sf(k, l, q)*dw_dz_hypo(k, l, q) - 2._wp*G_K_field(k, l, & + & q)*(1._wp/3._wp)*dw_dz_hypo(k, l, q)) + + rhs_vf(strxb + 1)%sf(k, l, q) = rhs_vf(strxb + 1)%sf(k, l, q) + rho_K_field(k, l, & + & q)*(q_prim_vf(strxb + 4)%sf(k, l, q)*du_dz_hypo(k, l, q) + q_prim_vf(strxb + 3)%sf(k, l, & + & q)*dv_dz_hypo(k, l, q) - q_prim_vf(strxb + 1)%sf(k, l, q)*dw_dz_hypo(k, l, q)) + + rhs_vf(strxb + 2)%sf(k, l, q) = rhs_vf(strxb + 2)%sf(k, l, q) + rho_K_field(k, l, & + & q)*(q_prim_vf(strxb + 4)%sf(k, l, q)*dv_dz_hypo(k, l, q) + q_prim_vf(strxb + 4)%sf(k, l, & + & q)*dv_dz_hypo(k, l, q) - q_prim_vf(strxb + 2)%sf(k, l, q)*dw_dz_hypo(k, l, & + & q) - 2._wp*G_K_field(k, l, q)*(1._wp/3._wp)*dw_dz_hypo(k, l, q)) + + rhs_vf(strxb + 3)%sf(k, l, q) = rhs_vf(strxb + 3)%sf(k, l, q) + rho_K_field(k, l, & + & q)*(q_prim_vf(strxb + 3)%sf(k, l, q)*du_dx_hypo(k, l, q) + q_prim_vf(strxb)%sf(k, l, & + & q)*dw_dx_hypo(k, l, q) - q_prim_vf(strxb + 3)%sf(k, l, q)*du_dx_hypo(k, l, & + & q) + q_prim_vf(strxb + 4)%sf(k, l, q)*du_dy_hypo(k, l, q) + q_prim_vf(strxb + 1)%sf(k, l, & + & q)*dw_dy_hypo(k, l, q) - q_prim_vf(strxb + 3)%sf(k, l, q)*dv_dy_hypo(k, l, & + & q) + q_prim_vf(strxb + 5)%sf(k, l, q)*du_dz_hypo(k, l, q) + q_prim_vf(strxb + 3)%sf(k, l, & + & q)*dw_dz_hypo(k, l, q) - q_prim_vf(strxb + 3)%sf(k, l, q)*dw_dz_hypo(k, l, & + & q) + 2._wp*G_K_field(k, l, q)*(1._wp/2._wp)*(du_dz_hypo(k, l, q) + dw_dx_hypo(k, l, q))) + + rhs_vf(strxb + 4)%sf(k, l, q) = rhs_vf(strxb + 4)%sf(k, l, q) + rho_K_field(k, l, & + & q)*(q_prim_vf(strxb + 3)%sf(k, l, q)*dv_dx_hypo(k, l, q) + q_prim_vf(strxb + 1)%sf(k, l, & + & q)*dw_dx_hypo(k, l, q) - q_prim_vf(strxb + 4)%sf(k, l, q)*du_dx_hypo(k, l, & + & q) + q_prim_vf(strxb + 4)%sf(k, l, q)*dv_dy_hypo(k, l, q) + q_prim_vf(strxb + 2)%sf(k, l, & + & q)*dw_dy_hypo(k, l, q) - q_prim_vf(strxb + 4)%sf(k, l, q)*dv_dy_hypo(k, l, & + & q) + q_prim_vf(strxb + 5)%sf(k, l, q)*dv_dz_hypo(k, l, q) + q_prim_vf(strxb + 4)%sf(k, l, & + & q)*dw_dz_hypo(k, l, q) - q_prim_vf(strxb + 4)%sf(k, l, q)*dw_dz_hypo(k, l, & + & q) + 2._wp*G_K_field(k, l, q)*(1._wp/2._wp)*(dv_dz_hypo(k, l, q) + dw_dy_hypo(k, l, q))) + + rhs_vf(strxe)%sf(k, l, q) = rhs_vf(strxe)%sf(k, l, q) + rho_K_field(k, l, q)*(q_prim_vf(strxe - 2)%sf(k, & + & l, q)*dw_dx_hypo(k, l, q) + q_prim_vf(strxe - 2)%sf(k, l, q)*dw_dx_hypo(k, l, & + & q) - q_prim_vf(strxe)%sf(k, l, q)*du_dx_hypo(k, l, q) + q_prim_vf(strxe - 1)%sf(k, l, & + & q)*dw_dy_hypo(k, l, q) + q_prim_vf(strxe - 1)%sf(k, l, q)*dw_dy_hypo(k, l, & + & q) - q_prim_vf(strxe)%sf(k, l, q)*dv_dy_hypo(k, l, q) + q_prim_vf(strxe)%sf(k, l, & + & q)*dw_dz_hypo(k, l, q) + q_prim_vf(strxe)%sf(k, l, q)*dw_dz_hypo(k, l, & + & q) - q_prim_vf(strxe)%sf(k, l, q)*dw_dz_hypo(k, l, q) + 2._wp*G_K_field(k, l, q)*(dw_dz_hypo(k, & + & l, q) - (1._wp/3._wp)*(du_dx_hypo(k, l, q) + dv_dy_hypo(k, l, q) + dw_dz_hypo(k, l, q)))) end do end do end do @@ -341,37 +299,33 @@ contains end if if (cyl_coord .and. idir == 2) then - $:GPU_PARALLEL_LOOP(collapse=3) do q = 0, p do l = 0, n do k = 0, m ! S_xx -= rho * v/r * (tau_xx + 2/3*G) - rhs_vf(strxb)%sf(k, l, q) = rhs_vf(strxb)%sf(k, l, q) - & - rho_K_field(k, l, q)*q_prim_vf(momxb + 1)%sf(k, l, q)/y_cc(l)* & - (q_prim_vf(strxb)%sf(k, l, q) + (2._wp/3._wp)*G_K_field(k, l, q)) ! tau_xx + 2/3*G + rhs_vf(strxb)%sf(k, l, q) = rhs_vf(strxb)%sf(k, l, q) - rho_K_field(k, l, q)*q_prim_vf(momxb + 1)%sf(k, & + & l, q)/y_cc(l)*(q_prim_vf(strxb)%sf(k, l, q) + (2._wp/3._wp)*G_K_field(k, l, q)) ! tau_xx + 2/3*G ! S_xr -= rho * v/r * tau_xr - rhs_vf(strxb + 1)%sf(k, l, q) = rhs_vf(strxb + 1)%sf(k, l, q) - & - rho_K_field(k, l, q)*q_prim_vf(momxb + 1)%sf(k, l, q)/y_cc(l)* & - q_prim_vf(strxb + 1)%sf(k, l, q) ! tau_xx + rhs_vf(strxb + 1)%sf(k, l, q) = rhs_vf(strxb + 1)%sf(k, l, q) - rho_K_field(k, l, & + & q)*q_prim_vf(momxb + 1)%sf(k, l, q)/y_cc(l)*q_prim_vf(strxb + 1)%sf(k, l, q) ! tau_xx ! S_rr -= rho * v/r * (tau_rr + 2/3*G) - rhs_vf(strxb + 2)%sf(k, l, q) = rhs_vf(strxb + 2)%sf(k, l, q) - & - rho_K_field(k, l, q)*q_prim_vf(momxb + 1)%sf(k, l, q)/y_cc(l)* & - (q_prim_vf(strxb + 2)%sf(k, l, q) + (2._wp/3._wp)*G_K_field(k, l, q)) ! tau_rr + 2/3*G + rhs_vf(strxb + 2)%sf(k, l, q) = rhs_vf(strxb + 2)%sf(k, l, q) - rho_K_field(k, l, & + & q)*q_prim_vf(momxb + 1)%sf(k, l, q)/y_cc(l)*(q_prim_vf(strxb + 2)%sf(k, l, & + & q) + (2._wp/3._wp)*G_K_field(k, l, q)) ! tau_rr + 2/3*G ! S_thetatheta += rho * ( -(tau_thetatheta + 2/3*G)*(du/dx + dv/dr + v/r) + 2*(tau_thetatheta + G)*v/r ) - rhs_vf(strxb + 3)%sf(k, l, q) = rhs_vf(strxb + 3)%sf(k, l, q) + & - rho_K_field(k, l, q)*( & - -(q_prim_vf(strxb + 3)%sf(k, l, q) + (2._wp/3._wp)*G_K_field(k, l, q))* & - (du_dx_hypo(k, l, q) + dv_dy_hypo(k, l, q) + q_prim_vf(momxb + 1)%sf(k, l, q)/y_cc(l)) & - + 2._wp*(q_prim_vf(strxb + 3)%sf(k, l, q) + G_K_field(k, l, q))*q_prim_vf(momxb + 1)%sf(k, l, q)/y_cc(l)) + rhs_vf(strxb + 3)%sf(k, l, q) = rhs_vf(strxb + 3)%sf(k, l, q) + rho_K_field(k, l, & + & q)*(-(q_prim_vf(strxb + 3)%sf(k, l, q) + (2._wp/3._wp)*G_K_field(k, l, q))*(du_dx_hypo(k, l, & + & q) + dv_dy_hypo(k, l, q) + q_prim_vf(momxb + 1)%sf(k, l, & + & q)/y_cc(l)) + 2._wp*(q_prim_vf(strxb + 3)%sf(k, l, q) + G_K_field(k, l, & + & q))*q_prim_vf(momxb + 1)%sf(k, l, q)/y_cc(l)) end do end do end do $:END_GPU_PARALLEL_LOOP() - end if end subroutine s_compute_hypoelastic_rhs @@ -397,39 +351,38 @@ contains !> @brief Computes the continuum damage source term from the principal stress state. subroutine s_compute_damage_state(q_cons_vf, rhs_vf) - type(scalar_field), dimension(sys_size), intent(in) :: q_cons_vf + type(scalar_field), dimension(sys_size), intent(in) :: q_cons_vf type(scalar_field), dimension(sys_size), intent(inout) :: rhs_vf - - real(wp) :: tau_p ! principal stress - real(wp) :: tau_xx, tau_xy, tau_yy, tau_zz, tau_yz, tau_xz - real(wp) :: I1, I2, I3, argument, phi, sqrt_term_1, sqrt_term_2, temp - integer :: q, l, k + real(wp) :: tau_p ! principal stress + real(wp) :: tau_xx, tau_xy, tau_yy, tau_zz, tau_yz, tau_xz + real(wp) :: I1, I2, I3, argument, phi, sqrt_term_1, sqrt_term_2, temp + integer :: q, l, k if (n == 0) then l = 0; q = 0 $:GPU_PARALLEL_LOOP() do k = 0, m - rhs_vf(damage_idx)%sf(k, l, q) = (alpha_bar*max(abs(real(q_cons_vf(stress_idx%beg)%sf(k, l, q), kind=wp)) - tau_star, 0._wp))**cont_damage_s + rhs_vf(damage_idx)%sf(k, l, q) = (alpha_bar*max(abs(real(q_cons_vf(stress_idx%beg)%sf(k, l, q), & + & kind=wp)) - tau_star, 0._wp))**cont_damage_s end do $:END_GPU_PARALLEL_LOOP() - elseif (p == 0) then + else if (p == 0) then q = 0 $:GPU_PARALLEL_LOOP(collapse=2, private='[tau_p]') do l = 0, n do k = 0, m ! Maximum principal stress - tau_p = 0.5_wp*(q_cons_vf(stress_idx%beg)%sf(k, l, q) + & - q_cons_vf(stress_idx%beg + 2)%sf(k, l, q)) + & - sqrt((q_cons_vf(stress_idx%beg)%sf(k, l, q) - & - q_cons_vf(stress_idx%beg + 2)%sf(k, l, q))**2.0_wp + & - 4._wp*q_cons_vf(stress_idx%beg + 1)%sf(k, l, q)**2.0_wp)/2._wp + tau_p = 0.5_wp*(q_cons_vf(stress_idx%beg)%sf(k, l, q) + q_cons_vf(stress_idx%beg + 2)%sf(k, l, & + & q)) + sqrt((q_cons_vf(stress_idx%beg)%sf(k, l, q) - q_cons_vf(stress_idx%beg + 2)%sf(k, l, & + & q))**2.0_wp + 4._wp*q_cons_vf(stress_idx%beg + 1)%sf(k, l, q)**2.0_wp)/2._wp rhs_vf(damage_idx)%sf(k, l, q) = (alpha_bar*max(tau_p - tau_star, 0._wp))**cont_damage_s end do end do $:END_GPU_PARALLEL_LOOP() else - $:GPU_PARALLEL_LOOP(collapse=3, private='[tau_xx, tau_xy, tau_yy, tau_xz, tau_yz, tau_zz, I1, I2, I3, temp, sqrt_term_1, sqrt_term_2, argument, phi, tau_p]') + $:GPU_PARALLEL_LOOP(collapse=3, private='[tau_xx, tau_xy, tau_yy, tau_xz, tau_yz, tau_zz, I1, I2, I3, temp, & + & sqrt_term_1, sqrt_term_2, argument, phi, tau_p]') do q = 0, p do l = 0, n do k = 0, m @@ -442,17 +395,15 @@ contains ! Invariants of the stress tensor I1 = tau_xx + tau_yy + tau_zz - I2 = tau_xx*tau_yy + tau_xx*tau_zz + tau_yy*tau_zz - & - (tau_xy**2.0_wp + tau_xz**2.0_wp + tau_yz**2.0_wp) - I3 = tau_xx*tau_yy*tau_zz + 2.0_wp*tau_xy*tau_xz*tau_yz - & - tau_xx*tau_yz**2.0_wp - tau_yy*tau_xz**2.0_wp - tau_zz*tau_xy**2.0_wp + I2 = tau_xx*tau_yy + tau_xx*tau_zz + tau_yy*tau_zz - (tau_xy**2.0_wp + tau_xz**2.0_wp + tau_yz**2.0_wp) + I3 = tau_xx*tau_yy*tau_zz + 2.0_wp*tau_xy*tau_xz*tau_yz - tau_xx*tau_yz**2.0_wp - tau_yy*tau_xz**2.0_wp & + & - tau_zz*tau_xy**2.0_wp ! Maximum principal stress temp = I1**2.0_wp - 3.0_wp*I2 sqrt_term_1 = sqrt(max(temp, 0.0_wp)) - if (sqrt_term_1 > verysmall) then ! Avoid 0/0 - argument = (2.0_wp*I1*I1*I1 - 9.0_wp*I1*I2 + 27.0_wp*I3)/ & - (2.0_wp*sqrt_term_1*sqrt_term_1*sqrt_term_1) + if (sqrt_term_1 > verysmall) then ! Avoid 0/0 + argument = (2.0_wp*I1*I1*I1 - 9.0_wp*I1*I2 + 27.0_wp*I3)/(2.0_wp*sqrt_term_1*sqrt_term_1*sqrt_term_1) if (argument > 1.0_wp) argument = 1.0_wp if (argument < -1.0_wp) argument = -1.0_wp phi = acos(argument) diff --git a/src/simulation/m_ib_patches.fpp b/src/simulation/m_ib_patches.fpp index 12fcccbf3c..abc05543a0 100644 --- a/src/simulation/m_ib_patches.fpp +++ b/src/simulation/m_ib_patches.fpp @@ -12,49 +12,42 @@ !> @brief Immersed boundary patch geometry constructors for 2D and 3D shapes module m_ib_patches - use m_model ! Subroutine(s) related to STL files - - use m_derived_types ! Definitions of the derived types - - use m_global_parameters !< Definitions of the global parameters - - use m_helper_basic !< Functions to compare floating point numbers - + use m_model ! Subroutine(s) related to STL files + use m_derived_types ! Definitions of the derived types + use m_global_parameters !< Definitions of the global parameters + use m_helper_basic !< Functions to compare floating point numbers use m_helper - use m_mpi_common implicit none - private; public :: s_apply_ib_patches, s_update_ib_rotation_matrix, f_convert_cyl_to_cart, s_instantiate_STL_models, s_decode_patch_periodicity + private; public :: s_apply_ib_patches, s_update_ib_rotation_matrix, f_convert_cyl_to_cart, s_instantiate_STL_models, & + & s_decode_patch_periodicity real(wp) :: x_centroid, y_centroid, z_centroid real(wp) :: length_x, length_y, length_z $:GPU_DECLARE(create='[x_centroid, y_centroid, z_centroid]') $:GPU_DECLARE(create='[length_x, length_y, length_z]') - integer :: smooth_patch_id + integer :: smooth_patch_id real(wp) :: smooth_coeff $:GPU_DECLARE(create='[smooth_patch_id, smooth_coeff]') - !! These variables are analogous in both meaning and use to the similarly - !! named components in the ic_patch_parameters type (see m_derived_types.f90 - !! for additional details). They are employed as a means to more concisely - !! perform the actions necessary to lay out a particular patch on the grid. + !! These variables are analogous in both meaning and use to the similarly named components in the ic_patch_parameters type (see + !! m_derived_types.f90 for additional details). They are employed as a means to more concisely perform the actions necessary to + !! lay out a particular patch on the grid. real(wp) :: cart_x, cart_y, cart_z - real(wp) :: sph_phi !< + real(wp) :: sph_phi $:GPU_DECLARE(create='[cart_x, cart_y, cart_z, sph_phi]') - !! Variables to be used to hold cell locations in Cartesian coordinates if - !! 3D simulation is using cylindrical coordinates + !! Variables to be used to hold cell locations in Cartesian coordinates if 3D simulation is using cylindrical coordinates type(bounds_info) :: x_boundary, y_boundary, z_boundary $:GPU_DECLARE(create='[x_boundary, y_boundary, z_boundary]') - !! These variables combine the centroid and length parameters associated with - !! a particular patch to yield the locations of the patch boundaries in the - !! x-, y- and z-coordinate directions. They are used as a means to concisely - !! perform the actions necessary to lay out a particular patch on the grid. + !! These variables combine the centroid and length parameters associated with a particular patch to yield the locations of the + !! patch boundaries in the x-, y- and z-coordinate directions. They are used as a means to concisely perform the actions + !! necessary to lay out a particular patch on the grid. - character(len=5) :: istr ! string to store int to string result for error checking + character(len=5) :: istr ! string to store int to string result for error checking contains @@ -62,13 +55,12 @@ contains impure subroutine s_apply_ib_patches(ib_markers) type(integer_field), intent(inout) :: ib_markers - - integer :: i, xp, yp, zp ! iterators - integer :: xp_lower, xp_upper, yp_lower, yp_upper, zp_lower, zp_upper ! periodic bounds + integer :: i, xp, yp, zp ! iterators + integer :: xp_lower, xp_upper, yp_lower, yp_upper, zp_lower, zp_upper ! periodic bounds ! 3D Patch Geometries - if (p > 0) then + if (p > 0) then !> IB Patches !> @{ call s_get_periodicities(xp_lower, xp_upper, yp_lower, yp_upper, zp_lower, zp_upper) @@ -78,13 +70,13 @@ contains do i = 1, num_ibs if (patch_ib(i)%geometry == 8) then call s_ib_sphere(i, ib_markers, xp, yp, zp) - elseif (patch_ib(i)%geometry == 9) then + else if (patch_ib(i)%geometry == 9) then call s_ib_cuboid(i, ib_markers, xp, yp, zp) - elseif (patch_ib(i)%geometry == 10) then + else if (patch_ib(i)%geometry == 10) then call s_ib_cylinder(i, ib_markers, xp, yp, zp) - elseif (patch_ib(i)%geometry == 11) then + else if (patch_ib(i)%geometry == 11) then call s_ib_3D_airfoil(i, ib_markers, xp, yp, zp) - elseif (patch_ib(i)%geometry == 12) then + else if (patch_ib(i)%geometry == 12) then call s_ib_3d_model(i, ib_markers, xp, yp, zp) end if end do @@ -94,8 +86,7 @@ contains !> @} ! 2D Patch Geometries - elseif (n > 0) then - + else if (n > 0) then !> IB Patches !> @{ call s_get_periodicities(xp_lower, xp_upper, yp_lower, yp_upper) @@ -104,45 +95,41 @@ contains do i = 1, num_ibs if (patch_ib(i)%geometry == 2) then call s_ib_circle(i, ib_markers, xp, yp) - elseif (patch_ib(i)%geometry == 3) then + else if (patch_ib(i)%geometry == 3) then call s_ib_rectangle(i, ib_markers, xp, yp) - elseif (patch_ib(i)%geometry == 4) then + else if (patch_ib(i)%geometry == 4) then call s_ib_airfoil(i, ib_markers, xp, yp) - elseif (patch_ib(i)%geometry == 5) then + else if (patch_ib(i)%geometry == 5) then call s_ib_model(i, ib_markers, xp, yp) - elseif (patch_ib(i)%geometry == 6) then + else if (patch_ib(i)%geometry == 6) then call s_ib_ellipse(i, ib_markers, xp, yp) end if end do end do end do !> @} - end if end subroutine s_apply_ib_patches - !> The circular patch is a 2D geometry that may be used, for - !! example, in creating a bubble or a droplet. The geometry - !! of the patch is well-defined when its centroid and radius - !! are provided. Note that the circular patch DOES allow for - !! the smoothing of its boundary. - !! @param patch_id is the patch identifier - !! @param ib_markers Array to track patch ids - !! @param ib True if this patch is an immersed boundary + !> The circular patch is a 2D geometry that may be used, for example, in creating a bubble or a droplet. The geometry of the + !! patch is well-defined when its centroid and radius are provided. Note that the circular patch DOES allow for the smoothing of + !! its boundary. + !! @param patch_id is the patch identifier + !! @param ib_markers Array to track patch ids + !! @param ib True if this patch is an immersed boundary subroutine s_ib_circle(patch_id, ib_markers, xp, yp) - integer, intent(in) :: patch_id - integer, intent(in) :: xp, yp !< integers containing the periodicity projection information + integer, intent(in) :: patch_id + integer, intent(in) :: xp, yp !< integers containing the periodicity projection information type(integer_field), intent(inout) :: ib_markers + real(wp), dimension(1:2) :: center + real(wp) :: radius + integer :: i, j, il, ir, jl, jr !< Generic loop iterators + integer :: encoded_patch_id - real(wp), dimension(1:2) :: center - real(wp) :: radius - integer :: i, j, il, ir, jl, jr !< Generic loop iterators - integer :: encoded_patch_id + ! Transferring the circular patch's radius, centroid, smearing patch identity and smearing coefficient information - ! Transferring the circular patch's radius, centroid, smearing patch - ! identity and smearing coefficient information center(1) = patch_ib(patch_id)%x_centroid + real(xp, wp)*(glb_bounds(1)%end - glb_bounds(1)%beg) center(2) = patch_ib(patch_id)%y_centroid + real(yp, wp)*(glb_bounds(2)%end - glb_bounds(2)%beg) radius = patch_ib(patch_id)%radius @@ -158,18 +145,13 @@ contains call get_bounding_indices(center(1) - radius, center(1) + radius, x_cc, il, ir) call get_bounding_indices(center(2) - radius, center(2) + radius, y_cc, jl, jr) - ! Checking whether the circle covers a particular cell in the domain - ! and verifying whether the current patch has permission to write to - ! that cell. If both queries check out, the primitive variables of - ! the current patch are assigned to this cell. + ! Checking whether the circle covers a particular cell in the domain and verifying whether the current patch has permission + ! to write to that cell. If both queries check out, the primitive variables of the current patch are assigned to this cell. - $:GPU_PARALLEL_LOOP(private='[i,j]',& - & copyin='[encoded_patch_id,center,radius]', collapse=2) + $:GPU_PARALLEL_LOOP(private='[i, j]', copyin='[encoded_patch_id, center, radius]', collapse=2) do j = jl, jr do i = il, ir - if ((x_cc(i) - center(1))**2 & - + (y_cc(j) - center(2))**2 <= radius**2) & - then + if ((x_cc(i) - center(1))**2 + (y_cc(j) - center(2))**2 <= radius**2) then ib_markers%sf(i, j, 0) = encoded_patch_id end if end do @@ -183,19 +165,17 @@ contains !! @param ib_markers Array to track patch ids subroutine s_ib_airfoil(patch_id, ib_markers, xp, yp) - integer, intent(in) :: patch_id + integer, intent(in) :: patch_id type(integer_field), intent(inout) :: ib_markers - integer, intent(in) :: xp, yp !< integers containing the periodicity projection information - - real(wp) :: f, ca_in, pa, ma, ta - real(wp) :: xa, yt, xu, yu, xl, yl, xc, yc, dycdxc, sin_c, cos_c - integer :: i, j, k, il, ir, jl, jr - integer :: Np1, Np2 - integer :: encoded_patch_id - - real(wp), dimension(1:3) :: xy_local, offset !< x and y coordinates in local IB frame - real(wp), dimension(1:2) :: center !< x and y coordinates in local IB frame - real(wp), dimension(1:3, 1:3) :: inverse_rotation + integer, intent(in) :: xp, yp !< integers containing the periodicity projection information + real(wp) :: f, ca_in, pa, ma, ta + real(wp) :: xa, yt, xu, yu, xl, yl, xc, yc, dycdxc, sin_c, cos_c + integer :: i, j, k, il, ir, jl, jr + integer :: Np1, Np2 + integer :: encoded_patch_id + real(wp), dimension(1:3) :: xy_local, offset !< x and y coordinates in local IB frame + real(wp), dimension(1:2) :: center !< x and y coordinates in local IB frame + real(wp), dimension(1:3,1:3) :: inverse_rotation center(1) = patch_ib(patch_id)%x_centroid + real(xp, wp)*(glb_bounds(1)%end - glb_bounds(1)%beg) center(2) = patch_ib(patch_id)%y_centroid + real(yp, wp)*(glb_bounds(2)%end - glb_bounds(2)%beg) @@ -203,7 +183,7 @@ contains pa = patch_ib(patch_id)%p ma = patch_ib(patch_id)%m ta = patch_ib(patch_id)%t - inverse_rotation(:, :) = patch_ib(patch_id)%rotation_matrix_inverse(:, :) + inverse_rotation(:,:) = patch_ib(patch_id)%rotation_matrix_inverse(:,:) offset(:) = patch_ib(patch_id)%centroid_offset(:) Np1 = int((pa*ca_in/dx(0))*20) @@ -223,7 +203,8 @@ contains airfoil_grid_l(1)%y = 0._wp do i = 1, Np1 + Np2 - 1 - ! TODO :: This allocated the upper and lower airfoil arrays, and does not need to be performed each time the IB markers are updated. Place this as a separate subroutine. + ! TODO :: This allocated the upper and lower airfoil arrays, and does not need to be performed each time the IB + ! markers are updated. Place this as a separate subroutine. if (i <= Np1) then xc = i*(pa*ca_in/Np1) xa = xc/ca_in @@ -257,7 +238,6 @@ contains airfoil_grid_l(i + 1)%x = xl airfoil_grid_l(i + 1)%y = yl - end do airfoil_grid_u(Np)%x = ca_in @@ -266,8 +246,7 @@ contains airfoil_grid_l(Np)%x = ca_in airfoil_grid_l(Np)%y = 0._wp - $:GPU_UPDATE(device='[airfoil_grid_l,airfoil_grid_u]') - + $:GPU_UPDATE(device='[airfoil_grid_l, airfoil_grid_u]') end if ! encode the periodicity information into the patch_id @@ -282,13 +261,13 @@ contains call get_bounding_indices(center(1) - ca_in, center(1) + ca_in, x_cc, il, ir) call get_bounding_indices(center(2) - ca_in, center(2) + ca_in, y_cc, jl, jr) - $:GPU_PARALLEL_LOOP(private='[i,j,xy_local,k,f]', & - & copyin='[encoded_patch_id,center,inverse_rotation,offset,ma,ca_in,airfoil_grid_u,airfoil_grid_l]', collapse=2) + $:GPU_PARALLEL_LOOP(private='[i, j, xy_local, k, f]', copyin='[encoded_patch_id, center, inverse_rotation, offset, ma, & + & ca_in, airfoil_grid_u, airfoil_grid_l]', collapse=2) do j = jl, jr do i = il, ir - xy_local = [x_cc(i) - center(1), y_cc(j) - center(2), 0._wp] ! get coordinate frame centered on IB - xy_local = matmul(inverse_rotation, xy_local) ! rotate the frame into the IB's coordinates - xy_local = xy_local - offset ! airfoils are a patch that require a centroid offset + xy_local = [x_cc(i) - center(1), y_cc(j) - center(2), 0._wp] ! get coordinate frame centered on IB + xy_local = matmul(inverse_rotation, xy_local) ! rotate the frame into the IB's coordinates + xy_local = xy_local - offset ! airfoils are a patch that require a centroid offset if (xy_local(1) >= 0._wp .and. xy_local(1) <= ca_in) then xa = xy_local(1)/ca_in @@ -350,15 +329,13 @@ contains integer, intent(in) :: patch_id type(integer_field), intent(inout) :: ib_markers - integer, intent(in) :: xp, yp, zp !< integers containing the periodicity projection information - + integer, intent(in) :: xp, yp, zp !< integers containing the periodicity projection information real(wp) :: lz, z_max, z_min, f, ca_in, pa, ma, ta, xa, yt, xu, yu, xl, yl, xc, yc, dycdxc, sin_c, cos_c integer :: i, j, k, l, il, ir, jl, jr, ll, lr integer :: Np1, Np2 integer :: encoded_patch_id - - real(wp), dimension(1:3) :: xyz_local, center, offset !< x, y, z coordinates in local IB frame - real(wp), dimension(1:3, 1:3) :: inverse_rotation + real(wp), dimension(1:3) :: xyz_local, center, offset !< x, y, z coordinates in local IB frame + real(wp), dimension(1:3,1:3) :: inverse_rotation center(1) = patch_ib(patch_id)%x_centroid + real(xp, wp)*(glb_bounds(1)%end - glb_bounds(1)%beg) center(2) = patch_ib(patch_id)%y_centroid + real(yp, wp)*(glb_bounds(2)%end - glb_bounds(2)%beg) @@ -368,7 +345,7 @@ contains pa = patch_ib(patch_id)%p ma = patch_ib(patch_id)%m ta = patch_ib(patch_id)%t - inverse_rotation(:, :) = patch_ib(patch_id)%rotation_matrix_inverse(:, :) + inverse_rotation(:,:) = patch_ib(patch_id)%rotation_matrix_inverse(:,:) offset(:) = patch_ib(patch_id)%centroid_offset(:) z_max = lz/2 @@ -380,7 +357,6 @@ contains $:GPU_UPDATE(device='[Np]') if (.not. allocated(airfoil_grid_u)) then - @:ALLOCATE(airfoil_grid_u(1:Np)) @:ALLOCATE(airfoil_grid_l(1:Np)) @@ -424,7 +400,6 @@ contains airfoil_grid_l(i + 1)%x = xl airfoil_grid_l(i + 1)%y = yl - end do airfoil_grid_u(Np)%x = ca_in @@ -433,7 +408,7 @@ contains airfoil_grid_l(Np)%x = ca_in airfoil_grid_l(Np)%y = 0._wp - $:GPU_UPDATE(device='[airfoil_grid_l,airfoil_grid_u]') + $:GPU_UPDATE(device='[airfoil_grid_l, airfoil_grid_u]') end if ! encode the periodicity information into the patch_id @@ -451,17 +426,17 @@ contains call get_bounding_indices(center(2) - ca_in, center(2) + ca_in, y_cc, jl, jr) call get_bounding_indices(center(3) - ca_in, center(3) + ca_in, z_cc, ll, lr) - $:GPU_PARALLEL_LOOP(private='[i,j,l,xyz_local,k,f]',& - & copyin='[encoded_patch_id,center,inverse_rotation,offset,ma,ca_in,airfoil_grid_u,airfoil_grid_l,z_min,z_max]', collapse=3) + $:GPU_PARALLEL_LOOP(private='[i, j, l, xyz_local, k, f]', copyin='[encoded_patch_id, center, inverse_rotation, offset, & + & ma, ca_in, airfoil_grid_u, airfoil_grid_l, z_min, z_max]', collapse=3) do l = ll, lr do j = jl, jr do i = il, ir - xyz_local = [x_cc(i) - center(1), y_cc(j) - center(2), z_cc(l) - center(3)] ! get coordinate frame centered on IB - xyz_local = matmul(inverse_rotation, xyz_local) ! rotate the frame into the IB's coordinates - xyz_local = xyz_local - offset ! airfoils are a patch that require a centroid offset + xyz_local = [x_cc(i) - center(1), y_cc(j) - center(2), & + & z_cc(l) - center(3)] ! get coordinate frame centered on IB + xyz_local = matmul(inverse_rotation, xyz_local) ! rotate the frame into the IB's coordinates + xyz_local = xyz_local - offset ! airfoils are a patch that require a centroid offset if (xyz_local(3) >= z_min .and. xyz_local(3) <= z_max) then - if (xyz_local(1) >= 0._wp .and. xyz_local(1) <= ca_in) then if (xyz_local(2) >= 0._wp) then k = 1 @@ -470,7 +445,7 @@ contains end do if (f_approx_equal(airfoil_grid_u(k)%x, xyz_local(1))) then if (xyz_local(2) <= airfoil_grid_u(k)%y) then - !IB + ! IB ib_markers%sf(i, j, l) = encoded_patch_id end if else @@ -508,36 +483,32 @@ contains end subroutine s_ib_3D_airfoil - !> The rectangular patch is a 2D geometry that may be used, - !! for example, in creating a solid boundary, or pre-/post- - !! shock region, in alignment with the axes of the Cartesian - !! coordinate system. The geometry of such a patch is well- - !! defined when its centroid and lengths in the x- and y- - !! coordinate directions are provided. Please note that the - !! rectangular patch DOES NOT allow for the smoothing of its - !! boundaries. - !! @param patch_id is the patch identifier - !! @param ib_markers Array to track patch ids - !! @param ib True if this patch is an immersed boundary + !> The rectangular patch is a 2D geometry that may be used, for example, in creating a solid boundary, or pre-/post- shock + !! region, in alignment with the axes of the Cartesian coordinate system. The geometry of such a patch is well- defined when its + !! centroid and lengths in the x- and y- coordinate directions are provided. Please note that the rectangular patch DOES NOT + !! allow for the smoothing of its boundaries. + !! @param patch_id is the patch identifier + !! @param ib_markers Array to track patch ids + !! @param ib True if this patch is an immersed boundary subroutine s_ib_rectangle(patch_id, ib_markers, xp, yp) - integer, intent(in) :: patch_id + integer, intent(in) :: patch_id type(integer_field), intent(inout) :: ib_markers - integer, intent(in) :: xp, yp !< integers containing the periodicity projection information - - integer :: i, j, il, ir, jl, jr !< generic loop iterators - integer :: encoded_patch_id - real(wp) :: corner_distance !< Equation of state parameters - real(wp), dimension(1:3) :: xy_local !< x and y coordinates in local IB frame - real(wp), dimension(1:2) :: length, center !< x and y coordinates in local IB frame - real(wp), dimension(1:3, 1:3) :: inverse_rotation + integer, intent(in) :: xp, yp !< integers containing the periodicity projection information + integer :: i, j, il, ir, jl, jr !< generic loop iterators + integer :: encoded_patch_id + real(wp) :: corner_distance !< Equation of state parameters + real(wp), dimension(1:3) :: xy_local !< x and y coordinates in local IB frame + real(wp), dimension(1:2) :: length, center !< x and y coordinates in local IB frame + real(wp), dimension(1:3,1:3) :: inverse_rotation ! Transferring the rectangle's centroid and length information + center(1) = patch_ib(patch_id)%x_centroid + real(xp, wp)*(glb_bounds(1)%end - glb_bounds(1)%beg) center(2) = patch_ib(patch_id)%y_centroid + real(yp, wp)*(glb_bounds(2)%end - glb_bounds(2)%beg) length(1) = patch_ib(patch_id)%length_x length(2) = patch_ib(patch_id)%length_y - inverse_rotation(:, :) = patch_ib(patch_id)%rotation_matrix_inverse(:, :) + inverse_rotation(:,:) = patch_ib(patch_id)%rotation_matrix_inverse(:,:) ! encode the periodicity information into the patch_id call s_encode_patch_periodicity(patch_id, xp, yp, 0, encoded_patch_id) @@ -547,30 +518,25 @@ contains jl = -gp_layers - 1 ir = m + gp_layers + 1 jr = n + gp_layers + 1 - corner_distance = sqrt(dot_product(length, length))/2._wp ! maximum distance any marker can be from the center + corner_distance = sqrt(dot_product(length, length))/2._wp ! maximum distance any marker can be from the center call get_bounding_indices(center(1) - corner_distance, center(1) + corner_distance, x_cc, il, ir) call get_bounding_indices(center(2) - corner_distance, center(2) + corner_distance, y_cc, jl, jr) - ! Checking whether the rectangle covers a particular cell in the - ! domain and verifying whether the current patch has the permission - ! to write to that cell. If both queries check out, the primitive - ! variables of the current patch are assigned to this cell. - $:GPU_PARALLEL_LOOP(private='[i,j, xy_local]',& - & copyin='[encoded_patch_id,center,length,inverse_rotation,x_cc,y_cc]', collapse=2) + ! Checking whether the rectangle covers a particular cell in the domain and verifying whether the current patch has the + ! permission to write to that cell. If both queries check out, the primitive variables of the current patch are assigned to + ! this cell. + $:GPU_PARALLEL_LOOP(private='[i, j, xy_local]', copyin='[encoded_patch_id, center, length, inverse_rotation, x_cc, & + & y_cc]', collapse=2) do j = jl, jr do i = il, ir ! get the x and y coordinates in the local IB frame xy_local = [x_cc(i) - center(1), y_cc(j) - center(2), 0._wp] xy_local = matmul(inverse_rotation, xy_local) - if (-0.5_wp*length(1) <= xy_local(1) .and. & - 0.5_wp*length(1) >= xy_local(1) .and. & - -0.5_wp*length(2) <= xy_local(2) .and. & - 0.5_wp*length(2) >= xy_local(2)) then - + if (-0.5_wp*length(1) <= xy_local(1) .and. 0.5_wp*length(1) >= xy_local(1) .and. -0.5_wp*length(2) <= xy_local(2) & + & .and. 0.5_wp*length(2) >= xy_local(2)) then ! Updating the patch identities bookkeeping variable ib_markers%sf(i, j, 0) = encoded_patch_id - end if end do end do @@ -578,32 +544,30 @@ contains end subroutine s_ib_rectangle - !> The spherical patch is a 3D geometry that may be used, - !! for example, in creating a bubble or a droplet. The patch - !! geometry is well-defined when its centroid and radius are - !! provided. Please note that the spherical patch DOES allow - !! for the smoothing of its boundary. - !! @param patch_id is the patch identifier - !! @param ib_markers Array to track patch ids - !! @param ib True if this patch is an immersed boundary + !> The spherical patch is a 3D geometry that may be used, for example, in creating a bubble or a droplet. The patch geometry is + !! well-defined when its centroid and radius are provided. Please note that the spherical patch DOES allow for the smoothing of + !! its boundary. + !! @param patch_id is the patch identifier + !! @param ib_markers Array to track patch ids + !! @param ib True if this patch is an immersed boundary subroutine s_ib_sphere(patch_id, ib_markers, xp, yp, zp) - integer, intent(in) :: patch_id + integer, intent(in) :: patch_id type(integer_field), intent(inout) :: ib_markers - integer, intent(in) :: xp, yp, zp !< integers containing the periodicity projection information + integer, intent(in) :: xp, yp, zp !< integers containing the periodicity projection information ! Generic loop iterators - integer :: i, j, k - integer :: il, ir, jl, jr, kl, kr - integer :: encoded_patch_id - real(wp) :: radius + integer :: i, j, k + integer :: il, ir, jl, jr, kl, kr + integer :: encoded_patch_id + real(wp) :: radius real(wp), dimension(1:3) :: center - !! Variables to initialize the pressure field that corresponds to the - !! bubble-collapse test case found in Tiwari et al. (2013) + !! Variables to initialize the pressure field that corresponds to the bubble-collapse test case found in Tiwari et al. + !! (2013) + + ! Transferring spherical patch's radius, centroid, smoothing patch identity and smoothing coefficient information - ! Transferring spherical patch's radius, centroid, smoothing patch - ! identity and smoothing coefficient information center(1) = patch_ib(patch_id)%x_centroid + real(xp, wp)*(glb_bounds(1)%end - glb_bounds(1)%beg) center(2) = patch_ib(patch_id)%y_centroid + real(yp, wp)*(glb_bounds(2)%end - glb_bounds(2)%beg) center(3) = patch_ib(patch_id)%z_centroid + real(zp, wp)*(glb_bounds(3)%end - glb_bounds(3)%beg) @@ -623,12 +587,9 @@ contains call get_bounding_indices(center(2) - radius, center(2) + radius, y_cc, jl, jr) call get_bounding_indices(center(3) - radius, center(3) + radius, z_cc, kl, kr) - ! Checking whether the sphere covers a particular cell in the domain - ! and verifying whether the current patch has permission to write to - ! that cell. If both queries check out, the primitive variables of - ! the current patch are assigned to this cell. - $:GPU_PARALLEL_LOOP(private='[i,j,k,cart_y,cart_z]',& - & copyin='[encoded_patch_id,center,radius]', collapse=3) + ! Checking whether the sphere covers a particular cell in the domain and verifying whether the current patch has permission + ! to write to that cell. If both queries check out, the primitive variables of the current patch are assigned to this cell. + $:GPU_PARALLEL_LOOP(private='[i, j, k, cart_y, cart_z]', copyin='[encoded_patch_id, center, radius]', collapse=3) do k = kl, kr do j = jl, jr do i = il, ir @@ -640,9 +601,7 @@ contains cart_z = z_cc(k) end if ! Updating the patch identities bookkeeping variable - if (((x_cc(i) - center(1))**2 & - + (cart_y - center(2))**2 & - + (cart_z - center(3))**2 <= radius**2)) then + if (((x_cc(i) - center(1))**2 + (cart_y - center(2))**2 + (cart_z - center(3))**2 <= radius**2)) then ib_markers%sf(i, j, k) = encoded_patch_id end if end do @@ -652,36 +611,32 @@ contains end subroutine s_ib_sphere - !> The cuboidal patch is a 3D geometry that may be used, for - !! example, in creating a solid boundary, or pre-/post-shock - !! region, which is aligned with the axes of the Cartesian - !! coordinate system. The geometry of such a patch is well- - !! defined when its centroid and lengths in the x-, y- and - !! z-coordinate directions are provided. Please notice that - !! the cuboidal patch DOES NOT allow for the smearing of its - !! boundaries. - !! @param patch_id is the patch identifier - !! @param ib_markers Array to track patch ids + !> The cuboidal patch is a 3D geometry that may be used, for example, in creating a solid boundary, or pre-/post-shock region, + !! which is aligned with the axes of the Cartesian coordinate system. The geometry of such a patch is well- defined when its + !! centroid and lengths in the x-, y- and z-coordinate directions are provided. Please notice that the cuboidal patch DOES NOT + !! allow for the smearing of its boundaries. + !! @param patch_id is the patch identifier + !! @param ib_markers Array to track patch ids subroutine s_ib_cuboid(patch_id, ib_markers, xp, yp, zp) - integer, intent(in) :: patch_id + integer, intent(in) :: patch_id type(integer_field), intent(inout) :: ib_markers - integer, intent(in) :: xp, yp, zp !< integers containing the periodicity projection information - - integer :: i, j, k, ir, il, jr, jl, kr, kl !< Generic loop iterators - integer :: encoded_patch_id - real(wp), dimension(1:3) :: xyz_local, center, length !< x and y coordinates in local IB frame - real(wp), dimension(1:3, 1:3) :: inverse_rotation - real(wp) :: corner_distance + integer, intent(in) :: xp, yp, zp !< integers containing the periodicity projection information + integer :: i, j, k, ir, il, jr, jl, kr, kl !< Generic loop iterators + integer :: encoded_patch_id + real(wp), dimension(1:3) :: xyz_local, center, length !< x and y coordinates in local IB frame + real(wp), dimension(1:3,1:3) :: inverse_rotation + real(wp) :: corner_distance ! Transferring the cuboid's centroid and length information + center(1) = patch_ib(patch_id)%x_centroid + real(xp, wp)*(glb_bounds(1)%end - glb_bounds(1)%beg) center(2) = patch_ib(patch_id)%y_centroid + real(yp, wp)*(glb_bounds(2)%end - glb_bounds(2)%beg) center(3) = patch_ib(patch_id)%z_centroid + real(zp, wp)*(glb_bounds(3)%end - glb_bounds(3)%beg) length(1) = patch_ib(patch_id)%length_x length(2) = patch_ib(patch_id)%length_y length(3) = patch_ib(patch_id)%length_z - inverse_rotation(:, :) = patch_ib(patch_id)%rotation_matrix_inverse(:, :) + inverse_rotation(:,:) = patch_ib(patch_id)%rotation_matrix_inverse(:,:) ! encode the periodicity information into the patch_id call s_encode_patch_periodicity(patch_id, xp, yp, zp, encoded_patch_id) @@ -693,21 +648,19 @@ contains ir = m + gp_layers + 1 jr = n + gp_layers + 1 kr = p + gp_layers + 1 - corner_distance = sqrt(dot_product(length, length))/2._wp ! maximum distance any marker can be from the center + corner_distance = sqrt(dot_product(length, length))/2._wp ! maximum distance any marker can be from the center call get_bounding_indices(center(1) - corner_distance, center(1) + corner_distance, x_cc, il, ir) call get_bounding_indices(center(2) - corner_distance, center(2) + corner_distance, y_cc, jl, jr) call get_bounding_indices(center(3) - corner_distance, center(3) + corner_distance, z_cc, kl, kr) - ! Checking whether the cuboid covers a particular cell in the domain - ! and verifying whether the current patch has permission to write to - ! to that cell. If both queries check out, the primitive variables - ! of the current patch are assigned to this cell. - $:GPU_PARALLEL_LOOP(private='[i,j,k,xyz_local,cart_y,cart_z]',& - & copyin='[encoded_patch_id,center,length,inverse_rotation]', collapse=3) + ! Checking whether the cuboid covers a particular cell in the domain and verifying whether the current patch has permission + ! to write to to that cell. If both queries check out, the primitive variables of the current patch are assigned to this + ! cell. + $:GPU_PARALLEL_LOOP(private='[i, j, k, xyz_local, cart_y, cart_z]', copyin='[encoded_patch_id, center, length, & + & inverse_rotation]', collapse=3) do k = kl, kr do j = jl, jr do i = il, ir - if (grid_geometry == 3) then ! TODO :: This does not work and is not covered by any tests. This should be fixed call s_convert_cylindrical_to_cartesian_coord(y_cc(j), z_cc(k)) @@ -715,16 +668,12 @@ contains cart_y = y_cc(j) cart_z = z_cc(k) end if - xyz_local = [x_cc(i), cart_y, cart_z] - center ! get coordinate frame centered on IB - xyz_local = matmul(inverse_rotation, xyz_local) ! rotate the frame into the IB's coordinates - - if (-0.5*length(1) <= xyz_local(1) .and. & - 0.5*length(1) >= xyz_local(1) .and. & - -0.5*length(2) <= xyz_local(2) .and. & - 0.5*length(2) >= xyz_local(2) .and. & - -0.5*length(3) <= xyz_local(3) .and. & - 0.5*length(3) >= xyz_local(3)) then + xyz_local = [x_cc(i), cart_y, cart_z] - center ! get coordinate frame centered on IB + xyz_local = matmul(inverse_rotation, xyz_local) ! rotate the frame into the IB's coordinates + if (-0.5*length(1) <= xyz_local(1) .and. 0.5*length(1) >= xyz_local(1) .and. -0.5*length(2) <= xyz_local(2) & + & .and. 0.5*length(2) >= xyz_local(2) .and. -0.5*length(3) <= xyz_local(3) .and. 0.5*length(3) & + & >= xyz_local(3)) then ! Updating the patch identities bookkeeping variable ib_markers%sf(i, j, k) = encoded_patch_id end if @@ -735,31 +684,27 @@ contains end subroutine s_ib_cuboid - !> The cylindrical patch is a 3D geometry that may be used, - !! for example, in setting up a cylindrical solid boundary - !! confinement, like a blood vessel. The geometry of this - !! patch is well-defined when the centroid, the radius and - !! the length along the cylinder's axis, parallel to the x-, - !! y- or z-coordinate direction, are provided. Please note - !! that the cylindrical patch DOES allow for the smoothing - !! of its lateral boundary. - !! @param patch_id is the patch identifier - !! @param ib_markers Array to track patch ids - !! @param ib True if this patch is an immersed boundary + !> The cylindrical patch is a 3D geometry that may be used, for example, in setting up a cylindrical solid boundary confinement, + !! like a blood vessel. The geometry of this patch is well-defined when the centroid, the radius and the length along the + !! cylinder's axis, parallel to the x-, y- or z-coordinate direction, are provided. Please note that the cylindrical patch DOES + !! allow for the smoothing of its lateral boundary. + !! @param patch_id is the patch identifier + !! @param ib_markers Array to track patch ids + !! @param ib True if this patch is an immersed boundary subroutine s_ib_cylinder(patch_id, ib_markers, xp, yp, zp) - integer, intent(in) :: patch_id + integer, intent(in) :: patch_id type(integer_field), intent(inout) :: ib_markers - integer, intent(in) :: xp, yp, zp !< integers containing the periodicity projection information - - integer :: i, j, k, il, ir, jl, jr, kl, kr !< Generic loop iterators - integer :: encoded_patch_id - real(wp) :: radius - real(wp), dimension(1:3) :: xyz_local, center, length !< x and y coordinates in local IB frame - real(wp), dimension(1:3, 1:3) :: inverse_rotation - real(wp) :: corner_distance + integer, intent(in) :: xp, yp, zp !< integers containing the periodicity projection information + integer :: i, j, k, il, ir, jl, jr, kl, kr !< Generic loop iterators + integer :: encoded_patch_id + real(wp) :: radius + real(wp), dimension(1:3) :: xyz_local, center, length !< x and y coordinates in local IB frame + real(wp), dimension(1:3,1:3) :: inverse_rotation + real(wp) :: corner_distance ! Transferring the cylindrical patch's centroid, length, radius, + center(1) = patch_ib(patch_id)%x_centroid + real(xp, wp)*(glb_bounds(1)%end - glb_bounds(1)%beg) center(2) = patch_ib(patch_id)%y_centroid + real(yp, wp)*(glb_bounds(2)%end - glb_bounds(2)%beg) center(3) = patch_ib(patch_id)%z_centroid + real(zp, wp)*(glb_bounds(3)%end - glb_bounds(3)%beg) @@ -767,7 +712,7 @@ contains length(2) = patch_ib(patch_id)%length_y length(3) = patch_ib(patch_id)%length_z radius = patch_ib(patch_id)%radius - inverse_rotation(:, :) = patch_ib(patch_id)%rotation_matrix_inverse(:, :) + inverse_rotation(:,:) = patch_ib(patch_id)%rotation_matrix_inverse(:,:) ! encode the periodicity information into the patch_id call s_encode_patch_periodicity(patch_id, xp, yp, zp, encoded_patch_id) @@ -778,48 +723,34 @@ contains ir = m + gp_layers + 1 jr = n + gp_layers + 1 kr = p + gp_layers + 1 - corner_distance = sqrt(radius**2 + maxval(length)**2) ! distance to rim of cylinder + corner_distance = sqrt(radius**2 + maxval(length)**2) ! distance to rim of cylinder call get_bounding_indices(center(1) - corner_distance, center(1) + corner_distance, x_cc, il, ir) call get_bounding_indices(center(2) - corner_distance, center(2) + corner_distance, y_cc, jl, jr) call get_bounding_indices(center(3) - corner_distance, center(3) + corner_distance, z_cc, kl, kr) - ! Checking whether the cylinder covers a particular cell in the - ! domain and verifying whether the current patch has the permission - ! to write to that cell. If both queries check out, the primitive - ! variables of the current patch are assigned to this cell. - $:GPU_PARALLEL_LOOP(private='[i,j,k,xyz_local,cart_y,cart_z]',& - & copyin='[encoded_patch_id,center,length,radius,inverse_rotation]', collapse=3) + ! Checking whether the cylinder covers a particular cell in the domain and verifying whether the current patch has the + ! permission to write to that cell. If both queries check out, the primitive variables of the current patch are assigned to + ! this cell. + $:GPU_PARALLEL_LOOP(private='[i, j, k, xyz_local, cart_y, cart_z]', copyin='[encoded_patch_id, center, length, radius, & + & inverse_rotation]', collapse=3) do k = kl, kr do j = jl, jr do i = il, ir - if (grid_geometry == 3) then call s_convert_cylindrical_to_cartesian_coord(y_cc(j), z_cc(k)) else cart_y = y_cc(j) cart_z = z_cc(k) end if - xyz_local = [x_cc(i), cart_y, cart_z] - center ! get coordinate frame centered on IB - xyz_local = matmul(inverse_rotation, xyz_local) ! rotate the frame into the IB's coordinates - - if (((.not. f_is_default(length(1)) .and. & - xyz_local(2)**2 & - + xyz_local(3)**2 <= radius**2 .and. & - -0.5_wp*length(1) <= xyz_local(1) .and. & - 0.5_wp*length(1) >= xyz_local(1)) & - .or. & - (.not. f_is_default(length(2)) .and. & - xyz_local(1)**2 & - + xyz_local(3)**2 <= radius**2 .and. & - -0.5_wp*length(2) <= xyz_local(2) .and. & - 0.5_wp*length(2) >= xyz_local(2)) & - .or. & - (.not. f_is_default(length(3)) .and. & - xyz_local(1)**2 & - + xyz_local(2)**2 <= radius**2 .and. & - -0.5_wp*length(3) <= xyz_local(3) .and. & - 0.5_wp*length(3) >= xyz_local(3)))) then - + xyz_local = [x_cc(i), cart_y, cart_z] - center ! get coordinate frame centered on IB + xyz_local = matmul(inverse_rotation, xyz_local) ! rotate the frame into the IB's coordinates + + if (((.not. f_is_default(length(1)) .and. xyz_local(2)**2 + xyz_local(3)**2 <= radius**2 .and. & + & -0.5_wp*length(1) <= xyz_local(1) .and. 0.5_wp*length(1) >= xyz_local(1)) & + & .or. (.not. f_is_default(length(2)) .and. xyz_local(1)**2 + xyz_local(3)**2 <= radius**2 .and. & + & -0.5_wp*length(2) <= xyz_local(2) .and. 0.5_wp*length(2) >= xyz_local(2)) & + & .or. (.not. f_is_default(length(3)) .and. xyz_local(1)**2 + xyz_local(2)**2 <= radius**2 .and. & + & -0.5_wp*length(3) <= xyz_local(3) .and. 0.5_wp*length(3) >= xyz_local(3)))) then ! Updating the patch identities bookkeeping variable ib_markers%sf(i, j, k) = encoded_patch_id end if @@ -833,23 +764,23 @@ contains !> @brief Marks cells inside a 2D elliptical immersed boundary defined by semi-axis lengths and rotation. subroutine s_ib_ellipse(patch_id, ib_markers, xp, yp) - integer, intent(in) :: patch_id + integer, intent(in) :: patch_id type(integer_field), intent(inout) :: ib_markers - integer, intent(in) :: xp, yp !< integers containing the periodicity projection information - - integer :: i, j, il, ir, jl, jr !< Generic loop iterators - integer :: encoded_patch_id - real(wp), dimension(1:3) :: xy_local !< x and y coordinates in local IB frame - real(wp), dimension(1:2) :: ellipse_coeffs !< a and b in the ellipse coefficients - real(wp), dimension(1:2) :: center !< x and y coordinates in local IB frame - real(wp), dimension(1:3, 1:3) :: inverse_rotation + integer, intent(in) :: xp, yp !< integers containing the periodicity projection information + integer :: i, j, il, ir, jl, jr !< Generic loop iterators + integer :: encoded_patch_id + real(wp), dimension(1:3) :: xy_local !< x and y coordinates in local IB frame + real(wp), dimension(1:2) :: ellipse_coeffs !< a and b in the ellipse coefficients + real(wp), dimension(1:2) :: center !< x and y coordinates in local IB frame + real(wp), dimension(1:3,1:3) :: inverse_rotation ! Transferring the ellipse's centroid and length information + center(1) = patch_ib(patch_id)%x_centroid + real(xp, wp)*(glb_bounds(1)%end - glb_bounds(1)%beg) center(2) = patch_ib(patch_id)%y_centroid + real(yp, wp)*(glb_bounds(2)%end - glb_bounds(2)%beg) ellipse_coeffs(1) = 0.5_wp*patch_ib(patch_id)%length_x ellipse_coeffs(2) = 0.5_wp*patch_ib(patch_id)%length_y - inverse_rotation(:, :) = patch_ib(patch_id)%rotation_matrix_inverse(:, :) + inverse_rotation(:,:) = patch_ib(patch_id)%rotation_matrix_inverse(:,:) ! encode the periodicity information into the patch_id call s_encode_patch_periodicity(patch_id, xp, yp, 0, encoded_patch_id) @@ -862,10 +793,9 @@ contains call get_bounding_indices(center(1) - maxval(ellipse_coeffs)*2._wp, center(1) + maxval(ellipse_coeffs)*2._wp, x_cc, il, ir) call get_bounding_indices(center(2) - maxval(ellipse_coeffs)*2._wp, center(2) + maxval(ellipse_coeffs)*2._wp, y_cc, jl, jr) - ! Checking whether the ellipse covers a particular cell in the - ! domain - $:GPU_PARALLEL_LOOP(private='[i,j, xy_local]',& - & copyin='[encoded_patch_id,center,ellipse_coeffs,inverse_rotation,x_cc,y_cc]', collapse=2) + ! Checking whether the ellipse covers a particular cell in the domain + $:GPU_PARALLEL_LOOP(private='[i, j, xy_local]', copyin='[encoded_patch_id, center, ellipse_coeffs, inverse_rotation, & + & x_cc, y_cc]', collapse=2) do j = jl, jr do i = il, ir ! get the x and y coordinates in the local IB frame @@ -888,27 +818,25 @@ contains !! @param ib_markers Array to track patch ids subroutine s_ib_model(patch_id, ib_markers, xp, yp) - integer, intent(in) :: patch_id + integer, intent(in) :: patch_id type(integer_field), intent(inout) :: ib_markers - integer, intent(in) :: xp, yp !< integers containing the periodicity projection information - - integer :: i, j, k, il, ir, jl, jr !< Generic loop iterators - integer :: spc, encoded_patch_id - integer :: cx, cy - real(wp) :: lx(2), ly(2) - real(wp), dimension(1:2) :: bbox_min, bbox_max - real(wp), dimension(1:3) :: local_corner, world_corner - - real(wp) :: eta, threshold - real(wp), dimension(1:3) :: point, local_point, offset - real(wp), dimension(1:3) :: center, xy_local - real(wp), dimension(1:3, 1:3) :: inverse_rotation, rotation + integer, intent(in) :: xp, yp !< integers containing the periodicity projection information + integer :: i, j, k, il, ir, jl, jr !< Generic loop iterators + integer :: spc, encoded_patch_id + integer :: cx, cy + real(wp) :: lx(2), ly(2) + real(wp), dimension(1:2) :: bbox_min, bbox_max + real(wp), dimension(1:3) :: local_corner, world_corner + real(wp) :: eta, threshold + real(wp), dimension(1:3) :: point, local_point, offset + real(wp), dimension(1:3) :: center, xy_local + real(wp), dimension(1:3,1:3) :: inverse_rotation, rotation center = 0._wp center(1) = patch_ib(patch_id)%x_centroid + real(xp, wp)*(glb_bounds(1)%end - glb_bounds(1)%beg) center(2) = patch_ib(patch_id)%y_centroid + real(yp, wp)*(glb_bounds(2)%end - glb_bounds(2)%beg) - inverse_rotation(:, :) = patch_ib(patch_id)%rotation_matrix_inverse(:, :) - rotation(:, :) = patch_ib(patch_id)%rotation_matrix(:, :) + inverse_rotation(:,:) = patch_ib(patch_id)%rotation_matrix_inverse(:,:) + rotation(:,:) = patch_ib(patch_id)%rotation_matrix(:,:) offset(:) = patch_ib(patch_id)%centroid_offset(:) spc = patch_ib(patch_id)%model_spc threshold = patch_ib(patch_id)%model_threshold @@ -929,8 +857,7 @@ contains bbox_min = 1e12 bbox_max = -1e12 - ! Enumerate all 8 corners of the local bounding box, - ! rotate to world space, track world-space AABB + ! Enumerate all 8 corners of the local bounding box, rotate to world space, track world-space AABB do cx = 1, 2 do cy = 1, 2 local_corner = [lx(cx), ly(cy), 0._wp] @@ -945,16 +872,15 @@ contains call get_bounding_indices(bbox_min(1), bbox_max(1), x_cc, il, ir) call get_bounding_indices(bbox_min(2), bbox_max(2), y_cc, jl, jr) - $:GPU_PARALLEL_LOOP(private='[i,j, xy_local, eta]',& - & copyin='[patch_id,encoded_patch_id,center,inverse_rotation, offset, spc, threshold]', collapse=2) + $:GPU_PARALLEL_LOOP(private='[i, j, xy_local, eta]', copyin='[patch_id, encoded_patch_id, center, inverse_rotation, & + & offset, spc, threshold]', collapse=2) do i = il, ir do j = jl, jr xy_local = [x_cc(i) - center(1), y_cc(j) - center(2), 0._wp] xy_local = matmul(inverse_rotation, xy_local) xy_local = xy_local - offset - eta = f_model_is_inside_flat(gpu_ntrs(patch_id), & - patch_id, xy_local) + eta = f_model_is_inside_flat(gpu_ntrs(patch_id), patch_id, xy_local) ! Reading STL boundary vertices and compute the levelset and levelset_norm if (eta > threshold) then @@ -971,30 +897,28 @@ contains !! @param ib_markers Array to track patch ids subroutine s_ib_3d_model(patch_id, ib_markers, xp, yp, zp) - integer, intent(in) :: patch_id + integer, intent(in) :: patch_id type(integer_field), intent(inout) :: ib_markers - integer, intent(in) :: xp, yp, zp !< integers containing the periodicity projection information - - integer :: i, j, k, il, ir, jl, jr, kl, kr !< Generic loop iterators - integer :: spc, encoded_patch_id - - real(wp) :: eta, threshold, corner_distance - real(wp), dimension(1:3) :: point, local_point, offset - real(wp), dimension(1:3) :: center, xyz_local - real(wp), dimension(1:3, 1:3) :: inverse_rotation, rotation - integer :: cx, cy, cz - real(wp) :: lx(2), ly(2), lz(2) - real(wp), dimension(1:3) :: bbox_min, bbox_max, local_corner, world_corner + integer, intent(in) :: xp, yp, zp !< integers containing the periodicity projection information + integer :: i, j, k, il, ir, jl, jr, kl, kr !< Generic loop iterators + integer :: spc, encoded_patch_id + real(wp) :: eta, threshold, corner_distance + real(wp), dimension(1:3) :: point, local_point, offset + real(wp), dimension(1:3) :: center, xyz_local + real(wp), dimension(1:3,1:3) :: inverse_rotation, rotation + integer :: cx, cy, cz + real(wp) :: lx(2), ly(2), lz(2) + real(wp), dimension(1:3) :: bbox_min, bbox_max, local_corner, world_corner center = 0._wp center(1) = patch_ib(patch_id)%x_centroid + real(xp, wp)*(glb_bounds(1)%end - glb_bounds(1)%beg) center(2) = patch_ib(patch_id)%y_centroid + real(yp, wp)*(glb_bounds(2)%end - glb_bounds(2)%beg) center(3) = patch_ib(patch_id)%z_centroid + real(zp, wp)*(glb_bounds(3)%end - glb_bounds(3)%beg) - inverse_rotation(:, :) = patch_ib(patch_id)%rotation_matrix_inverse(:, :) + inverse_rotation(:,:) = patch_ib(patch_id)%rotation_matrix_inverse(:,:) offset(:) = patch_ib(patch_id)%centroid_offset(:) spc = patch_ib(patch_id)%model_spc threshold = patch_ib(patch_id)%model_threshold - rotation(:, :) = patch_ib(patch_id)%rotation_matrix(:, :) + rotation(:,:) = patch_ib(patch_id)%rotation_matrix(:,:) ! encode the periodicity information into the patch_id call s_encode_patch_periodicity(patch_id, xp, yp, zp, encoded_patch_id) @@ -1016,8 +940,7 @@ contains bbox_min = 1e12 bbox_max = -1e12 - ! Enumerate all 8 corners of the local bounding box, - ! rotate to world space, track world-space AABB + ! Enumerate all 8 corners of the local bounding box, rotate to world space, track world-space AABB do cx = 1, 2 do cy = 1, 2 do cz = 1, 2 @@ -1037,8 +960,8 @@ contains call get_bounding_indices(bbox_min(2), bbox_max(2), y_cc, jl, jr) call get_bounding_indices(bbox_min(3), bbox_max(3), z_cc, kl, kr) - $:GPU_PARALLEL_LOOP(private='[i,j,k, xyz_local, eta]',& - & copyin='[patch_id,encoded_patch_id,center,inverse_rotation, offset, spc, threshold]', collapse=3) + $:GPU_PARALLEL_LOOP(private='[i, j, k, xyz_local, eta]', copyin='[patch_id, encoded_patch_id, center, inverse_rotation, & + & offset, spc, threshold]', collapse=3) do i = il, ir do j = jl, jr do k = kl, kr @@ -1046,8 +969,7 @@ contains xyz_local = matmul(inverse_rotation, xyz_local) xyz_local = xyz_local - offset - eta = f_model_is_inside_flat(gpu_ntrs(patch_id), & - patch_id, xyz_local) + eta = f_model_is_inside_flat(gpu_ntrs(patch_id), patch_id, xyz_local) if (eta > patch_ib(patch_id)%model_threshold) then ib_markers%sf(i, j, k) = encoded_patch_id @@ -1062,50 +984,52 @@ contains !> Subroutine that computes a rotation matrix for converting to the rotating frame of the boundary subroutine s_update_ib_rotation_matrix(patch_id) - integer, intent(in) :: patch_id - integer :: i - + integer, intent(in) :: patch_id + integer :: i real(wp), dimension(3, 3, 3) :: rotation - real(wp) :: angle + real(wp) :: angle ! construct the x, y, and z rotation matrices + if (num_dims == 3) then ! also compute the x and y axes in 3D angle = patch_ib(patch_id)%angles(1) - rotation(1, 1, :) = [1._wp, 0._wp, 0._wp] - rotation(1, 2, :) = [0._wp, cos(angle), -sin(angle)] - rotation(1, 3, :) = [0._wp, sin(angle), cos(angle)] + rotation(1, 1,:) = [1._wp, 0._wp, 0._wp] + rotation(1, 2,:) = [0._wp, cos(angle), -sin(angle)] + rotation(1, 3,:) = [0._wp, sin(angle), cos(angle)] angle = patch_ib(patch_id)%angles(2) - rotation(2, 1, :) = [cos(angle), 0._wp, sin(angle)] - rotation(2, 2, :) = [0._wp, 1._wp, 0._wp] - rotation(2, 3, :) = [-sin(angle), 0._wp, cos(angle)] + rotation(2, 1,:) = [cos(angle), 0._wp, sin(angle)] + rotation(2, 2,:) = [0._wp, 1._wp, 0._wp] + rotation(2, 3,:) = [-sin(angle), 0._wp, cos(angle)] ! apply the y rotation to the x rotation - patch_ib(patch_id)%rotation_matrix(:, :) = matmul(rotation(1, :, :), rotation(2, :, :)) - patch_ib(patch_id)%rotation_matrix_inverse(:, :) = matmul(transpose(rotation(2, :, :)), transpose(rotation(1, :, :))) + patch_ib(patch_id)%rotation_matrix(:,:) = matmul(rotation(1,:,:), rotation(2,:,:)) + patch_ib(patch_id)%rotation_matrix_inverse(:,:) = matmul(transpose(rotation(2,:,:)), transpose(rotation(1,:,:))) end if ! z component first, since it applies in 2D and 3D angle = patch_ib(patch_id)%angles(3) - rotation(3, 1, :) = [cos(angle), -sin(angle), 0._wp] - rotation(3, 2, :) = [sin(angle), cos(angle), 0._wp] - rotation(3, 3, :) = [0._wp, 0._wp, 1._wp] + rotation(3, 1,:) = [cos(angle), -sin(angle), 0._wp] + rotation(3, 2,:) = [sin(angle), cos(angle), 0._wp] + rotation(3, 3,:) = [0._wp, 0._wp, 1._wp] if (num_dims == 3) then ! apply the z rotation to the xy rotation in 3D - patch_ib(patch_id)%rotation_matrix(:, :) = matmul(patch_ib(patch_id)%rotation_matrix(:, :), rotation(3, :, :)) - patch_ib(patch_id)%rotation_matrix_inverse(:, :) = matmul(transpose(rotation(3, :, :)), patch_ib(patch_id)%rotation_matrix_inverse(:, :)) + patch_ib(patch_id)%rotation_matrix(:,:) = matmul(patch_ib(patch_id)%rotation_matrix(:,:), rotation(3,:,:)) + patch_ib(patch_id)%rotation_matrix_inverse(:,:) = matmul(transpose(rotation(3,:,:)), & + & patch_ib(patch_id)%rotation_matrix_inverse(:,:)) else ! write out only the z rotation in 2D - patch_ib(patch_id)%rotation_matrix(:, :) = rotation(3, :, :) - patch_ib(patch_id)%rotation_matrix_inverse(:, :) = transpose(rotation(3, :, :)) + patch_ib(patch_id)%rotation_matrix(:,:) = rotation(3,:,:) + patch_ib(patch_id)%rotation_matrix_inverse(:,:) = transpose(rotation(3,:,:)) end if end subroutine s_update_ib_rotation_matrix !> @brief Converts cylindrical (r, theta) coordinates to Cartesian (y, z) and stores in module variables. subroutine s_convert_cylindrical_to_cartesian_coord(cyl_y, cyl_z) + $:GPU_ROUTINE(parallelism='[seq]') real(wp), intent(in) :: cyl_y, cyl_z @@ -1121,19 +1045,18 @@ contains $:GPU_ROUTINE(parallelism='[seq]') real(wp), dimension(1:3), intent(in) :: cyl - real(wp), dimension(1:3) :: cart + real(wp), dimension(1:3) :: cart - cart = (/cyl(1), & - cyl(2)*sin(cyl(3)), & - cyl(2)*cos(cyl(3))/) + cart = (/cyl(1), cyl(2)*sin(cyl(3)), cyl(2)*cos(cyl(3))/) end function f_convert_cyl_to_cart !> @brief Converts cylindrical coordinates (x, r) to the spherical azimuthal angle phi and stores in a module variable. subroutine s_convert_cylindrical_to_spherical_coord(cyl_x, cyl_y) + $:GPU_ROUTINE(parallelism='[seq]') - real(wp), intent(IN) :: cyl_x, cyl_y + real(wp), intent(in) :: cyl_x, cyl_y sph_phi = atan(cyl_y/cyl_x) @@ -1141,11 +1064,10 @@ contains subroutine get_bounding_indices(left_bound, right_bound, cell_centers, left_index, right_index) - real(wp), intent(in) :: left_bound, right_bound - integer, intent(inout) :: left_index, right_index + real(wp), intent(in) :: left_bound, right_bound + integer, intent(inout) :: left_index, right_index real(wp), dimension(-buff_size:), intent(in) :: cell_centers - - integer :: itr_left, itr_middle, itr_right + integer :: itr_left, itr_middle, itr_right itr_left = left_index itr_right = right_index @@ -1182,10 +1104,9 @@ contains !> @brief encodes the patch id with a unique offset that contains information on how the IB marker wraps periodically subroutine s_encode_patch_periodicity(patch_id, x_periodicity, y_periodicity, z_periodicity, encoded_patch_id) - integer, intent(in) :: patch_id, x_periodicity, y_periodicity, z_periodicity + integer, intent(in) :: patch_id, x_periodicity, y_periodicity, z_periodicity integer, intent(out) :: encoded_patch_id - - integer :: temp_x_per, temp_y_per, temp_z_per, offset + integer :: temp_x_per, temp_y_per, temp_z_per, offset encoded_patch_id = patch_id @@ -1203,10 +1124,9 @@ contains $:GPU_ROUTINE(parallelism='[seq]') - integer, intent(in) :: encoded_patch_id + integer, intent(in) :: encoded_patch_id integer, intent(out) :: patch_id, x_periodicity, y_periodicity, z_periodicity - - integer :: offset, remainder, xp, yp, zp, base + integer :: offset, remainder, xp, yp, zp, base base = num_ibs + 1 @@ -1228,10 +1148,11 @@ contains !> @brief Determines if we should wrap periodically subroutine s_get_periodicities(xp_lower, xp_upper, yp_lower, yp_upper, zp_lower, zp_upper) - integer, intent(out) :: xp_lower, xp_upper, yp_lower, yp_upper + integer, intent(out) :: xp_lower, xp_upper, yp_lower, yp_upper integer, intent(out), optional :: zp_lower, zp_upper ! check domain wraps in x, y + #:for X, ID in [('x', 1), ('y', 2), ('z', 3)] if (num_dims >= ${ID}$) then ! check for periodicity @@ -1239,7 +1160,7 @@ contains ${X}$p_lower = -1 ${X}$p_upper = 1 else - !if it is not periodic, then both elements are 0 + ! if it is not periodic, then both elements are 0 ${X}$p_lower = 0 ${X}$p_upper = 0 end if @@ -1253,15 +1174,17 @@ contains !! @param offset Thickness !! @param a Starting position pure elemental function f_r(myth, offset, a) + $:GPU_ROUTINE(parallelism='[seq]') real(wp), intent(in) :: myth, offset, a - real(wp) :: b - real(wp) :: f_r + real(wp) :: b + real(wp) :: f_r - !r(th) = a + b*th + ! r(th) = a + b*th b = 2._wp*a/(2._wp*pi) f_r = a + b*myth + offset + end function f_r end module m_ib_patches diff --git a/src/simulation/m_ibm.fpp b/src/simulation/m_ibm.fpp index 109babdf68..1a641b0e74 100644 --- a/src/simulation/m_ibm.fpp +++ b/src/simulation/m_ibm.fpp @@ -4,42 +4,27 @@ #:include 'macros.fpp' -!> @brief Ghost-node immersed boundary method: locates ghost/image points, computes interpolation coefficients, and corrects the flow state +!> @brief Ghost-node immersed boundary method: locates ghost/image points, computes interpolation coefficients, and corrects the +!! flow state module m_ibm - use m_derived_types !< Definitions of the derived types - - use m_global_parameters !< Definitions of the global parameters - - use m_mpi_proxy !< Message passing interface (MPI) module proxy - - use m_variables_conversion !< State variables type conversion procedures - + use m_derived_types !< Definitions of the derived types + use m_global_parameters !< Definitions of the global parameters + use m_mpi_proxy !< Message passing interface (MPI) module proxy + use m_variables_conversion !< State variables type conversion procedures use m_helper - - use m_helper_basic !< Functions to compare floating point numbers - + use m_helper_basic !< Functions to compare floating point numbers use m_constants - use m_compute_levelset - use m_ib_patches - use m_viscous - use m_model implicit none - private :: s_compute_image_points, & - s_compute_interpolation_coeffs, & - s_interpolate_image_point, & - s_find_ghost_points, & - s_find_num_ghost_points - ; public :: s_initialize_ibm_module, & - s_ibm_setup, & - s_ibm_correct_state, & - s_finalize_ibm_module + private :: s_compute_image_points, s_compute_interpolation_coeffs, s_interpolate_image_point, s_find_ghost_points, & + & s_find_num_ghost_points + ; public :: s_initialize_ibm_module, s_ibm_setup, s_ibm_correct_state, s_finalize_ibm_module type(integer_field), public :: ib_markers $:GPU_DECLARE(create='[ib_markers]') @@ -47,9 +32,9 @@ module m_ibm type(ghost_point), dimension(:), allocatable :: ghost_points $:GPU_DECLARE(create='[ghost_points]') - integer :: num_gps !< Number of ghost points + integer :: num_gps !< Number of ghost points #if defined(MFC_OpenACC) - $:GPU_DECLARE(create='[gp_layers,num_gps]') + $:GPU_DECLARE(create='[gp_layers, num_gps]') #elif defined(MFC_OpenMP) $:GPU_DECLARE(create='[num_gps]') #endif @@ -57,15 +42,13 @@ module m_ibm contains - !> Allocates memory for the variables in the IBM module + !> Allocates memory for the variables in the IBM module impure subroutine s_initialize_ibm_module() if (p > 0) then - @:ALLOCATE(ib_markers%sf(-buff_size:m+buff_size, & - -buff_size:n+buff_size, -buff_size:p+buff_size)) + @:ALLOCATE(ib_markers%sf(-buff_size:m+buff_size, -buff_size:n+buff_size, -buff_size:p+buff_size)) else - @:ALLOCATE(ib_markers%sf(-buff_size:m+buff_size, & - -buff_size:n+buff_size, 0:0)) + @:ALLOCATE(ib_markers%sf(-buff_size:m+buff_size, -buff_size:n+buff_size, 0:0)) end if @:ALLOCATE(models(num_ibs)) @@ -76,8 +59,7 @@ contains end subroutine s_initialize_ibm_module - !> Initializes the values of various IBM variables, such as ghost points and - !! image points. + !> Initializes the values of various IBM variables, such as ghost points and image points. impure subroutine s_ibm_setup() integer :: i, j, k @@ -112,7 +94,7 @@ contains call s_apply_ib_patches(ib_markers) $:GPU_UPDATE(host='[ib_markers%sf]') do i = 1, num_ibs - if (patch_ib(i)%moving_ibm /= 0) call s_compute_centroid_offset(i) ! offsets are computed after IB markers are generated + if (patch_ib(i)%moving_ibm /= 0) call s_compute_centroid_offset(i) ! offsets are computed after IB markers are generated $:GPU_UPDATE(device='[patch_ib(i)]') end do @@ -140,60 +122,51 @@ contains end subroutine s_ibm_setup - !> Subroutine that updates the conservative variables at the ghost points - !! @param pb_in Internal bubble pressure - !! @param mv_in Mass of vapor in bubble + !> Subroutine that updates the conservative variables at the ghost points + !! @param pb_in Internal bubble pressure + !! @param mv_in Mass of vapor in bubble subroutine s_ibm_correct_state(q_cons_vf, q_prim_vf, pb_in, mv_in) - type(scalar_field), & - dimension(sys_size), & - intent(INOUT) :: q_cons_vf !< Primitive Variables - - type(scalar_field), & - dimension(sys_size), & - intent(INOUT) :: q_prim_vf !< Primitive Variables - - real(stp), dimension(idwbuff(1)%beg:, idwbuff(2)%beg:, idwbuff(3)%beg:, 1:, 1:), optional, intent(INOUT) :: pb_in, mv_in - - integer :: i, j, k, l, q, r!< Iterator variables - integer :: patch_id !< Patch ID of ghost point - real(wp) :: rho, gamma, pi_inf, dyn_pres !< Mixture variables + type(scalar_field), dimension(sys_size), intent(inout) :: q_cons_vf !< Primitive Variables + type(scalar_field), dimension(sys_size), intent(inout) :: q_prim_vf !< Primitive Variables + real(stp), dimension(idwbuff(1)%beg:,idwbuff(2)%beg:,idwbuff(3)%beg:,1:,1:), optional, intent(inout) :: pb_in, mv_in + integer :: i, j, k, l, q, r !< Iterator variables + integer :: patch_id !< Patch ID of ghost point + real(wp) :: rho, gamma, pi_inf, dyn_pres !< Mixture variables real(wp), dimension(2) :: Re_K real(wp) :: G_K real(wp) :: qv_K - real(wp) :: pres_IP real(wp), dimension(3) :: vel_IP, vel_norm_IP real(wp) :: c_IP + #:if not MFC_CASE_OPTIMIZATION and USING_AMD - real(wp), dimension(3) :: Gs - real(wp), dimension(3) :: alpha_rho_IP, alpha_IP - real(wp), dimension(3) :: r_IP, v_IP, pb_IP, mv_IP + real(wp), dimension(3) :: Gs + real(wp), dimension(3) :: alpha_rho_IP, alpha_IP + real(wp), dimension(3) :: r_IP, v_IP, pb_IP, mv_IP real(wp), dimension(18) :: nmom_IP real(wp), dimension(12) :: presb_IP, massv_IP #:else real(wp), dimension(num_fluids) :: Gs real(wp), dimension(num_fluids) :: alpha_rho_IP, alpha_IP - real(wp), dimension(nb) :: r_IP, v_IP, pb_IP, mv_IP - real(wp), dimension(nb*nmom) :: nmom_IP - real(wp), dimension(nb*nnode) :: presb_IP, massv_IP + real(wp), dimension(nb) :: r_IP, v_IP, pb_IP, mv_IP + real(wp), dimension(nb*nmom) :: nmom_IP + real(wp), dimension(nb*nnode) :: presb_IP, massv_IP #:endif - !! Primitive variables at the image point associated with a ghost point, - !! interpolated from surrounding fluid cells. - - real(wp), dimension(3) :: norm !< Normal vector from GP to IP - real(wp), dimension(3) :: physical_loc !< Physical loc of GP - real(wp), dimension(3) :: vel_g !< Velocity of GP - real(wp), dimension(3) :: radial_vector !< vector from centroid to ghost point - real(wp), dimension(3) :: rotation_velocity !< speed of the ghost point due to rotation - - real(wp) :: nbub - real(wp) :: buf - type(ghost_point) :: gp - type(ghost_point) :: innerp + !! Primitive variables at the image point associated with a ghost point, interpolated from surrounding fluid cells. + + real(wp), dimension(3) :: norm !< Normal vector from GP to IP + real(wp), dimension(3) :: physical_loc !< Physical loc of GP + real(wp), dimension(3) :: vel_g !< Velocity of GP + real(wp), dimension(3) :: radial_vector !< vector from centroid to ghost point + real(wp), dimension(3) :: rotation_velocity !< speed of the ghost point due to rotation + real(wp) :: nbub + real(wp) :: buf + type(ghost_point) :: gp + type(ghost_point) :: innerp ! set the Moving IBM interior conservative variables - $:GPU_PARALLEL_LOOP(private='[i,j,k,patch_id,rho]', copyin='[E_idx,momxb]', collapse=3) + $:GPU_PARALLEL_LOOP(private='[i, j, k, patch_id, rho]', copyin='[E_idx, momxb]', collapse=3) do l = 0, p do k = 0, n do j = 0, m @@ -217,9 +190,10 @@ contains $:END_GPU_PARALLEL_LOOP() if (num_gps > 0) then - $:GPU_PARALLEL_LOOP(private='[i,physical_loc,dyn_pres,alpha_rho_IP, alpha_IP,pres_IP,vel_IP,vel_g,vel_norm_IP,r_IP, v_IP,pb_IP,mv_IP,nmom_IP,presb_IP,massv_IP,rho, gamma,pi_inf,Re_K,G_K,Gs,gp,innerp,norm,buf, radial_vector, rotation_velocity, j,k,l,q,qv_K,c_IP,nbub,patch_id]') + $:GPU_PARALLEL_LOOP(private='[i, physical_loc, dyn_pres, alpha_rho_IP, alpha_IP, pres_IP, vel_IP, vel_g, vel_norm_IP, & + & r_IP, v_IP, pb_IP, mv_IP, nmom_IP, presb_IP, massv_IP, rho, gamma, pi_inf, Re_K, G_K, Gs, gp, & + & innerp, norm, buf, radial_vector, rotation_velocity, j, k, l, q, qv_K, c_IP, nbub, patch_id]') do i = 1, num_gps - gp = ghost_points(i) j = gp%loc(1) k = gp%loc(2) @@ -233,22 +207,18 @@ contains physical_loc = [x_cc(j), y_cc(k), 0._wp] end if - !Interpolate primitive variables at image point associated w/ GP + ! Interpolate primitive variables at image point associated w/ GP if (bubbles_euler .and. .not. qbmm) then - call s_interpolate_image_point(q_prim_vf, gp, & - alpha_rho_IP, alpha_IP, pres_IP, vel_IP, c_IP, & - r_IP, v_IP, pb_IP, mv_IP) + call s_interpolate_image_point(q_prim_vf, gp, alpha_rho_IP, alpha_IP, pres_IP, vel_IP, c_IP, r_IP, v_IP, & + & pb_IP, mv_IP) else if (qbmm .and. polytropic) then - call s_interpolate_image_point(q_prim_vf, gp, & - alpha_rho_IP, alpha_IP, pres_IP, vel_IP, c_IP, & - r_IP, v_IP, pb_IP, mv_IP, nmom_IP) + call s_interpolate_image_point(q_prim_vf, gp, alpha_rho_IP, alpha_IP, pres_IP, vel_IP, c_IP, r_IP, v_IP, & + & pb_IP, mv_IP, nmom_IP) else if (qbmm .and. .not. polytropic) then - call s_interpolate_image_point(q_prim_vf, gp, & - alpha_rho_IP, alpha_IP, pres_IP, vel_IP, c_IP, & - r_IP, v_IP, pb_IP, mv_IP, nmom_IP, pb_in, mv_in, presb_IP, massv_IP) + call s_interpolate_image_point(q_prim_vf, gp, alpha_rho_IP, alpha_IP, pres_IP, vel_IP, c_IP, r_IP, v_IP, & + & pb_IP, mv_IP, nmom_IP, pb_in, mv_in, presb_IP, massv_IP) else - call s_interpolate_image_point(q_prim_vf, gp, & - alpha_rho_IP, alpha_IP, pres_IP, vel_IP, c_IP) + call s_interpolate_image_point(q_prim_vf, gp, alpha_rho_IP, alpha_IP, pres_IP, vel_IP, c_IP) end if dyn_pres = 0._wp @@ -271,19 +241,21 @@ contains q_prim_vf(E_idx)%sf(j, k, l) = 0._wp $:GPU_LOOP(parallelism='[seq]') do q = 1, num_fluids - ! Se the pressure inside a moving immersed boundary based upon the pressure of the image point. acceleration, and normal vector direction - q_prim_vf(E_idx)%sf(j, k, l) = q_prim_vf(E_idx)%sf(j, k, l) + pres_IP/(1._wp - 2._wp*abs(gp%levelset*alpha_rho_IP(q)/pres_IP)*dot_product(patch_ib(patch_id)%force/patch_ib(patch_id)%mass, gp%levelset_norm)) + ! Se the pressure inside a moving immersed boundary based upon the pressure of the image point. + ! acceleration, and normal vector direction + q_prim_vf(E_idx)%sf(j, k, l) = q_prim_vf(E_idx)%sf(j, k, & + & l) + pres_IP/(1._wp - 2._wp*abs(gp%levelset*alpha_rho_IP(q)/pres_IP) & + & *dot_product(patch_ib(patch_id)%force/patch_ib(patch_id)%mass, gp%levelset_norm)) end do end if if (model_eqns /= 4) then ! If in simulation, use acc mixture subroutines if (elasticity) then - call s_convert_species_to_mixture_variables_acc(rho, gamma, pi_inf, qv_K, alpha_IP, & - alpha_rho_IP, Re_K, G_K, Gs) + call s_convert_species_to_mixture_variables_acc(rho, gamma, pi_inf, qv_K, alpha_IP, alpha_rho_IP, Re_K, & + & G_K, Gs) else - call s_convert_species_to_mixture_variables_acc(rho, gamma, pi_inf, qv_K, alpha_IP, & - alpha_rho_IP, Re_K) + call s_convert_species_to_mixture_variables_acc(rho, gamma, pi_inf, qv_K, alpha_IP, alpha_rho_IP, Re_K) end if end if @@ -296,9 +268,10 @@ contains vel_g = vel_IP - vel_norm_IP if (patch_ib(patch_id)%moving_ibm /= 0) then ! compute the linear velocity of the ghost point due to rotation - radial_vector = physical_loc - [patch_ib(patch_id)%x_centroid, & - patch_ib(patch_id)%y_centroid, patch_ib(patch_id)%z_centroid] - call s_cross_product(matmul(patch_ib(patch_id)%rotation_matrix, patch_ib(patch_id)%angular_vel), radial_vector, rotation_velocity) + radial_vector = physical_loc - [patch_ib(patch_id)%x_centroid, patch_ib(patch_id)%y_centroid, & + & patch_ib(patch_id)%z_centroid] + call s_cross_product(matmul(patch_ib(patch_id)%rotation_matrix, patch_ib(patch_id)%angular_vel), & + & radial_vector, rotation_velocity) ! add only the component of the IB's motion that is normal to the surface vel_g = vel_g + sum((patch_ib(patch_id)%vel + rotation_velocity)*norm)*norm @@ -309,14 +282,16 @@ contains vel_g = 0._wp else ! get the vector that points from the centroid to the ghost - radial_vector = physical_loc - [patch_ib(patch_id)%x_centroid, & - patch_ib(patch_id)%y_centroid, patch_ib(patch_id)%z_centroid] - ! convert the angular velocity from the inertial reference frame to the fluids frame, then convert to linear velocity - call s_cross_product(matmul(patch_ib(patch_id)%rotation_matrix, patch_ib(patch_id)%angular_vel), radial_vector, rotation_velocity) + radial_vector = physical_loc - [patch_ib(patch_id)%x_centroid, patch_ib(patch_id)%y_centroid, & + & patch_ib(patch_id)%z_centroid] + ! convert the angular velocity from the inertial reference frame to the fluids frame, then convert to linear + ! velocity + call s_cross_product(matmul(patch_ib(patch_id)%rotation_matrix, patch_ib(patch_id)%angular_vel), & + & radial_vector, rotation_velocity) do q = 1, 3 ! if mibm is 1 or 2, then the boundary may be moving - vel_g(q) = patch_ib(patch_id)%vel(q) ! add the linear velocity - vel_g(q) = vel_g(q) + rotation_velocity(q) ! add the rotational velocity + vel_g(q) = patch_ib(patch_id)%vel(q) ! add the linear velocity + vel_g(q) = vel_g(q) + rotation_velocity(q) ! add the rotational velocity end do end if end if @@ -325,8 +300,7 @@ contains $:GPU_LOOP(parallelism='[seq]') do q = momxb, momxe q_cons_vf(q)%sf(j, k, l) = rho*vel_g(q - momxb + 1) - dyn_pres = dyn_pres + q_cons_vf(q)%sf(j, k, l)* & - vel_g(q - momxb + 1)/2._wp + dyn_pres = dyn_pres + q_cons_vf(q)%sf(j, k, l)*vel_g(q - momxb + 1)/2._wp end do ! Set continuity and adv vars @@ -364,7 +338,6 @@ contains end if if (qbmm) then - nbub = nmom_IP(1) $:GPU_LOOP(parallelism='[seq]') do q = 1, nb*nmom @@ -391,8 +364,7 @@ contains if (model_eqns == 3) then $:GPU_LOOP(parallelism='[seq]') do q = intxb, intxe - q_cons_vf(q)%sf(j, k, l) = alpha_IP(q - intxb + 1)*(gammas(q - intxb + 1)*pres_IP & - + pi_infs(q - intxb + 1)) + q_cons_vf(q)%sf(j, k, l) = alpha_IP(q - intxb + 1)*(gammas(q - intxb + 1)*pres_IP + pi_infs(q - intxb + 1)) end do end if end do @@ -401,30 +373,29 @@ contains end subroutine s_ibm_correct_state - !> Function that computes the image points for each ghost point - !! @param ghost_points_in Ghost Points + !> Function that computes the image points for each ghost point + !! @param ghost_points_in Ghost Points impure subroutine s_compute_image_points(ghost_points_in) - type(ghost_point), dimension(num_gps), intent(INOUT) :: ghost_points_in - - real(wp) :: dist - real(wp), dimension(3) :: norm - real(wp), dimension(3) :: physical_loc - real(wp) :: temp_loc - real(wp), pointer, dimension(:) :: s_cc => null() - integer :: bound - type(ghost_point) :: gp - - integer :: q, dim !< Iterator variables - integer :: i, j, k, l !< Location indexes - integer :: patch_id !< IB Patch ID - integer :: dir - integer :: index - logical :: bounds_error + type(ghost_point), dimension(num_gps), intent(inout) :: ghost_points_in + real(wp) :: dist + real(wp), dimension(3) :: norm + real(wp), dimension(3) :: physical_loc + real(wp) :: temp_loc + real(wp), pointer, dimension(:) :: s_cc => null() + integer :: bound + type(ghost_point) :: gp + integer :: q, dim !< Iterator variables + integer :: i, j, k, l !< Location indexes + integer :: patch_id !< IB Patch ID + integer :: dir + integer :: index + logical :: bounds_error bounds_error = .false. - $:GPU_PARALLEL_LOOP(private='[q,gp,i,j,k,physical_loc,patch_id,dist,norm,dim,bound,dir,index,temp_loc,s_cc]', copy='[bounds_error]') + $:GPU_PARALLEL_LOOP(private='[q, gp, i, j, k, physical_loc, patch_id, dist, norm, dim, bound, dir, index, temp_loc, & + & s_cc]', copy='[bounds_error]') do q = 1, num_gps gp = ghost_points_in(q) i = gp%loc(1) @@ -446,12 +417,11 @@ contains ! Find the closest grid point to the image point do dim = 1, num_dims - ! s_cc points to the dim array we need if (dim == 1) then s_cc => x_cc bound = m + buff_size - 1 - elseif (dim == 2) then + else if (dim == 2) then s_cc => y_cc bound = n + buff_size - 1 else @@ -471,8 +441,7 @@ contains index = ghost_points_in(q)%loc(dim) temp_loc = ghost_points_in(q)%ip_loc(dim) - do while ((temp_loc < s_cc(index) & - .or. temp_loc > s_cc(index + 1)) .and. (.not. bounds_error)) + do while ((temp_loc < s_cc(index) .or. temp_loc > s_cc(index + 1)) .and. (.not. bounds_error)) index = index + dir if (index < -buff_size .or. index > bound) then #if !defined(MFC_OpenACC) && !defined(MFC_OpenMP) @@ -488,9 +457,12 @@ contains print *, "x: ", x_cc(-buff_size), " to: ", x_cc(m + buff_size - 1) print *, "y: ", y_cc(-buff_size), " to: ", y_cc(n + buff_size - 1) if (p /= 0) print *, "z: ", z_cc(-buff_size), " to: ", z_cc(p + buff_size - 1) - print *, "Image point is located approximately ", (ghost_points_in(q)%loc(dim) - ghost_points_in(q)%ip_loc(dim))/(s_cc(1) - s_cc(0)), " grid cells away" + print *, "Image point is located approximately ", & + & (ghost_points_in(q)%loc(dim) - ghost_points_in(q)%ip_loc(dim))/(s_cc(1) - s_cc(0)), & + & " grid cells away" print *, "Levelset ", dist, " and Norm: ", norm(:) - print *, "A short term fix may include increasing buff_size further in m_helper_basic (currently set to a minimum of 10)" + print *, & + & "A short term fix may include increasing buff_size further in m_helper_basic (currently set to a minimum of 10)" #endif bounds_error = .true. end if @@ -511,21 +483,20 @@ contains end subroutine s_compute_image_points - !> Subroutine that finds the number of ghost points, used for allocating - !! memory. + !> Subroutine that finds the number of ghost points, used for allocating memory. subroutine s_find_num_ghost_points(num_gps_out) integer, intent(out) :: num_gps_out - - integer :: i, j, k, ii, jj, kk, gp_layers_z !< Iterator variables - integer :: num_gps_local !< local copies of the gp count to support GPU compute - logical :: is_gp + integer :: i, j, k, ii, jj, kk, gp_layers_z !< Iterator variables + integer :: num_gps_local !< local copies of the gp count to support GPU compute + logical :: is_gp num_gps_local = 0 gp_layers_z = gp_layers if (p == 0) gp_layers_z = 0 - $:GPU_PARALLEL_LOOP(private='[i,j,k,ii,jj,kk,is_gp]', copy='[num_gps_local]', firstprivate='[gp_layers,gp_layers_z]', collapse=3) + $:GPU_PARALLEL_LOOP(private='[i, j, k, ii, jj, kk, is_gp]', copy='[num_gps_local]', firstprivate='[gp_layers, & + & gp_layers_z]', collapse=3) do i = 0, m do j = 0, n do k = 0, p @@ -560,19 +531,20 @@ contains !> Function that finds the ghost points subroutine s_find_ghost_points(ghost_points_in) - type(ghost_point), dimension(num_gps), intent(INOUT) :: ghost_points_in - integer :: i, j, k, ii, jj, kk, gp_layers_z !< Iterator variables - integer :: xp, yp, zp !< periodicities - integer :: count, count_i, local_idx - integer :: patch_id, encoded_patch_id - logical :: is_gp + type(ghost_point), dimension(num_gps), intent(inout) :: ghost_points_in + integer :: i, j, k, ii, jj, kk, gp_layers_z !< Iterator variables + integer :: xp, yp, zp !< periodicities + integer :: count, count_i, local_idx + integer :: patch_id, encoded_patch_id + logical :: is_gp count = 0 count_i = 0 gp_layers_z = gp_layers if (p == 0) gp_layers_z = 0 - $:GPU_PARALLEL_LOOP(private='[i,j,k,ii,jj,kk,is_gp,local_idx,patch_id,encoded_patch_id,xp,yp,zp]', copyin='[count,count_i,glb_bounds]', firstprivate='[gp_layers,gp_layers_z]', collapse=3) + $:GPU_PARALLEL_LOOP(private='[i, j, k, ii, jj, kk, is_gp, local_idx, patch_id, encoded_patch_id, xp, yp, zp]', & + & copyin='[count, count_i, glb_bounds]', firstprivate='[gp_layers, gp_layers_z]', collapse=3) do i = 0, m do j = 0, n do k = 0, p @@ -640,22 +612,21 @@ contains end subroutine s_find_ghost_points - !> Function that computes the interpolation coefficients of image points + !> Function that computes the interpolation coefficients of image points subroutine s_compute_interpolation_coeffs(ghost_points_in) - type(ghost_point), dimension(num_gps), intent(INOUT) :: ghost_points_in - - real(wp), dimension(2, 2, 2) :: dist - real(wp), dimension(2, 2, 2) :: alpha - real(wp), dimension(2, 2, 2) :: interp_coeffs - real(wp) :: buf - real(wp), dimension(2, 2, 2) :: eta - type(ghost_point) :: gp - integer :: q, i, j, k, ii, jj, kk !< Grid indexes and iterators - integer :: patch_id - logical is_cell_center - - $:GPU_PARALLEL_LOOP(private='[q,i,j,k,ii,jj,kk,dist,buf,gp,interp_coeffs,eta,alpha,patch_id,is_cell_center]') + type(ghost_point), dimension(num_gps), intent(inout) :: ghost_points_in + real(wp), dimension(2, 2, 2) :: dist + real(wp), dimension(2, 2, 2) :: alpha + real(wp), dimension(2, 2, 2) :: interp_coeffs + real(wp) :: buf + real(wp), dimension(2, 2, 2) :: eta + type(ghost_point) :: gp + integer :: q, i, j, k, ii, jj, kk !< Grid indexes and iterators + integer :: patch_id + logical :: is_cell_center + + $:GPU_PARALLEL_LOOP(private='[q, i, j, k, ii, jj, kk, dist, buf, gp, interp_coeffs, eta, alpha, patch_id, is_cell_center]') do q = 1, num_gps gp = ghost_points_in(q) ! Get the interpolation points @@ -664,7 +635,7 @@ contains if (p /= 0) then k = gp%ip_grid(3) else - k = 0; + k = 0 end if ! get the distance to a cell in each direction @@ -673,15 +644,12 @@ contains do ii = 0, 1 do jj = 0, 1 if (p == 0) then - dist(1 + ii, 1 + jj, 1) = sqrt( & - (x_cc(i + ii) - gp%ip_loc(1))**2 + & - (y_cc(j + jj) - gp%ip_loc(2))**2) + dist(1 + ii, 1 + jj, 1) = sqrt((x_cc(i + ii) - gp%ip_loc(1))**2 + (y_cc(j + jj) - gp%ip_loc(2))**2) else do kk = 0, 1 - dist(1 + ii, 1 + jj, 1 + kk) = sqrt( & - (x_cc(i + ii) - gp%ip_loc(1))**2 + & - (y_cc(j + jj) - gp%ip_loc(2))**2 + & - (z_cc(k + kk) - gp%ip_loc(3))**2) + dist(1 + ii, 1 + jj, & + & 1 + kk) = sqrt((x_cc(i + ii) - gp%ip_loc(1))**2 + (y_cc(j + jj) - gp%ip_loc(2))**2 + (z_cc(k & + & + kk) - gp%ip_loc(3))**2) end do end if end do @@ -718,16 +686,15 @@ contains if (ib_markers%sf(i + 1, j + 1, k) /= 0) alpha(2, 2, 1) = 0._wp if (p == 0) then - eta(:, :, 1) = 1._wp/dist(:, :, 1)**2 - buf = sum(alpha(:, :, 1)*eta(:, :, 1)) + eta(:,:,1) = 1._wp/dist(:,:,1)**2 + buf = sum(alpha(:,:,1)*eta(:,:,1)) if (buf > 0._wp) then - interp_coeffs(:, :, 1) = alpha(:, :, 1)*eta(:, :, 1)/buf + interp_coeffs(:,:,1) = alpha(:,:,1)*eta(:,:,1)/buf else - buf = sum(eta(:, :, 1)) - interp_coeffs(:, :, 1) = eta(:, :, 1)/buf + buf = sum(eta(:,:,1)) + interp_coeffs(:,:,1) = eta(:,:,1)/buf end if else - if (ib_markers%sf(i, j, k + 1) /= 0) alpha(1, 1, 2) = 0._wp if (ib_markers%sf(i + 1, j, k + 1) /= 0) alpha(2, 1, 2) = 0._wp if (ib_markers%sf(i, j + 1, k + 1) /= 0) alpha(1, 2, 2) = 0._wp @@ -742,7 +709,6 @@ contains interp_coeffs = eta/buf end if end if - end if ghost_points_in(q)%interp_coeffs = interp_coeffs @@ -751,10 +717,11 @@ contains end subroutine s_compute_interpolation_coeffs - !> Function that uses the interpolation coefficients and the current state - !! at the cell centers in order to estimate the state at the image point + !> Function that uses the interpolation coefficients and the current state at the cell centers in order to estimate the state at + !! the image point !! @param gp Ghost point data structure - !> @brief Interpolates primitive variables from the fluid domain to a ghost point's image point using bilinear or trilinear interpolation. + !> @brief Interpolates primitive variables from the fluid domain to a ghost point's image point using bilinear or trilinear + !! interpolation. !! @param alpha_rho_IP Partial density at image point !! @param alpha_IP Volume fraction at image point !! @param pres_IP Pressure at image point @@ -769,32 +736,26 @@ contains !! @param mv_in Mass of vapor in bubble array !! @param presb_IP Bubble node pressure at image point !! @param massv_IP Bubble node vapor mass at image point - subroutine s_interpolate_image_point(q_prim_vf, gp, alpha_rho_IP, alpha_IP, & - pres_IP, vel_IP, c_IP, r_IP, v_IP, pb_IP, & - mv_IP, nmom_IP, pb_in, mv_in, presb_IP, massv_IP) + subroutine s_interpolate_image_point(q_prim_vf, gp, alpha_rho_IP, alpha_IP, pres_IP, vel_IP, c_IP, r_IP, v_IP, pb_IP, mv_IP, & + & nmom_IP, pb_in, mv_in, presb_IP, massv_IP) $:GPU_ROUTINE(parallelism='[seq]') - type(scalar_field), & - dimension(sys_size), & - intent(IN) :: q_prim_vf !< Primitive Variables - - real(stp), optional, dimension(idwbuff(1)%beg:, idwbuff(2)%beg:, idwbuff(3)%beg:, 1:, 1:), intent(IN) :: pb_in, mv_in - - type(ghost_point), intent(IN) :: gp - real(wp), intent(INOUT) :: pres_IP - real(wp), dimension(3), intent(INOUT) :: vel_IP - real(wp), intent(INOUT) :: c_IP + type(scalar_field), dimension(sys_size), intent(in) :: q_prim_vf !< Primitive Variables + real(stp), optional, dimension(idwbuff(1)%beg:,idwbuff(2)%beg:,idwbuff(3)%beg:,1:,1:), intent(in) :: pb_in, mv_in + type(ghost_point), intent(in) :: gp + real(wp), intent(inout) :: pres_IP + real(wp), dimension(3), intent(inout) :: vel_IP + real(wp), intent(inout) :: c_IP #:if not MFC_CASE_OPTIMIZATION and USING_AMD - real(wp), dimension(3), intent(INOUT) :: alpha_IP, alpha_rho_IP + real(wp), dimension(3), intent(inout) :: alpha_IP, alpha_rho_IP #:else - real(wp), dimension(num_fluids), intent(INOUT) :: alpha_IP, alpha_rho_IP + real(wp), dimension(num_fluids), intent(inout) :: alpha_IP, alpha_rho_IP #:endif - real(wp), optional, dimension(:), intent(INOUT) :: r_IP, v_IP, pb_IP, mv_IP - real(wp), optional, dimension(:), intent(INOUT) :: nmom_IP - real(wp), optional, dimension(:), intent(INOUT) :: presb_IP, massv_IP - - integer :: i, j, k, l, q !< Iterator variables - integer :: i1, i2, j1, j2, k1, k2 !< Iterator variables - real(wp) :: coeff + real(wp), optional, dimension(:), intent(inout) :: r_IP, v_IP, pb_IP, mv_IP + real(wp), optional, dimension(:), intent(inout) :: nmom_IP + real(wp), optional, dimension(:), intent(inout) :: presb_IP, massv_IP + integer :: i, j, k, l, q !< Iterator variables + integer :: i1, i2, j1, j2, k1, k2 !< Iterator variables + real(wp) :: coeff i1 = gp%ip_grid(1); i2 = i1 + 1 j1 = gp%ip_grid(2); j2 = j1 + 1 @@ -835,24 +796,19 @@ contains do j = j1, j2 $:GPU_LOOP(parallelism='[seq]') do k = k1, k2 - coeff = gp%interp_coeffs(i - i1 + 1, j - j1 + 1, k - k1 + 1) - pres_IP = pres_IP + coeff* & - q_prim_vf(E_idx)%sf(i, j, k) + pres_IP = pres_IP + coeff*q_prim_vf(E_idx)%sf(i, j, k) $:GPU_LOOP(parallelism='[seq]') do q = momxb, momxe - vel_IP(q + 1 - momxb) = vel_IP(q + 1 - momxb) + coeff* & - q_prim_vf(q)%sf(i, j, k) + vel_IP(q + 1 - momxb) = vel_IP(q + 1 - momxb) + coeff*q_prim_vf(q)%sf(i, j, k) end do $:GPU_LOOP(parallelism='[seq]') do l = contxb, contxe - alpha_rho_IP(l) = alpha_rho_IP(l) + coeff* & - q_prim_vf(l)%sf(i, j, k) - alpha_IP(l) = alpha_IP(l) + coeff* & - q_prim_vf(advxb + l - 1)%sf(i, j, k) + alpha_rho_IP(l) = alpha_rho_IP(l) + coeff*q_prim_vf(l)%sf(i, j, k) + alpha_IP(l) = alpha_IP(l) + coeff*q_prim_vf(advxb + l - 1)%sf(i, j, k) end do if (surface_tension) then @@ -881,16 +837,14 @@ contains if (.not. polytropic) then do q = 1, nb do l = 1, nnode - presb_IP((q - 1)*nnode + l) = presb_IP((q - 1)*nnode + l) + & - coeff*real(pb_in(i, j, k, l, q), kind=wp) - massv_IP((q - 1)*nnode + l) = massv_IP((q - 1)*nnode + l) + & - coeff*real(mv_in(i, j, k, l, q), kind=wp) + presb_IP((q - 1)*nnode + l) = presb_IP((q - 1)*nnode + l) + coeff*real(pb_in(i, j, k, l, q), & + & kind=wp) + massv_IP((q - 1)*nnode + l) = massv_IP((q - 1)*nnode + l) + coeff*real(mv_in(i, j, k, l, q), & + & kind=wp) end do end do end if - end if - end do end do end do @@ -902,17 +856,16 @@ contains impure subroutine s_update_mib(num_ibs) integer, intent(in) :: num_ibs - - integer :: i, j, k, ierr, z_gp_layers + integer :: i, j, k, ierr, z_gp_layers call nvtxStartRange("UPDATE-MIBM") ! Clears the existing immersed boundary indices z_gp_layers = 0; if (p /= 0) z_gp_layers = gp_layers + 1 - $:GPU_PARALLEL_LOOP(private='[i,j,k]') + $:GPU_PARALLEL_LOOP(private='[i, j, k]') do i = -gp_layers - 1, m + gp_layers + 1; do j = -gp_layers - 1, n + gp_layers + 1; do k = -z_gp_layers, p + z_gp_layers - ib_markers%sf(i, j, k) = 0._wp - end do; end do; end do + ib_markers%sf(i, j, k) = 0._wp + end do; end do; end do $:END_GPU_PARALLEL_LOOP() ! recalulcate the rotation matrix based upon the new angles @@ -948,17 +901,17 @@ contains !> @brief Computes pressure and viscous forces and torques on immersed bodies via a volume integration method. subroutine s_compute_ib_forces(q_prim_vf, fluid_pp) - ! real(wp), dimension(idwbuff(1)%beg:idwbuff(1)%end, & - ! idwbuff(2)%beg:idwbuff(2)%end, & - ! idwbuff(3)%beg:idwbuff(3)%end), intent(in) :: pressure - type(scalar_field), dimension(1:sys_size), intent(in) :: q_prim_vf + ! real(wp), dimension(idwbuff(1)%beg:idwbuff(1)%end, & idwbuff(2)%beg:idwbuff(2)%end, & idwbuff(3)%beg:idwbuff(3)%end), + ! intent(in) :: pressure + type(scalar_field), dimension(1:sys_size), intent(in) :: q_prim_vf type(physical_parameters), dimension(1:num_fluids), intent(in) :: fluid_pp - - integer :: gp_id, i, j, k, l, q, ib_idx, fluid_idx - real(wp), dimension(num_ibs, 3) :: forces, torques - real(wp), dimension(1:3, 1:3) :: viscous_stress_div, viscous_stress_div_1, viscous_stress_div_2 ! viscous stress tensor with temp vectors to hold divergence calculations + integer :: gp_id, i, j, k, l, q, ib_idx, fluid_idx + real(wp), dimension(num_ibs, 3) :: forces, torques + real(wp), dimension(1:3,1:3) :: viscous_stress_div, viscous_stress_div_1, & + & viscous_stress_div_2 ! viscous stress tensor with temp vectors to hold divergence calculations real(wp), dimension(1:3) :: local_force_contribution, radial_vector, local_torque_contribution, vel - real(wp) :: cell_volume, dx, dy, dz, dynamic_viscosity + real(wp) :: cell_volume, dx, dy, dz, dynamic_viscosity + #:if not MFC_CASE_OPTIMIZATION and USING_AMD real(wp), dimension(3) :: dynamic_viscosities #:else @@ -980,7 +933,10 @@ contains end do end if - $:GPU_PARALLEL_LOOP(private='[ib_idx,fluid_idx, radial_vector,local_force_contribution,cell_volume,local_torque_contribution, dynamic_viscosity, viscous_stress_div, viscous_stress_div_1, viscous_stress_div_2, dx, dy, dz]', copy='[forces,torques]', copyin='[ib_markers,patch_ib,dynamic_viscosities]', collapse=3) + $:GPU_PARALLEL_LOOP(private='[ib_idx, fluid_idx, radial_vector, local_force_contribution, cell_volume, & + & local_torque_contribution, dynamic_viscosity, viscous_stress_div, viscous_stress_div_1, & + & viscous_stress_div_2, dx, dy, dz]', copy='[forces, torques]', copyin='[ib_markers, patch_ib, & + & dynamic_viscosities]', collapse=3) do i = 0, m do j = 0, n do k = 0, p @@ -988,23 +944,30 @@ contains if (ib_idx /= 0) then ! get the vector pointing to the grid cell from the IB centroid if (num_dims == 3) then - radial_vector = [x_cc(i), y_cc(j), z_cc(k)] - [patch_ib(ib_idx)%x_centroid, patch_ib(ib_idx)%y_centroid, patch_ib(ib_idx)%z_centroid] + radial_vector = [x_cc(i), y_cc(j), z_cc(k)] - [patch_ib(ib_idx)%x_centroid, & + & patch_ib(ib_idx)%y_centroid, patch_ib(ib_idx)%z_centroid] else - radial_vector = [x_cc(i), y_cc(j), 0._wp] - [patch_ib(ib_idx)%x_centroid, patch_ib(ib_idx)%y_centroid, 0._wp] + radial_vector = [x_cc(i), y_cc(j), 0._wp] - [patch_ib(ib_idx)%x_centroid, & + & patch_ib(ib_idx)%y_centroid, 0._wp] end if dx = x_cc(i + 1) - x_cc(i) dy = y_cc(j + 1) - y_cc(j) local_force_contribution(:) = 0._wp do fluid_idx = 0, num_fluids - 1 - ! Get the pressure contribution to force via a finite difference to compute the 2D components of the gradient of the pressure and cell volume - local_force_contribution(1) = local_force_contribution(1) - (q_prim_vf(E_idx + fluid_idx)%sf(i + 1, j, k) - q_prim_vf(E_idx + fluid_idx)%sf(i - 1, j, k))/(2._wp*dx) ! force is the negative pressure gradient - local_force_contribution(2) = local_force_contribution(2) - (q_prim_vf(E_idx + fluid_idx)%sf(i, j + 1, k) - q_prim_vf(E_idx + fluid_idx)%sf(i, j - 1, k))/(2._wp*dy) + ! Get the pressure contribution to force via a finite difference to compute the 2D components of the + ! gradient of the pressure and cell volume + local_force_contribution(1) = local_force_contribution(1) - (q_prim_vf(E_idx + fluid_idx)%sf(i + 1, & + & j, k) - q_prim_vf(E_idx + fluid_idx)%sf(i - 1, j, & + & k))/(2._wp*dx) ! force is the negative pressure gradient + local_force_contribution(2) = local_force_contribution(2) - (q_prim_vf(E_idx + fluid_idx)%sf(i, & + & j + 1, k) - q_prim_vf(E_idx + fluid_idx)%sf(i, j - 1, k))/(2._wp*dy) cell_volume = abs(dx*dy) ! add the 3D component of the pressure gradient, if we are working in 3 dimensions if (num_dims == 3) then dz = z_cc(k + 1) - z_cc(k) - local_force_contribution(3) = local_force_contribution(3) - (q_prim_vf(E_idx + fluid_idx)%sf(i, j, k + 1) - q_prim_vf(E_idx + fluid_idx)%sf(i, j, k - 1))/(2._wp*dz) + local_force_contribution(3) = local_force_contribution(3) - (q_prim_vf(E_idx + fluid_idx)%sf(i, & + & j, k + 1) - q_prim_vf(E_idx + fluid_idx)%sf(i, j, k - 1))/(2._wp*dz) cell_volume = abs(cell_volume*dz) end if end do @@ -1015,27 +978,35 @@ contains dynamic_viscosity = 0._wp do fluid_idx = 1, num_fluids ! local dynamic viscosity is the dynamic viscosity of the fluid times alpha of the fluid - dynamic_viscosity = dynamic_viscosity + (q_prim_vf(fluid_idx + advxb - 1)%sf(i, j, k)*dynamic_viscosities(fluid_idx)) + dynamic_viscosity = dynamic_viscosity + (q_prim_vf(fluid_idx + advxb - 1)%sf(i, j, & + & k)*dynamic_viscosities(fluid_idx)) end do ! get the linear force components first call s_compute_viscous_stress_tensor(viscous_stress_div_1, q_prim_vf, dynamic_viscosity, i - 1, j, k) call s_compute_viscous_stress_tensor(viscous_stress_div_2, q_prim_vf, dynamic_viscosity, i + 1, j, k) - viscous_stress_div(1, 1:3) = (viscous_stress_div_2(1, 1:3) - viscous_stress_div_1(1, 1:3))/(2._wp*dx) ! get x derivative of the first-row of viscous stress tensor - local_force_contribution(1:3) = local_force_contribution(1:3) + viscous_stress_div(1, 1:3) ! add the x components of the divergence to the force + viscous_stress_div(1,1:3) = (viscous_stress_div_2(1,1:3) - viscous_stress_div_1(1, & + & 1:3))/(2._wp*dx) ! get x derivative of the first-row of viscous stress tensor + local_force_contribution(1:3) = local_force_contribution(1:3) + viscous_stress_div(1, & + & 1:3) ! add the x components of the divergence to the force call s_compute_viscous_stress_tensor(viscous_stress_div_1, q_prim_vf, dynamic_viscosity, i, j - 1, k) call s_compute_viscous_stress_tensor(viscous_stress_div_2, q_prim_vf, dynamic_viscosity, i, j + 1, k) - viscous_stress_div(2, 1:3) = (viscous_stress_div_2(2, 1:3) - viscous_stress_div_1(2, 1:3))/(2._wp*dy) ! get y derivative of the second-row of viscous stress tensor - local_force_contribution(1:3) = local_force_contribution(1:3) + viscous_stress_div(2, 1:3) ! add the y components of the divergence to the force + viscous_stress_div(2,1:3) = (viscous_stress_div_2(2,1:3) - viscous_stress_div_1(2, & + & 1:3))/(2._wp*dy) ! get y derivative of the second-row of viscous stress tensor + local_force_contribution(1:3) = local_force_contribution(1:3) + viscous_stress_div(2, & + & 1:3) ! add the y components of the divergence to the force if (num_dims == 3) then - call s_compute_viscous_stress_tensor(viscous_stress_div_1, q_prim_vf, dynamic_viscosity, i, j, k - 1) - call s_compute_viscous_stress_tensor(viscous_stress_div_2, q_prim_vf, dynamic_viscosity, i, j, k + 1) - viscous_stress_div(3, 1:3) = (viscous_stress_div_2(3, 1:3) - viscous_stress_div_1(3, 1:3))/(2._wp*dz) ! get z derivative of the third-row of viscous stress tensor - local_force_contribution(1:3) = local_force_contribution(1:3) + viscous_stress_div(3, 1:3) ! add the z components of the divergence to the force + call s_compute_viscous_stress_tensor(viscous_stress_div_1, q_prim_vf, dynamic_viscosity, i, j, & + & k - 1) + call s_compute_viscous_stress_tensor(viscous_stress_div_2, q_prim_vf, dynamic_viscosity, i, j, & + & k + 1) + viscous_stress_div(3,1:3) = (viscous_stress_div_2(3,1:3) - viscous_stress_div_1(3, & + & 1:3))/(2._wp*dz) ! get z derivative of the third-row of viscous stress tensor + local_force_contribution(1:3) = local_force_contribution(1:3) + viscous_stress_div(3, & + & 1:3) ! add the z components of the divergence to the force end if - end if call s_cross_product(radial_vector, local_force_contribution, local_torque_contribution) @@ -1072,8 +1043,9 @@ contains ! apply the summed forces do i = 1, num_ibs - patch_ib(i)%force(:) = forces(i, :) - patch_ib(i)%torque(:) = matmul(patch_ib(i)%rotation_matrix_inverse, torques(i, :)) ! torques must be converted to the local coordinates of the IB + patch_ib(i)%force(:) = forces(i,:) + patch_ib(i)%torque(:) = matmul(patch_ib(i)%rotation_matrix_inverse, torques(i, & + & :)) ! torques must be converted to the local coordinates of the IB end do call nvtxEndRange @@ -1095,17 +1067,14 @@ contains !> These patches include things like NACA airfoils and STL models subroutine s_compute_centroid_offset(ib_marker) - integer, intent(in) :: ib_marker - - integer :: i, j, k, num_cells, num_cells_local + integer, intent(in) :: ib_marker + integer :: i, j, k, num_cells, num_cells_local real(wp), dimension(1:3) :: center_of_mass, center_of_mass_local ! Offset only needs to be computes for specific geometries - if (patch_ib(ib_marker)%geometry == 4 .or. & - patch_ib(ib_marker)%geometry == 5 .or. & - patch_ib(ib_marker)%geometry == 11 .or. & - patch_ib(ib_marker)%geometry == 12) then + if (patch_ib(ib_marker)%geometry == 4 .or. patch_ib(ib_marker)%geometry == 5 .or. patch_ib(ib_marker) & + & %geometry == 11 .or. patch_ib(ib_marker)%geometry == 12) then center_of_mass_local = [0._wp, 0._wp, 0._wp] num_cells_local = 0 @@ -1134,31 +1103,32 @@ contains return end if - ! assign the centroid offset as a vector pointing from the true COM to the "centroid" in the input file and replace the current centroid - patch_ib(ib_marker)%centroid_offset = [patch_ib(ib_marker)%x_centroid, patch_ib(ib_marker)%y_centroid, patch_ib(ib_marker)%z_centroid] & - - center_of_mass + ! assign the centroid offset as a vector pointing from the true COM to the "centroid" in the input file and replace the + ! current centroid + patch_ib(ib_marker)%centroid_offset = [patch_ib(ib_marker)%x_centroid, patch_ib(ib_marker)%y_centroid, & + & patch_ib(ib_marker)%z_centroid] - center_of_mass patch_ib(ib_marker)%x_centroid = center_of_mass(1) patch_ib(ib_marker)%y_centroid = center_of_mass(2) patch_ib(ib_marker)%z_centroid = center_of_mass(3) ! rotate the centroid offset back into the local coords of the IB - patch_ib(ib_marker)%centroid_offset = matmul(patch_ib(ib_marker)%rotation_matrix_inverse, patch_ib(ib_marker)%centroid_offset) + patch_ib(ib_marker)%centroid_offset = matmul(patch_ib(ib_marker)%rotation_matrix_inverse, & + & patch_ib(ib_marker)%centroid_offset) else patch_ib(ib_marker)%centroid_offset(:) = [0._wp, 0._wp, 0._wp] end if end subroutine s_compute_centroid_offset - !> Computes the moment of inertia for an immersed boundary - !! @param ib_marker Immersed boundary marker index + !> Computes the moment of inertia for an immersed boundary + !! @param ib_marker Immersed boundary marker index subroutine s_compute_moment_of_inertia(ib_marker, axis) - real(wp), dimension(3), intent(in) :: axis !< the axis about which we compute the moment. Only required in 3D. - integer, intent(in) :: ib_marker - - real(wp) :: moment, distance_to_axis, cell_volume - real(wp), dimension(3) :: position, closest_point_along_axis, vector_to_axis, normal_axis - integer :: i, j, k, count + real(wp), dimension(3), intent(in) :: axis !< the axis about which we compute the moment. Only required in 3D. + integer, intent(in) :: ib_marker + real(wp) :: moment, distance_to_axis, cell_volume + real(wp), dimension(3) :: position, closest_point_along_axis, vector_to_axis, normal_axis + integer :: i, j, k, count if (p == 0) then normal_axis = [0, 0, 1] @@ -1171,42 +1141,47 @@ contains end if ! if the IB is in 2D or a 3D sphere, we can compute this exactly - if (patch_ib(ib_marker)%geometry == 2) then ! circle + if (patch_ib(ib_marker)%geometry == 2) then ! circle patch_ib(ib_marker)%moment = 0.5_wp*patch_ib(ib_marker)%mass*(patch_ib(ib_marker)%radius)**2 - elseif (patch_ib(ib_marker)%geometry == 3) then ! rectangle - patch_ib(ib_marker)%moment = patch_ib(ib_marker)%mass*(patch_ib(ib_marker)%length_x**2 + patch_ib(ib_marker)%length_y**2)/6._wp - elseif (patch_ib(ib_marker)%geometry == 6) then ! ellipse - patch_ib(ib_marker)%moment = 0.0625_wp*patch_ib(ib_marker)%mass*(patch_ib(ib_marker)%length_x**2 + patch_ib(ib_marker)%length_y**2) - elseif (patch_ib(ib_marker)%geometry == 8) then ! sphere + else if (patch_ib(ib_marker)%geometry == 3) then ! rectangle + patch_ib(ib_marker)%moment = patch_ib(ib_marker)%mass*(patch_ib(ib_marker)%length_x**2 + patch_ib(ib_marker) & + & %length_y**2)/6._wp + else if (patch_ib(ib_marker)%geometry == 6) then ! ellipse + patch_ib(ib_marker)%moment = 0.0625_wp*patch_ib(ib_marker)%mass*(patch_ib(ib_marker)%length_x**2 + patch_ib(ib_marker) & + & %length_y**2) + else if (patch_ib(ib_marker)%geometry == 8) then ! sphere patch_ib(ib_marker)%moment = 0.4*patch_ib(ib_marker)%mass*(patch_ib(ib_marker)%radius)**2 - - else ! we do not have an analytic moment of inertia calculation and need to approximate it directly via a sum + else ! we do not have an analytic moment of inertia calculation and need to approximate it directly via a sum count = 0 moment = 0._wp - cell_volume = (x_cc(1) - x_cc(0))*(y_cc(1) - y_cc(0)) ! computed without grid stretching. Update in the loop to perform with stretching + cell_volume = (x_cc(1) - x_cc(0))*(y_cc(1) - y_cc(0)) & + & ! computed without grid stretching. Update in the loop to perform with stretching if (p /= 0) then cell_volume = cell_volume*(z_cc(1) - z_cc(0)) end if - $:GPU_PARALLEL_LOOP(private='[position,closest_point_along_axis,vector_to_axis,distance_to_axis]', copy='[moment,count]', copyin='[ib_marker,cell_volume,normal_axis]', collapse=3) + $:GPU_PARALLEL_LOOP(private='[position, closest_point_along_axis, vector_to_axis, distance_to_axis]', copy='[moment, & + & count]', copyin='[ib_marker, cell_volume, normal_axis]', collapse=3) do i = 0, m do j = 0, n do k = 0, p if (ib_markers%sf(i, j, k) == ib_marker) then $:GPU_ATOMIC(atomic='update') - count = count + 1 ! increment the count of total cells in the boundary + count = count + 1 ! increment the count of total cells in the boundary ! get the position in local coordinates so that the axis passes through 0, 0, 0 if (p == 0) then - position = [x_cc(i), y_cc(j), 0._wp] - [patch_ib(ib_marker)%x_centroid, patch_ib(ib_marker)%y_centroid, 0._wp] + position = [x_cc(i), y_cc(j), 0._wp] - [patch_ib(ib_marker)%x_centroid, & + & patch_ib(ib_marker)%y_centroid, 0._wp] else - position = [x_cc(i), y_cc(j), z_cc(k)] - [patch_ib(ib_marker)%x_centroid, patch_ib(ib_marker)%y_centroid, patch_ib(ib_marker)%z_centroid] + position = [x_cc(i), y_cc(j), z_cc(k)] - [patch_ib(ib_marker)%x_centroid, & + & patch_ib(ib_marker)%y_centroid, patch_ib(ib_marker)%z_centroid] end if ! project the position along the axis to find the closest distance to the rotation axis closest_point_along_axis = normal_axis*dot_product(normal_axis, position) vector_to_axis = position - closest_point_along_axis - distance_to_axis = dot_product(vector_to_axis, vector_to_axis) ! saves the distance to the axis squared + distance_to_axis = dot_product(vector_to_axis, vector_to_axis) ! saves the distance to the axis squared ! compute the position component of the moment $:GPU_ATOMIC(atomic='update') @@ -1238,10 +1213,12 @@ contains ! check if the boundary has left the domain, and then correct if (patch_ib(patch_id)%${X}$_centroid < glb_bounds(${ID}$)%beg) then ! if the boundary exited "left", wrap it back around to the "right" - patch_ib(patch_id)%${X}$_centroid = patch_ib(patch_id)%${X}$_centroid + (glb_bounds(${ID}$)%end - glb_bounds(${ID}$)%beg) + patch_ib(patch_id)%${X}$_centroid = patch_ib(patch_id)%${X}$_centroid + (glb_bounds(${ID}$)%end & + & - glb_bounds(${ID}$)%beg) else if (patch_ib(patch_id)%${X}$_centroid > glb_bounds(${ID}$)%end) then ! if the boundary exited "right", wrap it back around to the "left" - patch_ib(patch_id)%${X}$_centroid = patch_ib(patch_id)%${X}$_centroid - (glb_bounds(${ID}$)%end - glb_bounds(${ID}$)%beg) + patch_ib(patch_id)%${X}$_centroid = patch_ib(patch_id)%${X}$_centroid - (glb_bounds(${ID}$)%end & + & - glb_bounds(${ID}$)%beg) end if end if end if @@ -1252,13 +1229,15 @@ contains !> @brief Computes the cross product c = a x b of two 3D vectors. subroutine s_cross_product(a, b, c) + $:GPU_ROUTINE(parallelism='[seq]') - real(wp), intent(in) :: a(3), b(3) + real(wp), intent(in) :: a(3), b(3) real(wp), intent(out) :: c(3) c(1) = a(2)*b(3) - a(3)*b(2) c(2) = a(3)*b(1) - a(1)*b(3) c(3) = a(1)*b(2) - a(2)*b(1) + end subroutine s_cross_product end module m_ibm diff --git a/src/simulation/m_igr.fpp b/src/simulation/m_igr.fpp index 78956ef803..a4eafa7f75 100644 --- a/src/simulation/m_igr.fpp +++ b/src/simulation/m_igr.fpp @@ -8,46 +8,37 @@ !> @brief Iterative ghost rasterization (IGR) for sharp immersed boundary treatment module m_igr - use m_derived_types !< Definitions of the derived types - + use m_derived_types !< Definitions of the derived types use m_global_parameters - use m_variables_conversion - use m_mpi_proxy - use m_helper - use m_boundary_common implicit none - private; public :: s_initialize_igr_module, & - s_igr_iterative_solve, & - s_igr_riemann_solver, & - s_igr_sigma_x, & - s_igr_flux_add, & - s_finalize_igr_module + private; public :: s_initialize_igr_module, s_igr_iterative_solve, s_igr_riemann_solver, s_igr_sigma_x, s_igr_flux_add, & + & s_finalize_igr_module -!> @cond + !> @cond #ifdef __NVCOMPILER_GPU_UNIFIED_MEM - integer, dimension(3) :: nv_uvm_temp_on_gpu - real(wp), pointer, contiguous, dimension(:, :, :) :: jac, jac_rhs, jac_old - real(wp), allocatable, dimension(:, :, :), pinned, target :: jac_host - real(wp), allocatable, dimension(:, :, :), pinned, target :: jac_rhs_host - real(wp), allocatable, dimension(:, :, :), pinned, target :: jac_old_host + integer, dimension(3) :: nv_uvm_temp_on_gpu + real(wp), pointer, contiguous, dimension(:,:,:) :: jac, jac_rhs, jac_old + real(wp), allocatable, dimension(:,:,:), pinned, target :: jac_host + real(wp), allocatable, dimension(:,:,:), pinned, target :: jac_rhs_host + real(wp), allocatable, dimension(:,:,:), pinned, target :: jac_old_host #else -!> @endcond - real(wp), allocatable, target, dimension(:, :, :) :: jac - real(wp), allocatable, dimension(:, :, :) :: jac_rhs, jac_old + !> @endcond + real(wp), allocatable, target, dimension(:,:,:) :: jac + real(wp), allocatable, dimension(:,:,:) :: jac_rhs, jac_old $:GPU_DECLARE(create='[jac, jac_rhs, jac_old]') -!> @cond + !> @cond #endif -!> @endcond + !> @endcond type(scalar_field), dimension(1) :: jac_sf $:GPU_DECLARE(create='[jac_sf]') - real(wp), allocatable, dimension(:, :) :: Res_igr + real(wp), allocatable, dimension(:,:) :: Res_igr $:GPU_DECLARE(create='[Res_igr]') real(wp) :: alf_igr @@ -65,64 +56,22 @@ module m_igr integer, parameter :: vidxe = 3 #if defined(MFC_OpenMP) - real(wp) :: coeff_L(-1:3) = [ & - -3._wp/60._wp, & ! Index -1 - 27._wp/60._wp, & ! Index 0 - 47._wp/60._wp, & ! Index 1 - -13._wp/60._wp, & ! Index 2 - 2._wp/60._wp & ! Index 3 - ] - - real(wp) :: coeff_R(-2:2) = [ & - 2._wp/60._wp, & ! Index -2 - -13._wp/60._wp, & ! Index -1 - 47._wp/60._wp, & ! Index 0 - 27._wp/60._wp, & ! Index 1 - -3._wp/60._wp & ! Index 2 - ] + real(wp) :: coeff_L(-1:3) = [-3._wp/60._wp, 27._wp/60._wp, 47._wp/60._wp, -13._wp/60._wp, 2._wp/60._wp] + real(wp) :: coeff_R(-2:2) = [2._wp/60._wp, -13._wp/60._wp, 47._wp/60._wp, 27._wp/60._wp, -3._wp/60._wp] #else - real(wp), parameter :: coeff_L(-1:3) = [ & - -3._wp/60._wp, & ! Index -1 - 27._wp/60._wp, & ! Index 0 - 47._wp/60._wp, & ! Index 1 - -13._wp/60._wp, & ! Index 2 - 2._wp/60._wp & ! Index 3 - ] - - real(wp), parameter :: coeff_R(-2:2) = [ & - 2._wp/60._wp, & ! Index -2 - -13._wp/60._wp, & ! Index -1 - 47._wp/60._wp, & ! Index 0 - 27._wp/60._wp, & ! Index 1 - -3._wp/60._wp & ! Index 2 - ] + real(wp), parameter :: coeff_L(-1:3) = [-3._wp/60._wp, 27._wp/60._wp, 47._wp/60._wp, -13._wp/60._wp, 2._wp/60._wp] + real(wp), parameter :: coeff_R(-2:2) = [2._wp/60._wp, -13._wp/60._wp, 47._wp/60._wp, 27._wp/60._wp, -3._wp/60._wp] #endif #:elif igr_order == 3 integer, parameter :: vidxb = -1 integer, parameter :: vidxe = 2 #if defined(MFC_OpenMP) - real(wp) :: coeff_L(0:2) = [ & - 2._wp/6._wp, & ! Index 0 - 5._wp/6._wp, & ! Index 1 - -1._wp/6._wp & ! Index 2 - ] - real(wp) :: coeff_R(-1:1) = [ & - -1._wp/6._wp, & ! Index -1 - 5._wp/6._wp, & ! Index 0 - 2._wp/6._wp & ! Index 1 - ] + real(wp) :: coeff_L(0:2) = [2._wp/6._wp, 5._wp/6._wp, -1._wp/6._wp] + real(wp) :: coeff_R(-1:1) = [-1._wp/6._wp, 5._wp/6._wp, 2._wp/6._wp] #else - real(wp), parameter :: coeff_L(0:2) = [ & - 2._wp/6._wp, & ! Index 0 - 5._wp/6._wp, & ! Index 1 - -1._wp/6._wp & ! Index 2 - ] - real(wp), parameter :: coeff_R(-1:1) = [ & - -1._wp/6._wp, & ! Index -1 - 5._wp/6._wp, & ! Index 0 - 2._wp/6._wp & ! Index 1 - ] + real(wp), parameter :: coeff_L(0:2) = [2._wp/6._wp, 5._wp/6._wp, -1._wp/6._wp] + real(wp), parameter :: coeff_R(-1:1) = [-1._wp/6._wp, 5._wp/6._wp, 2._wp/6._wp] #endif #:endif @@ -135,7 +84,8 @@ module m_igr contains - !> @brief Allocates and initializes arrays, coefficients, and GPU data structures for the implicit gradient reconstruction module. + !> @brief Allocates and initializes arrays, coefficients, and GPU data structures for the implicit gradient reconstruction + !! module. subroutine s_initialize_igr_module() if (viscous) then @@ -151,15 +101,11 @@ contains end if #ifndef __NVCOMPILER_GPU_UNIFIED_MEM - @:ALLOCATE(jac(idwbuff(1)%beg:idwbuff(1)%end, & - idwbuff(2)%beg:idwbuff(2)%end, & - idwbuff(3)%beg:idwbuff(3)%end)) + @:ALLOCATE(jac(idwbuff(1)%beg:idwbuff(1)%end, idwbuff(2)%beg:idwbuff(2)%end, idwbuff(3)%beg:idwbuff(3)%end)) @:ALLOCATE(jac_rhs(-1:m,-1:n,-1:p)) - if (igr_iter_solver == 1) then ! Jacobi iteration - @:ALLOCATE(jac_old(idwbuff(1)%beg:idwbuff(1)%end, & - idwbuff(2)%beg:idwbuff(2)%end, & - idwbuff(3)%beg:idwbuff(3)%end)) + if (igr_iter_solver == 1) then ! Jacobi iteration + @:ALLOCATE(jac_old(idwbuff(1)%beg:idwbuff(1)%end, idwbuff(2)%beg:idwbuff(2)%end, idwbuff(3)%beg:idwbuff(3)%end)) end if #else ! create map @@ -167,47 +113,36 @@ contains nv_uvm_temp_on_gpu(1:nv_uvm_igr_temps_on_gpu) = 1 if (nv_uvm_temp_on_gpu(1) == 1) then - @:ALLOCATE(jac(idwbuff(1)%beg:idwbuff(1)%end, & - idwbuff(2)%beg:idwbuff(2)%end, & - idwbuff(3)%beg:idwbuff(3)%end)) + @:ALLOCATE(jac(idwbuff(1)%beg:idwbuff(1)%end, idwbuff(2)%beg:idwbuff(2)%end, idwbuff(3)%beg:idwbuff(3)%end)) @:PREFER_GPU(jac) else - allocate (jac_host(idwbuff(1)%beg:idwbuff(1)%end, & - idwbuff(2)%beg:idwbuff(2)%end, & - idwbuff(3)%beg:idwbuff(3)%end)) + allocate (jac_host(idwbuff(1)%beg:idwbuff(1)%end,idwbuff(2)%beg:idwbuff(2)%end,idwbuff(3)%beg:idwbuff(3)%end)) - jac(idwbuff(1)%beg:idwbuff(1)%end, & - idwbuff(2)%beg:idwbuff(2)%end, & - idwbuff(3)%beg:idwbuff(3)%end) => jac_host(:, :, :) + jac(idwbuff(1)%beg:idwbuff(1)%end,idwbuff(2)%beg:idwbuff(2)%end,idwbuff(3)%beg:idwbuff(3)%end) => jac_host(:,:,:) end if if (nv_uvm_temp_on_gpu(2) == 1) then @:ALLOCATE(jac_rhs(-1:m,-1:n,-1:p)) @:PREFER_GPU(jac_rhs) else - allocate (jac_rhs_host(-1:m, -1:n, -1:p)) - jac_rhs(-1:m, -1:n, -1:p) => jac_rhs_host(:, :, :) + allocate (jac_rhs_host(-1:m,-1:n,-1:p)) + jac_rhs(-1:m,-1:n,-1:p) => jac_rhs_host(:,:,:) end if - if (igr_iter_solver == 1) then ! Jacobi iteration + if (igr_iter_solver == 1) then ! Jacobi iteration if (nv_uvm_temp_on_gpu(3) == 1) then - @:ALLOCATE(jac_old(idwbuff(1)%beg:idwbuff(1)%end, & - idwbuff(2)%beg:idwbuff(2)%end, & - idwbuff(3)%beg:idwbuff(3)%end)) + @:ALLOCATE(jac_old(idwbuff(1)%beg:idwbuff(1)%end, idwbuff(2)%beg:idwbuff(2)%end, idwbuff(3)%beg:idwbuff(3)%end)) @:PREFER_GPU(jac_old) else - allocate (jac_old_host(idwbuff(1)%beg:idwbuff(1)%end, & - idwbuff(2)%beg:idwbuff(2)%end, & - idwbuff(3)%beg:idwbuff(3)%end)) + allocate (jac_old_host(idwbuff(1)%beg:idwbuff(1)%end,idwbuff(2)%beg:idwbuff(2)%end,idwbuff(3)%beg:idwbuff(3)%end)) - jac_old(idwbuff(1)%beg:idwbuff(1)%end, & - idwbuff(2)%beg:idwbuff(2)%end, & - idwbuff(3)%beg:idwbuff(3)%end) => jac_old_host(:, :, :) + jac_old(idwbuff(1)%beg:idwbuff(1)%end,idwbuff(2)%beg:idwbuff(2)%end, & + & idwbuff(3)%beg:idwbuff(3)%end) => jac_old_host(:,:,:) end if end if #endif - $:GPU_PARALLEL_LOOP(private='[j,k,l]', collapse=3) + $:GPU_PARALLEL_LOOP(private='[j, k, l]', collapse=3) do l = idwbuff(3)%beg, idwbuff(3)%end do k = idwbuff(2)%beg, idwbuff(2)%end do j = idwbuff(1)%beg, idwbuff(1)%end @@ -227,7 +162,7 @@ contains #:if not MFC_CASE_OPTIMIZATION if (igr_order == 3) then - vidxb = -1; vidxe = 2; + vidxb = -1; vidxe = 2 $:GPU_UPDATE(device='[vidxb, vidxe]') @:ALLOCATE(coeff_L(0:2)) @@ -239,9 +174,8 @@ contains coeff_R(1) = (2._wp/6._wp) coeff_R(0) = (5._wp/6._wp) coeff_R(-1) = (-1._wp/6._wp) - - elseif (igr_order == 5) then - vidxb = -2; vidxe = 3; + else if (igr_order == 5) then + vidxb = -2; vidxe = 3 $:GPU_UPDATE(device='[vidxb, vidxe]') @:ALLOCATE(coeff_L(-1:3)) @@ -275,16 +209,16 @@ contains !> @brief Iteratively solves the implicit gradient reconstruction system using Jacobi or Gauss-Seidel relaxation. subroutine s_igr_iterative_solve(q_cons_vf, bc_type, t_step) + #ifdef _CRAYFTN - !DIR$ OPTIMIZE (-haggress) + ! DIR$ OPTIMIZE (-haggress) #endif - type(scalar_field), dimension(sys_size), intent(inout) :: q_cons_vf - type(integer_field), dimension(1:num_dims, 1:2), intent(in) :: bc_type - integer, intent(in) :: t_step - - real(wp) :: rho_rx, rho_ry, rho_rz, rho_lx, rho_ly, rho_lz - real(wp) :: fd_coeff - integer :: num_iters + type(scalar_field), dimension(sys_size), intent(inout) :: q_cons_vf + type(integer_field), dimension(1:num_dims,1:2), intent(in) :: bc_type + integer, intent(in) :: t_step + real(wp) :: rho_rx, rho_ry, rho_rz, rho_lx, rho_ly, rho_lz + real(wp) :: fd_coeff + integer :: num_iters if (t_step == t_step_start) then num_iters = num_igr_warm_start_iters @@ -293,7 +227,7 @@ contains end if do q = 1, num_iters - $:GPU_PARALLEL_LOOP(collapse=3, private='[j,k,l,rho_lx, rho_rx, rho_ly, rho_ry, rho_lz, rho_rz, fd_coeff]') + $:GPU_PARALLEL_LOOP(collapse=3, private='[j, k, l, rho_lx, rho_rx, rho_ly, rho_ry, rho_lz, rho_rz, fd_coeff]') do l = 0, p do k = 0, n do j = 0, m @@ -318,39 +252,38 @@ contains fd_coeff = fd_coeff + q_cons_vf(i)%sf(j, k, l) end do - fd_coeff = 1._wp/fd_coeff + alf_igr* & - ((1._wp/dx(j)**2._wp)*(1._wp/rho_lx + 1._wp/rho_rx) + & - (1._wp/dy(k)**2._wp)*(1._wp/rho_ly + 1._wp/rho_ry)) + fd_coeff = 1._wp/fd_coeff + alf_igr*((1._wp/dx(j)**2._wp)*(1._wp/rho_lx + 1._wp/rho_rx) + (1._wp/dy(k) & + & **2._wp)*(1._wp/rho_ly + 1._wp/rho_ry)) if (num_dims == 3) then fd_coeff = fd_coeff + alf_igr*(1._wp/dz(l)**2._wp)*(1._wp/rho_lz + 1._wp/rho_rz) end if - if (igr_iter_solver == 1) then ! Jacobi iteration + if (igr_iter_solver == 1) then ! Jacobi iteration if (num_dims == 3) then - jac(j, k, l) = real((alf_igr/fd_coeff)* & - ((1._wp/dx(j)**2._wp)*(jac_old(j - 1, k, l)/rho_lx + jac_old(j + 1, k, l)/rho_rx) + & - (1._wp/dy(k)**2._wp)*(jac_old(j, k - 1, l)/rho_ly + jac_old(j, k + 1, l)/rho_ry) + & - (1._wp/dz(l)**2._wp)*(jac_old(j, k, l - 1)/rho_lz + jac_old(j, k, l + 1)/rho_rz)) + & - real(jac_rhs(j, k, l), kind=wp)/fd_coeff, kind=stp) + jac(j, k, l) = real((alf_igr/fd_coeff)*((1._wp/dx(j)**2._wp)*(jac_old(j - 1, k, & + & l)/rho_lx + jac_old(j + 1, k, l)/rho_rx) + (1._wp/dy(k)**2._wp)*(jac_old(j, k - 1, & + & l)/rho_ly + jac_old(j, k + 1, l)/rho_ry) + (1._wp/dz(l)**2._wp)*(jac_old(j, k, & + & l - 1)/rho_lz + jac_old(j, k, l + 1)/rho_rz)) + real(jac_rhs(j, k, l), kind=wp)/fd_coeff, & + & kind=stp) else - jac(j, k, l) = real((alf_igr/fd_coeff)* & - ((1._wp/dx(j)**2._wp)*(real(jac_old(j - 1, k, l), kind=wp)/rho_lx + real(jac_old(j + 1, k, l), kind=wp)/rho_rx) + & - (1._wp/dy(k)**2._wp)*(real(jac_old(j, k - 1, l), kind=wp)/rho_ly + real(jac_old(j, k + 1, l), kind=wp)/rho_ry)) + & - real(jac_rhs(j, k, l), kind=wp)/fd_coeff, kind=stp) + jac(j, k, l) = real((alf_igr/fd_coeff)*((1._wp/dx(j)**2._wp)*(real(jac_old(j - 1, k, l), & + & kind=wp)/rho_lx + real(jac_old(j + 1, k, l), & + & kind=wp)/rho_rx) + (1._wp/dy(k)**2._wp)*(real(jac_old(j, k - 1, l), & + & kind=wp)/rho_ly + real(jac_old(j, k + 1, l), kind=wp)/rho_ry)) + real(jac_rhs(j, k, l), & + & kind=wp)/fd_coeff, kind=stp) end if - else ! Gauss Seidel iteration + else ! Gauss Seidel iteration if (num_dims == 3) then - jac(j, k, l) = real((alf_igr/fd_coeff)* & - ((1._wp/dx(j)**2._wp)*(jac(j - 1, k, l)/rho_lx + jac(j + 1, k, l)/rho_rx) + & - (1._wp/dy(k)**2._wp)*(jac(j, k - 1, l)/rho_ly + jac(j, k + 1, l)/rho_ry) + & - (1._wp/dz(l)**2._wp)*(jac(j, k, l - 1)/rho_lz + jac(j, k, l + 1)/rho_rz)) + & - real(jac_rhs(j, k, l), kind=wp)/fd_coeff, kind=stp) + jac(j, k, l) = real((alf_igr/fd_coeff)*((1._wp/dx(j)**2._wp)*(jac(j - 1, k, & + & l)/rho_lx + jac(j + 1, k, l)/rho_rx) + (1._wp/dy(k)**2._wp)*(jac(j, k - 1, & + & l)/rho_ly + jac(j, k + 1, l)/rho_ry) + (1._wp/dz(l)**2._wp)*(jac(j, k, & + & l - 1)/rho_lz + jac(j, k, l + 1)/rho_rz)) + real(jac_rhs(j, k, l), kind=wp)/fd_coeff, & + & kind=stp) else - jac(j, k, l) = real((alf_igr/fd_coeff)* & - ((1._wp/dx(j)**2._wp)*(jac(j - 1, k, l)/rho_lx + jac(j + 1, k, l)/rho_rx) + & - (1._wp/dy(k)**2._wp)*(jac(j, k - 1, l)/rho_ly + jac(j, k + 1, l)/rho_ry)) + & - real(jac_rhs(j, k, l), kind=wp)/fd_coeff, kind=stp) + jac(j, k, l) = real((alf_igr/fd_coeff)*((1._wp/dx(j)**2._wp)*(jac(j - 1, k, & + & l)/rho_lx + jac(j + 1, k, l)/rho_rx) + (1._wp/dy(k)**2._wp)*(jac(j, k - 1, & + & l)/rho_ly + jac(j, k + 1, l)/rho_ry)) + real(jac_rhs(j, k, l), kind=wp)/fd_coeff, kind=stp) end if end if end do @@ -360,8 +293,8 @@ contains call s_populate_F_igr_buffers(bc_type, jac_sf) - if (igr_iter_solver == 1 .or. dummy) then ! Jacobi iteration - $:GPU_PARALLEL_LOOP(private='[j,k,l]', collapse=3) + if (igr_iter_solver == 1 .or. dummy) then ! Jacobi iteration + $:GPU_PARALLEL_LOOP(private='[j, k, l]', collapse=3) do l = idwbuff(3)%beg, idwbuff(3)%end do k = idwbuff(2)%beg, idwbuff(2)%end do j = idwbuff(1)%beg, idwbuff(1)%end @@ -377,28 +310,23 @@ contains !> @brief Computes the IGR viscous stress contribution in the x-direction and accumulates it into the RHS. subroutine s_igr_sigma_x(q_cons_vf, rhs_vf) + #ifdef _CRAYFTN - !DIR$ OPTIMIZE (-haggress) + ! DIR$ OPTIMIZE (-haggress) #endif - type(scalar_field), & - dimension(sys_size), & - intent(inout) :: rhs_vf - type(scalar_field), & - dimension(sys_size), & - intent(inout) :: q_cons_vf - - real(wp) :: F_L, vel_L, rho_L, F_R, vel_R, rho_R + type(scalar_field), dimension(sys_size), intent(inout) :: rhs_vf + type(scalar_field), dimension(sys_size), intent(inout) :: q_cons_vf + real(wp) :: F_L, vel_L, rho_L, F_R, vel_R, rho_R #:if not MFC_CASE_OPTIMIZATION real(wp), dimension(num_fluids_max) :: alpha_rho_L, alpha_rho_R #:else real(wp), dimension(num_fluids) :: alpha_rho_L, alpha_rho_R #:endif - $:GPU_PARALLEL_LOOP(collapse=3, private='[j,k,l,F_L, vel_L, alpha_rho_L, F_R, vel_R, alpha_rho_R, rho_L, rho_R]') + $:GPU_PARALLEL_LOOP(collapse=3, private='[j, k, l, F_L, vel_L, alpha_rho_L, F_R, vel_R, alpha_rho_R, rho_L, rho_R]') do l = 0, p do k = 0, n do j = -1, m - F_L = 0._wp; F_R = 0._wp vel_L = 0._wp; vel_R = 0._wp rho_L = 0._wp; rho_R = 0._wp @@ -442,17 +370,16 @@ contains #:for LR in ['L', 'R'] $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb)%sf(j + 1, k, l) = rhs_vf(momxb)%sf(j + 1, k, l) + & - real(0.5_wp*dt*F_${LR}$*(1._wp/dx(j + 1)), kind=stp) + rhs_vf(momxb)%sf(j + 1, k, l) = rhs_vf(momxb)%sf(j + 1, k, & + & l) + real(0.5_wp*dt*F_${LR}$*(1._wp/dx(j + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(E_idx)%sf(j + 1, k, l) = rhs_vf(E_idx)%sf(j + 1, k, l) + & - real(0.5_wp*dt*vel_${LR}$*F_${LR}$*(1._wp/dx(j + 1)), kind=stp) + rhs_vf(E_idx)%sf(j + 1, k, l) = rhs_vf(E_idx)%sf(j + 1, k, & + & l) + real(0.5_wp*dt*vel_${LR}$*F_${LR}$*(1._wp/dx(j + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb)%sf(j, k, l) = rhs_vf(momxb)%sf(j, k, l) - & - real(0.5_wp*dt*F_${LR}$*(1._wp/dx(j)), kind=stp) + rhs_vf(momxb)%sf(j, k, l) = rhs_vf(momxb)%sf(j, k, l) - real(0.5_wp*dt*F_${LR}$*(1._wp/dx(j)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(E_idx)%sf(j, k, l) = rhs_vf(E_idx)%sf(j, k, l) - & - real(0.5_wp*dt*vel_${LR}$*F_${LR}$*(1._wp/dx(j)), kind=stp) + rhs_vf(E_idx)%sf(j, k, l) = rhs_vf(E_idx)%sf(j, k, l) - real(0.5_wp*dt*vel_${LR}$*F_${LR}$*(1._wp/dx(j)), & + & kind=stp) #:endfor end do end do @@ -463,55 +390,52 @@ contains !> @brief Evaluates the approximate Riemann solver for the IGR scheme along a given coordinate direction. subroutine s_igr_riemann_solver(q_cons_vf, rhs_vf, idir) + #ifdef _CRAYFTN - !DIR$ OPTIMIZE (-haggress) + ! DIR$ OPTIMIZE (-haggress) #endif - type(scalar_field), & - dimension(sys_size), & - intent(inout) :: rhs_vf - type(scalar_field), & - dimension(sys_size), & - intent(inout) :: q_cons_vf - integer, intent(in) :: idir - - real(wp) :: cfl - real(wp) :: rho_L, gamma_L, pi_inf_L, E_L, mu_L, F_L, pres_L - real(wp) :: rho_R, gamma_R, pi_inf_R, E_R, mu_R, F_R, pres_R - real(wp), dimension(3) :: vflux_L_arr, vflux_R_arr - real(wp), dimension(-1:1) :: rho_sf_small + type(scalar_field), dimension(sys_size), intent(inout) :: rhs_vf + type(scalar_field), dimension(sys_size), intent(inout) :: q_cons_vf + integer, intent(in) :: idir + real(wp) :: cfl + real(wp) :: rho_L, gamma_L, pi_inf_L, E_L, mu_L, F_L, pres_L + real(wp) :: rho_R, gamma_R, pi_inf_R, E_R, mu_R, F_R, pres_R + real(wp), dimension(3) :: vflux_L_arr, vflux_R_arr + real(wp), dimension(-1:1) :: rho_sf_small #:if not MFC_CASE_OPTIMIZATION real(wp), dimension(num_fluids_max) :: alpha_rho_L, alpha_L, alpha_R, alpha_rho_R - real(wp), dimension(3) :: vel_L, vel_R - real(wp), dimension(3, 3) :: dvel - real(wp), dimension(3) :: dvel_small + real(wp), dimension(3) :: vel_L, vel_R + real(wp), dimension(3, 3) :: dvel + real(wp), dimension(3) :: dvel_small #:else - real(wp), dimension(num_fluids) :: alpha_rho_L, alpha_L, alpha_R, alpha_rho_R - real(wp), dimension(num_dims) :: vel_L, vel_R + real(wp), dimension(num_fluids) :: alpha_rho_L, alpha_L, alpha_R, alpha_rho_R + real(wp), dimension(num_dims) :: vel_L, vel_R real(wp), dimension(num_dims, num_dims) :: dvel - real(wp), dimension(num_dims) :: dvel_small + real(wp), dimension(num_dims) :: dvel_small #:endif if (idir == 1) then if (p == 0) then #:if not MFC_CASE_OPTIMIZATION or num_dims > 1 - $:GPU_PARALLEL_LOOP(collapse=3, private='[j,k,l,rho_L, rho_R, gamma_L, gamma_R, pi_inf_L, pi_inf_R, mu_L, mu_R, vel_L, vel_R, pres_L, pres_R, alpha_L, alpha_R, alpha_rho_L, alpha_rho_R, F_L, F_R, E_L, E_R, cfl, dvel, dvel_small, rho_sf_small, vflux_L_arr, vflux_R_arr]') + $:GPU_PARALLEL_LOOP(collapse=3, private='[j, k, l, rho_L, rho_R, gamma_L, gamma_R, pi_inf_L, pi_inf_R, mu_L, & + & mu_R, vel_L, vel_R, pres_L, pres_R, alpha_L, alpha_R, alpha_rho_L, alpha_rho_R, F_L, & + & F_R, E_L, E_R, cfl, dvel, dvel_small, rho_sf_small, vflux_L_arr, vflux_R_arr]') do l = 0, p do k = 0, n do j = -1, m - vflux_L_arr = 0._wp vflux_R_arr = 0._wp #:if MFC_CASE_OPTIMIZATION #:if igr_order == 5 - !DIR$ unroll 6 + ! DIR$ unroll 6 #:elif igr_order == 3 - !DIR$ unroll 4 + ! DIR$ unroll 4 #:endif #:endif $:GPU_LOOP(parallelism='[seq]') do q = vidxb, vidxe - !x-direction contributions + ! x-direction contributions $:GPU_LOOP(parallelism='[seq]') do i = -1, 1 rho_L = 0._wp @@ -522,12 +446,10 @@ contains rho_sf_small(i) = rho_L end do - dvel_small(1) = (1/(2._wp*dx(j)))*( & - 1._wp*q_cons_vf(momxb)%sf(j + 1 + q, k, l)/rho_sf_small(1) - & - 1._wp*q_cons_vf(momxb)%sf(j - 1 + q, k, l)/rho_sf_small(-1)) - dvel_small(2) = (1/(2._wp*dx(j)))*( & - q_cons_vf(momxb + 1)%sf(j + 1 + q, k, l)/rho_sf_small(1) - & - q_cons_vf(momxb + 1)%sf(j - 1 + q, k, l)/rho_sf_small(-1)) + dvel_small(1) = (1/(2._wp*dx(j)))*(1._wp*q_cons_vf(momxb)%sf(j + 1 + q, k, & + & l)/rho_sf_small(1) - 1._wp*q_cons_vf(momxb)%sf(j - 1 + q, k, l)/rho_sf_small(-1)) + dvel_small(2) = (1/(2._wp*dx(j)))*(q_cons_vf(momxb + 1)%sf(j + 1 + q, k, & + & l)/rho_sf_small(1) - q_cons_vf(momxb + 1)%sf(j - 1 + q, k, l)/rho_sf_small(-1)) if (q == 0) then $:GPU_LOOP(parallelism='[seq]') @@ -545,7 +467,7 @@ contains vflux_R_arr(3) = vflux_R_arr(3) + coeff_R(q)*(4._wp*dvel_small(1))/3._wp end if - !y-direction contributions + ! y-direction contributions $:GPU_LOOP(parallelism='[seq]') do i = -1, 1 rho_L = 0._wp @@ -556,12 +478,10 @@ contains rho_sf_small(i) = rho_L end do - dvel_small(1) = (1/(2._wp*dy(k)))*( & - q_cons_vf(momxb)%sf(j + q, k + 1, l)/rho_sf_small(1) - & - q_cons_vf(momxb)%sf(j + q, k - 1, l)/rho_sf_small(-1)) - dvel_small(2) = (1/(2._wp*dy(k)))*( & - q_cons_vf(momxb + 1)%sf(j + q, k + 1, l)/rho_sf_small(1) - & - q_cons_vf(momxb + 1)%sf(j + q, k - 1, l)/rho_sf_small(-1)) + dvel_small(1) = (1/(2._wp*dy(k)))*(q_cons_vf(momxb)%sf(j + q, k + 1, & + & l)/rho_sf_small(1) - q_cons_vf(momxb)%sf(j + q, k - 1, l)/rho_sf_small(-1)) + dvel_small(2) = (1/(2._wp*dy(k)))*(q_cons_vf(momxb + 1)%sf(j + q, k + 1, & + & l)/rho_sf_small(1) - q_cons_vf(momxb + 1)%sf(j + q, k - 1, l)/rho_sf_small(-1)) if (q == 0) then $:GPU_LOOP(parallelism='[seq]') @@ -580,9 +500,8 @@ contains end if if (q == 0) then - jac_rhs(j, k, l) = real(alf_igr*(2._wp*(dvel(1, 2)*dvel(2, 1)) & - + dvel(1, 1)**2._wp + dvel(2, 2)**2._wp & - + (dvel(1, 1) + dvel(2, 2))**2._wp), kind=stp) + jac_rhs(j, k, l) = real(alf_igr*(2._wp*(dvel(1, 2)*dvel(2, 1)) + dvel(1, & + & 1)**2._wp + dvel(2, 2)**2._wp + (dvel(1, 1) + dvel(2, 2))**2._wp), kind=stp) end if end do @@ -644,7 +563,6 @@ contains end do if (num_fluids > 1) then - alpha_L(num_fluids) = 1._wp alpha_R(num_fluids) = 1._wp @@ -685,60 +603,60 @@ contains end do $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb + 1)%sf(j + 1, k, l) = rhs_vf(momxb + 1)%sf(j + 1, k, l) - & - real(0.5_wp*dt*mu_L*vflux_L_arr(1)*(1._wp/dx(j + 1)), kind=stp) + rhs_vf(momxb + 1)%sf(j + 1, k, l) = rhs_vf(momxb + 1)%sf(j + 1, k, & + & l) - real(0.5_wp*dt*mu_L*vflux_L_arr(1)*(1._wp/dx(j + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(E_idx)%sf(j + 1, k, l) = rhs_vf(E_idx)%sf(j + 1, k, l) - & - real(0.5_wp*dt*mu_L*vflux_L_arr(1)*vel_L(2)*(1._wp/dx(j + 1)), kind=stp) + rhs_vf(E_idx)%sf(j + 1, k, l) = rhs_vf(E_idx)%sf(j + 1, k, & + & l) - real(0.5_wp*dt*mu_L*vflux_L_arr(1)*vel_L(2)*(1._wp/dx(j + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb + 1)%sf(j, k, l) = rhs_vf(momxb + 1)%sf(j, k, l) + & - real(0.5_wp*dt*mu_L*vflux_L_arr(1)*(1._wp/dx(j)), kind=stp) + rhs_vf(momxb + 1)%sf(j, k, l) = rhs_vf(momxb + 1)%sf(j, k, & + & l) + real(0.5_wp*dt*mu_L*vflux_L_arr(1)*(1._wp/dx(j)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(E_idx)%sf(j, k, l) = rhs_vf(E_idx)%sf(j, k, l) + & - real(0.5_wp*dt*mu_L*vflux_L_arr(1)*vel_L(2)*(1._wp/dx(j)), kind=stp) + rhs_vf(E_idx)%sf(j, k, l) = rhs_vf(E_idx)%sf(j, k, & + & l) + real(0.5_wp*dt*mu_L*vflux_L_arr(1)*vel_L(2)*(1._wp/dx(j)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb + 1)%sf(j + 1, k, l) = rhs_vf(momxb + 1)%sf(j + 1, k, l) - & - real(0.5_wp*dt*mu_R*vflux_R_arr(1)*(1._wp/dx(j + 1)), kind=stp) + rhs_vf(momxb + 1)%sf(j + 1, k, l) = rhs_vf(momxb + 1)%sf(j + 1, k, & + & l) - real(0.5_wp*dt*mu_R*vflux_R_arr(1)*(1._wp/dx(j + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(E_idx)%sf(j + 1, k, l) = rhs_vf(E_idx)%sf(j + 1, k, l) - & - real(0.5_wp*dt*mu_R*vflux_R_arr(1)*vel_R(2)*(1._wp/dx(j + 1)), kind=stp) + rhs_vf(E_idx)%sf(j + 1, k, l) = rhs_vf(E_idx)%sf(j + 1, k, & + & l) - real(0.5_wp*dt*mu_R*vflux_R_arr(1)*vel_R(2)*(1._wp/dx(j + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb + 1)%sf(j, k, l) = rhs_vf(momxb + 1)%sf(j, k, l) + & - real(0.5_wp*dt*mu_R*vflux_R_arr(1)*(1._wp/dx(j)), kind=stp) + rhs_vf(momxb + 1)%sf(j, k, l) = rhs_vf(momxb + 1)%sf(j, k, & + & l) + real(0.5_wp*dt*mu_R*vflux_R_arr(1)*(1._wp/dx(j)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(E_idx)%sf(j, k, l) = rhs_vf(E_idx)%sf(j, k, l) + & - real(0.5_wp*dt*mu_R*vflux_R_arr(1)*vel_R(2)*(1._wp/dx(j)), kind=stp) + rhs_vf(E_idx)%sf(j, k, l) = rhs_vf(E_idx)%sf(j, k, & + & l) + real(0.5_wp*dt*mu_R*vflux_R_arr(1)*vel_R(2)*(1._wp/dx(j)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb)%sf(j + 1, k, l) = rhs_vf(momxb)%sf(j + 1, k, l) - & - real(0.5_wp*dt*mu_L*vflux_L_arr(3)*(1._wp/dx(j + 1)), kind=stp) + rhs_vf(momxb)%sf(j + 1, k, l) = rhs_vf(momxb)%sf(j + 1, k, & + & l) - real(0.5_wp*dt*mu_L*vflux_L_arr(3)*(1._wp/dx(j + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(E_idx)%sf(j + 1, k, l) = rhs_vf(E_idx)%sf(j + 1, k, l) - & - real(0.5_wp*dt*mu_L*vflux_L_arr(3)*vel_L(1)*(1._wp/dx(j + 1)), kind=stp) + rhs_vf(E_idx)%sf(j + 1, k, l) = rhs_vf(E_idx)%sf(j + 1, k, & + & l) - real(0.5_wp*dt*mu_L*vflux_L_arr(3)*vel_L(1)*(1._wp/dx(j + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb)%sf(j, k, l) = rhs_vf(momxb)%sf(j, k, l) + & - real(0.5_wp*dt*mu_L*vflux_L_arr(3)*(1._wp/dx(j)), kind=stp) + rhs_vf(momxb)%sf(j, k, l) = rhs_vf(momxb)%sf(j, k, & + & l) + real(0.5_wp*dt*mu_L*vflux_L_arr(3)*(1._wp/dx(j)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(E_idx)%sf(j, k, l) = rhs_vf(E_idx)%sf(j, k, l) + & - real(0.5_wp*dt*mu_L*vflux_L_arr(3)*vel_L(1)*(1._wp/dx(j)), kind=stp) + rhs_vf(E_idx)%sf(j, k, l) = rhs_vf(E_idx)%sf(j, k, & + & l) + real(0.5_wp*dt*mu_L*vflux_L_arr(3)*vel_L(1)*(1._wp/dx(j)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb)%sf(j + 1, k, l) = rhs_vf(momxb)%sf(j + 1, k, l) - & - real(0.5_wp*dt*mu_R*vflux_R_arr(3)*(1._wp/dx(j + 1)), kind=stp) + rhs_vf(momxb)%sf(j + 1, k, l) = rhs_vf(momxb)%sf(j + 1, k, & + & l) - real(0.5_wp*dt*mu_R*vflux_R_arr(3)*(1._wp/dx(j + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(E_idx)%sf(j + 1, k, l) = rhs_vf(E_idx)%sf(j + 1, k, l) - & - real(0.5_wp*dt*mu_R*vflux_R_arr(3)*vel_R(1)*(1._wp/dx(j + 1)), kind=stp) + rhs_vf(E_idx)%sf(j + 1, k, l) = rhs_vf(E_idx)%sf(j + 1, k, & + & l) - real(0.5_wp*dt*mu_R*vflux_R_arr(3)*vel_R(1)*(1._wp/dx(j + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb)%sf(j, k, l) = rhs_vf(momxb)%sf(j, k, l) + & - real(0.5_wp*dt*mu_R*vflux_R_arr(3)*(1._wp/dx(j)), kind=stp) + rhs_vf(momxb)%sf(j, k, l) = rhs_vf(momxb)%sf(j, k, & + & l) + real(0.5_wp*dt*mu_R*vflux_R_arr(3)*(1._wp/dx(j)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(E_idx)%sf(j, k, l) = rhs_vf(E_idx)%sf(j, k, l) + & - real(0.5_wp*dt*mu_R*vflux_R_arr(3)*vel_R(1)*(1._wp/dx(j)), kind=stp) + rhs_vf(E_idx)%sf(j, k, l) = rhs_vf(E_idx)%sf(j, k, & + & l) + real(0.5_wp*dt*mu_R*vflux_R_arr(3)*vel_R(1)*(1._wp/dx(j)), kind=stp) end if E_L = 0._wp; E_R = 0._wp @@ -753,157 +671,143 @@ contains E_R = E_R + coeff_R(q)*q_cons_vf(E_idx)%sf(j + q, k, l) end do - call s_get_derived_states(E_L, gamma_L, pi_inf_L, rho_L, vel_L, & - E_R, gamma_R, pi_inf_R, rho_R, vel_R, & - pres_L, pres_R, cfl) + call s_get_derived_states(E_L, gamma_L, pi_inf_L, rho_L, vel_L, E_R, gamma_R, pi_inf_R, rho_R, & + & vel_R, pres_L, pres_R, cfl) do i = 1, num_fluids $:GPU_ATOMIC(atomic='update') - rhs_vf(i)%sf(j + 1, k, l) = rhs_vf(i)%sf(j + 1, k, l) + & - real((0.5_wp*dt*(alpha_rho_L(i)* & - vel_L(1))*(1._wp/dx(j + 1)) - & - 0.5_wp*dt*cfl*(alpha_rho_L(i))*(1._wp/dx(j + 1))), kind=stp) + rhs_vf(i)%sf(j + 1, k, l) = rhs_vf(i)%sf(j + 1, k, & + & l) + real((0.5_wp*dt*(alpha_rho_L(i)*vel_L(1))*(1._wp/dx(j + 1)) & + & - 0.5_wp*dt*cfl*(alpha_rho_L(i))*(1._wp/dx(j + 1))), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(i)%sf(j, k, l) = rhs_vf(i)%sf(j, k, l) - & - real((0.5_wp*dt*(alpha_rho_L(i)* & - vel_L(1))*(1._wp/dx(j)) - & - 0.5_wp*dt*cfl*(alpha_rho_L(i))*(1._wp/dx(j))), kind=stp) + rhs_vf(i)%sf(j, k, l) = rhs_vf(i)%sf(j, k, & + & l) - real((0.5_wp*dt*(alpha_rho_L(i)*vel_L(1))*(1._wp/dx(j)) & + & - 0.5_wp*dt*cfl*(alpha_rho_L(i))*(1._wp/dx(j))), kind=stp) end do if (num_fluids > 1) then $:GPU_LOOP(parallelism='[seq]') do i = 1, num_fluids - 1 $:GPU_ATOMIC(atomic='update') - rhs_vf(advxb + i - 1)%sf(j + 1, k, l) = rhs_vf(advxb + i - 1)%sf(j + 1, k, l) + & - real((0.5_wp*dt*(alpha_L(i)* & - vel_L(1))*(1._wp/dx(j + 1)) - & - 0.5_wp*dt*cfl*(alpha_L(i))*(1._wp/dx(j + 1))), kind=stp) + rhs_vf(advxb + i - 1)%sf(j + 1, k, l) = rhs_vf(advxb + i - 1)%sf(j + 1, k, & + & l) + real((0.5_wp*dt*(alpha_L(i)*vel_L(1))*(1._wp/dx(j + 1)) & + & - 0.5_wp*dt*cfl*(alpha_L(i))*(1._wp/dx(j + 1))), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(advxb + i - 1)%sf(j + 1, k, l) = rhs_vf(advxb + i - 1)%sf(j + 1, k, l) & - - real((0.5_wp*dt*q_cons_vf(advxb + i - 1)%sf(j + 1, k, l)*vel_L(1)*(1._wp/dx(j + 1))), kind=stp) + rhs_vf(advxb + i - 1)%sf(j + 1, k, l) = rhs_vf(advxb + i - 1)%sf(j + 1, k, & + & l) - real((0.5_wp*dt*q_cons_vf(advxb + i - 1)%sf(j + 1, k, & + & l)*vel_L(1)*(1._wp/dx(j + 1))), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(advxb + i - 1)%sf(j, k, l) = rhs_vf(advxb + i - 1)%sf(j, k, l) - & - real((0.5_wp*dt*(alpha_L(i)* & - vel_L(1))*(1._wp/dx(j)) - & - 0.5_wp*dt*cfl*(alpha_L(i))*(1._wp/dx(j))), kind=stp) + rhs_vf(advxb + i - 1)%sf(j, k, l) = rhs_vf(advxb + i - 1)%sf(j, k, & + & l) - real((0.5_wp*dt*(alpha_L(i)*vel_L(1))*(1._wp/dx(j)) & + & - 0.5_wp*dt*cfl*(alpha_L(i))*(1._wp/dx(j))), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(advxb + i - 1)%sf(j, k, l) = rhs_vf(advxb + i - 1)%sf(j, k, l) & - + real((0.5_wp*dt*q_cons_vf(advxb + i - 1)%sf(j, k, l)*vel_L(1)*(1._wp/dx(j))), kind=stp) + rhs_vf(advxb + i - 1)%sf(j, k, l) = rhs_vf(advxb + i - 1)%sf(j, k, & + & l) + real((0.5_wp*dt*q_cons_vf(advxb + i - 1)%sf(j, k, & + & l)*vel_L(1)*(1._wp/dx(j))), kind=stp) end do end if $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb)%sf(j + 1, k, l) = rhs_vf(momxb)%sf(j + 1, k, l) + & - real((0.5_wp*dt*(rho_L*(vel_L(1))**2.0 + & - pres_L)*(1._wp/dx(j + 1)) - & - 0.5_wp*dt*cfl*(rho_L*vel_L(1))*(1._wp/dx(j + 1))), kind=stp) + rhs_vf(momxb)%sf(j + 1, k, l) = rhs_vf(momxb)%sf(j + 1, k, & + & l) + real((0.5_wp*dt*(rho_L*(vel_L(1))**2.0 + pres_L)*(1._wp/dx(j + 1)) & + & - 0.5_wp*dt*cfl*(rho_L*vel_L(1))*(1._wp/dx(j + 1))), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb + 1)%sf(j + 1, k, l) = rhs_vf(momxb + 1)%sf(j + 1, k, l) + & - real((0.5_wp*dt*rho_L*vel_L(1)*vel_L(2)*(1._wp/dx(j + 1)) - & - 0.5_wp*dt*cfl*(rho_L*vel_L(2))*(1._wp/dx(j + 1))), kind=stp) + rhs_vf(momxb + 1)%sf(j + 1, k, l) = rhs_vf(momxb + 1)%sf(j + 1, k, & + & l) + real((0.5_wp*dt*rho_L*vel_L(1)*vel_L(2)*(1._wp/dx(j + 1)) & + & - 0.5_wp*dt*cfl*(rho_L*vel_L(2))*(1._wp/dx(j + 1))), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(E_idx)%sf(j + 1, k, l) = rhs_vf(E_idx)%sf(j + 1, k, l) + & - real((0.5_wp*dt*(vel_L(1)*(E_L + & - pres_L))*(1._wp/dx(j + 1)) - & - 0.5_wp*dt*cfl*(E_L)*(1._wp/dx(j + 1))), kind=stp) + rhs_vf(E_idx)%sf(j + 1, k, l) = rhs_vf(E_idx)%sf(j + 1, k, & + & l) + real((0.5_wp*dt*(vel_L(1)*(E_L + pres_L))*(1._wp/dx(j + 1)) - 0.5_wp*dt*cfl*(E_L) & + & *(1._wp/dx(j + 1))), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb)%sf(j, k, l) = rhs_vf(momxb)%sf(j, k, l) - & - real((0.5_wp*dt*(rho_L*(vel_L(1))**2.0 + & - pres_L)*(1._wp/dx(j)) - & - 0.5_wp*dt*cfl*(rho_L*vel_L(1))*(1._wp/dx(j))), kind=stp) + rhs_vf(momxb)%sf(j, k, l) = rhs_vf(momxb)%sf(j, k, & + & l) - real((0.5_wp*dt*(rho_L*(vel_L(1))**2.0 + pres_L)*(1._wp/dx(j)) & + & - 0.5_wp*dt*cfl*(rho_L*vel_L(1))*(1._wp/dx(j))), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb + 1)%sf(j, k, l) = rhs_vf(momxb + 1)%sf(j, k, l) - & - real((0.5_wp*dt*rho_L*vel_L(1)*vel_L(2)*(1._wp/dx(j)) - & - 0.5_wp*dt*cfl*(rho_L*vel_L(2))*(1._wp/dx(j))), kind=stp) + rhs_vf(momxb + 1)%sf(j, k, l) = rhs_vf(momxb + 1)%sf(j, k, & + & l) - real((0.5_wp*dt*rho_L*vel_L(1)*vel_L(2)*(1._wp/dx(j)) & + & - 0.5_wp*dt*cfl*(rho_L*vel_L(2))*(1._wp/dx(j))), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(E_idx)%sf(j, k, l) = rhs_vf(E_idx)%sf(j, k, l) - & - real((0.5_wp*dt*(vel_L(1)*(E_L + & - pres_L))*(1._wp/dx(j)) - & - 0.5_wp*dt*cfl*(E_L)*(1._wp/dx(j))), kind=stp) + rhs_vf(E_idx)%sf(j, k, l) = rhs_vf(E_idx)%sf(j, k, & + & l) - real((0.5_wp*dt*(vel_L(1)*(E_L + pres_L))*(1._wp/dx(j)) - 0.5_wp*dt*cfl*(E_L) & + & *(1._wp/dx(j))), kind=stp) $:GPU_LOOP(parallelism='[seq]') do i = 1, num_fluids $:GPU_ATOMIC(atomic='update') - rhs_vf(i)%sf(j + 1, k, l) = rhs_vf(i)%sf(j + 1, k, l) + & - real((0.5_wp*dt*(alpha_rho_R(i)* & - vel_R(1))*(1._wp/dx(j + 1)) + & - 0.5_wp*dt*cfl*(alpha_rho_R(i))*(1._wp/dx(j + 1))), kind=stp) + rhs_vf(i)%sf(j + 1, k, l) = rhs_vf(i)%sf(j + 1, k, & + & l) + real((0.5_wp*dt*(alpha_rho_R(i)*vel_R(1))*(1._wp/dx(j + 1)) & + & + 0.5_wp*dt*cfl*(alpha_rho_R(i))*(1._wp/dx(j + 1))), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(i)%sf(j, k, l) = rhs_vf(i)%sf(j, k, l) - & - real((0.5_wp*dt*(alpha_rho_R(i)* & - vel_R(1))*(1._wp/dx(j)) + & - 0.5_wp*dt*cfl*(alpha_rho_R(i))*(1._wp/dx(j))), kind=stp) + rhs_vf(i)%sf(j, k, l) = rhs_vf(i)%sf(j, k, & + & l) - real((0.5_wp*dt*(alpha_rho_R(i)*vel_R(1))*(1._wp/dx(j)) & + & + 0.5_wp*dt*cfl*(alpha_rho_R(i))*(1._wp/dx(j))), kind=stp) end do if (num_fluids > 1) then $:GPU_LOOP(parallelism='[seq]') do i = 1, num_fluids - 1 $:GPU_ATOMIC(atomic='update') - rhs_vf(advxb + i - 1)%sf(j + 1, k, l) = rhs_vf(advxb + i - 1)%sf(j + 1, k, l) + & - real((0.5_wp*dt*(alpha_R(i)* & - vel_R(1))*(1._wp/dx(j + 1)) + & - 0.5_wp*dt*cfl*(alpha_R(i))*(1._wp/dx(j + 1))), kind=stp) + rhs_vf(advxb + i - 1)%sf(j + 1, k, l) = rhs_vf(advxb + i - 1)%sf(j + 1, k, & + & l) + real((0.5_wp*dt*(alpha_R(i)*vel_R(1))*(1._wp/dx(j + 1)) & + & + 0.5_wp*dt*cfl*(alpha_R(i))*(1._wp/dx(j + 1))), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(advxb + i - 1)%sf(j + 1, k, l) = rhs_vf(advxb + i - 1)%sf(j + 1, k, l) & - - real((0.5_wp*dt*q_cons_vf(advxb + i - 1)%sf(j + 1, k, l)*vel_R(1)*(1._wp/dx(j + 1))), kind=stp) + rhs_vf(advxb + i - 1)%sf(j + 1, k, l) = rhs_vf(advxb + i - 1)%sf(j + 1, k, & + & l) - real((0.5_wp*dt*q_cons_vf(advxb + i - 1)%sf(j + 1, k, & + & l)*vel_R(1)*(1._wp/dx(j + 1))), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(advxb + i - 1)%sf(j, k, l) = rhs_vf(advxb + i - 1)%sf(j, k, l) - & - real((0.5_wp*dt*(alpha_R(i)* & - vel_R(1))*(1._wp/dx(j)) + & - 0.5_wp*dt*cfl*(alpha_R(i))*(1._wp/dx(j))), kind=stp) + rhs_vf(advxb + i - 1)%sf(j, k, l) = rhs_vf(advxb + i - 1)%sf(j, k, & + & l) - real((0.5_wp*dt*(alpha_R(i)*vel_R(1))*(1._wp/dx(j)) & + & + 0.5_wp*dt*cfl*(alpha_R(i))*(1._wp/dx(j))), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(advxb + i - 1)%sf(j, k, l) = rhs_vf(advxb + i - 1)%sf(j, k, l) & - + real((0.5_wp*dt*q_cons_vf(advxb + i - 1)%sf(j, k, l)*vel_R(1)*(1._wp/dx(j))), kind=stp) + rhs_vf(advxb + i - 1)%sf(j, k, l) = rhs_vf(advxb + i - 1)%sf(j, k, & + & l) + real((0.5_wp*dt*q_cons_vf(advxb + i - 1)%sf(j, k, & + & l)*vel_R(1)*(1._wp/dx(j))), kind=stp) end do end if $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb)%sf(j + 1, k, l) = rhs_vf(momxb)%sf(j + 1, k, l) + & - real((0.5_wp*dt*(rho_R*(vel_R(1))**2.0 + & - pres_R)*(1._wp/dx(j + 1)) + & - 0.5_wp*dt*cfl*(rho_R*vel_R(1))*(1._wp/dx(j + 1))), kind=stp) + rhs_vf(momxb)%sf(j + 1, k, l) = rhs_vf(momxb)%sf(j + 1, k, & + & l) + real((0.5_wp*dt*(rho_R*(vel_R(1))**2.0 + pres_R)*(1._wp/dx(j + 1)) & + & + 0.5_wp*dt*cfl*(rho_R*vel_R(1))*(1._wp/dx(j + 1))), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb + 1)%sf(j + 1, k, l) = rhs_vf(momxb + 1)%sf(j + 1, k, l) + & - real((0.5_wp*dt*rho_R*vel_R(1)*vel_R(2)*(1._wp/dx(j + 1)) + & - 0.5_wp*dt*cfl*(rho_R*vel_R(2))*(1._wp/dx(j + 1))), kind=stp) + rhs_vf(momxb + 1)%sf(j + 1, k, l) = rhs_vf(momxb + 1)%sf(j + 1, k, & + & l) + real((0.5_wp*dt*rho_R*vel_R(1)*vel_R(2)*(1._wp/dx(j + 1)) & + & + 0.5_wp*dt*cfl*(rho_R*vel_R(2))*(1._wp/dx(j + 1))), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(E_idx)%sf(j + 1, k, l) = rhs_vf(E_idx)%sf(j + 1, k, l) + & - real((0.5_wp*dt*(vel_R(1)*(E_R + & - pres_R))*(1._wp/dx(j + 1)) + & - 0.5_wp*dt*cfl*(E_R)*(1._wp/dx(j + 1))), kind=stp) + rhs_vf(E_idx)%sf(j + 1, k, l) = rhs_vf(E_idx)%sf(j + 1, k, & + & l) + real((0.5_wp*dt*(vel_R(1)*(E_R + pres_R))*(1._wp/dx(j + 1)) + 0.5_wp*dt*cfl*(E_R) & + & *(1._wp/dx(j + 1))), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb)%sf(j, k, l) = rhs_vf(momxb)%sf(j, k, l) - & - real((0.5_wp*dt*(rho_R*(vel_R(1))**2.0 + & - pres_R)*(1._wp/dx(j)) + & - 0.5_wp*dt*cfl*(rho_R*vel_R(1))*(1._wp/dx(j))), kind=stp) + rhs_vf(momxb)%sf(j, k, l) = rhs_vf(momxb)%sf(j, k, & + & l) - real((0.5_wp*dt*(rho_R*(vel_R(1))**2.0 + pres_R)*(1._wp/dx(j)) & + & + 0.5_wp*dt*cfl*(rho_R*vel_R(1))*(1._wp/dx(j))), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb + 1)%sf(j, k, l) = rhs_vf(momxb + 1)%sf(j, k, l) - & - real((0.5_wp*dt*rho_R*vel_R(1)*vel_R(2)*(1._wp/dx(j)) + & - 0.5_wp*dt*cfl*(rho_R*vel_R(2))*(1._wp/dx(j))), kind=stp) + rhs_vf(momxb + 1)%sf(j, k, l) = rhs_vf(momxb + 1)%sf(j, k, & + & l) - real((0.5_wp*dt*rho_R*vel_R(1)*vel_R(2)*(1._wp/dx(j)) & + & + 0.5_wp*dt*cfl*(rho_R*vel_R(2))*(1._wp/dx(j))), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(E_idx)%sf(j, k, l) = rhs_vf(E_idx)%sf(j, k, l) - & - real((0.5_wp*dt*(vel_R(1)*(E_R + & - pres_R))*(1._wp/dx(j)) + & - 0.5_wp*dt*cfl*(E_R)*(1._wp/dx(j))), kind=stp) - + rhs_vf(E_idx)%sf(j, k, l) = rhs_vf(E_idx)%sf(j, k, & + & l) - real((0.5_wp*dt*(vel_R(1)*(E_R + pres_R))*(1._wp/dx(j)) + 0.5_wp*dt*cfl*(E_R) & + & *(1._wp/dx(j))), kind=stp) end do end do end do @@ -911,25 +815,25 @@ contains #:endif else #:if not MFC_CASE_OPTIMIZATION or num_dims > 2 - $:GPU_PARALLEL_LOOP(collapse=3, private='[j,k,l,rho_L, rho_R, gamma_L, gamma_R, pi_inf_L, pi_inf_R, mu_L, mu_R, vel_L, vel_R, pres_L, pres_R, alpha_L, alpha_R, alpha_rho_L, alpha_rho_R, F_L, F_R, E_L, E_R, cfl, dvel, dvel_small, rho_sf_small, vflux_L_arr, vflux_R_arr]') + $:GPU_PARALLEL_LOOP(collapse=3, private='[j, k, l, rho_L, rho_R, gamma_L, gamma_R, pi_inf_L, pi_inf_R, mu_L, & + & mu_R, vel_L, vel_R, pres_L, pres_R, alpha_L, alpha_R, alpha_rho_L, alpha_rho_R, F_L, & + & F_R, E_L, E_R, cfl, dvel, dvel_small, rho_sf_small, vflux_L_arr, vflux_R_arr]') do l = 0, p do k = 0, n do j = -1, m - vflux_L_arr = 0._wp vflux_R_arr = 0._wp #:if MFC_CASE_OPTIMIZATION #:if igr_order == 5 - !DIR$ unroll 6 + ! DIR$ unroll 6 #:elif igr_order == 3 - !DIR$ unroll 4 + ! DIR$ unroll 4 #:endif #:endif $:GPU_LOOP(parallelism='[seq]') do q = vidxb, vidxe - - !x-direction contributions + ! x-direction contributions $:GPU_LOOP(parallelism='[seq]') do i = -1, 1 rho_L = 0._wp @@ -940,15 +844,12 @@ contains rho_sf_small(i) = rho_L end do - dvel_small(1) = (1/(2._wp*dx(j)))*( & - q_cons_vf(momxb)%sf(j + 1 + q, k, l)/rho_sf_small(1) - & - q_cons_vf(momxb)%sf(j - 1 + q, k, l)/rho_sf_small(-1)) - dvel_small(2) = (1/(2._wp*dx(j)))*( & - q_cons_vf(momxb + 1)%sf(j + 1 + q, k, l)/rho_sf_small(1) - & - q_cons_vf(momxb + 1)%sf(j - 1 + q, k, l)/rho_sf_small(-1)) - dvel_small(3) = (1/(2._wp*dx(j)))*( & - q_cons_vf(momxb + 2)%sf(j + 1 + q, k, l)/rho_sf_small(1) - & - q_cons_vf(momxb + 2)%sf(j - 1 + q, k, l)/rho_sf_small(-1)) + dvel_small(1) = (1/(2._wp*dx(j)))*(q_cons_vf(momxb)%sf(j + 1 + q, k, & + & l)/rho_sf_small(1) - q_cons_vf(momxb)%sf(j - 1 + q, k, l)/rho_sf_small(-1)) + dvel_small(2) = (1/(2._wp*dx(j)))*(q_cons_vf(momxb + 1)%sf(j + 1 + q, k, & + & l)/rho_sf_small(1) - q_cons_vf(momxb + 1)%sf(j - 1 + q, k, l)/rho_sf_small(-1)) + dvel_small(3) = (1/(2._wp*dx(j)))*(q_cons_vf(momxb + 2)%sf(j + 1 + q, k, & + & l)/rho_sf_small(1) - q_cons_vf(momxb + 2)%sf(j - 1 + q, k, l)/rho_sf_small(-1)) if (q == 0) then $:GPU_LOOP(parallelism='[seq]') @@ -968,7 +869,7 @@ contains vflux_R_arr(3) = vflux_R_arr(3) + coeff_R(q)*(4._wp*dvel_small(1))/3._wp end if - !y-direction contributions + ! y-direction contributions $:GPU_LOOP(parallelism='[seq]') do i = -1, 1 rho_L = 0._wp @@ -979,15 +880,12 @@ contains rho_sf_small(i) = rho_L end do - dvel_small(1) = (1/(2._wp*dy(k)))*( & - q_cons_vf(momxb)%sf(j + q, k + 1, l)/rho_sf_small(1) - & - q_cons_vf(momxb)%sf(j + q, k - 1, l)/rho_sf_small(-1)) - dvel_small(2) = (1/(2._wp*dy(k)))*( & - q_cons_vf(momxb + 1)%sf(j + q, k + 1, l)/rho_sf_small(1) - & - q_cons_vf(momxb + 1)%sf(j + q, k - 1, l)/rho_sf_small(-1)) - if (q == 0) dvel_small(3) = (1/(2._wp*dy(k)))*( & - q_cons_vf(momxb + 2)%sf(j + q, k + 1, l)/rho_sf_small(1) - & - q_cons_vf(momxb + 2)%sf(j + q, k - 1, l)/rho_sf_small(-1)) + dvel_small(1) = (1/(2._wp*dy(k)))*(q_cons_vf(momxb)%sf(j + q, k + 1, & + & l)/rho_sf_small(1) - q_cons_vf(momxb)%sf(j + q, k - 1, l)/rho_sf_small(-1)) + dvel_small(2) = (1/(2._wp*dy(k)))*(q_cons_vf(momxb + 1)%sf(j + q, k + 1, & + & l)/rho_sf_small(1) - q_cons_vf(momxb + 1)%sf(j + q, k - 1, l)/rho_sf_small(-1)) + if (q == 0) dvel_small(3) = (1/(2._wp*dy(k)))*(q_cons_vf(momxb + 2)%sf(j + q, k + 1, & + & l)/rho_sf_small(1) - q_cons_vf(momxb + 2)%sf(j + q, k - 1, l)/rho_sf_small(-1)) if (q == 0) then $:GPU_LOOP(parallelism='[seq]') do i = 1, num_dims @@ -1004,7 +902,7 @@ contains vflux_R_arr(3) = vflux_R_arr(3) + coeff_R(q)*(-2._wp*dvel_small(2))/3._wp end if - !z-direction contributions + ! z-direction contributions $:GPU_LOOP(parallelism='[seq]') do i = -1, 1 rho_L = 0._wp @@ -1015,15 +913,12 @@ contains rho_sf_small(i) = rho_L end do - dvel_small(1) = (1/(2._wp*dz(l)))*( & - q_cons_vf(momxb)%sf(j + q, k, l + 1)/rho_sf_small(1) - & - q_cons_vf(momxb)%sf(j + q, k, l - 1)/rho_sf_small(-1)) - if (q == 0) dvel_small(2) = (1/(2._wp*dz(l)))*( & - q_cons_vf(momxb + 1)%sf(j + q, k, l + 1)/rho_sf_small(1) - & - q_cons_vf(momxb + 1)%sf(j + q, k, l - 1)/rho_sf_small(-1)) - dvel_small(3) = (1/(2._wp*dz(l)))*( & - q_cons_vf(momxb + 2)%sf(j + q, k, l + 1)/rho_sf_small(1) - & - q_cons_vf(momxb + 2)%sf(j + q, k, l - 1)/rho_sf_small(-1)) + dvel_small(1) = (1/(2._wp*dz(l)))*(q_cons_vf(momxb)%sf(j + q, k, & + & l + 1)/rho_sf_small(1) - q_cons_vf(momxb)%sf(j + q, k, l - 1)/rho_sf_small(-1)) + if (q == 0) dvel_small(2) = (1/(2._wp*dz(l)))*(q_cons_vf(momxb + 1)%sf(j + q, k, & + & l + 1)/rho_sf_small(1) - q_cons_vf(momxb + 1)%sf(j + q, k, l - 1)/rho_sf_small(-1)) + dvel_small(3) = (1/(2._wp*dz(l)))*(q_cons_vf(momxb + 2)%sf(j + q, k, & + & l + 1)/rho_sf_small(1) - q_cons_vf(momxb + 2)%sf(j + q, k, l - 1)/rho_sf_small(-1)) if (q == 0) then $:GPU_LOOP(parallelism='[seq]') do i = 1, num_dims @@ -1041,12 +936,9 @@ contains end if if (q == 0) then - jac_rhs(j, k, l) = real(alf_igr*(2._wp*(dvel(1, 2)*dvel(2, 1) & - + dvel(1, 3)*dvel(3, 1) & - + dvel(2, 3)*dvel(3, 2)) & - + dvel(1, 1)**2._wp + dvel(2, 2)**2._wp & - + dvel(3, 3)**2._wp & - + (dvel(1, 1) + dvel(2, 2) + dvel(3, 3))**2._wp), kind=stp) + jac_rhs(j, k, l) = real(alf_igr*(2._wp*(dvel(1, 2)*dvel(2, 1) + dvel(1, 3)*dvel(3, & + & 1) + dvel(2, 3)*dvel(3, 2)) + dvel(1, 1)**2._wp + dvel(2, 2)**2._wp + dvel(3, & + & 3)**2._wp + (dvel(1, 1) + dvel(2, 2) + dvel(3, 3))**2._wp), kind=stp) end if end do @@ -1108,7 +1000,6 @@ contains end do if (num_fluids > 1) then - alpha_L(num_fluids) = 1._wp alpha_R(num_fluids) = 1._wp @@ -1150,88 +1041,88 @@ contains end do $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb + 1)%sf(j + 1, k, l) = rhs_vf(momxb + 1)%sf(j + 1, k, l) - & - real(0.5_wp*dt*mu_L*vflux_L_arr(1)*(1._wp/dx(j + 1)), kind=stp) + rhs_vf(momxb + 1)%sf(j + 1, k, l) = rhs_vf(momxb + 1)%sf(j + 1, k, & + & l) - real(0.5_wp*dt*mu_L*vflux_L_arr(1)*(1._wp/dx(j + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(E_idx)%sf(j + 1, k, l) = rhs_vf(E_idx)%sf(j + 1, k, l) - & - real(0.5_wp*dt*mu_L*vflux_L_arr(1)*vel_L(2)*(1._wp/dx(j + 1)), kind=stp) + rhs_vf(E_idx)%sf(j + 1, k, l) = rhs_vf(E_idx)%sf(j + 1, k, & + & l) - real(0.5_wp*dt*mu_L*vflux_L_arr(1)*vel_L(2)*(1._wp/dx(j + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb + 1)%sf(j, k, l) = rhs_vf(momxb + 1)%sf(j, k, l) + & - real(0.5_wp*dt*mu_L*vflux_L_arr(1)*(1._wp/dx(j)), kind=stp) + rhs_vf(momxb + 1)%sf(j, k, l) = rhs_vf(momxb + 1)%sf(j, k, & + & l) + real(0.5_wp*dt*mu_L*vflux_L_arr(1)*(1._wp/dx(j)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(E_idx)%sf(j, k, l) = rhs_vf(E_idx)%sf(j, k, l) + & - real(0.5_wp*dt*mu_L*vflux_L_arr(1)*vel_L(2)*(1._wp/dx(j)), kind=stp) + rhs_vf(E_idx)%sf(j, k, l) = rhs_vf(E_idx)%sf(j, k, & + & l) + real(0.5_wp*dt*mu_L*vflux_L_arr(1)*vel_L(2)*(1._wp/dx(j)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb + 1)%sf(j + 1, k, l) = rhs_vf(momxb + 1)%sf(j + 1, k, l) - & - real(0.5_wp*dt*mu_R*vflux_R_arr(1)*(1._wp/dx(j + 1)), kind=stp) + rhs_vf(momxb + 1)%sf(j + 1, k, l) = rhs_vf(momxb + 1)%sf(j + 1, k, & + & l) - real(0.5_wp*dt*mu_R*vflux_R_arr(1)*(1._wp/dx(j + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(E_idx)%sf(j + 1, k, l) = rhs_vf(E_idx)%sf(j + 1, k, l) - & - real(0.5_wp*dt*mu_R*vflux_R_arr(1)*vel_R(2)*(1._wp/dx(j + 1)), kind=stp) + rhs_vf(E_idx)%sf(j + 1, k, l) = rhs_vf(E_idx)%sf(j + 1, k, & + & l) - real(0.5_wp*dt*mu_R*vflux_R_arr(1)*vel_R(2)*(1._wp/dx(j + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb + 1)%sf(j, k, l) = rhs_vf(momxb + 1)%sf(j, k, l) + & - real(0.5_wp*dt*mu_R*vflux_R_arr(1)*(1._wp/dx(j)), kind=stp) + rhs_vf(momxb + 1)%sf(j, k, l) = rhs_vf(momxb + 1)%sf(j, k, & + & l) + real(0.5_wp*dt*mu_R*vflux_R_arr(1)*(1._wp/dx(j)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(E_idx)%sf(j, k, l) = rhs_vf(E_idx)%sf(j, k, l) + & - real(0.5_wp*dt*mu_R*vflux_R_arr(1)*vel_R(2)*(1._wp/dx(j)), kind=stp) + rhs_vf(E_idx)%sf(j, k, l) = rhs_vf(E_idx)%sf(j, k, & + & l) + real(0.5_wp*dt*mu_R*vflux_R_arr(1)*vel_R(2)*(1._wp/dx(j)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb + 2)%sf(j + 1, k, l) = rhs_vf(momxb + 2)%sf(j + 1, k, l) - & - real(0.5_wp*dt*mu_L*vflux_L_arr(2)*(1._wp/dx(j + 1)), kind=stp) + rhs_vf(momxb + 2)%sf(j + 1, k, l) = rhs_vf(momxb + 2)%sf(j + 1, k, & + & l) - real(0.5_wp*dt*mu_L*vflux_L_arr(2)*(1._wp/dx(j + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(E_idx)%sf(j + 1, k, l) = rhs_vf(E_idx)%sf(j + 1, k, l) - & - real(0.5_wp*dt*mu_L*vflux_L_arr(2)*vel_L(3)*(1._wp/dx(j + 1)), kind=stp) + rhs_vf(E_idx)%sf(j + 1, k, l) = rhs_vf(E_idx)%sf(j + 1, k, & + & l) - real(0.5_wp*dt*mu_L*vflux_L_arr(2)*vel_L(3)*(1._wp/dx(j + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb + 2)%sf(j, k, l) = rhs_vf(momxb + 2)%sf(j, k, l) + & - real(0.5_wp*dt*mu_L*vflux_L_arr(2)*(1._wp/dx(j)), kind=stp) + rhs_vf(momxb + 2)%sf(j, k, l) = rhs_vf(momxb + 2)%sf(j, k, & + & l) + real(0.5_wp*dt*mu_L*vflux_L_arr(2)*(1._wp/dx(j)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(E_idx)%sf(j, k, l) = rhs_vf(E_idx)%sf(j, k, l) + & - real(0.5_wp*dt*mu_L*vflux_L_arr(2)*vel_L(3)*(1._wp/dx(j)), kind=stp) + rhs_vf(E_idx)%sf(j, k, l) = rhs_vf(E_idx)%sf(j, k, & + & l) + real(0.5_wp*dt*mu_L*vflux_L_arr(2)*vel_L(3)*(1._wp/dx(j)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb + 2)%sf(j + 1, k, l) = rhs_vf(momxb + 2)%sf(j + 1, k, l) - & - real(0.5_wp*dt*mu_R*vflux_R_arr(2)*(1._wp/dx(j + 1)), kind=stp) + rhs_vf(momxb + 2)%sf(j + 1, k, l) = rhs_vf(momxb + 2)%sf(j + 1, k, & + & l) - real(0.5_wp*dt*mu_R*vflux_R_arr(2)*(1._wp/dx(j + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(E_idx)%sf(j + 1, k, l) = rhs_vf(E_idx)%sf(j + 1, k, l) - & - real(0.5_wp*dt*mu_R*vflux_R_arr(2)*vel_R(3)*(1._wp/dx(j + 1)), kind=stp) + rhs_vf(E_idx)%sf(j + 1, k, l) = rhs_vf(E_idx)%sf(j + 1, k, & + & l) - real(0.5_wp*dt*mu_R*vflux_R_arr(2)*vel_R(3)*(1._wp/dx(j + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb + 2)%sf(j, k, l) = rhs_vf(momxb + 2)%sf(j, k, l) + & - real(0.5_wp*dt*mu_R*vflux_R_arr(2)*(1._wp/dx(j)), kind=stp) + rhs_vf(momxb + 2)%sf(j, k, l) = rhs_vf(momxb + 2)%sf(j, k, & + & l) + real(0.5_wp*dt*mu_R*vflux_R_arr(2)*(1._wp/dx(j)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(E_idx)%sf(j, k, l) = rhs_vf(E_idx)%sf(j, k, l) + & - real(0.5_wp*dt*mu_R*vflux_R_arr(2)*vel_R(3)*(1._wp/dx(j)), kind=stp) + rhs_vf(E_idx)%sf(j, k, l) = rhs_vf(E_idx)%sf(j, k, & + & l) + real(0.5_wp*dt*mu_R*vflux_R_arr(2)*vel_R(3)*(1._wp/dx(j)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb)%sf(j + 1, k, l) = rhs_vf(momxb)%sf(j + 1, k, l) - & - real(0.5_wp*dt*mu_L*vflux_L_arr(3)*(1._wp/dx(j + 1)), kind=stp) + rhs_vf(momxb)%sf(j + 1, k, l) = rhs_vf(momxb)%sf(j + 1, k, & + & l) - real(0.5_wp*dt*mu_L*vflux_L_arr(3)*(1._wp/dx(j + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(E_idx)%sf(j + 1, k, l) = rhs_vf(E_idx)%sf(j + 1, k, l) - & - real(0.5_wp*dt*mu_L*vflux_L_arr(3)*vel_L(1)*(1._wp/dx(j + 1)), kind=stp) + rhs_vf(E_idx)%sf(j + 1, k, l) = rhs_vf(E_idx)%sf(j + 1, k, & + & l) - real(0.5_wp*dt*mu_L*vflux_L_arr(3)*vel_L(1)*(1._wp/dx(j + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb)%sf(j, k, l) = rhs_vf(momxb)%sf(j, k, l) + & - real(0.5_wp*dt*mu_L*vflux_L_arr(3)*(1._wp/dx(j)), kind=stp) + rhs_vf(momxb)%sf(j, k, l) = rhs_vf(momxb)%sf(j, k, & + & l) + real(0.5_wp*dt*mu_L*vflux_L_arr(3)*(1._wp/dx(j)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(E_idx)%sf(j, k, l) = rhs_vf(E_idx)%sf(j, k, l) + & - real(0.5_wp*dt*mu_L*vflux_L_arr(3)*vel_L(1)*(1._wp/dx(j)), kind=stp) + rhs_vf(E_idx)%sf(j, k, l) = rhs_vf(E_idx)%sf(j, k, & + & l) + real(0.5_wp*dt*mu_L*vflux_L_arr(3)*vel_L(1)*(1._wp/dx(j)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb)%sf(j + 1, k, l) = rhs_vf(momxb)%sf(j + 1, k, l) - & - real(0.5_wp*dt*mu_R*vflux_R_arr(3)*(1._wp/dx(j + 1)), kind=stp) + rhs_vf(momxb)%sf(j + 1, k, l) = rhs_vf(momxb)%sf(j + 1, k, & + & l) - real(0.5_wp*dt*mu_R*vflux_R_arr(3)*(1._wp/dx(j + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(E_idx)%sf(j + 1, k, l) = rhs_vf(E_idx)%sf(j + 1, k, l) - & - real(0.5_wp*dt*mu_R*vflux_R_arr(3)*vel_R(1)*(1._wp/dx(j + 1)), kind=stp) + rhs_vf(E_idx)%sf(j + 1, k, l) = rhs_vf(E_idx)%sf(j + 1, k, & + & l) - real(0.5_wp*dt*mu_R*vflux_R_arr(3)*vel_R(1)*(1._wp/dx(j + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb)%sf(j, k, l) = rhs_vf(momxb)%sf(j, k, l) + & - real(0.5_wp*dt*mu_R*vflux_R_arr(3)*(1._wp/dx(j)), kind=stp) + rhs_vf(momxb)%sf(j, k, l) = rhs_vf(momxb)%sf(j, k, & + & l) + real(0.5_wp*dt*mu_R*vflux_R_arr(3)*(1._wp/dx(j)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(E_idx)%sf(j, k, l) = rhs_vf(E_idx)%sf(j, k, l) + & - real(0.5_wp*dt*mu_R*vflux_R_arr(3)*vel_R(1)*(1._wp/dx(j)), kind=stp) + rhs_vf(E_idx)%sf(j, k, l) = rhs_vf(E_idx)%sf(j, k, & + & l) + real(0.5_wp*dt*mu_R*vflux_R_arr(3)*vel_R(1)*(1._wp/dx(j)), kind=stp) end if E_L = 0._wp; E_R = 0._wp @@ -1246,178 +1137,164 @@ contains E_R = E_R + coeff_R(q)*q_cons_vf(E_idx)%sf(j + q, k, l) end do - call s_get_derived_states(E_L, gamma_L, pi_inf_L, rho_L, vel_L, & - E_R, gamma_R, pi_inf_R, rho_R, vel_R, & - pres_L, pres_R, cfl) + call s_get_derived_states(E_L, gamma_L, pi_inf_L, rho_L, vel_L, E_R, gamma_R, pi_inf_R, rho_R, & + & vel_R, pres_L, pres_R, cfl) $:GPU_LOOP(parallelism='[seq]') do i = 1, num_fluids $:GPU_ATOMIC(atomic='update') - rhs_vf(i)%sf(j + 1, k, l) = rhs_vf(i)%sf(j + 1, k, l) + & - real((0.5_wp*dt*(alpha_rho_L(i)* & - vel_L(1))*(1._wp/dx(j + 1)) - & - 0.5_wp*dt*cfl*(alpha_rho_L(i))*(1._wp/dx(j + 1))), kind=stp) + rhs_vf(i)%sf(j + 1, k, l) = rhs_vf(i)%sf(j + 1, k, & + & l) + real((0.5_wp*dt*(alpha_rho_L(i)*vel_L(1))*(1._wp/dx(j + 1)) & + & - 0.5_wp*dt*cfl*(alpha_rho_L(i))*(1._wp/dx(j + 1))), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(i)%sf(j, k, l) = rhs_vf(i)%sf(j, k, l) - & - real((0.5_wp*dt*(alpha_rho_L(i)* & - vel_L(1))*(1._wp/dx(j)) - & - 0.5_wp*dt*cfl*(alpha_rho_L(i))*(1._wp/dx(j))), kind=stp) + rhs_vf(i)%sf(j, k, l) = rhs_vf(i)%sf(j, k, & + & l) - real((0.5_wp*dt*(alpha_rho_L(i)*vel_L(1))*(1._wp/dx(j)) & + & - 0.5_wp*dt*cfl*(alpha_rho_L(i))*(1._wp/dx(j))), kind=stp) end do if (num_fluids > 1) then $:GPU_LOOP(parallelism='[seq]') do i = 1, num_fluids - 1 $:GPU_ATOMIC(atomic='update') - rhs_vf(advxb + i - 1)%sf(j + 1, k, l) = rhs_vf(advxb + i - 1)%sf(j + 1, k, l) + & - real((0.5_wp*dt*(alpha_L(i)* & - vel_L(1))*(1._wp/dx(j + 1)) - & - 0.5_wp*dt*cfl*(alpha_L(i))*(1._wp/dx(j + 1))), kind=stp) + rhs_vf(advxb + i - 1)%sf(j + 1, k, l) = rhs_vf(advxb + i - 1)%sf(j + 1, k, & + & l) + real((0.5_wp*dt*(alpha_L(i)*vel_L(1))*(1._wp/dx(j + 1)) & + & - 0.5_wp*dt*cfl*(alpha_L(i))*(1._wp/dx(j + 1))), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(advxb + i - 1)%sf(j + 1, k, l) = rhs_vf(advxb + i - 1)%sf(j + 1, k, l) & - - real(0.5_wp*dt*q_cons_vf(advxb + i - 1)%sf(j + 1, k, l)*vel_L(1)*(1._wp/dx(j + 1)), kind=stp) + rhs_vf(advxb + i - 1)%sf(j + 1, k, l) = rhs_vf(advxb + i - 1)%sf(j + 1, k, & + & l) - real(0.5_wp*dt*q_cons_vf(advxb + i - 1)%sf(j + 1, k, & + & l)*vel_L(1)*(1._wp/dx(j + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(advxb + i - 1)%sf(j, k, l) = rhs_vf(advxb + i - 1)%sf(j, k, l) - & - real(0.5_wp*dt*(alpha_L(i)* & - vel_L(1))*(1._wp/dx(j)) - & - 0.5_wp*dt*cfl*(alpha_L(i))*(1._wp/dx(j)), kind=stp) + rhs_vf(advxb + i - 1)%sf(j, k, l) = rhs_vf(advxb + i - 1)%sf(j, k, & + & l) - real(0.5_wp*dt*(alpha_L(i)*vel_L(1))*(1._wp/dx(j)) & + & - 0.5_wp*dt*cfl*(alpha_L(i))*(1._wp/dx(j)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(advxb + i - 1)%sf(j, k, l) = rhs_vf(advxb + i - 1)%sf(j, k, l) & - + real(0.5_wp*dt*q_cons_vf(advxb + i - 1)%sf(j, k, l)*vel_L(1)*(1._wp/dx(j)), kind=stp) + rhs_vf(advxb + i - 1)%sf(j, k, l) = rhs_vf(advxb + i - 1)%sf(j, k, & + & l) + real(0.5_wp*dt*q_cons_vf(advxb + i - 1)%sf(j, k, l)*vel_L(1)*(1._wp/dx(j)), & + & kind=stp) end do end if $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb)%sf(j + 1, k, l) = rhs_vf(momxb)%sf(j + 1, k, l) + & - real((0.5_wp*dt*(rho_L*(vel_L(1))**2.0 + & - pres_L)*(1._wp/dx(j + 1)) - & - 0.5_wp*dt*cfl*(rho_L*vel_L(1))*(1._wp/dx(j + 1))), kind=stp) + rhs_vf(momxb)%sf(j + 1, k, l) = rhs_vf(momxb)%sf(j + 1, k, & + & l) + real((0.5_wp*dt*(rho_L*(vel_L(1))**2.0 + pres_L)*(1._wp/dx(j + 1)) & + & - 0.5_wp*dt*cfl*(rho_L*vel_L(1))*(1._wp/dx(j + 1))), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb + 1)%sf(j + 1, k, l) = rhs_vf(momxb + 1)%sf(j + 1, k, l) + & - real((0.5_wp*dt*rho_L*vel_L(1)*vel_L(2)*(1._wp/dx(j + 1)) - & - 0.5_wp*dt*cfl*(rho_L*vel_L(2))*(1._wp/dx(j + 1))), kind=stp) + rhs_vf(momxb + 1)%sf(j + 1, k, l) = rhs_vf(momxb + 1)%sf(j + 1, k, & + & l) + real((0.5_wp*dt*rho_L*vel_L(1)*vel_L(2)*(1._wp/dx(j + 1)) & + & - 0.5_wp*dt*cfl*(rho_L*vel_L(2))*(1._wp/dx(j + 1))), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb + 2)%sf(j + 1, k, l) = rhs_vf(momxb + 2)%sf(j + 1, k, l) + & - real((0.5_wp*dt*rho_L*vel_L(1)*vel_L(3)*(1._wp/dx(j + 1)) - & - 0.5_wp*dt*cfl*(rho_L*vel_L(3))*(1._wp/dx(j + 1))), kind=stp) + rhs_vf(momxb + 2)%sf(j + 1, k, l) = rhs_vf(momxb + 2)%sf(j + 1, k, & + & l) + real((0.5_wp*dt*rho_L*vel_L(1)*vel_L(3)*(1._wp/dx(j + 1)) & + & - 0.5_wp*dt*cfl*(rho_L*vel_L(3))*(1._wp/dx(j + 1))), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(E_idx)%sf(j + 1, k, l) = rhs_vf(E_idx)%sf(j + 1, k, l) + & - real((0.5_wp*dt*(vel_L(1)*(E_L + & - pres_L))*(1._wp/dx(j + 1)) - & - 0.5_wp*dt*cfl*(E_L)*(1._wp/dx(j + 1))), kind=stp) + rhs_vf(E_idx)%sf(j + 1, k, l) = rhs_vf(E_idx)%sf(j + 1, k, & + & l) + real((0.5_wp*dt*(vel_L(1)*(E_L + pres_L))*(1._wp/dx(j + 1)) - 0.5_wp*dt*cfl*(E_L) & + & *(1._wp/dx(j + 1))), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb)%sf(j, k, l) = rhs_vf(momxb)%sf(j, k, l) - & - real((0.5_wp*dt*(rho_L*(vel_L(1))**2.0 + & - pres_L)*(1._wp/dx(j)) - & - 0.5_wp*dt*cfl*(rho_L*vel_L(1))*(1._wp/dx(j))), kind=stp) + rhs_vf(momxb)%sf(j, k, l) = rhs_vf(momxb)%sf(j, k, & + & l) - real((0.5_wp*dt*(rho_L*(vel_L(1))**2.0 + pres_L)*(1._wp/dx(j)) & + & - 0.5_wp*dt*cfl*(rho_L*vel_L(1))*(1._wp/dx(j))), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb + 1)%sf(j, k, l) = rhs_vf(momxb + 1)%sf(j, k, l) - & - real((0.5_wp*dt*rho_L*vel_L(1)*vel_L(2)*(1._wp/dx(j)) - & - 0.5_wp*dt*cfl*(rho_L*vel_L(2))*(1._wp/dx(j))), kind=stp) + rhs_vf(momxb + 1)%sf(j, k, l) = rhs_vf(momxb + 1)%sf(j, k, & + & l) - real((0.5_wp*dt*rho_L*vel_L(1)*vel_L(2)*(1._wp/dx(j)) & + & - 0.5_wp*dt*cfl*(rho_L*vel_L(2))*(1._wp/dx(j))), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb + 2)%sf(j, k, l) = rhs_vf(momxb + 2)%sf(j, k, l) - & - real((0.5_wp*dt*rho_L*vel_L(1)*vel_L(3)*(1._wp/dx(j)) - & - 0.5_wp*dt*cfl*(rho_L*vel_L(3))*(1._wp/dx(j))), kind=stp) + rhs_vf(momxb + 2)%sf(j, k, l) = rhs_vf(momxb + 2)%sf(j, k, & + & l) - real((0.5_wp*dt*rho_L*vel_L(1)*vel_L(3)*(1._wp/dx(j)) & + & - 0.5_wp*dt*cfl*(rho_L*vel_L(3))*(1._wp/dx(j))), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(E_idx)%sf(j, k, l) = rhs_vf(E_idx)%sf(j, k, l) - & - real((0.5_wp*dt*(vel_L(1)*(E_L + & - pres_L))*(1._wp/dx(j)) - & - 0.5_wp*dt*cfl*(E_L)*(1._wp/dx(j))), kind=stp) + rhs_vf(E_idx)%sf(j, k, l) = rhs_vf(E_idx)%sf(j, k, & + & l) - real((0.5_wp*dt*(vel_L(1)*(E_L + pres_L))*(1._wp/dx(j)) - 0.5_wp*dt*cfl*(E_L) & + & *(1._wp/dx(j))), kind=stp) $:GPU_LOOP(parallelism='[seq]') do i = 1, num_fluids $:GPU_ATOMIC(atomic='update') - rhs_vf(i)%sf(j + 1, k, l) = rhs_vf(i)%sf(j + 1, k, l) + & - real((0.5_wp*dt*(alpha_rho_R(i)* & - vel_R(1))*(1._wp/dx(j + 1)) + & - 0.5_wp*dt*cfl*(alpha_rho_R(i))*(1._wp/dx(j + 1))), kind=stp) + rhs_vf(i)%sf(j + 1, k, l) = rhs_vf(i)%sf(j + 1, k, & + & l) + real((0.5_wp*dt*(alpha_rho_R(i)*vel_R(1))*(1._wp/dx(j + 1)) & + & + 0.5_wp*dt*cfl*(alpha_rho_R(i))*(1._wp/dx(j + 1))), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(i)%sf(j, k, l) = rhs_vf(i)%sf(j, k, l) - & - real((0.5_wp*dt*(alpha_rho_R(i)* & - vel_R(1))*(1._wp/dx(j)) + & - 0.5_wp*dt*cfl*(alpha_rho_R(i))*(1._wp/dx(j))), kind=stp) + rhs_vf(i)%sf(j, k, l) = rhs_vf(i)%sf(j, k, & + & l) - real((0.5_wp*dt*(alpha_rho_R(i)*vel_R(1))*(1._wp/dx(j)) & + & + 0.5_wp*dt*cfl*(alpha_rho_R(i))*(1._wp/dx(j))), kind=stp) end do if (num_fluids > 1) then $:GPU_LOOP(parallelism='[seq]') do i = 1, num_fluids - 1 $:GPU_ATOMIC(atomic='update') - rhs_vf(advxb + i - 1)%sf(j + 1, k, l) = rhs_vf(advxb + i - 1)%sf(j + 1, k, l) + & - real((0.5_wp*dt*(alpha_R(i)* & - vel_R(1))*(1._wp/dx(j + 1)) + & - 0.5_wp*dt*cfl*(alpha_R(i))*(1._wp/dx(j + 1))), kind=stp) + rhs_vf(advxb + i - 1)%sf(j + 1, k, l) = rhs_vf(advxb + i - 1)%sf(j + 1, k, & + & l) + real((0.5_wp*dt*(alpha_R(i)*vel_R(1))*(1._wp/dx(j + 1)) & + & + 0.5_wp*dt*cfl*(alpha_R(i))*(1._wp/dx(j + 1))), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(advxb + i - 1)%sf(j + 1, k, l) = rhs_vf(advxb + i - 1)%sf(j + 1, k, l) & - - real((0.5_wp*dt*q_cons_vf(advxb + i - 1)%sf(j + 1, k, l)*vel_R(1)*(1._wp/dx(j + 1))), kind=stp) + rhs_vf(advxb + i - 1)%sf(j + 1, k, l) = rhs_vf(advxb + i - 1)%sf(j + 1, k, & + & l) - real((0.5_wp*dt*q_cons_vf(advxb + i - 1)%sf(j + 1, k, & + & l)*vel_R(1)*(1._wp/dx(j + 1))), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(advxb + i - 1)%sf(j, k, l) = rhs_vf(advxb + i - 1)%sf(j, k, l) - & - real((0.5_wp*dt*(alpha_R(i)* & - vel_R(1))*(1._wp/dx(j)) + & - 0.5_wp*dt*cfl*(alpha_R(i))*(1._wp/dx(j))), kind=stp) + rhs_vf(advxb + i - 1)%sf(j, k, l) = rhs_vf(advxb + i - 1)%sf(j, k, & + & l) - real((0.5_wp*dt*(alpha_R(i)*vel_R(1))*(1._wp/dx(j)) & + & + 0.5_wp*dt*cfl*(alpha_R(i))*(1._wp/dx(j))), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(advxb + i - 1)%sf(j, k, l) = rhs_vf(advxb + i - 1)%sf(j, k, l) & - + real((0.5_wp*dt*q_cons_vf(advxb + i - 1)%sf(j, k, l)*vel_R(1)*(1._wp/dx(j))), kind=stp) + rhs_vf(advxb + i - 1)%sf(j, k, l) = rhs_vf(advxb + i - 1)%sf(j, k, & + & l) + real((0.5_wp*dt*q_cons_vf(advxb + i - 1)%sf(j, k, & + & l)*vel_R(1)*(1._wp/dx(j))), kind=stp) end do end if $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb)%sf(j + 1, k, l) = rhs_vf(momxb)%sf(j + 1, k, l) + & - real((0.5_wp*dt*(rho_R*(vel_R(1))**2.0 + & - pres_R)*(1._wp/dx(j + 1)) + & - 0.5_wp*dt*cfl*(rho_R*vel_R(1))*(1._wp/dx(j + 1))), kind=stp) + rhs_vf(momxb)%sf(j + 1, k, l) = rhs_vf(momxb)%sf(j + 1, k, & + & l) + real((0.5_wp*dt*(rho_R*(vel_R(1))**2.0 + pres_R)*(1._wp/dx(j + 1)) & + & + 0.5_wp*dt*cfl*(rho_R*vel_R(1))*(1._wp/dx(j + 1))), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb + 1)%sf(j + 1, k, l) = rhs_vf(momxb + 1)%sf(j + 1, k, l) + & - real((0.5_wp*dt*rho_R*vel_R(1)*vel_R(2)*(1._wp/dx(j + 1)) + & - 0.5_wp*dt*cfl*(rho_R*vel_R(2))*(1._wp/dx(j + 1))), kind=stp) + rhs_vf(momxb + 1)%sf(j + 1, k, l) = rhs_vf(momxb + 1)%sf(j + 1, k, & + & l) + real((0.5_wp*dt*rho_R*vel_R(1)*vel_R(2)*(1._wp/dx(j + 1)) & + & + 0.5_wp*dt*cfl*(rho_R*vel_R(2))*(1._wp/dx(j + 1))), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb + 2)%sf(j + 1, k, l) = rhs_vf(momxb + 2)%sf(j + 1, k, l) + & - real((0.5_wp*dt*rho_R*vel_R(1)*vel_R(3)*(1._wp/dx(j + 1)) + & - 0.5_wp*dt*cfl*(rho_R*vel_R(3))*(1._wp/dx(j + 1))), kind=stp) + rhs_vf(momxb + 2)%sf(j + 1, k, l) = rhs_vf(momxb + 2)%sf(j + 1, k, & + & l) + real((0.5_wp*dt*rho_R*vel_R(1)*vel_R(3)*(1._wp/dx(j + 1)) & + & + 0.5_wp*dt*cfl*(rho_R*vel_R(3))*(1._wp/dx(j + 1))), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(E_idx)%sf(j + 1, k, l) = rhs_vf(E_idx)%sf(j + 1, k, l) + & - real((0.5_wp*dt*(vel_R(1)*(E_R + & - pres_R))*(1._wp/dx(j + 1)) + & - 0.5_wp*dt*cfl*(E_R)*(1._wp/dx(j + 1))), kind=stp) + rhs_vf(E_idx)%sf(j + 1, k, l) = rhs_vf(E_idx)%sf(j + 1, k, & + & l) + real((0.5_wp*dt*(vel_R(1)*(E_R + pres_R))*(1._wp/dx(j + 1)) + 0.5_wp*dt*cfl*(E_R) & + & *(1._wp/dx(j + 1))), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb)%sf(j, k, l) = rhs_vf(momxb)%sf(j, k, l) - & - real((0.5_wp*dt*(rho_R*(vel_R(1))**2.0 + & - pres_R)*(1._wp/dx(j)) + & - 0.5_wp*dt*cfl*(rho_R*vel_R(1))*(1._wp/dx(j))), kind=stp) + rhs_vf(momxb)%sf(j, k, l) = rhs_vf(momxb)%sf(j, k, & + & l) - real((0.5_wp*dt*(rho_R*(vel_R(1))**2.0 + pres_R)*(1._wp/dx(j)) & + & + 0.5_wp*dt*cfl*(rho_R*vel_R(1))*(1._wp/dx(j))), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb + 1)%sf(j, k, l) = rhs_vf(momxb + 1)%sf(j, k, l) - & - real((0.5_wp*dt*rho_R*vel_R(1)*vel_R(2)*(1._wp/dx(j)) + & - 0.5_wp*dt*cfl*(rho_R*vel_R(2))*(1._wp/dx(j))), kind=stp) + rhs_vf(momxb + 1)%sf(j, k, l) = rhs_vf(momxb + 1)%sf(j, k, & + & l) - real((0.5_wp*dt*rho_R*vel_R(1)*vel_R(2)*(1._wp/dx(j)) & + & + 0.5_wp*dt*cfl*(rho_R*vel_R(2))*(1._wp/dx(j))), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb + 2)%sf(j, k, l) = rhs_vf(momxb + 2)%sf(j, k, l) - & - real((0.5_wp*dt*rho_R*vel_R(1)*vel_R(3)*(1._wp/dx(j)) + & - 0.5_wp*dt*cfl*(rho_R*vel_R(3))*(1._wp/dx(j))), kind=stp) + rhs_vf(momxb + 2)%sf(j, k, l) = rhs_vf(momxb + 2)%sf(j, k, & + & l) - real((0.5_wp*dt*rho_R*vel_R(1)*vel_R(3)*(1._wp/dx(j)) & + & + 0.5_wp*dt*cfl*(rho_R*vel_R(3))*(1._wp/dx(j))), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(E_idx)%sf(j, k, l) = rhs_vf(E_idx)%sf(j, k, l) - & - real((0.5_wp*dt*(vel_R(1)*(E_R + & - pres_R))*(1._wp/dx(j)) + & - 0.5_wp*dt*cfl*(E_R)*(1._wp/dx(j))), kind=stp) - + rhs_vf(E_idx)%sf(j, k, l) = rhs_vf(E_idx)%sf(j, k, & + & l) - real((0.5_wp*dt*(vel_R(1)*(E_R + pres_R))*(1._wp/dx(j)) + 0.5_wp*dt*cfl*(E_R) & + & *(1._wp/dx(j))), kind=stp) end do end do end do @@ -1427,26 +1304,26 @@ contains else if (idir == 2) then if (p == 0) then #:if not MFC_CASE_OPTIMIZATION or num_dims > 1 - $:GPU_PARALLEL_LOOP(collapse=3, private='[j,k,l,rho_L, rho_R, gamma_L, gamma_R, pi_inf_L, pi_inf_R, mu_L, mu_R, vel_L, vel_R, pres_L, pres_R, alpha_L, alpha_R, alpha_rho_L, alpha_rho_R, F_L, F_R, E_L, E_R, cfl, dvel_small, rho_sf_small, vflux_L_arr, vflux_R_arr]') + $:GPU_PARALLEL_LOOP(collapse=3, private='[j, k, l, rho_L, rho_R, gamma_L, gamma_R, pi_inf_L, pi_inf_R, mu_L, & + & mu_R, vel_L, vel_R, pres_L, pres_R, alpha_L, alpha_R, alpha_rho_L, alpha_rho_R, F_L, & + & F_R, E_L, E_R, cfl, dvel_small, rho_sf_small, vflux_L_arr, vflux_R_arr]') do l = 0, p do k = -1, n do j = 0, m - if (viscous) then vflux_L_arr = 0._wp vflux_R_arr = 0._wp #:if MFC_CASE_OPTIMIZATION #:if igr_order == 5 - !DIR$ unroll 6 + ! DIR$ unroll 6 #:elif igr_order == 3 - !DIR$ unroll 4 + ! DIR$ unroll 4 #:endif #:endif $:GPU_LOOP(parallelism='[seq]') do q = vidxb, vidxe - - !x-direction contributions + ! x-direction contributions $:GPU_LOOP(parallelism='[seq]') do i = -1, 1 rho_L = 0._wp @@ -1457,12 +1334,10 @@ contains rho_sf_small(i) = rho_L end do - dvel_small(1) = (1/(2._wp*dx(j)))*( & - q_cons_vf(momxb)%sf(j + 1, k + q, l)/rho_sf_small(1) - & - q_cons_vf(momxb)%sf(j - 1, k + q, l)/rho_sf_small(-1)) - dvel_small(2) = (1/(2._wp*dx(j)))*( & - q_cons_vf(momxb + 1)%sf(j + 1, k + q, l)/rho_sf_small(1) - & - q_cons_vf(momxb + 1)%sf(j - 1, k + q, l)/rho_sf_small(-1)) + dvel_small(1) = (1/(2._wp*dx(j)))*(q_cons_vf(momxb)%sf(j + 1, k + q, & + & l)/rho_sf_small(1) - q_cons_vf(momxb)%sf(j - 1, k + q, l)/rho_sf_small(-1)) + dvel_small(2) = (1/(2._wp*dx(j)))*(q_cons_vf(momxb + 1)%sf(j + 1, k + q, & + & l)/rho_sf_small(1) - q_cons_vf(momxb + 1)%sf(j - 1, k + q, l)/rho_sf_small(-1)) if (q > vidxb) then vflux_L_arr(1) = vflux_L_arr(1) + coeff_L(q)*(dvel_small(2)) @@ -1473,7 +1348,7 @@ contains vflux_R_arr(3) = vflux_R_arr(3) + coeff_R(q)*(-2._wp*dvel_small(1))/3._wp end if - !y-direction contributions + ! y-direction contributions $:GPU_LOOP(parallelism='[seq]') do i = -1, 1 rho_L = 0._wp @@ -1484,12 +1359,10 @@ contains rho_sf_small(i) = rho_L end do - dvel_small(1) = (1/(2._wp*dy(k)))*( & - q_cons_vf(momxb)%sf(j, k + 1 + q, l)/rho_sf_small(1) - & - q_cons_vf(momxb)%sf(j, k - 1 + q, l)/rho_sf_small(-1)) - dvel_small(2) = (1/(2._wp*dy(k)))*( & - q_cons_vf(momxb + 1)%sf(j, k + 1 + q, l)/rho_sf_small(1) - & - q_cons_vf(momxb + 1)%sf(j, k - 1 + q, l)/rho_sf_small(-1)) + dvel_small(1) = (1/(2._wp*dy(k)))*(q_cons_vf(momxb)%sf(j, k + 1 + q, & + & l)/rho_sf_small(1) - q_cons_vf(momxb)%sf(j, k - 1 + q, l)/rho_sf_small(-1)) + dvel_small(2) = (1/(2._wp*dy(k)))*(q_cons_vf(momxb + 1)%sf(j, k + 1 + q, & + & l)/rho_sf_small(1) - q_cons_vf(momxb + 1)%sf(j, k - 1 + q, l)/rho_sf_small(-1)) if (q > vidxb) then vflux_L_arr(1) = vflux_L_arr(1) + coeff_L(q)*(dvel_small(1)) @@ -1560,7 +1433,6 @@ contains end do if (num_fluids > 1) then - alpha_L(num_fluids) = 1._wp alpha_R(num_fluids) = 1._wp @@ -1602,60 +1474,60 @@ contains end do $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb)%sf(j, k + 1, l) = rhs_vf(momxb)%sf(j, k + 1, l) - & - real(0.5_wp*dt*mu_L*vflux_L_arr(1)*(1._wp/dy(k + 1)), kind=stp) + rhs_vf(momxb)%sf(j, k + 1, l) = rhs_vf(momxb)%sf(j, k + 1, & + & l) - real(0.5_wp*dt*mu_L*vflux_L_arr(1)*(1._wp/dy(k + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(E_idx)%sf(j, k + 1, l) = rhs_vf(E_idx)%sf(j, k + 1, l) - & - real(0.5_wp*dt*mu_L*vflux_L_arr(1)*vel_L(1)*(1._wp/dy(k + 1)), kind=stp) + rhs_vf(E_idx)%sf(j, k + 1, l) = rhs_vf(E_idx)%sf(j, k + 1, & + & l) - real(0.5_wp*dt*mu_L*vflux_L_arr(1)*vel_L(1)*(1._wp/dy(k + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb)%sf(j, k, l) = rhs_vf(momxb)%sf(j, k, l) + & - real(0.5_wp*dt*mu_L*vflux_L_arr(1)*(1._wp/dy(k)), kind=stp) + rhs_vf(momxb)%sf(j, k, l) = rhs_vf(momxb)%sf(j, k, & + & l) + real(0.5_wp*dt*mu_L*vflux_L_arr(1)*(1._wp/dy(k)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(E_idx)%sf(j, k, l) = rhs_vf(E_idx)%sf(j, k, l) + & - real(0.5_wp*dt*mu_L*vflux_L_arr(1)*vel_L(1)*(1._wp/dy(k)), kind=stp) + rhs_vf(E_idx)%sf(j, k, l) = rhs_vf(E_idx)%sf(j, k, & + & l) + real(0.5_wp*dt*mu_L*vflux_L_arr(1)*vel_L(1)*(1._wp/dy(k)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb)%sf(j, k + 1, l) = rhs_vf(momxb)%sf(j, k + 1, l) - & - real(0.5_wp*dt*mu_R*vflux_R_arr(1)*(1._wp/dy(k + 1)), kind=stp) + rhs_vf(momxb)%sf(j, k + 1, l) = rhs_vf(momxb)%sf(j, k + 1, & + & l) - real(0.5_wp*dt*mu_R*vflux_R_arr(1)*(1._wp/dy(k + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(E_idx)%sf(j, k + 1, l) = rhs_vf(E_idx)%sf(j, k + 1, l) - & - real(0.5_wp*dt*mu_R*vflux_R_arr(1)*vel_R(1)*(1._wp/dy(k + 1)), kind=stp) + rhs_vf(E_idx)%sf(j, k + 1, l) = rhs_vf(E_idx)%sf(j, k + 1, & + & l) - real(0.5_wp*dt*mu_R*vflux_R_arr(1)*vel_R(1)*(1._wp/dy(k + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb)%sf(j, k, l) = rhs_vf(momxb)%sf(j, k, l) + & - real(0.5_wp*dt*mu_R*vflux_R_arr(1)*(1._wp/dy(k)), kind=stp) + rhs_vf(momxb)%sf(j, k, l) = rhs_vf(momxb)%sf(j, k, & + & l) + real(0.5_wp*dt*mu_R*vflux_R_arr(1)*(1._wp/dy(k)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(E_idx)%sf(j, k, l) = rhs_vf(E_idx)%sf(j, k, l) + & - real(0.5_wp*dt*mu_R*vflux_R_arr(1)*vel_R(1)*(1._wp/dy(k)), kind=stp) + rhs_vf(E_idx)%sf(j, k, l) = rhs_vf(E_idx)%sf(j, k, & + & l) + real(0.5_wp*dt*mu_R*vflux_R_arr(1)*vel_R(1)*(1._wp/dy(k)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb + 1)%sf(j, k + 1, l) = rhs_vf(momxb + 1)%sf(j, k + 1, l) - & - real(0.5_wp*dt*mu_L*vflux_L_arr(3)*(1._wp/dy(k + 1)), kind=stp) + rhs_vf(momxb + 1)%sf(j, k + 1, l) = rhs_vf(momxb + 1)%sf(j, k + 1, & + & l) - real(0.5_wp*dt*mu_L*vflux_L_arr(3)*(1._wp/dy(k + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(E_idx)%sf(j, k + 1, l) = rhs_vf(E_idx)%sf(j, k + 1, l) - & - real(0.5_wp*dt*mu_L*vflux_L_arr(3)*vel_L(2)*(1._wp/dy(k + 1)), kind=stp) + rhs_vf(E_idx)%sf(j, k + 1, l) = rhs_vf(E_idx)%sf(j, k + 1, & + & l) - real(0.5_wp*dt*mu_L*vflux_L_arr(3)*vel_L(2)*(1._wp/dy(k + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb + 1)%sf(j, k, l) = rhs_vf(momxb + 1)%sf(j, k, l) + & - real(0.5_wp*dt*mu_L*vflux_L_arr(3)*(1._wp/dy(k)), kind=stp) + rhs_vf(momxb + 1)%sf(j, k, l) = rhs_vf(momxb + 1)%sf(j, k, & + & l) + real(0.5_wp*dt*mu_L*vflux_L_arr(3)*(1._wp/dy(k)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(E_idx)%sf(j, k, l) = rhs_vf(E_idx)%sf(j, k, l) + & - real(0.5_wp*dt*mu_L*vflux_L_arr(3)*vel_L(2)*(1._wp/dy(k)), kind=stp) + rhs_vf(E_idx)%sf(j, k, l) = rhs_vf(E_idx)%sf(j, k, & + & l) + real(0.5_wp*dt*mu_L*vflux_L_arr(3)*vel_L(2)*(1._wp/dy(k)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb + 1)%sf(j, k + 1, l) = rhs_vf(momxb + 1)%sf(j, k + 1, l) - & - real(0.5_wp*dt*mu_R*vflux_R_arr(3)*(1._wp/dy(k + 1)), kind=stp) + rhs_vf(momxb + 1)%sf(j, k + 1, l) = rhs_vf(momxb + 1)%sf(j, k + 1, & + & l) - real(0.5_wp*dt*mu_R*vflux_R_arr(3)*(1._wp/dy(k + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(E_idx)%sf(j, k + 1, l) = rhs_vf(E_idx)%sf(j, k + 1, l) - & - real(0.5_wp*dt*mu_R*vflux_R_arr(3)*vel_R(2)*(1._wp/dy(k + 1)), kind=stp) + rhs_vf(E_idx)%sf(j, k + 1, l) = rhs_vf(E_idx)%sf(j, k + 1, & + & l) - real(0.5_wp*dt*mu_R*vflux_R_arr(3)*vel_R(2)*(1._wp/dy(k + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb + 1)%sf(j, k, l) = rhs_vf(momxb + 1)%sf(j, k, l) + & - real(0.5_wp*dt*mu_R*vflux_R_arr(3)*(1._wp/dy(k)), kind=stp) + rhs_vf(momxb + 1)%sf(j, k, l) = rhs_vf(momxb + 1)%sf(j, k, & + & l) + real(0.5_wp*dt*mu_R*vflux_R_arr(3)*(1._wp/dy(k)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(E_idx)%sf(j, k, l) = rhs_vf(E_idx)%sf(j, k, l) + & - real(0.5_wp*dt*mu_R*vflux_R_arr(3)*vel_R(2)*(1._wp/dy(k)), kind=stp) + rhs_vf(E_idx)%sf(j, k, l) = rhs_vf(E_idx)%sf(j, k, & + & l) + real(0.5_wp*dt*mu_R*vflux_R_arr(3)*vel_R(2)*(1._wp/dy(k)), kind=stp) end if E_L = 0._wp; E_R = 0._wp @@ -1673,150 +1545,137 @@ contains F_R = F_R + coeff_R(q)*jac(j, k + q, l) end do - call s_get_derived_states(E_L, gamma_L, pi_inf_L, rho_L, vel_L, & - E_R, gamma_R, pi_inf_R, rho_R, vel_R, & - pres_L, pres_R, cfl) + call s_get_derived_states(E_L, gamma_L, pi_inf_L, rho_L, vel_L, E_R, gamma_R, pi_inf_R, rho_R, & + & vel_R, pres_L, pres_R, cfl) $:GPU_LOOP(parallelism='[seq]') do i = 1, num_fluids $:GPU_ATOMIC(atomic='update') - rhs_vf(i)%sf(j, k + 1, l) = rhs_vf(i)%sf(j, k + 1, l) + & - real(0.5_wp*dt*(alpha_rho_L(i)* & - vel_L(2))*(1._wp/dy(k + 1)) - & - 0.5_wp*dt*cfl*(alpha_rho_L(i))*(1._wp/dy(k + 1)), kind=stp) + rhs_vf(i)%sf(j, k + 1, l) = rhs_vf(i)%sf(j, k + 1, & + & l) + real(0.5_wp*dt*(alpha_rho_L(i)*vel_L(2))*(1._wp/dy(k + 1)) & + & - 0.5_wp*dt*cfl*(alpha_rho_L(i))*(1._wp/dy(k + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(i)%sf(j, k, l) = rhs_vf(i)%sf(j, k, l) - & - real(0.5_wp*dt*(alpha_rho_L(i)* & - vel_L(2))*(1._wp/dy(k)) - & - 0.5_wp*dt*cfl*(alpha_rho_L(i))*(1._wp/dy(k)), kind=stp) + rhs_vf(i)%sf(j, k, l) = rhs_vf(i)%sf(j, k, & + & l) - real(0.5_wp*dt*(alpha_rho_L(i)*vel_L(2))*(1._wp/dy(k)) & + & - 0.5_wp*dt*cfl*(alpha_rho_L(i))*(1._wp/dy(k)), kind=stp) end do if (num_fluids > 1) then $:GPU_LOOP(parallelism='[seq]') do i = 1, num_fluids - 1 $:GPU_ATOMIC(atomic='update') - rhs_vf(advxb + i - 1)%sf(j, k + 1, l) = rhs_vf(advxb + i - 1)%sf(j, k + 1, l) + & - real(0.5_wp*dt*(alpha_L(i)* & - vel_L(2))*(1._wp/dy(k + 1)) - & - 0.5_wp*dt*cfl*(alpha_L(i))*(1._wp/dy(k + 1)), kind=stp) + rhs_vf(advxb + i - 1)%sf(j, k + 1, l) = rhs_vf(advxb + i - 1)%sf(j, k + 1, & + & l) + real(0.5_wp*dt*(alpha_L(i)*vel_L(2))*(1._wp/dy(k + 1)) & + & - 0.5_wp*dt*cfl*(alpha_L(i))*(1._wp/dy(k + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(advxb + i - 1)%sf(j, k + 1, l) = rhs_vf(advxb + i - 1)%sf(j, k + 1, l) & - - real(0.5_wp*dt*q_cons_vf(advxb + i - 1)%sf(j, k + 1, l)*vel_L(2)*(1._wp/dy(k + 1)), kind=stp) + rhs_vf(advxb + i - 1)%sf(j, k + 1, l) = rhs_vf(advxb + i - 1)%sf(j, k + 1, & + & l) - real(0.5_wp*dt*q_cons_vf(advxb + i - 1)%sf(j, k + 1, & + & l)*vel_L(2)*(1._wp/dy(k + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(advxb + i - 1)%sf(j, k, l) = rhs_vf(advxb + i - 1)%sf(j, k, l) - & - real(0.5_wp*dt*(alpha_L(i)* & - vel_L(2))*(1._wp/dy(k)) - & - 0.5_wp*dt*cfl*(alpha_L(i))*(1._wp/dy(k)), kind=stp) + rhs_vf(advxb + i - 1)%sf(j, k, l) = rhs_vf(advxb + i - 1)%sf(j, k, & + & l) - real(0.5_wp*dt*(alpha_L(i)*vel_L(2))*(1._wp/dy(k)) & + & - 0.5_wp*dt*cfl*(alpha_L(i))*(1._wp/dy(k)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(advxb + i - 1)%sf(j, k, l) = rhs_vf(advxb + i - 1)%sf(j, k, l) & - + real(0.5_wp*dt*q_cons_vf(advxb + i - 1)%sf(j, k, l)*vel_L(2)*(1._wp/dy(k)), kind=stp) + rhs_vf(advxb + i - 1)%sf(j, k, l) = rhs_vf(advxb + i - 1)%sf(j, k, & + & l) + real(0.5_wp*dt*q_cons_vf(advxb + i - 1)%sf(j, k, l)*vel_L(2)*(1._wp/dy(k)), & + & kind=stp) end do end if $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb + 1)%sf(j, k + 1, l) = rhs_vf(momxb + 1)%sf(j, k + 1, l) + & - real(0.5_wp*dt*(rho_L*(vel_L(2))**2.0 + & - pres_L + F_L)*(1._wp/dy(k + 1)) - & - 0.5_wp*dt*cfl*(rho_L*vel_L(2))*(1._wp/dy(k + 1)), kind=stp) + rhs_vf(momxb + 1)%sf(j, k + 1, l) = rhs_vf(momxb + 1)%sf(j, k + 1, & + & l) + real(0.5_wp*dt*(rho_L*(vel_L(2))**2.0 + pres_L + F_L)*(1._wp/dy(k + 1)) & + & - 0.5_wp*dt*cfl*(rho_L*vel_L(2))*(1._wp/dy(k + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb)%sf(j, k + 1, l) = rhs_vf(momxb)%sf(j, k + 1, l) + & - real(0.5_wp*dt*rho_L*vel_L(1)*vel_L(2)*(1._wp/dy(k + 1)) - & - 0.5_wp*dt*cfl*(rho_L*vel_L(1))*(1._wp/dy(k + 1)), kind=stp) + rhs_vf(momxb)%sf(j, k + 1, l) = rhs_vf(momxb)%sf(j, k + 1, & + & l) + real(0.5_wp*dt*rho_L*vel_L(1)*vel_L(2)*(1._wp/dy(k + 1)) & + & - 0.5_wp*dt*cfl*(rho_L*vel_L(1))*(1._wp/dy(k + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(E_idx)%sf(j, k + 1, l) = rhs_vf(E_idx)%sf(j, k + 1, l) + & - real(0.5_wp*dt*(vel_L(2)*(E_L + & - pres_L + F_L))*(1._wp/dy(k + 1)) - & - 0.5_wp*dt*cfl*(E_L)*(1._wp/dy(k + 1)), kind=stp) + rhs_vf(E_idx)%sf(j, k + 1, l) = rhs_vf(E_idx)%sf(j, k + 1, & + & l) + real(0.5_wp*dt*(vel_L(2)*(E_L + pres_L + F_L))*(1._wp/dy(k + 1)) & + & - 0.5_wp*dt*cfl*(E_L)*(1._wp/dy(k + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb + 1)%sf(j, k, l) = rhs_vf(momxb + 1)%sf(j, k, l) - & - real(0.5_wp*dt*(rho_L*(vel_L(2))**2.0 + & - pres_L + F_L)*(1._wp/dy(k)) - & - 0.5_wp*dt*cfl*(rho_L*vel_L(2))*(1._wp/dy(k)), kind=stp) + rhs_vf(momxb + 1)%sf(j, k, l) = rhs_vf(momxb + 1)%sf(j, k, & + & l) - real(0.5_wp*dt*(rho_L*(vel_L(2))**2.0 + pres_L + F_L)*(1._wp/dy(k)) & + & - 0.5_wp*dt*cfl*(rho_L*vel_L(2))*(1._wp/dy(k)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb)%sf(j, k, l) = rhs_vf(momxb)%sf(j, k, l) - & - real(0.5_wp*dt*rho_L*vel_L(1)*vel_L(2)*(1._wp/dy(k)) - & - 0.5_wp*dt*cfl*(rho_L*vel_L(1))*(1._wp/dy(k)), kind=stp) + rhs_vf(momxb)%sf(j, k, l) = rhs_vf(momxb)%sf(j, k, & + & l) - real(0.5_wp*dt*rho_L*vel_L(1)*vel_L(2)*(1._wp/dy(k)) - 0.5_wp*dt*cfl*(rho_L*vel_L(1) & + & )*(1._wp/dy(k)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(E_idx)%sf(j, k, l) = rhs_vf(E_idx)%sf(j, k, l) - & - real(0.5_wp*dt*(vel_L(2)*(E_L + & - pres_L + F_L))*(1._wp/dy(k)) - & - 0.5_wp*dt*cfl*(E_L)*(1._wp/dy(k)), kind=stp) + rhs_vf(E_idx)%sf(j, k, l) = rhs_vf(E_idx)%sf(j, k, & + & l) - real(0.5_wp*dt*(vel_L(2)*(E_L + pres_L + F_L))*(1._wp/dy(k)) - 0.5_wp*dt*cfl*(E_L) & + & *(1._wp/dy(k)), kind=stp) $:GPU_LOOP(parallelism='[seq]') do i = 1, num_fluids $:GPU_ATOMIC(atomic='update') - rhs_vf(i)%sf(j, k + 1, l) = rhs_vf(i)%sf(j, k + 1, l) + & - real(0.5_wp*dt*(alpha_rho_R(i)* & - vel_R(2))*(1._wp/dy(k + 1)) + & - 0.5_wp*dt*cfl*(alpha_rho_R(i))*(1._wp/dy(k + 1)), kind=stp) + rhs_vf(i)%sf(j, k + 1, l) = rhs_vf(i)%sf(j, k + 1, & + & l) + real(0.5_wp*dt*(alpha_rho_R(i)*vel_R(2))*(1._wp/dy(k + 1)) & + & + 0.5_wp*dt*cfl*(alpha_rho_R(i))*(1._wp/dy(k + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(i)%sf(j, k, l) = rhs_vf(i)%sf(j, k, l) - & - real(0.5_wp*dt*(alpha_rho_R(i)* & - vel_R(2))*(1._wp/dy(k)) + & - 0.5_wp*dt*cfl*(alpha_rho_R(i))*(1._wp/dy(k)), kind=stp) + rhs_vf(i)%sf(j, k, l) = rhs_vf(i)%sf(j, k, & + & l) - real(0.5_wp*dt*(alpha_rho_R(i)*vel_R(2))*(1._wp/dy(k)) & + & + 0.5_wp*dt*cfl*(alpha_rho_R(i))*(1._wp/dy(k)), kind=stp) end do if (num_fluids > 1) then $:GPU_LOOP(parallelism='[seq]') do i = 1, num_fluids - 1 $:GPU_ATOMIC(atomic='update') - rhs_vf(advxb + i - 1)%sf(j, k + 1, l) = rhs_vf(advxb + i - 1)%sf(j, k + 1, l) + & - real(0.5_wp*dt*(alpha_R(i)* & - vel_R(2))*(1._wp/dy(k + 1)) + & - 0.5_wp*dt*cfl*(alpha_R(i))*(1._wp/dy(k + 1)), kind=stp) + rhs_vf(advxb + i - 1)%sf(j, k + 1, l) = rhs_vf(advxb + i - 1)%sf(j, k + 1, & + & l) + real(0.5_wp*dt*(alpha_R(i)*vel_R(2))*(1._wp/dy(k + 1)) & + & + 0.5_wp*dt*cfl*(alpha_R(i))*(1._wp/dy(k + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(advxb + i - 1)%sf(j, k + 1, l) = rhs_vf(advxb + i - 1)%sf(j, k + 1, l) & - - real(0.5_wp*dt*q_cons_vf(advxb + i - 1)%sf(j, k + 1, l)*vel_R(2)*(1._wp/dy(k + 1)), kind=stp) + rhs_vf(advxb + i - 1)%sf(j, k + 1, l) = rhs_vf(advxb + i - 1)%sf(j, k + 1, & + & l) - real(0.5_wp*dt*q_cons_vf(advxb + i - 1)%sf(j, k + 1, & + & l)*vel_R(2)*(1._wp/dy(k + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(advxb + i - 1)%sf(j, k, l) = rhs_vf(advxb + i - 1)%sf(j, k, l) - & - real(0.5_wp*dt*(alpha_R(i)* & - vel_R(2))*(1._wp/dy(k)) + & - 0.5_wp*dt*cfl*(alpha_R(i))*(1._wp/dy(k)), kind=stp) + rhs_vf(advxb + i - 1)%sf(j, k, l) = rhs_vf(advxb + i - 1)%sf(j, k, & + & l) - real(0.5_wp*dt*(alpha_R(i)*vel_R(2))*(1._wp/dy(k)) & + & + 0.5_wp*dt*cfl*(alpha_R(i))*(1._wp/dy(k)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(advxb + i - 1)%sf(j, k, l) = rhs_vf(advxb + i - 1)%sf(j, k, l) & - + real(0.5_wp*dt*q_cons_vf(advxb + i - 1)%sf(j, k, l)*vel_R(2)*(1._wp/dy(k)), kind=stp) + rhs_vf(advxb + i - 1)%sf(j, k, l) = rhs_vf(advxb + i - 1)%sf(j, k, & + & l) + real(0.5_wp*dt*q_cons_vf(advxb + i - 1)%sf(j, k, l)*vel_R(2)*(1._wp/dy(k)), & + & kind=stp) end do end if $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb + 1)%sf(j, k + 1, l) = rhs_vf(momxb + 1)%sf(j, k + 1, l) + & - real(0.5_wp*dt*(rho_R*(vel_R(2))**2.0 + & - pres_R + F_R)*(1._wp/dy(k + 1)) + & - 0.5_wp*dt*cfl*(rho_R*vel_R(2))*(1._wp/dy(k + 1)), kind=stp) - $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb)%sf(j, k + 1, l) = rhs_vf(momxb)%sf(j, k + 1, l) + & - real(0.5_wp*dt*rho_R*vel_R(2)*vel_R(1)*(1._wp/dy(k + 1)) + & - 0.5_wp*dt*cfl*(rho_R*vel_R(1))*(1._wp/dy(k + 1)), kind=stp) - $:GPU_ATOMIC(atomic='update') - rhs_vf(E_idx)%sf(j, k + 1, l) = rhs_vf(E_idx)%sf(j, k + 1, l) + & - real(0.5_wp*dt*(vel_R(2)*(E_R + & - pres_R + F_R))*(1._wp/dy(k + 1)) + & - 0.5_wp*dt*cfl*(E_R)*(1._wp/dy(k + 1)), kind=stp) - $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb + 1)%sf(j, k, l) = rhs_vf(momxb + 1)%sf(j, k, l) - & - real(0.5_wp*dt*(rho_R*(vel_R(2))**2.0 + & - pres_R + F_R)*(1._wp/dy(k)) + & - 0.5_wp*dt*cfl*(rho_R*vel_R(2))*(1._wp/dy(k)), kind=stp) - $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb)%sf(j, k, l) = rhs_vf(momxb)%sf(j, k, l) - & - real(0.5_wp*dt*rho_R*vel_R(2)*vel_R(1)*(1._wp/dy(k)) + & - 0.5_wp*dt*cfl*(rho_R*vel_R(1))*(1._wp/dy(k)), kind=stp) - $:GPU_ATOMIC(atomic='update') - rhs_vf(E_idx)%sf(j, k, l) = rhs_vf(E_idx)%sf(j, k, l) - & - real(0.5_wp*dt*(vel_R(2)*(E_R + & - pres_R + F_R))*(1._wp/dy(k)) + & - 0.5_wp*dt*cfl*(E_R)*(1._wp/dy(k)), kind=stp) + rhs_vf(momxb + 1)%sf(j, k + 1, l) = rhs_vf(momxb + 1)%sf(j, k + 1, & + & l) + real(0.5_wp*dt*(rho_R*(vel_R(2))**2.0 + pres_R + F_R)*(1._wp/dy(k + 1)) & + & + 0.5_wp*dt*cfl*(rho_R*vel_R(2))*(1._wp/dy(k + 1)), kind=stp) + $:GPU_ATOMIC(atomic='update') + rhs_vf(momxb)%sf(j, k + 1, l) = rhs_vf(momxb)%sf(j, k + 1, & + & l) + real(0.5_wp*dt*rho_R*vel_R(2)*vel_R(1)*(1._wp/dy(k + 1)) & + & + 0.5_wp*dt*cfl*(rho_R*vel_R(1))*(1._wp/dy(k + 1)), kind=stp) + $:GPU_ATOMIC(atomic='update') + rhs_vf(E_idx)%sf(j, k + 1, l) = rhs_vf(E_idx)%sf(j, k + 1, & + & l) + real(0.5_wp*dt*(vel_R(2)*(E_R + pres_R + F_R))*(1._wp/dy(k + 1)) & + & + 0.5_wp*dt*cfl*(E_R)*(1._wp/dy(k + 1)), kind=stp) + $:GPU_ATOMIC(atomic='update') + rhs_vf(momxb + 1)%sf(j, k, l) = rhs_vf(momxb + 1)%sf(j, k, & + & l) - real(0.5_wp*dt*(rho_R*(vel_R(2))**2.0 + pres_R + F_R)*(1._wp/dy(k)) & + & + 0.5_wp*dt*cfl*(rho_R*vel_R(2))*(1._wp/dy(k)), kind=stp) + $:GPU_ATOMIC(atomic='update') + rhs_vf(momxb)%sf(j, k, l) = rhs_vf(momxb)%sf(j, k, & + & l) - real(0.5_wp*dt*rho_R*vel_R(2)*vel_R(1)*(1._wp/dy(k)) + 0.5_wp*dt*cfl*(rho_R*vel_R(1) & + & )*(1._wp/dy(k)), kind=stp) + $:GPU_ATOMIC(atomic='update') + rhs_vf(E_idx)%sf(j, k, l) = rhs_vf(E_idx)%sf(j, k, & + & l) - real(0.5_wp*dt*(vel_R(2)*(E_R + pres_R + F_R))*(1._wp/dy(k)) + 0.5_wp*dt*cfl*(E_R) & + & *(1._wp/dy(k)), kind=stp) end do end do end do @@ -1824,26 +1683,26 @@ contains #:endif else #:if not MFC_CASE_OPTIMIZATION or num_dims > 2 - $:GPU_PARALLEL_LOOP(collapse=3, private='[j,k,l,rho_L, rho_R, gamma_L, gamma_R, pi_inf_L, pi_inf_R, mu_L, mu_R, vel_L, vel_R, pres_L, pres_R, alpha_L, alpha_R, alpha_rho_L, alpha_rho_R, F_L, F_R, E_L, E_R, cfl, dvel_small, rho_sf_small, vflux_L_arr, vflux_R_arr]') + $:GPU_PARALLEL_LOOP(collapse=3, private='[j, k, l, rho_L, rho_R, gamma_L, gamma_R, pi_inf_L, pi_inf_R, mu_L, & + & mu_R, vel_L, vel_R, pres_L, pres_R, alpha_L, alpha_R, alpha_rho_L, alpha_rho_R, F_L, & + & F_R, E_L, E_R, cfl, dvel_small, rho_sf_small, vflux_L_arr, vflux_R_arr]') do l = 0, p do k = -1, n do j = 0, m - if (viscous) then vflux_L_arr = 0._wp vflux_R_arr = 0._wp #:if MFC_CASE_OPTIMIZATION #:if igr_order == 5 - !DIR$ unroll 6 + ! DIR$ unroll 6 #:elif igr_order == 3 - !DIR$ unroll 4 + ! DIR$ unroll 4 #:endif #:endif $:GPU_LOOP(parallelism='[seq]') do q = vidxb, vidxe - - !x-direction contributions + ! x-direction contributions $:GPU_LOOP(parallelism='[seq]') do i = -1, 1 rho_L = 0._wp @@ -1854,12 +1713,10 @@ contains rho_sf_small(i) = rho_L end do - dvel_small(1) = (1/(2._wp*dx(j)))*( & - q_cons_vf(momxb)%sf(j + 1, k + q, l)/rho_sf_small(1) - & - q_cons_vf(momxb)%sf(j - 1, k + q, l)/rho_sf_small(-1)) - dvel_small(2) = (1/(2._wp*dx(j)))*( & - q_cons_vf(momxb + 1)%sf(j + 1, k + q, l)/rho_sf_small(1) - & - q_cons_vf(momxb + 1)%sf(j - 1, k + q, l)/rho_sf_small(-1)) + dvel_small(1) = (1/(2._wp*dx(j)))*(q_cons_vf(momxb)%sf(j + 1, k + q, & + & l)/rho_sf_small(1) - q_cons_vf(momxb)%sf(j - 1, k + q, l)/rho_sf_small(-1)) + dvel_small(2) = (1/(2._wp*dx(j)))*(q_cons_vf(momxb + 1)%sf(j + 1, k + q, & + & l)/rho_sf_small(1) - q_cons_vf(momxb + 1)%sf(j - 1, k + q, l)/rho_sf_small(-1)) if (q > vidxb) then vflux_L_arr(1) = vflux_L_arr(1) + coeff_L(q)*(dvel_small(2)) @@ -1870,7 +1727,7 @@ contains vflux_R_arr(3) = vflux_R_arr(3) + coeff_R(q)*(-2._wp*dvel_small(1))/3._wp end if - !y-direction contributions + ! y-direction contributions $:GPU_LOOP(parallelism='[seq]') do i = -1, 1 rho_L = 0._wp @@ -1881,15 +1738,12 @@ contains rho_sf_small(i) = rho_L end do - dvel_small(1) = (1/(2._wp*dy(k)))*( & - q_cons_vf(momxb)%sf(j, k + 1 + q, l)/rho_sf_small(1) - & - q_cons_vf(momxb)%sf(j, k - 1 + q, l)/rho_sf_small(-1)) - dvel_small(2) = (1/(2._wp*dy(k)))*( & - q_cons_vf(momxb + 1)%sf(j, k + 1 + q, l)/rho_sf_small(1) - & - q_cons_vf(momxb + 1)%sf(j, k - 1 + q, l)/rho_sf_small(-1)) - dvel_small(3) = (1/(2._wp*dy(k)))*( & - q_cons_vf(momxb + 2)%sf(j, k + 1 + q, l)/rho_sf_small(1) - & - q_cons_vf(momxb + 2)%sf(j, k - 1 + q, l)/rho_sf_small(-1)) + dvel_small(1) = (1/(2._wp*dy(k)))*(q_cons_vf(momxb)%sf(j, k + 1 + q, & + & l)/rho_sf_small(1) - q_cons_vf(momxb)%sf(j, k - 1 + q, l)/rho_sf_small(-1)) + dvel_small(2) = (1/(2._wp*dy(k)))*(q_cons_vf(momxb + 1)%sf(j, k + 1 + q, & + & l)/rho_sf_small(1) - q_cons_vf(momxb + 1)%sf(j, k - 1 + q, l)/rho_sf_small(-1)) + dvel_small(3) = (1/(2._wp*dy(k)))*(q_cons_vf(momxb + 2)%sf(j, k + 1 + q, & + & l)/rho_sf_small(1) - q_cons_vf(momxb + 2)%sf(j, k - 1 + q, l)/rho_sf_small(-1)) if (q > vidxb) then vflux_L_arr(1) = vflux_L_arr(1) + coeff_L(q)*(dvel_small(1)) @@ -1902,7 +1756,7 @@ contains vflux_R_arr(3) = vflux_R_arr(3) + coeff_R(q)*(4._wp*dvel_small(2))/3._wp end if - !z-direction contributions + ! z-direction contributions $:GPU_LOOP(parallelism='[seq]') do i = -1, 1 rho_L = 0._wp @@ -1913,12 +1767,12 @@ contains rho_sf_small(i) = rho_L end do - dvel_small(2) = (1/(2._wp*dz(l)))*( & - q_cons_vf(momxb + 1)%sf(j, k + q, l + 1)/rho_sf_small(1) - & - q_cons_vf(momxb + 1)%sf(j, k + q, l - 1)/rho_sf_small(-1)) - dvel_small(3) = (1/(2._wp*dz(l)))*( & - q_cons_vf(momxb + 2)%sf(j, k + q, l + 1)/rho_sf_small(1) - & - q_cons_vf(momxb + 2)%sf(j, k + q, l - 1)/rho_sf_small(-1)) + dvel_small(2) = (1/(2._wp*dz(l)))*(q_cons_vf(momxb + 1)%sf(j, k + q, & + & l + 1)/rho_sf_small(1) - q_cons_vf(momxb + 1)%sf(j, k + q, & + & l - 1)/rho_sf_small(-1)) + dvel_small(3) = (1/(2._wp*dz(l)))*(q_cons_vf(momxb + 2)%sf(j, k + q, & + & l + 1)/rho_sf_small(1) - q_cons_vf(momxb + 2)%sf(j, k + q, & + & l - 1)/rho_sf_small(-1)) if (q > vidxb) then vflux_L_arr(2) = vflux_L_arr(2) + coeff_L(q)*(dvel_small(2)) vflux_L_arr(3) = vflux_L_arr(3) + coeff_L(q)*(-2._wp*dvel_small(3))/3._wp @@ -1988,7 +1842,6 @@ contains end do if (num_fluids > 1) then - alpha_L(num_fluids) = 1._wp alpha_R(num_fluids) = 1._wp @@ -2030,88 +1883,88 @@ contains end do $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb)%sf(j, k + 1, l) = rhs_vf(momxb)%sf(j, k + 1, l) - & - real(0.5_wp*dt*mu_L*vflux_L_arr(1)*(1._wp/dy(k + 1)), kind=stp) + rhs_vf(momxb)%sf(j, k + 1, l) = rhs_vf(momxb)%sf(j, k + 1, & + & l) - real(0.5_wp*dt*mu_L*vflux_L_arr(1)*(1._wp/dy(k + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(E_idx)%sf(j, k + 1, l) = rhs_vf(E_idx)%sf(j, k + 1, l) - & - real(0.5_wp*dt*mu_L*vflux_L_arr(1)*vel_L(1)*(1._wp/dy(k + 1)), kind=stp) + rhs_vf(E_idx)%sf(j, k + 1, l) = rhs_vf(E_idx)%sf(j, k + 1, & + & l) - real(0.5_wp*dt*mu_L*vflux_L_arr(1)*vel_L(1)*(1._wp/dy(k + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb)%sf(j, k, l) = rhs_vf(momxb)%sf(j, k, l) + & - real(0.5_wp*dt*mu_L*vflux_L_arr(1)*(1._wp/dy(k)), kind=stp) + rhs_vf(momxb)%sf(j, k, l) = rhs_vf(momxb)%sf(j, k, & + & l) + real(0.5_wp*dt*mu_L*vflux_L_arr(1)*(1._wp/dy(k)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(E_idx)%sf(j, k, l) = rhs_vf(E_idx)%sf(j, k, l) + & - real(0.5_wp*dt*mu_L*vflux_L_arr(1)*vel_L(1)*(1._wp/dy(k)), kind=stp) + rhs_vf(E_idx)%sf(j, k, l) = rhs_vf(E_idx)%sf(j, k, & + & l) + real(0.5_wp*dt*mu_L*vflux_L_arr(1)*vel_L(1)*(1._wp/dy(k)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb)%sf(j, k + 1, l) = rhs_vf(momxb)%sf(j, k + 1, l) - & - real(0.5_wp*dt*mu_R*vflux_R_arr(1)*(1._wp/dy(k + 1)), kind=stp) + rhs_vf(momxb)%sf(j, k + 1, l) = rhs_vf(momxb)%sf(j, k + 1, & + & l) - real(0.5_wp*dt*mu_R*vflux_R_arr(1)*(1._wp/dy(k + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(E_idx)%sf(j, k + 1, l) = rhs_vf(E_idx)%sf(j, k + 1, l) - & - real(0.5_wp*dt*mu_R*vflux_R_arr(1)*vel_R(1)*(1._wp/dy(k + 1)), kind=stp) + rhs_vf(E_idx)%sf(j, k + 1, l) = rhs_vf(E_idx)%sf(j, k + 1, & + & l) - real(0.5_wp*dt*mu_R*vflux_R_arr(1)*vel_R(1)*(1._wp/dy(k + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb)%sf(j, k, l) = rhs_vf(momxb)%sf(j, k, l) + & - real(0.5_wp*dt*mu_R*vflux_R_arr(1)*(1._wp/dy(k)), kind=stp) + rhs_vf(momxb)%sf(j, k, l) = rhs_vf(momxb)%sf(j, k, & + & l) + real(0.5_wp*dt*mu_R*vflux_R_arr(1)*(1._wp/dy(k)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(E_idx)%sf(j, k, l) = rhs_vf(E_idx)%sf(j, k, l) + & - real(0.5_wp*dt*mu_R*vflux_R_arr(1)*vel_R(1)*(1._wp/dy(k)), kind=stp) + rhs_vf(E_idx)%sf(j, k, l) = rhs_vf(E_idx)%sf(j, k, & + & l) + real(0.5_wp*dt*mu_R*vflux_R_arr(1)*vel_R(1)*(1._wp/dy(k)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb + 2)%sf(j, k + 1, l) = rhs_vf(momxb + 2)%sf(j, k + 1, l) - & - real(0.5_wp*dt*mu_L*vflux_L_arr(2)*(1._wp/dy(k + 1)), kind=stp) + rhs_vf(momxb + 2)%sf(j, k + 1, l) = rhs_vf(momxb + 2)%sf(j, k + 1, & + & l) - real(0.5_wp*dt*mu_L*vflux_L_arr(2)*(1._wp/dy(k + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(E_idx)%sf(j, k + 1, l) = rhs_vf(E_idx)%sf(j, k + 1, l) - & - real(0.5_wp*dt*mu_L*vflux_L_arr(2)*vel_L(3)*(1._wp/dy(k + 1)), kind=stp) + rhs_vf(E_idx)%sf(j, k + 1, l) = rhs_vf(E_idx)%sf(j, k + 1, & + & l) - real(0.5_wp*dt*mu_L*vflux_L_arr(2)*vel_L(3)*(1._wp/dy(k + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb + 2)%sf(j, k, l) = rhs_vf(momxb + 2)%sf(j, k, l) + & - real(0.5_wp*dt*mu_L*vflux_L_arr(2)*(1._wp/dy(k)), kind=stp) + rhs_vf(momxb + 2)%sf(j, k, l) = rhs_vf(momxb + 2)%sf(j, k, & + & l) + real(0.5_wp*dt*mu_L*vflux_L_arr(2)*(1._wp/dy(k)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(E_idx)%sf(j, k, l) = rhs_vf(E_idx)%sf(j, k, l) + & - real(0.5_wp*dt*mu_L*vflux_L_arr(2)*vel_L(3)*(1._wp/dy(k)), kind=stp) + rhs_vf(E_idx)%sf(j, k, l) = rhs_vf(E_idx)%sf(j, k, & + & l) + real(0.5_wp*dt*mu_L*vflux_L_arr(2)*vel_L(3)*(1._wp/dy(k)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb + 2)%sf(j, k + 1, l) = rhs_vf(momxb + 2)%sf(j, k + 1, l) - & - real(0.5_wp*dt*mu_R*vflux_R_arr(2)*(1._wp/dy(k + 1)), kind=stp) + rhs_vf(momxb + 2)%sf(j, k + 1, l) = rhs_vf(momxb + 2)%sf(j, k + 1, & + & l) - real(0.5_wp*dt*mu_R*vflux_R_arr(2)*(1._wp/dy(k + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(E_idx)%sf(j, k + 1, l) = rhs_vf(E_idx)%sf(j, k + 1, l) - & - real(0.5_wp*dt*mu_R*vflux_R_arr(2)*vel_R(3)*(1._wp/dy(k + 1)), kind=stp) + rhs_vf(E_idx)%sf(j, k + 1, l) = rhs_vf(E_idx)%sf(j, k + 1, & + & l) - real(0.5_wp*dt*mu_R*vflux_R_arr(2)*vel_R(3)*(1._wp/dy(k + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb + 2)%sf(j, k, l) = rhs_vf(momxb + 2)%sf(j, k, l) + & - real(0.5_wp*dt*mu_R*vflux_R_arr(2)*(1._wp/dy(k)), kind=stp) + rhs_vf(momxb + 2)%sf(j, k, l) = rhs_vf(momxb + 2)%sf(j, k, & + & l) + real(0.5_wp*dt*mu_R*vflux_R_arr(2)*(1._wp/dy(k)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(E_idx)%sf(j, k, l) = rhs_vf(E_idx)%sf(j, k, l) + & - real(0.5_wp*dt*mu_R*vflux_R_arr(2)*vel_R(3)*(1._wp/dy(k)), kind=stp) + rhs_vf(E_idx)%sf(j, k, l) = rhs_vf(E_idx)%sf(j, k, & + & l) + real(0.5_wp*dt*mu_R*vflux_R_arr(2)*vel_R(3)*(1._wp/dy(k)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb + 1)%sf(j, k + 1, l) = rhs_vf(momxb + 1)%sf(j, k + 1, l) - & - real(0.5_wp*dt*mu_L*vflux_L_arr(3)*(1._wp/dy(k + 1)), kind=stp) + rhs_vf(momxb + 1)%sf(j, k + 1, l) = rhs_vf(momxb + 1)%sf(j, k + 1, & + & l) - real(0.5_wp*dt*mu_L*vflux_L_arr(3)*(1._wp/dy(k + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(E_idx)%sf(j, k + 1, l) = rhs_vf(E_idx)%sf(j, k + 1, l) - & - real(0.5_wp*dt*mu_L*vflux_L_arr(3)*vel_L(2)*(1._wp/dy(k + 1)), kind=stp) + rhs_vf(E_idx)%sf(j, k + 1, l) = rhs_vf(E_idx)%sf(j, k + 1, & + & l) - real(0.5_wp*dt*mu_L*vflux_L_arr(3)*vel_L(2)*(1._wp/dy(k + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb + 1)%sf(j, k, l) = rhs_vf(momxb + 1)%sf(j, k, l) + & - real(0.5_wp*dt*mu_L*vflux_L_arr(3)*(1._wp/dy(k)), kind=stp) + rhs_vf(momxb + 1)%sf(j, k, l) = rhs_vf(momxb + 1)%sf(j, k, & + & l) + real(0.5_wp*dt*mu_L*vflux_L_arr(3)*(1._wp/dy(k)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(E_idx)%sf(j, k, l) = rhs_vf(E_idx)%sf(j, k, l) + & - real(0.5_wp*dt*mu_L*vflux_L_arr(3)*vel_L(2)*(1._wp/dy(k)), kind=stp) + rhs_vf(E_idx)%sf(j, k, l) = rhs_vf(E_idx)%sf(j, k, & + & l) + real(0.5_wp*dt*mu_L*vflux_L_arr(3)*vel_L(2)*(1._wp/dy(k)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb + 1)%sf(j, k + 1, l) = rhs_vf(momxb + 1)%sf(j, k + 1, l) - & - real(0.5_wp*dt*mu_R*vflux_R_arr(3)*(1._wp/dy(k + 1)), kind=stp) + rhs_vf(momxb + 1)%sf(j, k + 1, l) = rhs_vf(momxb + 1)%sf(j, k + 1, & + & l) - real(0.5_wp*dt*mu_R*vflux_R_arr(3)*(1._wp/dy(k + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(E_idx)%sf(j, k + 1, l) = rhs_vf(E_idx)%sf(j, k + 1, l) - & - real(0.5_wp*dt*mu_R*vflux_R_arr(3)*vel_R(2)*(1._wp/dy(k + 1)), kind=stp) + rhs_vf(E_idx)%sf(j, k + 1, l) = rhs_vf(E_idx)%sf(j, k + 1, & + & l) - real(0.5_wp*dt*mu_R*vflux_R_arr(3)*vel_R(2)*(1._wp/dy(k + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb + 1)%sf(j, k, l) = rhs_vf(momxb + 1)%sf(j, k, l) + & - real(0.5_wp*dt*mu_R*vflux_R_arr(3)*(1._wp/dy(k)), kind=stp) + rhs_vf(momxb + 1)%sf(j, k, l) = rhs_vf(momxb + 1)%sf(j, k, & + & l) + real(0.5_wp*dt*mu_R*vflux_R_arr(3)*(1._wp/dy(k)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(E_idx)%sf(j, k, l) = rhs_vf(E_idx)%sf(j, k, l) + & - real(0.5_wp*dt*mu_R*vflux_R_arr(3)*vel_R(2)*(1._wp/dy(k)), kind=stp) + rhs_vf(E_idx)%sf(j, k, l) = rhs_vf(E_idx)%sf(j, k, & + & l) + real(0.5_wp*dt*mu_R*vflux_R_arr(3)*vel_R(2)*(1._wp/dy(k)), kind=stp) end if E_L = 0._wp; E_R = 0._wp @@ -2129,206 +1982,192 @@ contains F_R = F_R + coeff_R(q)*jac(j, k + q, l) end do - call s_get_derived_states(E_L, gamma_L, pi_inf_L, rho_L, vel_L, & - E_R, gamma_R, pi_inf_R, rho_R, vel_R, & - pres_L, pres_R, cfl) + call s_get_derived_states(E_L, gamma_L, pi_inf_L, rho_L, vel_L, E_R, gamma_R, pi_inf_R, rho_R, & + & vel_R, pres_L, pres_R, cfl) $:GPU_LOOP(parallelism='[seq]') do i = 1, num_fluids $:GPU_ATOMIC(atomic='update') - rhs_vf(i)%sf(j, k + 1, l) = rhs_vf(i)%sf(j, k + 1, l) + & - real(0.5_wp*dt*(alpha_rho_L(i)* & - vel_L(2))*(1._wp/dy(k + 1)) - & - 0.5_wp*dt*cfl*(alpha_rho_L(i))*(1._wp/dy(k + 1)), kind=stp) + rhs_vf(i)%sf(j, k + 1, l) = rhs_vf(i)%sf(j, k + 1, & + & l) + real(0.5_wp*dt*(alpha_rho_L(i)*vel_L(2))*(1._wp/dy(k + 1)) & + & - 0.5_wp*dt*cfl*(alpha_rho_L(i))*(1._wp/dy(k + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(i)%sf(j, k, l) = rhs_vf(i)%sf(j, k, l) - & - real(0.5_wp*dt*(alpha_rho_L(i)* & - vel_L(2))*(1._wp/dy(k)) - & - 0.5_wp*dt*cfl*(alpha_rho_L(i))*(1._wp/dy(k)), kind=stp) + rhs_vf(i)%sf(j, k, l) = rhs_vf(i)%sf(j, k, & + & l) - real(0.5_wp*dt*(alpha_rho_L(i)*vel_L(2))*(1._wp/dy(k)) & + & - 0.5_wp*dt*cfl*(alpha_rho_L(i))*(1._wp/dy(k)), kind=stp) end do if (num_fluids > 1) then $:GPU_LOOP(parallelism='[seq]') do i = 1, num_fluids - 1 $:GPU_ATOMIC(atomic='update') - rhs_vf(advxb + i - 1)%sf(j, k + 1, l) = rhs_vf(advxb + i - 1)%sf(j, k + 1, l) + & - real(0.5_wp*dt*(alpha_L(i)* & - vel_L(2))*(1._wp/dy(k + 1)) - & - 0.5_wp*dt*cfl*(alpha_L(i))*(1._wp/dy(k + 1)), kind=stp) + rhs_vf(advxb + i - 1)%sf(j, k + 1, l) = rhs_vf(advxb + i - 1)%sf(j, k + 1, & + & l) + real(0.5_wp*dt*(alpha_L(i)*vel_L(2))*(1._wp/dy(k + 1)) & + & - 0.5_wp*dt*cfl*(alpha_L(i))*(1._wp/dy(k + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(advxb + i - 1)%sf(j, k + 1, l) = rhs_vf(advxb + i - 1)%sf(j, k + 1, l) & - - real(0.5_wp*dt*q_cons_vf(advxb + i - 1)%sf(j, k + 1, l)*vel_L(2)*(1._wp/dy(k + 1)), kind=stp) + rhs_vf(advxb + i - 1)%sf(j, k + 1, l) = rhs_vf(advxb + i - 1)%sf(j, k + 1, & + & l) - real(0.5_wp*dt*q_cons_vf(advxb + i - 1)%sf(j, k + 1, & + & l)*vel_L(2)*(1._wp/dy(k + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(advxb + i - 1)%sf(j, k, l) = rhs_vf(advxb + i - 1)%sf(j, k, l) - & - real(0.5_wp*dt*(alpha_L(i)* & - vel_L(2))*(1._wp/dy(k)) - & - 0.5_wp*dt*cfl*(alpha_L(i))*(1._wp/dy(k)), kind=stp) + rhs_vf(advxb + i - 1)%sf(j, k, l) = rhs_vf(advxb + i - 1)%sf(j, k, & + & l) - real(0.5_wp*dt*(alpha_L(i)*vel_L(2))*(1._wp/dy(k)) & + & - 0.5_wp*dt*cfl*(alpha_L(i))*(1._wp/dy(k)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(advxb + i - 1)%sf(j, k, l) = rhs_vf(advxb + i - 1)%sf(j, k, l) & - + real(0.5_wp*dt*q_cons_vf(advxb + i - 1)%sf(j, k, l)*vel_L(2)*(1._wp/dy(k)), kind=stp) + rhs_vf(advxb + i - 1)%sf(j, k, l) = rhs_vf(advxb + i - 1)%sf(j, k, & + & l) + real(0.5_wp*dt*q_cons_vf(advxb + i - 1)%sf(j, k, l)*vel_L(2)*(1._wp/dy(k)), & + & kind=stp) end do end if $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb + 1)%sf(j, k + 1, l) = rhs_vf(momxb + 1)%sf(j, k + 1, l) + & - real(0.5_wp*dt*(rho_L*(vel_L(2))**2.0 + & - pres_L + F_L)*(1._wp/dy(k + 1)) - & - 0.5_wp*dt*cfl*(rho_L*vel_L(2))*(1._wp/dy(k + 1)), kind=stp) + rhs_vf(momxb + 1)%sf(j, k + 1, l) = rhs_vf(momxb + 1)%sf(j, k + 1, & + & l) + real(0.5_wp*dt*(rho_L*(vel_L(2))**2.0 + pres_L + F_L)*(1._wp/dy(k + 1)) & + & - 0.5_wp*dt*cfl*(rho_L*vel_L(2))*(1._wp/dy(k + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb)%sf(j, k + 1, l) = rhs_vf(momxb)%sf(j, k + 1, l) + & - real(0.5_wp*dt*rho_L*vel_L(1)*vel_L(2)*(1._wp/dy(k + 1)) - & - 0.5_wp*dt*cfl*(rho_L*vel_L(1))*(1._wp/dy(k + 1)), kind=stp) + rhs_vf(momxb)%sf(j, k + 1, l) = rhs_vf(momxb)%sf(j, k + 1, & + & l) + real(0.5_wp*dt*rho_L*vel_L(1)*vel_L(2)*(1._wp/dy(k + 1)) & + & - 0.5_wp*dt*cfl*(rho_L*vel_L(1))*(1._wp/dy(k + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb + 2)%sf(j, k + 1, l) = rhs_vf(momxb + 2)%sf(j, k + 1, l) + & - real(0.5_wp*dt*rho_L*vel_L(3)*vel_L(2)*(1._wp/dy(k + 1)) - & - 0.5_wp*dt*cfl*(rho_L*vel_L(3))*(1._wp/dy(k + 1)), kind=stp) + rhs_vf(momxb + 2)%sf(j, k + 1, l) = rhs_vf(momxb + 2)%sf(j, k + 1, & + & l) + real(0.5_wp*dt*rho_L*vel_L(3)*vel_L(2)*(1._wp/dy(k + 1)) & + & - 0.5_wp*dt*cfl*(rho_L*vel_L(3))*(1._wp/dy(k + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(E_idx)%sf(j, k + 1, l) = rhs_vf(E_idx)%sf(j, k + 1, l) + & - real(0.5_wp*dt*(vel_L(2)*(E_L + & - pres_L + F_L))*(1._wp/dy(k + 1)) - & - 0.5_wp*dt*cfl*(E_L)*(1._wp/dy(k + 1)), kind=stp) + rhs_vf(E_idx)%sf(j, k + 1, l) = rhs_vf(E_idx)%sf(j, k + 1, & + & l) + real(0.5_wp*dt*(vel_L(2)*(E_L + pres_L + F_L))*(1._wp/dy(k + 1)) & + & - 0.5_wp*dt*cfl*(E_L)*(1._wp/dy(k + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb + 1)%sf(j, k, l) = rhs_vf(momxb + 1)%sf(j, k, l) - & - real(0.5_wp*dt*(rho_L*(vel_L(2))**2.0 + & - pres_L + F_L)*(1._wp/dy(k)) - & - 0.5_wp*dt*cfl*(rho_L*vel_L(2))*(1._wp/dy(k)), kind=stp) + rhs_vf(momxb + 1)%sf(j, k, l) = rhs_vf(momxb + 1)%sf(j, k, & + & l) - real(0.5_wp*dt*(rho_L*(vel_L(2))**2.0 + pres_L + F_L)*(1._wp/dy(k)) & + & - 0.5_wp*dt*cfl*(rho_L*vel_L(2))*(1._wp/dy(k)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb)%sf(j, k, l) = rhs_vf(momxb)%sf(j, k, l) - & - real(0.5_wp*dt*rho_L*vel_L(1)*vel_L(2)*(1._wp/dy(k)) - & - 0.5_wp*dt*cfl*(rho_L*vel_L(1))*(1._wp/dy(k)), kind=stp) + rhs_vf(momxb)%sf(j, k, l) = rhs_vf(momxb)%sf(j, k, & + & l) - real(0.5_wp*dt*rho_L*vel_L(1)*vel_L(2)*(1._wp/dy(k)) - 0.5_wp*dt*cfl*(rho_L*vel_L(1) & + & )*(1._wp/dy(k)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb + 2)%sf(j, k, l) = rhs_vf(momxb + 2)%sf(j, k, l) - & - real(0.5_wp*dt*rho_L*vel_L(3)*vel_L(2)*(1._wp/dy(k)) - & - 0.5_wp*dt*cfl*(rho_L*vel_L(3))*(1._wp/dy(k)), kind=stp) + rhs_vf(momxb + 2)%sf(j, k, l) = rhs_vf(momxb + 2)%sf(j, k, & + & l) - real(0.5_wp*dt*rho_L*vel_L(3)*vel_L(2)*(1._wp/dy(k)) - 0.5_wp*dt*cfl*(rho_L*vel_L(3) & + & )*(1._wp/dy(k)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(E_idx)%sf(j, k, l) = rhs_vf(E_idx)%sf(j, k, l) - & - real(0.5_wp*dt*(vel_L(2)*(E_L + & - pres_L + F_L))*(1._wp/dy(k)) - & - 0.5_wp*dt*cfl*(E_L)*(1._wp/dy(k)), kind=stp) + rhs_vf(E_idx)%sf(j, k, l) = rhs_vf(E_idx)%sf(j, k, & + & l) - real(0.5_wp*dt*(vel_L(2)*(E_L + pres_L + F_L))*(1._wp/dy(k)) - 0.5_wp*dt*cfl*(E_L) & + & *(1._wp/dy(k)), kind=stp) $:GPU_LOOP(parallelism='[seq]') do i = 1, num_fluids $:GPU_ATOMIC(atomic='update') - rhs_vf(i)%sf(j, k + 1, l) = rhs_vf(i)%sf(j, k + 1, l) + & - real(0.5_wp*dt*(alpha_rho_R(i)* & - vel_R(2))*(1._wp/dy(k + 1)) + & - 0.5_wp*dt*cfl*(alpha_rho_R(i))*(1._wp/dy(k + 1)), kind=stp) + rhs_vf(i)%sf(j, k + 1, l) = rhs_vf(i)%sf(j, k + 1, & + & l) + real(0.5_wp*dt*(alpha_rho_R(i)*vel_R(2))*(1._wp/dy(k + 1)) & + & + 0.5_wp*dt*cfl*(alpha_rho_R(i))*(1._wp/dy(k + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(i)%sf(j, k, l) = rhs_vf(i)%sf(j, k, l) - & - real(0.5_wp*dt*(alpha_rho_R(i)* & - vel_R(2))*(1._wp/dy(k)) + & - 0.5_wp*dt*cfl*(alpha_rho_R(i))*(1._wp/dy(k)), kind=stp) + rhs_vf(i)%sf(j, k, l) = rhs_vf(i)%sf(j, k, & + & l) - real(0.5_wp*dt*(alpha_rho_R(i)*vel_R(2))*(1._wp/dy(k)) & + & + 0.5_wp*dt*cfl*(alpha_rho_R(i))*(1._wp/dy(k)), kind=stp) end do if (num_fluids > 1) then $:GPU_LOOP(parallelism='[seq]') do i = 1, num_fluids - 1 $:GPU_ATOMIC(atomic='update') - rhs_vf(advxb + i - 1)%sf(j, k + 1, l) = rhs_vf(advxb + i - 1)%sf(j, k + 1, l) + & - real(0.5_wp*dt*(alpha_R(i)* & - vel_R(2))*(1._wp/dy(k + 1)) + & - 0.5_wp*dt*cfl*(alpha_R(i))*(1._wp/dy(k + 1)), kind=stp) + rhs_vf(advxb + i - 1)%sf(j, k + 1, l) = rhs_vf(advxb + i - 1)%sf(j, k + 1, & + & l) + real(0.5_wp*dt*(alpha_R(i)*vel_R(2))*(1._wp/dy(k + 1)) & + & + 0.5_wp*dt*cfl*(alpha_R(i))*(1._wp/dy(k + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(advxb + i - 1)%sf(j, k + 1, l) = rhs_vf(advxb + i - 1)%sf(j, k + 1, l) & - - real(0.5_wp*dt*q_cons_vf(advxb + i - 1)%sf(j, k + 1, l)*vel_R(2)*(1._wp/dy(k + 1)), kind=stp) + rhs_vf(advxb + i - 1)%sf(j, k + 1, l) = rhs_vf(advxb + i - 1)%sf(j, k + 1, & + & l) - real(0.5_wp*dt*q_cons_vf(advxb + i - 1)%sf(j, k + 1, & + & l)*vel_R(2)*(1._wp/dy(k + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(advxb + i - 1)%sf(j, k, l) = rhs_vf(advxb + i - 1)%sf(j, k, l) - & - real(0.5_wp*dt*(alpha_R(i)* & - vel_R(2))*(1._wp/dy(k)) + & - 0.5_wp*dt*cfl*(alpha_R(i))*(1._wp/dy(k)), kind=stp) + rhs_vf(advxb + i - 1)%sf(j, k, l) = rhs_vf(advxb + i - 1)%sf(j, k, & + & l) - real(0.5_wp*dt*(alpha_R(i)*vel_R(2))*(1._wp/dy(k)) & + & + 0.5_wp*dt*cfl*(alpha_R(i))*(1._wp/dy(k)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(advxb + i - 1)%sf(j, k, l) = rhs_vf(advxb + i - 1)%sf(j, k, l) & - + real(0.5_wp*dt*q_cons_vf(advxb + i - 1)%sf(j, k, l)*vel_R(2)*(1._wp/dy(k)), kind=stp) + rhs_vf(advxb + i - 1)%sf(j, k, l) = rhs_vf(advxb + i - 1)%sf(j, k, & + & l) + real(0.5_wp*dt*q_cons_vf(advxb + i - 1)%sf(j, k, l)*vel_R(2)*(1._wp/dy(k)), & + & kind=stp) end do end if $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb + 1)%sf(j, k + 1, l) = rhs_vf(momxb + 1)%sf(j, k + 1, l) + & - real(0.5_wp*dt*(rho_R*(vel_R(2))**2.0 + & - pres_R + F_R)*(1._wp/dy(k + 1)) + & - 0.5_wp*dt*cfl*(rho_R*vel_R(2))*(1._wp/dy(k + 1)), kind=stp) + rhs_vf(momxb + 1)%sf(j, k + 1, l) = rhs_vf(momxb + 1)%sf(j, k + 1, & + & l) + real(0.5_wp*dt*(rho_R*(vel_R(2))**2.0 + pres_R + F_R)*(1._wp/dy(k + 1)) & + & + 0.5_wp*dt*cfl*(rho_R*vel_R(2))*(1._wp/dy(k + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb)%sf(j, k + 1, l) = rhs_vf(momxb)%sf(j, k + 1, l) + & - real(0.5_wp*dt*rho_R*vel_R(2)*vel_R(1)*(1._wp/dy(k + 1)) + & - 0.5_wp*dt*cfl*(rho_R*vel_R(1))*(1._wp/dy(k + 1)), kind=stp) + rhs_vf(momxb)%sf(j, k + 1, l) = rhs_vf(momxb)%sf(j, k + 1, & + & l) + real(0.5_wp*dt*rho_R*vel_R(2)*vel_R(1)*(1._wp/dy(k + 1)) & + & + 0.5_wp*dt*cfl*(rho_R*vel_R(1))*(1._wp/dy(k + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb + 2)%sf(j, k + 1, l) = rhs_vf(momxb + 2)%sf(j, k + 1, l) + & - real(0.5_wp*dt*rho_R*vel_R(2)*vel_R(3)*(1._wp/dy(k + 1)) + & - 0.5_wp*dt*cfl*(rho_R*vel_R(3))*(1._wp/dy(k + 1)), kind=stp) + rhs_vf(momxb + 2)%sf(j, k + 1, l) = rhs_vf(momxb + 2)%sf(j, k + 1, & + & l) + real(0.5_wp*dt*rho_R*vel_R(2)*vel_R(3)*(1._wp/dy(k + 1)) & + & + 0.5_wp*dt*cfl*(rho_R*vel_R(3))*(1._wp/dy(k + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(E_idx)%sf(j, k + 1, l) = rhs_vf(E_idx)%sf(j, k + 1, l) + & - real(0.5_wp*dt*(vel_R(2)*(E_R + & - pres_R + F_R))*(1._wp/dy(k + 1)) + & - 0.5_wp*dt*cfl*(E_R)*(1._wp/dy(k + 1)), kind=stp) + rhs_vf(E_idx)%sf(j, k + 1, l) = rhs_vf(E_idx)%sf(j, k + 1, & + & l) + real(0.5_wp*dt*(vel_R(2)*(E_R + pres_R + F_R))*(1._wp/dy(k + 1)) & + & + 0.5_wp*dt*cfl*(E_R)*(1._wp/dy(k + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb + 1)%sf(j, k, l) = rhs_vf(momxb + 1)%sf(j, k, l) - & - real(0.5_wp*dt*(rho_R*(vel_R(2))**2.0 + & - pres_R + F_R)*(1._wp/dy(k)) + & - 0.5_wp*dt*cfl*(rho_R*vel_R(2))*(1._wp/dy(k)), kind=stp) + rhs_vf(momxb + 1)%sf(j, k, l) = rhs_vf(momxb + 1)%sf(j, k, & + & l) - real(0.5_wp*dt*(rho_R*(vel_R(2))**2.0 + pres_R + F_R)*(1._wp/dy(k)) & + & + 0.5_wp*dt*cfl*(rho_R*vel_R(2))*(1._wp/dy(k)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb)%sf(j, k, l) = rhs_vf(momxb)%sf(j, k, l) - & - real(0.5_wp*dt*rho_R*vel_R(2)*vel_R(1)*(1._wp/dy(k)) + & - 0.5_wp*dt*cfl*(rho_R*vel_R(1))*(1._wp/dy(k)), kind=stp) + rhs_vf(momxb)%sf(j, k, l) = rhs_vf(momxb)%sf(j, k, & + & l) - real(0.5_wp*dt*rho_R*vel_R(2)*vel_R(1)*(1._wp/dy(k)) + 0.5_wp*dt*cfl*(rho_R*vel_R(1) & + & )*(1._wp/dy(k)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb + 2)%sf(j, k, l) = rhs_vf(momxb + 2)%sf(j, k, l) - & - real(0.5_wp*dt*rho_R*vel_R(2)*vel_R(3)*(1._wp/dy(k)) + & - 0.5_wp*dt*cfl*(rho_R*vel_R(3))*(1._wp/dy(k)), kind=stp) + rhs_vf(momxb + 2)%sf(j, k, l) = rhs_vf(momxb + 2)%sf(j, k, & + & l) - real(0.5_wp*dt*rho_R*vel_R(2)*vel_R(3)*(1._wp/dy(k)) + 0.5_wp*dt*cfl*(rho_R*vel_R(3) & + & )*(1._wp/dy(k)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(E_idx)%sf(j, k, l) = rhs_vf(E_idx)%sf(j, k, l) - & - real(0.5_wp*dt*(vel_R(2)*(E_R + & - pres_R + F_R))*(1._wp/dy(k)) + & - 0.5_wp*dt*cfl*(E_R)*(1._wp/dy(k)), kind=stp) - + rhs_vf(E_idx)%sf(j, k, l) = rhs_vf(E_idx)%sf(j, k, & + & l) - real(0.5_wp*dt*(vel_R(2)*(E_R + pres_R + F_R))*(1._wp/dy(k)) + 0.5_wp*dt*cfl*(E_R) & + & *(1._wp/dy(k)), kind=stp) end do end do end do $:END_GPU_PARALLEL_LOOP() #:endif end if - elseif (idir == 3) then + else if (idir == 3) then #:if not MFC_CASE_OPTIMIZATION or num_dims > 2 - $:GPU_PARALLEL_LOOP(collapse=3, private='[j,k,l,rho_L, rho_R, gamma_L, gamma_R, pi_inf_L, pi_inf_R, mu_L, mu_R, vel_L, vel_R, pres_L, pres_R, alpha_L, alpha_R, alpha_rho_L, alpha_rho_R, F_L, F_R, E_L, E_R, cfl, dvel_small, rho_sf_small, vflux_L_arr, vflux_R_arr]') + $:GPU_PARALLEL_LOOP(collapse=3, private='[j, k, l, rho_L, rho_R, gamma_L, gamma_R, pi_inf_L, pi_inf_R, mu_L, & + & mu_R, vel_L, vel_R, pres_L, pres_R, alpha_L, alpha_R, alpha_rho_L, alpha_rho_R, F_L, F_R, & + & E_L, E_R, cfl, dvel_small, rho_sf_small, vflux_L_arr, vflux_R_arr]') do l = -1, p do k = 0, n do j = 0, m - if (viscous) then vflux_L_arr = 0._wp vflux_R_arr = 0._wp #:if MFC_CASE_OPTIMIZATION #:if igr_order == 5 - !DIR$ unroll 6 + ! DIR$ unroll 6 #:elif igr_order == 3 - !DIR$ unroll 4 + ! DIR$ unroll 4 #:endif #:endif $:GPU_LOOP(parallelism='[seq]') do q = vidxb, vidxe - - !x-direction contributions + ! x-direction contributions $:GPU_LOOP(parallelism='[seq]') do i = -1, 1 rho_L = 0._wp @@ -2339,12 +2178,10 @@ contains rho_sf_small(i) = rho_L end do - dvel_small(1) = (1/(2._wp*dx(j)))*( & - q_cons_vf(momxb)%sf(j + 1, k, l + q)/rho_sf_small(1) - & - q_cons_vf(momxb)%sf(j - 1, k, l + q)/rho_sf_small(-1)) - dvel_small(3) = (1/(2._wp*dx(j)))*( & - q_cons_vf(momxb + 2)%sf(j + 1, k, l + q)/rho_sf_small(1) - & - q_cons_vf(momxb + 2)%sf(j - 1, k, l + q)/rho_sf_small(-1)) + dvel_small(1) = (1/(2._wp*dx(j)))*(q_cons_vf(momxb)%sf(j + 1, k, & + & l + q)/rho_sf_small(1) - q_cons_vf(momxb)%sf(j - 1, k, l + q)/rho_sf_small(-1)) + dvel_small(3) = (1/(2._wp*dx(j)))*(q_cons_vf(momxb + 2)%sf(j + 1, k, & + & l + q)/rho_sf_small(1) - q_cons_vf(momxb + 2)%sf(j - 1, k, l + q)/rho_sf_small(-1)) if (q > vidxb) then vflux_L_arr(1) = vflux_L_arr(1) + coeff_L(q)*(dvel_small(3)) @@ -2355,7 +2192,7 @@ contains vflux_R_arr(3) = vflux_R_arr(3) + coeff_R(q)*(-2._wp*dvel_small(1))/3._wp end if - !y-direction contributions + ! y-direction contributions $:GPU_LOOP(parallelism='[seq]') do i = -1, 1 rho_L = 0._wp @@ -2366,12 +2203,10 @@ contains rho_sf_small(i) = rho_L end do - dvel_small(2) = (1/(2._wp*dy(k)))*( & - q_cons_vf(momxb + 1)%sf(j, k + 1, l + q)/rho_sf_small(1) - & - q_cons_vf(momxb + 1)%sf(j, k - 1, l + q)/rho_sf_small(-1)) - dvel_small(3) = (1/(2._wp*dy(k)))*( & - q_cons_vf(momxb + 2)%sf(j, k + 1, l + q)/rho_sf_small(1) - & - q_cons_vf(momxb + 2)%sf(j, k - 1, l + q)/rho_sf_small(-1)) + dvel_small(2) = (1/(2._wp*dy(k)))*(q_cons_vf(momxb + 1)%sf(j, k + 1, & + & l + q)/rho_sf_small(1) - q_cons_vf(momxb + 1)%sf(j, k - 1, l + q)/rho_sf_small(-1)) + dvel_small(3) = (1/(2._wp*dy(k)))*(q_cons_vf(momxb + 2)%sf(j, k + 1, & + & l + q)/rho_sf_small(1) - q_cons_vf(momxb + 2)%sf(j, k - 1, l + q)/rho_sf_small(-1)) if (q > vidxb) then vflux_L_arr(2) = vflux_L_arr(2) + coeff_L(q)*(dvel_small(3)) @@ -2382,7 +2217,7 @@ contains vflux_R_arr(3) = vflux_R_arr(3) + coeff_R(q)*(-2._wp*dvel_small(2))/3._wp end if - !z-direction contributions + ! z-direction contributions $:GPU_LOOP(parallelism='[seq]') do i = -1, 1 rho_L = 0._wp @@ -2392,15 +2227,14 @@ contains end do rho_sf_small(i) = rho_L end do - dvel_small(1) = (1/(2._wp*dz(l)))*( & - q_cons_vf(momxb)%sf(j, k, l + 1 + q)/rho_sf_small(1) - & - q_cons_vf(momxb)%sf(j, k, l - 1 + q)/rho_sf_small(-1)) - dvel_small(2) = (1/(2._wp*dz(l)))*( & - q_cons_vf(momxb + 1)%sf(j, k, l + 1 + q)/rho_sf_small(1) - & - q_cons_vf(momxb + 1)%sf(j, k, l - 1 + q)/rho_sf_small(-1)) - dvel_small(3) = (1/(2._wp*dz(l)))*( & - q_cons_vf(momxb + 2)%sf(j, k, l + 1 + q)/rho_sf_small(1) - & - q_cons_vf(momxb + 2)%sf(j, k, l - 1 + q)/rho_sf_small(-1)) + dvel_small(1) = (1/(2._wp*dz(l)))*(q_cons_vf(momxb)%sf(j, k, & + & l + 1 + q)/rho_sf_small(1) - q_cons_vf(momxb)%sf(j, k, l - 1 + q)/rho_sf_small(-1)) + dvel_small(2) = (1/(2._wp*dz(l)))*(q_cons_vf(momxb + 1)%sf(j, k, & + & l + 1 + q)/rho_sf_small(1) - q_cons_vf(momxb + 1)%sf(j, k, & + & l - 1 + q)/rho_sf_small(-1)) + dvel_small(3) = (1/(2._wp*dz(l)))*(q_cons_vf(momxb + 2)%sf(j, k, & + & l + 1 + q)/rho_sf_small(1) - q_cons_vf(momxb + 2)%sf(j, k, & + & l - 1 + q)/rho_sf_small(-1)) if (q > vidxb) then vflux_L_arr(1) = vflux_L_arr(1) + coeff_L(q)*(dvel_small(1)) vflux_L_arr(2) = vflux_L_arr(2) + coeff_L(q)*(dvel_small(2)) @@ -2473,7 +2307,6 @@ contains end do if (num_fluids > 1) then - alpha_L(num_fluids) = 1._wp alpha_R(num_fluids) = 1._wp @@ -2515,88 +2348,88 @@ contains end do $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb)%sf(j, k, l + 1) = rhs_vf(momxb)%sf(j, k, l + 1) - & - real(0.5_wp*dt*mu_L*vflux_L_arr(1)*(1._wp/dz(l + 1)), kind=stp) + rhs_vf(momxb)%sf(j, k, l + 1) = rhs_vf(momxb)%sf(j, k, & + & l + 1) - real(0.5_wp*dt*mu_L*vflux_L_arr(1)*(1._wp/dz(l + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(E_idx)%sf(j, k, l + 1) = rhs_vf(E_idx)%sf(j, k, l + 1) - & - real(0.5_wp*dt*mu_L*vflux_L_arr(1)*vel_L(1)*(1._wp/dz(l + 1)), kind=stp) + rhs_vf(E_idx)%sf(j, k, l + 1) = rhs_vf(E_idx)%sf(j, k, & + & l + 1) - real(0.5_wp*dt*mu_L*vflux_L_arr(1)*vel_L(1)*(1._wp/dz(l + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb)%sf(j, k, l) = rhs_vf(momxb)%sf(j, k, l) + & - real(0.5_wp*dt*mu_L*vflux_L_arr(1)*(1._wp/dz(l)), kind=stp) + rhs_vf(momxb)%sf(j, k, l) = rhs_vf(momxb)%sf(j, k, & + & l) + real(0.5_wp*dt*mu_L*vflux_L_arr(1)*(1._wp/dz(l)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(E_idx)%sf(j, k, l) = rhs_vf(E_idx)%sf(j, k, l) + & - real(0.5_wp*dt*mu_L*vflux_L_arr(1)*vel_L(1)*(1._wp/dz(l)), kind=stp) + rhs_vf(E_idx)%sf(j, k, l) = rhs_vf(E_idx)%sf(j, k, & + & l) + real(0.5_wp*dt*mu_L*vflux_L_arr(1)*vel_L(1)*(1._wp/dz(l)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb)%sf(j, k, l + 1) = rhs_vf(momxb)%sf(j, k, l + 1) - & - real(0.5_wp*dt*mu_R*vflux_R_arr(1)*(1._wp/dz(l + 1)), kind=stp) + rhs_vf(momxb)%sf(j, k, l + 1) = rhs_vf(momxb)%sf(j, k, & + & l + 1) - real(0.5_wp*dt*mu_R*vflux_R_arr(1)*(1._wp/dz(l + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(E_idx)%sf(j, k, l + 1) = rhs_vf(E_idx)%sf(j, k, l + 1) - & - real(0.5_wp*dt*mu_R*vflux_R_arr(1)*vel_R(1)*(1._wp/dz(l + 1)), kind=stp) + rhs_vf(E_idx)%sf(j, k, l + 1) = rhs_vf(E_idx)%sf(j, k, & + & l + 1) - real(0.5_wp*dt*mu_R*vflux_R_arr(1)*vel_R(1)*(1._wp/dz(l + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb)%sf(j, k, l) = rhs_vf(momxb)%sf(j, k, l) + & - real(0.5_wp*dt*mu_R*vflux_R_arr(1)*(1._wp/dz(l)), kind=stp) + rhs_vf(momxb)%sf(j, k, l) = rhs_vf(momxb)%sf(j, k, & + & l) + real(0.5_wp*dt*mu_R*vflux_R_arr(1)*(1._wp/dz(l)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(E_idx)%sf(j, k, l) = rhs_vf(E_idx)%sf(j, k, l) + & - real(0.5_wp*dt*mu_R*vflux_R_arr(1)*vel_R(1)*(1._wp/dz(l)), kind=stp) + rhs_vf(E_idx)%sf(j, k, l) = rhs_vf(E_idx)%sf(j, k, & + & l) + real(0.5_wp*dt*mu_R*vflux_R_arr(1)*vel_R(1)*(1._wp/dz(l)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb + 1)%sf(j, k, l + 1) = rhs_vf(momxb + 1)%sf(j, k, l + 1) - & - real(0.5_wp*dt*mu_L*vflux_L_arr(2)*(1._wp/dz(l + 1)), kind=stp) + rhs_vf(momxb + 1)%sf(j, k, l + 1) = rhs_vf(momxb + 1)%sf(j, k, & + & l + 1) - real(0.5_wp*dt*mu_L*vflux_L_arr(2)*(1._wp/dz(l + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(E_idx)%sf(j, k, l + 1) = rhs_vf(E_idx)%sf(j, k, l + 1) - & - real(0.5_wp*dt*mu_L*vflux_L_arr(2)*vel_L(2)*(1._wp/dz(l + 1)), kind=stp) + rhs_vf(E_idx)%sf(j, k, l + 1) = rhs_vf(E_idx)%sf(j, k, & + & l + 1) - real(0.5_wp*dt*mu_L*vflux_L_arr(2)*vel_L(2)*(1._wp/dz(l + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb + 1)%sf(j, k, l) = rhs_vf(momxb + 1)%sf(j, k, l) + & - real(0.5_wp*dt*mu_L*vflux_L_arr(2)*(1._wp/dz(l)), kind=stp) + rhs_vf(momxb + 1)%sf(j, k, l) = rhs_vf(momxb + 1)%sf(j, k, & + & l) + real(0.5_wp*dt*mu_L*vflux_L_arr(2)*(1._wp/dz(l)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(E_idx)%sf(j, k, l) = rhs_vf(E_idx)%sf(j, k, l) + & - real(0.5_wp*dt*mu_L*vflux_L_arr(2)*vel_L(2)*(1._wp/dz(l)), kind=stp) + rhs_vf(E_idx)%sf(j, k, l) = rhs_vf(E_idx)%sf(j, k, & + & l) + real(0.5_wp*dt*mu_L*vflux_L_arr(2)*vel_L(2)*(1._wp/dz(l)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb + 1)%sf(j, k, l + 1) = rhs_vf(momxb + 1)%sf(j, k, l + 1) - & - real(0.5_wp*dt*mu_R*vflux_R_arr(2)*(1._wp/dz(l + 1)), kind=stp) + rhs_vf(momxb + 1)%sf(j, k, l + 1) = rhs_vf(momxb + 1)%sf(j, k, & + & l + 1) - real(0.5_wp*dt*mu_R*vflux_R_arr(2)*(1._wp/dz(l + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(E_idx)%sf(j, k, l + 1) = rhs_vf(E_idx)%sf(j, k, l + 1) - & - real(0.5_wp*dt*mu_R*vflux_R_arr(2)*vel_R(2)*(1._wp/dz(l + 1)), kind=stp) + rhs_vf(E_idx)%sf(j, k, l + 1) = rhs_vf(E_idx)%sf(j, k, & + & l + 1) - real(0.5_wp*dt*mu_R*vflux_R_arr(2)*vel_R(2)*(1._wp/dz(l + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb + 1)%sf(j, k, l) = rhs_vf(momxb + 1)%sf(j, k, l) + & - real(0.5_wp*dt*mu_R*vflux_R_arr(2)*(1._wp/dz(l)), kind=stp) + rhs_vf(momxb + 1)%sf(j, k, l) = rhs_vf(momxb + 1)%sf(j, k, & + & l) + real(0.5_wp*dt*mu_R*vflux_R_arr(2)*(1._wp/dz(l)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(E_idx)%sf(j, k, l) = rhs_vf(E_idx)%sf(j, k, l) + & - real(0.5_wp*dt*mu_R*vflux_R_arr(2)*vel_R(2)*(1._wp/dz(l)), kind=stp) + rhs_vf(E_idx)%sf(j, k, l) = rhs_vf(E_idx)%sf(j, k, & + & l) + real(0.5_wp*dt*mu_R*vflux_R_arr(2)*vel_R(2)*(1._wp/dz(l)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb + 2)%sf(j, k, l + 1) = rhs_vf(momxb + 2)%sf(j, k, l + 1) - & - real(0.5_wp*dt*mu_L*vflux_L_arr(3)*(1._wp/dz(l + 1)), kind=stp) + rhs_vf(momxb + 2)%sf(j, k, l + 1) = rhs_vf(momxb + 2)%sf(j, k, & + & l + 1) - real(0.5_wp*dt*mu_L*vflux_L_arr(3)*(1._wp/dz(l + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(E_idx)%sf(j, k, l + 1) = rhs_vf(E_idx)%sf(j, k, l + 1) - & - real(0.5_wp*dt*mu_L*vflux_L_arr(3)*vel_L(3)*(1._wp/dz(l + 1)), kind=stp) + rhs_vf(E_idx)%sf(j, k, l + 1) = rhs_vf(E_idx)%sf(j, k, & + & l + 1) - real(0.5_wp*dt*mu_L*vflux_L_arr(3)*vel_L(3)*(1._wp/dz(l + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb + 2)%sf(j, k, l) = rhs_vf(momxb + 2)%sf(j, k, l) + & - real(0.5_wp*dt*mu_L*vflux_L_arr(3)*(1._wp/dz(l)), kind=stp) + rhs_vf(momxb + 2)%sf(j, k, l) = rhs_vf(momxb + 2)%sf(j, k, & + & l) + real(0.5_wp*dt*mu_L*vflux_L_arr(3)*(1._wp/dz(l)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(E_idx)%sf(j, k, l) = rhs_vf(E_idx)%sf(j, k, l) + & - real(0.5_wp*dt*mu_L*vflux_L_arr(3)*vel_L(3)*(1._wp/dz(l)), kind=stp) + rhs_vf(E_idx)%sf(j, k, l) = rhs_vf(E_idx)%sf(j, k, & + & l) + real(0.5_wp*dt*mu_L*vflux_L_arr(3)*vel_L(3)*(1._wp/dz(l)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb + 2)%sf(j, k, l + 1) = rhs_vf(momxb + 2)%sf(j, k, l + 1) - & - real(0.5_wp*dt*mu_R*vflux_R_arr(3)*(1._wp/dz(l + 1)), kind=stp) + rhs_vf(momxb + 2)%sf(j, k, l + 1) = rhs_vf(momxb + 2)%sf(j, k, & + & l + 1) - real(0.5_wp*dt*mu_R*vflux_R_arr(3)*(1._wp/dz(l + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(E_idx)%sf(j, k, l + 1) = rhs_vf(E_idx)%sf(j, k, l + 1) - & - real(0.5_wp*dt*mu_R*vflux_R_arr(3)*vel_R(3)*(1._wp/dz(l + 1)), kind=stp) + rhs_vf(E_idx)%sf(j, k, l + 1) = rhs_vf(E_idx)%sf(j, k, & + & l + 1) - real(0.5_wp*dt*mu_R*vflux_R_arr(3)*vel_R(3)*(1._wp/dz(l + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb + 2)%sf(j, k, l) = rhs_vf(momxb + 2)%sf(j, k, l) + & - real(0.5_wp*dt*mu_R*vflux_R_arr(3)*(1._wp/dz(l)), kind=stp) + rhs_vf(momxb + 2)%sf(j, k, l) = rhs_vf(momxb + 2)%sf(j, k, & + & l) + real(0.5_wp*dt*mu_R*vflux_R_arr(3)*(1._wp/dz(l)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(E_idx)%sf(j, k, l) = rhs_vf(E_idx)%sf(j, k, l) + & - real(0.5_wp*dt*mu_R*vflux_R_arr(3)*vel_R(3)*(1._wp/dz(l)), kind=stp) + rhs_vf(E_idx)%sf(j, k, l) = rhs_vf(E_idx)%sf(j, k, & + & l) + real(0.5_wp*dt*mu_R*vflux_R_arr(3)*vel_R(3)*(1._wp/dz(l)), kind=stp) end if E_L = 0._wp; E_R = 0._wp @@ -2614,178 +2447,164 @@ contains F_R = F_R + coeff_R(q)*jac(j, k, l + q) end do - call s_get_derived_states(E_L, gamma_L, pi_inf_L, rho_L, vel_L, & - E_R, gamma_R, pi_inf_R, rho_R, vel_R, & - pres_L, pres_R, cfl) + call s_get_derived_states(E_L, gamma_L, pi_inf_L, rho_L, vel_L, E_R, gamma_R, pi_inf_R, rho_R, vel_R, & + & pres_L, pres_R, cfl) $:GPU_LOOP(parallelism='[seq]') do i = 1, num_fluids $:GPU_ATOMIC(atomic='update') - rhs_vf(i)%sf(j, k, l + 1) = rhs_vf(i)%sf(j, k, l + 1) + & - real(0.5_wp*dt*(alpha_rho_L(i)* & - vel_L(3))*(1._wp/dz(l + 1)) - & - 0.5_wp*dt*cfl*(alpha_rho_L(i))*(1._wp/dz(l + 1)), kind=stp) + rhs_vf(i)%sf(j, k, l + 1) = rhs_vf(i)%sf(j, k, & + & l + 1) + real(0.5_wp*dt*(alpha_rho_L(i)*vel_L(3))*(1._wp/dz(l + 1)) & + & - 0.5_wp*dt*cfl*(alpha_rho_L(i))*(1._wp/dz(l + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(i)%sf(j, k, l) = rhs_vf(i)%sf(j, k, l) - & - real(0.5_wp*dt*(alpha_rho_L(i)* & - vel_L(3))*(1._wp/dz(l)) - & - 0.5_wp*dt*cfl*(alpha_rho_L(i))*(1._wp/dz(l)), kind=stp) + rhs_vf(i)%sf(j, k, l) = rhs_vf(i)%sf(j, k, & + & l) - real(0.5_wp*dt*(alpha_rho_L(i)*vel_L(3))*(1._wp/dz(l)) & + & - 0.5_wp*dt*cfl*(alpha_rho_L(i))*(1._wp/dz(l)), kind=stp) end do if (num_fluids > 1) then $:GPU_LOOP(parallelism='[seq]') do i = 1, num_fluids - 1 $:GPU_ATOMIC(atomic='update') - rhs_vf(advxb + i - 1)%sf(j, k, l + 1) = rhs_vf(advxb + i - 1)%sf(j, k, l + 1) + & - real(0.5_wp*dt*(alpha_L(i)* & - vel_L(3))*(1._wp/dz(l + 1)) - & - 0.5_wp*dt*cfl*(alpha_L(i))*(1._wp/dz(l + 1)), kind=stp) + rhs_vf(advxb + i - 1)%sf(j, k, l + 1) = rhs_vf(advxb + i - 1)%sf(j, k, & + & l + 1) + real(0.5_wp*dt*(alpha_L(i)*vel_L(3))*(1._wp/dz(l + 1)) & + & - 0.5_wp*dt*cfl*(alpha_L(i))*(1._wp/dz(l + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(advxb + i - 1)%sf(j, k, l + 1) = rhs_vf(advxb + i - 1)%sf(j, k, l + 1) & - - real(0.5_wp*dt*q_cons_vf(advxb + i - 1)%sf(j, k, l + 1)*vel_L(3)*(1._wp/dz(l + 1)), kind=stp) + rhs_vf(advxb + i - 1)%sf(j, k, l + 1) = rhs_vf(advxb + i - 1)%sf(j, k, & + & l + 1) - real(0.5_wp*dt*q_cons_vf(advxb + i - 1)%sf(j, k, & + & l + 1)*vel_L(3)*(1._wp/dz(l + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(advxb + i - 1)%sf(j, k, l) = rhs_vf(advxb + i - 1)%sf(j, k, l) - & - real(0.5_wp*dt*(alpha_L(i)* & - vel_L(3))*(1._wp/dz(l)) - & - 0.5_wp*dt*cfl*(alpha_L(i))*(1._wp/dz(l)), kind=stp) + rhs_vf(advxb + i - 1)%sf(j, k, l) = rhs_vf(advxb + i - 1)%sf(j, k, & + & l) - real(0.5_wp*dt*(alpha_L(i)*vel_L(3))*(1._wp/dz(l)) - 0.5_wp*dt*cfl*(alpha_L(i)) & + & *(1._wp/dz(l)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(advxb + i - 1)%sf(j, k, l) = rhs_vf(advxb + i - 1)%sf(j, k, l) & - + real(0.5_wp*dt*q_cons_vf(advxb + i - 1)%sf(j, k, l)*vel_L(3)*(1._wp/dz(l)), kind=stp) + rhs_vf(advxb + i - 1)%sf(j, k, l) = rhs_vf(advxb + i - 1)%sf(j, k, & + & l) + real(0.5_wp*dt*q_cons_vf(advxb + i - 1)%sf(j, k, l)*vel_L(3)*(1._wp/dz(l)), & + & kind=stp) end do end if $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb + 2)%sf(j, k, l + 1) = rhs_vf(momxb + 2)%sf(j, k, l + 1) + & - real(0.5_wp*dt*(rho_L*(vel_L(3))**2.0 + & - pres_L + F_L)*(1._wp/dz(l + 1)) - & - 0.5_wp*dt*cfl*(rho_L*vel_L(3))*(1._wp/dz(l + 1)), kind=stp) + rhs_vf(momxb + 2)%sf(j, k, l + 1) = rhs_vf(momxb + 2)%sf(j, k, & + & l + 1) + real(0.5_wp*dt*(rho_L*(vel_L(3))**2.0 + pres_L + F_L)*(1._wp/dz(l + 1)) & + & - 0.5_wp*dt*cfl*(rho_L*vel_L(3))*(1._wp/dz(l + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb)%sf(j, k, l + 1) = rhs_vf(momxb)%sf(j, k, l + 1) + & - real(0.5_wp*dt*rho_L*vel_L(1)*vel_L(3)*(1._wp/dz(l + 1)) - & - 0.5_wp*dt*cfl*(rho_L*vel_L(1))*(1._wp/dz(l + 1)), kind=stp) + rhs_vf(momxb)%sf(j, k, l + 1) = rhs_vf(momxb)%sf(j, k, & + & l + 1) + real(0.5_wp*dt*rho_L*vel_L(1)*vel_L(3)*(1._wp/dz(l + 1)) & + & - 0.5_wp*dt*cfl*(rho_L*vel_L(1))*(1._wp/dz(l + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb + 1)%sf(j, k, l + 1) = rhs_vf(momxb + 1)%sf(j, k, l + 1) + & - real(0.5_wp*dt*rho_L*vel_L(2)*vel_L(3)*(1._wp/dz(l + 1)) - & - 0.5_wp*dt*cfl*(rho_L*vel_L(2))*(1._wp/dz(l + 1)), kind=stp) + rhs_vf(momxb + 1)%sf(j, k, l + 1) = rhs_vf(momxb + 1)%sf(j, k, & + & l + 1) + real(0.5_wp*dt*rho_L*vel_L(2)*vel_L(3)*(1._wp/dz(l + 1)) & + & - 0.5_wp*dt*cfl*(rho_L*vel_L(2))*(1._wp/dz(l + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(E_idx)%sf(j, k, l + 1) = rhs_vf(E_idx)%sf(j, k, l + 1) + & - real(0.5_wp*dt*(vel_L(3)*(E_L + & - pres_L + F_L))*(1._wp/dz(l + 1)) - & - 0.5_wp*dt*cfl*(E_L)*(1._wp/dz(l + 1)), kind=stp) + rhs_vf(E_idx)%sf(j, k, l + 1) = rhs_vf(E_idx)%sf(j, k, & + & l + 1) + real(0.5_wp*dt*(vel_L(3)*(E_L + pres_L + F_L))*(1._wp/dz(l + 1)) & + & - 0.5_wp*dt*cfl*(E_L)*(1._wp/dz(l + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb + 2)%sf(j, k, l) = rhs_vf(momxb + 2)%sf(j, k, l) - & - real(0.5_wp*dt*(rho_L*(vel_L(3))**2.0 + & - pres_L + F_L)*(1._wp/dz(l)) - & - 0.5_wp*dt*cfl*(rho_L*vel_L(3))*(1._wp/dz(l)), kind=stp) + rhs_vf(momxb + 2)%sf(j, k, l) = rhs_vf(momxb + 2)%sf(j, k, & + & l) - real(0.5_wp*dt*(rho_L*(vel_L(3))**2.0 + pres_L + F_L)*(1._wp/dz(l)) & + & - 0.5_wp*dt*cfl*(rho_L*vel_L(3))*(1._wp/dz(l)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb)%sf(j, k, l) = rhs_vf(momxb)%sf(j, k, l) - & - real(0.5_wp*dt*rho_L*vel_L(1)*vel_L(3)*(1._wp/dz(l)) - & - 0.5_wp*dt*cfl*(rho_L*vel_L(1))*(1._wp/dz(l)), kind=stp) + rhs_vf(momxb)%sf(j, k, l) = rhs_vf(momxb)%sf(j, k, & + & l) - real(0.5_wp*dt*rho_L*vel_L(1)*vel_L(3)*(1._wp/dz(l)) - 0.5_wp*dt*cfl*(rho_L*vel_L(1)) & + & *(1._wp/dz(l)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb + 1)%sf(j, k, l) = rhs_vf(momxb + 1)%sf(j, k, l) - & - real(0.5_wp*dt*rho_L*vel_L(2)*vel_L(3)*(1._wp/dz(l)) - & - 0.5_wp*dt*cfl*(rho_L*vel_L(2))*(1._wp/dz(l)), kind=stp) + rhs_vf(momxb + 1)%sf(j, k, l) = rhs_vf(momxb + 1)%sf(j, k, & + & l) - real(0.5_wp*dt*rho_L*vel_L(2)*vel_L(3)*(1._wp/dz(l)) - 0.5_wp*dt*cfl*(rho_L*vel_L(2)) & + & *(1._wp/dz(l)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(E_idx)%sf(j, k, l) = rhs_vf(E_idx)%sf(j, k, l) - & - real(0.5_wp*dt*(vel_L(3)*(E_L + & - pres_L + F_L))*(1._wp/dz(l)) - & - 0.5_wp*dt*cfl*(E_L)*(1._wp/dz(l)), kind=stp) + rhs_vf(E_idx)%sf(j, k, l) = rhs_vf(E_idx)%sf(j, k, & + & l) - real(0.5_wp*dt*(vel_L(3)*(E_L + pres_L + F_L))*(1._wp/dz(l)) - 0.5_wp*dt*cfl*(E_L) & + & *(1._wp/dz(l)), kind=stp) $:GPU_LOOP(parallelism='[seq]') do i = 1, num_fluids $:GPU_ATOMIC(atomic='update') - rhs_vf(i)%sf(j, k, l + 1) = rhs_vf(i)%sf(j, k, l + 1) + & - real(0.5_wp*dt*(alpha_rho_R(i)* & - vel_R(3))*(1._wp/dz(l + 1)) + & - 0.5_wp*dt*cfl*(alpha_rho_R(i))*(1._wp/dz(l + 1)), kind=stp) + rhs_vf(i)%sf(j, k, l + 1) = rhs_vf(i)%sf(j, k, & + & l + 1) + real(0.5_wp*dt*(alpha_rho_R(i)*vel_R(3))*(1._wp/dz(l + 1)) & + & + 0.5_wp*dt*cfl*(alpha_rho_R(i))*(1._wp/dz(l + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(i)%sf(j, k, l) = rhs_vf(i)%sf(j, k, l) - & - real(0.5_wp*dt*(alpha_rho_R(i)* & - vel_R(3))*(1._wp/dz(l)) + & - 0.5_wp*dt*cfl*(alpha_rho_R(i))*(1._wp/dz(l)), kind=stp) + rhs_vf(i)%sf(j, k, l) = rhs_vf(i)%sf(j, k, & + & l) - real(0.5_wp*dt*(alpha_rho_R(i)*vel_R(3))*(1._wp/dz(l)) & + & + 0.5_wp*dt*cfl*(alpha_rho_R(i))*(1._wp/dz(l)), kind=stp) end do if (num_fluids > 1) then $:GPU_LOOP(parallelism='[seq]') do i = 1, num_fluids - 1 $:GPU_ATOMIC(atomic='update') - rhs_vf(advxb + i - 1)%sf(j, k, l + 1) = rhs_vf(advxb + i - 1)%sf(j, k, l + 1) + & - real(0.5_wp*dt*(alpha_R(i)* & - vel_R(3))*(1._wp/dz(l + 1)) + & - 0.5_wp*dt*cfl*(alpha_R(i))*(1._wp/dz(l + 1)), kind=stp) + rhs_vf(advxb + i - 1)%sf(j, k, l + 1) = rhs_vf(advxb + i - 1)%sf(j, k, & + & l + 1) + real(0.5_wp*dt*(alpha_R(i)*vel_R(3))*(1._wp/dz(l + 1)) & + & + 0.5_wp*dt*cfl*(alpha_R(i))*(1._wp/dz(l + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(advxb + i - 1)%sf(j, k, l + 1) = rhs_vf(advxb + i - 1)%sf(j, k, l + 1) & - - real(0.5_wp*dt*q_cons_vf(advxb + i - 1)%sf(j, k, l + 1)*vel_R(3)*(1._wp/dz(l + 1)), kind=stp) + rhs_vf(advxb + i - 1)%sf(j, k, l + 1) = rhs_vf(advxb + i - 1)%sf(j, k, & + & l + 1) - real(0.5_wp*dt*q_cons_vf(advxb + i - 1)%sf(j, k, & + & l + 1)*vel_R(3)*(1._wp/dz(l + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(advxb + i - 1)%sf(j, k, l) = rhs_vf(advxb + i - 1)%sf(j, k, l) - & - real(0.5_wp*dt*(alpha_R(i)* & - vel_R(3))*(1._wp/dz(l)) + & - 0.5_wp*dt*cfl*(alpha_R(i))*(1._wp/dz(l)), kind=stp) + rhs_vf(advxb + i - 1)%sf(j, k, l) = rhs_vf(advxb + i - 1)%sf(j, k, & + & l) - real(0.5_wp*dt*(alpha_R(i)*vel_R(3))*(1._wp/dz(l)) + 0.5_wp*dt*cfl*(alpha_R(i)) & + & *(1._wp/dz(l)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(advxb + i - 1)%sf(j, k, l) = rhs_vf(advxb + i - 1)%sf(j, k, l) & - + real(0.5_wp*dt*q_cons_vf(advxb + i - 1)%sf(j, k, l)*vel_R(3)*(1._wp/dz(l)), kind=stp) + rhs_vf(advxb + i - 1)%sf(j, k, l) = rhs_vf(advxb + i - 1)%sf(j, k, & + & l) + real(0.5_wp*dt*q_cons_vf(advxb + i - 1)%sf(j, k, l)*vel_R(3)*(1._wp/dz(l)), & + & kind=stp) end do end if $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb + 2)%sf(j, k, l + 1) = rhs_vf(momxb + 2)%sf(j, k, l + 1) + & - real(0.5_wp*dt*(rho_R*(vel_R(3))**2.0 + & - pres_R + F_R)*(1._wp/dz(l + 1)) + & - 0.5_wp*dt*cfl*(rho_R*vel_R(3))*(1._wp/dz(l + 1)), kind=stp) + rhs_vf(momxb + 2)%sf(j, k, l + 1) = rhs_vf(momxb + 2)%sf(j, k, & + & l + 1) + real(0.5_wp*dt*(rho_R*(vel_R(3))**2.0 + pres_R + F_R)*(1._wp/dz(l + 1)) & + & + 0.5_wp*dt*cfl*(rho_R*vel_R(3))*(1._wp/dz(l + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb)%sf(j, k, l + 1) = rhs_vf(momxb)%sf(j, k, l + 1) + & - real(0.5_wp*dt*rho_R*vel_R(1)*vel_R(3)*(1._wp/dz(l + 1)) + & - 0.5_wp*dt*cfl*(rho_R*vel_R(1))*(1._wp/dz(l + 1)), kind=stp) + rhs_vf(momxb)%sf(j, k, l + 1) = rhs_vf(momxb)%sf(j, k, & + & l + 1) + real(0.5_wp*dt*rho_R*vel_R(1)*vel_R(3)*(1._wp/dz(l + 1)) & + & + 0.5_wp*dt*cfl*(rho_R*vel_R(1))*(1._wp/dz(l + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb + 1)%sf(j, k, l + 1) = rhs_vf(momxb + 1)%sf(j, k, l + 1) + & - real(0.5_wp*dt*rho_R*vel_R(2)*vel_R(3)*(1._wp/dz(l + 1)) + & - 0.5_wp*dt*cfl*(rho_R*vel_R(2))*(1._wp/dz(l + 1)), kind=stp) + rhs_vf(momxb + 1)%sf(j, k, l + 1) = rhs_vf(momxb + 1)%sf(j, k, & + & l + 1) + real(0.5_wp*dt*rho_R*vel_R(2)*vel_R(3)*(1._wp/dz(l + 1)) & + & + 0.5_wp*dt*cfl*(rho_R*vel_R(2))*(1._wp/dz(l + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(E_idx)%sf(j, k, l + 1) = rhs_vf(E_idx)%sf(j, k, l + 1) + & - real(0.5_wp*dt*(vel_R(3)*(E_R + & - pres_R + F_R))*(1._wp/dz(l + 1)) + & - 0.5_wp*dt*cfl*(E_R)*(1._wp/dz(l + 1)), kind=stp) + rhs_vf(E_idx)%sf(j, k, l + 1) = rhs_vf(E_idx)%sf(j, k, & + & l + 1) + real(0.5_wp*dt*(vel_R(3)*(E_R + pres_R + F_R))*(1._wp/dz(l + 1)) & + & + 0.5_wp*dt*cfl*(E_R)*(1._wp/dz(l + 1)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb + 2)%sf(j, k, l) = rhs_vf(momxb + 2)%sf(j, k, l) - & - real(0.5_wp*dt*(rho_R*(vel_R(3))**2.0 + & - pres_R + F_R)*(1._wp/dz(l)) + & - 0.5_wp*dt*cfl*(rho_R*vel_R(3))*(1._wp/dz(l)), kind=stp) + rhs_vf(momxb + 2)%sf(j, k, l) = rhs_vf(momxb + 2)%sf(j, k, & + & l) - real(0.5_wp*dt*(rho_R*(vel_R(3))**2.0 + pres_R + F_R)*(1._wp/dz(l)) & + & + 0.5_wp*dt*cfl*(rho_R*vel_R(3))*(1._wp/dz(l)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb)%sf(j, k, l) = rhs_vf(momxb)%sf(j, k, l) - & - real(0.5_wp*dt*rho_R*vel_R(1)*vel_R(3)*(1._wp/dz(l)) + & - 0.5_wp*dt*cfl*(rho_R*vel_R(1))*(1._wp/dz(l)), kind=stp) + rhs_vf(momxb)%sf(j, k, l) = rhs_vf(momxb)%sf(j, k, & + & l) - real(0.5_wp*dt*rho_R*vel_R(1)*vel_R(3)*(1._wp/dz(l)) + 0.5_wp*dt*cfl*(rho_R*vel_R(1)) & + & *(1._wp/dz(l)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(momxb + 1)%sf(j, k, l) = rhs_vf(momxb + 1)%sf(j, k, l) - & - real(0.5_wp*dt*rho_R*vel_R(2)*vel_R(3)*(1._wp/dz(l)) + & - 0.5_wp*dt*cfl*(rho_R*vel_R(2))*(1._wp/dz(l)), kind=stp) + rhs_vf(momxb + 1)%sf(j, k, l) = rhs_vf(momxb + 1)%sf(j, k, & + & l) - real(0.5_wp*dt*rho_R*vel_R(2)*vel_R(3)*(1._wp/dz(l)) + 0.5_wp*dt*cfl*(rho_R*vel_R(2)) & + & *(1._wp/dz(l)), kind=stp) $:GPU_ATOMIC(atomic='update') - rhs_vf(E_idx)%sf(j, k, l) = rhs_vf(E_idx)%sf(j, k, l) - & - real(0.5_wp*dt*(vel_R(3)*(E_R + & - pres_R + F_R))*(1._wp/dz(l)) + & - 0.5_wp*dt*cfl*(E_R)*(1._wp/dz(l)), kind=stp) - + rhs_vf(E_idx)%sf(j, k, l) = rhs_vf(E_idx)%sf(j, k, & + & l) - real(0.5_wp*dt*(vel_R(3)*(E_R + pres_R + F_R))*(1._wp/dz(l)) + 0.5_wp*dt*cfl*(E_R) & + & *(1._wp/dz(l)), kind=stp) end do end do end do @@ -2796,17 +2615,15 @@ contains end subroutine s_igr_riemann_solver !> @brief Computes pressure and maximum wavespeed from left and right reconstructed states for the IGR Riemann solver. - subroutine s_get_derived_states(E_L, gamma_L, pi_inf_L, rho_L, vel_L, & - E_R, gamma_R, pi_inf_R, rho_R, vel_R, & - pres_L, pres_R, cfl) + subroutine s_get_derived_states(E_L, gamma_L, pi_inf_L, rho_L, vel_L, E_R, gamma_R, pi_inf_R, rho_R, vel_R, pres_L, pres_R, cfl) + $:GPU_ROUTINE(parallelism='[seq]') - real(wp), intent(in) :: E_L, gamma_L, pi_inf_L, rho_L - real(wp), intent(in) :: E_R, gamma_R, pi_inf_R, rho_R + real(wp), intent(in) :: E_L, gamma_L, pi_inf_L, rho_L + real(wp), intent(in) :: E_R, gamma_R, pi_inf_R, rho_R real(wp), dimension(num_dims), intent(in) :: vel_L, vel_R - real(wp), intent(out) :: pres_L, pres_R, cfl - - real(wp) :: a_L, a_R + real(wp), intent(out) :: pres_L, pres_R, cfl + real(wp) :: a_L, a_R if (num_dims == 2) then pres_L = (E_L - pi_inf_L - 0.5_wp*rho_L*(vel_L(1)**2._wp + vel_L(2)**2._wp))/gamma_L @@ -2820,10 +2637,8 @@ contains a_L = sqrt((pres_L*(1._wp/gamma_L + 1._wp) + pi_inf_L/gamma_L)/rho_L) a_R = sqrt((pres_R*(1._wp/gamma_R + 1._wp) + pi_inf_R/gamma_R)/rho_R) - cfl = max(sqrt(vel_L(1)**2._wp + vel_L(2)**2._wp), & - sqrt(vel_R(1)**2._wp + vel_R(2)**2._wp)) + & - max(a_L, a_R) - elseif (num_dims == 3) then + cfl = max(sqrt(vel_L(1)**2._wp + vel_L(2)**2._wp), sqrt(vel_R(1)**2._wp + vel_R(2)**2._wp)) + max(a_L, a_R) + else if (num_dims == 3) then #:if not MFC_CASE_OPTIMIZATION or num_dims > 2 pres_L = (E_L - pi_inf_L - 0.5_wp*rho_L*(vel_L(1)**2._wp + vel_L(2)**2._wp + vel_L(3)**2._wp))/gamma_L pres_R = (E_R - pi_inf_R - 0.5_wp*rho_R*(vel_R(1)**2._wp + vel_R(2)**2._wp + vel_R(3)**2._wp))/gamma_R @@ -2837,8 +2652,7 @@ contains a_R = sqrt((pres_R*(1._wp/gamma_R + 1._wp) + pi_inf_R/gamma_R)/rho_R) cfl = max(sqrt(vel_L(1)**2._wp + vel_L(2)**2._wp + vel_L(3)**2._wp), & - sqrt(vel_R(1)**2._wp + vel_R(2)**2._wp + vel_R(3)**2._wp)) + & - max(a_L, a_R) + & sqrt(vel_R(1)**2._wp + vel_R(2)**2._wp + vel_R(3)**2._wp)) + max(a_L, a_R) #:endif end if @@ -2847,51 +2661,42 @@ contains !> @brief Accumulates the IGR numerical flux divergence into the right-hand side along the specified coordinate direction. subroutine s_igr_flux_add(q_cons_vf, rhs_vf, flux_vf, idir) - type(scalar_field), & - dimension(sys_size), & - intent(inout) :: q_cons_vf, flux_vf, rhs_vf - - integer, intent(in) :: idir + type(scalar_field), dimension(sys_size), intent(inout) :: q_cons_vf, flux_vf, rhs_vf + integer, intent(in) :: idir if (idir == 1) then - $:GPU_PARALLEL_LOOP(private='[i,j,k,l]', collapse=4) + $:GPU_PARALLEL_LOOP(private='[i, j, k, l]', collapse=4) do i = 1, sys_size do l = 0, p do k = 0, n do j = 0, m - rhs_vf(i)%sf(j, k, l) = 1._wp/dx(j)* & - (flux_vf(i)%sf(j - 1, k, l) & - - flux_vf(i)%sf(j, k, l)) + rhs_vf(i)%sf(j, k, l) = 1._wp/dx(j)*(flux_vf(i)%sf(j - 1, k, l) - flux_vf(i)%sf(j, k, l)) end do end do end do end do $:END_GPU_PARALLEL_LOOP() - elseif (idir == 2) then - $:GPU_PARALLEL_LOOP(private='[i,j,k,l]', collapse=4) + else if (idir == 2) then + $:GPU_PARALLEL_LOOP(private='[i, j, k, l]', collapse=4) do i = 1, sys_size do l = 0, p do k = 0, n do j = 0, m - rhs_vf(i)%sf(j, k, l) = & - rhs_vf(i)%sf(j, k, l) + 1._wp/dy(k)* & - (flux_vf(i)%sf(j, k - 1, l) & - - flux_vf(i)%sf(j, k, l)) + rhs_vf(i)%sf(j, k, l) = rhs_vf(i)%sf(j, k, l) + 1._wp/dy(k)*(flux_vf(i)%sf(j, k - 1, & + & l) - flux_vf(i)%sf(j, k, l)) end do end do end do end do $:END_GPU_PARALLEL_LOOP() - elseif (idir == 3) then - $:GPU_PARALLEL_LOOP(private='[i,j,k,l]', collapse=4) + else if (idir == 3) then + $:GPU_PARALLEL_LOOP(private='[i, j, k, l]', collapse=4) do i = 1, sys_size do l = 0, p do k = 0, n do j = 0, m - rhs_vf(i)%sf(j, k, l) = & - rhs_vf(i)%sf(j, k, l) + 1._wp/dz(l)* & - (flux_vf(i)%sf(j, k, l - 1) & - - flux_vf(i)%sf(j, k, l)) + rhs_vf(i)%sf(j, k, l) = rhs_vf(i)%sf(j, k, l) + 1._wp/dz(l)*(flux_vf(i)%sf(j, k, & + & l - 1) - flux_vf(i)%sf(j, k, l)) end do end do end do @@ -2911,7 +2716,7 @@ contains #ifndef __NVCOMPILER_GPU_UNIFIED_MEM @:DEALLOCATE(jac, jac_rhs) - if (igr_iter_solver == 1) then ! Jacobi iteration + if (igr_iter_solver == 1) then ! Jacobi iteration @:DEALLOCATE(jac_old) end if #else @@ -2929,7 +2734,7 @@ contains deallocate (jac_rhs_host) end if - if (igr_iter_solver == 1) then ! Jacobi iteration + if (igr_iter_solver == 1) then ! Jacobi iteration if (nv_uvm_temp_on_gpu(3) == 1) then @:DEALLOCATE(jac_old) else diff --git a/src/simulation/m_mpi_proxy.fpp b/src/simulation/m_mpi_proxy.fpp index 3bc731306f..43fda863ad 100644 --- a/src/simulation/m_mpi_proxy.fpp +++ b/src/simulation/m_mpi_proxy.fpp @@ -9,48 +9,39 @@ module m_mpi_proxy #ifdef MFC_MPI - use mpi !< Message passing interface (MPI) module + use mpi !< Message passing interface (MPI) module #endif - use m_helper_basic !< Functions to compare floating point numbers - + use m_helper_basic !< Functions to compare floating point numbers use m_helper - - use m_derived_types !< Definitions of the derived types - - use m_global_parameters !< Definitions of the global parameters - + use m_derived_types !< Definitions of the derived types + use m_global_parameters !< Definitions of the global parameters use m_mpi_common - use m_nvtx - use ieee_arithmetic implicit none - integer, private, allocatable, dimension(:) :: ib_buff_send !< - !! This variable is utilized to pack and send the buffer of the immersed - !! boundary markers, for a single computational domain boundary at the - !! time, to the relevant neighboring processor. - - integer, private, allocatable, dimension(:) :: ib_buff_recv !< - !! q_cons_buff_recv is utilized to receive and unpack the buffer of the - !! immersed boundary markers, for a single computational domain boundary - !! at the time, from the relevant neighboring processor. + !> This variable is utilized to pack and send the buffer of the immersed boundary markers, for a single computational domain + !! boundary at the time, to the relevant neighboring processor. + integer, private, allocatable, dimension(:) :: ib_buff_send - integer :: i_halo_size + !> q_cons_buff_recv is utilized to receive and unpack the buffer of the immersed boundary markers, for a single computational + !! domain boundary at the time, from the relevant neighboring processor. + integer, private, allocatable, dimension(:) :: ib_buff_recv + integer :: i_halo_size $:GPU_DECLARE(create='[i_halo_size]') - integer, dimension(-1:1, -1:1, -1:1) :: p_send_counts, p_recv_counts - integer, dimension(:, :, :, :), allocatable :: p_send_ids + integer, dimension(-1:1,-1:1,-1:1) :: p_send_counts, p_recv_counts + integer, dimension(:,:,:,:), allocatable :: p_send_ids character(len=1), dimension(:), allocatable :: p_send_buff, p_recv_buff - integer :: p_buff_size, p_var_size + integer :: p_buff_size, p_var_size !! EL Bubbles communication variables integer, parameter :: MAX_NEIGHBORS = 27 - integer :: send_requests(MAX_NEIGHBORS), recv_requests(MAX_NEIGHBORS) - integer :: recv_offsets(MAX_NEIGHBORS) - integer :: neighbor_list(MAX_NEIGHBORS, 3) - integer :: n_neighbors + integer :: send_requests(MAX_NEIGHBORS), recv_requests(MAX_NEIGHBORS) + integer :: recv_offsets(MAX_NEIGHBORS) + integer :: neighbor_list(MAX_NEIGHBORS, 3) + integer :: n_neighbors $:GPU_DECLARE(create='[p_send_counts]') contains @@ -62,14 +53,10 @@ contains if (ib) then if (n > 0) then if (p > 0) then - i_halo_size = -1 + buff_size* & - & (m + 2*buff_size + 1)* & - & (n + 2*buff_size + 1)* & - & (p + 2*buff_size + 1)/ & - & (cells_bounds%mnp_min + 2*buff_size + 1) + i_halo_size = -1 + buff_size*(m + 2*buff_size + 1)*(n + 2*buff_size + 1)*(p + 2*buff_size + 1) & + & /(cells_bounds%mnp_min + 2*buff_size + 1) else - i_halo_size = -1 + buff_size* & - & (cells_bounds%mn_max + 2*buff_size + 1) + i_halo_size = -1 + buff_size*(cells_bounds%mn_max + 2*buff_size + 1) end if else i_halo_size = -1 + buff_size @@ -82,15 +69,14 @@ contains end subroutine s_initialize_mpi_proxy_module - !! This subroutine initializes the MPI buffers and variables - !! required for the particle communication. - !! @param lag_num_ts Number of stages in time-stepping scheme + !! This subroutine initializes the MPI buffers and variables required for the particle communication. + !! @param lag_num_ts Number of stages in time-stepping scheme subroutine s_initialize_particles_mpi(lag_num_ts) integer, intent(in) :: lag_num_ts - integer :: i, j, k - integer :: real_size, int_size, nReal - integer :: ierr !< Generic flag used to identify and report MPI errors + integer :: i, j, k + integer :: real_size, int_size, nReal + integer :: ierr !< Generic flag used to identify and report MPI errors #ifdef MFC_MPI call MPI_Pack_size(1, mpi_p, MPI_COMM_WORLD, real_size, ierr) @@ -118,17 +104,14 @@ contains end subroutine s_initialize_particles_mpi - !> Since only the processor with rank 0 reads and verifies - !! the consistency of user inputs, these are initially not - !! available to the other processors. Then, the purpose of - !! this subroutine is to distribute the user inputs to the - !! remaining processors in the communicator. + !> Since only the processor with rank 0 reads and verifies the consistency of user inputs, these are initially not available to + !! the other processors. Then, the purpose of this subroutine is to distribute the user inputs to the remaining processors in + !! the communicator. impure subroutine s_mpi_bcast_user_inputs() #ifdef MFC_MPI - - integer :: i, j !< Generic loop iterator - integer :: ierr !< Generic flag used to identify and report MPI errors + integer :: i, j !< Generic loop iterator + integer :: ierr !< Generic flag used to identify and report MPI errors call MPI_BCAST(case_dir, len(case_dir), MPI_CHARACTER, 0, MPI_COMM_WORLD, ierr) @@ -251,7 +234,8 @@ contains end if do i = 1, num_fluids_max - #:for VAR in ['bc_x%alpha_rho_in','bc_x%alpha_in','bc_y%alpha_rho_in','bc_y%alpha_in','bc_z%alpha_rho_in','bc_z%alpha_in'] + #:for VAR in ['bc_x%alpha_rho_in','bc_x%alpha_in','bc_y%alpha_rho_in','bc_y%alpha_in','bc_z%alpha_rho_in', & + & 'bc_z%alpha_in'] call MPI_BCAST(${VAR}$ (i), 1, mpi_p, 0, MPI_COMM_WORLD, ierr) #:endfor end do @@ -306,7 +290,6 @@ contains ! Extra BC Variable call MPI_BCAST(periodic_bc, 3, MPI_LOGICAL, 0, MPI_COMM_WORLD, ierr) - #endif end subroutine s_mpi_bcast_user_inputs @@ -315,43 +298,31 @@ contains subroutine s_mpi_sendrecv_ib_buffers(ib_markers, mpi_dir, pbc_loc) type(integer_field), intent(inout) :: ib_markers - - integer, intent(in) :: mpi_dir, pbc_loc - - integer :: i, j, k, l, r, q !< Generic loop iterators - - integer :: buffer_counts(1:3), buffer_count - - type(int_bounds_info) :: boundary_conditions(1:3) - integer :: beg_end(1:2), grid_dims(1:3) - integer :: dst_proc, src_proc, recv_tag, send_tag - - logical :: beg_end_geq_0, qbmm_comm - - integer :: pack_offset, unpack_offset + integer, intent(in) :: mpi_dir, pbc_loc + integer :: i, j, k, l, r, q !< Generic loop iterators + integer :: buffer_counts(1:3), buffer_count + type(int_bounds_info) :: boundary_conditions(1:3) + integer :: beg_end(1:2), grid_dims(1:3) + integer :: dst_proc, src_proc, recv_tag, send_tag + logical :: beg_end_geq_0, qbmm_comm + integer :: pack_offset, unpack_offset #ifdef MFC_MPI - integer :: ierr !< Generic flag used to identify and report MPI errors + integer :: ierr !< Generic flag used to identify and report MPI errors call nvtxStartRange("IB-MARKER-COMM-PACKBUF") - buffer_counts = (/ & - buff_size*(n + 1)*(p + 1), & - buff_size*(m + 2*buff_size + 1)*(p + 1), & - buff_size*(m + 2*buff_size + 1)*(n + 2*buff_size + 1) & - /) + buffer_counts = (/buff_size*(n + 1)*(p + 1), buff_size*(m + 2*buff_size + 1)*(p + 1), & + & buff_size*(m + 2*buff_size + 1)*(n + 2*buff_size + 1)/) buffer_count = buffer_counts(mpi_dir) boundary_conditions = (/bc_x, bc_y, bc_z/) beg_end = (/boundary_conditions(mpi_dir)%beg, boundary_conditions(mpi_dir)%end/) beg_end_geq_0 = beg_end(max(pbc_loc, 0) - pbc_loc + 1) >= 0 - ! Implements: - ! pbc_loc bc_x >= 0 -> [send/recv]_tag [dst/src]_proc - ! -1 (=0) 0 -> [1,0] [0,0] | 0 0 [1,0] [beg,beg] - ! -1 (=0) 1 -> [0,0] [1,0] | 0 1 [0,0] [end,beg] - ! +1 (=1) 0 -> [0,1] [1,1] | 1 0 [0,1] [end,end] - ! +1 (=1) 1 -> [1,1] [0,1] | 1 1 [1,1] [beg,end] + ! Implements: pbc_loc bc_x >= 0 -> [send/recv]_tag [dst/src]_proc -1 (=0) 0 -> [1,0] [0,0] | 0 0 [1,0] [beg,beg] -1 (=0) 1 + ! -> [0,0] [1,0] | 0 1 [0,0] [end,beg] +1 (=1) 0 -> [0,1] [1,1] | 1 0 [0,1] [end,end] +1 (=1) 1 -> [1,1] [0,1] | 1 1 [1,1] + ! [beg,end] send_tag = f_logical_to_int(.not. f_xor(beg_end_geq_0, pbc_loc == 1)) recv_tag = f_logical_to_int(pbc_loc == 1) @@ -375,7 +346,7 @@ contains #:for mpi_dir in [1, 2, 3] if (mpi_dir == ${mpi_dir}$) then #:if mpi_dir == 1 - $:GPU_PARALLEL_LOOP(collapse=3,private='[j,k,l,r]') + $:GPU_PARALLEL_LOOP(collapse=3,private='[j, k, l, r]') do l = 0, p do k = 0, n do j = 0, buff_size - 1 @@ -386,24 +357,22 @@ contains end do $:END_GPU_PARALLEL_LOOP() #:elif mpi_dir == 2 - $:GPU_PARALLEL_LOOP(collapse=3,private='[j,k,l,r]') + $:GPU_PARALLEL_LOOP(collapse=3,private='[j, k, l, r]') do l = 0, p do k = 0, buff_size - 1 do j = -buff_size, m + buff_size - r = ((j + buff_size) + (m + 2*buff_size + 1)* & - (k + buff_size*l)) + r = ((j + buff_size) + (m + 2*buff_size + 1)*(k + buff_size*l)) ib_buff_send(r) = ib_markers%sf(j, k + pack_offset, l) end do end do end do $:END_GPU_PARALLEL_LOOP() #:else - $:GPU_PARALLEL_LOOP(collapse=3,private='[j,k,l,r]') + $:GPU_PARALLEL_LOOP(collapse=3,private='[j, k, l, r]') do l = 0, buff_size - 1 do k = -buff_size, n + buff_size do j = -buff_size, m + buff_size - r = ((j + buff_size) + (m + 2*buff_size + 1)* & - ((k + buff_size) + (n + 2*buff_size + 1)*l)) + r = ((j + buff_size) + (m + 2*buff_size + 1)*((k + buff_size) + (n + 2*buff_size + 1)*l)) ib_buff_send(r) = ib_markers%sf(j, k, l + pack_offset) end do end do @@ -412,20 +381,16 @@ contains #:endif end if #:endfor - call nvtxEndRange ! Packbuf + call nvtxEndRange ! Packbuf #:for rdma_mpi in [False, True] if (rdma_mpi .eqv. ${'.true.' if rdma_mpi else '.false.'}$) then #:if rdma_mpi #:call GPU_HOST_DATA(use_device_addr='[ib_buff_send, ib_buff_recv]') - call nvtxStartRange("IB-MARKER-SENDRECV-RDMA") - call MPI_SENDRECV( & - ib_buff_send, buffer_count, MPI_INTEGER, dst_proc, send_tag, & - ib_buff_recv, buffer_count, MPI_INTEGER, src_proc, recv_tag, & - MPI_COMM_WORLD, MPI_STATUS_IGNORE, ierr) + call MPI_SENDRECV(ib_buff_send, buffer_count, MPI_INTEGER, dst_proc, send_tag, ib_buff_recv, & + & buffer_count, MPI_INTEGER, src_proc, recv_tag, MPI_COMM_WORLD, MPI_STATUS_IGNORE, ierr) call nvtxEndRange - #:endcall GPU_HOST_DATA $:GPU_WAIT() #:else @@ -434,10 +399,8 @@ contains call nvtxEndRange call nvtxStartRange("IB-MARKER-SENDRECV-NO-RMDA") - call MPI_SENDRECV( & - ib_buff_send, buffer_count, MPI_INTEGER, dst_proc, send_tag, & - ib_buff_recv, buffer_count, MPI_INTEGER, src_proc, recv_tag, & - MPI_COMM_WORLD, MPI_STATUS_IGNORE, ierr) + call MPI_SENDRECV(ib_buff_send, buffer_count, MPI_INTEGER, dst_proc, send_tag, ib_buff_recv, buffer_count, & + & MPI_INTEGER, src_proc, recv_tag, MPI_COMM_WORLD, MPI_STATUS_IGNORE, ierr) call nvtxEndRange call nvtxStartRange("IB-MARKER-HOST2DEV") @@ -452,7 +415,7 @@ contains #:for mpi_dir in [1, 2, 3] if (mpi_dir == ${mpi_dir}$) then #:if mpi_dir == 1 - $:GPU_PARALLEL_LOOP(collapse=3,private='[j,k,l,r]') + $:GPU_PARALLEL_LOOP(collapse=3,private='[j, k, l, r]') do l = 0, p do k = 0, n do j = -buff_size, -1 @@ -463,12 +426,11 @@ contains end do $:END_GPU_PARALLEL_LOOP() #:elif mpi_dir == 2 - $:GPU_PARALLEL_LOOP(collapse=3,private='[j,k,l,r]') + $:GPU_PARALLEL_LOOP(collapse=3,private='[j, k, l, r]') do l = 0, p do k = -buff_size, -1 do j = -buff_size, m + buff_size - r = ((j + buff_size) + (m + 2*buff_size + 1)* & - ((k + buff_size) + buff_size*l)) + r = ((j + buff_size) + (m + 2*buff_size + 1)*((k + buff_size) + buff_size*l)) ib_markers%sf(j, k + unpack_offset, l) = ib_buff_recv(r) end do end do @@ -476,13 +438,12 @@ contains $:END_GPU_PARALLEL_LOOP() #:else ! Unpacking buffer from bc_z%beg - $:GPU_PARALLEL_LOOP(collapse=3,private='[j,k,l,r]') + $:GPU_PARALLEL_LOOP(collapse=3,private='[j, k, l, r]') do l = -buff_size, -1 do k = -buff_size, n + buff_size do j = -buff_size, m + buff_size - r = ((j + buff_size) + (m + 2*buff_size + 1)* & - ((k + buff_size) + (n + 2*buff_size + 1)* & - (l + buff_size))) + r = ((j + buff_size) + (m + 2*buff_size + 1)*((k + buff_size) + (n + 2*buff_size + 1)*(l & + & + buff_size))) ib_markers%sf(j, k, l + unpack_offset) = ib_buff_recv(r) end do end do @@ -496,18 +457,17 @@ contains end subroutine s_mpi_sendrecv_ib_buffers - !> This subroutine adds particles to the transfer list for the MPI - !! communication. - !! @param nBub Current LOCAL number of bubbles - !! @param pos Current position of each bubble - !! @param posPrev Previous position of each bubble (optional, not used - !! for communication of initial condition) + !> This subroutine adds particles to the transfer list for the MPI communication. + !! @param nBub Current LOCAL number of bubbles + !! @param pos Current position of each bubble + !! @param posPrev Previous position of each bubble (optional, not used + !! for communication of initial condition) impure subroutine s_add_particles_to_transfer_list(nBub, pos, posPrev) - integer, intent(in) :: nBub - real(wp), dimension(:, :), intent(in) :: pos, posPrev - integer :: bubID - integer :: i, j, k + integer, intent(in) :: nBub + real(wp), dimension(:,:), intent(in) :: pos, posPrev + integer :: bubID + integer :: i, j, k do k = nidx(3)%beg, nidx(3)%end do j = nidx(2)%beg, nidx(2)%end @@ -530,14 +490,14 @@ contains call s_add_particle_to_direction(k, 0, -1, -1) call s_add_particle_to_direction(k, -1, 0, -1) call s_add_particle_to_direction(k, 0, 0, -1) - elseif (f_crosses_boundary(k, 3, 1, pos, posPrev)) then + else if (f_crosses_boundary(k, 3, 1, pos, posPrev)) then call s_add_particle_to_direction(k, -1, -1, 1) call s_add_particle_to_direction(k, 0, -1, 1) call s_add_particle_to_direction(k, -1, 0, 1) call s_add_particle_to_direction(k, 0, 0, 1) end if end if - elseif (f_crosses_boundary(k, 2, 1, pos, posPrev)) then + else if (f_crosses_boundary(k, 2, 1, pos, posPrev)) then call s_add_particle_to_direction(k, -1, 1, 0) call s_add_particle_to_direction(k, 0, 1, 0) if (p > 0) then @@ -546,7 +506,7 @@ contains call s_add_particle_to_direction(k, 0, 1, -1) call s_add_particle_to_direction(k, -1, 0, -1) call s_add_particle_to_direction(k, 0, 0, -1) - elseif (f_crosses_boundary(k, 3, 1, pos, posPrev)) then + else if (f_crosses_boundary(k, 3, 1, pos, posPrev)) then call s_add_particle_to_direction(k, -1, 1, 1) call s_add_particle_to_direction(k, 0, 1, 1) call s_add_particle_to_direction(k, -1, 0, 1) @@ -558,14 +518,14 @@ contains if (f_crosses_boundary(k, 3, -1, pos, posPrev)) then call s_add_particle_to_direction(k, -1, 0, -1) call s_add_particle_to_direction(k, 0, 0, -1) - elseif (f_crosses_boundary(k, 3, 1, pos, posPrev)) then + else if (f_crosses_boundary(k, 3, 1, pos, posPrev)) then call s_add_particle_to_direction(k, -1, 0, 1) call s_add_particle_to_direction(k, 0, 0, 1) end if end if end if end if - elseif (f_crosses_boundary(k, 1, 1, pos, posPrev)) then + else if (f_crosses_boundary(k, 1, 1, pos, posPrev)) then call s_add_particle_to_direction(k, 1, 0, 0) if (n > 0) then if (f_crosses_boundary(k, 2, -1, pos, posPrev)) then @@ -577,14 +537,14 @@ contains call s_add_particle_to_direction(k, 0, -1, -1) call s_add_particle_to_direction(k, 1, 0, -1) call s_add_particle_to_direction(k, 0, 0, -1) - elseif (f_crosses_boundary(k, 3, 1, pos, posPrev)) then + else if (f_crosses_boundary(k, 3, 1, pos, posPrev)) then call s_add_particle_to_direction(k, 1, -1, 1) call s_add_particle_to_direction(k, 0, -1, 1) call s_add_particle_to_direction(k, 1, 0, 1) call s_add_particle_to_direction(k, 0, 0, 1) end if end if - elseif (f_crosses_boundary(k, 2, 1, pos, posPrev)) then + else if (f_crosses_boundary(k, 2, 1, pos, posPrev)) then call s_add_particle_to_direction(k, 1, 1, 0) call s_add_particle_to_direction(k, 0, 1, 0) if (p > 0) then @@ -593,7 +553,7 @@ contains call s_add_particle_to_direction(k, 0, 1, -1) call s_add_particle_to_direction(k, 1, 0, -1) call s_add_particle_to_direction(k, 0, 0, -1) - elseif (f_crosses_boundary(k, 3, 1, pos, posPrev)) then + else if (f_crosses_boundary(k, 3, 1, pos, posPrev)) then call s_add_particle_to_direction(k, 1, 1, 1) call s_add_particle_to_direction(k, 0, 1, 1) call s_add_particle_to_direction(k, 1, 0, 1) @@ -605,69 +565,68 @@ contains if (f_crosses_boundary(k, 3, -1, pos, posPrev)) then call s_add_particle_to_direction(k, 1, 0, -1) call s_add_particle_to_direction(k, 0, 0, -1) - elseif (f_crosses_boundary(k, 3, 1, pos, posPrev)) then + else if (f_crosses_boundary(k, 3, 1, pos, posPrev)) then call s_add_particle_to_direction(k, 1, 0, 1) call s_add_particle_to_direction(k, 0, 0, 1) end if end if end if end if - elseif (f_crosses_boundary(k, 2, -1, pos, posPrev)) then + else if (f_crosses_boundary(k, 2, -1, pos, posPrev)) then call s_add_particle_to_direction(k, 0, -1, 0) if (p > 0) then if (f_crosses_boundary(k, 3, -1, pos, posPrev)) then call s_add_particle_to_direction(k, 0, -1, -1) call s_add_particle_to_direction(k, 0, 0, -1) - elseif (f_crosses_boundary(k, 3, 1, pos, posPrev)) then + else if (f_crosses_boundary(k, 3, 1, pos, posPrev)) then call s_add_particle_to_direction(k, 0, -1, 1) call s_add_particle_to_direction(k, 0, 0, 1) end if end if - elseif (f_crosses_boundary(k, 2, 1, pos, posPrev)) then + else if (f_crosses_boundary(k, 2, 1, pos, posPrev)) then call s_add_particle_to_direction(k, 0, 1, 0) if (p > 0) then if (f_crosses_boundary(k, 3, -1, pos, posPrev)) then call s_add_particle_to_direction(k, 0, 1, -1) call s_add_particle_to_direction(k, 0, 0, -1) - elseif (f_crosses_boundary(k, 3, 1, pos, posPrev)) then + else if (f_crosses_boundary(k, 3, 1, pos, posPrev)) then call s_add_particle_to_direction(k, 0, 1, 1) call s_add_particle_to_direction(k, 0, 0, 1) end if end if - elseif (p > 0) then + else if (p > 0) then if (f_crosses_boundary(k, 3, -1, pos, posPrev)) then call s_add_particle_to_direction(k, 0, 0, -1) - elseif (f_crosses_boundary(k, 3, 1, pos, posPrev)) then + else if (f_crosses_boundary(k, 3, 1, pos, posPrev)) then call s_add_particle_to_direction(k, 0, 0, 1) end if end if - end do contains logical function f_crosses_boundary(particle_id, dir, loc, pos, posPrev) - integer, intent(in) :: particle_id, dir, loc - real(wp), dimension(:, :), intent(in) :: pos - real(wp), dimension(:, :), optional, intent(in) :: posPrev + integer, intent(in) :: particle_id, dir, loc + real(wp), dimension(:,:), intent(in) :: pos + real(wp), dimension(:,:), optional, intent(in) :: posPrev - if (loc == -1) then ! Beginning of the domain + if (loc == -1) then ! Beginning of the domain if (nidx(dir)%beg == 0) then f_crosses_boundary = .false. return end if - f_crosses_boundary = (posPrev(particle_id, dir) >= pcomm_coords(dir)%beg .and. & - pos(particle_id, dir) < pcomm_coords(dir)%beg) - elseif (loc == 1) then ! End of the domain + f_crosses_boundary = (posPrev(particle_id, dir) >= pcomm_coords(dir)%beg .and. pos(particle_id, & + & dir) < pcomm_coords(dir)%beg) + else if (loc == 1) then ! End of the domain if (nidx(dir)%end == 0) then f_crosses_boundary = .false. return end if - f_crosses_boundary = (posPrev(particle_id, dir) <= pcomm_coords(dir)%end .and. & - pos(particle_id, dir) > pcomm_coords(dir)%end) + f_crosses_boundary = (posPrev(particle_id, dir) <= pcomm_coords(dir)%end .and. pos(particle_id, & + & dir) > pcomm_coords(dir)%end) end if end function f_crosses_boundary @@ -683,46 +642,42 @@ contains end subroutine s_add_particles_to_transfer_list - !> This subroutine performs the MPI communication for lagrangian particles/ - !! bubbles. - !! @param bub_R0 Initial radius of each bubble - !! @param Rmax_stats Maximum radius of each bubble - !! @param Rmin_stats Minimum radius of each bubble - !! @param gas_mg Mass of gas in each bubble - !! @param gas_betaT Heat flux model coefficient for each bubble - !! @param gas_betaC mass flux model coefficient for each bubble - !! @param bub_dphidt Subgrid velocity potential for each bubble - !! @param lag_id Global and local ID of each bubble - !! @param gas_p Pressure of the gas in each bubble - !! @param gas_mv Mass of vapor in each bubble - !! @param rad Radius of each bubble - !! @param rvel Radial velocity of each bubble - !! @param pos Position of each bubble - !! @param posPrev Previous position of each bubble - !! @param vel Velocity of each bubble - !! @param scoord Cell index in real format of each bubble - !! @param drad Radial velocity of each bubble - !! @param drvel Radial acceleration of each bubble - !! @param dgasp Time derivative of gas pressure in each bubble - !! @param dgasmv Time derivative of vapor mass in each bubble - !! @param dpos Time derivative of position of each bubble - !! @param dvel Time derivative of velocity of each bubble - !! @param lag_num_ts Number of stages in time-stepping scheme - !! @param nBubs Local number of bubbles - impure subroutine s_mpi_sendrecv_particles(bub_R0, Rmax_stats, Rmin_stats, gas_mg, gas_betaT, & - gas_betaC, bub_dphidt, lag_id, gas_p, gas_mv, rad, & - rvel, pos, posPrev, vel, scoord, drad, drvel, dgasp, & - dgasmv, dpos, dvel, lag_num_ts, nbubs, dest) - - real(wp), dimension(:) :: bub_R0, Rmax_stats, Rmin_stats, gas_mg, gas_betaT, gas_betaC, bub_dphidt - integer, dimension(:, :) :: lag_id - real(wp), dimension(:, :) :: gas_p, gas_mv, rad, rvel, drad, drvel, dgasp, dgasmv - real(wp), dimension(:, :, :) :: pos, posPrev, vel, scoord, dpos, dvel - integer :: position, bub_id, lag_num_ts, tag, partner, send_tag, recv_tag, nbubs, p_recv_size, dest - - integer :: i, j, k, l, q, r - integer :: req_send, req_recv, ierr !< Generic flag used to identify and report MPI errors - integer :: send_count, send_offset, recv_count, recv_offset + !> This subroutine performs the MPI communication for lagrangian particles/ bubbles. + !! @param bub_R0 Initial radius of each bubble + !! @param Rmax_stats Maximum radius of each bubble + !! @param Rmin_stats Minimum radius of each bubble + !! @param gas_mg Mass of gas in each bubble + !! @param gas_betaT Heat flux model coefficient for each bubble + !! @param gas_betaC mass flux model coefficient for each bubble + !! @param bub_dphidt Subgrid velocity potential for each bubble + !! @param lag_id Global and local ID of each bubble + !! @param gas_p Pressure of the gas in each bubble + !! @param gas_mv Mass of vapor in each bubble + !! @param rad Radius of each bubble + !! @param rvel Radial velocity of each bubble + !! @param pos Position of each bubble + !! @param posPrev Previous position of each bubble + !! @param vel Velocity of each bubble + !! @param scoord Cell index in real format of each bubble + !! @param drad Radial velocity of each bubble + !! @param drvel Radial acceleration of each bubble + !! @param dgasp Time derivative of gas pressure in each bubble + !! @param dgasmv Time derivative of vapor mass in each bubble + !! @param dpos Time derivative of position of each bubble + !! @param dvel Time derivative of velocity of each bubble + !! @param lag_num_ts Number of stages in time-stepping scheme + !! @param nBubs Local number of bubbles + impure subroutine s_mpi_sendrecv_particles(bub_R0, Rmax_stats, Rmin_stats, gas_mg, gas_betaT, gas_betaC, bub_dphidt, lag_id, & + & gas_p, gas_mv, rad, rvel, pos, posPrev, vel, scoord, drad, drvel, dgasp, dgasmv, dpos, dvel, lag_num_ts, nbubs, dest) + + real(wp), dimension(:) :: bub_R0, Rmax_stats, Rmin_stats, gas_mg, gas_betaT, gas_betaC, bub_dphidt + integer, dimension(:,:) :: lag_id + real(wp), dimension(:,:) :: gas_p, gas_mv, rad, rvel, drad, drvel, dgasp, dgasmv + real(wp), dimension(:,:,:) :: pos, posPrev, vel, scoord, dpos, dvel + integer :: position, bub_id, lag_num_ts, tag, partner, send_tag, recv_tag, nbubs, p_recv_size, dest + integer :: i, j, k, l, q, r + integer :: req_send, req_recv, ierr !< Generic flag used to identify and report MPI errors + integer :: send_count, send_offset, recv_count, recv_offset #ifdef MFC_MPI ! Phase 1: Exchange particle counts using non-blocking communication @@ -738,8 +693,8 @@ contains recv_tag = neighbor_tag(i, j, k) recv_count = recv_count + 1 - call MPI_Irecv(p_recv_counts(i, j, k), 1, MPI_INTEGER, partner, recv_tag, & - MPI_COMM_WORLD, recv_requests(recv_count), ierr) + call MPI_Irecv(p_recv_counts(i, j, k), 1, MPI_INTEGER, partner, recv_tag, MPI_COMM_WORLD, recv_requests(recv_count), & + & ierr) end do ! Post all sends @@ -751,8 +706,8 @@ contains send_tag = neighbor_tag(-i, -j, -k) send_count = send_count + 1 - call MPI_Isend(p_send_counts(i, j, k), 1, MPI_INTEGER, partner, send_tag, & - MPI_COMM_WORLD, send_requests(send_count), ierr) + call MPI_Isend(p_send_counts(i, j, k), 1, MPI_INTEGER, partner, send_tag, MPI_COMM_WORLD, send_requests(send_count), & + & ierr) end do ! Wait for all count exchanges to complete @@ -780,8 +735,8 @@ contains recv_tag = neighbor_tag(i, j, k) recv_count = recv_count + 1 - call MPI_Irecv(p_recv_buff(recv_offset), p_recv_size, MPI_PACKED, partner, recv_tag, & - MPI_COMM_WORLD, recv_requests(recv_count), ierr) + call MPI_Irecv(p_recv_buff(recv_offset), p_recv_size, MPI_PACKED, partner, recv_tag, MPI_COMM_WORLD, & + & recv_requests(recv_count), ierr) recv_offsets(l) = recv_offset recv_offset = recv_offset + p_recv_size end if @@ -803,37 +758,57 @@ contains do q = 0, p_send_counts(i, j, k) - 1 bub_id = p_send_ids(i, j, k, q) - call MPI_Pack(lag_id(bub_id, 1), 1, MPI_INTEGER, p_send_buff(send_offset), p_buff_size, position, MPI_COMM_WORLD, ierr) + call MPI_Pack(lag_id(bub_id, 1), 1, MPI_INTEGER, p_send_buff(send_offset), p_buff_size, position, & + & MPI_COMM_WORLD, ierr) call MPI_Pack(bub_R0(bub_id), 1, mpi_p, p_send_buff(send_offset), p_buff_size, position, MPI_COMM_WORLD, ierr) - call MPI_Pack(Rmax_stats(bub_id), 1, mpi_p, p_send_buff(send_offset), p_buff_size, position, MPI_COMM_WORLD, ierr) - call MPI_Pack(Rmin_stats(bub_id), 1, mpi_p, p_send_buff(send_offset), p_buff_size, position, MPI_COMM_WORLD, ierr) + call MPI_Pack(Rmax_stats(bub_id), 1, mpi_p, p_send_buff(send_offset), p_buff_size, position, MPI_COMM_WORLD, & + & ierr) + call MPI_Pack(Rmin_stats(bub_id), 1, mpi_p, p_send_buff(send_offset), p_buff_size, position, MPI_COMM_WORLD, & + & ierr) call MPI_Pack(gas_mg(bub_id), 1, mpi_p, p_send_buff(send_offset), p_buff_size, position, MPI_COMM_WORLD, ierr) - call MPI_Pack(gas_betaT(bub_id), 1, mpi_p, p_send_buff(send_offset), p_buff_size, position, MPI_COMM_WORLD, ierr) - call MPI_Pack(gas_betaC(bub_id), 1, mpi_p, p_send_buff(send_offset), p_buff_size, position, MPI_COMM_WORLD, ierr) - call MPI_Pack(bub_dphidt(bub_id), 1, mpi_p, p_send_buff(send_offset), p_buff_size, position, MPI_COMM_WORLD, ierr) + call MPI_Pack(gas_betaT(bub_id), 1, mpi_p, p_send_buff(send_offset), p_buff_size, position, MPI_COMM_WORLD, & + & ierr) + call MPI_Pack(gas_betaC(bub_id), 1, mpi_p, p_send_buff(send_offset), p_buff_size, position, MPI_COMM_WORLD, & + & ierr) + call MPI_Pack(bub_dphidt(bub_id), 1, mpi_p, p_send_buff(send_offset), p_buff_size, position, MPI_COMM_WORLD, & + & ierr) do r = 1, 2 - call MPI_Pack(gas_p(bub_id, r), 1, mpi_p, p_send_buff(send_offset), p_buff_size, position, MPI_COMM_WORLD, ierr) - call MPI_Pack(gas_mv(bub_id, r), 1, mpi_p, p_send_buff(send_offset), p_buff_size, position, MPI_COMM_WORLD, ierr) - call MPI_Pack(rad(bub_id, r), 1, mpi_p, p_send_buff(send_offset), p_buff_size, position, MPI_COMM_WORLD, ierr) - call MPI_Pack(rvel(bub_id, r), 1, mpi_p, p_send_buff(send_offset), p_buff_size, position, MPI_COMM_WORLD, ierr) - call MPI_Pack(pos(bub_id, :, r), 3, mpi_p, p_send_buff(send_offset), p_buff_size, position, MPI_COMM_WORLD, ierr) - call MPI_Pack(posPrev(bub_id, :, r), 3, mpi_p, p_send_buff(send_offset), p_buff_size, position, MPI_COMM_WORLD, ierr) - call MPI_Pack(vel(bub_id, :, r), 3, mpi_p, p_send_buff(send_offset), p_buff_size, position, MPI_COMM_WORLD, ierr) - call MPI_Pack(scoord(bub_id, :, r), 3, mpi_p, p_send_buff(send_offset), p_buff_size, position, MPI_COMM_WORLD, ierr) + call MPI_Pack(gas_p(bub_id, r), 1, mpi_p, p_send_buff(send_offset), p_buff_size, position, & + & MPI_COMM_WORLD, ierr) + call MPI_Pack(gas_mv(bub_id, r), 1, mpi_p, p_send_buff(send_offset), p_buff_size, position, & + & MPI_COMM_WORLD, ierr) + call MPI_Pack(rad(bub_id, r), 1, mpi_p, p_send_buff(send_offset), p_buff_size, position, MPI_COMM_WORLD, & + & ierr) + call MPI_Pack(rvel(bub_id, r), 1, mpi_p, p_send_buff(send_offset), p_buff_size, position, MPI_COMM_WORLD, & + & ierr) + call MPI_Pack(pos(bub_id,:,r), 3, mpi_p, p_send_buff(send_offset), p_buff_size, position, MPI_COMM_WORLD, & + & ierr) + call MPI_Pack(posPrev(bub_id,:,r), 3, mpi_p, p_send_buff(send_offset), p_buff_size, position, & + & MPI_COMM_WORLD, ierr) + call MPI_Pack(vel(bub_id,:,r), 3, mpi_p, p_send_buff(send_offset), p_buff_size, position, MPI_COMM_WORLD, & + & ierr) + call MPI_Pack(scoord(bub_id,:,r), 3, mpi_p, p_send_buff(send_offset), p_buff_size, position, & + & MPI_COMM_WORLD, ierr) end do do r = 1, lag_num_ts - call MPI_Pack(drad(bub_id, r), 1, mpi_p, p_send_buff(send_offset), p_buff_size, position, MPI_COMM_WORLD, ierr) - call MPI_Pack(drvel(bub_id, r), 1, mpi_p, p_send_buff(send_offset), p_buff_size, position, MPI_COMM_WORLD, ierr) - call MPI_Pack(dgasp(bub_id, r), 1, mpi_p, p_send_buff(send_offset), p_buff_size, position, MPI_COMM_WORLD, ierr) - call MPI_Pack(dgasmv(bub_id, r), 1, mpi_p, p_send_buff(send_offset), p_buff_size, position, MPI_COMM_WORLD, ierr) - call MPI_Pack(dpos(bub_id, :, r), 3, mpi_p, p_send_buff(send_offset), p_buff_size, position, MPI_COMM_WORLD, ierr) - call MPI_Pack(dvel(bub_id, :, r), 3, mpi_p, p_send_buff(send_offset), p_buff_size, position, MPI_COMM_WORLD, ierr) + call MPI_Pack(drad(bub_id, r), 1, mpi_p, p_send_buff(send_offset), p_buff_size, position, MPI_COMM_WORLD, & + & ierr) + call MPI_Pack(drvel(bub_id, r), 1, mpi_p, p_send_buff(send_offset), p_buff_size, position, & + & MPI_COMM_WORLD, ierr) + call MPI_Pack(dgasp(bub_id, r), 1, mpi_p, p_send_buff(send_offset), p_buff_size, position, & + & MPI_COMM_WORLD, ierr) + call MPI_Pack(dgasmv(bub_id, r), 1, mpi_p, p_send_buff(send_offset), p_buff_size, position, & + & MPI_COMM_WORLD, ierr) + call MPI_Pack(dpos(bub_id,:,r), 3, mpi_p, p_send_buff(send_offset), p_buff_size, position, & + & MPI_COMM_WORLD, ierr) + call MPI_Pack(dvel(bub_id,:,r), 3, mpi_p, p_send_buff(send_offset), p_buff_size, position, & + & MPI_COMM_WORLD, ierr) end do end do send_count = send_count + 1 - call MPI_Isend(p_send_buff(send_offset), position, MPI_PACKED, partner, send_tag, & - MPI_COMM_WORLD, send_requests(send_count), ierr) + call MPI_Isend(p_send_buff(send_offset), position, MPI_PACKED, partner, send_tag, MPI_COMM_WORLD, & + & send_requests(send_count), ierr) send_offset = send_offset + position end if end do @@ -856,37 +831,56 @@ contains do q = 0, p_recv_counts(i, j, k) - 1 nbubs = nbubs + 1 bub_id = nbubs - call MPI_Unpack(p_recv_buff(recv_offset), p_recv_size, position, lag_id(bub_id, 1), 1, MPI_INTEGER, MPI_COMM_WORLD, ierr) + call MPI_Unpack(p_recv_buff(recv_offset), p_recv_size, position, lag_id(bub_id, 1), 1, MPI_INTEGER, & + & MPI_COMM_WORLD, ierr) call MPI_Unpack(p_recv_buff(recv_offset), p_recv_size, position, bub_R0(bub_id), 1, mpi_p, MPI_COMM_WORLD, ierr) - call MPI_Unpack(p_recv_buff(recv_offset), p_recv_size, position, Rmax_stats(bub_id), 1, mpi_p, MPI_COMM_WORLD, ierr) - call MPI_Unpack(p_recv_buff(recv_offset), p_recv_size, position, Rmin_stats(bub_id), 1, mpi_p, MPI_COMM_WORLD, ierr) + call MPI_Unpack(p_recv_buff(recv_offset), p_recv_size, position, Rmax_stats(bub_id), 1, mpi_p, & + & MPI_COMM_WORLD, ierr) + call MPI_Unpack(p_recv_buff(recv_offset), p_recv_size, position, Rmin_stats(bub_id), 1, mpi_p, & + & MPI_COMM_WORLD, ierr) call MPI_Unpack(p_recv_buff(recv_offset), p_recv_size, position, gas_mg(bub_id), 1, mpi_p, MPI_COMM_WORLD, ierr) - call MPI_Unpack(p_recv_buff(recv_offset), p_recv_size, position, gas_betaT(bub_id), 1, mpi_p, MPI_COMM_WORLD, ierr) - call MPI_Unpack(p_recv_buff(recv_offset), p_recv_size, position, gas_betaC(bub_id), 1, mpi_p, MPI_COMM_WORLD, ierr) - call MPI_Unpack(p_recv_buff(recv_offset), p_recv_size, position, bub_dphidt(bub_id), 1, mpi_p, MPI_COMM_WORLD, ierr) + call MPI_Unpack(p_recv_buff(recv_offset), p_recv_size, position, gas_betaT(bub_id), 1, mpi_p, MPI_COMM_WORLD, & + & ierr) + call MPI_Unpack(p_recv_buff(recv_offset), p_recv_size, position, gas_betaC(bub_id), 1, mpi_p, MPI_COMM_WORLD, & + & ierr) + call MPI_Unpack(p_recv_buff(recv_offset), p_recv_size, position, bub_dphidt(bub_id), 1, mpi_p, & + & MPI_COMM_WORLD, ierr) do r = 1, 2 - call MPI_Unpack(p_recv_buff(recv_offset), p_recv_size, position, gas_p(bub_id, r), 1, mpi_p, MPI_COMM_WORLD, ierr) - call MPI_Unpack(p_recv_buff(recv_offset), p_recv_size, position, gas_mv(bub_id, r), 1, mpi_p, MPI_COMM_WORLD, ierr) - call MPI_Unpack(p_recv_buff(recv_offset), p_recv_size, position, rad(bub_id, r), 1, mpi_p, MPI_COMM_WORLD, ierr) - call MPI_Unpack(p_recv_buff(recv_offset), p_recv_size, position, rvel(bub_id, r), 1, mpi_p, MPI_COMM_WORLD, ierr) - call MPI_Unpack(p_recv_buff(recv_offset), p_recv_size, position, pos(bub_id, :, r), 3, mpi_p, MPI_COMM_WORLD, ierr) - call MPI_Unpack(p_recv_buff(recv_offset), p_recv_size, position, posPrev(bub_id, :, r), 3, mpi_p, MPI_COMM_WORLD, ierr) - call MPI_Unpack(p_recv_buff(recv_offset), p_recv_size, position, vel(bub_id, :, r), 3, mpi_p, MPI_COMM_WORLD, ierr) - call MPI_Unpack(p_recv_buff(recv_offset), p_recv_size, position, scoord(bub_id, :, r), 3, mpi_p, MPI_COMM_WORLD, ierr) + call MPI_Unpack(p_recv_buff(recv_offset), p_recv_size, position, gas_p(bub_id, r), 1, mpi_p, & + & MPI_COMM_WORLD, ierr) + call MPI_Unpack(p_recv_buff(recv_offset), p_recv_size, position, gas_mv(bub_id, r), 1, mpi_p, & + & MPI_COMM_WORLD, ierr) + call MPI_Unpack(p_recv_buff(recv_offset), p_recv_size, position, rad(bub_id, r), 1, mpi_p, & + & MPI_COMM_WORLD, ierr) + call MPI_Unpack(p_recv_buff(recv_offset), p_recv_size, position, rvel(bub_id, r), 1, mpi_p, & + & MPI_COMM_WORLD, ierr) + call MPI_Unpack(p_recv_buff(recv_offset), p_recv_size, position, pos(bub_id,:,r), 3, mpi_p, & + & MPI_COMM_WORLD, ierr) + call MPI_Unpack(p_recv_buff(recv_offset), p_recv_size, position, posPrev(bub_id,:,r), 3, mpi_p, & + & MPI_COMM_WORLD, ierr) + call MPI_Unpack(p_recv_buff(recv_offset), p_recv_size, position, vel(bub_id,:,r), 3, mpi_p, & + & MPI_COMM_WORLD, ierr) + call MPI_Unpack(p_recv_buff(recv_offset), p_recv_size, position, scoord(bub_id,:,r), 3, mpi_p, & + & MPI_COMM_WORLD, ierr) end do do r = 1, lag_num_ts - call MPI_Unpack(p_recv_buff(recv_offset), p_recv_size, position, drad(bub_id, r), 1, mpi_p, MPI_COMM_WORLD, ierr) - call MPI_Unpack(p_recv_buff(recv_offset), p_recv_size, position, drvel(bub_id, r), 1, mpi_p, MPI_COMM_WORLD, ierr) - call MPI_Unpack(p_recv_buff(recv_offset), p_recv_size, position, dgasp(bub_id, r), 1, mpi_p, MPI_COMM_WORLD, ierr) - call MPI_Unpack(p_recv_buff(recv_offset), p_recv_size, position, dgasmv(bub_id, r), 1, mpi_p, MPI_COMM_WORLD, ierr) - call MPI_Unpack(p_recv_buff(recv_offset), p_recv_size, position, dpos(bub_id, :, r), 3, mpi_p, MPI_COMM_WORLD, ierr) - call MPI_Unpack(p_recv_buff(recv_offset), p_recv_size, position, dvel(bub_id, :, r), 3, mpi_p, MPI_COMM_WORLD, ierr) + call MPI_Unpack(p_recv_buff(recv_offset), p_recv_size, position, drad(bub_id, r), 1, mpi_p, & + & MPI_COMM_WORLD, ierr) + call MPI_Unpack(p_recv_buff(recv_offset), p_recv_size, position, drvel(bub_id, r), 1, mpi_p, & + & MPI_COMM_WORLD, ierr) + call MPI_Unpack(p_recv_buff(recv_offset), p_recv_size, position, dgasp(bub_id, r), 1, mpi_p, & + & MPI_COMM_WORLD, ierr) + call MPI_Unpack(p_recv_buff(recv_offset), p_recv_size, position, dgasmv(bub_id, r), 1, mpi_p, & + & MPI_COMM_WORLD, ierr) + call MPI_Unpack(p_recv_buff(recv_offset), p_recv_size, position, dpos(bub_id,:,r), 3, mpi_p, & + & MPI_COMM_WORLD, ierr) + call MPI_Unpack(p_recv_buff(recv_offset), p_recv_size, position, dvel(bub_id,:,r), 3, mpi_p, & + & MPI_COMM_WORLD, ierr) end do lag_id(bub_id, 2) = bub_id end do recv_offset = recv_offset + p_recv_size end if - end do ! Wait for all sends to complete @@ -901,10 +895,9 @@ contains end subroutine s_mpi_sendrecv_particles - !! This function returns a unique tag for each neighbor based on its position - !! relative to the current process. - !! @param i, j, k Indices of the neighbor in the range [-1, 1] - !! @return tag Unique integer tag for the neighbor + !! This function returns a unique tag for each neighbor based on its position relative to the current process. + !! @param i, j, k Indices of the neighbor in the range [-1, 1] + !! @return tag Unique integer tag for the neighbor integer function neighbor_tag(i, j, k) result(tag) integer, intent(in) :: i, j, k @@ -915,10 +908,10 @@ contains subroutine s_wrap_particle_positions(pos, posPrev, nbubs, dest) - real(wp), dimension(:, :, :) :: pos, posPrev - integer :: nbubs, dest - integer :: i, q - real(wp) :: offset + real(wp), dimension(:,:,:) :: pos, posPrev + integer :: nbubs, dest + integer :: i, q + real(wp) :: offset do i = 1, nbubs if (periodic_bc(1)) then @@ -974,11 +967,12 @@ contains !> @brief Broadcasts random phase numbers from rank 0 to all MPI processes. impure subroutine s_mpi_send_random_number(phi_rn, num_freq) - integer, intent(in) :: num_freq + + integer, intent(in) :: num_freq real(wp), intent(inout), dimension(1:num_freq) :: phi_rn #ifdef MFC_MPI - integer :: ierr !< Generic flag used to identify and report MPI errors + integer :: ierr !< Generic flag used to identify and report MPI errors call MPI_BCAST(phi_rn, num_freq, mpi_p, 0, MPI_COMM_WORLD, ierr) #endif diff --git a/src/simulation/m_muscl.fpp b/src/simulation/m_muscl.fpp index 739800f93a..fbdb324057 100644 --- a/src/simulation/m_muscl.fpp +++ b/src/simulation/m_muscl.fpp @@ -7,42 +7,34 @@ !> @brief MUSCL reconstruction with interface sharpening for contact-preserving advection module m_muscl - use m_derived_types !< Definitions of the derived types - - use m_global_parameters !< Definitions of the global parameters - - use m_variables_conversion !< State variables type conversion procedures + use m_derived_types !< Definitions of the derived types + use m_global_parameters !< Definitions of the global parameters + use m_variables_conversion !< State variables type conversion procedures #ifdef MFC_OpenACC use openacc #endif use m_mpi_proxy - use m_helper - private; public :: s_initialize_muscl_module, & - s_muscl, & - s_finalize_muscl_module, & - s_interface_compression + private; public :: s_initialize_muscl_module, s_muscl, s_finalize_muscl_module, s_interface_compression integer :: v_size $:GPU_DECLARE(create='[v_size]') type(int_bounds_info) :: is1_muscl, is2_muscl, is3_muscl - $:GPU_DECLARE(create='[is1_muscl,is2_muscl,is3_muscl]') - - !> @name The cell-average variables that will be MUSCL-reconstructed. Formerly, they - !! are stored in v_vf. However, they are transferred to v_rs_wsL and v_rs_wsR - !! as to be reshaped (RS) and/or characteristically decomposed. The reshaping - !! allows the muscl procedure to be independent of the coordinate direction of - !! the reconstruction. Lastly, notice that the left (L) and right (R) results - !! of the characteristic decomposition are stored in custom-constructed muscl- - !! stencils (WS) that are annexed to each position of a given scalar field. + $:GPU_DECLARE(create='[is1_muscl, is2_muscl, is3_muscl]') + + !> @name The cell-average variables that will be MUSCL-reconstructed. Formerly, they are stored in v_vf. However, they are + !! transferred to v_rs_wsL and v_rs_wsR as to be reshaped (RS) and/or characteristically decomposed. The reshaping allows the + !! muscl procedure to be independent of the coordinate direction of the reconstruction. Lastly, notice that the left (L) and + !! right (R) results of the characteristic decomposition are stored in custom-constructed muscl- stencils (WS) that are annexed + !! to each position of a given scalar field. !> @{ - real(wp), allocatable, dimension(:, :, :, :) :: v_rs_ws_x_muscl, v_rs_ws_y_muscl, v_rs_ws_z_muscl + real(wp), allocatable, dimension(:,:,:,:) :: v_rs_ws_x_muscl, v_rs_ws_y_muscl, v_rs_ws_z_muscl !> @} - $:GPU_DECLARE(create='[v_rs_ws_x_muscl,v_rs_ws_y_muscl,v_rs_ws_z_muscl]') + $:GPU_DECLARE(create='[v_rs_ws_x_muscl, v_rs_ws_y_muscl, v_rs_ws_z_muscl]') contains @@ -53,7 +45,7 @@ contains if (n == 0) then is2_muscl%beg = 0 else - is2_muscl%beg = -buff_size; + is2_muscl%beg = -buff_size end if is2_muscl%end = n - is2_muscl%beg @@ -66,8 +58,8 @@ contains is3_muscl%end = p - is3_muscl%beg - @:ALLOCATE(v_rs_ws_x_muscl(is1_muscl%beg:is1_muscl%end, & - is2_muscl%beg:is2_muscl%end, is3_muscl%beg:is3_muscl%end, 1:sys_size)) + @:ALLOCATE(v_rs_ws_x_muscl(is1_muscl%beg:is1_muscl%end, is2_muscl%beg:is2_muscl%end, is3_muscl%beg:is3_muscl%end, & + & 1:sys_size)) if (n == 0) return @@ -83,8 +75,8 @@ contains is3_muscl%end = p - is3_muscl%beg - @:ALLOCATE(v_rs_ws_y_muscl(is2_muscl%beg:is2_muscl%end, & - is1_muscl%beg:is1_muscl%end, is3_muscl%beg:is3_muscl%end, 1:sys_size)) + @:ALLOCATE(v_rs_ws_y_muscl(is2_muscl%beg:is2_muscl%end, is1_muscl%beg:is1_muscl%end, is3_muscl%beg:is3_muscl%end, & + & 1:sys_size)) if (p == 0) return @@ -93,31 +85,28 @@ contains is1_muscl%beg = -buff_size; is1_muscl%end = m - is1_muscl%beg is3_muscl%beg = -buff_size; is3_muscl%end = p - is3_muscl%beg - @:ALLOCATE(v_rs_ws_z_muscl(is3_muscl%beg:is3_muscl%end, & - is2_muscl%beg:is2_muscl%end, is1_muscl%beg:is1_muscl%end, 1:sys_size)) + @:ALLOCATE(v_rs_ws_z_muscl(is3_muscl%beg:is3_muscl%end, is2_muscl%beg:is2_muscl%end, is1_muscl%beg:is1_muscl%end, & + & 1:sys_size)) end subroutine s_initialize_muscl_module !> @brief Performs MUSCL reconstruction of left and right cell-boundary values from cell-averaged variables. - subroutine s_muscl(v_vf, vL_rs_vf_x, vL_rs_vf_y, vL_rs_vf_z, vR_rs_vf_x, vR_rs_vf_y, vR_rs_vf_z, & - muscl_dir, & - is1_muscl_d, is2_muscl_d, is3_muscl_d) - - type(scalar_field), dimension(1:), intent(in) :: v_vf - real(wp), dimension(idwbuff(1)%beg:, idwbuff(2)%beg:, idwbuff(3)%beg:, 1:), intent(inout) :: & - vL_rs_vf_x, vL_rs_vf_y, & - vL_rs_vf_z, vR_rs_vf_x, & - vR_rs_vf_y, vR_rs_vf_z - integer, intent(in) :: muscl_dir + subroutine s_muscl(v_vf, vL_rs_vf_x, vL_rs_vf_y, vL_rs_vf_z, vR_rs_vf_x, vR_rs_vf_y, vR_rs_vf_z, muscl_dir, is1_muscl_d, & + & is2_muscl_d, is3_muscl_d) + + type(scalar_field), dimension(1:), intent(in) :: v_vf + real(wp), dimension(idwbuff(1)%beg:,idwbuff(2)%beg:,idwbuff(3)%beg:,1:), intent(inout) :: vL_rs_vf_x, vL_rs_vf_y, & + & vL_rs_vf_z, vR_rs_vf_x, vR_rs_vf_y, vR_rs_vf_z + integer, intent(in) :: muscl_dir type(int_bounds_info), intent(in) :: is1_muscl_d, is2_muscl_d, is3_muscl_d + integer :: j, k, l, i + real(wp) :: slopeL, slopeR, slope - integer :: j, k, l, i - real(wp) :: slopeL, slopeR, slope is1_muscl = is1_muscl_d is2_muscl = is2_muscl_d is3_muscl = is3_muscl_d - $:GPU_UPDATE(device='[is1_muscl,is2_muscl,is3_muscl]') + $:GPU_UPDATE(device='[is1_muscl, is2_muscl, is3_muscl]') if (muscl_order /= 1 .or. dummy) then call s_initialize_muscl(v_vf, muscl_dir) @@ -138,7 +127,7 @@ contains end do $:END_GPU_PARALLEL_LOOP() else if (muscl_dir == 2) then - $:GPU_PARALLEL_LOOP(private='[i,j,k,l]', collapse=4) + $:GPU_PARALLEL_LOOP(private='[i, j, k, l]', collapse=4) do i = 1, ubound(v_vf, 1) do l = is3_muscl%beg, is3_muscl%end do k = is2_muscl%beg, is2_muscl%end @@ -151,7 +140,7 @@ contains end do $:END_GPU_PARALLEL_LOOP() else if (muscl_dir == 3) then - $:GPU_PARALLEL_LOOP(private='[i,j,k,l]', collapse=4) + $:GPU_PARALLEL_LOOP(private='[i, j, k, l]', collapse=4) do i = 1, ubound(v_vf, 1) do l = is3_muscl%beg, is3_muscl%end do k = is2_muscl%beg, is2_muscl%end @@ -170,52 +159,47 @@ contains ! MUSCL Reconstruction #:for MUSCL_DIR, XYZ in [(1, 'x'), (2, 'y'), (3, 'z')] if (muscl_dir == ${MUSCL_DIR}$) then - $:GPU_PARALLEL_LOOP(collapse=4,private='[i,j,k,l,slopeL,slopeR,slope]') + $:GPU_PARALLEL_LOOP(collapse=4,private='[i, j, k, l, slopeL, slopeR, slope]') do l = is3_muscl%beg, is3_muscl%end do k = is2_muscl%beg, is2_muscl%end do j = is1_muscl%beg, is1_muscl%end do i = 1, v_size - - slopeL = v_rs_ws_${XYZ}$_muscl(j + 1, k, l, i) - & - v_rs_ws_${XYZ}$_muscl(j, k, l, i) - slopeR = v_rs_ws_${XYZ}$_muscl(j, k, l, i) - & - v_rs_ws_${XYZ}$_muscl(j - 1, k, l, i) + slopeL = v_rs_ws_${XYZ}$_muscl(j + 1, k, l, i) - v_rs_ws_${XYZ}$_muscl(j, k, l, i) + slopeR = v_rs_ws_${XYZ}$_muscl(j, k, l, i) - v_rs_ws_${XYZ}$_muscl(j - 1, k, l, i) slope = 0._wp - if (muscl_lim == 1) then ! minmod + if (muscl_lim == 1) then ! minmod if (slopeL*slopeR > 1e-9_wp) then slope = min(abs(slopeL), abs(slopeR)) end if if (slopeL < 0._wp) slope = -slope - elseif (muscl_lim == 2) then ! MC + else if (muscl_lim == 2) then ! MC if (slopeL*slopeR > 1e-9_wp) then slope = min(2._wp*abs(slopeL), 2._wp*abs(slopeR)) slope = min(slope, 5e-1_wp*(abs(slopeL) + abs(slopeR))) end if if (slopeL < 0._wp) slope = -slope - elseif (muscl_lim == 3) then ! Van Albada - if (abs(slopeL) > 1e-6_wp .and. abs(slopeR) > 1e-6_wp .and. & - abs(slopeL + slopeR) > 1e-6_wp .and. slopeL*slopeR > 1e-6_wp) then + else if (muscl_lim == 3) then ! Van Albada + if (abs(slopeL) > 1e-6_wp .and. abs(slopeR) > 1e-6_wp .and. abs(slopeL + slopeR) & + & > 1e-6_wp .and. slopeL*slopeR > 1e-6_wp) then slope = ((slopeL + slopeR)*slopeL*slopeR)/(slopeL**2._wp + slopeR**2._wp) end if - elseif (muscl_lim == 4) then ! Van Leer + else if (muscl_lim == 4) then ! Van Leer if (abs(slopeL + slopeR) > 1.e-6_wp .and. slopeL*slopeR > 1.e-6_wp) then slope = 2._wp*slopeL*slopeR/(slopeL + slopeR) end if - elseif (muscl_lim == 5) then ! SUPERBEE + else if (muscl_lim == 5) then ! SUPERBEE if (slopeL*slopeR > 1e-6_wp) then - slope = -1._wp*min(-min(2._wp*abs(slopeL), abs(slopeR)), -min(abs(slopeL), 2._wp*abs(slopeR))) + slope = -1._wp*min(-min(2._wp*abs(slopeL), abs(slopeR)), -min(abs(slopeL), & + & 2._wp*abs(slopeR))) end if end if ! reconstruct from left side - vL_rs_vf_${XYZ}$ (j, k, l, i) = & - v_rs_ws_${XYZ}$_muscl(j, k, l, i) - (5.e-1_wp*slope) + vL_rs_vf_${XYZ}$ (j, k, l, i) = v_rs_ws_${XYZ}$_muscl(j, k, l, i) - (5.e-1_wp*slope) ! reconstruct from the right side - vR_rs_vf_${XYZ}$ (j, k, l, i) = & - v_rs_ws_${XYZ}$_muscl(j, k, l, i) + (5.e-1_wp*slope) - + vR_rs_vf_${XYZ}$ (j, k, l, i) = v_rs_ws_${XYZ}$_muscl(j, k, l, i) + (5.e-1_wp*slope) end do end do end do @@ -226,44 +210,36 @@ contains end if if (int_comp .and. v_size >= advxe) then - call s_interface_compression(vL_rs_vf_x, vL_rs_vf_y, vL_rs_vf_z, & - vR_rs_vf_x, vR_rs_vf_y, vR_rs_vf_z, & - muscl_dir, is1_muscl_d, is2_muscl_d, is3_muscl_d) + call s_interface_compression(vL_rs_vf_x, vL_rs_vf_y, vL_rs_vf_z, vR_rs_vf_x, vR_rs_vf_y, vR_rs_vf_z, muscl_dir, & + & is1_muscl_d, is2_muscl_d, is3_muscl_d) end if end subroutine s_muscl !> @brief Applies THINC interface-compression to sharpen volume-fraction reconstructions at material interfaces. - subroutine s_interface_compression(vL_rs_vf_x, vL_rs_vf_y, vL_rs_vf_z, vR_rs_vf_x, vR_rs_vf_y, vR_rs_vf_z, & - muscl_dir, & - is1_muscl_d, is2_muscl_d, is3_muscl_d) - - real(wp), dimension(idwbuff(1)%beg:, idwbuff(2)%beg:, idwbuff(3)%beg:, 1:), intent(inout) :: & - vL_rs_vf_x, vL_rs_vf_y, & - vL_rs_vf_z, vR_rs_vf_x, & - vR_rs_vf_y, vR_rs_vf_z - integer, intent(in) :: muscl_dir - type(int_bounds_info), intent(in) :: is1_muscl_d, is2_muscl_d, is3_muscl_d + subroutine s_interface_compression(vL_rs_vf_x, vL_rs_vf_y, vL_rs_vf_z, vR_rs_vf_x, vR_rs_vf_y, vR_rs_vf_z, muscl_dir, & + & is1_muscl_d, is2_muscl_d, is3_muscl_d) - integer :: j, k, l - - real(wp) :: aCL, aCR, aC, aTHINC, qmin, qmax, A, B, C, sign, moncon + real(wp), dimension(idwbuff(1)%beg:,idwbuff(2)%beg:,idwbuff(3)%beg:,1:), intent(inout) :: vL_rs_vf_x, vL_rs_vf_y, & + & vL_rs_vf_z, vR_rs_vf_x, vR_rs_vf_y, vR_rs_vf_z + integer, intent(in) :: muscl_dir + type(int_bounds_info), intent(in) :: is1_muscl_d, is2_muscl_d, is3_muscl_d + integer :: j, k, l + real(wp) :: aCL, aCR, aC, aTHINC, qmin, qmax, A, B, C, sign, moncon #:for MUSCL_DIR, XYZ in [(1, 'x'), (2, 'y'), (3, 'z')] if (muscl_dir == ${MUSCL_DIR}$) then - - $:GPU_PARALLEL_LOOP(collapse=3,private='[j,k,l,aCL,aC,aCR,aTHINC,moncon,sign,qmin,qmax]') + $:GPU_PARALLEL_LOOP(collapse=3,private='[j, k, l, aCL, aC, aCR, aTHINC, moncon, sign, qmin, qmax]') do l = is3_muscl%beg, is3_muscl%end do k = is2_muscl%beg, is2_muscl%end do j = is1_muscl%beg, is1_muscl%end - aCL = v_rs_ws_${XYZ}$_muscl(j - 1, k, l, advxb) aC = v_rs_ws_${XYZ}$_muscl(j, k, l, advxb) aCR = v_rs_ws_${XYZ}$_muscl(j + 1, k, l, advxb) moncon = (aCR - aC)*(aC - aCL) - if (aC >= ic_eps .and. aC <= 1._wp - ic_eps .and. moncon > moncon_cutoff) then ! Interface cell + if (aC >= ic_eps .and. aC <= 1._wp - ic_eps .and. moncon > moncon_cutoff) then ! Interface cell if (aCR - aCL > 0._wp) then sign = 1._wp @@ -282,10 +258,10 @@ contains aTHINC = qmin + 5e-1_wp*qmax*(1._wp + sign*A) if (aTHINC < ic_eps) aTHINC = ic_eps if (aTHINC > 1 - ic_eps) aTHINC = 1 - ic_eps - vL_rs_vf_${XYZ}$ (j, k, l, contxb) = vL_rs_vf_${XYZ}$ (j, k, l, contxb)/ & - vL_rs_vf_${XYZ}$ (j, k, l, advxb)*aTHINC - vL_rs_vf_${XYZ}$ (j, k, l, contxe) = vL_rs_vf_${XYZ}$ (j, k, l, contxe)/ & - (1._wp - vL_rs_vf_${XYZ}$ (j, k, l, advxb))*(1._wp - aTHINC) + vL_rs_vf_${XYZ}$ (j, k, l, contxb) = vL_rs_vf_${XYZ}$ (j, k, l, contxb)/vL_rs_vf_${XYZ}$ (j, k, & + & l, advxb)*aTHINC + vL_rs_vf_${XYZ}$ (j, k, l, contxe) = vL_rs_vf_${XYZ}$ (j, k, l, & + & contxe)/(1._wp - vL_rs_vf_${XYZ}$ (j, k, l, advxb))*(1._wp - aTHINC) vL_rs_vf_${XYZ}$ (j, k, l, advxb) = aTHINC vL_rs_vf_${XYZ}$ (j, k, l, advxe) = 1 - aTHINC @@ -293,15 +269,13 @@ contains aTHINC = qmin + 5e-1_wp*qmax*(1._wp + sign*(tanh(ic_beta) + A)/(1._wp + A*tanh(ic_beta))) if (aTHINC < ic_eps) aTHINC = ic_eps if (aTHINC > 1 - ic_eps) aTHINC = 1 - ic_eps - vR_rs_vf_${XYZ}$ (j, k, l, contxb) = vL_rs_vf_${XYZ}$ (j, k, l, contxb)/ & - vL_rs_vf_${XYZ}$ (j, k, l, advxb)*aTHINC - vR_rs_vf_${XYZ}$ (j, k, l, contxe) = vL_rs_vf_${XYZ}$ (j, k, l, contxe)/ & - (1._wp - vL_rs_vf_${XYZ}$ (j, k, l, advxb))*(1._wp - aTHINC) + vR_rs_vf_${XYZ}$ (j, k, l, contxb) = vL_rs_vf_${XYZ}$ (j, k, l, contxb)/vL_rs_vf_${XYZ}$ (j, k, & + & l, advxb)*aTHINC + vR_rs_vf_${XYZ}$ (j, k, l, contxe) = vL_rs_vf_${XYZ}$ (j, k, l, & + & contxe)/(1._wp - vL_rs_vf_${XYZ}$ (j, k, l, advxb))*(1._wp - aTHINC) vR_rs_vf_${XYZ}$ (j, k, l, advxb) = aTHINC vR_rs_vf_${XYZ}$ (j, k, l, advxe) = 1 - aTHINC - end if - end do end do end do @@ -315,20 +289,18 @@ contains subroutine s_initialize_muscl(v_vf, muscl_dir) type(scalar_field), dimension(:), intent(in) :: v_vf - integer, intent(in) :: muscl_dir + integer, intent(in) :: muscl_dir + integer :: j, k, l, q !< Generic loop iterators - integer :: j, k, l, q !< Generic loop iterators + ! Determining the number of cell-average variables which will be muscl-reconstructed and mapping their indical bounds in the + ! x-, y- and z-directions to those in the s1-, s2- and s3-directions as to reshape the inputted data in the coordinate + ! direction of the muscl reconstruction - ! Determining the number of cell-average variables which will be - ! muscl-reconstructed and mapping their indical bounds in the x-, - ! y- and z-directions to those in the s1-, s2- and s3-directions - ! as to reshape the inputted data in the coordinate direction of - ! the muscl reconstruction v_size = ubound(v_vf, 1) $:GPU_UPDATE(device='[v_size]') if (muscl_dir == 1) then - $:GPU_PARALLEL_LOOP(private='[j,k,l,q]', collapse=4) + $:GPU_PARALLEL_LOOP(private='[j, k, l, q]', collapse=4) do j = 1, v_size do q = is3_muscl%beg, is3_muscl%end do l = is2_muscl%beg, is2_muscl%end @@ -345,7 +317,7 @@ contains if (n == 0) return if (muscl_dir == 2) then - $:GPU_PARALLEL_LOOP(private='[j,k,l,q]', collapse=4) + $:GPU_PARALLEL_LOOP(private='[j, k, l, q]', collapse=4) do j = 1, v_size do q = is3_muscl%beg, is3_muscl%end do l = is2_muscl%beg, is2_muscl%end @@ -361,7 +333,7 @@ contains ! Reshaping/Projecting onto Characteristic Fields in z-direction if (p == 0) return if (muscl_dir == 3) then - $:GPU_PARALLEL_LOOP(private='[j,k,l,q]', collapse=4) + $:GPU_PARALLEL_LOOP(private='[j, k, l, q]', collapse=4) do j = 1, v_size do q = is3_muscl%beg, is3_muscl%end do l = is2_muscl%beg, is2_muscl%end @@ -390,4 +362,5 @@ contains @:DEALLOCATE(v_rs_ws_z_muscl) end subroutine s_finalize_muscl_module + end module m_muscl diff --git a/src/simulation/m_pressure_relaxation.fpp b/src/simulation/m_pressure_relaxation.fpp index 69689de06c..098890499e 100644 --- a/src/simulation/m_pressure_relaxation.fpp +++ b/src/simulation/m_pressure_relaxation.fpp @@ -5,19 +5,19 @@ #:include 'case.fpp' #:include 'macros.fpp' -!> @brief Pressure relaxation for the six-equation multi-component model via Newton--Raphson equilibration and volume-fraction correction +!> @brief Pressure relaxation for the six-equation multi-component model via Newton--Raphson equilibration and volume-fraction +!! correction module m_pressure_relaxation - use m_derived_types !< Definitions of the derived types - use m_global_parameters !< Definitions of the global parameters + use m_derived_types !< Definitions of the derived types + use m_global_parameters !< Definitions of the global parameters implicit none - private; public :: s_pressure_relaxation_procedure, & - s_initialize_pressure_relaxation_module, & - s_finalize_pressure_relaxation_module + private; public :: s_pressure_relaxation_procedure, s_initialize_pressure_relaxation_module, & + & s_finalize_pressure_relaxation_module - real(wp), allocatable, dimension(:, :) :: Res_pr + real(wp), allocatable, dimension(:,:) :: Res_pr $:GPU_DECLARE(create='[Res_pr]') contains @@ -53,9 +53,9 @@ contains subroutine s_pressure_relaxation_procedure(q_cons_vf) type(scalar_field), dimension(sys_size), intent(inout) :: q_cons_vf - integer :: j, k, l + integer :: j, k, l - $:GPU_PARALLEL_LOOP(private='[j,k,l]', collapse=3) + $:GPU_PARALLEL_LOOP(private='[j, k, l]', collapse=3) do l = 0, p do k = 0, n do j = 0, m @@ -69,10 +69,11 @@ contains !> Process pressure relaxation for a single cell subroutine s_relax_cell_pressure(q_cons_vf, j, k, l) + $:GPU_ROUTINE(parallelism='[seq]') type(scalar_field), dimension(sys_size), intent(inout) :: q_cons_vf - integer, intent(in) :: j, k, l + integer, intent(in) :: j, k, l ! Volume fraction correction if (mpp_lim) call s_correct_volume_fractions(q_cons_vf, j, k, l) @@ -89,11 +90,12 @@ contains !> Check if pressure relaxation is needed for this cell logical function s_needs_pressure_relaxation(q_cons_vf, j, k, l) + $:GPU_ROUTINE(parallelism='[seq]') type(scalar_field), dimension(sys_size), intent(in) :: q_cons_vf - integer, intent(in) :: j, k, l - integer :: i + integer, intent(in) :: j, k, l + integer :: i s_needs_pressure_relaxation = .true. $:GPU_LOOP(parallelism='[seq]') @@ -107,24 +109,23 @@ contains !> Correct volume fractions to physical bounds subroutine s_correct_volume_fractions(q_cons_vf, j, k, l) + $:GPU_ROUTINE(parallelism='[seq]') type(scalar_field), dimension(sys_size), intent(inout) :: q_cons_vf - integer, intent(in) :: j, k, l - real(wp) :: sum_alpha - integer :: i + integer, intent(in) :: j, k, l + real(wp) :: sum_alpha + integer :: i sum_alpha = 0._wp $:GPU_LOOP(parallelism='[seq]') do i = 1, num_fluids - if ((q_cons_vf(i + contxb - 1)%sf(j, k, l) < 0._wp) .or. & - (q_cons_vf(i + advxb - 1)%sf(j, k, l) < 0._wp)) then + if ((q_cons_vf(i + contxb - 1)%sf(j, k, l) < 0._wp) .or. (q_cons_vf(i + advxb - 1)%sf(j, k, l) < 0._wp)) then q_cons_vf(i + contxb - 1)%sf(j, k, l) = 0._wp q_cons_vf(i + advxb - 1)%sf(j, k, l) = 0._wp q_cons_vf(i + intxb - 1)%sf(j, k, l) = 0._wp end if - if (q_cons_vf(i + advxb - 1)%sf(j, k, l) > 1._wp) & - q_cons_vf(i + advxb - 1)%sf(j, k, l) = 1._wp + if (q_cons_vf(i + advxb - 1)%sf(j, k, l) > 1._wp) q_cons_vf(i + advxb - 1)%sf(j, k, l) = 1._wp sum_alpha = sum_alpha + q_cons_vf(i + advxb - 1)%sf(j, k, l) end do @@ -137,30 +138,29 @@ contains !> Main pressure equilibration using Newton-Raphson subroutine s_equilibrate_pressure(q_cons_vf, j, k, l) + $:GPU_ROUTINE(parallelism='[seq]') type(scalar_field), dimension(sys_size), intent(inout) :: q_cons_vf - integer, intent(in) :: j, k, l - - real(wp) :: pres_relax, f_pres, df_pres + integer, intent(in) :: j, k, l + real(wp) :: pres_relax, f_pres, df_pres #:if not MFC_CASE_OPTIMIZATION and USING_AMD real(wp), dimension(3) :: pres_K_init, rho_K_s #:else real(wp), dimension(num_fluids) :: pres_K_init, rho_K_s #:endif - integer, parameter :: MAX_ITER = 50 + integer, parameter :: MAX_ITER = 50 real(wp), parameter :: TOLERANCE = 1.e-10_wp - integer :: iter, i + integer :: iter, i ! Initialize pressures pres_relax = 0._wp $:GPU_LOOP(parallelism='[seq]') do i = 1, num_fluids if (q_cons_vf(i + advxb - 1)%sf(j, k, l) > sgm_eps) then - pres_K_init(i) = (q_cons_vf(i + intxb - 1)%sf(j, k, l)/ & - q_cons_vf(i + advxb - 1)%sf(j, k, l) - pi_infs(i))/gammas(i) - if (pres_K_init(i) <= -(1._wp - 1.e-8_wp)*ps_inf(i) + 1.e-8_wp) & - pres_K_init(i) = -(1._wp - 1.e-8_wp)*ps_inf(i) + 1.e-8_wp + pres_K_init(i) = (q_cons_vf(i + intxb - 1)%sf(j, k, l)/q_cons_vf(i + advxb - 1)%sf(j, k, l) - pi_infs(i))/gammas(i) + if (pres_K_init(i) <= -(1._wp - 1.e-8_wp)*ps_inf(i) + 1.e-8_wp) pres_K_init(i) = -(1._wp - 1.e-8_wp)*ps_inf(i) & + & + 1.e-8_wp else pres_K_init(i) = 0._wp end if @@ -177,8 +177,8 @@ contains ! Enforce pressure bounds do i = 1, num_fluids - if (pres_relax <= -(1._wp - 1.e-8_wp)*ps_inf(i) + 1.e-8_wp) & - pres_relax = -(1._wp - 1.e-8_wp)*ps_inf(i) + 1.e-8_wp + if (pres_relax <= -(1._wp - 1.e-8_wp)*ps_inf(i) + 1.e-8_wp) pres_relax = -(1._wp - 1.e-8_wp)*ps_inf(i) & + & + 1.e-8_wp end do ! Newton-Raphson step @@ -187,13 +187,10 @@ contains $:GPU_LOOP(parallelism='[seq]') do i = 1, num_fluids if (q_cons_vf(i + advxb - 1)%sf(j, k, l) > sgm_eps) then - rho_K_s(i) = q_cons_vf(i + contxb - 1)%sf(j, k, l)/ & - max(q_cons_vf(i + advxb - 1)%sf(j, k, l), sgm_eps) & - *((pres_relax + ps_inf(i))/(pres_K_init(i) + & - ps_inf(i)))**(1._wp/gs_min(i)) + rho_K_s(i) = q_cons_vf(i + contxb - 1)%sf(j, k, l)/max(q_cons_vf(i + advxb - 1)%sf(j, k, l), & + & sgm_eps)*((pres_relax + ps_inf(i))/(pres_K_init(i) + ps_inf(i)))**(1._wp/gs_min(i)) f_pres = f_pres + q_cons_vf(i + contxb - 1)%sf(j, k, l)/rho_K_s(i) - df_pres = df_pres - q_cons_vf(i + contxb - 1)%sf(j, k, l) & - /(gs_min(i)*rho_K_s(i)*(pres_relax + ps_inf(i))) + df_pres = df_pres - q_cons_vf(i + contxb - 1)%sf(j, k, l)/(gs_min(i)*rho_K_s(i)*(pres_relax + ps_inf(i))) end if end do end if @@ -202,26 +199,27 @@ contains ! Update volume fractions $:GPU_LOOP(parallelism='[seq]') do i = 1, num_fluids - if (q_cons_vf(i + advxb - 1)%sf(j, k, l) > sgm_eps) & - q_cons_vf(i + advxb - 1)%sf(j, k, l) = q_cons_vf(i + contxb - 1)%sf(j, k, l)/rho_K_s(i) + if (q_cons_vf(i + advxb - 1)%sf(j, k, l) > sgm_eps) q_cons_vf(i + advxb - 1)%sf(j, k, & + & l) = q_cons_vf(i + contxb - 1)%sf(j, k, l)/rho_K_s(i) end do end subroutine s_equilibrate_pressure !> Correct internal energies using equilibrated pressure subroutine s_correct_internal_energies(q_cons_vf, j, k, l) + $:GPU_ROUTINE(parallelism='[seq]') type(scalar_field), dimension(sys_size), intent(inout) :: q_cons_vf - integer, intent(in) :: j, k, l + integer, intent(in) :: j, k, l #:if not MFC_CASE_OPTIMIZATION and USING_AMD real(wp), dimension(2) :: alpha_rho, alpha #:else real(wp), dimension(num_fluids) :: alpha_rho, alpha #:endif - real(wp) :: rho, dyn_pres, gamma, pi_inf, pres_relax, sum_alpha + real(wp) :: rho, dyn_pres, gamma, pi_inf, pres_relax, sum_alpha real(wp), dimension(2) :: Re - integer :: i, q + integer :: i, q $:GPU_LOOP(parallelism='[seq]') do i = 1, num_fluids @@ -291,16 +289,14 @@ contains dyn_pres = 0._wp $:GPU_LOOP(parallelism='[seq]') do i = momxb, momxe - dyn_pres = dyn_pres + 5.e-1_wp*q_cons_vf(i)%sf(j, k, l)* & - q_cons_vf(i)%sf(j, k, l)/max(rho, sgm_eps) + dyn_pres = dyn_pres + 5.e-1_wp*q_cons_vf(i)%sf(j, k, l)*q_cons_vf(i)%sf(j, k, l)/max(rho, sgm_eps) end do pres_relax = (q_cons_vf(E_idx)%sf(j, k, l) - dyn_pres - pi_inf)/gamma $:GPU_LOOP(parallelism='[seq]') do i = 1, num_fluids - q_cons_vf(i + intxb - 1)%sf(j, k, l) = & - q_cons_vf(i + advxb - 1)%sf(j, k, l)*(gammas(i)*pres_relax + pi_infs(i)) + q_cons_vf(i + intxb - 1)%sf(j, k, l) = q_cons_vf(i + advxb - 1)%sf(j, k, l)*(gammas(i)*pres_relax + pi_infs(i)) end do end subroutine s_correct_internal_energies diff --git a/src/simulation/m_qbmm.fpp b/src/simulation/m_qbmm.fpp index d081b8f83e..491985f7ed 100644 --- a/src/simulation/m_qbmm.fpp +++ b/src/simulation/m_qbmm.fpp @@ -8,23 +8,18 @@ !> @brief Quadrature-based moment methods (QBMM) for polydisperse bubble moment inversion and transport module m_qbmm - use m_derived_types !< Definitions of the derived types - - use m_global_parameters !< Definitions of the global parameters - - use m_mpi_proxy !< Message passing interface (MPI) module proxy - - use m_variables_conversion !< State variables type conversion procedures - - use m_helper_basic !< Functions to compare floating point numbers - + use m_derived_types !< Definitions of the derived types + use m_global_parameters !< Definitions of the global parameters + use m_mpi_proxy !< Message passing interface (MPI) module proxy + use m_variables_conversion !< State variables type conversion procedures + use m_helper_basic !< Functions to compare floating point numbers use m_helper implicit none private; public :: s_initialize_qbmm_module, s_mom_inv, s_coeff, s_compute_qbmm_rhs - real(wp), allocatable, dimension(:, :, :, :, :) :: momrhs + real(wp), allocatable, dimension(:,:,:,:,:) :: momrhs $:GPU_DECLARE(create='[momrhs]') #:if MFC_CASE_OPTIMIZATION @@ -35,11 +30,11 @@ module m_qbmm #:endif type(int_bounds_info) :: is1_qbmm, is2_qbmm, is3_qbmm - $:GPU_DECLARE(create='[is1_qbmm,is2_qbmm,is3_qbmm]') + $:GPU_DECLARE(create='[is1_qbmm, is2_qbmm, is3_qbmm]') - integer, allocatable, dimension(:) :: bubrs_qbmm - integer, allocatable, dimension(:, :) :: bubmoms - $:GPU_DECLARE(create='[bubrs_qbmm,bubmoms]') + integer, allocatable, dimension(:) :: bubrs_qbmm + integer, allocatable, dimension(:,:) :: bubmoms + $:GPU_DECLARE(create='[bubrs_qbmm, bubmoms]') contains @@ -49,7 +44,6 @@ contains integer :: i1, i2, q, i, j #:if not MFC_CASE_OPTIMIZATION - if (bubble_model == 2) then ! Keller-Miksis without viscosity/surface tension nterms = 32 @@ -60,336 +54,330 @@ contains $:GPU_ENTER_DATA(copyin='[nterms]') $:GPU_UPDATE(device='[nterms]') - #:endif @:ALLOCATE(momrhs(1:3, 0:2, 0:2, 1:nterms, 1:nb)) momrhs = 0._wp - ! Assigns the required RHS moments for moment transport equations - ! The rhs%(:,3) is only to be used for R0 quadrature, not for computing X/Y indices - ! Accounts for different governing equations in polytropic and non-polytropic models + ! Assigns the required RHS moments for moment transport equations The rhs%(:,3) is only to be used for R0 quadrature, not + ! for computing X/Y indices Accounts for different governing equations in polytropic and non-polytropic models if (.not. polytropic) then do q = 1, nb do i1 = 0, 2; do i2 = 0, 2 - if ((i1 + i2) <= 2) then - if (bubble_model == 3) then - momrhs(1, i1, i2, 1, q) = -1._wp + i1 - momrhs(2, i1, i2, 1, q) = -1._wp + i2 - momrhs(3, i1, i2, 1, q) = 0._wp - - momrhs(1, i1, i2, 2, q) = -1._wp + i1 - momrhs(2, i1, i2, 2, q) = 1._wp + i2 - momrhs(3, i1, i2, 2, q) = 0._wp - - momrhs(1, i1, i2, 3, q) = -1._wp + i1 - momrhs(2, i1, i2, 3, q) = -1._wp + i2 - momrhs(3, i1, i2, 3, q) = 0._wp - - momrhs(1, i1, i2, 4, q) = -1._wp + i1 - momrhs(2, i1, i2, 4, q) = 1._wp + i2 - momrhs(3, i1, i2, 4, q) = 0._wp - - if (.not. f_is_default(Re_inv)) then - ! add viscosity - momrhs(1, i1, i2, 5, q) = -2._wp + i1 - momrhs(2, i1, i2, 5, q) = i2 - momrhs(3, i1, i2, 5, q) = 0._wp - end if - - if (.not. f_is_default(Web)) then - ! add surface tension - momrhs(1, i1, i2, 6, q) = -2._wp + i1 - momrhs(2, i1, i2, 6, q) = -1._wp + i2 - momrhs(3, i1, i2, 6, q) = 0._wp - end if - - momrhs(1, i1, i2, 7, q) = -1._wp + i1 - momrhs(2, i1, i2, 7, q) = -1._wp + i2 - momrhs(3, i1, i2, 7, q) = 0._wp - - else if (bubble_model == 2) then - ! KM with approximation of 1/(1-V/C) = 1+V/C - momrhs(1, i1, i2, 1, q) = -1._wp + i1 - momrhs(2, i1, i2, 1, q) = 1._wp + i2 - momrhs(3, i1, i2, 1, q) = 0._wp + if ((i1 + i2) <= 2) then + if (bubble_model == 3) then + momrhs(1, i1, i2, 1, q) = -1._wp + i1 + momrhs(2, i1, i2, 1, q) = -1._wp + i2 + momrhs(3, i1, i2, 1, q) = 0._wp - momrhs(1, i1, i2, 2, q) = -1._wp + i1 - momrhs(2, i1, i2, 2, q) = 2._wp + i2 - momrhs(3, i1, i2, 2, q) = 0._wp + momrhs(1, i1, i2, 2, q) = -1._wp + i1 + momrhs(2, i1, i2, 2, q) = 1._wp + i2 + momrhs(3, i1, i2, 2, q) = 0._wp - momrhs(1, i1, i2, 3, q) = -1._wp + i1 - momrhs(2, i1, i2, 3, q) = 3._wp + i2 - momrhs(3, i1, i2, 3, q) = 0._wp + momrhs(1, i1, i2, 3, q) = -1._wp + i1 + momrhs(2, i1, i2, 3, q) = -1._wp + i2 + momrhs(3, i1, i2, 3, q) = 0._wp - momrhs(1, i1, i2, 4, q) = -1._wp + i1 - momrhs(2, i1, i2, 4, q) = -1._wp + i2 - momrhs(3, i1, i2, 4, q) = 0._wp + momrhs(1, i1, i2, 4, q) = -1._wp + i1 + momrhs(2, i1, i2, 4, q) = 1._wp + i2 + momrhs(3, i1, i2, 4, q) = 0._wp - momrhs(1, i1, i2, 5, q) = -1._wp + i1 + if (.not. f_is_default(Re_inv)) then + ! add viscosity + momrhs(1, i1, i2, 5, q) = -2._wp + i1 momrhs(2, i1, i2, 5, q) = i2 momrhs(3, i1, i2, 5, q) = 0._wp + end if - momrhs(1, i1, i2, 6, q) = -1._wp + i1 - momrhs(2, i1, i2, 6, q) = 1._wp + i2 + if (.not. f_is_default(Web)) then + ! add surface tension + momrhs(1, i1, i2, 6, q) = -2._wp + i1 + momrhs(2, i1, i2, 6, q) = -1._wp + i2 momrhs(3, i1, i2, 6, q) = 0._wp + end if - momrhs(1, i1, i2, 7, q) = -1._wp + i1 - momrhs(2, i1, i2, 7, q) = -1._wp + i2 - momrhs(3, i1, i2, 7, q) = 0._wp - - momrhs(1, i1, i2, 8, q) = -1._wp + i1 - momrhs(2, i1, i2, 8, q) = i2 - momrhs(3, i1, i2, 8, q) = 0._wp - - momrhs(1, i1, i2, 9, q) = -1._wp + i1 - momrhs(2, i1, i2, 9, q) = 1._wp + i2 - momrhs(3, i1, i2, 9, q) = 0._wp - - momrhs(1, i1, i2, 10, q) = -1._wp + i1 - momrhs(2, i1, i2, 10, q) = i2 - momrhs(3, i1, i2, 10, q) = 0._wp - - momrhs(1, i1, i2, 11, q) = -1._wp + i1 - momrhs(2, i1, i2, 11, q) = 1._wp + i2 - momrhs(3, i1, i2, 11, q) = 0._wp - - momrhs(1, i1, i2, 12, q) = -1._wp + i1 - momrhs(2, i1, i2, 12, q) = 1._wp + i2 - momrhs(3, i1, i2, 12, q) = 0._wp - - momrhs(1, i1, i2, 13, q) = -1._wp + i1 - momrhs(2, i1, i2, 13, q) = -1._wp + i2 - momrhs(3, i1, i2, 13, q) = 0._wp - - momrhs(1, i1, i2, 14, q) = -1._wp + i1 - momrhs(2, i1, i2, 14, q) = i2 - momrhs(3, i1, i2, 14, q) = 0._wp - - momrhs(1, i1, i2, 15, q) = -1._wp + i1 - momrhs(2, i1, i2, 15, q) = 1._wp + i2 - momrhs(3, i1, i2, 15, q) = 0._wp - - momrhs(1, i1, i2, 16, q) = -2._wp + i1 - momrhs(2, i1, i2, 16, q) = i2 - momrhs(3, i1, i2, 16, q) = 0._wp - - momrhs(1, i1, i2, 17, q) = -2._wp + i1 - momrhs(2, i1, i2, 17, q) = -1._wp + i2 - momrhs(3, i1, i2, 17, q) = 0._wp - - momrhs(1, i1, i2, 18, q) = -2._wp + i1 - momrhs(2, i1, i2, 18, q) = 1._wp + i2 - momrhs(3, i1, i2, 18, q) = 0._wp - - momrhs(1, i1, i2, 19, q) = -2._wp + i1 - momrhs(2, i1, i2, 19, q) = 2._wp + i2 - momrhs(3, i1, i2, 19, q) = 0._wp - - momrhs(1, i1, i2, 20, q) = -2._wp + i1 - momrhs(2, i1, i2, 20, q) = -1._wp + i2 - momrhs(3, i1, i2, 20, q) = 0._wp + momrhs(1, i1, i2, 7, q) = -1._wp + i1 + momrhs(2, i1, i2, 7, q) = -1._wp + i2 + momrhs(3, i1, i2, 7, q) = 0._wp + else if (bubble_model == 2) then + ! KM with approximation of 1/(1-V/C) = 1+V/C + momrhs(1, i1, i2, 1, q) = -1._wp + i1 + momrhs(2, i1, i2, 1, q) = 1._wp + i2 + momrhs(3, i1, i2, 1, q) = 0._wp - momrhs(1, i1, i2, 21, q) = -2._wp + i1 - momrhs(2, i1, i2, 21, q) = i2 - momrhs(3, i1, i2, 21, q) = 0._wp + momrhs(1, i1, i2, 2, q) = -1._wp + i1 + momrhs(2, i1, i2, 2, q) = 2._wp + i2 + momrhs(3, i1, i2, 2, q) = 0._wp - momrhs(1, i1, i2, 22, q) = -2._wp + i1 - momrhs(2, i1, i2, 22, q) = -1._wp + i2 - momrhs(3, i1, i2, 22, q) = 0._wp + momrhs(1, i1, i2, 3, q) = -1._wp + i1 + momrhs(2, i1, i2, 3, q) = 3._wp + i2 + momrhs(3, i1, i2, 3, q) = 0._wp - momrhs(1, i1, i2, 23, q) = -2._wp + i1 - momrhs(2, i1, i2, 23, q) = i2 - momrhs(3, i1, i2, 23, q) = 0._wp + momrhs(1, i1, i2, 4, q) = -1._wp + i1 + momrhs(2, i1, i2, 4, q) = -1._wp + i2 + momrhs(3, i1, i2, 4, q) = 0._wp - momrhs(1, i1, i2, 24, q) = -3._wp + i1 - momrhs(2, i1, i2, 24, q) = i2 - momrhs(3, i1, i2, 24, q) = 0._wp + momrhs(1, i1, i2, 5, q) = -1._wp + i1 + momrhs(2, i1, i2, 5, q) = i2 + momrhs(3, i1, i2, 5, q) = 0._wp - momrhs(1, i1, i2, 25, q) = -3._wp + i1 - momrhs(2, i1, i2, 25, q) = -1._wp + i2 - momrhs(3, i1, i2, 25, q) = 0._wp + momrhs(1, i1, i2, 6, q) = -1._wp + i1 + momrhs(2, i1, i2, 6, q) = 1._wp + i2 + momrhs(3, i1, i2, 6, q) = 0._wp - momrhs(1, i1, i2, 26, q) = -2._wp + i1 - momrhs(2, i1, i2, 26, q) = i2 - momrhs(3, i1, i2, 26, q) = 0._wp + momrhs(1, i1, i2, 7, q) = -1._wp + i1 + momrhs(2, i1, i2, 7, q) = -1._wp + i2 + momrhs(3, i1, i2, 7, q) = 0._wp + + momrhs(1, i1, i2, 8, q) = -1._wp + i1 + momrhs(2, i1, i2, 8, q) = i2 + momrhs(3, i1, i2, 8, q) = 0._wp + + momrhs(1, i1, i2, 9, q) = -1._wp + i1 + momrhs(2, i1, i2, 9, q) = 1._wp + i2 + momrhs(3, i1, i2, 9, q) = 0._wp + + momrhs(1, i1, i2, 10, q) = -1._wp + i1 + momrhs(2, i1, i2, 10, q) = i2 + momrhs(3, i1, i2, 10, q) = 0._wp + + momrhs(1, i1, i2, 11, q) = -1._wp + i1 + momrhs(2, i1, i2, 11, q) = 1._wp + i2 + momrhs(3, i1, i2, 11, q) = 0._wp + + momrhs(1, i1, i2, 12, q) = -1._wp + i1 + momrhs(2, i1, i2, 12, q) = 1._wp + i2 + momrhs(3, i1, i2, 12, q) = 0._wp + + momrhs(1, i1, i2, 13, q) = -1._wp + i1 + momrhs(2, i1, i2, 13, q) = -1._wp + i2 + momrhs(3, i1, i2, 13, q) = 0._wp + + momrhs(1, i1, i2, 14, q) = -1._wp + i1 + momrhs(2, i1, i2, 14, q) = i2 + momrhs(3, i1, i2, 14, q) = 0._wp + + momrhs(1, i1, i2, 15, q) = -1._wp + i1 + momrhs(2, i1, i2, 15, q) = 1._wp + i2 + momrhs(3, i1, i2, 15, q) = 0._wp + + momrhs(1, i1, i2, 16, q) = -2._wp + i1 + momrhs(2, i1, i2, 16, q) = i2 + momrhs(3, i1, i2, 16, q) = 0._wp + + momrhs(1, i1, i2, 17, q) = -2._wp + i1 + momrhs(2, i1, i2, 17, q) = -1._wp + i2 + momrhs(3, i1, i2, 17, q) = 0._wp + + momrhs(1, i1, i2, 18, q) = -2._wp + i1 + momrhs(2, i1, i2, 18, q) = 1._wp + i2 + momrhs(3, i1, i2, 18, q) = 0._wp + + momrhs(1, i1, i2, 19, q) = -2._wp + i1 + momrhs(2, i1, i2, 19, q) = 2._wp + i2 + momrhs(3, i1, i2, 19, q) = 0._wp + + momrhs(1, i1, i2, 20, q) = -2._wp + i1 + momrhs(2, i1, i2, 20, q) = -1._wp + i2 + momrhs(3, i1, i2, 20, q) = 0._wp + + momrhs(1, i1, i2, 21, q) = -2._wp + i1 + momrhs(2, i1, i2, 21, q) = i2 + momrhs(3, i1, i2, 21, q) = 0._wp + + momrhs(1, i1, i2, 22, q) = -2._wp + i1 + momrhs(2, i1, i2, 22, q) = -1._wp + i2 + momrhs(3, i1, i2, 22, q) = 0._wp + + momrhs(1, i1, i2, 23, q) = -2._wp + i1 + momrhs(2, i1, i2, 23, q) = i2 + momrhs(3, i1, i2, 23, q) = 0._wp + + momrhs(1, i1, i2, 24, q) = -3._wp + i1 + momrhs(2, i1, i2, 24, q) = i2 + momrhs(3, i1, i2, 24, q) = 0._wp + + momrhs(1, i1, i2, 25, q) = -3._wp + i1 + momrhs(2, i1, i2, 25, q) = -1._wp + i2 + momrhs(3, i1, i2, 25, q) = 0._wp + + momrhs(1, i1, i2, 26, q) = -2._wp + i1 + momrhs(2, i1, i2, 26, q) = i2 + momrhs(3, i1, i2, 26, q) = 0._wp - momrhs(1, i1, i2, 27, q) = -1._wp + i1 - momrhs(2, i1, i2, 27, q) = -1._wp + i2 - momrhs(3, i1, i2, 27, q) = 0._wp + momrhs(1, i1, i2, 27, q) = -1._wp + i1 + momrhs(2, i1, i2, 27, q) = -1._wp + i2 + momrhs(3, i1, i2, 27, q) = 0._wp - momrhs(1, i1, i2, 28, q) = -1._wp + i1 - momrhs(2, i1, i2, 28, q) = i2 - momrhs(3, i1, i2, 28, q) = 0._wp + momrhs(1, i1, i2, 28, q) = -1._wp + i1 + momrhs(2, i1, i2, 28, q) = i2 + momrhs(3, i1, i2, 28, q) = 0._wp - momrhs(1, i1, i2, 29, q) = -2._wp + i1 - momrhs(2, i1, i2, 29, q) = i2 - momrhs(3, i1, i2, 29, q) = 0._wp + momrhs(1, i1, i2, 29, q) = -2._wp + i1 + momrhs(2, i1, i2, 29, q) = i2 + momrhs(3, i1, i2, 29, q) = 0._wp - momrhs(1, i1, i2, 30, q) = -1._wp + i1 - momrhs(2, i1, i2, 30, q) = -1._wp + i2 - momrhs(3, i1, i2, 30, q) = 0._wp + momrhs(1, i1, i2, 30, q) = -1._wp + i1 + momrhs(2, i1, i2, 30, q) = -1._wp + i2 + momrhs(3, i1, i2, 30, q) = 0._wp - momrhs(1, i1, i2, 31, q) = -1._wp + i1 - momrhs(2, i1, i2, 31, q) = i2 - momrhs(3, i1, i2, 31, q) = 0._wp + momrhs(1, i1, i2, 31, q) = -1._wp + i1 + momrhs(2, i1, i2, 31, q) = i2 + momrhs(3, i1, i2, 31, q) = 0._wp - momrhs(1, i1, i2, 32, q) = -2._wp + i1 - momrhs(2, i1, i2, 32, q) = i2 - momrhs(3, i1, i2, 32, q) = 0._wp - end if + momrhs(1, i1, i2, 32, q) = -2._wp + i1 + momrhs(2, i1, i2, 32, q) = i2 + momrhs(3, i1, i2, 32, q) = 0._wp end if - end do; end do + end if + end do; end do end do - else do q = 1, nb do i1 = 0, 2; do i2 = 0, 2 - if ((i1 + i2) <= 2) then - if (bubble_model == 3) then - momrhs(1, i1, i2, 1, q) = -1._wp + i1 - momrhs(2, i1, i2, 1, q) = -1._wp + i2 - momrhs(3, i1, i2, 1, q) = 0._wp - - momrhs(1, i1, i2, 2, q) = -1._wp + i1 - momrhs(2, i1, i2, 2, q) = 1._wp + i2 - momrhs(3, i1, i2, 2, q) = 0._wp - - momrhs(1, i1, i2, 3, q) = -1._wp + i1 - 3._wp*gam - momrhs(2, i1, i2, 3, q) = -1._wp + i2 - momrhs(3, i1, i2, 3, q) = 3._wp*gam - - momrhs(1, i1, i2, 4, q) = -1._wp + i1 - momrhs(2, i1, i2, 4, q) = 1._wp + i2 - momrhs(3, i1, i2, 4, q) = 0._wp - - if (.not. f_is_default(Re_inv)) then - ! add viscosity - momrhs(1, i1, i2, 5, q) = -2._wp + i1 - momrhs(2, i1, i2, 5, q) = i2 - momrhs(3, i1, i2, 5, q) = 0._wp - end if - - if (.not. f_is_default(Web)) then - ! add surface tension - momrhs(1, i1, i2, 6, q) = -2._wp + i1 - momrhs(2, i1, i2, 6, q) = -1._wp + i2 - momrhs(3, i1, i2, 6, q) = 0._wp - end if - - momrhs(1, i1, i2, 7, q) = -1._wp + i1 - momrhs(2, i1, i2, 7, q) = -1._wp + i2 - momrhs(3, i1, i2, 7, q) = 0._wp - - else if (bubble_model == 2) then - ! KM with approximation of 1/(1-V/C) = 1+V/C - momrhs(1, i1, i2, 1, q) = -1._wp + i1 - momrhs(2, i1, i2, 1, q) = 1._wp + i2 - momrhs(3, i1, i2, 1, q) = 0._wp + if ((i1 + i2) <= 2) then + if (bubble_model == 3) then + momrhs(1, i1, i2, 1, q) = -1._wp + i1 + momrhs(2, i1, i2, 1, q) = -1._wp + i2 + momrhs(3, i1, i2, 1, q) = 0._wp - momrhs(1, i1, i2, 2, q) = -1._wp + i1 - momrhs(2, i1, i2, 2, q) = 2._wp + i2 - momrhs(3, i1, i2, 2, q) = 0._wp + momrhs(1, i1, i2, 2, q) = -1._wp + i1 + momrhs(2, i1, i2, 2, q) = 1._wp + i2 + momrhs(3, i1, i2, 2, q) = 0._wp - momrhs(1, i1, i2, 3, q) = -1._wp + i1 - momrhs(2, i1, i2, 3, q) = 3._wp + i2 - momrhs(3, i1, i2, 3, q) = 0._wp + momrhs(1, i1, i2, 3, q) = -1._wp + i1 - 3._wp*gam + momrhs(2, i1, i2, 3, q) = -1._wp + i2 + momrhs(3, i1, i2, 3, q) = 3._wp*gam - momrhs(1, i1, i2, 4, q) = -1._wp + i1 - momrhs(2, i1, i2, 4, q) = -1._wp + i2 - momrhs(3, i1, i2, 4, q) = 0._wp + momrhs(1, i1, i2, 4, q) = -1._wp + i1 + momrhs(2, i1, i2, 4, q) = 1._wp + i2 + momrhs(3, i1, i2, 4, q) = 0._wp - momrhs(1, i1, i2, 5, q) = -1._wp + i1 + if (.not. f_is_default(Re_inv)) then + ! add viscosity + momrhs(1, i1, i2, 5, q) = -2._wp + i1 momrhs(2, i1, i2, 5, q) = i2 momrhs(3, i1, i2, 5, q) = 0._wp + end if - momrhs(1, i1, i2, 6, q) = -1._wp + i1 - momrhs(2, i1, i2, 6, q) = 1._wp + i2 + if (.not. f_is_default(Web)) then + ! add surface tension + momrhs(1, i1, i2, 6, q) = -2._wp + i1 + momrhs(2, i1, i2, 6, q) = -1._wp + i2 momrhs(3, i1, i2, 6, q) = 0._wp - - momrhs(1, i1, i2, 7, q) = -1._wp + i1 - 3._wp*gam - momrhs(2, i1, i2, 7, q) = -1._wp + i2 - momrhs(3, i1, i2, 7, q) = 3._wp*gam - - momrhs(1, i1, i2, 8, q) = -1._wp + i1 - 3._wp*gam - momrhs(2, i1, i2, 8, q) = i2 - momrhs(3, i1, i2, 8, q) = 3._wp*gam - - momrhs(1, i1, i2, 9, q) = -1._wp + i1 - 3._wp*gam - momrhs(2, i1, i2, 9, q) = 1._wp + i2 - momrhs(3, i1, i2, 9, q) = 3._wp*gam - - momrhs(1, i1, i2, 10, q) = -1._wp + i1 - 3._wp*gam - momrhs(2, i1, i2, 10, q) = i2 - momrhs(3, i1, i2, 10, q) = 3._wp*gam - - momrhs(1, i1, i2, 11, q) = -1._wp + i1 - 3._wp*gam - momrhs(2, i1, i2, 11, q) = 1._wp + i2 - momrhs(3, i1, i2, 11, q) = 3._wp*gam - - momrhs(1, i1, i2, 12, q) = -1._wp + i1 - momrhs(2, i1, i2, 12, q) = 1._wp + i2 - momrhs(3, i1, i2, 12, q) = 0._wp - - momrhs(1, i1, i2, 13, q) = -1._wp + i1 - momrhs(2, i1, i2, 13, q) = -1._wp + i2 - momrhs(3, i1, i2, 13, q) = 0._wp - - momrhs(1, i1, i2, 14, q) = -1._wp + i1 - momrhs(2, i1, i2, 14, q) = i2 - momrhs(3, i1, i2, 14, q) = 0._wp - - momrhs(1, i1, i2, 15, q) = -1._wp + i1 - momrhs(2, i1, i2, 15, q) = 1._wp + i2 - momrhs(3, i1, i2, 15, q) = 0._wp - - momrhs(1, i1, i2, 16, q) = -2._wp + i1 - momrhs(2, i1, i2, 16, q) = i2 - momrhs(3, i1, i2, 16, q) = 0._wp - - momrhs(1, i1, i2, 17, q) = -2._wp + i1 - momrhs(2, i1, i2, 17, q) = -1._wp + i2 - momrhs(3, i1, i2, 17, q) = 0._wp - - momrhs(1, i1, i2, 18, q) = -2._wp + i1 - momrhs(2, i1, i2, 18, q) = 1._wp + i2 - momrhs(3, i1, i2, 18, q) = 0._wp - - momrhs(1, i1, i2, 19, q) = -2._wp + i1 - momrhs(2, i1, i2, 19, q) = 2._wp + i2 - momrhs(3, i1, i2, 19, q) = 0._wp - - momrhs(1, i1, i2, 20, q) = -2._wp + i1 - momrhs(2, i1, i2, 20, q) = -1._wp + i2 - momrhs(3, i1, i2, 20, q) = 0._wp - - momrhs(1, i1, i2, 21, q) = -2._wp + i1 - momrhs(2, i1, i2, 21, q) = i2 - momrhs(3, i1, i2, 21, q) = 0._wp - - momrhs(1, i1, i2, 22, q) = -2._wp + i1 - 3._wp*gam - momrhs(2, i1, i2, 22, q) = -1._wp + i2 - momrhs(3, i1, i2, 22, q) = 3._wp*gam - - momrhs(1, i1, i2, 23, q) = -2._wp + i1 - 3._wp*gam - momrhs(2, i1, i2, 23, q) = i2 - momrhs(3, i1, i2, 23, q) = 3._wp*gam - - momrhs(1, i1, i2, 24, q) = -3._wp + i1 - momrhs(2, i1, i2, 24, q) = i2 - momrhs(3, i1, i2, 24, q) = 0._wp - - momrhs(1, i1, i2, 25, q) = -3._wp + i1 - momrhs(2, i1, i2, 25, q) = -1._wp + i2 - momrhs(3, i1, i2, 25, q) = 0._wp - - momrhs(1, i1, i2, 26, q) = -2._wp + i1 - 3._wp*gam - momrhs(2, i1, i2, 26, q) = i2 - momrhs(3, i1, i2, 26, q) = 3._wp*gam - end if + + momrhs(1, i1, i2, 7, q) = -1._wp + i1 + momrhs(2, i1, i2, 7, q) = -1._wp + i2 + momrhs(3, i1, i2, 7, q) = 0._wp + else if (bubble_model == 2) then + ! KM with approximation of 1/(1-V/C) = 1+V/C + momrhs(1, i1, i2, 1, q) = -1._wp + i1 + momrhs(2, i1, i2, 1, q) = 1._wp + i2 + momrhs(3, i1, i2, 1, q) = 0._wp + + momrhs(1, i1, i2, 2, q) = -1._wp + i1 + momrhs(2, i1, i2, 2, q) = 2._wp + i2 + momrhs(3, i1, i2, 2, q) = 0._wp + + momrhs(1, i1, i2, 3, q) = -1._wp + i1 + momrhs(2, i1, i2, 3, q) = 3._wp + i2 + momrhs(3, i1, i2, 3, q) = 0._wp + + momrhs(1, i1, i2, 4, q) = -1._wp + i1 + momrhs(2, i1, i2, 4, q) = -1._wp + i2 + momrhs(3, i1, i2, 4, q) = 0._wp + + momrhs(1, i1, i2, 5, q) = -1._wp + i1 + momrhs(2, i1, i2, 5, q) = i2 + momrhs(3, i1, i2, 5, q) = 0._wp + + momrhs(1, i1, i2, 6, q) = -1._wp + i1 + momrhs(2, i1, i2, 6, q) = 1._wp + i2 + momrhs(3, i1, i2, 6, q) = 0._wp + + momrhs(1, i1, i2, 7, q) = -1._wp + i1 - 3._wp*gam + momrhs(2, i1, i2, 7, q) = -1._wp + i2 + momrhs(3, i1, i2, 7, q) = 3._wp*gam + + momrhs(1, i1, i2, 8, q) = -1._wp + i1 - 3._wp*gam + momrhs(2, i1, i2, 8, q) = i2 + momrhs(3, i1, i2, 8, q) = 3._wp*gam + + momrhs(1, i1, i2, 9, q) = -1._wp + i1 - 3._wp*gam + momrhs(2, i1, i2, 9, q) = 1._wp + i2 + momrhs(3, i1, i2, 9, q) = 3._wp*gam + + momrhs(1, i1, i2, 10, q) = -1._wp + i1 - 3._wp*gam + momrhs(2, i1, i2, 10, q) = i2 + momrhs(3, i1, i2, 10, q) = 3._wp*gam + + momrhs(1, i1, i2, 11, q) = -1._wp + i1 - 3._wp*gam + momrhs(2, i1, i2, 11, q) = 1._wp + i2 + momrhs(3, i1, i2, 11, q) = 3._wp*gam + + momrhs(1, i1, i2, 12, q) = -1._wp + i1 + momrhs(2, i1, i2, 12, q) = 1._wp + i2 + momrhs(3, i1, i2, 12, q) = 0._wp + + momrhs(1, i1, i2, 13, q) = -1._wp + i1 + momrhs(2, i1, i2, 13, q) = -1._wp + i2 + momrhs(3, i1, i2, 13, q) = 0._wp + + momrhs(1, i1, i2, 14, q) = -1._wp + i1 + momrhs(2, i1, i2, 14, q) = i2 + momrhs(3, i1, i2, 14, q) = 0._wp + + momrhs(1, i1, i2, 15, q) = -1._wp + i1 + momrhs(2, i1, i2, 15, q) = 1._wp + i2 + momrhs(3, i1, i2, 15, q) = 0._wp + + momrhs(1, i1, i2, 16, q) = -2._wp + i1 + momrhs(2, i1, i2, 16, q) = i2 + momrhs(3, i1, i2, 16, q) = 0._wp + + momrhs(1, i1, i2, 17, q) = -2._wp + i1 + momrhs(2, i1, i2, 17, q) = -1._wp + i2 + momrhs(3, i1, i2, 17, q) = 0._wp + + momrhs(1, i1, i2, 18, q) = -2._wp + i1 + momrhs(2, i1, i2, 18, q) = 1._wp + i2 + momrhs(3, i1, i2, 18, q) = 0._wp + + momrhs(1, i1, i2, 19, q) = -2._wp + i1 + momrhs(2, i1, i2, 19, q) = 2._wp + i2 + momrhs(3, i1, i2, 19, q) = 0._wp + + momrhs(1, i1, i2, 20, q) = -2._wp + i1 + momrhs(2, i1, i2, 20, q) = -1._wp + i2 + momrhs(3, i1, i2, 20, q) = 0._wp + + momrhs(1, i1, i2, 21, q) = -2._wp + i1 + momrhs(2, i1, i2, 21, q) = i2 + momrhs(3, i1, i2, 21, q) = 0._wp + + momrhs(1, i1, i2, 22, q) = -2._wp + i1 - 3._wp*gam + momrhs(2, i1, i2, 22, q) = -1._wp + i2 + momrhs(3, i1, i2, 22, q) = 3._wp*gam + + momrhs(1, i1, i2, 23, q) = -2._wp + i1 - 3._wp*gam + momrhs(2, i1, i2, 23, q) = i2 + momrhs(3, i1, i2, 23, q) = 3._wp*gam + + momrhs(1, i1, i2, 24, q) = -3._wp + i1 + momrhs(2, i1, i2, 24, q) = i2 + momrhs(3, i1, i2, 24, q) = 0._wp + + momrhs(1, i1, i2, 25, q) = -3._wp + i1 + momrhs(2, i1, i2, 25, q) = -1._wp + i2 + momrhs(3, i1, i2, 25, q) = 0._wp + + momrhs(1, i1, i2, 26, q) = -2._wp + i1 - 3._wp*gam + momrhs(2, i1, i2, 26, q) = i2 + momrhs(3, i1, i2, 26, q) = 3._wp*gam end if - end do; end do + end if + end do; end do end do end if @@ -415,16 +403,18 @@ contains !> @brief Computes the QBMM right-hand side source terms for bubble moment transport equations. subroutine s_compute_qbmm_rhs(idir, q_cons_vf, q_prim_vf, rhs_vf, flux_n_vf, pb, rhs_pb) - integer, intent(in) :: idir - type(scalar_field), dimension(sys_size), intent(in) :: q_cons_vf, q_prim_vf - type(scalar_field), dimension(sys_size), intent(inout) :: rhs_vf - type(scalar_field), dimension(sys_size), intent(in) :: flux_n_vf - real(stp), dimension(idwbuff(1)%beg:, idwbuff(2)%beg:, idwbuff(3)%beg:, 1:, 1:), intent(inout) :: pb - real(wp), dimension(idwbuff(1)%beg:, idwbuff(2)%beg:, idwbuff(3)%beg:, 1:, 1:), intent(inout) :: rhs_pb ! TODO :: I think that this should be stp as well. + integer, intent(in) :: idir + type(scalar_field), dimension(sys_size), intent(in) :: q_cons_vf, q_prim_vf + type(scalar_field), dimension(sys_size), intent(inout) :: rhs_vf + type(scalar_field), dimension(sys_size), intent(in) :: flux_n_vf + real(stp), dimension(idwbuff(1)%beg:,idwbuff(2)%beg:,idwbuff(3)%beg:,1:,1:), intent(inout) :: pb + + real(wp), dimension(idwbuff(1)%beg:,idwbuff(2)%beg:,idwbuff(3)%beg:,1:,1:), & + & intent(inout) :: rhs_pb ! TODO :: I think that this should be stp as well. - integer :: i, j, k, l, q + integer :: i, j, k, l, q real(wp) :: nb_q, nb_dot, R, R2, nR, nR2, nR_dot, nR2_dot, var, AX - logical :: is_axisym + logical :: is_axisym select case (idir) case (1) @@ -436,7 +426,7 @@ contains end select if (.not. polytropic) then - $:GPU_PARALLEL_LOOP(collapse=5,private='[i,j,k,l,q,nb_q,nR,nR2,R,R2,nb_dot,nR_dot,nR2_dot,var,AX]') + $:GPU_PARALLEL_LOOP(collapse=5,private='[i, j, k, l, q, nb_q, nR, nR2, R, R2, nb_dot, nR_dot, nR2_dot, var, AX]') do i = 1, nb do q = 1, nnode do l = 0, p @@ -456,80 +446,109 @@ contains select case (idir) case (1) - nb_dot = flux_n_vf(bubxb + (i - 1)*nmom)%sf(j - 1, k, l) - flux_n_vf(bubxb + (i - 1)*nmom)%sf(j, k, l) - nR_dot = flux_n_vf(bubxb + 1 + (i - 1)*nmom)%sf(j - 1, k, l) - flux_n_vf(bubxb + 1 + (i - 1)*nmom)%sf(j, k, l) - nR2_dot = flux_n_vf(bubxb + 3 + (i - 1)*nmom)%sf(j - 1, k, l) - flux_n_vf(bubxb + 3 + (i - 1)*nmom)%sf(j, k, l) - rhs_pb(j, k, l, q, i) = rhs_pb(j, k, l, q, i) - 3._wp*gam/(dx(j)*AX*nb_q**2)* & - (nR_dot*nb_q - nR*nb_dot)*(pb(j, k, l, q, i)) + nb_dot = flux_n_vf(bubxb + (i - 1)*nmom)%sf(j - 1, k, & + & l) - flux_n_vf(bubxb + (i - 1)*nmom)%sf(j, k, l) + nR_dot = flux_n_vf(bubxb + 1 + (i - 1)*nmom)%sf(j - 1, k, & + & l) - flux_n_vf(bubxb + 1 + (i - 1)*nmom)%sf(j, k, l) + nR2_dot = flux_n_vf(bubxb + 3 + (i - 1)*nmom)%sf(j - 1, k, & + & l) - flux_n_vf(bubxb + 3 + (i - 1)*nmom)%sf(j, k, l) + rhs_pb(j, k, l, q, i) = rhs_pb(j, k, l, q, & + & i) - 3._wp*gam/(dx(j)*AX*nb_q**2)*(nR_dot*nb_q - nR*nb_dot)*(pb(j, k, l, q, i)) case (2) - nb_dot = flux_n_vf(bubxb + (i - 1)*nmom)%sf(j, k - 1, l) - flux_n_vf(bubxb + (i - 1)*nmom)%sf(j, k, l) - nR_dot = flux_n_vf(bubxb + 1 + (i - 1)*nmom)%sf(j, k - 1, l) - flux_n_vf(bubxb + 1 + (i - 1)*nmom)%sf(j, k, l) - nR2_dot = flux_n_vf(bubxb + 3 + (i - 1)*nmom)%sf(j, k - 1, l) - flux_n_vf(bubxb + 3 + (i - 1)*nmom)%sf(j, k, l) - rhs_pb(j, k, l, q, i) = rhs_pb(j, k, l, q, i) - 3._wp*gam/(dy(k)*AX*nb_q**2)* & - (nR_dot*nb_q - nR*nb_dot)*(pb(j, k, l, q, i)) + nb_dot = flux_n_vf(bubxb + (i - 1)*nmom)%sf(j, k - 1, & + & l) - flux_n_vf(bubxb + (i - 1)*nmom)%sf(j, k, l) + nR_dot = flux_n_vf(bubxb + 1 + (i - 1)*nmom)%sf(j, k - 1, & + & l) - flux_n_vf(bubxb + 1 + (i - 1)*nmom)%sf(j, k, l) + nR2_dot = flux_n_vf(bubxb + 3 + (i - 1)*nmom)%sf(j, k - 1, & + & l) - flux_n_vf(bubxb + 3 + (i - 1)*nmom)%sf(j, k, l) + rhs_pb(j, k, l, q, i) = rhs_pb(j, k, l, q, & + & i) - 3._wp*gam/(dy(k)*AX*nb_q**2)*(nR_dot*nb_q - nR*nb_dot)*(pb(j, k, l, q, i)) case (3) if (is_axisym) then - nb_dot = q_prim_vf(contxe + idir)%sf(j, k, l)*(flux_n_vf(bubxb + (i - 1)*nmom)%sf(j, k, l - 1) - flux_n_vf(bubxb + (i - 1)*nmom)%sf(j, k, l)) - nR_dot = q_prim_vf(contxe + idir)%sf(j, k, l)*(flux_n_vf(bubxb + 1 + (i - 1)*nmom)%sf(j, k, l - 1) - flux_n_vf(bubxb + 1 + (i - 1)*nmom)%sf(j, k, l)) - nR2_dot = q_prim_vf(contxe + idir)%sf(j, k, l)*(flux_n_vf(bubxb + 3 + (i - 1)*nmom)%sf(j, k, l - 1) - flux_n_vf(bubxb + 3 + (i - 1)*nmom)%sf(j, k, l)) - rhs_pb(j, k, l, q, i) = rhs_pb(j, k, l, q, i) - 3._wp*gam/(dz(l)*y_cc(k)*AX*nb_q**2)* & - (nR_dot*nb_q - nR*nb_dot)*(pb(j, k, l, q, i)) + nb_dot = q_prim_vf(contxe + idir)%sf(j, k, l)*(flux_n_vf(bubxb + (i - 1)*nmom)%sf(j, k, & + & l - 1) - flux_n_vf(bubxb + (i - 1)*nmom)%sf(j, k, l)) + nR_dot = q_prim_vf(contxe + idir)%sf(j, k, l)*(flux_n_vf(bubxb + 1 + (i - 1)*nmom)%sf(j, & + & k, l - 1) - flux_n_vf(bubxb + 1 + (i - 1)*nmom)%sf(j, k, l)) + nR2_dot = q_prim_vf(contxe + idir)%sf(j, k, l)*(flux_n_vf(bubxb + 3 + (i - 1)*nmom)%sf(j, & + & k, l - 1) - flux_n_vf(bubxb + 3 + (i - 1)*nmom)%sf(j, k, l)) + rhs_pb(j, k, l, q, i) = rhs_pb(j, k, l, q, & + & i) - 3._wp*gam/(dz(l)*y_cc(k)*AX*nb_q**2)*(nR_dot*nb_q - nR*nb_dot)*(pb(j, k, l, & + & q, i)) else - nb_dot = flux_n_vf(bubxb + (i - 1)*nmom)%sf(j, k, l - 1) - flux_n_vf(bubxb + (i - 1)*nmom)%sf(j, k, l) - nR_dot = flux_n_vf(bubxb + 1 + (i - 1)*nmom)%sf(j, k, l - 1) - flux_n_vf(bubxb + 1 + (i - 1)*nmom)%sf(j, k, l) - nR2_dot = flux_n_vf(bubxb + 3 + (i - 1)*nmom)%sf(j, k, l - 1) - flux_n_vf(bubxb + 3 + (i - 1)*nmom)%sf(j, k, l) - rhs_pb(j, k, l, q, i) = rhs_pb(j, k, l, q, i) - 3._wp*gam/(dz(l)*AX*nb_q**2)* & - (nR_dot*nb_q - nR*nb_dot)*(pb(j, k, l, q, i)) + nb_dot = flux_n_vf(bubxb + (i - 1)*nmom)%sf(j, k, & + & l - 1) - flux_n_vf(bubxb + (i - 1)*nmom)%sf(j, k, l) + nR_dot = flux_n_vf(bubxb + 1 + (i - 1)*nmom)%sf(j, k, & + & l - 1) - flux_n_vf(bubxb + 1 + (i - 1)*nmom)%sf(j, k, l) + nR2_dot = flux_n_vf(bubxb + 3 + (i - 1)*nmom)%sf(j, k, & + & l - 1) - flux_n_vf(bubxb + 3 + (i - 1)*nmom)%sf(j, k, l) + rhs_pb(j, k, l, q, i) = rhs_pb(j, k, l, q, & + & i) - 3._wp*gam/(dz(l)*AX*nb_q**2)*(nR_dot*nb_q - nR*nb_dot)*(pb(j, k, l, q, i)) end if end select if (q <= 2) then select case (idir) case (1) - rhs_pb(j, k, l, q, i) = rhs_pb(j, k, l, q, i) + 3._wp*gam/(dx(j)*AX*nb_q**2*sqrt(var)*2._wp)* & - (nR2_dot*nb_q - nR2*nb_dot)*(pb(j, k, l, q, i)) - rhs_pb(j, k, l, q, i) = rhs_pb(j, k, l, q, i) + 3._wp*gam/(dx(j)*AX*nb_q**2*sqrt(var)*2._wp)* & - (-2._wp*(nR/nb_q)*(nR_dot*nb_q - nR*nb_dot))*(pb(j, k, l, q, i)) + rhs_pb(j, k, l, q, i) = rhs_pb(j, k, l, q, & + & i) + 3._wp*gam/(dx(j)*AX*nb_q**2*sqrt(var)*2._wp)*(nR2_dot*nb_q - nR2*nb_dot) & + & *(pb(j, k, l, q, i)) + rhs_pb(j, k, l, q, i) = rhs_pb(j, k, l, q, & + & i) + 3._wp*gam/(dx(j)*AX*nb_q**2*sqrt(var)*2._wp)*(-2._wp*(nR/nb_q)*(nR_dot*nb_q & + & - nR*nb_dot))*(pb(j, k, l, q, i)) case (2) - rhs_pb(j, k, l, q, i) = rhs_pb(j, k, l, q, i) + 3._wp*gam/(dy(k)*AX*nb_q**2*sqrt(var)*2._wp)* & - (nR2_dot*nb_q - nR2*nb_dot)*(pb(j, k, l, q, i)) - rhs_pb(j, k, l, q, i) = rhs_pb(j, k, l, q, i) + 3._wp*gam/(dy(k)*AX*nb_q**2*sqrt(var)*2._wp)* & - (-2._wp*(nR/nb_q)*(nR_dot*nb_q - nR*nb_dot))*(pb(j, k, l, q, i)) + rhs_pb(j, k, l, q, i) = rhs_pb(j, k, l, q, & + & i) + 3._wp*gam/(dy(k)*AX*nb_q**2*sqrt(var)*2._wp)*(nR2_dot*nb_q - nR2*nb_dot) & + & *(pb(j, k, l, q, i)) + rhs_pb(j, k, l, q, i) = rhs_pb(j, k, l, q, & + & i) + 3._wp*gam/(dy(k)*AX*nb_q**2*sqrt(var)*2._wp)*(-2._wp*(nR/nb_q)*(nR_dot*nb_q & + & - nR*nb_dot))*(pb(j, k, l, q, i)) case (3) if (is_axisym) then - rhs_pb(j, k, l, q, i) = rhs_pb(j, k, l, q, i) + 3._wp*gam/(dz(l)*y_cc(k)*AX*nb_q**2*sqrt(var)*2._wp)* & - (nR2_dot*nb_q - nR2*nb_dot)*(pb(j, k, l, q, i)) - rhs_pb(j, k, l, q, i) = rhs_pb(j, k, l, q, i) + 3._wp*gam/(dz(l)*y_cc(k)*AX*nb_q**2*sqrt(var)*2._wp)* & - (-2._wp*(nR/nb_q)*(nR_dot*nb_q - nR*nb_dot))*(pb(j, k, l, q, i)) + rhs_pb(j, k, l, q, i) = rhs_pb(j, k, l, q, & + & i) + 3._wp*gam/(dz(l)*y_cc(k)*AX*nb_q**2*sqrt(var)*2._wp)*(nR2_dot*nb_q & + & - nR2*nb_dot)*(pb(j, k, l, q, i)) + rhs_pb(j, k, l, q, i) = rhs_pb(j, k, l, q, & + & i) + 3._wp*gam/(dz(l)*y_cc(k)*AX*nb_q**2*sqrt(var)*2._wp)*(-2._wp*(nR/nb_q) & + & *(nR_dot*nb_q - nR*nb_dot))*(pb(j, k, l, q, i)) else - rhs_pb(j, k, l, q, i) = rhs_pb(j, k, l, q, i) + 3._wp*gam/(dz(l)*AX*nb_q**2*sqrt(var)*2._wp)* & - (nR2_dot*nb_q - nR2*nb_dot)*(pb(j, k, l, q, i)) - rhs_pb(j, k, l, q, i) = rhs_pb(j, k, l, q, i) + 3._wp*gam/(dz(l)*AX*nb_q**2*sqrt(var)*2._wp)* & - (-2._wp*(nR/nb_q)*(nR_dot*nb_q - nR*nb_dot))*(pb(j, k, l, q, i)) + rhs_pb(j, k, l, q, i) = rhs_pb(j, k, l, q, & + & i) + 3._wp*gam/(dz(l)*AX*nb_q**2*sqrt(var)*2._wp)*(nR2_dot*nb_q - nR2*nb_dot) & + & *(pb(j, k, l, q, i)) + rhs_pb(j, k, l, q, i) = rhs_pb(j, k, l, q, & + & i) + 3._wp*gam/(dz(l)*AX*nb_q**2*sqrt(var)*2._wp)*(-2._wp*(nR/nb_q) & + & *(nR_dot*nb_q - nR*nb_dot))*(pb(j, k, l, q, i)) end if end select else select case (idir) case (1) - rhs_pb(j, k, l, q, i) = rhs_pb(j, k, l, q, i) - 3._wp*gam/(dx(j)*AX*nb_q**2*sqrt(var)*2._wp)* & - (nR2_dot*nb_q - nR2*nb_dot)*(pb(j, k, l, q, i)) - rhs_pb(j, k, l, q, i) = rhs_pb(j, k, l, q, i) - 3._wp*gam/(dx(j)*AX*nb_q**2*sqrt(var)*2._wp)* & - (-2._wp*(nR/nb_q)*(nR_dot*nb_q - nR*nb_dot))*(pb(j, k, l, q, i)) + rhs_pb(j, k, l, q, i) = rhs_pb(j, k, l, q, & + & i) - 3._wp*gam/(dx(j)*AX*nb_q**2*sqrt(var)*2._wp)*(nR2_dot*nb_q - nR2*nb_dot) & + & *(pb(j, k, l, q, i)) + rhs_pb(j, k, l, q, i) = rhs_pb(j, k, l, q, & + & i) - 3._wp*gam/(dx(j)*AX*nb_q**2*sqrt(var)*2._wp)*(-2._wp*(nR/nb_q)*(nR_dot*nb_q & + & - nR*nb_dot))*(pb(j, k, l, q, i)) case (2) - rhs_pb(j, k, l, q, i) = rhs_pb(j, k, l, q, i) - 3._wp*gam/(dy(k)*AX*nb_q**2*sqrt(var)*2._wp)* & - (nR2_dot*nb_q - nR2*nb_dot)*(pb(j, k, l, q, i)) - rhs_pb(j, k, l, q, i) = rhs_pb(j, k, l, q, i) - 3._wp*gam/(dy(k)*AX*nb_q**2*sqrt(var)*2._wp)* & - (-2._wp*(nR/nb_q)*(nR_dot*nb_q - nR*nb_dot))*(pb(j, k, l, q, i)) + rhs_pb(j, k, l, q, i) = rhs_pb(j, k, l, q, & + & i) - 3._wp*gam/(dy(k)*AX*nb_q**2*sqrt(var)*2._wp)*(nR2_dot*nb_q - nR2*nb_dot) & + & *(pb(j, k, l, q, i)) + rhs_pb(j, k, l, q, i) = rhs_pb(j, k, l, q, & + & i) - 3._wp*gam/(dy(k)*AX*nb_q**2*sqrt(var)*2._wp)*(-2._wp*(nR/nb_q)*(nR_dot*nb_q & + & - nR*nb_dot))*(pb(j, k, l, q, i)) case (3) if (is_axisym) then - rhs_pb(j, k, l, q, i) = rhs_pb(j, k, l, q, i) - 3._wp*gam/(dz(l)*y_cc(k)*AX*nb_q**2*sqrt(var)*2._wp)* & - (nR2_dot*nb_q - nR2*nb_dot)*(pb(j, k, l, q, i)) - rhs_pb(j, k, l, q, i) = rhs_pb(j, k, l, q, i) - 3._wp*gam/(dz(l)*y_cc(k)*AX*nb_q**2*sqrt(var)*2._wp)* & - (-2._wp*(nR/nb_q)*(nR_dot*nb_q - nR*nb_dot))*(pb(j, k, l, q, i)) + rhs_pb(j, k, l, q, i) = rhs_pb(j, k, l, q, & + & i) - 3._wp*gam/(dz(l)*y_cc(k)*AX*nb_q**2*sqrt(var)*2._wp)*(nR2_dot*nb_q & + & - nR2*nb_dot)*(pb(j, k, l, q, i)) + rhs_pb(j, k, l, q, i) = rhs_pb(j, k, l, q, & + & i) - 3._wp*gam/(dz(l)*y_cc(k)*AX*nb_q**2*sqrt(var)*2._wp)*(-2._wp*(nR/nb_q) & + & *(nR_dot*nb_q - nR*nb_dot))*(pb(j, k, l, q, i)) else - rhs_pb(j, k, l, q, i) = rhs_pb(j, k, l, q, i) - 3._wp*gam/(dz(l)*AX*nb_q**2*sqrt(var)*2._wp)* & - (nR2_dot*nb_q - nR2*nb_dot)*(pb(j, k, l, q, i)) - rhs_pb(j, k, l, q, i) = rhs_pb(j, k, l, q, i) - 3._wp*gam/(dz(l)*AX*nb_q**2*sqrt(var)*2._wp)* & - (-2._wp*(nR/nb_q)*(nR_dot*nb_q - nR*nb_dot))*(pb(j, k, l, q, i)) + rhs_pb(j, k, l, q, i) = rhs_pb(j, k, l, q, & + & i) - 3._wp*gam/(dz(l)*AX*nb_q**2*sqrt(var)*2._wp)*(nR2_dot*nb_q - nR2*nb_dot) & + & *(pb(j, k, l, q, i)) + rhs_pb(j, k, l, q, i) = rhs_pb(j, k, l, q, & + & i) - 3._wp*gam/(dz(l)*AX*nb_q**2*sqrt(var)*2._wp)*(-2._wp*(nR/nb_q) & + & *(nR_dot*nb_q - nR*nb_dot))*(pb(j, k, l, q, i)) end if end select end if @@ -543,7 +562,7 @@ contains ! The following block is not repeated and is left as is if (idir == 1) then - $:GPU_PARALLEL_LOOP(private='[i,l,q]', collapse=3) + $:GPU_PARALLEL_LOOP(private='[i, l, q]', collapse=3) do l = 0, p do q = 0, n do i = 0, m @@ -569,187 +588,189 @@ contains !> @brief Builds the coefficient array for the non-polytropic bubble model. subroutine s_coeff_nonpoly(pres, rho, c, coeffs) - $:GPU_ROUTINE(function_name='s_coeff_nonpoly',parallelism='[seq]', & - & cray_inline=True) + + $:GPU_ROUTINE(function_name='s_coeff_nonpoly',parallelism='[seq]', cray_inline=True) real(wp), intent(in) :: pres, rho, c #:if USING_AMD - real(wp), dimension(32, 0:2, 0:2), intent(out) :: coeffs + real(wp), dimension(32,0:2,0:2), intent(out) :: coeffs #:else - real(wp), dimension(nterms, 0:2, 0:2), intent(out) :: coeffs + real(wp), dimension(nterms,0:2,0:2), intent(out) :: coeffs #:endif integer :: i1, i2 - coeffs(:, :, :) = 0._wp + coeffs(:,:,:) = 0._wp do i2 = 0, 2; do i1 = 0, 2 - if ((i1 + i2) <= 2) then - if (bubble_model == 3) then - #:if not MFC_CASE_OPTIMIZATION or nterms > 1 - ! RPE - coeffs(1, i1, i2) = -1._wp*i2*pres/rho - coeffs(2, i1, i2) = -3._wp*i2/2._wp - coeffs(3, i1, i2) = i2/rho - coeffs(4, i1, i2) = i1 - if (.not. f_is_default(Re_inv)) coeffs(5, i1, i2) = -4._wp*i2*Re_inv/rho - if (.not. f_is_default(Web)) coeffs(6, i1, i2) = -2._wp*i2/Web/rho - coeffs(7, i1, i2) = 0._wp - #:endif - else if (bubble_model == 2) then - ! KM with approximation of 1/(1-V/C) = 1+V/C - #:if not MFC_CASE_OPTIMIZATION or nterms > 7 - coeffs(1, i1, i2) = -3._wp*i2/2._wp - coeffs(2, i1, i2) = -i2/c - coeffs(3, i1, i2) = i2/(2._wp*c*c) - coeffs(4, i1, i2) = -i2*pres/rho - coeffs(5, i1, i2) = -2._wp*i2*pres/(c*rho) - coeffs(6, i1, i2) = -i2*pres/(c*c*rho) - coeffs(7, i1, i2) = i2/rho - coeffs(8, i1, i2) = 2._wp*i2/(c*rho) - coeffs(9, i1, i2) = i2/(c*c*rho) - coeffs(10, i1, i2) = -3._wp*i2*gam/(c*rho) - coeffs(11, i1, i2) = -3._wp*i2*gam/(c*c*rho) - coeffs(12, i1, i2) = i1 - coeffs(13, i1, i2) = 0._wp - coeffs(14, i1, i2) = 0._wp - coeffs(15, i1, i2) = 0._wp - if (.not. f_is_default(Re_inv)) coeffs(16, i1, i2) = -i2*4._wp*Re_inv/rho - if (.not. f_is_default(Web)) coeffs(17, i1, i2) = -i2*2._wp/Web/rho - if (.not. f_is_default(Re_inv)) then - coeffs(18, i1, i2) = i2*6._wp*Re_inv/(rho*c) - coeffs(19, i1, i2) = -i2*2._wp*Re_inv/(rho*c*c) - coeffs(20, i1, i2) = i2*4._wp*pres*Re_inv/(rho*rho*c) - coeffs(21, i1, i2) = i2*4._wp*pres*Re_inv/(rho*rho*c*c) - coeffs(22, i1, i2) = -i2*4._wp*Re_inv/(rho*rho*c) - coeffs(23, i1, i2) = -i2*4._wp*Re_inv/(rho*rho*c*c) - coeffs(24, i1, i2) = i2*16._wp*Re_inv*Re_inv/(rho*rho*c) - if (.not. f_is_default(Web)) then - coeffs(25, i1, i2) = i2*8._wp*Re_inv/Web/(rho*rho*c) - end if - coeffs(26, i1, i2) = -12._wp*i2*gam*Re_inv/(rho*rho*c*c) - end if - coeffs(27, i1, i2) = 3._wp*i2*gam*R_v*Tw/(c*rho) - coeffs(28, i1, i2) = 3._wp*i2*gam*R_v*Tw/(c*c*rho) - if (.not. f_is_default(Re_inv)) then - coeffs(29, i1, i2) = 12._wp*i2*gam*R_v*Tw*Re_inv/(rho*rho*c*c) - end if - coeffs(30, i1, i2) = 3._wp*i2*gam/(c*rho) - coeffs(31, i1, i2) = 3._wp*i2*gam/(c*c*rho) - if (.not. f_is_default(Re_inv)) then - coeffs(32, i1, i2) = 12._wp*i2*gam*Re_inv/(rho*rho*c*c) + if ((i1 + i2) <= 2) then + if (bubble_model == 3) then + #:if not MFC_CASE_OPTIMIZATION or nterms > 1 + ! RPE + coeffs(1, i1, i2) = -1._wp*i2*pres/rho + coeffs(2, i1, i2) = -3._wp*i2/2._wp + coeffs(3, i1, i2) = i2/rho + coeffs(4, i1, i2) = i1 + if (.not. f_is_default(Re_inv)) coeffs(5, i1, i2) = -4._wp*i2*Re_inv/rho + if (.not. f_is_default(Web)) coeffs(6, i1, i2) = -2._wp*i2/Web/rho + coeffs(7, i1, i2) = 0._wp + #:endif + else if (bubble_model == 2) then + ! KM with approximation of 1/(1-V/C) = 1+V/C + #:if not MFC_CASE_OPTIMIZATION or nterms > 7 + coeffs(1, i1, i2) = -3._wp*i2/2._wp + coeffs(2, i1, i2) = -i2/c + coeffs(3, i1, i2) = i2/(2._wp*c*c) + coeffs(4, i1, i2) = -i2*pres/rho + coeffs(5, i1, i2) = -2._wp*i2*pres/(c*rho) + coeffs(6, i1, i2) = -i2*pres/(c*c*rho) + coeffs(7, i1, i2) = i2/rho + coeffs(8, i1, i2) = 2._wp*i2/(c*rho) + coeffs(9, i1, i2) = i2/(c*c*rho) + coeffs(10, i1, i2) = -3._wp*i2*gam/(c*rho) + coeffs(11, i1, i2) = -3._wp*i2*gam/(c*c*rho) + coeffs(12, i1, i2) = i1 + coeffs(13, i1, i2) = 0._wp + coeffs(14, i1, i2) = 0._wp + coeffs(15, i1, i2) = 0._wp + if (.not. f_is_default(Re_inv)) coeffs(16, i1, i2) = -i2*4._wp*Re_inv/rho + if (.not. f_is_default(Web)) coeffs(17, i1, i2) = -i2*2._wp/Web/rho + if (.not. f_is_default(Re_inv)) then + coeffs(18, i1, i2) = i2*6._wp*Re_inv/(rho*c) + coeffs(19, i1, i2) = -i2*2._wp*Re_inv/(rho*c*c) + coeffs(20, i1, i2) = i2*4._wp*pres*Re_inv/(rho*rho*c) + coeffs(21, i1, i2) = i2*4._wp*pres*Re_inv/(rho*rho*c*c) + coeffs(22, i1, i2) = -i2*4._wp*Re_inv/(rho*rho*c) + coeffs(23, i1, i2) = -i2*4._wp*Re_inv/(rho*rho*c*c) + coeffs(24, i1, i2) = i2*16._wp*Re_inv*Re_inv/(rho*rho*c) + if (.not. f_is_default(Web)) then + coeffs(25, i1, i2) = i2*8._wp*Re_inv/Web/(rho*rho*c) end if - #:endif - end if + coeffs(26, i1, i2) = -12._wp*i2*gam*Re_inv/(rho*rho*c*c) + end if + coeffs(27, i1, i2) = 3._wp*i2*gam*R_v*Tw/(c*rho) + coeffs(28, i1, i2) = 3._wp*i2*gam*R_v*Tw/(c*c*rho) + if (.not. f_is_default(Re_inv)) then + coeffs(29, i1, i2) = 12._wp*i2*gam*R_v*Tw*Re_inv/(rho*rho*c*c) + end if + coeffs(30, i1, i2) = 3._wp*i2*gam/(c*rho) + coeffs(31, i1, i2) = 3._wp*i2*gam/(c*c*rho) + if (.not. f_is_default(Re_inv)) then + coeffs(32, i1, i2) = 12._wp*i2*gam*Re_inv/(rho*rho*c*c) + end if + #:endif end if - end do; end do + end if + end do; end do end subroutine s_coeff_nonpoly !> @brief Builds the coefficient array for the polytropic bubble model. subroutine s_coeff(pres, rho, c, coeffs) - $:GPU_ROUTINE(function_name='s_coeff',parallelism='[seq]', & - & cray_inline=True) + + $:GPU_ROUTINE(function_name='s_coeff',parallelism='[seq]', cray_inline=True) real(wp), intent(in) :: pres, rho, c #:if USING_AMD - real(wp), dimension(32, 0:2, 0:2), intent(out) :: coeffs + real(wp), dimension(32,0:2,0:2), intent(out) :: coeffs #:else - real(wp), dimension(nterms, 0:2, 0:2), intent(out) :: coeffs + real(wp), dimension(nterms,0:2,0:2), intent(out) :: coeffs #:endif integer :: i1, i2 - coeffs(:, :, :) = 0._wp + coeffs(:,:,:) = 0._wp do i2 = 0, 2; do i1 = 0, 2 - if ((i1 + i2) <= 2) then - if (bubble_model == 3) then - ! RPE - #:if not MFC_CASE_OPTIMIZATION or nterms > 1 - coeffs(1, i1, i2) = -1._wp*i2*pres/rho - coeffs(2, i1, i2) = -3._wp*i2/2._wp - coeffs(3, i1, i2) = i2/rho - coeffs(4, i1, i2) = i1 - if (.not. f_is_default(Re_inv)) coeffs(5, i1, i2) = -4._wp*i2*Re_inv/rho - if (.not. f_is_default(Web)) coeffs(6, i1, i2) = -2._wp*i2/Web/rho - coeffs(7, i1, i2) = i2*pv/rho - #:endif - else if (bubble_model == 2) then - ! KM with approximation of 1/(1-V/C) = 1+V/C - #:if not MFC_CASE_OPTIMIZATION or nterms > 7 - coeffs(1, i1, i2) = -3._wp*i2/2._wp - coeffs(2, i1, i2) = -i2/c - coeffs(3, i1, i2) = i2/(2._wp*c*c) - coeffs(4, i1, i2) = -i2*pres/rho - coeffs(5, i1, i2) = -2._wp*i2*pres/(c*rho) - coeffs(6, i1, i2) = -i2*pres/(c*c*rho) - coeffs(7, i1, i2) = i2/rho - coeffs(8, i1, i2) = 2._wp*i2/(c*rho) - coeffs(9, i1, i2) = i2/(c*c*rho) - coeffs(10, i1, i2) = -3._wp*i2*gam/(c*rho) - coeffs(11, i1, i2) = -3._wp*i2*gam/(c*c*rho) - coeffs(12, i1, i2) = i1 - coeffs(13, i1, i2) = i2*(pv)/rho - coeffs(14, i1, i2) = 2._wp*i2*(pv)/(c*rho) - coeffs(15, i1, i2) = i2*(pv)/(c*c*rho) - if (.not. f_is_default(Re_inv)) coeffs(16, i1, i2) = -i2*4._wp*Re_inv/rho - if (.not. f_is_default(Web)) coeffs(17, i1, i2) = -i2*2._wp/Web/rho - if (.not. f_is_default(Re_inv)) then - coeffs(18, i1, i2) = i2*6._wp*Re_inv/(rho*c) - coeffs(19, i1, i2) = -i2*2._wp*Re_inv/(rho*c*c) - coeffs(20, i1, i2) = i2*4._wp*pres*Re_inv/(rho*rho*c) - coeffs(21, i1, i2) = i2*4._wp*pres*Re_inv/(rho*rho*c*c) - coeffs(22, i1, i2) = -i2*4._wp*Re_inv/(rho*rho*c) - coeffs(23, i1, i2) = -i2*4._wp*Re_inv/(rho*rho*c*c) - coeffs(24, i1, i2) = i2*16._wp*Re_inv*Re_inv/(rho*rho*c) - if (.not. f_is_default(Web)) then - coeffs(25, i1, i2) = i2*8._wp*Re_inv/Web/(rho*rho*c) - end if - coeffs(26, i1, i2) = -12._wp*i2*gam*Re_inv/(rho*rho*c*c) + if ((i1 + i2) <= 2) then + if (bubble_model == 3) then + ! RPE + #:if not MFC_CASE_OPTIMIZATION or nterms > 1 + coeffs(1, i1, i2) = -1._wp*i2*pres/rho + coeffs(2, i1, i2) = -3._wp*i2/2._wp + coeffs(3, i1, i2) = i2/rho + coeffs(4, i1, i2) = i1 + if (.not. f_is_default(Re_inv)) coeffs(5, i1, i2) = -4._wp*i2*Re_inv/rho + if (.not. f_is_default(Web)) coeffs(6, i1, i2) = -2._wp*i2/Web/rho + coeffs(7, i1, i2) = i2*pv/rho + #:endif + else if (bubble_model == 2) then + ! KM with approximation of 1/(1-V/C) = 1+V/C + #:if not MFC_CASE_OPTIMIZATION or nterms > 7 + coeffs(1, i1, i2) = -3._wp*i2/2._wp + coeffs(2, i1, i2) = -i2/c + coeffs(3, i1, i2) = i2/(2._wp*c*c) + coeffs(4, i1, i2) = -i2*pres/rho + coeffs(5, i1, i2) = -2._wp*i2*pres/(c*rho) + coeffs(6, i1, i2) = -i2*pres/(c*c*rho) + coeffs(7, i1, i2) = i2/rho + coeffs(8, i1, i2) = 2._wp*i2/(c*rho) + coeffs(9, i1, i2) = i2/(c*c*rho) + coeffs(10, i1, i2) = -3._wp*i2*gam/(c*rho) + coeffs(11, i1, i2) = -3._wp*i2*gam/(c*c*rho) + coeffs(12, i1, i2) = i1 + coeffs(13, i1, i2) = i2*(pv)/rho + coeffs(14, i1, i2) = 2._wp*i2*(pv)/(c*rho) + coeffs(15, i1, i2) = i2*(pv)/(c*c*rho) + if (.not. f_is_default(Re_inv)) coeffs(16, i1, i2) = -i2*4._wp*Re_inv/rho + if (.not. f_is_default(Web)) coeffs(17, i1, i2) = -i2*2._wp/Web/rho + if (.not. f_is_default(Re_inv)) then + coeffs(18, i1, i2) = i2*6._wp*Re_inv/(rho*c) + coeffs(19, i1, i2) = -i2*2._wp*Re_inv/(rho*c*c) + coeffs(20, i1, i2) = i2*4._wp*pres*Re_inv/(rho*rho*c) + coeffs(21, i1, i2) = i2*4._wp*pres*Re_inv/(rho*rho*c*c) + coeffs(22, i1, i2) = -i2*4._wp*Re_inv/(rho*rho*c) + coeffs(23, i1, i2) = -i2*4._wp*Re_inv/(rho*rho*c*c) + coeffs(24, i1, i2) = i2*16._wp*Re_inv*Re_inv/(rho*rho*c) + if (.not. f_is_default(Web)) then + coeffs(25, i1, i2) = i2*8._wp*Re_inv/Web/(rho*rho*c) end if - #:endif - end if + coeffs(26, i1, i2) = -12._wp*i2*gam*Re_inv/(rho*rho*c*c) + end if + #:endif end if - end do; end do + end if + end do; end do end subroutine s_coeff !> @brief Performs moment inversion to recover quadrature weights and abscissas and evaluates bubble source terms. subroutine s_mom_inv(q_cons_vf, q_prim_vf, momsp, moms3d, pb, rhs_pb, mv, rhs_mv, ix, iy, iz) - type(scalar_field), dimension(:), intent(inout) :: q_cons_vf, q_prim_vf - type(scalar_field), dimension(:), intent(inout) :: momsp - type(scalar_field), dimension(0:, 0:, :), intent(inout) :: moms3d - real(stp), dimension(idwbuff(1)%beg:, idwbuff(2)%beg:, idwbuff(3)%beg:, 1:, 1:), intent(inout) :: pb - real(wp), dimension(idwbuff(1)%beg:, idwbuff(2)%beg:, idwbuff(3)%beg:, 1:, 1:), intent(inout) :: rhs_pb - real(stp), dimension(idwbuff(1)%beg:, idwbuff(2)%beg:, idwbuff(3)%beg:, 1:, 1:), intent(inout) :: mv - real(wp), dimension(idwbuff(1)%beg:, idwbuff(2)%beg:, idwbuff(3)%beg:, 1:, 1:), intent(inout) :: rhs_mv - type(int_bounds_info), intent(in) :: ix, iy, iz + type(scalar_field), dimension(:), intent(inout) :: q_cons_vf, q_prim_vf + type(scalar_field), dimension(:), intent(inout) :: momsp + type(scalar_field), dimension(0:,0:,:), intent(inout) :: moms3d + real(stp), dimension(idwbuff(1)%beg:,idwbuff(2)%beg:,idwbuff(3)%beg:,1:,1:), intent(inout) :: pb + real(wp), dimension(idwbuff(1)%beg:,idwbuff(2)%beg:,idwbuff(3)%beg:,1:,1:), intent(inout) :: rhs_pb + real(stp), dimension(idwbuff(1)%beg:,idwbuff(2)%beg:,idwbuff(3)%beg:,1:,1:), intent(inout) :: mv + real(wp), dimension(idwbuff(1)%beg:,idwbuff(2)%beg:,idwbuff(3)%beg:,1:,1:), intent(inout) :: rhs_mv + type(int_bounds_info), intent(in) :: ix, iy, iz + #:if not MFC_CASE_OPTIMIZATION and USING_AMD - real(wp), dimension(6) :: moms, msum + real(wp), dimension(6) :: moms, msum real(wp), dimension(4, 3) :: wght, abscX, abscY, wght_pb, wght_mv, wght_ht, ht #:else - real(wp), dimension(nmom) :: moms, msum + real(wp), dimension(nmom) :: moms, msum real(wp), dimension(nnode, nb) :: wght, abscX, abscY, wght_pb, wght_mv, wght_ht, ht #:endif #:if USING_AMD - real(wp), dimension(32, 0:2, 0:2) :: coeff + real(wp), dimension(32,0:2,0:2) :: coeff #:else - real(wp), dimension(nterms, 0:2, 0:2) :: coeff + real(wp), dimension(nterms,0:2,0:2) :: coeff #:endif real(wp) :: pres, rho, nbub, c, alf, momsum, drdt, drdt2, chi_vw, x_vw, rho_mw, k_mw, grad_T real(wp) :: n_tait, B_tait - integer :: id1, id2, id3, i1, i2, j, q, r + integer :: id1, id2, id3, i1, i2, j, q, r is1_qbmm = ix; is2_qbmm = iy; is3_qbmm = iz - $:GPU_UPDATE(device='[is1_qbmm,is2_qbmm,is3_qbmm]') + $:GPU_UPDATE(device='[is1_qbmm, is2_qbmm, is3_qbmm]') - $:GPU_PARALLEL_LOOP(collapse=3, private='[id1,id2,id3,moms, msum, wght, abscX, abscY, wght_pb, wght_mv, wght_ht, coeff, ht, r, q, n_tait, B_tait, pres, rho, nbub, c, alf, momsum, drdt, drdt2, chi_vw, x_vw, rho_mw, k_mw, grad_T, i1, i2, j]') + $:GPU_PARALLEL_LOOP(collapse=3, private='[id1, id2, id3, moms, msum, wght, abscX, abscY, wght_pb, wght_mv, wght_ht, & + & coeff, ht, r, q, n_tait, B_tait, pres, rho, nbub, c, alf, momsum, drdt, drdt2, chi_vw, x_vw, & + & rho_mw, k_mw, grad_T, i1, i2, j]') do id3 = is3_qbmm%beg, is3_qbmm%end do id2 = is2_qbmm%beg, is2_qbmm%end do id1 = is1_qbmm%beg, is1_qbmm%end - alf = q_prim_vf(alf_idx)%sf(id1, id2, id3) pres = q_prim_vf(E_idx)%sf(id1, id2, id3) rho = q_prim_vf(contxb)%sf(id1, id2, id3) @@ -773,7 +794,7 @@ contains moms(r) = q_prim_vf(bubmoms(q, r))%sf(id1, id2, id3) end do moms(1) = 1._wp - call s_chyqmom(moms, wght(:, q), abscX(:, q), abscY(:, q)) + call s_chyqmom(moms, wght(:,q), abscX(:,q), abscY(:,q)) if (polytropic) then $:GPU_LOOP(parallelism='[seq]') @@ -785,11 +806,16 @@ contains do j = 1, nnode chi_vw = 1._wp/(1._wp + R_v/R_g*(pb(id1, id2, id3, j, q)/pv - 1._wp)) x_vw = M_g*chi_vw/(M_v + (M_g - M_v)*chi_vw) - k_mw = x_vw*k_v(q)/(x_vw + (1._wp - x_vw)*phi_vg) + (1._wp - x_vw)*k_g(q)/(x_vw*phi_gv + 1._wp - x_vw) + k_mw = x_vw*k_v(q)/(x_vw + (1._wp - x_vw)*phi_vg) + (1._wp - x_vw)*k_g(q)/(x_vw*phi_gv & + & + 1._wp - x_vw) rho_mw = pv/(chi_vw*R_v*Tw) - rhs_mv(id1, id2, id3, j, q) = -Re_trans_c(q)*((mv(id1, id2, id3, j, q)/(mv(id1, id2, id3, j, q) + mass_g0(q))) - chi_vw) - rhs_mv(id1, id2, id3, j, q) = rho_mw*rhs_mv(id1, id2, id3, j, q)/Pe_c/(1._wp - chi_vw)/abscX(j, q) - grad_T = -Re_trans_T(q)*((pb(id1, id2, id3, j, q)/pb0(q))*(abscX(j, q)/R0(q))**3*(mass_g0(q) + mass_v0(q))/(mass_g0(q) + mv(id1, id2, id3, j, q)) - 1._wp) + rhs_mv(id1, id2, id3, j, q) = -Re_trans_c(q)*((mv(id1, id2, id3, j, q)/(mv(id1, id2, id3, j, & + & q) + mass_g0(q))) - chi_vw) + rhs_mv(id1, id2, id3, j, q) = rho_mw*rhs_mv(id1, id2, id3, j, & + & q)/Pe_c/(1._wp - chi_vw)/abscX(j, q) + grad_T = -Re_trans_T(q)*((pb(id1, id2, id3, j, q)/pb0(q))*(abscX(j, & + & q)/R0(q))**3*(mass_g0(q) + mass_v0(q))/(mass_g0(q) + mv(id1, id2, id3, & + & j, q)) - 1._wp) ht(j, q) = pb0(q)*k_mw*grad_T/Pe_T(q)/abscX(j, q) wght_pb(j, q) = wght(j, q)*(pb(id1, id2, id3, j, q)) wght_mv(j, q) = wght(j, q)*(rhs_mv(id1, id2, id3, j, q)) @@ -810,19 +836,32 @@ contains select case (bubble_model) case (3) if (j == 3) then - momsum = momsum + coeff(j, i1, i2)*(R0(q)**momrhs(3, i1, i2, j, q))*f_quad2D(abscX(:, q), abscY(:, q), wght_pb(:, q), momrhs(:, i1, i2, j, q)) + momsum = momsum + coeff(j, i1, i2)*(R0(q)**momrhs(3, i1, i2, j, & + & q))*f_quad2D(abscX(:,q), abscY(:,q), wght_pb(:,q), & + & momrhs(:,i1, i2, j, q)) else - momsum = momsum + coeff(j, i1, i2)*(R0(q)**momrhs(3, i1, i2, j, q))*f_quad2D(abscX(:, q), abscY(:, q), wght(:, q), momrhs(:, i1, i2, j, q)) + momsum = momsum + coeff(j, i1, i2)*(R0(q)**momrhs(3, i1, i2, j, & + & q))*f_quad2D(abscX(:,q), abscY(:,q), wght(:,q), & + & momrhs(:,i1, i2, j, q)) end if case (2) - if ((j >= 7 .and. j <= 9) .or. (j >= 22 .and. j <= 23) .or. (j >= 10 .and. j <= 11) .or. (j == 26)) then - momsum = momsum + coeff(j, i1, i2)*(R0(q)**momrhs(3, i1, i2, j, q))*f_quad2D(abscX(:, q), abscY(:, q), wght_pb(:, q), momrhs(:, i1, i2, j, q)) + if ((j >= 7 .and. j <= 9) .or. (j >= 22 .and. j <= 23) & + & .or. (j >= 10 .and. j <= 11) .or. (j == 26)) then + momsum = momsum + coeff(j, i1, i2)*(R0(q)**momrhs(3, i1, i2, j, & + & q))*f_quad2D(abscX(:,q), abscY(:,q), wght_pb(:,q), & + & momrhs(:,i1, i2, j, q)) else if ((j >= 27 .and. j <= 29) .and. (.not. polytropic)) then - momsum = momsum + coeff(j, i1, i2)*(R0(q)**momrhs(3, i1, i2, j, q))*f_quad2D(abscX(:, q), abscY(:, q), wght_mv(:, q), momrhs(:, i1, i2, j, q)) + momsum = momsum + coeff(j, i1, i2)*(R0(q)**momrhs(3, i1, i2, j, & + & q))*f_quad2D(abscX(:,q), abscY(:,q), wght_mv(:,q), & + & momrhs(:,i1, i2, j, q)) else if ((j >= 30 .and. j <= 32) .and. (.not. polytropic)) then - momsum = momsum + coeff(j, i1, i2)*(R0(q)**momrhs(3, i1, i2, j, q))*f_quad2D(abscX(:, q), abscY(:, q), wght_ht(:, q), momrhs(:, i1, i2, j, q)) + momsum = momsum + coeff(j, i1, i2)*(R0(q)**momrhs(3, i1, i2, j, & + & q))*f_quad2D(abscX(:,q), abscY(:,q), wght_ht(:,q), & + & momrhs(:,i1, i2, j, q)) else - momsum = momsum + coeff(j, i1, i2)*(R0(q)**momrhs(3, i1, i2, j, q))*f_quad2D(abscX(:, q), abscY(:, q), wght(:, q), momrhs(:, i1, i2, j, q)) + momsum = momsum + coeff(j, i1, i2)*(R0(q)**momrhs(3, i1, i2, j, & + & q))*f_quad2D(abscX(:,q), abscY(:,q), wght(:,q), & + & momrhs(:,i1, i2, j, q)) end if end select end do @@ -838,14 +877,15 @@ contains $:GPU_LOOP(parallelism='[seq]') do j = 1, nnode drdt = msum(2) - drdt2 = merge(-1._wp, 1._wp, j == 1 .or. j == 2)/(2._wp*sqrt(merge(moms(4) - moms(2)**2._wp, sgm_eps, moms(4) - moms(2)**2._wp > 0._wp))) + drdt2 = merge(-1._wp, 1._wp, j == 1 .or. j == 2)/(2._wp*sqrt(merge(moms(4) - moms(2)**2._wp, & + & sgm_eps, moms(4) - moms(2)**2._wp > 0._wp))) drdt2 = drdt2*(msum(3) - 2._wp*moms(2)*msum(2)) drdt = drdt + drdt2 rhs_pb(id1, id2, id3, j, q) = (-3._wp*gam*drdt/abscX(j, q))*(pb(id1, id2, id3, j, q)) - rhs_pb(id1, id2, id3, j, q) = rhs_pb(id1, id2, id3, j, q) + (3._wp*gam/abscX(j, q))*rhs_mv(id1, id2, id3, j, q)*R_v*Tw + rhs_pb(id1, id2, id3, j, q) = rhs_pb(id1, id2, id3, j, q) + (3._wp*gam/abscX(j, & + & q))*rhs_mv(id1, id2, id3, j, q)*R_v*Tw rhs_pb(id1, id2, id3, j, q) = rhs_pb(id1, id2, id3, j, q) + (3._wp*gam/abscX(j, q))*ht(j, q) rhs_mv(id1, id2, id3, j, q) = rhs_mv(id1, id2, id3, j, q)*(4._wp*pi*abscX(j, q)**2._wp) - end do end if end do @@ -858,9 +898,14 @@ contains momsp(4)%sf(id1, id2, id3) = 1._wp else if (polytropic) then - momsp(4)%sf(id1, id2, id3) = f_quad(abscX, abscY, wght_pb, 3._wp*(1._wp - gam), 0._wp, 3._wp*gam) + pv*f_quad(abscX, abscY, wght, 3._wp, 0._wp, 0._wp) - 4._wp*Re_inv*f_quad(abscX, abscY, wght, 2._wp, 1._wp, 0._wp) - (2._wp/Web)*f_quad(abscX, abscY, wght, 2._wp, 0._wp, 0._wp) + momsp(4)%sf(id1, id2, id3) = f_quad(abscX, abscY, wght_pb, 3._wp*(1._wp - gam), 0._wp, & + & 3._wp*gam) + pv*f_quad(abscX, abscY, wght, 3._wp, 0._wp, & + & 0._wp) - 4._wp*Re_inv*f_quad(abscX, abscY, wght, 2._wp, 1._wp, & + & 0._wp) - (2._wp/Web)*f_quad(abscX, abscY, wght, 2._wp, 0._wp, 0._wp) else - momsp(4)%sf(id1, id2, id3) = f_quad(abscX, abscY, wght_pb, 3._wp, 0._wp, 0._wp) - 4._wp*Re_inv*f_quad(abscX, abscY, wght, 2._wp, 1._wp, 0._wp) - (2._wp/Web)*f_quad(abscX, abscY, wght, 2._wp, 0._wp, 0._wp) + momsp(4)%sf(id1, id2, id3) = f_quad(abscX, abscY, wght_pb, 3._wp, 0._wp, & + & 0._wp) - 4._wp*Re_inv*f_quad(abscX, abscY, wght, 2._wp, 1._wp, & + & 0._wp) - (2._wp/Web)*f_quad(abscX, abscY, wght, 2._wp, 0._wp, 0._wp) end if end if else @@ -887,13 +932,13 @@ contains contains !> @brief Selects the polytropic or non-polytropic coefficient routine. subroutine s_coeff_selector(pres, rho, c, coeff, polytropic) - $:GPU_ROUTINE(function_name='s_coeff_selector',parallelism='[seq]', & - & cray_inline=True) + + $:GPU_ROUTINE(function_name='s_coeff_selector',parallelism='[seq]', cray_inline=True) real(wp), intent(in) :: pres, rho, c #:if USING_AMD - real(wp), dimension(32, 0:2, 0:2), intent(out) :: coeff + real(wp), dimension(32,0:2,0:2), intent(out) :: coeff #:else - real(wp), dimension(nterms, 0:2, 0:2), intent(out) :: coeff + real(wp), dimension(nterms,0:2,0:2), intent(out) :: coeff #:endif logical, intent(in) :: polytropic if (polytropic) then @@ -901,22 +946,23 @@ contains else call s_coeff_nonpoly(pres, rho, c, coeff) end if + end subroutine s_coeff_selector !> @brief Performs conditional hyperbolic QMOM (CHyQMOM) inversion for bivariate moments. subroutine s_chyqmom(momin, wght, abscX, abscY) - $:GPU_ROUTINE(function_name='s_chyqmom',parallelism='[seq]', & - & cray_inline=True) - real(wp), dimension(nmom), intent(in) :: momin + $:GPU_ROUTINE(function_name='s_chyqmom',parallelism='[seq]', cray_inline=True) + + real(wp), dimension(nmom), intent(in) :: momin real(wp), dimension(nnode), intent(inout) :: wght, abscX, abscY ! Local variables - real(wp), dimension(0:2, 0:2) :: moms - real(wp), dimension(3) :: M1, M3 - real(wp), dimension(2) :: myrho, myrho3, up, up3, Vf - real(wp) :: bu, bv, d20, d11, d_02, c20, c11, c02 - real(wp) :: mu2, vp21, vp22, rho21, rho22 + real(wp), dimension(0:2,0:2) :: moms + real(wp), dimension(3) :: M1, M3 + real(wp), dimension(2) :: myrho, myrho3, up, up3, Vf + real(wp) :: bu, bv, d20, d11, d_02, c20, c11, c02 + real(wp) :: mu2, vp21, vp22, rho21, rho22 ! Assign moments to 2D array for clarity moms(0, 0) = momin(1) @@ -964,19 +1010,18 @@ contains !> @brief Performs hyperbolic QMOM (HyQMOM) inversion for univariate moments. subroutine s_hyqmom(frho, fup, fmom) - $:GPU_ROUTINE(function_name='s_hyqmom',parallelism='[seq]', & - & cray_inline=True) - real(wp), dimension(2), intent(inout) :: frho, fup - real(wp), dimension(3), intent(in) :: fmom + $:GPU_ROUTINE(function_name='s_hyqmom',parallelism='[seq]', cray_inline=True) - real(wp) :: bu, d2, c2 + real(wp), dimension(2), intent(inout) :: frho, fup + real(wp), dimension(3), intent(in) :: fmom + real(wp) :: bu, d2, c2 bu = fmom(2)/fmom(1) d2 = fmom(3)/fmom(1) c2 = d2 - bu**2._wp - frho(1) = fmom(1)/2._wp; - frho(2) = fmom(1)/2._wp; + frho(1) = fmom(1)/2._wp + frho(2) = fmom(1)/2._wp c2 = maxval((/c2, sgm_eps/)) fup(1) = bu - sqrt(c2) fup(2) = bu + sqrt(c2) @@ -985,6 +1030,7 @@ contains !> @brief Evaluates a weighted quadrature sum over all bubble size bins and nodes. function f_quad(abscX, abscY, wght_in, q, r, s) + $:GPU_ROUTINE(parallelism='[seq]') #:if not MFC_CASE_OPTIMIZATION and USING_AMD real(wp), dimension(4, 3), intent(in) :: abscX, abscY, wght_in @@ -992,9 +1038,8 @@ contains real(wp), dimension(nnode, nb), intent(in) :: abscX, abscY, wght_in #:endif real(wp), intent(in) :: q, r, s - - real(wp) :: f_quad_RV, f_quad - integer :: i, i1 + real(wp) :: f_quad_RV, f_quad + integer :: i, i1 f_quad = 0._wp $:GPU_LOOP(parallelism='[seq]') @@ -1011,6 +1056,7 @@ contains !> @brief Evaluates a weighted 2D quadrature sum over quadrature nodes for a single size bin. function f_quad2D(abscX, abscY, wght_in, pow) + $:GPU_ROUTINE(parallelism='[seq]') #:if not MFC_CASE_OPTIMIZATION and USING_AMD real(wp), dimension(4), intent(in) :: abscX, abscY, wght_in @@ -1018,15 +1064,15 @@ contains real(wp), dimension(nnode), intent(in) :: abscX, abscY, wght_in #:endif real(wp), dimension(3), intent(in) :: pow - - real(wp) :: f_quad2D - integer :: i + real(wp) :: f_quad2D + integer :: i f_quad2D = 0._wp $:GPU_LOOP(parallelism='[seq]') do i = 1, nnode f_quad2D = f_quad2D + wght_in(i)*(abscX(i)**pow(1))*(abscY(i)**pow(2)) end do + end function f_quad2D end subroutine s_mom_inv diff --git a/src/simulation/m_rhs.fpp b/src/simulation/m_rhs.fpp index 0b0d29d53b..c5e19eebb2 100644 --- a/src/simulation/m_rhs.fpp +++ b/src/simulation/m_rhs.fpp @@ -5,150 +5,116 @@ #:include 'case.fpp' #:include 'macros.fpp' -!> @brief Assembles the right-hand side of the governing equations using finite-volume flux differencing, Riemann solvers, and physical source terms +!> @brief Assembles the right-hand side of the governing equations using finite-volume flux differencing, Riemann solvers, and +!! physical source terms module m_rhs - use m_derived_types !< Definitions of the derived types - - use m_global_parameters !< Definitions of the global parameters - - use m_mpi_proxy !< Message passing interface (MPI) module proxy - - use m_variables_conversion !< State variables type conversion procedures - - use m_weno !< Weighted and essentially non-oscillatory (WENO) - !! schemes for spatial reconstruction of variables - - use m_muscl !< Monotonic Upstream-centered (MUSCL) - !! schemes for conservation laws - - use m_riemann_solvers !< Exact and approximate Riemann problem solvers - - use m_cbc !< Characteristic boundary conditions (CBC) - - use m_bubbles_EE !< Ensemble-averaged bubble dynamics routines - + use m_derived_types !< Definitions of the derived types + use m_global_parameters !< Definitions of the global parameters + use m_mpi_proxy !< Message passing interface (MPI) module proxy + use m_variables_conversion !< State variables type conversion procedures + use m_weno !< Weighted and essentially non-oscillatory (WENO) schemes for spatial reconstruction of variables + use m_muscl !< Monotonic Upstream-centered (MUSCL) schemes for conservation laws + use m_riemann_solvers !< Exact and approximate Riemann problem solvers + use m_cbc !< Characteristic boundary conditions (CBC) + use m_bubbles_EE !< Ensemble-averaged bubble dynamics routines use m_bubbles_EL - - use m_qbmm !< Moment inversion - + use m_qbmm !< Moment inversion use m_hypoelastic - use m_hyperelastic - use m_acoustic_src - use m_viscous - use m_ibm - use m_nvtx - use m_boundary_common - use m_helper - use m_surface_tension - use m_body_forces - use m_chemistry - use m_igr - use m_pressure_relaxation implicit none - private; public :: s_initialize_rhs_module, & - s_compute_rhs, & - s_finalize_rhs_module + private; public :: s_initialize_rhs_module, s_compute_rhs, s_finalize_rhs_module - !! This variable contains the WENO-reconstructed values of the cell-average - !! conservative variables, which are located in q_cons_vf, at cell-interior - !! Gaussian quadrature points (QP). - type(vector_field) :: q_cons_qp !< + !! This variable contains the WENO-reconstructed values of the cell-average conservative variables, which are located in + !! q_cons_vf, at cell-interior Gaussian quadrature points (QP). + type(vector_field) :: q_cons_qp $:GPU_DECLARE(create='[q_cons_qp]') - !! The primitive variables at cell-interior Gaussian quadrature points. These - !! are calculated from the conservative variables and gradient magnitude (GM) - !! of the volume fractions, q_cons_qp and gm_alpha_qp, respectively. - type(vector_field) :: q_prim_qp !< + !! The primitive variables at cell-interior Gaussian quadrature points. These are calculated from the conservative variables and + !! gradient magnitude (GM) of the volume fractions, q_cons_qp and gm_alpha_qp, respectively. + type(vector_field) :: q_prim_qp $:GPU_DECLARE(create='[q_prim_qp]') - !> @name The first-order spatial derivatives of the primitive variables at cell- - !! interior Gaussian quadrature points. These are WENO-reconstructed from - !! their respective cell-average values, obtained through the application - !! of the divergence theorem on the integral-average cell-boundary values - !! of the primitive variables, located in qK_prim_n, where K = L or R. + !> @name The first-order spatial derivatives of the primitive variables at cell- interior Gaussian quadrature points. These are + !! WENO-reconstructed from their respective cell-average values, obtained through the application of the divergence theorem on + !! the integral-average cell-boundary values of the primitive variables, located in qK_prim_n, where K = L or R. !> @{ type(vector_field), allocatable, dimension(:) :: dq_prim_dx_qp, dq_prim_dy_qp, dq_prim_dz_qp - $:GPU_DECLARE(create='[dq_prim_dx_qp,dq_prim_dy_qp,dq_prim_dz_qp]') + $:GPU_DECLARE(create='[dq_prim_dx_qp, dq_prim_dy_qp, dq_prim_dz_qp]') !> @} - !> @name The left and right WENO-reconstructed cell-boundary values of the cell- - !! average first-order spatial derivatives of the primitive variables. The - !! cell-average of the first-order spatial derivatives may be found in the - !! variables dq_prim_ds_qp, where s = x, y or z. + !> @name The left and right WENO-reconstructed cell-boundary values of the cell- average first-order spatial derivatives of the + !! primitive variables. The cell-average of the first-order spatial derivatives may be found in the variables dq_prim_ds_qp, + !! where s = x, y or z. !> @{ type(vector_field), allocatable, dimension(:) :: dqL_prim_dx_n, dqL_prim_dy_n, dqL_prim_dz_n type(vector_field), allocatable, dimension(:) :: dqR_prim_dx_n, dqR_prim_dy_n, dqR_prim_dz_n #if defined(MFC_OpenACC) - $:GPU_DECLARE(create='[dqL_prim_dx_n,dqL_prim_dy_n,dqL_prim_dz_n]') - $:GPU_DECLARE(create='[dqR_prim_dx_n,dqR_prim_dy_n,dqR_prim_dz_n]') + $:GPU_DECLARE(create='[dqL_prim_dx_n, dqL_prim_dy_n, dqL_prim_dz_n]') + $:GPU_DECLARE(create='[dqR_prim_dx_n, dqR_prim_dy_n, dqR_prim_dz_n]') #endif !> @} type(scalar_field), allocatable, dimension(:) :: tau_Re_vf $:GPU_DECLARE(create='[tau_Re_vf]') - type(vector_field) :: gm_alpha_qp !< - !! The gradient magnitude of the volume fractions at cell-interior Gaussian - !! quadrature points. gm_alpha_qp is calculated from individual first-order - !! spatial derivatives located in dq_prim_ds_qp. + !> The gradient magnitude of the volume fractions at cell-interior Gaussian quadrature points. gm_alpha_qp is calculated from + !! individual first-order spatial derivatives located in dq_prim_ds_qp. + type(vector_field) :: gm_alpha_qp $:GPU_DECLARE(create='[gm_alpha_qp]') - !> @name The left and right WENO-reconstructed cell-boundary values of the cell- - !! average gradient magnitude of volume fractions, located in gm_alpha_qp. + !> @name The left and right WENO-reconstructed cell-boundary values of the cell- average gradient magnitude of volume fractions, + !! located in gm_alpha_qp. !> @{ type(vector_field), allocatable, dimension(:) :: gm_alphaL_n type(vector_field), allocatable, dimension(:) :: gm_alphaR_n #if defined(MFC_OpenACC) - $:GPU_DECLARE(create='[gm_alphaL_n,gm_alphaR_n]') + $:GPU_DECLARE(create='[gm_alphaL_n, gm_alphaR_n]') #endif !> @} - !> @name The cell-boundary values of the fluxes (src - source, gsrc - geometrical - !! source). These are computed by applying the chosen Riemann problem solver - !! .on the left and right cell-boundary values of the primitive variables + !> @name The cell-boundary values of the fluxes (src - source, gsrc - geometrical source). These are computed by applying the + !! chosen Riemann problem solver .on the left and right cell-boundary values of the primitive variables !> @{ type(vector_field), allocatable, dimension(:) :: flux_n type(vector_field), allocatable, dimension(:) :: flux_src_n type(vector_field), allocatable, dimension(:) :: flux_gsrc_n #if defined(MFC_OpenACC) - $:GPU_DECLARE(create='[flux_n,flux_src_n,flux_gsrc_n]') + $:GPU_DECLARE(create='[flux_n, flux_src_n, flux_gsrc_n]') #endif - !> @} type(vector_field), allocatable, dimension(:) :: qL_prim, qR_prim #if defined(MFC_OpenACC) - $:GPU_DECLARE(create='[qL_prim,qR_prim]') + $:GPU_DECLARE(create='[qL_prim, qR_prim]') #endif - type(int_bounds_info) :: iv !< Vector field indical bounds + type(int_bounds_info) :: iv !< Vector field indical bounds $:GPU_DECLARE(create='[iv]') !> @name Indical bounds in the x-, y- and z-directions !> @{ type(int_bounds_info) :: irx, iry, irz - $:GPU_DECLARE(create='[irx,iry,irz]') + $:GPU_DECLARE(create='[irx, iry, irz]') type(int_bounds_info) :: is1, is2, is3 !> @} - $:GPU_DECLARE(create='[is1,is2,is3]') + $:GPU_DECLARE(create='[is1, is2, is3]') !> @name Saved fluxes for testing !> @{ @@ -156,24 +122,23 @@ module m_rhs !> @} $:GPU_DECLARE(create='[alf_sum]') - real(wp), allocatable, dimension(:, :, :) :: blkmod1, blkmod2, alpha1, alpha2, Kterm - real(wp), allocatable, dimension(:, :, :, :) :: qL_rsx_vf, qL_rsy_vf, qL_rsz_vf, qR_rsx_vf, qR_rsy_vf, qR_rsz_vf - real(wp), allocatable, dimension(:, :, :, :) :: dqL_rsx_vf, dqL_rsy_vf, dqL_rsz_vf, dqR_rsx_vf, dqR_rsy_vf, dqR_rsz_vf - $:GPU_DECLARE(create='[blkmod1,blkmod2,alpha1,alpha2,Kterm]') - $:GPU_DECLARE(create='[qL_rsx_vf,qL_rsy_vf,qL_rsz_vf,qR_rsx_vf,qR_rsy_vf,qR_rsz_vf]') - $:GPU_DECLARE(create='[dqL_rsx_vf,dqL_rsy_vf,dqL_rsz_vf,dqR_rsx_vf,dqR_rsy_vf,dqR_rsz_vf]') + real(wp), allocatable, dimension(:,:,:) :: blkmod1, blkmod2, alpha1, alpha2, Kterm + real(wp), allocatable, dimension(:,:,:,:) :: qL_rsx_vf, qL_rsy_vf, qL_rsz_vf, qR_rsx_vf, qR_rsy_vf, qR_rsz_vf + real(wp), allocatable, dimension(:,:,:,:) :: dqL_rsx_vf, dqL_rsy_vf, dqL_rsz_vf, dqR_rsx_vf, dqR_rsy_vf, dqR_rsz_vf + $:GPU_DECLARE(create='[blkmod1, blkmod2, alpha1, alpha2, Kterm]') + $:GPU_DECLARE(create='[qL_rsx_vf, qL_rsy_vf, qL_rsz_vf, qR_rsx_vf, qR_rsy_vf, qR_rsz_vf]') + $:GPU_DECLARE(create='[dqL_rsx_vf, dqL_rsy_vf, dqL_rsz_vf, dqR_rsx_vf, dqR_rsy_vf, dqR_rsz_vf]') - real(wp), allocatable, dimension(:, :, :) :: nbub !< Bubble number density + real(wp), allocatable, dimension(:,:,:) :: nbub !< Bubble number density $:GPU_DECLARE(create='[nbub]') contains - !> The computation of parameters, the allocation of memory, - !! the association of pointers and/or the execution of any - !! other procedures that are necessary to setup the module. + !> The computation of parameters, the allocation of memory, the association of pointers and/or the execution of any other + !! procedures that are necessary to setup the module. impure subroutine s_initialize_rhs_module - integer :: i, j, k, l, id !< Generic loop iterators + integer :: i, j, k, l, id !< Generic loop iterators $:GPU_ENTER_DATA(copyin='[idwbuff]') $:GPU_UPDATE(device='[idwbuff]') @@ -183,26 +148,27 @@ contains if (.not. igr) then do l = 1, sys_size - @:ALLOCATE(q_cons_qp%vf(l)%sf(idwbuff(1)%beg:idwbuff(1)%end, idwbuff(2)%beg:idwbuff(2)%end, idwbuff(3)%beg:idwbuff(3)%end)) + @:ALLOCATE(q_cons_qp%vf(l)%sf(idwbuff(1)%beg:idwbuff(1)%end, idwbuff(2)%beg:idwbuff(2)%end, & + & idwbuff(3)%beg:idwbuff(3)%end)) end do do l = mom_idx%beg, E_idx - @:ALLOCATE(q_prim_qp%vf(l)%sf(idwbuff(1)%beg:idwbuff(1)%end, idwbuff(2)%beg:idwbuff(2)%end, idwbuff(3)%beg:idwbuff(3)%end)) + @:ALLOCATE(q_prim_qp%vf(l)%sf(idwbuff(1)%beg:idwbuff(1)%end, idwbuff(2)%beg:idwbuff(2)%end, & + & idwbuff(3)%beg:idwbuff(3)%end)) end do - end if if (surface_tension) then - ! This assumes that the color function advection equation is - ! the last equation. If this changes then this logic will + ! This assumes that the color function advection equation is the last equation. If this changes then this logic will ! need updated do l = adv_idx%end + 1, sys_size - 1 - @:ALLOCATE(q_prim_qp%vf(l)%sf(idwbuff(1)%beg:idwbuff(1)%end, idwbuff(2)%beg:idwbuff(2)%end, idwbuff(3)%beg:idwbuff(3)%end)) + @:ALLOCATE(q_prim_qp%vf(l)%sf(idwbuff(1)%beg:idwbuff(1)%end, idwbuff(2)%beg:idwbuff(2)%end, & + & idwbuff(3)%beg:idwbuff(3)%end)) end do else do l = adv_idx%end + 1, sys_size - @:ALLOCATE(q_prim_qp%vf(l)%sf(idwbuff(1)%beg:idwbuff(1)%end, idwbuff(2)%beg:idwbuff(2)%end, idwbuff(3)%beg:idwbuff(3)%end)) + @:ALLOCATE(q_prim_qp%vf(l)%sf(idwbuff(1)%beg:idwbuff(1)%end, idwbuff(2)%beg:idwbuff(2)%end, & + & idwbuff(3)%beg:idwbuff(3)%end)) end do - end if if (.not. igr) then @@ -211,7 +177,8 @@ contains do l = 1, cont_idx%end if (relativity) then ! Cons and Prim densities are different for relativity - @:ALLOCATE(q_prim_qp%vf(l)%sf(idwbuff(1)%beg:idwbuff(1)%end, idwbuff(2)%beg:idwbuff(2)%end, idwbuff(3)%beg:idwbuff(3)%end)) + @:ALLOCATE(q_prim_qp%vf(l)%sf(idwbuff(1)%beg:idwbuff(1)%end, idwbuff(2)%beg:idwbuff(2)%end, & + & idwbuff(3)%beg:idwbuff(3)%end)) else q_prim_qp%vf(l)%sf => q_cons_qp%vf(l)%sf $:GPU_ENTER_DATA(copyin='[q_prim_qp%vf(l)%sf]') @@ -227,15 +194,13 @@ contains end if if (surface_tension) then - q_prim_qp%vf(c_idx)%sf => & - q_cons_qp%vf(c_idx)%sf + q_prim_qp%vf(c_idx)%sf => q_cons_qp%vf(c_idx)%sf $:GPU_ENTER_DATA(copyin='[q_prim_qp%vf(c_idx)%sf]') $:GPU_ENTER_DATA(attach='[q_prim_qp%vf(c_idx)%sf]') end if if (hyper_cleaning) then - q_prim_qp%vf(psi_idx)%sf => & - q_cons_qp%vf(psi_idx)%sf + q_prim_qp%vf(psi_idx)%sf => q_cons_qp%vf(psi_idx)%sf $:GPU_ENTER_DATA(copyin='[q_prim_qp%vf(psi_idx)%sf]') $:GPU_ENTER_DATA(attach='[q_prim_qp%vf(psi_idx)%sf]') end if @@ -247,67 +212,49 @@ contains @:ALLOCATE(flux_gsrc_n(1:num_dims)) do i = 1, num_dims - @:ALLOCATE(flux_n(i)%vf(1:sys_size)) @:ALLOCATE(flux_src_n(i)%vf(1:sys_size)) @:ALLOCATE(flux_gsrc_n(i)%vf(1:sys_size)) if (i == 1) then do l = 1, sys_size - @:ALLOCATE(flux_n(i)%vf(l)%sf( & - & idwbuff(1)%beg:idwbuff(1)%end, & - & idwbuff(2)%beg:idwbuff(2)%end, & - & idwbuff(3)%beg:idwbuff(3)%end)) - @:ALLOCATE(flux_gsrc_n(i)%vf(l)%sf( & - & idwbuff(1)%beg:idwbuff(1)%end, & - & idwbuff(2)%beg:idwbuff(2)%end, & - & idwbuff(3)%beg:idwbuff(3)%end)) + @:ALLOCATE(flux_n(i)%vf(l)%sf( idwbuff(1)%beg:idwbuff(1)%end, idwbuff(2)%beg:idwbuff(2)%end, & + & idwbuff(3)%beg:idwbuff(3)%end)) + @:ALLOCATE(flux_gsrc_n(i)%vf(l)%sf( idwbuff(1)%beg:idwbuff(1)%end, idwbuff(2)%beg:idwbuff(2)%end, & + & idwbuff(3)%beg:idwbuff(3)%end)) end do if (viscous .or. surface_tension) then do l = mom_idx%beg, E_idx - @:ALLOCATE(flux_src_n(i)%vf(l)%sf( & - & idwbuff(1)%beg:idwbuff(1)%end, & - & idwbuff(2)%beg:idwbuff(2)%end, & - & idwbuff(3)%beg:idwbuff(3)%end)) + @:ALLOCATE(flux_src_n(i)%vf(l)%sf( idwbuff(1)%beg:idwbuff(1)%end, idwbuff(2)%beg:idwbuff(2)%end, & + & idwbuff(3)%beg:idwbuff(3)%end)) end do end if - @:ALLOCATE(flux_src_n(i)%vf(adv_idx%beg)%sf( & - & idwbuff(1)%beg:idwbuff(1)%end, & - & idwbuff(2)%beg:idwbuff(2)%end, & - & idwbuff(3)%beg:idwbuff(3)%end)) + @:ALLOCATE(flux_src_n(i)%vf(adv_idx%beg)%sf( idwbuff(1)%beg:idwbuff(1)%end, idwbuff(2)%beg:idwbuff(2)%end, & + & idwbuff(3)%beg:idwbuff(3)%end)) if (riemann_solver == 1 .or. riemann_solver == 4) then do l = adv_idx%beg + 1, adv_idx%end - @:ALLOCATE(flux_src_n(i)%vf(l)%sf( & - & idwbuff(1)%beg:idwbuff(1)%end, & - & idwbuff(2)%beg:idwbuff(2)%end, & - & idwbuff(3)%beg:idwbuff(3)%end)) + @:ALLOCATE(flux_src_n(i)%vf(l)%sf( idwbuff(1)%beg:idwbuff(1)%end, idwbuff(2)%beg:idwbuff(2)%end, & + & idwbuff(3)%beg:idwbuff(3)%end)) end do end if if (chemistry) then do l = chemxb, chemxe - @:ALLOCATE(flux_src_n(i)%vf(l)%sf( & - & idwbuff(1)%beg:idwbuff(1)%end, & - & idwbuff(2)%beg:idwbuff(2)%end, & - & idwbuff(3)%beg:idwbuff(3)%end)) + @:ALLOCATE(flux_src_n(i)%vf(l)%sf( idwbuff(1)%beg:idwbuff(1)%end, idwbuff(2)%beg:idwbuff(2)%end, & + & idwbuff(3)%beg:idwbuff(3)%end)) end do if (chem_params%diffusion .and. .not. viscous) then - @:ALLOCATE(flux_src_n(i)%vf(E_idx)%sf( & - & idwbuff(1)%beg:idwbuff(1)%end, & - & idwbuff(2)%beg:idwbuff(2)%end, & - & idwbuff(3)%beg:idwbuff(3)%end)) + @:ALLOCATE(flux_src_n(i)%vf(E_idx)%sf( idwbuff(1)%beg:idwbuff(1)%end, idwbuff(2)%beg:idwbuff(2)%end, & + & idwbuff(3)%beg:idwbuff(3)%end)) end if end if - else do l = 1, sys_size - @:ALLOCATE(flux_gsrc_n(i)%vf(l)%sf( & - idwbuff(1)%beg:idwbuff(1)%end, & - idwbuff(2)%beg:idwbuff(2)%end, & - idwbuff(3)%beg:idwbuff(3)%end)) + @:ALLOCATE(flux_gsrc_n(i)%vf(l)%sf( idwbuff(1)%beg:idwbuff(1)%end, idwbuff(2)%beg:idwbuff(2)%end, & + & idwbuff(3)%beg:idwbuff(3)%end)) end do end if @@ -329,13 +276,11 @@ contains $:GPU_ENTER_DATA(attach='[flux_src_n(i)%vf(l)%sf]') end do end if - end do ! END: Allocation/Association of flux_n, flux_src_n, and flux_gsrc_n end if if ((.not. igr) .or. dummy) then - ! Allocation of dq_prim_ds_qp @:ALLOCATE(dq_prim_dx_qp(1:1)) @:ALLOCATE(dq_prim_dy_qp(1:1)) @@ -356,41 +301,41 @@ contains @:ALLOCATE(qL_prim(i)%vf(1:sys_size)) @:ALLOCATE(qR_prim(i)%vf(1:sys_size)) do l = mom_idx%beg, mom_idx%end - @:ALLOCATE(qL_prim(i)%vf(l)%sf(idwbuff(1)%beg:idwbuff(1)%end, idwbuff(2)%beg:idwbuff(2)%end, idwbuff(3)%beg:idwbuff(3)%end)) - @:ALLOCATE(qR_prim(i)%vf(l)%sf(idwbuff(1)%beg:idwbuff(1)%end, idwbuff(2)%beg:idwbuff(2)%end, idwbuff(3)%beg:idwbuff(3)%end)) + @:ALLOCATE(qL_prim(i)%vf(l)%sf(idwbuff(1)%beg:idwbuff(1)%end, idwbuff(2)%beg:idwbuff(2)%end, & + & idwbuff(3)%beg:idwbuff(3)%end)) + @:ALLOCATE(qR_prim(i)%vf(l)%sf(idwbuff(1)%beg:idwbuff(1)%end, idwbuff(2)%beg:idwbuff(2)%end, & + & idwbuff(3)%beg:idwbuff(3)%end)) end do @:ACC_SETUP_VFs(qL_prim(i), qR_prim(i)) end do - @:ALLOCATE(qL_rsx_vf(idwbuff(1)%beg:idwbuff(1)%end, & - idwbuff(2)%beg:idwbuff(2)%end, idwbuff(3)%beg:idwbuff(3)%end, 1:sys_size)) - @:ALLOCATE(qR_rsx_vf(idwbuff(1)%beg:idwbuff(1)%end, & - idwbuff(2)%beg:idwbuff(2)%end, idwbuff(3)%beg:idwbuff(3)%end, 1:sys_size)) + @:ALLOCATE(qL_rsx_vf(idwbuff(1)%beg:idwbuff(1)%end, idwbuff(2)%beg:idwbuff(2)%end, idwbuff(3)%beg:idwbuff(3)%end, & + & 1:sys_size)) + @:ALLOCATE(qR_rsx_vf(idwbuff(1)%beg:idwbuff(1)%end, idwbuff(2)%beg:idwbuff(2)%end, idwbuff(3)%beg:idwbuff(3)%end, & + & 1:sys_size)) if (n > 0) then - - @:ALLOCATE(qL_rsy_vf(idwbuff(2)%beg:idwbuff(2)%end, & - idwbuff(1)%beg:idwbuff(1)%end, idwbuff(3)%beg:idwbuff(3)%end, 1:sys_size)) - @:ALLOCATE(qR_rsy_vf(idwbuff(2)%beg:idwbuff(2)%end, & - idwbuff(1)%beg:idwbuff(1)%end, idwbuff(3)%beg:idwbuff(3)%end, 1:sys_size)) + @:ALLOCATE(qL_rsy_vf(idwbuff(2)%beg:idwbuff(2)%end, idwbuff(1)%beg:idwbuff(1)%end, idwbuff(3)%beg:idwbuff(3)%end, & + & 1:sys_size)) + @:ALLOCATE(qR_rsy_vf(idwbuff(2)%beg:idwbuff(2)%end, idwbuff(1)%beg:idwbuff(1)%end, idwbuff(3)%beg:idwbuff(3)%end, & + & 1:sys_size)) else - @:ALLOCATE(qL_rsy_vf(idwbuff(1)%beg:idwbuff(1)%end, & - idwbuff(2)%beg:idwbuff(2)%end, idwbuff(3)%beg:idwbuff(3)%end, 1:sys_size)) - @:ALLOCATE(qR_rsy_vf(idwbuff(1)%beg:idwbuff(1)%end, & - idwbuff(2)%beg:idwbuff(2)%end, idwbuff(3)%beg:idwbuff(3)%end, 1:sys_size)) + @:ALLOCATE(qL_rsy_vf(idwbuff(1)%beg:idwbuff(1)%end, idwbuff(2)%beg:idwbuff(2)%end, idwbuff(3)%beg:idwbuff(3)%end, & + & 1:sys_size)) + @:ALLOCATE(qR_rsy_vf(idwbuff(1)%beg:idwbuff(1)%end, idwbuff(2)%beg:idwbuff(2)%end, idwbuff(3)%beg:idwbuff(3)%end, & + & 1:sys_size)) end if if (p > 0) then - @:ALLOCATE(qL_rsz_vf(idwbuff(3)%beg:idwbuff(3)%end, & - idwbuff(2)%beg:idwbuff(2)%end, idwbuff(1)%beg:idwbuff(1)%end, 1:sys_size)) - @:ALLOCATE(qR_rsz_vf(idwbuff(3)%beg:idwbuff(3)%end, & - idwbuff(2)%beg:idwbuff(2)%end, idwbuff(1)%beg:idwbuff(1)%end, 1:sys_size)) + @:ALLOCATE(qL_rsz_vf(idwbuff(3)%beg:idwbuff(3)%end, idwbuff(2)%beg:idwbuff(2)%end, idwbuff(1)%beg:idwbuff(1)%end, & + & 1:sys_size)) + @:ALLOCATE(qR_rsz_vf(idwbuff(3)%beg:idwbuff(3)%end, idwbuff(2)%beg:idwbuff(2)%end, idwbuff(1)%beg:idwbuff(1)%end, & + & 1:sys_size)) else - @:ALLOCATE(qL_rsz_vf(idwbuff(1)%beg:idwbuff(1)%end, & - idwbuff(2)%beg:idwbuff(2)%end, idwbuff(3)%beg:idwbuff(3)%end, 1:sys_size)) - @:ALLOCATE(qR_rsz_vf(idwbuff(1)%beg:idwbuff(1)%end, & - idwbuff(2)%beg:idwbuff(2)%end, idwbuff(3)%beg:idwbuff(3)%end, 1:sys_size)) - + @:ALLOCATE(qL_rsz_vf(idwbuff(1)%beg:idwbuff(1)%end, idwbuff(2)%beg:idwbuff(2)%end, idwbuff(3)%beg:idwbuff(3)%end, & + & 1:sys_size)) + @:ALLOCATE(qR_rsz_vf(idwbuff(1)%beg:idwbuff(1)%end, idwbuff(2)%beg:idwbuff(2)%end, idwbuff(3)%beg:idwbuff(3)%end, & + & 1:sys_size)) end if if (.not. viscous) then @@ -416,17 +361,14 @@ contains end if if (viscous) then - @:ALLOCATE(tau_Re_vf(1:sys_size)) do i = 1, num_dims - @:ALLOCATE(tau_Re_vf(cont_idx%end + i)%sf(idwbuff(1)%beg:idwbuff(1)%end, & - & idwbuff(2)%beg:idwbuff(2)%end, & - & idwbuff(3)%beg:idwbuff(3)%end)) + @:ALLOCATE(tau_Re_vf(cont_idx%end + i)%sf(idwbuff(1)%beg:idwbuff(1)%end, idwbuff(2)%beg:idwbuff(2)%end, & + & idwbuff(3)%beg:idwbuff(3)%end)) @:ACC_SETUP_SFs(tau_Re_vf(cont_idx%end + i)) end do - @:ALLOCATE(tau_Re_vf(E_idx)%sf(idwbuff(1)%beg:idwbuff(1)%end, & - & idwbuff(2)%beg:idwbuff(2)%end, & - & idwbuff(3)%beg:idwbuff(3)%end)) + @:ALLOCATE(tau_Re_vf(E_idx)%sf(idwbuff(1)%beg:idwbuff(1)%end, idwbuff(2)%beg:idwbuff(2)%end, & + & idwbuff(3)%beg:idwbuff(3)%end)) @:ACC_SETUP_SFs(tau_Re_vf(E_idx)) @:ALLOCATE(dq_prim_dx_qp(1)%vf(1:sys_size)) @@ -434,36 +376,27 @@ contains @:ALLOCATE(dq_prim_dz_qp(1)%vf(1:sys_size)) do l = mom_idx%beg, mom_idx%end - @:ALLOCATE(dq_prim_dx_qp(1)%vf(l)%sf( & - & idwbuff(1)%beg:idwbuff(1)%end, & - & idwbuff(2)%beg:idwbuff(2)%end, & - & idwbuff(3)%beg:idwbuff(3)%end)) + @:ALLOCATE(dq_prim_dx_qp(1)%vf(l)%sf( idwbuff(1)%beg:idwbuff(1)%end, idwbuff(2)%beg:idwbuff(2)%end, & + & idwbuff(3)%beg:idwbuff(3)%end)) end do @:ACC_SETUP_VFs(dq_prim_dx_qp(1)) if (n > 0) then - do l = mom_idx%beg, mom_idx%end - @:ALLOCATE(dq_prim_dy_qp(1)%vf(l)%sf( & - & idwbuff(1)%beg:idwbuff(1)%end, & - & idwbuff(2)%beg:idwbuff(2)%end, & - & idwbuff(3)%beg:idwbuff(3)%end)) + @:ALLOCATE(dq_prim_dy_qp(1)%vf(l)%sf( idwbuff(1)%beg:idwbuff(1)%end, idwbuff(2)%beg:idwbuff(2)%end, & + & idwbuff(3)%beg:idwbuff(3)%end)) end do @:ACC_SETUP_VFs(dq_prim_dy_qp(1)) if (p > 0) then - do l = mom_idx%beg, mom_idx%end - @:ALLOCATE(dq_prim_dz_qp(1)%vf(l)%sf( & - & idwbuff(1)%beg:idwbuff(1)%end, & - & idwbuff(2)%beg:idwbuff(2)%end, & - & idwbuff(3)%beg:idwbuff(3)%end)) + @:ALLOCATE(dq_prim_dz_qp(1)%vf(l)%sf( idwbuff(1)%beg:idwbuff(1)%end, idwbuff(2)%beg:idwbuff(2)%end, & + & idwbuff(3)%beg:idwbuff(3)%end)) end do @:ACC_SETUP_VFs(dq_prim_dz_qp(1)) end if - end if do i = 1, num_dims @@ -476,41 +409,28 @@ contains end do do i = 1, num_dims - do l = mom_idx%beg, mom_idx%end - @:ALLOCATE(dqL_prim_dx_n(i)%vf(l)%sf( & - & idwbuff(1)%beg:idwbuff(1)%end, & - & idwbuff(2)%beg:idwbuff(2)%end, & - & idwbuff(3)%beg:idwbuff(3)%end)) - @:ALLOCATE(dqR_prim_dx_n(i)%vf(l)%sf( & - & idwbuff(1)%beg:idwbuff(1)%end, & - & idwbuff(2)%beg:idwbuff(2)%end, & - & idwbuff(3)%beg:idwbuff(3)%end)) + @:ALLOCATE(dqL_prim_dx_n(i)%vf(l)%sf( idwbuff(1)%beg:idwbuff(1)%end, idwbuff(2)%beg:idwbuff(2)%end, & + & idwbuff(3)%beg:idwbuff(3)%end)) + @:ALLOCATE(dqR_prim_dx_n(i)%vf(l)%sf( idwbuff(1)%beg:idwbuff(1)%end, idwbuff(2)%beg:idwbuff(2)%end, & + & idwbuff(3)%beg:idwbuff(3)%end)) end do if (n > 0) then do l = mom_idx%beg, mom_idx%end - @:ALLOCATE(dqL_prim_dy_n(i)%vf(l)%sf( & - & idwbuff(1)%beg:idwbuff(1)%end, & - & idwbuff(2)%beg:idwbuff(2)%end, & - & idwbuff(3)%beg:idwbuff(3)%end)) - @:ALLOCATE(dqR_prim_dy_n(i)%vf(l)%sf( & - & idwbuff(1)%beg:idwbuff(1)%end, & - & idwbuff(2)%beg:idwbuff(2)%end, & - & idwbuff(3)%beg:idwbuff(3)%end)) + @:ALLOCATE(dqL_prim_dy_n(i)%vf(l)%sf( idwbuff(1)%beg:idwbuff(1)%end, idwbuff(2)%beg:idwbuff(2)%end, & + & idwbuff(3)%beg:idwbuff(3)%end)) + @:ALLOCATE(dqR_prim_dy_n(i)%vf(l)%sf( idwbuff(1)%beg:idwbuff(1)%end, idwbuff(2)%beg:idwbuff(2)%end, & + & idwbuff(3)%beg:idwbuff(3)%end)) end do end if if (p > 0) then do l = mom_idx%beg, mom_idx%end - @:ALLOCATE(dqL_prim_dz_n(i)%vf(l)%sf( & - & idwbuff(1)%beg:idwbuff(1)%end, & - & idwbuff(2)%beg:idwbuff(2)%end, & - & idwbuff(3)%beg:idwbuff(3)%end)) - @:ALLOCATE(dqR_prim_dz_n(i)%vf(l)%sf( & - & idwbuff(1)%beg:idwbuff(1)%end, & - & idwbuff(2)%beg:idwbuff(2)%end, & - & idwbuff(3)%beg:idwbuff(3)%end)) + @:ALLOCATE(dqL_prim_dz_n(i)%vf(l)%sf( idwbuff(1)%beg:idwbuff(1)%end, idwbuff(2)%beg:idwbuff(2)%end, & + & idwbuff(3)%beg:idwbuff(3)%end)) + @:ALLOCATE(dqR_prim_dz_n(i)%vf(l)%sf( idwbuff(1)%beg:idwbuff(1)%end, idwbuff(2)%beg:idwbuff(2)%end, & + & idwbuff(3)%beg:idwbuff(3)%end)) end do end if @@ -519,36 +439,35 @@ contains end do if (weno_Re_flux) then - @:ALLOCATE(dqL_rsx_vf(idwbuff(1)%beg:idwbuff(1)%end, & - idwbuff(2)%beg:idwbuff(2)%end, idwbuff(3)%beg:idwbuff(3)%end, mom_idx%beg:mom_idx%end)) - @:ALLOCATE(dqR_rsx_vf(idwbuff(1)%beg:idwbuff(1)%end, & - idwbuff(2)%beg:idwbuff(2)%end, idwbuff(3)%beg:idwbuff(3)%end, mom_idx%beg:mom_idx%end)) + @:ALLOCATE(dqL_rsx_vf(idwbuff(1)%beg:idwbuff(1)%end, idwbuff(2)%beg:idwbuff(2)%end, & + & idwbuff(3)%beg:idwbuff(3)%end, mom_idx%beg:mom_idx%end)) + @:ALLOCATE(dqR_rsx_vf(idwbuff(1)%beg:idwbuff(1)%end, idwbuff(2)%beg:idwbuff(2)%end, & + & idwbuff(3)%beg:idwbuff(3)%end, mom_idx%beg:mom_idx%end)) if (n > 0) then - @:ALLOCATE(dqL_rsy_vf(idwbuff(2)%beg:idwbuff(2)%end, & - idwbuff(1)%beg:idwbuff(1)%end, idwbuff(3)%beg:idwbuff(3)%end, mom_idx%beg:mom_idx%end)) - @:ALLOCATE(dqR_rsy_vf(idwbuff(2)%beg:idwbuff(2)%end, & - idwbuff(1)%beg:idwbuff(1)%end, idwbuff(3)%beg:idwbuff(3)%end, mom_idx%beg:mom_idx%end)) + @:ALLOCATE(dqL_rsy_vf(idwbuff(2)%beg:idwbuff(2)%end, idwbuff(1)%beg:idwbuff(1)%end, & + & idwbuff(3)%beg:idwbuff(3)%end, mom_idx%beg:mom_idx%end)) + @:ALLOCATE(dqR_rsy_vf(idwbuff(2)%beg:idwbuff(2)%end, idwbuff(1)%beg:idwbuff(1)%end, & + & idwbuff(3)%beg:idwbuff(3)%end, mom_idx%beg:mom_idx%end)) else - @:ALLOCATE(dqL_rsy_vf(idwbuff(1)%beg:idwbuff(1)%end, & - idwbuff(2)%beg:idwbuff(2)%end, idwbuff(3)%beg:idwbuff(3)%end, mom_idx%beg:mom_idx%end)) - @:ALLOCATE(dqR_rsy_vf(idwbuff(1)%beg:idwbuff(1)%end, & - idwbuff(2)%beg:idwbuff(2)%end, idwbuff(3)%beg:idwbuff(3)%end, mom_idx%beg:mom_idx%end)) + @:ALLOCATE(dqL_rsy_vf(idwbuff(1)%beg:idwbuff(1)%end, idwbuff(2)%beg:idwbuff(2)%end, & + & idwbuff(3)%beg:idwbuff(3)%end, mom_idx%beg:mom_idx%end)) + @:ALLOCATE(dqR_rsy_vf(idwbuff(1)%beg:idwbuff(1)%end, idwbuff(2)%beg:idwbuff(2)%end, & + & idwbuff(3)%beg:idwbuff(3)%end, mom_idx%beg:mom_idx%end)) end if if (p > 0) then - @:ALLOCATE(dqL_rsz_vf(idwbuff(3)%beg:idwbuff(3)%end, & - idwbuff(2)%beg:idwbuff(2)%end, idwbuff(1)%beg:idwbuff(1)%end, mom_idx%beg:mom_idx%end)) - @:ALLOCATE(dqR_rsz_vf(idwbuff(3)%beg:idwbuff(3)%end, & - idwbuff(2)%beg:idwbuff(2)%end, idwbuff(1)%beg:idwbuff(1)%end, mom_idx%beg:mom_idx%end)) + @:ALLOCATE(dqL_rsz_vf(idwbuff(3)%beg:idwbuff(3)%end, idwbuff(2)%beg:idwbuff(2)%end, & + & idwbuff(1)%beg:idwbuff(1)%end, mom_idx%beg:mom_idx%end)) + @:ALLOCATE(dqR_rsz_vf(idwbuff(3)%beg:idwbuff(3)%end, idwbuff(2)%beg:idwbuff(2)%end, & + & idwbuff(1)%beg:idwbuff(1)%end, mom_idx%beg:mom_idx%end)) else - @:ALLOCATE(dqL_rsz_vf(idwbuff(1)%beg:idwbuff(1)%end, & - idwbuff(2)%beg:idwbuff(2)%end, idwbuff(3)%beg:idwbuff(3)%end, mom_idx%beg:mom_idx%end)) - @:ALLOCATE(dqR_rsz_vf(idwbuff(1)%beg:idwbuff(1)%end, & - idwbuff(2)%beg:idwbuff(2)%end, idwbuff(3)%beg:idwbuff(3)%end, mom_idx%beg:mom_idx%end)) + @:ALLOCATE(dqL_rsz_vf(idwbuff(1)%beg:idwbuff(1)%end, idwbuff(2)%beg:idwbuff(2)%end, & + & idwbuff(3)%beg:idwbuff(3)%end, mom_idx%beg:mom_idx%end)) + @:ALLOCATE(dqR_rsz_vf(idwbuff(1)%beg:idwbuff(1)%end, idwbuff(2)%beg:idwbuff(2)%end, & + & idwbuff(3)%beg:idwbuff(3)%end, mom_idx%beg:mom_idx%end)) end if - end if ! end allocation for weno_Re_flux - + end if ! end allocation for weno_Re_flux else @:ALLOCATE(dq_prim_dx_qp(1)%vf(1:sys_size)) @:ALLOCATE(dq_prim_dy_qp(1)%vf(1:sys_size)) @@ -566,9 +485,9 @@ contains end if end if end do - end if ! end allocation of viscous variables + end if ! end allocation of viscous variables - $:GPU_PARALLEL_LOOP(private='[i,j,k,l,id]', collapse=4) + $:GPU_PARALLEL_LOOP(private='[i, j, k, l, id]', collapse=4) do id = 1, num_dims do i = 1, sys_size do l = idwbuff(3)%beg, idwbuff(3)%end @@ -581,8 +500,7 @@ contains end do end do $:END_GPU_PARALLEL_LOOP() - - end if ! end allocation for .not. igr + end if ! end allocation for .not. igr if (qbmm) then @:ALLOCATE(mom_sp(1:nmomsp), mom_3d(0:2, 0:2, nb)) @@ -590,20 +508,16 @@ contains do i = 0, 2 do j = 0, 2 do k = 1, nb - @:ALLOCATE(mom_3d(i, j, k)%sf( & - & idwbuff(1)%beg:idwbuff(1)%end, & - & idwbuff(2)%beg:idwbuff(2)%end, & - & idwbuff(3)%beg:idwbuff(3)%end)) + @:ALLOCATE(mom_3d(i, j, k)%sf( idwbuff(1)%beg:idwbuff(1)%end, idwbuff(2)%beg:idwbuff(2)%end, & + & idwbuff(3)%beg:idwbuff(3)%end)) @:ACC_SETUP_SFs(mom_3d(i, j, k)) end do end do end do do i = 1, nmomsp - @:ALLOCATE(mom_sp(i)%sf( & - & idwbuff(1)%beg:idwbuff(1)%end, & - & idwbuff(2)%beg:idwbuff(2)%end, & - & idwbuff(3)%beg:idwbuff(3)%end)) + @:ALLOCATE(mom_sp(i)%sf( idwbuff(1)%beg:idwbuff(1)%end, idwbuff(2)%beg:idwbuff(2)%end, & + & idwbuff(3)%beg:idwbuff(3)%end)) @:ACC_SETUP_SFs(mom_sp(i)) end do end if @@ -620,7 +534,8 @@ contains end if if (alt_soundspeed) then - @:ALLOCATE(blkmod1(0:m, 0:n, 0:p), blkmod2(0:m, 0:n, 0:p), alpha1(0:m, 0:n, 0:p), alpha2(0:m, 0:n, 0:p), Kterm(0:m, 0:n, 0:p)) + @:ALLOCATE(blkmod1(0:m, 0:n, 0:p), blkmod2(0:m, 0:n, 0:p), alpha1(0:m, 0:n, 0:p), alpha2(0:m, 0:n, 0:p), Kterm(0:m, & + & 0:n, 0:p)) end if call s_initialize_pressure_relaxation_module @@ -632,24 +547,27 @@ contains end subroutine s_initialize_rhs_module !> @brief Computes the right-hand side of the semi-discrete governing equations for a single time stage. - impure subroutine s_compute_rhs(q_cons_vf, q_T_sf, q_prim_vf, bc_type, rhs_vf, pb_in, rhs_pb, mv_in, rhs_mv, t_step, time_avg, stage) - - type(scalar_field), dimension(sys_size), intent(inout) :: q_cons_vf - type(scalar_field), intent(inout) :: q_T_sf - type(scalar_field), dimension(sys_size), intent(inout) :: q_prim_vf - type(integer_field), dimension(1:num_dims, 1:2), intent(in) :: bc_type - type(scalar_field), dimension(sys_size), intent(inout) :: rhs_vf - real(stp), dimension(idwbuff(1)%beg:, idwbuff(2)%beg:, idwbuff(3)%beg:, 1:, 1:), intent(inout) :: pb_in - real(wp), dimension(idwbuff(1)%beg:, idwbuff(2)%beg:, idwbuff(3)%beg:, 1:, 1:), intent(inout) :: rhs_pb ! TODO :: I think these other two variables need to be stp as well, but it doesn't compile like that right now - real(stp), dimension(idwbuff(1)%beg:, idwbuff(2)%beg:, idwbuff(3)%beg:, 1:, 1:), intent(inout) :: mv_in - real(wp), dimension(idwbuff(1)%beg:, idwbuff(2)%beg:, idwbuff(3)%beg:, 1:, 1:), intent(inout) :: rhs_mv + impure subroutine s_compute_rhs(q_cons_vf, q_T_sf, q_prim_vf, bc_type, rhs_vf, pb_in, rhs_pb, mv_in, rhs_mv, t_step, & + & time_avg, stage) + + type(scalar_field), dimension(sys_size), intent(inout) :: q_cons_vf + type(scalar_field), intent(inout) :: q_T_sf + type(scalar_field), dimension(sys_size), intent(inout) :: q_prim_vf + type(integer_field), dimension(1:num_dims,1:2), intent(in) :: bc_type + type(scalar_field), dimension(sys_size), intent(inout) :: rhs_vf + real(stp), dimension(idwbuff(1)%beg:,idwbuff(2)%beg:,idwbuff(3)%beg:,1:,1:), intent(inout) :: pb_in + + real(wp), dimension(idwbuff(1)%beg:,idwbuff(2)%beg:,idwbuff(3)%beg:,1:,1:), & + & intent(inout) & + & :: rhs_pb ! TODO :: I think these other two variables need to be stp as well, but it doesn't compile like that right now + real(stp), dimension(idwbuff(1)%beg:,idwbuff(2)%beg:,idwbuff(3)%beg:,1:,1:), intent(inout) :: mv_in + real(wp), dimension(idwbuff(1)%beg:,idwbuff(2)%beg:,idwbuff(3)%beg:,1:,1:), intent(inout) :: rhs_mv integer, intent(in) :: t_step real(wp), intent(inout) :: time_avg integer, intent(in) :: stage - real(wp) :: t_start, t_finish integer :: id - integer(kind=8) :: i, j, k, l, q !< Generic loop iterators + integer(kind=8) :: i, j, k, l, q !< Generic loop iterators call nvtxStartRange("COMPUTE-RHS") @@ -657,7 +575,7 @@ contains if (.not. igr .or. dummy) then ! Association/Population of Working Variables - $:GPU_PARALLEL_LOOP(private='[i,j,k,l]', collapse=4) + $:GPU_PARALLEL_LOOP(private='[i, j, k, l]', collapse=4) do i = 1, sys_size do l = idwbuff(3)%beg, idwbuff(3)%end do k = idwbuff(2)%beg, idwbuff(2)%end @@ -672,7 +590,7 @@ contains ! Converting Conservative to Primitive Variables if (mpp_lim .and. bubbles_euler) then - $:GPU_PARALLEL_LOOP(private='[j,k,l]', collapse=3) + $:GPU_PARALLEL_LOOP(private='[j, k, l]', collapse=3) do l = idwbuff(3)%beg, idwbuff(3)%end do k = idwbuff(2)%beg, idwbuff(2)%end do j = idwbuff(1)%beg, idwbuff(1)%end @@ -683,8 +601,8 @@ contains end do $:GPU_LOOP(parallelism='[seq]') do i = advxb, advxe - 1 - q_cons_qp%vf(i)%sf(j, k, l) = q_cons_qp%vf(i)%sf(j, k, l)*(1._wp - q_cons_qp%vf(alf_idx)%sf(j, k, l)) & - /alf_sum%sf(j, k, l) + q_cons_qp%vf(i)%sf(j, k, l) = q_cons_qp%vf(i)%sf(j, k, l)*(1._wp - q_cons_qp%vf(alf_idx)%sf(j, k, & + & l))/alf_sum%sf(j, k, l) end do end do end do @@ -700,11 +618,7 @@ contains end if if (.not. igr .or. dummy) then call nvtxStartRange("RHS-CONVERT") - call s_convert_conservative_to_primitive_variables( & - q_cons_qp%vf, & - q_T_sf, & - q_prim_qp%vf, & - idwint) + call s_convert_conservative_to_primitive_variables(q_cons_qp%vf, q_T_sf, q_prim_qp%vf, idwint) call nvtxEndRange call nvtxStartRange("RHS-COMMUNICATION") @@ -722,19 +636,14 @@ contains if (t_step == t_step_stop) return end if - if (qbmm) call s_mom_inv(q_cons_qp%vf, q_prim_qp%vf, mom_sp, mom_3d, pb_in, rhs_pb, mv_in, rhs_mv, idwbuff(1), idwbuff(2), idwbuff(3)) + if (qbmm) call s_mom_inv(q_cons_qp%vf, q_prim_qp%vf, mom_sp, mom_3d, pb_in, rhs_pb, mv_in, rhs_mv, idwbuff(1), & + & idwbuff(2), idwbuff(3)) if ((viscous .and. .not. igr) .or. dummy) then call nvtxStartRange("RHS-VISCOUS") - call s_get_viscous(qL_rsx_vf, qL_rsy_vf, qL_rsz_vf, & - dqL_prim_dx_n, dqL_prim_dy_n, dqL_prim_dz_n, & - qL_prim, & - qR_rsx_vf, qR_rsy_vf, qR_rsz_vf, & - dqR_prim_dx_n, dqR_prim_dy_n, dqR_prim_dz_n, & - qR_prim, & - q_prim_qp, & - dq_prim_dx_qp, dq_prim_dy_qp, dq_prim_dz_qp, & - idwbuff(1), idwbuff(2), idwbuff(3)) + call s_get_viscous(qL_rsx_vf, qL_rsy_vf, qL_rsz_vf, dqL_prim_dx_n, dqL_prim_dy_n, dqL_prim_dz_n, qL_prim, qR_rsx_vf, & + & qR_rsy_vf, qR_rsz_vf, dqR_prim_dx_n, dqR_prim_dy_n, dqR_prim_dz_n, qR_prim, q_prim_qp, & + & dq_prim_dx_qp, dq_prim_dy_qp, dq_prim_dz_qp, idwbuff(1), idwbuff(2), idwbuff(3)) call nvtxEndRange end if @@ -746,11 +655,9 @@ contains ! Dimensional Splitting Loop do id = 1, num_dims - if (igr .or. dummy) then - if (id == 1) then - $:GPU_PARALLEL_LOOP(private='[i,j,k,l]', collapse=4) + $:GPU_PARALLEL_LOOP(private='[i, j, k, l]', collapse=4) do l = -1, p + 1 do k = -1, n + 1 do j = -1, m + 1 @@ -777,7 +684,7 @@ contains call nvtxEndRange end if end if - if ((.not. igr) .or. dummy) then! Finite volume solve + if ((.not. igr) .or. dummy) then ! Finite volume solve ! Reconstructing Primitive/Conservative Variables call nvtxStartRange("RHS-WENO") @@ -786,153 +693,98 @@ contains if (all(Re_size == 0)) then ! Reconstruct densitiess iv%beg = 1; iv%end = sys_size - call s_reconstruct_cell_boundary_values( & - q_prim_qp%vf(1:sys_size), & - qL_rsx_vf, qL_rsy_vf, qL_rsz_vf, & - qR_rsx_vf, qR_rsy_vf, qR_rsz_vf, & - id) + call s_reconstruct_cell_boundary_values(q_prim_qp%vf(1:sys_size), qL_rsx_vf, qL_rsy_vf, qL_rsz_vf, & + & qR_rsx_vf, qR_rsy_vf, qR_rsz_vf, id) else iv%beg = 1; iv%end = contxe - call s_reconstruct_cell_boundary_values( & - q_prim_qp%vf(iv%beg:iv%end), & - qL_rsx_vf, qL_rsy_vf, qL_rsz_vf, & - qR_rsx_vf, qR_rsy_vf, qR_rsz_vf, & - id) + call s_reconstruct_cell_boundary_values(q_prim_qp%vf(iv%beg:iv%end), qL_rsx_vf, qL_rsy_vf, qL_rsz_vf, & + & qR_rsx_vf, qR_rsy_vf, qR_rsz_vf, id) iv%beg = E_idx; iv%end = sys_size - call s_reconstruct_cell_boundary_values( & - q_prim_qp%vf(iv%beg:iv%end), & - qL_rsx_vf, qL_rsy_vf, qL_rsz_vf, & - qR_rsx_vf, qR_rsy_vf, qR_rsz_vf, & - id) + call s_reconstruct_cell_boundary_values(q_prim_qp%vf(iv%beg:iv%end), qL_rsx_vf, qL_rsy_vf, qL_rsz_vf, & + & qR_rsx_vf, qR_rsy_vf, qR_rsz_vf, id) end if - else if (all(Re_size == 0)) then iv%beg = 1; iv%end = E_idx - 1 - call s_reconstruct_cell_boundary_values( & - q_prim_qp%vf(iv%beg:iv%end), & - qL_rsx_vf, qL_rsy_vf, qL_rsz_vf, & - qR_rsx_vf, qR_rsy_vf, qR_rsz_vf, & - id) + call s_reconstruct_cell_boundary_values(q_prim_qp%vf(iv%beg:iv%end), qL_rsx_vf, qL_rsy_vf, qL_rsz_vf, & + & qR_rsx_vf, qR_rsy_vf, qR_rsz_vf, id) iv%beg = E_idx; iv%end = E_idx - call s_reconstruct_cell_boundary_values_first_order( & - q_prim_qp%vf(E_idx), & - qL_rsx_vf, qL_rsy_vf, qL_rsz_vf, & - qR_rsx_vf, qR_rsy_vf, qR_rsz_vf, & - id) + call s_reconstruct_cell_boundary_values_first_order(q_prim_qp%vf(E_idx), qL_rsx_vf, qL_rsy_vf, qL_rsz_vf, & + & qR_rsx_vf, qR_rsy_vf, qR_rsz_vf, id) iv%beg = E_idx + 1; iv%end = sys_size - call s_reconstruct_cell_boundary_values( & - q_prim_qp%vf(iv%beg:iv%end), & - qL_rsx_vf, qL_rsy_vf, qL_rsz_vf, & - qR_rsx_vf, qR_rsy_vf, qR_rsz_vf, & - id) + call s_reconstruct_cell_boundary_values(q_prim_qp%vf(iv%beg:iv%end), qL_rsx_vf, qL_rsy_vf, qL_rsz_vf, & + & qR_rsx_vf, qR_rsy_vf, qR_rsz_vf, id) else iv%beg = 1; iv%end = contxe - call s_reconstruct_cell_boundary_values( & - q_prim_qp%vf(iv%beg:iv%end), & - qL_rsx_vf, qL_rsy_vf, qL_rsz_vf, & - qR_rsx_vf, qR_rsy_vf, qR_rsz_vf, & - id) + call s_reconstruct_cell_boundary_values(q_prim_qp%vf(iv%beg:iv%end), qL_rsx_vf, qL_rsy_vf, qL_rsz_vf, & + & qR_rsx_vf, qR_rsy_vf, qR_rsz_vf, id) iv%beg = E_idx; iv%end = E_idx - call s_reconstruct_cell_boundary_values_first_order( & - q_prim_qp%vf(E_idx), & - qL_rsx_vf, qL_rsy_vf, qL_rsz_vf, & - qR_rsx_vf, qR_rsy_vf, qR_rsz_vf, & - id) + call s_reconstruct_cell_boundary_values_first_order(q_prim_qp%vf(E_idx), qL_rsx_vf, qL_rsy_vf, qL_rsz_vf, & + & qR_rsx_vf, qR_rsy_vf, qR_rsz_vf, id) iv%beg = E_idx + 1; iv%end = sys_size - call s_reconstruct_cell_boundary_values( & - q_prim_qp%vf(iv%beg:iv%end), & - qL_rsx_vf, qL_rsy_vf, qL_rsz_vf, & - qR_rsx_vf, qR_rsy_vf, qR_rsz_vf, & - id) + call s_reconstruct_cell_boundary_values(q_prim_qp%vf(iv%beg:iv%end), qL_rsx_vf, qL_rsy_vf, qL_rsz_vf, & + & qR_rsx_vf, qR_rsy_vf, qR_rsz_vf, id) end if - end if ! Reconstruct viscous derivatives for viscosity if (weno_Re_flux) then iv%beg = momxb; iv%end = momxe - call s_reconstruct_cell_boundary_values_visc_deriv( & - dq_prim_dx_qp(1)%vf(iv%beg:iv%end), & - dqL_rsx_vf, dqL_rsy_vf, dqL_rsz_vf, & - dqR_rsx_vf, dqR_rsy_vf, dqR_rsz_vf, & - id, dqL_prim_dx_n(id)%vf(iv%beg:iv%end), dqR_prim_dx_n(id)%vf(iv%beg:iv%end), & - idwbuff(1), idwbuff(2), idwbuff(3)) + call s_reconstruct_cell_boundary_values_visc_deriv(dq_prim_dx_qp(1)%vf(iv%beg:iv%end), dqL_rsx_vf, & + & dqL_rsy_vf, dqL_rsz_vf, dqR_rsx_vf, dqR_rsy_vf, dqR_rsz_vf, id, dqL_prim_dx_n(id)%vf(iv%beg:iv%end), & + & dqR_prim_dx_n(id)%vf(iv%beg:iv%end), idwbuff(1), idwbuff(2), idwbuff(3)) if (n > 0) then - call s_reconstruct_cell_boundary_values_visc_deriv( & - dq_prim_dy_qp(1)%vf(iv%beg:iv%end), & - dqL_rsx_vf, dqL_rsy_vf, dqL_rsz_vf, & - dqR_rsx_vf, dqR_rsy_vf, dqR_rsz_vf, & - id, dqL_prim_dy_n(id)%vf(iv%beg:iv%end), dqR_prim_dy_n(id)%vf(iv%beg:iv%end), & - idwbuff(1), idwbuff(2), idwbuff(3)) + call s_reconstruct_cell_boundary_values_visc_deriv(dq_prim_dy_qp(1)%vf(iv%beg:iv%end), dqL_rsx_vf, & + & dqL_rsy_vf, dqL_rsz_vf, dqR_rsx_vf, dqR_rsy_vf, dqR_rsz_vf, id, & + & dqL_prim_dy_n(id)%vf(iv%beg:iv%end), dqR_prim_dy_n(id)%vf(iv%beg:iv%end), idwbuff(1), idwbuff(2), & + & idwbuff(3)) if (p > 0) then - call s_reconstruct_cell_boundary_values_visc_deriv( & - dq_prim_dz_qp(1)%vf(iv%beg:iv%end), & - dqL_rsx_vf, dqL_rsy_vf, dqL_rsz_vf, & - dqR_rsx_vf, dqR_rsy_vf, dqR_rsz_vf, & - id, dqL_prim_dz_n(id)%vf(iv%beg:iv%end), dqR_prim_dz_n(id)%vf(iv%beg:iv%end), & - idwbuff(1), idwbuff(2), idwbuff(3)) + call s_reconstruct_cell_boundary_values_visc_deriv(dq_prim_dz_qp(1)%vf(iv%beg:iv%end), dqL_rsx_vf, & + & dqL_rsy_vf, dqL_rsz_vf, dqR_rsx_vf, dqR_rsy_vf, dqR_rsz_vf, id, & + & dqL_prim_dz_n(id)%vf(iv%beg:iv%end), dqR_prim_dz_n(id)%vf(iv%beg:iv%end), idwbuff(1), & + & idwbuff(2), idwbuff(3)) end if end if end if - call nvtxEndRange ! WENO + call nvtxEndRange ! WENO ! Configuring Coordinate Direction Indexes if (id == 1) then irx%beg = -1; iry%beg = 0; irz%beg = 0 - elseif (id == 2) then + else if (id == 2) then irx%beg = 0; iry%beg = -1; irz%beg = 0 else irx%beg = 0; iry%beg = 0; irz%beg = -1 end if irx%end = m; iry%end = n; irz%end = p - ! $:GPU_UPDATE(host='[qL_rsx_vf,qR_rsx_vf]') - ! print *, "L", qL_rsx_vf(100:300, 0, 0, 1) - ! print *, "R", qR_rsx_vf(100:300, 0, 0, 1) + ! $:GPU_UPDATE(host='[qL_rsx_vf,qR_rsx_vf]') print *, "L", qL_rsx_vf(100:300, 0, 0, 1) print *, "R", + ! qR_rsx_vf(100:300, 0, 0, 1) - !Computing Riemann Solver Flux and Source Flux + ! Computing Riemann Solver Flux and Source Flux call nvtxStartRange("RHS-RIEMANN-SOLVER") - call s_riemann_solver(qR_rsx_vf, qR_rsy_vf, qR_rsz_vf, & - dqR_prim_dx_n(id)%vf, & - dqR_prim_dy_n(id)%vf, & - dqR_prim_dz_n(id)%vf, & - qR_prim(id)%vf, & - qL_rsx_vf, qL_rsy_vf, qL_rsz_vf, & - dqL_prim_dx_n(id)%vf, & - dqL_prim_dy_n(id)%vf, & - dqL_prim_dz_n(id)%vf, & - qL_prim(id)%vf, & - q_prim_qp%vf, & - flux_n(id)%vf, & - flux_src_n(id)%vf, & - flux_gsrc_n(id)%vf, & - id, irx, iry, irz) + call s_riemann_solver(qR_rsx_vf, qR_rsy_vf, qR_rsz_vf, dqR_prim_dx_n(id)%vf, dqR_prim_dy_n(id)%vf, & + & dqR_prim_dz_n(id)%vf, qR_prim(id)%vf, qL_rsx_vf, qL_rsy_vf, qL_rsz_vf, & + & dqL_prim_dx_n(id)%vf, dqL_prim_dy_n(id)%vf, dqL_prim_dz_n(id)%vf, qL_prim(id)%vf, & + & q_prim_qp%vf, flux_n(id)%vf, flux_src_n(id)%vf, flux_gsrc_n(id)%vf, id, irx, iry, irz) call nvtxEndRange !$:GPU_UPDATE(host='[flux_n(1)%vf(1)%sf]') - !print *, "FLUX", flux_n(1)%vf(1)%sf(100:300, 0, 0) + ! print *, "FLUX", flux_n(1)%vf(1)%sf(100:300, 0, 0) - ! Additional physics and source terms - ! RHS addition for advection source + ! Additional physics and source terms RHS addition for advection source call nvtxStartRange("RHS-ADVECTION-SRC") - call s_compute_advection_source_term(id, & - rhs_vf, & - q_cons_qp, & - q_prim_qp, & - flux_src_n(id)) + call s_compute_advection_source_term(id, rhs_vf, q_cons_qp, q_prim_qp, flux_src_n(id)) call nvtxEndRange ! RHS additions for hypoelasticity call nvtxStartRange("RHS-HYPOELASTICITY") - if (hypoelasticity) call s_compute_hypoelastic_rhs(id, & - q_prim_qp%vf, & - rhs_vf) + if (hypoelasticity) call s_compute_hypoelastic_rhs(id, q_prim_qp%vf, rhs_vf) call nvtxEndRange ! RHS for diffusion @@ -945,13 +797,8 @@ contains ! RHS additions for viscosity if (viscous .or. surface_tension .or. chem_params%diffusion) then call nvtxStartRange("RHS-ADD-PHYSICS") - call s_compute_additional_physics_rhs(id, & - q_prim_qp%vf, & - rhs_vf, & - flux_src_n(id)%vf, & - dq_prim_dx_qp(1)%vf, & - dq_prim_dy_qp(1)%vf, & - dq_prim_dz_qp(1)%vf) + call s_compute_additional_physics_rhs(id, q_prim_qp%vf, rhs_vf, flux_src_n(id)%vf, dq_prim_dx_qp(1)%vf, & + & dq_prim_dy_qp(1)%vf, dq_prim_dz_qp(1)%vf) call nvtxEndRange end if @@ -965,24 +812,18 @@ contains ! RHS additions for qbmm bubbles if (qbmm) then call nvtxStartRange("RHS-QBMM") - call s_compute_qbmm_rhs(id, & - q_cons_qp%vf, & - q_prim_qp%vf, & - rhs_vf, & - flux_n(id)%vf, & - pb_in, & - rhs_pb) + call s_compute_qbmm_rhs(id, q_cons_qp%vf, q_prim_qp%vf, rhs_vf, flux_n(id)%vf, pb_in, rhs_pb) call nvtxEndRange end if ! END: Additional physics and source terms if (hyper_cleaning) then - $:GPU_PARALLEL_LOOP(private='[j,k,l]', collapse=3) + $:GPU_PARALLEL_LOOP(private='[j, k, l]', collapse=3) do l = 0, p do k = 0, n do j = 0, m - rhs_vf(psi_idx)%sf(j, k, l) = rhs_vf(psi_idx)%sf(j, k, l) - & - q_prim_vf(psi_idx)%sf(j, k, l)/hyper_cleaning_tau + rhs_vf(psi_idx)%sf(j, k, l) = rhs_vf(psi_idx)%sf(j, k, l) - q_prim_vf(psi_idx)%sf(j, k, & + & l)/hyper_cleaning_tau end do end do end do @@ -995,7 +836,7 @@ contains ! END: Dimensional Splitting Loop if (ib) then - $:GPU_PARALLEL_LOOP(private='[i,j,k,l]', collapse=3) + $:GPU_PARALLEL_LOOP(private='[i, j, k, l]', collapse=3) do l = 0, p do k = 0, n do j = 0, m @@ -1010,24 +851,17 @@ contains $:END_GPU_PARALLEL_LOOP() end if - ! Additional Physics and Source Terms - ! Additions for acoustic_source + ! Additional Physics and Source Terms Additions for acoustic_source if (acoustic_source) then call nvtxStartRange("RHS-ACOUSTIC-SRC") - call s_acoustic_src_calculations(q_cons_qp%vf(1:sys_size), & - q_prim_qp%vf(1:sys_size), & - rhs_vf) + call s_acoustic_src_calculations(q_cons_qp%vf(1:sys_size), q_prim_qp%vf(1:sys_size), rhs_vf) call nvtxEndRange end if ! Add bubbles source term if (bubbles_euler .and. (.not. adap_dt) .and. (.not. qbmm)) then call nvtxStartRange("RHS-BUBBLES-SRC") - call s_compute_bubble_EE_source( & - q_cons_qp%vf(1:sys_size), & - q_prim_qp%vf(1:sys_size), & - rhs_vf, & - divu) + call s_compute_bubble_EE_source(q_cons_qp%vf(1:sys_size), q_prim_qp%vf(1:sys_size), rhs_vf, divu) call nvtxEndRange end if @@ -1035,20 +869,14 @@ contains ! Compute bubble dynamics if (.not. adap_dt) then call nvtxStartRange("RHS-EL-BUBBLES-DYN") - call s_compute_bubble_EL_dynamics( & - q_prim_qp%vf(1:sys_size), & - bc_type, & - stage) + call s_compute_bubble_EL_dynamics(q_prim_qp%vf(1:sys_size), bc_type, stage) call nvtxEndRange end if ! RHS additions for sub-grid bubbles_lagrange if (lag_params%solver_approach == 2) then call nvtxStartRange("RHS-EL-BUBBLES-SRC") - call s_compute_bubbles_EL_source( & - q_cons_qp%vf(1:sys_size), & - q_prim_qp%vf(1:sys_size), & - rhs_vf) + call s_compute_bubbles_EL_source(q_cons_qp%vf(1:sys_size), q_prim_qp%vf(1:sys_size), rhs_vf) call nvtxEndRange end if end if @@ -1065,7 +893,7 @@ contains if (run_time_info .or. probe_wrt .or. ib .or. bubbles_lagrange) then if (.not. igr .or. dummy) then - $:GPU_PARALLEL_LOOP(private='[i,j,k,l]', collapse=4) + $:GPU_PARALLEL_LOOP(private='[i, j, k, l]', collapse=4) do i = 1, sys_size do l = idwbuff(3)%beg, idwbuff(3)%end do k = idwbuff(2)%beg, idwbuff(2)%end @@ -1099,23 +927,21 @@ contains type(vector_field), intent(inout) :: q_cons_vf type(vector_field), intent(inout) :: q_prim_vf type(vector_field), intent(inout) :: flux_src_n_vf - - integer :: j, k, l, q ! Loop iterators from original, meaning varies - integer :: k_loop, l_loop, q_loop ! Standardized spatial loop iterators 0:m, 0:n, 0:p + integer :: j, k, l, q ! Loop iterators from original, meaning varies + integer :: k_loop, l_loop, q_loop ! Standardized spatial loop iterators 0:m, 0:n, 0:p integer :: i_fluid_loop - real(wp) :: inv_ds, flux_face1, flux_face2 real(wp) :: advected_qty_val, pressure_val, velocity_val if (alt_soundspeed) then - $:GPU_PARALLEL_LOOP(private='[k_loop,l_loop,q_loop]', collapse=3) + $:GPU_PARALLEL_LOOP(private='[k_loop, l_loop, q_loop]', collapse=3) do q_loop = 0, p do l_loop = 0, n do k_loop = 0, m - blkmod1(k_loop, l_loop, q_loop) = ((gammas(1) + 1._wp)*q_prim_vf%vf(E_idx)%sf(k_loop, l_loop, q_loop) + & - pi_infs(1))/gammas(1) - blkmod2(k_loop, l_loop, q_loop) = ((gammas(2) + 1._wp)*q_prim_vf%vf(E_idx)%sf(k_loop, l_loop, q_loop) + & - pi_infs(2))/gammas(2) + blkmod1(k_loop, l_loop, q_loop) = ((gammas(1) + 1._wp)*q_prim_vf%vf(E_idx)%sf(k_loop, l_loop, & + & q_loop) + pi_infs(1))/gammas(1) + blkmod2(k_loop, l_loop, q_loop) = ((gammas(2) + 1._wp)*q_prim_vf%vf(E_idx)%sf(k_loop, l_loop, & + & q_loop) + pi_infs(2))/gammas(2) alpha1(k_loop, l_loop, q_loop) = q_cons_vf%vf(advxb)%sf(k_loop, l_loop, q_loop) if (bubbles_euler) then @@ -1124,10 +950,10 @@ contains alpha2(k_loop, l_loop, q_loop) = q_cons_vf%vf(advxe)%sf(k_loop, l_loop, q_loop) end if - Kterm(k_loop, l_loop, q_loop) = alpha1(k_loop, l_loop, q_loop)*alpha2(k_loop, l_loop, q_loop)* & - (blkmod2(k_loop, l_loop, q_loop) - blkmod1(k_loop, l_loop, q_loop))/ & - (alpha1(k_loop, l_loop, q_loop)*blkmod2(k_loop, l_loop, q_loop) + & - alpha2(k_loop, l_loop, q_loop)*blkmod1(k_loop, l_loop, q_loop)) + Kterm(k_loop, l_loop, q_loop) = alpha1(k_loop, l_loop, q_loop)*alpha2(k_loop, l_loop, & + & q_loop)*(blkmod2(k_loop, l_loop, q_loop) - blkmod1(k_loop, l_loop, q_loop))/(alpha1(k_loop, & + & l_loop, q_loop)*blkmod2(k_loop, l_loop, q_loop) + alpha2(k_loop, l_loop, q_loop)*blkmod1(k_loop, & + & l_loop, q_loop)) end do end do end do @@ -1143,7 +969,7 @@ contains call s_cbc(q_prim_vf%vf, flux_n(idir)%vf, flux_src_n_vf%vf, idir, 1, irx, iry, irz) end if - $:GPU_PARALLEL_LOOP(collapse=4,private='[j,k_loop,l_loop,q_loop,inv_ds,flux_face1,flux_face2]') + $:GPU_PARALLEL_LOOP(collapse=4,private='[j, k_loop, l_loop, q_loop, inv_ds, flux_face1, flux_face2]') do j = 1, sys_size do q_loop = 0, p do l_loop = 0, n @@ -1159,7 +985,8 @@ contains $:END_GPU_PARALLEL_LOOP() if (model_eqns == 3) then - $:GPU_PARALLEL_LOOP(collapse=4,private='[i_fluid_loop,k_loop,l_loop,q_loop,inv_ds,advected_qty_val, pressure_val,flux_face1,flux_face2]') + $:GPU_PARALLEL_LOOP(collapse=4,private='[i_fluid_loop, k_loop, l_loop, q_loop, inv_ds, advected_qty_val, & + & pressure_val, flux_face1, flux_face2]') do q_loop = 0, p do l_loop = 0, n do k_loop = 0, m @@ -1169,9 +996,9 @@ contains pressure_val = q_prim_vf%vf(E_idx)%sf(k_loop, l_loop, q_loop) flux_face1 = flux_src_n_vf%vf(advxb)%sf(k_loop, l_loop, q_loop) flux_face2 = flux_src_n_vf%vf(advxb)%sf(k_loop - 1, l_loop, q_loop) - rhs_vf(i_fluid_loop + intxb - 1)%sf(k_loop, l_loop, q_loop) = & - rhs_vf(i_fluid_loop + intxb - 1)%sf(k_loop, l_loop, q_loop) - & - inv_ds*advected_qty_val*pressure_val*(flux_face1 - flux_face2) + rhs_vf(i_fluid_loop + intxb - 1)%sf(k_loop, l_loop, & + & q_loop) = rhs_vf(i_fluid_loop + intxb - 1)%sf(k_loop, l_loop, & + & q_loop) - inv_ds*advected_qty_val*pressure_val*(flux_face1 - flux_face2) end do end do end do @@ -1180,8 +1007,7 @@ contains end if call s_add_directional_advection_source_terms(idir, rhs_vf, q_cons_vf, q_prim_vf, flux_src_n_vf, Kterm) - - case (2) ! y-direction + case (2) ! y-direction if (bc_y%beg <= BC_CHAR_SLIP_WALL .and. bc_y%beg >= BC_CHAR_SUP_OUTFLOW) then call s_cbc(q_prim_vf%vf, flux_n(idir)%vf, flux_src_n_vf%vf, idir, -1, irx, iry, irz) end if @@ -1189,7 +1015,7 @@ contains call s_cbc(q_prim_vf%vf, flux_n(idir)%vf, flux_src_n_vf%vf, idir, 1, irx, iry, irz) end if - $:GPU_PARALLEL_LOOP(collapse=4,private='[j,k,l,q,inv_ds,flux_face1,flux_face2]') + $:GPU_PARALLEL_LOOP(collapse=4,private='[j, k, l, q, inv_ds, flux_face1, flux_face2]') do j = 1, sys_size do l = 0, p do k = 0, n @@ -1205,7 +1031,8 @@ contains $:END_GPU_PARALLEL_LOOP() if (model_eqns == 3) then - $:GPU_PARALLEL_LOOP(collapse=4,private='[i_fluid_loop,k,l,q,inv_ds,advected_qty_val, pressure_val,flux_face1,flux_face2]') + $:GPU_PARALLEL_LOOP(collapse=4,private='[i_fluid_loop, k, l, q, inv_ds, advected_qty_val, pressure_val, & + & flux_face1, flux_face2]') do l = 0, p do k = 0, n do q = 0, m @@ -1215,13 +1042,11 @@ contains pressure_val = q_prim_vf%vf(E_idx)%sf(q, k, l) flux_face1 = flux_src_n_vf%vf(advxb)%sf(q, k, l) flux_face2 = flux_src_n_vf%vf(advxb)%sf(q, k - 1, l) - rhs_vf(i_fluid_loop + intxb - 1)%sf(q, k, l) = & - rhs_vf(i_fluid_loop + intxb - 1)%sf(q, k, l) - & - inv_ds*advected_qty_val*pressure_val*(flux_face1 - flux_face2) + rhs_vf(i_fluid_loop + intxb - 1)%sf(q, k, l) = rhs_vf(i_fluid_loop + intxb - 1)%sf(q, k, & + & l) - inv_ds*advected_qty_val*pressure_val*(flux_face1 - flux_face2) if (cyl_coord) then - rhs_vf(i_fluid_loop + intxb - 1)%sf(q, k, l) = & - rhs_vf(i_fluid_loop + intxb - 1)%sf(q, k, l) - & - 5.e-1_wp/y_cc(k)*advected_qty_val*pressure_val*(flux_face1 + flux_face2) + rhs_vf(i_fluid_loop + intxb - 1)%sf(q, k, l) = rhs_vf(i_fluid_loop + intxb - 1)%sf(q, k, & + & l) - 5.e-1_wp/y_cc(k)*advected_qty_val*pressure_val*(flux_face1 + flux_face2) end if end do end do @@ -1231,15 +1056,14 @@ contains end if if (cyl_coord) then - $:GPU_PARALLEL_LOOP(collapse=4,private='[j,k,l,q,flux_face1,flux_face2]') + $:GPU_PARALLEL_LOOP(collapse=4,private='[j, k, l, q, flux_face1, flux_face2]') do j = 1, sys_size do l = 0, p do k = 0, n do q = 0, m flux_face1 = flux_gsrc_n(2)%vf(j)%sf(q, k - 1, l) flux_face2 = flux_gsrc_n(2)%vf(j)%sf(q, k, l) - rhs_vf(j)%sf(q, k, l) = rhs_vf(j)%sf(q, k, l) - & - 5.e-1_wp/y_cc(k)*(flux_face1 + flux_face2) + rhs_vf(j)%sf(q, k, l) = rhs_vf(j)%sf(q, k, l) - 5.e-1_wp/y_cc(k)*(flux_face1 + flux_face2) end do end do end do @@ -1248,8 +1072,7 @@ contains end if call s_add_directional_advection_source_terms(idir, rhs_vf, q_cons_vf, q_prim_vf, flux_src_n_vf, Kterm) - - case (3) ! z-direction + case (3) ! z-direction if (bc_z%beg <= BC_CHAR_SLIP_WALL .and. bc_z%beg >= BC_CHAR_SUP_OUTFLOW) then call s_cbc(q_prim_vf%vf, flux_n(idir)%vf, flux_src_n_vf%vf, idir, -1, irx, iry, irz) end if @@ -1257,8 +1080,8 @@ contains call s_cbc(q_prim_vf%vf, flux_n(idir)%vf, flux_src_n_vf%vf, idir, 1, irx, iry, irz) end if - if (grid_geometry == 3) then ! Cylindrical Coordinates - $:GPU_PARALLEL_LOOP(collapse=4,private='[j,k,l,q,inv_ds,velocity_val,flux_face1,flux_face2]') + if (grid_geometry == 3) then ! Cylindrical Coordinates + $:GPU_PARALLEL_LOOP(collapse=4,private='[j, k, l, q, inv_ds, velocity_val, flux_face1, flux_face2]') do j = 1, sys_size do k = 0, p do q = 0, n @@ -1267,29 +1090,27 @@ contains velocity_val = q_prim_vf%vf(contxe + idir)%sf(l, q, k) flux_face1 = flux_n(3)%vf(j)%sf(l, q, k - 1) flux_face2 = flux_n(3)%vf(j)%sf(l, q, k) - rhs_vf(j)%sf(l, q, k) = rhs_vf(j)%sf(l, q, k) + & - inv_ds*velocity_val*(flux_face1 - flux_face2) + rhs_vf(j)%sf(l, q, k) = rhs_vf(j)%sf(l, q, k) + inv_ds*velocity_val*(flux_face1 - flux_face2) end do end do end do end do $:END_GPU_PARALLEL_LOOP() - $:GPU_PARALLEL_LOOP(collapse=4,private='[j,k,l,q,flux_face1,flux_face2]') + $:GPU_PARALLEL_LOOP(collapse=4,private='[j, k, l, q, flux_face1, flux_face2]') do j = 1, sys_size do k = 0, p do q = 0, n do l = 0, m flux_face1 = flux_gsrc_n(3)%vf(j)%sf(l, q, k - 1) flux_face2 = flux_gsrc_n(3)%vf(j)%sf(l, q, k) - rhs_vf(j)%sf(l, q, k) = rhs_vf(j)%sf(l, q, k) - & - 5.e-1_wp/y_cc(q)*(flux_face1 + flux_face2) + rhs_vf(j)%sf(l, q, k) = rhs_vf(j)%sf(l, q, k) - 5.e-1_wp/y_cc(q)*(flux_face1 + flux_face2) end do end do end do end do $:END_GPU_PARALLEL_LOOP() - else ! Cartesian Coordinates - $:GPU_PARALLEL_LOOP(collapse=4,private='[j,k,l,q,inv_ds,flux_face1,flux_face2]') + else ! Cartesian Coordinates + $:GPU_PARALLEL_LOOP(collapse=4,private='[j, k, l, q, inv_ds, flux_face1, flux_face2]') do j = 1, sys_size do k = 0, p do q = 0, n @@ -1306,7 +1127,8 @@ contains end if if (model_eqns == 3) then - $:GPU_PARALLEL_LOOP(collapse=4,private='[i_fluid_loop,k,l,q,inv_ds,advected_qty_val, pressure_val,flux_face1,flux_face2]') + $:GPU_PARALLEL_LOOP(collapse=4,private='[i_fluid_loop, k, l, q, inv_ds, advected_qty_val, pressure_val, & + & flux_face1, flux_face2]') do k = 0, p do q = 0, n do l = 0, m @@ -1316,9 +1138,8 @@ contains pressure_val = q_prim_vf%vf(E_idx)%sf(l, q, k) flux_face1 = flux_src_n_vf%vf(advxb)%sf(l, q, k) flux_face2 = flux_src_n_vf%vf(advxb)%sf(l, q, k - 1) - rhs_vf(i_fluid_loop + intxb - 1)%sf(l, q, k) = & - rhs_vf(i_fluid_loop + intxb - 1)%sf(l, q, k) - & - inv_ds*advected_qty_val*pressure_val*(flux_face1 - flux_face2) + rhs_vf(i_fluid_loop + intxb - 1)%sf(l, q, k) = rhs_vf(i_fluid_loop + intxb - 1)%sf(l, q, & + & k) - inv_ds*advected_qty_val*pressure_val*(flux_face1 - flux_face2) end do end do end do @@ -1327,165 +1148,171 @@ contains end if call s_add_directional_advection_source_terms(idir, rhs_vf, q_cons_vf, q_prim_vf, flux_src_n_vf, Kterm) - end select contains !> @brief Adds the advection source flux-difference terms for a single coordinate direction to the RHS. - subroutine s_add_directional_advection_source_terms(current_idir, rhs_vf_arg, q_cons_vf_arg, & - q_prim_vf_arg, flux_src_n_vf_arg, Kterm_arg) - integer, intent(in) :: current_idir + subroutine s_add_directional_advection_source_terms(current_idir, rhs_vf_arg, q_cons_vf_arg, q_prim_vf_arg, & + & flux_src_n_vf_arg, Kterm_arg) + integer, intent(in) :: current_idir type(scalar_field), dimension(sys_size), intent(inout) :: rhs_vf_arg - type(vector_field), intent(in) :: q_cons_vf_arg - type(vector_field), intent(in) :: q_prim_vf_arg - type(vector_field), intent(in) :: flux_src_n_vf_arg + type(vector_field), intent(in) :: q_cons_vf_arg + type(vector_field), intent(in) :: q_prim_vf_arg + type(vector_field), intent(in) :: flux_src_n_vf_arg ! CORRECTED DECLARATION FOR Kterm_arg: - real(wp), allocatable, dimension(:, :, :), intent(in) :: Kterm_arg - - integer :: j_adv, k_idx, l_idx, q_idx - real(wp) :: local_inv_ds, local_term_coeff, local_flux1, local_flux2 - real(wp) :: local_q_cons_val, local_k_term_val - logical :: use_standard_riemann + real(wp), allocatable, dimension(:,:,:), intent(in) :: Kterm_arg + integer :: j_adv, k_idx, l_idx, q_idx + real(wp) :: local_inv_ds, local_term_coeff, local_flux1, local_flux2 + real(wp) :: local_q_cons_val, local_k_term_val + logical :: use_standard_riemann select case (current_idir) - case (1) ! x-direction + case (1) ! x-direction use_standard_riemann = (riemann_solver == 1 .or. riemann_solver == 4) if (use_standard_riemann) then - $:GPU_PARALLEL_LOOP(collapse=4,private='[j_adv,k_idx,l_idx,q_idx,local_inv_ds, local_term_coeff,local_flux1,local_flux2]') + $:GPU_PARALLEL_LOOP(collapse=4,private='[j_adv, k_idx, l_idx, q_idx, local_inv_ds, local_term_coeff, & + & local_flux1, local_flux2]') do j_adv = advxb, advxe - do q_idx = 0, p ! z_extent - do l_idx = 0, n ! y_extent - do k_idx = 0, m ! x_extent + do q_idx = 0, p ! z_extent + do l_idx = 0, n ! y_extent + do k_idx = 0, m ! x_extent local_inv_ds = 1._wp/dx(k_idx) local_term_coeff = q_prim_vf_arg%vf(contxe + current_idir)%sf(k_idx, l_idx, q_idx) local_flux1 = flux_src_n_vf_arg%vf(j_adv)%sf(k_idx - 1, l_idx, q_idx) local_flux2 = flux_src_n_vf_arg%vf(j_adv)%sf(k_idx, l_idx, q_idx) - rhs_vf_arg(j_adv)%sf(k_idx, l_idx, q_idx) = rhs_vf_arg(j_adv)%sf(k_idx, l_idx, q_idx) + & - local_inv_ds*local_term_coeff*(local_flux1 - local_flux2) + rhs_vf_arg(j_adv)%sf(k_idx, l_idx, q_idx) = rhs_vf_arg(j_adv)%sf(k_idx, l_idx, & + & q_idx) + local_inv_ds*local_term_coeff*(local_flux1 - local_flux2) end do end do end do end do $:END_GPU_PARALLEL_LOOP() - else ! Other Riemann solvers + else ! Other Riemann solvers if (alt_soundspeed) then if (bubbles_euler .neqv. .true.) then - $:GPU_PARALLEL_LOOP(collapse=3, private='[k_idx,l_idx,q_idx,local_inv_ds, local_q_cons_val, local_k_term_val, local_term_coeff, local_flux1, local_flux2]') + $:GPU_PARALLEL_LOOP(collapse=3, private='[k_idx, l_idx, q_idx, local_inv_ds, local_q_cons_val, & + & local_k_term_val, local_term_coeff, local_flux1, local_flux2]') do q_idx = 0, p; do l_idx = 0, n; do k_idx = 0, m - local_inv_ds = 1._wp/dx(k_idx) - local_q_cons_val = q_cons_vf_arg%vf(advxe)%sf(k_idx, l_idx, q_idx) - local_k_term_val = Kterm_arg(k_idx, l_idx, q_idx) ! Access is safe due to outer alt_soundspeed check - local_term_coeff = local_q_cons_val - local_k_term_val - local_flux1 = flux_src_n_vf_arg%vf(advxe)%sf(k_idx, l_idx, q_idx) - local_flux2 = flux_src_n_vf_arg%vf(advxe)%sf(k_idx - 1, l_idx, q_idx) - rhs_vf_arg(advxe)%sf(k_idx, l_idx, q_idx) = rhs_vf_arg(advxe)%sf(k_idx, l_idx, q_idx) + & - local_inv_ds*local_term_coeff*(local_flux1 - local_flux2) - end do; end do; end do + local_inv_ds = 1._wp/dx(k_idx) + local_q_cons_val = q_cons_vf_arg%vf(advxe)%sf(k_idx, l_idx, q_idx) + local_k_term_val = Kterm_arg(k_idx, l_idx, q_idx) ! Access is safe due to outer alt_soundspeed check + local_term_coeff = local_q_cons_val - local_k_term_val + local_flux1 = flux_src_n_vf_arg%vf(advxe)%sf(k_idx, l_idx, q_idx) + local_flux2 = flux_src_n_vf_arg%vf(advxe)%sf(k_idx - 1, l_idx, q_idx) + rhs_vf_arg(advxe)%sf(k_idx, l_idx, q_idx) = rhs_vf_arg(advxe)%sf(k_idx, l_idx, & + & q_idx) + local_inv_ds*local_term_coeff*(local_flux1 - local_flux2) + end do; end do; end do $:END_GPU_PARALLEL_LOOP() - $:GPU_PARALLEL_LOOP(collapse=3, private='[k_idx,l_idx,q_idx,local_inv_ds,local_q_cons_val, local_k_term_val,local_term_coeff, local_flux1, local_flux2]') + $:GPU_PARALLEL_LOOP(collapse=3, private='[k_idx, l_idx, q_idx, local_inv_ds, local_q_cons_val, & + & local_k_term_val, local_term_coeff, local_flux1, local_flux2]') do q_idx = 0, p; do l_idx = 0, n; do k_idx = 0, m - local_inv_ds = 1._wp/dx(k_idx) - local_q_cons_val = q_cons_vf_arg%vf(advxb)%sf(k_idx, l_idx, q_idx) - local_k_term_val = Kterm_arg(k_idx, l_idx, q_idx) ! Access is safe - local_term_coeff = local_q_cons_val + local_k_term_val - local_flux1 = flux_src_n_vf_arg%vf(advxb)%sf(k_idx, l_idx, q_idx) - local_flux2 = flux_src_n_vf_arg%vf(advxb)%sf(k_idx - 1, l_idx, q_idx) - rhs_vf_arg(advxb)%sf(k_idx, l_idx, q_idx) = rhs_vf_arg(advxb)%sf(k_idx, l_idx, q_idx) + & - local_inv_ds*local_term_coeff*(local_flux1 - local_flux2) - end do; end do; end do + local_inv_ds = 1._wp/dx(k_idx) + local_q_cons_val = q_cons_vf_arg%vf(advxb)%sf(k_idx, l_idx, q_idx) + local_k_term_val = Kterm_arg(k_idx, l_idx, q_idx) ! Access is safe + local_term_coeff = local_q_cons_val + local_k_term_val + local_flux1 = flux_src_n_vf_arg%vf(advxb)%sf(k_idx, l_idx, q_idx) + local_flux2 = flux_src_n_vf_arg%vf(advxb)%sf(k_idx - 1, l_idx, q_idx) + rhs_vf_arg(advxb)%sf(k_idx, l_idx, q_idx) = rhs_vf_arg(advxb)%sf(k_idx, l_idx, & + & q_idx) + local_inv_ds*local_term_coeff*(local_flux1 - local_flux2) + end do; end do; end do $:END_GPU_PARALLEL_LOOP() end if - else ! NOT alt_soundspeed - $:GPU_PARALLEL_LOOP(collapse=4,private='[j_adv,k_idx,l_idx,q_idx,local_inv_ds, local_term_coeff,local_flux1,local_flux2]') + else ! NOT alt_soundspeed + $:GPU_PARALLEL_LOOP(collapse=4,private='[j_adv, k_idx, l_idx, q_idx, local_inv_ds, local_term_coeff, & + & local_flux1, local_flux2]') do j_adv = advxb, advxe do q_idx = 0, p; do l_idx = 0, n; do k_idx = 0, m - local_inv_ds = 1._wp/dx(k_idx) - local_term_coeff = q_cons_vf_arg%vf(j_adv)%sf(k_idx, l_idx, q_idx) - local_flux1 = flux_src_n_vf_arg%vf(j_adv)%sf(k_idx, l_idx, q_idx) - local_flux2 = flux_src_n_vf_arg%vf(j_adv)%sf(k_idx - 1, l_idx, q_idx) - rhs_vf_arg(j_adv)%sf(k_idx, l_idx, q_idx) = rhs_vf_arg(j_adv)%sf(k_idx, l_idx, q_idx) + & - local_inv_ds*local_term_coeff*(local_flux1 - local_flux2) - end do; end do; end do + local_inv_ds = 1._wp/dx(k_idx) + local_term_coeff = q_cons_vf_arg%vf(j_adv)%sf(k_idx, l_idx, q_idx) + local_flux1 = flux_src_n_vf_arg%vf(j_adv)%sf(k_idx, l_idx, q_idx) + local_flux2 = flux_src_n_vf_arg%vf(j_adv)%sf(k_idx - 1, l_idx, q_idx) + rhs_vf_arg(j_adv)%sf(k_idx, l_idx, q_idx) = rhs_vf_arg(j_adv)%sf(k_idx, l_idx, & + & q_idx) + local_inv_ds*local_term_coeff*(local_flux1 - local_flux2) + end do; end do; end do end do $:END_GPU_PARALLEL_LOOP() end if end if - - case (2) ! y-direction: loops q_idx (x), k_idx (y), l_idx (z); sf(q_idx, k_idx, l_idx); dy(k_idx); Kterm(q_idx,k_idx,l_idx) + case (2) & + & ! y-direction: loops q_idx (x), k_idx (y), l_idx (z); sf(q_idx, k_idx, l_idx); dy(k_idx); Kterm(q_idx,k_idx,l_idx) use_standard_riemann = (riemann_solver == 1 .or. riemann_solver == 4) if (use_standard_riemann) then - $:GPU_PARALLEL_LOOP(collapse=4,private='[j_adv,k_idx,l_idx,q_idx,local_inv_ds, local_term_coeff,local_flux1,local_flux2]') + $:GPU_PARALLEL_LOOP(collapse=4,private='[j_adv, k_idx, l_idx, q_idx, local_inv_ds, local_term_coeff, & + & local_flux1, local_flux2]') do j_adv = advxb, advxe - do l_idx = 0, p ! z_extent - do k_idx = 0, n ! y_extent - do q_idx = 0, m ! x_extent + do l_idx = 0, p ! z_extent + do k_idx = 0, n ! y_extent + do q_idx = 0, m ! x_extent local_inv_ds = 1._wp/dy(k_idx) local_term_coeff = q_prim_vf_arg%vf(contxe + current_idir)%sf(q_idx, k_idx, l_idx) local_flux1 = flux_src_n_vf_arg%vf(j_adv)%sf(q_idx, k_idx - 1, l_idx) local_flux2 = flux_src_n_vf_arg%vf(j_adv)%sf(q_idx, k_idx, l_idx) - rhs_vf_arg(j_adv)%sf(q_idx, k_idx, l_idx) = rhs_vf_arg(j_adv)%sf(q_idx, k_idx, l_idx) + & - local_inv_ds*local_term_coeff*(local_flux1 - local_flux2) + rhs_vf_arg(j_adv)%sf(q_idx, k_idx, l_idx) = rhs_vf_arg(j_adv)%sf(q_idx, k_idx, & + & l_idx) + local_inv_ds*local_term_coeff*(local_flux1 - local_flux2) end do end do end do end do $:END_GPU_PARALLEL_LOOP() - else ! Other Riemann solvers + else ! Other Riemann solvers if (alt_soundspeed) then if (bubbles_euler .neqv. .true.) then - $:GPU_PARALLEL_LOOP(collapse=3, private='[k_idx,l_idx,q_idx,local_inv_ds, local_q_cons_val, local_k_term_val, local_term_coeff, local_flux1, local_flux2]') + $:GPU_PARALLEL_LOOP(collapse=3, private='[k_idx, l_idx, q_idx, local_inv_ds, local_q_cons_val, & + & local_k_term_val, local_term_coeff, local_flux1, local_flux2]') do l_idx = 0, p; do k_idx = 0, n; do q_idx = 0, m - local_inv_ds = 1._wp/dy(k_idx) - local_q_cons_val = q_cons_vf_arg%vf(advxe)%sf(q_idx, k_idx, l_idx) - local_k_term_val = Kterm_arg(q_idx, k_idx, l_idx) ! Access is safe - local_term_coeff = local_q_cons_val - local_k_term_val - local_flux1 = flux_src_n_vf_arg%vf(advxe)%sf(q_idx, k_idx, l_idx) - local_flux2 = flux_src_n_vf_arg%vf(advxe)%sf(q_idx, k_idx - 1, l_idx) - rhs_vf_arg(advxe)%sf(q_idx, k_idx, l_idx) = rhs_vf_arg(advxe)%sf(q_idx, k_idx, l_idx) + & - local_inv_ds*local_term_coeff*(local_flux1 - local_flux2) - if (cyl_coord) then - rhs_vf_arg(advxe)%sf(q_idx, k_idx, l_idx) = rhs_vf_arg(advxe)%sf(q_idx, k_idx, l_idx) - & - (local_k_term_val/(2._wp*y_cc(k_idx)))*(local_flux1 + local_flux2) - end if - end do; end do; end do + local_inv_ds = 1._wp/dy(k_idx) + local_q_cons_val = q_cons_vf_arg%vf(advxe)%sf(q_idx, k_idx, l_idx) + local_k_term_val = Kterm_arg(q_idx, k_idx, l_idx) ! Access is safe + local_term_coeff = local_q_cons_val - local_k_term_val + local_flux1 = flux_src_n_vf_arg%vf(advxe)%sf(q_idx, k_idx, l_idx) + local_flux2 = flux_src_n_vf_arg%vf(advxe)%sf(q_idx, k_idx - 1, l_idx) + rhs_vf_arg(advxe)%sf(q_idx, k_idx, l_idx) = rhs_vf_arg(advxe)%sf(q_idx, k_idx, & + & l_idx) + local_inv_ds*local_term_coeff*(local_flux1 - local_flux2) + if (cyl_coord) then + rhs_vf_arg(advxe)%sf(q_idx, k_idx, l_idx) = rhs_vf_arg(advxe)%sf(q_idx, k_idx, & + & l_idx) - (local_k_term_val/(2._wp*y_cc(k_idx)))*(local_flux1 + local_flux2) + end if + end do; end do; end do $:END_GPU_PARALLEL_LOOP() - $:GPU_PARALLEL_LOOP(collapse=3, private='[k_idx,l_idx,q_idx,local_inv_ds, local_q_cons_val, local_k_term_val,local_term_coeff, local_flux1, local_flux2]') + $:GPU_PARALLEL_LOOP(collapse=3, private='[k_idx, l_idx, q_idx, local_inv_ds, local_q_cons_val, & + & local_k_term_val, local_term_coeff, local_flux1, local_flux2]') do l_idx = 0, p; do k_idx = 0, n; do q_idx = 0, m - local_inv_ds = 1._wp/dy(k_idx) - local_q_cons_val = q_cons_vf_arg%vf(advxb)%sf(q_idx, k_idx, l_idx) - local_k_term_val = Kterm_arg(q_idx, k_idx, l_idx) ! Access is safe - local_term_coeff = local_q_cons_val + local_k_term_val - local_flux1 = flux_src_n_vf_arg%vf(advxb)%sf(q_idx, k_idx, l_idx) - local_flux2 = flux_src_n_vf_arg%vf(advxb)%sf(q_idx, k_idx - 1, l_idx) - rhs_vf_arg(advxb)%sf(q_idx, k_idx, l_idx) = rhs_vf_arg(advxb)%sf(q_idx, k_idx, l_idx) + & - local_inv_ds*local_term_coeff*(local_flux1 - local_flux2) - if (cyl_coord) then - rhs_vf_arg(advxb)%sf(q_idx, k_idx, l_idx) = rhs_vf_arg(advxb)%sf(q_idx, k_idx, l_idx) + & - (local_k_term_val/(2._wp*y_cc(k_idx)))*(local_flux1 + local_flux2) - end if - end do; end do; end do + local_inv_ds = 1._wp/dy(k_idx) + local_q_cons_val = q_cons_vf_arg%vf(advxb)%sf(q_idx, k_idx, l_idx) + local_k_term_val = Kterm_arg(q_idx, k_idx, l_idx) ! Access is safe + local_term_coeff = local_q_cons_val + local_k_term_val + local_flux1 = flux_src_n_vf_arg%vf(advxb)%sf(q_idx, k_idx, l_idx) + local_flux2 = flux_src_n_vf_arg%vf(advxb)%sf(q_idx, k_idx - 1, l_idx) + rhs_vf_arg(advxb)%sf(q_idx, k_idx, l_idx) = rhs_vf_arg(advxb)%sf(q_idx, k_idx, & + & l_idx) + local_inv_ds*local_term_coeff*(local_flux1 - local_flux2) + if (cyl_coord) then + rhs_vf_arg(advxb)%sf(q_idx, k_idx, l_idx) = rhs_vf_arg(advxb)%sf(q_idx, k_idx, & + & l_idx) + (local_k_term_val/(2._wp*y_cc(k_idx)))*(local_flux1 + local_flux2) + end if + end do; end do; end do $:END_GPU_PARALLEL_LOOP() end if - else ! NOT alt_soundspeed - $:GPU_PARALLEL_LOOP(collapse=4,private='[j_adv,k_idx,l_idx,q_idx,local_inv_ds, local_term_coeff,local_flux1,local_flux2]') + else ! NOT alt_soundspeed + $:GPU_PARALLEL_LOOP(collapse=4,private='[j_adv, k_idx, l_idx, q_idx, local_inv_ds, local_term_coeff, & + & local_flux1, local_flux2]') do j_adv = advxb, advxe do l_idx = 0, p; do k_idx = 0, n; do q_idx = 0, m - local_inv_ds = 1._wp/dy(k_idx) - local_term_coeff = q_cons_vf_arg%vf(j_adv)%sf(q_idx, k_idx, l_idx) - local_flux1 = flux_src_n_vf_arg%vf(j_adv)%sf(q_idx, k_idx, l_idx) - local_flux2 = flux_src_n_vf_arg%vf(j_adv)%sf(q_idx, k_idx - 1, l_idx) - rhs_vf_arg(j_adv)%sf(q_idx, k_idx, l_idx) = rhs_vf_arg(j_adv)%sf(q_idx, k_idx, l_idx) + & - local_inv_ds*local_term_coeff*(local_flux1 - local_flux2) - end do; end do; end do + local_inv_ds = 1._wp/dy(k_idx) + local_term_coeff = q_cons_vf_arg%vf(j_adv)%sf(q_idx, k_idx, l_idx) + local_flux1 = flux_src_n_vf_arg%vf(j_adv)%sf(q_idx, k_idx, l_idx) + local_flux2 = flux_src_n_vf_arg%vf(j_adv)%sf(q_idx, k_idx - 1, l_idx) + rhs_vf_arg(j_adv)%sf(q_idx, k_idx, l_idx) = rhs_vf_arg(j_adv)%sf(q_idx, k_idx, & + & l_idx) + local_inv_ds*local_term_coeff*(local_flux1 - local_flux2) + end do; end do; end do end do $:END_GPU_PARALLEL_LOOP() end if end if - - case (3) ! z-direction: loops l_idx (x), q_idx (y), k_idx (z); sf(l_idx, q_idx, k_idx); dz(k_idx); Kterm(l_idx,q_idx,k_idx) + case (3) & + & ! z-direction: loops l_idx (x), q_idx (y), k_idx (z); sf(l_idx, q_idx, k_idx); dz(k_idx); Kterm(l_idx,q_idx,k_idx) if (grid_geometry == 3) then use_standard_riemann = (riemann_solver == 1) else @@ -1493,95 +1320,95 @@ contains end if if (use_standard_riemann) then - $:GPU_PARALLEL_LOOP(collapse=4,private='[j_adv,k_idx,l_idx,q_idx,local_inv_ds, local_term_coeff,local_flux1,local_flux2]') + $:GPU_PARALLEL_LOOP(collapse=4,private='[j_adv, k_idx, l_idx, q_idx, local_inv_ds, local_term_coeff, & + & local_flux1, local_flux2]') do j_adv = advxb, advxe - do k_idx = 0, p ! z_extent - do q_idx = 0, n ! y_extent - do l_idx = 0, m ! x_extent + do k_idx = 0, p ! z_extent + do q_idx = 0, n ! y_extent + do l_idx = 0, m ! x_extent local_inv_ds = 1._wp/dz(k_idx) local_term_coeff = q_prim_vf_arg%vf(contxe + current_idir)%sf(l_idx, q_idx, k_idx) local_flux1 = flux_src_n_vf_arg%vf(j_adv)%sf(l_idx, q_idx, k_idx - 1) local_flux2 = flux_src_n_vf_arg%vf(j_adv)%sf(l_idx, q_idx, k_idx) - rhs_vf_arg(j_adv)%sf(l_idx, q_idx, k_idx) = rhs_vf_arg(j_adv)%sf(l_idx, q_idx, k_idx) + & - local_inv_ds*local_term_coeff*(local_flux1 - local_flux2) + rhs_vf_arg(j_adv)%sf(l_idx, q_idx, k_idx) = rhs_vf_arg(j_adv)%sf(l_idx, q_idx, & + & k_idx) + local_inv_ds*local_term_coeff*(local_flux1 - local_flux2) end do end do end do end do $:END_GPU_PARALLEL_LOOP() - else ! Other Riemann solvers + else ! Other Riemann solvers if (alt_soundspeed) then if (bubbles_euler .neqv. .true.) then - $:GPU_PARALLEL_LOOP(collapse=3, private='[k_idx,l_idx,q_idx,local_inv_ds,local_q_cons_val, local_k_term_val, local_term_coeff, local_flux1, local_flux2]') + $:GPU_PARALLEL_LOOP(collapse=3, private='[k_idx, l_idx, q_idx, local_inv_ds, local_q_cons_val, & + & local_k_term_val, local_term_coeff, local_flux1, local_flux2]') do k_idx = 0, p; do q_idx = 0, n; do l_idx = 0, m - local_inv_ds = 1._wp/dz(k_idx) - local_q_cons_val = q_cons_vf_arg%vf(advxe)%sf(l_idx, q_idx, k_idx) - local_k_term_val = Kterm_arg(l_idx, q_idx, k_idx) ! Access is safe - local_term_coeff = local_q_cons_val - local_k_term_val - local_flux1 = flux_src_n_vf_arg%vf(advxe)%sf(l_idx, q_idx, k_idx) - local_flux2 = flux_src_n_vf_arg%vf(advxe)%sf(l_idx, q_idx, k_idx - 1) - rhs_vf_arg(advxe)%sf(l_idx, q_idx, k_idx) = rhs_vf_arg(advxe)%sf(l_idx, q_idx, k_idx) + & - local_inv_ds*local_term_coeff*(local_flux1 - local_flux2) - end do; end do; end do + local_inv_ds = 1._wp/dz(k_idx) + local_q_cons_val = q_cons_vf_arg%vf(advxe)%sf(l_idx, q_idx, k_idx) + local_k_term_val = Kterm_arg(l_idx, q_idx, k_idx) ! Access is safe + local_term_coeff = local_q_cons_val - local_k_term_val + local_flux1 = flux_src_n_vf_arg%vf(advxe)%sf(l_idx, q_idx, k_idx) + local_flux2 = flux_src_n_vf_arg%vf(advxe)%sf(l_idx, q_idx, k_idx - 1) + rhs_vf_arg(advxe)%sf(l_idx, q_idx, k_idx) = rhs_vf_arg(advxe)%sf(l_idx, q_idx, & + & k_idx) + local_inv_ds*local_term_coeff*(local_flux1 - local_flux2) + end do; end do; end do $:END_GPU_PARALLEL_LOOP() - $:GPU_PARALLEL_LOOP(collapse=3, private='[k_idx,l_idx,q_idx,local_inv_ds, local_q_cons_val, local_k_term_val, local_term_coeff, local_flux1, local_flux2]') + $:GPU_PARALLEL_LOOP(collapse=3, private='[k_idx, l_idx, q_idx, local_inv_ds, local_q_cons_val, & + & local_k_term_val, local_term_coeff, local_flux1, local_flux2]') do k_idx = 0, p; do q_idx = 0, n; do l_idx = 0, m - local_inv_ds = 1._wp/dz(k_idx) - local_q_cons_val = q_cons_vf_arg%vf(advxb)%sf(l_idx, q_idx, k_idx) - local_k_term_val = Kterm_arg(l_idx, q_idx, k_idx) ! Access is safe - local_term_coeff = local_q_cons_val + local_k_term_val - local_flux1 = flux_src_n_vf_arg%vf(advxb)%sf(l_idx, q_idx, k_idx) - local_flux2 = flux_src_n_vf_arg%vf(advxb)%sf(l_idx, q_idx, k_idx - 1) - rhs_vf_arg(advxb)%sf(l_idx, q_idx, k_idx) = rhs_vf_arg(advxb)%sf(l_idx, q_idx, k_idx) + & - local_inv_ds*local_term_coeff*(local_flux1 - local_flux2) - end do; end do; end do + local_inv_ds = 1._wp/dz(k_idx) + local_q_cons_val = q_cons_vf_arg%vf(advxb)%sf(l_idx, q_idx, k_idx) + local_k_term_val = Kterm_arg(l_idx, q_idx, k_idx) ! Access is safe + local_term_coeff = local_q_cons_val + local_k_term_val + local_flux1 = flux_src_n_vf_arg%vf(advxb)%sf(l_idx, q_idx, k_idx) + local_flux2 = flux_src_n_vf_arg%vf(advxb)%sf(l_idx, q_idx, k_idx - 1) + rhs_vf_arg(advxb)%sf(l_idx, q_idx, k_idx) = rhs_vf_arg(advxb)%sf(l_idx, q_idx, & + & k_idx) + local_inv_ds*local_term_coeff*(local_flux1 - local_flux2) + end do; end do; end do $:END_GPU_PARALLEL_LOOP() end if - else ! NOT alt_soundspeed - $:GPU_PARALLEL_LOOP(collapse=4, private='[j_adv,k_idx,l_idx,q_idx,local_inv_ds, local_term_coeff,local_flux1,local_flux2]') + else ! NOT alt_soundspeed + $:GPU_PARALLEL_LOOP(collapse=4, private='[j_adv, k_idx, l_idx, q_idx, local_inv_ds, local_term_coeff, & + & local_flux1, local_flux2]') do j_adv = advxb, advxe do k_idx = 0, p; do q_idx = 0, n; do l_idx = 0, m - local_inv_ds = 1._wp/dz(k_idx) - local_term_coeff = q_cons_vf_arg%vf(j_adv)%sf(l_idx, q_idx, k_idx) - local_flux1 = flux_src_n_vf_arg%vf(j_adv)%sf(l_idx, q_idx, k_idx) - local_flux2 = flux_src_n_vf_arg%vf(j_adv)%sf(l_idx, q_idx, k_idx - 1) - rhs_vf_arg(j_adv)%sf(l_idx, q_idx, k_idx) = rhs_vf_arg(j_adv)%sf(l_idx, q_idx, k_idx) + & - local_inv_ds*local_term_coeff*(local_flux1 - local_flux2) - end do; end do; end do + local_inv_ds = 1._wp/dz(k_idx) + local_term_coeff = q_cons_vf_arg%vf(j_adv)%sf(l_idx, q_idx, k_idx) + local_flux1 = flux_src_n_vf_arg%vf(j_adv)%sf(l_idx, q_idx, k_idx) + local_flux2 = flux_src_n_vf_arg%vf(j_adv)%sf(l_idx, q_idx, k_idx - 1) + rhs_vf_arg(j_adv)%sf(l_idx, q_idx, k_idx) = rhs_vf_arg(j_adv)%sf(l_idx, q_idx, & + & k_idx) + local_inv_ds*local_term_coeff*(local_flux1 - local_flux2) + end do; end do; end do end do $:END_GPU_PARALLEL_LOOP() end if end if end select + end subroutine s_add_directional_advection_source_terms end subroutine s_compute_advection_source_term !> @brief Adds viscous, surface-tension, and species-diffusion source flux contributions to the RHS for a given direction. - subroutine s_compute_additional_physics_rhs(idir, q_prim_vf, rhs_vf, flux_src_n_in, & - dq_prim_dx_vf, dq_prim_dy_vf, dq_prim_dz_vf) + subroutine s_compute_additional_physics_rhs(idir, q_prim_vf, rhs_vf, flux_src_n_in, dq_prim_dx_vf, dq_prim_dy_vf, dq_prim_dz_vf) - integer, intent(in) :: idir - type(scalar_field), dimension(sys_size), intent(in) :: q_prim_vf + integer, intent(in) :: idir + type(scalar_field), dimension(sys_size), intent(in) :: q_prim_vf type(scalar_field), dimension(sys_size), intent(inout) :: rhs_vf - type(scalar_field), dimension(sys_size), intent(in) :: flux_src_n_in - type(scalar_field), dimension(sys_size), intent(in) :: dq_prim_dx_vf, dq_prim_dy_vf, dq_prim_dz_vf + type(scalar_field), dimension(sys_size), intent(in) :: flux_src_n_in + type(scalar_field), dimension(sys_size), intent(in) :: dq_prim_dx_vf, dq_prim_dy_vf, dq_prim_dz_vf + integer :: i, j, k, l - integer :: i, j, k, l - - if (idir == 1) then ! x-direction + if (idir == 1) then ! x-direction if (surface_tension) then - $:GPU_PARALLEL_LOOP(private='[j,k,l]', collapse=3) + $:GPU_PARALLEL_LOOP(private='[j, k, l]', collapse=3) do l = 0, p do k = 0, n do j = 0, m - rhs_vf(c_idx)%sf(j, k, l) = & - rhs_vf(c_idx)%sf(j, k, l) + 1._wp/dx(j)* & - q_prim_vf(c_idx)%sf(j, k, l)* & - (flux_src_n_in(advxb)%sf(j, k, l) - & - flux_src_n_in(advxb)%sf(j - 1, k, l)) + rhs_vf(c_idx)%sf(j, k, l) = rhs_vf(c_idx)%sf(j, k, l) + 1._wp/dx(j)*q_prim_vf(c_idx)%sf(j, k, & + & l)*(flux_src_n_in(advxb)%sf(j, k, l) - flux_src_n_in(advxb)%sf(j - 1, k, l)) end do end do end do @@ -1589,34 +1416,29 @@ contains end if if ((surface_tension .or. viscous) .or. chem_params%diffusion) then - $:GPU_PARALLEL_LOOP(private='[j,k,l]', collapse=3) + $:GPU_PARALLEL_LOOP(private='[j, k, l]', collapse=3) do l = 0, p do k = 0, n do j = 0, m if (surface_tension .or. viscous) then $:GPU_LOOP(parallelism='[seq]') do i = momxb, E_idx - rhs_vf(i)%sf(j, k, l) = & - rhs_vf(i)%sf(j, k, l) + 1._wp/dx(j)* & - (flux_src_n_in(i)%sf(j - 1, k, l) & - - flux_src_n_in(i)%sf(j, k, l)) + rhs_vf(i)%sf(j, k, l) = rhs_vf(i)%sf(j, k, l) + 1._wp/dx(j)*(flux_src_n_in(i)%sf(j - 1, k, & + & l) - flux_src_n_in(i)%sf(j, k, l)) end do end if if (chem_params%diffusion) then $:GPU_LOOP(parallelism='[seq]') do i = chemxb, chemxe - rhs_vf(i)%sf(j, k, l) = & - rhs_vf(i)%sf(j, k, l) + 1._wp/dx(j)* & - (flux_src_n_in(i)%sf(j - 1, k, l) & - - flux_src_n_in(i)%sf(j, k, l)) + rhs_vf(i)%sf(j, k, l) = rhs_vf(i)%sf(j, k, l) + 1._wp/dx(j)*(flux_src_n_in(i)%sf(j - 1, k, & + & l) - flux_src_n_in(i)%sf(j, k, l)) end do if (.not. viscous) then - rhs_vf(E_idx)%sf(j, k, l) = & - rhs_vf(E_idx)%sf(j, k, l) + 1._wp/dx(j)* & - (flux_src_n_in(E_idx)%sf(j - 1, k, l) & - - flux_src_n_in(E_idx)%sf(j, k, l)) + rhs_vf(E_idx)%sf(j, k, l) = rhs_vf(E_idx)%sf(j, k, & + & l) + 1._wp/dx(j)*(flux_src_n_in(E_idx)%sf(j - 1, k, l) - flux_src_n_in(E_idx)%sf(j, & + & k, l)) end if end if end do @@ -1624,19 +1446,14 @@ contains end do $:END_GPU_PARALLEL_LOOP() end if - - elseif (idir == 2) then ! y-direction - + else if (idir == 2) then ! y-direction if (surface_tension) then - $:GPU_PARALLEL_LOOP(private='[j,k,l]', collapse=3) + $:GPU_PARALLEL_LOOP(private='[j, k, l]', collapse=3) do l = 0, p do k = 0, n do j = 0, m - rhs_vf(c_idx)%sf(j, k, l) = & - rhs_vf(c_idx)%sf(j, k, l) + 1._wp/dy(k)* & - q_prim_vf(c_idx)%sf(j, k, l)* & - (flux_src_n_in(advxb)%sf(j, k, l) - & - flux_src_n_in(advxb)%sf(j, k - 1, l)) + rhs_vf(c_idx)%sf(j, k, l) = rhs_vf(c_idx)%sf(j, k, l) + 1._wp/dy(k)*q_prim_vf(c_idx)%sf(j, k, & + & l)*(flux_src_n_in(advxb)%sf(j, k, l) - flux_src_n_in(advxb)%sf(j, k - 1, l)) end do end do end do @@ -1646,83 +1463,65 @@ contains if (cyl_coord .and. ((bc_y%beg == -2) .or. (bc_y%beg == -14))) then if (viscous .or. dummy) then if (p > 0) then - call s_compute_viscous_stress_cylindrical_boundary(q_prim_vf, & - dq_prim_dx_vf(mom_idx%beg:mom_idx%end), & - dq_prim_dy_vf(mom_idx%beg:mom_idx%end), & - dq_prim_dz_vf(mom_idx%beg:mom_idx%end), & - tau_Re_vf, & - idwbuff(1), idwbuff(2), idwbuff(3)) + call s_compute_viscous_stress_cylindrical_boundary(q_prim_vf, dq_prim_dx_vf(mom_idx%beg:mom_idx%end), & + & dq_prim_dy_vf(mom_idx%beg:mom_idx%end), dq_prim_dz_vf(mom_idx%beg:mom_idx%end), tau_Re_vf, & + & idwbuff(1), idwbuff(2), idwbuff(3)) else - call s_compute_viscous_stress_cylindrical_boundary(q_prim_vf, & - dq_prim_dx_vf(mom_idx%beg:mom_idx%end), & - dq_prim_dy_vf(mom_idx%beg:mom_idx%end), & - dq_prim_dz_vf(mom_idx%beg:mom_idx%end), & - tau_Re_vf, & - idwbuff(1), idwbuff(2), idwbuff(3)) + call s_compute_viscous_stress_cylindrical_boundary(q_prim_vf, dq_prim_dx_vf(mom_idx%beg:mom_idx%end), & + & dq_prim_dy_vf(mom_idx%beg:mom_idx%end), dq_prim_dz_vf(mom_idx%beg:mom_idx%end), tau_Re_vf, & + & idwbuff(1), idwbuff(2), idwbuff(3)) end if - $:GPU_PARALLEL_LOOP(private='[i,j,l]', collapse=2) + $:GPU_PARALLEL_LOOP(private='[i, j, l]', collapse=2) do l = 0, p do j = 0, m $:GPU_LOOP(parallelism='[seq]') do i = momxb, E_idx - rhs_vf(i)%sf(j, 0, l) = & - rhs_vf(i)%sf(j, 0, l) + 1._wp/(y_cc(1) - y_cc(-1))* & - (tau_Re_vf(i)%sf(j, -1, l) & - - tau_Re_vf(i)%sf(j, 1, l)) + rhs_vf(i)%sf(j, 0, l) = rhs_vf(i)%sf(j, 0, l) + 1._wp/(y_cc(1) - y_cc(-1))*(tau_Re_vf(i)%sf(j, & + & -1, l) - tau_Re_vf(i)%sf(j, 1, l)) end do end do end do $:END_GPU_PARALLEL_LOOP() - end if - $:GPU_PARALLEL_LOOP(private='[i,j,k,l]', collapse=3) + $:GPU_PARALLEL_LOOP(private='[i, j, k, l]', collapse=3) do l = 0, p do k = 1, n do j = 0, m $:GPU_LOOP(parallelism='[seq]') do i = momxb, E_idx - rhs_vf(i)%sf(j, k, l) = & - rhs_vf(i)%sf(j, k, l) + 1._wp/dy(k)* & - (flux_src_n_in(i)%sf(j, k - 1, l) & - - flux_src_n_in(i)%sf(j, k, l)) + rhs_vf(i)%sf(j, k, l) = rhs_vf(i)%sf(j, k, l) + 1._wp/dy(k)*(flux_src_n_in(i)%sf(j, k - 1, & + & l) - flux_src_n_in(i)%sf(j, k, l)) end do end do end do end do $:END_GPU_PARALLEL_LOOP() - else - if ((surface_tension .or. viscous) .or. chem_params%diffusion) then - $:GPU_PARALLEL_LOOP(private='[i,j,k,l]', collapse=3) + $:GPU_PARALLEL_LOOP(private='[i, j, k, l]', collapse=3) do l = 0, p do k = 0, n do j = 0, m if (surface_tension .or. viscous) then $:GPU_LOOP(parallelism='[seq]') do i = momxb, E_idx - rhs_vf(i)%sf(j, k, l) = & - rhs_vf(i)%sf(j, k, l) + 1._wp/dy(k)* & - (flux_src_n_in(i)%sf(j, k - 1, l) & - - flux_src_n_in(i)%sf(j, k, l)) + rhs_vf(i)%sf(j, k, l) = rhs_vf(i)%sf(j, k, l) + 1._wp/dy(k)*(flux_src_n_in(i)%sf(j, & + & k - 1, l) - flux_src_n_in(i)%sf(j, k, l)) end do end if if (chem_params%diffusion) then $:GPU_LOOP(parallelism='[seq]') do i = chemxb, chemxe - rhs_vf(i)%sf(j, k, l) = & - rhs_vf(i)%sf(j, k, l) + 1._wp/dy(k)* & - (flux_src_n_in(i)%sf(j, k - 1, l) & - - flux_src_n_in(i)%sf(j, k, l)) + rhs_vf(i)%sf(j, k, l) = rhs_vf(i)%sf(j, k, l) + 1._wp/dy(k)*(flux_src_n_in(i)%sf(j, & + & k - 1, l) - flux_src_n_in(i)%sf(j, k, l)) end do if (.not. viscous) then - rhs_vf(E_idx)%sf(j, k, l) = & - rhs_vf(E_idx)%sf(j, k, l) + 1._wp/dy(k)* & - (flux_src_n_in(E_idx)%sf(j, k - 1, l) & - - flux_src_n_in(E_idx)%sf(j, k, l)) + rhs_vf(E_idx)%sf(j, k, l) = rhs_vf(E_idx)%sf(j, k, & + & l) + 1._wp/dy(k)*(flux_src_n_in(E_idx)%sf(j, k - 1, & + & l) - flux_src_n_in(E_idx)%sf(j, k, l)) end if end if end do @@ -1732,21 +1531,17 @@ contains end if end if - ! Applying the geometrical viscous Riemann source fluxes calculated as average - ! of values at cell boundaries + ! Applying the geometrical viscous Riemann source fluxes calculated as average of values at cell boundaries if (cyl_coord) then if ((bc_y%beg == -2) .or. (bc_y%beg == -14)) then - - $:GPU_PARALLEL_LOOP(private='[i,j,k,l]', collapse=3) + $:GPU_PARALLEL_LOOP(private='[i, j, k, l]', collapse=3) do l = 0, p do k = 1, n do j = 0, m $:GPU_LOOP(parallelism='[seq]') do i = momxb, E_idx - rhs_vf(i)%sf(j, k, l) = & - rhs_vf(i)%sf(j, k, l) - 5.e-1_wp/y_cc(k)* & - (flux_src_n_in(i)%sf(j, k - 1, l) & - + flux_src_n_in(i)%sf(j, k, l)) + rhs_vf(i)%sf(j, k, l) = rhs_vf(i)%sf(j, k, l) - 5.e-1_wp/y_cc(k)*(flux_src_n_in(i)%sf(j, & + & k - 1, l) + flux_src_n_in(i)%sf(j, k, l)) end do end do end do @@ -1754,31 +1549,26 @@ contains $:END_GPU_PARALLEL_LOOP() if (viscous .or. dummy) then - $:GPU_PARALLEL_LOOP(private='[i,j,l]', collapse=2) + $:GPU_PARALLEL_LOOP(private='[i, j, l]', collapse=2) do l = 0, p do j = 0, m $:GPU_LOOP(parallelism='[seq]') do i = momxb, E_idx - rhs_vf(i)%sf(j, 0, l) = & - rhs_vf(i)%sf(j, 0, l) - 1._wp/y_cc(0)* & - tau_Re_vf(i)%sf(j, 0, l) + rhs_vf(i)%sf(j, 0, l) = rhs_vf(i)%sf(j, 0, l) - 1._wp/y_cc(0)*tau_Re_vf(i)%sf(j, 0, l) end do end do end do $:END_GPU_PARALLEL_LOOP() end if else - - $:GPU_PARALLEL_LOOP(private='[i,j,k,l]', collapse=3) + $:GPU_PARALLEL_LOOP(private='[i, j, k, l]', collapse=3) do l = 0, p do k = 0, n do j = 0, m $:GPU_LOOP(parallelism='[seq]') do i = momxb, E_idx - rhs_vf(i)%sf(j, k, l) = & - rhs_vf(i)%sf(j, k, l) - 5.e-1_wp/y_cc(k)* & - (flux_src_n_in(i)%sf(j, k - 1, l) & - + flux_src_n_in(i)%sf(j, k, l)) + rhs_vf(i)%sf(j, k, l) = rhs_vf(i)%sf(j, k, l) - 5.e-1_wp/y_cc(k)*(flux_src_n_in(i)%sf(j, & + & k - 1, l) + flux_src_n_in(i)%sf(j, k, l)) end do end do end do @@ -1786,19 +1576,14 @@ contains $:END_GPU_PARALLEL_LOOP() end if end if - - elseif (idir == 3) then ! z-direction - + else if (idir == 3) then ! z-direction if (surface_tension) then - $:GPU_PARALLEL_LOOP(private='[j,k,l]', collapse=3) + $:GPU_PARALLEL_LOOP(private='[j, k, l]', collapse=3) do l = 0, p do k = 0, n do j = 0, m - rhs_vf(c_idx)%sf(j, k, l) = & - rhs_vf(c_idx)%sf(j, k, l) + 1._wp/dz(l)* & - q_prim_vf(c_idx)%sf(j, k, l)* & - (flux_src_n_in(advxb)%sf(j, k, l) - & - flux_src_n_in(advxb)%sf(j, k, l - 1)) + rhs_vf(c_idx)%sf(j, k, l) = rhs_vf(c_idx)%sf(j, k, l) + 1._wp/dz(l)*q_prim_vf(c_idx)%sf(j, k, & + & l)*(flux_src_n_in(advxb)%sf(j, k, l) - flux_src_n_in(advxb)%sf(j, k, l - 1)) end do end do end do @@ -1806,33 +1591,28 @@ contains end if if ((surface_tension .or. viscous) .or. chem_params%diffusion) then - $:GPU_PARALLEL_LOOP(private='[i,j,k,l]', collapse=3) + $:GPU_PARALLEL_LOOP(private='[i, j, k, l]', collapse=3) do l = 0, p do k = 0, n do j = 0, m if (surface_tension .or. viscous) then $:GPU_LOOP(parallelism='[seq]') do i = momxb, E_idx - rhs_vf(i)%sf(j, k, l) = & - rhs_vf(i)%sf(j, k, l) + 1._wp/dz(l)* & - (flux_src_n_in(i)%sf(j, k, l - 1) & - - flux_src_n_in(i)%sf(j, k, l)) + rhs_vf(i)%sf(j, k, l) = rhs_vf(i)%sf(j, k, l) + 1._wp/dz(l)*(flux_src_n_in(i)%sf(j, k, & + & l - 1) - flux_src_n_in(i)%sf(j, k, l)) end do end if if (chem_params%diffusion) then $:GPU_LOOP(parallelism='[seq]') do i = chemxb, chemxe - rhs_vf(i)%sf(j, k, l) = & - rhs_vf(i)%sf(j, k, l) + 1._wp/dz(l)* & - (flux_src_n_in(i)%sf(j, k, l - 1) & - - flux_src_n_in(i)%sf(j, k, l)) + rhs_vf(i)%sf(j, k, l) = rhs_vf(i)%sf(j, k, l) + 1._wp/dz(l)*(flux_src_n_in(i)%sf(j, k, & + & l - 1) - flux_src_n_in(i)%sf(j, k, l)) end do if (.not. viscous) then - rhs_vf(E_idx)%sf(j, k, l) = & - rhs_vf(E_idx)%sf(j, k, l) + 1._wp/dz(l)* & - (flux_src_n_in(E_idx)%sf(j, k, l - 1) & - - flux_src_n_in(E_idx)%sf(j, k, l)) + rhs_vf(E_idx)%sf(j, k, l) = rhs_vf(E_idx)%sf(j, k, & + & l) + 1._wp/dz(l)*(flux_src_n_in(E_idx)%sf(j, k, l - 1) - flux_src_n_in(E_idx)%sf(j, & + & k, l)) end if end if end do @@ -1842,19 +1622,15 @@ contains end if if (grid_geometry == 3) then - $:GPU_PARALLEL_LOOP(private='[j,k,l]', collapse=3) + $:GPU_PARALLEL_LOOP(private='[j, k, l]', collapse=3) do l = 0, p do k = 0, n do j = 0, m - rhs_vf(momxb + 1)%sf(j, k, l) = & - rhs_vf(momxb + 1)%sf(j, k, l) + 5.e-1_wp* & - (flux_src_n_in(momxe)%sf(j, k, l - 1) & - + flux_src_n_in(momxe)%sf(j, k, l)) - - rhs_vf(momxe)%sf(j, k, l) = & - rhs_vf(momxe)%sf(j, k, l) - 5.e-1_wp* & - (flux_src_n_in(momxb + 1)%sf(j, k, l - 1) & - + flux_src_n_in(momxb + 1)%sf(j, k, l)) + rhs_vf(momxb + 1)%sf(j, k, l) = rhs_vf(momxb + 1)%sf(j, k, l) + 5.e-1_wp*(flux_src_n_in(momxe)%sf(j, & + & k, l - 1) + flux_src_n_in(momxe)%sf(j, k, l)) + + rhs_vf(momxe)%sf(j, k, l) = rhs_vf(momxe)%sf(j, k, l) - 5.e-1_wp*(flux_src_n_in(momxb + 1)%sf(j, k, & + & l - 1) + flux_src_n_in(momxb + 1)%sf(j, k, l)) end do end do end do @@ -1864,28 +1640,23 @@ contains end subroutine s_compute_additional_physics_rhs - !> The purpose of this subroutine is to WENO-reconstruct the - !! left and the right cell-boundary values, including values - !! at the Gaussian quadrature points, from the cell-averaged - !! variables. - !! @param v_vf Cell-average variables - !! @param vL_x Left reconstructed cell-boundary values in x - !! @param vL_y Left reconstructed cell-boundary values in y - !! @param vL_z Left reconstructed cell-boundary values in z - !! @param vR_x Right reconstructed cell-boundary values in x - !! @param vR_y Right reconstructed cell-boundary values in y - !! @param vR_z Right reconstructed cell-boundary values in z - !! @param norm_dir Splitting coordinate direction - subroutine s_reconstruct_cell_boundary_values(v_vf, vL_x, vL_y, vL_z, vR_x, vR_y, vR_z, & - norm_dir) + !> The purpose of this subroutine is to WENO-reconstruct the left and the right cell-boundary values, including values at the + !! Gaussian quadrature points, from the cell-averaged variables. + !! @param v_vf Cell-average variables + !! @param vL_x Left reconstructed cell-boundary values in x + !! @param vL_y Left reconstructed cell-boundary values in y + !! @param vL_z Left reconstructed cell-boundary values in z + !! @param vR_x Right reconstructed cell-boundary values in x + !! @param vR_y Right reconstructed cell-boundary values in y + !! @param vR_z Right reconstructed cell-boundary values in z + !! @param norm_dir Splitting coordinate direction + subroutine s_reconstruct_cell_boundary_values(v_vf, vL_x, vL_y, vL_z, vR_x, vR_y, vR_z, norm_dir) type(scalar_field), dimension(iv%beg:iv%end), intent(in) :: v_vf - real(wp), dimension(idwbuff(1)%beg:, idwbuff(2)%beg:, idwbuff(3)%beg:, 1:), intent(inout) :: vL_x, vL_y, vL_z - real(wp), dimension(idwbuff(1)%beg:, idwbuff(2)%beg:, idwbuff(3)%beg:, 1:), intent(inout) :: vR_x, vR_y, vR_z + real(wp), dimension(idwbuff(1)%beg:,idwbuff(2)%beg:,idwbuff(3)%beg:,1:), intent(inout) :: vL_x, vL_y, vL_z + real(wp), dimension(idwbuff(1)%beg:,idwbuff(2)%beg:,idwbuff(3)%beg:,1:), intent(inout) :: vR_x, vR_y, vR_z integer, intent(in) :: norm_dir - - integer :: recon_dir !< Coordinate direction of the reconstruction - + integer :: recon_dir !< Coordinate direction of the reconstruction integer :: i, j, k, l #:for SCHEME, TYPE in [('weno','WENO_TYPE'), ('muscl','MUSCL_TYPE')] @@ -1895,12 +1666,10 @@ contains is1 = idwbuff(1); is2 = idwbuff(2); is3 = idwbuff(3) recon_dir = 1; is1%beg = is1%beg + ${SCHEME}$_polyn is1%end = is1%end - ${SCHEME}$_polyn - - elseif (norm_dir == 2) then + else if (norm_dir == 2) then is1 = idwbuff(2); is2 = idwbuff(1); is3 = idwbuff(3) recon_dir = 2; is1%beg = is1%beg + ${SCHEME}$_polyn is1%end = is1%end - ${SCHEME}$_polyn - else is1 = idwbuff(3); is2 = idwbuff(2); is3 = idwbuff(1) recon_dir = 3; is1%beg = is1%beg + ${SCHEME}$_polyn @@ -1909,38 +1678,31 @@ contains if (n > 0) then if (p > 0) then - call s_${SCHEME}$ (v_vf(iv%beg:iv%end), & - vL_x(:, :, :, iv%beg:iv%end), vL_y(:, :, :, iv%beg:iv%end), vL_z(:, :, :, iv%beg:iv%end), vR_x(:, :, :, iv%beg:iv%end), vR_y(:, :, :, iv%beg:iv%end), vR_z(:, :, :, iv%beg:iv%end), & - recon_dir, & - is1, is2, is3) + call s_${SCHEME}$ (v_vf(iv%beg:iv%end), vL_x(:,:,:,iv%beg:iv%end), vL_y(:,:,:,iv%beg:iv%end), vL_z(:,:,:, & + & iv%beg:iv%end), vR_x(:,:,:,iv%beg:iv%end), vR_y(:,:,:,iv%beg:iv%end), vR_z(:,:,:, & + & iv%beg:iv%end), recon_dir, is1, is2, is3) else - call s_${SCHEME}$ (v_vf(iv%beg:iv%end), & - vL_x(:, :, :, iv%beg:iv%end), vL_y(:, :, :, iv%beg:iv%end), vL_z(:, :, :, :), vR_x(:, :, :, iv%beg:iv%end), vR_y(:, :, :, iv%beg:iv%end), vR_z(:, :, :, :), & - recon_dir, & - is1, is2, is3) + call s_${SCHEME}$ (v_vf(iv%beg:iv%end), vL_x(:,:,:,iv%beg:iv%end), vL_y(:,:,:,iv%beg:iv%end), vL_z(:,:,:, & + & :), vR_x(:,:,:,iv%beg:iv%end), vR_y(:,:,:,iv%beg:iv%end), vR_z(:,:,:,:), recon_dir, & + & is1, is2, is3) end if else - - call s_${SCHEME}$ (v_vf(iv%beg:iv%end), & - vL_x(:, :, :, iv%beg:iv%end), vL_y(:, :, :, :), vL_z(:, :, :, :), vR_x(:, :, :, iv%beg:iv%end), vR_y(:, :, :, :), vR_z(:, :, :, :), & - recon_dir, & - is1, is2, is3) + call s_${SCHEME}$ (v_vf(iv%beg:iv%end), vL_x(:,:,:,iv%beg:iv%end), vL_y(:,:,:,:), vL_z(:,:,:,:), vR_x(:,:,:, & + & iv%beg:iv%end), vR_y(:,:,:,:), vR_z(:,:,:,:), recon_dir, is1, is2, is3) end if end if #:endfor + end subroutine s_reconstruct_cell_boundary_values !> @brief Performs first-order (piecewise constant) reconstruction of left and right cell-boundary values. - subroutine s_reconstruct_cell_boundary_values_first_order(v_vf, vL_x, vL_y, vL_z, vR_x, vR_y, vR_z, & - norm_dir) + subroutine s_reconstruct_cell_boundary_values_first_order(v_vf, vL_x, vL_y, vL_z, vR_x, vR_y, vR_z, norm_dir) type(scalar_field), dimension(iv%beg:iv%end), intent(in) :: v_vf - real(wp), dimension(idwbuff(1)%beg:, idwbuff(2)%beg:, idwbuff(3)%beg:, 1:), intent(inout) :: vL_x, vL_y, vL_z - real(wp), dimension(idwbuff(1)%beg:, idwbuff(2)%beg:, idwbuff(3)%beg:, 1:), intent(inout) :: vR_x, vR_y, vR_z + real(wp), dimension(idwbuff(1)%beg:,idwbuff(2)%beg:,idwbuff(3)%beg:,1:), intent(inout) :: vL_x, vL_y, vL_z + real(wp), dimension(idwbuff(1)%beg:,idwbuff(2)%beg:,idwbuff(3)%beg:,1:), intent(inout) :: vR_x, vR_y, vR_z integer, intent(in) :: norm_dir - - integer :: recon_dir !< Coordinate direction of the WENO reconstruction - + integer :: recon_dir !< Coordinate direction of the WENO reconstruction integer :: i, j, k, l ! Reconstruction in s1-direction @@ -1950,25 +1712,22 @@ contains is1 = idwbuff(1); is2 = idwbuff(2); is3 = idwbuff(3) recon_dir = 1; is1%beg = is1%beg + ${SCHEME}$_polyn is1%end = is1%end - ${SCHEME}$_polyn - - elseif (norm_dir == 2) then + else if (norm_dir == 2) then is1 = idwbuff(2); is2 = idwbuff(1); is3 = idwbuff(3) recon_dir = 2; is1%beg = is1%beg + ${SCHEME}$_polyn is1%end = is1%end - ${SCHEME}$_polyn - else is1 = idwbuff(3); is2 = idwbuff(2); is3 = idwbuff(1) recon_dir = 3; is1%beg = is1%beg + ${SCHEME}$_polyn is1%end = is1%end - ${SCHEME}$_polyn - end if - $:GPU_UPDATE(device='[is1,is2,is3,iv]') + $:GPU_UPDATE(device='[is1, is2, is3, iv]') end if #:endfor if (recon_dir == 1) then - $:GPU_PARALLEL_LOOP(private='[i,j,k,l]', collapse=4) + $:GPU_PARALLEL_LOOP(private='[i, j, k, l]', collapse=4) do i = iv%beg, iv%end do l = is3%beg, is3%end do k = is2%beg, is2%end @@ -1981,7 +1740,7 @@ contains end do $:END_GPU_PARALLEL_LOOP() else if (recon_dir == 2) then - $:GPU_PARALLEL_LOOP(private='[i,j,k,l]', collapse=4) + $:GPU_PARALLEL_LOOP(private='[i, j, k, l]', collapse=4) do i = iv%beg, iv%end do l = is3%beg, is3%end do k = is2%beg, is2%end @@ -1994,7 +1753,7 @@ contains end do $:END_GPU_PARALLEL_LOOP() else if (recon_dir == 3) then - $:GPU_PARALLEL_LOOP(private='[i,j,k,l]', collapse=4) + $:GPU_PARALLEL_LOOP(private='[i, j, k, l]', collapse=4) do i = iv%beg, iv%end do l = is3%beg, is3%end do k = is2%beg, is2%end @@ -2057,7 +1816,6 @@ contains end do if (n > 0) then - do l = mom_idx%beg, mom_idx%end @:DEALLOCATE(dq_prim_dy_qp(1)%vf(l)%sf) end do @@ -2067,7 +1825,6 @@ contains @:DEALLOCATE(dq_prim_dz_qp(1)%vf(l)%sf) end do end if - end if @:DEALLOCATE(dq_prim_dx_qp(1)%vf) @@ -2075,7 +1832,6 @@ contains @:DEALLOCATE(dq_prim_dz_qp(1)%vf) do i = num_dims, 1, -1 - do l = mom_idx%beg, mom_idx%end @:DEALLOCATE(dqL_prim_dx_n(i)%vf(l)%sf) @:DEALLOCATE(dqR_prim_dx_n(i)%vf(l)%sf) @@ -2178,4 +1934,3 @@ contains end subroutine s_finalize_rhs_module end module m_rhs - diff --git a/src/simulation/m_riemann_solvers.fpp b/src/simulation/m_riemann_solvers.fpp index c28354d84e..096b16e057 100644 --- a/src/simulation/m_riemann_solvers.fpp +++ b/src/simulation/m_riemann_solvers.fpp @@ -10,29 +10,17 @@ module m_riemann_solvers - use m_derived_types !< Definitions of the derived types - - use m_global_parameters !< Definitions of the global parameters - - use m_mpi_proxy !< Message passing interface (MPI) module proxy - - use m_variables_conversion !< State variables type conversion procedures - - use m_bubbles !< To get the bubble wall pressure function - + use m_derived_types !< Definitions of the derived types + use m_global_parameters !< Definitions of the global parameters + use m_mpi_proxy !< Message passing interface (MPI) module proxy + use m_variables_conversion !< State variables type conversion procedures + use m_bubbles !< To get the bubble wall pressure function use m_bubbles_EE - - use m_surface_tension !< To get the capillary fluxes - - use m_helper_basic !< Functions to compare floating point numbers - + use m_surface_tension !< To get the capillary fluxes + use m_helper_basic !< Functions to compare floating point numbers use m_chemistry - - use m_thermochem, only: & - gas_constant, get_mixture_molecular_weight, & - get_mixture_specific_heat_cv_mass, get_mixture_energy_mass, & - get_species_specific_heats_r, get_species_enthalpies_rt, & - get_mixture_specific_heat_cp_mass + use m_thermochem, only: gas_constant, get_mixture_molecular_weight, get_mixture_specific_heat_cv_mass, & + & get_mixture_energy_mass, get_species_specific_heats_r, get_species_enthalpies_rt, get_mixture_specific_heat_cp_mass #:if USING_AMD use m_chemistry, only: molecular_weights_nonparameter @@ -40,54 +28,45 @@ module m_riemann_solvers implicit none - private; public :: s_initialize_riemann_solvers_module, & - s_riemann_solver, & - s_hll_riemann_solver, & - s_hllc_riemann_solver, & - s_hlld_riemann_solver, & - s_lf_riemann_solver, & - s_finalize_riemann_solvers_module - - !> The cell-boundary values of the fluxes (src - source) that are computed - !! through the chosen Riemann problem solver, and the direct evaluation of - !! source terms, by using the left and right states given in qK_prim_rs_vf, - !! dqK_prim_ds_vf where ds = dx, dy or dz. - !> @{ + private; public :: s_initialize_riemann_solvers_module, s_riemann_solver, s_hll_riemann_solver, s_hllc_riemann_solver, & + & s_hlld_riemann_solver, s_lf_riemann_solver, s_finalize_riemann_solvers_module - real(wp), allocatable, dimension(:, :, :, :) :: flux_rsx_vf, flux_src_rsx_vf - real(wp), allocatable, dimension(:, :, :, :) :: flux_rsy_vf, flux_src_rsy_vf - real(wp), allocatable, dimension(:, :, :, :) :: flux_rsz_vf, flux_src_rsz_vf - $:GPU_DECLARE(create='[flux_rsx_vf,flux_src_rsx_vf,flux_rsy_vf,flux_src_rsy_vf,flux_rsz_vf,flux_src_rsz_vf]') + !> The cell-boundary values of the fluxes (src - source) that are computed through the chosen Riemann problem solver, and the + !! direct evaluation of source terms, by using the left and right states given in qK_prim_rs_vf, dqK_prim_ds_vf where ds = dx, + !! dy or dz. + !> @{ + real(wp), allocatable, dimension(:,:,:,:) :: flux_rsx_vf, flux_src_rsx_vf + real(wp), allocatable, dimension(:,:,:,:) :: flux_rsy_vf, flux_src_rsy_vf + real(wp), allocatable, dimension(:,:,:,:) :: flux_rsz_vf, flux_src_rsz_vf + $:GPU_DECLARE(create='[flux_rsx_vf, flux_src_rsx_vf, flux_rsy_vf, flux_src_rsy_vf, flux_rsz_vf, flux_src_rsz_vf]') !> @} - !> The cell-boundary values of the geometrical source flux that are computed - !! through the chosen Riemann problem solver by using the left and right - !! states given in qK_prim_rs_vf. Currently 2D axisymmetric for inviscid only. + !> The cell-boundary values of the geometrical source flux that are computed through the chosen Riemann problem solver by using + !! the left and right states given in qK_prim_rs_vf. Currently 2D axisymmetric for inviscid only. !> @{ - - real(wp), allocatable, dimension(:, :, :, :) :: flux_gsrc_rsx_vf !< - real(wp), allocatable, dimension(:, :, :, :) :: flux_gsrc_rsy_vf !< - real(wp), allocatable, dimension(:, :, :, :) :: flux_gsrc_rsz_vf !< - $:GPU_DECLARE(create='[flux_gsrc_rsx_vf,flux_gsrc_rsy_vf,flux_gsrc_rsz_vf]') + real(wp), allocatable, dimension(:,:,:,:) :: flux_gsrc_rsx_vf + real(wp), allocatable, dimension(:,:,:,:) :: flux_gsrc_rsy_vf + real(wp), allocatable, dimension(:,:,:,:) :: flux_gsrc_rsz_vf + $:GPU_DECLARE(create='[flux_gsrc_rsx_vf, flux_gsrc_rsy_vf, flux_gsrc_rsz_vf]') !> @} - ! The cell-boundary values of the velocity. vel_src_rs_vf is determined as - ! part of Riemann problem solution and is used to evaluate the source flux. + ! The cell-boundary values of the velocity. vel_src_rs_vf is determined as part of Riemann problem solution and is used to + ! evaluate the source flux. - real(wp), allocatable, dimension(:, :, :, :) :: vel_src_rsx_vf - real(wp), allocatable, dimension(:, :, :, :) :: vel_src_rsy_vf - real(wp), allocatable, dimension(:, :, :, :) :: vel_src_rsz_vf - $:GPU_DECLARE(create='[vel_src_rsx_vf,vel_src_rsy_vf,vel_src_rsz_vf]') + real(wp), allocatable, dimension(:,:,:,:) :: vel_src_rsx_vf + real(wp), allocatable, dimension(:,:,:,:) :: vel_src_rsy_vf + real(wp), allocatable, dimension(:,:,:,:) :: vel_src_rsz_vf + $:GPU_DECLARE(create='[vel_src_rsx_vf, vel_src_rsy_vf, vel_src_rsz_vf]') - real(wp), allocatable, dimension(:, :, :, :) :: mom_sp_rsx_vf - real(wp), allocatable, dimension(:, :, :, :) :: mom_sp_rsy_vf - real(wp), allocatable, dimension(:, :, :, :) :: mom_sp_rsz_vf - $:GPU_DECLARE(create='[mom_sp_rsx_vf,mom_sp_rsy_vf,mom_sp_rsz_vf]') + real(wp), allocatable, dimension(:,:,:,:) :: mom_sp_rsx_vf + real(wp), allocatable, dimension(:,:,:,:) :: mom_sp_rsy_vf + real(wp), allocatable, dimension(:,:,:,:) :: mom_sp_rsz_vf + $:GPU_DECLARE(create='[mom_sp_rsx_vf, mom_sp_rsy_vf, mom_sp_rsz_vf]') - real(wp), allocatable, dimension(:, :, :, :) :: Re_avg_rsx_vf - real(wp), allocatable, dimension(:, :, :, :) :: Re_avg_rsy_vf - real(wp), allocatable, dimension(:, :, :, :) :: Re_avg_rsz_vf - $:GPU_DECLARE(create='[Re_avg_rsx_vf,Re_avg_rsy_vf,Re_avg_rsz_vf]') + real(wp), allocatable, dimension(:,:,:,:) :: Re_avg_rsx_vf + real(wp), allocatable, dimension(:,:,:,:) :: Re_avg_rsy_vf + real(wp), allocatable, dimension(:,:,:,:) :: Re_avg_rsz_vf + $:GPU_DECLARE(create='[Re_avg_rsx_vf, Re_avg_rsy_vf, Re_avg_rsz_vf]') !> @name Indical bounds in the s1-, s2- and s3-directions !> @{ @@ -95,273 +74,182 @@ module m_riemann_solvers type(int_bounds_info) :: isx, isy, isz !> @} - $:GPU_DECLARE(create='[is1,is2,is3,isx,isy,isz]') + $:GPU_DECLARE(create='[is1, is2, is3, isx, isy, isz]') real(wp), allocatable, dimension(:) :: Gs_rs $:GPU_DECLARE(create='[Gs_rs]') - real(wp), allocatable, dimension(:, :) :: Res_gs + real(wp), allocatable, dimension(:,:) :: Res_gs $:GPU_DECLARE(create='[Res_gs]') contains - !> Dispatch to the subroutines that are utilized to compute the - !! Riemann problem solution. For additional information please reference: - !! 1) s_hll_riemann_solver - !! 2) s_hllc_riemann_solver - !! 3) s_exact_riemann_solver - !! 4) s_hlld_riemann_solver - !! @param qL_prim_rsx_vf Left WENO-reconstructed cell-boundary values (x-dir) - !! @param qL_prim_rsy_vf Left WENO-reconstructed cell-boundary values (y-dir) - !! @param qL_prim_rsz_vf Left WENO-reconstructed cell-boundary values (z-dir) - !! @param dqL_prim_dx_vf The left WENO-reconstructed cell-boundary values of the - !! first-order x-dir spatial derivatives - !! @param dqL_prim_dy_vf The left WENO-reconstructed cell-boundary values of the - !! first-order y-dir spatial derivatives - !! @param dqL_prim_dz_vf The left WENO-reconstructed cell-boundary values of the - !! first-order z-dir spatial derivatives - !! @param qL_prim_vf The left WENO-reconstructed cell-boundary values of the - !! cell-average primitive variables - !! @param qR_prim_rsx_vf Right WENO-reconstructed cell-boundary values (x-dir) - !! @param qR_prim_rsy_vf Right WENO-reconstructed cell-boundary values (y-dir) - !! @param qR_prim_rsz_vf Right WENO-reconstructed cell-boundary values (z-dir) - !! @param dqR_prim_dx_vf The right WENO-reconstructed cell-boundary values of the - !! first-order x-dir spatial derivatives - !! @param dqR_prim_dy_vf The right WENO-reconstructed cell-boundary values of the - !! first-order y-dir spatial derivatives - !! @param dqR_prim_dz_vf The right WENO-reconstructed cell-boundary values of the - !! first-order z-dir spatial derivatives - !! @param qR_prim_vf The right WENO-reconstructed cell-boundary values of the - !! cell-average primitive variables - !! @param q_prim_vf Cell-averaged primitive variables - !! @param flux_vf Intra-cell fluxes - !! @param flux_src_vf Intra-cell fluxes sources - !! @param flux_gsrc_vf Intra-cell geometric fluxes sources - !! @param norm_dir Dir. splitting direction - !! @param ix Index bounds in the x-dir - !! @param iy Index bounds in the y-dir - !! @param iz Index bounds in the z-dir - subroutine s_riemann_solver(qL_prim_rsx_vf, qL_prim_rsy_vf, qL_prim_rsz_vf, dqL_prim_dx_vf, & - dqL_prim_dy_vf, & - dqL_prim_dz_vf, & - qL_prim_vf, & - qR_prim_rsx_vf, qR_prim_rsy_vf, qR_prim_rsz_vf, dqR_prim_dx_vf, & - dqR_prim_dy_vf, & - dqR_prim_dz_vf, & - qR_prim_vf, & - q_prim_vf, & - flux_vf, flux_src_vf, & - flux_gsrc_vf, & - norm_dir, ix, iy, iz) - - real(wp), dimension(idwbuff(1)%beg:, idwbuff(2)%beg:, idwbuff(3)%beg:, 1:), intent(INOUT) :: qL_prim_rsx_vf, qL_prim_rsy_vf, qL_prim_rsz_vf, qR_prim_rsx_vf, qR_prim_rsy_vf, qR_prim_rsz_vf - type(scalar_field), dimension(sys_size), intent(IN) :: q_prim_vf - - type(scalar_field), allocatable, dimension(:), intent(INOUT) :: qL_prim_vf, qR_prim_vf - - type(scalar_field), & - allocatable, dimension(:), & - intent(INOUT) :: dqL_prim_dx_vf, dqR_prim_dx_vf, & - dqL_prim_dy_vf, dqR_prim_dy_vf, & - dqL_prim_dz_vf, dqR_prim_dz_vf - - type(scalar_field), & - dimension(sys_size), & - intent(INOUT) :: flux_vf, flux_src_vf, flux_gsrc_vf - - integer, intent(IN) :: norm_dir - - type(int_bounds_info), intent(IN) :: ix, iy, iz + !> Dispatch to the subroutines that are utilized to compute the Riemann problem solution. For additional information please + !! reference: 1) s_hll_riemann_solver 2) s_hllc_riemann_solver 3) s_exact_riemann_solver 4) s_hlld_riemann_solver + !! @param qL_prim_rsx_vf Left WENO-reconstructed cell-boundary values (x-dir) + !! @param qL_prim_rsy_vf Left WENO-reconstructed cell-boundary values (y-dir) + !! @param qL_prim_rsz_vf Left WENO-reconstructed cell-boundary values (z-dir) + !! @param dqL_prim_dx_vf The left WENO-reconstructed cell-boundary values of the first-order x-dir spatial derivatives + !! @param dqL_prim_dy_vf The left WENO-reconstructed cell-boundary values of the first-order y-dir spatial derivatives + !! @param dqL_prim_dz_vf The left WENO-reconstructed cell-boundary values of the first-order z-dir spatial derivatives + !! @param qL_prim_vf The left WENO-reconstructed cell-boundary values of the cell-average primitive variables + !! @param qR_prim_rsx_vf Right WENO-reconstructed cell-boundary values (x-dir) + !! @param qR_prim_rsy_vf Right WENO-reconstructed cell-boundary values (y-dir) + !! @param qR_prim_rsz_vf Right WENO-reconstructed cell-boundary values (z-dir) + !! @param dqR_prim_dx_vf The right WENO-reconstructed cell-boundary values of the first-order x-dir spatial derivatives + !! @param dqR_prim_dy_vf The right WENO-reconstructed cell-boundary values of the first-order y-dir spatial derivatives + !! @param dqR_prim_dz_vf The right WENO-reconstructed cell-boundary values of the first-order z-dir spatial derivatives + !! @param qR_prim_vf The right WENO-reconstructed cell-boundary values of the cell-average primitive variables + !! @param q_prim_vf Cell-averaged primitive variables + !! @param flux_vf Intra-cell fluxes + !! @param flux_src_vf Intra-cell fluxes sources + !! @param flux_gsrc_vf Intra-cell geometric fluxes sources + !! @param norm_dir Dir. splitting direction + !! @param ix Index bounds in the x-dir + !! @param iy Index bounds in the y-dir + !! @param iz Index bounds in the z-dir + subroutine s_riemann_solver(qL_prim_rsx_vf, qL_prim_rsy_vf, qL_prim_rsz_vf, dqL_prim_dx_vf, dqL_prim_dy_vf, dqL_prim_dz_vf, & + & qL_prim_vf, qR_prim_rsx_vf, qR_prim_rsy_vf, qR_prim_rsz_vf, dqR_prim_dx_vf, dqR_prim_dy_vf, & + & dqR_prim_dz_vf, qR_prim_vf, q_prim_vf, flux_vf, flux_src_vf, flux_gsrc_vf, norm_dir, ix, iy, iz) + + real(wp), dimension(idwbuff(1)%beg:,idwbuff(2)%beg:,idwbuff(3)%beg:,1:), intent(inout) :: qL_prim_rsx_vf, qL_prim_rsy_vf, & + & qL_prim_rsz_vf, qR_prim_rsx_vf, qR_prim_rsy_vf, qR_prim_rsz_vf + type(scalar_field), dimension(sys_size), intent(in) :: q_prim_vf + type(scalar_field), allocatable, dimension(:), intent(inout) :: qL_prim_vf, qR_prim_vf + type(scalar_field), allocatable, dimension(:), intent(inout) :: dqL_prim_dx_vf, dqR_prim_dx_vf, dqL_prim_dy_vf, & + & dqR_prim_dy_vf, dqL_prim_dz_vf, dqR_prim_dz_vf + + type(scalar_field), dimension(sys_size), intent(inout) :: flux_vf, flux_src_vf, flux_gsrc_vf + integer, intent(in) :: norm_dir + type(int_bounds_info), intent(in) :: ix, iy, iz #:for NAME, NUM in [('hll', 1), ('hllc', 2), ('hlld', 4), ('lf', 5)] if (riemann_solver == ${NUM}$) then - call s_${NAME}$_riemann_solver(qL_prim_rsx_vf, qL_prim_rsy_vf, qL_prim_rsz_vf, dqL_prim_dx_vf, & - dqL_prim_dy_vf, & - dqL_prim_dz_vf, & - qL_prim_vf, & - qR_prim_rsx_vf, qR_prim_rsy_vf, qR_prim_rsz_vf, dqR_prim_dx_vf, & - dqR_prim_dy_vf, & - dqR_prim_dz_vf, & - qR_prim_vf, & - q_prim_vf, & - flux_vf, flux_src_vf, & - flux_gsrc_vf, & - norm_dir, ix, iy, iz) + call s_${NAME}$_riemann_solver(qL_prim_rsx_vf, qL_prim_rsy_vf, qL_prim_rsz_vf, dqL_prim_dx_vf, dqL_prim_dy_vf, & + & dqL_prim_dz_vf, qL_prim_vf, qR_prim_rsx_vf, qR_prim_rsy_vf, qR_prim_rsz_vf, & + & dqR_prim_dx_vf, dqR_prim_dy_vf, dqR_prim_dz_vf, qR_prim_vf, q_prim_vf, flux_vf, & + & flux_src_vf, flux_gsrc_vf, norm_dir, ix, iy, iz) end if #:endfor end subroutine s_riemann_solver - !> Dispatch to the subroutines that are utilized to compute - !! the viscous source fluxes for either Cartesian or cylindrical geometries. - !! For more information please refer to: - !! 1) s_compute_cartesian_viscous_source_flux - !! 2) s_compute_cylindrical_viscous_source_flux - subroutine s_compute_viscous_source_flux(velL_vf, & - dvelL_dx_vf, & - dvelL_dy_vf, & - dvelL_dz_vf, & - velR_vf, & - dvelR_dx_vf, & - dvelR_dy_vf, & - dvelR_dz_vf, & - flux_src_vf, & - norm_dir, & - ix, iy, iz) - - type(scalar_field), & - dimension(num_vels), & - intent(IN) :: velL_vf, velR_vf, & - dvelL_dx_vf, dvelR_dx_vf, & - dvelL_dy_vf, dvelR_dy_vf, & - dvelL_dz_vf, dvelR_dz_vf - - type(scalar_field), & - dimension(sys_size), & - intent(INOUT) :: flux_src_vf - - integer, intent(IN) :: norm_dir - - type(int_bounds_info), intent(IN) :: ix, iy, iz + !> Dispatch to the subroutines that are utilized to compute the viscous source fluxes for either Cartesian or cylindrical + !! geometries. For more information please refer to: 1) s_compute_cartesian_viscous_source_flux 2) + !! s_compute_cylindrical_viscous_source_flux + subroutine s_compute_viscous_source_flux(velL_vf, dvelL_dx_vf, dvelL_dy_vf, dvelL_dz_vf, velR_vf, dvelR_dx_vf, dvelR_dy_vf, & + & dvelR_dz_vf, flux_src_vf, norm_dir, ix, iy, iz) + + type(scalar_field), dimension(num_vels), intent(in) :: velL_vf, velR_vf, dvelL_dx_vf, dvelR_dx_vf, dvelL_dy_vf, & + & dvelR_dy_vf, dvelL_dz_vf, dvelR_dz_vf + + type(scalar_field), dimension(sys_size), intent(inout) :: flux_src_vf + integer, intent(in) :: norm_dir + type(int_bounds_info), intent(in) :: ix, iy, iz if (grid_geometry == 3) then - call s_compute_cylindrical_viscous_source_flux(velL_vf, & - dvelL_dx_vf, & - dvelL_dy_vf, & - dvelL_dz_vf, & - velR_vf, & - dvelR_dx_vf, & - dvelR_dy_vf, & - dvelR_dz_vf, & - flux_src_vf, & - norm_dir, & - ix, iy, iz) + call s_compute_cylindrical_viscous_source_flux(velL_vf, dvelL_dx_vf, dvelL_dy_vf, dvelL_dz_vf, velR_vf, dvelR_dx_vf, & + & dvelR_dy_vf, dvelR_dz_vf, flux_src_vf, norm_dir, ix, iy, iz) else - call s_compute_cartesian_viscous_source_flux(dvelL_dx_vf, & - dvelL_dy_vf, & - dvelL_dz_vf, & - dvelR_dx_vf, & - dvelR_dy_vf, & - dvelR_dz_vf, & - flux_src_vf, & - norm_dir) + call s_compute_cartesian_viscous_source_flux(dvelL_dx_vf, dvelL_dy_vf, dvelL_dz_vf, dvelR_dx_vf, dvelR_dy_vf, & + & dvelR_dz_vf, flux_src_vf, norm_dir) end if + end subroutine s_compute_viscous_source_flux !> @brief Computes intercell fluxes using the Harten-Lax-van Leer (HLL) approximate Riemann solver. - subroutine s_hll_riemann_solver(qL_prim_rsx_vf, qL_prim_rsy_vf, qL_prim_rsz_vf, dqL_prim_dx_vf, & - dqL_prim_dy_vf, & - dqL_prim_dz_vf, & - qL_prim_vf, & - qR_prim_rsx_vf, qR_prim_rsy_vf, qR_prim_rsz_vf, dqR_prim_dx_vf, & - dqR_prim_dy_vf, & - dqR_prim_dz_vf, & - qR_prim_vf, & - q_prim_vf, & - flux_vf, flux_src_vf, & - flux_gsrc_vf, & - norm_dir, ix, iy, iz) - - real(wp), dimension(idwbuff(1)%beg:, idwbuff(2)%beg:, idwbuff(3)%beg:, 1:), intent(inout) :: qL_prim_rsx_vf, qL_prim_rsy_vf, qL_prim_rsz_vf, qR_prim_rsx_vf, qR_prim_rsy_vf, qR_prim_rsz_vf - type(scalar_field), dimension(sys_size), intent(in) :: q_prim_vf - + subroutine s_hll_riemann_solver(qL_prim_rsx_vf, qL_prim_rsy_vf, qL_prim_rsz_vf, dqL_prim_dx_vf, dqL_prim_dy_vf, & + & dqL_prim_dz_vf, qL_prim_vf, qR_prim_rsx_vf, qR_prim_rsy_vf, qR_prim_rsz_vf, dqR_prim_dx_vf, & + & dqR_prim_dy_vf, dqR_prim_dz_vf, qR_prim_vf, q_prim_vf, flux_vf, flux_src_vf, flux_gsrc_vf, & + & norm_dir, ix, iy, iz) + + real(wp), dimension(idwbuff(1)%beg:,idwbuff(2)%beg:,idwbuff(3)%beg:,1:), intent(inout) :: qL_prim_rsx_vf, qL_prim_rsy_vf, & + & qL_prim_rsz_vf, qR_prim_rsx_vf, qR_prim_rsy_vf, qR_prim_rsz_vf + type(scalar_field), dimension(sys_size), intent(in) :: q_prim_vf type(scalar_field), allocatable, dimension(:), intent(inout) :: qL_prim_vf, qR_prim_vf - - type(scalar_field), & - allocatable, dimension(:), & - intent(inout) :: dqL_prim_dx_vf, dqR_prim_dx_vf, & - dqL_prim_dy_vf, dqR_prim_dy_vf, & - dqL_prim_dz_vf, dqR_prim_dz_vf + type(scalar_field), allocatable, dimension(:), intent(inout) :: dqL_prim_dx_vf, dqR_prim_dx_vf, dqL_prim_dy_vf, & + & dqR_prim_dy_vf, dqL_prim_dz_vf, dqR_prim_dz_vf ! Intercell fluxes - type(scalar_field), & - dimension(sys_size), & - intent(inout) :: flux_vf, flux_src_vf, flux_gsrc_vf - real(wp) :: flux_tau_L, flux_tau_R + type(scalar_field), dimension(sys_size), intent(inout) :: flux_vf, flux_src_vf, flux_gsrc_vf + real(wp) :: flux_tau_L, flux_tau_R + integer, intent(in) :: norm_dir + type(int_bounds_info), intent(in) :: ix, iy, iz - integer, intent(in) :: norm_dir - type(int_bounds_info), intent(in) :: ix, iy, iz #:if not MFC_CASE_OPTIMIZATION and USING_AMD - real(wp), dimension(3) :: alpha_rho_L, alpha_rho_R - real(wp), dimension(3) :: vel_L, vel_R - real(wp), dimension(3) :: alpha_L, alpha_R + real(wp), dimension(3) :: alpha_rho_L, alpha_rho_R + real(wp), dimension(3) :: vel_L, vel_R + real(wp), dimension(3) :: alpha_L, alpha_R real(wp), dimension(10) :: Ys_L, Ys_R real(wp), dimension(10) :: Cp_iL, Cp_iR, Xs_L, Xs_R, Gamma_iL, Gamma_iR real(wp), dimension(10) :: Yi_avg, Phi_avg, h_iL, h_iR, h_avg_2 #:else - real(wp), dimension(num_fluids) :: alpha_rho_L, alpha_rho_R - real(wp), dimension(num_vels) :: vel_L, vel_R - real(wp), dimension(num_fluids) :: alpha_L, alpha_R + real(wp), dimension(num_fluids) :: alpha_rho_L, alpha_rho_R + real(wp), dimension(num_vels) :: vel_L, vel_R + real(wp), dimension(num_fluids) :: alpha_L, alpha_R real(wp), dimension(num_species) :: Ys_L, Ys_R real(wp), dimension(num_species) :: Cp_iL, Cp_iR, Xs_L, Xs_R, Gamma_iL, Gamma_iR real(wp), dimension(num_species) :: Yi_avg, Phi_avg, h_iL, h_iR, h_avg_2 #:endif - real(wp) :: rho_L, rho_R - real(wp) :: pres_L, pres_R - real(wp) :: E_L, E_R - real(wp) :: H_L, H_R - real(wp) :: Cp_avg, Cv_avg, T_avg, eps, c_sum_Yi_Phi - real(wp) :: T_L, T_R - real(wp) :: Y_L, Y_R - real(wp) :: MW_L, MW_R - real(wp) :: R_gas_L, R_gas_R - real(wp) :: Cp_L, Cp_R - real(wp) :: Cv_L, Cv_R - real(wp) :: Gamm_L, Gamm_R - real(wp) :: gamma_L, gamma_R - real(wp) :: pi_inf_L, pi_inf_R - real(wp) :: qv_L, qv_R - real(wp) :: c_L, c_R - real(wp), dimension(6) :: tau_e_L, tau_e_R - real(wp) :: G_L, G_R - real(wp), dimension(2) :: Re_L, Re_R - real(wp), dimension(3) :: xi_field_L, xi_field_R - - real(wp) :: rho_avg - real(wp) :: H_avg - real(wp) :: qv_avg - real(wp) :: gamma_avg - real(wp) :: c_avg - - real(wp) :: s_L, s_R, s_M, s_P, s_S - real(wp) :: xi_M, xi_P - - real(wp) :: ptilde_L, ptilde_R - real(wp) :: vel_L_rms, vel_R_rms, vel_avg_rms - real(wp) :: vel_L_tmp, vel_R_tmp - real(wp) :: Ms_L, Ms_R, pres_SL, pres_SR - real(wp) :: alpha_L_sum, alpha_R_sum - real(wp) :: zcoef, pcorr !< low Mach number correction - - type(riemann_states) :: c_fast, pres_mag + real(wp) :: rho_L, rho_R + real(wp) :: pres_L, pres_R + real(wp) :: E_L, E_R + real(wp) :: H_L, H_R + real(wp) :: Cp_avg, Cv_avg, T_avg, eps, c_sum_Yi_Phi + real(wp) :: T_L, T_R + real(wp) :: Y_L, Y_R + real(wp) :: MW_L, MW_R + real(wp) :: R_gas_L, R_gas_R + real(wp) :: Cp_L, Cp_R + real(wp) :: Cv_L, Cv_R + real(wp) :: Gamm_L, Gamm_R + real(wp) :: gamma_L, gamma_R + real(wp) :: pi_inf_L, pi_inf_R + real(wp) :: qv_L, qv_R + real(wp) :: c_L, c_R + real(wp), dimension(6) :: tau_e_L, tau_e_R + real(wp) :: G_L, G_R + real(wp), dimension(2) :: Re_L, Re_R + real(wp), dimension(3) :: xi_field_L, xi_field_R + real(wp) :: rho_avg + real(wp) :: H_avg + real(wp) :: qv_avg + real(wp) :: gamma_avg + real(wp) :: c_avg + real(wp) :: s_L, s_R, s_M, s_P, s_S + real(wp) :: xi_M, xi_P + real(wp) :: ptilde_L, ptilde_R + real(wp) :: vel_L_rms, vel_R_rms, vel_avg_rms + real(wp) :: vel_L_tmp, vel_R_tmp + real(wp) :: Ms_L, Ms_R, pres_SL, pres_SR + real(wp) :: alpha_L_sum, alpha_R_sum + real(wp) :: zcoef, pcorr !< low Mach number correction + type(riemann_states) :: c_fast, pres_mag type(riemann_states_vec3) :: B + type(riemann_states) :: Ga ! Gamma (Lorentz factor) + type(riemann_states) :: vdotB, B2 + type(riemann_states_vec3) :: b4 ! 4-magnetic field components (spatial: b4x, b4y, b4z) + type(riemann_states_vec3) :: cm ! Conservative momentum variables + integer :: i, j, k, l, q !< Generic loop iterators - type(riemann_states) :: Ga ! Gamma (Lorentz factor) - type(riemann_states) :: vdotB, B2 - type(riemann_states_vec3) :: b4 ! 4-magnetic field components (spatial: b4x, b4y, b4z) - type(riemann_states_vec3) :: cm ! Conservative momentum variables - - integer :: i, j, k, l, q !< Generic loop iterators - - ! Populating the buffers of the left and right Riemann problem - ! states variables, based on the choice of boundary conditions - call s_populate_riemann_states_variables_buffers( & - qL_prim_rsx_vf, qL_prim_rsy_vf, qL_prim_rsz_vf, dqL_prim_dx_vf, & - dqL_prim_dy_vf, & - dqL_prim_dz_vf, & - qR_prim_rsx_vf, qR_prim_rsy_vf, qR_prim_rsz_vf, dqR_prim_dx_vf, & - dqR_prim_dy_vf, & - dqR_prim_dz_vf, & - norm_dir, ix, iy, iz) + ! Populating the buffers of the left and right Riemann problem states variables, based on the choice of boundary conditions + call s_populate_riemann_states_variables_buffers(qL_prim_rsx_vf, qL_prim_rsy_vf, qL_prim_rsz_vf, dqL_prim_dx_vf, & + & dqL_prim_dy_vf, dqL_prim_dz_vf, qR_prim_rsx_vf, qR_prim_rsy_vf, qR_prim_rsz_vf, dqR_prim_dx_vf, dqR_prim_dy_vf, & + & dqR_prim_dz_vf, norm_dir, ix, iy, iz) ! Reshaping inputted data based on dimensional splitting direction - call s_initialize_riemann_solver( & - flux_src_vf, & - norm_dir) + call s_initialize_riemann_solver(flux_src_vf, norm_dir) #:for NORM_DIR, XYZ in [(1, 'x'), (2, 'y'), (3, 'z')] - if (norm_dir == ${NORM_DIR}$) then - $:GPU_PARALLEL_LOOP(collapse=3, private='[i,j,k,l,q,alpha_rho_L,alpha_rho_R,vel_L,vel_R,alpha_L,alpha_R,tau_e_L,tau_e_R,Re_L,Re_R,s_L,s_R,s_S,Ys_L,Ys_R,xi_field_L, xi_field_R, Cp_iL, Cp_iR, Xs_L, Xs_R, Gamma_iL, Gamma_iR, Yi_avg, Phi_avg, h_iL, h_iR, h_avg_2, c_fast, pres_mag, B, Ga, vdotB, B2, b4, cm, pcorr, zcoef, vel_L_tmp, vel_R_tmp, rho_L, rho_R, pres_L, pres_R, E_L, E_R, H_L, H_R, Cp_avg, Cv_avg, T_avg, eps, c_sum_Yi_Phi, T_L, T_R, Y_L, Y_R, MW_L, MW_R, R_gas_L, R_gas_R, Cp_L, Cp_R, Cv_L, Cv_R, Gamm_L, Gamm_R, gamma_L, gamma_R, pi_inf_L, pi_inf_R, qv_L, qv_R, qv_avg, c_L, c_R, G_L, G_R, rho_avg, H_avg, c_avg, gamma_avg, ptilde_L, ptilde_R, vel_L_rms, vel_R_rms, vel_avg_rms, Ms_L, Ms_R, pres_SL, pres_SR, alpha_L_sum, alpha_R_sum, flux_tau_L, flux_tau_R]', copyin='[norm_dir]') + $:GPU_PARALLEL_LOOP(collapse=3, private='[i, j, k, l, q, alpha_rho_L, alpha_rho_R, vel_L, vel_R, alpha_L, & + & alpha_R, tau_e_L, tau_e_R, Re_L, Re_R, s_L, s_R, s_S, Ys_L, Ys_R, xi_field_L, xi_field_R, & + & Cp_iL, Cp_iR, Xs_L, Xs_R, Gamma_iL, Gamma_iR, Yi_avg, Phi_avg, h_iL, h_iR, h_avg_2, c_fast, & + & pres_mag, B, Ga, vdotB, B2, b4, cm, pcorr, zcoef, vel_L_tmp, vel_R_tmp, rho_L, rho_R, & + & pres_L, pres_R, E_L, E_R, H_L, H_R, Cp_avg, Cv_avg, T_avg, eps, c_sum_Yi_Phi, T_L, T_R, & + & Y_L, Y_R, MW_L, MW_R, R_gas_L, R_gas_R, Cp_L, Cp_R, Cv_L, Cv_R, Gamm_L, Gamm_R, gamma_L, & + & gamma_R, pi_inf_L, pi_inf_R, qv_L, qv_R, qv_avg, c_L, c_R, G_L, G_R, rho_avg, H_avg, c_avg, & + & gamma_avg, ptilde_L, ptilde_R, vel_L_rms, vel_R_rms, vel_avg_rms, Ms_L, Ms_R, pres_SL, & + & pres_SR, alpha_L_sum, alpha_R_sum, flux_tau_L, flux_tau_R]', copyin='[norm_dir]') do l = is3%beg, is3%end do k = is2%beg, is2%end do j = is1%beg, is1%end @@ -391,14 +279,14 @@ contains pres_R = qR_prim_rs${XYZ}$_vf(j + 1, k, l, E_idx) if (mhd) then - if (n == 0) then ! 1D: constant Bx; By, Bz as variables + if (n == 0) then ! 1D: constant Bx; By, Bz as variables B%L(1) = Bx0 B%R(1) = Bx0 B%L(2) = qL_prim_rs${XYZ}$_vf(j, k, l, B_idx%beg) B%R(2) = qR_prim_rs${XYZ}$_vf(j + 1, k, l, B_idx%beg) B%L(3) = qL_prim_rs${XYZ}$_vf(j, k, l, B_idx%beg + 1) B%R(3) = qR_prim_rs${XYZ}$_vf(j + 1, k, l, B_idx%beg + 1) - else ! 2D/3D: Bx, By, Bz as variables + else ! 2D/3D: Bx, By, Bz as variables B%L(1) = qL_prim_rs${XYZ}$_vf(j, k, l, B_idx%beg) B%R(1) = qR_prim_rs${XYZ}$_vf(j + 1, k, l, B_idx%beg) B%L(2) = qL_prim_rs${XYZ}$_vf(j, k, l, B_idx%beg + 1) @@ -463,10 +351,8 @@ contains $:GPU_LOOP(parallelism='[seq]') do q = 1, Re_size(i) - Re_L(i) = alpha_L(Re_idx(i, q))/Res_gs(i, q) & - + Re_L(i) - Re_R(i) = alpha_R(Re_idx(i, q))/Res_gs(i, q) & - + Re_R(i) + Re_L(i) = alpha_L(Re_idx(i, q))/Res_gs(i, q) + Re_L(i) + Re_R(i) = alpha_R(Re_idx(i, q))/Res_gs(i, q) + Re_R(i) end do Re_L(i) = 1._wp/max(Re_L(i), sgm_eps) @@ -526,7 +412,7 @@ contains E_R = rho_R*E_R + 5.e-1*rho_R*vel_R_rms H_L = (E_L + pres_L)/rho_L H_R = (E_R + pres_R)/rho_R - elseif (mhd .and. relativity) then + else if (mhd .and. relativity) then Ga%L = 1._wp/sqrt(1._wp - vel_L_rms) Ga%R = 1._wp/sqrt(1._wp - vel_R_rms) #:if not MFC_CASE_OPTIMIZATION or num_dims > 2 @@ -552,15 +438,17 @@ contains E_L = rho_L*H_L*Ga%L**2 - pres_L + 0.5_wp*(B2%L + vel_L_rms*B2%L - vdotB%L**2._wp) - rho_L*Ga%L E_R = rho_R*H_R*Ga%R**2 - pres_R + 0.5_wp*(B2%R + vel_R_rms*B2%R - vdotB%R**2._wp) - rho_R*Ga%R - elseif (mhd .and. .not. relativity) then + else if (mhd .and. .not. relativity) then #:if not MFC_CASE_OPTIMIZATION or num_dims > 2 pres_mag%L = 0.5_wp*(B%L(1)**2._wp + B%L(2)**2._wp + B%L(3)**2._wp) pres_mag%R = 0.5_wp*(B%R(1)**2._wp + B%R(2)**2._wp + B%R(3)**2._wp) #:endif E_L = gamma_L*pres_L + pi_inf_L + 0.5_wp*rho_L*vel_L_rms + qv_L + pres_mag%L - E_R = gamma_R*pres_R + pi_inf_R + 0.5_wp*rho_R*vel_R_rms + qv_R + pres_mag%R ! includes magnetic energy + E_R = gamma_R*pres_R + pi_inf_R + 0.5_wp*rho_R*vel_R_rms + qv_R & + & + pres_mag%R ! includes magnetic energy H_L = (E_L + pres_L - pres_mag%L)/rho_L - H_R = (E_R + pres_R - pres_mag%R)/rho_R ! stagnation enthalpy here excludes magnetic energy (only used to find speed of sound) + H_R = (E_R + pres_R - pres_mag%R) & + & /rho_R ! stagnation enthalpy here excludes magnetic energy (only used to find speed of sound) else E_L = gamma_L*pres_L + pi_inf_L + 5.e-1*rho_L*vel_L_rms + qv_L E_R = gamma_R*pres_R + pi_inf_R + 5.e-1*rho_R*vel_R_rms + qv_R @@ -587,8 +475,7 @@ contains do i = 1, strxe - strxb + 1 tau_e_L(i) = qL_prim_rs${XYZ}$_vf(j, k, l, strxb - 1 + i) tau_e_R(i) = qR_prim_rs${XYZ}$_vf(j + 1, k, l, strxb - 1 + i) - ! Elastic contribution to energy if G large enough - !TODO take out if statement if stable without + ! Elastic contribution to energy if G large enough TODO take out if statement if stable without if ((G_L > 1000) .and. (G_R > 1000)) then E_L = E_L + (tau_e_L(i)*tau_e_L(i))/(4._wp*G_L) E_R = E_R + (tau_e_R(i)*tau_e_R(i))/(4._wp*G_R) @@ -601,51 +488,31 @@ contains end do end if - ! elastic energy update - !if ( hyperelasticity ) then - ! G_L = 0._wp - ! G_R = 0._wp + ! elastic energy update if ( hyperelasticity ) then G_L = 0._wp G_R = 0._wp ! - ! $:GPU_LOOP(parallelism='[seq]') - ! do i = 1, num_fluids - ! G_L = G_L + alpha_L(i)*Gs_rs(i) - ! G_R = G_R + alpha_R(i)*Gs_rs(i) - ! end do - ! ! Elastic contribution to energy if G large enough - ! if ((G_L > 1.e-3_wp) .and. (G_R > 1.e-3_wp)) then - ! E_L = E_L + G_L*qL_prim_rs${XYZ}$_vf(j, k, l, xiend + 1) - ! E_R = E_R + G_R*qR_prim_rs${XYZ}$_vf(j + 1, k, l, xiend + 1) - ! $:GPU_LOOP(parallelism='[seq]') - ! do i = 1, b_size-1 - ! tau_e_L(i) = G_L*qL_prim_rs${XYZ}$_vf(j, k, l, strxb - 1 + i) - ! tau_e_R(i) = G_R*qR_prim_rs${XYZ}$_vf(j + 1, k, l, strxb - 1 + i) - ! end do - ! $:GPU_LOOP(parallelism='[seq]') - ! do i = 1, b_size-1 - ! tau_e_L(i) = 0._wp - ! tau_e_R(i) = 0._wp - ! end do - ! $:GPU_LOOP(parallelism='[seq]') - ! do i = 1, num_dims - ! xi_field_L(i) = qL_prim_rs${XYZ}$_vf(j, k, l, xibeg - 1 + i) - ! xi_field_R(i) = qR_prim_rs${XYZ}$_vf(j + 1, k, l, xibeg - 1 + i) - ! end do - ! end if - !end if + ! $:GPU_LOOP(parallelism='[seq]') do i = 1, num_fluids G_L = G_L + alpha_L(i)*Gs_rs(i) G_R = G_R + + ! alpha_R(i)*Gs_rs(i) end do ! Elastic contribution to energy if G large enough if ((G_L > 1.e-3_wp) + ! .and. (G_R > 1.e-3_wp)) then E_L = E_L + G_L*qL_prim_rs${XYZ}$_vf(j, k, l, xiend + 1) E_R = E_R + + ! G_R*qR_prim_rs${XYZ}$_vf(j + 1, k, l, xiend + 1) $:GPU_LOOP(parallelism='[seq]') do i = 1, b_size-1 + ! tau_e_L(i) = G_L*qL_prim_rs${XYZ}$_vf(j, k, l, strxb - 1 + i) tau_e_R(i) = G_R*qR_prim_rs${XYZ}$_vf(j + ! + 1, k, l, strxb - 1 + i) end do $:GPU_LOOP(parallelism='[seq]') do i = 1, b_size-1 tau_e_L(i) = 0._wp + ! tau_e_R(i) = 0._wp end do $:GPU_LOOP(parallelism='[seq]') do i = 1, num_dims xi_field_L(i) = + ! qL_prim_rs${XYZ}$_vf(j, k, l, xibeg - 1 + i) xi_field_R(i) = qR_prim_rs${XYZ}$_vf(j + 1, k, l, xibeg - + ! 1 + i) end do end if end if @:compute_average_state() - call s_compute_speed_of_sound(pres_L, rho_L, gamma_L, pi_inf_L, H_L, alpha_L, & - vel_L_rms, 0._wp, c_L, qv_L) + call s_compute_speed_of_sound(pres_L, rho_L, gamma_L, pi_inf_L, H_L, alpha_L, vel_L_rms, 0._wp, c_L, & + & qv_L) - call s_compute_speed_of_sound(pres_R, rho_R, gamma_R, pi_inf_R, H_R, alpha_R, & - vel_R_rms, 0._wp, c_R, qv_R) + call s_compute_speed_of_sound(pres_R, rho_R, gamma_R, pi_inf_R, H_R, alpha_R, vel_R_rms, 0._wp, c_R, & + & qv_R) !> The computation of c_avg does not require all the variables, and therefore the non '_avg' ! variables are placeholders to call the subroutine. - call s_compute_speed_of_sound(pres_R, rho_avg, gamma_avg, pi_inf_R, H_avg, alpha_R, & - vel_avg_rms, c_sum_Yi_Phi, c_avg, qv_avg) + call s_compute_speed_of_sound(pres_R, rho_avg, gamma_avg, pi_inf_R, H_avg, alpha_R, vel_avg_rms, & + & c_sum_Yi_Phi, c_avg, qv_avg) if (mhd) then call s_compute_fast_magnetosonic_speed(rho_L, c_L, B%L, norm_dir, c_fast%L, H_L) @@ -666,24 +533,20 @@ contains if (mhd) then s_L = min(vel_L(dir_idx(1)) - c_fast%L, vel_R(dir_idx(1)) - c_fast%R) s_R = max(vel_R(dir_idx(1)) + c_fast%R, vel_L(dir_idx(1)) + c_fast%L) - elseif (hypoelasticity) then - s_L = min(vel_L(dir_idx(1)) - sqrt(c_L*c_L + & - (((4._wp*G_L)/3._wp) + & - tau_e_L(dir_idx_tau(1)))/rho_L) & - , vel_R(dir_idx(1)) - sqrt(c_R*c_R + & - (((4._wp*G_R)/3._wp) + & - tau_e_R(dir_idx_tau(1)))/rho_R)) - s_R = max(vel_R(dir_idx(1)) + sqrt(c_R*c_R + & - (((4._wp*G_R)/3._wp) + & - tau_e_R(dir_idx_tau(1)))/rho_R) & - , vel_L(dir_idx(1)) + sqrt(c_L*c_L + & - (((4._wp*G_L)/3._wp) + & - tau_e_L(dir_idx_tau(1)))/rho_L)) + else if (hypoelasticity) then + s_L = min(vel_L(dir_idx(1)) - sqrt(c_L*c_L + (((4._wp*G_L)/3._wp) + tau_e_L(dir_idx_tau(1))) & + & /rho_L), & + & vel_R(dir_idx(1)) - sqrt(c_R*c_R + (((4._wp*G_R)/3._wp) + tau_e_R(dir_idx_tau(1))) & + & /rho_R)) + s_R = max(vel_R(dir_idx(1)) + sqrt(c_R*c_R + (((4._wp*G_R)/3._wp) + tau_e_R(dir_idx_tau(1))) & + & /rho_R), & + & vel_L(dir_idx(1)) + sqrt(c_L*c_L + (((4._wp*G_L)/3._wp) + tau_e_L(dir_idx_tau(1))) & + & /rho_L)) else if (hyperelasticity) then - s_L = min(vel_L(dir_idx(1)) - sqrt(c_L*c_L + (4._wp*G_L/3._wp)/rho_L) & - , vel_R(dir_idx(1)) - sqrt(c_R*c_R + (4._wp*G_R/3._wp)/rho_R)) - s_R = max(vel_R(dir_idx(1)) + sqrt(c_R*c_R + (4._wp*G_R/3._wp)/rho_R) & - , vel_L(dir_idx(1)) + sqrt(c_L*c_L + (4._wp*G_L/3._wp)/rho_L)) + s_L = min(vel_L(dir_idx(1)) - sqrt(c_L*c_L + (4._wp*G_L/3._wp)/rho_L), & + & vel_R(dir_idx(1)) - sqrt(c_R*c_R + (4._wp*G_R/3._wp)/rho_R)) + s_R = max(vel_R(dir_idx(1)) + sqrt(c_R*c_R + (4._wp*G_R/3._wp)/rho_R), & + & vel_L(dir_idx(1)) + sqrt(c_L*c_L + (4._wp*G_L/3._wp)/rho_L)) else s_L = min(vel_L(dir_idx(1)) - c_L, vel_R(dir_idx(1)) - c_R) s_R = max(vel_R(dir_idx(1)) + c_R, vel_L(dir_idx(1)) + c_L) @@ -695,42 +558,33 @@ contains s_R = max(s_R, hyper_cleaning_speed) end if - s_S = (pres_R - pres_L + rho_L*vel_L(dir_idx(1))* & - (s_L - vel_L(dir_idx(1))) - & - rho_R*vel_R(dir_idx(1))* & - (s_R - vel_R(dir_idx(1)))) & - /(rho_L*(s_L - vel_L(dir_idx(1))) - & - rho_R*(s_R - vel_R(dir_idx(1)))) - elseif (wave_speeds == 2) then - pres_SL = 5.e-1_wp*(pres_L + pres_R + rho_avg*c_avg* & - (vel_L(dir_idx(1)) - & - vel_R(dir_idx(1)))) + s_S = (pres_R - pres_L + rho_L*vel_L(dir_idx(1))*(s_L - vel_L(dir_idx(1))) & + & - rho_R*vel_R(dir_idx(1))*(s_R - vel_R(dir_idx(1))))/(rho_L*(s_L - vel_L(dir_idx(1))) & + & - rho_R*(s_R - vel_R(dir_idx(1)))) + else if (wave_speeds == 2) then + pres_SL = 5.e-1_wp*(pres_L + pres_R + rho_avg*c_avg*(vel_L(dir_idx(1)) - vel_R(dir_idx(1)))) pres_SR = pres_SL - Ms_L = max(1._wp, sqrt(1._wp + ((5.e-1_wp + gamma_L)/(1._wp + gamma_L))* & - (pres_SL/pres_L - 1._wp)*pres_L/ & - ((pres_L + pi_inf_L/(1._wp + gamma_L))))) - Ms_R = max(1._wp, sqrt(1._wp + ((5.e-1_wp + gamma_R)/(1._wp + gamma_R))* & - (pres_SR/pres_R - 1._wp)*pres_R/ & - ((pres_R + pi_inf_R/(1._wp + gamma_R))))) + Ms_L = max(1._wp, & + & sqrt(1._wp + ((5.e-1_wp + gamma_L)/(1._wp + gamma_L))*(pres_SL/pres_L - 1._wp) & + & *pres_L/((pres_L + pi_inf_L/(1._wp + gamma_L))))) + Ms_R = max(1._wp, & + & sqrt(1._wp + ((5.e-1_wp + gamma_R)/(1._wp + gamma_R))*(pres_SR/pres_R - 1._wp) & + & *pres_R/((pres_R + pi_inf_R/(1._wp + gamma_R))))) s_L = vel_L(dir_idx(1)) - c_L*Ms_L s_R = vel_R(dir_idx(1)) + c_R*Ms_R - s_S = 5.e-1_wp*((vel_L(dir_idx(1)) + vel_R(dir_idx(1))) + & - (pres_L - pres_R)/ & - (rho_avg*c_avg)) + s_S = 5.e-1_wp*((vel_L(dir_idx(1)) + vel_R(dir_idx(1))) + (pres_L - pres_R)/(rho_avg*c_avg)) end if s_M = min(0._wp, s_L); s_P = max(0._wp, s_R) - xi_M = (5.e-1_wp + sign(5.e-1_wp, s_L)) & - + (5.e-1_wp - sign(5.e-1_wp, s_L)) & - *(5.e-1_wp + sign(5.e-1_wp, s_R)) - xi_P = (5.e-1_wp - sign(5.e-1_wp, s_R)) & - + (5.e-1_wp - sign(5.e-1_wp, s_L)) & - *(5.e-1_wp + sign(5.e-1_wp, s_R)) + xi_M = (5.e-1_wp + sign(5.e-1_wp, s_L)) + (5.e-1_wp - sign(5.e-1_wp, s_L))*(5.e-1_wp + sign(5.e-1_wp, & + & s_R)) + xi_P = (5.e-1_wp - sign(5.e-1_wp, s_R)) + (5.e-1_wp - sign(5.e-1_wp, s_L))*(5.e-1_wp + sign(5.e-1_wp, & + & s_R)) ! Low Mach correction if (low_Mach == 1) then @@ -743,22 +597,17 @@ contains if (.not. relativity) then $:GPU_LOOP(parallelism='[seq]') do i = 1, contxe - flux_rs${XYZ}$_vf(j, k, l, i) = & - (s_M*alpha_rho_R(i)*vel_R(norm_dir) & - - s_P*alpha_rho_L(i)*vel_L(norm_dir) & - + s_M*s_P*(alpha_rho_L(i) & - - alpha_rho_R(i))) & - /(s_M - s_P) + flux_rs${XYZ}$_vf(j, k, l, & + & i) = (s_M*alpha_rho_R(i)*vel_R(norm_dir) - s_P*alpha_rho_L(i) & + & *vel_L(norm_dir) + s_M*s_P*(alpha_rho_L(i) - alpha_rho_R(i)))/(s_M - s_P) end do - elseif (relativity) then + else if (relativity) then $:GPU_LOOP(parallelism='[seq]') do i = 1, contxe - flux_rs${XYZ}$_vf(j, k, l, i) = & - (s_M*Ga%R*alpha_rho_R(i)*vel_R(norm_dir) & - - s_P*Ga%L*alpha_rho_L(i)*vel_L(norm_dir) & - + s_M*s_P*(Ga%L*alpha_rho_L(i) & - - Ga%R*alpha_rho_R(i))) & - /(s_M - s_P) + flux_rs${XYZ}$_vf(j, k, l, & + & i) = (s_M*Ga%R*alpha_rho_R(i)*vel_R(norm_dir) - s_P*Ga%L*alpha_rho_L(i) & + & *vel_L(norm_dir) + s_M*s_P*(Ga%L*alpha_rho_L(i) - Ga%R*alpha_rho_R(i))) & + & /(s_M - s_P) end do end if @@ -766,78 +615,54 @@ contains if (mhd .and. (.not. relativity)) then $:GPU_LOOP(parallelism='[seq]') do i = 1, 3 - ! Flux of rho*v_i in the ${XYZ}$ direction - ! = rho * v_i * v_${XYZ}$ - B_i * B_${XYZ}$ + delta_(${XYZ}$,i) * p_tot - flux_rs${XYZ}$_vf(j, k, l, contxe + i) = & - (s_M*(rho_R*vel_R(i)*vel_R(norm_dir) & - - B%R(i)*B%R(norm_dir) & - + dir_flg(i)*(pres_R + pres_mag%R)) & - - s_P*(rho_L*vel_L(i)*vel_L(norm_dir) & - - B%L(i)*B%L(norm_dir) & - + dir_flg(i)*(pres_L + pres_mag%L)) & - + s_M*s_P*(rho_L*vel_L(i) - rho_R*vel_R(i))) & - /(s_M - s_P) + ! Flux of rho*v_i in the ${XYZ}$ direction = rho * v_i * v_${XYZ}$ - B_i * B_${XYZ}$ + + ! delta_(${XYZ}$,i) * p_tot + flux_rs${XYZ}$_vf(j, k, l, & + & contxe + i) = (s_M*(rho_R*vel_R(i)*vel_R(norm_dir) - B%R(i)*B%R(norm_dir) & + & + dir_flg(i)*(pres_R + pres_mag%R)) - s_P*(rho_L*vel_L(i)*vel_L(norm_dir) & + & - B%L(i)*B%L(norm_dir) + dir_flg(i)*(pres_L + pres_mag%L)) & + & + s_M*s_P*(rho_L*vel_L(i) - rho_R*vel_R(i)))/(s_M - s_P) end do - elseif (mhd .and. relativity) then + else if (mhd .and. relativity) then $:GPU_LOOP(parallelism='[seq]') do i = 1, 3 - ! Flux of m_i in the ${XYZ}$ direction - ! = m_i * v_${XYZ}$ - b_i/Gamma * B_${XYZ}$ + delta_(${XYZ}$,i) * p_tot - flux_rs${XYZ}$_vf(j, k, l, contxe + i) = & - (s_M*(cm%R(i)*vel_R(norm_dir) & - - b4%R(i)/Ga%R*B%R(norm_dir) & - + dir_flg(i)*(pres_R + pres_mag%R)) & - - s_P*(cm%L(i)*vel_L(norm_dir) & - - b4%L(i)/Ga%L*B%L(norm_dir) & - + dir_flg(i)*(pres_L + pres_mag%L)) & - + s_M*s_P*(cm%L(i) - cm%R(i))) & - /(s_M - s_P) + ! Flux of m_i in the ${XYZ}$ direction = m_i * v_${XYZ}$ - b_i/Gamma * B_${XYZ}$ + + ! delta_(${XYZ}$,i) * p_tot + flux_rs${XYZ}$_vf(j, k, l, & + & contxe + i) = (s_M*(cm%R(i)*vel_R(norm_dir) - b4%R(i)/Ga%R*B%R(norm_dir) & + & + dir_flg(i)*(pres_R + pres_mag%R)) - s_P*(cm%L(i)*vel_L(norm_dir) & + & - b4%L(i)/Ga%L*B%L(norm_dir) + dir_flg(i)*(pres_L + pres_mag%L)) & + & + s_M*s_P*(cm%L(i) - cm%R(i)))/(s_M - s_P) end do - elseif (bubbles_euler) then + else if (bubbles_euler) then $:GPU_LOOP(parallelism='[seq]') do i = 1, num_vels - flux_rs${XYZ}$_vf(j, k, l, contxe + dir_idx(i)) = & - (s_M*(rho_R*vel_R(dir_idx(1)) & - *vel_R(dir_idx(i)) & - + dir_flg(dir_idx(i))*(pres_R - ptilde_R)) & - - s_P*(rho_L*vel_L(dir_idx(1)) & - *vel_L(dir_idx(i)) & - + dir_flg(dir_idx(i))*(pres_L - ptilde_L)) & - + s_M*s_P*(rho_L*vel_L(dir_idx(i)) & - - rho_R*vel_R(dir_idx(i)))) & - /(s_M - s_P) & - + (s_M/s_L)*(s_P/s_R)*pcorr*(vel_R(dir_idx(i)) - vel_L(dir_idx(i))) + flux_rs${XYZ}$_vf(j, k, l, & + & contxe + dir_idx(i)) = (s_M*(rho_R*vel_R(dir_idx(1))*vel_R(dir_idx(i)) & + & + dir_flg(dir_idx(i))*(pres_R - ptilde_R)) - s_P*(rho_L*vel_L(dir_idx(1)) & + & *vel_L(dir_idx(i)) + dir_flg(dir_idx(i))*(pres_L - ptilde_L)) & + & + s_M*s_P*(rho_L*vel_L(dir_idx(i)) - rho_R*vel_R(dir_idx(i))))/(s_M - s_P) & + & + (s_M/s_L)*(s_P/s_R)*pcorr*(vel_R(dir_idx(i)) - vel_L(dir_idx(i))) end do else if (hypoelasticity) then $:GPU_LOOP(parallelism='[seq]') do i = 1, num_vels - flux_rs${XYZ}$_vf(j, k, l, contxe + dir_idx(i)) = & - (s_M*(rho_R*vel_R(dir_idx(1)) & - *vel_R(dir_idx(i)) & - + dir_flg(dir_idx(i))*pres_R & - - tau_e_R(dir_idx_tau(i))) & - - s_P*(rho_L*vel_L(dir_idx(1)) & - *vel_L(dir_idx(i)) & - + dir_flg(dir_idx(i))*pres_L & - - tau_e_L(dir_idx_tau(i))) & - + s_M*s_P*(rho_L*vel_L(dir_idx(i)) & - - rho_R*vel_R(dir_idx(i)))) & - /(s_M - s_P) + flux_rs${XYZ}$_vf(j, k, l, & + & contxe + dir_idx(i)) = (s_M*(rho_R*vel_R(dir_idx(1))*vel_R(dir_idx(i)) & + & + dir_flg(dir_idx(i))*pres_R - tau_e_R(dir_idx_tau(i))) & + & - s_P*(rho_L*vel_L(dir_idx(1))*vel_L(dir_idx(i)) + dir_flg(dir_idx(i)) & + & *pres_L - tau_e_L(dir_idx_tau(i))) + s_M*s_P*(rho_L*vel_L(dir_idx(i)) & + & - rho_R*vel_R(dir_idx(i))))/(s_M - s_P) end do else $:GPU_LOOP(parallelism='[seq]') do i = 1, num_vels - flux_rs${XYZ}$_vf(j, k, l, contxe + dir_idx(i)) = & - (s_M*(rho_R*vel_R(dir_idx(1)) & - *vel_R(dir_idx(i)) & - + dir_flg(dir_idx(i))*pres_R) & - - s_P*(rho_L*vel_L(dir_idx(1)) & - *vel_L(dir_idx(i)) & - + dir_flg(dir_idx(i))*pres_L) & - + s_M*s_P*(rho_L*vel_L(dir_idx(i)) & - - rho_R*vel_R(dir_idx(i)))) & - /(s_M - s_P) & - + (s_M/s_L)*(s_P/s_R)*pcorr*(vel_R(dir_idx(i)) - vel_L(dir_idx(i))) + flux_rs${XYZ}$_vf(j, k, l, & + & contxe + dir_idx(i)) = (s_M*(rho_R*vel_R(dir_idx(1))*vel_R(dir_idx(i)) & + & + dir_flg(dir_idx(i))*pres_R) - s_P*(rho_L*vel_L(dir_idx(1)) & + & *vel_L(dir_idx(i)) + dir_flg(dir_idx(i))*pres_L) & + & + s_M*s_P*(rho_L*vel_L(dir_idx(i)) - rho_R*vel_R(dir_idx(i))))/(s_M - s_P) & + & + (s_M/s_L)*(s_P/s_R)*pcorr*(vel_R(dir_idx(i)) - vel_L(dir_idx(i))) end do end if @@ -845,27 +670,24 @@ contains if (mhd .and. (.not. relativity)) then ! energy flux = (E + p + p_mag) * v_${XYZ}$ - B_${XYZ}$ * (v_x*B_x + v_y*B_y + v_z*B_z) #:if not MFC_CASE_OPTIMIZATION or num_dims > 2 - flux_rs${XYZ}$_vf(j, k, l, E_idx) = & - (s_M*(vel_R(norm_dir)*(E_R + pres_R + pres_mag%R) - B%R(norm_dir)*(vel_R(1)*B%R(1) + vel_R(2)*B%R(2) + vel_R(3)*B%R(3))) & - - s_P*(vel_L(norm_dir)*(E_L + pres_L + pres_mag%L) - B%L(norm_dir)*(vel_L(1)*B%L(1) + vel_L(2)*B%L(2) + vel_L(3)*B%L(3))) & - + s_M*s_P*(E_L - E_R)) & - /(s_M - s_P) + flux_rs${XYZ}$_vf(j, k, l, & + & E_idx) = (s_M*(vel_R(norm_dir)*(E_R + pres_R + pres_mag%R) - B%R(norm_dir) & + & *(vel_R(1)*B%R(1) + vel_R(2)*B%R(2) + vel_R(3)*B%R(3))) & + & - s_P*(vel_L(norm_dir)*(E_L + pres_L + pres_mag%L) - B%L(norm_dir) & + & *(vel_L(1)*B%L(1) + vel_L(2)*B%L(2) + vel_L(3)*B%L(3))) + s_M*s_P*(E_L & + & - E_R))/(s_M - s_P) #:endif - elseif (mhd .and. relativity) then - ! energy flux = m_${XYZ}$ - mass flux - ! Hard-coded for single-component for now - flux_rs${XYZ}$_vf(j, k, l, E_idx) = & - (s_M*(cm%R(norm_dir) - Ga%R*alpha_rho_R(1)*vel_R(norm_dir)) & - - s_P*(cm%L(norm_dir) - Ga%L*alpha_rho_L(1)*vel_L(norm_dir)) & - + s_M*s_P*(E_L - E_R)) & - /(s_M - s_P) + else if (mhd .and. relativity) then + ! energy flux = m_${XYZ}$ - mass flux Hard-coded for single-component for now + flux_rs${XYZ}$_vf(j, k, l, & + & E_idx) = (s_M*(cm%R(norm_dir) - Ga%R*alpha_rho_R(1)*vel_R(norm_dir)) & + & - s_P*(cm%L(norm_dir) - Ga%L*alpha_rho_L(1)*vel_L(norm_dir)) + s_M*s_P*(E_L & + & - E_R))/(s_M - s_P) else if (bubbles_euler) then - flux_rs${XYZ}$_vf(j, k, l, E_idx) = & - (s_M*vel_R(dir_idx(1))*(E_R + pres_R - ptilde_R) & - - s_P*vel_L(dir_idx(1))*(E_L + pres_L - ptilde_L) & - + s_M*s_P*(E_L - E_R)) & - /(s_M - s_P) & - + (s_M/s_L)*(s_P/s_R)*pcorr*(vel_R_rms - vel_L_rms)/2._wp + flux_rs${XYZ}$_vf(j, k, l, & + & E_idx) = (s_M*vel_R(dir_idx(1))*(E_R + pres_R - ptilde_R) & + & - s_P*vel_L(dir_idx(1))*(E_L + pres_L - ptilde_L) + s_M*s_P*(E_L - E_R))/(s_M & + & - s_P) + (s_M/s_L)*(s_P/s_R)*pcorr*(vel_R_rms - vel_L_rms)/2._wp else if (hypoelasticity) then flux_tau_L = 0._wp; flux_tau_R = 0._wp $:GPU_LOOP(parallelism='[seq]') @@ -873,44 +695,34 @@ contains flux_tau_L = flux_tau_L + tau_e_L(dir_idx_tau(i))*vel_L(dir_idx(i)) flux_tau_R = flux_tau_R + tau_e_R(dir_idx_tau(i))*vel_R(dir_idx(i)) end do - flux_rs${XYZ}$_vf(j, k, l, E_idx) = & - (s_M*(vel_R(dir_idx(1))*(E_R + pres_R) - flux_tau_R) & - - s_P*(vel_L(dir_idx(1))*(E_L + pres_L) - flux_tau_L) & - + s_M*s_P*(E_L - E_R))/(s_M - s_P) + flux_rs${XYZ}$_vf(j, k, l, & + & E_idx) = (s_M*(vel_R(dir_idx(1))*(E_R + pres_R) - flux_tau_R) & + & - s_P*(vel_L(dir_idx(1))*(E_L + pres_L) - flux_tau_L) + s_M*s_P*(E_L - E_R)) & + & /(s_M - s_P) else - flux_rs${XYZ}$_vf(j, k, l, E_idx) = & - (s_M*vel_R(dir_idx(1))*(E_R + pres_R) & - - s_P*vel_L(dir_idx(1))*(E_L + pres_L) & - + s_M*s_P*(E_L - E_R)) & - /(s_M - s_P) & - + (s_M/s_L)*(s_P/s_R)*pcorr*(vel_R_rms - vel_L_rms)/2._wp + flux_rs${XYZ}$_vf(j, k, l, & + & E_idx) = (s_M*vel_R(dir_idx(1))*(E_R + pres_R) - s_P*vel_L(dir_idx(1))*(E_L & + & + pres_L) + s_M*s_P*(E_L - E_R))/(s_M - s_P) + (s_M/s_L)*(s_P/s_R) & + & *pcorr*(vel_R_rms - vel_L_rms)/2._wp end if ! Elastic Stresses if (hypoelasticity) then - do i = 1, strxe - strxb + 1 !TODO: this indexing may be slow - flux_rs${XYZ}$_vf(j, k, l, strxb - 1 + i) = & - (s_M*(rho_R*vel_R(dir_idx(1)) & - *tau_e_R(i)) & - - s_P*(rho_L*vel_L(dir_idx(1)) & - *tau_e_L(i)) & - + s_M*s_P*(rho_L*tau_e_L(i) & - - rho_R*tau_e_R(i))) & - /(s_M - s_P) + do i = 1, strxe - strxb + 1 ! TODO: this indexing may be slow + flux_rs${XYZ}$_vf(j, k, l, & + & strxb - 1 + i) = (s_M*(rho_R*vel_R(dir_idx(1))*tau_e_R(i)) & + & - s_P*(rho_L*vel_L(dir_idx(1))*tau_e_L(i)) + s_M*s_P*(rho_L*tau_e_L(i) & + & - rho_R*tau_e_R(i)))/(s_M - s_P) end do end if ! Advection $:GPU_LOOP(parallelism='[seq]') do i = advxb, advxe - flux_rs${XYZ}$_vf(j, k, l, i) = & - (qL_prim_rs${XYZ}$_vf(j, k, l, i) & - - qR_prim_rs${XYZ}$_vf(j + 1, k, l, i)) & - *s_M*s_P/(s_M - s_P) - flux_src_rs${XYZ}$_vf(j, k, l, i) = & - (s_M*qR_prim_rs${XYZ}$_vf(j + 1, k, l, i) & - - s_P*qL_prim_rs${XYZ}$_vf(j, k, l, i)) & - /(s_M - s_P) + flux_rs${XYZ}$_vf(j, k, l, i) = (qL_prim_rs${XYZ}$_vf(j, k, l, i) - qR_prim_rs${XYZ}$_vf(j + 1, & + & k, l, i))*s_M*s_P/(s_M - s_P) + flux_src_rs${XYZ}$_vf(j, k, l, i) = (s_M*qR_prim_rs${XYZ}$_vf(j + 1, k, l, & + & i) - s_P*qL_prim_rs${XYZ}$_vf(j, k, l, i))/(s_M - s_P) end do if (bubbles_euler) then @@ -926,43 +738,49 @@ contains Y_L = qL_prim_rs${XYZ}$_vf(j, k, l, i) Y_R = qR_prim_rs${XYZ}$_vf(j + 1, k, l, i) - flux_rs${XYZ}$_vf(j, k, l, i) = (s_M*Y_R*rho_R*vel_R(dir_idx(1)) & - - s_P*Y_L*rho_L*vel_L(dir_idx(1)) & - + s_M*s_P*(Y_L*rho_L - Y_R*rho_R)) & - /(s_M - s_P) + flux_rs${XYZ}$_vf(j, k, l, & + & i) = (s_M*Y_R*rho_R*vel_R(dir_idx(1)) - s_P*Y_L*rho_L*vel_L(dir_idx(1)) & + & + s_M*s_P*(Y_L*rho_L - Y_R*rho_R))/(s_M - s_P) flux_src_rs${XYZ}$_vf(j, k, l, i) = 0._wp end do end if if (mhd) then - if (n == 0) then ! 1D: d/dx flux only & Bx = Bx0 = const. - ! B_y flux = v_x * B_y - v_y * Bx0 - ! B_z flux = v_x * B_z - v_z * Bx0 + if (n == 0) then ! 1D: d/dx flux only & Bx = Bx0 = const. + ! B_y flux = v_x * B_y - v_y * Bx0 B_z flux = v_x * B_z - v_z * Bx0 $:GPU_LOOP(parallelism='[seq]') do i = 0, 1 - flux_rsx_vf(j, k, l, B_idx%beg + i) = (s_M*(vel_R(1)*B%R(2 + i) - vel_R(2 + i)*Bx0) & - - s_P*(vel_L(1)*B%L(2 + i) - vel_L(2 + i)*Bx0) & - + s_M*s_P*(B%L(2 + i) - B%R(2 + i)))/(s_M - s_P) + flux_rsx_vf(j, k, l, & + & B_idx%beg + i) = (s_M*(vel_R(1)*B%R(2 + i) - vel_R(2 + i)*Bx0) & + & - s_P*(vel_L(1)*B%L(2 + i) - vel_L(2 + i)*Bx0) + s_M*s_P*(B%L(2 + i) & + & - B%R(2 + i)))/(s_M - s_P) end do - else ! 2D/3D: Bx, By, Bz /= const. but zero flux component in the same direction - ! B_x d/d${XYZ}$ flux = (1 - delta(x,${XYZ}$)) * (v_${XYZ}$ * B_x - v_x * B_${XYZ}$) - ! B_y d/d${XYZ}$ flux = (1 - delta(y,${XYZ}$)) * (v_${XYZ}$ * B_y - v_y * B_${XYZ}$) - ! B_z d/d${XYZ}$ flux = (1 - delta(z,${XYZ}$)) * (v_${XYZ}$ * B_z - v_z * B_${XYZ}$) + else ! 2D/3D: Bx, By, Bz /= const. but zero flux component in the same direction + ! B_x d/d${XYZ}$ flux = (1 - delta(x,${XYZ}$)) * (v_${XYZ}$ * B_x - v_x * B_${XYZ}$) B_y + ! d/d${XYZ}$ flux = (1 - delta(y,${XYZ}$)) * (v_${XYZ}$ * B_y - v_y * B_${XYZ}$) B_z d/d${XYZ}$ + ! flux = (1 - delta(z,${XYZ}$)) * (v_${XYZ}$ * B_z - v_z * B_${XYZ}$) $:GPU_LOOP(parallelism='[seq]') do i = 0, 2 - flux_rs${XYZ}$_vf(j, k, l, B_idx%beg + i) = (s_M*(vel_R(dir_idx(1))*B%R(i + 1) - vel_R(i + 1)*B%R(norm_dir)) - & - s_P*(vel_L(dir_idx(1))*B%L(i + 1) - vel_L(i + 1)*B%L(norm_dir)) + & - s_M*s_P*(B%L(i + 1) - B%R(i + 1)))/(s_M - s_P) + flux_rs${XYZ}$_vf(j, k, l, & + & B_idx%beg + i) = (s_M*(vel_R(dir_idx(1))*B%R(i + 1) - vel_R(i + 1) & + & *B%R(norm_dir)) - s_P*(vel_L(dir_idx(1))*B%L(i + 1) - vel_L(i + 1) & + & *B%L(norm_dir)) + s_M*s_P*(B%L(i + 1) - B%R(i + 1)))/(s_M - s_P) end do if (hyper_cleaning) then ! propagate magnetic field divergence as a wave - flux_rs${XYZ}$_vf(j, k, l, B_idx%beg + norm_dir - 1) = flux_rs${XYZ}$_vf(j, k, l, B_idx%beg + norm_dir - 1) + & - (s_M*qR_prim_rs${XYZ}$_vf(j + 1, k, l, psi_idx) - s_P*qL_prim_rs${XYZ}$_vf(j, k, l, psi_idx))/(s_M - s_P) - - flux_rs${XYZ}$_vf(j, k, l, psi_idx) = (hyper_cleaning_speed**2*(s_M*B%R(norm_dir) - s_P*B%L(norm_dir)) + s_M*s_P*(qL_prim_rs${XYZ}$_vf(j, k, l, psi_idx) - qR_prim_rs${XYZ}$_vf(j + 1, k, l, psi_idx)))/(s_M - s_P) + flux_rs${XYZ}$_vf(j, k, l, B_idx%beg + norm_dir - 1) = flux_rs${XYZ}$_vf(j, k, l, & + & B_idx%beg + norm_dir - 1) + (s_M*qR_prim_rs${XYZ}$_vf(j + 1, k, l, & + & psi_idx) - s_P*qL_prim_rs${XYZ}$_vf(j, k, l, psi_idx))/(s_M - s_P) + + flux_rs${XYZ}$_vf(j, k, l, & + & psi_idx) = (hyper_cleaning_speed**2*(s_M*B%R(norm_dir) & + & - s_P*B%L(norm_dir)) + s_M*s_P*(qL_prim_rs${XYZ}$_vf(j, k, l, & + & psi_idx) - qR_prim_rs${XYZ}$_vf(j + 1, k, l, psi_idx)))/(s_M - s_P) else - flux_rs${XYZ}$_vf(j, k, l, B_idx%beg + norm_dir - 1) = 0._wp ! Without hyperbolic cleaning, make sure flux of B_normal is identically zero + flux_rs${XYZ}$_vf(j, k, l, & + & B_idx%beg + norm_dir - 1) & + & = 0._wp ! Without hyperbolic cleaning, make sure flux of B_normal is identically zero end if end if flux_src_rs${XYZ}$_vf(j, k, l, advxb) = 0._wp @@ -970,15 +788,14 @@ contains #:if (NORM_DIR == 2) if (cyl_coord) then - !Substituting the advective flux into the inviscid geometrical source flux + ! Substituting the advective flux into the inviscid geometrical source flux $:GPU_LOOP(parallelism='[seq]') do i = 1, E_idx flux_gsrc_rs${XYZ}$_vf(j, k, l, i) = flux_rs${XYZ}$_vf(j, k, l, i) end do ! Recalculating the radial momentum geometric source flux - flux_gsrc_rs${XYZ}$_vf(j, k, l, contxe + 2) = & - flux_rs${XYZ}$_vf(j, k, l, contxe + 2) & - - (s_M*pres_R - s_P*pres_L)/(s_M - s_P) + flux_gsrc_rs${XYZ}$_vf(j, k, l, contxe + 2) = flux_rs${XYZ}$_vf(j, k, l, & + & contxe + 2) - (s_M*pres_R - s_P*pres_L)/(s_M - s_P) ! Geometrical source of the void fraction(s) is zero $:GPU_LOOP(parallelism='[seq]') do i = advxb, advxe @@ -988,10 +805,8 @@ contains if (cyl_coord .and. hypoelasticity) then ! += tau_sigmasigma using HLL - flux_gsrc_rs${XYZ}$_vf(j, k, l, contxe + 2) = & - flux_gsrc_rs${XYZ}$_vf(j, k, l, contxe + 2) + & - (s_M*tau_e_R(4) - s_P*tau_e_L(4)) & - /(s_M - s_P) + flux_gsrc_rs${XYZ}$_vf(j, k, l, contxe + 2) = flux_gsrc_rs${XYZ}$_vf(j, k, l, & + & contxe + 2) + (s_M*tau_e_R(4) - s_P*tau_e_L(4))/(s_M - s_P) $:GPU_LOOP(parallelism='[seq]') do i = strxb, strxe @@ -999,165 +814,129 @@ contains end do end if #:endif - end do end do end do $:END_GPU_PARALLEL_LOOP() end if - #:endfor if (viscous .or. dummy) then if (weno_Re_flux) then - - call s_compute_viscous_source_flux( & - qL_prim_vf(momxb:momxe), & - dqL_prim_dx_vf(momxb:momxe), & - dqL_prim_dy_vf(momxb:momxe), & - dqL_prim_dz_vf(momxb:momxe), & - qR_prim_vf(momxb:momxe), & - dqR_prim_dx_vf(momxb:momxe), & - dqR_prim_dy_vf(momxb:momxe), & - dqR_prim_dz_vf(momxb:momxe), & - flux_src_vf, norm_dir, ix, iy, iz) + call s_compute_viscous_source_flux(qL_prim_vf(momxb:momxe), dqL_prim_dx_vf(momxb:momxe), & + & dqL_prim_dy_vf(momxb:momxe), dqL_prim_dz_vf(momxb:momxe), & + & qR_prim_vf(momxb:momxe), dqR_prim_dx_vf(momxb:momxe), & + & dqR_prim_dy_vf(momxb:momxe), dqR_prim_dz_vf(momxb:momxe), flux_src_vf, & + & norm_dir, ix, iy, iz) else - call s_compute_viscous_source_flux( & - q_prim_vf(momxb:momxe), & - dqL_prim_dx_vf(momxb:momxe), & - dqL_prim_dy_vf(momxb:momxe), & - dqL_prim_dz_vf(momxb:momxe), & - q_prim_vf(momxb:momxe), & - dqR_prim_dx_vf(momxb:momxe), & - dqR_prim_dy_vf(momxb:momxe), & - dqR_prim_dz_vf(momxb:momxe), & - flux_src_vf, norm_dir, ix, iy, iz) + call s_compute_viscous_source_flux(q_prim_vf(momxb:momxe), dqL_prim_dx_vf(momxb:momxe), & + & dqL_prim_dy_vf(momxb:momxe), dqL_prim_dz_vf(momxb:momxe), & + & q_prim_vf(momxb:momxe), dqR_prim_dx_vf(momxb:momxe), & + & dqR_prim_dy_vf(momxb:momxe), dqR_prim_dz_vf(momxb:momxe), flux_src_vf, & + & norm_dir, ix, iy, iz) end if end if - call s_finalize_riemann_solver(flux_vf, flux_src_vf, & - flux_gsrc_vf, & - norm_dir) + call s_finalize_riemann_solver(flux_vf, flux_src_vf, flux_gsrc_vf, norm_dir) end subroutine s_hll_riemann_solver !> @brief Computes intercell fluxes using the Lax-Friedrichs (LF) approximate Riemann solver. - subroutine s_lf_riemann_solver(qL_prim_rsx_vf, qL_prim_rsy_vf, qL_prim_rsz_vf, dqL_prim_dx_vf, & - dqL_prim_dy_vf, & - dqL_prim_dz_vf, & - qL_prim_vf, & - qR_prim_rsx_vf, qR_prim_rsy_vf, qR_prim_rsz_vf, dqR_prim_dx_vf, & - dqR_prim_dy_vf, & - dqR_prim_dz_vf, & - qR_prim_vf, & - q_prim_vf, & - flux_vf, flux_src_vf, & - flux_gsrc_vf, & - norm_dir, ix, iy, iz) - - real(wp), dimension(idwbuff(1)%beg:, idwbuff(2)%beg:, idwbuff(3)%beg:, 1:), intent(inout) :: qL_prim_rsx_vf, qL_prim_rsy_vf, qL_prim_rsz_vf, qR_prim_rsx_vf, qR_prim_rsy_vf, qR_prim_rsz_vf - type(scalar_field), dimension(sys_size), intent(in) :: q_prim_vf - + subroutine s_lf_riemann_solver(qL_prim_rsx_vf, qL_prim_rsy_vf, qL_prim_rsz_vf, dqL_prim_dx_vf, dqL_prim_dy_vf, & + & dqL_prim_dz_vf, qL_prim_vf, qR_prim_rsx_vf, qR_prim_rsy_vf, qR_prim_rsz_vf, dqR_prim_dx_vf, & + & dqR_prim_dy_vf, dqR_prim_dz_vf, qR_prim_vf, q_prim_vf, flux_vf, flux_src_vf, flux_gsrc_vf, & + & norm_dir, ix, iy, iz) + + real(wp), dimension(idwbuff(1)%beg:,idwbuff(2)%beg:,idwbuff(3)%beg:,1:), intent(inout) :: qL_prim_rsx_vf, qL_prim_rsy_vf, & + & qL_prim_rsz_vf, qR_prim_rsx_vf, qR_prim_rsy_vf, qR_prim_rsz_vf + type(scalar_field), dimension(sys_size), intent(in) :: q_prim_vf type(scalar_field), allocatable, dimension(:), intent(inout) :: qL_prim_vf, qR_prim_vf - - type(scalar_field), & - allocatable, dimension(:), & - intent(inout) :: dqL_prim_dx_vf, dqR_prim_dx_vf, & - dqL_prim_dy_vf, dqR_prim_dy_vf, & - dqL_prim_dz_vf, dqR_prim_dz_vf + type(scalar_field), allocatable, dimension(:), intent(inout) :: dqL_prim_dx_vf, dqR_prim_dx_vf, dqL_prim_dy_vf, & + & dqR_prim_dy_vf, dqL_prim_dz_vf, dqR_prim_dz_vf ! Intercell fluxes - type(scalar_field), & - dimension(sys_size), & - intent(inout) :: flux_vf, flux_src_vf, flux_gsrc_vf - real(wp) :: flux_tau_L, flux_tau_R + type(scalar_field), dimension(sys_size), intent(inout) :: flux_vf, flux_src_vf, flux_gsrc_vf + real(wp) :: flux_tau_L, flux_tau_R + integer, intent(in) :: norm_dir + type(int_bounds_info), intent(in) :: ix, iy, iz - integer, intent(in) :: norm_dir - type(int_bounds_info), intent(in) :: ix, iy, iz #:if not MFC_CASE_OPTIMIZATION and USING_AMD - real(wp), dimension(3) :: alpha_rho_L, alpha_rho_R - real(wp), dimension(3) :: vel_L, vel_R - real(wp), dimension(3) :: alpha_L, alpha_R - real(wp), dimension(10) :: Ys_L, Ys_R - real(wp), dimension(10) :: Cp_iL, Cp_iR, Xs_L, Xs_R, Gamma_iL, Gamma_iR - real(wp), dimension(10) :: Yi_avg, Phi_avg, h_iL, h_iR, h_avg_2 - real(wp), dimension(3, 3) :: vel_grad_L, vel_grad_R !< Averaged velocity gradient tensor `d(vel_i)/d(coord_j)`. + real(wp), dimension(3) :: alpha_rho_L, alpha_rho_R + real(wp), dimension(3) :: vel_L, vel_R + real(wp), dimension(3) :: alpha_L, alpha_R + real(wp), dimension(10) :: Ys_L, Ys_R + real(wp), dimension(10) :: Cp_iL, Cp_iR, Xs_L, Xs_R, Gamma_iL, Gamma_iR + real(wp), dimension(10) :: Yi_avg, Phi_avg, h_iL, h_iR, h_avg_2 + real(wp), dimension(3, 3) :: vel_grad_L, vel_grad_R !< Averaged velocity gradient tensor `d(vel_i)/d(coord_j)`. #:else - real(wp), dimension(num_fluids) :: alpha_rho_L, alpha_rho_R - real(wp), dimension(num_vels) :: vel_L, vel_R - real(wp), dimension(num_fluids) :: alpha_L, alpha_R + real(wp), dimension(num_fluids) :: alpha_rho_L, alpha_rho_R + real(wp), dimension(num_vels) :: vel_L, vel_R + real(wp), dimension(num_fluids) :: alpha_L, alpha_R real(wp), dimension(num_species) :: Ys_L, Ys_R real(wp), dimension(num_species) :: Cp_iL, Cp_iR, Xs_L, Xs_R, Gamma_iL, Gamma_iR real(wp), dimension(num_species) :: Yi_avg, Phi_avg, h_iL, h_iR, h_avg_2 - real(wp), dimension(num_dims, num_dims) :: vel_grad_L, vel_grad_R !< Averaged velocity gradient tensor `d(vel_i)/d(coord_j)`. + !> Averaged velocity gradient tensor `d(vel_i)/d(coord_j)`. + real(wp), dimension(num_dims, num_dims) :: vel_grad_L, vel_grad_R #:endif - real(wp) :: rho_L, rho_R - - real(wp) :: pres_L, pres_R - real(wp) :: E_L, E_R - real(wp) :: H_L, H_R - real(wp) :: Cp_avg, Cv_avg, T_avg, eps, c_sum_Yi_Phi - real(wp) :: T_L, T_R - real(wp) :: Y_L, Y_R - real(wp) :: MW_L, MW_R - real(wp) :: R_gas_L, R_gas_R - real(wp) :: Cp_L, Cp_R - real(wp) :: Cv_L, Cv_R - real(wp) :: Gamm_L, Gamm_R - real(wp) :: gamma_L, gamma_R - real(wp) :: pi_inf_L, pi_inf_R - real(wp) :: qv_L, qv_R - real(wp) :: c_L, c_R - real(wp), dimension(6) :: tau_e_L, tau_e_R - real(wp) :: G_L, G_R - real(wp), dimension(2) :: Re_L, Re_R - real(wp), dimension(3) :: xi_field_L, xi_field_R - - real(wp) :: rho_avg - real(wp) :: H_avg - real(wp) :: gamma_avg - real(wp) :: c_avg - - real(wp) :: s_L, s_R, s_M, s_P, s_S - real(wp) :: xi_M, xi_P - - real(wp) :: ptilde_L, ptilde_R - real(wp) :: vel_L_rms, vel_R_rms, vel_avg_rms - real(wp) :: vel_L_tmp, vel_R_tmp - real(wp) :: Ms_L, Ms_R, pres_SL, pres_SR - real(wp) :: alpha_L_sum, alpha_R_sum - real(wp) :: zcoef, pcorr !< low Mach number correction - - type(riemann_states) :: c_fast, pres_mag + real(wp) :: rho_L, rho_R + real(wp) :: pres_L, pres_R + real(wp) :: E_L, E_R + real(wp) :: H_L, H_R + real(wp) :: Cp_avg, Cv_avg, T_avg, eps, c_sum_Yi_Phi + real(wp) :: T_L, T_R + real(wp) :: Y_L, Y_R + real(wp) :: MW_L, MW_R + real(wp) :: R_gas_L, R_gas_R + real(wp) :: Cp_L, Cp_R + real(wp) :: Cv_L, Cv_R + real(wp) :: Gamm_L, Gamm_R + real(wp) :: gamma_L, gamma_R + real(wp) :: pi_inf_L, pi_inf_R + real(wp) :: qv_L, qv_R + real(wp) :: c_L, c_R + real(wp), dimension(6) :: tau_e_L, tau_e_R + real(wp) :: G_L, G_R + real(wp), dimension(2) :: Re_L, Re_R + real(wp), dimension(3) :: xi_field_L, xi_field_R + real(wp) :: rho_avg + real(wp) :: H_avg + real(wp) :: gamma_avg + real(wp) :: c_avg + real(wp) :: s_L, s_R, s_M, s_P, s_S + real(wp) :: xi_M, xi_P + real(wp) :: ptilde_L, ptilde_R + real(wp) :: vel_L_rms, vel_R_rms, vel_avg_rms + real(wp) :: vel_L_tmp, vel_R_tmp + real(wp) :: Ms_L, Ms_R, pres_SL, pres_SR + real(wp) :: alpha_L_sum, alpha_R_sum + real(wp) :: zcoef, pcorr !< low Mach number correction + type(riemann_states) :: c_fast, pres_mag type(riemann_states_vec3) :: B - - type(riemann_states) :: Ga ! Gamma (Lorentz factor) - type(riemann_states) :: vdotB, B2 - type(riemann_states_vec3) :: b4 ! 4-magnetic field components (spatial: b4x, b4y, b4z) - type(riemann_states_vec3) :: cm ! Conservative momentum variables - - integer :: i, j, k, l, q !< Generic loop iterators - integer, dimension(3) :: idx_right_phys !< Physical (j,k,l) indices for right state. - - ! Populating the buffers of the left and right Riemann problem - ! states variables, based on the choice of boundary conditions - call s_populate_riemann_states_variables_buffers( & - qL_prim_rsx_vf, qL_prim_rsy_vf, qL_prim_rsz_vf, dqL_prim_dx_vf, & - dqL_prim_dy_vf, & - dqL_prim_dz_vf, & - qR_prim_rsx_vf, qR_prim_rsy_vf, qR_prim_rsz_vf, dqR_prim_dx_vf, & - dqR_prim_dy_vf, & - dqR_prim_dz_vf, & - norm_dir, ix, iy, iz) + type(riemann_states) :: Ga ! Gamma (Lorentz factor) + type(riemann_states) :: vdotB, B2 + type(riemann_states_vec3) :: b4 ! 4-magnetic field components (spatial: b4x, b4y, b4z) + type(riemann_states_vec3) :: cm ! Conservative momentum variables + integer :: i, j, k, l, q !< Generic loop iterators + integer, dimension(3) :: idx_right_phys !< Physical (j,k,l) indices for right state. + + ! Populating the buffers of the left and right Riemann problem states variables, based on the choice of boundary conditions + call s_populate_riemann_states_variables_buffers(qL_prim_rsx_vf, qL_prim_rsy_vf, qL_prim_rsz_vf, dqL_prim_dx_vf, & + & dqL_prim_dy_vf, dqL_prim_dz_vf, qR_prim_rsx_vf, qR_prim_rsy_vf, qR_prim_rsz_vf, dqR_prim_dx_vf, dqR_prim_dy_vf, & + & dqR_prim_dz_vf, norm_dir, ix, iy, iz) ! Reshaping inputted data based on dimensional splitting direction - call s_initialize_riemann_solver( & - flux_src_vf, & - norm_dir) + call s_initialize_riemann_solver(flux_src_vf, norm_dir) #:for NORM_DIR, XYZ in [(1, 'x'), (2, 'y'), (3, 'z')] - if (norm_dir == ${NORM_DIR}$) then - $:GPU_PARALLEL_LOOP(collapse=3, private='[i,j,k,l, q, alpha_rho_L,alpha_rho_R,vel_L,vel_R,alpha_L,alpha_R,tau_e_L,tau_e_R,G_L,G_R,Re_L,Re_R,rho_avg,h_avg,gamma_avg,s_L,s_R,s_S,Ys_L,Ys_R,xi_field_L,xi_field_R,Cp_iL,Cp_iR,Xs_L,Xs_R,Gamma_iL,Gamma_iR,Yi_avg,Phi_avg,h_iL,h_iR,h_avg_2,c_fast,pres_mag,B,Ga,vdotB,B2,b4,cm,pcorr,zcoef,vel_grad_L,vel_grad_R,idx_right_phys,vel_L_rms,vel_R_rms,vel_avg_rms,vel_L_tmp,vel_R_tmp,Ms_L,Ms_R,pres_SL,pres_SR,alpha_L_sum,alpha_R_sum,c_avg,pres_L,pres_R,rho_L,rho_R,gamma_L,gamma_R,pi_inf_L,pi_inf_R,qv_L,qv_R,c_L,c_R,E_L,E_R,H_L,H_R,ptilde_L,ptilde_R,s_M,s_P,xi_M,xi_P,Cp_avg,Cv_avg,T_avg,eps,c_sum_Yi_Phi,Cp_L,Cp_R,Cv_L,Cv_R,R_gas_L,R_gas_R,MW_L,MW_R,T_L,T_R,Y_L,Y_R]') + $:GPU_PARALLEL_LOOP(collapse=3, private='[i, j, k, l, q, alpha_rho_L, alpha_rho_R, vel_L, vel_R, alpha_L, & + & alpha_R, tau_e_L, tau_e_R, G_L, G_R, Re_L, Re_R, rho_avg, h_avg, gamma_avg, s_L, s_R, s_S, & + & Ys_L, Ys_R, xi_field_L, xi_field_R, Cp_iL, Cp_iR, Xs_L, Xs_R, Gamma_iL, Gamma_iR, Yi_avg, & + & Phi_avg, h_iL, h_iR, h_avg_2, c_fast, pres_mag, B, Ga, vdotB, B2, b4, cm, pcorr, zcoef, & + & vel_grad_L, vel_grad_R, idx_right_phys, vel_L_rms, vel_R_rms, vel_avg_rms, vel_L_tmp, & + & vel_R_tmp, Ms_L, Ms_R, pres_SL, pres_SR, alpha_L_sum, alpha_R_sum, c_avg, pres_L, pres_R, & + & rho_L, rho_R, gamma_L, gamma_R, pi_inf_L, pi_inf_R, qv_L, qv_R, c_L, c_R, E_L, E_R, H_L, & + & H_R, ptilde_L, ptilde_R, s_M, s_P, xi_M, xi_P, Cp_avg, Cv_avg, T_avg, eps, c_sum_Yi_Phi, & + & Cp_L, Cp_R, Cv_L, Cv_R, R_gas_L, R_gas_R, MW_L, MW_R, T_L, T_R, Y_L, Y_R]') do l = is3%beg, is3%end do k = is2%beg, is2%end do j = is1%beg, is1%end @@ -1187,14 +966,14 @@ contains pres_R = qR_prim_rs${XYZ}$_vf(j + 1, k, l, E_idx) if (mhd) then - if (n == 0) then ! 1D: constant Bx; By, Bz as variables + if (n == 0) then ! 1D: constant Bx; By, Bz as variables B%L(1) = Bx0 B%R(1) = Bx0 B%L(2) = qL_prim_rs${XYZ}$_vf(j, k, l, B_idx%beg) B%R(2) = qR_prim_rs${XYZ}$_vf(j + 1, k, l, B_idx%beg) B%L(3) = qL_prim_rs${XYZ}$_vf(j, k, l, B_idx%beg + 1) B%R(3) = qR_prim_rs${XYZ}$_vf(j + 1, k, l, B_idx%beg + 1) - else ! 2D/3D: Bx, By, Bz as variables + else ! 2D/3D: Bx, By, Bz as variables B%L(1) = qL_prim_rs${XYZ}$_vf(j, k, l, B_idx%beg) B%R(1) = qR_prim_rs${XYZ}$_vf(j + 1, k, l, B_idx%beg) B%L(2) = qL_prim_rs${XYZ}$_vf(j, k, l, B_idx%beg + 1) @@ -1259,10 +1038,8 @@ contains $:GPU_LOOP(parallelism='[seq]') do q = 1, Re_size(i) - Re_L(i) = alpha_L(Re_idx(i, q))/Res_gs(i, q) & - + Re_L(i) - Re_R(i) = alpha_R(Re_idx(i, q))/Res_gs(i, q) & - + Re_R(i) + Re_L(i) = alpha_L(Re_idx(i, q))/Res_gs(i, q) + Re_L(i) + Re_R(i) = alpha_R(Re_idx(i, q))/Res_gs(i, q) + Re_R(i) end do Re_L(i) = 1._wp/max(Re_L(i), sgm_eps) @@ -1323,7 +1100,7 @@ contains E_R = rho_R*E_R + 5.e-1*rho_R*vel_R_rms H_L = (E_L + pres_L)/rho_L H_R = (E_R + pres_R)/rho_R - elseif (mhd .and. relativity) then + else if (mhd .and. relativity) then #:if not MFC_CASE_OPTIMIZATION or num_dims > 2 Ga%L = 1._wp/sqrt(1._wp - vel_L_rms) Ga%R = 1._wp/sqrt(1._wp - vel_R_rms) @@ -1348,13 +1125,15 @@ contains E_L = rho_L*H_L*Ga%L**2 - pres_L + 0.5_wp*(B2%L + vel_L_rms*B2%L - vdotB%L**2._wp) - rho_L*Ga%L E_R = rho_R*H_R*Ga%R**2 - pres_R + 0.5_wp*(B2%R + vel_R_rms*B2%R - vdotB%R**2._wp) - rho_R*Ga%R #:endif - elseif (mhd .and. .not. relativity) then + else if (mhd .and. .not. relativity) then pres_mag%L = 0.5_wp*(B%L(1)**2._wp + B%L(2)**2._wp + B%L(3)**2._wp) pres_mag%R = 0.5_wp*(B%R(1)**2._wp + B%R(2)**2._wp + B%R(3)**2._wp) E_L = gamma_L*pres_L + pi_inf_L + 0.5_wp*rho_L*vel_L_rms + qv_L + pres_mag%L - E_R = gamma_R*pres_R + pi_inf_R + 0.5_wp*rho_R*vel_R_rms + qv_R + pres_mag%R ! includes magnetic energy + E_R = gamma_R*pres_R + pi_inf_R + 0.5_wp*rho_R*vel_R_rms + qv_R & + & + pres_mag%R ! includes magnetic energy H_L = (E_L + pres_L - pres_mag%L)/rho_L - H_R = (E_R + pres_R - pres_mag%R)/rho_R ! stagnation enthalpy here excludes magnetic energy (only used to find speed of sound) + H_R = (E_R + pres_R - pres_mag%R) & + & /rho_R ! stagnation enthalpy here excludes magnetic energy (only used to find speed of sound) else E_L = gamma_L*pres_L + pi_inf_L + 5.e-1*rho_L*vel_L_rms + qv_L E_R = gamma_R*pres_R + pi_inf_R + 5.e-1*rho_R*vel_R_rms + qv_R @@ -1380,8 +1159,7 @@ contains do i = 1, strxe - strxb + 1 tau_e_L(i) = qL_prim_rs${XYZ}$_vf(j, k, l, strxb - 1 + i) tau_e_R(i) = qR_prim_rs${XYZ}$_vf(j + 1, k, l, strxb - 1 + i) - ! Elastic contribution to energy if G large enough - !TODO take out if statement if stable without + ! Elastic contribution to energy if G large enough TODO take out if statement if stable without if ((G_L > 1000) .and. (G_R > 1000)) then E_L = E_L + (tau_e_L(i)*tau_e_L(i))/(4._wp*G_L) E_R = E_R + (tau_e_R(i)*tau_e_R(i))/(4._wp*G_R) @@ -1394,11 +1172,11 @@ contains end do end if - call s_compute_speed_of_sound(pres_L, rho_L, gamma_L, pi_inf_L, H_L, alpha_L, & - vel_L_rms, 0._wp, c_L, qv_L) + call s_compute_speed_of_sound(pres_L, rho_L, gamma_L, pi_inf_L, H_L, alpha_L, vel_L_rms, 0._wp, c_L, & + & qv_L) - call s_compute_speed_of_sound(pres_R, rho_R, gamma_R, pi_inf_R, H_R, alpha_R, & - vel_R_rms, 0._wp, c_R, qv_R) + call s_compute_speed_of_sound(pres_R, rho_R, gamma_R, pi_inf_R, H_R, alpha_R, vel_R_rms, 0._wp, c_R, & + & qv_R) if (mhd) then call s_compute_fast_magnetosonic_speed(rho_L, c_L, B%L, norm_dir, c_fast%L, H_L) @@ -1433,22 +1211,17 @@ contains if (.not. relativity) then $:GPU_LOOP(parallelism='[seq]') do i = 1, contxe - flux_rs${XYZ}$_vf(j, k, l, i) = & - (s_M*alpha_rho_R(i)*vel_R(norm_dir) & - - s_P*alpha_rho_L(i)*vel_L(norm_dir) & - + s_M*s_P*(alpha_rho_L(i) & - - alpha_rho_R(i))) & - /(s_M - s_P) + flux_rs${XYZ}$_vf(j, k, l, & + & i) = (s_M*alpha_rho_R(i)*vel_R(norm_dir) - s_P*alpha_rho_L(i) & + & *vel_L(norm_dir) + s_M*s_P*(alpha_rho_L(i) - alpha_rho_R(i)))/(s_M - s_P) end do - elseif (relativity) then + else if (relativity) then $:GPU_LOOP(parallelism='[seq]') do i = 1, contxe - flux_rs${XYZ}$_vf(j, k, l, i) = & - (s_M*Ga%R*alpha_rho_R(i)*vel_R(norm_dir) & - - s_P*Ga%L*alpha_rho_L(i)*vel_L(norm_dir) & - + s_M*s_P*(Ga%L*alpha_rho_L(i) & - - Ga%R*alpha_rho_R(i))) & - /(s_M - s_P) + flux_rs${XYZ}$_vf(j, k, l, & + & i) = (s_M*Ga%R*alpha_rho_R(i)*vel_R(norm_dir) - s_P*Ga%L*alpha_rho_L(i) & + & *vel_L(norm_dir) + s_M*s_P*(Ga%L*alpha_rho_L(i) - Ga%R*alpha_rho_R(i))) & + & /(s_M - s_P) end do end if @@ -1456,78 +1229,54 @@ contains if (mhd .and. (.not. relativity)) then $:GPU_LOOP(parallelism='[seq]') do i = 1, 3 - ! Flux of rho*v_i in the ${XYZ}$ direction - ! = rho * v_i * v_${XYZ}$ - B_i * B_${XYZ}$ + delta_(${XYZ}$,i) * p_tot - flux_rs${XYZ}$_vf(j, k, l, contxe + i) = & - (s_M*(rho_R*vel_R(i)*vel_R(norm_dir) & - - B%R(i)*B%R(norm_dir) & - + dir_flg(i)*(pres_R + pres_mag%R)) & - - s_P*(rho_L*vel_L(i)*vel_L(norm_dir) & - - B%L(i)*B%L(norm_dir) & - + dir_flg(i)*(pres_L + pres_mag%L)) & - + s_M*s_P*(rho_L*vel_L(i) - rho_R*vel_R(i))) & - /(s_M - s_P) + ! Flux of rho*v_i in the ${XYZ}$ direction = rho * v_i * v_${XYZ}$ - B_i * B_${XYZ}$ + + ! delta_(${XYZ}$,i) * p_tot + flux_rs${XYZ}$_vf(j, k, l, & + & contxe + i) = (s_M*(rho_R*vel_R(i)*vel_R(norm_dir) - B%R(i)*B%R(norm_dir) & + & + dir_flg(i)*(pres_R + pres_mag%R)) - s_P*(rho_L*vel_L(i)*vel_L(norm_dir) & + & - B%L(i)*B%L(norm_dir) + dir_flg(i)*(pres_L + pres_mag%L)) & + & + s_M*s_P*(rho_L*vel_L(i) - rho_R*vel_R(i)))/(s_M - s_P) end do - elseif (mhd .and. relativity) then + else if (mhd .and. relativity) then $:GPU_LOOP(parallelism='[seq]') do i = 1, 3 - ! Flux of m_i in the ${XYZ}$ direction - ! = m_i * v_${XYZ}$ - b_i/Gamma * B_${XYZ}$ + delta_(${XYZ}$,i) * p_tot - flux_rs${XYZ}$_vf(j, k, l, contxe + i) = & - (s_M*(cm%R(i)*vel_R(norm_dir) & - - b4%R(i)/Ga%R*B%R(norm_dir) & - + dir_flg(i)*(pres_R + pres_mag%R)) & - - s_P*(cm%L(i)*vel_L(norm_dir) & - - b4%L(i)/Ga%L*B%L(norm_dir) & - + dir_flg(i)*(pres_L + pres_mag%L)) & - + s_M*s_P*(cm%L(i) - cm%R(i))) & - /(s_M - s_P) + ! Flux of m_i in the ${XYZ}$ direction = m_i * v_${XYZ}$ - b_i/Gamma * B_${XYZ}$ + + ! delta_(${XYZ}$,i) * p_tot + flux_rs${XYZ}$_vf(j, k, l, & + & contxe + i) = (s_M*(cm%R(i)*vel_R(norm_dir) - b4%R(i)/Ga%R*B%R(norm_dir) & + & + dir_flg(i)*(pres_R + pres_mag%R)) - s_P*(cm%L(i)*vel_L(norm_dir) & + & - b4%L(i)/Ga%L*B%L(norm_dir) + dir_flg(i)*(pres_L + pres_mag%L)) & + & + s_M*s_P*(cm%L(i) - cm%R(i)))/(s_M - s_P) end do - elseif (bubbles_euler) then + else if (bubbles_euler) then $:GPU_LOOP(parallelism='[seq]') do i = 1, num_vels - flux_rs${XYZ}$_vf(j, k, l, contxe + dir_idx(i)) = & - (s_M*(rho_R*vel_R(dir_idx(1)) & - *vel_R(dir_idx(i)) & - + dir_flg(dir_idx(i))*(pres_R - ptilde_R)) & - - s_P*(rho_L*vel_L(dir_idx(1)) & - *vel_L(dir_idx(i)) & - + dir_flg(dir_idx(i))*(pres_L - ptilde_L)) & - + s_M*s_P*(rho_L*vel_L(dir_idx(i)) & - - rho_R*vel_R(dir_idx(i)))) & - /(s_M - s_P) & - + (s_M/s_L)*(s_P/s_R)*pcorr*(vel_R(dir_idx(i)) - vel_L(dir_idx(i))) + flux_rs${XYZ}$_vf(j, k, l, & + & contxe + dir_idx(i)) = (s_M*(rho_R*vel_R(dir_idx(1))*vel_R(dir_idx(i)) & + & + dir_flg(dir_idx(i))*(pres_R - ptilde_R)) - s_P*(rho_L*vel_L(dir_idx(1)) & + & *vel_L(dir_idx(i)) + dir_flg(dir_idx(i))*(pres_L - ptilde_L)) & + & + s_M*s_P*(rho_L*vel_L(dir_idx(i)) - rho_R*vel_R(dir_idx(i))))/(s_M - s_P) & + & + (s_M/s_L)*(s_P/s_R)*pcorr*(vel_R(dir_idx(i)) - vel_L(dir_idx(i))) end do else if (hypoelasticity) then $:GPU_LOOP(parallelism='[seq]') do i = 1, num_vels - flux_rs${XYZ}$_vf(j, k, l, contxe + dir_idx(i)) = & - (s_M*(rho_R*vel_R(dir_idx(1)) & - *vel_R(dir_idx(i)) & - + dir_flg(dir_idx(i))*pres_R & - - tau_e_R(dir_idx_tau(i))) & - - s_P*(rho_L*vel_L(dir_idx(1)) & - *vel_L(dir_idx(i)) & - + dir_flg(dir_idx(i))*pres_L & - - tau_e_L(dir_idx_tau(i))) & - + s_M*s_P*(rho_L*vel_L(dir_idx(i)) & - - rho_R*vel_R(dir_idx(i)))) & - /(s_M - s_P) + flux_rs${XYZ}$_vf(j, k, l, & + & contxe + dir_idx(i)) = (s_M*(rho_R*vel_R(dir_idx(1))*vel_R(dir_idx(i)) & + & + dir_flg(dir_idx(i))*pres_R - tau_e_R(dir_idx_tau(i))) & + & - s_P*(rho_L*vel_L(dir_idx(1))*vel_L(dir_idx(i)) + dir_flg(dir_idx(i)) & + & *pres_L - tau_e_L(dir_idx_tau(i))) + s_M*s_P*(rho_L*vel_L(dir_idx(i)) & + & - rho_R*vel_R(dir_idx(i))))/(s_M - s_P) end do else $:GPU_LOOP(parallelism='[seq]') do i = 1, num_vels - flux_rs${XYZ}$_vf(j, k, l, contxe + dir_idx(i)) = & - (s_M*(rho_R*vel_R(dir_idx(1)) & - *vel_R(dir_idx(i)) & - + dir_flg(dir_idx(i))*pres_R) & - - s_P*(rho_L*vel_L(dir_idx(1)) & - *vel_L(dir_idx(i)) & - + dir_flg(dir_idx(i))*pres_L) & - + s_M*s_P*(rho_L*vel_L(dir_idx(i)) & - - rho_R*vel_R(dir_idx(i)))) & - /(s_M - s_P) & - + (s_M/s_L)*(s_P/s_R)*pcorr*(vel_R(dir_idx(i)) - vel_L(dir_idx(i))) + flux_rs${XYZ}$_vf(j, k, l, & + & contxe + dir_idx(i)) = (s_M*(rho_R*vel_R(dir_idx(1))*vel_R(dir_idx(i)) & + & + dir_flg(dir_idx(i))*pres_R) - s_P*(rho_L*vel_L(dir_idx(1)) & + & *vel_L(dir_idx(i)) + dir_flg(dir_idx(i))*pres_L) & + & + s_M*s_P*(rho_L*vel_L(dir_idx(i)) - rho_R*vel_R(dir_idx(i))))/(s_M - s_P) & + & + (s_M/s_L)*(s_P/s_R)*pcorr*(vel_R(dir_idx(i)) - vel_L(dir_idx(i))) end do end if @@ -1535,27 +1284,24 @@ contains if (mhd .and. (.not. relativity)) then ! energy flux = (E + p + p_mag) * v_${XYZ}$ - B_${XYZ}$ * (v_x*B_x + v_y*B_y + v_z*B_z) #:if not MFC_CASE_OPTIMIZATION or num_dims > 1 - flux_rs${XYZ}$_vf(j, k, l, E_idx) = & - (s_M*(vel_R(norm_dir)*(E_R + pres_R + pres_mag%R) - B%R(norm_dir)*(vel_R(1)*B%R(1) + vel_R(2)*B%R(2) + vel_R(3)*B%R(3))) & - - s_P*(vel_L(norm_dir)*(E_L + pres_L + pres_mag%L) - B%L(norm_dir)*(vel_L(1)*B%L(1) + vel_L(2)*B%L(2) + vel_L(3)*B%L(3))) & - + s_M*s_P*(E_L - E_R)) & - /(s_M - s_P) + flux_rs${XYZ}$_vf(j, k, l, & + & E_idx) = (s_M*(vel_R(norm_dir)*(E_R + pres_R + pres_mag%R) - B%R(norm_dir) & + & *(vel_R(1)*B%R(1) + vel_R(2)*B%R(2) + vel_R(3)*B%R(3))) & + & - s_P*(vel_L(norm_dir)*(E_L + pres_L + pres_mag%L) - B%L(norm_dir) & + & *(vel_L(1)*B%L(1) + vel_L(2)*B%L(2) + vel_L(3)*B%L(3))) + s_M*s_P*(E_L & + & - E_R))/(s_M - s_P) #:endif - elseif (mhd .and. relativity) then - ! energy flux = m_${XYZ}$ - mass flux - ! Hard-coded for single-component for now - flux_rs${XYZ}$_vf(j, k, l, E_idx) = & - (s_M*(cm%R(norm_dir) - Ga%R*alpha_rho_R(1)*vel_R(norm_dir)) & - - s_P*(cm%L(norm_dir) - Ga%L*alpha_rho_L(1)*vel_L(norm_dir)) & - + s_M*s_P*(E_L - E_R)) & - /(s_M - s_P) + else if (mhd .and. relativity) then + ! energy flux = m_${XYZ}$ - mass flux Hard-coded for single-component for now + flux_rs${XYZ}$_vf(j, k, l, & + & E_idx) = (s_M*(cm%R(norm_dir) - Ga%R*alpha_rho_R(1)*vel_R(norm_dir)) & + & - s_P*(cm%L(norm_dir) - Ga%L*alpha_rho_L(1)*vel_L(norm_dir)) + s_M*s_P*(E_L & + & - E_R))/(s_M - s_P) else if (bubbles_euler) then - flux_rs${XYZ}$_vf(j, k, l, E_idx) = & - (s_M*vel_R(dir_idx(1))*(E_R + pres_R - ptilde_R) & - - s_P*vel_L(dir_idx(1))*(E_L + pres_L - ptilde_L) & - + s_M*s_P*(E_L - E_R)) & - /(s_M - s_P) & - + (s_M/s_L)*(s_P/s_R)*pcorr*(vel_R_rms - vel_L_rms)/2._wp + flux_rs${XYZ}$_vf(j, k, l, & + & E_idx) = (s_M*vel_R(dir_idx(1))*(E_R + pres_R - ptilde_R) & + & - s_P*vel_L(dir_idx(1))*(E_L + pres_L - ptilde_L) + s_M*s_P*(E_L - E_R))/(s_M & + & - s_P) + (s_M/s_L)*(s_P/s_R)*pcorr*(vel_R_rms - vel_L_rms)/2._wp else if (hypoelasticity) then flux_tau_L = 0._wp; flux_tau_R = 0._wp $:GPU_LOOP(parallelism='[seq]') @@ -1563,44 +1309,34 @@ contains flux_tau_L = flux_tau_L + tau_e_L(dir_idx_tau(i))*vel_L(dir_idx(i)) flux_tau_R = flux_tau_R + tau_e_R(dir_idx_tau(i))*vel_R(dir_idx(i)) end do - flux_rs${XYZ}$_vf(j, k, l, E_idx) = & - (s_M*(vel_R(dir_idx(1))*(E_R + pres_R) - flux_tau_R) & - - s_P*(vel_L(dir_idx(1))*(E_L + pres_L) - flux_tau_L) & - + s_M*s_P*(E_L - E_R))/(s_M - s_P) + flux_rs${XYZ}$_vf(j, k, l, & + & E_idx) = (s_M*(vel_R(dir_idx(1))*(E_R + pres_R) - flux_tau_R) & + & - s_P*(vel_L(dir_idx(1))*(E_L + pres_L) - flux_tau_L) + s_M*s_P*(E_L - E_R)) & + & /(s_M - s_P) else - flux_rs${XYZ}$_vf(j, k, l, E_idx) = & - (s_M*vel_R(dir_idx(1))*(E_R + pres_R) & - - s_P*vel_L(dir_idx(1))*(E_L + pres_L) & - + s_M*s_P*(E_L - E_R)) & - /(s_M - s_P) & - + (s_M/s_L)*(s_P/s_R)*pcorr*(vel_R_rms - vel_L_rms)/2._wp + flux_rs${XYZ}$_vf(j, k, l, & + & E_idx) = (s_M*vel_R(dir_idx(1))*(E_R + pres_R) - s_P*vel_L(dir_idx(1))*(E_L & + & + pres_L) + s_M*s_P*(E_L - E_R))/(s_M - s_P) + (s_M/s_L)*(s_P/s_R) & + & *pcorr*(vel_R_rms - vel_L_rms)/2._wp end if ! Elastic Stresses if (hypoelasticity) then - do i = 1, strxe - strxb + 1 !TODO: this indexing may be slow - flux_rs${XYZ}$_vf(j, k, l, strxb - 1 + i) = & - (s_M*(rho_R*vel_R(dir_idx(1)) & - *tau_e_R(i)) & - - s_P*(rho_L*vel_L(dir_idx(1)) & - *tau_e_L(i)) & - + s_M*s_P*(rho_L*tau_e_L(i) & - - rho_R*tau_e_R(i))) & - /(s_M - s_P) + do i = 1, strxe - strxb + 1 ! TODO: this indexing may be slow + flux_rs${XYZ}$_vf(j, k, l, & + & strxb - 1 + i) = (s_M*(rho_R*vel_R(dir_idx(1))*tau_e_R(i)) & + & - s_P*(rho_L*vel_L(dir_idx(1))*tau_e_L(i)) + s_M*s_P*(rho_L*tau_e_L(i) & + & - rho_R*tau_e_R(i)))/(s_M - s_P) end do end if ! Advection $:GPU_LOOP(parallelism='[seq]') do i = advxb, advxe - flux_rs${XYZ}$_vf(j, k, l, i) = & - (qL_prim_rs${XYZ}$_vf(j, k, l, i) & - - qR_prim_rs${XYZ}$_vf(j + 1, k, l, i)) & - *s_M*s_P/(s_M - s_P) - flux_src_rs${XYZ}$_vf(j, k, l, i) = & - (s_M*qR_prim_rs${XYZ}$_vf(j + 1, k, l, i) & - - s_P*qL_prim_rs${XYZ}$_vf(j, k, l, i)) & - /(s_M - s_P) + flux_rs${XYZ}$_vf(j, k, l, i) = (qL_prim_rs${XYZ}$_vf(j, k, l, i) - qR_prim_rs${XYZ}$_vf(j + 1, & + & k, l, i))*s_M*s_P/(s_M - s_P) + flux_src_rs${XYZ}$_vf(j, k, l, i) = (s_M*qR_prim_rs${XYZ}$_vf(j + 1, k, l, & + & i) - s_P*qL_prim_rs${XYZ}$_vf(j, k, l, i))/(s_M - s_P) end do if (bubbles_euler) then @@ -1616,34 +1352,34 @@ contains Y_L = qL_prim_rs${XYZ}$_vf(j, k, l, i) Y_R = qR_prim_rs${XYZ}$_vf(j + 1, k, l, i) - flux_rs${XYZ}$_vf(j, k, l, i) = (s_M*Y_R*rho_R*vel_R(dir_idx(1)) & - - s_P*Y_L*rho_L*vel_L(dir_idx(1)) & - + s_M*s_P*(Y_L*rho_L - Y_R*rho_R)) & - /(s_M - s_P) + flux_rs${XYZ}$_vf(j, k, l, & + & i) = (s_M*Y_R*rho_R*vel_R(dir_idx(1)) - s_P*Y_L*rho_L*vel_L(dir_idx(1)) & + & + s_M*s_P*(Y_L*rho_L - Y_R*rho_R))/(s_M - s_P) flux_src_rs${XYZ}$_vf(j, k, l, i) = 0._wp end do end if if (mhd) then - if (n == 0) then ! 1D: d/dx flux only & Bx = Bx0 = const. - ! B_y flux = v_x * B_y - v_y * Bx0 - ! B_z flux = v_x * B_z - v_z * Bx0 + if (n == 0) then ! 1D: d/dx flux only & Bx = Bx0 = const. + ! B_y flux = v_x * B_y - v_y * Bx0 B_z flux = v_x * B_z - v_z * Bx0 $:GPU_LOOP(parallelism='[seq]') do i = 0, 1 - flux_rsx_vf(j, k, l, B_idx%beg + i) = (s_M*(vel_R(1)*B%R(2 + i) - vel_R(2 + i)*Bx0) & - - s_P*(vel_L(1)*B%L(2 + i) - vel_L(2 + i)*Bx0) & - + s_M*s_P*(B%L(2 + i) - B%R(2 + i)))/(s_M - s_P) + flux_rsx_vf(j, k, l, & + & B_idx%beg + i) = (s_M*(vel_R(1)*B%R(2 + i) - vel_R(2 + i)*Bx0) & + & - s_P*(vel_L(1)*B%L(2 + i) - vel_L(2 + i)*Bx0) + s_M*s_P*(B%L(2 + i) & + & - B%R(2 + i)))/(s_M - s_P) end do - else ! 2D/3D: Bx, By, Bz /= const. but zero flux component in the same direction - ! B_x d/d${XYZ}$ flux = (1 - delta(x,${XYZ}$)) * (v_${XYZ}$ * B_x - v_x * B_${XYZ}$) - ! B_y d/d${XYZ}$ flux = (1 - delta(y,${XYZ}$)) * (v_${XYZ}$ * B_y - v_y * B_${XYZ}$) - ! B_z d/d${XYZ}$ flux = (1 - delta(z,${XYZ}$)) * (v_${XYZ}$ * B_z - v_z * B_${XYZ}$) + else ! 2D/3D: Bx, By, Bz /= const. but zero flux component in the same direction + ! B_x d/d${XYZ}$ flux = (1 - delta(x,${XYZ}$)) * (v_${XYZ}$ * B_x - v_x * B_${XYZ}$) B_y + ! d/d${XYZ}$ flux = (1 - delta(y,${XYZ}$)) * (v_${XYZ}$ * B_y - v_y * B_${XYZ}$) B_z d/d${XYZ}$ + ! flux = (1 - delta(z,${XYZ}$)) * (v_${XYZ}$ * B_z - v_z * B_${XYZ}$) $:GPU_LOOP(parallelism='[seq]') do i = 0, 2 - flux_rs${XYZ}$_vf(j, k, l, B_idx%beg + i) = (1 - dir_flg(i + 1))*( & - s_M*(vel_R(dir_idx(1))*B%R(i + 1) - vel_R(i + 1)*B%R(norm_dir)) - & - s_P*(vel_L(dir_idx(1))*B%L(i + 1) - vel_L(i + 1)*B%L(norm_dir)) + & - s_M*s_P*(B%L(i + 1) - B%R(i + 1)))/(s_M - s_P) + flux_rs${XYZ}$_vf(j, k, l, & + & B_idx%beg + i) = (1 - dir_flg(i + 1))*(s_M*(vel_R(dir_idx(1))*B%R(i & + & + 1) - vel_R(i + 1)*B%R(norm_dir)) - s_P*(vel_L(dir_idx(1))*B%L(i + 1) & + & - vel_L(i + 1)*B%L(norm_dir)) + s_M*s_P*(B%L(i + 1) - B%R(i + 1))) & + & /(s_M - s_P) end do end if flux_src_rs${XYZ}$_vf(j, k, l, advxb) = 0._wp @@ -1651,15 +1387,14 @@ contains #:if (NORM_DIR == 2) if (cyl_coord) then - !Substituting the advective flux into the inviscid geometrical source flux + ! Substituting the advective flux into the inviscid geometrical source flux $:GPU_LOOP(parallelism='[seq]') do i = 1, E_idx flux_gsrc_rs${XYZ}$_vf(j, k, l, i) = flux_rs${XYZ}$_vf(j, k, l, i) end do ! Recalculating the radial momentum geometric source flux - flux_gsrc_rs${XYZ}$_vf(j, k, l, contxe + 2) = & - flux_rs${XYZ}$_vf(j, k, l, contxe + 2) & - - (s_M*pres_R - s_P*pres_L)/(s_M - s_P) + flux_gsrc_rs${XYZ}$_vf(j, k, l, contxe + 2) = flux_rs${XYZ}$_vf(j, k, l, & + & contxe + 2) - (s_M*pres_R - s_P*pres_L)/(s_M - s_P) ! Geometrical source of the void fraction(s) is zero $:GPU_LOOP(parallelism='[seq]') do i = advxb, advxe @@ -1669,10 +1404,8 @@ contains if (cyl_coord .and. hypoelasticity) then ! += tau_sigmasigma using HLL - flux_gsrc_rs${XYZ}$_vf(j, k, l, contxe + 2) = & - flux_gsrc_rs${XYZ}$_vf(j, k, l, contxe + 2) + & - (s_M*tau_e_R(4) - s_P*tau_e_L(4)) & - /(s_M - s_P) + flux_gsrc_rs${XYZ}$_vf(j, k, l, contxe + 2) = flux_gsrc_rs${XYZ}$_vf(j, k, l, & + & contxe + 2) + (s_M*tau_e_R(4) - s_P*tau_e_L(4))/(s_M - s_P) $:GPU_LOOP(parallelism='[seq]') do i = strxb, strxe @@ -1685,11 +1418,11 @@ contains end do $:END_GPU_PARALLEL_LOOP() end if - #:endfor if (viscous .or. dummy) then - $:GPU_PARALLEL_LOOP(collapse=3, private='[i,j,k,l, idx_right_phys, vel_grad_L, vel_grad_R, alpha_L, alpha_R, vel_L, vel_R, Re_L, Re_R]', copyin='[norm_dir]') + $:GPU_PARALLEL_LOOP(collapse=3, private='[i, j, k, l, idx_right_phys, vel_grad_L, vel_grad_R, alpha_L, alpha_R, & + & vel_L, vel_R, Re_L, Re_R]', copyin='[norm_dir]') do l = isz%beg, isz%end do k = isy%beg, isy%end do j = isx%beg, isx%end @@ -1745,10 +1478,8 @@ contains $:GPU_LOOP(parallelism='[seq]') do q = 1, Re_size(i) - Re_L(i) = alpha_L(Re_idx(i, q))/Res_gs(i, q) & - + Re_L(i) - Re_R(i) = alpha_R(Re_idx(i, q))/Res_gs(i, q) & - + Re_R(i) + Re_L(i) = alpha_L(Re_idx(i, q))/Res_gs(i, q) + Re_L(i) + Re_R(i) = alpha_R(Re_idx(i, q))/Res_gs(i, q) + Re_R(i) end do Re_L(i) = 1._wp/max(Re_L(i), sgm_eps) @@ -1756,231 +1487,268 @@ contains end do if (shear_stress) then - $:GPU_LOOP(parallelism='[seq]') do i = 1, num_dims vel_grad_L(i, 1) = (dqL_prim_dx_vf(momxb + i - 1)%sf(j, k, l)/Re_L(1)) - vel_grad_R(i, 1) = (dqR_prim_dx_vf(momxb + i - 1)%sf(idx_right_phys(1), idx_right_phys(2), idx_right_phys(3))/Re_R(1)) + vel_grad_R(i, 1) = (dqR_prim_dx_vf(momxb + i - 1)%sf(idx_right_phys(1), idx_right_phys(2), & + & idx_right_phys(3))/Re_R(1)) #:if not MFC_CASE_OPTIMIZATION or num_dims > 1 if (num_dims > 1) then vel_grad_L(i, 2) = (dqL_prim_dy_vf(momxb + i - 1)%sf(j, k, l)/Re_L(1)) - vel_grad_R(i, 2) = (dqR_prim_dy_vf(momxb + i - 1)%sf(idx_right_phys(1), idx_right_phys(2), idx_right_phys(3))/Re_R(1)) + vel_grad_R(i, 2) = (dqR_prim_dy_vf(momxb + i - 1)%sf(idx_right_phys(1), & + & idx_right_phys(2), idx_right_phys(3))/Re_R(1)) end if #:if not MFC_CASE_OPTIMIZATION or num_dims > 2 if (num_dims > 2) then vel_grad_L(i, 3) = (dqL_prim_dz_vf(momxb + i - 1)%sf(j, k, l)/Re_L(1)) - vel_grad_R(i, 3) = (dqR_prim_dz_vf(momxb + i - 1)%sf(idx_right_phys(1), idx_right_phys(2), idx_right_phys(3))/Re_R(1)) + vel_grad_R(i, 3) = (dqR_prim_dz_vf(momxb + i - 1)%sf(idx_right_phys(1), & + & idx_right_phys(2), idx_right_phys(3))/Re_R(1)) end if #:endif #:endif end do if (norm_dir == 1) then - flux_src_vf(momxb)%sf(j, k, l) = flux_src_vf(momxb)%sf(j, k, l) - (4._wp/3._wp)*0.5_wp*(vel_grad_L(1, 1) + vel_grad_R(1, 1)) - flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, l) - (4._wp/3._wp)*0.5_wp*(vel_grad_L(1, 1)*vel_L(1) + vel_grad_R(1, 1)*vel_R(1)) + flux_src_vf(momxb)%sf(j, k, l) = flux_src_vf(momxb)%sf(j, k, & + & l) - (4._wp/3._wp)*0.5_wp*(vel_grad_L(1, 1) + vel_grad_R(1, 1)) + flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, & + & l) - (4._wp/3._wp)*0.5_wp*(vel_grad_L(1, 1)*vel_L(1) + vel_grad_R(1, 1)*vel_R(1)) #:if not MFC_CASE_OPTIMIZATION or num_dims > 1 if (num_dims > 1) then - flux_src_vf(momxb)%sf(j, k, l) = flux_src_vf(momxb)%sf(j, k, l) - (-2._wp/3._wp)*0.5_wp*(vel_grad_L(2, 2) + vel_grad_R(2, 2)) - flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, l) - (-2._wp/3._wp)*0.5_wp*(vel_grad_L(2, 2)*vel_L(1) + vel_grad_R(2, 2)*vel_R(1)) - - flux_src_vf(momxb + 1)%sf(j, k, l) = flux_src_vf(momxb + 1)%sf(j, k, l) - 0.5_wp*(vel_grad_L(1, 2) + vel_grad_R(1, 2)) - 0.5_wp*(vel_grad_L(2, 1) + vel_grad_R(2, 1)) - flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, l) - 0.5_wp*(vel_grad_L(1, 2)*vel_L(2) + vel_grad_R(1, 2)*vel_R(2)) - 0.5_wp*(vel_grad_L(2, 1)*vel_L(2) + vel_grad_R(2, 1)*vel_R(2)) + flux_src_vf(momxb)%sf(j, k, l) = flux_src_vf(momxb)%sf(j, k, & + & l) - (-2._wp/3._wp)*0.5_wp*(vel_grad_L(2, 2) + vel_grad_R(2, 2)) + flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, & + & l) - (-2._wp/3._wp)*0.5_wp*(vel_grad_L(2, 2)*vel_L(1) + vel_grad_R(2, & + & 2)*vel_R(1)) + + flux_src_vf(momxb + 1)%sf(j, k, l) = flux_src_vf(momxb + 1)%sf(j, k, & + & l) - 0.5_wp*(vel_grad_L(1, 2) + vel_grad_R(1, 2)) - 0.5_wp*(vel_grad_L(2, & + & 1) + vel_grad_R(2, 1)) + flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, l) - 0.5_wp*(vel_grad_L(1, & + & 2)*vel_L(2) + vel_grad_R(1, 2)*vel_R(2)) - 0.5_wp*(vel_grad_L(2, & + & 1)*vel_L(2) + vel_grad_R(2, 1)*vel_R(2)) #:if not MFC_CASE_OPTIMIZATION or num_dims > 2 if (num_dims > 2) then - flux_src_vf(momxb)%sf(j, k, l) = flux_src_vf(momxb)%sf(j, k, l) - (-2._wp/3._wp)*0.5_wp*(vel_grad_L(3, 3) + vel_grad_R(3, 3)) - flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, l) - (-2._wp/3._wp)*0.5_wp*(vel_grad_L(3, 3)*vel_L(1) + vel_grad_R(3, 3)*vel_R(1)) - - flux_src_vf(momxb + 2)%sf(j, k, l) = flux_src_vf(momxb + 2)%sf(j, k, l) - 0.5_wp*(vel_grad_L(1, 3) + vel_grad_R(1, 3)) - 0.5_wp*(vel_grad_L(3, 1) + vel_grad_R(3, 1)) - flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, l) - 0.5_wp*(vel_grad_L(1, 3)*vel_L(3) + vel_grad_R(1, 3)*vel_R(3)) - 0.5_wp*(vel_grad_L(3, 1)*vel_L(3) + vel_grad_R(3, 1)*vel_R(3)) + flux_src_vf(momxb)%sf(j, k, l) = flux_src_vf(momxb)%sf(j, k, & + & l) - (-2._wp/3._wp)*0.5_wp*(vel_grad_L(3, 3) + vel_grad_R(3, 3)) + flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, & + & l) - (-2._wp/3._wp)*0.5_wp*(vel_grad_L(3, & + & 3)*vel_L(1) + vel_grad_R(3, 3)*vel_R(1)) + + flux_src_vf(momxb + 2)%sf(j, k, l) = flux_src_vf(momxb + 2)%sf(j, k, & + & l) - 0.5_wp*(vel_grad_L(1, 3) + vel_grad_R(1, & + & 3)) - 0.5_wp*(vel_grad_L(3, 1) + vel_grad_R(3, 1)) + flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, & + & l) - 0.5_wp*(vel_grad_L(1, 3)*vel_L(3) + vel_grad_R(1, & + & 3)*vel_R(3)) - 0.5_wp*(vel_grad_L(3, 1)*vel_L(3) + vel_grad_R(3, & + & 1)*vel_R(3)) end if #:endif end if #:endif - else if (norm_dir == 2) then #:if not MFC_CASE_OPTIMIZATION or num_dims > 1 - flux_src_vf(momxb + 1)%sf(j, k, l) = flux_src_vf(momxb + 1)%sf(j, k, l) - (-2._wp/3._wp)*0.5_wp*(vel_grad_L(1, 1) + vel_grad_R(1, 1)) - flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, l) - (-2._wp/3._wp)*0.5_wp*(vel_grad_L(1, 1)*vel_L(2) + vel_grad_R(1, 1)*vel_R(2)) - - flux_src_vf(momxb + 1)%sf(j, k, l) = flux_src_vf(momxb + 1)%sf(j, k, l) - (4._wp/3._wp)*0.5_wp*(vel_grad_L(2, 2) + vel_grad_R(2, 2)) - flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, l) - (4._wp/3._wp)*0.5_wp*(vel_grad_L(2, 2)*vel_L(2) + vel_grad_R(2, 2)*vel_R(2)) - - flux_src_vf(momxb)%sf(j, k, l) = flux_src_vf(momxb)%sf(j, k, l) - 0.5_wp*(vel_grad_L(1, 2) + vel_grad_R(1, 2)) - 0.5_wp*(vel_grad_L(2, 1) + vel_grad_R(2, 1)) - flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, l) - 0.5_wp*(vel_grad_L(1, 2)*vel_L(1) + vel_grad_R(1, 2)*vel_R(1)) - 0.5_wp*(vel_grad_L(2, 1)*vel_L(1) + vel_grad_R(2, 1)*vel_R(1)) + flux_src_vf(momxb + 1)%sf(j, k, l) = flux_src_vf(momxb + 1)%sf(j, k, & + & l) - (-2._wp/3._wp)*0.5_wp*(vel_grad_L(1, 1) + vel_grad_R(1, 1)) + flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, & + & l) - (-2._wp/3._wp)*0.5_wp*(vel_grad_L(1, 1)*vel_L(2) + vel_grad_R(1, 1)*vel_R(2)) + + flux_src_vf(momxb + 1)%sf(j, k, l) = flux_src_vf(momxb + 1)%sf(j, k, & + & l) - (4._wp/3._wp)*0.5_wp*(vel_grad_L(2, 2) + vel_grad_R(2, 2)) + flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, & + & l) - (4._wp/3._wp)*0.5_wp*(vel_grad_L(2, 2)*vel_L(2) + vel_grad_R(2, 2)*vel_R(2)) + + flux_src_vf(momxb)%sf(j, k, l) = flux_src_vf(momxb)%sf(j, k, l) - 0.5_wp*(vel_grad_L(1, & + & 2) + vel_grad_R(1, 2)) - 0.5_wp*(vel_grad_L(2, 1) + vel_grad_R(2, 1)) + flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, l) - 0.5_wp*(vel_grad_L(1, & + & 2)*vel_L(1) + vel_grad_R(1, 2)*vel_R(1)) - 0.5_wp*(vel_grad_L(2, & + & 1)*vel_L(1) + vel_grad_R(2, 1)*vel_R(1)) #:if not MFC_CASE_OPTIMIZATION or num_dims > 2 if (num_dims > 2) then - flux_src_vf(momxb + 1)%sf(j, k, l) = flux_src_vf(momxb + 1)%sf(j, k, l) - (-2._wp/3._wp)*0.5_wp*(vel_grad_L(3, 3) + vel_grad_R(3, 3)) - flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, l) - (-2._wp/3._wp)*0.5_wp*(vel_grad_L(3, 3)*vel_L(2) + vel_grad_R(3, 3)*vel_R(2)) - - flux_src_vf(momxb + 2)%sf(j, k, l) = flux_src_vf(momxb + 2)%sf(j, k, l) - 0.5_wp*(vel_grad_L(2, 3) + vel_grad_R(2, 3)) - 0.5_wp*(vel_grad_L(3, 2) + vel_grad_R(3, 2)) - flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, l) - 0.5_wp*(vel_grad_L(2, 3)*vel_L(3) + vel_grad_R(2, 3)*vel_R(3)) - 0.5_wp*(vel_grad_L(3, 2)*vel_L(3) + vel_grad_R(3, 2)*vel_R(3)) + flux_src_vf(momxb + 1)%sf(j, k, l) = flux_src_vf(momxb + 1)%sf(j, k, & + & l) - (-2._wp/3._wp)*0.5_wp*(vel_grad_L(3, 3) + vel_grad_R(3, 3)) + flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, & + & l) - (-2._wp/3._wp)*0.5_wp*(vel_grad_L(3, 3)*vel_L(2) + vel_grad_R(3, & + & 3)*vel_R(2)) + + flux_src_vf(momxb + 2)%sf(j, k, l) = flux_src_vf(momxb + 2)%sf(j, k, & + & l) - 0.5_wp*(vel_grad_L(2, 3) + vel_grad_R(2, & + & 3)) - 0.5_wp*(vel_grad_L(3, 2) + vel_grad_R(3, 2)) + flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, & + & l) - 0.5_wp*(vel_grad_L(2, 3)*vel_L(3) + vel_grad_R(2, & + & 3)*vel_R(3)) - 0.5_wp*(vel_grad_L(3, 2)*vel_L(3) + vel_grad_R(3, & + & 2)*vel_R(3)) end if #:endif #:endif else #:if not MFC_CASE_OPTIMIZATION or num_dims > 2 - flux_src_vf(momxb + 2)%sf(j, k, l) = flux_src_vf(momxb + 2)%sf(j, k, l) - (-2._wp/3._wp)*0.5_wp*(vel_grad_L(1, 1) + vel_grad_R(1, 1)) - flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, l) - (-2._wp/3._wp)*0.5_wp*(vel_grad_L(1, 1)*vel_L(3) + vel_grad_R(1, 1)*vel_R(3)) - - flux_src_vf(momxb + 2)%sf(j, k, l) = flux_src_vf(momxb + 2)%sf(j, k, l) - (-2._wp/3._wp)*0.5_wp*(vel_grad_L(2, 2) + vel_grad_R(2, 2)) - flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, l) - (-2._wp/3._wp)*0.5_wp*(vel_grad_L(2, 2)*vel_L(3) + vel_grad_R(2, 2)*vel_R(3)) - - flux_src_vf(momxb)%sf(j, k, l) = flux_src_vf(momxb)%sf(j, k, l) - 0.5_wp*(vel_grad_L(1, 3) + vel_grad_R(1, 3)) - 0.5_wp*(vel_grad_L(3, 1) + vel_grad_R(3, 1)) - flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, l) - 0.5_wp*(vel_grad_L(1, 3)*vel_L(1) + vel_grad_R(1, 3)*vel_R(1)) - 0.5_wp*(vel_grad_L(3, 1)*vel_L(1) + vel_grad_R(3, 1)*vel_R(1)) - - flux_src_vf(momxb + 2)%sf(j, k, l) = flux_src_vf(momxb + 2)%sf(j, k, l) - (4._wp/3._wp)*0.5_wp*(vel_grad_L(3, 3) + vel_grad_R(3, 3)) - flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, l) - (4._wp/3._wp)*0.5_wp*(vel_grad_L(3, 3)*vel_L(3) + vel_grad_R(3, 3)*vel_R(3)) - - flux_src_vf(momxb + 1)%sf(j, k, l) = flux_src_vf(momxb + 1)%sf(j, k, l) - 0.5_wp*(vel_grad_L(2, 3) + vel_grad_R(2, 3)) - 0.5_wp*(vel_grad_L(3, 2) + vel_grad_R(3, 2)) - flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, l) - 0.5_wp*(vel_grad_L(2, 3)*vel_L(2) + vel_grad_R(2, 3)*vel_R(2)) - 0.5_wp*(vel_grad_L(3, 2)*vel_L(2) + vel_grad_R(3, 2)*vel_R(2)) + flux_src_vf(momxb + 2)%sf(j, k, l) = flux_src_vf(momxb + 2)%sf(j, k, & + & l) - (-2._wp/3._wp)*0.5_wp*(vel_grad_L(1, 1) + vel_grad_R(1, 1)) + flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, & + & l) - (-2._wp/3._wp)*0.5_wp*(vel_grad_L(1, 1)*vel_L(3) + vel_grad_R(1, 1)*vel_R(3)) + + flux_src_vf(momxb + 2)%sf(j, k, l) = flux_src_vf(momxb + 2)%sf(j, k, & + & l) - (-2._wp/3._wp)*0.5_wp*(vel_grad_L(2, 2) + vel_grad_R(2, 2)) + flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, & + & l) - (-2._wp/3._wp)*0.5_wp*(vel_grad_L(2, 2)*vel_L(3) + vel_grad_R(2, 2)*vel_R(3)) + + flux_src_vf(momxb)%sf(j, k, l) = flux_src_vf(momxb)%sf(j, k, l) - 0.5_wp*(vel_grad_L(1, & + & 3) + vel_grad_R(1, 3)) - 0.5_wp*(vel_grad_L(3, 1) + vel_grad_R(3, 1)) + flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, l) - 0.5_wp*(vel_grad_L(1, & + & 3)*vel_L(1) + vel_grad_R(1, 3)*vel_R(1)) - 0.5_wp*(vel_grad_L(3, & + & 1)*vel_L(1) + vel_grad_R(3, 1)*vel_R(1)) + + flux_src_vf(momxb + 2)%sf(j, k, l) = flux_src_vf(momxb + 2)%sf(j, k, & + & l) - (4._wp/3._wp)*0.5_wp*(vel_grad_L(3, 3) + vel_grad_R(3, 3)) + flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, & + & l) - (4._wp/3._wp)*0.5_wp*(vel_grad_L(3, 3)*vel_L(3) + vel_grad_R(3, 3)*vel_R(3)) + + flux_src_vf(momxb + 1)%sf(j, k, l) = flux_src_vf(momxb + 1)%sf(j, k, & + & l) - 0.5_wp*(vel_grad_L(2, 3) + vel_grad_R(2, 3)) - 0.5_wp*(vel_grad_L(3, & + & 2) + vel_grad_R(3, 2)) + flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, l) - 0.5_wp*(vel_grad_L(2, & + & 3)*vel_L(2) + vel_grad_R(2, 3)*vel_R(2)) - 0.5_wp*(vel_grad_L(3, & + & 2)*vel_L(2) + vel_grad_R(3, 2)*vel_R(2)) #:endif end if end if if (bulk_stress) then - $:GPU_LOOP(parallelism='[seq]') do i = 1, num_dims vel_grad_L(i, 1) = (dqL_prim_dx_vf(momxb + i - 1)%sf(j, k, l)/Re_L(2)) - vel_grad_R(i, 1) = (dqR_prim_dx_vf(momxb + i - 1)%sf(idx_right_phys(1), idx_right_phys(2), idx_right_phys(3))/Re_R(2)) + vel_grad_R(i, 1) = (dqR_prim_dx_vf(momxb + i - 1)%sf(idx_right_phys(1), idx_right_phys(2), & + & idx_right_phys(3))/Re_R(2)) #:if not MFC_CASE_OPTIMIZATION or num_dims > 1 if (num_dims > 1) then vel_grad_L(i, 2) = (dqL_prim_dy_vf(momxb + i - 1)%sf(j, k, l)/Re_L(2)) - vel_grad_R(i, 2) = (dqR_prim_dy_vf(momxb + i - 1)%sf(idx_right_phys(1), idx_right_phys(2), idx_right_phys(3))/Re_R(2)) + vel_grad_R(i, 2) = (dqR_prim_dy_vf(momxb + i - 1)%sf(idx_right_phys(1), & + & idx_right_phys(2), idx_right_phys(3))/Re_R(2)) end if #:endif #:if not MFC_CASE_OPTIMIZATION or num_dims > 2 if (num_dims > 2) then vel_grad_L(i, 3) = (dqL_prim_dz_vf(momxb + i - 1)%sf(j, k, l)/Re_L(2)) - vel_grad_R(i, 3) = (dqR_prim_dz_vf(momxb + i - 1)%sf(idx_right_phys(1), idx_right_phys(2), idx_right_phys(3))/Re_R(2)) + vel_grad_R(i, 3) = (dqR_prim_dz_vf(momxb + i - 1)%sf(idx_right_phys(1), & + & idx_right_phys(2), idx_right_phys(3))/Re_R(2)) end if #:endif end do if (norm_dir == 1) then - flux_src_vf(momxb)%sf(j, k, l) = flux_src_vf(momxb)%sf(j, k, l) - 0.5_wp*(vel_grad_L(1, 1) + vel_grad_R(1, 1)) - flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, l) - 0.5_wp*(vel_grad_L(1, 1)*vel_L(1) + vel_grad_R(1, 1)*vel_R(1)) + flux_src_vf(momxb)%sf(j, k, l) = flux_src_vf(momxb)%sf(j, k, l) - 0.5_wp*(vel_grad_L(1, & + & 1) + vel_grad_R(1, 1)) + flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, l) - 0.5_wp*(vel_grad_L(1, & + & 1)*vel_L(1) + vel_grad_R(1, 1)*vel_R(1)) #:if not MFC_CASE_OPTIMIZATION or num_dims > 1 if (num_dims > 1) then - flux_src_vf(momxb)%sf(j, k, l) = flux_src_vf(momxb)%sf(j, k, l) - 0.5_wp*(vel_grad_L(2, 2) + vel_grad_R(2, 2)) - flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, l) - 0.5_wp*(vel_grad_L(2, 2)*vel_L(1) + vel_grad_R(2, 2)*vel_R(1)) + flux_src_vf(momxb)%sf(j, k, l) = flux_src_vf(momxb)%sf(j, k, l) - 0.5_wp*(vel_grad_L(2, & + & 2) + vel_grad_R(2, 2)) + flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, l) - 0.5_wp*(vel_grad_L(2, & + & 2)*vel_L(1) + vel_grad_R(2, 2)*vel_R(1)) #:if not MFC_CASE_OPTIMIZATION or num_dims > 2 if (num_dims > 2) then - flux_src_vf(momxb)%sf(j, k, l) = flux_src_vf(momxb)%sf(j, k, l) - 0.5_wp*(vel_grad_L(3, 3) + vel_grad_R(3, 3)) - flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, l) - 0.5_wp*(vel_grad_L(3, 3)*vel_L(1) + vel_grad_R(3, 3)*vel_R(1)) + flux_src_vf(momxb)%sf(j, k, l) = flux_src_vf(momxb)%sf(j, k, & + & l) - 0.5_wp*(vel_grad_L(3, 3) + vel_grad_R(3, 3)) + flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, & + & l) - 0.5_wp*(vel_grad_L(3, 3)*vel_L(1) + vel_grad_R(3, 3)*vel_R(1)) end if #:endif end if #:endif - else if (norm_dir == 2) then #:if not MFC_CASE_OPTIMIZATION or num_dims > 1 - flux_src_vf(momxb + 1)%sf(j, k, l) = flux_src_vf(momxb + 1)%sf(j, k, l) - 0.5_wp*(vel_grad_L(1, 1) + vel_grad_R(1, 1)) - flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, l) - 0.5_wp*(vel_grad_L(1, 1)*vel_L(2) + vel_grad_R(1, 1)*vel_R(2)) + flux_src_vf(momxb + 1)%sf(j, k, l) = flux_src_vf(momxb + 1)%sf(j, k, & + & l) - 0.5_wp*(vel_grad_L(1, 1) + vel_grad_R(1, 1)) + flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, l) - 0.5_wp*(vel_grad_L(1, & + & 1)*vel_L(2) + vel_grad_R(1, 1)*vel_R(2)) - flux_src_vf(momxb + 1)%sf(j, k, l) = flux_src_vf(momxb + 1)%sf(j, k, l) - 0.5_wp*(vel_grad_L(2, 2) + vel_grad_R(2, 2)) - flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, l) - 0.5_wp*(vel_grad_L(2, 2)*vel_L(2) + vel_grad_R(2, 2)*vel_R(2)) + flux_src_vf(momxb + 1)%sf(j, k, l) = flux_src_vf(momxb + 1)%sf(j, k, & + & l) - 0.5_wp*(vel_grad_L(2, 2) + vel_grad_R(2, 2)) + flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, l) - 0.5_wp*(vel_grad_L(2, & + & 2)*vel_L(2) + vel_grad_R(2, 2)*vel_R(2)) #:if not MFC_CASE_OPTIMIZATION or num_dims > 2 if (num_dims > 2) then - flux_src_vf(momxb + 1)%sf(j, k, l) = flux_src_vf(momxb + 1)%sf(j, k, l) - 0.5_wp*(vel_grad_L(3, 3) + vel_grad_R(3, 3)) - flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, l) - 0.5_wp*(vel_grad_L(3, 3)*vel_L(2) + vel_grad_R(3, 3)*vel_R(2)) + flux_src_vf(momxb + 1)%sf(j, k, l) = flux_src_vf(momxb + 1)%sf(j, k, & + & l) - 0.5_wp*(vel_grad_L(3, 3) + vel_grad_R(3, 3)) + flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, & + & l) - 0.5_wp*(vel_grad_L(3, 3)*vel_L(2) + vel_grad_R(3, 3)*vel_R(2)) end if #:endif #:endif else #:if not MFC_CASE_OPTIMIZATION or num_dims > 2 - flux_src_vf(momxb + 2)%sf(j, k, l) = flux_src_vf(momxb + 2)%sf(j, k, l) - 0.5_wp*(vel_grad_L(1, 1) + vel_grad_R(1, 1)) - flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, l) - 0.5_wp*(vel_grad_L(1, 1)*vel_L(3) + vel_grad_R(1, 1)*vel_R(3)) - - flux_src_vf(momxb + 2)%sf(j, k, l) = flux_src_vf(momxb + 2)%sf(j, k, l) - 0.5_wp*(vel_grad_L(2, 2) + vel_grad_R(2, 2)) - flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, l) - 0.5_wp*(vel_grad_L(2, 2)*vel_L(3) + vel_grad_R(2, 2)*vel_R(3)) - - flux_src_vf(momxb + 2)%sf(j, k, l) = flux_src_vf(momxb + 2)%sf(j, k, l) - 0.5_wp*(vel_grad_L(3, 3) + vel_grad_R(3, 3)) - flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, l) - 0.5_wp*(vel_grad_L(3, 3)*vel_L(3) + vel_grad_R(3, 3)*vel_R(3)) + flux_src_vf(momxb + 2)%sf(j, k, l) = flux_src_vf(momxb + 2)%sf(j, k, & + & l) - 0.5_wp*(vel_grad_L(1, 1) + vel_grad_R(1, 1)) + flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, l) - 0.5_wp*(vel_grad_L(1, & + & 1)*vel_L(3) + vel_grad_R(1, 1)*vel_R(3)) + + flux_src_vf(momxb + 2)%sf(j, k, l) = flux_src_vf(momxb + 2)%sf(j, k, & + & l) - 0.5_wp*(vel_grad_L(2, 2) + vel_grad_R(2, 2)) + flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, l) - 0.5_wp*(vel_grad_L(2, & + & 2)*vel_L(3) + vel_grad_R(2, 2)*vel_R(3)) + + flux_src_vf(momxb + 2)%sf(j, k, l) = flux_src_vf(momxb + 2)%sf(j, k, & + & l) - 0.5_wp*(vel_grad_L(3, 3) + vel_grad_R(3, 3)) + flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, l) - 0.5_wp*(vel_grad_L(3, & + & 3)*vel_L(3) + vel_grad_R(3, 3)*vel_R(3)) #:endif end if - end if end do end do end do $:END_GPU_PARALLEL_LOOP() - end if - call s_finalize_riemann_solver(flux_vf, flux_src_vf, & - flux_gsrc_vf, & - norm_dir) + call s_finalize_riemann_solver(flux_vf, flux_src_vf, flux_gsrc_vf, norm_dir) end subroutine s_lf_riemann_solver - !> This procedure is the implementation of the Harten, Lax, - !! van Leer, and contact (HLLC) approximate Riemann solver, - !! see Toro (1999) and Johnsen (2007). The viscous and the - !! surface tension effects have been included by modifying - !! the exact Riemann solver of Perigaud and Saurel (2005). - !! @param qL_prim_rsx_vf Left WENO-reconstructed cell-boundary values (x-dir) - !! @param qL_prim_rsy_vf Left WENO-reconstructed cell-boundary values (y-dir) - !! @param qL_prim_rsz_vf Left WENO-reconstructed cell-boundary values (z-dir) - !! @param dqL_prim_dx_vf The left WENO-reconstructed cell-boundary values of the - !! first-order x-dir spatial derivatives - !! @param dqL_prim_dy_vf The left WENO-reconstructed cell-boundary values of the - !! first-order y-dir spatial derivatives - !! @param dqL_prim_dz_vf The left WENO-reconstructed cell-boundary values of the - !! first-order z-dir spatial derivatives - !! @param qL_prim_vf The left WENO-reconstructed cell-boundary values of the - !! cell-average primitive variables - !! @param qR_prim_rsx_vf Right WENO-reconstructed cell-boundary values (x-dir) - !! @param qR_prim_rsy_vf Right WENO-reconstructed cell-boundary values (y-dir) - !! @param qR_prim_rsz_vf Right WENO-reconstructed cell-boundary values (z-dir) - !! @param dqR_prim_dx_vf The right WENO-reconstructed cell-boundary values of the - !! first-order x-dir spatial derivatives - !! @param dqR_prim_dy_vf The right WENO-reconstructed cell-boundary values of the - !! first-order y-dir spatial derivatives - !! @param dqR_prim_dz_vf The right WENO-reconstructed cell-boundary values of the - !! first-order z-dir spatial derivatives - !! @param qR_prim_vf The right WENO-reconstructed cell-boundary values of the - !! cell-average primitive variables - !! @param q_prim_vf Cell-averaged primitive variables - !! @param flux_vf Intra-cell fluxes - !! @param flux_src_vf Intra-cell fluxes sources - !! @param flux_gsrc_vf Intra-cell geometric fluxes sources - !! @param norm_dir Dir. splitting direction - !! @param ix Index bounds in the x-dir - !! @param iy Index bounds in the y-dir - !! @param iz Index bounds in the z-dir - subroutine s_hllc_riemann_solver(qL_prim_rsx_vf, qL_prim_rsy_vf, qL_prim_rsz_vf, dqL_prim_dx_vf, & - dqL_prim_dy_vf, & - dqL_prim_dz_vf, & - qL_prim_vf, & - qR_prim_rsx_vf, qR_prim_rsy_vf, qR_prim_rsz_vf, dqR_prim_dx_vf, & - dqR_prim_dy_vf, & - dqR_prim_dz_vf, & - qR_prim_vf, & - q_prim_vf, & - flux_vf, flux_src_vf, & - flux_gsrc_vf, & - norm_dir, ix, iy, iz) - - real(wp), dimension(idwbuff(1)%beg:, idwbuff(2)%beg:, idwbuff(3)%beg:, 1:), intent(inout) :: qL_prim_rsx_vf, qL_prim_rsy_vf, qL_prim_rsz_vf, qR_prim_rsx_vf, qR_prim_rsy_vf, qR_prim_rsz_vf - type(scalar_field), dimension(sys_size), intent(in) :: q_prim_vf + !> This procedure is the implementation of the Harten, Lax, van Leer, and contact (HLLC) approximate Riemann solver, see Toro + !! (1999) and Johnsen (2007). The viscous and the surface tension effects have been included by modifying the exact Riemann + !! solver of Perigaud and Saurel (2005). + !! @param qL_prim_rsx_vf Left WENO-reconstructed cell-boundary values (x-dir) + !! @param qL_prim_rsy_vf Left WENO-reconstructed cell-boundary values (y-dir) + !! @param qL_prim_rsz_vf Left WENO-reconstructed cell-boundary values (z-dir) + !! @param dqL_prim_dx_vf The left WENO-reconstructed cell-boundary values of the first-order x-dir spatial derivatives + !! @param dqL_prim_dy_vf The left WENO-reconstructed cell-boundary values of the first-order y-dir spatial derivatives + !! @param dqL_prim_dz_vf The left WENO-reconstructed cell-boundary values of the first-order z-dir spatial derivatives + !! @param qL_prim_vf The left WENO-reconstructed cell-boundary values of the cell-average primitive variables + !! @param qR_prim_rsx_vf Right WENO-reconstructed cell-boundary values (x-dir) + !! @param qR_prim_rsy_vf Right WENO-reconstructed cell-boundary values (y-dir) + !! @param qR_prim_rsz_vf Right WENO-reconstructed cell-boundary values (z-dir) + !! @param dqR_prim_dx_vf The right WENO-reconstructed cell-boundary values of the first-order x-dir spatial derivatives + !! @param dqR_prim_dy_vf The right WENO-reconstructed cell-boundary values of the first-order y-dir spatial derivatives + !! @param dqR_prim_dz_vf The right WENO-reconstructed cell-boundary values of the first-order z-dir spatial derivatives + !! @param qR_prim_vf The right WENO-reconstructed cell-boundary values of the cell-average primitive variables + !! @param q_prim_vf Cell-averaged primitive variables + !! @param flux_vf Intra-cell fluxes + !! @param flux_src_vf Intra-cell fluxes sources + !! @param flux_gsrc_vf Intra-cell geometric fluxes sources + !! @param norm_dir Dir. splitting direction + !! @param ix Index bounds in the x-dir + !! @param iy Index bounds in the y-dir + !! @param iz Index bounds in the z-dir + subroutine s_hllc_riemann_solver(qL_prim_rsx_vf, qL_prim_rsy_vf, qL_prim_rsz_vf, dqL_prim_dx_vf, dqL_prim_dy_vf, & + & dqL_prim_dz_vf, qL_prim_vf, qR_prim_rsx_vf, qR_prim_rsy_vf, qR_prim_rsz_vf, & + & dqR_prim_dx_vf, dqR_prim_dy_vf, dqR_prim_dz_vf, qR_prim_vf, q_prim_vf, flux_vf, & + & flux_src_vf, flux_gsrc_vf, norm_dir, ix, iy, iz) + + real(wp), dimension(idwbuff(1)%beg:,idwbuff(2)%beg:,idwbuff(3)%beg:,1:), intent(inout) :: qL_prim_rsx_vf, qL_prim_rsy_vf, & + & qL_prim_rsz_vf, qR_prim_rsx_vf, qR_prim_rsy_vf, qR_prim_rsz_vf + type(scalar_field), dimension(sys_size), intent(in) :: q_prim_vf type(scalar_field), allocatable, dimension(:), intent(inout) :: qL_prim_vf, qR_prim_vf - - type(scalar_field), & - allocatable, dimension(:), & - intent(inout) :: dqL_prim_dx_vf, dqR_prim_dx_vf, & - dqL_prim_dy_vf, dqR_prim_dy_vf, & - dqL_prim_dz_vf, dqR_prim_dz_vf + type(scalar_field), allocatable, dimension(:), intent(inout) :: dqL_prim_dx_vf, dqR_prim_dx_vf, dqL_prim_dy_vf, & + & dqR_prim_dy_vf, dqL_prim_dz_vf, dqR_prim_dz_vf ! Intercell fluxes - type(scalar_field), & - dimension(sys_size), & - intent(inout) :: flux_vf, flux_src_vf, flux_gsrc_vf - - integer, intent(in) :: norm_dir - type(int_bounds_info), intent(in) :: ix, iy, iz + type(scalar_field), dimension(sys_size), intent(inout) :: flux_vf, flux_src_vf, flux_gsrc_vf + integer, intent(in) :: norm_dir + type(int_bounds_info), intent(in) :: ix, iy, iz #:if not MFC_CASE_OPTIMIZATION and USING_AMD real(wp), dimension(3) :: alpha_rho_L, alpha_rho_R @@ -1989,7 +1757,7 @@ contains #:else real(wp), dimension(num_fluids) :: alpha_rho_L, alpha_rho_R real(wp), dimension(num_fluids) :: alpha_L, alpha_R - real(wp), dimension(num_dims) :: vel_L, vel_R + real(wp), dimension(num_dims) :: vel_L, vel_R #:endif real(wp) :: rho_L, rho_R @@ -2003,30 +1771,28 @@ contains real(wp), dimension(num_species) :: Ys_L, Ys_R, Xs_L, Xs_R, Gamma_iL, Gamma_iR, Cp_iL, Cp_iR real(wp), dimension(num_species) :: Yi_avg, Phi_avg, h_iL, h_iR, h_avg_2 #:endif - real(wp) :: Cp_avg, Cv_avg, T_avg, c_sum_Yi_Phi, eps - real(wp) :: T_L, T_R - real(wp) :: MW_L, MW_R - real(wp) :: R_gas_L, R_gas_R - real(wp) :: Cp_L, Cp_R - real(wp) :: Cv_L, Cv_R - real(wp) :: Gamm_L, Gamm_R - real(wp) :: Y_L, Y_R - real(wp) :: gamma_L, gamma_R - real(wp) :: pi_inf_L, pi_inf_R - real(wp) :: qv_L, qv_R - real(wp) :: c_L, c_R + real(wp) :: Cp_avg, Cv_avg, T_avg, c_sum_Yi_Phi, eps + real(wp) :: T_L, T_R + real(wp) :: MW_L, MW_R + real(wp) :: R_gas_L, R_gas_R + real(wp) :: Cp_L, Cp_R + real(wp) :: Cv_L, Cv_R + real(wp) :: Gamm_L, Gamm_R + real(wp) :: Y_L, Y_R + real(wp) :: gamma_L, gamma_R + real(wp) :: pi_inf_L, pi_inf_R + real(wp) :: qv_L, qv_R + real(wp) :: c_L, c_R real(wp), dimension(2) :: Re_L, Re_R - - real(wp) :: rho_avg - real(wp) :: H_avg - real(wp) :: gamma_avg - real(wp) :: qv_avg - real(wp) :: c_avg - - real(wp) :: s_L, s_R, s_M, s_P, s_S - real(wp) :: xi_L, xi_R !< Left and right wave speeds functions - real(wp) :: xi_M, xi_P - real(wp) :: xi_MP, xi_PP + real(wp) :: rho_avg + real(wp) :: H_avg + real(wp) :: gamma_avg + real(wp) :: qv_avg + real(wp) :: c_avg + real(wp) :: s_L, s_R, s_M, s_P, s_S + real(wp) :: xi_L, xi_R !< Left and right wave speeds functions + real(wp) :: xi_M, xi_P + real(wp) :: xi_MP, xi_PP #:if not MFC_CASE_OPTIMIZATION and USING_AMD real(wp), dimension(3) :: R0_L, R0_R real(wp), dimension(3) :: V0_L, V0_R @@ -2039,13 +1805,11 @@ contains real(wp), dimension(nb) :: pbw_L, pbw_R #:endif - real(wp) :: alpha_L_sum, alpha_R_sum, nbub_L, nbub_R - real(wp) :: ptilde_L, ptilde_R - - real(wp) :: PbwR3Lbar, PbwR3Rbar - real(wp) :: R3Lbar, R3Rbar - real(wp) :: R3V2Lbar, R3V2Rbar - + real(wp) :: alpha_L_sum, alpha_R_sum, nbub_L, nbub_R + real(wp) :: ptilde_L, ptilde_R + real(wp) :: PbwR3Lbar, PbwR3Rbar + real(wp) :: R3Lbar, R3Rbar + real(wp) :: R3V2Lbar, R3V2Rbar real(wp), dimension(6) :: tau_e_L, tau_e_R #:if not MFC_CASE_OPTIMIZATION and USING_AMD real(wp), dimension(3) :: xi_field_L, xi_field_R @@ -2053,46 +1817,42 @@ contains real(wp), dimension(num_dims) :: xi_field_L, xi_field_R #:endif real(wp) :: G_L, G_R - real(wp) :: vel_L_rms, vel_R_rms, vel_avg_rms real(wp) :: vel_L_tmp, vel_R_tmp real(wp) :: rho_Star, E_Star, p_Star, p_K_Star, vel_K_star real(wp) :: pres_SL, pres_SR, Ms_L, Ms_R real(wp) :: flux_ene_e - real(wp) :: zcoef, pcorr !< low Mach number correction + real(wp) :: zcoef, pcorr !< low Mach number correction + integer :: Re_max, i, j, k, l, q !< Generic loop iterators - integer :: Re_max, i, j, k, l, q !< Generic loop iterators + ! Populating the buffers of the left and right Riemann problem states variables, based on the choice of boundary conditions - ! Populating the buffers of the left and right Riemann problem - ! states variables, based on the choice of boundary conditions - - call s_populate_riemann_states_variables_buffers( & - qL_prim_rsx_vf, qL_prim_rsy_vf, qL_prim_rsz_vf, dqL_prim_dx_vf, & - dqL_prim_dy_vf, & - dqL_prim_dz_vf, & - qR_prim_rsx_vf, qR_prim_rsy_vf, qR_prim_rsz_vf, dqR_prim_dx_vf, & - dqR_prim_dy_vf, & - dqR_prim_dz_vf, & - norm_dir, ix, iy, iz) + call s_populate_riemann_states_variables_buffers(qL_prim_rsx_vf, qL_prim_rsy_vf, qL_prim_rsz_vf, dqL_prim_dx_vf, & + & dqL_prim_dy_vf, dqL_prim_dz_vf, qR_prim_rsx_vf, qR_prim_rsy_vf, qR_prim_rsz_vf, dqR_prim_dx_vf, dqR_prim_dy_vf, & + & dqR_prim_dz_vf, norm_dir, ix, iy, iz) ! Reshaping inputted data based on dimensional splitting direction - call s_initialize_riemann_solver( & - flux_src_vf, & - norm_dir) + call s_initialize_riemann_solver(flux_src_vf, norm_dir) #:for NORM_DIR, XYZ in [(1, 'x'), (2, 'y'), (3, 'z')] - if (norm_dir == ${NORM_DIR}$) then - ! 6-EQUATION MODEL WITH HLLC if (model_eqns == 3) then - !ME3 - $:GPU_PARALLEL_LOOP(collapse=3, private='[i,j,k,l, q, vel_L, vel_R, Re_L, Re_R, alpha_L, alpha_R, Ys_L, Ys_R, Xs_L, Xs_R, Gamma_iL, Gamma_iR, Cp_iL, Cp_iR, Yi_avg, Phi_avg, h_iL, h_iR, h_avg_2, tau_e_L, tau_e_R, flux_ene_e, xi_field_L, xi_field_R, pcorr, zcoef, rho_L, rho_R, pres_L, pres_R, E_L, E_R, H_L, H_R, Cp_avg, Cv_avg, T_avg, eps, c_sum_Yi_Phi, T_L, T_R, Y_L, Y_R, MW_L, MW_R, R_gas_L, R_gas_R, Cp_L, Cp_R, Cv_L, Cv_R, Gamm_L, Gamm_R, gamma_L, gamma_R, pi_inf_L, pi_inf_R, qv_L, qv_R, qv_avg, c_L, c_R, G_L, G_R, rho_avg, H_avg, c_avg, gamma_avg, ptilde_L, ptilde_R, vel_L_rms, vel_R_rms, vel_avg_rms, vel_L_tmp, vel_R_tmp, Ms_L, Ms_R, pres_SL, pres_SR, alpha_L_sum, alpha_R_sum, rho_Star, E_Star, p_Star, p_K_Star, vel_K_star, s_L, s_R, s_M, s_P, s_S, xi_M, xi_P, xi_L, xi_R, xi_MP, xi_PP]') + ! ME3 + $:GPU_PARALLEL_LOOP(collapse=3, private='[i, j, k, l, q, vel_L, vel_R, Re_L, Re_R, alpha_L, alpha_R, Ys_L, & + & Ys_R, Xs_L, Xs_R, Gamma_iL, Gamma_iR, Cp_iL, Cp_iR, Yi_avg, Phi_avg, h_iL, h_iR, & + & h_avg_2, tau_e_L, tau_e_R, flux_ene_e, xi_field_L, xi_field_R, pcorr, zcoef, rho_L, & + & rho_R, pres_L, pres_R, E_L, E_R, H_L, H_R, Cp_avg, Cv_avg, T_avg, eps, c_sum_Yi_Phi, & + & T_L, T_R, Y_L, Y_R, MW_L, MW_R, R_gas_L, R_gas_R, Cp_L, Cp_R, Cv_L, Cv_R, Gamm_L, & + & Gamm_R, gamma_L, gamma_R, pi_inf_L, pi_inf_R, qv_L, qv_R, qv_avg, c_L, c_R, G_L, G_R, & + & rho_avg, H_avg, c_avg, gamma_avg, ptilde_L, ptilde_R, vel_L_rms, vel_R_rms, & + & vel_avg_rms, vel_L_tmp, vel_R_tmp, Ms_L, Ms_R, pres_SL, pres_SR, alpha_L_sum, & + & alpha_R_sum, rho_Star, E_Star, p_Star, p_K_Star, vel_K_star, s_L, s_R, s_M, s_P, s_S, & + & xi_M, xi_P, xi_L, xi_R, xi_MP, xi_PP]') do l = is3%beg, is3%end do k = is2%beg, is2%end do j = is1%beg, is1%end - vel_L_rms = 0._wp; vel_R_rms = 0._wp rho_L = 0._wp; rho_R = 0._wp gamma_L = 0._wp; gamma_R = 0._wp @@ -2128,21 +1888,25 @@ contains $:GPU_LOOP(parallelism='[seq]') do i = 1, num_fluids qL_prim_rs${XYZ}$_vf(j, k, l, i) = max(0._wp, qL_prim_rs${XYZ}$_vf(j, k, l, i)) - qL_prim_rs${XYZ}$_vf(j, k, l, E_idx + i) = min(max(0._wp, qL_prim_rs${XYZ}$_vf(j, k, l, E_idx + i)), 1._wp) + qL_prim_rs${XYZ}$_vf(j, k, l, E_idx + i) = min(max(0._wp, qL_prim_rs${XYZ}$_vf(j, k, l, & + & E_idx + i)), 1._wp) alpha_L_sum = alpha_L_sum + qL_prim_rs${XYZ}$_vf(j, k, l, E_idx + i) end do $:GPU_LOOP(parallelism='[seq]') do i = 1, num_fluids qR_prim_rs${XYZ}$_vf(j + 1, k, l, i) = max(0._wp, qR_prim_rs${XYZ}$_vf(j + 1, k, l, i)) - qR_prim_rs${XYZ}$_vf(j + 1, k, l, E_idx + i) = min(max(0._wp, qR_prim_rs${XYZ}$_vf(j + 1, k, l, E_idx + i)), 1._wp) + qR_prim_rs${XYZ}$_vf(j + 1, k, l, E_idx + i) = min(max(0._wp, qR_prim_rs${XYZ}$_vf(j + 1, & + & k, l, E_idx + i)), 1._wp) alpha_R_sum = alpha_R_sum + qR_prim_rs${XYZ}$_vf(j + 1, k, l, E_idx + i) end do $:GPU_LOOP(parallelism='[seq]') do i = 1, num_fluids - qL_prim_rs${XYZ}$_vf(j, k, l, E_idx + i) = qL_prim_rs${XYZ}$_vf(j, k, l, E_idx + i)/max(alpha_L_sum, sgm_eps) - qR_prim_rs${XYZ}$_vf(j + 1, k, l, E_idx + i) = qR_prim_rs${XYZ}$_vf(j + 1, k, l, E_idx + i)/max(alpha_R_sum, sgm_eps) + qL_prim_rs${XYZ}$_vf(j, k, l, E_idx + i) = qL_prim_rs${XYZ}$_vf(j, k, l, & + & E_idx + i)/max(alpha_L_sum, sgm_eps) + qR_prim_rs${XYZ}$_vf(j + 1, k, l, E_idx + i) = qR_prim_rs${XYZ}$_vf(j + 1, k, l, & + & E_idx + i)/max(alpha_R_sum, sgm_eps) end do end if @@ -2171,10 +1935,8 @@ contains if (Re_size(i) > 0) Re_R(i) = 0._wp $:GPU_LOOP(parallelism='[seq]') do q = 1, Re_size(i) - Re_L(i) = qL_prim_rs${XYZ}$_vf(j, k, l, E_idx + Re_idx(i, q))/Res_gs(i, q) & - + Re_L(i) - Re_R(i) = qR_prim_rs${XYZ}$_vf(j + 1, k, l, E_idx + Re_idx(i, q))/Res_gs(i, q) & - + Re_R(i) + Re_L(i) = qL_prim_rs${XYZ}$_vf(j, k, l, E_idx + Re_idx(i, q))/Res_gs(i, q) + Re_L(i) + Re_R(i) = qR_prim_rs${XYZ}$_vf(j + 1, k, l, E_idx + Re_idx(i, q))/Res_gs(i, q) + Re_R(i) end do Re_L(i) = 1._wp/max(Re_L(i), sgm_eps) Re_R(i) = 1._wp/max(Re_R(i), sgm_eps) @@ -2219,7 +1981,7 @@ contains xi_field_L(i) = qL_prim_rs${XYZ}$_vf(j, k, l, xibeg - 1 + i) xi_field_R(i) = qR_prim_rs${XYZ}$_vf(j + 1, k, l, xibeg - 1 + i) end do - G_L = 0._wp; G_R = 0._wp; + G_L = 0._wp; G_R = 0._wp $:GPU_LOOP(parallelism='[seq]') do i = 1, num_fluids ! Mixture left and right shear modulus @@ -2243,16 +2005,16 @@ contains @:compute_average_state() - call s_compute_speed_of_sound(pres_L, rho_L, gamma_L, pi_inf_L, H_L, alpha_L, & - vel_L_rms, 0._wp, c_L, qv_L) + call s_compute_speed_of_sound(pres_L, rho_L, gamma_L, pi_inf_L, H_L, alpha_L, vel_L_rms, 0._wp, & + & c_L, qv_L) - call s_compute_speed_of_sound(pres_R, rho_R, gamma_R, pi_inf_R, H_R, alpha_R, & - vel_R_rms, 0._wp, c_R, qv_R) + call s_compute_speed_of_sound(pres_R, rho_R, gamma_R, pi_inf_R, H_R, alpha_R, vel_R_rms, 0._wp, & + & c_R, qv_R) !> The computation of c_avg does not require all the variables, and therefore the non '_avg' ! variables are placeholders to call the subroutine. - call s_compute_speed_of_sound(pres_R, rho_avg, gamma_avg, pi_inf_R, H_avg, alpha_R, & - vel_avg_rms, 0._wp, c_avg, qv_avg) + call s_compute_speed_of_sound(pres_R, rho_avg, gamma_avg, pi_inf_R, H_avg, alpha_R, vel_avg_rms, & + & 0._wp, c_avg, qv_avg) if (viscous) then $:GPU_LOOP(parallelism='[seq]') @@ -2269,77 +2031,68 @@ contains ! COMPUTING THE DIRECT WAVE SPEEDS if (wave_speeds == 1) then if (elasticity) then - s_L = min(vel_L(dir_idx(1)) - sqrt(c_L*c_L + & - (((4._wp*G_L)/3._wp) + tau_e_L(dir_idx_tau(1)))/rho_L), vel_R(dir_idx(1)) - sqrt(c_R*c_R + & - (((4._wp*G_R)/3._wp) + tau_e_R(dir_idx_tau(1)))/rho_R)) - s_R = max(vel_R(dir_idx(1)) + sqrt(c_R*c_R + & - (((4._wp*G_R)/3._wp) + tau_e_R(dir_idx_tau(1)))/rho_R), vel_L(dir_idx(1)) + sqrt(c_L*c_L + & - (((4._wp*G_L)/3._wp) + tau_e_L(dir_idx_tau(1)))/rho_L)) - s_S = (pres_R - tau_e_R(dir_idx_tau(1)) - pres_L + & - tau_e_L(dir_idx_tau(1)) + rho_L*vel_L(dir_idx(1))*(s_L - vel_L(dir_idx(1))) - & - rho_R*vel_R(dir_idx(1))*(s_R - vel_R(dir_idx(1))))/(rho_L*(s_L - vel_L(dir_idx(1))) - & - rho_R*(s_R - vel_R(dir_idx(1)))) + s_L = min(vel_L(dir_idx(1)) - sqrt(c_L*c_L + (((4._wp*G_L)/3._wp) + tau_e_L(dir_idx_tau(1) & + & ))/rho_L), & + & vel_R(dir_idx(1)) - sqrt(c_R*c_R + (((4._wp*G_R)/3._wp) & + & + tau_e_R(dir_idx_tau(1)))/rho_R)) + s_R = max(vel_R(dir_idx(1)) + sqrt(c_R*c_R + (((4._wp*G_R)/3._wp) + tau_e_R(dir_idx_tau(1) & + & ))/rho_R), & + & vel_L(dir_idx(1)) + sqrt(c_L*c_L + (((4._wp*G_L)/3._wp) & + & + tau_e_L(dir_idx_tau(1)))/rho_L)) + s_S = (pres_R - tau_e_R(dir_idx_tau(1)) - pres_L + tau_e_L(dir_idx_tau(1)) & + & + rho_L*vel_L(dir_idx(1))*(s_L - vel_L(dir_idx(1))) - rho_R*vel_R(dir_idx(1)) & + & *(s_R - vel_R(dir_idx(1))))/(rho_L*(s_L - vel_L(dir_idx(1))) - rho_R*(s_R & + & - vel_R(dir_idx(1)))) else s_L = min(vel_L(dir_idx(1)) - c_L, vel_R(dir_idx(1)) - c_R) s_R = max(vel_R(dir_idx(1)) + c_R, vel_L(dir_idx(1)) + c_L) - s_S = (pres_R - pres_L + rho_L*vel_L(dir_idx(1))* & - (s_L - vel_L(dir_idx(1))) - rho_R*vel_R(dir_idx(1))*(s_R - vel_R(dir_idx(1)))) & - /(rho_L*(s_L - vel_L(dir_idx(1))) - rho_R*(s_R - vel_R(dir_idx(1)))) - + s_S = (pres_R - pres_L + rho_L*vel_L(dir_idx(1))*(s_L - vel_L(dir_idx(1))) & + & - rho_R*vel_R(dir_idx(1))*(s_R - vel_R(dir_idx(1))))/(rho_L*(s_L & + & - vel_L(dir_idx(1))) - rho_R*(s_R - vel_R(dir_idx(1)))) end if - elseif (wave_speeds == 2) then - pres_SL = 5.e-1_wp*(pres_L + pres_R + rho_avg*c_avg* & - (vel_L(dir_idx(1)) - & - vel_R(dir_idx(1)))) + else if (wave_speeds == 2) then + pres_SL = 5.e-1_wp*(pres_L + pres_R + rho_avg*c_avg*(vel_L(dir_idx(1)) - vel_R(dir_idx(1)))) pres_SR = pres_SL - Ms_L = max(1._wp, sqrt(1._wp + ((5.e-1_wp + gamma_L)/(1._wp + gamma_L))* & - (pres_SL/pres_L - 1._wp)*pres_L/ & - ((pres_L + pi_inf_L/(1._wp + gamma_L))))) - Ms_R = max(1._wp, sqrt(1._wp + ((5.e-1_wp + gamma_R)/(1._wp + gamma_R))* & - (pres_SR/pres_R - 1._wp)*pres_R/ & - ((pres_R + pi_inf_R/(1._wp + gamma_R))))) + Ms_L = max(1._wp, & + & sqrt(1._wp + ((5.e-1_wp + gamma_L)/(1._wp + gamma_L))*(pres_SL/pres_L - 1._wp) & + & *pres_L/((pres_L + pi_inf_L/(1._wp + gamma_L))))) + Ms_R = max(1._wp, & + & sqrt(1._wp + ((5.e-1_wp + gamma_R)/(1._wp + gamma_R))*(pres_SR/pres_R - 1._wp) & + & *pres_R/((pres_R + pi_inf_R/(1._wp + gamma_R))))) s_L = vel_L(dir_idx(1)) - c_L*Ms_L s_R = vel_R(dir_idx(1)) + c_R*Ms_R - s_S = 5.e-1_wp*((vel_L(dir_idx(1)) + vel_R(dir_idx(1))) + & - (pres_L - pres_R)/ & - (rho_avg*c_avg)) + s_S = 5.e-1_wp*((vel_L(dir_idx(1)) + vel_R(dir_idx(1))) + (pres_L - pres_R)/(rho_avg*c_avg)) end if - ! follows Einfeldt et al. - ! s_M/P = min/max(0.,s_L/R) + ! follows Einfeldt et al. s_M/P = min/max(0.,s_L/R) s_M = min(0._wp, s_L); s_P = max(0._wp, s_R) - ! goes with q_star_L/R = xi_L/R * (variable) - ! xi_L/R = ( ( s_L/R - u_L/R )/(s_L/R - s_star) ) + ! goes with q_star_L/R = xi_L/R * (variable) xi_L/R = ( ( s_L/R - u_L/R )/(s_L/R - s_star) ) xi_L = (s_L - vel_L(dir_idx(1)))/(s_L - s_S) xi_R = (s_R - vel_R(dir_idx(1)))/(s_R - s_S) - ! goes with numerical star velocity in x/y/z directions - ! xi_P/M = 0.5 +/m sgn(0.5,s_star) + ! goes with numerical star velocity in x/y/z directions xi_P/M = 0.5 +/m sgn(0.5,s_star) xi_M = (5.e-1_wp + sign(0.5_wp, s_S)) xi_P = (5.e-1_wp - sign(0.5_wp, s_S)) - ! goes with the numerical velocity in x/y/z directions - ! xi_P/M (pressure) = min/max(0. sgn(1,sL/sR)) + ! goes with the numerical velocity in x/y/z directions xi_P/M (pressure) = min/max(0. sgn(1,sL/sR)) xi_MP = -min(0._wp, sign(1._wp, s_L)) xi_PP = max(0._wp, sign(1._wp, s_R)) - E_star = xi_M*(E_L + xi_MP*(xi_L*(E_L + (s_S - vel_L(dir_idx(1)))* & - (rho_L*s_S + pres_L/(s_L - vel_L(dir_idx(1))))) - E_L)) + & - xi_P*(E_R + xi_PP*(xi_R*(E_R + (s_S - vel_R(dir_idx(1)))* & - (rho_R*s_S + pres_R/(s_R - vel_R(dir_idx(1))))) - E_R)) - p_Star = xi_M*(pres_L + xi_MP*(rho_L*(s_L - vel_L(dir_idx(1)))*(s_S - vel_L(dir_idx(1))))) + & - xi_P*(pres_R + xi_PP*(rho_R*(s_R - vel_R(dir_idx(1)))*(s_S - vel_R(dir_idx(1))))) + E_star = xi_M*(E_L + xi_MP*(xi_L*(E_L + (s_S - vel_L(dir_idx(1)))*(rho_L*s_S + pres_L/(s_L & + & - vel_L(dir_idx(1))))) - E_L)) + xi_P*(E_R + xi_PP*(xi_R*(E_R + (s_S & + & - vel_R(dir_idx(1)))*(rho_R*s_S + pres_R/(s_R - vel_R(dir_idx(1))))) - E_R)) + p_Star = xi_M*(pres_L + xi_MP*(rho_L*(s_L - vel_L(dir_idx(1)))*(s_S - vel_L(dir_idx(1))))) & + & + xi_P*(pres_R + xi_PP*(rho_R*(s_R - vel_R(dir_idx(1)))*(s_S - vel_R(dir_idx(1))))) - rho_Star = xi_M*(rho_L*(xi_MP*xi_L + 1._wp - xi_MP)) + & - xi_P*(rho_R*(xi_PP*xi_R + 1._wp - xi_PP)) + rho_Star = xi_M*(rho_L*(xi_MP*xi_L + 1._wp - xi_MP)) + xi_P*(rho_R*(xi_PP*xi_R + 1._wp - xi_PP)) - vel_K_Star = vel_L(dir_idx(1))*(1._wp - xi_MP) + xi_MP*vel_R(dir_idx(1)) + & - xi_MP*xi_PP*(s_S - vel_R(dir_idx(1))) + vel_K_Star = vel_L(dir_idx(1))*(1._wp - xi_MP) + xi_MP*vel_R(dir_idx(1)) + xi_MP*xi_PP*(s_S & + & - vel_R(dir_idx(1))) ! Low Mach correction if (low_Mach == 1) then @@ -2348,44 +2101,42 @@ contains pcorr = 0._wp end if - ! COMPUTING FLUXES - ! MASS FLUX. + ! COMPUTING FLUXES MASS FLUX. $:GPU_LOOP(parallelism='[seq]') do i = 1, contxe - flux_rs${XYZ}$_vf(j, k, l, i) = & - xi_M*qL_prim_rs${XYZ}$_vf(j, k, l, i)*(vel_L(dir_idx(1)) + s_M*(xi_L - 1._wp)) + & - xi_P*qR_prim_rs${XYZ}$_vf(j + 1, k, l, i)*(vel_R(dir_idx(1)) + s_P*(xi_R - 1._wp)) + flux_rs${XYZ}$_vf(j, k, l, i) = xi_M*qL_prim_rs${XYZ}$_vf(j, k, l, & + & i)*(vel_L(dir_idx(1)) + s_M*(xi_L - 1._wp)) + xi_P*qR_prim_rs${XYZ}$_vf(j & + & + 1, k, l, i)*(vel_R(dir_idx(1)) + s_P*(xi_R - 1._wp)) end do - ! MOMENTUM FLUX. - ! f = \rho u u - \sigma, q = \rho u, q_star = \xi * \rho*(s_star, v, w) + ! MOMENTUM FLUX. f = \rho u u - \sigma, q = \rho u, q_star = \xi * \rho*(s_star, v, w) $:GPU_LOOP(parallelism='[seq]') do i = 1, num_dims - flux_rs${XYZ}$_vf(j, k, l, contxe + dir_idx(i)) = rho_Star*vel_K_Star* & - (dir_flg(dir_idx(i))*vel_K_Star + (1._wp - dir_flg(dir_idx(i)))*(xi_M*vel_L(dir_idx(i)) + xi_P*vel_R(dir_idx(i)))) + dir_flg(dir_idx(i))*p_Star & - + (s_M/s_L)*(s_P/s_R)*dir_flg(dir_idx(i))*pcorr + flux_rs${XYZ}$_vf(j, k, l, & + & contxe + dir_idx(i)) = rho_Star*vel_K_Star*(dir_flg(dir_idx(i)) & + & *vel_K_Star + (1._wp - dir_flg(dir_idx(i)))*(xi_M*vel_L(dir_idx(i)) & + & + xi_P*vel_R(dir_idx(i)))) + dir_flg(dir_idx(i))*p_Star + (s_M/s_L) & + & *(s_P/s_R)*dir_flg(dir_idx(i))*pcorr end do - ! ENERGY FLUX. - ! f = u*(E-\sigma), q = E, q_star = \xi*E+(s-u)(\rho s_star - \sigma/(s-u)) - flux_rs${XYZ}$_vf(j, k, l, E_idx) = (E_star + p_Star)*vel_K_Star & - + (s_M/s_L)*(s_P/s_R)*pcorr*s_S + ! ENERGY FLUX. f = u*(E-\sigma), q = E, q_star = \xi*E+(s-u)(\rho s_star - \sigma/(s-u)) + flux_rs${XYZ}$_vf(j, k, l, E_idx) = (E_star + p_Star)*vel_K_Star + (s_M/s_L)*(s_P/s_R)*pcorr*s_S ! ELASTICITY. Elastic shear stress additions for the momentum and energy flux if (elasticity) then - flux_ene_e = 0._wp; + flux_ene_e = 0._wp $:GPU_LOOP(parallelism='[seq]') do i = 1, num_dims ! MOMENTUM ELASTIC FLUX. - flux_rs${XYZ}$_vf(j, k, l, contxe + dir_idx(i)) = & - flux_rs${XYZ}$_vf(j, k, l, contxe + dir_idx(i)) & - - xi_M*tau_e_L(dir_idx_tau(i)) - xi_P*tau_e_R(dir_idx_tau(i)) + flux_rs${XYZ}$_vf(j, k, l, contxe + dir_idx(i)) = flux_rs${XYZ}$_vf(j, k, l, & + & contxe + dir_idx(i)) - xi_M*tau_e_L(dir_idx_tau(i)) & + & - xi_P*tau_e_R(dir_idx_tau(i)) ! ENERGY ELASTIC FLUX. - flux_ene_e = flux_ene_e - & - xi_M*(vel_L(dir_idx(i))*tau_e_L(dir_idx_tau(i)) + & - s_M*(xi_L*((s_S - vel_L(i))*(tau_e_L(dir_idx_tau(i))/(s_L - vel_L(i)))))) - & - xi_P*(vel_R(dir_idx(i))*tau_e_R(dir_idx_tau(i)) + & - s_P*(xi_R*((s_S - vel_R(i))*(tau_e_R(dir_idx_tau(i))/(s_R - vel_R(i)))))) + flux_ene_e = flux_ene_e - xi_M*(vel_L(dir_idx(i))*tau_e_L(dir_idx_tau(i)) & + & + s_M*(xi_L*((s_S - vel_L(i))*(tau_e_L(dir_idx_tau(i)) & + & /(s_L - vel_L(i)))))) - xi_P*(vel_R(dir_idx(i)) & + & *tau_e_R(dir_idx_tau(i)) + s_P*(xi_R*((s_S - vel_R(i)) & + & *(tau_e_R(dir_idx_tau(i))/(s_R - vel_R(i)))))) end do flux_rs${XYZ}$_vf(j, k, l, E_idx) = flux_rs${XYZ}$_vf(j, k, l, E_idx) + flux_ene_e end if @@ -2393,34 +2144,38 @@ contains ! VOLUME FRACTION FLUX. $:GPU_LOOP(parallelism='[seq]') do i = advxb, advxe - flux_rs${XYZ}$_vf(j, k, l, i) = & - xi_M*qL_prim_rs${XYZ}$_vf(j, k, l, i)*s_S + & - xi_P*qR_prim_rs${XYZ}$_vf(j + 1, k, l, i)*s_S + flux_rs${XYZ}$_vf(j, k, l, i) = xi_M*qL_prim_rs${XYZ}$_vf(j, k, l, & + & i)*s_S + xi_P*qR_prim_rs${XYZ}$_vf(j + 1, k, l, i)*s_S end do ! SOURCE TERM FOR VOLUME FRACTION ADVECTION FLUX. $:GPU_LOOP(parallelism='[seq]') do i = 1, num_dims - vel_src_rs${XYZ}$_vf(j, k, l, dir_idx(i)) = & - xi_M*(vel_L(dir_idx(i)) + dir_flg(dir_idx(i))*(s_S*(xi_MP*(xi_L - 1) + 1) - vel_L(dir_idx(i)))) + & - xi_P*(vel_R(dir_idx(i)) + dir_flg(dir_idx(i))*(s_S*(xi_PP*(xi_R - 1) + 1) - vel_R(dir_idx(i)))) + vel_src_rs${XYZ}$_vf(j, k, l, & + & dir_idx(i)) = xi_M*(vel_L(dir_idx(i)) + dir_flg(dir_idx(i)) & + & *(s_S*(xi_MP*(xi_L - 1) + 1) - vel_L(dir_idx(i)))) & + & + xi_P*(vel_R(dir_idx(i)) + dir_flg(dir_idx(i))*(s_S*(xi_PP*(xi_R - 1) & + & + 1) - vel_R(dir_idx(i)))) end do - ! INTERNAL ENERGIES ADVECTION FLUX. - ! K-th pressure and velocity in preparation for the internal energy flux + ! INTERNAL ENERGIES ADVECTION FLUX. K-th pressure and velocity in preparation for the internal + ! energy flux $:GPU_LOOP(parallelism='[seq]') do i = 1, num_fluids - p_K_Star = xi_M*(xi_MP*((pres_L + pi_infs(i)/(1._wp + gammas(i)))* & - xi_L**(1._wp/gammas(i) + 1._wp) - pi_infs(i)/(1._wp + gammas(i)) - pres_L) + pres_L) + & - xi_P*(xi_PP*((pres_R + pi_infs(i)/(1._wp + gammas(i)))* & - xi_R**(1._wp/gammas(i) + 1._wp) - pi_infs(i)/(1._wp + gammas(i)) - pres_R) + pres_R) - - flux_rs${XYZ}$_vf(j, k, l, i + intxb - 1) = & - ((xi_M*qL_prim_rs${XYZ}$_vf(j, k, l, i + advxb - 1) + xi_P*qR_prim_rs${XYZ}$_vf(j + 1, k, l, i + advxb - 1))* & - (gammas(i)*p_K_Star + pi_infs(i)) + & - (xi_M*qL_prim_rs${XYZ}$_vf(j, k, l, i + contxb - 1) + xi_P*qR_prim_rs${XYZ}$_vf(j + 1, k, l, i + contxb - 1))* & - qvs(i))*vel_K_Star & - + (s_M/s_L)*(s_P/s_R)*pcorr*s_S*(xi_M*qL_prim_rs${XYZ}$_vf(j, k, l, i + advxb - 1) + xi_P*qR_prim_rs${XYZ}$_vf(j + 1, k, l, i + advxb - 1)) + p_K_Star = xi_M*(xi_MP*((pres_L + pi_infs(i)/(1._wp + gammas(i)))*xi_L**(1._wp/gammas(i) & + & + 1._wp) - pi_infs(i)/(1._wp + gammas(i)) - pres_L) + pres_L) & + & + xi_P*(xi_PP*((pres_R + pi_infs(i)/(1._wp + gammas(i))) & + & *xi_R**(1._wp/gammas(i) + 1._wp) - pi_infs(i)/(1._wp + gammas(i)) - pres_R) & + & + pres_R) + + flux_rs${XYZ}$_vf(j, k, l, i + intxb - 1) = ((xi_M*qL_prim_rs${XYZ}$_vf(j, k, l, & + & i + advxb - 1) + xi_P*qR_prim_rs${XYZ}$_vf(j + 1, k, l, & + & i + advxb - 1))*(gammas(i)*p_K_Star + pi_infs(i)) & + & + (xi_M*qL_prim_rs${XYZ}$_vf(j, k, l, & + & i + contxb - 1) + xi_P*qR_prim_rs${XYZ}$_vf(j + 1, k, l, & + & i + contxb - 1))*qvs(i))*vel_K_Star + (s_M/s_L)*(s_P/s_R) & + & *pcorr*s_S*(xi_M*qL_prim_rs${XYZ}$_vf(j, k, l, & + & i + advxb - 1) + xi_P*qR_prim_rs${XYZ}$_vf(j + 1, k, l, i + advxb - 1)) end do flux_src_rs${XYZ}$_vf(j, k, l, advxb) = vel_src_rs${XYZ}$_vf(j, k, l, dir_idx(1)) @@ -2429,9 +2184,10 @@ contains if (hypoelasticity) then $:GPU_LOOP(parallelism='[seq]') do i = 1, strxe - strxb + 1 - flux_rs${XYZ}$_vf(j, k, l, strxb - 1 + i) = & - xi_M*(s_S/(s_L - s_S))*(s_L*rho_L*tau_e_L(i) - rho_L*vel_L(dir_idx(1))*tau_e_L(i)) + & - xi_P*(s_S/(s_R - s_S))*(s_R*rho_R*tau_e_R(i) - rho_R*vel_R(dir_idx(1))*tau_e_R(i)) + flux_rs${XYZ}$_vf(j, k, l, & + & strxb - 1 + i) = xi_M*(s_S/(s_L - s_S))*(s_L*rho_L*tau_e_L(i) & + & - rho_L*vel_L(dir_idx(1))*tau_e_L(i)) + xi_P*(s_S/(s_R - s_S)) & + & *(s_R*rho_R*tau_e_R(i) - rho_R*vel_R(dir_idx(1))*tau_e_R(i)) end do end if @@ -2439,25 +2195,23 @@ contains if (hyperelasticity) then $:GPU_LOOP(parallelism='[seq]') do i = 1, num_dims - flux_rs${XYZ}$_vf(j, k, l, xibeg - 1 + i) = & - xi_M*(s_S/(s_L - s_S))*(s_L*rho_L*xi_field_L(i) & - - rho_L*vel_L(dir_idx(1))*xi_field_L(i)) + & - xi_P*(s_S/(s_R - s_S))*(s_R*rho_R*xi_field_R(i) & - - rho_R*vel_R(dir_idx(1))*xi_field_R(i)) + flux_rs${XYZ}$_vf(j, k, l, & + & xibeg - 1 + i) = xi_M*(s_S/(s_L - s_S))*(s_L*rho_L*xi_field_L(i) & + & - rho_L*vel_L(dir_idx(1))*xi_field_L(i)) + xi_P*(s_S/(s_R - s_S)) & + & *(s_R*rho_R*xi_field_R(i) - rho_R*vel_R(dir_idx(1))*xi_field_R(i)) end do end if ! COLOR FUNCTION FLUX if (surface_tension) then - flux_rs${XYZ}$_vf(j, k, l, c_idx) = & - (xi_M*qL_prim_rs${XYZ}$_vf(j, k, l, c_idx) + & - xi_P*qR_prim_rs${XYZ}$_vf(j + 1, k, l, c_idx))*s_S + flux_rs${XYZ}$_vf(j, k, l, c_idx) = (xi_M*qL_prim_rs${XYZ}$_vf(j, k, l, & + & c_idx) + xi_P*qR_prim_rs${XYZ}$_vf(j + 1, k, l, c_idx))*s_S end if ! Geometrical source flux for cylindrical coordinates #:if (NORM_DIR == 2) if (cyl_coord) then - !Substituting the advective flux into the inviscid geometrical source flux + ! Substituting the advective flux into the inviscid geometrical source flux $:GPU_LOOP(parallelism='[seq]') do i = 1, E_idx flux_gsrc_rs${XYZ}$_vf(j, k, l, i) = flux_rs${XYZ}$_vf(j, k, l, i) @@ -2467,8 +2221,8 @@ contains flux_gsrc_rs${XYZ}$_vf(j, k, l, i) = flux_rs${XYZ}$_vf(j, k, l, i) end do ! Recalculating the radial momentum geometric source flux - flux_gsrc_rs${XYZ}$_vf(j, k, l, momxb - 1 + dir_idx(1)) = & - flux_gsrc_rs${XYZ}$_vf(j, k, l, momxb - 1 + dir_idx(1)) - p_Star + flux_gsrc_rs${XYZ}$_vf(j, k, l, momxb - 1 + dir_idx(1)) = flux_gsrc_rs${XYZ}$_vf(j, k, l, & + & momxb - 1 + dir_idx(1)) - p_Star ! Geometrical source of the void fraction(s) is zero $:GPU_LOOP(parallelism='[seq]') do i = advxb, advxe @@ -2482,25 +2236,29 @@ contains do i = 1, sys_size flux_gsrc_rs${XYZ}$_vf(j, k, l, i) = 0._wp end do - flux_gsrc_rs${XYZ}$_vf(j, k, l, momxb - 1 + dir_idx(1)) = & - flux_gsrc_rs${XYZ}$_vf(j, k, l, momxb - 1 + dir_idx(1)) - p_Star + flux_gsrc_rs${XYZ}$_vf(j, k, l, momxb - 1 + dir_idx(1)) = flux_gsrc_rs${XYZ}$_vf(j, k, l, & + & momxb - 1 + dir_idx(1)) - p_Star flux_gsrc_rs${XYZ}$_vf(j, k, l, momxe) = flux_rs${XYZ}$_vf(j, k, l, momxb + 1) end if #:endif - end do end do end do $:END_GPU_PARALLEL_LOOP() - - elseif (model_eqns == 4) then - !ME4 - $:GPU_PARALLEL_LOOP(collapse=3, private='[i, q, alpha_rho_L, alpha_rho_R, vel_L, vel_R, alpha_L, alpha_R, nbub_L, nbub_R, rho_L, rho_R, pres_L, pres_R, E_L, E_R, H_L, H_R, Cp_avg, Cv_avg, T_avg, eps, c_sum_Yi_Phi, T_L, T_R, Y_L, Y_R, MW_L, MW_R, R_gas_L, R_gas_R, Cp_L, Cp_R, Gamm_L, Gamm_R, gamma_L, gamma_R, pi_inf_L, pi_inf_R, qv_L, qv_R, qv_avg,c_L, c_R, G_L, G_R, rho_avg, H_avg, c_avg, gamma_avg, ptilde_L, ptilde_R, vel_L_rms, vel_R_rms, vel_avg_rms, vel_L_tmp, vel_R_tmp, Ms_L, Ms_R, pres_SL, pres_SR, alpha_L_sum, alpha_R_sum, rho_Star, E_Star, p_Star, p_K_Star, vel_K_star, s_L, s_R, s_M, s_P, s_S, xi_M, xi_P, xi_L, xi_R, xi_MP, xi_PP]') + else if (model_eqns == 4) then + ! ME4 + $:GPU_PARALLEL_LOOP(collapse=3, private='[i, q, alpha_rho_L, alpha_rho_R, vel_L, vel_R, alpha_L, alpha_R, & + & nbub_L, nbub_R, rho_L, rho_R, pres_L, pres_R, E_L, E_R, H_L, H_R, Cp_avg, Cv_avg, & + & T_avg, eps, c_sum_Yi_Phi, T_L, T_R, Y_L, Y_R, MW_L, MW_R, R_gas_L, R_gas_R, Cp_L, Cp_R, & + & Gamm_L, Gamm_R, gamma_L, gamma_R, pi_inf_L, pi_inf_R, qv_L, qv_R, qv_avg, c_L, c_R, & + & G_L, G_R, rho_avg, H_avg, c_avg, gamma_avg, ptilde_L, ptilde_R, vel_L_rms, vel_R_rms, & + & vel_avg_rms, vel_L_tmp, vel_R_tmp, Ms_L, Ms_R, pres_SL, pres_SR, alpha_L_sum, & + & alpha_R_sum, rho_Star, E_Star, p_Star, p_K_Star, vel_K_star, s_L, s_R, s_M, s_P, s_S, & + & xi_M, xi_P, xi_L, xi_R, xi_MP, xi_PP]') do l = is3%beg, is3%end do k = is2%beg, is2%end do j = is1%beg, is1%end - vel_L_rms = 0._wp; vel_R_rms = 0._wp rho_L = 0._wp; rho_R = 0._wp gamma_L = 0._wp; gamma_R = 0._wp @@ -2556,120 +2314,97 @@ contains @:compute_average_state() - call s_compute_speed_of_sound(pres_L, rho_L, gamma_L, pi_inf_L, H_L, alpha_L, & - vel_L_rms, 0._wp, c_L, qv_L) + call s_compute_speed_of_sound(pres_L, rho_L, gamma_L, pi_inf_L, H_L, alpha_L, vel_L_rms, 0._wp, & + & c_L, qv_L) - call s_compute_speed_of_sound(pres_R, rho_R, gamma_R, pi_inf_R, H_R, alpha_R, & - vel_R_rms, 0._wp, c_R, qv_R) + call s_compute_speed_of_sound(pres_R, rho_R, gamma_R, pi_inf_R, H_R, alpha_R, vel_R_rms, 0._wp, & + & c_R, qv_R) !> The computation of c_avg does not require all the variables, and therefore the non '_avg' ! variables are placeholders to call the subroutine. - call s_compute_speed_of_sound(pres_R, rho_avg, gamma_avg, pi_inf_R, H_avg, alpha_R, & - vel_avg_rms, 0._wp, c_avg, qv_avg) + call s_compute_speed_of_sound(pres_R, rho_avg, gamma_avg, pi_inf_R, H_avg, alpha_R, vel_avg_rms, & + & 0._wp, c_avg, qv_avg) if (wave_speeds == 1) then s_L = min(vel_L(dir_idx(1)) - c_L, vel_R(dir_idx(1)) - c_R) s_R = max(vel_R(dir_idx(1)) + c_R, vel_L(dir_idx(1)) + c_L) - s_S = (pres_R - pres_L + rho_L*vel_L(dir_idx(1))* & - (s_L - vel_L(dir_idx(1))) - & - rho_R*vel_R(dir_idx(1))* & - (s_R - vel_R(dir_idx(1)))) & - /(rho_L*(s_L - vel_L(dir_idx(1))) - & - rho_R*(s_R - vel_R(dir_idx(1)))) - elseif (wave_speeds == 2) then - pres_SL = 5.e-1_wp*(pres_L + pres_R + rho_avg*c_avg* & - (vel_L(dir_idx(1)) - & - vel_R(dir_idx(1)))) + s_S = (pres_R - pres_L + rho_L*vel_L(dir_idx(1))*(s_L - vel_L(dir_idx(1))) & + & - rho_R*vel_R(dir_idx(1))*(s_R - vel_R(dir_idx(1))))/(rho_L*(s_L - vel_L(dir_idx(1))) & + & - rho_R*(s_R - vel_R(dir_idx(1)))) + else if (wave_speeds == 2) then + pres_SL = 5.e-1_wp*(pres_L + pres_R + rho_avg*c_avg*(vel_L(dir_idx(1)) - vel_R(dir_idx(1)))) pres_SR = pres_SL - Ms_L = max(1._wp, sqrt(1._wp + ((5.e-1_wp + gamma_L)/(1._wp + gamma_L))* & - (pres_SL/pres_L - 1._wp)*pres_L/ & - ((pres_L + pi_inf_L/(1._wp + gamma_L))))) - Ms_R = max(1._wp, sqrt(1._wp + ((5.e-1_wp + gamma_R)/(1._wp + gamma_R))* & - (pres_SR/pres_R - 1._wp)*pres_R/ & - ((pres_R + pi_inf_R/(1._wp + gamma_R))))) + Ms_L = max(1._wp, & + & sqrt(1._wp + ((5.e-1_wp + gamma_L)/(1._wp + gamma_L))*(pres_SL/pres_L - 1._wp) & + & *pres_L/((pres_L + pi_inf_L/(1._wp + gamma_L))))) + Ms_R = max(1._wp, & + & sqrt(1._wp + ((5.e-1_wp + gamma_R)/(1._wp + gamma_R))*(pres_SR/pres_R - 1._wp) & + & *pres_R/((pres_R + pi_inf_R/(1._wp + gamma_R))))) s_L = vel_L(dir_idx(1)) - c_L*Ms_L s_R = vel_R(dir_idx(1)) + c_R*Ms_R - s_S = 5.e-1_wp*((vel_L(dir_idx(1)) + vel_R(dir_idx(1))) + & - (pres_L - pres_R)/ & - (rho_avg*c_avg)) + s_S = 5.e-1_wp*((vel_L(dir_idx(1)) + vel_R(dir_idx(1))) + (pres_L - pres_R)/(rho_avg*c_avg)) end if - ! follows Einfeldt et al. - ! s_M/P = min/max(0.,s_L/R) + ! follows Einfeldt et al. s_M/P = min/max(0.,s_L/R) s_M = min(0._wp, s_L); s_P = max(0._wp, s_R) - ! goes with q_star_L/R = xi_L/R * (variable) - ! xi_L/R = ( ( s_L/R - u_L/R )/(s_L/R - s_star) ) + ! goes with q_star_L/R = xi_L/R * (variable) xi_L/R = ( ( s_L/R - u_L/R )/(s_L/R - s_star) ) xi_L = (s_L - vel_L(dir_idx(1)))/(s_L - s_S) xi_R = (s_R - vel_R(dir_idx(1)))/(s_R - s_S) - ! goes with numerical velocity in x/y/z directions - ! xi_P/M = 0.5 +/m sgn(0.5,s_star) + ! goes with numerical velocity in x/y/z directions xi_P/M = 0.5 +/m sgn(0.5,s_star) xi_M = (5.e-1_wp + sign(5.e-1_wp, s_S)) xi_P = (5.e-1_wp - sign(5.e-1_wp, s_S)) $:GPU_LOOP(parallelism='[seq]') do i = 1, contxe - flux_rs${XYZ}$_vf(j, k, l, i) = & - xi_M*alpha_rho_L(i) & - *(vel_L(dir_idx(1)) + s_M*(xi_L - 1._wp)) & - + xi_P*alpha_rho_R(i) & - *(vel_R(dir_idx(1)) + s_P*(xi_R - 1._wp)) + flux_rs${XYZ}$_vf(j, k, l, & + & i) = xi_M*alpha_rho_L(i)*(vel_L(dir_idx(1)) + s_M*(xi_L - 1._wp)) & + & + xi_P*alpha_rho_R(i)*(vel_R(dir_idx(1)) + s_P*(xi_R - 1._wp)) end do - ! Momentum flux. - ! f = \rho u u + p I, q = \rho u, q_star = \xi * \rho*(s_star, v, w) + ! Momentum flux. f = \rho u u + p I, q = \rho u, q_star = \xi * \rho*(s_star, v, w) $:GPU_LOOP(parallelism='[seq]') do i = 1, num_dims - flux_rs${XYZ}$_vf(j, k, l, contxe + dir_idx(i)) = & - xi_M*(rho_L*(vel_L(dir_idx(1))* & - vel_L(dir_idx(i)) + & - s_M*(xi_L*(dir_flg(dir_idx(i))*s_S + & - (1._wp - dir_flg(dir_idx(i)))* & - vel_L(dir_idx(i))) - vel_L(dir_idx(i)))) + & - dir_flg(dir_idx(i))*pres_L) & - + xi_P*(rho_R*(vel_R(dir_idx(1))* & - vel_R(dir_idx(i)) + & - s_P*(xi_R*(dir_flg(dir_idx(i))*s_S + & - (1._wp - dir_flg(dir_idx(i)))* & - vel_R(dir_idx(i))) - vel_R(dir_idx(i)))) + & - dir_flg(dir_idx(i))*pres_R) + flux_rs${XYZ}$_vf(j, k, l, & + & contxe + dir_idx(i)) = xi_M*(rho_L*(vel_L(dir_idx(1))*vel_L(dir_idx(i)) & + & + s_M*(xi_L*(dir_flg(dir_idx(i))*s_S + (1._wp - dir_flg(dir_idx(i))) & + & *vel_L(dir_idx(i))) - vel_L(dir_idx(i)))) + dir_flg(dir_idx(i))*pres_L) & + & + xi_P*(rho_R*(vel_R(dir_idx(1))*vel_R(dir_idx(i)) & + & + s_P*(xi_R*(dir_flg(dir_idx(i))*s_S + (1._wp - dir_flg(dir_idx(i))) & + & *vel_R(dir_idx(i))) - vel_R(dir_idx(i)))) + dir_flg(dir_idx(i))*pres_R) end do if (bubbles_euler) then ! Put p_tilde in $:GPU_LOOP(parallelism='[seq]') do i = 1, num_dims - flux_rs${XYZ}$_vf(j, k, l, contxe + dir_idx(i)) = & - flux_rs${XYZ}$_vf(j, k, l, contxe + dir_idx(i)) + & - xi_M*(dir_flg(dir_idx(i))*(-1._wp*ptilde_L)) & - + xi_P*(dir_flg(dir_idx(i))*(-1._wp*ptilde_R)) + flux_rs${XYZ}$_vf(j, k, l, contxe + dir_idx(i)) = flux_rs${XYZ}$_vf(j, k, l, & + & contxe + dir_idx(i)) + xi_M*(dir_flg(dir_idx(i))*(-1._wp*ptilde_L)) & + & + xi_P*(dir_flg(dir_idx(i))*(-1._wp*ptilde_R)) end do end if flux_rs${XYZ}$_vf(j, k, l, E_idx) = 0._wp $:GPU_LOOP(parallelism='[seq]') - do i = alf_idx, alf_idx !only advect the void fraction - flux_rs${XYZ}$_vf(j, k, l, i) = & - xi_M*qL_prim_rs${XYZ}$_vf(j, k, l, i) & - *(vel_L(dir_idx(1)) + s_M*(xi_L - 1._wp)) & - + xi_P*qR_prim_rs${XYZ}$_vf(j + 1, k, l, i) & - *(vel_R(dir_idx(1)) + s_P*(xi_R - 1._wp)) + do i = alf_idx, alf_idx ! only advect the void fraction + flux_rs${XYZ}$_vf(j, k, l, i) = xi_M*qL_prim_rs${XYZ}$_vf(j, k, l, & + & i)*(vel_L(dir_idx(1)) + s_M*(xi_L - 1._wp)) + xi_P*qR_prim_rs${XYZ}$_vf(j & + & + 1, k, l, i)*(vel_R(dir_idx(1)) + s_P*(xi_R - 1._wp)) end do ! Source for volume fraction advection equation $:GPU_LOOP(parallelism='[seq]') do i = 1, num_dims - vel_src_rs${XYZ}$_vf(j, k, l, dir_idx(i)) = 0._wp - !IF ( (model_eqns == 4) .or. (num_fluids==1) ) vel_src_rs_vf(dir_idx(i))%sf(j,k,l) = 0._wp + ! IF ( (model_eqns == 4) .or. (num_fluids==1) ) vel_src_rs_vf(dir_idx(i))%sf(j,k,l) = 0._wp end do flux_src_rs${XYZ}$_vf(j, k, l, advxb) = vel_src_rs${XYZ}$_vf(j, k, l, dir_idx(1)) @@ -2678,11 +2413,10 @@ contains if (bubbles_euler) then $:GPU_LOOP(parallelism='[seq]') do i = bubxb, bubxe - flux_rs${XYZ}$_vf(j, k, l, i) = & - xi_M*nbub_L*qL_prim_rs${XYZ}$_vf(j, k, l, i) & - *(vel_L(dir_idx(1)) + s_M*(xi_L - 1._wp)) & - + xi_P*nbub_R*qR_prim_rs${XYZ}$_vf(j + 1, k, l, i) & - *(vel_R(dir_idx(1)) + s_P*(xi_R - 1._wp)) + flux_rs${XYZ}$_vf(j, k, l, i) = xi_M*nbub_L*qL_prim_rs${XYZ}$_vf(j, k, l, & + & i)*(vel_L(dir_idx(1)) + s_M*(xi_L - 1._wp)) & + & + xi_P*nbub_R*qR_prim_rs${XYZ}$_vf(j + 1, k, l, & + & i)*(vel_R(dir_idx(1)) + s_P*(xi_R - 1._wp)) end do end if @@ -2696,17 +2430,13 @@ contains flux_gsrc_rs${XYZ}$_vf(j, k, l, i) = flux_rs${XYZ}$_vf(j, k, l, i) end do ! Recalculating the radial momentum geometric source flux - flux_gsrc_rs${XYZ}$_vf(j, k, l, contxe + dir_idx(1)) = & - xi_M*(rho_L*(vel_L(dir_idx(1))* & - vel_L(dir_idx(1)) + & - s_M*(xi_L*(dir_flg(dir_idx(1))*s_S + & - (1._wp - dir_flg(dir_idx(1)))* & - vel_L(dir_idx(1))) - vel_L(dir_idx(1))))) & - + xi_P*(rho_R*(vel_R(dir_idx(1))* & - vel_R(dir_idx(1)) + & - s_P*(xi_R*(dir_flg(dir_idx(1))*s_S + & - (1._wp - dir_flg(dir_idx(1)))* & - vel_R(dir_idx(1))) - vel_R(dir_idx(1))))) + flux_gsrc_rs${XYZ}$_vf(j, k, l, & + & contxe + dir_idx(1)) = xi_M*(rho_L*(vel_L(dir_idx(1)) & + & *vel_L(dir_idx(1)) + s_M*(xi_L*(dir_flg(dir_idx(1))*s_S + (1._wp & + & - dir_flg(dir_idx(1)))*vel_L(dir_idx(1))) - vel_L(dir_idx(1))))) & + & + xi_P*(rho_R*(vel_R(dir_idx(1))*vel_R(dir_idx(1)) & + & + s_P*(xi_R*(dir_flg(dir_idx(1))*s_S + (1._wp & + & - dir_flg(dir_idx(1)))*vel_R(dir_idx(1))) - vel_R(dir_idx(1))))) ! Geometrical source of the void fraction(s) is zero $:GPU_LOOP(parallelism='[seq]') do i = advxb, advxe @@ -2720,17 +2450,13 @@ contains do i = 1, sys_size flux_gsrc_rs${XYZ}$_vf(j, k, l, i) = 0._wp end do - flux_gsrc_rs${XYZ}$_vf(j, k, l, momxb + 1) = & - -xi_M*(rho_L*(vel_L(dir_idx(1))* & - vel_L(dir_idx(1)) + & - s_M*(xi_L*(dir_flg(dir_idx(1))*s_S + & - (1._wp - dir_flg(dir_idx(1)))* & - vel_L(dir_idx(1))) - vel_L(dir_idx(1))))) & - - xi_P*(rho_R*(vel_R(dir_idx(1))* & - vel_R(dir_idx(1)) + & - s_P*(xi_R*(dir_flg(dir_idx(1))*s_S + & - (1._wp - dir_flg(dir_idx(1)))* & - vel_R(dir_idx(1))) - vel_R(dir_idx(1))))) + flux_gsrc_rs${XYZ}$_vf(j, k, l, & + & momxb + 1) = -xi_M*(rho_L*(vel_L(dir_idx(1))*vel_L(dir_idx(1)) & + & + s_M*(xi_L*(dir_flg(dir_idx(1))*s_S + (1._wp & + & - dir_flg(dir_idx(1)))*vel_L(dir_idx(1))) - vel_L(dir_idx(1))))) & + & - xi_P*(rho_R*(vel_R(dir_idx(1))*vel_R(dir_idx(1)) & + & + s_P*(xi_R*(dir_flg(dir_idx(1))*s_S + (1._wp & + & - dir_flg(dir_idx(1)))*vel_R(dir_idx(1))) - vel_R(dir_idx(1))))) flux_gsrc_rs${XYZ}$_vf(j, k, l, momxe) = flux_rs${XYZ}$_vf(j, k, l, momxb + 1) end if #:endif @@ -2738,13 +2464,17 @@ contains end do end do $:END_GPU_PARALLEL_LOOP() - - elseif (model_eqns == 2 .and. bubbles_euler) then - $:GPU_PARALLEL_LOOP(collapse=3, private='[i, q, R0_L, R0_R, V0_L, V0_R, P0_L, P0_R, pbw_L, pbw_R, vel_L, vel_R, rho_avg, alpha_L, alpha_R, h_avg, gamma_avg, Re_L, Re_R, pcorr, zcoef, rho_L, rho_R, pres_L, pres_R, E_L, E_R, H_L, H_R, gamma_L, gamma_R, pi_inf_L, pi_inf_R, qv_L, qv_R, qv_avg, c_L, c_R, c_avg, vel_L_rms, vel_R_rms, vel_avg_rms, vel_L_tmp, vel_R_tmp, Ms_L, Ms_R, pres_SL, pres_SR, alpha_L_sum, alpha_R_sum, s_L, s_R, s_M, s_P, s_S, xi_M, xi_P, xi_L, xi_R, xi_MP, xi_PP, nbub_L, nbub_R, PbwR3Lbar, PbwR3Rbar, R3Lbar, R3Rbar, R3V2Lbar, R3V2Rbar]') + else if (model_eqns == 2 .and. bubbles_euler) then + $:GPU_PARALLEL_LOOP(collapse=3, private='[i, q, R0_L, R0_R, V0_L, V0_R, P0_L, P0_R, pbw_L, pbw_R, vel_L, & + & vel_R, rho_avg, alpha_L, alpha_R, h_avg, gamma_avg, Re_L, Re_R, pcorr, zcoef, rho_L, & + & rho_R, pres_L, pres_R, E_L, E_R, H_L, H_R, gamma_L, gamma_R, pi_inf_L, pi_inf_R, qv_L, & + & qv_R, qv_avg, c_L, c_R, c_avg, vel_L_rms, vel_R_rms, vel_avg_rms, vel_L_tmp, vel_R_tmp, & + & Ms_L, Ms_R, pres_SL, pres_SR, alpha_L_sum, alpha_R_sum, s_L, s_R, s_M, s_P, s_S, xi_M, & + & xi_P, xi_L, xi_R, xi_MP, xi_PP, nbub_L, nbub_R, PbwR3Lbar, PbwR3Rbar, R3Lbar, R3Rbar, & + & R3V2Lbar, R3V2Rbar]') do l = is3%beg, is3%end do k = is2%beg, is2%end do j = is1%beg, is1%end - vel_L_rms = 0._wp; vel_R_rms = 0._wp rho_L = 0._wp; rho_R = 0._wp gamma_L = 0._wp; gamma_R = 0._wp @@ -2804,7 +2534,7 @@ contains end if if (viscous) then - if (num_fluids == 1) then ! Need to consider case with num_fluids >= 2 + if (num_fluids == 1) then ! Need to consider case with num_fluids >= 2 $:GPU_LOOP(parallelism='[seq]') do i = 1, 2 Re_L(i) = dflt_real @@ -2815,15 +2545,14 @@ contains $:GPU_LOOP(parallelism='[seq]') do q = 1, Re_size(i) - Re_L(i) = (1._wp - qL_prim_rs${XYZ}$_vf(j, k, l, E_idx + Re_idx(i, q)))/Res_gs(i, q) & - + Re_L(i) - Re_R(i) = (1._wp - qR_prim_rs${XYZ}$_vf(j + 1, k, l, E_idx + Re_idx(i, q)))/Res_gs(i, q) & - + Re_R(i) + Re_L(i) = (1._wp - qL_prim_rs${XYZ}$_vf(j, k, l, E_idx + Re_idx(i, q)))/Res_gs(i, & + & q) + Re_L(i) + Re_R(i) = (1._wp - qR_prim_rs${XYZ}$_vf(j + 1, k, l, E_idx + Re_idx(i, & + & q)))/Res_gs(i, q) + Re_R(i) end do Re_L(i) = 1._wp/max(Re_L(i), sgm_eps) Re_R(i) = 1._wp/max(Re_R(i), sgm_eps) - end do end if end if @@ -2868,7 +2597,7 @@ contains nbub_R = (3._wp/(4._wp*pi))*qR_prim_rs${XYZ}$_vf(j + 1, k, l, E_idx + num_fluids)/nbub_R end if else - !nb stored in 0th moment of first R0 bin in variable conversion module + ! nb stored in 0th moment of first R0 bin in variable conversion module nbub_L = qL_prim_rs${XYZ}$_vf(j, k, l, bubxb) nbub_R = qR_prim_rs${XYZ}$_vf(j + 1, k, l, bubxb) end if @@ -2891,7 +2620,6 @@ contains R3V2Lbar = mom_sp_rs${XYZ}$_vf(j, k, l, 3) R3V2Rbar = mom_sp_rs${XYZ}$_vf(j + 1, k, l, 3) else - PbwR3Lbar = 0._wp PbwR3Rbar = 0._wp @@ -2924,19 +2652,18 @@ contains do i = 1, num_dims vel_avg_rms = vel_avg_rms + (5.e-1_wp*(vel_L(i) + vel_R(i)))**2._wp end do - end if - call s_compute_speed_of_sound(pres_L, rho_L, gamma_L, pi_inf_L, H_L, alpha_L, & - vel_L_rms, 0._wp, c_L, qv_L) + call s_compute_speed_of_sound(pres_L, rho_L, gamma_L, pi_inf_L, H_L, alpha_L, vel_L_rms, 0._wp, & + & c_L, qv_L) - call s_compute_speed_of_sound(pres_R, rho_R, gamma_R, pi_inf_R, H_R, alpha_R, & - vel_R_rms, 0._wp, c_R, qv_R) + call s_compute_speed_of_sound(pres_R, rho_R, gamma_R, pi_inf_R, H_R, alpha_R, vel_R_rms, 0._wp, & + & c_R, qv_R) !> The computation of c_avg does not require all the variables, and therefore the non '_avg' ! variables are placeholders to call the subroutine. - call s_compute_speed_of_sound(pres_R, rho_avg, gamma_avg, pi_inf_R, H_avg, alpha_R, & - vel_avg_rms, 0._wp, c_avg, qv_avg) + call s_compute_speed_of_sound(pres_R, rho_avg, gamma_avg, pi_inf_R, H_avg, alpha_R, vel_avg_rms, & + & 0._wp, c_avg, qv_avg) if (viscous) then $:GPU_LOOP(parallelism='[seq]') @@ -2954,45 +2681,35 @@ contains s_L = min(vel_L(dir_idx(1)) - c_L, vel_R(dir_idx(1)) - c_R) s_R = max(vel_R(dir_idx(1)) + c_R, vel_L(dir_idx(1)) + c_L) - s_S = (pres_R - pres_L + rho_L*vel_L(dir_idx(1))* & - (s_L - vel_L(dir_idx(1))) - & - rho_R*vel_R(dir_idx(1))* & - (s_R - vel_R(dir_idx(1)))) & - /(rho_L*(s_L - vel_L(dir_idx(1))) - & - rho_R*(s_R - vel_R(dir_idx(1)))) - elseif (wave_speeds == 2) then - pres_SL = 5.e-1_wp*(pres_L + pres_R + rho_avg*c_avg* & - (vel_L(dir_idx(1)) - & - vel_R(dir_idx(1)))) + s_S = (pres_R - pres_L + rho_L*vel_L(dir_idx(1))*(s_L - vel_L(dir_idx(1))) & + & - rho_R*vel_R(dir_idx(1))*(s_R - vel_R(dir_idx(1))))/(rho_L*(s_L - vel_L(dir_idx(1))) & + & - rho_R*(s_R - vel_R(dir_idx(1)))) + else if (wave_speeds == 2) then + pres_SL = 5.e-1_wp*(pres_L + pres_R + rho_avg*c_avg*(vel_L(dir_idx(1)) - vel_R(dir_idx(1)))) pres_SR = pres_SL - Ms_L = max(1._wp, sqrt(1._wp + ((5.e-1_wp + gamma_L)/(1._wp + gamma_L))* & - (pres_SL/pres_L - 1._wp)*pres_L/ & - ((pres_L + pi_inf_L/(1._wp + gamma_L))))) - Ms_R = max(1._wp, sqrt(1._wp + ((5.e-1_wp + gamma_R)/(1._wp + gamma_R))* & - (pres_SR/pres_R - 1._wp)*pres_R/ & - ((pres_R + pi_inf_R/(1._wp + gamma_R))))) + Ms_L = max(1._wp, & + & sqrt(1._wp + ((5.e-1_wp + gamma_L)/(1._wp + gamma_L))*(pres_SL/pres_L - 1._wp) & + & *pres_L/((pres_L + pi_inf_L/(1._wp + gamma_L))))) + Ms_R = max(1._wp, & + & sqrt(1._wp + ((5.e-1_wp + gamma_R)/(1._wp + gamma_R))*(pres_SR/pres_R - 1._wp) & + & *pres_R/((pres_R + pi_inf_R/(1._wp + gamma_R))))) s_L = vel_L(dir_idx(1)) - c_L*Ms_L s_R = vel_R(dir_idx(1)) + c_R*Ms_R - s_S = 5.e-1_wp*((vel_L(dir_idx(1)) + vel_R(dir_idx(1))) + & - (pres_L - pres_R)/ & - (rho_avg*c_avg)) + s_S = 5.e-1_wp*((vel_L(dir_idx(1)) + vel_R(dir_idx(1))) + (pres_L - pres_R)/(rho_avg*c_avg)) end if - ! follows Einfeldt et al. - ! s_M/P = min/max(0.,s_L/R) + ! follows Einfeldt et al. s_M/P = min/max(0.,s_L/R) s_M = min(0._wp, s_L); s_P = max(0._wp, s_R) - ! goes with q_star_L/R = xi_L/R * (variable) - ! xi_L/R = ( ( s_L/R - u_L/R )/(s_L/R - s_star) ) + ! goes with q_star_L/R = xi_L/R * (variable) xi_L/R = ( ( s_L/R - u_L/R )/(s_L/R - s_star) ) xi_L = (s_L - vel_L(dir_idx(1)))/(s_L - s_S) xi_R = (s_R - vel_R(dir_idx(1)))/(s_R - s_S) - ! goes with numerical velocity in x/y/z directions - ! xi_P/M = 0.5 +/m sgn(0.5,s_star) + ! goes with numerical velocity in x/y/z directions xi_P/M = 0.5 +/m sgn(0.5,s_star) xi_M = (5.e-1_wp + sign(5.e-1_wp, s_S)) xi_P = (5.e-1_wp - sign(5.e-1_wp, s_S)) @@ -3005,11 +2722,9 @@ contains $:GPU_LOOP(parallelism='[seq]') do i = 1, contxe - flux_rs${XYZ}$_vf(j, k, l, i) = & - xi_M*qL_prim_rs${XYZ}$_vf(j, k, l, i) & - *(vel_L(dir_idx(1)) + s_M*(xi_L - 1._wp)) & - + xi_P*qR_prim_rs${XYZ}$_vf(j + 1, k, l, i) & - *(vel_R(dir_idx(1)) + s_P*(xi_R - 1._wp)) + flux_rs${XYZ}$_vf(j, k, l, i) = xi_M*qL_prim_rs${XYZ}$_vf(j, k, l, & + & i)*(vel_L(dir_idx(1)) + s_M*(xi_L - 1._wp)) + xi_P*qR_prim_rs${XYZ}$_vf(j & + & + 1, k, l, i)*(vel_R(dir_idx(1)) + s_P*(xi_R - 1._wp)) end do if (bubbles_euler .and. (num_fluids > 1)) then @@ -3017,8 +2732,7 @@ contains flux_rs${XYZ}$_vf(j, k, l, contxe) = 0._wp end if - ! Momentum flux. - ! f = \rho u u + p I, q = \rho u, q_star = \xi * \rho*(s_star, v, w) + ! Momentum flux. f = \rho u u + p I, q = \rho u, q_star = \xi * \rho*(s_star, v, w) ! Include p_tilde @@ -3026,71 +2740,53 @@ contains if (alpha_L(num_fluids) < small_alf .or. R3Lbar < small_alf) then pres_L = pres_L - alpha_L(num_fluids)*pres_L else - pres_L = pres_L - alpha_L(num_fluids)*(pres_L - PbwR3Lbar/R3Lbar - & - rho_L*R3V2Lbar/R3Lbar) + pres_L = pres_L - alpha_L(num_fluids)*(pres_L - PbwR3Lbar/R3Lbar - rho_L*R3V2Lbar/R3Lbar) end if if (alpha_R(num_fluids) < small_alf .or. R3Rbar < small_alf) then pres_R = pres_R - alpha_R(num_fluids)*pres_R else - pres_R = pres_R - alpha_R(num_fluids)*(pres_R - PbwR3Rbar/R3Rbar - & - rho_R*R3V2Rbar/R3Rbar) + pres_R = pres_R - alpha_R(num_fluids)*(pres_R - PbwR3Rbar/R3Rbar - rho_R*R3V2Rbar/R3Rbar) end if end if $:GPU_LOOP(parallelism='[seq]') do i = 1, num_dims - flux_rs${XYZ}$_vf(j, k, l, contxe + dir_idx(i)) = & - xi_M*(rho_L*(vel_L(dir_idx(1))* & - vel_L(dir_idx(i)) + & - s_M*(xi_L*(dir_flg(dir_idx(i))*s_S + & - (1._wp - dir_flg(dir_idx(i)))* & - vel_L(dir_idx(i))) - vel_L(dir_idx(i)))) + & - dir_flg(dir_idx(i))*(pres_L)) & - + xi_P*(rho_R*(vel_R(dir_idx(1))* & - vel_R(dir_idx(i)) + & - s_P*(xi_R*(dir_flg(dir_idx(i))*s_S + & - (1._wp - dir_flg(dir_idx(i)))* & - vel_R(dir_idx(i))) - vel_R(dir_idx(i)))) + & - dir_flg(dir_idx(i))*(pres_R)) & - + (s_M/s_L)*(s_P/s_R)*dir_flg(dir_idx(i))*pcorr + flux_rs${XYZ}$_vf(j, k, l, & + & contxe + dir_idx(i)) = xi_M*(rho_L*(vel_L(dir_idx(1))*vel_L(dir_idx(i)) & + & + s_M*(xi_L*(dir_flg(dir_idx(i))*s_S + (1._wp - dir_flg(dir_idx(i))) & + & *vel_L(dir_idx(i))) - vel_L(dir_idx(i)))) + dir_flg(dir_idx(i))*(pres_L)) & + & + xi_P*(rho_R*(vel_R(dir_idx(1))*vel_R(dir_idx(i)) & + & + s_P*(xi_R*(dir_flg(dir_idx(i))*s_S + (1._wp - dir_flg(dir_idx(i))) & + & *vel_R(dir_idx(i))) - vel_R(dir_idx(i)))) + dir_flg(dir_idx(i))*(pres_R)) & + & + (s_M/s_L)*(s_P/s_R)*dir_flg(dir_idx(i))*pcorr end do - ! Energy flux. - ! f = u*(E+p), q = E, q_star = \xi*E+(s-u)(\rho s_star + p/(s-u)) - flux_rs${XYZ}$_vf(j, k, l, E_idx) = & - xi_M*(vel_L(dir_idx(1))*(E_L + pres_L) + & - s_M*(xi_L*(E_L + (s_S - vel_L(dir_idx(1)))* & - (rho_L*s_S + (pres_L)/ & - (s_L - vel_L(dir_idx(1))))) - E_L)) & - + xi_P*(vel_R(dir_idx(1))*(E_R + pres_R) + & - s_P*(xi_R*(E_R + (s_S - vel_R(dir_idx(1)))* & - (rho_R*s_S + (pres_R)/ & - (s_R - vel_R(dir_idx(1))))) - E_R)) & - + (s_M/s_L)*(s_P/s_R)*pcorr*s_S + ! Energy flux. f = u*(E+p), q = E, q_star = \xi*E+(s-u)(\rho s_star + p/(s-u)) + flux_rs${XYZ}$_vf(j, k, l, & + & E_idx) = xi_M*(vel_L(dir_idx(1))*(E_L + pres_L) + s_M*(xi_L*(E_L + (s_S & + & - vel_L(dir_idx(1)))*(rho_L*s_S + (pres_L)/(s_L - vel_L(dir_idx(1))))) - E_L)) & + & + xi_P*(vel_R(dir_idx(1))*(E_R + pres_R) + s_P*(xi_R*(E_R + (s_S & + & - vel_R(dir_idx(1)))*(rho_R*s_S + (pres_R)/(s_R - vel_R(dir_idx(1))))) - E_R)) & + & + (s_M/s_L)*(s_P/s_R)*pcorr*s_S ! Volume fraction flux $:GPU_LOOP(parallelism='[seq]') do i = advxb, advxe - flux_rs${XYZ}$_vf(j, k, l, i) = & - xi_M*qL_prim_rs${XYZ}$_vf(j, k, l, i) & - *(vel_L(dir_idx(1)) + s_M*(xi_L - 1._wp)) & - + xi_P*qR_prim_rs${XYZ}$_vf(j + 1, k, l, i) & - *(vel_R(dir_idx(1)) + s_P*(xi_R - 1._wp)) + flux_rs${XYZ}$_vf(j, k, l, i) = xi_M*qL_prim_rs${XYZ}$_vf(j, k, l, & + & i)*(vel_L(dir_idx(1)) + s_M*(xi_L - 1._wp)) + xi_P*qR_prim_rs${XYZ}$_vf(j & + & + 1, k, l, i)*(vel_R(dir_idx(1)) + s_P*(xi_R - 1._wp)) end do ! Source for volume fraction advection equation $:GPU_LOOP(parallelism='[seq]') do i = 1, num_dims - vel_src_rs${XYZ}$_vf(j, k, l, dir_idx(i)) = & - xi_M*(vel_L(dir_idx(i)) + & - dir_flg(dir_idx(i))* & - s_M*(xi_L - 1._wp)) & - + xi_P*(vel_R(dir_idx(i)) + & - dir_flg(dir_idx(i))* & - s_P*(xi_R - 1._wp)) - - !IF ( (model_eqns == 4) .or. (num_fluids==1) ) vel_src_rs_vf(dir_idx(i))%sf(j,k,l) = 0._wp + vel_src_rs${XYZ}$_vf(j, k, l, & + & dir_idx(i)) = xi_M*(vel_L(dir_idx(i)) + dir_flg(dir_idx(i))*s_M*(xi_L & + & - 1._wp)) + xi_P*(vel_R(dir_idx(i)) + dir_flg(dir_idx(i))*s_P*(xi_R & + & - 1._wp)) + + ! IF ( (model_eqns == 4) .or. (num_fluids==1) ) vel_src_rs_vf(dir_idx(i))%sf(j,k,l) = 0._wp end do flux_src_rs${XYZ}$_vf(j, k, l, advxb) = vel_src_rs${XYZ}$_vf(j, k, l, dir_idx(1)) @@ -3098,27 +2794,22 @@ contains ! Add advection flux for bubble variables $:GPU_LOOP(parallelism='[seq]') do i = bubxb, bubxe - flux_rs${XYZ}$_vf(j, k, l, i) = & - xi_M*nbub_L*qL_prim_rs${XYZ}$_vf(j, k, l, i) & - *(vel_L(dir_idx(1)) + s_M*(xi_L - 1._wp)) & - + xi_P*nbub_R*qR_prim_rs${XYZ}$_vf(j + 1, k, l, i) & - *(vel_R(dir_idx(1)) + s_P*(xi_R - 1._wp)) + flux_rs${XYZ}$_vf(j, k, l, i) = xi_M*nbub_L*qL_prim_rs${XYZ}$_vf(j, k, l, & + & i)*(vel_L(dir_idx(1)) + s_M*(xi_L - 1._wp)) & + & + xi_P*nbub_R*qR_prim_rs${XYZ}$_vf(j + 1, k, l, & + & i)*(vel_R(dir_idx(1)) + s_P*(xi_R - 1._wp)) end do if (qbmm) then - flux_rs${XYZ}$_vf(j, k, l, bubxb) = & - xi_M*nbub_L & - *(vel_L(dir_idx(1)) + s_M*(xi_L - 1._wp)) & - + xi_P*nbub_R & - *(vel_R(dir_idx(1)) + s_P*(xi_R - 1._wp)) + flux_rs${XYZ}$_vf(j, k, l, & + & bubxb) = xi_M*nbub_L*(vel_L(dir_idx(1)) + s_M*(xi_L - 1._wp)) & + & + xi_P*nbub_R*(vel_R(dir_idx(1)) + s_P*(xi_R - 1._wp)) end if if (adv_n) then - flux_rs${XYZ}$_vf(j, k, l, n_idx) = & - xi_M*nbub_L & - *(vel_L(dir_idx(1)) + s_M*(xi_L - 1._wp)) & - + xi_P*nbub_R & - *(vel_R(dir_idx(1)) + s_P*(xi_R - 1._wp)) + flux_rs${XYZ}$_vf(j, k, l, & + & n_idx) = xi_M*nbub_L*(vel_L(dir_idx(1)) + s_M*(xi_L - 1._wp)) & + & + xi_P*nbub_R*(vel_R(dir_idx(1)) + s_P*(xi_R - 1._wp)) end if ! Geometrical source flux for cylindrical coordinates @@ -3130,17 +2821,13 @@ contains flux_gsrc_rs${XYZ}$_vf(j, k, l, i) = flux_rs${XYZ}$_vf(j, k, l, i) end do ! Recalculating the radial momentum geometric source flux - flux_gsrc_rs${XYZ}$_vf(j, k, l, contxe + dir_idx(1)) = & - xi_M*(rho_L*(vel_L(dir_idx(1))* & - vel_L(dir_idx(1)) + & - s_M*(xi_L*(dir_flg(dir_idx(1))*s_S + & - (1._wp - dir_flg(dir_idx(1)))* & - vel_L(dir_idx(1))) - vel_L(dir_idx(1))))) & - + xi_P*(rho_R*(vel_R(dir_idx(1))* & - vel_R(dir_idx(1)) + & - s_P*(xi_R*(dir_flg(dir_idx(1))*s_S + & - (1._wp - dir_flg(dir_idx(1)))* & - vel_R(dir_idx(1))) - vel_R(dir_idx(1))))) + flux_gsrc_rs${XYZ}$_vf(j, k, l, & + & contxe + dir_idx(1)) = xi_M*(rho_L*(vel_L(dir_idx(1)) & + & *vel_L(dir_idx(1)) + s_M*(xi_L*(dir_flg(dir_idx(1))*s_S + (1._wp & + & - dir_flg(dir_idx(1)))*vel_L(dir_idx(1))) - vel_L(dir_idx(1))))) & + & + xi_P*(rho_R*(vel_R(dir_idx(1))*vel_R(dir_idx(1)) & + & + s_P*(xi_R*(dir_flg(dir_idx(1))*s_S + (1._wp & + & - dir_flg(dir_idx(1)))*vel_R(dir_idx(1))) - vel_R(dir_idx(1))))) ! Geometrical source of the void fraction(s) is zero $:GPU_LOOP(parallelism='[seq]') do i = advxb, advxe @@ -3155,19 +2842,14 @@ contains flux_gsrc_rs${XYZ}$_vf(j, k, l, i) = 0._wp end do - flux_gsrc_rs${XYZ}$_vf(j, k, l, momxb + 1) = & - -xi_M*(rho_L*(vel_L(dir_idx(1))* & - vel_L(dir_idx(1)) + & - s_M*(xi_L*(dir_flg(dir_idx(1))*s_S + & - (1._wp - dir_flg(dir_idx(1)))* & - vel_L(dir_idx(1))) - vel_L(dir_idx(1))))) & - - xi_P*(rho_R*(vel_R(dir_idx(1))* & - vel_R(dir_idx(1)) + & - s_P*(xi_R*(dir_flg(dir_idx(1))*s_S + & - (1._wp - dir_flg(dir_idx(1)))* & - vel_R(dir_idx(1))) - vel_R(dir_idx(1))))) + flux_gsrc_rs${XYZ}$_vf(j, k, l, & + & momxb + 1) = -xi_M*(rho_L*(vel_L(dir_idx(1))*vel_L(dir_idx(1)) & + & + s_M*(xi_L*(dir_flg(dir_idx(1))*s_S + (1._wp & + & - dir_flg(dir_idx(1)))*vel_L(dir_idx(1))) - vel_L(dir_idx(1))))) & + & - xi_P*(rho_R*(vel_R(dir_idx(1))*vel_R(dir_idx(1)) & + & + s_P*(xi_R*(dir_flg(dir_idx(1))*s_S + (1._wp & + & - dir_flg(dir_idx(1)))*vel_R(dir_idx(1))) - vel_R(dir_idx(1))))) flux_gsrc_rs${XYZ}$_vf(j, k, l, momxe) = flux_rs${XYZ}$_vf(j, k, l, momxb + 1) - end if #:endif end do @@ -3176,11 +2858,17 @@ contains $:END_GPU_PARALLEL_LOOP() else ! 5-EQUATION MODEL WITH HLLC - $:GPU_PARALLEL_LOOP(collapse=3, private='[Re_max, i, q, T_L, T_R, vel_L_rms, vel_R_rms, pres_L, pres_R, rho_L, gamma_L, pi_inf_L, qv_L, rho_R, gamma_R, pi_inf_R, qv_R, alpha_L_sum, alpha_R_sum, E_L, E_R, MW_L, MW_R, R_gas_L, R_gas_R, Cp_L, Cp_R, Cv_L, Cv_R, Gamm_L, Gamm_R, Y_L, Y_R, H_L, H_R, qv_avg, rho_avg, gamma_avg, H_avg, c_L, c_R, c_avg, s_P, s_M, xi_P, xi_M, xi_L, xi_R, Ms_L, Ms_R, pres_SL, pres_SR, vel_L, vel_R, Re_L, Re_R, alpha_L, alpha_R, s_L, s_R, s_S, vel_avg_rms, pcorr, zcoef, vel_L_tmp, vel_R_tmp, Ys_L, Ys_R, Xs_L, Xs_R, Gamma_iL, Gamma_iR, Cp_iL, Cp_iR, tau_e_L, tau_e_R, xi_field_L, xi_field_R, Yi_avg,Phi_avg, h_iL, h_iR, h_avg_2, G_L, G_R]', copyin='[is1, is2, is3]') + $:GPU_PARALLEL_LOOP(collapse=3, private='[Re_max, i, q, T_L, T_R, vel_L_rms, vel_R_rms, pres_L, pres_R, & + & rho_L, gamma_L, pi_inf_L, qv_L, rho_R, gamma_R, pi_inf_R, qv_R, alpha_L_sum, & + & alpha_R_sum, E_L, E_R, MW_L, MW_R, R_gas_L, R_gas_R, Cp_L, Cp_R, Cv_L, Cv_R, Gamm_L, & + & Gamm_R, Y_L, Y_R, H_L, H_R, qv_avg, rho_avg, gamma_avg, H_avg, c_L, c_R, c_avg, s_P, & + & s_M, xi_P, xi_M, xi_L, xi_R, Ms_L, Ms_R, pres_SL, pres_SR, vel_L, vel_R, Re_L, Re_R, & + & alpha_L, alpha_R, s_L, s_R, s_S, vel_avg_rms, pcorr, zcoef, vel_L_tmp, vel_R_tmp, Ys_L, & + & Ys_R, Xs_L, Xs_R, Gamma_iL, Gamma_iR, Cp_iL, Cp_iR, tau_e_L, tau_e_R, xi_field_L, & + & xi_field_R, Yi_avg, Phi_avg, h_iL, h_iR, h_avg_2, G_L, G_R]', copyin='[is1, is2, is3]') do l = is3%beg, is3%end do k = is2%beg, is2%end do j = is1%beg, is1%end - vel_L_rms = 0._wp; vel_R_rms = 0._wp rho_L = 0._wp; rho_R = 0._wp gamma_L = 0._wp; gamma_R = 0._wp @@ -3205,23 +2893,26 @@ contains pres_L = qL_prim_rs${XYZ}$_vf(j, k, l, E_idx) pres_R = qR_prim_rs${XYZ}$_vf(j + 1, k, l, E_idx) - ! Change this by splitting it into the cases - ! present in the bubbles_euler + ! Change this by splitting it into the cases present in the bubbles_euler if (mpp_lim) then $:GPU_LOOP(parallelism='[seq]') do i = 1, num_fluids qL_prim_rs${XYZ}$_vf(j, k, l, i) = max(0._wp, qL_prim_rs${XYZ}$_vf(j, k, l, i)) - qL_prim_rs${XYZ}$_vf(j, k, l, E_idx + i) = min(max(0._wp, qL_prim_rs${XYZ}$_vf(j, k, l, E_idx + i)), 1._wp) + qL_prim_rs${XYZ}$_vf(j, k, l, E_idx + i) = min(max(0._wp, qL_prim_rs${XYZ}$_vf(j, k, l, & + & E_idx + i)), 1._wp) qR_prim_rs${XYZ}$_vf(j + 1, k, l, i) = max(0._wp, qR_prim_rs${XYZ}$_vf(j + 1, k, l, i)) - qR_prim_rs${XYZ}$_vf(j + 1, k, l, E_idx + i) = min(max(0._wp, qR_prim_rs${XYZ}$_vf(j + 1, k, l, E_idx + i)), 1._wp) + qR_prim_rs${XYZ}$_vf(j + 1, k, l, E_idx + i) = min(max(0._wp, qR_prim_rs${XYZ}$_vf(j + 1, & + & k, l, E_idx + i)), 1._wp) alpha_L_sum = alpha_L_sum + qL_prim_rs${XYZ}$_vf(j, k, l, E_idx + i) alpha_R_sum = alpha_R_sum + qR_prim_rs${XYZ}$_vf(j + 1, k, l, E_idx + i) end do $:GPU_LOOP(parallelism='[seq]') do i = 1, num_fluids - qL_prim_rs${XYZ}$_vf(j, k, l, E_idx + i) = qL_prim_rs${XYZ}$_vf(j, k, l, E_idx + i)/max(alpha_L_sum, sgm_eps) - qR_prim_rs${XYZ}$_vf(j + 1, k, l, E_idx + i) = qR_prim_rs${XYZ}$_vf(j + 1, k, l, E_idx + i)/max(alpha_R_sum, sgm_eps) + qL_prim_rs${XYZ}$_vf(j, k, l, E_idx + i) = qL_prim_rs${XYZ}$_vf(j, k, l, & + & E_idx + i)/max(alpha_L_sum, sgm_eps) + qR_prim_rs${XYZ}$_vf(j + 1, k, l, E_idx + i) = qR_prim_rs${XYZ}$_vf(j + 1, k, l, & + & E_idx + i)/max(alpha_R_sum, sgm_eps) end do end if @@ -3250,10 +2941,8 @@ contains $:GPU_LOOP(parallelism='[seq]') do q = 1, Re_size(i) - Re_L(i) = alpha_L(Re_idx(i, q))/Res_gs(i, q) & - + Re_L(i) - Re_R(i) = alpha_R(Re_idx(i, q))/Res_gs(i, q) & - + Re_R(i) + Re_L(i) = alpha_L(Re_idx(i, q))/Res_gs(i, q) + Re_L(i) + Re_R(i) = alpha_R(Re_idx(i, q))/Res_gs(i, q) + Re_R(i) end do Re_L(i) = 1._wp/max(Re_L(i), sgm_eps) @@ -3383,16 +3072,16 @@ contains @:compute_average_state() - call s_compute_speed_of_sound(pres_L, rho_L, gamma_L, pi_inf_L, H_L, alpha_L, & - vel_L_rms, 0._wp, c_L, qv_L) + call s_compute_speed_of_sound(pres_L, rho_L, gamma_L, pi_inf_L, H_L, alpha_L, vel_L_rms, 0._wp, & + & c_L, qv_L) - call s_compute_speed_of_sound(pres_R, rho_R, gamma_R, pi_inf_R, H_R, alpha_R, & - vel_R_rms, 0._wp, c_R, qv_R) + call s_compute_speed_of_sound(pres_R, rho_R, gamma_R, pi_inf_R, H_R, alpha_R, vel_R_rms, 0._wp, & + & c_R, qv_R) !> The computation of c_avg does not require all the variables, and therefore the non '_avg' ! variables are placeholders to call the subroutine. - call s_compute_speed_of_sound(pres_R, rho_avg, gamma_avg, pi_inf_R, H_avg, alpha_R, & - vel_avg_rms, c_sum_Yi_Phi, c_avg, qv_avg) + call s_compute_speed_of_sound(pres_R, rho_avg, gamma_avg, pi_inf_R, H_avg, alpha_R, vel_avg_rms, & + & c_sum_Yi_Phi, c_avg, qv_avg) if (viscous) then if (chemistry) then @@ -3411,57 +3100,51 @@ contains if (wave_speeds == 1) then if (elasticity) then - s_L = min(vel_L(dir_idx(1)) - sqrt(c_L*c_L + & - (((4._wp*G_L)/3._wp) + tau_e_L(dir_idx_tau(1)))/rho_L), vel_R(dir_idx(1)) - sqrt(c_R*c_R + & - (((4._wp*G_R)/3._wp) + tau_e_R(dir_idx_tau(1)))/rho_R)) - s_R = max(vel_R(dir_idx(1)) + sqrt(c_R*c_R + & - (((4._wp*G_R)/3._wp) + tau_e_R(dir_idx_tau(1)))/rho_R), vel_L(dir_idx(1)) + sqrt(c_L*c_L + & - (((4._wp*G_L)/3._wp) + tau_e_L(dir_idx_tau(1)))/rho_L)) - s_S = (pres_R - tau_e_R(dir_idx_tau(1)) - pres_L + & - tau_e_L(dir_idx_tau(1)) + rho_L*vel_L(dir_idx(1))*(s_L - vel_L(dir_idx(1))) - & - rho_R*vel_R(dir_idx(1))*(s_R - vel_R(dir_idx(1))))/(rho_L*(s_L - vel_L(dir_idx(1))) - & - rho_R*(s_R - vel_R(dir_idx(1)))) + s_L = min(vel_L(dir_idx(1)) - sqrt(c_L*c_L + (((4._wp*G_L)/3._wp) + tau_e_L(dir_idx_tau(1) & + & ))/rho_L), & + & vel_R(dir_idx(1)) - sqrt(c_R*c_R + (((4._wp*G_R)/3._wp) & + & + tau_e_R(dir_idx_tau(1)))/rho_R)) + s_R = max(vel_R(dir_idx(1)) + sqrt(c_R*c_R + (((4._wp*G_R)/3._wp) + tau_e_R(dir_idx_tau(1) & + & ))/rho_R), & + & vel_L(dir_idx(1)) + sqrt(c_L*c_L + (((4._wp*G_L)/3._wp) & + & + tau_e_L(dir_idx_tau(1)))/rho_L)) + s_S = (pres_R - tau_e_R(dir_idx_tau(1)) - pres_L + tau_e_L(dir_idx_tau(1)) & + & + rho_L*vel_L(dir_idx(1))*(s_L - vel_L(dir_idx(1))) - rho_R*vel_R(dir_idx(1)) & + & *(s_R - vel_R(dir_idx(1))))/(rho_L*(s_L - vel_L(dir_idx(1))) - rho_R*(s_R & + & - vel_R(dir_idx(1)))) else s_L = min(vel_L(dir_idx(1)) - c_L, vel_R(dir_idx(1)) - c_R) s_R = max(vel_R(dir_idx(1)) + c_R, vel_L(dir_idx(1)) + c_L) - s_S = (pres_R - pres_L + rho_L*vel_L(dir_idx(1))* & - (s_L - vel_L(dir_idx(1))) - rho_R*vel_R(dir_idx(1))*(s_R - vel_R(dir_idx(1)))) & - /(rho_L*(s_L - vel_L(dir_idx(1))) - rho_R*(s_R - vel_R(dir_idx(1)))) - + s_S = (pres_R - pres_L + rho_L*vel_L(dir_idx(1))*(s_L - vel_L(dir_idx(1))) & + & - rho_R*vel_R(dir_idx(1))*(s_R - vel_R(dir_idx(1))))/(rho_L*(s_L & + & - vel_L(dir_idx(1))) - rho_R*(s_R - vel_R(dir_idx(1)))) end if - elseif (wave_speeds == 2) then - pres_SL = 5.e-1_wp*(pres_L + pres_R + rho_avg*c_avg* & - (vel_L(dir_idx(1)) - & - vel_R(dir_idx(1)))) + else if (wave_speeds == 2) then + pres_SL = 5.e-1_wp*(pres_L + pres_R + rho_avg*c_avg*(vel_L(dir_idx(1)) - vel_R(dir_idx(1)))) pres_SR = pres_SL - Ms_L = max(1._wp, sqrt(1._wp + ((5.e-1_wp + gamma_L)/(1._wp + gamma_L))* & - (pres_SL/pres_L - 1._wp)*pres_L/ & - ((pres_L + pi_inf_L/(1._wp + gamma_L))))) - Ms_R = max(1._wp, sqrt(1._wp + ((5.e-1_wp + gamma_R)/(1._wp + gamma_R))* & - (pres_SR/pres_R - 1._wp)*pres_R/ & - ((pres_R + pi_inf_R/(1._wp + gamma_R))))) + Ms_L = max(1._wp, & + & sqrt(1._wp + ((5.e-1_wp + gamma_L)/(1._wp + gamma_L))*(pres_SL/pres_L - 1._wp) & + & *pres_L/((pres_L + pi_inf_L/(1._wp + gamma_L))))) + Ms_R = max(1._wp, & + & sqrt(1._wp + ((5.e-1_wp + gamma_R)/(1._wp + gamma_R))*(pres_SR/pres_R - 1._wp) & + & *pres_R/((pres_R + pi_inf_R/(1._wp + gamma_R))))) s_L = vel_L(dir_idx(1)) - c_L*Ms_L s_R = vel_R(dir_idx(1)) + c_R*Ms_R - s_S = 5.e-1_wp*((vel_L(dir_idx(1)) + vel_R(dir_idx(1))) + & - (pres_L - pres_R)/ & - (rho_avg*c_avg)) + s_S = 5.e-1_wp*((vel_L(dir_idx(1)) + vel_R(dir_idx(1))) + (pres_L - pres_R)/(rho_avg*c_avg)) end if - ! follows Einfeldt et al. - ! s_M/P = min/max(0.,s_L/R) + ! follows Einfeldt et al. s_M/P = min/max(0.,s_L/R) s_M = min(0._wp, s_L); s_P = max(0._wp, s_R) - ! goes with q_star_L/R = xi_L/R * (variable) - ! xi_L/R = ( ( s_L/R - u_L/R )/(s_L/R - s_star) ) + ! goes with q_star_L/R = xi_L/R * (variable) xi_L/R = ( ( s_L/R - u_L/R )/(s_L/R - s_star) ) xi_L = (s_L - vel_L(dir_idx(1)))/(s_L - s_S) xi_R = (s_R - vel_R(dir_idx(1)))/(s_R - s_S) - ! goes with numerical velocity in x/y/z directions - ! xi_P/M = 0.5 +/m sgn(0.5,s_star) + ! goes with numerical velocity in x/y/z directions xi_P/M = 0.5 +/m sgn(0.5,s_star) xi_M = (5.e-1_wp + sign(5.e-1_wp, s_S)) xi_P = (5.e-1_wp - sign(5.e-1_wp, s_S)) @@ -3472,49 +3155,34 @@ contains pcorr = 0._wp end if - ! COMPUTING THE HLLC FLUXES - ! MASS FLUX. + ! COMPUTING THE HLLC FLUXES MASS FLUX. $:GPU_LOOP(parallelism='[seq]') do i = 1, contxe - flux_rs${XYZ}$_vf(j, k, l, i) = & - xi_M*qL_prim_rs${XYZ}$_vf(j, k, l, i) & - *(vel_L(dir_idx(1)) + s_M*(xi_L - 1._wp)) & - + xi_P*qR_prim_rs${XYZ}$_vf(j + 1, k, l, i) & - *(vel_R(dir_idx(1)) + s_P*(xi_R - 1._wp)) + flux_rs${XYZ}$_vf(j, k, l, i) = xi_M*qL_prim_rs${XYZ}$_vf(j, k, l, & + & i)*(vel_L(dir_idx(1)) + s_M*(xi_L - 1._wp)) + xi_P*qR_prim_rs${XYZ}$_vf(j & + & + 1, k, l, i)*(vel_R(dir_idx(1)) + s_P*(xi_R - 1._wp)) end do - ! MOMENTUM FLUX. - ! f = \rho u u - \sigma, q = \rho u, q_star = \xi * \rho*(s_star, v, w) + ! MOMENTUM FLUX. f = \rho u u - \sigma, q = \rho u, q_star = \xi * \rho*(s_star, v, w) $:GPU_LOOP(parallelism='[seq]') do i = 1, num_dims - flux_rs${XYZ}$_vf(j, k, l, contxe + dir_idx(i)) = & - xi_M*(rho_L*(vel_L(dir_idx(1))* & - vel_L(dir_idx(i)) + & - s_M*(xi_L*(dir_flg(dir_idx(i))*s_S + & - (1._wp - dir_flg(dir_idx(i)))* & - vel_L(dir_idx(i))) - vel_L(dir_idx(i)))) + & - dir_flg(dir_idx(i))*(pres_L)) & - + xi_P*(rho_R*(vel_R(dir_idx(1))* & - vel_R(dir_idx(i)) + & - s_P*(xi_R*(dir_flg(dir_idx(i))*s_S + & - (1._wp - dir_flg(dir_idx(i)))* & - vel_R(dir_idx(i))) - vel_R(dir_idx(i)))) + & - dir_flg(dir_idx(i))*(pres_R)) & - + (s_M/s_L)*(s_P/s_R)*dir_flg(dir_idx(i))*pcorr + flux_rs${XYZ}$_vf(j, k, l, & + & contxe + dir_idx(i)) = xi_M*(rho_L*(vel_L(dir_idx(1))*vel_L(dir_idx(i)) & + & + s_M*(xi_L*(dir_flg(dir_idx(i))*s_S + (1._wp - dir_flg(dir_idx(i))) & + & *vel_L(dir_idx(i))) - vel_L(dir_idx(i)))) + dir_flg(dir_idx(i))*(pres_L)) & + & + xi_P*(rho_R*(vel_R(dir_idx(1))*vel_R(dir_idx(i)) & + & + s_P*(xi_R*(dir_flg(dir_idx(i))*s_S + (1._wp - dir_flg(dir_idx(i))) & + & *vel_R(dir_idx(i))) - vel_R(dir_idx(i)))) + dir_flg(dir_idx(i))*(pres_R)) & + & + (s_M/s_L)*(s_P/s_R)*dir_flg(dir_idx(i))*pcorr end do - ! ENERGY FLUX. - ! f = u*(E-\sigma), q = E, q_star = \xi*E+(s-u)(\rho s_star - \sigma/(s-u)) - flux_rs${XYZ}$_vf(j, k, l, E_idx) = & - xi_M*(vel_L(dir_idx(1))*(E_L + pres_L) + & - s_M*(xi_L*(E_L + (s_S - vel_L(dir_idx(1)))* & - (rho_L*s_S + pres_L/ & - (s_L - vel_L(dir_idx(1))))) - E_L)) & - + xi_P*(vel_R(dir_idx(1))*(E_R + pres_R) + & - s_P*(xi_R*(E_R + (s_S - vel_R(dir_idx(1)))* & - (rho_R*s_S + pres_R/ & - (s_R - vel_R(dir_idx(1))))) - E_R)) & - + (s_M/s_L)*(s_P/s_R)*pcorr*s_S + ! ENERGY FLUX. f = u*(E-\sigma), q = E, q_star = \xi*E+(s-u)(\rho s_star - \sigma/(s-u)) + flux_rs${XYZ}$_vf(j, k, l, & + & E_idx) = xi_M*(vel_L(dir_idx(1))*(E_L + pres_L) + s_M*(xi_L*(E_L + (s_S & + & - vel_L(dir_idx(1)))*(rho_L*s_S + pres_L/(s_L - vel_L(dir_idx(1))))) - E_L)) & + & + xi_P*(vel_R(dir_idx(1))*(E_R + pres_R) + s_P*(xi_R*(E_R + (s_S & + & - vel_R(dir_idx(1)))*(rho_R*s_S + pres_R/(s_R - vel_R(dir_idx(1))))) - E_R)) & + & + (s_M/s_L)*(s_P/s_R)*pcorr*s_S ! ELASTICITY. Elastic shear stress additions for the momentum and energy flux if (elasticity) then @@ -3522,15 +3190,15 @@ contains $:GPU_LOOP(parallelism='[seq]') do i = 1, num_dims ! MOMENTUM ELASTIC FLUX. - flux_rs${XYZ}$_vf(j, k, l, contxe + dir_idx(i)) = & - flux_rs${XYZ}$_vf(j, k, l, contxe + dir_idx(i)) & - - xi_M*tau_e_L(dir_idx_tau(i)) - xi_P*tau_e_R(dir_idx_tau(i)) + flux_rs${XYZ}$_vf(j, k, l, contxe + dir_idx(i)) = flux_rs${XYZ}$_vf(j, k, l, & + & contxe + dir_idx(i)) - xi_M*tau_e_L(dir_idx_tau(i)) & + & - xi_P*tau_e_R(dir_idx_tau(i)) ! ENERGY ELASTIC FLUX. - flux_ene_e = flux_ene_e - & - xi_M*(vel_L(dir_idx(i))*tau_e_L(dir_idx_tau(i)) + & - s_M*(xi_L*((s_S - vel_L(i))*(tau_e_L(dir_idx_tau(i))/(s_L - vel_L(i)))))) - & - xi_P*(vel_R(dir_idx(i))*tau_e_R(dir_idx_tau(i)) + & - s_P*(xi_R*((s_S - vel_R(i))*(tau_e_R(dir_idx_tau(i))/(s_R - vel_R(i)))))) + flux_ene_e = flux_ene_e - xi_M*(vel_L(dir_idx(i))*tau_e_L(dir_idx_tau(i)) & + & + s_M*(xi_L*((s_S - vel_L(i))*(tau_e_L(dir_idx_tau(i)) & + & /(s_L - vel_L(i)))))) - xi_P*(vel_R(dir_idx(i)) & + & *tau_e_R(dir_idx_tau(i)) + s_P*(xi_R*((s_S - vel_R(i)) & + & *(tau_e_R(dir_idx_tau(i))/(s_R - vel_R(i)))))) end do flux_rs${XYZ}$_vf(j, k, l, E_idx) = flux_rs${XYZ}$_vf(j, k, l, E_idx) + flux_ene_e end if @@ -3539,52 +3207,46 @@ contains if (hypoelasticity) then $:GPU_LOOP(parallelism='[seq]') do i = 1, strxe - strxb + 1 - flux_rs${XYZ}$_vf(j, k, l, strxb - 1 + i) = & - xi_M*(s_S/(s_L - s_S))*(s_L*rho_L*tau_e_L(i) - rho_L*vel_L(dir_idx(1))*tau_e_L(i)) + & - xi_P*(s_S/(s_R - s_S))*(s_R*rho_R*tau_e_R(i) - rho_R*vel_R(dir_idx(1))*tau_e_R(i)) + flux_rs${XYZ}$_vf(j, k, l, & + & strxb - 1 + i) = xi_M*(s_S/(s_L - s_S))*(s_L*rho_L*tau_e_L(i) & + & - rho_L*vel_L(dir_idx(1))*tau_e_L(i)) + xi_P*(s_S/(s_R - s_S)) & + & *(s_R*rho_R*tau_e_R(i) - rho_R*vel_R(dir_idx(1))*tau_e_R(i)) end do end if ! VOLUME FRACTION FLUX. $:GPU_LOOP(parallelism='[seq]') do i = advxb, advxe - flux_rs${XYZ}$_vf(j, k, l, i) = & - xi_M*qL_prim_rs${XYZ}$_vf(j, k, l, i) & - *(vel_L(dir_idx(1)) + s_M*(xi_L - 1._wp)) & - + xi_P*qR_prim_rs${XYZ}$_vf(j + 1, k, l, i) & - *(vel_R(dir_idx(1)) + s_P*(xi_R - 1._wp)) + flux_rs${XYZ}$_vf(j, k, l, i) = xi_M*qL_prim_rs${XYZ}$_vf(j, k, l, & + & i)*(vel_L(dir_idx(1)) + s_M*(xi_L - 1._wp)) + xi_P*qR_prim_rs${XYZ}$_vf(j & + & + 1, k, l, i)*(vel_R(dir_idx(1)) + s_P*(xi_R - 1._wp)) end do ! VOLUME FRACTION SOURCE FLUX. $:GPU_LOOP(parallelism='[seq]') do i = 1, num_dims - vel_src_rs${XYZ}$_vf(j, k, l, dir_idx(i)) = & - xi_M*(vel_L(dir_idx(i)) + & - dir_flg(dir_idx(i))* & - s_M*(xi_L - 1._wp)) & - + xi_P*(vel_R(dir_idx(i)) + & - dir_flg(dir_idx(i))* & - s_P*(xi_R - 1._wp)) + vel_src_rs${XYZ}$_vf(j, k, l, & + & dir_idx(i)) = xi_M*(vel_L(dir_idx(i)) + dir_flg(dir_idx(i))*s_M*(xi_L & + & - 1._wp)) + xi_P*(vel_R(dir_idx(i)) + dir_flg(dir_idx(i))*s_P*(xi_R & + & - 1._wp)) end do ! COLOR FUNCTION FLUX if (surface_tension) then - flux_rs${XYZ}$_vf(j, k, l, c_idx) = & - xi_M*qL_prim_rs${XYZ}$_vf(j, k, l, c_idx) & - *(vel_L(dir_idx(1)) + s_M*(xi_L - 1._wp)) & - + xi_P*qR_prim_rs${XYZ}$_vf(j + 1, k, l, c_idx) & - *(vel_R(dir_idx(1)) + s_P*(xi_R - 1._wp)) + flux_rs${XYZ}$_vf(j, k, l, c_idx) = xi_M*qL_prim_rs${XYZ}$_vf(j, k, l, & + & c_idx)*(vel_L(dir_idx(1)) + s_M*(xi_L - 1._wp)) & + & + xi_P*qR_prim_rs${XYZ}$_vf(j + 1, k, l, & + & c_idx)*(vel_R(dir_idx(1)) + s_P*(xi_R - 1._wp)) end if ! REFERENCE MAP FLUX. if (hyperelasticity) then $:GPU_LOOP(parallelism='[seq]') do i = 1, num_dims - flux_rs${XYZ}$_vf(j, k, l, xibeg - 1 + i) = & - xi_M*(s_S/(s_L - s_S))*(s_L*rho_L*xi_field_L(i) & - - rho_L*vel_L(dir_idx(1))*xi_field_L(i)) + & - xi_P*(s_S/(s_R - s_S))*(s_R*rho_R*xi_field_R(i) & - - rho_R*vel_R(dir_idx(1))*xi_field_R(i)) + flux_rs${XYZ}$_vf(j, k, l, & + & xibeg - 1 + i) = xi_M*(s_S/(s_L - s_S))*(s_L*rho_L*xi_field_L(i) & + & - rho_L*vel_L(dir_idx(1))*xi_field_L(i)) + xi_P*(s_S/(s_R - s_S)) & + & *(s_R*rho_R*xi_field_R(i) - rho_R*vel_R(dir_idx(1))*xi_field_R(i)) end do end if @@ -3596,8 +3258,9 @@ contains Y_L = qL_prim_rs${XYZ}$_vf(j, k, l, i) Y_R = qR_prim_rs${XYZ}$_vf(j + 1, k, l, i) - flux_rs${XYZ}$_vf(j, k, l, i) = xi_M*rho_L*Y_L*(vel_L(dir_idx(1)) + s_M*(xi_L - 1._wp)) & - + xi_P*rho_R*Y_R*(vel_R(dir_idx(1)) + s_P*(xi_R - 1._wp)) + flux_rs${XYZ}$_vf(j, k, l, & + & i) = xi_M*rho_L*Y_L*(vel_L(dir_idx(1)) + s_M*(xi_L - 1._wp)) & + & + xi_P*rho_R*Y_R*(vel_R(dir_idx(1)) + s_P*(xi_R - 1._wp)) flux_src_rs${XYZ}$_vf(j, k, l, i) = 0.0_wp end do end if @@ -3605,23 +3268,19 @@ contains ! Geometrical source flux for cylindrical coordinates #:if (NORM_DIR == 2) if (cyl_coord) then - !Substituting the advective flux into the inviscid geometrical source flux + ! Substituting the advective flux into the inviscid geometrical source flux $:GPU_LOOP(parallelism='[seq]') do i = 1, E_idx flux_gsrc_rs${XYZ}$_vf(j, k, l, i) = flux_rs${XYZ}$_vf(j, k, l, i) end do ! Recalculating the radial momentum geometric source flux - flux_gsrc_rs${XYZ}$_vf(j, k, l, contxe + dir_idx(1)) = & - xi_M*(rho_L*(vel_L(dir_idx(1))* & - vel_L(dir_idx(1)) + & - s_M*(xi_L*(dir_flg(dir_idx(1))*s_S + & - (1._wp - dir_flg(dir_idx(1)))* & - vel_L(dir_idx(1))) - vel_L(dir_idx(1))))) & - + xi_P*(rho_R*(vel_R(dir_idx(1))* & - vel_R(dir_idx(1)) + & - s_P*(xi_R*(dir_flg(dir_idx(1))*s_S + & - (1._wp - dir_flg(dir_idx(1)))* & - vel_R(dir_idx(1))) - vel_R(dir_idx(1))))) + flux_gsrc_rs${XYZ}$_vf(j, k, l, & + & contxe + dir_idx(1)) = xi_M*(rho_L*(vel_L(dir_idx(1)) & + & *vel_L(dir_idx(1)) + s_M*(xi_L*(dir_flg(dir_idx(1))*s_S + (1._wp & + & - dir_flg(dir_idx(1)))*vel_L(dir_idx(1))) - vel_L(dir_idx(1))))) & + & + xi_P*(rho_R*(vel_R(dir_idx(1))*vel_R(dir_idx(1)) & + & + s_P*(xi_R*(dir_flg(dir_idx(1))*s_S + (1._wp & + & - dir_flg(dir_idx(1)))*vel_R(dir_idx(1))) - vel_R(dir_idx(1))))) ! Geometrical source of the void fraction(s) is zero $:GPU_LOOP(parallelism='[seq]') do i = advxb, advxe @@ -3636,22 +3295,16 @@ contains flux_gsrc_rs${XYZ}$_vf(j, k, l, i) = 0._wp end do - flux_gsrc_rs${XYZ}$_vf(j, k, l, momxb + 1) = & - -xi_M*(rho_L*(vel_L(dir_idx(1))* & - vel_L(dir_idx(1)) + & - s_M*(xi_L*(dir_flg(dir_idx(1))*s_S + & - (1._wp - dir_flg(dir_idx(1)))* & - vel_L(dir_idx(1))) - vel_L(dir_idx(1))))) & - - xi_P*(rho_R*(vel_R(dir_idx(1))* & - vel_R(dir_idx(1)) + & - s_P*(xi_R*(dir_flg(dir_idx(1))*s_S + & - (1._wp - dir_flg(dir_idx(1)))* & - vel_R(dir_idx(1))) - vel_R(dir_idx(1))))) + flux_gsrc_rs${XYZ}$_vf(j, k, l, & + & momxb + 1) = -xi_M*(rho_L*(vel_L(dir_idx(1))*vel_L(dir_idx(1)) & + & + s_M*(xi_L*(dir_flg(dir_idx(1))*s_S + (1._wp & + & - dir_flg(dir_idx(1)))*vel_L(dir_idx(1))) - vel_L(dir_idx(1))))) & + & - xi_P*(rho_R*(vel_R(dir_idx(1))*vel_R(dir_idx(1)) & + & + s_P*(xi_R*(dir_flg(dir_idx(1))*s_S + (1._wp & + & - dir_flg(dir_idx(1)))*vel_R(dir_idx(1))) - vel_R(dir_idx(1))))) flux_gsrc_rs${XYZ}$_vf(j, k, l, momxe) = flux_rs${XYZ}$_vf(j, k, l, momxb + 1) - end if #:endif - end do end do end do @@ -3663,120 +3316,93 @@ contains if (viscous .or. dummy) then if (weno_Re_flux) then - call s_compute_viscous_source_flux( & - qL_prim_vf(momxb:momxe), & - dqL_prim_dx_vf(momxb:momxe), & - dqL_prim_dy_vf(momxb:momxe), & - dqL_prim_dz_vf(momxb:momxe), & - qR_prim_vf(momxb:momxe), & - dqR_prim_dx_vf(momxb:momxe), & - dqR_prim_dy_vf(momxb:momxe), & - dqR_prim_dz_vf(momxb:momxe), & - flux_src_vf, norm_dir, ix, iy, iz) + call s_compute_viscous_source_flux(qL_prim_vf(momxb:momxe), dqL_prim_dx_vf(momxb:momxe), & + & dqL_prim_dy_vf(momxb:momxe), dqL_prim_dz_vf(momxb:momxe), & + & qR_prim_vf(momxb:momxe), dqR_prim_dx_vf(momxb:momxe), & + & dqR_prim_dy_vf(momxb:momxe), dqR_prim_dz_vf(momxb:momxe), flux_src_vf, & + & norm_dir, ix, iy, iz) else - call s_compute_viscous_source_flux( & - q_prim_vf(momxb:momxe), & - dqL_prim_dx_vf(momxb:momxe), & - dqL_prim_dy_vf(momxb:momxe), & - dqL_prim_dz_vf(momxb:momxe), & - q_prim_vf(momxb:momxe), & - dqR_prim_dx_vf(momxb:momxe), & - dqR_prim_dy_vf(momxb:momxe), & - dqR_prim_dz_vf(momxb:momxe), & - flux_src_vf, norm_dir, ix, iy, iz) + call s_compute_viscous_source_flux(q_prim_vf(momxb:momxe), dqL_prim_dx_vf(momxb:momxe), & + & dqL_prim_dy_vf(momxb:momxe), dqL_prim_dz_vf(momxb:momxe), & + & q_prim_vf(momxb:momxe), dqR_prim_dx_vf(momxb:momxe), & + & dqR_prim_dy_vf(momxb:momxe), dqR_prim_dz_vf(momxb:momxe), flux_src_vf, & + & norm_dir, ix, iy, iz) end if end if if (surface_tension) then - call s_compute_capillary_source_flux( & - vel_src_rsx_vf, & - vel_src_rsy_vf, & - vel_src_rsz_vf, & - flux_src_vf, & - norm_dir, isx, isy, isz) + call s_compute_capillary_source_flux(vel_src_rsx_vf, vel_src_rsy_vf, vel_src_rsz_vf, flux_src_vf, norm_dir, isx, isy, & + & isz) end if - call s_finalize_riemann_solver(flux_vf, flux_src_vf, & - flux_gsrc_vf, & - norm_dir) + call s_finalize_riemann_solver(flux_vf, flux_src_vf, flux_gsrc_vf, norm_dir) end subroutine s_hllc_riemann_solver - !> HLLD Riemann solver resolves 5 of the 7 waves of MHD equations: - !! 1 entropy wave, 2 Alfvén waves, 2 fast magnetosonic waves. - subroutine s_hlld_riemann_solver(qL_prim_rsx_vf, qL_prim_rsy_vf, qL_prim_rsz_vf, & - dqL_prim_dx_vf, dqL_prim_dy_vf, dqL_prim_dz_vf, & - qL_prim_vf, & - qR_prim_rsx_vf, qR_prim_rsy_vf, qR_prim_rsz_vf, & - dqR_prim_dx_vf, dqR_prim_dy_vf, dqR_prim_dz_vf, & - qR_prim_vf, & - q_prim_vf, & - flux_vf, flux_src_vf, flux_gsrc_vf, & - norm_dir, ix, iy, iz) - - real(wp), dimension(idwbuff(1)%beg:, idwbuff(2)%beg:, idwbuff(3)%beg:, 1:), intent(inout) :: qL_prim_rsx_vf, qL_prim_rsy_vf, qL_prim_rsz_vf, & - qR_prim_rsx_vf, qR_prim_rsy_vf, qR_prim_rsz_vf - - type(scalar_field), allocatable, dimension(:), intent(inout) :: dqL_prim_dx_vf, dqR_prim_dx_vf, & - dqL_prim_dy_vf, dqR_prim_dy_vf, & - dqL_prim_dz_vf, dqR_prim_dz_vf + !> HLLD Riemann solver resolves 5 of the 7 waves of MHD equations: 1 entropy wave, 2 Alfven waves, 2 fast magnetosonic waves. + subroutine s_hlld_riemann_solver(qL_prim_rsx_vf, qL_prim_rsy_vf, qL_prim_rsz_vf, dqL_prim_dx_vf, dqL_prim_dy_vf, & + & dqL_prim_dz_vf, qL_prim_vf, qR_prim_rsx_vf, qR_prim_rsy_vf, qR_prim_rsz_vf, & + & dqR_prim_dx_vf, dqR_prim_dy_vf, dqR_prim_dz_vf, qR_prim_vf, q_prim_vf, flux_vf, & + & flux_src_vf, flux_gsrc_vf, norm_dir, ix, iy, iz) - type(scalar_field), allocatable, dimension(:), intent(inout) :: qL_prim_vf, qR_prim_vf + real(wp), dimension(idwbuff(1)%beg:,idwbuff(2)%beg:,idwbuff(3)%beg:,1:), intent(inout) :: qL_prim_rsx_vf, qL_prim_rsy_vf, & + & qL_prim_rsz_vf, qR_prim_rsx_vf, qR_prim_rsy_vf, qR_prim_rsz_vf - type(scalar_field), dimension(sys_size), intent(in) :: q_prim_vf - type(scalar_field), dimension(sys_size), intent(inout) :: flux_vf, flux_src_vf, flux_gsrc_vf + type(scalar_field), allocatable, dimension(:), intent(inout) :: dqL_prim_dx_vf, dqR_prim_dx_vf, dqL_prim_dy_vf, & + & dqR_prim_dy_vf, dqL_prim_dz_vf, dqR_prim_dz_vf - integer, intent(in) :: norm_dir - type(int_bounds_info), intent(in) :: ix, iy, iz + type(scalar_field), allocatable, dimension(:), intent(inout) :: qL_prim_vf, qR_prim_vf + type(scalar_field), dimension(sys_size), intent(in) :: q_prim_vf + type(scalar_field), dimension(sys_size), intent(inout) :: flux_vf, flux_src_vf, flux_gsrc_vf + integer, intent(in) :: norm_dir + type(int_bounds_info), intent(in) :: ix, iy, iz ! Local variables: + #:if not MFC_CASE_OPTIMIZATION and USING_AMD real(wp), dimension(3) :: alpha_L, alpha_R, alpha_rho_L, alpha_rho_R #:else real(wp), dimension(num_fluids) :: alpha_L, alpha_R, alpha_rho_L, alpha_rho_R #:endif type(riemann_states_vec3) :: vel - type(riemann_states) :: rho, pres, E, H_no_mag - type(riemann_states) :: gamma, pi_inf, qv - type(riemann_states) :: vel_rms - + type(riemann_states) :: rho, pres, E, H_no_mag + type(riemann_states) :: gamma, pi_inf, qv + type(riemann_states) :: vel_rms type(riemann_states_vec3) :: B - type(riemann_states) :: c, c_fast, pres_mag + type(riemann_states) :: c, c_fast, pres_mag ! HLLD speeds and intermediate state variables: - real(wp) :: s_L, s_R, s_M, s_starL, s_starR - real(wp) :: pTot_L, pTot_R, p_star, rhoL_star, rhoR_star, E_starL, E_starR - + real(wp) :: s_L, s_R, s_M, s_starL, s_starR + real(wp) :: pTot_L, pTot_R, p_star, rhoL_star, rhoR_star, E_starL, E_starR real(wp), dimension(7) :: U_L, U_R, U_starL, U_starR, U_doubleL, U_doubleR real(wp), dimension(7) :: F_L, F_R, F_starL, F_starR, F_hlld - ! Indices for U and F: (rho, rho*vel(1), rho*vel(2), rho*vel(3), By, Bz, E) - ! Note: vel and B are permutated, so vel(1) is the normal velocity, and x is the normal direction - ! Note: Bx is omitted as the magnetic flux is always zero in the normal direction + ! Indices for U and F: (rho, rho*vel(1), rho*vel(2), rho*vel(3), By, Bz, E) Note: vel and B are permutated, so vel(1) is the + ! normal velocity, and x is the normal direction Note: Bx is omitted as the magnetic flux is always zero in the normal + ! direction real(wp) :: sqrt_rhoL_star, sqrt_rhoR_star, denom_ds, sign_Bx real(wp) :: vL_star, vR_star, wL_star, wR_star real(wp) :: v_double, w_double, By_double, Bz_double, E_doubleL, E_doubleR, E_double + integer :: i, j, k, l - integer :: i, j, k, l - - call s_populate_riemann_states_variables_buffers( & - qL_prim_rsx_vf, qL_prim_rsy_vf, qL_prim_rsz_vf, dqL_prim_dx_vf, & - dqL_prim_dy_vf, dqL_prim_dz_vf, & - qR_prim_rsx_vf, qR_prim_rsy_vf, qR_prim_rsz_vf, dqR_prim_dx_vf, & - dqR_prim_dy_vf, dqR_prim_dz_vf, & - norm_dir, ix, iy, iz) + call s_populate_riemann_states_variables_buffers(qL_prim_rsx_vf, qL_prim_rsy_vf, qL_prim_rsz_vf, dqL_prim_dx_vf, & + & dqL_prim_dy_vf, dqL_prim_dz_vf, qR_prim_rsx_vf, qR_prim_rsy_vf, qR_prim_rsz_vf, dqR_prim_dx_vf, dqR_prim_dy_vf, & + & dqR_prim_dz_vf, norm_dir, ix, iy, iz) - call s_initialize_riemann_solver( & - flux_src_vf, norm_dir) + call s_initialize_riemann_solver(flux_src_vf, norm_dir) #:for NORM_DIR, XYZ in [(1, 'x'), (2, 'y'), (3, 'z')] if (norm_dir == ${NORM_DIR}$) then - $:GPU_PARALLEL_LOOP(collapse=3, private='[alpha_rho_L, alpha_rho_R, vel, alpha_L, alpha_R, rho, pres,E, H_no_mag, gamma, pi_inf, qv, vel_rms, B, c, c_fast, pres_mag, U_L, U_R, U_starL, U_starR, U_doubleL, U_doubleR, F_L, F_R, F_starL, F_starR, F_hlld, s_L, s_R, s_M, s_starL, s_starR, pTot_L, pTot_R, p_star, rhoL_star, rhoR_star, E_starL, E_starR, sqrt_rhoL_star, sqrt_rhoR_star, denom_ds, sign_Bx, vL_star, vR_star, wL_star, wR_star, v_double, w_double, By_double, Bz_double, E_doubleL, E_doubleR, E_double]', copyin='[norm_dir]') + $:GPU_PARALLEL_LOOP(collapse=3, private='[alpha_rho_L, alpha_rho_R, vel, alpha_L, alpha_R, rho, pres, E, & + & H_no_mag, gamma, pi_inf, qv, vel_rms, B, c, c_fast, pres_mag, U_L, U_R, U_starL, U_starR, & + & U_doubleL, U_doubleR, F_L, F_R, F_starL, F_starR, F_hlld, s_L, s_R, s_M, s_starL, s_starR, & + & pTot_L, pTot_R, p_star, rhoL_star, rhoR_star, E_starL, E_starR, sqrt_rhoL_star, & + & sqrt_rhoR_star, denom_ds, sign_Bx, vL_star, vR_star, wL_star, wR_star, v_double, w_double, & + & By_double, Bz_double, E_doubleL, E_doubleR, E_double]', copyin='[norm_dir]') do l = is3%beg, is3%end do k = is2%beg, is2%end do j = is1%beg, is1%end - ! (1) Extract the left/right primitive states do i = 1, contxe alpha_rho_L(i) = qL_prim_rs${XYZ}$_vf(j, k, l, i) @@ -3802,16 +3428,18 @@ contains ! NOTE: unlike HLL, Bx, By, Bz are permutated by dir_idx for simpler logic if (mhd) then - if (n == 0) then ! 1D: constant Bx; By, Bz as variables; only in x so not permutated - B%L = [Bx0, qL_prim_rs${XYZ}$_vf(j, k, l, B_idx%beg), qL_prim_rs${XYZ}$_vf(j, k, l, B_idx%beg + 1)] - B%R = [Bx0, qR_prim_rs${XYZ}$_vf(j + 1, k, l, B_idx%beg), qR_prim_rs${XYZ}$_vf(j + 1, k, l, B_idx%beg + 1)] - else ! 2D/3D: Bx, By, Bz as variables - B%L = [qL_prim_rs${XYZ}$_vf(j, k, l, B_idx%beg + dir_idx(1) - 1), & - qL_prim_rs${XYZ}$_vf(j, k, l, B_idx%beg + dir_idx(2) - 1), & - qL_prim_rs${XYZ}$_vf(j, k, l, B_idx%beg + dir_idx(3) - 1)] + if (n == 0) then ! 1D: constant Bx; By, Bz as variables; only in x so not permutated + B%L = [Bx0, qL_prim_rs${XYZ}$_vf(j, k, l, B_idx%beg), qL_prim_rs${XYZ}$_vf(j, k, l, & + & B_idx%beg + 1)] + B%R = [Bx0, qR_prim_rs${XYZ}$_vf(j + 1, k, l, B_idx%beg), qR_prim_rs${XYZ}$_vf(j + 1, k, l, & + & B_idx%beg + 1)] + else ! 2D/3D: Bx, By, Bz as variables + B%L = [qL_prim_rs${XYZ}$_vf(j, k, l, B_idx%beg + dir_idx(1) - 1), qL_prim_rs${XYZ}$_vf(j, k, & + & l, B_idx%beg + dir_idx(2) - 1), qL_prim_rs${XYZ}$_vf(j, k, l, & + & B_idx%beg + dir_idx(3) - 1)] B%R = [qR_prim_rs${XYZ}$_vf(j + 1, k, l, B_idx%beg + dir_idx(1) - 1), & - qR_prim_rs${XYZ}$_vf(j + 1, k, l, B_idx%beg + dir_idx(2) - 1), & - qR_prim_rs${XYZ}$_vf(j + 1, k, l, B_idx%beg + dir_idx(3) - 1)] + & qR_prim_rs${XYZ}$_vf(j + 1, k, l, B_idx%beg + dir_idx(2) - 1), & + & qR_prim_rs${XYZ}$_vf(j + 1, k, l, B_idx%beg + dir_idx(3) - 1)] end if end if @@ -3834,13 +3462,16 @@ contains pres_mag%L = 0.5_wp*sum(B%L**2._wp) pres_mag%R = 0.5_wp*sum(B%R**2._wp) E%L = gamma%L*pres%L + pi_inf%L + 0.5_wp*rho%L*vel_rms%L + qv%L + pres_mag%L - E%R = gamma%R*pres%R + pi_inf%R + 0.5_wp*rho%R*vel_rms%R + qv%R + pres_mag%R ! includes magnetic energy + E%R = gamma%R*pres%R + pi_inf%R + 0.5_wp*rho%R*vel_rms%R + qv%R + pres_mag%R ! includes magnetic energy H_no_mag%L = (E%L + pres%L - pres_mag%L)/rho%L - H_no_mag%R = (E%R + pres%R - pres_mag%R)/rho%R ! stagnation enthalpy here excludes magnetic energy (only used to find speed of sound) + H_no_mag%R = (E%R + pres%R - pres_mag%R) & + & /rho%R ! stagnation enthalpy here excludes magnetic energy (only used to find speed of sound) ! (2) Compute fast wave speeds - call s_compute_speed_of_sound(pres%L, rho%L, gamma%L, pi_inf%L, H_no_mag%L, alpha_L, vel_rms%L, 0._wp, c%L, qv%L) - call s_compute_speed_of_sound(pres%R, rho%R, gamma%R, pi_inf%R, H_no_mag%R, alpha_R, vel_rms%R, 0._wp, c%R, qv%R) + call s_compute_speed_of_sound(pres%L, rho%L, gamma%L, pi_inf%L, H_no_mag%L, alpha_L, vel_rms%L, & + & 0._wp, c%L, qv%L) + call s_compute_speed_of_sound(pres%R, rho%R, gamma%R, pi_inf%R, H_no_mag%R, alpha_R, vel_rms%R, & + & 0._wp, c%R, qv%R) call s_compute_fast_magnetosonic_speed(rho%L, c%L, B%L, norm_dir, c_fast%L, H_no_mag%L) call s_compute_fast_magnetosonic_speed(rho%R, c%R, B%R, norm_dir, c_fast%R, H_no_mag%R) @@ -3851,9 +3482,8 @@ contains pTot_L = pres%L + pres_mag%L pTot_R = pres%R + pres_mag%R - s_M = (((s_R - vel%R(1))*rho%R*vel%R(1) - & - (s_L - vel%L(1))*rho%L*vel%L(1) - pTot_R + pTot_L)/ & - ((s_R - vel%R(1))*rho%R - (s_L - vel%L(1))*rho%L)) + s_M = (((s_R - vel%R(1))*rho%R*vel%R(1) - (s_L - vel%L(1))*rho%L*vel%L(1) - pTot_R + pTot_L)/((s_R & + & - vel%R(1))*rho%R - (s_L - vel%L(1))*rho%L)) ! (4) Compute star state variables rhoL_star = rho%L*(s_L - vel%L(1))/(s_L - s_M) @@ -3883,28 +3513,34 @@ contains ! Compute the star flux using HLL relation F_starL = F_L + s_L*(U_starL - U_L) F_starR = F_R + s_R*(U_starR - U_R) - ! Compute the rotational (Alfvén) speeds + ! Compute the rotational (Alfven) speeds s_starL = s_M - abs(B%L(1))/sqrt(rhoL_star) s_starR = s_M + abs(B%L(1))/sqrt(rhoR_star) - ! Compute the double–star states [Miyoshi Eqns. (59)-(62)] + ! Compute the double-star states [Miyoshi Eqns. (59)-(62)] sqrt_rhoL_star = sqrt(rhoL_star); sqrt_rhoR_star = sqrt(rhoR_star) vL_star = vel%L(2); wL_star = vel%L(3) vR_star = vel%R(2); wR_star = vel%R(3) - ! (6) Compute the double–star states [Miyoshi Eqns. (59)-(62)] + ! (6) Compute the double-star states [Miyoshi Eqns. (59)-(62)] denom_ds = sqrt_rhoL_star + sqrt_rhoR_star sign_Bx = sign(1._wp, B%L(1)) v_double = (sqrt_rhoL_star*vL_star + sqrt_rhoR_star*vR_star + (B%R(2) - B%L(2))*sign_Bx)/denom_ds w_double = (sqrt_rhoL_star*wL_star + sqrt_rhoR_star*wR_star + (B%R(3) - B%L(3))*sign_Bx)/denom_ds - By_double = (sqrt_rhoL_star*B%R(2) + sqrt_rhoR_star*B%L(2) + sqrt_rhoL_star*sqrt_rhoR_star*(vR_star - vL_star)*sign_Bx)/denom_ds - Bz_double = (sqrt_rhoL_star*B%R(3) + sqrt_rhoR_star*B%L(3) + sqrt_rhoL_star*sqrt_rhoR_star*(wR_star - wL_star)*sign_Bx)/denom_ds - - E_doubleL = E_starL - sqrt_rhoL_star*((vL_star*B%L(2) + wL_star*B%L(3)) - (v_double*By_double + w_double*Bz_double))*sign_Bx - E_doubleR = E_starR + sqrt_rhoR_star*((vR_star*B%R(2) + wR_star*B%R(3)) - (v_double*By_double + w_double*Bz_double))*sign_Bx + By_double = (sqrt_rhoL_star*B%R(2) + sqrt_rhoR_star*B%L(2) + sqrt_rhoL_star*sqrt_rhoR_star*(vR_star & + & - vL_star)*sign_Bx)/denom_ds + Bz_double = (sqrt_rhoL_star*B%R(3) + sqrt_rhoR_star*B%L(3) + sqrt_rhoL_star*sqrt_rhoR_star*(wR_star & + & - wL_star)*sign_Bx)/denom_ds + + E_doubleL = E_starL - sqrt_rhoL_star*((vL_star*B%L(2) + wL_star*B%L(3)) - (v_double*By_double & + & + w_double*Bz_double))*sign_Bx + E_doubleR = E_starR + sqrt_rhoR_star*((vR_star*B%R(2) + wR_star*B%R(3)) - (v_double*By_double & + & + w_double*Bz_double))*sign_Bx E_double = 0.5_wp*(E_doubleL + E_doubleR) - U_doubleL = [rhoL_star, rhoL_star*s_M, rhoL_star*v_double, rhoL_star*w_double, By_double, Bz_double, E_double] - U_doubleR = [rhoR_star, rhoR_star*s_M, rhoR_star*v_double, rhoR_star*w_double, By_double, Bz_double, E_double] + U_doubleL = [rhoL_star, rhoL_star*s_M, rhoL_star*v_double, rhoL_star*w_double, By_double, Bz_double, & + & E_double] + U_doubleR = [rhoR_star, rhoR_star*s_M, rhoR_star*v_double, rhoR_star*w_double, By_double, Bz_double, & + & E_double] ! (11) Choose HLLD flux based on wave-speed regions if (0.0_wp <= s_L) then @@ -3921,9 +3557,8 @@ contains F_hlld = F_R end if - ! (12) Reorder and write temporary variables to the flux array - ! Mass - flux_rs${XYZ}$_vf(j, k, l, 1) = F_hlld(1) ! TODO multi-component + ! (12) Reorder and write temporary variables to the flux array Mass + flux_rs${XYZ}$_vf(j, k, l, 1) = F_hlld(1) ! TODO multi-component ! Momentum flux_rs${XYZ}$_vf(j, k, l, contxe + dir_idx(1)) = F_hlld(2) flux_rs${XYZ}$_vf(j, k, l, contxe + dir_idx(2)) = F_hlld(3) @@ -3941,7 +3576,7 @@ contains ! Partial fraction $:GPU_LOOP(parallelism='[seq]') do i = advxb, advxe - flux_rs${XYZ}$_vf(j, k, l, i) = 0._wp ! TODO multi-component (zero for now) + flux_rs${XYZ}$_vf(j, k, l, i) = 0._wp ! TODO multi-component (zero for now) end do flux_src_rs${XYZ}$_vf(j, k, l, advxb) = 0._wp @@ -3952,18 +3587,16 @@ contains end if #:endfor - call s_finalize_riemann_solver(flux_vf, flux_src_vf, flux_gsrc_vf, & - norm_dir) + call s_finalize_riemann_solver(flux_vf, flux_src_vf, flux_gsrc_vf, norm_dir) + end subroutine s_hlld_riemann_solver - !> The computation of parameters, the allocation of memory, - !! the association of pointers and/or the execution of any - !! other procedures that are necessary to setup the module. + !> The computation of parameters, the allocation of memory, the association of pointers and/or the execution of any other + !! procedures that are necessary to setup the module. impure subroutine s_initialize_riemann_solvers_module - ! Allocating the variables that will be utilized to formulate the - ! left, right, and average states of the Riemann problem, as well - ! the Riemann problem solution + ! Allocating the variables that will be utilized to formulate the left, right, and average states of the Riemann problem, as + ! well the Riemann problem solution integer :: i, j @:ALLOCATE(Gs_rs(1:num_fluids)) @@ -3983,34 +3616,24 @@ contains Res_gs(i, j) = fluid_pp(Re_idx(i, j))%Re(i) end do end do - $:GPU_UPDATE(device='[Res_gs,Re_idx,Re_size]') + $:GPU_UPDATE(device='[Res_gs, Re_idx, Re_size]') end if - $:GPU_ENTER_DATA(copyin='[is1,is2,is3,isx,isy,isz]') + $:GPU_ENTER_DATA(copyin='[is1, is2, is3, isx, isy, isz]') is1%beg = -1; is2%beg = 0; is3%beg = 0 is1%end = m; is2%end = n; is3%end = p - @:ALLOCATE(flux_rsx_vf(is1%beg:is1%end, & - is2%beg:is2%end, & - is3%beg:is3%end, 1:sys_size)) - @:ALLOCATE(flux_gsrc_rsx_vf(is1%beg:is1%end, & - is2%beg:is2%end, & - is3%beg:is3%end, 1:sys_size)) - @:ALLOCATE(flux_src_rsx_vf(is1%beg:is1%end, & - is2%beg:is2%end, & - is3%beg:is3%end, advxb:sys_size)) - @:ALLOCATE(vel_src_rsx_vf(is1%beg:is1%end, & - is2%beg:is2%end, & - is3%beg:is3%end, 1:num_vels)) + @:ALLOCATE(flux_rsx_vf(is1%beg:is1%end, is2%beg:is2%end, is3%beg:is3%end, 1:sys_size)) + @:ALLOCATE(flux_gsrc_rsx_vf(is1%beg:is1%end, is2%beg:is2%end, is3%beg:is3%end, 1:sys_size)) + @:ALLOCATE(flux_src_rsx_vf(is1%beg:is1%end, is2%beg:is2%end, is3%beg:is3%end, advxb:sys_size)) + @:ALLOCATE(vel_src_rsx_vf(is1%beg:is1%end, is2%beg:is2%end, is3%beg:is3%end, 1:num_vels)) if (qbmm) then @:ALLOCATE(mom_sp_rsx_vf(is1%beg:is1%end + 1, is2%beg:is2%end, is3%beg:is3%end, 1:4)) end if if (viscous) then - @:ALLOCATE(Re_avg_rsx_vf(is1%beg:is1%end, & - is2%beg:is2%end, & - is3%beg:is3%end, 1:2)) + @:ALLOCATE(Re_avg_rsx_vf(is1%beg:is1%end, is2%beg:is2%end, is3%beg:is3%end, 1:2)) end if if (n == 0) return @@ -4018,27 +3641,17 @@ contains is1%beg = -1; is2%beg = 0; is3%beg = 0 is1%end = n; is2%end = m; is3%end = p - @:ALLOCATE(flux_rsy_vf(is1%beg:is1%end, & - is2%beg:is2%end, & - is3%beg:is3%end, 1:sys_size)) - @:ALLOCATE(flux_gsrc_rsy_vf(is1%beg:is1%end, & - is2%beg:is2%end, & - is3%beg:is3%end, 1:sys_size)) - @:ALLOCATE(flux_src_rsy_vf(is1%beg:is1%end, & - is2%beg:is2%end, & - is3%beg:is3%end, advxb:sys_size)) - @:ALLOCATE(vel_src_rsy_vf(is1%beg:is1%end, & - is2%beg:is2%end, & - is3%beg:is3%end, 1:num_vels)) + @:ALLOCATE(flux_rsy_vf(is1%beg:is1%end, is2%beg:is2%end, is3%beg:is3%end, 1:sys_size)) + @:ALLOCATE(flux_gsrc_rsy_vf(is1%beg:is1%end, is2%beg:is2%end, is3%beg:is3%end, 1:sys_size)) + @:ALLOCATE(flux_src_rsy_vf(is1%beg:is1%end, is2%beg:is2%end, is3%beg:is3%end, advxb:sys_size)) + @:ALLOCATE(vel_src_rsy_vf(is1%beg:is1%end, is2%beg:is2%end, is3%beg:is3%end, 1:num_vels)) if (qbmm) then @:ALLOCATE(mom_sp_rsy_vf(is1%beg:is1%end + 1, is2%beg:is2%end, is3%beg:is3%end, 1:4)) end if if (viscous) then - @:ALLOCATE(Re_avg_rsy_vf(is1%beg:is1%end, & - is2%beg:is2%end, & - is3%beg:is3%end, 1:2)) + @:ALLOCATE(Re_avg_rsy_vf(is1%beg:is1%end, is2%beg:is2%end, is3%beg:is3%end, 1:2)) end if if (p == 0) return @@ -4046,82 +3659,57 @@ contains is1%beg = -1; is2%beg = 0; is3%beg = 0 is1%end = p; is2%end = n; is3%end = m - @:ALLOCATE(flux_rsz_vf(is1%beg:is1%end, & - is2%beg:is2%end, & - is3%beg:is3%end, 1:sys_size)) - @:ALLOCATE(flux_gsrc_rsz_vf(is1%beg:is1%end, & - is2%beg:is2%end, & - is3%beg:is3%end, 1:sys_size)) - @:ALLOCATE(flux_src_rsz_vf(is1%beg:is1%end, & - is2%beg:is2%end, & - is3%beg:is3%end, advxb:sys_size)) - @:ALLOCATE(vel_src_rsz_vf(is1%beg:is1%end, & - is2%beg:is2%end, & - is3%beg:is3%end, 1:num_vels)) + @:ALLOCATE(flux_rsz_vf(is1%beg:is1%end, is2%beg:is2%end, is3%beg:is3%end, 1:sys_size)) + @:ALLOCATE(flux_gsrc_rsz_vf(is1%beg:is1%end, is2%beg:is2%end, is3%beg:is3%end, 1:sys_size)) + @:ALLOCATE(flux_src_rsz_vf(is1%beg:is1%end, is2%beg:is2%end, is3%beg:is3%end, advxb:sys_size)) + @:ALLOCATE(vel_src_rsz_vf(is1%beg:is1%end, is2%beg:is2%end, is3%beg:is3%end, 1:num_vels)) if (qbmm) then @:ALLOCATE(mom_sp_rsz_vf(is1%beg:is1%end + 1, is2%beg:is2%end, is3%beg:is3%end, 1:4)) end if if (viscous) then - @:ALLOCATE(Re_avg_rsz_vf(is1%beg:is1%end, & - is2%beg:is2%end, & - is3%beg:is3%end, 1:2)) + @:ALLOCATE(Re_avg_rsz_vf(is1%beg:is1%end, is2%beg:is2%end, is3%beg:is3%end, 1:2)) end if end subroutine s_initialize_riemann_solvers_module - !> The purpose of this subroutine is to populate the buffers - !! of the left and right Riemann states variables, depending - !! on the boundary conditions. - !! @param qL_prim_rsx_vf Left WENO-reconstructed cell-boundary values (x-dir) - !! @param qL_prim_rsy_vf Left WENO-reconstructed cell-boundary values (y-dir) - !! @param qL_prim_rsz_vf Left WENO-reconstructed cell-boundary values (z-dir) - !! @param dqL_prim_dx_vf The left WENO-reconstructed cell-boundary values of the - !! first-order x-dir spatial derivatives - !! @param dqL_prim_dy_vf The left WENO-reconstructed cell-boundary values of the - !! first-order y-dir spatial derivatives - !! @param dqL_prim_dz_vf The left WENO-reconstructed cell-boundary values of the - !! first-order z-dir spatial derivatives - !! @param qR_prim_rsx_vf Right WENO-reconstructed cell-boundary values (x-dir) - !! @param qR_prim_rsy_vf Right WENO-reconstructed cell-boundary values (y-dir) - !! @param qR_prim_rsz_vf Right WENO-reconstructed cell-boundary values (z-dir) - !! @param dqR_prim_dx_vf The right WENO-reconstructed cell-boundary values of the - !! first-order x-dir spatial derivatives - !! @param dqR_prim_dy_vf The right WENO-reconstructed cell-boundary values of the - !! first-order y-dir spatial derivatives - !! @param dqR_prim_dz_vf The right WENO-reconstructed cell-boundary values of the - !! first-order z-dir spatial derivatives - !! @param norm_dir Dir. splitting direction - !! @param ix Index bounds in the x-dir - !! @param iy Index bounds in the y-dir - !! @param iz Index bounds in the z-dir - subroutine s_populate_riemann_states_variables_buffers( & - qL_prim_rsx_vf, qL_prim_rsy_vf, qL_prim_rsz_vf, dqL_prim_dx_vf, & - dqL_prim_dy_vf, & - dqL_prim_dz_vf, & - qR_prim_rsx_vf, qR_prim_rsy_vf, qR_prim_rsz_vf, dqR_prim_dx_vf, & - dqR_prim_dy_vf, & - dqR_prim_dz_vf, & - norm_dir, ix, iy, iz) - - real(wp), dimension(idwbuff(1)%beg:, idwbuff(2)%beg:, idwbuff(3)%beg:, 1:), intent(inout) :: qL_prim_rsx_vf, qL_prim_rsy_vf, qL_prim_rsz_vf, qR_prim_rsx_vf, qR_prim_rsy_vf, qR_prim_rsz_vf - - type(scalar_field), & - allocatable, dimension(:), & - intent(inout) :: dqL_prim_dx_vf, dqR_prim_dx_vf, & - dqL_prim_dy_vf, dqR_prim_dy_vf, & - dqL_prim_dz_vf, dqR_prim_dz_vf - - integer, intent(in) :: norm_dir + !> The purpose of this subroutine is to populate the buffers of the left and right Riemann states variables, depending on the + !! boundary conditions. + !! @param qL_prim_rsx_vf Left WENO-reconstructed cell-boundary values (x-dir) + !! @param qL_prim_rsy_vf Left WENO-reconstructed cell-boundary values (y-dir) + !! @param qL_prim_rsz_vf Left WENO-reconstructed cell-boundary values (z-dir) + !! @param dqL_prim_dx_vf The left WENO-reconstructed cell-boundary values of the first-order x-dir spatial derivatives + !! @param dqL_prim_dy_vf The left WENO-reconstructed cell-boundary values of the first-order y-dir spatial derivatives + !! @param dqL_prim_dz_vf The left WENO-reconstructed cell-boundary values of the first-order z-dir spatial derivatives + !! @param qR_prim_rsx_vf Right WENO-reconstructed cell-boundary values (x-dir) + !! @param qR_prim_rsy_vf Right WENO-reconstructed cell-boundary values (y-dir) + !! @param qR_prim_rsz_vf Right WENO-reconstructed cell-boundary values (z-dir) + !! @param dqR_prim_dx_vf The right WENO-reconstructed cell-boundary values of the first-order x-dir spatial derivatives + !! @param dqR_prim_dy_vf The right WENO-reconstructed cell-boundary values of the first-order y-dir spatial derivatives + !! @param dqR_prim_dz_vf The right WENO-reconstructed cell-boundary values of the first-order z-dir spatial derivatives + !! @param norm_dir Dir. splitting direction + !! @param ix Index bounds in the x-dir + !! @param iy Index bounds in the y-dir + !! @param iz Index bounds in the z-dir + subroutine s_populate_riemann_states_variables_buffers(qL_prim_rsx_vf, qL_prim_rsy_vf, qL_prim_rsz_vf, dqL_prim_dx_vf, & + & dqL_prim_dy_vf, dqL_prim_dz_vf, qR_prim_rsx_vf, qR_prim_rsy_vf, qR_prim_rsz_vf, dqR_prim_dx_vf, dqR_prim_dy_vf, & + & dqR_prim_dz_vf, norm_dir, ix, iy, iz) + + real(wp), dimension(idwbuff(1)%beg:,idwbuff(2)%beg:,idwbuff(3)%beg:,1:), intent(inout) :: qL_prim_rsx_vf, qL_prim_rsy_vf, & + & qL_prim_rsz_vf, qR_prim_rsx_vf, qR_prim_rsy_vf, qR_prim_rsz_vf + + type(scalar_field), allocatable, dimension(:), intent(inout) :: dqL_prim_dx_vf, dqR_prim_dx_vf, dqL_prim_dy_vf, & + & dqR_prim_dy_vf, dqL_prim_dz_vf, dqR_prim_dz_vf + + integer, intent(in) :: norm_dir type(int_bounds_info), intent(in) :: ix, iy, iz - - integer :: i, j, k, l !< Generic loop iterator + integer :: i, j, k, l !< Generic loop iterator if (norm_dir == 1) then is1 = ix; is2 = iy; is3 = iz dir_idx = (/1, 2, 3/); dir_flg = (/1._wp, 0._wp, 0._wp/) - elseif (norm_dir == 2) then + else if (norm_dir == 2) then is1 = iy; is2 = ix; is3 = iz dir_idx = (/2, 1, 3/); dir_flg = (/0._wp, 1._wp, 0._wp/) else @@ -4129,7 +3717,7 @@ contains dir_idx = (/3, 1, 2/); dir_flg = (/0._wp, 0._wp, 1._wp/) end if - $:GPU_UPDATE(device='[is1,is2,is3]') + $:GPU_UPDATE(device='[is1, is2, is3]') if (elasticity) then if (norm_dir == 1) then @@ -4143,20 +3731,18 @@ contains isx = ix; isy = iy; isz = iz ! for stuff in the same module - $:GPU_UPDATE(device='[isx,isy,isz]') + $:GPU_UPDATE(device='[isx, isy, isz]') ! for stuff in different modules - $:GPU_UPDATE(device='[dir_idx,dir_flg,dir_idx_tau]') + $:GPU_UPDATE(device='[dir_idx, dir_flg, dir_idx_tau]') ! Population of Buffers in x-direction if (norm_dir == 1) then - - if (bc_x%beg == BC_RIEMANN_EXTRAP) then ! Riemann state extrap. BC at beginning + if (bc_x%beg == BC_RIEMANN_EXTRAP) then ! Riemann state extrap. BC at beginning $:GPU_PARALLEL_LOOP(collapse=3) do i = 1, sys_size do l = is3%beg, is3%end do k = is2%beg, is2%end - qL_prim_rsx_vf(-1, k, l, i) = & - qR_prim_rsx_vf(0, k, l, i) + qL_prim_rsx_vf(-1, k, l, i) = qR_prim_rsx_vf(0, k, l, i) end do end do end do @@ -4167,9 +3753,7 @@ contains do i = momxb, momxe do l = isz%beg, isz%end do k = isy%beg, isy%end - - dqL_prim_dx_vf(i)%sf(-1, k, l) = & - dqR_prim_dx_vf(i)%sf(0, k, l) + dqL_prim_dx_vf(i)%sf(-1, k, l) = dqR_prim_dx_vf(i)%sf(0, k, l) end do end do end do @@ -4180,9 +3764,7 @@ contains do i = momxb, momxe do l = isz%beg, isz%end do k = isy%beg, isy%end - - dqL_prim_dy_vf(i)%sf(-1, k, l) = & - dqR_prim_dy_vf(i)%sf(0, k, l) + dqL_prim_dy_vf(i)%sf(-1, k, l) = dqR_prim_dy_vf(i)%sf(0, k, l) end do end do end do @@ -4193,43 +3775,34 @@ contains do i = momxb, momxe do l = isz%beg, isz%end do k = isy%beg, isy%end - - dqL_prim_dz_vf(i)%sf(-1, k, l) = & - dqR_prim_dz_vf(i)%sf(0, k, l) + dqL_prim_dz_vf(i)%sf(-1, k, l) = dqR_prim_dz_vf(i)%sf(0, k, l) end do end do end do $:END_GPU_PARALLEL_LOOP() end if - end if - end if - end if - if (bc_x%end == BC_RIEMANN_EXTRAP) then ! Riemann state extrap. BC at end + if (bc_x%end == BC_RIEMANN_EXTRAP) then ! Riemann state extrap. BC at end $:GPU_PARALLEL_LOOP(collapse=3) do i = 1, sys_size do l = is3%beg, is3%end do k = is2%beg, is2%end - qR_prim_rsx_vf(m + 1, k, l, i) = & - qL_prim_rsx_vf(m, k, l, i) + qR_prim_rsx_vf(m + 1, k, l, i) = qL_prim_rsx_vf(m, k, l, i) end do end do end do $:END_GPU_PARALLEL_LOOP() if (viscous .or. dummy) then - $:GPU_PARALLEL_LOOP(collapse=3) do i = momxb, momxe do l = isz%beg, isz%end do k = isy%beg, isy%end - - dqR_prim_dx_vf(i)%sf(m + 1, k, l) = & - dqL_prim_dx_vf(i)%sf(m, k, l) + dqR_prim_dx_vf(i)%sf(m + 1, k, l) = dqL_prim_dx_vf(i)%sf(m, k, l) end do end do end do @@ -4240,9 +3813,7 @@ contains do i = momxb, momxe do l = isz%beg, isz%end do k = isy%beg, isy%end - - dqR_prim_dy_vf(i)%sf(m + 1, k, l) = & - dqL_prim_dy_vf(i)%sf(m, k, l) + dqR_prim_dy_vf(i)%sf(m + 1, k, l) = dqL_prim_dy_vf(i)%sf(m, k, l) end do end do end do @@ -4253,45 +3824,36 @@ contains do i = momxb, momxe do l = isz%beg, isz%end do k = isy%beg, isy%end - - dqR_prim_dz_vf(i)%sf(m + 1, k, l) = & - dqL_prim_dz_vf(i)%sf(m, k, l) + dqR_prim_dz_vf(i)%sf(m + 1, k, l) = dqL_prim_dz_vf(i)%sf(m, k, l) end do end do end do $:END_GPU_PARALLEL_LOOP() end if - end if - end if - end if ! END: Population of Buffers in x-direction ! Population of Buffers in y-direction - elseif (norm_dir == 2) then - - if (bc_y%beg == BC_RIEMANN_EXTRAP) then ! Riemann state extrap. BC at beginning + else if (norm_dir == 2) then + if (bc_y%beg == BC_RIEMANN_EXTRAP) then ! Riemann state extrap. BC at beginning $:GPU_PARALLEL_LOOP(collapse=3) do i = 1, sys_size do l = is3%beg, is3%end do k = is2%beg, is2%end - qL_prim_rsy_vf(-1, k, l, i) = & - qR_prim_rsy_vf(0, k, l, i) + qL_prim_rsy_vf(-1, k, l, i) = qR_prim_rsy_vf(0, k, l, i) end do end do end do $:END_GPU_PARALLEL_LOOP() if (viscous .or. dummy) then - $:GPU_PARALLEL_LOOP(collapse=3) do i = momxb, momxe do l = isz%beg, isz%end do j = isx%beg, isx%end - dqL_prim_dx_vf(i)%sf(j, -1, l) = & - dqR_prim_dx_vf(i)%sf(j, 0, l) + dqL_prim_dx_vf(i)%sf(j, -1, l) = dqR_prim_dx_vf(i)%sf(j, 0, l) end do end do end do @@ -4301,8 +3863,7 @@ contains do i = momxb, momxe do l = isz%beg, isz%end do j = isx%beg, isx%end - dqL_prim_dy_vf(i)%sf(j, -1, l) = & - dqR_prim_dy_vf(i)%sf(j, 0, l) + dqL_prim_dy_vf(i)%sf(j, -1, l) = dqR_prim_dy_vf(i)%sf(j, 0, l) end do end do end do @@ -4313,39 +3874,33 @@ contains do i = momxb, momxe do l = isz%beg, isz%end do j = isx%beg, isx%end - dqL_prim_dz_vf(i)%sf(j, -1, l) = & - dqR_prim_dz_vf(i)%sf(j, 0, l) + dqL_prim_dz_vf(i)%sf(j, -1, l) = dqR_prim_dz_vf(i)%sf(j, 0, l) end do end do end do $:END_GPU_PARALLEL_LOOP() end if - end if - end if - if (bc_y%end == BC_RIEMANN_EXTRAP) then ! Riemann state extrap. BC at end + if (bc_y%end == BC_RIEMANN_EXTRAP) then ! Riemann state extrap. BC at end $:GPU_PARALLEL_LOOP(collapse=3) do i = 1, sys_size do l = is3%beg, is3%end do k = is2%beg, is2%end - qR_prim_rsy_vf(n + 1, k, l, i) = & - qL_prim_rsy_vf(n, k, l, i) + qR_prim_rsy_vf(n + 1, k, l, i) = qL_prim_rsy_vf(n, k, l, i) end do end do end do $:END_GPU_PARALLEL_LOOP() if (viscous .or. dummy) then - $:GPU_PARALLEL_LOOP(collapse=3) do i = momxb, momxe do l = isz%beg, isz%end do j = isx%beg, isx%end - dqR_prim_dx_vf(i)%sf(j, n + 1, l) = & - dqL_prim_dx_vf(i)%sf(j, n, l) + dqR_prim_dx_vf(i)%sf(j, n + 1, l) = dqL_prim_dx_vf(i)%sf(j, n, l) end do end do end do @@ -4355,8 +3910,7 @@ contains do i = momxb, momxe do l = isz%beg, isz%end do j = isx%beg, isx%end - dqR_prim_dy_vf(i)%sf(j, n + 1, l) = & - dqL_prim_dy_vf(i)%sf(j, n, l) + dqR_prim_dy_vf(i)%sf(j, n + 1, l) = dqL_prim_dy_vf(i)%sf(j, n, l) end do end do end do @@ -4367,29 +3921,24 @@ contains do i = momxb, momxe do l = isz%beg, isz%end do j = isx%beg, isx%end - dqR_prim_dz_vf(i)%sf(j, n + 1, l) = & - dqL_prim_dz_vf(i)%sf(j, n, l) + dqR_prim_dz_vf(i)%sf(j, n + 1, l) = dqL_prim_dz_vf(i)%sf(j, n, l) end do end do end do $:END_GPU_PARALLEL_LOOP() end if - end if - end if ! END: Population of Buffers in y-direction ! Population of Buffers in z-direction else - - if (bc_z%beg == BC_RIEMANN_EXTRAP) then ! Riemann state extrap. BC at beginning + if (bc_z%beg == BC_RIEMANN_EXTRAP) then ! Riemann state extrap. BC at beginning $:GPU_PARALLEL_LOOP(collapse=3) do i = 1, sys_size do l = is3%beg, is3%end do k = is2%beg, is2%end - qL_prim_rsz_vf(-1, k, l, i) = & - qR_prim_rsz_vf(0, k, l, i) + qL_prim_rsz_vf(-1, k, l, i) = qR_prim_rsz_vf(0, k, l, i) end do end do end do @@ -4400,8 +3949,7 @@ contains do i = momxb, momxe do k = isy%beg, isy%end do j = isx%beg, isx%end - dqL_prim_dx_vf(i)%sf(j, k, -1) = & - dqR_prim_dx_vf(i)%sf(j, k, 0) + dqL_prim_dx_vf(i)%sf(j, k, -1) = dqR_prim_dx_vf(i)%sf(j, k, 0) end do end do end do @@ -4410,8 +3958,7 @@ contains do i = momxb, momxe do k = isy%beg, isy%end do j = isx%beg, isx%end - dqL_prim_dy_vf(i)%sf(j, k, -1) = & - dqR_prim_dy_vf(i)%sf(j, k, 0) + dqL_prim_dy_vf(i)%sf(j, k, -1) = dqR_prim_dy_vf(i)%sf(j, k, 0) end do end do end do @@ -4420,24 +3967,21 @@ contains do i = momxb, momxe do k = isy%beg, isy%end do j = isx%beg, isx%end - dqL_prim_dz_vf(i)%sf(j, k, -1) = & - dqR_prim_dz_vf(i)%sf(j, k, 0) + dqL_prim_dz_vf(i)%sf(j, k, -1) = dqR_prim_dz_vf(i)%sf(j, k, 0) end do end do end do $:END_GPU_PARALLEL_LOOP() end if - end if - if (bc_z%end == BC_RIEMANN_EXTRAP) then ! Riemann state extrap. BC at end + if (bc_z%end == BC_RIEMANN_EXTRAP) then ! Riemann state extrap. BC at end $:GPU_PARALLEL_LOOP(collapse=3) do i = 1, sys_size do l = is3%beg, is3%end do k = is2%beg, is2%end - qR_prim_rsz_vf(p + 1, k, l, i) = & - qL_prim_rsz_vf(p, k, l, i) + qR_prim_rsz_vf(p + 1, k, l, i) = qL_prim_rsz_vf(p, k, l, i) end do end do end do @@ -4448,8 +3992,7 @@ contains do i = momxb, momxe do k = isy%beg, isy%end do j = isx%beg, isx%end - dqR_prim_dx_vf(i)%sf(j, k, p + 1) = & - dqL_prim_dx_vf(i)%sf(j, k, p) + dqR_prim_dx_vf(i)%sf(j, k, p + 1) = dqL_prim_dx_vf(i)%sf(j, k, p) end do end do end do @@ -4459,8 +4002,7 @@ contains do i = momxb, momxe do k = isy%beg, isy%end do j = isx%beg, isx%end - dqR_prim_dy_vf(i)%sf(j, k, p + 1) = & - dqL_prim_dy_vf(i)%sf(j, k, p) + dqR_prim_dy_vf(i)%sf(j, k, p + 1) = dqL_prim_dy_vf(i)%sf(j, k, p) end do end do end do @@ -4470,45 +4012,32 @@ contains do i = momxb, momxe do k = isy%beg, isy%end do j = isx%beg, isx%end - dqR_prim_dz_vf(i)%sf(j, k, p + 1) = & - dqL_prim_dz_vf(i)%sf(j, k, p) + dqR_prim_dz_vf(i)%sf(j, k, p + 1) = dqL_prim_dz_vf(i)%sf(j, k, p) end do end do end do $:END_GPU_PARALLEL_LOOP() end if - end if - end if ! END: Population of Buffers in z-direction end subroutine s_populate_riemann_states_variables_buffers - !> The computation of parameters, the allocation of memory, - !! the association of pointers and/or the execution of any - !! other procedures needed to configure the chosen Riemann - !! solver algorithm. - !! @param flux_src_vf Intra-cell fluxes sources - !! @param norm_dir Dir. splitting direction - subroutine s_initialize_riemann_solver( & - flux_src_vf, & - norm_dir) - - type(scalar_field), & - dimension(sys_size), & - intent(inout) :: flux_src_vf + !> The computation of parameters, the allocation of memory, the association of pointers and/or the execution of any other + !! procedures needed to configure the chosen Riemann solver algorithm. + !! @param flux_src_vf Intra-cell fluxes sources + !! @param norm_dir Dir. splitting direction + subroutine s_initialize_riemann_solver(flux_src_vf, norm_dir) - integer, intent(in) :: norm_dir - - integer :: i, j, k, l ! Generic loop iterators + type(scalar_field), dimension(sys_size), intent(inout) :: flux_src_vf + integer, intent(in) :: norm_dir + integer :: i, j, k, l ! Generic loop iterators ! Reshaping Inputted Data in x-direction if (norm_dir == 1) then - if (viscous .or. (surface_tension) .or. dummy) then - $:GPU_PARALLEL_LOOP(collapse=4) do i = momxb, E_idx do l = is3%beg, is3%end @@ -4553,8 +4082,7 @@ contains end if ! Reshaping Inputted Data in y-direction - elseif (norm_dir == 2) then - + else if (norm_dir == 2) then if (viscous .or. (surface_tension) .or. dummy) then $:GPU_PARALLEL_LOOP(collapse=4) do i = momxb, E_idx @@ -4601,7 +4129,6 @@ contains ! Reshaping Inputted Data in z-direction else - if (viscous .or. (surface_tension) .or. dummy) then $:GPU_PARALLEL_LOOP(collapse=4) do i = momxb, E_idx @@ -4645,95 +4172,95 @@ contains end do $:END_GPU_PARALLEL_LOOP() end if - end if end subroutine s_initialize_riemann_solver - !> @brief Computes cylindrical viscous source flux contributions for momentum and energy. - !! Calculates Cartesian components of the stress tensor using averaged velocity derivatives - !! and cylindrical geometric factors, then updates `flux_src_vf`. - !! Assumes x-dir is axial (z_cyl), y-dir is radial (r_cyl), z-dir is azimuthal (theta_cyl for derivatives). - !! @param[in] velL_vf Left boundary velocity (\f$v_x, v_y, v_z\f$) (num_dims scalar_field). - !! @param[in] dvelL_dx_vf Left boundary \f$\partial v_i/\partial x\f$ (num_dims scalar_field). - !! @param[in] dvelL_dy_vf Left boundary \f$\partial v_i/\partial y\f$ (num_dims scalar_field). - !! @param[in] dvelL_dz_vf Left boundary \f$\partial v_i/\partial z\f$ (num_dims scalar_field). - !! @param[in] velR_vf Right boundary velocity (\f$v_x, v_y, v_z\f$) (num_dims scalar_field). - !! @param[in] dvelR_dx_vf Right boundary \f$\partial v_i/\partial x\f$ (num_dims scalar_field). - !! @param[in] dvelR_dy_vf Right boundary \f$\partial v_i/\partial y\f$ (num_dims scalar_field). - !! @param[in] dvelR_dz_vf Right boundary \f$\partial v_i/\partial z\f$ (num_dims scalar_field). - !! @param[inout] flux_src_vf Intercell source flux array to update (sys_size scalar_field). - !! @param[in] norm_dir Interface normal direction (1=x-face, 2=y-face, 3=z-face). - !! @param[in] ix Global X-direction loop bounds (int_bounds_info). - !! @param[in] iy Global Y-direction loop bounds (int_bounds_info). - !! @param[in] iz Global Z-direction loop bounds (int_bounds_info). - subroutine s_compute_cylindrical_viscous_source_flux(velL_vf, & - dvelL_dx_vf, dvelL_dy_vf, dvelL_dz_vf, & - velR_vf, & - dvelR_dx_vf, dvelR_dy_vf, dvelR_dz_vf, & - flux_src_vf, norm_dir, ix, iy, iz) - - type(scalar_field), dimension(num_dims), intent(in) :: velL_vf, velR_vf - type(scalar_field), dimension(num_dims), intent(in) :: dvelL_dx_vf, dvelR_dx_vf - type(scalar_field), dimension(num_dims), intent(in) :: dvelL_dy_vf, dvelR_dy_vf - type(scalar_field), dimension(num_dims), intent(in) :: dvelL_dz_vf, dvelR_dz_vf + !> @brief Computes cylindrical viscous source flux contributions for momentum and energy. Calculates Cartesian components of the + !! stress tensor using averaged velocity derivatives and cylindrical geometric factors, then updates `flux_src_vf`. Assumes + !! x-dir is axial (z_cyl), y-dir is radial (r_cyl), z-dir is azimuthal (theta_cyl for derivatives). + !! @param[in] velL_vf Left boundary velocity (\f$v_x, v_y, v_z\f$) (num_dims scalar_field). + !! @param[in] dvelL_dx_vf Left boundary \f$\partial v_i/\partial x\f$ (num_dims scalar_field). + !! @param[in] dvelL_dy_vf Left boundary \f$\partial v_i/\partial y\f$ (num_dims scalar_field). + !! @param[in] dvelL_dz_vf Left boundary \f$\partial v_i/\partial z\f$ (num_dims scalar_field). + !! @param[in] velR_vf Right boundary velocity (\f$v_x, v_y, v_z\f$) (num_dims scalar_field). + !! @param[in] dvelR_dx_vf Right boundary \f$\partial v_i/\partial x\f$ (num_dims scalar_field). + !! @param[in] dvelR_dy_vf Right boundary \f$\partial v_i/\partial y\f$ (num_dims scalar_field). + !! @param[in] dvelR_dz_vf Right boundary \f$\partial v_i/\partial z\f$ (num_dims scalar_field). + !! @param[inout] flux_src_vf Intercell source flux array to update (sys_size scalar_field). + !! @param[in] norm_dir Interface normal direction (1=x-face, 2=y-face, 3=z-face). + !! @param[in] ix Global X-direction loop bounds (int_bounds_info). + !! @param[in] iy Global Y-direction loop bounds (int_bounds_info). + !! @param[in] iz Global Z-direction loop bounds (int_bounds_info). + subroutine s_compute_cylindrical_viscous_source_flux(velL_vf, dvelL_dx_vf, dvelL_dy_vf, dvelL_dz_vf, velR_vf, dvelR_dx_vf, & + & dvelR_dy_vf, dvelR_dz_vf, flux_src_vf, norm_dir, ix, iy, iz) + + type(scalar_field), dimension(num_dims), intent(in) :: velL_vf, velR_vf + type(scalar_field), dimension(num_dims), intent(in) :: dvelL_dx_vf, dvelR_dx_vf + type(scalar_field), dimension(num_dims), intent(in) :: dvelL_dy_vf, dvelR_dy_vf + type(scalar_field), dimension(num_dims), intent(in) :: dvelL_dz_vf, dvelR_dz_vf type(scalar_field), dimension(sys_size), intent(inout) :: flux_src_vf - integer, intent(in) :: norm_dir - type(int_bounds_info), intent(in) :: ix, iy, iz + integer, intent(in) :: norm_dir + type(int_bounds_info), intent(in) :: ix, iy, iz ! Local variables + #:if not MFC_CASE_OPTIMIZATION and USING_AMD real(wp), dimension(3) :: avg_v_int !!< Averaged interface velocity (\f$v_x, v_y, v_z\f$) (grid directions). real(wp), dimension(3) :: avg_dvdx_int !!< Averaged interface \f$\partial v_i/\partial x\f$ (grid dir 1). real(wp), dimension(3) :: avg_dvdy_int !!< Averaged interface \f$\partial v_i/\partial y\f$ (grid dir 2). real(wp), dimension(3) :: avg_dvdz_int !!< Averaged interface \f$\partial v_i/\partial z\f$ (grid dir 3). real(wp), dimension(3) :: vel_src_int !!< Interface velocity (\f$v_1,v_2,v_3\f$) (grid directions) for viscous work. - real(wp), dimension(3) :: stress_vector_shear !!< Shear stress vector (\f$\sigma_{N1}, \sigma_{N2}, \sigma_{N3}\f$) on N-face (grid directions). + real(wp), & + & dimension(3) & + & :: stress_vector_shear !!< Shear stress vector (\f$\sigma_{N1}, \sigma_{N2}, \sigma_{N3}\f$) on N-face (grid directions). #:else - real(wp), dimension(num_dims) :: avg_v_int !!< Averaged interface velocity (\f$v_x, v_y, v_z\f$) (grid directions). + real(wp), & + & dimension(num_dims) :: avg_v_int !!< Averaged interface velocity (\f$v_x, v_y, v_z\f$) (grid directions). real(wp), dimension(num_dims) :: avg_dvdx_int !!< Averaged interface \f$\partial v_i/\partial x\f$ (grid dir 1). real(wp), dimension(num_dims) :: avg_dvdy_int !!< Averaged interface \f$\partial v_i/\partial y\f$ (grid dir 2). real(wp), dimension(num_dims) :: avg_dvdz_int !!< Averaged interface \f$\partial v_i/\partial z\f$ (grid dir 3). - real(wp), dimension(num_dims) :: vel_src_int !!< Interface velocity (\f$v_1,v_2,v_3\f$) (grid directions) for viscous work. - real(wp), dimension(num_dims) :: stress_vector_shear !!< Shear stress vector (\f$\sigma_{N1}, \sigma_{N2}, \sigma_{N3}\f$) on N-face (grid directions). + real(wp), & + & dimension(num_dims) :: vel_src_int !!< Interface velocity (\f$v_1,v_2,v_3\f$) (grid directions) for viscous work. + real(wp), & + & dimension(num_dims) & + & :: stress_vector_shear !!< Shear stress vector (\f$\sigma_{N1}, \sigma_{N2}, \sigma_{N3}\f$) on N-face (grid directions). #:endif real(wp) :: stress_normal_bulk !!< Normal bulk stress component \f$\sigma_{NN}\f$ on N-face. - real(wp) :: Re_s, Re_b !!< Effective interface shear and bulk Reynolds numbers. real(wp) :: r_eff !!< Effective radius at interface for cylindrical terms. real(wp) :: div_v_term_const !!< Common term \f$-(2/3)(\nabla \cdot \mathbf{v}) / \text{Re}_s\f$ for shear stress diagonal. real(wp) :: divergence_cyl !!< Full divergence \f$\nabla \cdot \mathbf{v}\f$ in cylindrical coordinates. + integer :: j, k, l !!< Loop iterators for \f$x, y, z\f$ grid directions. + integer :: i_vel !!< Loop iterator for velocity components. + integer :: idx_rp(3) !!< Indices \f$(j,k,l)\f$ of 'right' point for averaging. - integer :: j, k, l !!< Loop iterators for \f$x, y, z\f$ grid directions. - integer :: i_vel !!< Loop iterator for velocity components. - integer :: idx_rp(3) !!< Indices \f$(j,k,l)\f$ of 'right' point for averaging. - - $:GPU_PARALLEL_LOOP(collapse=3, private='[idx_rp, avg_v_int, avg_dvdx_int, avg_dvdy_int, avg_dvdz_int, Re_s, Re_b, vel_src_int, r_eff, divergence_cyl, stress_vector_shear, stress_normal_bulk, div_v_term_const]') + $:GPU_PARALLEL_LOOP(collapse=3, private='[idx_rp, avg_v_int, avg_dvdx_int, avg_dvdy_int, avg_dvdz_int, Re_s, Re_b, & + & vel_src_int, r_eff, divergence_cyl, stress_vector_shear, stress_normal_bulk, div_v_term_const]') do l = iz%beg, iz%end do k = iy%beg, iy%end do j = ix%beg, ix%end - ! Determine indices for the 'right' state for averaging across the interface idx_rp = [j, k, l] idx_rp(norm_dir) = idx_rp(norm_dir) + 1 - ! Average velocities and their derivatives at the interface - ! For cylindrical: x-dir ~ axial (z_cyl), y-dir ~ radial (r_cyl), z-dir ~ azimuthal (theta_cyl) + ! Average velocities and their derivatives at the interface For cylindrical: x-dir ~ axial (z_cyl), y-dir ~ + ! radial (r_cyl), z-dir ~ azimuthal (theta_cyl) $:GPU_LOOP(parallelism='[seq]') do i_vel = 1, num_dims avg_v_int(i_vel) = 0.5_wp*(velL_vf(i_vel)%sf(j, k, l) + velR_vf(i_vel)%sf(idx_rp(1), idx_rp(2), idx_rp(3))) - avg_dvdx_int(i_vel) = 0.5_wp*(dvelL_dx_vf(i_vel)%sf(j, k, l) + & - dvelR_dx_vf(i_vel)%sf(idx_rp(1), idx_rp(2), idx_rp(3))) + avg_dvdx_int(i_vel) = 0.5_wp*(dvelL_dx_vf(i_vel)%sf(j, k, l) + dvelR_dx_vf(i_vel)%sf(idx_rp(1), & + & idx_rp(2), idx_rp(3))) if (num_dims > 1) then - avg_dvdy_int(i_vel) = 0.5_wp*(dvelL_dy_vf(i_vel)%sf(j, k, l) + & - dvelR_dy_vf(i_vel)%sf(idx_rp(1), idx_rp(2), idx_rp(3))) + avg_dvdy_int(i_vel) = 0.5_wp*(dvelL_dy_vf(i_vel)%sf(j, k, l) + dvelR_dy_vf(i_vel)%sf(idx_rp(1), & + & idx_rp(2), idx_rp(3))) else avg_dvdy_int(i_vel) = 0.0_wp end if if (num_dims > 2) then - avg_dvdz_int(i_vel) = 0.5_wp*(dvelL_dz_vf(i_vel)%sf(j, k, l) + & - dvelR_dz_vf(i_vel)%sf(idx_rp(1), idx_rp(2), idx_rp(3))) + avg_dvdz_int(i_vel) = 0.5_wp*(dvelL_dz_vf(i_vel)%sf(j, k, l) + dvelR_dz_vf(i_vel)%sf(idx_rp(1), & + & idx_rp(2), idx_rp(3))) else avg_dvdz_int(i_vel) = 0.0_wp end if @@ -4741,20 +4268,20 @@ contains ! Get Re numbers and interface velocity for viscous work select case (norm_dir) - case (1) ! x-face (axial face in z_cyl direction) + case (1) ! x-face (axial face in z_cyl direction) Re_s = Re_avg_rsx_vf(j, k, l, 1) Re_b = Re_avg_rsx_vf(j, k, l, 2) - vel_src_int = vel_src_rsx_vf(j, k, l, 1:num_dims) + vel_src_int = vel_src_rsx_vf(j, k, l,1:num_dims) r_eff = y_cc(k) - case (2) ! y-face (radial face in r_cyl direction) + case (2) ! y-face (radial face in r_cyl direction) Re_s = Re_avg_rsy_vf(k, j, l, 1) Re_b = Re_avg_rsy_vf(k, j, l, 2) - vel_src_int = vel_src_rsy_vf(k, j, l, 1:num_dims) + vel_src_int = vel_src_rsy_vf(k, j, l,1:num_dims) r_eff = y_cb(k) - case (3) ! z-face (azimuthal face in theta_cyl direction) + case (3) ! z-face (azimuthal face in theta_cyl direction) Re_s = Re_avg_rsz_vf(l, k, j, 1) Re_b = Re_avg_rsz_vf(l, k, j, 2) - vel_src_int = vel_src_rsz_vf(l, k, j, 1:num_dims) + vel_src_int = vel_src_rsz_vf(l, k, j,1:num_dims) r_eff = y_cc(k) end select @@ -4775,7 +4302,7 @@ contains div_v_term_const = -(2.0_wp/3.0_wp)*divergence_cyl/Re_s select case (norm_dir) - case (1) ! X-face (axial normal, z_cyl) + case (1) ! X-face (axial normal, z_cyl) stress_vector_shear(1) = (2.0_wp*avg_dvdx_int(1))/Re_s + div_v_term_const if (num_dims > 1) then #:if not MFC_CASE_OPTIMIZATION or num_dims > 1 @@ -4787,44 +4314,48 @@ contains stress_vector_shear(3) = (avg_dvdz_int(1)/r_eff + avg_dvdx_int(3))/Re_s #:endif end if - case (2) ! Y-face (radial normal, r_cyl) + case (2) ! Y-face (radial normal, r_cyl) if (num_dims > 1) then #:if not MFC_CASE_OPTIMIZATION or num_dims > 1 stress_vector_shear(1) = (avg_dvdy_int(1) + avg_dvdx_int(2))/Re_s stress_vector_shear(2) = (2.0_wp*avg_dvdy_int(2))/Re_s + div_v_term_const if (num_dims > 2) then #:if not MFC_CASE_OPTIMIZATION or num_dims > 2 - stress_vector_shear(3) = (avg_dvdz_int(2)/r_eff - avg_v_int(3)/r_eff + avg_dvdy_int(3))/Re_s + stress_vector_shear(3) = (avg_dvdz_int(2)/r_eff - avg_v_int(3)/r_eff + avg_dvdy_int(3) & + & )/Re_s #:endif end if #:endif else stress_vector_shear(1) = (2.0_wp*avg_dvdx_int(1))/Re_s + div_v_term_const end if - case (3) ! Z-face (azimuthal normal, theta_cyl) + case (3) ! Z-face (azimuthal normal, theta_cyl) if (num_dims > 2) then #:if not MFC_CASE_OPTIMIZATION or num_dims > 2 stress_vector_shear(1) = (avg_dvdz_int(1)/r_eff + avg_dvdx_int(3))/Re_s stress_vector_shear(2) = (avg_dvdz_int(2)/r_eff - avg_v_int(3)/r_eff + avg_dvdy_int(3))/Re_s - stress_vector_shear(3) = (2.0_wp*(avg_dvdz_int(3)/r_eff + avg_v_int(2)/r_eff))/Re_s + div_v_term_const + stress_vector_shear(3) = (2.0_wp*(avg_dvdz_int(3)/r_eff + avg_v_int(2)/r_eff))/Re_s & + & + div_v_term_const #:endif end if end select $:GPU_LOOP(parallelism='[seq]') do i_vel = 1, num_dims - flux_src_vf(momxb + i_vel - 1)%sf(j, k, l) = flux_src_vf(momxb + i_vel - 1)%sf(j, k, l) - stress_vector_shear(i_vel) - flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, l) - vel_src_int(i_vel)*stress_vector_shear(i_vel) + flux_src_vf(momxb + i_vel - 1)%sf(j, k, l) = flux_src_vf(momxb + i_vel - 1)%sf(j, k, & + & l) - stress_vector_shear(i_vel) + flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, & + & l) - vel_src_int(i_vel)*stress_vector_shear(i_vel) end do end if if (bulk_stress) then stress_normal_bulk = divergence_cyl/Re_b - flux_src_vf(momxb + norm_dir - 1)%sf(j, k, l) = flux_src_vf(momxb + norm_dir - 1)%sf(j, k, l) - stress_normal_bulk + flux_src_vf(momxb + norm_dir - 1)%sf(j, k, l) = flux_src_vf(momxb + norm_dir - 1)%sf(j, k, & + & l) - stress_normal_bulk flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, l) - vel_src_int(norm_dir)*stress_normal_bulk end if - end do end do end do @@ -4832,9 +4363,8 @@ contains end subroutine s_compute_cylindrical_viscous_source_flux - !> @brief Computes Cartesian viscous source flux contributions for momentum and energy. - !! Calculates averaged velocity gradients, gets Re and interface velocities, - !! calls helpers for shear/bulk stress, then updates `flux_src_vf`. + !> @brief Computes Cartesian viscous source flux contributions for momentum and energy. Calculates averaged velocity gradients, + !! gets Re and interface velocities, calls helpers for shear/bulk stress, then updates `flux_src_vf`. !! @param[in] dvelL_dx_vf Left boundary d(vel)/dx (num_dims scalar_field). !! @param[in] dvelL_dy_vf Left boundary d(vel)/dy (num_dims scalar_field). !! @param[in] dvelL_dz_vf Left boundary d(vel)/dz (num_dims scalar_field). @@ -4843,52 +4373,44 @@ contains !! @param[in] dvelR_dz_vf Right boundary d(vel)/dz (num_dims scalar_field). !! @param[inout] flux_src_vf Intercell source flux array to update (sys_size scalar_field). !! @param[in] norm_dir Interface normal direction (1=x, 2=y, 3=z). - subroutine s_compute_cartesian_viscous_source_flux(dvelL_dx_vf, & - dvelL_dy_vf, & - dvelL_dz_vf, & - dvelR_dx_vf, & - dvelR_dy_vf, & - dvelR_dz_vf, & - flux_src_vf, & - norm_dir) + subroutine s_compute_cartesian_viscous_source_flux(dvelL_dx_vf, dvelL_dy_vf, dvelL_dz_vf, dvelR_dx_vf, dvelR_dy_vf, & + & dvelR_dz_vf, flux_src_vf, norm_dir) ! Arguments - type(scalar_field), dimension(num_dims), intent(in) :: dvelL_dx_vf, dvelR_dx_vf - type(scalar_field), dimension(num_dims), intent(in) :: dvelL_dy_vf, dvelR_dy_vf - type(scalar_field), dimension(num_dims), intent(in) :: dvelL_dz_vf, dvelR_dz_vf + type(scalar_field), dimension(num_dims), intent(in) :: dvelL_dx_vf, dvelR_dx_vf + type(scalar_field), dimension(num_dims), intent(in) :: dvelL_dy_vf, dvelR_dy_vf + type(scalar_field), dimension(num_dims), intent(in) :: dvelL_dz_vf, dvelR_dz_vf type(scalar_field), dimension(sys_size), intent(inout) :: flux_src_vf - integer, intent(in) :: norm_dir + integer, intent(in) :: norm_dir ! Local variables + #:if not MFC_CASE_OPTIMIZATION and USING_AMD - real(wp), dimension(3, 3) :: vel_grad_avg !< Averaged velocity gradient tensor `d(vel_i)/d(coord_j)`. - real(wp), dimension(3, 3) :: current_tau_shear !< Current shear stress tensor. - real(wp), dimension(3, 3) :: current_tau_bulk !< Current bulk stress tensor. - real(wp), dimension(3) :: vel_src_at_interface !< Interface velocities (u,v,w) for viscous work. + real(wp), dimension(3, 3) :: vel_grad_avg !< Averaged velocity gradient tensor `d(vel_i)/d(coord_j)`. + real(wp), dimension(3, 3) :: current_tau_shear !< Current shear stress tensor. + real(wp), dimension(3, 3) :: current_tau_bulk !< Current bulk stress tensor. + real(wp), dimension(3) :: vel_src_at_interface !< Interface velocities (u,v,w) for viscous work. #:else - real(wp), dimension(num_dims, num_dims) :: vel_grad_avg !< Averaged velocity gradient tensor `d(vel_i)/d(coord_j)`. - real(wp), dimension(num_dims, num_dims) :: current_tau_shear !< Current shear stress tensor. - real(wp), dimension(num_dims, num_dims) :: current_tau_bulk !< Current bulk stress tensor. - real(wp), dimension(num_dims) :: vel_src_at_interface !< Interface velocities (u,v,w) for viscous work. + real(wp), dimension(num_dims, num_dims) :: vel_grad_avg !< Averaged velocity gradient tensor `d(vel_i)/d(coord_j)`. + real(wp), dimension(num_dims, num_dims) :: current_tau_shear !< Current shear stress tensor. + real(wp), dimension(num_dims, num_dims) :: current_tau_bulk !< Current bulk stress tensor. + real(wp), dimension(num_dims) :: vel_src_at_interface !< Interface velocities (u,v,w) for viscous work. #:endif - integer, dimension(3) :: idx_right_phys !< Physical (j,k,l) indices for right state. - - real(wp) :: Re_shear !< Interface shear Reynolds number. - real(wp) :: Re_bulk !< Interface bulk Reynolds number. - - integer :: j_loop !< Physical x-index loop iterator. - integer :: k_loop !< Physical y-index loop iterator. - integer :: l_loop !< Physical z-index loop iterator. - integer :: i_dim !< Generic dimension/component iterator. - integer :: vel_comp_idx !< Velocity component iterator (1=u, 2=v, 3=w). - - real(wp) :: divergence_v !< Velocity divergence at interface. - - $:GPU_PARALLEL_LOOP(collapse=3, private='[idx_right_phys, vel_grad_avg, current_tau_shear, current_tau_bulk, vel_src_at_interface, Re_shear, Re_bulk, divergence_v, i_dim, vel_comp_idx]') + integer, dimension(3) :: idx_right_phys !< Physical (j,k,l) indices for right state. + real(wp) :: Re_shear !< Interface shear Reynolds number. + real(wp) :: Re_bulk !< Interface bulk Reynolds number. + integer :: j_loop !< Physical x-index loop iterator. + integer :: k_loop !< Physical y-index loop iterator. + integer :: l_loop !< Physical z-index loop iterator. + integer :: i_dim !< Generic dimension/component iterator. + integer :: vel_comp_idx !< Velocity component iterator (1=u, 2=v, 3=w). + real(wp) :: divergence_v !< Velocity divergence at interface. + + $:GPU_PARALLEL_LOOP(collapse=3, private='[idx_right_phys, vel_grad_avg, current_tau_shear, current_tau_bulk, & + & vel_src_at_interface, Re_shear, Re_bulk, divergence_v, i_dim, vel_comp_idx]') do l_loop = isz%beg, isz%end do k_loop = isy%beg, isy%end do j_loop = isx%beg, isx%end - idx_right_phys(1) = j_loop idx_right_phys(2) = k_loop idx_right_phys(3) = l_loop @@ -4896,18 +4418,21 @@ contains vel_grad_avg = 0.0_wp do vel_comp_idx = 1, num_dims - vel_grad_avg(vel_comp_idx, 1) = 0.5_wp*(dvelL_dx_vf(vel_comp_idx)%sf(j_loop, k_loop, l_loop) + & - dvelR_dx_vf(vel_comp_idx)%sf(idx_right_phys(1), idx_right_phys(2), idx_right_phys(3))) + vel_grad_avg(vel_comp_idx, 1) = 0.5_wp*(dvelL_dx_vf(vel_comp_idx)%sf(j_loop, k_loop, & + & l_loop) + dvelR_dx_vf(vel_comp_idx)%sf(idx_right_phys(1), idx_right_phys(2), & + & idx_right_phys(3))) if (num_dims > 1) then #:if not MFC_CASE_OPTIMIZATION or num_dims > 1 - vel_grad_avg(vel_comp_idx, 2) = 0.5_wp*(dvelL_dy_vf(vel_comp_idx)%sf(j_loop, k_loop, l_loop) + & - dvelR_dy_vf(vel_comp_idx)%sf(idx_right_phys(1), idx_right_phys(2), idx_right_phys(3))) + vel_grad_avg(vel_comp_idx, 2) = 0.5_wp*(dvelL_dy_vf(vel_comp_idx)%sf(j_loop, k_loop, & + & l_loop) + dvelR_dy_vf(vel_comp_idx)%sf(idx_right_phys(1), idx_right_phys(2), & + & idx_right_phys(3))) #:endif end if if (num_dims > 2) then #:if not MFC_CASE_OPTIMIZATION or num_dims > 2 - vel_grad_avg(vel_comp_idx, 3) = 0.5_wp*(dvelL_dz_vf(vel_comp_idx)%sf(j_loop, k_loop, l_loop) + & - dvelR_dz_vf(vel_comp_idx)%sf(idx_right_phys(1), idx_right_phys(2), idx_right_phys(3))) + vel_grad_avg(vel_comp_idx, 3) = 0.5_wp*(dvelL_dz_vf(vel_comp_idx)%sf(j_loop, k_loop, & + & l_loop) + dvelR_dz_vf(vel_comp_idx)%sf(idx_right_phys(1), idx_right_phys(2), & + & idx_right_phys(3))) #:endif end if end do @@ -4943,12 +4468,11 @@ contains call s_calculate_shear_stress_tensor(vel_grad_avg, Re_shear, divergence_v, current_tau_shear) do i_dim = 1, num_dims - flux_src_vf(momxb + i_dim - 1)%sf(j_loop, k_loop, l_loop) = & - flux_src_vf(momxb + i_dim - 1)%sf(j_loop, k_loop, l_loop) - current_tau_shear(norm_dir, i_dim) + flux_src_vf(momxb + i_dim - 1)%sf(j_loop, k_loop, l_loop) = flux_src_vf(momxb + i_dim - 1)%sf(j_loop, & + & k_loop, l_loop) - current_tau_shear(norm_dir, i_dim) - flux_src_vf(E_idx)%sf(j_loop, k_loop, l_loop) = & - flux_src_vf(E_idx)%sf(j_loop, k_loop, l_loop) - & - vel_src_at_interface(i_dim)*current_tau_shear(norm_dir, i_dim) + flux_src_vf(E_idx)%sf(j_loop, k_loop, l_loop) = flux_src_vf(E_idx)%sf(j_loop, k_loop, & + & l_loop) - vel_src_at_interface(i_dim)*current_tau_shear(norm_dir, i_dim) end do end if @@ -4957,15 +4481,13 @@ contains call s_calculate_bulk_stress_tensor(Re_bulk, divergence_v, current_tau_bulk) do i_dim = 1, num_dims - flux_src_vf(momxb + i_dim - 1)%sf(j_loop, k_loop, l_loop) = & - flux_src_vf(momxb + i_dim - 1)%sf(j_loop, k_loop, l_loop) - current_tau_bulk(norm_dir, i_dim) + flux_src_vf(momxb + i_dim - 1)%sf(j_loop, k_loop, l_loop) = flux_src_vf(momxb + i_dim - 1)%sf(j_loop, & + & k_loop, l_loop) - current_tau_bulk(norm_dir, i_dim) - flux_src_vf(E_idx)%sf(j_loop, k_loop, l_loop) = & - flux_src_vf(E_idx)%sf(j_loop, k_loop, l_loop) - & - vel_src_at_interface(i_dim)*current_tau_bulk(norm_dir, i_dim) + flux_src_vf(E_idx)%sf(j_loop, k_loop, l_loop) = flux_src_vf(E_idx)%sf(j_loop, k_loop, & + & l_loop) - vel_src_at_interface(i_dim)*current_tau_bulk(norm_dir, i_dim) end do end if - end do end do end do @@ -4973,29 +4495,29 @@ contains end subroutine s_compute_cartesian_viscous_source_flux - !> @brief Calculates shear stress tensor components. - !! tau_ij_shear = ( (dui/dxj + duj/dxi) - (2/3)*(div_v)*delta_ij ) / Re_shear + !> @brief Calculates shear stress tensor components. tau_ij_shear = ( (dui/dxj + duj/dxi) - (2/3)*(div_v)*delta_ij ) / Re_shear !! @param[in] vel_grad_avg Averaged velocity gradient tensor (d(vel_i)/d(coord_j)). !! @param[in] Re_shear Shear Reynolds number. !! @param[in] divergence_v Velocity divergence (du/dx + dv/dy + dw/dz). !! @param[out] tau_shear_out Calculated shear stress tensor (stress on i-face, j-direction). subroutine s_calculate_shear_stress_tensor(vel_grad_avg, Re_shear, divergence_v, tau_shear_out) + $:GPU_ROUTINE(parallelism='[seq]') ! Arguments #:if not MFC_CASE_OPTIMIZATION and USING_AMD - real(wp), dimension(3, 3), intent(in) :: vel_grad_avg + real(wp), dimension(3, 3), intent(in) :: vel_grad_avg real(wp), dimension(3, 3), intent(out) :: tau_shear_out #:else - real(wp), dimension(num_dims, num_dims), intent(in) :: vel_grad_avg + real(wp), dimension(num_dims, num_dims), intent(in) :: vel_grad_avg real(wp), dimension(num_dims, num_dims), intent(out) :: tau_shear_out #:endif real(wp), intent(in) :: Re_shear real(wp), intent(in) :: divergence_v ! Local variables - integer :: i_dim !< Loop iterator for face normal. - integer :: j_dim !< Loop iterator for force component direction. + integer :: i_dim !< Loop iterator for face normal. + integer :: j_dim !< Loop iterator for force component direction. tau_shear_out = 0.0_wp @@ -5003,20 +4525,19 @@ contains do j_dim = 1, num_dims tau_shear_out(i_dim, j_dim) = (vel_grad_avg(j_dim, i_dim) + vel_grad_avg(i_dim, j_dim))/Re_shear if (i_dim == j_dim) then - tau_shear_out(i_dim, j_dim) = tau_shear_out(i_dim, j_dim) - & - (2.0_wp/3.0_wp)*divergence_v/Re_shear + tau_shear_out(i_dim, j_dim) = tau_shear_out(i_dim, j_dim) - (2.0_wp/3.0_wp)*divergence_v/Re_shear end if end do end do end subroutine s_calculate_shear_stress_tensor - !> @brief Calculates bulk stress tensor components (diagonal only). - !! tau_ii_bulk = (div_v) / Re_bulk. Off-diagonals are zero. + !> @brief Calculates bulk stress tensor components (diagonal only). tau_ii_bulk = (div_v) / Re_bulk. Off-diagonals are zero. !! @param[in] Re_bulk Bulk Reynolds number. !! @param[in] divergence_v Velocity divergence (du/dx + dv/dy + dw/dz). !! @param[out] tau_bulk_out Calculated bulk stress tensor (stress on i-face, i-direction). subroutine s_calculate_bulk_stress_tensor(Re_bulk, divergence_v, tau_bulk_out) + $:GPU_ROUTINE(parallelism='[seq]') ! Arguments @@ -5029,7 +4550,7 @@ contains #:endif ! Local variables - integer :: i_dim !< Loop iterator for diagonal components. + integer :: i_dim !< Loop iterator for diagonal components. tau_bulk_out = 0.0_wp @@ -5039,33 +4560,26 @@ contains end subroutine s_calculate_bulk_stress_tensor - !> Deallocation and/or disassociation procedures that are - !! needed to finalize the selected Riemann problem solver - !! @param flux_vf Intercell fluxes - !! @param flux_src_vf Intercell source fluxes - !! @param flux_gsrc_vf Intercell geometric source fluxes - !! @param norm_dir Dimensional splitting coordinate direction - subroutine s_finalize_riemann_solver(flux_vf, flux_src_vf, & - flux_gsrc_vf, & - norm_dir) - - type(scalar_field), & - dimension(sys_size), & - intent(inout) :: flux_vf, flux_src_vf, flux_gsrc_vf - - integer, intent(in) :: norm_dir + !> Deallocation and/or disassociation procedures that are needed to finalize the selected Riemann problem solver + !! @param flux_vf Intercell fluxes + !! @param flux_src_vf Intercell source fluxes + !! @param flux_gsrc_vf Intercell geometric source fluxes + !! @param norm_dir Dimensional splitting coordinate direction + subroutine s_finalize_riemann_solver(flux_vf, flux_src_vf, flux_gsrc_vf, norm_dir) - integer :: i, j, k, l !< Generic loop iterators + type(scalar_field), dimension(sys_size), intent(inout) :: flux_vf, flux_src_vf, flux_gsrc_vf + integer, intent(in) :: norm_dir + integer :: i, j, k, l !< Generic loop iterators ! Reshaping Outputted Data in y-direction + if (norm_dir == 2) then $:GPU_PARALLEL_LOOP(collapse=4) do i = 1, sys_size do l = is3%beg, is3%end do j = is1%beg, is1%end do k = is2%beg, is2%end - flux_vf(i)%sf(k, j, l) = & - flux_rsy_vf(j, k, l, i) + flux_vf(i)%sf(k, j, l) = flux_rsy_vf(j, k, l, i) end do end do end do @@ -5078,8 +4592,7 @@ contains do l = is3%beg, is3%end do j = is1%beg, is1%end do k = is2%beg, is2%end - flux_gsrc_vf(i)%sf(k, j, l) = & - flux_gsrc_rsy_vf(j, k, l, i) + flux_gsrc_vf(i)%sf(k, j, l) = flux_gsrc_rsy_vf(j, k, l, i) end do end do end do @@ -5091,8 +4604,7 @@ contains do l = is3%beg, is3%end do j = is1%beg, is1%end do k = is2%beg, is2%end - flux_src_vf(advxb)%sf(k, j, l) = & - flux_src_rsy_vf(j, k, l, advxb) + flux_src_vf(advxb)%sf(k, j, l) = flux_src_rsy_vf(j, k, l, advxb) end do end do end do @@ -5104,25 +4616,21 @@ contains do l = is3%beg, is3%end do j = is1%beg, is1%end do k = is2%beg, is2%end - flux_src_vf(i)%sf(k, j, l) = & - flux_src_rsy_vf(j, k, l, i) + flux_src_vf(i)%sf(k, j, l) = flux_src_rsy_vf(j, k, l, i) end do end do end do end do $:END_GPU_PARALLEL_LOOP() - end if ! Reshaping Outputted Data in z-direction - elseif (norm_dir == 3) then + else if (norm_dir == 3) then $:GPU_PARALLEL_LOOP(collapse=4) do i = 1, sys_size do j = is1%beg, is1%end do k = is2%beg, is2%end do l = is3%beg, is3%end - - flux_vf(i)%sf(l, k, j) = & - flux_rsz_vf(j, k, l, i) + flux_vf(i)%sf(l, k, j) = flux_rsz_vf(j, k, l, i) end do end do end do @@ -5134,9 +4642,7 @@ contains do j = is1%beg, is1%end do k = is2%beg, is2%end do l = is3%beg, is3%end - - flux_gsrc_vf(i)%sf(l, k, j) = & - flux_gsrc_rsz_vf(j, k, l, i) + flux_gsrc_vf(i)%sf(l, k, j) = flux_gsrc_rsz_vf(j, k, l, i) end do end do end do @@ -5148,8 +4654,7 @@ contains do j = is1%beg, is1%end do k = is2%beg, is2%end do l = is3%beg, is3%end - flux_src_vf(advxb)%sf(l, k, j) = & - flux_src_rsz_vf(j, k, l, advxb) + flux_src_vf(advxb)%sf(l, k, j) = flux_src_rsz_vf(j, k, l, advxb) end do end do end do @@ -5161,23 +4666,20 @@ contains do j = is1%beg, is1%end do k = is2%beg, is2%end do l = is3%beg, is3%end - flux_src_vf(i)%sf(l, k, j) = & - flux_src_rsz_vf(j, k, l, i) + flux_src_vf(i)%sf(l, k, j) = flux_src_rsz_vf(j, k, l, i) end do end do end do end do $:END_GPU_PARALLEL_LOOP() - end if - elseif (norm_dir == 1) then + else if (norm_dir == 1) then $:GPU_PARALLEL_LOOP(collapse=4) do i = 1, sys_size do l = is3%beg, is3%end do k = is2%beg, is2%end do j = is1%beg, is1%end - flux_vf(i)%sf(j, k, l) = & - flux_rsx_vf(j, k, l, i) + flux_vf(i)%sf(j, k, l) = flux_rsx_vf(j, k, l, i) end do end do end do @@ -5188,8 +4690,7 @@ contains do l = is3%beg, is3%end do k = is2%beg, is2%end do j = is1%beg, is1%end - flux_src_vf(advxb)%sf(j, k, l) = & - flux_src_rsx_vf(j, k, l, advxb) + flux_src_vf(advxb)%sf(j, k, l) = flux_src_rsx_vf(j, k, l, advxb) end do end do end do @@ -5201,8 +4702,7 @@ contains do l = is3%beg, is3%end do k = is2%beg, is2%end do j = is1%beg, is1%end - flux_src_vf(i)%sf(j, k, l) = & - flux_src_rsx_vf(j, k, l, i) + flux_src_vf(i)%sf(j, k, l) = flux_src_rsx_vf(j, k, l, i) end do end do end do diff --git a/src/simulation/m_sim_helpers.fpp b/src/simulation/m_sim_helpers.fpp index f8e8526ced..180ea05028 100644 --- a/src/simulation/m_sim_helpers.fpp +++ b/src/simulation/m_sim_helpers.fpp @@ -8,34 +8,31 @@ !> @brief Simulation helper routines for enthalpy computation, CFL calculation, and stability checks module m_sim_helpers - use m_derived_types !< Definitions of the derived types - + use m_derived_types !< Definitions of the derived types use m_global_parameters - use m_variables_conversion implicit none - private; public :: s_compute_enthalpy, & - s_compute_stability_from_dt, & - s_compute_dt_from_cfl + private; public :: s_compute_enthalpy, s_compute_stability_from_dt, s_compute_dt_from_cfl contains !> Computes the modified dtheta for Fourier filtering in azimuthal direction - !! @param k y coordinate index - !! @param l z coordinate index - !! @return fltr_dtheta Modified dtheta value for cylindrical coordinates + !! @param k y coordinate index + !! @param l z coordinate index + !! @return fltr_dtheta Modified dtheta value for cylindrical coordinates function f_compute_filtered_dtheta(k, l) result(fltr_dtheta) + $:GPU_ROUTINE(parallelism='[seq]') integer, intent(in) :: k, l - real(wp) :: fltr_dtheta - integer :: Nfq + real(wp) :: fltr_dtheta + integer :: Nfq if (grid_geometry == 3) then if (k == 0) then fltr_dtheta = 2._wp*pi*y_cb(0)/3._wp - elseif (k <= fourier_rings) then + else if (k <= fourier_rings) then Nfq = min(floor(2._wp*real(k, wp)*pi), (p + 1)/2 + 1) fltr_dtheta = 2._wp*pi*y_cb(k - 1)/real(Nfq, wp) else @@ -44,63 +41,61 @@ contains else fltr_dtheta = 0._wp end if + end function f_compute_filtered_dtheta !> Computes inviscid CFL terms for multi-dimensional cases (2D/3D only) - !! @param vel directional velocities - !! @param c mixture speed of sound - !! @param j x coordinate index - !! @param k y coordinate index - !! @param l z coordinate index - !! @return cfl_terms computed CFL terms for 2D/3D cases + !! @param vel directional velocities + !! @param c mixture speed of sound + !! @param j x coordinate index + !! @param k y coordinate index + !! @param l z coordinate index + !! @return cfl_terms computed CFL terms for 2D/3D cases function f_compute_multidim_cfl_terms(vel, c, j, k, l) result(cfl_terms) + $:GPU_ROUTINE(parallelism='[seq]') real(wp), dimension(num_vels), intent(in) :: vel - real(wp), intent(in) :: c - integer, intent(in) :: j, k, l - real(wp) :: cfl_terms - real(wp) :: fltr_dtheta + real(wp), intent(in) :: c + integer, intent(in) :: j, k, l + real(wp) :: cfl_terms + real(wp) :: fltr_dtheta fltr_dtheta = f_compute_filtered_dtheta(k, l) if (p > 0) then - !3D + ! 3D #:if not MFC_CASE_OPTIMIZATION or num_dims > 2 if (grid_geometry == 3) then - cfl_terms = min(dx(j)/(abs(vel(1)) + c), & - dy(k)/(abs(vel(2)) + c), & - fltr_dtheta/(abs(vel(3)) + c)) + cfl_terms = min(dx(j)/(abs(vel(1)) + c), dy(k)/(abs(vel(2)) + c), fltr_dtheta/(abs(vel(3)) + c)) else - cfl_terms = min(dx(j)/(abs(vel(1)) + c), & - dy(k)/(abs(vel(2)) + c), & - dz(l)/(abs(vel(3)) + c)) + cfl_terms = min(dx(j)/(abs(vel(1)) + c), dy(k)/(abs(vel(2)) + c), dz(l)/(abs(vel(3)) + c)) end if #:endif else - !2D - cfl_terms = min(dx(j)/(abs(vel(1)) + c), & - dy(k)/(abs(vel(2)) + c)) + ! 2D + cfl_terms = min(dx(j)/(abs(vel(1)) + c), dy(k)/(abs(vel(2)) + c)) end if + end function f_compute_multidim_cfl_terms !> Computes enthalpy - !! @param q_prim_vf cell centered primitive variables - !! @param pres mixture pressure - !! @param rho mixture density - !! @param gamma mixture gamma - !! @param pi_inf mixture pi_inf - !! @param Re mixture reynolds number - !! @param H mixture enthalpy - !! @param alpha component alphas - !! @param vel directional velocities - !! @param vel_sum squard sum of velocity components - !! @param qv Fluid reference energy - !! @param j x index - !! @param k y index - !! @param l z index + !! @param q_prim_vf cell centered primitive variables + !! @param pres mixture pressure + !! @param rho mixture density + !! @param gamma mixture gamma + !! @param pi_inf mixture pi_inf + !! @param Re mixture reynolds number + !! @param H mixture enthalpy + !! @param alpha component alphas + !! @param vel directional velocities + !! @param vel_sum squard sum of velocity components + !! @param qv Fluid reference energy + !! @param j x index + !! @param k y index + !! @param l z index subroutine s_compute_enthalpy(q_prim_vf, pres, rho, gamma, pi_inf, Re, H, alpha, vel, vel_sum, qv, j, k, l) - $:GPU_ROUTINE(function_name='s_compute_enthalpy',parallelism='[seq]', & - & cray_inline=True) + + $:GPU_ROUTINE(function_name='s_compute_enthalpy',parallelism='[seq]', cray_inline=True) type(scalar_field), intent(in), dimension(sys_size) :: q_prim_vf #:if not MFC_CASE_OPTIMIZATION and USING_AMD @@ -108,11 +103,11 @@ contains real(wp), intent(inout), dimension(3) :: vel #:else real(wp), intent(inout), dimension(num_fluids) :: alpha - real(wp), intent(inout), dimension(num_vels) :: vel + real(wp), intent(inout), dimension(num_vels) :: vel #:endif - real(wp), intent(inout) :: rho, gamma, pi_inf, vel_sum, H, pres - real(wp), intent(out) :: qv - integer, intent(in) :: j, k, l + real(wp), intent(inout) :: rho, gamma, pi_inf, vel_sum, H, pres + real(wp), intent(out) :: qv + integer, intent(in) :: j, k, l real(wp), dimension(2), intent(inout) :: Re #:if not MFC_CASE_OPTIMIZATION and USING_AMD real(wp), dimension(3) :: alpha_rho, Gs @@ -120,14 +115,12 @@ contains real(wp), dimension(num_fluids) :: alpha_rho, Gs #:endif real(wp) :: E, G_local - - integer :: i + integer :: i call s_compute_species_fraction(q_prim_vf, j, k, l, alpha_rho, alpha) if (elasticity) then - call s_convert_species_to_mixture_variables_acc(rho, gamma, pi_inf, qv, alpha, & - alpha_rho, Re, G_local, Gs) + call s_convert_species_to_mixture_variables_acc(rho, gamma, pi_inf, qv, alpha, alpha_rho, Re, G_local, Gs) else call s_convert_species_to_mixture_variables_acc(rho, gamma, pi_inf, qv, alpha, alpha_rho, Re) end if @@ -168,61 +161,51 @@ contains end subroutine s_compute_enthalpy !> Computes stability criterion for a specified dt - !! @param vel directional velocities - !! @param c mixture speed of sound - !! @param rho Density - !! @param Re_l mixture Reynolds number - !! @param j x index - !! @param k y index - !! @param l z index - !! @param icfl cell-centered inviscid cfl number - !! @param vcfl (optional) cell-centered viscous CFL number - !! @param Rc (optional) cell centered Rc + !! @param vel directional velocities + !! @param c mixture speed of sound + !! @param rho Density + !! @param Re_l mixture Reynolds number + !! @param j x index + !! @param k y index + !! @param l z index + !! @param icfl cell-centered inviscid cfl number + !! @param vcfl (optional) cell-centered viscous CFL number + !! @param Rc (optional) cell centered Rc subroutine s_compute_stability_from_dt(vel, c, rho, Re_l, j, k, l, icfl, vcfl, Rc) + $:GPU_ROUTINE(parallelism='[seq]') real(wp), intent(in), dimension(num_vels) :: vel - real(wp), intent(in) :: c, rho - real(wp), intent(inout) :: icfl - real(wp), intent(inout), optional :: vcfl, Rc - real(wp), dimension(2), intent(in) :: Re_l - integer, intent(in) :: j, k, l - - real(wp) :: fltr_dtheta + real(wp), intent(in) :: c, rho + real(wp), intent(inout) :: icfl + real(wp), intent(inout), optional :: vcfl, Rc + real(wp), dimension(2), intent(in) :: Re_l + integer, intent(in) :: j, k, l + real(wp) :: fltr_dtheta ! Inviscid CFL calculation - if (p > 0 .or. n > 0) then ! 2D/3D + if (p > 0 .or. n > 0) then ! 2D/3D icfl = dt/f_compute_multidim_cfl_terms(vel, c, j, k, l) - else ! 1D + else ! 1D icfl = (dt/dx(j))*(abs(vel(1)) + c) end if ! Viscous calculations if (viscous) then - if (p > 0) then !3D + if (p > 0) then ! 3D #:if not MFC_CASE_OPTIMIZATION or num_dims > 2 if (grid_geometry == 3) then fltr_dtheta = f_compute_filtered_dtheta(k, l) - vcfl = maxval(dt/Re_l/rho) & - /min(dx(j), dy(k), fltr_dtheta)**2._wp - Rc = min(dx(j)*(abs(vel(1)) + c), & - dy(k)*(abs(vel(2)) + c), & - fltr_dtheta*(abs(vel(3)) + c)) & - /maxval(1._wp/Re_l) + vcfl = maxval(dt/Re_l/rho)/min(dx(j), dy(k), fltr_dtheta)**2._wp + Rc = min(dx(j)*(abs(vel(1)) + c), dy(k)*(abs(vel(2)) + c), fltr_dtheta*(abs(vel(3)) + c))/maxval(1._wp/Re_l) else - vcfl = maxval(dt/Re_l/rho) & - /min(dx(j), dy(k), dz(l))**2._wp - Rc = min(dx(j)*(abs(vel(1)) + c), & - dy(k)*(abs(vel(2)) + c), & - dz(l)*(abs(vel(3)) + c)) & - /maxval(1._wp/Re_l) + vcfl = maxval(dt/Re_l/rho)/min(dx(j), dy(k), dz(l))**2._wp + Rc = min(dx(j)*(abs(vel(1)) + c), dy(k)*(abs(vel(2)) + c), dz(l)*(abs(vel(3)) + c))/maxval(1._wp/Re_l) end if #:endif - elseif (n > 0) then !2D + else if (n > 0) then ! 2D vcfl = maxval(dt/Re_l/rho)/min(dx(j), dy(k))**2._wp - Rc = min(dx(j)*(abs(vel(1)) + c), & - dy(k)*(abs(vel(2)) + c)) & - /maxval(1._wp/Re_l) - else !1D + Rc = min(dx(j)*(abs(vel(1)) + c), dy(k)*(abs(vel(2)) + c))/maxval(1._wp/Re_l) + else ! 1D vcfl = maxval(dt/Re_l/rho)/dx(j)**2._wp Rc = dx(j)*(abs(vel(1)) + c)/maxval(1._wp/Re_l) end if @@ -231,46 +214,44 @@ contains end subroutine s_compute_stability_from_dt !> Computes dt for a specified CFL number - !! @param vel directional velocities - !! @param c Speed of sound - !! @param max_dt cell centered maximum dt - !! @param rho cell centered density - !! @param Re_l cell centered Reynolds number - !! @param j x coordinate - !! @param k y coordinate - !! @param l z coordinate + !! @param vel directional velocities + !! @param c Speed of sound + !! @param max_dt cell centered maximum dt + !! @param rho cell centered density + !! @param Re_l cell centered Reynolds number + !! @param j x coordinate + !! @param k y coordinate + !! @param l z coordinate subroutine s_compute_dt_from_cfl(vel, c, max_dt, rho, Re_l, j, k, l) + $:GPU_ROUTINE(parallelism='[seq]') real(wp), dimension(num_vels), intent(in) :: vel - real(wp), intent(in) :: c, rho - real(wp), intent(inout) :: max_dt - real(wp), dimension(2), intent(in) :: Re_l - integer, intent(in) :: j, k, l - - real(wp) :: icfl_dt, vcfl_dt - real(wp) :: fltr_dtheta + real(wp), intent(in) :: c, rho + real(wp), intent(inout) :: max_dt + real(wp), dimension(2), intent(in) :: Re_l + integer, intent(in) :: j, k, l + real(wp) :: icfl_dt, vcfl_dt + real(wp) :: fltr_dtheta ! Inviscid CFL calculation - if (p > 0 .or. n > 0) then ! 2D/3D cases + if (p > 0 .or. n > 0) then ! 2D/3D cases icfl_dt = cfl_target*f_compute_multidim_cfl_terms(vel, c, j, k, l) - else ! 1D cases + else ! 1D cases icfl_dt = cfl_target*(dx(j)/(abs(vel(1)) + c)) end if ! Viscous calculations if (viscous) then - if (p > 0) then !3D + if (p > 0) then ! 3D if (grid_geometry == 3) then fltr_dtheta = f_compute_filtered_dtheta(k, l) - vcfl_dt = cfl_target*(min(dx(j), dy(k), fltr_dtheta)**2._wp) & - /maxval(1/(rho*Re_l)) + vcfl_dt = cfl_target*(min(dx(j), dy(k), fltr_dtheta)**2._wp)/maxval(1/(rho*Re_l)) else - vcfl_dt = cfl_target*(min(dx(j), dy(k), dz(l))**2._wp) & - /maxval(1/(rho*Re_l)) + vcfl_dt = cfl_target*(min(dx(j), dy(k), dz(l))**2._wp)/maxval(1/(rho*Re_l)) end if - elseif (n > 0) then !2D + else if (n > 0) then ! 2D vcfl_dt = cfl_target*(min(dx(j), dy(k))**2._wp)/maxval((1/Re_l)/rho) - else !1D + else ! 1D vcfl_dt = cfl_target*(dx(j)**2._wp)/maxval(1/(rho*Re_l)) end if end if diff --git a/src/simulation/m_start_up.fpp b/src/simulation/m_start_up.fpp index 9ee99b273e..7edb684cf3 100644 --- a/src/simulation/m_start_up.fpp +++ b/src/simulation/m_start_up.fpp @@ -8,106 +8,61 @@ !> @brief Reads input files, loads initial conditions and grid data, and orchestrates solver initialization and finalization module m_start_up - use m_derived_types !< Definitions of the derived types - - use m_global_parameters !< Definitions of the global parameters - - use m_mpi_proxy !< Message passing interface (MPI) module proxy - + use m_derived_types !< Definitions of the derived types + use m_global_parameters !< Definitions of the global parameters + use m_mpi_proxy !< Message passing interface (MPI) module proxy use m_mpi_common - - use m_variables_conversion !< State variables type conversion procedures - - use m_weno !< Weighted and essentially non-oscillatory (WENO) - !! schemes for spatial reconstruction of variables - - use m_muscl !< Monotonic Upstream-centered (MUSCL) - !! schemes for convservation laws - - use m_riemann_solvers !< Exact and approximate Riemann problem solvers - - use m_cbc !< Characteristic boundary conditions (CBC) - + use m_variables_conversion !< State variables type conversion procedures + use m_weno !< Weighted and essentially non-oscillatory (WENO) schemes for spatial reconstruction of variables + use m_muscl !< Monotonic Upstream-centered (MUSCL) schemes for convservation laws + use m_riemann_solvers !< Exact and approximate Riemann problem solvers + use m_cbc !< Characteristic boundary conditions (CBC) use m_boundary_common - - use m_acoustic_src !< Acoustic source calculations - - use m_rhs !< Right-hand-side (RHS) evaluation procedures - - use m_chemistry !< Chemistry module - - use m_data_output !< Run-time info & solution data output procedures - - use m_time_steppers !< Time-stepping algorithms - - use m_qbmm !< Quadrature MOM - - use m_derived_variables !< Procedures used to compute quantities derived - !! from the conservative and primitive variables + use m_acoustic_src !< Acoustic source calculations + use m_rhs !< Right-hand-side (RHS) evaluation procedures + use m_chemistry !< Chemistry module + use m_data_output !< Run-time info & solution data output procedures + use m_time_steppers !< Time-stepping algorithms + use m_qbmm !< Quadrature MOM + use m_derived_variables !< Procedures used to compute quantities derived from the conservative and primitive variables use m_hypoelastic - use m_hyperelastic - use m_phase_change !< Phase-change module - use m_viscous - use m_bubbles_EE !< Ensemble-averaged bubble dynamics routines - use m_bubbles_EL !< Lagrange bubble dynamics routines - use ieee_arithmetic - use m_helper_basic !< Functions to compare floating point numbers - use m_helper $:USE_GPU_MODULE() use m_nvtx - use m_ibm - use m_compile_specific - use m_checker_common - use m_checker - use m_surface_tension - use m_body_forces - use m_sim_helpers - use m_igr implicit none - private; public :: s_read_input_file, & - s_check_input_file, & - s_read_data_files, & - s_read_serial_data_files, & - s_read_parallel_data_files, & - s_initialize_internal_energy_equations, & - s_initialize_modules, s_initialize_gpu_vars, & - s_initialize_mpi_domain, s_finalize_modules, & - s_perform_time_step, s_save_data, & - s_save_performance_metrics + private; public :: s_read_input_file, s_check_input_file, s_read_data_files, s_read_serial_data_files, & + & s_read_parallel_data_files, s_initialize_internal_energy_equations, s_initialize_modules, s_initialize_gpu_vars, & + & s_initialize_mpi_domain, s_finalize_modules, s_perform_time_step, s_save_data, s_save_performance_metrics type(scalar_field), allocatable, dimension(:) :: q_cons_temp - - real(wp) :: dt_init + real(wp) :: dt_init contains !> Read data files. Dispatch subroutine that replaces procedure pointer. - !! @param q_cons_vf Conservative variables + !! @param q_cons_vf Conservative variables impure subroutine s_read_data_files(q_cons_vf) - type(scalar_field), & - dimension(sys_size), & - intent(inout) :: q_cons_vf + type(scalar_field), dimension(sys_size), intent(inout) :: q_cons_vf if (.not. parallel_io) then call s_read_serial_data_files(q_cons_vf) @@ -117,23 +72,20 @@ contains end subroutine s_read_data_files - !> The purpose of this procedure is to first verify that an - !! input file has been made available by the user. Provided - !! that this is so, the input file is then read in. + !> The purpose of this procedure is to first verify that an input file has been made available by the user. Provided that this + !! is so, the input file is then read in. impure subroutine s_read_input_file ! Relative path to the input file provided by the user character(LEN=name_len), parameter :: file_path = './simulation.inp' - - logical :: file_exist !< - !! Logical used to check the existence of the input file - - integer :: iostatus - !! Integer to check iostat of file read + logical :: file_exist !< Logical used to check the existence of the input file + integer :: iostatus + !! Integer to check iostat of file read character(len=1000) :: line ! Namelist of the global parameters which may be specified by user + namelist /user_inputs/ case_dir, run_time_info, m, n, p, dt, & t_step_start, t_step_stop, t_step_save, t_step_print, & model_eqns, mpp_lim, time_stepper, weno_eps, & @@ -149,50 +101,33 @@ contains null_weights, precision, parallel_io, cyl_coord, & rhoref, pref, bubbles_euler, bubble_model, & R0ref, chem_params, & -#:if not MFC_CASE_OPTIMIZATION + #:if not MFC_CASE_OPTIMIZATION nb, mapped_weno, wenoz, teno, wenoz_q, weno_order, & num_fluids, mhd, relativity, igr_order, viscous, & igr_iter_solver, igr, igr_pres_lim, & recon_type, muscl_order, muscl_lim, & -#:endif - Ca, Web, Re_inv, & - acoustic_source, acoustic, num_source, & - polytropic, thermal, & - integral, integral_wrt, num_integrals, & - polydisperse, poly_sigma, qbmm, & - relax, relax_model, & - palpha_eps, ptgalpha_eps, & - file_per_process, sigma, & - pi_fac, adv_n, adap_dt, adap_dt_tol, adap_dt_max_iters, & - bf_x, bf_y, bf_z, & - k_x, k_y, k_z, w_x, w_y, w_z, p_x, p_y, p_z, & - g_x, g_y, g_z, n_start, t_save, t_stop, & - cfl_adap_dt, cfl_const_dt, cfl_target, & - surface_tension, bubbles_lagrange, lag_params, & - hyperelasticity, R0ref, num_bc_patches, Bx0, & - cont_damage, tau_star, cont_damage_s, alpha_bar, & - hyper_cleaning, hyper_cleaning_speed, hyper_cleaning_tau, & - alf_factor, num_igr_iters, num_igr_warm_start_iters, & - int_comp, ic_eps, ic_beta, nv_uvm_out_of_core, & - nv_uvm_igr_temps_on_gpu, nv_uvm_pref_gpu, down_sample, fft_wrt - - ! Checking that an input file has been provided by the user. If it - ! has, then the input file is read in, otherwise, simulation exits. + #:endif + Ca, Web, Re_inv, acoustic_source, acoustic, num_source, polytropic, thermal, integral, integral_wrt, num_integrals, & + & polydisperse, poly_sigma, qbmm, relax, relax_model, palpha_eps, ptgalpha_eps, file_per_process, sigma, pi_fac, & + & adv_n, adap_dt, adap_dt_tol, adap_dt_max_iters, bf_x, bf_y, bf_z, k_x, k_y, k_z, w_x, w_y, w_z, p_x, p_y, p_z, g_x, & + & g_y, g_z, n_start, t_save, t_stop, cfl_adap_dt, cfl_const_dt, cfl_target, surface_tension, bubbles_lagrange, & + & lag_params, hyperelasticity, R0ref, num_bc_patches, Bx0, cont_damage, tau_star, cont_damage_s, alpha_bar, & + & hyper_cleaning, hyper_cleaning_speed, hyper_cleaning_tau, alf_factor, num_igr_iters, num_igr_warm_start_iters, & + & int_comp, ic_eps, ic_beta, nv_uvm_out_of_core, nv_uvm_igr_temps_on_gpu, nv_uvm_pref_gpu, down_sample, fft_wrt + + ! Checking that an input file has been provided by the user. If it has, then the input file is read in, otherwise, + ! simulation exits. inquire (FILE=trim(file_path), EXIST=file_exist) if (file_exist) then - open (1, FILE=trim(file_path), & - FORM='formatted', & - ACTION='read', & - STATUS='old') + open (1, FILE=trim(file_path), form='formatted', ACTION='read', STATUS='old') read (1, NML=user_inputs, iostat=iostatus) if (iostatus /= 0) then backspace (1) read (1, fmt='(A)') line - print *, 'Invalid line in namelist: '//trim(line) - call s_mpi_abort('Invalid line in simulation.inp. It is '// & - 'likely due to a datatype mismatch. Exiting.') + print *, 'Invalid line in namelist: ' // trim(line) + call s_mpi_abort('Invalid line in simulation.inp. It is ' // 'likely due to a datatype mismatch. Exiting.') end if close (1) @@ -210,24 +145,21 @@ contains if (cfl_adap_dt .or. cfl_const_dt) cfl_dt = .true. - if (any((/bc_x%beg, bc_x%end, bc_y%beg, bc_y%end, bc_z%beg, bc_z%end/) == BC_DIRICHLET) .or. & - num_bc_patches > 0) then + if (any((/bc_x%beg, bc_x%end, bc_y%beg, bc_y%end, bc_z%beg, bc_z%end/) == BC_DIRICHLET) .or. num_bc_patches > 0) then bc_io = .true. end if if (bc_x%beg == BC_PERIODIC .and. bc_x%end == BC_PERIODIC) periodic_bc(1) = .true. if (bc_y%beg == BC_PERIODIC .and. bc_y%end == BC_PERIODIC) periodic_bc(2) = .true. if (bc_z%beg == BC_PERIODIC .and. bc_z%end == BC_PERIODIC) periodic_bc(3) = .true. - else - call s_mpi_abort(trim(file_path)//' is missing. Exiting.') + call s_mpi_abort(trim(file_path) // ' is missing. Exiting.') end if end subroutine s_read_input_file - !> The goal of this procedure is to verify that each of the - !! user provided inputs is valid and that their combination - !! constitutes a meaningful configuration for the simulation. + !> The goal of this procedure is to verify that each of the user provided inputs is valid and that their combination constitutes + !! a meaningful configuration for the simulation. impure subroutine s_check_input_file ! Relative path to the current directory file in the case directory @@ -237,12 +169,13 @@ contains logical :: file_exist ! Logistics - file_path = trim(case_dir)//'/.' + + file_path = trim(case_dir) // '/.' call my_inquire(file_path, file_exist) if (file_exist .neqv. .true.) then - call s_mpi_abort(trim(file_path)//' is missing. Exiting.') + call s_mpi_abort(trim(file_path) // ' is missing. Exiting.') end if call s_check_inputs_common() @@ -251,37 +184,31 @@ contains end subroutine s_check_input_file !> @brief Reads serial initial condition and grid data files and computes cell-width distributions. - !! @param q_cons_vf Cell-averaged conservative variables + !! @param q_cons_vf Cell-averaged conservative variables impure subroutine s_read_serial_data_files(q_cons_vf) - type(scalar_field), dimension(sys_size), intent(INOUT) :: q_cons_vf - - character(LEN=path_len + 2*name_len) :: t_step_dir !< - !! Relative path to the starting time-step directory - - character(LEN=path_len + 3*name_len) :: file_path !< - !! Relative path to the grid and conservative variables data files - - logical :: file_exist !< + type(scalar_field), dimension(sys_size), intent(inout) :: q_cons_vf + character(LEN=path_len + 2*name_len) :: t_step_dir !< Relative path to the starting time-step directory + character(LEN=path_len + 3*name_len) :: file_path !< Relative path to the grid and conservative variables data files + logical :: file_exist ! Logical used to check the existence of the data files - integer :: i, r !< Generic loop iterator + integer :: i, r !< Generic loop iterator + + ! Confirming that the directory from which the initial condition and the grid data files are to be read in exists and + ! exiting otherwise - ! Confirming that the directory from which the initial condition and - ! the grid data files are to be read in exists and exiting otherwise if (cfl_dt) then - write (t_step_dir, '(A,I0,A,I0)') & - trim(case_dir)//'/p_all/p', proc_rank, '/', n_start + write (t_step_dir, '(A,I0,A,I0)') trim(case_dir) // '/p_all/p', proc_rank, '/', n_start else - write (t_step_dir, '(A,I0,A,I0)') & - trim(case_dir)//'/p_all/p', proc_rank, '/', t_step_start + write (t_step_dir, '(A,I0,A,I0)') trim(case_dir) // '/p_all/p', proc_rank, '/', t_step_start end if - file_path = trim(t_step_dir)//'/.' + file_path = trim(t_step_dir) // '/.' call my_inquire(file_path, file_exist) if (file_exist .neqv. .true.) then - call s_mpi_abort(trim(file_path)//' is missing. Exiting.') + call s_mpi_abort(trim(file_path) // ' is missing. Exiting.') end if if (bc_io) then @@ -291,18 +218,15 @@ contains end if ! Cell-boundary Locations in x-direction - file_path = trim(t_step_dir)//'/x_cb.dat' + file_path = trim(t_step_dir) // '/x_cb.dat' inquire (FILE=trim(file_path), EXIST=file_exist) if (file_exist) then - open (2, FILE=trim(file_path), & - FORM='unformatted', & - ACTION='read', & - STATUS='old') + open (2, FILE=trim(file_path), form='unformatted', ACTION='read', STATUS='old') read (2) x_cb(-1:m); close (2) else - call s_mpi_abort(trim(file_path)//' is missing. Exiting.') + call s_mpi_abort(trim(file_path) // ' is missing. Exiting.') end if dx(0:m) = x_cb(0:m) - x_cb(-1:m - 1) @@ -311,67 +235,54 @@ contains if (ib) then do i = 1, num_ibs if (patch_ib(i)%c > 0) then - Np = int((patch_ib(i)%p*patch_ib(i)%c/dx(0))*20) + int(((patch_ib(i)%c - patch_ib(i)%p*patch_ib(i)%c)/dx(0))*20) + 1 + Np = int((patch_ib(i)%p*patch_ib(i)%c/dx(0))*20) + int(((patch_ib(i)%c - patch_ib(i)%p*patch_ib(i)%c)/dx(0)) & + & *20) + 1 end if end do end if ! Cell-boundary Locations in y-direction if (n > 0) then - - file_path = trim(t_step_dir)//'/y_cb.dat' + file_path = trim(t_step_dir) // '/y_cb.dat' inquire (FILE=trim(file_path), EXIST=file_exist) if (file_exist) then - open (2, FILE=trim(file_path), & - FORM='unformatted', & - ACTION='read', & - STATUS='old') + open (2, FILE=trim(file_path), form='unformatted', ACTION='read', STATUS='old') read (2) y_cb(-1:n); close (2) else - call s_mpi_abort(trim(file_path)//' is missing. Exiting.') + call s_mpi_abort(trim(file_path) // ' is missing. Exiting.') end if dy(0:n) = y_cb(0:n) - y_cb(-1:n - 1) y_cc(0:n) = y_cb(-1:n - 1) + dy(0:n)/2._wp - end if ! Cell-boundary Locations in z-direction if (p > 0) then - - file_path = trim(t_step_dir)//'/z_cb.dat' + file_path = trim(t_step_dir) // '/z_cb.dat' inquire (FILE=trim(file_path), EXIST=file_exist) if (file_exist) then - open (2, FILE=trim(file_path), & - FORM='unformatted', & - ACTION='read', & - STATUS='old') + open (2, FILE=trim(file_path), form='unformatted', ACTION='read', STATUS='old') read (2) z_cb(-1:p); close (2) else - call s_mpi_abort(trim(file_path)//' is missing. Exiting.') + call s_mpi_abort(trim(file_path) // ' is missing. Exiting.') end if dz(0:p) = z_cb(0:p) - z_cb(-1:p - 1) z_cc(0:p) = z_cb(-1:p - 1) + dz(0:p)/2._wp - end if do i = 1, sys_size - write (file_path, '(A,I0,A)') & - trim(t_step_dir)//'/q_cons_vf', i, '.dat' + write (file_path, '(A,I0,A)') trim(t_step_dir) // '/q_cons_vf', i, '.dat' inquire (FILE=trim(file_path), EXIST=file_exist) if (file_exist) then - open (2, FILE=trim(file_path), & - FORM='unformatted', & - ACTION='read', & - STATUS='old') - read (2) q_cons_vf(i)%sf(0:m, 0:n, 0:p); close (2) + open (2, FILE=trim(file_path), form='unformatted', ACTION='read', STATUS='old') + read (2) q_cons_vf(i)%sf(0:m,0:n,0:p); close (2) else - call s_mpi_abort(trim(file_path)//' is missing. Exiting.') + call s_mpi_abort(trim(file_path) // ' is missing. Exiting.') end if end do @@ -380,33 +291,25 @@ contains if (qbmm .and. .not. polytropic) then do i = 1, nb do r = 1, nnode - write (file_path, '(A,I0,A)') & - trim(t_step_dir)//'/pb', sys_size + (i - 1)*nnode + r, '.dat' + write (file_path, '(A,I0,A)') trim(t_step_dir) // '/pb', sys_size + (i - 1)*nnode + r, '.dat' inquire (FILE=trim(file_path), EXIST=file_exist) if (file_exist) then - open (2, FILE=trim(file_path), & - FORM='unformatted', & - ACTION='read', & - STATUS='old') - read (2) pb_ts(1)%sf(0:m, 0:n, 0:p, r, i); close (2) + open (2, FILE=trim(file_path), form='unformatted', ACTION='read', STATUS='old') + read (2) pb_ts(1)%sf(0:m,0:n,0:p,r, i); close (2) else - call s_mpi_abort(trim(file_path)//' is missing. Exiting.') + call s_mpi_abort(trim(file_path) // ' is missing. Exiting.') end if end do end do do i = 1, nb do r = 1, nnode - write (file_path, '(A,I0,A)') & - trim(t_step_dir)//'/mv', sys_size + (i - 1)*nnode + r, '.dat' + write (file_path, '(A,I0,A)') trim(t_step_dir) // '/mv', sys_size + (i - 1)*nnode + r, '.dat' inquire (FILE=trim(file_path), EXIST=file_exist) if (file_exist) then - open (2, FILE=trim(file_path), & - FORM='unformatted', & - ACTION='read', & - STATUS='old') - read (2) mv_ts(1)%sf(0:m, 0:n, 0:p, r, i); close (2) + open (2, FILE=trim(file_path), form='unformatted', ACTION='read', STATUS='old') + read (2) mv_ts(1)%sf(0:m,0:n,0:p,r, i); close (2) else - call s_mpi_abort(trim(file_path)//' is missing. Exiting.') + call s_mpi_abort(trim(file_path) // ' is missing. Exiting.') end if end do end do @@ -416,43 +319,36 @@ contains end subroutine s_read_serial_data_files !> @brief Reads parallel initial condition and grid data files via MPI I/O. - !! @param q_cons_vf Conservative variables + !! @param q_cons_vf Conservative variables impure subroutine s_read_parallel_data_files(q_cons_vf) - type(scalar_field), & - dimension(sys_size), & - intent(INOUT) :: q_cons_vf + type(scalar_field), dimension(sys_size), intent(inout) :: q_cons_vf #ifdef MFC_MPI - - real(wp), allocatable, dimension(:) :: x_cb_glb, y_cb_glb, z_cb_glb - - integer :: ifile, ierr, data_size - integer, dimension(MPI_STATUS_SIZE) :: status - integer(KIND=MPI_OFFSET_KIND) :: disp - integer(KIND=MPI_OFFSET_KIND) :: m_MOK, n_MOK, p_MOK - integer(KIND=MPI_OFFSET_KIND) :: WP_MOK, var_MOK, str_MOK - integer(KIND=MPI_OFFSET_KIND) :: NVARS_MOK - integer(KIND=MPI_OFFSET_KIND) :: MOK - + real(wp), allocatable, dimension(:) :: x_cb_glb, y_cb_glb, z_cb_glb + integer :: ifile, ierr, data_size + integer, dimension(MPI_STATUS_SIZE) :: status + integer(KIND=MPI_OFFSET_KIND) :: disp + integer(KIND=MPI_OFFSET_KIND) :: m_MOK, n_MOK, p_MOK + integer(KIND=MPI_OFFSET_KIND) :: WP_MOK, var_MOK, str_MOK + integer(KIND=MPI_OFFSET_KIND) :: NVARS_MOK + integer(KIND=MPI_OFFSET_KIND) :: MOK character(LEN=path_len + 2*name_len) :: file_loc - logical :: file_exist - - character(len=10) :: t_step_start_string - - integer :: i, j + logical :: file_exist + character(len=10) :: t_step_start_string + integer :: i, j ! Downsampled data variables integer :: m_ds, n_ds, p_ds integer :: m_glb_ds, n_glb_ds, p_glb_ds - integer :: m_glb_read, n_glb_read, p_glb_read ! data size of read + integer :: m_glb_read, n_glb_read, p_glb_read ! data size of read allocate (x_cb_glb(-1:m_glb)) allocate (y_cb_glb(-1:n_glb)) allocate (z_cb_glb(-1:p_glb)) ! Read in cell boundary locations in x-direction - file_loc = trim(case_dir)//'/restart_data'//trim(mpiiofs)//'x_cb.dat' + file_loc = trim(case_dir) // '/restart_data' // trim(mpiiofs) // 'x_cb.dat' inquire (FILE=trim(file_loc), EXIST=file_exist) if (down_sample) then @@ -471,7 +367,7 @@ contains call MPI_FILE_READ(ifile, x_cb_glb, data_size, mpi_p, status, ierr) call MPI_FILE_CLOSE(ifile, ierr) else - call s_mpi_abort('File '//trim(file_loc)//' is missing. Exiting.') + call s_mpi_abort('File ' // trim(file_loc) // ' is missing. Exiting.') end if ! Assigning local cell boundary locations @@ -484,7 +380,8 @@ contains if (ib) then do i = 1, num_ibs if (patch_ib(i)%c > 0) then - Np = int((patch_ib(i)%p*patch_ib(i)%c/dx(0))*20) + int(((patch_ib(i)%c - patch_ib(i)%p*patch_ib(i)%c)/dx(0))*20) + 1 + Np = int((patch_ib(i)%p*patch_ib(i)%c/dx(0))*20) + int(((patch_ib(i)%c - patch_ib(i)%p*patch_ib(i)%c)/dx(0)) & + & *20) + 1 allocate (MPI_IO_airfoil_IB_DATA%var(1:2*Np)) end if end do @@ -492,7 +389,7 @@ contains if (n > 0) then ! Read in cell boundary locations in y-direction - file_loc = trim(case_dir)//'/restart_data'//trim(mpiiofs)//'y_cb.dat' + file_loc = trim(case_dir) // '/restart_data' // trim(mpiiofs) // 'y_cb.dat' inquire (FILE=trim(file_loc), EXIST=file_exist) if (file_exist) then @@ -501,7 +398,7 @@ contains call MPI_FILE_READ(ifile, y_cb_glb, data_size, mpi_p, status, ierr) call MPI_FILE_CLOSE(ifile, ierr) else - call s_mpi_abort('File '//trim(file_loc)//' is missing. Exiting.') + call s_mpi_abort('File ' // trim(file_loc) // ' is missing. Exiting.') end if ! Assigning local cell boundary locations @@ -513,7 +410,7 @@ contains if (p > 0) then ! Read in cell boundary locations in z-direction - file_loc = trim(case_dir)//'/restart_data'//trim(mpiiofs)//'z_cb.dat' + file_loc = trim(case_dir) // '/restart_data' // trim(mpiiofs) // 'z_cb.dat' inquire (FILE=trim(file_loc), EXIST=file_exist) if (file_exist) then @@ -522,7 +419,7 @@ contains call MPI_FILE_READ(ifile, z_cb_glb, data_size, mpi_p, status, ierr) call MPI_FILE_CLOSE(ifile, ierr) else - call s_mpi_abort('File '//trim(file_loc)//'is missing. Exiting.') + call s_mpi_abort('File ' // trim(file_loc) // 'is missing. Exiting.') end if ! Assigning local cell boundary locations @@ -531,7 +428,6 @@ contains dz(0:p) = z_cb(0:p) - z_cb(-1:p - 1) ! Computing the cell center locations z_cc(0:p) = z_cb(-1:p - 1) + dz(0:p)/2._wp - end if end if @@ -543,7 +439,7 @@ contains call s_int_to_str(t_step_start, t_step_start_string) write (file_loc, '(I0,A1,I7.7,A)') t_step_start, '_', proc_rank, '.dat' end if - file_loc = trim(case_dir)//'/restart_data/lustre_'//trim(t_step_start_string)//trim(mpiiofs)//trim(file_loc) + file_loc = trim(case_dir) // '/restart_data/lustre_' // trim(t_step_start_string) // trim(mpiiofs) // trim(file_loc) inquire (FILE=trim(file_loc), EXIST=file_exist) if (file_exist) then @@ -585,19 +481,17 @@ contains ! Read the data for each variable if (bubbles_euler .or. elasticity) then - do i = 1, sys_size!adv_idx%end + do i = 1, sys_size ! adv_idx%end var_MOK = int(i, MPI_OFFSET_KIND) - call MPI_FILE_READ(ifile, MPI_IO_DATA%var(i)%sf, data_size*mpi_io_type, & - mpi_io_p, status, ierr) + call MPI_FILE_READ(ifile, MPI_IO_DATA%var(i)%sf, data_size*mpi_io_type, mpi_io_p, status, ierr) end do - !Read pb and mv for non-polytropic qbmm + ! Read pb and mv for non-polytropic qbmm if (qbmm .and. .not. polytropic) then do i = sys_size + 1, sys_size + 2*nb*nnode var_MOK = int(i, MPI_OFFSET_KIND) - call MPI_FILE_READ(ifile, MPI_IO_DATA%var(i)%sf, data_size*mpi_io_type, & - mpi_io_p, status, ierr) + call MPI_FILE_READ(ifile, MPI_IO_DATA%var(i)%sf, data_size*mpi_io_type, mpi_io_p, status, ierr) end do end if else @@ -605,15 +499,13 @@ contains do i = 1, sys_size var_MOK = int(i, MPI_OFFSET_KIND) - call MPI_FILE_READ(ifile, q_cons_temp(i)%sf, data_size*mpi_io_type, & - mpi_io_p, status, ierr) + call MPI_FILE_READ(ifile, q_cons_temp(i)%sf, data_size*mpi_io_type, mpi_io_p, status, ierr) end do else do i = 1, sys_size var_MOK = int(i, MPI_OFFSET_KIND) - call MPI_FILE_READ(ifile, MPI_IO_DATA%var(i)%sf, data_size*mpi_io_type, & - mpi_io_p, status, ierr) + call MPI_FILE_READ(ifile, MPI_IO_DATA%var(i)%sf, data_size*mpi_io_type, mpi_io_p, status, ierr) end do end if end if @@ -621,9 +513,8 @@ contains call s_mpi_barrier() call MPI_FILE_CLOSE(ifile, ierr) - else - call s_mpi_abort('File '//trim(file_loc)//' is missing. Exiting.') + call s_mpi_abort('File ' // trim(file_loc) // ' is missing. Exiting.') end if else ! Open the file to read conservative variables @@ -632,7 +523,7 @@ contains else write (file_loc, '(I0,A)') t_step_start, '.dat' end if - file_loc = trim(case_dir)//'/restart_data'//trim(mpiiofs)//trim(file_loc) + file_loc = trim(case_dir) // '/restart_data' // trim(mpiiofs) // trim(file_loc) inquire (FILE=trim(file_loc), EXIST=file_exist) if (file_exist) then @@ -643,9 +534,7 @@ contains if (ib) then call s_initialize_mpi_data(q_cons_vf, ib_markers) else - call s_initialize_mpi_data(q_cons_vf) - end if ! Size of local arrays @@ -662,27 +551,23 @@ contains ! Read the data for each variable if (bubbles_euler .or. elasticity) then - do i = 1, sys_size !adv_idx%end + do i = 1, sys_size ! adv_idx%end var_MOK = int(i, MPI_OFFSET_KIND) ! Initial displacement to skip at beginning of file disp = m_MOK*max(MOK, n_MOK)*max(MOK, p_MOK)*WP_MOK*(var_MOK - 1) - call MPI_FILE_SET_VIEW(ifile, disp, mpi_io_p, MPI_IO_DATA%view(i), & - 'native', mpi_info_int, ierr) - call MPI_FILE_READ(ifile, MPI_IO_DATA%var(i)%sf, data_size*mpi_io_type, & - mpi_io_p, status, ierr) + call MPI_FILE_SET_VIEW(ifile, disp, mpi_io_p, MPI_IO_DATA%view(i), 'native', mpi_info_int, ierr) + call MPI_FILE_READ(ifile, MPI_IO_DATA%var(i)%sf, data_size*mpi_io_type, mpi_io_p, status, ierr) end do - !Read pb and mv for non-polytropic qbmm + ! Read pb and mv for non-polytropic qbmm if (qbmm .and. .not. polytropic) then do i = sys_size + 1, sys_size + 2*nb*nnode var_MOK = int(i, MPI_OFFSET_KIND) ! Initial displacement to skip at beginning of file disp = m_MOK*max(MOK, n_MOK)*max(MOK, p_MOK)*WP_MOK*(var_MOK - 1) - call MPI_FILE_SET_VIEW(ifile, disp, mpi_io_p, MPI_IO_DATA%view(i), & - 'native', mpi_info_int, ierr) - call MPI_FILE_READ(ifile, MPI_IO_DATA%var(i)%sf, data_size*mpi_io_type, & - mpi_io_p, status, ierr) + call MPI_FILE_SET_VIEW(ifile, disp, mpi_io_p, MPI_IO_DATA%view(i), 'native', mpi_info_int, ierr) + call MPI_FILE_READ(ifile, MPI_IO_DATA%var(i)%sf, data_size*mpi_io_type, mpi_io_p, status, ierr) end do end if else @@ -692,21 +577,17 @@ contains ! Initial displacement to skip at beginning of file disp = m_MOK*max(MOK, n_MOK)*max(MOK, p_MOK)*WP_MOK*(var_MOK - 1) - call MPI_FILE_SET_VIEW(ifile, disp, mpi_io_p, MPI_IO_DATA%view(i), & - 'native', mpi_info_int, ierr) - call MPI_FILE_READ_ALL(ifile, MPI_IO_DATA%var(i)%sf, data_size*mpi_io_type, & - mpi_io_p, status, ierr) + call MPI_FILE_SET_VIEW(ifile, disp, mpi_io_p, MPI_IO_DATA%view(i), 'native', mpi_info_int, ierr) + call MPI_FILE_READ_ALL(ifile, MPI_IO_DATA%var(i)%sf, data_size*mpi_io_type, mpi_io_p, status, ierr) end do end if call s_mpi_barrier() call MPI_FILE_CLOSE(ifile, ierr) - else - call s_mpi_abort('File '//trim(file_loc)//' is missing. Exiting.') + call s_mpi_abort('File ' // trim(file_loc) // ' is missing. Exiting.') end if - end if deallocate (x_cb_glb, y_cb_glb, z_cb_glb) @@ -716,33 +597,26 @@ contains else call s_assign_default_bc_type(bc_type) end if - #endif end subroutine s_read_parallel_data_files - !> The purpose of this procedure is to initialize the - !! values of the internal-energy equations of each phase - !! from the mass of each phase, the mixture momentum and - !! mixture-total-energy equations. - !! @param v_vf conservative variables + !> The purpose of this procedure is to initialize the values of the internal-energy equations of each phase from the mass of + !! each phase, the mixture momentum and mixture-total-energy equations. + !! @param v_vf conservative variables subroutine s_initialize_internal_energy_equations(v_vf) type(scalar_field), dimension(sys_size), intent(inout) :: v_vf - - real(wp) :: rho - real(wp) :: dyn_pres - real(wp) :: gamma - real(wp) :: pi_inf - real(wp) :: qv - real(wp), dimension(2) :: Re - real(wp) :: pres, T - - integer :: i, j, k, l, c - - real(wp), dimension(num_species) :: rhoYks - - real(wp) :: pres_mag + real(wp) :: rho + real(wp) :: dyn_pres + real(wp) :: gamma + real(wp) :: pi_inf + real(wp) :: qv + real(wp), dimension(2) :: Re + real(wp) :: pres, T + integer :: i, j, k, l, c + real(wp), dimension(num_species) :: rhoYks + real(wp) :: pres_mag pres_mag = 0._wp @@ -751,13 +625,11 @@ contains do j = 0, m do k = 0, n do l = 0, p - call s_convert_to_mixture_variables(v_vf, j, k, l, rho, gamma, pi_inf, qv, Re) dyn_pres = 0._wp do i = mom_idx%beg, mom_idx%end - dyn_pres = dyn_pres + 5.e-1_wp*v_vf(i)%sf(j, k, l)*v_vf(i)%sf(j, k, l) & - /max(rho, sgm_eps) + dyn_pres = dyn_pres + 5.e-1_wp*v_vf(i)%sf(j, k, l)*v_vf(i)%sf(j, k, l)/max(rho, sgm_eps) end do if (chemistry) then @@ -770,18 +642,18 @@ contains if (n == 0) then pres_mag = 0.5_wp*(Bx0**2 + v_vf(B_idx%beg)%sf(j, k, l)**2 + v_vf(B_idx%beg + 1)%sf(j, k, l)**2) else - pres_mag = 0.5_wp*(v_vf(B_idx%beg)%sf(j, k, l)**2 + v_vf(B_idx%beg + 1)%sf(j, k, l)**2 + v_vf(B_idx%beg + 2)%sf(j, k, l)**2) + pres_mag = 0.5_wp*(v_vf(B_idx%beg)%sf(j, k, l)**2 + v_vf(B_idx%beg + 1)%sf(j, k, & + & l)**2 + v_vf(B_idx%beg + 2)%sf(j, k, l)**2) end if end if - call s_compute_pressure(v_vf(E_idx)%sf(j, k, l), 0._stp, & - dyn_pres, pi_inf, gamma, rho, qv, rhoYks, pres, T, pres_mag=pres_mag) + call s_compute_pressure(v_vf(E_idx)%sf(j, k, l), 0._stp, dyn_pres, pi_inf, gamma, rho, qv, rhoYks, pres, T, & + & pres_mag=pres_mag) do i = 1, num_fluids - v_vf(i + intxb - 1)%sf(j, k, l) = v_vf(i + advxb - 1)%sf(j, k, l)*(gammas(i)*pres + pi_infs(i)) & - + v_vf(i + contxb - 1)%sf(j, k, l)*qvs(i) + v_vf(i + intxb - 1)%sf(j, k, l) = v_vf(i + advxb - 1)%sf(j, k, & + & l)*(gammas(i)*pres + pi_infs(i)) + v_vf(i + contxb - 1)%sf(j, k, l)*qvs(i) end do - end do end do end do @@ -790,10 +662,10 @@ contains !> @brief Advances the simulation by one time step, handling CFL-based dt and time-stepper dispatch. impure subroutine s_perform_time_step(t_step, time_avg) - integer, intent(inout) :: t_step - real(wp), intent(inout) :: time_avg - integer :: i + integer, intent(inout) :: t_step + real(wp), intent(inout) :: time_avg + integer :: i if (cfl_dt) then if (cfl_const_dt .and. t_step == 0) call s_compute_dt() @@ -823,22 +695,13 @@ contains if (cfl_dt) then if (proc_rank == 0 .and. mod(t_step - t_step_start, t_step_print) == 0) then print '(" [", I3, "%] Time ", ES16.6, " dt = ", ES16.6, " @ Time Step = ", I8, " Time Avg = ", ES16.6, " Time/step = ", ES12.6, "")', & - int(ceiling(100._wp*(mytime/t_stop))), & - mytime, & - dt, & - t_step, & - wall_time_avg, & - wall_time + & int(ceiling(100._wp*(mytime/t_stop))), mytime, dt, t_step, wall_time_avg, wall_time end if else if (proc_rank == 0 .and. mod(t_step - t_step_start, t_step_print) == 0) then print '(" [", I3, "%] Time step ", I8, " of ", I0, " @ t_step = ", I8, " Time Avg = ", ES12.6, " Time/step= ", ES12.6, "")', & - int(ceiling(100._wp*(real(t_step - t_step_start)/(t_step_stop - t_step_start + 1)))), & - t_step - t_step_start + 1, & - t_step_stop - t_step_start + 1, & - t_step, & - wall_time_avg, & - wall_time + & int(ceiling(100._wp*(real(t_step - t_step_start)/(t_step_stop - t_step_start + 1)))), & + & t_step - t_step_start + 1, t_step_stop - t_step_start + 1, t_step, wall_time_avg, wall_time end if end if @@ -864,15 +727,15 @@ contains end subroutine s_perform_time_step !> @brief Collects per-process wall-clock times and writes aggregate performance metrics to file. - impure subroutine s_save_performance_metrics(time_avg, time_final, io_time_avg, io_time_final, proc_time, io_proc_time, file_exists) + impure subroutine s_save_performance_metrics(time_avg, time_final, io_time_avg, io_time_final, proc_time, io_proc_time, & + & file_exists) - real(wp), intent(inout) :: time_avg, time_final - real(wp), intent(inout) :: io_time_avg, io_time_final + real(wp), intent(inout) :: time_avg, time_final + real(wp), intent(inout) :: io_time_avg, io_time_final real(wp), dimension(:), intent(inout) :: proc_time real(wp), dimension(:), intent(inout) :: io_proc_time - logical, intent(inout) :: file_exists - - real(wp) :: grind_time + logical, intent(inout) :: file_exists + real(wp) :: grind_time call s_mpi_barrier() @@ -893,9 +756,8 @@ contains io_time_final = maxval(io_proc_time) end if - grind_time = time_final*1.0e9_wp/ & - (real(sys_size, wp)*real(maxval((/1, m_glb/)), wp)* & - real(maxval((/1, n_glb/)), wp)*real(maxval((/1, p_glb/)), wp)) + grind_time = time_final*1.0e9_wp/(real(sys_size, wp)*real(maxval((/1, m_glb/)), wp)*real(maxval((/1, n_glb/)), & + & wp)*real(maxval((/1, p_glb/)), wp)) print *, "Performance:", grind_time, "ns/gp/eq/rhs" inquire (FILE='time_data.dat', EXIST=file_exists) @@ -920,21 +782,19 @@ contains write (1, '(I10, F15.8)') num_procs, io_time_final close (1) - end if end subroutine s_save_performance_metrics !> @brief Saves conservative variable data to disk at the current time step. impure subroutine s_save_data(t_step, start, finish, io_time_avg, nt) - integer, intent(inout) :: t_step - real(wp), intent(inout) :: start, finish, io_time_avg - integer, intent(inout) :: nt - - integer(kind=8) :: i, j, k, l - integer :: stor - integer :: save_count + integer, intent(inout) :: t_step + real(wp), intent(inout) :: start, finish, io_time_avg + integer, intent(inout) :: nt + integer(kind=8) :: i, j, k, l + integer :: stor + integer :: save_count if (down_sample) then call s_populate_variables_buffers(bc_type, q_cons_ts(1)%vf) @@ -948,8 +808,7 @@ contains do l = idwbuff(3)%beg, idwbuff(3)%end do k = idwbuff(2)%beg, idwbuff(2)%end do j = idwbuff(1)%beg, idwbuff(1)%end - q_cons_ts(2)%vf(i)%sf(j, k, l) = & - q_cons_ts(1)%vf(i)%sf(j, k, l) + q_cons_ts(2)%vf(i)%sf(j, k, l) = q_cons_ts(1)%vf(i)%sf(j, k, l) end do end do end do @@ -988,9 +847,8 @@ contains end if if (bubbles_lagrange) then - $:GPU_UPDATE(host='[lag_id, mtn_pos, mtn_posPrev, mtn_vel, intfc_rad, & - & intfc_vel, bub_R0, Rmax_stats, Rmin_stats, bub_dphidt, gas_p, & - & gas_mv, gas_mg, gas_betaT, gas_betaC]') + $:GPU_UPDATE(host='[lag_id, mtn_pos, mtn_posPrev, mtn_vel, intfc_rad, intfc_vel, bub_R0, Rmax_stats, Rmin_stats, & + & bub_dphidt, gas_p, gas_mv, gas_mg, gas_betaT, gas_betaC]') do i = 1, n_el_bubs_loc if (ieee_is_nan(intfc_rad(i, 1)) .or. intfc_rad(i, 1) <= 0._wp) then call s_mpi_abort("Bubble radius is negative or NaN, please reduce dt.") @@ -999,8 +857,8 @@ contains $:GPU_UPDATE(host='[q_beta(1)%sf]') call s_write_data_files(q_cons_ts(stor)%vf, q_T_sf, q_prim_vf, save_count, bc_type, q_beta(1)) - $:GPU_UPDATE(host='[Rmax_stats,Rmin_stats,gas_p,gas_mv,intfc_vel]') - call s_write_restart_lag_bubbles(save_count) !parallel + $:GPU_UPDATE(host='[Rmax_stats, Rmin_stats, gas_p, gas_mv, intfc_vel]') + call s_write_restart_lag_bubbles(save_count) ! parallel if (lag_params%write_bubbles_stats) call s_write_lag_bubble_stats() else call s_write_data_files(q_cons_ts(stor)%vf, q_T_sf, q_prim_vf, save_count, bc_type) @@ -1025,15 +883,19 @@ contains !> @brief Initializes all simulation sub-modules in the required dependency order. impure subroutine s_initialize_modules - integer :: m_ds, n_ds, p_ds - integer :: i, j, k, l, x_id, y_id, z_id, ix, iy, iz + integer :: m_ds, n_ds, p_ds + integer :: i, j, k, l, x_id, y_id, z_id, ix, iy, iz real(wp) :: temp1, temp2, temp3, temp4 call s_initialize_global_parameters_module() #:if USING_AMD #:for BC in {-5, -6, -7, -8, -9, -10, -11, -12, -13} - @:PROHIBIT(any((/bc_x%beg, bc_x%end, bc_y%beg, bc_y%end, bc_z%beg, bc_z%end/) == ${BC}$) .and. adv_idx%end > 20 .and. (.not. chemistry), "CBC module with AMD compiler requires adv_idx%end <= 20 when case optimization is turned off") - @:PROHIBIT(any((/bc_x%beg, bc_x%end, bc_y%beg, bc_y%end, bc_z%beg, bc_z%end/) == ${BC}$) .and. sys_size > 20 .and. (chemistry), "CBC module with AMD compiler and chemistry requires sys_size <= 20 when case optimization is turned off") + @:PROHIBIT(any((/bc_x%beg, bc_x%end, bc_y%beg, bc_y%end, bc_z%beg, & + & bc_z%end/) == ${BC}$) .and. adv_idx%end > 20 .and. (.not. chemistry), & + & "CBC module with AMD compiler requires adv_idx%end <= 20 when case optimization is turned off") + @:PROHIBIT(any((/bc_x%beg, bc_x%end, bc_y%beg, bc_y%end, bc_z%beg, & + & bc_z%end/) == ${BC}$) .and. sys_size > 20 .and. (chemistry), & + & "CBC module with AMD compiler and chemistry requires sys_size <= 20 when case optimization is turned off") #:endfor #:endif if (bubbles_euler .or. bubbles_lagrange) then @@ -1075,7 +937,7 @@ contains allocate (q_cons_temp(1:sys_size)) do i = 1, sys_size - allocate (q_cons_temp(i)%sf(-1:m_ds + 1, -1:n_ds + 1, -1:p_ds + 1)) + allocate (q_cons_temp(i)%sf(-1:m_ds + 1,-1:n_ds + 1,-1:p_ds + 1)) end do end if @@ -1108,16 +970,15 @@ contains ! Initialize the Temperature cache. if (chemistry) call s_compute_q_T_sf(q_T_sf, q_cons_ts(1)%vf, idwint) - ! Computation of parameters, allocation of memory, association of pointers, - ! and/or execution of any other tasks that are needed to properly configure - ! the modules. The preparations below DO DEPEND on the grid being complete. + ! Computation of parameters, allocation of memory, association of pointers, and/or execution of any other tasks that are + ! needed to properly configure the modules. The preparations below DO DEPEND on the grid being complete. if (igr .or. dummy) then call s_initialize_igr_module() end if if (.not. igr .or. dummy) then if (recon_type == WENO_TYPE) then call s_initialize_weno_module() - elseif (recon_type == MUSCL_TYPE) then + else if (recon_type == MUSCL_TYPE) then call s_initialize_muscl_module() end if call s_initialize_cbc_module() @@ -1133,11 +994,13 @@ contains !> @brief Sets up the MPI execution environment, binds GPUs, and decomposes the computational domain. impure subroutine s_initialize_mpi_domain + integer :: ierr + #ifdef MFC_GPU real(wp) :: starttime, endtime - integer :: num_devices, local_size, num_nodes, ppn, my_device_num - integer :: dev, devNum, local_rank + integer :: num_devices, local_size, num_nodes, ppn, my_device_num + integer :: dev, devNum, local_rank #ifdef MFC_MPI integer :: local_comm #endif @@ -1156,8 +1019,7 @@ contains local_size = 1 local_rank = 0 #else - call MPI_Comm_split_type(MPI_COMM_WORLD, MPI_COMM_TYPE_SHARED, 0, & - MPI_INFO_NULL, local_comm, ierr) + call MPI_Comm_split_type(MPI_COMM_WORLD, MPI_COMM_TYPE_SHARED, 0, MPI_INFO_NULL, local_comm, ierr) call MPI_Comm_size(local_comm, local_size, ierr) call MPI_Comm_rank(local_comm, local_rank, ierr) #endif @@ -1174,24 +1036,23 @@ contains #endif #endif - ! The rank 0 processor assigns default values to the user inputs prior to - ! reading them in from the input file. Next, the user inputs are read and - ! their consistency is checked. The identification of any inconsistencies - ! will result in the termination of the simulation. + ! The rank 0 processor assigns default values to the user inputs prior to reading them in from the input file. Next, the + ! user inputs are read and their consistency is checked. The identification of any inconsistencies will result in the + ! termination of the simulation. if (proc_rank == 0) then call s_assign_default_values_to_user_inputs() call s_read_input_file() call s_check_input_file() print '(" Simulating a ", A, " ", I0, "x", I0, "x", I0, " case on ", I0, " rank(s) ", A, ".")', & -#:if not MFC_CASE_OPTIMIZATION + #:if not MFC_CASE_OPTIMIZATION "regular", & -#:else + #:else "case-optimized", & -#:endif - m, n, p, num_procs, & + #:endif + m, n, p, num_procs, & #if defined(MFC_OpenACC) - "with OpenACC offloading" + "with OpenACC offloading" #elif defined(MFC_OpenMP) "with OpenMP offloading" #else @@ -1199,9 +1060,8 @@ contains #endif end if - ! Broadcasting the user inputs to all of the processors and performing the - ! parallel computational domain decomposition. Neither procedure has to be - ! carried out if the simulation is in fact not truly executed in parallel. + ! Broadcasting the user inputs to all of the processors and performing the parallel computational domain decomposition. + ! Neither procedure has to be carried out if the simulation is in fact not truly executed in parallel. call s_mpi_bcast_user_inputs() @@ -1213,8 +1073,10 @@ contains !> @brief Transfers initial conservative variable and model parameter data to the GPU device. subroutine s_initialize_gpu_vars + integer :: i - !Update GPU DATA + ! Update GPU DATA + if (.not. down_sample) then do i = 1, sys_size $:GPU_UPDATE(device='[q_cons_ts(1)%vf(i)%sf]') @@ -1222,7 +1084,7 @@ contains end if if (qbmm .and. .not. polytropic) then - $:GPU_UPDATE(device='[pb_ts(1)%sf,mv_ts(1)%sf]') + $:GPU_UPDATE(device='[pb_ts(1)%sf, mv_ts(1)%sf]') end if if (chemistry) then $:GPU_UPDATE(device='[q_T_sf%sf]') @@ -1230,36 +1092,33 @@ contains $:GPU_UPDATE(device='[chem_params]') - $:GPU_UPDATE(device='[R0ref,p0ref,rho0ref,ss,pv,vd,mu_l,mu_v,mu_g, & - & gam_v,gam_g,M_v,M_g,R_v,R_g,Tw,cp_v,cp_g,k_vl,k_gl, & - & gam, gam_m,Eu,Ca,Web,Re_inv,Pe_c,phi_vg,phi_gv,omegaN, & - & bubbles_euler,polytropic,polydisperse,qbmm, & - & ptil,bubble_model,thermal,poly_sigma,adv_n,adap_dt, & - & adap_dt_tol,adap_dt_max_iters,n_idx,pi_fac,low_Mach]') + $:GPU_UPDATE(device='[R0ref, p0ref, rho0ref, ss, pv, vd, mu_l, mu_v, mu_g, gam_v, gam_g, M_v, M_g, R_v, R_g, Tw, cp_v, & + & cp_g, k_vl, k_gl, gam, gam_m, Eu, Ca, Web, Re_inv, Pe_c, phi_vg, phi_gv, omegaN, bubbles_euler, & + & polytropic, polydisperse, qbmm, ptil, bubble_model, thermal, poly_sigma, adv_n, adap_dt, adap_dt_tol, & + & adap_dt_max_iters, n_idx, pi_fac, low_Mach]') if (bubbles_euler) then - $:GPU_UPDATE(device='[weight,R0]') + $:GPU_UPDATE(device='[weight, R0]') if (.not. polytropic) then - $:GPU_UPDATE(device='[pb0,Pe_T,k_g,k_v,mass_g0,mass_v0, & - & Re_trans_T,Re_trans_c,Im_trans_T,Im_trans_c]') + $:GPU_UPDATE(device='[pb0, Pe_T, k_g, k_v, mass_g0, mass_v0, Re_trans_T, Re_trans_c, Im_trans_T, Im_trans_c]') else if (qbmm) then $:GPU_UPDATE(device='[pb0]') end if end if - $:GPU_UPDATE(device='[adv_n,adap_dt,adap_dt_tol,adap_dt_max_iters,n_idx,pi_fac,low_Mach]') + $:GPU_UPDATE(device='[adv_n, adap_dt, adap_dt_tol, adap_dt_max_iters, n_idx, pi_fac, low_Mach]') $:GPU_UPDATE(device='[acoustic_source, num_source]') $:GPU_UPDATE(device='[sigma, surface_tension]') - $:GPU_UPDATE(device='[dx,dy,dz,x_cb,x_cc,y_cb,y_cc,z_cb,z_cc]') - $:GPU_UPDATE(device='[bc_x%vb1,bc_x%vb2,bc_x%vb3,bc_x%ve1,bc_x%ve2,bc_x%ve3]') - $:GPU_UPDATE(device='[bc_y%vb1,bc_y%vb2,bc_y%vb3,bc_y%ve1,bc_y%ve2,bc_y%ve3]') - $:GPU_UPDATE(device='[bc_z%vb1,bc_z%vb2,bc_z%vb3,bc_z%ve1,bc_z%ve2,bc_z%ve3]') + $:GPU_UPDATE(device='[dx, dy, dz, x_cb, x_cc, y_cb, y_cc, z_cb, z_cc]') + $:GPU_UPDATE(device='[bc_x%vb1, bc_x%vb2, bc_x%vb3, bc_x%ve1, bc_x%ve2, bc_x%ve3]') + $:GPU_UPDATE(device='[bc_y%vb1, bc_y%vb2, bc_y%vb3, bc_y%ve1, bc_y%ve2, bc_y%ve3]') + $:GPU_UPDATE(device='[bc_z%vb1, bc_z%vb2, bc_z%vb3, bc_z%ve1, bc_z%ve2, bc_z%ve3]') - $:GPU_UPDATE(device='[bc_x%grcbc_in,bc_x%grcbc_out,bc_x%grcbc_vel_out]') - $:GPU_UPDATE(device='[bc_y%grcbc_in,bc_y%grcbc_out,bc_y%grcbc_vel_out]') - $:GPU_UPDATE(device='[bc_z%grcbc_in,bc_z%grcbc_out,bc_z%grcbc_vel_out]') + $:GPU_UPDATE(device='[bc_x%grcbc_in, bc_x%grcbc_out, bc_x%grcbc_vel_out]') + $:GPU_UPDATE(device='[bc_y%grcbc_in, bc_y%grcbc_out, bc_y%grcbc_vel_out]') + $:GPU_UPDATE(device='[bc_z%grcbc_in, bc_z%grcbc_out, bc_z%grcbc_vel_out]') $:GPU_UPDATE(device='[relax, relax_model]') if (relax) then @@ -1270,7 +1129,7 @@ contains $:GPU_UPDATE(device='[ib_markers%sf]') end if #:if not MFC_CASE_OPTIMIZATION - $:GPU_UPDATE(device='[igr,nb,igr_order]') + $:GPU_UPDATE(device='[igr, nb, igr_order]') #:endif #:if USING_AMD block @@ -1299,7 +1158,7 @@ contains call s_finalize_riemann_solvers_module() if (recon_type == WENO_TYPE) then call s_finalize_weno_module() - elseif (recon_type == MUSCL_TYPE) then + else if (recon_type == MUSCL_TYPE) then call s_finalize_muscl_module() end if end if @@ -1320,6 +1179,7 @@ contains ! Terminating MPI execution environment call s_mpi_finalize() + end subroutine s_finalize_modules end module m_start_up diff --git a/src/simulation/m_surface_tension.fpp b/src/simulation/m_surface_tension.fpp index c67375bc01..aa206044c0 100644 --- a/src/simulation/m_surface_tension.fpp +++ b/src/simulation/m_surface_tension.fpp @@ -9,29 +9,19 @@ !> @brief Computes capillary source fluxes and color-function gradients for the diffuse-interface surface tension model module m_surface_tension - use m_derived_types !< Definitions of the derived types - - use m_global_parameters !< Definitions of the global parameters - - use m_mpi_proxy !< Message passing interface (MPI) module proxy - + use m_derived_types !< Definitions of the derived types + use m_global_parameters !< Definitions of the global parameters + use m_mpi_proxy !< Message passing interface (MPI) module proxy use m_variables_conversion - use m_weno - - use m_muscl !< Monotonic Upstream-centered (MUSCL) - !! schemes for conservation laws - + use m_muscl !< Monotonic Upstream-centered (MUSCL) schemes for conservation laws use m_helper - use m_boundary_common implicit none - private; public :: s_initialize_surface_tension_module, & - s_compute_capillary_source_flux, & - s_get_capillary, & - s_finalize_surface_tension_module + private; public :: s_initialize_surface_tension_module, s_compute_capillary_source_flux, s_get_capillary, & + & s_finalize_surface_tension_module !> @name color function gradient components and magnitude !> @{ @@ -41,12 +31,12 @@ module m_surface_tension !> @name cell boundary reconstructed gradient components and magnitude !> @{ - real(wp), allocatable, dimension(:, :, :, :) :: gL_x, gR_x, gL_y, gR_y, gL_z, gR_z + real(wp), allocatable, dimension(:,:,:,:) :: gL_x, gR_x, gL_y, gR_y, gL_z, gR_z !> @} - $:GPU_DECLARE(create='[gL_x,gR_x,gL_y,gR_y,gL_z,gR_z]') + $:GPU_DECLARE(create='[gL_x, gR_x, gL_y, gR_y, gL_z, gR_z]') type(int_bounds_info) :: is1, is2, is3, iv - $:GPU_DECLARE(create='[is1,is2,is3,iv]') + $:GPU_DECLARE(create='[is1, is2, is3, iv]') contains @@ -68,25 +58,24 @@ contains @:ALLOCATE(gR_y(idwbuff(2)%beg:idwbuff(2)%end, idwbuff(1)%beg:idwbuff(1)%end, idwbuff(3)%beg:idwbuff(3)%end, num_dims + 1)) if (p > 0) then - @:ALLOCATE(gL_z(idwbuff(3)%beg:idwbuff(3)%end, idwbuff(2)%beg:idwbuff(2)%end, idwbuff(1)%beg:idwbuff(1)%end, num_dims + 1)) - @:ALLOCATE(gR_z(idwbuff(3)%beg:idwbuff(3)%end, idwbuff(2)%beg:idwbuff(2)%end, idwbuff(1)%beg:idwbuff(1)%end, num_dims + 1)) + @:ALLOCATE(gL_z(idwbuff(3)%beg:idwbuff(3)%end, idwbuff(2)%beg:idwbuff(2)%end, idwbuff(1)%beg:idwbuff(1)%end, & + & num_dims + 1)) + @:ALLOCATE(gR_z(idwbuff(3)%beg:idwbuff(3)%end, idwbuff(2)%beg:idwbuff(2)%end, idwbuff(1)%beg:idwbuff(1)%end, & + & num_dims + 1)) end if + end subroutine s_initialize_surface_tension_module !> @brief Computes the capillary (surface-tension) source flux from reconstructed color-gradient fields. - subroutine s_compute_capillary_source_flux( & - vSrc_rsx_vf, vSrc_rsy_vf, vSrc_rsz_vf, & - flux_src_vf, & - id, isx, isy, isz) - - real(wp), dimension(-1:, 0:, 0:, 1:), intent(in) :: vSrc_rsx_vf - real(wp), dimension(-1:, 0:, 0:, 1:), intent(in) :: vSrc_rsy_vf - real(wp), dimension(-1:, 0:, 0:, 1:), intent(in) :: vSrc_rsz_vf - type(scalar_field), & - dimension(sys_size), & - intent(inout) :: flux_src_vf - integer, intent(in) :: id - type(int_bounds_info), intent(in) :: isx, isy, isz + subroutine s_compute_capillary_source_flux(vSrc_rsx_vf, vSrc_rsy_vf, vSrc_rsz_vf, flux_src_vf, id, isx, isy, isz) + + real(wp), dimension(-1:,0:,0:,1:), intent(in) :: vSrc_rsx_vf + real(wp), dimension(-1:,0:,0:,1:), intent(in) :: vSrc_rsy_vf + real(wp), dimension(-1:,0:,0:,1:), intent(in) :: vSrc_rsz_vf + type(scalar_field), dimension(sys_size), intent(inout) :: flux_src_vf + integer, intent(in) :: id + type(int_bounds_info), intent(in) :: isx, isy, isz + #:if not MFC_CASE_OPTIMIZATION and USING_AMD real(wp), dimension(3, 3) :: Omega #:else @@ -94,14 +83,13 @@ contains #:endif real(wp) :: w1L, w1R, w2L, w2R, w3L, w3R, w1, w2, w3 real(wp) :: normWL, normWR, normW - integer :: j, k, l, i + integer :: j, k, l, i if (id == 1) then $:GPU_PARALLEL_LOOP(collapse=3, private='[Omega, w1L, w2L, w3L, w1R, w2R, w3R, w1, w2, w3, normWL, normWR, normW]') do l = isz%beg, isz%end do k = isy%beg, isy%end do j = isx%beg, isx%end - w1L = gL_x(j, k, l, 1) w2L = gL_x(j, k, l, 2) w3L = 0._wp @@ -124,30 +112,25 @@ contains @:compute_capillary_stress_tensor() do i = 1, num_dims + flux_src_vf(momxb + i - 1)%sf(j, k, l) = flux_src_vf(momxb + i - 1)%sf(j, k, l) + Omega(1, i) - flux_src_vf(momxb + i - 1)%sf(j, k, l) = & - flux_src_vf(momxb + i - 1)%sf(j, k, l) + Omega(1, i) - - flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, l) + & - Omega(1, i)*vSrc_rsx_vf(j, k, l, i) - + flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, l) + Omega(1, i)*vSrc_rsx_vf(j, k, & + & l, i) end do - flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, l) + & - sigma*c_divs(num_dims + 1)%sf(j, k, l)*vSrc_rsx_vf(j, k, l, 1) + flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, l) + sigma*c_divs(num_dims + 1)%sf(j, k, & + & l)*vSrc_rsx_vf(j, k, l, 1) end if end do end do end do $:END_GPU_PARALLEL_LOOP() - - elseif (id == 2) then + else if (id == 2) then #:if not MFC_CASE_OPTIMIZATION or num_dims > 1 $:GPU_PARALLEL_LOOP(collapse=3, private='[Omega, w1L, w2L, w3L, w1R, w2R, w3R, w1, w2, w3, normWL, normWR, normW]') do l = isz%beg, isz%end do k = isy%beg, isy%end do j = isx%beg, isx%end - w1L = gL_y(k, j, l, 1) w2L = gL_y(k, j, l, 2) w3L = 0._wp @@ -170,32 +153,26 @@ contains @:compute_capillary_stress_tensor() do i = 1, num_dims + flux_src_vf(momxb + i - 1)%sf(j, k, l) = flux_src_vf(momxb + i - 1)%sf(j, k, l) + Omega(2, i) - flux_src_vf(momxb + i - 1)%sf(j, k, l) = & - flux_src_vf(momxb + i - 1)%sf(j, k, l) + Omega(2, i) - - flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, l) + & - Omega(2, i)*vSrc_rsy_vf(k, j, l, i) - + flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, l) + Omega(2, i)*vSrc_rsy_vf(k, & + & j, l, i) end do - flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, l) + & - sigma*c_divs(num_dims + 1)%sf(j, k, l)*vSrc_rsy_vf(k, j, l, 2) + flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, & + & l) + sigma*c_divs(num_dims + 1)%sf(j, k, l)*vSrc_rsy_vf(k, j, l, 2) end if end do end do end do $:END_GPU_PARALLEL_LOOP() #:endif - - elseif (id == 3) then + else if (id == 3) then #:if not MFC_CASE_OPTIMIZATION or num_dims > 2 - $:GPU_PARALLEL_LOOP(collapse=3, private='[Omega, w1L, w2L, w3L, w1R, w2R, w3R, w1, w2, w3, normWL, normWR, normW]') do l = isz%beg, isz%end do k = isy%beg, isy%end do j = isx%beg, isx%end - w1L = gL_z(l, k, j, 1) w2L = gL_z(l, k, j, 2) w3L = 0._wp @@ -218,17 +195,14 @@ contains @:compute_capillary_stress_tensor() do i = 1, num_dims + flux_src_vf(momxb + i - 1)%sf(j, k, l) = flux_src_vf(momxb + i - 1)%sf(j, k, l) + Omega(3, i) - flux_src_vf(momxb + i - 1)%sf(j, k, l) = & - flux_src_vf(momxb + i - 1)%sf(j, k, l) + Omega(3, i) - - flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, l) + & - Omega(3, i)*vSrc_rsz_vf(l, k, j, i) - + flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, l) + Omega(3, i)*vSrc_rsz_vf(l, & + & k, j, i) end do - flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, l) + & - sigma*c_divs(num_dims + 1)%sf(j, k, l)*vSrc_rsz_vf(l, k, j, 3) + flux_src_vf(E_idx)%sf(j, k, l) = flux_src_vf(E_idx)%sf(j, k, & + & l) + sigma*c_divs(num_dims + 1)%sf(j, k, l)*vSrc_rsz_vf(l, k, j, 3) end if end do end do @@ -242,11 +216,10 @@ contains !> @brief Computes color-function gradients and their norms, then reconstructs them at cell boundaries. impure subroutine s_get_capillary(q_prim_vf, bc_type) - type(scalar_field), dimension(sys_size), intent(in) :: q_prim_vf - type(integer_field), dimension(1:num_dims, 1:2), intent(in) :: bc_type - - type(int_bounds_info) :: isx, isy, isz - integer :: j, k, l, i + type(scalar_field), dimension(sys_size), intent(in) :: q_prim_vf + type(integer_field), dimension(1:num_dims,1:2), intent(in) :: bc_type + type(int_bounds_info) :: isx, isy, isz + integer :: j, k, l, i isx%beg = -1; isy%beg = 0; isz%beg = 0 @@ -259,8 +232,8 @@ contains do l = 0, p do k = 0, n do j = 0, m - c_divs(1)%sf(j, k, l) = 1._wp/(x_cc(j + 1) - x_cc(j - 1))* & - (q_prim_vf(c_idx)%sf(j + 1, k, l) - q_prim_vf(c_idx)%sf(j - 1, k, l)) + c_divs(1)%sf(j, k, l) = 1._wp/(x_cc(j + 1) - x_cc(j - 1))*(q_prim_vf(c_idx)%sf(j + 1, k, & + & l) - q_prim_vf(c_idx)%sf(j - 1, k, l)) end do end do end do @@ -270,8 +243,8 @@ contains do l = 0, p do k = 0, n do j = 0, m - c_divs(2)%sf(j, k, l) = 1._wp/(y_cc(k + 1) - y_cc(k - 1))* & - (q_prim_vf(c_idx)%sf(j, k + 1, l) - q_prim_vf(c_idx)%sf(j, k - 1, l)) + c_divs(2)%sf(j, k, l) = 1._wp/(y_cc(k + 1) - y_cc(k - 1))*(q_prim_vf(c_idx)%sf(j, k + 1, & + & l) - q_prim_vf(c_idx)%sf(j, k - 1, l)) end do end do end do @@ -282,8 +255,8 @@ contains do l = 0, p do k = 0, n do j = 0, m - c_divs(3)%sf(j, k, l) = 1._wp/(z_cc(l + 1) - z_cc(l - 1))* & - (q_prim_vf(c_idx)%sf(j, k, l + 1) - q_prim_vf(c_idx)%sf(j, k, l - 1)) + c_divs(3)%sf(j, k, l) = 1._wp/(z_cc(l + 1) - z_cc(l - 1))*(q_prim_vf(c_idx)%sf(j, k, & + & l + 1) - q_prim_vf(c_idx)%sf(j, k, l - 1)) end do end do end do @@ -297,14 +270,10 @@ contains c_divs(num_dims + 1)%sf(j, k, l) = 0._wp $:GPU_LOOP(parallelism='[seq]') do i = 1, num_dims - c_divs(num_dims + 1)%sf(j, k, l) = & - c_divs(num_dims + 1)%sf(j, k, l) + & - c_divs(i)%sf(j, k, l)**2._wp + c_divs(num_dims + 1)%sf(j, k, l) = c_divs(num_dims + 1)%sf(j, k, l) + c_divs(i)%sf(j, k, l)**2._wp end do - !c_divs(num_dims + 1)%sf(j, k, l) = & - !sqrt(c_divs(num_dims + 1)%sf(j, k, l)) - c_divs(num_dims + 1)%sf(j, k, l) = & - sqrt(real(c_divs(num_dims + 1)%sf(j, k, l), kind=wp)) + ! c_divs(num_dims + 1)%sf(j, k, l) = & sqrt(c_divs(num_dims + 1)%sf(j, k, l)) + c_divs(num_dims + 1)%sf(j, k, l) = sqrt(real(c_divs(num_dims + 1)%sf(j, k, l), kind=wp)) end do end do end do @@ -322,16 +291,13 @@ contains end subroutine s_get_capillary !> @brief Reconstructs left and right cell-boundary values of capillary (color-gradient) variables using WENO or MUSCL. - subroutine s_reconstruct_cell_boundary_values_capillary(v_vf, vL_x, vL_y, vL_z, vR_x, vR_y, vR_z, & - norm_dir) - type(scalar_field), dimension(iv%beg:iv%end), intent(in) :: v_vf + subroutine s_reconstruct_cell_boundary_values_capillary(v_vf, vL_x, vL_y, vL_z, vR_x, vR_y, vR_z, norm_dir) - real(wp), dimension(idwbuff(1)%beg:, idwbuff(2)%beg:, idwbuff(3)%beg:, iv%beg:), intent(out) :: vL_x, vL_y, vL_z - real(wp), dimension(idwbuff(1)%beg:, idwbuff(2)%beg:, idwbuff(3)%beg:, iv%beg:), intent(out) :: vR_x, vR_y, vR_z + type(scalar_field), dimension(iv%beg:iv%end), intent(in) :: v_vf + real(wp), dimension(idwbuff(1)%beg:,idwbuff(2)%beg:,idwbuff(3)%beg:,iv%beg:), intent(out) :: vL_x, vL_y, vL_z + real(wp), dimension(idwbuff(1)%beg:,idwbuff(2)%beg:,idwbuff(3)%beg:,iv%beg:), intent(out) :: vR_x, vR_y, vR_z integer, intent(in) :: norm_dir - - integer :: recon_dir !< Coordinate direction of the reconstruction - + integer :: recon_dir !< Coordinate direction of the reconstruction integer :: i, j, k, l #:for SCHEME, TYPE in [('weno', 'WENO_TYPE'),('muscl', 'MUSCL_TYPE')] @@ -342,20 +308,17 @@ contains is1 = idwbuff(1); is2 = idwbuff(2); is3 = idwbuff(3) recon_dir = 1; is1%beg = is1%beg + ${SCHEME}$_polyn is1%end = is1%end - ${SCHEME}$_polyn - - elseif (norm_dir == 2) then + else if (norm_dir == 2) then is1 = idwbuff(2); is2 = idwbuff(1); is3 = idwbuff(3) recon_dir = 2; is1%beg = is1%beg + ${SCHEME}$_polyn is1%end = is1%end - ${SCHEME}$_polyn - else is1 = idwbuff(3); is2 = idwbuff(2); is3 = idwbuff(1) recon_dir = 3; is1%beg = is1%beg + ${SCHEME}$_polyn is1%end = is1%end - ${SCHEME}$_polyn - end if - $:GPU_UPDATE(device='[is1,is2,is3,iv]') + $:GPU_UPDATE(device='[is1, is2, is3, iv]') end if #:endfor @@ -404,6 +367,7 @@ contains !> @brief Deallocates the color-gradient divergence and reconstructed boundary arrays for surface tension. impure subroutine s_finalize_surface_tension_module + integer :: j do j = 1, num_dims diff --git a/src/simulation/m_time_steppers.fpp b/src/simulation/m_time_steppers.fpp index cc17df07f1..253f0aaf9a 100644 --- a/src/simulation/m_time_steppers.fpp +++ b/src/simulation/m_time_steppers.fpp @@ -9,91 +9,60 @@ module m_time_steppers use m_derived_types !< Definitions of the derived types - use m_global_parameters !< Definitions of the global parameters - use m_rhs !< Right-hane-side (RHS) evaluation procedures - use m_pressure_relaxation !< Pressure relaxation procedures - use m_data_output !< Run-time info & solution data output procedures - use m_bubbles_EE !< Ensemble-averaged bubble dynamics routines - use m_bubbles_EL !< Lagrange bubble dynamics routines - use m_ibm - use m_hyperelastic - use m_mpi_proxy !< Message passing interface (MPI) module proxy - use m_boundary_common - use m_helper - use m_sim_helpers - use m_fftw - use m_nvtx - use m_thermochem, only: num_species - use m_body_forces - use m_derived_variables implicit none - type(vector_field), allocatable, dimension(:) :: q_cons_ts !< - !! Cell-average conservative variables at each time-stage (TS) - - type(scalar_field), allocatable, dimension(:) :: q_prim_vf !< - !! Cell-average primitive variables at the current time-stage - - type(scalar_field), allocatable, dimension(:) :: rhs_vf !< - !! Cell-average RHS variables at the current time-stage - - type(integer_field), allocatable, dimension(:, :) :: bc_type !< - !! Boundary condition identifiers - - type(vector_field), allocatable, dimension(:) :: q_prim_ts1, q_prim_ts2 !< - !! Cell-average primitive variables at consecutive TIMESTEPS + type(vector_field), allocatable, dimension(:) :: q_cons_ts !< Cell-average conservative variables at each time-stage (TS) + type(scalar_field), allocatable, dimension(:) :: q_prim_vf !< Cell-average primitive variables at the current time-stage + type(scalar_field), allocatable, dimension(:) :: rhs_vf !< Cell-average RHS variables at the current time-stage + type(integer_field), allocatable, dimension(:,:) :: bc_type !< Boundary condition identifiers - real(wp), allocatable, dimension(:, :, :, :, :) :: rhs_pb + !> Cell-average primitive variables at consecutive TIMESTEPS + type(vector_field), allocatable, dimension(:) :: q_prim_ts1, q_prim_ts2 + real(wp), allocatable, dimension(:,:,:,:,:) :: rhs_pb + type(scalar_field) :: q_T_sf !< Cell-average temperature variables at the current time-stage + real(wp), allocatable, dimension(:,:,:,:,:) :: rhs_mv + integer, private :: num_ts !< Number of time stages in the time-stepping scheme + integer :: stor !< storage index + real(wp), allocatable, dimension(:,:) :: rk_coef + integer, private :: num_probe_ts - type(scalar_field) :: q_T_sf !< - !! Cell-average temperature variables at the current time-stage + $:GPU_DECLARE(create='[q_cons_ts, q_prim_vf, q_T_sf, rhs_vf, q_prim_ts1, q_prim_ts2, rhs_mv, rhs_pb, rk_coef, stor, bc_type]') - real(wp), allocatable, dimension(:, :, :, :, :) :: rhs_mv - - integer, private :: num_ts !< - !! Number of time stages in the time-stepping scheme - - integer :: stor !< storage index - real(wp), allocatable, dimension(:, :) :: rk_coef - integer, private :: num_probe_ts - - $:GPU_DECLARE(create='[q_cons_ts,q_prim_vf,q_T_sf,rhs_vf,q_prim_ts1,q_prim_ts2,rhs_mv,rhs_pb,rk_coef,stor,bc_type]') - -!> @cond + !> @cond #if defined(__NVCOMPILER_GPU_UNIFIED_MEM) - real(stp), allocatable, dimension(:, :, :, :), pinned, target :: q_cons_ts_pool_host + real(stp), allocatable, dimension(:,:,:,:), pinned, target :: q_cons_ts_pool_host #elif defined(FRONTIER_UNIFIED) - real(stp), pointer, contiguous, dimension(:, :, :, :) :: q_cons_ts_pool_host, q_cons_ts_pool_device - integer(kind=8) :: pool_dims(4), pool_starts(4) - integer(kind=8) :: pool_size - type(c_ptr) :: cptr_host, cptr_device + real(stp), pointer, contiguous, dimension(:,:,:,:) :: q_cons_ts_pool_host, q_cons_ts_pool_device + integer(kind=8) :: pool_dims(4), pool_starts(4) + integer(kind=8) :: pool_size + type(c_ptr) :: cptr_host, cptr_device #endif -!> @endcond + !> @endcond contains - !> The computation of parameters, the allocation of memory, - !! the association of pointers and/or the execution of any - !! other procedures that are necessary to setup the module. + !> The computation of parameters, the allocation of memory, the association of pointers and/or the execution of any other + !! procedures that are necessary to setup the module. impure subroutine s_initialize_time_steppers_module + #ifdef FRONTIER_UNIFIED use hipfort use hipfort_hipmalloc @@ -102,12 +71,12 @@ contains use openacc #endif #endif - integer :: i, j !< Generic loop iterators + integer :: i, j !< Generic loop iterators ! Setting number of time-stages for selected time-stepping scheme if (time_stepper == 1) then num_ts = 1 - elseif (any(time_stepper == (/2, 3/))) then + else if (any(time_stepper == (/2, 3/))) then num_ts = 2 end if @@ -124,32 +93,27 @@ contains @:PREFER_GPU(q_cons_ts(i)%vf) end do -!> @cond + !> @cond #if defined(__NVCOMPILER_GPU_UNIFIED_MEM) if (num_ts == 2 .and. nv_uvm_out_of_core) then ! host allocation for q_cons_ts(2)%vf(j)%sf for all j - allocate (q_cons_ts_pool_host(idwbuff(1)%beg:idwbuff(1)%end, & - idwbuff(2)%beg:idwbuff(2)%end, & - idwbuff(3)%beg:idwbuff(3)%end, & - 1:sys_size)) + allocate (q_cons_ts_pool_host(idwbuff(1)%beg:idwbuff(1)%end,idwbuff(2)%beg:idwbuff(2)%end, & + & idwbuff(3)%beg:idwbuff(3)%end,1:sys_size)) end if do j = 1, sys_size ! q_cons_ts(1) lives on the device - @:ALLOCATE(q_cons_ts(1)%vf(j)%sf(idwbuff(1)%beg:idwbuff(1)%end, & - idwbuff(2)%beg:idwbuff(2)%end, & - idwbuff(3)%beg:idwbuff(3)%end)) + @:ALLOCATE(q_cons_ts(1)%vf(j)%sf(idwbuff(1)%beg:idwbuff(1)%end, idwbuff(2)%beg:idwbuff(2)%end, & + & idwbuff(3)%beg:idwbuff(3)%end)) @:PREFER_GPU(q_cons_ts(1)%vf(j)%sf) if (num_ts == 2) then if (nv_uvm_out_of_core) then ! q_cons_ts(2) lives on the host - q_cons_ts(2)%vf(j)%sf(idwbuff(1)%beg:idwbuff(1)%end, & - idwbuff(2)%beg:idwbuff(2)%end, & - idwbuff(3)%beg:idwbuff(3)%end) => q_cons_ts_pool_host(:, :, :, j) + q_cons_ts(2)%vf(j)%sf(idwbuff(1)%beg:idwbuff(1)%end,idwbuff(2)%beg:idwbuff(2)%end, & + & idwbuff(3)%beg:idwbuff(3)%end) => q_cons_ts_pool_host(:,:,:,j) else - @:ALLOCATE(q_cons_ts(2)%vf(j)%sf(idwbuff(1)%beg:idwbuff(1)%end, & - idwbuff(2)%beg:idwbuff(2)%end, & - idwbuff(3)%beg:idwbuff(3)%end)) + @:ALLOCATE(q_cons_ts(2)%vf(j)%sf(idwbuff(1)%beg:idwbuff(1)%end, idwbuff(2)%beg:idwbuff(2)%end, & + & idwbuff(3)%beg:idwbuff(3)%end)) @:PREFER_GPU(q_cons_ts(2)%vf(j)%sf) end if end if @@ -159,8 +123,7 @@ contains @:ACC_SETUP_VFs(q_cons_ts(i)) end do #elif defined(FRONTIER_UNIFIED) - ! Allocate to memory regions using hip calls - ! that we will attach pointers to + ! Allocate to memory regions using hip calls that we will attach pointers to do i = 1, 3 pool_dims(i) = idwbuff(i)%end - idwbuff(i)%beg + 1 pool_starts(i) = idwbuff(i)%beg @@ -168,14 +131,15 @@ contains pool_dims(4) = sys_size pool_starts(4) = 1 #ifdef MFC_MIXED_PRECISION - pool_size = 1_8*(idwbuff(1)%end - idwbuff(1)%beg + 1)*(idwbuff(2)%end - idwbuff(2)%beg + 1)*(idwbuff(3)%end - idwbuff(3)%beg + 1)*sys_size + pool_size = 1_8*(idwbuff(1)%end - idwbuff(1)%beg + 1)*(idwbuff(2)%end - idwbuff(2)%beg + 1)*(idwbuff(3)%end - idwbuff(3) & + & %beg + 1)*sys_size call hipCheck(hipMalloc_(cptr_device, pool_size*2_8)) call c_f_pointer(cptr_device, q_cons_ts_pool_device, shape=pool_dims) - q_cons_ts_pool_device(idwbuff(1)%beg:, idwbuff(2)%beg:, idwbuff(3)%beg:, 1:) => q_cons_ts_pool_device + q_cons_ts_pool_device(idwbuff(1)%beg:,idwbuff(2)%beg:,idwbuff(3)%beg:,1:) => q_cons_ts_pool_device call hipCheck(hipMallocManaged_(cptr_host, pool_size*2_8, hipMemAttachGlobal)) call c_f_pointer(cptr_host, q_cons_ts_pool_host, shape=pool_dims) - q_cons_ts_pool_host(idwbuff(1)%beg:, idwbuff(2)%beg:, idwbuff(3)%beg:, 1:) => q_cons_ts_pool_host + q_cons_ts_pool_host(idwbuff(1)%beg:,idwbuff(2)%beg:,idwbuff(3)%beg:,1:) => q_cons_ts_pool_host #else ! Doing hipMalloc then mapping should be most performant call hipCheck(hipMalloc(q_cons_ts_pool_device, dims8=pool_dims, lbounds8=pool_starts)) @@ -183,27 +147,26 @@ contains #if defined(MFC_OpenACC) call acc_map_data(q_cons_ts_pool_device, c_loc(q_cons_ts_pool_device), c_sizeof(q_cons_ts_pool_device)) #endif - ! CCE see it can access this and will leave it on the host. It will stay on the host so long as HSA_XNACK=1 - ! NOTE: WE CANNOT DO ATOMICS INTO THIS MEMORY. We have to change a property to use atomics here - ! Otherwise leaving this as fine-grained will actually help performance since it can't be cached in GPU L2 + ! CCE see it can access this and will leave it on the host. It will stay on the host so long as HSA_XNACK=1 NOTE: WE CANNOT + ! DO ATOMICS INTO THIS MEMORY. We have to change a property to use atomics here Otherwise leaving this as fine-grained will + ! actually help performance since it can't be cached in GPU L2 if (num_ts == 2) then call hipCheck(hipMallocManaged(q_cons_ts_pool_host, dims8=pool_dims, lbounds8=pool_starts, flags=hipMemAttachGlobal)) #if defined(MFC_OpenMP) - call hipCheck(hipMemAdvise(c_loc(q_cons_ts_pool_host), c_sizeof(q_cons_ts_pool_host), hipMemAdviseSetPreferredLocation, -1)) + call hipCheck(hipMemAdvise(c_loc(q_cons_ts_pool_host), c_sizeof(q_cons_ts_pool_host), & + & hipMemAdviseSetPreferredLocation, -1)) #endif end if #endif do j = 1, sys_size ! q_cons_ts(1) lives on the device - q_cons_ts(1)%vf(j)%sf(idwbuff(1)%beg:idwbuff(1)%end, & - idwbuff(2)%beg:idwbuff(2)%end, & - idwbuff(3)%beg:idwbuff(3)%end) => q_cons_ts_pool_device(:, :, :, j) + q_cons_ts(1)%vf(j)%sf(idwbuff(1)%beg:idwbuff(1)%end,idwbuff(2)%beg:idwbuff(2)%end, & + & idwbuff(3)%beg:idwbuff(3)%end) => q_cons_ts_pool_device(:,:,:,j) if (num_ts == 2) then ! q_cons_ts(2) lives on the host - q_cons_ts(2)%vf(j)%sf(idwbuff(1)%beg:idwbuff(1)%end, & - idwbuff(2)%beg:idwbuff(2)%end, & - idwbuff(3)%beg:idwbuff(3)%end) => q_cons_ts_pool_host(:, :, :, j) + q_cons_ts(2)%vf(j)%sf(idwbuff(1)%beg:idwbuff(1)%end,idwbuff(2)%beg:idwbuff(2)%end, & + & idwbuff(3)%beg:idwbuff(3)%end) => q_cons_ts_pool_host(:,:,:,j) end if end do @@ -214,18 +177,17 @@ contains end do end do #else -!> @endcond + !> @endcond do i = 1, num_ts do j = 1, sys_size - @:ALLOCATE(q_cons_ts(i)%vf(j)%sf(idwbuff(1)%beg:idwbuff(1)%end, & - idwbuff(2)%beg:idwbuff(2)%end, & - idwbuff(3)%beg:idwbuff(3)%end)) + @:ALLOCATE(q_cons_ts(i)%vf(j)%sf(idwbuff(1)%beg:idwbuff(1)%end, idwbuff(2)%beg:idwbuff(2)%end, & + & idwbuff(3)%beg:idwbuff(3)%end)) end do @:ACC_SETUP_VFs(q_cons_ts(i)) end do -!> @cond + !> @cond #endif -!> @endcond + !> @endcond ! Allocating the cell-average primitive ts variables if (probe_wrt) then @@ -237,9 +199,8 @@ contains do i = 1, num_probe_ts do j = 1, sys_size - @:ALLOCATE(q_prim_ts1(i)%vf(j)%sf(idwbuff(1)%beg:idwbuff(1)%end, & - idwbuff(2)%beg:idwbuff(2)%end, & - idwbuff(3)%beg:idwbuff(3)%end)) + @:ALLOCATE(q_prim_ts1(i)%vf(j)%sf(idwbuff(1)%beg:idwbuff(1)%end, idwbuff(2)%beg:idwbuff(2)%end, & + & idwbuff(3)%beg:idwbuff(3)%end)) end do @:ACC_SETUP_VFs(q_prim_ts1(i)) end do @@ -252,9 +213,8 @@ contains do i = 1, num_probe_ts do j = 1, sys_size - @:ALLOCATE(q_prim_ts2(i)%vf(j)%sf(idwbuff(1)%beg:idwbuff(1)%end, & - idwbuff(2)%beg:idwbuff(2)%end, & - idwbuff(3)%beg:idwbuff(3)%end)) + @:ALLOCATE(q_prim_ts2(i)%vf(j)%sf(idwbuff(1)%beg:idwbuff(1)%end, idwbuff(2)%beg:idwbuff(2)%end, & + & idwbuff(3)%beg:idwbuff(3)%end)) end do @:ACC_SETUP_VFs(q_prim_ts2(i)) end do @@ -265,129 +225,110 @@ contains if (.not. igr) then do i = 1, adv_idx%end - @:ALLOCATE(q_prim_vf(i)%sf(idwbuff(1)%beg:idwbuff(1)%end, & - idwbuff(2)%beg:idwbuff(2)%end, & - idwbuff(3)%beg:idwbuff(3)%end)) + @:ALLOCATE(q_prim_vf(i)%sf(idwbuff(1)%beg:idwbuff(1)%end, idwbuff(2)%beg:idwbuff(2)%end, & + & idwbuff(3)%beg:idwbuff(3)%end)) @:ACC_SETUP_SFs(q_prim_vf(i)) end do if (bubbles_euler) then do i = bub_idx%beg, bub_idx%end - @:ALLOCATE(q_prim_vf(i)%sf(idwbuff(1)%beg:idwbuff(1)%end, & - idwbuff(2)%beg:idwbuff(2)%end, & - idwbuff(3)%beg:idwbuff(3)%end)) + @:ALLOCATE(q_prim_vf(i)%sf(idwbuff(1)%beg:idwbuff(1)%end, idwbuff(2)%beg:idwbuff(2)%end, & + & idwbuff(3)%beg:idwbuff(3)%end)) @:ACC_SETUP_SFs(q_prim_vf(i)) end do if (adv_n) then - @:ALLOCATE(q_prim_vf(n_idx)%sf(idwbuff(1)%beg:idwbuff(1)%end, & - idwbuff(2)%beg:idwbuff(2)%end, & - idwbuff(3)%beg:idwbuff(3)%end)) + @:ALLOCATE(q_prim_vf(n_idx)%sf(idwbuff(1)%beg:idwbuff(1)%end, idwbuff(2)%beg:idwbuff(2)%end, & + & idwbuff(3)%beg:idwbuff(3)%end)) @:ACC_SETUP_SFs(q_prim_vf(n_idx)) end if end if if (mhd) then do i = B_idx%beg, B_idx%end - @:ALLOCATE(q_prim_vf(i)%sf(idwbuff(1)%beg:idwbuff(1)%end, & - idwbuff(2)%beg:idwbuff(2)%end, & - idwbuff(3)%beg:idwbuff(3)%end)) + @:ALLOCATE(q_prim_vf(i)%sf(idwbuff(1)%beg:idwbuff(1)%end, idwbuff(2)%beg:idwbuff(2)%end, & + & idwbuff(3)%beg:idwbuff(3)%end)) @:ACC_SETUP_SFs(q_prim_vf(i)) end do end if if (elasticity) then do i = stress_idx%beg, stress_idx%end - @:ALLOCATE(q_prim_vf(i)%sf(idwbuff(1)%beg:idwbuff(1)%end, & - idwbuff(2)%beg:idwbuff(2)%end, & - idwbuff(3)%beg:idwbuff(3)%end)) + @:ALLOCATE(q_prim_vf(i)%sf(idwbuff(1)%beg:idwbuff(1)%end, idwbuff(2)%beg:idwbuff(2)%end, & + & idwbuff(3)%beg:idwbuff(3)%end)) @:ACC_SETUP_SFs(q_prim_vf(i)) end do end if if (hyperelasticity) then do i = xibeg, xiend + 1 - @:ALLOCATE(q_prim_vf(i)%sf(idwbuff(1)%beg:idwbuff(1)%end, & - idwbuff(2)%beg:idwbuff(2)%end, & - idwbuff(3)%beg:idwbuff(3)%end)) + @:ALLOCATE(q_prim_vf(i)%sf(idwbuff(1)%beg:idwbuff(1)%end, idwbuff(2)%beg:idwbuff(2)%end, & + & idwbuff(3)%beg:idwbuff(3)%end)) @:ACC_SETUP_SFs(q_prim_vf(i)) end do end if if (cont_damage) then - @:ALLOCATE(q_prim_vf(damage_idx)%sf(idwbuff(1)%beg:idwbuff(1)%end, & - idwbuff(2)%beg:idwbuff(2)%end, & - idwbuff(3)%beg:idwbuff(3)%end)) + @:ALLOCATE(q_prim_vf(damage_idx)%sf(idwbuff(1)%beg:idwbuff(1)%end, idwbuff(2)%beg:idwbuff(2)%end, & + & idwbuff(3)%beg:idwbuff(3)%end)) @:ACC_SETUP_SFs(q_prim_vf(damage_idx)) end if if (hyper_cleaning) then - @:ALLOCATE(q_prim_vf(psi_idx)%sf(idwbuff(1)%beg:idwbuff(1)%end, & - idwbuff(2)%beg:idwbuff(2)%end, & - idwbuff(3)%beg:idwbuff(3)%end)) + @:ALLOCATE(q_prim_vf(psi_idx)%sf(idwbuff(1)%beg:idwbuff(1)%end, idwbuff(2)%beg:idwbuff(2)%end, & + & idwbuff(3)%beg:idwbuff(3)%end)) @:ACC_SETUP_SFs(q_prim_vf(psi_idx)) end if if (model_eqns == 3) then do i = internalEnergies_idx%beg, internalEnergies_idx%end - @:ALLOCATE(q_prim_vf(i)%sf(idwbuff(1)%beg:idwbuff(1)%end, & - idwbuff(2)%beg:idwbuff(2)%end, & - idwbuff(3)%beg:idwbuff(3)%end)) + @:ALLOCATE(q_prim_vf(i)%sf(idwbuff(1)%beg:idwbuff(1)%end, idwbuff(2)%beg:idwbuff(2)%end, & + & idwbuff(3)%beg:idwbuff(3)%end)) @:ACC_SETUP_SFs(q_prim_vf(i)) end do end if if (surface_tension) then - @:ALLOCATE(q_prim_vf(c_idx)%sf(idwbuff(1)%beg:idwbuff(1)%end, & - idwbuff(2)%beg:idwbuff(2)%end, & - idwbuff(3)%beg:idwbuff(3)%end)) + @:ALLOCATE(q_prim_vf(c_idx)%sf(idwbuff(1)%beg:idwbuff(1)%end, idwbuff(2)%beg:idwbuff(2)%end, & + & idwbuff(3)%beg:idwbuff(3)%end)) @:ACC_SETUP_SFs(q_prim_vf(c_idx)) end if if (chemistry) then do i = chemxb, chemxe - @:ALLOCATE(q_prim_vf(i)%sf(idwbuff(1)%beg:idwbuff(1)%end, & - idwbuff(2)%beg:idwbuff(2)%end, & - idwbuff(3)%beg:idwbuff(3)%end)) + @:ALLOCATE(q_prim_vf(i)%sf(idwbuff(1)%beg:idwbuff(1)%end, idwbuff(2)%beg:idwbuff(2)%end, & + & idwbuff(3)%beg:idwbuff(3)%end)) @:ACC_SETUP_SFs(q_prim_vf(i)) end do - @:ALLOCATE(q_T_sf%sf(idwbuff(1)%beg:idwbuff(1)%end, & - idwbuff(2)%beg:idwbuff(2)%end, & - idwbuff(3)%beg:idwbuff(3)%end)) + @:ALLOCATE(q_T_sf%sf(idwbuff(1)%beg:idwbuff(1)%end, idwbuff(2)%beg:idwbuff(2)%end, idwbuff(3)%beg:idwbuff(3)%end)) @:ACC_SETUP_SFs(q_T_sf) end if end if @:ALLOCATE(pb_ts(1:2)) - !Initialize bubble variables pb and mv at all quadrature nodes for all R0 bins + ! Initialize bubble variables pb and mv at all quadrature nodes for all R0 bins if (qbmm .and. (.not. polytropic)) then - @:ALLOCATE(pb_ts(1)%sf(idwbuff(1)%beg:idwbuff(1)%end, & - idwbuff(2)%beg:idwbuff(2)%end, & - idwbuff(3)%beg:idwbuff(3)%end, 1:nnode, 1:nb)) + @:ALLOCATE(pb_ts(1)%sf(idwbuff(1)%beg:idwbuff(1)%end, idwbuff(2)%beg:idwbuff(2)%end, idwbuff(3)%beg:idwbuff(3)%end, & + & 1:nnode, 1:nb)) @:ACC_SETUP_SFs(pb_ts(1)) - @:ALLOCATE(pb_ts(2)%sf(idwbuff(1)%beg:idwbuff(1)%end, & - idwbuff(2)%beg:idwbuff(2)%end, & - idwbuff(3)%beg:idwbuff(3)%end, 1:nnode, 1:nb)) + @:ALLOCATE(pb_ts(2)%sf(idwbuff(1)%beg:idwbuff(1)%end, idwbuff(2)%beg:idwbuff(2)%end, idwbuff(3)%beg:idwbuff(3)%end, & + & 1:nnode, 1:nb)) @:ACC_SETUP_SFs(pb_ts(2)) - @:ALLOCATE(rhs_pb(idwbuff(1)%beg:idwbuff(1)%end, & - idwbuff(2)%beg:idwbuff(2)%end, & - idwbuff(3)%beg:idwbuff(3)%end, 1:nnode, 1:nb)) + @:ALLOCATE(rhs_pb(idwbuff(1)%beg:idwbuff(1)%end, idwbuff(2)%beg:idwbuff(2)%end, idwbuff(3)%beg:idwbuff(3)%end, & + & 1:nnode, 1:nb)) else if (qbmm .and. polytropic) then - @:ALLOCATE(pb_ts(1)%sf(idwbuff(1)%beg:idwbuff(1)%beg + 1, & - idwbuff(2)%beg:idwbuff(2)%beg + 1, & - idwbuff(3)%beg:idwbuff(3)%beg + 1, 1:nnode, 1:nb)) + @:ALLOCATE(pb_ts(1)%sf(idwbuff(1)%beg:idwbuff(1)%beg + 1, idwbuff(2)%beg:idwbuff(2)%beg + 1, & + & idwbuff(3)%beg:idwbuff(3)%beg + 1, 1:nnode, 1:nb)) @:ACC_SETUP_SFs(pb_ts(1)) - @:ALLOCATE(pb_ts(2)%sf(idwbuff(1)%beg:idwbuff(1)%beg + 1, & - idwbuff(2)%beg:idwbuff(2)%beg + 1, & - idwbuff(3)%beg:idwbuff(3)%beg + 1, 1:nnode, 1:nb)) + @:ALLOCATE(pb_ts(2)%sf(idwbuff(1)%beg:idwbuff(1)%beg + 1, idwbuff(2)%beg:idwbuff(2)%beg + 1, & + & idwbuff(3)%beg:idwbuff(3)%beg + 1, 1:nnode, 1:nb)) @:ACC_SETUP_SFs(pb_ts(2)) - @:ALLOCATE(rhs_pb(idwbuff(1)%beg:idwbuff(1)%beg + 1, & - idwbuff(2)%beg:idwbuff(2)%beg + 1, & - idwbuff(3)%beg:idwbuff(3)%beg + 1, 1:nnode, 1:nb)) + @:ALLOCATE(rhs_pb(idwbuff(1)%beg:idwbuff(1)%beg + 1, idwbuff(2)%beg:idwbuff(2)%beg + 1, & + & idwbuff(3)%beg:idwbuff(3)%beg + 1, 1:nnode, 1:nb)) else @:ALLOCATE(pb_ts(1)%sf(0,0,0,0,0)) @:ACC_SETUP_SFs(pb_ts(1)) @@ -401,34 +342,27 @@ contains @:ALLOCATE(mv_ts(1:2)) if (qbmm .and. (.not. polytropic)) then - @:ALLOCATE(mv_ts(1)%sf(idwbuff(1)%beg:idwbuff(1)%end, & - idwbuff(2)%beg:idwbuff(2)%end, & - idwbuff(3)%beg:idwbuff(3)%end, 1:nnode, 1:nb)) + @:ALLOCATE(mv_ts(1)%sf(idwbuff(1)%beg:idwbuff(1)%end, idwbuff(2)%beg:idwbuff(2)%end, idwbuff(3)%beg:idwbuff(3)%end, & + & 1:nnode, 1:nb)) @:ACC_SETUP_SFs(mv_ts(1)) - @:ALLOCATE(mv_ts(2)%sf(idwbuff(1)%beg:idwbuff(1)%end, & - idwbuff(2)%beg:idwbuff(2)%end, & - idwbuff(3)%beg:idwbuff(3)%end, 1:nnode, 1:nb)) + @:ALLOCATE(mv_ts(2)%sf(idwbuff(1)%beg:idwbuff(1)%end, idwbuff(2)%beg:idwbuff(2)%end, idwbuff(3)%beg:idwbuff(3)%end, & + & 1:nnode, 1:nb)) @:ACC_SETUP_SFs(mv_ts(2)) - @:ALLOCATE(rhs_mv(idwbuff(1)%beg:idwbuff(1)%end, & - idwbuff(2)%beg:idwbuff(2)%end, & - idwbuff(3)%beg:idwbuff(3)%end, 1:nnode, 1:nb)) - + @:ALLOCATE(rhs_mv(idwbuff(1)%beg:idwbuff(1)%end, idwbuff(2)%beg:idwbuff(2)%end, idwbuff(3)%beg:idwbuff(3)%end, & + & 1:nnode, 1:nb)) else if (qbmm .and. polytropic) then - @:ALLOCATE(mv_ts(1)%sf(idwbuff(1)%beg:idwbuff(1)%beg + 1, & - idwbuff(2)%beg:idwbuff(2)%beg + 1, & - idwbuff(3)%beg:idwbuff(3)%beg + 1, 1:nnode, 1:nb)) + @:ALLOCATE(mv_ts(1)%sf(idwbuff(1)%beg:idwbuff(1)%beg + 1, idwbuff(2)%beg:idwbuff(2)%beg + 1, & + & idwbuff(3)%beg:idwbuff(3)%beg + 1, 1:nnode, 1:nb)) @:ACC_SETUP_SFs(mv_ts(1)) - @:ALLOCATE(mv_ts(2)%sf(idwbuff(1)%beg:idwbuff(1)%beg + 1, & - idwbuff(2)%beg:idwbuff(2)%beg + 1, & - idwbuff(3)%beg:idwbuff(3)%beg + 1, 1:nnode, 1:nb)) + @:ALLOCATE(mv_ts(2)%sf(idwbuff(1)%beg:idwbuff(1)%beg + 1, idwbuff(2)%beg:idwbuff(2)%beg + 1, & + & idwbuff(3)%beg:idwbuff(3)%beg + 1, 1:nnode, 1:nb)) @:ACC_SETUP_SFs(mv_ts(2)) - @:ALLOCATE(rhs_mv(idwbuff(1)%beg:idwbuff(1)%beg + 1, & - idwbuff(2)%beg:idwbuff(2)%beg + 1, & - idwbuff(3)%beg:idwbuff(3)%beg + 1, 1:nnode, 1:nb)) + @:ALLOCATE(rhs_mv(idwbuff(1)%beg:idwbuff(1)%beg + 1, idwbuff(2)%beg:idwbuff(2)%beg + 1, & + & idwbuff(3)%beg:idwbuff(3)%beg + 1, 1:nnode, 1:nb)) else @:ALLOCATE(mv_ts(1)%sf(0,0,0,0,0)) @:ACC_SETUP_SFs(mv_ts(1)) @@ -499,16 +433,16 @@ contains end if ! TVD RK coefficients - @:ALLOCATE (rk_coef(time_stepper, 4)) + @:ALLOCATE(rk_coef(time_stepper, 4)) if (time_stepper == 1) then - rk_coef(1, :) = (/1._wp, 0._wp, 1._wp, 1._wp/) + rk_coef(1,:) = (/1._wp, 0._wp, 1._wp, 1._wp/) else if (time_stepper == 2) then - rk_coef(1, :) = (/1._wp, 0._wp, 1._wp, 1._wp/) - rk_coef(2, :) = (/1._wp, 1._wp, 1._wp, 2._wp/) + rk_coef(1,:) = (/1._wp, 0._wp, 1._wp, 1._wp/) + rk_coef(2,:) = (/1._wp, 1._wp, 1._wp, 2._wp/) else if (time_stepper == 3) then - rk_coef(1, :) = (/1._wp, 0._wp, 1._wp, 1._wp/) - rk_coef(2, :) = (/1._wp, 3._wp, 1._wp, 4._wp/) - rk_coef(3, :) = (/2._wp, 1._wp, 2._wp, 3._wp/) + rk_coef(1,:) = (/1._wp, 0._wp, 1._wp, 1._wp/) + rk_coef(2,:) = (/1._wp, 3._wp, 1._wp, 4._wp/) + rk_coef(3,:) = (/2._wp, 1._wp, 2._wp, 3._wp/) end if $:GPU_UPDATE(device='[rk_coef, stor]') end if @@ -517,16 +451,16 @@ contains !> @brief Advances the solution one full step using a TVD Runge-Kutta time integrator. impure subroutine s_tvd_rk(t_step, time_avg, nstage) + #ifdef _CRAYFTN - !DIR$ OPTIMIZE (-haggress) + ! DIR$ OPTIMIZE (-haggress) #endif - integer, intent(in) :: t_step + integer, intent(in) :: t_step real(wp), intent(inout) :: time_avg - integer, intent(in) :: nstage - - integer :: i, j, k, l, q, s !< Generic loop iterator - real(wp) :: start, finish - integer :: dest + integer, intent(in) :: nstage + integer :: i, j, k, l, q, s !< Generic loop iterator + real(wp) :: start, finish + integer :: dest call cpu_time(start) call nvtxStartRange("TIMESTEP") @@ -535,7 +469,8 @@ contains if (adap_dt) call s_adaptive_dt_bubble(1) do s = 1, nstage - call s_compute_rhs(q_cons_ts(1)%vf, q_T_sf, q_prim_vf, bc_type, rhs_vf, pb_ts(1)%sf, rhs_pb, mv_ts(1)%sf, rhs_mv, t_step, time_avg, s) + call s_compute_rhs(q_cons_ts(1)%vf, q_T_sf, q_prim_vf, bc_type, rhs_vf, pb_ts(1)%sf, rhs_pb, mv_ts(1)%sf, rhs_mv, & + & t_step, time_avg, s) if (s == 1) then if (run_time_info) then @@ -566,26 +501,23 @@ contains do k = 0, n do j = 0, m if (s == 1 .and. nstage > 1) then - q_cons_ts(stor)%vf(i)%sf(j, k, l) = & - q_cons_ts(1)%vf(i)%sf(j, k, l) + q_cons_ts(stor)%vf(i)%sf(j, k, l) = q_cons_ts(1)%vf(i)%sf(j, k, l) end if if (igr) then - q_cons_ts(1)%vf(i)%sf(j, k, l) = & - (rk_coef(s, 1)*q_cons_ts(1)%vf(i)%sf(j, k, l) & - + rk_coef(s, 2)*q_cons_ts(stor)%vf(i)%sf(j, k, l) & - + rk_coef(s, 3)*rhs_vf(i)%sf(j, k, l))/rk_coef(s, 4) + q_cons_ts(1)%vf(i)%sf(j, k, l) = (rk_coef(s, 1)*q_cons_ts(1)%vf(i)%sf(j, k, l) + rk_coef(s, & + & 2)*q_cons_ts(stor)%vf(i)%sf(j, k, l) + rk_coef(s, 3)*rhs_vf(i)%sf(j, k, & + & l))/rk_coef(s, 4) else - q_cons_ts(1)%vf(i)%sf(j, k, l) = & - (rk_coef(s, 1)*q_cons_ts(1)%vf(i)%sf(j, k, l) & - + rk_coef(s, 2)*q_cons_ts(stor)%vf(i)%sf(j, k, l) & - + rk_coef(s, 3)*dt*rhs_vf(i)%sf(j, k, l))/rk_coef(s, 4) + q_cons_ts(1)%vf(i)%sf(j, k, l) = (rk_coef(s, 1)*q_cons_ts(1)%vf(i)%sf(j, k, l) + rk_coef(s, & + & 2)*q_cons_ts(stor)%vf(i)%sf(j, k, l) + rk_coef(s, 3)*dt*rhs_vf(i)%sf(j, k, & + & l))/rk_coef(s, 4) end if end do end do end do end do $:END_GPU_PARALLEL_LOOP() - !Evolve pb and mv for non-polytropic qbmm + ! Evolve pb and mv for non-polytropic qbmm if (qbmm .and. (.not. polytropic)) then $:GPU_PARALLEL_LOOP(collapse=5) do i = 1, nb @@ -594,19 +526,13 @@ contains do j = 0, m do q = 1, nnode if (s == 1 .and. nstage > 1) then - pb_ts(stor)%sf(j, k, l, q, i) = & - pb_ts(1)%sf(j, k, l, q, i) - mv_ts(stor)%sf(j, k, l, q, i) = & - mv_ts(1)%sf(j, k, l, q, i) + pb_ts(stor)%sf(j, k, l, q, i) = pb_ts(1)%sf(j, k, l, q, i) + mv_ts(stor)%sf(j, k, l, q, i) = mv_ts(1)%sf(j, k, l, q, i) end if - pb_ts(1)%sf(j, k, l, q, i) = & - (rk_coef(s, 1)*pb_ts(1)%sf(j, k, l, q, i) & - + rk_coef(s, 2)*pb_ts(stor)%sf(j, k, l, q, i) & - + rk_coef(s, 3)*dt*rhs_pb(j, k, l, q, i))/rk_coef(s, 4) - mv_ts(1)%sf(j, k, l, q, i) = & - (rk_coef(s, 1)*mv_ts(1)%sf(j, k, l, q, i) & - + rk_coef(s, 2)*mv_ts(stor)%sf(j, k, l, q, i) & - + rk_coef(s, 3)*dt*rhs_mv(j, k, l, q, i))/rk_coef(s, 4) + pb_ts(1)%sf(j, k, l, q, i) = (rk_coef(s, 1)*pb_ts(1)%sf(j, k, l, q, i) + rk_coef(s, & + & 2)*pb_ts(stor)%sf(j, k, l, q, i) + rk_coef(s, 3)*dt*rhs_pb(j, k, l, q, i))/rk_coef(s, 4) + mv_ts(1)%sf(j, k, l, q, i) = (rk_coef(s, 1)*mv_ts(1)%sf(j, k, l, q, i) + rk_coef(s, & + & 2)*mv_ts(stor)%sf(j, k, l, q, i) + rk_coef(s, 3)*dt*rhs_mv(j, k, l, q, i))/rk_coef(s, 4) end do end do end do @@ -646,7 +572,6 @@ contains call s_ibm_correct_state(q_cons_ts(1)%vf, q_prim_vf) end if end if - end do if (moving_immersed_boundary_flag) call s_wrap_periodic_ibs() @@ -668,38 +593,29 @@ contains end subroutine s_tvd_rk !> Bubble source part in Strang operator splitting scheme - !! @param stage Current time-stage + !! @param stage Current time-stage impure subroutine s_adaptive_dt_bubble(stage) integer, intent(in) :: stage + type(vector_field) :: gm_alpha_qp - type(vector_field) :: gm_alpha_qp - - call s_convert_conservative_to_primitive_variables( & - q_cons_ts(1)%vf, & - q_T_sf, & - q_prim_vf, & - idwbuff) + call s_convert_conservative_to_primitive_variables(q_cons_ts(1)%vf, q_T_sf, q_prim_vf, idwbuff) if (bubbles_euler) then - call s_compute_bubble_EE_source(q_cons_ts(1)%vf, q_prim_vf, rhs_vf, divu) call s_comp_alpha_from_n(q_cons_ts(1)%vf) - - elseif (bubbles_lagrange) then - + else if (bubbles_lagrange) then call s_populate_variables_buffers(bc_type, q_prim_vf, pb_ts(1)%sf, mv_ts(1)%sf) call s_compute_bubble_EL_dynamics(q_prim_vf, bc_type, stage) if (stage == 3) then if (lag_params%write_bubbles_stats) call s_calculate_lag_bubble_stats() if (lag_params%write_bubbles) then - $:GPU_UPDATE(host='[gas_p,gas_mv,intfc_rad,intfc_vel]') + $:GPU_UPDATE(host='[gas_p, gas_mv, intfc_rad, intfc_vel]') call s_write_lag_bubble_evol(mytime) end if if (lag_params%write_void_evol) call s_write_void_evol(mytime) end if - end if end subroutine s_adaptive_dt_bubble @@ -707,38 +623,35 @@ contains !> @brief Computes the global time step size from CFL stability constraints across all cells. impure subroutine s_compute_dt() - real(wp) :: rho !< Cell-avg. density + real(wp) :: rho !< Cell-avg. density + #:if not MFC_CASE_OPTIMIZATION and USING_AMD - real(wp), dimension(3) :: vel !< Cell-avg. velocity - real(wp), dimension(3) :: alpha !< Cell-avg. volume fraction + real(wp), dimension(3) :: vel !< Cell-avg. velocity + real(wp), dimension(3) :: alpha !< Cell-avg. volume fraction #:else - real(wp), dimension(num_vels) :: vel !< Cell-avg. velocity - real(wp), dimension(num_fluids) :: alpha !< Cell-avg. volume fraction + real(wp), dimension(num_vels) :: vel !< Cell-avg. velocity + real(wp), dimension(num_fluids) :: alpha !< Cell-avg. volume fraction #:endif - real(wp) :: vel_sum !< Cell-avg. velocity sum - real(wp) :: pres !< Cell-avg. pressure - real(wp) :: gamma !< Cell-avg. sp. heat ratio - real(wp) :: pi_inf !< Cell-avg. liquid stiffness function - real(wp) :: qv !< Cell-avg. fluid reference energy - real(wp) :: c !< Cell-avg. sound speed - real(wp) :: H !< Cell-avg. enthalpy - real(wp), dimension(2) :: Re !< Cell-avg. Reynolds numbers - type(vector_field) :: gm_alpha_qp - real(wp) :: max_dt - real(wp) :: dt_local - integer :: j, k, l !< Generic loop iterators + real(wp) :: vel_sum !< Cell-avg. velocity sum + real(wp) :: pres !< Cell-avg. pressure + real(wp) :: gamma !< Cell-avg. sp. heat ratio + real(wp) :: pi_inf !< Cell-avg. liquid stiffness function + real(wp) :: qv !< Cell-avg. fluid reference energy + real(wp) :: c !< Cell-avg. sound speed + real(wp) :: H !< Cell-avg. enthalpy + real(wp), dimension(2) :: Re !< Cell-avg. Reynolds numbers + type(vector_field) :: gm_alpha_qp + real(wp) :: max_dt + real(wp) :: dt_local + integer :: j, k, l !< Generic loop iterators if (.not. igr .or. dummy) then - call s_convert_conservative_to_primitive_variables( & - q_cons_ts(1)%vf, & - q_T_sf, & - q_prim_vf, & - idwint) + call s_convert_conservative_to_primitive_variables(q_cons_ts(1)%vf, q_T_sf, q_prim_vf, idwint) end if dt_local = huge(1.0_wp) $:GPU_PARALLEL_LOOP(collapse=3, private='[vel, alpha, Re, rho, vel_sum, pres, gamma, pi_inf, c, H, qv]', & - & reduction='[[dt_local]]', reductionOp='[min]') + & reduction='[[dt_local]]', reductionOp='[min]') do l = 0, p do k = 0, n do j = 0, m @@ -769,20 +682,17 @@ contains end subroutine s_compute_dt - !> This subroutine applies the body forces source term at each - !! Runge-Kutta stage - !! @param q_cons_vf Conservative variables - !! @param q_prim_vf_in Primitive variables - !! @param rhs_vf_in Right-hand side variables + !> This subroutine applies the body forces source term at each Runge-Kutta stage + !! @param q_cons_vf Conservative variables + !! @param q_prim_vf_in Primitive variables + !! @param rhs_vf_in Right-hand side variables subroutine s_apply_bodyforces(q_cons_vf, q_prim_vf_in, rhs_vf_in, ldt) type(scalar_field), dimension(1:sys_size), intent(inout) :: q_cons_vf - type(scalar_field), dimension(1:sys_size), intent(in) :: q_prim_vf_in + type(scalar_field), dimension(1:sys_size), intent(in) :: q_prim_vf_in type(scalar_field), dimension(1:sys_size), intent(inout) :: rhs_vf_in - - real(wp), intent(in) :: ldt !< local dt - - integer :: i, j, k, l + real(wp), intent(in) :: ldt !< local dt + integer :: i, j, k, l call nvtxStartRange("RHS-BODYFORCES") call s_compute_body_forces_rhs(q_prim_vf_in, q_cons_vf, rhs_vf_in) @@ -792,8 +702,7 @@ contains do l = 0, p do k = 0, n do j = 0, m - q_cons_vf(i)%sf(j, k, l) = q_cons_vf(i)%sf(j, k, l) + & - ldt*rhs_vf_in(i)%sf(j, k, l) + q_cons_vf(i)%sf(j, k, l) = q_cons_vf(i)%sf(j, k, l) + ldt*rhs_vf_in(i)%sf(j, k, l) end do end do end do @@ -808,8 +717,8 @@ contains subroutine s_propagate_immersed_boundaries(s) integer, intent(in) :: s - integer :: i - logical :: forces_computed + integer :: i + logical :: forces_computed call nvtxStartRange("PROPAGATE-IMMERSED-BOUNDARIES") @@ -827,12 +736,13 @@ contains if (patch_ib(i)%moving_ibm > 0) then patch_ib(i)%vel = (rk_coef(s, 1)*patch_ib(i)%step_vel + rk_coef(s, 2)*patch_ib(i)%vel)/rk_coef(s, 4) - patch_ib(i)%angular_vel = (rk_coef(s, 1)*patch_ib(i)%step_angular_vel + rk_coef(s, 2)*patch_ib(i)%angular_vel)/rk_coef(s, 4) + patch_ib(i)%angular_vel = (rk_coef(s, 1)*patch_ib(i)%step_angular_vel + rk_coef(s, & + & 2)*patch_ib(i)%angular_vel)/rk_coef(s, 4) if (patch_ib(i)%moving_ibm == 1) then ! plug in analytic velocities for 1-way coupling, if it exists @:mib_analytical() - else if (patch_ib(i)%moving_ibm == 2) then ! if we are using two-way coupling, apply force and torque + else if (patch_ib(i)%moving_ibm == 2) then ! if we are using two-way coupling, apply force and torque ! compute the force and torque on the IB from the fluid if (.not. forces_computed) then call s_compute_ib_forces(q_prim_vf, fluid_pp) @@ -843,18 +753,26 @@ contains patch_ib(i)%vel = patch_ib(i)%vel + rk_coef(s, 3)*dt*(patch_ib(i)%force/patch_ib(i)%mass)/rk_coef(s, 4) ! update the angular velocity with the torque value - patch_ib(i)%angular_vel = (patch_ib(i)%angular_vel*patch_ib(i)%moment) + (rk_coef(s, 3)*dt*patch_ib(i)%torque/rk_coef(s, 4)) ! add the torque to the angular momentum - call s_compute_moment_of_inertia(i, patch_ib(i)%angular_vel) ! update the moment of inertia to be based on the direction of the angular momentum - patch_ib(i)%angular_vel = patch_ib(i)%angular_vel/patch_ib(i)%moment ! convert back to angular velocity with the new moment of inertia + patch_ib(i)%angular_vel = (patch_ib(i)%angular_vel*patch_ib(i)%moment) + (rk_coef(s, & + & 3)*dt*patch_ib(i)%torque/rk_coef(s, 4)) ! add the torque to the angular momentum + call s_compute_moment_of_inertia(i, & + & patch_ib(i)%angular_vel) & + & ! update the moment of inertia to be based on the direction of the angular momentum + patch_ib(i)%angular_vel = patch_ib(i)%angular_vel/patch_ib(i) & + & %moment ! convert back to angular velocity with the new moment of inertia end if ! Update the angle of the IB - patch_ib(i)%angles = (rk_coef(s, 1)*patch_ib(i)%step_angles + rk_coef(s, 2)*patch_ib(i)%angles + rk_coef(s, 3)*patch_ib(i)%angular_vel*dt)/rk_coef(s, 4) + patch_ib(i)%angles = (rk_coef(s, 1)*patch_ib(i)%step_angles + rk_coef(s, 2)*patch_ib(i)%angles + rk_coef(s, & + & 3)*patch_ib(i)%angular_vel*dt)/rk_coef(s, 4) ! Update the position of the IB - patch_ib(i)%x_centroid = (rk_coef(s, 1)*patch_ib(i)%step_x_centroid + rk_coef(s, 2)*patch_ib(i)%x_centroid + rk_coef(s, 3)*patch_ib(i)%vel(1)*dt)/rk_coef(s, 4) - patch_ib(i)%y_centroid = (rk_coef(s, 1)*patch_ib(i)%step_y_centroid + rk_coef(s, 2)*patch_ib(i)%y_centroid + rk_coef(s, 3)*patch_ib(i)%vel(2)*dt)/rk_coef(s, 4) - patch_ib(i)%z_centroid = (rk_coef(s, 1)*patch_ib(i)%step_z_centroid + rk_coef(s, 2)*patch_ib(i)%z_centroid + rk_coef(s, 3)*patch_ib(i)%vel(3)*dt)/rk_coef(s, 4) + patch_ib(i)%x_centroid = (rk_coef(s, 1)*patch_ib(i)%step_x_centroid + rk_coef(s, & + & 2)*patch_ib(i)%x_centroid + rk_coef(s, 3)*patch_ib(i)%vel(1)*dt)/rk_coef(s, 4) + patch_ib(i)%y_centroid = (rk_coef(s, 1)*patch_ib(i)%step_y_centroid + rk_coef(s, & + & 2)*patch_ib(i)%y_centroid + rk_coef(s, 3)*patch_ib(i)%vel(2)*dt)/rk_coef(s, 4) + patch_ib(i)%z_centroid = (rk_coef(s, 1)*patch_ib(i)%step_z_centroid + rk_coef(s, & + & 2)*patch_ib(i)%z_centroid + rk_coef(s, 3)*patch_ib(i)%vel(3)*dt)/rk_coef(s, 4) end if end do @@ -864,14 +782,12 @@ contains end subroutine s_propagate_immersed_boundaries - !> This subroutine saves the temporary q_prim_vf vector - !! into the q_prim_ts vector that is then used in p_main - !! @param t_step current time-step + !> This subroutine saves the temporary q_prim_vf vector into the q_prim_ts vector that is then used in p_main + !! @param t_step current time-step subroutine s_time_step_cycling(t_step) integer, intent(in) :: t_step - - integer :: i, j, k, l !< Generic loop iterator + integer :: i, j, k, l !< Generic loop iterator if (t_step == t_step_start) then $:GPU_PARALLEL_LOOP(collapse=4) @@ -885,7 +801,7 @@ contains end do end do $:END_GPU_PARALLEL_LOOP() - elseif (t_step == t_step_start + 1) then + else if (t_step == t_step_start + 1) then $:GPU_PARALLEL_LOOP(collapse=4) do i = 1, sys_size do l = 0, p @@ -897,7 +813,7 @@ contains end do end do $:END_GPU_PARALLEL_LOOP() - elseif (t_step == t_step_start + 2) then + else if (t_step == t_step_start + 2) then $:GPU_PARALLEL_LOOP(collapse=4) do i = 1, sys_size do l = 0, p @@ -909,7 +825,7 @@ contains end do end do $:END_GPU_PARALLEL_LOOP() - elseif (t_step == t_step_start + 3) then + else if (t_step == t_step_start + 3) then $:GPU_PARALLEL_LOOP(collapse=4) do i = 1, sys_size do l = 0, p @@ -921,7 +837,7 @@ contains end do end do $:END_GPU_PARALLEL_LOOP() - else ! All other timesteps + else ! All other timesteps $:GPU_PARALLEL_LOOP(collapse=4) do i = 1, sys_size do l = 0, p @@ -942,12 +858,13 @@ contains !> Module deallocation and/or disassociation procedures impure subroutine s_finalize_time_steppers_module + #ifdef FRONTIER_UNIFIED use hipfort use hipfort_hipmalloc use hipfort_check #endif - integer :: i, j !< Generic loop iterators + integer :: i, j !< Generic loop iterators ! Deallocating the cell-average conservative variables #if defined(__NVCOMPILER_GPU_UNIFIED_MEM) diff --git a/src/simulation/m_viscous.fpp b/src/simulation/m_viscous.fpp index 9c6e4ad4d8..50aa935357 100644 --- a/src/simulation/m_viscous.fpp +++ b/src/simulation/m_viscous.fpp @@ -7,31 +7,21 @@ !> @brief Computes viscous stress tensors and diffusive flux contributions for the Navier--Stokes equations module m_viscous - use m_derived_types !< Definitions of the derived types - - use m_global_parameters !< Definitions of the global parameters - + use m_derived_types !< Definitions of the derived types + use m_global_parameters !< Definitions of the global parameters use m_weno - - use m_muscl !< Monotonic Upstream-centered (MUSCL) - !! schemes for conservation laws - + use m_muscl !< Monotonic Upstream-centered (MUSCL) schemes for conservation laws use m_helper - use m_finite_differences - private; public s_get_viscous, & - s_compute_viscous_stress_cylindrical_boundary, & - s_initialize_viscous_module, & - s_reconstruct_cell_boundary_values_visc_deriv, & - s_finalize_viscous_module, & - s_compute_viscous_stress_tensor + private; public s_get_viscous, s_compute_viscous_stress_cylindrical_boundary, s_initialize_viscous_module, & + & s_reconstruct_cell_boundary_values_visc_deriv, s_finalize_viscous_module, s_compute_viscous_stress_tensor type(int_bounds_info) :: iv type(int_bounds_info) :: is1_viscous, is2_viscous, is3_viscous - $:GPU_DECLARE(create='[is1_viscous,is2_viscous,is3_viscous,iv]') + $:GPU_DECLARE(create='[is1_viscous, is2_viscous, is3_viscous, iv]') - real(wp), allocatable, dimension(:, :) :: Res_viscous + real(wp), allocatable, dimension(:,:) :: Res_viscous $:GPU_DECLARE(create='[Res_viscous]') contains @@ -39,7 +29,7 @@ contains !> @brief Allocates and populates the viscous Reynolds number arrays and transfers data to the GPU. impure subroutine s_initialize_viscous_module - integer :: i, j !< generic loop iterators + integer :: i, j !< generic loop iterators @:ALLOCATE(Res_viscous(1:2, 1:Re_size_max)) @@ -48,44 +38,38 @@ contains Res_viscous(i, j) = fluid_pp(Re_idx(i, j))%Re(i) end do end do - $:GPU_UPDATE(device='[Res_viscous,Re_idx,Re_size]') - $:GPU_ENTER_DATA(copyin='[is1_viscous,is2_viscous,is3_viscous,iv]') + $:GPU_UPDATE(device='[Res_viscous, Re_idx, Re_size]') + $:GPU_ENTER_DATA(copyin='[is1_viscous, is2_viscous, is3_viscous, iv]') end subroutine s_initialize_viscous_module !> The purpose of this subroutine is to compute the viscous - ! stress tensor for the cells directly next to the axis in - ! cylindrical coordinates. This is necessary to avoid the - ! 1/r singularity that arises at the cell boundary coinciding - ! with the axis, i.e., y_cb(-1) = 0. - ! @param q_prim_vf Cell-average primitive variables - ! @param grad_x_vf Cell-average primitive variable derivatives, x-dir - ! @param grad_y_vf Cell-average primitive variable derivatives, y-dir - ! @param grad_z_vf Cell-average primitive variable derivatives, z-dir - subroutine s_compute_viscous_stress_cylindrical_boundary(q_prim_vf, grad_x_vf, grad_y_vf, grad_z_vf, & - tau_Re_vf, & - ix, iy, iz) + ! stress tensor for the cells directly next to the axis in cylindrical coordinates. This is necessary to avoid the 1/r + ! singularity that arises at the cell boundary coinciding with the axis, i.e., y_cb(-1) = 0. @param q_prim_vf Cell-average + ! primitive variables @param grad_x_vf Cell-average primitive variable derivatives, x-dir @param grad_y_vf Cell-average + ! primitive variable derivatives, y-dir @param grad_z_vf Cell-average primitive variable derivatives, z-dir + subroutine s_compute_viscous_stress_cylindrical_boundary(q_prim_vf, grad_x_vf, grad_y_vf, grad_z_vf, tau_Re_vf, ix, iy, iz) type(scalar_field), dimension(sys_size), intent(in) :: q_prim_vf type(scalar_field), dimension(num_dims), intent(in) :: grad_x_vf, grad_y_vf, grad_z_vf type(scalar_field), dimension(1:sys_size), intent(inout) :: tau_Re_vf type(int_bounds_info), intent(in) :: ix, iy, iz - real(wp) :: rho_visc, gamma_visc, pi_inf_visc, alpha_visc_sum !< Mixture variables real(wp), dimension(2) :: Re_visc + #:if not MFC_CASE_OPTIMIZATION and USING_AMD - real(wp), dimension(3) :: alpha_visc, alpha_rho_visc + real(wp), dimension(3) :: alpha_visc, alpha_rho_visc real(wp), dimension(3, 3) :: tau_Re #:else - real(wp), dimension(num_fluids) :: alpha_visc, alpha_rho_visc + real(wp), dimension(num_fluids) :: alpha_visc, alpha_rho_visc real(wp), dimension(num_dims, num_dims) :: tau_Re #:endif - integer :: i, j, k, l, q !< Generic loop iterator + integer :: i, j, k, l, q !< Generic loop iterator is1_viscous = ix; is2_viscous = iy; is3_viscous = iz - $:GPU_UPDATE(device='[is1_viscous,is2_viscous,is3_viscous]') + $:GPU_UPDATE(device='[is1_viscous, is2_viscous, is3_viscous]') $:GPU_PARALLEL_LOOP(collapse=3) do l = is3_viscous%beg, is3_viscous%end @@ -101,12 +85,12 @@ contains $:END_GPU_PARALLEL_LOOP() #:if not MFC_CASE_OPTIMIZATION or num_dims > 1 - if (shear_stress) then ! Shear stresses - $:GPU_PARALLEL_LOOP(collapse=3, private='[i,j,k,l,q,rho_visc, gamma_visc, pi_inf_visc, alpha_visc_sum, alpha_visc, alpha_rho_visc, Re_visc, tau_Re]') + if (shear_stress) then ! Shear stresses + $:GPU_PARALLEL_LOOP(collapse=3, private='[i, j, k, l, q, rho_visc, gamma_visc, pi_inf_visc, alpha_visc_sum, & + & alpha_visc, alpha_rho_visc, Re_visc, tau_Re]') do l = is3_viscous%beg, is3_viscous%end do k = -1, 1 do j = is1_viscous%beg, is1_viscous%end - $:GPU_LOOP(parallelism='[seq]') do i = 1, num_fluids alpha_rho_visc(i) = q_prim_vf(i)%sf(j, k, l) @@ -157,7 +141,6 @@ contains end do alpha_visc = alpha_visc/max(alpha_visc_sum, sgm_eps) - end if $:GPU_LOOP(parallelism='[seq]') @@ -175,33 +158,24 @@ contains if (Re_size(i) > 0) Re_visc(i) = 0._wp $:GPU_LOOP(parallelism='[seq]') do q = 1, Re_size(i) - Re_visc(i) = alpha_visc(Re_idx(i, q))/Res_viscous(i, q) & - + Re_visc(i) + Re_visc(i) = alpha_visc(Re_idx(i, q))/Res_viscous(i, q) + Re_visc(i) end do Re_visc(i) = 1._wp/max(Re_visc(i), sgm_eps) - end do end if end if - tau_Re(2, 1) = (grad_y_vf(1)%sf(j, k, l) + & - grad_x_vf(2)%sf(j, k, l))/ & - Re_visc(1) + tau_Re(2, 1) = (grad_y_vf(1)%sf(j, k, l) + grad_x_vf(2)%sf(j, k, l))/Re_visc(1) - tau_Re(2, 2) = (4._wp*grad_y_vf(2)%sf(j, k, l) & - - 2._wp*grad_x_vf(1)%sf(j, k, l) & - - 2._wp*q_prim_vf(momxb + 1)%sf(j, k, l)/y_cc(k))/ & - (3._wp*Re_visc(1)) + tau_Re(2, 2) = (4._wp*grad_y_vf(2)%sf(j, k, l) - 2._wp*grad_x_vf(1)%sf(j, k, & + & l) - 2._wp*q_prim_vf(momxb + 1)%sf(j, k, l)/y_cc(k))/(3._wp*Re_visc(1)) $:GPU_LOOP(parallelism='[seq]') do i = 1, 2 - tau_Re_vf(contxe + i)%sf(j, k, l) = & - tau_Re_vf(contxe + i)%sf(j, k, l) - & - tau_Re(2, i) + tau_Re_vf(contxe + i)%sf(j, k, l) = tau_Re_vf(contxe + i)%sf(j, k, l) - tau_Re(2, i) - tau_Re_vf(E_idx)%sf(j, k, l) = & - tau_Re_vf(E_idx)%sf(j, k, l) - & - q_prim_vf(contxe + i)%sf(j, k, l)*tau_Re(2, i) + tau_Re_vf(E_idx)%sf(j, k, l) = tau_Re_vf(E_idx)%sf(j, k, l) - q_prim_vf(contxe + i)%sf(j, k, & + & l)*tau_Re(2, i) end do end do end do @@ -211,12 +185,12 @@ contains #:endif #:if not MFC_CASE_OPTIMIZATION or num_dims > 1 - if (bulk_stress) then ! Bulk stresses - $:GPU_PARALLEL_LOOP(collapse=3, private='[i,j,k,l,q,rho_visc, gamma_visc, pi_inf_visc, alpha_visc_sum, alpha_visc, alpha_rho_visc, Re_visc, tau_Re]') + if (bulk_stress) then ! Bulk stresses + $:GPU_PARALLEL_LOOP(collapse=3, private='[i, j, k, l, q, rho_visc, gamma_visc, pi_inf_visc, alpha_visc_sum, & + & alpha_visc, alpha_rho_visc, Re_visc, tau_Re]') do l = is3_viscous%beg, is3_viscous%end do k = -1, 1 do j = is1_viscous%beg, is1_viscous%end - $:GPU_LOOP(parallelism='[seq]') do i = 1, num_fluids alpha_rho_visc(i) = q_prim_vf(i)%sf(j, k, l) @@ -267,7 +241,6 @@ contains end do alpha_visc = alpha_visc/max(alpha_visc_sum, sgm_eps) - end if $:GPU_LOOP(parallelism='[seq]') @@ -285,29 +258,21 @@ contains if (Re_size(i) > 0) Re_visc(i) = 0._wp $:GPU_LOOP(parallelism='[seq]') do q = 1, Re_size(i) - Re_visc(i) = alpha_visc(Re_idx(i, q))/Res_viscous(i, q) & - + Re_visc(i) + Re_visc(i) = alpha_visc(Re_idx(i, q))/Res_viscous(i, q) + Re_visc(i) end do Re_visc(i) = 1._wp/max(Re_visc(i), sgm_eps) - end do end if end if - tau_Re(2, 2) = (grad_x_vf(1)%sf(j, k, l) + & - grad_y_vf(2)%sf(j, k, l) + & - q_prim_vf(momxb + 1)%sf(j, k, l)/y_cc(k))/ & - Re_visc(2) - - tau_Re_vf(momxb + 1)%sf(j, k, l) = & - tau_Re_vf(momxb + 1)%sf(j, k, l) - & - tau_Re(2, 2) + tau_Re(2, 2) = (grad_x_vf(1)%sf(j, k, l) + grad_y_vf(2)%sf(j, k, l) + q_prim_vf(momxb + 1)%sf(j, k, & + & l)/y_cc(k))/Re_visc(2) - tau_Re_vf(E_idx)%sf(j, k, l) = & - tau_Re_vf(E_idx)%sf(j, k, l) - & - q_prim_vf(momxb + 1)%sf(j, k, l)*tau_Re(2, 2) + tau_Re_vf(momxb + 1)%sf(j, k, l) = tau_Re_vf(momxb + 1)%sf(j, k, l) - tau_Re(2, 2) + tau_Re_vf(E_idx)%sf(j, k, l) = tau_Re_vf(E_idx)%sf(j, k, l) - q_prim_vf(momxb + 1)%sf(j, k, & + & l)*tau_Re(2, 2) end do end do end do @@ -317,13 +282,12 @@ contains if (p == 0) return #:if not MFC_CASE_OPTIMIZATION or num_dims > 2 - - if (shear_stress) then ! Shear stresses - $:GPU_PARALLEL_LOOP(collapse=3, private='[i,j,k,l,q,rho_visc, gamma_visc, pi_inf_visc, alpha_visc_sum, alpha_visc, alpha_rho_visc, Re_visc, tau_Re]') + if (shear_stress) then ! Shear stresses + $:GPU_PARALLEL_LOOP(collapse=3, private='[i, j, k, l, q, rho_visc, gamma_visc, pi_inf_visc, alpha_visc_sum, & + & alpha_visc, alpha_rho_visc, Re_visc, tau_Re]') do l = is3_viscous%beg, is3_viscous%end do k = -1, 1 do j = is1_viscous%beg, is1_viscous%end - $:GPU_LOOP(parallelism='[seq]') do i = 1, num_fluids alpha_rho_visc(i) = q_prim_vf(i)%sf(j, k, l) @@ -374,7 +338,6 @@ contains end do alpha_visc = alpha_visc/max(alpha_visc_sum, sgm_eps) - end if $:GPU_LOOP(parallelism='[seq]') @@ -392,47 +355,38 @@ contains if (Re_size(i) > 0) Re_visc(i) = 0._wp $:GPU_LOOP(parallelism='[seq]') do q = 1, Re_size(i) - Re_visc(i) = alpha_visc(Re_idx(i, q))/Res_viscous(i, q) & - + Re_visc(i) + Re_visc(i) = alpha_visc(Re_idx(i, q))/Res_viscous(i, q) + Re_visc(i) end do Re_visc(i) = 1._wp/max(Re_visc(i), sgm_eps) - end do end if end if - tau_Re(2, 2) = -(2._wp/3._wp)*grad_z_vf(3)%sf(j, k, l)/y_cc(k)/ & - Re_visc(1) + tau_Re(2, 2) = -(2._wp/3._wp)*grad_z_vf(3)%sf(j, k, l)/y_cc(k)/Re_visc(1) - tau_Re(2, 3) = ((grad_z_vf(2)%sf(j, k, l) - & - q_prim_vf(momxe)%sf(j, k, l))/ & - y_cc(k) + grad_y_vf(3)%sf(j, k, l))/ & - Re_visc(1) + tau_Re(2, 3) = ((grad_z_vf(2)%sf(j, k, l) - q_prim_vf(momxe)%sf(j, k, & + & l))/y_cc(k) + grad_y_vf(3)%sf(j, k, l))/Re_visc(1) $:GPU_LOOP(parallelism='[seq]') do i = 2, 3 - tau_Re_vf(contxe + i)%sf(j, k, l) = & - tau_Re_vf(contxe + i)%sf(j, k, l) - & - tau_Re(2, i) + tau_Re_vf(contxe + i)%sf(j, k, l) = tau_Re_vf(contxe + i)%sf(j, k, l) - tau_Re(2, i) - tau_Re_vf(E_idx)%sf(j, k, l) = & - tau_Re_vf(E_idx)%sf(j, k, l) - & - q_prim_vf(contxe + i)%sf(j, k, l)*tau_Re(2, i) + tau_Re_vf(E_idx)%sf(j, k, l) = tau_Re_vf(E_idx)%sf(j, k, l) - q_prim_vf(contxe + i)%sf(j, k, & + & l)*tau_Re(2, i) end do - end do end do end do $:END_GPU_PARALLEL_LOOP() end if - if (bulk_stress) then ! Bulk stresses - $:GPU_PARALLEL_LOOP(collapse=3, private='[i,j,k,l,q,rho_visc, gamma_visc, pi_inf_visc, alpha_visc_sum, alpha_visc, alpha_rho_visc, Re_visc, tau_Re]') + if (bulk_stress) then ! Bulk stresses + $:GPU_PARALLEL_LOOP(collapse=3, private='[i, j, k, l, q, rho_visc, gamma_visc, pi_inf_visc, alpha_visc_sum, & + & alpha_visc, alpha_rho_visc, Re_visc, tau_Re]') do l = is3_viscous%beg, is3_viscous%end do k = -1, 1 do j = is1_viscous%beg, is1_viscous%end - $:GPU_LOOP(parallelism='[seq]') do i = 1, num_fluids alpha_rho_visc(i) = q_prim_vf(i)%sf(j, k, l) @@ -483,7 +437,6 @@ contains end do alpha_visc = alpha_visc/max(alpha_visc_sum, sgm_eps) - end if $:GPU_LOOP(parallelism='[seq]') @@ -501,133 +454,101 @@ contains if (Re_size(i) > 0) Re_visc(i) = 0._wp $:GPU_LOOP(parallelism='[seq]') do q = 1, Re_size(i) - Re_visc(i) = alpha_visc(Re_idx(i, q))/Res_viscous(i, q) & - + Re_visc(i) + Re_visc(i) = alpha_visc(Re_idx(i, q))/Res_viscous(i, q) + Re_visc(i) end do Re_visc(i) = 1._wp/max(Re_visc(i), sgm_eps) - end do end if end if - tau_Re(2, 2) = grad_z_vf(3)%sf(j, k, l)/y_cc(k)/ & - Re_visc(2) + tau_Re(2, 2) = grad_z_vf(3)%sf(j, k, l)/y_cc(k)/Re_visc(2) - tau_Re_vf(momxb + 1)%sf(j, k, l) = & - tau_Re_vf(momxb + 1)%sf(j, k, l) - & - tau_Re(2, 2) - - tau_Re_vf(E_idx)%sf(j, k, l) = & - tau_Re_vf(E_idx)%sf(j, k, l) - & - q_prim_vf(momxb + 1)%sf(j, k, l)*tau_Re(2, 2) + tau_Re_vf(momxb + 1)%sf(j, k, l) = tau_Re_vf(momxb + 1)%sf(j, k, l) - tau_Re(2, 2) + tau_Re_vf(E_idx)%sf(j, k, l) = tau_Re_vf(E_idx)%sf(j, k, l) - q_prim_vf(momxb + 1)%sf(j, k, & + & l)*tau_Re(2, 2) end do end do end do $:END_GPU_PARALLEL_LOOP() end if #:endif + end subroutine s_compute_viscous_stress_cylindrical_boundary - !> Computes viscous terms - !! @param qL_prim_rsx_vf Left reconstructed primitive variables in x - !! @param qL_prim_rsy_vf Left reconstructed primitive variables in y - !! @param qL_prim_rsz_vf Left reconstructed primitive variables in z - !! @param dqL_prim_dx_n Left primitive x-derivative - !! @param dqL_prim_dy_n Left primitive y-derivative - !! @param dqL_prim_dz_n Left primitive z-derivative - !! @param qL_prim Left cell-boundary primitive variables - !! @param qR_prim_rsx_vf Right reconstructed primitive variables in x - !! @param qR_prim_rsy_vf Right reconstructed primitive variables in y - !! @param qR_prim_rsz_vf Right reconstructed primitive variables in z - !! @param dqR_prim_dx_n Right primitive x-derivative - !! @param dqR_prim_dy_n Right primitive y-derivative - !! @param dqR_prim_dz_n Right primitive z-derivative - !! @param qR_prim Right cell-boundary primitive variables - !! @param q_prim_qp Cell-averaged primitive variables - !! @param dq_prim_dx_qp Cell-averaged primitive x-derivative - !! @param dq_prim_dy_qp Cell-averaged primitive y-derivative - !! @param dq_prim_dz_qp Cell-averaged primitive z-derivative - !! @param ix Index bounds in the x-direction - !! @param iy Index bounds in the y-direction - !! @param iz Index bounds in the z-direction - subroutine s_get_viscous(qL_prim_rsx_vf, qL_prim_rsy_vf, qL_prim_rsz_vf, & - dqL_prim_dx_n, dqL_prim_dy_n, dqL_prim_dz_n, & - qL_prim, & - qR_prim_rsx_vf, qR_prim_rsy_vf, qR_prim_rsz_vf, & - dqR_prim_dx_n, dqR_prim_dy_n, dqR_prim_dz_n, & - qR_prim, & - q_prim_qp, & - dq_prim_dx_qp, dq_prim_dy_qp, dq_prim_dz_qp, & - ix, iy, iz) - - real(wp), dimension(idwbuff(1)%beg:, idwbuff(2)%beg:, idwbuff(3)%beg:, 1:), & - intent(inout) :: qL_prim_rsx_vf, qR_prim_rsx_vf, & - qL_prim_rsy_vf, qR_prim_rsy_vf, & - qL_prim_rsz_vf, qR_prim_rsz_vf - - type(vector_field), dimension(num_dims), intent(inout) :: qL_prim, qR_prim - - type(vector_field), intent(in) :: q_prim_qp - - type(vector_field), dimension(1:num_dims), & - intent(inout) :: dqL_prim_dx_n, dqR_prim_dx_n, & - dqL_prim_dy_n, dqR_prim_dy_n, & - dqL_prim_dz_n, dqR_prim_dz_n + !> Computes viscous terms + !! @param qL_prim_rsx_vf Left reconstructed primitive variables in x + !! @param qL_prim_rsy_vf Left reconstructed primitive variables in y + !! @param qL_prim_rsz_vf Left reconstructed primitive variables in z + !! @param dqL_prim_dx_n Left primitive x-derivative + !! @param dqL_prim_dy_n Left primitive y-derivative + !! @param dqL_prim_dz_n Left primitive z-derivative + !! @param qL_prim Left cell-boundary primitive variables + !! @param qR_prim_rsx_vf Right reconstructed primitive variables in x + !! @param qR_prim_rsy_vf Right reconstructed primitive variables in y + !! @param qR_prim_rsz_vf Right reconstructed primitive variables in z + !! @param dqR_prim_dx_n Right primitive x-derivative + !! @param dqR_prim_dy_n Right primitive y-derivative + !! @param dqR_prim_dz_n Right primitive z-derivative + !! @param qR_prim Right cell-boundary primitive variables + !! @param q_prim_qp Cell-averaged primitive variables + !! @param dq_prim_dx_qp Cell-averaged primitive x-derivative + !! @param dq_prim_dy_qp Cell-averaged primitive y-derivative + !! @param dq_prim_dz_qp Cell-averaged primitive z-derivative + !! @param ix Index bounds in the x-direction + !! @param iy Index bounds in the y-direction + !! @param iz Index bounds in the z-direction + subroutine s_get_viscous(qL_prim_rsx_vf, qL_prim_rsy_vf, qL_prim_rsz_vf, dqL_prim_dx_n, dqL_prim_dy_n, dqL_prim_dz_n, & + & qL_prim, qR_prim_rsx_vf, qR_prim_rsy_vf, qR_prim_rsz_vf, dqR_prim_dx_n, dqR_prim_dy_n, & + & dqR_prim_dz_n, qR_prim, q_prim_qp, dq_prim_dx_qp, dq_prim_dy_qp, dq_prim_dz_qp, ix, iy, iz) + + real(wp), dimension(idwbuff(1)%beg:,idwbuff(2)%beg:,idwbuff(3)%beg:,1:), intent(inout) :: qL_prim_rsx_vf, qR_prim_rsx_vf, & + & qL_prim_rsy_vf, qR_prim_rsy_vf, qL_prim_rsz_vf, qR_prim_rsz_vf + + type(vector_field), dimension(num_dims), intent(inout) :: qL_prim, qR_prim + type(vector_field), intent(in) :: q_prim_qp + type(vector_field), dimension(1:num_dims), intent(inout) :: dqL_prim_dx_n, dqR_prim_dx_n, dqL_prim_dy_n, dqR_prim_dy_n, & + & dqL_prim_dz_n, dqR_prim_dz_n type(vector_field), dimension(1), intent(inout) :: dq_prim_dx_qp, dq_prim_dy_qp, dq_prim_dz_qp - type(int_bounds_info), intent(in) :: ix, iy, iz - - integer :: i, j, k, l + type(int_bounds_info), intent(in) :: ix, iy, iz + integer :: i, j, k, l do i = 1, num_dims - iv%beg = mom_idx%beg; iv%end = mom_idx%end $:GPU_UPDATE(device='[iv]') - call s_reconstruct_cell_boundary_values_visc( & - q_prim_qp%vf(iv%beg:iv%end), & - qL_prim_rsx_vf, qL_prim_rsy_vf, qL_prim_rsz_vf, & - qR_prim_rsx_vf, qR_prim_rsy_vf, qR_prim_rsz_vf, & - i, qL_prim(i)%vf(iv%beg:iv%end), qR_prim(i)%vf(iv%beg:iv%end), & - ix, iy, iz) + call s_reconstruct_cell_boundary_values_visc(q_prim_qp%vf(iv%beg:iv%end), qL_prim_rsx_vf, qL_prim_rsy_vf, & + & qL_prim_rsz_vf, qR_prim_rsx_vf, qR_prim_rsy_vf, qR_prim_rsz_vf, i, qL_prim(i)%vf(iv%beg:iv%end), & + & qR_prim(i)%vf(iv%beg:iv%end), ix, iy, iz) end do if (weno_Re_flux) then - ! Compute velocity gradient at cell centers using scalar - ! divergence theorem + ! Compute velocity gradient at cell centers using scalar divergence theorem do i = 1, num_dims if (i == 1) then - call s_apply_scalar_divergence_theorem( & - qL_prim(i)%vf(iv%beg:iv%end), & - qR_prim(i)%vf(iv%beg:iv%end), & - dq_prim_dx_qp(1)%vf(iv%beg:iv%end), i, & - ix, iy, iz, iv, dx, m, buff_size) - elseif (i == 2) then - call s_apply_scalar_divergence_theorem( & - qL_prim(i)%vf(iv%beg:iv%end), & - qR_prim(i)%vf(iv%beg:iv%end), & - dq_prim_dy_qp(1)%vf(iv%beg:iv%end), i, & - ix, iy, iz, iv, dy, n, buff_size) + call s_apply_scalar_divergence_theorem(qL_prim(i)%vf(iv%beg:iv%end), qR_prim(i)%vf(iv%beg:iv%end), & + & dq_prim_dx_qp(1)%vf(iv%beg:iv%end), i, ix, iy, iz, iv, dx, m, & + & buff_size) + else if (i == 2) then + call s_apply_scalar_divergence_theorem(qL_prim(i)%vf(iv%beg:iv%end), qR_prim(i)%vf(iv%beg:iv%end), & + & dq_prim_dy_qp(1)%vf(iv%beg:iv%end), i, ix, iy, iz, iv, dy, n, & + & buff_size) else - call s_apply_scalar_divergence_theorem( & - qL_prim(i)%vf(iv%beg:iv%end), & - qR_prim(i)%vf(iv%beg:iv%end), & - dq_prim_dz_qp(1)%vf(iv%beg:iv%end), i, & - ix, iy, iz, iv, dz, p, buff_size) + call s_apply_scalar_divergence_theorem(qL_prim(i)%vf(iv%beg:iv%end), qR_prim(i)%vf(iv%beg:iv%end), & + & dq_prim_dz_qp(1)%vf(iv%beg:iv%end), i, ix, iy, iz, iv, dz, p, & + & buff_size) end if end do - - else ! Compute velocity gradient at cell centers using finite differences - + else ! Compute velocity gradient at cell centers using finite differences iv%beg = mom_idx%beg; iv%end = mom_idx%end $:GPU_UPDATE(device='[iv]') is1_viscous = ix; is2_viscous = iy; is3_viscous = iz - $:GPU_UPDATE(device='[is1_viscous,is2_viscous,is3_viscous]') + $:GPU_UPDATE(device='[is1_viscous, is2_viscous, is3_viscous]') $:GPU_PARALLEL_LOOP(collapse=3) do l = is3_viscous%beg, is3_viscous%end @@ -635,10 +556,8 @@ contains do j = is1_viscous%beg + 1, is1_viscous%end $:GPU_LOOP(parallelism='[seq]') do i = iv%beg, iv%end - dqL_prim_dx_n(1)%vf(i)%sf(j, k, l) = & - (q_prim_qp%vf(i)%sf(j, k, l) - & - q_prim_qp%vf(i)%sf(j - 1, k, l))/ & - (x_cc(j) - x_cc(j - 1)) + dqL_prim_dx_n(1)%vf(i)%sf(j, k, l) = (q_prim_qp%vf(i)%sf(j, k, l) - q_prim_qp%vf(i)%sf(j - 1, k, & + & l))/(x_cc(j) - x_cc(j - 1)) end do end do end do @@ -651,10 +570,8 @@ contains do j = is1_viscous%beg, is1_viscous%end - 1 $:GPU_LOOP(parallelism='[seq]') do i = iv%beg, iv%end - dqR_prim_dx_n(1)%vf(i)%sf(j, k, l) = & - (q_prim_qp%vf(i)%sf(j + 1, k, l) - & - q_prim_qp%vf(i)%sf(j, k, l))/ & - (x_cc(j + 1) - x_cc(j)) + dqR_prim_dx_n(1)%vf(i)%sf(j, k, l) = (q_prim_qp%vf(i)%sf(j + 1, k, l) - q_prim_qp%vf(i)%sf(j, k, & + & l))/(x_cc(j + 1) - x_cc(j)) end do end do end do @@ -662,7 +579,6 @@ contains $:END_GPU_PARALLEL_LOOP() if (n > 0) then - #:if not MFC_CASE_OPTIMIZATION or num_dims > 1 $:GPU_PARALLEL_LOOP(collapse=3) do l = is3_viscous%beg, is3_viscous%end @@ -670,10 +586,8 @@ contains do k = is1_viscous%beg, is1_viscous%end $:GPU_LOOP(parallelism='[seq]') do i = iv%beg, iv%end - dqL_prim_dy_n(2)%vf(i)%sf(k, j, l) = & - (q_prim_qp%vf(i)%sf(k, j, l) - & - q_prim_qp%vf(i)%sf(k, j - 1, l))/ & - (y_cc(j) - y_cc(j - 1)) + dqL_prim_dy_n(2)%vf(i)%sf(k, j, l) = (q_prim_qp%vf(i)%sf(k, j, l) - q_prim_qp%vf(i)%sf(k, & + & j - 1, l))/(y_cc(j) - y_cc(j - 1)) end do end do end do @@ -686,10 +600,8 @@ contains do k = is1_viscous%beg, is1_viscous%end $:GPU_LOOP(parallelism='[seq]') do i = iv%beg, iv%end - dqR_prim_dy_n(2)%vf(i)%sf(k, j, l) = & - (q_prim_qp%vf(i)%sf(k, j + 1, l) - & - q_prim_qp%vf(i)%sf(k, j, l))/ & - (y_cc(j + 1) - y_cc(j)) + dqR_prim_dy_n(2)%vf(i)%sf(k, j, l) = (q_prim_qp%vf(i)%sf(k, j + 1, l) - q_prim_qp%vf(i)%sf(k, & + & j, l))/(y_cc(j + 1) - y_cc(j)) end do end do end do @@ -702,14 +614,11 @@ contains do k = is1_viscous%beg + 1, is1_viscous%end - 1 $:GPU_LOOP(parallelism='[seq]') do i = iv%beg, iv%end - dqL_prim_dx_n(2)%vf(i)%sf(k, j, l) = & - (dqL_prim_dx_n(1)%vf(i)%sf(k, j, l) + & - dqR_prim_dx_n(1)%vf(i)%sf(k, j, l) + & - dqL_prim_dx_n(1)%vf(i)%sf(k, j - 1, l) + & - dqR_prim_dx_n(1)%vf(i)%sf(k, j - 1, l)) - - dqL_prim_dx_n(2)%vf(i)%sf(k, j, l) = 25.e-2_wp* & - dqL_prim_dx_n(2)%vf(i)%sf(k, j, l) + dqL_prim_dx_n(2)%vf(i)%sf(k, j, l) = (dqL_prim_dx_n(1)%vf(i)%sf(k, j, & + & l) + dqR_prim_dx_n(1)%vf(i)%sf(k, j, l) + dqL_prim_dx_n(1)%vf(i)%sf(k, j - 1, & + & l) + dqR_prim_dx_n(1)%vf(i)%sf(k, j - 1, l)) + + dqL_prim_dx_n(2)%vf(i)%sf(k, j, l) = 25.e-2_wp*dqL_prim_dx_n(2)%vf(i)%sf(k, j, l) end do end do end do @@ -722,15 +631,11 @@ contains do k = is1_viscous%beg + 1, is1_viscous%end - 1 $:GPU_LOOP(parallelism='[seq]') do i = iv%beg, iv%end - dqR_prim_dx_n(2)%vf(i)%sf(k, j, l) = & - (dqL_prim_dx_n(1)%vf(i)%sf(k, j + 1, l) + & - dqR_prim_dx_n(1)%vf(i)%sf(k, j + 1, l) + & - dqL_prim_dx_n(1)%vf(i)%sf(k, j, l) + & - dqR_prim_dx_n(1)%vf(i)%sf(k, j, l)) - - dqR_prim_dx_n(2)%vf(i)%sf(k, j, l) = 25.e-2_wp* & - dqR_prim_dx_n(2)%vf(i)%sf(k, j, l) + dqR_prim_dx_n(2)%vf(i)%sf(k, j, l) = (dqL_prim_dx_n(1)%vf(i)%sf(k, j + 1, & + & l) + dqR_prim_dx_n(1)%vf(i)%sf(k, j + 1, l) + dqL_prim_dx_n(1)%vf(i)%sf(k, j, & + & l) + dqR_prim_dx_n(1)%vf(i)%sf(k, j, l)) + dqR_prim_dx_n(2)%vf(i)%sf(k, j, l) = 25.e-2_wp*dqR_prim_dx_n(2)%vf(i)%sf(k, j, l) end do end do end do @@ -743,15 +648,11 @@ contains do j = is1_viscous%beg + 1, is1_viscous%end $:GPU_LOOP(parallelism='[seq]') do i = iv%beg, iv%end - dqL_prim_dy_n(1)%vf(i)%sf(j, k, l) = & - (dqL_prim_dy_n(2)%vf(i)%sf(j, k, l) + & - dqR_prim_dy_n(2)%vf(i)%sf(j, k, l) + & - dqL_prim_dy_n(2)%vf(i)%sf(j - 1, k, l) + & - dqR_prim_dy_n(2)%vf(i)%sf(j - 1, k, l)) - - dqL_prim_dy_n(1)%vf(i)%sf(j, k, l) = 25.e-2_wp* & - dqL_prim_dy_n(1)%vf(i)%sf(j, k, l) + dqL_prim_dy_n(1)%vf(i)%sf(j, k, l) = (dqL_prim_dy_n(2)%vf(i)%sf(j, k, & + & l) + dqR_prim_dy_n(2)%vf(i)%sf(j, k, l) + dqL_prim_dy_n(2)%vf(i)%sf(j - 1, k, & + & l) + dqR_prim_dy_n(2)%vf(i)%sf(j - 1, k, l)) + dqL_prim_dy_n(1)%vf(i)%sf(j, k, l) = 25.e-2_wp*dqL_prim_dy_n(1)%vf(i)%sf(j, k, l) end do end do end do @@ -764,21 +665,16 @@ contains do j = is1_viscous%beg, is1_viscous%end - 1 $:GPU_LOOP(parallelism='[seq]') do i = iv%beg, iv%end - dqR_prim_dy_n(1)%vf(i)%sf(j, k, l) = & - (dqL_prim_dy_n(2)%vf(i)%sf(j + 1, k, l) + & - dqR_prim_dy_n(2)%vf(i)%sf(j + 1, k, l) + & - dqL_prim_dy_n(2)%vf(i)%sf(j, k, l) + & - dqR_prim_dy_n(2)%vf(i)%sf(j, k, l)) - - dqR_prim_dy_n(1)%vf(i)%sf(j, k, l) = 25.e-2_wp* & - dqR_prim_dy_n(1)%vf(i)%sf(j, k, l) + dqR_prim_dy_n(1)%vf(i)%sf(j, k, l) = (dqL_prim_dy_n(2)%vf(i)%sf(j + 1, k, & + & l) + dqR_prim_dy_n(2)%vf(i)%sf(j + 1, k, l) + dqL_prim_dy_n(2)%vf(i)%sf(j, k, & + & l) + dqR_prim_dy_n(2)%vf(i)%sf(j, k, l)) + dqR_prim_dy_n(1)%vf(i)%sf(j, k, l) = 25.e-2_wp*dqR_prim_dy_n(1)%vf(i)%sf(j, k, l) end do end do end do end do $:END_GPU_PARALLEL_LOOP() - #:endif if (p > 0) then @@ -789,11 +685,8 @@ contains do k = is1_viscous%beg, is1_viscous%end $:GPU_LOOP(parallelism='[seq]') do i = iv%beg, iv%end - - dqL_prim_dz_n(3)%vf(i)%sf(k, l, j) = & - (q_prim_qp%vf(i)%sf(k, l, j) - & - q_prim_qp%vf(i)%sf(k, l, j - 1))/ & - (z_cc(j) - z_cc(j - 1)) + dqL_prim_dz_n(3)%vf(i)%sf(k, l, j) = (q_prim_qp%vf(i)%sf(k, l, j) - q_prim_qp%vf(i)%sf(k, & + & l, j - 1))/(z_cc(j) - z_cc(j - 1)) end do end do end do @@ -806,11 +699,8 @@ contains do k = is1_viscous%beg, is1_viscous%end $:GPU_LOOP(parallelism='[seq]') do i = iv%beg, iv%end - - dqR_prim_dz_n(3)%vf(i)%sf(k, l, j) = & - (q_prim_qp%vf(i)%sf(k, l, j + 1) - & - q_prim_qp%vf(i)%sf(k, l, j))/ & - (z_cc(j + 1) - z_cc(j)) + dqR_prim_dz_n(3)%vf(i)%sf(k, l, j) = (q_prim_qp%vf(i)%sf(k, l, & + & j + 1) - q_prim_qp%vf(i)%sf(k, l, j))/(z_cc(j + 1) - z_cc(j)) end do end do end do @@ -823,16 +713,12 @@ contains do j = is1_viscous%beg + 1, is1_viscous%end $:GPU_LOOP(parallelism='[seq]') do i = iv%beg, iv%end + dqL_prim_dz_n(1)%vf(i)%sf(j, k, l) = (dqL_prim_dz_n(3)%vf(i)%sf(j, k, & + & l) + dqR_prim_dz_n(3)%vf(i)%sf(j, k, & + & l) + dqL_prim_dz_n(3)%vf(i)%sf(j - 1, k, & + & l) + dqR_prim_dz_n(3)%vf(i)%sf(j - 1, k, l)) - dqL_prim_dz_n(1)%vf(i)%sf(j, k, l) = & - (dqL_prim_dz_n(3)%vf(i)%sf(j, k, l) + & - dqR_prim_dz_n(3)%vf(i)%sf(j, k, l) + & - dqL_prim_dz_n(3)%vf(i)%sf(j - 1, k, l) + & - dqR_prim_dz_n(3)%vf(i)%sf(j - 1, k, l)) - - dqL_prim_dz_n(1)%vf(i)%sf(j, k, l) = 25.e-2_wp* & - dqL_prim_dz_n(1)%vf(i)%sf(j, k, l) - + dqL_prim_dz_n(1)%vf(i)%sf(j, k, l) = 25.e-2_wp*dqL_prim_dz_n(1)%vf(i)%sf(j, k, l) end do end do end do @@ -845,16 +731,12 @@ contains do j = is1_viscous%beg, is1_viscous%end - 1 $:GPU_LOOP(parallelism='[seq]') do i = iv%beg, iv%end + dqR_prim_dz_n(1)%vf(i)%sf(j, k, l) = (dqL_prim_dz_n(3)%vf(i)%sf(j + 1, k, & + & l) + dqR_prim_dz_n(3)%vf(i)%sf(j + 1, k, & + & l) + dqL_prim_dz_n(3)%vf(i)%sf(j, k, l) + dqR_prim_dz_n(3)%vf(i)%sf(j, k, & + & l)) - dqR_prim_dz_n(1)%vf(i)%sf(j, k, l) = & - (dqL_prim_dz_n(3)%vf(i)%sf(j + 1, k, l) + & - dqR_prim_dz_n(3)%vf(i)%sf(j + 1, k, l) + & - dqL_prim_dz_n(3)%vf(i)%sf(j, k, l) + & - dqR_prim_dz_n(3)%vf(i)%sf(j, k, l)) - - dqR_prim_dz_n(1)%vf(i)%sf(j, k, l) = 25.e-2_wp* & - dqR_prim_dz_n(1)%vf(i)%sf(j, k, l) - + dqR_prim_dz_n(1)%vf(i)%sf(j, k, l) = 25.e-2_wp*dqR_prim_dz_n(1)%vf(i)%sf(j, k, l) end do end do end do @@ -867,16 +749,11 @@ contains do k = is1_viscous%beg, is1_viscous%end $:GPU_LOOP(parallelism='[seq]') do i = iv%beg, iv%end + dqL_prim_dz_n(2)%vf(i)%sf(k, j, l) = (dqL_prim_dz_n(3)%vf(i)%sf(k, j, & + & l) + dqR_prim_dz_n(3)%vf(i)%sf(k, j, l) + dqL_prim_dz_n(3)%vf(i)%sf(k, & + & j - 1, l) + dqR_prim_dz_n(3)%vf(i)%sf(k, j - 1, l)) - dqL_prim_dz_n(2)%vf(i)%sf(k, j, l) = & - (dqL_prim_dz_n(3)%vf(i)%sf(k, j, l) + & - dqR_prim_dz_n(3)%vf(i)%sf(k, j, l) + & - dqL_prim_dz_n(3)%vf(i)%sf(k, j - 1, l) + & - dqR_prim_dz_n(3)%vf(i)%sf(k, j - 1, l)) - - dqL_prim_dz_n(2)%vf(i)%sf(k, j, l) = 25.e-2_wp* & - dqL_prim_dz_n(2)%vf(i)%sf(k, j, l) - + dqL_prim_dz_n(2)%vf(i)%sf(k, j, l) = 25.e-2_wp*dqL_prim_dz_n(2)%vf(i)%sf(k, j, l) end do end do end do @@ -889,16 +766,12 @@ contains do k = is1_viscous%beg, is1_viscous%end $:GPU_LOOP(parallelism='[seq]') do i = iv%beg, iv%end + dqR_prim_dz_n(2)%vf(i)%sf(k, j, l) = (dqL_prim_dz_n(3)%vf(i)%sf(k, j + 1, & + & l) + dqR_prim_dz_n(3)%vf(i)%sf(k, j + 1, & + & l) + dqL_prim_dz_n(3)%vf(i)%sf(k, j, l) + dqR_prim_dz_n(3)%vf(i)%sf(k, j, & + & l)) - dqR_prim_dz_n(2)%vf(i)%sf(k, j, l) = & - (dqL_prim_dz_n(3)%vf(i)%sf(k, j + 1, l) + & - dqR_prim_dz_n(3)%vf(i)%sf(k, j + 1, l) + & - dqL_prim_dz_n(3)%vf(i)%sf(k, j, l) + & - dqR_prim_dz_n(3)%vf(i)%sf(k, j, l)) - - dqR_prim_dz_n(2)%vf(i)%sf(k, j, l) = 25.e-2_wp* & - dqR_prim_dz_n(2)%vf(i)%sf(k, j, l) - + dqR_prim_dz_n(2)%vf(i)%sf(k, j, l) = 25.e-2_wp*dqR_prim_dz_n(2)%vf(i)%sf(k, j, l) end do end do end do @@ -911,16 +784,11 @@ contains do k = is1_viscous%beg, is1_viscous%end $:GPU_LOOP(parallelism='[seq]') do i = iv%beg, iv%end + dqL_prim_dy_n(3)%vf(i)%sf(k, l, j) = (dqL_prim_dy_n(2)%vf(i)%sf(k, l, & + & j) + dqR_prim_dy_n(2)%vf(i)%sf(k, l, j) + dqL_prim_dy_n(2)%vf(i)%sf(k, l, & + & j - 1) + dqR_prim_dy_n(2)%vf(i)%sf(k, l, j - 1)) - dqL_prim_dy_n(3)%vf(i)%sf(k, l, j) = & - (dqL_prim_dy_n(2)%vf(i)%sf(k, l, j) + & - dqR_prim_dy_n(2)%vf(i)%sf(k, l, j) + & - dqL_prim_dy_n(2)%vf(i)%sf(k, l, j - 1) + & - dqR_prim_dy_n(2)%vf(i)%sf(k, l, j - 1)) - - dqL_prim_dy_n(3)%vf(i)%sf(k, l, j) = 25.e-2_wp* & - dqL_prim_dy_n(3)%vf(i)%sf(k, l, j) - + dqL_prim_dy_n(3)%vf(i)%sf(k, l, j) = 25.e-2_wp*dqL_prim_dy_n(3)%vf(i)%sf(k, l, j) end do end do end do @@ -933,16 +801,12 @@ contains do k = is1_viscous%beg, is1_viscous%end $:GPU_LOOP(parallelism='[seq]') do i = iv%beg, iv%end + dqR_prim_dy_n(3)%vf(i)%sf(k, l, j) = (dqL_prim_dy_n(2)%vf(i)%sf(k, l, & + & j + 1) + dqR_prim_dy_n(2)%vf(i)%sf(k, l, & + & j + 1) + dqL_prim_dy_n(2)%vf(i)%sf(k, l, & + & j) + dqR_prim_dy_n(2)%vf(i)%sf(k, l, j)) - dqR_prim_dy_n(3)%vf(i)%sf(k, l, j) = & - (dqL_prim_dy_n(2)%vf(i)%sf(k, l, j + 1) + & - dqR_prim_dy_n(2)%vf(i)%sf(k, l, j + 1) + & - dqL_prim_dy_n(2)%vf(i)%sf(k, l, j) + & - dqR_prim_dy_n(2)%vf(i)%sf(k, l, j)) - - dqR_prim_dy_n(3)%vf(i)%sf(k, l, j) = 25.e-2_wp* & - dqR_prim_dy_n(3)%vf(i)%sf(k, l, j) - + dqR_prim_dy_n(3)%vf(i)%sf(k, l, j) = 25.e-2_wp*dqR_prim_dy_n(3)%vf(i)%sf(k, l, j) end do end do end do @@ -954,16 +818,11 @@ contains do k = is1_viscous%beg + 1, is1_viscous%end - 1 $:GPU_LOOP(parallelism='[seq]') do i = iv%beg, iv%end + dqL_prim_dx_n(3)%vf(i)%sf(k, l, j) = (dqL_prim_dx_n(1)%vf(i)%sf(k, l, & + & j) + dqR_prim_dx_n(1)%vf(i)%sf(k, l, j) + dqL_prim_dx_n(1)%vf(i)%sf(k, l, & + & j - 1) + dqR_prim_dx_n(1)%vf(i)%sf(k, l, j - 1)) - dqL_prim_dx_n(3)%vf(i)%sf(k, l, j) = & - (dqL_prim_dx_n(1)%vf(i)%sf(k, l, j) + & - dqR_prim_dx_n(1)%vf(i)%sf(k, l, j) + & - dqL_prim_dx_n(1)%vf(i)%sf(k, l, j - 1) + & - dqR_prim_dx_n(1)%vf(i)%sf(k, l, j - 1)) - - dqL_prim_dx_n(3)%vf(i)%sf(k, l, j) = 25.e-2_wp* & - dqL_prim_dx_n(3)%vf(i)%sf(k, l, j) - + dqL_prim_dx_n(3)%vf(i)%sf(k, l, j) = 25.e-2_wp*dqL_prim_dx_n(3)%vf(i)%sf(k, l, j) end do end do end do @@ -975,15 +834,12 @@ contains do k = is1_viscous%beg + 1, is1_viscous%end - 1 $:GPU_LOOP(parallelism='[seq]') do i = iv%beg, iv%end - dqR_prim_dx_n(3)%vf(i)%sf(k, l, j) = & - (dqL_prim_dx_n(1)%vf(i)%sf(k, l, j + 1) + & - dqR_prim_dx_n(1)%vf(i)%sf(k, l, j + 1) + & - dqL_prim_dx_n(1)%vf(i)%sf(k, l, j) + & - dqR_prim_dx_n(1)%vf(i)%sf(k, l, j)) - - dqR_prim_dx_n(3)%vf(i)%sf(k, l, j) = 25.e-2_wp* & - dqR_prim_dx_n(3)%vf(i)%sf(k, l, j) + dqR_prim_dx_n(3)%vf(i)%sf(k, l, j) = (dqL_prim_dx_n(1)%vf(i)%sf(k, l, & + & j + 1) + dqR_prim_dx_n(1)%vf(i)%sf(k, l, & + & j + 1) + dqL_prim_dx_n(1)%vf(i)%sf(k, l, & + & j) + dqR_prim_dx_n(1)%vf(i)%sf(k, l, j)) + dqR_prim_dx_n(3)%vf(i)%sf(k, l, j) = 25.e-2_wp*dqR_prim_dx_n(3)%vf(i)%sf(k, l, j) end do end do end do @@ -991,52 +847,36 @@ contains $:END_GPU_PARALLEL_LOOP() do i = iv%beg, iv%end - call s_compute_fd_gradient(q_prim_qp%vf(i), & - dq_prim_dx_qp(1)%vf(i), & - dq_prim_dy_qp(1)%vf(i), & - dq_prim_dz_qp(1)%vf(i)) + call s_compute_fd_gradient(q_prim_qp%vf(i), dq_prim_dx_qp(1)%vf(i), dq_prim_dy_qp(1)%vf(i), & + & dq_prim_dz_qp(1)%vf(i)) end do #:endif - else - do i = iv%beg, iv%end - call s_compute_fd_gradient(q_prim_qp%vf(i), & - dq_prim_dx_qp(1)%vf(i), & - dq_prim_dy_qp(1)%vf(i), & - dq_prim_dy_qp(1)%vf(i)) + call s_compute_fd_gradient(q_prim_qp%vf(i), dq_prim_dx_qp(1)%vf(i), dq_prim_dy_qp(1)%vf(i), & + & dq_prim_dy_qp(1)%vf(i)) end do - end if - else - do i = iv%beg, iv%end - call s_compute_fd_gradient(q_prim_qp%vf(i), & - dq_prim_dx_qp(1)%vf(i), & - dq_prim_dx_qp(1)%vf(i), & - dq_prim_dx_qp(1)%vf(i)) + call s_compute_fd_gradient(q_prim_qp%vf(i), dq_prim_dx_qp(1)%vf(i), dq_prim_dx_qp(1)%vf(i), & + & dq_prim_dx_qp(1)%vf(i)) end do - end if - end if end subroutine s_get_viscous !> @brief Reconstructs left and right cell-boundary values of viscous primitive variables using WENO or MUSCL. - subroutine s_reconstruct_cell_boundary_values_visc(v_vf, vL_x, vL_y, vL_z, vR_x, vR_y, vR_z, & - norm_dir, vL_prim_vf, vR_prim_vf, ix, iy, iz) + subroutine s_reconstruct_cell_boundary_values_visc(v_vf, vL_x, vL_y, vL_z, vR_x, vR_y, vR_z, norm_dir, vL_prim_vf, & + & vR_prim_vf, ix, iy, iz) type(scalar_field), dimension(iv%beg:iv%end), intent(in) :: v_vf type(scalar_field), dimension(iv%beg:iv%end), intent(inout) :: vL_prim_vf, vR_prim_vf - - real(wp), dimension(idwbuff(1)%beg:, idwbuff(2)%beg:, idwbuff(3)%beg:, 1:), intent(inout) :: vL_x, vL_y, vL_z, vR_x, vR_y, vR_z + real(wp), dimension(idwbuff(1)%beg:,idwbuff(2)%beg:,idwbuff(3)%beg:,1:), intent(inout) :: vL_x, vL_y, vL_z, vR_x, vR_y, vR_z integer, intent(in) :: norm_dir type(int_bounds_info), intent(in) :: ix, iy, iz - - integer :: recon_dir !< Coordinate direction of the WENO reconstruction - + integer :: recon_dir !< Coordinate direction of the WENO reconstruction integer :: i, j, k, l #:for SCHEME, TYPE in [('weno','WENO_TYPE'), ('muscl','MUSCL_TYPE')] @@ -1047,37 +887,31 @@ contains is1_viscous = ix; is2_viscous = iy; is3_viscous = iz recon_dir = 1; is1_viscous%beg = is1_viscous%beg + ${SCHEME}$_polyn is1_viscous%end = is1_viscous%end - ${SCHEME}$_polyn - - elseif (norm_dir == 2) then + else if (norm_dir == 2) then is1_viscous = iy; is2_viscous = ix; is3_viscous = iz recon_dir = 2; is1_viscous%beg = is1_viscous%beg + ${SCHEME}$_polyn is1_viscous%end = is1_viscous%end - ${SCHEME}$_polyn - else is1_viscous = iz; is2_viscous = iy; is3_viscous = ix recon_dir = 3; is1_viscous%beg = is1_viscous%beg + ${SCHEME}$_polyn is1_viscous%end = is1_viscous%end - ${SCHEME}$_polyn - end if $:GPU_UPDATE(device='[is1_viscous, is2_viscous, is3_viscous, iv]') if (n > 0) then if (p > 0) then - call s_${SCHEME}$ (v_vf(iv%beg:iv%end), & - vL_x(:, :, :, iv%beg:iv%end), vL_y(:, :, :, iv%beg:iv%end), vL_z(:, :, :, iv%beg:iv%end), vR_x(:, :, :, iv%beg:iv%end), vR_y(:, :, :, iv%beg:iv%end), vR_z(:, :, :, iv%beg:iv%end), & - recon_dir, & - is1_viscous, is2_viscous, is3_viscous) + call s_${SCHEME}$ (v_vf(iv%beg:iv%end), vL_x(:,:,:,iv%beg:iv%end), vL_y(:,:,:,iv%beg:iv%end), vL_z(:,:,:, & + & iv%beg:iv%end), vR_x(:,:,:,iv%beg:iv%end), vR_y(:,:,:,iv%beg:iv%end), vR_z(:,:,:, & + & iv%beg:iv%end), recon_dir, is1_viscous, is2_viscous, is3_viscous) else - call s_${SCHEME}$ (v_vf(iv%beg:iv%end), & - vL_x(:, :, :, iv%beg:iv%end), vL_y(:, :, :, iv%beg:iv%end), vL_z(:, :, :, :), vR_x(:, :, :, iv%beg:iv%end), vR_y(:, :, :, iv%beg:iv%end), vR_z(:, :, :, :), & - recon_dir, & - is1_viscous, is2_viscous, is3_viscous) + call s_${SCHEME}$ (v_vf(iv%beg:iv%end), vL_x(:,:,:,iv%beg:iv%end), vL_y(:,:,:,iv%beg:iv%end), vL_z(:,:,:, & + & :), vR_x(:,:,:,iv%beg:iv%end), vR_y(:,:,:,iv%beg:iv%end), vR_z(:,:,:,:), recon_dir, & + & is1_viscous, is2_viscous, is3_viscous) end if else - call s_${SCHEME}$ (v_vf(iv%beg:iv%end), & - vL_x(:, :, :, iv%beg:iv%end), vL_y(:, :, :, :), vL_z(:, :, :, :), vR_x(:, :, :, iv%beg:iv%end), vR_y(:, :, :, :), vR_z(:, :, :, :), & - recon_dir, & - is1_viscous, is2_viscous, is3_viscous) + call s_${SCHEME}$ (v_vf(iv%beg:iv%end), vL_x(:,:,:,iv%beg:iv%end), vL_y(:,:,:,:), vL_z(:,:,:,:), vR_x(:,:,:, & + & iv%beg:iv%end), vR_y(:,:,:,:), vR_z(:,:,:,:), recon_dir, is1_viscous, is2_viscous, & + & is3_viscous) end if end if #:endfor @@ -1097,7 +931,7 @@ contains end do end do $:END_GPU_PARALLEL_LOOP() - elseif (norm_dir == 3) then + else if (norm_dir == 3) then $:GPU_PARALLEL_LOOP(collapse=4) do i = iv%beg, iv%end do j = is1_viscous%beg, is1_viscous%end @@ -1110,7 +944,7 @@ contains end do end do $:END_GPU_PARALLEL_LOOP() - elseif (norm_dir == 1) then + else if (norm_dir == 1) then $:GPU_PARALLEL_LOOP(collapse=4) do i = iv%beg, iv%end do l = is3_viscous%beg, is3_viscous%end @@ -1130,18 +964,17 @@ contains end subroutine s_reconstruct_cell_boundary_values_visc !> @brief Reconstructs left and right cell-boundary values of viscous primitive variable derivatives using WENO or MUSCL. - subroutine s_reconstruct_cell_boundary_values_visc_deriv(v_vf, vL_x, vL_y, vL_z, vR_x, vR_y, vR_z, & - norm_dir, vL_prim_vf, vR_prim_vf, ix, iy, iz) - type(scalar_field), dimension(iv%beg:iv%end), intent(in) :: v_vf - real(wp), dimension(idwbuff(1)%beg:, idwbuff(2)%beg:, idwbuff(3)%beg:, iv%beg:), intent(inout) :: vL_x, vL_y, vL_z, vR_x, vR_y, vR_z + subroutine s_reconstruct_cell_boundary_values_visc_deriv(v_vf, vL_x, vL_y, vL_z, vR_x, vR_y, vR_z, norm_dir, vL_prim_vf, & + & vR_prim_vf, ix, iy, iz) + type(scalar_field), dimension(iv%beg:iv%end), intent(in) :: v_vf + real(wp), dimension(idwbuff(1)%beg:,idwbuff(2)%beg:,idwbuff(3)%beg:,iv%beg:), intent(inout) :: vL_x, vL_y, vL_z, vR_x, & + & vR_y, vR_z type(scalar_field), dimension(iv%beg:iv%end), intent(inout) :: vL_prim_vf, vR_prim_vf - type(int_bounds_info), intent(in) :: ix, iy, iz - - integer, intent(IN) :: norm_dir + type(int_bounds_info), intent(in) :: ix, iy, iz + integer, intent(in) :: norm_dir + integer :: recon_dir !< Coordinate direction of the WENO reconstruction + integer :: i, j, k, l - integer :: recon_dir !< Coordinate direction of the WENO reconstruction - - integer :: i, j, k, l #:for SCHEME, TYPE in [('weno','WENO_TYPE'), ('muscl','MUSCL_TYPE')] if (recon_type == ${TYPE}$) then ! Reconstruction in s1-direction @@ -1150,38 +983,30 @@ contains is1_viscous = ix; is2_viscous = iy; is3_viscous = iz recon_dir = 1; is1_viscous%beg = is1_viscous%beg + ${SCHEME}$_polyn is1_viscous%end = is1_viscous%end - ${SCHEME}$_polyn - - elseif (norm_dir == 2) then + else if (norm_dir == 2) then is1_viscous = iy; is2_viscous = ix; is3_viscous = iz recon_dir = 2; is1_viscous%beg = is1_viscous%beg + ${SCHEME}$_polyn is1_viscous%end = is1_viscous%end - ${SCHEME}$_polyn - else is1_viscous = iz; is2_viscous = iy; is3_viscous = ix recon_dir = 3; is1_viscous%beg = is1_viscous%beg + ${SCHEME}$_polyn is1_viscous%end = is1_viscous%end - ${SCHEME}$_polyn - end if $:GPU_UPDATE(device='[is1_viscous, is2_viscous, is3_viscous, iv]') if (n > 0) then if (p > 0) then - - call s_${SCHEME}$ (v_vf(iv%beg:iv%end), & - vL_x(:, :, :, iv%beg:iv%end), vL_y(:, :, :, iv%beg:iv%end), vL_z(:, :, :, iv%beg:iv%end), vR_x(:, :, :, iv%beg:iv%end), vR_y(:, :, :, iv%beg:iv%end), vR_z(:, :, :, iv%beg:iv%end), & - recon_dir, & - is1_viscous, is2_viscous, is3_viscous) + call s_${SCHEME}$ (v_vf(iv%beg:iv%end), vL_x(:,:,:,iv%beg:iv%end), vL_y(:,:,:,iv%beg:iv%end), vL_z(:,:,:, & + & iv%beg:iv%end), vR_x(:,:,:,iv%beg:iv%end), vR_y(:,:,:,iv%beg:iv%end), vR_z(:,:,:, & + & iv%beg:iv%end), recon_dir, is1_viscous, is2_viscous, is3_viscous) else - call s_${SCHEME}$ (v_vf(iv%beg:iv%end), & - vL_x(:, :, :, iv%beg:iv%end), vL_y(:, :, :, iv%beg:iv%end), vL_z(:, :, :, :), vR_x(:, :, :, iv%beg:iv%end), vR_y(:, :, :, iv%beg:iv%end), vR_z(:, :, :, :), & - recon_dir, & - is1_viscous, is2_viscous, is3_viscous) + call s_${SCHEME}$ (v_vf(iv%beg:iv%end), vL_x(:,:,:,iv%beg:iv%end), vL_y(:,:,:,iv%beg:iv%end), vL_z(:,:,:, & + & :), vR_x(:,:,:,iv%beg:iv%end), vR_y(:,:,:,iv%beg:iv%end), vR_z(:,:,:,:), recon_dir, & + & is1_viscous, is2_viscous, is3_viscous) end if else - - call s_${SCHEME}$ (v_vf(iv%beg:iv%end), & - vL_x(:, :, :, iv%beg:iv%end), vL_y(:, :, :, :), vL_z(:, :, :, :), vR_x(:, :, :, iv%beg:iv%end), vR_y(:, :, :, :), vR_z(:, :, :, :), & - recon_dir, & - is1_viscous, is2_viscous, is3_viscous) + call s_${SCHEME}$ (v_vf(iv%beg:iv%end), vL_x(:,:,:,iv%beg:iv%end), vL_y(:,:,:,:), vL_z(:,:,:,:), vR_x(:,:,:, & + & iv%beg:iv%end), vR_y(:,:,:,:), vR_z(:,:,:,:), recon_dir, is1_viscous, is2_viscous, & + & is3_viscous) end if end if #:endfor @@ -1201,7 +1026,7 @@ contains end do end do $:END_GPU_PARALLEL_LOOP() - elseif (norm_dir == 3) then + else if (norm_dir == 3) then $:GPU_PARALLEL_LOOP(collapse=4) do i = iv%beg, iv%end do j = is1_viscous%beg, is1_viscous%end @@ -1214,7 +1039,7 @@ contains end do end do $:END_GPU_PARALLEL_LOOP() - elseif (norm_dir == 1) then + else if (norm_dir == 1) then $:GPU_PARALLEL_LOOP(collapse=4) do i = iv%beg, iv%end do l = is3_viscous%beg, is3_viscous%end @@ -1233,43 +1058,30 @@ contains end subroutine s_reconstruct_cell_boundary_values_visc_deriv - !> The purpose of this subroutine is to employ the inputted - !! left and right cell-boundary integral-averaged variables - !! to compute the relevant cell-average first-order spatial - !! derivatives in the x-, y- or z-direction by means of the - !! scalar divergence theorem. - !! @param vL_vf Left cell-boundary integral averages - !! @param vR_vf Right cell-boundary integral averages - !! @param dv_ds_vf Cell-average first-order spatial derivatives - !! @param norm_dir Splitting coordinate direction - !! @param ix Index bounds in the x-direction - !! @param iy Index bounds in the y-direction - !! @param iz Index bounds in the z-direction - !! @param iv_in Variable index bounds - !! @param dL Cell width array - !! @param dim Dimension size - !! @param buff_size_in Buffer layer size - subroutine s_apply_scalar_divergence_theorem(vL_vf, vR_vf, & - dv_ds_vf, & - norm_dir, & - ix, iy, iz, iv_in, & - dL, dim, buff_size_in) + !> The purpose of this subroutine is to employ the inputted left and right cell-boundary integral-averaged variables to compute + !! the relevant cell-average first-order spatial derivatives in the x-, y- or z-direction by means of the scalar divergence + !! theorem. + !! @param vL_vf Left cell-boundary integral averages + !! @param vR_vf Right cell-boundary integral averages + !! @param dv_ds_vf Cell-average first-order spatial derivatives + !! @param norm_dir Splitting coordinate direction + !! @param ix Index bounds in the x-direction + !! @param iy Index bounds in the y-direction + !! @param iz Index bounds in the z-direction + !! @param iv_in Variable index bounds + !! @param dL Cell width array + !! @param dim Dimension size + !! @param buff_size_in Buffer layer size + subroutine s_apply_scalar_divergence_theorem(vL_vf, vR_vf, dv_ds_vf, norm_dir, ix, iy, iz, iv_in, dL, dim, buff_size_in) ! arrays of cell widths - type(scalar_field), & - dimension(iv%beg:iv%end), & - intent(in) :: vL_vf, vR_vf - - type(scalar_field), & - dimension(iv%beg:iv%end), & - intent(inout) :: dv_ds_vf - - integer, intent(in) :: norm_dir - type(int_bounds_info), intent(in) :: ix, iy, iz, iv_in - integer, intent(in) :: dim, buff_size_in + type(scalar_field), dimension(iv%beg:iv%end), intent(in) :: vL_vf, vR_vf + type(scalar_field), dimension(iv%beg:iv%end), intent(inout) :: dv_ds_vf + integer, intent(in) :: norm_dir + type(int_bounds_info), intent(in) :: ix, iy, iz, iv_in + integer, intent(in) :: dim, buff_size_in real(wp), dimension(-buff_size_in:dim + buff_size_in), intent(in) :: dL - - integer :: i, j, k, l !< Generic loop iterators + integer :: i, j, k, l !< Generic loop iterators is1_viscous = ix is2_viscous = iy @@ -1280,12 +1092,9 @@ contains ! First-Order Spatial Derivatives in x-direction if (norm_dir == 1) then - - ! A general application of the scalar divergence theorem that - ! utilizes the left and right cell-boundary integral-averages, - ! inside each cell, or an arithmetic mean of these two at the - ! cell-boundaries, to calculate the cell-averaged first-order - ! spatial derivatives inside the cell. + ! A general application of the scalar divergence theorem that utilizes the left and right cell-boundary + ! integral-averages, inside each cell, or an arithmetic mean of these two at the cell-boundaries, to calculate the + ! cell-averaged first-order spatial derivatives inside the cell. $:GPU_PARALLEL_LOOP(collapse=3) do l = is3_viscous%beg, is3_viscous%end @@ -1293,12 +1102,8 @@ contains do j = is1_viscous%beg + 1, is1_viscous%end - 1 $:GPU_LOOP(parallelism='[seq]') do i = iv%beg, iv%end - dv_ds_vf(i)%sf(j, k, l) = & - 1._wp/((1._wp + wa_flg)*dL(j)) & - *(wa_flg*vL_vf(i)%sf(j + 1, k, l) & - + vR_vf(i)%sf(j, k, l) & - - vL_vf(i)%sf(j, k, l) & - - wa_flg*vR_vf(i)%sf(j - 1, k, l)) + dv_ds_vf(i)%sf(j, k, l) = 1._wp/((1._wp + wa_flg)*dL(j))*(wa_flg*vL_vf(i)%sf(j + 1, k, & + & l) + vR_vf(i)%sf(j, k, l) - vL_vf(i)%sf(j, k, l) - wa_flg*vR_vf(i)%sf(j - 1, k, l)) end do end do end do @@ -1308,13 +1113,10 @@ contains ! END: First-Order Spatial Derivatives in x-direction ! First-Order Spatial Derivatives in y-direction - elseif (norm_dir == 2) then - - ! A general application of the scalar divergence theorem that - ! utilizes the left and right cell-boundary integral-averages, - ! inside each cell, or an arithmetic mean of these two at the - ! cell-boundaries, to calculate the cell-averaged first-order - ! spatial derivatives inside the cell. + else if (norm_dir == 2) then + ! A general application of the scalar divergence theorem that utilizes the left and right cell-boundary + ! integral-averages, inside each cell, or an arithmetic mean of these two at the cell-boundaries, to calculate the + ! cell-averaged first-order spatial derivatives inside the cell. $:GPU_PARALLEL_LOOP(collapse=3) do l = is3_viscous%beg, is3_viscous%end @@ -1322,12 +1124,8 @@ contains do j = is1_viscous%beg, is1_viscous%end $:GPU_LOOP(parallelism='[seq]') do i = iv%beg, iv%end - dv_ds_vf(i)%sf(j, k, l) = & - 1._wp/((1._wp + wa_flg)*dL(k)) & - *(wa_flg*vL_vf(i)%sf(j, k + 1, l) & - + vR_vf(i)%sf(j, k, l) & - - vL_vf(i)%sf(j, k, l) & - - wa_flg*vR_vf(i)%sf(j, k - 1, l)) + dv_ds_vf(i)%sf(j, k, l) = 1._wp/((1._wp + wa_flg)*dL(k))*(wa_flg*vL_vf(i)%sf(j, k + 1, & + & l) + vR_vf(i)%sf(j, k, l) - vL_vf(i)%sf(j, k, l) - wa_flg*vR_vf(i)%sf(j, k - 1, l)) end do end do end do @@ -1338,12 +1136,9 @@ contains ! First-Order Spatial Derivatives in z-direction else - - ! A general application of the scalar divergence theorem that - ! utilizes the left and right cell-boundary integral-averages, - ! inside each cell, or an arithmetic mean of these two at the - ! cell-boundaries, to calculate the cell-averaged first-order - ! spatial derivatives inside the cell. + ! A general application of the scalar divergence theorem that utilizes the left and right cell-boundary + ! integral-averages, inside each cell, or an arithmetic mean of these two at the cell-boundaries, to calculate the + ! cell-averaged first-order spatial derivatives inside the cell. $:GPU_PARALLEL_LOOP(collapse=3) do l = is3_viscous%beg + 1, is3_viscous%end - 1 @@ -1351,37 +1146,31 @@ contains do j = is1_viscous%beg, is1_viscous%end $:GPU_LOOP(parallelism='[seq]') do i = iv%beg, iv%end - dv_ds_vf(i)%sf(j, k, l) = & - 1._wp/((1._wp + wa_flg)*dL(l)) & - *(wa_flg*vL_vf(i)%sf(j, k, l + 1) & - + vR_vf(i)%sf(j, k, l) & - - vL_vf(i)%sf(j, k, l) & - - wa_flg*vR_vf(i)%sf(j, k, l - 1)) + dv_ds_vf(i)%sf(j, k, l) = 1._wp/((1._wp + wa_flg)*dL(l))*(wa_flg*vL_vf(i)%sf(j, k, & + & l + 1) + vR_vf(i)%sf(j, k, l) - vL_vf(i)%sf(j, k, l) - wa_flg*vR_vf(i)%sf(j, k, l - 1)) end do end do end do end do $:END_GPU_PARALLEL_LOOP() - end if ! END: First-Order Spatial Derivatives in z-direction end subroutine s_apply_scalar_divergence_theorem - !> Computes the scalar gradient fields via finite differences - !! @param var Variable to compute derivative of - !! @param grad_x First coordinate direction component of the derivative - !! @param grad_y Second coordinate direction component of the derivative - !! @param grad_z Third coordinate direction component of the derivative + !> Computes the scalar gradient fields via finite differences + !! @param var Variable to compute derivative of + !! @param grad_x First coordinate direction component of the derivative + !! @param grad_y Second coordinate direction component of the derivative + !! @param grad_z Third coordinate direction component of the derivative subroutine s_compute_fd_gradient(var, grad_x, grad_y, grad_z) - type(scalar_field), intent(in) :: var + type(scalar_field), intent(in) :: var type(scalar_field), intent(inout) :: grad_x type(scalar_field), intent(inout) :: grad_y type(scalar_field), intent(inout) :: grad_z - type(int_bounds_info) :: ix, iy, iz - - integer :: j, k, l !< Generic loop iterators + type(int_bounds_info) :: ix, iy, iz + integer :: j, k, l !< Generic loop iterators ix%beg = 1 - buff_size; ix%end = m + buff_size - 1 if (n > 0) then @@ -1398,15 +1187,13 @@ contains is1_viscous = ix; is2_viscous = iy; is3_viscous = iz - $:GPU_UPDATE(device='[is1_viscous,is2_viscous,is3_viscous]') + $:GPU_UPDATE(device='[is1_viscous, is2_viscous, is3_viscous]') $:GPU_PARALLEL_LOOP(collapse=3) do l = is3_viscous%beg, is3_viscous%end do k = is2_viscous%beg, is2_viscous%end do j = is1_viscous%beg, is1_viscous%end - grad_x%sf(j, k, l) = & - (var%sf(j + 1, k, l) - var%sf(j - 1, k, l))/ & - (x_cc(j + 1) - x_cc(j - 1)) + grad_x%sf(j, k, l) = (var%sf(j + 1, k, l) - var%sf(j - 1, k, l))/(x_cc(j + 1) - x_cc(j - 1)) end do end do end do @@ -1417,9 +1204,7 @@ contains do l = is3_viscous%beg, is3_viscous%end do k = is2_viscous%beg, is2_viscous%end do j = is1_viscous%beg, is1_viscous%end - grad_y%sf(j, k, l) = & - (var%sf(j, k + 1, l) - var%sf(j, k - 1, l))/ & - (y_cc(k + 1) - y_cc(k - 1)) + grad_y%sf(j, k, l) = (var%sf(j, k + 1, l) - var%sf(j, k - 1, l))/(y_cc(k + 1) - y_cc(k - 1)) end do end do end do @@ -1431,9 +1216,7 @@ contains do l = is3_viscous%beg, is3_viscous%end do k = is2_viscous%beg, is2_viscous%end do j = is1_viscous%beg, is1_viscous%end - grad_z%sf(j, k, l) = & - (var%sf(j, k, l + 1) - var%sf(j, k, l - 1))/ & - (z_cc(l + 1) - z_cc(l - 1)) + grad_z%sf(j, k, l) = (var%sf(j, k, l + 1) - var%sf(j, k, l - 1))/(z_cc(l + 1) - z_cc(l - 1)) end do end do end do @@ -1443,12 +1226,10 @@ contains $:GPU_PARALLEL_LOOP(collapse=2) do l = idwbuff(3)%beg, idwbuff(3)%end do k = idwbuff(2)%beg, idwbuff(2)%end - grad_x%sf(idwbuff(1)%beg, k, l) = & - (-3._wp*var%sf(idwbuff(1)%beg, k, l) + 4._wp*var%sf(idwbuff(1)%beg + 1, k, l) - var%sf(idwbuff(1)%beg + 2, k, l))/ & - (x_cc(idwbuff(1)%beg + 2) - x_cc(idwbuff(1)%beg)) - grad_x%sf(idwbuff(1)%end, k, l) = & - (+3._wp*var%sf(idwbuff(1)%end, k, l) - 4._wp*var%sf(idwbuff(1)%end - 1, k, l) + var%sf(idwbuff(1)%end - 2, k, l))/ & - (x_cc(idwbuff(1)%end) - x_cc(idwbuff(1)%end - 2)) + grad_x%sf(idwbuff(1)%beg, k, l) = (-3._wp*var%sf(idwbuff(1)%beg, k, l) + 4._wp*var%sf(idwbuff(1)%beg + 1, k, & + & l) - var%sf(idwbuff(1)%beg + 2, k, l))/(x_cc(idwbuff(1)%beg + 2) - x_cc(idwbuff(1)%beg)) + grad_x%sf(idwbuff(1)%end, k, l) = (+3._wp*var%sf(idwbuff(1)%end, k, l) - 4._wp*var%sf(idwbuff(1)%end - 1, k, & + & l) + var%sf(idwbuff(1)%end - 2, k, l))/(x_cc(idwbuff(1)%end) - x_cc(idwbuff(1)%end - 2)) end do end do $:END_GPU_PARALLEL_LOOP() @@ -1456,12 +1237,10 @@ contains $:GPU_PARALLEL_LOOP(collapse=2) do l = idwbuff(3)%beg, idwbuff(3)%end do j = idwbuff(1)%beg, idwbuff(1)%end - grad_y%sf(j, idwbuff(2)%beg, l) = & - (-3._wp*var%sf(j, idwbuff(2)%beg, l) + 4._wp*var%sf(j, idwbuff(2)%beg + 1, l) - var%sf(j, idwbuff(2)%beg + 2, l))/ & - (y_cc(idwbuff(2)%beg + 2) - y_cc(idwbuff(2)%beg)) - grad_y%sf(j, idwbuff(2)%end, l) = & - (+3._wp*var%sf(j, idwbuff(2)%end, l) - 4._wp*var%sf(j, idwbuff(2)%end - 1, l) + var%sf(j, idwbuff(2)%end - 2, l))/ & - (y_cc(idwbuff(2)%end) - y_cc(idwbuff(2)%end - 2)) + grad_y%sf(j, idwbuff(2)%beg, l) = (-3._wp*var%sf(j, idwbuff(2)%beg, l) + 4._wp*var%sf(j, idwbuff(2)%beg + 1, & + & l) - var%sf(j, idwbuff(2)%beg + 2, l))/(y_cc(idwbuff(2)%beg + 2) - y_cc(idwbuff(2)%beg)) + grad_y%sf(j, idwbuff(2)%end, l) = (+3._wp*var%sf(j, idwbuff(2)%end, l) - 4._wp*var%sf(j, idwbuff(2)%end - 1, & + & l) + var%sf(j, idwbuff(2)%end - 2, l))/(y_cc(idwbuff(2)%end) - y_cc(idwbuff(2)%end - 2)) end do end do $:END_GPU_PARALLEL_LOOP() @@ -1469,12 +1248,12 @@ contains $:GPU_PARALLEL_LOOP(collapse=2) do k = idwbuff(2)%beg, idwbuff(2)%end do j = idwbuff(1)%beg, idwbuff(1)%end - grad_z%sf(j, k, idwbuff(3)%beg) = & - (-3._wp*var%sf(j, k, idwbuff(3)%beg) + 4._wp*var%sf(j, k, idwbuff(3)%beg + 1) - var%sf(j, k, idwbuff(3)%beg + 2))/ & - (z_cc(idwbuff(3)%beg + 2) - z_cc(is3_viscous%beg)) - grad_z%sf(j, k, idwbuff(3)%end) = & - (+3._wp*var%sf(j, k, idwbuff(3)%end) - 4._wp*var%sf(j, k, idwbuff(3)%end - 1) + var%sf(j, k, idwbuff(3)%end - 2))/ & - (z_cc(idwbuff(3)%end) - z_cc(idwbuff(3)%end - 2)) + grad_z%sf(j, k, idwbuff(3)%beg) = (-3._wp*var%sf(j, k, idwbuff(3)%beg) + 4._wp*var%sf(j, k, & + & idwbuff(3)%beg + 1) - var%sf(j, k, & + & idwbuff(3)%beg + 2))/(z_cc(idwbuff(3)%beg + 2) - z_cc(is3_viscous%beg)) + grad_z%sf(j, k, idwbuff(3)%end) = (+3._wp*var%sf(j, k, idwbuff(3)%end) - 4._wp*var%sf(j, k, & + & idwbuff(3)%end - 1) + var%sf(j, k, & + & idwbuff(3)%end - 2))/(z_cc(idwbuff(3)%end) - z_cc(idwbuff(3)%end - 2)) end do end do $:END_GPU_PARALLEL_LOOP() @@ -1485,8 +1264,7 @@ contains $:GPU_PARALLEL_LOOP(collapse=2) do l = idwbuff(3)%beg, idwbuff(3)%end do k = idwbuff(2)%beg, idwbuff(2)%end - grad_x%sf(0, k, l) = (-3._wp*var%sf(0, k, l) + 4._wp*var%sf(1, k, l) - var%sf(2, k, l))/ & - (x_cc(2) - x_cc(0)) + grad_x%sf(0, k, l) = (-3._wp*var%sf(0, k, l) + 4._wp*var%sf(1, k, l) - var%sf(2, k, l))/(x_cc(2) - x_cc(0)) end do end do $:END_GPU_PARALLEL_LOOP() @@ -1495,8 +1273,8 @@ contains $:GPU_PARALLEL_LOOP(collapse=2) do l = idwbuff(3)%beg, idwbuff(3)%end do k = idwbuff(2)%beg, idwbuff(2)%end - grad_x%sf(m, k, l) = (3._wp*var%sf(m, k, l) - 4._wp*var%sf(m - 1, k, l) + var%sf(m - 2, k, l))/ & - (x_cc(m) - x_cc(m - 2)) + grad_x%sf(m, k, l) = (3._wp*var%sf(m, k, l) - 4._wp*var%sf(m - 1, k, l) + var%sf(m - 2, k, & + & l))/(x_cc(m) - x_cc(m - 2)) end do end do $:END_GPU_PARALLEL_LOOP() @@ -1506,8 +1284,7 @@ contains $:GPU_PARALLEL_LOOP(collapse=2) do l = idwbuff(3)%beg, idwbuff(3)%end do j = idwbuff(1)%beg, idwbuff(1)%end - grad_y%sf(j, 0, l) = (-3._wp*var%sf(j, 0, l) + 4._wp*var%sf(j, 1, l) - var%sf(j, 2, l))/ & - (y_cc(2) - y_cc(0)) + grad_y%sf(j, 0, l) = (-3._wp*var%sf(j, 0, l) + 4._wp*var%sf(j, 1, l) - var%sf(j, 2, l))/(y_cc(2) - y_cc(0)) end do end do $:END_GPU_PARALLEL_LOOP() @@ -1516,8 +1293,8 @@ contains $:GPU_PARALLEL_LOOP(collapse=2) do l = idwbuff(3)%beg, idwbuff(3)%end do j = idwbuff(1)%beg, idwbuff(1)%end - grad_y%sf(j, n, l) = (3._wp*var%sf(j, n, l) - 4._wp*var%sf(j, n - 1, l) + var%sf(j, n - 2, l))/ & - (y_cc(n) - y_cc(n - 2)) + grad_y%sf(j, n, l) = (3._wp*var%sf(j, n, l) - 4._wp*var%sf(j, n - 1, l) + var%sf(j, n - 2, & + & l))/(y_cc(n) - y_cc(n - 2)) end do end do $:END_GPU_PARALLEL_LOOP() @@ -1527,9 +1304,8 @@ contains $:GPU_PARALLEL_LOOP(collapse=2) do k = idwbuff(2)%beg, idwbuff(2)%end do j = idwbuff(1)%beg, idwbuff(1)%end - grad_z%sf(j, k, 0) = & - (-3._wp*var%sf(j, k, 0) + 4._wp*var%sf(j, k, 1) - var%sf(j, k, 2))/ & - (z_cc(2) - z_cc(0)) + grad_z%sf(j, k, 0) = (-3._wp*var%sf(j, k, 0) + 4._wp*var%sf(j, k, 1) - var%sf(j, k, & + & 2))/(z_cc(2) - z_cc(0)) end do end do $:END_GPU_PARALLEL_LOOP() @@ -1538,9 +1314,8 @@ contains $:GPU_PARALLEL_LOOP(collapse=2) do k = idwbuff(2)%beg, idwbuff(2)%end do j = idwbuff(1)%beg, idwbuff(1)%end - grad_z%sf(j, k, p) = & - (3._wp*var%sf(j, k, p) - 4._wp*var%sf(j, k, p - 1) + var%sf(j, k, p - 2))/ & - (z_cc(p) - z_cc(p - 2)) + grad_z%sf(j, k, p) = (3._wp*var%sf(j, k, p) - 4._wp*var%sf(j, k, p - 1) + var%sf(j, k, & + & p - 2))/(z_cc(p) - z_cc(p - 2)) end do end do $:END_GPU_PARALLEL_LOOP() @@ -1552,17 +1327,17 @@ contains !> @brief Computes the viscous stress tensor at a single grid cell using finite-difference velocity gradients. subroutine s_compute_viscous_stress_tensor(viscous_stress_tensor, q_prim_vf, dynamic_viscosity, i, j, k) + $:GPU_ROUTINE(parallelism='[seq]') - real(wp), dimension(1:3, 1:3), intent(inout) :: viscous_stress_tensor + real(wp), dimension(1:3,1:3), intent(inout) :: viscous_stress_tensor type(scalar_field), dimension(1:sys_size), intent(in) :: q_prim_vf - real(wp), intent(in) :: dynamic_viscosity - integer, intent(in) :: i, j, k - - real(wp), dimension(1:3, 1:3) :: velocity_gradient_tensor - real(wp), dimension(1:3) :: dx - real(wp) :: divergence - integer :: l, q ! iterators + real(wp), intent(in) :: dynamic_viscosity + integer, intent(in) :: i, j, k + real(wp), dimension(1:3,1:3) :: velocity_gradient_tensor + real(wp), dimension(1:3) :: dx + real(wp) :: divergence + integer :: l, q ! iterators ! zero the viscous stress, collection of velocity derivatives, and spatial finite differences viscous_stress_tensor = 0._wp @@ -1578,10 +1353,13 @@ contains ! compute the velocity gradient tensor do l = 1, num_dims - velocity_gradient_tensor(l, 1) = (q_prim_vf(momxb + l - 1)%sf(i + 1, j, k) - q_prim_vf(momxb + l - 1)%sf(i - 1, j, k))/(2._wp*dx(1)) - velocity_gradient_tensor(l, 2) = (q_prim_vf(momxb + l - 1)%sf(i, j + 1, k) - q_prim_vf(momxb + l - 1)%sf(i, j - 1, k))/(2._wp*dx(2)) + velocity_gradient_tensor(l, 1) = (q_prim_vf(momxb + l - 1)%sf(i + 1, j, k) - q_prim_vf(momxb + l - 1)%sf(i - 1, j, & + & k))/(2._wp*dx(1)) + velocity_gradient_tensor(l, 2) = (q_prim_vf(momxb + l - 1)%sf(i, j + 1, k) - q_prim_vf(momxb + l - 1)%sf(i, j - 1, & + & k))/(2._wp*dx(2)) if (num_dims == 3) then - velocity_gradient_tensor(l, 3) = (q_prim_vf(momxb + l - 1)%sf(i, j, k + 1) - q_prim_vf(momxb + l - 1)%sf(i, j, k - 1))/(2._wp*dx(3)) + velocity_gradient_tensor(l, 3) = (q_prim_vf(momxb + l - 1)%sf(i, j, k + 1) - q_prim_vf(momxb + l - 1)%sf(i, j, & + & k - 1))/(2._wp*dx(3)) end if end do diff --git a/src/simulation/m_weno.fpp b/src/simulation/m_weno.fpp index 357a4e9b3e..a276d92601 100644 --- a/src/simulation/m_weno.fpp +++ b/src/simulation/m_weno.fpp @@ -7,95 +7,85 @@ !> @brief WENO/WENO-Z/TENO reconstruction with optional monotonicity-preserving bounds and mapped weights module m_weno - use m_derived_types !< Definitions of the derived types - - use m_global_parameters !< Definitions of the global parameters - - use m_variables_conversion !< State variables type conversion procedures + use m_derived_types !< Definitions of the derived types + use m_global_parameters !< Definitions of the global parameters + use m_variables_conversion !< State variables type conversion procedures ! $:USE_GPU_MODULE() use m_mpi_proxy - - use m_muscl !< For Interface Compression + use m_muscl !< For Interface Compression private; public :: s_initialize_weno_module, s_initialize_weno, s_finalize_weno_module, s_weno - !> @name The cell-average variables that will be WENO-reconstructed. Formerly, they - !! are stored in v_vf. However, they are transferred to v_rs_wsL and v_rs_wsR - !! as to be reshaped (RS) and/or characteristically decomposed. The reshaping - !! allows the WENO procedure to be independent of the coordinate direction of - !! the reconstruction. Lastly, notice that the left (L) and right (R) results - !! of the characteristic decomposition are stored in custom-constructed WENO- - !! stencils (WS) that are annexed to each position of a given scalar field. + !> @name The cell-average variables that will be WENO-reconstructed. Formerly, they are stored in v_vf. However, they are + !! transferred to v_rs_wsL and v_rs_wsR as to be reshaped (RS) and/or characteristically decomposed. The reshaping allows the + !! WENO procedure to be independent of the coordinate direction of the reconstruction. Lastly, notice that the left (L) and + !! right (R) results of the characteristic decomposition are stored in custom-constructed WENO- stencils (WS) that are annexed + !! to each position of a given scalar field. !> @{ - real(wp), allocatable, dimension(:, :, :, :) :: v_rs_ws_x, v_rs_ws_y, v_rs_ws_z + real(wp), allocatable, dimension(:,:,:,:) :: v_rs_ws_x, v_rs_ws_y, v_rs_ws_z !> @} - $:GPU_DECLARE(create='[v_rs_ws_x,v_rs_ws_y,v_rs_ws_z]') + $:GPU_DECLARE(create='[v_rs_ws_x, v_rs_ws_y, v_rs_ws_z]') ! WENO Coefficients - !> @name Polynomial coefficients at the left and right cell-boundaries (CB) and at - !! the left and right quadrature points (QP), in the x-, y- and z-directions. - !! Note that the first dimension of the array identifies the polynomial, the - !! second dimension identifies the position of its coefficients and the last - !! dimension denotes the cell-location in the relevant coordinate direction. + !> @name Polynomial coefficients at the left and right cell-boundaries (CB) and at the left and right quadrature points (QP), in + !! the x-, y- and z-directions. Note that the first dimension of the array identifies the polynomial, the second dimension + !! identifies the position of its coefficients and the last dimension denotes the cell-location in the relevant coordinate + !! direction. !> @{ - real(wp), target, allocatable, dimension(:, :, :) :: poly_coef_cbL_x - real(wp), target, allocatable, dimension(:, :, :) :: poly_coef_cbL_y - real(wp), target, allocatable, dimension(:, :, :) :: poly_coef_cbL_z - real(wp), target, allocatable, dimension(:, :, :) :: poly_coef_cbR_x - real(wp), target, allocatable, dimension(:, :, :) :: poly_coef_cbR_y - real(wp), target, allocatable, dimension(:, :, :) :: poly_coef_cbR_z + real(wp), target, allocatable, dimension(:,:,:) :: poly_coef_cbL_x + real(wp), target, allocatable, dimension(:,:,:) :: poly_coef_cbL_y + real(wp), target, allocatable, dimension(:,:,:) :: poly_coef_cbL_z + real(wp), target, allocatable, dimension(:,:,:) :: poly_coef_cbR_x + real(wp), target, allocatable, dimension(:,:,:) :: poly_coef_cbR_y + real(wp), target, allocatable, dimension(:,:,:) :: poly_coef_cbR_z !> @} - $:GPU_DECLARE(create='[poly_coef_cbL_x,poly_coef_cbL_y,poly_coef_cbL_z]') - $:GPU_DECLARE(create='[poly_coef_cbR_x,poly_coef_cbR_y,poly_coef_cbR_z]') + $:GPU_DECLARE(create='[poly_coef_cbL_x, poly_coef_cbL_y, poly_coef_cbL_z]') + $:GPU_DECLARE(create='[poly_coef_cbR_x, poly_coef_cbR_y, poly_coef_cbR_z]') - !> @name The ideal weights at the left and the right cell-boundaries and at the - !! left and the right quadrature points, in x-, y- and z-directions. Note - !! that the first dimension of the array identifies the weight, while the - !! last denotes the cell-location in the relevant coordinate direction. + !> @name The ideal weights at the left and the right cell-boundaries and at the left and the right quadrature points, in x-, y- + !! and z-directions. Note that the first dimension of the array identifies the weight, while the last denotes the cell-location + !! in the relevant coordinate direction. !> @{ - real(wp), target, allocatable, dimension(:, :) :: d_cbL_x - real(wp), target, allocatable, dimension(:, :) :: d_cbL_y - real(wp), target, allocatable, dimension(:, :) :: d_cbL_z - - real(wp), target, allocatable, dimension(:, :) :: d_cbR_x - real(wp), target, allocatable, dimension(:, :) :: d_cbR_y - real(wp), target, allocatable, dimension(:, :) :: d_cbR_z + real(wp), target, allocatable, dimension(:,:) :: d_cbL_x + real(wp), target, allocatable, dimension(:,:) :: d_cbL_y + real(wp), target, allocatable, dimension(:,:) :: d_cbL_z + real(wp), target, allocatable, dimension(:,:) :: d_cbR_x + real(wp), target, allocatable, dimension(:,:) :: d_cbR_y + real(wp), target, allocatable, dimension(:,:) :: d_cbR_z !> @} - $:GPU_DECLARE(create='[d_cbL_x,d_cbL_y,d_cbL_z,d_cbR_x,d_cbR_y,d_cbR_z]') + $:GPU_DECLARE(create='[d_cbL_x, d_cbL_y, d_cbL_z, d_cbR_x, d_cbR_y, d_cbR_z]') - !> @name Smoothness indicator coefficients in the x-, y-, and z-directions. Note - !! that the first array dimension identifies the smoothness indicator, the - !! second identifies the position of its coefficients and the last denotes - !! the cell-location in the relevant coordinate direction. + !> @name Smoothness indicator coefficients in the x-, y-, and z-directions. Note that the first array dimension identifies the + !! smoothness indicator, the second identifies the position of its coefficients and the last denotes the cell-location in the + !! relevant coordinate direction. !> @{ - real(wp), target, allocatable, dimension(:, :, :) :: beta_coef_x - real(wp), target, allocatable, dimension(:, :, :) :: beta_coef_y - real(wp), target, allocatable, dimension(:, :, :) :: beta_coef_z + real(wp), target, allocatable, dimension(:,:,:) :: beta_coef_x + real(wp), target, allocatable, dimension(:,:,:) :: beta_coef_y + real(wp), target, allocatable, dimension(:,:,:) :: beta_coef_z !> @} - $:GPU_DECLARE(create='[beta_coef_x,beta_coef_y,beta_coef_z]') + $:GPU_DECLARE(create='[beta_coef_x, beta_coef_y, beta_coef_z]') ! END: WENO Coefficients - integer :: v_size !< Number of WENO-reconstructed cell-average variables + integer :: v_size !< Number of WENO-reconstructed cell-average variables $:GPU_DECLARE(create='[v_size]') !> @name Indical bounds in the s1-, s2- and s3-directions !> @{ type(int_bounds_info) :: is1_weno, is2_weno, is3_weno #ifndef __NVCOMPILER_GPU_UNIFIED_MEM - $:GPU_DECLARE(create='[is1_weno,is2_weno,is3_weno]') + $:GPU_DECLARE(create='[is1_weno, is2_weno, is3_weno]') #endif ! !> @} contains - !> The computation of parameters, the allocation of memory, - !! the association of pointers and/or the execution of any - !! other procedures that are necessary to setup the module. + !> The computation of parameters, the allocation of memory, the association of pointers and/or the execution of any other + !! procedures that are necessary to setup the module. impure subroutine s_initialize_weno_module if (weno_order == 1) return @@ -105,7 +95,7 @@ contains if (n == 0) then is2_weno%beg = 0 else - is2_weno%beg = -buff_size; + is2_weno%beg = -buff_size end if is2_weno%end = n - is2_weno%beg @@ -118,23 +108,20 @@ contains is3_weno%end = p - is3_weno%beg - @:ALLOCATE(poly_coef_cbL_x(is1_weno%beg + weno_polyn:is1_weno%end - weno_polyn, 0:weno_polyn, & - 0:weno_polyn - 1)) - @:ALLOCATE(poly_coef_cbR_x(is1_weno%beg + weno_polyn:is1_weno%end - weno_polyn, 0:weno_polyn, & - 0:weno_polyn - 1)) + @:ALLOCATE(poly_coef_cbL_x(is1_weno%beg + weno_polyn:is1_weno%end - weno_polyn, 0:weno_polyn, 0:weno_polyn - 1)) + @:ALLOCATE(poly_coef_cbR_x(is1_weno%beg + weno_polyn:is1_weno%end - weno_polyn, 0:weno_polyn, 0:weno_polyn - 1)) @:ALLOCATE(d_cbL_x(0:weno_num_stencils, is1_weno%beg + weno_polyn:is1_weno%end - weno_polyn)) @:ALLOCATE(d_cbR_x(0:weno_num_stencils, is1_weno%beg + weno_polyn:is1_weno%end - weno_polyn)) @:ALLOCATE(beta_coef_x(is1_weno%beg + weno_polyn:is1_weno%end - weno_polyn, 0:weno_polyn, & - 0:weno_polyn*(weno_polyn + 1)/2 - 1)) - ! Number of cross terms for dvd = (k-1)(k-1+1)/2, where weno_polyn = k-1 - ! Note: k-1 not k because we are using value differences (dvd) not the values themselves + & 0:weno_polyn*(weno_polyn + 1)/2 - 1)) + ! Number of cross terms for dvd = (k-1)(k-1+1)/2, where weno_polyn = k-1 Note: k-1 not k because we are using value + ! differences (dvd) not the values themselves call s_compute_weno_coefficients(1, is1_weno) - @:ALLOCATE(v_rs_ws_x(is1_weno%beg:is1_weno%end, & - is2_weno%beg:is2_weno%end, is3_weno%beg:is3_weno%end, 1:sys_size)) + @:ALLOCATE(v_rs_ws_x(is1_weno%beg:is1_weno%end, is2_weno%beg:is2_weno%end, is3_weno%beg:is3_weno%end, 1:sys_size)) ! Allocating/Computing WENO Coefficients in y-direction if (n == 0) return @@ -150,21 +137,18 @@ contains is3_weno%end = p - is3_weno%beg - @:ALLOCATE(poly_coef_cbL_y(is2_weno%beg + weno_polyn:is2_weno%end - weno_polyn, 0:weno_polyn, & - 0:weno_polyn - 1)) - @:ALLOCATE(poly_coef_cbR_y(is2_weno%beg + weno_polyn:is2_weno%end - weno_polyn, 0:weno_polyn, & - 0:weno_polyn - 1)) + @:ALLOCATE(poly_coef_cbL_y(is2_weno%beg + weno_polyn:is2_weno%end - weno_polyn, 0:weno_polyn, 0:weno_polyn - 1)) + @:ALLOCATE(poly_coef_cbR_y(is2_weno%beg + weno_polyn:is2_weno%end - weno_polyn, 0:weno_polyn, 0:weno_polyn - 1)) @:ALLOCATE(d_cbL_y(0:weno_num_stencils, is2_weno%beg + weno_polyn:is2_weno%end - weno_polyn)) @:ALLOCATE(d_cbR_y(0:weno_num_stencils, is2_weno%beg + weno_polyn:is2_weno%end - weno_polyn)) @:ALLOCATE(beta_coef_y(is2_weno%beg + weno_polyn:is2_weno%end - weno_polyn, 0:weno_polyn, & - 0:weno_polyn*(weno_polyn + 1)/2 - 1)) + & 0:weno_polyn*(weno_polyn + 1)/2 - 1)) call s_compute_weno_coefficients(2, is2_weno) - @:ALLOCATE(v_rs_ws_y(is2_weno%beg:is2_weno%end, & - is1_weno%beg:is1_weno%end, is3_weno%beg:is3_weno%end, 1:sys_size)) + @:ALLOCATE(v_rs_ws_y(is2_weno%beg:is2_weno%end, is1_weno%beg:is1_weno%end, is3_weno%beg:is3_weno%end, 1:sys_size)) ! Allocating/Computing WENO Coefficients in z-direction if (p == 0) return @@ -173,53 +157,42 @@ contains is1_weno%beg = -buff_size; is1_weno%end = m - is1_weno%beg is3_weno%beg = -buff_size; is3_weno%end = p - is3_weno%beg - @:ALLOCATE(poly_coef_cbL_z(is3_weno%beg + weno_polyn:is3_weno%end - weno_polyn, 0:weno_polyn, & - 0:weno_polyn - 1)) - @:ALLOCATE(poly_coef_cbR_z(is3_weno%beg + weno_polyn:is3_weno%end - weno_polyn, 0:weno_polyn, & - 0:weno_polyn - 1)) + @:ALLOCATE(poly_coef_cbL_z(is3_weno%beg + weno_polyn:is3_weno%end - weno_polyn, 0:weno_polyn, 0:weno_polyn - 1)) + @:ALLOCATE(poly_coef_cbR_z(is3_weno%beg + weno_polyn:is3_weno%end - weno_polyn, 0:weno_polyn, 0:weno_polyn - 1)) @:ALLOCATE(d_cbL_z(0:weno_num_stencils, is3_weno%beg + weno_polyn:is3_weno%end - weno_polyn)) @:ALLOCATE(d_cbR_z(0:weno_num_stencils, is3_weno%beg + weno_polyn:is3_weno%end - weno_polyn)) @:ALLOCATE(beta_coef_z(is3_weno%beg + weno_polyn:is3_weno%end - weno_polyn, 0:weno_polyn, & - 0:weno_polyn*(weno_polyn + 1)/2 - 1)) + & 0:weno_polyn*(weno_polyn + 1)/2 - 1)) call s_compute_weno_coefficients(3, is3_weno) - @:ALLOCATE(v_rs_ws_z(is3_weno%beg:is3_weno%end, & - is2_weno%beg:is2_weno%end, is1_weno%beg:is1_weno%end, 1:sys_size)) + @:ALLOCATE(v_rs_ws_z(is3_weno%beg:is3_weno%end, is2_weno%beg:is2_weno%end, is1_weno%beg:is1_weno%end, 1:sys_size)) end subroutine s_initialize_weno_module - !> The purpose of this subroutine is to compute the grid - !! dependent coefficients of the WENO polynomials, ideal - !! weights and smoothness indicators, provided the order, - !! the coordinate direction and the location of the WENO - !! reconstruction. - !! @param weno_dir Coordinate direction of the WENO reconstruction - !! @param is Index bounds in the s-direction + !> The purpose of this subroutine is to compute the grid dependent coefficients of the WENO polynomials, ideal weights and + !! smoothness indicators, provided the order, the coordinate direction and the location of the WENO reconstruction. + !! @param weno_dir Coordinate direction of the WENO reconstruction + !! @param is Index bounds in the s-direction subroutine s_compute_weno_coefficients(weno_dir, is) - integer, intent(in) :: weno_dir + integer, intent(in) :: weno_dir type(int_bounds_info), intent(in) :: is - integer :: s - - real(wp), pointer, dimension(:) :: s_cb => null() !< - !! Cell-boundary locations in the s-direction + integer :: s + real(wp), pointer, dimension(:) :: s_cb => null() !< Cell-boundary locations in the s-direction + type(int_bounds_info) :: bc_s !< Boundary conditions (BC) in the s-direction + integer :: i !< Generic loop iterator + real(wp) :: w(1:8) ! Intermediate var for ideal weights: s_cb across overall stencil + real(wp) :: y(1:4) ! Intermediate var for poly & beta: diff(s_cb) across sub-stencil - type(int_bounds_info) :: bc_s !< Boundary conditions (BC) in the s-direction + ! Determining the number of cells, the cell-boundary locations and the boundary conditions in the coordinate direction + ! selected for the WENO reconstruction - integer :: i !< Generic loop iterator - - real(wp) :: w(1:8) ! Intermediate var for ideal weights: s_cb across overall stencil - real(wp) :: y(1:4) ! Intermediate var for poly & beta: diff(s_cb) across sub-stencil - - ! Determining the number of cells, the cell-boundary locations and - ! the boundary conditions in the coordinate direction selected for - ! the WENO reconstruction if (weno_dir == 1) then s = m; s_cb => x_cb; bc_s = bc_x - elseif (weno_dir == 2) then + else if (weno_dir == 2) then s = n; s_cb => y_cb; bc_s = bc_y else s = p; s_cb => z_cb; bc_s = bc_z @@ -230,34 +203,24 @@ contains if (weno_dir == ${WENO_DIR}$) then if (weno_order == 3) then do i = is%beg - 1 + weno_polyn, is%end - 1 - weno_polyn - - poly_coef_cbR_${XYZ}$ (i + 1, 0, 0) = (s_cb(i) - s_cb(i + 1))/ & - (s_cb(i) - s_cb(i + 2)) - poly_coef_cbR_${XYZ}$ (i + 1, 1, 0) = (s_cb(i) - s_cb(i + 1))/ & - (s_cb(i - 1) - s_cb(i + 1)) + poly_coef_cbR_${XYZ}$ (i + 1, 0, 0) = (s_cb(i) - s_cb(i + 1))/(s_cb(i) - s_cb(i + 2)) + poly_coef_cbR_${XYZ}$ (i + 1, 1, 0) = (s_cb(i) - s_cb(i + 1))/(s_cb(i - 1) - s_cb(i + 1)) poly_coef_cbL_${XYZ}$ (i + 1, 0, 0) = -poly_coef_cbR_${XYZ}$ (i + 1, 0, 0) poly_coef_cbL_${XYZ}$ (i + 1, 1, 0) = -poly_coef_cbR_${XYZ}$ (i + 1, 1, 0) - d_cbR_${XYZ}$ (0, i + 1) = (s_cb(i - 1) - s_cb(i + 1))/ & - (s_cb(i - 1) - s_cb(i + 2)) - d_cbL_${XYZ}$ (0, i + 1) = (s_cb(i - 1) - s_cb(i))/ & - (s_cb(i - 1) - s_cb(i + 2)) + d_cbR_${XYZ}$ (0, i + 1) = (s_cb(i - 1) - s_cb(i + 1))/(s_cb(i - 1) - s_cb(i + 2)) + d_cbL_${XYZ}$ (0, i + 1) = (s_cb(i - 1) - s_cb(i))/(s_cb(i - 1) - s_cb(i + 2)) d_cbR_${XYZ}$ (1, i + 1) = 1._wp - d_cbR_${XYZ}$ (0, i + 1) d_cbL_${XYZ}$ (1, i + 1) = 1._wp - d_cbL_${XYZ}$ (0, i + 1) - beta_coef_${XYZ}$ (i + 1, 0, 0) = 4._wp*(s_cb(i) - s_cb(i + 1))**2._wp/ & - (s_cb(i) - s_cb(i + 2))**2._wp - beta_coef_${XYZ}$ (i + 1, 1, 0) = 4._wp*(s_cb(i) - s_cb(i + 1))**2._wp/ & - (s_cb(i - 1) - s_cb(i + 1))**2._wp - + beta_coef_${XYZ}$ (i + 1, 0, 0) = 4._wp*(s_cb(i) - s_cb(i + 1))**2._wp/(s_cb(i) - s_cb(i + 2))**2._wp + beta_coef_${XYZ}$ (i + 1, 1, 0) = 4._wp*(s_cb(i) - s_cb(i + 1))**2._wp/(s_cb(i - 1) - s_cb(i + 1))**2._wp end do - ! Modifying the ideal weights coefficients in the neighborhood - ! of beginning and end Riemann state extrapolation BC to avoid - ! any contributions from outside of the physical domain during - ! the WENO reconstruction + ! Modifying the ideal weights coefficients in the neighborhood of beginning and end Riemann state extrapolation + ! BC to avoid any contributions from outside of the physical domain during the WENO reconstruction if (null_weights) then if (bc_s%beg == BC_RIEMANN_EXTRAP) then d_cbR_${XYZ}$ (1, 0) = 0._wp; d_cbR_${XYZ}$ (0, 0) = 1._wp @@ -272,351 +235,618 @@ contains ! END: Computing WENO3 Coefficients ! Computing WENO5 Coefficients - elseif (weno_order == 5) then - + else if (weno_order == 5) then do i = is%beg - 1 + weno_polyn, is%end - 1 - weno_polyn - - poly_coef_cbR_${XYZ}$ (i + 1, 0, 0) = & - ((s_cb(i) - s_cb(i + 1))*(s_cb(i + 1) - s_cb(i + 2)))/ & - ((s_cb(i) - s_cb(i + 3))*(s_cb(i + 3) - s_cb(i + 1))) - poly_coef_cbR_${XYZ}$ (i + 1, 1, 0) = & - ((s_cb(i - 1) - s_cb(i + 1))*(s_cb(i + 1) - s_cb(i)))/ & - ((s_cb(i - 1) - s_cb(i + 2))*(s_cb(i + 2) - s_cb(i))) - poly_coef_cbR_${XYZ}$ (i + 1, 1, 1) = & - ((s_cb(i) - s_cb(i + 1))*(s_cb(i + 1) - s_cb(i + 2)))/ & - ((s_cb(i - 1) - s_cb(i + 1))*(s_cb(i - 1) - s_cb(i + 2))) - poly_coef_cbR_${XYZ}$ (i + 1, 2, 1) = & - ((s_cb(i) - s_cb(i + 1))*(s_cb(i + 1) - s_cb(i - 1)))/ & - ((s_cb(i - 2) - s_cb(i))*(s_cb(i - 2) - s_cb(i + 1))) - poly_coef_cbL_${XYZ}$ (i + 1, 0, 0) = & - ((s_cb(i + 1) - s_cb(i))*(s_cb(i) - s_cb(i + 2)))/ & - ((s_cb(i) - s_cb(i + 3))*(s_cb(i + 3) - s_cb(i + 1))) - poly_coef_cbL_${XYZ}$ (i + 1, 1, 0) = & - ((s_cb(i) - s_cb(i - 1))*(s_cb(i) - s_cb(i + 1)))/ & - ((s_cb(i - 1) - s_cb(i + 2))*(s_cb(i) - s_cb(i + 2))) - poly_coef_cbL_${XYZ}$ (i + 1, 1, 1) = & - ((s_cb(i + 1) - s_cb(i))*(s_cb(i) - s_cb(i + 2)))/ & - ((s_cb(i - 1) - s_cb(i + 1))*(s_cb(i - 1) - s_cb(i + 2))) - poly_coef_cbL_${XYZ}$ (i + 1, 2, 1) = & - ((s_cb(i - 1) - s_cb(i))*(s_cb(i) - s_cb(i + 1)))/ & - ((s_cb(i - 2) - s_cb(i))*(s_cb(i - 2) - s_cb(i + 1))) - - poly_coef_cbR_${XYZ}$ (i + 1, 0, 1) = & - ((s_cb(i) - s_cb(i + 2)) + (s_cb(i + 1) - s_cb(i + 3)))/ & - ((s_cb(i) - s_cb(i + 2))*(s_cb(i) - s_cb(i + 3)))* & - ((s_cb(i) - s_cb(i + 1))) - poly_coef_cbR_${XYZ}$ (i + 1, 2, 0) = & - ((s_cb(i - 2) - s_cb(i + 1)) + (s_cb(i - 1) - s_cb(i + 1)))/ & - ((s_cb(i - 1) - s_cb(i + 1))*(s_cb(i + 1) - s_cb(i - 2)))* & - ((s_cb(i + 1) - s_cb(i))) - poly_coef_cbL_${XYZ}$ (i + 1, 0, 1) = & - ((s_cb(i) - s_cb(i + 2)) + (s_cb(i) - s_cb(i + 3)))/ & - ((s_cb(i) - s_cb(i + 2))*(s_cb(i) - s_cb(i + 3)))* & - ((s_cb(i + 1) - s_cb(i))) - poly_coef_cbL_${XYZ}$ (i + 1, 2, 0) = & - ((s_cb(i - 2) - s_cb(i)) + (s_cb(i - 1) - s_cb(i + 1)))/ & - ((s_cb(i - 2) - s_cb(i + 1))*(s_cb(i + 1) - s_cb(i - 1)))* & - ((s_cb(i) - s_cb(i + 1))) - - d_cbR_${XYZ}$ (0, i + 1) = & - ((s_cb(i - 2) - s_cb(i + 1))*(s_cb(i + 1) - s_cb(i - 1)))/ & - ((s_cb(i - 2) - s_cb(i + 3))*(s_cb(i + 3) - s_cb(i - 1))) - d_cbR_${XYZ}$ (2, i + 1) = & - ((s_cb(i + 1) - s_cb(i + 2))*(s_cb(i + 1) - s_cb(i + 3)))/ & - ((s_cb(i - 2) - s_cb(i + 2))*(s_cb(i - 2) - s_cb(i + 3))) - d_cbL_${XYZ}$ (0, i + 1) = & - ((s_cb(i - 2) - s_cb(i))*(s_cb(i) - s_cb(i - 1)))/ & - ((s_cb(i - 2) - s_cb(i + 3))*(s_cb(i + 3) - s_cb(i - 1))) - d_cbL_${XYZ}$ (2, i + 1) = & - ((s_cb(i) - s_cb(i + 2))*(s_cb(i) - s_cb(i + 3)))/ & - ((s_cb(i - 2) - s_cb(i + 2))*(s_cb(i - 2) - s_cb(i + 3))) + poly_coef_cbR_${XYZ}$ (i + 1, 0, & + & 0) = ((s_cb(i) - s_cb(i + 1))*(s_cb(i + 1) - s_cb(i + 2)))/((s_cb(i) - s_cb(i & + & + 3))*(s_cb(i + 3) - s_cb(i + 1))) + poly_coef_cbR_${XYZ}$ (i + 1, 1, & + & 0) = ((s_cb(i - 1) - s_cb(i + 1))*(s_cb(i + 1) - s_cb(i)))/((s_cb(i - 1) & + & - s_cb(i + 2))*(s_cb(i + 2) - s_cb(i))) + poly_coef_cbR_${XYZ}$ (i + 1, 1, & + & 1) = ((s_cb(i) - s_cb(i + 1))*(s_cb(i + 1) - s_cb(i + 2)))/((s_cb(i - 1) & + & - s_cb(i + 1))*(s_cb(i - 1) - s_cb(i + 2))) + poly_coef_cbR_${XYZ}$ (i + 1, 2, & + & 1) = ((s_cb(i) - s_cb(i + 1))*(s_cb(i + 1) - s_cb(i - 1)))/((s_cb(i - 2) & + & - s_cb(i))*(s_cb(i - 2) - s_cb(i + 1))) + poly_coef_cbL_${XYZ}$ (i + 1, 0, & + & 0) = ((s_cb(i + 1) - s_cb(i))*(s_cb(i) - s_cb(i + 2)))/((s_cb(i) - s_cb(i + 3)) & + & *(s_cb(i + 3) - s_cb(i + 1))) + poly_coef_cbL_${XYZ}$ (i + 1, 1, & + & 0) = ((s_cb(i) - s_cb(i - 1))*(s_cb(i) - s_cb(i + 1)))/((s_cb(i - 1) - s_cb(i & + & + 2))*(s_cb(i) - s_cb(i + 2))) + poly_coef_cbL_${XYZ}$ (i + 1, 1, & + & 1) = ((s_cb(i + 1) - s_cb(i))*(s_cb(i) - s_cb(i + 2)))/((s_cb(i - 1) - s_cb(i & + & + 1))*(s_cb(i - 1) - s_cb(i + 2))) + poly_coef_cbL_${XYZ}$ (i + 1, 2, & + & 1) = ((s_cb(i - 1) - s_cb(i))*(s_cb(i) - s_cb(i + 1)))/((s_cb(i - 2) - s_cb(i)) & + & *(s_cb(i - 2) - s_cb(i + 1))) + + poly_coef_cbR_${XYZ}$ (i + 1, 0, & + & 1) = ((s_cb(i) - s_cb(i + 2)) + (s_cb(i + 1) - s_cb(i + 3)))/((s_cb(i) - s_cb(i & + & + 2))*(s_cb(i) - s_cb(i + 3)))*((s_cb(i) - s_cb(i + 1))) + poly_coef_cbR_${XYZ}$ (i + 1, 2, & + & 0) = ((s_cb(i - 2) - s_cb(i + 1)) + (s_cb(i - 1) - s_cb(i + 1)))/((s_cb(i - 1) & + & - s_cb(i + 1))*(s_cb(i + 1) - s_cb(i - 2)))*((s_cb(i + 1) - s_cb(i))) + poly_coef_cbL_${XYZ}$ (i + 1, 0, & + & 1) = ((s_cb(i) - s_cb(i + 2)) + (s_cb(i) - s_cb(i + 3)))/((s_cb(i) - s_cb(i + 2)) & + & *(s_cb(i) - s_cb(i + 3)))*((s_cb(i + 1) - s_cb(i))) + poly_coef_cbL_${XYZ}$ (i + 1, 2, & + & 0) = ((s_cb(i - 2) - s_cb(i)) + (s_cb(i - 1) - s_cb(i + 1)))/((s_cb(i - 2) & + & - s_cb(i + 1))*(s_cb(i + 1) - s_cb(i - 1)))*((s_cb(i) - s_cb(i + 1))) + + d_cbR_${XYZ}$ (0, & + & i + 1) = ((s_cb(i - 2) - s_cb(i + 1))*(s_cb(i + 1) - s_cb(i - 1)))/((s_cb(i - 2) & + & - s_cb(i + 3))*(s_cb(i + 3) - s_cb(i - 1))) + d_cbR_${XYZ}$ (2, & + & i + 1) = ((s_cb(i + 1) - s_cb(i + 2))*(s_cb(i + 1) - s_cb(i + 3)))/((s_cb(i - 2) & + & - s_cb(i + 2))*(s_cb(i - 2) - s_cb(i + 3))) + d_cbL_${XYZ}$ (0, & + & i + 1) = ((s_cb(i - 2) - s_cb(i))*(s_cb(i) - s_cb(i - 1)))/((s_cb(i - 2) - s_cb(i + 3)) & + & *(s_cb(i + 3) - s_cb(i - 1))) + d_cbL_${XYZ}$ (2, & + & i + 1) = ((s_cb(i) - s_cb(i + 2))*(s_cb(i) - s_cb(i + 3)))/((s_cb(i - 2) - s_cb(i + 2)) & + & *(s_cb(i - 2) - s_cb(i + 3))) d_cbR_${XYZ}$ (1, i + 1) = 1._wp - d_cbR_${XYZ}$ (0, i + 1) - d_cbR_${XYZ}$ (2, i + 1) d_cbL_${XYZ}$ (1, i + 1) = 1._wp - d_cbL_${XYZ}$ (0, i + 1) - d_cbL_${XYZ}$ (2, i + 1) - beta_coef_${XYZ}$ (i + 1, 0, 0) = & - 4._wp*(s_cb(i) - s_cb(i + 1))**2._wp*(10._wp*(s_cb(i + 1) - & - s_cb(i))**2._wp + (s_cb(i + 1) - s_cb(i))*(s_cb(i + 2) - & - s_cb(i + 1)) + (s_cb(i + 2) - s_cb(i + 1))**2._wp)/((s_cb(i) - & - s_cb(i + 3))**2._wp*(s_cb(i + 1) - s_cb(i + 3))**2._wp) - - beta_coef_${XYZ}$ (i + 1, 0, 1) = & - 4._wp*(s_cb(i) - s_cb(i + 1))**2._wp*(19._wp*(s_cb(i + 1) - & - s_cb(i))**2._wp - (s_cb(i + 1) - s_cb(i))*(s_cb(i + 3) - & - s_cb(i + 1)) + 2._wp*(s_cb(i + 2) - s_cb(i))*((s_cb(i + 2) - & - s_cb(i)) + (s_cb(i + 3) - s_cb(i + 1))))/((s_cb(i) - & - s_cb(i + 2))*(s_cb(i) - s_cb(i + 3))**2._wp*(s_cb(i + 3) - & - s_cb(i + 1))) - - beta_coef_${XYZ}$ (i + 1, 0, 2) = & - 4._wp*(s_cb(i) - s_cb(i + 1))**2._wp*(10._wp*(s_cb(i + 1) - & - s_cb(i))**2._wp + (s_cb(i + 1) - s_cb(i))*((s_cb(i + 2) - & - s_cb(i)) + (s_cb(i + 3) - s_cb(i + 1))) + ((s_cb(i + 2) - & - s_cb(i)) + (s_cb(i + 3) - s_cb(i + 1)))**2._wp)/((s_cb(i) - & - s_cb(i + 2))**2._wp*(s_cb(i) - s_cb(i + 3))**2._wp) - - beta_coef_${XYZ}$ (i + 1, 1, 0) = & - 4._wp*(s_cb(i) - s_cb(i + 1))**2._wp*(10._wp*(s_cb(i + 1) - & - s_cb(i))**2._wp + (s_cb(i) - s_cb(i - 1))**2._wp + (s_cb(i) - & - s_cb(i - 1))*(s_cb(i + 1) - s_cb(i)))/((s_cb(i - 1) - & - s_cb(i + 2))**2._wp*(s_cb(i) - s_cb(i + 2))**2._wp) - - beta_coef_${XYZ}$ (i + 1, 1, 1) = & - 4._wp*(s_cb(i) - s_cb(i + 1))**2._wp*((s_cb(i) - & - s_cb(i + 1))*((s_cb(i) - s_cb(i - 1)) + 20._wp*(s_cb(i + 1) - & - s_cb(i))) + (2._wp*(s_cb(i) - s_cb(i - 1)) + (s_cb(i + 1) - & - s_cb(i)))*(s_cb(i + 2) - s_cb(i)))/((s_cb(i + 1) - & - s_cb(i - 1))*(s_cb(i - 1) - s_cb(i + 2))**2._wp*(s_cb(i + 2) - & - s_cb(i))) - - beta_coef_${XYZ}$ (i + 1, 1, 2) = & - 4._wp*(s_cb(i) - s_cb(i + 1))**2._wp*(10._wp*(s_cb(i + 1) - & - s_cb(i))**2._wp + (s_cb(i + 1) - s_cb(i))*(s_cb(i + 2) - & - s_cb(i + 1)) + (s_cb(i + 2) - s_cb(i + 1))**2._wp)/ & - ((s_cb(i - 1) - s_cb(i + 1))**2._wp*(s_cb(i - 1) - & - s_cb(i + 2))**2._wp) - - beta_coef_${XYZ}$ (i + 1, 2, 0) = & - 4._wp*(s_cb(i) - s_cb(i + 1))**2._wp*(12._wp*(s_cb(i + 1) - & - s_cb(i))**2._wp + ((s_cb(i) - s_cb(i - 2)) + (s_cb(i) - & - s_cb(i - 1)))**2._wp + 3._wp*((s_cb(i) - s_cb(i - 2)) + & - (s_cb(i) - s_cb(i - 1)))*(s_cb(i + 1) - s_cb(i)))/ & - ((s_cb(i - 2) - s_cb(i + 1))**2._wp*(s_cb(i - 1) - & - s_cb(i + 1))**2._wp) - - beta_coef_${XYZ}$ (i + 1, 2, 1) = & - 4._wp*(s_cb(i) - s_cb(i + 1))**2._wp*(19._wp*(s_cb(i + 1) - & - s_cb(i))**2._wp + ((s_cb(i) - s_cb(i - 2))*(s_cb(i) - & - s_cb(i + 1))) + 2._wp*(s_cb(i + 1) - s_cb(i - 1))*((s_cb(i) - & - s_cb(i - 2)) + (s_cb(i + 1) - s_cb(i - 1))))/((s_cb(i - 2) - & - s_cb(i))*(s_cb(i - 2) - s_cb(i + 1))**2._wp*(s_cb(i + 1) - & - s_cb(i - 1))) - - beta_coef_${XYZ}$ (i + 1, 2, 2) = & - 4._wp*(s_cb(i) - s_cb(i + 1))**2._wp*(10._wp*(s_cb(i + 1) - & - s_cb(i))**2._wp + (s_cb(i) - s_cb(i - 1))**2._wp + (s_cb(i) - & - s_cb(i - 1))*(s_cb(i + 1) - s_cb(i)))/((s_cb(i - 2) - & - s_cb(i))**2._wp*(s_cb(i - 2) - s_cb(i + 1))**2._wp) - + beta_coef_${XYZ}$ (i + 1, 0, & + & 0) = 4._wp*(s_cb(i) - s_cb(i + 1))**2._wp*(10._wp*(s_cb(i + 1) - s_cb(i))**2._wp & + & + (s_cb(i + 1) - s_cb(i))*(s_cb(i + 2) - s_cb(i + 1)) + (s_cb(i + 2) - s_cb(i + 1)) & + & **2._wp)/((s_cb(i) - s_cb(i + 3))**2._wp*(s_cb(i + 1) - s_cb(i + 3))**2._wp) + + beta_coef_${XYZ}$ (i + 1, 0, & + & 1) = 4._wp*(s_cb(i) - s_cb(i + 1))**2._wp*(19._wp*(s_cb(i + 1) - s_cb(i))**2._wp & + & - (s_cb(i + 1) - s_cb(i))*(s_cb(i + 3) - s_cb(i + 1)) + 2._wp*(s_cb(i + 2) - s_cb(i)) & + & *((s_cb(i + 2) - s_cb(i)) + (s_cb(i + 3) - s_cb(i + 1))))/((s_cb(i) - s_cb(i + 2)) & + & *(s_cb(i) - s_cb(i + 3))**2._wp*(s_cb(i + 3) - s_cb(i + 1))) + + beta_coef_${XYZ}$ (i + 1, 0, & + & 2) = 4._wp*(s_cb(i) - s_cb(i + 1))**2._wp*(10._wp*(s_cb(i + 1) - s_cb(i))**2._wp & + & + (s_cb(i + 1) - s_cb(i))*((s_cb(i + 2) - s_cb(i)) + (s_cb(i + 3) - s_cb(i + 1))) & + & + ((s_cb(i + 2) - s_cb(i)) + (s_cb(i + 3) - s_cb(i + 1)))**2._wp)/((s_cb(i) - s_cb(i & + & + 2))**2._wp*(s_cb(i) - s_cb(i + 3))**2._wp) + + beta_coef_${XYZ}$ (i + 1, 1, & + & 0) = 4._wp*(s_cb(i) - s_cb(i + 1))**2._wp*(10._wp*(s_cb(i + 1) - s_cb(i))**2._wp & + & + (s_cb(i) - s_cb(i - 1))**2._wp + (s_cb(i) - s_cb(i - 1))*(s_cb(i + 1) - s_cb(i))) & + & /((s_cb(i - 1) - s_cb(i + 2))**2._wp*(s_cb(i) - s_cb(i + 2))**2._wp) + + beta_coef_${XYZ}$ (i + 1, 1, & + & 1) = 4._wp*(s_cb(i) - s_cb(i + 1))**2._wp*((s_cb(i) - s_cb(i + 1))*((s_cb(i) & + & - s_cb(i - 1)) + 20._wp*(s_cb(i + 1) - s_cb(i))) + (2._wp*(s_cb(i) - s_cb(i - 1)) & + & + (s_cb(i + 1) - s_cb(i)))*(s_cb(i + 2) - s_cb(i)))/((s_cb(i + 1) - s_cb(i - 1)) & + & *(s_cb(i - 1) - s_cb(i + 2))**2._wp*(s_cb(i + 2) - s_cb(i))) + + beta_coef_${XYZ}$ (i + 1, 1, & + & 2) = 4._wp*(s_cb(i) - s_cb(i + 1))**2._wp*(10._wp*(s_cb(i + 1) - s_cb(i))**2._wp & + & + (s_cb(i + 1) - s_cb(i))*(s_cb(i + 2) - s_cb(i + 1)) + (s_cb(i + 2) - s_cb(i + 1)) & + & **2._wp)/((s_cb(i - 1) - s_cb(i + 1))**2._wp*(s_cb(i - 1) - s_cb(i + 2))**2._wp) + + beta_coef_${XYZ}$ (i + 1, 2, & + & 0) = 4._wp*(s_cb(i) - s_cb(i + 1))**2._wp*(12._wp*(s_cb(i + 1) - s_cb(i))**2._wp & + & + ((s_cb(i) - s_cb(i - 2)) + (s_cb(i) - s_cb(i - 1)))**2._wp + 3._wp*((s_cb(i) & + & - s_cb(i - 2)) + (s_cb(i) - s_cb(i - 1)))*(s_cb(i + 1) - s_cb(i)))/((s_cb(i - 2) & + & - s_cb(i + 1))**2._wp*(s_cb(i - 1) - s_cb(i + 1))**2._wp) + + beta_coef_${XYZ}$ (i + 1, 2, & + & 1) = 4._wp*(s_cb(i) - s_cb(i + 1))**2._wp*(19._wp*(s_cb(i + 1) - s_cb(i))**2._wp & + & + ((s_cb(i) - s_cb(i - 2))*(s_cb(i) - s_cb(i + 1))) + 2._wp*(s_cb(i + 1) - s_cb(i & + & - 1))*((s_cb(i) - s_cb(i - 2)) + (s_cb(i + 1) - s_cb(i - 1))))/((s_cb(i - 2) & + & - s_cb(i))*(s_cb(i - 2) - s_cb(i + 1))**2._wp*(s_cb(i + 1) - s_cb(i - 1))) + + beta_coef_${XYZ}$ (i + 1, 2, & + & 2) = 4._wp*(s_cb(i) - s_cb(i + 1))**2._wp*(10._wp*(s_cb(i + 1) - s_cb(i))**2._wp & + & + (s_cb(i) - s_cb(i - 1))**2._wp + (s_cb(i) - s_cb(i - 1))*(s_cb(i + 1) - s_cb(i))) & + & /((s_cb(i - 2) - s_cb(i))**2._wp*(s_cb(i - 2) - s_cb(i + 1))**2._wp) end do - ! Modifying the ideal weights coefficients in the neighborhood - ! of beginning and end Riemann state extrapolation BC to avoid - ! any contributions from outside of the physical domain during - ! the WENO reconstruction + ! Modifying the ideal weights coefficients in the neighborhood of beginning and end Riemann state extrapolation + ! BC to avoid any contributions from outside of the physical domain during the WENO reconstruction if (null_weights) then if (bc_s%beg == BC_RIEMANN_EXTRAP) then - d_cbR_${XYZ}$ (1:2, 0) = 0._wp; d_cbR_${XYZ}$ (0, 0) = 1._wp - d_cbL_${XYZ}$ (1:2, 0) = 0._wp; d_cbL_${XYZ}$ (0, 0) = 1._wp - d_cbR_${XYZ}$ (2, 1) = 0._wp; d_cbR_${XYZ}$ (:, 1) = d_cbR_${XYZ}$ (:, 1)/sum(d_cbR_${XYZ}$ (:, 1)) - d_cbL_${XYZ}$ (2, 1) = 0._wp; d_cbL_${XYZ}$ (:, 1) = d_cbL_${XYZ}$ (:, 1)/sum(d_cbL_${XYZ}$ (:, 1)) + d_cbR_${XYZ}$ (1:2,0) = 0._wp; d_cbR_${XYZ}$ (0, 0) = 1._wp + d_cbL_${XYZ}$ (1:2,0) = 0._wp; d_cbL_${XYZ}$ (0, 0) = 1._wp + d_cbR_${XYZ}$ (2, 1) = 0._wp; d_cbR_${XYZ}$ (:,1) = d_cbR_${XYZ}$ (:,1)/sum(d_cbR_${XYZ}$ (:,1)) + d_cbL_${XYZ}$ (2, 1) = 0._wp; d_cbL_${XYZ}$ (:,1) = d_cbL_${XYZ}$ (:,1)/sum(d_cbL_${XYZ}$ (:,1)) end if if (bc_s%end == BC_RIEMANN_EXTRAP) then - d_cbR_${XYZ}$ (0, s - 1) = 0._wp; d_cbR_${XYZ}$ (:, s - 1) = d_cbR_${XYZ}$ (:, s - 1)/sum(d_cbR_${XYZ}$ (:, s - 1)) - d_cbL_${XYZ}$ (0, s - 1) = 0._wp; d_cbL_${XYZ}$ (:, s - 1) = d_cbL_${XYZ}$ (:, s - 1)/sum(d_cbL_${XYZ}$ (:, s - 1)) - d_cbR_${XYZ}$ (0:1, s) = 0._wp; d_cbR_${XYZ}$ (2, s) = 1._wp - d_cbL_${XYZ}$ (0:1, s) = 0._wp; d_cbL_${XYZ}$ (2, s) = 1._wp + d_cbR_${XYZ}$ (0, s - 1) = 0._wp; d_cbR_${XYZ}$ (:,s - 1) = d_cbR_${XYZ}$ (:, & + & s - 1)/sum(d_cbR_${XYZ}$ (:,s - 1)) + d_cbL_${XYZ}$ (0, s - 1) = 0._wp; d_cbL_${XYZ}$ (:,s - 1) = d_cbL_${XYZ}$ (:, & + & s - 1)/sum(d_cbL_${XYZ}$ (:,s - 1)) + d_cbR_${XYZ}$ (0:1,s) = 0._wp; d_cbR_${XYZ}$ (2, s) = 1._wp + d_cbL_${XYZ}$ (0:1,s) = 0._wp; d_cbL_${XYZ}$ (2, s) = 1._wp end if end if - - else ! WENO7 - + else ! WENO7 if (.not. teno) then - do i = is%beg - 1 + weno_polyn, is%end - 1 - weno_polyn - - ! Reference: Shu (1997) "Essentially Non-Oscillatory and Weighted Essentially Non-Oscillatory Schemes for Hyperbolic Conservation Laws" - ! Equation 2.20: Polynomial Coefficients (poly_coef_cb) - ! Equation 2.61: Smoothness Indicators (beta_coef) - ! To reduce computational cost, we leverage the fact that all polynomial coefficients in a stencil sum to 1 - ! and compute the polynomial coefficients (poly_coef_cb) for the cell value differences (dvd) instead of the values themselves. - ! The computation of coefficients is further simplified by using grid spacing (y or w) rather than the grid locations (s_cb) directly. - ! Ideal weights (d_cb) are obtained by comparing the grid location coefficients of the polynomial coefficients. - ! The smoothness indicators (beta_coef) are calculated through numerical differentiation and integration of each cross term of the polynomial coefficients, - ! using the cell value differences (dvd) instead of the values themselves. - ! While the polynomial coefficients sum to 1, the derivative of 1 is 0, which means it does not create additional cross terms in the smoothness indicators. - - w = s_cb(i - 3:i + 4) - s_cb(i) ! Offset using s_cb(i) to reduce floating point error - d_cbR_${XYZ}$ (0, i + 1) = ((w(5) - w(6))*(w(5) - w(7))*(w(5) - w(8)))/((w(1) - w(6))*(w(1) - w(7))*(w(1) - w(8))) !& - d_cbR_${XYZ}$ (1, i + 1) = ((w(1) - w(5))*(w(5) - w(7))*(w(5) - w(8))*(w(1)*w(2) - w(1)*w(6) - w(1)*w(7) - w(2)*w(6) - w(1)*w(8) - w(2)*w(7) - w(2)*w(8) + w(6)*w(7) + w(6)*w(8) + w(7)*w(8) + w(1)**2 + w(2)**2))/((w(1) - w(6))*(w(1) - w(7))*(w(1) - w(8))*(w(2) - w(7))*(w(2) - w(8))) !& - d_cbR_${XYZ}$ (2, i + 1) = ((w(1) - w(5))*(w(2) - w(5))*(w(5) - w(8))*(w(1)*w(2) + w(1)*w(3) + w(2)*w(3) - w(1)*w(7) - w(1)*w(8) - w(2)*w(7) - w(2)*w(8) - w(3)*w(7) - w(3)*w(8) + w(7)*w(8) + w(7)**2 + w(8)**2))/((w(1) - w(7))*(w(1) - w(8))*(w(2) - w(7))*(w(2) - w(8))*(w(3) - w(8))) !& - d_cbR_${XYZ}$ (3, i + 1) = ((w(1) - w(5))*(w(2) - w(5))*(w(3) - w(5)))/((w(1) - w(8))*(w(2) - w(8))*(w(3) - w(8))) !& + ! Reference: Shu (1997) "Essentially Non-Oscillatory and Weighted Essentially Non-Oscillatory Schemes + ! for Hyperbolic Conservation Laws" Equation 2.20: Polynomial Coefficients (poly_coef_cb) Equation 2.61: + ! Smoothness Indicators (beta_coef) To reduce computational cost, we leverage the fact that all + ! polynomial coefficients in a stencil sum to 1 and compute the polynomial coefficients (poly_coef_cb) + ! for the cell value differences (dvd) instead of the values themselves. The computation of coefficients + ! is further simplified by using grid spacing (y or w) rather than the grid locations (s_cb) directly. + ! Ideal weights (d_cb) are obtained by comparing the grid location coefficients of the polynomial + ! coefficients. The smoothness indicators (beta_coef) are calculated through numerical differentiation + ! and integration of each cross term of the polynomial coefficients, using the cell value differences + ! (dvd) instead of the values themselves. While the polynomial coefficients sum to 1, the derivative of + ! 1 is 0, which means it does not create additional cross terms in the smoothness indicators. + + w = s_cb(i - 3:i + 4) - s_cb(i) ! Offset using s_cb(i) to reduce floating point error + d_cbR_${XYZ}$ (0, & + & i + 1) = ((w(5) - w(6))*(w(5) - w(7))*(w(5) - w(8)))/((w(1) - w(6))*(w(1) - w(7)) & + & *(w(1) - w(8))) + d_cbR_${XYZ}$ (1, & + & i + 1) = ((w(1) - w(5))*(w(5) - w(7))*(w(5) - w(8))*(w(1)*w(2) - w(1)*w(6) - w(1) & + & *w(7) - w(2)*w(6) - w(1)*w(8) - w(2)*w(7) - w(2)*w(8) + w(6)*w(7) + w(6)*w(8) + w(7) & + & *w(8) + w(1)**2 + w(2)**2))/((w(1) - w(6))*(w(1) - w(7))*(w(1) - w(8))*(w(2) - w(7)) & + & *(w(2) - w(8))) + d_cbR_${XYZ}$ (2, & + & i + 1) = ((w(1) - w(5))*(w(2) - w(5))*(w(5) - w(8))*(w(1)*w(2) + w(1)*w(3) + w(2) & + & *w(3) - w(1)*w(7) - w(1)*w(8) - w(2)*w(7) - w(2)*w(8) - w(3)*w(7) - w(3)*w(8) + w(7) & + & *w(8) + w(7)**2 + w(8)**2))/((w(1) - w(7))*(w(1) - w(8))*(w(2) - w(7))*(w(2) - w(8)) & + & *(w(3) - w(8))) + d_cbR_${XYZ}$ (3, & + & i + 1) = ((w(1) - w(5))*(w(2) - w(5))*(w(3) - w(5)))/((w(1) - w(8))*(w(2) - w(8)) & + & *(w(3) - w(8))) w = s_cb(i + 4:i - 3:-1) - s_cb(i) - d_cbL_${XYZ}$ (0, i + 1) = ((w(1) - w(5))*(w(2) - w(5))*(w(3) - w(5)))/((w(1) - w(8))*(w(2) - w(8))*(w(3) - w(8))) !& - d_cbL_${XYZ}$ (1, i + 1) = ((w(1) - w(5))*(w(2) - w(5))*(w(5) - w(8))*(w(1)*w(2) + w(1)*w(3) + w(2)*w(3) - w(1)*w(7) - w(1)*w(8) - w(2)*w(7) - w(2)*w(8) - w(3)*w(7) - w(3)*w(8) + w(7)*w(8) + w(7)**2 + w(8)**2))/((w(1) - w(7))*(w(1) - w(8))*(w(2) - w(7))*(w(2) - w(8))*(w(3) - w(8))) !& - d_cbL_${XYZ}$ (2, i + 1) = ((w(1) - w(5))*(w(5) - w(7))*(w(5) - w(8))*(w(1)*w(2) - w(1)*w(6) - w(1)*w(7) - w(2)*w(6) - w(1)*w(8) - w(2)*w(7) - w(2)*w(8) + w(6)*w(7) + w(6)*w(8) + w(7)*w(8) + w(1)**2 + w(2)**2))/((w(1) - w(6))*(w(1) - w(7))*(w(1) - w(8))*(w(2) - w(7))*(w(2) - w(8))) !& - d_cbL_${XYZ}$ (3, i + 1) = ((w(5) - w(6))*(w(5) - w(7))*(w(5) - w(8)))/((w(1) - w(6))*(w(1) - w(7))*(w(1) - w(8))) !& + d_cbL_${XYZ}$ (0, & + & i + 1) = ((w(1) - w(5))*(w(2) - w(5))*(w(3) - w(5)))/((w(1) - w(8))*(w(2) - w(8)) & + & *(w(3) - w(8))) + d_cbL_${XYZ}$ (1, & + & i + 1) = ((w(1) - w(5))*(w(2) - w(5))*(w(5) - w(8))*(w(1)*w(2) + w(1)*w(3) + w(2) & + & *w(3) - w(1)*w(7) - w(1)*w(8) - w(2)*w(7) - w(2)*w(8) - w(3)*w(7) - w(3)*w(8) + w(7) & + & *w(8) + w(7)**2 + w(8)**2))/((w(1) - w(7))*(w(1) - w(8))*(w(2) - w(7))*(w(2) - w(8)) & + & *(w(3) - w(8))) + d_cbL_${XYZ}$ (2, & + & i + 1) = ((w(1) - w(5))*(w(5) - w(7))*(w(5) - w(8))*(w(1)*w(2) - w(1)*w(6) - w(1) & + & *w(7) - w(2)*w(6) - w(1)*w(8) - w(2)*w(7) - w(2)*w(8) + w(6)*w(7) + w(6)*w(8) + w(7) & + & *w(8) + w(1)**2 + w(2)**2))/((w(1) - w(6))*(w(1) - w(7))*(w(1) - w(8))*(w(2) - w(7)) & + & *(w(2) - w(8))) + d_cbL_${XYZ}$ (3, & + & i + 1) = ((w(5) - w(6))*(w(5) - w(7))*(w(5) - w(8)))/((w(1) - w(6))*(w(1) - w(7)) & + & *(w(1) - w(8))) ! Note: Left has the reversed order of both points and coefficients compared to the right y = s_cb(i + 1:i + 4) - s_cb(i:i + 3) - poly_coef_cbR_${XYZ}$ (i + 1, 0, 0) = (y(1)*y(2)*(y(2) + y(3)))/((y(3) + y(4))*(y(2) + y(3) + y(4))*(y(1) + y(2) + y(3) + y(4))) !& - poly_coef_cbR_${XYZ}$ (i + 1, 0, 1) = -(y(1)*y(2)*(3*y(2)**2 + 6*y(2)*y(3) + 3*y(2)*y(4) + 2*y(1)*y(2) + 3*y(3)**2 + 3*y(3)*y(4) + 2*y(1)*y(3) + y(4)**2 + y(1)*y(4)))/((y(2) + y(3))*(y(1) + y(2) + y(3))*(y(2) + y(3) + y(4))*(y(1) + y(2) + y(3) + y(4))) !& - poly_coef_cbR_${XYZ}$ (i + 1, 0, 2) = (y(1)*(y(1)**2 + 3*y(1)*y(2) + 2*y(1)*y(3) + y(4)*y(1) + 3*y(2)**2 + 4*y(2)*y(3) + 2*y(4)*y(2) + y(3)**2 + y(4)*y(3)))/((y(1) + y(2))*(y(1) + y(2) + y(3))*(y(1) + y(2) + y(3) + y(4))) !& + poly_coef_cbR_${XYZ}$ (i + 1, 0, & + & 0) = (y(1)*y(2)*(y(2) + y(3)))/((y(3) + y(4))*(y(2) + y(3) + y(4))*(y(1) & + & + y(2) + y(3) + y(4))) + poly_coef_cbR_${XYZ}$ (i + 1, 0, & + & 1) = -(y(1)*y(2)*(3*y(2)**2 + 6*y(2)*y(3) + 3*y(2)*y(4) + 2*y(1)*y(2) & + & + 3*y(3)**2 + 3*y(3)*y(4) + 2*y(1)*y(3) + y(4)**2 + y(1)*y(4)))/((y(2) + y(3) & + & )*(y(1) + y(2) + y(3))*(y(2) + y(3) + y(4))*(y(1) + y(2) + y(3) + y(4))) + poly_coef_cbR_${XYZ}$ (i + 1, 0, & + & 2) = (y(1)*(y(1)**2 + 3*y(1)*y(2) + 2*y(1)*y(3) + y(4)*y(1) + 3*y(2)**2 & + & + 4*y(2)*y(3) + 2*y(4)*y(2) + y(3)**2 + y(4)*y(3)))/((y(1) + y(2))*(y(1) & + & + y(2) + y(3))*(y(1) + y(2) + y(3) + y(4))) y = s_cb(i:i + 3) - s_cb(i - 1:i + 2) - poly_coef_cbR_${XYZ}$ (i + 1, 1, 0) = -(y(2)*y(3)*(y(1) + y(2)))/((y(3) + y(4))*(y(2) + y(3) + y(4))*(y(1) + y(2) + y(3) + y(4))) !& - poly_coef_cbR_${XYZ}$ (i + 1, 1, 1) = (y(2)*(y(1) + y(2))*(y(2)**2 + 4*y(2)*y(3) + 2*y(2)*y(4) + y(1)*y(2) + 3*y(3)**2 + 3*y(3)*y(4) + 2*y(1)*y(3) + y(4)**2 + y(1)*y(4)))/((y(2) + y(3))*(y(1) + y(2) + y(3))*(y(2) + y(3) + y(4))*(y(1) + y(2) + y(3) + y(4))) !& - poly_coef_cbR_${XYZ}$ (i + 1, 1, 2) = (y(2)*y(3)*(y(3) + y(4)))/((y(1) + y(2))*(y(1) + y(2) + y(3))*(y(1) + y(2) + y(3) + y(4))) !& + poly_coef_cbR_${XYZ}$ (i + 1, 1, & + & 0) = -(y(2)*y(3)*(y(1) + y(2)))/((y(3) + y(4))*(y(2) + y(3) + y(4))*(y(1) & + & + y(2) + y(3) + y(4))) + poly_coef_cbR_${XYZ}$ (i + 1, 1, & + & 1) = (y(2)*(y(1) + y(2))*(y(2)**2 + 4*y(2)*y(3) + 2*y(2)*y(4) + y(1)*y(2) & + & + 3*y(3)**2 + 3*y(3)*y(4) + 2*y(1)*y(3) + y(4)**2 + y(1)*y(4)))/((y(2) + y(3) & + & )*(y(1) + y(2) + y(3))*(y(2) + y(3) + y(4))*(y(1) + y(2) + y(3) + y(4))) + poly_coef_cbR_${XYZ}$ (i + 1, 1, & + & 2) = (y(2)*y(3)*(y(3) + y(4)))/((y(1) + y(2))*(y(1) + y(2) + y(3))*(y(1) & + & + y(2) + y(3) + y(4))) y = s_cb(i - 1:i + 2) - s_cb(i - 2:i + 1) - poly_coef_cbR_${XYZ}$ (i + 1, 2, 0) = (y(3)*(y(2) + y(3))*(y(1) + y(2) + y(3)))/((y(3) + y(4))*(y(2) + y(3) + y(4))*(y(1) + y(2) + y(3) + y(4))) !& - poly_coef_cbR_${XYZ}$ (i + 1, 2, 1) = (y(3)*y(4)*(y(1)**2 + 3*y(1)*y(2) + 3*y(1)*y(3) + y(4)*y(1) + 3*y(2)**2 + 6*y(2)*y(3) + 2*y(4)*y(2) + 3*y(3)**2 + 2*y(4)*y(3)))/((y(2) + y(3))*(y(1) + y(2) + y(3))*(y(2) + y(3) + y(4))*(y(1) + y(2) + y(3) + y(4))) !& - poly_coef_cbR_${XYZ}$ (i + 1, 2, 2) = -(y(3)*y(4)*(y(2) + y(3)))/((y(1) + y(2))*(y(1) + y(2) + y(3))*(y(1) + y(2) + y(3) + y(4))) !& + poly_coef_cbR_${XYZ}$ (i + 1, 2, & + & 0) = (y(3)*(y(2) + y(3))*(y(1) + y(2) + y(3)))/((y(3) + y(4))*(y(2) + y(3) & + & + y(4))*(y(1) + y(2) + y(3) + y(4))) + poly_coef_cbR_${XYZ}$ (i + 1, 2, & + & 1) = (y(3)*y(4)*(y(1)**2 + 3*y(1)*y(2) + 3*y(1)*y(3) + y(4)*y(1) + 3*y(2)**2 & + & + 6*y(2)*y(3) + 2*y(4)*y(2) + 3*y(3)**2 + 2*y(4)*y(3)))/((y(2) + y(3))*(y(1) & + & + y(2) + y(3))*(y(2) + y(3) + y(4))*(y(1) + y(2) + y(3) + y(4))) + poly_coef_cbR_${XYZ}$ (i + 1, 2, & + & 2) = -(y(3)*y(4)*(y(2) + y(3)))/((y(1) + y(2))*(y(1) + y(2) + y(3))*(y(1) & + & + y(2) + y(3) + y(4))) y = s_cb(i - 2:i + 1) - s_cb(i - 3:i) - poly_coef_cbR_${XYZ}$ (i + 1, 3, 0) = (y(4)*(y(2)**2 + 4*y(2)*y(3) + 4*y(2)*y(4) + y(1)*y(2) + 3*y(3)**2 + 6*y(3)*y(4) + 2*y(1)*y(3) + 3*y(4)**2 + 2*y(1)*y(4)))/((y(3) + y(4))*(y(2) + y(3) + y(4))*(y(1) + y(2) + y(3) + y(4))) !& - poly_coef_cbR_${XYZ}$ (i + 1, 3, 1) = -(y(4)*(y(3) + y(4))*(y(1)**2 + 3*y(1)*y(2) + 3*y(1)*y(3) + 2*y(1)*y(4) + 3*y(2)**2 + 6*y(2)*y(3) + 4*y(2)*y(4) + 3*y(3)**2 + 4*y(3)*y(4) + y(4)**2))/((y(2) + y(3))*(y(1) + y(2) + y(3))*(y(2) + y(3) + y(4))*(y(1) + y(2) + y(3) + y(4))) !& - poly_coef_cbR_${XYZ}$ (i + 1, 3, 2) = (y(4)*(y(3) + y(4))*(y(2) + y(3) + y(4)))/((y(1) + y(2))*(y(1) + y(2) + y(3))*(y(1) + y(2) + y(3) + y(4))) !& + poly_coef_cbR_${XYZ}$ (i + 1, 3, & + & 0) = (y(4)*(y(2)**2 + 4*y(2)*y(3) + 4*y(2)*y(4) + y(1)*y(2) + 3*y(3)**2 & + & + 6*y(3)*y(4) + 2*y(1)*y(3) + 3*y(4)**2 + 2*y(1)*y(4)))/((y(3) + y(4))*(y(2) & + & + y(3) + y(4))*(y(1) + y(2) + y(3) + y(4))) + poly_coef_cbR_${XYZ}$ (i + 1, 3, & + & 1) = -(y(4)*(y(3) + y(4))*(y(1)**2 + 3*y(1)*y(2) + 3*y(1)*y(3) + 2*y(1)*y(4) & + & + 3*y(2)**2 + 6*y(2)*y(3) + 4*y(2)*y(4) + 3*y(3)**2 + 4*y(3)*y(4) + y(4)**2)) & + & /((y(2) + y(3))*(y(1) + y(2) + y(3))*(y(2) + y(3) + y(4))*(y(1) + y(2) + y(3) & + & + y(4))) + poly_coef_cbR_${XYZ}$ (i + 1, 3, & + & 2) = (y(4)*(y(3) + y(4))*(y(2) + y(3) + y(4)))/((y(1) + y(2))*(y(1) + y(2) & + & + y(3))*(y(1) + y(2) + y(3) + y(4))) y = s_cb(i + 1:i - 2:-1) - s_cb(i:i - 3:-1) - poly_coef_cbL_${XYZ}$ (i + 1, 3, 2) = (y(1)*y(2)*(y(2) + y(3)))/((y(3) + y(4))*(y(2) + y(3) + y(4))*(y(1) + y(2) + y(3) + y(4))) !& - poly_coef_cbL_${XYZ}$ (i + 1, 3, 1) = -(y(1)*y(2)*(3*y(2)**2 + 6*y(2)*y(3) + 3*y(2)*y(4) + 2*y(1)*y(2) + 3*y(3)**2 + 3*y(3)*y(4) + 2*y(1)*y(3) + y(4)**2 + y(1)*y(4)))/((y(2) + y(3))*(y(1) + y(2) + y(3))*(y(2) + y(3) + y(4))*(y(1) + y(2) + y(3) + y(4))) !& - poly_coef_cbL_${XYZ}$ (i + 1, 3, 0) = (y(1)*(y(1)**2 + 3*y(1)*y(2) + 2*y(1)*y(3) + y(4)*y(1) + 3*y(2)**2 + 4*y(2)*y(3) + 2*y(4)*y(2) + y(3)**2 + y(4)*y(3)))/((y(1) + y(2))*(y(1) + y(2) + y(3))*(y(1) + y(2) + y(3) + y(4))) !& + poly_coef_cbL_${XYZ}$ (i + 1, 3, & + & 2) = (y(1)*y(2)*(y(2) + y(3)))/((y(3) + y(4))*(y(2) + y(3) + y(4))*(y(1) & + & + y(2) + y(3) + y(4))) + poly_coef_cbL_${XYZ}$ (i + 1, 3, & + & 1) = -(y(1)*y(2)*(3*y(2)**2 + 6*y(2)*y(3) + 3*y(2)*y(4) + 2*y(1)*y(2) & + & + 3*y(3)**2 + 3*y(3)*y(4) + 2*y(1)*y(3) + y(4)**2 + y(1)*y(4)))/((y(2) + y(3) & + & )*(y(1) + y(2) + y(3))*(y(2) + y(3) + y(4))*(y(1) + y(2) + y(3) + y(4))) + poly_coef_cbL_${XYZ}$ (i + 1, 3, & + & 0) = (y(1)*(y(1)**2 + 3*y(1)*y(2) + 2*y(1)*y(3) + y(4)*y(1) + 3*y(2)**2 & + & + 4*y(2)*y(3) + 2*y(4)*y(2) + y(3)**2 + y(4)*y(3)))/((y(1) + y(2))*(y(1) & + & + y(2) + y(3))*(y(1) + y(2) + y(3) + y(4))) y = s_cb(i + 2:i - 1:-1) - s_cb(i + 1:i - 2:-1) - poly_coef_cbL_${XYZ}$ (i + 1, 2, 2) = -(y(2)*y(3)*(y(1) + y(2)))/((y(3) + y(4))*(y(2) + y(3) + y(4))*(y(1) + y(2) + y(3) + y(4))) !& - poly_coef_cbL_${XYZ}$ (i + 1, 2, 1) = (y(2)*(y(1) + y(2))*(y(2)**2 + 4*y(2)*y(3) + 2*y(2)*y(4) + y(1)*y(2) + 3*y(3)**2 + 3*y(3)*y(4) + 2*y(1)*y(3) + y(4)**2 + y(1)*y(4)))/((y(2) + y(3))*(y(1) + y(2) + y(3))*(y(2) + y(3) + y(4))*(y(1) + y(2) + y(3) + y(4))) !& - poly_coef_cbL_${XYZ}$ (i + 1, 2, 0) = (y(2)*y(3)*(y(3) + y(4)))/((y(1) + y(2))*(y(1) + y(2) + y(3))*(y(1) + y(2) + y(3) + y(4))) !& + poly_coef_cbL_${XYZ}$ (i + 1, 2, & + & 2) = -(y(2)*y(3)*(y(1) + y(2)))/((y(3) + y(4))*(y(2) + y(3) + y(4))*(y(1) & + & + y(2) + y(3) + y(4))) + poly_coef_cbL_${XYZ}$ (i + 1, 2, & + & 1) = (y(2)*(y(1) + y(2))*(y(2)**2 + 4*y(2)*y(3) + 2*y(2)*y(4) + y(1)*y(2) & + & + 3*y(3)**2 + 3*y(3)*y(4) + 2*y(1)*y(3) + y(4)**2 + y(1)*y(4)))/((y(2) + y(3) & + & )*(y(1) + y(2) + y(3))*(y(2) + y(3) + y(4))*(y(1) + y(2) + y(3) + y(4))) + poly_coef_cbL_${XYZ}$ (i + 1, 2, & + & 0) = (y(2)*y(3)*(y(3) + y(4)))/((y(1) + y(2))*(y(1) + y(2) + y(3))*(y(1) & + & + y(2) + y(3) + y(4))) y = s_cb(i + 3:i:-1) - s_cb(i + 2:i - 1:-1) - poly_coef_cbL_${XYZ}$ (i + 1, 1, 2) = (y(3)*(y(2) + y(3))*(y(1) + y(2) + y(3)))/((y(3) + y(4))*(y(2) + y(3) + y(4))*(y(1) + y(2) + y(3) + y(4))) !& - poly_coef_cbL_${XYZ}$ (i + 1, 1, 1) = (y(3)*y(4)*(y(1)**2 + 3*y(1)*y(2) + 3*y(1)*y(3) + y(4)*y(1) + 3*y(2)**2 + 6*y(2)*y(3) + 2*y(4)*y(2) + 3*y(3)**2 + 2*y(4)*y(3)))/((y(2) + y(3))*(y(1) + y(2) + y(3))*(y(2) + y(3) + y(4))*(y(1) + y(2) + y(3) + y(4))) !& - poly_coef_cbL_${XYZ}$ (i + 1, 1, 0) = -(y(3)*y(4)*(y(2) + y(3)))/((y(1) + y(2))*(y(1) + y(2) + y(3))*(y(1) + y(2) + y(3) + y(4))) !& + poly_coef_cbL_${XYZ}$ (i + 1, 1, & + & 2) = (y(3)*(y(2) + y(3))*(y(1) + y(2) + y(3)))/((y(3) + y(4))*(y(2) + y(3) & + & + y(4))*(y(1) + y(2) + y(3) + y(4))) + poly_coef_cbL_${XYZ}$ (i + 1, 1, & + & 1) = (y(3)*y(4)*(y(1)**2 + 3*y(1)*y(2) + 3*y(1)*y(3) + y(4)*y(1) + 3*y(2)**2 & + & + 6*y(2)*y(3) + 2*y(4)*y(2) + 3*y(3)**2 + 2*y(4)*y(3)))/((y(2) + y(3))*(y(1) & + & + y(2) + y(3))*(y(2) + y(3) + y(4))*(y(1) + y(2) + y(3) + y(4))) + poly_coef_cbL_${XYZ}$ (i + 1, 1, & + & 0) = -(y(3)*y(4)*(y(2) + y(3)))/((y(1) + y(2))*(y(1) + y(2) + y(3))*(y(1) & + & + y(2) + y(3) + y(4))) y = s_cb(i + 4:i + 1:-1) - s_cb(i + 3:i:-1) - poly_coef_cbL_${XYZ}$ (i + 1, 0, 2) = (y(4)*(y(2)**2 + 4*y(2)*y(3) + 4*y(2)*y(4) + y(1)*y(2) + 3*y(3)**2 + 6*y(3)*y(4) + 2*y(1)*y(3) + 3*y(4)**2 + 2*y(1)*y(4)))/((y(3) + y(4))*(y(2) + y(3) + y(4))*(y(1) + y(2) + y(3) + y(4))) !& - poly_coef_cbL_${XYZ}$ (i + 1, 0, 1) = -(y(4)*(y(3) + y(4))*(y(1)**2 + 3*y(1)*y(2) + 3*y(1)*y(3) + 2*y(1)*y(4) + 3*y(2)**2 + 6*y(2)*y(3) + 4*y(2)*y(4) + 3*y(3)**2 + 4*y(3)*y(4) + y(4)**2))/((y(2) + y(3))*(y(1) + y(2) + y(3))*(y(2) + y(3) + y(4))*(y(1) + y(2) + y(3) + y(4))) !& - poly_coef_cbL_${XYZ}$ (i + 1, 0, 0) = (y(4)*(y(3) + y(4))*(y(2) + y(3) + y(4)))/((y(1) + y(2))*(y(1) + y(2) + y(3))*(y(1) + y(2) + y(3) + y(4))) !& - - poly_coef_cbL_${XYZ}$ (i + 1, :, :) = -poly_coef_cbL_${XYZ}$ (i + 1, :, :) + poly_coef_cbL_${XYZ}$ (i + 1, 0, & + & 2) = (y(4)*(y(2)**2 + 4*y(2)*y(3) + 4*y(2)*y(4) + y(1)*y(2) + 3*y(3)**2 & + & + 6*y(3)*y(4) + 2*y(1)*y(3) + 3*y(4)**2 + 2*y(1)*y(4)))/((y(3) + y(4))*(y(2) & + & + y(3) + y(4))*(y(1) + y(2) + y(3) + y(4))) + poly_coef_cbL_${XYZ}$ (i + 1, 0, & + & 1) = -(y(4)*(y(3) + y(4))*(y(1)**2 + 3*y(1)*y(2) + 3*y(1)*y(3) + 2*y(1)*y(4) & + & + 3*y(2)**2 + 6*y(2)*y(3) + 4*y(2)*y(4) + 3*y(3)**2 + 4*y(3)*y(4) + y(4)**2)) & + & /((y(2) + y(3))*(y(1) + y(2) + y(3))*(y(2) + y(3) + y(4))*(y(1) + y(2) + y(3) & + & + y(4))) + poly_coef_cbL_${XYZ}$ (i + 1, 0, & + & 0) = (y(4)*(y(3) + y(4))*(y(2) + y(3) + y(4)))/((y(1) + y(2))*(y(1) + y(2) & + & + y(3))*(y(1) + y(2) + y(3) + y(4))) + + poly_coef_cbL_${XYZ}$ (i + 1,:,:) = -poly_coef_cbL_${XYZ}$ (i + 1,:,:) ! Note: negative sign as the direction of taking the difference (dvd) is reversed y = s_cb(i - 2:i + 1) - s_cb(i - 3:i) - beta_coef_${XYZ}$ (i + 1, 3, 0) = (4*y(4)**2*(5*y(1)**2*y(2)**2 + 20*y(1)**2*y(2)*y(3) + 15*y(1)**2*y(2)*y(4) + 20*y(1)**2*y(3)**2 + 30*y(1)**2*y(3)*y(4) + 60*y(1)**2*y(4)**2 + 10*y(1)*y(2)**3 + 60*y(1)*y(2)**2*y(3) + 45*y(1)*y(2)**2*y(4) + 110*y(1)*y(2)*y(3)**2 + 165*y(1)*y(2)*y(3)*y(4) & !& - + 260*y(1)*y(2)*y(4)**2 + 60*y(1)*y(3)**3 + 135*y(1)*y(3)**2*y(4) + 400*y(1)*y(3)*y(4)**2 + 225*y(1)*y(4)**3 + 5*y(2)**4 + 40*y(2)**3*y(3) + 30*y(2)**3*y(4) + 110*y(2)**2*y(3)**2 + 165*y(2)**2*y(3)*y(4) + 260*y(2)**2*y(4)**2 + 120*y(2)*y(3)**3 & !& - + 270*y(2)*y(3)**2*y(4) + 800*y(2)*y(3)*y(4)**2 + 450*y(2)*y(4)**3 + 45*y(3)**4 + 135*y(3)**3*y(4) + 600*y(3)**2*y(4)**2 + 675*y(3)*y(4)**3 + 996*y(4)**4))/(5*(y(3) + y(4))**2*(y(2) + y(3) + y(4))**2*(y(1) + y(2) + y(3) + y(4))**2) !& - beta_coef_${XYZ}$ (i + 1, 3, 1) = -(4*y(4)**2*(10*y(1)**3*y(2)*y(3) + 5*y(1)**3*y(2)*y(4) + 20*y(1)**3*y(3)**2 + 25*y(1)**3*y(3)*y(4) + 105*y(1)**3*y(4)**2 + 40*y(1)**2*y(2)**2*y(3) + 20*y(1)**2*y(2)**2*y(4) + 130*y(1)**2*y(2)*y(3)**2 + 155*y(1)**2*y(2)*y(3)*y(4) + 535*y(1)**2*y(2)*y(4)**2 & !& - + 90*y(1)**2*y(3)**3 + 165*y(1)**2*y(3)**2*y(4) + 790*y(1)**2*y(3)*y(4)**2 + 415*y(1)**2*y(4)**3 + 60*y(1)*y(2)**3*y(3) + 30*y(1)*y(2)**3*y(4) + 270*y(1)*y(2)**2*y(3)**2 + 315*y(1)*y(2)**2*y(3)*y(4) + 975*y(1)*y(2)**2*y(4)**2 + 360*y(1)*y(2)*y(3)**3 & !& - + 645*y(1)*y(2)*y(3)**2*y(4) + 2850*y(1)*y(2)*y(3)*y(4)**2 + 1460*y(1)*y(2)*y(4)**3 + 150*y(1)*y(3)**4 + 360*y(1)*y(3)**3*y(4) + 2000*y(1)*y(3)**2*y(4)**2 + 2005*y(1)*y(3)*y(4)**3 + 2077*y(1)*y(4)**4 + 30*y(2)**4*y(3) + 15*y(2)**4*y(4) + 180*y(2)**3*y(3)**2 & !& - + 210*y(2)**3*y(3)*y(4) + 650*y(2)**3*y(4)**2 + 360*y(2)**2*y(3)**3 + 645*y(2)**2*y(3)**2*y(4) + 2850*y(2)**2*y(3)*y(4)**2 + 1460*y(2)**2*y(4)**3 + 300*y(2)*y(3)**4 + 720*y(2)*y(3)**3*y(4) + 4000*y(2)*y(3)**2*y(4)**2 + 4010*y(2)*y(3)*y(4)**3 + 4154*y(2)*y(4)**4 & !& - + 90*y(3)**5 + 270*y(3)**4*y(4) + 1800*y(3)**3*y(4)**2 + 2655*y(3)**2*y(4)**3 + 4464*y(3)*y(4)**4 + 1767*y(4)**5))/(5*(y(2) + y(3))*(y(3) + y(4))*(y(1) + y(2) + y(3))*(y(2) + y(3) + y(4))**2*(y(1) + y(2) + y(3) + y(4))**2) !& - beta_coef_${XYZ}$ (i + 1, 3, 2) = (4*y(4)**2*(10*y(2)**3*y(3) + 5*y(2)**3*y(4) + 50*y(2)**2*y(3)**2 + 60*y(2)**2*y(3)*y(4) + 10*y(1)*y(2)**2*y(3) + 215*y(2)**2*y(4)**2 + 5*y(1)*y(2)**2*y(4) + 70*y(2)*y(3)**3 + 130*y(2)*y(3)**2*y(4) + 30*y(1)*y(2)*y(3)**2 + 775*y(2)*y(3)*y(4)**2 & !& - + 35*y(1)*y(2)*y(3)*y(4) + 415*y(2)*y(4)**3 + 110*y(1)*y(2)*y(4)**2 + 30*y(3)**4 + 75*y(3)**3*y(4) + 20*y(1)*y(3)**3 + 665*y(3)**2*y(4)**2 + 35*y(1)*y(3)**2*y(4) + 725*y(3)*y(4)**3 + 220*y(1)*y(3)*y(4)**2 + 1767*y(4)**4 + 105*y(1)*y(4)**3)) & !& - /(5*(y(1) + y(2))*(y(3) + y(4))*(y(1) + y(2) + y(3))*(y(2) + y(3) + y(4))*(y(1) + y(2) + y(3) + y(4))**2) !& - beta_coef_${XYZ}$ (i + 1, 3, 3) = (4*y(4)**2*(5*y(1)**4*y(3)**2 + 5*y(1)**4*y(3)*y(4) + 50*y(1)**4*y(4)**2 + 30*y(1)**3*y(2)*y(3)**2 + 30*y(1)**3*y(2)*y(3)*y(4) + 300*y(1)**3*y(2)*y(4)**2 + 30*y(1)**3*y(3)**3 + 45*y(1)**3*y(3)**2*y(4) + 415*y(1)**3*y(3)*y(4)**2 + 200*y(1)**3*y(4)**3 & !& - + 75*y(1)**2*y(2)**2*y(3)**2 + 75*y(1)**2*y(2)**2*y(3)*y(4) + 750*y(1)**2*y(2)**2*y(4)**2 + 150*y(1)**2*y(2)*y(3)**3 + 225*y(1)**2*y(2)*y(3)**2*y(4) + 2075*y(1)**2*y(2)*y(3)*y(4)**2 + 1000*y(1)**2*y(2)*y(4)**3 + 75*y(1)**2*y(3)**4 + 150*y(1)**2*y(3)**3*y(4) & !& - + 1390*y(1)**2*y(3)**2*y(4)**2 + 1315*y(1)**2*y(3)*y(4)**3 + 1081*y(1)**2*y(4)**4 + 90*y(1)*y(2)**3*y(3)**2 + 90*y(1)*y(2)**3*y(3)*y(4) + 900*y(1)*y(2)**3*y(4)**2 + 270*y(1)*y(2)**2*y(3)**3 + 405*y(1)*y(2)**2*y(3)**2*y(4) + 3735*y(1)*y(2)**2*y(3)*y(4)**2 & !& - + 1800*y(1)*y(2)**2*y(4)**3 + 270*y(1)*y(2)*y(3)**4 + 540*y(1)*y(2)*y(3)**3*y(4) + 5025*y(1)*y(2)*y(3)**2*y(4)**2 + 4755*y(1)*y(2)*y(3)*y(4)**3 + 4224*y(1)*y(2)*y(4)**4 + 90*y(1)*y(3)**5 + 225*y(1)*y(3)**4*y(4) + 2190*y(1)*y(3)**3*y(4)**2 + 3060*y(1)*y(3)**2*y(4)**3 & !& - + 4529*y(1)*y(3)*y(4)**4 + 1762*y(1)*y(4)**5 + 45*y(2)**4*y(3)**2 + 45*y(2)**4*y(3)*y(4) + 450*y(2)**4*y(4)**2 + 180*y(2)**3*y(3)**3 + 270*y(2)**3*y(3)**2*y(4) + 2490*y(2)**3*y(3)*y(4)**2 + 1200*y(2)**3*y(4)**3 + 270*y(2)**2*y(3)**4 + 540*y(2)**2*y(3)**3*y(4) & !& - + 5025*y(2)**2*y(3)**2*y(4)**2 + 4755*y(2)**2*y(3)*y(4)**3 + 4224*y(2)**2*y(4)**4 + 180*y(2)*y(3)**5 + 450*y(2)*y(3)**4*y(4) + 4380*y(2)*y(3)**3*y(4)**2 + 6120*y(2)*y(3)**2*y(4)**3 + 9058*y(2)*y(3)*y(4)**4 + 3524*y(2)*y(4)**5 + 45*y(3)**6 + 135*y(3)**5*y(4) & !& - + 1395*y(3)**4*y(4)**2 + 2565*y(3)**3*y(4)**3 + 4884*y(3)**2*y(4)**4 + 3624*y(3)*y(4)**5 + 831*y(4)**6))/(5*(y(2) + y(3))**2*(y(1) + y(2) + y(3))**2*(y(2) + y(3) + y(4))**2*(y(1) + y(2) + y(3) + y(4))**2) !& - beta_coef_${XYZ}$ (i + 1, 3, 4) = -(4*y(4)**2*(10*y(1)**2*y(2)*y(3)**2 + 10*y(1)**2*y(2)*y(3)*y(4) + 100*y(1)**2*y(2)*y(4)**2 + 10*y(1)**2*y(3)**3 + 15*y(1)**2*y(3)**2*y(4) + 205*y(1)**2*y(3)*y(4)**2 + 100*y(1)**2*y(4)**3 + 30*y(1)*y(2)**2*y(3)**2 + 30*y(1)*y(2)**2*y(3)*y(4) & !& - + 300*y(1)*y(2)**2*y(4)**2 + 60*y(1)*y(2)*y(3)**3 + 90*y(1)*y(2)*y(3)**2*y(4) + 1030*y(1)*y(2)*y(3)*y(4)**2 + 500*y(1)*y(2)*y(4)**3 + 30*y(1)*y(3)**4 + 60*y(1)*y(3)**3*y(4) + 835*y(1)*y(3)**2*y(4)**2 + 805*y(1)*y(3)*y(4)**3 + 1762*y(1)*y(4)**4 + 30*y(2)**3*y(3)**2 & !& - + 30*y(2)**3*y(3)*y(4) + 300*y(2)**3*y(4)**2 + 90*y(2)**2*y(3)**3 + 135*y(2)**2*y(3)**2*y(4) + 1445*y(2)**2*y(3)*y(4)**2 + 700*y(2)**2*y(4)**3 + 90*y(2)*y(3)**4 + 180*y(2)*y(3)**3*y(4) + 2205*y(2)*y(3)**2*y(4)**2 + 2115*y(2)*y(3)*y(4)**3 + 3624*y(2)*y(4)**4 & !& - + 30*y(3)**5 + 75*y(3)**4*y(4) + 1060*y(3)**3*y(4)**2 + 1515*y(3)**2*y(4)**3 + 3824*y(3)*y(4)**4 + 1662*y(4)**5))/(5*(y(1) + y(2))*(y(2) + y(3))*(y(1) + y(2) + y(3))**2*(y(2) + y(3) + y(4))*(y(1) + y(2) + y(3) + y(4))**2) !& - beta_coef_${XYZ}$ (i + 1, 3, 5) = (4*y(4)**2*(5*y(2)**2*y(3)**2 + 5*y(2)**2*y(3)*y(4) + 50*y(2)**2*y(4)**2 + 10*y(2)*y(3)**3 + 15*y(2)*y(3)**2*y(4) + 205*y(2)*y(3)*y(4)**2 + 100*y(2)*y(4)**3 + 5*y(3)**4 + 10*y(3)**3*y(4) + 205*y(3)**2*y(4)**2 + 200*y(3)*y(4)**3 + 831*y(4)**4))/(5*(y(1) & !& - + y(2))**2*(y(1) + y(2) + y(3))**2*(y(1) + y(2) + y(3) + y(4))**2) !& + beta_coef_${XYZ}$ (i + 1, 3, & + & 0) = (4*y(4)**2*(5*y(1)**2*y(2)**2 + 20*y(1)**2*y(2)*y(3) + 15*y(1)**2*y(2)*y(4) & + & + 20*y(1)**2*y(3)**2 + 30*y(1)**2*y(3)*y(4) + 60*y(1)**2*y(4)**2 + 10*y(1)*y(2) & + & **3 + 60*y(1)*y(2)**2*y(3) + 45*y(1)*y(2)**2*y(4) + 110*y(1)*y(2)*y(3)**2 & + & + 165*y(1)*y(2)*y(3)*y(4) + 260*y(1)*y(2)*y(4)**2 + 60*y(1)*y(3)**3 + 135*y(1) & + & *y(3)**2*y(4) + 400*y(1)*y(3)*y(4)**2 + 225*y(1)*y(4)**3 + 5*y(2)**4 + 40*y(2) & + & **3*y(3) + 30*y(2)**3*y(4) + 110*y(2)**2*y(3)**2 + 165*y(2)**2*y(3)*y(4) & + & + 260*y(2)**2*y(4)**2 + 120*y(2)*y(3)**3 + 270*y(2)*y(3)**2*y(4) + 800*y(2)*y(3) & + & *y(4)**2 + 450*y(2)*y(4)**3 + 45*y(3)**4 + 135*y(3)**3*y(4) + 600*y(3)**2*y(4) & + & **2 + 675*y(3)*y(4)**3 + 996*y(4)**4))/(5*(y(3) + y(4))**2*(y(2) + y(3) + y(4)) & + & **2*(y(1) + y(2) + y(3) + y(4))**2) + beta_coef_${XYZ}$ (i + 1, 3, & + & 1) = -(4*y(4)**2*(10*y(1)**3*y(2)*y(3) + 5*y(1)**3*y(2)*y(4) + 20*y(1)**3*y(3) & + & **2 + 25*y(1)**3*y(3)*y(4) + 105*y(1)**3*y(4)**2 + 40*y(1)**2*y(2)**2*y(3) & + & + 20*y(1)**2*y(2)**2*y(4) + 130*y(1)**2*y(2)*y(3)**2 + 155*y(1)**2*y(2)*y(3)*y(4) & + & + 535*y(1)**2*y(2)*y(4)**2 + 90*y(1)**2*y(3)**3 + 165*y(1)**2*y(3)**2*y(4) & + & + 790*y(1)**2*y(3)*y(4)**2 + 415*y(1)**2*y(4)**3 + 60*y(1)*y(2)**3*y(3) + 30*y(1) & + & *y(2)**3*y(4) + 270*y(1)*y(2)**2*y(3)**2 + 315*y(1)*y(2)**2*y(3)*y(4) + 975*y(1) & + & *y(2)**2*y(4)**2 + 360*y(1)*y(2)*y(3)**3 + 645*y(1)*y(2)*y(3)**2*y(4) + 2850*y(1) & + & *y(2)*y(3)*y(4)**2 + 1460*y(1)*y(2)*y(4)**3 + 150*y(1)*y(3)**4 + 360*y(1)*y(3) & + & **3*y(4) + 2000*y(1)*y(3)**2*y(4)**2 + 2005*y(1)*y(3)*y(4)**3 + 2077*y(1)*y(4) & + & **4 + 30*y(2)**4*y(3) + 15*y(2)**4*y(4) + 180*y(2)**3*y(3)**2 + 210*y(2)**3*y(3) & + & *y(4) + 650*y(2)**3*y(4)**2 + 360*y(2)**2*y(3)**3 + 645*y(2)**2*y(3)**2*y(4) & + & + 2850*y(2)**2*y(3)*y(4)**2 + 1460*y(2)**2*y(4)**3 + 300*y(2)*y(3)**4 + 720*y(2) & + & *y(3)**3*y(4) + 4000*y(2)*y(3)**2*y(4)**2 + 4010*y(2)*y(3)*y(4)**3 + 4154*y(2) & + & *y(4)**4 + 90*y(3)**5 + 270*y(3)**4*y(4) + 1800*y(3)**3*y(4)**2 + 2655*y(3) & + & **2*y(4)**3 + 4464*y(3)*y(4)**4 + 1767*y(4)**5))/(5*(y(2) + y(3))*(y(3) + y(4)) & + & *(y(1) + y(2) + y(3))*(y(2) + y(3) + y(4))**2*(y(1) + y(2) + y(3) + y(4))**2) + beta_coef_${XYZ}$ (i + 1, 3, & + & 2) = (4*y(4)**2*(10*y(2)**3*y(3) + 5*y(2)**3*y(4) + 50*y(2)**2*y(3)**2 + 60*y(2) & + & **2*y(3)*y(4) + 10*y(1)*y(2)**2*y(3) + 215*y(2)**2*y(4)**2 + 5*y(1)*y(2)**2*y(4) & + & + 70*y(2)*y(3)**3 + 130*y(2)*y(3)**2*y(4) + 30*y(1)*y(2)*y(3)**2 + 775*y(2)*y(3) & + & *y(4)**2 + 35*y(1)*y(2)*y(3)*y(4) + 415*y(2)*y(4)**3 + 110*y(1)*y(2)*y(4)**2 & + & + 30*y(3)**4 + 75*y(3)**3*y(4) + 20*y(1)*y(3)**3 + 665*y(3)**2*y(4)**2 + 35*y(1) & + & *y(3)**2*y(4) + 725*y(3)*y(4)**3 + 220*y(1)*y(3)*y(4)**2 + 1767*y(4)**4 & + & + 105*y(1)*y(4)**3))/(5*(y(1) + y(2))*(y(3) + y(4))*(y(1) + y(2) + y(3))*(y(2) & + & + y(3) + y(4))*(y(1) + y(2) + y(3) + y(4))**2) + beta_coef_${XYZ}$ (i + 1, 3, & + & 3) = (4*y(4)**2*(5*y(1)**4*y(3)**2 + 5*y(1)**4*y(3)*y(4) + 50*y(1)**4*y(4)**2 & + & + 30*y(1)**3*y(2)*y(3)**2 + 30*y(1)**3*y(2)*y(3)*y(4) + 300*y(1)**3*y(2)*y(4)**2 & + & + 30*y(1)**3*y(3)**3 + 45*y(1)**3*y(3)**2*y(4) + 415*y(1)**3*y(3)*y(4)**2 & + & + 200*y(1)**3*y(4)**3 + 75*y(1)**2*y(2)**2*y(3)**2 + 75*y(1)**2*y(2)**2*y(3)*y(4) & + & + 750*y(1)**2*y(2)**2*y(4)**2 + 150*y(1)**2*y(2)*y(3)**3 + 225*y(1)**2*y(2)*y(3) & + & **2*y(4) + 2075*y(1)**2*y(2)*y(3)*y(4)**2 + 1000*y(1)**2*y(2)*y(4)**3 + 75*y(1) & + & **2*y(3)**4 + 150*y(1)**2*y(3)**3*y(4) + 1390*y(1)**2*y(3)**2*y(4)**2 + 1315*y(1) & + & **2*y(3)*y(4)**3 + 1081*y(1)**2*y(4)**4 + 90*y(1)*y(2)**3*y(3)**2 + 90*y(1)*y(2) & + & **3*y(3)*y(4) + 900*y(1)*y(2)**3*y(4)**2 + 270*y(1)*y(2)**2*y(3)**3 + 405*y(1) & + & *y(2)**2*y(3)**2*y(4) + 3735*y(1)*y(2)**2*y(3)*y(4)**2 + 1800*y(1)*y(2)**2*y(4) & + & **3 + 270*y(1)*y(2)*y(3)**4 + 540*y(1)*y(2)*y(3)**3*y(4) + 5025*y(1)*y(2)*y(3) & + & **2*y(4)**2 + 4755*y(1)*y(2)*y(3)*y(4)**3 + 4224*y(1)*y(2)*y(4)**4 + 90*y(1)*y(3) & + & **5 + 225*y(1)*y(3)**4*y(4) + 2190*y(1)*y(3)**3*y(4)**2 + 3060*y(1)*y(3)**2*y(4) & + & **3 + 4529*y(1)*y(3)*y(4)**4 + 1762*y(1)*y(4)**5 + 45*y(2)**4*y(3)**2 + 45*y(2) & + & **4*y(3)*y(4) + 450*y(2)**4*y(4)**2 + 180*y(2)**3*y(3)**3 + 270*y(2)**3*y(3) & + & **2*y(4) + 2490*y(2)**3*y(3)*y(4)**2 + 1200*y(2)**3*y(4)**3 + 270*y(2)**2*y(3) & + & **4 + 540*y(2)**2*y(3)**3*y(4) + 5025*y(2)**2*y(3)**2*y(4)**2 + 4755*y(2)**2*y(3) & + & *y(4)**3 + 4224*y(2)**2*y(4)**4 + 180*y(2)*y(3)**5 + 450*y(2)*y(3)**4*y(4) & + & + 4380*y(2)*y(3)**3*y(4)**2 + 6120*y(2)*y(3)**2*y(4)**3 + 9058*y(2)*y(3)*y(4)**4 & + & + 3524*y(2)*y(4)**5 + 45*y(3)**6 + 135*y(3)**5*y(4) + 1395*y(3)**4*y(4)**2 & + & + 2565*y(3)**3*y(4)**3 + 4884*y(3)**2*y(4)**4 + 3624*y(3)*y(4)**5 + 831*y(4)**6)) & + & /(5*(y(2) + y(3))**2*(y(1) + y(2) + y(3))**2*(y(2) + y(3) + y(4))**2*(y(1) + y(2) & + & + y(3) + y(4))**2) + beta_coef_${XYZ}$ (i + 1, 3, & + & 4) = -(4*y(4)**2*(10*y(1)**2*y(2)*y(3)**2 + 10*y(1)**2*y(2)*y(3)*y(4) + 100*y(1) & + & **2*y(2)*y(4)**2 + 10*y(1)**2*y(3)**3 + 15*y(1)**2*y(3)**2*y(4) + 205*y(1) & + & **2*y(3)*y(4)**2 + 100*y(1)**2*y(4)**3 + 30*y(1)*y(2)**2*y(3)**2 + 30*y(1)*y(2) & + & **2*y(3)*y(4) + 300*y(1)*y(2)**2*y(4)**2 + 60*y(1)*y(2)*y(3)**3 + 90*y(1)*y(2) & + & *y(3)**2*y(4) + 1030*y(1)*y(2)*y(3)*y(4)**2 + 500*y(1)*y(2)*y(4)**3 + 30*y(1) & + & *y(3)**4 + 60*y(1)*y(3)**3*y(4) + 835*y(1)*y(3)**2*y(4)**2 + 805*y(1)*y(3)*y(4) & + & **3 + 1762*y(1)*y(4)**4 + 30*y(2)**3*y(3)**2 + 30*y(2)**3*y(3)*y(4) + 300*y(2) & + & **3*y(4)**2 + 90*y(2)**2*y(3)**3 + 135*y(2)**2*y(3)**2*y(4) + 1445*y(2)**2*y(3) & + & *y(4)**2 + 700*y(2)**2*y(4)**3 + 90*y(2)*y(3)**4 + 180*y(2)*y(3)**3*y(4) & + & + 2205*y(2)*y(3)**2*y(4)**2 + 2115*y(2)*y(3)*y(4)**3 + 3624*y(2)*y(4)**4 & + & + 30*y(3)**5 + 75*y(3)**4*y(4) + 1060*y(3)**3*y(4)**2 + 1515*y(3)**2*y(4)**3 & + & + 3824*y(3)*y(4)**4 + 1662*y(4)**5))/(5*(y(1) + y(2))*(y(2) + y(3))*(y(1) + y(2) & + & + y(3))**2*(y(2) + y(3) + y(4))*(y(1) + y(2) + y(3) + y(4))**2) + beta_coef_${XYZ}$ (i + 1, 3, & + & 5) = (4*y(4)**2*(5*y(2)**2*y(3)**2 + 5*y(2)**2*y(3)*y(4) + 50*y(2)**2*y(4)**2 & + & + 10*y(2)*y(3)**3 + 15*y(2)*y(3)**2*y(4) + 205*y(2)*y(3)*y(4)**2 + 100*y(2)*y(4) & + & **3 + 5*y(3)**4 + 10*y(3)**3*y(4) + 205*y(3)**2*y(4)**2 + 200*y(3)*y(4)**3 & + & + 831*y(4)**4))/(5*(y(1) + y(2))**2*(y(1) + y(2) + y(3))**2*(y(1) + y(2) + y(3) & + & + y(4))**2) y = s_cb(i - 1:i + 2) - s_cb(i - 2:i + 1) - beta_coef_${XYZ}$ (i + 1, 2, 0) = (4*y(3)**2*(5*y(1)**2*y(2)**2 + 5*y(1)**2*y(2)*y(3) + 50*y(1)**2*y(3)**2 + 10*y(1)*y(2)**3 + 15*y(1)*y(2)**2*y(3) + 205*y(1)*y(2)*y(3)**2 + 100*y(1)*y(3)**3 + 5*y(2)**4 + 10*y(2)**3*y(3) + 205*y(2)**2*y(3)**2 + 200*y(2)*y(3)**3 + 831*y(3)**4))/(5*(y(3) & !& - + y(4))**2*(y(2) + y(3) + y(4))**2*(y(1) + y(2) + y(3) + y(4))**2) !& - beta_coef_${XYZ}$ (i + 1, 2, 1) = (4*y(3)**2*(5*y(1)**3*y(2)*y(3) + 10*y(1)**3*y(2)*y(4) - 95*y(1)**3*y(3)**2 + 5*y(1)**3*y(3)*y(4) + 20*y(1)**2*y(2)**2*y(3) + 40*y(1)**2*y(2)**2*y(4) - 465*y(1)**2*y(2)*y(3)**2 + 55*y(1)**2*y(2)*y(3)*y(4) + 10*y(1)**2*y(2)*y(4)**2 - 285*y(1)**2*y(3)**3 & !& - + 20*y(1)**2*y(3)**2*y(4) + 5*y(1)**2*y(3)*y(4)**2 + 30*y(1)*y(2)**3*y(3) + 60*y(1)*y(2)**3*y(4) - 825*y(1)*y(2)**2*y(3)**2 + 135*y(1)*y(2)**2*y(3)*y(4) + 30*y(1)*y(2)**2*y(4)**2 - 1040*y(1)*y(2)*y(3)**3 + 100*y(1)*y(2)*y(3)**2*y(4) + 35*y(1)*y(2)*y(3)*y(4)**2 & !& - - 1847*y(1)*y(3)**4 + 125*y(1)*y(3)**3*y(4) + 110*y(1)*y(3)**2*y(4)**2 + 15*y(2)**4*y(3) + 30*y(2)**4*y(4) - 550*y(2)**3*y(3)**2 + 90*y(2)**3*y(3)*y(4) + 20*y(2)**3*y(4)**2 - 1040*y(2)**2*y(3)**3 + 100*y(2)**2*y(3)**2*y(4) + 35*y(2)**2*y(3)*y(4)**2 & !& - - 3694*y(2)*y(3)**4 + 250*y(2)*y(3)**3*y(4) + 220*y(2)*y(3)**2*y(4)**2 - 3219*y(3)**5 - 1452*y(3)**4*y(4) + 105*y(3)**3*y(4)**2))/(5*(y(2) + y(3))*(y(3) + y(4))*(y(1) + y(2) + y(3))*(y(2) + y(3) + y(4))**2*(y(1) + y(2) + y(3) + y(4))**2) !& - beta_coef_${XYZ}$ (i + 1, 2, 2) = -(4*y(3)**2*(5*y(2)**3*y(3) - 95*y(2)*y(3)**3 - 190*y(2)**2*y(3)**2 + 10*y(2)**3*y(4) + 100*y(3)**3*y(4) - 1562*y(3)**4 - 95*y(1)*y(2)*y(3)**2 + 5*y(1)*y(2)**2*y(3) + 10*y(1)*y(2)**2*y(4) + 100*y(1)*y(3)**2*y(4) + 205*y(2)*y(3)**2*y(4) & !& - + 15*y(2)**2*y(3)*y(4) + 10*y(1)*y(2)*y(3)*y(4)))/(5*(y(1) + y(2))*(y(3) + y(4))*(y(1) + y(2) + y(3))*(y(2) + y(3) + y(4))*(y(1) + y(2) + y(3) + y(4))**2) !& - beta_coef_${XYZ}$ (i + 1, 2, 3) = (4*y(3)**2*(50*y(1)**4*y(3)**2 + 5*y(1)**4*y(3)*y(4) + 5*y(1)**4*y(4)**2 + 300*y(1)**3*y(2)*y(3)**2 + 30*y(1)**3*y(2)*y(3)*y(4) + 30*y(1)**3*y(2)*y(4)**2 + 200*y(1)**3*y(3)**3 + 25*y(1)**3*y(3)**2*y(4) + 35*y(1)**3*y(3)*y(4)**2 + 10*y(1)**3*y(4)**3 & !& - + 750*y(1)**2*y(2)**2*y(3)**2 + 75*y(1)**2*y(2)**2*y(3)*y(4) + 75*y(1)**2*y(2)**2*y(4)**2 + 1000*y(1)**2*y(2)*y(3)**3 + 125*y(1)**2*y(2)*y(3)**2*y(4) + 175*y(1)**2*y(2)*y(3)*y(4)**2 + 50*y(1)**2*y(2)*y(4)**3 + 1081*y(1)**2*y(3)**4 - 50*y(1)**2*y(3)**3*y(4) & !& - - 10*y(1)**2*y(3)**2*y(4)**2 + 45*y(1)**2*y(3)*y(4)**3 + 5*y(1)**2*y(4)**4 + 900*y(1)*y(2)**3*y(3)**2 + 90*y(1)*y(2)**3*y(3)*y(4) + 90*y(1)*y(2)**3*y(4)**2 + 1800*y(1)*y(2)**2*y(3)**3 + 225*y(1)*y(2)**2*y(3)**2*y(4) + 315*y(1)*y(2)**2*y(3)*y(4)**2 & !& - + 90*y(1)*y(2)**2*y(4)**3 + 4224*y(1)*y(2)*y(3)**4 - 120*y(1)*y(2)*y(3)**3*y(4) + 25*y(1)*y(2)*y(3)**2*y(4)**2 + 165*y(1)*y(2)*y(3)*y(4)**3 + 20*y(1)*y(2)*y(4)**4 + 3324*y(1)*y(3)**5 + 1407*y(1)*y(3)**4*y(4) - 100*y(1)*y(3)**3*y(4)**2 + 70*y(1)*y(3)**2*y(4)**3 & !& - + 15*y(1)*y(3)*y(4)**4 + 450*y(2)**4*y(3)**2 + 45*y(2)**4*y(3)*y(4) + 45*y(2)**4*y(4)**2 + 1200*y(2)**3*y(3)**3 + 150*y(2)**3*y(3)**2*y(4) + 210*y(2)**3*y(3)*y(4)**2 + 60*y(2)**3*y(4)**3 + 4224*y(2)**2*y(3)**4 - 120*y(2)**2*y(3)**3*y(4) + 25*y(2)**2*y(3)**2*y(4)**2 & !& - + 165*y(2)**2*y(3)*y(4)**3 + 20*y(2)**2*y(4)**4 + 6648*y(2)*y(3)**5 + 2814*y(2)*y(3)**4*y(4) - 200*y(2)*y(3)**3*y(4)**2 + 140*y(2)*y(3)**2*y(4)**3 + 30*y(2)*y(3)*y(4)**4 + 3174*y(3)**6 + 3039*y(3)**5*y(4) + 771*y(3)**4*y(4)**2 + 135*y(3)**3*y(4)**3 + 60*y(3)**2*y(4)**4)) & !& - /(5*(y(2) + y(3))**2*(y(1) + y(2) + y(3))**2*(y(2) + y(3) + y(4))**2*(y(1) + y(2) + y(3) + y(4))**2) !& - beta_coef_${XYZ}$ (i + 1, 2, 4) = -(4*y(3)**2*(100*y(1)**2*y(2)*y(3)**2 + 10*y(1)**2*y(2)*y(3)*y(4) + 10*y(1)**2*y(2)*y(4)**2 - 95*y(1)**2*y(3)**2*y(4) + 5*y(1)**2*y(3)*y(4)**2 + 300*y(1)*y(2)**2*y(3)**2 + 30*y(1)*y(2)**2*y(3)*y(4) + 30*y(1)*y(2)**2*y(4)**2 + 200*y(1)*y(2)*y(3)**3 & !& - - 260*y(1)*y(2)*y(3)**2*y(4) + 50*y(1)*y(2)*y(3)*y(4)**2 + 10*y(1)*y(2)*y(4)**3 + 1562*y(1)*y(3)**4 - 190*y(1)*y(3)**3*y(4) + 15*y(1)*y(3)**2*y(4)**2 + 5*y(1)*y(3)*y(4)**3 + 300*y(2)**3*y(3)**2 + 30*y(2)**3*y(3)*y(4) + 30*y(2)**3*y(4)**2 + 400*y(2)**2*y(3)**3 & !& - - 235*y(2)**2*y(3)**2*y(4) + 85*y(2)**2*y(3)*y(4)**2 + 20*y(2)**2*y(4)**3 + 3224*y(2)*y(3)**4 - 460*y(2)*y(3)**3*y(4) - 35*y(2)*y(3)**2*y(4)**2 + 25*y(2)*y(3)*y(4)**3 + 3124*y(3)**5 + 1467*y(3)**4*y(4) + 110*y(3)**3*y(4)**2 + 105*y(3)**2*y(4)**3)) & !& - /(5*(y(1) + y(2))*(y(2) + y(3))*(y(1) + y(2) + y(3))**2*(y(2) + y(3) + y(4))*(y(1) + y(2) + y(3) + y(4))**2) !& - beta_coef_${XYZ}$ (i + 1, 2, 5) = (4*y(3)**2*(50*y(2)**2*y(3)**2 + 5*y(2)**2*y(3)*y(4) + 5*y(2)**2*y(4)**2 - 95*y(2)*y(3)**2*y(4) + 5*y(2)*y(3)*y(4)**2 + 781*y(3)**4 + 50*y(3)**2*y(4)**2))/(5*(y(1) + y(2))**2*(y(1) + y(2) + y(3))**2*(y(1) + y(2) + y(3) + y(4))**2) !& + beta_coef_${XYZ}$ (i + 1, 2, & + & 0) = (4*y(3)**2*(5*y(1)**2*y(2)**2 + 5*y(1)**2*y(2)*y(3) + 50*y(1)**2*y(3)**2 & + & + 10*y(1)*y(2)**3 + 15*y(1)*y(2)**2*y(3) + 205*y(1)*y(2)*y(3)**2 + 100*y(1)*y(3) & + & **3 + 5*y(2)**4 + 10*y(2)**3*y(3) + 205*y(2)**2*y(3)**2 + 200*y(2)*y(3)**3 & + & + 831*y(3)**4))/(5*(y(3) + y(4))**2*(y(2) + y(3) + y(4))**2*(y(1) + y(2) + y(3) & + & + y(4))**2) + beta_coef_${XYZ}$ (i + 1, 2, & + & 1) = (4*y(3)**2*(5*y(1)**3*y(2)*y(3) + 10*y(1)**3*y(2)*y(4) - 95*y(1)**3*y(3)**2 & + & + 5*y(1)**3*y(3)*y(4) + 20*y(1)**2*y(2)**2*y(3) + 40*y(1)**2*y(2)**2*y(4) & + & - 465*y(1)**2*y(2)*y(3)**2 + 55*y(1)**2*y(2)*y(3)*y(4) + 10*y(1)**2*y(2)*y(4)**2 & + & - 285*y(1)**2*y(3)**3 + 20*y(1)**2*y(3)**2*y(4) + 5*y(1)**2*y(3)*y(4)**2 & + & + 30*y(1)*y(2)**3*y(3) + 60*y(1)*y(2)**3*y(4) - 825*y(1)*y(2)**2*y(3)**2 & + & + 135*y(1)*y(2)**2*y(3)*y(4) + 30*y(1)*y(2)**2*y(4)**2 - 1040*y(1)*y(2)*y(3)**3 & + & + 100*y(1)*y(2)*y(3)**2*y(4) + 35*y(1)*y(2)*y(3)*y(4)**2 - 1847*y(1)*y(3)**4 & + & + 125*y(1)*y(3)**3*y(4) + 110*y(1)*y(3)**2*y(4)**2 + 15*y(2)**4*y(3) + 30*y(2) & + & **4*y(4) - 550*y(2)**3*y(3)**2 + 90*y(2)**3*y(3)*y(4) + 20*y(2)**3*y(4)**2 & + & - 1040*y(2)**2*y(3)**3 + 100*y(2)**2*y(3)**2*y(4) + 35*y(2)**2*y(3)*y(4)**2 & + & - 3694*y(2)*y(3)**4 + 250*y(2)*y(3)**3*y(4) + 220*y(2)*y(3)**2*y(4)**2 & + & - 3219*y(3)**5 - 1452*y(3)**4*y(4) + 105*y(3)**3*y(4)**2))/(5*(y(2) + y(3))*(y(3) & + & + y(4))*(y(1) + y(2) + y(3))*(y(2) + y(3) + y(4))**2*(y(1) + y(2) + y(3) + y(4)) & + & **2) + beta_coef_${XYZ}$ (i + 1, 2, & + & 2) = -(4*y(3)**2*(5*y(2)**3*y(3) - 95*y(2)*y(3)**3 - 190*y(2)**2*y(3)**2 & + & + 10*y(2)**3*y(4) + 100*y(3)**3*y(4) - 1562*y(3)**4 - 95*y(1)*y(2)*y(3)**2 & + & + 5*y(1)*y(2)**2*y(3) + 10*y(1)*y(2)**2*y(4) + 100*y(1)*y(3)**2*y(4) + 205*y(2) & + & *y(3)**2*y(4) + 15*y(2)**2*y(3)*y(4) + 10*y(1)*y(2)*y(3)*y(4)))/(5*(y(1) + y(2)) & + & *(y(3) + y(4))*(y(1) + y(2) + y(3))*(y(2) + y(3) + y(4))*(y(1) + y(2) + y(3) & + & + y(4))**2) + beta_coef_${XYZ}$ (i + 1, 2, & + & 3) = (4*y(3)**2*(50*y(1)**4*y(3)**2 + 5*y(1)**4*y(3)*y(4) + 5*y(1)**4*y(4)**2 & + & + 300*y(1)**3*y(2)*y(3)**2 + 30*y(1)**3*y(2)*y(3)*y(4) + 30*y(1)**3*y(2)*y(4)**2 & + & + 200*y(1)**3*y(3)**3 + 25*y(1)**3*y(3)**2*y(4) + 35*y(1)**3*y(3)*y(4)**2 & + & + 10*y(1)**3*y(4)**3 + 750*y(1)**2*y(2)**2*y(3)**2 + 75*y(1)**2*y(2)**2*y(3)*y(4) & + & + 75*y(1)**2*y(2)**2*y(4)**2 + 1000*y(1)**2*y(2)*y(3)**3 + 125*y(1)**2*y(2)*y(3) & + & **2*y(4) + 175*y(1)**2*y(2)*y(3)*y(4)**2 + 50*y(1)**2*y(2)*y(4)**3 + 1081*y(1) & + & **2*y(3)**4 - 50*y(1)**2*y(3)**3*y(4) - 10*y(1)**2*y(3)**2*y(4)**2 + 45*y(1) & + & **2*y(3)*y(4)**3 + 5*y(1)**2*y(4)**4 + 900*y(1)*y(2)**3*y(3)**2 + 90*y(1)*y(2) & + & **3*y(3)*y(4) + 90*y(1)*y(2)**3*y(4)**2 + 1800*y(1)*y(2)**2*y(3)**3 + 225*y(1) & + & *y(2)**2*y(3)**2*y(4) + 315*y(1)*y(2)**2*y(3)*y(4)**2 + 90*y(1)*y(2)**2*y(4)**3 & + & + 4224*y(1)*y(2)*y(3)**4 - 120*y(1)*y(2)*y(3)**3*y(4) + 25*y(1)*y(2)*y(3)**2*y(4) & + & **2 + 165*y(1)*y(2)*y(3)*y(4)**3 + 20*y(1)*y(2)*y(4)**4 + 3324*y(1)*y(3)**5 & + & + 1407*y(1)*y(3)**4*y(4) - 100*y(1)*y(3)**3*y(4)**2 + 70*y(1)*y(3)**2*y(4)**3 & + & + 15*y(1)*y(3)*y(4)**4 + 450*y(2)**4*y(3)**2 + 45*y(2)**4*y(3)*y(4) + 45*y(2) & + & **4*y(4)**2 + 1200*y(2)**3*y(3)**3 + 150*y(2)**3*y(3)**2*y(4) + 210*y(2)**3*y(3) & + & *y(4)**2 + 60*y(2)**3*y(4)**3 + 4224*y(2)**2*y(3)**4 - 120*y(2)**2*y(3)**3*y(4) & + & + 25*y(2)**2*y(3)**2*y(4)**2 + 165*y(2)**2*y(3)*y(4)**3 + 20*y(2)**2*y(4)**4 & + & + 6648*y(2)*y(3)**5 + 2814*y(2)*y(3)**4*y(4) - 200*y(2)*y(3)**3*y(4)**2 & + & + 140*y(2)*y(3)**2*y(4)**3 + 30*y(2)*y(3)*y(4)**4 + 3174*y(3)**6 + 3039*y(3) & + & **5*y(4) + 771*y(3)**4*y(4)**2 + 135*y(3)**3*y(4)**3 + 60*y(3)**2*y(4)**4)) & + & /(5*(y(2) + y(3))**2*(y(1) + y(2) + y(3))**2*(y(2) + y(3) + y(4))**2*(y(1) + y(2) & + & + y(3) + y(4))**2) + beta_coef_${XYZ}$ (i + 1, 2, & + & 4) = -(4*y(3)**2*(100*y(1)**2*y(2)*y(3)**2 + 10*y(1)**2*y(2)*y(3)*y(4) + 10*y(1) & + & **2*y(2)*y(4)**2 - 95*y(1)**2*y(3)**2*y(4) + 5*y(1)**2*y(3)*y(4)**2 + 300*y(1) & + & *y(2)**2*y(3)**2 + 30*y(1)*y(2)**2*y(3)*y(4) + 30*y(1)*y(2)**2*y(4)**2 + 200*y(1) & + & *y(2)*y(3)**3 - 260*y(1)*y(2)*y(3)**2*y(4) + 50*y(1)*y(2)*y(3)*y(4)**2 + 10*y(1) & + & *y(2)*y(4)**3 + 1562*y(1)*y(3)**4 - 190*y(1)*y(3)**3*y(4) + 15*y(1)*y(3)**2*y(4) & + & **2 + 5*y(1)*y(3)*y(4)**3 + 300*y(2)**3*y(3)**2 + 30*y(2)**3*y(3)*y(4) + 30*y(2) & + & **3*y(4)**2 + 400*y(2)**2*y(3)**3 - 235*y(2)**2*y(3)**2*y(4) + 85*y(2)**2*y(3) & + & *y(4)**2 + 20*y(2)**2*y(4)**3 + 3224*y(2)*y(3)**4 - 460*y(2)*y(3)**3*y(4) & + & - 35*y(2)*y(3)**2*y(4)**2 + 25*y(2)*y(3)*y(4)**3 + 3124*y(3)**5 + 1467*y(3) & + & **4*y(4) + 110*y(3)**3*y(4)**2 + 105*y(3)**2*y(4)**3))/(5*(y(1) + y(2))*(y(2) & + & + y(3))*(y(1) + y(2) + y(3))**2*(y(2) + y(3) + y(4))*(y(1) + y(2) + y(3) + y(4)) & + & **2) + beta_coef_${XYZ}$ (i + 1, 2, & + & 5) = (4*y(3)**2*(50*y(2)**2*y(3)**2 + 5*y(2)**2*y(3)*y(4) + 5*y(2)**2*y(4)**2 & + & - 95*y(2)*y(3)**2*y(4) + 5*y(2)*y(3)*y(4)**2 + 781*y(3)**4 + 50*y(3)**2*y(4)**2)) & + & /(5*(y(1) + y(2))**2*(y(1) + y(2) + y(3))**2*(y(1) + y(2) + y(3) + y(4))**2) y = s_cb(i:i + 3) - s_cb(i - 1:i + 2) - beta_coef_${XYZ}$ (i + 1, 1, 0) = (4*y(2)**2*(50*y(1)**2*y(2)**2 + 5*y(1)**2*y(2)*y(3) + 5*y(1)**2*y(3)**2 - 95*y(1)*y(2)**2*y(3) + 5*y(1)*y(2)*y(3)**2 + 781*y(2)**4 + 50*y(2)**2*y(3)**2))/(5*(y(3) + y(4))**2*(y(2) + y(3) + y(4))**2*(y(1) + y(2) + y(3) + y(4))**2) !& - beta_coef_${XYZ}$ (i + 1, 1, 1) = -(4*y(2)**2*(105*y(1)**3*y(2)**2 + 25*y(1)**3*y(2)*y(3) + 5*y(1)**3*y(2)*y(4) + 20*y(1)**3*y(3)**2 + 10*y(1)**3*y(3)*y(4) + 110*y(1)**2*y(2)**3 - 35*y(1)**2*y(2)**2*y(3) + 15*y(1)**2*y(2)**2*y(4) + 85*y(1)**2*y(2)*y(3)**2 + 50*y(1)**2*y(2)*y(3)*y(4) & !& - + 5*y(1)**2*y(2)*y(4)**2 + 30*y(1)**2*y(3)**3 + 30*y(1)**2*y(3)**2*y(4) + 10*y(1)**2*y(3)*y(4)**2 + 1467*y(1)*y(2)**4 - 460*y(1)*y(2)**3*y(3) - 190*y(1)*y(2)**3*y(4) - 235*y(1)*y(2)**2*y(3)**2 - 260*y(1)*y(2)**2*y(3)*y(4) - 95*y(1)*y(2)**2*y(4)**2 & !& - + 30*y(1)*y(2)*y(3)**3 + 30*y(1)*y(2)*y(3)**2*y(4) + 10*y(1)*y(2)*y(3)*y(4)**2 + 3124*y(2)**5 + 3224*y(2)**4*y(3) + 1562*y(2)**4*y(4) + 400*y(2)**3*y(3)**2 + 200*y(2)**3*y(3)*y(4) + 300*y(2)**2*y(3)**3 + 300*y(2)**2*y(3)**2*y(4) + 100*y(2)**2*y(3)*y(4)**2)) & !& - /(5*(y(2) + y(3))*(y(3) + y(4))*(y(1) + y(2) + y(3))*(y(2) + y(3) + y(4))**2*(y(1) + y(2) + y(3) + y(4))**2) !& - beta_coef_${XYZ}$ (i + 1, 1, 2) = -(4*y(2)**2*(100*y(1)*y(2)**3 - 190*y(2)**2*y(3)**2 + 10*y(1)*y(3)**3 + 5*y(2)*y(3)**3 - 95*y(2)**3*y(3) - 1562*y(2)**4 + 15*y(1)*y(2)*y(3)**2 + 205*y(1)*y(2)**2*y(3) + 100*y(1)*y(2)**2*y(4) + 10*y(1)*y(3)**2*y(4) + 5*y(2)*y(3)**2*y(4) - 95*y(2)**2*y(3)*y(4) & !& - + 10*y(1)*y(2)*y(3)*y(4)))/(5*(y(1) + y(2))*(y(3) + y(4))*(y(1) + y(2) + y(3))*(y(2) + y(3) + y(4))*(y(1) + y(2) + y(3) + y(4))**2) !& - beta_coef_${XYZ}$ (i + 1, 1, 3) = (4*y(2)**2*(60*y(1)**4*y(2)**2 + 30*y(1)**4*y(2)*y(3) + 15*y(1)**4*y(2)*y(4) + 20*y(1)**4*y(3)**2 + 20*y(1)**4*y(3)*y(4) + 5*y(1)**4*y(4)**2 + 135*y(1)**3*y(2)**3 + 140*y(1)**3*y(2)**2*y(3) + 70*y(1)**3*y(2)**2*y(4) + 165*y(1)**3*y(2)*y(3)**2 & !& - + 165*y(1)**3*y(2)*y(3)*y(4) + 45*y(1)**3*y(2)*y(4)**2 + 60*y(1)**3*y(3)**3 + 90*y(1)**3*y(3)**2*y(4) + 50*y(1)**3*y(3)*y(4)**2 + 10*y(1)**3*y(4)**3 + 771*y(1)**2*y(2)**4 - 200*y(1)**2*y(2)**3*y(3) - 100*y(1)**2*y(2)**3*y(4) + 25*y(1)**2*y(2)**2*y(3)**2 & !& - + 25*y(1)**2*y(2)**2*y(3)*y(4) - 10*y(1)**2*y(2)**2*y(4)**2 + 210*y(1)**2*y(2)*y(3)**3 + 315*y(1)**2*y(2)*y(3)**2*y(4) + 175*y(1)**2*y(2)*y(3)*y(4)**2 + 35*y(1)**2*y(2)*y(4)**3 + 45*y(1)**2*y(3)**4 + 90*y(1)**2*y(3)**3*y(4) + 75*y(1)**2*y(3)**2*y(4)**2 & !& - + 30*y(1)**2*y(3)*y(4)**3 + 5*y(1)**2*y(4)**4 + 3039*y(1)*y(2)**5 + 2814*y(1)*y(2)**4*y(3) + 1407*y(1)*y(2)**4*y(4) - 120*y(1)*y(2)**3*y(3)**2 - 120*y(1)*y(2)**3*y(3)*y(4) - 50*y(1)*y(2)**3*y(4)**2 + 150*y(1)*y(2)**2*y(3)**3 + 225*y(1)*y(2)**2*y(3)**2*y(4) & !& - + 125*y(1)*y(2)**2*y(3)*y(4)**2 + 25*y(1)*y(2)**2*y(4)**3 + 45*y(1)*y(2)*y(3)**4 + 90*y(1)*y(2)*y(3)**3*y(4) + 75*y(1)*y(2)*y(3)**2*y(4)**2 + 30*y(1)*y(2)*y(3)*y(4)**3 + 5*y(1)*y(2)*y(4)**4 + 3174*y(2)**6 + 6648*y(2)**5*y(3) + 3324*y(2)**5*y(4) & !& - + 4224*y(2)**4*y(3)**2 + 4224*y(2)**4*y(3)*y(4) + 1081*y(2)**4*y(4)**2 + 1200*y(2)**3*y(3)**3 + 1800*y(2)**3*y(3)**2*y(4) + 1000*y(2)**3*y(3)*y(4)**2 + 200*y(2)**3*y(4)**3 + 450*y(2)**2*y(3)**4 + 900*y(2)**2*y(3)**3*y(4) + 750*y(2)**2*y(3)**2*y(4)**2 & !& - + 300*y(2)**2*y(3)*y(4)**3 + 50*y(2)**2*y(4)**4))/(5*(y(2) + y(3))**2*(y(1) + y(2) + y(3))**2*(y(2) + y(3) + y(4))**2*(y(1) + y(2) + y(3) + y(4))**2) !& - beta_coef_${XYZ}$ (i + 1, 1, 4) = (4*y(2)**2*(105*y(1)**2*y(2)**3 + 220*y(1)**2*y(2)**2*y(3) + 110*y(1)**2*y(2)**2*y(4) + 35*y(1)**2*y(2)*y(3)**2 + 35*y(1)**2*y(2)*y(3)*y(4) + 5*y(1)**2*y(2)*y(4)**2 + 20*y(1)**2*y(3)**3 + 30*y(1)**2*y(3)**2*y(4) + 10*y(1)**2*y(3)*y(4)**2 - 1452*y(1)*y(2)**4 & !& - + 250*y(1)*y(2)**3*y(3) + 125*y(1)*y(2)**3*y(4) + 100*y(1)*y(2)**2*y(3)**2 + 100*y(1)*y(2)**2*y(3)*y(4) + 20*y(1)*y(2)**2*y(4)**2 + 90*y(1)*y(2)*y(3)**3 + 135*y(1)*y(2)*y(3)**2*y(4) + 55*y(1)*y(2)*y(3)*y(4)**2 + 5*y(1)*y(2)*y(4)**3 + 30*y(1)*y(3)**4 & !& - + 60*y(1)*y(3)**3*y(4) + 40*y(1)*y(3)**2*y(4)**2 + 10*y(1)*y(3)*y(4)**3 - 3219*y(2)**5 - 3694*y(2)**4*y(3) - 1847*y(2)**4*y(4) - 1040*y(2)**3*y(3)**2 - 1040*y(2)**3*y(3)*y(4) - 285*y(2)**3*y(4)**2 - 550*y(2)**2*y(3)**3 - 825*y(2)**2*y(3)**2*y(4) & !& - - 465*y(2)**2*y(3)*y(4)**2 - 95*y(2)**2*y(4)**3 + 15*y(2)*y(3)**4 + 30*y(2)*y(3)**3*y(4) + 20*y(2)*y(3)**2*y(4)**2 + 5*y(2)*y(3)*y(4)**3))/(5*(y(1) + y(2))*(y(2) + y(3))*(y(1) + y(2) + y(3))**2*(y(2) + y(3) + y(4))*(y(1) + y(2) + y(3) + y(4))**2) !& - beta_coef_${XYZ}$ (i + 1, 1, 5) = (4*y(2)**2*(831*y(2)**4 + 200*y(2)**3*y(3) + 100*y(2)**3*y(4) + 205*y(2)**2*y(3)**2 + 205*y(2)**2*y(3)*y(4) + 50*y(2)**2*y(4)**2 + 10*y(2)*y(3)**3 + 15*y(2)*y(3)**2*y(4) + 5*y(2)*y(3)*y(4)**2 + 5*y(3)**4 + 10*y(3)**3*y(4) + 5*y(3)**2*y(4)**2))/(5*(y(1) & !& - + y(2))**2*(y(1) + y(2) + y(3))**2*(y(1) + y(2) + y(3) + y(4))**2) !& + beta_coef_${XYZ}$ (i + 1, 1, & + & 0) = (4*y(2)**2*(50*y(1)**2*y(2)**2 + 5*y(1)**2*y(2)*y(3) + 5*y(1)**2*y(3)**2 & + & - 95*y(1)*y(2)**2*y(3) + 5*y(1)*y(2)*y(3)**2 + 781*y(2)**4 + 50*y(2)**2*y(3)**2)) & + & /(5*(y(3) + y(4))**2*(y(2) + y(3) + y(4))**2*(y(1) + y(2) + y(3) + y(4))**2) + beta_coef_${XYZ}$ (i + 1, 1, & + & 1) = -(4*y(2)**2*(105*y(1)**3*y(2)**2 + 25*y(1)**3*y(2)*y(3) + 5*y(1)**3*y(2) & + & *y(4) + 20*y(1)**3*y(3)**2 + 10*y(1)**3*y(3)*y(4) + 110*y(1)**2*y(2)**3 - 35*y(1) & + & **2*y(2)**2*y(3) + 15*y(1)**2*y(2)**2*y(4) + 85*y(1)**2*y(2)*y(3)**2 + 50*y(1) & + & **2*y(2)*y(3)*y(4) + 5*y(1)**2*y(2)*y(4)**2 + 30*y(1)**2*y(3)**3 + 30*y(1) & + & **2*y(3)**2*y(4) + 10*y(1)**2*y(3)*y(4)**2 + 1467*y(1)*y(2)**4 - 460*y(1)*y(2) & + & **3*y(3) - 190*y(1)*y(2)**3*y(4) - 235*y(1)*y(2)**2*y(3)**2 - 260*y(1)*y(2) & + & **2*y(3)*y(4) - 95*y(1)*y(2)**2*y(4)**2 + 30*y(1)*y(2)*y(3)**3 + 30*y(1)*y(2) & + & *y(3)**2*y(4) + 10*y(1)*y(2)*y(3)*y(4)**2 + 3124*y(2)**5 + 3224*y(2)**4*y(3) & + & + 1562*y(2)**4*y(4) + 400*y(2)**3*y(3)**2 + 200*y(2)**3*y(3)*y(4) + 300*y(2) & + & **2*y(3)**3 + 300*y(2)**2*y(3)**2*y(4) + 100*y(2)**2*y(3)*y(4)**2))/(5*(y(2) & + & + y(3))*(y(3) + y(4))*(y(1) + y(2) + y(3))*(y(2) + y(3) + y(4))**2*(y(1) + y(2) & + & + y(3) + y(4))**2) + beta_coef_${XYZ}$ (i + 1, 1, & + & 2) = -(4*y(2)**2*(100*y(1)*y(2)**3 - 190*y(2)**2*y(3)**2 + 10*y(1)*y(3)**3 & + & + 5*y(2)*y(3)**3 - 95*y(2)**3*y(3) - 1562*y(2)**4 + 15*y(1)*y(2)*y(3)**2 & + & + 205*y(1)*y(2)**2*y(3) + 100*y(1)*y(2)**2*y(4) + 10*y(1)*y(3)**2*y(4) + 5*y(2) & + & *y(3)**2*y(4) - 95*y(2)**2*y(3)*y(4) + 10*y(1)*y(2)*y(3)*y(4)))/(5*(y(1) + y(2)) & + & *(y(3) + y(4))*(y(1) + y(2) + y(3))*(y(2) + y(3) + y(4))*(y(1) + y(2) + y(3) & + & + y(4))**2) + beta_coef_${XYZ}$ (i + 1, 1, & + & 3) = (4*y(2)**2*(60*y(1)**4*y(2)**2 + 30*y(1)**4*y(2)*y(3) + 15*y(1)**4*y(2)*y(4) & + & + 20*y(1)**4*y(3)**2 + 20*y(1)**4*y(3)*y(4) + 5*y(1)**4*y(4)**2 + 135*y(1) & + & **3*y(2)**3 + 140*y(1)**3*y(2)**2*y(3) + 70*y(1)**3*y(2)**2*y(4) + 165*y(1) & + & **3*y(2)*y(3)**2 + 165*y(1)**3*y(2)*y(3)*y(4) + 45*y(1)**3*y(2)*y(4)**2 + 60*y(1) & + & **3*y(3)**3 + 90*y(1)**3*y(3)**2*y(4) + 50*y(1)**3*y(3)*y(4)**2 + 10*y(1)**3*y(4) & + & **3 + 771*y(1)**2*y(2)**4 - 200*y(1)**2*y(2)**3*y(3) - 100*y(1)**2*y(2)**3*y(4) & + & + 25*y(1)**2*y(2)**2*y(3)**2 + 25*y(1)**2*y(2)**2*y(3)*y(4) - 10*y(1)**2*y(2) & + & **2*y(4)**2 + 210*y(1)**2*y(2)*y(3)**3 + 315*y(1)**2*y(2)*y(3)**2*y(4) + 175*y(1) & + & **2*y(2)*y(3)*y(4)**2 + 35*y(1)**2*y(2)*y(4)**3 + 45*y(1)**2*y(3)**4 + 90*y(1) & + & **2*y(3)**3*y(4) + 75*y(1)**2*y(3)**2*y(4)**2 + 30*y(1)**2*y(3)*y(4)**3 + 5*y(1) & + & **2*y(4)**4 + 3039*y(1)*y(2)**5 + 2814*y(1)*y(2)**4*y(3) + 1407*y(1)*y(2)**4*y(4) & + & - 120*y(1)*y(2)**3*y(3)**2 - 120*y(1)*y(2)**3*y(3)*y(4) - 50*y(1)*y(2)**3*y(4) & + & **2 + 150*y(1)*y(2)**2*y(3)**3 + 225*y(1)*y(2)**2*y(3)**2*y(4) + 125*y(1)*y(2) & + & **2*y(3)*y(4)**2 + 25*y(1)*y(2)**2*y(4)**3 + 45*y(1)*y(2)*y(3)**4 + 90*y(1)*y(2) & + & *y(3)**3*y(4) + 75*y(1)*y(2)*y(3)**2*y(4)**2 + 30*y(1)*y(2)*y(3)*y(4)**3 + 5*y(1) & + & *y(2)*y(4)**4 + 3174*y(2)**6 + 6648*y(2)**5*y(3) + 3324*y(2)**5*y(4) + 4224*y(2) & + & **4*y(3)**2 + 4224*y(2)**4*y(3)*y(4) + 1081*y(2)**4*y(4)**2 + 1200*y(2)**3*y(3) & + & **3 + 1800*y(2)**3*y(3)**2*y(4) + 1000*y(2)**3*y(3)*y(4)**2 + 200*y(2)**3*y(4) & + & **3 + 450*y(2)**2*y(3)**4 + 900*y(2)**2*y(3)**3*y(4) + 750*y(2)**2*y(3)**2*y(4) & + & **2 + 300*y(2)**2*y(3)*y(4)**3 + 50*y(2)**2*y(4)**4))/(5*(y(2) + y(3))**2*(y(1) & + & + y(2) + y(3))**2*(y(2) + y(3) + y(4))**2*(y(1) + y(2) + y(3) + y(4))**2) + beta_coef_${XYZ}$ (i + 1, 1, & + & 4) = (4*y(2)**2*(105*y(1)**2*y(2)**3 + 220*y(1)**2*y(2)**2*y(3) + 110*y(1) & + & **2*y(2)**2*y(4) + 35*y(1)**2*y(2)*y(3)**2 + 35*y(1)**2*y(2)*y(3)*y(4) + 5*y(1) & + & **2*y(2)*y(4)**2 + 20*y(1)**2*y(3)**3 + 30*y(1)**2*y(3)**2*y(4) + 10*y(1)**2*y(3) & + & *y(4)**2 - 1452*y(1)*y(2)**4 + 250*y(1)*y(2)**3*y(3) + 125*y(1)*y(2)**3*y(4) & + & + 100*y(1)*y(2)**2*y(3)**2 + 100*y(1)*y(2)**2*y(3)*y(4) + 20*y(1)*y(2)**2*y(4) & + & **2 + 90*y(1)*y(2)*y(3)**3 + 135*y(1)*y(2)*y(3)**2*y(4) + 55*y(1)*y(2)*y(3)*y(4) & + & **2 + 5*y(1)*y(2)*y(4)**3 + 30*y(1)*y(3)**4 + 60*y(1)*y(3)**3*y(4) + 40*y(1)*y(3) & + & **2*y(4)**2 + 10*y(1)*y(3)*y(4)**3 - 3219*y(2)**5 - 3694*y(2)**4*y(3) - 1847*y(2) & + & **4*y(4) - 1040*y(2)**3*y(3)**2 - 1040*y(2)**3*y(3)*y(4) - 285*y(2)**3*y(4)**2 & + & - 550*y(2)**2*y(3)**3 - 825*y(2)**2*y(3)**2*y(4) - 465*y(2)**2*y(3)*y(4)**2 & + & - 95*y(2)**2*y(4)**3 + 15*y(2)*y(3)**4 + 30*y(2)*y(3)**3*y(4) + 20*y(2)*y(3) & + & **2*y(4)**2 + 5*y(2)*y(3)*y(4)**3))/(5*(y(1) + y(2))*(y(2) + y(3))*(y(1) + y(2) & + & + y(3))**2*(y(2) + y(3) + y(4))*(y(1) + y(2) + y(3) + y(4))**2) + beta_coef_${XYZ}$ (i + 1, 1, & + & 5) = (4*y(2)**2*(831*y(2)**4 + 200*y(2)**3*y(3) + 100*y(2)**3*y(4) + 205*y(2) & + & **2*y(3)**2 + 205*y(2)**2*y(3)*y(4) + 50*y(2)**2*y(4)**2 + 10*y(2)*y(3)**3 & + & + 15*y(2)*y(3)**2*y(4) + 5*y(2)*y(3)*y(4)**2 + 5*y(3)**4 + 10*y(3)**3*y(4) & + & + 5*y(3)**2*y(4)**2))/(5*(y(1) + y(2))**2*(y(1) + y(2) + y(3))**2*(y(1) + y(2) & + & + y(3) + y(4))**2) y = s_cb(i + 1:i + 4) - s_cb(i:i + 3) - beta_coef_${XYZ}$ (i + 1, 0, 0) = (4*y(1)**2*(831*y(1)**4 + 200*y(1)**3*y(2) + 100*y(1)**3*y(3) + 205*y(1)**2*y(2)**2 + 205*y(1)**2*y(2)*y(3) + 50*y(1)**2*y(3)**2 + 10*y(1)*y(2)**3 + 15*y(1)*y(2)**2*y(3) + 5*y(1)*y(2)*y(3)**2 + 5*y(2)**4 + 10*y(2)**3*y(3) + 5*y(2)**2*y(3)**2))/(5*(y(3) & !& - + y(4))**2*(y(2) + y(3) + y(4))**2*(y(1) + y(2) + y(3) + y(4))**2) !& - beta_coef_${XYZ}$ (i + 1, 0, 1) = -(4*y(1)**2*(1662*y(1)**5 + 3824*y(1)**4*y(2) + 3624*y(1)**4*y(3) + 1762*y(1)**4*y(4) + 1515*y(1)**3*y(2)**2 + 2115*y(1)**3*y(2)*y(3) + 805*y(1)**3*y(2)*y(4) + 700*y(1)**3*y(3)**2 + 500*y(1)**3*y(3)*y(4) + 100*y(1)**3*y(4)**2 + 1060*y(1)**2*y(2)**3 & !& - + 2205*y(1)**2*y(2)**2*y(3) + 835*y(1)**2*y(2)**2*y(4) + 1445*y(1)**2*y(2)*y(3)**2 + 1030*y(1)**2*y(2)*y(3)*y(4) + 205*y(1)**2*y(2)*y(4)**2 + 300*y(1)**2*y(3)**3 + 300*y(1)**2*y(3)**2*y(4) + 100*y(1)**2*y(3)*y(4)**2 + 75*y(1)*y(2)**4 + 180*y(1)*y(2)**3*y(3) & !& - + 60*y(1)*y(2)**3*y(4) + 135*y(1)*y(2)**2*y(3)**2 + 90*y(1)*y(2)**2*y(3)*y(4) + 15*y(1)*y(2)**2*y(4)**2 + 30*y(1)*y(2)*y(3)**3 + 30*y(1)*y(2)*y(3)**2*y(4) + 10*y(1)*y(2)*y(3)*y(4)**2 + 30*y(2)**5 + 90*y(2)**4*y(3) + 30*y(2)**4*y(4) + 90*y(2)**3*y(3)**2 & !& - + 60*y(2)**3*y(3)*y(4) + 10*y(2)**3*y(4)**2 + 30*y(2)**2*y(3)**3 + 30*y(2)**2*y(3)**2*y(4) + 10*y(2)**2*y(3)*y(4)**2))/(5*(y(2) + y(3))*(y(3) + y(4))*(y(1) + y(2) + y(3))*(y(2) + y(3) + y(4))**2*(y(1) + y(2) + y(3) + y(4))**2) !& - beta_coef_${XYZ}$ (i + 1, 0, 2) = (4*y(1)**2*(1767*y(1)**4 + 725*y(1)**3*y(2) + 415*y(1)**3*y(3) + 105*y(4)*y(1)**3 + 665*y(1)**2*y(2)**2 + 775*y(1)**2*y(2)*y(3) + 220*y(4)*y(1)**2*y(2) + 215*y(1)**2*y(3)**2 + 110*y(4)*y(1)**2*y(3) + 75*y(1)*y(2)**3 + 130*y(1)*y(2)**2*y(3) + 35*y(4)*y(1)*y(2)**2 & !& - + 60*y(1)*y(2)*y(3)**2 + 35*y(4)*y(1)*y(2)*y(3) + 5*y(1)*y(3)**3 + 5*y(4)*y(1)*y(3)**2 + 30*y(2)**4 + 70*y(2)**3*y(3) + 20*y(4)*y(2)**3 + 50*y(2)**2*y(3)**2 + 30*y(4)*y(2)**2*y(3) + 10*y(2)*y(3)**3 + 10*y(4)*y(2)*y(3)**2)) & !& - /(5*(y(1) + y(2))*(y(3) + y(4))*(y(1) + y(2) + y(3))*(y(2) + y(3) + y(4))*(y(1) + y(2) + y(3) + y(4))**2) !& - beta_coef_${XYZ}$ (i + 1, 0, 3) = (4*y(1)**2*(831*y(1)**6 + 3624*y(1)**5*y(2) + 3524*y(1)**5*y(3) + 1762*y(1)**5*y(4) + 4884*y(1)**4*y(2)**2 + 9058*y(1)**4*y(2)*y(3) + 4529*y(1)**4*y(2)*y(4) + 4224*y(1)**4*y(3)**2 + 4224*y(1)**4*y(3)*y(4) + 1081*y(1)**4*y(4)**2 + 2565*y(1)**3*y(2)**3 & !& - + 6120*y(1)**3*y(2)**2*y(3) + 3060*y(1)**3*y(2)**2*y(4) + 4755*y(1)**3*y(2)*y(3)**2 + 4755*y(1)**3*y(2)*y(3)*y(4) + 1315*y(1)**3*y(2)*y(4)**2 + 1200*y(1)**3*y(3)**3 + 1800*y(1)**3*y(3)**2*y(4) + 1000*y(1)**3*y(3)*y(4)**2 + 200*y(1)**3*y(4)**3 + 1395*y(1)**2*y(2)**4 & !& - + 4380*y(1)**2*y(2)**3*y(3) + 2190*y(1)**2*y(2)**3*y(4) + 5025*y(1)**2*y(2)**2*y(3)**2 + 5025*y(1)**2*y(2)**2*y(3)*y(4) + 1390*y(1)**2*y(2)**2*y(4)**2 + 2490*y(1)**2*y(2)*y(3)**3 + 3735*y(1)**2*y(2)*y(3)**2*y(4) + 2075*y(1)**2*y(2)*y(3)*y(4)**2 & !& - + 415*y(1)**2*y(2)*y(4)**3 + 450*y(1)**2*y(3)**4 + 900*y(1)**2*y(3)**3*y(4) + 750*y(1)**2*y(3)**2*y(4)**2 + 300*y(1)**2*y(3)*y(4)**3 + 50*y(1)**2*y(4)**4 + 135*y(1)*y(2)**5 + 450*y(1)*y(2)**4*y(3) + 225*y(1)*y(2)**4*y(4) + 540*y(1)*y(2)**3*y(3)**2 & !& - + 540*y(1)*y(2)**3*y(3)*y(4) + 150*y(1)*y(2)**3*y(4)**2 + 270*y(1)*y(2)**2*y(3)**3 + 405*y(1)*y(2)**2*y(3)**2*y(4) + 225*y(1)*y(2)**2*y(3)*y(4)**2 + 45*y(1)*y(2)**2*y(4)**3 + 45*y(1)*y(2)*y(3)**4 + 90*y(1)*y(2)*y(3)**3*y(4) + 75*y(1)*y(2)*y(3)**2*y(4)**2 & !& - + 30*y(1)*y(2)*y(3)*y(4)**3 + 5*y(1)*y(2)*y(4)**4 + 45*y(2)**6 + 180*y(2)**5*y(3) + 90*y(2)**5*y(4) + 270*y(2)**4*y(3)**2 + 270*y(2)**4*y(3)*y(4) + 75*y(2)**4*y(4)**2 + 180*y(2)**3*y(3)**3 + 270*y(2)**3*y(3)**2*y(4) + 150*y(2)**3*y(3)*y(4)**2 + 30*y(2)**3*y(4)**3 & !& - + 45*y(2)**2*y(3)**4 + 90*y(2)**2*y(3)**3*y(4) + 75*y(2)**2*y(3)**2*y(4)**2 + 30*y(2)**2*y(3)*y(4)**3 + 5*y(2)**2*y(4)**4))/(5*(y(2) + y(3))**2*(y(1) + y(2) + y(3))**2*(y(2) + y(3) + y(4))**2*(y(1) + y(2) + y(3) + y(4))**2) !& - beta_coef_${XYZ}$ (i + 1, 0, 4) = -(4*y(1)**2*(1767*y(1)**5 + 4464*y(1)**4*y(2) + 4154*y(1)**4*y(3) + 2077*y(1)**4*y(4) + 2655*y(1)**3*y(2)**2 + 4010*y(1)**3*y(2)*y(3) + 2005*y(1)**3*y(2)*y(4) + 1460*y(1)**3*y(3)**2 + 1460*y(1)**3*y(3)*y(4) + 415*y(1)**3*y(4)**2 + 1800*y(1)**2*y(2)**3 & !& - + 4000*y(1)**2*y(2)**2*y(3) + 2000*y(1)**2*y(2)**2*y(4) + 2850*y(1)**2*y(2)*y(3)**2 + 2850*y(1)**2*y(2)*y(3)*y(4) + 790*y(1)**2*y(2)*y(4)**2 + 650*y(1)**2*y(3)**3 + 975*y(1)**2*y(3)**2*y(4) + 535*y(1)**2*y(3)*y(4)**2 + 105*y(1)**2*y(4)**3 + 270*y(1)*y(2)**4 & !& - + 720*y(1)*y(2)**3*y(3) + 360*y(1)*y(2)**3*y(4) + 645*y(1)*y(2)**2*y(3)**2 + 645*y(1)*y(2)**2*y(3)*y(4) + 165*y(1)*y(2)**2*y(4)**2 + 210*y(1)*y(2)*y(3)**3 + 315*y(1)*y(2)*y(3)**2*y(4) + 155*y(1)*y(2)*y(3)*y(4)**2 + 25*y(1)*y(2)*y(4)**3 + 15*y(1)*y(3)**4 & !& - + 30*y(1)*y(3)**3*y(4) + 20*y(1)*y(3)**2*y(4)**2 + 5*y(1)*y(3)*y(4)**3 + 90*y(2)**5 + 300*y(2)**4*y(3) + 150*y(2)**4*y(4) + 360*y(2)**3*y(3)**2 + 360*y(2)**3*y(3)*y(4) + 90*y(2)**3*y(4)**2 + 180*y(2)**2*y(3)**3 + 270*y(2)**2*y(3)**2*y(4) + 130*y(2)**2*y(3)*y(4)**2 & !& - + 20*y(2)**2*y(4)**3 + 30*y(2)*y(3)**4 + 60*y(2)*y(3)**3*y(4) + 40*y(2)*y(3)**2*y(4)**2 + 10*y(2)*y(3)*y(4)**3))/(5*(y(1) + y(2))*(y(2) + y(3))*(y(1) + y(2) + y(3))**2*(y(2) + y(3) + y(4))*(y(1) + y(2) + y(3) + y(4))**2) !& - beta_coef_${XYZ}$ (i + 1, 0, 5) = (4*y(1)**2*(996*y(1)**4 + 675*y(1)**3*y(2) + 450*y(1)**3*y(3) + 225*y(1)**3*y(4) + 600*y(1)**2*y(2)**2 + 800*y(1)**2*y(2)*y(3) + 400*y(1)**2*y(2)*y(4) + 260*y(1)**2*y(3)**2 + 260*y(1)**2*y(3)*y(4) + 60*y(1)**2*y(4)**2 + 135*y(1)*y(2)**3 + 270*y(1)*y(2)**2*y(3) & !& - + 135*y(1)*y(2)**2*y(4) + 165*y(1)*y(2)*y(3)**2 + 165*y(1)*y(2)*y(3)*y(4) + 30*y(1)*y(2)*y(4)**2 + 30*y(1)*y(3)**3 + 45*y(1)*y(3)**2*y(4) + 15*y(1)*y(3)*y(4)**2 + 45*y(2)**4 + 120*y(2)**3*y(3) + 60*y(2)**3*y(4) + 110*y(2)**2*y(3)**2 + 110*y(2)**2*y(3)*y(4) & !& - + 20*y(2)**2*y(4)**2 + 40*y(2)*y(3)**3 + 60*y(2)*y(3)**2*y(4) + 20*y(2)*y(3)*y(4)**2 + 5*y(3)**4 + 10*y(3)**3*y(4) + 5*y(3)**2*y(4)**2))/(5*(y(1) + y(2))**2*(y(1) + y(2) + y(3))**2*(y(1) + y(2) + y(3) + y(4))**2) !& - + beta_coef_${XYZ}$ (i + 1, 0, & + & 0) = (4*y(1)**2*(831*y(1)**4 + 200*y(1)**3*y(2) + 100*y(1)**3*y(3) + 205*y(1) & + & **2*y(2)**2 + 205*y(1)**2*y(2)*y(3) + 50*y(1)**2*y(3)**2 + 10*y(1)*y(2)**3 & + & + 15*y(1)*y(2)**2*y(3) + 5*y(1)*y(2)*y(3)**2 + 5*y(2)**4 + 10*y(2)**3*y(3) & + & + 5*y(2)**2*y(3)**2))/(5*(y(3) + y(4))**2*(y(2) + y(3) + y(4))**2*(y(1) + y(2) & + & + y(3) + y(4))**2) + beta_coef_${XYZ}$ (i + 1, 0, & + & 1) = -(4*y(1)**2*(1662*y(1)**5 + 3824*y(1)**4*y(2) + 3624*y(1)**4*y(3) & + & + 1762*y(1)**4*y(4) + 1515*y(1)**3*y(2)**2 + 2115*y(1)**3*y(2)*y(3) + 805*y(1) & + & **3*y(2)*y(4) + 700*y(1)**3*y(3)**2 + 500*y(1)**3*y(3)*y(4) + 100*y(1)**3*y(4) & + & **2 + 1060*y(1)**2*y(2)**3 + 2205*y(1)**2*y(2)**2*y(3) + 835*y(1)**2*y(2)**2*y(4) & + & + 1445*y(1)**2*y(2)*y(3)**2 + 1030*y(1)**2*y(2)*y(3)*y(4) + 205*y(1)**2*y(2)*y(4) & + & **2 + 300*y(1)**2*y(3)**3 + 300*y(1)**2*y(3)**2*y(4) + 100*y(1)**2*y(3)*y(4)**2 & + & + 75*y(1)*y(2)**4 + 180*y(1)*y(2)**3*y(3) + 60*y(1)*y(2)**3*y(4) + 135*y(1)*y(2) & + & **2*y(3)**2 + 90*y(1)*y(2)**2*y(3)*y(4) + 15*y(1)*y(2)**2*y(4)**2 + 30*y(1)*y(2) & + & *y(3)**3 + 30*y(1)*y(2)*y(3)**2*y(4) + 10*y(1)*y(2)*y(3)*y(4)**2 + 30*y(2)**5 & + & + 90*y(2)**4*y(3) + 30*y(2)**4*y(4) + 90*y(2)**3*y(3)**2 + 60*y(2)**3*y(3)*y(4) & + & + 10*y(2)**3*y(4)**2 + 30*y(2)**2*y(3)**3 + 30*y(2)**2*y(3)**2*y(4) + 10*y(2) & + & **2*y(3)*y(4)**2))/(5*(y(2) + y(3))*(y(3) + y(4))*(y(1) + y(2) + y(3))*(y(2) & + & + y(3) + y(4))**2*(y(1) + y(2) + y(3) + y(4))**2) + beta_coef_${XYZ}$ (i + 1, 0, & + & 2) = (4*y(1)**2*(1767*y(1)**4 + 725*y(1)**3*y(2) + 415*y(1)**3*y(3) + 105*y(4) & + & *y(1)**3 + 665*y(1)**2*y(2)**2 + 775*y(1)**2*y(2)*y(3) + 220*y(4)*y(1)**2*y(2) & + & + 215*y(1)**2*y(3)**2 + 110*y(4)*y(1)**2*y(3) + 75*y(1)*y(2)**3 + 130*y(1)*y(2) & + & **2*y(3) + 35*y(4)*y(1)*y(2)**2 + 60*y(1)*y(2)*y(3)**2 + 35*y(4)*y(1)*y(2)*y(3) & + & + 5*y(1)*y(3)**3 + 5*y(4)*y(1)*y(3)**2 + 30*y(2)**4 + 70*y(2)**3*y(3) + 20*y(4) & + & *y(2)**3 + 50*y(2)**2*y(3)**2 + 30*y(4)*y(2)**2*y(3) + 10*y(2)*y(3)**3 + 10*y(4) & + & *y(2)*y(3)**2))/(5*(y(1) + y(2))*(y(3) + y(4))*(y(1) + y(2) + y(3))*(y(2) + y(3) & + & + y(4))*(y(1) + y(2) + y(3) + y(4))**2) + beta_coef_${XYZ}$ (i + 1, 0, & + & 3) = (4*y(1)**2*(831*y(1)**6 + 3624*y(1)**5*y(2) + 3524*y(1)**5*y(3) + 1762*y(1) & + & **5*y(4) + 4884*y(1)**4*y(2)**2 + 9058*y(1)**4*y(2)*y(3) + 4529*y(1)**4*y(2)*y(4) & + & + 4224*y(1)**4*y(3)**2 + 4224*y(1)**4*y(3)*y(4) + 1081*y(1)**4*y(4)**2 & + & + 2565*y(1)**3*y(2)**3 + 6120*y(1)**3*y(2)**2*y(3) + 3060*y(1)**3*y(2)**2*y(4) & + & + 4755*y(1)**3*y(2)*y(3)**2 + 4755*y(1)**3*y(2)*y(3)*y(4) + 1315*y(1)**3*y(2) & + & *y(4)**2 + 1200*y(1)**3*y(3)**3 + 1800*y(1)**3*y(3)**2*y(4) + 1000*y(1)**3*y(3) & + & *y(4)**2 + 200*y(1)**3*y(4)**3 + 1395*y(1)**2*y(2)**4 + 4380*y(1)**2*y(2)**3*y(3) & + & + 2190*y(1)**2*y(2)**3*y(4) + 5025*y(1)**2*y(2)**2*y(3)**2 + 5025*y(1)**2*y(2) & + & **2*y(3)*y(4) + 1390*y(1)**2*y(2)**2*y(4)**2 + 2490*y(1)**2*y(2)*y(3)**3 & + & + 3735*y(1)**2*y(2)*y(3)**2*y(4) + 2075*y(1)**2*y(2)*y(3)*y(4)**2 + 415*y(1) & + & **2*y(2)*y(4)**3 + 450*y(1)**2*y(3)**4 + 900*y(1)**2*y(3)**3*y(4) + 750*y(1) & + & **2*y(3)**2*y(4)**2 + 300*y(1)**2*y(3)*y(4)**3 + 50*y(1)**2*y(4)**4 + 135*y(1) & + & *y(2)**5 + 450*y(1)*y(2)**4*y(3) + 225*y(1)*y(2)**4*y(4) + 540*y(1)*y(2)**3*y(3) & + & **2 + 540*y(1)*y(2)**3*y(3)*y(4) + 150*y(1)*y(2)**3*y(4)**2 + 270*y(1)*y(2) & + & **2*y(3)**3 + 405*y(1)*y(2)**2*y(3)**2*y(4) + 225*y(1)*y(2)**2*y(3)*y(4)**2 & + & + 45*y(1)*y(2)**2*y(4)**3 + 45*y(1)*y(2)*y(3)**4 + 90*y(1)*y(2)*y(3)**3*y(4) & + & + 75*y(1)*y(2)*y(3)**2*y(4)**2 + 30*y(1)*y(2)*y(3)*y(4)**3 + 5*y(1)*y(2)*y(4)**4 & + & + 45*y(2)**6 + 180*y(2)**5*y(3) + 90*y(2)**5*y(4) + 270*y(2)**4*y(3)**2 & + & + 270*y(2)**4*y(3)*y(4) + 75*y(2)**4*y(4)**2 + 180*y(2)**3*y(3)**3 + 270*y(2) & + & **3*y(3)**2*y(4) + 150*y(2)**3*y(3)*y(4)**2 + 30*y(2)**3*y(4)**3 + 45*y(2) & + & **2*y(3)**4 + 90*y(2)**2*y(3)**3*y(4) + 75*y(2)**2*y(3)**2*y(4)**2 + 30*y(2) & + & **2*y(3)*y(4)**3 + 5*y(2)**2*y(4)**4))/(5*(y(2) + y(3))**2*(y(1) + y(2) + y(3)) & + & **2*(y(2) + y(3) + y(4))**2*(y(1) + y(2) + y(3) + y(4))**2) + beta_coef_${XYZ}$ (i + 1, 0, & + & 4) = -(4*y(1)**2*(1767*y(1)**5 + 4464*y(1)**4*y(2) + 4154*y(1)**4*y(3) & + & + 2077*y(1)**4*y(4) + 2655*y(1)**3*y(2)**2 + 4010*y(1)**3*y(2)*y(3) + 2005*y(1) & + & **3*y(2)*y(4) + 1460*y(1)**3*y(3)**2 + 1460*y(1)**3*y(3)*y(4) + 415*y(1)**3*y(4) & + & **2 + 1800*y(1)**2*y(2)**3 + 4000*y(1)**2*y(2)**2*y(3) + 2000*y(1)**2*y(2) & + & **2*y(4) + 2850*y(1)**2*y(2)*y(3)**2 + 2850*y(1)**2*y(2)*y(3)*y(4) + 790*y(1) & + & **2*y(2)*y(4)**2 + 650*y(1)**2*y(3)**3 + 975*y(1)**2*y(3)**2*y(4) + 535*y(1) & + & **2*y(3)*y(4)**2 + 105*y(1)**2*y(4)**3 + 270*y(1)*y(2)**4 + 720*y(1)*y(2)**3*y(3) & + & + 360*y(1)*y(2)**3*y(4) + 645*y(1)*y(2)**2*y(3)**2 + 645*y(1)*y(2)**2*y(3)*y(4) & + & + 165*y(1)*y(2)**2*y(4)**2 + 210*y(1)*y(2)*y(3)**3 + 315*y(1)*y(2)*y(3)**2*y(4) & + & + 155*y(1)*y(2)*y(3)*y(4)**2 + 25*y(1)*y(2)*y(4)**3 + 15*y(1)*y(3)**4 + 30*y(1) & + & *y(3)**3*y(4) + 20*y(1)*y(3)**2*y(4)**2 + 5*y(1)*y(3)*y(4)**3 + 90*y(2)**5 & + & + 300*y(2)**4*y(3) + 150*y(2)**4*y(4) + 360*y(2)**3*y(3)**2 + 360*y(2)**3*y(3) & + & *y(4) + 90*y(2)**3*y(4)**2 + 180*y(2)**2*y(3)**3 + 270*y(2)**2*y(3)**2*y(4) & + & + 130*y(2)**2*y(3)*y(4)**2 + 20*y(2)**2*y(4)**3 + 30*y(2)*y(3)**4 + 60*y(2)*y(3) & + & **3*y(4) + 40*y(2)*y(3)**2*y(4)**2 + 10*y(2)*y(3)*y(4)**3))/(5*(y(1) + y(2)) & + & *(y(2) + y(3))*(y(1) + y(2) + y(3))**2*(y(2) + y(3) + y(4))*(y(1) + y(2) + y(3) & + & + y(4))**2) + beta_coef_${XYZ}$ (i + 1, 0, & + & 5) = (4*y(1)**2*(996*y(1)**4 + 675*y(1)**3*y(2) + 450*y(1)**3*y(3) + 225*y(1) & + & **3*y(4) + 600*y(1)**2*y(2)**2 + 800*y(1)**2*y(2)*y(3) + 400*y(1)**2*y(2)*y(4) & + & + 260*y(1)**2*y(3)**2 + 260*y(1)**2*y(3)*y(4) + 60*y(1)**2*y(4)**2 + 135*y(1) & + & *y(2)**3 + 270*y(1)*y(2)**2*y(3) + 135*y(1)*y(2)**2*y(4) + 165*y(1)*y(2)*y(3)**2 & + & + 165*y(1)*y(2)*y(3)*y(4) + 30*y(1)*y(2)*y(4)**2 + 30*y(1)*y(3)**3 + 45*y(1)*y(3) & + & **2*y(4) + 15*y(1)*y(3)*y(4)**2 + 45*y(2)**4 + 120*y(2)**3*y(3) + 60*y(2)**3*y(4) & + & + 110*y(2)**2*y(3)**2 + 110*y(2)**2*y(3)*y(4) + 20*y(2)**2*y(4)**2 + 40*y(2)*y(3) & + & **3 + 60*y(2)*y(3)**2*y(4) + 20*y(2)*y(3)*y(4)**2 + 5*y(3)**4 + 10*y(3)**3*y(4) & + & + 5*y(3)**2*y(4)**2))/(5*(y(1) + y(2))**2*(y(1) + y(2) + y(3))**2*(y(1) + y(2) & + & + y(3) + y(4))**2) end do - - else ! TENO (only supports uniform grid) + else ! TENO (only supports uniform grid) ! (Fu, et al., 2016) Table 2 (for right flux) - d_cbL_${XYZ}$ (0, :) = 18._wp/35._wp - d_cbL_${XYZ}$ (1, :) = 3._wp/35._wp - d_cbL_${XYZ}$ (2, :) = 9._wp/35._wp - d_cbL_${XYZ}$ (3, :) = 1._wp/35._wp - d_cbL_${XYZ}$ (4, :) = 4._wp/35._wp - - d_cbR_${XYZ}$ (0, :) = 18._wp/35._wp - d_cbR_${XYZ}$ (1, :) = 9._wp/35._wp - d_cbR_${XYZ}$ (2, :) = 3._wp/35._wp - d_cbR_${XYZ}$ (3, :) = 4._wp/35._wp - d_cbR_${XYZ}$ (4, :) = 1._wp/35._wp - + d_cbL_${XYZ}$ (0,:) = 18._wp/35._wp + d_cbL_${XYZ}$ (1,:) = 3._wp/35._wp + d_cbL_${XYZ}$ (2,:) = 9._wp/35._wp + d_cbL_${XYZ}$ (3,:) = 1._wp/35._wp + d_cbL_${XYZ}$ (4,:) = 4._wp/35._wp + + d_cbR_${XYZ}$ (0,:) = 18._wp/35._wp + d_cbR_${XYZ}$ (1,:) = 9._wp/35._wp + d_cbR_${XYZ}$ (2,:) = 3._wp/35._wp + d_cbR_${XYZ}$ (3,:) = 4._wp/35._wp + d_cbR_${XYZ}$ (4,:) = 1._wp/35._wp end if end if - end if #:endfor if (weno_dir == 1) then - $:GPU_UPDATE(device='[poly_coef_cbL_x,poly_coef_cbR_x,d_cbL_x,d_cbR_x,beta_coef_x]') - elseif (weno_dir == 2) then - $:GPU_UPDATE(device='[poly_coef_cbL_y,poly_coef_cbR_y,d_cbL_y,d_cbR_y,beta_coef_y]') + $:GPU_UPDATE(device='[poly_coef_cbL_x, poly_coef_cbR_x, d_cbL_x, d_cbR_x, beta_coef_x]') + else if (weno_dir == 2) then + $:GPU_UPDATE(device='[poly_coef_cbL_y, poly_coef_cbR_y, d_cbL_y, d_cbR_y, beta_coef_y]') else - $:GPU_UPDATE(device='[poly_coef_cbL_z,poly_coef_cbR_z,d_cbL_z,d_cbR_z,beta_coef_z]') + $:GPU_UPDATE(device='[poly_coef_cbL_z, poly_coef_cbR_z, d_cbL_z, d_cbR_z, beta_coef_z]') end if ! Nullifying WENO coefficients and cell-boundary locations pointers @@ -626,45 +856,42 @@ contains end subroutine s_compute_weno_coefficients !> @brief Performs WENO reconstruction of left and right cell-boundary values from cell-averaged variables. - subroutine s_weno(v_vf, vL_rs_vf_x, vL_rs_vf_y, vL_rs_vf_z, vR_rs_vf_x, vR_rs_vf_y, vR_rs_vf_z, & - weno_dir, & - is1_weno_d, is2_weno_d, is3_weno_d) + subroutine s_weno(v_vf, vL_rs_vf_x, vL_rs_vf_y, vL_rs_vf_z, vR_rs_vf_x, vR_rs_vf_y, vR_rs_vf_z, weno_dir, is1_weno_d, & + & is2_weno_d, is3_weno_d) - type(scalar_field), dimension(1:), intent(in) :: v_vf - real(wp), dimension(idwbuff(1)%beg:, idwbuff(2)%beg:, idwbuff(3)%beg:, 1:), intent(inout) :: vL_rs_vf_x, vL_rs_vf_y, vL_rs_vf_z - real(wp), dimension(idwbuff(1)%beg:, idwbuff(2)%beg:, idwbuff(3)%beg:, 1:), intent(inout) :: vR_rs_vf_x, vR_rs_vf_y, vR_rs_vf_z - integer, intent(in) :: weno_dir - type(int_bounds_info), intent(in) :: is1_weno_d, is2_weno_d, is3_weno_d + type(scalar_field), dimension(1:), intent(in) :: v_vf + real(wp), dimension(idwbuff(1)%beg:,idwbuff(2)%beg:,idwbuff(3)%beg:,1:), intent(inout) :: vL_rs_vf_x, vL_rs_vf_y, vL_rs_vf_z + real(wp), dimension(idwbuff(1)%beg:,idwbuff(2)%beg:,idwbuff(3)%beg:,1:), intent(inout) :: vR_rs_vf_x, vR_rs_vf_y, vR_rs_vf_z + integer, intent(in) :: weno_dir + type(int_bounds_info), intent(in) :: is1_weno_d, is2_weno_d, is3_weno_d #:if not MFC_CASE_OPTIMIZATION and USING_AMD real(wp), dimension(-3:2) :: dvd - real(wp), dimension(0:4) :: poly - real(wp), dimension(0:4) :: alpha - real(wp), dimension(0:4) :: omega - real(wp), dimension(0:4) :: beta - real(wp), dimension(0:4) :: delta + real(wp), dimension(0:4) :: poly + real(wp), dimension(0:4) :: alpha + real(wp), dimension(0:4) :: omega + real(wp), dimension(0:4) :: beta + real(wp), dimension(0:4) :: delta #:else real(wp), dimension(-weno_polyn:weno_polyn - 1) :: dvd - real(wp), dimension(0:weno_num_stencils) :: poly - real(wp), dimension(0:weno_num_stencils) :: alpha - real(wp), dimension(0:weno_num_stencils) :: omega - real(wp), dimension(0:weno_num_stencils) :: beta - real(wp), dimension(0:weno_num_stencils) :: delta + real(wp), dimension(0:weno_num_stencils) :: poly + real(wp), dimension(0:weno_num_stencils) :: alpha + real(wp), dimension(0:weno_num_stencils) :: omega + real(wp), dimension(0:weno_num_stencils) :: beta + real(wp), dimension(0:weno_num_stencils) :: delta #:endif - real(wp), dimension(-3:3) :: v ! temporary field value array for clarity (WENO7 only) - real(wp) :: tau - - integer :: i, j, k, l, q + real(wp), dimension(-3:3) :: v ! temporary field value array for clarity (WENO7 only) + real(wp) :: tau + integer :: i, j, k, l, q is1_weno = is1_weno_d is2_weno = is2_weno_d is3_weno = is3_weno_d - $:GPU_UPDATE(device='[is1_weno,is2_weno,is3_weno]') + $:GPU_UPDATE(device='[is1_weno, is2_weno, is3_weno]') if (weno_order /= 1 .or. dummy) then - call s_initialize_weno(v_vf, & - weno_dir) + call s_initialize_weno(v_vf, weno_dir) end if if (weno_order == 1 .or. dummy) then @@ -712,7 +939,7 @@ contains if (weno_order == 3 .or. dummy) then #:for WENO_DIR, XYZ in [(1, 'x'), (2, 'y'), (3, 'z')] if (weno_dir == ${WENO_DIR}$) then - $:GPU_PARALLEL_LOOP(collapse=4,private='[beta,dvd,poly,omega,alpha,tau]') + $:GPU_PARALLEL_LOOP(collapse=4,private='[beta, dvd, poly, omega, alpha, tau]') do l = is3_weno%beg, is3_weno%end do k = is2_weno%beg, is2_weno%end do j = is1_weno%beg, is1_weno%end @@ -723,36 +950,34 @@ contains omega(:) = 0._wp beta(:) = weno_eps - dvd(0) = v_rs_ws_${XYZ}$ (j + 1, k, l, i) & - - v_rs_ws_${XYZ}$ (j, k, l, i) - dvd(-1) = v_rs_ws_${XYZ}$ (j, k, l, i) & - - v_rs_ws_${XYZ}$ (j - 1, k, l, i) + dvd(0) = v_rs_ws_${XYZ}$ (j + 1, k, l, i) - v_rs_ws_${XYZ}$ (j, k, l, i) + dvd(-1) = v_rs_ws_${XYZ}$ (j, k, l, i) - v_rs_ws_${XYZ}$ (j - 1, k, l, i) - poly(0) = v_rs_ws_${XYZ}$ (j, k, l, i) & - + poly_coef_cbL_${XYZ}$ (j, 0, 0)*dvd(0) - poly(1) = v_rs_ws_${XYZ}$ (j, k, l, i) & - + poly_coef_cbL_${XYZ}$ (j, 1, 0)*dvd(-1) + poly(0) = v_rs_ws_${XYZ}$ (j, k, l, i) + poly_coef_cbL_${XYZ}$ (j, 0, 0)*dvd(0) + poly(1) = v_rs_ws_${XYZ}$ (j, k, l, i) + poly_coef_cbL_${XYZ}$ (j, 1, 0)*dvd(-1) - beta(0) = beta_coef_${XYZ}$ (j, 0, 0)*dvd(0)*dvd(0) & - + weno_eps - beta(1) = beta_coef_${XYZ}$ (j, 1, 0)*dvd(-1)*dvd(-1) & - + weno_eps + beta(0) = beta_coef_${XYZ}$ (j, 0, 0)*dvd(0)*dvd(0) + weno_eps + beta(1) = beta_coef_${XYZ}$ (j, 1, 0)*dvd(-1)*dvd(-1) + weno_eps if (wenojs) then - alpha(0:weno_num_stencils) = d_cbL_${XYZ}$ (0:weno_num_stencils, j)/(beta(0:weno_num_stencils)**2._wp) - - elseif (mapped_weno) then - alpha(0:weno_num_stencils) = d_cbL_${XYZ}$ (0:weno_num_stencils, j)/(beta(0:weno_num_stencils)**2._wp) + alpha(0:weno_num_stencils) = d_cbL_${XYZ}$ (0:weno_num_stencils, & + & j)/(beta(0:weno_num_stencils)**2._wp) + else if (mapped_weno) then + alpha(0:weno_num_stencils) = d_cbL_${XYZ}$ (0:weno_num_stencils, & + & j)/(beta(0:weno_num_stencils)**2._wp) omega = alpha/sum(alpha) - alpha(0:weno_num_stencils) = (d_cbL_${XYZ}$ (0:weno_num_stencils, j)*(1._wp + d_cbL_${XYZ}$ (0:weno_num_stencils, j) - 3._wp*omega(0:weno_num_stencils)) + omega(0:weno_num_stencils)**2._wp) & - *(omega(0:weno_num_stencils)/(d_cbL_${XYZ}$ (0:weno_num_stencils, j)**2._wp + omega(0:weno_num_stencils)*(1._wp - 2._wp*d_cbL_${XYZ}$ (0:weno_num_stencils, j)))) - - elseif (wenoz) then + alpha(0:weno_num_stencils) = (d_cbL_${XYZ}$ (0:weno_num_stencils, & + & j)*(1._wp + d_cbL_${XYZ}$ (0:weno_num_stencils, & + & j) - 3._wp*omega(0:weno_num_stencils)) + omega(0:weno_num_stencils)**2._wp) & + & *(omega(0:weno_num_stencils)/(d_cbL_${XYZ}$ (0:weno_num_stencils, & + & j)**2._wp + omega(0:weno_num_stencils)*(1._wp & + & - 2._wp*d_cbL_${XYZ}$ (0:weno_num_stencils,j)))) + else if (wenoz) then ! Borges, et al. (2008) tau = abs(beta(1) - beta(0)) - alpha(0:weno_num_stencils) = d_cbL_${XYZ}$ (0:weno_num_stencils, j)*(1._wp + tau/beta(0:weno_num_stencils)) - + alpha(0:weno_num_stencils) = d_cbL_${XYZ}$ (0:weno_num_stencils, & + & j)*(1._wp + tau/beta(0:weno_num_stencils)) end if omega = alpha/sum(alpha) @@ -761,30 +986,30 @@ contains ! reconstruct from right side - poly(0) = v_rs_ws_${XYZ}$ (j, k, l, i) & - + poly_coef_cbR_${XYZ}$ (j, 0, 0)*dvd(0) - poly(1) = v_rs_ws_${XYZ}$ (j, k, l, i) & - + poly_coef_cbR_${XYZ}$ (j, 1, 0)*dvd(-1) + poly(0) = v_rs_ws_${XYZ}$ (j, k, l, i) + poly_coef_cbR_${XYZ}$ (j, 0, 0)*dvd(0) + poly(1) = v_rs_ws_${XYZ}$ (j, k, l, i) + poly_coef_cbR_${XYZ}$ (j, 1, 0)*dvd(-1) if (wenojs) then - alpha(0:weno_num_stencils) = d_cbR_${XYZ}$ (0:weno_num_stencils, j)/(beta(0:weno_num_stencils)**2._wp) - - elseif (mapped_weno) then - alpha(0:weno_num_stencils) = d_cbR_${XYZ}$ (0:weno_num_stencils, j)/(beta(0:weno_num_stencils)**2._wp) + alpha(0:weno_num_stencils) = d_cbR_${XYZ}$ (0:weno_num_stencils, & + & j)/(beta(0:weno_num_stencils)**2._wp) + else if (mapped_weno) then + alpha(0:weno_num_stencils) = d_cbR_${XYZ}$ (0:weno_num_stencils, & + & j)/(beta(0:weno_num_stencils)**2._wp) omega = alpha/sum(alpha) - alpha(0:weno_num_stencils) = (d_cbR_${XYZ}$ (0:weno_num_stencils, j)*(1._wp + d_cbR_${XYZ}$ (0:weno_num_stencils, j) - 3._wp*omega(0:weno_num_stencils)) + omega(0:weno_num_stencils)**2._wp) & - *(omega(0:weno_num_stencils)/(d_cbR_${XYZ}$ (0:weno_num_stencils, j)**2._wp + omega(0:weno_num_stencils)*(1._wp - 2._wp*d_cbR_${XYZ}$ (0:weno_num_stencils, j)))) - - elseif (wenoz) then - - alpha(0:weno_num_stencils) = d_cbR_${XYZ}$ (0:weno_num_stencils, j)*(1._wp + tau/beta(0:weno_num_stencils)) - + alpha(0:weno_num_stencils) = (d_cbR_${XYZ}$ (0:weno_num_stencils, & + & j)*(1._wp + d_cbR_${XYZ}$ (0:weno_num_stencils, & + & j) - 3._wp*omega(0:weno_num_stencils)) + omega(0:weno_num_stencils)**2._wp) & + & *(omega(0:weno_num_stencils)/(d_cbR_${XYZ}$ (0:weno_num_stencils, & + & j)**2._wp + omega(0:weno_num_stencils)*(1._wp & + & - 2._wp*d_cbR_${XYZ}$ (0:weno_num_stencils,j)))) + else if (wenoz) then + alpha(0:weno_num_stencils) = d_cbR_${XYZ}$ (0:weno_num_stencils, & + & j)*(1._wp + tau/beta(0:weno_num_stencils)) end if omega = alpha/sum(alpha) vR_rs_vf_${XYZ}$ (j, k, l, i) = omega(0)*poly(0) + omega(1)*poly(1) - end do end do end do @@ -797,7 +1022,7 @@ contains #:if not MFC_CASE_OPTIMIZATION or weno_num_stencils > 1 #:for WENO_DIR, XYZ in [(1, 'x'), (2, 'y'), (3, 'z')] if (weno_dir == ${WENO_DIR}$) then - $:GPU_PARALLEL_LOOP(collapse=3,private='[dvd,poly,beta,alpha,omega,tau,delta,q]') + $:GPU_PARALLEL_LOOP(collapse=3,private='[dvd, poly, beta, alpha, omega, tau, delta, q]') do l = is3_weno%beg, is3_weno%end do k = is2_weno%beg, is2_weno%end do j = is1_weno%beg, is1_weno%end @@ -810,76 +1035,67 @@ contains delta(:) = 0._wp beta(:) = weno_eps - dvd(1) = v_rs_ws_${XYZ}$ (j + 2, k, l, i) & - - v_rs_ws_${XYZ}$ (j + 1, k, l, i) - dvd(0) = v_rs_ws_${XYZ}$ (j + 1, k, l, i) & - - v_rs_ws_${XYZ}$ (j, k, l, i) - dvd(-1) = v_rs_ws_${XYZ}$ (j, k, l, i) & - - v_rs_ws_${XYZ}$ (j - 1, k, l, i) - dvd(-2) = v_rs_ws_${XYZ}$ (j - 1, k, l, i) & - - v_rs_ws_${XYZ}$ (j - 2, k, l, i) - - poly(0) = v_rs_ws_${XYZ}$ (j, k, l, i) & - + poly_coef_cbL_${XYZ}$ (j, 0, 0)*dvd(1) & - + poly_coef_cbL_${XYZ}$ (j, 0, 1)*dvd(0) - poly(1) = v_rs_ws_${XYZ}$ (j, k, l, i) & - + poly_coef_cbL_${XYZ}$ (j, 1, 0)*dvd(0) & - + poly_coef_cbL_${XYZ}$ (j, 1, 1)*dvd(-1) - poly(2) = v_rs_ws_${XYZ}$ (j, k, l, i) & - + poly_coef_cbL_${XYZ}$ (j, 2, 0)*dvd(-1) & - + poly_coef_cbL_${XYZ}$ (j, 2, 1)*dvd(-2) - - beta(0) = beta_coef_${XYZ}$ (j, 0, 0)*dvd(1)*dvd(1) & - + beta_coef_${XYZ}$ (j, 0, 1)*dvd(1)*dvd(0) & - + beta_coef_${XYZ}$ (j, 0, 2)*dvd(0)*dvd(0) & - + weno_eps - beta(1) = beta_coef_${XYZ}$ (j, 1, 0)*dvd(0)*dvd(0) & - + beta_coef_${XYZ}$ (j, 1, 1)*dvd(0)*dvd(-1) & - + beta_coef_${XYZ}$ (j, 1, 2)*dvd(-1)*dvd(-1) & - + weno_eps - beta(2) = beta_coef_${XYZ}$ (j, 2, 0)*dvd(-1)*dvd(-1) & - + beta_coef_${XYZ}$ (j, 2, 1)*dvd(-1)*dvd(-2) & - + beta_coef_${XYZ}$ (j, 2, 2)*dvd(-2)*dvd(-2) & - + weno_eps + dvd(1) = v_rs_ws_${XYZ}$ (j + 2, k, l, i) - v_rs_ws_${XYZ}$ (j + 1, k, l, i) + dvd(0) = v_rs_ws_${XYZ}$ (j + 1, k, l, i) - v_rs_ws_${XYZ}$ (j, k, l, i) + dvd(-1) = v_rs_ws_${XYZ}$ (j, k, l, i) - v_rs_ws_${XYZ}$ (j - 1, k, l, i) + dvd(-2) = v_rs_ws_${XYZ}$ (j - 1, k, l, i) - v_rs_ws_${XYZ}$ (j - 2, k, l, i) + + poly(0) = v_rs_ws_${XYZ}$ (j, k, l, i) + poly_coef_cbL_${XYZ}$ (j, 0, & + & 0)*dvd(1) + poly_coef_cbL_${XYZ}$ (j, 0, 1)*dvd(0) + poly(1) = v_rs_ws_${XYZ}$ (j, k, l, i) + poly_coef_cbL_${XYZ}$ (j, 1, & + & 0)*dvd(0) + poly_coef_cbL_${XYZ}$ (j, 1, 1)*dvd(-1) + poly(2) = v_rs_ws_${XYZ}$ (j, k, l, i) + poly_coef_cbL_${XYZ}$ (j, 2, & + & 0)*dvd(-1) + poly_coef_cbL_${XYZ}$ (j, 2, 1)*dvd(-2) + + beta(0) = beta_coef_${XYZ}$ (j, 0, 0)*dvd(1)*dvd(1) + beta_coef_${XYZ}$ (j, 0, & + & 1)*dvd(1)*dvd(0) + beta_coef_${XYZ}$ (j, 0, 2)*dvd(0)*dvd(0) + weno_eps + beta(1) = beta_coef_${XYZ}$ (j, 1, 0)*dvd(0)*dvd(0) + beta_coef_${XYZ}$ (j, 1, & + & 1)*dvd(0)*dvd(-1) + beta_coef_${XYZ}$ (j, 1, 2)*dvd(-1)*dvd(-1) + weno_eps + beta(2) = beta_coef_${XYZ}$ (j, 2, 0)*dvd(-1)*dvd(-1) + beta_coef_${XYZ}$ (j, 2, & + & 1)*dvd(-1)*dvd(-2) + beta_coef_${XYZ}$ (j, 2, 2)*dvd(-2)*dvd(-2) + weno_eps if (wenojs) then - alpha(0:weno_num_stencils) = d_cbL_${XYZ}$ (0:weno_num_stencils, j)/(beta(0:weno_num_stencils)**2._wp) - - elseif (mapped_weno) then - alpha(0:weno_num_stencils) = d_cbL_${XYZ}$ (0:weno_num_stencils, j)/(beta(0:weno_num_stencils)**2._wp) + alpha(0:weno_num_stencils) = d_cbL_${XYZ}$ (0:weno_num_stencils, & + & j)/(beta(0:weno_num_stencils)**2._wp) + else if (mapped_weno) then + alpha(0:weno_num_stencils) = d_cbL_${XYZ}$ (0:weno_num_stencils, & + & j)/(beta(0:weno_num_stencils)**2._wp) omega = alpha/sum(alpha) - alpha(0:weno_num_stencils) = (d_cbL_${XYZ}$ (0:weno_num_stencils, j)*(1._wp + d_cbL_${XYZ}$ (0:weno_num_stencils, j) - 3._wp*omega(0:weno_num_stencils)) + omega(0:weno_num_stencils)**2._wp) & - *(omega(0:weno_num_stencils)/(d_cbL_${XYZ}$ (0:weno_num_stencils, j)**2._wp + omega(0:weno_num_stencils)*(1._wp - 2._wp*d_cbL_${XYZ}$ (0:weno_num_stencils, j)))) - - elseif (wenoz) then - + alpha(0:weno_num_stencils) = (d_cbL_${XYZ}$ (0:weno_num_stencils, & + & j)*(1._wp + d_cbL_${XYZ}$ (0:weno_num_stencils, & + & j) - 3._wp*omega(0:weno_num_stencils)) + omega(0:weno_num_stencils)**2._wp) & + & *(omega(0:weno_num_stencils)/(d_cbL_${XYZ}$ (0:weno_num_stencils, & + & j)**2._wp + omega(0:weno_num_stencils)*(1._wp & + & - 2._wp*d_cbL_${XYZ}$ (0:weno_num_stencils,j)))) + else if (wenoz) then ! Borges, et al. (2008) - tau = abs(beta(2) - beta(0)) ! Equation 25 + tau = abs(beta(2) - beta(0)) ! Equation 25 $:GPU_LOOP(parallelism='[seq]') do q = 0, weno_num_stencils - alpha(q) = d_cbL_${XYZ}$ (q, j)*(1._wp + (tau/beta(q))) ! Equation 28 (note: weno_eps was already added to beta) + alpha(q) = d_cbL_${XYZ}$ (q, & + & j)*(1._wp + (tau/beta(q))) & + & ! Equation 28 (note: weno_eps was already added to beta) end do - - elseif (teno) then - ! Fu, et al. (2016) - ! Fu''s code: https://dx.doi.org/10.13140/RG.2.2.36250.34247 + else if (teno) then + ! Fu, et al. (2016) Fu''s code: https://dx.doi.org/10.13140/RG.2.2.36250.34247 tau = abs(beta(2) - beta(0)) $:GPU_LOOP(parallelism='[seq]') do q = 0, weno_num_stencils - alpha(q) = 1._wp + tau/beta(q) ! Equation 22 (reuse alpha as gamma; pick C=1 & q=6) - alpha(q) = (alpha(q)**3._wp)**2._wp ! Equation 22 cont. (some CPU compilers cannot optimize x**6.0) + alpha(q) = 1._wp + tau/beta(q) ! Equation 22 (reuse alpha as gamma; pick C=1 & q=6) + alpha(q) = (alpha(q)**3._wp) & + & **2._wp ! Equation 22 cont. (some CPU compilers cannot optimize x**6.0) end do - omega = alpha/sum(alpha) ! Equation 25 (reuse omega as xi) + omega = alpha/sum(alpha) ! Equation 25 (reuse omega as xi) $:GPU_LOOP(parallelism='[seq]') do q = 0, weno_num_stencils - if (omega(q) < teno_CT) then ! Equation 26 + if (omega(q) < teno_CT) then ! Equation 26 delta(q) = 0._wp else delta(q) = 1._wp end if - alpha(q) = delta(q)*d_cbL_${XYZ}$ (q, j) ! Equation 27 + alpha(q) = delta(q)*d_cbL_${XYZ}$ (q, j) ! Equation 27 end do end if @@ -889,33 +1105,32 @@ contains ! reconstruct from right side - poly(0) = v_rs_ws_${XYZ}$ (j, k, l, i) & - + poly_coef_cbR_${XYZ}$ (j, 0, 0)*dvd(1) & - + poly_coef_cbR_${XYZ}$ (j, 0, 1)*dvd(0) - poly(1) = v_rs_ws_${XYZ}$ (j, k, l, i) & - + poly_coef_cbR_${XYZ}$ (j, 1, 0)*dvd(0) & - + poly_coef_cbR_${XYZ}$ (j, 1, 1)*dvd(-1) - poly(2) = v_rs_ws_${XYZ}$ (j, k, l, i) & - + poly_coef_cbR_${XYZ}$ (j, 2, 0)*dvd(-1) & - + poly_coef_cbR_${XYZ}$ (j, 2, 1)*dvd(-2) + poly(0) = v_rs_ws_${XYZ}$ (j, k, l, i) + poly_coef_cbR_${XYZ}$ (j, 0, & + & 0)*dvd(1) + poly_coef_cbR_${XYZ}$ (j, 0, 1)*dvd(0) + poly(1) = v_rs_ws_${XYZ}$ (j, k, l, i) + poly_coef_cbR_${XYZ}$ (j, 1, & + & 0)*dvd(0) + poly_coef_cbR_${XYZ}$ (j, 1, 1)*dvd(-1) + poly(2) = v_rs_ws_${XYZ}$ (j, k, l, i) + poly_coef_cbR_${XYZ}$ (j, 2, & + & 0)*dvd(-1) + poly_coef_cbR_${XYZ}$ (j, 2, 1)*dvd(-2) if (wenojs) then - alpha(0:weno_num_stencils) = d_cbR_${XYZ}$ (0:weno_num_stencils, j)/(beta(0:weno_num_stencils)**2._wp) - - elseif (mapped_weno) then - alpha(0:weno_num_stencils) = d_cbR_${XYZ}$ (0:weno_num_stencils, j)/(beta(0:weno_num_stencils)**2._wp) + alpha(0:weno_num_stencils) = d_cbR_${XYZ}$ (0:weno_num_stencils, & + & j)/(beta(0:weno_num_stencils)**2._wp) + else if (mapped_weno) then + alpha(0:weno_num_stencils) = d_cbR_${XYZ}$ (0:weno_num_stencils, & + & j)/(beta(0:weno_num_stencils)**2._wp) omega = alpha/sum(alpha) - alpha(0:weno_num_stencils) = (d_cbR_${XYZ}$ (0:weno_num_stencils, j)*(1._wp + d_cbR_${XYZ}$ (0:weno_num_stencils, j) - 3._wp*omega(0:weno_num_stencils)) + omega(0:weno_num_stencils)**2._wp) & - *(omega(0:weno_num_stencils)/(d_cbR_${XYZ}$ (0:weno_num_stencils, j)**2._wp + omega(0:weno_num_stencils)*(1._wp - 2._wp*d_cbR_${XYZ}$ (0:weno_num_stencils, j)))) - - elseif (wenoz) then - + alpha(0:weno_num_stencils) = (d_cbR_${XYZ}$ (0:weno_num_stencils, & + & j)*(1._wp + d_cbR_${XYZ}$ (0:weno_num_stencils, & + & j) - 3._wp*omega(0:weno_num_stencils)) + omega(0:weno_num_stencils)**2._wp) & + & *(omega(0:weno_num_stencils)/(d_cbR_${XYZ}$ (0:weno_num_stencils, & + & j)**2._wp + omega(0:weno_num_stencils)*(1._wp & + & - 2._wp*d_cbR_${XYZ}$ (0:weno_num_stencils,j)))) + else if (wenoz) then $:GPU_LOOP(parallelism='[seq]') do q = 0, weno_num_stencils alpha(q) = d_cbR_${XYZ}$ (q, j)*(1._wp + (tau/beta(q))) end do - - elseif (teno) then + else if (teno) then $:GPU_LOOP(parallelism='[seq]') do q = 0, weno_num_stencils alpha(q) = delta(q)*d_cbR_${XYZ}$ (q, j) @@ -925,7 +1140,6 @@ contains omega = alpha/sum(alpha) vR_rs_vf_${XYZ}$ (j, k, l, i) = omega(0)*poly(0) + omega(1)*poly(1) + omega(2)*poly(2) - end do end do end do @@ -933,8 +1147,7 @@ contains $:END_GPU_PARALLEL_LOOP() if (mp_weno) then - call s_preserve_monotonicity(v_rs_ws_${XYZ}$, vL_rs_vf_${XYZ}$, & - vR_rs_vf_${XYZ}$) + call s_preserve_monotonicity(v_rs_ws_${XYZ}$, vL_rs_vf_${XYZ}$, vR_rs_vf_${XYZ}$) end if end if #:endfor @@ -944,161 +1157,144 @@ contains #:if not MFC_CASE_OPTIMIZATION or weno_num_stencils > 2 #:for WENO_DIR, XYZ in [(1, 'x'), (2, 'y'), (3, 'z')] if (weno_dir == ${WENO_DIR}$) then - $:GPU_PARALLEL_LOOP(collapse=3,private='[poly,beta,alpha,omega,tau,delta,dvd,v,q]') + $:GPU_PARALLEL_LOOP(collapse=3,private='[poly, beta, alpha, omega, tau, delta, dvd, v, q]') do l = is3_weno%beg, is3_weno%end do k = is2_weno%beg, is2_weno%end do j = is1_weno%beg, is1_weno%end $:GPU_LOOP(parallelism='[seq]') do i = 1, v_size - alpha(:) = 0._wp omega(:) = 0._wp delta(:) = 0._wp beta(:) = weno_eps - if (teno) v = v_rs_ws_${XYZ}$ (j - 3:j + 3, k, l, i) ! temporary field value array for clarity + if (teno) v = v_rs_ws_${XYZ}$ (j - 3:j + 3,k, l, & + & i) ! temporary field value array for clarity if (.not. teno) then - dvd(2) = v_rs_ws_${XYZ}$ (j + 3, k, l, i) & - - v_rs_ws_${XYZ}$ (j + 2, k, l, i) - dvd(1) = v_rs_ws_${XYZ}$ (j + 2, k, l, i) & - - v_rs_ws_${XYZ}$ (j + 1, k, l, i) - dvd(0) = v_rs_ws_${XYZ}$ (j + 1, k, l, i) & - - v_rs_ws_${XYZ}$ (j, k, l, i) - dvd(-1) = v_rs_ws_${XYZ}$ (j, k, l, i) & - - v_rs_ws_${XYZ}$ (j - 1, k, l, i) - dvd(-2) = v_rs_ws_${XYZ}$ (j - 1, k, l, i) & - - v_rs_ws_${XYZ}$ (j - 2, k, l, i) - dvd(-3) = v_rs_ws_${XYZ}$ (j - 2, k, l, i) & - - v_rs_ws_${XYZ}$ (j - 3, k, l, i) - - poly(3) = v_rs_ws_${XYZ}$ (j, k, l, i) & - + poly_coef_cbL_${XYZ}$ (j, 0, 0)*dvd(2) & - + poly_coef_cbL_${XYZ}$ (j, 0, 1)*dvd(1) & - + poly_coef_cbL_${XYZ}$ (j, 0, 2)*dvd(0) - poly(2) = v_rs_ws_${XYZ}$ (j, k, l, i) & - + poly_coef_cbL_${XYZ}$ (j, 1, 0)*dvd(1) & - + poly_coef_cbL_${XYZ}$ (j, 1, 1)*dvd(0) & - + poly_coef_cbL_${XYZ}$ (j, 1, 2)*dvd(-1) - poly(1) = v_rs_ws_${XYZ}$ (j, k, l, i) & - + poly_coef_cbL_${XYZ}$ (j, 2, 0)*dvd(0) & - + poly_coef_cbL_${XYZ}$ (j, 2, 1)*dvd(-1) & - + poly_coef_cbL_${XYZ}$ (j, 2, 2)*dvd(-2) - poly(0) = v_rs_ws_${XYZ}$ (j, k, l, i) & - + poly_coef_cbL_${XYZ}$ (j, 3, 0)*dvd(-1) & - + poly_coef_cbL_${XYZ}$ (j, 3, 1)*dvd(-2) & - + poly_coef_cbL_${XYZ}$ (j, 3, 2)*dvd(-3) - + dvd(2) = v_rs_ws_${XYZ}$ (j + 3, k, l, i) - v_rs_ws_${XYZ}$ (j + 2, k, l, i) + dvd(1) = v_rs_ws_${XYZ}$ (j + 2, k, l, i) - v_rs_ws_${XYZ}$ (j + 1, k, l, i) + dvd(0) = v_rs_ws_${XYZ}$ (j + 1, k, l, i) - v_rs_ws_${XYZ}$ (j, k, l, i) + dvd(-1) = v_rs_ws_${XYZ}$ (j, k, l, i) - v_rs_ws_${XYZ}$ (j - 1, k, l, i) + dvd(-2) = v_rs_ws_${XYZ}$ (j - 1, k, l, i) - v_rs_ws_${XYZ}$ (j - 2, k, l, i) + dvd(-3) = v_rs_ws_${XYZ}$ (j - 2, k, l, i) - v_rs_ws_${XYZ}$ (j - 3, k, l, i) + + poly(3) = v_rs_ws_${XYZ}$ (j, k, l, i) + poly_coef_cbL_${XYZ}$ (j, 0, & + & 0)*dvd(2) + poly_coef_cbL_${XYZ}$ (j, 0, 1)*dvd(1) + poly_coef_cbL_${XYZ}$ (j, & + & 0, 2)*dvd(0) + poly(2) = v_rs_ws_${XYZ}$ (j, k, l, i) + poly_coef_cbL_${XYZ}$ (j, 1, & + & 0)*dvd(1) + poly_coef_cbL_${XYZ}$ (j, 1, 1)*dvd(0) + poly_coef_cbL_${XYZ}$ (j, & + & 1, 2)*dvd(-1) + poly(1) = v_rs_ws_${XYZ}$ (j, k, l, i) + poly_coef_cbL_${XYZ}$ (j, 2, & + & 0)*dvd(0) + poly_coef_cbL_${XYZ}$ (j, 2, & + & 1)*dvd(-1) + poly_coef_cbL_${XYZ}$ (j, 2, 2)*dvd(-2) + poly(0) = v_rs_ws_${XYZ}$ (j, k, l, i) + poly_coef_cbL_${XYZ}$ (j, 3, & + & 0)*dvd(-1) + poly_coef_cbL_${XYZ}$ (j, 3, & + & 1)*dvd(-2) + poly_coef_cbL_${XYZ}$ (j, 3, 2)*dvd(-3) else #:if not MFC_CASE_OPTIMIZATION or weno_num_stencils > 3 - ! (Fu, et al., 2016) Table 1 - ! Note: Unlike TENO5, TENO7 stencils differ from WENO7 stencils - ! See Figure 2 (right) for right-sided flux (at i+1/2) - ! Here we need the left-sided flux, so we flip the weights with respect to the x=i point - ! But we need to keep the stencil order to reuse the beta coefficients - poly(0) = ( 2._wp*v(-1) + 5._wp*v( 0) - 1._wp*v( 1)) / 6._wp !& - poly(1) = (11._wp*v( 0) - 7._wp*v( 1) + 2._wp*v( 2)) / 6._wp !& - poly(2) = (-1._wp*v(-2) + 5._wp*v(-1) + 2._wp*v( 0)) / 6._wp !& - poly(3) = (25._wp*v( 0) - 23._wp*v( 1) + 13._wp*v( 2) - 3._wp*v( 3)) / 12._wp !& - poly(4) = ( 1._wp*v(-3) - 5._wp*v(-2) + 13._wp*v(-1) + 3._wp*v( 0)) / 12._wp !& + ! (Fu, et al., 2016) Table 1 Note: Unlike TENO5, TENO7 stencils differ from WENO7 + ! stencils See Figure 2 (right) for right-sided flux (at i+1/2) Here we need the + ! left-sided flux, so we flip the weights with respect to the x=i point But we need + ! to keep the stencil order to reuse the beta coefficients + poly(0) = (2._wp*v(-1) + 5._wp*v(0) - 1._wp*v(1))/6._wp + poly(1) = (11._wp*v(0) - 7._wp*v(1) + 2._wp*v(2))/6._wp + poly(2) = (-1._wp*v(-2) + 5._wp*v(-1) + 2._wp*v(0))/6._wp + poly(3) = (25._wp*v(0) - 23._wp*v(1) + 13._wp*v(2) - 3._wp*v(3))/12._wp + poly(4) = (1._wp*v(-3) - 5._wp*v(-2) + 13._wp*v(-1) + 3._wp*v(0))/12._wp #:endif end if if (.not. teno) then - - beta(3) = beta_coef_${XYZ}$ (j, 0, 0)*dvd(2)*dvd(2) & - + beta_coef_${XYZ}$ (j, 0, 1)*dvd(2)*dvd(1) & - + beta_coef_${XYZ}$ (j, 0, 2)*dvd(2)*dvd(0) & - + beta_coef_${XYZ}$ (j, 0, 3)*dvd(1)*dvd(1) & - + beta_coef_${XYZ}$ (j, 0, 4)*dvd(1)*dvd(0) & - + beta_coef_${XYZ}$ (j, 0, 5)*dvd(0)*dvd(0) & - + weno_eps - - beta(2) = beta_coef_${XYZ}$ (j, 1, 0)*dvd(1)*dvd(1) & - + beta_coef_${XYZ}$ (j, 1, 1)*dvd(1)*dvd(0) & - + beta_coef_${XYZ}$ (j, 1, 2)*dvd(1)*dvd(-1) & - + beta_coef_${XYZ}$ (j, 1, 3)*dvd(0)*dvd(0) & - + beta_coef_${XYZ}$ (j, 1, 4)*dvd(0)*dvd(-1) & - + beta_coef_${XYZ}$ (j, 1, 5)*dvd(-1)*dvd(-1) & - + weno_eps - - beta(1) = beta_coef_${XYZ}$ (j, 2, 0)*dvd(0)*dvd(0) & - + beta_coef_${XYZ}$ (j, 2, 1)*dvd(0)*dvd(-1) & - + beta_coef_${XYZ}$ (j, 2, 2)*dvd(0)*dvd(-2) & - + beta_coef_${XYZ}$ (j, 2, 3)*dvd(-1)*dvd(-1) & - + beta_coef_${XYZ}$ (j, 2, 4)*dvd(-1)*dvd(-2) & - + beta_coef_${XYZ}$ (j, 2, 5)*dvd(-2)*dvd(-2) & - + weno_eps - - beta(0) = beta_coef_${XYZ}$ (j, 3, 0)*dvd(-1)*dvd(-1) & - + beta_coef_${XYZ}$ (j, 3, 1)*dvd(-1)*dvd(-2) & - + beta_coef_${XYZ}$ (j, 3, 2)*dvd(-1)*dvd(-3) & - + beta_coef_${XYZ}$ (j, 3, 3)*dvd(-2)*dvd(-2) & - + beta_coef_${XYZ}$ (j, 3, 4)*dvd(-2)*dvd(-3) & - + beta_coef_${XYZ}$ (j, 3, 5)*dvd(-3)*dvd(-3) & - + weno_eps - - else ! TENO + beta(3) = beta_coef_${XYZ}$ (j, 0, 0)*dvd(2)*dvd(2) + beta_coef_${XYZ}$ (j, 0, & + & 1)*dvd(2)*dvd(1) + beta_coef_${XYZ}$ (j, 0, & + & 2)*dvd(2)*dvd(0) + beta_coef_${XYZ}$ (j, 0, & + & 3)*dvd(1)*dvd(1) + beta_coef_${XYZ}$ (j, 0, & + & 4)*dvd(1)*dvd(0) + beta_coef_${XYZ}$ (j, 0, 5)*dvd(0)*dvd(0) + weno_eps + + beta(2) = beta_coef_${XYZ}$ (j, 1, 0)*dvd(1)*dvd(1) + beta_coef_${XYZ}$ (j, 1, & + & 1)*dvd(1)*dvd(0) + beta_coef_${XYZ}$ (j, 1, & + & 2)*dvd(1)*dvd(-1) + beta_coef_${XYZ}$ (j, 1, & + & 3)*dvd(0)*dvd(0) + beta_coef_${XYZ}$ (j, 1, & + & 4)*dvd(0)*dvd(-1) + beta_coef_${XYZ}$ (j, 1, 5)*dvd(-1)*dvd(-1) + weno_eps + + beta(1) = beta_coef_${XYZ}$ (j, 2, 0)*dvd(0)*dvd(0) + beta_coef_${XYZ}$ (j, 2, & + & 1)*dvd(0)*dvd(-1) + beta_coef_${XYZ}$ (j, 2, & + & 2)*dvd(0)*dvd(-2) + beta_coef_${XYZ}$ (j, 2, & + & 3)*dvd(-1)*dvd(-1) + beta_coef_${XYZ}$ (j, 2, & + & 4)*dvd(-1)*dvd(-2) + beta_coef_${XYZ}$ (j, 2, 5)*dvd(-2)*dvd(-2) + weno_eps + + beta(0) = beta_coef_${XYZ}$ (j, 3, 0)*dvd(-1)*dvd(-1) + beta_coef_${XYZ}$ (j, 3, & + & 1)*dvd(-1)*dvd(-2) + beta_coef_${XYZ}$ (j, 3, & + & 2)*dvd(-1)*dvd(-3) + beta_coef_${XYZ}$ (j, 3, & + & 3)*dvd(-2)*dvd(-2) + beta_coef_${XYZ}$ (j, 3, & + & 4)*dvd(-2)*dvd(-3) + beta_coef_${XYZ}$ (j, 3, 5)*dvd(-3)*dvd(-3) + weno_eps + else ! TENO #:if not MFC_CASE_OPTIMIZATION or weno_num_stencils > 3 - ! High-Order Low-Dissipation Targeted ENO Schemes for Ideal Magnetohydrodynamics (Fu & Tang, 2019) Section 3.2 - beta(0) = 13._wp/12._wp*(v(-1) - 2._wp*v( 0) + v( 1))**2._wp + (( v(-1) - v( 1))**2._wp)/4._wp + weno_eps !& - beta(1) = 13._wp/12._wp*(v( 0) - 2._wp*v( 1) + v( 2))**2._wp + ((3._wp*v( 0) - 4._wp*v( 1) + v( 2))**2._wp)/4._wp + weno_eps !& - beta(2) = 13._wp/12._wp*(v(-2) - 2._wp*v(-1) + v( 0))**2._wp + (( v(-2) - 4._wp*v(-1) + 3._wp*v( 0))**2._wp)/4._wp + weno_eps !& - - beta(3) = ( v( 0)*(2107._wp*v( 0) - 9402._wp*v( 1) + 7042._wp*v( 2) - 1854._wp*v( 3)) & !& - + v( 1)*( 11003._wp*v( 1) - 17246._wp*v( 2) + 4642._wp*v( 3)) & !& - + v( 2)*( 7043._wp*v( 2) - 3882._wp*v( 3)) & !& - + v( 3)*( 547._wp*v( 3)) ) / 240._wp & !& - + weno_eps !& - - beta(4) = ( v(-3)*(547._wp*v(-3) - 3882._wp*v(-2) + 4642._wp*v(-1) - 1854._wp*v( 0)) & !& - + v(-2)*( 7043._wp*v(-2) - 17246._wp*v(-1) + 7042._wp*v( 0)) & !& - + v(-1)*( 11003._wp*v(-1) - 9402._wp*v( 0)) & !& - + v( 0)*( 2107._wp*v( 0)) ) / 240._wp & !& - + weno_eps !& + ! High-Order Low-Dissipation Targeted ENO Schemes for Ideal Magnetohydrodynamics (Fu + ! & Tang, 2019) Section 3.2 + beta(0) = 13._wp/12._wp*(v(-1) - 2._wp*v(0) + v(1))**2._wp + ((v(-1) - v(1)) & + & **2._wp)/4._wp + weno_eps + beta(1) = 13._wp/12._wp*(v(0) - 2._wp*v(1) + v(2))**2._wp + ((3._wp*v(0) & + & - 4._wp*v(1) + v(2))**2._wp)/4._wp + weno_eps + beta(2) = 13._wp/12._wp*(v(-2) - 2._wp*v(-1) + v(0))**2._wp + ((v(-2) & + & - 4._wp*v(-1) + 3._wp*v(0))**2._wp)/4._wp + weno_eps + + beta(3) = (v(0)*(2107._wp*v(0) - 9402._wp*v(1) + 7042._wp*v(2) - 1854._wp*v(3)) & + & + v(1)*(11003._wp*v(1) - 17246._wp*v(2) + 4642._wp*v(3)) + v(2) & + & *(7043._wp*v(2) - 3882._wp*v(3)) + v(3)*(547._wp*v(3)))/240._wp + weno_eps + + beta(4) = (v(-3)*(547._wp*v(-3) - 3882._wp*v(-2) + 4642._wp*v(-1) - 1854._wp*v(0)) & + & + v(-2)*(7043._wp*v(-2) - 17246._wp*v(-1) + 7042._wp*v(0)) + v(-1) & + & *(11003._wp*v(-1) - 9402._wp*v(0)) + v(0)*(2107._wp*v(0)))/240._wp + weno_eps #:endif end if if (wenojs) then - alpha(0:weno_num_stencils) = d_cbL_${XYZ}$ (0:weno_num_stencils, j)/(beta(0:weno_num_stencils)**2._wp) - - elseif (mapped_weno) then - alpha(0:weno_num_stencils) = d_cbL_${XYZ}$ (0:weno_num_stencils, j)/(beta(0:weno_num_stencils)**2._wp) + alpha(0:weno_num_stencils) = d_cbL_${XYZ}$ (0:weno_num_stencils, & + & j)/(beta(0:weno_num_stencils)**2._wp) + else if (mapped_weno) then + alpha(0:weno_num_stencils) = d_cbL_${XYZ}$ (0:weno_num_stencils, & + & j)/(beta(0:weno_num_stencils)**2._wp) omega = alpha/sum(alpha) - alpha(0:weno_num_stencils) = (d_cbL_${XYZ}$ (0:weno_num_stencils, j)*(1._wp + d_cbL_${XYZ}$ (0:weno_num_stencils, j) - 3._wp*omega(0:weno_num_stencils)) + omega(0:weno_num_stencils)**2._wp) & - *(omega(0:weno_num_stencils)/(d_cbL_${XYZ}$ (0:weno_num_stencils, j)**2._wp + omega(0:weno_num_stencils)*(1._wp - 2._wp*d_cbL_${XYZ}$ (0:weno_num_stencils, j)))) - - elseif (wenoz) then - ! Castro, et al. (2010) - ! Don & Borges (2013) also helps - tau = abs(beta(3) - beta(0)) ! Equation 50 + alpha(0:weno_num_stencils) = (d_cbL_${XYZ}$ (0:weno_num_stencils, & + & j)*(1._wp + d_cbL_${XYZ}$ (0:weno_num_stencils, & + & j) - 3._wp*omega(0:weno_num_stencils)) + omega(0:weno_num_stencils)**2._wp) & + & *(omega(0:weno_num_stencils)/(d_cbL_${XYZ}$ (0:weno_num_stencils, & + & j)**2._wp + omega(0:weno_num_stencils)*(1._wp & + & - 2._wp*d_cbL_${XYZ}$ (0:weno_num_stencils,j)))) + else if (wenoz) then + ! Castro, et al. (2010) Don & Borges (2013) also helps + tau = abs(beta(3) - beta(0)) ! Equation 50 $:GPU_LOOP(parallelism='[seq]') do q = 0, weno_num_stencils - alpha(q) = d_cbL_${XYZ}$ (q, j)*(1._wp + (tau/beta(q))**wenoz_q) ! wenoz_q = 2,3,4 for stability + alpha(q) = d_cbL_${XYZ}$ (q, & + & j)*(1._wp + (tau/beta(q))**wenoz_q) ! wenoz_q = 2,3,4 for stability end do - - elseif (teno) then + else if (teno) then #:if not MFC_CASE_OPTIMIZATION or weno_num_stencils > 3 - tau = abs(beta(4) - beta(3)) ! Note the reordering of stencils + tau = abs(beta(4) - beta(3)) ! Note the reordering of stencils alpha = 1._wp + tau/beta - alpha = (alpha**3._wp)**2._wp ! some CPU compilers cannot optimize x**6.0 + alpha = (alpha**3._wp)**2._wp ! some CPU compilers cannot optimize x**6.0 omega = alpha/sum(alpha) $:GPU_LOOP(parallelism='[seq]') do q = 0, weno_num_stencils - if (omega(q) < teno_CT) then ! Equation 26 + if (omega(q) < teno_CT) then ! Equation 26 delta(q) = 0._wp else delta(q) = 1._wp end if - alpha(q) = delta(q)*d_cbL_${XYZ}$ (q, j) ! Equation 27 + alpha(q) = delta(q)*d_cbL_${XYZ}$ (q, j) ! Equation 27 end do #:endif end if omega = alpha/sum(alpha) - vL_rs_vf_${XYZ}$ (j, k, l, i) = omega(0)*poly(0) + omega(1)*poly(1) + omega(2)*poly(2) + omega(3)*poly(3) + vL_rs_vf_${XYZ}$ (j, k, l, & + & i) = omega(0)*poly(0) + omega(1)*poly(1) + omega(2)*poly(2) + omega(3) & + & *poly(3) if (teno) then #:if not MFC_CASE_OPTIMIZATION or weno_num_stencils > 3 @@ -1107,49 +1303,48 @@ contains end if if (.not. teno) then - poly(3) = v_rs_ws_${XYZ}$ (j, k, l, i) & - + poly_coef_cbR_${XYZ}$ (j, 0, 0)*dvd(2) & - + poly_coef_cbR_${XYZ}$ (j, 0, 1)*dvd(1) & - + poly_coef_cbR_${XYZ}$ (j, 0, 2)*dvd(0) - poly(2) = v_rs_ws_${XYZ}$ (j, k, l, i) & - + poly_coef_cbR_${XYZ}$ (j, 1, 0)*dvd(1) & - + poly_coef_cbR_${XYZ}$ (j, 1, 1)*dvd(0) & - + poly_coef_cbR_${XYZ}$ (j, 1, 2)*dvd(-1) - poly(1) = v_rs_ws_${XYZ}$ (j, k, l, i) & - + poly_coef_cbR_${XYZ}$ (j, 2, 0)*dvd(0) & - + poly_coef_cbR_${XYZ}$ (j, 2, 1)*dvd(-1) & - + poly_coef_cbR_${XYZ}$ (j, 2, 2)*dvd(-2) - poly(0) = v_rs_ws_${XYZ}$ (j, k, l, i) & - + poly_coef_cbR_${XYZ}$ (j, 3, 0)*dvd(-1) & - + poly_coef_cbR_${XYZ}$ (j, 3, 1)*dvd(-2) & - + poly_coef_cbR_${XYZ}$ (j, 3, 2)*dvd(-3) + poly(3) = v_rs_ws_${XYZ}$ (j, k, l, i) + poly_coef_cbR_${XYZ}$ (j, 0, & + & 0)*dvd(2) + poly_coef_cbR_${XYZ}$ (j, 0, 1)*dvd(1) + poly_coef_cbR_${XYZ}$ (j, & + & 0, 2)*dvd(0) + poly(2) = v_rs_ws_${XYZ}$ (j, k, l, i) + poly_coef_cbR_${XYZ}$ (j, 1, & + & 0)*dvd(1) + poly_coef_cbR_${XYZ}$ (j, 1, 1)*dvd(0) + poly_coef_cbR_${XYZ}$ (j, & + & 1, 2)*dvd(-1) + poly(1) = v_rs_ws_${XYZ}$ (j, k, l, i) + poly_coef_cbR_${XYZ}$ (j, 2, & + & 0)*dvd(0) + poly_coef_cbR_${XYZ}$ (j, 2, & + & 1)*dvd(-1) + poly_coef_cbR_${XYZ}$ (j, 2, 2)*dvd(-2) + poly(0) = v_rs_ws_${XYZ}$ (j, k, l, i) + poly_coef_cbR_${XYZ}$ (j, 3, & + & 0)*dvd(-1) + poly_coef_cbR_${XYZ}$ (j, 3, & + & 1)*dvd(-2) + poly_coef_cbR_${XYZ}$ (j, 3, 2)*dvd(-3) else #:if not MFC_CASE_OPTIMIZATION or weno_num_stencils > 3 - poly(0) = (-1._wp*v(-1) + 5._wp*v( 0) + 2._wp*v( 1)) / 6._wp !& - poly(1) = ( 2._wp*v( 0) + 5._wp*v( 1) - 1._wp*v( 2)) / 6._wp !& - poly(2) = ( 2._wp*v(-2) - 7._wp*v(-1) + 11._wp*v( 0)) / 6._wp !& - poly(3) = ( 3._wp*v( 0) + 13._wp*v( 1) - 5._wp*v( 2) + 1._wp*v( 3)) / 12._wp !& - poly(4) = (-3._wp*v(-3) + 13._wp*v(-2) - 23._wp*v(-1) + 25._wp*v( 0)) / 12._wp !& + poly(0) = (-1._wp*v(-1) + 5._wp*v(0) + 2._wp*v(1))/6._wp + poly(1) = (2._wp*v(0) + 5._wp*v(1) - 1._wp*v(2))/6._wp + poly(2) = (2._wp*v(-2) - 7._wp*v(-1) + 11._wp*v(0))/6._wp + poly(3) = (3._wp*v(0) + 13._wp*v(1) - 5._wp*v(2) + 1._wp*v(3))/12._wp + poly(4) = (-3._wp*v(-3) + 13._wp*v(-2) - 23._wp*v(-1) + 25._wp*v(0))/12._wp #:endif end if if (wenojs) then - alpha(0:weno_num_stencils) = d_cbR_${XYZ}$ (0:weno_num_stencils, j)/(beta(0:weno_num_stencils)**2._wp) - - elseif (mapped_weno) then - alpha(0:weno_num_stencils) = d_cbR_${XYZ}$ (0:weno_num_stencils, j)/(beta(0:weno_num_stencils)**2._wp) + alpha(0:weno_num_stencils) = d_cbR_${XYZ}$ (0:weno_num_stencils, & + & j)/(beta(0:weno_num_stencils)**2._wp) + else if (mapped_weno) then + alpha(0:weno_num_stencils) = d_cbR_${XYZ}$ (0:weno_num_stencils, & + & j)/(beta(0:weno_num_stencils)**2._wp) omega = alpha/sum(alpha) - alpha(0:weno_num_stencils) = (d_cbR_${XYZ}$ (0:weno_num_stencils, j)*(1._wp + d_cbR_${XYZ}$ (0:weno_num_stencils, j) - 3._wp*omega(0:weno_num_stencils)) + omega(0:weno_num_stencils)**2._wp) & - *(omega(0:weno_num_stencils)/(d_cbR_${XYZ}$ (0:weno_num_stencils, j)**2._wp + omega(0:weno_num_stencils)*(1._wp - 2._wp*d_cbR_${XYZ}$ (0:weno_num_stencils, j)))) - - elseif (wenoz) then - + alpha(0:weno_num_stencils) = (d_cbR_${XYZ}$ (0:weno_num_stencils, & + & j)*(1._wp + d_cbR_${XYZ}$ (0:weno_num_stencils, & + & j) - 3._wp*omega(0:weno_num_stencils)) + omega(0:weno_num_stencils)**2._wp) & + & *(omega(0:weno_num_stencils)/(d_cbR_${XYZ}$ (0:weno_num_stencils, & + & j)**2._wp + omega(0:weno_num_stencils)*(1._wp & + & - 2._wp*d_cbR_${XYZ}$ (0:weno_num_stencils,j)))) + else if (wenoz) then $:GPU_LOOP(parallelism='[seq]') do q = 0, weno_num_stencils - alpha(q) = d_cbR_${XYZ}$ (q, j)*(1._wp + (tau/beta(q))**wenoz_q) ! wenoz_q = 2,3,4 for stability + alpha(q) = d_cbR_${XYZ}$ (q, & + & j)*(1._wp + (tau/beta(q))**wenoz_q) ! wenoz_q = 2,3,4 for stability end do - - elseif (teno) then + else if (teno) then $:GPU_LOOP(parallelism='[seq]') do q = 0, weno_num_stencils alpha(q) = delta(q)*d_cbR_${XYZ}$ (q, j) @@ -1158,14 +1353,15 @@ contains omega = alpha/sum(alpha) - vR_rs_vf_${XYZ}$ (j, k, l, i) = omega(0)*poly(0) + omega(1)*poly(1) + omega(2)*poly(2) + omega(3)*poly(3) + vR_rs_vf_${XYZ}$ (j, k, l, & + & i) = omega(0)*poly(0) + omega(1)*poly(1) + omega(2)*poly(2) + omega(3) & + & *poly(3) if (teno) then #:if not MFC_CASE_OPTIMIZATION or weno_num_stencils > 3 vR_rs_vf_${XYZ}$ (j, k, l, i) = vR_rs_vf_${XYZ}$ (j, k, l, i) + omega(4)*poly(4) #:endif end if - end do end do end do @@ -1177,33 +1373,26 @@ contains end if if (int_comp .and. v_size >= advxe) then - call s_interface_compression(vL_rs_vf_x, vL_rs_vf_y, vL_rs_vf_z, & - vR_rs_vf_x, vR_rs_vf_y, vR_rs_vf_z, & - weno_dir, is1_weno_d, is2_weno_d, is3_weno_d) + call s_interface_compression(vL_rs_vf_x, vL_rs_vf_y, vL_rs_vf_z, vR_rs_vf_x, vR_rs_vf_y, vR_rs_vf_z, weno_dir, & + & is1_weno_d, is2_weno_d, is3_weno_d) end if end subroutine s_weno - !> The computation of parameters, the allocation of memory, - !! the association of pointers and/or the execution of any - !! other procedures that are required for the setup of the - !! WENO reconstruction. - !! @param v_vf Cell-averaged variables - !! @param weno_dir Coordinate direction of the WENO reconstruction - subroutine s_initialize_weno(v_vf, & - weno_dir) - - type(scalar_field), dimension(:), intent(IN) :: v_vf + !> The computation of parameters, the allocation of memory, the association of pointers and/or the execution of any other + !! procedures that are required for the setup of the WENO reconstruction. + !! @param v_vf Cell-averaged variables + !! @param weno_dir Coordinate direction of the WENO reconstruction + subroutine s_initialize_weno(v_vf, weno_dir) - integer, intent(IN) :: weno_dir + type(scalar_field), dimension(:), intent(in) :: v_vf + integer, intent(in) :: weno_dir + integer :: j, k, l, q - integer :: j, k, l, q + ! Determining the number of cell-average variables which will be WENO-reconstructed and mapping their indical bounds in the + ! x-, y- and z-directions to those in the s1-, s2- and s3-directions as to reshape the inputted data in the coordinate + ! direction of the WENO reconstruction - ! Determining the number of cell-average variables which will be - ! WENO-reconstructed and mapping their indical bounds in the x-, - ! y- and z-directions to those in the s1-, s2- and s3-directions - ! as to reshape the inputted data in the coordinate direction of - ! the WENO reconstruction v_size = ubound(v_vf, 1) $:GPU_UPDATE(device='[v_size]') @@ -1257,47 +1446,34 @@ contains end subroutine s_initialize_weno - !> The goal of this subroutine is to ensure that the WENO - !! reconstruction is monotonic. The latter is achieved by - !! enforcing monotonicity preserving bounds of Suresh and - !! Huynh (1997). The resulting MPWENO reconstruction, see - !! Balsara and Shu (2000), ensures that the reconstructed - !! values do not reside outside the range spanned by WENO - !! stencil. - !! @param v_rs_ws Reshaped cell-averaged variables - !! @param vL_rs_vf Left WENO reconstructed cell-boundary values - !! @param vR_rs_vf Right WENO reconstructed cell-boundary values + !> The goal of this subroutine is to ensure that the WENO reconstruction is monotonic. The latter is achieved by enforcing + !! monotonicity preserving bounds of Suresh and Huynh (1997). The resulting MPWENO reconstruction, see Balsara and Shu (2000), + !! ensures that the reconstructed values do not reside outside the range spanned by WENO stencil. + !! @param v_rs_ws Reshaped cell-averaged variables + !! @param vL_rs_vf Left WENO reconstructed cell-boundary values + !! @param vR_rs_vf Right WENO reconstructed cell-boundary values subroutine s_preserve_monotonicity(v_rs_ws, vL_rs_vf, vR_rs_vf) - real(wp), dimension(idwbuff(1)%beg:, idwbuff(2)%beg:, idwbuff(3)%beg:, 1:), intent(IN) :: v_rs_ws - real(wp), dimension(idwbuff(1)%beg:, idwbuff(2)%beg:, idwbuff(3)%beg:, 1:), intent(INOUT) :: vL_rs_vf, vR_rs_vf - + real(wp), dimension(idwbuff(1)%beg:,idwbuff(2)%beg:,idwbuff(3)%beg:,1:), intent(in) :: v_rs_ws + real(wp), dimension(idwbuff(1)%beg:,idwbuff(2)%beg:,idwbuff(3)%beg:,1:), intent(inout) :: vL_rs_vf, vR_rs_vf integer :: i, j, k, l - - real(wp), dimension(-1:1) :: d !< Curvature measures at the zone centers - - real(wp) :: d_MD, d_LC !< - !! Median (md) curvature and large curvature (LC) measures - - ! The left and right upper bounds (UL), medians, large curvatures, - ! minima, and maxima of the WENO-reconstructed values of the cell- - ! average variables. - real(wp) :: vL_UL, vR_UL - real(wp) :: vL_MD, vR_MD - real(wp) :: vL_LC, vR_LC - real(wp) :: vL_min, vR_min - real(wp) :: vL_max, vR_max - + real(wp), dimension(-1:1) :: d !< Curvature measures at the zone centers + real(wp) :: d_MD, d_LC !< Median (md) curvature and large curvature (LC) measures + + ! The left and right upper bounds (UL), medians, large curvatures, minima, and maxima of the WENO-reconstructed values of + ! the cell- average variables. + real(wp) :: vL_UL, vR_UL + real(wp) :: vL_MD, vR_MD + real(wp) :: vL_LC, vR_LC + real(wp) :: vL_min, vR_min + real(wp) :: vL_max, vR_max real(wp), parameter :: alpha = 2._wp !> - !! Determines the maximum Courant–Friedrichs–Lewy (CFL) number that - !! may be utilized with the scheme. In theory, for stability, a CFL - !! number less than 1/(1+alpha) is necessary. The default value for - !! alpha is 2. - - real(wp), parameter :: beta = 4._wp/3._wp !< - !! Determines the amount of freedom available from utilizing a large - !! value for the local curvature. The default value for beta is 4/3. + !! Determines the maximum Courant-Friedrichs-Lewy (CFL) number that may be utilized with the scheme. In theory, for + !! stability, a CFL number less than 1/(1+alpha) is necessary. The default value for alpha is 2. + !> Determines the amount of freedom available from utilizing a large value for the local curvature. The default value for + !! beta is 4/3. + real(wp), parameter :: beta = 4._wp/3._wp real(wp), parameter :: alpha_mp = 2._wp real(wp), parameter :: beta_mp = 4._wp/3._wp @@ -1306,121 +1482,63 @@ contains do k = is2_weno%beg, is2_weno%end do j = is1_weno%beg, is1_weno%end do i = 1, v_size - d(-1) = v_rs_ws(j, k, l, i) & - + v_rs_ws(j - 2, k, l, i) & - - v_rs_ws(j - 1, k, l, i) & - *2._wp - d(0) = v_rs_ws(j + 1, k, l, i) & - + v_rs_ws(j - 1, k, l, i) & - - v_rs_ws(j, k, l, i) & - *2._wp - d(1) = v_rs_ws(j + 2, k, l, i) & - + v_rs_ws(j, k, l, i) & - - v_rs_ws(j + 1, k, l, i) & - *2._wp - - d_MD = (sign(1._wp, 4._wp*d(-1) - d(0)) + sign(1._wp, 4._wp*d(0) - d(-1))) & - *abs((sign(1._wp, 4._wp*d(-1) - d(0)) + sign(1._wp, d(-1))) & - *(sign(1._wp, 4._wp*d(-1) - d(0)) + sign(1._wp, d(0)))) & - *min(abs(4._wp*d(-1) - d(0)), abs(d(-1)), & - abs(4._wp*d(0) - d(-1)), abs(d(0)))/8._wp - - d_LC = (sign(1._wp, 4._wp*d(0) - d(1)) + sign(1._wp, 4._wp*d(1) - d(0))) & - *abs((sign(1._wp, 4._wp*d(0) - d(1)) + sign(1._wp, d(0))) & - *(sign(1._wp, 4._wp*d(0) - d(1)) + sign(1._wp, d(1)))) & - *min(abs(4._wp*d(0) - d(1)), abs(d(0)), & - abs(4._wp*d(1) - d(0)), abs(d(1)))/8._wp - - vL_UL = v_rs_ws(j, k, l, i) & - - (v_rs_ws(j + 1, k, l, i) & - - v_rs_ws(j, k, l, i))*alpha_mp - - vL_MD = (v_rs_ws(j, k, l, i) & - + v_rs_ws(j - 1, k, l, i) & - - d_MD)*5.e-1_wp - - vL_LC = v_rs_ws(j, k, l, i) & - - (v_rs_ws(j + 1, k, l, i) & - - v_rs_ws(j, k, l, i))*5.e-1_wp + beta_mp*d_LC - - vL_min = max(min(v_rs_ws(j, k, l, i), & - v_rs_ws(j - 1, k, l, i), & - vL_MD), & - min(v_rs_ws(j, k, l, i), & - vL_UL, & - vL_LC)) - - vL_max = min(max(v_rs_ws(j, k, l, i), & - v_rs_ws(j - 1, k, l, i), & - vL_MD), & - max(v_rs_ws(j, k, l, i), & - vL_UL, & - vL_LC)) - - vL_rs_vf(j, k, l, i) = vL_rs_vf(j, k, l, i) & - + (sign(5.e-1_wp, vL_min - vL_rs_vf(j, k, l, i)) & - + sign(5.e-1_wp, vL_max - vL_rs_vf(j, k, l, i))) & - *min(abs(vL_min - vL_rs_vf(j, k, l, i)), & - abs(vL_max - vL_rs_vf(j, k, l, i))) + d(-1) = v_rs_ws(j, k, l, i) + v_rs_ws(j - 2, k, l, i) - v_rs_ws(j - 1, k, l, i)*2._wp + d(0) = v_rs_ws(j + 1, k, l, i) + v_rs_ws(j - 1, k, l, i) - v_rs_ws(j, k, l, i)*2._wp + d(1) = v_rs_ws(j + 2, k, l, i) + v_rs_ws(j, k, l, i) - v_rs_ws(j + 1, k, l, i)*2._wp + + d_MD = (sign(1._wp, 4._wp*d(-1) - d(0)) + sign(1._wp, 4._wp*d(0) - d(-1)))*abs((sign(1._wp, & + & 4._wp*d(-1) - d(0)) + sign(1._wp, d(-1)))*(sign(1._wp, 4._wp*d(-1) - d(0)) + sign(1._wp, & + & d(0))))*min(abs(4._wp*d(-1) - d(0)), abs(d(-1)), abs(4._wp*d(0) - d(-1)), abs(d(0)))/8._wp + + d_LC = (sign(1._wp, 4._wp*d(0) - d(1)) + sign(1._wp, 4._wp*d(1) - d(0)))*abs((sign(1._wp, & + & 4._wp*d(0) - d(1)) + sign(1._wp, d(0)))*(sign(1._wp, 4._wp*d(0) - d(1)) + sign(1._wp, & + & d(1))))*min(abs(4._wp*d(0) - d(1)), abs(d(0)), abs(4._wp*d(1) - d(0)), abs(d(1)))/8._wp + + vL_UL = v_rs_ws(j, k, l, i) - (v_rs_ws(j + 1, k, l, i) - v_rs_ws(j, k, l, i))*alpha_mp + + vL_MD = (v_rs_ws(j, k, l, i) + v_rs_ws(j - 1, k, l, i) - d_MD)*5.e-1_wp + + vL_LC = v_rs_ws(j, k, l, i) - (v_rs_ws(j + 1, k, l, i) - v_rs_ws(j, k, l, i))*5.e-1_wp + beta_mp*d_LC + + vL_min = max(min(v_rs_ws(j, k, l, i), v_rs_ws(j - 1, k, l, i), vL_MD), min(v_rs_ws(j, k, l, i), vL_UL, & + & vL_LC)) + + vL_max = min(max(v_rs_ws(j, k, l, i), v_rs_ws(j - 1, k, l, i), vL_MD), max(v_rs_ws(j, k, l, i), vL_UL, & + & vL_LC)) + + vL_rs_vf(j, k, l, i) = vL_rs_vf(j, k, l, i) + (sign(5.e-1_wp, vL_min - vL_rs_vf(j, k, l, & + & i)) + sign(5.e-1_wp, vL_max - vL_rs_vf(j, k, l, i)))*min(abs(vL_min - vL_rs_vf(j, k, l, i)), & + & abs(vL_max - vL_rs_vf(j, k, l, i))) ! END: Left Monotonicity Preserving Bound ! Right Monotonicity Preserving Bound - d(-1) = v_rs_ws(j, k, l, i) & - + v_rs_ws(j - 2, k, l, i) & - - v_rs_ws(j - 1, k, l, i) & - *2._wp - d(0) = v_rs_ws(j + 1, k, l, i) & - + v_rs_ws(j - 1, k, l, i) & - - v_rs_ws(j, k, l, i) & - *2._wp - d(1) = v_rs_ws(j + 2, k, l, i) & - + v_rs_ws(j, k, l, i) & - - v_rs_ws(j + 1, k, l, i) & - *2._wp - - d_MD = (sign(1._wp, 4._wp*d(0) - d(1)) + sign(1._wp, 4._wp*d(1) - d(0))) & - *abs((sign(1._wp, 4._wp*d(0) - d(1)) + sign(1._wp, d(0))) & - *(sign(1._wp, 4._wp*d(0) - d(1)) + sign(1._wp, d(1)))) & - *min(abs(4._wp*d(0) - d(1)), abs(d(0)), & - abs(4._wp*d(1) - d(0)), abs(d(1)))/8._wp - - d_LC = (sign(1._wp, 4._wp*d(-1) - d(0)) + sign(1._wp, 4._wp*d(0) - d(-1))) & - *abs((sign(1._wp, 4._wp*d(-1) - d(0)) + sign(1._wp, d(-1))) & - *(sign(1._wp, 4._wp*d(-1) - d(0)) + sign(1._wp, d(0)))) & - *min(abs(4._wp*d(-1) - d(0)), abs(d(-1)), & - abs(4._wp*d(0) - d(-1)), abs(d(0)))/8._wp - - vR_UL = v_rs_ws(j, k, l, i) & - + (v_rs_ws(j, k, l, i) & - - v_rs_ws(j - 1, k, l, i))*alpha_mp - - vR_MD = (v_rs_ws(j, k, l, i) & - + v_rs_ws(j + 1, k, l, i) & - - d_MD)*5.e-1_wp - - vR_LC = v_rs_ws(j, k, l, i) & - + (v_rs_ws(j, k, l, i) & - - v_rs_ws(j - 1, k, l, i))*5.e-1_wp + beta_mp*d_LC - - vR_min = max(min(v_rs_ws(j, k, l, i), & - v_rs_ws(j + 1, k, l, i), & - vR_MD), & - min(v_rs_ws(j, k, l, i), & - vR_UL, & - vR_LC)) - - vR_max = min(max(v_rs_ws(j, k, l, i), & - v_rs_ws(j + 1, k, l, i), & - vR_MD), & - max(v_rs_ws(j, k, l, i), & - vR_UL, & - vR_LC)) - - vR_rs_vf(j, k, l, i) = vR_rs_vf(j, k, l, i) & - + (sign(5.e-1_wp, vR_min - vR_rs_vf(j, k, l, i)) & - + sign(5.e-1_wp, vR_max - vR_rs_vf(j, k, l, i))) & - *min(abs(vR_min - vR_rs_vf(j, k, l, i)), & - abs(vR_max - vR_rs_vf(j, k, l, i))) + d(-1) = v_rs_ws(j, k, l, i) + v_rs_ws(j - 2, k, l, i) - v_rs_ws(j - 1, k, l, i)*2._wp + d(0) = v_rs_ws(j + 1, k, l, i) + v_rs_ws(j - 1, k, l, i) - v_rs_ws(j, k, l, i)*2._wp + d(1) = v_rs_ws(j + 2, k, l, i) + v_rs_ws(j, k, l, i) - v_rs_ws(j + 1, k, l, i)*2._wp + + d_MD = (sign(1._wp, 4._wp*d(0) - d(1)) + sign(1._wp, 4._wp*d(1) - d(0)))*abs((sign(1._wp, & + & 4._wp*d(0) - d(1)) + sign(1._wp, d(0)))*(sign(1._wp, 4._wp*d(0) - d(1)) + sign(1._wp, & + & d(1))))*min(abs(4._wp*d(0) - d(1)), abs(d(0)), abs(4._wp*d(1) - d(0)), abs(d(1)))/8._wp + + d_LC = (sign(1._wp, 4._wp*d(-1) - d(0)) + sign(1._wp, 4._wp*d(0) - d(-1)))*abs((sign(1._wp, & + & 4._wp*d(-1) - d(0)) + sign(1._wp, d(-1)))*(sign(1._wp, 4._wp*d(-1) - d(0)) + sign(1._wp, & + & d(0))))*min(abs(4._wp*d(-1) - d(0)), abs(d(-1)), abs(4._wp*d(0) - d(-1)), abs(d(0)))/8._wp + + vR_UL = v_rs_ws(j, k, l, i) + (v_rs_ws(j, k, l, i) - v_rs_ws(j - 1, k, l, i))*alpha_mp + + vR_MD = (v_rs_ws(j, k, l, i) + v_rs_ws(j + 1, k, l, i) - d_MD)*5.e-1_wp + + vR_LC = v_rs_ws(j, k, l, i) + (v_rs_ws(j, k, l, i) - v_rs_ws(j - 1, k, l, i))*5.e-1_wp + beta_mp*d_LC + + vR_min = max(min(v_rs_ws(j, k, l, i), v_rs_ws(j + 1, k, l, i), vR_MD), min(v_rs_ws(j, k, l, i), vR_UL, & + & vR_LC)) + + vR_max = min(max(v_rs_ws(j, k, l, i), v_rs_ws(j + 1, k, l, i), vR_MD), max(v_rs_ws(j, k, l, i), vR_UL, & + & vR_LC)) + + vR_rs_vf(j, k, l, i) = vR_rs_vf(j, k, l, i) + (sign(5.e-1_wp, vR_min - vR_rs_vf(j, k, l, & + & i)) + sign(5.e-1_wp, vR_max - vR_rs_vf(j, k, l, i)))*min(abs(vR_min - vR_rs_vf(j, k, l, i)), & + & abs(vR_max - vR_rs_vf(j, k, l, i))) ! END: Right Monotonicity Preserving Bound end do end do @@ -1430,14 +1548,14 @@ contains end subroutine s_preserve_monotonicity - !> Module deallocation and/or disassociation procedures + !> Module deallocation and/or disassociation procedures impure subroutine s_finalize_weno_module() if (weno_order == 1) return ! Deallocating the WENO-stencil of the WENO-reconstructed variables - !deallocate(vL_rs_vf_x, vR_rs_vf_x) + ! deallocate(vL_rs_vf_x, vR_rs_vf_x) @:DEALLOCATE(v_rs_ws_x) ! Deallocating WENO coefficients in x-direction @@ -1448,7 +1566,7 @@ contains ! Deallocating WENO coefficients in y-direction if (n == 0) return - !deallocate(vL_rs_vf_y, vR_rs_vf_y) + ! deallocate(vL_rs_vf_y, vR_rs_vf_y) @:DEALLOCATE(v_rs_ws_y) @:DEALLOCATE(poly_coef_cbL_y, poly_coef_cbR_y) @@ -1458,7 +1576,7 @@ contains ! Deallocating WENO coefficients in z-direction if (p == 0) return - !deallocate(vL_rs_vf_z, vR_rs_vf_z) + ! deallocate(vL_rs_vf_z, vR_rs_vf_z) @:DEALLOCATE(v_rs_ws_z) @:DEALLOCATE(poly_coef_cbL_z, poly_coef_cbR_z) diff --git a/src/simulation/p_main.fpp b/src/simulation/p_main.fpp index e65722e191..be332ebf0e 100644 --- a/src/simulation/p_main.fpp +++ b/src/simulation/p_main.fpp @@ -2,47 +2,40 @@ !! @file !! @brief Contains program p_main -!> @brief Quasi-conservative, shock- and interface- capturing finite-volume -!! scheme for the multicomponent Navier-Stokes equations. The system -!! is augmented with the relevant advection equations to capture the -!! material interfaces and closed by the stiffened equation of state -!! as well as any required mixture relations. The effects of surface -!! tension are included and modeled through a volume force that acts -!! across the diffuse material interface regions. The implementation -!! specifics of surface tension may be found in the work by Perigaud -!! and Saurel (2005). Note that both viscous and capillarity effects -!! are only available in the volume fraction model. +!> @brief Quasi-conservative, shock- and interface- capturing finite-volume scheme for the multicomponent Navier-Stokes equations. +!! The system is augmented with the relevant advection equations to capture the material interfaces and closed by the stiffened +!! equation of state as well as any required mixture relations. The effects of surface tension are included and modeled through a +!! volume force that acts across the diffuse material interface regions. The implementation specifics of surface tension may be +!! found in the work by Perigaud and Saurel (2005). Note that both viscous and capillarity effects are only available in the volume +!! fraction model. program p_main - use m_global_parameters !< Definitions of the global parameters - + use m_global_parameters !< Definitions of the global parameters use m_start_up - use m_time_steppers - use m_nvtx implicit none - integer :: t_step !< Iterator for the time-stepping loop - real(wp) :: time_avg, time_final - real(wp) :: io_time_avg, io_time_final + integer :: t_step !< Iterator for the time-stepping loop + real(wp) :: time_avg, time_final + real(wp) :: io_time_avg, io_time_final real(wp), allocatable, dimension(:) :: proc_time real(wp), allocatable, dimension(:) :: io_proc_time - logical :: file_exists - real(wp) :: start, finish - integer :: nt + logical :: file_exists + real(wp) :: start, finish + integer :: nt call system_clock(COUNT=cpu_start, COUNT_RATE=cpu_rate) call nvtxStartRange("INIT") - !Initialize MPI + ! Initialize MPI call nvtxStartRange("INIT-MPI") call s_initialize_mpi_domain() call nvtxEndRange - !Initialize Modules + ! Initialize Modules call nvtxStartRange("INIT-MODULES") call s_initialize_modules() call nvtxEndRange @@ -68,22 +61,21 @@ program p_main finaltime = t_step_stop*dt end if - call nvtxEndRange ! INIT + call nvtxEndRange ! INIT call nvtxStartRange("SIMULATION-TIME-MARCH") ! Time-stepping Loop do - if (cfl_dt) then if (mytime >= t_stop) then - call s_save_performance_metrics(time_avg, time_final, io_time_avg, & - io_time_final, proc_time, io_proc_time, file_exists) + call s_save_performance_metrics(time_avg, time_final, io_time_avg, io_time_final, proc_time, io_proc_time, & + & file_exists) exit end if else if (t_step == t_step_stop) then - call s_save_performance_metrics(time_avg, time_final, io_time_avg, & - io_time_final, proc_time, io_proc_time, file_exists) + call s_save_performance_metrics(time_avg, time_final, io_time_avg, io_time_final, proc_time, io_proc_time, & + & file_exists) exit end if end if @@ -103,12 +95,11 @@ program p_main call system_clock(cpu_end) end do - call nvtxEndRange ! Simulation + call nvtxEndRange ! Simulation deallocate (proc_time, io_proc_time) call nvtxStartRange("FINALIZE-MODULES") call s_finalize_modules() call nvtxEndRange - end program p_main diff --git a/src/syscheck/syscheck.fpp b/src/syscheck/syscheck.fpp index 75e18efc33..c3ecad2e02 100644 --- a/src/syscheck/syscheck.fpp +++ b/src/syscheck/syscheck.fpp @@ -102,7 +102,6 @@ program syscheck @:LOG("") @:LOG("Syscheck: PASSED.") - end program syscheck subroutine assert(condition) diff --git a/toolchain/bootstrap/format.sh b/toolchain/bootstrap/format.sh index ce500ab301..962fe5d7a9 100644 --- a/toolchain/bootstrap/format.sh +++ b/toolchain/bootstrap/format.sh @@ -51,59 +51,10 @@ else PYTHON_DIRS="toolchain/ examples/ benchmarks/" fi -# Format Fortran files (.f90, .fpp) -FORTRAN_FILES=$(find $FORTRAN_DIRS -type f 2>/dev/null | grep -Ev 'autogen' | grep -E '\.(f90|fpp)$' || true) -if [[ -n "$FORTRAN_FILES" ]]; then - FPRETTIFY_OPTS="--silent --indent 4 --c-relations --enable-replacements --enable-decl --whitespace-comma 1 --whitespace-multdiv 0 --whitespace-plusminus 1 --case 1 1 1 1 --strict-indent --line-length 1000" - - # Skip files unchanged since last format (hash cache in build/.cache/format/) - CACHE_DIR="build/.cache/format" - mkdir -p "$CACHE_DIR" - DIRTY_FILES="" - for f in $FORTRAN_FILES; do - cache_key=$(echo "$f" | tr '/' '_') - current_hash=$(md5sum "$f" | cut -d' ' -f1) - cached_hash=$(cat "$CACHE_DIR/$cache_key" 2>/dev/null || true) - if [[ "$current_hash" != "$cached_hash" ]]; then - DIRTY_FILES+="$f"$'\n' - fi - done - DIRTY_FILES=$(echo "$DIRTY_FILES" | sed '/^$/d') - - if [[ -n "$DIRTY_FILES" ]]; then - for niter in 1 2 3 4; do - old_hash=$(echo "$DIRTY_FILES" | xargs cat | md5sum) - - # Run indenter on dirty files in one process - if ! echo "$DIRTY_FILES" | xargs python3 toolchain/indenter.py; then - error "Formatting Fortran files failed: indenter.py." - exit 1 - fi - - # Run fprettify in parallel (one process per file) - if ! echo "$DIRTY_FILES" | xargs -P ${JOBS:-1} -L 1 fprettify $FPRETTIFY_OPTS; then - error "Formatting Fortran files failed: fprettify." - exit 1 - fi - - new_hash=$(echo "$DIRTY_FILES" | xargs cat | md5sum) - if [[ "$old_hash" == "$new_hash" ]]; then - break - fi - if [[ "$niter" -eq 4 ]]; then - error "Formatting Fortran files failed: no steady-state after $niter iterations." - exit 1 - fi - done - - # Update hash cache for formatted files - for f in $DIRTY_FILES; do - cache_key=$(echo "$f" | tr '/' '_') - md5sum "$f" | cut -d' ' -f1 > "$CACHE_DIR/$cache_key" - done - - echo "$DIRTY_FILES" | while read -r f; do echo "> $f"; done - fi +# Format Fortran files with ffmt (single-pass, idempotent) +if ! ffmt -j ${JOBS:-1} $FORTRAN_DIRS 2>/dev/null; then + error "Formatting Fortran files failed: ffmt." + exit 1 fi # Apply safe auto-fixes (import sorting, etc.) before formatting. diff --git a/toolchain/indenter.py b/toolchain/indenter.py deleted file mode 100644 index ab0203ae4e..0000000000 --- a/toolchain/indenter.py +++ /dev/null @@ -1,83 +0,0 @@ -#!/usr/bin/env python3 - -import argparse -import os - - -def main(): - parser = argparse.ArgumentParser(prog="indenter.py", description="Adjust indentation of OpenACC directives in Fortran files") - parser.add_argument("filepaths", metavar="input_file", type=str, nargs="+", help="Files to format") - args = parser.parse_args() - - for filepath in args.filepaths: - temp_filepath = f"{filepath}.new" - adjust_indentation(filepath, temp_filepath) - os.replace(temp_filepath, filepath) - - -BLOCK_STARTERS = ("if", "do", "#:if", "#:else", "#ifdef", "#else") -BLOCK_ENDERS = ("end", "contains", "else", "#:end", "#:else", "#else", "#endif") -LOOP_DIRECTIVES = ("!$acc loop", "!$acc parallel loop") -INDENTERS = ("!DIR", "!$acc") - - -def adjust_indentation(input_file, output_file): - max_empty_lines = 4 - indent_len = 4 - - with open(input_file, "r") as file_in, open(output_file, "w") as file_out: - lines = file_in.readlines() - - # this makes sure !$acc lines that have line continuations get indented at proper level - for _ in range(10): - # loop through file - for i in range(len(lines)): - if lines[i].lstrip().startswith(INDENTERS) and i + 1 < len(lines): - j = i + 1 - empty_lines = 0 - # look down to see how to indent a line - while j < len(lines) and empty_lines < max_empty_lines: - # if the following line starts with [end, else, contains], skip to looking up - if lines[j].lstrip().startswith(BLOCK_ENDERS): - empty_lines = max_empty_lines - # skip empty lines - elif lines[j].strip() == "": - empty_lines += 1 - # indent acc lines - elif not lines[j].lstrip().startswith(INDENTERS): - indent = len(lines[j]) - len(lines[j].lstrip()) - lines[i] = " " * indent + lines[i].lstrip() - break - j += 1 - # if looking down just finds empty lines, start looking up for indentation level - if empty_lines == max_empty_lines: - k = i - 1 - while k >= 0: - # if line above is not empty - if lines[k].strip() != "": - # if line 2 above ends with line continuation, indent at that level - if lines[k - 1].strip().endswith("&"): - indent = len(lines[k - 1]) - len(lines[k - 1].lstrip()) - # if line above starts a loop or branch, indent - elif lines[k].lstrip().startswith(BLOCK_STARTERS): - indent = indent_len + (len(lines[k]) - len(lines[k].lstrip())) - # else indent at level of line above - else: - indent = len(lines[k]) - len(lines[k].lstrip()) - lines[i] = " " * indent + lines[i].lstrip() - break - k -= 1 - - # remove empty lines following an acc loop directive - i = 0 - while i < len(lines): - if lines[i].lstrip().startswith(LOOP_DIRECTIVES) and i + 1 < len(lines) and lines[i + 1].strip() == "": - file_out.write(lines[i]) - i += 2 - else: - file_out.write(lines[i]) - i += 1 - - -if __name__ == "__main__": - main() diff --git a/toolchain/mfc/test/coverage.py b/toolchain/mfc/test/coverage.py index eca6f3fae5..429129afc3 100644 --- a/toolchain/mfc/test/coverage.py +++ b/toolchain/mfc/test/coverage.py @@ -44,6 +44,8 @@ # are conservatively included (not in cache -> always runs). # - definitions.py: adding a parameter doesn't affect tests that don't use it; # the PR's .fpp changes trigger the relevant tests via coverage overlap. +# - case_validator.py: validation only affects user-facing error messages for +# invalid configs, not test outputs (tests use valid configs). ALWAYS_RUN_ALL = frozenset( [ "CMakeLists.txt", @@ -56,7 +58,6 @@ "toolchain/mfc/test/case.py", "toolchain/mfc/test/coverage.py", "toolchain/mfc/run/input.py", - "toolchain/mfc/case_validator.py", ] ) diff --git a/toolchain/mfc/test/test_coverage_unit.py b/toolchain/mfc/test/test_coverage_unit.py index 9b9302f84b..6327a31e17 100644 --- a/toolchain/mfc/test/test_coverage_unit.py +++ b/toolchain/mfc/test/test_coverage_unit.py @@ -237,8 +237,9 @@ def test_definitions_py_does_not_trigger_all(self): def test_input_py_triggers_all(self): assert should_run_all_tests({"toolchain/mfc/run/input.py"}) is True - def test_case_validator_triggers_all(self): - assert should_run_all_tests({"toolchain/mfc/case_validator.py"}) is True + def test_case_validator_does_not_trigger_all(self): + """case_validator.py removed: validation only affects error messages, not test outputs.""" + assert should_run_all_tests({"toolchain/mfc/case_validator.py"}) is False def test_cmakelists_triggers_all(self): assert should_run_all_tests({"CMakeLists.txt"}) is True diff --git a/toolchain/pyproject.toml b/toolchain/pyproject.toml index 74611d3442..fe9b7b7fee 100644 --- a/toolchain/pyproject.toml +++ b/toolchain/pyproject.toml @@ -24,7 +24,7 @@ dependencies = [ # Code Health "typos", "ruff", - "fprettify", + "ffmt", "ansi2txt", # Profiling From cf431a309d01d5f0f56b881067571d7d6972c6bb Mon Sep 17 00:00:00 2001 From: Spencer Bryngelson Date: Fri, 27 Mar 2026 10:00:41 -0400 Subject: [PATCH 05/14] restore master inline comments safely (exclude PR-removed variables) --- .ffmt_cache/hashes | 136 ++++++++++---------- src/common/include/1dHardcodedIC.fpp | 8 +- src/common/include/2dHardcodedIC.fpp | 10 +- src/common/include/3dHardcodedIC.fpp | 14 +- src/common/include/ExtrusionHardcodedIC.fpp | 12 +- src/common/m_boundary_common.fpp | 102 +++++++-------- src/common/m_checker_common.fpp | 6 +- src/common/m_constants.fpp | 30 ++--- src/common/m_derived_types.fpp | 110 ++++++++-------- src/common/m_helper.fpp | 10 +- src/common/m_helper_basic.fpp | 2 +- src/common/m_model.fpp | 6 +- src/common/m_mpi_common.fpp | 38 +++--- src/common/m_nvtx.f90 | 10 +- src/common/m_phase_change.fpp | 32 ++--- src/common/m_precision_select.f90 | 6 +- src/common/m_variables_conversion.fpp | 56 ++++---- src/post_process/m_checker.fpp | 6 +- src/post_process/m_data_input.f90 | 22 ++-- src/post_process/m_data_output.fpp | 30 ++--- src/post_process/m_derived_variables.fpp | 57 ++++---- src/post_process/m_global_parameters.fpp | 26 ++-- src/post_process/m_mpi_proxy.fpp | 4 +- src/post_process/m_start_up.fpp | 26 ++-- src/post_process/p_main.fpp | 2 +- src/pre_process/m_assign_variables.fpp | 12 +- src/pre_process/m_check_ib_patches.fpp | 10 +- src/pre_process/m_check_patches.fpp | 10 +- src/pre_process/m_checker.fpp | 6 +- src/pre_process/m_data_output.fpp | 40 +++--- src/pre_process/m_global_parameters.fpp | 52 ++++---- src/pre_process/m_grid.f90 | 2 +- src/pre_process/m_icpp_patches.fpp | 12 +- src/pre_process/m_initial_condition.fpp | 14 +- src/pre_process/m_mpi_proxy.fpp | 6 +- src/pre_process/m_perturbation.fpp | 12 +- src/pre_process/m_start_up.fpp | 32 ++--- src/pre_process/p_main.f90 | 2 +- src/simulation/m_acoustic_src.fpp | 18 +-- src/simulation/m_body_forces.fpp | 4 +- src/simulation/m_bubbles.fpp | 10 +- src/simulation/m_bubbles_EE.fpp | 10 +- src/simulation/m_bubbles_EL.fpp | 26 ++-- src/simulation/m_bubbles_EL_kernels.fpp | 2 +- src/simulation/m_cbc.fpp | 8 +- src/simulation/m_checker.fpp | 6 +- src/simulation/m_compute_levelset.fpp | 16 +-- src/simulation/m_data_output.fpp | 38 +++--- src/simulation/m_derived_variables.fpp | 8 +- src/simulation/m_fftw.fpp | 6 +- src/simulation/m_global_parameters.fpp | 30 ++--- src/simulation/m_hyperelastic.fpp | 6 +- src/simulation/m_hypoelastic.fpp | 6 +- src/simulation/m_ib_patches.fpp | 10 +- src/simulation/m_ibm.fpp | 10 +- src/simulation/m_igr.fpp | 2 +- src/simulation/m_mpi_proxy.fpp | 10 +- src/simulation/m_muscl.fpp | 6 +- src/simulation/m_pressure_relaxation.fpp | 4 +- src/simulation/m_qbmm.fpp | 10 +- src/simulation/m_rhs.fpp | 30 ++--- src/simulation/m_riemann_solvers.fpp | 60 ++++----- src/simulation/m_sim_helpers.fpp | 22 ++-- src/simulation/m_start_up.fpp | 42 +++--- src/simulation/m_surface_tension.fpp | 8 +- src/simulation/m_time_steppers.fpp | 16 +-- src/simulation/m_viscous.fpp | 10 +- src/simulation/m_weno.fpp | 33 ++--- src/simulation/p_main.fpp | 2 +- 69 files changed, 719 insertions(+), 721 deletions(-) diff --git a/.ffmt_cache/hashes b/.ffmt_cache/hashes index bca4027465..69bf2d477d 100644 --- a/.ffmt_cache/hashes +++ b/.ffmt_cache/hashes @@ -1,49 +1,54 @@ +10009860086781508725 src/simulation/m_sim_helpers.fpp 10103916424136661533 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.YNbWNpe5YF/b/src/common/m_delay_file_access.f90 10103916424136661533 src/common/m_delay_file_access.f90 10105209818380589033 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.UKcnsjaI4a/b/src/simulation/m_rhs.fpp 10105209818380589033 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.dhTNdaQgUC/b/src/simulation/m_rhs.fpp 10105209818380589033 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.erX3snVzaV/pr.fpp -10105209818380589033 src/simulation/m_rhs.fpp 10547681541613149381 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.QwIzwEBHeU/b/src/simulation/m_compute_cbc.fpp 10547681541613149381 src/simulation/m_compute_cbc.fpp +10547908418817167772 src/common/m_checker_common.fpp 10971775388782938368 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.wXyGiacHHu/b/src/pre_process/m_initial_condition.fpp -10971775388782938368 src/pre_process/m_initial_condition.fpp +11128781068164813518 src/simulation/m_surface_tension.fpp 1123613300469720145 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.NhWX9QvMiS/b/src/simulation/m_pressure_relaxation.fpp -1123613300469720145 src/simulation/m_pressure_relaxation.fpp 11247271584116519044 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.5zMHO1bIjC/b/src/common/m_helper.fpp 11247271584116519044 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.UKcnsjaI4a/b/src/common/m_helper.fpp -11247271584116519044 src/common/m_helper.fpp +11296479789568295899 src/post_process/p_main.fpp +11299621811843082331 src/pre_process/m_icpp_patches.fpp 11328367635707741672 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.fRp2cEQ9ib/b/src/pre_process/m_grid.f90 -11328367635707741672 src/pre_process/m_grid.f90 1152355942436141718 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.yvB87OqER1/b/src/post_process/m_derived_variables.fpp -1152355942436141718 src/post_process/m_derived_variables.fpp 1162163686405901254 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.IXCiOAmlT9/b/src/simulation/m_bubbles.fpp 1162163686405901254 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.OMiiuUbkm3/pr.fpp 1162163686405901254 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.UKcnsjaI4a/b/src/simulation/m_bubbles.fpp 1162163686405901254 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.iJz2nMUb3Q/b/src/simulation/m_bubbles.fpp -1162163686405901254 src/simulation/m_bubbles.fpp +11671852064421512331 src/simulation/m_bubbles.fpp 1177935745597610133 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.KsaCosfP7l/b/src/simulation/m_surface_tension.fpp -1177935745597610133 src/simulation/m_surface_tension.fpp 11799777124238319529 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.p6vSsTKmTQ/b/src/common/include/ExtrusionHardcodedIC.fpp -11799777124238319529 src/common/include/ExtrusionHardcodedIC.fpp 11844429005742744406 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.p40EgjuOZ4/b/src/common/include/macros.fpp 11844429005742744406 src/common/include/macros.fpp +11845929787624151121 src/simulation/m_igr.fpp +11858275667014895903 src/pre_process/m_perturbation.fpp 11886921327637192006 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.rNk4nDDuiA/b/src/pre_process/m_assign_variables.fpp -11886921327637192006 src/pre_process/m_assign_variables.fpp 11928143073477354808 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.ApVsay2rl0/b/src/common/m_chemistry.fpp 11928143073477354808 src/common/m_chemistry.fpp +12464738087200294908 src/pre_process/m_initial_condition.fpp 12545196112158418286 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.4QCea7ntGd/b/src/common/m_constants.fpp 12545196112158418286 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.UKcnsjaI4a/b/src/common/m_constants.fpp 12545196112158418286 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.pHQFxfnpka/pr.fpp -12545196112158418286 src/common/m_constants.fpp +12614301032225053702 src/simulation/m_qbmm.fpp +12776587850356873970 src/simulation/m_pressure_relaxation.fpp +1298984555937275901 src/pre_process/p_main.f90 1302629992983287045 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.jlX0OxaJWC/b/src/common/include/2dHardcodedIC.fpp -1302629992983287045 src/common/include/2dHardcodedIC.fpp +13038648724116207061 src/simulation/m_start_up.fpp +13116240964782596330 src/simulation/m_muscl.fpp +13160620054921289456 src/simulation/m_ibm.fpp +13371470821044798149 src/simulation/m_acoustic_src.fpp +13377292145430364954 src/simulation/m_mpi_proxy.fpp 13379422254557003055 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.tQPN4tJmBS/b/src/common/include/parallel_macros.fpp 13379422254557003055 src/common/include/parallel_macros.fpp +13404712065072015994 src/common/include/1dHardcodedIC.fpp +13585296417644820871 src/simulation/m_weno.fpp 13737474862947549962 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.wBcCWjwdfh/b/src/common/include/1dHardcodedIC.fpp -13737474862947549962 src/common/include/1dHardcodedIC.fpp 13778436859709422582 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.ZQxwzOCdYP/b/src/pre_process/p_main.f90 -13778436859709422582 src/pre_process/p_main.f90 13798070750203827352 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.9oWQDBRzDO/b/src/simulation/m_data_output.fpp 13798070750203827352 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.BPphaiI0iT/b/src/simulation/m_data_output.fpp 13798070750203827352 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.FyLr7CvpOg/b/src/simulation/m_data_output.fpp @@ -52,14 +57,14 @@ 13798070750203827352 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.l4geGiBejN/b/src/simulation/m_data_output.fpp 13798070750203827352 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.mAWaP5Yqf6/pr.fpp 13798070750203827352 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.nW8Pq43Vvf/b/src/simulation/m_data_output.fpp +13920301627764782241 src/common/m_nvtx.f90 14047356244834746872 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.xVza69symx/b/src/simulation/m_hyperelastic.fpp -14047356244834746872 src/simulation/m_hyperelastic.fpp 14218853748338101619 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.F8v3PuEaEB/b/src/common/m_checker_common.fpp -14218853748338101619 src/common/m_checker_common.fpp 14257682203105278348 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.CZPMCJMBJW/b/src/common/m_phase_change.fpp -14257682203105278348 src/common/m_phase_change.fpp +14264799885104244614 src/common/m_mpi_common.fpp +14438687236384090363 src/simulation/m_bubbles_EL_kernels.fpp 14450336682570067792 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.1BExP6R8f9/b/src/simulation/m_acoustic_src.fpp -14450336682570067792 src/simulation/m_acoustic_src.fpp +14551696709150228093 src/common/m_phase_change.fpp 14636237826800124746 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.1geSh90r6o/b/src/pre_process/m_global_parameters.fpp 14636237826800124746 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.1nYoCE2Z93/b/src/pre_process/m_global_parameters.fpp 14636237826800124746 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.CF4oy4IF0z/b/src/pre_process/m_global_parameters.fpp @@ -69,127 +74,123 @@ 14636237826800124746 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.UKcnsjaI4a/b/src/pre_process/m_global_parameters.fpp 14636237826800124746 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.ketcpZUBhe/b/src/pre_process/m_global_parameters.fpp 14636237826800124746 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.kfAB4MRB1T/b/src/pre_process/m_global_parameters.fpp -14636237826800124746 src/pre_process/m_global_parameters.fpp +14670547982328888582 src/post_process/m_derived_variables.fpp 14739644014569295158 src/common/include/SharedHardcoded.fpp 14954376616734417912 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.5wobk7aEG0/b/src/simulation/p_main.fpp -14954376616734417912 src/simulation/p_main.fpp 14999475271112169381 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.zed9MGw8lu/b/src/common/include/acc_macros.fpp 14999475271112169381 src/common/include/acc_macros.fpp 15049314966727887552 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.foNVQzeyQX/b/src/pre_process/m_simplex_noise.fpp 15049314966727887552 src/pre_process/m_simplex_noise.fpp 15110474130912937443 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.EOjTtcOp00/b/src/post_process/m_checker.fpp -15110474130912937443 src/post_process/m_checker.fpp +15317541443631750607 src/simulation/m_bubbles_EE.fpp 15343341342992294043 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.ZE1xLrrD4M/b/src/simulation/m_body_forces.fpp -15343341342992294043 src/simulation/m_body_forces.fpp 15508824445404703824 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.DJdV0uDXkk/pr.fpp 15508824445404703824 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.UKcnsjaI4a/b/src/common/m_helper_basic.fpp 15508824445404703824 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.dpV8UkalaA/b/src/common/m_helper_basic.fpp -15508824445404703824 src/common/m_helper_basic.fpp 15573111593524903869 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.7rXfBv7i7f/b/src/simulation/m_qbmm.fpp -15573111593524903869 src/simulation/m_qbmm.fpp +15615432817640526542 src/post_process/m_checker.fpp +15809629697745920208 src/simulation/m_body_forces.fpp 15811265556360623843 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.6h5PDEc3xX/b/src/simulation/include/inline_capillary.fpp 15811265556360623843 src/simulation/include/inline_capillary.fpp +15874659916346725348 src/pre_process/m_data_output.fpp 15941699165887750367 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.S0h68IhVLd/b/src/common/m_precision_select.f90 -15941699165887750367 src/common/m_precision_select.f90 -16362615099332163096 src/simulation/m_data_output.fpp +16277666294786574062 src/simulation/m_viscous.fpp +16325267463833969784 src/pre_process/m_start_up.fpp +16397783534027655847 src/simulation/m_checker.fpp 16590815127468205830 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.wqmnQUCDbi/b/src/common/include/omp_macros.fpp 16590815127468205830 src/common/include/omp_macros.fpp +16613830963758284333 src/common/include/2dHardcodedIC.fpp 16666864254209086704 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.4QVjyhlBbR/b/src/simulation/m_ib_patches.fpp 16666864254209086704 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.EKTuvrJmZf/pr.fpp 16666864254209086704 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.UKcnsjaI4a/b/src/simulation/m_ib_patches.fpp -16666864254209086704 src/simulation/m_ib_patches.fpp +16716924334175372818 src/simulation/m_global_parameters.fpp 16819660696315222173 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.wZ5g7DS74M/b/src/simulation/include/inline_riemann.fpp 16819660696315222173 src/simulation/include/inline_riemann.fpp 16863576169260976215 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.BtoC8sntqC/b/src/common/m_boundary_common.fpp 16863576169260976215 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.UKcnsjaI4a/b/src/common/m_boundary_common.fpp 16863576169260976215 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.WV8J0UVWWc/pr.fpp 16863576169260976215 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.tPbHdHuGzL/b/src/common/m_boundary_common.fpp -16863576169260976215 src/common/m_boundary_common.fpp 17150360143499547248 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.GwPH1PymWU/b/src/pre_process/m_mpi_proxy.fpp 17150360143499547248 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.UKcnsjaI4a/b/src/pre_process/m_mpi_proxy.fpp -17150360143499547248 src/pre_process/m_mpi_proxy.fpp 17374991166589206306 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.CKefDZblI8/b/src/simulation/m_muscl.fpp 17374991166589206306 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.UKcnsjaI4a/b/src/simulation/m_muscl.fpp 17374991166589206306 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.bThVXwVjHQ/pr.fpp -17374991166589206306 src/simulation/m_muscl.fpp +17383712883767117007 src/simulation/m_derived_variables.fpp 17475717397114845816 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.7vhQq2kOXS/b/src/pre_process/m_check_ib_patches.fpp -17475717397114845816 src/pre_process/m_check_ib_patches.fpp 17489851833420935241 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.UKcnsjaI4a/b/src/pre_process/m_start_up.fpp 17489851833420935241 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.jKReiOTmE3/pr.fpp 17489851833420935241 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.pN7wf0OOXk/b/src/pre_process/m_start_up.fpp -17489851833420935241 src/pre_process/m_start_up.fpp +17521335209975820849 src/post_process/m_mpi_proxy.fpp +17578011942315344381 src/common/m_helper.fpp 17729534019838315074 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.5q1Y270gxY/b/src/post_process/m_global_parameters.fpp 17729534019838315074 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.UKcnsjaI4a/b/src/post_process/m_global_parameters.fpp 17729534019838315074 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.VmGqKfWL4e/b/src/post_process/m_global_parameters.fpp 17729534019838315074 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.fEo4jGidK0/pr.fpp -17729534019838315074 src/post_process/m_global_parameters.fpp +17747955368322546147 src/simulation/m_time_steppers.fpp +17786640510670779223 src/common/m_derived_types.fpp 17939937579085231691 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.1FlGgFgoLk/b/src/simulation/m_riemann_solvers.fpp -17939937579085231691 src/simulation/m_riemann_solvers.fpp 17952081853197839750 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.FM3hyTJcC1/b/src/post_process/p_main.fpp -17952081853197839750 src/post_process/p_main.fpp 18080888037678917285 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.UOicaksnAM/b/src/common/m_variables_conversion.fpp -18080888037678917285 src/common/m_variables_conversion.fpp 18166547160227944552 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.04SRuU4uDG/b/src/simulation/m_sim_helpers.fpp 18166547160227944552 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.UH5isBDNLP/pr.fpp 18166547160227944552 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.UKcnsjaI4a/b/src/simulation/m_sim_helpers.fpp -18166547160227944552 src/simulation/m_sim_helpers.fpp +18226449463280282712 src/simulation/m_rhs.fpp 18308153827535525888 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.LcZmBtbXI5/b/src/simulation/m_time_steppers.fpp 18308153827535525888 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.TMdfrAiUad/b/src/simulation/m_time_steppers.fpp 18308153827535525888 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.UKcnsjaI4a/b/src/simulation/m_time_steppers.fpp 18308153827535525888 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.zBXQoIJ9Ns/pr.fpp -18308153827535525888 src/simulation/m_time_steppers.fpp 18424647052757242046 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.90F2SuKdN3/b/src/simulation/m_igr.fpp -18424647052757242046 src/simulation/m_igr.fpp +1921723504088853053 src/simulation/m_hypoelastic.fpp +2065425623481551924 src/common/m_boundary_common.fpp 2089934286629799065 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.UKcnsjaI4a/b/src/simulation/m_bubbles_EE.fpp 2089934286629799065 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.ehVOiqSEna/b/src/simulation/m_bubbles_EE.fpp 2089934286629799065 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.mGbGtZnmMH/pr.fpp -2089934286629799065 src/simulation/m_bubbles_EE.fpp +2092302292714238550 src/pre_process/m_checker.fpp 2179692337769865707 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.UKcnsjaI4a/b/src/common/m_derived_types.fpp 2179692337769865707 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.ahYsbo4OkN/b/src/common/m_derived_types.fpp 2179692337769865707 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.u43jNT6Y9N/pr.fpp 2179692337769865707 /tmp/pr_derived.fpp -2179692337769865707 src/common/m_derived_types.fpp 2180900767736986011 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.2wyV79dZFt/pr.fpp 2180900767736986011 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.9ywat4IE5E/b/src/simulation/m_ibm.fpp 2180900767736986011 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.UKcnsjaI4a/b/src/simulation/m_ibm.fpp -2180900767736986011 src/simulation/m_ibm.fpp 2238355401608193277 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.Xeee1w2Np4/b/src/post_process/m_start_up.fpp -2238355401608193277 src/post_process/m_start_up.fpp 2246088494097541240 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.6XVxKq1Gls/b/src/simulation/m_mpi_proxy.fpp 2246088494097541240 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.UKcnsjaI4a/b/src/simulation/m_mpi_proxy.fpp 2246088494097541240 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.bFnMb9Yj6X/pr.fpp -2246088494097541240 src/simulation/m_mpi_proxy.fpp 2275015924369440500 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.GyRQmToKip/b/src/simulation/m_bubbles_EL.fpp 2275015924369440500 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.QWfhmzAUhW/b/src/simulation/m_bubbles_EL.fpp 2275015924369440500 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.UKcnsjaI4a/b/src/simulation/m_bubbles_EL.fpp 2275015924369440500 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.sq9eLcwlqR/pr.fpp -2275015924369440500 src/simulation/m_bubbles_EL.fpp 2431245550782554100 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.IwOd4FjXKf/b/src/simulation/m_viscous.fpp -2431245550782554100 src/simulation/m_viscous.fpp 2525268250784412532 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.2moDi289m2/b/src/simulation/m_compute_levelset.fpp 2525268250784412532 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.UKcnsjaI4a/b/src/simulation/m_compute_levelset.fpp 2525268250784412532 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.fNlW6mq81s/pr.fpp -2525268250784412532 src/simulation/m_compute_levelset.fpp 2551148861500766043 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.61vHeCBp3z/b/src/common/m_nvtx.f90 -2551148861500766043 src/common/m_nvtx.f90 +3296338549351377009 src/post_process/m_data_input.f90 330369965658929155 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.l3vlWwFtc6/b/src/pre_process/m_checker.fpp -330369965658929155 src/pre_process/m_checker.fpp 3322818355154981622 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.zxtBRdLiDM/b/src/simulation/m_derived_variables.fpp -3322818355154981622 src/simulation/m_derived_variables.fpp +3474524733030028692 src/pre_process/m_grid.f90 +3586268134361254209 src/common/m_variables_conversion.fpp 3852216218768625740 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.ON0VZhypev/b/src/common/m_compile_specific.f90 3852216218768625740 src/common/m_compile_specific.f90 +419528971510258904 src/common/m_constants.fpp 4271870002582174631 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.h1I7f50x8l/b/src/post_process/m_mpi_proxy.fpp -4271870002582174631 src/post_process/m_mpi_proxy.fpp 4316649851528138914 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.vJ4faZHES0/b/src/post_process/m_data_input.f90 -4316649851528138914 src/post_process/m_data_input.f90 +4353656613440585819 src/post_process/m_data_output.fpp +4417977747387015039 src/simulation/m_bubbles_EL.fpp 47037120222980462 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.oFDAmDeZN7/b/src/simulation/m_fftw.fpp -47037120222980462 src/simulation/m_fftw.fpp +4769787692054280401 src/common/m_precision_select.f90 +4898418582330870284 src/simulation/m_data_output.fpp 4993379909229078812 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.RprlXGCudJ/b/src/simulation/m_checker.fpp -4993379909229078812 src/simulation/m_checker.fpp +5179107110711951524 src/common/m_model.fpp +5290618235356275088 src/pre_process/m_assign_variables.fpp +5434153436692493302 src/post_process/m_start_up.fpp +5684204796802451846 src/simulation/m_cbc.fpp +5725362251714205830 src/post_process/m_global_parameters.fpp +5783893076695788858 src/pre_process/m_check_ib_patches.fpp 5871828278470799827 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.hpU6ltVEIS/b/src/syscheck/syscheck.fpp 5871828278470799827 src/syscheck/syscheck.fpp 5928207121067860413 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.mpy7h1Q0k4/b/src/common/m_model.fpp -5928207121067860413 src/common/m_model.fpp 6137784461014282246 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.21jzdeIFZA/b/src/common/include/3dHardcodedIC.fpp 6137784461014282246 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.Ngtiv1vOCD/b/src/common/include/3dHardcodedIC.fpp 6137784461014282246 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.UKcnsjaI4a/b/src/common/include/3dHardcodedIC.fpp @@ -198,8 +199,9 @@ 6137784461014282246 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.ox5RwzwCDq/b/src/common/include/3dHardcodedIC.fpp 6137784461014282246 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.uHW6w2dKmd/b/src/common/include/3dHardcodedIC.fpp 6137784461014282246 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.unuGVybPf5/b/src/common/include/3dHardcodedIC.fpp -6137784461014282246 src/common/include/3dHardcodedIC.fpp 6240714802147004944 src/common/include/shared_parallel_macros.fpp +6276978915188096958 src/common/include/3dHardcodedIC.fpp +68593444489471372 src/simulation/m_compute_levelset.fpp 6938669613291679776 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.4o4LVAkqMP/b/src/common/m_finite_differences.fpp 6938669613291679776 src/common/m_finite_differences.fpp 732149268206108348 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.2J0Z5N2qcF/b/src/simulation/m_weno.fpp @@ -207,43 +209,41 @@ 732149268206108348 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.D9KOPlN1LD/pr.fpp 732149268206108348 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.UKcnsjaI4a/b/src/simulation/m_weno.fpp 732149268206108348 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.xwrbhmKSBn/b/src/simulation/m_weno.fpp -732149268206108348 src/simulation/m_weno.fpp +7463753986237902141 src/common/m_helper_basic.fpp 7530723425281110009 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.A857NqLisR/b/src/simulation/m_cbc.fpp -7530723425281110009 src/simulation/m_cbc.fpp 7580365803335695134 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.WMlJs7jEPw/b/src/simulation/m_hypoelastic.fpp -7580365803335695134 src/simulation/m_hypoelastic.fpp 7723221865542041495 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.svITM8tMXS/b/src/pre_process/m_icpp_patches.fpp -7723221865542041495 src/pre_process/m_icpp_patches.fpp 7737322002952828776 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.UKcnsjaI4a/b/src/simulation/m_start_up.fpp 7737322002952828776 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.aYeUsTe6vQ/b/src/simulation/m_start_up.fpp 7737322002952828776 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.mGRII3r92Q/pr.fpp -7737322002952828776 src/simulation/m_start_up.fpp +8042763174988148227 src/simulation/m_riemann_solvers.fpp 8093344263636711422 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.CtULDFfiWw/pr.fpp 8093344263636711422 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.UKcnsjaI4a/b/src/simulation/m_bubbles_EL_kernels.fpp 8093344263636711422 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.u1zFhDbdg8/b/src/simulation/m_bubbles_EL_kernels.fpp -8093344263636711422 src/simulation/m_bubbles_EL_kernels.fpp 8258277022714838383 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.7MRd899dQW/b/src/simulation/m_global_parameters.fpp 8258277022714838383 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.Du4hJUphgy/b/src/simulation/m_global_parameters.fpp 8258277022714838383 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.M29f3SMb5C/pr.fpp 8258277022714838383 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.UKcnsjaI4a/b/src/simulation/m_global_parameters.fpp 8258277022714838383 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.cJ15SrprHl/b/src/simulation/m_global_parameters.fpp 8258277022714838383 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.yxQ0X6fv0o/b/src/simulation/m_global_parameters.fpp -8258277022714838383 src/simulation/m_global_parameters.fpp 8373688306336592140 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.tVW0Ag4HFB/b/src/pre_process/m_data_output.fpp -8373688306336592140 src/pre_process/m_data_output.fpp 8639686218598077333 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.fo85j8vdro/b/src/post_process/m_data_output.fpp -8639686218598077333 src/post_process/m_data_output.fpp +8755329155192764099 src/pre_process/m_global_parameters.fpp 8835068673407070922 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.qfglItrwDK/b/src/pre_process/m_boundary_conditions.fpp 8835068673407070922 src/pre_process/m_boundary_conditions.fpp +8849574993014605176 src/simulation/m_ib_patches.fpp 8870602128241043159 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.V53atDEagj/b/src/pre_process/m_check_patches.fpp -8870602128241043159 src/pre_process/m_check_patches.fpp +8978802987682839827 src/pre_process/m_mpi_proxy.fpp +919624630099600931 src/common/include/ExtrusionHardcodedIC.fpp 9370663205287462789 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.zoRoHcwA35/b/src/pre_process/m_perturbation.fpp -9370663205287462789 src/pre_process/m_perturbation.fpp +9419299607787709748 src/simulation/p_main.fpp 9606486790139625748 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.QCod6CiPeT/b/src/common/m_mpi_common.fpp 9606486790139625748 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.UKcnsjaI4a/b/src/common/m_mpi_common.fpp 9606486790139625748 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.Z9FK1bV094/b/src/common/m_mpi_common.fpp 9606486790139625748 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.dF9qaNUJjz/b/src/common/m_mpi_common.fpp 9606486790139625748 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.j1H2hZqcGd/pr.fpp 9606486790139625748 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.sBmtXp00OQ/b/src/common/m_mpi_common.fpp -9606486790139625748 src/common/m_mpi_common.fpp +9634210289819551950 src/pre_process/m_check_patches.fpp 9812035701611855679 /tmp/test_ffmt.fpp +9864053594660500546 src/simulation/m_fftw.fpp +9961309992593322894 src/simulation/m_hyperelastic.fpp diff --git a/src/common/include/1dHardcodedIC.fpp b/src/common/include/1dHardcodedIC.fpp index 80b7e9edcb..562005ac32 100644 --- a/src/common/include/1dHardcodedIC.fpp +++ b/src/common/include/1dHardcodedIC.fpp @@ -13,21 +13,21 @@ ! magnetic field q_prim_vf(B_idx%end - 1)%sf(i, 0, 0) = 0.1_wp*sin(2._wp*pi*x_cc(i)) q_prim_vf(B_idx%end)%sf(i, 0, 0) = 0.1_wp*cos(2._wp*pi*x_cc(i)) - case (170) + case (170) ! 1D profile from external data (e.g. Cantera, SDtoolbox) ! This hardcoded case can be used to start a simulation with initial conditions given from a known 1D profile (e.g. Cantera, ! SDtoolbox) @: HardcodedReadValues() - case (180) + case (180) ! Shu-Osher problem ! This is patch is hard-coded for test suite optimization used in the 1D_shuoser cases: "patch_icpp(2)%alpha_rho(1)": "1 + ! 0.2*sin(5*x)" if (patch_id == 2) then q_prim_vf(contxb + 0)%sf(i, 0, 0) = 1 + 0.2*sin(5*x_cc(i)) end if - case (181) + case (181) ! Titarev-Torro problem ! This is patch is hard-coded for test suite optimization used in the 1D_titarevtorro cases: "patch_icpp(2)%alpha_rho(1)": ! "1 + 0.1*sin(20*x*pi)" q_prim_vf(contxb + 0)%sf(i, 0, 0) = 1 + 0.1*sin(20*x_cc(i)*pi) - case (182) + case (182) ! Multi-component diffusion ! This patch is a hard-coded for test suite optimization (multiple component diffusion) x_mid_diffu = 0.05_wp/2.0_wp width_sq = (2.5_wp*10.0_wp**(-3.0_wp))**2 diff --git a/src/common/include/2dHardcodedIC.fpp b/src/common/include/2dHardcodedIC.fpp index a39e68b662..7f233320da 100644 --- a/src/common/include/2dHardcodedIC.fpp +++ b/src/common/include/2dHardcodedIC.fpp @@ -18,7 +18,7 @@ #:def Hardcoded2D() select case (patch_icpp(patch_id)%hcid) ! 2D_hardcoded_ic example case - case (200) + case (200) ! Two-fluid cubic interface if (y_cc(j) <= (-x_cc(i)**3 + 1)**(1._wp/3._wp)) then ! Volume Fractions q_prim_vf(advxb)%sf(i, j, 0) = eps @@ -265,10 +265,10 @@ q_prim_vf(B_idx%beg + 1)%sf(i, j, 0) = (5._wp/sqrt(4._wp*pi))*sinA + (5._wp/sqrt(4._wp*pi))*cosA end if ! v^z and B^z remain zero by default - case (270) + case (270) ! 2D extrusion of 1D profile from external data ! This hardcoded case extrudes a 1D profile to initialize a 2D simulation domain @: HardcodedReadValues() - case (280) + case (280) ! Isentropic vortex ! This is patch is hard-coded for test suite optimization used in the 2D_isentropicvortex case: This analytic patch uses ! geometry 2 if (patch_id == 1) then @@ -285,7 +285,7 @@ & 0) = 0.0 - (x_cc(i) - patch_icpp(1)%x_centroid)*(5.0/(2.0*pi))*exp(1.0*(1.0 - (x_cc(i) - patch_icpp(1) & & %x_centroid)**2.0 - (y_cc(j) - patch_icpp(1)%y_centroid)**2.0)) end if - case (281) + case (281) ! Acoustic pulse ! This is patch is hard-coded for test suite optimization used in the 2D_acoustic_pulse case: This analytic patch uses ! geometry 2 if (patch_id == 2) then @@ -294,7 +294,7 @@ q_prim_vf(contxb + 0)%sf(i, j, & & 0) = 1*(1 - 0.5*(1.4 - 1)*(0.4)**2*exp(0.5*(1 - sqrt(x_cc(i)**2 + y_cc(j)**2))))**(1/(1.4 - 1)) end if - case (282) + case (282) ! Zero-circulation vortex ! This is patch is hard-coded for test suite optimization used in the 2D_zero_circ_vortex case: This analytic patch uses ! geometry 2 if (patch_id == 2) then diff --git a/src/common/include/3dHardcodedIC.fpp b/src/common/include/3dHardcodedIC.fpp index cb3132ca17..28cfac3b39 100644 --- a/src/common/include/3dHardcodedIC.fpp +++ b/src/common/include/3dHardcodedIC.fpp @@ -7,13 +7,13 @@ real(wp), dimension(:), allocatable :: y_th_arr, z_th_arr, r_th_arr ! Variables to describe initial condition of jet real(wp) :: r, ux_th, ux_am, p_th, p_am, rho_th, rho_am, y_th, z_th, r_th, eps_smooth - real(wp) :: rcut, xcut ! Intermediate variables for creating smooth initial condition + real(wp) :: rcut, xcut !< Intermediate variables for creating smooth initial condition real(wp), dimension(0:n,0:p) :: rcut_arr - integer :: l, q, s ! Iterators for reading input files - integer :: start, end ! Ints to keep track of position in file + integer :: l, q, s !< Iterators for reading input files + integer :: start, end !< Ints to keep track of position in file character(len=100000) :: line ! String to store line in file - character(len=25) :: value ! String to store value in line - integer :: NJet ! Number of jets + character(len=25) :: value !< String to store value in line + integer :: NJet !< Number of jets real(wp), allocatable, dimension(:,:) :: ih ! Array to store interface height in logical :: file_exist ! Flag to check if file exists @@ -261,10 +261,10 @@ & k))*g0_ic*(ih(start_idx(1) + i, start_idx(3) + k) - y_cc(j)) if (surface_tension) q_prim_vf(c_idx)%sf(i, j, k) = alph - case (370) + case (370) ! 3D extrusion of 2D profile from external data ! This hardcoded case extrudes a 2D profile to initialize a 3D simulation domain @: HardcodedReadValues() - case (380) + case (380) ! Taylor-Green vortex ! This is patch is hard-coded for test suite optimization used in the 3D_TaylorGreenVortex case: This analytic patch used ! geometry 9 Mach = 0.1 diff --git a/src/common/include/ExtrusionHardcodedIC.fpp b/src/common/include/ExtrusionHardcodedIC.fpp index 0adb8beaa1..e67b44ae2d 100644 --- a/src/common/include/ExtrusionHardcodedIC.fpp +++ b/src/common/include/ExtrusionHardcodedIC.fpp @@ -40,18 +40,18 @@ integer :: f, iter, ios, ios2, unit, unit2, idx, idy, index_x, index_y, jump, line_count, ycount real(wp) :: x_len, x_step, y_len, y_step real(wp) :: dummy_x, dummy_y, dummy_z, x0, y0 - integer :: global_offset_x, global_offset_y ! MPI subdomain offset + integer :: global_offset_x, global_offset_y !< MPI subdomain offset real(wp) :: delta_x, delta_y - character(len=100), dimension(sys_size) :: fileNames ! Arrays to store all data from files + character(len=100), dimension(sys_size) :: fileNames !< Arrays to store all data from files character(len=200) :: errmsg real(wp), allocatable :: stored_values(:,:,:) real(wp), allocatable :: x_coords(:), y_coords(:) logical :: files_loaded = .false. real(wp) :: domain_xstart, domain_xend, domain_ystart, domain_yend - character(len=*), parameter :: init_dir = "/home/MFC/FilesDirectory" ! For example /home/MFC/examples/1D_Shock/D/ - character(len=20) :: file_num_str ! For storing the file number as a string - character(len=20) :: zeros_part ! For the trailing zeros part - character(len=6), parameter :: zeros_default = "000000" ! Default zeros (can be changed) + character(len=*), parameter :: init_dir = "/home/MFC/FilesDirectory" !< For example /home/MFC/examples/1D_Shock/D/ + character(len=20) :: file_num_str !< For storing the file number as a string + character(len=20) :: zeros_part !< For the trailing zeros part + character(len=6), parameter :: zeros_default = "000000" !< Default zeros (can be changed) #:enddef #:def HardcodedReadValues() diff --git a/src/common/m_boundary_common.fpp b/src/common/m_boundary_common.fpp index 5d8675d84f..e86aea1303 100644 --- a/src/common/m_boundary_common.fpp +++ b/src/common/m_boundary_common.fpp @@ -8,8 +8,8 @@ module m_boundary_common - use m_derived_types !< Definitions of the derived types - use m_global_parameters !< Definitions of the global parameters + use m_derived_types + use m_global_parameters use m_mpi_proxy use m_constants use m_delay_file_access @@ -261,7 +261,7 @@ contains if (bc_z%end >= 0) then call s_mpi_sendrecv_variables_buffers(q_prim_vf, 3, 1, sys_size, pb_in, mv_in) - else + else !< bc_x%end $:GPU_PARALLEL_LOOP(private='[l, k]', collapse=2) do l = -buff_size, n + buff_size do k = -buff_size, m + buff_size @@ -308,7 +308,7 @@ contains q_prim_vf(i)%sf(-j, k, l) = q_prim_vf(i)%sf(0, k, l) end do end do - else !< bc_x%end + else !< bc_y%end do i = 1, sys_size do j = 1, buff_size q_prim_vf(i)%sf(m + j, k, l) = q_prim_vf(i)%sf(m, k, l) @@ -322,7 +322,7 @@ contains q_prim_vf(i)%sf(k, -j, l) = q_prim_vf(i)%sf(k, 0, l) end do end do - else !< bc_y%end + else !< bc_z%end do i = 1, sys_size do j = 1, buff_size q_prim_vf(i)%sf(k, n + j, l) = q_prim_vf(i)%sf(k, n, l) @@ -336,7 +336,7 @@ contains q_prim_vf(i)%sf(k, l, -j) = q_prim_vf(i)%sf(k, l, 0) end do end do - else !< bc_z%end + else !< bc_x%end do i = 1, sys_size do j = 1, buff_size q_prim_vf(i)%sf(k, l, p + j) = q_prim_vf(i)%sf(k, l, p) @@ -393,7 +393,7 @@ contains end do end do end if - else !< bc_x%end + else !< bc_y%end do j = 1, buff_size do i = 1, contxe q_prim_vf(i)%sf(m + j, k, l) = q_prim_vf(i)%sf(m - (j - 1), k, l) @@ -462,7 +462,7 @@ contains end do end do end if - else !< bc_y%end + else !< bc_z%end do j = 1, buff_size do i = 1, momxb q_prim_vf(i)%sf(k, n + j, l) = q_prim_vf(i)%sf(k, n - (j - 1), l) @@ -532,7 +532,7 @@ contains end do end do end if - else !< bc_z%end + else !< bc_x%end do j = 1, buff_size do i = 1, momxb + 1 q_prim_vf(i)%sf(k, l, p + j) = q_prim_vf(i)%sf(k, l, p - (j - 1)) @@ -599,7 +599,7 @@ contains end do end do end if - else !< bc_x%end + else !< bc_y%end do i = 1, sys_size do j = 1, buff_size q_prim_vf(i)%sf(m + j, k, l) = q_prim_vf(i)%sf(j - 1, k, l) @@ -635,7 +635,7 @@ contains end do end do end if - else !< bc_y%end + else !< bc_z%end do i = 1, sys_size do j = 1, buff_size q_prim_vf(i)%sf(k, n + j, l) = q_prim_vf(i)%sf(k, j - 1, l) @@ -671,7 +671,7 @@ contains end do end do end if - else !< bc_z%end + else do i = 1, sys_size do j = 1, buff_size q_prim_vf(i)%sf(k, l, p + j) = q_prim_vf(i)%sf(k, l, j - 1) @@ -759,12 +759,12 @@ contains do j = 1, buff_size if (i == momxb) then q_prim_vf(i)%sf(-j, k, l) = -q_prim_vf(i)%sf(j - 1, k, l) + 2._wp*bc_x%vb1 - else + else !< bc_x%end q_prim_vf(i)%sf(-j, k, l) = q_prim_vf(i)%sf(0, k, l) end if end do end do - else !< bc_x%end + else do i = 1, sys_size do j = 1, buff_size if (i == momxb) then @@ -781,12 +781,12 @@ contains do j = 1, buff_size if (i == momxb + 1) then q_prim_vf(i)%sf(k, -j, l) = -q_prim_vf(i)%sf(k, j - 1, l) + 2._wp*bc_y%vb2 - else + else !< bc_y%end q_prim_vf(i)%sf(k, -j, l) = q_prim_vf(i)%sf(k, 0, l) end if end do end do - else !< bc_y%end + else do i = 1, sys_size do j = 1, buff_size if (i == momxb + 1) then @@ -803,12 +803,12 @@ contains do j = 1, buff_size if (i == momxe) then q_prim_vf(i)%sf(k, l, -j) = -q_prim_vf(i)%sf(k, l, j - 1) + 2._wp*bc_z%vb3 - else + else !< bc_z%end q_prim_vf(i)%sf(k, l, -j) = q_prim_vf(i)%sf(k, l, 0) end if end do end do - else !< bc_z%end + else do i = 1, sys_size do j = 1, buff_size if (i == momxe) then @@ -843,12 +843,12 @@ contains q_prim_vf(i)%sf(-j, k, l) = -q_prim_vf(i)%sf(j - 1, k, l) + 2._wp*bc_x%vb2 else if (i == momxb + 2 .and. num_dims > 2) then q_prim_vf(i)%sf(-j, k, l) = -q_prim_vf(i)%sf(j - 1, k, l) + 2._wp*bc_x%vb3 - else + else !< bc_x%end q_prim_vf(i)%sf(-j, k, l) = q_prim_vf(i)%sf(0, k, l) end if end do end do - else !< bc_x%end + else do i = 1, sys_size do j = 1, buff_size if (i == momxb) then @@ -873,12 +873,12 @@ contains q_prim_vf(i)%sf(k, -j, l) = -q_prim_vf(i)%sf(k, j - 1, l) + 2._wp*bc_y%vb2 else if (i == momxb + 2 .and. num_dims > 2) then q_prim_vf(i)%sf(k, -j, l) = -q_prim_vf(i)%sf(k, j - 1, l) + 2._wp*bc_y%vb3 - else + else !< bc_y%end q_prim_vf(i)%sf(k, -j, l) = q_prim_vf(i)%sf(k, 0, l) end if end do end do - else !< bc_y%end + else do i = 1, sys_size do j = 1, buff_size if (i == momxb) then @@ -903,12 +903,12 @@ contains q_prim_vf(i)%sf(k, l, -j) = -q_prim_vf(i)%sf(k, l, j - 1) + 2._wp*bc_z%vb2 else if (i == momxb + 2 .and. num_dims > 2) then q_prim_vf(i)%sf(k, l, -j) = -q_prim_vf(i)%sf(k, l, j - 1) + 2._wp*bc_z%vb3 - else + else !< bc_z%end q_prim_vf(i)%sf(k, l, -j) = q_prim_vf(i)%sf(k, l, 0) end if end do end do - else !< bc_z%end + else do i = 1, sys_size do j = 1, buff_size if (i == momxb) then @@ -917,7 +917,7 @@ contains q_prim_vf(i)%sf(k, l, p + j) = -q_prim_vf(i)%sf(k, l, p - (j - 1)) + 2._wp*bc_z%ve2 else if (i == momxb + 2 .and. num_dims > 2) then q_prim_vf(i)%sf(k, l, p + j) = -q_prim_vf(i)%sf(k, l, p - (j - 1)) + 2._wp*bc_z%ve3 - else + else !< bc_x%end q_prim_vf(i)%sf(k, l, p + j) = q_prim_vf(i)%sf(k, l, p) end if end do @@ -944,7 +944,7 @@ contains q_prim_vf(i)%sf(-j, k, l) = bc_buffers(1, 1)%sf(i, k, l) end do end do - else !< bc_x%end + else !< bc_y%end do i = 1, sys_size do j = 1, buff_size q_prim_vf(i)%sf(m + j, k, l) = bc_buffers(1, 2)%sf(i, k, l) @@ -959,7 +959,7 @@ contains q_prim_vf(i)%sf(k, -j, l) = bc_buffers(2, 1)%sf(k, i, l) end do end do - else !< bc_y%end + else !< bc_z%end do i = 1, sys_size do j = 1, buff_size q_prim_vf(i)%sf(k, n + j, l) = bc_buffers(2, 2)%sf(k, i, l) @@ -975,7 +975,7 @@ contains q_prim_vf(i)%sf(k, l, -j) = bc_buffers(3, 1)%sf(k, l, i) end do end do - else !< bc_z%end + else !< bc_x%end do i = 1, sys_size do j = 1, buff_size q_prim_vf(i)%sf(k, l, p + j) = bc_buffers(3, 2)%sf(k, l, i) @@ -1009,7 +1009,7 @@ contains end do end do end do - else !< bc_x%end + else !< bc_y%end do i = 1, nb do q = 1, nnode do j = 1, buff_size @@ -1029,7 +1029,7 @@ contains end do end do end do - else !< bc_y%end + else !< bc_z%end do i = 1, nb do q = 1, nnode do j = 1, buff_size @@ -1049,7 +1049,7 @@ contains end do end do end do - else !< bc_z%end + else do i = 1, nb do q = 1, nnode do j = 1, buff_size @@ -1219,7 +1219,7 @@ contains q_beta(beta_vars(i))%sf(j, k, l) = t_kahan end do end do - else !< bc_x%end + else do i = 1, nvar do j = -mapcells, mapcells + 1 q_beta(beta_vars(i))%sf(m + j, k, l) = q_beta(beta_vars(i))%sf(j - 1, k, l) @@ -1238,7 +1238,7 @@ contains q_beta(beta_vars(i))%sf(k, j, l) = t_kahan end do end do - else !< bc_y%end + else do i = 1, nvar do j = -mapcells, mapcells + 1 q_beta(beta_vars(i))%sf(k, n + j, l) = q_beta(beta_vars(i))%sf(k, j - 1, l) @@ -1257,7 +1257,7 @@ contains q_beta(beta_vars(i))%sf(k, l, j) = t_kahan end do end do - else !< bc_z%end + else do i = 1, nvar do j = -mapcells, mapcells + 1 q_beta(beta_vars(i))%sf(k, l, p + j) = q_beta(beta_vars(i))%sf(k, l, j - 1) @@ -1287,7 +1287,7 @@ contains q_beta(beta_vars(i))%sf(-j, k, l) = 0._wp end do end do - else !< bc_x%end + else do i = 1, nvar do j = 1, buff_size q_beta(beta_vars(i))%sf(m + j, k, l) = 0._wp @@ -1301,7 +1301,7 @@ contains q_beta(beta_vars(i))%sf(k, -j, l) = 0._wp end do end do - else !< bc_y%end + else do i = 1, nvar do j = 1, buff_size q_beta(beta_vars(i))%sf(k, n + j, l) = 0._wp @@ -1315,7 +1315,7 @@ contains q_beta(beta_vars(i))%sf(k, l, -j) = 0._wp end do end do - else !< bc_z%end + else !< bc_x%end do i = 1, nvar do j = 1, buff_size q_beta(beta_vars(i))%sf(k, l, p + j) = 0._wp @@ -1341,7 +1341,7 @@ contains ! ghost cells = mirror of (now-folded) interior values if (bc_dir == 1) then !< x-direction - if (bc_loc == -1) then !< bc_x%beg + if (bc_loc == -1) then ! bc_x%beg do i = 1, nvar do j = 1, mapCells + 1 y_kahan = real(q_beta(beta_vars(i))%sf(-j, k, l), kind=wp) + kahan_comp(beta_vars(i))%sf(-j, k, & @@ -1355,7 +1355,7 @@ contains kahan_comp(beta_vars(i))%sf(-j, k, l) = kahan_comp(beta_vars(i))%sf(j - 1, k, l) end do end do - else !< bc_x%end + else !< bc_y%end do i = 1, nvar do j = 1, mapCells + 1 y_kahan = real(q_beta(beta_vars(i))%sf(m + j, k, l), kind=wp) + kahan_comp(beta_vars(i))%sf(m + j, k, & @@ -1386,7 +1386,7 @@ contains kahan_comp(beta_vars(i))%sf(k, -j, l) = kahan_comp(beta_vars(i))%sf(k, j - 1, l) end do end do - else !< bc_y%end + else !< bc_z%end do i = 1, nvar do j = 1, mapCells + 1 y_kahan = real(q_beta(beta_vars(i))%sf(k, n + j, l), kind=wp) + kahan_comp(beta_vars(i))%sf(k, n + j, & @@ -1417,7 +1417,7 @@ contains kahan_comp(beta_vars(i))%sf(k, l, -j) = kahan_comp(beta_vars(i))%sf(k, l, j - 1) end do end do - else !< bc_z%end + else do i = 1, nvar do j = 1, mapCells + 1 y_kahan = real(q_beta(beta_vars(i))%sf(k, l, p + j), kind=wp) + kahan_comp(beta_vars(i))%sf(k, l, & @@ -1448,7 +1448,7 @@ contains if (bc_x%beg >= 0) then call s_mpi_sendrecv_variables_buffers(c_divs, 1, -1, num_dims + 1) - else + else !< bc_x%end $:GPU_PARALLEL_LOOP(private='[l, k]', collapse=2) do l = 0, p do k = 0, n @@ -1509,7 +1509,7 @@ contains if (bc_y%end >= 0) then call s_mpi_sendrecv_variables_buffers(c_divs, 2, 1, num_dims + 1) - else + else !< bc_y%end $:GPU_PARALLEL_LOOP(private='[l, k]', collapse=2) do l = 0, p do k = -buff_size, m + buff_size @@ -1588,7 +1588,7 @@ contains c_divs(i)%sf(-j, k, l) = c_divs(i)%sf(m - (j - 1), k, l) end do end do - else !< bc_x%end + else !< bc_z%end do i = 1, num_dims + 1 do j = 1, buff_size c_divs(i)%sf(m + j, k, l) = c_divs(i)%sf(j - 1, k, l) @@ -1602,7 +1602,7 @@ contains c_divs(i)%sf(k, -j, l) = c_divs(i)%sf(k, n - (j - 1), l) end do end do - else !< bc_y%end + else do i = 1, num_dims + 1 do j = 1, buff_size c_divs(i)%sf(k, n + j, l) = c_divs(i)%sf(k, j - 1, l) @@ -1616,7 +1616,7 @@ contains c_divs(i)%sf(k, l, -j) = c_divs(i)%sf(k, l, p - (j - 1)) end do end do - else !< bc_z%end + else !< bc_x%end do i = 1, num_dims + 1 do j = 1, buff_size c_divs(i)%sf(k, l, p + j) = c_divs(i)%sf(k, l, j - 1) @@ -1642,12 +1642,12 @@ contains do j = 1, buff_size if (i == bc_dir) then c_divs(i)%sf(-j, k, l) = -c_divs(i)%sf(j - 1, k, l) - else + else !< bc_y%end c_divs(i)%sf(-j, k, l) = c_divs(i)%sf(j - 1, k, l) end if end do end do - else !< bc_x%end + else !< bc_z%end do i = 1, num_dims + 1 do j = 1, buff_size if (i == bc_dir) then @@ -1669,7 +1669,7 @@ contains end if end do end do - else !< bc_y%end + else do i = 1, num_dims + 1 do j = 1, buff_size if (i == bc_dir) then @@ -1691,7 +1691,7 @@ contains end if end do end do - else !< bc_z%end + else do i = 1, num_dims + 1 do j = 1, buff_size if (i == bc_dir) then @@ -2250,7 +2250,7 @@ contains !! locations and cell-width distributions, based on the boundary conditions. subroutine s_populate_grid_variables_buffers - integer :: i !< Generic loop iterator + integer :: i #ifdef MFC_SIMULATION ! Required for compatibility between codes diff --git a/src/common/m_checker_common.fpp b/src/common/m_checker_common.fpp index e6c6b54632..eafd01803a 100644 --- a/src/common/m_checker_common.fpp +++ b/src/common/m_checker_common.fpp @@ -8,9 +8,9 @@ !> @brief Shared input validation checks for grid dimensions and AMD GPU compiler limits module m_checker_common - use m_global_parameters !< Definitions of the global parameters - use m_mpi_proxy !< Message passing interface (MPI) module proxy - use m_helper_basic !< Functions to compare floating point numbers + use m_global_parameters + use m_mpi_proxy + use m_helper_basic use m_helper implicit none diff --git a/src/common/m_constants.fpp b/src/common/m_constants.fpp index f7f9623f37..3e5cedefd2 100644 --- a/src/common/m_constants.fpp +++ b/src/common/m_constants.fpp @@ -23,11 +23,11 @@ module m_constants integer, parameter :: fourier_rings = 5 !< Fourier filter ring limit integer, parameter :: num_fluids_max = 10 !< Maximum number of fluids in the simulation integer, parameter :: num_probes_max = 10 !< Maximum number of flow probes in the simulation - integer, parameter :: num_patches_max = 1000 - integer, parameter :: num_bc_patches_max = 10 + integer, parameter :: num_patches_max = 1000 !< Maximum number of IC patches + integer, parameter :: num_bc_patches_max = 10 !< Maximum number of boundary condition patches integer, parameter :: max_2d_fourier_modes = 10 !< Max Fourier mode index for 2D modal patch (geometry 13) integer, parameter :: max_sph_harm_degree = 5 !< Max degree L for 3D spherical harmonic patch (geometry 14) - integer, parameter :: pathlen_max = 400 + integer, parameter :: pathlen_max = 400 !< Maximum path length for STL/OBJ model files integer, parameter :: nnode = 4 !< Number of QBMM nodes integer, parameter :: dflt_num_igr_iters = 2 !< number of iterations for IGR elliptic solve integer, parameter :: dflt_num_igr_warm_start_iters = 50 !< default number of iterations for IGR elliptic solve @@ -53,7 +53,7 @@ module m_constants real(wp), parameter :: moncon_cutoff = 1e-8_wp !< Monotonicity constraint's limiter to prevent extremas in THINC ! Chemistry - real(wp), parameter :: dflt_T_guess = 1200._wp ! Default guess for temperature (when a previous value is not available) + real(wp), parameter :: dflt_T_guess = 1200._wp !< Default guess for temperature (when a previous value is not available) ! IBM+STL interpolation constants integer, parameter :: num_ray = 20 !< Default number of rays traced per cell @@ -75,24 +75,24 @@ module m_constants ! Constants of the algorithm described by Heirer, E. Hairer, S. P.Norsett, G. Wanner, Solving Ordinary Differential Equations I, ! Chapter II.4 to choose the initial time step size for the adaptive time stepping routine - real(wp), parameter :: threshold_first_guess = 1.e-5_wp - real(wp), parameter :: threshold_second_guess = 1.e-15_wp - real(wp), parameter :: scale_first_guess = 1.e-3_wp - real(wp), parameter :: scale_guess = 1.e-2_wp - real(wp), parameter :: small_guess = 1.e-6_wp + real(wp), parameter :: threshold_first_guess = 1.e-5_wp !< Threshold for initial step size estimate + real(wp), parameter :: threshold_second_guess = 1.e-15_wp !< Threshold for refined step size estimate + real(wp), parameter :: scale_first_guess = 1.e-3_wp !< Scale factor for initial step size + real(wp), parameter :: scale_guess = 1.e-2_wp !< Scale factor for step size adjustment + real(wp), parameter :: small_guess = 1.e-6_wp !< Minimum initial step size ! Relativity integer, parameter :: relativity_cons_to_prim_max_iter = 100 ! Pseudo-random number generator - integer, parameter :: modulus = 2**30 - 1 - integer, parameter :: multiplier = 1664525 - integer, parameter :: increment = 1013904223 - integer, parameter :: amplifier = 3**13 - real(wp), parameter :: decimal_trim = 1.e5_wp + integer, parameter :: modulus = 2**30 - 1 !< PRNG modulus + integer, parameter :: multiplier = 1664525 !< PRNG multiplier + integer, parameter :: increment = 1013904223 !< PRNG increment + integer, parameter :: amplifier = 3**13 !< PRNG amplifier for mixing + real(wp), parameter :: decimal_trim = 1.e5_wp !< PRNG decimal truncation factor ! System constants - integer, parameter :: CASE_FILE_ERROR_CODE = 22 + integer, parameter :: CASE_FILE_ERROR_CODE = 22 !< Exit code for case file validation errors ! Boundary condition enumeration Abbreviations CHAR - Characteristic NR - Non-reflecting SUB - subsonic SUP - supersonic FF - ! Force-free CP - Constant pressure diff --git a/src/common/m_derived_types.fpp b/src/common/m_derived_types.fpp index 3c7cc2fcf9..89a2d0b15c 100644 --- a/src/common/m_derived_types.fpp +++ b/src/common/m_derived_types.fpp @@ -7,7 +7,7 @@ !> @brief Shared derived types for field data, patch geometry, bubble dynamics, and MPI I/O structures module m_derived_types - use m_constants !< Constants + use m_constants use m_precision_select use m_thermochem, only: num_species @@ -147,38 +147,38 @@ module m_derived_types end type ic_model_parameters type :: t_triangle - real(wp), dimension(1:3,1:3) :: v ! Vertices of the triangle - real(wp), dimension(1:3) :: n ! Normal vector + real(wp), dimension(1:3,1:3) :: v !< Vertices of the triangle + real(wp), dimension(1:3) :: n !< Normal vector end type t_triangle type :: t_ray - real(wp), dimension(1:3) :: o ! Origin - real(wp), dimension(1:3) :: d ! Direction + real(wp), dimension(1:3) :: o !< Origin + real(wp), dimension(1:3) :: d !< Direction end type t_ray type :: t_bbox - real(wp), dimension(1:3) :: min ! Minimum coordinates - real(wp), dimension(1:3) :: max ! Maximum coordinates + real(wp), dimension(1:3) :: min !< Minimum coordinates + real(wp), dimension(1:3) :: max !< Maximum coordinates end type t_bbox type :: t_model - integer :: ntrs ! Number of triangles - type(t_triangle), allocatable :: trs(:) ! Triangles + integer :: ntrs !< Number of triangles + type(t_triangle), allocatable :: trs(:) !< Triangles end type t_model type :: t_model_array ! Original CPU-side fields (unchanged) - type(t_model), allocatable :: model - real(wp), allocatable, dimension(:,:,:) :: boundary_v - real(wp), allocatable, dimension(:,:) :: interpolated_boundary_v - integer :: boundary_edge_count - integer :: total_vertices - integer :: interpolate + type(t_model), allocatable :: model !< STL/OBJ geometry model + real(wp), allocatable, dimension(:,:,:) :: boundary_v !< Boundary vertices + real(wp), allocatable, dimension(:,:) :: interpolated_boundary_v !< Interpolated boundary vertices + integer :: boundary_edge_count !< Number of boundary edges + integer :: total_vertices !< Total vertex count + integer :: interpolate !< Interpolation flag ! GPU-friendly flattened arrays - integer :: ntrs ! copy of model%ntrs - real(wp), allocatable, dimension(:,:,:) :: trs_v ! (3, 3, ntrs) - triangle vertices - real(wp), allocatable, dimension(:,:) :: trs_n ! (3, ntrs) - triangle normals + integer :: ntrs !< Copy of model%ntrs + real(wp), allocatable, dimension(:,:,:) :: trs_v !< Triangle vertices (3, 3, ntrs) + real(wp), allocatable, dimension(:,:) :: trs_n !< Triangle normals (3, ntrs) end type t_model_array !> Derived type adding initial condition (ic) patch parameters as attributes NOTE: The requirements for the specification of the @@ -190,13 +190,13 @@ module m_derived_types !> Location of the geometric center, i.e. the centroid, of the patch. It is specified through its x-, y- and z-coordinates, !! respectively. - real(wp) :: x_centroid, y_centroid, z_centroid - real(wp) :: length_x, length_y, length_z !< Dimensions of the patch. x,y,z Lengths. - real(wp) :: radius !< Dimensions of the patch. radius. + real(wp) :: x_centroid, y_centroid, z_centroid !< Geometric center coordinates of the patch + real(wp) :: length_x, length_y, length_z !< Dimensions of the patch. x,y,z Lengths. + real(wp) :: radius !< Dimensions of the patch. radius. !> Vector indicating the various radii for the elliptical and ellipsoidal patch geometries. It is specified through its x-, !! y-, and z-components respectively. - real(wp), dimension(3) :: radii + real(wp), dimension(3) :: radii !< Elliptical/ellipsoidal patch radii in x, y, z real(wp) :: epsilon, beta !< The isentropic vortex parameters for the amplitude of the disturbance and domain of influence. real(wp), dimension(2:9) :: a !< Used by hardcoded IC and as temporary variables. logical :: non_axis_sym @@ -211,20 +211,20 @@ module m_derived_types real(wp), dimension(0:max_sph_harm_degree,-max_sph_harm_degree:max_sph_harm_degree) :: sph_har_coeff !> Normal vector indicating the orientation of the patch. It is specified through its x-, y- and z-components, respectively. - real(wp), dimension(3) :: normal + real(wp), dimension(3) :: normal !< Patch orientation normal vector (x, y, z) !> List of permissions that indicate to the current patch which preceding patches it is allowed to overwrite when it is in !! process of being laid out in the domain - logical, dimension(0:num_patches_max - 1) :: alter_patch + logical, dimension(0:num_patches_max - 1) :: alter_patch !< Overwrite permissions for preceding patches !> Permission indicating to the current patch whether its boundaries will be smoothed out across a few cells or whether they !! are to remain sharp - logical :: smoothen + logical :: smoothen !< Whether patch boundaries are smoothed across cells integer :: smooth_patch_id !< Identity (id) of the patch with which current patch is to get smoothed !> Smoothing coefficient (coeff) for the size of the stencil of cells across which boundaries of the current patch will be !! smeared out - real(wp) :: smooth_coeff + real(wp) :: smooth_coeff !< Smoothing stencil size coefficient real(wp), dimension(num_fluids_max) :: alpha_rho real(wp) :: rho real(wp), dimension(3) :: vel @@ -236,26 +236,22 @@ module m_derived_types real(wp) :: qv !> Primitive variables associated with the patch. In order, these include the partial densities, density, velocity, !! pressure, volume fractions, specific heat ratio function and the liquid stiffness function. - real(wp) :: qvp - real(wp) :: Bx, By, Bz !< Magnetic field components; B%x is not used for 1D - real(wp), dimension(6) :: tau_e !< Elastic stresses added to primitive variables if hypoelasticity = True - real(wp) :: R0 !< Bubble size - real(wp) :: V0 !< Bubble velocity - real(wp) :: p0 !< Bubble size - real(wp) :: m0 !< Bubble velocity - integer :: hcid - !! id for hard coded initial condition - - real(wp) :: cf_val !! color function value - real(wp) :: Y(1:num_species) - - !! STL or OBJ model input parameter - character(LEN=pathlen_max) :: model_filepath !< Path the STL file relative to case_dir. - real(wp), dimension(1:3) :: model_translate !< Translation of the STL object. - real(wp), dimension(1:3) :: model_scale !< Scale factor for the STL object. - real(wp), dimension(1:3) :: model_rotate !< Angle to rotate the STL object along each cartesian coordinate axis, in radians. - integer :: model_spc !< Number of samples per cell to use when discretizing the STL object. - real(wp) :: model_threshold !< Threshold to turn on smoothen STL patch. + real(wp) :: qvp !< Reference entropy per unit mass (SGEOS) + real(wp) :: Bx, By, Bz !< Magnetic field components; B%x is not used for 1D + real(wp), dimension(6) :: tau_e !< Elastic stresses added to primitive variables if hypoelasticity = True + real(wp) :: R0 !< Bubble size + real(wp) :: V0 !< Bubble velocity + real(wp) :: p0 !< Bubble size + real(wp) :: m0 !< Bubble velocity + integer :: hcid !< Hardcoded initial condition ID id for hard coded initial condition + real(wp) :: cf_val !< Color function value + real(wp) :: Y(1:num_species) !< Species mass fractions STL or OBJ model input parameter + character(LEN=pathlen_max) :: model_filepath !< Path the STL file relative to case_dir. + real(wp), dimension(1:3) :: model_translate !< Translation of the STL object. + real(wp), dimension(1:3) :: model_scale !< Scale factor for the STL object. + real(wp), dimension(1:3) :: model_rotate + integer :: model_spc !< Number of samples per cell to use when discretizing the STL object. + real(wp) :: model_threshold !< Threshold to turn on smoothen STL patch. end type ic_patch_parameters type ib_patch_parameters @@ -264,13 +260,13 @@ module m_derived_types !> Location of the geometric center, i.e. the centroid, of the patch. It is specified through its x-, y- and z-coordinates, !! respectively. - real(wp) :: x_centroid, y_centroid, z_centroid + real(wp) :: x_centroid, y_centroid, z_centroid !< Geometric center coordinates of the patch !> Centroid locations of intermediate steps in the time_stepper module real(wp) :: step_x_centroid, step_y_centroid, step_z_centroid - real(wp), dimension(1:3) :: centroid_offset ! offset of center of mass from computed cell center for odd-shaped IBs + real(wp), dimension(1:3) :: centroid_offset !< offset of center of mass from computed cell center for odd-shaped IBs real(wp), dimension(1:3) :: angles real(wp), dimension(1:3) :: step_angles - real(wp), dimension(1:3,1:3) :: rotation_matrix !< matrix that converts from IB reference frame to fluid reference frame + real(wp), dimension(1:3,1:3) :: rotation_matrix !> matrix that converts from fluid reference frame to IB reference frame real(wp), dimension(1:3,1:3) :: rotation_matrix_inverse real(wp) :: c, p, t, m @@ -283,16 +279,16 @@ module m_derived_types character(LEN=pathlen_max) :: model_filepath !< Path the STL file relative to case_dir. real(wp), dimension(1:3) :: model_translate !< Translation of the STL object. real(wp), dimension(1:3) :: model_scale !< Scale factor for the STL object. - real(wp), dimension(1:3) :: model_rotate !< Angle to rotate the STL object along each cartesian coordinate axis, in radians. + real(wp), dimension(1:3) :: model_rotate integer :: model_spc !< Number of samples per cell to use when discretizing the STL object. real(wp) :: model_threshold !< Threshold to turn on smoothen STL patch. Patch conditions for moving imersed boundaries - integer :: moving_ibm ! 0 for no moving, 1 for moving, 2 for moving on forced path - real(wp) :: mass, moment ! mass and moment of inertia of object used to compute forces in 2-way coupling - real(wp), dimension(1:3) :: force, torque ! vectors for the computed force and torque values applied to an IB + integer :: moving_ibm !< 0 for no moving, 1 for moving, 2 for moving on forced path + real(wp) :: mass, moment !< mass and moment of inertia of object used to compute forces in 2-way coupling + real(wp), dimension(1:3) :: force, torque !< vectors for the computed force and torque values applied to an IB real(wp), dimension(1:3) :: vel - real(wp), dimension(1:3) :: step_vel ! velocity array used to store intermediate steps in the time_stepper module + real(wp), dimension(1:3) :: step_vel !< velocity array used to store intermediate steps in the time_stepper module real(wp), dimension(1:3) :: angular_vel - real(wp), dimension(1:3) :: step_angular_vel ! velocity array used to store intermediate steps in the time_stepper module + real(wp), dimension(1:3) :: step_angular_vel !< velocity array used to store intermediate steps in the time_stepper module end type ib_patch_parameters !> Derived type annexing the physical parameters (PP) of the fluids. These include the specific heat ratio function and liquid @@ -362,8 +358,8 @@ module m_derived_types real(wp) :: npulse !< Number of cycles of pulse real(wp) :: dir !< Direction of pulse real(wp) :: delay !< Time-delay of pulse start - real(wp) :: foc_length ! < Focal length of transducer - real(wp) :: aperture ! < Aperture diameter of transducer + real(wp) :: foc_length !< Focal length of transducer + real(wp) :: aperture !< Aperture diameter of transducer real(wp) :: element_spacing_angle !< Spacing between aperture elements in 2D acoustic array !> Ratio of aperture element diameter to side length of polygon connecting their centers, in 3D acoustic array real(wp) :: element_polygon_ratio diff --git a/src/common/m_helper.fpp b/src/common/m_helper.fpp index 72a92442d5..7af699cfd4 100644 --- a/src/common/m_helper.fpp +++ b/src/common/m_helper.fpp @@ -8,9 +8,9 @@ !> @brief Utility routines for bubble model setup, coordinate transforms, array sampling, and special functions module m_helper - use m_derived_types !< Definitions of the derived types - use m_global_parameters !< Definitions of the global parameters - use ieee_arithmetic !< For checking NaN + use m_derived_types + use m_global_parameters + use ieee_arithmetic !< For checking NaN implicit none @@ -542,7 +542,7 @@ contains elemental function double_factorial(n_in) result(R_result) integer, intent(in) :: n_in - integer, parameter :: int64_kind = selected_int_kind(18) ! 18 bytes for 64-bit integer + integer, parameter :: int64_kind = selected_int_kind(18) !< 18 bytes for 64-bit integer integer(kind=int64_kind) :: R_result integer :: i @@ -556,7 +556,7 @@ contains elemental function factorial(n_in) result(R_result) integer, intent(in) :: n_in - integer, parameter :: int64_kind = selected_int_kind(18) ! 18 bytes for 64-bit integer + integer, parameter :: int64_kind = selected_int_kind(18) !< 18 bytes for 64-bit integer integer(kind=int64_kind) :: R_result integer :: i diff --git a/src/common/m_helper_basic.fpp b/src/common/m_helper_basic.fpp index c4f2599d62..0ab15a41ee 100644 --- a/src/common/m_helper_basic.fpp +++ b/src/common/m_helper_basic.fpp @@ -7,7 +7,7 @@ !> @brief Basic floating-point utilities: approximate equality, default detection, and coordinate bounds module m_helper_basic - use m_derived_types !< Definitions of the derived types + use m_derived_types implicit none diff --git a/src/common/m_model.fpp b/src/common/m_model.fpp index 2c297ebe8e..9cfc11872c 100644 --- a/src/common/m_model.fpp +++ b/src/common/m_model.fpp @@ -29,9 +29,9 @@ module m_model #endif !! array of STL models that can be allocated and then used in IB marker and levelset compute - type(t_model_array), allocatable, target :: models(:) - !! GPU-friendly flat arrays for STL model data - integer, allocatable :: gpu_ntrs(:) + !> STL/OBJ models for IB markers and levelset GPU-friendly flat arrays for STL model data + type(t_model_array), allocatable, target :: models(:) + integer, allocatable :: gpu_ntrs(:) !< GPU-friendly flat arrays for STL model data real(wp), allocatable, dimension(:,:,:,:) :: gpu_trs_v real(wp), allocatable, dimension(:,:,:) :: gpu_trs_n real(wp), allocatable, dimension(:,:,:,:) :: gpu_boundary_v diff --git a/src/common/m_mpi_common.fpp b/src/common/m_mpi_common.fpp index 627c6a30bf..40355b8632 100644 --- a/src/common/m_mpi_common.fpp +++ b/src/common/m_mpi_common.fpp @@ -12,8 +12,8 @@ module m_mpi_common use mpi !< Message passing interface (MPI) module #endif - use m_derived_types !< Definitions of the derived types - use m_global_parameters !< Definitions of the global parameters + use m_derived_types + use m_global_parameters use m_helper use ieee_arithmetic use m_nvtx @@ -26,11 +26,11 @@ module m_mpi_common !> This variable is utilized to pack and send the buffer of the cell-average primitive variables, for a single computational !! domain boundary at the time, to the relevant neighboring processor. - real(wp), private, allocatable, dimension(:) :: buff_send + real(wp), private, allocatable, dimension(:) :: buff_send !< Primitive variable send buffer for halo exchange !> buff_recv is utilized to receive and unpack the buffer of the cell- average primitive variables, for a single computational !! domain boundary at the time, from the relevant neighboring processor. - real(wp), private, allocatable, dimension(:) :: buff_recv + real(wp), private, allocatable, dimension(:) :: buff_recv !< Primitive variable receive buffer for halo exchange type(int_bounds_info) :: comm_coords(3) integer :: comm_size(3) $:GPU_DECLARE(create='[comm_coords, comm_size]') @@ -250,12 +250,12 @@ contains !> @brief Gathers variable-length real vectors from all MPI ranks onto the root process. impure subroutine s_mpi_gather_data(my_vector, counts, gathered_vector, root) - integer, intent(in) :: counts ! Array of vector lengths for each process - real(wp), intent(in), dimension(counts) :: my_vector ! Input vector on each process - integer, intent(in) :: root ! Rank of the root process - real(wp), allocatable, intent(out) :: gathered_vector(:) ! Gathered vector on the root process + integer, intent(in) :: counts !< Array of vector lengths for each process + real(wp), intent(in), dimension(counts) :: my_vector !< Input vector on each process + integer, intent(in) :: root !< Rank of the root process + real(wp), allocatable, intent(out) :: gathered_vector(:) !< Gathered vector on the root process integer :: i - integer :: ierr !< Generic flag used to identify and report MPI errors + integer :: ierr !< Generic flag used to identify and report MPI errors integer, allocatable :: recounts(:), displs(:) #ifdef MFC_MPI @@ -523,7 +523,7 @@ contains !> Temporary storage variable that holds the reduced maximum value and the rank of the processor with which the value is !! associated - real(wp), dimension(2) :: var_glb + real(wp), dimension(2) :: var_glb !< Reduced (max value, rank) pair ! Performing reduction procedure and eventually storing its result into the variable that was initially inputted into the ! subroutine @@ -1070,7 +1070,7 @@ contains beg_end = (/boundary_conditions(mpi_dir)%beg, boundary_conditions(mpi_dir)%end/) grid_dims = (/m, n, p/) - if (pbc_loc == -1) then + if (pbc_loc == -1) then ! PBC at the beginning ! Phase 1: Rightward accumulation Send END buffer to right neighbor, recv from left into BEG, ADD pack_offset = grid_dims(mpi_dir) + 1 unpack_offset = 0 @@ -1287,7 +1287,7 @@ contains !> Remaining number of cells, in a particular coordinate direction, after the majority is divided up among the available !! processors - integer :: rem_cells + integer :: rem_cells !< Remaining cells after distribution among processors integer :: recon_order !< WENO or MUSCL reconstruction order integer :: i, j, k !< Generic loop iterators integer :: ierr !< Generic flag used to identify and report MPI errors @@ -1677,7 +1677,7 @@ contains ! Ghost zone at the end if (proc_coords(1) < num_procs_x - 1 .and. format == 1) then offset_x%end = 2 - else + else ! PBC at the beginning only offset_x%end = 0 end if #endif @@ -1686,10 +1686,10 @@ contains if (parallel_io) then if (proc_coords(1) < rem_cells) then start_idx(1) = (m + 1)*proc_coords(1) - else + else ! PBC at the end start_idx(1) = (m + 1)*proc_coords(1) + rem_cells end if - else + else ! PBC at the end only #ifdef MFC_PRE_PROCESS if (old_grid .neqv. .true.) then dx = (x_domain%end - x_domain%beg)/real(m_glb + 1, wp) @@ -1697,7 +1697,7 @@ contains if (proc_coords(1) < rem_cells) then x_domain%beg = x_domain%beg + dx*real((m + 1)*proc_coords(1)) x_domain%end = x_domain%end - dx*real((m + 1)*(num_procs_x - proc_coords(1) - 1) - (num_procs_x - rem_cells)) - else + else ! PBC at the beginning only x_domain%beg = x_domain%beg + dx*real((m + 1)*proc_coords(1) + rem_cells) x_domain%end = x_domain%end - dx*real((m + 1)*(num_procs_x - proc_coords(1) - 1)) end if @@ -1745,18 +1745,18 @@ contains ! Send/receive buffer to/from bc_x%end/bc_x%beg call MPI_SENDRECV(dx(m - buff_size + 1), buff_size, mpi_p, bc_x%end, 0, dx(-buff_size), buff_size, mpi_p, & & bc_x%beg, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE, ierr) - else ! PBC at the beginning only + else ! PBC at the end ! Send/receive buffer to/from bc_x%beg/bc_x%beg call MPI_SENDRECV(dx(0), buff_size, mpi_p, bc_x%beg, 1, dx(-buff_size), buff_size, mpi_p, bc_x%beg, 0, & & MPI_COMM_WORLD, MPI_STATUS_IGNORE, ierr) end if - else ! PBC at the end + else ! PBC at the end only if (bc_x%beg >= 0) then ! PBC at the end and beginning ! Send/receive buffer to/from bc_x%beg/bc_x%end call MPI_SENDRECV(dx(0), buff_size, mpi_p, bc_x%beg, 1, dx(m + 1), buff_size, mpi_p, bc_x%end, 1, & & MPI_COMM_WORLD, MPI_STATUS_IGNORE, ierr) - else ! PBC at the end only + else ! Send/receive buffer to/from bc_x%end/bc_x%end call MPI_SENDRECV(dx(m - buff_size + 1), buff_size, mpi_p, bc_x%end, 0, dx(m + 1), buff_size, mpi_p, & & bc_x%end, 1, MPI_COMM_WORLD, MPI_STATUS_IGNORE, ierr) diff --git a/src/common/m_nvtx.f90 b/src/common/m_nvtx.f90 index 82d6e1a208..d5adbffb14 100644 --- a/src/common/m_nvtx.f90 +++ b/src/common/m_nvtx.f90 @@ -18,13 +18,13 @@ module m_nvtx integer(c_int16_t) :: version = 1 integer(c_int16_t) :: size = 48 ! integer(c_int) :: category = 0 - integer(c_int) :: colorType = 1 ! NVTX_COLOR_ARGB = 1 + integer(c_int) :: colorType = 1 !< NVTX_COLOR_ARGB = 1 integer(c_int) :: color - integer(c_int) :: payloadType = 0 ! NVTX_PAYLOAD_UNKNOWN = 0 + integer(c_int) :: payloadType = 0 !< NVTX_PAYLOAD_UNKNOWN = 0 integer(c_int) :: reserved0 - integer(c_int64_t) :: payload ! union uint,int,double - integer(c_int) :: messageType = 1 ! NVTX_MESSAGE_TYPE_ASCII = 1 - type(c_ptr) :: message ! ascii char + integer(c_int64_t) :: payload !< union uint,int,double + integer(c_int) :: messageType = 1 !< NVTX_MESSAGE_TYPE_ASCII = 1 + type(c_ptr) :: message !< ascii char end type nvtxEventAttributes #if defined(MFC_GPU) && defined(__PGI) diff --git a/src/common/m_phase_change.fpp b/src/common/m_phase_change.fpp index f8e5aaa6f0..751c34cca6 100644 --- a/src/common/m_phase_change.fpp +++ b/src/common/m_phase_change.fpp @@ -9,12 +9,12 @@ module m_phase_change #ifndef MFC_POST_PROCESS - use m_derived_types !< Definitions of the derived types - use m_global_parameters !< Definitions of the global parameters - use m_mpi_proxy !< Message passing interface (MPI) module proxy - use m_variables_conversion !< State variables type conversion procedures + use m_derived_types + use m_global_parameters + use m_mpi_proxy + use m_variables_conversion use ieee_arithmetic - use m_helper_basic !< Functions to compare floating point numbers + use m_helper_basic implicit none @@ -24,9 +24,9 @@ module m_phase_change !> @name Parameters for the first order transition phase change !> @{ integer, parameter :: max_iter = 1e8_wp !< max # of iterations - real(wp), parameter :: pCr = 4.94e7_wp !< Critical water pressure - real(wp), parameter :: TCr = 385.05_wp + 273.15_wp !< Critical water temperature - real(wp), parameter :: mixM = 1.0e-8_wp !< threshold for 'mixture cell'. If Y < mixM, phase change does not happen + real(wp), parameter :: pCr = 4.94e7_wp !< Critical pressure of water [Pa] + real(wp), parameter :: TCr = 385.05_wp + 273.15_wp !< Critical temperature of water [K] + real(wp), parameter :: mixM = 1.0e-8_wp !< Mixture mass fraction threshold for triggering phase change integer, parameter :: lp = 1 !< index for the liquid phase of the reacting fluid integer, parameter :: vp = 2 !< index for the vapor phase of the reacting fluid !> @} @@ -75,10 +75,10 @@ contains real(wp) :: pS, pSOV, pSSL !< equilibrium pressure for mixture, overheated vapor, and subcooled liquid !> equilibrium temperature for mixture, overheated vapor, and subcooled liquid. Saturation Temperatures at overheated vapor !! and subcooled liquid - real(wp) :: TS, TSOV, TSSL, TSatOV, TSatSL - real(wp) :: rhoe, dynE, rhos !< total internal energy, kinetic energy, and total entropy - real(wp) :: rho, rM, m1, m2, MCT !< total density, total reacting mass, individual reacting masses - real(wp) :: TvF !< total volume fraction + real(wp) :: TS, TSOV, TSSL, TSatOV, TSatSL !< Equilibrium and saturation temperatures + real(wp) :: rhoe, dynE, rhos !< total internal energy, kinetic energy, and total entropy + real(wp) :: rho, rM, m1, m2, MCT !< total density, total reacting mass, individual reacting masses + real(wp) :: TvF !< total volume fraction ! $:GPU_DECLARE(create='[pS,pSOV,pSSL,TS,TSOV,TSSL,TSatOV,TSatSL]') ! $:GPU_DECLARE(create='[rhoe,dynE,rhos,rho,rM,m1,m2,MCT,TvF]') @@ -385,10 +385,10 @@ contains #:else real(wp), dimension(num_fluids) :: p_infpTg !< stiffness for the participating fluids for pTg-equilibrium #:endif - real(wp), dimension(2, 2) :: Jac, InvJac, TJac !< matrices for the Newton Solver - real(wp), dimension(2) :: R2D, DeltamP !< residual and correction array - real(wp) :: Om ! underrelaxation factor - real(wp) :: mCP, mCPD, mCVGP, mCVGP2, mQ, mQD ! auxiliary variables for the pTg-solver + real(wp), dimension(2, 2) :: Jac, InvJac, TJac !< matrices for the Newton Solver + real(wp), dimension(2) :: R2D, DeltamP !< residual and correction array + real(wp) :: Om !< underrelaxation factor + real(wp) :: mCP, mCPD, mCVGP, mCVGP2, mQ, mQD !< auxiliary variables for the pTg-solver real(wp) :: ml, mT, dFdT, dTdm, dTdp !> Generic loop iterators diff --git a/src/common/m_precision_select.f90 b/src/common/m_precision_select.f90 index 5fc1c5c667..7c730cf303 100644 --- a/src/common/m_precision_select.f90 +++ b/src/common/m_precision_select.f90 @@ -13,7 +13,7 @@ module m_precision_select implicit none ! Define the available precision types - integer, parameter :: half_precision = 2 ! selected_real_kind(3, 4) + integer, parameter :: half_precision = 2 !< selected_real_kind(3, 4) integer, parameter :: single_precision = selected_real_kind(6, 37) integer, parameter :: double_precision = selected_real_kind(15, 307) integer, parameter :: hp = half_precision @@ -22,7 +22,7 @@ module m_precision_select ! Set the working precision (wp) to single or double #ifdef MFC_SINGLE_PRECISION - integer, parameter :: wp = single_precision ! Change to single_precision if needed + integer, parameter :: wp = single_precision !< Change to single_precision if needed #else integer, parameter :: wp = double_precision #endif @@ -42,7 +42,7 @@ module m_precision_select ! MPI types per element. IE Real(kind=2) <=> 2 MPI_BYTE integer, parameter :: mpi_io_type = merge(2, 1, stp == half_precision) #else - integer, parameter :: mpi_p = -100 ! Default value when MPI is not used + integer, parameter :: mpi_p = -100 !< Default value when MPI is not used integer, parameter :: mpi_2p = -100 integer, parameter :: mpi_io_p = -100 integer, parameter :: mpi_io_type = -100 diff --git a/src/common/m_variables_conversion.fpp b/src/common/m_variables_conversion.fpp index e19919c27e..712261ced0 100644 --- a/src/common/m_variables_conversion.fpp +++ b/src/common/m_variables_conversion.fpp @@ -8,10 +8,10 @@ !> @brief Conservative-to-primitive variable conversion, mixture property evaluation, and pressure computation module m_variables_conversion - use m_derived_types !< Definitions of the derived types - use m_global_parameters !< Definitions of the global parameters - use m_mpi_proxy !< Message passing interface (MPI) module proxy - use m_helper_basic !< Functions to compare floating point numbers + use m_derived_types + use m_global_parameters + use m_mpi_proxy + use m_helper_basic use m_helper use m_thermochem, only: num_species, get_temperature, get_pressure, gas_constant, get_mixture_molecular_weight, & & get_mixture_energy_mass @@ -189,7 +189,7 @@ contains rho = q_vf(1)%sf(i, j, k) gamma = q_vf(gamma_idx)%sf(i, j, k) pi_inf = q_vf(pi_inf_idx)%sf(i, j, k) - qv = 0._wp ! keep this value nill for now. For future adjustment + qv = 0._wp ! keep this value nil for now. For future adjustment ! Post process requires rho_sf/gamma_sf/pi_inf_sf/qv_sf to also be updated #ifdef MFC_POST_PROCESS @@ -527,18 +527,18 @@ contains real(wp) :: vftmp, nbub_sc real(wp) :: G_K real(wp) :: pres - integer :: i, j, k, l !< Generic loop iterators + integer :: i, j, k, l !< Generic loop iterators real(wp) :: T real(wp) :: pres_mag - real(wp) :: Ga ! Lorentz factor (gamma in relativity) - real(wp) :: B2 ! Magnetic field magnitude squared - real(wp) :: B(3) ! Magnetic field components - real(wp) :: m2 ! Relativistic momentum magnitude squared - real(wp) :: S ! Dot product of the magnetic field and the relativistic momentum - real(wp) :: W, dW ! W := rho*v*Ga**2; f = f(W) in Newton-Raphson - real(wp) :: E, D ! Prim/Cons variables within Newton-Raphson iteration - real(wp) :: f, dGa_dW, dp_dW, df_dW ! Functions within Newton-Raphson iteration - integer :: iter ! Newton-Raphson iteration counter + real(wp) :: Ga !< Lorentz factor (gamma in relativity) + real(wp) :: B2 !< Magnetic field magnitude squared + real(wp) :: B(3) !< Magnetic field components + real(wp) :: m2 !< Relativistic momentum magnitude squared + real(wp) :: S !< Dot product of the magnetic field and the relativistic momentum + real(wp) :: W, dW !< W := rho*v*Ga**2; f = f(W) in Newton-Raphson + real(wp) :: E, D !< Prim/Cons variables within Newton-Raphson iteration + real(wp) :: f, dGa_dW, dp_dW, df_dW !< Functions within Newton-Raphson iteration + integer :: iter !< Newton-Raphson iteration counter $:GPU_PARALLEL_LOOP(collapse=3, private='[alpha_K, alpha_rho_K, Re_K, nRtmp, rho_K, gamma_K, pi_inf_K, qv_K, dyn_pres_K, & & rhoYks, B, pres, vftmp, nbub_sc, G_K, T, pres_mag, Ga, B2, m2, S, W, dW, E, D, f, dGa_dW, dp_dW, & @@ -608,7 +608,7 @@ contains $:GPU_LOOP(parallelism='[seq]') do iter = 1, relativity_cons_to_prim_max_iter Ga = (W + B2)*W/sqrt((W + B2)**2*W**2 - (m2*W**2 + S**2*(2*W + B2))) - pres = (W - D*Ga)/((gamma_K + 1)*Ga**2) ! Thermal pressure from EOS + pres = (W - D*Ga)/((gamma_K + 1)*Ga**2) f = W - pres + (1 - 1/(2*Ga**2))*B2 - S**2/(2*W**2) - E - D ! The first equation below corrects a typo in (Mignone & Bodo, 2006) m2*W**2 -> 2*m2*W**2, which would @@ -622,7 +622,7 @@ contains dW = -f/df_dW W = W + dW - if (abs(dW) < 1.e-12_wp*W) exit + if (abs(dW) < 1.e-12_wp*W) exit ! Relative convergence criterion end do ! Recalculate pressure using converged W @@ -832,12 +832,12 @@ contains real(wp), dimension(num_species) :: Ys real(wp) :: e_mix, mix_mol_weight, T real(wp) :: pres_mag - real(wp) :: Ga ! Lorentz factor (gamma in relativity) - real(wp) :: h ! relativistic enthalpy - real(wp) :: v2 ! Square of the velocity magnitude - real(wp) :: B2 ! Square of the magnetic field magnitude - real(wp) :: vdotB ! Dot product of the velocity and magnetic field vectors - real(wp) :: B(3) ! Magnetic field components + real(wp) :: Ga !< Lorentz factor (gamma in relativity) + real(wp) :: h !< relativistic enthalpy + real(wp) :: v2 !< Square of the velocity magnitude + real(wp) :: B2 !< Square of the magnetic field magnitude + real(wp) :: vdotB !< Dot product of the velocity and magnetic field vectors + real(wp) :: B(3) !< Magnetic field components pres_mag = 0._wp @@ -1299,21 +1299,21 @@ contains real(wp) :: blkmod1, blkmod2 integer :: q - if (chemistry) then + if (chemistry) then ! Reacting mixture sound speed if (avg_state == 1 .and. abs(c_c) > verysmall) then c = sqrt(c_c - (gamma - 1.0_wp)*(vel_sum - H)) else c = sqrt((1.0_wp + 1.0_wp/gamma)*pres/rho) end if - else if (relativity) then + else if (relativity) then ! Relativistic sound speed ! Only supports perfect gas for now c = sqrt((1._wp + 1._wp/gamma)*pres/rho/H) else - if (alt_soundspeed) then + if (alt_soundspeed) then ! Wood's mixture sound speed via bulk moduli blkmod1 = ((gammas(1) + 1._wp)*pres + pi_infs(1))/gammas(1) blkmod2 = ((gammas(2) + 1._wp)*pres + pi_infs(2))/gammas(2) c = (1._wp/(rho*(adv(1)/blkmod1 + adv(2)/blkmod2))) - else if (model_eqns == 3) then + else if (model_eqns == 3) then ! Six-equation model sound speed c = 0._wp $:GPU_LOOP(parallelism='[seq]') do q = 1, num_fluids @@ -1349,7 +1349,7 @@ contains $:GPU_ROUTINE(function_name='s_compute_fast_magnetosonic_speed', parallelism='[seq]', cray_noinline=True) real(wp), intent(in) :: B(3), rho, c - real(wp), intent(in) :: h ! only used for relativity + real(wp), intent(in) :: h !< only used for relativity real(wp), intent(out) :: c_fast integer, intent(in) :: norm real(wp) :: B2, term, disc diff --git a/src/post_process/m_checker.fpp b/src/post_process/m_checker.fpp index 6d01538edb..c46bc8fd0b 100644 --- a/src/post_process/m_checker.fpp +++ b/src/post_process/m_checker.fpp @@ -7,9 +7,9 @@ !> @brief Validates post-process input parameters and output format consistency module m_checker - use m_global_parameters !< Definitions of the global parameters - use m_mpi_proxy !< Message passing interface (MPI) module proxy - use m_helper_basic !< Functions to compare floating point numbers + use m_global_parameters + use m_mpi_proxy + use m_helper_basic use m_helper implicit none diff --git a/src/post_process/m_data_input.f90 b/src/post_process/m_data_input.f90 index ef006ddeda..255b93f964 100644 --- a/src/post_process/m_data_input.f90 +++ b/src/post_process/m_data_input.f90 @@ -6,12 +6,12 @@ module m_data_input #ifdef MFC_MPI - use mpi !< Message passing interface (MPI) module + use mpi #endif - use m_derived_types !< Definitions of the derived types - use m_global_parameters !< Global parameters for the code - use m_mpi_proxy !< Message passing interface (MPI) module proxy + use m_derived_types + use m_global_parameters + use m_mpi_proxy use m_mpi_common use m_compile_specific use m_boundary_common @@ -214,17 +214,17 @@ end subroutine s_allocate_field_arrays impure subroutine s_read_serial_data_files(t_step) integer, intent(in) :: t_step - character(LEN=len_trim(case_dir) + 2*name_len) :: t_step_dir !< Location of the time-step directory associated with t_step - character(LEN=len_trim(case_dir) + 3*name_len) :: file_loc !< Generic string used to store the location of a particular file + character(LEN=len_trim(case_dir) + 2*name_len) :: t_step_dir + character(LEN=len_trim(case_dir) + 3*name_len) :: file_loc !> Used to store the variable position, in character form, of the currently manipulated conservative variable file character(LEN=int(floor(log10(real(sys_size, wp)))) + 1) :: file_num !> Location of the time-step directory associated with t_step character(LEN=len_trim(case_dir) + 2*name_len) :: t_step_ib_dir - logical :: dir_check !< Generic logical used to test the existence of a particular folder - logical :: file_check !< Generic logical used to test the existence of a particular file - integer :: i !< Generic loop iterator + logical :: dir_check + logical :: file_check + integer :: i ! Setting location of time-step folder based on current time-step @@ -533,7 +533,7 @@ end subroutine s_read_parallel_conservative_data !> Computation of parameters, allocation procedures, and/or any other tasks needed to properly setup the module impure subroutine s_initialize_data_input_module - integer :: i !< Generic loop iterator + integer :: i ! Allocating the parts of the conservative and primitive variables that do not require the direct knowledge of the ! dimensionality of the simulation @@ -589,7 +589,7 @@ end subroutine s_initialize_data_input_module !> Deallocation procedures for the module impure subroutine s_finalize_data_input_module - integer :: i !< Generic loop iterator + integer :: i ! Deallocating the conservative and primitive variables diff --git a/src/post_process/m_data_output.fpp b/src/post_process/m_data_output.fpp index 166fd67f5a..4a679c85c5 100644 --- a/src/post_process/m_data_output.fpp +++ b/src/post_process/m_data_output.fpp @@ -5,10 +5,10 @@ !> @brief Writes post-processed grid and flow-variable data to Silo-HDF5 or binary database files module m_data_output - use m_derived_types ! Definitions of the derived types - use m_global_parameters ! Global parameters - use m_derived_variables !< Procedures used to compute quantities derived - use m_mpi_proxy ! Message passing interface (MPI) module proxy + use m_derived_types + use m_global_parameters + use m_derived_variables + use m_mpi_proxy use m_compile_specific use m_helper use m_variables_conversion @@ -414,7 +414,7 @@ contains ! Generic string used to store the location of a particular file character(LEN=len_trim(case_dir) + 3*name_len) :: file_loc - integer :: ierr !< Generic flag used to identify and report database errors + integer :: ierr ! Silo-HDF5 Database Format @@ -499,7 +499,7 @@ contains !> @brief Open the interface data file for appending extracted interface coordinates. impure subroutine s_open_intf_data_file() - character(LEN=path_len + 3*name_len) :: file_path !< Relative path to a file in the case directory + character(LEN=path_len + 3*name_len) :: file_path write (file_path, '(A)') '/intf_data.dat' file_path = trim(case_dir) // trim(file_path) @@ -512,7 +512,7 @@ contains !> @brief Open the energy data file for appending volume-integrated energy budget quantities. impure subroutine s_open_energy_data_file() - character(LEN=path_len + 3*name_len) :: file_path !< Relative path to a file in the case directory + character(LEN=path_len + 3*name_len) :: file_path write (file_path, '(A)') '/eng_data.dat' file_path = trim(case_dir) // trim(file_path) @@ -545,7 +545,7 @@ contains ! Generic loop iterator integer :: i - integer :: ierr !< Generic flag used to identify and report database errors + integer :: ierr ! Silo-HDF5 Database Format @@ -703,7 +703,7 @@ contains ! Generic loop iterator integer :: i, j, k - integer :: ierr !< Generic flag used to identify and report database errors + integer :: ierr ! Silo-HDF5 Database Format @@ -852,7 +852,7 @@ contains logical :: lg_bub_file, file_exist integer, dimension(2) :: gsizes, lsizes, start_idx_part integer :: ifile - integer :: ierr !< Generic flag used to identify and report MPI errors + integer :: ierr real(wp) :: file_time, file_dt integer :: file_num_procs, file_tot_part, tot_part integer :: i @@ -1206,7 +1206,7 @@ contains character(len=64), dimension(num_procs) :: var_names integer, dimension(num_procs) :: var_types real(wp) :: dummy_data - integer :: ierr !< Generic flag used to identify and report database errors + integer :: ierr integer :: i dummy_data = 0._wp @@ -1296,8 +1296,8 @@ contains impure subroutine s_write_intf_data_file(q_prim_vf) type(scalar_field), dimension(sys_size), intent(in) :: q_prim_vf - integer :: i, j, k, l, cent !< Generic loop iterators - integer :: counter, root !< number of data points extracted to fit shape to SH perturbations + integer :: i, j, k, l, cent + integer :: counter, root !< number of data points extracted to fit shape to SH perturbations real(wp), allocatable :: x_td(:), y_td(:), x_d1(:), y_d1(:), y_d(:), x_d(:) real(wp) :: axp, axm, ayp, aym, tgp, euc_d, thres, maxalph_loc, maxalph_glb @@ -1387,7 +1387,7 @@ contains real(wp) :: rho, pres, dV, tmp, gamma, pi_inf, MaxMa, MaxMa_glb, maxvel, c, Ma, H, qv real(wp), dimension(num_vels) :: vel real(wp), dimension(num_fluids) :: adv - integer :: i, j, k, l, s ! looping indices + integer :: i, j, k, l, s !< looping indices Egk = 0._wp Elp = 0._wp @@ -1480,7 +1480,7 @@ contains ! the local sub-domain. Note that for the Binary data- base format and multidimensional data, the root process only has to ! close the file associated with the local sub- domain, because one associated with the entire domain is not generated. - integer :: ierr !< Generic flag used to identify and report database errors + integer :: ierr ! Silo-HDF5 database format diff --git a/src/post_process/m_derived_variables.fpp b/src/post_process/m_derived_variables.fpp index f3c2bef50e..4c18dee689 100644 --- a/src/post_process/m_derived_variables.fpp +++ b/src/post_process/m_derived_variables.fpp @@ -6,10 +6,10 @@ module m_derived_variables - use m_derived_types !< Definitions of the derived types - use m_global_parameters !< Global parameters for the code - use m_mpi_proxy !< Message passing interface (MPI) module proxy - use m_helper_basic !< Functions to compare floating point numbers + use m_derived_types + use m_global_parameters + use m_mpi_proxy + use m_helper_basic use m_variables_conversion implicit none @@ -20,7 +20,7 @@ module m_derived_variables !> Gradient magnitude (gm) of the density for each cell of the computational sub-domain. This variable is employed in the !! calculation of the numerical Schlieren function. - real(wp), allocatable, dimension(:,:,:) :: gm_rho_sf + real(wp), allocatable, dimension(:,:,:) :: gm_rho_sf !< Density gradient magnitude for numerical Schlieren !> @name Finite-difference (fd) coefficients in x-, y- and z-coordinate directions. Note that because sufficient boundary !! information is available for all the active coordinate directions, the centered family of the finite-difference schemes is @@ -36,7 +36,7 @@ module m_derived_variables !! avoid cycling through the third dimension of the flow variable(s) when the simulation is not 3D and the size of the buffer is !! non-zero. Note that a similar procedure does not have to be applied to the second dimension since in 1D, the buffer size is !! always zero. - integer, private :: flg + integer, private :: flg !< Dimensionality flag: 1 = 3D dataset, 0 = otherwise contains @@ -87,7 +87,7 @@ contains real(wp), dimension(-offset_x%beg:m + offset_x%end,-offset_y%beg:n + offset_y%end,-offset_z%beg:p + offset_z%end), & & intent(inout) :: q_sf - integer :: i, j, k !< Generic loop iterators + integer :: i, j, k ! Computing specific heat ratio from specific heat ratio function do k = -offset_z%beg, p + offset_z%end @@ -109,7 +109,7 @@ contains real(wp), dimension(-offset_x%beg:m + offset_x%end,-offset_y%beg:n + offset_y%end,-offset_z%beg:p + offset_z%end), & & intent(inout) :: q_sf - integer :: i, j, k !< Generic loop iterators + integer :: i, j, k ! Calculating the values of the liquid stiffness from those of the specific heat ratio function and the liquid stiffness ! function @@ -135,7 +135,7 @@ contains real(wp), dimension(-offset_x%beg:m + offset_x%end,-offset_y%beg:n + offset_y%end,-offset_z%beg:p + offset_z%end), & & intent(inout) :: q_sf - integer :: i, j, k !< Generic loop iterators + integer :: i, j, k ! Fluid bulk modulus for alternate sound speed real(wp) :: blkmod1, blkmod2 @@ -181,8 +181,8 @@ contains real(wp), dimension(-offset_x%beg:m + offset_x%end,-offset_y%beg:n + offset_y%end,-offset_z%beg:p + offset_z%end), & & intent(inout) :: q_sf - real(wp) :: top, bottom, slope !< Flux limiter calcs - integer :: j, k, l !< Generic loop iterators + real(wp) :: top, bottom, slope + integer :: j, k, l do l = -offset_z%beg, p + offset_z%end do k = -offset_y%beg, n + offset_y%end @@ -306,7 +306,7 @@ contains real(wp), dimension(-offset_x%beg:m + offset_x%end,-offset_y%beg:n + offset_y%end,-offset_z%beg:p + offset_z%end), & & intent(inout) :: q_sf - integer :: j, k, l, r !< Generic loop iterators + integer :: j, k, l, r ! Computing the vorticity component in the x-coordinate direction if (i == 1) then @@ -380,7 +380,7 @@ contains real(wp), dimension(1:3,1:3) :: q_jacobian_sf, S, S2, O, O2 real(wp) :: trS, Q, IIS - integer :: j, k, l, r, jj, kk !< Generic loop iterators + integer :: j, k, l, r, jj, kk do l = -offset_z%beg, p + offset_z%end do k = -offset_y%beg, n + offset_y%end @@ -438,6 +438,7 @@ contains type(scalar_field), dimension(sys_size), intent(in) :: q_prim_vf !> Liutex magnitude + real(wp), dimension(-offset_x%beg:m + offset_x%end,-offset_y%beg:n + offset_y%end,-offset_z%beg:p + offset_z%end), & & intent(out) :: liutex_mag @@ -445,20 +446,20 @@ contains real(wp), dimension(-offset_x%beg:m + offset_x%end,-offset_y%beg:n + offset_y%end,-offset_z%beg:p + offset_z%end,nm), & & intent(out) :: liutex_axis - character, parameter :: ivl = 'N' !< compute left eigenvectors - character, parameter :: ivr = 'V' !< compute right eigenvectors - real(wp), dimension(nm, nm) :: vgt !< velocity gradient tensor - real(wp), dimension(nm) :: lr, li !< real and imaginary parts of eigenvalues - real(wp), dimension(nm, nm) :: vl, vr !< left and right eigenvectors - integer, parameter :: lwork = 4*nm !< size of work array (4*nm recommended) - real(wp), dimension(lwork) :: work !< work array + character, parameter :: ivl = 'N' !< compute left eigenvectors + character, parameter :: ivr = 'V' !< compute right eigenvectors + real(wp), dimension(nm, nm) :: vgt !< velocity gradient tensor + real(wp), dimension(nm) :: lr, li !< real and imaginary parts of eigenvalues + real(wp), dimension(nm, nm) :: vl, vr !< left and right eigenvectors + integer, parameter :: lwork = 4*nm !< size of work array (4*nm recommended) + real(wp), dimension(lwork) :: work !< work array integer :: info - real(wp), dimension(nm) :: eigvec !< real eigenvector - real(wp) :: eigvec_mag !< magnitude of real eigenvector - real(wp) :: omega_proj !< projection of vorticity on real eigenvector - real(wp) :: lci !< imaginary part of complex eigenvalue + real(wp), dimension(nm) :: eigvec !< real eigenvector + real(wp) :: eigvec_mag !< magnitude of real eigenvector + real(wp) :: omega_proj !< projection of vorticity on real eigenvector + real(wp) :: lci !< imaginary part of complex eigenvalue real(wp) :: alpha - integer :: j, k, l, r, i !< Generic loop iterators + integer :: j, k, l, r, i integer :: idx do l = -offset_z%beg, p + offset_z%end @@ -516,7 +517,7 @@ contains lci = li(mod(idx, 3) + 1) ! Compute Liutex magnitude - alpha = omega_proj**2._wp - 4._wp*lci**2._wp ! (2*alpha)^2 + alpha = omega_proj**2._wp - 4._wp*lci**2._wp if (alpha > 0._wp) then liutex_mag(j, k, l) = omega_proj - sqrt(alpha) else @@ -549,8 +550,8 @@ contains !> Maximum value of the gradient magnitude (gm) of the density field in entire computational domain and not just the local !! sub-domain. The first position in the variable contains the maximum value and the second contains the rank of the !! processor on which it occurred. - real(wp), dimension(2) :: gm_rho_max - integer :: i, j, k, l !< Generic loop iterators + real(wp), dimension(2) :: gm_rho_max !< Global (max gradient magnitude, rank) pair for density + integer :: i, j, k, l ! Computing Gradient Magnitude of Density diff --git a/src/post_process/m_global_parameters.fpp b/src/post_process/m_global_parameters.fpp index feb5ec5107..e8d961b416 100644 --- a/src/post_process/m_global_parameters.fpp +++ b/src/post_process/m_global_parameters.fpp @@ -11,8 +11,8 @@ module m_global_parameters use mpi !< Message passing interface (MPI) module #endif - use m_derived_types !< Definitions of the derived types - use m_helper_basic !< Functions to compare floating point numbers + use m_derived_types + use m_helper_basic use m_thermochem, only: num_species, species_names implicit none @@ -36,7 +36,7 @@ module m_global_parameters !> @name Max and min number of cells in a direction of each combination of x-,y-, and z- type(cell_num_bounds) :: cells_bounds - integer(kind=8) :: nGlobal ! Total number of cells in global domain + integer(kind=8) :: nGlobal !< Total number of cells in global domain !> @name Cylindrical coordinates (either axisymmetric or full 3D) !> @{ @@ -70,7 +70,7 @@ module m_global_parameters !> Number of cells in buffer region. For the variables which feature a buffer region, this region is used to store information !! outside the computational domain based on the boundary conditions. - integer :: buff_size + integer :: buff_size !< Number of ghost cells for boundary condition storage integer :: t_step_start !< First time-step directory integer :: t_step_stop !< Last time-step directory integer :: t_step_save !< Interval between consecutive time-step directory @@ -152,16 +152,16 @@ module m_global_parameters type(int_bounds_info) :: bc_x, bc_y, bc_z !> @} - integer :: shear_num !! Number of shear stress components + integer :: shear_num !< Number of shear stress components integer, dimension(3) :: shear_indices !< Indices of the stress components that represent shear stress integer :: shear_BC_flip_num !< Number of shear stress components to reflect for boundary conditions !> Indices of shear stress components to reflect for boundary conditions. Size: (1:3, 1:shear_BC_flip_num) for (x/y/z, !! [indices]) - integer, dimension(3, 2) :: shear_BC_flip_indices - logical :: parallel_io !< Format of the data files + integer, dimension(3, 2) :: shear_BC_flip_indices !< Shear stress BC reflection indices (1:3, 1:shear_BC_flip_num) + logical :: parallel_io !< Format of the data files logical :: sim_data logical :: file_per_process !< output format - integer, allocatable, dimension(:) :: proc_coords !< Processor coordinates in MPI_CART_COMM + integer, allocatable, dimension(:) :: proc_coords !< Processor coordinates in MPI_CART_COMM type(int_bounds_info), dimension(3) :: nidx integer, allocatable, dimension(:,:,:) :: neighbor_ranks !! Neighbor processor ranks @@ -185,7 +185,7 @@ module m_global_parameters !> Database of the physical parameters of each of the fluids that is present in the flow. These include the stiffened gas !! equation of state parameters, and the Reynolds numbers. - type(physical_parameters), dimension(num_fluids_max) :: fluid_pp + type(physical_parameters), dimension(num_fluids_max) :: fluid_pp !< Stiffened gas EOS parameters and Reynolds numbers per fluid ! Subgrid Bubble Parameters type(subgrid_bubble_physical_parameters) :: bub_pp @@ -223,7 +223,7 @@ module m_global_parameters logical :: fft_wrt !> AMDFlang workaround: keep a dummy logical to avoid a compiler case-optimization bug when a parameter+GPU-kernel conditional !! is false - logical :: dummy + logical :: dummy !< AMDFlang workaround for case-optimization + GPU-kernel bug logical :: pres_wrt logical, dimension(num_fluids_max) :: alpha_wrt logical :: gamma_wrt @@ -265,15 +265,15 @@ module m_global_parameters !> Amplitude coefficients of the numerical Schlieren function that are used to adjust the intensity of numerical Schlieren !! renderings for individual fluids. This enables waves and interfaces of varying strengths and in all of the fluids to be made !! simultaneously visible on a single plot. - real(wp), dimension(num_fluids_max) :: schlieren_alpha + real(wp), dimension(num_fluids_max) :: schlieren_alpha !< Per-fluid Schlieren intensity amplitude coefficients !> The order of the finite-difference (fd) approximations of the first-order derivatives that need to be evaluated when !! vorticity and/or the numerical Schlieren function are to be outputted to the formatted database file(s). - integer :: fd_order + integer :: fd_order !< Finite-difference order for vorticity and Schlieren derivatives !> The finite-difference number is given by MAX(1, fd_order/2). Essentially, it is a measure of the half-size of the !! finite-difference stencil for the selected order of accuracy. - integer :: fd_number + integer :: fd_number !< Finite-difference half-stencil size: MAX(1, fd_order/2) !> @name Reference parameters for Tait EOS !> @{ diff --git a/src/post_process/m_mpi_proxy.fpp b/src/post_process/m_mpi_proxy.fpp index 84d1861f7d..9d18bb18c8 100644 --- a/src/post_process/m_mpi_proxy.fpp +++ b/src/post_process/m_mpi_proxy.fpp @@ -9,8 +9,8 @@ module m_mpi_proxy use mpi !< Message passing interface (MPI) module #endif - use m_derived_types !< Definitions of the derived types - use m_global_parameters !< Global parameters for the code + use m_derived_types + use m_global_parameters use m_mpi_common use ieee_arithmetic diff --git a/src/post_process/m_start_up.fpp b/src/post_process/m_start_up.fpp index 7563310c4a..a3868a75d9 100644 --- a/src/post_process/m_start_up.fpp +++ b/src/post_process/m_start_up.fpp @@ -12,15 +12,15 @@ module m_start_up use, intrinsic :: iso_c_binding - use m_derived_types !< Definitions of the derived types - use m_global_parameters !< Global parameters for the code - use m_mpi_proxy !< Message passing interface (MPI) module proxy - use m_mpi_common !< Common MPI subroutines - use m_boundary_common !< Common boundary conditions subroutines - use m_variables_conversion !< Subroutines to change the state variables from one form to another - use m_data_input !< Procedures reading raw simulation data to fill the conservative, primitive and grid variables - use m_data_output !< Procedures that write the grid and chosen flow variable(s) to the formatted database file(s) - use m_derived_variables !< Procedures used to compute quantities derived from the conservative and primitive variables + use m_derived_types + use m_global_parameters + use m_mpi_proxy + use m_mpi_common + use m_boundary_common + use m_variables_conversion + use m_data_input + use m_data_output + use m_derived_variables use m_helper use m_compile_specific use m_checker_common @@ -30,7 +30,7 @@ module m_start_up use m_chemistry #ifdef MFC_MPI - use mpi !< Message passing interface (MPI) module + use mpi #endif implicit none @@ -56,7 +56,7 @@ contains !! user provided inputs impure subroutine s_read_input_file - character(LEN=name_len) :: file_loc !< Generic string used to store the address of a particular file + character(LEN=name_len) :: file_loc !> Generic logical used for the purpose of asserting whether a file is or is not present in the designated location logical :: file_check @@ -128,8 +128,8 @@ contains !! the combination of these choices results into a valid configuration for the post-process impure subroutine s_check_input_file - character(LEN=len_trim(case_dir)) :: file_loc !< Generic string used to store the address of a particular file - logical :: dir_check !< Logical variable used to test the existence of folders + character(LEN=len_trim(case_dir)) :: file_loc + logical :: dir_check ! Checking the existence of the case folder diff --git a/src/post_process/p_main.fpp b/src/post_process/p_main.fpp index 76a5017883..166b449463 100644 --- a/src/post_process/p_main.fpp +++ b/src/post_process/p_main.fpp @@ -8,7 +8,7 @@ !! fraction, specific heat ratio, liquid stiffness, speed of sound, vorticity and the numerical Schlieren function. program p_main - use m_global_parameters !< Global parameters for the code + use m_global_parameters use m_start_up implicit none diff --git a/src/pre_process/m_assign_variables.fpp b/src/pre_process/m_assign_variables.fpp index 5c6786139f..b91a9045f8 100644 --- a/src/pre_process/m_assign_variables.fpp +++ b/src/pre_process/m_assign_variables.fpp @@ -8,10 +8,10 @@ !> @brief Assigns initial primitive variables to computational cells based on patch geometry module m_assign_variables - use m_derived_types ! Definitions of the derived types - use m_global_parameters ! Global parameters for the code - use m_variables_conversion ! Subroutines to change the state variables from - use m_helper_basic !< Functions to compare floating point numbers + use m_derived_types + use m_global_parameters + use m_variables_conversion + use m_helper_basic use m_thermochem, only: num_species, gas_constant, get_mixture_molecular_weight implicit none @@ -106,7 +106,7 @@ contains real(wp) :: Ys(1:num_species) integer :: smooth_patch_id - integer :: i !< generic loop operator + integer :: i ! Assigning the mixture primitive variables of a uniform state patch @@ -277,7 +277,7 @@ contains real(wp), dimension(3) :: xi_cart real(wp) :: Ys(1:num_species) real(stp), dimension(sys_size) :: orig_prim_vf !< Vector to hold original values of cell for smoothing purposes - integer :: i !< Generic loop iterator + integer :: i integer :: smooth_patch_id ! Transferring the identity of the smoothing patch diff --git a/src/pre_process/m_check_ib_patches.fpp b/src/pre_process/m_check_ib_patches.fpp index 5c96c56722..1c82bcd5bc 100644 --- a/src/pre_process/m_check_ib_patches.fpp +++ b/src/pre_process/m_check_ib_patches.fpp @@ -8,17 +8,17 @@ module m_check_ib_patches - use m_derived_types !< Definitions of the derived types - use m_global_parameters !< Global parameters - use m_mpi_proxy !< Message passing interface (MPI) module proxy - use m_data_output !< Procedures to write the grid data and the conservative variables to files + use m_derived_types + use m_global_parameters + use m_mpi_proxy + use m_data_output #ifdef MFC_MPI use mpi !< Message passing interface (MPI) module #endif use m_compile_specific - use m_helper_basic !< Functions to compare floating point numbers + use m_helper_basic use m_helper implicit none diff --git a/src/pre_process/m_check_patches.fpp b/src/pre_process/m_check_patches.fpp index 170c52ea90..50be404eb9 100644 --- a/src/pre_process/m_check_patches.fpp +++ b/src/pre_process/m_check_patches.fpp @@ -11,17 +11,17 @@ module m_check_patches ! Dependencies - use m_derived_types !< Definitions of the derived types - use m_global_parameters !< Global parameters for the code - use m_mpi_proxy !< Message passing interface (MPI) module proxy - use m_data_output !< Procedures to write the grid data and the conservative variables to files + use m_derived_types + use m_global_parameters + use m_mpi_proxy + use m_data_output #ifdef MFC_MPI use mpi !< Message passing interface (MPI) module #endif use m_compile_specific - use m_helper_basic !< Functions to compare floating point numbers + use m_helper_basic use m_helper implicit none diff --git a/src/pre_process/m_checker.fpp b/src/pre_process/m_checker.fpp index 5585ca0a7a..bd6ca48ee0 100644 --- a/src/pre_process/m_checker.fpp +++ b/src/pre_process/m_checker.fpp @@ -7,9 +7,9 @@ !> @brief Checks pre-process input file parameters for compatibility and correctness module m_checker - use m_global_parameters !< Definitions of the global parameters - use m_mpi_proxy !< Message passing interface (MPI) module proxy - use m_helper_basic !< Functions to compare floating point numbers + use m_global_parameters + use m_mpi_proxy + use m_helper_basic use m_helper implicit none diff --git a/src/pre_process/m_data_output.fpp b/src/pre_process/m_data_output.fpp index 0d1b9d76b5..e5123b7ee7 100644 --- a/src/pre_process/m_data_output.fpp +++ b/src/pre_process/m_data_output.fpp @@ -5,13 +5,13 @@ !> @brief Writes grid and initial condition data to serial or parallel output files module m_data_output - use m_derived_types !< Definitions of the derived types - use m_global_parameters !< Global parameters for the code + use m_derived_types + use m_global_parameters use m_helper - use m_mpi_proxy !< Message passing interface (MPI) module proxy + use m_mpi_proxy #ifdef MFC_MPI - use mpi !< Message passing interface (MPI) module + use mpi #endif use m_compile_specific @@ -64,22 +64,22 @@ contains ! BC types type(integer_field), dimension(1:num_dims,-1:1), intent(in) :: bc_type - logical :: file_exist !< checks if file exists + logical :: file_exist character(LEN=15) :: FMT character(LEN=3) :: status !> Used to store the number, in character form, of the currently manipulated conservative variable data file character(LEN=int(floor(log10(real(sys_size, wp)))) + 1) :: file_num - character(LEN=len_trim(t_step_dir) + name_len) :: file_loc !< Generic string used to store the address of a particular file - integer :: i, j, k, l, r, c !< Generic loop iterator - integer :: t_step - real(wp), dimension(nb) :: nRtmp !< Temporary bubble concentration - real(wp) :: nbub !< Temporary bubble number density - real(wp) :: gamma, lit_gamma, pi_inf, qv !< Temporary EOS params - real(wp) :: rho !< Temporary density - real(wp) :: pres, T !< Temporary pressure - real(wp) :: rhoYks(1:num_species) !< Temporary species mass fractions - real(wp) :: pres_mag + character(LEN=len_trim(t_step_dir) + name_len) :: file_loc + integer :: i, j, k, l, r, c + integer :: t_step + real(wp), dimension(nb) :: nRtmp + real(wp) :: nbub + real(wp) :: gamma, lit_gamma, pi_inf, qv + real(wp) :: rho + real(wp) :: pres, T + real(wp) :: rhoYks(1:num_species) + real(wp) :: pres_mag pres_mag = 0._wp @@ -429,7 +429,7 @@ contains ! Downsample variables integer :: m_ds, n_ds, p_ds integer :: m_glb_ds, n_glb_ds, p_glb_ds - integer :: m_glb_save, n_glb_save, p_glb_save ! Size of array being saved + integer :: m_glb_save, n_glb_save, p_glb_save !< Size of array being saved loc_violations = 0._wp @@ -505,7 +505,7 @@ contains ! Write the data for each variable if (bubbles_euler) then - do i = 1, sys_size ! adv_idx%end + do i = 1, sys_size var_MOK = int(i, MPI_OFFSET_KIND) call MPI_FILE_WRITE_ALL(ifile, MPI_IO_DATA%var(i)%sf, data_size*mpi_io_type, mpi_io_p, status, ierr) @@ -565,7 +565,7 @@ contains ! Write the data for each variable if (bubbles_euler) then - do i = 1, sys_size ! adv_idx%end + do i = 1, sys_size var_MOK = int(i, MPI_OFFSET_KIND) ! Initial displacement to skip at beginning of file @@ -587,7 +587,7 @@ contains end do end if else - do i = 1, sys_size ! TODO: check if this is right + do i = 1, sys_size ! do i = 1, adv_idx%end var_MOK = int(i, MPI_OFFSET_KIND) @@ -624,7 +624,7 @@ contains ! Generic logical used to check the existence of directories logical :: dir_check integer :: i - integer :: m_ds, n_ds, p_ds !< down sample dimensions + integer :: m_ds, n_ds, p_ds if (parallel_io .neqv. .true.) then ! Setting the address of the time-step directory diff --git a/src/pre_process/m_global_parameters.fpp b/src/pre_process/m_global_parameters.fpp index e934edded8..118add7996 100644 --- a/src/pre_process/m_global_parameters.fpp +++ b/src/pre_process/m_global_parameters.fpp @@ -127,26 +127,26 @@ module m_global_parameters !> @} type(int_bounds_info) :: bc_x, bc_y, bc_z !< Boundary conditions in the x-, y- and z-coordinate directions - integer :: shear_num !! Number of shear stress components + integer :: shear_num !< Number of shear stress components integer, dimension(3) :: shear_indices !< Indices of the stress components that represent shear stress integer :: shear_BC_flip_num !< Number of shear stress components to reflect for boundary conditions !> Indices of shear stress components to reflect for boundary conditions. Size: (1:3, 1:shear_BC_flip_num) for (x/y/z, !! [indices]) - integer, dimension(3, 2) :: shear_BC_flip_indices - logical :: parallel_io !< Format of the data files - logical :: file_per_process !< type of data output - integer :: precision !< Precision of output files - logical :: down_sample !< Down-sample the output data - logical :: mixlayer_vel_profile !< Set hyperbolic tangent streamwise velocity profile - real(wp) :: mixlayer_vel_coef !< Coefficient for the hyperbolic tangent streamwise velocity profile - logical :: mixlayer_perturb !< Superimpose instability waves to surrounding fluid flow - integer :: mixlayer_perturb_nk !< Number of Fourier modes for perturbation with mixlayer_perturb flag + integer, dimension(3, 2) :: shear_BC_flip_indices !< Shear stress BC reflection indices (1:3, 1:shear_BC_flip_num) + logical :: parallel_io !< Format of the data files + logical :: file_per_process !< type of data output + integer :: precision !< Precision of output files + logical :: down_sample !< Down-sample the output data + logical :: mixlayer_vel_profile !< Set hyperbolic tangent streamwise velocity profile + real(wp) :: mixlayer_vel_coef !< Coefficient for the hyperbolic tangent streamwise velocity profile + logical :: mixlayer_perturb !< Superimpose instability waves to surrounding fluid flow + integer :: mixlayer_perturb_nk !< Number of Fourier modes for perturbation with mixlayer_perturb flag !> Peak wavenumber of prescribed energy spectra with mixlayer_perturb flag Default value (k0 = 0.4446) is most unstable mode !! obtained from linear stability analysis See Michalke (1964, JFM) for details - real(wp) :: mixlayer_perturb_k0 + real(wp) :: mixlayer_perturb_k0 !< Peak wavenumber for mixlayer perturbation (default: most unstable mode) logical :: simplex_perturb type(simplex_noise_params) :: simplex_params - real(wp) :: pi_fac !< Factor for artificial pi_inf + real(wp) :: pi_fac !< Factor for artificial pi_inf logical :: viscous logical :: bubbles_lagrange @@ -178,17 +178,17 @@ module m_global_parameters !> Database of the initial condition patch parameters (icpp) for each of the patches employed in the configuration of the !! initial condition. Note that the maximum allowable number of patches, num_patches_max, may be changed in the module !! m_derived_types.f90. - type(ic_patch_parameters), dimension(num_patches_max) :: patch_icpp - integer :: num_bc_patches !< Number of boundary condition patches - logical :: bc_io !< whether or not to save BC data + type(ic_patch_parameters), dimension(num_patches_max) :: patch_icpp !< IC patch parameters (max: num_patches_max) + integer :: num_bc_patches !< Number of boundary condition patches + logical :: bc_io !< whether or not to save BC data + !> Boundary condition patch parameters Database of the boundary condition patch parameters for each of the patches employed in + !! the configuration of the boundary conditions type(bc_patch_parameters), dimension(num_bc_patches_max) :: patch_bc - !! Database of the boundary condition patch parameters for each of the patches employed in the configuration of the boundary - !! conditions ! Fluids Physical Parameters !> Database of the physical parameters of each of the fluids that is present in the flow. These include the stiffened gas !! equation of state parameters, and the Reynolds numbers. - type(physical_parameters), dimension(num_fluids_max) :: fluid_pp + type(physical_parameters), dimension(num_fluids_max) :: fluid_pp !< Stiffened gas EOS parameters and Reynolds numbers per fluid ! Subgrid Bubble Parameters type(subgrid_bubble_physical_parameters) :: bub_pp @@ -208,10 +208,10 @@ module m_global_parameters !> @name Immersed Boundaries !> @{ - logical :: ib !< Turn immersed boundaries on - integer :: num_ibs !< Number of immersed boundaries + logical :: ib !< Turn immersed boundaries on + integer :: num_ibs !< Number of immersed boundaries integer :: Np - type(ib_patch_parameters), dimension(num_patches_max) :: patch_ib + type(ib_patch_parameters), dimension(num_patches_max) :: patch_ib !< Immersed boundary patch parameters type(vec3_dt), allocatable, dimension(:) :: airfoil_grid_u, airfoil_grid_l !! Database of the immersed boundary patch parameters for each of the patches employed in the configuration of the initial !! condition. Note that the maximum allowable number of patches, num_patches_max, may be changed in the module @@ -223,8 +223,8 @@ module m_global_parameters logical :: polytropic logical :: polydisperse real(wp) :: poly_sigma - integer :: dist_type ! 1 = binormal, 2 = lognormal-normal - integer :: thermal ! 1 = adiabatic, 2 = isotherm, 3 = transfer + integer :: dist_type !< 1 = binormal, 2 = lognormal-normal + integer :: thermal !< 1 = adiabatic, 2 = isotherm, 3 = transfer real(wp) :: phi_vg, phi_gv, Pe_c, Tw, k_vl, k_gl real(wp) :: gam_m real(wp), dimension(:), allocatable :: pb0, mass_g0, mass_v0, Pe_T, k_v, k_g @@ -257,11 +257,11 @@ module m_global_parameters !> The number of cells that are necessary to be able to store enough boundary conditions data to march the solution in the !! physical computational domain to the next time-step. - integer :: buff_size + integer :: buff_size !< Number of ghost cells for boundary condition storage logical :: fft_wrt !> AMDFlang workaround: keep a dummy logical to avoid a compiler case-optimization bug when a parameter+GPU-kernel conditional !! is false - logical :: dummy + logical :: dummy !< AMDFlang workaround for case-optimization + GPU-kernel bug ! Variables for hardcoded initial conditions that are read from input files character(LEN=2*path_len) :: interface_file @@ -681,7 +681,7 @@ contains bub_idx%beg = sys_size + 1 if (qbmm) then if (nnode == 4) then - nmom = 6 !! Already set as a parameter + nmom = 6 !< Already set as a parameter end if bub_idx%end = adv_idx%end + nb*nmom else diff --git a/src/pre_process/m_grid.f90 b/src/pre_process/m_grid.f90 index 47968251bf..34a6a59dc8 100644 --- a/src/pre_process/m_grid.f90 +++ b/src/pre_process/m_grid.f90 @@ -8,7 +8,7 @@ module m_grid use m_derived_types ! Definitions of the derived types use m_global_parameters ! Global parameters for the code use m_mpi_proxy ! Message passing interface (MPI) module proxy - use m_helper_basic !< Functions to compare floating point numbers + use m_helper_basic #ifdef MFC_MPI use mpi ! Message passing interface (MPI) module diff --git a/src/pre_process/m_icpp_patches.fpp b/src/pre_process/m_icpp_patches.fpp index 2c40594f11..e3a586b875 100644 --- a/src/pre_process/m_icpp_patches.fpp +++ b/src/pre_process/m_icpp_patches.fpp @@ -14,9 +14,9 @@ module m_icpp_patches use m_model ! Subroutine(s) related to STL files use m_derived_types ! Definitions of the derived types - use m_global_parameters !< Definitions of the global parameters + use m_global_parameters use m_constants, only: max_2d_fourier_modes, max_sph_harm_degree, small_radius - use m_helper_basic !< Functions to compare floating point numbers + use m_helper_basic use m_helper use m_mpi_common use m_assign_variables @@ -33,21 +33,21 @@ module m_icpp_patches !> These variables are analogous in both meaning and use to the similarly named components in the ic_patch_parameters type (see !! m_derived_types.f90 for additional details). They are employed as a means to more concisely perform the actions necessary to !! lay out a particular patch on the grid. - real(wp) :: smooth_coeff + real(wp) :: smooth_coeff !< Smoothing coefficient (mirrors ic_patch_parameters%smooth_coeff) !> In the case that smoothing of patch boundaries is enabled and the boundary between two adjacent patches is to be smeared out, !! this variable's purpose is to act as a pseudo volume fraction to indicate the contribution of each patch toward the !! composition of a cell's fluid state. - real(wp) :: eta + real(wp) :: eta !< Pseudo volume fraction for patch boundary smoothing real(wp) :: cart_x, cart_y, cart_z !> Variables to be used to hold cell locations in Cartesian coordinates if 3D simulation is using cylindrical coordinates - real(wp) :: sph_phi + real(wp) :: sph_phi !< Spherical phi for Cartesian conversion in cylindrical coordinates !> These variables combine the centroid and length parameters associated with a particular patch to yield the locations of the !! patch boundaries in the x-, y- and z-coordinate directions. They are used as a means to concisely perform the actions !! necessary to lay out a particular patch on the grid. type(bounds_info) :: x_boundary, y_boundary, z_boundary - character(len=5) :: istr ! string to store int to string result for error checking + character(len=5) :: istr !< string to store int to string result for error checking contains diff --git a/src/pre_process/m_initial_condition.fpp b/src/pre_process/m_initial_condition.fpp index f591798fe2..6692d613d7 100644 --- a/src/pre_process/m_initial_condition.fpp +++ b/src/pre_process/m_initial_condition.fpp @@ -5,16 +5,16 @@ !> @brief Assembles initial conditions by layering prioritized patches via constructive solid geometry module m_initial_condition - use m_derived_types ! Definitions of the derived types - use m_global_parameters ! Global parameters for the code - use m_mpi_proxy !< Message passing interface (MPI) module proxy + use m_derived_types + use m_global_parameters + use m_mpi_proxy use m_helper - use m_variables_conversion ! Subroutines to change the state variables from + use m_variables_conversion ! one form to another use m_icpp_patches use m_assign_variables - use m_perturbation ! Subroutines to perturb initial flow fields + use m_perturbation use m_chemistry use m_boundary_conditions @@ -43,7 +43,7 @@ contains !> Computation of parameters, allocation procedures, and/or any other tasks needed to properly setup the module impure subroutine s_initialize_initial_condition_module - integer :: i, j, k, l !< generic loop iterators + integer :: i, j, k, l ! Allocating the primitive and conservative variables @@ -172,7 +172,7 @@ contains !> Deallocation procedures for the module impure subroutine s_finalize_initial_condition_module - integer :: i !< Generic loop iterator + integer :: i ! Dellocating the primitive and conservative variables diff --git a/src/pre_process/m_mpi_proxy.fpp b/src/pre_process/m_mpi_proxy.fpp index 1fe5d54b6d..6bf646f858 100644 --- a/src/pre_process/m_mpi_proxy.fpp +++ b/src/pre_process/m_mpi_proxy.fpp @@ -6,12 +6,12 @@ module m_mpi_proxy #ifdef MFC_MPI - use mpi !< Message passing interface (MPI) module + use mpi #endif use m_helper - use m_derived_types !< Definitions of the derived types - use m_global_parameters !< Global parameters for the code + use m_derived_types + use m_global_parameters use m_mpi_common implicit none diff --git a/src/pre_process/m_perturbation.fpp b/src/pre_process/m_perturbation.fpp index ffc5633b82..9f98ddba4c 100644 --- a/src/pre_process/m_perturbation.fpp +++ b/src/pre_process/m_perturbation.fpp @@ -5,10 +5,10 @@ !> @brief Perturbs initial mean flow fields with random noise, mixing-layer instabilities, or simplex noise module m_perturbation - use m_derived_types ! Definitions of the derived types - use m_global_parameters ! Global parameters for the code - use m_mpi_proxy !< Message passing interface (MPI) module proxy - use m_boundary_common ! Boundary conditions module + use m_derived_types + use m_global_parameters + use m_mpi_proxy + use m_boundary_common use m_helper use m_simplex_noise use ieee_arithmetic @@ -32,7 +32,7 @@ contains impure subroutine s_perturb_sphere(q_prim_vf) type(scalar_field), dimension(sys_size), intent(inout) :: q_prim_vf - integer :: i, j, k, l !< generic loop operators + integer :: i, j, k, l real(wp) :: perturb_alpha real(wp) :: rand_real @@ -63,7 +63,7 @@ contains impure subroutine s_perturb_surrounding_flow(q_prim_vf) type(scalar_field), dimension(sys_size), intent(inout) :: q_prim_vf - integer :: i, j, k !< generic loop iterators + integer :: i, j, k real(wp) :: perturb_alpha real(wp) :: rand_real diff --git a/src/pre_process/m_start_up.fpp b/src/pre_process/m_start_up.fpp index 11187bd780..ae9829f2c2 100644 --- a/src/pre_process/m_start_up.fpp +++ b/src/pre_process/m_start_up.fpp @@ -7,23 +7,23 @@ !> @brief Reads and validates user inputs, loads existing grid/IC data, and initializes pre-process modules module m_start_up - use m_derived_types !< Definitions of the derived types - use m_global_parameters !< Global parameters for the code - use m_mpi_proxy !< Message passing interface (MPI) module proxy + use m_derived_types + use m_global_parameters + use m_mpi_proxy use m_mpi_common - use m_variables_conversion !< Subroutines to change the state variables from one form to another - use m_grid !< Procedures to generate (non-)uniform grids - use m_initial_condition !< Procedures to generate initial condition - use m_data_output !< Procedures to write the grid data and the conservative variables to files - use m_compile_specific !< Compile-specific procedures + use m_variables_conversion + use m_grid + use m_initial_condition + use m_data_output + use m_compile_specific use m_icpp_patches use m_assign_variables - use m_phase_change !< Phase-change module - use m_helper_basic !< Functions to compare floating point numbers + use m_phase_change + use m_helper_basic use m_helper #ifdef MFC_MPI - use mpi !< Message passing interface (MPI) module + use mpi #endif use m_check_patches @@ -63,7 +63,7 @@ module m_start_up !> Possible location of time-step folder containing preexisting grid and/or conservative variables data to be used as starting !! point for pre-process - character(LEN=path_len + 2*name_len), private :: t_step_dir + character(LEN=path_len + 2*name_len), private :: t_step_dir !< Path to preexisting time-step folder for restart procedure(s_read_abstract_grid_data_files), pointer :: s_read_grid_data_files => null() procedure(s_read_abstract_ic_data_files), pointer :: s_read_ic_data_files => null() @@ -74,7 +74,7 @@ contains !! user provided inputs impure subroutine s_read_input_file - character(LEN=name_len) :: file_loc !< Generic string used to store the address of a particular file + character(LEN=name_len) :: file_loc !> Generic logical used for the purpose of asserting whether a file is or is not present in the designated location logical :: file_check @@ -138,8 +138,8 @@ contains !! the combination of these choices results into a valid configuration for the pre-process impure subroutine s_check_input_file - character(LEN=len_trim(case_dir)) :: file_loc !< Generic string used to store the address of a particular file - logical :: dir_check !< Logical variable used to test the existence of folders + character(LEN=len_trim(case_dir)) :: file_loc + logical :: dir_check ! Checking the existence of the case folder @@ -329,7 +329,7 @@ contains !> Generic logical used for the purpose of asserting whether a file is or is not present in the designated location logical :: file_check - integer :: i, r !< Generic loop iterator + integer :: i, r ! Reading the Conservative Variables Data Files diff --git a/src/pre_process/p_main.f90 b/src/pre_process/p_main.f90 index fb663412f0..c61b120f09 100644 --- a/src/pre_process/p_main.f90 +++ b/src/pre_process/p_main.f90 @@ -5,7 +5,7 @@ !> @brief This program takes care of setting up the initial condition and grid data for the multicomponent flow code. program p_main - use m_global_parameters !< Global parameters for the code + use m_global_parameters use m_start_up implicit none diff --git a/src/simulation/m_acoustic_src.fpp b/src/simulation/m_acoustic_src.fpp index 1f30873f20..18bda58790 100644 --- a/src/simulation/m_acoustic_src.fpp +++ b/src/simulation/m_acoustic_src.fpp @@ -7,12 +7,12 @@ !> @brief Applies acoustic pressure source terms including focused, planar, and broadband transducers module m_acoustic_src - use m_derived_types !< Definitions of the derived types - use m_global_parameters !< Definitions of the global parameters - use m_bubbles !< Bubble dynamic routines - use m_variables_conversion !< State variables type conversion procedures - use m_helper_basic !< Functions to compare floating point numbers - use m_constants !< Definitions of the constants + use m_derived_types + use m_global_parameters + use m_bubbles + use m_variables_conversion + use m_helper_basic + use m_constants implicit none @@ -349,9 +349,9 @@ contains real(wp), intent(in) :: sim_time, c, sum_BB real(wp), intent(in) :: frequency_local, gauss_sigma_time_local real(wp), intent(out) :: source - real(wp) :: omega ! angular frequency - real(wp) :: sine_wave ! sine function for square wave - real(wp) :: foc_length_factor ! Scale amplitude with radius for spherical support + real(wp) :: omega !< angular frequency + real(wp) :: sine_wave !< sine function for square wave + real(wp) :: foc_length_factor !< Scale amplitude with radius for spherical support ! i.e. Spherical support -> 1/r scaling; Cylindrical support -> 1/sqrt(r) [empirical correction: ^-0.5 -> ^-0.85] integer, parameter :: mass_label = 1 diff --git a/src/simulation/m_body_forces.fpp b/src/simulation/m_body_forces.fpp index 5d13919865..cc9a62bcb2 100644 --- a/src/simulation/m_body_forces.fpp +++ b/src/simulation/m_body_forces.fpp @@ -7,8 +7,8 @@ !> @brief Computes gravitational and user-defined body force source terms for the momentum equations module m_body_forces - use m_derived_types !< Definitions of the derived types - use m_global_parameters !< Definitions of the global parameters + use m_derived_types + use m_global_parameters use m_variables_conversion use m_nvtx diff --git a/src/simulation/m_bubbles.fpp b/src/simulation/m_bubbles.fpp index 52ae804140..ef065cb6be 100644 --- a/src/simulation/m_bubbles.fpp +++ b/src/simulation/m_bubbles.fpp @@ -8,11 +8,11 @@ !! models module m_bubbles - use m_derived_types !< Definitions of the derived types - use m_global_parameters !< Definitions of the global parameters - use m_mpi_proxy !< Message passing interface (MPI) module proxy - use m_variables_conversion !< State variables type conversion procedures - use m_helper_basic !< Functions to compare floating point numbers + use m_derived_types + use m_global_parameters + use m_mpi_proxy + use m_variables_conversion + use m_helper_basic use m_bubbles_EL_kernels implicit none diff --git a/src/simulation/m_bubbles_EE.fpp b/src/simulation/m_bubbles_EE.fpp index 24929202db..42cacbf882 100644 --- a/src/simulation/m_bubbles_EE.fpp +++ b/src/simulation/m_bubbles_EE.fpp @@ -7,11 +7,11 @@ !> @brief Computes ensemble-averaged (Euler--Euler) bubble source terms for radius, velocity, pressure, and mass transfer module m_bubbles_EE - use m_derived_types !< Definitions of the derived types - use m_global_parameters !< Definitions of the global parameters - use m_mpi_proxy !< Message passing interface (MPI) module proxy - use m_variables_conversion !< State variables type conversion procedures - use m_bubbles !< General bubble dynamics procedures + use m_derived_types + use m_global_parameters + use m_mpi_proxy + use m_variables_conversion + use m_bubbles implicit none diff --git a/src/simulation/m_bubbles_EL.fpp b/src/simulation/m_bubbles_EL.fpp index 1e89a7b7af..3be530186b 100644 --- a/src/simulation/m_bubbles_EL.fpp +++ b/src/simulation/m_bubbles_EL.fpp @@ -7,14 +7,14 @@ !> @brief Tracks Lagrangian bubbles and couples their dynamics to the Eulerian flow via volume averaging module m_bubbles_EL - use m_global_parameters !< Definitions of the global parameters - use m_mpi_proxy !< Message passing interface (MPI) module proxy - use m_bubbles_EL_kernels !< Definitions of the kernel functions - use m_bubbles !< General bubble dynamics procedures - use m_variables_conversion !< State variables type conversion procedures + use m_global_parameters + use m_mpi_proxy + use m_bubbles_EL_kernels + use m_bubbles + use m_variables_conversion use m_compile_specific use m_boundary_common - use m_helper_basic !< Functions to compare floating point numbers + use m_helper_basic use m_sim_helpers use m_helper use m_mpi_common @@ -61,7 +61,7 @@ module m_bubbles_EL $:GPU_DECLARE(create='[lag_num_ts]') - real(wp) :: Rmax_glb, Rmin_glb !< Maximum and minimum bubble size in the local domain + real(wp) :: Rmax_glb, Rmin_glb !< Maximum and minimum bubbe size in the local domain !> Projection of the lagrangian particles in the Eulerian framework type(scalar_field), dimension(:), allocatable :: q_beta type(scalar_field), dimension(:), allocatable :: kahan_comp !< Kahan compensation for q_beta accumulation @@ -828,7 +828,7 @@ contains end do $:END_GPU_PARALLEL_LOOP() end do - call nvtxEndRange ! LAGRANGE-BUBBLE-EL-SOURCE + call nvtxEndRange end subroutine s_compute_bubbles_EL_source @@ -1002,7 +1002,7 @@ contains ! Z-direction basis functions psi_z(1) = 1._wp - psi_pos(3) ! Left basis function psi_z(2) = psi_pos(3) ! Right basis function - else + else ! 3D psi_z(1) = 1._wp psi_z(2) = 0._wp end if @@ -1010,13 +1010,13 @@ contains !> Perform bilinear interpolation f_pinfl = 0._wp - if (p == 0) then ! 2D - 4 point interpolation (2x2) + if (p == 0) then do j = 1, 2 do i = 1, 2 f_pinfl = f_pinfl + q_prim_vf(E_idx)%sf(cell(1) + i - 1, cell(2) + j - 1, cell(3))*psi_x(i)*psi_y(j) end do end do - else ! 3D - 8 point interpolation (2x2x2) + else do k = 1, 2 do j = 1, 2 do i = 1, 2 @@ -1082,13 +1082,13 @@ contains !> Perform biquadratic interpolation f_pinfl = 0._wp - if (p == 0) then ! 2D - 9 point interpolation (3x3) + if (p == 0) then ! 2D do j = 1, 3 do i = 1, 3 f_pinfl = f_pinfl + q_prim_vf(E_idx)%sf(cell(1) + i - 2, cell(2) + j - 2, cell(3))*psi_x(i)*psi_y(j) end do end do - else ! 3D - 27 point interpolation (3x3x3) + else do k = 1, 3 do j = 1, 3 do i = 1, 3 diff --git a/src/simulation/m_bubbles_EL_kernels.fpp b/src/simulation/m_bubbles_EL_kernels.fpp index f0ff7b012f..908faf5d23 100644 --- a/src/simulation/m_bubbles_EL_kernels.fpp +++ b/src/simulation/m_bubbles_EL_kernels.fpp @@ -7,7 +7,7 @@ !> @brief Kernel functions (Gaussian, delta) that smear Lagrangian bubble effects onto the Eulerian grid module m_bubbles_EL_kernels - use m_mpi_proxy !< Message passing interface (MPI) module proxy + use m_mpi_proxy implicit none diff --git a/src/simulation/m_cbc.fpp b/src/simulation/m_cbc.fpp index f1b825a907..2da0141f33 100644 --- a/src/simulation/m_cbc.fpp +++ b/src/simulation/m_cbc.fpp @@ -8,9 +8,9 @@ module m_cbc - use m_derived_types !< Definitions of the derived types - use m_global_parameters !< Definitions of the global parameters - use m_variables_conversion !< State variables type conversion procedures + use m_derived_types + use m_global_parameters + use m_variables_conversion use m_compute_cbc use m_thermochem, only: get_mixture_energy_mass, get_mixture_specific_heat_cv_mass, get_mixture_specific_heat_cp_mass, & & gas_constant, get_mixture_molecular_weight, get_species_enthalpies_rt, molecular_weights, get_species_specific_heats_r, & @@ -57,7 +57,7 @@ module m_cbc real(wp), allocatable, dimension(:,:) :: fd_coef_y !< Finite diff. coefficients y-dir !> Finite diff. coefficients z-dir The first dimension identifies the location of a coefficient in the FD formula, while the !! last dimension denotes the location of the CBC. - real(wp), allocatable, dimension(:,:) :: fd_coef_z + real(wp), allocatable, dimension(:,:) :: fd_coef_z !< Finite diff. coefficients, z-direction ! Bug with NVHPC when using nullified pointers in a declare create real(wp), pointer, dimension(:, :) :: fd_coef => null() diff --git a/src/simulation/m_checker.fpp b/src/simulation/m_checker.fpp index 81e25563bb..c2ebdb076f 100644 --- a/src/simulation/m_checker.fpp +++ b/src/simulation/m_checker.fpp @@ -8,10 +8,10 @@ !> @brief Validates simulation input parameters for consistency and supported configurations module m_checker - use m_global_parameters !< Definitions of the global parameters - use m_mpi_proxy !< Message passing interface (MPI) module proxy + use m_global_parameters + use m_mpi_proxy use m_helper - use m_helper_basic !< Functions to compare floating point numbers + use m_helper_basic implicit none diff --git a/src/simulation/m_compute_levelset.fpp b/src/simulation/m_compute_levelset.fpp index e7f23db4dc..d97b3fea1c 100644 --- a/src/simulation/m_compute_levelset.fpp +++ b/src/simulation/m_compute_levelset.fpp @@ -7,12 +7,12 @@ !> @brief Computes signed-distance level-set fields and surface normals for immersed-boundary patch geometries module m_compute_levelset - use m_ib_patches !< The IB patch parameters - use m_model !< Subroutine(s) related to STL files - use m_derived_types !< Definitions of the derived types - use m_global_parameters !< Definitions of the global parameters - use m_mpi_proxy !< Message passing interface (MPI) module proxy - use m_helper_basic !< Functions to compare floating point numbers + use m_ib_patches + use m_model + use m_derived_types + use m_global_parameters + use m_mpi_proxy + use m_helper_basic implicit none @@ -362,8 +362,8 @@ contains $:GPU_ROUTINE(parallelism='[seq]') type(ghost_point), intent(inout) :: gp - real(wp) :: ellipse_coeffs(2) ! a and b in the ellipse equation - real(wp) :: quadratic_coeffs(3) ! A, B, C in the quadratic equation to compute levelset + real(wp) :: ellipse_coeffs(2) !< a and b in the ellipse equation + real(wp) :: quadratic_coeffs(3) !< A, B, C in the quadratic equation to compute levelset real(wp) :: length_x, length_y real(wp), dimension(1:3) :: xy_local, normal_vector !< x and y coordinates in local IB frame real(wp), dimension(2) :: center !< x and y coordinates in local IB frame diff --git a/src/simulation/m_data_output.fpp b/src/simulation/m_data_output.fpp index 0b03033c25..0104dbfddb 100644 --- a/src/simulation/m_data_output.fpp +++ b/src/simulation/m_data_output.fpp @@ -8,13 +8,13 @@ !> @brief Writes solution data, run-time stability diagnostics (ICFL, VCFL, CCFL, Rc), and probe/center-of-mass files module m_data_output - use m_derived_types !< Definitions of the derived types - use m_global_parameters !< Definitions of the global parameters - use m_mpi_proxy !< Message passing interface (MPI) module proxy - use m_variables_conversion !< State variables type conversion procedures + use m_derived_types + use m_global_parameters + use m_mpi_proxy + use m_variables_conversion use m_compile_specific use m_helper - use m_helper_basic !< Functions to compare floating point numbers + use m_helper_basic use m_sim_helpers use m_delay_file_access use m_ibm @@ -712,7 +712,7 @@ contains ! Down sampling variables integer :: m_ds, n_ds, p_ds integer :: m_glb_ds, n_glb_ds, p_glb_ds - integer :: m_glb_save, n_glb_save, p_glb_save ! Global save size + integer :: m_glb_save, n_glb_save, p_glb_save !< Global save size if (down_sample) then call s_downsample_data(q_cons_vf, q_cons_temp_ds, m_ds, n_ds, p_ds, m_glb_ds, n_glb_ds, p_glb_ds) @@ -801,13 +801,13 @@ contains end if else if (down_sample) then - do i = 1, sys_size ! TODO: check if correct (sys_size + do i = 1, sys_size ! TODO: check if sys_size is correct var_MOK = int(i, MPI_OFFSET_KIND) call MPI_FILE_WRITE_ALL(ifile, q_cons_temp_ds(i)%sf, data_size*mpi_io_type, mpi_io_p, status, ierr) end do else - do i = 1, sys_size ! TODO: check if correct (sys_size + do i = 1, sys_size ! TODO: check if sys_size is correct var_MOK = int(i, MPI_OFFSET_KIND) call MPI_FILE_WRITE_ALL(ifile, MPI_IO_DATA%var(i)%sf, data_size*mpi_io_type, mpi_io_p, status, ierr) @@ -871,7 +871,7 @@ contains end do end if else - do i = 1, sys_size ! TODO: check if correct (sys_size + do i = 1, sys_size ! TODO: check if sys_size is correct var_MOK = int(i, MPI_OFFSET_KIND) ! Initial displacement to skip at beginning of file @@ -1015,16 +1015,16 @@ contains end if if (proc_rank == 0) then - if (n == 0) then ! 1D simulation - do i = 1, num_fluids ! Loop through fluids + if (n == 0) then + do i = 1, num_fluids write (i + 120, '(6X,4F24.12)') nondim_time, c_mass_in(i, 1), c_mass_in(i, 2), c_mass_in(i, 5) end do - else if (p == 0) then ! 2D simulation - do i = 1, num_fluids ! Loop through fluids + else if (p == 0) then + do i = 1, num_fluids write (i + 120, '(6X,5F24.12)') nondim_time, c_mass_in(i, 1), c_mass_in(i, 2), c_mass_in(i, 3), c_mass_in(i, 5) end do - else ! 3D simulation - do i = 1, num_fluids ! Loop through fluids + else + do i = 1, num_fluids write (i + 120, '(6X,6F24.12)') nondim_time, c_mass_in(i, 1), c_mass_in(i, 2), c_mass_in(i, 3), c_mass_in(i, & & 4), c_mass_in(i, 5) end do @@ -1123,7 +1123,7 @@ contains damage_state = 0._wp ! Find probe location in terms of indices on a specific processor - if (n == 0) then ! 1D simulation + if (n == 0) then if ((probe(i)%x >= x_cb(-1)) .and. (probe(i)%x <= x_cb(m))) then do s = -1, m distx(s) = x_cb(s) - probe(i)%x @@ -1226,7 +1226,7 @@ contains accel = accel_mag(j - 2, k, l) end if - else if (p == 0) then ! 2D simulation + else if (p == 0) then if (chemistry) then do d = 1, num_species rhoYks(d) = q_cons_vf(chemxb + d - 1)%sf(j - 2, k - 2, l) @@ -1307,7 +1307,7 @@ contains & 0._wp, 0._wp, c, qv) end if end if - else ! 3D + else if ((probe(i)%x >= x_cb(-1)) .and. (probe(i)%x <= x_cb(m))) then if ((probe(i)%y >= y_cb(-1)) .and. (probe(i)%y <= y_cb(n))) then if ((probe(i)%z >= z_cb(-1)) .and. (probe(i)%z <= z_cb(p))) then @@ -1456,7 +1456,7 @@ contains end do if (integral_wrt .and. bubbles_euler) then - if (n == 0) then ! 1D simulation + if (n == 0) then do i = 1, num_integrals int_pres = 0._wp max_pres = 0._wp diff --git a/src/simulation/m_derived_variables.fpp b/src/simulation/m_derived_variables.fpp index a87c36465e..c608a596c5 100644 --- a/src/simulation/m_derived_variables.fpp +++ b/src/simulation/m_derived_variables.fpp @@ -8,10 +8,10 @@ module m_derived_variables - use m_derived_types !< Definitions of the derived types - use m_global_parameters !< Global parameters for the code - use m_mpi_proxy !< Message passing interface (MPI) module proxy - use m_data_output !< Data output module + use m_derived_types + use m_global_parameters + use m_mpi_proxy + use m_data_output use m_compile_specific use m_helper use m_finite_differences diff --git a/src/simulation/m_fftw.fpp b/src/simulation/m_fftw.fpp index b27b708621..cc884cb0f5 100644 --- a/src/simulation/m_fftw.fpp +++ b/src/simulation/m_fftw.fpp @@ -9,9 +9,9 @@ module m_fftw use, intrinsic :: iso_c_binding - use m_derived_types !< Definitions of the derived types - use m_global_parameters !< Definitions of the global parameters - use m_mpi_proxy !< Message passing interface (MPI) module proxy + use m_derived_types + use m_global_parameters + use m_mpi_proxy #if defined(MFC_GPU) && defined(__PGI) use cufft diff --git a/src/simulation/m_global_parameters.fpp b/src/simulation/m_global_parameters.fpp index 222d4aa97a..9951465a23 100644 --- a/src/simulation/m_global_parameters.fpp +++ b/src/simulation/m_global_parameters.fpp @@ -12,8 +12,8 @@ module m_global_parameters use mpi !< Message passing interface (MPI) module #endif - use m_derived_types !< Definitions of the derived types - use m_helper_basic !< Functions to compare floating point numbers + use m_derived_types + use m_helper_basic ! $:USE_GPU_MODULE() @@ -147,17 +147,17 @@ module m_global_parameters !> @name Variables for our of core IGR computation on NVIDIA !> @{ - logical :: nv_uvm_out_of_core ! Enable out-of-core storage of q_cons_ts(2) in timestepping (default FALSE) - integer :: nv_uvm_igr_temps_on_gpu ! 0 => jac, jac_rhs, and jac_old on CPU + logical :: nv_uvm_out_of_core !< Enable out-of-core storage of q_cons_ts(2) in timestepping (default FALSE) + integer :: nv_uvm_igr_temps_on_gpu !< 0 => jac, jac_rhs, and jac_old on CPU ! 1 => jac on GPU, jac_rhs and jac_old on CPU 2 => jac and jac_rhs on GPU, jac_old on CPU 3 => jac, jac_rhs, and jac_old on GPU ! (default) - logical :: nv_uvm_pref_gpu ! Enable explicit gpu memory hints (default FALSE) + logical :: nv_uvm_pref_gpu !< Enable explicit gpu memory hints (default FALSE) !> @} real(wp) :: weno_eps !< Binding for the WENO nonlinear weights real(wp) :: teno_CT !< Smoothness threshold for TENO logical :: mp_weno !< Monotonicity preserving (MP) WENO - logical :: weno_avg ! Average left/right cell-boundary states + logical :: weno_avg !< Average left/right cell-boundary states logical :: weno_Re_flux !< WENO reconstruct velocity gradients for viscous stress tensor integer :: riemann_solver !< Riemann solver algorithm integer :: low_Mach !< Low Mach number fix to HLLC Riemann solver @@ -322,23 +322,23 @@ module m_global_parameters !> @{ integer, dimension(3) :: dir_idx real(wp), dimension(3) :: dir_flg - integer, dimension(3) :: dir_idx_tau !!used for hypoelasticity=true + integer, dimension(3) :: dir_idx_tau !< used for hypoelasticity=true !> @} $:GPU_DECLARE(create='[dir_idx, dir_flg, dir_idx_tau]') !> The number of cells that are necessary to be able to store enough boundary conditions data to march the solution in the !! physical computational domain to the next time-step. - integer :: buff_size + integer :: buff_size !< Number of ghost cells for boundary condition storage $:GPU_DECLARE(create='[buff_size]') - integer :: shear_num !! Number of shear stress components + integer :: shear_num !< Number of shear stress components integer, dimension(3) :: shear_indices !< Indices of the stress components that represent shear stress integer :: shear_BC_flip_num !< Number of shear stress components to reflect for boundary conditions !> Indices of shear stress components to reflect for boundary conditions. Size: (1:3, 1:shear_BC_flip_num) for (x/y/z, !! [indices]) - integer, dimension(3, 2) :: shear_BC_flip_indices + integer, dimension(3, 2) :: shear_BC_flip_indices !< Shear stress BC reflection indices (1:3, 1:shear_BC_flip_num) $:GPU_DECLARE(create='[shear_num, shear_indices, shear_BC_flip_num, shear_BC_flip_indices]') @@ -348,18 +348,18 @@ module m_global_parameters !> Database of the physical parameters of each of the fluids that is present in the flow. These include the stiffened gas !! equation of state parameters, and the Reynolds numbers. - type(physical_parameters), dimension(num_fluids_max) :: fluid_pp + type(physical_parameters), dimension(num_fluids_max) :: fluid_pp !< Stiffened gas EOS parameters and Reynolds numbers per fluid ! Subgrid Bubble Parameters type(subgrid_bubble_physical_parameters) :: bub_pp !> The order of the finite-difference (fd) approximations of the first-order derivatives that need to be evaluated when the CoM !! or flow probe data files are to be written at each time step - integer :: fd_order + integer :: fd_order !< Finite-difference order for CoM and flow probe derivatives !> The finite-difference number is given by MAX(1, fd_order/2). Essentially, it is a measure of the half-size of the !! finite-difference stencil for the selected order of accuracy. - integer :: fd_number + integer :: fd_number !< Finite-difference half-stencil size: MAX(1, fd_order/2) $:GPU_DECLARE(create='[fd_order, fd_number]') logical :: probe_wrt @@ -380,7 +380,7 @@ module m_global_parameters logical :: ib integer :: num_ibs logical :: ib_state_wrt - type(ib_patch_parameters), dimension(num_patches_max) :: patch_ib + type(ib_patch_parameters), dimension(num_patches_max) :: patch_ib !< Immersed boundary patch parameters type(vec3_dt), allocatable, dimension(:) :: airfoil_grid_u, airfoil_grid_l integer :: Np !! Database of the immersed boundary patch parameters for each of the patches employed in the configuration of the initial @@ -522,7 +522,7 @@ module m_global_parameters logical :: fft_wrt !> AMDFlang workaround: keep a dummy logical to avoid a compiler case-optimization bug when a parameter+GPU-kernel conditional !! is false - logical :: dummy + logical :: dummy !< AMDFlang workaround for case-optimization + GPU-kernel bug !> @name Continuum damage model parameters !> @{! diff --git a/src/simulation/m_hyperelastic.fpp b/src/simulation/m_hyperelastic.fpp index 4fb504b2bc..0e5c00709b 100644 --- a/src/simulation/m_hyperelastic.fpp +++ b/src/simulation/m_hyperelastic.fpp @@ -8,9 +8,9 @@ module m_hyperelastic - use m_derived_types !< Definitions of the derived types - use m_global_parameters !< Definitions of the global parameters - use m_variables_conversion !< State variables type conversion procedures + use m_derived_types + use m_global_parameters + use m_variables_conversion use m_finite_differences implicit none diff --git a/src/simulation/m_hypoelastic.fpp b/src/simulation/m_hypoelastic.fpp index a04fcb6b3b..79b2c620be 100644 --- a/src/simulation/m_hypoelastic.fpp +++ b/src/simulation/m_hypoelastic.fpp @@ -7,8 +7,8 @@ !> @brief Computes hypoelastic stress-rate source terms and damage-state evolution module m_hypoelastic - use m_derived_types !< Definitions of the derived types - use m_global_parameters !< Definitions of the global parameters + use m_derived_types + use m_global_parameters use m_finite_differences use m_helper @@ -353,7 +353,7 @@ contains type(scalar_field), dimension(sys_size), intent(in) :: q_cons_vf type(scalar_field), dimension(sys_size), intent(inout) :: rhs_vf - real(wp) :: tau_p ! principal stress + real(wp) :: tau_p !< principal stress real(wp) :: tau_xx, tau_xy, tau_yy, tau_zz, tau_yz, tau_xz real(wp) :: I1, I2, I3, argument, phi, sqrt_term_1, sqrt_term_2, temp integer :: q, l, k diff --git a/src/simulation/m_ib_patches.fpp b/src/simulation/m_ib_patches.fpp index abc05543a0..41aeffec30 100644 --- a/src/simulation/m_ib_patches.fpp +++ b/src/simulation/m_ib_patches.fpp @@ -14,8 +14,8 @@ module m_ib_patches use m_model ! Subroutine(s) related to STL files use m_derived_types ! Definitions of the derived types - use m_global_parameters !< Definitions of the global parameters - use m_helper_basic !< Functions to compare floating point numbers + use m_global_parameters + use m_helper_basic use m_helper use m_mpi_common @@ -47,7 +47,7 @@ module m_ib_patches !! patch boundaries in the x-, y- and z-coordinate directions. They are used as a means to concisely perform the actions !! necessary to lay out a particular patch on the grid. - character(len=5) :: istr ! string to store int to string result for error checking + character(len=5) :: istr !< string to store int to string result for error checking contains @@ -55,8 +55,8 @@ contains impure subroutine s_apply_ib_patches(ib_markers) type(integer_field), intent(inout) :: ib_markers - integer :: i, xp, yp, zp ! iterators - integer :: xp_lower, xp_upper, yp_lower, yp_upper, zp_lower, zp_upper ! periodic bounds + integer :: i, xp, yp, zp !< iterators + integer :: xp_lower, xp_upper, yp_lower, yp_upper, zp_lower, zp_upper !< periodic bounds ! 3D Patch Geometries diff --git a/src/simulation/m_ibm.fpp b/src/simulation/m_ibm.fpp index 1a641b0e74..f70209a9cb 100644 --- a/src/simulation/m_ibm.fpp +++ b/src/simulation/m_ibm.fpp @@ -8,12 +8,12 @@ !! flow state module m_ibm - use m_derived_types !< Definitions of the derived types - use m_global_parameters !< Definitions of the global parameters - use m_mpi_proxy !< Message passing interface (MPI) module proxy - use m_variables_conversion !< State variables type conversion procedures + use m_derived_types + use m_global_parameters + use m_mpi_proxy + use m_variables_conversion use m_helper - use m_helper_basic !< Functions to compare floating point numbers + use m_helper_basic use m_constants use m_compute_levelset use m_ib_patches diff --git a/src/simulation/m_igr.fpp b/src/simulation/m_igr.fpp index a4eafa7f75..0157b803ed 100644 --- a/src/simulation/m_igr.fpp +++ b/src/simulation/m_igr.fpp @@ -8,7 +8,7 @@ !> @brief Iterative ghost rasterization (IGR) for sharp immersed boundary treatment module m_igr - use m_derived_types !< Definitions of the derived types + use m_derived_types use m_global_parameters use m_variables_conversion use m_mpi_proxy diff --git a/src/simulation/m_mpi_proxy.fpp b/src/simulation/m_mpi_proxy.fpp index 43fda863ad..4abbf8ac70 100644 --- a/src/simulation/m_mpi_proxy.fpp +++ b/src/simulation/m_mpi_proxy.fpp @@ -12,10 +12,10 @@ module m_mpi_proxy use mpi !< Message passing interface (MPI) module #endif - use m_helper_basic !< Functions to compare floating point numbers + use m_helper_basic use m_helper - use m_derived_types !< Definitions of the derived types - use m_global_parameters !< Definitions of the global parameters + use m_derived_types + use m_global_parameters use m_mpi_common use m_nvtx use ieee_arithmetic @@ -24,11 +24,11 @@ module m_mpi_proxy !> This variable is utilized to pack and send the buffer of the immersed boundary markers, for a single computational domain !! boundary at the time, to the relevant neighboring processor. - integer, private, allocatable, dimension(:) :: ib_buff_send + integer, private, allocatable, dimension(:) :: ib_buff_send !< IB marker send buffer for halo exchange !> q_cons_buff_recv is utilized to receive and unpack the buffer of the immersed boundary markers, for a single computational !! domain boundary at the time, from the relevant neighboring processor. - integer, private, allocatable, dimension(:) :: ib_buff_recv + integer, private, allocatable, dimension(:) :: ib_buff_recv !< IB marker receive buffer for halo exchange integer :: i_halo_size $:GPU_DECLARE(create='[i_halo_size]') diff --git a/src/simulation/m_muscl.fpp b/src/simulation/m_muscl.fpp index fbdb324057..3378bf681e 100644 --- a/src/simulation/m_muscl.fpp +++ b/src/simulation/m_muscl.fpp @@ -7,9 +7,9 @@ !> @brief MUSCL reconstruction with interface sharpening for contact-preserving advection module m_muscl - use m_derived_types !< Definitions of the derived types - use m_global_parameters !< Definitions of the global parameters - use m_variables_conversion !< State variables type conversion procedures + use m_derived_types + use m_global_parameters + use m_variables_conversion #ifdef MFC_OpenACC use openacc diff --git a/src/simulation/m_pressure_relaxation.fpp b/src/simulation/m_pressure_relaxation.fpp index 098890499e..cb53a30550 100644 --- a/src/simulation/m_pressure_relaxation.fpp +++ b/src/simulation/m_pressure_relaxation.fpp @@ -9,8 +9,8 @@ !! correction module m_pressure_relaxation - use m_derived_types !< Definitions of the derived types - use m_global_parameters !< Definitions of the global parameters + use m_derived_types + use m_global_parameters implicit none diff --git a/src/simulation/m_qbmm.fpp b/src/simulation/m_qbmm.fpp index 491985f7ed..a926ac35f1 100644 --- a/src/simulation/m_qbmm.fpp +++ b/src/simulation/m_qbmm.fpp @@ -8,11 +8,11 @@ !> @brief Quadrature-based moment methods (QBMM) for polydisperse bubble moment inversion and transport module m_qbmm - use m_derived_types !< Definitions of the derived types - use m_global_parameters !< Definitions of the global parameters - use m_mpi_proxy !< Message passing interface (MPI) module proxy - use m_variables_conversion !< State variables type conversion procedures - use m_helper_basic !< Functions to compare floating point numbers + use m_derived_types + use m_global_parameters + use m_mpi_proxy + use m_variables_conversion + use m_helper_basic use m_helper implicit none diff --git a/src/simulation/m_rhs.fpp b/src/simulation/m_rhs.fpp index c5e19eebb2..e39dd02e8b 100644 --- a/src/simulation/m_rhs.fpp +++ b/src/simulation/m_rhs.fpp @@ -9,17 +9,17 @@ !! physical source terms module m_rhs - use m_derived_types !< Definitions of the derived types - use m_global_parameters !< Definitions of the global parameters - use m_mpi_proxy !< Message passing interface (MPI) module proxy - use m_variables_conversion !< State variables type conversion procedures - use m_weno !< Weighted and essentially non-oscillatory (WENO) schemes for spatial reconstruction of variables - use m_muscl !< Monotonic Upstream-centered (MUSCL) schemes for conservation laws - use m_riemann_solvers !< Exact and approximate Riemann problem solvers - use m_cbc !< Characteristic boundary conditions (CBC) - use m_bubbles_EE !< Ensemble-averaged bubble dynamics routines + use m_derived_types + use m_global_parameters + use m_mpi_proxy + use m_variables_conversion + use m_weno + use m_muscl + use m_riemann_solvers + use m_cbc + use m_bubbles_EE use m_bubbles_EL - use m_qbmm !< Moment inversion + use m_qbmm use m_hypoelastic use m_hyperelastic use m_acoustic_src @@ -40,12 +40,12 @@ module m_rhs !! This variable contains the WENO-reconstructed values of the cell-average conservative variables, which are located in !! q_cons_vf, at cell-interior Gaussian quadrature points (QP). - type(vector_field) :: q_cons_qp + type(vector_field) :: q_cons_qp !< WENO-reconstructed cell-average conservative variables at quadrature points $:GPU_DECLARE(create='[q_cons_qp]') !! The primitive variables at cell-interior Gaussian quadrature points. These are calculated from the conservative variables and !! gradient magnitude (GM) of the volume fractions, q_cons_qp and gm_alpha_qp, respectively. - type(vector_field) :: q_prim_qp + type(vector_field) :: q_prim_qp !< Primitive variables at cell-interior quadrature points $:GPU_DECLARE(create='[q_prim_qp]') !> @name The first-order spatial derivatives of the primitive variables at cell- interior Gaussian quadrature points. These are @@ -73,7 +73,7 @@ module m_rhs !> The gradient magnitude of the volume fractions at cell-interior Gaussian quadrature points. gm_alpha_qp is calculated from !! individual first-order spatial derivatives located in dq_prim_ds_qp. - type(vector_field) :: gm_alpha_qp + type(vector_field) :: gm_alpha_qp !< Volume fraction gradient magnitudes at cell-interior quadrature points $:GPU_DECLARE(create='[gm_alpha_qp]') @@ -927,8 +927,8 @@ contains type(vector_field), intent(inout) :: q_cons_vf type(vector_field), intent(inout) :: q_prim_vf type(vector_field), intent(inout) :: flux_src_n_vf - integer :: j, k, l, q ! Loop iterators from original, meaning varies - integer :: k_loop, l_loop, q_loop ! Standardized spatial loop iterators 0:m, 0:n, 0:p + integer :: j, k, l, q !< Loop iterators from original, meaning varies + integer :: k_loop, l_loop, q_loop !< Standardized spatial loop iterators 0:m, 0:n, 0:p integer :: i_fluid_loop real(wp) :: inv_ds, flux_face1, flux_face2 real(wp) :: advected_qty_val, pressure_val, velocity_val diff --git a/src/simulation/m_riemann_solvers.fpp b/src/simulation/m_riemann_solvers.fpp index 096b16e057..4e1f182049 100644 --- a/src/simulation/m_riemann_solvers.fpp +++ b/src/simulation/m_riemann_solvers.fpp @@ -10,14 +10,14 @@ module m_riemann_solvers - use m_derived_types !< Definitions of the derived types - use m_global_parameters !< Definitions of the global parameters - use m_mpi_proxy !< Message passing interface (MPI) module proxy - use m_variables_conversion !< State variables type conversion procedures - use m_bubbles !< To get the bubble wall pressure function + use m_derived_types + use m_global_parameters + use m_mpi_proxy + use m_variables_conversion + use m_bubbles use m_bubbles_EE - use m_surface_tension !< To get the capillary fluxes - use m_helper_basic !< Functions to compare floating point numbers + use m_surface_tension + use m_helper_basic use m_chemistry use m_thermochem, only: gas_constant, get_mixture_molecular_weight, get_mixture_specific_heat_cv_mass, & & get_mixture_energy_mass, get_species_specific_heats_r, get_species_enthalpies_rt, get_mixture_specific_heat_cp_mass @@ -226,10 +226,10 @@ contains real(wp) :: zcoef, pcorr !< low Mach number correction type(riemann_states) :: c_fast, pres_mag type(riemann_states_vec3) :: B - type(riemann_states) :: Ga ! Gamma (Lorentz factor) + type(riemann_states) :: Ga !< Gamma (Lorentz factor) type(riemann_states) :: vdotB, B2 - type(riemann_states_vec3) :: b4 ! 4-magnetic field components (spatial: b4x, b4y, b4z) - type(riemann_states_vec3) :: cm ! Conservative momentum variables + type(riemann_states_vec3) :: b4 !< 4-magnetic field components (spatial: b4x, b4y, b4z) + type(riemann_states_vec3) :: cm !< Conservative momentum variables integer :: i, j, k, l, q !< Generic loop iterators ! Populating the buffers of the left and right Riemann problem states variables, based on the choice of boundary conditions @@ -912,10 +912,10 @@ contains real(wp) :: zcoef, pcorr !< low Mach number correction type(riemann_states) :: c_fast, pres_mag type(riemann_states_vec3) :: B - type(riemann_states) :: Ga ! Gamma (Lorentz factor) + type(riemann_states) :: Ga !< Gamma (Lorentz factor) type(riemann_states) :: vdotB, B2 - type(riemann_states_vec3) :: b4 ! 4-magnetic field components (spatial: b4x, b4y, b4z) - type(riemann_states_vec3) :: cm ! Conservative momentum variables + type(riemann_states_vec3) :: b4 !< 4-magnetic field components (spatial: b4x, b4y, b4z) + type(riemann_states_vec3) :: cm !< Conservative momentum variables integer :: i, j, k, l, q !< Generic loop iterators integer, dimension(3) :: idx_right_phys !< Physical (j,k,l) indices for right state. @@ -4032,7 +4032,7 @@ contains type(scalar_field), dimension(sys_size), intent(inout) :: flux_src_vf integer, intent(in) :: norm_dir - integer :: i, j, k, l ! Generic loop iterators + integer :: i, j, k, l !< Generic loop iterators ! Reshaping Inputted Data in x-direction @@ -4206,34 +4206,34 @@ contains ! Local variables #:if not MFC_CASE_OPTIMIZATION and USING_AMD - real(wp), dimension(3) :: avg_v_int !!< Averaged interface velocity (\f$v_x, v_y, v_z\f$) (grid directions). - real(wp), dimension(3) :: avg_dvdx_int !!< Averaged interface \f$\partial v_i/\partial x\f$ (grid dir 1). - real(wp), dimension(3) :: avg_dvdy_int !!< Averaged interface \f$\partial v_i/\partial y\f$ (grid dir 2). - real(wp), dimension(3) :: avg_dvdz_int !!< Averaged interface \f$\partial v_i/\partial z\f$ (grid dir 3). - real(wp), dimension(3) :: vel_src_int !!< Interface velocity (\f$v_1,v_2,v_3\f$) (grid directions) for viscous work. + real(wp), dimension(3) :: avg_v_int !< Averaged interface velocity (\f$v_x, v_y, v_z\f$) (grid directions). + real(wp), dimension(3) :: avg_dvdx_int !< Averaged interface \f$\partial v_i/\partial x\f$ (grid dir 1). + real(wp), dimension(3) :: avg_dvdy_int !< Averaged interface \f$\partial v_i/\partial y\f$ (grid dir 2). + real(wp), dimension(3) :: avg_dvdz_int !< Averaged interface \f$\partial v_i/\partial z\f$ (grid dir 3). + real(wp), dimension(3) :: vel_src_int !< Interface velocity (\f$v_1,v_2,v_3\f$) (grid directions) for viscous work. real(wp), & & dimension(3) & & :: stress_vector_shear !!< Shear stress vector (\f$\sigma_{N1}, \sigma_{N2}, \sigma_{N3}\f$) on N-face (grid directions). #:else real(wp), & & dimension(num_dims) :: avg_v_int !!< Averaged interface velocity (\f$v_x, v_y, v_z\f$) (grid directions). - real(wp), dimension(num_dims) :: avg_dvdx_int !!< Averaged interface \f$\partial v_i/\partial x\f$ (grid dir 1). - real(wp), dimension(num_dims) :: avg_dvdy_int !!< Averaged interface \f$\partial v_i/\partial y\f$ (grid dir 2). - real(wp), dimension(num_dims) :: avg_dvdz_int !!< Averaged interface \f$\partial v_i/\partial z\f$ (grid dir 3). + real(wp), dimension(num_dims) :: avg_dvdx_int !< Averaged interface \f$\partial v_i/\partial x\f$ (grid dir 1). + real(wp), dimension(num_dims) :: avg_dvdy_int !< Averaged interface \f$\partial v_i/\partial y\f$ (grid dir 2). + real(wp), dimension(num_dims) :: avg_dvdz_int !< Averaged interface \f$\partial v_i/\partial z\f$ (grid dir 3). real(wp), & & dimension(num_dims) :: vel_src_int !!< Interface velocity (\f$v_1,v_2,v_3\f$) (grid directions) for viscous work. real(wp), & & dimension(num_dims) & & :: stress_vector_shear !!< Shear stress vector (\f$\sigma_{N1}, \sigma_{N2}, \sigma_{N3}\f$) on N-face (grid directions). #:endif - real(wp) :: stress_normal_bulk !!< Normal bulk stress component \f$\sigma_{NN}\f$ on N-face. - real(wp) :: Re_s, Re_b !!< Effective interface shear and bulk Reynolds numbers. - real(wp) :: r_eff !!< Effective radius at interface for cylindrical terms. - real(wp) :: div_v_term_const !!< Common term \f$-(2/3)(\nabla \cdot \mathbf{v}) / \text{Re}_s\f$ for shear stress diagonal. - real(wp) :: divergence_cyl !!< Full divergence \f$\nabla \cdot \mathbf{v}\f$ in cylindrical coordinates. - integer :: j, k, l !!< Loop iterators for \f$x, y, z\f$ grid directions. - integer :: i_vel !!< Loop iterator for velocity components. - integer :: idx_rp(3) !!< Indices \f$(j,k,l)\f$ of 'right' point for averaging. + real(wp) :: stress_normal_bulk !< Normal bulk stress component \f$\sigma_{NN}\f$ on N-face. + real(wp) :: Re_s, Re_b !< Effective interface shear and bulk Reynolds numbers. + real(wp) :: r_eff !< Effective radius at interface for cylindrical terms. + real(wp) :: div_v_term_const !< Common term \f$-(2/3)(\nabla \cdot \mathbf{v}) / \text{Re}_s\f$ for shear stress diagonal. + real(wp) :: divergence_cyl !< Full divergence \f$\nabla \cdot \mathbf{v}\f$ in cylindrical coordinates. + integer :: j, k, l !< Loop iterators for \f$x, y, z\f$ grid directions. + integer :: i_vel !< Loop iterator for velocity components. + integer :: idx_rp(3) !< Indices \f$(j,k,l)\f$ of 'right' point for averaging. $:GPU_PARALLEL_LOOP(collapse=3, private='[idx_rp, avg_v_int, avg_dvdx_int, avg_dvdy_int, avg_dvdz_int, Re_s, Re_b, & & vel_src_int, r_eff, divergence_cyl, stress_vector_shear, stress_normal_bulk, div_v_term_const]') diff --git a/src/simulation/m_sim_helpers.fpp b/src/simulation/m_sim_helpers.fpp index 180ea05028..b9a5b10cf8 100644 --- a/src/simulation/m_sim_helpers.fpp +++ b/src/simulation/m_sim_helpers.fpp @@ -8,7 +8,7 @@ !> @brief Simulation helper routines for enthalpy computation, CFL calculation, and stability checks module m_sim_helpers - use m_derived_types !< Definitions of the derived types + use m_derived_types use m_global_parameters use m_variables_conversion @@ -183,15 +183,15 @@ contains real(wp) :: fltr_dtheta ! Inviscid CFL calculation - if (p > 0 .or. n > 0) then ! 2D/3D + if (p > 0 .or. n > 0) then icfl = dt/f_compute_multidim_cfl_terms(vel, c, j, k, l) - else ! 1D + else icfl = (dt/dx(j))*(abs(vel(1)) + c) end if ! Viscous calculations if (viscous) then - if (p > 0) then ! 3D + if (p > 0) then #:if not MFC_CASE_OPTIMIZATION or num_dims > 2 if (grid_geometry == 3) then fltr_dtheta = f_compute_filtered_dtheta(k, l) @@ -202,10 +202,10 @@ contains Rc = min(dx(j)*(abs(vel(1)) + c), dy(k)*(abs(vel(2)) + c), dz(l)*(abs(vel(3)) + c))/maxval(1._wp/Re_l) end if #:endif - else if (n > 0) then ! 2D + else if (n > 0) then vcfl = maxval(dt/Re_l/rho)/min(dx(j), dy(k))**2._wp Rc = min(dx(j)*(abs(vel(1)) + c), dy(k)*(abs(vel(2)) + c))/maxval(1._wp/Re_l) - else ! 1D + else vcfl = maxval(dt/Re_l/rho)/dx(j)**2._wp Rc = dx(j)*(abs(vel(1)) + c)/maxval(1._wp/Re_l) end if @@ -234,24 +234,24 @@ contains real(wp) :: fltr_dtheta ! Inviscid CFL calculation - if (p > 0 .or. n > 0) then ! 2D/3D cases + if (p > 0 .or. n > 0) then icfl_dt = cfl_target*f_compute_multidim_cfl_terms(vel, c, j, k, l) - else ! 1D cases + else icfl_dt = cfl_target*(dx(j)/(abs(vel(1)) + c)) end if ! Viscous calculations if (viscous) then - if (p > 0) then ! 3D + if (p > 0) then if (grid_geometry == 3) then fltr_dtheta = f_compute_filtered_dtheta(k, l) vcfl_dt = cfl_target*(min(dx(j), dy(k), fltr_dtheta)**2._wp)/maxval(1/(rho*Re_l)) else vcfl_dt = cfl_target*(min(dx(j), dy(k), dz(l))**2._wp)/maxval(1/(rho*Re_l)) end if - else if (n > 0) then ! 2D + else if (n > 0) then vcfl_dt = cfl_target*(min(dx(j), dy(k))**2._wp)/maxval((1/Re_l)/rho) - else ! 1D + else vcfl_dt = cfl_target*(dx(j)**2._wp)/maxval(1/(rho*Re_l)) end if end if diff --git a/src/simulation/m_start_up.fpp b/src/simulation/m_start_up.fpp index 7edb684cf3..b217d72d08 100644 --- a/src/simulation/m_start_up.fpp +++ b/src/simulation/m_start_up.fpp @@ -8,31 +8,31 @@ !> @brief Reads input files, loads initial conditions and grid data, and orchestrates solver initialization and finalization module m_start_up - use m_derived_types !< Definitions of the derived types - use m_global_parameters !< Definitions of the global parameters - use m_mpi_proxy !< Message passing interface (MPI) module proxy + use m_derived_types + use m_global_parameters + use m_mpi_proxy use m_mpi_common - use m_variables_conversion !< State variables type conversion procedures - use m_weno !< Weighted and essentially non-oscillatory (WENO) schemes for spatial reconstruction of variables - use m_muscl !< Monotonic Upstream-centered (MUSCL) schemes for convservation laws - use m_riemann_solvers !< Exact and approximate Riemann problem solvers - use m_cbc !< Characteristic boundary conditions (CBC) + use m_variables_conversion + use m_weno + use m_muscl + use m_riemann_solvers + use m_cbc use m_boundary_common - use m_acoustic_src !< Acoustic source calculations - use m_rhs !< Right-hand-side (RHS) evaluation procedures - use m_chemistry !< Chemistry module - use m_data_output !< Run-time info & solution data output procedures - use m_time_steppers !< Time-stepping algorithms - use m_qbmm !< Quadrature MOM - use m_derived_variables !< Procedures used to compute quantities derived from the conservative and primitive variables + use m_acoustic_src + use m_rhs + use m_chemistry + use m_data_output + use m_time_steppers + use m_qbmm + use m_derived_variables use m_hypoelastic use m_hyperelastic - use m_phase_change !< Phase-change module + use m_phase_change use m_viscous - use m_bubbles_EE !< Ensemble-averaged bubble dynamics routines - use m_bubbles_EL !< Lagrange bubble dynamics routines + use m_bubbles_EE + use m_bubbles_EL use ieee_arithmetic - use m_helper_basic !< Functions to compare floating point numbers + use m_helper_basic use m_helper $:USE_GPU_MODULE() @@ -193,7 +193,7 @@ contains logical :: file_exist ! Logical used to check the existence of the data files - integer :: i, r !< Generic loop iterator + integer :: i, r ! Confirming that the directory from which the initial condition and the grid data files are to be read in exists and ! exiting otherwise @@ -341,7 +341,7 @@ contains ! Downsampled data variables integer :: m_ds, n_ds, p_ds integer :: m_glb_ds, n_glb_ds, p_glb_ds - integer :: m_glb_read, n_glb_read, p_glb_read ! data size of read + integer :: m_glb_read, n_glb_read, p_glb_read !< data size of read allocate (x_cb_glb(-1:m_glb)) allocate (y_cb_glb(-1:n_glb)) diff --git a/src/simulation/m_surface_tension.fpp b/src/simulation/m_surface_tension.fpp index aa206044c0..f2ba76c1a7 100644 --- a/src/simulation/m_surface_tension.fpp +++ b/src/simulation/m_surface_tension.fpp @@ -9,12 +9,12 @@ !> @brief Computes capillary source fluxes and color-function gradients for the diffuse-interface surface tension model module m_surface_tension - use m_derived_types !< Definitions of the derived types - use m_global_parameters !< Definitions of the global parameters - use m_mpi_proxy !< Message passing interface (MPI) module proxy + use m_derived_types + use m_global_parameters + use m_mpi_proxy use m_variables_conversion use m_weno - use m_muscl !< Monotonic Upstream-centered (MUSCL) schemes for conservation laws + use m_muscl use m_helper use m_boundary_common diff --git a/src/simulation/m_time_steppers.fpp b/src/simulation/m_time_steppers.fpp index 253f0aaf9a..a9b4af0577 100644 --- a/src/simulation/m_time_steppers.fpp +++ b/src/simulation/m_time_steppers.fpp @@ -8,16 +8,16 @@ !> @brief Total-variation-diminishing (TVD) Runge--Kutta time integrators (1st-, 2nd-, and 3rd-order SSP) module m_time_steppers - use m_derived_types !< Definitions of the derived types - use m_global_parameters !< Definitions of the global parameters - use m_rhs !< Right-hane-side (RHS) evaluation procedures - use m_pressure_relaxation !< Pressure relaxation procedures - use m_data_output !< Run-time info & solution data output procedures - use m_bubbles_EE !< Ensemble-averaged bubble dynamics routines - use m_bubbles_EL !< Lagrange bubble dynamics routines + use m_derived_types + use m_global_parameters + use m_rhs + use m_pressure_relaxation + use m_data_output + use m_bubbles_EE + use m_bubbles_EL use m_ibm use m_hyperelastic - use m_mpi_proxy !< Message passing interface (MPI) module proxy + use m_mpi_proxy use m_boundary_common use m_helper use m_sim_helpers diff --git a/src/simulation/m_viscous.fpp b/src/simulation/m_viscous.fpp index 50aa935357..1607739158 100644 --- a/src/simulation/m_viscous.fpp +++ b/src/simulation/m_viscous.fpp @@ -7,10 +7,10 @@ !> @brief Computes viscous stress tensors and diffusive flux contributions for the Navier--Stokes equations module m_viscous - use m_derived_types !< Definitions of the derived types - use m_global_parameters !< Definitions of the global parameters + use m_derived_types + use m_global_parameters use m_weno - use m_muscl !< Monotonic Upstream-centered (MUSCL) schemes for conservation laws + use m_muscl use m_helper use m_finite_differences @@ -542,7 +542,7 @@ contains & buff_size) end if end do - else ! Compute velocity gradient at cell centers using finite differences + else ! Compute velocity gradients at cell centers using central finite differences iv%beg = mom_idx%beg; iv%end = mom_idx%end $:GPU_UPDATE(device='[iv]') @@ -1337,7 +1337,7 @@ contains real(wp), dimension(1:3,1:3) :: velocity_gradient_tensor real(wp), dimension(1:3) :: dx real(wp) :: divergence - integer :: l, q ! iterators + integer :: l, q !< iterators ! zero the viscous stress, collection of velocity derivatives, and spatial finite differences viscous_stress_tensor = 0._wp diff --git a/src/simulation/m_weno.fpp b/src/simulation/m_weno.fpp index a276d92601..6d7c87546f 100644 --- a/src/simulation/m_weno.fpp +++ b/src/simulation/m_weno.fpp @@ -7,14 +7,14 @@ !> @brief WENO/WENO-Z/TENO reconstruction with optional monotonicity-preserving bounds and mapped weights module m_weno - use m_derived_types !< Definitions of the derived types - use m_global_parameters !< Definitions of the global parameters - use m_variables_conversion !< State variables type conversion procedures + use m_derived_types + use m_global_parameters + use m_variables_conversion ! $:USE_GPU_MODULE() use m_mpi_proxy - use m_muscl !< For Interface Compression + use m_muscl private; public :: s_initialize_weno_module, s_initialize_weno, s_finalize_weno_module, s_weno @@ -184,8 +184,8 @@ contains real(wp), pointer, dimension(:) :: s_cb => null() !< Cell-boundary locations in the s-direction type(int_bounds_info) :: bc_s !< Boundary conditions (BC) in the s-direction integer :: i !< Generic loop iterator - real(wp) :: w(1:8) ! Intermediate var for ideal weights: s_cb across overall stencil - real(wp) :: y(1:4) ! Intermediate var for poly & beta: diff(s_cb) across sub-stencil + real(wp) :: w(1:8) !< Intermediate var for ideal weights: s_cb across overall stencil + real(wp) :: y(1:4) !< Intermediate var for poly & beta: diff(s_cb) across sub-stencil ! Determining the number of cells, the cell-boundary locations and the boundary conditions in the coordinate direction ! selected for the WENO reconstruction @@ -880,7 +880,7 @@ contains real(wp), dimension(0:weno_num_stencils) :: beta real(wp), dimension(0:weno_num_stencils) :: delta #:endif - real(wp), dimension(-3:3) :: v ! temporary field value array for clarity (WENO7 only) + real(wp), dimension(-3:3) :: v !< temporary field value array for clarity (WENO7 only) real(wp) :: tau integer :: i, j, k, l, q @@ -1462,18 +1462,19 @@ contains ! The left and right upper bounds (UL), medians, large curvatures, minima, and maxima of the WENO-reconstructed values of ! the cell- average variables. - real(wp) :: vL_UL, vR_UL - real(wp) :: vL_MD, vR_MD - real(wp) :: vL_LC, vR_LC - real(wp) :: vL_min, vR_min - real(wp) :: vL_max, vR_max - real(wp), parameter :: alpha = 2._wp !> - !! Determines the maximum Courant-Friedrichs-Lewy (CFL) number that may be utilized with the scheme. In theory, for - !! stability, a CFL number less than 1/(1+alpha) is necessary. The default value for alpha is 2. + real(wp) :: vL_UL, vR_UL + real(wp) :: vL_MD, vR_MD + real(wp) :: vL_LC, vR_LC + real(wp) :: vL_min, vR_min + real(wp) :: vL_max, vR_max + !> Max CFL stability parameter (CFL < 1/(1+alpha)) Determines the maximum Courant-Friedrichs-Lewy (CFL) number that may be + !! utilized with the scheme. In theory, for stability, a CFL number less than 1/(1+alpha) is necessary. The default value + !! for alpha is 2. + real(wp), parameter :: alpha = 2._wp !> Determines the amount of freedom available from utilizing a large value for the local curvature. The default value for !! beta is 4/3. - real(wp), parameter :: beta = 4._wp/3._wp + real(wp), parameter :: beta = 4._wp/3._wp !< Local curvature freedom parameter real(wp), parameter :: alpha_mp = 2._wp real(wp), parameter :: beta_mp = 4._wp/3._wp diff --git a/src/simulation/p_main.fpp b/src/simulation/p_main.fpp index be332ebf0e..1d0ad72035 100644 --- a/src/simulation/p_main.fpp +++ b/src/simulation/p_main.fpp @@ -10,7 +10,7 @@ !! fraction model. program p_main - use m_global_parameters !< Definitions of the global parameters + use m_global_parameters use m_start_up use m_time_steppers use m_nvtx From ea0b07007cfc8caf7909327927efbbbf8fa65b72 Mon Sep 17 00:00:00 2001 From: Spencer Bryngelson Date: Fri, 27 Mar 2026 10:47:00 -0400 Subject: [PATCH 06/14] fix: add missing lag_params%%write_void_evol to Lagrange bubble test cases --- toolchain/mfc/test/cases.py | 1 + 1 file changed, 1 insertion(+) diff --git a/toolchain/mfc/test/cases.py b/toolchain/mfc/test/cases.py index 3666b930c3..f5c78ec79c 100644 --- a/toolchain/mfc/test/cases.py +++ b/toolchain/mfc/test/cases.py @@ -1325,6 +1325,7 @@ def alter_lag_bubbles(dimInfo): "lag_betaC_wrt": "T", "lag_params%write_bubbles": "T", "lag_params%write_bubbles_stats": "T", + "lag_params%write_void_evol": "T", "polytropic": "F", "bub_pp%R0ref": 1.0, "bub_pp%p0ref": 1.0, From 8bd0d157c14455716d40eab53a204b4939199a4f Mon Sep 17 00:00:00 2001 From: Spencer Bryngelson Date: Fri, 27 Mar 2026 11:02:29 -0400 Subject: [PATCH 07/14] fix: use correct 3D Lagrange golden files (from moving-bubbles branch, not fix/time-stepping-order) --- tests/016C1B8B/golden.txt | 4 ++-- tests/CE7B0BC7/golden.txt | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/016C1B8B/golden.txt b/tests/016C1B8B/golden.txt index 29eca83b98..e44a2ae8c7 100644 --- a/tests/016C1B8B/golden.txt +++ b/tests/016C1B8B/golden.txt @@ -1,4 +1,4 @@ -D/beta.9.00.000050.dat 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999999708435 0.9999999644801 0.99999984081087 0.99999973754149 0.99999984081087 0.9999999644801 0.99999999708435 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.9999999644801 0.99999956727907 0.99999806067933 0.99999680260076 0.99999806067933 0.99999956727907 0.9999999644801 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999984081087 0.99999806067933 0.99999130856774 0.99998567025075 0.99999130856774 0.99999806067933 0.99999984081087 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999973754149 0.99999680260076 0.99998567025075 0.99997637423761 0.99998567025075 0.99999680260076 0.99999973754149 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999984081087 0.99999806067933 0.99999130856774 0.99998567025075 0.99999130856774 0.99999806067933 0.99999984081087 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.9999999644801 0.99999956727907 0.99999806067933 0.99999680260076 0.99999806067933 0.99999956727907 0.9999999644801 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999999708435 0.9999999644801 0.99999984081087 0.99999973754149 0.99999984081087 0.9999999644801 0.99999999708435 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.9999999644801 0.99999956727907 0.99999806067933 0.99999680260076 0.99999806067933 0.99999956727907 0.9999999644801 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999956727907 0.99999472837985 0.99997637423761 0.99996104770302 0.99997637423761 0.99999472837985 0.99999956727907 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999806067933 0.99997637423761 0.99989411667893 0.99982542791634 0.99989411667893 0.99997637423761 0.99999806067933 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999680260076 0.99996104770302 0.99982542791634 0.9997121792924 0.99982542791634 0.99996104770302 0.99999680260076 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999806067933 0.99997637423761 0.99989411667893 0.99982542791634 0.99989411667893 0.99997637423761 0.99999806067933 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999956727907 0.99999472837985 0.99997637423761 0.99996104770302 0.99997637423761 0.99999472837985 0.99999956727907 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.9999999644801 0.99999956727907 0.99999806067933 0.99999680260076 0.99999806067933 0.99999956727907 0.9999999644801 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999984081087 0.99999806067933 0.99999130856774 0.99998567025075 0.99999130856774 0.99999806067933 0.99999984081087 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999806067933 0.99997637423761 0.99989411667893 0.99982542791634 0.99989411667893 0.99997637423761 0.99999806067933 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999130856774 0.99989411667893 0.99952546387724 0.99921762220069 0.99952546387724 0.99989411667893 0.99999130856774 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99998567025075 0.99982542791634 0.99921762220069 0.99871007708055 0.99921762220069 0.99982542791634 0.99998567025075 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999130856774 0.99989411667893 0.99952546387724 0.99921762220069 0.99952546387724 0.99989411667893 0.99999130856774 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999806067933 0.99997637423761 0.99989411667893 0.99982542791634 0.99989411667893 0.99997637423761 0.99999806067933 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999984081087 0.99999806067933 0.99999130856774 0.99998567025075 0.99999130856774 0.99999806067933 0.99999984081087 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999973754149 0.99999680260076 0.99998567025075 0.99997637423761 0.99998567025075 0.99999680260076 0.99999973754149 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999680260076 0.99996104770302 0.99982542791634 0.9997121792924 0.99982542791634 0.99996104770302 0.99999680260076 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99998567025075 0.99982542791634 0.99921762220069 0.99871007708055 0.99921762220069 0.99982542791634 0.99998567025075 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99997637423761 0.9997121792924 0.99871007708055 0.99787327664514 0.99871007708055 0.9997121792924 0.99997637423761 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99998567025075 0.99982542791634 0.99921762220069 0.99871007708055 0.99921762220069 0.99982542791634 0.99998567025075 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999680260076 0.99996104770302 0.99982542791634 0.9997121792924 0.99982542791634 0.99996104770302 0.99999680260076 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999973754149 0.99999680260076 0.99998567025075 0.99997637423761 0.99998567025075 0.99999680260076 0.99999973754149 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999984081087 0.99999806067933 0.99999130856774 0.99998567025075 0.99999130856774 0.99999806067933 0.99999984081087 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999806067933 0.99997637423761 0.99989411667893 0.99982542791634 0.99989411667893 0.99997637423761 0.99999806067933 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999130856774 0.99989411667893 0.99952546387724 0.99921762220069 0.99952546387724 0.99989411667893 0.99999130856774 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99998567025075 0.99982542791634 0.99921762220069 0.99871007708055 0.99921762220069 0.99982542791634 0.99998567025075 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999130856774 0.99989411667893 0.99952546387724 0.99921762220069 0.99952546387724 0.99989411667893 0.99999130856774 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999806067933 0.99997637423761 0.99989411667893 0.99982542791634 0.99989411667893 0.99997637423761 0.99999806067933 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999984081087 0.99999806067933 0.99999130856774 0.99998567025075 0.99999130856774 0.99999806067933 0.99999984081087 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.9999999644801 0.99999956727907 0.99999806067933 0.99999680260076 0.99999806067933 0.99999956727907 0.9999999644801 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999956727907 0.99999472837985 0.99997637423761 0.99996104770302 0.99997637423761 0.99999472837985 0.99999956727907 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999806067933 0.99997637423761 0.99989411667893 0.99982542791634 0.99989411667893 0.99997637423761 0.99999806067933 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999680260076 0.99996104770302 0.99982542791634 0.9997121792924 0.99982542791634 0.99996104770302 0.99999680260076 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999806067933 0.99997637423761 0.99989411667893 0.99982542791634 0.99989411667893 0.99997637423761 0.99999806067933 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999956727907 0.99999472837985 0.99997637423761 0.99996104770302 0.99997637423761 0.99999472837985 0.99999956727907 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.9999999644801 0.99999956727907 0.99999806067933 0.99999680260076 0.99999806067933 0.99999956727907 0.9999999644801 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999999708435 0.9999999644801 0.99999984081087 0.99999973754149 0.99999984081087 0.9999999644801 0.99999999708435 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.9999999644801 0.99999956727907 0.99999806067933 0.99999680260076 0.99999806067933 0.99999956727907 0.9999999644801 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999984081087 0.99999806067933 0.99999130856774 0.99998567025075 0.99999130856774 0.99999806067933 0.99999984081087 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999973754149 0.99999680260076 0.99998567025075 0.99997637423761 0.99998567025075 0.99999680260076 0.99999973754149 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999984081087 0.99999806067933 0.99999130856774 0.99998567025075 0.99999130856774 0.99999806067933 0.99999984081087 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.9999999644801 0.99999956727907 0.99999806067933 0.99999680260076 0.99999806067933 0.99999956727907 0.9999999644801 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999999708435 0.9999999644801 0.99999984081087 0.99999973754149 0.99999984081087 0.9999999644801 0.99999999708435 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 +D/beta.9.00.000050.dat 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.9999999970844 0.99999996448075 0.99999984081375 0.99999973754625 0.99999984081375 0.99999996448075 0.9999999970844 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999996448075 0.99999956728691 0.9999980607145 0.99999680265874 0.9999980607145 0.99999956728691 0.99999996448075 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999984081375 0.9999980607145 0.99999130872535 0.99998567051061 0.99999130872535 0.9999980607145 0.99999984081375 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999973754625 0.99999680265874 0.99998567051061 0.99997637466605 0.99998567051061 0.99999680265874 0.99999973754625 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999984081375 0.9999980607145 0.99999130872535 0.99998567051061 0.99999130872535 0.9999980607145 0.99999984081375 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999996448075 0.99999956728691 0.9999980607145 0.99999680265874 0.9999980607145 0.99999956728691 0.99999996448075 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.9999999970844 0.99999996448075 0.99999984081375 0.99999973754625 0.99999984081375 0.99999996448075 0.9999999970844 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999996448075 0.99999956728691 0.9999980607145 0.99999680265874 0.9999980607145 0.99999956728691 0.99999996448075 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999956728691 0.99999472847545 0.99997637466605 0.99996104840939 0.99997637466605 0.99999472847545 0.99999956728691 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.9999980607145 0.99997637466605 0.99989411859905 0.99982543108208 0.99989411859905 0.99997637466605 0.9999980607145 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999680265874 0.99996104840939 0.99982543108208 0.99971218451182 0.99982543108208 0.99996104840939 0.99999680265874 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.9999980607145 0.99997637466605 0.99989411859905 0.99982543108208 0.99989411859905 0.99997637466605 0.9999980607145 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999956728691 0.99999472847545 0.99997637466605 0.99996104840939 0.99997637466605 0.99999472847545 0.99999956728691 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999996448075 0.99999956728691 0.9999980607145 0.99999680265874 0.9999980607145 0.99999956728691 0.99999996448075 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999984081375 0.9999980607145 0.99999130872535 0.99998567051061 0.99999130872535 0.9999980607145 0.99999984081375 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.9999980607145 0.99997637466605 0.99989411859905 0.99982543108208 0.99989411859905 0.99997637466605 0.9999980607145 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999130872535 0.99989411859905 0.9995254724826 0.99921763638853 0.9995254724826 0.99989411859905 0.99999130872535 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99998567051061 0.99982543108208 0.99921763638853 0.99871010047234 0.99921763638853 0.99982543108208 0.99998567051061 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999130872535 0.99989411859905 0.9995254724826 0.99921763638853 0.9995254724826 0.99989411859905 0.99999130872535 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.9999980607145 0.99997637466605 0.99989411859905 0.99982543108208 0.99989411859905 0.99997637466605 0.9999980607145 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999984081375 0.9999980607145 0.99999130872535 0.99998567051061 0.99999130872535 0.9999980607145 0.99999984081375 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999973754625 0.99999680265874 0.99998567051061 0.99997637466605 0.99998567051061 0.99999680265874 0.99999973754625 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999680265874 0.99996104840939 0.99982543108208 0.99971218451182 0.99982543108208 0.99996104840939 0.99999680265874 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99998567051061 0.99982543108208 0.99921763638853 0.99871010047234 0.99921763638853 0.99982543108208 0.99998567051061 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99997637466605 0.99971218451182 0.99871010047234 0.99787331521169 0.99871010047234 0.99971218451182 0.99997637466605 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99998567051061 0.99982543108208 0.99921763638853 0.99871010047234 0.99921763638853 0.99982543108208 0.99998567051061 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999680265874 0.99996104840939 0.99982543108208 0.99971218451182 0.99982543108208 0.99996104840939 0.99999680265874 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999973754625 0.99999680265874 0.99998567051061 0.99997637466605 0.99998567051061 0.99999680265874 0.99999973754625 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999984081375 0.9999980607145 0.99999130872535 0.99998567051061 0.99999130872535 0.9999980607145 0.99999984081375 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.9999980607145 0.99997637466605 0.99989411859905 0.99982543108208 0.99989411859905 0.99997637466605 0.9999980607145 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999130872535 0.99989411859905 0.9995254724826 0.99921763638853 0.9995254724826 0.99989411859905 0.99999130872535 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99998567051061 0.99982543108208 0.99921763638853 0.99871010047234 0.99921763638853 0.99982543108208 0.99998567051061 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999130872535 0.99989411859905 0.9995254724826 0.99921763638853 0.9995254724826 0.99989411859905 0.99999130872535 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.9999980607145 0.99997637466605 0.99989411859905 0.99982543108208 0.99989411859905 0.99997637466605 0.9999980607145 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999984081375 0.9999980607145 0.99999130872535 0.99998567051061 0.99999130872535 0.9999980607145 0.99999984081375 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999996448075 0.99999956728691 0.9999980607145 0.99999680265874 0.9999980607145 0.99999956728691 0.99999996448075 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999956728691 0.99999472847545 0.99997637466605 0.99996104840939 0.99997637466605 0.99999472847545 0.99999956728691 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.9999980607145 0.99997637466605 0.99989411859905 0.99982543108208 0.99989411859905 0.99997637466605 0.9999980607145 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999680265874 0.99996104840939 0.99982543108208 0.99971218451182 0.99982543108208 0.99996104840939 0.99999680265874 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.9999980607145 0.99997637466605 0.99989411859905 0.99982543108208 0.99989411859905 0.99997637466605 0.9999980607145 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999956728691 0.99999472847545 0.99997637466605 0.99996104840939 0.99997637466605 0.99999472847545 0.99999956728691 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999996448075 0.99999956728691 0.9999980607145 0.99999680265874 0.9999980607145 0.99999956728691 0.99999996448075 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.9999999970844 0.99999996448075 0.99999984081375 0.99999973754625 0.99999984081375 0.99999996448075 0.9999999970844 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999996448075 0.99999956728691 0.9999980607145 0.99999680265874 0.9999980607145 0.99999956728691 0.99999996448075 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999984081375 0.9999980607145 0.99999130872535 0.99998567051061 0.99999130872535 0.9999980607145 0.99999984081375 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999973754625 0.99999680265874 0.99998567051061 0.99997637466605 0.99998567051061 0.99999680265874 0.99999973754625 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999984081375 0.9999980607145 0.99999130872535 0.99998567051061 0.99999130872535 0.9999980607145 0.99999984081375 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999996448075 0.99999956728691 0.9999980607145 0.99999680265874 0.9999980607145 0.99999956728691 0.99999996448075 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.9999999970844 0.99999996448075 0.99999984081375 0.99999973754625 0.99999984081375 0.99999996448075 0.9999999970844 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 D/cons.1.00.000000.dat 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 D/cons.1.00.000050.dat 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999987 0.95999999999987 0.95999999999987 0.95999999999987 0.95999999999987 0.95999999999987 0.95999999999987 0.95999999999987 0.95999999999987 0.95999999999987 0.95999999999987 0.95999999999987 0.95999999999987 0.95999999999987 0.95999999999987 0.95999999999987 0.95999999999987 0.95999999999987 0.95999999999987 0.95999999999987 0.95999999999987 0.95999999999987 0.95999999999987 0.95999999999987 0.95999999999987 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000106 0.96000000000106 0.96000000000106 0.96000000000106 0.96000000000106 0.96000000000106 0.96000000000106 0.96000000000106 0.96000000000106 0.96000000000106 0.96000000000106 0.96000000000106 0.96000000000106 0.96000000000106 0.96000000000106 0.96000000000106 0.96000000000106 0.96000000000106 0.96000000000106 0.96000000000106 0.96000000000106 0.96000000000106 0.96000000000106 0.96000000000106 0.96000000000106 0.96000000000071 0.96000000000071 0.96000000000071 0.96000000000071 0.96000000000071 0.96000000000071 0.96000000000071 0.96000000000071 0.96000000000071 0.96000000000071 0.96000000000071 0.96000000000071 0.96000000000071 0.96000000000071 0.96000000000071 0.96000000000071 0.96000000000071 0.96000000000071 0.96000000000071 0.96000000000071 0.96000000000071 0.96000000000071 0.96000000000071 0.96000000000071 0.96000000000071 0.96000000000373 0.96000000000373 0.96000000000373 0.96000000000373 0.96000000000373 0.96000000000373 0.96000000000373 0.96000000000373 0.96000000000373 0.96000000000373 0.96000000000373 0.96000000000373 0.96000000000373 0.96000000000373 0.96000000000373 0.96000000000373 0.96000000000373 0.96000000000373 0.96000000000373 0.96000000000373 0.96000000000373 0.96000000000373 0.96000000000373 0.96000000000373 0.96000000000373 0.96000000000075 0.96000000000075 0.96000000000075 0.96000000000075 0.96000000000075 0.96000000000075 0.96000000000075 0.96000000000075 0.96000000000075 0.96000000000075 0.96000000000075 0.96000000000075 0.96000000000075 0.96000000000075 0.96000000000075 0.96000000000075 0.96000000000075 0.96000000000075 0.96000000000075 0.96000000000075 0.96000000000075 0.96000000000075 0.96000000000075 0.96000000000075 0.96000000000075 0.96000000000107 0.96000000000107 0.96000000000107 0.96000000000107 0.96000000000107 0.96000000000107 0.96000000000107 0.96000000000107 0.96000000000107 0.96000000000107 0.96000000000107 0.96000000000107 0.96000000000107 0.96000000000107 0.96000000000107 0.96000000000107 0.96000000000107 0.96000000000107 0.96000000000107 0.96000000000107 0.96000000000107 0.96000000000107 0.96000000000107 0.96000000000107 0.96000000000107 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.9600000000001 0.9600000000001 0.9600000000001 0.9600000000001 0.9600000000001 0.9600000000001 0.9600000000001 0.9600000000001 0.9600000000001 0.9600000000001 0.9600000000001 0.9600000000001 0.9600000000001 0.9600000000001 0.9600000000001 0.9600000000001 0.9600000000001 0.9600000000001 0.9600000000001 0.9600000000001 0.9600000000001 0.9600000000001 0.9600000000001 0.9600000000001 0.9600000000001 0.96000000000079 0.96000000000079 0.96000000000079 0.96000000000079 0.96000000000079 0.96000000000079 0.96000000000079 0.96000000000079 0.96000000000079 0.96000000000079 0.96000000000079 0.96000000000079 0.96000000000079 0.96000000000079 0.96000000000079 0.96000000000079 0.96000000000079 0.96000000000079 0.96000000000079 0.96000000000079 0.96000000000079 0.96000000000079 0.96000000000079 0.96000000000079 0.96000000000079 0.96000000002206 0.96000000002206 0.96000000002206 0.96000000002206 0.96000000002206 0.96000000002206 0.96000000002206 0.96000000002206 0.96000000002206 0.96000000002206 0.96000000002206 0.96000000002206 0.96000000002206 0.96000000002206 0.96000000002206 0.96000000002206 0.96000000002206 0.96000000002206 0.96000000002206 0.96000000002206 0.96000000002206 0.96000000002206 0.96000000002206 0.96000000002206 0.96000000002206 0.96000000005987 0.96000000005987 0.96000000005987 0.96000000005987 0.96000000005987 0.96000000005987 0.96000000005987 0.96000000005987 0.96000000005987 0.96000000005987 0.96000000005987 0.96000000005987 0.96000000005987 0.96000000005987 0.96000000005987 0.96000000005987 0.96000000005987 0.96000000005987 0.96000000005987 0.96000000005987 0.96000000005987 0.96000000005987 0.96000000005987 0.96000000005987 0.96000000005987 0.96000000004881 0.96000000004881 0.96000000004881 0.96000000004881 0.96000000004881 0.96000000004881 0.96000000004881 0.96000000004881 0.96000000004881 0.96000000004881 0.96000000004881 0.96000000004881 0.96000000004881 0.96000000004881 0.96000000004881 0.96000000004881 0.96000000004881 0.96000000004881 0.96000000004881 0.96000000004881 0.96000000004881 0.96000000004881 0.96000000004881 0.96000000004881 0.96000000004881 0.96000000032881 0.96000000032881 0.96000000032881 0.96000000032881 0.96000000032881 0.96000000032881 0.96000000032881 0.96000000032881 0.96000000032881 0.96000000032881 0.96000000032881 0.96000000032881 0.96000000032882 0.96000000032881 0.96000000032881 0.96000000032881 0.96000000032881 0.96000000032881 0.96000000032881 0.96000000032881 0.96000000032881 0.96000000032881 0.96000000032881 0.96000000032881 0.96000000032881 0.96000000005864 0.96000000005864 0.96000000005864 0.96000000005864 0.96000000005864 0.96000000005864 0.96000000005864 0.96000000005864 0.96000000005864 0.96000000005864 0.96000000005864 0.96000000005864 0.96000000005864 0.96000000005864 0.96000000005864 0.96000000005864 0.96000000005864 0.96000000005864 0.96000000005864 0.96000000005864 0.96000000005864 0.96000000005864 0.96000000005864 0.96000000005864 0.96000000005864 0.96000000008629 0.96000000008629 0.96000000008629 0.96000000008629 0.96000000008629 0.96000000008629 0.96000000008629 0.96000000008629 0.96000000008629 0.96000000008629 0.96000000008629 0.96000000008629 0.96000000008629 0.96000000008629 0.96000000008629 0.96000000008629 0.96000000008629 0.96000000008629 0.96000000008629 0.96000000008629 0.96000000008629 0.96000000008629 0.96000000008629 0.96000000008629 0.96000000008629 0.96000000000597 0.96000000000597 0.96000000000597 0.96000000000597 0.96000000000597 0.96000000000597 0.96000000000597 0.96000000000597 0.96000000000597 0.96000000000597 0.96000000000597 0.96000000000597 0.96000000000597 0.96000000000597 0.96000000000597 0.96000000000597 0.96000000000597 0.96000000000597 0.96000000000597 0.96000000000597 0.96000000000597 0.96000000000597 0.96000000000597 0.96000000000597 0.96000000000597 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.9600000000021 0.9600000000021 0.9600000000021 0.9600000000021 0.9600000000021 0.9600000000021 0.9600000000021 0.9600000000021 0.9600000000021 0.9600000000021 0.9600000000021 0.9600000000021 0.9600000000021 0.9600000000021 0.9600000000021 0.9600000000021 0.9600000000021 0.9600000000021 0.9600000000021 0.9600000000021 0.9600000000021 0.9600000000021 0.9600000000021 0.9600000000021 0.9600000000021 0.96000000013587 0.96000000013587 0.96000000013587 0.96000000013587 0.96000000013587 0.96000000013587 0.96000000013587 0.96000000013587 0.96000000013587 0.96000000013587 0.96000000013587 0.96000000013587 0.96000000013587 0.96000000013587 0.96000000013587 0.96000000013587 0.96000000013587 0.96000000013587 0.96000000013587 0.96000000013587 0.96000000013587 0.96000000013587 0.96000000013587 0.96000000013587 0.96000000013587 0.96000000392457 0.96000000392457 0.96000000392457 0.96000000392457 0.96000000392457 0.96000000392457 0.96000000392457 0.96000000392457 0.96000000392457 0.96000000392457 0.96000000392457 0.96000000392457 0.96000000392457 0.96000000392457 0.96000000392457 0.96000000392457 0.96000000392457 0.96000000392457 0.96000000392457 0.96000000392457 0.96000000392457 0.96000000392457 0.96000000392457 0.96000000392457 0.96000000392457 0.96000000386601 0.96000000386601 0.96000000386601 0.96000000386601 0.96000000386601 0.96000000386601 0.96000000386601 0.96000000386601 0.96000000386601 0.96000000386601 0.96000000386601 0.96000000386601 0.96000000386601 0.96000000386601 0.96000000386601 0.96000000386601 0.96000000386601 0.96000000386601 0.96000000386601 0.96000000386601 0.96000000386601 0.96000000386601 0.96000000386601 0.96000000386601 0.96000000386601 0.96000000372715 0.96000000372715 0.96000000372715 0.96000000372715 0.96000000372715 0.96000000372715 0.96000000372715 0.96000000372715 0.96000000372715 0.96000000372715 0.96000000372716 0.96000000372717 0.96000000372717 0.96000000372717 0.96000000372716 0.96000000372715 0.96000000372715 0.96000000372715 0.96000000372715 0.96000000372715 0.96000000372715 0.96000000372715 0.96000000372715 0.96000000372715 0.96000000372715 0.96000002634421 0.96000002634421 0.96000002634421 0.96000002634421 0.96000002634421 0.96000002634421 0.96000002634421 0.96000002634421 0.96000002634421 0.96000002634422 0.96000002634425 0.96000002634436 0.96000002634445 0.96000002634436 0.96000002634425 0.96000002634422 0.96000002634421 0.96000002634421 0.96000002634421 0.96000002634421 0.96000002634421 0.96000002634421 0.96000002634421 0.96000002634421 0.96000002634421 0.96000000528784 0.96000000528784 0.96000000528784 0.96000000528784 0.96000000528784 0.96000000528784 0.96000000528784 0.96000000528784 0.96000000528784 0.96000000528784 0.96000000528784 0.96000000528782 0.96000000528781 0.96000000528782 0.96000000528784 0.96000000528784 0.96000000528784 0.96000000528784 0.96000000528784 0.96000000528784 0.96000000528784 0.96000000528784 0.96000000528784 0.96000000528784 0.96000000528784 0.96000000790203 0.96000000790203 0.96000000790203 0.96000000790203 0.96000000790203 0.96000000790203 0.96000000790203 0.96000000790203 0.96000000790203 0.96000000790203 0.96000000790201 0.96000000790195 0.96000000790189 0.96000000790195 0.96000000790201 0.96000000790203 0.96000000790203 0.96000000790203 0.96000000790203 0.96000000790203 0.96000000790203 0.96000000790203 0.96000000790203 0.96000000790203 0.96000000790203 0.96000000059137 0.96000000059137 0.96000000059137 0.96000000059137 0.96000000059137 0.96000000059137 0.96000000059137 0.96000000059137 0.96000000059137 0.96000000059137 0.96000000059137 0.96000000059137 0.96000000059136 0.96000000059137 0.96000000059137 0.96000000059137 0.96000000059137 0.96000000059137 0.96000000059137 0.96000000059137 0.96000000059137 0.96000000059137 0.96000000059137 0.96000000059137 0.96000000059137 0.96000000001228 0.96000000001228 0.96000000001228 0.96000000001228 0.96000000001228 0.96000000001228 0.96000000001228 0.96000000001228 0.96000000001228 0.96000000001228 0.96000000001228 0.96000000001228 0.96000000001228 0.96000000001228 0.96000000001228 0.96000000001228 0.96000000001228 0.96000000001228 0.96000000001228 0.96000000001228 0.96000000001228 0.96000000001228 0.96000000001228 0.96000000001228 0.96000000001228 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000002232 0.96000000002232 0.96000000002232 0.96000000002232 0.96000000002232 0.96000000002232 0.96000000002232 0.96000000002232 0.96000000002232 0.96000000002232 0.96000000002232 0.96000000002232 0.96000000002232 0.96000000002232 0.96000000002232 0.96000000002232 0.96000000002232 0.96000000002232 0.96000000002232 0.96000000002232 0.96000000002232 0.96000000002232 0.96000000002232 0.96000000002232 0.96000000002232 0.960000001086 0.960000001086 0.960000001086 0.960000001086 0.960000001086 0.960000001086 0.960000001086 0.960000001086 0.960000001086 0.960000001086 0.960000001086 0.960000001086 0.960000001086 0.960000001086 0.960000001086 0.960000001086 0.960000001086 0.960000001086 0.960000001086 0.960000001086 0.960000001086 0.960000001086 0.960000001086 0.960000001086 0.960000001086 0.96000003357351 0.96000003357351 0.96000003357351 0.96000003357351 0.96000003357351 0.96000003357351 0.96000003357351 0.96000003357351 0.96000003357351 0.96000003357351 0.96000003357351 0.96000003357351 0.96000003357351 0.96000003357351 0.96000003357351 0.96000003357351 0.96000003357351 0.96000003357351 0.96000003357351 0.96000003357351 0.96000003357351 0.96000003357351 0.96000003357351 0.96000003357351 0.96000003357351 0.9600007182478 0.9600007182478 0.9600007182478 0.9600007182478 0.9600007182478 0.9600007182478 0.9600007182478 0.9600007182478 0.9600007182478 0.9600007182478 0.96000071824781 0.96000071824783 0.96000071824785 0.96000071824783 0.96000071824781 0.9600007182478 0.9600007182478 0.9600007182478 0.9600007182478 0.9600007182478 0.9600007182478 0.9600007182478 0.9600007182478 0.9600007182478 0.9600007182478 0.96000023896672 0.96000023896672 0.96000023896672 0.96000023896672 0.96000023896672 0.96000023896672 0.96000023896672 0.96000023896672 0.96000023896672 0.96000023896674 0.96000023896695 0.96000023896772 0.96000023896835 0.96000023896772 0.96000023896695 0.96000023896674 0.96000023896672 0.96000023896672 0.96000023896672 0.96000023896672 0.96000023896672 0.96000023896672 0.96000023896672 0.96000023896672 0.96000023896672 0.96000168485738 0.96000168485738 0.96000168485738 0.96000168485738 0.96000168485738 0.96000168485738 0.96000168485738 0.96000168485738 0.96000168485738 0.96000168485765 0.96000168486045 0.9600016848708 0.9600016848794 0.9600016848708 0.96000168486045 0.96000168485765 0.96000168485738 0.96000168485738 0.96000168485738 0.96000168485738 0.96000168485738 0.96000168485738 0.96000168485738 0.96000168485738 0.96000168485738 0.96000038977218 0.96000038977218 0.96000038977218 0.96000038977218 0.96000038977218 0.96000038977218 0.96000038977218 0.96000038977218 0.96000038977218 0.96000038977213 0.96000038977162 0.96000038976971 0.96000038976812 0.96000038976971 0.96000038977162 0.96000038977213 0.96000038977218 0.96000038977218 0.96000038977218 0.96000038977218 0.96000038977218 0.96000038977218 0.96000038977218 0.96000038977218 0.96000038977218 0.96000058691047 0.96000058691047 0.96000058691047 0.96000058691047 0.96000058691047 0.96000058691047 0.96000058691047 0.96000058691047 0.96000058691047 0.9600005869103 0.96000058690856 0.96000058690212 0.96000058689677 0.96000058690212 0.96000058690856 0.9600005869103 0.96000058691047 0.96000058691047 0.96000058691047 0.96000058691047 0.96000058691047 0.96000058691047 0.96000058691047 0.96000058691047 0.96000058691047 0.96000005194927 0.96000005194927 0.96000005194927 0.96000005194927 0.96000005194927 0.96000005194927 0.96000005194927 0.96000005194927 0.96000005194927 0.96000005194927 0.96000005194925 0.96000005194915 0.96000005194908 0.96000005194915 0.96000005194925 0.96000005194927 0.96000005194927 0.96000005194927 0.96000005194927 0.96000005194927 0.96000005194927 0.96000005194927 0.96000005194927 0.96000005194927 0.96000005194927 0.96000000110092 0.96000000110092 0.96000000110092 0.96000000110092 0.96000000110092 0.96000000110092 0.96000000110092 0.96000000110092 0.96000000110092 0.96000000110092 0.96000000110092 0.96000000110092 0.96000000110091 0.96000000110092 0.96000000110092 0.96000000110092 0.96000000110092 0.96000000110092 0.96000000110092 0.96000000110092 0.96000000110092 0.96000000110092 0.96000000110092 0.96000000110092 0.96000000110092 0.96000000002787 0.96000000002787 0.96000000002787 0.96000000002787 0.96000000002787 0.96000000002787 0.96000000002787 0.96000000002787 0.96000000002787 0.96000000002787 0.96000000002787 0.96000000002787 0.96000000002787 0.96000000002787 0.96000000002787 0.96000000002787 0.96000000002787 0.96000000002787 0.96000000002787 0.96000000002787 0.96000000002787 0.96000000002787 0.96000000002787 0.96000000002787 0.96000000002787 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96000000000024 0.96000000000024 0.96000000000024 0.96000000000024 0.96000000000024 0.96000000000024 0.96000000000024 0.96000000000024 0.96000000000024 0.96000000000024 0.96000000000024 0.96000000000024 0.96000000000024 0.96000000000024 0.96000000000024 0.96000000000024 0.96000000000024 0.96000000000024 0.96000000000024 0.96000000000024 0.96000000000024 0.96000000000024 0.96000000000024 0.96000000000024 0.96000000000024 0.96000000000461 0.96000000000461 0.96000000000461 0.96000000000461 0.96000000000461 0.96000000000461 0.96000000000461 0.96000000000461 0.96000000000461 0.96000000000461 0.96000000000461 0.96000000000461 0.96000000000461 0.96000000000461 0.96000000000461 0.96000000000461 0.96000000000461 0.96000000000461 0.96000000000461 0.96000000000461 0.96000000000461 0.96000000000461 0.96000000000461 0.96000000000461 0.96000000000461 0.96000000028923 0.96000000028923 0.96000000028923 0.96000000028923 0.96000000028923 0.96000000028923 0.96000000028923 0.96000000028923 0.96000000028923 0.96000000028923 0.96000000028923 0.96000000028923 0.96000000028923 0.96000000028923 0.96000000028923 0.96000000028923 0.96000000028923 0.96000000028923 0.96000000028923 0.96000000028923 0.96000000028923 0.96000000028923 0.96000000028923 0.96000000028923 0.96000000028923 0.96000001055314 0.96000001055314 0.96000001055314 0.96000001055314 0.96000001055314 0.96000001055314 0.96000001055314 0.96000001055314 0.96000001055314 0.96000001055314 0.96000001055314 0.96000001055314 0.96000001055314 0.96000001055314 0.96000001055314 0.96000001055314 0.96000001055314 0.96000001055314 0.96000001055314 0.96000001055314 0.96000001055314 0.96000001055314 0.96000001055314 0.96000001055314 0.96000001055314 0.96000025210076 0.96000025210076 0.96000025210076 0.96000025210076 0.96000025210076 0.96000025210076 0.96000025210076 0.96000025210076 0.96000025210076 0.96000025210076 0.96000025210075 0.96000025210075 0.96000025210074 0.96000025210075 0.96000025210075 0.96000025210076 0.96000025210076 0.96000025210076 0.96000025210076 0.96000025210076 0.96000025210076 0.96000025210076 0.96000025210076 0.96000025210076 0.96000025210076 0.96000388888139 0.96000388888139 0.96000388888139 0.96000388888139 0.96000388888139 0.96000388888139 0.96000388888139 0.96000388888139 0.96000388888139 0.96000388888138 0.96000388888123 0.9600038888807 0.96000388888026 0.9600038888807 0.96000388888123 0.96000388888138 0.96000388888139 0.96000388888139 0.96000388888139 0.96000388888139 0.96000388888139 0.96000388888139 0.96000388888139 0.96000388888139 0.96000388888139 0.96003762422319 0.96003762422319 0.96003762422319 0.96003762422319 0.96003762422319 0.96003762422319 0.96003762422319 0.96003762422319 0.96003762422319 0.9600376242231 0.96003762422213 0.96003762421858 0.96003762421563 0.96003762421858 0.96003762422213 0.9600376242231 0.96003762422319 0.96003762422319 0.96003762422319 0.96003762422319 0.96003762422319 0.96003762422319 0.96003762422319 0.96003762422319 0.96003762422319 0.96024757938339 0.96024757938339 0.96024757938339 0.96024757938339 0.96024757938339 0.96024757938339 0.96024757938339 0.96024757938339 0.96024757938339 0.96024757938299 0.96024757937889 0.96024757936384 0.96024757935133 0.96024757936384 0.96024757937889 0.96024757938299 0.96024757938339 0.96024757938339 0.96024757938339 0.96024757938339 0.96024757938339 0.96024757938339 0.96024757938339 0.96024757938339 0.96024757938339 0.96002715152843 0.96002715152843 0.96002715152843 0.96002715152843 0.96002715152843 0.96002715152843 0.96002715152843 0.96002715152843 0.96002715152838 0.96002715152368 0.96002715147466 0.96002715129448 0.96002715114453 0.96002715129448 0.96002715147466 0.96002715152368 0.96002715152838 0.96002715152843 0.96002715152843 0.96002715152843 0.96002715152843 0.96002715152843 0.96002715152843 0.96002715152843 0.96002715152843 0.96003089249465 0.96003089249465 0.96003089249465 0.96003089249465 0.96003089249465 0.96003089249465 0.96003089249465 0.96003089249465 0.96003089249453 0.96003089248229 0.96003089235395 0.96003089188122 0.96003089148813 0.96003089188122 0.96003089235395 0.96003089248229 0.96003089249453 0.96003089249465 0.96003089249465 0.96003089249465 0.96003089249465 0.96003089249465 0.96003089249465 0.96003089249465 0.96003089249465 0.96000375036941 0.96000375036941 0.96000375036941 0.96000375036941 0.96000375036941 0.96000375036941 0.96000375036941 0.96000375036941 0.9600037503694 0.96000375036924 0.96000375036749 0.96000375036112 0.96000375035583 0.96000375036112 0.96000375036749 0.96000375036924 0.9600037503694 0.96000375036941 0.96000375036941 0.96000375036941 0.96000375036941 0.96000375036941 0.96000375036941 0.96000375036941 0.96000375036941 0.96000008693805 0.96000008693805 0.96000008693805 0.96000008693805 0.96000008693805 0.96000008693805 0.96000008693805 0.96000008693805 0.96000008693805 0.96000008693804 0.96000008693792 0.96000008693746 0.96000008693709 0.96000008693746 0.96000008693792 0.96000008693804 0.96000008693805 0.96000008693805 0.96000008693805 0.96000008693805 0.96000008693805 0.96000008693805 0.96000008693805 0.96000008693805 0.96000008693805 0.96000000244292 0.96000000244292 0.96000000244292 0.96000000244292 0.96000000244292 0.96000000244292 0.96000000244292 0.96000000244292 0.96000000244292 0.96000000244292 0.96000000244292 0.96000000244292 0.96000000244291 0.96000000244292 0.96000000244292 0.96000000244292 0.96000000244292 0.96000000244292 0.96000000244292 0.96000000244292 0.96000000244292 0.96000000244292 0.96000000244292 0.96000000244292 0.96000000244292 0.96000000003463 0.96000000003463 0.96000000003463 0.96000000003463 0.96000000003463 0.96000000003463 0.96000000003463 0.96000000003463 0.96000000003463 0.96000000003463 0.96000000003463 0.96000000003463 0.96000000003463 0.96000000003463 0.96000000003463 0.96000000003463 0.96000000003463 0.96000000003463 0.96000000003463 0.96000000003463 0.96000000003463 0.96000000003463 0.96000000003463 0.96000000003463 0.96000000003463 0.9600000000004 0.9600000000004 0.9600000000004 0.9600000000004 0.9600000000004 0.9600000000004 0.9600000000004 0.9600000000004 0.9600000000004 0.9600000000004 0.9600000000004 0.9600000000004 0.9600000000004 0.9600000000004 0.9600000000004 0.9600000000004 0.9600000000004 0.9600000000004 0.9600000000004 0.9600000000004 0.9600000000004 0.9600000000004 0.9600000000004 0.9600000000004 0.9600000000004 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.96000000000021 0.96000000000021 0.96000000000021 0.96000000000021 0.96000000000021 0.96000000000021 0.96000000000021 0.96000000000021 0.96000000000021 0.96000000000021 0.96000000000021 0.96000000000021 0.96000000000021 0.96000000000021 0.96000000000021 0.96000000000021 0.96000000000021 0.96000000000021 0.96000000000021 0.96000000000021 0.96000000000021 0.96000000000021 0.96000000000021 0.96000000000021 0.96000000000021 0.96000000000066 0.96000000000066 0.96000000000066 0.96000000000066 0.96000000000066 0.96000000000066 0.96000000000066 0.96000000000066 0.96000000000066 0.96000000000066 0.96000000000066 0.96000000000066 0.96000000000066 0.96000000000066 0.96000000000066 0.96000000000066 0.96000000000066 0.96000000000066 0.96000000000066 0.96000000000066 0.96000000000066 0.96000000000066 0.96000000000066 0.96000000000066 0.96000000000066 0.9600000000725 0.9600000000725 0.9600000000725 0.9600000000725 0.9600000000725 0.9600000000725 0.9600000000725 0.9600000000725 0.9600000000725 0.9600000000725 0.9600000000725 0.9600000000725 0.9600000000725 0.9600000000725 0.9600000000725 0.9600000000725 0.9600000000725 0.9600000000725 0.9600000000725 0.9600000000725 0.9600000000725 0.9600000000725 0.9600000000725 0.9600000000725 0.9600000000725 0.96000000306584 0.96000000306584 0.96000000306584 0.96000000306584 0.96000000306584 0.96000000306584 0.96000000306584 0.96000000306584 0.96000000306584 0.96000000306584 0.96000000306584 0.96000000306584 0.96000000306584 0.96000000306584 0.96000000306584 0.96000000306584 0.96000000306584 0.96000000306584 0.96000000306584 0.96000000306584 0.96000000306584 0.96000000306584 0.96000000306584 0.96000000306584 0.96000000306584 0.96000008513635 0.96000008513635 0.96000008513635 0.96000008513635 0.96000008513635 0.96000008513635 0.96000008513635 0.96000008513635 0.96000008513635 0.96000008513635 0.96000008513635 0.96000008513635 0.96000008513634 0.96000008513635 0.96000008513635 0.96000008513635 0.96000008513635 0.96000008513635 0.96000008513635 0.96000008513635 0.96000008513635 0.96000008513635 0.96000008513635 0.96000008513635 0.96000008513635 0.96000153658661 0.96000153658661 0.96000153658661 0.96000153658661 0.96000153658661 0.96000153658661 0.96000153658661 0.96000153658661 0.96000153658661 0.9600015365866 0.96000153658648 0.96000153658605 0.96000153658568 0.96000153658605 0.96000153658648 0.9600015365866 0.96000153658661 0.96000153658661 0.96000153658661 0.96000153658661 0.96000153658661 0.96000153658661 0.96000153658661 0.96000153658661 0.96000153658661 0.96001782964953 0.96001782964953 0.96001782964953 0.96001782964953 0.96001782964953 0.96001782964953 0.96001782964953 0.96001782964953 0.96001782964952 0.96001782964798 0.96001782963141 0.96001782956971 0.96001782951832 0.96001782956971 0.96001782963141 0.96001782964798 0.96001782964952 0.96001782964953 0.96001782964953 0.96001782964953 0.96001782964953 0.96001782964953 0.96001782964953 0.96001782964953 0.96001782964953 0.96013299338417 0.96013299338417 0.96013299338417 0.96013299338417 0.96013299338417 0.96013299338417 0.96013299338417 0.96013299338417 0.96013299338407 0.96013299336664 0.96013299317938 0.96013299248152 0.9601329919003 0.96013299248152 0.96013299317938 0.96013299336664 0.96013299338407 0.96013299338417 0.96013299338417 0.96013299338417 0.96013299338417 0.96013299338417 0.96013299338417 0.96013299338417 0.96013299338417 0.96063533731738 0.96063533731738 0.96063533731738 0.96063533731738 0.96063533731738 0.96063533731738 0.96063533731738 0.96063533731738 0.96063533731696 0.96063533724286 0.96063533644612 0.96063533347361 0.96063533099909 0.96063533347361 0.96063533644612 0.96063533724286 0.96063533731696 0.96063533731738 0.96063533731738 0.96063533731738 0.96063533731738 0.96063533731738 0.96063533731738 0.96063533731738 0.96063533731738 0.96190052351632 0.96190052351632 0.96190052351632 0.96190052351632 0.96190052351632 0.96190052351632 0.96190052351631 0.96190052351633 0.96190052351558 0.9619005233962 0.9619005221108 0.96190051731369 0.96190051332184 0.96190051731369 0.9619005221108 0.9619005233962 0.96190052351558 0.96190052351633 0.96190052351631 0.96190052351632 0.96190052351632 0.96190052351632 0.96190052351632 0.96190052351632 0.96190052351632 0.96374631791153 0.96374631791153 0.96374631791153 0.96374631791153 0.96374631791153 0.96374631791153 0.96374631791153 0.96374631791153 0.9637463179113 0.96374631785162 0.9637463172047 0.96374631478143 0.96374631276272 0.96374631478143 0.9637463172047 0.96374631785162 0.9637463179113 0.96374631791153 0.96374631791153 0.96374631791153 0.96374631791153 0.96374631791153 0.96374631791153 0.96374631791153 0.96374631791153 0.96026255957098 0.96026255957098 0.96026255957098 0.96026255957098 0.96026255957098 0.96026255957098 0.96026255957098 0.96026255957098 0.96026255957094 0.96026255955942 0.96026255943523 0.96026255897133 0.96026255858468 0.96026255897133 0.96026255943523 0.96026255955942 0.96026255957094 0.96026255957098 0.96026255957098 0.96026255957098 0.96026255957098 0.96026255957098 0.96026255957098 0.96026255957098 0.96026255957098 0.96000700586267 0.96000700586267 0.96000700586267 0.96000700586267 0.96000700586267 0.96000700586267 0.96000700586267 0.96000700586267 0.96000700586266 0.96000700586123 0.96000700584591 0.96000700578881 0.96000700574126 0.96000700578881 0.96000700584591 0.96000700586123 0.96000700586266 0.96000700586267 0.96000700586267 0.96000700586267 0.96000700586267 0.96000700586267 0.96000700586267 0.96000700586267 0.96000700586267 0.96000019245935 0.96000019245935 0.96000019245935 0.96000019245935 0.96000019245935 0.96000019245935 0.96000019245935 0.96000019245935 0.96000019245935 0.96000019245934 0.96000019245924 0.96000019245887 0.96000019245857 0.96000019245887 0.96000019245924 0.96000019245934 0.96000019245935 0.96000019245935 0.96000019245935 0.96000019245935 0.96000019245935 0.96000019245935 0.96000019245935 0.96000019245935 0.96000019245935 0.9600000027078 0.9600000027078 0.9600000027078 0.9600000027078 0.9600000027078 0.9600000027078 0.9600000027078 0.9600000027078 0.9600000027078 0.9600000027078 0.9600000027078 0.9600000027078 0.96000000270779 0.9600000027078 0.9600000027078 0.9600000027078 0.9600000027078 0.9600000027078 0.9600000027078 0.9600000027078 0.9600000027078 0.9600000027078 0.9600000027078 0.9600000027078 0.9600000027078 0.96000000003541 0.96000000003541 0.96000000003541 0.96000000003541 0.96000000003541 0.96000000003541 0.96000000003541 0.96000000003541 0.96000000003541 0.96000000003541 0.96000000003541 0.96000000003541 0.96000000003541 0.96000000003541 0.96000000003541 0.96000000003541 0.96000000003541 0.96000000003541 0.96000000003541 0.96000000003541 0.96000000003541 0.96000000003541 0.96000000003541 0.96000000003541 0.96000000003541 0.96000000000036 0.96000000000036 0.96000000000036 0.96000000000036 0.96000000000036 0.96000000000036 0.96000000000036 0.96000000000036 0.96000000000036 0.96000000000036 0.96000000000036 0.96000000000036 0.96000000000036 0.96000000000036 0.96000000000036 0.96000000000036 0.96000000000036 0.96000000000036 0.96000000000036 0.96000000000036 0.96000000000036 0.96000000000036 0.96000000000036 0.96000000000036 0.96000000000036 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000004 0.96000000000004 0.96000000000004 0.96000000000004 0.96000000000004 0.96000000000004 0.96000000000004 0.96000000000004 0.96000000000004 0.96000000000004 0.96000000000004 0.96000000000004 0.96000000000004 0.96000000000004 0.96000000000004 0.96000000000004 0.96000000000004 0.96000000000004 0.96000000000004 0.96000000000004 0.96000000000004 0.96000000000004 0.96000000000004 0.96000000000004 0.96000000000004 0.96000000001662 0.96000000001662 0.96000000001662 0.96000000001662 0.96000000001662 0.96000000001662 0.96000000001662 0.96000000001662 0.96000000001662 0.96000000001662 0.96000000001662 0.96000000001662 0.96000000001662 0.96000000001662 0.96000000001662 0.96000000001662 0.96000000001662 0.96000000001662 0.96000000001662 0.96000000001662 0.96000000001662 0.96000000001662 0.96000000001662 0.96000000001662 0.96000000001662 0.96000000087018 0.96000000087018 0.96000000087018 0.96000000087018 0.96000000087018 0.96000000087018 0.96000000087018 0.96000000087018 0.96000000087018 0.96000000087018 0.96000000087018 0.96000000087018 0.96000000087018 0.96000000087018 0.96000000087018 0.96000000087018 0.96000000087018 0.96000000087018 0.96000000087018 0.96000000087018 0.96000000087018 0.96000000087018 0.96000000087018 0.96000000087018 0.96000000087018 0.96000002801722 0.96000002801722 0.96000002801722 0.96000002801722 0.96000002801722 0.96000002801722 0.96000002801722 0.96000002801722 0.96000002801722 0.96000002801722 0.96000002801722 0.96000002801722 0.96000002801722 0.96000002801722 0.96000002801722 0.96000002801722 0.96000002801722 0.96000002801722 0.96000002801722 0.96000002801722 0.96000002801722 0.96000002801722 0.96000002801722 0.96000002801722 0.96000002801722 0.96000057403111 0.96000057403111 0.96000057403111 0.96000057403111 0.96000057403111 0.96000057403111 0.96000057403111 0.96000057403111 0.96000057403111 0.96000057403111 0.96000057403109 0.96000057403102 0.96000057403097 0.96000057403102 0.96000057403109 0.96000057403111 0.96000057403111 0.96000057403111 0.96000057403111 0.96000057403111 0.96000057403111 0.96000057403111 0.96000057403111 0.96000057403111 0.96000057403111 0.9600078024614 0.9600078024614 0.9600078024614 0.9600078024614 0.9600078024614 0.9600078024614 0.9600078024614 0.9600078024614 0.9600078024614 0.96000780246127 0.96000780245992 0.96000780245496 0.96000780245084 0.96000780245496 0.96000780245992 0.96000780246127 0.9600078024614 0.9600078024614 0.9600078024614 0.9600078024614 0.9600078024614 0.9600078024614 0.9600078024614 0.9600078024614 0.9600078024614 0.96006802884276 0.96006802884276 0.96006802884276 0.96006802884276 0.96006802884276 0.96006802884276 0.96006802884276 0.96006802884276 0.96006802884267 0.96006802882497 0.96006802863493 0.96006802792686 0.96006802733718 0.96006802792686 0.96006802863493 0.96006802882497 0.96006802884267 0.96006802884276 0.96006802884276 0.96006802884276 0.96006802884276 0.96006802884276 0.96006802884276 0.96006802884276 0.96006802884276 0.96038137379852 0.96038137379852 0.96038137379852 0.96038137379852 0.96038137379852 0.96038137379852 0.96038137379851 0.96038137379854 0.96038137379712 0.96038137359152 0.96038137137588 0.96038136311132 0.96038135623538 0.96038136311132 0.96038137137588 0.96038137359152 0.96038137379712 0.96038137379854 0.96038137379851 0.96038137379852 0.96038137379852 0.96038137379852 0.96038137379852 0.96038137379852 0.96038137379852 0.96137903643732 0.96137903643732 0.96137903643732 0.96137903643732 0.96137903643732 0.96137903643732 0.96137903643732 0.96137903643733 0.96137903643076 0.96137903552684 0.96137902576482 0.96137898935413 0.96137895906936 0.96137898935413 0.96137902576482 0.96137903552684 0.96137903643076 0.96137903643733 0.96137903643732 0.96137903643732 0.96137903643732 0.96137903643732 0.96137903643732 0.96137903643732 0.96137903643732 0.96321014680893 0.96321014680893 0.96321014680893 0.96321014680893 0.96321014680893 0.96321014680893 0.96321014680895 0.96321014680885 0.96321014679832 0.96321014529002 0.96321012899152 0.96321006817364 0.9632100175864 0.96321006817364 0.96321012899152 0.96321014529002 0.96321014679832 0.96321014680885 0.96321014680895 0.96321014680893 0.96321014680893 0.96321014680893 0.96321014680893 0.96321014680893 0.96321014680893 0.96472448360735 0.96472448360735 0.96472448360735 0.96472448360735 0.96472448360735 0.96472448360735 0.96472448360736 0.96472448360735 0.96472448360078 0.96472448266336 0.96472447252939 0.96472443470448 0.96472440324446 0.96472443470448 0.96472447252939 0.96472448266336 0.96472448360078 0.96472448360735 0.96472448360736 0.96472448360735 0.96472448360735 0.96472448360735 0.96472448360735 0.96472448360735 0.96472448360735 0.96430483319369 0.96430483319369 0.96430483319369 0.96430483319369 0.96430483319369 0.96430483319369 0.96430483319369 0.96430483319372 0.96430483319207 0.96430483296631 0.96430483053594 0.96430482147442 0.96430481393844 0.96430482147442 0.96430483053594 0.96430483296631 0.96430483319207 0.96430483319372 0.96430483319369 0.96430483319369 0.96430483319369 0.96430483319369 0.96430483319369 0.96430483319369 0.96430483319369 0.96019082432575 0.96019082432575 0.96019082432575 0.96019082432575 0.96019082432575 0.96019082432575 0.96019082432575 0.96019082432575 0.96019082432576 0.96019082431475 0.96019082419333 0.96019082373483 0.96019082335182 0.96019082373483 0.96019082419333 0.96019082431475 0.96019082432576 0.96019082432575 0.96019082432575 0.96019082432575 0.96019082432575 0.96019082432575 0.96019082432575 0.96019082432575 0.96019082432575 0.96000932467124 0.96000932467124 0.96000932467124 0.96000932467124 0.96000932467124 0.96000932467124 0.96000932467124 0.96000932467124 0.96000932467124 0.96000932467127 0.96000932467156 0.96000932467266 0.96000932467357 0.96000932467266 0.96000932467156 0.96000932467127 0.96000932467124 0.96000932467124 0.96000932467124 0.96000932467124 0.96000932467124 0.96000932467124 0.96000932467124 0.96000932467124 0.96000932467124 0.96000014529282 0.96000014529282 0.96000014529282 0.96000014529282 0.96000014529282 0.96000014529282 0.96000014529282 0.96000014529282 0.96000014529282 0.96000014529282 0.96000014529282 0.96000014529279 0.96000014529278 0.96000014529279 0.96000014529282 0.96000014529282 0.96000014529282 0.96000014529282 0.96000014529282 0.96000014529282 0.96000014529282 0.96000014529282 0.96000014529282 0.96000014529282 0.96000014529282 0.96000000210283 0.96000000210283 0.96000000210283 0.96000000210283 0.96000000210283 0.96000000210283 0.96000000210283 0.96000000210283 0.96000000210283 0.96000000210283 0.96000000210283 0.96000000210283 0.96000000210283 0.96000000210283 0.96000000210283 0.96000000210283 0.96000000210283 0.96000000210283 0.96000000210283 0.96000000210283 0.96000000210283 0.96000000210283 0.96000000210283 0.96000000210283 0.96000000210283 0.96000000002503 0.96000000002503 0.96000000002503 0.96000000002503 0.96000000002503 0.96000000002503 0.96000000002503 0.96000000002503 0.96000000002503 0.96000000002503 0.96000000002503 0.96000000002503 0.96000000002503 0.96000000002503 0.96000000002503 0.96000000002503 0.96000000002503 0.96000000002503 0.96000000002503 0.96000000002503 0.96000000002503 0.96000000002503 0.96000000002503 0.96000000002503 0.96000000002503 0.96000000000025 0.96000000000025 0.96000000000025 0.96000000000025 0.96000000000025 0.96000000000025 0.96000000000025 0.96000000000025 0.96000000000025 0.96000000000025 0.96000000000025 0.96000000000025 0.96000000000025 0.96000000000025 0.96000000000025 0.96000000000025 0.96000000000025 0.96000000000025 0.96000000000025 0.96000000000025 0.96000000000025 0.96000000000025 0.96000000000025 0.96000000000025 0.96000000000025 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.96000000000049 0.96000000000049 0.96000000000049 0.96000000000049 0.96000000000049 0.96000000000049 0.96000000000049 0.96000000000049 0.96000000000049 0.96000000000049 0.96000000000049 0.96000000000049 0.96000000000049 0.96000000000049 0.96000000000049 0.96000000000049 0.96000000000049 0.96000000000049 0.96000000000049 0.96000000000049 0.96000000000049 0.96000000000049 0.96000000000049 0.96000000000049 0.96000000000049 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000804388 0.96000000804388 0.96000000804388 0.96000000804388 0.96000000804388 0.96000000804388 0.96000000804388 0.96000000804388 0.96000000804388 0.96000000804388 0.96000000804388 0.96000000804388 0.96000000804388 0.96000000804388 0.96000000804388 0.96000000804388 0.96000000804388 0.96000000804388 0.96000000804388 0.96000000804388 0.96000000804388 0.96000000804388 0.96000000804388 0.96000000804388 0.96000000804388 0.96000020225341 0.96000020225341 0.96000020225341 0.96000020225341 0.96000020225341 0.96000020225341 0.96000020225341 0.96000020225341 0.96000020225341 0.96000020225341 0.96000020225341 0.96000020225341 0.9600002022534 0.96000020225341 0.96000020225341 0.96000020225341 0.96000020225341 0.96000020225341 0.96000020225341 0.96000020225341 0.96000020225341 0.96000020225341 0.96000020225341 0.96000020225341 0.96000020225341 0.96000325281143 0.96000325281143 0.96000325281143 0.96000325281143 0.96000325281143 0.96000325281143 0.96000325281143 0.96000325281143 0.96000325281143 0.96000325281142 0.9600032528113 0.96000325281087 0.96000325281052 0.96000325281087 0.9600032528113 0.96000325281142 0.96000325281143 0.96000325281143 0.96000325281143 0.96000325281143 0.96000325281143 0.96000325281143 0.96000325281143 0.96000325281143 0.96000325281143 0.96003298088296 0.96003298088296 0.96003298088296 0.96003298088296 0.96003298088296 0.96003298088296 0.96003298088296 0.96003298088296 0.96003298088296 0.96003298088233 0.9600329808758 0.96003298085173 0.96003298083173 0.96003298085173 0.9600329808758 0.96003298088233 0.96003298088296 0.96003298088296 0.96003298088296 0.96003298088296 0.96003298088296 0.96003298088296 0.96003298088296 0.96003298088296 0.96003298088296 0.96021653301433 0.96021653301433 0.96021653301433 0.96021653301433 0.96021653301433 0.96021653301433 0.96021653301433 0.96021653301433 0.96021653301387 0.96021653293621 0.96021653210171 0.96021652898977 0.96021652639943 0.96021652898977 0.96021653210171 0.96021653293621 0.96021653301387 0.96021653301433 0.96021653301433 0.96021653301433 0.96021653301433 0.96021653301433 0.96021653301433 0.96021653301433 0.96021653301433 0.9609147657699 0.9609147657699 0.9609147657699 0.9609147657699 0.9609147657699 0.9609147657699 0.9609147657699 0.96091476576991 0.96091476576336 0.96091476486061 0.96091475511009 0.96091471874159 0.96091468849072 0.96091471874159 0.96091475511009 0.96091476486061 0.96091476576336 0.96091476576991 0.9609147657699 0.9609147657699 0.9609147657699 0.9609147657699 0.9609147657699 0.9609147657699 0.9609147657699 0.96249799243187 0.96249799243187 0.96249799243187 0.96249799243187 0.96249799243187 0.96249799243186 0.96249799243194 0.96249799243145 0.96249799240347 0.96249798832948 0.96249794431262 0.96249778003937 0.96249764334349 0.96249778003937 0.96249794431262 0.96249798832948 0.96249799240347 0.96249799243145 0.96249799243194 0.96249799243186 0.96249799243187 0.96249799243187 0.96249799243187 0.96249799243187 0.96249799243187 0.964334322046 0.964334322046 0.964334322046 0.964334322046 0.964334322046 0.96433432204598 0.96433432204609 0.96433432204522 0.96433432200005 0.96433431519141 0.96433424156069 0.9643339665361 0.96433373757564 0.9643339665361 0.96433424156069 0.96433431519141 0.96433432200005 0.96433432204522 0.96433432204609 0.96433432204598 0.964334322046 0.964334322046 0.964334322046 0.964334322046 0.964334322046 0.96481258179925 0.96481258179925 0.96481258179925 0.96481258179925 0.96481258179925 0.96481258179924 0.96481258179932 0.96481258179879 0.96481258177069 0.96481257753645 0.96481253174495 0.9648123607406 0.96481221843602 0.9648123607406 0.96481253174495 0.96481257753645 0.96481258177069 0.96481258179879 0.96481258179932 0.96481258179924 0.96481258179925 0.96481258179925 0.96481258179925 0.96481258179925 0.96481258179925 0.96336759080543 0.96336759080543 0.96336759080543 0.96336759080543 0.96336759080543 0.96336759080543 0.96336759080543 0.96336759080543 0.96336759079908 0.96336758987471 0.96336757987429 0.96336754253673 0.96336751147799 0.96336754253673 0.96336757987429 0.96336758987471 0.96336759079908 0.96336759080543 0.96336759080543 0.96336759080543 0.96336759080543 0.96336759080543 0.96336759080543 0.96336759080543 0.96336759080543 0.96143584361298 0.96143584361298 0.96143584361298 0.96143584361298 0.96143584361298 0.96143584361298 0.96143584361298 0.96143584361298 0.96143584361266 0.96143584354588 0.96143584282501 0.96143584013045 0.9614358378864 0.96143584013045 0.96143584282501 0.96143584354588 0.96143584361266 0.96143584361298 0.96143584361298 0.96143584361298 0.96143584361298 0.96143584361298 0.96143584361298 0.96143584361298 0.96143584361298 0.96040089864196 0.96040089864196 0.96040089864196 0.96040089864196 0.96040089864196 0.96040089864196 0.96040089864196 0.96040089864196 0.96040089864197 0.96040089864318 0.96040089865577 0.96040089870198 0.9604008987403 0.96040089870198 0.96040089865577 0.96040089864318 0.96040089864197 0.96040089864196 0.96040089864196 0.96040089864196 0.96040089864196 0.96040089864196 0.96040089864196 0.96040089864196 0.96040089864196 0.96000697925381 0.96000697925381 0.96000697925381 0.96000697925381 0.96000697925381 0.96000697925381 0.96000697925381 0.96000697925381 0.96000697925381 0.96000697925368 0.96000697925236 0.96000697924749 0.96000697924345 0.96000697924749 0.96000697925236 0.96000697925368 0.96000697925381 0.96000697925381 0.96000697925381 0.96000697925381 0.96000697925381 0.96000697925381 0.96000697925381 0.96000697925381 0.96000697925381 0.96000011362105 0.96000011362105 0.96000011362105 0.96000011362105 0.96000011362105 0.96000011362105 0.96000011362105 0.96000011362105 0.96000011362105 0.96000011362105 0.96000011362104 0.96000011362101 0.96000011362098 0.96000011362101 0.96000011362104 0.96000011362105 0.96000011362105 0.96000011362105 0.96000011362105 0.96000011362105 0.96000011362105 0.96000011362105 0.96000011362105 0.96000011362105 0.96000011362105 0.9600000014265 0.9600000014265 0.9600000014265 0.9600000014265 0.9600000014265 0.9600000014265 0.9600000014265 0.9600000014265 0.9600000014265 0.9600000014265 0.9600000014265 0.9600000014265 0.9600000014265 0.9600000014265 0.9600000014265 0.9600000014265 0.9600000014265 0.9600000014265 0.9600000014265 0.9600000014265 0.9600000014265 0.9600000014265 0.9600000014265 0.9600000014265 0.9600000014265 0.96000000001533 0.96000000001533 0.96000000001533 0.96000000001533 0.96000000001533 0.96000000001533 0.96000000001533 0.96000000001533 0.96000000001533 0.96000000001533 0.96000000001533 0.96000000001533 0.96000000001533 0.96000000001533 0.96000000001533 0.96000000001533 0.96000000001533 0.96000000001533 0.96000000001533 0.96000000001533 0.96000000001533 0.96000000001533 0.96000000001533 0.96000000001533 0.96000000001533 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.96000000000005 0.96000000000005 0.96000000000005 0.96000000000005 0.96000000000005 0.96000000000005 0.96000000000005 0.96000000000005 0.96000000000005 0.96000000000005 0.96000000000005 0.96000000000005 0.96000000000005 0.96000000000005 0.96000000000005 0.96000000000005 0.96000000000005 0.96000000000005 0.96000000000005 0.96000000000005 0.96000000000005 0.96000000000005 0.96000000000005 0.96000000000005 0.96000000000005 0.96000000000918 0.96000000000918 0.96000000000918 0.96000000000918 0.96000000000918 0.96000000000918 0.96000000000918 0.96000000000918 0.96000000000918 0.96000000000918 0.96000000000918 0.96000000000918 0.96000000000918 0.96000000000918 0.96000000000918 0.96000000000918 0.96000000000918 0.96000000000918 0.96000000000918 0.96000000000918 0.96000000000918 0.96000000000918 0.96000000000918 0.96000000000918 0.96000000000918 0.96000000079179 0.96000000079179 0.96000000079179 0.96000000079179 0.96000000079179 0.96000000079179 0.96000000079179 0.96000000079179 0.96000000079179 0.96000000079179 0.96000000079179 0.96000000079179 0.96000000079179 0.96000000079179 0.96000000079179 0.96000000079179 0.96000000079179 0.96000000079179 0.96000000079179 0.96000000079179 0.96000000079179 0.96000000079179 0.96000000079179 0.96000000079179 0.96000000079179 0.96000003419278 0.96000003419278 0.96000003419278 0.96000003419278 0.96000003419278 0.96000003419278 0.96000003419278 0.96000003419278 0.96000003419278 0.96000003419278 0.96000003419277 0.96000003419276 0.96000003419274 0.96000003419276 0.96000003419277 0.96000003419278 0.96000003419278 0.96000003419278 0.96000003419278 0.96000003419278 0.96000003419278 0.96000003419278 0.96000003419278 0.96000003419278 0.96000003419278 0.9600149885594 0.9600149885594 0.9600149885594 0.9600149885594 0.9600149885594 0.9600149885594 0.9600149885594 0.9600149885594 0.9600149885594 0.96001498855937 0.96001498855903 0.96001498855777 0.96001498855672 0.96001498855777 0.96001498855903 0.96001498855937 0.9600149885594 0.9600149885594 0.9600149885594 0.9600149885594 0.9600149885594 0.9600149885594 0.9600149885594 0.9600149885594 0.9600149885594 0.96011618398765 0.96011618398765 0.96011618398765 0.96011618398765 0.96011618398765 0.96011618398765 0.96011618398765 0.96011618398765 0.96011618398764 0.96011618398599 0.96011618396883 0.96011618390582 0.96011618385351 0.96011618390582 0.96011618396883 0.96011618398599 0.96011618398764 0.96011618398765 0.96011618398765 0.96011618398765 0.96011618398765 0.96011618398765 0.96011618398765 0.96011618398765 0.96011618398765 0.96057389899636 0.96057389899636 0.96057389899636 0.96057389899636 0.96057389899636 0.96057389899636 0.96057389899635 0.96057389899636 0.96057389899562 0.96057389887514 0.96057389757742 0.96057389273422 0.96057388870364 0.96057389273422 0.96057389757742 0.96057389887514 0.96057389899562 0.96057389899636 0.96057389899635 0.96057389899636 0.96057389899636 0.96057389899636 0.96057389899636 0.96057389899636 0.96057389899636 0.96183629361123 0.96183629361123 0.96183629361123 0.96183629361123 0.96183629361123 0.96183629361122 0.96183629361124 0.96183629361116 0.96183629360059 0.96183629211335 0.96183627604931 0.96183621612527 0.96183616628099 0.96183621612527 0.96183627604931 0.96183629211335 0.96183629360059 0.96183629361116 0.96183629361124 0.96183629361122 0.96183629361123 0.96183629361123 0.96183629361123 0.96183629361123 0.96183629361123 0.96374953553679 0.96374953553679 0.96374953553679 0.96374953553679 0.96374953553679 0.96374953553677 0.96374953553688 0.96374953553603 0.96374953549077 0.9637495287244 0.96374945556744 0.96374918235336 0.96374895490264 0.96374918235336 0.96374945556744 0.9637495287244 0.96374953549077 0.96374953553603 0.96374953553688 0.96374953553677 0.96374953553679 0.96374953553679 0.96374953553679 0.96374953553679 0.96374953553679 0.96487828647848 0.96487828647848 0.96487828647848 0.96487828647848 0.96487828647848 0.96487828647846 0.96487828647859 0.96487828647723 0.9648782864029 0.96487827506076 0.9648781523473 0.96487769368186 0.96487731156637 0.96487769368186 0.9648781523473 0.96487827506076 0.9648782864029 0.96487828647723 0.96487828647859 0.96487828647846 0.96487828647848 0.96487828647848 0.96487828647848 0.96487828647848 0.96487828647848 0.96403753353408 0.96403753353408 0.96403753353408 0.96403753353408 0.96403753353408 0.96403753353407 0.96403753353418 0.96403753353333 0.96403753348892 0.96403752666429 0.96403745281019 0.96403717686123 0.96403694710762 0.96403717686123 0.96403745281019 0.96403752666429 0.96403753348892 0.96403753353333 0.96403753353418 0.96403753353407 0.96403753353408 0.96403753353408 0.96403753353408 0.96403753353408 0.96403753353408 0.96213071462991 0.96213071462991 0.96213071462991 0.96213071462991 0.96213071462991 0.9621307146299 0.96213071462992 0.96213071462984 0.96213071461969 0.96213071311423 0.96213069682395 0.96213063599922 0.96213058539482 0.96213063599922 0.96213069682395 0.96213071311423 0.96213071461969 0.96213071462984 0.96213071462992 0.9621307146299 0.96213071462991 0.96213071462991 0.96213071462991 0.96213071462991 0.96213071462991 0.96071011797522 0.96071011797522 0.96071011797522 0.96071011797522 0.96071011797522 0.96071011797522 0.96071011797522 0.96071011797523 0.96071011797456 0.96071011785818 0.96071011660284 0.96071011191419 0.96071010801161 0.96071011191419 0.96071011660284 0.96071011785818 0.96071011797456 0.96071011797523 0.96071011797522 0.96071011797522 0.96071011797522 0.96071011797522 0.96071011797522 0.96071011797522 0.96071011797522 0.9601508434791 0.9601508434791 0.9601508434791 0.9601508434791 0.9601508434791 0.9601508434791 0.9601508434791 0.9601508434791 0.96015084347909 0.96015084347783 0.96015084346476 0.96015084341687 0.96015084337711 0.96015084341687 0.96015084346476 0.96015084347783 0.96015084347909 0.9601508434791 0.9601508434791 0.9601508434791 0.9601508434791 0.9601508434791 0.9601508434791 0.9601508434791 0.9601508434791 0.9600196248461 0.9600196248461 0.9600196248461 0.9600196248461 0.9600196248461 0.9600196248461 0.9600196248461 0.9600196248461 0.9600196248461 0.96001962484607 0.96001962484575 0.9600196248446 0.96001962484365 0.9600196248446 0.96001962484575 0.96001962484607 0.9600196248461 0.9600196248461 0.9600196248461 0.9600196248461 0.9600196248461 0.9600196248461 0.9600196248461 0.9600196248461 0.9600196248461 0.96000036744425 0.96000036744425 0.96000036744425 0.96000036744425 0.96000036744425 0.96000036744425 0.96000036744425 0.96000036744425 0.96000036744425 0.96000036744425 0.96000036744425 0.96000036744423 0.96000036744422 0.96000036744423 0.96000036744425 0.96000036744425 0.96000036744425 0.96000036744425 0.96000036744425 0.96000036744425 0.96000036744425 0.96000036744425 0.96000036744425 0.96000036744425 0.96000036744425 0.96000000570381 0.96000000570381 0.96000000570381 0.96000000570381 0.96000000570381 0.96000000570381 0.96000000570381 0.96000000570381 0.96000000570381 0.96000000570381 0.96000000570381 0.96000000570381 0.96000000570381 0.96000000570381 0.96000000570381 0.96000000570381 0.96000000570381 0.96000000570381 0.96000000570381 0.96000000570381 0.96000000570381 0.96000000570381 0.96000000570381 0.96000000570381 0.96000000570381 0.96000000007383 0.96000000007383 0.96000000007383 0.96000000007383 0.96000000007383 0.96000000007383 0.96000000007383 0.96000000007383 0.96000000007383 0.96000000007383 0.96000000007383 0.96000000007383 0.96000000007383 0.96000000007383 0.96000000007383 0.96000000007383 0.96000000007383 0.96000000007383 0.96000000007383 0.96000000007383 0.96000000007383 0.96000000007383 0.96000000007383 0.96000000007383 0.96000000007383 0.96000000000109 0.96000000000109 0.96000000000109 0.96000000000109 0.96000000000109 0.96000000000109 0.96000000000109 0.96000000000109 0.96000000000109 0.96000000000109 0.96000000000109 0.96000000000109 0.96000000000109 0.96000000000109 0.96000000000109 0.96000000000109 0.96000000000109 0.96000000000109 0.96000000000109 0.96000000000109 0.96000000000109 0.96000000000109 0.96000000000109 0.96000000000109 0.96000000000109 0.95999999999988 0.95999999999988 0.95999999999988 0.95999999999988 0.95999999999988 0.95999999999988 0.95999999999988 0.95999999999988 0.95999999999988 0.95999999999988 0.95999999999988 0.95999999999988 0.95999999999988 0.95999999999988 0.95999999999988 0.95999999999988 0.95999999999988 0.95999999999988 0.95999999999988 0.95999999999988 0.95999999999988 0.95999999999988 0.95999999999988 0.95999999999988 0.95999999999988 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.96000000000232 0.96000000000232 0.96000000000232 0.96000000000232 0.96000000000232 0.96000000000232 0.96000000000232 0.96000000000232 0.96000000000232 0.96000000000232 0.96000000000232 0.96000000000232 0.96000000000232 0.96000000000232 0.96000000000232 0.96000000000232 0.96000000000232 0.96000000000232 0.96000000000232 0.96000000000232 0.96000000000232 0.96000000000232 0.96000000000232 0.96000000000232 0.96000000000232 0.96000000018275 0.96000000018275 0.96000000018275 0.96000000018275 0.96000000018275 0.96000000018275 0.96000000018275 0.96000000018275 0.96000000018275 0.96000000018275 0.96000000018275 0.96000000018275 0.96000000018275 0.96000000018275 0.96000000018275 0.96000000018275 0.96000000018275 0.96000000018275 0.96000000018275 0.96000000018275 0.96000000018275 0.96000000018275 0.96000000018275 0.96000000018275 0.96000000018275 0.96000001363188 0.96000001363188 0.96000001363188 0.96000001363188 0.96000001363188 0.96000001363188 0.96000001363188 0.96000001363188 0.96000001363188 0.96000001363188 0.96000001363187 0.96000001363183 0.9600000136318 0.96000001363183 0.96000001363187 0.96000001363188 0.96000001363188 0.96000001363188 0.96000001363188 0.96000001363188 0.96000001363188 0.96000001363188 0.96000001363188 0.96000001363188 0.96000001363188 0.96000111210589 0.96000111210589 0.96000111210589 0.96000111210589 0.96000111210589 0.96000111210589 0.96000111210589 0.96000111210589 0.96000111210588 0.96000111210575 0.96000111210433 0.96000111209908 0.96000111209473 0.96000111209908 0.96000111210433 0.96000111210575 0.96000111210588 0.96000111210589 0.96000111210589 0.96000111210589 0.96000111210589 0.96000111210589 0.96000111210589 0.96000111210589 0.96000111210589 0.96033224617124 0.96033224617124 0.96033224617124 0.96033224617124 0.96033224617124 0.96033224617124 0.96033224617124 0.96033224617124 0.96033224617125 0.96033224617226 0.96033224618278 0.96033224622142 0.96033224625347 0.96033224622142 0.96033224618278 0.96033224617226 0.96033224617125 0.96033224617124 0.96033224617124 0.96033224617124 0.96033224617124 0.96033224617124 0.96033224617124 0.96033224617124 0.96033224617124 0.96126932110788 0.96126932110788 0.96126932110788 0.96126932110788 0.96126932110788 0.96126932110788 0.96126932110787 0.96126932110788 0.96126932110752 0.96126932104009 0.96126932031355 0.96126931760025 0.961269315341 0.96126931760025 0.96126932031355 0.96126932104009 0.96126932110752 0.96126932110788 0.96126932110787 0.96126932110788 0.96126932110788 0.96126932110788 0.96126932110788 0.96126932110788 0.96126932110788 0.96305949909787 0.96305949909787 0.96305949909787 0.96305949909787 0.96305949909787 0.96305949909786 0.96305949909787 0.96305949909786 0.96305949909115 0.96305949816147 0.96305948812066 0.96305945066439 0.96305941951215 0.96305945066439 0.96305948812066 0.96305949816147 0.96305949909115 0.96305949909786 0.96305949909787 0.96305949909786 0.96305949909787 0.96305949909787 0.96305949909787 0.96305949909787 0.96305949909787 0.96466883490351 0.96466883490351 0.96466883490351 0.96466883490351 0.9646688349035 0.96466883490349 0.96466883490357 0.96466883490304 0.96466883487489 0.96466883066562 0.9646687851556 0.96466861522582 0.96466847382042 0.96466861522582 0.9646687851556 0.96466883066562 0.96466883487489 0.96466883490304 0.96466883490357 0.96466883490349 0.9646688349035 0.96466883490351 0.96466883490351 0.96466883490351 0.96466883490351 0.96456048864478 0.96456048864478 0.96456048864478 0.96456048864478 0.96456048864478 0.96456048864476 0.96456048864487 0.96456048864401 0.96456048859914 0.96456048174206 0.96456040755388 0.96456013037967 0.96455989961608 0.96456013037967 0.96456040755388 0.96456048174206 0.96456048859914 0.96456048864401 0.96456048864487 0.96456048864476 0.96456048864478 0.96456048864478 0.96456048864478 0.96456048864478 0.96456048864478 0.96281609353146 0.96281609353146 0.96281609353146 0.96281609353146 0.96281609353146 0.96281609353145 0.96281609353152 0.96281609353106 0.96281609350432 0.96281608939444 0.96281604490869 0.96281587872987 0.96281574041835 0.96281587872987 0.96281604490869 0.96281608939444 0.96281609350432 0.96281609353106 0.96281609353152 0.96281609353145 0.96281609353146 0.96281609353146 0.96281609353146 0.96281609353146 0.96281609353146 0.96111125786873 0.96111125786873 0.96111125786873 0.96111125786873 0.96111125786873 0.96111125786873 0.96111125786873 0.96111125786875 0.96111125786243 0.96111125695906 0.96111124718917 0.96111121072379 0.96111118038786 0.96111121072379 0.96111124718917 0.96111125695906 0.96111125786243 0.96111125786875 0.96111125786873 0.96111125786873 0.96111125786873 0.96111125786873 0.96111125786873 0.96111125786873 0.96111125786873 0.96027471074325 0.96027471074325 0.96027471074325 0.96027471074325 0.96027471074325 0.96027471074325 0.96027471074325 0.96027471074325 0.9602747107428 0.96027471066573 0.96027470983716 0.9602747067466 0.96027470417394 0.9602747067466 0.96027470983716 0.96027471066573 0.9602747107428 0.96027471074325 0.96027471074325 0.96027471074325 0.96027471074325 0.96027471074325 0.96027471074325 0.96027471074325 0.96027471074325 0.96004459277341 0.96004459277341 0.96004459277341 0.96004459277341 0.96004459277341 0.96004459277341 0.96004459277341 0.96004459277341 0.9600445927734 0.96004459277274 0.96004459276578 0.96004459274017 0.96004459271889 0.96004459274017 0.96004459276578 0.96004459277274 0.9600445927734 0.96004459277341 0.96004459277341 0.96004459277341 0.96004459277341 0.96004459277341 0.96004459277341 0.96004459277341 0.96004459277341 0.96000499233933 0.96000499233933 0.96000499233933 0.96000499233933 0.96000499233933 0.96000499233933 0.96000499233933 0.96000499233933 0.96000499233933 0.96000499233932 0.96000499233918 0.96000499233868 0.96000499233826 0.96000499233868 0.96000499233918 0.96000499233932 0.96000499233933 0.96000499233933 0.96000499233933 0.96000499233933 0.96000499233933 0.96000499233933 0.96000499233933 0.96000499233933 0.96000499233933 0.96000031117462 0.96000031117462 0.96000031117462 0.96000031117462 0.96000031117462 0.96000031117462 0.96000031117462 0.96000031117462 0.96000031117462 0.96000031117462 0.96000031117462 0.96000031117461 0.96000031117461 0.96000031117461 0.96000031117462 0.96000031117462 0.96000031117462 0.96000031117462 0.96000031117462 0.96000031117462 0.96000031117462 0.96000031117462 0.96000031117462 0.96000031117462 0.96000031117462 0.96000001433426 0.96000001433426 0.96000001433426 0.96000001433426 0.96000001433426 0.96000001433426 0.96000001433426 0.96000001433426 0.96000001433426 0.96000001433426 0.96000001433426 0.96000001433426 0.96000001433426 0.96000001433426 0.96000001433426 0.96000001433426 0.96000001433426 0.96000001433426 0.96000001433426 0.96000001433426 0.96000001433426 0.96000001433426 0.96000001433426 0.96000001433426 0.96000001433426 0.96000000025446 0.96000000025446 0.96000000025446 0.96000000025446 0.96000000025446 0.96000000025446 0.96000000025446 0.96000000025446 0.96000000025446 0.96000000025446 0.96000000025446 0.96000000025446 0.96000000025446 0.96000000025446 0.96000000025446 0.96000000025446 0.96000000025446 0.96000000025446 0.96000000025446 0.96000000025446 0.96000000025446 0.96000000025446 0.96000000025446 0.96000000025446 0.96000000025446 0.96000000000415 0.96000000000415 0.96000000000415 0.96000000000415 0.96000000000415 0.96000000000415 0.96000000000415 0.96000000000415 0.96000000000415 0.96000000000415 0.96000000000415 0.96000000000415 0.96000000000415 0.96000000000415 0.96000000000415 0.96000000000415 0.96000000000415 0.96000000000415 0.96000000000415 0.96000000000415 0.96000000000415 0.96000000000415 0.96000000000415 0.96000000000415 0.96000000000415 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.9600000000212 0.9600000000212 0.9600000000212 0.9600000000212 0.9600000000212 0.9600000000212 0.9600000000212 0.9600000000212 0.9600000000212 0.9600000000212 0.9600000000212 0.9600000000212 0.9600000000212 0.9600000000212 0.9600000000212 0.9600000000212 0.9600000000212 0.9600000000212 0.9600000000212 0.9600000000212 0.9600000000212 0.9600000000212 0.9600000000212 0.9600000000212 0.9600000000212 0.960000001965 0.960000001965 0.960000001965 0.960000001965 0.960000001965 0.960000001965 0.960000001965 0.960000001965 0.960000001965 0.960000001965 0.960000001965 0.96000000196499 0.96000000196499 0.96000000196499 0.960000001965 0.960000001965 0.960000001965 0.960000001965 0.960000001965 0.960000001965 0.960000001965 0.960000001965 0.960000001965 0.960000001965 0.960000001965 0.96000015611273 0.96000015611273 0.96000015611273 0.96000015611273 0.96000015611273 0.96000015611273 0.96000015611273 0.96000015611273 0.96000015611273 0.96000015611273 0.96000015611271 0.96000015611266 0.96000015611262 0.96000015611266 0.96000015611271 0.96000015611273 0.96000015611273 0.96000015611273 0.96000015611273 0.96000015611273 0.96000015611273 0.96000015611273 0.96000015611273 0.96000015611273 0.96000015611273 0.96001764480948 0.96001764480948 0.96001764480948 0.96001764480948 0.96001764480948 0.96001764480948 0.96001764480948 0.96001764480948 0.96001764480948 0.96001764480942 0.96001764480884 0.96001764480673 0.96001764480496 0.96001764480673 0.96001764480884 0.96001764480942 0.96001764480948 0.96001764480948 0.96001764480948 0.96001764480948 0.96001764480948 0.96001764480948 0.96001764480948 0.96001764480948 0.96001764480948 0.96006279164586 0.96006279164586 0.96006279164586 0.96006279164586 0.96006279164586 0.96006279164586 0.96006279164586 0.96006279164586 0.96006279164581 0.96006279163295 0.96006279149437 0.96006279097683 0.96006279054534 0.96006279097683 0.96006279149437 0.96006279163295 0.96006279164581 0.96006279164586 0.96006279164586 0.96006279164586 0.96006279164586 0.96006279164586 0.96006279164586 0.96006279164586 0.96006279164586 0.96400989035802 0.96400989035802 0.96400989035802 0.96400989035802 0.96400989035802 0.96400989035802 0.96400989035801 0.96400989035804 0.96400989035652 0.96400989013945 0.96400988779989 0.96400987907136 0.96400987181106 0.96400987907136 0.96400988779989 0.96400989013945 0.96400989035652 0.96400989035804 0.96400989035801 0.96400989035802 0.96400989035802 0.96400989035802 0.96400989035802 0.96400989035802 0.96400989035802 0.96485606976477 0.96485606976477 0.96485606976477 0.96485606976477 0.96485606976477 0.96485606976477 0.96485606976478 0.96485606976476 0.96485606975791 0.96485606879102 0.96485605834299 0.96485601935399 0.96485598692712 0.96485601935399 0.96485605834299 0.96485606879102 0.96485606975791 0.96485606976476 0.96485606976478 0.96485606976477 0.96485606976477 0.96485606976477 0.96485606976477 0.96485606976477 0.96485606976477 0.96351313793838 0.96351313793838 0.96351313793838 0.96351313793838 0.96351313793838 0.96351313793837 0.96351313793839 0.9635131379383 0.96351313792819 0.96351313641333 0.96351312001869 0.963513058795 0.96351300786241 0.963513058795 0.96351312001869 0.96351313641333 0.96351313792819 0.9635131379383 0.96351313793839 0.96351313793837 0.96351313793838 0.96351313793838 0.96351313793838 0.96351313793838 0.96351313793838 0.96163554558384 0.96163554558384 0.96163554558384 0.96163554558384 0.96163554558384 0.96163554558383 0.96163554558384 0.96163554558385 0.96163554557755 0.96163554466832 0.96163553483201 0.96163549811157 0.96163546756308 0.96163549811157 0.96163553483201 0.96163554466832 0.96163554557755 0.96163554558385 0.96163554558384 0.96163554558383 0.96163554558384 0.96163554558384 0.96163554558384 0.96163554558384 0.96163554558384 0.96047642292959 0.96047642292959 0.96047642292959 0.96047642292959 0.96047642292959 0.96047642292959 0.96047642292959 0.96047642292961 0.96047642292822 0.96047642272307 0.96047642051116 0.96047641225836 0.96047640539179 0.96047641225836 0.96047642051116 0.96047642272307 0.96047642292822 0.96047642292961 0.96047642292959 0.96047642292959 0.96047642292959 0.96047642292959 0.96047642292959 0.96047642292959 0.96047642292959 0.9600895136462 0.9600895136462 0.9600895136462 0.9600895136462 0.9600895136462 0.9600895136462 0.9600895136462 0.9600895136462 0.9600895136461 0.96008951362844 0.9600895134387 0.96008951273172 0.96008951214295 0.96008951273172 0.9600895134387 0.96008951362844 0.9600895136461 0.9600895136462 0.9600895136462 0.9600895136462 0.9600895136462 0.9600895136462 0.9600895136462 0.9600895136462 0.9600895136462 0.96001112432289 0.96001112432289 0.96001112432289 0.96001112432289 0.96001112432289 0.96001112432289 0.96001112432289 0.96001112432289 0.96001112432289 0.96001112432276 0.96001112432141 0.96001112431642 0.96001112431228 0.96001112431642 0.96001112432141 0.96001112432276 0.96001112432289 0.96001112432289 0.96001112432289 0.96001112432289 0.96001112432289 0.96001112432289 0.96001112432289 0.96001112432289 0.96001112432289 0.96000091493657 0.96000091493657 0.96000091493657 0.96000091493657 0.96000091493657 0.96000091493657 0.96000091493657 0.96000091493657 0.96000091493657 0.96000091493657 0.96000091493655 0.96000091493648 0.96000091493643 0.96000091493648 0.96000091493655 0.96000091493657 0.96000091493657 0.96000091493657 0.96000091493657 0.96000091493657 0.96000091493657 0.96000091493657 0.96000091493657 0.96000091493657 0.96000091493657 0.96000005380412 0.96000005380412 0.96000005380412 0.96000005380412 0.96000005380412 0.96000005380412 0.96000005380412 0.96000005380412 0.96000005380412 0.96000005380412 0.96000005380412 0.96000005380412 0.96000005380411 0.96000005380412 0.96000005380412 0.96000005380412 0.96000005380412 0.96000005380412 0.96000005380412 0.96000005380412 0.96000005380412 0.96000005380412 0.96000005380412 0.96000005380412 0.96000005380412 0.96000000216497 0.96000000216497 0.96000000216497 0.96000000216497 0.96000000216497 0.96000000216497 0.96000000216497 0.96000000216497 0.96000000216497 0.96000000216497 0.96000000216497 0.96000000216497 0.96000000216497 0.96000000216497 0.96000000216497 0.96000000216497 0.96000000216497 0.96000000216497 0.96000000216497 0.96000000216497 0.96000000216497 0.96000000216497 0.96000000216497 0.96000000216497 0.96000000216497 0.96000000005184 0.96000000005184 0.96000000005184 0.96000000005184 0.96000000005184 0.96000000005184 0.96000000005184 0.96000000005184 0.96000000005184 0.96000000005184 0.96000000005184 0.96000000005184 0.96000000005184 0.96000000005184 0.96000000005184 0.96000000005184 0.96000000005184 0.96000000005184 0.96000000005184 0.96000000005184 0.96000000005184 0.96000000005184 0.96000000005184 0.96000000005184 0.96000000005184 0.96000000000113 0.96000000000113 0.96000000000113 0.96000000000113 0.96000000000113 0.96000000000113 0.96000000000113 0.96000000000113 0.96000000000113 0.96000000000113 0.96000000000113 0.96000000000113 0.96000000000113 0.96000000000113 0.96000000000113 0.96000000000113 0.96000000000113 0.96000000000113 0.96000000000113 0.96000000000113 0.96000000000113 0.96000000000113 0.96000000000113 0.96000000000113 0.96000000000113 0.95999999999986 0.95999999999986 0.95999999999986 0.95999999999986 0.95999999999986 0.95999999999986 0.95999999999986 0.95999999999986 0.95999999999986 0.95999999999986 0.95999999999986 0.95999999999986 0.95999999999986 0.95999999999986 0.95999999999986 0.95999999999986 0.95999999999986 0.95999999999986 0.95999999999986 0.95999999999986 0.95999999999986 0.95999999999986 0.95999999999986 0.95999999999986 0.95999999999986 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.95999999999994 0.95999999999994 0.95999999999994 0.95999999999994 0.95999999999994 0.95999999999994 0.95999999999994 0.95999999999994 0.95999999999994 0.95999999999994 0.95999999999994 0.95999999999994 0.95999999999994 0.95999999999994 0.95999999999994 0.95999999999994 0.95999999999994 0.95999999999994 0.95999999999994 0.95999999999994 0.95999999999994 0.95999999999994 0.95999999999994 0.95999999999994 0.95999999999994 0.96000000000048 0.96000000000048 0.96000000000048 0.96000000000048 0.96000000000048 0.96000000000048 0.96000000000048 0.96000000000048 0.96000000000048 0.96000000000048 0.96000000000048 0.96000000000048 0.96000000000048 0.96000000000048 0.96000000000048 0.96000000000048 0.96000000000048 0.96000000000048 0.96000000000048 0.96000000000048 0.96000000000048 0.96000000000048 0.96000000000048 0.96000000000048 0.96000000000048 0.96000000004002 0.96000000004002 0.96000000004002 0.96000000004002 0.96000000004002 0.96000000004002 0.96000000004002 0.96000000004002 0.96000000004002 0.96000000004002 0.96000000004002 0.96000000004002 0.96000000004002 0.96000000004002 0.96000000004002 0.96000000004002 0.96000000004002 0.96000000004002 0.96000000004002 0.96000000004002 0.96000000004002 0.96000000004002 0.96000000004002 0.96000000004002 0.96000000004002 0.96000000333307 0.96000000333307 0.96000000333307 0.96000000333307 0.96000000333307 0.96000000333307 0.96000000333307 0.96000000333307 0.96000000333307 0.96000000333307 0.96000000333307 0.96000000333306 0.96000000333306 0.96000000333306 0.96000000333307 0.96000000333307 0.96000000333307 0.96000000333307 0.96000000333307 0.96000000333307 0.96000000333307 0.96000000333307 0.96000000333307 0.96000000333307 0.96000000333307 0.96000032143279 0.96000032143279 0.96000032143279 0.96000032143279 0.96000032143279 0.96000032143279 0.96000032143279 0.96000032143279 0.96000032143279 0.96000032143278 0.96000032143268 0.96000032143232 0.96000032143201 0.96000032143232 0.96000032143268 0.96000032143278 0.96000032143279 0.96000032143279 0.96000032143279 0.96000032143279 0.96000032143279 0.96000032143279 0.96000032143279 0.96000032143279 0.96000032143279 0.96000308149917 0.96000308149917 0.96000308149917 0.96000308149917 0.96000308149917 0.96000308149917 0.96000308149916 0.96000308149917 0.96000308149916 0.96000308149771 0.96000308148218 0.96000308142432 0.96000308137613 0.96000308142432 0.96000308148218 0.96000308149771 0.96000308149916 0.96000308149917 0.96000308149916 0.96000308149917 0.96000308149917 0.96000308149917 0.96000308149917 0.96000308149917 0.96000308149917 0.96017194993358 0.96017194993358 0.96017194993358 0.96017194993358 0.96017194993358 0.96017194993358 0.96017194993358 0.96017194993358 0.96017194993357 0.96017194992391 0.96017194981823 0.96017194942076 0.96017194908906 0.96017194942076 0.96017194981823 0.96017194992391 0.96017194993357 0.96017194993358 0.96017194993358 0.96017194993358 0.96017194993358 0.96017194993358 0.96017194993358 0.96017194993358 0.96017194993358 0.96391155244328 0.96391155244328 0.96391155244328 0.96391155244328 0.96391155244328 0.96391155244328 0.96391155244328 0.96391155244328 0.96391155244324 0.96391155239908 0.9639115519151 0.96391155009172 0.9639115485704 0.96391155009172 0.9639115519151 0.96391155239908 0.96391155244324 0.96391155244328 0.96391155244328 0.96391155244328 0.96391155244328 0.96391155244328 0.96391155244328 0.96391155244328 0.96391155244328 0.96224311853402 0.96224311853402 0.96224311853402 0.96224311853402 0.96224311853402 0.96224311853402 0.96224311853402 0.96224311853403 0.96224311853335 0.96224311841748 0.96224311716783 0.9622431125003 0.96224310861581 0.9622431125003 0.96224311716783 0.96224311841748 0.96224311853335 0.96224311853403 0.96224311853402 0.96224311853402 0.96224311853402 0.96224311853402 0.96224311853402 0.96224311853402 0.96224311853402 0.96078380667 0.96078380667 0.96078380667 0.96078380667 0.96078380667 0.96078380667 0.96078380667 0.96078380667 0.9607838066696 0.96078380659643 0.96078380580856 0.96078380286718 0.9607838004182 0.96078380286718 0.96078380580856 0.96078380659643 0.9607838066696 0.96078380667 0.96078380667 0.96078380667 0.96078380667 0.96078380667 0.96078380667 0.96078380667 0.96078380667 0.9601705079647 0.9601705079647 0.9601705079647 0.9601705079647 0.9601705079647 0.9601705079647 0.9601705079647 0.9601705079647 0.96017050796461 0.96017050794711 0.96017050775915 0.96017050705865 0.96017050647523 0.96017050705865 0.96017050775915 0.96017050794711 0.96017050796461 0.9601705079647 0.9601705079647 0.9601705079647 0.9601705079647 0.9601705079647 0.9601705079647 0.9601705079647 0.9601705079647 0.96002464093767 0.96002464093767 0.96002464093767 0.96002464093767 0.96002464093767 0.96002464093767 0.96002464093767 0.96002464093767 0.96002464093766 0.96002464093612 0.96002464091957 0.96002464085794 0.96002464080663 0.96002464085794 0.96002464091957 0.96002464093612 0.96002464093766 0.96002464093767 0.96002464093767 0.96002464093767 0.96002464093767 0.96002464093767 0.96002464093767 0.96002464093767 0.96002464093767 0.96000234110585 0.96000234110585 0.96000234110585 0.96000234110585 0.96000234110585 0.96000234110585 0.96000234110585 0.96000234110585 0.96000234110585 0.96000234110584 0.96000234110572 0.96000234110529 0.96000234110492 0.96000234110529 0.96000234110572 0.96000234110584 0.96000234110585 0.96000234110585 0.96000234110585 0.96000234110585 0.96000234110585 0.96000234110585 0.96000234110585 0.96000234110585 0.96000234110585 0.96000014892106 0.96000014892106 0.96000014892106 0.96000014892106 0.96000014892106 0.96000014892106 0.96000014892106 0.96000014892106 0.96000014892106 0.96000014892106 0.96000014892106 0.96000014892105 0.96000014892105 0.96000014892105 0.96000014892106 0.96000014892106 0.96000014892106 0.96000014892106 0.96000014892106 0.96000014892106 0.96000014892106 0.96000014892106 0.96000014892106 0.96000014892106 0.96000014892106 0.9600000065405 0.9600000065405 0.9600000065405 0.9600000065405 0.9600000065405 0.9600000065405 0.9600000065405 0.9600000065405 0.9600000065405 0.9600000065405 0.9600000065405 0.9600000065405 0.9600000065405 0.9600000065405 0.9600000065405 0.9600000065405 0.9600000065405 0.9600000065405 0.9600000065405 0.9600000065405 0.9600000065405 0.9600000065405 0.9600000065405 0.9600000065405 0.9600000065405 0.96000000020369 0.96000000020369 0.96000000020369 0.96000000020369 0.96000000020369 0.96000000020369 0.96000000020369 0.96000000020369 0.96000000020369 0.96000000020369 0.96000000020369 0.96000000020369 0.96000000020369 0.96000000020369 0.96000000020369 0.96000000020369 0.96000000020369 0.96000000020369 0.96000000020369 0.96000000020369 0.96000000020369 0.96000000020369 0.96000000020369 0.96000000020369 0.96000000020369 0.96000000000543 0.96000000000543 0.96000000000543 0.96000000000543 0.96000000000543 0.96000000000543 0.96000000000543 0.96000000000543 0.96000000000543 0.96000000000543 0.96000000000543 0.96000000000543 0.96000000000543 0.96000000000543 0.96000000000543 0.96000000000543 0.96000000000543 0.96000000000543 0.96000000000543 0.96000000000543 0.96000000000543 0.96000000000543 0.96000000000543 0.96000000000543 0.96000000000543 0.95999999999992 0.95999999999992 0.95999999999992 0.95999999999992 0.95999999999992 0.95999999999992 0.95999999999992 0.95999999999992 0.95999999999992 0.95999999999992 0.95999999999992 0.95999999999992 0.95999999999992 0.95999999999992 0.95999999999992 0.95999999999992 0.95999999999992 0.95999999999992 0.95999999999992 0.95999999999992 0.95999999999992 0.95999999999992 0.95999999999992 0.95999999999992 0.95999999999992 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.9600000000006 0.9600000000006 0.9600000000006 0.9600000000006 0.9600000000006 0.9600000000006 0.9600000000006 0.9600000000006 0.9600000000006 0.9600000000006 0.9600000000006 0.9600000000006 0.9600000000006 0.9600000000006 0.9600000000006 0.9600000000006 0.9600000000006 0.9600000000006 0.9600000000006 0.9600000000006 0.9600000000006 0.9600000000006 0.9600000000006 0.9600000000006 0.9600000000006 0.96000000005181 0.96000000005181 0.96000000005181 0.96000000005181 0.96000000005181 0.96000000005181 0.96000000005181 0.96000000005181 0.96000000005181 0.96000000005181 0.96000000005181 0.96000000005181 0.96000000005181 0.96000000005181 0.96000000005181 0.96000000005181 0.96000000005181 0.96000000005181 0.96000000005181 0.96000000005181 0.96000000005181 0.96000000005181 0.96000000005181 0.96000000005181 0.96000000005181 0.96000000471331 0.96000000471331 0.96000000471331 0.96000000471331 0.96000000471331 0.96000000471331 0.96000000471331 0.96000000471331 0.96000000471331 0.96000000471331 0.96000000471331 0.9600000047133 0.9600000047133 0.9600000047133 0.96000000471331 0.96000000471331 0.96000000471331 0.96000000471331 0.96000000471331 0.96000000471331 0.96000000471331 0.96000000471331 0.96000000471331 0.96000000471331 0.96000000471331 0.96000009639196 0.96000009639196 0.96000009639196 0.96000009639196 0.96000009639196 0.96000009639196 0.96000009639196 0.96000009639196 0.96000009639196 0.96000009639195 0.96000009639181 0.9600000963913 0.96000009639088 0.9600000963913 0.96000009639181 0.96000009639195 0.96000009639196 0.96000009639196 0.96000009639196 0.96000009639196 0.96000009639196 0.96000009639196 0.96000009639196 0.96000009639196 0.96000009639196 0.96000622376079 0.96000622376079 0.96000622376079 0.96000622376079 0.96000622376079 0.96000622376079 0.96000622376079 0.96000622376079 0.96000622376078 0.96000622376058 0.96000622375841 0.9600062237505 0.96000622374392 0.9600062237505 0.96000622375841 0.96000622376058 0.96000622376078 0.96000622376079 0.96000622376079 0.96000622376079 0.96000622376079 0.96000622376079 0.96000622376079 0.96000622376079 0.96000622376079 0.96013879588321 0.96013879588321 0.96013879588321 0.96013879588321 0.96013879588321 0.96013879588321 0.96013879588321 0.96013879588321 0.96013879588308 0.96013879587095 0.96013879574464 0.96013879528095 0.96013879489543 0.96013879528095 0.96013879574464 0.96013879587095 0.96013879588308 0.96013879588321 0.96013879588321 0.96013879588321 0.96013879588321 0.96013879588321 0.96013879588321 0.96013879588321 0.96013879588321 0.96006476986403 0.96006476986403 0.96006476986403 0.96006476986403 0.96006476986403 0.96006476986403 0.96006476986403 0.96006476986403 0.96006476986392 0.96006476985413 0.96006476975191 0.96006476937608 0.96006476906349 0.96006476937608 0.96006476975191 0.96006476985413 0.96006476986392 0.96006476986403 0.96006476986403 0.96006476986403 0.96006476986403 0.96006476986403 0.96006476986403 0.96006476986403 0.96006476986403 0.96027520928189 0.96027520928189 0.96027520928189 0.96027520928189 0.96027520928189 0.96027520928189 0.96027520928189 0.96027520928189 0.96027520928189 0.96027520928145 0.96027520927704 0.96027520926098 0.96027520924764 0.96027520926098 0.96027520927704 0.96027520928145 0.96027520928189 0.96027520928189 0.96027520928189 0.96027520928189 0.96027520928189 0.96027520928189 0.96027520928189 0.96027520928189 0.96027520928189 0.96005494775729 0.96005494775729 0.96005494775729 0.96005494775729 0.96005494775729 0.96005494775729 0.96005494775729 0.96005494775729 0.96005494775729 0.96005494775717 0.96005494775593 0.96005494775135 0.96005494774755 0.96005494775135 0.96005494775593 0.96005494775717 0.96005494775729 0.96005494775729 0.96005494775729 0.96005494775729 0.96005494775729 0.96005494775729 0.96005494775729 0.96005494775729 0.96005494775729 0.96000571977412 0.96000571977412 0.96000571977412 0.96000571977412 0.96000571977412 0.96000571977412 0.96000571977412 0.96000571977412 0.96000571977412 0.96000571977411 0.96000571977396 0.96000571977341 0.96000571977296 0.96000571977341 0.96000571977396 0.96000571977411 0.96000571977412 0.96000571977412 0.96000571977412 0.96000571977412 0.96000571977412 0.96000571977412 0.96000571977412 0.96000571977412 0.96000571977412 0.96000041848693 0.96000041848693 0.96000041848693 0.96000041848693 0.96000041848693 0.96000041848693 0.96000041848693 0.96000041848693 0.96000041848693 0.96000041848693 0.96000041848692 0.96000041848692 0.96000041848691 0.96000041848692 0.96000041848692 0.96000041848693 0.96000041848693 0.96000041848693 0.96000041848693 0.96000041848693 0.96000041848693 0.96000041848693 0.96000041848693 0.96000041848693 0.96000041848693 0.96000002077145 0.96000002077145 0.96000002077145 0.96000002077145 0.96000002077145 0.96000002077145 0.96000002077145 0.96000002077145 0.96000002077145 0.96000002077145 0.96000002077145 0.96000002077145 0.96000002077145 0.96000002077145 0.96000002077145 0.96000002077145 0.96000002077145 0.96000002077145 0.96000002077145 0.96000002077145 0.96000002077145 0.96000002077145 0.96000002077145 0.96000002077145 0.96000002077145 0.96000000072415 0.96000000072415 0.96000000072415 0.96000000072415 0.96000000072415 0.96000000072415 0.96000000072415 0.96000000072415 0.96000000072415 0.96000000072415 0.96000000072415 0.96000000072415 0.96000000072415 0.96000000072415 0.96000000072415 0.96000000072415 0.96000000072415 0.96000000072415 0.96000000072415 0.96000000072415 0.96000000072415 0.96000000072415 0.96000000072415 0.96000000072415 0.96000000072415 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000000027 0.96000000000027 0.96000000000027 0.96000000000027 0.96000000000027 0.96000000000027 0.96000000000027 0.96000000000027 0.96000000000027 0.96000000000027 0.96000000000027 0.96000000000027 0.96000000000027 0.96000000000027 0.96000000000027 0.96000000000027 0.96000000000027 0.96000000000027 0.96000000000027 0.96000000000027 0.96000000000027 0.96000000000027 0.96000000000027 0.96000000000027 0.96000000000027 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000005445 0.96000000005445 0.96000000005445 0.96000000005445 0.96000000005445 0.96000000005445 0.96000000005445 0.96000000005445 0.96000000005445 0.96000000005445 0.96000000005445 0.96000000005445 0.96000000005445 0.96000000005445 0.96000000005445 0.96000000005445 0.96000000005445 0.96000000005445 0.96000000005445 0.96000000005445 0.96000000005445 0.96000000005445 0.96000000005445 0.96000000005445 0.96000000005445 0.96000000142375 0.96000000142375 0.96000000142375 0.96000000142375 0.96000000142375 0.96000000142375 0.96000000142375 0.96000000142375 0.96000000142375 0.96000000142375 0.96000000142374 0.96000000142374 0.96000000142373 0.96000000142374 0.96000000142374 0.96000000142375 0.96000000142375 0.96000000142375 0.96000000142375 0.96000000142375 0.96000000142375 0.96000000142375 0.96000000142375 0.96000000142375 0.96000000142375 0.96000009370674 0.96000009370674 0.96000009370674 0.96000009370674 0.96000009370674 0.96000009370674 0.96000009370674 0.96000009370674 0.96000009370674 0.96000009370673 0.9600000937067 0.9600000937066 0.96000009370651 0.9600000937066 0.9600000937067 0.96000009370673 0.96000009370674 0.96000009370674 0.96000009370674 0.96000009370674 0.96000009370674 0.96000009370674 0.96000009370674 0.96000009370674 0.96000009370674 0.96000254523862 0.96000254523862 0.96000254523862 0.96000254523862 0.96000254523862 0.96000254523862 0.96000254523862 0.96000254523862 0.96000254523862 0.96000254523842 0.9600025452363 0.96000254522849 0.96000254522198 0.96000254522849 0.9600025452363 0.96000254523842 0.96000254523862 0.96000254523862 0.96000254523862 0.96000254523862 0.96000254523862 0.96000254523862 0.96000254523862 0.96000254523862 0.96000254523862 0.96000117610763 0.96000117610763 0.96000117610763 0.96000117610763 0.96000117610763 0.96000117610763 0.96000117610763 0.96000117610763 0.96000117610763 0.96000117610752 0.96000117610631 0.96000117610187 0.96000117609818 0.96000117610187 0.96000117610631 0.96000117610752 0.96000117610763 0.96000117610763 0.96000117610763 0.96000117610763 0.96000117610763 0.96000117610763 0.96000117610763 0.96000117610763 0.96000117610763 0.96000524478499 0.96000524478499 0.96000524478499 0.96000524478499 0.96000524478499 0.96000524478499 0.96000524478499 0.96000524478499 0.96000524478499 0.96000524478493 0.96000524478429 0.96000524478192 0.96000524477994 0.96000524478192 0.96000524478429 0.96000524478493 0.96000524478499 0.96000524478499 0.96000524478499 0.96000524478499 0.96000524478499 0.96000524478499 0.96000524478499 0.96000524478499 0.96000524478499 0.96000087573747 0.96000087573747 0.96000087573747 0.96000087573747 0.96000087573747 0.96000087573747 0.96000087573747 0.96000087573747 0.96000087573747 0.9600008757375 0.96000087573786 0.9600008757392 0.96000087574031 0.9600008757392 0.96000087573786 0.9600008757375 0.96000087573747 0.96000087573747 0.96000087573747 0.96000087573747 0.96000087573747 0.96000087573747 0.96000087573747 0.96000087573747 0.96000087573747 0.96000085120187 0.96000085120187 0.96000085120187 0.96000085120187 0.96000085120187 0.96000085120187 0.96000085120187 0.96000085120187 0.96000085120187 0.96000085120187 0.96000085120186 0.96000085120185 0.96000085120184 0.96000085120185 0.96000085120186 0.96000085120187 0.96000085120187 0.96000085120187 0.96000085120187 0.96000085120187 0.96000085120187 0.96000085120187 0.96000085120187 0.96000085120187 0.96000085120187 0.96000007393657 0.96000007393657 0.96000007393657 0.96000007393657 0.96000007393657 0.96000007393657 0.96000007393657 0.96000007393657 0.96000007393657 0.96000007393657 0.96000007393657 0.96000007393657 0.96000007393657 0.96000007393657 0.96000007393657 0.96000007393657 0.96000007393657 0.96000007393657 0.96000007393657 0.96000007393657 0.96000007393657 0.96000007393657 0.96000007393657 0.96000007393657 0.96000007393657 0.96000000267574 0.96000000267574 0.96000000267574 0.96000000267574 0.96000000267574 0.96000000267574 0.96000000267574 0.96000000267574 0.96000000267574 0.96000000267574 0.96000000267574 0.96000000267574 0.96000000267574 0.96000000267574 0.96000000267574 0.96000000267574 0.96000000267574 0.96000000267574 0.96000000267574 0.96000000267574 0.96000000267574 0.96000000267574 0.96000000267574 0.96000000267574 0.96000000267574 0.96000000007354 0.96000000007354 0.96000000007354 0.96000000007354 0.96000000007354 0.96000000007354 0.96000000007354 0.96000000007354 0.96000000007354 0.96000000007354 0.96000000007354 0.96000000007354 0.96000000007354 0.96000000007354 0.96000000007354 0.96000000007354 0.96000000007354 0.96000000007354 0.96000000007354 0.96000000007354 0.96000000007354 0.96000000007354 0.96000000007354 0.96000000007354 0.96000000007354 0.96000000000181 0.96000000000181 0.96000000000181 0.96000000000181 0.96000000000181 0.96000000000181 0.96000000000181 0.96000000000181 0.96000000000181 0.96000000000181 0.96000000000181 0.96000000000181 0.96000000000181 0.96000000000181 0.96000000000181 0.96000000000181 0.96000000000181 0.96000000000181 0.96000000000181 0.96000000000181 0.96000000000181 0.96000000000181 0.96000000000181 0.96000000000181 0.96000000000181 0.95999999999985 0.95999999999985 0.95999999999985 0.95999999999985 0.95999999999985 0.95999999999985 0.95999999999985 0.95999999999985 0.95999999999985 0.95999999999985 0.95999999999985 0.95999999999985 0.95999999999985 0.95999999999985 0.95999999999985 0.95999999999985 0.95999999999985 0.95999999999985 0.95999999999985 0.95999999999985 0.95999999999985 0.95999999999985 0.95999999999985 0.95999999999985 0.95999999999985 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.96000000000058 0.96000000000058 0.96000000000058 0.96000000000058 0.96000000000058 0.96000000000058 0.96000000000058 0.96000000000058 0.96000000000058 0.96000000000058 0.96000000000058 0.96000000000058 0.96000000000058 0.96000000000058 0.96000000000058 0.96000000000058 0.96000000000058 0.96000000000058 0.96000000000058 0.96000000000058 0.96000000000058 0.96000000000058 0.96000000000058 0.96000000000058 0.96000000000058 0.96000000001744 0.96000000001744 0.96000000001744 0.96000000001744 0.96000000001744 0.96000000001744 0.96000000001744 0.96000000001744 0.96000000001744 0.96000000001744 0.96000000001744 0.96000000001744 0.96000000001744 0.96000000001744 0.96000000001744 0.96000000001744 0.96000000001744 0.96000000001744 0.96000000001744 0.96000000001744 0.96000000001744 0.96000000001744 0.96000000001744 0.96000000001744 0.96000000001744 0.96000000114058 0.96000000114058 0.96000000114058 0.96000000114058 0.96000000114058 0.96000000114058 0.96000000114058 0.96000000114058 0.96000000114058 0.96000000114058 0.96000000114058 0.96000000114057 0.96000000114057 0.96000000114057 0.96000000114058 0.96000000114058 0.96000000114058 0.96000000114058 0.96000000114058 0.96000000114058 0.96000000114058 0.96000000114058 0.96000000114058 0.96000000114058 0.96000000114058 0.9600000318752 0.9600000318752 0.9600000318752 0.9600000318752 0.9600000318752 0.9600000318752 0.9600000318752 0.9600000318752 0.9600000318752 0.96000003187519 0.96000003187517 0.9600000318751 0.96000003187504 0.9600000318751 0.96000003187517 0.96000003187519 0.9600000318752 0.9600000318752 0.9600000318752 0.9600000318752 0.9600000318752 0.9600000318752 0.9600000318752 0.9600000318752 0.9600000318752 0.96000001538587 0.96000001538587 0.96000001538587 0.96000001538587 0.96000001538587 0.96000001538587 0.96000001538587 0.96000001538587 0.96000001538587 0.96000001538587 0.96000001538586 0.96000001538582 0.96000001538579 0.96000001538582 0.96000001538586 0.96000001538587 0.96000001538587 0.96000001538587 0.96000001538587 0.96000001538587 0.96000001538587 0.96000001538587 0.96000001538587 0.96000001538587 0.96000001538587 0.96000008339363 0.96000008339363 0.96000008339363 0.96000008339363 0.96000008339363 0.96000008339363 0.96000008339363 0.96000008339363 0.96000008339363 0.96000008339363 0.96000008339363 0.96000008339362 0.96000008339361 0.96000008339362 0.96000008339363 0.96000008339363 0.96000008339363 0.96000008339363 0.96000008339363 0.96000008339363 0.96000008339363 0.96000008339363 0.96000008339363 0.96000008339363 0.96000008339363 0.96000001383394 0.96000001383394 0.96000001383394 0.96000001383394 0.96000001383394 0.96000001383394 0.96000001383394 0.96000001383394 0.96000001383394 0.96000001383394 0.96000001383395 0.96000001383396 0.96000001383397 0.96000001383396 0.96000001383395 0.96000001383394 0.96000001383394 0.96000001383394 0.96000001383394 0.96000001383394 0.96000001383394 0.96000001383394 0.96000001383394 0.96000001383394 0.96000001383394 0.96000001361022 0.96000001361022 0.96000001361022 0.96000001361022 0.96000001361022 0.96000001361022 0.96000001361022 0.96000001361022 0.96000001361022 0.96000001361022 0.96000001361022 0.96000001361022 0.96000001361022 0.96000001361022 0.96000001361022 0.96000001361022 0.96000001361022 0.96000001361022 0.96000001361022 0.96000001361022 0.96000001361022 0.96000001361022 0.96000001361022 0.96000001361022 0.96000001361022 0.96000000508758 0.96000000508758 0.96000000508758 0.96000000508758 0.96000000508758 0.96000000508758 0.96000000508758 0.96000000508758 0.96000000508758 0.96000000508758 0.96000000508758 0.96000000508758 0.96000000508758 0.96000000508758 0.96000000508758 0.96000000508758 0.96000000508758 0.96000000508758 0.96000000508758 0.96000000508758 0.96000000508758 0.96000000508758 0.96000000508758 0.96000000508758 0.96000000508758 0.96000000027613 0.96000000027613 0.96000000027613 0.96000000027613 0.96000000027613 0.96000000027613 0.96000000027613 0.96000000027613 0.96000000027613 0.96000000027613 0.96000000027613 0.96000000027613 0.96000000027613 0.96000000027613 0.96000000027613 0.96000000027613 0.96000000027613 0.96000000027613 0.96000000027613 0.96000000027613 0.96000000027613 0.96000000027613 0.96000000027613 0.96000000027613 0.96000000027613 0.96000000000723 0.96000000000723 0.96000000000723 0.96000000000723 0.96000000000723 0.96000000000723 0.96000000000723 0.96000000000723 0.96000000000723 0.96000000000723 0.96000000000723 0.96000000000723 0.96000000000723 0.96000000000723 0.96000000000723 0.96000000000723 0.96000000000723 0.96000000000723 0.96000000000723 0.96000000000723 0.96000000000723 0.96000000000723 0.96000000000723 0.96000000000723 0.96000000000723 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.96000000000014 0.96000000000014 0.96000000000014 0.96000000000014 0.96000000000014 0.96000000000014 0.96000000000014 0.96000000000014 0.96000000000014 0.96000000000014 0.96000000000014 0.96000000000014 0.96000000000014 0.96000000000014 0.96000000000014 0.96000000000014 0.96000000000014 0.96000000000014 0.96000000000014 0.96000000000014 0.96000000000014 0.96000000000014 0.96000000000014 0.96000000000014 0.96000000000014 0.96000000001185 0.96000000001185 0.96000000001185 0.96000000001185 0.96000000001185 0.96000000001185 0.96000000001185 0.96000000001185 0.96000000001185 0.96000000001185 0.96000000001185 0.96000000001185 0.96000000001185 0.96000000001185 0.96000000001185 0.96000000001185 0.96000000001185 0.96000000001185 0.96000000001185 0.96000000001185 0.96000000001185 0.96000000001185 0.96000000001185 0.96000000001185 0.96000000001185 0.96000000033252 0.96000000033252 0.96000000033252 0.96000000033252 0.96000000033252 0.96000000033252 0.96000000033252 0.96000000033252 0.96000000033252 0.96000000033252 0.96000000033252 0.96000000033252 0.96000000033252 0.96000000033252 0.96000000033252 0.96000000033252 0.96000000033252 0.96000000033252 0.96000000033252 0.96000000033252 0.96000000033252 0.96000000033252 0.96000000033252 0.96000000033252 0.96000000033252 0.9600000001676 0.9600000001676 0.9600000001676 0.9600000001676 0.9600000001676 0.9600000001676 0.9600000001676 0.9600000001676 0.9600000001676 0.9600000001676 0.9600000001676 0.9600000001676 0.9600000001676 0.9600000001676 0.9600000001676 0.9600000001676 0.9600000001676 0.9600000001676 0.9600000001676 0.9600000001676 0.9600000001676 0.9600000001676 0.9600000001676 0.9600000001676 0.9600000001676 0.96000000105006 0.96000000105006 0.96000000105006 0.96000000105006 0.96000000105006 0.96000000105006 0.96000000105006 0.96000000105006 0.96000000105006 0.96000000105006 0.96000000105006 0.96000000105006 0.96000000105006 0.96000000105006 0.96000000105006 0.96000000105006 0.96000000105006 0.96000000105006 0.96000000105006 0.96000000105006 0.96000000105006 0.96000000105006 0.96000000105006 0.96000000105006 0.96000000105006 0.96000000017454 0.96000000017454 0.96000000017454 0.96000000017454 0.96000000017454 0.96000000017454 0.96000000017454 0.96000000017454 0.96000000017454 0.96000000017454 0.96000000017454 0.96000000017454 0.96000000017454 0.96000000017454 0.96000000017454 0.96000000017454 0.96000000017454 0.96000000017454 0.96000000017454 0.96000000017454 0.96000000017454 0.96000000017454 0.96000000017454 0.96000000017454 0.96000000017454 0.96000000021066 0.96000000021066 0.96000000021066 0.96000000021066 0.96000000021066 0.96000000021066 0.96000000021066 0.96000000021066 0.96000000021066 0.96000000021066 0.96000000021066 0.96000000021066 0.96000000021066 0.96000000021066 0.96000000021066 0.96000000021066 0.96000000021066 0.96000000021066 0.96000000021066 0.96000000021066 0.96000000021066 0.96000000021066 0.96000000021066 0.96000000021066 0.96000000021066 0.96000000008263 0.96000000008263 0.96000000008263 0.96000000008263 0.96000000008263 0.96000000008263 0.96000000008263 0.96000000008263 0.96000000008263 0.96000000008263 0.96000000008263 0.96000000008263 0.96000000008263 0.96000000008263 0.96000000008263 0.96000000008263 0.96000000008263 0.96000000008263 0.96000000008263 0.96000000008263 0.96000000008263 0.96000000008263 0.96000000008263 0.96000000008263 0.96000000008263 0.96000000000466 0.96000000000466 0.96000000000466 0.96000000000466 0.96000000000466 0.96000000000466 0.96000000000466 0.96000000000466 0.96000000000466 0.96000000000466 0.96000000000466 0.96000000000466 0.96000000000466 0.96000000000466 0.96000000000466 0.96000000000466 0.96000000000466 0.96000000000466 0.96000000000466 0.96000000000466 0.96000000000466 0.96000000000466 0.96000000000466 0.96000000000466 0.96000000000466 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000325 0.96000000000325 0.96000000000325 0.96000000000325 0.96000000000325 0.96000000000325 0.96000000000325 0.96000000000325 0.96000000000325 0.96000000000325 0.96000000000325 0.96000000000325 0.96000000000325 0.96000000000325 0.96000000000325 0.96000000000325 0.96000000000325 0.96000000000325 0.96000000000325 0.96000000000325 0.96000000000325 0.96000000000325 0.96000000000325 0.96000000000325 0.96000000000325 0.96000000000187 0.96000000000187 0.96000000000187 0.96000000000187 0.96000000000187 0.96000000000187 0.96000000000187 0.96000000000187 0.96000000000187 0.96000000000187 0.96000000000187 0.96000000000187 0.96000000000187 0.96000000000187 0.96000000000187 0.96000000000187 0.96000000000187 0.96000000000187 0.96000000000187 0.96000000000187 0.96000000000187 0.96000000000187 0.96000000000187 0.96000000000187 0.96000000000187 0.96000000001122 0.96000000001122 0.96000000001122 0.96000000001122 0.96000000001122 0.96000000001122 0.96000000001122 0.96000000001122 0.96000000001122 0.96000000001122 0.96000000001122 0.96000000001122 0.96000000001122 0.96000000001122 0.96000000001122 0.96000000001122 0.96000000001122 0.96000000001122 0.96000000001122 0.96000000001122 0.96000000001122 0.96000000001122 0.96000000001122 0.96000000001122 0.96000000001122 0.96000000000219 0.96000000000219 0.96000000000219 0.96000000000219 0.96000000000219 0.96000000000219 0.96000000000219 0.96000000000219 0.96000000000219 0.96000000000219 0.96000000000219 0.96000000000219 0.96000000000219 0.96000000000219 0.96000000000219 0.96000000000219 0.96000000000219 0.96000000000219 0.96000000000219 0.96000000000219 0.96000000000219 0.96000000000219 0.96000000000219 0.96000000000219 0.96000000000219 0.96000000000302 0.96000000000302 0.96000000000302 0.96000000000302 0.96000000000302 0.96000000000302 0.96000000000302 0.96000000000302 0.96000000000302 0.96000000000302 0.96000000000302 0.96000000000302 0.96000000000302 0.96000000000302 0.96000000000302 0.96000000000302 0.96000000000302 0.96000000000302 0.96000000000302 0.96000000000302 0.96000000000302 0.96000000000302 0.96000000000302 0.96000000000302 0.96000000000302 0.9600000000017 0.9600000000017 0.9600000000017 0.9600000000017 0.9600000000017 0.9600000000017 0.9600000000017 0.9600000000017 0.9600000000017 0.9600000000017 0.9600000000017 0.9600000000017 0.9600000000017 0.9600000000017 0.9600000000017 0.9600000000017 0.9600000000017 0.9600000000017 0.9600000000017 0.9600000000017 0.9600000000017 0.9600000000017 0.9600000000017 0.9600000000017 0.9600000000017 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999984 0.95999999999984 0.95999999999984 0.95999999999984 0.95999999999984 0.95999999999984 0.95999999999984 0.95999999999984 0.95999999999984 0.95999999999984 0.95999999999984 0.95999999999984 0.95999999999984 0.95999999999984 0.95999999999984 0.95999999999984 0.95999999999984 0.95999999999984 0.95999999999984 0.95999999999984 0.95999999999984 0.95999999999984 0.95999999999984 0.95999999999984 0.95999999999984 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 D/cons.2.00.000000.dat 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 @@ -17,4 +17,4 @@ D/cons.8.00.000000.dat 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0 D/cons.8.00.000050.dat 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 D/lag_bubble_evol_0.dat 0.0 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832988093882 0.008 0.0 1.0001782913460961 0.0 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832988093882 0.008 0.0 1.0001782913460961 1e-06 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832988093882 0.0079999999991335 -2.5998347812e-06 1.000178291800741 2e-06 1.0 0.5 0.5 0.5 3.64821e-11 0.014383298809388 0.0079999999922017 -1.29983238775e-05 1.0001782954379947 3e-06 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832988093872 0.0079999999688074 -3.63926994597e-05 1.000178307713318 4e-06 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832988093845 0.0079999999133575 -7.79781479331e-05 1.0001783368087096 5e-06 1.0 0.5 0.5 0.5 3.64821e-11 0.014383298809378 0.0079999998050647 -0.0001429472756538 1.0001783936314923 6e-06 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832988093644 0.0079999996179508 -0.0002364894691138 1.0001784918127927 7e-06 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832988093391 0.00799999932085 -0.0003637901198454 1.0001786477056553 8e-06 1.0 0.5 0.5 0.5 3.64821e-11 0.014383298809296 0.0079999988774137 -0.0005300296841069 1.0001788803827116 9e-06 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832988092268 0.0079999982461156 -0.000740382547164 1.0001792116333146 1e-05 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832988091214 0.0079999973802587 -0.0010000156616928 1.0001796659600262 1.1e-05 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832988089671 0.0079999962279833 -0.0013140869294889 1.0001802705743383 1.2e-05 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832988087485 0.0079999947322772 -0.0016877432952982 1.0001810553914838 1.3e-05 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832988084475 0.0079999928309878 -0.0021261185211773 1.0001820530241825 1.4e-05 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832988080425 0.007999990456836 -0.002634330609384 1.0001832987751504 1.5e-05 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832988075089 0.0079999875374341 -0.0032174788413769 1.0001848306281818 1.6e-05 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832988068183 0.0079999839953059 -0.0038806404001024 1.0001866892375992 1.7e-05 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832988059382 0.0079999797479105 -0.0046288665423713 1.0001889179158479 1.8e-05 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832988048322 0.0079999747076704 -0.0054671782877993 1.0001915626189932 1.9e-05 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832988034595 0.0079999687820044 -0.0064005615905186 1.0001946719298669 2e-05 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832988017745 0.007999961873365 -0.007433961959695 1.0001982970385817 2.1e-05 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832987997269 0.0079999538792819 -0.0085722784948069 1.000202491720126 2.2e-05 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832987972612 0.0079999446924115 -0.0098203573017131 1.0002073123087254 2.3e-05 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832987943166 0.0079999342005938 -0.0111829842557531 1.000212817668644 2.4e-05 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832987908266 0.007999922286916 -0.0126648770785396 1.0002190691610786 2.5e-05 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832987867191 0.0079999088297855 -0.0142706766957323 1.000226130606784 2.6e-05 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832987819157 0.007999893703011 -0.0160049378439864 1.0002340682440483 2.7e-05 1.0 0.5 0.5 0.5 3.64821e-11 0.014383298776332 0.0079998767758937 -0.0178721188962179 1.000242950681623 2.8e-05 1.0 0.5 0.5 0.5 3.64821e-11 0.014383298769877 0.007999857913329 -0.0198765708761419 1.0002528488461935 2.9e-05 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832987624529 0.0079998369759201 -0.0220225256346343 1.0002638359239637 3e-05 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832987539553 0.007999813820103 -0.0243140831627582 1.000275987295915 3.1e-05 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832987442724 0.0079997882982854 -0.0267551980189568 1.0002893804662816 3.2e-05 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832987332854 0.007999760258999 -0.0293496648510724 1.0003040949837791 3.3e-05 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832987208677 0.0079997295470672 -0.0321011029972354 1.0003202123551105 3.4e-05 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832987068853 0.0079996960037885 -0.0350129401543523 1.0003378159502636 3.5e-05 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832986911963 0.0079996594671366 -0.0380883951075977 1.0003569908991143 3.6e-05 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832986736509 0.0079996197719785 -0.041330459519923 1.0003778239788415 3.7e-05 1.0 0.5 0.5 0.5 3.64821e-11 0.014383298654091 0.0079995767503109 -0.0447418787855614 1.0004004034916618 3.8e-05 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832986323505 0.0079995302315166 -0.0483251319566073 1.000424819132395 3.9e-05 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832986082548 0.0079994800426413 -0.0520824107647706 1.0004511618453742 4e-05 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832985816207 0.0079994260086914 -0.0560155977723029 1.0004795236702335 4.1e-05 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832985522566 0.0079993679529551 -0.0601262436835033 1.0005099975761178 4.2e-05 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832985199623 0.0079993056973452 -0.0644155438558731 1.0005426772838766 4.3e-05 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832984845287 0.0079992390627669 -0.0688843140513614 1.0005776570758202 4.4e-05 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832984457381 0.00799916786951 -0.0735329655284826 1.0006150315926565 4.5e-05 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832984033639 0.0079990919376656 -0.0783614795576986 1.0006548956172674 4.6e-05 1.0 0.5 0.5 0.5 3.64821e-11 0.014383298357171 0.0079990110875694 -0.0833693814493191 1.0006973438450313 4.7e-05 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832983069152 0.0079989251402707 -0.0885557141955299 1.000742470640441 4.8e-05 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832982523439 0.0079988339180279 -0.0939190118482383 1.000790369779823 4.9e-05 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832981931958 0.0079987372448311 -0.0994572727784473 1.0008411341800327 D/stats_lag_bubbles_0.dat 0.0 1.0 0.5 0.5 0.5 1.0 0.9998421556038835 -D/voidfraction.dat 2.1429198e-06 2.1429198e-06 2.1429198e-06 2.1429198e-06 2.1429197e-06 2.1429197e-06 2.1429196e-06 2.1429195e-06 2.1429193e-06 2.142919e-06 2.1429186e-06 2.142918e-06 2.1429172e-06 2.1429161e-06 2.1429148e-06 2.142913e-06 2.1429109e-06 2.1429083e-06 2.1429052e-06 2.1429015e-06 2.1428971e-06 2.1428919e-06 2.1428859e-06 2.142879e-06 2.1428711e-06 2.1428621e-06 2.1428519e-06 2.1428404e-06 2.1428275e-06 2.1428132e-06 2.1427972e-06 2.1427795e-06 2.1427599e-06 2.1427384e-06 2.1427148e-06 2.142689e-06 2.1426608e-06 2.1426302e-06 2.142597e-06 2.142561e-06 2.1425221e-06 2.1424803e-06 2.1424352e-06 2.1423869e-06 2.1423351e-06 2.1422797e-06 2.1422206e-06 2.1421577e-06 2.1420907e-06 2.1420195e-06 2.141944e-06 \ No newline at end of file +D/voidfraction.dat 2.1429198e-06 2.1429198e-06 2.1429198e-06 2.1429198e-06 2.1429197e-06 2.1429197e-06 2.1429196e-06 2.1429195e-06 2.1429192e-06 2.1429189e-06 2.1429183e-06 2.1429177e-06 2.1429167e-06 2.1429155e-06 2.142914e-06 2.1429121e-06 2.1429097e-06 2.1429069e-06 2.1429035e-06 2.1428994e-06 2.1428947e-06 2.1428891e-06 2.1428827e-06 2.1428753e-06 2.1428669e-06 2.1428573e-06 2.1428465e-06 2.1428343e-06 2.1428207e-06 2.1428056e-06 2.1427888e-06 2.1427701e-06 2.1427496e-06 2.1427271e-06 2.1427024e-06 2.1426755e-06 2.1426461e-06 2.1426142e-06 2.1425797e-06 2.1425423e-06 2.142502e-06 2.1424585e-06 2.1424119e-06 2.1423619e-06 2.1423083e-06 2.1422511e-06 2.1421901e-06 2.1421252e-06 2.1420561e-06 2.1419828e-06 2.1419052e-06 \ No newline at end of file diff --git a/tests/CE7B0BC7/golden.txt b/tests/CE7B0BC7/golden.txt index b1011e6325..d02ecc3b2d 100644 --- a/tests/CE7B0BC7/golden.txt +++ b/tests/CE7B0BC7/golden.txt @@ -1,4 +1,4 @@ -D/beta.9.00.000050.dat 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999999708435 0.9999999644801 0.99999984081087 0.99999973754149 0.99999984081087 0.9999999644801 0.99999999708435 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.9999999644801 0.99999956727907 0.99999806067934 0.99999680260077 0.99999806067934 0.99999956727907 0.9999999644801 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999984081087 0.99999806067934 0.99999130856777 0.99998567025082 0.99999130856777 0.99999806067934 0.99999984081087 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999973754149 0.99999680260077 0.99998567025082 0.99997637423772 0.99998567025082 0.99999680260077 0.99999973754149 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999984081087 0.99999806067934 0.99999130856777 0.99998567025082 0.99999130856777 0.99999806067934 0.99999984081087 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.9999999644801 0.99999956727907 0.99999806067934 0.99999680260077 0.99999806067934 0.99999956727907 0.9999999644801 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999999708435 0.9999999644801 0.99999984081087 0.99999973754149 0.99999984081087 0.9999999644801 0.99999999708435 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.9999999644801 0.99999956727907 0.99999806067934 0.99999680260077 0.99999806067934 0.99999956727907 0.9999999644801 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999956727907 0.99999472837988 0.99997637423772 0.99996104770319 0.99997637423772 0.99999472837988 0.99999956727907 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999806067934 0.99997637423772 0.9998941166794 0.99982542791712 0.9998941166794 0.99997637423772 0.99999806067934 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999680260077 0.99996104770319 0.99982542791712 0.99971217929369 0.99982542791712 0.99996104770319 0.99999680260077 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999806067934 0.99997637423772 0.9998941166794 0.99982542791712 0.9998941166794 0.99997637423772 0.99999806067934 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999956727907 0.99999472837988 0.99997637423772 0.99996104770319 0.99997637423772 0.99999472837988 0.99999956727907 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.9999999644801 0.99999956727907 0.99999806067934 0.99999680260077 0.99999806067934 0.99999956727907 0.9999999644801 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999984081087 0.99999806067934 0.99999130856777 0.99998567025082 0.99999130856777 0.99999806067934 0.99999984081087 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999806067934 0.99997637423772 0.9998941166794 0.99982542791712 0.9998941166794 0.99997637423772 0.99999806067934 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999130856777 0.9998941166794 0.99952546387935 0.99921762220417 0.99952546387935 0.9998941166794 0.99999130856777 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99998567025082 0.99982542791712 0.99921762220417 0.99871007708629 0.99921762220417 0.99982542791712 0.99998567025082 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999130856777 0.9998941166794 0.99952546387935 0.99921762220417 0.99952546387935 0.9998941166794 0.99999130856777 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999806067934 0.99997637423772 0.9998941166794 0.99982542791712 0.9998941166794 0.99997637423772 0.99999806067934 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999984081087 0.99999806067934 0.99999130856777 0.99998567025082 0.99999130856777 0.99999806067934 0.99999984081087 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999973754149 0.99999680260077 0.99998567025082 0.99997637423772 0.99998567025082 0.99999680260077 0.99999973754149 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999680260077 0.99996104770319 0.99982542791712 0.99971217929369 0.99982542791712 0.99996104770319 0.99999680260077 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99998567025082 0.99982542791712 0.99921762220417 0.99871007708629 0.99921762220417 0.99982542791712 0.99998567025082 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99997637423772 0.99971217929369 0.99871007708629 0.99787327665461 0.99871007708629 0.99971217929369 0.99997637423772 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99998567025082 0.99982542791712 0.99921762220417 0.99871007708629 0.99921762220417 0.99982542791712 0.99998567025082 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999680260077 0.99996104770319 0.99982542791712 0.99971217929369 0.99982542791712 0.99996104770319 0.99999680260077 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999973754149 0.99999680260077 0.99998567025082 0.99997637423772 0.99998567025082 0.99999680260077 0.99999973754149 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999984081087 0.99999806067934 0.99999130856777 0.99998567025082 0.99999130856777 0.99999806067934 0.99999984081087 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999806067934 0.99997637423772 0.9998941166794 0.99982542791712 0.9998941166794 0.99997637423772 0.99999806067934 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999130856777 0.9998941166794 0.99952546387935 0.99921762220417 0.99952546387935 0.9998941166794 0.99999130856777 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99998567025082 0.99982542791712 0.99921762220417 0.99871007708629 0.99921762220417 0.99982542791712 0.99998567025082 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999130856777 0.9998941166794 0.99952546387935 0.99921762220417 0.99952546387935 0.9998941166794 0.99999130856777 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999806067934 0.99997637423772 0.9998941166794 0.99982542791712 0.9998941166794 0.99997637423772 0.99999806067934 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999984081087 0.99999806067934 0.99999130856777 0.99998567025082 0.99999130856777 0.99999806067934 0.99999984081087 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.9999999644801 0.99999956727907 0.99999806067934 0.99999680260077 0.99999806067934 0.99999956727907 0.9999999644801 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999956727907 0.99999472837988 0.99997637423772 0.99996104770319 0.99997637423772 0.99999472837988 0.99999956727907 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999806067934 0.99997637423772 0.9998941166794 0.99982542791712 0.9998941166794 0.99997637423772 0.99999806067934 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999680260077 0.99996104770319 0.99982542791712 0.99971217929369 0.99982542791712 0.99996104770319 0.99999680260077 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999806067934 0.99997637423772 0.9998941166794 0.99982542791712 0.9998941166794 0.99997637423772 0.99999806067934 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999956727907 0.99999472837988 0.99997637423772 0.99996104770319 0.99997637423772 0.99999472837988 0.99999956727907 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.9999999644801 0.99999956727907 0.99999806067934 0.99999680260077 0.99999806067934 0.99999956727907 0.9999999644801 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999999708435 0.9999999644801 0.99999984081087 0.99999973754149 0.99999984081087 0.9999999644801 0.99999999708435 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.9999999644801 0.99999956727907 0.99999806067934 0.99999680260077 0.99999806067934 0.99999956727907 0.9999999644801 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999984081087 0.99999806067934 0.99999130856777 0.99998567025082 0.99999130856777 0.99999806067934 0.99999984081087 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999973754149 0.99999680260077 0.99998567025082 0.99997637423772 0.99998567025082 0.99999680260077 0.99999973754149 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999984081087 0.99999806067934 0.99999130856777 0.99998567025082 0.99999130856777 0.99999806067934 0.99999984081087 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.9999999644801 0.99999956727907 0.99999806067934 0.99999680260077 0.99999806067934 0.99999956727907 0.9999999644801 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999999708435 0.9999999644801 0.99999984081087 0.99999973754149 0.99999984081087 0.9999999644801 0.99999999708435 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 +D/beta.9.00.000050.dat 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.9999999970844 0.99999996448075 0.99999984081375 0.99999973754625 0.99999984081375 0.99999996448075 0.9999999970844 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999996448075 0.99999956728692 0.9999980607145 0.99999680265875 0.9999980607145 0.99999956728692 0.99999996448075 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999984081375 0.9999980607145 0.99999130872539 0.99998567051068 0.99999130872539 0.9999980607145 0.99999984081375 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999973754625 0.99999680265875 0.99998567051068 0.99997637466616 0.99998567051068 0.99999680265875 0.99999973754625 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999984081375 0.9999980607145 0.99999130872539 0.99998567051068 0.99999130872539 0.9999980607145 0.99999984081375 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999996448075 0.99999956728692 0.9999980607145 0.99999680265875 0.9999980607145 0.99999956728692 0.99999996448075 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.9999999970844 0.99999996448075 0.99999984081375 0.99999973754625 0.99999984081375 0.99999996448075 0.9999999970844 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999996448075 0.99999956728692 0.9999980607145 0.99999680265875 0.9999980607145 0.99999956728692 0.99999996448075 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999956728692 0.99999472847548 0.99997637466616 0.99996104840957 0.99997637466616 0.99999472847548 0.99999956728692 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.9999980607145 0.99997637466616 0.99989411859955 0.9998254310829 0.99989411859955 0.99997637466616 0.9999980607145 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999680265875 0.99996104840957 0.9998254310829 0.99971218451318 0.9998254310829 0.99996104840957 0.99999680265875 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.9999980607145 0.99997637466616 0.99989411859955 0.9998254310829 0.99989411859955 0.99997637466616 0.9999980607145 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999956728692 0.99999472847548 0.99997637466616 0.99996104840957 0.99997637466616 0.99999472847548 0.99999956728692 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999996448075 0.99999956728692 0.9999980607145 0.99999680265875 0.9999980607145 0.99999956728692 0.99999996448075 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999984081375 0.9999980607145 0.99999130872539 0.99998567051068 0.99999130872539 0.9999980607145 0.99999984081375 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.9999980607145 0.99997637466616 0.99989411859955 0.9998254310829 0.99989411859955 0.99997637466616 0.9999980607145 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999130872539 0.99989411859955 0.99952547248484 0.99921763639223 0.99952547248484 0.99989411859955 0.99999130872539 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99998567051068 0.9998254310829 0.99921763639223 0.99871010047844 0.99921763639223 0.9998254310829 0.99998567051068 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999130872539 0.99989411859955 0.99952547248484 0.99921763639223 0.99952547248484 0.99989411859955 0.99999130872539 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.9999980607145 0.99997637466616 0.99989411859955 0.9998254310829 0.99989411859955 0.99997637466616 0.9999980607145 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999984081375 0.9999980607145 0.99999130872539 0.99998567051068 0.99999130872539 0.9999980607145 0.99999984081375 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999973754625 0.99999680265875 0.99998567051068 0.99997637466616 0.99998567051068 0.99999680265875 0.99999973754625 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999680265875 0.99996104840957 0.9998254310829 0.99971218451318 0.9998254310829 0.99996104840957 0.99999680265875 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99998567051068 0.9998254310829 0.99921763639223 0.99871010047844 0.99921763639223 0.9998254310829 0.99998567051068 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99997637466616 0.99971218451318 0.99871010047844 0.99787331522175 0.99871010047844 0.99971218451318 0.99997637466616 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99998567051068 0.9998254310829 0.99921763639223 0.99871010047844 0.99921763639223 0.9998254310829 0.99998567051068 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999680265875 0.99996104840957 0.9998254310829 0.99971218451318 0.9998254310829 0.99996104840957 0.99999680265875 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999973754625 0.99999680265875 0.99998567051068 0.99997637466616 0.99998567051068 0.99999680265875 0.99999973754625 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999984081375 0.9999980607145 0.99999130872539 0.99998567051068 0.99999130872539 0.9999980607145 0.99999984081375 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.9999980607145 0.99997637466616 0.99989411859955 0.9998254310829 0.99989411859955 0.99997637466616 0.9999980607145 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999130872539 0.99989411859955 0.99952547248484 0.99921763639223 0.99952547248484 0.99989411859955 0.99999130872539 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99998567051068 0.9998254310829 0.99921763639223 0.99871010047844 0.99921763639223 0.9998254310829 0.99998567051068 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999130872539 0.99989411859955 0.99952547248484 0.99921763639223 0.99952547248484 0.99989411859955 0.99999130872539 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.9999980607145 0.99997637466616 0.99989411859955 0.9998254310829 0.99989411859955 0.99997637466616 0.9999980607145 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999984081375 0.9999980607145 0.99999130872539 0.99998567051068 0.99999130872539 0.9999980607145 0.99999984081375 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999996448075 0.99999956728692 0.9999980607145 0.99999680265875 0.9999980607145 0.99999956728692 0.99999996448075 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999956728692 0.99999472847548 0.99997637466616 0.99996104840957 0.99997637466616 0.99999472847548 0.99999956728692 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.9999980607145 0.99997637466616 0.99989411859955 0.9998254310829 0.99989411859955 0.99997637466616 0.9999980607145 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999680265875 0.99996104840957 0.9998254310829 0.99971218451318 0.9998254310829 0.99996104840957 0.99999680265875 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.9999980607145 0.99997637466616 0.99989411859955 0.9998254310829 0.99989411859955 0.99997637466616 0.9999980607145 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999956728692 0.99999472847548 0.99997637466616 0.99996104840957 0.99997637466616 0.99999472847548 0.99999956728692 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999996448075 0.99999956728692 0.9999980607145 0.99999680265875 0.9999980607145 0.99999956728692 0.99999996448075 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.9999999970844 0.99999996448075 0.99999984081375 0.99999973754625 0.99999984081375 0.99999996448075 0.9999999970844 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999996448075 0.99999956728692 0.9999980607145 0.99999680265875 0.9999980607145 0.99999956728692 0.99999996448075 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999984081375 0.9999980607145 0.99999130872539 0.99998567051068 0.99999130872539 0.9999980607145 0.99999984081375 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999973754625 0.99999680265875 0.99998567051068 0.99997637466616 0.99998567051068 0.99999680265875 0.99999973754625 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999984081375 0.9999980607145 0.99999130872539 0.99998567051068 0.99999130872539 0.9999980607145 0.99999984081375 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.99999996448075 0.99999956728692 0.9999980607145 0.99999680265875 0.9999980607145 0.99999956728692 0.99999996448075 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.9999999970844 0.99999996448075 0.99999984081375 0.99999973754625 0.99999984081375 0.99999996448075 0.9999999970844 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 D/cons.1.00.000000.dat 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 D/cons.1.00.000050.dat 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999987 0.95999999999987 0.95999999999987 0.95999999999987 0.95999999999987 0.95999999999987 0.95999999999987 0.95999999999987 0.95999999999987 0.95999999999987 0.95999999999987 0.95999999999987 0.95999999999987 0.95999999999987 0.95999999999987 0.95999999999987 0.95999999999987 0.95999999999987 0.95999999999987 0.95999999999987 0.95999999999987 0.95999999999987 0.95999999999987 0.95999999999987 0.95999999999987 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000106 0.96000000000106 0.96000000000106 0.96000000000106 0.96000000000106 0.96000000000106 0.96000000000106 0.96000000000106 0.96000000000106 0.96000000000106 0.96000000000106 0.96000000000106 0.96000000000106 0.96000000000106 0.96000000000106 0.96000000000106 0.96000000000106 0.96000000000106 0.96000000000106 0.96000000000106 0.96000000000106 0.96000000000106 0.96000000000106 0.96000000000106 0.96000000000106 0.96000000000071 0.96000000000071 0.96000000000071 0.96000000000071 0.96000000000071 0.96000000000071 0.96000000000071 0.96000000000071 0.96000000000071 0.96000000000071 0.96000000000071 0.96000000000071 0.96000000000071 0.96000000000071 0.96000000000071 0.96000000000071 0.96000000000071 0.96000000000071 0.96000000000071 0.96000000000071 0.96000000000071 0.96000000000071 0.96000000000071 0.96000000000071 0.96000000000071 0.96000000000373 0.96000000000373 0.96000000000373 0.96000000000373 0.96000000000373 0.96000000000373 0.96000000000373 0.96000000000373 0.96000000000373 0.96000000000373 0.96000000000373 0.96000000000373 0.96000000000373 0.96000000000373 0.96000000000373 0.96000000000373 0.96000000000373 0.96000000000373 0.96000000000373 0.96000000000373 0.96000000000373 0.96000000000373 0.96000000000373 0.96000000000373 0.96000000000373 0.96000000000075 0.96000000000075 0.96000000000075 0.96000000000075 0.96000000000075 0.96000000000075 0.96000000000075 0.96000000000075 0.96000000000075 0.96000000000075 0.96000000000075 0.96000000000075 0.96000000000075 0.96000000000075 0.96000000000075 0.96000000000075 0.96000000000075 0.96000000000075 0.96000000000075 0.96000000000075 0.96000000000075 0.96000000000075 0.96000000000075 0.96000000000075 0.96000000000075 0.96000000000107 0.96000000000107 0.96000000000107 0.96000000000107 0.96000000000107 0.96000000000107 0.96000000000107 0.96000000000107 0.96000000000107 0.96000000000107 0.96000000000107 0.96000000000107 0.96000000000107 0.96000000000107 0.96000000000107 0.96000000000107 0.96000000000107 0.96000000000107 0.96000000000107 0.96000000000107 0.96000000000107 0.96000000000107 0.96000000000107 0.96000000000107 0.96000000000107 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.9600000000001 0.9600000000001 0.9600000000001 0.9600000000001 0.9600000000001 0.9600000000001 0.9600000000001 0.9600000000001 0.9600000000001 0.9600000000001 0.9600000000001 0.9600000000001 0.9600000000001 0.9600000000001 0.9600000000001 0.9600000000001 0.9600000000001 0.9600000000001 0.9600000000001 0.9600000000001 0.9600000000001 0.9600000000001 0.9600000000001 0.9600000000001 0.9600000000001 0.96000000000079 0.96000000000079 0.96000000000079 0.96000000000079 0.96000000000079 0.96000000000079 0.96000000000079 0.96000000000079 0.96000000000079 0.96000000000079 0.96000000000079 0.96000000000079 0.96000000000079 0.96000000000079 0.96000000000079 0.96000000000079 0.96000000000079 0.96000000000079 0.96000000000079 0.96000000000079 0.96000000000079 0.96000000000079 0.96000000000079 0.96000000000079 0.96000000000079 0.96000000002206 0.96000000002206 0.96000000002206 0.96000000002206 0.96000000002206 0.96000000002206 0.96000000002206 0.96000000002206 0.96000000002206 0.96000000002206 0.96000000002206 0.96000000002206 0.96000000002206 0.96000000002206 0.96000000002206 0.96000000002206 0.96000000002206 0.96000000002206 0.96000000002206 0.96000000002206 0.96000000002206 0.96000000002206 0.96000000002206 0.96000000002206 0.96000000002206 0.96000000005987 0.96000000005987 0.96000000005987 0.96000000005987 0.96000000005987 0.96000000005987 0.96000000005987 0.96000000005987 0.96000000005987 0.96000000005987 0.96000000005987 0.96000000005987 0.96000000005987 0.96000000005987 0.96000000005987 0.96000000005987 0.96000000005987 0.96000000005987 0.96000000005987 0.96000000005987 0.96000000005987 0.96000000005987 0.96000000005987 0.96000000005987 0.96000000005987 0.96000000004881 0.96000000004881 0.96000000004881 0.96000000004881 0.96000000004881 0.96000000004881 0.96000000004881 0.96000000004881 0.96000000004881 0.96000000004881 0.96000000004881 0.96000000004881 0.96000000004881 0.96000000004881 0.96000000004881 0.96000000004881 0.96000000004881 0.96000000004881 0.96000000004881 0.96000000004881 0.96000000004881 0.96000000004881 0.96000000004881 0.96000000004881 0.96000000004881 0.96000000032881 0.96000000032881 0.96000000032881 0.96000000032881 0.96000000032881 0.96000000032881 0.96000000032881 0.96000000032881 0.96000000032881 0.96000000032881 0.96000000032881 0.96000000032881 0.96000000032881 0.96000000032881 0.96000000032881 0.96000000032881 0.96000000032881 0.96000000032881 0.96000000032881 0.96000000032881 0.96000000032881 0.96000000032881 0.96000000032881 0.96000000032881 0.96000000032881 0.96000000005864 0.96000000005864 0.96000000005864 0.96000000005864 0.96000000005864 0.96000000005864 0.96000000005864 0.96000000005864 0.96000000005864 0.96000000005864 0.96000000005864 0.96000000005864 0.96000000005864 0.96000000005864 0.96000000005864 0.96000000005864 0.96000000005864 0.96000000005864 0.96000000005864 0.96000000005864 0.96000000005864 0.96000000005864 0.96000000005864 0.96000000005864 0.96000000005864 0.96000000008629 0.96000000008629 0.96000000008629 0.96000000008629 0.96000000008629 0.96000000008629 0.96000000008629 0.96000000008629 0.96000000008629 0.96000000008629 0.96000000008629 0.96000000008629 0.96000000008629 0.96000000008629 0.96000000008629 0.96000000008629 0.96000000008629 0.96000000008629 0.96000000008629 0.96000000008629 0.96000000008629 0.96000000008629 0.96000000008629 0.96000000008629 0.96000000008629 0.96000000000597 0.96000000000597 0.96000000000597 0.96000000000597 0.96000000000597 0.96000000000597 0.96000000000597 0.96000000000597 0.96000000000597 0.96000000000597 0.96000000000597 0.96000000000597 0.96000000000597 0.96000000000597 0.96000000000597 0.96000000000597 0.96000000000597 0.96000000000597 0.96000000000597 0.96000000000597 0.96000000000597 0.96000000000597 0.96000000000597 0.96000000000597 0.96000000000597 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.9600000000021 0.9600000000021 0.9600000000021 0.9600000000021 0.9600000000021 0.9600000000021 0.9600000000021 0.9600000000021 0.9600000000021 0.9600000000021 0.9600000000021 0.9600000000021 0.9600000000021 0.9600000000021 0.9600000000021 0.9600000000021 0.9600000000021 0.9600000000021 0.9600000000021 0.9600000000021 0.9600000000021 0.9600000000021 0.9600000000021 0.9600000000021 0.9600000000021 0.96000000013587 0.96000000013587 0.96000000013587 0.96000000013587 0.96000000013587 0.96000000013587 0.96000000013587 0.96000000013587 0.96000000013587 0.96000000013587 0.96000000013587 0.96000000013587 0.96000000013587 0.96000000013587 0.96000000013587 0.96000000013587 0.96000000013587 0.96000000013587 0.96000000013587 0.96000000013587 0.96000000013587 0.96000000013587 0.96000000013587 0.96000000013587 0.96000000013587 0.96000000392457 0.96000000392457 0.96000000392457 0.96000000392457 0.96000000392457 0.96000000392457 0.96000000392457 0.96000000392457 0.96000000392457 0.96000000392457 0.96000000392457 0.96000000392457 0.96000000392457 0.96000000392457 0.96000000392457 0.96000000392457 0.96000000392457 0.96000000392457 0.96000000392457 0.96000000392457 0.96000000392457 0.96000000392457 0.96000000392457 0.96000000392457 0.96000000392457 0.96000000386601 0.96000000386601 0.96000000386601 0.96000000386601 0.96000000386601 0.96000000386601 0.96000000386601 0.96000000386601 0.96000000386601 0.96000000386601 0.96000000386601 0.96000000386601 0.96000000386601 0.96000000386601 0.96000000386601 0.96000000386601 0.96000000386601 0.96000000386601 0.96000000386601 0.96000000386601 0.96000000386601 0.96000000386601 0.96000000386601 0.96000000386601 0.96000000386601 0.96000000372715 0.96000000372715 0.96000000372715 0.96000000372715 0.96000000372715 0.96000000372715 0.96000000372715 0.96000000372715 0.96000000372715 0.96000000372715 0.96000000372715 0.96000000372715 0.96000000372715 0.96000000372715 0.96000000372715 0.96000000372715 0.96000000372715 0.96000000372715 0.96000000372715 0.96000000372715 0.96000000372715 0.96000000372715 0.96000000372715 0.96000000372715 0.96000000372715 0.96000002634421 0.96000002634421 0.96000002634421 0.96000002634421 0.96000002634421 0.96000002634421 0.96000002634421 0.96000002634421 0.96000002634421 0.96000002634421 0.96000002634421 0.96000002634421 0.96000002634421 0.96000002634421 0.96000002634421 0.96000002634421 0.96000002634421 0.96000002634421 0.96000002634421 0.96000002634421 0.96000002634421 0.96000002634421 0.96000002634421 0.96000002634421 0.96000002634421 0.96000000528784 0.96000000528784 0.96000000528784 0.96000000528784 0.96000000528784 0.96000000528784 0.96000000528784 0.96000000528784 0.96000000528784 0.96000000528784 0.96000000528784 0.96000000528784 0.96000000528784 0.96000000528784 0.96000000528784 0.96000000528784 0.96000000528784 0.96000000528784 0.96000000528784 0.96000000528784 0.96000000528784 0.96000000528784 0.96000000528784 0.96000000528784 0.96000000528784 0.96000000790203 0.96000000790203 0.96000000790203 0.96000000790203 0.96000000790203 0.96000000790203 0.96000000790203 0.96000000790203 0.96000000790203 0.96000000790203 0.96000000790203 0.96000000790203 0.96000000790203 0.96000000790203 0.96000000790203 0.96000000790203 0.96000000790203 0.96000000790203 0.96000000790203 0.96000000790203 0.96000000790203 0.96000000790203 0.96000000790203 0.96000000790203 0.96000000790203 0.96000000059137 0.96000000059137 0.96000000059137 0.96000000059137 0.96000000059137 0.96000000059137 0.96000000059137 0.96000000059137 0.96000000059137 0.96000000059137 0.96000000059137 0.96000000059137 0.96000000059137 0.96000000059137 0.96000000059137 0.96000000059137 0.96000000059137 0.96000000059137 0.96000000059137 0.96000000059137 0.96000000059137 0.96000000059137 0.96000000059137 0.96000000059137 0.96000000059137 0.96000000001228 0.96000000001228 0.96000000001228 0.96000000001228 0.96000000001228 0.96000000001228 0.96000000001228 0.96000000001228 0.96000000001228 0.96000000001228 0.96000000001228 0.96000000001228 0.96000000001228 0.96000000001228 0.96000000001228 0.96000000001228 0.96000000001228 0.96000000001228 0.96000000001228 0.96000000001228 0.96000000001228 0.96000000001228 0.96000000001228 0.96000000001228 0.96000000001228 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.96000000000016 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000002232 0.96000000002232 0.96000000002232 0.96000000002232 0.96000000002232 0.96000000002232 0.96000000002232 0.96000000002232 0.96000000002232 0.96000000002232 0.96000000002232 0.96000000002232 0.96000000002232 0.96000000002232 0.96000000002232 0.96000000002232 0.96000000002232 0.96000000002232 0.96000000002232 0.96000000002232 0.96000000002232 0.96000000002232 0.96000000002232 0.96000000002232 0.96000000002232 0.960000001086 0.960000001086 0.960000001086 0.960000001086 0.960000001086 0.960000001086 0.960000001086 0.960000001086 0.960000001086 0.960000001086 0.960000001086 0.960000001086 0.960000001086 0.960000001086 0.960000001086 0.960000001086 0.960000001086 0.960000001086 0.960000001086 0.960000001086 0.960000001086 0.960000001086 0.960000001086 0.960000001086 0.960000001086 0.96000003357351 0.96000003357351 0.96000003357351 0.96000003357351 0.96000003357351 0.96000003357351 0.96000003357351 0.96000003357351 0.96000003357351 0.96000003357351 0.96000003357351 0.96000003357351 0.96000003357351 0.96000003357351 0.96000003357351 0.96000003357351 0.96000003357351 0.96000003357351 0.96000003357351 0.96000003357351 0.96000003357351 0.96000003357351 0.96000003357351 0.96000003357351 0.96000003357351 0.9600007182478 0.9600007182478 0.9600007182478 0.9600007182478 0.9600007182478 0.9600007182478 0.9600007182478 0.9600007182478 0.9600007182478 0.9600007182478 0.9600007182478 0.9600007182478 0.9600007182478 0.9600007182478 0.9600007182478 0.9600007182478 0.9600007182478 0.9600007182478 0.9600007182478 0.9600007182478 0.9600007182478 0.9600007182478 0.9600007182478 0.9600007182478 0.9600007182478 0.96000023896672 0.96000023896672 0.96000023896672 0.96000023896672 0.96000023896672 0.96000023896672 0.96000023896672 0.96000023896672 0.96000023896672 0.96000023896672 0.96000023896672 0.96000023896672 0.96000023896672 0.96000023896672 0.96000023896672 0.96000023896672 0.96000023896672 0.96000023896672 0.96000023896672 0.96000023896672 0.96000023896672 0.96000023896672 0.96000023896672 0.96000023896672 0.96000023896672 0.96000168485738 0.96000168485738 0.96000168485738 0.96000168485738 0.96000168485738 0.96000168485738 0.96000168485738 0.96000168485738 0.96000168485738 0.96000168485738 0.96000168485738 0.96000168485738 0.96000168485738 0.96000168485738 0.96000168485738 0.96000168485738 0.96000168485738 0.96000168485738 0.96000168485738 0.96000168485738 0.96000168485738 0.96000168485738 0.96000168485738 0.96000168485738 0.96000168485738 0.96000038977218 0.96000038977218 0.96000038977218 0.96000038977218 0.96000038977218 0.96000038977218 0.96000038977218 0.96000038977218 0.96000038977218 0.96000038977218 0.96000038977218 0.96000038977218 0.96000038977218 0.96000038977218 0.96000038977218 0.96000038977218 0.96000038977218 0.96000038977218 0.96000038977218 0.96000038977218 0.96000038977218 0.96000038977218 0.96000038977218 0.96000038977218 0.96000038977218 0.96000058691047 0.96000058691047 0.96000058691047 0.96000058691047 0.96000058691047 0.96000058691047 0.96000058691047 0.96000058691047 0.96000058691047 0.96000058691047 0.96000058691047 0.96000058691047 0.96000058691047 0.96000058691047 0.96000058691047 0.96000058691047 0.96000058691047 0.96000058691047 0.96000058691047 0.96000058691047 0.96000058691047 0.96000058691047 0.96000058691047 0.96000058691047 0.96000058691047 0.96000005194927 0.96000005194927 0.96000005194927 0.96000005194927 0.96000005194927 0.96000005194927 0.96000005194927 0.96000005194927 0.96000005194927 0.96000005194927 0.96000005194927 0.96000005194927 0.96000005194927 0.96000005194927 0.96000005194927 0.96000005194927 0.96000005194927 0.96000005194927 0.96000005194927 0.96000005194927 0.96000005194927 0.96000005194927 0.96000005194927 0.96000005194927 0.96000005194927 0.96000000110092 0.96000000110092 0.96000000110092 0.96000000110092 0.96000000110092 0.96000000110092 0.96000000110092 0.96000000110092 0.96000000110092 0.96000000110092 0.96000000110092 0.96000000110092 0.96000000110092 0.96000000110092 0.96000000110092 0.96000000110092 0.96000000110092 0.96000000110092 0.96000000110092 0.96000000110092 0.96000000110092 0.96000000110092 0.96000000110092 0.96000000110092 0.96000000110092 0.96000000002787 0.96000000002787 0.96000000002787 0.96000000002787 0.96000000002787 0.96000000002787 0.96000000002787 0.96000000002787 0.96000000002787 0.96000000002787 0.96000000002787 0.96000000002787 0.96000000002787 0.96000000002787 0.96000000002787 0.96000000002787 0.96000000002787 0.96000000002787 0.96000000002787 0.96000000002787 0.96000000002787 0.96000000002787 0.96000000002787 0.96000000002787 0.96000000002787 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.96000000000033 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96000000000024 0.96000000000024 0.96000000000024 0.96000000000024 0.96000000000024 0.96000000000024 0.96000000000024 0.96000000000024 0.96000000000024 0.96000000000024 0.96000000000024 0.96000000000024 0.96000000000024 0.96000000000024 0.96000000000024 0.96000000000024 0.96000000000024 0.96000000000024 0.96000000000024 0.96000000000024 0.96000000000024 0.96000000000024 0.96000000000024 0.96000000000024 0.96000000000024 0.96000000000461 0.96000000000461 0.96000000000461 0.96000000000461 0.96000000000461 0.96000000000461 0.96000000000461 0.96000000000461 0.96000000000461 0.96000000000461 0.96000000000461 0.96000000000461 0.96000000000461 0.96000000000461 0.96000000000461 0.96000000000461 0.96000000000461 0.96000000000461 0.96000000000461 0.96000000000461 0.96000000000461 0.96000000000461 0.96000000000461 0.96000000000461 0.96000000000461 0.96000000028923 0.96000000028923 0.96000000028923 0.96000000028923 0.96000000028923 0.96000000028923 0.96000000028923 0.96000000028923 0.96000000028923 0.96000000028923 0.96000000028923 0.96000000028923 0.96000000028923 0.96000000028923 0.96000000028923 0.96000000028923 0.96000000028923 0.96000000028923 0.96000000028923 0.96000000028923 0.96000000028923 0.96000000028923 0.96000000028923 0.96000000028923 0.96000000028923 0.96000001055314 0.96000001055314 0.96000001055314 0.96000001055314 0.96000001055314 0.96000001055314 0.96000001055314 0.96000001055314 0.96000001055314 0.96000001055314 0.96000001055314 0.96000001055314 0.96000001055314 0.96000001055314 0.96000001055314 0.96000001055314 0.96000001055314 0.96000001055314 0.96000001055314 0.96000001055314 0.96000001055314 0.96000001055314 0.96000001055314 0.96000001055314 0.96000001055314 0.96000025210076 0.96000025210076 0.96000025210076 0.96000025210076 0.96000025210076 0.96000025210076 0.96000025210076 0.96000025210076 0.96000025210076 0.96000025210076 0.96000025210076 0.96000025210076 0.96000025210076 0.96000025210076 0.96000025210076 0.96000025210076 0.96000025210076 0.96000025210076 0.96000025210076 0.96000025210076 0.96000025210076 0.96000025210076 0.96000025210076 0.96000025210076 0.96000025210076 0.96000388888139 0.96000388888139 0.96000388888139 0.96000388888139 0.96000388888139 0.96000388888139 0.96000388888139 0.96000388888139 0.96000388888139 0.96000388888139 0.96000388888139 0.96000388888139 0.96000388888139 0.96000388888139 0.96000388888139 0.96000388888139 0.96000388888139 0.96000388888139 0.96000388888139 0.96000388888139 0.96000388888139 0.96000388888139 0.96000388888139 0.96000388888139 0.96000388888139 0.96003762422319 0.96003762422319 0.96003762422319 0.96003762422319 0.96003762422319 0.96003762422319 0.96003762422319 0.96003762422319 0.96003762422319 0.96003762422319 0.96003762422319 0.96003762422319 0.96003762422319 0.96003762422319 0.96003762422319 0.96003762422319 0.96003762422319 0.96003762422319 0.96003762422319 0.96003762422319 0.96003762422319 0.96003762422319 0.96003762422319 0.96003762422319 0.96003762422319 0.96024757938339 0.96024757938339 0.96024757938339 0.96024757938339 0.96024757938339 0.96024757938339 0.96024757938339 0.96024757938339 0.96024757938339 0.96024757938339 0.96024757938339 0.96024757938339 0.96024757938339 0.96024757938339 0.96024757938339 0.96024757938339 0.96024757938339 0.96024757938339 0.96024757938339 0.96024757938339 0.96024757938339 0.96024757938339 0.96024757938339 0.96024757938339 0.96024757938339 0.96002715152843 0.96002715152843 0.96002715152843 0.96002715152843 0.96002715152843 0.96002715152843 0.96002715152843 0.96002715152843 0.96002715152843 0.96002715152843 0.96002715152843 0.96002715152843 0.96002715152843 0.96002715152843 0.96002715152843 0.96002715152843 0.96002715152843 0.96002715152843 0.96002715152843 0.96002715152843 0.96002715152843 0.96002715152843 0.96002715152843 0.96002715152843 0.96002715152843 0.96003089249465 0.96003089249465 0.96003089249465 0.96003089249465 0.96003089249465 0.96003089249465 0.96003089249465 0.96003089249465 0.96003089249465 0.96003089249465 0.96003089249465 0.96003089249465 0.96003089249465 0.96003089249465 0.96003089249465 0.96003089249465 0.96003089249465 0.96003089249465 0.96003089249465 0.96003089249465 0.96003089249465 0.96003089249465 0.96003089249465 0.96003089249465 0.96003089249465 0.96000375036941 0.96000375036941 0.96000375036941 0.96000375036941 0.96000375036941 0.96000375036941 0.96000375036941 0.96000375036941 0.96000375036941 0.96000375036941 0.96000375036941 0.96000375036941 0.96000375036941 0.96000375036941 0.96000375036941 0.96000375036941 0.96000375036941 0.96000375036941 0.96000375036941 0.96000375036941 0.96000375036941 0.96000375036941 0.96000375036941 0.96000375036941 0.96000375036941 0.96000008693805 0.96000008693805 0.96000008693805 0.96000008693805 0.96000008693805 0.96000008693805 0.96000008693805 0.96000008693805 0.96000008693805 0.96000008693805 0.96000008693805 0.96000008693805 0.96000008693805 0.96000008693805 0.96000008693805 0.96000008693805 0.96000008693805 0.96000008693805 0.96000008693805 0.96000008693805 0.96000008693805 0.96000008693805 0.96000008693805 0.96000008693805 0.96000008693805 0.96000000244292 0.96000000244292 0.96000000244292 0.96000000244292 0.96000000244292 0.96000000244292 0.96000000244292 0.96000000244292 0.96000000244292 0.96000000244292 0.96000000244292 0.96000000244292 0.96000000244292 0.96000000244292 0.96000000244292 0.96000000244292 0.96000000244292 0.96000000244292 0.96000000244292 0.96000000244292 0.96000000244292 0.96000000244292 0.96000000244292 0.96000000244292 0.96000000244292 0.96000000003463 0.96000000003463 0.96000000003463 0.96000000003463 0.96000000003463 0.96000000003463 0.96000000003463 0.96000000003463 0.96000000003463 0.96000000003463 0.96000000003463 0.96000000003463 0.96000000003463 0.96000000003463 0.96000000003463 0.96000000003463 0.96000000003463 0.96000000003463 0.96000000003463 0.96000000003463 0.96000000003463 0.96000000003463 0.96000000003463 0.96000000003463 0.96000000003463 0.9600000000004 0.9600000000004 0.9600000000004 0.9600000000004 0.9600000000004 0.9600000000004 0.9600000000004 0.9600000000004 0.9600000000004 0.9600000000004 0.9600000000004 0.9600000000004 0.9600000000004 0.9600000000004 0.9600000000004 0.9600000000004 0.9600000000004 0.9600000000004 0.9600000000004 0.9600000000004 0.9600000000004 0.9600000000004 0.9600000000004 0.9600000000004 0.9600000000004 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.96000000000021 0.96000000000021 0.96000000000021 0.96000000000021 0.96000000000021 0.96000000000021 0.96000000000021 0.96000000000021 0.96000000000021 0.96000000000021 0.96000000000021 0.96000000000021 0.96000000000021 0.96000000000021 0.96000000000021 0.96000000000021 0.96000000000021 0.96000000000021 0.96000000000021 0.96000000000021 0.96000000000021 0.96000000000021 0.96000000000021 0.96000000000021 0.96000000000021 0.96000000000066 0.96000000000066 0.96000000000066 0.96000000000066 0.96000000000066 0.96000000000066 0.96000000000066 0.96000000000066 0.96000000000066 0.96000000000066 0.96000000000066 0.96000000000066 0.96000000000066 0.96000000000066 0.96000000000066 0.96000000000066 0.96000000000066 0.96000000000066 0.96000000000066 0.96000000000066 0.96000000000066 0.96000000000066 0.96000000000066 0.96000000000066 0.96000000000066 0.9600000000725 0.9600000000725 0.9600000000725 0.9600000000725 0.9600000000725 0.9600000000725 0.9600000000725 0.9600000000725 0.9600000000725 0.9600000000725 0.9600000000725 0.9600000000725 0.9600000000725 0.9600000000725 0.9600000000725 0.9600000000725 0.9600000000725 0.9600000000725 0.9600000000725 0.9600000000725 0.9600000000725 0.9600000000725 0.9600000000725 0.9600000000725 0.9600000000725 0.96000000306584 0.96000000306584 0.96000000306584 0.96000000306584 0.96000000306584 0.96000000306584 0.96000000306584 0.96000000306584 0.96000000306584 0.96000000306584 0.96000000306584 0.96000000306584 0.96000000306584 0.96000000306584 0.96000000306584 0.96000000306584 0.96000000306584 0.96000000306584 0.96000000306584 0.96000000306584 0.96000000306584 0.96000000306584 0.96000000306584 0.96000000306584 0.96000000306584 0.96000008513635 0.96000008513635 0.96000008513635 0.96000008513635 0.96000008513635 0.96000008513635 0.96000008513635 0.96000008513635 0.96000008513635 0.96000008513635 0.96000008513635 0.96000008513635 0.96000008513635 0.96000008513635 0.96000008513635 0.96000008513635 0.96000008513635 0.96000008513635 0.96000008513635 0.96000008513635 0.96000008513635 0.96000008513635 0.96000008513635 0.96000008513635 0.96000008513635 0.96000153658661 0.96000153658661 0.96000153658661 0.96000153658661 0.96000153658661 0.96000153658661 0.96000153658661 0.96000153658661 0.96000153658661 0.96000153658661 0.96000153658661 0.96000153658661 0.96000153658661 0.96000153658661 0.96000153658661 0.96000153658661 0.96000153658661 0.96000153658661 0.96000153658661 0.96000153658661 0.96000153658661 0.96000153658661 0.96000153658661 0.96000153658661 0.96000153658661 0.96001782964953 0.96001782964953 0.96001782964953 0.96001782964953 0.96001782964953 0.96001782964953 0.96001782964953 0.96001782964953 0.96001782964953 0.96001782964953 0.96001782964953 0.96001782964953 0.96001782964953 0.96001782964953 0.96001782964953 0.96001782964953 0.96001782964953 0.96001782964953 0.96001782964953 0.96001782964953 0.96001782964953 0.96001782964953 0.96001782964953 0.96001782964953 0.96001782964953 0.96013299338417 0.96013299338417 0.96013299338417 0.96013299338417 0.96013299338417 0.96013299338417 0.96013299338417 0.96013299338417 0.96013299338417 0.96013299338417 0.96013299338417 0.96013299338417 0.96013299338417 0.96013299338417 0.96013299338417 0.96013299338417 0.96013299338417 0.96013299338417 0.96013299338417 0.96013299338417 0.96013299338417 0.96013299338417 0.96013299338417 0.96013299338417 0.96013299338417 0.96063533731738 0.96063533731738 0.96063533731738 0.96063533731738 0.96063533731738 0.96063533731738 0.96063533731738 0.96063533731738 0.96063533731738 0.96063533731738 0.96063533731738 0.96063533731738 0.96063533731738 0.96063533731738 0.96063533731738 0.96063533731738 0.96063533731738 0.96063533731738 0.96063533731738 0.96063533731738 0.96063533731738 0.96063533731738 0.96063533731738 0.96063533731738 0.96063533731738 0.96190052351632 0.96190052351632 0.96190052351632 0.96190052351632 0.96190052351632 0.96190052351632 0.96190052351632 0.96190052351632 0.96190052351632 0.96190052351632 0.96190052351632 0.96190052351632 0.96190052351632 0.96190052351632 0.96190052351632 0.96190052351632 0.96190052351632 0.96190052351632 0.96190052351632 0.96190052351632 0.96190052351632 0.96190052351632 0.96190052351632 0.96190052351632 0.96190052351632 0.96374631791153 0.96374631791153 0.96374631791153 0.96374631791153 0.96374631791153 0.96374631791153 0.96374631791153 0.96374631791153 0.96374631791153 0.96374631791153 0.96374631791153 0.96374631791153 0.96374631791153 0.96374631791153 0.96374631791153 0.96374631791153 0.96374631791153 0.96374631791153 0.96374631791153 0.96374631791153 0.96374631791153 0.96374631791153 0.96374631791153 0.96374631791153 0.96374631791153 0.96026255957098 0.96026255957098 0.96026255957098 0.96026255957098 0.96026255957098 0.96026255957098 0.96026255957098 0.96026255957098 0.96026255957098 0.96026255957098 0.96026255957098 0.96026255957098 0.96026255957098 0.96026255957098 0.96026255957098 0.96026255957098 0.96026255957098 0.96026255957098 0.96026255957098 0.96026255957098 0.96026255957098 0.96026255957098 0.96026255957098 0.96026255957098 0.96026255957098 0.96000700586267 0.96000700586267 0.96000700586267 0.96000700586267 0.96000700586267 0.96000700586267 0.96000700586267 0.96000700586267 0.96000700586267 0.96000700586267 0.96000700586267 0.96000700586267 0.96000700586267 0.96000700586267 0.96000700586267 0.96000700586267 0.96000700586267 0.96000700586267 0.96000700586267 0.96000700586267 0.96000700586267 0.96000700586267 0.96000700586267 0.96000700586267 0.96000700586267 0.96000019245935 0.96000019245935 0.96000019245935 0.96000019245935 0.96000019245935 0.96000019245935 0.96000019245935 0.96000019245935 0.96000019245935 0.96000019245935 0.96000019245935 0.96000019245935 0.96000019245935 0.96000019245935 0.96000019245935 0.96000019245935 0.96000019245935 0.96000019245935 0.96000019245935 0.96000019245935 0.96000019245935 0.96000019245935 0.96000019245935 0.96000019245935 0.96000019245935 0.9600000027078 0.9600000027078 0.9600000027078 0.9600000027078 0.9600000027078 0.9600000027078 0.9600000027078 0.9600000027078 0.9600000027078 0.9600000027078 0.9600000027078 0.9600000027078 0.9600000027078 0.9600000027078 0.9600000027078 0.9600000027078 0.9600000027078 0.9600000027078 0.9600000027078 0.9600000027078 0.9600000027078 0.9600000027078 0.9600000027078 0.9600000027078 0.9600000027078 0.96000000003541 0.96000000003541 0.96000000003541 0.96000000003541 0.96000000003541 0.96000000003541 0.96000000003541 0.96000000003541 0.96000000003541 0.96000000003541 0.96000000003541 0.96000000003541 0.96000000003541 0.96000000003541 0.96000000003541 0.96000000003541 0.96000000003541 0.96000000003541 0.96000000003541 0.96000000003541 0.96000000003541 0.96000000003541 0.96000000003541 0.96000000003541 0.96000000003541 0.96000000000036 0.96000000000036 0.96000000000036 0.96000000000036 0.96000000000036 0.96000000000036 0.96000000000036 0.96000000000036 0.96000000000036 0.96000000000036 0.96000000000036 0.96000000000036 0.96000000000036 0.96000000000036 0.96000000000036 0.96000000000036 0.96000000000036 0.96000000000036 0.96000000000036 0.96000000000036 0.96000000000036 0.96000000000036 0.96000000000036 0.96000000000036 0.96000000000036 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000004 0.96000000000004 0.96000000000004 0.96000000000004 0.96000000000004 0.96000000000004 0.96000000000004 0.96000000000004 0.96000000000004 0.96000000000004 0.96000000000004 0.96000000000004 0.96000000000004 0.96000000000004 0.96000000000004 0.96000000000004 0.96000000000004 0.96000000000004 0.96000000000004 0.96000000000004 0.96000000000004 0.96000000000004 0.96000000000004 0.96000000000004 0.96000000000004 0.96000000001662 0.96000000001662 0.96000000001662 0.96000000001662 0.96000000001662 0.96000000001662 0.96000000001662 0.96000000001662 0.96000000001662 0.96000000001662 0.96000000001662 0.96000000001662 0.96000000001662 0.96000000001662 0.96000000001662 0.96000000001662 0.96000000001662 0.96000000001662 0.96000000001662 0.96000000001662 0.96000000001662 0.96000000001662 0.96000000001662 0.96000000001662 0.96000000001662 0.96000000087018 0.96000000087018 0.96000000087018 0.96000000087018 0.96000000087018 0.96000000087018 0.96000000087018 0.96000000087018 0.96000000087018 0.96000000087018 0.96000000087018 0.96000000087018 0.96000000087018 0.96000000087018 0.96000000087018 0.96000000087018 0.96000000087018 0.96000000087018 0.96000000087018 0.96000000087018 0.96000000087018 0.96000000087018 0.96000000087018 0.96000000087018 0.96000000087018 0.96000002801722 0.96000002801722 0.96000002801722 0.96000002801722 0.96000002801722 0.96000002801722 0.96000002801722 0.96000002801722 0.96000002801722 0.96000002801722 0.96000002801722 0.96000002801722 0.96000002801722 0.96000002801722 0.96000002801722 0.96000002801722 0.96000002801722 0.96000002801722 0.96000002801722 0.96000002801722 0.96000002801722 0.96000002801722 0.96000002801722 0.96000002801722 0.96000002801722 0.96000057403111 0.96000057403111 0.96000057403111 0.96000057403111 0.96000057403111 0.96000057403111 0.96000057403111 0.96000057403111 0.96000057403111 0.96000057403111 0.96000057403111 0.96000057403111 0.96000057403111 0.96000057403111 0.96000057403111 0.96000057403111 0.96000057403111 0.96000057403111 0.96000057403111 0.96000057403111 0.96000057403111 0.96000057403111 0.96000057403111 0.96000057403111 0.96000057403111 0.9600078024614 0.9600078024614 0.9600078024614 0.9600078024614 0.9600078024614 0.9600078024614 0.9600078024614 0.9600078024614 0.9600078024614 0.9600078024614 0.9600078024614 0.9600078024614 0.9600078024614 0.9600078024614 0.9600078024614 0.9600078024614 0.9600078024614 0.9600078024614 0.9600078024614 0.9600078024614 0.9600078024614 0.9600078024614 0.9600078024614 0.9600078024614 0.9600078024614 0.96006802884276 0.96006802884276 0.96006802884276 0.96006802884276 0.96006802884276 0.96006802884276 0.96006802884276 0.96006802884276 0.96006802884276 0.96006802884276 0.96006802884276 0.96006802884276 0.96006802884276 0.96006802884276 0.96006802884276 0.96006802884276 0.96006802884276 0.96006802884276 0.96006802884276 0.96006802884276 0.96006802884276 0.96006802884276 0.96006802884276 0.96006802884276 0.96006802884276 0.96038137379852 0.96038137379852 0.96038137379852 0.96038137379852 0.96038137379852 0.96038137379852 0.96038137379852 0.96038137379852 0.96038137379852 0.96038137379852 0.96038137379852 0.96038137379852 0.96038137379852 0.96038137379852 0.96038137379852 0.96038137379852 0.96038137379852 0.96038137379852 0.96038137379852 0.96038137379852 0.96038137379852 0.96038137379852 0.96038137379852 0.96038137379852 0.96038137379852 0.96137903643732 0.96137903643732 0.96137903643732 0.96137903643732 0.96137903643732 0.96137903643732 0.96137903643732 0.96137903643732 0.96137903643732 0.96137903643732 0.96137903643732 0.96137903643732 0.96137903643732 0.96137903643732 0.96137903643732 0.96137903643732 0.96137903643732 0.96137903643732 0.96137903643732 0.96137903643732 0.96137903643732 0.96137903643732 0.96137903643732 0.96137903643732 0.96137903643732 0.96321014680893 0.96321014680893 0.96321014680893 0.96321014680893 0.96321014680893 0.96321014680893 0.96321014680893 0.96321014680893 0.96321014680893 0.96321014680893 0.96321014680893 0.96321014680893 0.96321014680893 0.96321014680893 0.96321014680893 0.96321014680893 0.96321014680893 0.96321014680893 0.96321014680893 0.96321014680893 0.96321014680893 0.96321014680893 0.96321014680893 0.96321014680893 0.96321014680893 0.96472448360735 0.96472448360735 0.96472448360735 0.96472448360735 0.96472448360735 0.96472448360735 0.96472448360735 0.96472448360735 0.96472448360735 0.96472448360735 0.96472448360735 0.96472448360735 0.96472448360735 0.96472448360735 0.96472448360735 0.96472448360735 0.96472448360735 0.96472448360735 0.96472448360735 0.96472448360735 0.96472448360735 0.96472448360735 0.96472448360735 0.96472448360735 0.96472448360735 0.96430483319369 0.96430483319369 0.96430483319369 0.96430483319369 0.96430483319369 0.96430483319369 0.96430483319369 0.96430483319369 0.96430483319369 0.96430483319369 0.96430483319369 0.96430483319369 0.96430483319369 0.96430483319369 0.96430483319369 0.96430483319369 0.96430483319369 0.96430483319369 0.96430483319369 0.96430483319369 0.96430483319369 0.96430483319369 0.96430483319369 0.96430483319369 0.96430483319369 0.96019082432575 0.96019082432575 0.96019082432575 0.96019082432575 0.96019082432575 0.96019082432575 0.96019082432575 0.96019082432575 0.96019082432575 0.96019082432575 0.96019082432575 0.96019082432575 0.96019082432575 0.96019082432575 0.96019082432575 0.96019082432575 0.96019082432575 0.96019082432575 0.96019082432575 0.96019082432575 0.96019082432575 0.96019082432575 0.96019082432575 0.96019082432575 0.96019082432575 0.96000932467124 0.96000932467124 0.96000932467124 0.96000932467124 0.96000932467124 0.96000932467124 0.96000932467124 0.96000932467124 0.96000932467124 0.96000932467124 0.96000932467124 0.96000932467124 0.96000932467124 0.96000932467124 0.96000932467124 0.96000932467124 0.96000932467124 0.96000932467124 0.96000932467124 0.96000932467124 0.96000932467124 0.96000932467124 0.96000932467124 0.96000932467124 0.96000932467124 0.96000014529282 0.96000014529282 0.96000014529282 0.96000014529282 0.96000014529282 0.96000014529282 0.96000014529282 0.96000014529282 0.96000014529282 0.96000014529282 0.96000014529282 0.96000014529282 0.96000014529282 0.96000014529282 0.96000014529282 0.96000014529282 0.96000014529282 0.96000014529282 0.96000014529282 0.96000014529282 0.96000014529282 0.96000014529282 0.96000014529282 0.96000014529282 0.96000014529282 0.96000000210283 0.96000000210283 0.96000000210283 0.96000000210283 0.96000000210283 0.96000000210283 0.96000000210283 0.96000000210283 0.96000000210283 0.96000000210283 0.96000000210283 0.96000000210283 0.96000000210283 0.96000000210283 0.96000000210283 0.96000000210283 0.96000000210283 0.96000000210283 0.96000000210283 0.96000000210283 0.96000000210283 0.96000000210283 0.96000000210283 0.96000000210283 0.96000000210283 0.96000000002503 0.96000000002503 0.96000000002503 0.96000000002503 0.96000000002503 0.96000000002503 0.96000000002503 0.96000000002503 0.96000000002503 0.96000000002503 0.96000000002503 0.96000000002503 0.96000000002503 0.96000000002503 0.96000000002503 0.96000000002503 0.96000000002503 0.96000000002503 0.96000000002503 0.96000000002503 0.96000000002503 0.96000000002503 0.96000000002503 0.96000000002503 0.96000000002503 0.96000000000025 0.96000000000025 0.96000000000025 0.96000000000025 0.96000000000025 0.96000000000025 0.96000000000025 0.96000000000025 0.96000000000025 0.96000000000025 0.96000000000025 0.96000000000025 0.96000000000025 0.96000000000025 0.96000000000025 0.96000000000025 0.96000000000025 0.96000000000025 0.96000000000025 0.96000000000025 0.96000000000025 0.96000000000025 0.96000000000025 0.96000000000025 0.96000000000025 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.96000000000049 0.96000000000049 0.96000000000049 0.96000000000049 0.96000000000049 0.96000000000049 0.96000000000049 0.96000000000049 0.96000000000049 0.96000000000049 0.96000000000049 0.96000000000049 0.96000000000049 0.96000000000049 0.96000000000049 0.96000000000049 0.96000000000049 0.96000000000049 0.96000000000049 0.96000000000049 0.96000000000049 0.96000000000049 0.96000000000049 0.96000000000049 0.96000000000049 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000804388 0.96000000804388 0.96000000804388 0.96000000804388 0.96000000804388 0.96000000804388 0.96000000804388 0.96000000804388 0.96000000804388 0.96000000804388 0.96000000804388 0.96000000804388 0.96000000804388 0.96000000804388 0.96000000804388 0.96000000804388 0.96000000804388 0.96000000804388 0.96000000804388 0.96000000804388 0.96000000804388 0.96000000804388 0.96000000804388 0.96000000804388 0.96000000804388 0.96000020225341 0.96000020225341 0.96000020225341 0.96000020225341 0.96000020225341 0.96000020225341 0.96000020225341 0.96000020225341 0.96000020225341 0.96000020225341 0.96000020225341 0.96000020225341 0.96000020225341 0.96000020225341 0.96000020225341 0.96000020225341 0.96000020225341 0.96000020225341 0.96000020225341 0.96000020225341 0.96000020225341 0.96000020225341 0.96000020225341 0.96000020225341 0.96000020225341 0.96000325281143 0.96000325281143 0.96000325281143 0.96000325281143 0.96000325281143 0.96000325281143 0.96000325281143 0.96000325281143 0.96000325281143 0.96000325281143 0.96000325281143 0.96000325281143 0.96000325281143 0.96000325281143 0.96000325281143 0.96000325281143 0.96000325281143 0.96000325281143 0.96000325281143 0.96000325281143 0.96000325281143 0.96000325281143 0.96000325281143 0.96000325281143 0.96000325281143 0.96003298088296 0.96003298088296 0.96003298088296 0.96003298088296 0.96003298088296 0.96003298088296 0.96003298088296 0.96003298088296 0.96003298088296 0.96003298088296 0.96003298088296 0.96003298088296 0.96003298088296 0.96003298088296 0.96003298088296 0.96003298088296 0.96003298088296 0.96003298088296 0.96003298088296 0.96003298088296 0.96003298088296 0.96003298088296 0.96003298088296 0.96003298088296 0.96003298088296 0.96021653301433 0.96021653301433 0.96021653301433 0.96021653301433 0.96021653301433 0.96021653301433 0.96021653301433 0.96021653301433 0.96021653301433 0.96021653301433 0.96021653301433 0.96021653301433 0.96021653301433 0.96021653301433 0.96021653301433 0.96021653301433 0.96021653301433 0.96021653301433 0.96021653301433 0.96021653301433 0.96021653301433 0.96021653301433 0.96021653301433 0.96021653301433 0.96021653301433 0.9609147657699 0.9609147657699 0.9609147657699 0.9609147657699 0.9609147657699 0.9609147657699 0.9609147657699 0.9609147657699 0.9609147657699 0.9609147657699 0.9609147657699 0.9609147657699 0.9609147657699 0.9609147657699 0.9609147657699 0.9609147657699 0.9609147657699 0.9609147657699 0.9609147657699 0.9609147657699 0.9609147657699 0.9609147657699 0.9609147657699 0.9609147657699 0.9609147657699 0.96249799243187 0.96249799243187 0.96249799243187 0.96249799243187 0.96249799243187 0.96249799243187 0.96249799243187 0.96249799243187 0.96249799243187 0.96249799243187 0.96249799243187 0.96249799243187 0.96249799243187 0.96249799243187 0.96249799243187 0.96249799243187 0.96249799243187 0.96249799243187 0.96249799243187 0.96249799243187 0.96249799243187 0.96249799243187 0.96249799243187 0.96249799243187 0.96249799243187 0.964334322046 0.964334322046 0.964334322046 0.964334322046 0.964334322046 0.964334322046 0.964334322046 0.964334322046 0.964334322046 0.964334322046 0.964334322046 0.964334322046 0.964334322046 0.964334322046 0.964334322046 0.964334322046 0.964334322046 0.964334322046 0.964334322046 0.964334322046 0.964334322046 0.964334322046 0.964334322046 0.964334322046 0.964334322046 0.96481258179925 0.96481258179925 0.96481258179925 0.96481258179925 0.96481258179925 0.96481258179925 0.96481258179925 0.96481258179925 0.96481258179925 0.96481258179925 0.96481258179925 0.96481258179925 0.96481258179925 0.96481258179925 0.96481258179925 0.96481258179925 0.96481258179925 0.96481258179925 0.96481258179925 0.96481258179925 0.96481258179925 0.96481258179925 0.96481258179925 0.96481258179925 0.96481258179925 0.96336759080543 0.96336759080543 0.96336759080543 0.96336759080543 0.96336759080543 0.96336759080543 0.96336759080543 0.96336759080543 0.96336759080543 0.96336759080543 0.96336759080543 0.96336759080543 0.96336759080543 0.96336759080543 0.96336759080543 0.96336759080543 0.96336759080543 0.96336759080543 0.96336759080543 0.96336759080543 0.96336759080543 0.96336759080543 0.96336759080543 0.96336759080543 0.96336759080543 0.96143584361298 0.96143584361298 0.96143584361298 0.96143584361298 0.96143584361298 0.96143584361298 0.96143584361298 0.96143584361298 0.96143584361298 0.96143584361298 0.96143584361298 0.96143584361298 0.96143584361298 0.96143584361298 0.96143584361298 0.96143584361298 0.96143584361298 0.96143584361298 0.96143584361298 0.96143584361298 0.96143584361298 0.96143584361298 0.96143584361298 0.96143584361298 0.96143584361298 0.96040089864196 0.96040089864196 0.96040089864196 0.96040089864196 0.96040089864196 0.96040089864196 0.96040089864196 0.96040089864196 0.96040089864196 0.96040089864196 0.96040089864196 0.96040089864196 0.96040089864196 0.96040089864196 0.96040089864196 0.96040089864196 0.96040089864196 0.96040089864196 0.96040089864196 0.96040089864196 0.96040089864196 0.96040089864196 0.96040089864196 0.96040089864196 0.96040089864196 0.96000697925381 0.96000697925381 0.96000697925381 0.96000697925381 0.96000697925381 0.96000697925381 0.96000697925381 0.96000697925381 0.96000697925381 0.96000697925381 0.96000697925381 0.96000697925381 0.96000697925381 0.96000697925381 0.96000697925381 0.96000697925381 0.96000697925381 0.96000697925381 0.96000697925381 0.96000697925381 0.96000697925381 0.96000697925381 0.96000697925381 0.96000697925381 0.96000697925381 0.96000011362105 0.96000011362105 0.96000011362105 0.96000011362105 0.96000011362105 0.96000011362105 0.96000011362105 0.96000011362105 0.96000011362105 0.96000011362105 0.96000011362105 0.96000011362105 0.96000011362105 0.96000011362105 0.96000011362105 0.96000011362105 0.96000011362105 0.96000011362105 0.96000011362105 0.96000011362105 0.96000011362105 0.96000011362105 0.96000011362105 0.96000011362105 0.96000011362105 0.9600000014265 0.9600000014265 0.9600000014265 0.9600000014265 0.9600000014265 0.9600000014265 0.9600000014265 0.9600000014265 0.9600000014265 0.9600000014265 0.9600000014265 0.9600000014265 0.9600000014265 0.9600000014265 0.9600000014265 0.9600000014265 0.9600000014265 0.9600000014265 0.9600000014265 0.9600000014265 0.9600000014265 0.9600000014265 0.9600000014265 0.9600000014265 0.9600000014265 0.96000000001533 0.96000000001533 0.96000000001533 0.96000000001533 0.96000000001533 0.96000000001533 0.96000000001533 0.96000000001533 0.96000000001533 0.96000000001533 0.96000000001533 0.96000000001533 0.96000000001533 0.96000000001533 0.96000000001533 0.96000000001533 0.96000000001533 0.96000000001533 0.96000000001533 0.96000000001533 0.96000000001533 0.96000000001533 0.96000000001533 0.96000000001533 0.96000000001533 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.95999999999997 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.96000000000005 0.96000000000005 0.96000000000005 0.96000000000005 0.96000000000005 0.96000000000005 0.96000000000005 0.96000000000005 0.96000000000005 0.96000000000005 0.96000000000005 0.96000000000005 0.96000000000005 0.96000000000005 0.96000000000005 0.96000000000005 0.96000000000005 0.96000000000005 0.96000000000005 0.96000000000005 0.96000000000005 0.96000000000005 0.96000000000005 0.96000000000005 0.96000000000005 0.96000000000918 0.96000000000918 0.96000000000918 0.96000000000918 0.96000000000918 0.96000000000918 0.96000000000918 0.96000000000918 0.96000000000918 0.96000000000918 0.96000000000918 0.96000000000918 0.96000000000918 0.96000000000918 0.96000000000918 0.96000000000918 0.96000000000918 0.96000000000918 0.96000000000918 0.96000000000918 0.96000000000918 0.96000000000918 0.96000000000918 0.96000000000918 0.96000000000918 0.96000000079179 0.96000000079179 0.96000000079179 0.96000000079179 0.96000000079179 0.96000000079179 0.96000000079179 0.96000000079179 0.96000000079179 0.96000000079179 0.96000000079179 0.96000000079179 0.96000000079179 0.96000000079179 0.96000000079179 0.96000000079179 0.96000000079179 0.96000000079179 0.96000000079179 0.96000000079179 0.96000000079179 0.96000000079179 0.96000000079179 0.96000000079179 0.96000000079179 0.96000003419278 0.96000003419278 0.96000003419278 0.96000003419278 0.96000003419278 0.96000003419278 0.96000003419278 0.96000003419278 0.96000003419278 0.96000003419278 0.96000003419278 0.96000003419278 0.96000003419278 0.96000003419278 0.96000003419278 0.96000003419278 0.96000003419278 0.96000003419278 0.96000003419278 0.96000003419278 0.96000003419278 0.96000003419278 0.96000003419278 0.96000003419278 0.96000003419278 0.9600149885594 0.9600149885594 0.9600149885594 0.9600149885594 0.9600149885594 0.9600149885594 0.9600149885594 0.9600149885594 0.9600149885594 0.9600149885594 0.9600149885594 0.9600149885594 0.9600149885594 0.9600149885594 0.9600149885594 0.9600149885594 0.9600149885594 0.9600149885594 0.9600149885594 0.9600149885594 0.9600149885594 0.9600149885594 0.9600149885594 0.9600149885594 0.9600149885594 0.96011618398765 0.96011618398765 0.96011618398765 0.96011618398765 0.96011618398765 0.96011618398765 0.96011618398765 0.96011618398765 0.96011618398765 0.96011618398765 0.96011618398765 0.96011618398765 0.96011618398765 0.96011618398765 0.96011618398765 0.96011618398765 0.96011618398765 0.96011618398765 0.96011618398765 0.96011618398765 0.96011618398765 0.96011618398765 0.96011618398765 0.96011618398765 0.96011618398765 0.96057389899636 0.96057389899636 0.96057389899636 0.96057389899636 0.96057389899636 0.96057389899636 0.96057389899636 0.96057389899636 0.96057389899636 0.96057389899636 0.96057389899636 0.96057389899636 0.96057389899636 0.96057389899636 0.96057389899636 0.96057389899636 0.96057389899636 0.96057389899636 0.96057389899636 0.96057389899636 0.96057389899636 0.96057389899636 0.96057389899636 0.96057389899636 0.96057389899636 0.96183629361123 0.96183629361123 0.96183629361123 0.96183629361123 0.96183629361123 0.96183629361123 0.96183629361123 0.96183629361123 0.96183629361123 0.96183629361123 0.96183629361123 0.96183629361123 0.96183629361123 0.96183629361123 0.96183629361123 0.96183629361123 0.96183629361123 0.96183629361123 0.96183629361123 0.96183629361123 0.96183629361123 0.96183629361123 0.96183629361123 0.96183629361123 0.96183629361123 0.96374953553679 0.96374953553679 0.96374953553679 0.96374953553679 0.96374953553679 0.96374953553679 0.96374953553679 0.96374953553679 0.96374953553679 0.96374953553679 0.96374953553679 0.96374953553679 0.96374953553679 0.96374953553679 0.96374953553679 0.96374953553679 0.96374953553679 0.96374953553679 0.96374953553679 0.96374953553679 0.96374953553679 0.96374953553679 0.96374953553679 0.96374953553679 0.96374953553679 0.96487828647848 0.96487828647848 0.96487828647848 0.96487828647848 0.96487828647848 0.96487828647848 0.96487828647848 0.96487828647848 0.96487828647848 0.96487828647848 0.96487828647848 0.96487828647848 0.96487828647848 0.96487828647848 0.96487828647848 0.96487828647848 0.96487828647848 0.96487828647848 0.96487828647848 0.96487828647848 0.96487828647848 0.96487828647848 0.96487828647848 0.96487828647848 0.96487828647848 0.96403753353408 0.96403753353408 0.96403753353408 0.96403753353408 0.96403753353408 0.96403753353408 0.96403753353408 0.96403753353408 0.96403753353408 0.96403753353408 0.96403753353408 0.96403753353408 0.96403753353408 0.96403753353408 0.96403753353408 0.96403753353408 0.96403753353408 0.96403753353408 0.96403753353408 0.96403753353408 0.96403753353408 0.96403753353408 0.96403753353408 0.96403753353408 0.96403753353408 0.96213071462991 0.96213071462991 0.96213071462991 0.96213071462991 0.96213071462991 0.96213071462991 0.96213071462991 0.96213071462991 0.96213071462991 0.96213071462991 0.96213071462991 0.96213071462991 0.96213071462991 0.96213071462991 0.96213071462991 0.96213071462991 0.96213071462991 0.96213071462991 0.96213071462991 0.96213071462991 0.96213071462991 0.96213071462991 0.96213071462991 0.96213071462991 0.96213071462991 0.96071011797522 0.96071011797522 0.96071011797522 0.96071011797522 0.96071011797522 0.96071011797522 0.96071011797522 0.96071011797522 0.96071011797522 0.96071011797522 0.96071011797522 0.96071011797522 0.96071011797522 0.96071011797522 0.96071011797522 0.96071011797522 0.96071011797522 0.96071011797522 0.96071011797522 0.96071011797522 0.96071011797522 0.96071011797522 0.96071011797522 0.96071011797522 0.96071011797522 0.9601508434791 0.9601508434791 0.9601508434791 0.9601508434791 0.9601508434791 0.9601508434791 0.9601508434791 0.9601508434791 0.9601508434791 0.9601508434791 0.9601508434791 0.9601508434791 0.9601508434791 0.9601508434791 0.9601508434791 0.9601508434791 0.9601508434791 0.9601508434791 0.9601508434791 0.9601508434791 0.9601508434791 0.9601508434791 0.9601508434791 0.9601508434791 0.9601508434791 0.9600196248461 0.9600196248461 0.9600196248461 0.9600196248461 0.9600196248461 0.9600196248461 0.9600196248461 0.9600196248461 0.9600196248461 0.9600196248461 0.9600196248461 0.9600196248461 0.9600196248461 0.9600196248461 0.9600196248461 0.9600196248461 0.9600196248461 0.9600196248461 0.9600196248461 0.9600196248461 0.9600196248461 0.9600196248461 0.9600196248461 0.9600196248461 0.9600196248461 0.96000036744425 0.96000036744425 0.96000036744425 0.96000036744425 0.96000036744425 0.96000036744425 0.96000036744425 0.96000036744425 0.96000036744425 0.96000036744425 0.96000036744425 0.96000036744425 0.96000036744425 0.96000036744425 0.96000036744425 0.96000036744425 0.96000036744425 0.96000036744425 0.96000036744425 0.96000036744425 0.96000036744425 0.96000036744425 0.96000036744425 0.96000036744425 0.96000036744425 0.96000000570381 0.96000000570381 0.96000000570381 0.96000000570381 0.96000000570381 0.96000000570381 0.96000000570381 0.96000000570381 0.96000000570381 0.96000000570381 0.96000000570381 0.96000000570381 0.96000000570381 0.96000000570381 0.96000000570381 0.96000000570381 0.96000000570381 0.96000000570381 0.96000000570381 0.96000000570381 0.96000000570381 0.96000000570381 0.96000000570381 0.96000000570381 0.96000000570381 0.96000000007383 0.96000000007383 0.96000000007383 0.96000000007383 0.96000000007383 0.96000000007383 0.96000000007383 0.96000000007383 0.96000000007383 0.96000000007383 0.96000000007383 0.96000000007383 0.96000000007383 0.96000000007383 0.96000000007383 0.96000000007383 0.96000000007383 0.96000000007383 0.96000000007383 0.96000000007383 0.96000000007383 0.96000000007383 0.96000000007383 0.96000000007383 0.96000000007383 0.96000000000109 0.96000000000109 0.96000000000109 0.96000000000109 0.96000000000109 0.96000000000109 0.96000000000109 0.96000000000109 0.96000000000109 0.96000000000109 0.96000000000109 0.96000000000109 0.96000000000109 0.96000000000109 0.96000000000109 0.96000000000109 0.96000000000109 0.96000000000109 0.96000000000109 0.96000000000109 0.96000000000109 0.96000000000109 0.96000000000109 0.96000000000109 0.96000000000109 0.95999999999988 0.95999999999988 0.95999999999988 0.95999999999988 0.95999999999988 0.95999999999988 0.95999999999988 0.95999999999988 0.95999999999988 0.95999999999988 0.95999999999988 0.95999999999988 0.95999999999988 0.95999999999988 0.95999999999988 0.95999999999988 0.95999999999988 0.95999999999988 0.95999999999988 0.95999999999988 0.95999999999988 0.95999999999988 0.95999999999988 0.95999999999988 0.95999999999988 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.96000000000232 0.96000000000232 0.96000000000232 0.96000000000232 0.96000000000232 0.96000000000232 0.96000000000232 0.96000000000232 0.96000000000232 0.96000000000232 0.96000000000232 0.96000000000232 0.96000000000232 0.96000000000232 0.96000000000232 0.96000000000232 0.96000000000232 0.96000000000232 0.96000000000232 0.96000000000232 0.96000000000232 0.96000000000232 0.96000000000232 0.96000000000232 0.96000000000232 0.96000000018275 0.96000000018275 0.96000000018275 0.96000000018275 0.96000000018275 0.96000000018275 0.96000000018275 0.96000000018275 0.96000000018275 0.96000000018275 0.96000000018275 0.96000000018275 0.96000000018275 0.96000000018275 0.96000000018275 0.96000000018275 0.96000000018275 0.96000000018275 0.96000000018275 0.96000000018275 0.96000000018275 0.96000000018275 0.96000000018275 0.96000000018275 0.96000000018275 0.96000001363188 0.96000001363188 0.96000001363188 0.96000001363188 0.96000001363188 0.96000001363188 0.96000001363188 0.96000001363188 0.96000001363188 0.96000001363188 0.96000001363188 0.96000001363188 0.96000001363188 0.96000001363188 0.96000001363188 0.96000001363188 0.96000001363188 0.96000001363188 0.96000001363188 0.96000001363188 0.96000001363188 0.96000001363188 0.96000001363188 0.96000001363188 0.96000001363188 0.96000111210589 0.96000111210589 0.96000111210589 0.96000111210589 0.96000111210589 0.96000111210589 0.96000111210589 0.96000111210589 0.96000111210589 0.96000111210589 0.96000111210589 0.96000111210589 0.96000111210589 0.96000111210589 0.96000111210589 0.96000111210589 0.96000111210589 0.96000111210589 0.96000111210589 0.96000111210589 0.96000111210589 0.96000111210589 0.96000111210589 0.96000111210589 0.96000111210589 0.96033224617124 0.96033224617124 0.96033224617124 0.96033224617124 0.96033224617124 0.96033224617124 0.96033224617124 0.96033224617124 0.96033224617124 0.96033224617124 0.96033224617124 0.96033224617124 0.96033224617124 0.96033224617124 0.96033224617124 0.96033224617124 0.96033224617124 0.96033224617124 0.96033224617124 0.96033224617124 0.96033224617124 0.96033224617124 0.96033224617124 0.96033224617124 0.96033224617124 0.96126932110788 0.96126932110788 0.96126932110788 0.96126932110788 0.96126932110788 0.96126932110788 0.96126932110788 0.96126932110788 0.96126932110788 0.96126932110788 0.96126932110788 0.96126932110788 0.96126932110788 0.96126932110788 0.96126932110788 0.96126932110788 0.96126932110788 0.96126932110788 0.96126932110788 0.96126932110788 0.96126932110788 0.96126932110788 0.96126932110788 0.96126932110788 0.96126932110788 0.96305949909787 0.96305949909787 0.96305949909787 0.96305949909787 0.96305949909787 0.96305949909787 0.96305949909787 0.96305949909787 0.96305949909787 0.96305949909787 0.96305949909787 0.96305949909787 0.96305949909787 0.96305949909787 0.96305949909787 0.96305949909787 0.96305949909787 0.96305949909787 0.96305949909787 0.96305949909787 0.96305949909787 0.96305949909787 0.96305949909787 0.96305949909787 0.96305949909787 0.96466883490351 0.96466883490351 0.96466883490351 0.96466883490351 0.96466883490351 0.96466883490351 0.96466883490351 0.96466883490351 0.96466883490351 0.96466883490351 0.96466883490351 0.96466883490351 0.96466883490351 0.96466883490351 0.96466883490351 0.96466883490351 0.96466883490351 0.96466883490351 0.96466883490351 0.96466883490351 0.96466883490351 0.96466883490351 0.96466883490351 0.96466883490351 0.96466883490351 0.96456048864478 0.96456048864478 0.96456048864478 0.96456048864478 0.96456048864478 0.96456048864478 0.96456048864478 0.96456048864478 0.96456048864478 0.96456048864478 0.96456048864478 0.96456048864478 0.96456048864478 0.96456048864478 0.96456048864478 0.96456048864478 0.96456048864478 0.96456048864478 0.96456048864478 0.96456048864478 0.96456048864478 0.96456048864478 0.96456048864478 0.96456048864478 0.96456048864478 0.96281609353146 0.96281609353146 0.96281609353146 0.96281609353146 0.96281609353146 0.96281609353146 0.96281609353146 0.96281609353146 0.96281609353146 0.96281609353146 0.96281609353146 0.96281609353146 0.96281609353146 0.96281609353146 0.96281609353146 0.96281609353146 0.96281609353146 0.96281609353146 0.96281609353146 0.96281609353146 0.96281609353146 0.96281609353146 0.96281609353146 0.96281609353146 0.96281609353146 0.96111125786873 0.96111125786873 0.96111125786873 0.96111125786873 0.96111125786873 0.96111125786873 0.96111125786873 0.96111125786873 0.96111125786873 0.96111125786873 0.96111125786873 0.96111125786873 0.96111125786873 0.96111125786873 0.96111125786873 0.96111125786873 0.96111125786873 0.96111125786873 0.96111125786873 0.96111125786873 0.96111125786873 0.96111125786873 0.96111125786873 0.96111125786873 0.96111125786873 0.96027471074325 0.96027471074325 0.96027471074325 0.96027471074325 0.96027471074325 0.96027471074325 0.96027471074325 0.96027471074325 0.96027471074325 0.96027471074325 0.96027471074325 0.96027471074325 0.96027471074325 0.96027471074325 0.96027471074325 0.96027471074325 0.96027471074325 0.96027471074325 0.96027471074325 0.96027471074325 0.96027471074325 0.96027471074325 0.96027471074325 0.96027471074325 0.96027471074325 0.96004459277341 0.96004459277341 0.96004459277341 0.96004459277341 0.96004459277341 0.96004459277341 0.96004459277341 0.96004459277341 0.96004459277341 0.96004459277341 0.96004459277341 0.96004459277341 0.96004459277341 0.96004459277341 0.96004459277341 0.96004459277341 0.96004459277341 0.96004459277341 0.96004459277341 0.96004459277341 0.96004459277341 0.96004459277341 0.96004459277341 0.96004459277341 0.96004459277341 0.96000499233933 0.96000499233933 0.96000499233933 0.96000499233933 0.96000499233933 0.96000499233933 0.96000499233933 0.96000499233933 0.96000499233933 0.96000499233933 0.96000499233933 0.96000499233933 0.96000499233933 0.96000499233933 0.96000499233933 0.96000499233933 0.96000499233933 0.96000499233933 0.96000499233933 0.96000499233933 0.96000499233933 0.96000499233933 0.96000499233933 0.96000499233933 0.96000499233933 0.96000031117462 0.96000031117462 0.96000031117462 0.96000031117462 0.96000031117462 0.96000031117462 0.96000031117462 0.96000031117462 0.96000031117462 0.96000031117462 0.96000031117462 0.96000031117462 0.96000031117462 0.96000031117462 0.96000031117462 0.96000031117462 0.96000031117462 0.96000031117462 0.96000031117462 0.96000031117462 0.96000031117462 0.96000031117462 0.96000031117462 0.96000031117462 0.96000031117462 0.96000001433426 0.96000001433426 0.96000001433426 0.96000001433426 0.96000001433426 0.96000001433426 0.96000001433426 0.96000001433426 0.96000001433426 0.96000001433426 0.96000001433426 0.96000001433426 0.96000001433426 0.96000001433426 0.96000001433426 0.96000001433426 0.96000001433426 0.96000001433426 0.96000001433426 0.96000001433426 0.96000001433426 0.96000001433426 0.96000001433426 0.96000001433426 0.96000001433426 0.96000000025446 0.96000000025446 0.96000000025446 0.96000000025446 0.96000000025446 0.96000000025446 0.96000000025446 0.96000000025446 0.96000000025446 0.96000000025446 0.96000000025446 0.96000000025446 0.96000000025446 0.96000000025446 0.96000000025446 0.96000000025446 0.96000000025446 0.96000000025446 0.96000000025446 0.96000000025446 0.96000000025446 0.96000000025446 0.96000000025446 0.96000000025446 0.96000000025446 0.96000000000415 0.96000000000415 0.96000000000415 0.96000000000415 0.96000000000415 0.96000000000415 0.96000000000415 0.96000000000415 0.96000000000415 0.96000000000415 0.96000000000415 0.96000000000415 0.96000000000415 0.96000000000415 0.96000000000415 0.96000000000415 0.96000000000415 0.96000000000415 0.96000000000415 0.96000000000415 0.96000000000415 0.96000000000415 0.96000000000415 0.96000000000415 0.96000000000415 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.95999999999996 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.96000000000022 0.9600000000212 0.9600000000212 0.9600000000212 0.9600000000212 0.9600000000212 0.9600000000212 0.9600000000212 0.9600000000212 0.9600000000212 0.9600000000212 0.9600000000212 0.9600000000212 0.9600000000212 0.9600000000212 0.9600000000212 0.9600000000212 0.9600000000212 0.9600000000212 0.9600000000212 0.9600000000212 0.9600000000212 0.9600000000212 0.9600000000212 0.9600000000212 0.9600000000212 0.960000001965 0.960000001965 0.960000001965 0.960000001965 0.960000001965 0.960000001965 0.960000001965 0.960000001965 0.960000001965 0.960000001965 0.960000001965 0.960000001965 0.960000001965 0.960000001965 0.960000001965 0.960000001965 0.960000001965 0.960000001965 0.960000001965 0.960000001965 0.960000001965 0.960000001965 0.960000001965 0.960000001965 0.960000001965 0.96000015611273 0.96000015611273 0.96000015611273 0.96000015611273 0.96000015611273 0.96000015611273 0.96000015611273 0.96000015611273 0.96000015611273 0.96000015611273 0.96000015611273 0.96000015611273 0.96000015611273 0.96000015611273 0.96000015611273 0.96000015611273 0.96000015611273 0.96000015611273 0.96000015611273 0.96000015611273 0.96000015611273 0.96000015611273 0.96000015611273 0.96000015611273 0.96000015611273 0.96001764480948 0.96001764480948 0.96001764480948 0.96001764480948 0.96001764480948 0.96001764480948 0.96001764480948 0.96001764480948 0.96001764480948 0.96001764480948 0.96001764480948 0.96001764480948 0.96001764480948 0.96001764480948 0.96001764480948 0.96001764480948 0.96001764480948 0.96001764480948 0.96001764480948 0.96001764480948 0.96001764480948 0.96001764480948 0.96001764480948 0.96001764480948 0.96001764480948 0.96006279164586 0.96006279164586 0.96006279164586 0.96006279164586 0.96006279164586 0.96006279164586 0.96006279164586 0.96006279164586 0.96006279164586 0.96006279164586 0.96006279164586 0.96006279164586 0.96006279164586 0.96006279164586 0.96006279164586 0.96006279164586 0.96006279164586 0.96006279164586 0.96006279164586 0.96006279164586 0.96006279164586 0.96006279164586 0.96006279164586 0.96006279164586 0.96006279164586 0.96400989035802 0.96400989035802 0.96400989035802 0.96400989035802 0.96400989035802 0.96400989035802 0.96400989035802 0.96400989035802 0.96400989035802 0.96400989035802 0.96400989035802 0.96400989035802 0.96400989035802 0.96400989035802 0.96400989035802 0.96400989035802 0.96400989035802 0.96400989035802 0.96400989035802 0.96400989035802 0.96400989035802 0.96400989035802 0.96400989035802 0.96400989035802 0.96400989035802 0.96485606976477 0.96485606976477 0.96485606976477 0.96485606976477 0.96485606976477 0.96485606976477 0.96485606976477 0.96485606976477 0.96485606976477 0.96485606976477 0.96485606976477 0.96485606976477 0.96485606976477 0.96485606976477 0.96485606976477 0.96485606976477 0.96485606976477 0.96485606976477 0.96485606976477 0.96485606976477 0.96485606976477 0.96485606976477 0.96485606976477 0.96485606976477 0.96485606976477 0.96351313793838 0.96351313793838 0.96351313793838 0.96351313793838 0.96351313793838 0.96351313793838 0.96351313793838 0.96351313793838 0.96351313793838 0.96351313793838 0.96351313793838 0.96351313793838 0.96351313793838 0.96351313793838 0.96351313793838 0.96351313793838 0.96351313793838 0.96351313793838 0.96351313793838 0.96351313793838 0.96351313793838 0.96351313793838 0.96351313793838 0.96351313793838 0.96351313793838 0.96163554558384 0.96163554558384 0.96163554558384 0.96163554558384 0.96163554558384 0.96163554558384 0.96163554558384 0.96163554558384 0.96163554558384 0.96163554558384 0.96163554558384 0.96163554558384 0.96163554558384 0.96163554558384 0.96163554558384 0.96163554558384 0.96163554558384 0.96163554558384 0.96163554558384 0.96163554558384 0.96163554558384 0.96163554558384 0.96163554558384 0.96163554558384 0.96163554558384 0.96047642292959 0.96047642292959 0.96047642292959 0.96047642292959 0.96047642292959 0.96047642292959 0.96047642292959 0.96047642292959 0.96047642292959 0.96047642292959 0.96047642292959 0.96047642292959 0.96047642292959 0.96047642292959 0.96047642292959 0.96047642292959 0.96047642292959 0.96047642292959 0.96047642292959 0.96047642292959 0.96047642292959 0.96047642292959 0.96047642292959 0.96047642292959 0.96047642292959 0.9600895136462 0.9600895136462 0.9600895136462 0.9600895136462 0.9600895136462 0.9600895136462 0.9600895136462 0.9600895136462 0.9600895136462 0.9600895136462 0.9600895136462 0.9600895136462 0.9600895136462 0.9600895136462 0.9600895136462 0.9600895136462 0.9600895136462 0.9600895136462 0.9600895136462 0.9600895136462 0.9600895136462 0.9600895136462 0.9600895136462 0.9600895136462 0.9600895136462 0.96001112432289 0.96001112432289 0.96001112432289 0.96001112432289 0.96001112432289 0.96001112432289 0.96001112432289 0.96001112432289 0.96001112432289 0.96001112432289 0.96001112432289 0.96001112432289 0.96001112432289 0.96001112432289 0.96001112432289 0.96001112432289 0.96001112432289 0.96001112432289 0.96001112432289 0.96001112432289 0.96001112432289 0.96001112432289 0.96001112432289 0.96001112432289 0.96001112432289 0.96000091493657 0.96000091493657 0.96000091493657 0.96000091493657 0.96000091493657 0.96000091493657 0.96000091493657 0.96000091493657 0.96000091493657 0.96000091493657 0.96000091493657 0.96000091493657 0.96000091493657 0.96000091493657 0.96000091493657 0.96000091493657 0.96000091493657 0.96000091493657 0.96000091493657 0.96000091493657 0.96000091493657 0.96000091493657 0.96000091493657 0.96000091493657 0.96000091493657 0.96000005380412 0.96000005380412 0.96000005380412 0.96000005380412 0.96000005380412 0.96000005380412 0.96000005380412 0.96000005380412 0.96000005380412 0.96000005380412 0.96000005380412 0.96000005380412 0.96000005380412 0.96000005380412 0.96000005380412 0.96000005380412 0.96000005380412 0.96000005380412 0.96000005380412 0.96000005380412 0.96000005380412 0.96000005380412 0.96000005380412 0.96000005380412 0.96000005380412 0.96000000216497 0.96000000216497 0.96000000216497 0.96000000216497 0.96000000216497 0.96000000216497 0.96000000216497 0.96000000216497 0.96000000216497 0.96000000216497 0.96000000216497 0.96000000216497 0.96000000216497 0.96000000216497 0.96000000216497 0.96000000216497 0.96000000216497 0.96000000216497 0.96000000216497 0.96000000216497 0.96000000216497 0.96000000216497 0.96000000216497 0.96000000216497 0.96000000216497 0.96000000005184 0.96000000005184 0.96000000005184 0.96000000005184 0.96000000005184 0.96000000005184 0.96000000005184 0.96000000005184 0.96000000005184 0.96000000005184 0.96000000005184 0.96000000005184 0.96000000005184 0.96000000005184 0.96000000005184 0.96000000005184 0.96000000005184 0.96000000005184 0.96000000005184 0.96000000005184 0.96000000005184 0.96000000005184 0.96000000005184 0.96000000005184 0.96000000005184 0.96000000000113 0.96000000000113 0.96000000000113 0.96000000000113 0.96000000000113 0.96000000000113 0.96000000000113 0.96000000000113 0.96000000000113 0.96000000000113 0.96000000000113 0.96000000000113 0.96000000000113 0.96000000000113 0.96000000000113 0.96000000000113 0.96000000000113 0.96000000000113 0.96000000000113 0.96000000000113 0.96000000000113 0.96000000000113 0.96000000000113 0.96000000000113 0.96000000000113 0.95999999999986 0.95999999999986 0.95999999999986 0.95999999999986 0.95999999999986 0.95999999999986 0.95999999999986 0.95999999999986 0.95999999999986 0.95999999999986 0.95999999999986 0.95999999999986 0.95999999999986 0.95999999999986 0.95999999999986 0.95999999999986 0.95999999999986 0.95999999999986 0.95999999999986 0.95999999999986 0.95999999999986 0.95999999999986 0.95999999999986 0.95999999999986 0.95999999999986 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.95999999999994 0.95999999999994 0.95999999999994 0.95999999999994 0.95999999999994 0.95999999999994 0.95999999999994 0.95999999999994 0.95999999999994 0.95999999999994 0.95999999999994 0.95999999999994 0.95999999999994 0.95999999999994 0.95999999999994 0.95999999999994 0.95999999999994 0.95999999999994 0.95999999999994 0.95999999999994 0.95999999999994 0.95999999999994 0.95999999999994 0.95999999999994 0.95999999999994 0.96000000000048 0.96000000000048 0.96000000000048 0.96000000000048 0.96000000000048 0.96000000000048 0.96000000000048 0.96000000000048 0.96000000000048 0.96000000000048 0.96000000000048 0.96000000000048 0.96000000000048 0.96000000000048 0.96000000000048 0.96000000000048 0.96000000000048 0.96000000000048 0.96000000000048 0.96000000000048 0.96000000000048 0.96000000000048 0.96000000000048 0.96000000000048 0.96000000000048 0.96000000004002 0.96000000004002 0.96000000004002 0.96000000004002 0.96000000004002 0.96000000004002 0.96000000004002 0.96000000004002 0.96000000004002 0.96000000004002 0.96000000004002 0.96000000004002 0.96000000004002 0.96000000004002 0.96000000004002 0.96000000004002 0.96000000004002 0.96000000004002 0.96000000004002 0.96000000004002 0.96000000004002 0.96000000004002 0.96000000004002 0.96000000004002 0.96000000004002 0.96000000333307 0.96000000333307 0.96000000333307 0.96000000333307 0.96000000333307 0.96000000333307 0.96000000333307 0.96000000333307 0.96000000333307 0.96000000333307 0.96000000333307 0.96000000333307 0.96000000333307 0.96000000333307 0.96000000333307 0.96000000333307 0.96000000333307 0.96000000333307 0.96000000333307 0.96000000333307 0.96000000333307 0.96000000333307 0.96000000333307 0.96000000333307 0.96000000333307 0.96000032143279 0.96000032143279 0.96000032143279 0.96000032143279 0.96000032143279 0.96000032143279 0.96000032143279 0.96000032143279 0.96000032143279 0.96000032143279 0.96000032143279 0.96000032143279 0.96000032143279 0.96000032143279 0.96000032143279 0.96000032143279 0.96000032143279 0.96000032143279 0.96000032143279 0.96000032143279 0.96000032143279 0.96000032143279 0.96000032143279 0.96000032143279 0.96000032143279 0.96000308149917 0.96000308149917 0.96000308149917 0.96000308149917 0.96000308149917 0.96000308149917 0.96000308149917 0.96000308149917 0.96000308149917 0.96000308149917 0.96000308149917 0.96000308149917 0.96000308149917 0.96000308149917 0.96000308149917 0.96000308149917 0.96000308149917 0.96000308149917 0.96000308149917 0.96000308149917 0.96000308149917 0.96000308149917 0.96000308149917 0.96000308149917 0.96000308149917 0.96017194993358 0.96017194993358 0.96017194993358 0.96017194993358 0.96017194993358 0.96017194993358 0.96017194993358 0.96017194993358 0.96017194993358 0.96017194993358 0.96017194993358 0.96017194993358 0.96017194993358 0.96017194993358 0.96017194993358 0.96017194993358 0.96017194993358 0.96017194993358 0.96017194993358 0.96017194993358 0.96017194993358 0.96017194993358 0.96017194993358 0.96017194993358 0.96017194993358 0.96391155244328 0.96391155244328 0.96391155244328 0.96391155244328 0.96391155244328 0.96391155244328 0.96391155244328 0.96391155244328 0.96391155244328 0.96391155244328 0.96391155244328 0.96391155244328 0.96391155244328 0.96391155244328 0.96391155244328 0.96391155244328 0.96391155244328 0.96391155244328 0.96391155244328 0.96391155244328 0.96391155244328 0.96391155244328 0.96391155244328 0.96391155244328 0.96391155244328 0.96224311853402 0.96224311853402 0.96224311853402 0.96224311853402 0.96224311853402 0.96224311853402 0.96224311853402 0.96224311853402 0.96224311853402 0.96224311853402 0.96224311853402 0.96224311853402 0.96224311853402 0.96224311853402 0.96224311853402 0.96224311853402 0.96224311853402 0.96224311853402 0.96224311853402 0.96224311853402 0.96224311853402 0.96224311853402 0.96224311853402 0.96224311853402 0.96224311853402 0.96078380667 0.96078380667 0.96078380667 0.96078380667 0.96078380667 0.96078380667 0.96078380667 0.96078380667 0.96078380667 0.96078380667 0.96078380667 0.96078380667 0.96078380667 0.96078380667 0.96078380667 0.96078380667 0.96078380667 0.96078380667 0.96078380667 0.96078380667 0.96078380667 0.96078380667 0.96078380667 0.96078380667 0.96078380667 0.9601705079647 0.9601705079647 0.9601705079647 0.9601705079647 0.9601705079647 0.9601705079647 0.9601705079647 0.9601705079647 0.9601705079647 0.9601705079647 0.9601705079647 0.9601705079647 0.9601705079647 0.9601705079647 0.9601705079647 0.9601705079647 0.9601705079647 0.9601705079647 0.9601705079647 0.9601705079647 0.9601705079647 0.9601705079647 0.9601705079647 0.9601705079647 0.9601705079647 0.96002464093767 0.96002464093767 0.96002464093767 0.96002464093767 0.96002464093767 0.96002464093767 0.96002464093767 0.96002464093767 0.96002464093767 0.96002464093767 0.96002464093767 0.96002464093767 0.96002464093767 0.96002464093767 0.96002464093767 0.96002464093767 0.96002464093767 0.96002464093767 0.96002464093767 0.96002464093767 0.96002464093767 0.96002464093767 0.96002464093767 0.96002464093767 0.96002464093767 0.96000234110585 0.96000234110585 0.96000234110585 0.96000234110585 0.96000234110585 0.96000234110585 0.96000234110585 0.96000234110585 0.96000234110585 0.96000234110585 0.96000234110585 0.96000234110585 0.96000234110585 0.96000234110585 0.96000234110585 0.96000234110585 0.96000234110585 0.96000234110585 0.96000234110585 0.96000234110585 0.96000234110585 0.96000234110585 0.96000234110585 0.96000234110585 0.96000234110585 0.96000014892106 0.96000014892106 0.96000014892106 0.96000014892106 0.96000014892106 0.96000014892106 0.96000014892106 0.96000014892106 0.96000014892106 0.96000014892106 0.96000014892106 0.96000014892106 0.96000014892106 0.96000014892106 0.96000014892106 0.96000014892106 0.96000014892106 0.96000014892106 0.96000014892106 0.96000014892106 0.96000014892106 0.96000014892106 0.96000014892106 0.96000014892106 0.96000014892106 0.9600000065405 0.9600000065405 0.9600000065405 0.9600000065405 0.9600000065405 0.9600000065405 0.9600000065405 0.9600000065405 0.9600000065405 0.9600000065405 0.9600000065405 0.9600000065405 0.9600000065405 0.9600000065405 0.9600000065405 0.9600000065405 0.9600000065405 0.9600000065405 0.9600000065405 0.9600000065405 0.9600000065405 0.9600000065405 0.9600000065405 0.9600000065405 0.9600000065405 0.96000000020369 0.96000000020369 0.96000000020369 0.96000000020369 0.96000000020369 0.96000000020369 0.96000000020369 0.96000000020369 0.96000000020369 0.96000000020369 0.96000000020369 0.96000000020369 0.96000000020369 0.96000000020369 0.96000000020369 0.96000000020369 0.96000000020369 0.96000000020369 0.96000000020369 0.96000000020369 0.96000000020369 0.96000000020369 0.96000000020369 0.96000000020369 0.96000000020369 0.96000000000543 0.96000000000543 0.96000000000543 0.96000000000543 0.96000000000543 0.96000000000543 0.96000000000543 0.96000000000543 0.96000000000543 0.96000000000543 0.96000000000543 0.96000000000543 0.96000000000543 0.96000000000543 0.96000000000543 0.96000000000543 0.96000000000543 0.96000000000543 0.96000000000543 0.96000000000543 0.96000000000543 0.96000000000543 0.96000000000543 0.96000000000543 0.96000000000543 0.95999999999992 0.95999999999992 0.95999999999992 0.95999999999992 0.95999999999992 0.95999999999992 0.95999999999992 0.95999999999992 0.95999999999992 0.95999999999992 0.95999999999992 0.95999999999992 0.95999999999992 0.95999999999992 0.95999999999992 0.95999999999992 0.95999999999992 0.95999999999992 0.95999999999992 0.95999999999992 0.95999999999992 0.95999999999992 0.95999999999992 0.95999999999992 0.95999999999992 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.9600000000006 0.9600000000006 0.9600000000006 0.9600000000006 0.9600000000006 0.9600000000006 0.9600000000006 0.9600000000006 0.9600000000006 0.9600000000006 0.9600000000006 0.9600000000006 0.9600000000006 0.9600000000006 0.9600000000006 0.9600000000006 0.9600000000006 0.9600000000006 0.9600000000006 0.9600000000006 0.9600000000006 0.9600000000006 0.9600000000006 0.9600000000006 0.9600000000006 0.96000000005181 0.96000000005181 0.96000000005181 0.96000000005181 0.96000000005181 0.96000000005181 0.96000000005181 0.96000000005181 0.96000000005181 0.96000000005181 0.96000000005181 0.96000000005181 0.96000000005181 0.96000000005181 0.96000000005181 0.96000000005181 0.96000000005181 0.96000000005181 0.96000000005181 0.96000000005181 0.96000000005181 0.96000000005181 0.96000000005181 0.96000000005181 0.96000000005181 0.96000000471331 0.96000000471331 0.96000000471331 0.96000000471331 0.96000000471331 0.96000000471331 0.96000000471331 0.96000000471331 0.96000000471331 0.96000000471331 0.96000000471331 0.96000000471331 0.96000000471331 0.96000000471331 0.96000000471331 0.96000000471331 0.96000000471331 0.96000000471331 0.96000000471331 0.96000000471331 0.96000000471331 0.96000000471331 0.96000000471331 0.96000000471331 0.96000000471331 0.96000009639196 0.96000009639196 0.96000009639196 0.96000009639196 0.96000009639196 0.96000009639196 0.96000009639196 0.96000009639196 0.96000009639196 0.96000009639196 0.96000009639196 0.96000009639196 0.96000009639196 0.96000009639196 0.96000009639196 0.96000009639196 0.96000009639196 0.96000009639196 0.96000009639196 0.96000009639196 0.96000009639196 0.96000009639196 0.96000009639196 0.96000009639196 0.96000009639196 0.96000622376079 0.96000622376079 0.96000622376079 0.96000622376079 0.96000622376079 0.96000622376079 0.96000622376079 0.96000622376079 0.96000622376079 0.96000622376079 0.96000622376079 0.96000622376079 0.96000622376079 0.96000622376079 0.96000622376079 0.96000622376079 0.96000622376079 0.96000622376079 0.96000622376079 0.96000622376079 0.96000622376079 0.96000622376079 0.96000622376079 0.96000622376079 0.96000622376079 0.96013879588321 0.96013879588321 0.96013879588321 0.96013879588321 0.96013879588321 0.96013879588321 0.96013879588321 0.96013879588321 0.96013879588321 0.96013879588321 0.96013879588321 0.96013879588321 0.96013879588321 0.96013879588321 0.96013879588321 0.96013879588321 0.96013879588321 0.96013879588321 0.96013879588321 0.96013879588321 0.96013879588321 0.96013879588321 0.96013879588321 0.96013879588321 0.96013879588321 0.96006476986403 0.96006476986403 0.96006476986403 0.96006476986403 0.96006476986403 0.96006476986403 0.96006476986403 0.96006476986403 0.96006476986403 0.96006476986403 0.96006476986403 0.96006476986403 0.96006476986403 0.96006476986403 0.96006476986403 0.96006476986403 0.96006476986403 0.96006476986403 0.96006476986403 0.96006476986403 0.96006476986403 0.96006476986403 0.96006476986403 0.96006476986403 0.96006476986403 0.96027520928189 0.96027520928189 0.96027520928189 0.96027520928189 0.96027520928189 0.96027520928189 0.96027520928189 0.96027520928189 0.96027520928189 0.96027520928189 0.96027520928189 0.96027520928189 0.96027520928189 0.96027520928189 0.96027520928189 0.96027520928189 0.96027520928189 0.96027520928189 0.96027520928189 0.96027520928189 0.96027520928189 0.96027520928189 0.96027520928189 0.96027520928189 0.96027520928189 0.96005494775729 0.96005494775729 0.96005494775729 0.96005494775729 0.96005494775729 0.96005494775729 0.96005494775729 0.96005494775729 0.96005494775729 0.96005494775729 0.96005494775729 0.96005494775729 0.96005494775729 0.96005494775729 0.96005494775729 0.96005494775729 0.96005494775729 0.96005494775729 0.96005494775729 0.96005494775729 0.96005494775729 0.96005494775729 0.96005494775729 0.96005494775729 0.96005494775729 0.96000571977412 0.96000571977412 0.96000571977412 0.96000571977412 0.96000571977412 0.96000571977412 0.96000571977412 0.96000571977412 0.96000571977412 0.96000571977412 0.96000571977412 0.96000571977412 0.96000571977412 0.96000571977412 0.96000571977412 0.96000571977412 0.96000571977412 0.96000571977412 0.96000571977412 0.96000571977412 0.96000571977412 0.96000571977412 0.96000571977412 0.96000571977412 0.96000571977412 0.96000041848693 0.96000041848693 0.96000041848693 0.96000041848693 0.96000041848693 0.96000041848693 0.96000041848693 0.96000041848693 0.96000041848693 0.96000041848693 0.96000041848693 0.96000041848693 0.96000041848693 0.96000041848693 0.96000041848693 0.96000041848693 0.96000041848693 0.96000041848693 0.96000041848693 0.96000041848693 0.96000041848693 0.96000041848693 0.96000041848693 0.96000041848693 0.96000041848693 0.96000002077145 0.96000002077145 0.96000002077145 0.96000002077145 0.96000002077145 0.96000002077145 0.96000002077145 0.96000002077145 0.96000002077145 0.96000002077145 0.96000002077145 0.96000002077145 0.96000002077145 0.96000002077145 0.96000002077145 0.96000002077145 0.96000002077145 0.96000002077145 0.96000002077145 0.96000002077145 0.96000002077145 0.96000002077145 0.96000002077145 0.96000002077145 0.96000002077145 0.96000000072415 0.96000000072415 0.96000000072415 0.96000000072415 0.96000000072415 0.96000000072415 0.96000000072415 0.96000000072415 0.96000000072415 0.96000000072415 0.96000000072415 0.96000000072415 0.96000000072415 0.96000000072415 0.96000000072415 0.96000000072415 0.96000000072415 0.96000000072415 0.96000000072415 0.96000000072415 0.96000000072415 0.96000000072415 0.96000000072415 0.96000000072415 0.96000000072415 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000001913 0.96000000000027 0.96000000000027 0.96000000000027 0.96000000000027 0.96000000000027 0.96000000000027 0.96000000000027 0.96000000000027 0.96000000000027 0.96000000000027 0.96000000000027 0.96000000000027 0.96000000000027 0.96000000000027 0.96000000000027 0.96000000000027 0.96000000000027 0.96000000000027 0.96000000000027 0.96000000000027 0.96000000000027 0.96000000000027 0.96000000000027 0.96000000000027 0.96000000000027 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000000062 0.96000000005445 0.96000000005445 0.96000000005445 0.96000000005445 0.96000000005445 0.96000000005445 0.96000000005445 0.96000000005445 0.96000000005445 0.96000000005445 0.96000000005445 0.96000000005445 0.96000000005445 0.96000000005445 0.96000000005445 0.96000000005445 0.96000000005445 0.96000000005445 0.96000000005445 0.96000000005445 0.96000000005445 0.96000000005445 0.96000000005445 0.96000000005445 0.96000000005445 0.96000000142375 0.96000000142375 0.96000000142375 0.96000000142375 0.96000000142375 0.96000000142375 0.96000000142375 0.96000000142375 0.96000000142375 0.96000000142375 0.96000000142375 0.96000000142375 0.96000000142375 0.96000000142375 0.96000000142375 0.96000000142375 0.96000000142375 0.96000000142375 0.96000000142375 0.96000000142375 0.96000000142375 0.96000000142375 0.96000000142375 0.96000000142375 0.96000000142375 0.96000009370674 0.96000009370674 0.96000009370674 0.96000009370674 0.96000009370674 0.96000009370674 0.96000009370674 0.96000009370674 0.96000009370674 0.96000009370674 0.96000009370674 0.96000009370674 0.96000009370674 0.96000009370674 0.96000009370674 0.96000009370674 0.96000009370674 0.96000009370674 0.96000009370674 0.96000009370674 0.96000009370674 0.96000009370674 0.96000009370674 0.96000009370674 0.96000009370674 0.96000254523862 0.96000254523862 0.96000254523862 0.96000254523862 0.96000254523862 0.96000254523862 0.96000254523862 0.96000254523862 0.96000254523862 0.96000254523862 0.96000254523862 0.96000254523862 0.96000254523862 0.96000254523862 0.96000254523862 0.96000254523862 0.96000254523862 0.96000254523862 0.96000254523862 0.96000254523862 0.96000254523862 0.96000254523862 0.96000254523862 0.96000254523862 0.96000254523862 0.96000117610763 0.96000117610763 0.96000117610763 0.96000117610763 0.96000117610763 0.96000117610763 0.96000117610763 0.96000117610763 0.96000117610763 0.96000117610763 0.96000117610763 0.96000117610763 0.96000117610763 0.96000117610763 0.96000117610763 0.96000117610763 0.96000117610763 0.96000117610763 0.96000117610763 0.96000117610763 0.96000117610763 0.96000117610763 0.96000117610763 0.96000117610763 0.96000117610763 0.96000524478499 0.96000524478499 0.96000524478499 0.96000524478499 0.96000524478499 0.96000524478499 0.96000524478499 0.96000524478499 0.96000524478499 0.96000524478499 0.96000524478499 0.96000524478499 0.96000524478499 0.96000524478499 0.96000524478499 0.96000524478499 0.96000524478499 0.96000524478499 0.96000524478499 0.96000524478499 0.96000524478499 0.96000524478499 0.96000524478499 0.96000524478499 0.96000524478499 0.96000087573747 0.96000087573747 0.96000087573747 0.96000087573747 0.96000087573747 0.96000087573747 0.96000087573747 0.96000087573747 0.96000087573747 0.96000087573747 0.96000087573747 0.96000087573747 0.96000087573747 0.96000087573747 0.96000087573747 0.96000087573747 0.96000087573747 0.96000087573747 0.96000087573747 0.96000087573747 0.96000087573747 0.96000087573747 0.96000087573747 0.96000087573747 0.96000087573747 0.96000085120187 0.96000085120187 0.96000085120187 0.96000085120187 0.96000085120187 0.96000085120187 0.96000085120187 0.96000085120187 0.96000085120187 0.96000085120187 0.96000085120187 0.96000085120187 0.96000085120187 0.96000085120187 0.96000085120187 0.96000085120187 0.96000085120187 0.96000085120187 0.96000085120187 0.96000085120187 0.96000085120187 0.96000085120187 0.96000085120187 0.96000085120187 0.96000085120187 0.96000007393657 0.96000007393657 0.96000007393657 0.96000007393657 0.96000007393657 0.96000007393657 0.96000007393657 0.96000007393657 0.96000007393657 0.96000007393657 0.96000007393657 0.96000007393657 0.96000007393657 0.96000007393657 0.96000007393657 0.96000007393657 0.96000007393657 0.96000007393657 0.96000007393657 0.96000007393657 0.96000007393657 0.96000007393657 0.96000007393657 0.96000007393657 0.96000007393657 0.96000000267574 0.96000000267574 0.96000000267574 0.96000000267574 0.96000000267574 0.96000000267574 0.96000000267574 0.96000000267574 0.96000000267574 0.96000000267574 0.96000000267574 0.96000000267574 0.96000000267574 0.96000000267574 0.96000000267574 0.96000000267574 0.96000000267574 0.96000000267574 0.96000000267574 0.96000000267574 0.96000000267574 0.96000000267574 0.96000000267574 0.96000000267574 0.96000000267574 0.96000000007354 0.96000000007354 0.96000000007354 0.96000000007354 0.96000000007354 0.96000000007354 0.96000000007354 0.96000000007354 0.96000000007354 0.96000000007354 0.96000000007354 0.96000000007354 0.96000000007354 0.96000000007354 0.96000000007354 0.96000000007354 0.96000000007354 0.96000000007354 0.96000000007354 0.96000000007354 0.96000000007354 0.96000000007354 0.96000000007354 0.96000000007354 0.96000000007354 0.96000000000181 0.96000000000181 0.96000000000181 0.96000000000181 0.96000000000181 0.96000000000181 0.96000000000181 0.96000000000181 0.96000000000181 0.96000000000181 0.96000000000181 0.96000000000181 0.96000000000181 0.96000000000181 0.96000000000181 0.96000000000181 0.96000000000181 0.96000000000181 0.96000000000181 0.96000000000181 0.96000000000181 0.96000000000181 0.96000000000181 0.96000000000181 0.96000000000181 0.95999999999985 0.95999999999985 0.95999999999985 0.95999999999985 0.95999999999985 0.95999999999985 0.95999999999985 0.95999999999985 0.95999999999985 0.95999999999985 0.95999999999985 0.95999999999985 0.95999999999985 0.95999999999985 0.95999999999985 0.95999999999985 0.95999999999985 0.95999999999985 0.95999999999985 0.95999999999985 0.95999999999985 0.95999999999985 0.95999999999985 0.95999999999985 0.95999999999985 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.95999999999995 0.96000000000058 0.96000000000058 0.96000000000058 0.96000000000058 0.96000000000058 0.96000000000058 0.96000000000058 0.96000000000058 0.96000000000058 0.96000000000058 0.96000000000058 0.96000000000058 0.96000000000058 0.96000000000058 0.96000000000058 0.96000000000058 0.96000000000058 0.96000000000058 0.96000000000058 0.96000000000058 0.96000000000058 0.96000000000058 0.96000000000058 0.96000000000058 0.96000000000058 0.96000000001744 0.96000000001744 0.96000000001744 0.96000000001744 0.96000000001744 0.96000000001744 0.96000000001744 0.96000000001744 0.96000000001744 0.96000000001744 0.96000000001744 0.96000000001744 0.96000000001744 0.96000000001744 0.96000000001744 0.96000000001744 0.96000000001744 0.96000000001744 0.96000000001744 0.96000000001744 0.96000000001744 0.96000000001744 0.96000000001744 0.96000000001744 0.96000000001744 0.96000000114058 0.96000000114058 0.96000000114058 0.96000000114058 0.96000000114058 0.96000000114058 0.96000000114058 0.96000000114058 0.96000000114058 0.96000000114058 0.96000000114058 0.96000000114058 0.96000000114058 0.96000000114058 0.96000000114058 0.96000000114058 0.96000000114058 0.96000000114058 0.96000000114058 0.96000000114058 0.96000000114058 0.96000000114058 0.96000000114058 0.96000000114058 0.96000000114058 0.9600000318752 0.9600000318752 0.9600000318752 0.9600000318752 0.9600000318752 0.9600000318752 0.9600000318752 0.9600000318752 0.9600000318752 0.9600000318752 0.9600000318752 0.9600000318752 0.9600000318752 0.9600000318752 0.9600000318752 0.9600000318752 0.9600000318752 0.9600000318752 0.9600000318752 0.9600000318752 0.9600000318752 0.9600000318752 0.9600000318752 0.9600000318752 0.9600000318752 0.96000001538587 0.96000001538587 0.96000001538587 0.96000001538587 0.96000001538587 0.96000001538587 0.96000001538587 0.96000001538587 0.96000001538587 0.96000001538587 0.96000001538587 0.96000001538587 0.96000001538587 0.96000001538587 0.96000001538587 0.96000001538587 0.96000001538587 0.96000001538587 0.96000001538587 0.96000001538587 0.96000001538587 0.96000001538587 0.96000001538587 0.96000001538587 0.96000001538587 0.96000008339363 0.96000008339363 0.96000008339363 0.96000008339363 0.96000008339363 0.96000008339363 0.96000008339363 0.96000008339363 0.96000008339363 0.96000008339363 0.96000008339363 0.96000008339363 0.96000008339363 0.96000008339363 0.96000008339363 0.96000008339363 0.96000008339363 0.96000008339363 0.96000008339363 0.96000008339363 0.96000008339363 0.96000008339363 0.96000008339363 0.96000008339363 0.96000008339363 0.96000001383394 0.96000001383394 0.96000001383394 0.96000001383394 0.96000001383394 0.96000001383394 0.96000001383394 0.96000001383394 0.96000001383394 0.96000001383394 0.96000001383394 0.96000001383394 0.96000001383394 0.96000001383394 0.96000001383394 0.96000001383394 0.96000001383394 0.96000001383394 0.96000001383394 0.96000001383394 0.96000001383394 0.96000001383394 0.96000001383394 0.96000001383394 0.96000001383394 0.96000001361022 0.96000001361022 0.96000001361022 0.96000001361022 0.96000001361022 0.96000001361022 0.96000001361022 0.96000001361022 0.96000001361022 0.96000001361022 0.96000001361022 0.96000001361022 0.96000001361022 0.96000001361022 0.96000001361022 0.96000001361022 0.96000001361022 0.96000001361022 0.96000001361022 0.96000001361022 0.96000001361022 0.96000001361022 0.96000001361022 0.96000001361022 0.96000001361022 0.96000000508758 0.96000000508758 0.96000000508758 0.96000000508758 0.96000000508758 0.96000000508758 0.96000000508758 0.96000000508758 0.96000000508758 0.96000000508758 0.96000000508758 0.96000000508758 0.96000000508758 0.96000000508758 0.96000000508758 0.96000000508758 0.96000000508758 0.96000000508758 0.96000000508758 0.96000000508758 0.96000000508758 0.96000000508758 0.96000000508758 0.96000000508758 0.96000000508758 0.96000000027613 0.96000000027613 0.96000000027613 0.96000000027613 0.96000000027613 0.96000000027613 0.96000000027613 0.96000000027613 0.96000000027613 0.96000000027613 0.96000000027613 0.96000000027613 0.96000000027613 0.96000000027613 0.96000000027613 0.96000000027613 0.96000000027613 0.96000000027613 0.96000000027613 0.96000000027613 0.96000000027613 0.96000000027613 0.96000000027613 0.96000000027613 0.96000000027613 0.96000000000723 0.96000000000723 0.96000000000723 0.96000000000723 0.96000000000723 0.96000000000723 0.96000000000723 0.96000000000723 0.96000000000723 0.96000000000723 0.96000000000723 0.96000000000723 0.96000000000723 0.96000000000723 0.96000000000723 0.96000000000723 0.96000000000723 0.96000000000723 0.96000000000723 0.96000000000723 0.96000000000723 0.96000000000723 0.96000000000723 0.96000000000723 0.96000000000723 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.95999999999991 0.96000000000014 0.96000000000014 0.96000000000014 0.96000000000014 0.96000000000014 0.96000000000014 0.96000000000014 0.96000000000014 0.96000000000014 0.96000000000014 0.96000000000014 0.96000000000014 0.96000000000014 0.96000000000014 0.96000000000014 0.96000000000014 0.96000000000014 0.96000000000014 0.96000000000014 0.96000000000014 0.96000000000014 0.96000000000014 0.96000000000014 0.96000000000014 0.96000000000014 0.96000000001185 0.96000000001185 0.96000000001185 0.96000000001185 0.96000000001185 0.96000000001185 0.96000000001185 0.96000000001185 0.96000000001185 0.96000000001185 0.96000000001185 0.96000000001185 0.96000000001185 0.96000000001185 0.96000000001185 0.96000000001185 0.96000000001185 0.96000000001185 0.96000000001185 0.96000000001185 0.96000000001185 0.96000000001185 0.96000000001185 0.96000000001185 0.96000000001185 0.96000000033252 0.96000000033252 0.96000000033252 0.96000000033252 0.96000000033252 0.96000000033252 0.96000000033252 0.96000000033252 0.96000000033252 0.96000000033252 0.96000000033252 0.96000000033252 0.96000000033252 0.96000000033252 0.96000000033252 0.96000000033252 0.96000000033252 0.96000000033252 0.96000000033252 0.96000000033252 0.96000000033252 0.96000000033252 0.96000000033252 0.96000000033252 0.96000000033252 0.9600000001676 0.9600000001676 0.9600000001676 0.9600000001676 0.9600000001676 0.9600000001676 0.9600000001676 0.9600000001676 0.9600000001676 0.9600000001676 0.9600000001676 0.9600000001676 0.9600000001676 0.9600000001676 0.9600000001676 0.9600000001676 0.9600000001676 0.9600000001676 0.9600000001676 0.9600000001676 0.9600000001676 0.9600000001676 0.9600000001676 0.9600000001676 0.9600000001676 0.96000000105006 0.96000000105006 0.96000000105006 0.96000000105006 0.96000000105006 0.96000000105006 0.96000000105006 0.96000000105006 0.96000000105006 0.96000000105006 0.96000000105006 0.96000000105006 0.96000000105006 0.96000000105006 0.96000000105006 0.96000000105006 0.96000000105006 0.96000000105006 0.96000000105006 0.96000000105006 0.96000000105006 0.96000000105006 0.96000000105006 0.96000000105006 0.96000000105006 0.96000000017454 0.96000000017454 0.96000000017454 0.96000000017454 0.96000000017454 0.96000000017454 0.96000000017454 0.96000000017454 0.96000000017454 0.96000000017454 0.96000000017454 0.96000000017454 0.96000000017454 0.96000000017454 0.96000000017454 0.96000000017454 0.96000000017454 0.96000000017454 0.96000000017454 0.96000000017454 0.96000000017454 0.96000000017454 0.96000000017454 0.96000000017454 0.96000000017454 0.96000000021066 0.96000000021066 0.96000000021066 0.96000000021066 0.96000000021066 0.96000000021066 0.96000000021066 0.96000000021066 0.96000000021066 0.96000000021066 0.96000000021066 0.96000000021066 0.96000000021066 0.96000000021066 0.96000000021066 0.96000000021066 0.96000000021066 0.96000000021066 0.96000000021066 0.96000000021066 0.96000000021066 0.96000000021066 0.96000000021066 0.96000000021066 0.96000000021066 0.96000000008263 0.96000000008263 0.96000000008263 0.96000000008263 0.96000000008263 0.96000000008263 0.96000000008263 0.96000000008263 0.96000000008263 0.96000000008263 0.96000000008263 0.96000000008263 0.96000000008263 0.96000000008263 0.96000000008263 0.96000000008263 0.96000000008263 0.96000000008263 0.96000000008263 0.96000000008263 0.96000000008263 0.96000000008263 0.96000000008263 0.96000000008263 0.96000000008263 0.96000000000466 0.96000000000466 0.96000000000466 0.96000000000466 0.96000000000466 0.96000000000466 0.96000000000466 0.96000000000466 0.96000000000466 0.96000000000466 0.96000000000466 0.96000000000466 0.96000000000466 0.96000000000466 0.96000000000466 0.96000000000466 0.96000000000466 0.96000000000466 0.96000000000466 0.96000000000466 0.96000000000466 0.96000000000466 0.96000000000466 0.96000000000466 0.96000000000466 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96000000000013 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000006 0.96000000000325 0.96000000000325 0.96000000000325 0.96000000000325 0.96000000000325 0.96000000000325 0.96000000000325 0.96000000000325 0.96000000000325 0.96000000000325 0.96000000000325 0.96000000000325 0.96000000000325 0.96000000000325 0.96000000000325 0.96000000000325 0.96000000000325 0.96000000000325 0.96000000000325 0.96000000000325 0.96000000000325 0.96000000000325 0.96000000000325 0.96000000000325 0.96000000000325 0.96000000000187 0.96000000000187 0.96000000000187 0.96000000000187 0.96000000000187 0.96000000000187 0.96000000000187 0.96000000000187 0.96000000000187 0.96000000000187 0.96000000000187 0.96000000000187 0.96000000000187 0.96000000000187 0.96000000000187 0.96000000000187 0.96000000000187 0.96000000000187 0.96000000000187 0.96000000000187 0.96000000000187 0.96000000000187 0.96000000000187 0.96000000000187 0.96000000000187 0.96000000001122 0.96000000001122 0.96000000001122 0.96000000001122 0.96000000001122 0.96000000001122 0.96000000001122 0.96000000001122 0.96000000001122 0.96000000001122 0.96000000001122 0.96000000001122 0.96000000001122 0.96000000001122 0.96000000001122 0.96000000001122 0.96000000001122 0.96000000001122 0.96000000001122 0.96000000001122 0.96000000001122 0.96000000001122 0.96000000001122 0.96000000001122 0.96000000001122 0.96000000000219 0.96000000000219 0.96000000000219 0.96000000000219 0.96000000000219 0.96000000000219 0.96000000000219 0.96000000000219 0.96000000000219 0.96000000000219 0.96000000000219 0.96000000000219 0.96000000000219 0.96000000000219 0.96000000000219 0.96000000000219 0.96000000000219 0.96000000000219 0.96000000000219 0.96000000000219 0.96000000000219 0.96000000000219 0.96000000000219 0.96000000000219 0.96000000000219 0.96000000000302 0.96000000000302 0.96000000000302 0.96000000000302 0.96000000000302 0.96000000000302 0.96000000000302 0.96000000000302 0.96000000000302 0.96000000000302 0.96000000000302 0.96000000000302 0.96000000000302 0.96000000000302 0.96000000000302 0.96000000000302 0.96000000000302 0.96000000000302 0.96000000000302 0.96000000000302 0.96000000000302 0.96000000000302 0.96000000000302 0.96000000000302 0.96000000000302 0.9600000000017 0.9600000000017 0.9600000000017 0.9600000000017 0.9600000000017 0.9600000000017 0.9600000000017 0.9600000000017 0.9600000000017 0.9600000000017 0.9600000000017 0.9600000000017 0.9600000000017 0.9600000000017 0.9600000000017 0.9600000000017 0.9600000000017 0.9600000000017 0.9600000000017 0.9600000000017 0.9600000000017 0.9600000000017 0.9600000000017 0.9600000000017 0.9600000000017 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999999 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.95999999999993 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.9599999999999 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.96000000000007 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999989 0.95999999999984 0.95999999999984 0.95999999999984 0.95999999999984 0.95999999999984 0.95999999999984 0.95999999999984 0.95999999999984 0.95999999999984 0.95999999999984 0.95999999999984 0.95999999999984 0.95999999999984 0.95999999999984 0.95999999999984 0.95999999999984 0.95999999999984 0.95999999999984 0.95999999999984 0.95999999999984 0.95999999999984 0.95999999999984 0.95999999999984 0.95999999999984 0.95999999999984 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.95999999999998 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96000000000002 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96000000000001 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 0.96 D/cons.2.00.000000.dat 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 @@ -17,4 +17,4 @@ D/cons.8.00.000000.dat 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0 D/cons.8.00.000050.dat 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 D/lag_bubble_evol_0.dat 0.0 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832988093882 0.008 0.0 1.0001782913460961 0.0 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832988093882 0.008 0.0 1.0001782913460961 1e-06 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832988093882 0.0079999999991335 -2.5998347812e-06 1.000178291800741 2e-06 1.0 0.5 0.5 0.5 3.64821e-11 0.014383298809388 0.0079999999922017 -1.29983242186e-05 1.000178295437995 3e-06 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832988093872 0.0079999999688074 -3.63927017024e-05 1.0001783077133188 4e-06 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832988093845 0.0079999999133575 -7.79781563216e-05 1.000178336808713 5e-06 1.0 0.5 0.5 0.5 3.64821e-11 0.014383298809378 0.0079999998050647 -0.0001429472991708 1.0001783936315034 6e-06 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832988093644 0.0079999996179507 -0.0002364895241275 1.0001784918128234 7e-06 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832988093391 0.0079999993208499 -0.0003637902333544 1.0001786477057284 8e-06 1.0 0.5 0.5 0.5 3.64821e-11 0.014383298809296 0.0079999988774134 -0.0005300298975884 1.000178880382868 9e-06 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832988092268 0.0079999982461151 -0.0007403829210309 1.0001792116336214 1e-05 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832988091214 0.0079999973802576 -0.0010000162803676 1.0001796659605886 1.1e-05 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832988089671 0.0079999962279814 -0.0013140879071025 1.0001802705753133 1.2e-05 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832988087485 0.0079999947322742 -0.001687744782021 1.0001810553930972 1.3e-05 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832988084475 0.0079999928309829 -0.002126120710193 1.0001820530267498 1.4e-05 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832988080425 0.0079999904568284 -0.0026343337445149 1.0001832987791015 1.5e-05 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832988075089 0.0079999875374229 -0.0032174832253708 1.0001848306340897 1.6e-05 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832988068183 0.0079999839952895 -0.0038806464035904 1.000186689246213 1.7e-05 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832988059382 0.0079999797478871 -0.0046288746135072 1.000188917928131 1.8e-05 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832988048322 0.0079999747076377 -0.0054671889625894 1.000191562636167 1.9e-05 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832988034595 0.0079999687819595 -0.0064005755038528 1.0001946719534596 2e-05 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832988017745 0.0079999618733042 -0.007433979857085 1.0001982970704828 2.1e-05 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832987997269 0.0079999538792009 -0.0085723012448426 1.000202491762648 2.2e-05 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832987972612 0.0079999446923049 -0.0098203859092421 1.0002073123646718 2.3e-05 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832987943166 0.0079999342004551 -0.011183019875789 1.0002128177413845 2.4e-05 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832987908266 0.0079999222867377 -0.0126649210309033 1.0002190692546316 2.5e-05 1.0 0.5 0.5 0.5 3.64821e-11 0.014383298786719 0.0079999088295585 -0.0142707304804285 1.000226130725907 2.6e-05 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832987819156 0.0079998937027246 -0.0160050031573143 1.0002340683943376 2.7e-05 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832987763319 0.0079998767755354 -0.0178721976476137 1.0002429508696198 2.8e-05 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832987698769 0.0079998579128844 -0.0198766652057478 1.000252849079501 2.9e-05 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832987624528 0.0079998369753724 -0.0220226379315838 1.0002638362113736 3e-05 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832987539552 0.007999813819433 -0.0243142160841659 1.0002759876475424 3.1e-05 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832987442723 0.0079997882974709 -0.0267553545095958 1.0002893808937117 3.2e-05 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832987332852 0.0079997602580149 -0.029349848163718 1.0003040955002234 3.3e-05 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832987208674 0.0079997295458849 -0.0321013167136486 1.0003202129755737 3.4e-05 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832987068849 0.0079996960023757 -0.0350131882068714 1.000337816691723 3.5e-05 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832986911959 0.0079996594654568 -0.0380886818013008 1.0003569917807094 3.6e-05 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832986736504 0.0079996197699907 -0.0413307895553177 1.0003778250220763 3.7e-05 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832986540904 0.0079995767479693 -0.0447422572817508 1.0004004047206192 3.8e-05 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832986323498 0.0079995302287701 -0.048325564474873 1.000424820573963 3.9e-05 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832986082539 0.0079994800394327 -0.0520829033325081 1.000451163529485 4e-05 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832985816196 0.0079994260049577 -0.0560161569072351 1.0004795256301158 4.1e-05 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832985522554 0.007999367948626 -0.0601268764180896 1.0005099998485611 4.2e-05 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832985199608 0.0079993056923434 -0.0644162577618181 1.0005426799095096 4.3e-05 1.0 0.5 0.5 0.5 3.64821e-11 0.014383298484527 0.0079992390570073 -0.0688851172641215 1.0005776600994014 4.4e-05 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832984457361 0.007999167862899 -0.0735338667716603 1.0006150350633782 4.5e-05 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832984033616 0.0079990919301005 -0.0783624881671981 1.000654899589073 4.6e-05 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832983571682 0.0079990110789379 -0.0833705073971212 1.000697348376945 4.7e-05 1.0 0.5 0.5 0.5 3.64821e-11 0.014383298306912 0.0079989251304502 -0.0885569681129268 1.0007424757969103 4.8e-05 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832982523402 0.0079988339068849 -0.0939204050483519 1.0007903756310734 4.9e-05 1.0 0.5 0.5 0.5 3.64821e-11 0.0143832981931914 0.0079987372322203 -0.0994588172778342 1.000841140802435 D/stats_lag_bubbles_0.dat 0.0 1.0 0.5 0.5 0.5 1.0 0.9998421540275337 -D/voidfraction.dat 2.1429198e-06 2.1429198e-06 2.1429198e-06 2.1429198e-06 2.1429197e-06 2.1429197e-06 2.1429196e-06 2.1429195e-06 2.1429193e-06 2.142919e-06 2.1429186e-06 2.142918e-06 2.1429172e-06 2.1429161e-06 2.1429148e-06 2.142913e-06 2.1429109e-06 2.1429083e-06 2.1429052e-06 2.1429015e-06 2.1428971e-06 2.1428919e-06 2.1428859e-06 2.142879e-06 2.1428711e-06 2.1428621e-06 2.1428519e-06 2.1428404e-06 2.1428275e-06 2.1428132e-06 2.1427972e-06 2.1427795e-06 2.1427599e-06 2.1427384e-06 2.1427148e-06 2.142689e-06 2.1426608e-06 2.1426302e-06 2.1425969e-06 2.142561e-06 2.1425221e-06 2.1424803e-06 2.1424352e-06 2.1423869e-06 2.1423351e-06 2.1422797e-06 2.1422206e-06 2.1421577e-06 2.1420907e-06 2.1420195e-06 2.141944e-06 \ No newline at end of file +D/voidfraction.dat 2.1429198e-06 2.1429198e-06 2.1429198e-06 2.1429198e-06 2.1429197e-06 2.1429197e-06 2.1429196e-06 2.1429195e-06 2.1429192e-06 2.1429189e-06 2.1429183e-06 2.1429177e-06 2.1429167e-06 2.1429155e-06 2.142914e-06 2.1429121e-06 2.1429097e-06 2.1429069e-06 2.1429035e-06 2.1428994e-06 2.1428947e-06 2.1428891e-06 2.1428827e-06 2.1428753e-06 2.1428669e-06 2.1428573e-06 2.1428465e-06 2.1428343e-06 2.1428207e-06 2.1428056e-06 2.1427888e-06 2.1427701e-06 2.1427496e-06 2.1427271e-06 2.1427024e-06 2.1426755e-06 2.1426461e-06 2.1426142e-06 2.1425797e-06 2.1425423e-06 2.1425019e-06 2.1424585e-06 2.1424119e-06 2.1423619e-06 2.1423083e-06 2.1422511e-06 2.1421901e-06 2.1421252e-06 2.1420561e-06 2.1419828e-06 2.1419052e-06 \ No newline at end of file From 158c1144072af90263cbc475d414348c64c474f0 Mon Sep 17 00:00:00 2001 From: Spencer Bryngelson Date: Fri, 27 Mar 2026 11:51:44 -0400 Subject: [PATCH 08/14] fix: add particle MPI deallocation, fallback params, checker validation, and comment typo --- src/simulation/m_checker.fpp | 2 ++ src/simulation/m_global_parameters.fpp | 10 +++++----- src/simulation/m_mpi_proxy.fpp | 7 +++++++ toolchain/mfc/params/namelist_parser.py | 6 ++++++ 4 files changed, 20 insertions(+), 5 deletions(-) diff --git a/src/simulation/m_checker.fpp b/src/simulation/m_checker.fpp index 478f778c84..1e6015e25e 100644 --- a/src/simulation/m_checker.fpp +++ b/src/simulation/m_checker.fpp @@ -37,6 +37,8 @@ contains call s_check_inputs_time_stepping @:PROHIBIT(ib_state_wrt .and. .not. ib, "ib_state_wrt requires ib to be enabled") + @:PROHIBIT(particles_lagrange .and. bubbles_lagrange, "particles_lagrange and bubbles_lagrange cannot both be enabled") + @:PROHIBIT(particles_lagrange .and. n == 0, "particles_lagrange requires at least 2D (n > 0)") end subroutine s_check_inputs diff --git a/src/simulation/m_global_parameters.fpp b/src/simulation/m_global_parameters.fpp index 18687ea89b..98b3b44d0d 100644 --- a/src/simulation/m_global_parameters.fpp +++ b/src/simulation/m_global_parameters.fpp @@ -520,11 +520,11 @@ module m_global_parameters !> @name lagrangian subgrid bubble parameters !> @{! - logical :: bubbles_lagrange !< Lagrangian subgrid bubble model switch - logical :: particles_lagrange !< Lagrangian subgrid particle model switch - type(bubbles_lagrange_parameters) :: lag_params !< Lagrange bubbles' parameters - integer :: n_el_bubs_loc, n_el_bubs_glb !< Number of Lagrangian bubbles (local and global) - integer :: n_el_particles_loc, n_el_particles_glb !< Number of Lagrangian bubbles (local and global) + logical :: bubbles_lagrange !< Lagrangian subgrid bubble model switch + logical :: particles_lagrange !< Lagrangian subgrid particle model switch + type(bubbles_lagrange_parameters) :: lag_params !< Lagrange bubbles' parameters + integer :: n_el_bubs_loc, n_el_bubs_glb !< Number of Lagrangian bubbles (local and global) + integer :: n_el_particles_loc, n_el_particles_glb !< Number of Lagrangian particles (local and global) logical :: moving_lag_bubbles logical :: moving_lag_particles logical :: lag_pressure_force diff --git a/src/simulation/m_mpi_proxy.fpp b/src/simulation/m_mpi_proxy.fpp index a4708cce4d..d2415bb45c 100644 --- a/src/simulation/m_mpi_proxy.fpp +++ b/src/simulation/m_mpi_proxy.fpp @@ -1426,6 +1426,13 @@ contains if (ib) then @:DEALLOCATE(ib_buff_send, ib_buff_recv) end if + + if (particles_lagrange) then + @:DEALLOCATE(p_send_buff, p_recv_buff, p_send_ids) + @:DEALLOCATE(force_send_counts, force_recv_counts) + @:DEALLOCATE(force_send_ids, force_send_vals) + @:DEALLOCATE(flat_send_ids, flat_send_vals) + end if #endif end subroutine s_finalize_mpi_proxy_module diff --git a/toolchain/mfc/params/namelist_parser.py b/toolchain/mfc/params/namelist_parser.py index 5ac3913499..34a975223e 100644 --- a/toolchain/mfc/params/namelist_parser.py +++ b/toolchain/mfc/params/namelist_parser.py @@ -33,6 +33,8 @@ "bub_pp", "bubbles_euler", "bubbles_lagrange", + "particles_lagrange", + "particle_pp", "case_dir", "cfl_adap_dt", "cfl_const_dt", @@ -151,6 +153,8 @@ "bubble_model", "bubbles_euler", "bubbles_lagrange", + "particles_lagrange", + "particle_pp", "case_dir", "cfl_adap_dt", "cfl_const_dt", @@ -293,6 +297,8 @@ "bub_pp", "bubbles_euler", "bubbles_lagrange", + "particles_lagrange", + "particle_pp", "c_wrt", "case_dir", "cf_wrt", From 882dc0a75789a87b366b7846f47d074198e581ea Mon Sep 17 00:00:00 2001 From: Spencer Bryngelson Date: Fri, 27 Mar 2026 13:37:14 -0400 Subject: [PATCH 09/14] fix: add missing write_void_evol to lagrange_shbubcollapse example --- examples/3D_lagrange_shbubcollapse/case.py | 1 + 1 file changed, 1 insertion(+) diff --git a/examples/3D_lagrange_shbubcollapse/case.py b/examples/3D_lagrange_shbubcollapse/case.py index 73e0b88f69..d78095b587 100644 --- a/examples/3D_lagrange_shbubcollapse/case.py +++ b/examples/3D_lagrange_shbubcollapse/case.py @@ -155,6 +155,7 @@ "lag_params%valmaxvoid": 0.9, "lag_params%write_bubbles": "F", "lag_params%write_bubbles_stats": "F", + "lag_params%write_void_evol": "T", # Bubble parameters "bub_pp%R0ref": 1.0, "bub_pp%p0ref": 1.0, From f061ae235e04eb60f8293a74b3906220ced7c24d Mon Sep 17 00:00:00 2001 From: jaguilar Date: Fri, 27 Mar 2026 18:09:08 -0400 Subject: [PATCH 10/14] Updates to E-L Solver (Models/documentation/bugs) 1. Fixes volume fraction and source term smearing. Previously, these two were combined in a convoluted way. Volume fraction field needs to be computed/communicated at the start of the timestep, source term contributions need to be computed/communicated after computing the fluid force on the particle. These are now split in a clean way. 2. The filling in the buffer cells has the update that uses sum and replace algorithm (implemented by Ben W.). This was further modified to take in an array as input with the indexes of the variables in q_particles/q_beta that should be updated by the algorithm. This was done so that the volume fraction update could be split from the source term contribution update. 3. The collision force parameters are now defined in the inputs in the particle physical properties. Includes: particle_pp%ksp_col, particle_pp%nu_col, particle_pp%E_col, particle_pp%cor_col. Need to be set if collisions is turned on. The collision forces are not communicated anymore. Instead, each local particle is looped through and checked for overlap with neighbors. Then, only the collision force on this local particle of interest is added to this local particle. This avoids communication of forces. 4. The sutherland viscosity for air is hardcoded into the force subroutine if "viscous" is turned off. This is a temporary bandaid. Use lag_params%mu_ref = 1.716E-5 5. Implements quasi-steady drag fluctuations force (logical input : lag_params%qs_fluct_force) The subroutine is within the kernels file. This uses the random number generator in src/common/m_model.fpp. src/common/m_model.fpp was modified to make the random number generator subroutine public. 6. The documentation for the qs_drag_model was corrected. New documentation is added for the collision force inputs, quasi-steady fluctuation force, and fluid (air) reference viscosity). --- docs/documentation/case.md | 12 +- src/common/m_boundary_common.fpp | 244 +++++---- src/common/m_derived_types.fpp | 6 + src/common/m_model.fpp | 2 +- src/common/m_mpi_common.fpp | 209 ++++---- src/post_process/m_global_parameters.fpp | 8 +- src/pre_process/m_global_parameters.fpp | 9 +- src/simulation/m_bubbles_EL.fpp | 192 ++++--- src/simulation/m_global_parameters.fpp | 10 +- src/simulation/m_mpi_proxy.fpp | 169 +----- src/simulation/m_particles_EL.fpp | 596 ++++++++++++---------- src/simulation/m_particles_EL_kernels.fpp | 411 +++++++++++---- src/simulation/m_rhs.fpp | 4 +- toolchain/mfc/params/definitions.py | 11 +- 14 files changed, 1107 insertions(+), 776 deletions(-) diff --git a/docs/documentation/case.md b/docs/documentation/case.md index 1ae3851b33..86af84e0b3 100644 --- a/docs/documentation/case.md +++ b/docs/documentation/case.md @@ -931,17 +931,23 @@ When ``polytropic = 'F'``, the gas compression is modeled as non-polytropic due | `solver_approach` | Integer | 1: One-way coupling, 2: Two-way coupling | | `smooth_type` | Integer | Smoothing function. 1: Gaussian, 2: Delta 3x3 | | `stokes_drag` | Integer | Stokes drag model flag | -| `qs_drag_model` | Integer | Quasi-steady drag model (0: off, 1: Parmar, 2: Modified Parmar, 3: Osnes, 4: Gidaspow) | +| `qs_drag_model` | Integer | Quasi-steady drag model (0: off, 1: Parmar, 2: Osnes, 3: Modified Parmar, 4: Gidaspow) | | `added_mass_model` | Integer | Added mass model (0: off, >0: active) | | `interpolation_order` | Integer | Polynomial order for barycentric field interpolation | | `collision_force` | Logical | Enable soft-sphere DEM particle-particle collisions | +| `qs_fluct_force` | Logical | Enable quasi-steady drag force fluctuation contribution | | `pressure_force` | Logical | Enable pressure gradient force on particles | | `gravity_force` | Logical | Enable gravitational force on particles | | `write_void_evol` | Logical | Write void fraction evolution data | | `epsilonb` | Real | Standard deviation scaling for the Gaussian kernel | | `valmaxvoid` | Real | Maximum void fraction permitted | +| `mu_ref` | Real | Fluid reference dynamic viscosity | | `particle_pp%%rho0ref_particle` | Real | Reference particle material density | | `particle_pp%%cp_particle` | Real | Particle specific heat capacity | +| `particle_pp%%ksp_col` | Real | Spring stiffness multiplier for collisions | +| `particle_pp%%nu_col` | Real | Poisson's ratio used for collisions | +| `particle_pp%%E_col` | Real | Young's modulus [Pa] used for collisions | +| `particle_pp%%cor_col` | Real | Coefficient of restitution of particles | - `particles_lagrange` activates the Euler-Lagrange solid particle solver. Particle initial conditions are read from `./input/lag_particles.dat`. The solver tracks non-deformable spherical particles in a compressible carrier flow using volume-averaged source terms (\cite Maeda18). @@ -949,12 +955,14 @@ When ``polytropic = 'F'``, the gas compression is modeled as non-polytropic due - `solver_approach` specifies the coupling method: [1] one-way coupling where particles are advected by the flow but do not influence it, [2] two-way coupling where particle forces are projected back onto the Eulerian grid as source terms. -- `qs_drag_model` selects the quasi-steady drag correlation: [1] Parmar et al. (2010) with Sangani volume fraction correction, [2] Modified Parmar with Osnes et al. (2023) volume fraction correction, [3] Osnes et al. (2023) full correlation with Loth et al. (2021) rarefied regime, [4] Gidaspow (1994) correlation for dense particle suspensions. +- `qs_drag_model` selects the quasi-steady drag correlation: [1] Parmar et al. (2010) with Sangani volume fraction correction, [2] Osnes et al. (2023) full correlation with Loth et al. (2021) rarefied regime, [3] Modified Parmar with Osnes et al. (2023) volume fraction correction, [4] Gidaspow (1994) correlation for dense particle suspensions. - `collision_force` activates soft-sphere DEM collisions using a spring-dashpot contact model with Hertzian stiffness. Collision forces between particles on different MPI ranks are communicated via non-blocking point-to-point messaging. - `interpolation_order` sets the order of the barycentric Lagrange polynomial used to interpolate Eulerian field quantities (pressure, velocity, density) to particle positions. Must be even; the interpolation stencil uses `N/2` points in each direction. +- `mu_ref` is the fluids reference dynamic viscosity at 273.15 K. Used for particle drag if "viscous" is turned off. Only the air sutherland model is currently implemented. If "viscous" is enabled, the true fluid's viscosity is used. + ### 10. Velocity Field Setup {#sec-velocity-field-setup} | Parameter | Type | Description | diff --git a/src/common/m_boundary_common.fpp b/src/common/m_boundary_common.fpp index b041bbc74d..c3687cafde 100644 --- a/src/common/m_boundary_common.fpp +++ b/src/common/m_boundary_common.fpp @@ -1063,152 +1063,169 @@ contains end subroutine s_qbmm_extrapolation - impure subroutine s_populate_beta_buffers(q_beta, bc_type, nvar) + impure subroutine s_populate_beta_buffers(q_beta, kahan_comp, bc_type, nvar, vars_comm) type(scalar_field), dimension(:), intent(inout) :: q_beta + type(scalar_field), dimension(:), intent(inout) :: kahan_comp type(integer_field), dimension(1:num_dims,1:2), intent(in) :: bc_type integer, intent(in) :: nvar + integer, dimension(:), intent(in) :: vars_comm integer :: k, l !> x-direction - if (bc_x%beg >= 0) then - call s_mpi_reduce_beta_variables_buffers(q_beta, 1, -1, nvar) - else + if (bc_x%beg < 0) then $:GPU_PARALLEL_LOOP(private='[l, k]', collapse=2) do l = beta_bc_bounds(3)%beg, beta_bc_bounds(3)%end do k = beta_bc_bounds(2)%beg, beta_bc_bounds(2)%end select case (bc_x%beg) case (BC_PERIODIC) - call s_beta_periodic(q_beta, 1, -1, k, l, nvar) + call s_beta_periodic(q_beta, kahan_comp, 1, -1, k, l, nvar, vars_comm) case (BC_REFLECTIVE) - call s_beta_reflective(q_beta, 1, -1, k, l, nvar) + call s_beta_reflective(q_beta, kahan_comp, 1, -1, k, l, nvar, vars_comm) case default end select end do end do $:END_GPU_PARALLEL_LOOP() end if + if (bc_x%beg >= 0 .or. bc_x%end >= 0) then + call s_mpi_reduce_beta_variables_buffers(q_beta, kahan_comp, 1, -1, nvar, vars_comm) + end if - if (bc_x%end >= 0) then - call s_mpi_reduce_beta_variables_buffers(q_beta, 1, 1, nvar) - else + if (bc_x%end < 0) then $:GPU_PARALLEL_LOOP(private='[l, k]', collapse=2) do l = beta_bc_bounds(3)%beg, beta_bc_bounds(3)%end do k = beta_bc_bounds(2)%beg, beta_bc_bounds(2)%end select case (bc_x%end) case (BC_PERIODIC) - call s_beta_periodic(q_beta, 1, 1, k, l, nvar) + call s_beta_periodic(q_beta, kahan_comp, 1, 1, k, l, nvar, vars_comm) case (BC_REFLECTIVE) - call s_beta_reflective(q_beta, 1, 1, k, l, nvar) + call s_beta_reflective(q_beta, kahan_comp, 1, 1, k, l, nvar, vars_comm) case default end select end do end do $:END_GPU_PARALLEL_LOOP() end if + if (bc_x%beg >= 0 .or. bc_x%end >= 0) then + call s_mpi_reduce_beta_variables_buffers(q_beta, kahan_comp, 1, 1, nvar, vars_comm) + end if !> y-direction - if (bc_y%beg >= 0) then - call s_mpi_reduce_beta_variables_buffers(q_beta, 2, -1, nvar) - else + if (bc_y%beg < 0) then $:GPU_PARALLEL_LOOP(private='[l, k]', collapse=2) do l = beta_bc_bounds(3)%beg, beta_bc_bounds(3)%end do k = beta_bc_bounds(1)%beg, beta_bc_bounds(1)%end select case (bc_y%beg) case (BC_PERIODIC) - call s_beta_periodic(q_beta, 2, -1, k, l, nvar) + call s_beta_periodic(q_beta, kahan_comp, 2, -1, k, l, nvar, vars_comm) case (BC_REFLECTIVE) - call s_beta_reflective(q_beta, 2, -1, k, l, nvar) + call s_beta_reflective(q_beta, kahan_comp, 2, -1, k, l, nvar, vars_comm) case default end select end do end do $:END_GPU_PARALLEL_LOOP() end if + if (bc_y%beg >= 0 .or. bc_y%end >= 0) then + call s_mpi_reduce_beta_variables_buffers(q_beta, kahan_comp, 2, -1, nvar, vars_comm) + end if - if (bc_y%end >= 0) then - call s_mpi_reduce_beta_variables_buffers(q_beta, 2, 1, nvar) - else + if (bc_y%end < 0) then $:GPU_PARALLEL_LOOP(private='[l, k]', collapse=2) do l = beta_bc_bounds(3)%beg, beta_bc_bounds(3)%end do k = beta_bc_bounds(1)%beg, beta_bc_bounds(1)%end select case (bc_y%end) case (BC_PERIODIC) - call s_beta_periodic(q_beta, 2, 1, k, l, nvar) + call s_beta_periodic(q_beta, kahan_comp, 2, 1, k, l, nvar, vars_comm) case (BC_REFLECTIVE) - call s_beta_reflective(q_beta, 2, 1, k, l, nvar) + call s_beta_reflective(q_beta, kahan_comp, 2, 1, k, l, nvar, vars_comm) case default end select end do end do $:END_GPU_PARALLEL_LOOP() end if + if (bc_y%beg >= 0 .or. bc_y%end >= 0) then + call s_mpi_reduce_beta_variables_buffers(q_beta, kahan_comp, 2, 1, nvar, vars_comm) + end if if (num_dims == 2) return #:if not MFC_CASE_OPTIMIZATION or num_dims > 2 !> z-direction - if (bc_z%beg >= 0) then - call s_mpi_reduce_beta_variables_buffers(q_beta, 3, -1, nvar) - else + if (bc_z%beg < 0) then $:GPU_PARALLEL_LOOP(private='[l, k]', collapse=2) do l = beta_bc_bounds(2)%beg, beta_bc_bounds(2)%end do k = beta_bc_bounds(1)%beg, beta_bc_bounds(1)%end select case (bc_type(3, 1)%sf(k, l, 0)) case (BC_PERIODIC) - call s_beta_periodic(q_beta, 3, -1, k, l, nvar) + call s_beta_periodic(q_beta, kahan_comp, 3, -1, k, l, nvar, vars_comm) case (BC_REFLECTIVE) - call s_beta_reflective(q_beta, 3, -1, k, l, nvar) + call s_beta_reflective(q_beta, kahan_comp, 3, -1, k, l, nvar, vars_comm) case default end select end do end do $:END_GPU_PARALLEL_LOOP() end if + if (bc_z%beg >= 0 .or. bc_z%end >= 0) then + call s_mpi_reduce_beta_variables_buffers(q_beta, kahan_comp, 3, -1, nvar, vars_comm) + end if - if (bc_z%end >= 0) then - call s_mpi_reduce_beta_variables_buffers(q_beta, 3, 1, nvar) - else !< bc_x%end + if (bc_z%end < 0) then $:GPU_PARALLEL_LOOP(private='[l, k]', collapse=2) do l = beta_bc_bounds(2)%beg, beta_bc_bounds(2)%end do k = beta_bc_bounds(1)%beg, beta_bc_bounds(1)%end select case (bc_type(3, 2)%sf(k, l, 0)) case (BC_PERIODIC) - call s_beta_periodic(q_beta, 3, 1, k, l, nvar) + call s_beta_periodic(q_beta, kahan_comp, 3, 1, k, l, nvar, vars_comm) case (BC_REFLECTIVE) - call s_beta_reflective(q_beta, 3, 1, k, l, nvar) + call s_beta_reflective(q_beta, kahan_comp, 3, 1, k, l, nvar, vars_comm) case default end select end do end do $:END_GPU_PARALLEL_LOOP() end if + if (bc_z%beg >= 0 .or. bc_z%end >= 0) then + call s_mpi_reduce_beta_variables_buffers(q_beta, kahan_comp, 3, 1, nvar, vars_comm) + end if #:endif end subroutine s_populate_beta_buffers - subroutine s_beta_periodic(q_beta, bc_dir, bc_loc, k, l, nvar) + subroutine s_beta_periodic(q_beta, kahan_comp, bc_dir, bc_loc, k, l, nvar, vars_comm) $:GPU_ROUTINE(function_name='s_beta_periodic', parallelism='[seq]', cray_inline=True) - type(scalar_field), dimension(num_dims + 1), intent(inout) :: q_beta - integer, intent(in) :: bc_dir, bc_loc - integer, intent(in) :: k, l - integer, intent(in) :: nvar - integer :: j, i + type(scalar_field), dimension(1:), intent(inout) :: q_beta + type(scalar_field), dimension(1:), intent(inout) :: kahan_comp + integer, intent(in) :: bc_dir, bc_loc + integer, intent(in) :: k, l + integer, intent(in) :: nvar + integer, dimension(:), intent(in) :: vars_comm + integer :: j, i + real(wp) :: y_kahan, t_kahan if (bc_dir == 1) then !< x-direction if (bc_loc == -1) then ! bc_x%beg do i = 1, nvar do j = -mapCells - 1, mapCells - q_beta(beta_vars(i))%sf(j, k, l) = q_beta(beta_vars(i))%sf(j, k, l) + q_beta(beta_vars(i))%sf(m + j + 1, & - & k, l) + ! Kahan-compensated addition of ghost to interior + y_kahan = real(q_beta(vars_comm(i))%sf(m + j + 1, k, l), & + & kind=wp) + kahan_comp(vars_comm(i))%sf(m + j + 1, k, l) - kahan_comp(vars_comm(i))%sf(j, & + & k, l) + t_kahan = real(q_beta(vars_comm(i))%sf(j, k, l), kind=wp) + y_kahan + kahan_comp(vars_comm(i))%sf(j, k, l) = (t_kahan - q_beta(vars_comm(i))%sf(j, k, l)) - y_kahan + q_beta(vars_comm(i))%sf(j, k, l) = t_kahan end do end do - else !< bc_y%end + else !< bc_x%end do i = 1, nvar do j = -mapcells, mapcells + 1 - q_beta(beta_vars(i))%sf(m + j, k, l) = q_beta(beta_vars(i))%sf(j - 1, k, l) + q_beta(vars_comm(i))%sf(m + j, k, l) = q_beta(vars_comm(i))%sf(j - 1, k, l) + kahan_comp(vars_comm(i))%sf(m + j, k, l) = kahan_comp(vars_comm(i))%sf(j - 1, k, l) end do end do end if @@ -1216,14 +1233,18 @@ contains if (bc_loc == -1) then !< bc_y%beg do i = 1, nvar do j = -mapcells - 1, mapcells - q_beta(beta_vars(i))%sf(k, j, l) = q_beta(beta_vars(i))%sf(k, j, l) + q_beta(beta_vars(i))%sf(k, & - & n + j + 1, l) + y_kahan = real(q_beta(vars_comm(i))%sf(k, n + j + 1, l), kind=wp) + kahan_comp(vars_comm(i))%sf(k, & + & n + j + 1, l) - kahan_comp(vars_comm(i))%sf(k, j, l) + t_kahan = real(q_beta(vars_comm(i))%sf(k, j, l), kind=wp) + y_kahan + kahan_comp(vars_comm(i))%sf(k, j, l) = (t_kahan - q_beta(vars_comm(i))%sf(k, j, l)) - y_kahan + q_beta(vars_comm(i))%sf(k, j, l) = t_kahan end do end do - else !< bc_z%end + else !< bc_y%end do i = 1, nvar do j = -mapcells, mapcells + 1 - q_beta(beta_vars(i))%sf(k, n + j, l) = q_beta(beta_vars(i))%sf(k, j - 1, l) + q_beta(vars_comm(i))%sf(k, n + j, l) = q_beta(vars_comm(i))%sf(k, j - 1, l) + kahan_comp(vars_comm(i))%sf(k, n + j, l) = kahan_comp(vars_comm(i))%sf(k, j - 1, l) end do end do end if @@ -1231,14 +1252,18 @@ contains if (bc_loc == -1) then !< bc_z%beg do i = 1, nvar do j = -mapcells - 1, mapcells - q_beta(beta_vars(i))%sf(k, l, j) = q_beta(beta_vars(i))%sf(k, l, j) + q_beta(beta_vars(i))%sf(k, l, & - & p + j + 1) + y_kahan = real(q_beta(vars_comm(i))%sf(k, l, p + j + 1), kind=wp) + kahan_comp(vars_comm(i))%sf(k, l, & + & p + j + 1) - kahan_comp(vars_comm(i))%sf(k, l, j) + t_kahan = real(q_beta(vars_comm(i))%sf(k, l, j), kind=wp) + y_kahan + kahan_comp(vars_comm(i))%sf(k, l, j) = (t_kahan - q_beta(vars_comm(i))%sf(k, l, j)) - y_kahan + q_beta(vars_comm(i))%sf(k, l, j) = t_kahan end do end do - else + else !< bc_z%end do i = 1, nvar do j = -mapcells, mapcells + 1 - q_beta(beta_vars(i))%sf(k, l, p + j) = q_beta(beta_vars(i))%sf(k, l, j - 1) + q_beta(vars_comm(i))%sf(k, l, p + j) = q_beta(vars_comm(i))%sf(k, l, j - 1) + kahan_comp(vars_comm(i))%sf(k, l, p + j) = kahan_comp(vars_comm(i))%sf(k, l, j - 1) end do end do end if @@ -1246,14 +1271,15 @@ contains end subroutine s_beta_periodic - subroutine s_beta_extrapolation(q_beta, bc_dir, bc_loc, k, l, nvar) + subroutine s_beta_extrapolation(q_beta, bc_dir, bc_loc, k, l, nvar, vars_comm) $:GPU_ROUTINE(function_name='s_beta_extrapolation', parallelism='[seq]', cray_inline=True) - type(scalar_field), dimension(num_dims + 1), intent(inout) :: q_beta - integer, intent(in) :: bc_dir, bc_loc - integer, intent(in) :: k, l - integer, intent(in) :: nvar - integer :: j, i + type(scalar_field), dimension(1:), intent(inout) :: q_beta + integer, intent(in) :: bc_dir, bc_loc + integer, intent(in) :: k, l + integer, intent(in) :: nvar + integer, dimension(:), intent(in) :: vars_comm + integer :: j, i ! Set beta in buffer regions equal to zero @@ -1261,13 +1287,13 @@ contains if (bc_loc == -1) then ! bc_x%beg do i = 1, nvar do j = 1, buff_size - q_beta(beta_vars(i))%sf(-j, k, l) = 0._wp + q_beta(vars_comm(i))%sf(-j, k, l) = 0._wp end do end do else !< bc_x%end do i = 1, nvar do j = 1, buff_size - q_beta(beta_vars(i))%sf(m + j, k, l) = 0._wp + q_beta(vars_comm(i))%sf(m + j, k, l) = 0._wp end do end do end if @@ -1275,13 +1301,13 @@ contains if (bc_loc == -1) then !< bc_y%beg do i = 1, nvar do j = 1, buff_size - q_beta(beta_vars(i))%sf(k, -j, l) = 0._wp + q_beta(vars_comm(i))%sf(k, -j, l) = 0._wp end do end do - else + else !< bc_y%end do i = 1, nvar do j = 1, buff_size - q_beta(beta_vars(i))%sf(k, n + j, l) = 0._wp + q_beta(vars_comm(i))%sf(k, n + j, l) = 0._wp end do end do end if @@ -1289,13 +1315,13 @@ contains if (bc_loc == -1) then !< bc_z%beg do i = 1, nvar do j = 1, buff_size - q_beta(beta_vars(i))%sf(k, l, -j) = 0._wp + q_beta(vars_comm(i))%sf(k, l, -j) = 0._wp end do end do - else + else !< bc_z%end do i = 1, nvar do j = 1, buff_size - q_beta(beta_vars(i))%sf(k, l, p + j) = 0._wp + q_beta(vars_comm(i))%sf(k, l, p + j) = 0._wp end do end do end if @@ -1303,37 +1329,49 @@ contains end subroutine s_beta_extrapolation - subroutine s_beta_reflective(q_beta, bc_dir, bc_loc, k, l, nvar) + subroutine s_beta_reflective(q_beta, kahan_comp, bc_dir, bc_loc, k, l, nvar, vars_comm) $:GPU_ROUTINE(function_name='s_beta_reflective', parallelism='[seq]', cray_inline=True) - type(scalar_field), dimension(num_dims + 1), intent(inout) :: q_beta - integer, intent(in) :: bc_dir, bc_loc - integer, intent(in) :: k, l - integer, intent(in) :: nvar - integer :: j, i - - ! Reflective BC for void fraction: 1) Fold ghost-cell contributions back onto their mirror interior cells 2) Set ghost cells - ! = mirror of (now-folded) interior values + type(scalar_field), dimension(1:), intent(inout) :: q_beta + type(scalar_field), dimension(1:), intent(inout) :: kahan_comp + integer, intent(in) :: bc_dir, bc_loc + integer, intent(in) :: k, l + integer, intent(in) :: nvar + integer, dimension(:), intent(in) :: vars_comm + integer :: j, i + real(wp) :: y_kahan, t_kahan + + ! Reflective BC for void fraction: 1) Fold ghost-cell contributions back onto their mirror interior cells (Kahan) 2) Set + ! ghost cells = mirror of (now-folded) interior values if (bc_dir == 1) then !< x-direction - if (bc_loc == -1) then ! bc_x%beg + if (bc_loc == -1) then !< bc_x%beg do i = 1, nvar do j = 1, mapCells + 1 - q_beta(beta_vars(i))%sf(j - 1, k, l) = q_beta(beta_vars(i))%sf(j - 1, k, l) + q_beta(beta_vars(i))%sf(-j, & - & k, l) + y_kahan = real(q_beta(vars_comm(i))%sf(-j, k, l), kind=wp) + kahan_comp(vars_comm(i))%sf(-j, k, & + & l) - kahan_comp(vars_comm(i))%sf(j - 1, k, l) + t_kahan = real(q_beta(vars_comm(i))%sf(j - 1, k, l), kind=wp) + y_kahan + kahan_comp(vars_comm(i))%sf(j - 1, k, l) = (t_kahan - q_beta(vars_comm(i))%sf(j - 1, k, l)) - y_kahan + q_beta(vars_comm(i))%sf(j - 1, k, l) = t_kahan end do do j = 1, mapCells + 1 - q_beta(beta_vars(i))%sf(-j, k, l) = q_beta(beta_vars(i))%sf(j - 1, k, l) + q_beta(vars_comm(i))%sf(-j, k, l) = q_beta(vars_comm(i))%sf(j - 1, k, l) + kahan_comp(vars_comm(i))%sf(-j, k, l) = kahan_comp(vars_comm(i))%sf(j - 1, k, l) end do end do - else !< bc_y%end + else !< bc_x%end do i = 1, nvar do j = 1, mapCells + 1 - q_beta(beta_vars(i))%sf(m - (j - 1), k, l) = q_beta(beta_vars(i))%sf(m - (j - 1), k, & - & l) + q_beta(beta_vars(i))%sf(m + j, k, l) + y_kahan = real(q_beta(vars_comm(i))%sf(m + j, k, l), kind=wp) + kahan_comp(vars_comm(i))%sf(m + j, k, & + & l) - kahan_comp(vars_comm(i))%sf(m - (j - 1), k, l) + t_kahan = real(q_beta(vars_comm(i))%sf(m - (j - 1), k, l), kind=wp) + y_kahan + kahan_comp(vars_comm(i))%sf(m - (j - 1), k, l) = (t_kahan - q_beta(vars_comm(i))%sf(m - (j - 1), k, & + & l)) - y_kahan + q_beta(vars_comm(i))%sf(m - (j - 1), k, l) = t_kahan end do do j = 1, mapCells + 1 - q_beta(beta_vars(i))%sf(m + j, k, l) = q_beta(beta_vars(i))%sf(m - (j - 1), k, l) + q_beta(vars_comm(i))%sf(m + j, k, l) = q_beta(vars_comm(i))%sf(m - (j - 1), k, l) + kahan_comp(vars_comm(i))%sf(m + j, k, l) = kahan_comp(vars_comm(i))%sf(m - (j - 1), k, l) end do end do end if @@ -1341,21 +1379,30 @@ contains if (bc_loc == -1) then !< bc_y%beg do i = 1, nvar do j = 1, mapCells + 1 - q_beta(beta_vars(i))%sf(k, j - 1, l) = q_beta(beta_vars(i))%sf(k, j - 1, l) + q_beta(beta_vars(i))%sf(k, & - & -j, l) + y_kahan = real(q_beta(vars_comm(i))%sf(k, -j, l), kind=wp) + kahan_comp(vars_comm(i))%sf(k, -j, & + & l) - kahan_comp(vars_comm(i))%sf(k, j - 1, l) + t_kahan = real(q_beta(vars_comm(i))%sf(k, j - 1, l), kind=wp) + y_kahan + kahan_comp(vars_comm(i))%sf(k, j - 1, l) = (t_kahan - q_beta(vars_comm(i))%sf(k, j - 1, l)) - y_kahan + q_beta(vars_comm(i))%sf(k, j - 1, l) = t_kahan end do do j = 1, mapCells + 1 - q_beta(beta_vars(i))%sf(k, -j, l) = q_beta(beta_vars(i))%sf(k, j - 1, l) + q_beta(vars_comm(i))%sf(k, -j, l) = q_beta(vars_comm(i))%sf(k, j - 1, l) + kahan_comp(vars_comm(i))%sf(k, -j, l) = kahan_comp(vars_comm(i))%sf(k, j - 1, l) end do end do - else + else !< bc_y%end do i = 1, nvar do j = 1, mapCells + 1 - q_beta(beta_vars(i))%sf(k, n - (j - 1), l) = q_beta(beta_vars(i))%sf(k, n - (j - 1), & - & l) + q_beta(beta_vars(i))%sf(k, n + j, l) + y_kahan = real(q_beta(vars_comm(i))%sf(k, n + j, l), kind=wp) + kahan_comp(vars_comm(i))%sf(k, n + j, & + & l) - kahan_comp(vars_comm(i))%sf(k, n - (j - 1), l) + t_kahan = real(q_beta(vars_comm(i))%sf(k, n - (j - 1), l), kind=wp) + y_kahan + kahan_comp(vars_comm(i))%sf(k, n - (j - 1), l) = (t_kahan - q_beta(vars_comm(i))%sf(k, n - (j - 1), & + & l)) - y_kahan + q_beta(vars_comm(i))%sf(k, n - (j - 1), l) = t_kahan end do do j = 1, mapCells + 1 - q_beta(beta_vars(i))%sf(k, n + j, l) = q_beta(beta_vars(i))%sf(k, n - (j - 1), l) + q_beta(vars_comm(i))%sf(k, n + j, l) = q_beta(vars_comm(i))%sf(k, n - (j - 1), l) + kahan_comp(vars_comm(i))%sf(k, n + j, l) = kahan_comp(vars_comm(i))%sf(k, n - (j - 1), l) end do end do end if @@ -1363,21 +1410,30 @@ contains if (bc_loc == -1) then !< bc_z%beg do i = 1, nvar do j = 1, mapCells + 1 - q_beta(beta_vars(i))%sf(k, l, j - 1) = q_beta(beta_vars(i))%sf(k, l, j - 1) + q_beta(beta_vars(i))%sf(k, & - & l, -j) + y_kahan = real(q_beta(vars_comm(i))%sf(k, l, -j), kind=wp) + kahan_comp(vars_comm(i))%sf(k, l, & + & -j) - kahan_comp(vars_comm(i))%sf(k, l, j - 1) + t_kahan = real(q_beta(vars_comm(i))%sf(k, l, j - 1), kind=wp) + y_kahan + kahan_comp(vars_comm(i))%sf(k, l, j - 1) = (t_kahan - q_beta(vars_comm(i))%sf(k, l, j - 1)) - y_kahan + q_beta(vars_comm(i))%sf(k, l, j - 1) = t_kahan end do do j = 1, mapCells + 1 - q_beta(beta_vars(i))%sf(k, l, -j) = q_beta(beta_vars(i))%sf(k, l, j - 1) + q_beta(vars_comm(i))%sf(k, l, -j) = q_beta(vars_comm(i))%sf(k, l, j - 1) + kahan_comp(vars_comm(i))%sf(k, l, -j) = kahan_comp(vars_comm(i))%sf(k, l, j - 1) end do end do - else + else !< bc_z%end do i = 1, nvar do j = 1, mapCells + 1 - q_beta(beta_vars(i))%sf(k, l, p - (j - 1)) = q_beta(beta_vars(i))%sf(k, l, & - & p - (j - 1)) + q_beta(beta_vars(i))%sf(k, l, p + j) + y_kahan = real(q_beta(vars_comm(i))%sf(k, l, p + j), kind=wp) + kahan_comp(vars_comm(i))%sf(k, l, & + & p + j) - kahan_comp(vars_comm(i))%sf(k, l, p - (j - 1)) + t_kahan = real(q_beta(vars_comm(i))%sf(k, l, p - (j - 1)), kind=wp) + y_kahan + kahan_comp(vars_comm(i))%sf(k, l, p - (j - 1)) = (t_kahan - q_beta(vars_comm(i))%sf(k, l, & + & p - (j - 1))) - y_kahan + q_beta(vars_comm(i))%sf(k, l, p - (j - 1)) = t_kahan end do do j = 1, mapCells + 1 - q_beta(beta_vars(i))%sf(k, l, p + j) = q_beta(beta_vars(i))%sf(k, l, p - (j - 1)) + q_beta(vars_comm(i))%sf(k, l, p + j) = q_beta(vars_comm(i))%sf(k, l, p - (j - 1)) + kahan_comp(vars_comm(i))%sf(k, l, p + j) = kahan_comp(vars_comm(i))%sf(k, l, p - (j - 1)) end do end do end if diff --git a/src/common/m_derived_types.fpp b/src/common/m_derived_types.fpp index 620569e96b..506c914e6a 100644 --- a/src/common/m_derived_types.fpp +++ b/src/common/m_derived_types.fpp @@ -313,6 +313,10 @@ module m_derived_types type subgrid_particle_physical_parameters real(wp) :: rho0ref_particle !< Reference particle density real(wp) :: cp_particle !< Specific heat capacity of particle + real(wp) :: ksp_col !< number of timesteps over which collision occurs + real(wp) :: nu_col !< Poisson's ratio of particle for collision + real(wp) :: E_col !< Young's modulus of particle for collision + real(wp) :: cor_col !< coefficient of restituion for collision end type subgrid_particle_physical_parameters type mpi_io_airfoil_ib_var @@ -425,8 +429,10 @@ module m_derived_types integer :: added_mass_model !< Particle added mass model integer :: interpolation_order !< Fluid-to-Particle barycentric interpolation order logical :: collision_force !< Include collision forces + logical :: qs_fluct_force !< QS Fluctuations character(LEN=pathlen_max) :: input_path !< Path to lag_bubbles.dat integer :: charNz !< Number of grid cells in characteristic depth + real(wp) :: mu_ref !< Reference Viscosity for particle drag end type bubbles_lagrange_parameters !> Max and min number of cells in a direction of each combination of x-,y-, and z- diff --git a/src/common/m_model.fpp b/src/common/m_model.fpp index c88bffa7e6..d994ed3220 100644 --- a/src/common/m_model.fpp +++ b/src/common/m_model.fpp @@ -18,7 +18,7 @@ module m_model private public :: f_model_read, s_model_write, s_model_free, f_model_is_inside, models, gpu_ntrs, gpu_trs_v, gpu_trs_n, & - & gpu_boundary_v, gpu_boundary_edge_count, gpu_total_vertices, stl_bounding_boxes + & gpu_boundary_v, gpu_boundary_edge_count, gpu_total_vertices, stl_bounding_boxes, f_model_random_number ! Subroutines for STL immersed boundaries public :: s_check_boundary, s_register_edge, f_model_is_inside_flat, s_distance_normals_3D, s_distance_normals_2D, & diff --git a/src/common/m_mpi_common.fpp b/src/common/m_mpi_common.fpp index fd18eaad4b..3dc14c9d69 100644 --- a/src/common/m_mpi_common.fpp +++ b/src/common/m_mpi_common.fpp @@ -954,26 +954,35 @@ contains end subroutine s_mpi_sendrecv_variables_buffers - !> Decompose the computational domain among processors by balancing cells per rank in each coordinate direction. + !> The goal of this procedure is to populate the buffers of the cell-average conservative variables by communicating with the + !! neighboring processors. !! @param q_cons_vf Cell-average conservative variables - subroutine s_mpi_reduce_beta_variables_buffers(q_comm, mpi_dir, pbc_loc, nVar) + !! @param mpi_dir MPI communication coordinate direction + !! @param pbc_loc Processor boundary condition (PBC) location + subroutine s_mpi_reduce_beta_variables_buffers(q_comm, kahan_comp, mpi_dir, pbc_loc, nVar, vars_comm) type(scalar_field), dimension(1:), intent(inout) :: q_comm + type(scalar_field), dimension(1:), intent(inout) :: kahan_comp integer, intent(in) :: mpi_dir, pbc_loc, nVar + integer, dimension(:), intent(in) :: vars_comm integer :: i, j, k, l, r, q !< Generic loop iterators integer :: lb_size integer :: buffer_counts(1:3), buffer_count type(int_bounds_info) :: boundary_conditions(1:3) integer :: beg_end(1:2), grid_dims(1:3) integer :: dst_proc, src_proc, recv_tag, send_tag - logical :: beg_end_geq_0, qbmm_comm, replace_buff + logical :: replace_buff integer :: pack_offset, unpack_offset + real(wp) :: y_kahan, t_kahan #ifdef MFC_MPI integer :: ierr !< Generic flag used to identify and report MPI errors call nvtxStartRange("BETA-COMM-PACKBUF") + ! Set bounds for each dimension Always include the full buffer range for each existing dimension. The Gaussian smearing + ! kernel writes to buffer cells even at physical boundaries, and these contributions must be communicated to neighbors in + ! other directions via ADD operations. comm_coords(1)%beg = -mapcells - 1 comm_coords(1)%end = m + mapcells + 1 comm_coords(2)%beg = merge(-mapcells - 1, 0, n > 0) @@ -997,68 +1006,71 @@ contains buffer_count = buffer_counts(mpi_dir) boundary_conditions = (/bc_x, bc_y, bc_z/) beg_end = (/boundary_conditions(mpi_dir)%beg, boundary_conditions(mpi_dir)%end/) - beg_end_geq_0 = beg_end(max(pbc_loc, 0) - pbc_loc + 1) >= 0 - - send_tag = f_logical_to_int(.not. f_xor(beg_end_geq_0, pbc_loc == 1)) - recv_tag = f_logical_to_int(pbc_loc == 1) - - dst_proc = beg_end(1 + f_logical_to_int(f_xor(pbc_loc == 1, beg_end_geq_0))) - src_proc = beg_end(1 + f_logical_to_int(pbc_loc == 1)) - grid_dims = (/m, n, p/) - pack_offset = 0 - if (f_xor(pbc_loc == 1, beg_end_geq_0)) then + if (pbc_loc == -1) then + ! Phase 1: Rightward accumulation Send END buffer to right neighbor, recv from left into BEG, ADD pack_offset = grid_dims(mpi_dir) + 1 - end if - - unpack_offset = 0 - if (pbc_loc == 1) then + unpack_offset = 0 + dst_proc = merge(beg_end(2), MPI_PROC_NULL, beg_end(2) >= 0) + src_proc = merge(beg_end(1), MPI_PROC_NULL, beg_end(1) >= 0) + send_tag = 0 + recv_tag = 0 + replace_buff = .false. + else + ! Phase 2: Leftward distribution Send BEG buffer to left neighbor, recv from right into END, REPLACE + pack_offset = 0 unpack_offset = grid_dims(mpi_dir) + 1 + dst_proc = merge(beg_end(1), MPI_PROC_NULL, beg_end(1) >= 0) + src_proc = merge(beg_end(2), MPI_PROC_NULL, beg_end(2) >= 0) + send_tag = 1 + recv_tag = 1 + replace_buff = .true. end if - replace_buff = .false. - if (pbc_loc == 1 .and. beg_end_geq_0) replace_buff = .true. - + ! Pack Buffer to Send #:for mpi_dir in [1, 2, 3] if (mpi_dir == ${mpi_dir}$) then #:if mpi_dir == 1 - $:GPU_PARALLEL_LOOP(collapse=4,private='[r]') + $:GPU_PARALLEL_LOOP(collapse=4,private='[r]',copyin='[vars_comm]') do l = comm_coords(3)%beg, comm_coords(3)%end do k = comm_coords(2)%beg, comm_coords(2)%end do j = -mapcells - 1, mapcells do i = 1, v_size r = (i - 1) + v_size*((j + mapcells + 1) + lb_size*((k - comm_coords(2)%beg) + comm_size(2) & & *(l - comm_coords(3)%beg))) - buff_send(r) = real(q_comm(beta_vars(i))%sf(j + pack_offset, k, l), kind=wp) + buff_send(r) = real(q_comm(vars_comm(i))%sf(j + pack_offset, k, l), & + & kind=wp) - real(kahan_comp(vars_comm(i))%sf(j + pack_offset, k, l), kind=wp) end do end do end do end do $:END_GPU_PARALLEL_LOOP() #:elif mpi_dir == 2 - $:GPU_PARALLEL_LOOP(collapse=4,private='[r]') + $:GPU_PARALLEL_LOOP(collapse=4,private='[r]',copyin='[vars_comm]') do i = 1, v_size do l = comm_coords(3)%beg, comm_coords(3)%end do k = -mapcells - 1, mapcells do j = comm_coords(1)%beg, comm_coords(1)%end r = (i - 1) + v_size*((j - comm_coords(1)%beg) + comm_size(1)*((k + mapcells + 1) & & + lb_size*(l - comm_coords(3)%beg))) - buff_send(r) = real(q_comm(beta_vars(i))%sf(j, k + pack_offset, l), kind=wp) + buff_send(r) = real(q_comm(vars_comm(i))%sf(j, k + pack_offset, l), & + & kind=wp) - real(kahan_comp(vars_comm(i))%sf(j, k + pack_offset, l), kind=wp) end do end do end do end do $:END_GPU_PARALLEL_LOOP() #:else - $:GPU_PARALLEL_LOOP(collapse=4,private='[r]') + $:GPU_PARALLEL_LOOP(collapse=4,private='[r]',copyin='[vars_comm]') do i = 1, v_size do l = -mapcells - 1, mapcells do k = comm_coords(2)%beg, comm_coords(2)%end do j = comm_coords(1)%beg, comm_coords(1)%end r = (i - 1) + v_size*((j - comm_coords(1)%beg) + comm_size(1)*((k - comm_coords(2)%beg) & & + comm_size(2)*(l + mapcells + 1))) - buff_send(r) = real(q_comm(beta_vars(i))%sf(j, k, l + pack_offset), kind=wp) + buff_send(r) = real(q_comm(vars_comm(i))%sf(j, k, l + pack_offset), & + & kind=wp) - real(kahan_comp(vars_comm(i))%sf(j, k, l + pack_offset), kind=wp) end do end do end do @@ -1069,6 +1081,7 @@ contains #:endfor call nvtxEndRange ! Packbuf + ! Send/Recv #ifdef MFC_SIMULATION #:for rdma_mpi in [False, True] if (rdma_mpi .eqv. ${'.true.' if rdma_mpi else '.false.'}$) then @@ -1079,23 +1092,23 @@ contains call MPI_SENDRECV(buff_send, buffer_count, mpi_p, dst_proc, send_tag, buff_recv, buffer_count, mpi_p, & & src_proc, recv_tag, MPI_COMM_WORLD, MPI_STATUS_IGNORE, ierr) - call nvtxEndRange ! Packbuf + call nvtxEndRange ! BETA-MPI-SENDRECV-(NO)-RDMA #:endcall GPU_HOST_DATA $:GPU_WAIT() #:else call nvtxStartRange("BETA-COMM-DEV2HOST") $:GPU_UPDATE(host='[buff_send]') - call nvtxEndRange ! Packbuf - call nvtxStartRange("BETA-COMM-SENDRECV-NO-RDMA") + call nvtxEndRange + call nvtxStartRange("BETA-COMM-SENDRECV-NO-RMDA") call MPI_SENDRECV(buff_send, buffer_count, mpi_p, dst_proc, send_tag, buff_recv, buffer_count, mpi_p, & & src_proc, recv_tag, MPI_COMM_WORLD, MPI_STATUS_IGNORE, ierr) - call nvtxEndRange ! Packbuf + call nvtxEndRange ! BETA-MPI-SENDRECV-(NO)-RDMA call nvtxStartRange("BETA-COMM-HOST2DEV") $:GPU_UPDATE(device='[buff_recv]') - call nvtxEndRange ! Packbuf + call nvtxEndRange #:endif end if #:endfor @@ -1104,71 +1117,95 @@ contains & MPI_COMM_WORLD, MPI_STATUS_IGNORE, ierr) #endif + ! Unpack Received Buffer (skip if no source rank) call nvtxStartRange("BETA-COMM-UNPACKBUF") - #:for mpi_dir in [1, 2, 3] - if (mpi_dir == ${mpi_dir}$) then - #:if mpi_dir == 1 - $:GPU_PARALLEL_LOOP(collapse=4,private='[r]',copyin='[replace_buff]') - do l = comm_coords(3)%beg, comm_coords(3)%end - do k = comm_coords(2)%beg, comm_coords(2)%end - do j = -mapcells - 1, mapcells - do i = 1, v_size - r = (i - 1) + v_size*((j + mapcells + 1) + lb_size*((k - comm_coords(2)%beg) + comm_size(2) & - & *(l - comm_coords(3)%beg))) - if (replace_buff) then - q_comm(beta_vars(i))%sf(j + unpack_offset, k, l) = real(buff_recv(r), kind=stp) - else - q_comm(beta_vars(i))%sf(j + unpack_offset, k, & - & l) = q_comm(beta_vars(i))%sf(j + unpack_offset, k, l) + real(buff_recv(r), & - & kind=stp) - end if + if (src_proc /= MPI_PROC_NULL) then + #:for mpi_dir in [1, 2, 3] + if (mpi_dir == ${mpi_dir}$) then + #:if mpi_dir == 1 + $:GPU_PARALLEL_LOOP(collapse=4,private='[r, y_kahan, t_kahan]',copyin='[replace_buff, vars_comm]') + do l = comm_coords(3)%beg, comm_coords(3)%end + do k = comm_coords(2)%beg, comm_coords(2)%end + do j = -mapcells - 1, mapcells + do i = 1, v_size + r = (i - 1) + v_size*((j + mapcells + 1) + lb_size*((k - comm_coords(2)%beg) & + & + comm_size(2)*(l - comm_coords(3)%beg))) + if (replace_buff) then + q_comm(vars_comm(i))%sf(j + unpack_offset, k, l) = real(buff_recv(r), kind=stp) + kahan_comp(vars_comm(i))%sf(j + unpack_offset, k, & + & l) = real(q_comm(vars_comm(i))%sf(j + unpack_offset, k, l), & + & kind=wp) - buff_recv(r) + else + y_kahan = buff_recv(r) - real(kahan_comp(vars_comm(i))%sf(j + unpack_offset, k, l), & + & kind=wp) + t_kahan = real(q_comm(vars_comm(i))%sf(j + unpack_offset, k, l), kind=wp) + y_kahan + kahan_comp(vars_comm(i))%sf(j + unpack_offset, k, & + & l) = (t_kahan - q_comm(vars_comm(i))%sf(j + unpack_offset, k, l)) - y_kahan + q_comm(vars_comm(i))%sf(j + unpack_offset, k, l) = t_kahan + end if + end do end do end do end do - end do - $:END_GPU_PARALLEL_LOOP() - #:elif mpi_dir == 2 - $:GPU_PARALLEL_LOOP(collapse=4,private='[r]',copyin='[replace_buff]') - do i = 1, v_size - do l = comm_coords(3)%beg, comm_coords(3)%end - do k = -mapcells - 1, mapcells - do j = comm_coords(1)%beg, comm_coords(1)%end - r = (i - 1) + v_size*((j - comm_coords(1)%beg) + comm_size(1)*((k + mapcells + 1) & - & + lb_size*(l - comm_coords(3)%beg))) - if (replace_buff) then - q_comm(beta_vars(i))%sf(j, k + unpack_offset, l) = real(buff_recv(r), kind=stp) - else - q_comm(beta_vars(i))%sf(j, k + unpack_offset, l) = q_comm(beta_vars(i))%sf(j, & - & k + unpack_offset, l) + real(buff_recv(r), kind=stp) - end if + $:END_GPU_PARALLEL_LOOP() + #:elif mpi_dir == 2 + $:GPU_PARALLEL_LOOP(collapse=4,private='[r, y_kahan, t_kahan]',copyin='[replace_buff, vars_comm]') + do i = 1, v_size + do l = comm_coords(3)%beg, comm_coords(3)%end + do k = -mapcells - 1, mapcells + do j = comm_coords(1)%beg, comm_coords(1)%end + r = (i - 1) + v_size*((j - comm_coords(1)%beg) + comm_size(1)*((k + mapcells + 1) & + & + lb_size*(l - comm_coords(3)%beg))) + if (replace_buff) then + q_comm(vars_comm(i))%sf(j, k + unpack_offset, l) = real(buff_recv(r), kind=stp) + kahan_comp(vars_comm(i))%sf(j, k + unpack_offset, & + & l) = real(q_comm(vars_comm(i))%sf(j, k + unpack_offset, l), & + & kind=wp) - buff_recv(r) + else + y_kahan = buff_recv(r) - real(kahan_comp(vars_comm(i))%sf(j, k + unpack_offset, l), & + & kind=wp) + t_kahan = real(q_comm(vars_comm(i))%sf(j, k + unpack_offset, l), kind=wp) + y_kahan + kahan_comp(vars_comm(i))%sf(j, k + unpack_offset, & + & l) = (t_kahan - q_comm(vars_comm(i))%sf(j, k + unpack_offset, l)) - y_kahan + q_comm(vars_comm(i))%sf(j, k + unpack_offset, l) = t_kahan + end if + end do end do end do end do - end do - $:END_GPU_PARALLEL_LOOP() - #:else - $:GPU_PARALLEL_LOOP(collapse=4,private='[r]',copyin='[replace_buff]') - do i = 1, v_size - do l = -mapcells - 1, mapcells - do k = comm_coords(2)%beg, comm_coords(2)%end - do j = comm_coords(1)%beg, comm_coords(1)%end - r = (i - 1) + v_size*((j - comm_coords(1)%beg) + comm_size(1)*((k - comm_coords(2)%beg) & - & + comm_size(2)*(l + mapcells + 1))) - if (replace_buff) then - q_comm(beta_vars(i))%sf(j, k, l + unpack_offset) = real(buff_recv(r), kind=stp) - else - q_comm(beta_vars(i))%sf(j, k, l + unpack_offset) = q_comm(beta_vars(i))%sf(j, k, & - & l + unpack_offset) + real(buff_recv(r), kind=stp) - end if + $:END_GPU_PARALLEL_LOOP() + #:else + $:GPU_PARALLEL_LOOP(collapse=4,private='[r, y_kahan, t_kahan]',copyin='[replace_buff, vars_comm]') + do i = 1, v_size + do l = -mapcells - 1, mapcells + do k = comm_coords(2)%beg, comm_coords(2)%end + do j = comm_coords(1)%beg, comm_coords(1)%end + r = (i - 1) + v_size*((j - comm_coords(1)%beg) + comm_size(1)*((k - comm_coords(2)%beg) & + & + comm_size(2)*(l + mapcells + 1))) + if (replace_buff) then + q_comm(vars_comm(i))%sf(j, k, l + unpack_offset) = real(buff_recv(r), kind=stp) + kahan_comp(vars_comm(i))%sf(j, k, & + & l + unpack_offset) = real(q_comm(vars_comm(i))%sf(j, k, & + & l + unpack_offset), kind=wp) - buff_recv(r) + else + y_kahan = buff_recv(r) - real(kahan_comp(vars_comm(i))%sf(j, k, l + unpack_offset), & + & kind=wp) + t_kahan = real(q_comm(vars_comm(i))%sf(j, k, l + unpack_offset), kind=wp) + y_kahan + kahan_comp(vars_comm(i))%sf(j, k, & + & l + unpack_offset) = (t_kahan - q_comm(vars_comm(i))%sf(j, k, & + & l + unpack_offset)) - y_kahan + q_comm(vars_comm(i))%sf(j, k, l + unpack_offset) = t_kahan + end if + end do end do end do end do - end do - $:END_GPU_PARALLEL_LOOP() - #:endif - end if - #:endfor - call nvtxEndRange ! Packbuf + $:END_GPU_PARALLEL_LOOP() + #:endif + end if + #:endfor + end if + call nvtxEndRange #endif end subroutine s_mpi_reduce_beta_variables_buffers diff --git a/src/post_process/m_global_parameters.fpp b/src/post_process/m_global_parameters.fpp index 212449b90f..8e44769036 100644 --- a/src/post_process/m_global_parameters.fpp +++ b/src/post_process/m_global_parameters.fpp @@ -444,6 +444,10 @@ contains ! Subgrid particle parameters particle_pp%rho0ref_particle = dflt_real particle_pp%cp_particle = dflt_real + particle_pp%ksp_col = dflt_real + particle_pp%nu_col = dflt_real + particle_pp%E_col = dflt_real + particle_pp%cor_col = dflt_real ! Formatted database file(s) structure parameters format = dflt_int @@ -809,8 +813,8 @@ contains allocate (beta_vars(1:3)) beta_vars(1:3) = [1, 2, 5] else if (particles_lagrange) then - allocate (beta_vars(1:8)) - beta_vars(1:8) = [1, 2, 3, 4, 5, 6, 7, 8] + allocate (beta_vars(1:7)) + beta_vars(1:7) = [1, 2, 3, 4, 5, 6, 7] end if if (chemistry) then diff --git a/src/pre_process/m_global_parameters.fpp b/src/pre_process/m_global_parameters.fpp index db675c3cf6..6ec72b7034 100644 --- a/src/pre_process/m_global_parameters.fpp +++ b/src/pre_process/m_global_parameters.fpp @@ -419,6 +419,7 @@ contains lag_params%interpolation_order = dflt_int lag_params%charNz = dflt_int lag_params%valmaxvoid = dflt_real + lag_params%mu_ref = dflt_real do i = 1, num_patches_max patch_icpp(i)%geometry = dflt_int @@ -625,6 +626,10 @@ contains ! Subgrid particle parameters particle_pp%rho0ref_particle = dflt_real particle_pp%cp_particle = dflt_real + particle_pp%ksp_col = dflt_real + particle_pp%nu_col = dflt_real + particle_pp%E_col = dflt_real + particle_pp%cor_col = dflt_real end subroutine s_assign_default_values_to_user_inputs @@ -887,8 +892,8 @@ contains allocate (beta_vars(1:3)) beta_vars(1:3) = [1, 2, 5] else if (particles_lagrange) then - allocate (beta_vars(1:8)) - beta_vars(1:8) = [1, 2, 3, 4, 5, 6, 7, 8] + allocate (beta_vars(1:7)) + beta_vars(1:7) = [1, 2, 3, 4, 5, 6, 7] end if if (chemistry) then diff --git a/src/simulation/m_bubbles_EL.fpp b/src/simulation/m_bubbles_EL.fpp index 8a55d787ee..768b939295 100644 --- a/src/simulation/m_bubbles_EL.fpp +++ b/src/simulation/m_bubbles_EL.fpp @@ -7,14 +7,14 @@ !> @brief Tracks Lagrangian bubbles and couples their dynamics to the Eulerian flow via volume averaging module m_bubbles_EL - use m_global_parameters - use m_mpi_proxy - use m_bubbles_EL_kernels - use m_bubbles - use m_variables_conversion + use m_global_parameters !< Definitions of the global parameters + use m_mpi_proxy !< Message passing interface (MPI) module proxy + use m_bubbles_EL_kernels !< Definitions of the kernel functions + use m_bubbles !< General bubble dynamics procedures + use m_variables_conversion !< State variables type conversion procedures use m_compile_specific use m_boundary_common - use m_helper_basic + use m_helper_basic !< Functions to compare floating point numbers use m_sim_helpers use m_helper use m_mpi_common @@ -58,9 +58,10 @@ module m_bubbles_EL $:GPU_DECLARE(create='[intfc_draddt, intfc_dveldt, gas_dpdt, gas_dmvdt, mtn_dposdt, mtn_dveldt]') integer, private :: lag_num_ts !< Number of time stages in the time-stepping scheme + $:GPU_DECLARE(create='[lag_num_ts]') - real(wp) :: Rmax_glb, Rmin_glb !< Maximum and minimum bubbe size in the local domain + real(wp) :: Rmax_glb, Rmin_glb !< Maximum and minimum bubble size in the local domain !> Projection of the lagrangian particles in the Eulerian framework type(scalar_field), dimension(:), allocatable :: q_beta type(scalar_field), dimension(:), allocatable :: kahan_comp !< Kahan compensation for q_beta accumulation @@ -79,6 +80,7 @@ module m_bubbles_EL contains !> Initializes the lagrangian subgrid bubble solver + !! @param q_cons_vf Initial conservative variables impure subroutine s_initialize_bubbles_EL_module(q_cons_vf, bc_type) type(scalar_field), dimension(sys_size), intent(inout) :: q_cons_vf @@ -207,7 +209,8 @@ contains end subroutine s_initialize_bubbles_EL_module - !> Read initial bubble data from input files + !> The purpose of this procedure is to obtain the initial bubbles' information + !! @param q_cons_vf Conservative variables impure subroutine s_read_input_bubbles(q_cons_vf, bc_type) type(scalar_field), dimension(sys_size), intent(inout) :: q_cons_vf @@ -308,7 +311,10 @@ contains end subroutine s_read_input_bubbles - !> Add a new bubble from input data for a fresh start + !> The purpose of this procedure is to obtain the information of the bubbles when starting fresh + !! @param inputBubble Bubble information + !! @param q_cons_vf Conservative variables + !! @param bub_id Local id of the bubble impure subroutine s_add_bubbles(inputBubble, q_cons_vf, bub_id) type(scalar_field), dimension(sys_size), intent(in) :: q_cons_vf @@ -416,7 +422,9 @@ contains end subroutine s_add_bubbles - !> Restore bubble data from a restart file + !> The purpose of this procedure is to obtain the information of the bubbles from a restart point. + !! @param bub_id Local ID of the particle + !! @param save_count File identifier impure subroutine s_restart_bubbles(bub_id, save_count) integer, intent(inout) :: bub_id, save_count @@ -570,6 +578,8 @@ contains end subroutine s_restart_bubbles !> Contains the bubble dynamics subroutines. + !! @param q_prim_vf Primitive variables + !! @param stage Current stage in the time-stepper algorithm subroutine s_compute_bubble_EL_dynamics(q_prim_vf, bc_type, stage) type(scalar_field), dimension(sys_size), intent(inout) :: q_prim_vf @@ -683,6 +693,7 @@ contains ! Radial acceleration from bubble models intfc_dveldt(k, stage) = f_rddot(myRho, myPinf, myR, myV, myR0, myPb, myPbdot, dmalf, dmntait, dmBtait, & & dm_bub_adv_src, dm_divu, myCson) + intfc_draddt(k, stage) = myV gas_dmvdt(k, stage) = myMvdot gas_dpdt(k, stage) = myPbdot @@ -715,7 +726,6 @@ contains adap_dt_stop_sum = adap_dt_stop_sum + adap_dt_stop end do $:END_GPU_PARALLEL_LOOP() - ! Bubbles remain in a fixed position call nvtxEndRange if (adap_dt .and. adap_dt_stop_sum > 0) call s_mpi_abort("Adaptive time stepping failed to converge.") @@ -728,7 +738,11 @@ contains end subroutine s_compute_bubble_EL_dynamics - !> Compute the Lagrangian bubble source terms and add them to the RHS + !> The purpose of this subroutine is to obtain the bubble source terms based on Maeda and Colonius (2018) and add them to the + !! RHS scalar field. + !! @param q_cons_vf Conservative variables + !! @param q_prim_vf Conservative variables + !! @param rhs_vf Time derivative of the conservative variables subroutine s_compute_bubbles_EL_source(q_cons_vf, q_prim_vf, rhs_vf) type(scalar_field), dimension(sys_size), intent(inout) :: q_cons_vf @@ -737,6 +751,7 @@ contains integer :: i, j, k, l call nvtxStartRange("LAGRANGE-BUBBLE-EL-SOURCE") + ! (q / (1 - beta)) * d(beta)/dt source if (lag_params%cluster_type >= 4) then $:GPU_PARALLEL_LOOP(private='[i, j, k, l]', collapse=4) do k = idwint(3)%beg, idwint(3)%end @@ -772,6 +787,7 @@ contains do l = 1, num_dims call s_gradient_dir(q_prim_vf(E_idx)%sf, q_beta(3)%sf, l) + ! (q / (1 - beta)) * d(beta)/dt source $:GPU_PARALLEL_LOOP(private='[i, j, k]', collapse=3) do k = idwint(3)%beg, idwint(3)%end do j = idwint(2)%beg, idwint(2)%end @@ -785,6 +801,7 @@ contains end do $:END_GPU_PARALLEL_LOOP() + ! source in energy $:GPU_PARALLEL_LOOP(private='[i, j, k]', collapse=3) do k = idwbuff(3)%beg, idwbuff(3)%end do j = idwbuff(2)%beg, idwbuff(2)%end @@ -797,6 +814,7 @@ contains call s_gradient_dir(q_beta(3)%sf, q_beta(4)%sf, l) + ! (beta / (1 - beta)) * d(Pu)/dl source $:GPU_PARALLEL_LOOP(private='[i, j, k]', collapse=3) do k = idwint(3)%beg, idwint(3)%end do j = idwint(2)%beg, idwint(2)%end @@ -810,11 +828,18 @@ contains end do $:END_GPU_PARALLEL_LOOP() end do - call nvtxEndRange + call nvtxEndRange ! LAGRANGE-BUBBLE-EL-SOURCE end subroutine s_compute_bubbles_EL_source - !> Compute the speed of sound from a given driving pressure + !> This procedure computes the speed of sound from a given driving pressure + !! @param q_prim_vf Primitive variables + !! @param pinf Driving pressure + !! @param cell Bubble cell + !! @param rhol Liquid density + !! @param gamma Liquid specific heat ratio + !! @param pi_inf Liquid stiffness + !! @param cson Calculated speed of sound subroutine s_compute_cson_from_pinf(q_prim_vf, pinf, cell, rhol, gamma, pi_inf, cson) $:GPU_ROUTINE(function_name='s_compute_cson_from_pinf', parallelism='[seq]', cray_inline=True) @@ -842,7 +867,7 @@ contains end subroutine s_compute_cson_from_pinf - !> Smear the bubble effects onto the Eulerian grid + !> The purpose of this subroutine is to smear the effect of the bubbles in the Eulerian framework subroutine s_smear_voidfraction(bc_type) type(integer_field), dimension(1:num_dims,1:2), intent(in) :: bc_type @@ -869,9 +894,9 @@ contains call nvtxStartRange("BUBBLES-LAGRANGE-BETA-COMM") if (lag_params%cluster_type >= 4) then - call s_populate_beta_buffers(q_beta, bc_type, 3) + call s_populate_beta_buffers(q_beta, kahan_comp, bc_type, 3, beta_vars) else - call s_populate_beta_buffers(q_beta, bc_type, 2) + call s_populate_beta_buffers(q_beta, kahan_comp, bc_type, 2, beta_vars) end if call nvtxEndRange @@ -887,11 +912,19 @@ contains end do end do $:END_GPU_PARALLEL_LOOP() - call nvtxEndRange + call nvtxEndRange ! BUBBLES-LAGRANGE-SMEARING end subroutine s_smear_voidfraction - !> Compute the bubble driving pressure p_inf + !> The purpose of this procedure is obtain the bubble driving pressure p_inf + !! @param bub_id Particle identifier + !! @param q_prim_vf Primitive variables + !! @param ptype 1: p at infinity, 2: averaged P at the bubble location + !! @param f_pinfl Driving pressure + !! @param cell Bubble cell + !! @param preterm1 Pre-computed term 1 + !! @param term2 Computed term 2 + !! @param Romega Control volume radius subroutine s_get_pinf(bub_id, q_prim_vf, ptype, f_pinfl, cell, preterm1, term2, Romega) $:GPU_ROUTINE(function_name='s_get_pinf',parallelism='[seq]', cray_inline=True) @@ -912,7 +945,6 @@ contains f_pinfl = 0._wp - !> Find current bubble cell if (moving_lag_bubbles) then cell = fd_number - buff_size call s_locate_cell(mtn_pos(bub_id,1:3,2), cell, mtn_s(bub_id,1:3,2)) @@ -928,7 +960,6 @@ contains if ((lag_params%cluster_type == 1)) then !> Getting p_cell in terms of only the current cell by interpolation - !> Getting the cell volulme as Omega if (fd_order == 2) then ! Bilinear interpolation @@ -941,8 +972,8 @@ contains vol = dx(cell(1))*dy(cell(2))*lag_params%charwidth end if end if - !> Obtain bilinear interpolation coefficients, based on the current location of the bubble. + !> Obtain bilinear interpolation coefficients, based on the current location of the bubble. psi_pos(1) = (scoord(1) - real(cell(1)))*dx(cell(1)) + x_cb(cell(1) - 1) psi_pos(1) = abs((psi_pos(1) - x_cc(cell(1)))/(x_cc(cell(1) + 1) - x_cc(cell(1)))) @@ -955,7 +986,9 @@ contains else psi_pos(3) = 0._wp end if - !> Perform bilinear interpolation + + ! Calculate bilinear basis functions for each direction For normalized coordinate xi in [0, 1], the two basis + ! functions are: phi_0(xi) = 1 - xi, phi_1(xi) = xi ! X-direction basis functions psi_x(1) = 1._wp - psi_pos(1) ! Left basis function @@ -969,20 +1002,21 @@ contains ! Z-direction basis functions psi_z(1) = 1._wp - psi_pos(3) ! Left basis function psi_z(2) = psi_pos(3) ! Right basis function - else ! 3D + else psi_z(1) = 1._wp psi_z(2) = 0._wp end if + !> Perform bilinear interpolation f_pinfl = 0._wp - if (p == 0) then + if (p == 0) then ! 2D - 4 point interpolation (2x2) do j = 1, 2 do i = 1, 2 f_pinfl = f_pinfl + q_prim_vf(E_idx)%sf(cell(1) + i - 1, cell(2) + j - 1, cell(3))*psi_x(i)*psi_y(j) end do end do - else + else ! 3D - 8 point interpolation (2x2x2) do k = 1, 2 do j = 1, 2 do i = 1, 2 @@ -1003,6 +1037,7 @@ contains end if end if + !> Obtain biquadratic interpolation coefficients, based on the current location of the bubble. ! For biquadratic interpolation, we need coefficients for 3 points in each direction psi_pos(1) = (scoord(1) - real(cell(1)))*dx(cell(1)) + x_cb(cell(1) - 1) psi_pos(1) = (psi_pos(1) - x_cc(cell(1)))/(x_cc(cell(1) + 1) - x_cc(cell(1))) @@ -1017,6 +1052,9 @@ contains psi_pos(3) = 0._wp end if + ! Calculate biquadratic basis functions for each direction For normalized coordinate xi in [-1, 1], the three basis + ! functions are: phi_0(xi) = xi*(xi-1)/2, phi_1(xi) = (1-xi)*(1+xi), phi_2(xi) = xi*(xi+1)/2 + ! X-direction basis functions xi = 2._wp*psi_pos(1) - 1._wp ! Convert to [-1, 1] range psi_x(1) = xi*(xi - 1._wp)/2._wp ! Left basis function @@ -1041,15 +1079,16 @@ contains psi_z(3) = 0._wp end if + !> Perform biquadratic interpolation f_pinfl = 0._wp - if (p == 0) then ! 2D + if (p == 0) then ! 2D - 9 point interpolation (3x3) do j = 1, 3 do i = 1, 3 f_pinfl = f_pinfl + q_prim_vf(E_idx)%sf(cell(1) + i - 2, cell(2) + j - 2, cell(3))*psi_x(i)*psi_y(j) end do end do - else + else ! 3D - 27 point interpolation (3x3x3) do k = 1, 3 do j = 1, 3 do i = 1, 3 @@ -1088,7 +1127,7 @@ contains cellaux(3) = cell(3) + k - (mapCells + 1) if (p == 0) cellaux(3) = 0 - !> check if the current cell is outside the computational domain or not (including ghost cells) + !> Obtaining the cell volume if (p > 0) then vol = dx(cellaux(1))*dy(cellaux(2))*dz(cellaux(3)) else @@ -1098,7 +1137,6 @@ contains vol = dx(cellaux(1))*dy(cellaux(2))*lag_params%charwidth end if end if - !> Obtaining the cell volulme !> Update values charvol = charvol + vol charpres = charpres + q_prim_vf(E_idx)%sf(cellaux(1), cellaux(2), cellaux(3))*vol @@ -1137,7 +1175,9 @@ contains end subroutine s_get_pinf - !> Update Lagrangian bubble variables using TVD Runge-Kutta time stepping + !> This subroutine updates the Lagrange variables using the tvd RK time steppers. The time derivative of the bubble variables + !! must be stored at every stage to avoid precision errors. + !! @param stage Current tvd RK stage impure subroutine s_update_lagrange_tdv_rk(q_prim_vf, bc_type, stage) type(scalar_field), dimension(sys_size), intent(in) :: q_prim_vf @@ -1146,6 +1186,7 @@ contains integer :: k if (time_stepper == 1) then ! 1st order TVD RK + $:GPU_PARALLEL_LOOP(private='[k]') do k = 1, n_el_bubs_loc ! u{1} = u{n} + dt * RHS{n} @@ -1286,7 +1327,6 @@ contains end subroutine s_update_lagrange_tdv_rk - !> Locate the cell index for a given physical position !> This subroutine enforces reflective and wall boundary conditions for EL bubbles !! @param dest Destination for the bubble position update impure subroutine s_enforce_EL_bubbles_boundary_conditions(q_prim_vf) @@ -1330,6 +1370,7 @@ contains wrap_bubble_loc(k,:) = 0 wrap_bubble_dir(k,:) = 0 + ! Relocate bubbles at solid boundaries and delete bubbles that leave buffer regions if (any(bc_x%beg == (/BC_REFLECTIVE, BC_CHAR_SLIP_WALL, BC_SLIP_WALL, BC_NO_SLIP_WALL/)) .and. mtn_pos(k, 1, & & 2) < x_cb(-1) + intfc_rad(k, 2)) then mtn_pos(k, 1, 2) = x_cb(-1) + intfc_rad(k, 2) @@ -1457,11 +1498,16 @@ contains cell = fd_number - buff_size call s_locate_cell(mtn_pos(k,1:3,2), cell, mtn_s(k,1:3,2)) end do + $:END_GPU_PARALLEL_LOOP() - call nvtxEndRange + call nvtxEndRange ! LAG-BC end subroutine s_enforce_EL_bubbles_boundary_conditions + !> This subroutine returns the computational coordinate of the cell for the given position. + !! @param pos Input coordinates + !! @param cell Computational coordinate of the cell + !! @param scoord Calculated particle coordinates subroutine s_locate_cell(pos, cell, scoord) $:GPU_ROUTINE(function_name='s_locate_cell',parallelism='[seq]', cray_inline=True) @@ -1512,7 +1558,7 @@ contains end subroutine s_locate_cell - !> Transfer data into the temporal variables + !> This subroutine transfer data into the temporal variables. impure subroutine s_transfer_data_to_tmp() integer :: k @@ -1532,7 +1578,9 @@ contains end subroutine s_transfer_data_to_tmp - !> Determine if a bubble position lies within the current MPI subdomain including ghost cells + !> The purpose of this procedure is to determine if the global coordinates of the bubbles are present in the current MPI + !! processor (including ghost cells). + !! @param pos_part Spatial coordinates of the bubble function particle_in_domain(pos_part) logical :: particle_in_domain @@ -1585,7 +1633,9 @@ contains end function particle_in_domain - !> Determine if a Lagrangian bubble is within the physical domain excluding ghost cells + !> The purpose of this procedure is to determine if the lagrangian bubble is located in the physical domain. The ghost cells are + !! not part of the physical domain. + !! @param pos_part Spatial coordinates of the bubble function particle_in_domain_physical(pos_part) logical :: particle_in_domain_physical @@ -1601,7 +1651,11 @@ contains end function particle_in_domain_physical - !> Compute the gradient of a scalar field using second-order central differences on a non-uniform grid + !> The purpose of this procedure is to calculate the gradient of a scalar field along the x, y and z directions following a + !! second-order central difference considering uneven widths + !! @param q Input scalar field + !! @param dq Output gradient of q + !! @param dir Gradient spatial direction subroutine s_gradient_dir(q, dq, dir) real(stp), dimension(idwbuff(1)%beg:,idwbuff(2)%beg:,idwbuff(3)%beg:), intent(inout) :: q, dq @@ -1651,7 +1705,8 @@ contains end subroutine s_gradient_dir - !> Write Lagrangian bubble state data at each time step + !> Subroutine that writes on each time step the changes of the lagrangian bubbles. + !! @param qtime Current time impure subroutine s_write_lag_particles(qtime) real(wp), intent(in) :: qtime @@ -1707,6 +1762,7 @@ contains end subroutine s_open_lag_bubble_evol + !> Subroutine that writes on each time step the changes of the lagrangian bubbles. !! @param q_time Current time impure subroutine s_write_lag_bubble_evol(qtime) @@ -1728,8 +1784,6 @@ contains & gas_mv(k, 1)/(gas_mv(k, 1) + gas_mg(k)), intfc_rad(k, 1), intfc_vel(k, 1), gas_p(k, 1) end do - !> Write void fraction statistics at each time step - end subroutine s_write_lag_bubble_evol impure subroutine s_close_lag_bubble_evol @@ -1749,6 +1803,9 @@ contains call my_inquire(trim(file_loc), file_exist) if (.not. file_exist) then open (LAG_VOID_ID, FILE=trim(file_loc), form='formatted', position='rewind') + ! write (12, *) 'currentTime, averageVoidFraction, ', & 'maximumVoidFraction, totalParticlesVolume' write (12, *) + ! 'The averageVoidFraction value does ', & 'not reflect the real void fraction in the cloud since the ', & 'cells + ! which do not have bubbles are not accounted' else open (LAG_VOID_ID, FILE=trim(file_loc), form='formatted', position='append') end if @@ -1756,6 +1813,9 @@ contains end subroutine s_open_void_evol + !> Subroutine that writes some useful statistics related to the volume fraction of the particles (void fraction) in the + !! computational domain on each time step. + !! @param qtime Current time impure subroutine s_write_void_evol(qtime) real(wp), intent(in) :: qtime @@ -1806,13 +1866,14 @@ contains end subroutine s_write_void_evol - !> Write restart files for the Lagrangian bubble solver subroutine s_close_void_evol if (proc_rank == 0) close (LAG_VOID_ID) end subroutine s_close_void_evol + !> Subroutine that writes the restarting files for the particles in the lagrangian solver. + !! @param t_step Current time step impure subroutine s_write_restart_lag_bubbles(t_step) ! Generic string used to store the address of a particular file @@ -1829,8 +1890,7 @@ contains integer(KIND=MPI_OFFSET_KIND) :: disp integer :: view integer, dimension(2) :: gsizes, lsizes, start_idx_part - integer, dimension(num_procs) :: part_order, part_ord_mpi - integer, dimension(num_procs) :: proc_bubble_counts + integer, allocatable :: proc_bubble_counts(:) real(wp), dimension(1:1,1:lag_io_vars) :: dummy dummy = 0._wp @@ -1845,6 +1905,8 @@ contains if (.not. parallel_io) return + allocate (proc_bubble_counts(num_procs)) + lsizes(1) = bub_id lsizes(2) = lag_io_vars @@ -1892,22 +1954,25 @@ contains if (bub_id > 0) then allocate (MPI_IO_DATA_lag_bubbles(max(1, bub_id),1:lag_io_vars)) + i = 0 do k = 1, n_el_bubs_loc - MPI_IO_DATA_lag_bubbles(k, 1) = real(lag_id(k, 1)) - MPI_IO_DATA_lag_bubbles(k,2:4) = mtn_pos(k,1:3,1) - MPI_IO_DATA_lag_bubbles(k,5:7) = mtn_posPrev(k,1:3,1) - MPI_IO_DATA_lag_bubbles(k,8:10) = mtn_vel(k,1:3,1) - MPI_IO_DATA_lag_bubbles(k, 11) = intfc_rad(k, 1) - MPI_IO_DATA_lag_bubbles(k, 12) = intfc_vel(k, 1) - MPI_IO_DATA_lag_bubbles(k, 13) = bub_R0(k) - MPI_IO_DATA_lag_bubbles(k, 14) = Rmax_stats(k) - MPI_IO_DATA_lag_bubbles(k, 15) = Rmin_stats(k) - MPI_IO_DATA_lag_bubbles(k, 16) = bub_dphidt(k) - MPI_IO_DATA_lag_bubbles(k, 17) = gas_p(k, 1) - MPI_IO_DATA_lag_bubbles(k, 18) = gas_mv(k, 1) - MPI_IO_DATA_lag_bubbles(k, 19) = gas_mg(k) - MPI_IO_DATA_lag_bubbles(k, 20) = gas_betaT(k) - MPI_IO_DATA_lag_bubbles(k, 21) = gas_betaC(k) + if (.not. particle_in_domain_physical(mtn_pos(k,1:3,1))) cycle + i = i + 1 + MPI_IO_DATA_lag_bubbles(i, 1) = real(lag_id(k, 1)) + MPI_IO_DATA_lag_bubbles(i,2:4) = mtn_pos(k,1:3,1) + MPI_IO_DATA_lag_bubbles(i,5:7) = mtn_posPrev(k,1:3,1) + MPI_IO_DATA_lag_bubbles(i,8:10) = mtn_vel(k,1:3,1) + MPI_IO_DATA_lag_bubbles(i, 11) = intfc_rad(k, 1) + MPI_IO_DATA_lag_bubbles(i, 12) = intfc_vel(k, 1) + MPI_IO_DATA_lag_bubbles(i, 13) = bub_R0(k) + MPI_IO_DATA_lag_bubbles(i, 14) = Rmax_stats(k) + MPI_IO_DATA_lag_bubbles(i, 15) = Rmin_stats(k) + MPI_IO_DATA_lag_bubbles(i, 16) = bub_dphidt(k) + MPI_IO_DATA_lag_bubbles(i, 17) = gas_p(k, 1) + MPI_IO_DATA_lag_bubbles(i, 18) = gas_mv(k, 1) + MPI_IO_DATA_lag_bubbles(i, 19) = gas_mg(k) + MPI_IO_DATA_lag_bubbles(i, 20) = gas_betaT(k) + MPI_IO_DATA_lag_bubbles(i, 21) = gas_betaC(k) end do call MPI_TYPE_CREATE_SUBARRAY(2, gsizes, lsizes, start_idx_part, MPI_ORDER_FORTRAN, mpi_p, view, ierr) @@ -1940,11 +2005,13 @@ contains call MPI_FILE_CLOSE(ifile, ierr) end if + + deallocate (proc_bubble_counts) #endif end subroutine s_write_restart_lag_bubbles - !> Compute the maximum and minimum radius of each bubble + !> This procedure calculates the maximum and minimum radius of each bubble. subroutine s_calculate_lag_bubble_stats() integer :: k @@ -1961,7 +2028,6 @@ contains end subroutine s_calculate_lag_bubble_stats - !> Write the maximum and minimum radius statistics for each bubble impure subroutine s_open_lag_bubble_stats() character(LEN=path_len + 2*name_len) :: file_loc @@ -1987,6 +2053,7 @@ contains end subroutine s_open_lag_bubble_stats + !> Subroutine that writes the maximum and minimum radius of each bubble. impure subroutine s_write_lag_bubble_stats() integer :: k @@ -2008,14 +2075,14 @@ contains end subroutine s_write_lag_bubble_stats - !> Remove a specific Lagrangian bubble when dt becomes too small - !> Finalize the Lagrangian bubble solver subroutine s_close_lag_bubble_stats close (LAG_STATS_ID) end subroutine s_close_lag_bubble_stats + !> The purpose of this subroutine is to remove one specific particle if dt is too small. + !! @param bub_id Particle id impure subroutine s_copy_lag_bubble(dest, src) integer, intent(in) :: src, dest @@ -2045,6 +2112,7 @@ contains end subroutine s_copy_lag_bubble + !> The purpose of this subroutine is to deallocate variables impure subroutine s_finalize_lagrangian_solver() integer :: i diff --git a/src/simulation/m_global_parameters.fpp b/src/simulation/m_global_parameters.fpp index 98b3b44d0d..2942fbe4cc 100644 --- a/src/simulation/m_global_parameters.fpp +++ b/src/simulation/m_global_parameters.fpp @@ -715,6 +715,10 @@ contains ! Subgrid particle parameters particle_pp%rho0ref_particle = dflt_real particle_pp%cp_particle = dflt_real + particle_pp%ksp_col = dflt_real + particle_pp%nu_col = dflt_real + particle_pp%E_col = dflt_real + particle_pp%cor_col = dflt_real ! Tait EOS rhoref = dflt_real @@ -862,6 +866,8 @@ contains lag_params%added_mass_model = dflt_int lag_params%interpolation_order = dflt_int lag_params%collision_force = .false. + lag_params%qs_fluct_force = .false. + lag_params%mu_ref = dflt_real moving_lag_bubbles = .false. lag_vel_model = dflt_int @@ -1222,8 +1228,8 @@ contains beta_vars(1:3) = [1, 2, 5] $:GPU_UPDATE(device='[beta_vars]') else if (particles_lagrange) then - @:ALLOCATE(beta_vars(1:8)) - beta_vars(1:8) = [1, 2, 3, 4, 5, 6, 7, 8] + @:ALLOCATE(beta_vars(1:7)) + beta_vars(1:7) = [1, 2, 3, 4, 5, 6, 7] $:GPU_UPDATE(device='[beta_vars]') end if diff --git a/src/simulation/m_mpi_proxy.fpp b/src/simulation/m_mpi_proxy.fpp index d2415bb45c..bffebf079d 100644 --- a/src/simulation/m_mpi_proxy.fpp +++ b/src/simulation/m_mpi_proxy.fpp @@ -113,8 +113,8 @@ contains #ifdef MFC_MPI call MPI_Pack_size(1, mpi_p, MPI_COMM_WORLD, real_size, ierr) call MPI_Pack_size(1, MPI_INTEGER, MPI_COMM_WORLD, int_size, ierr) - nReal = 7 + 13*2 + 7*lag_num_ts - p_var_size = (nReal*real_size + int_size) + nReal = 10 + 13*2 + 7*lag_num_ts + p_var_size = (nReal*real_size + 2*int_size) p_buff_size = lag_params%nParticles_glb*p_var_size @:ALLOCATE(p_send_buff(0:p_buff_size), p_recv_buff(0:p_buff_size)) @:ALLOCATE(p_send_ids(nidx(1)%beg:nidx(1)%end, nidx(2)%beg:nidx(2)%end, nidx(3)%beg:nidx(3)%end, & @@ -220,7 +220,7 @@ contains if (particles_lagrange) then #:for VAR in [ 'heatTransfer_model', 'massTransfer_model', 'pressure_corrector', & & 'write_bubbles', 'write_bubbles_stats', 'write_void_evol', 'pressure_force', & - & 'gravity_force', 'collision_force'] + & 'gravity_force', 'collision_force', 'qs_fluct_force'] call MPI_BCAST(lag_params%${VAR}$, 1, MPI_LOGICAL, 0, MPI_COMM_WORLD, ierr) #:endfor @@ -229,7 +229,7 @@ contains call MPI_BCAST(lag_params%${VAR}$, 1, MPI_INTEGER, 0, MPI_COMM_WORLD, ierr) #:endfor - #:for VAR in ['epsilonb','charwidth','valmaxvoid'] + #:for VAR in ['epsilonb','charwidth','valmaxvoid','mu_ref'] call MPI_BCAST(lag_params%${VAR}$, 1, mpi_p, 0, MPI_COMM_WORLD, ierr) #:endfor @@ -292,7 +292,7 @@ contains end if if (particles_lagrange) then - #:for VAR in [ 'rho0ref_particle','cp_particle'] + #:for VAR in [ 'rho0ref_particle','cp_particle','ksp_col','nu_col','E_col','cor_col'] call MPI_BCAST(particle_pp%${VAR}$, 1, mpi_p, 0, MPI_COMM_WORLD, ierr) #:endfor end if @@ -989,12 +989,14 @@ contains !! @param dvel Time derivative of velocity of each particle !! @param lag_num_ts Number of stages in time-stepping scheme !! @param nParticles Local number of particles - impure subroutine s_mpi_sendrecv_solid_particles(p_owner_rank, particle_R0, Rmax_stats, Rmin_stats, particle_mass, f_p, & - & lag_id, rad, pos, posPrev, vel, scoord, drad, dpos, dvel, lag_num_ts, nParticles, dest) + impure subroutine s_mpi_sendrecv_solid_particles(p_owner_rank, particle_R0, Rmax_stats, Rmin_stats, particle_mass, & + & particle_seed, f_p, fqs_fluct, lag_id, rad, pos, posPrev, vel, scoord, drad, dpos, dvel, lag_num_ts, nParticles, dest) integer, dimension(:) :: p_owner_rank real(wp), dimension(:) :: particle_R0, Rmax_stats, Rmin_stats, particle_mass + integer, dimension(:) :: particle_seed real(wp), dimension(:,:) :: f_p + real(wp), dimension(:,:) :: fqs_fluct integer, dimension(:,:) :: lag_id real(wp), dimension(:,:) :: rad, drad real(wp), dimension(:,:,:) :: pos, posPrev, vel, scoord, dpos, dvel @@ -1092,8 +1094,12 @@ contains & MPI_COMM_WORLD, ierr) call MPI_Pack(particle_mass(particle_id), 1, mpi_p, p_send_buff(send_offset), p_buff_size, position, & & MPI_COMM_WORLD, ierr) + call MPI_Pack(particle_seed(particle_id), 1, MPI_INTEGER, p_send_buff(send_offset), p_buff_size, position, & + & MPI_COMM_WORLD, ierr) call MPI_Pack(f_p(particle_id,:), 3, mpi_p, p_send_buff(send_offset), p_buff_size, position, MPI_COMM_WORLD, & & ierr) + call MPI_Pack(fqs_fluct(particle_id,:), 3, mpi_p, p_send_buff(send_offset), p_buff_size, position, & + & MPI_COMM_WORLD, ierr) do r = 1, 2 call MPI_Pack(rad(particle_id, r), 1, mpi_p, p_send_buff(send_offset), p_buff_size, position, & & MPI_COMM_WORLD, ierr) @@ -1143,7 +1149,6 @@ contains particle_id = nParticles p_owner_rank(particle_id) = neighbor_ranks(i, j, k) - call MPI_Unpack(p_recv_buff(recv_offset), p_recv_size, position, lag_id(particle_id, 1), 1, MPI_INTEGER, & & MPI_COMM_WORLD, ierr) call MPI_Unpack(p_recv_buff(recv_offset), p_recv_size, position, particle_R0(particle_id), 1, mpi_p, & @@ -1154,8 +1159,12 @@ contains & MPI_COMM_WORLD, ierr) call MPI_Unpack(p_recv_buff(recv_offset), p_recv_size, position, particle_mass(particle_id), 1, mpi_p, & & MPI_COMM_WORLD, ierr) + call MPI_Unpack(p_recv_buff(recv_offset), p_recv_size, position, particle_seed(particle_id), 1, MPI_INTEGER, & + & MPI_COMM_WORLD, ierr) call MPI_Unpack(p_recv_buff(recv_offset), p_recv_size, position, f_p(particle_id,:), 3, mpi_p, & & MPI_COMM_WORLD, ierr) + call MPI_Unpack(p_recv_buff(recv_offset), p_recv_size, position, fqs_fluct(particle_id,:), 3, mpi_p, & + & MPI_COMM_WORLD, ierr) do r = 1, 2 call MPI_Unpack(p_recv_buff(recv_offset), p_recv_size, position, rad(particle_id, r), 1, mpi_p, & & MPI_COMM_WORLD, ierr) @@ -1194,150 +1203,6 @@ contains end subroutine s_mpi_sendrecv_solid_particles - !> This resets the collision force buffers - impure subroutine s_reset_force_buffers() - - force_send_counts = 0 - force_recv_counts = 0 - force_send_ids = 0 - force_send_vals = 0._wp - - $:GPU_UPDATE(device='[force_send_counts, force_send_ids, force_send_vals]') - - end subroutine s_reset_force_buffers - - !> This adds the forces to the buffer arrays for mpi transfer - impure subroutine s_add_force_to_send_buffer(dest_rank, gid, force) - - $:GPU_ROUTINE(function_name='s_add_force_to_send_buffer', parallelism='[seq]') - - integer, intent(in) :: dest_rank, gid - real(wp), intent(in), dimension(3) :: force - integer :: idx - - $:GPU_ATOMIC(atomic='capture') - force_send_counts(dest_rank) = force_send_counts(dest_rank) + 1 - idx = force_send_counts(dest_rank) - $:END_GPU_ATOMIC_CAPTURE() - - force_send_ids(dest_rank, idx) = gid - force_send_vals(dest_rank, idx, 1) = force(1) - force_send_vals(dest_rank, idx, 2) = force(2) - force_send_vals(dest_rank, idx, 3) = force(3) - - end subroutine s_add_force_to_send_buffer - - !> This communicates the collision forces across neighbor mpi ranks - impure subroutine s_transfer_collision_forces(total_recv, force_recv_ids, force_recv_vals) - - integer, intent(inout) :: total_recv - integer, intent(inout) :: force_recv_ids(:) - real(wp), intent(inout) :: force_recv_vals(:) - -#ifdef MFC_MPI - integer :: ierr !< Generic flag used to identify and report MPI errors - integer :: i, j, k, l, idx, total_send, recv_tag, send_tag, partner, recv_count, send_count - integer :: send_displs(0:num_procs - 1), recv_displs(0:num_procs - 1) - integer :: sendcounts_vals(0:num_procs - 1), recvcounts_vals(0:num_procs - 1) - integer :: senddispls_vals(0:num_procs - 1), recvdispls_vals(0:num_procs - 1) - ! Local request arrays sized for 2 requests per neighbor (IDs + values) - integer :: coll_send_requests(2*MAX_NEIGHBORS), coll_recv_requests(2*MAX_NEIGHBORS) - - $:GPU_UPDATE(host='[force_send_counts, force_send_ids, force_send_vals]') - - ! Phase 1: Exchange force counts with neighbors only - send_count = 0 - recv_count = 0 - - do l = 1, n_neighbors - i = neighbor_list(l, 1) - j = neighbor_list(l, 2) - k = neighbor_list(l, 3) - partner = neighbor_ranks(i, j, k) - recv_tag = neighbor_tag(i, j, k) - send_tag = neighbor_tag(-i, -j, -k) - - recv_count = recv_count + 1 - call MPI_Irecv(force_recv_counts(partner), 1, MPI_INTEGER, partner, recv_tag, MPI_COMM_WORLD, & - & recv_requests(recv_count), ierr) - - send_count = send_count + 1 - call MPI_Isend(force_send_counts(partner), 1, MPI_INTEGER, partner, send_tag, MPI_COMM_WORLD, & - & send_requests(send_count), ierr) - end do - - call MPI_Waitall(recv_count, recv_requests(1:recv_count), MPI_STATUSES_IGNORE, ierr) - call MPI_Waitall(send_count, send_requests(1:send_count), MPI_STATUSES_IGNORE, ierr) - - ! Compute displacements - send_displs(0) = 0 - recv_displs(0) = 0 - do i = 1, num_procs - 1 - send_displs(i) = send_displs(i - 1) + force_send_counts(i - 1) - recv_displs(i) = recv_displs(i - 1) + force_recv_counts(i - 1) - end do - - do i = 0, num_procs - 1 - sendcounts_vals(i) = 3*force_send_counts(i) - recvcounts_vals(i) = 3*force_recv_counts(i) - senddispls_vals(i) = 3*send_displs(i) - recvdispls_vals(i) = 3*recv_displs(i) - end do - - total_send = sum(force_send_counts) - total_recv = sum(force_recv_counts) - - ! Flatten send buffers - idx = 1 - do i = 0, num_procs - 1 - do j = 1, force_send_counts(i) - flat_send_ids(idx) = force_send_ids(i, j) - flat_send_vals(3*(idx - 1) + 1) = force_send_vals(i, j, 1) - flat_send_vals(3*(idx - 1) + 2) = force_send_vals(i, j, 2) - flat_send_vals(3*(idx - 1) + 3) = force_send_vals(i, j, 3) - idx = idx + 1 - end do - end do - - ! Phase 2: Exchange force data with neighbors only - send_count = 0 - recv_count = 0 - - do l = 1, n_neighbors - i = neighbor_list(l, 1) - j = neighbor_list(l, 2) - k = neighbor_list(l, 3) - partner = neighbor_ranks(i, j, k) - recv_tag = neighbor_tag(i, j, k) - send_tag = neighbor_tag(-i, -j, -k) - - if (force_recv_counts(partner) > 0) then - recv_count = recv_count + 1 - call MPI_Irecv(force_recv_ids(recv_displs(partner) + 1), force_recv_counts(partner), MPI_INTEGER, partner, & - & recv_tag, MPI_COMM_WORLD, coll_recv_requests(recv_count), ierr) - recv_count = recv_count + 1 - call MPI_Irecv(force_recv_vals(recvdispls_vals(partner) + 1), recvcounts_vals(partner), mpi_p, partner, & - & recv_tag + 1, MPI_COMM_WORLD, coll_recv_requests(recv_count), ierr) - end if - - if (force_send_counts(partner) > 0) then - send_count = send_count + 1 - call MPI_Isend(flat_send_ids(send_displs(partner) + 1), force_send_counts(partner), MPI_INTEGER, partner, & - & send_tag, MPI_COMM_WORLD, coll_send_requests(send_count), ierr) - send_count = send_count + 1 - call MPI_Isend(flat_send_vals(senddispls_vals(partner) + 1), sendcounts_vals(partner), mpi_p, partner, & - & send_tag + 1, MPI_COMM_WORLD, coll_send_requests(send_count), ierr) - end if - end do - - call MPI_Waitall(recv_count, coll_recv_requests(1:recv_count), MPI_STATUSES_IGNORE, ierr) - call MPI_Waitall(send_count, coll_send_requests(1:send_count), MPI_STATUSES_IGNORE, ierr) -#else - total_recv = 0 -#endif - - end subroutine s_transfer_collision_forces - !! @param i, j, k Indices of the neighbor in the range [-1, 1] !! @return tag Unique integer tag for the neighbor integer function neighbor_tag(i, j, k) result(tag) diff --git a/src/simulation/m_particles_EL.fpp b/src/simulation/m_particles_EL.fpp index 1674f07c6f..5dfed3af01 100644 --- a/src/simulation/m_particles_EL.fpp +++ b/src/simulation/m_particles_EL.fpp @@ -38,6 +38,9 @@ module m_particles_EL real(wp), allocatable, dimension(:) :: p_AM !< Particle Added Mass $:GPU_DECLARE(create='[p_AM]') + integer, allocatable, dimension(:) :: particle_seed !< Particle Seed for random number + $:GPU_DECLARE(create='[particle_seed]') + integer, allocatable, dimension(:) :: p_owner_rank !< MPI rank that owns this particle $:GPU_DECLARE(create='[p_owner_rank]') @@ -72,15 +75,19 @@ module m_particles_EL real(wp) :: Rmax_glb, Rmin_glb !< Global maximum and minimum R/R0 ratio across all particles !> Eulerian projection of particle data (volume fraction, momentum, sources) type(scalar_field), dimension(:), allocatable :: q_particles - integer :: q_particles_idx !< Size of the q vector field for particle cell (q)uantities + type(scalar_field), dimension(:), allocatable :: kahan_comp !< Kahan compensation for q_particles accumulation + integer :: q_particles_idx !< Size of the q vector field for particle cell (q)uantities integer, parameter :: alphaf_id = 1 - integer, parameter :: alphaupx_id = 2 !< x particle momentum index - integer, parameter :: alphaupy_id = 3 !< y particle momentum index - integer, parameter :: alphaupz_id = 4 !< z particle momentum index - integer, parameter :: Smx_id = 5 - integer, parameter :: Smy_id = 6 - integer, parameter :: Smz_id = 7 - integer, parameter :: SE_id = 8 + integer, parameter :: alphaupx_id = 2 !< x particle momentum index + integer, parameter :: alphaupy_id = 3 !< y particle momentum index + integer, parameter :: alphaupz_id = 4 !< z particle momentum index + integer, parameter :: alphaup2x_id = 5 !< x particle velocity squared index + integer, parameter :: alphaup2y_id = 6 !< y particle velocity squared index + integer, parameter :: alphaup2z_id = 7 !< z particle velocity squared index + integer, parameter :: Smx_id = 8 + integer, parameter :: Smy_id = 9 + integer, parameter :: Smz_id = 10 + integer, parameter :: SE_id = 11 !> Interpolated Eulerian field gradients at particle locations type(scalar_field), dimension(:), allocatable :: field_vars !< For cell quantities (field gradients, etc.) @@ -90,26 +97,38 @@ module m_particles_EL integer, parameter :: drhox_id = 4 !< Spatial density gradient in x, y, and z integer, parameter :: drhoy_id = 5 integer, parameter :: drhoz_id = 6 - integer, parameter :: dufx_id = 7 !< Spatial velocity gradient in x, y, and z - integer, parameter :: dufy_id = 8 - integer, parameter :: dufz_id = 9 - integer, parameter :: dalphafx_id = 10 !< Spatial fluid volume fraction gradient in x, y, and z - integer, parameter :: dalphafy_id = 11 - integer, parameter :: dalphafz_id = 12 - integer, parameter :: dalphap_upx_id = 13 !< Spatial particle momentum gradient in x, y, and z - integer, parameter :: dalphap_upy_id = 14 - integer, parameter :: dalphap_upz_id = 15 - integer, parameter :: nField_vars = 15 - type(scalar_field), dimension(:), allocatable :: weights_x_interp !< For precomputing weights - type(scalar_field), dimension(:), allocatable :: weights_y_interp !< For precomputing weights - type(scalar_field), dimension(:), allocatable :: weights_z_interp !< For precomputing weights + integer, parameter :: dufxdx_id = 7 ! du_x/dx + integer, parameter :: dufxdy_id = 8 ! du_x/dy + integer, parameter :: dufxdz_id = 9 ! du_x/dz + integer, parameter :: dufydx_id = 10 ! du_y/dx + integer, parameter :: dufydy_id = 11 ! du_y/dy + integer, parameter :: dufydz_id = 12 ! du_y/dz + integer, parameter :: dufzdx_id = 13 ! du_z/dx + integer, parameter :: dufzdy_id = 14 ! du_z/dy + integer, parameter :: dufzdz_id = 15 ! du_z/dz + integer, parameter :: dalphafx_id = 16 !< Spatial fluid volume fraction gradient in x, y, and z + integer, parameter :: dalphafy_id = 17 + integer, parameter :: dalphafz_id = 18 + integer, parameter :: dalphap_upx_id = 19 !< Spatial particle momentum gradient in x, y, and z + integer, parameter :: dalphap_upy_id = 20 + integer, parameter :: dalphap_upz_id = 21 + integer, parameter :: nField_vars = 21 + + ! duidxj_id(i,j) gives the field_vars index for du_i/dx_j + integer, parameter :: duidxj_id(3, 3) = reshape([dufxdx_id, dufydx_id, dufzdx_id, dufxdy_id, dufydy_id, dufzdy_id, dufxdz_id, & + & dufydz_id, dufzdz_id], [3, 3]) + + type(scalar_field), dimension(:), allocatable :: rhs_old !< For previous rhs values + type(scalar_field), dimension(:), allocatable :: weights_x_interp !< For precomputing weights + type(scalar_field), dimension(:), allocatable :: weights_y_interp !< For precomputing weights + type(scalar_field), dimension(:), allocatable :: weights_z_interp !< For precomputing weights integer :: nWeights_interp - type(scalar_field), dimension(:), allocatable :: weights_x_grad !< For precomputing weights - type(scalar_field), dimension(:), allocatable :: weights_y_grad !< For precomputing weights - type(scalar_field), dimension(:), allocatable :: weights_z_grad !< For precomputing weights + type(scalar_field), dimension(:), allocatable :: weights_x_grad !< For precomputing weights + type(scalar_field), dimension(:), allocatable :: weights_y_grad !< For precomputing weights + type(scalar_field), dimension(:), allocatable :: weights_z_grad !< For precomputing weights integer :: nWeights_grad - $:GPU_DECLARE(create='[Rmax_glb, Rmin_glb, q_particles, q_particles_idx, field_vars]') + $:GPU_DECLARE(create='[Rmax_glb, Rmin_glb, q_particles, kahan_comp, q_particles_idx, field_vars, rhs_old]') $:GPU_DECLARE(create='[weights_x_interp, weights_y_interp, weights_z_interp, nWeights_interp]') $:GPU_DECLARE(create='[weights_x_grad, weights_y_grad, weights_z_grad, nWeights_grad]') @@ -117,9 +136,15 @@ module m_particles_EL real(wp), allocatable, dimension(:,:) :: f_p !< force on each particle $:GPU_DECLARE(create='[f_p]') + real(wp), allocatable, dimension(:,:) :: fqs_fluct !< QS fluctuation force on each particle + $:GPU_DECLARE(create='[fqs_fluct]') + real(wp), allocatable, dimension(:) :: gSum !< gaussian sum for each particle $:GPU_DECLARE(create='[gSum]') + real(wp), allocatable, dimension(:) :: gSum_sources !< gaussian sum for each particle + $:GPU_DECLARE(create='[gSum_sources]') + integer, allocatable :: force_recv_ids(:) !< ids of collision forces received from other ranks real(wp), allocatable :: force_recv_vals(:) !< collision forces received from other ranks $:GPU_DECLARE(create='[force_recv_ids, force_recv_vals]') @@ -155,12 +180,7 @@ contains real(wp) :: rhoYks(1:num_species) integer :: save_count real(wp) :: qtime - real(wp) :: myR, func_sum - real(wp), dimension(3) :: myPos, myVel, myForce - integer, dimension(3) :: cell - logical :: only_beta - - only_beta = .true. + integer :: ind_end_loc next_write_time = 0._wp @@ -182,10 +202,10 @@ contains ! Allocate space for the Eulerian fields needed to map the effect of the particles if (lag_params%solver_approach == 1) then ! One-way coupling - q_particles_idx = 1 ! For tracking volume fraction + q_particles_idx = 7 ! For tracking volume fraction, alpha_p u_p (x(2),y(3),z(4)), alpha_p u_p^2 (x(5),y(6),z(7)) else if (lag_params%solver_approach == 2) then ! Two-way coupling - q_particles_idx = 8 ! For tracking volume fraction(1), x-mom(2), y-mom(3), z-mom(4), and energy(5) sources, and alpha_p u_p (x(6),y(7),z(8)) + q_particles_idx = 11 ! For tracking volume fraction(1), alpha_p u_p (x(2),y(3),z(4)), alpha_p u_p^2 (x(5),y(6),z(7)), x-mom(8), y-mom(9), z-mom(10), and energy(11) sources else call s_mpi_abort('Please check the lag_params%solver_approach input') end if @@ -224,10 +244,14 @@ contains $:GPU_UPDATE(device='[lag_num_ts, q_particles_idx]') @:ALLOCATE(q_particles(1:q_particles_idx)) + @:ALLOCATE(kahan_comp(1:q_particles_idx)) do i = 1, q_particles_idx @:ALLOCATE(q_particles(i)%sf(idwbuff(1)%beg:idwbuff(1)%end, idwbuff(2)%beg:idwbuff(2)%end, & & idwbuff(3)%beg:idwbuff(3)%end)) @:ACC_SETUP_SFs(q_particles(i)) + @:ALLOCATE(kahan_comp(i)%sf(idwbuff(1)%beg:idwbuff(1)%end, idwbuff(2)%beg:idwbuff(2)%end, & + & idwbuff(3)%beg:idwbuff(3)%end)) + @:ACC_SETUP_SFs(kahan_comp(i)) end do @:ALLOCATE(field_vars(1:nField_vars)) @@ -237,6 +261,12 @@ contains @:ACC_SETUP_SFs(field_vars(i)) end do + @:ALLOCATE(rhs_old(1:sys_size)) + do i = 1, sys_size + @:ALLOCATE(rhs_old(i)%sf(idwint(1)%beg:idwint(1)%end, idwint(2)%beg:idwint(2)%end, idwint(3)%beg:idwint(3)%end)) + @:ACC_SETUP_SFs(rhs_old(i)) + end do + @:ALLOCATE(weights_x_interp(1:nWeights_interp)) do i = 1, nWeights_interp @:ALLOCATE(weights_x_interp(i)%sf(idwbuff(1)%beg:idwbuff(1)%end,1:1,1:1)) @@ -282,6 +312,7 @@ contains @:ALLOCATE(Rmax_stats_part(1:nParticles_glb)) @:ALLOCATE(Rmin_stats_part(1:nParticles_glb)) @:ALLOCATE(particle_mass(1:nParticles_glb)) + @:ALLOCATE(particle_seed(1:nParticles_glb)) @:ALLOCATE(p_AM(1:nParticles_glb)) @:ALLOCATE(p_owner_rank(1:nParticles_glb)) @:ALLOCATE(particle_rad(1:nParticles_glb, 1:2)) @@ -293,7 +324,9 @@ contains @:ALLOCATE(particle_dposdt(1:nParticles_glb, 1:3, 1:lag_num_ts)) @:ALLOCATE(particle_dveldt(1:nParticles_glb, 1:3, 1:lag_num_ts)) @:ALLOCATE(f_p(1:nParticles_glb, 1:3)) + @:ALLOCATE(fqs_fluct(1:nParticles_glb, 1:3)) @:ALLOCATE(gSum(1:nParticles_glb)) + @:ALLOCATE(gSum_sources(1:nParticles_glb)) @:ALLOCATE(linked_list(1:nParticles_glb)) @@ -324,33 +357,21 @@ contains $:GPU_UPDATE(device='[moving_lag_particles, lag_pressure_force, lag_gravity_force, lag_vel_model, lag_drag_model]') - ! Allocate cell list arrays for atomic-free Gaussian smearing - @:ALLOCATE(cell_list_start(0:m, 0:n, 0:p)) - @:ALLOCATE(cell_list_count(0:m, 0:n, 0:p)) - @:ALLOCATE(cell_list_idx(1:lag_params%nParticles_glb)) - call s_read_input_particles(q_cons_vf, bc_type) - call s_reset_cell_vars() - - $:GPU_PARALLEL_LOOP(private='[k, cell, myR, myPos, myVel, myForce, func_sum]',copyin='[only_beta]') - do k = 1, n_el_particles_loc - cell = fd_number - buff_size - call s_locate_cell(particle_pos(k,1:3,1), cell, particle_s(k,1:3,1)) - - myR = particle_R0(k) - myPos = particle_pos(k,1:3,1) - myVel = particle_vel(k,1:3,1) - myForce = f_p(k,:) - ! Compute the total gaussian contribution for each particle for normalization - call s_compute_gaussian_contribution(myR, myPos, cell, func_sum) - gSum(k) = func_sum + if (lag_params%qs_fluct_force) then + ind_end_loc = alphaup2z_id + else if (lag_params%solver_approach == 2) then + ind_end_loc = alphaupz_id + else + ind_end_loc = alphaf_id + end if - call s_gaussian_atomic(myR, myVel, myPos, myForce, func_sum, cell, q_particles, only_beta) - end do - $:END_GPU_PARALLEL_LOOP() + call s_smear_field_contributions(bc_type, alphaf_id, ind_end_loc, .true.) - call s_finalize_beta_field(bc_type, only_beta) + if (lag_params%solver_approach == 2) then + call s_compute_gaussian_source_contribution() + end if npts = (nWeights_interp - 1)/2 call s_compute_barycentric_weights(npts) ! For interpolation @@ -388,6 +409,10 @@ contains & pi_inf, gamma, alpharho, qv, rhoYks, pres, T) q_cons_vf(E_idx)%sf(i, j, k) = gamma*pres + dyn_pres + pi_inf + qv ! Updating energy in cons + + do l = 1, sys_size + rhs_old(l)%sf(i, j, k) = 0._wp + end do end do end do end do @@ -440,7 +465,7 @@ contains end if if (indomain) then particle_id = particle_id + 1 - call s_add_particles(inputParticle, q_cons_vf, particle_id) + call s_add_particles(inputParticle, q_cons_vf, particle_id, id) lag_part_id(particle_id, 1) = id ! global ID lag_part_id(particle_id, 2) = particle_id ! local ID n_el_particles_loc = particle_id ! local number of particles @@ -469,9 +494,9 @@ contains $:GPU_UPDATE(device='[particles_lagrange, lag_params]') - $:GPU_UPDATE(device='[lag_part_id, particle_R0, Rmax_stats_part, Rmin_stats_part, particle_mass, f_p, p_AM, p_owner_rank, & - & gid_to_local, particle_rad, particle_pos, particle_posPrev, particle_vel, particle_s, particle_draddt, & - & particle_dposdt, particle_dveldt, n_el_particles_loc]') + $:GPU_UPDATE(device='[lag_part_id, particle_R0, Rmax_stats_part, Rmin_stats_part, particle_mass, particle_seed, f_p, & + & fqs_fluct, p_AM, p_owner_rank, gid_to_local, particle_rad, particle_pos, particle_posPrev, particle_vel, & + & particle_s, particle_draddt, particle_dposdt, particle_dveldt, n_el_particles_loc]') Rmax_glb = min(dflt_real, -dflt_real) Rmin_glb = max(dflt_real, -dflt_real) @@ -502,11 +527,11 @@ contains !! @param inputPart Particle information !! @param q_cons_vf Conservative variables !! @param part_id Local id of the particle - impure subroutine s_add_particles(inputPart, q_cons_vf, part_id) + impure subroutine s_add_particles(inputPart, q_cons_vf, part_id, glb_part_id) type(scalar_field), dimension(sys_size), intent(in) :: q_cons_vf real(wp), dimension(8), intent(in) :: inputPart - integer, intent(in) :: part_id + integer, intent(in) :: part_id, glb_part_id integer :: i real(wp) :: pliq, volparticle, concvap, totalmass, kparticle, cpparticle real(wp) :: omegaN_local, PeG, PeT, rhol, pcrit, qv, gamma, pi_inf, dynP @@ -530,6 +555,7 @@ contains ! Initialize Particle Sources f_p(part_id,1:3) = 0._wp + fqs_fluct(part_id,1:3) = 0._wp p_AM(part_id) = 0._wp p_owner_rank(part_id) = proc_rank gid_to_local(part_id) = -1 @@ -568,6 +594,8 @@ contains call s_mpi_abort("The initial particle mass is negative or zero. Check the particle file.") end if + particle_seed(part_id) = glb_part_id*1103515245 + 12345 + end subroutine s_add_particles !> Read particle data from a restart checkpoint @@ -727,30 +755,38 @@ contains !! @param rhs_vf Calculated change of conservative variables !! @param t_step Current time step !! @param stage Current stage in the time-stepper algorithm - subroutine s_compute_particle_EL_dynamics(q_prim_vf, bc_type, stage, vL_x, vL_y, vL_z, vR_x, vR_y, vR_z, rhs_vf) + subroutine s_compute_particle_EL_dynamics(q_cons_vf, q_prim_vf, bc_type, stage, vL_x, vL_y, vL_z, vR_x, vR_y, vR_z, rhs_vf) + type(scalar_field), dimension(sys_size), intent(in) :: q_cons_vf type(scalar_field), dimension(sys_size), intent(in) :: q_prim_vf type(integer_field), dimension(1:num_dims,1:2), intent(in) :: bc_type type(scalar_field), dimension(sys_size), intent(in) :: rhs_vf integer, intent(in) :: stage real(wp), dimension(idwbuff(1)%beg:,idwbuff(2)%beg:,idwbuff(3)%beg:,1:), intent(inout) :: vL_x, vL_y, vL_z real(wp), dimension(idwbuff(1)%beg:,idwbuff(2)%beg:,idwbuff(3)%beg:,1:), intent(inout) :: vR_x, vR_y, vR_z - integer, dimension(3) :: cell, cellijk - real(wp) :: myMass, myR, myBeta_c, myBeta_t, myR0, myRe, mydrhodt, myVolumeFrac, myGamma, rmass_add, func_sum - real(wp), dimension(3) :: myVel, myPos, force_vec, s_cell - logical :: only_beta - integer :: k, l, i, j - - only_beta = .false. + integer, dimension(3) :: cell + real(wp) :: myMass, myR, myBeta_c, myBeta_t, myR0, myRe, myGamma, rmass_add, func_sum, func_sum_sources + real(wp), dimension(3) :: myVel, myPos, force_vec, s_cell, myForce, my_fqs_fluct, new_fqs_fluct + integer :: mySeed, new_seed + integer :: k, l, i, j, dir if (lag_params%pressure_force .or. lag_params%added_mass_model > 0) then do l = 1, num_dims if (l == 1) then call s_gradient_field(vL_x, vR_x, field_vars(dPx_id)%sf, l, E_idx) + do dir = 1, num_dims + call s_gradient_field(vL_x, vR_x, field_vars(duidxj_id(dir, l))%sf, l, momxb + dir - 1) + end do else if (l == 2) then call s_gradient_field(vL_y, vR_y, field_vars(dPy_id)%sf, l, E_idx) + do dir = 1, num_dims + call s_gradient_field(vL_y, vR_y, field_vars(duidxj_id(dir, l))%sf, l, momxb + dir - 1) + end do else if (l == 3) then call s_gradient_field(vL_z, vR_z, field_vars(dPz_id)%sf, l, E_idx) + do dir = 1, num_dims + call s_gradient_field(vL_z, vR_z, field_vars(duidxj_id(dir, l))%sf, l, momxb + dir - 1) + end do end if end do end if @@ -772,14 +808,14 @@ contains myRe = 1._wp/fluid_pp(1)%Re(1) else ! TODO: Wire to a fluid parameter for non-air flows - myRe = 1.845e-5_wp + myRe = lag_params%mu_ref end if call nvtxStartRange("LAGRANGE-PARTICLE-DYNAMICS") !> Compute Fluid-Particle Forces (drag/pressure/added mass) and convert to particle acceleration - $:GPU_PARALLEL_LOOP(private='[i, k, l, cell, s_cell, myMass, myR, myR0, myPos, myVel, myVolumeFrac, force_vec, rmass_add, & - & func_sum, mydrhodt]', copyin='[stage, myGamma, myRe, only_beta]') + $:GPU_PARALLEL_LOOP(private='[i, k, l, cell, s_cell, myMass, myR, myR0, myPos, myVel, mySeed, my_fqs_fluct, & + & new_fqs_fluct, force_vec, rmass_add, func_sum, new_seed]', copyin='[stage, myGamma, myRe]') do k = 1, n_el_particles_loc f_p(k,:) = 0._wp p_owner_rank(k) = proc_rank @@ -796,19 +832,26 @@ contains myR0 = particle_R0(k) myPos = particle_pos(k,:,2) myVel = particle_vel(k,:,2) - myVolumeFrac = 1._wp - q_particles(alphaf_id)%sf(cell(1), cell(2), cell(3)) - mydrhodt = rhs_vf(1)%sf(cell(1), cell(2), cell(3)) + + mySeed = particle_seed(k) + my_fqs_fluct = fqs_fluct(k,:) particle_dposdt(k,:,stage) = 0._wp particle_dveldt(k,:,stage) = 0._wp particle_draddt(k, stage) = 0._wp - call s_get_particle_force(myPos, myR, myVel, myMass, myRe, myGamma, myVolumeFrac, mydrhodt, cell, q_prim_vf, & - & field_vars, weights_x_interp, weights_y_interp, weights_z_interp, force_vec, rmass_add) + call s_get_particle_force(myPos, myR, myVel, myMass, myRe, myGamma, mySeed, my_fqs_fluct, cell, q_prim_vf, q_cons_vf, & + & q_particles, field_vars, rhs_old, duidxj_id, weights_x_interp, weights_y_interp, & + & weights_z_interp, force_vec, rmass_add, new_seed, new_fqs_fluct) p_AM(k) = rMass_add f_p(k,:) = f_p(k,:) + force_vec(:) + if (lag_params%qs_fluct_force) then + particle_seed(k) = new_seed + fqs_fluct(k,:) = new_fqs_fluct + end if + if (.not. lag_params%collision_force) then myMass = particle_mass(k) + p_AM(k) myVel = particle_vel(k,:,2) @@ -818,16 +861,11 @@ contains particle_draddt(k, stage) = 0._wp end do end if - - if (lag_params%solver_approach == 2) then - func_sum = gSum(k) - call s_gaussian_atomic(myR, myVel, myPos, force_vec, func_sum, cell, q_particles, only_beta) - end if end do $:END_GPU_PARALLEL_LOOP() if (lag_params%solver_approach == 2) then - call s_finalize_beta_field(bc_type, only_beta) + call s_smear_field_contributions(bc_type, Smx_id, SE_id, .false.) end if call nvtxStartRange("LAGRANGE-PARTICLE-COLLISIONS") @@ -853,9 +891,91 @@ contains end subroutine s_compute_particle_EL_dynamics + subroutine s_smear_field_contributions(bc_type, ind_start, ind_end, recompute_gSum) + + type(integer_field), dimension(1:num_dims,1:2), intent(in) :: bc_type + integer, intent(in) :: ind_start, ind_end + logical, intent(in) :: recompute_gSum + integer :: i, j, k, l, nVar + real(wp) :: myR, func_sum, func_sum_sources, func_sum_sources_dummy + real(wp), dimension(3) :: myVel, myPos, s_cell, myForce + integer, dimension(3) :: cell + integer, dimension(:), allocatable :: vars_send + + nVar = ind_end - ind_start + 1 + allocate (vars_send(nVar)) + + do i = 1, nVar + vars_send(i) = ind_start + (i - 1) + end do + + $:GPU_PARALLEL_LOOP(private='[i, j, k, l]', collapse=4) + do i = ind_start, ind_end + do l = idwbuff(3)%beg, idwbuff(3)%end + do k = idwbuff(2)%beg, idwbuff(2)%end + do j = idwbuff(1)%beg, idwbuff(1)%end + if (i <= q_particles_idx) then + q_particles(i)%sf(j, k, l) = 0._wp + kahan_comp(i)%sf(j, k, l) = 0._wp + end if + end do + end do + end do + end do + $:END_GPU_PARALLEL_LOOP() + + $:GPU_PARALLEL_LOOP(private='[i, k, cell, s_cell, myR, myPos, myVel, myForce, func_sum, func_sum_sources_dummy]') + do k = 1, n_el_particles_loc + myR = particle_rad(k, 2) + myPos = particle_pos(k,1:3,2) + myVel = particle_vel(k,1:3,2) + myForce = f_p(k,:) + + if (recompute_gSum) then + cell = fd_number - buff_size + call s_locate_cell(particle_pos(k,1:3,2), cell, particle_s(k,1:3,2)) + + ! Compute the total gaussian contribution for each particle for normalization + call s_compute_gaussian_contribution(myR, myPos, cell, func_sum, func_sum_sources_dummy, q_particles) + gSum(k) = func_sum + else + s_cell = particle_s(k,1:3,2) + cell = int(s_cell(:)) + do i = 1, num_dims + if (s_cell(i) < 0._wp) cell(i) = cell(i) - 1 + end do + func_sum = gSum(k) + func_sum_sources = gSum_sources(k) + end if + + call s_gaussian_atomic(myR, myVel, myPos, myForce, func_sum, func_sum_sources, cell, q_particles, kahan_comp, & + & ind_start, ind_end) + end do + + call nvtxStartRange("PARTICLES-LAGRANGE-BETA-COMM") + call s_populate_beta_buffers(q_particles, kahan_comp, bc_type, nVar, vars_send) + call nvtxEndRange + + if (alphaf_id >= ind_start .and. alphaf_id <= ind_end) then + ! Store 1-q_particles(1) + $:GPU_PARALLEL_LOOP(private='[j, k, l]', collapse=3) + do l = idwbuff(3)%beg, idwbuff(3)%end + do k = idwbuff(2)%beg, idwbuff(2)%end + do j = idwbuff(1)%beg, idwbuff(1)%end + q_particles(alphaf_id)%sf(j, k, l) = 1._wp - q_particles(alphaf_id)%sf(j, k, l) + ! Limiting void fraction given max value + q_particles(alphaf_id)%sf(j, k, l) = max(q_particles(alphaf_id)%sf(j, k, l), 1._wp - lag_params%valmaxvoid) + end do + end do + end do + end if + + !!!!!!!!!!!!!!!!!!! + + end subroutine s_smear_field_contributions + !> Compute inter-particle collision forces using a soft-sphere DEM model. Uses a cell-based linked list for O(N) neighbor - !! search. The contact force model is a spring-dashpot (Hertzian stiffness with viscous damping). Forces on particles owned by - !! other MPI ranks are buffered for later transfer. + !! search. The contact force model is a spring-dashpot (Hertzian stiffness with viscous damping). subroutine s_compute_particle_EL_collisions(stage, bc_type) integer, intent(in) :: stage @@ -865,30 +985,32 @@ contains integer, dimension(3) :: cellaux integer :: i, k, l, q, ip, jp, kp, ii, jj, kk logical :: celloutside - real(wp) :: pidtksp2, ksp, nu1, nu2, Rp1, Rp2, E1, E2, Estar, cor, rmag, Rstar, dij, eta_n, kappa_n, mp1, mp2, dt_loc + real(wp) :: pidtksp2, pidtksp2_wall, ksp, ksp_wall, nu1, nu2, Rp1, Rp2, E1, E2, Estar, cor, rmag, Rstar, dij, eta_n, & + & kappa_n, rmult, mp1, mp2, dt_loc real(wp), dimension(3) :: xp1, xp2, vp1, vp2, v_rel, rpij, nij, vnij, Fnpp_ij, force_vec - integer :: kpz - integer :: total_recv - integer :: glb_id, count - integer :: n_el_particles_loc_before_ghost + integer :: kpz + integer :: total_recv + integer :: glb_id, count + integer :: n_el_particles_loc_before_ghost if (num_procs > 1) then n_el_particles_loc_before_ghost = n_el_particles_loc - call s_reset_force_buffers() call s_add_ghost_particles() end if kpz = 0 - if (num_dims == 3) kpz = 1 + if (num_dims == 3) kpz = ncc - ksp = 10._wp ! Spring stiffness multiplier - nu1 = 0.35_wp ! Poisson's ratio, particle 1 (glass/steel-like) - nu2 = 0.35_wp ! Poisson's ratio, particle 2 - E1 = 1.e9_wp ! Young's modulus [Pa], particle 1 - E2 = 1.e9_wp ! Young's modulus [Pa], particle 2 - cor = 0.7_wp ! Coefficient of restitution + ksp = particle_pp%ksp_col ! Spring stiffness multiplier + ksp_wall = ksp ! Spring stiffness multiplier for wall collision + nu1 = particle_pp%nu_col ! Poisson's ratio, particle 1 (glass/steel-like) + nu2 = nu1 ! Poisson's ratio, particle 2 + E1 = particle_pp%E_col ! Young's modulus [Pa], particle 1 + E2 = E1 ! Young's modulus [Pa], particle 2 + cor = particle_pp%cor_col ! Coefficient of restitution pidtksp2 = (pi**2)/((dt*ksp)**2) + pidtksp2_wall = (pi**2)/((dt*ksp_wall)**2) Estar = 1._wp/(((1._wp - nu1**2)/E1) + ((1._wp - nu2**2)/E2)) Estar = (4._wp/3._wp)*Estar @@ -900,10 +1022,10 @@ contains $:GPU_UPDATE(device='[error_flag]') $:GPU_PARALLEL_LOOP(private='[i, k, cell, ip, jp, kp, Rp1, xp1, mp1, vp1, kk, jj, ii, cellaux, q, Rp2, xp2, mp2, vp2, & - & v_rel, Rstar, rpij, rmag, nij, vnij, dij, kappa_n, eta_n, Fnpp_ij, force_vec, s_cell, celloutside, & - & count]', copyin='[ksp, nu1, nu2, E1, E2, cor, pidtksp2, Estar, kpz]') + & v_rel, Rstar, rpij, rmag, nij, vnij, dij, kappa_n, rmult, eta_n, Fnpp_ij, force_vec, s_cell, & + & celloutside, count]', copyin='[ksp, nu1, nu2, E1, E2, cor, pidtksp2, pidtksp2_wall, Estar, kpz]') do k = 1, n_el_particles_loc - if (.not. particle_in_domain_physical(particle_pos(k,1:3,2))) then + if (p_owner_rank(k) /= proc_rank) then cycle end if @@ -923,8 +1045,8 @@ contains vp1 = particle_vel(k,:,2) do kk = kp - kpz, kp + kpz - do jj = jp - 1, jp + 1 - do ii = ip - 1, ip + 1 + do jj = jp - ncc, jp + ncc + do ii = ip - ncc, ip + ncc cellaux(1) = ii cellaux(2) = jj cellaux(3) = kk @@ -944,7 +1066,7 @@ contains exit end if - if (lag_part_id(q, 1) > lag_part_id(k, 1)) then + if (q /= k) then Rp2 = particle_rad(q, 2) xp2 = particle_pos(q,:,2) mp2 = particle_mass(q) @@ -960,29 +1082,14 @@ contains dij = (Rp1 + Rp2) - rmag if (dij > 0._wp) then - kappa_n = min((pidtksp2*mp1), (pidtksp2*mp2), (Estar*sqrt(Rstar)*sqrt(abs(dij)))) + kappa_n = min((pidtksp2*mp1), (Estar*sqrt(Rstar)*sqrt(abs(dij)))) - eta_n = ((-2._wp*sqrt(kappa_n)*log(cor))/sqrt((log(cor))**2 + pi**2)) & - & *(1._wp/sqrt((1._wp/mp1) + (1._wp/mp2))) + rmult = (mp1*mp2)/(mp1 + mp2) + eta_n = ((-2._wp*sqrt(kappa_n)*log(cor))/sqrt((log(cor))**2 + pi**2))*sqrt(rmult) Fnpp_ij = -kappa_n*dij*nij - eta_n*vnij f_p(k,:) = f_p(k,:) + Fnpp_ij - - if (p_owner_rank(q) == proc_rank) then - ! f_p(q, :) = f_p(q, :) - Fnpp_ij - - $:GPU_ATOMIC(atomic='update') - f_p(q, 1) = f_p(q, 1) - Fnpp_ij(1) - - $:GPU_ATOMIC(atomic='update') - f_p(q, 2) = f_p(q, 2) - Fnpp_ij(2) - - $:GPU_ATOMIC(atomic='update') - f_p(q, 3) = f_p(q, 3) - Fnpp_ij(3) - else - call s_add_force_to_send_buffer(p_owner_rank(q), lag_part_id(q, 1), -Fnpp_ij) - end if end if end if @@ -995,7 +1102,7 @@ contains !> Check each local particle for wall collisions - call s_compute_wall_collisions(xp1, vp1, Rp1, mp1, Estar, pidtksp2, cor, force_vec) + call s_compute_wall_collisions(xp1, vp1, Rp1, mp1, Estar, pidtksp2_wall, cor, force_vec) f_p(k,:) = f_p(k,:) + force_vec end do $:END_GPU_PARALLEL_LOOP() @@ -1010,30 +1117,6 @@ contains if (num_procs > 1) then n_el_particles_loc = n_el_particles_loc_before_ghost $:GPU_UPDATE(device='[n_el_particles_loc]') - - total_recv = 0 - force_recv_ids = 0 - force_recv_vals = 0._wp - - call s_transfer_collision_forces(total_recv, force_recv_ids, force_recv_vals) - - $:GPU_UPDATE(device = '[force_recv_ids, force_recv_vals]') - - $:GPU_PARALLEL_LOOP(private='[i, k]',copyin = '[total_recv]') - do i = 1, total_recv - k = gid_to_local(force_recv_ids(i)) - if (k > 0) then - $:GPU_ATOMIC(atomic='update') - f_p(k, 1) = f_p(k, 1) + force_recv_vals(3*(i - 1) + 1) - - $:GPU_ATOMIC(atomic='update') - f_p(k, 2) = f_p(k, 2) + force_recv_vals(3*(i - 1) + 2) - - $:GPU_ATOMIC(atomic='update') - f_p(k, 3) = f_p(k, 3) + force_recv_vals(3*(i - 1) + 3) - end if - end do - $:END_GPU_PARALLEL_LOOP() end if end subroutine s_compute_particle_EL_collisions @@ -1138,15 +1221,13 @@ contains integer :: k, i, q integer :: patch_id, newBubs integer, dimension(3) :: cell - logical :: inc_ghost - - inc_ghost = .true. + logical :: inc_ghost = .true. call nvtxStartRange("LAG-GHOSTADD") call nvtxStartRange("LAG-GHOSTADD-DEV2HOST") - $:GPU_UPDATE(host='[p_owner_rank, particle_R0, Rmax_stats_part, Rmin_stats_part, particle_mass, f_p, lag_part_id, & - & particle_rad, particle_pos, particle_posPrev, particle_vel, particle_s, particle_draddt, particle_dposdt, & - & particle_dveldt, n_el_particles_loc, wrap_bubble_dir, wrap_bubble_loc]') + $:GPU_UPDATE(host='[p_owner_rank, particle_R0, Rmax_stats_part, Rmin_stats_part, particle_mass, particle_seed, f_p, & + & fqs_fluct, lag_part_id, particle_rad, particle_pos, particle_posPrev, particle_vel, particle_s, & + & particle_draddt, particle_dposdt, particle_dveldt, n_el_particles_loc, wrap_bubble_dir, wrap_bubble_loc]') call nvtxEndRange ! Handle MPI transfer of particles going to another processor's local domain @@ -1156,17 +1237,18 @@ contains call nvtxEndRange call nvtxStartRange("LAG-GHOSTADD-SENDRECV") - call s_mpi_sendrecv_solid_particles(p_owner_rank, particle_R0, Rmax_stats_part, Rmin_stats_part, particle_mass, f_p, & - & lag_part_id, particle_rad, particle_pos, particle_posPrev, particle_vel, & - & particle_s, particle_draddt, particle_dposdt, particle_dveldt, lag_num_ts, & - & n_el_particles_loc, 2) + call s_mpi_sendrecv_solid_particles(p_owner_rank, particle_R0, Rmax_stats_part, Rmin_stats_part, particle_mass, & + & particle_seed, f_p, fqs_fluct, lag_part_id, particle_rad, particle_pos, & + & particle_posPrev, particle_vel, particle_s, particle_draddt, particle_dposdt, & + & particle_dveldt, lag_num_ts, n_el_particles_loc, 2) + call nvtxEndRange end if call nvtxStartRange("LAG-GHOSTADD-HOST2DEV") - $:GPU_UPDATE(device='[p_owner_rank, particle_R0, Rmax_stats_part, Rmin_stats_part, particle_mass, f_p, lag_part_id, & - & particle_rad, particle_pos, particle_posPrev, particle_vel, particle_s, particle_draddt, particle_dposdt, & - & particle_dveldt, n_el_particles_loc]') + $:GPU_UPDATE(device='[p_owner_rank, particle_R0, Rmax_stats_part, Rmin_stats_part, particle_mass, particle_seed, f_p, & + & fqs_fluct, lag_part_id, particle_rad, particle_pos, particle_posPrev, particle_vel, particle_s, & + & particle_draddt, particle_dposdt, particle_dveldt, n_el_particles_loc]') call nvtxEndRange call nvtxEndRange ! LAG-GHOSTADD @@ -1287,6 +1369,10 @@ contains rhs_vf(E_idx)%sf(i, j, k) = rhs_vf(E_idx)%sf(i, j, k) + (q_particles(Smz_id)%sf(i, j, & & k)*q_prim_vf(momxb + 2)%sf(i, j, k))*(1._wp/alpha_f) end if + + do l = 1, E_idx + rhs_old(l)%sf(i, j, k) = rhs_vf(l)%sf(i, j, k) + end do end if end do end do @@ -1320,61 +1406,6 @@ contains end subroutine s_reset_linked_list - !> Zero all Eulerian field variables and particle projection arrays - subroutine s_reset_cell_vars() - - integer :: i, j, k, l - - $:GPU_PARALLEL_LOOP(private='[i, j, k, l]', collapse=4) - do i = 1, max(nField_vars, q_particles_idx) ! outermost is largest of the i-like dims - do l = idwbuff(3)%beg, idwbuff(3)%end - do k = idwbuff(2)%beg, idwbuff(2)%end - do j = idwbuff(1)%beg, idwbuff(1)%end - ! Zero field_vars if i <= nField_vars - if (i <= nField_vars) field_vars(i)%sf(j, k, l) = 0._wp - ! Zero q_particles if i <= q_particles_idx - if (i <= q_particles_idx) then - q_particles(i)%sf(j, k, l) = 0._wp - end if - end do - end do - end do - end do - $:END_GPU_PARALLEL_LOOP() - - end subroutine s_reset_cell_vars - - !> Finalize the particle volume fraction field after Gaussian smearing. Applies boundary conditions to the smeared field, then - !! converts accumulated particle volume alpha_p to fluid volume fraction alpha_f = 1 - alpha_p. - subroutine s_finalize_beta_field(bc_type, onlyBeta) - - type(integer_field), dimension(1:num_dims,1:2), intent(in) :: bc_type - integer :: j, k, l - logical, intent(in) :: onlyBeta - - call nvtxStartRange("PARTICLES-LAGRANGE-BETA-COMM") - if (onlyBeta) then - call s_populate_beta_buffers(q_particles, bc_type, 1) - else - call s_populate_beta_buffers(q_particles, bc_type, q_particles_idx) - end if - call nvtxEndRange - - ! Store 1-q_particles(1) - $:GPU_PARALLEL_LOOP(private='[j, k, l]', collapse=3) - do l = idwbuff(3)%beg, idwbuff(3)%end - do k = idwbuff(2)%beg, idwbuff(2)%end - do j = idwbuff(1)%beg, idwbuff(1)%end - q_particles(alphaf_id)%sf(j, k, l) = 1._wp - q_particles(alphaf_id)%sf(j, k, l) - ! Limiting void fraction given max value - q_particles(alphaf_id)%sf(j, k, l) = max(q_particles(alphaf_id)%sf(j, k, l), 1._wp - lag_params%valmaxvoid) - end do - end do - end do - $:END_GPU_PARALLEL_LOOP() - - end subroutine s_finalize_beta_field - !> Build a cell-based linked list for particle-to-cell mapping. particle_head(i,j,k) points to the first particle in cell !! (i,j,k). linked_list(k) points to the next particle in the same cell (-1 = end). subroutine s_build_linked_list() @@ -1554,19 +1585,15 @@ contains integer :: k, i, q integer :: patch_id, newBubs, new_idx integer, dimension(3) :: cell - logical :: inc_ghost - real(wp) :: myR, func_sum - real(wp), dimension(3) :: myPos, myVel, myForce - logical :: only_beta - - inc_ghost = .false. - only_beta = .true. + logical :: inc_ghost = .false. + integer :: ind_end_loc call nvtxStartRange("LAG-BC") call nvtxStartRange("LAG-BC-DEV2HOST") - $:GPU_UPDATE(host='[p_owner_rank, particle_R0, Rmax_stats_part, Rmin_stats_part, particle_mass, f_p, lag_part_id, & - & particle_rad, particle_pos, particle_posPrev, particle_vel, particle_s, particle_draddt, particle_dposdt, & - & particle_dveldt, keep_bubble, n_el_particles_loc, wrap_bubble_dir, wrap_bubble_loc]') + $:GPU_UPDATE(host='[p_owner_rank, particle_R0, Rmax_stats_part, Rmin_stats_part, particle_mass, particle_seed, f_p, & + & fqs_fluct, lag_part_id, particle_rad, particle_pos, particle_posPrev, particle_vel, particle_s, & + & particle_draddt, particle_dposdt, particle_dveldt, keep_bubble, n_el_particles_loc, wrap_bubble_dir, & + & wrap_bubble_loc]') call nvtxEndRange ! Handle MPI transfer of particles going to another processor's local domain @@ -1576,17 +1603,17 @@ contains call nvtxEndRange call nvtxStartRange("LAG-BC-SENDRECV") - call s_mpi_sendrecv_solid_particles(p_owner_rank, particle_R0, Rmax_stats_part, Rmin_stats_part, particle_mass, f_p, & - & lag_part_id, particle_rad, particle_pos, particle_posPrev, particle_vel, & - & particle_s, particle_draddt, particle_dposdt, particle_dveldt, lag_num_ts, & - & n_el_particles_loc, 2) + call s_mpi_sendrecv_solid_particles(p_owner_rank, particle_R0, Rmax_stats_part, Rmin_stats_part, particle_mass, & + & particle_seed, f_p, fqs_fluct, lag_part_id, particle_rad, particle_pos, & + & particle_posPrev, particle_vel, particle_s, particle_draddt, particle_dposdt, & + & particle_dveldt, lag_num_ts, n_el_particles_loc, 2) call nvtxEndRange end if call nvtxStartRange("LAG-BC-HOST2DEV") - $:GPU_UPDATE(device='[p_owner_rank, particle_R0, Rmax_stats_part, Rmin_stats_part, particle_mass, f_p, lag_part_id, & - & particle_rad, particle_pos, particle_posPrev, particle_vel, particle_s, particle_draddt, particle_dposdt, & - & particle_dveldt, n_el_particles_loc]') + $:GPU_UPDATE(device='[p_owner_rank, particle_R0, Rmax_stats_part, Rmin_stats_part, particle_mass, particle_seed, f_p, & + & fqs_fluct, lag_part_id, particle_rad, particle_pos, particle_posPrev, particle_vel, particle_s, & + & particle_draddt, particle_dposdt, particle_dveldt, n_el_particles_loc]') call nvtxEndRange $:GPU_PARALLEL_LOOP(private='[k, cell]',copyin='[nstage]') @@ -1597,14 +1624,14 @@ contains ! Relocate particles at solid boundaries and delete particles that leave buffer regions if (any(bc_x%beg == (/BC_REFLECTIVE, BC_CHAR_SLIP_WALL, BC_SLIP_WALL, BC_NO_SLIP_WALL/)) .and. particle_pos(k, 1, & - & 2) < x_cb(-1) + eps_overlap*particle_rad(k, 2)) then - particle_pos(k, 1, 2) = x_cb(-1) + eps_overlap*particle_rad(k, 2) + & 2) < x_cb(-1) + eps_overlap) then + particle_pos(k, 1, 2) = x_cb(-1) + eps_overlap if (nstage == lag_num_ts) then particle_pos(k, 1, 1) = particle_pos(k, 1, 2) end if else if (any(bc_x%end == (/BC_REFLECTIVE, BC_CHAR_SLIP_WALL, BC_SLIP_WALL, BC_NO_SLIP_WALL/)) .and. particle_pos(k, & - & 1, 2) > x_cb(m) - eps_overlap*particle_rad(k, 2)) then - particle_pos(k, 1, 2) = x_cb(m) - eps_overlap*particle_rad(k, 2) + & 1, 2) > x_cb(m) - eps_overlap) then + particle_pos(k, 1, 2) = x_cb(m) - eps_overlap if (nstage == lag_num_ts) then particle_pos(k, 1, 1) = particle_pos(k, 1, 2) end if @@ -1623,14 +1650,14 @@ contains end if if (any(bc_y%beg == (/BC_REFLECTIVE, BC_CHAR_SLIP_WALL, BC_SLIP_WALL, BC_NO_SLIP_WALL/)) .and. particle_pos(k, 2, & - & 2) < y_cb(-1) + eps_overlap*particle_rad(k, 2)) then - particle_pos(k, 2, 2) = y_cb(-1) + eps_overlap*particle_rad(k, 2) + & 2) < y_cb(-1) + eps_overlap) then + particle_pos(k, 2, 2) = y_cb(-1) + eps_overlap if (nstage == lag_num_ts) then particle_pos(k, 2, 1) = particle_pos(k, 2, 2) end if else if (any(bc_y%end == (/BC_REFLECTIVE, BC_CHAR_SLIP_WALL, BC_SLIP_WALL, BC_NO_SLIP_WALL/)) .and. particle_pos(k, & - & 2, 2) > y_cb(n) - eps_overlap*particle_rad(k, 2)) then - particle_pos(k, 2, 2) = y_cb(n) - eps_overlap*particle_rad(k, 2) + & 2, 2) > y_cb(n) - eps_overlap) then + particle_pos(k, 2, 2) = y_cb(n) - eps_overlap if (nstage == lag_num_ts) then particle_pos(k, 2, 1) = particle_pos(k, 2, 2) end if @@ -1650,14 +1677,14 @@ contains if (p > 0) then if (any(bc_z%beg == (/BC_REFLECTIVE, BC_CHAR_SLIP_WALL, BC_SLIP_WALL, BC_NO_SLIP_WALL/)) .and. particle_pos(k, 3, & - & 2) < z_cb(-1) + eps_overlap*particle_rad(k, 2)) then - particle_pos(k, 3, 2) = z_cb(-1) + eps_overlap*particle_rad(k, 2) + & 2) < z_cb(-1) + eps_overlap) then + particle_pos(k, 3, 2) = z_cb(-1) + eps_overlap if (nstage == lag_num_ts) then particle_pos(k, 3, 1) = particle_pos(k, 3, 2) end if else if (any(bc_z%end == (/BC_REFLECTIVE, BC_CHAR_SLIP_WALL, BC_SLIP_WALL, & - & BC_NO_SLIP_WALL/)) .and. particle_pos(k, 3, 2) > z_cb(p) - eps_overlap*particle_rad(k, 2)) then - particle_pos(k, 3, 2) = z_cb(p) - eps_overlap*particle_rad(k, 2) + & BC_NO_SLIP_WALL/)) .and. particle_pos(k, 3, 2) > z_cb(p) - eps_overlap) then + particle_pos(k, 3, 2) = z_cb(p) - eps_overlap if (nstage == lag_num_ts) then particle_pos(k, 3, 1) = particle_pos(k, 3, 2) end if @@ -1691,9 +1718,10 @@ contains if (n_el_particles_loc > 0) then call nvtxStartRange("LAG-BC") call nvtxStartRange("LAG-BC-DEV2HOST") - $:GPU_UPDATE(host='[particle_R0, Rmax_stats_part, Rmin_stats_part, particle_mass, f_p, lag_part_id, particle_rad, & - & particle_pos, particle_posPrev, particle_vel, particle_s, particle_draddt, particle_dposdt, & - & particle_dveldt, keep_bubble, n_el_particles_loc, wrap_bubble_dir, wrap_bubble_loc]') + $:GPU_UPDATE(host='[p_owner_rank, particle_R0, Rmax_stats_part, Rmin_stats_part, particle_mass, particle_seed, f_p, & + & fqs_fluct, lag_part_id, particle_rad, particle_pos, particle_posPrev, particle_vel, particle_s, & + & particle_draddt, particle_dposdt, particle_dveldt, keep_bubble, n_el_particles_loc, wrap_bubble_dir, & + & wrap_bubble_loc]') call nvtxEndRange newBubs = 0 @@ -1736,38 +1764,54 @@ contains end if end do call nvtxStartRange("LAG-BC-HOST2DEV") - $:GPU_UPDATE(device='[particle_R0, Rmax_stats_part, Rmin_stats_part, particle_mass, f_p, lag_part_id, particle_rad, & - & particle_pos, particle_posPrev, particle_vel, particle_s, particle_draddt, particle_dposdt, & - & particle_dveldt, n_el_particles_loc]') + $:GPU_UPDATE(device='[p_owner_rank, particle_R0, Rmax_stats_part, Rmin_stats_part, particle_mass, particle_seed, f_p, & + & fqs_fluct, lag_part_id, particle_rad, particle_pos, particle_posPrev, particle_vel, particle_s, & + & particle_draddt, particle_dposdt, particle_dveldt, n_el_particles_loc]') call nvtxEndRange end if - call s_reset_cell_vars() + if (lag_params%qs_fluct_force) then + ind_end_loc = alphaup2z_id + else if (lag_params%solver_approach == 2) then + ind_end_loc = alphaupz_id + else + ind_end_loc = alphaf_id + end if + + call s_smear_field_contributions(bc_type, alphaf_id, ind_end_loc, .true.) + + if (lag_params%solver_approach == 2) then + call s_compute_gaussian_source_contribution() + end if + + call nvtxEndRange ! LAG-BC + + end subroutine s_enforce_EL_particles_boundary_conditions + + subroutine s_compute_gaussian_source_contribution() + + real(wp) :: myR, func_sum_dummy, func_sum_sources + real(wp), dimension(3) :: myPos, s_cell + integer :: k, i + integer, dimension(3) :: cell - $:GPU_PARALLEL_LOOP(private='[cell, myR, myPos, myVel, myForce, func_sum]',copyin='[only_beta]') + $:GPU_PARALLEL_LOOP(private='[k, i, cell, s_cell, myR, myPos, func_sum_dummy, func_sum_sources]') do k = 1, n_el_particles_loc myR = particle_rad(k, 2) myPos = particle_pos(k,1:3,2) - myVel = particle_vel(k,1:3,2) - myForce = f_p(k,:) - cell = fd_number - buff_size - call s_locate_cell(particle_pos(k,1:3,2), cell, particle_s(k,1:3,2)) + s_cell = particle_s(k,1:3,2) + cell = int(s_cell(:)) + do i = 1, num_dims + if (s_cell(i) < 0._wp) cell(i) = cell(i) - 1 + end do ! Compute the total gaussian contribution for each particle for normalization - call s_compute_gaussian_contribution(myR, myPos, cell, func_sum) - gSum(k) = func_sum - - call s_gaussian_atomic(myR, myVel, myPos, myForce, func_sum, cell, q_particles, only_beta) + call s_compute_gaussian_contribution(myR, myPos, cell, func_sum_dummy, func_sum_sources, q_particles) + gSum_sources(k) = func_sum_sources end do - $:END_GPU_PARALLEL_LOOP() - - ! Update void fraction and communicate buffers - call s_finalize_beta_field(bc_type, only_beta) - - call nvtxEndRange ! LAG-BC - end subroutine s_enforce_EL_particles_boundary_conditions + end subroutine s_compute_gaussian_source_contribution !> This subroutine returns the computational coordinate of the cell for the given position. !! @param pos Input coordinates @@ -2540,10 +2584,12 @@ contains integer, intent(in) :: src, dest + p_owner_rank(dest) = p_owner_rank(src) particle_R0(dest) = particle_R0(src) Rmax_stats_part(dest) = Rmax_stats_part(src) Rmin_stats_part(dest) = Rmin_stats_part(src) particle_mass(dest) = particle_mass(src) + particle_seed(dest) = particle_seed(src) lag_part_id(dest, 1) = lag_part_id(src, 1) particle_rad(dest,1:2) = particle_rad(src,1:2) particle_vel(dest,1:3,1:2) = particle_vel(src,1:3,1:2) @@ -2552,6 +2598,7 @@ contains particle_posPrev(dest,1:3,1:2) = particle_posPrev(src,1:3,1:2) particle_draddt(dest,1:lag_num_ts) = particle_draddt(src,1:lag_num_ts) f_p(dest,1:3) = f_p(src,1:3) + fqs_fluct(dest,1:3) = fqs_fluct(src,1:3) particle_dposdt(dest,1:3,1:lag_num_ts) = particle_dposdt(src,1:3,1:lag_num_ts) particle_dveldt(dest,1:3,1:lag_num_ts) = particle_dveldt(src,1:3,1:lag_num_ts) @@ -2568,14 +2615,21 @@ contains do i = 1, q_particles_idx @:DEALLOCATE(q_particles(i)%sf) + @:DEALLOCATE(kahan_comp(i)%sf) end do @:DEALLOCATE(q_particles) + @:DEALLOCATE(kahan_comp) do i = 1, nField_vars @:DEALLOCATE(field_vars(i)%sf) end do @:DEALLOCATE(field_vars) + do i = 1, sys_size + @:DEALLOCATE(rhs_old(i)%sf) + end do + @:DEALLOCATE(rhs_old) + do i = 1, nWeights_interp @:DEALLOCATE(weights_x_interp(i)%sf) end do @@ -2613,6 +2667,7 @@ contains @:DEALLOCATE(Rmax_stats_part) @:DEALLOCATE(Rmin_stats_part) @:DEALLOCATE(particle_mass) + @:DEALLOCATE(particle_seed) @:DEALLOCATE(p_AM) @:DEALLOCATE(p_owner_rank) @:DEALLOCATE(particle_rad) @@ -2624,7 +2679,9 @@ contains @:DEALLOCATE(particle_dposdt) @:DEALLOCATE(particle_dveldt) @:DEALLOCATE(f_p) + @:DEALLOCATE(fqs_fluct) @:DEALLOCATE(gSum) + @:DEALLOCATE(gSum_sources) @:DEALLOCATE(force_recv_ids) @:DEALLOCATE(force_recv_vals) @@ -2635,11 +2692,6 @@ contains @:DEALLOCATE(linked_list) @:DEALLOCATE(particle_head) - ! Deallocate cell list arrays - @:DEALLOCATE(cell_list_start) - @:DEALLOCATE(cell_list_count) - @:DEALLOCATE(cell_list_idx) - end subroutine s_finalize_particle_lagrangian_solver end module m_particles_EL diff --git a/src/simulation/m_particles_EL_kernels.fpp b/src/simulation/m_particles_EL_kernels.fpp index 08d2c22c8c..cfcb40d746 100644 --- a/src/simulation/m_particles_EL_kernels.fpp +++ b/src/simulation/m_particles_EL_kernels.fpp @@ -9,30 +9,49 @@ module m_particles_EL_kernels use m_mpi_proxy !< Message passing interface (MPI) module proxy use ieee_arithmetic !< For checking NaN + use m_model !< For getting f_model_random_number implicit none - ! Cell list for particle-to-cell mapping (rebuilt each RK stage before smearing) - integer, allocatable, dimension(:,:,:) :: cell_list_start ! (0:m, 0:n, 0:p) - integer, allocatable, dimension(:,:,:) :: cell_list_count ! (0:m, 0:n, 0:p) - integer, allocatable, dimension(:) :: cell_list_idx ! (1:nParticles_glb) sorted particle indices - $:GPU_DECLARE(create='[cell_list_start, cell_list_count, cell_list_idx]') + integer, parameter :: alphaf_id_loc = 1 + integer, parameter :: alphaupx_id_loc = 2 !< x particle momentum index + integer, parameter :: alphaupy_id_loc = 3 !< y particle momentum index + integer, parameter :: alphaupz_id_loc = 4 !< z particle momentum index + integer, parameter :: alphaup2x_id_loc = 5 !< x particle velocity squared + integer, parameter :: alphaup2y_id_loc = 6 !< y particle velocity squared + integer, parameter :: alphaup2z_id_loc = 7 !< z particle velocity squared + integer, parameter :: Smx_id_loc = 8 + integer, parameter :: Smy_id_loc = 9 + integer, parameter :: Smz_id_loc = 10 + integer, parameter :: SE_id_loc = 11 + integer, parameter :: dPx_id_loc = 1 !< Spatial pressure gradient in x, y, and z + integer, parameter :: drhox_id_loc = 4 !< Spatial density gradient in x, y, and z + integer, parameter :: dufxdx_id_loc = 7 ! du_x/dx + integer, parameter :: dufxdy_id_loc = 8 ! du_x/dy + integer, parameter :: dufxdz_id_loc = 9 ! du_x/dz + integer, parameter :: dufydx_id_loc = 10 ! du_y/dx + integer, parameter :: dufydy_id_loc = 11 ! du_y/dy + integer, parameter :: dufydz_id_loc = 12 ! du_y/dz + integer, parameter :: dufzdx_id_loc = 13 ! du_z/dx + integer, parameter :: dufzdy_id_loc = 14 ! du_z/dy + integer, parameter :: dufzdz_id_loc = 15 ! du_z/dz contains ! !> The purpose of this subroutine is to compute each particles total contribution to the gaussian for proper normalization - subroutine s_compute_gaussian_contribution(rad, pos, cell, func_s) + subroutine s_compute_gaussian_contribution(rad, pos, cell, func_s, func_s_sources, updatedvar_old) $:GPU_ROUTINE(function_name='s_compute_gaussian_contribution',parallelism='[seq]', cray_inline=True) - real(wp), intent(in) :: rad + type(scalar_field), dimension(:), intent(in) :: updatedvar_old + real(wp), intent(in) :: rad real(wp), intent(in), dimension(3) :: pos - integer, intent(in), dimension(3) :: cell - real(wp), intent(out) :: func_s - real(wp) :: volpart, stddsv, Vol_loc, func - real(wp), dimension(3) :: nodecoord, center - integer :: ip, jp, kp, di, dj, dk, di_beg, di_end, dj_beg, dj_end, dk_beg, dk_end, mapCells_loc - integer, dimension(3) :: cellijk + integer, intent(in), dimension(3) :: cell + real(wp), intent(out) :: func_s, func_s_sources + real(wp) :: volpart, stddsv, Vol_loc, func, alpha_f + real(wp), dimension(3) :: nodecoord, center + integer :: ip, jp, kp, di, dj, dk, di_beg, di_end, dj_beg, dj_end, dk_beg, dk_end, mapCells_loc + integer, dimension(3) :: cellijk mapCells_loc = 1 @@ -57,6 +76,7 @@ contains end if func_s = 0._wp + func_s_sources = 0._wp do dk = dk_beg, dk_end do dj = dj_beg, dj_end do di = di_beg, di_end @@ -78,7 +98,9 @@ contains call s_applygaussian(center, cellijk, nodecoord, stddsv, 0._wp, func) - func_s = func_s + func*Vol_loc + alpha_f = updatedvar_old(alphaf_id_loc)%sf(cellijk(1), cellijk(2), cellijk(3)) + func_s = func_s + (func*Vol_loc) + func_s_sources = func_s_sources + (func*Vol_loc*alpha_f) end do end do end do @@ -87,26 +109,26 @@ contains !> The purpose of this subroutine is to compute the gaussian smearing of particle volume fraction and source terms with atomic !! cell updates - subroutine s_gaussian_atomic(rad, vel, pos, force_p, gauSum, cell, updatedvar, onlyBeta) + subroutine s_gaussian_atomic(rad, vel, pos, force_p, gauSum, gauSum_sources, cell, updatedvar, kcomp, ind_start, ind_end) $:GPU_ROUTINE(function_name='s_gaussian_atomic',parallelism='[seq]', cray_inline=True) - real(wp), intent(in) :: rad, gauSum + real(wp), intent(in) :: rad, gauSum, gauSum_sources real(wp), intent(in), dimension(3) :: pos, vel, force_p integer, intent(in), dimension(3) :: cell type(scalar_field), dimension(:), intent(inout) :: updatedvar + type(scalar_field), dimension(:), intent(inout) :: kcomp + integer, intent(in) :: ind_start, ind_end real(wp) :: volpart, stddsv, Vol_loc, func, weight real(wp) :: fp_x, fp_y, fp_z, vp_x, vp_y, vp_z - real(wp) :: addFun_alphap, addFun_alphap_vp_x, addFun_alphap_vp_y, addFun_alphap_vp_z - real(wp) :: addFun2_x, addFun2_y, addFun2_z, addFun_E + real(wp) :: addFun real(wp), dimension(3) :: nodecoord, center - integer :: ip, jp, kp, di, dj, dk, di_beg, di_end, dj_beg, dj_end, dk_beg, dk_end, mapCells_loc + integer :: ip, jp, kp, di, dj, dk, di_beg, di_end, dj_beg, dj_end, dk_beg, dk_end, mapCells_loc, field_ind integer, dimension(3) :: cellijk - logical, intent(in) :: onlyBeta mapCells_loc = 1 - volpart = (4._wp/3._wp)*pi*rad**3 + volpart = (4._wp/3._wp)*pi*rad**3._wp call s_compute_stddsv(cell, volpart, stddsv) @@ -155,61 +177,41 @@ contains call s_applygaussian(center, cellijk, nodecoord, stddsv, 0._wp, func) - if (gauSum <= 0._wp) return weight = func/gauSum - addFun_alphap = weight*volpart - $:GPU_ATOMIC(atomic='update') - updatedvar(1)%sf(cellijk(1), cellijk(2), cellijk(3)) = updatedvar(1)%sf(cellijk(1), cellijk(2), & - & cellijk(3)) + real(addFun_alphap, kind=stp) - - if (lag_params%solver_approach == 2 .and. .not. onlyBeta) then - ! Update particle momentum field(x) - addFun_alphap_vp_x = weight*volpart*vp_x - $:GPU_ATOMIC(atomic='update') - updatedvar(2)%sf(cellijk(1), cellijk(2), cellijk(3)) = updatedvar(2)%sf(cellijk(1), cellijk(2), & - & cellijk(3)) + real(addFun_alphap_vp_x, kind=stp) - - ! Update particle momentum field(y) - addFun_alphap_vp_y = weight*volpart*vp_y - $:GPU_ATOMIC(atomic='update') - updatedvar(3)%sf(cellijk(1), cellijk(2), cellijk(3)) = updatedvar(3)%sf(cellijk(1), cellijk(2), & - & cellijk(3)) + real(addFun_alphap_vp_y, kind=stp) - - if (num_dims == 3) then - ! Update particle momentum field(z) - addFun_alphap_vp_z = weight*volpart*vp_z - $:GPU_ATOMIC(atomic='update') - updatedvar(4)%sf(cellijk(1), cellijk(2), cellijk(3)) = updatedvar(4)%sf(cellijk(1), cellijk(2), & - & cellijk(3)) + real(addFun_alphap_vp_z, kind=stp) - end if - - ! Update x-momentum source term - addFun2_x = weight*fp_x - $:GPU_ATOMIC(atomic='update') - updatedvar(5)%sf(cellijk(1), cellijk(2), cellijk(3)) = updatedvar(5)%sf(cellijk(1), cellijk(2), & - & cellijk(3)) + real(addFun2_x, kind=stp) - - ! Update y-momentum source term - addFun2_y = weight*fp_y - $:GPU_ATOMIC(atomic='update') - updatedvar(6)%sf(cellijk(1), cellijk(2), cellijk(3)) = updatedvar(6)%sf(cellijk(1), cellijk(2), & - & cellijk(3)) + real(addFun2_y, kind=stp) - - if (num_dims == 3) then - ! Update z-momentum source term - addFun2_z = weight*fp_z - $:GPU_ATOMIC(atomic='update') - updatedvar(7)%sf(cellijk(1), cellijk(2), cellijk(3)) = updatedvar(7)%sf(cellijk(1), cellijk(2), & - & cellijk(3)) + real(addFun2_z, kind=stp) + do field_ind = ind_start, ind_end + if (field_ind == alphaf_id_loc) then + addFun = weight*volpart + else if (field_ind == alphaupx_id_loc) then + addFun = weight*volpart*vp_x + else if (field_ind == alphaupy_id_loc) then + addFun = weight*volpart*vp_y + else if (field_ind == alphaupz_id_loc) then + addFun = weight*volpart*vp_z + else if (field_ind == alphaup2x_id_loc) then + addFun = weight*volpart*vp_x**2 + else if (field_ind == alphaup2y_id_loc) then + addFun = weight*volpart*vp_y**2 + else if (field_ind == alphaup2z_id_loc) then + addFun = weight*volpart*vp_z**2 + else if (field_ind == Smx_id_loc) then + weight = func/gauSum_sources + addFun = weight*fp_x + else if (field_ind == Smy_id_loc) then + weight = func/gauSum_sources + addFun = weight*fp_y + else if (field_ind == Smz_id_loc) then + weight = func/gauSum_sources + addFun = weight*fp_z + else if (field_ind == SE_id_loc) then + weight = func/gauSum_sources + addFun = 0._wp end if - ! Update energy source term - addFun_E = 0._wp $:GPU_ATOMIC(atomic='update') - updatedvar(8)%sf(cellijk(1), cellijk(2), cellijk(3)) = updatedvar(8)%sf(cellijk(1), cellijk(2), & - & cellijk(3)) + real(addFun_E, kind=stp) - end if + updatedvar(field_ind)%sf(cellijk(1), cellijk(2), cellijk(3)) = updatedvar(field_ind)%sf(cellijk(1), & + & cellijk(2), cellijk(3)) + real(addFun, kind=stp) + end do end do end do end do @@ -394,31 +396,44 @@ contains !! @param cell Computational coordinates of the particle !! @param q_prim_vf Eulerian field with primitive variables !! @return a Acceleration of the particle in direction i - subroutine s_get_particle_force(pos, rad, vel_p, mass_p, Re, gamm, vol_frac, drhodt, cell, q_prim_vf, fieldvars, wx, wy, wz, & - & force, rmass_add) + subroutine s_get_particle_force(pos, rad, vel_p, mass_p, Re, gamm, seed, fqsfluct, cell, q_prim_vf, q_cons_vf, q_particles, & + & fieldvars, rhs_old, duidxj_id_loc, wx, wy, wz, force, rmass_add, new_seed, new_fqsfluct) $:GPU_ROUTINE(parallelism='[seq]') - real(wp), intent(in) :: rad, mass_p, Re, gamm, vol_frac, drhodt + real(wp), intent(in) :: rad, mass_p, Re, gamm real(wp), dimension(3), intent(in) :: pos integer, dimension(3), intent(in) :: cell - real(wp), dimension(3), intent(in) :: vel_p + integer, intent(in) :: seed + real(wp), dimension(3), intent(in) :: vel_p, fqsfluct + integer, dimension(3, 3), intent(in) :: duidxj_id_loc + type(scalar_field), dimension(:), intent(in) :: q_particles type(scalar_field), dimension(:), intent(in) :: fieldvars type(scalar_field), dimension(:), intent(in) :: wx, wy, wz type(scalar_field), dimension(sys_size), intent(in) :: q_prim_vf - real(wp), dimension(3), intent(out) :: force + type(scalar_field), dimension(sys_size), intent(in) :: q_cons_vf + type(scalar_field), dimension(sys_size), intent(in) :: rhs_old + real(wp), dimension(3), intent(out) :: force, new_fqsfluct real(wp), intent(out) :: rmass_add - real(wp) :: a, vol, rho_fluid, pressure_fluid + integer, intent(out) :: new_seed + integer :: seed_loc + real(wp) :: a, vol, rho_fluid, pressure_fluid, alpha_f real(wp), dimension(3) :: v_rel, dp - real(wp), dimension(fd_order) :: xi, eta, L real(wp) :: particle_diam, gas_mu, vmag, cson real(wp) :: slip_velocity_x, slip_velocity_y, slip_velocity_z, beta + real(wp) :: vol_frac real(wp), dimension(3) :: fluid_vel - integer :: dir + integer :: dir, l ! Added pass params - real(wp) :: mach, Cam, flux_f, flux_b, div_u, SDrho, vpgradrho - real(wp), dimension(3) :: rhoDuDt, grad_rho, fam + real(wp) :: mach, Cam, flux_f, flux_b, SDrho, vrel_gradrho, drhodt + real(wp), dimension(3) :: rhoDuDt, grad_rho, fam, udot_gradu integer, dimension(3) :: p1 + ! QS Fluct + real(wp), dimension(3) :: vel_p_mean, vel2_p_mean + + ! Suth + real(wp) :: fluid_temp, R_fluid, suth, tref + force = 0._wp dp = 0._wp grad_rho = 0._wp @@ -427,34 +442,72 @@ contains v_rel = 0._wp rhoDuDt = 0._wp SDrho = 0._wp - ! div_u = 0._wp + + udot_gradu = 0._wp + + vel_p_mean = 0._wp + vel2_p_mean = 0._wp !!Interpolation - either even ordered barycentric or 0th order if (lag_params%interpolation_order > 1) then rho_fluid = f_interp_barycentric(pos, cell, q_prim_vf, 1, wx, wy, wz) pressure_fluid = f_interp_barycentric(pos, cell, q_prim_vf, E_idx, wx, wy, wz) + alpha_f = f_interp_barycentric(pos, cell, q_particles, alphaf_id_loc, wx, wy, wz) + vol_frac = 1._wp - alpha_f + + do dir = 1, num_dims + vel_p_mean(dir) = f_interp_barycentric(pos, cell, q_particles, alphaupx_id_loc + dir - 1, wx, wy, & + & wz)/max(vol_frac, 1.e-12_wp) + vel2_p_mean(dir) = f_interp_barycentric(pos, cell, q_particles, alphaup2x_id_loc + dir - 1, wx, wy, & + & wz)/max(vol_frac, 1.e-12_wp) + fluid_vel(dir) = f_interp_barycentric(pos, cell, q_prim_vf, momxb + dir - 1, wx, wy, wz) + end do + + if (lag_params%added_mass_model > 0) then + drhodt = rhs_old(1)%sf(cell(1), cell(2), cell(3)) + end if + do dir = 1, num_dims if (lag_params%pressure_force .or. lag_params%added_mass_model > 0) then - dp(dir) = f_interp_barycentric(pos, cell, fieldvars, dir, wx, wy, wz) + dp(dir) = f_interp_barycentric(pos, cell, fieldvars, dPx_id_loc + dir - 1, wx, wy, wz) end if if (lag_params%added_mass_model > 0) then - grad_rho(dir) = f_interp_barycentric(pos, cell, fieldvars, 3 + dir, wx, wy, wz) - ! div_u = div_u + f_interp_barycentric(pos, cell, fieldvars, 6 + dir, wx, wy, wz) + grad_rho(dir) = f_interp_barycentric(pos, cell, fieldvars, drhox_id_loc + dir - 1, wx, wy, wz) + rhoDuDt(dir) = (rhs_old(momxb + dir - 1)%sf(cell(1), cell(2), cell(3)) - fluid_vel(dir)*drhodt)/rho_fluid + do l = 1, num_dims + udot_gradu(dir) = udot_gradu(dir) + fluid_vel(l)*f_interp_barycentric(pos, cell, fieldvars, & + & duidxj_id_loc(dir, l), wx, wy, wz) + end do end if - fluid_vel(dir) = f_interp_barycentric(pos, cell, q_prim_vf, momxb + dir - 1, wx, wy, wz) end do else rho_fluid = q_prim_vf(1)%sf(cell(1), cell(2), cell(3)) pressure_fluid = q_prim_vf(E_idx)%sf(cell(1), cell(2), cell(3)) + alpha_f = q_particles(alphaf_id_loc)%sf(cell(1), cell(2), cell(3)) + vol_frac = 1._wp - alpha_f + + do dir = 1, num_dims + vel_p_mean(dir) = q_particles(alphaupx_id_loc + dir - 1)%sf(cell(1), cell(2), cell(3))/max(vol_frac, 1.e-12_wp) + vel2_p_mean(dir) = q_particles(alphaup2x_id_loc + dir - 1)%sf(cell(1), cell(2), cell(3))/max(vol_frac, 1.e-12_wp) + fluid_vel(dir) = q_prim_vf(momxb + dir - 1)%sf(cell(1), cell(2), cell(3)) + end do + + if (lag_params%added_mass_model > 0) then + drhodt = rhs_old(1)%sf(cell(1), cell(2), cell(3)) + end if + do dir = 1, num_dims if (lag_params%pressure_force .or. lag_params%added_mass_model > 0) then - dp(dir) = fieldvars(dir)%sf(cell(1), cell(2), cell(3)) + dp(dir) = fieldvars(dPx_id_loc + dir - 1)%sf(cell(1), cell(2), cell(3)) end if if (lag_params%added_mass_model > 0) then - grad_rho(dir) = fieldvars(3 + dir)%sf(cell(1), cell(2), cell(3)) - ! div_u = div_u + fieldvars(6 + dir)%sf(cell(1), cell(2), cell(3)) + grad_rho(dir) = fieldvars(drhox_id_loc + dir - 1)%sf(cell(1), cell(2), cell(3)) + rhoDuDt(dir) = (rhs_old(momxb + dir - 1)%sf(cell(1), cell(2), cell(3)) - fluid_vel(dir)*drhodt)/rho_fluid + do l = 1, num_dims + udot_gradu(dir) = udot_gradu(dir) + fluid_vel(l)*fieldvars(duidxj_id_loc(dir, l))%sf(cell(1), cell(2), & + & cell(3)) + end do end if - fluid_vel(dir) = q_prim_vf(momxb + dir - 1)%sf(cell(1), cell(2), cell(3)) end do end if @@ -477,12 +530,21 @@ contains cson = 1._wp end if gas_mu = Re + + if (.not. viscous) then + tref = 273.15_wp + R_fluid = 287.05_wp ! J/kg-K for Air + suth = 110.4_wp + fluid_temp = pressure_fluid/(rho_fluid*R_fluid) + + gas_mu = gas_mu*sqrt(fluid_temp/tref)*(1.0_wp + suth/tref)/(1.0_wp + suth/fluid_temp) + end if end if if (lag_params%added_mass_model > 0) then - rhoDuDt = -dp - vpgradrho = dot_product(vel_p, grad_rho) - SDrho = drhodt + fluid_vel(1)*grad_rho(1) + fluid_vel(2)*grad_rho(2) + fluid_vel(3)*grad_rho(3) + rhoDuDt = rho_fluid*(rhoDuDt + udot_gradu) + vrel_gradrho = dot_product(-v_rel, grad_rho) + SDrho = drhodt + vel_p(1)*grad_rho(1) + vel_p(2)*grad_rho(2) + vel_p(3)*grad_rho(3) mach = vmag/cson end if @@ -533,9 +595,9 @@ contains end if Cam = 0.5_wp*Cam*(1._wp + 0.68_wp*vol_frac**2) - rmass_add = rho_fluid*vol*Cam ! (1._wp-vol_frac)*rho_fluid*vol*Cam + rmass_add = rho_fluid*vol*Cam - fam = Cam*vol*(vel_p*SDrho + rhoDuDt + fluid_vel*(vpgradrho)) + fam = Cam*vol*(-v_rel*SDrho + rhoDuDt + fluid_vel*(vrel_gradrho)) do dir = 1, num_dims if (.not. ieee_is_finite(fam(dir))) then @@ -548,6 +610,17 @@ contains rmass_add = 0._wp end if + if (lag_params%qs_fluct_force) then + ! Step 5: QS Fluctuations + !> New addition: QS Fluctuations + seed_loc = seed + call s_compute_qs_fluctuations(vel_p, fluid_vel, rho_fluid, cson, gas_mu, particle_diam, vol_frac, vmag, vel_p_mean, & + & vel2_p_mean, seed_loc, fqsfluct, dt, new_fqsfluct) + force = force + new_fqsfluct + new_seed = seed_loc + !> + end if + do dir = 1, num_dims if (.not. ieee_is_finite(force(dir))) then force(dir) = 0._wp @@ -556,6 +629,154 @@ contains end subroutine s_get_particle_force + ! Quasi-steady force fluctuations Osnes, Vartdal, Khalloufi, Capecelatro (2023) Comprehensive quasi-steady force correlations + ! for compressible flow through random particle suspensions. International Journal of Multiphase Flows, Vo. 165, 104485. + ! Lattanzi, Tavanashad, Subramaniam, Capecelatro (2022) Stochastic model for the hydrodynamic force in Euler-Lagrange + ! silumations of particle-laden flows. Physical Review Fluids, Vol. 7, 014301. Note: To compute the granular temperature, we + ! assume the velocity fluctuations are uncorrelated. Note: The means are computed using a box filter with an adaptive filter + ! width. Compute mean using box filter for langevin model - not for feedback + ! + ! The mean is calculated according to Lattanzi etal, Physical Review Fluids, 2022. + subroutine s_compute_qs_fluctuations(vel_p, fluid_vel, rho_fluid, cson, gas_mu, particle_diam, vol_frac, vmag, vel_p_mean, & + & vel2_p_mean, seed, fqs_fluct_old, dt_loc, fqs_fluct_new) + $:GPU_ROUTINE(parallelism='[seq]') + + real(wp), dimension(3), intent(in) :: vel_p, fluid_vel + real(wp), intent(in) :: rho_fluid, cson, gas_mu, particle_diam, vol_frac, vmag + real(wp), dimension(3), intent(in) :: vel_p_mean, vel2_p_mean + integer, intent(inout) :: seed + real(wp), dimension(3), intent(in) :: fqs_fluct_old + real(wp), intent(in) :: dt_loc + real(wp), dimension(3), intent(out) :: fqs_fluct_new + real(wp) :: upmean, vpmean, wpmean + real(wp) :: u2pmean, v2pmean, w2pmean + real(wp) :: rphip, rep, rmachp, theta, chi, tF_inv + real(wp) :: fq, bq, Fs, sigD, sigT + real(wp) :: aSDE, bSDE_CD, bSDE_CL + real(wp) :: CD_prime, CD_frac, sigmoid_cf, f_CF + real(wp) :: Z1, Z2, dW1, dW2, cosrand, sinrand + real(wp), dimension(3) :: avec, bvec, cvec, dvec, eunit + real(wp), dimension(3) :: slip_vel + real(wp) :: denum, TwoPi + real(wp), dimension(5) :: UnifRnd + + fqs_fluct_new = 0._wp + + upmean = vel_p_mean(1) + vpmean = vel_p_mean(2) + wpmean = vel_p_mean(3) + + u2pmean = vel2_p_mean(1) + v2pmean = vel2_p_mean(2) + w2pmean = vel2_p_mean(3) + + TwoPi = 2._wp*pi + + ! Particle phase properties + rphip = vol_frac ! particle volume fraction + slip_vel = fluid_vel - vel_p + + ! Particle Reynolds number + rep = rho_fluid*vmag*particle_diam/gas_mu + + ! Particle Mach number + rmachp = vmag/cson + + ! Granular temperature from Eulerian fields \theta = ( - ^2) / 3 + theta = ((u2pmean + v2pmean + w2pmean) - (upmean**2 + vpmean**2 + wpmean**2))/3._wp + + if (theta <= 1.e-12_wp) theta = 0._wp + + ! Fluctuating drag magnitude (Osnes Eqs 9-12) + fq = 6.52_wp*rphip - 22.56_wp*(rphip**2) + 49.90_wp*(rphip**3) + Fs = 3._wp*pi*gas_mu*particle_diam*(1._wp + 0.15_wp*((rep*(1._wp - rphip))**0.687_wp))*(1._wp - rphip)*vmag + bq = min(sqrt(20._wp*rmachp), 1._wp)*0.55_wp*(rphip**0.7_wp)*(1._wp + tanh((rmachp - 0.5_wp)/0.2_wp)) + sigD = (fq + bq)*Fs + + ! Granular kinetic theory relaxation rate + chi = (1._wp + 2.50_wp*rphip + 4.51_wp*(rphip**2) + 4.52_wp*(rphip**3))/((1._wp - (rphip/0.64_wp)**3)**0.68_wp) + tF_inv = (24._wp*rphip*chi/particle_diam)*sqrt(theta/pi) + + ! SDE coefficients + aSDE = tF_inv + bSDE_CD = sigD*sqrt(2._wp*tF_inv) + + ! Unit slip velocity direction + if (vmag > 1.e-8_wp) then + avec = slip_vel/vmag + + ! Project old fluctuating force onto slip direction + CD_prime = fqs_fluct_old(1)*avec(1) + fqs_fluct_old(2)*avec(2) + fqs_fluct_old(3)*avec(3) + CD_frac = CD_prime/max(sigD, 1.e-30_wp) + else + avec = [1._wp, 0._wp, 0._wp] + CD_prime = 0._wp + sigD = 0._wp + CD_frac = 0._wp + end if + + ! Perpendicular fluctuation magnitude + sigmoid_cf = 1._wp/(1._wp + exp(-CD_frac)) + f_CF = 0.39356905_wp*sigmoid_cf + 0.43758848_wp + sigT = f_CF*sigD + bSDE_CL = sigT*sqrt(2._wp*tF_inv) + + ! Build orthogonal basis + eunit = [1._wp, 0._wp, 0._wp] + if (abs(avec(2)) + abs(avec(3)) <= 1.e-8_wp) then + eunit = [0._wp, 1._wp, 0._wp] + else if (abs(avec(1)) + abs(avec(3)) <= 1.e-8_wp) then + eunit = [0._wp, 0._wp, 1._wp] + end if + + ! bvec = avec x eunit + bvec(1) = avec(2)*eunit(3) - avec(3)*eunit(2) + bvec(2) = avec(3)*eunit(1) - avec(1)*eunit(3) + bvec(3) = avec(1)*eunit(2) - avec(2)*eunit(1) + denum = max(1.e-8_wp, sqrt(bvec(1)**2 + bvec(2)**2 + bvec(3)**2)) + bvec = bvec/denum + + ! cvec = avec x bvec + cvec(1) = avec(2)*bvec(3) - avec(3)*bvec(2) + cvec(2) = avec(3)*bvec(1) - avec(1)*bvec(3) + cvec(3) = avec(1)*bvec(2) - avec(2)*bvec(1) + denum = max(1.e-8_wp, sqrt(cvec(1)**2 + cvec(2)**2 + cvec(3)**2)) + cvec = cvec/denum + + ! Generate random numbers + UnifRnd(1) = f_model_random_number(seed) + UnifRnd(2) = f_model_random_number(seed) + UnifRnd(3) = f_model_random_number(seed) + UnifRnd(4) = f_model_random_number(seed) + UnifRnd(5) = f_model_random_number(seed) + + UnifRnd(1) = max(UnifRnd(1), 1.e-30_wp) + UnifRnd(3) = max(UnifRnd(3), 1.e-30_wp) + + ! Box-Muller transform + Z1 = sqrt(-2._wp*log(UnifRnd(1)))*cos(TwoPi*UnifRnd(2)) + Z2 = sqrt(-2._wp*log(UnifRnd(3)))*cos(TwoPi*UnifRnd(4)) + + ! Scaled stochastic increments + dW1 = sqrt(dt_loc)*Z1 + dW2 = sqrt(dt_loc)*Z2 + + ! Random perpendicular direction + cosrand = cos(TwoPi*UnifRnd(5)) + sinrand = sin(TwoPi*UnifRnd(5)) + dvec = bvec*cosrand + cvec*sinrand + denum = max(1.e-8_wp, sqrt(dvec(1)**2 + dvec(2)**2 + dvec(3)**2)) + dvec = dvec/denum + + ! Ornstein-Uhlenbeck update + fqs_fluct_new(1) = (1._wp - aSDE*dt_loc)*fqs_fluct_old(1) + bSDE_CD*dW1*avec(1) + bSDE_CL*dW2*dvec(1) + fqs_fluct_new(2) = (1._wp - aSDE*dt_loc)*fqs_fluct_old(2) + bSDE_CD*dW1*avec(2) + bSDE_CL*dW2*dvec(2) + if (num_dims == 3) then + fqs_fluct_new(3) = (1._wp - aSDE*dt_loc)*fqs_fluct_old(3) + bSDE_CD*dW1*avec(3) + bSDE_CL*dW2*dvec(3) + end if + + end subroutine s_compute_qs_fluctuations + !> Interpolate an Eulerian field to a particle position using barycentric Lagrange interpolation with precomputed weights. Falls !! back to nearest-cell value if the interpolant is non-finite. !! @param pos Particle position diff --git a/src/simulation/m_rhs.fpp b/src/simulation/m_rhs.fpp index e61da866a6..bdcf8c8fb5 100644 --- a/src/simulation/m_rhs.fpp +++ b/src/simulation/m_rhs.fpp @@ -865,8 +865,8 @@ contains if (particles_lagrange) then ! Compute particle dynamics, forces, dvdt call nvtxStartRange("RHS-EL-PARTICLES-DYN") - call s_compute_particle_EL_dynamics(q_prim_qp%vf(1:sys_size), bc_type, stage, qL_rsx_vf, qL_rsy_vf, qL_rsz_vf, & - & qR_rsx_vf, qR_rsy_vf, qR_rsz_vf, rhs_vf) + call s_compute_particle_EL_dynamics(q_cons_qp%vf(1:sys_size), q_prim_qp%vf(1:sys_size), bc_type, stage, qL_rsx_vf, & + & qL_rsy_vf, qL_rsz_vf, qR_rsx_vf, qR_rsy_vf, qR_rsz_vf, rhs_vf) call nvtxEndRange ! RHS additions for sub-grid particles_lagrange diff --git a/toolchain/mfc/params/definitions.py b/toolchain/mfc/params/definitions.py index a193d9df49..558bdbf159 100644 --- a/toolchain/mfc/params/definitions.py +++ b/toolchain/mfc/params/definitions.py @@ -1160,8 +1160,8 @@ def _load(): ]: _r(f"bub_pp%{a}", REAL, {"bubbles"}, math=sym) - # particle_pp (particle properties) - for a in ["rho0ref_particle", "cp_particle"]: + # --- particle_pp (particle properties) --- + for a in ["rho0ref_particle", "cp_particle", "ksp_col", "nu_col", "E_col", "cor_col"]: _r(f"particle_pp%{a}", REAL, {"particles"}) # patch_ib (immersed boundaries) — registered as indexed family for O(1) lookup. @@ -1285,8 +1285,11 @@ def _load(): for a in ["nParticles_glb", "stokes_drag", "qs_drag_model", "added_mass_model", "interpolation_order"]: _r(f"lag_params%{a}", INT, {"particles"}) - for a in ["collision_force"]: - _r(f"lag_params%{a}", LOG, {"particles"}) + for a in ["collision_force", "qs_fluct_force"]: + _r(f"lag_params%{a}", LOG, {'particles'}) + + for a in ["mu_ref"]: + _r(f"lag_params%{a}", REAL, {'particles'}) # chem_params for a in ["diffusion", "reactions"]: From 3cb6462bc39b3e7d185974ed76b86d1ab9914c9e Mon Sep 17 00:00:00 2001 From: Spencer Bryngelson Date: Fri, 27 Mar 2026 21:52:02 -0400 Subject: [PATCH 11/14] comment cleanup --- src/common/m_boundary_common.fpp | 147 +++++++++++------------- src/pre_process/m_global_parameters.fpp | 45 ++------ src/simulation/m_data_output.fpp | 101 +++------------- src/simulation/m_global_parameters.fpp | 31 +---- src/simulation/m_ib_patches.fpp | 110 ++++-------------- src/simulation/m_ibm.fpp | 3 +- src/simulation/m_sim_helpers.fpp | 51 +------- src/simulation/m_time_steppers.fpp | 11 +- 8 files changed, 128 insertions(+), 371 deletions(-) diff --git a/src/common/m_boundary_common.fpp b/src/common/m_boundary_common.fpp index e86aea1303..c293ba2b5d 100644 --- a/src/common/m_boundary_common.fpp +++ b/src/common/m_boundary_common.fpp @@ -1,8 +1,8 @@ !> !! @file -!! @brief Contains module m_boundary_common +!! Contains module m_boundary_common -!> @brief Noncharacteristic and processor boundary condition application for ghost cells and buffer regions +!> Noncharacteristic and processor boundary condition application for ghost cells and buffer regions #:include 'case.fpp' #:include 'macros.fpp' @@ -42,7 +42,7 @@ module m_boundary_common contains - !> @brief Allocates and sets up boundary condition buffer arrays for all coordinate directions. + !> Allocates and sets up boundary condition buffer arrays for all coordinate directions. impure subroutine s_initialize_boundary_common_module() integer :: i, j @@ -89,8 +89,7 @@ contains end subroutine s_initialize_boundary_common_module - !> The purpose of this procedure is to populate the buffers of the primitive variables, depending on the selected boundary - !! conditions. + !> Populate the buffers of the primitive variables based on the selected boundary conditions. impure subroutine s_populate_variables_buffers(bc_type, q_prim_vf, pb_in, mv_in) type(scalar_field), dimension(sys_size), intent(inout) :: q_prim_vf @@ -98,7 +97,6 @@ contains type(integer_field), dimension(1:num_dims,1:2), intent(in) :: bc_type integer :: k, l - ! Population of Buffers in x-direction if (bc_x%beg >= 0) then call s_mpi_sendrecv_variables_buffers(q_prim_vf, 1, -1, sys_size, pb_in, mv_in) @@ -158,7 +156,6 @@ contains $:END_GPU_PARALLEL_LOOP() end if - ! Population of Buffers in y-direction if (n == 0) return @@ -225,7 +222,6 @@ contains end if #:endif - ! Population of Buffers in z-direction if (p == 0) return @@ -261,7 +257,7 @@ contains if (bc_z%end >= 0) then call s_mpi_sendrecv_variables_buffers(q_prim_vf, 3, 1, sys_size, pb_in, mv_in) - else !< bc_x%end + else !< bc_z%end $:GPU_PARALLEL_LOOP(private='[l, k]', collapse=2) do l = -buff_size, n + buff_size do k = -buff_size, m + buff_size @@ -288,11 +284,10 @@ contains $:END_GPU_PARALLEL_LOOP() end if #:endif - ! END: Population of Buffers in z-direction end subroutine s_populate_variables_buffers - !> @brief Fills ghost cells by copying the nearest boundary cell value along the specified direction. + !> Fills ghost cells by copying the nearest boundary cell value along the specified direction. subroutine s_ghost_cell_extrapolation(q_prim_vf, bc_dir, bc_loc, k, l) $:GPU_ROUTINE(function_name='s_ghost_cell_extrapolation', parallelism='[seq]', cray_inline=True) @@ -308,7 +303,7 @@ contains q_prim_vf(i)%sf(-j, k, l) = q_prim_vf(i)%sf(0, k, l) end do end do - else !< bc_y%end + else !< bc_x%end do i = 1, sys_size do j = 1, buff_size q_prim_vf(i)%sf(m + j, k, l) = q_prim_vf(i)%sf(m, k, l) @@ -322,7 +317,7 @@ contains q_prim_vf(i)%sf(k, -j, l) = q_prim_vf(i)%sf(k, 0, l) end do end do - else !< bc_z%end + else !< bc_y%end do i = 1, sys_size do j = 1, buff_size q_prim_vf(i)%sf(k, n + j, l) = q_prim_vf(i)%sf(k, n, l) @@ -336,7 +331,7 @@ contains q_prim_vf(i)%sf(k, l, -j) = q_prim_vf(i)%sf(k, l, 0) end do end do - else !< bc_x%end + else !< bc_z%end do i = 1, sys_size do j = 1, buff_size q_prim_vf(i)%sf(k, l, p + j) = q_prim_vf(i)%sf(k, l, p) @@ -347,8 +342,7 @@ contains end subroutine s_ghost_cell_extrapolation - !> @brief Applies reflective (symmetry) boundary conditions by mirroring primitive variables and flipping the normal velocity - !! component. + !> Applies reflective (symmetry) boundary conditions by mirroring primitive variables and flipping the normal velocity component. subroutine s_symmetry(q_prim_vf, bc_dir, bc_loc, k, l, pb_in, mv_in) $:GPU_ROUTINE(parallelism='[seq]') @@ -393,7 +387,7 @@ contains end do end do end if - else !< bc_y%end + else !< bc_x%end do j = 1, buff_size do i = 1, contxe q_prim_vf(i)%sf(m + j, k, l) = q_prim_vf(i)%sf(m - (j - 1), k, l) @@ -462,7 +456,7 @@ contains end do end do end if - else !< bc_z%end + else !< bc_y%end do j = 1, buff_size do i = 1, momxb q_prim_vf(i)%sf(k, n + j, l) = q_prim_vf(i)%sf(k, n - (j - 1), l) @@ -532,7 +526,7 @@ contains end do end do end if - else !< bc_x%end + else !< bc_z%end do j = 1, buff_size do i = 1, momxb + 1 q_prim_vf(i)%sf(k, l, p + j) = q_prim_vf(i)%sf(k, l, p - (j - 1)) @@ -571,7 +565,7 @@ contains end subroutine s_symmetry - !> @brief Applies periodic boundary conditions by copying values from the opposite domain boundary. + !> Applies periodic boundary conditions by copying values from the opposite domain boundary. subroutine s_periodic(q_prim_vf, bc_dir, bc_loc, k, l, pb_in, mv_in) $:GPU_ROUTINE(parallelism='[seq]') @@ -599,7 +593,7 @@ contains end do end do end if - else !< bc_y%end + else !< bc_x%end do i = 1, sys_size do j = 1, buff_size q_prim_vf(i)%sf(m + j, k, l) = q_prim_vf(i)%sf(j - 1, k, l) @@ -635,7 +629,7 @@ contains end do end do end if - else !< bc_z%end + else !< bc_y%end do i = 1, sys_size do j = 1, buff_size q_prim_vf(i)%sf(k, n + j, l) = q_prim_vf(i)%sf(k, j - 1, l) @@ -671,7 +665,7 @@ contains end do end do end if - else + else !< bc_z%end do i = 1, sys_size do j = 1, buff_size q_prim_vf(i)%sf(k, l, p + j) = q_prim_vf(i)%sf(k, l, j - 1) @@ -693,8 +687,7 @@ contains end subroutine s_periodic - !> @brief Applies axis boundary conditions for cylindrical coordinates by reflecting values across the axis with azimuthal phase - !! shift. + !> Applies axis boundary conditions for cylindrical coordinates by reflecting values across the axis with azimuthal phase shift. subroutine s_axis(q_prim_vf, pb_in, mv_in, k, l) $:GPU_ROUTINE(parallelism='[seq]') @@ -744,7 +737,7 @@ contains end subroutine s_axis - !> @brief Applies slip wall boundary conditions by extrapolating scalars and reflecting the wall-normal velocity component. + !> Applies slip wall boundary conditions by extrapolating scalars and reflecting the wall-normal velocity component. subroutine s_slip_wall(q_prim_vf, bc_dir, bc_loc, k, l) $:GPU_ROUTINE(function_name='s_slip_wall',parallelism='[seq]', cray_inline=True) @@ -759,12 +752,12 @@ contains do j = 1, buff_size if (i == momxb) then q_prim_vf(i)%sf(-j, k, l) = -q_prim_vf(i)%sf(j - 1, k, l) + 2._wp*bc_x%vb1 - else !< bc_x%end + else q_prim_vf(i)%sf(-j, k, l) = q_prim_vf(i)%sf(0, k, l) end if end do end do - else + else !< bc_x%end do i = 1, sys_size do j = 1, buff_size if (i == momxb) then @@ -781,12 +774,12 @@ contains do j = 1, buff_size if (i == momxb + 1) then q_prim_vf(i)%sf(k, -j, l) = -q_prim_vf(i)%sf(k, j - 1, l) + 2._wp*bc_y%vb2 - else !< bc_y%end + else q_prim_vf(i)%sf(k, -j, l) = q_prim_vf(i)%sf(k, 0, l) end if end do end do - else + else !< bc_y%end do i = 1, sys_size do j = 1, buff_size if (i == momxb + 1) then @@ -803,12 +796,12 @@ contains do j = 1, buff_size if (i == momxe) then q_prim_vf(i)%sf(k, l, -j) = -q_prim_vf(i)%sf(k, l, j - 1) + 2._wp*bc_z%vb3 - else !< bc_z%end + else q_prim_vf(i)%sf(k, l, -j) = q_prim_vf(i)%sf(k, l, 0) end if end do end do - else + else !< bc_z%end do i = 1, sys_size do j = 1, buff_size if (i == momxe) then @@ -823,7 +816,7 @@ contains end subroutine s_slip_wall - !> @brief Applies no-slip wall boundary conditions by reflecting and negating all velocity components at the wall. + !> Applies no-slip wall boundary conditions by reflecting and negating all velocity components at the wall. subroutine s_no_slip_wall(q_prim_vf, bc_dir, bc_loc, k, l) $:GPU_ROUTINE(function_name='s_no_slip_wall',parallelism='[seq]', cray_inline=True) @@ -843,12 +836,12 @@ contains q_prim_vf(i)%sf(-j, k, l) = -q_prim_vf(i)%sf(j - 1, k, l) + 2._wp*bc_x%vb2 else if (i == momxb + 2 .and. num_dims > 2) then q_prim_vf(i)%sf(-j, k, l) = -q_prim_vf(i)%sf(j - 1, k, l) + 2._wp*bc_x%vb3 - else !< bc_x%end + else q_prim_vf(i)%sf(-j, k, l) = q_prim_vf(i)%sf(0, k, l) end if end do end do - else + else !< bc_x%end do i = 1, sys_size do j = 1, buff_size if (i == momxb) then @@ -873,12 +866,12 @@ contains q_prim_vf(i)%sf(k, -j, l) = -q_prim_vf(i)%sf(k, j - 1, l) + 2._wp*bc_y%vb2 else if (i == momxb + 2 .and. num_dims > 2) then q_prim_vf(i)%sf(k, -j, l) = -q_prim_vf(i)%sf(k, j - 1, l) + 2._wp*bc_y%vb3 - else !< bc_y%end + else q_prim_vf(i)%sf(k, -j, l) = q_prim_vf(i)%sf(k, 0, l) end if end do end do - else + else !< bc_y%end do i = 1, sys_size do j = 1, buff_size if (i == momxb) then @@ -903,12 +896,12 @@ contains q_prim_vf(i)%sf(k, l, -j) = -q_prim_vf(i)%sf(k, l, j - 1) + 2._wp*bc_z%vb2 else if (i == momxb + 2 .and. num_dims > 2) then q_prim_vf(i)%sf(k, l, -j) = -q_prim_vf(i)%sf(k, l, j - 1) + 2._wp*bc_z%vb3 - else !< bc_z%end + else q_prim_vf(i)%sf(k, l, -j) = q_prim_vf(i)%sf(k, l, 0) end if end do end do - else + else !< bc_z%end do i = 1, sys_size do j = 1, buff_size if (i == momxb) then @@ -917,7 +910,7 @@ contains q_prim_vf(i)%sf(k, l, p + j) = -q_prim_vf(i)%sf(k, l, p - (j - 1)) + 2._wp*bc_z%ve2 else if (i == momxb + 2 .and. num_dims > 2) then q_prim_vf(i)%sf(k, l, p + j) = -q_prim_vf(i)%sf(k, l, p - (j - 1)) + 2._wp*bc_z%ve3 - else !< bc_x%end + else q_prim_vf(i)%sf(k, l, p + j) = q_prim_vf(i)%sf(k, l, p) end if end do @@ -927,7 +920,7 @@ contains end subroutine s_no_slip_wall - !> @brief Applies Dirichlet boundary conditions by prescribing ghost cell values from stored boundary buffers. + !> Applies Dirichlet boundary conditions by prescribing ghost cell values from stored boundary buffers. subroutine s_dirichlet(q_prim_vf, bc_dir, bc_loc, k, l) $:GPU_ROUTINE(function_name='s_dirichlet',parallelism='[seq]', cray_inline=True) @@ -944,7 +937,7 @@ contains q_prim_vf(i)%sf(-j, k, l) = bc_buffers(1, 1)%sf(i, k, l) end do end do - else !< bc_y%end + else !< bc_x%end do i = 1, sys_size do j = 1, buff_size q_prim_vf(i)%sf(m + j, k, l) = bc_buffers(1, 2)%sf(i, k, l) @@ -959,7 +952,7 @@ contains q_prim_vf(i)%sf(k, -j, l) = bc_buffers(2, 1)%sf(k, i, l) end do end do - else !< bc_z%end + else !< bc_y%end do i = 1, sys_size do j = 1, buff_size q_prim_vf(i)%sf(k, n + j, l) = bc_buffers(2, 2)%sf(k, i, l) @@ -975,7 +968,7 @@ contains q_prim_vf(i)%sf(k, l, -j) = bc_buffers(3, 1)%sf(k, l, i) end do end do - else !< bc_x%end + else !< bc_z%end do i = 1, sys_size do j = 1, buff_size q_prim_vf(i)%sf(k, l, p + j) = bc_buffers(3, 2)%sf(k, l, i) @@ -990,7 +983,7 @@ contains end subroutine s_dirichlet - !> @brief Extrapolates QBMM bubble pressure and mass-vapor variables into ghost cells by copying boundary values. + !> Extrapolates QBMM bubble pressure and mass-vapor variables into ghost cells by copying boundary values. subroutine s_qbmm_extrapolation(bc_dir, bc_loc, k, l, pb_in, mv_in) $:GPU_ROUTINE(parallelism='[seq]') @@ -1009,7 +1002,7 @@ contains end do end do end do - else !< bc_y%end + else !< bc_x%end do i = 1, nb do q = 1, nnode do j = 1, buff_size @@ -1029,7 +1022,7 @@ contains end do end do end do - else !< bc_z%end + else !< bc_y%end do i = 1, nb do q = 1, nnode do j = 1, buff_size @@ -1049,7 +1042,7 @@ contains end do end do end do - else + else !< bc_z%end do i = 1, nb do q = 1, nnode do j = 1, buff_size @@ -1315,7 +1308,7 @@ contains q_beta(beta_vars(i))%sf(k, l, -j) = 0._wp end do end do - else !< bc_x%end + else !< bc_z%end do i = 1, nvar do j = 1, buff_size q_beta(beta_vars(i))%sf(k, l, p + j) = 0._wp @@ -1355,7 +1348,7 @@ contains kahan_comp(beta_vars(i))%sf(-j, k, l) = kahan_comp(beta_vars(i))%sf(j - 1, k, l) end do end do - else !< bc_y%end + else !< bc_x%end do i = 1, nvar do j = 1, mapCells + 1 y_kahan = real(q_beta(beta_vars(i))%sf(m + j, k, l), kind=wp) + kahan_comp(beta_vars(i))%sf(m + j, k, & @@ -1386,7 +1379,7 @@ contains kahan_comp(beta_vars(i))%sf(k, -j, l) = kahan_comp(beta_vars(i))%sf(k, j - 1, l) end do end do - else !< bc_z%end + else !< bc_y%end do i = 1, nvar do j = 1, mapCells + 1 y_kahan = real(q_beta(beta_vars(i))%sf(k, n + j, l), kind=wp) + kahan_comp(beta_vars(i))%sf(k, n + j, & @@ -1417,7 +1410,7 @@ contains kahan_comp(beta_vars(i))%sf(k, l, -j) = kahan_comp(beta_vars(i))%sf(k, l, j - 1) end do end do - else + else !< bc_z%end do i = 1, nvar do j = 1, mapCells + 1 y_kahan = real(q_beta(beta_vars(i))%sf(k, l, p + j), kind=wp) + kahan_comp(beta_vars(i))%sf(k, l, & @@ -1437,7 +1430,7 @@ contains end subroutine s_beta_reflective - !> @brief Populates ghost cell buffers for the color function and its divergence used in capillary surface tension. + !> Populates ghost cell buffers for the color function and its divergence used in capillary surface tension. impure subroutine s_populate_capillary_buffers(c_divs, bc_type) type(scalar_field), dimension(num_dims + 1), intent(inout) :: c_divs @@ -1448,7 +1441,7 @@ contains if (bc_x%beg >= 0) then call s_mpi_sendrecv_variables_buffers(c_divs, 1, -1, num_dims + 1) - else !< bc_x%end + else $:GPU_PARALLEL_LOOP(private='[l, k]', collapse=2) do l = 0, p do k = 0, n @@ -1509,7 +1502,7 @@ contains if (bc_y%end >= 0) then call s_mpi_sendrecv_variables_buffers(c_divs, 2, 1, num_dims + 1) - else !< bc_y%end + else $:GPU_PARALLEL_LOOP(private='[l, k]', collapse=2) do l = 0, p do k = -buff_size, m + buff_size @@ -1572,7 +1565,7 @@ contains end subroutine s_populate_capillary_buffers - !> @brief Applies periodic boundary conditions to the color function and its divergence fields. + !> Applies periodic boundary conditions to the color function and its divergence fields. subroutine s_color_function_periodic(c_divs, bc_dir, bc_loc, k, l) $:GPU_ROUTINE(function_name='s_color_function_periodic', parallelism='[seq]', cray_inline=True) @@ -1588,7 +1581,7 @@ contains c_divs(i)%sf(-j, k, l) = c_divs(i)%sf(m - (j - 1), k, l) end do end do - else !< bc_z%end + else !< bc_x%end do i = 1, num_dims + 1 do j = 1, buff_size c_divs(i)%sf(m + j, k, l) = c_divs(i)%sf(j - 1, k, l) @@ -1602,7 +1595,7 @@ contains c_divs(i)%sf(k, -j, l) = c_divs(i)%sf(k, n - (j - 1), l) end do end do - else + else !< bc_y%end do i = 1, num_dims + 1 do j = 1, buff_size c_divs(i)%sf(k, n + j, l) = c_divs(i)%sf(k, j - 1, l) @@ -1616,7 +1609,7 @@ contains c_divs(i)%sf(k, l, -j) = c_divs(i)%sf(k, l, p - (j - 1)) end do end do - else !< bc_x%end + else !< bc_z%end do i = 1, num_dims + 1 do j = 1, buff_size c_divs(i)%sf(k, l, p + j) = c_divs(i)%sf(k, l, j - 1) @@ -1627,7 +1620,7 @@ contains end subroutine s_color_function_periodic - !> @brief Applies reflective boundary conditions to the color function and its divergence fields. + !> Applies reflective boundary conditions to the color function and its divergence fields. subroutine s_color_function_reflective(c_divs, bc_dir, bc_loc, k, l) $:GPU_ROUTINE(function_name='s_color_function_reflective', parallelism='[seq]', cray_inline=True) @@ -1642,12 +1635,12 @@ contains do j = 1, buff_size if (i == bc_dir) then c_divs(i)%sf(-j, k, l) = -c_divs(i)%sf(j - 1, k, l) - else !< bc_y%end + else c_divs(i)%sf(-j, k, l) = c_divs(i)%sf(j - 1, k, l) end if end do end do - else !< bc_z%end + else !< bc_x%end do i = 1, num_dims + 1 do j = 1, buff_size if (i == bc_dir) then @@ -1669,7 +1662,7 @@ contains end if end do end do - else + else !< bc_y%end do i = 1, num_dims + 1 do j = 1, buff_size if (i == bc_dir) then @@ -1691,7 +1684,7 @@ contains end if end do end do - else + else !< bc_z%end do i = 1, num_dims + 1 do j = 1, buff_size if (i == bc_dir) then @@ -1706,7 +1699,7 @@ contains end subroutine s_color_function_reflective - !> @brief Extrapolates the color function and its divergence into ghost cells by copying boundary values. + !> Extrapolates the color function and its divergence into ghost cells by copying boundary values. subroutine s_color_function_ghost_cell_extrapolation(c_divs, bc_dir, bc_loc, k, l) $:GPU_ROUTINE(function_name='s_color_function_ghost_cell_extrapolation', parallelism='[seq]', cray_inline=True) @@ -1761,7 +1754,7 @@ contains end subroutine s_color_function_ghost_cell_extrapolation - !> @brief Populates ghost cell buffers for the Jacobian scalar field used in the IGR elliptic solver. + !> Populates ghost cell buffers for the Jacobian scalar field used in the IGR elliptic solver. impure subroutine s_populate_F_igr_buffers(bc_type, jac_sf) type(integer_field), dimension(1:num_dims,1:2), intent(in) :: bc_type @@ -1928,7 +1921,7 @@ contains end subroutine s_populate_F_igr_buffers - !> @brief Creates MPI derived datatypes for boundary condition type arrays and buffer arrays used in parallel I/O. + !> Creates MPI derived datatypes for boundary condition type arrays and buffer arrays used in parallel I/O. impure subroutine s_create_mpi_types(bc_type) type(integer_field), dimension(1:num_dims,1:2), intent(in) :: bc_type @@ -1963,7 +1956,7 @@ contains end subroutine s_create_mpi_types - !> @brief Writes boundary condition type and buffer data to serial (unformatted) restart files. + !> Writes boundary condition type and buffer data to serial (unformatted) restart files. subroutine s_write_serial_boundary_condition_files(q_prim_vf, bc_type, step_dirpath, old_grid_in) type(scalar_field), dimension(sys_size), intent(in) :: q_prim_vf @@ -2002,7 +1995,7 @@ contains end subroutine s_write_serial_boundary_condition_files - !> @brief Writes boundary condition type and buffer data to per-rank parallel files using MPI I/O. + !> Writes boundary condition type and buffer data to per-rank parallel files using MPI I/O. subroutine s_write_parallel_boundary_condition_files(q_prim_vf, bc_type) type(scalar_field), dimension(sys_size), intent(in) :: q_prim_vf @@ -2067,7 +2060,7 @@ contains end subroutine s_write_parallel_boundary_condition_files - !> @brief Reads boundary condition type and buffer data from serial (unformatted) restart files. + !> Reads boundary condition type and buffer data from serial (unformatted) restart files. subroutine s_read_serial_boundary_condition_files(step_dirpath, bc_type) character(LEN=*), intent(in) :: step_dirpath @@ -2112,7 +2105,7 @@ contains end subroutine s_read_serial_boundary_condition_files - !> @brief Reads boundary condition type and buffer data from per-rank parallel files using MPI I/O. + !> Reads boundary condition type and buffer data from per-rank parallel files using MPI I/O. subroutine s_read_parallel_boundary_condition_files(bc_type) type(integer_field), dimension(1:num_dims,1:2), intent(inout) :: bc_type @@ -2177,7 +2170,7 @@ contains end subroutine s_read_parallel_boundary_condition_files - !> @brief Packs primitive variable boundary slices into bc_buffers arrays for serialization. + !> Packs primitive variable boundary slices into bc_buffers arrays for serialization. subroutine s_pack_boundary_condition_buffers(q_prim_vf) type(scalar_field), dimension(sys_size), intent(in) :: q_prim_vf @@ -2220,7 +2213,7 @@ contains end subroutine s_pack_boundary_condition_buffers - !> @brief Initializes the per-cell boundary condition type arrays with the global default BC values. + !> Initializes the per-cell boundary condition type arrays with the global default BC values. subroutine s_assign_default_bc_type(bc_type) type(integer_field), dimension(1:num_dims,1:2), intent(in) :: bc_type @@ -2285,7 +2278,6 @@ contains #endif #ifndef MFC_PRE_PROCESS - ! Population of Buffers in x-direction ! Populating cell-width distribution buffer at bc_x%beg if (bc_x%beg >= 0) then @@ -2338,9 +2330,7 @@ contains do i = 1, buff_size x_cc(m + i) = x_cc(m + (i - 1)) + (dx(m + (i - 1)) + dx(m + i))/2._wp end do - ! END: Population of Buffers in x-direction - ! Population of Buffers in y-direction ! Populating cell-width distribution buffer at bc_y%beg if (n == 0) then @@ -2395,9 +2385,7 @@ contains do i = 1, buff_size y_cc(n + i) = y_cc(n + (i - 1)) + (dy(n + (i - 1)) + dy(n + i))/2._wp end do - ! END: Population of Buffers in y-direction - ! Population of Buffers in z-direction ! Populating cell-width distribution buffer at bc_z%beg if (p == 0) then @@ -2452,12 +2440,11 @@ contains do i = 1, buff_size z_cc(p + i) = z_cc(p + (i - 1)) + (dz(p + (i - 1)) + dz(p + i))/2._wp end do - ! END: Population of Buffers in z-direction #endif end subroutine s_populate_grid_variables_buffers - !> @brief Deallocates boundary condition buffer arrays allocated during module initialization. + !> Deallocates boundary condition buffer arrays allocated during module initialization. subroutine s_finalize_boundary_common_module() if (bc_io) then diff --git a/src/pre_process/m_global_parameters.fpp b/src/pre_process/m_global_parameters.fpp index 118add7996..01e31ad0ed 100644 --- a/src/pre_process/m_global_parameters.fpp +++ b/src/pre_process/m_global_parameters.fpp @@ -1,10 +1,10 @@ !> !! @file -!! @brief Contains module m_global_parameters +!! Contains module m_global_parameters #:include 'case.fpp' -!> @brief Defines global parameters for the computational domain, simulation algorithm, and initial conditions +!> Defines global parameters for the computational domain, simulation algorithm, and initial conditions module m_global_parameters #ifdef MFC_MPI @@ -113,13 +113,8 @@ module m_global_parameters ! idwint are the same otherwise. Stands for "InDices With BUFFer". type(int_bounds_info) :: idwbuff(1:3) - !> The order of the finite-difference (fd) approximations of the first-order derivatives that need to be evaluated when the CoM - !! or flow probe data files are to be written at each time step - integer :: fd_order - - !> The finite-difference number is given by MAX(1, fd_order/2). Essentially, it is a measure of the half-size of the - !! finite-difference stencil for the selected order of accuracy. - integer :: fd_number + integer :: fd_order !< Finite-difference order for CoM/probe derivative approximations + integer :: fd_number !< FD half-stencil size: MAX(1, fd_order/2) !> @name lagrangian subgrid bubble parameters !> @{! @@ -130,8 +125,6 @@ module m_global_parameters integer :: shear_num !< Number of shear stress components integer, dimension(3) :: shear_indices !< Indices of the stress components that represent shear stress integer :: shear_BC_flip_num !< Number of shear stress components to reflect for boundary conditions - !> Indices of shear stress components to reflect for boundary conditions. Size: (1:3, 1:shear_BC_flip_num) for (x/y/z, - !! [indices]) integer, dimension(3, 2) :: shear_BC_flip_indices !< Shear stress BC reflection indices (1:3, 1:shear_BC_flip_num) logical :: parallel_io !< Format of the data files logical :: file_per_process !< type of data output @@ -141,8 +134,6 @@ module m_global_parameters real(wp) :: mixlayer_vel_coef !< Coefficient for the hyperbolic tangent streamwise velocity profile logical :: mixlayer_perturb !< Superimpose instability waves to surrounding fluid flow integer :: mixlayer_perturb_nk !< Number of Fourier modes for perturbation with mixlayer_perturb flag - !> Peak wavenumber of prescribed energy spectra with mixlayer_perturb flag Default value (k0 = 0.4446) is most unstable mode - !! obtained from linear stability analysis See Michalke (1964, JFM) for details real(wp) :: mixlayer_perturb_k0 !< Peak wavenumber for mixlayer perturbation (default: most unstable mode) logical :: simplex_perturb type(simplex_noise_params) :: simplex_params @@ -161,8 +152,7 @@ module m_global_parameters integer :: elliptic_smoothing_iters integer, allocatable, dimension(:) :: proc_coords !< Processor coordinates in MPI_CART_COMM type(int_bounds_info), dimension(3) :: nidx - integer, allocatable, dimension(:,:,:) :: neighbor_ranks - !! Neighbor ranks + integer, allocatable, dimension(:,:,:) :: neighbor_ranks !< Neighbor ranks integer, allocatable, dimension(:) :: start_idx !< Starting cell-center index of local processor in global grid @@ -175,19 +165,11 @@ module m_global_parameters ! Initial Condition Parameters integer :: num_patches !< Number of patches composing initial condition - !> Database of the initial condition patch parameters (icpp) for each of the patches employed in the configuration of the - !! initial condition. Note that the maximum allowable number of patches, num_patches_max, may be changed in the module - !! m_derived_types.f90. type(ic_patch_parameters), dimension(num_patches_max) :: patch_icpp !< IC patch parameters (max: num_patches_max) integer :: num_bc_patches !< Number of boundary condition patches logical :: bc_io !< whether or not to save BC data - !> Boundary condition patch parameters Database of the boundary condition patch parameters for each of the patches employed in - !! the configuration of the boundary conditions - type(bc_patch_parameters), dimension(num_bc_patches_max) :: patch_bc + type(bc_patch_parameters), dimension(num_bc_patches_max) :: patch_bc !< BC patch parameters - ! Fluids Physical Parameters - !> Database of the physical parameters of each of the fluids that is present in the flow. These include the stiffened gas - !! equation of state parameters, and the Reynolds numbers. type(physical_parameters), dimension(num_fluids_max) :: fluid_pp !< Stiffened gas EOS parameters and Reynolds numbers per fluid ! Subgrid Bubble Parameters @@ -213,9 +195,7 @@ module m_global_parameters integer :: Np type(ib_patch_parameters), dimension(num_patches_max) :: patch_ib !< Immersed boundary patch parameters type(vec3_dt), allocatable, dimension(:) :: airfoil_grid_u, airfoil_grid_l - !! Database of the immersed boundary patch parameters for each of the patches employed in the configuration of the initial - !! condition. Note that the maximum allowable number of patches, num_patches_max, may be changed in the module - !! m_derived_types.f90. + ! IB patch parameters database (max count: num_patches_max in m_derived_types.f90). !> @} !> @name Non-polytropic bubble gas compression @@ -255,12 +235,8 @@ module m_global_parameters type(pres_field) :: mv real(wp) :: Bx0 !< Constant magnetic field in the x-direction (1D) - !> The number of cells that are necessary to be able to store enough boundary conditions data to march the solution in the - !! physical computational domain to the next time-step. integer :: buff_size !< Number of ghost cells for boundary condition storage logical :: fft_wrt - !> AMDFlang workaround: keep a dummy logical to avoid a compiler case-optimization bug when a parameter+GPU-kernel conditional - !! is false logical :: dummy !< AMDFlang workaround for case-optimization + GPU-kernel bug ! Variables for hardcoded initial conditions that are read from input files @@ -269,8 +245,7 @@ module m_global_parameters contains - !> Assigns default values to user inputs prior to reading them in. This allows for an easier consistency check of these - !! parameters once they are read from the input file. + !> Assigns default values to user inputs prior to reading them in. impure subroutine s_assign_default_values_to_user_inputs integer :: i !< Generic loop operator @@ -944,7 +919,7 @@ contains end subroutine s_initialize_global_parameters_module - !> @brief Configures MPI parallel I/O settings and allocates processor coordinate arrays. + !> Configures MPI parallel I/O settings and allocates processor coordinate arrays. impure subroutine s_initialize_parallel_io #ifdef MFC_MPI @@ -978,7 +953,7 @@ contains end subroutine s_initialize_parallel_io - !> @brief Deallocates all global grid, index, and equation-of-state parameter arrays. + !> Deallocates all global grid, index, and equation-of-state parameter arrays. impure subroutine s_finalize_global_parameters_module integer :: i diff --git a/src/simulation/m_data_output.fpp b/src/simulation/m_data_output.fpp index 0104dbfddb..59013b1196 100644 --- a/src/simulation/m_data_output.fpp +++ b/src/simulation/m_data_output.fpp @@ -1,11 +1,11 @@ !> !! @file -!! @brief Contains module m_data_output +!! Contains module m_data_output #:include 'macros.fpp' #:include 'case.fpp' -!> @brief Writes solution data, run-time stability diagnostics (ICFL, VCFL, CCFL, Rc), and probe/center-of-mass files +!> Writes solution data, run-time stability diagnostics (ICFL, VCFL, CCFL, Rc), and probe/center-of-mass files module m_data_output use m_derived_types @@ -46,12 +46,6 @@ module m_data_output contains !> Write data files. Dispatch subroutine that replaces procedure pointer. - !! @param q_cons_vf Conservative variables - !! @param q_T_sf Temperature scalar field - !! @param q_prim_vf Primitive variables - !! @param t_step Current time step - !! @param bc_type Boundary condition type - !! @param beta Eulerian void fraction from lagrangian bubbles impure subroutine s_write_data_files(q_cons_vf, q_T_sf, q_prim_vf, t_step, bc_type, beta) type(scalar_field), dimension(sys_size), intent(inout) :: q_cons_vf @@ -69,17 +63,13 @@ contains end subroutine s_write_data_files - !> The purpose of this subroutine is to open a new or pre- existing run-time information file and append to it the basic header - !! information relevant to current simulation. In general, this requires generating a table header for those stability criteria - !! which will be written at every time-step. + !> Open the run-time information file and write the stability criteria table header. impure subroutine s_open_run_time_information_file character(LEN=name_len), parameter :: file_name = 'run_time.inf' !< Name of the run-time information file character(LEN=path_len + name_len) :: file_path !< Relative path to a file in the case directory character(LEN=8) :: file_date !< Creation date of the run-time information file - ! Opening the run-time information file - file_path = trim(case_dir) // '/' // trim(file_name) open (3, FILE=trim(file_path), form='formatted', STATUS='replace') @@ -97,7 +87,6 @@ contains write (3, '(A)') ''; write (3, '(A)') '' - ! Generating table header for the stability criteria to be outputted write (3, '(13X,A9,13X,A10,13X,A10,13X,A10)', advance="no") trim('Time-step'), trim('dt'), trim('Time'), trim('ICFL Max') if (viscous) then @@ -184,11 +173,7 @@ contains end subroutine s_open_ib_state_file - !> The goal of the procedure is to output to the run-time information file the stability criteria extrema in the entire - !! computational domain and at the given time-step. Moreover, the subroutine is also in charge of tracking these stability - !! criteria extrema over all time-steps. - !! @param q_prim_vf Cell-average primitive variables - !! @param t_step Current time step + !> Write stability criteria extrema to the run-time information file and track them over all time-steps. impure subroutine s_write_run_time_information(q_prim_vf, t_step) type(scalar_field), dimension(sys_size), intent(in) :: q_prim_vf @@ -264,7 +249,6 @@ contains if (Rc_min_glb < Rc_min) Rc_min = Rc_min_glb end if - ! Outputting global stability criteria extrema at current time-step if (proc_rank == 0) then write (3, '(13X,I9,13X,F10.6,13X,F10.6,13X,F10.6)', advance="no") t_step, dt, mytime, icfl_max_glb @@ -305,13 +289,7 @@ contains end subroutine s_write_run_time_information - !> The goal of this subroutine is to output the grid and conservative variables data files for given time-step. - !! @param q_cons_vf Cell-average conservative variables - !! @param q_T_sf Temperature scalar field - !! @param q_prim_vf Cell-average primitive variables - !! @param t_step Current time-step - !! @param bc_type Boundary condition type - !! @param beta Eulerian void fraction from lagrangian bubbles + !> Output the grid and conservative variables data files for the given time-step (serial). impure subroutine s_write_serial_data_files(q_cons_vf, q_T_sf, q_prim_vf, t_step, bc_type, beta) type(scalar_field), dimension(sys_size), intent(inout) :: q_cons_vf @@ -327,11 +305,9 @@ contains integer :: i, j, k, l, r real(wp) :: gamma, lit_gamma, pi_inf, qv !< Temporary EOS params - ! Creating or overwriting the time-step root directory write (t_step_dir, '(A,I0,A,I0)') trim(case_dir) // '/p_all' - ! Creating or overwriting the current time-step directory write (t_step_dir, '(a,i0,a,i0)') trim(case_dir) // '/p_all/p', proc_rank, '/', t_step file_path = trim(t_step_dir) // '/.' @@ -339,13 +315,11 @@ contains if (file_exist) call s_delete_directory(trim(t_step_dir)) call s_create_directory(trim(t_step_dir)) - ! Writing the grid data file in the x-direction file_path = trim(t_step_dir) // '/x_cb.dat' open (2, FILE=trim(file_path), form='unformatted', STATUS='new') write (2) x_cb(-1:m); close (2) - ! Writing the grid data files in the y- and z-directions if (n > 0) then file_path = trim(t_step_dir) // '/y_cb.dat' @@ -360,7 +334,6 @@ contains end if end if - ! Writing the conservative variables data files do i = 1, sys_size write (file_path, '(A,I0,A)') trim(t_step_dir) // '/q_cons_vf', i, '.dat' @@ -683,11 +656,7 @@ contains end subroutine s_write_serial_data_files - !> The goal of this subroutine is to output the grid and conservative variables data files for given time-step. - !! @param q_cons_vf Cell-average conservative variables - !! @param t_step Current time-step - !! @param bc_type Boundary condition type - !! @param beta Eulerian void fraction from lagrangian bubbles + !> Output the grid and conservative variables data files for the given time-step (parallel). impure subroutine s_write_parallel_data_files(q_cons_vf, t_step, bc_type, beta) type(scalar_field), dimension(sys_size), intent(inout) :: q_cons_vf @@ -727,7 +696,6 @@ contains if (file_per_process) then call s_int_to_str(t_step, t_step_string) - ! Initialize MPI data I/O if (down_sample) then call s_initialize_mpi_data_ds(q_cons_temp_ds) else @@ -749,10 +717,8 @@ contains call s_mpi_barrier() call DelayFileAccess(proc_rank) - ! Initialize MPI data I/O call s_initialize_mpi_data(q_cons_vf) - ! Open the file to write all flow variables write (file_loc, '(I0,A,i7.7,A)') t_step, '_', proc_rank, '.dat' file_loc = trim(case_dir) // '/restart_data/lustre_' // trim(t_step_string) // trim(mpiiofs) // trim(file_loc) inquire (FILE=trim(file_loc), EXIST=file_exist) @@ -762,20 +728,17 @@ contains call MPI_FILE_OPEN(MPI_COMM_SELF, file_loc, ior(MPI_MODE_WRONLY, MPI_MODE_CREATE), mpi_info_int, ifile, ierr) if (down_sample) then - ! Size of local arrays data_size = (m_ds + 3)*(n_ds + 3)*(p_ds + 3) m_glb_save = m_glb_ds + 1 n_glb_save = n_glb_ds + 1 p_glb_save = p_glb_ds + 1 else - ! Size of local arrays data_size = (m + 1)*(n + 1)*(p + 1) m_glb_save = m_glb + 1 n_glb_save = n_glb + 1 p_glb_save = p_glb + 1 end if - ! Resize some integers so MPI can write even the biggest files m_MOK = int(m_glb_save + 1, MPI_OFFSET_KIND) n_MOK = int(n_glb_save + 1, MPI_OFFSET_KIND) p_MOK = int(p_glb_save + 1, MPI_OFFSET_KIND) @@ -785,7 +748,6 @@ contains NVARS_MOK = int(sys_size, MPI_OFFSET_KIND) if (bubbles_euler) then - ! Write the data for each variable do i = 1, sys_size var_MOK = int(i, MPI_OFFSET_KIND) @@ -817,7 +779,6 @@ contains call MPI_FILE_CLOSE(ifile, ierr) else - ! Initialize MPI data I/O if (ib) then call s_initialize_mpi_data(q_cons_vf, ib_markers) @@ -835,10 +796,8 @@ contains end if call MPI_FILE_OPEN(MPI_COMM_WORLD, file_loc, ior(MPI_MODE_WRONLY, MPI_MODE_CREATE), mpi_info_int, ifile, ierr) - ! Size of local arrays data_size = (m + 1)*(n + 1)*(p + 1) - ! Resize some integers so MPI can write even the biggest files m_MOK = int(m_glb + 1, MPI_OFFSET_KIND) n_MOK = int(n_glb + 1, MPI_OFFSET_KIND) p_MOK = int(p_glb + 1, MPI_OFFSET_KIND) @@ -848,11 +807,9 @@ contains NVARS_MOK = int(alt_sys, MPI_OFFSET_KIND) if (bubbles_euler) then - ! Write the data for each variable do i = 1, sys_size var_MOK = int(i, MPI_OFFSET_KIND) - ! Initial displacement to skip at beginning of file disp = m_MOK*max(MOK, n_MOK)*max(MOK, p_MOK)*WP_MOK*(var_MOK - 1) call MPI_FILE_SET_VIEW(ifile, disp, mpi_p, MPI_IO_DATA%view(i), 'native', mpi_info_int, ierr) @@ -863,7 +820,6 @@ contains do i = sys_size + 1, sys_size + 2*nb*nnode var_MOK = int(i, MPI_OFFSET_KIND) - ! Initial displacement to skip at beginning of file disp = m_MOK*max(MOK, n_MOK)*max(MOK, p_MOK)*WP_MOK*(var_MOK - 1) call MPI_FILE_SET_VIEW(ifile, disp, mpi_p, MPI_IO_DATA%view(i), 'native', mpi_info_int, ierr) @@ -874,7 +830,6 @@ contains do i = 1, sys_size ! TODO: check if sys_size is correct var_MOK = int(i, MPI_OFFSET_KIND) - ! Initial displacement to skip at beginning of file disp = m_MOK*max(MOK, n_MOK)*max(MOK, p_MOK)*WP_MOK*(var_MOK - 1) call MPI_FILE_SET_VIEW(ifile, disp, mpi_p, MPI_IO_DATA%view(i), 'native', mpi_info_int, ierr) @@ -882,11 +837,9 @@ contains end do end if - ! Correction for the lagrangian subgrid bubble model if (present(beta)) then var_MOK = int(sys_size + 1, MPI_OFFSET_KIND) - ! Initial displacement to skip at beginning of file disp = m_MOK*max(MOK, n_MOK)*max(MOK, p_MOK)*WP_MOK*(var_MOK - 1) call MPI_FILE_SET_VIEW(ifile, disp, mpi_p, MPI_IO_DATA%view(sys_size + 1), 'native', mpi_info_int, ierr) @@ -895,32 +848,21 @@ contains call MPI_FILE_CLOSE(ifile, ierr) - ! Write ib data if (ib) then call s_write_parallel_ib_data(t_step) - ! write (file_loc, '(A)') 'ib.dat' file_loc = trim(case_dir)//'/restart_data'//trim(mpiiofs)//trim(file_loc) call - ! MPI_FILE_OPEN(MPI_COMM_WORLD, file_loc, ior(MPI_MODE_WRONLY, MPI_MODE_CREATE), & mpi_info_int, ifile, ierr) - - ! var_MOK = int(sys_size + 1, MPI_OFFSET_KIND) disp = m_MOK*max(MOK, n_MOK)*max(MOK, p_MOK)*WP_MOK*(var_MOK - 1 + - ! int(t_step/t_step_save)) - - ! call MPI_FILE_SET_VIEW(ifile, disp, MPI_INTEGER, MPI_IO_IB_DATA%view, & 'native', mpi_info_int, ierr) call - ! MPI_FILE_WRITE_ALL(ifile, MPI_IO_IB_DATA%var%sf, data_size, & MPI_INTEGER, status, ierr) call - ! MPI_FILE_CLOSE(ifile, ierr) end if end if #endif end subroutine s_write_parallel_data_files - !> @brief Writes immersed boundary marker data to a serial (per-processor) unformatted file. + !> Writes immersed boundary marker data to a serial (per-processor) unformatted file. subroutine s_write_serial_ib_data(time_step) integer, intent(in) :: time_step character(LEN=path_len + 2*name_len) :: file_path character(LEN=path_len + 2*name_len) :: t_step_dir - ! Creating or overwriting the time-step root directory write (t_step_dir, '(A,I0,A,I0)') trim(case_dir) // '/p_all' write (t_step_dir, '(a,i0,a,i0)') trim(case_dir) // '/p_all/p', proc_rank, '/', time_step @@ -933,7 +875,7 @@ contains end subroutine s_write_serial_ib_data - !> @brief Writes immersed boundary marker data in parallel using MPI I/O. + !> Writes immersed boundary marker data in parallel using MPI I/O. subroutine s_write_parallel_ib_data(time_step) integer, intent(in) :: time_step @@ -948,7 +890,6 @@ contains $:GPU_UPDATE(host='[ib_markers%sf]') - ! Size of local arrays data_size = (m + 1)*(n + 1)*(p + 1) m_MOK = int(m_glb + 1, MPI_OFFSET_KIND) n_MOK = int(n_glb + 1, MPI_OFFSET_KIND) @@ -971,7 +912,7 @@ contains end subroutine s_write_parallel_ib_data - !> @brief Dispatches immersed boundary data output to the serial or parallel writer. + !> Dispatches immersed boundary data output to the serial or parallel writer. subroutine s_write_ib_data_file(time_step) integer, intent(in) :: time_step @@ -984,7 +925,7 @@ contains end subroutine s_write_ib_data_file - !> @brief Writes IB state records to D/ib_state.dat. Must be called only on rank 0. + !> Writes IB state records to D/ib_state.dat. Must be called only on rank 0. impure subroutine s_write_ib_state_file() integer :: i @@ -996,9 +937,7 @@ contains end subroutine s_write_ib_state_file - !> This writes a formatted data file where the root processor can write out the CoM information - !! @param t_step Current time-step - !! @param c_mass_in Center of mass information + !> Write center-of-mass data to formatted file (root processor only). impure subroutine s_write_com_files(t_step, c_mass_in) integer, intent(in) :: t_step @@ -1006,7 +945,6 @@ contains integer :: i !< Generic loop iterator real(wp) :: nondim_time !< Non-dimensional time - ! Non-dimensional time calculation if (t_step_old /= dflt_int) then nondim_time = real(t_step + t_step_old, wp)*dt @@ -1033,10 +971,7 @@ contains end subroutine s_write_com_files - !> This writes a formatted data file for the flow probe information - !! @param t_step Current time-step - !! @param q_cons_vf Conservative variables - !! @param accel_mag Acceleration magnitude information + !> Write flow probe data to formatted files. impure subroutine s_write_probe_files(t_step, q_cons_vf, accel_mag) integer, intent(in) :: t_step @@ -1046,8 +981,6 @@ contains real(wp), dimension(-1:n) :: disty real(wp), dimension(-1:p) :: distz - ! The cell-averaged partial densities, density, velocity, pressure, volume fractions, specific heat ratio function, liquid - ! stiffness function, and sound speed. real(wp) :: lit_gamma, nbub real(wp) :: rho real(wp), dimension(num_vels) :: vel @@ -1083,7 +1016,6 @@ contains T = dflt_T_guess - ! Non-dimensional time calculation if (time_stepper == 23) then nondim_time = mytime else @@ -1095,7 +1027,6 @@ contains end if do i = 1, num_probes - ! Zeroing out flow variables for all processors rho = 0._wp do s = 1, num_vels vel(s) = 0._wp @@ -1122,7 +1053,6 @@ contains end do damage_state = 0._wp - ! Find probe location in terms of indices on a specific processor if (n == 0) then if ((probe(i)%x >= x_cb(-1)) .and. (probe(i)%x <= x_cb(m))) then do s = -1, m @@ -1576,9 +1506,7 @@ contains end subroutine s_write_probe_files - !> The goal of this subroutine is to write to the run-time information file basic footer information applicable to the current - !! computation and to close the file when done. The footer contains the stability criteria extrema over all of the time-steps - !! and the simulation run-time. + !> Write stability criteria extrema footer to the run-time information file and close it. impure subroutine s_close_run_time_information_file real(wp) :: run_time !< Run-time of the simulation @@ -1629,8 +1557,7 @@ contains end subroutine s_close_ib_state_file - !> The computation of parameters, the allocation of memory, the association of pointers and/or the execution of any other - !! procedures that are necessary to setup the module. + !> Initialize the data output module. impure subroutine s_initialize_data_output_module integer :: i, m_ds, n_ds, p_ds diff --git a/src/simulation/m_global_parameters.fpp b/src/simulation/m_global_parameters.fpp index 9951465a23..63294a3254 100644 --- a/src/simulation/m_global_parameters.fpp +++ b/src/simulation/m_global_parameters.fpp @@ -1,11 +1,11 @@ !> !! @file -!! @brief Contains module m_global_parameters +!! Contains module m_global_parameters #:include 'case.fpp' #:include 'macros.fpp' -!> @brief Global parameters for the computational domain, fluid properties, and simulation algorithm configuration +!> Global parameters for the computational domain, fluid properties, and simulation algorithm configuration module m_global_parameters #ifdef MFC_MPI @@ -22,7 +22,6 @@ module m_global_parameters real(wp) :: wall_time = 0 real(wp) :: wall_time_avg = 0 - ! Logistics integer :: num_procs !< Number of processors character(LEN=path_len) :: case_dir !< Case folder location logical :: run_time_info !< Run-time output flag @@ -327,8 +326,6 @@ module m_global_parameters $:GPU_DECLARE(create='[dir_idx, dir_flg, dir_idx_tau]') - !> The number of cells that are necessary to be able to store enough boundary conditions data to march the solution in the - !! physical computational domain to the next time-step. integer :: buff_size !< Number of ghost cells for boundary condition storage $:GPU_DECLARE(create='[buff_size]') @@ -336,8 +333,6 @@ module m_global_parameters integer :: shear_num !< Number of shear stress components integer, dimension(3) :: shear_indices !< Indices of the stress components that represent shear stress integer :: shear_BC_flip_num !< Number of shear stress components to reflect for boundary conditions - !> Indices of shear stress components to reflect for boundary conditions. Size: (1:3, 1:shear_BC_flip_num) for (x/y/z, - !! [indices]) integer, dimension(3, 2) :: shear_BC_flip_indices !< Shear stress BC reflection indices (1:3, 1:shear_BC_flip_num) $:GPU_DECLARE(create='[shear_num, shear_indices, shear_BC_flip_num, shear_BC_flip_indices]') @@ -346,20 +341,13 @@ module m_global_parameters ! Fluids Physical Parameters - !> Database of the physical parameters of each of the fluids that is present in the flow. These include the stiffened gas - !! equation of state parameters, and the Reynolds numbers. type(physical_parameters), dimension(num_fluids_max) :: fluid_pp !< Stiffened gas EOS parameters and Reynolds numbers per fluid ! Subgrid Bubble Parameters type(subgrid_bubble_physical_parameters) :: bub_pp - !> The order of the finite-difference (fd) approximations of the first-order derivatives that need to be evaluated when the CoM - !! or flow probe data files are to be written at each time step - integer :: fd_order !< Finite-difference order for CoM and flow probe derivatives - - !> The finite-difference number is given by MAX(1, fd_order/2). Essentially, it is a measure of the half-size of the - !! finite-difference stencil for the selected order of accuracy. - integer :: fd_number !< Finite-difference half-stencil size: MAX(1, fd_order/2) + integer :: fd_order !< Finite-difference order for CoM and flow probe derivatives + integer :: fd_number !< FD half-stencil size: MAX(1, fd_order/2) $:GPU_DECLARE(create='[fd_order, fd_number]') logical :: probe_wrt @@ -383,9 +371,6 @@ module m_global_parameters type(ib_patch_parameters), dimension(num_patches_max) :: patch_ib !< Immersed boundary patch parameters type(vec3_dt), allocatable, dimension(:) :: airfoil_grid_u, airfoil_grid_l integer :: Np - !! Database of the immersed boundary patch parameters for each of the patches employed in the configuration of the initial - !! condition. Note that the maximum allowable number of patches, num_patches_max, may be changed in the module - !! m_derived_types.f90. $:GPU_DECLARE(create='[ib, num_ibs, patch_ib, Np, airfoil_grid_u, airfoil_grid_l]') !> @} @@ -520,8 +505,6 @@ module m_global_parameters $:GPU_DECLARE(create='[Bx0]') logical :: fft_wrt - !> AMDFlang workaround: keep a dummy logical to avoid a compiler case-optimization bug when a parameter+GPU-kernel conditional - !! is false logical :: dummy !< AMDFlang workaround for case-optimization + GPU-kernel bug !> @name Continuum damage model parameters @@ -547,8 +530,6 @@ contains integer :: i, j !< Generic loop iterator - ! Logistics - case_dir = '.' run_time_info = .false. t_step_old = dflt_int @@ -918,9 +899,7 @@ contains $:GPU_UPDATE(device='[igr, igr_order, igr_iter_solver]') #:endif - ! Initializing the number of fluids for which viscous effects will be non-negligible, the number of distinctive material - ! interfaces for which surface tension will be important and also, the number of fluids for which the physical and geometric - ! curvatures of the interfaces will be computed + ! Initialize viscous fluid count and curvature tracking Re_size = 0 Re_size_max = 0 diff --git a/src/simulation/m_ib_patches.fpp b/src/simulation/m_ib_patches.fpp index 41aeffec30..87a0faf742 100644 --- a/src/simulation/m_ib_patches.fpp +++ b/src/simulation/m_ib_patches.fpp @@ -1,6 +1,6 @@ !> !! @file -!! @brief Contains module m_ib_patches +!! Contains module m_ib_patches #:include 'case.fpp' #:include 'ExtrusionHardcodedIC.fpp' @@ -9,7 +9,7 @@ #:include '3dHardcodedIC.fpp' #:include 'macros.fpp' -!> @brief Immersed boundary patch geometry constructors for 2D and 3D shapes +!> Immersed boundary patch geometry constructors for 2D and 3D shapes module m_ib_patches use m_model ! Subroutine(s) related to STL files @@ -32,26 +32,22 @@ module m_ib_patches integer :: smooth_patch_id real(wp) :: smooth_coeff $:GPU_DECLARE(create='[smooth_patch_id, smooth_coeff]') - !! These variables are analogous in both meaning and use to the similarly named components in the ic_patch_parameters type (see - !! m_derived_types.f90 for additional details). They are employed as a means to more concisely perform the actions necessary to - !! lay out a particular patch on the grid. + ! Analogous to ic_patch_parameters fields; used to lay out IB patches on the grid. real(wp) :: cart_x, cart_y, cart_z real(wp) :: sph_phi $:GPU_DECLARE(create='[cart_x, cart_y, cart_z, sph_phi]') - !! Variables to be used to hold cell locations in Cartesian coordinates if 3D simulation is using cylindrical coordinates + ! Cell locations in Cartesian coordinates for 3D cylindrical simulations. type(bounds_info) :: x_boundary, y_boundary, z_boundary $:GPU_DECLARE(create='[x_boundary, y_boundary, z_boundary]') - !! These variables combine the centroid and length parameters associated with a particular patch to yield the locations of the - !! patch boundaries in the x-, y- and z-coordinate directions. They are used as a means to concisely perform the actions - !! necessary to lay out a particular patch on the grid. + ! Patch boundary locations in x, y, z derived from centroid and length parameters. character(len=5) :: istr !< string to store int to string result for error checking contains - !> @brief Applies all immersed boundary patch geometries to mark interior cells in the IB marker array. + !> Applies all immersed boundary patch geometries to mark interior cells in the IB marker array. impure subroutine s_apply_ib_patches(ib_markers) type(integer_field), intent(inout) :: ib_markers @@ -112,12 +108,7 @@ contains end subroutine s_apply_ib_patches - !> The circular patch is a 2D geometry that may be used, for example, in creating a bubble or a droplet. The geometry of the - !! patch is well-defined when its centroid and radius are provided. Note that the circular patch DOES allow for the smoothing of - !! its boundary. - !! @param patch_id is the patch identifier - !! @param ib_markers Array to track patch ids - !! @param ib True if this patch is an immersed boundary + !> Mark cells inside a 2D circular immersed boundary defined by centroid and radius. subroutine s_ib_circle(patch_id, ib_markers, xp, yp) integer, intent(in) :: patch_id @@ -128,7 +119,6 @@ contains integer :: i, j, il, ir, jl, jr !< Generic loop iterators integer :: encoded_patch_id - ! Transferring the circular patch's radius, centroid, smearing patch identity and smearing coefficient information center(1) = patch_ib(patch_id)%x_centroid + real(xp, wp)*(glb_bounds(1)%end - glb_bounds(1)%beg) center(2) = patch_ib(patch_id)%y_centroid + real(yp, wp)*(glb_bounds(2)%end - glb_bounds(2)%beg) @@ -145,8 +135,6 @@ contains call get_bounding_indices(center(1) - radius, center(1) + radius, x_cc, il, ir) call get_bounding_indices(center(2) - radius, center(2) + radius, y_cc, jl, jr) - ! Checking whether the circle covers a particular cell in the domain and verifying whether the current patch has permission - ! to write to that cell. If both queries check out, the primitive variables of the current patch are assigned to this cell. $:GPU_PARALLEL_LOOP(private='[i, j]', copyin='[encoded_patch_id, center, radius]', collapse=2) do j = jl, jr @@ -160,9 +148,7 @@ contains end subroutine s_ib_circle - !> @brief Marks cells inside a 2D NACA 4-digit airfoil immersed boundary using upper and lower surface grids. - !! @param patch_id is the patch identifier - !! @param ib_markers Array to track patch ids + !> Marks cells inside a 2D NACA 4-digit airfoil immersed boundary using upper and lower surface grids. subroutine s_ib_airfoil(patch_id, ib_markers, xp, yp) integer, intent(in) :: patch_id @@ -195,7 +181,7 @@ contains @:ALLOCATE(airfoil_grid_u(1:Np)) @:ALLOCATE(airfoil_grid_l(1:Np)) - ! TODO :: The below instantiations are already handles by the loop below + ! TODO :: The below instantiations are already handled by the loop below airfoil_grid_u(1)%x = 0._wp airfoil_grid_u(1)%y = 0._wp @@ -203,7 +189,7 @@ contains airfoil_grid_l(1)%y = 0._wp do i = 1, Np1 + Np2 - 1 - ! TODO :: This allocated the upper and lower airfoil arrays, and does not need to be performed each time the IB + ! TODO :: This allocates the upper and lower airfoil arrays, and does not need to be performed each time the IB ! markers are updated. Place this as a separate subroutine. if (i <= Np1) then xc = i*(pa*ca_in/Np1) @@ -285,13 +271,11 @@ contains end do if (f_approx_equal(airfoil_grid_u(k)%x, xy_local(1))) then if (xy_local(2) <= airfoil_grid_u(k)%y) then - !!IB ib_markers%sf(i, j, 0) = encoded_patch_id end if else f = (airfoil_grid_u(k)%x - xy_local(1))/(airfoil_grid_u(k)%x - airfoil_grid_u(k - 1)%x) if (xy_local(2) <= ((1._wp - f)*airfoil_grid_u(k)%y + f*airfoil_grid_u(k - 1)%y)) then - !!IB ib_markers%sf(i, j, 0) = encoded_patch_id end if end if @@ -302,14 +286,12 @@ contains end do if (f_approx_equal(airfoil_grid_l(k)%x, xy_local(1))) then if (xy_local(2) >= airfoil_grid_l(k)%y) then - !!IB ib_markers%sf(i, j, 0) = encoded_patch_id end if else f = (airfoil_grid_l(k)%x - xy_local(1))/(airfoil_grid_l(k)%x - airfoil_grid_l(k - 1)%x) if (xy_local(2) >= ((1._wp - f)*airfoil_grid_l(k)%y + f*airfoil_grid_l(k - 1)%y)) then - !!IB ib_markers%sf(i, j, 0) = encoded_patch_id end if end if @@ -321,10 +303,7 @@ contains end subroutine s_ib_airfoil - !> @brief Marks cells inside a 3D extruded NACA 4-digit airfoil immersed boundary with finite span. - !! @param patch_id is the patch identifier - !! @param ib_markers Array to track patch ids - !! @param ib True if this patch is an immersed boundary + !> Marks cells inside a 3D extruded NACA 4-digit airfoil immersed boundary with finite span. subroutine s_ib_3D_airfoil(patch_id, ib_markers, xp, yp, zp) integer, intent(in) :: patch_id @@ -451,7 +430,6 @@ contains else f = (airfoil_grid_u(k)%x - xyz_local(1))/(airfoil_grid_u(k)%x - airfoil_grid_u(k - 1)%x) if (xyz_local(2) <= ((1._wp - f)*airfoil_grid_u(k)%y + f*airfoil_grid_u(k - 1)%y)) then - !!IB ib_markers%sf(i, j, l) = encoded_patch_id end if end if @@ -462,14 +440,12 @@ contains end do if (f_approx_equal(airfoil_grid_l(k)%x, xyz_local(1))) then if (xyz_local(2) >= airfoil_grid_l(k)%y) then - !!IB ib_markers%sf(i, j, l) = encoded_patch_id end if else f = (airfoil_grid_l(k)%x - xyz_local(1))/(airfoil_grid_l(k)%x - airfoil_grid_l(k - 1)%x) if (xyz_local(2) >= ((1._wp - f)*airfoil_grid_l(k)%y + f*airfoil_grid_l(k - 1)%y)) then - !!IB ib_markers%sf(i, j, l) = encoded_patch_id end if end if @@ -483,13 +459,7 @@ contains end subroutine s_ib_3D_airfoil - !> The rectangular patch is a 2D geometry that may be used, for example, in creating a solid boundary, or pre-/post- shock - !! region, in alignment with the axes of the Cartesian coordinate system. The geometry of such a patch is well- defined when its - !! centroid and lengths in the x- and y- coordinate directions are provided. Please note that the rectangular patch DOES NOT - !! allow for the smoothing of its boundaries. - !! @param patch_id is the patch identifier - !! @param ib_markers Array to track patch ids - !! @param ib True if this patch is an immersed boundary + !> Marks cells inside a 2D rectangular immersed boundary defined by centroid and side lengths. subroutine s_ib_rectangle(patch_id, ib_markers, xp, yp) integer, intent(in) :: patch_id @@ -502,7 +472,6 @@ contains real(wp), dimension(1:2) :: length, center !< x and y coordinates in local IB frame real(wp), dimension(1:3,1:3) :: inverse_rotation - ! Transferring the rectangle's centroid and length information center(1) = patch_ib(patch_id)%x_centroid + real(xp, wp)*(glb_bounds(1)%end - glb_bounds(1)%beg) center(2) = patch_ib(patch_id)%y_centroid + real(yp, wp)*(glb_bounds(2)%end - glb_bounds(2)%beg) @@ -522,8 +491,6 @@ contains call get_bounding_indices(center(1) - corner_distance, center(1) + corner_distance, x_cc, il, ir) call get_bounding_indices(center(2) - corner_distance, center(2) + corner_distance, y_cc, jl, jr) - ! Checking whether the rectangle covers a particular cell in the domain and verifying whether the current patch has the - ! permission to write to that cell. If both queries check out, the primitive variables of the current patch are assigned to ! this cell. $:GPU_PARALLEL_LOOP(private='[i, j, xy_local]', copyin='[encoded_patch_id, center, length, inverse_rotation, x_cc, & & y_cc]', collapse=2) @@ -544,12 +511,7 @@ contains end subroutine s_ib_rectangle - !> The spherical patch is a 3D geometry that may be used, for example, in creating a bubble or a droplet. The patch geometry is - !! well-defined when its centroid and radius are provided. Please note that the spherical patch DOES allow for the smoothing of - !! its boundary. - !! @param patch_id is the patch identifier - !! @param ib_markers Array to track patch ids - !! @param ib True if this patch is an immersed boundary + !> Marks cells inside a 3D spherical immersed boundary defined by centroid and radius. subroutine s_ib_sphere(patch_id, ib_markers, xp, yp, zp) integer, intent(in) :: patch_id @@ -566,7 +528,6 @@ contains !! Variables to initialize the pressure field that corresponds to the bubble-collapse test case found in Tiwari et al. !! (2013) - ! Transferring spherical patch's radius, centroid, smoothing patch identity and smoothing coefficient information center(1) = patch_ib(patch_id)%x_centroid + real(xp, wp)*(glb_bounds(1)%end - glb_bounds(1)%beg) center(2) = patch_ib(patch_id)%y_centroid + real(yp, wp)*(glb_bounds(2)%end - glb_bounds(2)%beg) @@ -587,8 +548,6 @@ contains call get_bounding_indices(center(2) - radius, center(2) + radius, y_cc, jl, jr) call get_bounding_indices(center(3) - radius, center(3) + radius, z_cc, kl, kr) - ! Checking whether the sphere covers a particular cell in the domain and verifying whether the current patch has permission - ! to write to that cell. If both queries check out, the primitive variables of the current patch are assigned to this cell. $:GPU_PARALLEL_LOOP(private='[i, j, k, cart_y, cart_z]', copyin='[encoded_patch_id, center, radius]', collapse=3) do k = kl, kr do j = jl, jr @@ -611,12 +570,7 @@ contains end subroutine s_ib_sphere - !> The cuboidal patch is a 3D geometry that may be used, for example, in creating a solid boundary, or pre-/post-shock region, - !! which is aligned with the axes of the Cartesian coordinate system. The geometry of such a patch is well- defined when its - !! centroid and lengths in the x-, y- and z-coordinate directions are provided. Please notice that the cuboidal patch DOES NOT - !! allow for the smearing of its boundaries. - !! @param patch_id is the patch identifier - !! @param ib_markers Array to track patch ids + !> Marks cells inside a 3D cuboidal immersed boundary defined by centroid and side lengths. subroutine s_ib_cuboid(patch_id, ib_markers, xp, yp, zp) integer, intent(in) :: patch_id @@ -628,7 +582,6 @@ contains real(wp), dimension(1:3,1:3) :: inverse_rotation real(wp) :: corner_distance - ! Transferring the cuboid's centroid and length information center(1) = patch_ib(patch_id)%x_centroid + real(xp, wp)*(glb_bounds(1)%end - glb_bounds(1)%beg) center(2) = patch_ib(patch_id)%y_centroid + real(yp, wp)*(glb_bounds(2)%end - glb_bounds(2)%beg) @@ -653,7 +606,6 @@ contains call get_bounding_indices(center(2) - corner_distance, center(2) + corner_distance, y_cc, jl, jr) call get_bounding_indices(center(3) - corner_distance, center(3) + corner_distance, z_cc, kl, kr) - ! Checking whether the cuboid covers a particular cell in the domain and verifying whether the current patch has permission ! to write to to that cell. If both queries check out, the primitive variables of the current patch are assigned to this ! cell. $:GPU_PARALLEL_LOOP(private='[i, j, k, xyz_local, cart_y, cart_z]', copyin='[encoded_patch_id, center, length, & @@ -684,13 +636,7 @@ contains end subroutine s_ib_cuboid - !> The cylindrical patch is a 3D geometry that may be used, for example, in setting up a cylindrical solid boundary confinement, - !! like a blood vessel. The geometry of this patch is well-defined when the centroid, the radius and the length along the - !! cylinder's axis, parallel to the x-, y- or z-coordinate direction, are provided. Please note that the cylindrical patch DOES - !! allow for the smoothing of its lateral boundary. - !! @param patch_id is the patch identifier - !! @param ib_markers Array to track patch ids - !! @param ib True if this patch is an immersed boundary + !> Marks cells inside a 3D cylindrical immersed boundary defined by centroid, radius, and axis length. subroutine s_ib_cylinder(patch_id, ib_markers, xp, yp, zp) integer, intent(in) :: patch_id @@ -703,7 +649,6 @@ contains real(wp), dimension(1:3,1:3) :: inverse_rotation real(wp) :: corner_distance - ! Transferring the cylindrical patch's centroid, length, radius, center(1) = patch_ib(patch_id)%x_centroid + real(xp, wp)*(glb_bounds(1)%end - glb_bounds(1)%beg) center(2) = patch_ib(patch_id)%y_centroid + real(yp, wp)*(glb_bounds(2)%end - glb_bounds(2)%beg) @@ -728,8 +673,6 @@ contains call get_bounding_indices(center(2) - corner_distance, center(2) + corner_distance, y_cc, jl, jr) call get_bounding_indices(center(3) - corner_distance, center(3) + corner_distance, z_cc, kl, kr) - ! Checking whether the cylinder covers a particular cell in the domain and verifying whether the current patch has the - ! permission to write to that cell. If both queries check out, the primitive variables of the current patch are assigned to ! this cell. $:GPU_PARALLEL_LOOP(private='[i, j, k, xyz_local, cart_y, cart_z]', copyin='[encoded_patch_id, center, length, radius, & & inverse_rotation]', collapse=3) @@ -761,7 +704,7 @@ contains end subroutine s_ib_cylinder - !> @brief Marks cells inside a 2D elliptical immersed boundary defined by semi-axis lengths and rotation. + !> Marks cells inside a 2D elliptical immersed boundary defined by semi-axis lengths and rotation. subroutine s_ib_ellipse(patch_id, ib_markers, xp, yp) integer, intent(in) :: patch_id @@ -774,7 +717,6 @@ contains real(wp), dimension(1:2) :: center !< x and y coordinates in local IB frame real(wp), dimension(1:3,1:3) :: inverse_rotation - ! Transferring the ellipse's centroid and length information center(1) = patch_ib(patch_id)%x_centroid + real(xp, wp)*(glb_bounds(1)%end - glb_bounds(1)%beg) center(2) = patch_ib(patch_id)%y_centroid + real(yp, wp)*(glb_bounds(2)%end - glb_bounds(2)%beg) @@ -793,7 +735,6 @@ contains call get_bounding_indices(center(1) - maxval(ellipse_coeffs)*2._wp, center(1) + maxval(ellipse_coeffs)*2._wp, x_cc, il, ir) call get_bounding_indices(center(2) - maxval(ellipse_coeffs)*2._wp, center(2) + maxval(ellipse_coeffs)*2._wp, y_cc, jl, jr) - ! Checking whether the ellipse covers a particular cell in the domain $:GPU_PARALLEL_LOOP(private='[i, j, xy_local]', copyin='[encoded_patch_id, center, ellipse_coeffs, inverse_rotation, & & x_cc, y_cc]', collapse=2) do j = jl, jr @@ -814,8 +755,6 @@ contains end subroutine s_ib_ellipse !> The STL patch is a 2D geometry that is imported from an STL file. - !! @param patch_id is the patch identifier - !! @param ib_markers Array to track patch ids subroutine s_ib_model(patch_id, ib_markers, xp, yp) integer, intent(in) :: patch_id @@ -893,8 +832,6 @@ contains end subroutine s_ib_model !> The STL patch is a 3D geometry that is imported from an STL file. - !! @param patch_id is the patch identifier - !! @param ib_markers Array to track patch ids subroutine s_ib_3d_model(patch_id, ib_markers, xp, yp, zp) integer, intent(in) :: patch_id @@ -1027,7 +964,7 @@ contains end subroutine s_update_ib_rotation_matrix - !> @brief Converts cylindrical (r, theta) coordinates to Cartesian (y, z) and stores in module variables. + !> Converts cylindrical (r, theta) coordinates to Cartesian (y, z) and stores in module variables. subroutine s_convert_cylindrical_to_cartesian_coord(cyl_y, cyl_z) $:GPU_ROUTINE(parallelism='[seq]') @@ -1039,7 +976,7 @@ contains end subroutine s_convert_cylindrical_to_cartesian_coord - !> @brief Converts a 3D cylindrical coordinate vector (x, r, theta) to Cartesian (x, y, z). + !> Converts a 3D cylindrical coordinate vector (x, r, theta) to Cartesian (x, y, z). pure function f_convert_cyl_to_cart(cyl) result(cart) $:GPU_ROUTINE(parallelism='[seq]') @@ -1051,7 +988,7 @@ contains end function f_convert_cyl_to_cart - !> @brief Converts cylindrical coordinates (x, r) to the spherical azimuthal angle phi and stores in a module variable. + !> Converts cylindrical coordinates (x, r) to the spherical azimuthal angle phi and stores in a module variable. subroutine s_convert_cylindrical_to_spherical_coord(cyl_x, cyl_y) $:GPU_ROUTINE(parallelism='[seq]') @@ -1101,7 +1038,7 @@ contains end subroutine get_bounding_indices - !> @brief encodes the patch id with a unique offset that contains information on how the IB marker wraps periodically + !> encodes the patch id with a unique offset that contains information on how the IB marker wraps periodically subroutine s_encode_patch_periodicity(patch_id, x_periodicity, y_periodicity, z_periodicity, encoded_patch_id) integer, intent(in) :: patch_id, x_periodicity, y_periodicity, z_periodicity @@ -1119,7 +1056,7 @@ contains end subroutine s_encode_patch_periodicity - !> @brief decodes the encoded id to get out the original id and the way in which it is periodic + !> decodes the encoded id to get out the original id and the way in which it is periodic subroutine s_decode_patch_periodicity(encoded_patch_id, patch_id, x_periodicity, y_periodicity, z_periodicity) $:GPU_ROUTINE(parallelism='[seq]') @@ -1145,7 +1082,7 @@ contains end subroutine s_decode_patch_periodicity - !> @brief Determines if we should wrap periodically + !> Determines if we should wrap periodically subroutine s_get_periodicities(xp_lower, xp_upper, yp_lower, yp_upper, zp_lower, zp_upper) integer, intent(out) :: xp_lower, xp_upper, yp_lower, yp_upper @@ -1170,9 +1107,6 @@ contains end subroutine s_get_periodicities !> Archimedes spiral function - !! @param myth Angle - !! @param offset Thickness - !! @param a Starting position pure elemental function f_r(myth, offset, a) $:GPU_ROUTINE(parallelism='[seq]') diff --git a/src/simulation/m_ibm.fpp b/src/simulation/m_ibm.fpp index f70209a9cb..2ff0f2f7db 100644 --- a/src/simulation/m_ibm.fpp +++ b/src/simulation/m_ibm.fpp @@ -1154,8 +1154,7 @@ contains else ! we do not have an analytic moment of inertia calculation and need to approximate it directly via a sum count = 0 moment = 0._wp - cell_volume = (x_cc(1) - x_cc(0))*(y_cc(1) - y_cc(0)) & - & ! computed without grid stretching. Update in the loop to perform with stretching + cell_volume = (x_cc(1) - x_cc(0))*(y_cc(1) - y_cc(0)) if (p /= 0) then cell_volume = cell_volume*(z_cc(1) - z_cc(0)) end if diff --git a/src/simulation/m_sim_helpers.fpp b/src/simulation/m_sim_helpers.fpp index b9a5b10cf8..e31e9bee47 100644 --- a/src/simulation/m_sim_helpers.fpp +++ b/src/simulation/m_sim_helpers.fpp @@ -18,10 +18,7 @@ module m_sim_helpers contains - !> Computes the modified dtheta for Fourier filtering in azimuthal direction - !! @param k y coordinate index - !! @param l z coordinate index - !! @return fltr_dtheta Modified dtheta value for cylindrical coordinates + !> Computes the modified dtheta for Fourier filtering in azimuthal direction. function f_compute_filtered_dtheta(k, l) result(fltr_dtheta) $:GPU_ROUTINE(parallelism='[seq]') @@ -44,13 +41,7 @@ contains end function f_compute_filtered_dtheta - !> Computes inviscid CFL terms for multi-dimensional cases (2D/3D only) - !! @param vel directional velocities - !! @param c mixture speed of sound - !! @param j x coordinate index - !! @param k y coordinate index - !! @param l z coordinate index - !! @return cfl_terms computed CFL terms for 2D/3D cases + !> Computes inviscid CFL terms for multi-dimensional cases (2D/3D only). function f_compute_multidim_cfl_terms(vel, c, j, k, l) result(cfl_terms) $:GPU_ROUTINE(parallelism='[seq]') @@ -78,21 +69,7 @@ contains end function f_compute_multidim_cfl_terms - !> Computes enthalpy - !! @param q_prim_vf cell centered primitive variables - !! @param pres mixture pressure - !! @param rho mixture density - !! @param gamma mixture gamma - !! @param pi_inf mixture pi_inf - !! @param Re mixture reynolds number - !! @param H mixture enthalpy - !! @param alpha component alphas - !! @param vel directional velocities - !! @param vel_sum squard sum of velocity components - !! @param qv Fluid reference energy - !! @param j x index - !! @param k y index - !! @param l z index + !> Computes enthalpy. subroutine s_compute_enthalpy(q_prim_vf, pres, rho, gamma, pi_inf, Re, H, alpha, vel, vel_sum, qv, j, k, l) $:GPU_ROUTINE(function_name='s_compute_enthalpy',parallelism='[seq]', cray_inline=True) @@ -160,17 +137,7 @@ contains end subroutine s_compute_enthalpy - !> Computes stability criterion for a specified dt - !! @param vel directional velocities - !! @param c mixture speed of sound - !! @param rho Density - !! @param Re_l mixture Reynolds number - !! @param j x index - !! @param k y index - !! @param l z index - !! @param icfl cell-centered inviscid cfl number - !! @param vcfl (optional) cell-centered viscous CFL number - !! @param Rc (optional) cell centered Rc + !> Computes stability criterion for a specified dt. subroutine s_compute_stability_from_dt(vel, c, rho, Re_l, j, k, l, icfl, vcfl, Rc) $:GPU_ROUTINE(parallelism='[seq]') @@ -213,15 +180,7 @@ contains end subroutine s_compute_stability_from_dt - !> Computes dt for a specified CFL number - !! @param vel directional velocities - !! @param c Speed of sound - !! @param max_dt cell centered maximum dt - !! @param rho cell centered density - !! @param Re_l cell centered Reynolds number - !! @param j x coordinate - !! @param k y coordinate - !! @param l z coordinate + !> Computes dt for a specified CFL number. subroutine s_compute_dt_from_cfl(vel, c, max_dt, rho, Re_l, j, k, l) $:GPU_ROUTINE(parallelism='[seq]') diff --git a/src/simulation/m_time_steppers.fpp b/src/simulation/m_time_steppers.fpp index a9b4af0577..8170a360cd 100644 --- a/src/simulation/m_time_steppers.fpp +++ b/src/simulation/m_time_steppers.fpp @@ -752,14 +752,11 @@ contains ! update the velocity from the force value patch_ib(i)%vel = patch_ib(i)%vel + rk_coef(s, 3)*dt*(patch_ib(i)%force/patch_ib(i)%mass)/rk_coef(s, 4) - ! update the angular velocity with the torque value + ! Update angular velocity from torque, then recompute moment of inertia patch_ib(i)%angular_vel = (patch_ib(i)%angular_vel*patch_ib(i)%moment) + (rk_coef(s, & - & 3)*dt*patch_ib(i)%torque/rk_coef(s, 4)) ! add the torque to the angular momentum - call s_compute_moment_of_inertia(i, & - & patch_ib(i)%angular_vel) & - & ! update the moment of inertia to be based on the direction of the angular momentum - patch_ib(i)%angular_vel = patch_ib(i)%angular_vel/patch_ib(i) & - & %moment ! convert back to angular velocity with the new moment of inertia + & 3)*dt*patch_ib(i)%torque/rk_coef(s, 4)) + call s_compute_moment_of_inertia(i, patch_ib(i)%angular_vel) + patch_ib(i)%angular_vel = patch_ib(i)%angular_vel/patch_ib(i)%moment end if ! Update the angle of the IB From 98bcbf993ddffdd6ec939c592fcf97188c709c90 Mon Sep 17 00:00:00 2001 From: Spencer Bryngelson Date: Fri, 27 Mar 2026 22:03:03 -0400 Subject: [PATCH 12/14] fix linter --- .ffmt_cache/hashes | 249 ------------------------ .gitignore | 1 + src/common/m_boundary_common.fpp | 11 +- src/pre_process/m_global_parameters.fpp | 59 +++--- src/simulation/m_data_output.fpp | 71 ++++--- src/simulation/m_global_parameters.fpp | 18 +- src/simulation/m_ib_patches.fpp | 9 +- 7 files changed, 73 insertions(+), 345 deletions(-) delete mode 100644 .ffmt_cache/hashes diff --git a/.ffmt_cache/hashes b/.ffmt_cache/hashes deleted file mode 100644 index 69bf2d477d..0000000000 --- a/.ffmt_cache/hashes +++ /dev/null @@ -1,249 +0,0 @@ -10009860086781508725 src/simulation/m_sim_helpers.fpp -10103916424136661533 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.YNbWNpe5YF/b/src/common/m_delay_file_access.f90 -10103916424136661533 src/common/m_delay_file_access.f90 -10105209818380589033 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.UKcnsjaI4a/b/src/simulation/m_rhs.fpp -10105209818380589033 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.dhTNdaQgUC/b/src/simulation/m_rhs.fpp -10105209818380589033 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.erX3snVzaV/pr.fpp -10547681541613149381 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.QwIzwEBHeU/b/src/simulation/m_compute_cbc.fpp -10547681541613149381 src/simulation/m_compute_cbc.fpp -10547908418817167772 src/common/m_checker_common.fpp -10971775388782938368 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.wXyGiacHHu/b/src/pre_process/m_initial_condition.fpp -11128781068164813518 src/simulation/m_surface_tension.fpp -1123613300469720145 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.NhWX9QvMiS/b/src/simulation/m_pressure_relaxation.fpp -11247271584116519044 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.5zMHO1bIjC/b/src/common/m_helper.fpp -11247271584116519044 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.UKcnsjaI4a/b/src/common/m_helper.fpp -11296479789568295899 src/post_process/p_main.fpp -11299621811843082331 src/pre_process/m_icpp_patches.fpp -11328367635707741672 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.fRp2cEQ9ib/b/src/pre_process/m_grid.f90 -1152355942436141718 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.yvB87OqER1/b/src/post_process/m_derived_variables.fpp -1162163686405901254 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.IXCiOAmlT9/b/src/simulation/m_bubbles.fpp -1162163686405901254 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.OMiiuUbkm3/pr.fpp -1162163686405901254 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.UKcnsjaI4a/b/src/simulation/m_bubbles.fpp -1162163686405901254 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.iJz2nMUb3Q/b/src/simulation/m_bubbles.fpp -11671852064421512331 src/simulation/m_bubbles.fpp -1177935745597610133 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.KsaCosfP7l/b/src/simulation/m_surface_tension.fpp -11799777124238319529 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.p6vSsTKmTQ/b/src/common/include/ExtrusionHardcodedIC.fpp -11844429005742744406 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.p40EgjuOZ4/b/src/common/include/macros.fpp -11844429005742744406 src/common/include/macros.fpp -11845929787624151121 src/simulation/m_igr.fpp -11858275667014895903 src/pre_process/m_perturbation.fpp -11886921327637192006 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.rNk4nDDuiA/b/src/pre_process/m_assign_variables.fpp -11928143073477354808 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.ApVsay2rl0/b/src/common/m_chemistry.fpp -11928143073477354808 src/common/m_chemistry.fpp -12464738087200294908 src/pre_process/m_initial_condition.fpp -12545196112158418286 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.4QCea7ntGd/b/src/common/m_constants.fpp -12545196112158418286 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.UKcnsjaI4a/b/src/common/m_constants.fpp -12545196112158418286 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.pHQFxfnpka/pr.fpp -12614301032225053702 src/simulation/m_qbmm.fpp -12776587850356873970 src/simulation/m_pressure_relaxation.fpp -1298984555937275901 src/pre_process/p_main.f90 -1302629992983287045 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.jlX0OxaJWC/b/src/common/include/2dHardcodedIC.fpp -13038648724116207061 src/simulation/m_start_up.fpp -13116240964782596330 src/simulation/m_muscl.fpp -13160620054921289456 src/simulation/m_ibm.fpp -13371470821044798149 src/simulation/m_acoustic_src.fpp -13377292145430364954 src/simulation/m_mpi_proxy.fpp -13379422254557003055 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.tQPN4tJmBS/b/src/common/include/parallel_macros.fpp -13379422254557003055 src/common/include/parallel_macros.fpp -13404712065072015994 src/common/include/1dHardcodedIC.fpp -13585296417644820871 src/simulation/m_weno.fpp -13737474862947549962 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.wBcCWjwdfh/b/src/common/include/1dHardcodedIC.fpp -13778436859709422582 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.ZQxwzOCdYP/b/src/pre_process/p_main.f90 -13798070750203827352 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.9oWQDBRzDO/b/src/simulation/m_data_output.fpp -13798070750203827352 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.BPphaiI0iT/b/src/simulation/m_data_output.fpp -13798070750203827352 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.FyLr7CvpOg/b/src/simulation/m_data_output.fpp -13798070750203827352 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.UKcnsjaI4a/b/src/simulation/m_data_output.fpp -13798070750203827352 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.czvPHMadlf/b/src/simulation/m_data_output.fpp -13798070750203827352 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.l4geGiBejN/b/src/simulation/m_data_output.fpp -13798070750203827352 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.mAWaP5Yqf6/pr.fpp -13798070750203827352 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.nW8Pq43Vvf/b/src/simulation/m_data_output.fpp -13920301627764782241 src/common/m_nvtx.f90 -14047356244834746872 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.xVza69symx/b/src/simulation/m_hyperelastic.fpp -14218853748338101619 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.F8v3PuEaEB/b/src/common/m_checker_common.fpp -14257682203105278348 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.CZPMCJMBJW/b/src/common/m_phase_change.fpp -14264799885104244614 src/common/m_mpi_common.fpp -14438687236384090363 src/simulation/m_bubbles_EL_kernels.fpp -14450336682570067792 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.1BExP6R8f9/b/src/simulation/m_acoustic_src.fpp -14551696709150228093 src/common/m_phase_change.fpp -14636237826800124746 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.1geSh90r6o/b/src/pre_process/m_global_parameters.fpp -14636237826800124746 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.1nYoCE2Z93/b/src/pre_process/m_global_parameters.fpp -14636237826800124746 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.CF4oy4IF0z/b/src/pre_process/m_global_parameters.fpp -14636237826800124746 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.HVIH7qJvcV/b/src/pre_process/m_global_parameters.fpp -14636237826800124746 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.PjipPs9F6i/b/src/pre_process/m_global_parameters.fpp -14636237826800124746 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.QrrnxH74mE/pr.fpp -14636237826800124746 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.UKcnsjaI4a/b/src/pre_process/m_global_parameters.fpp -14636237826800124746 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.ketcpZUBhe/b/src/pre_process/m_global_parameters.fpp -14636237826800124746 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.kfAB4MRB1T/b/src/pre_process/m_global_parameters.fpp -14670547982328888582 src/post_process/m_derived_variables.fpp -14739644014569295158 src/common/include/SharedHardcoded.fpp -14954376616734417912 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.5wobk7aEG0/b/src/simulation/p_main.fpp -14999475271112169381 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.zed9MGw8lu/b/src/common/include/acc_macros.fpp -14999475271112169381 src/common/include/acc_macros.fpp -15049314966727887552 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.foNVQzeyQX/b/src/pre_process/m_simplex_noise.fpp -15049314966727887552 src/pre_process/m_simplex_noise.fpp -15110474130912937443 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.EOjTtcOp00/b/src/post_process/m_checker.fpp -15317541443631750607 src/simulation/m_bubbles_EE.fpp -15343341342992294043 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.ZE1xLrrD4M/b/src/simulation/m_body_forces.fpp -15508824445404703824 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.DJdV0uDXkk/pr.fpp -15508824445404703824 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.UKcnsjaI4a/b/src/common/m_helper_basic.fpp -15508824445404703824 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.dpV8UkalaA/b/src/common/m_helper_basic.fpp -15573111593524903869 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.7rXfBv7i7f/b/src/simulation/m_qbmm.fpp -15615432817640526542 src/post_process/m_checker.fpp -15809629697745920208 src/simulation/m_body_forces.fpp -15811265556360623843 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.6h5PDEc3xX/b/src/simulation/include/inline_capillary.fpp -15811265556360623843 src/simulation/include/inline_capillary.fpp -15874659916346725348 src/pre_process/m_data_output.fpp -15941699165887750367 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.S0h68IhVLd/b/src/common/m_precision_select.f90 -16277666294786574062 src/simulation/m_viscous.fpp -16325267463833969784 src/pre_process/m_start_up.fpp -16397783534027655847 src/simulation/m_checker.fpp -16590815127468205830 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.wqmnQUCDbi/b/src/common/include/omp_macros.fpp -16590815127468205830 src/common/include/omp_macros.fpp -16613830963758284333 src/common/include/2dHardcodedIC.fpp -16666864254209086704 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.4QVjyhlBbR/b/src/simulation/m_ib_patches.fpp -16666864254209086704 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.EKTuvrJmZf/pr.fpp -16666864254209086704 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.UKcnsjaI4a/b/src/simulation/m_ib_patches.fpp -16716924334175372818 src/simulation/m_global_parameters.fpp -16819660696315222173 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.wZ5g7DS74M/b/src/simulation/include/inline_riemann.fpp -16819660696315222173 src/simulation/include/inline_riemann.fpp -16863576169260976215 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.BtoC8sntqC/b/src/common/m_boundary_common.fpp -16863576169260976215 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.UKcnsjaI4a/b/src/common/m_boundary_common.fpp -16863576169260976215 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.WV8J0UVWWc/pr.fpp -16863576169260976215 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.tPbHdHuGzL/b/src/common/m_boundary_common.fpp -17150360143499547248 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.GwPH1PymWU/b/src/pre_process/m_mpi_proxy.fpp -17150360143499547248 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.UKcnsjaI4a/b/src/pre_process/m_mpi_proxy.fpp -17374991166589206306 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.CKefDZblI8/b/src/simulation/m_muscl.fpp -17374991166589206306 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.UKcnsjaI4a/b/src/simulation/m_muscl.fpp -17374991166589206306 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.bThVXwVjHQ/pr.fpp -17383712883767117007 src/simulation/m_derived_variables.fpp -17475717397114845816 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.7vhQq2kOXS/b/src/pre_process/m_check_ib_patches.fpp -17489851833420935241 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.UKcnsjaI4a/b/src/pre_process/m_start_up.fpp -17489851833420935241 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.jKReiOTmE3/pr.fpp -17489851833420935241 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.pN7wf0OOXk/b/src/pre_process/m_start_up.fpp -17521335209975820849 src/post_process/m_mpi_proxy.fpp -17578011942315344381 src/common/m_helper.fpp -17729534019838315074 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.5q1Y270gxY/b/src/post_process/m_global_parameters.fpp -17729534019838315074 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.UKcnsjaI4a/b/src/post_process/m_global_parameters.fpp -17729534019838315074 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.VmGqKfWL4e/b/src/post_process/m_global_parameters.fpp -17729534019838315074 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.fEo4jGidK0/pr.fpp -17747955368322546147 src/simulation/m_time_steppers.fpp -17786640510670779223 src/common/m_derived_types.fpp -17939937579085231691 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.1FlGgFgoLk/b/src/simulation/m_riemann_solvers.fpp -17952081853197839750 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.FM3hyTJcC1/b/src/post_process/p_main.fpp -18080888037678917285 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.UOicaksnAM/b/src/common/m_variables_conversion.fpp -18166547160227944552 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.04SRuU4uDG/b/src/simulation/m_sim_helpers.fpp -18166547160227944552 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.UH5isBDNLP/pr.fpp -18166547160227944552 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.UKcnsjaI4a/b/src/simulation/m_sim_helpers.fpp -18226449463280282712 src/simulation/m_rhs.fpp -18308153827535525888 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.LcZmBtbXI5/b/src/simulation/m_time_steppers.fpp -18308153827535525888 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.TMdfrAiUad/b/src/simulation/m_time_steppers.fpp -18308153827535525888 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.UKcnsjaI4a/b/src/simulation/m_time_steppers.fpp -18308153827535525888 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.zBXQoIJ9Ns/pr.fpp -18424647052757242046 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.90F2SuKdN3/b/src/simulation/m_igr.fpp -1921723504088853053 src/simulation/m_hypoelastic.fpp -2065425623481551924 src/common/m_boundary_common.fpp -2089934286629799065 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.UKcnsjaI4a/b/src/simulation/m_bubbles_EE.fpp -2089934286629799065 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.ehVOiqSEna/b/src/simulation/m_bubbles_EE.fpp -2089934286629799065 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.mGbGtZnmMH/pr.fpp -2092302292714238550 src/pre_process/m_checker.fpp -2179692337769865707 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.UKcnsjaI4a/b/src/common/m_derived_types.fpp -2179692337769865707 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.ahYsbo4OkN/b/src/common/m_derived_types.fpp -2179692337769865707 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.u43jNT6Y9N/pr.fpp -2179692337769865707 /tmp/pr_derived.fpp -2180900767736986011 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.2wyV79dZFt/pr.fpp -2180900767736986011 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.9ywat4IE5E/b/src/simulation/m_ibm.fpp -2180900767736986011 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.UKcnsjaI4a/b/src/simulation/m_ibm.fpp -2238355401608193277 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.Xeee1w2Np4/b/src/post_process/m_start_up.fpp -2246088494097541240 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.6XVxKq1Gls/b/src/simulation/m_mpi_proxy.fpp -2246088494097541240 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.UKcnsjaI4a/b/src/simulation/m_mpi_proxy.fpp -2246088494097541240 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.bFnMb9Yj6X/pr.fpp -2275015924369440500 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.GyRQmToKip/b/src/simulation/m_bubbles_EL.fpp -2275015924369440500 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.QWfhmzAUhW/b/src/simulation/m_bubbles_EL.fpp -2275015924369440500 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.UKcnsjaI4a/b/src/simulation/m_bubbles_EL.fpp -2275015924369440500 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.sq9eLcwlqR/pr.fpp -2431245550782554100 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.IwOd4FjXKf/b/src/simulation/m_viscous.fpp -2525268250784412532 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.2moDi289m2/b/src/simulation/m_compute_levelset.fpp -2525268250784412532 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.UKcnsjaI4a/b/src/simulation/m_compute_levelset.fpp -2525268250784412532 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.fNlW6mq81s/pr.fpp -2551148861500766043 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.61vHeCBp3z/b/src/common/m_nvtx.f90 -3296338549351377009 src/post_process/m_data_input.f90 -330369965658929155 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.l3vlWwFtc6/b/src/pre_process/m_checker.fpp -3322818355154981622 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.zxtBRdLiDM/b/src/simulation/m_derived_variables.fpp -3474524733030028692 src/pre_process/m_grid.f90 -3586268134361254209 src/common/m_variables_conversion.fpp -3852216218768625740 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.ON0VZhypev/b/src/common/m_compile_specific.f90 -3852216218768625740 src/common/m_compile_specific.f90 -419528971510258904 src/common/m_constants.fpp -4271870002582174631 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.h1I7f50x8l/b/src/post_process/m_mpi_proxy.fpp -4316649851528138914 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.vJ4faZHES0/b/src/post_process/m_data_input.f90 -4353656613440585819 src/post_process/m_data_output.fpp -4417977747387015039 src/simulation/m_bubbles_EL.fpp -47037120222980462 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.oFDAmDeZN7/b/src/simulation/m_fftw.fpp -4769787692054280401 src/common/m_precision_select.f90 -4898418582330870284 src/simulation/m_data_output.fpp -4993379909229078812 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.RprlXGCudJ/b/src/simulation/m_checker.fpp -5179107110711951524 src/common/m_model.fpp -5290618235356275088 src/pre_process/m_assign_variables.fpp -5434153436692493302 src/post_process/m_start_up.fpp -5684204796802451846 src/simulation/m_cbc.fpp -5725362251714205830 src/post_process/m_global_parameters.fpp -5783893076695788858 src/pre_process/m_check_ib_patches.fpp -5871828278470799827 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.hpU6ltVEIS/b/src/syscheck/syscheck.fpp -5871828278470799827 src/syscheck/syscheck.fpp -5928207121067860413 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.mpy7h1Q0k4/b/src/common/m_model.fpp -6137784461014282246 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.21jzdeIFZA/b/src/common/include/3dHardcodedIC.fpp -6137784461014282246 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.Ngtiv1vOCD/b/src/common/include/3dHardcodedIC.fpp -6137784461014282246 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.UKcnsjaI4a/b/src/common/include/3dHardcodedIC.fpp -6137784461014282246 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.aS6jzEPk9Y/b/src/common/include/3dHardcodedIC.fpp -6137784461014282246 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.b91atfZWFM/pr.fpp -6137784461014282246 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.ox5RwzwCDq/b/src/common/include/3dHardcodedIC.fpp -6137784461014282246 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.uHW6w2dKmd/b/src/common/include/3dHardcodedIC.fpp -6137784461014282246 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.unuGVybPf5/b/src/common/include/3dHardcodedIC.fpp -6240714802147004944 src/common/include/shared_parallel_macros.fpp -6276978915188096958 src/common/include/3dHardcodedIC.fpp -68593444489471372 src/simulation/m_compute_levelset.fpp -6938669613291679776 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.4o4LVAkqMP/b/src/common/m_finite_differences.fpp -6938669613291679776 src/common/m_finite_differences.fpp -732149268206108348 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.2J0Z5N2qcF/b/src/simulation/m_weno.fpp -732149268206108348 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.2QXPygy8q1/pr_1646504.fpp -732149268206108348 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.D9KOPlN1LD/pr.fpp -732149268206108348 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.UKcnsjaI4a/b/src/simulation/m_weno.fpp -732149268206108348 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.xwrbhmKSBn/b/src/simulation/m_weno.fpp -7463753986237902141 src/common/m_helper_basic.fpp -7530723425281110009 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.A857NqLisR/b/src/simulation/m_cbc.fpp -7580365803335695134 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.WMlJs7jEPw/b/src/simulation/m_hypoelastic.fpp -7723221865542041495 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.svITM8tMXS/b/src/pre_process/m_icpp_patches.fpp -7737322002952828776 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.UKcnsjaI4a/b/src/simulation/m_start_up.fpp -7737322002952828776 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.aYeUsTe6vQ/b/src/simulation/m_start_up.fpp -7737322002952828776 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.mGRII3r92Q/pr.fpp -8042763174988148227 src/simulation/m_riemann_solvers.fpp -8093344263636711422 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.CtULDFfiWw/pr.fpp -8093344263636711422 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.UKcnsjaI4a/b/src/simulation/m_bubbles_EL_kernels.fpp -8093344263636711422 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.u1zFhDbdg8/b/src/simulation/m_bubbles_EL_kernels.fpp -8258277022714838383 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.7MRd899dQW/b/src/simulation/m_global_parameters.fpp -8258277022714838383 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.Du4hJUphgy/b/src/simulation/m_global_parameters.fpp -8258277022714838383 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.M29f3SMb5C/pr.fpp -8258277022714838383 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.UKcnsjaI4a/b/src/simulation/m_global_parameters.fpp -8258277022714838383 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.cJ15SrprHl/b/src/simulation/m_global_parameters.fpp -8258277022714838383 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.yxQ0X6fv0o/b/src/simulation/m_global_parameters.fpp -8373688306336592140 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.tVW0Ag4HFB/b/src/pre_process/m_data_output.fpp -8639686218598077333 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.fo85j8vdro/b/src/post_process/m_data_output.fpp -8755329155192764099 src/pre_process/m_global_parameters.fpp -8835068673407070922 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.qfglItrwDK/b/src/pre_process/m_boundary_conditions.fpp -8835068673407070922 src/pre_process/m_boundary_conditions.fpp -8849574993014605176 src/simulation/m_ib_patches.fpp -8870602128241043159 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.V53atDEagj/b/src/pre_process/m_check_patches.fpp -8978802987682839827 src/pre_process/m_mpi_proxy.fpp -919624630099600931 src/common/include/ExtrusionHardcodedIC.fpp -9370663205287462789 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.zoRoHcwA35/b/src/pre_process/m_perturbation.fpp -9419299607787709748 src/simulation/p_main.fpp -9606486790139625748 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.QCod6CiPeT/b/src/common/m_mpi_common.fpp -9606486790139625748 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.UKcnsjaI4a/b/src/common/m_mpi_common.fpp -9606486790139625748 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.Z9FK1bV094/b/src/common/m_mpi_common.fpp -9606486790139625748 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.dF9qaNUJjz/b/src/common/m_mpi_common.fpp -9606486790139625748 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.j1H2hZqcGd/pr.fpp -9606486790139625748 /storage/home/hcoda1/6/sbryngelson3/tmp_claude/tmp.sBmtXp00OQ/b/src/common/m_mpi_common.fpp -9634210289819551950 src/pre_process/m_check_patches.fpp -9812035701611855679 /tmp/test_ffmt.fpp -9864053594660500546 src/simulation/m_fftw.fpp -9961309992593322894 src/simulation/m_hyperelastic.fpp diff --git a/.gitignore b/.gitignore index aba54411e1..87c14cd0b9 100644 --- a/.gitignore +++ b/.gitignore @@ -114,3 +114,4 @@ cce_*/ cce_*.log run_cce_*.sh .ffmt_cache/ +**/.ffmt_cache/ diff --git a/src/common/m_boundary_common.fpp b/src/common/m_boundary_common.fpp index c293ba2b5d..a4b71806b6 100644 --- a/src/common/m_boundary_common.fpp +++ b/src/common/m_boundary_common.fpp @@ -2,7 +2,7 @@ !! @file !! Contains module m_boundary_common -!> Noncharacteristic and processor boundary condition application for ghost cells and buffer regions +!> @brief Noncharacteristic and processor boundary condition application for ghost cells and buffer regions #:include 'case.fpp' #:include 'macros.fpp' @@ -97,7 +97,6 @@ contains type(integer_field), dimension(1:num_dims,1:2), intent(in) :: bc_type integer :: k, l - if (bc_x%beg >= 0) then call s_mpi_sendrecv_variables_buffers(q_prim_vf, 1, -1, sys_size, pb_in, mv_in) else @@ -156,7 +155,6 @@ contains $:END_GPU_PARALLEL_LOOP() end if - if (n == 0) return #:if not MFC_CASE_OPTIMIZATION or num_dims > 1 @@ -222,7 +220,6 @@ contains end if #:endif - if (p == 0) return #:if not MFC_CASE_OPTIMIZATION or num_dims > 2 @@ -342,7 +339,8 @@ contains end subroutine s_ghost_cell_extrapolation - !> Applies reflective (symmetry) boundary conditions by mirroring primitive variables and flipping the normal velocity component. + !> Applies reflective (symmetry) boundary conditions by mirroring primitive variables and flipping the normal velocity + !! component. subroutine s_symmetry(q_prim_vf, bc_dir, bc_loc, k, l, pb_in, mv_in) $:GPU_ROUTINE(parallelism='[seq]') @@ -2278,7 +2276,6 @@ contains #endif #ifndef MFC_PRE_PROCESS - ! Populating cell-width distribution buffer at bc_x%beg if (bc_x%beg >= 0) then call s_mpi_sendrecv_grid_variables_buffers(1, -1) @@ -2331,7 +2328,6 @@ contains x_cc(m + i) = x_cc(m + (i - 1)) + (dx(m + (i - 1)) + dx(m + i))/2._wp end do - ! Populating cell-width distribution buffer at bc_y%beg if (n == 0) then return @@ -2386,7 +2382,6 @@ contains y_cc(n + i) = y_cc(n + (i - 1)) + (dy(n + (i - 1)) + dy(n + i))/2._wp end do - ! Populating cell-width distribution buffer at bc_z%beg if (p == 0) then return diff --git a/src/pre_process/m_global_parameters.fpp b/src/pre_process/m_global_parameters.fpp index 01e31ad0ed..a709cc4a35 100644 --- a/src/pre_process/m_global_parameters.fpp +++ b/src/pre_process/m_global_parameters.fpp @@ -4,7 +4,7 @@ #:include 'case.fpp' -!> Defines global parameters for the computational domain, simulation algorithm, and initial conditions +!> @brief Defines global parameters for the computational domain, simulation algorithm, and initial conditions module m_global_parameters #ifdef MFC_MPI @@ -112,32 +112,31 @@ module m_global_parameters ! Cell Indices for the entire (local) domain. In simulation and post_process, this includes the buffer region. idwbuff and ! idwint are the same otherwise. Stands for "InDices With BUFFer". type(int_bounds_info) :: idwbuff(1:3) - - integer :: fd_order !< Finite-difference order for CoM/probe derivative approximations - integer :: fd_number !< FD half-stencil size: MAX(1, fd_order/2) + integer :: fd_order !< Finite-difference order for CoM/probe derivative approximations + integer :: fd_number !< FD half-stencil size: MAX(1, fd_order/2) !> @name lagrangian subgrid bubble parameters !> @{! type(bubbles_lagrange_parameters) :: lag_params !< Lagrange bubbles' parameters !> @} - type(int_bounds_info) :: bc_x, bc_y, bc_z !< Boundary conditions in the x-, y- and z-coordinate directions - integer :: shear_num !< Number of shear stress components - integer, dimension(3) :: shear_indices !< Indices of the stress components that represent shear stress - integer :: shear_BC_flip_num !< Number of shear stress components to reflect for boundary conditions - integer, dimension(3, 2) :: shear_BC_flip_indices !< Shear stress BC reflection indices (1:3, 1:shear_BC_flip_num) - logical :: parallel_io !< Format of the data files - logical :: file_per_process !< type of data output - integer :: precision !< Precision of output files - logical :: down_sample !< Down-sample the output data - logical :: mixlayer_vel_profile !< Set hyperbolic tangent streamwise velocity profile - real(wp) :: mixlayer_vel_coef !< Coefficient for the hyperbolic tangent streamwise velocity profile - logical :: mixlayer_perturb !< Superimpose instability waves to surrounding fluid flow - integer :: mixlayer_perturb_nk !< Number of Fourier modes for perturbation with mixlayer_perturb flag - real(wp) :: mixlayer_perturb_k0 !< Peak wavenumber for mixlayer perturbation (default: most unstable mode) + type(int_bounds_info) :: bc_x, bc_y, bc_z !< Boundary conditions in the x-, y- and z-coordinate directions + integer :: shear_num !< Number of shear stress components + integer, dimension(3) :: shear_indices !< Indices of the stress components that represent shear stress + integer :: shear_BC_flip_num !< Number of shear stress components to reflect for boundary conditions + integer, dimension(3, 2) :: shear_BC_flip_indices !< Shear stress BC reflection indices (1:3, 1:shear_BC_flip_num) + logical :: parallel_io !< Format of the data files + logical :: file_per_process !< type of data output + integer :: precision !< Precision of output files + logical :: down_sample !< Down-sample the output data + logical :: mixlayer_vel_profile !< Set hyperbolic tangent streamwise velocity profile + real(wp) :: mixlayer_vel_coef !< Coefficient for the hyperbolic tangent streamwise velocity profile + logical :: mixlayer_perturb !< Superimpose instability waves to surrounding fluid flow + integer :: mixlayer_perturb_nk !< Number of Fourier modes for perturbation with mixlayer_perturb flag + real(wp) :: mixlayer_perturb_k0 !< Peak wavenumber for mixlayer perturbation (default: most unstable mode) logical :: simplex_perturb type(simplex_noise_params) :: simplex_params - real(wp) :: pi_fac !< Factor for artificial pi_inf + real(wp) :: pi_fac !< Factor for artificial pi_inf logical :: viscous logical :: bubbles_lagrange @@ -152,9 +151,8 @@ module m_global_parameters integer :: elliptic_smoothing_iters integer, allocatable, dimension(:) :: proc_coords !< Processor coordinates in MPI_CART_COMM type(int_bounds_info), dimension(3) :: nidx - integer, allocatable, dimension(:,:,:) :: neighbor_ranks !< Neighbor ranks - - integer, allocatable, dimension(:) :: start_idx !< Starting cell-center index of local processor in global grid + integer, allocatable, dimension(:,:,:) :: neighbor_ranks !< Neighbor ranks + integer, allocatable, dimension(:) :: start_idx !< Starting cell-center index of local processor in global grid #ifdef MFC_MPI type(mpi_io_var), public :: MPI_IO_DATA @@ -164,12 +162,10 @@ module m_global_parameters ! Initial Condition Parameters integer :: num_patches !< Number of patches composing initial condition - - type(ic_patch_parameters), dimension(num_patches_max) :: patch_icpp !< IC patch parameters (max: num_patches_max) - integer :: num_bc_patches !< Number of boundary condition patches - logical :: bc_io !< whether or not to save BC data + type(ic_patch_parameters), dimension(num_patches_max) :: patch_icpp !< IC patch parameters (max: num_patches_max) + integer :: num_bc_patches !< Number of boundary condition patches + logical :: bc_io !< whether or not to save BC data type(bc_patch_parameters), dimension(num_bc_patches_max) :: patch_bc !< BC patch parameters - type(physical_parameters), dimension(num_fluids_max) :: fluid_pp !< Stiffened gas EOS parameters and Reynolds numbers per fluid ! Subgrid Bubble Parameters @@ -233,11 +229,10 @@ module m_global_parameters integer, allocatable, dimension(:,:,:) :: logic_grid type(pres_field) :: pb type(pres_field) :: mv - real(wp) :: Bx0 !< Constant magnetic field in the x-direction (1D) - - integer :: buff_size !< Number of ghost cells for boundary condition storage - logical :: fft_wrt - logical :: dummy !< AMDFlang workaround for case-optimization + GPU-kernel bug + real(wp) :: Bx0 !< Constant magnetic field in the x-direction (1D) + integer :: buff_size !< Number of ghost cells for boundary condition storage + logical :: fft_wrt + logical :: dummy !< AMDFlang workaround for case-optimization + GPU-kernel bug ! Variables for hardcoded initial conditions that are read from input files character(LEN=2*path_len) :: interface_file diff --git a/src/simulation/m_data_output.fpp b/src/simulation/m_data_output.fpp index 59013b1196..37931a7aca 100644 --- a/src/simulation/m_data_output.fpp +++ b/src/simulation/m_data_output.fpp @@ -5,7 +5,7 @@ #:include 'macros.fpp' #:include 'case.fpp' -!> Writes solution data, run-time stability diagnostics (ICFL, VCFL, CCFL, Rc), and probe/center-of-mass files +!> @brief Writes solution data, run-time stability diagnostics (ICFL, VCFL, CCFL, Rc), and probe/center-of-mass files module m_data_output use m_derived_types @@ -305,7 +305,6 @@ contains integer :: i, j, k, l, r real(wp) :: gamma, lit_gamma, pi_inf, qv !< Temporary EOS params - write (t_step_dir, '(A,I0,A,I0)') trim(case_dir) // '/p_all' write (t_step_dir, '(a,i0,a,i0)') trim(case_dir) // '/p_all/p', proc_rank, '/', t_step @@ -779,7 +778,6 @@ contains call MPI_FILE_CLOSE(ifile, ierr) else - if (ib) then call s_initialize_mpi_data(q_cons_vf, ib_markers) else if (present(beta)) then @@ -863,7 +861,6 @@ contains character(LEN=path_len + 2*name_len) :: file_path character(LEN=path_len + 2*name_len) :: t_step_dir - write (t_step_dir, '(A,I0,A,I0)') trim(case_dir) // '/p_all' write (t_step_dir, '(a,i0,a,i0)') trim(case_dir) // '/p_all/p', proc_rank, '/', time_step write (file_path, '(A,I0,A)') trim(t_step_dir) // '/ib_data.dat' @@ -945,7 +942,6 @@ contains integer :: i !< Generic loop iterator real(wp) :: nondim_time !< Non-dimensional time - if (t_step_old /= dflt_int) then nondim_time = real(t_step + t_step_old, wp)*dt else @@ -980,39 +976,38 @@ contains real(wp), dimension(-1:m) :: distx real(wp), dimension(-1:n) :: disty real(wp), dimension(-1:p) :: distz - - real(wp) :: lit_gamma, nbub - real(wp) :: rho - real(wp), dimension(num_vels) :: vel - real(wp) :: pres - real(wp) :: ptilde - real(wp) :: ptot - real(wp) :: alf - real(wp) :: alfgr - real(wp), dimension(num_fluids) :: alpha - real(wp) :: gamma - real(wp) :: pi_inf - real(wp) :: qv - real(wp) :: c - real(wp) :: M00, M10, M01, M20, M11, M02 - real(wp) :: varR, varV - real(wp), dimension(Nb) :: nR, R, nRdot, Rdot - real(wp) :: nR3 - real(wp) :: accel - real(wp) :: int_pres - real(wp) :: max_pres - real(wp), dimension(2) :: Re - real(wp), dimension(6) :: tau_e - real(wp) :: G_local - real(wp) :: dyn_p, T - real(wp) :: damage_state - integer :: i, j, k, l, s, d !< Generic loop iterator - real(wp) :: nondim_time !< Non-dimensional time - real(wp) :: tmp !< Temporary variable to store quantity for mpi_allreduce - integer :: npts !< Number of included integral points - real(wp) :: rad, thickness !< For integral quantities - logical :: trigger !< For integral quantities - real(wp) :: rhoYks(1:num_species) + real(wp) :: lit_gamma, nbub + real(wp) :: rho + real(wp), dimension(num_vels) :: vel + real(wp) :: pres + real(wp) :: ptilde + real(wp) :: ptot + real(wp) :: alf + real(wp) :: alfgr + real(wp), dimension(num_fluids) :: alpha + real(wp) :: gamma + real(wp) :: pi_inf + real(wp) :: qv + real(wp) :: c + real(wp) :: M00, M10, M01, M20, M11, M02 + real(wp) :: varR, varV + real(wp), dimension(Nb) :: nR, R, nRdot, Rdot + real(wp) :: nR3 + real(wp) :: accel + real(wp) :: int_pres + real(wp) :: max_pres + real(wp), dimension(2) :: Re + real(wp), dimension(6) :: tau_e + real(wp) :: G_local + real(wp) :: dyn_p, T + real(wp) :: damage_state + integer :: i, j, k, l, s, d !< Generic loop iterator + real(wp) :: nondim_time !< Non-dimensional time + real(wp) :: tmp !< Temporary variable to store quantity for mpi_allreduce + integer :: npts !< Number of included integral points + real(wp) :: rad, thickness !< For integral quantities + logical :: trigger !< For integral quantities + real(wp) :: rhoYks(1:num_species) T = dflt_T_guess diff --git a/src/simulation/m_global_parameters.fpp b/src/simulation/m_global_parameters.fpp index 63294a3254..5e706c400b 100644 --- a/src/simulation/m_global_parameters.fpp +++ b/src/simulation/m_global_parameters.fpp @@ -5,7 +5,7 @@ #:include 'case.fpp' #:include 'macros.fpp' -!> Global parameters for the computational domain, fluid properties, and simulation algorithm configuration +!> @brief Global parameters for the computational domain, fluid properties, and simulation algorithm configuration module m_global_parameters #ifdef MFC_MPI @@ -19,9 +19,8 @@ module m_global_parameters implicit none - real(wp) :: wall_time = 0 - real(wp) :: wall_time_avg = 0 - + real(wp) :: wall_time = 0 + real(wp) :: wall_time_avg = 0 integer :: num_procs !< Number of processors character(LEN=path_len) :: case_dir !< Case folder location logical :: run_time_info !< Run-time output flag @@ -330,9 +329,9 @@ module m_global_parameters $:GPU_DECLARE(create='[buff_size]') - integer :: shear_num !< Number of shear stress components - integer, dimension(3) :: shear_indices !< Indices of the stress components that represent shear stress - integer :: shear_BC_flip_num !< Number of shear stress components to reflect for boundary conditions + integer :: shear_num !< Number of shear stress components + integer, dimension(3) :: shear_indices !< Indices of the stress components that represent shear stress + integer :: shear_BC_flip_num !< Number of shear stress components to reflect for boundary conditions integer, dimension(3, 2) :: shear_BC_flip_indices !< Shear stress BC reflection indices (1:3, 1:shear_BC_flip_num) $:GPU_DECLARE(create='[shear_num, shear_indices, shear_BC_flip_num, shear_BC_flip_indices]') @@ -345,9 +344,8 @@ module m_global_parameters ! Subgrid Bubble Parameters type(subgrid_bubble_physical_parameters) :: bub_pp - - integer :: fd_order !< Finite-difference order for CoM and flow probe derivatives - integer :: fd_number !< FD half-stencil size: MAX(1, fd_order/2) + integer :: fd_order !< Finite-difference order for CoM and flow probe derivatives + integer :: fd_number !< FD half-stencil size: MAX(1, fd_order/2) $:GPU_DECLARE(create='[fd_order, fd_number]') logical :: probe_wrt diff --git a/src/simulation/m_ib_patches.fpp b/src/simulation/m_ib_patches.fpp index 87a0faf742..2becce0bc3 100644 --- a/src/simulation/m_ib_patches.fpp +++ b/src/simulation/m_ib_patches.fpp @@ -9,7 +9,7 @@ #:include '3dHardcodedIC.fpp' #:include 'macros.fpp' -!> Immersed boundary patch geometry constructors for 2D and 3D shapes +!> @brief Immersed boundary patch geometry constructors for 2D and 3D shapes module m_ib_patches use m_model ! Subroutine(s) related to STL files @@ -119,7 +119,6 @@ contains integer :: i, j, il, ir, jl, jr !< Generic loop iterators integer :: encoded_patch_id - center(1) = patch_ib(patch_id)%x_centroid + real(xp, wp)*(glb_bounds(1)%end - glb_bounds(1)%beg) center(2) = patch_ib(patch_id)%y_centroid + real(yp, wp)*(glb_bounds(2)%end - glb_bounds(2)%beg) radius = patch_ib(patch_id)%radius @@ -135,7 +134,6 @@ contains call get_bounding_indices(center(1) - radius, center(1) + radius, x_cc, il, ir) call get_bounding_indices(center(2) - radius, center(2) + radius, y_cc, jl, jr) - $:GPU_PARALLEL_LOOP(private='[i, j]', copyin='[encoded_patch_id, center, radius]', collapse=2) do j = jl, jr do i = il, ir @@ -472,7 +470,6 @@ contains real(wp), dimension(1:2) :: length, center !< x and y coordinates in local IB frame real(wp), dimension(1:3,1:3) :: inverse_rotation - center(1) = patch_ib(patch_id)%x_centroid + real(xp, wp)*(glb_bounds(1)%end - glb_bounds(1)%beg) center(2) = patch_ib(patch_id)%y_centroid + real(yp, wp)*(glb_bounds(2)%end - glb_bounds(2)%beg) length(1) = patch_ib(patch_id)%length_x @@ -528,7 +525,6 @@ contains !! Variables to initialize the pressure field that corresponds to the bubble-collapse test case found in Tiwari et al. !! (2013) - center(1) = patch_ib(patch_id)%x_centroid + real(xp, wp)*(glb_bounds(1)%end - glb_bounds(1)%beg) center(2) = patch_ib(patch_id)%y_centroid + real(yp, wp)*(glb_bounds(2)%end - glb_bounds(2)%beg) center(3) = patch_ib(patch_id)%z_centroid + real(zp, wp)*(glb_bounds(3)%end - glb_bounds(3)%beg) @@ -582,7 +578,6 @@ contains real(wp), dimension(1:3,1:3) :: inverse_rotation real(wp) :: corner_distance - center(1) = patch_ib(patch_id)%x_centroid + real(xp, wp)*(glb_bounds(1)%end - glb_bounds(1)%beg) center(2) = patch_ib(patch_id)%y_centroid + real(yp, wp)*(glb_bounds(2)%end - glb_bounds(2)%beg) center(3) = patch_ib(patch_id)%z_centroid + real(zp, wp)*(glb_bounds(3)%end - glb_bounds(3)%beg) @@ -649,7 +644,6 @@ contains real(wp), dimension(1:3,1:3) :: inverse_rotation real(wp) :: corner_distance - center(1) = patch_ib(patch_id)%x_centroid + real(xp, wp)*(glb_bounds(1)%end - glb_bounds(1)%beg) center(2) = patch_ib(patch_id)%y_centroid + real(yp, wp)*(glb_bounds(2)%end - glb_bounds(2)%beg) center(3) = patch_ib(patch_id)%z_centroid + real(zp, wp)*(glb_bounds(3)%end - glb_bounds(3)%beg) @@ -717,7 +711,6 @@ contains real(wp), dimension(1:2) :: center !< x and y coordinates in local IB frame real(wp), dimension(1:3,1:3) :: inverse_rotation - center(1) = patch_ib(patch_id)%x_centroid + real(xp, wp)*(glb_bounds(1)%end - glb_bounds(1)%beg) center(2) = patch_ib(patch_id)%y_centroid + real(yp, wp)*(glb_bounds(2)%end - glb_bounds(2)%beg) ellipse_coeffs(1) = 0.5_wp*patch_ib(patch_id)%length_x From 23aacd7c6b169449f76ef19c2f963300aa879edf Mon Sep 17 00:00:00 2001 From: jaguilar Date: Sun, 29 Mar 2026 15:44:52 -0400 Subject: [PATCH 13/14] Bug Fix in simulation/mpi_proxy I removed the collision force sending arrays in mpi_proxy and added a check in the deallocate for processor count greater than 0. This is a bug fix for running mfc with mpi with only 1 rank. --- src/simulation/m_mpi_proxy.fpp | 17 +---------------- 1 file changed, 1 insertion(+), 16 deletions(-) diff --git a/src/simulation/m_mpi_proxy.fpp b/src/simulation/m_mpi_proxy.fpp index bffebf079d..e778fa751a 100644 --- a/src/simulation/m_mpi_proxy.fpp +++ b/src/simulation/m_mpi_proxy.fpp @@ -38,12 +38,6 @@ module m_mpi_proxy integer :: neighbor_list(MAX_NEIGHBORS, 3) integer :: n_neighbors $:GPU_DECLARE(create='[p_send_counts]') - integer, allocatable :: force_send_counts(:), force_recv_counts(:) - integer, allocatable :: force_send_ids(:,:) - integer, allocatable :: flat_send_ids(:) - real(wp), allocatable :: force_send_vals(:,:,:) - real(wp), allocatable :: flat_send_vals(:) - $:GPU_DECLARE(create='[force_send_counts, force_send_ids, force_send_vals]') contains @@ -133,12 +127,6 @@ contains end do end do end do - @:ALLOCATE(force_send_counts(0:num_procs-1)) - @:ALLOCATE(force_recv_counts(0:num_procs-1)) - @:ALLOCATE(force_send_ids(0:num_procs-1, 1:lag_params%nParticles_glb)) - @:ALLOCATE(force_send_vals(0:num_procs-1, 1:lag_params%nParticles_glb, 1:3)) - @:ALLOCATE(flat_send_ids(1:lag_params%nParticles_glb)) - @:ALLOCATE(flat_send_vals(1:3*lag_params%nParticles_glb)) #endif end subroutine s_initialize_solid_particles_mpi @@ -1292,11 +1280,8 @@ contains @:DEALLOCATE(ib_buff_send, ib_buff_recv) end if - if (particles_lagrange) then + if (particles_lagrange .and. num_procs > 1) then @:DEALLOCATE(p_send_buff, p_recv_buff, p_send_ids) - @:DEALLOCATE(force_send_counts, force_recv_counts) - @:DEALLOCATE(force_send_ids, force_send_vals) - @:DEALLOCATE(flat_send_ids, flat_send_vals) end if #endif From 719fdb49d77147cc46d89611260925c8ac179ce1 Mon Sep 17 00:00:00 2001 From: jaguilar Date: Wed, 1 Apr 2026 14:05:26 -0400 Subject: [PATCH 14/14] GPU Bug fix adding "copyin" of array with buffer communicated variables for EL solver --- src/common/m_boundary_common.fpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/common/m_boundary_common.fpp b/src/common/m_boundary_common.fpp index 1891fb4be7..d2ce40d456 100644 --- a/src/common/m_boundary_common.fpp +++ b/src/common/m_boundary_common.fpp @@ -1068,7 +1068,7 @@ contains !> x-direction if (bc_x%beg < 0) then - $:GPU_PARALLEL_LOOP(private='[l, k]', collapse=2) + $:GPU_PARALLEL_LOOP(private='[l, k]', collapse=2, copyin = '[vars_comm]') do l = beta_bc_bounds(3)%beg, beta_bc_bounds(3)%end do k = beta_bc_bounds(2)%beg, beta_bc_bounds(2)%end select case (bc_x%beg) @@ -1087,7 +1087,7 @@ contains end if if (bc_x%end < 0) then - $:GPU_PARALLEL_LOOP(private='[l, k]', collapse=2) + $:GPU_PARALLEL_LOOP(private='[l, k]', collapse=2, copyin = '[vars_comm]') do l = beta_bc_bounds(3)%beg, beta_bc_bounds(3)%end do k = beta_bc_bounds(2)%beg, beta_bc_bounds(2)%end select case (bc_x%end) @@ -1107,7 +1107,7 @@ contains !> y-direction if (bc_y%beg < 0) then - $:GPU_PARALLEL_LOOP(private='[l, k]', collapse=2) + $:GPU_PARALLEL_LOOP(private='[l, k]', collapse=2, copyin = '[vars_comm]') do l = beta_bc_bounds(3)%beg, beta_bc_bounds(3)%end do k = beta_bc_bounds(1)%beg, beta_bc_bounds(1)%end select case (bc_y%beg) @@ -1126,7 +1126,7 @@ contains end if if (bc_y%end < 0) then - $:GPU_PARALLEL_LOOP(private='[l, k]', collapse=2) + $:GPU_PARALLEL_LOOP(private='[l, k]', collapse=2, copyin = '[vars_comm]') do l = beta_bc_bounds(3)%beg, beta_bc_bounds(3)%end do k = beta_bc_bounds(1)%beg, beta_bc_bounds(1)%end select case (bc_y%end) @@ -1149,7 +1149,7 @@ contains #:if not MFC_CASE_OPTIMIZATION or num_dims > 2 !> z-direction if (bc_z%beg < 0) then - $:GPU_PARALLEL_LOOP(private='[l, k]', collapse=2) + $:GPU_PARALLEL_LOOP(private='[l, k]', collapse=2, copyin = '[vars_comm]') do l = beta_bc_bounds(2)%beg, beta_bc_bounds(2)%end do k = beta_bc_bounds(1)%beg, beta_bc_bounds(1)%end select case (bc_type(3, 1)%sf(k, l, 0)) @@ -1168,7 +1168,7 @@ contains end if if (bc_z%end < 0) then - $:GPU_PARALLEL_LOOP(private='[l, k]', collapse=2) + $:GPU_PARALLEL_LOOP(private='[l, k]', collapse=2, copyin = '[vars_comm]') do l = beta_bc_bounds(2)%beg, beta_bc_bounds(2)%end do k = beta_bc_bounds(1)%beg, beta_bc_bounds(1)%end select case (bc_type(3, 2)%sf(k, l, 0))